sootsim 0.1.169 → 0.1.170

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 (184) hide show
  1. package/README.md +66 -63
  2. package/detox/index.ts +3 -3
  3. package/dist-cli/bin.js +3 -3
  4. package/dist-cli/chunks/agent-3C2BKQKX.js +46 -0
  5. package/dist-cli/chunks/{agent-wrapper-Y5FQA3RL.js → agent-wrapper-OIKCYOXZ.js} +2 -2
  6. package/dist-cli/chunks/{app-fonts-FYVA4XV6.js → app-fonts-25O32NAP.js} +2 -2
  7. package/dist-cli/chunks/{assert-U64QBDM2.js → assert-ONEP4NQU.js} +2 -2
  8. package/dist-cli/chunks/beta-4E5USTEI.js +2 -0
  9. package/dist-cli/chunks/{camera-3GXBVIAM.js → camera-RORW4MAA.js} +2 -2
  10. package/dist-cli/chunks/{chunk-5C6BR24W.js → chunk-25RFZ6WP.js} +6 -6
  11. package/dist-cli/chunks/chunk-35GMFXVJ.js +2 -0
  12. package/dist-cli/chunks/{chunk-GLRFKYDV.js → chunk-3TM7DHWE.js} +2 -2
  13. package/dist-cli/chunks/{chunk-4F3BBP7B.js → chunk-4XVY5TUF.js} +2 -2
  14. package/dist-cli/chunks/{chunk-LZEL2RU3.js → chunk-5ZHUPPS5.js} +1 -1
  15. package/dist-cli/chunks/{chunk-GC4THE6K.js → chunk-6FAEORJ2.js} +2 -2
  16. package/dist-cli/chunks/{chunk-G2ZFDIPK.js → chunk-6TSXXN2W.js} +4 -4
  17. package/dist-cli/chunks/chunk-AJF3QF4K.js +1 -0
  18. package/dist-cli/chunks/{chunk-FIDPRJYH.js → chunk-AUCNBB6Q.js} +2 -2
  19. package/dist-cli/chunks/{chunk-SIB6I72P.js → chunk-BP3EGFER.js} +2 -2
  20. package/dist-cli/chunks/{chunk-OGLWXPVG.js → chunk-DAXME77O.js} +3 -3
  21. package/dist-cli/chunks/chunk-DGJTEFE7.js +13 -0
  22. package/dist-cli/chunks/chunk-DIRDEKRW.js +23 -0
  23. package/dist-cli/chunks/{chunk-3L4NRJ6C.js → chunk-DKTC53HV.js} +1 -1
  24. package/dist-cli/chunks/{chunk-KUUFY6FC.js → chunk-DWXC25XG.js} +1 -1
  25. package/dist-cli/chunks/{chunk-CR6DOLUD.js → chunk-E3FKMY5E.js} +1 -1
  26. package/dist-cli/chunks/chunk-ER4GBJRY.js +2 -0
  27. package/dist-cli/chunks/chunk-EX6V4ZV6.js +6 -0
  28. package/dist-cli/chunks/{chunk-VMYMPL6H.js → chunk-GQH3PD3W.js} +5 -5
  29. package/dist-cli/chunks/{chunk-MVOHANJG.js → chunk-GST4YSBO.js} +4 -4
  30. package/dist-cli/chunks/{chunk-BIWJE7CB.js → chunk-I4RV5I6V.js} +1 -1
  31. package/dist-cli/chunks/{chunk-Y6IDAARY.js → chunk-I5WXVKR6.js} +1 -1
  32. package/dist-cli/chunks/{chunk-HC72ILJK.js → chunk-IO7KAVFK.js} +2 -2
  33. package/dist-cli/chunks/{chunk-XEH4QGWB.js → chunk-LMX7UB5T.js} +2 -2
  34. package/dist-cli/chunks/{chunk-YADWU7OZ.js → chunk-N4YCSOCR.js} +2 -2
  35. package/dist-cli/chunks/{chunk-IODOTOOP.js → chunk-NI3L4A65.js} +2 -2
  36. package/dist-cli/chunks/{chunk-IACEJQIO.js → chunk-ODGEH6OW.js} +2 -2
  37. package/dist-cli/chunks/{chunk-DNA6VS6M.js → chunk-Q4NDYO2U.js} +1 -1
  38. package/dist-cli/chunks/{chunk-PV6MBKKE.js → chunk-QPRF3UYX.js} +2 -2
  39. package/dist-cli/chunks/{chunk-M2TMFGZH.js → chunk-QXJMXSQP.js} +1 -1
  40. package/dist-cli/chunks/chunk-RLKSLUNR.js +2 -0
  41. package/dist-cli/chunks/{chunk-WZG3YVJR.js → chunk-S244IT4W.js} +1 -1
  42. package/dist-cli/chunks/chunk-SDHOM6ZG.js +62 -0
  43. package/dist-cli/chunks/{chunk-B7BMSU7H.js → chunk-TXKOJ3P5.js} +1 -1
  44. package/dist-cli/chunks/{chunk-IBEMMV5E.js → chunk-UDMJSFSH.js} +8 -8
  45. package/dist-cli/chunks/{chunk-DQZEN256.js → chunk-ULV4PWN4.js} +1 -1
  46. package/dist-cli/chunks/{chunk-2TYEWVS4.js → chunk-V4HTQPMA.js} +1 -1
  47. package/dist-cli/chunks/chunk-VATHADSI.js +2 -0
  48. package/dist-cli/chunks/{chunk-5Q7IHJ7K.js → chunk-VUOCUCJ2.js} +2 -2
  49. package/dist-cli/chunks/{chunk-JDGLBW64.js → chunk-WN7R4GL4.js} +1 -1
  50. package/dist-cli/chunks/chunk-XOTJD6PU.js +118 -0
  51. package/dist-cli/chunks/chunk-XUNPVF5K.js +1 -0
  52. package/dist-cli/chunks/{chunk-KZIXAYN5.js → chunk-YMFSRCHL.js} +4 -4
  53. package/dist-cli/chunks/{chunk-X2HNVXNM.js → chunk-YV74D4MG.js} +2 -2
  54. package/dist-cli/chunks/{chunk-SNX3M4XD.js → chunk-YVTWSC5Y.js} +3 -3
  55. package/dist-cli/chunks/cli-version-EKKWCHRX.js +2 -0
  56. package/dist-cli/chunks/{compat-ORRWNXVT.js → compat-ZVZM5TML.js} +3 -3
  57. package/dist-cli/chunks/control-TWINYHMY.js +2 -0
  58. package/dist-cli/chunks/{cpu-profile-6PRSBZ2F.js → cpu-profile-RWGQTWLP.js} +2 -2
  59. package/dist-cli/chunks/daemon-AOSMNBD4.js +2 -0
  60. package/dist-cli/chunks/{debug-Q3J2X4WW.js → debug-R7PL3MHF.js} +5 -5
  61. package/dist-cli/chunks/{detox-DN57GMMJ.js → detox-UIJMKIGQ.js} +2 -2
  62. package/dist-cli/chunks/{device-IL5TPYGU.js → device-7SRVX2PU.js} +2 -2
  63. package/dist-cli/chunks/{diagnose-BW6QWP4F.js → diagnose-OXAKLLZT.js} +2 -2
  64. package/dist-cli/chunks/drivers-BPPG22VP.js +2 -0
  65. package/dist-cli/chunks/{electron-DGMSXQWG.js → electron-CTCH4VOL.js} +3 -3
  66. package/dist-cli/chunks/flow-KA2WCWDL.js +2 -0
  67. package/dist-cli/chunks/help-XBQIK2XY.js +2 -0
  68. package/dist-cli/chunks/{hints-TK3EHB4U.js → hints-P3ZIAP3Z.js} +2 -2
  69. package/dist-cli/chunks/home-paths-ZSCTLOYE.js +2 -0
  70. package/dist-cli/chunks/{inspect-NFWFGU4B.js → inspect-2ABU5WET.js} +24 -24
  71. package/dist-cli/chunks/{install-desktop-GB3JKSNX.js → install-desktop-4NOQ3YY4.js} +3 -3
  72. package/dist-cli/chunks/{keys-RAAHRIFH.js → keys-RPVEUNUC.js} +2 -2
  73. package/dist-cli/chunks/{login-KQ37GHDE.js → login-6D6DXBO3.js} +4 -4
  74. package/dist-cli/chunks/{logout-63SH2Y25.js → logout-T5OSWDTJ.js} +2 -2
  75. package/dist-cli/chunks/{maestro-24BT3MML.js → maestro-MKCHEOKA.js} +2 -2
  76. package/dist-cli/chunks/optional-demo-registry-EYD2K3QH.js +2 -0
  77. package/dist-cli/chunks/{preview-KQAOVN6R.js → preview-S52ZNGN2.js} +2 -2
  78. package/dist-cli/chunks/{profile-AN2B4NJT.js → profile-IG5F3LTL.js} +2 -2
  79. package/dist-cli/chunks/{react-ATGV35B4.js → react-275HCOFC.js} +2 -2
  80. package/dist-cli/chunks/{record-36662T3R.js → record-YT63SUHO.js} +4 -4
  81. package/dist-cli/chunks/runtime-WYZMDZAK.js +2 -0
  82. package/dist-cli/chunks/{screenshot-K4N5MPAT.js → screenshot-5AZ4MY3A.js} +4 -4
  83. package/dist-cli/chunks/{screenshot-mode-4QOJDLSH.js → screenshot-mode-4S4EX2XJ.js} +2 -2
  84. package/dist-cli/chunks/{screenshots-TB35YMSR.js → screenshots-UUJNZSG7.js} +2 -2
  85. package/dist-cli/chunks/{screenshots-capture-W6X33BZ4.js → screenshots-capture-I66JD3AD.js} +2 -2
  86. package/dist-cli/chunks/{server-L2PKDJZ2.js → serve-O46Q4WAD.js} +18 -17
  87. package/dist-cli/chunks/setup-C44N54O7.js +77 -0
  88. package/dist-cli/chunks/skills-PPVS4XOQ.js +40 -0
  89. package/dist-cli/chunks/{slides-TORKO36P.js → slides-ZWSZJZUY.js} +2 -2
  90. package/dist-cli/chunks/store-3SLGP5O3.js +2 -0
  91. package/dist-cli/chunks/telemetry-2XLLWARK.js +2 -0
  92. package/dist-cli/chunks/{test-5VCENVW3.js → test-362G4M5A.js} +3 -3
  93. package/dist-cli/chunks/{three-mode-ZVS2DSX6.js → three-mode-JNVTM2UT.js} +2 -2
  94. package/dist-cli/chunks/{timeline-TNC5OWLF.js → timeline-VKC6ULRK.js} +2 -2
  95. package/dist-cli/chunks/{upgrade-E7IO6A7Z.js → upgrade-SJPX4SPA.js} +2 -2
  96. package/dist-cli/chunks/upload-MXOBV6RT.js +2 -0
  97. package/dist-cli/chunks/version-4Z7AFNH3.js +4 -0
  98. package/dist-cli/chunks/web-WB2I2AWL.js +2 -0
  99. package/dist-cli/chunks/{what-happened-RMHZ7DGX.js → what-happened-KQCWMQJT.js} +3 -3
  100. package/dist-cli/chunks/{whoami-D53ANHR5.js → whoami-K76PXAD4.js} +2 -2
  101. package/dist-lib/agent-daemon-client.cjs +4 -5
  102. package/dist-lib/agent-events.cjs +1 -1
  103. package/dist-lib/agent-sessions.cjs +1 -1
  104. package/dist-lib/attached-projects.cjs +1 -1
  105. package/dist-lib/auth/shared-session.cjs +1 -1
  106. package/dist-lib/backend-origin.cjs +1 -1
  107. package/dist-lib/beta.cjs +3 -6
  108. package/dist-lib/beta.mjs +3 -5
  109. package/dist-lib/bridge-constants.cjs +1 -1
  110. package/dist-lib/cli-constants.cjs +1 -1
  111. package/dist-lib/config.cjs +1 -1
  112. package/dist-lib/detox/index.cjs +4 -4
  113. package/dist-lib/dev-bundle-resolution.cjs +2 -9
  114. package/dist-lib/home-paths.cjs +59 -1
  115. package/dist-lib/host/bridge-host.cjs +67 -5
  116. package/dist-lib/host/fetch-proxy-handler.cjs +1 -1
  117. package/dist-lib/host/fetch-proxy-overrides.cjs +1 -1
  118. package/dist-lib/host/fetch-proxy-overrides.mjs +1 -1
  119. package/dist-lib/host/websocket-proxy.cjs +1 -1
  120. package/dist-lib/index.cjs +2 -2
  121. package/dist-lib/menu.cjs +1 -1
  122. package/dist-lib/menu.mjs +1 -1
  123. package/dist-lib/metro.cjs +2 -2
  124. package/dist-lib/profiles.cjs +1 -1
  125. package/dist-lib/render-mode.cjs +1 -1
  126. package/dist-lib/scripts/dev-server-scanner.cjs +5 -4
  127. package/dist-lib/sdk.cjs +1 -1
  128. package/dist-lib/sdk.mjs +1 -1
  129. package/dist-lib/skills.cjs +124 -8
  130. package/dist-lib/vite.cjs +2 -2
  131. package/package.json +2 -1
  132. package/scripts/dev-server-scanner.ts +3 -4
  133. package/scripts/postinstall.cjs +2 -2
  134. package/scripts/preuninstall.cjs +5 -7
  135. package/skills/soot.md +178 -0
  136. package/skills/sootsim-debug.md +384 -0
  137. package/skills/sootsim-setup.md +96 -0
  138. package/skills/sootsim-test.md +292 -0
  139. package/skills/sootsim-visual.md +122 -0
  140. package/src/agent-daemon-client.ts +4 -14
  141. package/src/beta.ts +3 -5
  142. package/src/dev-bundle-resolution.ts +1 -14
  143. package/src/home-paths.ts +77 -2
  144. package/src/host/agent-host.ts +1 -1
  145. package/src/host/bridge-host.ts +65 -6
  146. package/src/metro-plugin.ts +1 -1
  147. package/src/runtime-assets.ts +1 -1
  148. package/src/vite-plugin.ts +1 -0
  149. package/dist-cli/chunks/agent-V3GVCRPL.js +0 -46
  150. package/dist-cli/chunks/auto-bootstrap-YXDP3WKH.js +0 -2
  151. package/dist-cli/chunks/beta-FGSMZWLP.js +0 -2
  152. package/dist-cli/chunks/chunk-2IFWVIKM.js +0 -2
  153. package/dist-cli/chunks/chunk-3T36XLP3.js +0 -119
  154. package/dist-cli/chunks/chunk-5KY7TQ42.js +0 -5
  155. package/dist-cli/chunks/chunk-BQOMDL4K.js +0 -1
  156. package/dist-cli/chunks/chunk-FHMPJZKM.js +0 -7
  157. package/dist-cli/chunks/chunk-GQAWFQNN.js +0 -23
  158. package/dist-cli/chunks/chunk-HJTKKF7M.js +0 -13
  159. package/dist-cli/chunks/chunk-K4JAWKOY.js +0 -1
  160. package/dist-cli/chunks/chunk-NXGQS7IR.js +0 -2
  161. package/dist-cli/chunks/chunk-R2INPDGW.js +0 -1
  162. package/dist-cli/chunks/chunk-SLL5SZN4.js +0 -2
  163. package/dist-cli/chunks/chunk-XM66K64H.js +0 -79
  164. package/dist-cli/chunks/cli-version-3L6FFDIX.js +0 -2
  165. package/dist-cli/chunks/config-5IB6ONJ2.js +0 -45
  166. package/dist-cli/chunks/control-BM4V27OB.js +0 -2
  167. package/dist-cli/chunks/daemon-62MZT4G4.js +0 -67
  168. package/dist-cli/chunks/drivers-V6QDFZQD.js +0 -2
  169. package/dist-cli/chunks/flow-VBM6TU32.js +0 -2
  170. package/dist-cli/chunks/help-XWKNL743.js +0 -2
  171. package/dist-cli/chunks/home-paths-G23H3RO6.js +0 -2
  172. package/dist-cli/chunks/install-5YL7FITA.js +0 -2
  173. package/dist-cli/chunks/launch-DYFE4CAD.js +0 -16
  174. package/dist-cli/chunks/optional-demo-registry-JJXPB3UD.js +0 -2
  175. package/dist-cli/chunks/runtime-NRMC3U3D.js +0 -2
  176. package/dist-cli/chunks/runtime-delivery-RO6CTYPQ.js +0 -2
  177. package/dist-cli/chunks/setup-repo-AK6QOUE7.js +0 -2
  178. package/dist-cli/chunks/skills-KDSOWUOE.js +0 -10
  179. package/dist-cli/chunks/start-GH2AOUX6.js +0 -23
  180. package/dist-cli/chunks/store-JHW65VGQ.js +0 -2
  181. package/dist-cli/chunks/telemetry-SZLRXJXW.js +0 -2
  182. package/dist-cli/chunks/upload-KKEWETA5.js +0 -2
  183. package/dist-cli/chunks/version-37OD33SE.js +0 -4
  184. package/dist-cli/chunks/web-4JVMIBTB.js +0 -2
