@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
@@ -0,0 +1,23 @@
1
+ /**
2
+ * The agent link row of `reticle doctor`, as one pure decision (reticlehq/reticle#1710).
3
+ *
4
+ * The row used to be built inline from the attach record alone: once a client had attached,
5
+ * enumerated and called, it stayed green forever, and a client that had started but never listed
6
+ * was told to restart the client. Both answers are wrong when the port is held but `/status`
7
+ * does not answer: the record cannot say whether the link works now, and the daemon row above
8
+ * already names the one fix for the held port. So in that state this row only points back at
9
+ * the daemon row. It never prints a second command, and it never says "the daemon", because
10
+ * this state also covers a port held by a different program.
11
+ *
12
+ * The record and action strings below are copied verbatim from the inline row this replaces;
13
+ * this module changes their priority, not their words.
14
+ */
15
+ export interface AgentLinkInput {
16
+ /** The split-brain sentence, when this project is served by another daemon. */
17
+ split: string | undefined;
18
+ /** The attach-record action, or undefined when the record says the link worked. */
19
+ attachAction: string | undefined;
20
+ /** True when the port is held but `/status` does not answer. */
21
+ foreign: boolean;
22
+ }
23
+ export declare function agentLinkText(input: AgentLinkInput): string;
@@ -0,0 +1,28 @@
1
+ /**
2
+ * The agent link row of `reticle doctor`, as one pure decision (reticlehq/reticle#1710).
3
+ *
4
+ * The row used to be built inline from the attach record alone: once a client had attached,
5
+ * enumerated and called, it stayed green forever, and a client that had started but never listed
6
+ * was told to restart the client. Both answers are wrong when the port is held but `/status`
7
+ * does not answer: the record cannot say whether the link works now, and the daemon row above
8
+ * already names the one fix for the held port. So in that state this row only points back at
9
+ * the daemon row. It never prints a second command, and it never says "the daemon", because
10
+ * this state also covers a port held by a different program.
11
+ *
12
+ * The record and action strings below are copied verbatim from the inline row this replaces;
13
+ * this module changes their priority, not their words.
14
+ */
15
+ /** The healthy-record sentence, word for word as doctor printed it before. */
16
+ const RECORD_HEALTHY = '✓ an MCP client attached here and called tools before (a record, not a live check)';
17
+ export function agentLinkText(input) {
18
+ if (input.split !== undefined) {
19
+ return `✗ ${input.split}`;
20
+ }
21
+ if (input.foreign) {
22
+ return '✗ the agent link is not checked live here — follow the daemon row above.';
23
+ }
24
+ if (input.attachAction === undefined) {
25
+ return RECORD_HEALTHY;
26
+ }
27
+ return `✗ ${input.attachAction}`;
28
+ }
@@ -36,12 +36,6 @@ export function coverageLines(status) {
36
36
  ...tab.prompt.split('\n').map((line) => ` ${line}`),
37
37
  ]
38
38
  : [];
39
- const gate = tab.harnessGate;
40
- const reason = 'object' === typeof gate && null !== gate
41
- ? gate['reason']
42
- : undefined;
43
- // The Harness gate, in the sentence a refused drive says.
44
- const locked = 'string' === typeof reason ? [` ${reason}`] : [];
45
- return [doctorRow(DoctorRow.COVERAGE, parts.join(' — ')), ...locked, ...prompt];
39
+ return [doctorRow(DoctorRow.COVERAGE, parts.join(' — ')), ...prompt];
46
40
  });
47
41
  }
@@ -64,6 +64,10 @@ export declare const DoctorRow: {
64
64
  readonly COVERAGE: "coverage";
65
65
  /** A project folder holding runs the platform never got. Only when there is one. */
66
66
  readonly UNSYNCED: "unsynced";
67
+ /** Per agent: does its prompt hook hand prompts to Reticle, or do the MCP instructions. */
68
+ readonly PROMPTS: "prompts";
69
+ /** The daemon's background sync for this project: on or off, why, and the last push. */
70
+ readonly SYNC: "sync";
67
71
  };
