@reticlehq/server 3.6.0 → 3.7.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (614) hide show
  1. package/SKILL.md +122 -123
  2. package/dist/command/cli/adhoc-suite.d.ts +14 -0
  3. package/dist/command/cli/adhoc-suite.js +42 -7
  4. package/dist/command/cli/adhoc-verdict.d.ts +18 -2
  5. package/dist/command/cli/adhoc-verdict.js +70 -6
  6. package/dist/command/cli/answers/gate-exit.d.ts +23 -0
  7. package/dist/command/cli/answers/gate-exit.js +45 -0
  8. package/dist/command/cli/answers/gate-hook-message.d.ts +2 -0
  9. package/dist/command/cli/answers/gate-hook-message.js +3 -1
  10. package/dist/command/cli/auth/device-flow.d.ts +13 -2
  11. package/dist/command/cli/auth/device-flow.js +17 -0
  12. package/dist/command/cli/cli-doctor.js +14 -0
  13. package/dist/command/cli/cli-flow-commands.d.ts +0 -11
  14. package/dist/command/cli/cli-flow-commands.js +28 -105
  15. package/dist/command/cli/cli-kill.js +3 -2
  16. package/dist/command/cli/cli-parse-grammar.d.ts +24 -0
  17. package/dist/command/cli/cli-parse-grammar.js +75 -0
  18. package/dist/command/cli/cli-parse-verify.d.ts +2 -0
  19. package/dist/command/cli/cli-parse-verify.js +18 -0
  20. package/dist/command/cli/cli-parse.d.ts +19 -28
  21. package/dist/command/cli/cli-parse.js +82 -182
  22. package/dist/command/cli/cli-update-commands.d.ts +1 -1
  23. package/dist/command/cli/cli-update-commands.js +61 -9
  24. package/dist/command/cli/cli-usage.d.ts +33 -0
  25. package/dist/command/cli/cli-usage.js +287 -0
  26. package/dist/command/cli/cli-verify.d.ts +34 -4
  27. package/dist/command/cli/cli-verify.js +81 -12
  28. package/dist/command/cli/cloud-cli.d.ts +13 -0
  29. package/dist/command/cli/cloud-cli.js +145 -333
  30. package/dist/command/cli/cloud-kit.d.ts +12 -0
  31. package/dist/command/cli/cloud-kit.js +41 -2
  32. package/dist/command/cli/cloud-link.d.ts +57 -0
  33. package/dist/command/cli/cloud-link.js +308 -0
  34. package/dist/command/cli/cloud-login.d.ts +15 -1
  35. package/dist/command/cli/cloud-login.js +67 -13
  36. package/dist/command/cli/context-command.d.ts +1 -0
  37. package/dist/command/cli/context-command.js +33 -0
  38. package/dist/command/cli/daemon-start-options.d.ts +3 -0
  39. package/dist/command/cli/daemon-start-options.js +24 -3
  40. package/dist/command/cli/doctor/doctor-coverage-line.d.ts +2 -0
  41. package/dist/command/cli/doctor/doctor-coverage-line.js +47 -0
  42. package/dist/command/cli/doctor/doctor-project-line.d.ts +0 -12
  43. package/dist/command/cli/doctor/doctor-project-line.js +5 -4
  44. package/dist/command/cli/doctor/doctor-rows.d.ts +6 -0
  45. package/dist/command/cli/doctor/doctor-rows.js +6 -0
  46. package/dist/command/cli/doctor/doctor-signing-line.d.ts +38 -0
  47. package/dist/command/cli/doctor/doctor-signing-line.js +114 -0
  48. package/dist/command/cli/known-regression.d.ts +13 -0
  49. package/dist/command/cli/known-regression.js +34 -0
  50. package/dist/command/cli/launch/sdk-version-match.d.ts +12 -0
  51. package/dist/command/cli/launch/sdk-version-match.js +25 -0
  52. package/dist/command/cli/lifecycle/daemon-lifecycle.js +11 -2
  53. package/dist/command/cli/mcp-command.d.ts +6 -0
  54. package/dist/command/cli/mcp-command.js +13 -5
  55. package/dist/command/cli/ports/port-holder.js +1 -1
  56. package/dist/command/cli/project-name.d.ts +29 -1
  57. package/dist/command/cli/project-name.js +107 -2
  58. package/dist/command/cli/setup-mcp-cli.d.ts +17 -1
  59. package/dist/command/cli/setup-mcp-cli.js +29 -8
  60. package/dist/command/cli/status/status-lines.d.ts +1 -0
  61. package/dist/command/cli/status/status-lines.js +47 -2
  62. package/dist/command/cli/status/workspace-links.d.ts +10 -0
  63. package/dist/command/cli/status/workspace-links.js +29 -0
  64. package/dist/command/cli/try-command.d.ts +96 -0
  65. package/dist/command/cli/try-command.js +362 -0
  66. package/dist/command/cli/tutorial.d.ts +0 -100
  67. package/dist/command/cli/tutorial.js +0 -178
  68. package/dist/command/cli/verify-results.d.ts +19 -0
  69. package/dist/command/cli/verify-results.js +29 -0
  70. package/dist/command/cli-onboarding.d.ts +0 -11
  71. package/dist/command/cli-onboarding.js +0 -15
  72. package/dist/command/cli.d.ts +14 -0
  73. package/dist/command/cli.js +103 -83
  74. package/dist/command/daemon/daemon-resilience.js +4 -4
  75. package/dist/command/daemon/daemon-resolve.d.ts +9 -1
  76. package/dist/command/daemon/daemon-resolve.js +49 -10
  77. package/dist/command/setup/bringup/bridge-port.d.ts +3 -1
  78. package/dist/command/setup/bringup/bridge-port.js +13 -3
  79. package/dist/command/setup/bringup/dev-server-log-cap.js +2 -0
  80. package/dist/command/setup/bringup/ensure-daemon.js +9 -2
  81. package/dist/command/setup/init/agent-restart.d.ts +23 -0
  82. package/dist/command/setup/init/agent-restart.js +28 -0
  83. package/dist/command/setup/init/init-port.d.ts +10 -1
  84. package/dist/command/setup/init/init-port.js +22 -2
  85. package/dist/command/setup/init/init-runtime.d.ts +12 -2
  86. package/dist/command/setup/init/init-runtime.js +96 -37
  87. package/dist/command/setup/node-effects.d.ts +2 -0
  88. package/dist/command/setup/node-effects.js +36 -8
  89. package/dist/command/setup/probe/existing-app.d.ts +12 -0
  90. package/dist/command/setup/probe/existing-app.js +14 -0
  91. package/dist/command/setup/remaining-steps.js +1 -1
  92. package/dist/command/setup/run-setup.d.ts +29 -9
  93. package/dist/command/setup/run-setup.js +34 -28
  94. package/dist/command/setup/setup-command.d.ts +23 -0
  95. package/dist/command/setup/setup-command.js +57 -4
  96. package/dist/command/setup/setup-mcp.js +25 -2
  97. package/dist/command/setup/tauri-signing.d.ts +19 -0
  98. package/dist/command/setup/tauri-signing.js +79 -0
  99. package/dist/command/setup/terminal/listeners.d.ts +10 -1
  100. package/dist/command/setup/terminal/listeners.js +37 -6
  101. package/dist/command/update/update-nudge.d.ts +9 -0
  102. package/dist/command/update/update-nudge.js +1 -1
  103. package/dist/command/update/updater.js +11 -15
  104. package/dist/command/version/version-nudge.js +3 -0
  105. package/dist/command/version/version-skew.d.ts +20 -1
  106. package/dist/command/version/version-skew.js +38 -2
  107. package/dist/features/crawl/crawl.js +14 -1
  108. package/dist/features/exhaust/ledger.d.ts +14 -14
  109. package/dist/features/harness/drive-report.d.ts +39 -5
  110. package/dist/features/harness/drive-report.js +271 -54
  111. package/dist/features/harness/drive-runs.d.ts +120 -0
  112. package/dist/features/harness/drive-runs.js +289 -0
  113. package/dist/features/harness/drivers.d.ts +1 -1
  114. package/dist/features/harness/drivers.js +1 -1
  115. package/dist/features/harness/explore/console-pages.d.ts +15 -0
  116. package/dist/features/harness/explore/console-pages.js +146 -0
  117. package/dist/features/harness/explore/disparity.d.ts +19 -0
  118. package/dist/features/harness/explore/disparity.js +71 -0
  119. package/dist/features/harness/explore/fake-app.d.ts +16 -0
  120. package/dist/features/harness/explore/fake-app.js +49 -0
  121. package/dist/features/harness/explore/goal-search.d.ts +26 -0
  122. package/dist/features/harness/explore/goal-search.js +144 -0
  123. package/dist/features/harness/explore/page-tree.d.ts +49 -0
  124. package/dist/features/harness/explore/page-tree.js +148 -0
  125. package/dist/features/harness/explore/site-map.d.ts +34 -0
  126. package/dist/features/harness/explore/site-map.js +150 -0
  127. package/dist/features/harness/goals.d.ts +68 -7
  128. package/dist/features/harness/goals.js +289 -36
  129. package/dist/features/harness/harness.d.ts +30 -1
  130. package/dist/features/harness/harness.js +141 -7
  131. package/dist/features/harness/platform/local-apps.d.ts +36 -3
  132. package/dist/features/harness/platform/local-apps.js +81 -5
  133. package/dist/features/harness/platform/persona-credentials.d.ts +20 -0
  134. package/dist/features/harness/platform/persona-credentials.js +69 -0
  135. package/dist/features/harness/platform/platform-drives.d.ts +61 -0
  136. package/dist/features/harness/platform/platform-drives.js +114 -0
  137. package/dist/features/harness/platform/refusal.d.ts +52 -0
  138. package/dist/features/harness/platform/refusal.js +71 -0
  139. package/dist/features/harness/platform/remote-drive.d.ts +8 -2
  140. package/dist/features/harness/platform/remote-drive.js +22 -9
  141. package/dist/features/harness/platform/script.d.ts +57 -11
  142. package/dist/features/harness/platform/script.js +144 -12
  143. package/dist/features/harness/platform/server-driver.d.ts +17 -4
  144. package/dist/features/harness/platform/server-driver.js +29 -26
  145. package/dist/features/harness/platform-config.d.ts +38 -5
  146. package/dist/features/harness/platform-config.js +93 -8
  147. package/dist/features/harness/route-guess.d.ts +13 -0
  148. package/dist/features/harness/route-guess.js +49 -0
  149. package/dist/features/harness/script/script-run.d.ts +30 -1
  150. package/dist/features/harness/script/script-run.js +355 -48
  151. package/dist/features/license/license.d.ts +2 -2
  152. package/dist/features/visual/step-shots.d.ts +31 -0
  153. package/dist/features/visual/step-shots.js +231 -0
  154. package/dist/features/visual/visual-tools.js +22 -14
  155. package/dist/hooks/client-directory.d.ts +18 -0
  156. package/dist/hooks/client-directory.js +57 -0
  157. package/dist/hooks/coding-agents.d.ts +34 -0
  158. package/dist/hooks/coding-agents.js +117 -0
  159. package/dist/hooks/driven-by.d.ts +21 -2
  160. package/dist/hooks/driven-by.js +42 -2
  161. package/dist/hooks/hook-bus.d.ts +4 -0
  162. package/dist/hooks/hook-bus.js +18 -0
  163. package/dist/index.d.ts +1 -0
  164. package/dist/index.js +26 -183
  165. package/dist/judgement/capsule/capsule-store.d.ts +2 -2
  166. package/dist/judgement/capsule/causal-summary.d.ts +15 -1
  167. package/dist/judgement/capsule/causal-summary.js +33 -0
  168. package/dist/judgement/runs/artifact/build-verification-run.d.ts +1 -1
  169. package/dist/judgement/runs/artifact/build-verification-run.js +20 -4
  170. package/dist/judgement/runs/artifact/gap-summary.d.ts +0 -18
  171. package/dist/judgement/runs/artifact/gap-summary.js +12 -3
  172. package/dist/judgement/runs/artifact/replay-mapping.js +25 -9
  173. package/dist/judgement/runs/artifact/run-store.d.ts +13 -1
  174. package/dist/judgement/runs/artifact/run-store.js +175 -8
  175. package/dist/judgement/runs/context-tools.js +59 -1
  176. package/dist/judgement/runs/default-run-id.d.ts +3 -0
  177. package/dist/judgement/runs/default-run-id.js +16 -0
  178. package/dist/judgement/runs/drive-run.d.ts +53 -5
  179. package/dist/judgement/runs/drive-run.js +234 -20
  180. package/dist/judgement/runs/resume.d.ts +44 -0
  181. package/dist/judgement/runs/resume.js +137 -0
  182. package/dist/judgement/runs/reticle-runner.js +5 -2
  183. package/dist/judgement/runs/runner-port.d.ts +5 -1
  184. package/dist/judgement/runs/runner-port.js +8 -2
  185. package/dist/judgement/runs/verification-sync.d.ts +2 -0
  186. package/dist/judgement/runs/verification-sync.js +36 -15
  187. package/dist/language/flows/decision.js +2 -1
  188. package/dist/language/flows/fields/flow-secret-field.d.ts +12 -0
  189. package/dist/language/flows/fields/flow-secret-field.js +25 -2
  190. package/dist/language/flows/flow-anchor.d.ts +7 -2
  191. package/dist/language/flows/flow-anchor.js +10 -3
  192. package/dist/language/flows/flow-intent.d.ts +1 -0
  193. package/dist/language/flows/flow-journey.d.ts +6 -0
  194. package/dist/language/flows/flow-journey.js +20 -0
  195. package/dist/language/flows/flow-learning.d.ts +4 -0
  196. package/dist/language/flows/flow-learning.js +37 -3
  197. package/dist/language/flows/flow-replay-run.js +16 -18
  198. package/dist/language/flows/flow-replay-types.d.ts +1 -1
  199. package/dist/language/flows/flow-replay.d.ts +18 -1
  200. package/dist/language/flows/flow-replay.js +22 -7
  201. package/dist/language/flows/flow-result.d.ts +22 -1
  202. package/dist/language/flows/flow-result.js +47 -2
  203. package/dist/language/flows/flow-step-runners.d.ts +2 -0
  204. package/dist/language/flows/flow-step-runners.js +12 -6
  205. package/dist/language/flows/flow-store-for-session.js +5 -1
  206. package/dist/language/flows/flow-tools.d.ts +10 -0
  207. package/dist/language/flows/flow-tools.js +61 -62
  208. package/dist/language/flows/flows.d.ts +16 -1
  209. package/dist/language/flows/flows.js +69 -10
  210. package/dist/language/flows/narrow-write.d.ts +7 -0
  211. package/dist/language/flows/narrow-write.js +36 -1
  212. package/dist/language/flows/recording/recording-backtrack.js +14 -1
  213. package/dist/language/flows/recording/tape/recordings.d.ts +29 -1
  214. package/dist/language/flows/recording/tape/recordings.js +60 -10
  215. package/dist/language/flows/replay.js +29 -6
  216. package/dist/language/flows/single-replay.d.ts +7 -0
  217. package/dist/language/flows/single-replay.js +26 -0
  218. package/dist/language/flows/verify-change-tools.d.ts +1 -0
  219. package/dist/language/flows/verify-change-tools.js +200 -193
  220. package/dist/memory/cloud/cloud-config.d.ts +10 -1
  221. package/dist/memory/cloud/cloud-config.js +19 -5
  222. package/dist/memory/cloud/cloud-sync.js +3 -3
  223. package/dist/memory/cloud/harness-config.d.ts +49 -0
  224. package/dist/memory/cloud/harness-config.js +16 -20
  225. package/dist/memory/cloud/memory-scope.d.ts +17 -0
  226. package/dist/memory/cloud/memory-scope.js +22 -0
  227. package/dist/memory/cloud/sync-cycle.d.ts +32 -4
  228. package/dist/memory/cloud/sync-cycle.js +113 -12
  229. package/dist/memory/cloud/sync-daemon.d.ts +11 -0
  230. package/dist/memory/cloud/sync-daemon.js +114 -4
  231. package/dist/memory/cloud/sync-disk.js +26 -2
  232. package/dist/memory/cloud/sync-screenshots.d.ts +32 -0
  233. package/dist/memory/cloud/sync-screenshots.js +105 -0
  234. package/dist/memory/cloud/unsynced-roots.d.ts +47 -0
  235. package/dist/memory/cloud/unsynced-roots.js +166 -0
  236. package/dist/memory/impact/account-watch.d.ts +16 -1
  237. package/dist/memory/impact/account-watch.js +26 -1
  238. package/dist/memory/impact/impact-store.d.ts +1 -4
  239. package/dist/memory/impact/impact-store.js +32 -42
  240. package/dist/memory/intent/inline-intent.d.ts +1 -0
  241. package/dist/memory/intent/intent-shard-store.js +16 -4
  242. package/dist/memory/intent/intent-shard.d.ts +12 -0
  243. package/dist/memory/intent/intent-store.d.ts +1 -0
  244. package/dist/memory/intent/intent-tools.js +42 -2
  245. package/dist/memory/intent/open-intents.d.ts +6 -0
  246. package/dist/memory/intent/open-intents.js +10 -1
  247. package/dist/memory/intent/settled-words.d.ts +24 -0
  248. package/dist/memory/intent/settled-words.js +130 -0
  249. package/dist/memory/journal/drive-flow.d.ts +16 -0
  250. package/dist/memory/journal/drive-flow.js +34 -2
  251. package/dist/memory/journal/drive-run-flush.d.ts +2 -0
  252. package/dist/memory/journal/drive-run-flush.js +20 -5
  253. package/dist/memory/journal/journal-recorder.js +46 -3
  254. package/dist/memory/journal/on-disk/retention.d.ts +5 -0
  255. package/dist/memory/journal/on-disk/retention.js +27 -2
  256. package/dist/memory/journal/on-disk/workspace-tiers.js +2 -0
  257. package/dist/memory/journal/session-end.d.ts +15 -1
  258. package/dist/memory/journal/session-end.js +38 -7
  259. package/dist/memory/project/artifact-root-resolver.js +33 -5
  260. package/dist/memory/project/artifact-root.d.ts +4 -3
  261. package/dist/memory/project/artifact-root.js +2 -2
  262. package/dist/memory/project/dir/reticle-dir.d.ts +14 -0
  263. package/dist/memory/project/dir/reticle-dir.js +23 -2
  264. package/dist/memory/project/link-directory.d.ts +15 -0
  265. package/dist/memory/project/link-directory.js +44 -0
  266. package/dist/memory/project/root-claims.d.ts +6 -0
  267. package/dist/memory/project/root-claims.js +39 -0
  268. package/dist/memory/project/session-root.d.ts +2 -0
  269. package/dist/memory/project/session-root.js +9 -1
  270. package/dist/memory/project/sync-status.d.ts +46 -0
  271. package/dist/memory/project/sync-status.js +135 -1
  272. package/dist/memory/recall/memory-tools.js +46 -3
  273. package/dist/memory/recall/platform-memory.d.ts +34 -0
  274. package/dist/memory/recall/platform-memory.js +139 -0
  275. package/dist/memory/recall/project-memory.js +36 -8
  276. package/dist/portal/bridge/bridge.d.ts +9 -5
  277. package/dist/portal/bridge/bridge.js +66 -23
  278. package/dist/portal/bridge/harness-request.d.ts +23 -0
  279. package/dist/portal/bridge/harness-request.js +27 -0
  280. package/dist/portal/bridge/wrong-path.d.ts +17 -0
  281. package/dist/portal/bridge/wrong-path.js +35 -0
  282. package/dist/portal/input/network-mock-tools.js +11 -2
  283. package/dist/portal/input/real-input.d.ts +2 -0
  284. package/dist/portal/input/real-input.js +13 -10
  285. package/dist/portal/pool/browser-pool.d.ts +48 -0
  286. package/dist/portal/pool/browser-pool.js +120 -2
  287. package/dist/portal/pool/context-permissions.d.ts +33 -0
  288. package/dist/portal/pool/context-permissions.js +33 -0
  289. package/dist/portal/pool/lease-marker-stamp.d.ts +23 -0
  290. package/dist/portal/pool/lease-marker-stamp.js +49 -0
  291. package/dist/portal/pool/playwright-launcher.d.ts +27 -5
  292. package/dist/portal/pool/playwright-launcher.js +59 -14
  293. package/dist/portal/pool/pool-contract.d.ts +21 -1
  294. package/dist/portal/session/agent-link.d.ts +8 -0
  295. package/dist/portal/session/agent-link.js +17 -0
  296. package/dist/portal/session/command-payload.js +6 -1
  297. package/dist/portal/session/daemon-answers.d.ts +3 -3
  298. package/dist/portal/session/daemon-answers.js +4 -2
  299. package/dist/portal/session/dev-server/dev-command.d.ts +9 -0
  300. package/dist/portal/session/dev-server/dev-command.js +27 -1
  301. package/dist/portal/session/facts/observed-state.d.ts +16 -18
  302. package/dist/portal/session/facts/observed-state.js +46 -3
  303. package/dist/portal/session/human/live-control.d.ts +9 -2
  304. package/dist/portal/session/human/live-control.js +12 -3
  305. package/dist/portal/session/live-control-tools.js +82 -13
  306. package/dist/portal/session/narration-args.d.ts +5 -0
  307. package/dist/portal/session/narration-args.js +17 -0
  308. package/dist/portal/session/no-session-diagnosis.d.ts +1 -1
  309. package/dist/portal/session/no-session-diagnosis.js +31 -9
  310. package/dist/portal/session/no-session-next-action.d.ts +20 -0
  311. package/dist/portal/session/no-session-next-action.js +134 -61
  312. package/dist/portal/session/no-session-watch.js +179 -22
  313. package/dist/portal/session/presence/session-lease.js +1 -1
  314. package/dist/portal/session/recorded-gaps.d.ts +97 -0
  315. package/dist/portal/session/recorded-gaps.js +251 -0
  316. package/dist/portal/session/session-health.d.ts +11 -0
  317. package/dist/portal/session/session-health.js +3 -1
  318. package/dist/portal/session/session-info.js +2 -1
  319. package/dist/portal/session/session-manager.d.ts +18 -0
  320. package/dist/portal/session/session-manager.js +54 -3
  321. package/dist/portal/session/session-successor.d.ts +8 -0
  322. package/dist/portal/session/session-successor.js +1 -1
  323. package/dist/portal/session/session.d.ts +15 -28
  324. package/dist/portal/session/session.js +60 -61
  325. package/dist/portal/session/timing/command-timeout.js +25 -1
  326. package/dist/portal/session/timing/wall-clock.d.ts +1 -1
  327. package/dist/portal/session/timing/wall-clock.js +1 -1
  328. package/dist/portal/session/zero-install-first-call.d.ts +31 -0
  329. package/dist/portal/session/zero-install-first-call.js +88 -0
  330. package/dist/start-options.d.ts +7 -1
  331. package/dist/start-wiring.d.ts +63 -0
  332. package/dist/start-wiring.js +169 -0
  333. package/dist/status-payload.d.ts +13 -1
  334. package/dist/status-payload.js +13 -1
  335. package/dist/surface/http-server.js +7 -1
  336. package/dist/surface/mcp/attach-memory.d.ts +1 -0
  337. package/dist/surface/mcp/attach-memory.js +12 -1
  338. package/dist/surface/mcp/mcp-proxy.d.ts +4 -0
  339. package/dist/surface/mcp/mcp-proxy.js +29 -8
  340. package/dist/surface/mcp/mcp.d.ts +23 -0
  341. package/dist/surface/mcp/mcp.js +34 -4
  342. package/dist/surface/mcp/proxy/drive-calls.d.ts +10 -0
  343. package/dist/surface/mcp/proxy/drive-calls.js +27 -0
  344. package/dist/surface/mcp/proxy/mcp-post-transport.js +5 -0
  345. package/dist/surface/mcp/server-instructions.js +22 -14
  346. package/dist/surface/mcp/shared-params.js +1 -1
  347. package/dist/surface/mcp/surface-vocabulary.d.ts +2 -0
  348. package/dist/surface/mcp/surface-vocabulary.js +1 -0
  349. package/dist/surface/tools/account-tool.d.ts +22 -0
  350. package/dist/surface/tools/account-tool.js +157 -0
  351. package/dist/surface/tools/act/act-danger.d.ts +11 -0
  352. package/dist/surface/tools/act/act-danger.js +38 -1
  353. package/dist/surface/tools/act/act-observation.d.ts +33 -0
  354. package/dist/surface/tools/act/act-observation.js +57 -0
  355. package/dist/surface/tools/act/act-preflight.js +25 -2
  356. package/dist/surface/tools/act/act-target.js +8 -3
  357. package/dist/surface/tools/act/resolve-target.d.ts +1 -1
  358. package/dist/surface/tools/act/resolve-target.js +18 -3
  359. package/dist/surface/tools/act/screen-request.d.ts +34 -0
  360. package/dist/surface/tools/act/screen-request.js +113 -0
  361. package/dist/surface/tools/act/sequence-grade.d.ts +8 -0
  362. package/dist/surface/tools/act/sequence-grade.js +13 -2
  363. package/dist/surface/tools/act-sequence-tool.js +136 -27
  364. package/dist/surface/tools/act-tools.d.ts +0 -9
  365. package/dist/surface/tools/act-tools.js +48 -34
  366. package/dist/surface/tools/agent/app-notes-learning.d.ts +7 -0
  367. package/dist/surface/tools/agent/app-notes-learning.js +80 -0
  368. package/dist/surface/tools/agent/app-notes.d.ts +4 -0
  369. package/dist/surface/tools/agent/app-notes.js +48 -0
  370. package/dist/surface/tools/agent/build-staleness.d.ts +7 -0
  371. package/dist/surface/tools/agent/build-staleness.js +62 -0
  372. package/dist/surface/tools/agent/compact-envelope.d.ts +80 -0
  373. package/dist/surface/tools/agent/compact-envelope.js +374 -0
  374. package/dist/surface/tools/agent/for-the-agent.d.ts +12 -0
  375. package/dist/surface/tools/agent/for-the-agent.js +44 -0
  376. package/dist/surface/tools/agent/notices.d.ts +50 -0
  377. package/dist/surface/tools/agent/notices.js +152 -0
  378. package/dist/surface/tools/agent/reteach.d.ts +11 -0
  379. package/dist/surface/tools/agent/reteach.js +50 -0
  380. package/dist/surface/tools/args/alias-args.d.ts +5 -0
  381. package/dist/surface/tools/args/alias-args.js +10 -0
  382. package/dist/surface/tools/args/confirm-dangerous-arg.d.ts +6 -0
  383. package/dist/surface/tools/args/confirm-dangerous-arg.js +6 -0
  384. package/dist/surface/tools/assert/assert-source.d.ts +15 -0
  385. package/dist/surface/tools/assert/assert-source.js +40 -0
  386. package/dist/surface/tools/assert/assert-verdict.js +25 -15
  387. package/dist/surface/tools/browser-tools.js +43 -1
  388. package/dist/surface/tools/chat-drives.d.ts +75 -0
  389. package/dist/surface/tools/chat-drives.js +265 -21
  390. package/dist/surface/tools/coverage-tools.d.ts +2 -10
  391. package/dist/surface/tools/coverage-tools.js +2 -53
  392. package/dist/surface/tools/dynamic-tools.js +29 -1
  393. package/dist/surface/tools/empty-session-list.d.ts +10 -0
  394. package/dist/surface/tools/empty-session-list.js +45 -5
  395. package/dist/surface/tools/error-recovery.d.ts +8 -0
  396. package/dist/surface/tools/error-recovery.js +69 -5
  397. package/dist/surface/tools/explore-tools.d.ts +23 -2
  398. package/dist/surface/tools/explore-tools.js +377 -74
  399. package/dist/surface/tools/feedback-tools.d.ts +2 -3
  400. package/dist/surface/tools/feedback-tools.js +4 -3
  401. package/dist/surface/tools/gap-novelty.d.ts +3 -1
  402. package/dist/surface/tools/gap-novelty.js +8 -1
  403. package/dist/surface/tools/harness-explore.d.ts +52 -73
  404. package/dist/surface/tools/harness-explore.js +177 -146
  405. package/dist/surface/tools/harness-gate.d.ts +88 -0
  406. package/dist/surface/tools/harness-gate.js +235 -0
  407. package/dist/surface/tools/harness-hunt.d.ts +43 -0
  408. package/dist/surface/tools/harness-hunt.js +215 -0
  409. package/dist/surface/tools/harness-plan.d.ts +5 -0
  410. package/dist/surface/tools/harness-plan.js +7 -0
  411. package/dist/surface/tools/harness-script.d.ts +22 -0
  412. package/dist/surface/tools/harness-script.js +256 -38
  413. package/dist/surface/tools/harness-tab-guard.d.ts +5 -0
  414. package/dist/surface/tools/harness-tab-guard.js +27 -0
  415. package/dist/surface/tools/harness-toolset.d.ts +8 -0
  416. package/dist/surface/tools/harness-toolset.js +27 -4
  417. package/dist/surface/tools/human-notes.d.ts +16 -0
  418. package/dist/surface/tools/human-notes.js +27 -0
  419. package/dist/surface/tools/invoke-tool.d.ts +5 -2
  420. package/dist/surface/tools/invoke-tool.js +220 -93
  421. package/dist/surface/tools/lease-hint.js +26 -5
  422. package/dist/surface/tools/lease-permissions.d.ts +33 -0
  423. package/dist/surface/tools/lease-permissions.js +73 -0
  424. package/dist/surface/tools/lease-readiness.d.ts +38 -0
  425. package/dist/surface/tools/lease-readiness.js +57 -0
  426. package/dist/surface/tools/lease-seed.d.ts +20 -0
  427. package/dist/surface/tools/lease-seed.js +45 -1
  428. package/dist/surface/tools/lease-tools.d.ts +10 -1
  429. package/dist/surface/tools/lease-tools.js +119 -69
  430. package/dist/surface/tools/live-call-text.js +2 -2
  431. package/dist/surface/tools/merge-tools.js +42 -2
  432. package/dist/surface/tools/merged-name-redirect.js +4 -0
  433. package/dist/surface/tools/next-step.d.ts +11 -1
  434. package/dist/surface/tools/next-step.js +73 -18
  435. package/dist/surface/tools/observe-tools.js +43 -5
  436. package/dist/surface/tools/platform-moment.d.ts +60 -0
  437. package/dist/surface/tools/platform-moment.js +132 -4
  438. package/dist/surface/tools/read-tools.js +65 -14
  439. package/dist/surface/tools/reticle-result.d.ts +120 -0
  440. package/dist/surface/tools/reticle-result.js +364 -0
  441. package/dist/surface/tools/tool-kit.d.ts +68 -2
  442. package/dist/surface/tools/tool-kit.js +73 -1
  443. package/dist/surface/tools/tools.js +25 -13
  444. package/dist/telemetry/account-envelope.d.ts +7 -0
  445. package/dist/telemetry/account-envelope.js +61 -0
  446. package/dist/telemetry/agent-client.d.ts +15 -0
  447. package/dist/telemetry/agent-client.js +57 -0
  448. package/dist/telemetry/app-instrumented.js +9 -2
  449. package/dist/telemetry/argument-shape.d.ts +7 -0
  450. package/dist/telemetry/argument-shape.js +86 -1
  451. package/dist/telemetry/automation-hint.d.ts +2 -3
  452. package/dist/telemetry/automation-hint.js +33 -8
  453. package/dist/telemetry/cli-telemetry.js +7 -2
  454. package/dist/telemetry/daemon-telemetry.js +3 -0
  455. package/dist/telemetry/error-fingerprint.d.ts +10 -1
  456. package/dist/telemetry/error-fingerprint.js +61 -5
  457. package/dist/telemetry/feedback-cli.d.ts +0 -13
  458. package/dist/telemetry/feedback-cli.js +0 -77
  459. package/dist/telemetry/feedback.d.ts +13 -0
  460. package/dist/telemetry/feedback.js +183 -17
  461. package/dist/telemetry/harness-run.d.ts +18 -0
  462. package/dist/telemetry/harness-run.js +80 -0
  463. package/dist/telemetry/hud-events.d.ts +16 -0
  464. package/dist/telemetry/hud-events.js +27 -0
  465. package/dist/telemetry/hud-metrics.d.ts +27 -6
  466. package/dist/telemetry/hud-metrics.js +99 -25
  467. package/dist/telemetry/init-telemetry.js +2 -2
  468. package/dist/telemetry/install-source.d.ts +13 -25
  469. package/dist/telemetry/install-source.js +44 -3
  470. package/dist/telemetry/mcp-connection.d.ts +0 -14
  471. package/dist/telemetry/mcp-connection.js +5 -1
  472. package/dist/telemetry/onboarding-firsts.d.ts +32 -0
  473. package/dist/telemetry/onboarding-firsts.js +81 -6
  474. package/dist/telemetry/platform-linked.d.ts +5 -0
  475. package/dist/telemetry/platform-linked.js +32 -0
  476. package/dist/telemetry/project-profile.js +5 -3
  477. package/dist/telemetry/proxy-telemetry.js +4 -1
  478. package/dist/telemetry/session-metrics.d.ts +15 -4
  479. package/dist/telemetry/session-metrics.js +88 -52
  480. package/dist/telemetry/telemetry.d.ts +26 -2
  481. package/dist/telemetry/telemetry.js +102 -21
  482. package/dist/telemetry/verification-of.d.ts +3 -1
  483. package/dist/telemetry/verification-of.js +12 -4
  484. package/dist/wire-journal.d.ts +2 -2
  485. package/dist/wire-journal.js +16 -5
  486. package/docs/README.md +2 -2
  487. package/docs/actions.mdx +6 -3
  488. package/docs/adapters.md +1 -1
  489. package/docs/agent-cheatsheet.md +24 -27
  490. package/docs/architecture.md +5 -5
  491. package/docs/autodrive.md +13 -12
  492. package/docs/benchmarks.md +5 -5
  493. package/docs/best-practices.mdx +27 -9
  494. package/docs/capabilities.mdx +14 -16
  495. package/docs/cli/affected.mdx +1 -1
  496. package/docs/cli/cloud.mdx +54 -75
  497. package/docs/cli/doctor.mdx +8 -3
  498. package/docs/cli/drive.mdx +12 -12
  499. package/docs/cli/feedback.mdx +3 -3
  500. package/docs/cli/gate.mdx +7 -2
  501. package/docs/cli/help.mdx +50 -55
  502. package/docs/cli/init.mdx +32 -15
  503. package/docs/cli/license.mdx +12 -8
  504. package/docs/cli/mcp.mdx +4 -4
  505. package/docs/cli/open.mdx +3 -3
  506. package/docs/cli/report.mdx +4 -2
  507. package/docs/cli/restart.mdx +2 -2
  508. package/docs/cli/rollback.mdx +14 -8
  509. package/docs/cli/serve.mdx +4 -4
  510. package/docs/cli/setup.mdx +23 -0
  511. package/docs/cli/status.mdx +13 -4
  512. package/docs/cli/stop.mdx +67 -8
  513. package/docs/cli/try.mdx +62 -0
  514. package/docs/cli/update.mdx +4 -3
  515. package/docs/cli/verify.mdx +17 -6
  516. package/docs/cli/version.mdx +3 -2
  517. package/docs/cli.mdx +110 -41
  518. package/docs/debugging.md +3 -3
  519. package/docs/deploy-checks.md +1 -1
  520. package/docs/desktop.mdx +5 -3
  521. package/docs/enterprise.md +11 -10
  522. package/docs/environment.mdx +5 -2
  523. package/docs/faq.mdx +3 -3
  524. package/docs/first-drive.md +5 -4
  525. package/docs/flows.md +35 -27
  526. package/docs/for-agents.md +4 -5
  527. package/docs/frameworks.mdx +32 -21
  528. package/docs/getting-started.md +66 -64
  529. package/docs/human-control.md +15 -14
  530. package/docs/index.mdx +15 -43
  531. package/docs/install-agentic.mdx +22 -37
  532. package/docs/install-manual.mdx +22 -12
  533. package/docs/instrumentation.mdx +5 -3
  534. package/docs/integration-patterns.md +7 -7
  535. package/docs/license-activation.mdx +1 -1
  536. package/docs/multi-agent-testing.md +24 -6
  537. package/docs/packages/babel-plugin.mdx +4 -2
  538. package/docs/packages/browser.mdx +16 -10
  539. package/docs/packages/core.mdx +12 -5
  540. package/docs/packages/electron.mdx +3 -2
  541. package/docs/packages/engine.mdx +1 -1
  542. package/docs/packages/eslint-plugin.mdx +18 -12
  543. package/docs/packages/next.mdx +8 -7
  544. package/docs/packages/open-verification.mdx +1 -1
  545. package/docs/packages/server.mdx +5 -5
  546. package/docs/packages/tauri.mdx +8 -8
  547. package/docs/packages/test.mdx +4 -10
  548. package/docs/packages/vite-plugin.mdx +11 -4
  549. package/docs/packages.mdx +11 -15
  550. package/docs/platform-integration.md +6 -5
  551. package/docs/predicates.mdx +40 -24
  552. package/docs/quickstart.mdx +58 -29
  553. package/docs/required-checks.md +8 -7
  554. package/docs/reticle-manual.md +15 -5
  555. package/docs/skill-file.mdx +17 -79
  556. package/docs/skill-setup.md +9 -9
  557. package/docs/skill.md +200 -0
  558. package/docs/system-map.md +7 -7
  559. package/docs/telemetry.md +22 -24
  560. package/docs/testing.md +4 -4
  561. package/docs/token-efficiency.md +12 -12
  562. package/docs/tools/act-and-wait.mdx +9 -2
  563. package/docs/tools/act-sequence.mdx +6 -7
  564. package/docs/tools/act.mdx +2 -2
  565. package/docs/tools/assert.mdx +18 -17
  566. package/docs/tools/console.mdx +9 -9
  567. package/docs/tools/inspect.mdx +16 -7
  568. package/docs/tools/look.mdx +24 -0
  569. package/docs/tools/navigate.mdx +5 -3
  570. package/docs/tools/network.mdx +2 -2
  571. package/docs/tools/observe.mdx +6 -6
  572. package/docs/tools/overview.mdx +34 -33
  573. package/docs/tools/query.mdx +5 -5
  574. package/docs/tools/session-and-feedback.mdx +13 -4
  575. package/docs/tools/sessions.mdx +8 -8
  576. package/docs/tools/snapshot.mdx +6 -5
  577. package/docs/tools/state.mdx +9 -9
  578. package/docs/tools/tools-and-run.mdx +26 -24
  579. package/docs/tools/verify.mdx +28 -0
  580. package/docs/tools/wait-for.mdx +8 -4
  581. package/docs/troubleshooting.mdx +21 -6
  582. package/docs/usage.md +51 -45
  583. package/docs/use-cases.mdx +3 -3
  584. package/docs/vs-chrome-devtools-mcp.mdx +9 -6
  585. package/docs/vs-playwright-mcp.mdx +3 -1
  586. package/docs/what-is-recorded.md +7 -5
  587. package/docs/what-is-reticle.mdx +2 -2
  588. package/docs/why-reticle.mdx +1 -1
  589. package/package.json +6 -5
  590. package/dist/command/cli/demo/demo-page.d.ts +0 -78
  591. package/dist/command/cli/demo/demo-page.js +0 -249
  592. package/dist/command/cli/demo/demo-run.d.ts +0 -38
  593. package/dist/command/cli/demo/demo-run.js +0 -138
  594. package/dist/judgement/hunt/hunt-report.d.ts +0 -49
  595. package/dist/judgement/hunt/hunt-report.js +0 -84
  596. package/dist/language/flows/buddy-status.d.ts +0 -25
  597. package/dist/language/flows/buddy-status.js +0 -32
  598. package/dist/language/flows/change/watch-batcher.d.ts +0 -18
  599. package/dist/language/flows/change/watch-batcher.js +0 -19
  600. package/dist/memory/cloud/harness-offer.d.ts +0 -44
  601. package/dist/memory/cloud/harness-offer.js +0 -145
  602. package/dist/surface/tools/feature-capture.d.ts +0 -151
  603. package/dist/surface/tools/feature-capture.js +0 -235
  604. package/dist/surface/tools/tool-hit-rate.d.ts +0 -87
  605. package/dist/surface/tools/tool-hit-rate.js +0 -90
  606. package/dist/telemetry/harness-drive.d.ts +0 -4
  607. package/dist/telemetry/harness-drive.js +0 -35
  608. package/dist/telemetry/identify.d.ts +0 -22
  609. package/dist/telemetry/identify.js +0 -73
  610. package/docs/cli/capsules.mdx +0 -70
  611. package/docs/cli/hunt.mdx +0 -73
  612. package/docs/cli/identify.mdx +0 -76
  613. package/docs/cli/kill.mdx +0 -91
  614. package/docs/cli/watch.mdx +0 -62
