@reticlehq/server 3.5.0 → 3.7.0

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 (721) hide show
  1. package/README.md +1 -1
  2. package/SKILL.md +123 -116
  3. package/dist/chromium-launch-options.d.ts +3 -1
  4. package/dist/chromium-launch-options.js +2 -1
  5. package/dist/command/cli/adhoc-suite.d.ts +14 -0
  6. package/dist/command/cli/adhoc-suite.js +42 -7
  7. package/dist/command/cli/adhoc-verdict.d.ts +19 -2
  8. package/dist/command/cli/adhoc-verdict.js +76 -9
  9. package/dist/command/cli/answers/gate-exit.d.ts +23 -0
  10. package/dist/command/cli/answers/gate-exit.js +45 -0
  11. package/dist/command/cli/answers/gate-hook-message.d.ts +2 -0
  12. package/dist/command/cli/answers/gate-hook-message.js +3 -1
  13. package/dist/command/cli/answers/open-note.d.ts +2 -0
  14. package/dist/command/cli/answers/open-note.js +22 -0
  15. package/dist/command/cli/auth/device-flow.d.ts +13 -2
  16. package/dist/command/cli/auth/device-flow.js +17 -0
  17. package/dist/command/cli/cli-doctor.js +14 -0
  18. package/dist/command/cli/cli-flow-commands.d.ts +0 -11
  19. package/dist/command/cli/cli-flow-commands.js +31 -112
  20. package/dist/command/cli/cli-kill.js +3 -2
  21. package/dist/command/cli/cli-parse-grammar.d.ts +24 -0
  22. package/dist/command/cli/cli-parse-grammar.js +75 -0
  23. package/dist/command/cli/cli-parse-verify.d.ts +2 -0
  24. package/dist/command/cli/cli-parse-verify.js +18 -0
  25. package/dist/command/cli/cli-parse.d.ts +19 -28
  26. package/dist/command/cli/cli-parse.js +82 -182
  27. package/dist/command/cli/cli-update-commands.d.ts +1 -1
  28. package/dist/command/cli/cli-update-commands.js +61 -9
  29. package/dist/command/cli/cli-usage.d.ts +33 -0
  30. package/dist/command/cli/cli-usage.js +287 -0
  31. package/dist/command/cli/cli-verify.d.ts +35 -5
  32. package/dist/command/cli/cli-verify.js +114 -35
  33. package/dist/command/cli/cloud-cli.d.ts +13 -0
  34. package/dist/command/cli/cloud-cli.js +192 -341
  35. package/dist/command/cli/cloud-kit.d.ts +12 -0
  36. package/dist/command/cli/cloud-kit.js +41 -2
  37. package/dist/command/cli/cloud-link.d.ts +57 -0
  38. package/dist/command/cli/cloud-link.js +308 -0
  39. package/dist/command/cli/cloud-login.d.ts +22 -0
  40. package/dist/command/cli/cloud-login.js +96 -8
  41. package/dist/command/cli/context-command.d.ts +1 -0
  42. package/dist/command/cli/context-command.js +33 -0
  43. package/dist/command/cli/daemon-start-options.d.ts +3 -0
  44. package/dist/command/cli/daemon-start-options.js +24 -3
  45. package/dist/command/cli/doctor/browser/chromium-hint.d.ts +46 -0
  46. package/dist/command/cli/doctor/browser/chromium-hint.js +99 -1
  47. package/dist/command/cli/doctor/doctor-coverage-line.d.ts +2 -0
  48. package/dist/command/cli/doctor/doctor-coverage-line.js +47 -0
  49. package/dist/command/cli/doctor/doctor-project-line.d.ts +0 -12
  50. package/dist/command/cli/doctor/doctor-project-line.js +5 -4
  51. package/dist/command/cli/doctor/doctor-rows.d.ts +6 -0
  52. package/dist/command/cli/doctor/doctor-rows.js +6 -0
  53. package/dist/command/cli/doctor/doctor-signing-line.d.ts +38 -0
  54. package/dist/command/cli/doctor/doctor-signing-line.js +114 -0
  55. package/dist/command/cli/drive/drive-attach.d.ts +27 -2
  56. package/dist/command/cli/drive/drive-attach.js +71 -4
  57. package/dist/command/cli/drive/drive-command.d.ts +2 -1
  58. package/dist/command/cli/drive/drive-command.js +13 -7
  59. package/dist/command/cli/known-regression.d.ts +13 -0
  60. package/dist/command/cli/known-regression.js +34 -0
  61. package/dist/command/cli/launch/sdk-version-match.d.ts +12 -0
  62. package/dist/command/cli/launch/sdk-version-match.js +25 -0
  63. package/dist/command/cli/lifecycle/daemon-lifecycle.js +15 -3
  64. package/dist/command/cli/mcp-command.d.ts +6 -0
  65. package/dist/command/cli/mcp-command.js +13 -5
  66. package/dist/command/cli/ports/port-holder.d.ts +10 -0
  67. package/dist/command/cli/ports/port-holder.js +25 -1
  68. package/dist/command/cli/project-name.d.ts +29 -1
  69. package/dist/command/cli/project-name.js +107 -2
  70. package/dist/command/cli/setup-mcp-cli.d.ts +17 -1
  71. package/dist/command/cli/setup-mcp-cli.js +35 -12
  72. package/dist/command/cli/status/status-lines.d.ts +1 -0
  73. package/dist/command/cli/status/status-lines.js +47 -2
  74. package/dist/command/cli/status/workspace-links.d.ts +10 -0
  75. package/dist/command/cli/status/workspace-links.js +29 -0
  76. package/dist/command/cli/try-command.d.ts +96 -0
  77. package/dist/command/cli/try-command.js +362 -0
  78. package/dist/command/cli/tutorial.d.ts +0 -100
  79. package/dist/command/cli/tutorial.js +0 -181
  80. package/dist/command/cli/verify-results.d.ts +19 -0
  81. package/dist/command/cli/verify-results.js +29 -0
  82. package/dist/command/cli-onboarding.d.ts +0 -11
  83. package/dist/command/cli-onboarding.js +0 -15
  84. package/dist/command/cli.d.ts +20 -0
  85. package/dist/command/cli.js +130 -104
  86. package/dist/command/daemon/binding/daemon-status-probe.d.ts +2 -0
  87. package/dist/command/daemon/binding/daemon-status-probe.js +1 -0
  88. package/dist/command/daemon/daemon-resilience.js +4 -4
  89. package/dist/command/daemon/daemon-resolve.d.ts +23 -1
  90. package/dist/command/daemon/daemon-resolve.js +79 -9
  91. package/dist/command/setup/agent-writer.d.ts +1 -1
  92. package/dist/command/setup/agent-writer.js +3 -2
  93. package/dist/command/setup/bringup/bridge-port.d.ts +3 -1
  94. package/dist/command/setup/bringup/bridge-port.js +13 -3
  95. package/dist/command/setup/bringup/connect-lease.d.ts +1 -0
  96. package/dist/command/setup/bringup/connect-lease.js +1 -0
  97. package/dist/command/setup/bringup/dev-server-log-cap.js +2 -0
  98. package/dist/command/setup/bringup/dev-server-wait.d.ts +8 -0
  99. package/dist/command/setup/bringup/dev-server-wait.js +19 -0
  100. package/dist/command/setup/bringup/ensure-daemon.js +9 -2
  101. package/dist/command/setup/init/agent-restart.d.ts +23 -0
  102. package/dist/command/setup/init/agent-restart.js +28 -0
  103. package/dist/command/setup/init/init-port.d.ts +14 -1
  104. package/dist/command/setup/init/init-port.js +32 -2
  105. package/dist/command/setup/init/init-runtime.d.ts +22 -2
  106. package/dist/command/setup/init/init-runtime.js +114 -38
  107. package/dist/command/setup/node-effects.d.ts +2 -0
  108. package/dist/command/setup/node-effects.js +38 -9
  109. package/dist/command/setup/probe/existing-app.d.ts +12 -0
  110. package/dist/command/setup/probe/existing-app.js +14 -0
  111. package/dist/command/setup/remaining-steps.js +2 -1
  112. package/dist/command/setup/run-setup.d.ts +34 -9
  113. package/dist/command/setup/run-setup.js +65 -51
  114. package/dist/command/setup/setup-command.d.ts +25 -1
  115. package/dist/command/setup/setup-command.js +59 -4
  116. package/dist/command/setup/setup-mcp.js +25 -2
  117. package/dist/command/setup/tauri-signing.d.ts +19 -0
  118. package/dist/command/setup/tauri-signing.js +79 -0
  119. package/dist/command/setup/terminal/listeners.d.ts +10 -1
  120. package/dist/command/setup/terminal/listeners.js +37 -6
  121. package/dist/command/update/update-nudge.d.ts +9 -0
  122. package/dist/command/update/update-nudge.js +1 -1
  123. package/dist/command/update/updater.js +11 -15
  124. package/dist/command/version/version-nudge.js +3 -0
  125. package/dist/command/version/version-skew.d.ts +20 -1
  126. package/dist/command/version/version-skew.js +49 -4
  127. package/dist/features/crawl/crawl-tools.js +4 -0
  128. package/dist/features/crawl/crawl.d.ts +6 -0
  129. package/dist/features/crawl/crawl.js +23 -2
  130. package/dist/features/exhaust/ledger.d.ts +21 -14
  131. package/dist/features/exhaust/ledger.js +35 -9
  132. package/dist/features/harness/app-findings.d.ts +2 -0
  133. package/dist/features/harness/app-findings.js +52 -0
  134. package/dist/features/harness/drive-report.d.ts +61 -1
  135. package/dist/features/harness/drive-report.js +394 -26
  136. package/dist/features/harness/drive-runs.d.ts +120 -0
  137. package/dist/features/harness/drive-runs.js +289 -0
  138. package/dist/features/harness/drivers.d.ts +10 -14
  139. package/dist/features/harness/drivers.js +10 -14
  140. package/dist/features/harness/explore/console-pages.d.ts +15 -0
  141. package/dist/features/harness/explore/console-pages.js +146 -0
  142. package/dist/features/harness/explore/disparity.d.ts +19 -0
  143. package/dist/features/harness/explore/disparity.js +71 -0
  144. package/dist/features/harness/explore/fake-app.d.ts +16 -0
  145. package/dist/features/harness/explore/fake-app.js +49 -0
  146. package/dist/features/harness/explore/goal-search.d.ts +26 -0
  147. package/dist/features/harness/explore/goal-search.js +144 -0
  148. package/dist/features/harness/explore/page-tree.d.ts +49 -0
  149. package/dist/features/harness/explore/page-tree.js +148 -0
  150. package/dist/features/harness/explore/site-map.d.ts +34 -0
  151. package/dist/features/harness/explore/site-map.js +150 -0
  152. package/dist/features/harness/fill-values.d.ts +3 -73
  153. package/dist/features/harness/fill-values.js +3 -169
  154. package/dist/features/harness/goals.d.ts +82 -0
  155. package/dist/features/harness/goals.js +330 -0
  156. package/dist/features/harness/harness.d.ts +51 -1
  157. package/dist/features/harness/harness.js +207 -6
  158. package/dist/features/harness/platform/drive-target.d.ts +30 -0
  159. package/dist/features/harness/platform/drive-target.js +81 -0
  160. package/dist/features/harness/platform/local-apps.d.ts +127 -0
  161. package/dist/features/harness/platform/local-apps.js +280 -0
  162. package/dist/features/harness/platform/persona-credentials.d.ts +20 -0
  163. package/dist/features/harness/platform/persona-credentials.js +69 -0
  164. package/dist/features/harness/platform/platform-drives.d.ts +61 -0
  165. package/dist/features/harness/platform/platform-drives.js +114 -0
  166. package/dist/features/harness/platform/refusal.d.ts +52 -0
  167. package/dist/features/harness/platform/refusal.js +71 -0
  168. package/dist/features/harness/platform/remote-drive.d.ts +186 -0
  169. package/dist/features/harness/platform/remote-drive.js +378 -0
  170. package/dist/features/harness/platform/script.d.ts +94 -0
  171. package/dist/features/harness/platform/script.js +260 -0
  172. package/dist/features/harness/platform/server-driver.d.ts +54 -0
  173. package/dist/features/harness/platform/server-driver.js +182 -0
  174. package/dist/features/harness/platform-config.d.ts +41 -1
  175. package/dist/features/harness/platform-config.js +106 -9
  176. package/dist/features/harness/route-guess.d.ts +13 -0
  177. package/dist/features/harness/route-guess.js +49 -0
  178. package/dist/features/harness/script/app-controls.d.ts +5 -0
  179. package/dist/features/harness/script/app-controls.js +40 -0
  180. package/dist/features/harness/script/lane-ids.d.ts +14 -0
  181. package/dist/features/harness/script/lane-ids.js +16 -0
  182. package/dist/features/harness/script/script-run.d.ts +70 -0
  183. package/dist/features/harness/script/script-run.js +606 -0
  184. package/dist/features/license/license.d.ts +2 -2
  185. package/dist/features/visual/step-shots.d.ts +31 -0
  186. package/dist/features/visual/step-shots.js +231 -0
  187. package/dist/features/visual/visual-tools.d.ts +10 -1
  188. package/dist/features/visual/visual-tools.js +62 -17
  189. package/dist/hooks/client-directory.d.ts +18 -0
  190. package/dist/hooks/client-directory.js +57 -0
  191. package/dist/hooks/coding-agents.d.ts +34 -0
  192. package/dist/hooks/coding-agents.js +117 -0
  193. package/dist/hooks/driven-by.d.ts +23 -0
  194. package/dist/hooks/driven-by.js +56 -0
  195. package/dist/hooks/hook-bus.d.ts +4 -0
  196. package/dist/hooks/hook-bus.js +18 -0
  197. package/dist/hooks/hook-commands.js +15 -4
  198. package/dist/hooks/tool-log.d.ts +9 -0
  199. package/dist/hooks/tool-log.js +29 -0
  200. package/dist/index.d.ts +2 -0
  201. package/dist/index.js +80 -243
  202. package/dist/judgement/capsule/capsule-store.d.ts +2 -2
  203. package/dist/judgement/capsule/causal-summary.d.ts +15 -1
  204. package/dist/judgement/capsule/causal-summary.js +33 -0
  205. package/dist/judgement/runs/artifact/build-verification-run.d.ts +1 -1
  206. package/dist/judgement/runs/artifact/build-verification-run.js +25 -3
  207. package/dist/judgement/runs/artifact/gap-summary.d.ts +0 -18
  208. package/dist/judgement/runs/artifact/gap-summary.js +12 -3
  209. package/dist/judgement/runs/artifact/replay-mapping.d.ts +1 -1
  210. package/dist/judgement/runs/artifact/replay-mapping.js +37 -11
  211. package/dist/judgement/runs/artifact/run-store.d.ts +14 -2
  212. package/dist/judgement/runs/artifact/run-store.js +195 -3
  213. package/dist/judgement/runs/context-tools.js +59 -1
  214. package/dist/judgement/runs/default-run-id.d.ts +3 -0
  215. package/dist/judgement/runs/default-run-id.js +16 -0
  216. package/dist/judgement/runs/drive-run.d.ts +71 -1
  217. package/dist/judgement/runs/drive-run.js +317 -5
  218. package/dist/judgement/runs/repair-prompt.js +1 -1
  219. package/dist/judgement/runs/resume.d.ts +44 -0
  220. package/dist/judgement/runs/resume.js +137 -0
  221. package/dist/judgement/runs/reticle-runner.js +13 -3
  222. package/dist/judgement/runs/runner-port.d.ts +5 -1
  223. package/dist/judgement/runs/runner-port.js +8 -2
  224. package/dist/judgement/runs/verification-sync.d.ts +5 -2
  225. package/dist/judgement/runs/verification-sync.js +40 -18
  226. package/dist/language/flows/change/gate.d.ts +10 -0
  227. package/dist/language/flows/change/gate.js +22 -0
  228. package/dist/language/flows/decision.js +36 -1
  229. package/dist/language/flows/fields/flow-secret-field.d.ts +12 -0
  230. package/dist/language/flows/fields/flow-secret-field.js +25 -2
  231. package/dist/language/flows/flow-anchor.d.ts +61 -10
  232. package/dist/language/flows/flow-anchor.js +98 -6
  233. package/dist/language/flows/flow-cross-step.d.ts +15 -0
  234. package/dist/language/flows/flow-cross-step.js +21 -0
  235. package/dist/language/flows/flow-intent.d.ts +1 -0
  236. package/dist/language/flows/flow-journey.d.ts +6 -0
  237. package/dist/language/flows/flow-journey.js +20 -0
  238. package/dist/language/flows/flow-learning.d.ts +4 -0
  239. package/dist/language/flows/flow-learning.js +45 -14
  240. package/dist/language/flows/flow-mutate-tools.js +5 -3
  241. package/dist/language/flows/flow-replay-run.d.ts +23 -9
  242. package/dist/language/flows/flow-replay-run.js +115 -110
  243. package/dist/language/flows/flow-replay-types.d.ts +1 -1
  244. package/dist/language/flows/flow-replay.d.ts +40 -1
  245. package/dist/language/flows/flow-replay.js +110 -22
  246. package/dist/language/flows/flow-result.d.ts +22 -1
  247. package/dist/language/flows/flow-result.js +47 -2
  248. package/dist/language/flows/flow-scope.js +5 -1
  249. package/dist/language/flows/flow-step-runners.d.ts +22 -2
  250. package/dist/language/flows/flow-step-runners.js +247 -47
  251. package/dist/language/flows/flow-store-for-session.d.ts +2 -2
  252. package/dist/language/flows/flow-store-for-session.js +7 -3
  253. package/dist/language/flows/flow-tools.d.ts +10 -0
  254. package/dist/language/flows/flow-tools.js +112 -89
  255. package/dist/language/flows/flows.d.ts +16 -1
  256. package/dist/language/flows/flows.js +74 -12
  257. package/dist/language/flows/heal-run.js +6 -4
  258. package/dist/language/flows/narrow-write.d.ts +7 -0
  259. package/dist/language/flows/narrow-write.js +36 -1
  260. package/dist/language/flows/recording/flake.d.ts +2 -2
  261. package/dist/language/flows/recording/recording-backtrack.js +14 -1
  262. package/dist/language/flows/recording/tape/recordings.d.ts +58 -4
  263. package/dist/language/flows/recording/tape/recordings.js +95 -13
  264. package/dist/language/flows/replay-from-hud.d.ts +20 -0
  265. package/dist/language/flows/replay-from-hud.js +51 -0
  266. package/dist/language/flows/replay.d.ts +9 -5
  267. package/dist/language/flows/replay.js +56 -15
  268. package/dist/language/flows/single-replay.d.ts +7 -0
  269. package/dist/language/flows/single-replay.js +26 -0
  270. package/dist/language/flows/suite/suite-flakes.js +2 -0
  271. package/dist/language/flows/suite-selection.d.ts +2 -15
  272. package/dist/language/flows/suite-selection.js +4 -3
  273. package/dist/language/flows/verify-change-tools.d.ts +1 -0
  274. package/dist/language/flows/verify-change-tools.js +202 -191
  275. package/dist/launch-chromium.d.ts +27 -5
  276. package/dist/launch-chromium.js +38 -8
  277. package/dist/memory/cloud/cloud-config.d.ts +22 -1
  278. package/dist/memory/cloud/cloud-config.js +34 -5
  279. package/dist/memory/cloud/cloud-sync.d.ts +17 -14
  280. package/dist/memory/cloud/cloud-sync.js +15 -4
  281. package/dist/memory/cloud/harness-config.d.ts +75 -1
  282. package/dist/memory/cloud/harness-config.js +115 -24
  283. package/dist/memory/cloud/hud-notices-source.d.ts +21 -0
  284. package/dist/memory/cloud/hud-notices-source.js +128 -0
  285. package/dist/memory/cloud/memory-scope.d.ts +161 -0
  286. package/dist/memory/cloud/memory-scope.js +227 -0
  287. package/dist/memory/cloud/sync-cycle.d.ts +44 -7
  288. package/dist/memory/cloud/sync-cycle.js +129 -15
  289. package/dist/memory/cloud/sync-daemon.d.ts +11 -0
  290. package/dist/memory/cloud/sync-daemon.js +121 -9
  291. package/dist/memory/cloud/sync-disk.d.ts +1 -1
  292. package/dist/memory/cloud/sync-disk.js +31 -10
  293. package/dist/memory/cloud/sync-screenshots.d.ts +32 -0
  294. package/dist/memory/cloud/sync-screenshots.js +105 -0
  295. package/dist/memory/cloud/unsynced-roots.d.ts +47 -0
  296. package/dist/memory/cloud/unsynced-roots.js +166 -0
  297. package/dist/memory/impact/account-watch.d.ts +34 -0
  298. package/dist/memory/impact/account-watch.js +59 -0
  299. package/dist/memory/impact/impact-recorder.d.ts +8 -0
  300. package/dist/memory/impact/impact-recorder.js +12 -2
  301. package/dist/memory/impact/impact-store.d.ts +17 -4
  302. package/dist/memory/impact/impact-store.js +169 -63
  303. package/dist/memory/intent/inline-intent.d.ts +1 -0
  304. package/dist/memory/intent/intent-shard-store.js +16 -4
  305. package/dist/memory/intent/intent-shard.d.ts +14 -2
  306. package/dist/memory/intent/intent-store.d.ts +1 -0
  307. package/dist/memory/intent/intent-tools.js +122 -4
  308. package/dist/memory/intent/open-intents.d.ts +6 -0
  309. package/dist/memory/intent/open-intents.js +10 -1
  310. package/dist/memory/intent/settled-words.d.ts +24 -0
  311. package/dist/memory/intent/settled-words.js +130 -0
  312. package/dist/memory/journal/drive-flow.d.ts +16 -0
  313. package/dist/memory/journal/drive-flow.js +34 -2
  314. package/dist/memory/journal/drive-run-flush.d.ts +2 -0
  315. package/dist/memory/journal/drive-run-flush.js +20 -5
  316. package/dist/memory/journal/envelope.d.ts +8 -8
  317. package/dist/memory/journal/journal-recorder.js +52 -3
  318. package/dist/memory/journal/on-disk/retention.d.ts +8 -0
  319. package/dist/memory/journal/on-disk/retention.js +32 -2
  320. package/dist/memory/journal/on-disk/startup-maintenance.js +3 -1
  321. package/dist/memory/journal/on-disk/workspace-tiers.js +9 -4
  322. package/dist/memory/journal/session-end.d.ts +15 -1
  323. package/dist/memory/journal/session-end.js +42 -9
  324. package/dist/memory/project/artifact-root-resolver.d.ts +26 -1
  325. package/dist/memory/project/artifact-root-resolver.js +125 -16
  326. package/dist/memory/project/artifact-root.d.ts +46 -8
  327. package/dist/memory/project/artifact-root.js +89 -10
  328. package/dist/memory/project/dir/reticle-dir.d.ts +18 -2
  329. package/dist/memory/project/dir/reticle-dir.js +26 -3
  330. package/dist/memory/project/link-directory.d.ts +15 -0
  331. package/dist/memory/project/link-directory.js +44 -0
  332. package/dist/memory/project/project-tools.js +22 -3
  333. package/dist/memory/project/root-claims.d.ts +6 -0
  334. package/dist/memory/project/root-claims.js +39 -0
  335. package/dist/memory/project/session-root.d.ts +26 -1
  336. package/dist/memory/project/session-root.js +49 -5
  337. package/dist/memory/project/sync-status.d.ts +85 -0
  338. package/dist/memory/project/sync-status.js +224 -0
  339. package/dist/memory/recall/memory-tools.js +47 -2
  340. package/dist/memory/recall/platform-memory.d.ts +34 -0
  341. package/dist/memory/recall/platform-memory.js +139 -0
  342. package/dist/memory/recall/project-memory.d.ts +19 -0
  343. package/dist/memory/recall/project-memory.js +80 -13
  344. package/dist/portal/bridge/bridge.d.ts +9 -3
  345. package/dist/portal/bridge/bridge.js +82 -22
  346. package/dist/portal/bridge/harness-request.d.ts +23 -0
  347. package/dist/portal/bridge/harness-request.js +27 -0
  348. package/dist/portal/bridge/pairing-token.d.ts +9 -0
  349. package/dist/portal/bridge/pairing-token.js +17 -0
  350. package/dist/portal/bridge/wrong-path.d.ts +17 -0
  351. package/dist/portal/bridge/wrong-path.js +35 -0
  352. package/dist/portal/input/network-mock-tools.js +11 -2
  353. package/dist/portal/input/real-input.d.ts +83 -10
  354. package/dist/portal/input/real-input.js +218 -30
  355. package/dist/portal/input/viewport-tools.js +3 -3
  356. package/dist/portal/pool/browser-pool.d.ts +70 -9
  357. package/dist/portal/pool/browser-pool.js +190 -37
  358. package/dist/portal/pool/context-permissions.d.ts +33 -0
  359. package/dist/portal/pool/context-permissions.js +33 -0
  360. package/dist/portal/pool/lease-marker-stamp.d.ts +23 -0
  361. package/dist/portal/pool/lease-marker-stamp.js +49 -0
  362. package/dist/portal/pool/playwright-launcher.d.ts +35 -0
  363. package/dist/portal/pool/playwright-launcher.js +64 -3
  364. package/dist/portal/pool/pool-contract.d.ts +28 -5
  365. package/dist/portal/session/agent-link.d.ts +8 -0
  366. package/dist/portal/session/agent-link.js +17 -0
  367. package/dist/portal/session/command-payload.d.ts +8 -0
  368. package/dist/portal/session/command-payload.js +24 -0
  369. package/dist/portal/session/daemon-answers.d.ts +3 -3
  370. package/dist/portal/session/daemon-answers.js +4 -2
  371. package/dist/portal/session/dev-server/dev-command.d.ts +21 -0
  372. package/dist/portal/session/dev-server/dev-command.js +87 -12
  373. package/dist/portal/session/facts/departure-note.d.ts +22 -0
  374. package/dist/portal/session/facts/departure-note.js +47 -0
  375. package/dist/portal/session/facts/observed-state.d.ts +16 -18
  376. package/dist/portal/session/facts/observed-state.js +46 -3
  377. package/dist/portal/session/facts/session-replaced.d.ts +5 -0
  378. package/dist/portal/session/facts/session-replaced.js +5 -0
  379. package/dist/portal/session/first-run-wiring.d.ts +42 -0
  380. package/dist/portal/session/first-run-wiring.js +132 -0
  381. package/dist/portal/session/human/live-control.d.ts +9 -2
  382. package/dist/portal/session/human/live-control.js +12 -3
  383. package/dist/portal/session/human/notes-ledger.d.ts +20 -0
  384. package/dist/portal/session/human/notes-ledger.js +55 -0
  385. package/dist/portal/session/human/review-store.d.ts +12 -0
  386. package/dist/portal/session/human/review-store.js +18 -10
  387. package/dist/portal/session/live-control-tools.d.ts +0 -13
  388. package/dist/portal/session/live-control-tools.js +107 -13
  389. package/dist/portal/session/narration-args.d.ts +5 -0
  390. package/dist/portal/session/narration-args.js +17 -0
  391. package/dist/portal/session/no-session-diagnosis.d.ts +8 -1
  392. package/dist/portal/session/no-session-diagnosis.js +46 -9
  393. package/dist/portal/session/no-session-next-action.d.ts +31 -0
  394. package/dist/portal/session/no-session-next-action.js +159 -60
  395. package/dist/portal/session/no-session-watch.d.ts +14 -1
  396. package/dist/portal/session/no-session-watch.js +227 -17
  397. package/dist/portal/session/presence/session-lease.js +1 -1
  398. package/dist/portal/session/presence/session-mirror.js +3 -0
  399. package/dist/portal/session/recorded-gaps.d.ts +97 -0
  400. package/dist/portal/session/recorded-gaps.js +251 -0
  401. package/dist/portal/session/serving-directory.d.ts +27 -0
  402. package/dist/portal/session/serving-directory.js +45 -0
  403. package/dist/portal/session/session-health.d.ts +18 -0
  404. package/dist/portal/session/session-health.js +9 -1
  405. package/dist/portal/session/session-info.d.ts +8 -1
  406. package/dist/portal/session/session-info.js +8 -1
  407. package/dist/portal/session/session-manager.d.ts +39 -0
  408. package/dist/portal/session/session-manager.js +98 -11
  409. package/dist/portal/session/session-reaper.js +4 -1
  410. package/dist/portal/session/session-successor.d.ts +13 -0
  411. package/dist/portal/session/session-successor.js +1 -1
  412. package/dist/portal/session/session-tools.js +26 -3
  413. package/dist/portal/session/session.d.ts +22 -30
  414. package/dist/portal/session/session.js +81 -79
  415. package/dist/portal/session/timing/command-timeout.js +25 -1
  416. package/dist/portal/session/timing/wall-clock.d.ts +1 -1
  417. package/dist/portal/session/timing/wall-clock.js +1 -1
  418. package/dist/portal/session/zero-install-first-call.d.ts +31 -0
  419. package/dist/portal/session/zero-install-first-call.js +88 -0
  420. package/dist/start-options.d.ts +12 -0
  421. package/dist/start-wiring.d.ts +63 -0
  422. package/dist/start-wiring.js +169 -0
  423. package/dist/status-payload.d.ts +23 -1
  424. package/dist/status-payload.js +36 -1
  425. package/dist/surface/http-server.js +18 -2
  426. package/dist/surface/mcp/attach-memory.d.ts +1 -0
  427. package/dist/surface/mcp/attach-memory.js +12 -1
  428. package/dist/surface/mcp/mcp-proxy.d.ts +9 -0
  429. package/dist/surface/mcp/mcp-proxy.js +65 -13
  430. package/dist/surface/mcp/mcp.d.ts +34 -6
  431. package/dist/surface/mcp/mcp.js +61 -17
  432. package/dist/surface/mcp/proxy/drive-calls.d.ts +10 -0
  433. package/dist/surface/mcp/proxy/drive-calls.js +27 -0
  434. package/dist/surface/mcp/proxy/mcp-post-transport.js +5 -0
  435. package/dist/surface/mcp/server-instructions.d.ts +4 -2
  436. package/dist/surface/mcp/server-instructions.js +32 -14
  437. package/dist/surface/mcp/shared-params.js +2 -2
  438. package/dist/surface/mcp/surface-vocabulary.d.ts +2 -0
  439. package/dist/surface/mcp/surface-vocabulary.js +1 -0
  440. package/dist/surface/tools/account-tool.d.ts +22 -0
  441. package/dist/surface/tools/account-tool.js +157 -0
  442. package/dist/surface/tools/act/act-danger.d.ts +11 -0
  443. package/dist/surface/tools/act/act-danger.js +38 -1
  444. package/dist/surface/tools/act/act-observation.d.ts +33 -0
  445. package/dist/surface/tools/act/act-observation.js +57 -0
  446. package/dist/surface/tools/act/act-preflight.js +25 -2
  447. package/dist/surface/tools/act/act-target.js +8 -3
  448. package/dist/surface/tools/act/navigation/navigate-arrival.d.ts +8 -0
  449. package/dist/surface/tools/act/navigation/navigate-arrival.js +56 -2
  450. package/dist/surface/tools/act/resolve-target.d.ts +1 -1
  451. package/dist/surface/tools/act/resolve-target.js +18 -3
  452. package/dist/surface/tools/act/screen-request.d.ts +34 -0
  453. package/dist/surface/tools/act/screen-request.js +113 -0
  454. package/dist/surface/tools/act/sequence-grade.d.ts +8 -0
  455. package/dist/surface/tools/act/sequence-grade.js +13 -2
  456. package/dist/surface/tools/act/settle-in-flight.js +25 -3
  457. package/dist/surface/tools/act-sequence-tool.js +138 -29
  458. package/dist/surface/tools/act-tools.d.ts +0 -9
  459. package/dist/surface/tools/act-tools.js +71 -41
  460. package/dist/surface/tools/agent/app-notes-learning.d.ts +7 -0
  461. package/dist/surface/tools/agent/app-notes-learning.js +80 -0
  462. package/dist/surface/tools/agent/app-notes.d.ts +4 -0
  463. package/dist/surface/tools/agent/app-notes.js +48 -0
  464. package/dist/surface/tools/agent/build-staleness.d.ts +7 -0
  465. package/dist/surface/tools/agent/build-staleness.js +62 -0
  466. package/dist/surface/tools/agent/compact-envelope.d.ts +80 -0
  467. package/dist/surface/tools/agent/compact-envelope.js +374 -0
  468. package/dist/surface/tools/agent/for-the-agent.d.ts +12 -0
  469. package/dist/surface/tools/agent/for-the-agent.js +44 -0
  470. package/dist/surface/tools/agent/notices.d.ts +50 -0
  471. package/dist/surface/tools/agent/notices.js +152 -0
  472. package/dist/surface/tools/agent/reteach.d.ts +11 -0
  473. package/dist/surface/tools/agent/reteach.js +50 -0
  474. package/dist/surface/tools/args/alias-args.d.ts +5 -0
  475. package/dist/surface/tools/args/alias-args.js +10 -0
  476. package/dist/surface/tools/args/confirm-dangerous-arg.d.ts +6 -0
  477. package/dist/surface/tools/args/confirm-dangerous-arg.js +6 -0
  478. package/dist/surface/tools/assert/assert-source.d.ts +15 -0
  479. package/dist/surface/tools/assert/assert-source.js +40 -0
  480. package/dist/surface/tools/assert/assert-verdict.d.ts +1 -1
  481. package/dist/surface/tools/assert/assert-verdict.js +42 -17
  482. package/dist/surface/tools/browser-tools.js +51 -2
  483. package/dist/surface/tools/chat-drives.d.ts +101 -0
  484. package/dist/surface/tools/chat-drives.js +409 -0
  485. package/dist/surface/tools/coverage-tools.d.ts +2 -10
  486. package/dist/surface/tools/coverage-tools.js +2 -53
  487. package/dist/surface/tools/dynamic-tools.js +29 -1
  488. package/dist/surface/tools/empty-session-list.d.ts +51 -0
  489. package/dist/surface/tools/empty-session-list.js +120 -0
  490. package/dist/surface/tools/error-recovery.d.ts +14 -0
  491. package/dist/surface/tools/error-recovery.js +105 -8
  492. package/dist/surface/tools/explore-tools.d.ts +31 -1
  493. package/dist/surface/tools/explore-tools.js +438 -66
  494. package/dist/surface/tools/feedback-tools.d.ts +2 -3
  495. package/dist/surface/tools/feedback-tools.js +18 -3
  496. package/dist/surface/tools/gap-novelty.d.ts +3 -1
  497. package/dist/surface/tools/gap-novelty.js +8 -1
  498. package/dist/surface/tools/harness-explore.d.ts +118 -57
  499. package/dist/surface/tools/harness-explore.js +344 -292
  500. package/dist/surface/tools/harness-gate.d.ts +88 -0
  501. package/dist/surface/tools/harness-gate.js +235 -0
  502. package/dist/surface/tools/harness-hunt.d.ts +43 -0
  503. package/dist/surface/tools/harness-hunt.js +215 -0
  504. package/dist/surface/tools/harness-plan.d.ts +17 -0
  505. package/dist/surface/tools/harness-plan.js +38 -0
  506. package/dist/surface/tools/harness-script.d.ts +30 -0
  507. package/dist/surface/tools/harness-script.js +560 -0
  508. package/dist/surface/tools/harness-tab-guard.d.ts +5 -0
  509. package/dist/surface/tools/harness-tab-guard.js +27 -0
  510. package/dist/surface/tools/harness-toolset.d.ts +22 -1
  511. package/dist/surface/tools/harness-toolset.js +101 -7
  512. package/dist/surface/tools/human-notes.d.ts +16 -0
  513. package/dist/surface/tools/human-notes.js +27 -0
  514. package/dist/surface/tools/invoke-tool.d.ts +5 -2
  515. package/dist/surface/tools/invoke-tool.js +263 -85
  516. package/dist/surface/tools/lease-hint.js +26 -5
  517. package/dist/surface/tools/lease-permissions.d.ts +33 -0
  518. package/dist/surface/tools/lease-permissions.js +73 -0
  519. package/dist/surface/tools/lease-readiness.d.ts +38 -0
  520. package/dist/surface/tools/lease-readiness.js +57 -0
  521. package/dist/surface/tools/lease-seed.d.ts +49 -0
  522. package/dist/surface/tools/lease-seed.js +167 -0
  523. package/dist/surface/tools/lease-tools.d.ts +13 -24
  524. package/dist/surface/tools/lease-tools.js +146 -197
  525. package/dist/surface/tools/live-call-text.js +4 -4
  526. package/dist/surface/tools/merge-tools.js +42 -2
  527. package/dist/surface/tools/merged-name-redirect.js +4 -0
  528. package/dist/surface/tools/next-step.d.ts +29 -0
  529. package/dist/surface/tools/next-step.js +214 -0
  530. package/dist/surface/tools/observe-tools.js +45 -9
  531. package/dist/surface/tools/platform-moment.d.ts +72 -0
  532. package/dist/surface/tools/platform-moment.js +296 -0
  533. package/dist/surface/tools/query-hint-schema.d.ts +7 -0
  534. package/dist/surface/tools/query-hint-schema.js +10 -0
  535. package/dist/surface/tools/read-tools.js +71 -14
  536. package/dist/surface/tools/real-input-attempt.js +96 -13
  537. package/dist/surface/tools/reticle-result.d.ts +120 -0
  538. package/dist/surface/tools/reticle-result.js +364 -0
  539. package/dist/surface/tools/tool-kit.d.ts +83 -3
  540. package/dist/surface/tools/tool-kit.js +77 -7
  541. package/dist/surface/tools/tools.js +43 -59
  542. package/dist/telemetry/account-envelope.d.ts +7 -0
  543. package/dist/telemetry/account-envelope.js +61 -0
  544. package/dist/telemetry/agent-client.d.ts +15 -0
  545. package/dist/telemetry/agent-client.js +57 -0
  546. package/dist/telemetry/app-instrumented.js +9 -2
  547. package/dist/telemetry/argument-shape.d.ts +7 -0
  548. package/dist/telemetry/argument-shape.js +86 -1
  549. package/dist/telemetry/automation-hint.d.ts +2 -3
  550. package/dist/telemetry/automation-hint.js +33 -8
  551. package/dist/telemetry/cli-telemetry.js +7 -2
  552. package/dist/telemetry/daemon-telemetry.js +3 -0
  553. package/dist/telemetry/error-fingerprint.d.ts +10 -1
  554. package/dist/telemetry/error-fingerprint.js +61 -5
  555. package/dist/telemetry/feedback-cli.d.ts +0 -13
  556. package/dist/telemetry/feedback-cli.js +0 -77
  557. package/dist/telemetry/feedback.d.ts +13 -0
  558. package/dist/telemetry/feedback.js +183 -17
  559. package/dist/telemetry/harness-run.d.ts +18 -0
  560. package/dist/telemetry/harness-run.js +80 -0
  561. package/dist/telemetry/hud-events.d.ts +16 -0
  562. package/dist/telemetry/hud-events.js +27 -0
  563. package/dist/telemetry/hud-metrics.d.ts +29 -6
  564. package/dist/telemetry/hud-metrics.js +116 -25
  565. package/dist/telemetry/init-telemetry.js +2 -2
  566. package/dist/telemetry/install-source.d.ts +13 -25
  567. package/dist/telemetry/install-source.js +44 -3
  568. package/dist/telemetry/mcp-connection.d.ts +0 -14
  569. package/dist/telemetry/mcp-connection.js +5 -1
  570. package/dist/telemetry/onboarding-firsts.d.ts +32 -0
  571. package/dist/telemetry/onboarding-firsts.js +81 -6
  572. package/dist/telemetry/platform-linked.d.ts +5 -0
  573. package/dist/telemetry/platform-linked.js +32 -0
  574. package/dist/telemetry/project-profile.js +5 -3
  575. package/dist/telemetry/proxy-telemetry.js +4 -1
  576. package/dist/telemetry/session-metrics.d.ts +15 -4
  577. package/dist/telemetry/session-metrics.js +88 -52
  578. package/dist/telemetry/telemetry.d.ts +38 -2
  579. package/dist/telemetry/telemetry.js +144 -34
  580. package/dist/telemetry/verification-of.d.ts +3 -1
  581. package/dist/telemetry/verification-of.js +13 -4
  582. package/dist/wire-journal.d.ts +2 -2
  583. package/dist/wire-journal.js +20 -6
  584. package/docs/README.md +3 -3
  585. package/docs/actions.mdx +6 -3
  586. package/docs/adapters.md +1 -1
  587. package/docs/agent-cheatsheet.md +25 -28
  588. package/docs/architecture.md +5 -5
  589. package/docs/autodrive.md +33 -28
  590. package/docs/benchmarks.md +5 -5
  591. package/docs/best-practices.mdx +27 -9
  592. package/docs/capabilities.mdx +14 -16
  593. package/docs/cli/affected.mdx +1 -1
  594. package/docs/cli/cloud.mdx +54 -75
  595. package/docs/cli/doctor.mdx +14 -3
  596. package/docs/cli/drive.mdx +20 -14
  597. package/docs/cli/feedback.mdx +3 -3
  598. package/docs/cli/gate.mdx +7 -2
  599. package/docs/cli/help.mdx +50 -55
  600. package/docs/cli/init.mdx +43 -28
  601. package/docs/cli/license.mdx +12 -8
  602. package/docs/cli/mcp.mdx +4 -4
  603. package/docs/cli/open.mdx +3 -3
  604. package/docs/cli/report.mdx +4 -2
  605. package/docs/cli/restart.mdx +2 -2
  606. package/docs/cli/rollback.mdx +14 -8
  607. package/docs/cli/serve.mdx +4 -4
  608. package/docs/cli/setup.mdx +23 -0
  609. package/docs/cli/status.mdx +18 -5
  610. package/docs/cli/stop.mdx +67 -8
  611. package/docs/cli/try.mdx +62 -0
  612. package/docs/cli/update.mdx +4 -3
  613. package/docs/cli/verify.mdx +17 -6
  614. package/docs/cli/version.mdx +5 -4
  615. package/docs/cli.mdx +111 -42
  616. package/docs/debugging.md +3 -3
  617. package/docs/deploy-checks.md +1 -1
  618. package/docs/desktop.mdx +9 -3
  619. package/docs/enterprise.md +11 -10
  620. package/docs/environment.mdx +7 -8
  621. package/docs/faq.mdx +3 -3
  622. package/docs/first-drive.md +5 -4
  623. package/docs/flows.md +35 -27
  624. package/docs/for-agents.md +4 -5
  625. package/docs/frameworks.mdx +32 -21
  626. package/docs/getting-started.md +65 -61
  627. package/docs/human-control.md +16 -16
  628. package/docs/index.mdx +15 -42
  629. package/docs/install-agentic.mdx +22 -37
  630. package/docs/install-manual.mdx +23 -13
  631. package/docs/instrumentation.mdx +5 -3
  632. package/docs/integration-patterns.md +7 -7
  633. package/docs/license-activation.mdx +1 -1
  634. package/docs/multi-agent-testing.md +24 -6
  635. package/docs/packages/babel-plugin.mdx +4 -2
  636. package/docs/packages/browser.mdx +16 -10
  637. package/docs/packages/core.mdx +12 -5
  638. package/docs/packages/electron.mdx +3 -2
  639. package/docs/packages/engine.mdx +1 -1
  640. package/docs/packages/eslint-plugin.mdx +18 -12
  641. package/docs/packages/next.mdx +8 -7
  642. package/docs/packages/open-verification.mdx +1 -1
  643. package/docs/packages/server.mdx +5 -5
  644. package/docs/packages/tauri.mdx +9 -9
  645. package/docs/packages/test.mdx +4 -10
  646. package/docs/packages/vite-plugin.mdx +32 -4
  647. package/docs/packages.mdx +11 -15
  648. package/docs/platform-integration.md +6 -5
  649. package/docs/predicates.mdx +40 -24
  650. package/docs/quickstart.mdx +69 -30
  651. package/docs/required-checks.md +8 -7
  652. package/docs/reticle-manual.md +15 -5
  653. package/docs/skill-file.mdx +17 -79
  654. package/docs/skill-setup.md +9 -9
  655. package/docs/skill.md +200 -0
  656. package/docs/system-map.md +7 -7
  657. package/docs/telemetry.md +23 -25
  658. package/docs/testing.md +4 -4
  659. package/docs/token-efficiency.md +12 -12
  660. package/docs/tools/act-and-wait.mdx +9 -2
  661. package/docs/tools/act-sequence.mdx +6 -7
  662. package/docs/tools/act.mdx +2 -2
  663. package/docs/tools/assert.mdx +18 -17
  664. package/docs/tools/console.mdx +9 -9
  665. package/docs/tools/inspect.mdx +16 -7
  666. package/docs/tools/look.mdx +24 -0
  667. package/docs/tools/navigate.mdx +5 -3
  668. package/docs/tools/network.mdx +2 -2
  669. package/docs/tools/observe.mdx +6 -6
  670. package/docs/tools/overview.mdx +34 -33
  671. package/docs/tools/query.mdx +5 -5
  672. package/docs/tools/session-and-feedback.mdx +22 -13
  673. package/docs/tools/sessions.mdx +8 -8
  674. package/docs/tools/snapshot.mdx +6 -5
  675. package/docs/tools/state.mdx +9 -9
  676. package/docs/tools/tools-and-run.mdx +26 -24
  677. package/docs/tools/verify.mdx +28 -0
  678. package/docs/tools/wait-for.mdx +8 -4
  679. package/docs/troubleshooting.mdx +21 -6
  680. package/docs/usage.md +55 -46
  681. package/docs/use-cases.mdx +3 -3
  682. package/docs/vs-chrome-devtools-mcp.mdx +9 -6
  683. package/docs/vs-playwright-mcp.mdx +3 -1
  684. package/docs/what-is-recorded.md +17 -5
  685. package/docs/what-is-reticle.mdx +5 -3
  686. package/docs/why-reticle.mdx +1 -1
  687. package/package.json +9 -12
  688. package/dist/command/cli/demo/demo-page.d.ts +0 -78
  689. package/dist/command/cli/demo/demo-page.js +0 -241
  690. package/dist/command/cli/demo/demo-run.d.ts +0 -38
  691. package/dist/command/cli/demo/demo-run.js +0 -138
  692. package/dist/features/harness/driver.d.ts +0 -50
  693. package/dist/features/harness/driver.js +0 -236
  694. package/dist/features/harness/jev-driver.d.ts +0 -188
  695. package/dist/features/harness/jev-driver.js +0 -678
  696. package/dist/features/harness/openai-driver.d.ts +0 -58
  697. package/dist/features/harness/openai-driver.js +0 -206
  698. package/dist/judgement/hunt/hunt-report.d.ts +0 -49
  699. package/dist/judgement/hunt/hunt-report.js +0 -84
  700. package/dist/language/flows/buddy-status.d.ts +0 -25
  701. package/dist/language/flows/buddy-status.js +0 -32
  702. package/dist/language/flows/change/watch-batcher.d.ts +0 -18
  703. package/dist/language/flows/change/watch-batcher.js +0 -19
  704. package/dist/memory/cloud/harness-offer.d.ts +0 -44
  705. package/dist/memory/cloud/harness-offer.js +0 -145
  706. package/dist/memory/project/dir/fill-value-store.d.ts +0 -32
  707. package/dist/memory/project/dir/fill-value-store.js +0 -88
  708. package/dist/surface/tools/feature-capture.d.ts +0 -151
  709. package/dist/surface/tools/feature-capture.js +0 -235
  710. package/dist/surface/tools/tool-hit-rate.d.ts +0 -87
  711. package/dist/surface/tools/tool-hit-rate.js +0 -90
  712. package/dist/telemetry/harness-drive.d.ts +0 -4
  713. package/dist/telemetry/harness-drive.js +0 -35
  714. package/dist/telemetry/identify.d.ts +0 -22
  715. package/dist/telemetry/identify.js +0 -73
  716. package/docs/cli/capsules.mdx +0 -70
  717. package/docs/cli/hunt.mdx +0 -73
  718. package/docs/cli/identify.mdx +0 -76
  719. package/docs/cli/kill.mdx +0 -91
  720. package/docs/cli/watch.mdx +0 -62
  721. package/docs/local-registry.md +0 -143
