@reticlehq/server 3.6.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 (614) hide show
  1. package/SKILL.md +122 -123
  2. package/dist/command/cli/adhoc-suite.d.ts +14 -0
  3. package/dist/command/cli/adhoc-suite.js +42 -7
  4. package/dist/command/cli/adhoc-verdict.d.ts +18 -2
  5. package/dist/command/cli/adhoc-verdict.js +70 -6
  6. package/dist/command/cli/answers/gate-exit.d.ts +23 -0
  7. package/dist/command/cli/answers/gate-exit.js +45 -0
  8. package/dist/command/cli/answers/gate-hook-message.d.ts +2 -0
  9. package/dist/command/cli/answers/gate-hook-message.js +3 -1
  10. package/dist/command/cli/auth/device-flow.d.ts +13 -2
  11. package/dist/command/cli/auth/device-flow.js +17 -0
  12. package/dist/command/cli/cli-doctor.js +14 -0
  13. package/dist/command/cli/cli-flow-commands.d.ts +0 -11
  14. package/dist/command/cli/cli-flow-commands.js +28 -105
  15. package/dist/command/cli/cli-kill.js +3 -2
  16. package/dist/command/cli/cli-parse-grammar.d.ts +24 -0
  17. package/dist/command/cli/cli-parse-grammar.js +75 -0
  18. package/dist/command/cli/cli-parse-verify.d.ts +2 -0
  19. package/dist/command/cli/cli-parse-verify.js +18 -0
  20. package/dist/command/cli/cli-parse.d.ts +19 -28
  21. package/dist/command/cli/cli-parse.js +82 -182
  22. package/dist/command/cli/cli-update-commands.d.ts +1 -1
  23. package/dist/command/cli/cli-update-commands.js +61 -9
  24. package/dist/command/cli/cli-usage.d.ts +33 -0
  25. package/dist/command/cli/cli-usage.js +287 -0
  26. package/dist/command/cli/cli-verify.d.ts +34 -4
  27. package/dist/command/cli/cli-verify.js +81 -12
  28. package/dist/command/cli/cloud-cli.d.ts +13 -0
  29. package/dist/command/cli/cloud-cli.js +145 -333
  30. package/dist/command/cli/cloud-kit.d.ts +12 -0
  31. package/dist/command/cli/cloud-kit.js +41 -2
  32. package/dist/command/cli/cloud-link.d.ts +57 -0
  33. package/dist/command/cli/cloud-link.js +308 -0
  34. package/dist/command/cli/cloud-login.d.ts +15 -1
  35. package/dist/command/cli/cloud-login.js +67 -13
  36. package/dist/command/cli/context-command.d.ts +1 -0
  37. package/dist/command/cli/context-command.js +33 -0
  38. package/dist/command/cli/daemon-start-options.d.ts +3 -0
  39. package/dist/command/cli/daemon-start-options.js +24 -3
  40. package/dist/command/cli/doctor/doctor-coverage-line.d.ts +2 -0
  41. package/dist/command/cli/doctor/doctor-coverage-line.js +47 -0
  42. package/dist/command/cli/doctor/doctor-project-line.d.ts +0 -12
  43. package/dist/command/cli/doctor/doctor-project-line.js +5 -4
  44. package/dist/command/cli/doctor/doctor-rows.d.ts +6 -0
  45. package/dist/command/cli/doctor/doctor-rows.js +6 -0
  46. package/dist/command/cli/doctor/doctor-signing-line.d.ts +38 -0
  47. package/dist/command/cli/doctor/doctor-signing-line.js +114 -0
  48. package/dist/command/cli/known-regression.d.ts +13 -0
  49. package/dist/command/cli/known-regression.js +34 -0
  50. package/dist/command/cli/launch/sdk-version-match.d.ts +12 -0
  51. package/dist/command/cli/launch/sdk-version-match.js +25 -0
  52. package/dist/command/cli/lifecycle/daemon-lifecycle.js +11 -2
  53. package/dist/command/cli/mcp-command.d.ts +6 -0
  54. package/dist/command/cli/mcp-command.js +13 -5
  55. package/dist/command/cli/ports/port-holder.js +1 -1
  56. package/dist/command/cli/project-name.d.ts +29 -1
  57. package/dist/command/cli/project-name.js +107 -2
  58. package/dist/command/cli/setup-mcp-cli.d.ts +17 -1
  59. package/dist/command/cli/setup-mcp-cli.js +29 -8
  60. package/dist/command/cli/status/status-lines.d.ts +1 -0
  61. package/dist/command/cli/status/status-lines.js +47 -2
  62. package/dist/command/cli/status/workspace-links.d.ts +10 -0
  63. package/dist/command/cli/status/workspace-links.js +29 -0
  64. package/dist/command/cli/try-command.d.ts +96 -0
  65. package/dist/command/cli/try-command.js +362 -0
  66. package/dist/command/cli/tutorial.d.ts +0 -100
  67. package/dist/command/cli/tutorial.js +0 -178
  68. package/dist/command/cli/verify-results.d.ts +19 -0
  69. package/dist/command/cli/verify-results.js +29 -0
  70. package/dist/command/cli-onboarding.d.ts +0 -11
  71. package/dist/command/cli-onboarding.js +0 -15
  72. package/dist/command/cli.d.ts +14 -0
  73. package/dist/command/cli.js +103 -83
  74. package/dist/command/daemon/daemon-resilience.js +4 -4
  75. package/dist/command/daemon/daemon-resolve.d.ts +9 -1
  76. package/dist/command/daemon/daemon-resolve.js +49 -10
  77. package/dist/command/setup/bringup/bridge-port.d.ts +3 -1
  78. package/dist/command/setup/bringup/bridge-port.js +13 -3
  79. package/dist/command/setup/bringup/dev-server-log-cap.js +2 -0
  80. package/dist/command/setup/bringup/ensure-daemon.js +9 -2
  81. package/dist/command/setup/init/agent-restart.d.ts +23 -0
  82. package/dist/command/setup/init/agent-restart.js +28 -0
  83. package/dist/command/setup/init/init-port.d.ts +10 -1
  84. package/dist/command/setup/init/init-port.js +22 -2
  85. package/dist/command/setup/init/init-runtime.d.ts +12 -2
  86. package/dist/command/setup/init/init-runtime.js +96 -37
  87. package/dist/command/setup/node-effects.d.ts +2 -0
  88. package/dist/command/setup/node-effects.js +36 -8
  89. package/dist/command/setup/probe/existing-app.d.ts +12 -0
  90. package/dist/command/setup/probe/existing-app.js +14 -0
  91. package/dist/command/setup/remaining-steps.js +1 -1
  92. package/dist/command/setup/run-setup.d.ts +29 -9
  93. package/dist/command/setup/run-setup.js +34 -28
  94. package/dist/command/setup/setup-command.d.ts +23 -0
  95. package/dist/command/setup/setup-command.js +57 -4
  96. package/dist/command/setup/setup-mcp.js +25 -2
  97. package/dist/command/setup/tauri-signing.d.ts +19 -0
  98. package/dist/command/setup/tauri-signing.js +79 -0
  99. package/dist/command/setup/terminal/listeners.d.ts +10 -1
  100. package/dist/command/setup/terminal/listeners.js +37 -6
  101. package/dist/command/update/update-nudge.d.ts +9 -0
  102. package/dist/command/update/update-nudge.js +1 -1
  103. package/dist/command/update/updater.js +11 -15
  104. package/dist/command/version/version-nudge.js +3 -0
  105. package/dist/command/version/version-skew.d.ts +20 -1
  106. package/dist/command/version/version-skew.js +38 -2
  107. package/dist/features/crawl/crawl.js +14 -1
  108. package/dist/features/exhaust/ledger.d.ts +14 -14
  109. package/dist/features/harness/drive-report.d.ts +39 -5
  110. package/dist/features/harness/drive-report.js +271 -54
  111. package/dist/features/harness/drive-runs.d.ts +120 -0
  112. package/dist/features/harness/drive-runs.js +289 -0
  113. package/dist/features/harness/drivers.d.ts +1 -1
  114. package/dist/features/harness/drivers.js +1 -1
  115. package/dist/features/harness/explore/console-pages.d.ts +15 -0
  116. package/dist/features/harness/explore/console-pages.js +146 -0
  117. package/dist/features/harness/explore/disparity.d.ts +19 -0
  118. package/dist/features/harness/explore/disparity.js +71 -0
  119. package/dist/features/harness/explore/fake-app.d.ts +16 -0
  120. package/dist/features/harness/explore/fake-app.js +49 -0
  121. package/dist/features/harness/explore/goal-search.d.ts +26 -0
  122. package/dist/features/harness/explore/goal-search.js +144 -0
  123. package/dist/features/harness/explore/page-tree.d.ts +49 -0
  124. package/dist/features/harness/explore/page-tree.js +148 -0
  125. package/dist/features/harness/explore/site-map.d.ts +34 -0
  126. package/dist/features/harness/explore/site-map.js +150 -0
  127. package/dist/features/harness/goals.d.ts +68 -7
  128. package/dist/features/harness/goals.js +289 -36
  129. package/dist/features/harness/harness.d.ts +30 -1
  130. package/dist/features/harness/harness.js +141 -7
  131. package/dist/features/harness/platform/local-apps.d.ts +36 -3
  132. package/dist/features/harness/platform/local-apps.js +81 -5
  133. package/dist/features/harness/platform/persona-credentials.d.ts +20 -0
  134. package/dist/features/harness/platform/persona-credentials.js +69 -0
  135. package/dist/features/harness/platform/platform-drives.d.ts +61 -0
  136. package/dist/features/harness/platform/platform-drives.js +114 -0
  137. package/dist/features/harness/platform/refusal.d.ts +52 -0
  138. package/dist/features/harness/platform/refusal.js +71 -0
  139. package/dist/features/harness/platform/remote-drive.d.ts +8 -2
  140. package/dist/features/harness/platform/remote-drive.js +22 -9
  141. package/dist/features/harness/platform/script.d.ts +57 -11
  142. package/dist/features/harness/platform/script.js +144 -12
  143. package/dist/features/harness/platform/server-driver.d.ts +17 -4
  144. package/dist/features/harness/platform/server-driver.js +29 -26
  145. package/dist/features/harness/platform-config.d.ts +38 -5
  146. package/dist/features/harness/platform-config.js +93 -8
  147. package/dist/features/harness/route-guess.d.ts +13 -0
  148. package/dist/features/harness/route-guess.js +49 -0
  149. package/dist/features/harness/script/script-run.d.ts +30 -1
  150. package/dist/features/harness/script/script-run.js +355 -48
  151. package/dist/features/license/license.d.ts +2 -2
  152. package/dist/features/visual/step-shots.d.ts +31 -0
  153. package/dist/features/visual/step-shots.js +231 -0
  154. package/dist/features/visual/visual-tools.js +22 -14
  155. package/dist/hooks/client-directory.d.ts +18 -0
  156. package/dist/hooks/client-directory.js +57 -0
  157. package/dist/hooks/coding-agents.d.ts +34 -0
  158. package/dist/hooks/coding-agents.js +117 -0
  159. package/dist/hooks/driven-by.d.ts +21 -2
  160. package/dist/hooks/driven-by.js +42 -2
  161. package/dist/hooks/hook-bus.d.ts +4 -0
  162. package/dist/hooks/hook-bus.js +18 -0
  163. package/dist/index.d.ts +1 -0
  164. package/dist/index.js +26 -183
  165. package/dist/judgement/capsule/capsule-store.d.ts +2 -2
  166. package/dist/judgement/capsule/causal-summary.d.ts +15 -1
  167. package/dist/judgement/capsule/causal-summary.js +33 -0
  168. package/dist/judgement/runs/artifact/build-verification-run.d.ts +1 -1
  169. package/dist/judgement/runs/artifact/build-verification-run.js +20 -4
  170. package/dist/judgement/runs/artifact/gap-summary.d.ts +0 -18
  171. package/dist/judgement/runs/artifact/gap-summary.js +12 -3
  172. package/dist/judgement/runs/artifact/replay-mapping.js +25 -9
  173. package/dist/judgement/runs/artifact/run-store.d.ts +13 -1
  174. package/dist/judgement/runs/artifact/run-store.js +175 -8
  175. package/dist/judgement/runs/context-tools.js +59 -1
  176. package/dist/judgement/runs/default-run-id.d.ts +3 -0
  177. package/dist/judgement/runs/default-run-id.js +16 -0
  178. package/dist/judgement/runs/drive-run.d.ts +53 -5
  179. package/dist/judgement/runs/drive-run.js +234 -20
  180. package/dist/judgement/runs/resume.d.ts +44 -0
  181. package/dist/judgement/runs/resume.js +137 -0
  182. package/dist/judgement/runs/reticle-runner.js +5 -2
  183. package/dist/judgement/runs/runner-port.d.ts +5 -1
  184. package/dist/judgement/runs/runner-port.js +8 -2
  185. package/dist/judgement/runs/verification-sync.d.ts +2 -0
  186. package/dist/judgement/runs/verification-sync.js +36 -15
  187. package/dist/language/flows/decision.js +2 -1
  188. package/dist/language/flows/fields/flow-secret-field.d.ts +12 -0
  189. package/dist/language/flows/fields/flow-secret-field.js +25 -2
  190. package/dist/language/flows/flow-anchor.d.ts +7 -2
  191. package/dist/language/flows/flow-anchor.js +10 -3
  192. package/dist/language/flows/flow-intent.d.ts +1 -0
  193. package/dist/language/flows/flow-journey.d.ts +6 -0
  194. package/dist/language/flows/flow-journey.js +20 -0
  195. package/dist/language/flows/flow-learning.d.ts +4 -0
  196. package/dist/language/flows/flow-learning.js +37 -3
  197. package/dist/language/flows/flow-replay-run.js +16 -18
  198. package/dist/language/flows/flow-replay-types.d.ts +1 -1
  199. package/dist/language/flows/flow-replay.d.ts +18 -1
  200. package/dist/language/flows/flow-replay.js +22 -7
  201. package/dist/language/flows/flow-result.d.ts +22 -1
  202. package/dist/language/flows/flow-result.js +47 -2
  203. package/dist/language/flows/flow-step-runners.d.ts +2 -0
  204. package/dist/language/flows/flow-step-runners.js +12 -6
  205. package/dist/language/flows/flow-store-for-session.js +5 -1
  206. package/dist/language/flows/flow-tools.d.ts +10 -0
  207. package/dist/language/flows/flow-tools.js +61 -62
  208. package/dist/language/flows/flows.d.ts +16 -1
  209. package/dist/language/flows/flows.js +69 -10
  210. package/dist/language/flows/narrow-write.d.ts +7 -0
  211. package/dist/language/flows/narrow-write.js +36 -1
  212. package/dist/language/flows/recording/recording-backtrack.js +14 -1
  213. package/dist/language/flows/recording/tape/recordings.d.ts +29 -1
  214. package/dist/language/flows/recording/tape/recordings.js +60 -10
  215. package/dist/language/flows/replay.js +29 -6
  216. package/dist/language/flows/single-replay.d.ts +7 -0
  217. package/dist/language/flows/single-replay.js +26 -0
  218. package/dist/language/flows/verify-change-tools.d.ts +1 -0
  219. package/dist/language/flows/verify-change-tools.js +200 -193
  220. package/dist/memory/cloud/cloud-config.d.ts +10 -1
  221. package/dist/memory/cloud/cloud-config.js +19 -5
  222. package/dist/memory/cloud/cloud-sync.js +3 -3
  223. package/dist/memory/cloud/harness-config.d.ts +49 -0
  224. package/dist/memory/cloud/harness-config.js +16 -20
  225. package/dist/memory/cloud/memory-scope.d.ts +17 -0
  226. package/dist/memory/cloud/memory-scope.js +22 -0
  227. package/dist/memory/cloud/sync-cycle.d.ts +32 -4
  228. package/dist/memory/cloud/sync-cycle.js +113 -12
  229. package/dist/memory/cloud/sync-daemon.d.ts +11 -0
  230. package/dist/memory/cloud/sync-daemon.js +114 -4
  231. package/dist/memory/cloud/sync-disk.js +26 -2
  232. package/dist/memory/cloud/sync-screenshots.d.ts +32 -0
  233. package/dist/memory/cloud/sync-screenshots.js +105 -0
  234. package/dist/memory/cloud/unsynced-roots.d.ts +47 -0
  235. package/dist/memory/cloud/unsynced-roots.js +166 -0
  236. package/dist/memory/impact/account-watch.d.ts +16 -1
  237. package/dist/memory/impact/account-watch.js +26 -1
  238. package/dist/memory/impact/impact-store.d.ts +1 -4
  239. package/dist/memory/impact/impact-store.js +32 -42
  240. package/dist/memory/intent/inline-intent.d.ts +1 -0
  241. package/dist/memory/intent/intent-shard-store.js +16 -4
  242. package/dist/memory/intent/intent-shard.d.ts +12 -0
  243. package/dist/memory/intent/intent-store.d.ts +1 -0
  244. package/dist/memory/intent/intent-tools.js +42 -2
  245. package/dist/memory/intent/open-intents.d.ts +6 -0
  246. package/dist/memory/intent/open-intents.js +10 -1
  247. package/dist/memory/intent/settled-words.d.ts +24 -0
  248. package/dist/memory/intent/settled-words.js +130 -0
  249. package/dist/memory/journal/drive-flow.d.ts +16 -0
  250. package/dist/memory/journal/drive-flow.js +34 -2
  251. package/dist/memory/journal/drive-run-flush.d.ts +2 -0
  252. package/dist/memory/journal/drive-run-flush.js +20 -5
  253. package/dist/memory/journal/journal-recorder.js +46 -3
  254. package/dist/memory/journal/on-disk/retention.d.ts +5 -0
  255. package/dist/memory/journal/on-disk/retention.js +27 -2
  256. package/dist/memory/journal/on-disk/workspace-tiers.js +2 -0
  257. package/dist/memory/journal/session-end.d.ts +15 -1
  258. package/dist/memory/journal/session-end.js +38 -7
  259. package/dist/memory/project/artifact-root-resolver.js +33 -5
  260. package/dist/memory/project/artifact-root.d.ts +4 -3
  261. package/dist/memory/project/artifact-root.js +2 -2
  262. package/dist/memory/project/dir/reticle-dir.d.ts +14 -0
  263. package/dist/memory/project/dir/reticle-dir.js +23 -2
  264. package/dist/memory/project/link-directory.d.ts +15 -0
  265. package/dist/memory/project/link-directory.js +44 -0
  266. package/dist/memory/project/root-claims.d.ts +6 -0
  267. package/dist/memory/project/root-claims.js +39 -0
  268. package/dist/memory/project/session-root.d.ts +2 -0
  269. package/dist/memory/project/session-root.js +9 -1
  270. package/dist/memory/project/sync-status.d.ts +46 -0
  271. package/dist/memory/project/sync-status.js +135 -1
  272. package/dist/memory/recall/memory-tools.js +46 -3
  273. package/dist/memory/recall/platform-memory.d.ts +34 -0
  274. package/dist/memory/recall/platform-memory.js +139 -0
  275. package/dist/memory/recall/project-memory.js +36 -8
  276. package/dist/portal/bridge/bridge.d.ts +9 -5
  277. package/dist/portal/bridge/bridge.js +66 -23
  278. package/dist/portal/bridge/harness-request.d.ts +23 -0
  279. package/dist/portal/bridge/harness-request.js +27 -0
  280. package/dist/portal/bridge/wrong-path.d.ts +17 -0
  281. package/dist/portal/bridge/wrong-path.js +35 -0
  282. package/dist/portal/input/network-mock-tools.js +11 -2
  283. package/dist/portal/input/real-input.d.ts +2 -0
  284. package/dist/portal/input/real-input.js +13 -10
  285. package/dist/portal/pool/browser-pool.d.ts +48 -0
  286. package/dist/portal/pool/browser-pool.js +120 -2
  287. package/dist/portal/pool/context-permissions.d.ts +33 -0
  288. package/dist/portal/pool/context-permissions.js +33 -0
  289. package/dist/portal/pool/lease-marker-stamp.d.ts +23 -0
  290. package/dist/portal/pool/lease-marker-stamp.js +49 -0
  291. package/dist/portal/pool/playwright-launcher.d.ts +27 -5
  292. package/dist/portal/pool/playwright-launcher.js +59 -14
  293. package/dist/portal/pool/pool-contract.d.ts +21 -1
  294. package/dist/portal/session/agent-link.d.ts +8 -0
  295. package/dist/portal/session/agent-link.js +17 -0
  296. package/dist/portal/session/command-payload.js +6 -1
  297. package/dist/portal/session/daemon-answers.d.ts +3 -3
  298. package/dist/portal/session/daemon-answers.js +4 -2
  299. package/dist/portal/session/dev-server/dev-command.d.ts +9 -0
  300. package/dist/portal/session/dev-server/dev-command.js +27 -1
  301. package/dist/portal/session/facts/observed-state.d.ts +16 -18
  302. package/dist/portal/session/facts/observed-state.js +46 -3
  303. package/dist/portal/session/human/live-control.d.ts +9 -2
  304. package/dist/portal/session/human/live-control.js +12 -3
  305. package/dist/portal/session/live-control-tools.js +82 -13
  306. package/dist/portal/session/narration-args.d.ts +5 -0
  307. package/dist/portal/session/narration-args.js +17 -0
  308. package/dist/portal/session/no-session-diagnosis.d.ts +1 -1
  309. package/dist/portal/session/no-session-diagnosis.js +31 -9
  310. package/dist/portal/session/no-session-next-action.d.ts +20 -0
  311. package/dist/portal/session/no-session-next-action.js +134 -61
  312. package/dist/portal/session/no-session-watch.js +179 -22
  313. package/dist/portal/session/presence/session-lease.js +1 -1
  314. package/dist/portal/session/recorded-gaps.d.ts +97 -0
  315. package/dist/portal/session/recorded-gaps.js +251 -0
  316. package/dist/portal/session/session-health.d.ts +11 -0
  317. package/dist/portal/session/session-health.js +3 -1
  318. package/dist/portal/session/session-info.js +2 -1
  319. package/dist/portal/session/session-manager.d.ts +18 -0
  320. package/dist/portal/session/session-manager.js +54 -3
  321. package/dist/portal/session/session-successor.d.ts +8 -0
  322. package/dist/portal/session/session-successor.js +1 -1
  323. package/dist/portal/session/session.d.ts +15 -28
  324. package/dist/portal/session/session.js +60 -61
  325. package/dist/portal/session/timing/command-timeout.js +25 -1
  326. package/dist/portal/session/timing/wall-clock.d.ts +1 -1
  327. package/dist/portal/session/timing/wall-clock.js +1 -1
  328. package/dist/portal/session/zero-install-first-call.d.ts +31 -0
  329. package/dist/portal/session/zero-install-first-call.js +88 -0
  330. package/dist/start-options.d.ts +7 -1
  331. package/dist/start-wiring.d.ts +63 -0
  332. package/dist/start-wiring.js +169 -0
  333. package/dist/status-payload.d.ts +13 -1
  334. package/dist/status-payload.js +13 -1
  335. package/dist/surface/http-server.js +7 -1
  336. package/dist/surface/mcp/attach-memory.d.ts +1 -0
  337. package/dist/surface/mcp/attach-memory.js +12 -1
  338. package/dist/surface/mcp/mcp-proxy.d.ts +4 -0
  339. package/dist/surface/mcp/mcp-proxy.js +29 -8
  340. package/dist/surface/mcp/mcp.d.ts +23 -0
  341. package/dist/surface/mcp/mcp.js +34 -4
  342. package/dist/surface/mcp/proxy/drive-calls.d.ts +10 -0
  343. package/dist/surface/mcp/proxy/drive-calls.js +27 -0
  344. package/dist/surface/mcp/proxy/mcp-post-transport.js +5 -0
  345. package/dist/surface/mcp/server-instructions.js +22 -14
  346. package/dist/surface/mcp/shared-params.js +1 -1
  347. package/dist/surface/mcp/surface-vocabulary.d.ts +2 -0
  348. package/dist/surface/mcp/surface-vocabulary.js +1 -0
  349. package/dist/surface/tools/account-tool.d.ts +22 -0
  350. package/dist/surface/tools/account-tool.js +157 -0
  351. package/dist/surface/tools/act/act-danger.d.ts +11 -0
  352. package/dist/surface/tools/act/act-danger.js +38 -1
  353. package/dist/surface/tools/act/act-observation.d.ts +33 -0
  354. package/dist/surface/tools/act/act-observation.js +57 -0
  355. package/dist/surface/tools/act/act-preflight.js +25 -2
  356. package/dist/surface/tools/act/act-target.js +8 -3
  357. package/dist/surface/tools/act/resolve-target.d.ts +1 -1
  358. package/dist/surface/tools/act/resolve-target.js +18 -3
  359. package/dist/surface/tools/act/screen-request.d.ts +34 -0
  360. package/dist/surface/tools/act/screen-request.js +113 -0
  361. package/dist/surface/tools/act/sequence-grade.d.ts +8 -0
  362. package/dist/surface/tools/act/sequence-grade.js +13 -2
  363. package/dist/surface/tools/act-sequence-tool.js +136 -27
  364. package/dist/surface/tools/act-tools.d.ts +0 -9
  365. package/dist/surface/tools/act-tools.js +48 -34
  366. package/dist/surface/tools/agent/app-notes-learning.d.ts +7 -0
  367. package/dist/surface/tools/agent/app-notes-learning.js +80 -0
  368. package/dist/surface/tools/agent/app-notes.d.ts +4 -0
  369. package/dist/surface/tools/agent/app-notes.js +48 -0
  370. package/dist/surface/tools/agent/build-staleness.d.ts +7 -0
  371. package/dist/surface/tools/agent/build-staleness.js +62 -0
  372. package/dist/surface/tools/agent/compact-envelope.d.ts +80 -0
  373. package/dist/surface/tools/agent/compact-envelope.js +374 -0
  374. package/dist/surface/tools/agent/for-the-agent.d.ts +12 -0
  375. package/dist/surface/tools/agent/for-the-agent.js +44 -0
  376. package/dist/surface/tools/agent/notices.d.ts +50 -0
  377. package/dist/surface/tools/agent/notices.js +152 -0
  378. package/dist/surface/tools/agent/reteach.d.ts +11 -0
  379. package/dist/surface/tools/agent/reteach.js +50 -0
  380. package/dist/surface/tools/args/alias-args.d.ts +5 -0
  381. package/dist/surface/tools/args/alias-args.js +10 -0
  382. package/dist/surface/tools/args/confirm-dangerous-arg.d.ts +6 -0
  383. package/dist/surface/tools/args/confirm-dangerous-arg.js +6 -0
  384. package/dist/surface/tools/assert/assert-source.d.ts +15 -0
  385. package/dist/surface/tools/assert/assert-source.js +40 -0
  386. package/dist/surface/tools/assert/assert-verdict.js +25 -15
  387. package/dist/surface/tools/browser-tools.js +43 -1
  388. package/dist/surface/tools/chat-drives.d.ts +75 -0
  389. package/dist/surface/tools/chat-drives.js +265 -21
  390. package/dist/surface/tools/coverage-tools.d.ts +2 -10
  391. package/dist/surface/tools/coverage-tools.js +2 -53
  392. package/dist/surface/tools/dynamic-tools.js +29 -1
  393. package/dist/surface/tools/empty-session-list.d.ts +10 -0
  394. package/dist/surface/tools/empty-session-list.js +45 -5
  395. package/dist/surface/tools/error-recovery.d.ts +8 -0
  396. package/dist/surface/tools/error-recovery.js +69 -5
  397. package/dist/surface/tools/explore-tools.d.ts +23 -2
  398. package/dist/surface/tools/explore-tools.js +377 -74
  399. package/dist/surface/tools/feedback-tools.d.ts +2 -3
  400. package/dist/surface/tools/feedback-tools.js +4 -3
  401. package/dist/surface/tools/gap-novelty.d.ts +3 -1
  402. package/dist/surface/tools/gap-novelty.js +8 -1
  403. package/dist/surface/tools/harness-explore.d.ts +52 -73
  404. package/dist/surface/tools/harness-explore.js +177 -146
  405. package/dist/surface/tools/harness-gate.d.ts +88 -0
  406. package/dist/surface/tools/harness-gate.js +235 -0
  407. package/dist/surface/tools/harness-hunt.d.ts +43 -0
  408. package/dist/surface/tools/harness-hunt.js +215 -0
  409. package/dist/surface/tools/harness-plan.d.ts +5 -0
  410. package/dist/surface/tools/harness-plan.js +7 -0
  411. package/dist/surface/tools/harness-script.d.ts +22 -0
  412. package/dist/surface/tools/harness-script.js +256 -38
  413. package/dist/surface/tools/harness-tab-guard.d.ts +5 -0
  414. package/dist/surface/tools/harness-tab-guard.js +27 -0
  415. package/dist/surface/tools/harness-toolset.d.ts +8 -0
  416. package/dist/surface/tools/harness-toolset.js +27 -4
  417. package/dist/surface/tools/human-notes.d.ts +16 -0
  418. package/dist/surface/tools/human-notes.js +27 -0
  419. package/dist/surface/tools/invoke-tool.d.ts +5 -2
  420. package/dist/surface/tools/invoke-tool.js +220 -93
  421. package/dist/surface/tools/lease-hint.js +26 -5
  422. package/dist/surface/tools/lease-permissions.d.ts +33 -0
  423. package/dist/surface/tools/lease-permissions.js +73 -0
  424. package/dist/surface/tools/lease-readiness.d.ts +38 -0
  425. package/dist/surface/tools/lease-readiness.js +57 -0
  426. package/dist/surface/tools/lease-seed.d.ts +20 -0
  427. package/dist/surface/tools/lease-seed.js +45 -1
  428. package/dist/surface/tools/lease-tools.d.ts +10 -1
  429. package/dist/surface/tools/lease-tools.js +119 -69
  430. package/dist/surface/tools/live-call-text.js +2 -2
  431. package/dist/surface/tools/merge-tools.js +42 -2
  432. package/dist/surface/tools/merged-name-redirect.js +4 -0
  433. package/dist/surface/tools/next-step.d.ts +11 -1
  434. package/dist/surface/tools/next-step.js +73 -18
  435. package/dist/surface/tools/observe-tools.js +43 -5
  436. package/dist/surface/tools/platform-moment.d.ts +60 -0
  437. package/dist/surface/tools/platform-moment.js +132 -4
  438. package/dist/surface/tools/read-tools.js +65 -14
  439. package/dist/surface/tools/reticle-result.d.ts +120 -0
  440. package/dist/surface/tools/reticle-result.js +364 -0
  441. package/dist/surface/tools/tool-kit.d.ts +68 -2
  442. package/dist/surface/tools/tool-kit.js +73 -1
  443. package/dist/surface/tools/tools.js +25 -13
  444. package/dist/telemetry/account-envelope.d.ts +7 -0
  445. package/dist/telemetry/account-envelope.js +61 -0
  446. package/dist/telemetry/agent-client.d.ts +15 -0
  447. package/dist/telemetry/agent-client.js +57 -0
  448. package/dist/telemetry/app-instrumented.js +9 -2
  449. package/dist/telemetry/argument-shape.d.ts +7 -0
  450. package/dist/telemetry/argument-shape.js +86 -1
  451. package/dist/telemetry/automation-hint.d.ts +2 -3
  452. package/dist/telemetry/automation-hint.js +33 -8
  453. package/dist/telemetry/cli-telemetry.js +7 -2
  454. package/dist/telemetry/daemon-telemetry.js +3 -0
  455. package/dist/telemetry/error-fingerprint.d.ts +10 -1
  456. package/dist/telemetry/error-fingerprint.js +61 -5
  457. package/dist/telemetry/feedback-cli.d.ts +0 -13
  458. package/dist/telemetry/feedback-cli.js +0 -77
  459. package/dist/telemetry/feedback.d.ts +13 -0
  460. package/dist/telemetry/feedback.js +183 -17
  461. package/dist/telemetry/harness-run.d.ts +18 -0
  462. package/dist/telemetry/harness-run.js +80 -0
  463. package/dist/telemetry/hud-events.d.ts +16 -0
  464. package/dist/telemetry/hud-events.js +27 -0
  465. package/dist/telemetry/hud-metrics.d.ts +27 -6
  466. package/dist/telemetry/hud-metrics.js +99 -25
  467. package/dist/telemetry/init-telemetry.js +2 -2
  468. package/dist/telemetry/install-source.d.ts +13 -25
  469. package/dist/telemetry/install-source.js +44 -3
  470. package/dist/telemetry/mcp-connection.d.ts +0 -14
  471. package/dist/telemetry/mcp-connection.js +5 -1
  472. package/dist/telemetry/onboarding-firsts.d.ts +32 -0
  473. package/dist/telemetry/onboarding-firsts.js +81 -6
  474. package/dist/telemetry/platform-linked.d.ts +5 -0
  475. package/dist/telemetry/platform-linked.js +32 -0
  476. package/dist/telemetry/project-profile.js +5 -3
  477. package/dist/telemetry/proxy-telemetry.js +4 -1
  478. package/dist/telemetry/session-metrics.d.ts +15 -4
  479. package/dist/telemetry/session-metrics.js +88 -52
  480. package/dist/telemetry/telemetry.d.ts +26 -2
  481. package/dist/telemetry/telemetry.js +102 -21
  482. package/dist/telemetry/verification-of.d.ts +3 -1
  483. package/dist/telemetry/verification-of.js +12 -4
  484. package/dist/wire-journal.d.ts +2 -2
  485. package/dist/wire-journal.js +16 -5
  486. package/docs/README.md +2 -2
  487. package/docs/actions.mdx +6 -3
  488. package/docs/adapters.md +1 -1
  489. package/docs/agent-cheatsheet.md +24 -27
  490. package/docs/architecture.md +5 -5
  491. package/docs/autodrive.md +13 -12
  492. package/docs/benchmarks.md +5 -5
  493. package/docs/best-practices.mdx +27 -9
  494. package/docs/capabilities.mdx +14 -16
  495. package/docs/cli/affected.mdx +1 -1
  496. package/docs/cli/cloud.mdx +54 -75
  497. package/docs/cli/doctor.mdx +8 -3
  498. package/docs/cli/drive.mdx +12 -12
  499. package/docs/cli/feedback.mdx +3 -3
  500. package/docs/cli/gate.mdx +7 -2
  501. package/docs/cli/help.mdx +50 -55
  502. package/docs/cli/init.mdx +32 -15
  503. package/docs/cli/license.mdx +12 -8
  504. package/docs/cli/mcp.mdx +4 -4
  505. package/docs/cli/open.mdx +3 -3
  506. package/docs/cli/report.mdx +4 -2
  507. package/docs/cli/restart.mdx +2 -2
  508. package/docs/cli/rollback.mdx +14 -8
  509. package/docs/cli/serve.mdx +4 -4
  510. package/docs/cli/setup.mdx +23 -0
  511. package/docs/cli/status.mdx +13 -4
  512. package/docs/cli/stop.mdx +67 -8
  513. package/docs/cli/try.mdx +62 -0
  514. package/docs/cli/update.mdx +4 -3
  515. package/docs/cli/verify.mdx +17 -6
  516. package/docs/cli/version.mdx +3 -2
  517. package/docs/cli.mdx +110 -41
  518. package/docs/debugging.md +3 -3
  519. package/docs/deploy-checks.md +1 -1
  520. package/docs/desktop.mdx +5 -3
  521. package/docs/enterprise.md +11 -10
  522. package/docs/environment.mdx +5 -2
  523. package/docs/faq.mdx +3 -3
  524. package/docs/first-drive.md +5 -4
  525. package/docs/flows.md +35 -27
  526. package/docs/for-agents.md +4 -5
  527. package/docs/frameworks.mdx +32 -21
  528. package/docs/getting-started.md +66 -64
  529. package/docs/human-control.md +15 -14
  530. package/docs/index.mdx +15 -43
  531. package/docs/install-agentic.mdx +22 -37
  532. package/docs/install-manual.mdx +22 -12
  533. package/docs/instrumentation.mdx +5 -3
  534. package/docs/integration-patterns.md +7 -7
  535. package/docs/license-activation.mdx +1 -1
  536. package/docs/multi-agent-testing.md +24 -6
  537. package/docs/packages/babel-plugin.mdx +4 -2
  538. package/docs/packages/browser.mdx +16 -10
  539. package/docs/packages/core.mdx +12 -5
  540. package/docs/packages/electron.mdx +3 -2
  541. package/docs/packages/engine.mdx +1 -1
  542. package/docs/packages/eslint-plugin.mdx +18 -12
  543. package/docs/packages/next.mdx +8 -7
  544. package/docs/packages/open-verification.mdx +1 -1
  545. package/docs/packages/server.mdx +5 -5
  546. package/docs/packages/tauri.mdx +8 -8
  547. package/docs/packages/test.mdx +4 -10
  548. package/docs/packages/vite-plugin.mdx +11 -4
  549. package/docs/packages.mdx +11 -15
  550. package/docs/platform-integration.md +6 -5
  551. package/docs/predicates.mdx +40 -24
  552. package/docs/quickstart.mdx +58 -29
  553. package/docs/required-checks.md +8 -7
  554. package/docs/reticle-manual.md +15 -5
  555. package/docs/skill-file.mdx +17 -79
  556. package/docs/skill-setup.md +9 -9
  557. package/docs/skill.md +200 -0
  558. package/docs/system-map.md +7 -7
  559. package/docs/telemetry.md +22 -24
  560. package/docs/testing.md +4 -4
  561. package/docs/token-efficiency.md +12 -12
  562. package/docs/tools/act-and-wait.mdx +9 -2
  563. package/docs/tools/act-sequence.mdx +6 -7
  564. package/docs/tools/act.mdx +2 -2
  565. package/docs/tools/assert.mdx +18 -17
  566. package/docs/tools/console.mdx +9 -9
  567. package/docs/tools/inspect.mdx +16 -7
  568. package/docs/tools/look.mdx +24 -0
  569. package/docs/tools/navigate.mdx +5 -3
  570. package/docs/tools/network.mdx +2 -2
  571. package/docs/tools/observe.mdx +6 -6
  572. package/docs/tools/overview.mdx +34 -33
  573. package/docs/tools/query.mdx +5 -5
  574. package/docs/tools/session-and-feedback.mdx +13 -4
  575. package/docs/tools/sessions.mdx +8 -8
  576. package/docs/tools/snapshot.mdx +6 -5
  577. package/docs/tools/state.mdx +9 -9
  578. package/docs/tools/tools-and-run.mdx +26 -24
  579. package/docs/tools/verify.mdx +28 -0
  580. package/docs/tools/wait-for.mdx +8 -4
  581. package/docs/troubleshooting.mdx +21 -6
  582. package/docs/usage.md +51 -45
  583. package/docs/use-cases.mdx +3 -3
  584. package/docs/vs-chrome-devtools-mcp.mdx +9 -6
  585. package/docs/vs-playwright-mcp.mdx +3 -1
  586. package/docs/what-is-recorded.md +7 -5
  587. package/docs/what-is-reticle.mdx +2 -2
  588. package/docs/why-reticle.mdx +1 -1
  589. package/package.json +6 -5
  590. package/dist/command/cli/demo/demo-page.d.ts +0 -78
  591. package/dist/command/cli/demo/demo-page.js +0 -249
  592. package/dist/command/cli/demo/demo-run.d.ts +0 -38
  593. package/dist/command/cli/demo/demo-run.js +0 -138
  594. package/dist/judgement/hunt/hunt-report.d.ts +0 -49
  595. package/dist/judgement/hunt/hunt-report.js +0 -84
  596. package/dist/language/flows/buddy-status.d.ts +0 -25
  597. package/dist/language/flows/buddy-status.js +0 -32
  598. package/dist/language/flows/change/watch-batcher.d.ts +0 -18
  599. package/dist/language/flows/change/watch-batcher.js +0 -19
  600. package/dist/memory/cloud/harness-offer.d.ts +0 -44
  601. package/dist/memory/cloud/harness-offer.js +0 -145
  602. package/dist/surface/tools/feature-capture.d.ts +0 -151
  603. package/dist/surface/tools/feature-capture.js +0 -235
  604. package/dist/surface/tools/tool-hit-rate.d.ts +0 -87
  605. package/dist/surface/tools/tool-hit-rate.js +0 -90
  606. package/dist/telemetry/harness-drive.d.ts +0 -4
  607. package/dist/telemetry/harness-drive.js +0 -35
  608. package/dist/telemetry/identify.d.ts +0 -22
  609. package/dist/telemetry/identify.js +0 -73
  610. package/docs/cli/capsules.mdx +0 -70
  611. package/docs/cli/hunt.mdx +0 -73
  612. package/docs/cli/identify.mdx +0 -76
  613. package/docs/cli/kill.mdx +0 -91
  614. package/docs/cli/watch.mdx +0 -62
