@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.
- package/SKILL.md +59 -68
- package/bin/reticle.js +9 -2
- package/dist/command/cli/adhoc-suite.js +1 -1
- package/dist/command/cli/adhoc-verdict.d.ts +12 -0
- package/dist/command/cli/adhoc-verdict.js +62 -4
- package/dist/command/cli/answers/gate-hook-message.d.ts +2 -0
- package/dist/command/cli/answers/gate-hook-message.js +5 -1
- package/dist/command/cli/auth/cloud-session.d.ts +11 -19
- package/dist/command/cli/auth/cloud-session.js +23 -0
- package/dist/command/cli/auth/device-flow.d.ts +3 -37
- package/dist/command/cli/cli-doctor.js +66 -21
- package/dist/command/cli/cli-flow-commands.js +53 -11
- package/dist/command/cli/cli-kill.d.ts +8 -0
- package/dist/command/cli/cli-kill.js +43 -3
- package/dist/command/cli/cli-parse-feedback.d.ts +4 -0
- package/dist/command/cli/cli-parse-feedback.js +13 -1
- package/dist/command/cli/cli-parse-grammar.d.ts +1 -2
- package/dist/command/cli/cli-parse-grammar.js +1 -6
- package/dist/command/cli/cli-parse-serve.d.ts +24 -0
- package/dist/command/cli/cli-parse-serve.js +124 -0
- package/dist/command/cli/cli-parse.d.ts +12 -11
- package/dist/command/cli/cli-parse.js +100 -123
- package/dist/command/cli/cli-usage.d.ts +0 -11
- package/dist/command/cli/cli-usage.js +43 -16
- package/dist/command/cli/cli-verify.d.ts +1 -1
- package/dist/command/cli/cli-verify.js +29 -14
- package/dist/command/cli/cloud-cli.js +27 -9
- package/dist/command/cli/cloud-kit.js +3 -3
- package/dist/command/cli/cloud-link.d.ts +1 -20
- package/dist/command/cli/cloud-link.js +2 -0
- package/dist/command/cli/cloud-login.d.ts +6 -2
- package/dist/command/cli/cloud-login.js +13 -41
- package/dist/command/cli/config/checkout.d.ts +10 -0
- package/dist/command/cli/config/checkout.js +78 -0
- package/dist/command/cli/doctor/doctor-agent-link.d.ts +23 -0
- package/dist/command/cli/doctor/doctor-agent-link.js +28 -0
- package/dist/command/cli/doctor/doctor-coverage-line.js +1 -7
- package/dist/command/cli/doctor/doctor-rows.d.ts +4 -0
- package/dist/command/cli/doctor/doctor-rows.js +4 -0
- package/dist/command/cli/drive/drive-attach.d.ts +5 -0
- package/dist/command/cli/drive/drive-attach.js +21 -1
- package/dist/command/cli/hook/codex-transcript.d.ts +20 -0
- package/dist/command/cli/hook/codex-transcript.js +224 -0
- package/dist/command/cli/hook/episode-structure.d.ts +24 -0
- package/dist/command/cli/hook/episode-structure.js +138 -0
- package/dist/command/cli/hook/hook-command.d.ts +9 -0
- package/dist/command/cli/hook/hook-command.js +211 -0
- package/dist/command/cli/hook/hook-fast.d.ts +31 -0
- package/dist/command/cli/hook/hook-fast.js +136 -0
- package/dist/command/cli/hook/prompt-hook.d.ts +30 -0
- package/dist/command/cli/hook/prompt-hook.js +199 -0
- package/dist/command/cli/hook/tool-hook.d.ts +21 -0
- package/dist/command/cli/hook/tool-hook.js +259 -0
- package/dist/command/cli/launch/cli-launch.d.ts +2 -0
- package/dist/command/cli/launch/cli-launch.js +22 -2
- package/dist/command/cli/lifecycle/daemon-lifecycle.js +28 -2
- package/dist/command/cli/mcp-command.d.ts +9 -0
- package/dist/command/cli/mcp-command.js +127 -41
- package/dist/command/cli/open-navigate.d.ts +43 -0
- package/dist/command/cli/open-navigate.js +85 -0
- package/dist/command/cli/ports/port-holder.d.ts +16 -4
- package/dist/command/cli/ports/port-holder.js +58 -12
- package/dist/command/cli/ports/resolve/cli-port.js +18 -2
- package/dist/command/cli/project-name.d.ts +1 -7
- package/dist/command/cli/project-name.js +1 -0
- package/dist/command/cli/report-command.d.ts +8 -2
- package/dist/command/cli/report-command.js +95 -18
- package/dist/command/cli/status-fields.d.ts +9 -2
- package/dist/command/cli/status-fields.js +148 -4
- package/dist/command/cli/try-command.d.ts +3 -4
- package/dist/command/cli/try-command.js +6 -11
- package/dist/command/cli/verify-results.d.ts +4 -1
- package/dist/command/cli/verify-results.js +3 -1
- package/dist/command/cli.d.ts +1 -7
- package/dist/command/cli.js +79 -160
- package/dist/command/daemon/daemon-resilience.d.ts +6 -1
- package/dist/command/daemon/daemon-resilience.js +31 -18
- package/dist/command/daemon/daemon.d.ts +11 -0
- package/dist/command/daemon/daemon.js +70 -2
- package/dist/command/daemon/lifetime/daemon-usefulness.d.ts +2 -0
- package/dist/command/daemon/lifetime/daemon-usefulness.js +13 -2
- package/dist/command/daemon/wake-decision.js +4 -2
- package/dist/command/daemon/win32-escape.d.ts +32 -0
- package/dist/command/daemon/win32-escape.js +119 -0
- package/dist/command/setup/agent-configs.d.ts +9 -0
- package/dist/command/setup/agent-configs.js +9 -0
- package/dist/command/setup/auto-approve.d.ts +10 -3
- package/dist/command/setup/auto-approve.js +51 -3
- package/dist/command/setup/bringup/dev-server-files.d.ts +1 -9
- package/dist/command/setup/bringup/dev-server-wait.js +5 -1
- package/dist/command/setup/bringup/ensure-daemon.js +4 -7
- package/dist/command/setup/init/init-host.js +6 -0
- package/dist/command/setup/init/init-port.js +5 -4
- package/dist/command/setup/init/init-runtime.js +7 -1
- package/dist/command/setup/node-effects.d.ts +8 -0
- package/dist/command/setup/node-effects.js +36 -4
- package/dist/command/setup/probe/dev-port.d.ts +26 -0
- package/dist/command/setup/probe/dev-port.js +117 -0
- package/dist/command/setup/probe/page-probe.d.ts +1 -1
- package/dist/command/setup/probe/page-probe.js +11 -3
- package/dist/command/setup/remaining-steps.d.ts +0 -7
- package/dist/command/setup/remaining-steps.js +3 -2
- package/dist/command/setup/run-setup.d.ts +11 -0
- package/dist/command/setup/run-setup.js +33 -5
- package/dist/command/setup/setup-command.d.ts +2 -0
- package/dist/command/setup/setup-command.js +22 -4
- package/dist/command/update/updater.d.ts +1 -6
- package/dist/command/update/updater.js +4 -5
- package/dist/command/update/version-seen.d.ts +24 -0
- package/dist/command/update/version-seen.js +65 -0
- package/dist/command/version/peer-announce.d.ts +9 -1
- package/dist/command/version/peer-announce.js +25 -2
- package/dist/command/version/sdk-fix.d.ts +5 -6
- package/dist/command/version/sdk-fix.js +17 -32
- package/dist/command/version/version-skew.d.ts +16 -1
- package/dist/command/version/version-skew.js +84 -10
- package/dist/features/crawl/crawl-tools.js +2 -2
- package/dist/features/crawl/crawl.js +2 -0
- package/dist/features/exhaust/ledger.d.ts +15 -96
- package/dist/features/exhaust/ledger.js +3 -3
- package/dist/features/harness/drive-runs.d.ts +28 -4
- package/dist/features/harness/drive-runs.js +99 -7
- package/dist/features/harness/drivers.d.ts +1 -1
- package/dist/features/harness/drivers.js +1 -1
- package/dist/features/harness/harness.d.ts +5 -0
- package/dist/features/harness/harness.js +24 -12
- package/dist/features/harness/platform/platform-drives.d.ts +7 -1
- package/dist/features/harness/platform/platform-drives.js +12 -7
- package/dist/features/harness/platform/refusal.d.ts +1 -1
- package/dist/features/harness/platform/refusal.js +4 -4
- package/dist/features/harness/platform/remote-drive.js +70 -28
- package/dist/features/harness/platform/server-driver.js +22 -1
- package/dist/features/harness/platform-config.d.ts +1 -10
- package/dist/features/harness/platform-config.js +0 -20
- package/dist/features/license/license.d.ts +2 -14
- package/dist/features/visual/step-shots.d.ts +33 -1
- package/dist/features/visual/step-shots.js +155 -1
- package/dist/features/visual/visual-tools.js +12 -4
- package/dist/hooks/coding-agents.d.ts +6 -0
- package/dist/hooks/coding-agents.js +24 -3
- package/dist/hooks/episode-stamp.d.ts +32 -0
- package/dist/hooks/episode-stamp.js +61 -0
- package/dist/hooks/hook-commands.js +19 -9
- package/dist/index.d.ts +5 -1
- package/dist/index.js +66 -24
- package/dist/judgement/app-graph/journal-steps.d.ts +8 -0
- package/dist/judgement/app-graph/journal-steps.js +92 -0
- package/dist/judgement/capsule/capsule-store.d.ts +2 -39
- package/dist/judgement/domain/domain-model.js +1 -10
- package/dist/judgement/domain/domain-tools.js +4 -2
- package/dist/judgement/runs/artifact/run-store.d.ts +28 -8
- package/dist/judgement/runs/artifact/run-store.js +153 -28
- package/dist/judgement/runs/default-run-id.d.ts +3 -1
- package/dist/judgement/runs/default-run-id.js +15 -3
- package/dist/judgement/runs/drive-run.d.ts +3 -3
- package/dist/judgement/runs/drive-run.js +11 -7
- package/dist/judgement/runs/run-ledger.d.ts +21 -0
- package/dist/judgement/runs/run-ledger.js +143 -0
- package/dist/judgement/runs/runner-port.d.ts +1 -1
- package/dist/judgement/runs/runner-port.js +8 -2
- package/dist/judgement/runs/verification-sync.d.ts +4 -3
- package/dist/judgement/runs/verification-sync.js +27 -5
- package/dist/language/flows/affected-tools.js +2 -1
- package/dist/language/flows/annotate-notes/annotate.js +8 -3
- package/dist/language/flows/annotate-tools.js +1 -1
- package/dist/language/flows/change/affected.d.ts +8 -0
- package/dist/language/flows/change/affected.js +20 -7
- package/dist/language/flows/decision.js +19 -4
- package/dist/language/flows/fields/flow-secret-field.d.ts +9 -0
- package/dist/language/flows/fields/flow-secret-field.js +67 -5
- package/dist/language/flows/flow-anchor.d.ts +5 -0
- package/dist/language/flows/flow-anchor.js +4 -0
- package/dist/language/flows/flow-cross-step.d.ts +7 -1
- package/dist/language/flows/flow-cross-step.js +9 -0
- package/dist/language/flows/flow-expect-grammar.js +15 -10
- package/dist/language/flows/flow-intent.js +6 -1
- package/dist/language/flows/flow-journey.d.ts +8 -0
- package/dist/language/flows/flow-journey.js +13 -0
- package/dist/language/flows/flow-lease.d.ts +27 -0
- package/dist/language/flows/flow-lease.js +59 -0
- package/dist/language/flows/flow-replay-run.d.ts +1 -87
- package/dist/language/flows/flow-replay-run.js +111 -310
- package/dist/language/flows/flow-replay.js +21 -19
- package/dist/language/flows/flow-replayable.d.ts +38 -0
- package/dist/language/flows/flow-replayable.js +179 -0
- package/dist/language/flows/flow-start-path.d.ts +108 -0
- package/dist/language/flows/flow-start-path.js +313 -0
- package/dist/language/flows/flow-step-runners.d.ts +23 -2
- package/dist/language/flows/flow-step-runners.js +191 -32
- package/dist/language/flows/flow-store-for-session.d.ts +8 -1
- package/dist/language/flows/flow-store-for-session.js +6 -0
- package/dist/language/flows/flow-tools.d.ts +2 -23
- package/dist/language/flows/flow-tools.js +63 -113
- package/dist/language/flows/flows.d.ts +4 -6
- package/dist/language/flows/flows.js +90 -15
- package/dist/language/flows/heal-run.d.ts +10 -4
- package/dist/language/flows/heal-run.js +26 -9
- package/dist/language/flows/recording/flake.d.ts +3 -27
- package/dist/language/flows/recording/flake.js +1 -1
- package/dist/language/flows/recording/recording-backtrack.js +1 -4
- package/dist/language/flows/recording/tape/recordings.d.ts +11 -1
- package/dist/language/flows/recording/tape/recordings.js +9 -3
- package/dist/language/flows/replay.d.ts +25 -5
- package/dist/language/flows/replay.js +83 -16
- package/dist/language/flows/stores/assertion-tiers-store.js +1 -1
- package/dist/language/flows/suite/coverage.d.ts +9 -0
- package/dist/language/flows/suite/coverage.js +12 -1
- package/dist/language/flows/suite-selection.d.ts +25 -0
- package/dist/language/flows/suite-selection.js +41 -9
- package/dist/machine/git-tracks.d.ts +6 -0
- package/dist/machine/git-tracks.js +36 -0
- package/dist/memory/cloud/background-sync.d.ts +25 -0
- package/dist/memory/cloud/background-sync.js +79 -0
- package/dist/memory/cloud/cloud-config.d.ts +12 -1
- package/dist/memory/cloud/cloud-config.js +39 -13
- package/dist/memory/cloud/cloud-sync.d.ts +3 -24
- package/dist/memory/cloud/cloud-sync.js +5 -2
- package/dist/memory/cloud/harness-config.d.ts +0 -7
- package/dist/memory/cloud/memory-scope.d.ts +19 -0
- package/dist/memory/cloud/memory-scope.js +48 -0
- package/dist/memory/cloud/sync-answer.d.ts +43 -0
- package/dist/memory/cloud/sync-answer.js +42 -0
- package/dist/memory/cloud/sync-cycle.d.ts +40 -10
- package/dist/memory/cloud/sync-cycle.js +97 -144
- package/dist/memory/cloud/sync-daemon.d.ts +50 -3
- package/dist/memory/cloud/sync-daemon.js +473 -83
- package/dist/memory/cloud/sync-describe.d.ts +28 -0
- package/dist/memory/cloud/sync-describe.js +92 -0
- package/dist/memory/cloud/sync-disk.d.ts +9 -1
- package/dist/memory/cloud/sync-disk.js +137 -33
- package/dist/memory/cloud/sync-flow-versions.d.ts +26 -0
- package/dist/memory/cloud/sync-flow-versions.js +42 -0
- package/dist/memory/impact/impact-store.js +32 -15
- package/dist/memory/intent/intent-shard.d.ts +41 -266
- package/dist/memory/intent/intent-tools.js +20 -61
- package/dist/memory/intent/record-request.d.ts +27 -0
- package/dist/memory/intent/record-request.js +88 -0
- package/dist/memory/intent/settled-words.js +9 -1
- package/dist/memory/journal/drive-flow.d.ts +3 -0
- package/dist/memory/journal/drive-flow.js +11 -41
- package/dist/memory/journal/envelope-store.js +1 -1
- package/dist/memory/journal/envelope.d.ts +6 -154
- package/dist/memory/journal/episode-log.d.ts +107 -0
- package/dist/memory/journal/episode-log.js +302 -0
- package/dist/memory/journal/journal-recorder.d.ts +7 -0
- package/dist/memory/journal/journal-recorder.js +22 -9
- package/dist/memory/journal/on-disk/ambient-file.d.ts +1 -7
- package/dist/memory/journal/on-disk/ambient-file.js +1 -1
- package/dist/memory/journal/on-disk/workspace-gitignore.d.ts +24 -3
- package/dist/memory/journal/on-disk/workspace-gitignore.js +38 -7
- package/dist/memory/journal/on-disk/workspace-tiers.js +7 -0
- package/dist/memory/journal/self-observation.js +3 -1
- package/dist/memory/journal/session-end.js +23 -9
- package/dist/memory/journal/session-journal.js +39 -20
- package/dist/memory/project/artifact-root-resolver.d.ts +14 -1
- package/dist/memory/project/artifact-root-resolver.js +68 -23
- package/dist/memory/project/artifact-root.d.ts +17 -3
- package/dist/memory/project/artifact-root.js +47 -9
- package/dist/memory/project/fs/fs-port.d.ts +5 -0
- package/dist/memory/project/fs/fs-port.js +13 -0
- package/dist/memory/project/learned-routes.d.ts +3 -4
- package/dist/memory/project/learned-routes.js +3 -11
- package/dist/memory/project/link-directory.js +5 -2
- package/dist/memory/project/root-claims.d.ts +3 -1
- package/dist/memory/project/root-claims.js +41 -7
- package/dist/memory/project/session-root.d.ts +1 -1
- package/dist/memory/project/session-root.js +1 -15
- package/dist/memory/project/sync-status.js +5 -6
- package/dist/memory/recall/memory-tools.js +2 -2
- package/dist/memory/recall/platform-memory.d.ts +3 -1
- package/dist/memory/recall/platform-memory.js +9 -1
- package/dist/memory/recall/project-memory.js +15 -19
- package/dist/portal/bridge/auth-failure-reason.d.ts +13 -0
- package/dist/portal/bridge/auth-failure-reason.js +19 -0
- package/dist/portal/bridge/bridge.d.ts +19 -4
- package/dist/portal/bridge/bridge.js +150 -177
- package/dist/portal/bridge/harness-request.d.ts +15 -0
- package/dist/portal/bridge/harness-request.js +19 -0
- package/dist/portal/bridge/origin/origin-follow.d.ts +46 -0
- package/dist/portal/bridge/origin/origin-follow.js +110 -0
- package/dist/portal/bridge/pairing-token.d.ts +6 -0
- package/dist/portal/bridge/pairing-token.js +47 -16
- package/dist/portal/bridge/protocol-skew.d.ts +27 -2
- package/dist/portal/bridge/protocol-skew.js +66 -2
- package/dist/portal/bridge/session-nonces.d.ts +46 -0
- package/dist/portal/bridge/session-nonces.js +72 -0
- package/dist/portal/input/viewport-tools.d.ts +31 -0
- package/dist/portal/input/viewport-tools.js +106 -15
- package/dist/portal/pool/bounded-close.d.ts +23 -0
- package/dist/portal/pool/bounded-close.js +38 -0
- package/dist/portal/pool/browser-pool.d.ts +44 -39
- package/dist/portal/pool/browser-pool.js +247 -95
- package/dist/portal/pool/context-permissions.d.ts +9 -1
- package/dist/portal/pool/context-permissions.js +26 -0
- package/dist/portal/pool/lease-emulation.d.ts +37 -0
- package/dist/portal/pool/lease-emulation.js +29 -0
- package/dist/portal/pool/playwright-launcher.d.ts +6 -0
- package/dist/portal/pool/playwright-launcher.js +74 -7
- package/dist/portal/pool/pool-contract.d.ts +23 -1
- package/dist/portal/pool/pool-lease.d.ts +128 -0
- package/dist/portal/pool/pool-lease.js +49 -0
- package/dist/portal/pool/zero-install.d.ts +8 -1
- package/dist/portal/pool/zero-install.js +24 -2
- package/dist/portal/production/production-activation.d.ts +136 -0
- package/dist/portal/production/production-activation.js +173 -0
- package/dist/portal/production/production-drive.d.ts +52 -0
- package/dist/portal/production/production-drive.js +301 -0
- package/dist/portal/production/production-hello.d.ts +23 -0
- package/dist/portal/production/production-hello.js +23 -0
- package/dist/portal/realm/web-realm.js +42 -15
- package/dist/portal/session/control-envelope.d.ts +1 -1
- package/dist/portal/session/dev-server/served-document.d.ts +0 -5
- package/dist/portal/session/dev-server/served-document.js +6 -8
- package/dist/portal/session/facts/handshake-facts.d.ts +8 -1
- package/dist/portal/session/first-run-wiring.d.ts +3 -36
- package/dist/portal/session/first-run-wiring.js +10 -103
- package/dist/portal/session/live-control-tools.js +61 -19
- package/dist/portal/session/no-session-next-action.d.ts +11 -0
- package/dist/portal/session/no-session-next-action.js +40 -15
- package/dist/portal/session/no-session-watch.d.ts +7 -0
- package/dist/portal/session/no-session-watch.js +67 -23
- package/dist/portal/session/output-budget.d.ts +10 -0
- package/dist/portal/session/output-budget.js +16 -0
- package/dist/portal/session/presence/session-lease.d.ts +2 -0
- package/dist/portal/session/presence/session-lease.js +8 -0
- package/dist/portal/session/recorded-gaps.d.ts +15 -11
- package/dist/portal/session/recorded-gaps.js +39 -18
- package/dist/portal/session/serving-directory.d.ts +24 -2
- package/dist/portal/session/serving-directory.js +93 -5
- package/dist/portal/session/session-info.d.ts +26 -0
- package/dist/portal/session/session-info.js +20 -0
- package/dist/portal/session/session-manager.d.ts +35 -3
- package/dist/portal/session/session-manager.js +69 -14
- package/dist/portal/session/session-successor.js +1 -9
- package/dist/portal/session/session-tools.js +22 -4
- package/dist/portal/session/session.d.ts +10 -10
- package/dist/portal/session/session.js +37 -29
- package/dist/portal/session/zero-install-first-call.d.ts +7 -2
- package/dist/portal/session/zero-install-first-call.js +43 -20
- package/dist/start-wiring.d.ts +2 -2
- package/dist/start-wiring.js +17 -3
- package/dist/status-payload.d.ts +11 -1
- package/dist/status-payload.js +7 -1
- package/dist/surface/agent-presence-grace.d.ts +11 -0
- package/dist/surface/agent-presence-grace.js +34 -0
- package/dist/surface/http-server.d.ts +12 -1
- package/dist/surface/http-server.js +64 -15
- package/dist/surface/mcp/faults/mcp-outage.d.ts +12 -2
- package/dist/surface/mcp/faults/mcp-outage.js +19 -1
- package/dist/surface/mcp/mcp-proxy.d.ts +17 -74
- package/dist/surface/mcp/mcp-proxy.js +194 -267
- package/dist/surface/mcp/mcp.d.ts +20 -3
- package/dist/surface/mcp/mcp.js +88 -25
- package/dist/surface/mcp/proxy/drive-calls.d.ts +44 -0
- package/dist/surface/mcp/proxy/drive-calls.js +114 -5
- package/dist/surface/mcp/proxy/proxy-boot.d.ts +11 -0
- package/dist/surface/mcp/proxy/proxy-boot.js +1 -0
- package/dist/surface/mcp/proxy/proxy-daemon-probe.d.ts +6 -0
- package/dist/surface/mcp/proxy/proxy-daemon-probe.js +14 -1
- package/dist/surface/mcp/proxy/proxy-handshake.d.ts +34 -2
- package/dist/surface/mcp/proxy/proxy-handshake.js +76 -8
- package/dist/surface/mcp/server-instructions.js +35 -16
- package/dist/surface/mcp/shared-params.d.ts +8 -0
- package/dist/surface/mcp/shared-params.js +15 -1
- package/dist/surface/mcp/sse-frame-parser.d.ts +11 -0
- package/dist/surface/mcp/sse-frame-parser.js +18 -0
- package/dist/surface/mcp/surface-vocabulary.d.ts +2 -0
- package/dist/surface/mcp/surface-vocabulary.js +13 -0
- package/dist/surface/mcp/tool-catalog-cache.d.ts +2 -0
- package/dist/surface/mcp/tool-catalog-cache.js +14 -4
- package/dist/surface/tools/account-tool.d.ts +4 -3
- package/dist/surface/tools/account-tool.js +20 -31
- package/dist/surface/tools/act/act-danger.d.ts +2 -0
- package/dist/surface/tools/act/act-danger.js +41 -14
- package/dist/surface/tools/act/act-observation.d.ts +11 -0
- package/dist/surface/tools/act/act-observation.js +33 -0
- package/dist/surface/tools/act/act-preflight.js +10 -3
- package/dist/surface/tools/act/act-sequence-retry.js +2 -1
- package/dist/surface/tools/act/act-target.js +19 -5
- package/dist/surface/tools/act/durable.js +1 -1
- package/dist/surface/tools/act/navigation/navigate-arrival.d.ts +9 -7
- package/dist/surface/tools/act/navigation/navigate-arrival.js +11 -14
- package/dist/surface/tools/act/unsettled-find.d.ts +36 -0
- package/dist/surface/tools/act/unsettled-find.js +71 -0
- package/dist/surface/tools/act-sequence-tool.js +53 -24
- package/dist/surface/tools/act-tools.d.ts +2 -3
- package/dist/surface/tools/act-tools.js +49 -47
- package/dist/surface/tools/agent/compact-envelope.d.ts +2 -2
- package/dist/surface/tools/agent/for-the-agent.js +41 -3
- package/dist/surface/tools/assert/assert-grade.js +8 -3
- package/dist/surface/tools/assert/assert-verdict.js +4 -2
- package/dist/surface/tools/browser-tools.js +7 -4
- package/dist/surface/tools/chat-drives.js +50 -25
- package/dist/surface/tools/coverage-tools.js +1 -1
- package/dist/surface/tools/dynamic-tools.d.ts +8 -0
- package/dist/surface/tools/dynamic-tools.js +89 -34
- package/dist/surface/tools/empty-session-list.d.ts +18 -25
- package/dist/surface/tools/empty-session-list.js +67 -38
- package/dist/surface/tools/error-recovery.d.ts +17 -7
- package/dist/surface/tools/error-recovery.js +53 -20
- package/dist/surface/tools/explore-tools.d.ts +10 -0
- package/dist/surface/tools/explore-tools.js +72 -19
- package/dist/surface/tools/feedback-tools.js +23 -2
- package/dist/surface/tools/gap-novelty.d.ts +6 -0
- package/dist/surface/tools/gap-novelty.js +9 -0
- package/dist/surface/tools/gaps/capability-absences.js +4 -3
- package/dist/surface/tools/harness-explore.d.ts +1 -1
- package/dist/surface/tools/harness-explore.js +6 -4
- package/dist/surface/tools/harness-gate.d.ts +43 -21
- package/dist/surface/tools/harness-gate.js +55 -81
- package/dist/surface/tools/harness-script.d.ts +2 -0
- package/dist/surface/tools/harness-script.js +11 -6
- package/dist/surface/tools/harness-toolset.js +3 -4
- package/dist/surface/tools/invoke-tool.d.ts +0 -8
- package/dist/surface/tools/invoke-tool.js +164 -178
- package/dist/surface/tools/lease-hint.d.ts +9 -0
- package/dist/surface/tools/lease-hint.js +22 -3
- package/dist/surface/tools/lease-permissions.d.ts +1 -1
- package/dist/surface/tools/lease-readiness.d.ts +55 -0
- package/dist/surface/tools/lease-readiness.js +150 -2
- package/dist/surface/tools/lease-tools.d.ts +3 -75
- package/dist/surface/tools/lease-tools.js +124 -188
- package/dist/surface/tools/map-tools.d.ts +20 -0
- package/dist/surface/tools/map-tools.js +145 -0
- package/dist/surface/tools/merge-tools.js +11 -7
- package/dist/surface/tools/next-step.js +6 -3
- package/dist/surface/tools/observe-tools.js +46 -35
- package/dist/surface/tools/platform-moment.d.ts +3 -12
- package/dist/surface/tools/platform-moment.js +12 -24
- package/dist/surface/tools/read/complete-snapshot.d.ts +7 -1
- package/dist/surface/tools/read/complete-snapshot.js +13 -2
- package/dist/surface/tools/read/query-paginate.js +6 -0
- package/dist/surface/tools/read/query-shape.d.ts +9 -0
- package/dist/surface/tools/read/query-shape.js +15 -0
- package/dist/surface/tools/read/snapshot-unmounted-note.d.ts +1 -0
- package/dist/surface/tools/read/snapshot-unmounted-note.js +73 -0
- package/dist/surface/tools/read-tools.js +5 -5
- package/dist/surface/tools/real-input-attempt.d.ts +11 -0
- package/dist/surface/tools/real-input-attempt.js +206 -38
- package/dist/surface/tools/reconcile-tools.js +21 -8
- package/dist/surface/tools/reticle-result.d.ts +3 -0
- package/dist/surface/tools/reticle-result.js +8 -1
- package/dist/surface/tools/run-report.d.ts +22 -0
- package/dist/surface/tools/run-report.js +141 -0
- package/dist/surface/tools/session-ports.d.ts +57 -0
- package/dist/surface/tools/session-ports.js +102 -0
- package/dist/surface/tools/tool-kit.d.ts +58 -4
- package/dist/surface/tools/tool-kit.js +140 -6
- package/dist/surface/tools/tool-surface.d.ts +2 -0
- package/dist/surface/tools/tool-surface.js +45 -0
- package/dist/surface/tools/tools.js +49 -87
- package/dist/telemetry/automation-hint.d.ts +5 -0
- package/dist/telemetry/automation-hint.js +7 -0
- package/dist/telemetry/cli-telemetry.d.ts +22 -0
- package/dist/telemetry/cli-telemetry.js +80 -11
- package/dist/telemetry/daemon-telemetry.d.ts +3 -1
- package/dist/telemetry/daemon-telemetry.js +9 -2
- package/dist/telemetry/feedback-cli.d.ts +1 -1
- package/dist/telemetry/feedback-cli.js +8 -3
- package/dist/telemetry/feedback.d.ts +1 -1
- package/dist/telemetry/feedback.js +51 -4
- package/dist/telemetry/harness-run.d.ts +3 -3
- package/dist/telemetry/harness-run.js +18 -7
- package/dist/telemetry/hud-events.d.ts +1 -1
- package/dist/telemetry/hud-metrics.d.ts +6 -3
- package/dist/telemetry/hud-metrics.js +20 -8
- package/dist/telemetry/install-source.js +1 -1
- package/dist/telemetry/mcp-connection.d.ts +1 -1
- package/dist/telemetry/mcp-connection.js +21 -2
- package/dist/telemetry/onboarding-firsts.d.ts +6 -1
- package/dist/telemetry/onboarding-firsts.js +41 -1
- package/dist/telemetry/proxy-telemetry.d.ts +42 -0
- package/dist/telemetry/proxy-telemetry.js +70 -1
- package/dist/telemetry/session-metrics.d.ts +1 -3
- package/dist/telemetry/session-metrics.js +16 -12
- package/dist/telemetry/telemetry.d.ts +9 -1
- package/dist/telemetry/telemetry.js +16 -1
- package/dist/telemetry/verification-of.d.ts +3 -1
- package/dist/telemetry/verification-of.js +7 -1
- package/dist/wire-journal.js +12 -2
- package/docs/README.md +4 -2
- package/docs/actions.mdx +7 -6
- package/docs/adapters.md +2 -1
- package/docs/agent-cheatsheet.md +19 -5
- package/docs/architecture.md +13 -10
- package/docs/autodrive.md +6 -5
- package/docs/benchmarks.md +2 -2
- package/docs/capabilities.mdx +1 -1
- package/docs/cli/affected.mdx +1 -1
- package/docs/cli/cloud.mdx +6 -6
- package/docs/cli/doctor.mdx +3 -1
- package/docs/cli/feedback.mdx +11 -7
- package/docs/cli/gate.mdx +1 -1
- package/docs/cli/help.mdx +1 -1
- package/docs/cli/init.mdx +20 -16
- package/docs/cli/mcp.mdx +5 -2
- package/docs/cli/open.mdx +5 -2
- package/docs/cli/report.mdx +1 -1
- package/docs/cli/restart.mdx +1 -1
- package/docs/cli/rollback.mdx +4 -4
- package/docs/cli/serve.mdx +7 -5
- package/docs/cli/setup.mdx +1 -1
- package/docs/cli/status.mdx +6 -2
- package/docs/cli/stop.mdx +3 -3
- package/docs/cli/telemetry.mdx +5 -1
- package/docs/cli/try.mdx +8 -8
- package/docs/cli/update.mdx +8 -5
- package/docs/cli/verify.mdx +12 -5
- package/docs/cli/version.mdx +1 -1
- package/docs/cli.mdx +10 -6
- package/docs/debugging.md +1 -1
- package/docs/deploy-checks.md +8 -6
- package/docs/desktop.mdx +14 -18
- package/docs/enterprise.md +6 -6
- package/docs/environment.mdx +5 -3
- package/docs/faq.mdx +9 -6
- package/docs/first-drive.md +19 -9
- package/docs/flows.md +3 -4
- package/docs/for-agents.md +1 -1
- package/docs/frameworks.mdx +34 -11
- package/docs/getting-started.md +46 -29
- package/docs/http-transport.md +2 -2
- package/docs/human-control.md +8 -8
- package/docs/index.mdx +2 -2
- package/docs/install-agentic.mdx +18 -19
- package/docs/install-manual.mdx +8 -4
- package/docs/integration-patterns.md +5 -5
- package/docs/multi-agent-testing.md +7 -5
- package/docs/packages/browser.mdx +34 -2
- package/docs/packages/core.mdx +2 -1
- package/docs/packages/electron.mdx +15 -3
- package/docs/packages/eslint-plugin.mdx +1 -1
- package/docs/packages/next.mdx +17 -5
- package/docs/packages/react.mdx +8 -1
- package/docs/packages/server.mdx +3 -3
- package/docs/packages/tauri.mdx +3 -3
- package/docs/packages/vite-plugin.mdx +1 -1
- package/docs/packages.mdx +19 -6
- package/docs/platform-integration.md +12 -4
- package/docs/predicates.mdx +18 -7
- package/docs/production-mode.md +108 -0
- package/docs/prompt-capture.md +99 -0
- package/docs/quickstart.mdx +14 -12
- package/docs/recipes.mdx +9 -8
- package/docs/required-checks.md +3 -2
- package/docs/skill-file.mdx +4 -3
- package/docs/skill-setup.md +2 -2
- package/docs/skill.md +62 -70
- package/docs/state-files.md +1 -0
- package/docs/state-management.mdx +11 -9
- package/docs/system-map.md +14 -13
- package/docs/telemetry.md +32 -24
- package/docs/testing.md +9 -5
- package/docs/tools/act-and-wait.mdx +17 -13
- package/docs/tools/act-sequence.mdx +40 -66
- package/docs/tools/act.mdx +7 -5
- package/docs/tools/assert.mdx +1 -1
- package/docs/tools/look.mdx +1 -1
- package/docs/tools/navigate.mdx +1 -1
- package/docs/tools/network.mdx +13 -11
- package/docs/tools/overview.mdx +3 -3
- package/docs/tools/query.mdx +3 -3
- package/docs/tools/session-and-feedback.mdx +9 -6
- package/docs/tools/sessions.mdx +7 -0
- package/docs/tools/snapshot.mdx +9 -7
- package/docs/tools/tools-and-run.mdx +11 -10
- package/docs/tools/verify.mdx +1 -1
- package/docs/troubleshooting.mdx +21 -9
- package/docs/usage.md +58 -43
- package/docs/use-cases.mdx +2 -2
- package/docs/vs-chrome-devtools-mcp.mdx +5 -5
- package/docs/vs-playwright-mcp.mdx +5 -4
- package/docs/what-is-recorded.md +12 -7
- package/docs/what-is-reticle.mdx +2 -2
- package/docs/why-reticle.mdx +1 -1
- package/package.json +9 -12
- package/dist/command/dev/stale-issue-guard.d.ts +0 -34
- package/dist/command/dev/stale-issue-guard.js +0 -69
|
@@ -6,13 +6,16 @@
|
|
|
6
6
|
* one `reticle_context` serves, so the terminal and the agent cannot be told two different stories.
|
|
7
7
|
*/
|
|
8
8
|
import { execFileSync } from 'node:child_process';
|
|
9
|
-
import { existsSync, readdirSync, statSync } from 'node:fs';
|
|
9
|
+
import { existsSync, readFileSync, readdirSync, statSync } from 'node:fs';
|
|
10
|
+
import { homedir } from 'node:os';
|
|
10
11
|
import { join } from 'node:path';
|
|
11
|
-
import { DiscoveryInvite, ReticleDir } from '@reticlehq/core';
|
|
12
|
+
import { DiscoveryInvite, ReticleDir, asRecord } from '@reticlehq/core';
|
|
12
13
|
import { gapSummary } from '../../judgement/runs/artifact/gap-summary.js';
|
|
13
14
|
import { SessionJournal } from '../../memory/journal/session-journal.js';
|
|
14
15
|
import { createNodeFileSystem } from '../../memory/project/fs/fs-port.js';
|
|
15
16
|
import { gapHookLine, gapReportLines } from '../../judgement/runs/artifact/gap-report.js';
|
|
17
|
+
import { DriveOrigin, DriveStatus, pollCall } from '../../features/harness/drive-runs.js';
|
|
18
|
+
import { DRIVE_RECORD_SUFFIX, UNMATCHED_SUBDIR } from '../../memory/project/dir/reticle-dir.js';
|
|
16
19
|
/**
|
|
17
20
|
* A session last written longer ago than this is not the turn a hook is asking about.
|
|
18
21
|
*
|
|
@@ -20,33 +23,99 @@ import { gapHookLine, gapReportLines } from '../../judgement/runs/artifact/gap-r
|
|
|
20
23
|
* drive older than an hour reads as "no claim this session", which errs toward saying so.
|
|
21
24
|
*/
|
|
22
25
|
const HOOK_WINDOW_MS = 60 * 60 * 1000;
|
|
23
|
-
/**
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
26
|
+
/**
|
|
27
|
+
* How long the Stop hook keeps an agent for one Harness drive. A record still `running` after this
|
|
28
|
+
* was left by a daemon that stopped, and it would hold the agent forever.
|
|
29
|
+
*
|
|
30
|
+
* ponytail: a fixed bound from the start time, not a liveness check on the daemon. Ask the daemon
|
|
31
|
+
* when a real drive runs longer than this.
|
|
32
|
+
*/
|
|
33
|
+
const KEEP_ALIVE_MAX_MS = 30 * 60 * 1000;
|
|
34
|
+
/** What the Stop hook tells an agent that tried to stop while its Harness drive runs. */
|
|
35
|
+
export function keepAliveReason(runId) {
|
|
36
|
+
return (`The Harness drive ${runId} that you started is still running. Do not stop yet. ` +
|
|
37
|
+
`Call ${pollCall(runId)} until it ends. If it reports a failed check, fix the code, then ` +
|
|
38
|
+
`start the same drive again to verify the fix.`);
|
|
39
|
+
}
|
|
40
|
+
/** The newest drive this agent started that still runs, read from `.reticle/runs/`. */
|
|
41
|
+
function agentDriveRunning(root, now) {
|
|
42
|
+
const runs = join(root, ReticleDir.RUNS_SUBDIR);
|
|
43
|
+
if (!existsSync(runs))
|
|
27
44
|
return undefined;
|
|
28
45
|
let newest;
|
|
29
|
-
for (const
|
|
30
|
-
|
|
31
|
-
|
|
46
|
+
for (const name of readdirSync(runs)) {
|
|
47
|
+
if (!name.endsWith(DRIVE_RECORD_SUFFIX))
|
|
48
|
+
continue;
|
|
49
|
+
let record;
|
|
50
|
+
try {
|
|
51
|
+
record = asRecord(JSON.parse(readFileSync(join(runs, name), 'utf8')));
|
|
52
|
+
}
|
|
53
|
+
catch {
|
|
54
|
+
continue;
|
|
55
|
+
}
|
|
56
|
+
const { harnessRun, status, origin, startedAt } = record;
|
|
57
|
+
if (DriveStatus.RUNNING !== status || DriveOrigin.AGENT !== origin)
|
|
58
|
+
continue;
|
|
59
|
+
if ('string' !== typeof harnessRun || 'number' !== typeof startedAt)
|
|
60
|
+
continue;
|
|
61
|
+
if (now - startedAt > KEEP_ALIVE_MAX_MS)
|
|
62
|
+
continue;
|
|
63
|
+
if (newest === undefined || startedAt > newest.startedAt)
|
|
64
|
+
newest = { runId: harnessRun, startedAt };
|
|
65
|
+
}
|
|
66
|
+
return newest?.runId;
|
|
67
|
+
}
|
|
68
|
+
/**
|
|
69
|
+
* Every `.reticle` root a session of this project can be in: the project's own, then each folder the
|
|
70
|
+
* daemon filed under `~/.reticle/unmatched` for a page it could not tie to a project (before
|
|
71
|
+
* `reticle init`). Without them the hook said "No claim was checked" after claims had held.
|
|
72
|
+
*
|
|
73
|
+
* ponytail: an unmatched folder is not tied to this cwd; the newest session in the window wins.
|
|
74
|
+
*/
|
|
75
|
+
function sessionRoots(root, home) {
|
|
76
|
+
if (home === undefined)
|
|
77
|
+
return [root];
|
|
78
|
+
const unmatched = join(home, ReticleDir.ROOT, UNMATCHED_SUBDIR);
|
|
79
|
+
if (!existsSync(unmatched))
|
|
80
|
+
return [root];
|
|
81
|
+
return [root, ...readdirSync(unmatched).map((name) => join(unmatched, name))];
|
|
82
|
+
}
|
|
83
|
+
/** The session whose action ledger was written most recently, if any. */
|
|
84
|
+
function newestSession(roots) {
|
|
85
|
+
let newest;
|
|
86
|
+
for (const root of roots) {
|
|
87
|
+
const sessionsDir = join(root, ReticleDir.SESSIONS_SUBDIR);
|
|
88
|
+
if (!existsSync(sessionsDir))
|
|
32
89
|
continue;
|
|
33
|
-
const
|
|
34
|
-
|
|
35
|
-
|
|
90
|
+
for (const id of readdirSync(sessionsDir)) {
|
|
91
|
+
const ledger = join(sessionsDir, id, ReticleDir.JOURNAL_ACTIONS_FILE);
|
|
92
|
+
if (!existsSync(ledger))
|
|
93
|
+
continue;
|
|
94
|
+
const writtenAt = statSync(ledger).mtimeMs;
|
|
95
|
+
if (newest === undefined || writtenAt > newest.writtenAt)
|
|
96
|
+
newest = { id, writtenAt, root };
|
|
97
|
+
}
|
|
36
98
|
}
|
|
37
99
|
return newest;
|
|
38
100
|
}
|
|
39
101
|
export async function reportFor(input) {
|
|
102
|
+
const root = join(input.cwd, ReticleDir.ROOT);
|
|
103
|
+
// The one case the hook blocks: the agent's own Harness drive is still running, so its result,
|
|
104
|
+
// and any defect it finds, would reach nobody.
|
|
105
|
+
const driving = true === input.hook ? agentDriveRunning(root, input.now) : undefined;
|
|
106
|
+
if (driving !== undefined)
|
|
107
|
+
return { lines: [], block: keepAliveReason(driving) };
|
|
40
108
|
if (true === input.hook && !input.treeChanged)
|
|
41
109
|
return { lines: [] };
|
|
42
|
-
const
|
|
43
|
-
|
|
110
|
+
const found = input.session === undefined
|
|
111
|
+
? newestSession(sessionRoots(root, input.home))
|
|
112
|
+
: { id: input.session, writtenAt: input.now, root };
|
|
44
113
|
const current = found !== undefined && (true !== input.hook || input.now - found.writtenAt <= HOOK_WINDOW_MS)
|
|
45
114
|
? found
|
|
46
115
|
: undefined;
|
|
47
116
|
const actions = current === undefined
|
|
48
117
|
? []
|
|
49
|
-
: await new SessionJournal(createNodeFileSystem(), root, current.id).readActions();
|
|
118
|
+
: await new SessionJournal(createNodeFileSystem(), current.root, current.id).readActions();
|
|
50
119
|
const gap = gapSummary(actions);
|
|
51
120
|
if (true === input.hook) {
|
|
52
121
|
const line = gapHookLine(gap);
|
|
@@ -66,16 +135,19 @@ function treeChanged(cwd) {
|
|
|
66
135
|
}
|
|
67
136
|
}
|
|
68
137
|
/**
|
|
69
|
-
* The command. As a hook it prints Claude Code's `systemMessage` shape and always exits 0
|
|
70
|
-
*
|
|
138
|
+
* The command. As a hook it prints Claude Code's `systemMessage` shape and always exits 0, so the
|
|
139
|
+
* human sees the gap. It blocks the stop in one case only: a Harness drive the agent started is still
|
|
140
|
+
* running, bounded by `KEEP_ALIVE_MAX_MS`.
|
|
71
141
|
*/
|
|
72
142
|
export async function handleReport(session, hook) {
|
|
73
143
|
const cwd = process.cwd();
|
|
74
144
|
let lines;
|
|
145
|
+
let block;
|
|
75
146
|
try {
|
|
76
|
-
({ lines } = await reportFor({
|
|
147
|
+
({ lines, block } = await reportFor({
|
|
77
148
|
cwd,
|
|
78
149
|
now: Date.now(),
|
|
150
|
+
home: homedir(),
|
|
79
151
|
treeChanged: hook ? treeChanged(cwd) : true,
|
|
80
152
|
...(session === undefined ? {} : { session }),
|
|
81
153
|
hook,
|
|
@@ -91,6 +163,11 @@ export async function handleReport(session, hook) {
|
|
|
91
163
|
process.exitCode = 1;
|
|
92
164
|
return;
|
|
93
165
|
}
|
|
166
|
+
// Claude Code and Codex both read this shape from a Stop hook: the agent goes on, told `reason`.
|
|
167
|
+
if (block !== undefined) {
|
|
168
|
+
process.stdout.write(`${JSON.stringify({ decision: 'block', reason: block })}\n`);
|
|
169
|
+
return;
|
|
170
|
+
}
|
|
94
171
|
if (0 === lines.length)
|
|
95
172
|
return;
|
|
96
173
|
process.stdout.write(hook ? `${JSON.stringify({ systemMessage: lines.join('\n') })}\n` : `${lines.join('\n')}\n`);
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
/**
|
|
2
|
-
*
|
|
3
|
-
* 1000-line cap and the rule is to split rather than raise it.
|
|
2
|
+
* `reticle status`: what it reads and reports, and the two optional blocks it adds to its payload.
|
|
3
|
+
* Out of cli.ts because that file hit the 1000-line cap and the rule is to split rather than raise it.
|
|
4
4
|
*
|
|
5
5
|
* They belong together: both answer "is there anything else the reader needs to know", both are
|
|
6
6
|
* absent when the answer is no, and both are the reason a healthy `status` reads as healthy.
|
|
@@ -26,3 +26,10 @@ export declare function withNextAction(facts: {
|
|
|
26
26
|
export declare function splitBrainFields(port: number, projectId: string | undefined): {
|
|
27
27
|
splitBrain?: string;
|
|
28
28
|
};
|
|
29
|
+
/**
|
|
30
|
+
* Report status to the terminal. `--json` writes one structured line to STDOUT so it can be piped
|
|
31
|
+
* into `jq`; the human-readable block goes to stdout too. `log()` stays on stderr (the MCP
|
|
32
|
+
* transport lives on stdout), so `--json` must not go through it.
|
|
33
|
+
*/
|
|
34
|
+
export declare function reportStatus(fields: Record<string, unknown>, json: boolean): void;
|
|
35
|
+
export declare function handleStatus(port: number, json?: boolean): Promise<void>;
|
|
@@ -1,10 +1,22 @@
|
|
|
1
1
|
import { statusNextAction } from './answers/status-next-action.js';
|
|
2
2
|
import { daemonsServingProjectElsewhere, resolveDaemonForProject, splitBrainNote, wrongDaemonNote, } from '../daemon/daemon-resolve.js';
|
|
3
|
-
import { isAlive, reticleStateHome } from '../daemon/daemon.js';
|
|
4
|
-
import { hasProjectConnectedBefore } from '../../memory/recall/prior/connection-memory.js';
|
|
3
|
+
import { isAlive, readPid, reticleStateHome } from '../daemon/daemon.js';
|
|
4
|
+
import { hasAnyAppConnectedBefore, hasProjectConnectedBefore, } from '../../memory/recall/prior/connection-memory.js';
|
|
5
|
+
import { devServersForProject } from '@reticlehq/core';
|
|
6
|
+
import { readDevServers } from '../daemon/dev-servers.js';
|
|
7
|
+
import { attachStatusFields } from '../../surface/mcp/attach-memory.js';
|
|
8
|
+
import { probeDaemon } from '../../surface/mcp/mcp-proxy.js';
|
|
9
|
+
import { availableUpdate } from '../update/update-nudge.js';
|
|
10
|
+
import { fetchStatus } from '../daemon/binding/daemon-status-probe.js';
|
|
11
|
+
import { PortPresence, probePresence, presenceIsUsable, describePresence, } from '../daemon/binding/port-presence.js';
|
|
12
|
+
import { summarizeStatus } from './launch/cli-launch.js';
|
|
13
|
+
import { readProjectId } from './ports/resolve/cli-port.js';
|
|
14
|
+
import { accountStatusFields } from './cloud-cli.js';
|
|
15
|
+
import { localLinkOf, workspaceAppLinks } from './status/workspace-links.js';
|
|
16
|
+
import { statusLines } from './status/status-lines.js';
|
|
5
17
|
/**
|
|
6
|
-
*
|
|
7
|
-
* 1000-line cap and the rule is to split rather than raise it.
|
|
18
|
+
* `reticle status`: what it reads and reports, and the two optional blocks it adds to its payload.
|
|
19
|
+
* Out of cli.ts because that file hit the 1000-line cap and the rule is to split rather than raise it.
|
|
8
20
|
*
|
|
9
21
|
* They belong together: both answer "is there anything else the reader needs to know", both are
|
|
10
22
|
* absent when the answer is no, and both are the reason a healthy `status` reads as healthy.
|
|
@@ -27,3 +39,135 @@ export function splitBrainFields(port, projectId) {
|
|
|
27
39
|
const note = elsewhere ?? wrongDaemonNote(port, resolveDaemonForProject(projectId, home, isAlive));
|
|
28
40
|
return note === undefined ? {} : { splitBrain: note };
|
|
29
41
|
}
|
|
42
|
+
/**
|
|
43
|
+
* Report status to the terminal. `--json` writes one structured line to STDOUT so it can be piped
|
|
44
|
+
* into `jq`; the human-readable block goes to stdout too. `log()` stays on stderr (the MCP
|
|
45
|
+
* transport lives on stdout), so `--json` must not go through it.
|
|
46
|
+
*/
|
|
47
|
+
export function reportStatus(fields, json) {
|
|
48
|
+
if (json) {
|
|
49
|
+
const line = JSON.stringify({
|
|
50
|
+
t: new Date().toISOString(),
|
|
51
|
+
event: 'reticle_status',
|
|
52
|
+
...fields,
|
|
53
|
+
});
|
|
54
|
+
process.stdout.write(`${line}\n`);
|
|
55
|
+
return;
|
|
56
|
+
}
|
|
57
|
+
process.stdout.write(`${statusLines(fields).join('\n')}\n`);
|
|
58
|
+
}
|
|
59
|
+
export async function handleStatus(port, json = false) {
|
|
60
|
+
// A broken session file must not cost the reader the rest of the status.
|
|
61
|
+
const account = await accountStatusFields().catch(() => ({}));
|
|
62
|
+
// At a workspace root that is no app of its own, each app and its link: "not linked" named none.
|
|
63
|
+
const linked = account.linkedProject;
|
|
64
|
+
if ('string' !== typeof linked && readProjectId(process.cwd()) === undefined) {
|
|
65
|
+
Object.assign(account, {
|
|
66
|
+
workspaceApps: await workspaceAppLinks(process.cwd(), localLinkOf).catch(() => []),
|
|
67
|
+
});
|
|
68
|
+
}
|
|
69
|
+
const report = (fields) => reportStatus({ ...fields, ...account }, json);
|
|
70
|
+
const pid = readPid(port);
|
|
71
|
+
// Durable, so it survives the daemon idling out — which is the state `status` is most often run in.
|
|
72
|
+
const projectId = readProjectId(process.cwd());
|
|
73
|
+
const previouslyConnected = hasAnyAppConnectedBefore(reticleStateHome(), port, projectId);
|
|
74
|
+
// The narrow twin. Every sentence that says "this project", and the decision about whether THIS
|
|
75
|
+
// app is instrumented, needs the question the wide one cannot answer without a project id.
|
|
76
|
+
const projectPreviouslyConnected = hasProjectConnectedBefore(reticleStateHome(), port, projectId);
|
|
77
|
+
// Whether `init` has run HERE. Registering the MCP server does not wire the app, and more than one
|
|
78
|
+
// path does the first without the second — so this is the commonest reason `status` has nothing to
|
|
79
|
+
// report, and it was not among the facts this command could state.
|
|
80
|
+
const initialized = projectId !== undefined;
|
|
81
|
+
// The OTHER half of the install, and the half this command could not see. A host that registers
|
|
82
|
+
// Reticle and never lists its tools looks exactly like an abandoned install from here — same idle
|
|
83
|
+
// daemon, same zero sessions — and the user sees a tool that does nothing. See attach-memory.ts.
|
|
84
|
+
const client = attachStatusFields(reticleStateHome(), port);
|
|
85
|
+
// What the dev servers themselves said. The reason this command could previously only guess at
|
|
86
|
+
// whether the app was running is that it had no way to see one; now the ones carrying Reticle
|
|
87
|
+
// announce, and the advice below stops contradicting the terminal the reader is looking at.
|
|
88
|
+
// Scoped to THIS project: the registry is machine-wide, and an unrelated app's dev server must
|
|
89
|
+
// not make this project look like it is running.
|
|
90
|
+
const devServerPorts = devServersForProject(readDevServers(reticleStateHome()), {
|
|
91
|
+
projectId,
|
|
92
|
+
root: process.cwd(),
|
|
93
|
+
}).map((d) => d.port);
|
|
94
|
+
// The failure where every individual check is green and the chain is broken: the agent's proxy and
|
|
95
|
+
// the app resolved their ports independently and landed on two different daemons. Reported from
|
|
96
|
+
// BOTH stances, because neither one can see it alone.
|
|
97
|
+
const split = splitBrainFields(port, projectId);
|
|
98
|
+
// Doctor and status must answer the same liveness question. A live pid only says that some
|
|
99
|
+
// process exists; a Reticle daemon is running only when the shared port probe reaches /status.
|
|
100
|
+
const presence = await probePresence(port, { tcpOpen: probeDaemon, status: fetchStatus });
|
|
101
|
+
if (!presenceIsUsable(presence)) {
|
|
102
|
+
report({
|
|
103
|
+
port,
|
|
104
|
+
running: false,
|
|
105
|
+
presence,
|
|
106
|
+
...(presence === PortPresence.FOREIGN ? { reason: describePresence(presence, port) } : {}),
|
|
107
|
+
// `init` promises this command says why the app has not connected. Without it the answer was
|
|
108
|
+
// `running: false` and nothing else, which reads as "Reticle is broken" for what is usually
|
|
109
|
+
// just a daemon that has not been asked to do anything yet.
|
|
110
|
+
...withNextAction({
|
|
111
|
+
running: false,
|
|
112
|
+
sessionCount: 0,
|
|
113
|
+
previouslyConnected,
|
|
114
|
+
projectPreviouslyConnected,
|
|
115
|
+
initialized,
|
|
116
|
+
devServerPorts,
|
|
117
|
+
}),
|
|
118
|
+
...client,
|
|
119
|
+
...split,
|
|
120
|
+
});
|
|
121
|
+
return;
|
|
122
|
+
}
|
|
123
|
+
// The daemon answered the same probe doctor trusts — ask it for live sessions + health.
|
|
124
|
+
const payload = await fetchStatus(port);
|
|
125
|
+
// `status` is the second-most-run command and the one a HUMAN types. The update nudge otherwise
|
|
126
|
+
// only rides a tool result, which the majority of daemons never produce — so the people most in
|
|
127
|
+
// need of an upgrade were the ones with no path to hearing about it.
|
|
128
|
+
const update = availableUpdate();
|
|
129
|
+
const nudge = update === undefined ? {} : { updateAvailable: update };
|
|
130
|
+
if (payload === undefined) {
|
|
131
|
+
report({
|
|
132
|
+
port,
|
|
133
|
+
running: true,
|
|
134
|
+
pid,
|
|
135
|
+
...nudge,
|
|
136
|
+
...withNextAction({
|
|
137
|
+
running: true,
|
|
138
|
+
sessionCount: 0,
|
|
139
|
+
previouslyConnected,
|
|
140
|
+
projectPreviouslyConnected,
|
|
141
|
+
initialized,
|
|
142
|
+
devServerPorts,
|
|
143
|
+
}),
|
|
144
|
+
...client,
|
|
145
|
+
...split,
|
|
146
|
+
});
|
|
147
|
+
return;
|
|
148
|
+
}
|
|
149
|
+
const summary = summarizeStatus(payload);
|
|
150
|
+
// Only when the daemon did NOT already explain itself. It has the whole diagnosis in-process and
|
|
151
|
+
// puts it on the wire as `why`; printing a second, thinner opinion beside it risks two confident
|
|
152
|
+
// answers pointing different ways, which is worse than one.
|
|
153
|
+
const next = summary.why === undefined
|
|
154
|
+
? withNextAction({
|
|
155
|
+
running: true,
|
|
156
|
+
...summary,
|
|
157
|
+
previouslyConnected,
|
|
158
|
+
projectPreviouslyConnected,
|
|
159
|
+
initialized,
|
|
160
|
+
devServerPorts,
|
|
161
|
+
})
|
|
162
|
+
: {};
|
|
163
|
+
report({
|
|
164
|
+
port,
|
|
165
|
+
running: true,
|
|
166
|
+
pid,
|
|
167
|
+
...summary,
|
|
168
|
+
...next,
|
|
169
|
+
...client,
|
|
170
|
+
...split,
|
|
171
|
+
...nudge,
|
|
172
|
+
});
|
|
173
|
+
}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import type { CloudConfig } from '../../memory/cloud/cloud-sync.js';
|
|
2
2
|
import { type FreeDrive } from '../../features/harness/platform/platform-drives.js';
|
|
3
|
-
export declare const MSG_SIGN_IN_FIRST = "
|
|
3
|
+
export declare const MSG_SIGN_IN_FIRST = "Link this folder first: reticle connect. It signs you in if you are not, and it is free, no card.";
|
|
4
4
|
/** The whole drive, model turns and browser included, before the CLI stops waiting for it. */
|
|
5
5
|
export declare const TRY_BUDGET_MS = 120000;
|
|
6
6
|
/** Model turns in the one free drive. Bounds what it costs, not what it may find. */
|
|
@@ -53,8 +53,7 @@ export declare function cmdTry(argv: readonly string[], cloudCommands: TryCloud)
|
|
|
53
53
|
/**
|
|
54
54
|
* How `init` ends once the connection is proved: what Reticle sees of the app, what it is missing,
|
|
55
55
|
* and the prompt that hands the rest to the coding agent, which proves the first flow. `init` never
|
|
56
|
-
* drives: the Harness is opt-in
|
|
57
|
-
* freshly wired app is rarely there yet.
|
|
56
|
+
* drives: the Harness is opt-in. It runs at any setup score.
|
|
58
57
|
*
|
|
59
58
|
* Read from the daemon's `/status`, the same coverage `doctor` prints, so the two never disagree.
|
|
60
59
|
*/
|
|
@@ -64,7 +63,7 @@ export declare const UNLINKED_PITCH: string[];
|
|
|
64
63
|
export declare const msgProveOneFlow: (url: string) => string;
|
|
65
64
|
/**
|
|
66
65
|
* The closing lines for one tab's coverage, as `/status` reports it: the score, what is missing, the
|
|
67
|
-
* Harness
|
|
66
|
+
* Harness switch, and the prompt for the coding agent. Pure.
|
|
68
67
|
*/
|
|
69
68
|
export declare function initCoverageLines(tab: Record<string, unknown> | undefined, url: string): string[];
|
|
70
69
|
/**
|
|
@@ -27,7 +27,7 @@ import { callerArtifactRoot } from '../../memory/project/link-directory.js';
|
|
|
27
27
|
import { seeRunLine } from '../../memory/project/sync-status.js';
|
|
28
28
|
import { DAEMON_INNER_COMMAND, PORT_FLAG } from './cli-parse.js';
|
|
29
29
|
import { acquireLease, connectOverSse, endpointFor, exploreToEnd, refusalText, releaseLease, verdictOf, } from './adhoc-verdict.js';
|
|
30
|
-
export const MSG_SIGN_IN_FIRST = '
|
|
30
|
+
export const MSG_SIGN_IN_FIRST = 'Link this folder first: reticle connect. It signs you in if you are not, and it is free, no card.';
|
|
31
31
|
const PERSONA_FLAG = '--persona';
|
|
32
32
|
/** The whole drive, model turns and browser included, before the CLI stops waiting for it. */
|
|
33
33
|
export const TRY_BUDGET_MS = 120_000;
|
|
@@ -263,15 +263,14 @@ export async function cmdTry(argv, cloudCommands) {
|
|
|
263
263
|
/**
|
|
264
264
|
* How `init` ends once the connection is proved: what Reticle sees of the app, what it is missing,
|
|
265
265
|
* and the prompt that hands the rest to the coding agent, which proves the first flow. `init` never
|
|
266
|
-
* drives: the Harness is opt-in
|
|
267
|
-
* freshly wired app is rarely there yet.
|
|
266
|
+
* drives: the Harness is opt-in. It runs at any setup score.
|
|
268
267
|
*
|
|
269
268
|
* Read from the daemon's `/status`, the same coverage `doctor` prints, so the two never disagree.
|
|
270
269
|
*/
|
|
271
270
|
/** What a project that is not linked is told, once, at the end. */
|
|
272
271
|
export const UNLINKED_PITCH = [
|
|
273
272
|
'Results stay on this machine. `reticle connect` saves them to your dashboard and lets Reticle',
|
|
274
|
-
'Harness test the whole app: a new account gets
|
|
273
|
+
'Harness test the whole app: a new account gets free credits to start.',
|
|
275
274
|
];
|
|
276
275
|
/** Prove one flow with the coding agent: the line every ending names. */
|
|
277
276
|
export const msgProveOneFlow = (url) => `Then ask your coding agent: "Use Reticle to prove one flow in ${url}: drive it, and end with ` +
|
|
@@ -286,25 +285,21 @@ const names = (value) => Array.isArray(value)
|
|
|
286
285
|
: [];
|
|
287
286
|
/**
|
|
288
287
|
* The closing lines for one tab's coverage, as `/status` reports it: the score, what is missing, the
|
|
289
|
-
* Harness
|
|
288
|
+
* Harness switch, and the prompt for the coding agent. Pure.
|
|
290
289
|
*/
|
|
291
290
|
export function initCoverageLines(tab, url) {
|
|
292
|
-
const
|
|
293
|
-
const percent = gate['percent'];
|
|
291
|
+
const percent = tab?.['setupScore'];
|
|
294
292
|
if (tab === undefined || 'number' !== typeof percent)
|
|
295
293
|
return [
|
|
296
294
|
'Instrumentation is measured on an open tab of the app: run `reticle doctor` with it open.',
|
|
297
295
|
msgProveOneFlow(url),
|
|
298
296
|
];
|
|
299
297
|
const unseen = [...names(tab['missing']), ...names(tab['notSeenYet'])];
|
|
300
|
-
const reason = gate['reason'];
|
|
301
298
|
const prompt = tab['prompt'];
|
|
302
299
|
return [
|
|
303
300
|
`Instrumentation: ${String(percent)}%` +
|
|
304
301
|
(0 === unseen.length ? '' : ` — missing: ${unseen.join(', ')}`),
|
|
305
|
-
|
|
306
|
-
? reason
|
|
307
|
-
: `Harness can be switched on: it is off until you switch it on in the HUD's Settings.`,
|
|
302
|
+
`Harness can be switched on: it is off until you switch it on in the HUD's Settings.`,
|
|
308
303
|
...('string' === typeof prompt
|
|
309
304
|
? [
|
|
310
305
|
'Paste this into your coding agent; it closes the gaps and proves the first flow:',
|
|
@@ -9,11 +9,14 @@ import { Verified, type ReticleVerificationRun } from '@reticlehq/core';
|
|
|
9
9
|
type JourneyVerdict = typeof Verified.YES | typeof Verified.NO | typeof Verified.UNKNOWN;
|
|
10
10
|
export interface VerifyResults {
|
|
11
11
|
verdict: JourneyVerdict;
|
|
12
|
+
/** `runId` is the run the journey came from, set only when that run reached the platform. */
|
|
12
13
|
results: {
|
|
13
14
|
journey: string;
|
|
14
15
|
verdict: JourneyVerdict;
|
|
15
16
|
reason?: string;
|
|
17
|
+
runId?: string;
|
|
16
18
|
}[];
|
|
17
19
|
}
|
|
18
|
-
|
|
20
|
+
/** `pushed`: the run reached the platform, so its id resolves there and the results name it. */
|
|
21
|
+
export declare function verifyResults(run: ReticleVerificationRun, pushed?: boolean): VerifyResults;
|
|
19
22
|
export {};
|
|
@@ -14,11 +14,13 @@ function journeyVerdict(status) {
|
|
|
14
14
|
return Verified.YES;
|
|
15
15
|
return Verified.UNKNOWN;
|
|
16
16
|
}
|
|
17
|
-
|
|
17
|
+
/** `pushed`: the run reached the platform, so its id resolves there and the results name it. */
|
|
18
|
+
export function verifyResults(run, pushed = false) {
|
|
18
19
|
const results = run.flows.map((flow) => ({
|
|
19
20
|
journey: flow.name,
|
|
20
21
|
verdict: journeyVerdict(flow.status),
|
|
21
22
|
...(flow.failureReason === undefined ? {} : { reason: flow.failureReason }),
|
|
23
|
+
...(pushed ? { runId: run.runId } : {}),
|
|
22
24
|
}));
|
|
23
25
|
const verdict = results.some((r) => Verified.NO === r.verdict)
|
|
24
26
|
? Verified.NO
|
package/dist/command/cli.d.ts
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
|
+
export { handleStatus, reportStatus } from './cli/status-fields.js';
|
|
2
3
|
import { parseCliArgs, CLI_USAGE } from './cli/cli-parse.js';
|
|
3
4
|
export { parseCliArgs, CLI_USAGE };
|
|
4
5
|
export type { CliResult } from './cli/cli-parse.js';
|
|
@@ -16,11 +17,4 @@ export declare function connectExit(cloudCode: number, initUnfinished: string |
|
|
|
16
17
|
code: number;
|
|
17
18
|
note?: string;
|
|
18
19
|
};
|
|
19
|
-
/**
|
|
20
|
-
* Report status to the terminal. `--json` writes one structured line to STDOUT so it can be piped
|
|
21
|
-
* into `jq`; the human-readable block goes to stdout too. `log()` stays on stderr (the MCP
|
|
22
|
-
* transport lives on stdout), so `--json` must not go through it.
|
|
23
|
-
*/
|
|
24
|
-
export declare function reportStatus(fields: Record<string, unknown>, json: boolean): void;
|
|
25
|
-
export declare function handleStatus(port: number, json?: boolean): Promise<void>;
|
|
26
20
|
export declare function main(): void;
|