claudecode-omc 5.6.6 → 5.6.8

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (179) hide show
  1. package/.local/skills/THIRD_PARTY_LICENSES/AvdLee-SwiftUI-Agent-Skill.LICENSE +21 -0
  2. package/.local/skills/THIRD_PARTY_LICENSES/Dimillian-Skills.LICENSE +21 -0
  3. package/.local/skills/THIRD_PARTY_LICENSES/README.md +36 -0
  4. package/.local/skills/THIRD_PARTY_LICENSES/twostraws-swiftui-agent-skill.LICENSE +21 -0
  5. package/.local/skills/h5-to-swiftui/SKILL.md +201 -0
  6. package/.local/skills/h5-to-swiftui/assets/calibration/README.md +176 -0
  7. package/.local/skills/h5-to-swiftui/assets/calibration/h5-twin/index.html +52 -0
  8. package/.local/skills/h5-to-swiftui/assets/calibration/h5-twin/style.css +133 -0
  9. package/.local/skills/h5-to-swiftui/assets/calibration/swiftui-twin/Package.swift +26 -0
  10. package/.local/skills/h5-to-swiftui/assets/calibration/swiftui-twin/Sources/CalibrationScreen/CalibrationScreen.swift +142 -0
  11. package/.local/skills/h5-to-swiftui/assets/calibration/swiftui-twin-divergent/Package.swift +32 -0
  12. package/.local/skills/h5-to-swiftui/assets/calibration/swiftui-twin-divergent/Sources/CalibrationScreenDivergent/CalibrationScreenDivergent.swift +122 -0
  13. package/.local/skills/h5-to-swiftui/assets/calibration/tokens.json +42 -0
  14. package/.local/skills/h5-to-swiftui/assets/sample-h5-react/index.html +14 -0
  15. package/.local/skills/h5-to-swiftui/assets/sample-h5-react/package.json +20 -0
  16. package/.local/skills/h5-to-swiftui/assets/sample-h5-react/public/api/articles/001.json +96 -0
  17. package/.local/skills/h5-to-swiftui/assets/sample-h5-react/public/api/articles/index.json +89 -0
  18. package/.local/skills/h5-to-swiftui/assets/sample-h5-react/src/App.jsx +22 -0
  19. package/.local/skills/h5-to-swiftui/assets/sample-h5-react/src/App.module.css +11 -0
  20. package/.local/skills/h5-to-swiftui/assets/sample-h5-react/src/components/ArticleCard.jsx +53 -0
  21. package/.local/skills/h5-to-swiftui/assets/sample-h5-react/src/components/ArticleCard.module.css +139 -0
  22. package/.local/skills/h5-to-swiftui/assets/sample-h5-react/src/components/NavBar.jsx +37 -0
  23. package/.local/skills/h5-to-swiftui/assets/sample-h5-react/src/components/NavBar.module.css +72 -0
  24. package/.local/skills/h5-to-swiftui/assets/sample-h5-react/src/components/TagCloud.jsx +30 -0
  25. package/.local/skills/h5-to-swiftui/assets/sample-h5-react/src/components/TagCloud.module.css +50 -0
  26. package/.local/skills/h5-to-swiftui/assets/sample-h5-react/src/components/TrendChart.jsx +159 -0
  27. package/.local/skills/h5-to-swiftui/assets/sample-h5-react/src/components/TrendChart.module.css +21 -0
  28. package/.local/skills/h5-to-swiftui/assets/sample-h5-react/src/main.jsx +12 -0
  29. package/.local/skills/h5-to-swiftui/assets/sample-h5-react/src/screens/ArticleScreen.jsx +182 -0
  30. package/.local/skills/h5-to-swiftui/assets/sample-h5-react/src/screens/ArticleScreen.module.css +294 -0
  31. package/.local/skills/h5-to-swiftui/assets/sample-h5-react/src/screens/FeedScreen.jsx +147 -0
  32. package/.local/skills/h5-to-swiftui/assets/sample-h5-react/src/screens/FeedScreen.module.css +161 -0
  33. package/.local/skills/h5-to-swiftui/assets/sample-h5-react/src/styles/global.css +50 -0
  34. package/.local/skills/h5-to-swiftui/assets/sample-h5-react/src/styles/tokens.css +103 -0
  35. package/.local/skills/h5-to-swiftui/assets/sample-h5-react/vite.config.js +6 -0
  36. package/.local/skills/h5-to-swiftui/assets/sample-h5-vanilla/data/tasks.js +67 -0
  37. package/.local/skills/h5-to-swiftui/assets/sample-h5-vanilla/index.html +26 -0
  38. package/.local/skills/h5-to-swiftui/assets/sample-h5-vanilla/router.js +73 -0
  39. package/.local/skills/h5-to-swiftui/assets/sample-h5-vanilla/screens/detail.js +164 -0
  40. package/.local/skills/h5-to-swiftui/assets/sample-h5-vanilla/screens/home.js +53 -0
  41. package/.local/skills/h5-to-swiftui/assets/sample-h5-vanilla/screens/list.js +87 -0
  42. package/.local/skills/h5-to-swiftui/assets/sample-h5-vanilla/styles/app.css +342 -0
  43. package/.local/skills/h5-to-swiftui/assets/sample-h5-vanilla/styles/tokens.css +68 -0
  44. package/.local/skills/h5-to-swiftui/references/css-to-swiftui-map.md +205 -0
  45. package/.local/skills/h5-to-swiftui/references/design-token-extraction.md +209 -0
  46. package/.local/skills/h5-to-swiftui/references/high-risk-triage.md +209 -0
  47. package/.local/skills/h5-to-swiftui/references/render-equivalence-calibration.md +193 -0
  48. package/.local/skills/h5-to-swiftui/references/stack-detection.md +160 -0
  49. package/.local/skills/h5-to-swiftui/references/visual-diff-loop-protocol.md +365 -0
  50. package/.local/skills/h5-to-swiftui/scripts/_calib-consts.mjs +150 -0
  51. package/.local/skills/h5-to-swiftui/scripts/_imglib.mjs +547 -0
  52. package/.local/skills/h5-to-swiftui/scripts/_provenance.mjs +123 -0
  53. package/.local/skills/h5-to-swiftui/scripts/calibrate-render.mjs +625 -0
  54. package/.local/skills/h5-to-swiftui/scripts/capture-reference.mjs +386 -0
  55. package/.local/skills/h5-to-swiftui/scripts/detect-stack.mjs +305 -0
  56. package/.local/skills/h5-to-swiftui/scripts/evaluate-convergence.mjs +1093 -0
  57. package/.local/skills/h5-to-swiftui/scripts/extract-tokens.mjs +600 -0
  58. package/.local/skills/h5-to-swiftui/scripts/mark-overlay.mjs +379 -0
  59. package/.local/skills/h5-to-swiftui/scripts/pixel-diff.mjs +530 -0
  60. package/.local/skills/h5-to-swiftui/scripts/sim-screenshot.sh +544 -0
  61. package/.local/skills/ios-debugger-agent/SKILL.md +51 -0
  62. package/.local/skills/ios-debugger-agent/agents/openai.yaml +4 -0
  63. package/.local/skills/swift-concurrency-expert/SKILL.md +105 -0
  64. package/.local/skills/swift-concurrency-expert/agents/openai.yaml +4 -0
  65. package/.local/skills/swift-concurrency-expert/references/approachable-concurrency.md +63 -0
  66. package/.local/skills/swift-concurrency-expert/references/swift-6-2-concurrency.md +272 -0
  67. package/.local/skills/swift-concurrency-expert/references/swiftui-concurrency-tour-wwdc.md +33 -0
  68. package/.local/skills/swiftui-expert-skill/SKILL.md +162 -0
  69. package/.local/skills/swiftui-expert-skill/references/accessibility-patterns.md +215 -0
  70. package/.local/skills/swiftui-expert-skill/references/animation-advanced.md +403 -0
  71. package/.local/skills/swiftui-expert-skill/references/animation-basics.md +284 -0
  72. package/.local/skills/swiftui-expert-skill/references/animation-transitions.md +326 -0
  73. package/.local/skills/swiftui-expert-skill/references/charts-accessibility.md +135 -0
  74. package/.local/skills/swiftui-expert-skill/references/charts.md +602 -0
  75. package/.local/skills/swiftui-expert-skill/references/focus-patterns.md +299 -0
  76. package/.local/skills/swiftui-expert-skill/references/image-optimization.md +203 -0
  77. package/.local/skills/swiftui-expert-skill/references/latest-apis.md +488 -0
  78. package/.local/skills/swiftui-expert-skill/references/layout-best-practices.md +266 -0
  79. package/.local/skills/swiftui-expert-skill/references/liquid-glass.md +423 -0
  80. package/.local/skills/swiftui-expert-skill/references/list-patterns.md +446 -0
  81. package/.local/skills/swiftui-expert-skill/references/macos-scenes.md +318 -0
  82. package/.local/skills/swiftui-expert-skill/references/macos-views.md +357 -0
  83. package/.local/skills/swiftui-expert-skill/references/macos-window-styling.md +303 -0
  84. package/.local/skills/swiftui-expert-skill/references/performance-patterns.md +403 -0
  85. package/.local/skills/swiftui-expert-skill/references/scroll-patterns.md +293 -0
  86. package/.local/skills/swiftui-expert-skill/references/sheet-navigation-patterns.md +363 -0
  87. package/.local/skills/swiftui-expert-skill/references/state-management.md +388 -0
  88. package/.local/skills/swiftui-expert-skill/references/text-patterns.md +32 -0
  89. package/.local/skills/swiftui-expert-skill/references/trace-analysis.md +295 -0
  90. package/.local/skills/swiftui-expert-skill/references/trace-recording.md +134 -0
  91. package/.local/skills/swiftui-expert-skill/references/view-structure.md +780 -0
  92. package/.local/skills/swiftui-expert-skill/scripts/__pycache__/analyze_trace.cpython-313.pyc +0 -0
  93. package/.local/skills/swiftui-expert-skill/scripts/__pycache__/record_trace.cpython-313.pyc +0 -0
  94. package/.local/skills/swiftui-expert-skill/scripts/analyze_trace.py +301 -0
  95. package/.local/skills/swiftui-expert-skill/scripts/instruments_parser/__init__.py +1 -0
  96. package/.local/skills/swiftui-expert-skill/scripts/instruments_parser/__pycache__/__init__.cpython-313.pyc +0 -0
  97. package/.local/skills/swiftui-expert-skill/scripts/instruments_parser/__pycache__/causes.cpython-313.pyc +0 -0
  98. package/.local/skills/swiftui-expert-skill/scripts/instruments_parser/__pycache__/correlate.cpython-313.pyc +0 -0
  99. package/.local/skills/swiftui-expert-skill/scripts/instruments_parser/__pycache__/events.cpython-313.pyc +0 -0
  100. package/.local/skills/swiftui-expert-skill/scripts/instruments_parser/__pycache__/hangs.cpython-313.pyc +0 -0
  101. package/.local/skills/swiftui-expert-skill/scripts/instruments_parser/__pycache__/hitches.cpython-313.pyc +0 -0
  102. package/.local/skills/swiftui-expert-skill/scripts/instruments_parser/__pycache__/summary.cpython-313.pyc +0 -0
  103. package/.local/skills/swiftui-expert-skill/scripts/instruments_parser/__pycache__/swiftui.cpython-313.pyc +0 -0
  104. package/.local/skills/swiftui-expert-skill/scripts/instruments_parser/__pycache__/time_profiler.cpython-313.pyc +0 -0
  105. package/.local/skills/swiftui-expert-skill/scripts/instruments_parser/__pycache__/xctrace.cpython-313.pyc +0 -0
  106. package/.local/skills/swiftui-expert-skill/scripts/instruments_parser/__pycache__/xml_utils.cpython-313.pyc +0 -0
  107. package/.local/skills/swiftui-expert-skill/scripts/instruments_parser/causes.py +187 -0
  108. package/.local/skills/swiftui-expert-skill/scripts/instruments_parser/correlate.py +179 -0
  109. package/.local/skills/swiftui-expert-skill/scripts/instruments_parser/events.py +291 -0
  110. package/.local/skills/swiftui-expert-skill/scripts/instruments_parser/hangs.py +108 -0
  111. package/.local/skills/swiftui-expert-skill/scripts/instruments_parser/hitches.py +145 -0
  112. package/.local/skills/swiftui-expert-skill/scripts/instruments_parser/summary.py +243 -0
  113. package/.local/skills/swiftui-expert-skill/scripts/instruments_parser/swiftui.py +195 -0
  114. package/.local/skills/swiftui-expert-skill/scripts/instruments_parser/time_profiler.py +135 -0
  115. package/.local/skills/swiftui-expert-skill/scripts/instruments_parser/xctrace.py +117 -0
  116. package/.local/skills/swiftui-expert-skill/scripts/instruments_parser/xml_utils.py +224 -0
  117. package/.local/skills/swiftui-expert-skill/scripts/record_trace.py +252 -0
  118. package/.local/skills/swiftui-liquid-glass/SKILL.md +90 -0
  119. package/.local/skills/swiftui-liquid-glass/agents/openai.yaml +4 -0
  120. package/.local/skills/swiftui-liquid-glass/references/liquid-glass.md +280 -0
  121. package/.local/skills/swiftui-performance-audit/SKILL.md +106 -0
  122. package/.local/skills/swiftui-performance-audit/agents/openai.yaml +4 -0
  123. package/.local/skills/swiftui-performance-audit/references/code-smells.md +150 -0
  124. package/.local/skills/swiftui-performance-audit/references/demystify-swiftui-performance-wwdc23.md +46 -0
  125. package/.local/skills/swiftui-performance-audit/references/optimizing-swiftui-performance-instruments.md +29 -0
  126. package/.local/skills/swiftui-performance-audit/references/profiling-intake.md +44 -0
  127. package/.local/skills/swiftui-performance-audit/references/report-template.md +47 -0
  128. package/.local/skills/swiftui-performance-audit/references/understanding-hangs-in-your-app.md +33 -0
  129. package/.local/skills/swiftui-performance-audit/references/understanding-improving-swiftui-performance.md +52 -0
  130. package/.local/skills/swiftui-pro/SKILL.md +108 -0
  131. package/.local/skills/swiftui-pro/agents/openai.yaml +10 -0
  132. package/.local/skills/swiftui-pro/assets/swiftui-pro-icon.png +0 -0
  133. package/.local/skills/swiftui-pro/assets/swiftui-pro-icon.svg +29 -0
  134. package/.local/skills/swiftui-pro/references/accessibility.md +13 -0
  135. package/.local/skills/swiftui-pro/references/api.md +39 -0
  136. package/.local/skills/swiftui-pro/references/data.md +43 -0
  137. package/.local/skills/swiftui-pro/references/design.md +32 -0
  138. package/.local/skills/swiftui-pro/references/hygiene.md +9 -0
  139. package/.local/skills/swiftui-pro/references/navigation.md +14 -0
  140. package/.local/skills/swiftui-pro/references/performance.md +46 -0
  141. package/.local/skills/swiftui-pro/references/swift.md +56 -0
  142. package/.local/skills/swiftui-pro/references/views.md +36 -0
  143. package/.local/skills/swiftui-ui-patterns/SKILL.md +95 -0
  144. package/.local/skills/swiftui-ui-patterns/agents/openai.yaml +4 -0
  145. package/.local/skills/swiftui-ui-patterns/references/app-wiring.md +201 -0
  146. package/.local/skills/swiftui-ui-patterns/references/async-state.md +96 -0
  147. package/.local/skills/swiftui-ui-patterns/references/components-index.md +50 -0
  148. package/.local/skills/swiftui-ui-patterns/references/controls.md +57 -0
  149. package/.local/skills/swiftui-ui-patterns/references/deeplinks.md +66 -0
  150. package/.local/skills/swiftui-ui-patterns/references/focus.md +90 -0
  151. package/.local/skills/swiftui-ui-patterns/references/form.md +97 -0
  152. package/.local/skills/swiftui-ui-patterns/references/grids.md +71 -0
  153. package/.local/skills/swiftui-ui-patterns/references/haptics.md +71 -0
  154. package/.local/skills/swiftui-ui-patterns/references/input-toolbar.md +51 -0
  155. package/.local/skills/swiftui-ui-patterns/references/lightweight-clients.md +93 -0
  156. package/.local/skills/swiftui-ui-patterns/references/list.md +86 -0
  157. package/.local/skills/swiftui-ui-patterns/references/loading-placeholders.md +38 -0
  158. package/.local/skills/swiftui-ui-patterns/references/macos-settings.md +71 -0
  159. package/.local/skills/swiftui-ui-patterns/references/matched-transitions.md +59 -0
  160. package/.local/skills/swiftui-ui-patterns/references/media.md +73 -0
  161. package/.local/skills/swiftui-ui-patterns/references/menu-bar.md +101 -0
  162. package/.local/skills/swiftui-ui-patterns/references/navigationstack.md +159 -0
  163. package/.local/skills/swiftui-ui-patterns/references/overlay.md +45 -0
  164. package/.local/skills/swiftui-ui-patterns/references/performance.md +62 -0
  165. package/.local/skills/swiftui-ui-patterns/references/previews.md +48 -0
  166. package/.local/skills/swiftui-ui-patterns/references/scroll-reveal.md +133 -0
  167. package/.local/skills/swiftui-ui-patterns/references/scrollview.md +87 -0
  168. package/.local/skills/swiftui-ui-patterns/references/searchable.md +71 -0
  169. package/.local/skills/swiftui-ui-patterns/references/sheets.md +155 -0
  170. package/.local/skills/swiftui-ui-patterns/references/split-views.md +72 -0
  171. package/.local/skills/swiftui-ui-patterns/references/tabview.md +114 -0
  172. package/.local/skills/swiftui-ui-patterns/references/theming.md +71 -0
  173. package/.local/skills/swiftui-ui-patterns/references/title-menus.md +93 -0
  174. package/.local/skills/swiftui-ui-patterns/references/top-bar.md +49 -0
  175. package/.local/skills/swiftui-view-refactor/SKILL.md +202 -0
  176. package/.local/skills/swiftui-view-refactor/agents/openai.yaml +4 -0
  177. package/.local/skills/swiftui-view-refactor/references/mv-patterns.md +161 -0
  178. package/bundled/manifest.json +1 -1
  179. package/package.json +1 -1
