@reticlehq/server 2.11.0 → 2.13.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 +93 -111
- package/dist/bridge/auth-failure-reason.d.ts +6 -2
- package/dist/bridge/auth-failure-reason.js +15 -8
- package/dist/bridge/bridge.d.ts +18 -14
- package/dist/bridge/bridge.js +248 -165
- package/dist/bridge/bridge.test-harness.d.ts +2 -0
- package/dist/bridge/bridge.test-harness.js +8 -1
- package/dist/bridge/pairing-token.d.ts +5 -0
- package/dist/bridge/pairing-token.js +28 -0
- package/dist/bridge/protocol-skew.d.ts +37 -0
- package/dist/bridge/protocol-skew.js +45 -0
- package/dist/capsule/capsule-store.d.ts +8 -7
- package/dist/capsule/capsule-store.js +1 -1
- package/dist/capsule/causal-summary.d.ts +2 -2
- package/dist/capsule/causal-summary.js +7 -2
- package/dist/chromium-launch-options.d.ts +28 -0
- package/dist/chromium-launch-options.js +29 -0
- package/dist/cli/cli-doctor.js +39 -1
- package/dist/cli/cli-flow-commands.d.ts +3 -1
- package/dist/cli/cli-flow-commands.js +34 -4
- package/dist/cli/cli-kill.d.ts +2 -1
- package/dist/cli/cli-launch.d.ts +11 -1
- package/dist/cli/cli-launch.js +59 -10
- package/dist/cli/cli-parse.d.ts +17 -1
- package/dist/cli/cli-parse.js +238 -12
- package/dist/cli/cli-update-commands.js +20 -1
- package/dist/cli/cli-verify.d.ts +2 -1
- package/dist/cli/cli-verify.js +5 -4
- package/dist/cli/cloud-cli.js +428 -253
- package/dist/cli/cloud-keystore.d.ts +37 -0
- package/dist/cli/cloud-keystore.js +97 -0
- package/dist/cli/cloud-kit.d.ts +37 -0
- package/dist/cli/cloud-kit.js +121 -0
- package/dist/cli/cloud-login.d.ts +17 -0
- package/dist/cli/cloud-login.js +183 -0
- package/dist/cli/cloud-session.d.ts +48 -0
- package/dist/cli/cloud-session.js +53 -0
- package/dist/cli/config-discovery.d.ts +2 -1
- package/dist/cli/config-discovery.js +1 -0
- package/dist/cli/daemon-start-options.d.ts +32 -0
- package/dist/cli/daemon-start-options.js +38 -0
- package/dist/cli/device-flow.d.ts +76 -0
- package/dist/cli/device-flow.js +56 -0
- package/dist/cli/doctor-rows.d.ts +12 -1
- package/dist/cli/doctor-rows.js +12 -1
- package/dist/cli/drive-attach.d.ts +13 -0
- package/dist/cli/drive-attach.js +18 -0
- package/dist/cli/drive-command.js +7 -3
- package/dist/cli/gate-exit.d.ts +21 -0
- package/dist/cli/gate-exit.js +21 -0
- package/dist/cli/gate-hook-message.d.ts +33 -0
- package/dist/cli/gate-hook-message.js +46 -0
- package/dist/cli/mcp-command.d.ts +25 -0
- package/dist/cli/mcp-command.js +174 -0
- package/dist/cli/project-name.d.ts +30 -0
- package/dist/cli/project-name.js +44 -0
- package/dist/cli/sibling-ports.d.ts +37 -0
- package/dist/cli/sibling-ports.js +56 -0
- package/dist/cli/status-next-action.d.ts +14 -0
- package/dist/cli/status-next-action.js +4 -4
- package/dist/cli.d.ts +1 -0
- package/dist/cli.js +167 -186
- package/dist/cloud/cloud-config.d.ts +24 -2
- package/dist/cloud/cloud-config.js +64 -5
- package/dist/cloud/cloud-sync.d.ts +16 -5
- package/dist/cloud/cloud-sync.js +64 -1
- package/dist/cloud/sync-cycle.d.ts +110 -0
- package/dist/cloud/sync-cycle.js +270 -0
- package/dist/cloud/sync-daemon.d.ts +69 -0
- package/dist/cloud/sync-daemon.js +260 -0
- package/dist/cloud/sync-disk.d.ts +9 -0
- package/dist/cloud/sync-disk.js +191 -0
- package/dist/cloud/sync-hash.d.ts +2 -0
- package/dist/cloud/sync-hash.js +35 -0
- package/dist/crawl/crawl-tools.js +5 -3
- package/dist/crawl/crawl.d.ts +12 -13
- package/dist/crawl/crawl.js +25 -3
- package/dist/daemon/daemon-resolve.d.ts +122 -0
- package/dist/daemon/daemon-resolve.js +187 -0
- package/dist/daemon/dev-servers.d.ts +15 -0
- package/dist/daemon/dev-servers.js +68 -0
- package/dist/daemon/free-port.d.ts +29 -0
- package/dist/daemon/free-port.js +55 -0
- package/dist/daemon/heartbeat.d.ts +0 -4
- package/dist/daemon/heartbeat.js +2 -2
- package/dist/daemon/wake-decision.d.ts +32 -0
- package/dist/daemon/wake-decision.js +38 -0
- package/dist/dev/stale-issue-guard.d.ts +0 -2
- package/dist/dev/stale-issue-guard.js +1 -1
- package/dist/domain/domain-tools.js +2 -2
- package/dist/events/contradictions.d.ts +59 -0
- package/dist/events/contradictions.js +253 -27
- package/dist/events/declared.d.ts +17 -0
- package/dist/events/declared.js +43 -1
- package/dist/events/echo-mismatch.js +65 -1
- package/dist/events/event-filters.d.ts +8 -0
- package/dist/events/event-filters.js +19 -2
- package/dist/events/observed-in-window.d.ts +12 -0
- package/dist/events/observed-in-window.js +17 -0
- package/dist/events/predicate-asks.d.ts +13 -0
- package/dist/events/predicate-asks.js +22 -0
- package/dist/events/predicate-eval.js +117 -27
- package/dist/events/predicate-parse.d.ts +0 -6
- package/dist/events/predicate-parse.js +43 -3
- package/dist/events/predicate-precheck.d.ts +8 -0
- package/dist/events/predicate-precheck.js +41 -0
- package/dist/events/predicate-route.d.ts +14 -0
- package/dist/events/predicate-route.js +36 -8
- package/dist/events/predicate-schema.d.ts +44 -0
- package/dist/events/predicate-schema.js +126 -23
- package/dist/events/predicate.d.ts +20 -0
- package/dist/events/predicate.js +77 -6
- package/dist/events/split-text-miss.d.ts +30 -0
- package/dist/events/split-text-miss.js +44 -0
- package/dist/flows/coverage.d.ts +0 -8
- package/dist/flows/coverage.js +1 -1
- package/dist/flows/decision.d.ts +5 -1
- package/dist/flows/decision.js +33 -7
- package/dist/flows/flake.d.ts +6 -8
- package/dist/flows/flake.js +1 -1
- package/dist/flows/flow-intent.d.ts +52 -0
- package/dist/flows/flow-intent.js +123 -0
- package/dist/flows/flow-memory-consult.d.ts +55 -0
- package/dist/flows/flow-memory-consult.js +38 -0
- package/dist/flows/flow-replay-run.d.ts +18 -7
- package/dist/flows/flow-replay-run.js +263 -23
- package/dist/flows/flow-replay.js +11 -2
- package/dist/flows/flow-step-runners.d.ts +8 -0
- package/dist/flows/flow-step-runners.js +8 -2
- package/dist/flows/flow-store-for-session.d.ts +31 -0
- package/dist/flows/flow-store-for-session.js +33 -0
- package/dist/flows/flow-success.js +15 -3
- package/dist/flows/flow-tools.js +87 -33
- package/dist/flows/flows.d.ts +14 -1
- package/dist/flows/flows.js +502 -24
- package/dist/flows/heal-run.js +5 -2
- package/dist/flows/predicate-to-expect.d.ts +17 -12
- package/dist/flows/predicate-to-expect.js +36 -15
- package/dist/flows/recordings.d.ts +13 -1
- package/dist/flows/recordings.js +17 -2
- package/dist/flows/replay.d.ts +22 -2
- package/dist/flows/replay.js +28 -2
- package/dist/flows/server-verify.js +16 -2
- package/dist/flows/verify-change-tools.js +9 -3
- package/dist/honesty/blind-spots.d.ts +51 -15
- package/dist/honesty/blind-spots.js +64 -4
- package/dist/honesty/feature-capture.d.ts +150 -0
- package/dist/honesty/feature-capture.js +233 -0
- package/dist/honesty/honesty.d.ts +24 -0
- package/dist/honesty/honesty.js +25 -1
- package/dist/honesty/instrumentation-gaps.d.ts +39 -6
- package/dist/honesty/instrumentation-gaps.js +88 -5
- package/dist/honesty/tool-hit-rate.d.ts +86 -0
- package/dist/honesty/tool-hit-rate.js +90 -0
- package/dist/honesty/undeclared-change.d.ts +51 -0
- package/dist/honesty/undeclared-change.js +56 -0
- package/dist/honesty/verified.d.ts +16 -0
- package/dist/honesty/verified.js +84 -5
- package/dist/http-server.d.ts +0 -1
- package/dist/http-server.js +13 -1
- package/dist/hunt/hunt-report.d.ts +0 -2
- package/dist/hunt/hunt-report.js +1 -1
- package/dist/impact/impact-recorder.d.ts +31 -8
- package/dist/impact/impact-recorder.js +104 -21
- package/dist/impact/impact-store.d.ts +13 -4
- package/dist/impact/impact-store.js +44 -3
- package/dist/index.d.ts +4 -1
- package/dist/index.js +113 -7
- package/dist/init/agent-rules.d.ts +30 -6
- package/dist/init/agent-rules.js +54 -13
- package/dist/init/astro-patch.d.ts +16 -0
- package/dist/init/astro-patch.js +28 -0
- package/dist/init/capabilities.d.ts +4 -3
- package/dist/init/capabilities.js +23 -3
- package/dist/init/closing-hint.d.ts +36 -0
- package/dist/init/closing-hint.js +120 -0
- package/dist/init/confirm.d.ts +27 -28
- package/dist/init/confirm.js +51 -11
- package/dist/init/cra.d.ts +34 -5
- package/dist/init/cra.js +96 -25
- package/dist/init/csp-check.js +17 -2
- package/dist/init/csp-doctor.d.ts +8 -1
- package/dist/init/csp-doctor.js +8 -3
- package/dist/init/dev-script.d.ts +50 -0
- package/dist/init/dev-script.js +66 -0
- package/dist/init/format-generated.d.ts +18 -0
- package/dist/init/format-generated.js +39 -0
- package/dist/init/install-hint.d.ts +9 -0
- package/dist/init/install-hint.js +29 -0
- package/dist/init/mcp-clients.d.ts +7 -0
- package/dist/init/mcp-clients.js +7 -0
- package/dist/init/mcp.d.ts +17 -6
- package/dist/init/mcp.js +27 -11
- package/dist/init/node-io.js +11 -1
- package/dist/init/plan-framework.d.ts +0 -5
- package/dist/init/plan-framework.js +147 -37
- package/dist/init/plan.d.ts +30 -37
- package/dist/init/plan.js +50 -60
- package/dist/init/preflight.d.ts +28 -0
- package/dist/init/preflight.js +38 -0
- package/dist/init/refresh-rules.d.ts +39 -0
- package/dist/init/refresh-rules.js +51 -0
- package/dist/init/run.d.ts +32 -35
- package/dist/init/run.js +151 -202
- package/dist/init/slash-command.d.ts +1 -1
- package/dist/init/snippets.js +90 -31
- package/dist/init/vite-config.d.ts +1 -1
- package/dist/init/vite-config.js +39 -25
- package/dist/init/workspace-apps.d.ts +17 -10
- package/dist/init/workspace-apps.js +110 -0
- package/dist/input/network-mock-tools.js +3 -6
- package/dist/input/real-input.d.ts +2 -0
- package/dist/input/real-input.js +28 -7
- package/dist/input/scroll-find.d.ts +7 -4
- package/dist/input/scroll-find.js +63 -25
- package/dist/input/scroll-tools.js +4 -6
- package/dist/input/viewport-tools.js +5 -4
- package/dist/intent/inline-intent.d.ts +37 -0
- package/dist/intent/inline-intent.js +193 -0
- package/dist/intent/intent-shard-store.d.ts +72 -0
- package/dist/intent/intent-shard-store.js +203 -0
- package/dist/intent/intent-shard.d.ts +411 -0
- package/dist/intent/intent-shard.js +176 -0
- package/dist/intent/intent-store.d.ts +49 -0
- package/dist/intent/intent-store.js +133 -0
- package/dist/intent/intent-subject.d.ts +45 -0
- package/dist/intent/intent-subject.js +177 -0
- package/dist/intent/intent-tools.d.ts +2 -0
- package/dist/intent/intent-tools.js +143 -0
- package/dist/intent/open-intents.d.ts +42 -0
- package/dist/intent/open-intents.js +40 -0
- package/dist/journal/envelope.d.ts +26 -26
- package/dist/journal/journal-recorder.d.ts +23 -0
- package/dist/journal/journal-recorder.js +35 -0
- package/dist/license/license-env.d.ts +29 -0
- package/dist/license/license-env.js +148 -0
- package/dist/loopback-agent.d.ts +31 -0
- package/dist/loopback-agent.js +57 -0
- package/dist/mcp/attach-memory.d.ts +83 -0
- package/dist/mcp/attach-memory.js +185 -0
- package/dist/mcp/client-identity.d.ts +31 -0
- package/dist/mcp/client-identity.js +51 -0
- package/dist/mcp/mcp-post-transport.d.ts +26 -0
- package/dist/mcp/mcp-post-transport.js +109 -0
- package/dist/mcp/mcp-proxy.d.ts +2 -8
- package/dist/mcp/mcp-proxy.js +64 -62
- package/dist/mcp/mcp.d.ts +2 -0
- package/dist/mcp/mcp.js +52 -24
- package/dist/mcp/proxy-backoff.d.ts +11 -0
- package/dist/mcp/proxy-backoff.js +13 -0
- package/dist/mcp/proxy-daemon-probe.d.ts +1 -0
- package/dist/mcp/proxy-daemon-probe.js +7 -1
- package/dist/mcp/proxy-handshake.d.ts +23 -0
- package/dist/mcp/proxy-handshake.js +31 -0
- package/dist/mcp/server-instructions.js +45 -3
- package/dist/mcp/tool-catalog-cache.d.ts +16 -0
- package/dist/mcp/tool-catalog-cache.js +22 -0
- package/dist/memory/memory-tools.d.ts +2 -0
- package/dist/memory/memory-tools.js +82 -0
- package/dist/memory/project-memory.d.ts +34 -0
- package/dist/memory/project-memory.js +96 -0
- package/dist/oracles/flow-instrument-gaps.d.ts +4 -4
- package/dist/oracles/flow-instrument-gaps.js +4 -5
- package/dist/oracles/propose-consequences.js +12 -3
- package/dist/oracles/self-instrument.d.ts +9 -9
- package/dist/oracles/self-instrument.js +19 -13
- package/dist/pool/browser-pool.d.ts +75 -5
- package/dist/pool/browser-pool.js +144 -5
- package/dist/pool/playwright-launcher.js +12 -1
- package/dist/project/fs-port.d.ts +3 -0
- package/dist/project/fs-port.js +3 -2
- package/dist/project/memory-fs.js +6 -1
- package/dist/project/project-tools.js +6 -35
- package/dist/project/reticle-dir.d.ts +17 -2
- package/dist/project/reticle-dir.js +22 -4
- package/dist/runs/context-tools.d.ts +2 -0
- package/dist/runs/context-tools.js +89 -0
- package/dist/runs/run-context.d.ts +40 -0
- package/dist/runs/run-context.js +158 -0
- package/dist/runs/run-diff.d.ts +2 -1
- package/dist/runs/run-store.d.ts +10 -0
- package/dist/runs/run-store.js +10 -0
- package/dist/runs/verification-sync.d.ts +0 -11
- package/dist/runs/verification-sync.js +24 -3
- package/dist/runs/verify-server.d.ts +8 -1
- package/dist/runs/verify-server.js +14 -2
- package/dist/session/command-timeout.d.ts +5 -2
- package/dist/session/command-timeout.js +5 -4
- package/dist/session/dev-server-probe.d.ts +0 -8
- package/dist/session/dev-server-probe.js +1 -1
- package/dist/session/last-act.d.ts +7 -1
- package/dist/session/last-act.js +2 -2
- package/dist/session/lease-visibility.d.ts +67 -0
- package/dist/session/lease-visibility.js +76 -0
- package/dist/session/live-control-tools.js +1 -42
- package/dist/session/no-session-diagnosis.d.ts +33 -0
- package/dist/session/no-session-diagnosis.js +82 -24
- package/dist/session/no-session-next-action.d.ts +12 -0
- package/dist/session/no-session-next-action.js +77 -6
- package/dist/session/no-session-watch.d.ts +18 -6
- package/dist/session/no-session-watch.js +125 -75
- package/dist/session/output-budget.js +4 -1
- package/dist/session/pending-commands.d.ts +11 -1
- package/dist/session/pending-commands.js +12 -2
- package/dist/session/resolve-within.d.ts +34 -0
- package/dist/session/resolve-within.js +53 -0
- package/dist/session/session-health.d.ts +9 -0
- package/dist/session/session-health.js +23 -0
- package/dist/session/session-info.d.ts +18 -0
- package/dist/session/session-info.js +11 -0
- package/dist/session/session-manager.d.ts +14 -0
- package/dist/session/session-manager.js +111 -4
- package/dist/session/session-mirror.d.ts +16 -0
- package/dist/session/session-mirror.js +22 -0
- package/dist/session/session-recommendation.d.ts +19 -5
- package/dist/session/session-recommendation.js +25 -9
- package/dist/session/session-successor.d.ts +37 -0
- package/dist/session/session-successor.js +113 -0
- package/dist/session/session-tools.js +2 -2
- package/dist/session/session.d.ts +53 -3
- package/dist/session/session.js +162 -9
- package/dist/session/wall-clock.d.ts +12 -0
- package/dist/session/wall-clock.js +14 -0
- package/dist/setup/agent-configs.d.ts +96 -0
- package/dist/setup/agent-configs.js +333 -0
- package/dist/setup/agent-io.d.ts +9 -0
- package/dist/setup/agent-io.js +16 -0
- package/dist/setup/agent-writer.d.ts +51 -0
- package/dist/setup/agent-writer.js +115 -0
- package/dist/setup/approval-migration.d.ts +47 -0
- package/dist/setup/approval-migration.js +68 -0
- package/dist/setup/auto-approve.d.ts +85 -0
- package/dist/setup/auto-approve.js +150 -0
- package/dist/setup/bridge-port.d.ts +15 -0
- package/dist/setup/bridge-port.js +24 -0
- package/dist/setup/desktop-shape.d.ts +57 -0
- package/dist/setup/desktop-shape.js +63 -0
- package/dist/setup/dev-server-wait.d.ts +60 -0
- package/dist/setup/dev-server-wait.js +65 -0
- package/dist/setup/drive-agent.d.ts +71 -0
- package/dist/setup/drive-agent.js +171 -0
- package/dist/setup/drive-plan.d.ts +68 -0
- package/dist/setup/drive-plan.js +130 -0
- package/dist/setup/ensure-daemon.d.ts +29 -0
- package/dist/setup/ensure-daemon.js +58 -0
- package/dist/setup/init-runtime.d.ts +47 -0
- package/dist/setup/init-runtime.js +160 -0
- package/dist/setup/interrupt.d.ts +25 -0
- package/dist/setup/interrupt.js +40 -0
- package/dist/setup/license-key.d.ts +39 -0
- package/dist/setup/license-key.js +72 -0
- package/dist/setup/listeners.d.ts +37 -0
- package/dist/setup/listeners.js +85 -0
- package/dist/setup/node-effects.d.ts +60 -0
- package/dist/setup/node-effects.js +210 -0
- package/dist/setup/page-probe.d.ts +39 -0
- package/dist/setup/page-probe.js +49 -0
- package/dist/setup/relaunch.d.ts +36 -0
- package/dist/setup/relaunch.js +57 -0
- package/dist/setup/remaining-steps.d.ts +19 -0
- package/dist/setup/remaining-steps.js +31 -0
- package/dist/setup/run-setup.d.ts +99 -0
- package/dist/setup/run-setup.js +187 -0
- package/dist/setup/session-pick.d.ts +47 -0
- package/dist/setup/session-pick.js +51 -0
- package/dist/setup/setup-command.d.ts +45 -0
- package/dist/setup/setup-command.js +199 -0
- package/dist/setup/setup-options.d.ts +74 -0
- package/dist/setup/setup-options.js +67 -0
- package/dist/setup/transcripts.d.ts +16 -0
- package/dist/setup/transcripts.js +43 -0
- package/dist/status-payload.d.ts +14 -1
- package/dist/status-payload.js +23 -1
- package/dist/telemetry/automation-hint.d.ts +2 -1
- package/dist/telemetry/daemon-telemetry.d.ts +8 -1
- package/dist/telemetry/daemon-telemetry.js +52 -5
- package/dist/telemetry/error-class.js +1 -1
- package/dist/telemetry/feedback-context.d.ts +9 -1
- package/dist/telemetry/feedback-context.js +60 -29
- package/dist/telemetry/feedback-local.d.ts +15 -0
- package/dist/telemetry/feedback-local.js +56 -0
- package/dist/telemetry/feedback-outbox.d.ts +2 -1
- package/dist/telemetry/feedback.d.ts +11 -0
- package/dist/telemetry/feedback.js +19 -6
- package/dist/telemetry/init-telemetry.d.ts +2 -0
- package/dist/telemetry/init-telemetry.js +2 -0
- package/dist/telemetry/install-source.d.ts +14 -0
- package/dist/telemetry/install-source.js +30 -0
- package/dist/telemetry/license-activation.d.ts +7 -1
- package/dist/telemetry/license-activation.js +9 -5
- package/dist/telemetry/mcp-connection.js +7 -0
- package/dist/telemetry/project-profile.d.ts +12 -9
- package/dist/telemetry/project-profile.js +12 -7
- package/dist/telemetry/proxy-telemetry.d.ts +3 -0
- package/dist/telemetry/proxy-telemetry.js +21 -0
- package/dist/telemetry/run-telemetry.d.ts +0 -2
- package/dist/telemetry/run-telemetry.js +1 -1
- package/dist/telemetry/session-metrics.d.ts +12 -0
- package/dist/telemetry/session-metrics.js +35 -1
- package/dist/telemetry/telemetry.js +17 -2
- package/dist/telemetry/tool-refused.d.ts +3 -1
- package/dist/telemetry/tool-refused.js +34 -2
- package/dist/telemetry/verification-of.js +2 -2
- package/dist/tools/act-capsule.d.ts +10 -0
- package/dist/tools/act-capsule.js +8 -2
- package/dist/tools/act-danger.d.ts +2 -1
- package/dist/tools/act-danger.js +11 -3
- package/dist/tools/act-observation.d.ts +41 -0
- package/dist/tools/act-observation.js +36 -0
- package/dist/tools/act-preflight.d.ts +20 -0
- package/dist/tools/act-preflight.js +98 -0
- package/dist/tools/act-sequence-retry.d.ts +45 -0
- package/dist/tools/act-sequence-retry.js +58 -0
- package/dist/tools/act-sequence-tool.d.ts +13 -0
- package/dist/tools/act-sequence-tool.js +135 -0
- package/dist/tools/act-target.d.ts +14 -0
- package/dist/tools/act-target.js +47 -0
- package/dist/tools/act-tools.d.ts +21 -1
- package/dist/tools/act-tools.js +196 -204
- package/dist/tools/assert-source.d.ts +22 -0
- package/dist/tools/assert-source.js +53 -0
- package/dist/tools/assert-verdict.d.ts +20 -3
- package/dist/tools/assert-verdict.js +58 -20
- package/dist/tools/browser-tools.js +6 -22
- package/dist/tools/complete-snapshot.d.ts +48 -0
- package/dist/tools/complete-snapshot.js +75 -0
- package/dist/tools/coverage-tools.d.ts +10 -1
- package/dist/tools/coverage-tools.js +123 -69
- package/dist/tools/dynamic-tools.js +53 -13
- package/dist/tools/error-recovery.d.ts +25 -14
- package/dist/tools/error-recovery.js +78 -9
- package/dist/tools/feedback-tools.d.ts +1 -1
- package/dist/tools/feedback-tools.js +2 -2
- package/dist/tools/invoke-tool.js +121 -11
- package/dist/tools/lease-hint.d.ts +10 -0
- package/dist/tools/lease-hint.js +53 -4
- package/dist/tools/lease-tools.d.ts +35 -5
- package/dist/tools/lease-tools.js +191 -13
- package/dist/tools/merged-name-redirect.d.ts +13 -0
- package/dist/tools/merged-name-redirect.js +22 -0
- package/dist/tools/navigate-arrival.d.ts +0 -2
- package/dist/tools/navigate-arrival.js +1 -1
- package/dist/tools/numeric-bounds.d.ts +100 -0
- package/dist/tools/numeric-bounds.js +125 -0
- package/dist/tools/observe-tools.js +109 -65
- package/dist/tools/read-tools.js +31 -8
- package/dist/tools/real-input-attempt.d.ts +32 -0
- package/dist/tools/real-input-attempt.js +212 -2
- package/dist/tools/reconcile-tools.js +22 -8
- package/dist/tools/resolve-target.d.ts +0 -7
- package/dist/tools/sdk-marker-probe.d.ts +29 -0
- package/dist/tools/sdk-marker-probe.js +57 -0
- package/dist/tools/snapshot-delta.d.ts +1 -1
- package/dist/tools/tool-kit.d.ts +24 -0
- package/dist/tools/tool-kit.js +21 -0
- package/dist/tools/tool-names.d.ts +5 -0
- package/dist/tools/tool-names.js +5 -0
- package/dist/tools/tool-surface.d.ts +85 -6
- package/dist/tools/tool-surface.js +122 -2
- package/dist/tools/tools-helpers.d.ts +19 -0
- package/dist/tools/tools-helpers.js +46 -0
- package/dist/tools/tools.d.ts +2 -0
- package/dist/tools/tools.js +78 -12
- package/dist/tools/unadvertised-help.js +4 -4
- package/dist/tools/verify-next-baton.d.ts +53 -0
- package/dist/tools/verify-next-baton.js +52 -0
- package/dist/update/reticle-deps.d.ts +9 -0
- package/dist/update/reticle-deps.js +27 -0
- package/dist/update/sdk-sync.d.ts +1 -2
- package/dist/update/sdk-sync.js +1 -21
- package/dist/update/update-nudge.d.ts +25 -10
- package/dist/update/update-nudge.js +32 -3
- package/dist/update/updater.d.ts +1 -1
- package/dist/version/peer-announce.js +4 -2
- package/dist/version/sdk-fix.d.ts +47 -0
- package/dist/version/sdk-fix.js +127 -0
- package/dist/version/version-nudge.d.ts +14 -0
- package/dist/version/version-nudge.js +21 -0
- package/dist/version/version-skew.d.ts +38 -3
- package/dist/version/version-skew.js +83 -7
- package/dist/visual/visual-store.d.ts +6 -6
- package/dist/visual/visual-store.js +18 -16
- package/dist/visual/visual-tools.js +57 -12
- package/docs/README.md +2 -1
- package/docs/cli/cloud.mdx +1 -1
- package/docs/cli/doctor.mdx +2 -0
- package/docs/cli/serve.mdx +4 -2
- package/docs/cli/verify.mdx +4 -5
- package/docs/cli.mdx +7 -3
- package/docs/desktop.mdx +1 -1
- package/docs/docs.json +2 -2
- package/docs/gates.md +1 -1
- package/docs/getting-started.md +19 -3
- package/docs/index.mdx +9 -6
- package/docs/install-agentic.mdx +38 -12
- package/docs/install-manual.mdx +1 -1
- package/docs/packages/browser.mdx +2 -2
- package/docs/packages/server.mdx +1 -1
- package/docs/packages.mdx +8 -6
- package/docs/platform-integration.md +17 -0
- package/docs/predicates.mdx +8 -0
- package/docs/reticle-manual.md +106 -0
- package/docs/skill-file.mdx +3 -3
- package/docs/telemetry-contract.md +108 -4
- package/docs/tools-act-sequence.mdx +16 -0
- package/docs/tools-tools-and-run.mdx +2 -4
- package/docs/troubleshooting.mdx +9 -0
- package/docs/usage.md +4 -3
- package/package.json +4 -3
- package/dist/init/cursor.d.ts +0 -24
- package/dist/init/cursor.js +0 -80
- package/dist/session/session-readiness.d.ts +0 -34
- package/dist/session/session-readiness.js +0 -36
package/dist/session/session.js
CHANGED
|
@@ -1,8 +1,10 @@
|
|
|
1
1
|
import { recordImpact } from '../impact/impact-recorder.js';
|
|
2
2
|
import { LastAct } from './last-act.js';
|
|
3
3
|
import { GapLedger } from '../honesty/gap-ledger.js';
|
|
4
|
+
import { CaptureLedger } from '../honesty/feature-capture.js';
|
|
4
5
|
import { commandTimeoutMessage } from './command-timeout.js';
|
|
5
6
|
import { readHealthEvent } from './session-health.js';
|
|
7
|
+
import { MIRRORED_COMMANDS, mirroredNarration } from './session-mirror.js';
|
|
6
8
|
/** The HUD does not need 200 frames to watch a counter climb; the last state always lands. */
|
|
7
9
|
const IMPACT_PUSH_DEBOUNCE_MS = 700;
|
|
8
10
|
import { PendingCommands, CommandTimeoutError } from './pending-commands.js';
|
|
@@ -51,6 +53,12 @@ const REBINDABLE_COMMANDS = new Set([
|
|
|
51
53
|
]);
|
|
52
54
|
/** Prefix on minted action ids (a1, a2, …) — the journal's action identity, independent of commands. */
|
|
53
55
|
const ACTION_ID_PREFIX = 'a';
|
|
56
|
+
/**
|
|
57
|
+
* How many consecutive unanswered commands make a tab unresponsive. One is a page that was merely
|
|
58
|
+
* busy for its budget; two in a row with no reply between them is a wedge, and the cost of being
|
|
59
|
+
* wrong about that is one extra browser tab.
|
|
60
|
+
*/
|
|
61
|
+
const UNRESPONSIVE_AFTER_TIMEOUTS = 2;
|
|
54
62
|
/** ws readyState for an OPEN socket — guard fire-and-forget pushes against a closing tab. */
|
|
55
63
|
const WS_OPEN = 1;
|
|
56
64
|
/**
|
|
@@ -61,6 +69,17 @@ export class Session {
|
|
|
61
69
|
id;
|
|
62
70
|
/** Stable build-stamped project identity; undefined for v1.0 SDKs that omit it. */
|
|
63
71
|
projectId;
|
|
72
|
+
/**
|
|
73
|
+
* The `.reticle` directory this session's evidence belongs in — impact counters AND capsules.
|
|
74
|
+
*
|
|
75
|
+
* Stamped once when the session is created, from the project it declared in HELLO, rather than
|
|
76
|
+
* resolved per call: the answer cannot change while the tab is connected, and resolving it once
|
|
77
|
+
* means every counter that fires for this session agrees about where it goes.
|
|
78
|
+
*
|
|
79
|
+
* Undefined when nothing could name a project — the caller then falls back to the daemon's own
|
|
80
|
+
* root, which is what every counter did unconditionally before this existed.
|
|
81
|
+
*/
|
|
82
|
+
artifactRoot;
|
|
64
83
|
url;
|
|
65
84
|
title;
|
|
66
85
|
adapters;
|
|
@@ -81,6 +100,8 @@ export class Session {
|
|
|
81
100
|
#listeners = new Set();
|
|
82
101
|
#disconnectListeners = new Set();
|
|
83
102
|
#actionSeq = 0;
|
|
103
|
+
/** Consecutive missed command budgets — free liveness evidence. Any reply resets it. */
|
|
104
|
+
#unansweredCommands = 0;
|
|
84
105
|
#lastSeenAt;
|
|
85
106
|
#hidden = false;
|
|
86
107
|
/** Which shell the page reported (PAGE_HEALTH). Undefined until the first report lands. */
|
|
@@ -107,6 +128,30 @@ export class Session {
|
|
|
107
128
|
#journalReader;
|
|
108
129
|
/** What this session has learned by watching its own stream: ambient churn + blind-spot levels. */
|
|
109
130
|
#observed = new ObservedState();
|
|
131
|
+
/**
|
|
132
|
+
* Which document is on screen right now — the one the most recent stamped event was observed under.
|
|
133
|
+
*
|
|
134
|
+
* DERIVED, never announced. The SDK mints a document id once per real document and stamps it on
|
|
135
|
+
* every event, so the stream already carries the answer; asking the page for it separately would be
|
|
136
|
+
* a second source of truth that can disagree with the evidence it is supposed to scope. A full
|
|
137
|
+
* navigation or a reload builds a new document, mints a new id, and the first event carrying it
|
|
138
|
+
* moves this forward — which is exactly the moment the previous document's evidence stops being
|
|
139
|
+
* about the world. An SPA route change keeps the same document and so keeps the same id, which is
|
|
140
|
+
* correct rather than a limitation: same JavaScript context, same in-flight requests, same evidence.
|
|
141
|
+
*
|
|
142
|
+
* An UNSTAMPED event never clears this. An SDK older than the field stamps nothing, and letting one
|
|
143
|
+
* such event blank the current document would make every later comparison vacuous.
|
|
144
|
+
*/
|
|
145
|
+
#documentId;
|
|
146
|
+
/**
|
|
147
|
+
* The edit epoch of the most recent stamped event. DERIVED for the same reason `#documentId` is:
|
|
148
|
+
* the stream already carries it, and asking the page separately would be a second source of truth.
|
|
149
|
+
*
|
|
150
|
+
* A hot update advances it INSIDE the same document, which is the case `#documentId` structurally
|
|
151
|
+
* cannot see — no navigation, same page, replaced code. An unstamped event never clears it: most
|
|
152
|
+
* pages have no hot-update channel at all, so absence is "unknown", never "back to no edits".
|
|
153
|
+
*/
|
|
154
|
+
#editEpoch;
|
|
110
155
|
constructor(hello, socket, clock) {
|
|
111
156
|
this.id = hello.sessionId;
|
|
112
157
|
this.projectId = hello.projectId;
|
|
@@ -179,6 +224,9 @@ export class Session {
|
|
|
179
224
|
hidden: this.#hidden,
|
|
180
225
|
throttled: base.throttled,
|
|
181
226
|
focused: base.focused,
|
|
227
|
+
// Without this the desktop branch is unreachable in production: every unit test would pass and
|
|
228
|
+
// every real Electron window would still be told to open a browser.
|
|
229
|
+
runtime: this.#runtime,
|
|
182
230
|
});
|
|
183
231
|
return recommendation === undefined ? base : { ...base, recommendation };
|
|
184
232
|
}
|
|
@@ -190,19 +238,42 @@ export class Session {
|
|
|
190
238
|
title: this.title,
|
|
191
239
|
adapters: this.adapters,
|
|
192
240
|
hasCapabilities: this.hasCapabilities,
|
|
241
|
+
runtime: this.#runtime,
|
|
193
242
|
versionSkew: this.versionSkew,
|
|
194
243
|
hidden: this.#hidden,
|
|
195
244
|
health: () => this.health(),
|
|
196
245
|
staleMs: () => this.staleMs(),
|
|
197
246
|
pendingMarkCount: () => this.#review.pendingCount(),
|
|
247
|
+
unresponsive: () => this.unresponsive(),
|
|
198
248
|
});
|
|
199
249
|
}
|
|
250
|
+
/**
|
|
251
|
+
* Attached but not answering. A tab can be `connected` with a fresh `lastSeenMs` and still answer
|
|
252
|
+
* nothing: `lastSeenMs` measures the events the SDK streams, not the commands it replies to. Reuse
|
|
253
|
+
* and auto-selection read that as health, so `reticle open` handed a wedged tab back forever and
|
|
254
|
+
* `reticle_session{action:"end"}` — a flag on the record, not on the page — could not help.
|
|
255
|
+
*/
|
|
256
|
+
unresponsive() {
|
|
257
|
+
return this.#unansweredCommands >= UNRESPONSIVE_AFTER_TIMEOUTS;
|
|
258
|
+
}
|
|
200
259
|
/** Wall-clock age of the session in milliseconds. */
|
|
201
260
|
staleMs() {
|
|
202
261
|
return this.#clock() - this.#startedAt;
|
|
203
262
|
}
|
|
263
|
+
/** The document the most recent stamped event was observed under. See `#documentId`. */
|
|
264
|
+
get currentDocumentId() {
|
|
265
|
+
return this.#documentId;
|
|
266
|
+
}
|
|
267
|
+
/** The edit epoch the most recent stamped event was observed under. See `#editEpoch`. */
|
|
268
|
+
get currentEditEpoch() {
|
|
269
|
+
return this.#editEpoch;
|
|
270
|
+
}
|
|
204
271
|
/** Re-stamp an incoming event with server-relative time, buffer it, and fan out. */
|
|
205
272
|
pushEvent(event, byteSize) {
|
|
273
|
+
if (event.documentId !== undefined)
|
|
274
|
+
this.#documentId = event.documentId;
|
|
275
|
+
if (event.editEpoch !== undefined)
|
|
276
|
+
this.#editEpoch = event.editEpoch;
|
|
206
277
|
if (event.type === EventType.PAGE_HEALTH) {
|
|
207
278
|
const r = readHealthEvent(event.data);
|
|
208
279
|
this.applyHealth(r.hidden ?? this.#hidden, r.focused ?? this.#focused, r.runtime, r.engine, r.brand);
|
|
@@ -227,7 +298,7 @@ export class Session {
|
|
|
227
298
|
this.#review.add(parsed.data, this.elapsed());
|
|
228
299
|
// The impact record's `marks` field existed and nothing ever wrote it: the report would
|
|
229
300
|
// have shown a permanent zero next to a page covered in pins.
|
|
230
|
-
recordImpact({ marks: 1 });
|
|
301
|
+
recordImpact({ marks: 1 }, {}, this.artifactRoot);
|
|
231
302
|
}
|
|
232
303
|
}
|
|
233
304
|
if (event.type === EventType.ROUTE_CHANGE) {
|
|
@@ -344,19 +415,50 @@ export class Session {
|
|
|
344
415
|
* action id. Ids are minted independently of command correlation ids so the journal is self-contained.
|
|
345
416
|
*/
|
|
346
417
|
beginAction(tool, args) {
|
|
347
|
-
this.#
|
|
348
|
-
const actionId = `${ACTION_ID_PREFIX}${String(this.#actionSeq)}`;
|
|
418
|
+
const actionId = this.#mintActionId();
|
|
349
419
|
// Held here, not only in the journal: with the journal off every event was unattributed, and
|
|
350
420
|
// pushEvent reads that as ambient churn the settle oracle then ignores. See action-attribution test.
|
|
351
421
|
this.#activeActionId = actionId;
|
|
352
422
|
this.#journal?.beginAction(actionId, tool, args);
|
|
353
423
|
return actionId;
|
|
354
424
|
}
|
|
425
|
+
/**
|
|
426
|
+
* Record one action WITHOUT opening an attribution window — for a tool that returns a verdict but
|
|
427
|
+
* drives nothing, so no event it observes was caused by it. See `JournalRecorder.recordAction`.
|
|
428
|
+
*/
|
|
429
|
+
recordAction(tool, args, effect) {
|
|
430
|
+
const actionId = this.#mintActionId();
|
|
431
|
+
this.#journal?.recordAction(actionId, tool, args, effect);
|
|
432
|
+
return actionId;
|
|
433
|
+
}
|
|
434
|
+
#mintActionId() {
|
|
435
|
+
this.#actionSeq += 1;
|
|
436
|
+
return `${ACTION_ID_PREFIX}${String(this.#actionSeq)}`;
|
|
437
|
+
}
|
|
438
|
+
/**
|
|
439
|
+
* How many actions this session has dispatched.
|
|
440
|
+
*
|
|
441
|
+
* The counter that mints journal action ids, not a second one — so it equals the journal's own
|
|
442
|
+
* length, and `reticle_context`'s `step`, whenever this session journals at all.
|
|
443
|
+
*/
|
|
444
|
+
get actionCount() {
|
|
445
|
+
return this.#actionSeq;
|
|
446
|
+
}
|
|
355
447
|
/** Close the active action window, persisting its action record with the settle outcome. */
|
|
356
448
|
finishAction(effect, settled, settledInMs) {
|
|
357
449
|
this.#activeActionId = undefined;
|
|
358
450
|
this.#journal?.finishAction(effect, settled, settledInMs);
|
|
359
451
|
}
|
|
452
|
+
/**
|
|
453
|
+
* The durable action ledger for this session — the ledger the run context is folded out of.
|
|
454
|
+
*
|
|
455
|
+
* `[]` when nothing journals this session (journaling disabled, or an id that is not a safe path
|
|
456
|
+
* segment). An absent ledger reads as an empty run, never as a missing one: the fold simply has
|
|
457
|
+
* nothing to say, which is the honest answer.
|
|
458
|
+
*/
|
|
459
|
+
async readJournalActions() {
|
|
460
|
+
return (await this.#journalReader?.readActions?.()) ?? [];
|
|
461
|
+
}
|
|
360
462
|
/** Flush any buffered journal events to disk (call on session end). */
|
|
361
463
|
async flushJournal() {
|
|
362
464
|
await this.#journal?.flush();
|
|
@@ -379,6 +481,11 @@ export class Session {
|
|
|
379
481
|
* end of it.
|
|
380
482
|
*/
|
|
381
483
|
gaps = new GapLedger();
|
|
484
|
+
/**
|
|
485
|
+
* The read-only calls the journal does not keep, so "was `reticle_context` ever called" has
|
|
486
|
+
* something to fold. See honesty/feature-capture.ts — it is the only state that instrument adds.
|
|
487
|
+
*/
|
|
488
|
+
capture = new CaptureLedger();
|
|
382
489
|
// ── Server-authoritative liveness (immune to browser-tab throttling) ──────────────
|
|
383
490
|
/**
|
|
384
491
|
* Stamp the wall-clock of the latest AGENT command (called whenever a tool resolves this session).
|
|
@@ -478,6 +585,8 @@ export class Session {
|
|
|
478
585
|
// the app taking its time — the split telemetry reports in aggregate, made visible per call.
|
|
479
586
|
return span('browser.command', { command: name, sessionId: this.id }, () => awaited)
|
|
480
587
|
.then((result) => {
|
|
588
|
+
// Answered — whatever the reply said, the command channel is alive.
|
|
589
|
+
this.#unansweredCommands = 0;
|
|
481
590
|
// The label is only knowable from the REPLY — the request carries a ref, and a ref dies with
|
|
482
591
|
// the next re-render. Recorded here so coverage survives frameworks that replace nodes.
|
|
483
592
|
if (name === ReticleCommand.ACT)
|
|
@@ -493,6 +602,8 @@ export class Session {
|
|
|
493
602
|
// simply not been answered in budget was read as "you were replaced, ask again" — and
|
|
494
603
|
// against a page re-dialling in a loop that turned one read into hundreds of commands on the
|
|
495
604
|
// wire, minutes of wall clock, and an answer still quoting the budget it had blown.
|
|
605
|
+
if (error instanceof CommandTimeoutError)
|
|
606
|
+
this.#unansweredCommands += 1;
|
|
496
607
|
const next = error instanceof CommandTimeoutError ? undefined : this.#liveSuccessor();
|
|
497
608
|
if (next === undefined || !REBINDABLE_COMMANDS.has(name))
|
|
498
609
|
throw error;
|
|
@@ -507,11 +618,14 @@ export class Session {
|
|
|
507
618
|
});
|
|
508
619
|
}
|
|
509
620
|
handleResult(result) {
|
|
621
|
+
// Any reply at all clears the wedge, including one for a command that already timed out: it is
|
|
622
|
+
// still proof that bridge→page→bridge works right now, which is the only thing being claimed.
|
|
623
|
+
this.#unansweredCommands = 0;
|
|
510
624
|
this.#pending.settle(result);
|
|
511
625
|
}
|
|
512
626
|
/** Reject everything still in flight — used on disconnect. */
|
|
513
|
-
rejectAll(reason) {
|
|
514
|
-
this.#pending.rejectAll(reason);
|
|
627
|
+
rejectAll(reason, replaced = false) {
|
|
628
|
+
this.#pending.rejectAll(reason, replaced);
|
|
515
629
|
for (const listener of this.#disconnectListeners)
|
|
516
630
|
listener();
|
|
517
631
|
this.#disconnectListeners.clear();
|
|
@@ -558,11 +672,11 @@ export class Session {
|
|
|
558
672
|
return undefined;
|
|
559
673
|
}
|
|
560
674
|
/** End this transport without letting a stale socket remove its replacement session. */
|
|
561
|
-
disconnect(reason) {
|
|
675
|
+
disconnect(reason, replaced = false) {
|
|
562
676
|
// "Longest run" means the longest SESSION, and it used to be fed a single tool call's duration
|
|
563
677
|
// - so the report's superlative was a number in milliseconds that never grew past a click.
|
|
564
|
-
recordImpact({}, { runMs: this.elapsed() });
|
|
565
|
-
this.rejectAll(reason);
|
|
678
|
+
recordImpact({}, { runMs: this.elapsed() }, this.artifactRoot);
|
|
679
|
+
this.rejectAll(reason, replaced);
|
|
566
680
|
try {
|
|
567
681
|
this.#socket.close(1008, reason);
|
|
568
682
|
}
|
|
@@ -691,8 +805,47 @@ export class Session {
|
|
|
691
805
|
const minutes = Math.floor(ageMs / 60_000);
|
|
692
806
|
return `Session ${this.id} has been open for ${String(minutes)} minutes. If your task is complete, call reticle_session{action:"end"} now.`;
|
|
693
807
|
}
|
|
694
|
-
/**
|
|
808
|
+
/**
|
|
809
|
+
* The tabs that should SEE what this session is told, supplied by the SessionManager.
|
|
810
|
+
*
|
|
811
|
+
* `reticle drive` attaches to the running daemon and is handed a pooled HEADLESS context, so the
|
|
812
|
+
* whole HUD feed — the narration, the counters, the bug that was just raised — went to a browser
|
|
813
|
+
* with nobody in front of it, while the developer's own tab showed nothing. The feed is now a
|
|
814
|
+
* per-project broadcast: the driven tab is still the only one DRIVEN, and any other tab of the
|
|
815
|
+
* same app is a viewer.
|
|
816
|
+
*/
|
|
817
|
+
#viewers;
|
|
818
|
+
/** Wired by SessionManager.add, the one place every session registers. */
|
|
819
|
+
setViewers(read) {
|
|
820
|
+
this.#viewers = read;
|
|
821
|
+
}
|
|
822
|
+
/**
|
|
823
|
+
* Fire-and-forget command send — NOT registered in #pending (no correlated result expected).
|
|
824
|
+
*
|
|
825
|
+
* Mirrored to this project's other tabs, for the two commands that are a REPORT of what happened
|
|
826
|
+
* (narration, impact). PRESENTER is deliberately not among them: it is the glow and the lifecycle
|
|
827
|
+
* that say "the agent is driving THIS tab", and a viewer that showed it would be claiming
|
|
828
|
+
* something untrue about itself.
|
|
829
|
+
*/
|
|
695
830
|
#post(name, args) {
|
|
831
|
+
this.#send(name, args);
|
|
832
|
+
if (!MIRRORED_COMMANDS.has(name))
|
|
833
|
+
return;
|
|
834
|
+
for (const viewer of this.#viewers?.() ?? []) {
|
|
835
|
+
if (viewer === this)
|
|
836
|
+
continue;
|
|
837
|
+
// Straight to the raw send, so a mirrored row is never mirrored again.
|
|
838
|
+
viewer.#send(name, name === ReticleCommand.NARRATE ? this.#labelled(args) : args);
|
|
839
|
+
}
|
|
840
|
+
}
|
|
841
|
+
/** A narration row re-addressed to a tab that is watching rather than being driven. */
|
|
842
|
+
#labelled(args) {
|
|
843
|
+
const text = args['text'];
|
|
844
|
+
if ('string' !== typeof text)
|
|
845
|
+
return args;
|
|
846
|
+
return { ...args, text: mirroredNarration(this.id, text) };
|
|
847
|
+
}
|
|
848
|
+
#send(name, args) {
|
|
696
849
|
if (this.#socket.readyState !== WS_OPEN)
|
|
697
850
|
return;
|
|
698
851
|
// Shares the same counter as tracked commands, so a fire-and-forget id can never collide with
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The real clock, named once.
|
|
3
|
+
*
|
|
4
|
+
* The logic that needs a clock takes one as an argument so a test can drive it without waiting
|
|
5
|
+
* (CLAUDE.md rule 7). That leaves the production callers each constructing the same pair of
|
|
6
|
+
* closures, which is how two of them end up with different sleep implementations. One export, one
|
|
7
|
+
* place to look.
|
|
8
|
+
*/
|
|
9
|
+
export declare const WALL_CLOCK: {
|
|
10
|
+
now: () => number;
|
|
11
|
+
sleep: (ms: number) => Promise<void>;
|
|
12
|
+
};
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The real clock, named once.
|
|
3
|
+
*
|
|
4
|
+
* The logic that needs a clock takes one as an argument so a test can drive it without waiting
|
|
5
|
+
* (CLAUDE.md rule 7). That leaves the production callers each constructing the same pair of
|
|
6
|
+
* closures, which is how two of them end up with different sleep implementations. One export, one
|
|
7
|
+
* place to look.
|
|
8
|
+
*/
|
|
9
|
+
export const WALL_CLOCK = {
|
|
10
|
+
now: () => Date.now(),
|
|
11
|
+
sleep: (ms) => new Promise((resolve) => {
|
|
12
|
+
setTimeout(resolve, ms).unref?.();
|
|
13
|
+
}),
|
|
14
|
+
};
|
|
@@ -0,0 +1,96 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The coding agents `init`'s own MCP registration does not reach, and where their config lives.
|
|
3
|
+
*
|
|
4
|
+
* `init` covers eight clients and only where it already finds them. That leaves real holes: VS
|
|
5
|
+
* Code's USER-scope mcp.json exists on machines today and init only ever writes the project-scope
|
|
6
|
+
* one, so a VS Code user has no tools outside the directory they ran init in. Zed, Warp, Kiro, Amp,
|
|
7
|
+
* Copilot CLI, Amazon Q, Factory Droid, Cline and Roo are not covered at all.
|
|
8
|
+
*
|
|
9
|
+
* Three rules, and the second is what keeps this honest:
|
|
10
|
+
*
|
|
11
|
+
* 1. A path with OFFICIAL documentation is written even when the agent is absent, so a later
|
|
12
|
+
* install finds itself already wired.
|
|
13
|
+
* 2. A path we cannot evidence is REFUSED. Cline's and Roo's live under VS Code globalStorage,
|
|
14
|
+
* which moves under Insiders, portable installs and a custom --user-data-dir; they are written
|
|
15
|
+
* only where the host's standard layout is present. A config file at a guessed location is one
|
|
16
|
+
* nobody reads, which is indistinguishable from success.
|
|
17
|
+
* 3. A format we cannot merge safely is never rewritten. TOML, an existing YAML, JSONC carrying
|
|
18
|
+
* comments: we print the snippet instead. Reformatting somebody's config to add one entry is
|
|
19
|
+
* not ours to do.
|
|
20
|
+
*/
|
|
21
|
+
export declare const AgentConfidence: {
|
|
22
|
+
/** Documented by the vendor. Safe to create before the agent exists. */
|
|
23
|
+
readonly OFFICIAL: "official";
|
|
24
|
+
/** Community-sourced. Only written where the host's own layout proves the path. */
|
|
25
|
+
readonly COMMUNITY: "community";
|
|
26
|
+
};
|
|
27
|
+
export type AgentConfidence = (typeof AgentConfidence)[keyof typeof AgentConfidence];
|
|
28
|
+
export declare const AgentAction: {
|
|
29
|
+
readonly CREATE: "create";
|
|
30
|
+
readonly CREATE_YAML: "create-yaml";
|
|
31
|
+
readonly MERGE: "merge";
|
|
32
|
+
readonly ALREADY: "already";
|
|
33
|
+
readonly MANUAL: "manual";
|
|
34
|
+
readonly SKIP: "skip";
|
|
35
|
+
};
|
|
36
|
+
export type AgentAction = (typeof AgentAction)[keyof typeof AgentAction];
|
|
37
|
+
/** Per-platform relative paths, from the user's home directory. */
|
|
38
|
+
export interface PlatformPaths {
|
|
39
|
+
readonly darwin: string;
|
|
40
|
+
readonly linux: string;
|
|
41
|
+
readonly win32: string;
|
|
42
|
+
}
|
|
43
|
+
export interface AgentClient {
|
|
44
|
+
readonly id: string;
|
|
45
|
+
readonly name: string;
|
|
46
|
+
readonly confidence: AgentConfidence;
|
|
47
|
+
/** `json` merges; `yaml-manual` is only ever created fresh, never edited. */
|
|
48
|
+
readonly format: 'json' | 'yaml-manual';
|
|
49
|
+
/** Where the server map lives. Getting this wrong writes a file the client silently ignores. */
|
|
50
|
+
readonly key: string;
|
|
51
|
+
readonly entry?: Readonly<Record<string, unknown>> | undefined;
|
|
52
|
+
readonly paths: PlatformPaths;
|
|
53
|
+
/** Existence proves the agent is installed. */
|
|
54
|
+
readonly marker: PlatformPaths;
|
|
55
|
+
/** The HOST's directory, when the marker belongs to an extension rather than the app. */
|
|
56
|
+
readonly parentMarker?: PlatformPaths | undefined;
|
|
57
|
+
/** Where this agent loads reusable skills from, when it has such a place. */
|
|
58
|
+
readonly skillDir?: string | undefined;
|
|
59
|
+
}
|
|
60
|
+
export declare const AGENT_CLIENTS: readonly AgentClient[];
|
|
61
|
+
/** What to do for one client, decided without touching the disk. */
|
|
62
|
+
export interface AgentPlanStep {
|
|
63
|
+
readonly id: string;
|
|
64
|
+
readonly name: string;
|
|
65
|
+
readonly file: string;
|
|
66
|
+
readonly action: AgentAction;
|
|
67
|
+
readonly key?: string | undefined;
|
|
68
|
+
readonly entry?: Readonly<Record<string, unknown>> | undefined;
|
|
69
|
+
readonly why: string;
|
|
70
|
+
}
|
|
71
|
+
export interface AgentPlanInput {
|
|
72
|
+
readonly home: string;
|
|
73
|
+
readonly platform: keyof PlatformPaths;
|
|
74
|
+
readonly exists: (path: string) => boolean;
|
|
75
|
+
readonly readFile: (path: string) => string;
|
|
76
|
+
}
|
|
77
|
+
/**
|
|
78
|
+
* Join for the platform the CALLER named, never the one this process happens to run on.
|
|
79
|
+
*
|
|
80
|
+
* Every planner here takes `platform` as an argument and claims to be pure over it — the doc below
|
|
81
|
+
* says the Windows rows are "testable from any machine". `node:path`'s bare `join` broke that claim
|
|
82
|
+
* silently in both directions: a mac planning win32 rows emitted `/` separators into paths Windows
|
|
83
|
+
* cannot use, and a Windows host planning linux rows emitted `\`. The second half is what turned
|
|
84
|
+
* the whole Windows CI job red — the pure planners returned `\home\u\.claude\settings.json`,
|
|
85
|
+
* every injected filesystem is keyed by the POSIX path the caller asked for, so every lookup missed
|
|
86
|
+
* and every row came back `absent`/`skip`. Twenty-eight tests failed for a reason that had nothing
|
|
87
|
+
* to do with what they were testing, which left the platform with the most users unwatched.
|
|
88
|
+
*
|
|
89
|
+
* A separator is part of the answer, so it belongs to the platform being planned for.
|
|
90
|
+
*/
|
|
91
|
+
export declare const joinFor: (os: keyof PlatformPaths) => ((...parts: string[]) => string);
|
|
92
|
+
/**
|
|
93
|
+
* Decide what to do for every client. Pure: the filesystem arrives as two functions, which is what
|
|
94
|
+
* makes the Windows rows testable from any machine.
|
|
95
|
+
*/
|
|
96
|
+
export declare function planAgentConfigs(input: AgentPlanInput): AgentPlanStep[];
|