@@ -0,0 +1,79 @@
1
+ /**
2
+ * Sign the Tauri dev build Reticle starts with the project's own signing identity, so macOS stops
3
+ * asking for the keychain password.
4
+ *
5
+ * macOS ties a keychain item to the designated requirement of the app that saved it: its code
6
+ * identifier and its signing team. `tauri dev` produces an ad-hoc signed binary named after the
7
+ * crate, so every keychain read from it is a different app asking, and macOS prompts each time.
8
+ * `reticle doctor` explained that; this removes it when the project has said who signs it.
9
+ *
10
+ * `APPLE_SIGNING_IDENTITY` cannot simply be passed through: Tauri reads it only when it bundles
11
+ * (`tauri build`), never in `tauri dev`. What `tauri dev` does run is `cargo run`, and Cargo hands
12
+ * the freshly built binary to a per-target RUNNER before executing it. The runner written here signs
13
+ * that binary — with the identity, and with the app's bundle identifier so the requirement matches
14
+ * the release app's — and then executes it unchanged. A signing failure is said on stderr and never
15
+ * stops the app.
16
+ *
17
+ * Nothing happens off macOS, outside a Tauri project, with no identity, with the ad-hoc identity
18
+ * `-` (which matches nothing), or when the project already sets a Cargo runner of its own.
19
+ */
20
+ import { join } from 'node:path';
21
+ /** The env the runner reads its arguments from: the script stays a fixed file. */
22
+ export const SigningEnv = {
23
+ IDENTITY: 'RETICLE_SIGNING_IDENTITY',
24
+ IDENTIFIER: 'RETICLE_SIGNING_IDENTIFIER',
25
+ APPLE: 'APPLE_SIGNING_IDENTITY',
26
+ };
27
+ /** Cargo's runner variable for each Mac target `tauri dev` builds. */
28
+ const RUNNER_VARS = [
29
+ 'CARGO_TARGET_AARCH64_APPLE_DARWIN_RUNNER',
30
+ 'CARGO_TARGET_X86_64_APPLE_DARWIN_RUNNER',
31
+ ];
32
+ const DARWIN = 'darwin';
33
+ const AD_HOC = '-';
34
+ const TAURI_CONF = join('src-tauri', 'tauri.conf.json');
35
+ export const RUNNER_FILE = 'tauri-sign-runner.sh';
36
+ /** The runner: sign the binary Cargo built, then run it exactly as Cargo would have. */
37
+ export const RUNNER_SCRIPT = `#!/bin/sh
38
+ # Written by Reticle. Signs the Tauri dev build with this project's signing identity before it
39
+ # starts, so macOS treats it as the app that owns your keychain items and stops asking for the
40
+ # password. Remove RETICLE_SIGNING_IDENTITY from the environment to turn it off.
41
+ codesign --force --sign "$${SigningEnv.IDENTITY}" --identifier "$${SigningEnv.IDENTIFIER}" "$1" >/dev/null 2>&1 ||
42
+ echo "reticle: could not sign $1 with $${SigningEnv.IDENTITY}; macOS may ask for the keychain password" >&2
43
+ exec "$@"
44
+ `;
45
+ const asRecord = (value) => 'object' === typeof value && null !== value ? value : {};
46
+ const asText = (value) => 'string' === typeof value && 0 < value.trim().length ? value.trim() : undefined;
47
+ /** The extra env for starting a Tauri dev build signed, or `{}` when there is nothing to sign with. */
48
+ export function tauriSigningEnv(deps) {
49
+ if (DARWIN !== deps.platform)
50
+ return {};
51
+ const raw = deps.read(TAURI_CONF);
52
+ if (raw === undefined)
53
+ return {};
54
+ let conf;
55
+ try {
56
+ conf = asRecord(JSON.parse(raw));
57
+ }
58
+ catch {
59
+ return {};
60
+ }
61
+ const macOS = asRecord(asRecord(conf['bundle'])['macOS']);
62
+ const identity = asText(deps.env[SigningEnv.APPLE]) ?? asText(macOS['signingIdentity']);
63
+ const identifier = asText(conf['identifier']);
64
+ if (identity === undefined || AD_HOC === identity || identifier === undefined)
65
+ return {};
66
+ // A project that runs its builds through a runner of its own keeps it.
67
+ if (RUNNER_VARS.some((name) => deps.env[name] !== undefined))
68
+ return {};
69
+ const runner = deps.writeRunner(RUNNER_FILE, RUNNER_SCRIPT);
70
+ // Cargo splits a runner given in the environment on whitespace, so a path with a space in it
71
+ // would run the wrong program. ponytail: skip it; doctor still explains the prompt.
72
+ if (/\s/.test(runner))
73
+ return {};
74
+ return {
75
+ [SigningEnv.IDENTITY]: identity,
76
+ [SigningEnv.IDENTIFIER]: identifier,
77
+ ...Object.fromEntries(RUNNER_VARS.map((name) => [name, runner])),
78
+ };
79
+ }
@@ -21,11 +21,20 @@ export declare function parseLsofPorts(out: string): number[];
21
21
  * and taking index 1 reads every IPv6 row as port 0 and silently drops half the table.