68
72
  type DoctorRowLabel = (typeof DoctorRow)[keyof typeof DoctorRow];
69
73
  export declare const DOCTOR_ROW_LABELS: readonly DoctorRowLabel[];
@@ -64,6 +64,10 @@ export const DoctorRow = {
64
64
  COVERAGE: 'coverage',
65
65
  /** A project folder holding runs the platform never got. Only when there is one. */
66
66
  UNSYNCED: 'unsynced',
67
+ /** Per agent: does its prompt hook hand prompts to Reticle, or do the MCP instructions. */
68
+ PROMPTS: 'prompts',
69
+ /** The daemon's background sync for this project: on or off, why, and the last push. */
70
+ SYNC: 'sync',
67
71
  };
68
72
  export const DOCTOR_ROW_LABELS = Object.values(DoctorRow);
69
73
  /** Indent every row carries, before the label. */
@@ -74,6 +74,11 @@ export declare function readAttachResponse(port: number, url: string, res: {
74
74
  status: number;
75
75
  body: string;
76
76
  }): DriveAttachResult;
77
+ /** The drive request got no answer in time: the daemon is up and busy, which is not a shutdown. */
78
+ export declare class DriveRequestTimeout extends Error {
79
+ readonly ms: number;
80
+ constructor(ms: number);
81
+ }
77
82
  /** Ask the daemon on `port` to open a driveable browser at `url`. */
78
83
  export declare function requestDriveSession(port: number, url: string, post?: DrivePost): Promise<DriveAttachResult>;
79
84
  /** Which app the attached page says it is, beside the project this directory names. */
@@ -117,6 +117,15 @@ function parseJson(body) {
117
117
  return undefined;
118
118
  }
119
119
  }
120
+ /** The drive request got no answer in time: the daemon is up and busy, which is not a shutdown. */
121
+ export class DriveRequestTimeout extends Error {
122
+ ms;
123
+ constructor(ms) {
124
+ super(`no answer within ${String(ms)}ms`);
125
+ this.ms = ms;
126
+ this.name = 'DriveRequestTimeout';
127
+ }
128
+ }
120
129
  /** Ask the daemon on `port` to open a driveable browser at `url`. */
