-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathxcode_claw.py
More file actions
206 lines (159 loc) · 7.25 KB
/
xcode_claw.py
File metadata and controls
206 lines (159 loc) · 7.25 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
#!/usr/bin/env python3
"""
xcode-claw — main CLI dispatcher.
"""
import typer
from typing import Optional
app = typer.Typer(
name="xcode-claw",
help="Xcode & Apple platform skill for OpenClaw",
no_args_is_help=True,
)
sim_app = typer.Typer(help="Simulator management (simctl)")
certs_app = typer.Typer(help="Code signing certificates")
prof_app = typer.Typer(help="Provisioning profiles")
app.add_typer(sim_app, name="sim")
app.add_typer(certs_app, name="certs")
app.add_typer(prof_app, name="profiles")
# ── Build / Test / Archive ─────────────────────────────────────────────────────
@app.command("build")
def build(
project: Optional[str] = typer.Option(None, "--project", "-p", help=".xcodeproj or .xcworkspace path"),
scheme: Optional[str] = typer.Option(None, "--scheme", "-s", help="Scheme name"),
config: str = typer.Option("Debug", help="Build configuration"),
sdk: Optional[str] = typer.Option(None, help="SDK (iphonesimulator, iphoneos, macosx)"),
destination: Optional[str] = typer.Option(None, "--dest", help="xcodebuild -destination string"),
no_sign: bool = typer.Option(False, "--no-sign", help="Skip code signing"),
):
"""Build a project scheme."""
from scripts.build import cmd_build
cmd_build(project, scheme, config, sdk, destination, no_sign)
@app.command("test")
def test(
project: Optional[str] = typer.Option(None, "--project", "-p"),
scheme: Optional[str] = typer.Option(None, "--scheme", "-s"),
destination: Optional[str] = typer.Option(None, "--dest", help="e.g. 'platform=iOS Simulator,name=iPhone 15'"),
result_path: Optional[str] = typer.Option(None, "--result-path", help="Path to write .xcresult bundle"),
):
"""Run the test suite."""
from scripts.build import cmd_test
cmd_test(project, scheme, destination, result_path)
@app.command("clean")
def clean(
project: Optional[str] = typer.Option(None, "--project", "-p"),
scheme: Optional[str] = typer.Option(None, "--scheme", "-s"),
):
"""Clean build artifacts and derived data."""
from scripts.build import cmd_clean
cmd_clean(project, scheme)
@app.command("archive")
def archive(
project: Optional[str] = typer.Option(None, "--project", "-p"),
scheme: Optional[str] = typer.Option(None, "--scheme", "-s"),
output: Optional[str] = typer.Option(None, "--output", "-o", help="Archive output path (.xcarchive)"),
export_plist:Optional[str] = typer.Option(None, "--export-plist", help="ExportOptions.plist for IPA export"),
):
"""Archive the app for distribution."""
from scripts.build import cmd_archive
cmd_archive(project, scheme, output, export_plist)
# ── Project Inspection ─────────────────────────────────────────────────────────
@app.command("info")
def info(
project: Optional[str] = typer.Option(None, "--project", "-p"),
):
"""List schemes, targets, and configurations."""
from scripts.inspect import cmd_info
cmd_info(project)
@app.command("settings")
def settings(
project: Optional[str] = typer.Option(None, "--project", "-p"),
scheme: Optional[str] = typer.Option(None, "--scheme", "-s"),
config: str = typer.Option("Debug", help="Build configuration"),
):
"""Show build settings for a scheme."""
from scripts.inspect import cmd_settings
cmd_settings(project, scheme, config)
@app.command("swift-version")
def swift_version():
"""Show active Swift and Xcode toolchain versions."""
from scripts.inspect import cmd_swift_version
cmd_swift_version()
# ── Simulators ─────────────────────────────────────────────────────────────────
@sim_app.command("list")
def sim_list(
filter: Optional[str] = typer.Option(None, help="Filter by name or OS"),
available: bool = typer.Option(True, help="Show only available simulators"),
):
"""List simulators with their state."""
from scripts.simulators import cmd_list
cmd_list(filter, available)
@sim_app.command("boot")
def sim_boot(udid: str = typer.Argument(..., help="Simulator UDID")):
"""Boot a simulator."""
from scripts.simulators import cmd_boot
cmd_boot(udid)
@sim_app.command("shutdown")
def sim_shutdown(udid: str = typer.Argument(..., help="Simulator UDID")):
"""Shutdown a simulator."""
from scripts.simulators import cmd_shutdown
cmd_shutdown(udid)
@sim_app.command("install")
def sim_install(
udid: str = typer.Argument(..., help="Simulator UDID"),
app: str = typer.Argument(..., help="Path to .app bundle"),
):
"""Install an .app bundle on a simulator."""
from scripts.simulators import cmd_install
cmd_install(udid, app)
@sim_app.command("launch")
def sim_launch(
udid: str = typer.Argument(..., help="Simulator UDID"),
bundle_id: str = typer.Argument(..., help="Bundle identifier"),
):
"""Launch an app on a simulator."""
from scripts.simulators import cmd_launch
cmd_launch(udid, bundle_id)
@sim_app.command("screenshot")
def sim_screenshot(
udid: str = typer.Argument(..., help="Simulator UDID"),
output: Optional[str] = typer.Option(None, "--output", "-o", help="Output file path"),
):
"""Capture a screenshot from a simulator."""
from scripts.simulators import cmd_screenshot
cmd_screenshot(udid, output)
# ── Signing ────────────────────────────────────────────────────────────────────
@certs_app.command("list")
def certs_list(
kind: str = typer.Option("codesigning", help="Certificate type to show"),
):
"""List installed code signing certificates."""
from scripts.signing import cmd_certs_list
cmd_certs_list(kind)
@prof_app.command("list")
def profiles_list(
expired: bool = typer.Option(False, "--expired", help="Show only expired profiles"),
):
"""List provisioning profiles."""
from scripts.signing import cmd_profiles_list
cmd_profiles_list(expired)
@prof_app.command("clean")
def profiles_clean():
"""Remove expired provisioning profiles."""
from scripts.signing import cmd_profiles_clean
cmd_profiles_clean()
# ── Diagnostics ────────────────────────────────────────────────────────────────
@app.command("doctor")
def doctor():
"""Run a full health check on Xcode, CLT, simulators, and signing."""
from scripts.doctor import cmd_doctor
cmd_doctor()
@app.command("logs")
def logs(
udid: str = typer.Argument(..., help="Simulator or device UDID"),
filter: Optional[str] = typer.Option(None, help="Grep filter for log output"),
):
"""Stream logs from a simulator or device."""
from scripts.simulators import cmd_logs
cmd_logs(udid, filter)
if __name__ == "__main__":
app()