22
22
  */
23
23
  export declare function parseNetstatListeners(out: string): Listener[];
24
- /** One (pid, parent) pair, as `wmic process get ParentProcessId,ProcessId` prints them. */
24
+ /**
25
+ * One (pid, parent) pair, as `wmic process get CreationDate,ParentProcessId,ProcessId` prints them.
26
+ *
27
+ * `startedAtMs` is the process's own creation time, when the source gave one. It is what tells a
28
+ * real child from a stale link: Windows never clears ParentProcessId when a parent exits, and it
29
+ * reuses pids, so "ppid matches" alone can adopt an unrelated, older process. See `descendants`.
30
+ */
25
31
  export interface ProcessPair {
26
32
  readonly pid: number;
27
33
  readonly ppid: number;
34
+ readonly startedAtMs?: number;
28
35
  }
36
+ /** Epoch milliseconds of a WMI datetime, or undefined when it is not one. */
37
+ export declare function parseWmiDatetime(text: string): number | undefined;
29
38
  export declare function parseWmicProcesses(out: string): ProcessPair[];
30
39
  /**
31
40
  * `root` and everything descended from it.
@@ -39,16 +39,37 @@ export function parseNetstatListeners(out) {
39
39
  }
40
40
  return rows;
41
41
  }
42
+ /** A WMI datetime: `yyyymmddHHMMSS.ffffff` then the offset from UTC in minutes, `+000` / `-300`. */
43
+ const WMI_DATETIME = /^(\d{4})(\d{2})(\d{2})(\d{2})(\d{2})(\d{2})\.(\d{6})([+-])(\d{3})$/;
44
+ const MICROS_PER_MS = 1000;
45
+ const MS_PER_MINUTE = 60_000;
46
+ /** Epoch milliseconds of a WMI datetime, or undefined when it is not one. */
47
+ export function parseWmiDatetime(text) {
48
+ const m = WMI_DATETIME.exec(text);
49
+ if (null === m)
50
+ return undefined;
51
+ const n = (index) => Number(m[index]);
52
+ const local = Date.UTC(n(1), n(2) - 1, n(3), n(4), n(5), n(6), Math.floor(n(7) / MICROS_PER_MS));
53
+ const minutesEast = '-' === m[8] ? -n(9) : n(9);
54
+ return local - minutesEast * MS_PER_MINUTE;
55
+ }
42
56
  export function parseWmicProcesses(out) {
43
57
  const pairs = [];
44
58
  for (const line of String(out).split(/\r?\n/)) {
45
59
  const f = line.trim().split(/\s+/);
46
- if (f.length !== 2)
60
+ // Two columns (ppid pid), or three with the creation time first: wmic prints its columns in
61
+ // alphabetical order, and the PowerShell fallback prints the same shape on purpose.
62
+ const timed = 3 === f.length;
63
+ if (!timed && 2 !== f.length)
64
+ continue;
65
+ const startedAtMs = timed ? parseWmiDatetime(f[0] ?? '') : undefined;
66
+ if (timed && undefined === startedAtMs)
67
+ continue;
68
+ const ppid = Number(f[timed ? 1 : 0]);
69
+ const pid = Number(f[timed ? 2 : 1]);
70
+ if (!Number.isInteger(pid) || !Number.isInteger(ppid))
47
71
  continue;
48
- const ppid = Number(f[0]);
49
- const pid = Number(f[1]);
50
- if (Number.isInteger(pid) && Number.isInteger(ppid))
51
- pairs.push({ pid, ppid });
72
+ pairs.push(undefined === startedAtMs ? { pid, ppid } : { pid, ppid, startedAtMs });
52
73
  }
53
74
  return pairs;
54
75
  }
