@reticlehq/server 3.5.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/README.md +1 -1
- package/SKILL.md +123 -116
- package/dist/chromium-launch-options.d.ts +3 -1
- package/dist/chromium-launch-options.js +2 -1
- 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 +19 -2
- package/dist/command/cli/adhoc-verdict.js +76 -9
- 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/answers/open-note.d.ts +2 -0
- package/dist/command/cli/answers/open-note.js +22 -0
- 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 +31 -112
- 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 +35 -5
- package/dist/command/cli/cli-verify.js +114 -35
- package/dist/command/cli/cloud-cli.d.ts +13 -0
- package/dist/command/cli/cloud-cli.js +192 -341
- 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 +22 -0
- package/dist/command/cli/cloud-login.js +96 -8
- 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/browser/chromium-hint.d.ts +46 -0
- package/dist/command/cli/doctor/browser/chromium-hint.js +99 -1
- 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/drive/drive-attach.d.ts +27 -2
- package/dist/command/cli/drive/drive-attach.js +71 -4
- package/dist/command/cli/drive/drive-command.d.ts +2 -1
- package/dist/command/cli/drive/drive-command.js +13 -7
- 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 +15 -3
- 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.d.ts +10 -0
- package/dist/command/cli/ports/port-holder.js +25 -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 +35 -12
- 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 -181
- 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 +20 -0
- package/dist/command/cli.js +130 -104
- package/dist/command/daemon/binding/daemon-status-probe.d.ts +2 -0
- package/dist/command/daemon/binding/daemon-status-probe.js +1 -0
- package/dist/command/daemon/daemon-resilience.js +4 -4
- package/dist/command/daemon/daemon-resolve.d.ts +23 -1
- package/dist/command/daemon/daemon-resolve.js +79 -9
- package/dist/command/setup/agent-writer.d.ts +1 -1
- package/dist/command/setup/agent-writer.js +3 -2
- 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/connect-lease.d.ts +1 -0
- package/dist/command/setup/bringup/connect-lease.js +1 -0
- package/dist/command/setup/bringup/dev-server-log-cap.js +2 -0
- package/dist/command/setup/bringup/dev-server-wait.d.ts +8 -0
- package/dist/command/setup/bringup/dev-server-wait.js +19 -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 +14 -1
- package/dist/command/setup/init/init-port.js +32 -2
- package/dist/command/setup/init/init-runtime.d.ts +22 -2
- package/dist/command/setup/init/init-runtime.js +114 -38
- package/dist/command/setup/node-effects.d.ts +2 -0
- package/dist/command/setup/node-effects.js +38 -9
- 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 +2 -1
- package/dist/command/setup/run-setup.d.ts +34 -9
- package/dist/command/setup/run-setup.js +65 -51
- package/dist/command/setup/setup-command.d.ts +25 -1
- package/dist/command/setup/setup-command.js +59 -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 +49 -4
- package/dist/features/crawl/crawl-tools.js +4 -0
- package/dist/features/crawl/crawl.d.ts +6 -0
- package/dist/features/crawl/crawl.js +23 -2
- package/dist/features/exhaust/ledger.d.ts +21 -14
- package/dist/features/exhaust/ledger.js +35 -9
- package/dist/features/harness/app-findings.d.ts +2 -0
- package/dist/features/harness/app-findings.js +52 -0
- package/dist/features/harness/drive-report.d.ts +61 -1
- package/dist/features/harness/drive-report.js +394 -26
- 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 +10 -14
- package/dist/features/harness/drivers.js +10 -14
- 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/fill-values.d.ts +3 -73
- package/dist/features/harness/fill-values.js +3 -169
- package/dist/features/harness/goals.d.ts +82 -0
- package/dist/features/harness/goals.js +330 -0
- package/dist/features/harness/harness.d.ts +51 -1
- package/dist/features/harness/harness.js +207 -6
- package/dist/features/harness/platform/drive-target.d.ts +30 -0
- package/dist/features/harness/platform/drive-target.js +81 -0
- package/dist/features/harness/platform/local-apps.d.ts +127 -0
- package/dist/features/harness/platform/local-apps.js +280 -0
- 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 +186 -0
- package/dist/features/harness/platform/remote-drive.js +378 -0
- package/dist/features/harness/platform/script.d.ts +94 -0
- package/dist/features/harness/platform/script.js +260 -0
- package/dist/features/harness/platform/server-driver.d.ts +54 -0
- package/dist/features/harness/platform/server-driver.js +182 -0
- package/dist/features/harness/platform-config.d.ts +41 -1
- package/dist/features/harness/platform-config.js +106 -9
- package/dist/features/harness/route-guess.d.ts +13 -0
- package/dist/features/harness/route-guess.js +49 -0
- package/dist/features/harness/script/app-controls.d.ts +5 -0
- package/dist/features/harness/script/app-controls.js +40 -0
- package/dist/features/harness/script/lane-ids.d.ts +14 -0
- package/dist/features/harness/script/lane-ids.js +16 -0
- package/dist/features/harness/script/script-run.d.ts +70 -0
- package/dist/features/harness/script/script-run.js +606 -0
- 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.d.ts +10 -1
- package/dist/features/visual/visual-tools.js +62 -17
- 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 +23 -0
- package/dist/hooks/driven-by.js +56 -0
- package/dist/hooks/hook-bus.d.ts +4 -0
- package/dist/hooks/hook-bus.js +18 -0
- package/dist/hooks/hook-commands.js +15 -4
- package/dist/hooks/tool-log.d.ts +9 -0
- package/dist/hooks/tool-log.js +29 -0
- package/dist/index.d.ts +2 -0
- package/dist/index.js +80 -243
- 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 +25 -3
- 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.d.ts +1 -1
- package/dist/judgement/runs/artifact/replay-mapping.js +37 -11
- package/dist/judgement/runs/artifact/run-store.d.ts +14 -2
- package/dist/judgement/runs/artifact/run-store.js +195 -3
- 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 +71 -1
- package/dist/judgement/runs/drive-run.js +317 -5
- package/dist/judgement/runs/repair-prompt.js +1 -1
- package/dist/judgement/runs/resume.d.ts +44 -0
- package/dist/judgement/runs/resume.js +137 -0
- package/dist/judgement/runs/reticle-runner.js +13 -3
- 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 +5 -2
- package/dist/judgement/runs/verification-sync.js +40 -18
- package/dist/language/flows/change/gate.d.ts +10 -0
- package/dist/language/flows/change/gate.js +22 -0
- package/dist/language/flows/decision.js +36 -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 +61 -10
- package/dist/language/flows/flow-anchor.js +98 -6
- package/dist/language/flows/flow-cross-step.d.ts +15 -0
- package/dist/language/flows/flow-cross-step.js +21 -0
- 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 +45 -14
- package/dist/language/flows/flow-mutate-tools.js +5 -3
- package/dist/language/flows/flow-replay-run.d.ts +23 -9
- package/dist/language/flows/flow-replay-run.js +115 -110
- package/dist/language/flows/flow-replay-types.d.ts +1 -1
- package/dist/language/flows/flow-replay.d.ts +40 -1
- package/dist/language/flows/flow-replay.js +110 -22
- package/dist/language/flows/flow-result.d.ts +22 -1
- package/dist/language/flows/flow-result.js +47 -2
- package/dist/language/flows/flow-scope.js +5 -1
- package/dist/language/flows/flow-step-runners.d.ts +22 -2
- package/dist/language/flows/flow-step-runners.js +247 -47
- package/dist/language/flows/flow-store-for-session.d.ts +2 -2
- package/dist/language/flows/flow-store-for-session.js +7 -3
- package/dist/language/flows/flow-tools.d.ts +10 -0
- package/dist/language/flows/flow-tools.js +112 -89
- package/dist/language/flows/flows.d.ts +16 -1
- package/dist/language/flows/flows.js +74 -12
- package/dist/language/flows/heal-run.js +6 -4
- package/dist/language/flows/narrow-write.d.ts +7 -0
- package/dist/language/flows/narrow-write.js +36 -1
- package/dist/language/flows/recording/flake.d.ts +2 -2
- package/dist/language/flows/recording/recording-backtrack.js +14 -1
- package/dist/language/flows/recording/tape/recordings.d.ts +58 -4
- package/dist/language/flows/recording/tape/recordings.js +95 -13
- package/dist/language/flows/replay-from-hud.d.ts +20 -0
- package/dist/language/flows/replay-from-hud.js +51 -0
- package/dist/language/flows/replay.d.ts +9 -5
- package/dist/language/flows/replay.js +56 -15
- package/dist/language/flows/single-replay.d.ts +7 -0
- package/dist/language/flows/single-replay.js +26 -0
- package/dist/language/flows/suite/suite-flakes.js +2 -0
- package/dist/language/flows/suite-selection.d.ts +2 -15
- package/dist/language/flows/suite-selection.js +4 -3
- package/dist/language/flows/verify-change-tools.d.ts +1 -0
- package/dist/language/flows/verify-change-tools.js +202 -191
- package/dist/launch-chromium.d.ts +27 -5
- package/dist/launch-chromium.js +38 -8
- package/dist/memory/cloud/cloud-config.d.ts +22 -1
- package/dist/memory/cloud/cloud-config.js +34 -5
- package/dist/memory/cloud/cloud-sync.d.ts +17 -14
- package/dist/memory/cloud/cloud-sync.js +15 -4
- package/dist/memory/cloud/harness-config.d.ts +75 -1
- package/dist/memory/cloud/harness-config.js +115 -24
- package/dist/memory/cloud/hud-notices-source.d.ts +21 -0
- package/dist/memory/cloud/hud-notices-source.js +128 -0
- package/dist/memory/cloud/memory-scope.d.ts +161 -0
- package/dist/memory/cloud/memory-scope.js +227 -0
- package/dist/memory/cloud/sync-cycle.d.ts +44 -7
- package/dist/memory/cloud/sync-cycle.js +129 -15
- package/dist/memory/cloud/sync-daemon.d.ts +11 -0
- package/dist/memory/cloud/sync-daemon.js +121 -9
- package/dist/memory/cloud/sync-disk.d.ts +1 -1
- package/dist/memory/cloud/sync-disk.js +31 -10
- 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 +34 -0
- package/dist/memory/impact/account-watch.js +59 -0
- package/dist/memory/impact/impact-recorder.d.ts +8 -0
- package/dist/memory/impact/impact-recorder.js +12 -2
- package/dist/memory/impact/impact-store.d.ts +17 -4
- package/dist/memory/impact/impact-store.js +169 -63
- 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 +14 -2
- package/dist/memory/intent/intent-store.d.ts +1 -0
- package/dist/memory/intent/intent-tools.js +122 -4
- 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/envelope.d.ts +8 -8
- package/dist/memory/journal/journal-recorder.js +52 -3
- package/dist/memory/journal/on-disk/retention.d.ts +8 -0
- package/dist/memory/journal/on-disk/retention.js +32 -2
- package/dist/memory/journal/on-disk/startup-maintenance.js +3 -1
- package/dist/memory/journal/on-disk/workspace-tiers.js +9 -4
- package/dist/memory/journal/session-end.d.ts +15 -1
- package/dist/memory/journal/session-end.js +42 -9
- package/dist/memory/project/artifact-root-resolver.d.ts +26 -1
- package/dist/memory/project/artifact-root-resolver.js +125 -16
- package/dist/memory/project/artifact-root.d.ts +46 -8
- package/dist/memory/project/artifact-root.js +89 -10
- package/dist/memory/project/dir/reticle-dir.d.ts +18 -2
- package/dist/memory/project/dir/reticle-dir.js +26 -3
- package/dist/memory/project/link-directory.d.ts +15 -0
- package/dist/memory/project/link-directory.js +44 -0
- package/dist/memory/project/project-tools.js +22 -3
- 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 +26 -1
- package/dist/memory/project/session-root.js +49 -5
- package/dist/memory/project/sync-status.d.ts +85 -0
- package/dist/memory/project/sync-status.js +224 -0
- package/dist/memory/recall/memory-tools.js +47 -2
- 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.d.ts +19 -0
- package/dist/memory/recall/project-memory.js +80 -13
- package/dist/portal/bridge/bridge.d.ts +9 -3
- package/dist/portal/bridge/bridge.js +82 -22
- package/dist/portal/bridge/harness-request.d.ts +23 -0
- package/dist/portal/bridge/harness-request.js +27 -0
- package/dist/portal/bridge/pairing-token.d.ts +9 -0
- package/dist/portal/bridge/pairing-token.js +17 -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 +83 -10
- package/dist/portal/input/real-input.js +218 -30
- package/dist/portal/input/viewport-tools.js +3 -3
- package/dist/portal/pool/browser-pool.d.ts +70 -9
- package/dist/portal/pool/browser-pool.js +190 -37
- 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 +35 -0
- package/dist/portal/pool/playwright-launcher.js +64 -3
- package/dist/portal/pool/pool-contract.d.ts +28 -5
- 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.d.ts +8 -0
- package/dist/portal/session/command-payload.js +24 -0
- 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 +21 -0
- package/dist/portal/session/dev-server/dev-command.js +87 -12
- package/dist/portal/session/facts/departure-note.d.ts +22 -0
- package/dist/portal/session/facts/departure-note.js +47 -0
- 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/facts/session-replaced.d.ts +5 -0
- package/dist/portal/session/facts/session-replaced.js +5 -0
- package/dist/portal/session/first-run-wiring.d.ts +42 -0
- package/dist/portal/session/first-run-wiring.js +132 -0
- 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/human/notes-ledger.d.ts +20 -0
- package/dist/portal/session/human/notes-ledger.js +55 -0
- package/dist/portal/session/human/review-store.d.ts +12 -0
- package/dist/portal/session/human/review-store.js +18 -10
- package/dist/portal/session/live-control-tools.d.ts +0 -13
- package/dist/portal/session/live-control-tools.js +107 -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 +8 -1
- package/dist/portal/session/no-session-diagnosis.js +46 -9
- package/dist/portal/session/no-session-next-action.d.ts +31 -0
- package/dist/portal/session/no-session-next-action.js +159 -60
- package/dist/portal/session/no-session-watch.d.ts +14 -1
- package/dist/portal/session/no-session-watch.js +227 -17
- package/dist/portal/session/presence/session-lease.js +1 -1
- package/dist/portal/session/presence/session-mirror.js +3 -0
- package/dist/portal/session/recorded-gaps.d.ts +97 -0
- package/dist/portal/session/recorded-gaps.js +251 -0
- package/dist/portal/session/serving-directory.d.ts +27 -0
- package/dist/portal/session/serving-directory.js +45 -0
- package/dist/portal/session/session-health.d.ts +18 -0
- package/dist/portal/session/session-health.js +9 -1
- package/dist/portal/session/session-info.d.ts +8 -1
- package/dist/portal/session/session-info.js +8 -1
- package/dist/portal/session/session-manager.d.ts +39 -0
- package/dist/portal/session/session-manager.js +98 -11
- package/dist/portal/session/session-reaper.js +4 -1
- package/dist/portal/session/session-successor.d.ts +13 -0
- package/dist/portal/session/session-successor.js +1 -1
- package/dist/portal/session/session-tools.js +26 -3
- package/dist/portal/session/session.d.ts +22 -30
- package/dist/portal/session/session.js +81 -79
- 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 +12 -0
- package/dist/start-wiring.d.ts +63 -0
- package/dist/start-wiring.js +169 -0
- package/dist/status-payload.d.ts +23 -1
- package/dist/status-payload.js +36 -1
- package/dist/surface/http-server.js +18 -2
- 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 +9 -0
- package/dist/surface/mcp/mcp-proxy.js +65 -13
- package/dist/surface/mcp/mcp.d.ts +34 -6
- package/dist/surface/mcp/mcp.js +61 -17
- 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.d.ts +4 -2
- package/dist/surface/mcp/server-instructions.js +32 -14
- package/dist/surface/mcp/shared-params.js +2 -2
- 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/navigation/navigate-arrival.d.ts +8 -0
- package/dist/surface/tools/act/navigation/navigate-arrival.js +56 -2
- 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/settle-in-flight.js +25 -3
- package/dist/surface/tools/act-sequence-tool.js +138 -29
- package/dist/surface/tools/act-tools.d.ts +0 -9
- package/dist/surface/tools/act-tools.js +71 -41
- 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.d.ts +1 -1
- package/dist/surface/tools/assert/assert-verdict.js +42 -17
- package/dist/surface/tools/browser-tools.js +51 -2
- package/dist/surface/tools/chat-drives.d.ts +101 -0
- package/dist/surface/tools/chat-drives.js +409 -0
- 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 +51 -0
- package/dist/surface/tools/empty-session-list.js +120 -0
- package/dist/surface/tools/error-recovery.d.ts +14 -0
- package/dist/surface/tools/error-recovery.js +105 -8
- package/dist/surface/tools/explore-tools.d.ts +31 -1
- package/dist/surface/tools/explore-tools.js +438 -66
- package/dist/surface/tools/feedback-tools.d.ts +2 -3
- package/dist/surface/tools/feedback-tools.js +18 -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 +118 -57
- package/dist/surface/tools/harness-explore.js +344 -292
- 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 +17 -0
- package/dist/surface/tools/harness-plan.js +38 -0
- package/dist/surface/tools/harness-script.d.ts +30 -0
- package/dist/surface/tools/harness-script.js +560 -0
- 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 +22 -1
- package/dist/surface/tools/harness-toolset.js +101 -7
- 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 +263 -85
- 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 +49 -0
- package/dist/surface/tools/lease-seed.js +167 -0
- package/dist/surface/tools/lease-tools.d.ts +13 -24
- package/dist/surface/tools/lease-tools.js +146 -197
- package/dist/surface/tools/live-call-text.js +4 -4
- 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 +29 -0
- package/dist/surface/tools/next-step.js +214 -0
- package/dist/surface/tools/observe-tools.js +45 -9
- package/dist/surface/tools/platform-moment.d.ts +72 -0
- package/dist/surface/tools/platform-moment.js +296 -0
- package/dist/surface/tools/query-hint-schema.d.ts +7 -0
- package/dist/surface/tools/query-hint-schema.js +10 -0
- package/dist/surface/tools/read-tools.js +71 -14
- package/dist/surface/tools/real-input-attempt.js +96 -13
- 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 +83 -3
- package/dist/surface/tools/tool-kit.js +77 -7
- package/dist/surface/tools/tools.js +43 -59
- 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 +29 -6
- package/dist/telemetry/hud-metrics.js +116 -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 +38 -2
- package/dist/telemetry/telemetry.js +144 -34
- package/dist/telemetry/verification-of.d.ts +3 -1
- package/dist/telemetry/verification-of.js +13 -4
- package/dist/wire-journal.d.ts +2 -2
- package/dist/wire-journal.js +20 -6
- package/docs/README.md +3 -3
- package/docs/actions.mdx +6 -3
- package/docs/adapters.md +1 -1
- package/docs/agent-cheatsheet.md +25 -28
- package/docs/architecture.md +5 -5
- package/docs/autodrive.md +33 -28
- 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 +14 -3
- package/docs/cli/drive.mdx +20 -14
- 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 +43 -28
- 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 +18 -5
- 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 +5 -4
- package/docs/cli.mdx +111 -42
- package/docs/debugging.md +3 -3
- package/docs/deploy-checks.md +1 -1
- package/docs/desktop.mdx +9 -3
- package/docs/enterprise.md +11 -10
- package/docs/environment.mdx +7 -8
- 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 +65 -61
- package/docs/human-control.md +16 -16
- package/docs/index.mdx +15 -42
- package/docs/install-agentic.mdx +22 -37
- package/docs/install-manual.mdx +23 -13
- 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 +9 -9
- package/docs/packages/test.mdx +4 -10
- package/docs/packages/vite-plugin.mdx +32 -4
- package/docs/packages.mdx +11 -15
- package/docs/platform-integration.md +6 -5
- package/docs/predicates.mdx +40 -24
- package/docs/quickstart.mdx +69 -30
- 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 +23 -25
- 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 +22 -13
- 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 +55 -46
- 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 +17 -5
- package/docs/what-is-reticle.mdx +5 -3
- package/docs/why-reticle.mdx +1 -1
- package/package.json +9 -12
- package/dist/command/cli/demo/demo-page.d.ts +0 -78
- package/dist/command/cli/demo/demo-page.js +0 -241
- package/dist/command/cli/demo/demo-run.d.ts +0 -38
- package/dist/command/cli/demo/demo-run.js +0 -138
- package/dist/features/harness/driver.d.ts +0 -50
- package/dist/features/harness/driver.js +0 -236
- package/dist/features/harness/jev-driver.d.ts +0 -188
- package/dist/features/harness/jev-driver.js +0 -678
- package/dist/features/harness/openai-driver.d.ts +0 -58
- package/dist/features/harness/openai-driver.js +0 -206
- 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/memory/project/dir/fill-value-store.d.ts +0 -32
- package/dist/memory/project/dir/fill-value-store.js +0 -88
- 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
- package/docs/local-registry.md +0 -143
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* `reticle context --compact [--session <id>]` — the resume block, read from disk with no daemon.
|
|
3
|
+
*
|
|
4
|
+
* Installed by `reticle init` as a Claude Code SessionStart hook with matcher `compact`: right after
|
|
5
|
+
* a compaction, whatever this prints is put back into the agent's fresh context. So it must never
|
|
6
|
+
* fail loudly — a hook that throws is an error the user did not cause — and it prints nothing when
|
|
7
|
+
* this directory has no Reticle record at all.
|
|
8
|
+
*/
|
|
9
|
+
import { existsSync } from 'node:fs';
|
|
10
|
+
import { join } from 'node:path';
|
|
11
|
+
import { ReticleDir } from '@reticlehq/core';
|
|
12
|
+
import { resumeFromDisk } from '../../judgement/runs/resume.js';
|
|
13
|
+
import { SessionJournal } from '../../memory/journal/session-journal.js';
|
|
14
|
+
import { createNodeFileSystem } from '../../memory/project/fs/fs-port.js';
|
|
15
|
+
export async function handleContext(session) {
|
|
16
|
+
const root = join(process.cwd(), ReticleDir.ROOT);
|
|
17
|
+
if (!existsSync(root))
|
|
18
|
+
return;
|
|
19
|
+
try {
|
|
20
|
+
const fs = createNodeFileSystem();
|
|
21
|
+
const lines = await resumeFromDisk({
|
|
22
|
+
root,
|
|
23
|
+
now: Date.now(),
|
|
24
|
+
fs,
|
|
25
|
+
readActions: (id) => new SessionJournal(fs, root, id).readActions(),
|
|
26
|
+
sessionId: session,
|
|
27
|
+
});
|
|
28
|
+
process.stdout.write(`${lines.join('\n')}\n`);
|
|
29
|
+
}
|
|
30
|
+
catch {
|
|
31
|
+
// Silent by design: see the header.
|
|
32
|
+
}
|
|
33
|
+
}
|
|
@@ -30,4 +30,7 @@ export declare function daemonStartOptions(parsed: DaemonFlags): StartOptions;
|
|
|
30
30
|
* idea: that headless belongs to the drive URL. It belongs to the pool, which exists either way.
|
|
31
31
|
*/
|
|
32
32
|
export declare function daemonSpawnArgs(parsed: DaemonFlags): string[];
|
|
33
|
+
/** Set (to anything but '', '0' or 'false') to hide every browser Reticle opens. Batteries set it. */
|
|
34
|
+
export declare const HEADLESS_ENV = "RETICLE_HEADLESS";
|
|
35
|
+
export declare function headlessByDefault(env: Readonly<Record<string, string | undefined>>, platform: string): boolean;
|
|
33
36
|
export {};
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { DAEMON_INNER_COMMAND, DRIVE_FLAG, HEADED_FLAG, HTTP_FLAG, HTTP_PORT_FLAG, HTTP_TOKEN_FLAG, PORT_FLAG, } from './cli-parse.js';
|
|
1
|
+
import { DAEMON_INNER_COMMAND, DRIVE_FLAG, HEADED_FLAG, HEADLESS_FLAG, HTTP_FLAG, HTTP_PORT_FLAG, HTTP_TOKEN_FLAG, PORT_FLAG, } from './cli-parse.js';
|
|
2
2
|
export function daemonStartOptions(parsed) {
|
|
3
3
|
return {
|
|
4
4
|
port: parsed.port,
|
|
@@ -25,8 +25,9 @@ export function daemonSpawnArgs(parsed) {
|
|
|
25
25
|
const args = [DAEMON_INNER_COMMAND, PORT_FLAG, String(parsed.port)];
|
|
26
26
|
if (parsed.driveUrl !== undefined)
|
|
27
27
|
args.push(DRIVE_FLAG, parsed.driveUrl);
|
|
28
|
-
|
|
29
|
-
|
|
28
|
+
// Said either way: the child decides its own default from its environment, so a parent that
|
|
29
|
+
// resolved hidden must say so rather than leave it to a default that may differ.
|
|
30
|
+
args.push(parsed.headless ? HEADLESS_FLAG : HEADED_FLAG);
|
|
30
31
|
if (parsed.http) {
|
|
31
32
|
args.push(HTTP_FLAG);
|
|
32
33
|
if (parsed.httpPort !== undefined)
|
|
@@ -36,3 +37,23 @@ export function daemonSpawnArgs(parsed) {
|
|
|
36
37
|
}
|
|
37
38
|
return args;
|
|
38
39
|
}
|
|
40
|
+
/*
|
|
41
|
+
* Whether a browser a daemon opens is shown or hidden when no flag says. Here because both callers that
|
|
42
|
+
* decide it -- `cli.ts` and init's bring-up -- already start daemons through this module.
|
|
43
|
+
*/
|
|
44
|
+
/** Set (to anything but '', '0' or 'false') to hide every browser Reticle opens. Batteries set it. */
|
|
45
|
+
export const HEADLESS_ENV = 'RETICLE_HEADLESS';
|
|
46
|
+
/**
|
|
47
|
+
* Whether a browser Reticle opens is hidden when no flag says. Shown by default, for every command:
|
|
48
|
+
* the pool behind `serve`/`mcp` used to be hidden on the theory that nobody watches batch work, and
|
|
49
|
+
* from the field that was a person watching an agent drive their app and seeing nothing happen.
|
|
50
|
+
* Hidden where showing is impossible or unwanted: CI, the test batteries, and a Linux machine with
|
|
51
|
+
* no display server, where a headed launch fails instead of showing anything.
|
|
52
|
+
*/
|
|
53
|
+
const OFF = new Set(['', '0', 'false']);
|
|
54
|
+
export function headlessByDefault(env, platform) {
|
|
55
|
+
const forced = env[HEADLESS_ENV];
|
|
56
|
+
if (env['CI'] !== undefined || (forced !== undefined && !OFF.has(forced)))
|
|
57
|
+
return true;
|
|
58
|
+
return ('linux' === platform && env['DISPLAY'] === undefined && env['WAYLAND_DISPLAY'] === undefined);
|
|
59
|
+
}
|
|
@@ -48,7 +48,45 @@ export interface ChromiumProbe {
|
|
|
48
48
|
* `Microsoft Edge`) — see launch-chromium. Present only when `exists` is false and one was found.
|
|
49
49
|
*/
|
|
50
50
|
fallback?: string | undefined;
|
|
51
|
+
/** `executablePath` came from RETICLE_CHROMIUM_PATH, so the bundled build is not in play at all. */
|
|
52
|
+
configured?: boolean | undefined;
|
|
53
|
+
/** Why that configured executable cannot be launched. Present only when `exists` is false. */
|
|
54
|
+
problem?: ChromiumPathProblem | undefined;
|
|
51
55
|
}
|
|
56
|
+
/** What stops the executable RETICLE_CHROMIUM_PATH names from being launched. */
|
|
57
|
+
export declare const ChromiumPathProblem: {
|
|
58
|
+
readonly MISSING: "missing";
|
|
59
|
+
readonly NOT_A_FILE: "not-a-file";
|
|
60
|
+
readonly NOT_EXECUTABLE: "not-executable";
|
|
61
|
+
};
|
|
62
|
+
export type ChromiumPathProblem = (typeof ChromiumPathProblem)[keyof typeof ChromiumPathProblem];
|
|
63
|
+
/**
|
|
64
|
+
* What stops the file at `path` from being launched, or undefined when nothing does.
|
|
65
|
+
*
|
|
66
|
+
* Existing is not enough: Playwright cannot start a directory or a file without the executable bit,
|
|
67
|
+
* and its error for that reads like a missing install. Windows has no executable bit, so only the
|
|
68
|
+
* file check applies there.
|
|
69
|
+
*/
|
|
70
|
+
export declare function chromiumPathProblem(path: string, platform: NodeJS.Platform): ChromiumPathProblem | undefined;
|
|
71
|
+
/** The Chromium RETICLE_CHROMIUM_PATH names, or undefined when it is unset or blank. */
|
|
72
|
+
export declare function configuredChromiumPath(env: NodeJS.ProcessEnv): string | undefined;
|
|
73
|
+
/**
|
|
74
|
+
* What the probes report when RETICLE_CHROMIUM_PATH is set, or undefined when it is not. The user
|
|
75
|
+
* named the browser, so the bundled revision, the installed channels and the browsers root say
|
|
76
|
+
* nothing about whether a launch will work. Only the named file does.
|
|
77
|
+
*/
|
|
78
|
+
export declare function configuredChromiumProbe(env: NodeJS.ProcessEnv, pathProblem: (path: string) => ChromiumPathProblem | undefined): ChromiumProbe | undefined;
|
|
79
|
+
/**
|
|
80
|
+
* How every RETICLE_CHROMIUM_PATH refusal begins. Error recovery keys on it, so the variable's name
|
|
81
|
+
* is read as configuration rather than as a `reticle_*` tool the call got wrong.
|
|
82
|
+
*/
|
|
83
|
+
export declare const CHROMIUM_PATH_REFUSAL_PREFIX: string;
|
|
84
|
+
/**
|
|
85
|
+
* A RETICLE_CHROMIUM_PATH that cannot be launched. Worded apart from the missing-browser hint on
|
|
86
|
+
* purpose: that one sends the reader to install Playwright's build, which does nothing for a path
|
|
87
|
+
* typed wrong.
|
|
88
|
+
*/
|
|
89
|
+
export declare function configuredChromiumRefusal(path: string, problem: ChromiumPathProblem): string;
|
|
52
90
|
/** The install command, pinned when we know what to pin to. */
|
|
53
91
|
export declare function chromiumInstallCommand(playwrightVersion?: string): string;
|
|
54
92
|
/**
|
|
@@ -83,5 +121,13 @@ export declare function parseChromiumRevision(executablePath: string): {
|
|
|
83
121
|
export declare function probeChromium(): Promise<ChromiumProbe>;
|
|
84
122
|
/** The bundled playwright's version, or undefined if it cannot be read (the hint then goes unpinned). */
|
|
85
123
|
export declare function bundledPlaywrightVersion(): string | undefined;
|
|
124
|
+
/**
|
|
125
|
+
* Why the lease preflight refuses, or undefined when a launch can go ahead.
|
|
126
|
+
*
|
|
127
|
+
* "Chromium is not installed" is kept in the usual message because error-recovery routes it to the
|
|
128
|
+
* install fix. A RETICLE_CHROMIUM_PATH that cannot be launched is a wrong path, not a missing
|
|
129
|
+
* install, so it says only that and the install fix is never attached.
|
|
130
|
+
*/
|
|
131
|
+
export declare function chromiumPreflightRefusal(probe: ChromiumProbe): string | undefined;
|
|
86
132
|
/** The doctor line for the Chromium check — verdict, what was probed, and how to satisfy it. */
|
|
87
133
|
export declare function chromiumHint(probe: ChromiumProbe): string;
|
|
@@ -20,8 +20,86 @@
|
|
|
20
20
|
* resolves, so `PLAYWRIGHT_BROWSERS_PATH` and every platform default are honoured by construction
|
|
21
21
|
* rather than by a table of roots this file would have to keep in step with Playwright's.
|
|
22
22
|
*/
|
|
23
|
-
import { existsSync, readdirSync } from 'node:fs';
|
|
23
|
+
import { accessSync, constants as fsConstants, existsSync, readdirSync, statSync } from 'node:fs';
|
|
24
24
|
import { createRequire } from 'node:module';
|
|
25
|
+
import { ReticleEnv } from '@reticlehq/core';
|
|
26
|
+
/** What stops the executable RETICLE_CHROMIUM_PATH names from being launched. */
|
|
27
|
+
export const ChromiumPathProblem = {
|
|
28
|
+
MISSING: 'missing',
|
|
29
|
+
NOT_A_FILE: 'not-a-file',
|
|
30
|
+
NOT_EXECUTABLE: 'not-executable',
|
|
31
|
+
};
|
|
32
|
+
/**
|
|
33
|
+
* What stops the file at `path` from being launched, or undefined when nothing does.
|
|
34
|
+
*
|
|
35
|
+
* Existing is not enough: Playwright cannot start a directory or a file without the executable bit,
|
|
36
|
+
* and its error for that reads like a missing install. Windows has no executable bit, so only the
|
|
37
|
+
* file check applies there.
|
|
38
|
+
*/
|
|
39
|
+
export function chromiumPathProblem(path, platform) {
|
|
40
|
+
let isFile;
|
|
41
|
+
try {
|
|
42
|
+
isFile = statSync(path).isFile();
|
|
43
|
+
}
|
|
44
|
+
catch {
|
|
45
|
+
return ChromiumPathProblem.MISSING;
|
|
46
|
+
}
|
|
47
|
+
if (!isFile)
|
|
48
|
+
return ChromiumPathProblem.NOT_A_FILE;
|
|
49
|
+
if ('win32' === platform)
|
|
50
|
+
return undefined;
|
|
51
|
+
try {
|
|
52
|
+
accessSync(path, fsConstants.X_OK);
|
|
53
|
+
return undefined;
|
|
54
|
+
}
|
|
55
|
+
catch {
|
|
56
|
+
return ChromiumPathProblem.NOT_EXECUTABLE;
|
|
57
|
+
}
|
|
58
|
+
}
|
|
59
|
+
/** The Chromium RETICLE_CHROMIUM_PATH names, or undefined when it is unset or blank. */
|
|
60
|
+
export function configuredChromiumPath(env) {
|
|
61
|
+
const path = env[ReticleEnv.CHROMIUM_PATH]?.trim();
|
|
62
|
+
return path === undefined || 0 === path.length ? undefined : path;
|
|
63
|
+
}
|
|
64
|
+
/**
|
|
65
|
+
* What the probes report when RETICLE_CHROMIUM_PATH is set, or undefined when it is not. The user
|
|
66
|
+
* named the browser, so the bundled revision, the installed channels and the browsers root say
|
|
67
|
+
* nothing about whether a launch will work. Only the named file does.
|
|
68
|
+
*/
|
|
69
|
+
export function configuredChromiumProbe(env, pathProblem) {
|
|
70
|
+
const path = configuredChromiumPath(env);
|
|
71
|
+
if (path === undefined)
|
|
72
|
+
return undefined;
|
|
73
|
+
const problem = pathProblem(path);
|
|
74
|
+
return {
|
|
75
|
+
executablePath: path,
|
|
76
|
+
exists: problem === undefined,
|
|
77
|
+
configured: true,
|
|
78
|
+
...(problem === undefined ? {} : { problem }),
|
|
79
|
+
};
|
|
80
|
+
}
|
|
81
|
+
/**
|
|
82
|
+
* How every RETICLE_CHROMIUM_PATH refusal begins. Error recovery keys on it, so the variable's name
|
|
83
|
+
* is read as configuration rather than as a `reticle_*` tool the call got wrong.
|
|
84
|
+
*/
|
|
85
|
+
export const CHROMIUM_PATH_REFUSAL_PREFIX = `${ReticleEnv.CHROMIUM_PATH} points at `;
|
|
86
|
+
/** What each problem reads as, after the path. */
|
|
87
|
+
const CHROMIUM_PATH_PROBLEM_TEXT = {
|
|
88
|
+
[ChromiumPathProblem.MISSING]: 'which does not exist',
|
|
89
|
+
[ChromiumPathProblem.NOT_A_FILE]: 'which is not a file',
|
|
90
|
+
[ChromiumPathProblem.NOT_EXECUTABLE]: 'which is not executable',
|
|
91
|
+
};
|
|
92
|
+
const CHROMIUM_PATH_FIX = "fix the path, or unset it to use Playwright's own Chromium";
|
|
93
|
+
/** The doctor verdict for a RETICLE_CHROMIUM_PATH that can be launched. */
|
|
94
|
+
const CHROMIUM_PATH_IN_USE = (path) => `✓ using ${path} (${ReticleEnv.CHROMIUM_PATH})`;
|
|
95
|
+
/**
|
|
96
|
+
* A RETICLE_CHROMIUM_PATH that cannot be launched. Worded apart from the missing-browser hint on
|
|
97
|
+
* purpose: that one sends the reader to install Playwright's build, which does nothing for a path
|
|
98
|
+
* typed wrong.
|
|
99
|
+
*/
|
|
100
|
+
export function configuredChromiumRefusal(path, problem) {
|
|
101
|
+
return `${CHROMIUM_PATH_REFUSAL_PREFIX}${path}, ${CHROMIUM_PATH_PROBLEM_TEXT[problem]}; ${CHROMIUM_PATH_FIX}`;
|
|
102
|
+
}
|
|
25
103
|
/**
|
|
26
104
|
* A browsers-root entry that is a chromium build.
|
|
27
105
|
*
|
|
@@ -160,8 +238,28 @@ export function bundledPlaywrightVersion() {
|
|
|
160
238
|
}
|
|
161
239
|
return undefined;
|
|
162
240
|
}
|
|
241
|
+
/**
|
|
242
|
+
* Why the lease preflight refuses, or undefined when a launch can go ahead.
|
|
243
|
+
*
|
|
244
|
+
* "Chromium is not installed" is kept in the usual message because error-recovery routes it to the
|
|
245
|
+
* install fix. A RETICLE_CHROMIUM_PATH that cannot be launched is a wrong path, not a missing
|
|
246
|
+
* install, so it says only that and the install fix is never attached.
|
|
247
|
+
*/
|
|
248
|
+
export function chromiumPreflightRefusal(probe) {
|
|
249
|
+
if (probe.exists)
|
|
250
|
+
return undefined;
|
|
251
|
+
if (true === probe.configured && probe.executablePath !== undefined) {
|
|
252
|
+
return configuredChromiumRefusal(probe.executablePath, probe.problem ?? ChromiumPathProblem.MISSING);
|
|
253
|
+
}
|
|
254
|
+
return `Chromium is not installed for Playwright — ${chromiumHint(probe)}`;
|
|
255
|
+
}
|
|
163
256
|
/** The doctor line for the Chromium check — verdict, what was probed, and how to satisfy it. */
|
|
164
257
|
export function chromiumHint(probe) {
|
|
258
|
+
if (true === probe.configured && probe.executablePath !== undefined) {
|
|
259
|
+
return probe.exists
|
|
260
|
+
? CHROMIUM_PATH_IN_USE(probe.executablePath)
|
|
261
|
+
: `✗ ${configuredChromiumRefusal(probe.executablePath, probe.problem ?? ChromiumPathProblem.MISSING)}`;
|
|
262
|
+
}
|
|
165
263
|
if (probe.exists) {
|
|
166
264
|
// Naming the revision on the happy line too: it is the number the mismatch line talks about, and
|
|
167
265
|
// a reader comparing two machines has nothing to compare without it.
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* `doctor`'s coverage rows: what Reticle sees in each connected app, read from the daemon's
|
|
3
|
+
* `/status` (`coverage`), and — once a verdict recorded a gap — the prompt to hand a coding agent.
|
|
4
|
+
* A terminal cannot copy, so the prompt is printed whole, ready to paste.
|
|
5
|
+
*/
|
|
6
|
+
import { DoctorRow, doctorRow } from './doctor-rows.js';
|
|
7
|
+
const capabilitiesIn = (value) => Array.isArray(value)
|
|
8
|
+
? value.flatMap((item) => {
|
|
9
|
+
const name = 'object' === typeof item && null !== item
|
|
10
|
+
? item['capability']
|
|
11
|
+
: item;
|
|
12
|
+
return 'string' === typeof name ? [name] : [];
|
|
13
|
+
})
|
|
14
|
+
: [];
|
|
15
|
+
/** The rows for every tab the status names; nothing when it names none. Never throws. */
|
|
16
|
+
export function coverageLines(status) {
|
|
17
|
+
const list = 'object' === typeof status && null !== status
|
|
18
|
+
? status['coverage']
|
|
19
|
+
: undefined;
|
|
20
|
+
if (!Array.isArray(list))
|
|
21
|
+
return [];
|
|
22
|
+
return list.flatMap((raw) => {
|
|
23
|
+
const tab = ('object' === typeof raw && null !== raw ? raw : {});
|
|
24
|
+
if ('number' !== typeof tab.covered || 'number' !== typeof tab.total)
|
|
25
|
+
return [];
|
|
26
|
+
const missing = capabilitiesIn(tab.missing);
|
|
27
|
+
const notSeen = capabilitiesIn(tab.notSeenYet);
|
|
28
|
+
const parts = [
|
|
29
|
+
`${String(tab.covered)}/${String(tab.total)}${'string' === typeof tab.url ? ` at ${tab.url}` : ''}`,
|
|
30
|
+
...(0 === missing.length ? [] : [`missing: ${missing.join(', ')}`]),
|
|
31
|
+
...(0 === notSeen.length ? [] : [`not seen yet: ${notSeen.join(', ')}`]),
|
|
32
|
+
];
|
|
33
|
+
const prompt = 'string' === typeof tab.prompt
|
|
34
|
+
? [
|
|
35
|
+
' prompt for your coding agent (copy it):',
|
|
36
|
+
...tab.prompt.split('\n').map((line) => ` ${line}`),
|
|
37
|
+
]
|
|
38
|
+
: [];
|
|
39
|
+
const gate = tab.harnessGate;
|
|
40
|
+
const reason = 'object' === typeof gate && null !== gate
|
|
41
|
+
? gate['reason']
|
|
42
|
+
: undefined;
|
|
43
|
+
// The Harness gate, in the sentence a refused drive says.
|
|
44
|
+
const locked = 'string' === typeof reason ? [` ${reason}`] : [];
|
|
45
|
+
return [doctorRow(DoctorRow.COVERAGE, parts.join(' — ')), ...locked, ...prompt];
|
|
46
|
+
});
|
|
47
|
+
}
|
|
@@ -1,15 +1,3 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Whether `init` has wired THIS directory — the check `doctor` was missing.
|
|
3
|
-
*
|
|
4
|
-
* `doctor` already read `.reticle.json` for the port, so it knew whether the file existed and never
|
|
5
|
-
* said so. In a project where `init` has not run the checklist came out clean: node fine, chromium
|
|
6
|
-
* fine, a daemon that starts on demand, a bridge port. Every line true, and the app carrying no SDK
|
|
7
|
-
* went unremarked — which is exactly the state that produces "the tools are here and nothing ever
|
|
8
|
-
* verifies", and the state `doctor` is run to explain.
|
|
9
|
-
*
|
|
10
|
-
* Registering the MCP server and instrumenting the app are two different halves of the install, and
|
|
11
|
-
* more than one route does the first without the second.
|
|
12
|
-
*/
|
|
13
1
|
interface ProjectWiringFacts {
|
|
14
2
|
/** The id from `.reticle.json`, or undefined when there is no config here. */
|
|
15
3
|
projectId: string | undefined;
|
|
@@ -10,6 +10,7 @@
|
|
|
10
10
|
* Registering the MCP server and instrumenting the app are two different halves of the install, and
|
|
11
11
|
* more than one route does the first without the second.
|
|
12
12
|
*/
|
|
13
|
+
import { DoctorRow, doctorRow } from './doctor-rows.js';
|
|
13
14
|
/**
|
|
14
15
|
* One line, in the same shape as the checks beside it.
|
|
15
16
|
*
|
|
@@ -20,16 +21,16 @@
|
|
|
20
21
|
*/
|
|
21
22
|
export function projectWiringLine(facts) {
|
|
22
23
|
if (facts.projectId !== undefined) {
|
|
23
|
-
return
|
|
24
|
+
return doctorRow(DoctorRow.PROJECT, `✓ wired here (${facts.projectId})`);
|
|
24
25
|
}
|
|
25
26
|
if (facts.previouslyConnected) {
|
|
26
|
-
return '
|
|
27
|
+
return doctorRow(DoctorRow.PROJECT, '✓ an app has connected here before, so it is wired (no .reticle.json — a build plugin can wire an app without one)');
|
|
27
28
|
}
|
|
28
29
|
if (true === facts.configPresent) {
|
|
29
|
-
return ('
|
|
30
|
+
return doctorRow(DoctorRow.PROJECT, '✗ .reticle.json is here but carries no readable projectId — a corrupt or ' +
|
|
30
31
|
'hand-edited config reads the same as no config, and points this project at the default ' +
|
|
31
32
|
'daemon. Run `npx @reticlehq/server init` in the app directory to rewrite it');
|
|
32
33
|
}
|
|
33
|
-
return ('
|
|
34
|
+
return doctorRow(DoctorRow.PROJECT, '✗ no .reticle.json here and nothing has ever connected — the tools may be ' +
|
|
34
35
|
'registered, but this app is not instrumented. Run `npx @reticlehq/server init` in the app directory');
|
|
35
36
|
}
|
|
@@ -40,6 +40,8 @@ export declare const DoctorRow: {
|
|
|
40
40
|
* verification." Every row in this list checks a COMPONENT; none checked a LINK.
|
|
41
41
|
*/
|
|
42
42
|
readonly AGENT_LINK: "agent link";
|
|
43
|
+
/** Is the APP in this folder wired, not just the tools. Printed by `doctor-project-line.ts`. */
|
|
44
|
+
readonly PROJECT: "project";
|
|
43
45
|
/**
|
|
44
46
|
* Which of `localhost`'s two answers reaches the bridge, printed only when they disagree.
|
|
45
47
|
*
|
|
@@ -58,6 +60,10 @@ export declare const DoctorRow: {
|
|
|
58
60
|
readonly DAEMON_LOG: "daemon log";
|
|
59
61
|
readonly TRACING: "tracing";
|
|
60
62
|
readonly DESKTOP: "desktop";
|
|
63
|
+
/** What Reticle sees in each connected app, out of eight capabilities. Only with a live tab. */
|
|
64
|
+
readonly COVERAGE: "coverage";
|
|
65
|
+
/** A project folder holding runs the platform never got. Only when there is one. */
|
|
66
|
+
readonly UNSYNCED: "unsynced";
|
|
61
67
|
};
|
|
62
68
|
type DoctorRowLabel = (typeof DoctorRow)[keyof typeof DoctorRow];
|
|
63
69
|
export declare const DOCTOR_ROW_LABELS: readonly DoctorRowLabel[];
|
|
@@ -40,6 +40,8 @@ export const DoctorRow = {
|
|
|
40
40
|
* verification." Every row in this list checks a COMPONENT; none checked a LINK.
|
|
41
41
|
*/
|
|
42
42
|
AGENT_LINK: 'agent link',
|
|
43
|
+
/** Is the APP in this folder wired, not just the tools. Printed by `doctor-project-line.ts`. */
|
|
44
|
+
PROJECT: 'project',
|
|
43
45
|
/**
|
|
44
46
|
* Which of `localhost`'s two answers reaches the bridge, printed only when they disagree.
|
|
45
47
|
*
|
|
@@ -58,6 +60,10 @@ export const DoctorRow = {
|
|
|
58
60
|
DAEMON_LOG: 'daemon log',
|
|
59
61
|
TRACING: 'tracing',
|
|
60
62
|
DESKTOP: 'desktop',
|
|
63
|
+
/** What Reticle sees in each connected app, out of eight capabilities. Only with a live tab. */
|
|
64
|
+
COVERAGE: 'coverage',
|
|
65
|
+
/** A project folder holding runs the platform never got. Only when there is one. */
|
|
66
|
+
UNSYNCED: 'unsynced',
|
|
61
67
|
};
|
|
62
68
|
export const DOCTOR_ROW_LABELS = Object.values(DoctorRow);
|
|
63
69
|
/** Indent every row carries, before the label. */
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
/** What `codesign -dv` says about one binary. */
|
|
2
|
+
export interface Signature {
|
|
3
|
+
/** Ad-hoc signed, or not signed at all: no identity the keychain can recognise. */
|
|
4
|
+
adhoc: boolean;
|
|
5
|
+
identifier?: string;
|
|
6
|
+
teamId?: string;
|
|
7
|
+
}
|
|
8
|
+
export declare const KEYCHAIN_NOTE: string;
|
|
9
|
+
/** `codesign -dv` output (it writes to stderr), or undefined when it said nothing usable. */
|
|
10
|
+
export declare function parseCodesign(output: string): Signature | undefined;
|
|
11
|
+
/** The note, when the build is unsigned, ad-hoc, or signed by another team than the installed app. */
|
|
12
|
+
export declare function signingNote(build: Signature | undefined, installed: Signature | undefined): string | undefined;
|
|
13
|
+
/**
|
|
14
|
+
* The dev binary `tauri dev` runs, the release builds `tauri build` leaves (the bundle first), and
|
|
15
|
+
* where an installed copy of the same app would be.
|
|
16
|
+
*/
|
|
17
|
+
export declare function tauriDevBinary(read: (path: string) => string | undefined): {
|
|
18
|
+
build: string;
|
|
19
|
+
release: string[];
|
|
20
|
+
installed?: string;
|
|
21
|
+
} | undefined;
|
|
22
|
+
/** How to look at a project, injected so the decision is a unit test. */
|
|
23
|
+
export interface SigningProbe {
|
|
24
|
+
read: (relative: string) => string | undefined;
|
|
25
|
+
codesign?: (path: string) => Signature | undefined;
|
|
26
|
+
platform?: NodeJS.Platform;
|
|
27
|
+
/** The project folder the dev build's relative path is under. */
|
|
28
|
+
dir?: string;
|
|
29
|
+
}
|
|
30
|
+
/** On macOS, the keychain note for the Tauri build Reticle drives, when it applies. */
|
|
31
|
+
export declare function keychainNoteFor(probe: SigningProbe): string | undefined;
|
|
32
|
+
/** A project folder's files, read relative to it. */
|
|
33
|
+
export declare const projectReader: (dir: string) => (relative: string) => string | undefined;
|
|
34
|
+
/**
|
|
35
|
+
* The note for an agent session's first answer, then never again for that session: the person
|
|
36
|
+
* flooded with password dialogs is talking to the agent, and may never run doctor.
|
|
37
|
+
*/
|
|
38
|
+
export declare function keychainNoticeOnce(attach: string, probe: SigningProbe): string | undefined;
|
|
@@ -0,0 +1,114 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Whether macOS will ask for the keychain password every time the app Reticle drives reads it.
|
|
3
|
+
*
|
|
4
|
+
* Reported from the field: a signed macOS Tauri app driven by Reticle flooded its user with password
|
|
5
|
+
* dialogs. Reticle never touches the keychain; macOS binds each keychain item to the signature of
|
|
6
|
+
* the app that saved it, and the build Reticle runs (`tauri dev`, ad-hoc signed) is another app to
|
|
7
|
+
* the keychain. Read from `codesign -dv`, through an injected runner, so the parsing is a unit test.
|
|
8
|
+
*/
|
|
9
|
+
import { existsSync, readFileSync } from 'node:fs';
|
|
10
|
+
import { spawnSync } from 'node:child_process';
|
|
11
|
+
import { isAbsolute, join, posix } from 'node:path';
|
|
12
|
+
export const KEYCHAIN_NOTE = "macOS ties keychain items to the app's signature; this build is signed differently, so the " +
|
|
13
|
+
"app's keychain reads will ask for your password. Set your release identity " +
|
|
14
|
+
'(APPLE_SIGNING_IDENTITY, or signingIdentity in tauri.conf.json) and `reticle setup` signs the ' +
|
|
15
|
+
'dev build it starts with it; or use a separate keychain service in dev.';
|
|
16
|
+
const NOT_SIGNED = 'code object is not signed at all';
|
|
17
|
+
const NO_TEAM = 'not set';
|
|
18
|
+
/** `codesign -dv` output (it writes to stderr), or undefined when it said nothing usable. */
|
|
19
|
+
export function parseCodesign(output) {
|
|
20
|
+
if (output.includes(NOT_SIGNED))
|
|
21
|
+
return { adhoc: true };
|
|
22
|
+
const field = (key) => new RegExp(`^${key}=(.+)$`, 'm').exec(output)?.[1]?.trim();
|
|
23
|
+
const identifier = field('Identifier');
|
|
24
|
+
if (identifier === undefined)
|
|
25
|
+
return undefined;
|
|
26
|
+
const team = field('TeamIdentifier');
|
|
27
|
+
return {
|
|
28
|
+
adhoc: 'adhoc' === field('Signature'),
|
|
29
|
+
identifier,
|
|
30
|
+
...(team === undefined || NO_TEAM === team ? {} : { teamId: team }),
|
|
31
|
+
};
|
|
32
|
+
}
|
|
33
|
+
/** The note, when the build is unsigned, ad-hoc, or signed by another team than the installed app. */
|
|
34
|
+
export function signingNote(build, installed) {
|
|
35
|
+
if (build === undefined)
|
|
36
|
+
return undefined;
|
|
37
|
+
if (build.adhoc)
|
|
38
|
+
return KEYCHAIN_NOTE;
|
|
39
|
+
if (installed !== undefined && installed.teamId !== build.teamId)
|
|
40
|
+
return KEYCHAIN_NOTE;
|
|
41
|
+
return undefined;
|
|
42
|
+
}
|
|
43
|
+
/**
|
|
44
|
+
* The dev binary `tauri dev` runs, the release builds `tauri build` leaves (the bundle first), and
|
|
45
|
+
* where an installed copy of the same app would be.
|
|
46
|
+
*/
|
|
47
|
+
export function tauriDevBinary(read) {
|
|
48
|
+
const cargo = read('src-tauri/Cargo.toml');
|
|
49
|
+
const name = cargo === undefined ? undefined : /^name\s*=\s*"([^"]+)"/m.exec(cargo)?.[1];
|
|
50
|
+
if (name === undefined)
|
|
51
|
+
return undefined;
|
|
52
|
+
let product;
|
|
53
|
+
try {
|
|
54
|
+
product = JSON.parse(read('src-tauri/tauri.conf.json') ?? '{}')['productName'];
|
|
55
|
+
}
|
|
56
|
+
catch {
|
|
57
|
+
product = undefined;
|
|
58
|
+
}
|
|
59
|
+
const named = 'string' === typeof product && 0 < product.length ? product : undefined;
|
|
60
|
+
return {
|
|
61
|
+
build: `src-tauri/target/debug/${name}`,
|
|
62
|
+
release: [
|
|
63
|
+
...(named === undefined ? [] : [`src-tauri/target/release/bundle/macos/${named}.app`]),
|
|
64
|
+
`src-tauri/target/release/${name}`,
|
|
65
|
+
],
|
|
66
|
+
...(named === undefined ? {} : { installed: `/Applications/${named}.app` }),
|
|
67
|
+
};
|
|
68
|
+
}
|
|
69
|
+
/** `codesign -dv` of one path, as it prints it (to stderr). Undefined when nothing ran. */
|
|
70
|
+
function codesignOf(path) {
|
|
71
|
+
if (!existsSync(path))
|
|
72
|
+
return undefined;
|
|
73
|
+
const run = spawnSync('codesign', ['-dv', '--verbose=2', path], { encoding: 'utf8' });
|
|
74
|
+
return parseCodesign(`${run.stdout}${run.stderr}`);
|
|
75
|
+
}
|
|
76
|
+
/** On macOS, the keychain note for the Tauri build Reticle drives, when it applies. */
|
|
77
|
+
export function keychainNoteFor(probe) {
|
|
78
|
+
if ('darwin' !== (probe.platform ?? process.platform))
|
|
79
|
+
return undefined;
|
|
80
|
+
const app = tauriDevBinary(probe.read);
|
|
81
|
+
if (app === undefined)
|
|
82
|
+
return undefined;
|
|
83
|
+
const codesign = probe.codesign ?? codesignOf;
|
|
84
|
+
const installed = app.installed === undefined ? undefined : codesign(app.installed);
|
|
85
|
+
// Every build on disk, debug and release: a person with only a release build heard nothing.
|
|
86
|
+
for (const build of [app.build, ...app.release]) {
|
|
87
|
+
// macOS only, so a POSIX path on every host the unit test runs on.
|
|
88
|
+
const note = signingNote(codesign(posix.join(probe.dir ?? process.cwd(), build)), installed);
|
|
89
|
+
if (note !== undefined)
|
|
90
|
+
return note;
|
|
91
|
+
}
|
|
92
|
+
return undefined;
|
|
93
|
+
}
|
|
94
|
+
/** A project folder's files, read relative to it. */
|
|
95
|
+
export const projectReader = (dir) => (relative) => {
|
|
96
|
+
try {
|
|
97
|
+
return readFileSync(isAbsolute(relative) ? relative : join(dir, relative), 'utf8');
|
|
98
|
+
}
|
|
99
|
+
catch {
|
|
100
|
+
return undefined;
|
|
101
|
+
}
|
|
102
|
+
};
|
|
103
|
+
// ponytail: grows by one id per agent connection the daemon ever served; bound it if that matters.
|
|
104
|
+
const noticed = new Set();
|
|
105
|
+
/**
|
|
106
|
+
* The note for an agent session's first answer, then never again for that session: the person
|
|
107
|
+
* flooded with password dialogs is talking to the agent, and may never run doctor.
|
|
108
|
+
*/
|
|
109
|
+
export function keychainNoticeOnce(attach, probe) {
|
|
110
|
+
if (noticed.has(attach))
|
|
111
|
+
return undefined;
|
|
112
|
+
noticed.add(attach);
|
|
113
|
+
return keychainNoteFor(probe);
|
|
114
|
+
}
|
|
@@ -44,7 +44,7 @@ export declare function decideDriveMode(presence: PortPresence): DriveMode;
|
|
|
44
44
|
/** A driveable session the daemon opened on our behalf. */
|
|
45
45
|
interface DriveSession {
|
|
46
46
|
sessionId: string;
|
|
47
|
-
/** Whether the tab's SDK actually registered — false ⇒ the app may not embed @reticlehq/
|
|
47
|
+
/** Whether the tab's SDK actually registered — false ⇒ the app may not embed @reticlehq/browser. */
|
|
48
48
|
ready: boolean;
|
|
49
49
|
/** How long the session survives untouched. Absent from a daemon that does not report it. */
|
|
50
50
|
expiresInMs?: number;
|
|
@@ -76,8 +76,33 @@ export declare function readAttachResponse(port: number, url: string, res: {
|
|
|
76
76
|
}): DriveAttachResult;
|
|
77
77
|
/** Ask the daemon on `port` to open a driveable browser at `url`. */
|
|
78
78
|
export declare function requestDriveSession(port: number, url: string, post?: DrivePost): Promise<DriveAttachResult>;
|
|
79
|
+
/** Which app the attached page says it is, beside the project this directory names. */
|
|
80
|
+
export interface AttachedApp {
|
|
81
|
+
/** What the JSON line carries. Every value is printable, see `printable`. */
|
|
82
|
+
fields: {
|
|
83
|
+
/** The project the page reported when it connected. */
|
|
84
|
+
projectId?: string;
|
|
85
|
+
title?: string;
|
|
86
|
+
/** The `projectId` in this directory's `.reticle.json`, when there is one. */
|
|
87
|
+
expectedProjectId?: string;
|
|
88
|
+
};
|
|
89
|
+
/**
|
|
90
|
+
* The two project ids differ. Decided on the raw values, before either is made printable, so two
|
|
91
|
+
* ids that differ only in a control character still count as different.
|
|
92
|
+
*/
|
|
93
|
+
mismatch: boolean;
|
|
94
|
+
}
|
|
95
|
+
/** Nothing known about the app, as for a page that never connected. */
|
|
96
|
+
export declare const NO_ATTACHED_APP: AttachedApp;
|
|
97
|
+
/**
|
|
98
|
+
* Pick the attached session out of a `/status` payload. Pure.
|
|
99
|
+
*
|
|
100
|
+
* The drive answer is a lease result, which carries no project: the page reports that itself when
|
|
101
|
+
* it connects, and `/status` is where it is already listed.
|
|
102
|
+
*/
|
|
103
|
+
export declare function attachedApp(status: unknown, sessionId: string, expectedProjectId: string | undefined): AttachedApp;
|
|
79
104
|
/** The success line. Names the session, because that is the handle everything downstream needs. */
|
|
80
|
-
export declare function describeAttached(port: number, url: string, session: DriveSession): string;
|
|
105
|
+
export declare function describeAttached(port: number, url: string, session: DriveSession, app?: AttachedApp): string;
|
|
81
106
|
/**
|
|
82
107
|
* What an attach cannot honour: the window.
|
|
83
108
|
*
|