@reticlehq/server 3.7.0 → 3.8.1

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 (578) hide show
  1. package/SKILL.md +59 -68
  2. package/bin/reticle.js +9 -2
  3. package/dist/command/cli/adhoc-suite.js +1 -1
  4. package/dist/command/cli/adhoc-verdict.d.ts +12 -0
  5. package/dist/command/cli/adhoc-verdict.js +62 -4
  6. package/dist/command/cli/answers/gate-hook-message.d.ts +2 -0
  7. package/dist/command/cli/answers/gate-hook-message.js +5 -1
  8. package/dist/command/cli/auth/cloud-session.d.ts +11 -19
  9. package/dist/command/cli/auth/cloud-session.js +23 -0
  10. package/dist/command/cli/auth/device-flow.d.ts +3 -37
  11. package/dist/command/cli/cli-doctor.js +66 -21
  12. package/dist/command/cli/cli-flow-commands.js +53 -11
  13. package/dist/command/cli/cli-kill.d.ts +8 -0
  14. package/dist/command/cli/cli-kill.js +43 -3
  15. package/dist/command/cli/cli-parse-feedback.d.ts +4 -0
  16. package/dist/command/cli/cli-parse-feedback.js +13 -1
  17. package/dist/command/cli/cli-parse-grammar.d.ts +1 -2
  18. package/dist/command/cli/cli-parse-grammar.js +1 -6
  19. package/dist/command/cli/cli-parse-serve.d.ts +24 -0
  20. package/dist/command/cli/cli-parse-serve.js +124 -0
  21. package/dist/command/cli/cli-parse.d.ts +12 -11
  22. package/dist/command/cli/cli-parse.js +100 -123
  23. package/dist/command/cli/cli-usage.d.ts +0 -11
  24. package/dist/command/cli/cli-usage.js +43 -16
  25. package/dist/command/cli/cli-verify.d.ts +1 -1
  26. package/dist/command/cli/cli-verify.js +29 -14
  27. package/dist/command/cli/cloud-cli.js +27 -9
  28. package/dist/command/cli/cloud-kit.js +3 -3
  29. package/dist/command/cli/cloud-link.d.ts +1 -20
  30. package/dist/command/cli/cloud-link.js +2 -0
  31. package/dist/command/cli/cloud-login.d.ts +6 -2
  32. package/dist/command/cli/cloud-login.js +13 -41
  33. package/dist/command/cli/config/checkout.d.ts +10 -0
  34. package/dist/command/cli/config/checkout.js +78 -0
  35. package/dist/command/cli/doctor/doctor-agent-link.d.ts +23 -0
  36. package/dist/command/cli/doctor/doctor-agent-link.js +28 -0
  37. package/dist/command/cli/doctor/doctor-coverage-line.js +1 -7
  38. package/dist/command/cli/doctor/doctor-rows.d.ts +4 -0
  39. package/dist/command/cli/doctor/doctor-rows.js +4 -0
  40. package/dist/command/cli/drive/drive-attach.d.ts +5 -0
  41. package/dist/command/cli/drive/drive-attach.js +21 -1
  42. package/dist/command/cli/hook/codex-transcript.d.ts +20 -0
  43. package/dist/command/cli/hook/codex-transcript.js +224 -0
  44. package/dist/command/cli/hook/episode-structure.d.ts +24 -0
  45. package/dist/command/cli/hook/episode-structure.js +138 -0
  46. package/dist/command/cli/hook/hook-command.d.ts +9 -0
  47. package/dist/command/cli/hook/hook-command.js +211 -0
  48. package/dist/command/cli/hook/hook-fast.d.ts +31 -0
  49. package/dist/command/cli/hook/hook-fast.js +136 -0
  50. package/dist/command/cli/hook/prompt-hook.d.ts +30 -0
  51. package/dist/command/cli/hook/prompt-hook.js +199 -0
  52. package/dist/command/cli/hook/tool-hook.d.ts +21 -0
  53. package/dist/command/cli/hook/tool-hook.js +259 -0
  54. package/dist/command/cli/launch/cli-launch.d.ts +2 -0
  55. package/dist/command/cli/launch/cli-launch.js +22 -2
  56. package/dist/command/cli/lifecycle/daemon-lifecycle.js +28 -2
  57. package/dist/command/cli/mcp-command.d.ts +9 -0
  58. package/dist/command/cli/mcp-command.js +127 -41
  59. package/dist/command/cli/open-navigate.d.ts +43 -0
  60. package/dist/command/cli/open-navigate.js +85 -0
  61. package/dist/command/cli/ports/port-holder.d.ts +16 -4
  62. package/dist/command/cli/ports/port-holder.js +58 -12
  63. package/dist/command/cli/ports/resolve/cli-port.js +18 -2
  64. package/dist/command/cli/project-name.d.ts +1 -7
  65. package/dist/command/cli/project-name.js +1 -0
  66. package/dist/command/cli/report-command.d.ts +8 -2
  67. package/dist/command/cli/report-command.js +95 -18
  68. package/dist/command/cli/status-fields.d.ts +9 -2
  69. package/dist/command/cli/status-fields.js +148 -4
  70. package/dist/command/cli/try-command.d.ts +3 -4
  71. package/dist/command/cli/try-command.js +6 -11
  72. package/dist/command/cli/verify-results.d.ts +4 -1
  73. package/dist/command/cli/verify-results.js +3 -1
  74. package/dist/command/cli.d.ts +1 -7
  75. package/dist/command/cli.js +79 -160
  76. package/dist/command/daemon/daemon-resilience.d.ts +6 -1
  77. package/dist/command/daemon/daemon-resilience.js +31 -18
  78. package/dist/command/daemon/daemon.d.ts +11 -0
  79. package/dist/command/daemon/daemon.js +70 -2
  80. package/dist/command/daemon/lifetime/daemon-usefulness.d.ts +2 -0
  81. package/dist/command/daemon/lifetime/daemon-usefulness.js +13 -2
  82. package/dist/command/daemon/wake-decision.js +4 -2
  83. package/dist/command/daemon/win32-escape.d.ts +32 -0
  84. package/dist/command/daemon/win32-escape.js +119 -0
  85. package/dist/command/setup/agent-configs.d.ts +9 -0
  86. package/dist/command/setup/agent-configs.js +9 -0
  87. package/dist/command/setup/auto-approve.d.ts +10 -3
  88. package/dist/command/setup/auto-approve.js +51 -3
  89. package/dist/command/setup/bringup/dev-server-files.d.ts +1 -9
  90. package/dist/command/setup/bringup/dev-server-wait.js +5 -1
  91. package/dist/command/setup/bringup/ensure-daemon.js +4 -7
  92. package/dist/command/setup/init/init-host.js +6 -0
  93. package/dist/command/setup/init/init-port.js +5 -4
  94. package/dist/command/setup/init/init-runtime.js +7 -1
  95. package/dist/command/setup/node-effects.d.ts +8 -0
  96. package/dist/command/setup/node-effects.js +36 -4
  97. package/dist/command/setup/probe/dev-port.d.ts +26 -0
  98. package/dist/command/setup/probe/dev-port.js +117 -0
  99. package/dist/command/setup/probe/page-probe.d.ts +1 -1
  100. package/dist/command/setup/probe/page-probe.js +11 -3
  101. package/dist/command/setup/remaining-steps.d.ts +0 -7
  102. package/dist/command/setup/remaining-steps.js +3 -2
  103. package/dist/command/setup/run-setup.d.ts +11 -0
  104. package/dist/command/setup/run-setup.js +33 -5
  105. package/dist/command/setup/setup-command.d.ts +2 -0
  106. package/dist/command/setup/setup-command.js +22 -4
  107. package/dist/command/update/updater.d.ts +1 -6
  108. package/dist/command/update/updater.js +4 -5
  109. package/dist/command/update/version-seen.d.ts +24 -0
  110. package/dist/command/update/version-seen.js +65 -0
  111. package/dist/command/version/peer-announce.d.ts +9 -1
  112. package/dist/command/version/peer-announce.js +25 -2
  113. package/dist/command/version/sdk-fix.d.ts +5 -6
  114. package/dist/command/version/sdk-fix.js +17 -32
  115. package/dist/command/version/version-skew.d.ts +16 -1
  116. package/dist/command/version/version-skew.js +84 -10
  117. package/dist/features/crawl/crawl-tools.js +2 -2
  118. package/dist/features/crawl/crawl.js +2 -0
  119. package/dist/features/exhaust/ledger.d.ts +15 -96
  120. package/dist/features/exhaust/ledger.js +3 -3
  121. package/dist/features/harness/drive-runs.d.ts +28 -4
  122. package/dist/features/harness/drive-runs.js +99 -7
  123. package/dist/features/harness/drivers.d.ts +1 -1
  124. package/dist/features/harness/drivers.js +1 -1
  125. package/dist/features/harness/harness.d.ts +5 -0
  126. package/dist/features/harness/harness.js +24 -12
  127. package/dist/features/harness/platform/platform-drives.d.ts +7 -1
  128. package/dist/features/harness/platform/platform-drives.js +12 -7
  129. package/dist/features/harness/platform/refusal.d.ts +1 -1
  130. package/dist/features/harness/platform/refusal.js +4 -4
  131. package/dist/features/harness/platform/remote-drive.js +70 -28
  132. package/dist/features/harness/platform/server-driver.js +22 -1
  133. package/dist/features/harness/platform-config.d.ts +1 -10
  134. package/dist/features/harness/platform-config.js +0 -20
  135. package/dist/features/license/license.d.ts +2 -14
  136. package/dist/features/visual/step-shots.d.ts +33 -1
  137. package/dist/features/visual/step-shots.js +155 -1
  138. package/dist/features/visual/visual-tools.js +12 -4
  139. package/dist/hooks/coding-agents.d.ts +6 -0
  140. package/dist/hooks/coding-agents.js +24 -3
  141. package/dist/hooks/episode-stamp.d.ts +32 -0
  142. package/dist/hooks/episode-stamp.js +61 -0
  143. package/dist/hooks/hook-commands.js +19 -9
  144. package/dist/index.d.ts +5 -1
  145. package/dist/index.js +66 -24
  146. package/dist/judgement/app-graph/journal-steps.d.ts +8 -0
  147. package/dist/judgement/app-graph/journal-steps.js +92 -0
  148. package/dist/judgement/capsule/capsule-store.d.ts +2 -39
  149. package/dist/judgement/domain/domain-model.js +1 -10
  150. package/dist/judgement/domain/domain-tools.js +4 -2
  151. package/dist/judgement/runs/artifact/run-store.d.ts +28 -8
  152. package/dist/judgement/runs/artifact/run-store.js +153 -28
  153. package/dist/judgement/runs/default-run-id.d.ts +3 -1
  154. package/dist/judgement/runs/default-run-id.js +15 -3
  155. package/dist/judgement/runs/drive-run.d.ts +3 -3
  156. package/dist/judgement/runs/drive-run.js +11 -7
  157. package/dist/judgement/runs/run-ledger.d.ts +21 -0
  158. package/dist/judgement/runs/run-ledger.js +143 -0
  159. package/dist/judgement/runs/runner-port.d.ts +1 -1
  160. package/dist/judgement/runs/runner-port.js +8 -2
  161. package/dist/judgement/runs/verification-sync.d.ts +4 -3
  162. package/dist/judgement/runs/verification-sync.js +27 -5
  163. package/dist/language/flows/affected-tools.js +2 -1
  164. package/dist/language/flows/annotate-notes/annotate.js +8 -3
  165. package/dist/language/flows/annotate-tools.js +1 -1
  166. package/dist/language/flows/change/affected.d.ts +8 -0
  167. package/dist/language/flows/change/affected.js +20 -7
  168. package/dist/language/flows/decision.js +19 -4
  169. package/dist/language/flows/fields/flow-secret-field.d.ts +9 -0
  170. package/dist/language/flows/fields/flow-secret-field.js +67 -5
  171. package/dist/language/flows/flow-anchor.d.ts +5 -0
  172. package/dist/language/flows/flow-anchor.js +4 -0
  173. package/dist/language/flows/flow-cross-step.d.ts +7 -1
  174. package/dist/language/flows/flow-cross-step.js +9 -0
  175. package/dist/language/flows/flow-expect-grammar.js +15 -10
  176. package/dist/language/flows/flow-intent.js +6 -1
  177. package/dist/language/flows/flow-journey.d.ts +8 -0
  178. package/dist/language/flows/flow-journey.js +13 -0
  179. package/dist/language/flows/flow-lease.d.ts +27 -0
  180. package/dist/language/flows/flow-lease.js +59 -0
  181. package/dist/language/flows/flow-replay-run.d.ts +1 -87
  182. package/dist/language/flows/flow-replay-run.js +111 -310
  183. package/dist/language/flows/flow-replay.js +21 -19
  184. package/dist/language/flows/flow-replayable.d.ts +38 -0
  185. package/dist/language/flows/flow-replayable.js +179 -0
  186. package/dist/language/flows/flow-start-path.d.ts +108 -0
  187. package/dist/language/flows/flow-start-path.js +313 -0
  188. package/dist/language/flows/flow-step-runners.d.ts +23 -2
  189. package/dist/language/flows/flow-step-runners.js +191 -32
  190. package/dist/language/flows/flow-store-for-session.d.ts +8 -1
  191. package/dist/language/flows/flow-store-for-session.js +6 -0
  192. package/dist/language/flows/flow-tools.d.ts +2 -23
  193. package/dist/language/flows/flow-tools.js +63 -113
  194. package/dist/language/flows/flows.d.ts +4 -6
  195. package/dist/language/flows/flows.js +90 -15
  196. package/dist/language/flows/heal-run.d.ts +10 -4
  197. package/dist/language/flows/heal-run.js +26 -9
  198. package/dist/language/flows/recording/flake.d.ts +3 -27
  199. package/dist/language/flows/recording/flake.js +1 -1
  200. package/dist/language/flows/recording/recording-backtrack.js +1 -4
  201. package/dist/language/flows/recording/tape/recordings.d.ts +11 -1
  202. package/dist/language/flows/recording/tape/recordings.js +9 -3
  203. package/dist/language/flows/replay.d.ts +25 -5
  204. package/dist/language/flows/replay.js +83 -16
  205. package/dist/language/flows/stores/assertion-tiers-store.js +1 -1
  206. package/dist/language/flows/suite/coverage.d.ts +9 -0
  207. package/dist/language/flows/suite/coverage.js +12 -1
  208. package/dist/language/flows/suite-selection.d.ts +25 -0
  209. package/dist/language/flows/suite-selection.js +41 -9
  210. package/dist/machine/git-tracks.d.ts +6 -0
  211. package/dist/machine/git-tracks.js +36 -0
  212. package/dist/memory/cloud/background-sync.d.ts +25 -0
  213. package/dist/memory/cloud/background-sync.js +79 -0
  214. package/dist/memory/cloud/cloud-config.d.ts +12 -1
  215. package/dist/memory/cloud/cloud-config.js +39 -13
  216. package/dist/memory/cloud/cloud-sync.d.ts +3 -24
  217. package/dist/memory/cloud/cloud-sync.js +5 -2
  218. package/dist/memory/cloud/harness-config.d.ts +0 -7
  219. package/dist/memory/cloud/memory-scope.d.ts +19 -0
  220. package/dist/memory/cloud/memory-scope.js +48 -0
  221. package/dist/memory/cloud/sync-answer.d.ts +43 -0
  222. package/dist/memory/cloud/sync-answer.js +42 -0
  223. package/dist/memory/cloud/sync-cycle.d.ts +40 -10
  224. package/dist/memory/cloud/sync-cycle.js +97 -144
  225. package/dist/memory/cloud/sync-daemon.d.ts +50 -3
  226. package/dist/memory/cloud/sync-daemon.js +473 -83
  227. package/dist/memory/cloud/sync-describe.d.ts +28 -0
  228. package/dist/memory/cloud/sync-describe.js +92 -0
  229. package/dist/memory/cloud/sync-disk.d.ts +9 -1
  230. package/dist/memory/cloud/sync-disk.js +137 -33
  231. package/dist/memory/cloud/sync-flow-versions.d.ts +26 -0
  232. package/dist/memory/cloud/sync-flow-versions.js +42 -0
  233. package/dist/memory/impact/impact-store.js +32 -15
  234. package/dist/memory/intent/intent-shard.d.ts +41 -266
  235. package/dist/memory/intent/intent-tools.js +20 -61
  236. package/dist/memory/intent/record-request.d.ts +27 -0
  237. package/dist/memory/intent/record-request.js +88 -0
  238. package/dist/memory/intent/settled-words.js +9 -1
  239. package/dist/memory/journal/drive-flow.d.ts +3 -0
  240. package/dist/memory/journal/drive-flow.js +11 -41
  241. package/dist/memory/journal/envelope-store.js +1 -1
  242. package/dist/memory/journal/envelope.d.ts +6 -154
  243. package/dist/memory/journal/episode-log.d.ts +107 -0
  244. package/dist/memory/journal/episode-log.js +302 -0
  245. package/dist/memory/journal/journal-recorder.d.ts +7 -0
  246. package/dist/memory/journal/journal-recorder.js +22 -9
  247. package/dist/memory/journal/on-disk/ambient-file.d.ts +1 -7
  248. package/dist/memory/journal/on-disk/ambient-file.js +1 -1
  249. package/dist/memory/journal/on-disk/workspace-gitignore.d.ts +24 -3
  250. package/dist/memory/journal/on-disk/workspace-gitignore.js +38 -7
  251. package/dist/memory/journal/on-disk/workspace-tiers.js +7 -0
  252. package/dist/memory/journal/self-observation.js +3 -1
  253. package/dist/memory/journal/session-end.js +23 -9
  254. package/dist/memory/journal/session-journal.js +39 -20
  255. package/dist/memory/project/artifact-root-resolver.d.ts +14 -1
  256. package/dist/memory/project/artifact-root-resolver.js +68 -23
  257. package/dist/memory/project/artifact-root.d.ts +17 -3
  258. package/dist/memory/project/artifact-root.js +47 -9
  259. package/dist/memory/project/fs/fs-port.d.ts +5 -0
  260. package/dist/memory/project/fs/fs-port.js +13 -0
  261. package/dist/memory/project/learned-routes.d.ts +3 -4
  262. package/dist/memory/project/learned-routes.js +3 -11
  263. package/dist/memory/project/link-directory.js +5 -2
  264. package/dist/memory/project/root-claims.d.ts +3 -1
  265. package/dist/memory/project/root-claims.js +41 -7
  266. package/dist/memory/project/session-root.d.ts +1 -1
  267. package/dist/memory/project/session-root.js +1 -15
  268. package/dist/memory/project/sync-status.js +5 -6
  269. package/dist/memory/recall/memory-tools.js +2 -2
  270. package/dist/memory/recall/platform-memory.d.ts +3 -1
  271. package/dist/memory/recall/platform-memory.js +9 -1
  272. package/dist/memory/recall/project-memory.js +15 -19
  273. package/dist/portal/bridge/auth-failure-reason.d.ts +13 -0
  274. package/dist/portal/bridge/auth-failure-reason.js +19 -0
  275. package/dist/portal/bridge/bridge.d.ts +19 -4
  276. package/dist/portal/bridge/bridge.js +150 -177
  277. package/dist/portal/bridge/harness-request.d.ts +15 -0
  278. package/dist/portal/bridge/harness-request.js +19 -0
  279. package/dist/portal/bridge/origin/origin-follow.d.ts +46 -0
  280. package/dist/portal/bridge/origin/origin-follow.js +110 -0
  281. package/dist/portal/bridge/pairing-token.d.ts +6 -0
  282. package/dist/portal/bridge/pairing-token.js +47 -16
  283. package/dist/portal/bridge/protocol-skew.d.ts +27 -2
  284. package/dist/portal/bridge/protocol-skew.js +66 -2
  285. package/dist/portal/bridge/session-nonces.d.ts +46 -0
  286. package/dist/portal/bridge/session-nonces.js +72 -0
  287. package/dist/portal/input/viewport-tools.d.ts +31 -0
  288. package/dist/portal/input/viewport-tools.js +106 -15
  289. package/dist/portal/pool/bounded-close.d.ts +23 -0
  290. package/dist/portal/pool/bounded-close.js +38 -0
  291. package/dist/portal/pool/browser-pool.d.ts +44 -39
  292. package/dist/portal/pool/browser-pool.js +247 -95
  293. package/dist/portal/pool/context-permissions.d.ts +9 -1
  294. package/dist/portal/pool/context-permissions.js +26 -0
  295. package/dist/portal/pool/lease-emulation.d.ts +37 -0
  296. package/dist/portal/pool/lease-emulation.js +29 -0
  297. package/dist/portal/pool/playwright-launcher.d.ts +6 -0
  298. package/dist/portal/pool/playwright-launcher.js +74 -7
  299. package/dist/portal/pool/pool-contract.d.ts +23 -1
  300. package/dist/portal/pool/pool-lease.d.ts +128 -0
  301. package/dist/portal/pool/pool-lease.js +49 -0
  302. package/dist/portal/pool/zero-install.d.ts +8 -1
  303. package/dist/portal/pool/zero-install.js +24 -2
  304. package/dist/portal/production/production-activation.d.ts +136 -0
  305. package/dist/portal/production/production-activation.js +173 -0
  306. package/dist/portal/production/production-drive.d.ts +52 -0
  307. package/dist/portal/production/production-drive.js +301 -0
  308. package/dist/portal/production/production-hello.d.ts +23 -0
  309. package/dist/portal/production/production-hello.js +23 -0
  310. package/dist/portal/realm/web-realm.js +42 -15
  311. package/dist/portal/session/control-envelope.d.ts +1 -1
  312. package/dist/portal/session/dev-server/served-document.d.ts +0 -5
  313. package/dist/portal/session/dev-server/served-document.js +6 -8
  314. package/dist/portal/session/facts/handshake-facts.d.ts +8 -1
  315. package/dist/portal/session/first-run-wiring.d.ts +3 -36
  316. package/dist/portal/session/first-run-wiring.js +10 -103
  317. package/dist/portal/session/live-control-tools.js +61 -19
  318. package/dist/portal/session/no-session-next-action.d.ts +11 -0
  319. package/dist/portal/session/no-session-next-action.js +40 -15
  320. package/dist/portal/session/no-session-watch.d.ts +7 -0
  321. package/dist/portal/session/no-session-watch.js +67 -23
  322. package/dist/portal/session/output-budget.d.ts +10 -0
  323. package/dist/portal/session/output-budget.js +16 -0
  324. package/dist/portal/session/presence/session-lease.d.ts +2 -0
  325. package/dist/portal/session/presence/session-lease.js +8 -0
  326. package/dist/portal/session/recorded-gaps.d.ts +15 -11
  327. package/dist/portal/session/recorded-gaps.js +39 -18
  328. package/dist/portal/session/serving-directory.d.ts +24 -2
  329. package/dist/portal/session/serving-directory.js +93 -5
  330. package/dist/portal/session/session-info.d.ts +26 -0
  331. package/dist/portal/session/session-info.js +20 -0
  332. package/dist/portal/session/session-manager.d.ts +35 -3
  333. package/dist/portal/session/session-manager.js +69 -14
  334. package/dist/portal/session/session-successor.js +1 -9
  335. package/dist/portal/session/session-tools.js +22 -4
  336. package/dist/portal/session/session.d.ts +10 -10
  337. package/dist/portal/session/session.js +37 -29
  338. package/dist/portal/session/zero-install-first-call.d.ts +7 -2
  339. package/dist/portal/session/zero-install-first-call.js +43 -20
  340. package/dist/start-wiring.d.ts +2 -2
  341. package/dist/start-wiring.js +17 -3
  342. package/dist/status-payload.d.ts +11 -1
  343. package/dist/status-payload.js +7 -1
  344. package/dist/surface/agent-presence-grace.d.ts +11 -0
  345. package/dist/surface/agent-presence-grace.js +34 -0
  346. package/dist/surface/http-server.d.ts +12 -1
  347. package/dist/surface/http-server.js +64 -15
  348. package/dist/surface/mcp/faults/mcp-outage.d.ts +12 -2
  349. package/dist/surface/mcp/faults/mcp-outage.js +19 -1
  350. package/dist/surface/mcp/mcp-proxy.d.ts +17 -74
  351. package/dist/surface/mcp/mcp-proxy.js +194 -267
  352. package/dist/surface/mcp/mcp.d.ts +20 -3
  353. package/dist/surface/mcp/mcp.js +88 -25
  354. package/dist/surface/mcp/proxy/drive-calls.d.ts +44 -0
  355. package/dist/surface/mcp/proxy/drive-calls.js +114 -5
  356. package/dist/surface/mcp/proxy/proxy-boot.d.ts +11 -0
  357. package/dist/surface/mcp/proxy/proxy-boot.js +1 -0
  358. package/dist/surface/mcp/proxy/proxy-daemon-probe.d.ts +6 -0
  359. package/dist/surface/mcp/proxy/proxy-daemon-probe.js +14 -1
  360. package/dist/surface/mcp/proxy/proxy-handshake.d.ts +34 -2
  361. package/dist/surface/mcp/proxy/proxy-handshake.js +76 -8
  362. package/dist/surface/mcp/server-instructions.js +35 -16
  363. package/dist/surface/mcp/shared-params.d.ts +8 -0
  364. package/dist/surface/mcp/shared-params.js +15 -1
  365. package/dist/surface/mcp/sse-frame-parser.d.ts +11 -0
  366. package/dist/surface/mcp/sse-frame-parser.js +18 -0
  367. package/dist/surface/mcp/surface-vocabulary.d.ts +2 -0
  368. package/dist/surface/mcp/surface-vocabulary.js +13 -0
  369. package/dist/surface/mcp/tool-catalog-cache.d.ts +2 -0
  370. package/dist/surface/mcp/tool-catalog-cache.js +14 -4
  371. package/dist/surface/tools/account-tool.d.ts +4 -3
  372. package/dist/surface/tools/account-tool.js +20 -31
  373. package/dist/surface/tools/act/act-danger.d.ts +2 -0
  374. package/dist/surface/tools/act/act-danger.js +41 -14
  375. package/dist/surface/tools/act/act-observation.d.ts +11 -0
  376. package/dist/surface/tools/act/act-observation.js +33 -0
  377. package/dist/surface/tools/act/act-preflight.js +10 -3
  378. package/dist/surface/tools/act/act-sequence-retry.js +2 -1
  379. package/dist/surface/tools/act/act-target.js +19 -5
  380. package/dist/surface/tools/act/durable.js +1 -1
  381. package/dist/surface/tools/act/navigation/navigate-arrival.d.ts +9 -7
  382. package/dist/surface/tools/act/navigation/navigate-arrival.js +11 -14
  383. package/dist/surface/tools/act/unsettled-find.d.ts +36 -0
  384. package/dist/surface/tools/act/unsettled-find.js +71 -0
  385. package/dist/surface/tools/act-sequence-tool.js +53 -24
  386. package/dist/surface/tools/act-tools.d.ts +2 -3
  387. package/dist/surface/tools/act-tools.js +49 -47
  388. package/dist/surface/tools/agent/compact-envelope.d.ts +2 -2
  389. package/dist/surface/tools/agent/for-the-agent.js +41 -3
  390. package/dist/surface/tools/assert/assert-grade.js +8 -3
  391. package/dist/surface/tools/assert/assert-verdict.js +4 -2
  392. package/dist/surface/tools/browser-tools.js +7 -4
  393. package/dist/surface/tools/chat-drives.js +50 -25
  394. package/dist/surface/tools/coverage-tools.js +1 -1
  395. package/dist/surface/tools/dynamic-tools.d.ts +8 -0
  396. package/dist/surface/tools/dynamic-tools.js +89 -34
  397. package/dist/surface/tools/empty-session-list.d.ts +18 -25
  398. package/dist/surface/tools/empty-session-list.js +67 -38
  399. package/dist/surface/tools/error-recovery.d.ts +17 -7
  400. package/dist/surface/tools/error-recovery.js +53 -20
  401. package/dist/surface/tools/explore-tools.d.ts +10 -0
  402. package/dist/surface/tools/explore-tools.js +72 -19
  403. package/dist/surface/tools/feedback-tools.js +23 -2
  404. package/dist/surface/tools/gap-novelty.d.ts +6 -0
  405. package/dist/surface/tools/gap-novelty.js +9 -0
  406. package/dist/surface/tools/gaps/capability-absences.js +4 -3
  407. package/dist/surface/tools/harness-explore.d.ts +1 -1
  408. package/dist/surface/tools/harness-explore.js +6 -4
  409. package/dist/surface/tools/harness-gate.d.ts +43 -21
  410. package/dist/surface/tools/harness-gate.js +55 -81
  411. package/dist/surface/tools/harness-script.d.ts +2 -0
  412. package/dist/surface/tools/harness-script.js +11 -6
  413. package/dist/surface/tools/harness-toolset.js +3 -4
  414. package/dist/surface/tools/invoke-tool.d.ts +0 -8
  415. package/dist/surface/tools/invoke-tool.js +164 -178
  416. package/dist/surface/tools/lease-hint.d.ts +9 -0
  417. package/dist/surface/tools/lease-hint.js +22 -3
  418. package/dist/surface/tools/lease-permissions.d.ts +1 -1
  419. package/dist/surface/tools/lease-readiness.d.ts +55 -0
  420. package/dist/surface/tools/lease-readiness.js +150 -2
  421. package/dist/surface/tools/lease-tools.d.ts +3 -75
  422. package/dist/surface/tools/lease-tools.js +124 -188
  423. package/dist/surface/tools/map-tools.d.ts +20 -0
  424. package/dist/surface/tools/map-tools.js +145 -0
  425. package/dist/surface/tools/merge-tools.js +11 -7
  426. package/dist/surface/tools/next-step.js +6 -3
  427. package/dist/surface/tools/observe-tools.js +46 -35
  428. package/dist/surface/tools/platform-moment.d.ts +3 -12
  429. package/dist/surface/tools/platform-moment.js +12 -24
  430. package/dist/surface/tools/read/complete-snapshot.d.ts +7 -1
  431. package/dist/surface/tools/read/complete-snapshot.js +13 -2
  432. package/dist/surface/tools/read/query-paginate.js +6 -0
  433. package/dist/surface/tools/read/query-shape.d.ts +9 -0
  434. package/dist/surface/tools/read/query-shape.js +15 -0
  435. package/dist/surface/tools/read/snapshot-unmounted-note.d.ts +1 -0
  436. package/dist/surface/tools/read/snapshot-unmounted-note.js +73 -0
  437. package/dist/surface/tools/read-tools.js +5 -5
  438. package/dist/surface/tools/real-input-attempt.d.ts +11 -0
  439. package/dist/surface/tools/real-input-attempt.js +206 -38
  440. package/dist/surface/tools/reconcile-tools.js +21 -8
  441. package/dist/surface/tools/reticle-result.d.ts +3 -0
  442. package/dist/surface/tools/reticle-result.js +8 -1
  443. package/dist/surface/tools/run-report.d.ts +22 -0
  444. package/dist/surface/tools/run-report.js +141 -0
  445. package/dist/surface/tools/session-ports.d.ts +57 -0
  446. package/dist/surface/tools/session-ports.js +102 -0
  447. package/dist/surface/tools/tool-kit.d.ts +58 -4
  448. package/dist/surface/tools/tool-kit.js +140 -6
  449. package/dist/surface/tools/tool-surface.d.ts +2 -0
  450. package/dist/surface/tools/tool-surface.js +45 -0
  451. package/dist/surface/tools/tools.js +49 -87
  452. package/dist/telemetry/automation-hint.d.ts +5 -0
  453. package/dist/telemetry/automation-hint.js +7 -0
  454. package/dist/telemetry/cli-telemetry.d.ts +22 -0
  455. package/dist/telemetry/cli-telemetry.js +80 -11
  456. package/dist/telemetry/daemon-telemetry.d.ts +3 -1
  457. package/dist/telemetry/daemon-telemetry.js +9 -2
  458. package/dist/telemetry/feedback-cli.d.ts +1 -1
  459. package/dist/telemetry/feedback-cli.js +8 -3
  460. package/dist/telemetry/feedback.d.ts +1 -1
  461. package/dist/telemetry/feedback.js +51 -4
  462. package/dist/telemetry/harness-run.d.ts +3 -3
  463. package/dist/telemetry/harness-run.js +18 -7
  464. package/dist/telemetry/hud-events.d.ts +1 -1
  465. package/dist/telemetry/hud-metrics.d.ts +6 -3
  466. package/dist/telemetry/hud-metrics.js +20 -8
  467. package/dist/telemetry/install-source.js +1 -1
  468. package/dist/telemetry/mcp-connection.d.ts +1 -1
  469. package/dist/telemetry/mcp-connection.js +21 -2
  470. package/dist/telemetry/onboarding-firsts.d.ts +6 -1
  471. package/dist/telemetry/onboarding-firsts.js +41 -1
  472. package/dist/telemetry/proxy-telemetry.d.ts +42 -0
  473. package/dist/telemetry/proxy-telemetry.js +70 -1
  474. package/dist/telemetry/session-metrics.d.ts +1 -3
  475. package/dist/telemetry/session-metrics.js +16 -12
  476. package/dist/telemetry/telemetry.d.ts +9 -1
  477. package/dist/telemetry/telemetry.js +16 -1
  478. package/dist/telemetry/verification-of.d.ts +3 -1
  479. package/dist/telemetry/verification-of.js +7 -1
  480. package/dist/wire-journal.js +12 -2
  481. package/docs/README.md +4 -2
  482. package/docs/actions.mdx +7 -6
  483. package/docs/adapters.md +2 -1
  484. package/docs/agent-cheatsheet.md +19 -5
  485. package/docs/architecture.md +13 -10
  486. package/docs/autodrive.md +6 -5
  487. package/docs/benchmarks.md +2 -2
  488. package/docs/capabilities.mdx +1 -1
  489. package/docs/cli/affected.mdx +1 -1
  490. package/docs/cli/cloud.mdx +6 -6
  491. package/docs/cli/doctor.mdx +3 -1
  492. package/docs/cli/feedback.mdx +11 -7
  493. package/docs/cli/gate.mdx +1 -1
  494. package/docs/cli/help.mdx +1 -1
  495. package/docs/cli/init.mdx +20 -16
  496. package/docs/cli/mcp.mdx +5 -2
  497. package/docs/cli/open.mdx +5 -2
  498. package/docs/cli/report.mdx +1 -1
  499. package/docs/cli/restart.mdx +1 -1
  500. package/docs/cli/rollback.mdx +4 -4
  501. package/docs/cli/serve.mdx +7 -5
  502. package/docs/cli/setup.mdx +1 -1
  503. package/docs/cli/status.mdx +6 -2
  504. package/docs/cli/stop.mdx +3 -3
  505. package/docs/cli/telemetry.mdx +5 -1
  506. package/docs/cli/try.mdx +8 -8
  507. package/docs/cli/update.mdx +8 -5
  508. package/docs/cli/verify.mdx +12 -5
  509. package/docs/cli/version.mdx +1 -1
  510. package/docs/cli.mdx +10 -6
  511. package/docs/debugging.md +1 -1
  512. package/docs/deploy-checks.md +8 -6
  513. package/docs/desktop.mdx +14 -18
  514. package/docs/enterprise.md +6 -6
  515. package/docs/environment.mdx +5 -3
  516. package/docs/faq.mdx +9 -6
  517. package/docs/first-drive.md +19 -9
  518. package/docs/flows.md +3 -4
  519. package/docs/for-agents.md +1 -1
  520. package/docs/frameworks.mdx +34 -11
  521. package/docs/getting-started.md +46 -29
  522. package/docs/http-transport.md +2 -2
  523. package/docs/human-control.md +8 -8
  524. package/docs/index.mdx +2 -2
  525. package/docs/install-agentic.mdx +18 -19
  526. package/docs/install-manual.mdx +8 -4
  527. package/docs/integration-patterns.md +5 -5
  528. package/docs/multi-agent-testing.md +7 -5
  529. package/docs/packages/browser.mdx +34 -2
  530. package/docs/packages/core.mdx +2 -1
  531. package/docs/packages/electron.mdx +15 -3
  532. package/docs/packages/eslint-plugin.mdx +1 -1
  533. package/docs/packages/next.mdx +17 -5
  534. package/docs/packages/react.mdx +8 -1
  535. package/docs/packages/server.mdx +3 -3
  536. package/docs/packages/tauri.mdx +3 -3
  537. package/docs/packages/vite-plugin.mdx +1 -1
  538. package/docs/packages.mdx +19 -6
  539. package/docs/platform-integration.md +12 -4
  540. package/docs/predicates.mdx +18 -7
  541. package/docs/production-mode.md +108 -0
  542. package/docs/prompt-capture.md +99 -0
  543. package/docs/quickstart.mdx +14 -12
  544. package/docs/recipes.mdx +9 -8
  545. package/docs/required-checks.md +3 -2
  546. package/docs/skill-file.mdx +4 -3
  547. package/docs/skill-setup.md +2 -2
  548. package/docs/skill.md +62 -70
  549. package/docs/state-files.md +1 -0
  550. package/docs/state-management.mdx +11 -9
  551. package/docs/system-map.md +14 -13
  552. package/docs/telemetry.md +32 -24
  553. package/docs/testing.md +9 -5
  554. package/docs/tools/act-and-wait.mdx +17 -13
  555. package/docs/tools/act-sequence.mdx +40 -66
  556. package/docs/tools/act.mdx +7 -5
  557. package/docs/tools/assert.mdx +1 -1
  558. package/docs/tools/look.mdx +1 -1
  559. package/docs/tools/navigate.mdx +1 -1
  560. package/docs/tools/network.mdx +13 -11
  561. package/docs/tools/overview.mdx +3 -3
  562. package/docs/tools/query.mdx +3 -3
  563. package/docs/tools/session-and-feedback.mdx +9 -6
  564. package/docs/tools/sessions.mdx +7 -0
  565. package/docs/tools/snapshot.mdx +9 -7
  566. package/docs/tools/tools-and-run.mdx +11 -10
  567. package/docs/tools/verify.mdx +1 -1
  568. package/docs/troubleshooting.mdx +21 -9
  569. package/docs/usage.md +58 -43
  570. package/docs/use-cases.mdx +2 -2
  571. package/docs/vs-chrome-devtools-mcp.mdx +5 -5
  572. package/docs/vs-playwright-mcp.mdx +5 -4
  573. package/docs/what-is-recorded.md +12 -7
  574. package/docs/what-is-reticle.mdx +2 -2
  575. package/docs/why-reticle.mdx +1 -1
  576. package/package.json +9 -12
  577. package/dist/command/dev/stale-issue-guard.d.ts +0 -34
  578. package/dist/command/dev/stale-issue-guard.js +0 -69
