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,295 @@
1
+ # Instruments Trace Analysis
2
+
3
+ Use this reference whenever the user references an Xcode Instruments `.trace`
4
+ file. A target SwiftUI source file is **optional** — if provided, you can
5
+ cite specific lines; without one, the trace still surfaces view names,
6
+ hot symbols, and high-severity events that tell the user where to look.
7
+
8
+ The bundled parser reads five lanes for SwiftUI responsiveness (Time
9
+ Profiler, Hangs, Animation Hitches, SwiftUI updates, and the SwiftUI
10
+ cause graph) and exposes three discovery modes (`--list-logs`,
11
+ `--list-signposts`, `--fanin-for`) plus a `--window` flag so the agent
12
+ can focus analysis on a precise slice of the trace.
13
+
14
+ ## When to invoke
15
+
16
+ Any of these signals:
17
+
18
+ - Message contains a path ending in `.trace`.
19
+ - User mentions "hangs", "hitches", "jank", "slow view", or performance
20
+ issues alongside an Instruments recording.
21
+ - User asks to focus analysis "after / before / between / during" a log
22
+ message or signpost.
23
+
24
+ Triggering does **not** require a SwiftUI source file. If one is present
25
+ you'll ground recommendations in specific lines; if not, base them on the
26
+ view names and symbols the trace reveals.
27
+
28
+ ## The three CLI modes
29
+
30
+ The scripts live alongside this skill at `scripts/` and need only the
31
+ Python 3 stdlib + `xctrace` (ships with Xcode at `/usr/bin/xctrace`).
32
+
33
+ ### 1. Full analysis (default)
34
+
35
+ ```bash
36
+ python3 "${SKILL_DIR}/scripts/analyze_trace.py" \
37
+ --trace "/path/to/file.trace" \
38
+ --top 10 --top-hitches 5 \
39
+ [--window START_MS:END_MS] \
40
+ --json-only
41
+ ```
42
+
43
+ - `--json-only` gives you structured data; omit for JSON + markdown
44
+ summary; `--markdown-only` is for pasting a digest into the chat.
45
+ - `--output <path>` writes `<path>.json` and `<path>.md` instead of stdout.
46
+ - `--window START_MS:END_MS` (optional) restricts every lane and every
47
+ correlation to that time slice.
48
+ - `--run N` selects a specific run when the trace contains more than one
49
+ recording session. Single-run traces don't need it; multi-run traces
50
+ require it and will error with the available run numbers if omitted.
51
+ Use `--list-runs` to dump per-run metadata (template, duration,
52
+ start/end dates, schemas) before analyzing.
53
+
54
+ ### 2. `--list-logs` — find os_log timestamps
55
+
56
+ ```bash
57
+ python3 "${SKILL_DIR}/scripts/analyze_trace.py" --trace <path> --list-logs \
58
+ [--log-subsystem com.myapp.net] \
59
+ [--log-category "Network"] \
60
+ [--log-type Fault] \
61
+ [--log-message-contains "loaded feed"] \
62
+ [--log-limit 10] \
63
+ [--window START_MS:END_MS]
64
+ ```
65
+
66
+ Returns JSON `{ "logs": [...], "count": N }` where each log entry includes
67
+ `time_ms`, `type`, `subsystem`, `category`, `process`, and the formatted
68
+ `message` (with args substituted) + raw `format_string`. All filters are
69
+ AND-combined; `--log-message-contains` is case-insensitive substring match.
70
+
71
+ ### 3. `--list-signposts` — find signpost intervals
72
+
73
+ ```bash
74
+ python3 "${SKILL_DIR}/scripts/analyze_trace.py" --trace <path> --list-signposts \
75
+ [--signpost-name-contains "ImageDecode"] \
76
+ [--signpost-subsystem com.myapp.feed] \
77
+ [--signpost-category "Rendering"] \
78
+ [--window START_MS:END_MS]
79
+ ```
80
+
81
+ Returns JSON `{ "intervals": [...], "events": [...] }`. Intervals are
82
+ paired `begin`/`end` signposts with `start_ms`, `end_ms`, `duration_ms`,
83
+ `name`, `subsystem`, `category`, `process`, `signpost_id`. Single-point
84
+ events (and any unpaired begins) go into `events`. All filters are
85
+ AND-combined; `--signpost-name-contains` is case-insensitive substring
86
+ match.
87
+
88
+ ### 4. `--fanin-for` — who keeps invalidating this view?
89
+
90
+ ```bash
91
+ python3 "${SKILL_DIR}/scripts/analyze_trace.py" --trace <path> \
92
+ --fanin-for "TextStyleModifier" \
93
+ [--window START_MS:END_MS] \
94
+ [--top 10]
95
+ ```
96
+
97
+ Returns JSON `{ "matches": [...] }`. Each match names a destination node
98
+ whose fmt string contains the substring (case-insensitive) and lists its
99
+ top incoming source nodes ranked by edge count. Use this after the
100
+ `swiftui` lane names an expensive view and you want to know *why it keeps
101
+ being invalidated*. For the example above, the top source is
102
+ `closure #1 in UserDefaultObserver.Target.GraphAttribute.send()` — the
103
+ canonical signature of an `@AppStorage` / `UserDefaults` feedback storm.
104
+
105
+ ## Composition pattern — scoping to a slice
106
+
107
+ When the user says something like "focus on X", "between A and B", or
108
+ "during signpost Y", compose the three modes:
109
+
110
+ 1. **Discover** — call `--list-logs` or `--list-signposts` with filters
111
+ that match the user's description. Pick the right entries.
112
+ 2. **Build the window** — take `time_ms` (logs) or `start_ms`/`end_ms`
113
+ (intervals) and form `--window START:END`.
114
+ 3. **Analyse** — call the default mode with `--window`.
115
+
116
+ Examples:
117
+
118
+ - *"Focus on the section after the log saying 'loaded feed'."*
119
+ → `--list-logs --log-message-contains "loaded feed"`, take the entry's
120
+ `time_ms`, set window = `[that_ms, end_of_trace_ms]` (or use the trace
121
+ `duration_s × 1000`).
122
+ - *"Between the 'begin-sync' log and the 'done-sync' log."*
123
+ → Two `--list-logs` calls (or one with a broader filter), pick the two
124
+ timestamps, set window = `[first, second]`.
125
+ - *"During the signpost 'ImageDecode'."*
126
+ → `--list-signposts --signpost-name-contains "ImageDecode"`, pick the
127
+ interval, set window = `[start_ms, end_ms]`.
128
+
129
+ ## JSON shape
130
+
131
+ ```json
132
+ {
133
+ "trace": "...",
134
+ "xctrace_version": "26.4 (...)",
135
+ "template": "SwiftUI",
136
+ "duration_s": 14.83,
137
+ "schemas_available": [...],
138
+ "lanes": [
139
+ { "lane": "time-profiler", "available": true, "schema_used": "time-profile",
140
+ "metrics": { "total_samples": N, "total_weight_ms": ms, "processes": [...] },
141
+ "top_offenders": [ { "symbol", "weight_ms", "percent", "samples", "thread" } ] },
142
+ { "lane": "hangs", "available": true, "schema_used": "potential-hangs",
143
+ "metrics": { "count", "total_duration_ms", "worst_duration_ms",
144
+ "severity_buckets": {"lt_250ms","250ms_1s","gt_1s"} },
145
+ "top_offenders": [ { "start_ms", "duration_ms", "hang_type", "thread" } ] },
146
+ { "lane": "hitches", "available": true, "schema_used": "hitches",
147
+ "metrics": { "count", "total_hitch_ms", "worst_hitch_ms",
148
+ "narrative_breakdown": {...}, "system_hitches", "app_hitches" },
149
+ "top_offenders": [ { "start_ms", "hitch_duration_ms", "narrative", "is_system" } ] },
150
+ { "lane": "swiftui", "available": true, "schemas_used": [...],
151
+ "metrics": { "total_events", "unique_views", "total_duration_ms",
152
+ "severity_breakdown": {"Very Low":N,"Moderate":N,"High":N},
153
+ "update_type_breakdown": {"View Body Updates":N, ...} },
154
+ "top_offenders": [ { "view", "total_ms", "count", "avg_ms" } ],
155
+ "high_severity_events": [ { "view", "severity", "duration_ms", "category",
156
+ "update_type", "description" } ] },
157
+ { "lane": "swiftui-causes", "available": true, "schema_used": "swiftui-causes",
158
+ "metrics": { "total_edges", "unique_sources", "unique_destinations",
159
+ "top_labels": {...} },
160
+ "top_sources": [ { "source", "edges", "top_destinations": [...] } ],
161
+ "top_destinations": [ { "destination", "edges", "top_sources": [...] } ] }
162
+ ],
163
+ "correlations": [
164
+ {
165
+ "trigger": { "lane": "hangs"|"hitches", "start_ms", "end_ms", "duration_ms",
166
+ "hang_type"|"frame_duration_ms" },
167
+ "time_profiler_main_thread": {
168
+ "samples_in_window": N, "samples_on_main": M,
169
+ "main_running_coverage_pct": 0–100,
170
+ "hot_symbols": [ { "symbol", "samples", "weight_ms", "percent_of_main" } ]
171
+ },
172
+ "swiftui_overlapping_updates": [ { "view", "duration_ms", "start_ms" } ]
173
+ }
174
+ ]
175
+ }
176
+ ```
177
+
178
+ ## Interpretation guide
179
+
180
+ ### `main_running_coverage_pct` is the key diagnostic
181
+
182
+ Time Profiler samples the main thread every ~1ms. For a correlation window
183
+ of `N` ms, you'd expect ~`N` main-thread running samples if main were fully
184
+ CPU-bound. Coverage is the ratio of observed main-thread samples to that
185
+ expectation.
186
+
187
+ - **< 25% coverage** → main thread was **blocked** (I/O, lock, sync XPC,
188
+ `Task.sleep`, waiting on an actor-isolated call). The `hot_symbols` you
189
+ do see are the moments main *was* executing — look there for the code
190
+ that *initiates* the blocking work, not the work itself. Common fix:
191
+ move to a background executor / `nonisolated` / `Task.detached`.
192
+ - **≥ 75% coverage** → main was **CPU-bound** the whole time. `hot_symbols`
193
+ point directly at the expensive work. Common fixes: hoist computation
194
+ out of view bodies, cache derived values, avoid per-frame allocation,
195
+ debounce `onChange`.
196
+ - **25–75%** → mix. Usually computation plus intermittent I/O; show both
197
+ hot symbols and note that main was partially blocked.
198
+
199
+ ### High-severity SwiftUI events → reference routing
200
+
201
+ When `swiftui.high_severity_events[].description` is one of:
202
+
203
+ | description | Likely cause | Route to |
204
+ |------------------|---------------------------|-------------------------------------|
205
+ | `onChange` | Expensive `.onChange` body | `references/performance-patterns.md`, `references/state-management.md` |
206
+ | `Gesture` | Heavy gesture handler | `references/performance-patterns.md` |
207
+ | `Action Callback`| Button/tap handler work | `references/performance-patterns.md` |
208
+ | `Update` | View body recomputation | `references/view-structure.md`, `references/performance-patterns.md` |
209
+ | `Creation` | View init cost | `references/view-structure.md` |
210
+ | `Layout` | GeometryReader churn | `references/layout-best-practices.md` |
211
+
212
+ ### Mapping trace findings to source code
213
+
214
+ If the user gave you a specific file, use it to confirm/cite. If they didn't, the trace itself tells you which views and symbols to look up.
215
+
216
+ 1. **From `swiftui.top_offenders` and `high_severity_events`**, use the
217
+ `view` string as your search key. If a target file is open, grep it;
218
+ if not, recommend the user grep their project for that type or the
219
+ module name. A partial match (prefix / generic stripping) means it's
220
+ probably a subview.
221
+ 2. **From `correlations[].time_profiler_main_thread.hot_symbols`**, treat
222
+ symbols starting with the user's module name (or in Swift free-function
223
+ form) as candidates. System frames (`swift_`, `dyld`, `objc_`, `CA*`,
224
+ `CF*`, `NS*`, `__open`, `pthread*`) identify *what* the code was doing
225
+ but the user-code caller one frame up is typically what to fix — say
226
+ so and, if you can, suggest searching the project for callers of the
227
+ equivalent Swift API (e.g. `__open` → `FileHandle` / `Data(contentsOf:)` /
228
+ `JSONDecoder.decode(from: Data)` sites).
229
+ 3. **From `hitches[].narrative`**, Apple pre-attributes each hitch. The
230
+ string `"Potentially expensive app update(s)"` means SwiftUI blamed the
231
+ app (so user code is in scope); absence of narrative usually means it
232
+ was a system hitch or below the threshold.
233
+ 4. **Correlating hitches with SwiftUI updates**: the
234
+ `swiftui_overlapping_updates` list on each hitch names the views that
235
+ were actively rendering when the frame dropped. Prioritise those.
236
+
237
+ ### Cause graph: finding *why* updates keep happening
238
+
239
+ The `swiftui` lane tells you *what* is expensive; the `swiftui-causes`
240
+ lane tells you *why* it keeps being triggered. Each edge is "source node
241
+ propagated to destination node" in SwiftUI's attribute graph.
242
+
243
+ Signatures to watch for in `top_sources`:
244
+
245
+ - **`closure #1 in UserDefaultObserver.Target.GraphAttribute.send()`** —
246
+ an `@AppStorage` / `UserDefaults` write is fanning out to every reader.
247
+ If the destination list contains multiple `@AppStorage <Type>.<prop>`
248
+ entries with thousands of edges each, you have a feedback storm. Fix
249
+ by reading each key once at a high level and passing values down, or
250
+ wrapping settings in a single `@Observable` so only genuine readers
251
+ invalidate. Route to `references/state-management.md` and
252
+ `references/performance-patterns.md`.
253
+ - **`EnvironmentWriter: …`** with thousands of edges — a modifier (often
254
+ `.hoverEffect`, custom environment keys) is applied too widely and
255
+ being re-installed during every layout pass. Route to
256
+ `references/view-structure.md`.
257
+ - **`View Creation / Reuse`** as the #1 source — the hierarchy is
258
+ replacing children rather than mutating in place. Look for ID
259
+ instability (missing/unstable `.id(…)` on ForEach, type-erased
260
+ `AnyView` wrappers, conditional structure swaps). Route to
261
+ `references/list-patterns.md` and `references/view-structure.md`.
262
+
263
+ When a specific view in `swiftui.high_severity_events` keeps showing up,
264
+ run `--fanin-for "<view name>"` to see the ranked list of sources
265
+ invalidating it.
266
+
267
+ ### Picking targets from a full-trace analysis
268
+
269
+ Prioritise from most actionable to least:
270
+
271
+ 1. **Any `hangs` with `main_running_coverage_pct < 25%`** — these are
272
+ blocking-I/O smells; nearly always fixable by moving work off-main.
273
+ 2. **Any `hangs` with `main_running_coverage_pct ≥ 75%`** — CPU-bound
274
+ main-thread work; fix the top `hot_symbols`.
275
+ 3. **`swiftui-causes.top_sources` with > ~1k edges** — structural
276
+ invalidation bugs (feedback storms, over-applied modifiers). These
277
+ are often cheaper to fix than per-view optimisations and collapse
278
+ many downstream high-severity updates at once.
279
+ 4. **`hitches` with `narrative == "Potentially expensive app update(s)"`**
280
+ and overlapping `swiftui_overlapping_updates` — specific views to
281
+ restructure.
282
+ 5. **`swiftui.high_severity_events`** — `onChange`, `Gesture`, or `Action
283
+ Callback` with `duration_ms > ~16` are frame-dropping handlers. For
284
+ any that keep firing, run `--fanin-for` to find the source.
285
+ 6. **`swiftui.top_offenders`** — heaviest views by total body time, even
286
+ without triggering hitches; candidates for view extraction or
287
+ memoisation (`equatable`, `@ViewBuilder` extraction).
288
+
289
+ ## Recommended output format for the user
290
+
291
+ After running the parser, structure your response as:
292
+
293
+ 1. **One-line summary** — "Found N hangs, worst Wms; K hitches; J high-severity SwiftUI updates."
294
+ 2. **Root-cause findings** — per prioritised target (see above), one paragraph with the trace evidence (coverage %, hot symbol, overlapping view) and a citation from `references/…` for the fix pattern.
295
+ 3. **Plan** — numbered, file-specific edits. Cite line numbers in the user's Swift file when you know them. Don't edit the file unless the user asked for edits.
@@ -0,0 +1,134 @@
1
+ # Recording an Instruments Trace
2
+
3
+ Use this reference when the user asks to record a new trace — either to
4
+ attach to a running app, launch one fresh, or capture a specific session
5
+ of actions they'll perform interactively.
6
+
7
+ The bundled `scripts/record_trace.py` wraps `xctrace record` with:
8
+
9
+ - The **SwiftUI** template by default (override with `--template`).
10
+ - **Manual stop** via Ctrl+C, a stop-file, or `--time-limit`.
11
+ - JSON discovery for devices and templates.
12
+ - Normal Python exit codes so an agent can orchestrate.
13
+
14
+ ## Typical flows
15
+
16
+ ### A) Attach to a running app on a connected device
17
+
18
+ ```bash
19
+ python3 "${SKILL_DIR}/scripts/record_trace.py" \
20
+ --device "Pol's iPhone" \
21
+ --attach "Helm" \
22
+ --output ~/Desktop/helm-session.trace
23
+ ```
24
+
25
+ Leave it running while the user exercises the app. Stop with **Ctrl+C**.
26
+
27
+ ### B) Launch an app and record from the first frame
28
+
29
+ ```bash
30
+ python3 "${SKILL_DIR}/scripts/record_trace.py" \
31
+ --device "<UDID>" \
32
+ --launch "/path/to/App.app" \
33
+ --output ~/Desktop/launch.trace
34
+ ```
35
+
36
+ Useful for diagnosing cold-start hitches and view-creation cost.
37
+
38
+ ### C) Agent-driven: start in background, stop via stop-file
39
+
40
+ When you (the agent) are running non-interactively — e.g. via
41
+ `Bash run_in_background` — use a stop-file so you can signal the
42
+ recording to end cleanly:
43
+
44
+ ```bash
45
+ # Start recording (background)
46
+ python3 "${SKILL_DIR}/scripts/record_trace.py" \
47
+ --attach Helm --stop-file /tmp/stop-trace \
48
+ --output ~/Desktop/session.trace
49
+
50
+ # ...user does their thing...
51
+
52
+ # Stop cleanly (from another shell or tool call)
53
+ touch /tmp/stop-trace
54
+ ```
55
+
56
+ The script polls every 0.5s for the stop-file, sends SIGINT to xctrace
57
+ when it appears, and waits up to 60s for the trace to finalise.
58
+
59
+ ### D) Time-boxed recording
60
+
61
+ ```bash
62
+ python3 "${SKILL_DIR}/scripts/record_trace.py" \
63
+ --attach Helm --time-limit 30s --output ~/Desktop/30s.trace
64
+ ```
65
+
66
+ xctrace stops itself at the limit.
67
+
68
+ ## Discovery helpers
69
+
70
+ ```bash
71
+ # List every connected device, simulator, and the host — JSON.
72
+ python3 "${SKILL_DIR}/scripts/record_trace.py" --list-devices
73
+
74
+ # List all Instruments templates — JSON with a flat list + by-section map.
75
+ python3 "${SKILL_DIR}/scripts/record_trace.py" --list-templates
76
+ ```
77
+
78
+ Device entries have `kind` (`devices`, `devices offline`, `simulators`),
79
+ `name`, `os`, `udid`. Offline devices are known but unplugged / unpaired —
80
+ plug them in before recording.
81
+
82
+ ## Picking a template
83
+
84
+ > **Hard rule: the `SwiftUI` template only populates the SwiftUI lane on a
85
+ > real device — a physical iOS/iPadOS device or the host Mac. On the iOS
86
+ > Simulator it records but the SwiftUI lane comes back empty.** If the
87
+ > chosen UDID falls under the `simulators` kind from `--list-devices`,
88
+ > switch to `Time Profiler`. It still gives you Time Profiler + Hangs +
89
+ > Animation Hitches, which `analyze_trace.py` analyses and correlates
90
+ > normally; only the `swiftui` lane will report `available: false`.
91
+
92
+ Decision flow:
93
+
94
+ | Target | Template to pass |
95
+ |----------------------------------------------|----------------------|
96
+ | Physical iOS/iPadOS device (connected) | `SwiftUI` (default) |
97
+ | Host Mac (macOS app, `--all-processes`, etc.)| `SwiftUI` (default) |
98
+ | iOS / iPadOS / watchOS / tvOS Simulator | `Time Profiler` |
99
+
100
+ Always confirm the target kind with `--list-devices` before starting a
101
+ recording: entries under `simulators` mean you must switch to Time
102
+ Profiler; entries under `devices` (both connected devices and the host
103
+ Mac) support the SwiftUI template. Entries under `devices offline` need
104
+ the user to connect/unlock/trust the device before recording.
105
+
106
+ For ad-hoc hang hunting on any target, `Time Profiler` or
107
+ `Animation Hitches` alone may be enough.
108
+
109
+ ## Chaining into analysis
110
+
111
+ The recording script prints `trace written: <path>` on exit. Feed that
112
+ path straight into `analyze_trace.py`:
113
+
114
+ ```bash
115
+ TRACE=$(python3 "${SKILL_DIR}/scripts/record_trace.py" \
116
+ --attach Helm --stop-file /tmp/stop-trace --output ~/Desktop/session.trace \
117
+ 2>&1 | awk '/trace written:/ {print $NF}')
118
+ python3 "${SKILL_DIR}/scripts/analyze_trace.py" --trace "$TRACE" --json-only
119
+ ```
120
+
121
+ If the user wanted a specific scope, combine with `--list-logs` /
122
+ `--list-signposts` / `--window` from `references/trace-analysis.md`.
123
+
124
+ ## Failure modes to handle
125
+
126
+ - **Device offline** — `--list-devices` shows it in `devices offline`.
127
+ Ask the user to connect/unlock the device and retry.
128
+ - **Output path exists** — the script refuses to overwrite. Either pick
129
+ a new `--output` or delete the existing bundle.
130
+ - **App not running (for `--attach`)** — xctrace exits with an error;
131
+ fall back to `--launch` or tell the user to open the app first.
132
+ - **Signing / trust on device** — iOS requires a development build
133
+ signed with the user's team. If xctrace returns a signing error, point
134
+ the user to trust the developer profile on the device.