@@ -0,0 +1,544 @@
1
+ #!/usr/bin/env bash
2
+ # sim-screenshot.sh — Stage 5: iOS Simulator render + capture for SwiftUI snapshot host
3
+ #
4
+ # Usage:
5
+ # sim-screenshot.sh --probe
6
+ # Print capability JSON to stdout and exit 0.
7
+ # { "schema":"h5-to-swiftui/simprobe@1", "xcode":bool, "simctl":bool,
8
+ # "xcodebuild":bool, "available_runtimes":[...],
9
+ # "stage5_ready":bool, "ok":bool }
10
+ # stage5_ready is true ONLY iff every required tool is present AND at
11
+ # least one simulator runtime is available — tools-present alone is
12
+ # misleading (you cannot capture without a runtime). ok mirrors
13
+ # stage5_ready. The probe itself always exits 0 (diagnostic only).
14
+ #
15
+ # sim-screenshot.sh --project <path> --scheme <scheme> --device "iPhone 15 Pro"
16
+ # --component <Name> --out <output.png>
17
+ # Build the snapshot host project, boot the simulator, capture the
18
+ # per-component snapshot and write it to <output.png>.
19
+ # Exit 0 on success.
20
+ #
21
+ # sim-screenshot.sh --help
22
+ # Print this usage and exit 0.
23
+ #
24
+ # Capability gate (no-fake spine):
25
+ # If xcrun simctl or xcodebuild is unavailable, the build fails, OR the
26
+ # --project path does not exist (cannot yield a build artifact), writes
27
+ # blocked.json next to --out and exits 3.
28
+ # Build failure NEVER produces a PNG. No fake convergence. Only pure usage
29
+ # errors (missing required flags) exit 1.
30
+ #
31
+ # Simulator selection:
32
+ # The first available runtime for the requested device model is used.
33
+ # "Available" means listed by xcrun simctl list devices --json. If multiple
34
+ # runtimes match, the highest-version one is selected (sort -r on the
35
+ # runtime identifier, which is lexicographically ordered by version).
36
+ # The selected runtime and device UDID are recorded in the blocked.json on
37
+ # failure and in a companion .meta.json on success.
38
+ #
39
+ # Dependencies:
40
+ # xcrun (Xcode command-line tools), simctl, xcodebuild
41
+ # All are checked at runtime; missing tools => blocked.json + exit 3.
42
+ #
43
+ # Exit codes:
44
+ # 0 -- success (PNG written) OR probe completed OR --help
45
+ # 1 -- pure usage error (missing required flags)
46
+ # 3 -- capability gate: no-xcode | build-failed | no-runtime |
47
+ # project-missing | capture-failed (blocked.json written)
48
+ #
49
+ # POSIX bash; set -euo pipefail.
50
+
51
+ set -euo pipefail
52
+
53
+ # ── Constants ─────────────────────────────────────────────────────────────────
54
+
55
+ SCHEMA_BLOCKED="h5-to-swiftui/blocked@1"
56
+ SCHEMA_PROBE="h5-to-swiftui/simprobe@1"
57
+ STAGE="5"
58
+
59
+ # ── Helpers ───────────────────────────────────────────────────────────────────
60
+
61
+ die() {
62
+ echo "Error: $*" >&2
63
+ exit 1
64
+ }
65
+
66
+ # Write blocked.json next to --out path.
67
+ # $1 out_path $2 component $3 reason
68
+ # $4.. optional extra fields, each as a literal "key=value" token; every
69
+ # extra is emitted as its own JSON string line (valid + consistent
70
+ # with the probe/meta artifacts — no same-line concatenation).
71
+ write_blocked() {
72
+ local out_path="$1"
73
+ local component="$2"
74
+ local reason="$3"
75
+ shift 3
76
+
77
+ local blocked_path
78
+ blocked_path="$(dirname "$out_path")/blocked.json"
79
+
80
+ # Base fields, one key per line.
81
+ {
82
+ printf '{\n'
83
+ printf ' "schema": "%s",\n' "$SCHEMA_BLOCKED"
84
+ printf ' "stage": "%s",\n' "$STAGE"
85
+ printf ' "component": "%s",\n' "$component"
86
+ # reason is last UNLESS extras follow; emit comma conditionally.
87
+ if [ "$#" -gt 0 ]; then
88
+ printf ' "reason": "%s",\n' "$reason"
89
+ local n=$#
90
+ local idx=0
91
+ local pair key val
92
+ for pair in "$@"; do
93
+ idx=$((idx + 1))
94
+ key="${pair%%=*}"
95
+ val="${pair#*=}"
96
+ if [ "$idx" -lt "$n" ]; then
97
+ printf ' "%s": "%s",\n' "$key" "$val"
98
+ else
99
+ printf ' "%s": "%s"\n' "$key" "$val"
100
+ fi
101
+ done
102
+ else
103
+ printf ' "reason": "%s"\n' "$reason"
104
+ fi
105
+ printf '}\n'
106
+ } > "$blocked_path"
107
+
108
+ echo "Wrote: $blocked_path" >&2
109
+ }
110
+
111
+ # Check whether a command exists on PATH
112
+ have_cmd() {
113
+ command -v "$1" > /dev/null 2>&1
114
+ }
115
+
116
+ # ── Probe mode ────────────────────────────────────────────────────────────────
117
+
118
+ do_probe() {
119
+ local has_xcode=false
120
+ local has_simctl=false
121
+ local has_xcodebuild=false
122
+ local runtimes_json='[]'
123
+
124
+ if have_cmd xcrun; then
125
+ has_xcode=true
126
+
127
+ # simctl
128
+ if xcrun simctl help > /dev/null 2>&1; then
129
+ has_simctl=true
130
+
131
+ # Collect available runtimes (name field where isAvailable=true).
132
+ # Use awk for POSIX portability; store the program in a variable to
133
+ # avoid single-quote nesting issues.
134
+ local raw
135
+ raw="$(xcrun simctl list runtimes --json 2>/dev/null || printf '{}')"
136
+
137
+ # awk program: emit JSON array of runtime name strings
138
+ local awk_prog
139
+ awk_prog='BEGIN { is_avail=0; name=""; first=1; printf "[" }
140
+ /"isAvailable"[[:space:]]*:[[:space:]]*true/ { is_avail=1 }
141
+ /"name"[[:space:]]*:/ {
142
+ n=split($0,a,"\""); for(i=1;i<=n;i++) { if(a[i]=="name") { name=a[i+2]; break } }
143
+ }
144
+ /^[[:space:]]*\}/ {
145
+ if (is_avail && name != "") {
146
+ if (!first) printf ","
147
+ printf "\"%s\"", name
148
+ first=0
149
+ }
150
+ is_avail=0; name=""
151
+ }
152
+ END { printf "]\n" }'
153
+
154
+ runtimes_json="$(printf '%s' "$raw" | awk "$awk_prog" 2>/dev/null || printf '[]')"
155
+ fi
156
+
157
+ # xcodebuild
158
+ if xcrun xcodebuild -version > /dev/null 2>&1; then
159
+ has_xcodebuild=true
160
+ fi
161
+ fi
162
+
163
+ # Tools present?
164
+ local tools_present=true
165
+ if [ "$has_xcode" = "false" ] || [ "$has_simctl" = "false" ] || [ "$has_xcodebuild" = "false" ]; then
166
+ tools_present=false
167
+ fi
168
+
169
+ # At least one runtime available? (runtimes_json is "[]" when none)
170
+ local has_runtime=false
171
+ if [ "$runtimes_json" != "[]" ] && [ -n "$runtimes_json" ]; then
172
+ has_runtime=true
173
+ fi
174
+
175
+ # stage5_ready: tools AND >=1 runtime. Tools-present alone is misleading —
176
+ # a capture cannot happen without a runtime, so ok must reflect that.
177
+ local stage5_ready=false
178
+ if [ "$tools_present" = "true" ] && [ "$has_runtime" = "true" ]; then
179
+ stage5_ready=true
180
+ fi
181
+
182
+ printf '{\n "schema": "%s",\n "xcode": %s,\n "simctl": %s,\n "xcodebuild": %s,\n "available_runtimes": %s,\n "stage5_ready": %s,\n "ok": %s\n}\n' \
183
+ "$SCHEMA_PROBE" \
184
+ "$has_xcode" \
185
+ "$has_simctl" \
186
+ "$has_xcodebuild" \
187
+ "$runtimes_json" \
188
+ "$stage5_ready" \
189
+ "$stage5_ready"
190
+
191
+ exit 0
192
+ }
193
+
194
+ # ── Capability check (for non-probe modes) ────────────────────────────────────
195
+
196
+ # Returns 0 if all required tools are present, sets BLOCK_REASON on failure.
197
+ BLOCK_REASON=""
198
+ check_capabilities() {
199
+ if ! have_cmd xcrun; then
200
+ BLOCK_REASON="no-xcode"
201
+ return 1
202
+ fi
203
+ if ! xcrun simctl help > /dev/null 2>&1; then
204
+ BLOCK_REASON="no-xcode"
205
+ return 1
206
+ fi
207
+ if ! xcrun xcodebuild -version > /dev/null 2>&1; then
208
+ BLOCK_REASON="no-xcode"
209
+ return 1
210
+ fi
211
+ return 0
212
+ }
213
+
214
+ # ── Runtime + device selection ────────────────────────────────────────────────
215
+
216
+ # Finds the best available simulator for the requested device model.
217
+ # Outputs: <runtime_identifier>|<udid> (single line, highest version first)
218
+ # Returns 1 (empty output) if no matching device/runtime is found.
219
+ find_simulator() {
220
+ local device_model="$1" # e.g. "iPhone 15 Pro"
221
+
222
+ # List all available devices as JSON
223
+ local raw
224
+ raw="$(xcrun simctl list devices --json 2>/dev/null || printf '{}')"
225
+
226
+ # awk program stored in variable to avoid single-quote quoting issues.
227
+ # Walk the JSON; track current runtime key; for each device entry matching
228
+ # device_model with isAvailable=true, emit "runtime|udid".
229
+ local awk_prog
230
+ awk_prog='BEGIN { cur_rt=""; cur_name=""; cur_udid=""; cur_avail=0 }
231
+ /^[[:space:]]*"com\.apple\.CoreSimulator\.SimRuntime\./ {
232
+ n=split($0,a,"\""); for(i=1;i<=n;i++) {
233
+ if(a[i] ~ /^com\.apple\.CoreSimulator\.SimRuntime\./) { cur_rt=a[i]; break }
234
+ }
235
+ cur_name=""; cur_udid=""; cur_avail=0
236
+ }
237
+ /"name"[[:space:]]*:/ {
238
+ n=split($0,a,"\""); for(i=1;i<=n;i++) { if(a[i]=="name") { cur_name=a[i+2]; break } }
239
+ }
240
+ /"udid"[[:space:]]*:/ {
241
+ n=split($0,a,"\""); for(i=1;i<=n;i++) { if(a[i]=="udid") { cur_udid=a[i+2]; break } }
242
+ }
243
+ /"isAvailable"[[:space:]]*:[[:space:]]*true/ { cur_avail=1 }
244
+ /^[[:space:]]*\}/ {
245
+ if (cur_avail && cur_name==model && cur_udid!="") {
246
+ print cur_rt "|" cur_udid
247
+ }
248
+ cur_avail=0; cur_name=""; cur_udid=""
249
+ }'
250
+
251
+ printf '%s' "$raw" | awk -v model="$device_model" "$awk_prog" | sort -r | head -1
252
+ }
253
+
254
+ # ── Build snapshot host ───────────────────────────────────────────────────────
255
+
256
+ build_snapshot_host() {
257
+ local project_path="$1"
258
+ local scheme="$2"
259
+ local sdk="$3" # e.g. "iphonesimulator"
260
+ local destination="$4" # xcodebuild -destination value
261
+ local build_log="$5"
262
+
263
+ xcrun xcodebuild \
264
+ -project "$project_path" \
265
+ -scheme "$scheme" \
266
+ -sdk "$sdk" \
267
+ -destination "$destination" \
268
+ -configuration Debug \
269
+ build \
270
+ > "$build_log" 2>&1
271
+ }
272
+
273
+ # ── Main capture flow ─────────────────────────────────────────────────────────
274
+
275
+ do_capture() {
276
+ local project_path="$1"
277
+ local scheme="$2"
278
+ local device_model="$3"
279
+ local component="$4"
280
+ local out_png="$5"
281
+
282
+ local out_dir
283
+ out_dir="$(dirname "$out_png")"
284
+ mkdir -p "$out_dir"
285
+
286
+ # 1. Capability gate
287
+ if ! check_capabilities; then
288
+ echo "Error: required toolchain unavailable: $BLOCK_REASON" >&2
289
+ echo "Install Xcode and command-line tools, then re-run." >&2
290
+ write_blocked "$out_png" "$component" "$BLOCK_REASON"
291
+ exit 3
292
+ fi
293
+
294
+ # 2. Find simulator
295
+ echo "Looking for simulator: $device_model" >&2
296
+ local sim_info
297
+ sim_info="$(find_simulator "$device_model" || true)"
298
+
299
+ if [ -z "$sim_info" ]; then
300
+ echo "Error: no available simulator found for device \"$device_model\"." >&2
301
+ echo "Run: xcrun simctl list devices" >&2
302
+ write_blocked "$out_png" "$component" "no-runtime" \
303
+ "device=$device_model"
304
+ exit 3
305
+ fi
306
+
307
+ local runtime_id udid
308
+ runtime_id="${sim_info%%|*}"
309
+ udid="${sim_info##*|}"
310
+
311
+ echo "Selected runtime: $runtime_id" >&2
312
+ echo "Selected UDID: $udid" >&2
313
+
314
+ # Extract human-readable runtime name from the identifier
315
+ # e.g. com.apple.CoreSimulator.SimRuntime.iOS-17-5 -> iOS 17.5
316
+ local runtime_name
317
+ runtime_name="$(printf '%s' "$runtime_id" | sed -E 's/.*\.iOS-([0-9]+)-([0-9]+)$/iOS \1.\2/')"
318
+ echo "Runtime name: $runtime_name" >&2
319
+
320
+ # 3. Build the snapshot host project
321
+ echo "Building $scheme in $project_path ..." >&2
322
+ local build_log
323
+ build_log="$(mktemp /tmp/sim-screenshot-build.XXXXXX.log)"
324
+
325
+ local sdk="iphonesimulator"
326
+ local destination="platform=iOS Simulator,id=$udid"
327
+
328
+ if ! build_snapshot_host "$project_path" "$scheme" "$sdk" "$destination" "$build_log"; then
329
+ echo "Error: xcodebuild failed. Build log: $build_log" >&2
330
+ echo "--- Last 20 lines of build log ---" >&2
331
+ tail -20 "$build_log" >&2
332
+ echo "----------------------------------" >&2
333
+ write_blocked "$out_png" "$component" "build-failed" \
334
+ "build_log=$build_log" "runtime=$runtime_name" "udid=$udid"
335
+ # NEVER produce a png on build failure
336
+ exit 3
337
+ fi
338
+
339
+ echo "Build succeeded." >&2
340
+ rm -f "$build_log"
341
+
342
+ # 4. Boot simulator (idempotent -- already booted is fine)
343
+ echo "Booting simulator $udid ..." >&2
344
+
345
+ # Check current sim state using awk (stored in variable to avoid quoting issues)
346
+ local awk_state
347
+ awk_state='BEGIN { found=0 }
348
+ /"udid"/ { if ($0 ~ udid) found=1 }
349
+ /"state"/ {
350
+ if (found) {
351
+ n=split($0,a,"\""); for(i=1;i<=n;i++) { if(a[i]=="state") { print a[i+2]; found=0; break } }
352
+ }
353
+ }'
354
+ local boot_status
355
+ boot_status="$(xcrun simctl list devices --json 2>/dev/null | \
356
+ awk -v udid="$udid" "$awk_state" | head -1 || true)"
357
+
358
+ if [ "$boot_status" != "Booted" ]; then
359
+ xcrun simctl boot "$udid" 2>&1 | sed 's/^/ [simctl boot] /' >&2 || true
360
+ # Wait for boot completion (bootstatus blocks until the sim is ready)
361
+ xcrun simctl bootstatus "$udid" -b >&2 || true
362
+ else
363
+ echo "Simulator already booted." >&2
364
+ fi
365
+
366
+ # 5. Launch the app / snapshot host
367
+ # The snapshot host is expected to write a PNG when launched with the
368
+ # component name as a launch argument. We launch it, wait for render,
369
+ # then capture with simctl io screenshot.
370
+ local bundle_id="$scheme"
371
+
372
+ echo "Launching snapshot host for component: $component ..." >&2
373
+ if ! xcrun simctl launch "$udid" "$bundle_id" \
374
+ --component "$component" \
375
+ 2>&1 | sed 's/^/ [simctl launch] /' >&2; then
376
+ echo "Error: simctl launch failed for bundle $bundle_id on $udid." >&2
377
+ write_blocked "$out_png" "$component" "build-failed" \
378
+ "detail=simctl launch failed" "bundle_id=$bundle_id" "runtime=$runtime_name" "udid=$udid"
379
+ exit 3
380
+ fi
381
+
382
+ # Give the app time to render the snapshot
383
+ sleep 2
384
+
385
+ # 6. Capture screenshot via simctl io
386
+ echo "Capturing screenshot from simulator ..." >&2
387
+ if ! xcrun simctl io "$udid" screenshot "$out_png" 2>&1 | sed 's/^/ [simctl io] /' >&2; then
388
+ echo "Error: simctl io screenshot failed." >&2
389
+ write_blocked "$out_png" "$component" "build-failed" \
390
+ "detail=simctl io screenshot failed" "runtime=$runtime_name" "udid=$udid"
391
+ exit 3
392
+ fi
393
+
394
+ if [ ! -f "$out_png" ]; then
395
+ echo "Error: screenshot not found at $out_png after capture." >&2
396
+ write_blocked "$out_png" "$component" "build-failed" \
397
+ "detail=output PNG not produced" "runtime=$runtime_name" "udid=$udid"
398
+ exit 3
399
+ fi
400
+
401
+ # 7. Write companion .meta.json
402
+ local meta_path="${out_png%.png}.meta.json"
403
+ local ts
404
+ ts="$(date -u +%Y-%m-%dT%H:%M:%SZ)"
405
+ printf '{\n "schema": "h5-to-swiftui/simsnapshot@1",\n "component": "%s",\n "device": "%s",\n "runtime": "%s",\n "udid": "%s",\n "png": "%s",\n "captured_at": "%s"\n}\n' \
406
+ "$component" "$device_model" "$runtime_name" "$udid" "$out_png" "$ts" > "$meta_path"
407
+
408
+ echo "Screenshot: $out_png" >&2
409
+ echo "Meta: $meta_path" >&2
410
+ echo "Capture complete." >&2
411
+ exit 0
412
+ }
413
+
414
+ # ── CLI dispatch ──────────────────────────────────────────────────────────────
415
+
416
+ if [ $# -eq 0 ]; then
417
+ echo "Error: no arguments given. Run with --help for usage." >&2
418
+ exit 1
419
+ fi
420
+
421
+ # Handle --help first (before set -e touches anything)
422
+ for arg in "$@"; do
423
+ if [ "$arg" = "--help" ] || [ "$arg" = "-h" ]; then
424
+ printf '%s\n' \
425
+ "sim-screenshot.sh -- Stage 5: iOS Simulator render + capture" \
426
+ "" \
427
+ "Usage:" \
428
+ " sim-screenshot.sh --probe" \
429
+ " Print capability JSON to stdout and exit 0. The JSON includes" \
430
+ " stage5_ready (true iff tools present AND >=1 runtime); ok mirrors" \
431
+ " stage5_ready — tools-present alone is NOT enough to capture." \
432
+ "" \
433
+ " sim-screenshot.sh --project <path> --scheme <scheme> \\" \
434
+ " --device \"iPhone 15 Pro\" \\" \
435
+ " --component <Name> --out <output.png>" \
436
+ " Build the snapshot host, boot the simulator, capture the per-component" \
437
+ " snapshot, and write it to <output.png>. Exit 0 on success." \
438
+ "" \
439
+ " sim-screenshot.sh --help" \
440
+ " Print this usage and exit 0." \
441
+ "" \
442
+ "Arguments (capture mode):" \
443
+ " --project <path> Path to the .xcodeproj snapshot host project (required)" \
444
+ " --scheme <scheme> Xcode scheme to build; also used as the app bundle ID (required)" \
445
+ " --device <name> Device model, e.g. \"iPhone 15 Pro\" (required)" \
446
+ " --component <Name> SwiftUI component name to snapshot (required)" \
447
+ " --out <path> Output PNG path (required)" \
448
+ "" \
449
+ "Capability gate (no-fake spine):" \
450
+ " If xcrun simctl/xcodebuild is unavailable, the build fails, OR the" \
451
+ " --project path does not exist (cannot yield a build artifact), this" \
452
+ " writes blocked.json next to --out and exits 3. Build failure NEVER" \
453
+ " produces a PNG. Only pure usage errors (missing required flags) exit 1." \
454
+ "" \
455
+ "Simulator selection:" \
456
+ " The highest-version available runtime matching the requested device model" \
457
+ " is selected via xcrun simctl list devices --json. The selection is" \
458
+ " recorded in the .meta.json companion file written on success." \
459
+ "" \
460
+ "Exit codes:" \
461
+ " 0 Success (PNG written) or probe completed" \
462
+ " 1 Pure usage error (missing required flags)" \
463
+ " 3 Capability gate: no-xcode | build-failed | no-runtime |" \
464
+ " project-missing | capture-failed (blocked.json written)" \
465
+ "" \
466
+ "Examples:" \
467
+ " sim-screenshot.sh --probe" \
468
+ " sim-screenshot.sh --project SnapshotHost.xcodeproj \\" \
469
+ " --scheme com.example.SnapshotHost \\" \
470
+ " --device \"iPhone 15 Pro\" \\" \
471
+ " --component ProductCard \\" \
472
+ " --out artifacts/ProductCard.png"
473
+ exit 0
474
+ fi
475
+ done
476
+
477
+ # Handle --probe
478
+ for arg in "$@"; do
479
+ if [ "$arg" = "--probe" ]; then
480
+ do_probe
481
+ # do_probe calls exit 0 internally
482
+ fi
483
+ done
484
+
485
+ # Parse capture-mode arguments
486
+ PROJECT_PATH=""
487
+ SCHEME=""
488
+ DEVICE_MODEL=""
489
+ COMPONENT=""
490
+ OUT_PNG=""
491
+
492
+ while [ $# -gt 0 ]; do
493
+ case "$1" in
494
+ --project)
495
+ [ $# -ge 2 ] || die "--project requires an argument."
496
+ PROJECT_PATH="$2"; shift 2 ;;
497
+ --scheme)
498
+ [ $# -ge 2 ] || die "--scheme requires an argument."
499
+ SCHEME="$2"; shift 2 ;;
500
+ --device)
501
+ [ $# -ge 2 ] || die "--device requires an argument."
502
+ DEVICE_MODEL="$2"; shift 2 ;;
503
+ --component)
504
+ [ $# -ge 2 ] || die "--component requires an argument."
505
+ COMPONENT="$2"; shift 2 ;;
506
+ --out)
507
+ [ $# -ge 2 ] || die "--out requires an argument."
508
+ OUT_PNG="$2"; shift 2 ;;
509
+ --sim-runtime|--browser|--model-id)
510
+ # Accepted but unused in capture mode (informational flags for callers)
511
+ shift 2 ;;
512
+ *)
513
+ die "Unknown argument: $1. Run with --help for usage." ;;
514
+ esac
515
+ done
516
+
517
+ # Validate required capture-mode args
518
+ MISSING_ARGS=""
519
+ [ -z "$PROJECT_PATH" ] && MISSING_ARGS="$MISSING_ARGS --project"
520
+ [ -z "$SCHEME" ] && MISSING_ARGS="$MISSING_ARGS --scheme"
521
+ [ -z "$DEVICE_MODEL" ] && MISSING_ARGS="$MISSING_ARGS --device"
522
+ [ -z "$COMPONENT" ] && MISSING_ARGS="$MISSING_ARGS --component"
523
+ [ -z "$OUT_PNG" ] && MISSING_ARGS="$MISSING_ARGS --out"
524
+
525
+ if [ -n "$MISSING_ARGS" ]; then
526
+ echo "Error: missing required arguments:$MISSING_ARGS" >&2
527
+ echo "Run with --help for usage." >&2
528
+ exit 1
529
+ fi
530
+
531
+ # A --project that does not exist is a capture-mode path that cannot yield a
532
+ # build artifact. It MUST go through the no-fake guarantee: write_blocked
533
+ # (stage 5, reason project-missing) and exit 3 — never a bare exit 1, which
534
+ # would bypass the no-fake-success spine. (Pure usage errors above still exit 1.)
535
+ if [ ! -e "$PROJECT_PATH" ]; then
536
+ echo "Error: --project not found: $PROJECT_PATH" >&2
537
+ echo "Cannot produce a build artifact — blocking (no fake success)." >&2
538
+ mkdir -p "$(dirname "$OUT_PNG")"
539
+ write_blocked "$OUT_PNG" "$COMPONENT" "project-missing" \
540
+ "detail=--project path does not exist" "project=$PROJECT_PATH"
541
+ exit 3
542
+ fi
543
+
544
+ do_capture "$PROJECT_PATH" "$SCHEME" "$DEVICE_MODEL" "$COMPONENT" "$OUT_PNG"
@@ -0,0 +1,51 @@
1
+ ---
2
+ name: ios-debugger-agent
3
+ description: Use XcodeBuildMCP to build, run, launch, and debug the current iOS project on a booted simulator. Trigger when asked to run an iOS app, interact with the simulator UI, inspect on-screen state, capture logs/console output, or diagnose runtime behavior using XcodeBuildMCP tools.
4
+ ---
5
+
6
+ # iOS Debugger Agent
7
+
8
+ ## Overview
9
+ Use XcodeBuildMCP to build and run the current project scheme on a booted iOS simulator, interact with the UI, and capture logs. Prefer the MCP tools for simulator control, logs, and view inspection.
10
+
11
+ ## Core Workflow
12
+ Follow this sequence unless the user asks for a narrower action.
13
+
14
+ ### 1) Discover the booted simulator
15
+ - Call `mcp__XcodeBuildMCP__list_sims` and select the simulator with state `Booted`.
16
+ - If none are booted, ask the user to boot one (do not boot automatically unless asked).
17
+
18
+ ### 2) Set session defaults
19
+ - Call `mcp__XcodeBuildMCP__session-set-defaults` with:
20
+ - `projectPath` or `workspacePath` (whichever the repo uses)
21
+ - `scheme` for the current app
22
+ - `simulatorId` from the booted device
23
+ - Optional: `configuration: "Debug"`, `useLatestOS: true`
24
+
25
+ ### 3) Build + run (when requested)
26
+ - Call `mcp__XcodeBuildMCP__build_run_sim`.
27
+ - **If the build fails**, check the error output and retry (optionally with `preferXcodebuild: true`) or escalate to the user before attempting any UI interaction.
28
+ - **After a successful build**, verify the app launched by calling `mcp__XcodeBuildMCP__describe_ui` or `mcp__XcodeBuildMCP__screenshot` before proceeding to UI interaction.
29
+ - If the app is already built and only launch is requested, use `mcp__XcodeBuildMCP__launch_app_sim`.
30
+ - If bundle id is unknown:
31
+ 1) `mcp__XcodeBuildMCP__get_sim_app_path`
32
+ 2) `mcp__XcodeBuildMCP__get_app_bundle_id`
33
+
34
+ ## UI Interaction & Debugging
35
+ Use these when asked to inspect or interact with the running app.
36
+
37
+ - **Describe UI**: `mcp__XcodeBuildMCP__describe_ui` before tapping or swiping.
38
+ - **Tap**: `mcp__XcodeBuildMCP__tap` (prefer `id` or `label`; use coordinates only if needed).
39
+ - **Type**: `mcp__XcodeBuildMCP__type_text` after focusing a field.
40
+ - **Gestures**: `mcp__XcodeBuildMCP__gesture` for common scrolls and edge swipes.
41
+ - **Screenshot**: `mcp__XcodeBuildMCP__screenshot` for visual confirmation.
42
+
43
+ ## Logs & Console Output
44
+ - Start logs: `mcp__XcodeBuildMCP__start_sim_log_cap` with the app bundle id.
45
+ - Stop logs: `mcp__XcodeBuildMCP__stop_sim_log_cap` and summarize important lines.
46
+ - For console output, set `captureConsole: true` and relaunch if required.
47
+
48
+ ## Troubleshooting
49
+ - If build fails, ask whether to retry with `preferXcodebuild: true`.
50
+ - If the wrong app launches, confirm the scheme and bundle id.
51
+ - If UI elements are not hittable, re-run `describe_ui` after layout changes.
@@ -0,0 +1,4 @@
1
+ interface:
2
+ display_name: "iOS Debugger Agent"
3
+ short_description: "Debug iOS apps on Simulator"
4
+ default_prompt: "Use $ios-debugger-agent to build, launch, and inspect the current iOS app on the booted simulator."