@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.
- package/SKILL.md +122 -123
- package/dist/command/cli/adhoc-suite.d.ts +14 -0
- package/dist/command/cli/adhoc-suite.js +42 -7
- package/dist/command/cli/adhoc-verdict.d.ts +18 -2
- package/dist/command/cli/adhoc-verdict.js +70 -6
- package/dist/command/cli/answers/gate-exit.d.ts +23 -0
- package/dist/command/cli/answers/gate-exit.js +45 -0
- package/dist/command/cli/answers/gate-hook-message.d.ts +2 -0
- package/dist/command/cli/answers/gate-hook-message.js +3 -1
- package/dist/command/cli/auth/device-flow.d.ts +13 -2
- package/dist/command/cli/auth/device-flow.js +17 -0
- package/dist/command/cli/cli-doctor.js +14 -0
- package/dist/command/cli/cli-flow-commands.d.ts +0 -11
- package/dist/command/cli/cli-flow-commands.js +28 -105
- package/dist/command/cli/cli-kill.js +3 -2
- package/dist/command/cli/cli-parse-grammar.d.ts +24 -0
- package/dist/command/cli/cli-parse-grammar.js +75 -0
- package/dist/command/cli/cli-parse-verify.d.ts +2 -0
- package/dist/command/cli/cli-parse-verify.js +18 -0
- package/dist/command/cli/cli-parse.d.ts +19 -28
- package/dist/command/cli/cli-parse.js +82 -182
- package/dist/command/cli/cli-update-commands.d.ts +1 -1
- package/dist/command/cli/cli-update-commands.js +61 -9
- package/dist/command/cli/cli-usage.d.ts +33 -0
- package/dist/command/cli/cli-usage.js +287 -0
- package/dist/command/cli/cli-verify.d.ts +34 -4
- package/dist/command/cli/cli-verify.js +81 -12
- package/dist/command/cli/cloud-cli.d.ts +13 -0
- package/dist/command/cli/cloud-cli.js +145 -333
- package/dist/command/cli/cloud-kit.d.ts +12 -0
- package/dist/command/cli/cloud-kit.js +41 -2
- package/dist/command/cli/cloud-link.d.ts +57 -0
- package/dist/command/cli/cloud-link.js +308 -0
- package/dist/command/cli/cloud-login.d.ts +15 -1
- package/dist/command/cli/cloud-login.js +67 -13
- package/dist/command/cli/context-command.d.ts +1 -0
- package/dist/command/cli/context-command.js +33 -0
- package/dist/command/cli/daemon-start-options.d.ts +3 -0
- package/dist/command/cli/daemon-start-options.js +24 -3
- package/dist/command/cli/doctor/doctor-coverage-line.d.ts +2 -0
- package/dist/command/cli/doctor/doctor-coverage-line.js +47 -0
- package/dist/command/cli/doctor/doctor-project-line.d.ts +0 -12
- package/dist/command/cli/doctor/doctor-project-line.js +5 -4
- package/dist/command/cli/doctor/doctor-rows.d.ts +6 -0
- package/dist/command/cli/doctor/doctor-rows.js +6 -0
- package/dist/command/cli/doctor/doctor-signing-line.d.ts +38 -0
- package/dist/command/cli/doctor/doctor-signing-line.js +114 -0
- package/dist/command/cli/known-regression.d.ts +13 -0
- package/dist/command/cli/known-regression.js +34 -0
- package/dist/command/cli/launch/sdk-version-match.d.ts +12 -0
- package/dist/command/cli/launch/sdk-version-match.js +25 -0
- package/dist/command/cli/lifecycle/daemon-lifecycle.js +11 -2
- package/dist/command/cli/mcp-command.d.ts +6 -0
- package/dist/command/cli/mcp-command.js +13 -5
- package/dist/command/cli/ports/port-holder.js +1 -1
- package/dist/command/cli/project-name.d.ts +29 -1
- package/dist/command/cli/project-name.js +107 -2
- package/dist/command/cli/setup-mcp-cli.d.ts +17 -1
- package/dist/command/cli/setup-mcp-cli.js +29 -8
- package/dist/command/cli/status/status-lines.d.ts +1 -0
- package/dist/command/cli/status/status-lines.js +47 -2
- package/dist/command/cli/status/workspace-links.d.ts +10 -0
- package/dist/command/cli/status/workspace-links.js +29 -0
- package/dist/command/cli/try-command.d.ts +96 -0
- package/dist/command/cli/try-command.js +362 -0
- package/dist/command/cli/tutorial.d.ts +0 -100
- package/dist/command/cli/tutorial.js +0 -178
- package/dist/command/cli/verify-results.d.ts +19 -0
- package/dist/command/cli/verify-results.js +29 -0
- package/dist/command/cli-onboarding.d.ts +0 -11
- package/dist/command/cli-onboarding.js +0 -15
- package/dist/command/cli.d.ts +14 -0
- package/dist/command/cli.js +103 -83
- package/dist/command/daemon/daemon-resilience.js +4 -4
- package/dist/command/daemon/daemon-resolve.d.ts +9 -1
- package/dist/command/daemon/daemon-resolve.js +49 -10
- package/dist/command/setup/bringup/bridge-port.d.ts +3 -1
- package/dist/command/setup/bringup/bridge-port.js +13 -3
- package/dist/command/setup/bringup/dev-server-log-cap.js +2 -0
- package/dist/command/setup/bringup/ensure-daemon.js +9 -2
- package/dist/command/setup/init/agent-restart.d.ts +23 -0
- package/dist/command/setup/init/agent-restart.js +28 -0
- package/dist/command/setup/init/init-port.d.ts +10 -1
- package/dist/command/setup/init/init-port.js +22 -2
- package/dist/command/setup/init/init-runtime.d.ts +12 -2
- package/dist/command/setup/init/init-runtime.js +96 -37
- package/dist/command/setup/node-effects.d.ts +2 -0
- package/dist/command/setup/node-effects.js +36 -8
- package/dist/command/setup/probe/existing-app.d.ts +12 -0
- package/dist/command/setup/probe/existing-app.js +14 -0
- package/dist/command/setup/remaining-steps.js +1 -1
- package/dist/command/setup/run-setup.d.ts +29 -9
- package/dist/command/setup/run-setup.js +34 -28
- package/dist/command/setup/setup-command.d.ts +23 -0
- package/dist/command/setup/setup-command.js +57 -4
- package/dist/command/setup/setup-mcp.js +25 -2
- package/dist/command/setup/tauri-signing.d.ts +19 -0
- package/dist/command/setup/tauri-signing.js +79 -0
- package/dist/command/setup/terminal/listeners.d.ts +10 -1
- package/dist/command/setup/terminal/listeners.js +37 -6
- package/dist/command/update/update-nudge.d.ts +9 -0
- package/dist/command/update/update-nudge.js +1 -1
- package/dist/command/update/updater.js +11 -15
- package/dist/command/version/version-nudge.js +3 -0
- package/dist/command/version/version-skew.d.ts +20 -1
- package/dist/command/version/version-skew.js +38 -2
- package/dist/features/crawl/crawl.js +14 -1
- package/dist/features/exhaust/ledger.d.ts +14 -14
- package/dist/features/harness/drive-report.d.ts +39 -5
- package/dist/features/harness/drive-report.js +271 -54
- package/dist/features/harness/drive-runs.d.ts +120 -0
- package/dist/features/harness/drive-runs.js +289 -0
- package/dist/features/harness/drivers.d.ts +1 -1
- package/dist/features/harness/drivers.js +1 -1
- package/dist/features/harness/explore/console-pages.d.ts +15 -0
- package/dist/features/harness/explore/console-pages.js +146 -0
- package/dist/features/harness/explore/disparity.d.ts +19 -0
- package/dist/features/harness/explore/disparity.js +71 -0
- package/dist/features/harness/explore/fake-app.d.ts +16 -0
- package/dist/features/harness/explore/fake-app.js +49 -0
- package/dist/features/harness/explore/goal-search.d.ts +26 -0
- package/dist/features/harness/explore/goal-search.js +144 -0
- package/dist/features/harness/explore/page-tree.d.ts +49 -0
- package/dist/features/harness/explore/page-tree.js +148 -0
- package/dist/features/harness/explore/site-map.d.ts +34 -0
- package/dist/features/harness/explore/site-map.js +150 -0
- package/dist/features/harness/goals.d.ts +68 -7
- package/dist/features/harness/goals.js +289 -36
- package/dist/features/harness/harness.d.ts +30 -1
- package/dist/features/harness/harness.js +141 -7
- package/dist/features/harness/platform/local-apps.d.ts +36 -3
- package/dist/features/harness/platform/local-apps.js +81 -5
- package/dist/features/harness/platform/persona-credentials.d.ts +20 -0
- package/dist/features/harness/platform/persona-credentials.js +69 -0
- package/dist/features/harness/platform/platform-drives.d.ts +61 -0
- package/dist/features/harness/platform/platform-drives.js +114 -0
- package/dist/features/harness/platform/refusal.d.ts +52 -0
- package/dist/features/harness/platform/refusal.js +71 -0
- package/dist/features/harness/platform/remote-drive.d.ts +8 -2
- package/dist/features/harness/platform/remote-drive.js +22 -9
- package/dist/features/harness/platform/script.d.ts +57 -11
- package/dist/features/harness/platform/script.js +144 -12
- package/dist/features/harness/platform/server-driver.d.ts +17 -4
- package/dist/features/harness/platform/server-driver.js +29 -26
- package/dist/features/harness/platform-config.d.ts +38 -5
- package/dist/features/harness/platform-config.js +93 -8
- package/dist/features/harness/route-guess.d.ts +13 -0
- package/dist/features/harness/route-guess.js +49 -0
- package/dist/features/harness/script/script-run.d.ts +30 -1
- package/dist/features/harness/script/script-run.js +355 -48
- package/dist/features/license/license.d.ts +2 -2
- package/dist/features/visual/step-shots.d.ts +31 -0
- package/dist/features/visual/step-shots.js +231 -0
- package/dist/features/visual/visual-tools.js +22 -14
- package/dist/hooks/client-directory.d.ts +18 -0
- package/dist/hooks/client-directory.js +57 -0
- package/dist/hooks/coding-agents.d.ts +34 -0
- package/dist/hooks/coding-agents.js +117 -0
- package/dist/hooks/driven-by.d.ts +21 -2
- package/dist/hooks/driven-by.js +42 -2
- package/dist/hooks/hook-bus.d.ts +4 -0
- package/dist/hooks/hook-bus.js +18 -0
- package/dist/index.d.ts +1 -0
- package/dist/index.js +26 -183
- package/dist/judgement/capsule/capsule-store.d.ts +2 -2
- package/dist/judgement/capsule/causal-summary.d.ts +15 -1
- package/dist/judgement/capsule/causal-summary.js +33 -0
- package/dist/judgement/runs/artifact/build-verification-run.d.ts +1 -1
- package/dist/judgement/runs/artifact/build-verification-run.js +20 -4
- package/dist/judgement/runs/artifact/gap-summary.d.ts +0 -18
- package/dist/judgement/runs/artifact/gap-summary.js +12 -3
- package/dist/judgement/runs/artifact/replay-mapping.js +25 -9
- package/dist/judgement/runs/artifact/run-store.d.ts +13 -1
- package/dist/judgement/runs/artifact/run-store.js +175 -8
- package/dist/judgement/runs/context-tools.js +59 -1
- package/dist/judgement/runs/default-run-id.d.ts +3 -0
- package/dist/judgement/runs/default-run-id.js +16 -0
- package/dist/judgement/runs/drive-run.d.ts +53 -5
- package/dist/judgement/runs/drive-run.js +234 -20
- package/dist/judgement/runs/resume.d.ts +44 -0
- package/dist/judgement/runs/resume.js +137 -0
- package/dist/judgement/runs/reticle-runner.js +5 -2
- package/dist/judgement/runs/runner-port.d.ts +5 -1
- package/dist/judgement/runs/runner-port.js +8 -2
- package/dist/judgement/runs/verification-sync.d.ts +2 -0
- package/dist/judgement/runs/verification-sync.js +36 -15
- package/dist/language/flows/decision.js +2 -1
- package/dist/language/flows/fields/flow-secret-field.d.ts +12 -0
- package/dist/language/flows/fields/flow-secret-field.js +25 -2
- package/dist/language/flows/flow-anchor.d.ts +7 -2
- package/dist/language/flows/flow-anchor.js +10 -3
- package/dist/language/flows/flow-intent.d.ts +1 -0
- package/dist/language/flows/flow-journey.d.ts +6 -0
- package/dist/language/flows/flow-journey.js +20 -0
- package/dist/language/flows/flow-learning.d.ts +4 -0
- package/dist/language/flows/flow-learning.js +37 -3
- package/dist/language/flows/flow-replay-run.js +16 -18
- package/dist/language/flows/flow-replay-types.d.ts +1 -1
- package/dist/language/flows/flow-replay.d.ts +18 -1
- package/dist/language/flows/flow-replay.js +22 -7
- package/dist/language/flows/flow-result.d.ts +22 -1
- package/dist/language/flows/flow-result.js +47 -2
- package/dist/language/flows/flow-step-runners.d.ts +2 -0
- package/dist/language/flows/flow-step-runners.js +12 -6
- package/dist/language/flows/flow-store-for-session.js +5 -1
- package/dist/language/flows/flow-tools.d.ts +10 -0
- package/dist/language/flows/flow-tools.js +61 -62
- package/dist/language/flows/flows.d.ts +16 -1
- package/dist/language/flows/flows.js +69 -10
- package/dist/language/flows/narrow-write.d.ts +7 -0
- package/dist/language/flows/narrow-write.js +36 -1
- package/dist/language/flows/recording/recording-backtrack.js +14 -1
- package/dist/language/flows/recording/tape/recordings.d.ts +29 -1
- package/dist/language/flows/recording/tape/recordings.js +60 -10
- package/dist/language/flows/replay.js +29 -6
- package/dist/language/flows/single-replay.d.ts +7 -0
- package/dist/language/flows/single-replay.js +26 -0
- package/dist/language/flows/verify-change-tools.d.ts +1 -0
- package/dist/language/flows/verify-change-tools.js +200 -193
- package/dist/memory/cloud/cloud-config.d.ts +10 -1
- package/dist/memory/cloud/cloud-config.js +19 -5
- package/dist/memory/cloud/cloud-sync.js +3 -3
- package/dist/memory/cloud/harness-config.d.ts +49 -0
- package/dist/memory/cloud/harness-config.js +16 -20
- package/dist/memory/cloud/memory-scope.d.ts +17 -0
- package/dist/memory/cloud/memory-scope.js +22 -0
- package/dist/memory/cloud/sync-cycle.d.ts +32 -4
- package/dist/memory/cloud/sync-cycle.js +113 -12
- package/dist/memory/cloud/sync-daemon.d.ts +11 -0
- package/dist/memory/cloud/sync-daemon.js +114 -4
- package/dist/memory/cloud/sync-disk.js +26 -2
- package/dist/memory/cloud/sync-screenshots.d.ts +32 -0
- package/dist/memory/cloud/sync-screenshots.js +105 -0
- package/dist/memory/cloud/unsynced-roots.d.ts +47 -0
- package/dist/memory/cloud/unsynced-roots.js +166 -0
- package/dist/memory/impact/account-watch.d.ts +16 -1
- package/dist/memory/impact/account-watch.js +26 -1
- package/dist/memory/impact/impact-store.d.ts +1 -4
- package/dist/memory/impact/impact-store.js +32 -42
- package/dist/memory/intent/inline-intent.d.ts +1 -0
- package/dist/memory/intent/intent-shard-store.js +16 -4
- package/dist/memory/intent/intent-shard.d.ts +12 -0
- package/dist/memory/intent/intent-store.d.ts +1 -0
- package/dist/memory/intent/intent-tools.js +42 -2
- package/dist/memory/intent/open-intents.d.ts +6 -0
- package/dist/memory/intent/open-intents.js +10 -1
- package/dist/memory/intent/settled-words.d.ts +24 -0
- package/dist/memory/intent/settled-words.js +130 -0
- package/dist/memory/journal/drive-flow.d.ts +16 -0
- package/dist/memory/journal/drive-flow.js +34 -2
- package/dist/memory/journal/drive-run-flush.d.ts +2 -0
- package/dist/memory/journal/drive-run-flush.js +20 -5
- package/dist/memory/journal/journal-recorder.js +46 -3
- package/dist/memory/journal/on-disk/retention.d.ts +5 -0
- package/dist/memory/journal/on-disk/retention.js +27 -2
- package/dist/memory/journal/on-disk/workspace-tiers.js +2 -0
- package/dist/memory/journal/session-end.d.ts +15 -1
- package/dist/memory/journal/session-end.js +38 -7
- package/dist/memory/project/artifact-root-resolver.js +33 -5
- package/dist/memory/project/artifact-root.d.ts +4 -3
- package/dist/memory/project/artifact-root.js +2 -2
- package/dist/memory/project/dir/reticle-dir.d.ts +14 -0
- package/dist/memory/project/dir/reticle-dir.js +23 -2
- package/dist/memory/project/link-directory.d.ts +15 -0
- package/dist/memory/project/link-directory.js +44 -0
- package/dist/memory/project/root-claims.d.ts +6 -0
- package/dist/memory/project/root-claims.js +39 -0
- package/dist/memory/project/session-root.d.ts +2 -0
- package/dist/memory/project/session-root.js +9 -1
- package/dist/memory/project/sync-status.d.ts +46 -0
- package/dist/memory/project/sync-status.js +135 -1
- package/dist/memory/recall/memory-tools.js +46 -3
- package/dist/memory/recall/platform-memory.d.ts +34 -0
- package/dist/memory/recall/platform-memory.js +139 -0
- package/dist/memory/recall/project-memory.js +36 -8
- package/dist/portal/bridge/bridge.d.ts +9 -5
- package/dist/portal/bridge/bridge.js +66 -23
- package/dist/portal/bridge/harness-request.d.ts +23 -0
- package/dist/portal/bridge/harness-request.js +27 -0
- package/dist/portal/bridge/wrong-path.d.ts +17 -0
- package/dist/portal/bridge/wrong-path.js +35 -0
- package/dist/portal/input/network-mock-tools.js +11 -2
- package/dist/portal/input/real-input.d.ts +2 -0
- package/dist/portal/input/real-input.js +13 -10
- package/dist/portal/pool/browser-pool.d.ts +48 -0
- package/dist/portal/pool/browser-pool.js +120 -2
- package/dist/portal/pool/context-permissions.d.ts +33 -0
- package/dist/portal/pool/context-permissions.js +33 -0
- package/dist/portal/pool/lease-marker-stamp.d.ts +23 -0
- package/dist/portal/pool/lease-marker-stamp.js +49 -0
- package/dist/portal/pool/playwright-launcher.d.ts +27 -5
- package/dist/portal/pool/playwright-launcher.js +59 -14
- package/dist/portal/pool/pool-contract.d.ts +21 -1
- package/dist/portal/session/agent-link.d.ts +8 -0
- package/dist/portal/session/agent-link.js +17 -0
- package/dist/portal/session/command-payload.js +6 -1
- package/dist/portal/session/daemon-answers.d.ts +3 -3
- package/dist/portal/session/daemon-answers.js +4 -2
- package/dist/portal/session/dev-server/dev-command.d.ts +9 -0
- package/dist/portal/session/dev-server/dev-command.js +27 -1
- package/dist/portal/session/facts/observed-state.d.ts +16 -18
- package/dist/portal/session/facts/observed-state.js +46 -3
- package/dist/portal/session/human/live-control.d.ts +9 -2
- package/dist/portal/session/human/live-control.js +12 -3
- package/dist/portal/session/live-control-tools.js +82 -13
- package/dist/portal/session/narration-args.d.ts +5 -0
- package/dist/portal/session/narration-args.js +17 -0
- package/dist/portal/session/no-session-diagnosis.d.ts +1 -1
- package/dist/portal/session/no-session-diagnosis.js +31 -9
- package/dist/portal/session/no-session-next-action.d.ts +20 -0
- package/dist/portal/session/no-session-next-action.js +134 -61
- package/dist/portal/session/no-session-watch.js +179 -22
- package/dist/portal/session/presence/session-lease.js +1 -1
- package/dist/portal/session/recorded-gaps.d.ts +97 -0
- package/dist/portal/session/recorded-gaps.js +251 -0
- package/dist/portal/session/session-health.d.ts +11 -0
- package/dist/portal/session/session-health.js +3 -1
- package/dist/portal/session/session-info.js +2 -1
- package/dist/portal/session/session-manager.d.ts +18 -0
- package/dist/portal/session/session-manager.js +54 -3
- package/dist/portal/session/session-successor.d.ts +8 -0
- package/dist/portal/session/session-successor.js +1 -1
- package/dist/portal/session/session.d.ts +15 -28
- package/dist/portal/session/session.js +60 -61
- package/dist/portal/session/timing/command-timeout.js +25 -1
- package/dist/portal/session/timing/wall-clock.d.ts +1 -1
- package/dist/portal/session/timing/wall-clock.js +1 -1
- package/dist/portal/session/zero-install-first-call.d.ts +31 -0
- package/dist/portal/session/zero-install-first-call.js +88 -0
- package/dist/start-options.d.ts +7 -1
- package/dist/start-wiring.d.ts +63 -0
- package/dist/start-wiring.js +169 -0
- package/dist/status-payload.d.ts +13 -1
- package/dist/status-payload.js +13 -1
- package/dist/surface/http-server.js +7 -1
- package/dist/surface/mcp/attach-memory.d.ts +1 -0
- package/dist/surface/mcp/attach-memory.js +12 -1
- package/dist/surface/mcp/mcp-proxy.d.ts +4 -0
- package/dist/surface/mcp/mcp-proxy.js +29 -8
- package/dist/surface/mcp/mcp.d.ts +23 -0
- package/dist/surface/mcp/mcp.js +34 -4
- package/dist/surface/mcp/proxy/drive-calls.d.ts +10 -0
- package/dist/surface/mcp/proxy/drive-calls.js +27 -0
- package/dist/surface/mcp/proxy/mcp-post-transport.js +5 -0
- package/dist/surface/mcp/server-instructions.js +22 -14
- package/dist/surface/mcp/shared-params.js +1 -1
- package/dist/surface/mcp/surface-vocabulary.d.ts +2 -0
- package/dist/surface/mcp/surface-vocabulary.js +1 -0
- package/dist/surface/tools/account-tool.d.ts +22 -0
- package/dist/surface/tools/account-tool.js +157 -0
- package/dist/surface/tools/act/act-danger.d.ts +11 -0
- package/dist/surface/tools/act/act-danger.js +38 -1
- package/dist/surface/tools/act/act-observation.d.ts +33 -0
- package/dist/surface/tools/act/act-observation.js +57 -0
- package/dist/surface/tools/act/act-preflight.js +25 -2
- package/dist/surface/tools/act/act-target.js +8 -3
- package/dist/surface/tools/act/resolve-target.d.ts +1 -1
- package/dist/surface/tools/act/resolve-target.js +18 -3
- package/dist/surface/tools/act/screen-request.d.ts +34 -0
- package/dist/surface/tools/act/screen-request.js +113 -0
- package/dist/surface/tools/act/sequence-grade.d.ts +8 -0
- package/dist/surface/tools/act/sequence-grade.js +13 -2
- package/dist/surface/tools/act-sequence-tool.js +136 -27
- package/dist/surface/tools/act-tools.d.ts +0 -9
- package/dist/surface/tools/act-tools.js +48 -34
- package/dist/surface/tools/agent/app-notes-learning.d.ts +7 -0
- package/dist/surface/tools/agent/app-notes-learning.js +80 -0
- package/dist/surface/tools/agent/app-notes.d.ts +4 -0
- package/dist/surface/tools/agent/app-notes.js +48 -0
- package/dist/surface/tools/agent/build-staleness.d.ts +7 -0
- package/dist/surface/tools/agent/build-staleness.js +62 -0
- package/dist/surface/tools/agent/compact-envelope.d.ts +80 -0
- package/dist/surface/tools/agent/compact-envelope.js +374 -0
- package/dist/surface/tools/agent/for-the-agent.d.ts +12 -0
- package/dist/surface/tools/agent/for-the-agent.js +44 -0
- package/dist/surface/tools/agent/notices.d.ts +50 -0
- package/dist/surface/tools/agent/notices.js +152 -0
- package/dist/surface/tools/agent/reteach.d.ts +11 -0
- package/dist/surface/tools/agent/reteach.js +50 -0
- package/dist/surface/tools/args/alias-args.d.ts +5 -0
- package/dist/surface/tools/args/alias-args.js +10 -0
- package/dist/surface/tools/args/confirm-dangerous-arg.d.ts +6 -0
- package/dist/surface/tools/args/confirm-dangerous-arg.js +6 -0
- package/dist/surface/tools/assert/assert-source.d.ts +15 -0
- package/dist/surface/tools/assert/assert-source.js +40 -0
- package/dist/surface/tools/assert/assert-verdict.js +25 -15
- package/dist/surface/tools/browser-tools.js +43 -1
- package/dist/surface/tools/chat-drives.d.ts +75 -0
- package/dist/surface/tools/chat-drives.js +265 -21
- package/dist/surface/tools/coverage-tools.d.ts +2 -10
- package/dist/surface/tools/coverage-tools.js +2 -53
- package/dist/surface/tools/dynamic-tools.js +29 -1
- package/dist/surface/tools/empty-session-list.d.ts +10 -0
- package/dist/surface/tools/empty-session-list.js +45 -5
- package/dist/surface/tools/error-recovery.d.ts +8 -0
- package/dist/surface/tools/error-recovery.js +69 -5
- package/dist/surface/tools/explore-tools.d.ts +23 -2
- package/dist/surface/tools/explore-tools.js +377 -74
- package/dist/surface/tools/feedback-tools.d.ts +2 -3
- package/dist/surface/tools/feedback-tools.js +4 -3
- package/dist/surface/tools/gap-novelty.d.ts +3 -1
- package/dist/surface/tools/gap-novelty.js +8 -1
- package/dist/surface/tools/harness-explore.d.ts +52 -73
- package/dist/surface/tools/harness-explore.js +177 -146
- package/dist/surface/tools/harness-gate.d.ts +88 -0
- package/dist/surface/tools/harness-gate.js +235 -0
- package/dist/surface/tools/harness-hunt.d.ts +43 -0
- package/dist/surface/tools/harness-hunt.js +215 -0
- package/dist/surface/tools/harness-plan.d.ts +5 -0
- package/dist/surface/tools/harness-plan.js +7 -0
- package/dist/surface/tools/harness-script.d.ts +22 -0
- package/dist/surface/tools/harness-script.js +256 -38
- package/dist/surface/tools/harness-tab-guard.d.ts +5 -0
- package/dist/surface/tools/harness-tab-guard.js +27 -0
- package/dist/surface/tools/harness-toolset.d.ts +8 -0
- package/dist/surface/tools/harness-toolset.js +27 -4
- package/dist/surface/tools/human-notes.d.ts +16 -0
- package/dist/surface/tools/human-notes.js +27 -0
- package/dist/surface/tools/invoke-tool.d.ts +5 -2
- package/dist/surface/tools/invoke-tool.js +220 -93
- package/dist/surface/tools/lease-hint.js +26 -5
- package/dist/surface/tools/lease-permissions.d.ts +33 -0
- package/dist/surface/tools/lease-permissions.js +73 -0
- package/dist/surface/tools/lease-readiness.d.ts +38 -0
- package/dist/surface/tools/lease-readiness.js +57 -0
- package/dist/surface/tools/lease-seed.d.ts +20 -0
- package/dist/surface/tools/lease-seed.js +45 -1
- package/dist/surface/tools/lease-tools.d.ts +10 -1
- package/dist/surface/tools/lease-tools.js +119 -69
- package/dist/surface/tools/live-call-text.js +2 -2
- package/dist/surface/tools/merge-tools.js +42 -2
- package/dist/surface/tools/merged-name-redirect.js +4 -0
- package/dist/surface/tools/next-step.d.ts +11 -1
- package/dist/surface/tools/next-step.js +73 -18
- package/dist/surface/tools/observe-tools.js +43 -5
- package/dist/surface/tools/platform-moment.d.ts +60 -0
- package/dist/surface/tools/platform-moment.js +132 -4
- package/dist/surface/tools/read-tools.js +65 -14
- package/dist/surface/tools/reticle-result.d.ts +120 -0
- package/dist/surface/tools/reticle-result.js +364 -0
- package/dist/surface/tools/tool-kit.d.ts +68 -2
- package/dist/surface/tools/tool-kit.js +73 -1
- package/dist/surface/tools/tools.js +25 -13
- package/dist/telemetry/account-envelope.d.ts +7 -0
- package/dist/telemetry/account-envelope.js +61 -0
- package/dist/telemetry/agent-client.d.ts +15 -0
- package/dist/telemetry/agent-client.js +57 -0
- package/dist/telemetry/app-instrumented.js +9 -2
- package/dist/telemetry/argument-shape.d.ts +7 -0
- package/dist/telemetry/argument-shape.js +86 -1
- package/dist/telemetry/automation-hint.d.ts +2 -3
- package/dist/telemetry/automation-hint.js +33 -8
- package/dist/telemetry/cli-telemetry.js +7 -2
- package/dist/telemetry/daemon-telemetry.js +3 -0
- package/dist/telemetry/error-fingerprint.d.ts +10 -1
- package/dist/telemetry/error-fingerprint.js +61 -5
- package/dist/telemetry/feedback-cli.d.ts +0 -13
- package/dist/telemetry/feedback-cli.js +0 -77
- package/dist/telemetry/feedback.d.ts +13 -0
- package/dist/telemetry/feedback.js +183 -17
- package/dist/telemetry/harness-run.d.ts +18 -0
- package/dist/telemetry/harness-run.js +80 -0
- package/dist/telemetry/hud-events.d.ts +16 -0
- package/dist/telemetry/hud-events.js +27 -0
- package/dist/telemetry/hud-metrics.d.ts +27 -6
- package/dist/telemetry/hud-metrics.js +99 -25
- package/dist/telemetry/init-telemetry.js +2 -2
- package/dist/telemetry/install-source.d.ts +13 -25
- package/dist/telemetry/install-source.js +44 -3
- package/dist/telemetry/mcp-connection.d.ts +0 -14
- package/dist/telemetry/mcp-connection.js +5 -1
- package/dist/telemetry/onboarding-firsts.d.ts +32 -0
- package/dist/telemetry/onboarding-firsts.js +81 -6
- package/dist/telemetry/platform-linked.d.ts +5 -0
- package/dist/telemetry/platform-linked.js +32 -0
- package/dist/telemetry/project-profile.js +5 -3
- package/dist/telemetry/proxy-telemetry.js +4 -1
- package/dist/telemetry/session-metrics.d.ts +15 -4
- package/dist/telemetry/session-metrics.js +88 -52
- package/dist/telemetry/telemetry.d.ts +26 -2
- package/dist/telemetry/telemetry.js +102 -21
- package/dist/telemetry/verification-of.d.ts +3 -1
- package/dist/telemetry/verification-of.js +12 -4
- package/dist/wire-journal.d.ts +2 -2
- package/dist/wire-journal.js +16 -5
- package/docs/README.md +2 -2
- package/docs/actions.mdx +6 -3
- package/docs/adapters.md +1 -1
- package/docs/agent-cheatsheet.md +24 -27
- package/docs/architecture.md +5 -5
- package/docs/autodrive.md +13 -12
- package/docs/benchmarks.md +5 -5
- package/docs/best-practices.mdx +27 -9
- package/docs/capabilities.mdx +14 -16
- package/docs/cli/affected.mdx +1 -1
- package/docs/cli/cloud.mdx +54 -75
- package/docs/cli/doctor.mdx +8 -3
- package/docs/cli/drive.mdx +12 -12
- package/docs/cli/feedback.mdx +3 -3
- package/docs/cli/gate.mdx +7 -2
- package/docs/cli/help.mdx +50 -55
- package/docs/cli/init.mdx +32 -15
- package/docs/cli/license.mdx +12 -8
- package/docs/cli/mcp.mdx +4 -4
- package/docs/cli/open.mdx +3 -3
- package/docs/cli/report.mdx +4 -2
- package/docs/cli/restart.mdx +2 -2
- package/docs/cli/rollback.mdx +14 -8
- package/docs/cli/serve.mdx +4 -4
- package/docs/cli/setup.mdx +23 -0
- package/docs/cli/status.mdx +13 -4
- package/docs/cli/stop.mdx +67 -8
- package/docs/cli/try.mdx +62 -0
- package/docs/cli/update.mdx +4 -3
- package/docs/cli/verify.mdx +17 -6
- package/docs/cli/version.mdx +3 -2
- package/docs/cli.mdx +110 -41
- package/docs/debugging.md +3 -3
- package/docs/deploy-checks.md +1 -1
- package/docs/desktop.mdx +5 -3
- package/docs/enterprise.md +11 -10
- package/docs/environment.mdx +5 -2
- package/docs/faq.mdx +3 -3
- package/docs/first-drive.md +5 -4
- package/docs/flows.md +35 -27
- package/docs/for-agents.md +4 -5
- package/docs/frameworks.mdx +32 -21
- package/docs/getting-started.md +66 -64
- package/docs/human-control.md +15 -14
- package/docs/index.mdx +15 -43
- package/docs/install-agentic.mdx +22 -37
- package/docs/install-manual.mdx +22 -12
- package/docs/instrumentation.mdx +5 -3
- package/docs/integration-patterns.md +7 -7
- package/docs/license-activation.mdx +1 -1
- package/docs/multi-agent-testing.md +24 -6
- package/docs/packages/babel-plugin.mdx +4 -2
- package/docs/packages/browser.mdx +16 -10
- package/docs/packages/core.mdx +12 -5
- package/docs/packages/electron.mdx +3 -2
- package/docs/packages/engine.mdx +1 -1
- package/docs/packages/eslint-plugin.mdx +18 -12
- package/docs/packages/next.mdx +8 -7
- package/docs/packages/open-verification.mdx +1 -1
- package/docs/packages/server.mdx +5 -5
- package/docs/packages/tauri.mdx +8 -8
- package/docs/packages/test.mdx +4 -10
- package/docs/packages/vite-plugin.mdx +11 -4
- package/docs/packages.mdx +11 -15
- package/docs/platform-integration.md +6 -5
- package/docs/predicates.mdx +40 -24
- package/docs/quickstart.mdx +58 -29
- package/docs/required-checks.md +8 -7
- package/docs/reticle-manual.md +15 -5
- package/docs/skill-file.mdx +17 -79
- package/docs/skill-setup.md +9 -9
- package/docs/skill.md +200 -0
- package/docs/system-map.md +7 -7
- package/docs/telemetry.md +22 -24
- package/docs/testing.md +4 -4
- package/docs/token-efficiency.md +12 -12
- package/docs/tools/act-and-wait.mdx +9 -2
- package/docs/tools/act-sequence.mdx +6 -7
- package/docs/tools/act.mdx +2 -2
- package/docs/tools/assert.mdx +18 -17
- package/docs/tools/console.mdx +9 -9
- package/docs/tools/inspect.mdx +16 -7
- package/docs/tools/look.mdx +24 -0
- package/docs/tools/navigate.mdx +5 -3
- package/docs/tools/network.mdx +2 -2
- package/docs/tools/observe.mdx +6 -6
- package/docs/tools/overview.mdx +34 -33
- package/docs/tools/query.mdx +5 -5
- package/docs/tools/session-and-feedback.mdx +13 -4
- package/docs/tools/sessions.mdx +8 -8
- package/docs/tools/snapshot.mdx +6 -5
- package/docs/tools/state.mdx +9 -9
- package/docs/tools/tools-and-run.mdx +26 -24
- package/docs/tools/verify.mdx +28 -0
- package/docs/tools/wait-for.mdx +8 -4
- package/docs/troubleshooting.mdx +21 -6
- package/docs/usage.md +51 -45
- package/docs/use-cases.mdx +3 -3
- package/docs/vs-chrome-devtools-mcp.mdx +9 -6
- package/docs/vs-playwright-mcp.mdx +3 -1
- package/docs/what-is-recorded.md +7 -5
- package/docs/what-is-reticle.mdx +2 -2
- package/docs/why-reticle.mdx +1 -1
- package/package.json +6 -5
- package/dist/command/cli/demo/demo-page.d.ts +0 -78
- package/dist/command/cli/demo/demo-page.js +0 -249
- package/dist/command/cli/demo/demo-run.d.ts +0 -38
- package/dist/command/cli/demo/demo-run.js +0 -138
- package/dist/judgement/hunt/hunt-report.d.ts +0 -49
- package/dist/judgement/hunt/hunt-report.js +0 -84
- package/dist/language/flows/buddy-status.d.ts +0 -25
- package/dist/language/flows/buddy-status.js +0 -32
- package/dist/language/flows/change/watch-batcher.d.ts +0 -18
- package/dist/language/flows/change/watch-batcher.js +0 -19
- package/dist/memory/cloud/harness-offer.d.ts +0 -44
- package/dist/memory/cloud/harness-offer.js +0 -145
- package/dist/surface/tools/feature-capture.d.ts +0 -151
- package/dist/surface/tools/feature-capture.js +0 -235
- package/dist/surface/tools/tool-hit-rate.d.ts +0 -87
- package/dist/surface/tools/tool-hit-rate.js +0 -90
- package/dist/telemetry/harness-drive.d.ts +0 -4
- package/dist/telemetry/harness-drive.js +0 -35
- package/dist/telemetry/identify.d.ts +0 -22
- package/dist/telemetry/identify.js +0 -73
- package/docs/cli/capsules.mdx +0 -70
- package/docs/cli/hunt.mdx +0 -73
- package/docs/cli/identify.mdx +0 -76
- package/docs/cli/kill.mdx +0 -91
- package/docs/cli/watch.mdx +0 -62
|
@@ -0,0 +1,29 @@
|
|
|
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 { RunFlowStatus, VerdictStatus, Verified, } from '@reticlehq/core';
|
|
9
|
+
function journeyVerdict(status) {
|
|
10
|
+
if (RunFlowStatus.FAIL === status)
|
|
11
|
+
return Verified.NO;
|
|
12
|
+
// A heal is consequence-verified before it is reported, so it proves as much as a pass.
|
|
13
|
+
if (RunFlowStatus.PASS === status || RunFlowStatus.HEALED === status)
|
|
14
|
+
return Verified.YES;
|
|
15
|
+
return Verified.UNKNOWN;
|
|
16
|
+
}
|
|
17
|
+
export function verifyResults(run) {
|
|
18
|
+
const results = run.flows.map((flow) => ({
|
|
19
|
+
journey: flow.name,
|
|
20
|
+
verdict: journeyVerdict(flow.status),
|
|
21
|
+
...(flow.failureReason === undefined ? {} : { reason: flow.failureReason }),
|
|
22
|
+
}));
|
|
23
|
+
const verdict = results.some((r) => Verified.NO === r.verdict)
|
|
24
|
+
? Verified.NO
|
|
25
|
+
: VerdictStatus.PASS === run.verdict.status && results.every((r) => Verified.YES === r.verdict)
|
|
26
|
+
? Verified.YES
|
|
27
|
+
: Verified.UNKNOWN;
|
|
28
|
+
return { verdict, results };
|
|
29
|
+
}
|
|
@@ -8,14 +8,3 @@ import type { OnboardingStep } from '@reticlehq/core/telemetry';
|
|
|
8
8
|
* reporter is built here and handed down to every command that needs one.
|
|
9
9
|
*/
|
|
10
10
|
export declare const reportStepFromCli: (step: OnboardingStep) => void;
|
|
11
|
-
/**
|
|
12
|
-
* The two ONBOARD steps `reticle tutorial` can honestly answer.
|
|
13
|
-
*
|
|
14
|
-
* Asking for the tour is a fact here, and so is having been shown what Reticle is. Whether the
|
|
15
|
-
* reader then looked, acted or proved is not — even on `tutorial --run`, which drives the demo: those
|
|
16
|
-
* three are reported by the daemon at the first look / act / verdict it actually witnesses, through
|
|
17
|
-
* the dispatch chokepoint, because that is the only place they are observations rather than claims.
|
|
18
|
-
* Reporting them from here would turn "the tour reached step four" into "somebody verified something",
|
|
19
|
-
* which is the same substitution the fourth step of the tour exists to warn about.
|
|
20
|
-
*/
|
|
21
|
-
export declare function reportTutorialShown(): void;
|
|
@@ -1,5 +1,4 @@
|
|
|
1
1
|
import { reportOnboardingStep } from '../telemetry/onboarding-funnel.js';
|
|
2
|
-
import { tutorialShownSteps } from './cli/tutorial.js';
|
|
3
2
|
/**
|
|
4
3
|
* The CLI's half of the setup funnel.
|
|
5
4
|
*
|
|
@@ -11,17 +10,3 @@ import { tutorialShownSteps } from './cli/tutorial.js';
|
|
|
11
10
|
export const reportStepFromCli = (step) => {
|
|
12
11
|
void reportOnboardingStep(step);
|
|
13
12
|
};
|
|
14
|
-
/**
|
|
15
|
-
* The two ONBOARD steps `reticle tutorial` can honestly answer.
|
|
16
|
-
*
|
|
17
|
-
* Asking for the tour is a fact here, and so is having been shown what Reticle is. Whether the
|
|
18
|
-
* reader then looked, acted or proved is not — even on `tutorial --run`, which drives the demo: those
|
|
19
|
-
* three are reported by the daemon at the first look / act / verdict it actually witnesses, through
|
|
20
|
-
* the dispatch chokepoint, because that is the only place they are observations rather than claims.
|
|
21
|
-
* Reporting them from here would turn "the tour reached step four" into "somebody verified something",
|
|
22
|
-
* which is the same substitution the fourth step of the tour exists to warn about.
|
|
23
|
-
*/
|
|
24
|
-
export function reportTutorialShown() {
|
|
25
|
-
for (const step of tutorialShownSteps())
|
|
26
|
-
reportStepFromCli(step);
|
|
27
|
-
}
|
package/dist/command/cli.d.ts
CHANGED
|
@@ -2,6 +2,20 @@
|
|
|
2
2
|
import { parseCliArgs, CLI_USAGE } from './cli/cli-parse.js';
|
|
3
3
|
export { parseCliArgs, CLI_USAGE };
|
|
4
4
|
export type { CliResult } from './cli/cli-parse.js';
|
|
5
|
+
/**
|
|
6
|
+
* Said last, when the account is linked and the one thing left is installing a dependency. Exit 0:
|
|
7
|
+
* connect's job — signing in and linking — is done, and a non-zero exit read as a failed connect.
|
|
8
|
+
*/
|
|
9
|
+
export declare const MSG_CONNECTED_DEPS_PENDING: string;
|
|
10
|
+
/**
|
|
11
|
+
* How `reticle connect` exits: the cloud step's code when linking failed; 0 when it linked and setup
|
|
12
|
+
* finished or left only the dependency install (said in `note`); 1 when setup stopped for anything
|
|
13
|
+
* else. `initUnfinished` is why init's setup did not finish, or undefined when it did.
|
|
14
|
+
*/
|
|
15
|
+
export declare function connectExit(cloudCode: number, initUnfinished: string | undefined): {
|
|
16
|
+
code: number;
|
|
17
|
+
note?: string;
|
|
18
|
+
};
|
|
5
19
|
/**
|
|
6
20
|
* Report status to the terminal. `--json` writes one structured line to STDOUT so it can be piped
|
|
7
21
|
* into `jq`; the human-readable block goes to stdout too. `log()` stays on stderr (the MCP
|
package/dist/command/cli.js
CHANGED
|
@@ -1,9 +1,8 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
|
+
import { PlatformLinkVia } from '@reticlehq/core/telemetry';
|
|
2
3
|
import { hudSignIn } from './cli/cloud-login.js';
|
|
3
4
|
import { handleSetupMcp, handleSetupInstall } from './cli/setup-mcp-cli.js';
|
|
4
|
-
import { reportStepFromCli
|
|
5
|
-
import { runDemoTour } from './cli/demo/demo-run.js';
|
|
6
|
-
import { renderTutorial } from './cli/tutorial.js';
|
|
5
|
+
import { reportStepFromCli } from './cli-onboarding.js';
|
|
7
6
|
import { pathToFileURL } from 'node:url';
|
|
8
7
|
import { openFailureNote, openLaunchFailureNote } from './cli/answers/open-note.js';
|
|
9
8
|
import { realpathSync } from 'node:fs';
|
|
@@ -16,21 +15,24 @@ import { splitBrainFields, withNextAction } from './cli/status-fields.js';
|
|
|
16
15
|
import { reticleStateHome } from './daemon/daemon.js';
|
|
17
16
|
import { handleMcp } from './cli/mcp-command.js';
|
|
18
17
|
import { handleReport } from './cli/report-command.js';
|
|
18
|
+
import { handleContext } from './cli/context-command.js';
|
|
19
19
|
import { daemonProjectAt, readDaemonRegistry, resolveDaemonForProject, } from './daemon/daemon-resolve.js';
|
|
20
20
|
import { pickDaemonPortToBind } from './daemon/binding/free-port.js';
|
|
21
21
|
import { isSameOrAbove, portForInit, portFromEnv } from './setup/init/init-port.js';
|
|
22
22
|
import { daemonStartOptions } from './cli/daemon-start-options.js';
|
|
23
|
-
import {
|
|
23
|
+
import { handleGate, loadNamedFlows, resolveChangedFiles } from './cli/cli-flow-commands.js';
|
|
24
24
|
import { RETICLE_DEFAULT_PORT, ReticleDir, ReticleEnv, devServersForProject, } from '@reticlehq/core';
|
|
25
25
|
import { loadDotEnv } from '../telemetry/dev-repo.js';
|
|
26
26
|
import { licenseKeyFromEnvFiles } from '../features/license/license-env.js';
|
|
27
27
|
import { LICENSE_KEY_ENV } from '../features/license/license.js';
|
|
28
28
|
import { createNodeFileSystem } from '../memory/project/fs/fs-port.js';
|
|
29
|
+
import { localLinkOf, workspaceAppLinks } from './cli/status/workspace-links.js';
|
|
29
30
|
import { affectedSavedFlows } from '../language/flows/change/flow-sources.js';
|
|
30
31
|
import { availableUpdate } from './update/update-nudge.js';
|
|
31
32
|
import { handleUpdate, handleRollback } from './cli/cli-update-commands.js';
|
|
33
|
+
import { headlessByDefault } from './cli/daemon-start-options.js';
|
|
32
34
|
import { startDaemon } from '../index.js';
|
|
33
|
-
import { isCloudCommand, runCloudCommand } from './cli/cloud-cli.js';
|
|
35
|
+
import { accountStatusFields, cmdLink, connectInstalls, isCloudCommand, runCloudCommand, } from './cli/cloud-cli.js';
|
|
34
36
|
import { SERVER_VERSION } from './version/identity/server-version.js';
|
|
35
37
|
import { log } from '../log.js';
|
|
36
38
|
import { readPid, isAlive, removePid, spawnDaemon, discoverDaemonPort, writeDaemonRegistry, } from './daemon/daemon.js';
|
|
@@ -46,20 +48,46 @@ import { fetchStatus } from './daemon/binding/daemon-status-probe.js';
|
|
|
46
48
|
import { handleDrive } from './cli/drive/drive-command.js';
|
|
47
49
|
import { handleVerify } from './cli/cli-verify.js';
|
|
48
50
|
import { runKill } from './cli/cli-kill.js';
|
|
49
|
-
import {
|
|
50
|
-
import { runInit, buildNodeIo } from '@reticlehq/init';
|
|
51
|
+
import { runInit, buildNodeIo, InitFailure } from '@reticlehq/init';
|
|
51
52
|
import { continueAfterInit } from './setup/init/init-runtime.js';
|
|
53
|
+
import { initFirstFlow } from './cli/try-command.js';
|
|
52
54
|
import { handleDoctor } from './cli/cli-doctor.js';
|
|
53
55
|
import { serverInitHost } from './setup/init/init-host.js';
|
|
54
56
|
import { describeLicense } from '../features/license/license.js';
|
|
55
57
|
import { isLikelyDevServerPort, devServerPortWarning, readProjectPort, readProjectId, workspacePortConflict, projectDirOf, } from './cli/ports/resolve/cli-port.js';
|
|
56
|
-
import { nodeSpawner, readTextFile, reexecAtVersion, versionMatchNote, versionToMatch, } from './cli/launch/sdk-version-match.js';
|
|
58
|
+
import { helpRunsAt, helpVersionNote, nodeSpawner, readTextFile, reexecAtVersion, versionMatchNote, versionToMatch, } from './cli/launch/sdk-version-match.js';
|
|
57
59
|
import { DAEMON_INNER_COMMAND, PORT_FLAG, parseCliArgs, CLI_USAGE, dialsTheDaemon, } from './cli/cli-parse.js';
|
|
58
|
-
import {
|
|
60
|
+
import { renderHelp } from './cli/cli-usage.js';
|
|
61
|
+
import { RENAMED_COMMANDS, renamedCommandFor, renamedNote } from './cli/cli-parse-grammar.js';
|
|
62
|
+
import { handleFeedback, handleTelemetry } from '../telemetry/feedback-cli.js';
|
|
59
63
|
import { installDaemonTelemetry } from '../telemetry/daemon-telemetry.js';
|
|
60
64
|
import { reportCliRun } from '../telemetry/cli-telemetry.js';
|
|
61
65
|
// Re-exported so existing imports (and the CLI tests) keep resolving from '@/cli.js'.
|
|
62
66
|
export { parseCliArgs, CLI_USAGE };
|
|
67
|
+
/** Said when `connect` carries on past an init whose setup did not finish. */
|
|
68
|
+
const MSG_CONNECT_AFTER_UNFINISHED_INIT = 'Setup did not finish (above) — signing in and linking anyway. Fix what it names, then run ' +
|
|
69
|
+
'`reticle init` again.';
|
|
70
|
+
/**
|
|
71
|
+
* Said last, when the account is linked and the one thing left is installing a dependency. Exit 0:
|
|
72
|
+
* connect's job — signing in and linking — is done, and a non-zero exit read as a failed connect.
|
|
73
|
+
*/
|
|
74
|
+
export const MSG_CONNECTED_DEPS_PENDING = '⚠ Connected, but the dependency install did not finish (see above). Run the install it names, ' +
|
|
75
|
+
'then `reticle init` to wire the app.';
|
|
76
|
+
/**
|
|
77
|
+
* How `reticle connect` exits: the cloud step's code when linking failed; 0 when it linked and setup
|
|
78
|
+
* finished or left only the dependency install (said in `note`); 1 when setup stopped for anything
|
|
79
|
+
* else. `initUnfinished` is why init's setup did not finish, or undefined when it did.
|
|
80
|
+
*/
|
|
81
|
+
export function connectExit(cloudCode, initUnfinished) {
|
|
82
|
+
if (0 !== cloudCode)
|
|
83
|
+
return { code: cloudCode };
|
|
84
|
+
if (initUnfinished === undefined)
|
|
85
|
+
return { code: 0 };
|
|
86
|
+
if (InitFailure.DEPENDENCY_INSTALL === initUnfinished) {
|
|
87
|
+
return { code: 0, note: MSG_CONNECTED_DEPS_PENDING };
|
|
88
|
+
}
|
|
89
|
+
return { code: 1 };
|
|
90
|
+
}
|
|
63
91
|
async function handleInit(parsed) {
|
|
64
92
|
const cwd = process.cwd();
|
|
65
93
|
// RETICLE_PORT counts as explicit, as it does for every other command: resolved once here, so the
|
|
@@ -83,7 +111,7 @@ async function handleInit(parsed) {
|
|
|
83
111
|
const started = readDaemonRegistry(reticleStateHome()).find((e) => e.port === p)?.cwd;
|
|
84
112
|
return started !== undefined && isSameOrAbove(started, cwd);
|
|
85
113
|
},
|
|
86
|
-
});
|
|
114
|
+
}, cwd);
|
|
87
115
|
const io = buildNodeIo(cwd, serverInitHost(), { stderr: true === parsed.json });
|
|
88
116
|
const result = runInit({
|
|
89
117
|
cwd,
|
|
@@ -102,7 +130,8 @@ async function handleInit(parsed) {
|
|
|
102
130
|
deferOutcome: true,
|
|
103
131
|
continuesToRuntime: true !== parsed.filesOnly && true !== parsed.dryRun,
|
|
104
132
|
}, io);
|
|
105
|
-
await continueAfterInit({ ...parsed, port }, result, io, cwd);
|
|
133
|
+
await continueAfterInit({ ...parsed, port }, result, io, cwd, initFirstFlow);
|
|
134
|
+
return result;
|
|
106
135
|
}
|
|
107
136
|
// `serve`, `stop` and `restart` live in `cli/lifecycle/daemon-lifecycle.ts`: one idea, and the
|
|
108
137
|
// largest group this file could give up without splitting something that belongs together.
|
|
@@ -126,7 +155,15 @@ export function reportStatus(fields, json) {
|
|
|
126
155
|
process.stdout.write(`${statusLines(fields).join('\n')}\n`);
|
|
127
156
|
}
|
|
128
157
|
export async function handleStatus(port, json = false) {
|
|
129
|
-
|
|
158
|
+
// A broken session file must not cost the reader the rest of the status.
|
|
159
|
+
const account = await accountStatusFields().catch(() => ({}));
|
|
160
|
+
// At a workspace root that is no app of its own, each app and its link: "not linked" named none.
|
|
161
|
+
const linked = account.linkedProject;
|
|
162
|
+
if ('string' !== typeof linked && readProjectId(process.cwd()) === undefined)
|
|
163
|
+
Object.assign(account, {
|
|
164
|
+
workspaceApps: await workspaceAppLinks(process.cwd(), localLinkOf).catch(() => []),
|
|
165
|
+
});
|
|
166
|
+
const report = (fields) => reportStatus({ ...fields, ...account }, json);
|
|
130
167
|
const pid = readPid(port);
|
|
131
168
|
// Durable, so it survives the daemon idling out — which is the state `status` is most often run in.
|
|
132
169
|
const projectId = readProjectId(process.cwd());
|
|
@@ -269,42 +306,6 @@ async function handleAffected(files, since) {
|
|
|
269
306
|
});
|
|
270
307
|
}
|
|
271
308
|
}
|
|
272
|
-
/**
|
|
273
|
-
* `reticle hunt <dir>` — aggregate crawl reports from many checkouts into one number.
|
|
274
|
-
*
|
|
275
|
-
* Detection already exists (`reticle_crawl`). This is the arithmetic that turns a pile of runs into
|
|
276
|
-
* the claim worth making: over N already-merged, already-green changes, how many carried a candidate
|
|
277
|
-
* false green? No control arm is needed, because those changes SHIPPED — the counterfactual is
|
|
278
|
-
* already established, which is what makes this the cheapest credible evidence available.
|
|
279
|
-
*
|
|
280
|
-
* Each file in <dir> is one crawl result. Producing them is a shell loop over a commit range:
|
|
281
|
-
* check out, boot the app, `reticle_crawl`, write the JSON here.
|
|
282
|
-
*/
|
|
283
|
-
async function handleHunt(dir) {
|
|
284
|
-
try {
|
|
285
|
-
const fs = createNodeFileSystem();
|
|
286
|
-
const names = await fs.readdir(dir);
|
|
287
|
-
const runs = [];
|
|
288
|
-
for (const name of names.filter((n) => n.endsWith('.json'))) {
|
|
289
|
-
const raw = await fs.readFile(join(dir, name));
|
|
290
|
-
if (raw === undefined)
|
|
291
|
-
continue;
|
|
292
|
-
const parsed = JSON.parse(raw);
|
|
293
|
-
const report = parsed;
|
|
294
|
-
runs.push({
|
|
295
|
-
label: report.label ?? name.replace(/\.json$/, ''),
|
|
296
|
-
anomalies: report.anomalies ?? [],
|
|
297
|
-
...(report.stepsRun === undefined ? {} : { stepsRun: report.stepsRun }),
|
|
298
|
-
});
|
|
299
|
-
}
|
|
300
|
-
log('reticle_hunt', { ...summarizeHunt(runs) });
|
|
301
|
-
}
|
|
302
|
-
catch (error) {
|
|
303
|
-
log('reticle_hunt_failed', {
|
|
304
|
-
error: error instanceof Error ? error.message : String(error),
|
|
305
|
-
});
|
|
306
|
-
}
|
|
307
|
-
}
|
|
308
309
|
/** Ensure a daemon is reachable on `port` (probe the real port; spawn + wait only if nothing's there). */
|
|
309
310
|
function ensureDaemon(port) {
|
|
310
311
|
return probePresence(port, { tcpOpen: probeDaemon, status: fetchStatus }).then(async (presence) => {
|
|
@@ -437,7 +438,11 @@ function handleOpen(requestedPort, url) {
|
|
|
437
438
|
}
|
|
438
439
|
function handleDaemonInner(parsed) {
|
|
439
440
|
// The daemon the CLI starts is the one that can sign in for the panel: it owns ~/.reticle.
|
|
440
|
-
const options = {
|
|
441
|
+
const options = {
|
|
442
|
+
...daemonStartOptions(parsed),
|
|
443
|
+
hudSignIn: (repaint, link) => hudSignIn(repaint, undefined, undefined, link),
|
|
444
|
+
hudLink: (root) => cmdLink([], root, PlatformLinkVia.HUD),
|
|
445
|
+
};
|
|
441
446
|
startDaemon(options)
|
|
442
447
|
.then((server) => {
|
|
443
448
|
log('reticle_daemon_ready', { port: parsed.port, pid: process.pid });
|
|
@@ -555,13 +560,15 @@ export function main() {
|
|
|
555
560
|
// `version_skew`, and the unpinned `npx @reticlehq/server` every agent entry uses resolves the
|
|
556
561
|
// LATEST major whatever the project installed. Hand the same arguments to the matching release and
|
|
557
562
|
// step aside — it reports its own run. See cli/launch/sdk-version-match.ts.
|
|
558
|
-
|
|
563
|
+
// One project lookup for both questions below: it reads config and walks the workspace.
|
|
564
|
+
const versionInput = {
|
|
559
565
|
argv,
|
|
560
566
|
cliVersion: SERVER_VERSION,
|
|
561
567
|
env: process.env,
|
|
562
568
|
projectDir: projectDirOf(process.cwd()),
|
|
563
569
|
readFile: readTextFile,
|
|
564
|
-
}
|
|
570
|
+
};
|
|
571
|
+
const matchVersion = versionToMatch(versionInput);
|
|
565
572
|
if (matchVersion !== undefined) {
|
|
566
573
|
process.stderr.write(`${versionMatchNote(matchVersion, SERVER_VERSION)}\n`);
|
|
567
574
|
reexecAtVersion(matchVersion, argv, process.env, {
|
|
@@ -571,6 +578,11 @@ export function main() {
|
|
|
571
578
|
});
|
|
572
579
|
return;
|
|
573
580
|
}
|
|
581
|
+
// Help stays on this binary, so say which version the command it describes really runs at (#1378).
|
|
582
|
+
const helpVersion = helpRunsAt(versionInput);
|
|
583
|
+
if (helpVersion !== undefined) {
|
|
584
|
+
process.stdout.write(`${helpVersionNote(helpVersion, SERVER_VERSION)}\n\n`);
|
|
585
|
+
}
|
|
574
586
|
// Every invocation passes through here — the single chokepoint for the "how often is it used / how
|
|
575
587
|
// many distinct machines + projects" metrics. Fire-and-forget: a metric must never delay or fail a run.
|
|
576
588
|
//
|
|
@@ -582,6 +594,13 @@ export function main() {
|
|
|
582
594
|
// just the scale, which is the kind of error you cannot correct for after the fact. The daemon's
|
|
583
595
|
// own lifecycle is already reported by `daemon_started` / `daemon_stopped`; it is not a CLI run.
|
|
584
596
|
reportCliRun(argv);
|
|
597
|
+
// An old name still runs, for one release, and says once what it is called now. Not when the
|
|
598
|
+
// person only asked for help: that answer names the new command itself, on stdout.
|
|
599
|
+
const renamedTo = renamedCommandFor(argv);
|
|
600
|
+
if (renamedTo !== undefined) {
|
|
601
|
+
const colour = true === process.stderr.isTTY && process.env['NO_COLOR'] === undefined;
|
|
602
|
+
process.stderr.write(`${renamedNote(argv[0] ?? '', renamedTo, colour)}\n`);
|
|
603
|
+
}
|
|
585
604
|
// Cloud subcommands (login/link/project/config/push) are a distinct family with their own async client;
|
|
586
605
|
// handle them before the local typed parser so `reticle login` etc. work as one tool.
|
|
587
606
|
if (isCloudCommand(argv[0])) {
|
|
@@ -590,17 +609,39 @@ export function main() {
|
|
|
590
609
|
// `reticle link --help` used to run the command: it reached for the network and answered
|
|
591
610
|
// `fetch failed` with exit 1, to somebody who had asked what the command was for.
|
|
592
611
|
if (argv.some((arg) => '--help' === arg || '-h' === arg)) {
|
|
593
|
-
process.stdout.write(`${
|
|
612
|
+
process.stdout.write(`${renderHelp(argv[0], RENAMED_COMMANDS)}\n`);
|
|
594
613
|
return;
|
|
595
614
|
}
|
|
596
615
|
if ('connect' === argv[0]) {
|
|
597
616
|
void (async () => {
|
|
598
617
|
// A fresh project gets the same install, dev-server handover and browser proof as `init`.
|
|
599
618
|
// Its failure exits non-zero before any cloud binding can claim this repo is ready.
|
|
619
|
+
// A setup that did not finish is said above and still fails the run, but no longer ends it
|
|
620
|
+
// before sign-in: the second identical run was the only way to get signed in.
|
|
621
|
+
let unfinished;
|
|
600
622
|
if (readProjectId(process.cwd()) === undefined) {
|
|
601
|
-
await handleInit({
|
|
623
|
+
const init = await handleInit({
|
|
624
|
+
port: undefined,
|
|
625
|
+
mcp: true,
|
|
626
|
+
dryRun: false,
|
|
627
|
+
install: connectInstalls(argv),
|
|
628
|
+
keepGoing: true,
|
|
629
|
+
});
|
|
630
|
+
if (1 === process.exitCode) {
|
|
631
|
+
// init hands no context over exactly when the dependency install failed (run.ts); its
|
|
632
|
+
// outcome's own reason is unset when the files were all written and the app was not.
|
|
633
|
+
unfinished =
|
|
634
|
+
init.context === undefined && init.outcome !== undefined
|
|
635
|
+
? InitFailure.DEPENDENCY_INSTALL
|
|
636
|
+
: (init.outcome?.reason ?? InitFailure.OTHER);
|
|
637
|
+
process.exitCode = 0;
|
|
638
|
+
process.stderr.write(`${MSG_CONNECT_AFTER_UNFINISHED_INIT}\n`);
|
|
639
|
+
}
|
|
602
640
|
}
|
|
603
|
-
|
|
641
|
+
const exit = connectExit(await runCloudCommand(argv), unfinished);
|
|
642
|
+
if (exit.note !== undefined)
|
|
643
|
+
process.stderr.write(`${exit.note}\n`);
|
|
644
|
+
return exit.code;
|
|
604
645
|
})()
|
|
605
646
|
.then((code) => process.exit(code))
|
|
606
647
|
.catch((cause) => {
|
|
@@ -641,7 +682,7 @@ export function main() {
|
|
|
641
682
|
const defaultPort = envPort ?? projectPort ?? myDaemonPort ?? RETICLE_DEFAULT_PORT;
|
|
642
683
|
// Headed by default; hidden only where there is no display to be headed on. A run nobody can see
|
|
643
684
|
// is a run nobody trusts, and every "did it actually do anything?" cost a human round-trip.
|
|
644
|
-
const parsed = parseCliArgs(argv, defaultPort, process.env
|
|
685
|
+
const parsed = parseCliArgs(argv, defaultPort, headlessByDefault(process.env, process.platform));
|
|
645
686
|
// The refusal the line above promised. Printing it and carrying on let the default port answer
|
|
646
687
|
// anyway, for whichever project's daemon owned it.
|
|
647
688
|
if (portConflict !== undefined && dialsTheDaemon(parsed)) {
|
|
@@ -686,14 +727,15 @@ export function main() {
|
|
|
686
727
|
case 'feedback':
|
|
687
728
|
void handleFeedback(parsed.text, parsed.rating, parsed.bug, parsed.feedbackKind, parsed.agent);
|
|
688
729
|
break;
|
|
689
|
-
case 'identify':
|
|
690
|
-
void handleIdentify(parsed);
|
|
691
|
-
break;
|
|
692
730
|
case 'version':
|
|
693
731
|
handleVersion();
|
|
694
732
|
break;
|
|
695
733
|
case 'help':
|
|
696
|
-
process.stdout.write(`${
|
|
734
|
+
process.stdout.write(`${renderHelp(parsed.topic, RENAMED_COMMANDS)}\n`);
|
|
735
|
+
break;
|
|
736
|
+
case 'removed':
|
|
737
|
+
process.stderr.write(`${parsed.message}\n`);
|
|
738
|
+
process.exit(1);
|
|
697
739
|
break;
|
|
698
740
|
case 'doctor':
|
|
699
741
|
void handleDoctor(parsed.port);
|
|
@@ -708,22 +750,6 @@ export function main() {
|
|
|
708
750
|
mcp: parsed.mcp,
|
|
709
751
|
}, reportStepFromCli);
|
|
710
752
|
break;
|
|
711
|
-
case 'tutorial':
|
|
712
|
-
// Reported for BOTH paths, and before either: a run is a tour too, and these two steps are
|
|
713
|
-
// about the tour being asked for, which is already true by the time we get here.
|
|
714
|
-
reportTutorialShown();
|
|
715
|
-
if (parsed.run) {
|
|
716
|
-
void runDemoTour({
|
|
717
|
-
port: parsed.port,
|
|
718
|
-
headless: parsed.headless,
|
|
719
|
-
say: (line) => process.stdout.write(`${line}\n`),
|
|
720
|
-
}).then((result) => {
|
|
721
|
-
process.exit(result.code);
|
|
722
|
-
});
|
|
723
|
-
break;
|
|
724
|
-
}
|
|
725
|
-
process.stdout.write(`${renderTutorial(parsed.audience)}\n`);
|
|
726
|
-
break;
|
|
727
753
|
case 'open':
|
|
728
754
|
handleOpen(parsed.port, parsed.url);
|
|
729
755
|
break;
|
|
@@ -733,23 +759,17 @@ export function main() {
|
|
|
733
759
|
case 'verify':
|
|
734
760
|
handleVerify(parsed);
|
|
735
761
|
break;
|
|
736
|
-
case 'capsules':
|
|
737
|
-
void handleCapsules();
|
|
738
|
-
break;
|
|
739
762
|
case 'affected':
|
|
740
763
|
void handleAffected(parsed.files, parsed.since);
|
|
741
764
|
break;
|
|
742
|
-
case 'hunt':
|
|
743
|
-
void handleHunt(parsed.dir);
|
|
744
|
-
break;
|
|
745
765
|
case 'gate':
|
|
746
766
|
void handleGate(parsed.files, parsed.since, parsed.hook, parsed.acceptCoverage);
|
|
747
767
|
break;
|
|
748
768
|
case 'report':
|
|
749
769
|
void handleReport(parsed.session, parsed.hook);
|
|
750
770
|
break;
|
|
751
|
-
case '
|
|
752
|
-
|
|
771
|
+
case 'context':
|
|
772
|
+
void handleContext(parsed.session);
|
|
753
773
|
break;
|
|
754
774
|
case 'update':
|
|
755
775
|
void handleUpdate();
|
|
@@ -8,7 +8,7 @@
|
|
|
8
8
|
* per Node's guidance, so LOG a clear reason and exit cleanly; the next `reticle mcp` respawns a fresh
|
|
9
9
|
* daemon, which beats crashing silently or limping along corrupt.
|
|
10
10
|
*/
|
|
11
|
-
import { RETICLE_DEFAULT_PORT,
|
|
11
|
+
import { RETICLE_DEFAULT_PORT, TelemetryEventKind } from '@reticlehq/core';
|
|
12
12
|
import { errorSkeleton, errorTypeOf, fingerprintCrash, MAX_REPORTED_FRAMES, reticleFrames, } from '../../telemetry/error-fingerprint.js';
|
|
13
13
|
import { getSessionMetrics } from '../../telemetry/session-metrics.js';
|
|
14
14
|
import { machineSnapshot } from '../../telemetry/machine-snapshot.js';
|
|
@@ -157,9 +157,9 @@ function reportCrash(kind, value) {
|
|
|
157
157
|
* gone for months.
|
|
158
158
|
*/
|
|
159
159
|
detach: true,
|
|
160
|
-
//
|
|
161
|
-
//
|
|
162
|
-
actor
|
|
160
|
+
// No `actor`. The daemon does plenty on its own (timers, the bridge, a page's SDK, the update
|
|
161
|
+
// check), and the core contract says a crash is neither human nor agent: tagging every one
|
|
162
|
+
// `agent` put the whole crash count on the agent side of every actor split.
|
|
163
163
|
crash: {
|
|
164
164
|
kind,
|
|
165
165
|
errorType,
|
|
@@ -112,6 +112,12 @@ export declare function splitBrainNote(myPort: number, elsewhere: readonly numbe
|
|
|
112
112
|
* being inspected is the project's own.
|
|
113
113
|
*/
|
|
114
114
|
export declare function wrongDaemonNote(inspectedPort: number, ownPort: number | undefined): string | undefined;
|
|
115
|
+
/**
|
|
116
|
+
* Why the proxy serves `port` and not the `requested` one, in words a person can act on. It said
|
|
117
|
+
* "the requested port serves a different project" for every move, including the commonest one: this
|
|
118
|
+
* project's own daemon was already running elsewhere (a `connect` started it on the default).
|
|
119
|
+
*/
|
|
120
|
+
export declare function relocationReason(requested: number, port: number, projectId: string | undefined, home: string, alive: (pid: number) => boolean): string;
|
|
115
121
|
/**
|
|
116
122
|
* The port this agent's MCP proxy should serve, decided BEFORE the proxy starts.
|
|
117
123
|
*
|
|
@@ -133,4 +139,6 @@ export declare function resolveMcpPort(preferred: number, projectId: string | un
|
|
|
133
139
|
alive: (pid: number) => boolean;
|
|
134
140
|
daemonPresent: (port: number) => Promise<boolean>;
|
|
135
141
|
pickPort: (preferred: number) => Promise<number>;
|
|
136
|
-
}
|
|
142
|
+
},
|
|
143
|
+
/** The port this project's `.reticle.json` names: the one its app dials. */
|
|
144
|
+
own?: number): Promise<number>;
|
|
@@ -19,7 +19,7 @@
|
|
|
19
19
|
import { readdirSync, readFileSync } from 'node:fs';
|
|
20
20
|
import { join } from 'node:path';
|
|
21
21
|
import { DaemonRegistryEntrySchema, daemonRegistryPort, pickDaemonPort, } from '@reticlehq/core/artifacts';
|
|
22
|
-
import { ReticleEnv } from '@reticlehq/core';
|
|
22
|
+
import { ReticleEnv, RETICLE_DEFAULT_PORT } from '@reticlehq/core';
|
|
23
23
|
const RETICLE_PORT_ENV = ReticleEnv.PORT;
|
|
24
24
|
/**
|
|
25
25
|
* Every well-formed registry entry in `home`.
|
|
@@ -156,12 +156,17 @@ export function splitBrainNote(myPort, elsewhere) {
|
|
|
156
156
|
return undefined;
|
|
157
157
|
const listed = elsewhere.map((port) => `:${String(port)}`).join(', ');
|
|
158
158
|
const first = elsewhere[0] ?? myPort;
|
|
159
|
+
// The agent moves, not the app (#1546). The daemon the app is on is a working session this agent
|
|
160
|
+
// did not start, and it may be a person's, another agent's or another project's. Stopping it was
|
|
161
|
+
// the first thing this used to say. It comes last now, with what it costs.
|
|
159
162
|
return (`this project's app is connected to a DIFFERENT Reticle daemon (${listed}), while this one is ` +
|
|
160
163
|
`on :${String(myPort)} — two daemons for one project, and the agent is attached to the empty ` +
|
|
161
|
-
'half. Nothing is wrong with the app or the wiring.
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
'
|
|
164
|
+
'half. Nothing is wrong with the app or the wiring. Move the agent to the app: set ' +
|
|
165
|
+
`${RETICLE_PORT_ENV}=${String(first)} in this MCP server's config, or launch the agent from the ` +
|
|
166
|
+
`project directory the dev server runs in, then restart the agent session. Leave :${String(first)} ` +
|
|
167
|
+
'running. Only if nothing else is using it, `reticle stop --port ' +
|
|
168
|
+
`${String(first)}\` and a dev server restart move the app here instead; that disconnects every ` +
|
|
169
|
+
'tab and agent on that daemon.');
|
|
165
170
|
}
|
|
166
171
|
/**
|
|
167
172
|
* The other stance on the same split, for a command standing on the port that HAS the app.
|
|
@@ -184,6 +189,25 @@ export function wrongDaemonNote(inspectedPort, ownPort) {
|
|
|
184
189
|
'be different processes, with both reporting healthy. Stop one of them and restart the dev ' +
|
|
185
190
|
'server so everything lands on the same port.');
|
|
186
191
|
}
|
|
192
|
+
/**
|
|
193
|
+
* Why the proxy serves `port` and not the `requested` one, in words a person can act on. It said
|
|
194
|
+
* "the requested port serves a different project" for every move, including the commonest one: this
|
|
195
|
+
* project's own daemon was already running elsewhere (a `connect` started it on the default).
|
|
196
|
+
*/
|
|
197
|
+
export function relocationReason(requested, port, projectId, home, alive) {
|
|
198
|
+
const at = `:${String(port)}`;
|
|
199
|
+
if (projectId !== undefined && resolveDaemonForProject(projectId, home, alive) === port)
|
|
200
|
+
return (`this project's daemon is already running on ${at}, so the agent uses it instead of ` +
|
|
201
|
+
`:${String(requested)}. To use :${String(requested)}, run \`reticle stop --port ${String(port)}\` ` +
|
|
202
|
+
'and reconnect the agent.');
|
|
203
|
+
const holder = daemonProjectAt(requested, home);
|
|
204
|
+
if (holder !== undefined && holder !== projectId)
|
|
205
|
+
return (`:${String(requested)} serves project "${holder}", so this one is served on ${at}. Give this ` +
|
|
206
|
+
'project its own port (RETICLE_PORT, or `port` in its .reticle.json) and restart the agent.');
|
|
207
|
+
if (projectId === undefined)
|
|
208
|
+
return `no project here, and the one live project daemon is on ${at}: the agent uses it.`;
|
|
209
|
+
return `nothing usable answered on :${String(requested)}, so the agent is served on ${at}.`;
|
|
210
|
+
}
|
|
187
211
|
/**
|
|
188
212
|
* The port this agent's MCP proxy should serve, decided BEFORE the proxy starts.
|
|
189
213
|
*
|
|
@@ -201,7 +225,9 @@ export function wrongDaemonNote(inspectedPort, ownPort) {
|
|
|
201
225
|
* silent adoption is what made every agent on a machine share one process, one identity and one
|
|
202
226
|
* blast radius.
|
|
203
227
|
*/
|
|
204
|
-
export async function resolveMcpPort(preferred, projectId, home, deps
|
|
228
|
+
export async function resolveMcpPort(preferred, projectId, home, deps,
|
|
229
|
+
/** The port this project's `.reticle.json` names: the one its app dials. */
|
|
230
|
+
own) {
|
|
205
231
|
const mine = resolveDaemonForProject(projectId, home, deps.alive);
|
|
206
232
|
if (mine !== undefined)
|
|
207
233
|
return mine;
|
|
@@ -209,10 +235,23 @@ export async function resolveMcpPort(preferred, projectId, home, deps) {
|
|
|
209
235
|
// A caller outside any project (an editor's user-scope MCP, launched from $HOME) used to dial the
|
|
210
236
|
// default and never see the one project that had moved off it (#1240). With exactly one project
|
|
211
237
|
// daemon live, that is the one; with several, the no-session answer names them instead.
|
|
212
|
-
|
|
238
|
+
// Only on the DEFAULT port, which is the guess #1240 corrects. A port passed with --port or
|
|
239
|
+
// RETICLE_PORT is a choice: relocating it attached an unwired app to another project's daemon.
|
|
240
|
+
const projects = projectId === undefined && RETICLE_DEFAULT_PORT === preferred
|
|
241
|
+
? projectDaemonsElsewhere(preferred, home, deps.alive)
|
|
242
|
+
: [];
|
|
213
243
|
return 1 === projects.length ? (projects[0]?.port ?? preferred) : preferred;
|
|
214
244
|
}
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
245
|
+
if (adoptable(daemonProjectAt(preferred, home), projectId))
|
|
246
|
+
return preferred;
|
|
247
|
+
// Moved off a port another project holds: to the one this project's app dials, when it is free or
|
|
248
|
+
// already ours. A random port served nobody — the app kept dialling its own, and the agent was
|
|
249
|
+
// told "wired, and a dev server is listening, but no session".
|
|
250
|
+
if (own !== undefined && own !== preferred) {
|
|
251
|
+
if (!(await deps.daemonPresent(own)))
|
|
252
|
+
return own;
|
|
253
|
+
if (adoptable(daemonProjectAt(own, home), projectId))
|
|
254
|
+
return own;
|
|
255
|
+
}
|
|
256
|
+
return deps.pickPort(preferred);
|
|
218
257
|
}
|
|
@@ -12,4 +12,6 @@
|
|
|
12
12
|
*/
|
|
13
13
|
import { PortPresence } from '../../daemon/binding/port-presence.js';
|
|
14
14
|
/** The refusal to print, or undefined when the port is usable. */
|
|
15
|
-
export declare function bridgeOccupied(presence: PortPresence, port: number): string | undefined;
|
|
15
|
+
export declare function bridgeOccupied(presence: PortPresence, port: number, freePort?: number): string | undefined;
|
|
16
|
+
/** The first port after `port` that nothing answers on, or undefined within the scan. */
|
|
17
|
+
export declare function freePortAfter(port: number, isOpen: (port: number) => Promise<boolean>): Promise<number | undefined>;
|
|
@@ -12,13 +12,23 @@
|
|
|
12
12
|
*/
|
|
13
13
|
import { PortPresence } from '../../daemon/binding/port-presence.js';
|
|
14
14
|
/** The refusal to print, or undefined when the port is usable. */
|
|
15
|
-
export function bridgeOccupied(presence, port) {
|
|
15
|
+
export function bridgeOccupied(presence, port, freePort) {
|
|
16
16
|
// DAEMON is the ordinary case — that is the daemon init is about to use. FREE is fine too: one
|
|
17
17
|
// gets started. Only a stranger is fatal.
|
|
18
18
|
if (PortPresence.FOREIGN !== presence)
|
|
19
19
|
return undefined;
|
|
20
20
|
return (`port ${String(port)} is held by something that is not a Reticle daemon. That is the bridge — ` +
|
|
21
21
|
'the channel between the daemon and the SDK in your page — so no session can ever appear while ' +
|
|
22
|
-
'it is occupied, however correct the wiring is. Free it, or re-run
|
|
23
|
-
|
|
22
|
+
'it is occupied, however correct the wiring is. Free it, or re-run on another port (init moves ' +
|
|
23
|
+
`the config and the page with it): reticle init --port ${freePort === undefined ? '<n>' : String(freePort)}`);
|
|
24
|
+
}
|
|
25
|
+
/** How many ports past the held one are tried before giving up on a suggestion. */
|
|
26
|
+
const FREE_PORT_SCAN = 20;
|
|
27
|
+
/** The first port after `port` that nothing answers on, or undefined within the scan. */
|
|
28
|
+
export async function freePortAfter(port, isOpen) {
|
|
29
|
+
for (let candidate = port + 1; candidate <= port + FREE_PORT_SCAN; candidate++) {
|
|
30
|
+
if (!(await isOpen(candidate)))
|
|
31
|
+
return candidate;
|
|
32
|
+
}
|
|
33
|
+
return undefined;
|
|
24
34
|
}
|
|
@@ -101,6 +101,8 @@ function main(argv) {
|
|
|
101
101
|
const child = spawn(command, {
|
|
102
102
|
shell: true,
|
|
103
103
|
stdio: ['ignore', 'pipe', 'pipe'],
|
|
104
|
+
// This supervisor runs detached with no console on Windows, so the shell would open a window.
|
|
105
|
+
windowsHide: true,
|
|
104
106
|
env: process.env,
|
|
105
107
|
});
|
|
106
108
|
child.stdout.on('data', (chunk) => log.write(chunk));
|