@@ -60,8 +81,18 @@ export function parseWmicProcesses(out) {
60
81
  * indistinguishable from "no server".
61
82
  */
62
83
  export function descendants(pairs, root) {
84
+ const startedAt = new Map();
85
+ for (const { pid, startedAtMs } of pairs) {
86
+ if (undefined !== startedAtMs)
87
+ startedAt.set(pid, startedAtMs);
88
+ }
63
89
  const byParent = new Map();
64
- for (const { pid, ppid } of pairs) {
90
+ for (const { pid, ppid, startedAtMs } of pairs) {
91
+ // A child created before the parent it names is a stale link left by pid reuse, not a child.
92
+ const parentStarted = startedAt.get(ppid);
93
+ if (undefined !== startedAtMs && undefined !== parentStarted && startedAtMs < parentStarted) {
94
+ continue;
95
+ }
65
96
  const kids = byParent.get(ppid);
66
97
  if (kids === undefined)
67
98
  byParent.set(ppid, [pid]);
@@ -1,3 +1,12 @@
1
+ /**
2
+ * Is `candidate` a strictly NEWER release than `current`?
3
+ *
4
+ * Replaces a plain `!==`, which told anyone on a version newer than the published one — a
5
+ * prerelease, a local build, a rollback in progress — to "update" to something older. A nudge that
6
+ * prompts a downgrade is one people learn to ignore. Numeric per segment, so a 10 patch correctly
7
+ * beats a 9 (string order does not), and a bare release beats its own prerelease.
8
+ */
9
+ export declare function isNewerVersion(candidate: string, current: string): boolean;
1
10
  interface UpdateNudge {
2
11
  /** The version available, so the agent can tell the human what they would be moving to. */
3
12
  latestVersion: string;
@@ -28,7 +28,7 @@ import { creditNudge } from './nudge-credit.js';
28
28
  * prompts a downgrade is one people learn to ignore. Numeric per segment, so a 10 patch correctly
29
29
  * beats a 9 (string order does not), and a bare release beats its own prerelease.
30
30
  */
31
- function isNewerVersion(candidate, current) {
31
+ export function isNewerVersion(candidate, current) {
32
32
  const parse = (v) => {
33
33
  const [core = '', ...rest] = v.split(/[-+]/);
34
34
  return { parts: core.split('.').map((n) => Number.parseInt(n, 10) || 0), pre: rest.length > 0 };
@@ -168,15 +168,6 @@ async function installVersion(version, kind) {
168
168
  }
169
169
  await runNpm(plan.args, plan.cwd !== undefined ? { cwd: plan.cwd } : {});
170
170
  }
171
- async function installVersionRollback(version, kind) {
172
- if (kind === ExecutionKind.NPX) {
173
- log('reticle_rollback_npx_strategy', {
174
- note: 'Running via npx — update your .mcp.json args to pin the version you want to restore',
175
- });
176
- return;
177
- }
178
- await installVersion(version, kind);
179
- }
180
171
  /**
181
172
  * Install targetVersion using the appropriate strategy for the detected execution kind,
182
173
  * then exit so Claude Code restarts with the new binary. Saves the current version
@@ -209,15 +200,20 @@ export async function rollback() {
209
200
  }
210
201
  const prev = manifest.previousVersion;
211
202
  const kind = detectExecutionKind();
203
+ // Under npx there is nothing to reinstall: the next start re-resolves the package. Say how to pin
204
+ // the old version and stop, rather than logging and reporting a rollback that never landed.
205
+ if (kind === ExecutionKind.NPX) {
206
+ log('reticle_rollback_npx_strategy', {
207
+ version: prev,
208
+ note: 'Running via npx — update your .mcp.json args to pin the version you want to restore',
209
+ });
210
+ return;
211
+ }
212
212
  log('reticle_rollback_applying', { version: prev, executionKind: kind });
213
- await installVersionRollback(prev, kind);
213
+ await installVersion(prev, kind);
214
214
  log('reticle_rollback_applied', { version: prev, executionKind: kind });
215
215
  // A rollback is a release-quality alarm — someone shipped something that broke a real user badly
216
216
  // enough for them to go backwards. Worth knowing about within the hour, not at the next retro.
217
217
  await reportVersionChange(SERVER_VERSION, prev, VersionChangeDirection.ROLLBACK);
218
- // For npx, exiting would let the next restart re-resolve @latest — rolling FORWARD, the opposite
219
- // of rollback. installVersionRollback already told the user to pin the version in.mcp.json, so
220
- // stay running rather than trigger that. Other kinds installed the old version and must restart.
221
- if (kind !== ExecutionKind.NPX)
222
- process.exit(0);
218
+ process.exit(0);
223
219
  }
@@ -68,6 +68,9 @@ export function takeVersionSkewOnto(payload, connection) {
68
68
  const skew = takeVersionSkew(connection);
69
69
  if (skew === undefined)
70
70
  return payload;
71
+ // Compatible, so it did not cause this error: ride along, and leave the advice and the ask alone.
72
+ if (SkewPair.SDK_BEHIND === skew.pair)
73
+ return { ...payload, [EnvelopeKey.VERSION_SKEW]: skew };
71
74
  const { feedback, ...rest } = payload;
72
75
  return {
73
76
  ...rest,
@@ -28,6 +28,12 @@ export declare const SkewPair: {
28
28
  readonly SDK: "sdk";
29
29
  /** Another Reticle process — a CLI, or the MCP server an agent spawned — vs this daemon. */
30
30
  readonly DAEMON: "daemon";
31
+ /**
32
+ * The SDK in the page is a minor or more behind, on the same contract: compatible, so it is news
33
+ * and not a cause. Its own pair so it never displaces an untold real skew, and never stands in for
34
+ * the advice on an error it did not cause (see takeVersionSkewOnto).
35
+ */
36
+ readonly SDK_BEHIND: "sdk_behind";
31
37
  };
32
38
  export type SkewPair = (typeof SkewPair)[keyof typeof SkewPair];
33
39
  /** What a piece says about itself when it connects. */
@@ -78,7 +84,7 @@ interface SelfIdentity {
78
84
  * a build provably older than this daemon. With neither signal there is nothing to go on, and
79
85
  * inventing a warning would be as dishonest as staying silent about a real one.
80
86
  */
81
- export declare function describeSkew(peer: PeerIdentity, self: SelfIdentity): string | undefined;
87
+ export declare function describeSkew(given: PeerIdentity, self: SelfIdentity): string | undefined;
82
88
  /**
83
89
  * The fix line for a page whose SDK disagrees with this daemon, with no project to read.
84
90
  *
@@ -88,6 +94,19 @@ export declare function describeSkew(peer: PeerIdentity, self: SelfIdentity): st
88
94
  * `@reticlehq/react` and told Vue projects to install a React package (#618).
89
95
  */
90
96
  export declare function sdkFix(daemonVersion: string): string;
97
+ /** The same fact for the person looking at the page, on its overlay. */
98
+ export declare const SDK_BEHIND_NARRATION: (sdk: string, daemon: string) => string;
99
+ /**
100
+ * A page whose SDK is a minor release or more behind this daemon.
101
+ *
102
+ * `describeSkew` is silent here on purpose: the contract matches, so the page connects and every
103
+ * verdict is sound. But whatever shipped since is not in the page, the overlay included, and from
104
+ * the field that looked exactly like a broken release: the CLI reported the new version while the
105
+ * page showed an overlay without the newer controls, and nothing anywhere said which SDK it was
106
+ * running. Patch releases stay silent for the cry-wolf reason in the header. `fix` is a thunk
107
+ * because reading the project's manifest is only worth it when the page IS behind.
108
+ */
109
+ export declare function describeSdkBehind(sdk: string | undefined, daemon: string, fix: () => string): string | undefined;
91
110
  /**
92
111
  * The fix line for another Reticle process that disagrees with the daemon it attached to.
93
112
  *
@@ -22,6 +22,7 @@
22
22
  * the wire changes and stays put when internals do. Versions still ride along, because they are what
23
23
  * a human acts on.
24
24
  */
25
+ import { RETIRED_WIRE_NAMES } from '@reticlehq/core';
25
26
  import { resolveSdkFix } from './sdk-fix.js';
26
27
  /** Which pair disagreed. Named so the nudge can report each independently. */
27
28
  export const SkewPair = {
@@ -29,6 +30,12 @@ export const SkewPair = {
29
30
  SDK: 'sdk',
30
31
  /** Another Reticle process — a CLI, or the MCP server an agent spawned — vs this daemon. */
31
32
  DAEMON: 'daemon',
33
+ /**
34
+ * The SDK in the page is a minor or more behind, on the same contract: compatible, so it is news
35
+ * and not a cause. Its own pair so it never displaces an untold real skew, and never stands in for
36
+ * the advice on an error it did not cause (see takeVersionSkewOnto).
37
+ */
38
+ SDK_BEHIND: 'sdk_behind',
32
39
  };
33
40
  /**
34
41
  * Names the peer speaks that we have never heard of.
@@ -38,15 +45,20 @@ export const SkewPair = {
38
45
  * is not a browser to do -- there is no touch equivalent of a console error. A peer speaking a name
39
46
  * we do not know was built against a contract this daemon does not have, and that is a genuine
40
47
  * mismatch: one of us is stale, and tools will behave in ways neither side reports.
48
+ *
49
+ * A name we RETIRED is not unknown: an older peer still lists it, and we never send it (#1343).
41
50
  */
42
51
  function namesWeDoNotKnow(peer, self) {
43
52
  const unknown = [
44
53
  ...peer.commands.filter((name) => !self.commands.includes(name)),
45
54
  ...peer.events.filter((name) => !self.events.includes(name)),
46
55
  ...peer.actions.filter((name) => !self.actions.includes(name)),
47
- ];
56
+ ].filter((name) => !RETIRED_WIRE_NAMES.includes(name));
48
57
  return [...new Set(unknown)].sort();
49
58
  }
59
+ /** The fix for two builds of one version. */
60
+ const SAME_VERSION_FIX = 'Both say the same version, so one of them is an older build of it: run `reticle restart`, then ' +
61
+ 'reload the page so it loads the SDK the dev server serves now.';
50
62
  function versionPhrase(peer, self) {
51
63
  return peer.version === undefined
52
64
  ? `${peer.what} is on an unknown version; this daemon is ${self.version}`
@@ -69,16 +81,25 @@ function versionPhrase(peer, self) {
69
81
  * a build provably older than this daemon. With neither signal there is nothing to go on, and
70
82
  * inventing a warning would be as dishonest as staying silent about a real one.
71
83
  */
72
- export function describeSkew(peer, self) {
73
- if (peer.contract !== undefined && peer.contract === self.contract)
84
+ export function describeSkew(given, self) {
85
+ if (given.contract !== undefined && given.contract === self.contract)
74
86
  return undefined;
87
+ // One version, two builds (a daemon running code older than its install, a cached page bundle):
88
+ // installing that version again changes nothing, so the fix is the restart and the reload.
89
+ const peer = given.version === self.version ? { ...given, fix: SAME_VERSION_FIX } : given;
75
90
  // Both sides said which names they speak, so compare the names rather than a hash over them.
76
91
  if (peer.contractParts !== undefined && self.contractParts !== undefined) {
77
92
  const unknown = namesWeDoNotKnow(peer.contractParts, self.contractParts);
78
93
  if (0 === unknown.length)
79
94
  return undefined;
95
+ // Direction comes from the versions when both are known. An older peer naming something we do
96
+ // not know has a name we removed without retiring it, not a newer contract.
97
+ const order = compareVersions(peer.version, self.version);
98
+ const why = order !== undefined && order < 0
99
+ ? 'though it is the older of the two — so this daemon dropped a name it still uses'
100
+ : 'so it was built against a newer contract than this one';
80
101
  return (`version skew: ${versionPhrase(peer, self)}, and ${peer.what} speaks names this daemon does ` +
81
- `not know (${unknown.join(', ')}) — so it was built against a newer contract than this one. ` +
102
+ `not know (${unknown.join(', ')}) — ${why}. ` +
82
103
  `Tools will behave in ways neither side reports. ${peer.fix}`);
83
104
  }
84
105
  if (peer.contract === undefined) {
@@ -143,6 +164,30 @@ function compareVersions(a, b) {
143
164
  }
144
165
  return 0;
145
166
  }
167
+ /** The same fact for the person looking at the page, on its overlay. */
168
+ export const SDK_BEHIND_NARRATION = (sdk, daemon) => `This app runs Reticle SDK ${sdk}, older than Reticle ${daemon}. Run \`reticle update\` in the ` +
169
+ "app's folder, then restart its dev server.";
170
+ /**
171
+ * A page whose SDK is a minor release or more behind this daemon.
172
+ *
173
+ * `describeSkew` is silent here on purpose: the contract matches, so the page connects and every
174
+ * verdict is sound. But whatever shipped since is not in the page, the overlay included, and from
175
+ * the field that looked exactly like a broken release: the CLI reported the new version while the
176
+ * page showed an overlay without the newer controls, and nothing anywhere said which SDK it was
177
+ * running. Patch releases stay silent for the cry-wolf reason in the header. `fix` is a thunk
178
+ * because reading the project's manifest is only worth it when the page IS behind.
179
+ */
180
+ export function describeSdkBehind(sdk, daemon, fix) {
181
+ const minorOf = (v) => v.split('-')[0]?.split('.').slice(0, 2).join('.') ?? v;
182
+ if (sdk === undefined)
183
+ return undefined;
184
+ const order = compareVersions(minorOf(sdk), minorOf(daemon));
185
+ if (order === undefined || order >= 0)
186
+ return undefined;
187
+ return (`This page runs Reticle SDK ${sdk}, older than Reticle ${daemon}. It connects and verifies, ` +
188
+ `but everything added since is missing from the page, the overlay's newer controls included. ` +
189
+ fix());
190
+ }
146
191
  /**
147
192
  * The fix line for another Reticle process that disagrees with the daemon it attached to.
148
193
  *
@@ -87,6 +87,10 @@ export const CRAWL_TOOLS = [
87
87
  .optional()
88
88
  .describe('Present only when the page exceeded one snapshot, so controls past the cap were never listed. When present, a zero-anomaly result does NOT mean the app is clean.'),
89
89
  truncated: z.boolean(),
90
+ notJudged: z
91
+ .array(z.object({ ref: z.string(), desc: z.string(), reason: z.string() }))
92
+ .optional()
93
+ .describe('Controls clicked whose silence could not be judged, e.g. on a background tab. They are NOT reported as dead, and they are not known to work either.'),
90
94
  // Only on `exhaustive` — see features/exhaust/exhaust-run.ts. Loose: it carries the levels.
91
95
  exhaustive: z.record(z.unknown()).optional(),
92
96
  },
@@ -81,6 +81,12 @@ export interface CrawlReport {
81
81
  truncated: boolean;
82
82
  /** Present only when the snapshot itself was capped, i.e. controls exist that were never listed. */
83
83
  coverageNote?: string;
84
+ /** Controls whose silence could not be judged, present only when non-empty. */
85
+ notJudged?: {
86
+ ref: string;
87
+ desc: string;
88
+ reason: string;
89
+ }[];
84
90
  }
85
91
  export interface CrawlOptions {
86
92
  maxSteps?: number;
@@ -33,6 +33,15 @@ function revealedControlsNote(count) {
33
33
  'started were never visited — interactiveFound is a floor, not a total; re-run the crawl from ' +
34
34
  'the state you are now in to cover them');
35
35
  }
36
+ /**
37
+ * Controls that end the signed-in session. Not destructive (signing out is reversible, so the
38
+ * action gate lets it through), but a crawl that presses one drives everything after it signed out:
39
+ * every Harness plan run clicked the sidebar's "Sign out", then stale refs on the sign-in page.
40
+ */
41
+ const ENDS_SESSION = /\b(?:sign ?out|log ?out|sign ?off|log ?off)\b/i;
42
+ const ENDS_SESSION_NOT_PRESSED = 'not pressed: it ends the signed-in session the crawl is driving';
43
+ /** Why a silent control on a throttled page is not reported as dead. */
44
+ const BACKGROUND_TAB_NOT_JUDGED = 'not judged: the page is throttled (its tab is in the background, or it has not been heard from recently), so a reaction may not show inside the sample window; bring the tab to the front and crawl again';
36
45
  /** Any buffer event that proves the app reacted to a click (vs a dead/no-op control). */
37
46
  function isActivity(e) {
38
47
  return (e.type === EventType.NET_REQUEST ||
@@ -255,6 +264,7 @@ export async function crawl(session, opts, sleep) {
255
264
  // `truncated:false` would positively assert that nothing was cut.
256
265
  const coverageCapped = true === snapshot.truncated;
257
266
  const anomalies = [];
267
+ const notJudged = [];
258
268
  const visited = [];
259
269
  const counts = { consoleErrors: 0, failedRequests: 0, deadControls: 0, contradictions: 0 };
260
270
  const seen = new Set();
@@ -275,6 +285,10 @@ export async function crawl(session, opts, sleep) {
275
285
  if (seen.has(dedupeKey))
276
286
  continue; // don't re-click the same control
277
287
  seen.add(dedupeKey);
288
+ if (ENDS_SESSION.test(item.desc)) {
289
+ notJudged.push({ ref: item.ref, desc: item.desc, reason: ENDS_SESSION_NOT_PRESSED });
290
+ continue;
291
+ }
278
292
  stepsRun += 1;
279
293
  visited.push(item.desc);
280
294
  const since = session.elapsed();
@@ -401,7 +415,11 @@ export async function crawl(session, opts, sleep) {
401
415
  //
402
416
  // A second click costs one round trip on the rare control that looked dead, and nothing at all
403
417
  // on every control that did not. A genuinely dead control is silent twice; the flake is not.
404
- if (await stillSilent(session, item, settleMs, confirm, sleep)) {
418
+ // A throttled page may defer DOM observer flushes, so silence cannot prove a dead control.
419
+ if (true === session.throttled?.()) {
420
+ notJudged.push({ ref: item.ref, desc: item.desc, reason: BACKGROUND_TAB_NOT_JUDGED });
421
+ }
422
+ else if (await stillSilent(session, item, settleMs, confirm, sleep)) {
405
423
  counts.deadControls += 1;
406
424
  anomalies.push({
407
425
  kind: CrawlAnomalyKind.DEAD_CONTROL,
@@ -429,16 +447,19 @@ export async function crawl(session, opts, sleep) {
429
447
  // unvisited. Skipped when the snapshot was already capped: that case has its own note and a second
430
448
  // one would only muddy it.
431
449
  const revealed = coverageCapped ? 0 : (await revealedItems(session, opts, found)).length;
450
+ // Left alone on purpose, so not a step the budget ran out before.
451
+ const leftAlone = notJudged.filter((n) => ENDS_SESSION_NOT_PRESSED === n.reason).length;
432
452
  return {
433
453
  interactiveFound: found.length,
434
454
  stepsRun,
435
455
  anomalies,
436
456
  counts,
437
457
  visited,
458
+ ...(0 === notJudged.length ? {} : { notJudged }),
438
459
  // True when coverage was bounded for EITHER reason: the step budget ran out, or the page was
439
460
  // bigger than one snapshot. Conflating "I stopped early" with "I saw everything" is what turns a
440
461
  // partial sweep into "all controls healthy".
441
- truncated: found.length > stepsRun || coverageCapped || revealed > 0,
462
+ truncated: found.length - leftAlone > stepsRun || coverageCapped || revealed > 0,
442
463
  ...(coverageCapped
443
464
  ? { coverageNote: CAPPED_SNAPSHOT_NOTE }
444
465
  : revealed > 0
@@ -47,12 +47,12 @@ declare const LedgerSchema: z.ZodObject<{
47
47
  proved: z.ZodArray<z.ZodString, "many">;
48
48
  }, "strip", z.ZodTypeAny, {
49
49
  proved: string[];
50
- touched: string[];
51
50
  seen: string[];
51
+ touched: string[];
52
52
  }, {
53
53
  proved: string[];
54
- touched: string[];
55
54
  seen: string[];
55
+ touched: string[];
56
56
  }>;
57
57
  journeys: z.ZodObject<{
58
58
  completed: z.ZodArray<z.ZodString, "many">;
@@ -66,12 +66,12 @@ declare const LedgerSchema: z.ZodObject<{
66
66
  branched: z.ZodArray<z.ZodString, "many">;
67
67
  unhandled: z.ZodArray<z.ZodString, "many">;
68
68
  }, "strip", z.ZodTypeAny, {
69
- branched: string[];
70
69
  seen: string[];
70
+ branched: string[];
71
71
  unhandled: string[];
72
72
  }, {
73
- branched: string[];
74
73
  seen: string[];
74
+ branched: string[];
75
75
  unhandled: string[];
76
76
  }>;
77
77
  code: z.ZodRecord<z.ZodString, z.ZodRecord<z.ZodString, z.ZodObject<{
@@ -92,6 +92,9 @@ declare const LedgerSchema: z.ZodObject<{
92
92
  name: string;
93
93
  executed: boolean;
94
94
  }>>;
95
+ journeys: {
96
+ completed: string[];
97
+ };
95
98
  best: Record<string, number>;
96
99
  routes: {
97
100
  reached: string[];
@@ -99,15 +102,12 @@ declare const LedgerSchema: z.ZodObject<{
99
102
  };
100
103
  controls: {
101
104
  proved: string[];
102
- touched: string[];
103
105
  seen: string[];
104
- };
105
- journeys: {
106
- completed: string[];
106
+ touched: string[];
107
107
  };
108
108
  writes: {
109
- branched: string[];
110
109
  seen: string[];
110
+ branched: string[];
111
111
  unhandled: string[];
112
112
  };
113
113
  codeTaken: Record<string, number>;
@@ -116,6 +116,9 @@ declare const LedgerSchema: z.ZodObject<{
116
116
  name: string;
117
117
  executed: boolean;
118
118
  }>>;
119
+ journeys: {
120
+ completed: string[];
121
+ };
119
122
  best: Record<string, number>;
120
123
  routes: {
121
124
  reached: string[];
@@ -123,15 +126,12 @@ declare const LedgerSchema: z.ZodObject<{
123
126
  };
124
127
  controls: {
125
128
  proved: string[];
126
- touched: string[];
127
129
  seen: string[];
128
- };
129
- journeys: {
130
- completed: string[];
130
+ touched: string[];
131
131
  };
132
132
  writes: {
133
- branched: string[];
134
133
  seen: string[];
134
+ branched: string[];
135
135
  unhandled: string[];
136
136
  };
137
137
  codeTaken?: Record<string, number> | undefined;
@@ -158,6 +158,13 @@ export interface LevelReport {
158
158
  /** How many more are missing than `missing` names. */
159
159
  missingOverflow?: number;
160
160
  }
161
+ /**
162
+ * Each level's percentage for the project at `reticleRoot`, for the HUD: numbers only, and only the
163
+ * levels with an honest denominator. Undefined when nothing has been measured yet.
164
+ *
165
+ * Synchronous because the impact snapshot it feeds is: one small file read per snapshot.
166
+ */
167
+ export declare function coveragePercents(reticleRoot: string): Record<string, number> | undefined;
161
168
  export declare function emptyLedger(): AppLedger;
162
169
  export declare function mergeLedger(into: AppLedger, delta: LedgerDelta): AppLedger;
163
170
  export declare function levelsOf(ledger: AppLedger): LevelReport[];
@@ -18,6 +18,7 @@
18
18
  * Union-only. A later drive can add coverage and never remove it, so the number only moves down when
19
19
  * the app grows something nobody has covered yet — which is precisely what the ratchet is for.
20
20
  */
21
+ import { readFileSync } from 'node:fs';
21
22
  import { dirname } from 'node:path';
22
23
  import { z } from 'zod';
23
24
  import { writeFileAtomic } from '../../memory/project/fs/write-atomic.js';
@@ -45,6 +46,39 @@ const LedgerSchema = z.object({
45
46
  codeTaken: z.record(z.number()).default({}),
46
47
  best: z.record(z.number()),
47
48
  });
49
+ /** A ledger file's text, or an empty ledger for anything unreadable: coverage never throws. */
50
+ function parseLedger(text) {
51
+ try {
52
+ const parsed = z
53
+ .object({ version: z.literal(LEDGER_VERSION), ledger: LedgerSchema })
54
+ .safeParse(JSON.parse(text));
55
+ return parsed.success ? parsed.data.ledger : emptyLedger();
56
+ }
57
+ catch {
58
+ return emptyLedger();
59
+ }
60
+ }
61
+ /**
62
+ * Each level's percentage for the project at `reticleRoot`, for the HUD: numbers only, and only the
63
+ * levels with an honest denominator. Undefined when nothing has been measured yet.
64
+ *
65
+ * Synchronous because the impact snapshot it feeds is: one small file read per snapshot.
66
+ */
67
+ export function coveragePercents(reticleRoot) {
68
+ let text;
69
+ try {
70
+ text = readFileSync(reticleDirPaths(reticleRoot).coverage, 'utf8');
71
+ }
72
+ catch {
73
+ return undefined;
74
+ }
75
+ const out = {};
76
+ for (const report of levelsOf(parseLedger(text))) {
77
+ if (report.pct !== undefined)
78
+ out[report.level] = report.pct;
79
+ }
80
+ return 0 < Object.keys(out).length ? out : undefined;
81
+ }
48
82
  export function emptyLedger() {
49
83
  return {
50
84
  routes: { discovered: [], reached: [] },
@@ -213,15 +247,7 @@ export class LedgerStore {
213
247
  return emptyLedger();
214
248
  throw error;
215
249
  }
216
- try {
217
- const parsed = z
218
- .object({ version: z.literal(LEDGER_VERSION), ledger: LedgerSchema })
219
- .safeParse(JSON.parse(text));
220
- return parsed.success ? parsed.data.ledger : emptyLedger();
221
- }
222
- catch {
223
- return emptyLedger();
224
- }
250
+ return parseLedger(text);
225
251
  }
226
252
  /**
227
253
  * Fold a delta in, raise the best, persist, and hand back the result. Under the file's lock: two
@@ -0,0 +1,2 @@
1
+ import type { ToolOutcome } from './harness.js';
2
+ export declare function appFindings(toolCalls: readonly ToolOutcome[]): string[];