@@ -0,0 +1,362 @@
1
+ /**
2
+ * `reticle try <url>`: one free Harness drive of somebody's app, watched in a window, ending in a
3
+ * plain list of which journeys work and which are broken.
4
+ *
5
+ * Sign-in comes first, and on purpose: the drive runs on the platform, so a machine that is not
6
+ * linked could only be told no AFTER a browser had opened, which is the worst moment to say it.
7
+ *
8
+ * The decisions (refuse, ask the platform, drive, summarise, sync) are `runTry`, behind `TryPorts`, so
9
+ * every branch is tested without a browser, a daemon or a network. The verdicts in the summary are the
10
+ * engine's: a journey that neither passed nor failed is "not proved", never rounded up to "works".
11
+ */
12
+ import { existsSync } from 'node:fs';
13
+ import { homedir } from 'node:os';
14
+ import { join } from 'node:path';
15
+ import { RETICLE_DEFAULT_PORT, ReticleDir, ReticleEnv, RunFlowStatus, ScriptStatus, asRecord, driveFlowStatus, } from '@reticlehq/core';
16
+ import { FreeDriveKind, planUrl, requestFreeDrive, } from '../../features/harness/platform/platform-drives.js';
17
+ import { linkedCloudPort, resolveProjectCloud } from '../../memory/cloud/cloud-config.js';
18
+ import { describeUnsynced, unsyncedRoots } from '../../memory/cloud/unsynced-roots.js';
19
+ import { createNodeFileSystem } from '../../memory/project/fs/fs-port.js';
20
+ import { defaultPairingTokenDir, readOrCreatePairingTokenSync, } from '../../portal/bridge/pairing-token.js';
21
+ import { spawnDaemon } from '../daemon/daemon.js';
22
+ import { PortPresence, describePresence, presenceIsUsable, probePresence, } from '../daemon/binding/port-presence.js';
23
+ import { fetchStatus } from '../daemon/binding/daemon-status-probe.js';
24
+ import { probeDaemon, waitForDaemonBind } from '../../surface/mcp/mcp-proxy.js';
25
+ import { readProjectPort } from './ports/resolve/cli-port.js';
26
+ import { callerArtifactRoot } from '../../memory/project/link-directory.js';
27
+ import { seeRunLine } from '../../memory/project/sync-status.js';
28
+ import { DAEMON_INNER_COMMAND, PORT_FLAG } from './cli-parse.js';
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)';
31
+ const PERSONA_FLAG = '--persona';
32
+ /** The whole drive, model turns and browser included, before the CLI stops waiting for it. */
33
+ export const TRY_BUDGET_MS = 120_000;
34
+ /** Model turns in the one free drive. Bounds what it costs, not what it may find. */
35
+ export const TRY_MAX_STEPS = 40;
36
+ /** How long to wait for the daemon to write the drive's run once the tab is closed. */
37
+ const RUN_WRITE_WAIT_MS = 10_000;
38
+ const RUN_WRITE_POLL_MS = 250;
39
+ const EXIT_OK = 0;
40
+ const EXIT_FAIL = 1;
41
+ /** `try <url> [--persona <who>]`, or the sentence that says what is missing. */
42
+ export function parseTryArgs(argv) {
43
+ let url;
44
+ let persona;
45
+ for (let i = 0; i < argv.length; i++) {
46
+ const arg = argv[i];
47
+ if (arg === PERSONA_FLAG) {
48
+ persona = argv[i + 1];
49
+ if (persona === undefined)
50
+ return { error: `${PERSONA_FLAG} needs a value` };
51
+ i++;
52
+ }
53
+ else if (arg !== undefined && arg.startsWith('--')) {
54
+ return { error: `unknown argument '${arg}'` };
55
+ }
56
+ else if (url === undefined) {
57
+ url = arg;
58
+ }
59
+ else {
60
+ return { error: `unknown argument '${String(arg)}'` };
61
+ }
62
+ }
63
+ if (url === undefined)
64
+ return { error: 'usage: reticle try <url> [--persona <who>]' };
65
+ return persona === undefined ? { url } : { url, persona };
66
+ }
67
+ const WORKS = new Set([ScriptStatus.PASSED]);
68
+ const BROKEN = new Set([ScriptStatus.FAILED]);
69
+ /** The summary, worst news last so it is the line a reader's eye lands on. Pure. */
70
+ export function summarizeTry(journeys) {
71
+ // A branch whose condition did not hold was never a journey this app took.
72
+ const tried = journeys.filter((j) => ScriptStatus.NOT_TAKEN !== j.status);
73
+ const works = tried.filter((j) => WORKS.has(j.status)).length;
74
+ const broken = tried.filter((j) => BROKEN.has(j.status)).length;
75
+ const unproved = tried.length - works - broken;
76
+ const head = `Tried ${String(tried.length)} journey${1 === tried.length ? '' : 's'}: ` +
77
+ `${String(works)} work, ${String(broken)} broken` +
78
+ (0 === unproved ? '' : `, ${String(unproved)} not proved`);
79
+ return [
80
+ head,
81
+ ...tried.map((j) => WORKS.has(j.status)
82
+ ? ` ✓ works: ${j.title}`
83
+ : BROKEN.has(j.status)
84
+ ? ` ✗ broken: ${j.title}`
85
+ : ` ? not proved (${j.status}): ${j.title}`),
86
+ ];
87
+ }
88
+ export async function runTry(args, ports) {
89
+ const cloud = await ports.linked();
90
+ if (null === cloud) {
91
+ ports.fail(MSG_SIGN_IN_FIRST);
92
+ return EXIT_FAIL;
93
+ }
94
+ const grant = await ports.requestDrive(cloud);
95
+ if (!grant.granted) {
96
+ ports.fail(grant.message);
97
+ if (grant.hint !== undefined)
98
+ ports.fail(grant.hint);
99
+ if (grant.needsCard) {
100
+ const base = (await ports.dashboardUrl(cloud).catch(() => undefined)) ?? cloud.url;
101
+ ports.fail(`Plans: ${planUrl(base)}`);
102
+ }
103
+ return EXIT_FAIL;
104
+ }
105
+ ports.out(`Driving ${args.url} — watch the window Reticle opens.`);
106
+ const drive = await ports.drive({
107
+ url: args.url,
108
+ driveId: grant.driveId,
109
+ ...(args.persona === undefined ? {} : { persona: args.persona }),
110
+ });
111
+ if (drive.error !== undefined) {
112
+ ports.fail(drive.error);
113
+ return EXIT_FAIL;
114
+ }
115
+ for (const line of summarizeTry(drive.journeys))
116
+ ports.out(line);
117
+ // Saying "saved" over a sync that failed would be this command lying about its own work.
118
+ if (await ports.sync(drive.runIds).catch(() => false)) {
119
+ const dashboard = await ports.dashboardUrl(cloud).catch(() => undefined);
120
+ // Each run on its own page when the dashboard is known; the dashboard itself otherwise.
121
+ const lines = dashboard === undefined || 0 === drive.runIds.length
122
+ ? [`Saved to your dashboard: ${dashboard ?? cloud.url}`]
123
+ : drive.runIds.map((runId) => seeRunLine(dashboard, runId));
124
+ for (const line of lines)
125
+ ports.out(line);
126
+ }
127
+ else {
128
+ ports.fail('The run is kept on this machine; it could not be sent. Run `reticle sync` to retry.');
129
+ }
130
+ return EXIT_OK;
131
+ }
132
+ const str = (value) => ('string' === typeof value ? value : undefined);
133
+ /** The journeys out of an explore report, or one journey graded from the drive when unplanned. */
134
+ export function journeysOf(report, persona) {
135
+ const listed = report['journeys'];
136
+ if (Array.isArray(listed) && 0 < listed.length) {
137
+ return listed.flatMap((item) => {
138
+ const j = item;
139
+ const title = str(j['title']);
140
+ const status = str(j['status']);
141
+ return title === undefined || status === undefined ? [] : [{ title, status }];
142
+ });
143
+ }
144
+ // An unplanned drive is one journey, graded by the one rule every drive is: failed only when a
145
+ // check came back no. A missed goal or undecided checks prove nothing either way.
146
+ const checks = asRecord(report['checks']);
147
+ const count = (key) => ('number' === typeof checks[key] ? checks[key] : 0);
148
+ const goalMet = report['goalMet'];
149
+ const flow = driveFlowStatus({
150
+ held: count('held'),
151
+ failed: count('failed'),
152
+ ...('boolean' === typeof goalMet ? { goalMet } : {}),
153
+ });
154
+ const status = RunFlowStatus.FAIL === flow
155
+ ? ScriptStatus.FAILED
156
+ : RunFlowStatus.PASS === flow
157
+ ? ScriptStatus.PASSED
158
+ : ScriptStatus.BLOCKED;
159
+ return [{ title: persona ?? 'Autonomous drive', status }];
160
+ }
161
+ function tryPort(cwd) {
162
+ const fromEnv = Number(process.env[ReticleEnv.PORT]);
163
+ if (Number.isInteger(fromEnv) && 0 < fromEnv)
164
+ return fromEnv;
165
+ return readProjectPort(cwd) ?? RETICLE_DEFAULT_PORT;
166
+ }
167
+ /** A daemon serving `port`: the one already there, or one started now. Undefined when ready. */
168
+ async function ensureTryDaemon(port) {
169
+ const presence = await probePresence(port, { tcpOpen: probeDaemon, status: fetchStatus });
170
+ if (presenceIsUsable(presence))
171
+ return undefined;
172
+ // A stranger on the port: a daemon spawned now could not bind, so say who holds it instead.
173
+ if (PortPresence.FREE !== presence)
174
+ return describePresence(presence, port);
175
+ const script = process.argv[1];
176
+ if (script === undefined)
177
+ return 'Cannot locate the reticle daemon script.';
178
+ spawnDaemon(process.execPath, script, [DAEMON_INNER_COMMAND, PORT_FLAG, String(port)], port);
179
+ return (await waitForDaemonBind(port))
180
+ ? undefined
181
+ : `Could not start the Reticle daemon on port ${String(port)}.`;
182
+ }
183
+ /** The drive itself, through the daemon: a watched window, the zero-install reader, one explore. */
184
+ async function driveThroughDaemon(port, request,
185
+ /** Where the drive's run must land: the folder `try` waits on and pushes from. */
186
+ reticleRoot) {
187
+ const unavailable = await ensureTryDaemon(port);
188
+ if (unavailable !== undefined)
189
+ return { journeys: [], runIds: [], error: unavailable };
190
+ const token = readOrCreatePairingTokenSync(defaultPairingTokenDir());
191
+ const caller = await connectOverSse(endpointFor(port, token));
192
+ try {
193
+ // Headed whatever the daemon was started as: the point of `try` is watching it happen. An app
194
+ // with no Reticle SDK gets one supplied by the lease.
195
+ const opened = await acquireLease(caller, request.url, true, reticleRoot);
196
+ if ('failed' in opened)
197
+ return { journeys: [], runIds: [], error: opened.failed.join('\n') };
198
+ try {
199
+ const drove = await exploreToEnd(caller, {
200
+ sessionId: opened.leased,
201
+ driveId: request.driveId,
202
+ maxSteps: TRY_MAX_STEPS,
203
+ ...(request.persona === undefined ? {} : { persona: request.persona }),
204
+ }, TRY_BUDGET_MS);
205
+ const refusal = refusalText(drove);
206
+ if (refusal !== undefined)
207
+ return { journeys: [], runIds: [], error: refusal };
208
+ const report = verdictOf(drove, 'stopReason') ?? {};
209
+ const runIds = Array.isArray(report['runIds'])
210
+ ? report['runIds'].filter((id) => 'string' === typeof id)
211
+ : [];
212
+ const broke = str(report['error']);
213
+ return {
214
+ journeys: journeysOf(report, request.persona),
215
+ runIds,
216
+ ...(broke === undefined ? {} : { error: `The drive broke: ${broke}` }),
217
+ };
218
+ }
219
+ finally {
220
+ // Closing the tab is what ends the session, and the session's end is what writes the run.
221
+ await releaseLease(caller, opened.leased);
222
+ }
223
+ }
224
+ finally {
225
+ await caller.close().catch(() => undefined);
226
+ }
227
+ }
228
+ /** Wait, bounded, for the daemon to write the drive's runs; a run that never lands is not sent. */
229
+ async function waitForRuns(reticleRoot, runIds) {
230
+ const runsDir = join(reticleRoot, ReticleDir.RUNS_SUBDIR);
231
+ for (let waited = 0; waited < RUN_WRITE_WAIT_MS; waited += RUN_WRITE_POLL_MS) {
232
+ if (runIds.every((id) => existsSync(join(runsDir, `${id}.json`))))
233
+ return;
234
+ await new Promise((resolve) => setTimeout(resolve, RUN_WRITE_POLL_MS));
235
+ }
236
+ }
237
+ /** `reticle try`, wired to this machine. Returns the exit code. */
238
+ export async function cmdTry(argv, cloudCommands) {
239
+ const parsed = parseTryArgs(argv);
240
+ if ('error' in parsed) {
241
+ process.stderr.write(`${parsed.error}\n`);
242
+ return EXIT_FAIL;
243
+ }
244
+ const cwd = process.cwd();
245
+ // The project this folder belongs to, else this folder: the lease writes the run here, and this is
246
+ // where try waits for it and pushes it from — wherever the daemon happened to be started.
247
+ const reticleRoot = callerArtifactRoot(cwd) ?? join(cwd, ReticleDir.ROOT);
248
+ const port = tryPort(cwd);
249
+ return runTry(parsed, {
250
+ linked: linkedCloudPort(createNodeFileSystem(), reticleRoot, homedir(), process.env),
251
+ requestDrive: (cloud) => requestFreeDrive(cloud, FreeDriveKind.TRY),
252
+ drive: (request) => driveThroughDaemon(port, request, reticleRoot),
253
+ sync: async (runIds) => {
254
+ await waitForRuns(reticleRoot, runIds);
255
+ return EXIT_OK === (await cloudCommands.push());
256
+ },
257
+ dashboardUrl: cloudCommands.dashboardUrl,
258
+ out: (line) => process.stdout.write(`${line}\n`),
259
+ fail: (line) => process.stderr.write(`${line}\n`),
260
+ });
261
+ }
262
+ // ── how `init` ends ───────────────────────────────────────────────────────────────────────
263
+ /**
264
+ * How `init` ends once the connection is proved: what Reticle sees of the app, what it is missing,
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.
268
+ *
269
+ * Read from the daemon's `/status`, the same coverage `doctor` prints, so the two never disagree.
270
+ */
271
+ /** What a project that is not linked is told, once, at the end. */
272
+ export const UNLINKED_PITCH = [
273
+ '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.',
275
+ ];
276
+ /** Prove one flow with the coding agent: the line every ending names. */
277
+ export const msgProveOneFlow = (url) => `Then ask your coding agent: "Use Reticle to prove one flow in ${url}: drive it, and end with ` +
278
+ 'reticle_act_and_wait and an until on the last step."';
279
+ const names = (value) => Array.isArray(value)
280
+ ? value.flatMap((item) => {
281
+ const name = 'object' === typeof item && null !== item
282
+ ? item['capability']
283
+ : item;
284
+ return 'string' === typeof name ? [name] : [];
285
+ })
286
+ : [];
287
+ /**
288
+ * 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.
290
+ */
291
+ export function initCoverageLines(tab, url) {
292
+ const gate = asRecord(tab?.['harnessGate']);
293
+ const percent = gate['percent'];
294
+ if (tab === undefined || 'number' !== typeof percent)
295
+ return [
296
+ 'Instrumentation is measured on an open tab of the app: run `reticle doctor` with it open.',
297
+ msgProveOneFlow(url),
298
+ ];
299
+ const unseen = [...names(tab['missing']), ...names(tab['notSeenYet'])];
300
+ const reason = gate['reason'];
301
+ const prompt = tab['prompt'];
302
+ return [
303
+ `Instrumentation: ${String(percent)}%` +
304
+ (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.`,
308
+ ...('string' === typeof prompt
309
+ ? [
310
+ 'Paste this into your coding agent; it closes the gaps and proves the first flow:',
311
+ ...prompt.split('\n').map((line) => ` ${line}`),
312
+ ]
313
+ : [msgProveOneFlow(url)]),
314
+ ];
315
+ }
316
+ /** The project's own `.reticle`, where the drive's flow and run land and where its link lives. */
317
+ const projectRoot = (appDir) => callerArtifactRoot(appDir) ?? join(appDir, ReticleDir.ROOT);
318
+ /**
319
+ * This project's runs and flows that will never reach the dashboard as things stand, one line each:
320
+ * not linked, no key for its host, flow sync off, or refused. A linked root's pending runs are left
321
+ * out, because the daemon sends them within seconds and saying so would be noise.
322
+ */
323
+ export async function strandedWorkLines(appDir) {
324
+ const fs = createNodeFileSystem();
325
+ const cloud = () => resolveProjectCloud(fs, projectRoot(appDir), homedir(), process.env);
326
+ const roots = await unsyncedRoots([projectRoot(appDir)], async () => {
327
+ const c = await cloud();
328
+ return null !== c.config && null !== c.projectId;
329
+ }, async () => (await cloud()).policy.flows);
330
+ return roots
331
+ .filter((entry) => !entry.linked || 0 < entry.flows)
332
+ .map((entry) => `⚠ ${describeUnsynced(entry, appDir)}`);
333
+ }
334
+ /** The tab `init` proved, out of `/status`: by session, else the only one on the same url. */
335
+ function tabIn(status, sessionId, url) {
336
+ const list = asRecord(status)['coverage'];
337
+ if (!Array.isArray(list))
338
+ return undefined;
339
+ const tabs = list.map((entry) => asRecord(entry));
340
+ return (tabs.find((tab) => sessionId === tab['sessionId']) ??
341
+ tabs.find((tab) => 'string' === typeof tab['url'] && tab['url'].startsWith(url)));
342
+ }
343
+ /**
344
+ * How `init` ends: the coverage score, the gaps and the agent prompt, the pitch when the project is
345
+ * not linked, then what will never reach the dashboard. Nothing is driven. Never throws.
346
+ */
347
+ export async function initFirstFlow(ctx, say) {
348
+ if (ctx.firstRun) {
349
+ // A leased proof's tab has closed; another open tab of the same app still answers for it.
350
+ const status = await fetchStatus(ctx.bridgePort).catch(() => undefined);
351
+ say('');
352
+ for (const line of initCoverageLines(tabIn(status, ctx.sessionId, ctx.url), ctx.url))
353
+ say(line);
354
+ const linked = linkedCloudPort(createNodeFileSystem(), projectRoot(ctx.appDir), homedir(), process.env);
355
+ if (null === (await linked().catch(() => null)))
356
+ for (const line of UNLINKED_PITCH)
357
+ say(line);
358
+ }
359
+ for (const line of await strandedWorkLines(ctx.appDir).catch(() => []))
360
+ say(line);
361
+ return { flowSaved: false };
362
+ }
@@ -1,19 +1,3 @@
1
- /**
2
- * The tutorial: one sequence, two audiences.
3
- *
4
- * A human wants to know what to do next and why it is worth doing. An agent wants the exact call and
5
- * the exact shape of the answer, because prose it has to interpret is a turn it has to spend. Write
6
- * for one and hope the other copes, and you get a page agents skip and humans skim.
7
- *
8
- * What both MUST share is the order. Two audiences taking different routes through one product is
9
- * how a support answer stops matching what anybody actually did.
10
- *
11
- * The sequence is not arbitrary either. It ends at a VERDICT because a tour that ends at "you can see
12
- * the page now" has taught the least valuable half: looking is not verifying, and an agent that
13
- * learns only to look will report that it looked. And it declares the consequence BEFORE acting,
14
- * because that ordering IS the idea — naming what should happen first is the difference between a
15
- * check and a rationalisation written afterwards.
16
- */
17
1
  import { type OnboardingStep } from '@reticlehq/core/telemetry';
18
2
  /**
19
3
  * The two ONBOARD steps a SHOWN tour can honestly answer.
@@ -30,87 +14,3 @@ import { type OnboardingStep } from '@reticlehq/core/telemetry';
30
14
  * which is the only place they are a fact.
31
15
  */
32
16
  export declare function tutorialShownSteps(): OnboardingStep[];
33
- export declare const TutorialAudience: {
34
- /** Prose, and a reason per step. */
35
- readonly HUMAN: "human";
36
- /** The call, and what comes back. */
37
- readonly AGENT: "agent";
38
- };
39
- export type TutorialAudience = (typeof TutorialAudience)[keyof typeof TutorialAudience];
40
- export interface TutorialStep {
41
- id: string;
42
- /** What this step is, in words. Always present: an agent reading only calls learns the what, not the why. */
43
- say: string;
44
- /** Why it is worth doing. The half that stops a tutorial being a list of keystrokes. */
45
- why: string;
46
- /** The exact call, for the audience that would otherwise have to infer it from the prose. */
47
- call?: string;
48
- }
49
- /**
50
- * The same steps, shaped for who is reading.
51
- *
52
- * The agent form keeps the prose as well as the call. An agent that has only the call learns what to
53
- * type and not what it means, which is exactly the reader that later reports a green it cannot
54
- * explain.
55
- */
56
- export declare function tutorialScript(audience: TutorialAudience): TutorialStep[];
57
- /**
58
- * The script as text for whoever asked.
59
- *
60
- * A human gets the reason on its own line, because the reason is what makes the step worth doing and
61
- * a list of commands without them is a keystroke tour. An agent gets the call, because prose it has
62
- * to interpret is a turn it has to spend — and it gets the prose too, since an agent that has only
63
- * the call learns what to type and not what it means, which is the reader that later reports a green
64
- * it cannot explain.
65
- */
66
- /**
67
- * What to do now the tour is over.
68
- *
69
- * Every other stage of setup ends by naming the next command — `install.sh` points at `reticle init`
70
- * and this tutorial, `init` points at the dev server and `status`. This one ended at step 4 and
71
- * stopped, so the stage whose entire job is to teach the sequence was the only one that never said
72
- * how to start it. The steps above describe tools that need an instrumented, running app, and a
73
- * reader who has just been told that a verdict is the point and shown no way to reach one is exactly
74
- * where a funnel stalls.
75
- *
76
- * Split from `renderTutorial` so the closing block is a value a caller can assert on, rather than a
77
- * string only findable by matching rendered prose.
78
- */
79
- export declare function tutorialNextSteps(audience: TutorialAudience, restartAgent?: boolean): string;
80
- /**
81
- * What the installer prints when it has finished.
82
- *
83
- * Installation and onboarding are ONE script, so the tour is not conditional on anything. Gating it
84
- * on `process.stdout.isTTY` does not work: that is `undefined` through every pipe, so the tour never
85
- * prints. A heuristic that silently answers "nobody is watching" is worse than no heuristic.
86
- *
87
- * It ends with the tour's OWN closing. Installing changes no project: the app is wired the first time
88
- * an agent uses Reticle in it (see first-run-wiring.ts).
89
- */
90
- export declare function installClosing(registered?: boolean): string;
91
- export declare function renderTutorial(audience: TutorialAudience): string;
92
- export type DemoPlan = {
93
- ok: true;
94
- ref: string;
95
- name: string;
96
- call: string;
97
- } | {
98
- ok: false;
99
- because: string;
100
- };
101
- /**
102
- * Pick something safe on THIS page, and build the call that proves it moved.
103
- *
104
- * The sequence is the tutorial's; what this adds is a target from the app actually in front of the
105
- * user, because a walkthrough against a fixture teaches the fixture. The consequence is declared in
106
- * the call rather than checked afterwards — a demo that ends without a verdict would teach the exact
107
- * habit the tutorial exists to correct.
108
- *
109
- * Refusing is a real outcome. A page with nothing safe on it gets told so, because demonstrating on
110
- * "Delete account" to avoid an awkward message is not a trade anybody would make deliberately.
111
- */
112
- export declare function demoPlan(controls: readonly {
113
- ref: string;
114
- name: string;
115
- role?: string;
116
- }[]): DemoPlan;
@@ -1,34 +1,4 @@
1
- /**
2
- * The tutorial: one sequence, two audiences.
3
- *
4
- * A human wants to know what to do next and why it is worth doing. An agent wants the exact call and
5
- * the exact shape of the answer, because prose it has to interpret is a turn it has to spend. Write
6
- * for one and hope the other copes, and you get a page agents skip and humans skim.
7
- *
8
- * What both MUST share is the order. Two audiences taking different routes through one product is
9
- * how a support answer stops matching what anybody actually did.
10
- *
11
- * The sequence is not arbitrary either. It ends at a VERDICT because a tour that ends at "you can see
12
- * the page now" has taught the least valuable half: looking is not verifying, and an agent that
13
- * learns only to look will report that it looked. And it declares the consequence BEFORE acting,
14
- * because that ordering IS the idea — naming what should happen first is the difference between a
15
- * check and a rationalisation written afterwards.
16
- */
17
1
  import { OnboardingPhase, OnboardingStepStatus, } from '@reticlehq/core/telemetry';
18
- import { TOUR_STEPS } from '@reticlehq/core/tour';
19
- /**
20
- * The steps, from the one place both surfaces read them.
21
- *
22
- * They used to be a private array here, which is why the browser could not render the same tour:
23
- * nothing outside this package could see them. `title` and `anchor` are the carousel's business and
24
- * a terminal ignores them.
25
- */
26
- const STEPS = TOUR_STEPS.map((s) => ({
27
- id: s.id,
28
- say: s.say,
29
- why: s.why,
30
- ...(undefined === s.call ? {} : { call: s.call }),
31
- }));
32
2
  /**
33
3
  * The two ONBOARD steps a SHOWN tour can honestly answer.
34
4
  *
@@ -50,151 +20,3 @@ export function tutorialShownSteps() {
50
20
  status: OnboardingStepStatus.COMPLETED,
51
21
  }));
52
22
  }
53
- export const TutorialAudience = {
54
- /** Prose, and a reason per step. */
55
- HUMAN: 'human',
56
- /** The call, and what comes back. */
57
- AGENT: 'agent',
58
- };
59
- /**
60
- * The same steps, shaped for who is reading.
61
- *
62
- * The agent form keeps the prose as well as the call. An agent that has only the call learns what to
63
- * type and not what it means, which is exactly the reader that later reports a green it cannot
64
- * explain.
65
- */
66
- export function tutorialScript(audience) {
67
- return STEPS.map((step) => TutorialAudience.AGENT === audience
68
- ? { ...step, call: step.call ?? '' }
69
- : // A human is not handed a raw call to paste without understanding it; the prose carries it.
70
- { id: step.id, say: step.say, why: step.why });
71
- }
72
- /**
73
- * The script as text for whoever asked.
74
- *
75
- * A human gets the reason on its own line, because the reason is what makes the step worth doing and
76
- * a list of commands without them is a keystroke tour. An agent gets the call, because prose it has
77
- * to interpret is a turn it has to spend — and it gets the prose too, since an agent that has only
78
- * the call learns what to type and not what it means, which is the reader that later reports a green
79
- * it cannot explain.
80
- */
81
- /**
82
- * What to do now the tour is over.
83
- *
84
- * Every other stage of setup ends by naming the next command — `install.sh` points at `reticle init`
85
- * and this tutorial, `init` points at the dev server and `status`. This one ended at step 4 and
86
- * stopped, so the stage whose entire job is to teach the sequence was the only one that never said
87
- * how to start it. The steps above describe tools that need an instrumented, running app, and a
88
- * reader who has just been told that a verdict is the point and shown no way to reach one is exactly
89
- * where a funnel stalls.
90
- *
91
- * Split from `renderTutorial` so the closing block is a value a caller can assert on, rather than a
92
- * string only findable by matching rendered prose.
93
- */
94
- export function tutorialNextSteps(audience, restartAgent = false) {
95
- const lines = TutorialAudience.AGENT === audience
96
- ? [
97
- 'Next:',
98
- ' reticle_session list # the first call wires this project: Reticle runs init itself',
99
- ' # and names every file it changed — tell the user which',
100
- ' then run the four steps above against it, and report the verdict',
101
- ]
102
- : [
103
- 'Next:',
104
- ...(restartAgent
105
- ? [' restart your agent # it loads new tools only when it starts']
106
- : []),
107
- '',
108
- // One line: the terminal wraps it at the reader's width, not ours.
109
- 'Ask your agent to verify one real flow in your project. Nothing in your app changed at install: the first time the agent uses Reticle there, Reticle wires the app, starts it, and tells you which files it changed.',
110
- ];
111
- return lines.join('\n');
112
- }
113
- /**
114
- * What the installer prints when it has finished.
115
- *
116
- * Installation and onboarding are ONE script, so the tour is not conditional on anything. Gating it
117
- * on `process.stdout.isTTY` does not work: that is `undefined` through every pipe, so the tour never
118
- * prints. A heuristic that silently answers "nobody is watching" is worse than no heuristic.
119
- *
120
- * It ends with the tour's OWN closing. Installing changes no project: the app is wired the first time
121
- * an agent uses Reticle in it (see first-run-wiring.ts).
122
- */
123
- export function installClosing(registered = true) {
124
- // One line a step. The reasons are for `reticle tutorial`; right after an install they turned a
125
- // four-step idea into twenty-five lines of prose between the reader and the next command.
126
- const steps = tutorialScript(TutorialAudience.HUMAN).map((step, index) => ` ${String(index + 1)}. ${INSTALL_SAYS[step.id] ?? step.say}`);
127
- return [
128
- '',
129
- '✓ Reticle is installed. How it works:',
130
- ...steps,
131
- '',
132
- tutorialNextSteps(TutorialAudience.HUMAN, registered),
133
- ].join('\n');
134
- }
135
- /**
136
- * Tour steps reworded for a reader who has no app wired yet. The in-app tour's "That panel is
137
- * Reticle" points at a panel on screen; straight after an install there is none to point at.
138
- */
139
- const INSTALL_SAYS = {
140
- connect: 'The first time your agent uses Reticle in a project, it wires the app and a Reticle panel appears in it: your proof the SDK is connected.',
141
- };
142
- export function renderTutorial(audience) {
143
- const steps = tutorialScript(audience)
144
- .map((step, index) => {
145
- const head = `${String(index + 1)}. ${step.say}`;
146
- const why = ` why: ${step.why}`;
147
- return step.call === undefined || 0 === step.call.length
148
- ? `${head}\n${why}`
149
- : `${head}\n${why}\n ${step.call}`;
150
- })
151
- .join('\n\n');
152
- return `${steps}\n\n${tutorialNextSteps(audience)}`;
153
- }
154
- /**
155
- * Names that must never be demonstrated on.
156
- *
157
- * Deliberately broad, and deliberately matched on the NAME a user reads rather than on anything
158
- * structural. A demo runs unattended against an app whose author has never seen this code, so the
159
- * cost of being wrong is asymmetric: refusing a harmless button wastes a demo, clicking a harmful
160
- * one costs somebody their data. When those are the two errors available, take the first one every
161
- * time.
162
- *
163
- * `cancel` is here for the case that reads backwards: "Cancel subscription" is destructive, and a
164
- * word-boundary match on a dismissive "Cancel" would be a false refusal — which is the cheap error.
165
- */
166
- const UNSAFE_TO_DEMO = /delete|remove|deploy|publish|pay|purchase|buy|checkout|cancel|revoke|archive|reset|destroy|drop|send|submit|confirm/i;
167
- /**
168
- * Pick something safe on THIS page, and build the call that proves it moved.
169
- *
170
- * The sequence is the tutorial's; what this adds is a target from the app actually in front of the
171
- * user, because a walkthrough against a fixture teaches the fixture. The consequence is declared in
172
- * the call rather than checked afterwards — a demo that ends without a verdict would teach the exact
173
- * habit the tutorial exists to correct.
174
- *
175
- * Refusing is a real outcome. A page with nothing safe on it gets told so, because demonstrating on
176
- * "Delete account" to avoid an awkward message is not a trade anybody would make deliberately.
177
- */
178
- export function demoPlan(controls) {
179
- const safe = controls.find((c) => !UNSAFE_TO_DEMO.test(c.name));
180
- if (safe === undefined) {
181
- return {
182
- ok: false,
183
- because: 0 === controls.length
184
- ? 'nothing interactive is on this page yet — load the app and try again'
185
- : 'no control here is safe to demonstrate on: every one reads as something that commits. ' +
186
- 'Drive it yourself with a consequence you choose.',
187
- };
188
- }
189
- return {
190
- ok: true,
191
- ref: safe.ref,
192
- name: safe.name,
193
- // `{ element: { testid } }` reads naturally and is REFUSED: a consequence is a predicate with a
194
- // `kind`, and act_and_wait says so in its own refusal text. This line is a call the reader is
195
- // meant to paste, so a plausible-but-unparseable spelling here teaches the exact mistake that
196
- // tool exists to catch.
197
- call: `reticle_act_and_wait { ref: "${safe.ref}", action: "click", ` +
198
- `until: { kind: "element", by: "testid", value: "<what should appear>" } }`,
199
- };
200
- }
@@ -0,0 +1,19 @@
1
+ /**
2
+ * `reticle verify --results-json <file>`: the run, one line per journey, for a machine to read.
3
+ *
4
+ * The rendered report is for a person, and a CI step that has to post per-journey verdicts somewhere
5
+ * else would otherwise scrape it. Three words only, the engine's own: a skipped flow is `unknown`,
6
+ * never rounded up to `yes`, and the run is `yes` only when every journey is.
7
+ */
8
+ import { Verified, type ReticleVerificationRun } from '@reticlehq/core';
9
+ type JourneyVerdict = typeof Verified.YES | typeof Verified.NO | typeof Verified.UNKNOWN;
10
+ export interface VerifyResults {
11
+ verdict: JourneyVerdict;
12
+ results: {
13
+ journey: string;
14
+ verdict: JourneyVerdict;
15
+ reason?: string;
16
+ }[];
17
+ }
18
+ export declare function verifyResults(run: ReticleVerificationRun): VerifyResults;
19
+ export {};