@@ -0,0 +1,384 @@
1
+ ---
2
+ name: sootsim-debug
3
+ description: Debug rendering, performance, and accessibility issues in your React Native app under sootsim
4
+ ---
5
+
6
+ # sootsim debug
7
+
8
+ the foundational skill for "something is wrong with my app in sootsim".
9
+ covers debugging, performance, and accessibility — three branches that
10
+ share the same CLI primitives, the same auto-settling contract, and the
11
+ same diff/snapshot workflow. start here for any rendering, interaction,
12
+ event-order, or correctness question. for pixel-level rendering fidelity
13
+ load `/sootsim-visual` instead.
14
+
15
+ > needs a connected, pinned sim. if `sootsim describe` errors, load
16
+ > `/sootsim-setup` first.
17
+
18
+ ## route in
19
+
20
+ - "my app renders wrong / wrong props / wrong tree" → [debugging](#branch--debugging)
21
+ - "feels slow / drops frames / janks on scroll" → [performance](#branch--performance)
22
+ - "screen reader can't find this / wrong label / tap target too small" → [accessibility](#branch--accessibility)
23
+ - "I want to see what just happened" (ephemeral toast, async navigation,
24
+ fetch + alert sequence) → [the timeline](#the-timeline-what-happened)
25
+ - "I want pixel-level fidelity to iOS" → load `/sootsim-visual`
26
+ - "I want to author a test" → load `/sootsim-test`
27
+
28
+ ## anti-patterns (apply to every branch)
29
+
30
+ - **`a1`/`a2`/`b0` style ids mean sootsim sims, never browser tabs.** when a user
31
+ says "look at a3", that's the `sootsim list` sim id. do not open chrome
32
+ MCP unless the user explicitly says "use chrome" — the canvas has no
33
+ DOM to inspect anyway.
34
+ - **the CLI auto-settles. don't add `sleep`.** every read waits up to
35
+ 1800 ms for in-flight transitions to start; every write polls layout
36
+ hash until stable. if a read keeps racing its write, the fix is **never**
37
+ a blind `sleep` — it's `wait selector`, `wait ready`, `wait idle`, or
38
+ fixing the underlying animation-completion signal.
39
+ - **prefer `--testid` over text matching.** text drifts under i18n, copy
40
+ changes, and duplicate strings. add `testID` during implementation and
41
+ query against it.
42
+ - **pin a sim once.** if more than one is live, an unpinned command
43
+ hits the first and produces results from the wrong app. `sootsim use
44
+ <id>` at the start of the workflow.
45
+ - **`debug eval` is an escape hatch.** if a top-level command feels
46
+ broken or missing, file an issue — every agent after you benefits from
47
+ a better CLI, not a pile of ad-hoc scripts.
48
+ - **sweep `get errors` and `get requests` after every repro.** the
49
+ one-line summary tells you the count grew; you still have to *look at
50
+ them*. a "fixed" behavior with a new console error is not fixed.
51
+ - **"found a testID" is not done.** done is: reliable repro + identified
52
+ root cause (specific node + prop, or event + handler) + verified fix.
53
+
54
+ ## the timeline ("what happened")
55
+
56
+ between two CLI calls, things happen invisibly — toasts flash, keyboards
57
+ open and close, screens push and pop, alerts fire and dismiss, async
58
+ fetches resolve. the timeline records them so you can ask "what
59
+ happened" instead of racing the UI with `find`.
60
+
61
+ ```sh
62
+ sootsim timeline start # arm recording (cheap kinds default-on)
63
+ # reproduce the flow
64
+ sootsim what-happened # events since the last CLI call
65
+ sootsim what-happened --since 10s # absolute window
66
+ sootsim what-happened --kinds toast,fetch # filter to a few kinds
67
+ sootsim what-happened --summary # one-line counts
68
+ sootsim what-happened --flow # section events by screen/route
69
+ ```
70
+
71
+ semantic kinds the timeline understands: `keyboard`, `screen`, `route`,
72
+ `alert`, `actionsheet`, `picker`, `notification`, `toast`, `scroll`,
73
+ `gesture`, `text-input`, `reanimated`, `animation`, `fetch`, `console`,
74
+ `app-launch`, `shell`. cheap kinds record by default; heavier kinds
75
+ (scroll, gesture, text-input, reanimated, animation) opt in via
76
+ `sootsim timeline start scroll,gesture,…`.
77
+
78
+ every other CLI command also prints a one-line footer for events since
79
+ the last call — that's the headline indicator. when the footer is empty,
80
+ there's nothing new to look at; when it says `since last: 1 error · 1
81
+ toast · 1 screen push`, run `sootsim what-happened` to see the detail.
82
+
83
+ > reach for the timeline first when the question involves *something
84
+ > that appeared briefly and disappeared*. it's faster than a screenshot
85
+ > and tells you the duration too.
86
+
87
+ ## automatic settling — when you actually need a manual wait
88
+
89
+ every CLI command already participates in a two-phase settle. you only
90
+ need a manual wait when:
91
+
92
+ 1. the CLI explicitly printed `⚠ auto-wait timed out after Nms — next
93
+ command may see mid-animation state` *and* your next read depends on
94
+ the animation finishing.
95
+ 2. the transition is longer than ~1.2 s (full stack navigation,
96
+ crossfades, video first-frame, network-backed render).
97
+ 3. you want `--strict` settle, which also requires animation flags to
98
+ clear — only safe for apps with no perpetual background animation
99
+ (no pulsing dots, no shimmer, no looping Lottie).
100
+
101
+ ```sh
102
+ sootsim do settle 5 # wait up to 5s for layout stability
103
+ sootsim wait idle --max-ms 5000 # same thing under the `wait` verb
104
+ sootsim wait idle --strict # also require animation flags clear
105
+ sootsim do tap-id play --no-wait # skip auto-settle on one command
106
+ SOOTSIM_NO_AUTO_WAIT=1 sootsim ... # disable auto-settle for a lane
107
+ ```
108
+
109
+ ## branch — debugging
110
+
111
+ the playbook for "wrong tree / wrong props / wrong handler":
112
+
113
+ ```sh
114
+ sootsim describe # what's on screen now
115
+ sootsim get errors 5 # any console smoke?
116
+ sootsim find --testid <node> # locate the suspect
117
+ sootsim debug snapshot before
118
+ # reproduce
119
+ sootsim debug snapshot after
120
+ sootsim debug diff before after # structural diff: what changed?
121
+ sootsim what-happened # timeline events during the repro
122
+ ```
123
+
124
+ reading `describe` output:
125
+
126
+ ```
127
+ [button] "Sign in" #loginButton @(0,347) 402x44 [bg:#006AFF fg:#fff] (tap)
128
+ <text> "Forgot?" @(341,287) 55x28 [fg:#666 fontSize:14]
129
+ ```
130
+
131
+ format: `[type] "text" #testID @(x,y) WxH [styles] (flags)`. coordinates
132
+ are points (CSS pixels), origin top-left, parent-relative.
133
+
134
+ for transitions, alerts, native UI, or anything spanning the shell ↔
135
+ tenant boundary, lean on the timeline before reaching for traces:
136
+
137
+ ```sh
138
+ sootsim timeline start
139
+ # reproduce the launch / dismiss / alert
140
+ sootsim what-happened --kinds shell,alert,screen,animation
141
+ ```
142
+
143
+ you're done when:
144
+
145
+ 1. repro is reliable (same input → same output)
146
+ 2. root cause is identified (specific node + prop, or event + handler,
147
+ not "something in the navigation stack")
148
+ 3. fix re-verified through the same `snapshot → reproduce → diff` loop
149
+
150
+ ## branch — performance
151
+
152
+ ```sh
153
+ sootsim debug perf start # arm capture (also clears prior frames)
154
+ # reproduce the slow interaction
155
+ sootsim debug perf stop # full report
156
+ sootsim debug perf stop --json # machine-readable summary
157
+ sootsim debug perf frames # per-frame ring breakdown
158
+ sootsim debug perf worst # the slowest frames first
159
+ ```
160
+
161
+ `debug perf` output:
162
+
163
+ ```
164
+ frames: 847
165
+ total: 14123ms
166
+ avg: 16.7ms
167
+ max: 42ms (⚠ dropped frames)
168
+ p95: 22.3ms
169
+ layout frames: 123
170
+ layout avg: 2.1ms
171
+ ```
172
+
173
+ frame budget: target **8 ms / frame (120 fps)** — render <4 ms, layout
174
+ <2 ms, JS/react <2 ms. heavier paints can fall back to the 16 ms / 60 fps
175
+ budget. **p95 >20 ms is visible jank for a scrolling surface.**
176
+
177
+ profiling a whole flow:
178
+
179
+ ```sh
180
+ sootsim flow flows/scroll-feed.yaml --profile # per-step + frame stats
181
+ sootsim cpu-profile --duration 5 --output /tmp/trace.cpuprofile # sampled CPU
182
+ ```
183
+
184
+ common patterns → first probe:
185
+
186
+ | symptom | likely | next |
187
+ | --- | --- | --- |
188
+ | scroll jank | layout firing during scroll | `debug enable layout` + `debug recent layout 40` |
189
+ | anim stutter | `Animated.Value` on `width`/`height` | switch to `transform: [{ scale }]` or `translate` |
190
+ | first-tap lag | font / image still loading | `get requests` + `debug state image` |
191
+ | memory growth | live animation drivers not cleaned up | `debug state animations` |
192
+ | slow initial render | many text measurements | `debug recent text` on first paint |
193
+
194
+ debug channels that help, but cost 1–3 ms/frame on their own — enable
195
+ only what you're investigating:
196
+
197
+ ```sh
198
+ sootsim debug enable layout,onlayout,render,animated
199
+ # reproduce
200
+ sootsim debug recent layout 20 # last 20 layout events
201
+ sootsim debug recent render 20 # last 20 draw passes
202
+ sootsim debug disable layout,onlayout,render,animated
203
+ ```
204
+
205
+ you're done when: a p95 number for the interaction + named hot path +
206
+ remeasured (a fresh `perf start` between runs clears the buffer) and the
207
+ number moved.
208
+
209
+ watch out for:
210
+
211
+ - **dynamic format strings bust the text-measurement cache.** `${count}
212
+ messages` re-measures every change — render the number and the word as
213
+ separate `<Text>` nodes.
214
+ - **`--strict` settle hangs forever on perpetual animation.** anything
215
+ with a pulsing dot or looping Lottie will never go quiet under
216
+ `--strict`. use plain `wait idle` there.
217
+ - **p95 over a single run is noise.** take three runs minimum.
218
+
219
+ ## branch — accessibility
220
+
221
+ ```sh
222
+ sootsim get a11y # full a11y tree
223
+ sootsim get a11y --issues # only nodes with problems
224
+ sootsim describe --a11y # inline a11y info on every node
225
+ ```
226
+
227
+ issue summary format:
228
+
229
+ ```
230
+ [input] "" role=none label=null ⚠ missing label
231
+ [button] "➜" @(340,280) 20x20 (tap) ⚠ touch target <44×44
232
+ <text> "Sign in" color=#777 bg=#888 ⚠ contrast 1.4:1 (need 4.5:1)
233
+ ```
234
+
235
+ finding offenders fast:
236
+
237
+ ```sh
238
+ sootsim find --no-label # interactive nodes missing label
239
+ sootsim find --no-role # interactive nodes missing role
240
+ sootsim find --pressable --max-dim 44 # undersized tap targets
241
+ ```
242
+
243
+ what gets checked:
244
+
245
+ - **missing labels** — interactive nodes without `accessibilityLabel`
246
+ - **missing roles** — `Pressable`/`Touchable` without `accessibilityRole`
247
+ - **missing hints** — complex interactions without `accessibilityHint`
248
+ - **touch target size** — tappable nodes with hitSlop-expanded rect <44×44
249
+ - **contrast** — text color vs detectable background
250
+ - **label / visible-text mismatch** — label that reads differently from
251
+ the text VoiceOver would fall back to (often a translation bug)
252
+ - **duplicate labels** — two reachable nodes with identical labels on
253
+ one screen ("Open" + "Open" leaves no way to disambiguate)
254
+
255
+ triage order:
256
+
257
+ - **P0** — interactive node with no label or no role (blocks screen
258
+ reader entirely)
259
+ - **P1** — tap target <44×44, duplicate labels
260
+ - **P2** — contrast, label/visible-text mismatch
261
+
262
+ fix → verify loop (the same shape as debugging):
263
+
264
+ ```sh
265
+ sootsim get a11y --issues > before.txt
266
+ # apply the fix
267
+ sootsim get a11y --issues > after.txt
268
+ diff before.txt after.txt
269
+ ```
270
+
271
+ fixing common cases:
272
+
273
+ ```tsx
274
+ // bad: icon button with no accessible name
275
+ <Pressable onPress={onBack}>
276
+ <ChevronLeftIcon />
277
+ </Pressable>
278
+
279
+ // good: labeled + roled + hinted + hitSlop'd
280
+ <Pressable
281
+ onPress={onBack}
282
+ accessibilityRole="button"
283
+ accessibilityLabel="Back"
284
+ accessibilityHint="Returns to the previous screen"
285
+ hitSlop={12} // bumps tap target to 44×44 minimum
286
+ >
287
+ <ChevronLeftIcon />
288
+ </Pressable>
289
+
290
+ // bad: text input with no programmatic label
291
+ <TextInput placeholder="Email" onChangeText={setEmail} />
292
+
293
+ // good: label survives even when placeholder is hidden
294
+ <TextInput
295
+ placeholder="Email"
296
+ accessibilityLabel="Email address"
297
+ onChangeText={setEmail}
298
+ />
299
+ ```
300
+
301
+ watch out for:
302
+
303
+ - **placeholders are not labels.** they disappear after the user types.
304
+ - **hitSlop expands the a11y rect too.** rarely need to make the
305
+ rendered button bigger — `hitSlop={12}` is usually enough.
306
+ - **`accessibilityRole="image"` is not an `alt` tag.** pair it with
307
+ `accessibilityLabel` or VoiceOver reads "image" and nothing else.
308
+ - **`importantForAccessibility="no-hide-descendants"` hides an entire
309
+ subtree.** useful for decorative chrome, dangerous if you forget it.
310
+
311
+ run the screen reader on a real device at least once before shipping —
312
+ labels that read fine on paper often sound robotic ("delete_message_btn_v2"
313
+ type names sneak in).
314
+
315
+ ## recovery — common failure modes
316
+
317
+ - **`describe` returns nothing** — no sim pinned, or the app isn't
318
+ loaded. load `/sootsim-setup` and re-confirm.
319
+ - **`find` returns multiple matches** — narrow with `--testid`,
320
+ `--visible`, or both.
321
+ - **`debug perf` reports zero frames** — you didn't run `perf start`
322
+ first, or the capture window closed before any frame committed.
323
+ - **`get a11y --issues` returns 100+ items** — sort by P0 first; fixing
324
+ one label often cascades to a parent's a11y subtree.
325
+ - **timeline footer keeps showing 1 error but `get errors` is empty** —
326
+ the footer reads "since last cursor advance"; `get errors` is absolute.
327
+ the error already scrolled out of the absolute ring buffer.
328
+
329
+ ## reference
330
+
331
+ ### finding and interacting
332
+
333
+ ```sh
334
+ sootsim describe # all visible elements with styles
335
+ sootsim describe button # filter by text/role/label/testID
336
+ sootsim describe --testid foo # only the subtree under a testID
337
+ sootsim describe --verbose # include every style property
338
+
339
+ sootsim find "Sign in" # by text content
340
+ sootsim find --testid loginButton
341
+ sootsim find --role button
342
+ sootsim find --pressable
343
+ sootsim find --visible # only on-screen nodes
344
+
345
+ sootsim do tap-id loginButton # tap by testID (preferred)
346
+ sootsim do tap-text "Submit" # tap by text
347
+ sootsim do tap 196 400 # tap at coordinates
348
+ sootsim do type "hello world" # type into focused input
349
+ sootsim do type-into emailInput "a@b" # focus then type
350
+ sootsim do key return # special key (return, backspace, …)
351
+ sootsim do scroll feed-list 0 500 # scroll a testID by dx/dy
352
+ sootsim do swipe feed-list left # directional swipe
353
+ sootsim do long-press messageRow 800 # ms hold
354
+ ```
355
+
356
+ ### errors and requests
357
+
358
+ ```sh
359
+ sootsim get errors 5 # last 5 console errors
360
+ sootsim get warnings 5
361
+ sootsim get requests 5 # recent failed requests
362
+ sootsim logs --since 30s # recent console output
363
+ sootsim network --since 30s # recent network traffic
364
+ ```
365
+
366
+ ### snapshots and diff
367
+
368
+ ```sh
369
+ sootsim debug snapshot before
370
+ # interact
371
+ sootsim debug snapshot after
372
+ sootsim debug diff before after # added / removed / changed nodes
373
+ ```
374
+
375
+ ### debug channels
376
+
377
+ useful: `animated`, `layout`, `onlayout`, `render`, `sheets`, `portals`,
378
+ `gesture`, `scroll`, `text`, `image`.
379
+
380
+ ```sh
381
+ sootsim debug enable animated,layout,sheets,portals
382
+ sootsim debug recent layout 20 # last 20 events on the channel
383
+ sootsim debug disable animated,layout,sheets,portals
384
+ ```
@@ -0,0 +1,96 @@
1
+ ---
2
+ name: sootsim-setup
3
+ description: Get sootsim connected to your React Native app — from `npm install sootsim` to a driveable sim
4
+ ---
5
+
6
+ # sootsim setup
7
+
8
+ you've installed sootsim into a React Native project and want to drive it
9
+ from the CLI. this skill takes you from zero to a connected, pinned sim
10
+ that every other sootsim skill assumes exists. if `sootsim describe` already
11
+ returns a tree, you're past this skill — load `/sootsim-debug` for
12
+ debugging or `/sootsim-test` for writing tests.
13
+
14
+ ## anti-patterns (read first)
15
+
16
+ - **never `sootsim claim --force` a sim held by another CLI.** the lease
17
+ exists for a reason — forcing strands the other agent and corrupts the
18
+ bridge state. use `sootsim open --new` to start a fresh sim instead.
19
+ - **don't switch sims mid-investigation.** pin once with `sootsim use
20
+ <id>` and keep it pinned. an unpinned command hits the first sim,
21
+ which produces baffling results when more than one is live.
22
+ - **an empty `sootsim list` is not "broken sootsim"** — it usually means the
23
+ daemon is down, the dev server port is wrong, or the runtime is missing.
24
+ walk the recovery checklist before reinstalling.
25
+
26
+ ## first move
27
+
28
+ ```sh
29
+ sootsim setup # one-time — installs daemon, optional repo setup
30
+ sootsim open 8081 # load a metro/expo dev server
31
+ sootsim list # confirm exactly one sim is reachable
32
+ sootsim use <id> # pin it for the rest of the workflow
33
+ sootsim describe # smoke test — should print a render tree
34
+ ```
35
+
36
+ if you do not know the port, run `sootsim open` with no target and pick from
37
+ the detected dev servers. for hosted or unusual targets, pass the URL
38
+ explicitly:
39
+
40
+ ```sh
41
+ sootsim open 8081 # load a metro dev server
42
+ sootsim open https://my-app.local # load a hosted bundle
43
+ ```
44
+
45
+ ## you're done when
46
+
47
+ - `sootsim list` shows your sim and no orphans
48
+ - `sootsim describe` returns a render tree, not an error
49
+ - the same sim id appears in `sootsim describe`, `sootsim find`, and
50
+ every subsequent command
51
+ - `sootsim get errors 5` and `sootsim get requests 5` are quiet (or the
52
+ warnings are ones you understand)
53
+
54
+ ## recovery — common failure modes
55
+
56
+ **`sootsim list` is empty.** walk this checklist in order:
57
+
58
+ ```sh
59
+ sootsim daemon status # is the bridge daemon up?
60
+ sootsim runtime list # is at least one engine runtime installed?
61
+ sootsim open <port> # does loading explicitly work?
62
+ ```
63
+
64
+ if daemon is down: run `sootsim setup`, or `sootsim serve` in another shell for
65
+ a foreground bridge. if no runtime is installed, `sootsim open` installs it
66
+ before launching. if open errors with "port unreachable": confirm your dev
67
+ server is actually serving — the bundler has to be up before sootsim can
68
+ attach.
69
+
70
+ **two sims appear unexpectedly.** an earlier `sootsim claim` didn't
71
+ release on exit. close the orphan explicitly:
72
+
73
+ ```sh
74
+ sootsim list # note the stale id
75
+ sootsim close <id> # release it cleanly
76
+ ```
77
+
78
+ **`sootsim open` errors with "no runtime".** the engine binary isn't installed.
79
+ Run `sootsim runtime install`, then retry `sootsim open <port>`.
80
+
81
+ **bridge disconnects mid-sim.** the WebSocket dropped (laptop slept,
82
+ network blip). re-pin: `sootsim use <id>`. the daemon retries reconnection
83
+ automatically; you usually just need to re-issue the command.
84
+
85
+ **"sim held by another CLI".** another agent or your own previous CLI
86
+ process has the lease. find it (`sootsim list`), close it (`sootsim close
87
+ <id>`), or start a clean sim (`sootsim open --new`) — do **not**
88
+ `sootsim claim --force`.
89
+
90
+ ## related
91
+
92
+ - `/sootsim-debug` — once setup is good, this is where you debug
93
+ rendering, performance, and accessibility issues.
94
+ - `/sootsim-test` — write or run automated flows against the connected
95
+ sim.
96
+ - `/sootsim-visual` — pixel-level rendering comparisons.