@@ -6,13 +6,16 @@
6
6
  * one `reticle_context` serves, so the terminal and the agent cannot be told two different stories.
7
7
  */
8
8
  import { execFileSync } from 'node:child_process';
9
- import { existsSync, readdirSync, statSync } from 'node:fs';
9
+ import { existsSync, readFileSync, readdirSync, statSync } from 'node:fs';
10
+ import { homedir } from 'node:os';
10
11
  import { join } from 'node:path';
11
- import { DiscoveryInvite, ReticleDir } from '@reticlehq/core';
12
+ import { DiscoveryInvite, ReticleDir, asRecord } from '@reticlehq/core';
12
13
  import { gapSummary } from '../../judgement/runs/artifact/gap-summary.js';
13
14
  import { SessionJournal } from '../../memory/journal/session-journal.js';
14
15
  import { createNodeFileSystem } from '../../memory/project/fs/fs-port.js';
15
16
  import { gapHookLine, gapReportLines } from '../../judgement/runs/artifact/gap-report.js';
17
+ import { DriveOrigin, DriveStatus, pollCall } from '../../features/harness/drive-runs.js';
18
+ import { DRIVE_RECORD_SUFFIX, UNMATCHED_SUBDIR } from '../../memory/project/dir/reticle-dir.js';
16
19
  /**
17
20
  * A session last written longer ago than this is not the turn a hook is asking about.
18
21
  *
@@ -20,33 +23,99 @@ import { gapHookLine, gapReportLines } from '../../judgement/runs/artifact/gap-r
20
23
  * drive older than an hour reads as "no claim this session", which errs toward saying so.
21
24
  */