@@ -2,12 +2,8 @@
2
2
  * The half of setup that happens after the files are written.
3
3
  *
4
4
  * `init` wires a project; this gets the app running with the SDK inside it and proves a session
5
- * connected. That is where ONBOARDING ends — the first run, which proves a flow, is a separate
6
- * stage and a separate command.
7
- *
8
- * It does NOT drive a flow. `reticle_verify { action: "explore" }` does that, with a model inside
9
- * the daemon that already holds the tools — so no client restart is needed and no second CLI has to
10
- * exist on the machine.
5
+ * connected. That is where ONBOARDING ends. Then init says what Reticle sees and hands the first
6
+ * flow to the coding agent (`try-command.ts`'s `initFirstFlow`); nothing in init drives.
11
7
  *
12
8
  * Every effect is injected. That is not ceremony: the sequence has five phases, each with its own
13
9
  * way of going wrong, and the alternative to injecting them is a test that boots a real dev server
@@ -47,6 +43,21 @@ const NO_BROWSER_GRACE_MS = 3_000;
47
43
  * as opened, and init then waited out its whole connect budget over a correct install.
48
44
  */
49
45
  const SYSTEM_BROWSER_GRACE_MS = 15_000;
46
+ /**
47
+ * Said before Reticle starts its own static server for a plain page, while it can still be acted
48
+ * on: the page may already be served by something with an API behind it, and only the person
49
+ * running init knows that (#1426).
50
+ */
51
+ export const STATIC_PAGE_URL_HINT = 'This page has no dev server of its own, so Reticle is starting a static one. ' +
52
+ 'If the page is already served (python -m http.server, php -S, a Node server with an API), ' +
53
+ 're-run with `reticle init --url <app>` to attach to that server instead.';
54
+ /** Whose server the success line names, so a session on Reticle's own is never mistaken for the app. */
55
+ export const ServerStartedBy = {
56
+ CALLER: 'you passed its url',
57
+ ALREADY_RUNNING: 'it was already running',
58
+ RETICLE_STATIC: 'Reticle started this static server',
59
+ SETUP: 'setup started the dev server',
60
+ };
50
61
  export const SetupPhase = {
51
62
  DEV_SERVER: 'dev-server',
52
63
  CONNECT: 'connect',
@@ -129,12 +140,14 @@ export async function runSetupPhases(input, fx) {
129
140
  note(
130
141
  // "stop here rather than invent one" is the SKILL.md rule, and the words are the contract —
131
142
  // inventing a dev command is how a setup script runs the wrong thing and reports success.
132
- 'No dev command: the project names no dev, start or serve script, and there is no --url. ' +
143
+ 'No dev command: the project names no dev, start or serve script, and no app url was given (`reticle init --url <app>`). ' +
133
144
  'Stopping here rather than invent one — start the app yourself and pass --url to say ' +
134
145
  'where it is serving, or add a dev/start/serve script to package.json and re-run.');
135
146
  return stop(input, SetupPhase.DEV_SERVER, {}, notes);
136
147
  }
137
148
  else {
149
+ if (true === input.devCommandIsStaticPage)
150
+ note(STATIC_PAGE_URL_HINT);
138
151
  await fx.startDevServer(input.devCommand, input.appDir);
139
152
  const startedAt = fx.now();
140
153
  // This loop used to poll in complete silence. Reported as thirty minutes of nothing ending in a
@@ -372,40 +385,33 @@ export async function runSetupPhases(input, fx) {
372
385
  // Getting started is three stages — installation puts the CLI on the machine, onboarding wires
373
386
  // the project, the first run proves a flow — and this command owns the middle one. A connected
374
387
  // session is the whole proof that onboarding worked: the SDK is in the page, the bridge paired,
375
- // and the tools now have something to talk to.
376
- //
377
- // `<url>` stays a placeholder in this string on purpose: `guidance-commands-run` feeds every
378
- // command we print to the real parser, and an interpolated value reads there as a missing operand.
379
- // The live url is named in the sentence instead, where a reader needs it anyway.
380
- // Both routes, because `explore` runs on the platform: without a linked project it refuses.
381
- // Naming only that one hands the reader a dead end on any machine without one.
382
- // A heading and a numbered list rather than one paragraph: a reader scans for what to do next.
388
+ // and the tools now have something to talk to. What to do next is the first flow's to say.
383
389
  //
384
- // This was a single 524-character note, measured on a real first run: eighty-three words, no
385
- // break, naming `reticle_*` tools at a reader who had just typed `reticle init` in a terminal and
386
- // has no such tools to call. The facts were right and the shape made them unreadable, which on
387
- // the last line of onboarding is the same as not saying them.
388
- note(`✓ Connected. ${url} is instrumented. Onboarding is done; nothing is verified yet.`);
390
+ // It names whose server that is, because a session on Reticle's static server is not the app a
391
+ // real server was serving, and "connected" alone let an agent verify the wrong one (#1426).
392
+ const startedBy = undefined !== input.suppliedUrl
393
+ ? ServerStartedBy.CALLER
394
+ : attachedToExisting
395
+ ? ServerStartedBy.ALREADY_RUNNING
396
+ : true === input.devCommandIsStaticPage
397
+ ? ServerStartedBy.RETICLE_STATIC
398
+ : ServerStartedBy.SETUP;
399
+ note(`✓ Connected to ${new URL(url).origin} (${startedBy}). Onboarding is done; nothing is verified yet.`);
389
400
  // Said, because "connected" otherwise reads as "your browser connected": the page that dialled
390
401
  // was a headless one Reticle launched and has now closed, and nothing is open on this screen.
391
- if (undefined !== lease && session.sessionId === lease.sessionId) {
402
+ const leased = undefined !== lease && session.sessionId === lease.sessionId;
403
+ if (leased) {
392
404
  note('The proof came from a Reticle-owned headless browser (now closed), not a window of yours — ' +
393
405
  `open ${url} in your own browser to use the app.`);
394
406
  }
395
407
  await releaseLease(lease);
396
- note('');
397
- note('Next, prove one flow. Your agent does this:');
398
- note(' 1. Drive one flow and end it with `reticle_act_and_wait` or `reticle_assert`. Those two ' +
399
- 'produce a verdict; nothing else does.');
400
- note(' 2. Or hand over the whole drive: `reticle_verify { action: "explore", persona: "<who does ' +
401
- 'what>" }` records what it drove, so later runs replay with no model in the loop. Runs on ' +
402
- 'the Reticle platform: needs a linked project (`reticle connect`); Free includes monthly Harness credits.');
403
408
  return {
404
409
  ok: true,
405
410
  reachedPhase: SetupPhase.CONNECT,
406
411
  url,
407
412
  sessionId: session.sessionId,
408
413
  flowSaved: false,
414
+ leased,
409
415
  notes,
410
416
  fallback: [],
411
417
  };
@@ -29,7 +29,30 @@ interface SetupCommandInput extends Omit<SetupInput, 'shape'> {
29
29
  readonly registerAgents: boolean;
30
30
  /** The bridge's pairing token, for the MCP transport a connect-proof lease is opened over. */
31
31
  readonly pairingToken?: string | undefined;
32
+ /** False for `--no-first-run`: connect, and say nothing more. */
33
+ readonly firstRun: boolean;
34
+ /** `--json`: an agent is reading, so nothing is driven on its behalf. */
35
+ readonly json: boolean;
36
+ /**
37
+ * What happens once the connection is proved: the coverage summary and the agent prompt. A port,
38
+ * because it reads the daemon's status and the link, which this directory does not reach for.
39
+ */
40
+ readonly firstFlow?: FirstFlowPort | undefined;
32
41
  }
42
+ /** init's ending, as `command/cli/try-command.ts` says it. Structural, so setup imports nothing. */
43
+ export type FirstFlowPort = (ctx: {
44
+ appDir: string;
45
+ bridgePort: number;
46
+ pairingToken?: string | undefined;
47
+ url: string;
48
+ sessionId: string;
49
+ leased: boolean;
50
+ openBrowser: boolean;
51
+ firstRun: boolean;
52
+ json: boolean;
53
+ }, say: (line: string) => void) => Promise<{
54
+ flowSaved: boolean;
55
+ }>;
33
56
  /** Returns how many agents it wrote a config for, so a caller does not then say "none found". */
34
57
  export declare function registerOtherAgents(print: (line: string) => void): number;
35
58
  type SetupCommandResult = SetupOutcome;
@@ -5,11 +5,12 @@
5
5
  * three lines it was. The only decision here is which effects to hand over; the sequencing lives in
6
6
  * run-setup.ts and the pieces it calls.
7
7
  */
8
- import { existsSync, readFileSync, writeFileSync } from 'node:fs';
8
+ import { chmodSync, existsSync, readFileSync, writeFileSync } from 'node:fs';
9
9
  import { homedir } from 'node:os';
10
10
  import { join } from 'node:path';
11
11
  import { planAgentConfigs } from './agent-configs.js';
12
12
  import { AppShape, describeShape, readShape } from './desktop-shape.js';
13
+ import { SigningEnv, tauriSigningEnv } from './tauri-signing.js';
13
14
  import { stopOnInterrupt } from './terminal/interrupt.js';
14
15
  import { stopOnCrash, crashSentence } from './terminal/crash.js';
15
16
  import { applyAgentPlan, applyAgentSkills } from './agent-writer.js';
@@ -22,7 +23,7 @@ import { readProjectId } from '../cli/ports/resolve/cli-port.js';
22
23
  import { spawnSync } from 'node:child_process';
23
24
  import { isAlive, reticleStateHome } from '../daemon/daemon.js';
24
25
  import { readDevServers } from '../daemon/dev-servers.js';
25
- import { urlOfExistingApp } from './probe/existing-app.js';
26
+ import { connectedAppUrl, urlOfExistingApp } from './probe/existing-app.js';
26
27
  import { handedOverUrl, stopHandedOver } from './bringup/dev-server-files.js';
27
28
  import { listSessions, OwnedDevServer, probePage } from './node-effects.js';
28
29
  import { fetchStatus } from '../daemon/binding/daemon-status-probe.js';
@@ -164,6 +165,31 @@ async function restartHandedOverServer(appDir) {
164
165
  }
165
166
  return stopped;
166
167
  }
168
+ /**
169
+ * init's ending, inside the dev server's lifetime: coverage is read off the open tab, and the `finally`
170
+ * in `runSetupCommand` only stops a server that was not handed over. Its lines join the notes, so
171
+ * `--json` carries the next step too.
172
+ */
173
+ async function afterConnect(input, url, sessionId, outcome, print) {
174
+ const notes = [...outcome.notes];
175
+ if (input.firstFlow === undefined)
176
+ return { flowSaved: false, notes };
177
+ const { flowSaved } = await input.firstFlow({
178
+ appDir: input.appDir,
179
+ bridgePort: input.bridgePort,
180
+ pairingToken: input.pairingToken,
181
+ url,
182
+ sessionId,
183
+ leased: true === outcome.leased,
184
+ openBrowser: input.openBrowser,
185
+ firstRun: input.firstRun,
186
+ json: input.json,
187
+ }, (line) => {
188
+ notes.push(line);
189
+ print(line);
190
+ });
191
+ return { flowSaved, notes };
192
+ }
167
193
  export async function runSetupCommand(input, print) {
168
194
  if (input.registerAgents)
169
195
  registerOtherAgents(print);
@@ -214,7 +240,29 @@ export async function runSetupCommand(input, print) {
214
240
  const effects = {
215
241
  startDevServer: (command, cwd) => {
216
242
  print(`starting: ${command}`);
217
- server.start(command, cwd, input.env);
243
+ const signing = AppShape.TAURI === shape
244
+ ? tauriSigningEnv({
245
+ platform: process.platform,
246
+ env: { ...process.env, ...input.env },
247
+ read: (path) => {
248
+ try {
249
+ return readFileSync(join(cwd, path), 'utf8');
250
+ }
251
+ catch {
252
+ return undefined;
253
+ }
254
+ },
255
+ writeRunner: (name, script) => {
256
+ const path = join(reticleStateHome(), name);
257
+ writeFileSync(path, script);
258
+ chmodSync(path, 0o755);
259
+ return path;
260
+ },
261
+ })
262
+ : {};
263
+ if (SigningEnv.IDENTITY in signing)
264
+ print(`signing the dev build as ${String(signing[SigningEnv.IDENTITY])}, so macOS does not ask for the keychain password`);
265
+ server.start(command, cwd, { ...input.env, ...signing });
218
266
  return Promise.resolve();
219
267
  },
220
268
  // The server the plugin announced (Vite), or failing that the one a previous init handed over
@@ -226,7 +274,9 @@ export async function runSetupCommand(input, print) {
226
274
  (await handedOverUrl(reticleStateHome(), input.appDir, {
227
275
  alive: isAlive,
228
276
  answers: async (url) => (await probePage(url)).served,
229
- })),
277
+ })) ??
278
+ // A desktop window of this project already connected: its renderer announces no server.
279
+ connectedAppUrl(await listSessions(input.bridgePort), readProjectId(input.appDir)),
230
280
  devServerOutput: () => server.output(),
231
281
  devServerExited: () => server.exited(),
232
282
  devServerQuietForMs: () => server.quietForMs(),
@@ -287,8 +337,11 @@ export async function runSetupCommand(input, print) {
287
337
  if (undefined !== log)
288
338
  print(`The dev server keeps running; its output goes to ${log}`);
289
339
  }
340
+ if (!outcome.ok || undefined === outcome.url || undefined === outcome.sessionId)
341
+ return outcome;
290
342
  return {
291
343
  ...outcome,
344
+ ...(await afterConnect(input, outcome.url, outcome.sessionId, outcome, print)),
292
345
  };
293
346
  }
294
347
  finally {
@@ -1,5 +1,22 @@
1
- import { McpClient, MCP_CLIENTS, claudeAddCommand, claudeAvailableProbe, claudeHasReticle, detectMcpClients, mergeClientConfig, clientSpec, ClientMergeStatus, } from '@reticlehq/init';
1
+ import { McpClient, MCP_CLIENTS, claudeAddCommand, claudeAvailableProbe, claudeHasReticle, codexAddCommand, codexAvailableProbe, codexNamesOurServer, detectMcpClients, mergeClientConfig, clientSpec, ClientMergeStatus, } from '@reticlehq/init';
2
2
  import { OnboardingPhase, OnboardingStepStatus, } from '@reticlehq/core/telemetry';
3
+ /**
4
+ * Codex registers through `codex mcp add`, which does the TOML editing we refuse to do (#1238).
5
+ * `undefined` when that does not apply, and the caller reports a hand edit exactly as before: not
6
+ * Codex, the `codex` binary is not here, or the config already names a `reticle` server. That last
7
+ * one matters: `codex mcp add` REPLACES an entry of the same name and still exits 0, so an entry
8
+ * somebody wrote themselves, in any shape, must never reach it. Otherwise: did the command take.
9
+ */
10
+ function registerWithCodexCli(io, client, serversKey) {
11
+ if (McpClient.CODEX !== client.id || codexNamesOurServer(client.existing, serversKey)) {
12
+ return undefined;
13
+ }
14
+ const probe = codexAvailableProbe();
15
+ if (!io.runCli(probe.command, probe.args))
16
+ return undefined;
17
+ const cmd = codexAddCommand();
18
+ return io.runCli(cmd.command, cmd.args);
19
+ }
3
20
  export function setupMcp(io) {
4
21
  const detected = [];
5
22
  const registered = [];
@@ -47,7 +64,13 @@ export function setupMcp(io) {
47
64
  // on an existing file and would CREATE an empty one otherwise, and either way claiming success
48
65
  // sends somebody to an agent that has no Reticle tools in it.
49
66
  if (ClientMergeStatus.MANUAL === merged.status) {
50
- manual.push({ id: client.id, configPath: client.configPath, docs: spec.docs });
67
+ const viaCli = registerWithCodexCli(io, client, spec.serversKey);
68
+ if (true === viaCli)
69
+ registered.push(client.id);
70
+ else if (false === viaCli)
71
+ failed.push(client.id);
72
+ else
73
+ manual.push({ id: client.id, configPath: client.configPath, docs: spec.docs });
51
74
  continue;
52
75
  }
53
76
  try {
@@ -0,0 +1,19 @@
1
+ /** The env the runner reads its arguments from: the script stays a fixed file. */
2
+ export declare const SigningEnv: {
3
+ readonly IDENTITY: "RETICLE_SIGNING_IDENTITY";
4
+ readonly IDENTIFIER: "RETICLE_SIGNING_IDENTIFIER";
5
+ readonly APPLE: "APPLE_SIGNING_IDENTITY";
6
+ };
7
+ export declare const RUNNER_FILE = "tauri-sign-runner.sh";
8
+ /** The runner: sign the binary Cargo built, then run it exactly as Cargo would have. */
9
+ export declare const RUNNER_SCRIPT: string;
10
+ export interface SigningDeps {
11
+ readonly platform: string;
12
+ readonly env: Readonly<Record<string, string | undefined>>;
13
+ /** A file's text relative to the app directory, or undefined when it is absent. */
14
+ readonly read: (path: string) => string | undefined;
15
+ /** Writes the runner and makes it executable; returns its absolute path. */
16
+ readonly writeRunner: (name: string, script: string) => string;
17
+ }
18
+ /** The extra env for starting a Tauri dev build signed, or `{}` when there is nothing to sign with. */
19
+ export declare function tauriSigningEnv(deps: SigningDeps): Record<string, string>;
@@ -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
  *