121
130
  export async function requestDriveSession(port, url, post = postJson) {
122
131
  let res;
@@ -124,6 +133,17 @@ export async function requestDriveSession(port, url, post = postJson) {
124
133
  res = await post(port, DRIVE_PATH, JSON.stringify({ url }));
125
134
  }
126
135
  catch (error) {
136
+ // A timeout is not a shutdown (#1535). The daemon took the request and said nothing for the
137
+ // whole window, so it is alive and busy: telling the user it stopped sends them to restart a
138
+ // healthy daemon, and an agent into a retry loop that hits the same wait.
139
+ if (error instanceof DriveRequestTimeout) {
140
+ return {
141
+ ok: false,
142
+ reason: `the Reticle daemon on :${String(port)} took the drive request but gave no answer within ` +
143
+ `${String(error.ms / 1000)}s. It is running; a cold browser launch can take this long. ` +
144
+ 'Check `reticle status`, then retry.',
145
+ };
146
+ }
127
147
  // The daemon answered /status a moment ago and is gone now — a shutdown, a crash, a `stop` from
128
148
  // another terminal. Retrying is the whole answer, and it is the one thing an errno never says.
129
149
  const message = error instanceof Error ? error.message : String(error);
@@ -281,7 +301,7 @@ function postJson(port, path, body) {
281
301
  req.on('error', reject);
282
302
  req.on('timeout', () => {
283
303
  req.destroy();
284
- reject(new Error(`no answer within ${String(DRIVE_REQUEST_TIMEOUT_MS)}ms`));
304
+ reject(new DriveRequestTimeout(DRIVE_REQUEST_TIMEOUT_MS));
285
305
  });
286
306
  req.end(body);
287
307
  });
@@ -0,0 +1,20 @@
1
+ export declare const CODEX_AGENT = "codex";
2
+ /** The `source` of a record imported from Codex's transcript rather than handed over by a hook. */
3
+ export declare const CODEX_TRANSCRIPT_SOURCE = "codex-transcript";
4
+ export declare const WEB_SEARCH_TOOL = "web_search";
5
+ type Json = Record<string, unknown>;
6
+ /** Codex's home: `$CODEX_HOME`, else `~/.codex`. */
7
+ export declare function codexHome(env: NodeJS.ProcessEnv): string;
8
+ /**
9
+ * The session's transcript: the payload's `transcript_path`, else the rollout file under
10
+ * `<codexHome>/sessions/` whose name ends with the session id.
11
+ * ponytail: walks every dated folder; a home with years of sessions would want the newest first.
12
+ */
13
+ export declare function codexTranscriptPath(payload: Json, home: string): string | undefined;
14
+ /** The web searches in a transcript's text, oldest first. */
15
+ export declare function codexWebSearches(transcript: string, session: string, base: string): Json[];
16
+ /** The searches not yet in `sessionFile`, by their `toolUseId`. */
17
+ export declare function newCodexSearches(searches: readonly Json[], sessionFile: string): Json[];
18
+ /** The transcript's text, or undefined when it is missing or too large to read now. */
19
+ export declare function readTranscript(path: string): string | undefined;
20
+ export {};
@@ -0,0 +1,224 @@
1
+ /**
2
+ * Codex's web search, imported from Codex's own session transcript.
3
+ *
4
+ * Codex's `web_search` is a hosted tool: it never reaches PostToolUse (stated in the Codex hooks
5
+ * docs, and seen live on 2026-10-19). Codex does write it to its session transcript, which every
6
+ * hook payload names in `transcript_path` (else `$CODEX_HOME/sessions/**` holds it, named by the
7
+ * session id). So any Codex hook that fires (a tool call, the turn's Stop) reads that file and
8
+ * appends each search it has not kept yet to the same `agent-<session>.jsonl`, as an `agent_tool`
9
+ * record with `tool: "web_search"`.
10
+ *
11
+ * Two shapes, both read from real transcripts on this machine (structure only):
12
+ * - Codex 0.160.0: `event_msg` → `item_completed` whose `item` is `{ type: "Extension",
13
+ * kind: "web.search", id, query, action, results[] }`, with `started_at_ms`/`completed_at_ms`.
14
+ * - Older builds: `response_item` → `web_search_call` `{ status, action }`: no result, no id, and
15
+ * the line's `timestamp` is the only time.
16
+ *
17
+ * Idempotent: a search is keyed by its item id, else by its line number (the transcript is
18
+ * append-only), and a key already in the session file is skipped. Read-only on Codex's files.
19
+ */
20
+ import { closeSync, fstatSync, openSync, readFileSync, readdirSync } from 'node:fs';
21
+ import { homedir } from 'node:os';
22
+ import { join } from 'node:path';
23
+ import { redactSecrets } from '../../../memory/intent/record-request.js';
24
+ import { AgentRecordKind, EPISODE_FILE_VERSION } from '../../../memory/journal/episode-log.js';
25
+ export const CODEX_AGENT = 'codex';
26
+ /** The `source` of a record imported from Codex's transcript rather than handed over by a hook. */
27
+ export const CODEX_TRANSCRIPT_SOURCE = 'codex-transcript';
28
+ export const WEB_SEARCH_TOOL = 'web_search';
29
+ const CODEX_HOME_ENV = 'CODEX_HOME';
30
+ const CODEX_DIR = '.codex';
31
+ const SESSIONS_DIR = 'sessions';
32
+ const ITEM_COMPLETED = 'item_completed';
33
+ const EXTENSION_ITEM = 'Extension';
34
+ const WEB_SEARCH_KIND = 'web.search';
35
+ const WEB_SEARCH_CALL = 'web_search_call';
36
+ const RESPONSE_ITEM = 'response_item';
37
+ const FAILED = 'failed';
38
+ /** A result keeps this many characters, as the hook's own records do. */
39
+ const MAX_RESULT_TEXT = 4_000;
40
+ const MAX_ARG_TEXT = 2_000;
41
+ /** Codex's transcript holds the whole session. Past this size it is not read on a hook's time. */
42
+ const MAX_TRANSCRIPT_BYTES = 64 * 1024 * 1024;
43
+ const isObject = (value) => 'object' === typeof value && null !== value && !Array.isArray(value);
44
+ const text = (value) => 'string' === typeof value && 0 < value.length ? value : undefined;
45
+ /** Codex's home: `$CODEX_HOME`, else `~/.codex`. */
46
+ export function codexHome(env) {
47
+ return text(env[CODEX_HOME_ENV]) ?? join(homedir(), CODEX_DIR);
48
+ }
49
+ /**
50
+ * The session's transcript: the payload's `transcript_path`, else the rollout file under
51
+ * `<codexHome>/sessions/` whose name ends with the session id.
52
+ * ponytail: walks every dated folder; a home with years of sessions would want the newest first.
53
+ */
54
+ export function codexTranscriptPath(payload, home) {
55
+ const given = text(payload['transcript_path']);
56
+ if (given !== undefined) {
57
+ return given;
58
+ }
59
+ const session = text(payload['session_id']);
60
+ if (session === undefined) {
61
+ return undefined;
62
+ }
63
+ const suffix = `-${session}.jsonl`;
64
+ const walk = (dir) => {
65
+ let entries;
66
+ try {
67
+ entries = readdirSync(dir, { withFileTypes: true });
68
+ }
69
+ catch {
70
+ return undefined;
71
+ }
72
+ for (const entry of entries) {
73
+ const path = join(dir, entry.name);
74
+ if (entry.isFile() && entry.name.endsWith(suffix)) {
75
+ return path;
76
+ }
77
+ if (entry.isDirectory()) {
78
+ const found = walk(path);
79
+ if (found !== undefined) {
80
+ return found;
81
+ }
82
+ }
83
+ }
84
+ return undefined;
85
+ };
86
+ return walk(join(home, SESSIONS_DIR));
87
+ }
88
+ /** Every string redacted and cut, project paths made relative, as the hook's own args are. */
89
+ function clean(value, base) {
90
+ if ('string' === typeof value) {
91
+ return redactSecrets(value.split(`${base}/`).join(''), MAX_ARG_TEXT);
92
+ }
93
+ if (Array.isArray(value)) {
94
+ return value.map((item) => clean(item, base));
95
+ }
96
+ if (!isObject(value)) {
97
+ return value;
98
+ }
99
+ return Object.fromEntries(Object.entries(value)
100
+ .filter(([, v]) => null !== v && v !== undefined)
101
+ .map(([k, v]) => [k, clean(v, base)]));
102
+ }
103
+ /** One web search as an `agent_tool` record, or undefined when the line is not one. */
104
+ function searchFrom(line, lineNo, session, base) {
105
+ const payload = isObject(line['payload']) ? line['payload'] : undefined;
106
+ if (payload === undefined) {
107
+ return undefined;
108
+ }
109
+ const who = {
110
+ v: EPISODE_FILE_VERSION,
111
+ agent: CODEX_AGENT,
112
+ agentSession: session,
113
+ kind: AgentRecordKind.TOOL,
114
+ source: CODEX_TRANSCRIPT_SOURCE,
115
+ tool: WEB_SEARCH_TOOL,
116
+ };
117
+ const item = isObject(payload['item']) ? payload['item'] : undefined;
118
+ if (ITEM_COMPLETED === payload['type'] &&
119
+ item !== undefined &&
120
+ EXTENSION_ITEM === item['type'] &&
121
+ WEB_SEARCH_KIND === item['kind']) {
122
+ const started = payload['started_at_ms'];
123
+ const ended = payload['completed_at_ms'];
124
+ const action = isObject(item['action']) ? item['action'] : { query: item['query'] };
125
+ const results = item['results'];
126
+ const full = results === undefined ? undefined : JSON.stringify(results);
127
+ return {
128
+ ...who,
129
+ toolUseId: text(item['id']) ?? `L${String(lineNo)}`,
130
+ args: clean(action, base),
131
+ ok: true,
132
+ ...(full === undefined
133
+ ? {}
134
+ : {
135
+ result: {
136
+ head: redactSecrets(full, MAX_RESULT_TEXT),
137
+ chars: full.length,
138
+ truncated: full.length > MAX_RESULT_TEXT,
139
+ },
140
+ }),
141
+ ...('number' === typeof started ? { startedAt: started } : {}),
142
+ ...('number' === typeof ended ? { endedAt: ended } : {}),
143
+ ...('number' === typeof started && 'number' === typeof ended
144
+ ? { durationMs: ended - started }
145
+ : {}),
146
+ };
147
+ }
148
+ if (RESPONSE_ITEM === line['type'] && WEB_SEARCH_CALL === payload['type']) {
149
+ const at = Date.parse(String(line['timestamp']));
150
+ return {
151
+ ...who,
152
+ toolUseId: text(payload['id']) ?? `L${String(lineNo)}`,
153
+ args: clean(isObject(payload['action']) ? payload['action'] : {}, base),
154
+ ok: FAILED !== payload['status'],
155
+ ...(Number.isFinite(at) ? { endedAt: at } : {}),
156
+ };
157
+ }
158
+ return undefined;
159
+ }
160
+ /** The web searches in a transcript's text, oldest first. */
161
+ export function codexWebSearches(transcript, session, base) {
162
+ return transcript.split('\n').flatMap((raw, index) => {
163
+ if (!raw.includes(WEB_SEARCH_KIND) && !raw.includes(WEB_SEARCH_CALL)) {
164
+ return [];
165
+ }
166
+ try {
167
+ const line = JSON.parse(raw);
168
+ const record = isObject(line) ? searchFrom(line, index + 1, session, base) : undefined;
169
+ return record === undefined ? [] : [record];
170
+ }
171
+ catch {
172
+ return [];
173
+ }
174
+ });
175
+ }
176
+ /** The searches not yet in `sessionFile`, by their `toolUseId`. */
177
+ export function newCodexSearches(searches, sessionFile) {
178
+ if (0 === searches.length) {
179
+ return [];
180
+ }
181
+ const kept = new Set();
182
+ let text = '';
183
+ try {
184
+ text = readFileSync(sessionFile, 'utf8');
185
+ }
186
+ catch {
187
+ // No session file yet: nothing is kept.
188
+ }
189
+ for (const raw of text.split('\n')) {
190
+ if (!raw.includes(CODEX_TRANSCRIPT_SOURCE)) {
191
+ continue;
192
+ }
193
+ try {
194
+ const line = JSON.parse(raw);
195
+ if (isObject(line)) {
196
+ kept.add(line['toolUseId']);
197
+ }
198
+ }
199
+ catch {
200
+ // A torn line names nothing.
201
+ }
202
+ }
203
+ return searches.filter((s) => !kept.has(s['toolUseId']));
204
+ }
205
+ /** The transcript's text, or undefined when it is missing or too large to read now. */
206
+ export function readTranscript(path) {
207
+ let fd;
208
+ try {
209
+ fd = openSync(path, 'r');
210
+ }
211
+ catch {
212
+ return undefined;
213
+ }
214
+ // One open file for the size and the read, so the file cannot change between the two.
215
+ try {
216
+ return fstatSync(fd).size > MAX_TRANSCRIPT_BYTES ? undefined : readFileSync(fd, 'utf8');
217
+ }
218
+ catch {
219
+ return undefined;
220
+ }
221
+ finally {
222
+ closeSync(fd);
223
+ }
224
+ }
@@ -0,0 +1,24 @@
1
+ export interface StructureNode {
2
+ depth: number;
3
+ role: string;
4
+ ref?: string;
5
+ /** Had an accessible name. The name itself is never kept. */
6
+ named?: boolean;
7
+ /** Had a form value. */
8
+ valued?: boolean;
9
+ /** Had its own text. */
10
+ texted?: boolean;
11
+ /** A grid container's track signature (CSS, not page text). */
12
+ layout?: string;
13
+ states?: string[];
14
+ }
15
+ /** One snapshot tree as text-free nodes. Lines that are not snapshot lines are dropped. */
16
+ export declare function structureOfTree(tree: string): StructureNode[];
17
+ /**
18
+ * Every snapshot step in a project's episodes, as structure lines handed to `write`. A result the
19
+ * episode cut short holds no whole tree and is counted, never guessed at.
20
+ */
21
+ export declare function exportStructure(reticleRoot: string, write: (line: string) => void): {
22
+ steps: number;
23
+ skippedCut: number;
24
+ };
@@ -0,0 +1,138 @@
1
+ /**
2
+ * The page's structure at each step, without its text: what a dataset can carry.
3
+ *
4
+ * The episode log keeps each `reticle_snapshot` result whole, on the machine. An export needs the
5
+ * shape of the page (roles, nesting, refs, layout, form state) and none of its words: accessible
6
+ * names, values and text are the customer's data. `structureOfTree` reads the snapshot's line format
7
+ * from the END of each line, and copies only what it can check against a fixed vocabulary or a
8
+ * fixed pattern (a role token, `e<n>`, a grid layout, a known state). Everything else becomes a
9
+ * boolean, so a word can never pass through, however a line is shaped.
10
+ *
11
+ * `reticle hook export --structure` writes one JSON line per snapshot step to stdout.
12
+ */
13
+ import { readFileSync, readdirSync } from 'node:fs';
14
+ import { join } from 'node:path';
15
+ import { ElementState, ReticleDir } from '@reticlehq/core';
16
+ const LINE = /^((?: {2})*)- ([a-z][a-z-]*)(.*)$/;
17
+ const INDENT = 2;
18
+ const STATES = new Set([
19
+ ElementState.DISABLED,
20
+ ElementState.CHECKED,
21
+ ElementState.EXPANDED,
22
+ ElementState.PRESSED,
23
+ ElementState.FOCUSED,
24
+ ]);
25
+ const STATE_SUFFIX = / \[([a-zA-Z,]+)\]$/;
26
+ const LAYOUT_SUFFIX = / \[(grid(?:-cols:[^\]"]*)?)\]$/;
27
+ const REF_SUFFIX = / \(ref=(e\d+)\)$/;
28
+ const TEXT_FIELD = ' [text="';
29
+ const VALUE_FIELD = ' [value="';
30
+ const FIELD_END = '"]';
31
+ /** The snapshot role for a generic container's bare text line. */
32
+ const TEXT_ROLE = 'text';
33
+ const SNAPSHOT_TOOL = 'reticle_snapshot';
34
+ /** One snapshot tree as text-free nodes. Lines that are not snapshot lines are dropped. */
35
+ export function structureOfTree(tree) {
36
+ const nodes = [];
37
+ for (const line of tree.split('\n')) {
38
+ const match = LINE.exec(line);
39
+ if (null === match) {
40
+ continue;
41
+ }
42
+ const [, indent = '', role = '', tail = ''] = match;
43
+ const node = { depth: indent.length / INDENT, role };
44
+ let rest = tail;
45
+ const states = STATE_SUFFIX.exec(rest);
46
+ const named = states?.[1]?.split(',') ?? [];
47
+ if (states !== null && 0 < named.length && named.every((s) => STATES.has(s))) {
48
+ node.states = named;
49
+ rest = rest.slice(0, states.index);
50
+ }
51
+ const layout = LAYOUT_SUFFIX.exec(rest);
52
+ if (layout !== null) {
53
+ node.layout = layout[1] ?? '';
54
+ rest = rest.slice(0, layout.index);
55
+ }
56
+ for (const [field, flag] of [
57
+ [TEXT_FIELD, 'texted'],
58
+ [VALUE_FIELD, 'valued'],
59
+ ]) {
60
+ const at = rest.lastIndexOf(field);
61
+ if (-1 !== at && rest.endsWith(FIELD_END)) {
62
+ node[flag] = true;
63
+ rest = rest.slice(0, at);
64
+ }
65
+ }
66
+ const ref = REF_SUFFIX.exec(rest);
67
+ if (ref !== null) {
68
+ node.ref = ref[1] ?? '';
69
+ rest = rest.slice(0, ref.index);
70
+ }
71
+ if (rest.startsWith(' "')) {
72
+ if (TEXT_ROLE === role) {
73
+ node.texted = true;
74
+ }
75
+ else {
76
+ node.named = true;
77
+ }
78
+ }
79
+ nodes.push(node);
80
+ }
81
+ return nodes;
82
+ }
83
+ const isObject = (value) => 'object' === typeof value && null !== value && !Array.isArray(value);
84
+ /**
85
+ * Every snapshot step in a project's episodes, as structure lines handed to `write`. A result the
86
+ * episode cut short holds no whole tree and is counted, never guessed at.
87
+ */
88
+ export function exportStructure(reticleRoot, write) {
89
+ const dir = join(reticleRoot, ReticleDir.EPISODES_SUBDIR);
90
+ let files;
91
+ try {
92
+ files = readdirSync(dir).filter((file) => file.endsWith('.jsonl'));
93
+ }
94
+ catch {
95
+ return { steps: 0, skippedCut: 0 };
96
+ }
97
+ let steps = 0;
98
+ let skippedCut = 0;
99
+ for (const file of files) {
100
+ let episodeId;
101
+ for (const line of readFileSync(join(dir, file), 'utf8').split('\n')) {
102
+ let record;
103
+ try {
104
+ record = JSON.parse(line);
105
+ }
106
+ catch {
107
+ continue;
108
+ }
109
+ if (!isObject(record)) {
110
+ continue;
111
+ }
112
+ if (record['episodeId'] !== undefined) {
113
+ episodeId = record['episodeId'];
114
+ }
115
+ if (SNAPSHOT_TOOL !== record['tool']) {
116
+ continue;
117
+ }
118
+ const result = record['result'];
119
+ const tree = isObject(result) ? result['tree'] : undefined;
120
+ if ('string' !== typeof tree) {
121
+ if (Array.isArray(record['truncated'])) {
122
+ skippedCut += 1;
123
+ }
124
+ continue;
125
+ }
126
+ steps += 1;
127
+ write(JSON.stringify({
128
+ episodeId,
129
+ n: record['n'],
130
+ tool: record['tool'],
131
+ sessionId: record['sessionId'],
132
+ startedAt: record['startedAt'],
133
+ structure: structureOfTree(tree),
134
+ }));
135
+ }
136
+ }
137
+ return { steps, skippedCut };
138
+ }
@@ -0,0 +1,9 @@
1
+ /** The project folder `cwd` belongs to: the nearest `.reticle.json` above it, else `cwd`. */
2
+ export declare function projectDirOf(cwd: string): string;
3
+ export declare function claudeCliHere(): boolean;
4
+ /**
5
+ * One row per agent: does it capture prompts here, through its hook or the MCP instructions, or is
6
+ * capture off. `reticle doctor` prints the same rows.
7
+ */
8
+ export declare function promptCaptureRows(projectDir: string, env: NodeJS.ProcessEnv, claudeCli: boolean, home?: string): string[];
9
+ export declare function handleHook(argv: readonly string[], print?: (line: string) => void): Promise<number>;