22
25
  const HOOK_WINDOW_MS = 60 * 60 * 1000;
23
- /** The session whose action ledger was written most recently, if any. */
24
- function newestSession(root) {
25
- const sessionsDir = join(root, ReticleDir.SESSIONS_SUBDIR);
26
- if (!existsSync(sessionsDir))
26
+ /**
27
+ * How long the Stop hook keeps an agent for one Harness drive. A record still `running` after this
28
+ * was left by a daemon that stopped, and it would hold the agent forever.
29
+ *
30
+ * ponytail: a fixed bound from the start time, not a liveness check on the daemon. Ask the daemon
31
+ * when a real drive runs longer than this.
32
+ */
33
+ const KEEP_ALIVE_MAX_MS = 30 * 60 * 1000;
34
+ /** What the Stop hook tells an agent that tried to stop while its Harness drive runs. */
35
+ export function keepAliveReason(runId) {
36
+ return (`The Harness drive ${runId} that you started is still running. Do not stop yet. ` +
37
+ `Call ${pollCall(runId)} until it ends. If it reports a failed check, fix the code, then ` +
38
+ `start the same drive again to verify the fix.`);
39
+ }
40
+ /** The newest drive this agent started that still runs, read from `.reticle/runs/`. */
41
+ function agentDriveRunning(root, now) {
42
+ const runs = join(root, ReticleDir.RUNS_SUBDIR);
43
+ if (!existsSync(runs))
27
44
  return undefined;
28
45
  let newest;
29
- for (const id of readdirSync(sessionsDir)) {
30
- const ledger = join(sessionsDir, id, ReticleDir.JOURNAL_ACTIONS_FILE);
31
- if (!existsSync(ledger))
46
+ for (const name of readdirSync(runs)) {
47
+ if (!name.endsWith(DRIVE_RECORD_SUFFIX))
48
+ continue;
49
+ let record;
50
+ try {
51
+ record = asRecord(JSON.parse(readFileSync(join(runs, name), 'utf8')));
52
+ }
53
+ catch {
54
+ continue;
55
+ }
56
+ const { harnessRun, status, origin, startedAt } = record;
57
+ if (DriveStatus.RUNNING !== status || DriveOrigin.AGENT !== origin)
58
+ continue;
59
+ if ('string' !== typeof harnessRun || 'number' !== typeof startedAt)
60
+ continue;
61
+ if (now - startedAt > KEEP_ALIVE_MAX_MS)
62
+ continue;
63
+ if (newest === undefined || startedAt > newest.startedAt)
64
+ newest = { runId: harnessRun, startedAt };
65
+ }
66
+ return newest?.runId;
67
+ }
68
+ /**
69
+ * Every `.reticle` root a session of this project can be in: the project's own, then each folder the
70
+ * daemon filed under `~/.reticle/unmatched` for a page it could not tie to a project (before
71
+ * `reticle init`). Without them the hook said "No claim was checked" after claims had held.
72
+ *
73
+ * ponytail: an unmatched folder is not tied to this cwd; the newest session in the window wins.
74
+ */
75
+ function sessionRoots(root, home) {
76
+ if (home === undefined)
77
+ return [root];
78
+ const unmatched = join(home, ReticleDir.ROOT, UNMATCHED_SUBDIR);
79
+ if (!existsSync(unmatched))
80
+ return [root];
81
+ return [root, ...readdirSync(unmatched).map((name) => join(unmatched, name))];
82
+ }
83
+ /** The session whose action ledger was written most recently, if any. */
84
+ function newestSession(roots) {
85
+ let newest;
86
+ for (const root of roots) {
87
+ const sessionsDir = join(root, ReticleDir.SESSIONS_SUBDIR);
88
+ if (!existsSync(sessionsDir))
32
89
  continue;
33
- const writtenAt = statSync(ledger).mtimeMs;
34
- if (newest === undefined || writtenAt > newest.writtenAt)
35
- newest = { id, writtenAt };
90
+ for (const id of readdirSync(sessionsDir)) {
91
+ const ledger = join(sessionsDir, id, ReticleDir.JOURNAL_ACTIONS_FILE);
92
+ if (!existsSync(ledger))
93
+ continue;
94
+ const writtenAt = statSync(ledger).mtimeMs;
95
+ if (newest === undefined || writtenAt > newest.writtenAt)
96
+ newest = { id, writtenAt, root };
97
+ }
36
98
  }
37
99
  return newest;
38
100
  }
39
101
  export async function reportFor(input) {
102
+ const root = join(input.cwd, ReticleDir.ROOT);
103
+ // The one case the hook blocks: the agent's own Harness drive is still running, so its result,
104
+ // and any defect it finds, would reach nobody.
105
+ const driving = true === input.hook ? agentDriveRunning(root, input.now) : undefined;
106
+ if (driving !== undefined)
107
+ return { lines: [], block: keepAliveReason(driving) };
40
108
  if (true === input.hook && !input.treeChanged)
41
109
  return { lines: [] };
42
- const root = join(input.cwd, ReticleDir.ROOT);
43
- const found = input.session === undefined ? newestSession(root) : { id: input.session, writtenAt: input.now };
110
+ const found = input.session === undefined
111
+ ? newestSession(sessionRoots(root, input.home))
112
+ : { id: input.session, writtenAt: input.now, root };
44
113
  const current = found !== undefined && (true !== input.hook || input.now - found.writtenAt <= HOOK_WINDOW_MS)
45
114
  ? found
46
115
  : undefined;
47
116
  const actions = current === undefined
48
117
  ? []
49
- : await new SessionJournal(createNodeFileSystem(), root, current.id).readActions();
118
+ : await new SessionJournal(createNodeFileSystem(), current.root, current.id).readActions();
50
119
  const gap = gapSummary(actions);
51
120
  if (true === input.hook) {
52
121
  const line = gapHookLine(gap);
@@ -66,16 +135,19 @@ function treeChanged(cwd) {
66
135
  }
67
136
  }
68
137
  /**
69
- * The command. As a hook it prints Claude Code's `systemMessage` shape and always exits 0: it is
70
- * print-only by design, so the human sees the gap and the agent is never blocked by it.
138
+ * The command. As a hook it prints Claude Code's `systemMessage` shape and always exits 0, so the
139
+ * human sees the gap. It blocks the stop in one case only: a Harness drive the agent started is still
140
+ * running, bounded by `KEEP_ALIVE_MAX_MS`.
71
141
  */
72
142
  export async function handleReport(session, hook) {
73
143
  const cwd = process.cwd();
74
144
  let lines;
145
+ let block;
75
146
  try {
76
- ({ lines } = await reportFor({
147
+ ({ lines, block } = await reportFor({
77
148
  cwd,
78
149
  now: Date.now(),
150
+ home: homedir(),
79
151
  treeChanged: hook ? treeChanged(cwd) : true,
80
152
  ...(session === undefined ? {} : { session }),
81
153
  hook,
@@ -91,6 +163,11 @@ export async function handleReport(session, hook) {
91
163
  process.exitCode = 1;
92
164
  return;
93
165
  }
166
+ // Claude Code and Codex both read this shape from a Stop hook: the agent goes on, told `reason`.
167
+ if (block !== undefined) {
168
+ process.stdout.write(`${JSON.stringify({ decision: 'block', reason: block })}\n`);
169
+ return;
170
+ }
94
171
  if (0 === lines.length)
95
172
  return;
96
173
  process.stdout.write(hook ? `${JSON.stringify({ systemMessage: lines.join('\n') })}\n` : `${lines.join('\n')}\n`);
@@ -1,6 +1,6 @@
1
1
  /**
2
- * The two optional blocks `status` adds to its payload, out of cli.ts because that file hit the
3
- * 1000-line cap and the rule is to split rather than raise it.
2
+ * `reticle status`: what it reads and reports, and the two optional blocks it adds to its payload.
3
+ * Out of cli.ts because that file hit the 1000-line cap and the rule is to split rather than raise it.
4
4
  *
5
5
  * They belong together: both answer "is there anything else the reader needs to know", both are
6
6
  * absent when the answer is no, and both are the reason a healthy `status` reads as healthy.
@@ -26,3 +26,10 @@ export declare function withNextAction(facts: {
26
26
  export declare function splitBrainFields(port: number, projectId: string | undefined): {
27
27
  splitBrain?: string;
28
28
  };
29
+ /**
30
+ * Report status to the terminal. `--json` writes one structured line to STDOUT so it can be piped
31
+ * into `jq`; the human-readable block goes to stdout too. `log()` stays on stderr (the MCP
32
+ * transport lives on stdout), so `--json` must not go through it.
33
+ */
34
+ export declare function reportStatus(fields: Record<string, unknown>, json: boolean): void;
35
+ export declare function handleStatus(port: number, json?: boolean): Promise<void>;
@@ -1,10 +1,22 @@
1
1
  import { statusNextAction } from './answers/status-next-action.js';
2
2
  import { daemonsServingProjectElsewhere, resolveDaemonForProject, splitBrainNote, wrongDaemonNote, } from '../daemon/daemon-resolve.js';
3
- import { isAlive, reticleStateHome } from '../daemon/daemon.js';
4
- import { hasProjectConnectedBefore } from '../../memory/recall/prior/connection-memory.js';
3
+ import { isAlive, readPid, reticleStateHome } from '../daemon/daemon.js';
4
+ import { hasAnyAppConnectedBefore, hasProjectConnectedBefore, } from '../../memory/recall/prior/connection-memory.js';
5
+ import { devServersForProject } from '@reticlehq/core';
6
+ import { readDevServers } from '../daemon/dev-servers.js';
7
+ import { attachStatusFields } from '../../surface/mcp/attach-memory.js';
8
+ import { probeDaemon } from '../../surface/mcp/mcp-proxy.js';
9
+ import { availableUpdate } from '../update/update-nudge.js';
10
+ import { fetchStatus } from '../daemon/binding/daemon-status-probe.js';
11
+ import { PortPresence, probePresence, presenceIsUsable, describePresence, } from '../daemon/binding/port-presence.js';
12
+ import { summarizeStatus } from './launch/cli-launch.js';
13
+ import { readProjectId } from './ports/resolve/cli-port.js';
14
+ import { accountStatusFields } from './cloud-cli.js';
15
+ import { localLinkOf, workspaceAppLinks } from './status/workspace-links.js';
16
+ import { statusLines } from './status/status-lines.js';
5
17
  /**
6
- * The two optional blocks `status` adds to its payload, out of cli.ts because that file hit the
7
- * 1000-line cap and the rule is to split rather than raise it.
18
+ * `reticle status`: what it reads and reports, and the two optional blocks it adds to its payload.
19
+ * Out of cli.ts because that file hit the 1000-line cap and the rule is to split rather than raise it.
8
20
  *
9
21
  * They belong together: both answer "is there anything else the reader needs to know", both are
10
22
  * absent when the answer is no, and both are the reason a healthy `status` reads as healthy.
@@ -27,3 +39,135 @@ export function splitBrainFields(port, projectId) {
27
39
  const note = elsewhere ?? wrongDaemonNote(port, resolveDaemonForProject(projectId, home, isAlive));
28
40
  return note === undefined ? {} : { splitBrain: note };
29
41
  }
42
+ /**
43
+ * Report status to the terminal. `--json` writes one structured line to STDOUT so it can be piped
44
+ * into `jq`; the human-readable block goes to stdout too. `log()` stays on stderr (the MCP
45
+ * transport lives on stdout), so `--json` must not go through it.
46
+ */
47
+ export function reportStatus(fields, json) {
48
+ if (json) {
49
+ const line = JSON.stringify({
50
+ t: new Date().toISOString(),
51
+ event: 'reticle_status',
52
+ ...fields,
53
+ });
54
+ process.stdout.write(`${line}\n`);
55
+ return;
56
+ }
57
+ process.stdout.write(`${statusLines(fields).join('\n')}\n`);
58
+ }
59
+ export async function handleStatus(port, json = false) {
60
+ // A broken session file must not cost the reader the rest of the status.
61
+ const account = await accountStatusFields().catch(() => ({}));
62
+ // At a workspace root that is no app of its own, each app and its link: "not linked" named none.
63
+ const linked = account.linkedProject;
64
+ if ('string' !== typeof linked && readProjectId(process.cwd()) === undefined) {
65
+ Object.assign(account, {
66
+ workspaceApps: await workspaceAppLinks(process.cwd(), localLinkOf).catch(() => []),
67
+ });
68
+ }
69
+ const report = (fields) => reportStatus({ ...fields, ...account }, json);
70
+ const pid = readPid(port);
71
+ // Durable, so it survives the daemon idling out — which is the state `status` is most often run in.
72
+ const projectId = readProjectId(process.cwd());
73
+ const previouslyConnected = hasAnyAppConnectedBefore(reticleStateHome(), port, projectId);
74
+ // The narrow twin. Every sentence that says "this project", and the decision about whether THIS
75
+ // app is instrumented, needs the question the wide one cannot answer without a project id.
76
+ const projectPreviouslyConnected = hasProjectConnectedBefore(reticleStateHome(), port, projectId);
77
+ // Whether `init` has run HERE. Registering the MCP server does not wire the app, and more than one
78
+ // path does the first without the second — so this is the commonest reason `status` has nothing to
79
+ // report, and it was not among the facts this command could state.
80
+ const initialized = projectId !== undefined;
81
+ // The OTHER half of the install, and the half this command could not see. A host that registers
82
+ // Reticle and never lists its tools looks exactly like an abandoned install from here — same idle
83
+ // daemon, same zero sessions — and the user sees a tool that does nothing. See attach-memory.ts.
84
+ const client = attachStatusFields(reticleStateHome(), port);
85
+ // What the dev servers themselves said. The reason this command could previously only guess at
86
+ // whether the app was running is that it had no way to see one; now the ones carrying Reticle
87
+ // announce, and the advice below stops contradicting the terminal the reader is looking at.
88
+ // Scoped to THIS project: the registry is machine-wide, and an unrelated app's dev server must
89
+ // not make this project look like it is running.
90
+ const devServerPorts = devServersForProject(readDevServers(reticleStateHome()), {
91
+ projectId,
92
+ root: process.cwd(),
93
+ }).map((d) => d.port);
94
+ // The failure where every individual check is green and the chain is broken: the agent's proxy and
95
+ // the app resolved their ports independently and landed on two different daemons. Reported from
96
+ // BOTH stances, because neither one can see it alone.
97
+ const split = splitBrainFields(port, projectId);
98
+ // Doctor and status must answer the same liveness question. A live pid only says that some
99
+ // process exists; a Reticle daemon is running only when the shared port probe reaches /status.
100
+ const presence = await probePresence(port, { tcpOpen: probeDaemon, status: fetchStatus });
101
+ if (!presenceIsUsable(presence)) {
102
+ report({
103
+ port,
104
+ running: false,
105
+ presence,
106
+ ...(presence === PortPresence.FOREIGN ? { reason: describePresence(presence, port) } : {}),
107
+ // `init` promises this command says why the app has not connected. Without it the answer was
108
+ // `running: false` and nothing else, which reads as "Reticle is broken" for what is usually
109
+ // just a daemon that has not been asked to do anything yet.
110
+ ...withNextAction({
111
+ running: false,
112
+ sessionCount: 0,
113
+ previouslyConnected,
114
+ projectPreviouslyConnected,
115
+ initialized,
116
+ devServerPorts,
117
+ }),
118
+ ...client,
119
+ ...split,
120
+ });
121
+ return;
122
+ }
123
+ // The daemon answered the same probe doctor trusts — ask it for live sessions + health.
124
+ const payload = await fetchStatus(port);
125
+ // `status` is the second-most-run command and the one a HUMAN types. The update nudge otherwise
126
+ // only rides a tool result, which the majority of daemons never produce — so the people most in
127
+ // need of an upgrade were the ones with no path to hearing about it.
128
+ const update = availableUpdate();
129
+ const nudge = update === undefined ? {} : { updateAvailable: update };
130
+ if (payload === undefined) {
131
+ report({
132
+ port,
133
+ running: true,
134
+ pid,
135
+ ...nudge,
136
+ ...withNextAction({
137
+ running: true,
138
+ sessionCount: 0,
139
+ previouslyConnected,
140
+ projectPreviouslyConnected,
141
+ initialized,
142
+ devServerPorts,
143
+ }),
144
+ ...client,
145
+ ...split,
146
+ });
147
+ return;
148
+ }
149
+ const summary = summarizeStatus(payload);
150
+ // Only when the daemon did NOT already explain itself. It has the whole diagnosis in-process and
151
+ // puts it on the wire as `why`; printing a second, thinner opinion beside it risks two confident
152
+ // answers pointing different ways, which is worse than one.
153
+ const next = summary.why === undefined
154
+ ? withNextAction({
155
+ running: true,
156
+ ...summary,
157
+ previouslyConnected,
158
+ projectPreviouslyConnected,
159
+ initialized,
160
+ devServerPorts,
161
+ })
162
+ : {};
163
+ report({
164
+ port,
165
+ running: true,
166
+ pid,
167
+ ...summary,
168
+ ...next,
169
+ ...client,
170
+ ...split,
171
+ ...nudge,
172
+ });
173
+ }
@@ -1,6 +1,6 @@
1
1
  import type { CloudConfig } from '../../memory/cloud/cloud-sync.js';
2
2
  import { type FreeDrive } from '../../features/harness/platform/platform-drives.js';
3
- export declare const MSG_SIGN_IN_FIRST = "Sign in first: reticle connect (it is free, no card)";
3
+ export declare const MSG_SIGN_IN_FIRST = "Link this folder first: reticle connect. It signs you in if you are not, and it is free, no card.";
4
4
  /** The whole drive, model turns and browser included, before the CLI stops waiting for it. */
5
5
  export declare const TRY_BUDGET_MS = 120000;
6
6
  /** Model turns in the one free drive. Bounds what it costs, not what it may find. */
@@ -53,8 +53,7 @@ export declare function cmdTry(argv: readonly string[], cloudCommands: TryCloud)
53
53
  /**
54
54
  * How `init` ends once the connection is proved: what Reticle sees of the app, what it is missing,
55
55
  * and the prompt that hands the rest to the coding agent, which proves the first flow. `init` never
56
- * drives: the Harness is opt-in and unlocks at a coverage score (core's `instrumentation-coverage.ts`), and a
57
- * freshly wired app is rarely there yet.
56
+ * drives: the Harness is opt-in. It runs at any setup score.
58
57
  *
59
58
  * Read from the daemon's `/status`, the same coverage `doctor` prints, so the two never disagree.
60
59
  */
@@ -64,7 +63,7 @@ export declare const UNLINKED_PITCH: string[];
64
63
  export declare const msgProveOneFlow: (url: string) => string;
65
64
  /**
66
65
  * The closing lines for one tab's coverage, as `/status` reports it: the score, what is missing, the
67
- * Harness gate in its own sentence, and the prompt for the coding agent. Pure.
66
+ * Harness switch, and the prompt for the coding agent. Pure.
68
67
  */
69
68
  export declare function initCoverageLines(tab: Record<string, unknown> | undefined, url: string): string[];
70
69
  /**
@@ -27,7 +27,7 @@ import { callerArtifactRoot } from '../../memory/project/link-directory.js';
27
27
  import { seeRunLine } from '../../memory/project/sync-status.js';
28
28
  import { DAEMON_INNER_COMMAND, PORT_FLAG } from './cli-parse.js';
29
29
  import { acquireLease, connectOverSse, endpointFor, exploreToEnd, refusalText, releaseLease, verdictOf, } from './adhoc-verdict.js';
30
- export const MSG_SIGN_IN_FIRST = 'Sign in first: reticle connect (it is free, no card)';
30
+ export const MSG_SIGN_IN_FIRST = 'Link this folder first: reticle connect. It signs you in if you are not, and it is free, no card.';
31
31
  const PERSONA_FLAG = '--persona';
32
32
  /** The whole drive, model turns and browser included, before the CLI stops waiting for it. */
33
33
  export const TRY_BUDGET_MS = 120_000;
@@ -263,15 +263,14 @@ export async function cmdTry(argv, cloudCommands) {
263
263
  /**
264
264
  * How `init` ends once the connection is proved: what Reticle sees of the app, what it is missing,
265
265
  * and the prompt that hands the rest to the coding agent, which proves the first flow. `init` never
266
- * drives: the Harness is opt-in and unlocks at a coverage score (core's `instrumentation-coverage.ts`), and a
267
- * freshly wired app is rarely there yet.
266
+ * drives: the Harness is opt-in. It runs at any setup score.
268
267
  *
269
268
  * Read from the daemon's `/status`, the same coverage `doctor` prints, so the two never disagree.
270
269
  */
271
270
  /** What a project that is not linked is told, once, at the end. */
272
271
  export const UNLINKED_PITCH = [
273
272
  'Results stay on this machine. `reticle connect` saves them to your dashboard and lets Reticle',
274
- 'Harness test the whole app: a new account gets 10 free credits.',
273
+ 'Harness test the whole app: a new account gets free credits to start.',
275
274
  ];
276
275
  /** Prove one flow with the coding agent: the line every ending names. */
277
276
  export const msgProveOneFlow = (url) => `Then ask your coding agent: "Use Reticle to prove one flow in ${url}: drive it, and end with ` +
@@ -286,25 +285,21 @@ const names = (value) => Array.isArray(value)
286
285
  : [];
287
286
  /**
288
287
  * The closing lines for one tab's coverage, as `/status` reports it: the score, what is missing, the
289
- * Harness gate in its own sentence, and the prompt for the coding agent. Pure.
288
+ * Harness switch, and the prompt for the coding agent. Pure.
290
289
  */
291
290
  export function initCoverageLines(tab, url) {
292
- const gate = asRecord(tab?.['harnessGate']);
293
- const percent = gate['percent'];
291
+ const percent = tab?.['setupScore'];
294
292
  if (tab === undefined || 'number' !== typeof percent)
295
293
  return [
296
294
  'Instrumentation is measured on an open tab of the app: run `reticle doctor` with it open.',
297
295
  msgProveOneFlow(url),
298
296
  ];
299
297
  const unseen = [...names(tab['missing']), ...names(tab['notSeenYet'])];
300
- const reason = gate['reason'];
301
298
  const prompt = tab['prompt'];
302
299
  return [
303
300
  `Instrumentation: ${String(percent)}%` +
304
301
  (0 === unseen.length ? '' : ` — missing: ${unseen.join(', ')}`),
305
- 'string' === typeof reason
306
- ? reason
307
- : `Harness can be switched on: it is off until you switch it on in the HUD's Settings.`,
302
+ `Harness can be switched on: it is off until you switch it on in the HUD's Settings.`,
308
303
  ...('string' === typeof prompt
309
304
  ? [
310
305
  'Paste this into your coding agent; it closes the gaps and proves the first flow:',
@@ -9,11 +9,14 @@ import { Verified, type ReticleVerificationRun } from '@reticlehq/core';
9
9
  type JourneyVerdict = typeof Verified.YES | typeof Verified.NO | typeof Verified.UNKNOWN;
10
10
  export interface VerifyResults {
11
11
  verdict: JourneyVerdict;
12
+ /** `runId` is the run the journey came from, set only when that run reached the platform. */
12
13
  results: {
13
14
  journey: string;
14
15
  verdict: JourneyVerdict;
15
16
  reason?: string;
17
+ runId?: string;
16
18
  }[];
17
19
  }
18
- export declare function verifyResults(run: ReticleVerificationRun): VerifyResults;
20
+ /** `pushed`: the run reached the platform, so its id resolves there and the results name it. */
21
+ export declare function verifyResults(run: ReticleVerificationRun, pushed?: boolean): VerifyResults;
19
22
  export {};
@@ -14,11 +14,13 @@ function journeyVerdict(status) {
14
14
  return Verified.YES;
15
15
  return Verified.UNKNOWN;
16
16
  }
17
- export function verifyResults(run) {
17
+ /** `pushed`: the run reached the platform, so its id resolves there and the results name it. */
18
+ export function verifyResults(run, pushed = false) {
18
19
  const results = run.flows.map((flow) => ({
19
20
  journey: flow.name,
20
21
  verdict: journeyVerdict(flow.status),
21
22
  ...(flow.failureReason === undefined ? {} : { reason: flow.failureReason }),
23
+ ...(pushed ? { runId: run.runId } : {}),
22
24
  }));
23
25
  const verdict = results.some((r) => Verified.NO === r.verdict)
24
26
  ? Verified.NO
@@ -1,4 +1,5 @@
1
1
  #!/usr/bin/env node
2
+ export { handleStatus, reportStatus } from './cli/status-fields.js';
2
3
  import { parseCliArgs, CLI_USAGE } from './cli/cli-parse.js';
3
4
  export { parseCliArgs, CLI_USAGE };
4
5
  export type { CliResult } from './cli/cli-parse.js';
@@ -16,11 +17,4 @@ export declare function connectExit(cloudCode: number, initUnfinished: string |
16
17
  code: number;
17
18
  note?: string;
18
19
  };
19
- /**
20
- * Report status to the terminal. `--json` writes one structured line to STDOUT so it can be piped
21
- * into `jq`; the human-readable block goes to stdout too. `log()` stays on stderr (the MCP
22
- * transport lives on stdout), so `--json` must not go through it.
23
- */
24
- export declare function reportStatus(fields: Record<string, unknown>, json: boolean): void;
25
- export declare function handleStatus(port: number, json?: boolean): Promise<void>;
26
20
  export declare function main(): void;