@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
|
@@ -70,6 +70,45 @@ export const TOOL_SURFACE = {
|
|
|
70
70
|
* supplies the evidence the surface would otherwise have to go and find.
|
|
71
71
|
*/
|
|
72
72
|
VERIFY: 'verify',
|
|
73
|
+
/**
|
|
74
|
+
* EXPERIMENTAL, opt-in, and UNDER MEASUREMENT. Not a recommendation, and not on a path to becoming
|
|
75
|
+
* the default until it has a number of its own.
|
|
76
|
+
*
|
|
77
|
+
* It exists because of the finding recorded on VERIFY above, read forwards instead of backwards.
|
|
78
|
+
* That surface cut the bill 37% and TRIPLED false alarms, and the five new false alarms were not
|
|
79
|
+
* scattered: every one of them was a defect whose evidence lives in `reticle_state`,
|
|
80
|
+
* `reticle_network` or `reticle_observe`. So the token saving and the accuracy loss came from two
|
|
81
|
+
* different cuts, and only one of them has to be paid for. `lean` keeps every observation tool and
|
|
82
|
+
* cuts the rest.
|
|
83
|
+
*
|
|
84
|
+
* What stays, and why each one is not a candidate for removal:
|
|
85
|
+
* SNAPSHOT / QUERY look. Without them the agent cannot name an element it did not already know.
|
|
86
|
+
* STATE / NETWORK / CONSOLE / OBSERVE the four evidence tools. Dropping these is the MEASURED
|
|
87
|
+
* cause of the tripled false-alarm rate. They are the point of the profile.
|
|
88
|
+
* ACT_AND_WAIT the only tool that acts AND returns a verdict. Omitting `until` makes it
|
|
89
|
+
* act-then-settle, which is what `reticle_act` does, so `act` is redundant here.
|
|
90
|
+
* ASSERT the only way to get a verdict WITHOUT acting. `act_and_wait` requires an
|
|
91
|
+
* `action`, so this is a capability it genuinely cannot express, not a synonym.
|
|
92
|
+
*
|
|
93
|
+
* What goes, and what it costs (one `reticle_run` hop each — `unadvertisedToolHelp` hands the agent
|
|
94
|
+
* the exact call, so a dropped name never comes back as "not found"):
|
|
95
|
+
* ACT subsumed: `act_and_wait` with `until` omitted is act-then-settle.
|
|
96
|
+
* WAIT_FOR subsumed: `act_and_wait { until }` takes the same PredicateSchema.
|
|
97
|
+
* ACT_SEQUENCE batching is a cost optimisation on top of a surface built to be cheap.
|
|
98
|
+
* NAVIGATE once per run, not once per turn — the wrong thing to pay for every turn.
|
|
99
|
+
* SESSIONS the CLI answers this (`reticle status`) without spending any turn budget.
|
|
100
|
+
* INSPECT fix-side, not verdict-side: it is called once a bug is FOUND, so its hop is
|
|
101
|
+
* paid once per finding rather than once per turn. Nothing else maps a node to
|
|
102
|
+
* a source file, which is why it is a hop and not a deletion.
|
|
103
|
+
* SESSION the lease block and the pause hint name it in prose, which is what made it
|
|
104
|
+
* load-bearing on the default surface. Under a trimmed surface the
|
|
105
|
+
* unadvertised-tool help turns that into a working `reticle_run` call.
|
|
106
|
+
* FEEDBACK the one drop with a KNOWN CEILING: an unadvertised feedback channel collects
|
|
107
|
+
* little to nothing, so a long-lived profile must not ship without it. Acceptable
|
|
108
|
+
* only because this profile is opt-in and short-lived by construction; if it
|
|
109
|
+
* ever stops being an experiment, feedback comes back first.
|
|
110
|
+
*/
|
|
111
|
+
LEAN: 'lean',
|
|
73
112
|
};
|
|
74
113
|
/**
|
|
75
114
|
* The switch that turns on the full, output-schema-carrying surface. A boolean, not a menu.
|
|
@@ -79,7 +118,7 @@ export const TOOL_SURFACE = {
|
|
|
79
118
|
*/
|
|
80
119
|
export const ADVERTISE_ALL_ENV = 'RETICLE_ADVERTISE_ALL_TOOLS';
|
|
81
120
|
/** Opt into the smallest verdict-capable surface. Read by the DAEMON at startup, like the others. */
|
|
82
|
-
|
|
121
|
+
const VERIFY_SURFACE_ENV = 'RETICLE_VERIFY_SURFACE';
|
|
83
122
|
/**
|
|
84
123
|
* The retired setting, still read so nobody's shell profile breaks.
|
|
85
124
|
*
|
|
@@ -185,6 +224,17 @@ export const CORE_TOOL_NAMES = new Set([
|
|
|
185
224
|
* 48 by itself can push a user's other servers out or be dropped wholesale. The budget is a count,
|
|
186
225
|
* so no amount of trimming parameter prose buys anything back — only advertising fewer names does.
|
|
187
226
|
*
|
|
227
|
+
* That is true of the COUNT cap and false of everything else, which is worth separating here before
|
|
228
|
+
* somebody reads it as "prose is free". Measured against two competitor MCP servers on the same
|
|
229
|
+
* agent loop: this server advertises the FEWEST tools of the three and ships the HEAVIEST schema
|
|
230
|
+
* block, and 83% of that weight is parameter descriptions, not tool descriptions. The block is
|
|
231
|
+
* re-sent every turn, so it is multiplied by turn count before one byte of evidence is counted, and
|
|
232
|
+
* it was most of the gap in that run.
|
|
233
|
+
*
|
|
234
|
+
* Which does NOT license trimming by eye. Those descriptions are what make a tool get called
|
|
235
|
+
* correctly, and one malformed call costs a whole extra turn — more than the bytes saved. The
|
|
236
|
+
* outcome to measure is turn count and error rate, not size.
|
|
237
|
+
*
|
|
188
238
|
* Everything omitted stays in the registry, stays catalogued by `reticle_tools`, and stays callable
|
|
189
239
|
* by name through `reticle_run { tool, args }`. The cost is one discovery hop on the cold tail, which
|
|
190
240
|
* is the same trade the default surface has always made, applied one level further out.
|
|
@@ -206,6 +256,13 @@ export const EXTENDED_TOOL_NAMES = new Set([
|
|
|
206
256
|
ReticleTool.CAPABILITIES,
|
|
207
257
|
ReticleTool.FLOW_SAVE,
|
|
208
258
|
ReticleTool.FLOW_REPLAY,
|
|
259
|
+
// New and unproven, so it does not take a default-surface slot under the cap. Same terms the
|
|
260
|
+
// capabilities demotion set: reachable in one reticle_run hop by any agent that wants it.
|
|
261
|
+
ReticleTool.INTENT,
|
|
262
|
+
// Same terms again, plus one argument specific to it: its caller is BY CONSTRUCTION an agent that
|
|
263
|
+
// just lost its context and is re-reading the tool list, so the discovery hop it costs is a call
|
|
264
|
+
// that caller was already going to make. See context-tools.ts for the full argument.
|
|
265
|
+
ReticleTool.CONTEXT,
|
|
209
266
|
ReticleTool.RECORD,
|
|
210
267
|
ReticleTool.SCREENSHOT,
|
|
211
268
|
ReticleTool.VISUAL_DIFF,
|
|
@@ -220,7 +277,53 @@ export const EXTENDED_TOOL_NAMES = new Set([
|
|
|
220
277
|
* everything else. `act_and_wait` can resolve its own target, so no query tool is needed to name an
|
|
221
278
|
* element — that round trip was half the token cost of a verification.
|
|
222
279
|
*/
|
|
223
|
-
|
|
280
|
+
const VERIFY_TOOL_NAMES = new Set([ReticleTool.ACT_AND_WAIT]);
|
|
281
|
+
/**
|
|
282
|
+
* The lean surface: look, observe, act-with-a-verdict, assert. Pinned by lean-surface.test.ts,
|
|
283
|
+
* because an experiment whose independent variable drifts mid-flight measures nothing. Every
|
|
284
|
+
* inclusion and every exclusion is argued at TOOL_SURFACE.LEAN.
|
|
285
|
+
*
|
|
286
|
+
* ## MEASURED: it is cheaper and less correct. Do not promote it to the default.
|
|
287
|
+
*
|
|
288
|
+
* Run as its own arm of the fix-and-verify benchmark — same five bugs, same model, same budget, the
|
|
289
|
+
* full surface as its control:
|
|
290
|
+
*
|
|
291
|
+
* | | full surface | lean |
|
|
292
|
+
* |---|---|---|
|
|
293
|
+
* | bugs fixed | **5/5** | **3/5** |
|
|
294
|
+
* | FALSE GREENS | **0** | **1** |
|
|
295
|
+
*
|
|
296
|
+
* The false green is the finding, and it is the first this benchmark has ever produced. On
|
|
297
|
+
* `broken-form-validation` the lean agent finished in SIX turns and 62k tokens — the cheapest cell
|
|
298
|
+
* of the whole run, a fifth of what the full surface spent — edited the file, took one snapshot,
|
|
299
|
+
* and ended with a hypothetical walkthrough: "Enter spaces + valid name -> spaces are trimmed,
|
|
300
|
+
* valid part is used. VERDICT: FIXED". The submit button was still enabled for a whitespace-only
|
|
301
|
+
* service. It reasoned about what its own code would now do instead of driving it, which is exactly
|
|
302
|
+
* the failure this product exists to catch, produced by our own surface.
|
|
303
|
+
*
|
|
304
|
+
* The other loss has the same root from the other side. On `cross-component-regression` the agent
|
|
305
|
+
* called `reticle_tools` three times and `reticle_run` eight, saying "since Reticle isn't
|
|
306
|
+
* connecting, let me see what reticle_tools offers" — it spent the run hunting for capabilities
|
|
307
|
+
* this surface does not advertise instead of using them, and never fixed the bug.
|
|
308
|
+
*
|
|
309
|
+
* That is the same result the `verify` surface already recorded — dropping the observation tools
|
|
310
|
+
* TRIPLED false alarms — arriving from the other direction: strip the surface and the agent stops
|
|
311
|
+
* verifying, then claims anyway. The known ceiling written here was that `reticle_feedback` goes
|
|
312
|
+
* uncollected. This is a bigger one and it was not predicted.
|
|
313
|
+
*
|
|
314
|
+
* It stays opt-in and it stays measured. The one thing it genuinely bought — the ceiling-bound cell
|
|
315
|
+
* halved, 30 turns to 14 — is not worth a verdict that lies, because the product is the verdict.
|
|
316
|
+
*/
|
|
317
|
+
export const LEAN_TOOL_NAMES = new Set([
|
|
318
|
+
ReticleTool.SNAPSHOT,
|
|
319
|
+
ReticleTool.QUERY,
|
|
320
|
+
ReticleTool.ACT_AND_WAIT,
|
|
321
|
+
ReticleTool.ASSERT,
|
|
322
|
+
ReticleTool.OBSERVE,
|
|
323
|
+
ReticleTool.NETWORK,
|
|
324
|
+
ReticleTool.CONSOLE,
|
|
325
|
+
ReticleTool.STATE,
|
|
326
|
+
]);
|
|
224
327
|
/** Is the truthy form of a boolean env var set? `1`, `true`, `yes` — anything else is off. */
|
|
225
328
|
function envFlagOn(raw) {
|
|
226
329
|
if (raw === undefined)
|
|
@@ -235,6 +338,8 @@ function envFlagOn(raw) {
|
|
|
235
338
|
* switch decides, and the retired setting is honoured last so an old shell profile still works.
|
|
236
339
|
*/
|
|
237
340
|
export function resolveToolSurface(explicit) {
|
|
341
|
+
if (explicit === TOOL_SURFACE.LEAN)
|
|
342
|
+
return TOOL_SURFACE.LEAN;
|
|
238
343
|
if (explicit === TOOL_SURFACE.VERIFY)
|
|
239
344
|
return TOOL_SURFACE.VERIFY;
|
|
240
345
|
if (explicit === TOOL_SURFACE.ALL)
|
|
@@ -244,6 +349,11 @@ export function resolveToolSurface(explicit) {
|
|
|
244
349
|
const retiredExplicit = explicit === undefined ? undefined : RETIRED_PROFILE_VALUES[explicit];
|
|
245
350
|
if (retiredExplicit !== undefined)
|
|
246
351
|
return retiredExplicit;
|
|
352
|
+
// The one LIVE value of the otherwise-retired setting. It rides there rather than on a switch of
|
|
353
|
+
// its own because the experiment is an A/B between two surfaces, and a boolean cannot name an arm.
|
|
354
|
+
if (TOOL_SURFACE.LEAN === process.env[TOOL_PROFILE_ENV]?.trim().toLowerCase()) {
|
|
355
|
+
return TOOL_SURFACE.LEAN;
|
|
356
|
+
}
|
|
247
357
|
if (envFlagOn(process.env[VERIFY_SURFACE_ENV]))
|
|
248
358
|
return TOOL_SURFACE.VERIFY;
|
|
249
359
|
if (envFlagOn(process.env[ADVERTISE_ALL_ENV]))
|
|
@@ -262,6 +372,14 @@ export function resolveToolSurface(explicit) {
|
|
|
262
372
|
*/
|
|
263
373
|
export function describeToolSurface(active, requested) {
|
|
264
374
|
const retired = requested ?? process.env[TOOL_PROFILE_ENV];
|
|
375
|
+
// `lean` is the one value of this setting that is NOT retired. Reporting it as retired would tell
|
|
376
|
+
// an agent its arm did not take, which on an A/B is worse than saying nothing.
|
|
377
|
+
if (TOOL_SURFACE.LEAN === active) {
|
|
378
|
+
return {
|
|
379
|
+
active,
|
|
380
|
+
source: `${TOOL_PROFILE_ENV}=${TOOL_SURFACE.LEAN} — an EXPERIMENTAL surface under measurement; unadvertised tools stay callable via ${ReticleTool.RUN}`,
|
|
381
|
+
};
|
|
382
|
+
}
|
|
265
383
|
if (retired !== undefined && retired in RETIRED_PROFILE_VALUES) {
|
|
266
384
|
return {
|
|
267
385
|
active,
|
|
@@ -293,6 +411,8 @@ export function filterTools(tools, surface) {
|
|
|
293
411
|
// interesting thing about the `core` PROFILE, whose only distinction was a second name for this.
|
|
294
412
|
if (surface === TOOL_SURFACE.VERIFY)
|
|
295
413
|
return tools.filter((t) => VERIFY_TOOL_NAMES.has(t.name));
|
|
414
|
+
if (surface === TOOL_SURFACE.LEAN)
|
|
415
|
+
return tools.filter((t) => LEAN_TOOL_NAMES.has(t.name));
|
|
296
416
|
if (surface === TOOL_SURFACE.DEFAULT)
|
|
297
417
|
return tools.filter((t) => CORE_TOOL_NAMES.has(t.name));
|
|
298
418
|
// `all` is the extended surface, not the whole registry — the cap is a hard budget shared with
|
|
@@ -8,6 +8,25 @@ export declare function parseInteractive(tree: string): InteractiveItem[];
|
|
|
8
8
|
export declare function asString(value: unknown): string | undefined;
|
|
9
9
|
export declare function asNumber(value: unknown): number | undefined;
|
|
10
10
|
export declare function asRecord(value: unknown): Record<string, unknown>;
|
|
11
|
+
/**
|
|
12
|
+
* The session this call is aimed at: a top-level `sessionId`, or the same key on sequence steps.
|
|
13
|
+
*
|
|
14
|
+
* `reticle_act_sequence` describes each step as equivalent to one `reticle_act`, so an agent that
|
|
15
|
+
* learned the escape hatch on the single-action tool puts `sessionId` on the step. Reading only the
|
|
16
|
+
* top-level key then auto-selects a different tab, the step refs miss, and the refusal reads as a
|
|
17
|
+
* stale ref — a confident diagnosis of the wrong thing. Top-level still wins when both are given.
|
|
18
|
+
*
|
|
19
|
+
* Mixed step ids refuse rather than pick: two named tabs is a guess we will not make.
|
|
20
|
+
*/
|
|
21
|
+
export declare function sessionIdFromArgs(args: Record<string, unknown>): string | undefined;
|
|
22
|
+
/**
|
|
23
|
+
* The ref this call is about to spend: a top-level `ref`, or the first sequence step's.
|
|
24
|
+
*
|
|
25
|
+
* Wrong-tab refusal keys off this. A sequence that only carries refs inside `steps` used to look
|
|
26
|
+
* like a call with no ref, so auto-selection could pick a different tab and the miss was blamed
|
|
27
|
+
* on the DOM.
|
|
28
|
+
*/
|
|
29
|
+
export declare function spentRefFromArgs(args: Record<string, unknown>): string | undefined;
|
|
11
30
|
/**
|
|
12
31
|
* A `{ file, line }` source location off an untrusted result payload, or undefined.
|
|
13
32
|
*
|
|
@@ -19,6 +19,52 @@ export function asNumber(value) {
|
|
|
19
19
|
export function asRecord(value) {
|
|
20
20
|
return 'object' === typeof value && value !== null ? value : {};
|
|
21
21
|
}
|
|
22
|
+
/**
|
|
23
|
+
* The session this call is aimed at: a top-level `sessionId`, or the same key on sequence steps.
|
|
24
|
+
*
|
|
25
|
+
* `reticle_act_sequence` describes each step as equivalent to one `reticle_act`, so an agent that
|
|
26
|
+
* learned the escape hatch on the single-action tool puts `sessionId` on the step. Reading only the
|
|
27
|
+
* top-level key then auto-selects a different tab, the step refs miss, and the refusal reads as a
|
|
28
|
+
* stale ref — a confident diagnosis of the wrong thing. Top-level still wins when both are given.
|
|
29
|
+
*
|
|
30
|
+
* Mixed step ids refuse rather than pick: two named tabs is a guess we will not make.
|
|
31
|
+
*/
|
|
32
|
+
export function sessionIdFromArgs(args) {
|
|
33
|
+
const top = asString(args['sessionId']);
|
|
34
|
+
if (top !== undefined)
|
|
35
|
+
return top;
|
|
36
|
+
const steps = args['steps'];
|
|
37
|
+
if (!Array.isArray(steps))
|
|
38
|
+
return undefined;
|
|
39
|
+
let found;
|
|
40
|
+
for (const raw of steps) {
|
|
41
|
+
const id = asString(asRecord(raw)['sessionId']);
|
|
42
|
+
if (id === undefined)
|
|
43
|
+
continue;
|
|
44
|
+
if (found !== undefined && found !== id) {
|
|
45
|
+
throw new Error(`reticle_act_sequence steps name different sessionIds ('${found}' and '${id}'). ` +
|
|
46
|
+
'Pass one sessionId at the top level to target a tab. Nothing was acted on.');
|
|
47
|
+
}
|
|
48
|
+
found = id;
|
|
49
|
+
}
|
|
50
|
+
return found;
|
|
51
|
+
}
|
|
52
|
+
/**
|
|
53
|
+
* The ref this call is about to spend: a top-level `ref`, or the first sequence step's.
|
|
54
|
+
*
|
|
55
|
+
* Wrong-tab refusal keys off this. A sequence that only carries refs inside `steps` used to look
|
|
56
|
+
* like a call with no ref, so auto-selection could pick a different tab and the miss was blamed
|
|
57
|
+
* on the DOM.
|
|
58
|
+
*/
|
|
59
|
+
export function spentRefFromArgs(args) {
|
|
60
|
+
const top = asString(args['ref']);
|
|
61
|
+
if (top !== undefined)
|
|
62
|
+
return top;
|
|
63
|
+
const steps = args['steps'];
|
|
64
|
+
if (!Array.isArray(steps) || 0 === steps.length)
|
|
65
|
+
return undefined;
|
|
66
|
+
return asString(asRecord(steps[0])['ref']);
|
|
67
|
+
}
|
|
22
68
|
/**
|
|
23
69
|
* A `{ file, line }` source location off an untrusted result payload, or undefined.
|
|
24
70
|
*
|
package/dist/tools/tools.d.ts
CHANGED
|
@@ -1,6 +1,8 @@
|
|
|
1
1
|
import { type ToolDef } from './tool-kit.js';
|
|
2
2
|
import { type MergePlan } from './merge-tools.js';
|
|
3
3
|
export type { ToolDef, ToolDeps } from './tool-kit.js';
|
|
4
|
+
/** Every handler, including tools retired from the advertised MCP surface. */
|
|
5
|
+
export declare const RAW_TOOLS: ToolDef[];
|
|
4
6
|
/**
|
|
5
7
|
* surface consolidation. Tool defs are re-sent EVERY turn, so the advertised count is a per-turn
|
|
6
8
|
* tax multiplied by loop length. Sibling families collapse into one action-dispatched tool; the member
|
package/dist/tools/tools.js
CHANGED
|
@@ -3,7 +3,8 @@ import { NoSessionAction, QueryBy, ReticleCommand, SnapshotMode } from '@reticle
|
|
|
3
3
|
import { ReticleTool } from './tool-names.js';
|
|
4
4
|
import { withSizeCost } from '../session/output-budget.js';
|
|
5
5
|
import { applySnapshotDelta, SnapshotCache } from './snapshot-delta.js';
|
|
6
|
-
import { asString, asNumber } from './tools-helpers.js';
|
|
6
|
+
import { asRecord, asString, asNumber } from './tools-helpers.js';
|
|
7
|
+
import { countSchema } from './numeric-bounds.js';
|
|
7
8
|
import { normalizeQueryArgs } from './query-shape.js';
|
|
8
9
|
import { paginateQueryResult } from './query-paginate.js';
|
|
9
10
|
/**
|
|
@@ -21,11 +22,14 @@ import { CONTRACT_TOOLS } from './contract-tools.js';
|
|
|
21
22
|
import { DOMAIN_TOOLS } from '../domain/domain-tools.js';
|
|
22
23
|
import { BROWSER_TOOLS } from './browser-tools.js';
|
|
23
24
|
import { FLOW_TOOLS } from '../flows/flow-tools.js';
|
|
25
|
+
import { INTENT_TOOLS } from '../intent/intent-tools.js';
|
|
26
|
+
import { CONTEXT_TOOLS } from '../runs/context-tools.js';
|
|
24
27
|
import { PROJECT_TOOLS } from '../project/project-tools.js';
|
|
28
|
+
import { MEMORY_TOOLS } from '../memory/memory-tools.js';
|
|
25
29
|
import { RUN_TOOLS } from '../runs/run-tools.js';
|
|
26
30
|
import { VISUAL_TOOLS } from '../visual/visual-tools.js';
|
|
27
31
|
import { AFFECTED_TOOLS } from '../flows/affected-tools.js';
|
|
28
|
-
import {
|
|
32
|
+
import { buildCoverageTools } from './coverage-tools.js';
|
|
29
33
|
import { VERIFY_CHANGE_TOOLS } from '../flows/verify-change-tools.js';
|
|
30
34
|
import { CRAWL_TOOLS } from '../crawl/crawl-tools.js';
|
|
31
35
|
import { SCROLL_TOOLS } from '../input/scroll-tools.js';
|
|
@@ -44,10 +48,11 @@ import { LEASE_TOOLS } from './lease-tools.js';
|
|
|
44
48
|
import { FEEDBACK_TOOLS } from './feedback-tools.js';
|
|
45
49
|
/** Per-server last-snapshot cache backing reticle_snapshot's diff:true delta mode (route-invalidated). */
|
|
46
50
|
const SNAPSHOT_CACHE = new SnapshotCache();
|
|
47
|
-
|
|
51
|
+
/** Every handler, including tools retired from the advertised MCP surface. */
|
|
52
|
+
export const RAW_TOOLS = [
|
|
48
53
|
{
|
|
49
54
|
name: ReticleTool.SESSIONS,
|
|
50
|
-
description: 'List connected browser sessions (tab url/title, sessionId, last-seen, health: hidden/focused/throttled, and `realInputAvailable` — true when native CDP/launched real input is driving this tab), plus a `recommendation`
|
|
55
|
+
description: 'List connected browser sessions (tab url/title, sessionId, last-seen, health: hidden/focused/throttled, and `realInputAvailable` — true when native CDP/launched real input is driving this tab), plus a `recommendation` naming the in-protocol escape hatch (`reticle_run { tool: "reticle_lease" }`, with `reticle drive` as the human-side equivalent) when a tab is hidden/throttled and may be un-scriptable from here.',
|
|
51
56
|
inputSchema: {},
|
|
52
57
|
outputSchema: {
|
|
53
58
|
sessions: z
|
|
@@ -61,6 +66,10 @@ const RAW_TOOLS = [
|
|
|
61
66
|
title: z.string().optional(),
|
|
62
67
|
adapters: z.array(z.string()),
|
|
63
68
|
hasCapabilities: z.boolean(),
|
|
69
|
+
runtime: z
|
|
70
|
+
.string()
|
|
71
|
+
.optional()
|
|
72
|
+
.describe("Which shell answered: web, electron or tauri. Absent on an SDK too old to report one — never defaulted, because a browser tab and a desktop window on the same url are otherwise indistinguishable and only one of them has the app's IPC."),
|
|
64
73
|
versionSkew: z
|
|
65
74
|
.string()
|
|
66
75
|
.optional()
|
|
@@ -73,9 +82,26 @@ const RAW_TOOLS = [
|
|
|
73
82
|
leased: z.boolean().optional(),
|
|
74
83
|
stale: z.boolean().optional(),
|
|
75
84
|
cleanup_suggestion: z.string().optional(),
|
|
85
|
+
unresponsive: z
|
|
86
|
+
.literal(true)
|
|
87
|
+
.optional()
|
|
88
|
+
.describe('Present only when this tab is attached but has stopped answering commands: every call against it will time out. The other health fields still look fine, which is what makes this state invisible without the flag.'),
|
|
89
|
+
unresponsive_suggestion: z.string().optional(),
|
|
76
90
|
pendingMarks: z.number().optional(),
|
|
77
91
|
review_suggestion: z.string().optional(),
|
|
78
92
|
recommendation: z.string().optional(),
|
|
93
|
+
// Attached by SessionManager.list() (#117): whether this tab ever dropped and came back,
|
|
94
|
+
// how often, and how long the last drop lasted. Undeclared here, a validating client
|
|
95
|
+
// stripped the outage history while the row still looked complete — a verdict over a
|
|
96
|
+
// window with a four-second blind gap read as trustworthy.
|
|
97
|
+
attachment: z
|
|
98
|
+
.object({
|
|
99
|
+
connectedSinceMs: z.number(),
|
|
100
|
+
outages: z.number(),
|
|
101
|
+
lastOutage: z.object({ startedMs: z.number(), durationMs: z.number() }).optional(),
|
|
102
|
+
})
|
|
103
|
+
.optional()
|
|
104
|
+
.describe('Present only when this tab has dropped and reconnected at least once: how long it has been attached in total, how many outages occurred, and when the last one started and how long it lasted. A verdict over this window spans a gap where nothing was observed.'),
|
|
79
105
|
}))
|
|
80
106
|
.describe('Connected browser sessions with health state. `projectId` groups sessions by app (stable across port changes); `leased` marks a pool-managed headless context vs a human tab.'),
|
|
81
107
|
why: z
|
|
@@ -90,7 +116,7 @@ const RAW_TOOLS = [
|
|
|
90
116
|
reason: z.string(),
|
|
91
117
|
})
|
|
92
118
|
.optional()
|
|
93
|
-
.describe("Present ONLY when `sessions` is empty: the same answer as `why`, executable. `command` is the LITERAL command to run, sourced from this project's own package.json scripts and lockfile — it is absent, never guessed, when the project declares no dev script. `action` is one of start_dev_server | run_init | open_app | reopen_app."),
|
|
119
|
+
.describe("Present ONLY when `sessions` is empty: the same answer as `why`, executable. `command` is the LITERAL command to run, sourced from this project's own package.json scripts and lockfile — it is absent, never guessed, when the project declares no dev script. `action` is one of daemon_split | start_dev_server | run_init | open_app | reopen_app. `daemon_split` outranks the rest and means the app IS running and instrumented, on a DIFFERENT daemon than the one you are attached to — do not start or re-init anything, read `reason`."),
|
|
94
120
|
},
|
|
95
121
|
handler: async (deps) => {
|
|
96
122
|
const provider = deps.realInput;
|
|
@@ -207,18 +233,18 @@ const RAW_TOOLS = [
|
|
|
207
233
|
return commandOrThrow(deps, resolved.id, ReticleCommand.SNAPSHOT, {
|
|
208
234
|
scope: args['scope'],
|
|
209
235
|
mode,
|
|
210
|
-
}).then((raw) => withSizeCost(applySnapshotDelta(raw, {
|
|
236
|
+
}).then((raw) => withSizeCost(noteEmptyLeanTree(applySnapshotDelta(raw, {
|
|
211
237
|
sessionId: resolved.id,
|
|
212
238
|
scope: asString(args['scope']) ?? '',
|
|
213
239
|
mode,
|
|
214
240
|
diff: true === args['diff'],
|
|
215
|
-
}, SNAPSHOT_CACHE)));
|
|
241
|
+
}, SNAPSHOT_CACHE), mode)));
|
|
216
242
|
},
|
|
217
243
|
},
|
|
218
244
|
{
|
|
219
245
|
name: ReticleTool.QUERY,
|
|
220
246
|
example: { by: 'testid', value: 'todo-list' },
|
|
221
|
-
description: `Find elements by Testing-Library semantics, INCLUDING open shadow roots — \`count_only:true\` gives just the count (~30x smaller); \`limit\` caps descriptors. Pass \`by\` (${QUERY_BY_LIST}) and \`value\` (the query string). Returns matching refs + descriptors + visibility. Pass \`attrs:["href"]\` to project attributes (link/image URLs) onto each match. Pass \`limit\` to cap descriptors (broad role queries can be large) or \`count_only:true\` for just the match count — both cut tokens. On zero matches, also returns hint:{ route, presentRegions[], knownEmptyState } so you can distinguish an empty state from a missing element WITHOUT taking a snapshot.`,
|
|
247
|
+
description: `Find elements by Testing-Library semantics, INCLUDING open shadow roots — \`count_only:true\` gives just the count (~30x smaller); \`limit\` caps descriptors. Pass \`by\` (${QUERY_BY_LIST}) and \`value\` (the query string). Returns matching refs + descriptors + visibility. Pass \`attrs:["href"]\` to project attributes (link/image URLs) onto each match. Pass \`limit\` to cap descriptors (broad role queries can be large) or \`count_only:true\` for just the match count — both cut tokens. On zero matches, also returns hint:{ route, presentRegions[], knownEmptyState } so you can distinguish an empty state from a missing element WITHOUT taking a snapshot. ASKING SEVERAL QUESTIONS ABOUT THE PAGE? One reticle_snapshot answers them all at once — a run of queries costs a round trip each and returns what the snapshot already held.`,
|
|
222
248
|
inputSchema: {
|
|
223
249
|
// Constrained to the enum, NOT z.string(). A free string let `by:'css'` through to the
|
|
224
250
|
// browser's `default: return []`, so an unsupported strategy answered "0 matches" — which
|
|
@@ -245,9 +271,7 @@ const RAW_TOOLS = [
|
|
|
245
271
|
.array(z.string())
|
|
246
272
|
.optional()
|
|
247
273
|
.describe("Attribute names to return per match, e.g. ['href'] to inventory links or ['src'] for images. Absent attributes are omitted; credential-bearing names are redacted."),
|
|
248
|
-
limit:
|
|
249
|
-
.number()
|
|
250
|
-
.nonnegative()
|
|
274
|
+
limit: countSchema
|
|
251
275
|
.optional()
|
|
252
276
|
.describe('Cap the returned descriptors to the first N (cuts tokens on broad queries). If more matched, the result carries total + truncated:true so the trim is never silent — narrow with name/scope.'),
|
|
253
277
|
count_only: z
|
|
@@ -322,6 +346,15 @@ const RAW_TOOLS = [
|
|
|
322
346
|
.describe('Structural clusters on the page — what IS here, to diagnose the miss.'),
|
|
323
347
|
presentTestids: z.array(z.string()).optional(),
|
|
324
348
|
knownEmptyState: z.boolean(),
|
|
349
|
+
splitText: z
|
|
350
|
+
.object({
|
|
351
|
+
ref: z.string().optional(),
|
|
352
|
+
role: z.string().optional(),
|
|
353
|
+
name: z.string().optional(),
|
|
354
|
+
})
|
|
355
|
+
.passthrough()
|
|
356
|
+
.optional()
|
|
357
|
+
.describe("Present when a TEXT search missed but the string IS on the page, split across this container's children. Retry as { scope: <ref>, self: true } — no text query can match a string no single element owns."),
|
|
325
358
|
})
|
|
326
359
|
.optional()
|
|
327
360
|
.describe('Present only on zero matches — tells you what IS on the page so you can diagnose the miss.'),
|
|
@@ -446,11 +479,14 @@ const RAW_TOOLS = [
|
|
|
446
479
|
// reticle_capabilities (live | fromDisk) + reticle_contract_save. See contract-tools.ts.
|
|
447
480
|
...RECONCILE_TOOLS,
|
|
448
481
|
...CONTRACT_TOOLS,
|
|
482
|
+
...INTENT_TOOLS,
|
|
483
|
+
...CONTEXT_TOOLS,
|
|
449
484
|
...DOMAIN_TOOLS,
|
|
450
485
|
// reticle_flow_save / reticle_flow_list / reticle_flow_load. See flow-tools.ts.
|
|
451
486
|
...FLOW_TOOLS,
|
|
452
487
|
// reticle_project (read history + diff-vs-last) / reticle_run_record. See project-tools.ts.
|
|
453
488
|
...PROJECT_TOOLS,
|
|
489
|
+
...MEMORY_TOOLS,
|
|
454
490
|
// reticle_run_export — export the verification-run verdict artifact (.reticle/runs/). See run-tools.ts.
|
|
455
491
|
...RUN_TOOLS,
|
|
456
492
|
// reticle_screenshot / reticle_visual_diff — opt-in, CDP-driven. See visual-tools.ts.
|
|
@@ -469,7 +505,9 @@ const RAW_TOOLS = [
|
|
|
469
505
|
// reachable through reticle_run. See affected-tools.ts.
|
|
470
506
|
...AFFECTED_TOOLS,
|
|
471
507
|
// reticle_coverage — which controls were driven vs never touched. Unadvertised; via reticle_run.
|
|
472
|
-
|
|
508
|
+
// The table is passed as a thunk so the coverage tool can report which of it was called without
|
|
509
|
+
// importing it back — see buildCoverageTools. Called from the handler, long after TOOLS exists.
|
|
510
|
+
...buildCoverageTools(() => TOOLS.map((t) => t.name)),
|
|
473
511
|
// reticle_verify_change — "did my change break anything" in one call. See verify-change-tools.ts.
|
|
474
512
|
...VERIFY_CHANGE_TOOLS,
|
|
475
513
|
// Live-control: reticle_end_session / reticle_resume / reticle_messages. See live-control-tools.ts.
|
|
@@ -561,4 +599,32 @@ export const RETIRED_FROM_SURFACE = [
|
|
|
561
599
|
ReticleTool.REFRESH, // absorbed into reticle_navigate { reload: true }
|
|
562
600
|
ReticleTool.WAIT_READY, // server-internal: the first live call already blocks for the session
|
|
563
601
|
];
|
|
602
|
+
/**
|
|
603
|
+
* An empty `interactive` tree is a claim, and it is usually the wrong one.
|
|
604
|
+
*
|
|
605
|
+
* `mode:"interactive"` filters on ARIA role, and a large share of production UI carries none. On
|
|
606
|
+
* MarkText — a shipped Electron editor — it returns NOTHING while `mode:"full"` returns 47 nodes,
|
|
607
|
+
* because its whole block picker is `<div>`s with no role, no testid and no pointer cursor. This
|
|
608
|
+
* tool's own description recommends the lean mode, so an agent takes the cheap look, is handed `""`,
|
|
609
|
+
* and reads it as an empty page. It is the one shape of answer this product must never invent.
|
|
610
|
+
*
|
|
611
|
+
* The browser counts what leanness passed over, so the tool can say which of the two it is.
|
|
612
|
+
*/
|
|
613
|
+
function noteEmptyLeanTree(result, mode) {
|
|
614
|
+
if (SnapshotMode.INTERACTIVE !== mode)
|
|
615
|
+
return result;
|
|
616
|
+
const row = asRecord(result);
|
|
617
|
+
if (0 !== asNumber(row['nodes']))
|
|
618
|
+
return result;
|
|
619
|
+
const skipped = asNumber(row['leanSkipped']) ?? 0;
|
|
620
|
+
if (0 === skipped)
|
|
621
|
+
return result;
|
|
622
|
+
return {
|
|
623
|
+
...row,
|
|
624
|
+
note: `no element on this page carries an interactive ARIA role, so this mode found nothing — ` +
|
|
625
|
+
`${String(skipped)} element(s) were passed over for leanness and this is NOT an empty page. ` +
|
|
626
|
+
`Take reticle_snapshot { mode: "full" } instead; the controls here are addressed by text or ` +
|
|
627
|
+
`by testid rather than by role.`,
|
|
628
|
+
};
|
|
629
|
+
}
|
|
564
630
|
export const TOOLS = applyMerges(RAW_TOOLS, MERGE_PLANS, RETIRED_FROM_SURFACE);
|
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* What to say when an agent calls a real Reticle tool that this profile does not advertise.
|
|
3
3
|
*
|
|
4
|
-
* The default surface
|
|
5
|
-
*
|
|
6
|
-
*
|
|
7
|
-
*
|
|
4
|
+
* The default surface is the verify loop plus the two meta-tools; the extended one is larger but
|
|
5
|
+
* still capped. Counts live in `surface-sizes.test.ts` — restating them here is how they drift.
|
|
6
|
+
* Everything omitted stays fully callable through `reticle_run`, which `surface-reachability.test.ts`
|
|
7
|
+
* guards.
|
|
8
8
|
*
|
|
9
9
|
* The gap was in the ERROR. The MCP SDK answers `Tool <name> not found`, which is indistinguishable
|
|
10
10
|
* from "this tool does not exist", so an agent that trusts it stops trying. Reported from a real
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The verdict nudge, as a call the agent can make rather than a sentence it has to translate.
|
|
3
|
+
*
|
|
4
|
+
* `verify_next` already fires when an agent has driven the page several times and asked for no
|
|
5
|
+
* verdict, which is the commonest shape of a wasted session: almost every verdict-less session in
|
|
6
|
+
* the field never called a verdict-producing tool once. What it carried was prose. Prose has to be
|
|
7
|
+
* turned back into a call, and the translation is exactly where the agent was already going wrong —
|
|
8
|
+
* `until` omitted, arguments flat instead of nested under `args`, a predicate written as a bare
|
|
9
|
+
* array.
|
|
10
|
+
*
|
|
11
|
+
* So it carries the call. `ref` and `action` come from the act that actually dispatched, so the
|
|
12
|
+
* suggestion is about the element the agent really touched rather than a worked example from a
|
|
13
|
+
* document. `until` is deliberately left as a placeholder the agent must replace: naming the
|
|
14
|
+
* consequence is the one part nothing but the agent can know, and filling it in with a guess would
|
|
15
|
+
* be Reticle inventing the assertion — the failure `no-fault` exists to prevent.
|
|
16
|
+
*
|
|
17
|
+
* Emitted only when there is a real call to suggest. A baton with nothing behind it is the router
|
|
18
|
+
* failure in miniature: an agent that follows a fabricated next step follows it confidently.
|
|
19
|
+
*/
|
|
20
|
+
/**
|
|
21
|
+
* Set to `1` to withhold the baton from tool results — the control arm of its A/B, and nothing else.
|
|
22
|
+
*
|
|
23
|
+
* A measurement flag, not a product setting: it is read at one call site, documented here, and named
|
|
24
|
+
* loudly enough that nobody sets it by accident. It exists because this feature has shipped, been
|
|
25
|
+
* declared the largest lever on whether a session verifies at all, and never been measured — and a
|
|
26
|
+
* control arm is the only way to tell "agents that see it verify" from "agents that were going to
|
|
27
|
+
* verify anyway also saw it".
|
|
28
|
+
*/
|
|
29
|
+
export declare const SUPPRESS_VERIFY_NEXT_ENV = "RETICLE_SUPPRESS_VERIFY_NEXT";
|
|
30
|
+
/** What the agent must supply itself. Phrased as an instruction so it cannot be sent verbatim. */
|
|
31
|
+
export declare const UNTIL_PLACEHOLDER = "<name the consequence this action causes>";
|
|
32
|
+
export interface VerifyNextBaton {
|
|
33
|
+
/** The fact that produced this, in the agent's own terms. */
|
|
34
|
+
why: string;
|
|
35
|
+
/** A call, ready to make once `until` is filled in. */
|
|
36
|
+
call?: {
|
|
37
|
+
tool: string;
|
|
38
|
+
args: Record<string, unknown>;
|
|
39
|
+
};
|
|
40
|
+
/** Where the argument shapes are stated, on disk and version-exact rather than on the web. */
|
|
41
|
+
docs?: string;
|
|
42
|
+
}
|
|
43
|
+
/**
|
|
44
|
+
* Build the baton from what the session actually did.
|
|
45
|
+
*
|
|
46
|
+
* `ref` absent means no act dispatched under a ref this session — a navigation, or a run that only
|
|
47
|
+
* read. There is then no honest call to name, so the prose stands alone rather than pointing at an
|
|
48
|
+
* element nobody touched.
|
|
49
|
+
*/
|
|
50
|
+
export declare function verifyNextBaton(prose: string, lastAct: {
|
|
51
|
+
action?: string | undefined;
|
|
52
|
+
ref?: string | undefined;
|
|
53
|
+
}): VerifyNextBaton;
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The verdict nudge, as a call the agent can make rather than a sentence it has to translate.
|
|
3
|
+
*
|
|
4
|
+
* `verify_next` already fires when an agent has driven the page several times and asked for no
|
|
5
|
+
* verdict, which is the commonest shape of a wasted session: almost every verdict-less session in
|
|
6
|
+
* the field never called a verdict-producing tool once. What it carried was prose. Prose has to be
|
|
7
|
+
* turned back into a call, and the translation is exactly where the agent was already going wrong —
|
|
8
|
+
* `until` omitted, arguments flat instead of nested under `args`, a predicate written as a bare
|
|
9
|
+
* array.
|
|
10
|
+
*
|
|
11
|
+
* So it carries the call. `ref` and `action` come from the act that actually dispatched, so the
|
|
12
|
+
* suggestion is about the element the agent really touched rather than a worked example from a
|
|
13
|
+
* document. `until` is deliberately left as a placeholder the agent must replace: naming the
|
|
14
|
+
* consequence is the one part nothing but the agent can know, and filling it in with a guess would
|
|
15
|
+
* be Reticle inventing the assertion — the failure `no-fault` exists to prevent.
|
|
16
|
+
*
|
|
17
|
+
* Emitted only when there is a real call to suggest. A baton with nothing behind it is the router
|
|
18
|
+
* failure in miniature: an agent that follows a fabricated next step follows it confidently.
|
|
19
|
+
*/
|
|
20
|
+
import { ReticleTool } from './tool-names.js';
|
|
21
|
+
/**
|
|
22
|
+
* Set to `1` to withhold the baton from tool results — the control arm of its A/B, and nothing else.
|
|
23
|
+
*
|
|
24
|
+
* A measurement flag, not a product setting: it is read at one call site, documented here, and named
|
|
25
|
+
* loudly enough that nobody sets it by accident. It exists because this feature has shipped, been
|
|
26
|
+
* declared the largest lever on whether a session verifies at all, and never been measured — and a
|
|
27
|
+
* control arm is the only way to tell "agents that see it verify" from "agents that were going to
|
|
28
|
+
* verify anyway also saw it".
|
|
29
|
+
*/
|
|
30
|
+
export const SUPPRESS_VERIFY_NEXT_ENV = 'RETICLE_SUPPRESS_VERIFY_NEXT';
|
|
31
|
+
/** What the agent must supply itself. Phrased as an instruction so it cannot be sent verbatim. */
|
|
32
|
+
export const UNTIL_PLACEHOLDER = '<name the consequence this action causes>';
|
|
33
|
+
/**
|
|
34
|
+
* Build the baton from what the session actually did.
|
|
35
|
+
*
|
|
36
|
+
* `ref` absent means no act dispatched under a ref this session — a navigation, or a run that only
|
|
37
|
+
* read. There is then no honest call to name, so the prose stands alone rather than pointing at an
|
|
38
|
+
* element nobody touched.
|
|
39
|
+
*/
|
|
40
|
+
export function verifyNextBaton(prose, lastAct) {
|
|
41
|
+
const { ref, action } = lastAct;
|
|
42
|
+
if (ref === undefined || action === undefined)
|
|
43
|
+
return { why: prose };
|
|
44
|
+
return {
|
|
45
|
+
why: prose,
|
|
46
|
+
call: {
|
|
47
|
+
tool: ReticleTool.ACT_AND_WAIT,
|
|
48
|
+
args: { ref, action, until: { kind: 'text', value: UNTIL_PLACEHOLDER } },
|
|
49
|
+
},
|
|
50
|
+
docs: `reticle_tools { names: ["${ReticleTool.ACT_AND_WAIT}"] }`,
|
|
51
|
+
};
|
|
52
|
+
}
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The `@reticlehq/*` packages a project actually declares.
|
|
3
|
+
*
|
|
4
|
+
* Shared by `reticle update` (which syncs them) and the version-skew remedy (which names them).
|
|
5
|
+
* Lives here, not in `init/`, so the daemon library path can read a package.json without pulling
|
|
6
|
+
* the installer in behind it.
|
|
7
|
+
*/
|
|
8
|
+
/** The Reticle packages this project declares, from either dependency section. */
|
|
9
|
+
export declare function reticleDepsOf(pkgJson: unknown): string[];
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The `@reticlehq/*` packages a project actually declares.
|
|
3
|
+
*
|
|
4
|
+
* Shared by `reticle update` (which syncs them) and the version-skew remedy (which names them).
|
|
5
|
+
* Lives here, not in `init/`, so the daemon library path can read a package.json without pulling
|
|
6
|
+
* the installer in behind it.
|
|
7
|
+
*/
|
|
8
|
+
/** Everything we publish is scoped here. */
|
|
9
|
+
const RETICLE_SCOPE = '@reticlehq/';
|
|
10
|
+
/**
|
|
11
|
+
* The CLI. Never an app dependency: it carries the Node MCP server and `ws`, and putting it in a
|
|
12
|
+
* browser app's tree is what the retired `@reticlehq/core` umbrella got wrong.
|
|
13
|
+
*/
|
|
14
|
+
const SERVER_PACKAGE = '@reticlehq/server';
|
|
15
|
+
function namesIn(section) {
|
|
16
|
+
if ('object' !== typeof section || null === section)
|
|
17
|
+
return [];
|
|
18
|
+
return Object.keys(section);
|
|
19
|
+
}
|
|
20
|
+
/** The Reticle packages this project declares, from either dependency section. */
|
|
21
|
+
export function reticleDepsOf(pkgJson) {
|
|
22
|
+
if ('object' !== typeof pkgJson || null === pkgJson)
|
|
23
|
+
return [];
|
|
24
|
+
const manifest = pkgJson;
|
|
25
|
+
const declared = [...namesIn(manifest['dependencies']), ...namesIn(manifest['devDependencies'])];
|
|
26
|
+
return [...new Set(declared)].filter((name) => name.startsWith(RETICLE_SCOPE) && name !== SERVER_PACKAGE);
|
|
27
|
+
}
|
|
@@ -12,8 +12,7 @@
|
|
|
12
12
|
* npm took 2.3.0 in the next project over.
|
|
13
13
|
*/
|
|
14
14
|
import { type PackageManager } from '../init/detect.js';
|
|
15
|
-
|
|
16
|
-
export declare function reticleDepsOf(pkgJson: unknown): string[];
|
|
15
|
+
export { reticleDepsOf } from './reticle-deps.js';
|
|
17
16
|
/** The install to run, or null when this project has nothing of ours to sync. */
|
|
18
17
|
export declare function sdkSyncCommand(pm: PackageManager, packages: readonly string[], version: string): {
|
|
19
18
|
command: string;
|