@reticlehq/server 2.0.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/LICENSE +105 -0
- package/README.md +17 -0
- package/dist/bridge-security.d.ts +23 -0
- package/dist/bridge-security.d.ts.map +1 -0
- package/dist/bridge-security.js +44 -0
- package/dist/bridge-security.js.map +1 -0
- package/dist/bridge.d.ts +42 -0
- package/dist/bridge.d.ts.map +1 -0
- package/dist/bridge.js +281 -0
- package/dist/bridge.js.map +1 -0
- package/dist/bridge.test-harness.d.ts +42 -0
- package/dist/bridge.test-harness.d.ts.map +1 -0
- package/dist/bridge.test-harness.js +192 -0
- package/dist/bridge.test-harness.js.map +1 -0
- package/dist/cli-launch.d.ts +53 -0
- package/dist/cli-launch.d.ts.map +1 -0
- package/dist/cli-launch.js +109 -0
- package/dist/cli-launch.js.map +1 -0
- package/dist/cli-parse.d.ts +74 -0
- package/dist/cli-parse.d.ts.map +1 -0
- package/dist/cli-parse.js +321 -0
- package/dist/cli-parse.js.map +1 -0
- package/dist/cli-port.d.ts +26 -0
- package/dist/cli-port.d.ts.map +1 -0
- package/dist/cli-port.js +57 -0
- package/dist/cli-port.js.map +1 -0
- package/dist/cli-verify.d.ts +46 -0
- package/dist/cli-verify.d.ts.map +1 -0
- package/dist/cli-verify.js +181 -0
- package/dist/cli-verify.js.map +1 -0
- package/dist/cli.d.ts +6 -0
- package/dist/cli.d.ts.map +1 -0
- package/dist/cli.js +337 -0
- package/dist/cli.js.map +1 -0
- package/dist/cloud/cloud-sync.d.ts +50 -0
- package/dist/cloud/cloud-sync.d.ts.map +1 -0
- package/dist/cloud/cloud-sync.js +47 -0
- package/dist/cloud/cloud-sync.js.map +1 -0
- package/dist/crawl/crawl-tools.d.ts +8 -0
- package/dist/crawl/crawl-tools.d.ts.map +1 -0
- package/dist/crawl/crawl-tools.js +61 -0
- package/dist/crawl/crawl-tools.js.map +1 -0
- package/dist/crawl/crawl.d.ts +45 -0
- package/dist/crawl/crawl.d.ts.map +1 -0
- package/dist/crawl/crawl.js +106 -0
- package/dist/crawl/crawl.js.map +1 -0
- package/dist/daemon-resilience.d.ts +17 -0
- package/dist/daemon-resilience.d.ts.map +1 -0
- package/dist/daemon-resilience.js +23 -0
- package/dist/daemon-resilience.js.map +1 -0
- package/dist/daemon.d.ts +26 -0
- package/dist/daemon.d.ts.map +1 -0
- package/dist/daemon.js +122 -0
- package/dist/daemon.js.map +1 -0
- package/dist/domain/domain-model.d.ts +64 -0
- package/dist/domain/domain-model.d.ts.map +1 -0
- package/dist/domain/domain-model.js +127 -0
- package/dist/domain/domain-model.js.map +1 -0
- package/dist/domain/domain-tools.d.ts +9 -0
- package/dist/domain/domain-tools.d.ts.map +1 -0
- package/dist/domain/domain-tools.js +66 -0
- package/dist/domain/domain-tools.js.map +1 -0
- package/dist/domain/flow-risk.d.ts +34 -0
- package/dist/domain/flow-risk.d.ts.map +1 -0
- package/dist/domain/flow-risk.js +81 -0
- package/dist/domain/flow-risk.js.map +1 -0
- package/dist/ee/audit-log.d.ts +15 -0
- package/dist/ee/audit-log.d.ts.map +1 -0
- package/dist/ee/audit-log.js +12 -0
- package/dist/ee/audit-log.js.map +1 -0
- package/dist/events/event-filters.d.ts +65 -0
- package/dist/events/event-filters.d.ts.map +1 -0
- package/dist/events/event-filters.js +98 -0
- package/dist/events/event-filters.js.map +1 -0
- package/dist/events/predicate-eval.d.ts +91 -0
- package/dist/events/predicate-eval.d.ts.map +1 -0
- package/dist/events/predicate-eval.js +299 -0
- package/dist/events/predicate-eval.js.map +1 -0
- package/dist/events/predicate.d.ts +19 -0
- package/dist/events/predicate.d.ts.map +1 -0
- package/dist/events/predicate.js +188 -0
- package/dist/events/predicate.js.map +1 -0
- package/dist/events/reaction.d.ts +34 -0
- package/dist/events/reaction.d.ts.map +1 -0
- package/dist/events/reaction.js +60 -0
- package/dist/events/reaction.js.map +1 -0
- package/dist/events/ring-buffer.d.ts +32 -0
- package/dist/events/ring-buffer.d.ts.map +1 -0
- package/dist/events/ring-buffer.js +75 -0
- package/dist/events/ring-buffer.js.map +1 -0
- package/dist/flows/annotate-tools.d.ts +16 -0
- package/dist/flows/annotate-tools.d.ts.map +1 -0
- package/dist/flows/annotate-tools.js +136 -0
- package/dist/flows/annotate-tools.js.map +1 -0
- package/dist/flows/annotate.d.ts +22 -0
- package/dist/flows/annotate.d.ts.map +1 -0
- package/dist/flows/annotate.js +134 -0
- package/dist/flows/annotate.js.map +1 -0
- package/dist/flows/annotation-store.d.ts +23 -0
- package/dist/flows/annotation-store.d.ts.map +1 -0
- package/dist/flows/annotation-store.js +51 -0
- package/dist/flows/annotation-store.js.map +1 -0
- package/dist/flows/decision.d.ts +13 -0
- package/dist/flows/decision.d.ts.map +1 -0
- package/dist/flows/decision.js +111 -0
- package/dist/flows/decision.js.map +1 -0
- package/dist/flows/flow-classify.d.ts +52 -0
- package/dist/flows/flow-classify.d.ts.map +1 -0
- package/dist/flows/flow-classify.js +99 -0
- package/dist/flows/flow-classify.js.map +1 -0
- package/dist/flows/flow-replay-run.d.ts +15 -0
- package/dist/flows/flow-replay-run.d.ts.map +1 -0
- package/dist/flows/flow-replay-run.js +120 -0
- package/dist/flows/flow-replay-run.js.map +1 -0
- package/dist/flows/flow-replay.d.ts +49 -0
- package/dist/flows/flow-replay.d.ts.map +1 -0
- package/dist/flows/flow-replay.js +391 -0
- package/dist/flows/flow-replay.js.map +1 -0
- package/dist/flows/flow-report.d.ts +23 -0
- package/dist/flows/flow-report.d.ts.map +1 -0
- package/dist/flows/flow-report.js +106 -0
- package/dist/flows/flow-report.js.map +1 -0
- package/dist/flows/flow-scope.d.ts +25 -0
- package/dist/flows/flow-scope.d.ts.map +1 -0
- package/dist/flows/flow-scope.js +32 -0
- package/dist/flows/flow-scope.js.map +1 -0
- package/dist/flows/flow-success.d.ts +33 -0
- package/dist/flows/flow-success.d.ts.map +1 -0
- package/dist/flows/flow-success.js +131 -0
- package/dist/flows/flow-success.js.map +1 -0
- package/dist/flows/flow-tools.d.ts +4 -0
- package/dist/flows/flow-tools.d.ts.map +1 -0
- package/dist/flows/flow-tools.js +460 -0
- package/dist/flows/flow-tools.js.map +1 -0
- package/dist/flows/flows.d.ts +86 -0
- package/dist/flows/flows.d.ts.map +1 -0
- package/dist/flows/flows.js +319 -0
- package/dist/flows/flows.js.map +1 -0
- package/dist/flows/heal.d.ts +43 -0
- package/dist/flows/heal.d.ts.map +1 -0
- package/dist/flows/heal.js +98 -0
- package/dist/flows/heal.js.map +1 -0
- package/dist/flows/recordings.d.ts +46 -0
- package/dist/flows/recordings.d.ts.map +1 -0
- package/dist/flows/recordings.js +43 -0
- package/dist/flows/recordings.js.map +1 -0
- package/dist/flows/replay.d.ts +23 -0
- package/dist/flows/replay.d.ts.map +1 -0
- package/dist/flows/replay.js +160 -0
- package/dist/flows/replay.js.map +1 -0
- package/dist/http-server.d.ts +39 -0
- package/dist/http-server.d.ts.map +1 -0
- package/dist/http-server.js +145 -0
- package/dist/http-server.js.map +1 -0
- package/dist/idle-shutdown.d.ts +34 -0
- package/dist/idle-shutdown.d.ts.map +1 -0
- package/dist/idle-shutdown.js +68 -0
- package/dist/idle-shutdown.js.map +1 -0
- package/dist/index.d.ts +135 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +371 -0
- package/dist/index.js.map +1 -0
- package/dist/init/cursor.d.ts +25 -0
- package/dist/init/cursor.d.ts.map +1 -0
- package/dist/init/cursor.js +49 -0
- package/dist/init/cursor.js.map +1 -0
- package/dist/init/detect.d.ts +49 -0
- package/dist/init/detect.d.ts.map +1 -0
- package/dist/init/detect.js +84 -0
- package/dist/init/detect.js.map +1 -0
- package/dist/init/mcp.d.ts +40 -0
- package/dist/init/mcp.d.ts.map +1 -0
- package/dist/init/mcp.js +55 -0
- package/dist/init/mcp.js.map +1 -0
- package/dist/init/node-io.d.ts +8 -0
- package/dist/init/node-io.d.ts.map +1 -0
- package/dist/init/node-io.js +57 -0
- package/dist/init/node-io.js.map +1 -0
- package/dist/init/plan.d.ts +72 -0
- package/dist/init/plan.d.ts.map +1 -0
- package/dist/init/plan.js +280 -0
- package/dist/init/plan.js.map +1 -0
- package/dist/init/project-id.d.ts +17 -0
- package/dist/init/project-id.d.ts.map +1 -0
- package/dist/init/project-id.js +38 -0
- package/dist/init/project-id.js.map +1 -0
- package/dist/init/run.d.ts +42 -0
- package/dist/init/run.d.ts.map +1 -0
- package/dist/init/run.js +171 -0
- package/dist/init/run.js.map +1 -0
- package/dist/init/snippets.d.ts +33 -0
- package/dist/init/snippets.d.ts.map +1 -0
- package/dist/init/snippets.js +117 -0
- package/dist/init/snippets.js.map +1 -0
- package/dist/init/vite-config.d.ts +25 -0
- package/dist/init/vite-config.d.ts.map +1 -0
- package/dist/init/vite-config.js +45 -0
- package/dist/init/vite-config.js.map +1 -0
- package/dist/input/network-mock-tools.d.ts +3 -0
- package/dist/input/network-mock-tools.d.ts.map +1 -0
- package/dist/input/network-mock-tools.js +94 -0
- package/dist/input/network-mock-tools.js.map +1 -0
- package/dist/input/network-mock.d.ts +55 -0
- package/dist/input/network-mock.d.ts.map +1 -0
- package/dist/input/network-mock.js +62 -0
- package/dist/input/network-mock.js.map +1 -0
- package/dist/input/real-input.d.ts +174 -0
- package/dist/input/real-input.d.ts.map +1 -0
- package/dist/input/real-input.js +289 -0
- package/dist/input/real-input.js.map +1 -0
- package/dist/input/scroll-find.d.ts +41 -0
- package/dist/input/scroll-find.d.ts.map +1 -0
- package/dist/input/scroll-find.js +59 -0
- package/dist/input/scroll-find.js.map +1 -0
- package/dist/input/scroll-tools.d.ts +8 -0
- package/dist/input/scroll-tools.d.ts.map +1 -0
- package/dist/input/scroll-tools.js +68 -0
- package/dist/input/scroll-tools.js.map +1 -0
- package/dist/input/viewport-tools.d.ts +3 -0
- package/dist/input/viewport-tools.d.ts.map +1 -0
- package/dist/input/viewport-tools.js +65 -0
- package/dist/input/viewport-tools.js.map +1 -0
- package/dist/license/license.d.ts +108 -0
- package/dist/license/license.d.ts.map +1 -0
- package/dist/license/license.js +203 -0
- package/dist/license/license.js.map +1 -0
- package/dist/log.d.ts +6 -0
- package/dist/log.d.ts.map +1 -0
- package/dist/log.js +9 -0
- package/dist/log.js.map +1 -0
- package/dist/mcp-proxy.d.ts +16 -0
- package/dist/mcp-proxy.d.ts.map +1 -0
- package/dist/mcp-proxy.js +168 -0
- package/dist/mcp-proxy.js.map +1 -0
- package/dist/mcp.d.ts +14 -0
- package/dist/mcp.d.ts.map +1 -0
- package/dist/mcp.js +101 -0
- package/dist/mcp.js.map +1 -0
- package/dist/pairing-token.d.ts +28 -0
- package/dist/pairing-token.d.ts.map +1 -0
- package/dist/pairing-token.js +62 -0
- package/dist/pairing-token.js.map +1 -0
- package/dist/pool/browser-pool.d.ts +90 -0
- package/dist/pool/browser-pool.d.ts.map +1 -0
- package/dist/pool/browser-pool.js +221 -0
- package/dist/pool/browser-pool.js.map +1 -0
- package/dist/pool/lease-reaper.d.ts +16 -0
- package/dist/pool/lease-reaper.d.ts.map +1 -0
- package/dist/pool/lease-reaper.js +41 -0
- package/dist/pool/lease-reaper.js.map +1 -0
- package/dist/pool/playwright-launcher.d.ts +19 -0
- package/dist/pool/playwright-launcher.d.ts.map +1 -0
- package/dist/pool/playwright-launcher.js +51 -0
- package/dist/pool/playwright-launcher.js.map +1 -0
- package/dist/project/baselines.d.ts +22 -0
- package/dist/project/baselines.d.ts.map +1 -0
- package/dist/project/baselines.js +45 -0
- package/dist/project/baselines.js.map +1 -0
- package/dist/project/fs-port.d.ts +27 -0
- package/dist/project/fs-port.d.ts.map +1 -0
- package/dist/project/fs-port.js +32 -0
- package/dist/project/fs-port.js.map +1 -0
- package/dist/project/project-store.d.ts +32 -0
- package/dist/project/project-store.d.ts.map +1 -0
- package/dist/project/project-store.js +127 -0
- package/dist/project/project-store.js.map +1 -0
- package/dist/project/project-tools.d.ts +9 -0
- package/dist/project/project-tools.d.ts.map +1 -0
- package/dist/project/project-tools.js +118 -0
- package/dist/project/project-tools.js.map +1 -0
- package/dist/project/reticle-dir.d.ts +61 -0
- package/dist/project/reticle-dir.d.ts.map +1 -0
- package/dist/project/reticle-dir.js +144 -0
- package/dist/project/reticle-dir.js.map +1 -0
- package/dist/runs/build-verification-run.d.ts +30 -0
- package/dist/runs/build-verification-run.d.ts.map +1 -0
- package/dist/runs/build-verification-run.js +71 -0
- package/dist/runs/build-verification-run.js.map +1 -0
- package/dist/runs/profile-redact.d.ts +16 -0
- package/dist/runs/profile-redact.d.ts.map +1 -0
- package/dist/runs/profile-redact.js +32 -0
- package/dist/runs/profile-redact.js.map +1 -0
- package/dist/runs/render-report.d.ts +9 -0
- package/dist/runs/render-report.d.ts.map +1 -0
- package/dist/runs/render-report.js +70 -0
- package/dist/runs/render-report.js.map +1 -0
- package/dist/runs/repair-prompt.d.ts +15 -0
- package/dist/runs/repair-prompt.d.ts.map +1 -0
- package/dist/runs/repair-prompt.js +59 -0
- package/dist/runs/repair-prompt.js.map +1 -0
- package/dist/runs/replay-mapping.d.ts +12 -0
- package/dist/runs/replay-mapping.d.ts.map +1 -0
- package/dist/runs/replay-mapping.js +35 -0
- package/dist/runs/replay-mapping.js.map +1 -0
- package/dist/runs/reticle-runner.d.ts +48 -0
- package/dist/runs/reticle-runner.d.ts.map +1 -0
- package/dist/runs/reticle-runner.js +56 -0
- package/dist/runs/reticle-runner.js.map +1 -0
- package/dist/runs/risk-classify.d.ts +27 -0
- package/dist/runs/risk-classify.d.ts.map +1 -0
- package/dist/runs/risk-classify.js +76 -0
- package/dist/runs/risk-classify.js.map +1 -0
- package/dist/runs/run-store.d.ts +40 -0
- package/dist/runs/run-store.d.ts.map +1 -0
- package/dist/runs/run-store.js +118 -0
- package/dist/runs/run-store.js.map +1 -0
- package/dist/runs/run-tools.d.ts +10 -0
- package/dist/runs/run-tools.d.ts.map +1 -0
- package/dist/runs/run-tools.js +69 -0
- package/dist/runs/run-tools.js.map +1 -0
- package/dist/runs/runner-port.d.ts +14 -0
- package/dist/runs/runner-port.d.ts.map +1 -0
- package/dist/runs/runner-port.js +23 -0
- package/dist/runs/runner-port.js.map +1 -0
- package/dist/runs/verify-http.d.ts +34 -0
- package/dist/runs/verify-http.d.ts.map +1 -0
- package/dist/runs/verify-http.js +102 -0
- package/dist/runs/verify-http.js.map +1 -0
- package/dist/runs/verify-server.d.ts +26 -0
- package/dist/runs/verify-server.d.ts.map +1 -0
- package/dist/runs/verify-server.js +99 -0
- package/dist/runs/verify-server.js.map +1 -0
- package/dist/server-version.d.ts +3 -0
- package/dist/server-version.d.ts.map +1 -0
- package/dist/server-version.js +5 -0
- package/dist/server-version.js.map +1 -0
- package/dist/session/control-envelope.d.ts +49 -0
- package/dist/session/control-envelope.d.ts.map +1 -0
- package/dist/session/control-envelope.js +44 -0
- package/dist/session/control-envelope.js.map +1 -0
- package/dist/session/live-control-tools.d.ts +16 -0
- package/dist/session/live-control-tools.d.ts.map +1 -0
- package/dist/session/live-control-tools.js +204 -0
- package/dist/session/live-control-tools.js.map +1 -0
- package/dist/session/output-budget.d.ts +41 -0
- package/dist/session/output-budget.d.ts.map +1 -0
- package/dist/session/output-budget.js +54 -0
- package/dist/session/output-budget.js.map +1 -0
- package/dist/session/presenter-args.d.ts +8 -0
- package/dist/session/presenter-args.d.ts.map +1 -0
- package/dist/session/presenter-args.js +15 -0
- package/dist/session/presenter-args.js.map +1 -0
- package/dist/session/review-store.d.ts +40 -0
- package/dist/session/review-store.d.ts.map +1 -0
- package/dist/session/review-store.js +61 -0
- package/dist/session/review-store.js.map +1 -0
- package/dist/session/session-health.d.ts +22 -0
- package/dist/session/session-health.d.ts.map +1 -0
- package/dist/session/session-health.js +26 -0
- package/dist/session/session-health.js.map +1 -0
- package/dist/session/session-manager.d.ts +43 -0
- package/dist/session/session-manager.d.ts.map +1 -0
- package/dist/session/session-manager.js +155 -0
- package/dist/session/session-manager.js.map +1 -0
- package/dist/session/session-readiness.d.ts +35 -0
- package/dist/session/session-readiness.d.ts.map +1 -0
- package/dist/session/session-readiness.js +32 -0
- package/dist/session/session-readiness.js.map +1 -0
- package/dist/session/session-reaper.d.ts +37 -0
- package/dist/session/session-reaper.d.ts.map +1 -0
- package/dist/session/session-reaper.js +94 -0
- package/dist/session/session-reaper.js.map +1 -0
- package/dist/session/session-recommendation.d.ts +18 -0
- package/dist/session/session-recommendation.d.ts.map +1 -0
- package/dist/session/session-recommendation.js +14 -0
- package/dist/session/session-recommendation.js.map +1 -0
- package/dist/session/session-tools.d.ts +9 -0
- package/dist/session/session-tools.d.ts.map +1 -0
- package/dist/session/session-tools.js +43 -0
- package/dist/session/session-tools.js.map +1 -0
- package/dist/session/session.d.ts +166 -0
- package/dist/session/session.d.ts.map +1 -0
- package/dist/session/session.js +408 -0
- package/dist/session/session.js.map +1 -0
- package/dist/session/state-select.d.ts +8 -0
- package/dist/session/state-select.d.ts.map +1 -0
- package/dist/session/state-select.js +8 -0
- package/dist/session/state-select.js.map +1 -0
- package/dist/token-auth.d.ts +24 -0
- package/dist/token-auth.d.ts.map +1 -0
- package/dist/token-auth.js +71 -0
- package/dist/token-auth.js.map +1 -0
- package/dist/tools/act-tools.d.ts +3 -0
- package/dist/tools/act-tools.d.ts.map +1 -0
- package/dist/tools/act-tools.js +327 -0
- package/dist/tools/act-tools.js.map +1 -0
- package/dist/tools/act-view.d.ts +19 -0
- package/dist/tools/act-view.d.ts.map +1 -0
- package/dist/tools/act-view.js +46 -0
- package/dist/tools/act-view.js.map +1 -0
- package/dist/tools/assert-grade.d.ts +21 -0
- package/dist/tools/assert-grade.d.ts.map +1 -0
- package/dist/tools/assert-grade.js +52 -0
- package/dist/tools/assert-grade.js.map +1 -0
- package/dist/tools/browser-tools.d.ts +3 -0
- package/dist/tools/browser-tools.d.ts.map +1 -0
- package/dist/tools/browser-tools.js +52 -0
- package/dist/tools/browser-tools.js.map +1 -0
- package/dist/tools/contract-tools.d.ts +8 -0
- package/dist/tools/contract-tools.d.ts.map +1 -0
- package/dist/tools/contract-tools.js +62 -0
- package/dist/tools/contract-tools.js.map +1 -0
- package/dist/tools/dynamic-tools.d.ts +7 -0
- package/dist/tools/dynamic-tools.d.ts.map +1 -0
- package/dist/tools/dynamic-tools.js +103 -0
- package/dist/tools/dynamic-tools.js.map +1 -0
- package/dist/tools/error-recovery.d.ts +31 -0
- package/dist/tools/error-recovery.d.ts.map +1 -0
- package/dist/tools/error-recovery.js +52 -0
- package/dist/tools/error-recovery.js.map +1 -0
- package/dist/tools/invoke-tool.d.ts +23 -0
- package/dist/tools/invoke-tool.d.ts.map +1 -0
- package/dist/tools/invoke-tool.js +99 -0
- package/dist/tools/invoke-tool.js.map +1 -0
- package/dist/tools/lease-tools.d.ts +31 -0
- package/dist/tools/lease-tools.d.ts.map +1 -0
- package/dist/tools/lease-tools.js +164 -0
- package/dist/tools/lease-tools.js.map +1 -0
- package/dist/tools/observe-tools.d.ts +3 -0
- package/dist/tools/observe-tools.d.ts.map +1 -0
- package/dist/tools/observe-tools.js +259 -0
- package/dist/tools/observe-tools.js.map +1 -0
- package/dist/tools/profiles.d.ts +33 -0
- package/dist/tools/profiles.d.ts.map +1 -0
- package/dist/tools/profiles.js +105 -0
- package/dist/tools/profiles.js.map +1 -0
- package/dist/tools/query-paginate.d.ts +15 -0
- package/dist/tools/query-paginate.d.ts.map +1 -0
- package/dist/tools/query-paginate.js +31 -0
- package/dist/tools/query-paginate.js.map +1 -0
- package/dist/tools/read-tools.d.ts +3 -0
- package/dist/tools/read-tools.d.ts.map +1 -0
- package/dist/tools/read-tools.js +329 -0
- package/dist/tools/read-tools.js.map +1 -0
- package/dist/tools/snapshot-delta.d.ts +59 -0
- package/dist/tools/snapshot-delta.d.ts.map +1 -0
- package/dist/tools/snapshot-delta.js +0 -0
- package/dist/tools/snapshot-delta.js.map +1 -0
- package/dist/tools/tool-invoker.d.ts +15 -0
- package/dist/tools/tool-invoker.d.ts.map +1 -0
- package/dist/tools/tool-invoker.js +20 -0
- package/dist/tools/tool-invoker.js.map +1 -0
- package/dist/tools/tool-kit.d.ts +60 -0
- package/dist/tools/tool-kit.d.ts.map +1 -0
- package/dist/tools/tool-kit.js +33 -0
- package/dist/tools/tool-kit.js.map +1 -0
- package/dist/tools/tool-names.d.ts +89 -0
- package/dist/tools/tool-names.d.ts.map +1 -0
- package/dist/tools/tool-names.js +88 -0
- package/dist/tools/tool-names.js.map +1 -0
- package/dist/tools/tools-helpers.d.ts +12 -0
- package/dist/tools/tools-helpers.d.ts.map +1 -0
- package/dist/tools/tools-helpers.js +22 -0
- package/dist/tools/tools-helpers.js.map +1 -0
- package/dist/tools/tools.d.ts +4 -0
- package/dist/tools/tools.d.ts.map +1 -0
- package/dist/tools/tools.js +268 -0
- package/dist/tools/tools.js.map +1 -0
- package/dist/update/update-checker.d.ts +20 -0
- package/dist/update/update-checker.d.ts.map +1 -0
- package/dist/update/update-checker.js +94 -0
- package/dist/update/update-checker.js.map +1 -0
- package/dist/update/update-tools.d.ts +3 -0
- package/dist/update/update-tools.d.ts.map +1 -0
- package/dist/update/update-tools.js +94 -0
- package/dist/update/update-tools.js.map +1 -0
- package/dist/update/updater.d.ts +31 -0
- package/dist/update/updater.d.ts.map +1 -0
- package/dist/update/updater.js +120 -0
- package/dist/update/updater.js.map +1 -0
- package/dist/visual/visual-diff.d.ts +46 -0
- package/dist/visual/visual-diff.d.ts.map +1 -0
- package/dist/visual/visual-diff.js +100 -0
- package/dist/visual/visual-diff.js.map +1 -0
- package/dist/visual/visual-store.d.ts +22 -0
- package/dist/visual/visual-store.d.ts.map +1 -0
- package/dist/visual/visual-store.js +60 -0
- package/dist/visual/visual-store.js.map +1 -0
- package/dist/visual/visual-tools.d.ts +9 -0
- package/dist/visual/visual-tools.d.ts.map +1 -0
- package/dist/visual/visual-tools.js +182 -0
- package/dist/visual/visual-tools.js.map +1 -0
- package/package.json +68 -0
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
import { z } from 'zod';
|
|
2
|
+
import { CapabilitiesSchema, ContractReadError, FROM_DISK_ARG, ReticleCommand, } from '@reticlehq/core';
|
|
3
|
+
import { ReticleTool } from './tool-names.js';
|
|
4
|
+
import { asString } from './tools-helpers.js';
|
|
5
|
+
import { sessionIdShape, commandOrThrow } from './tool-kit.js';
|
|
6
|
+
import { reticleDirPaths, readContract, writeContract } from '../project/reticle-dir.js';
|
|
7
|
+
/**
|
|
8
|
+
* The capability-contract tools. `reticle_capabilities` reads the live session, or the
|
|
9
|
+
* git-checked `.reticle/contract.json` when `{ fromDisk:true }`; `reticle_contract_save` persists the
|
|
10
|
+
* live registry to that file (pretty-printed, stable key order — diffable in PRs).
|
|
11
|
+
*/
|
|
12
|
+
export const CONTRACT_TOOLS = [
|
|
13
|
+
{
|
|
14
|
+
name: ReticleTool.CAPABILITIES,
|
|
15
|
+
description: 'The app-advertised testable surface (reticle.describe): testids, signals, stores, and named flows. Call this first to learn what to assert on without reading source. Pass { fromDisk:true } to read the git-checked .reticle/contract.json instead of the live session (a fresh agent can learn the surface with no browser attached).',
|
|
16
|
+
inputSchema: { [FROM_DISK_ARG]: z.boolean().optional(), ...sessionIdShape },
|
|
17
|
+
outputSchema: {
|
|
18
|
+
testids: z.array(z.string()),
|
|
19
|
+
signals: z.array(z.string()),
|
|
20
|
+
stores: z.array(z.string()),
|
|
21
|
+
flows: z.array(z.object({ name: z.string(), steps: z.array(z.string()) })),
|
|
22
|
+
source: z
|
|
23
|
+
.string()
|
|
24
|
+
.describe('live = real-time from the browser; disk = last saved contract.json'),
|
|
25
|
+
},
|
|
26
|
+
handler: async (deps, args) => {
|
|
27
|
+
if (args[FROM_DISK_ARG] === true) {
|
|
28
|
+
const r = await readContract(deps.fs, deps.reticleRoot);
|
|
29
|
+
if (!r.ok)
|
|
30
|
+
throw new Error(r.reason === ContractReadError.MISSING
|
|
31
|
+
? 'no .reticle/contract.json on disk — run reticle_contract_save first (or omit fromDisk to read the live session)'
|
|
32
|
+
: '.reticle/contract.json is malformed — fix or regenerate it with reticle_contract_save');
|
|
33
|
+
return { ...r.capabilities, source: 'disk', generatedAt: r.generatedAt };
|
|
34
|
+
}
|
|
35
|
+
const caps = await commandOrThrow(deps, asString(args['sessionId']), ReticleCommand.CAPABILITIES, {});
|
|
36
|
+
return { ...caps, source: 'live' };
|
|
37
|
+
},
|
|
38
|
+
},
|
|
39
|
+
{
|
|
40
|
+
name: ReticleTool.CONTRACT_SAVE,
|
|
41
|
+
description: "Persist the app's live capability registry (reticle.describe) to .reticle/contract.json — git-checked, diffable, readable by a fresh agent via reticle_capabilities({ fromDisk:true }). Returns { path, counts }.",
|
|
42
|
+
inputSchema: { ...sessionIdShape },
|
|
43
|
+
outputSchema: {
|
|
44
|
+
saved: z.boolean(),
|
|
45
|
+
path: z.string(),
|
|
46
|
+
testidCount: z.number(),
|
|
47
|
+
signalCount: z.number(),
|
|
48
|
+
},
|
|
49
|
+
handler: async (deps, args) => {
|
|
50
|
+
const res = await commandOrThrow(deps, asString(args['sessionId']), ReticleCommand.CAPABILITIES, {});
|
|
51
|
+
const caps = CapabilitiesSchema.parse(res);
|
|
52
|
+
await writeContract(deps.fs, deps.reticleRoot, caps, deps.now);
|
|
53
|
+
return {
|
|
54
|
+
saved: true,
|
|
55
|
+
path: reticleDirPaths(deps.reticleRoot).contract,
|
|
56
|
+
testidCount: caps.testids.length,
|
|
57
|
+
signalCount: caps.signals.length,
|
|
58
|
+
};
|
|
59
|
+
},
|
|
60
|
+
},
|
|
61
|
+
];
|
|
62
|
+
//# sourceMappingURL=contract-tools.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"contract-tools.js","sourceRoot":"","sources":["../../src/tools/contract-tools.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import type { ToolDef } from './tools.js';
|
|
2
|
+
/**
|
|
3
|
+
* Build the two dynamic meta-tools over the full tool table. `reticle_run` dispatches through the same
|
|
4
|
+
* `runTool` chokepoint as a direct call, so session-health splicing and every other invariant hold.
|
|
5
|
+
*/
|
|
6
|
+
export declare function buildDynamicTools(allTools: ToolDef[]): ToolDef[];
|
|
7
|
+
//# sourceMappingURL=dynamic-tools.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"dynamic-tools.d.ts","sourceRoot":"","sources":["../../src/tools/dynamic-tools.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,OAAO,EAAY,MAAM,YAAY,CAAC;AA8CpD;;;GAGG;AACH,wBAAgB,iBAAiB,CAAC,QAAQ,EAAE,OAAO,EAAE,GAAG,OAAO,EAAE,CAkEhE"}
|
|
@@ -0,0 +1,103 @@
|
|
|
1
|
+
import { z } from 'zod';
|
|
2
|
+
import { runTool } from './invoke-tool.js';
|
|
3
|
+
/**
|
|
4
|
+
* On-demand tool loading for MCP — the answer to the per-turn tool-definition tax.
|
|
5
|
+
*
|
|
6
|
+
* A normal MCP server advertises every tool's full description + schema, and the client re-sends
|
|
7
|
+
* all of them to the model on EVERY turn. Measured here: Reticle at ~5.6k–14.6k tokens/turn just for
|
|
8
|
+
* definitions, which dominates a real agent loop and only grows as the tool surface grows.
|
|
9
|
+
*
|
|
10
|
+
* The `dynamic` profile advertises just TWO meta-tools (~hundreds of tokens, fixed regardless of
|
|
11
|
+
* how many real tools exist):
|
|
12
|
+
* reticle_tools — discover. No args ⇒ a compact catalog (name + one-line summary) of every tool.
|
|
13
|
+
* names:[...] ⇒ full description + params for just those tools, loaded on demand.
|
|
14
|
+
* reticle_run — invoke any tool by name. On a bad/unknown call it returns that tool's params as a
|
|
15
|
+
* hint, so the model self-corrects without ever needing the schema up front.
|
|
16
|
+
*
|
|
17
|
+
* The model lists once, loads the 2–3 tools it actually needs, and calls them — paying for tool
|
|
18
|
+
* detail only when used, not every turn. Works with any MCP client (no client-side support needed).
|
|
19
|
+
*/
|
|
20
|
+
/** First sentence (purpose) of a description — keeps the catalog one line per tool. */
|
|
21
|
+
function firstSentence(description) {
|
|
22
|
+
const nl = description.indexOf('\n');
|
|
23
|
+
const base = nl >= 0 ? description.slice(0, nl) : description;
|
|
24
|
+
const dot = base.search(/\.\s/);
|
|
25
|
+
const sentence = dot >= 0 ? base.slice(0, dot + 1) : base;
|
|
26
|
+
return sentence.length > 140 ? `${sentence.slice(0, 139)}…` : sentence;
|
|
27
|
+
}
|
|
28
|
+
/** Compact param list from a tool's zod shape — name/required/description (the description already
|
|
29
|
+
* carries the type and any enum hints, so no JSON-Schema machinery is needed). */
|
|
30
|
+
function paramInfo(shape) {
|
|
31
|
+
return Object.entries(shape).map(([name, schema]) => ({
|
|
32
|
+
name,
|
|
33
|
+
required: !schema.isOptional(),
|
|
34
|
+
description: schema.description ?? '',
|
|
35
|
+
}));
|
|
36
|
+
}
|
|
37
|
+
/**
|
|
38
|
+
* Build the two dynamic meta-tools over the full tool table. `reticle_run` dispatches through the same
|
|
39
|
+
* `runTool` chokepoint as a direct call, so session-health splicing and every other invariant hold.
|
|
40
|
+
*/
|
|
41
|
+
export function buildDynamicTools(allTools) {
|
|
42
|
+
const byName = new Map(allTools.map((t) => [t.name, t]));
|
|
43
|
+
const reticleTools = {
|
|
44
|
+
name: 'reticle_tools',
|
|
45
|
+
description: 'Discover Reticle tools on demand. Call with no arguments to list every tool (name + one-line summary); call with names:["reticle_network", …] to load full descriptions and parameters for specific tools. Then invoke them with reticle_run. This avoids paying for every tool definition on every turn.',
|
|
46
|
+
inputSchema: {
|
|
47
|
+
names: z
|
|
48
|
+
.array(z.string())
|
|
49
|
+
.optional()
|
|
50
|
+
.describe('Tool names to load full params for. Omit to list all tools with summaries.'),
|
|
51
|
+
},
|
|
52
|
+
handler: (_deps, args) => {
|
|
53
|
+
const names = Array.isArray(args['names'])
|
|
54
|
+
? args['names'].filter((n) => typeof n === 'string')
|
|
55
|
+
: undefined;
|
|
56
|
+
if (names === undefined || names.length === 0) {
|
|
57
|
+
return Promise.resolve({
|
|
58
|
+
tools: allTools.map((t) => ({ name: t.name, summary: firstSentence(t.description) })),
|
|
59
|
+
next: 'Load params with reticle_tools { names:[…] }, then call reticle_run { tool, args }.',
|
|
60
|
+
});
|
|
61
|
+
}
|
|
62
|
+
return Promise.resolve({
|
|
63
|
+
tools: names.map((n) => {
|
|
64
|
+
const t = byName.get(n);
|
|
65
|
+
return t === undefined
|
|
66
|
+
? { name: n, error: 'unknown tool' }
|
|
67
|
+
: { name: n, description: t.description, params: paramInfo(t.inputSchema) };
|
|
68
|
+
}),
|
|
69
|
+
});
|
|
70
|
+
},
|
|
71
|
+
};
|
|
72
|
+
const reticleRun = {
|
|
73
|
+
name: 'reticle_run',
|
|
74
|
+
description: "Invoke any Reticle tool by name (discover names/params first with reticle_tools). On an unknown tool or bad arguments it returns the available names or the tool's params, so you can correct and retry.",
|
|
75
|
+
inputSchema: {
|
|
76
|
+
tool: z.string().describe('Tool name to invoke, e.g. reticle_network.'),
|
|
77
|
+
args: z.record(z.unknown()).optional().describe('Arguments object for that tool.'),
|
|
78
|
+
},
|
|
79
|
+
handler: async (deps, args) => {
|
|
80
|
+
const name = typeof args['tool'] === 'string' ? args['tool'] : '';
|
|
81
|
+
const callArgs = typeof args['args'] === 'object' && args['args'] !== null
|
|
82
|
+
? args['args']
|
|
83
|
+
: {};
|
|
84
|
+
const target = byName.get(name);
|
|
85
|
+
if (target === undefined) {
|
|
86
|
+
return { error: `unknown tool '${name}'`, available: allTools.map((t) => t.name) };
|
|
87
|
+
}
|
|
88
|
+
try {
|
|
89
|
+
return await runTool(target, deps, callArgs);
|
|
90
|
+
}
|
|
91
|
+
catch (error) {
|
|
92
|
+
return {
|
|
93
|
+
error: error instanceof Error ? error.message : String(error),
|
|
94
|
+
tool: name,
|
|
95
|
+
params: paramInfo(target.inputSchema),
|
|
96
|
+
hint: 'fix the arguments and call reticle_run again',
|
|
97
|
+
};
|
|
98
|
+
}
|
|
99
|
+
},
|
|
100
|
+
};
|
|
101
|
+
return [reticleTools, reticleRun];
|
|
102
|
+
}
|
|
103
|
+
//# sourceMappingURL=dynamic-tools.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"dynamic-tools.js","sourceRoot":"","sources":["../../src/tools/dynamic-tools.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Actionable error recovery. Every tool error the agent hits should answer "what do I do next?", not
|
|
3
|
+
* just "what went wrong". This pure mapping turns a known error message into a concrete recovery hint
|
|
4
|
+
* the agent (or the human, via the agent) can act on — so the first 5 minutes never dead-end on a
|
|
5
|
+
* cryptic "no session connected". Spliced onto the error envelope at the MCP boundary (mcp.ts).
|
|
6
|
+
*
|
|
7
|
+
* Conservative by design: an unrecognized error returns `undefined` (no invented advice). Matching is
|
|
8
|
+
* on stable, human-authored substrings of the thrown messages (see session-manager.ts, the flow/
|
|
9
|
+
* baseline stores). No clock, no IO — unit-testable in isolation.
|
|
10
|
+
*/
|
|
11
|
+
/** The recovery hints, named so they are not free strings and can be asserted in tests. */
|
|
12
|
+
export declare const RECOVERY: {
|
|
13
|
+
readonly NO_SESSION: string;
|
|
14
|
+
readonly MULTIPLE_SESSIONS: string;
|
|
15
|
+
readonly UNKNOWN_SESSION: "That sessionId is not connected. Call reticle_sessions for the current ids and retry with a valid one.";
|
|
16
|
+
readonly THROTTLED: string;
|
|
17
|
+
readonly MISSING_BASELINE: string;
|
|
18
|
+
readonly MISSING_RECORDING: string;
|
|
19
|
+
readonly TOKEN_REQUIRED: string;
|
|
20
|
+
};
|
|
21
|
+
/** The actionable next move for a known error message, or undefined when none is recognized. */
|
|
22
|
+
export declare function recoveryFor(message: string): string | undefined;
|
|
23
|
+
/** The error envelope sent to the agent: the message, plus a recovery hint when one is known. */
|
|
24
|
+
interface ErrorPayload {
|
|
25
|
+
error: string;
|
|
26
|
+
recovery?: string;
|
|
27
|
+
}
|
|
28
|
+
/** Build the tool-error payload spliced at the MCP boundary — `recovery` is added only when known. */
|
|
29
|
+
export declare function buildErrorPayload(message: string): ErrorPayload;
|
|
30
|
+
export {};
|
|
31
|
+
//# sourceMappingURL=error-recovery.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"error-recovery.d.ts","sourceRoot":"","sources":["../../src/tools/error-recovery.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAEH,2FAA2F;AAC3F,eAAO,MAAM,QAAQ;;;;;;;;CAuBX,CAAC;AAaX,gGAAgG;AAChG,wBAAgB,WAAW,CAAC,OAAO,EAAE,MAAM,GAAG,MAAM,GAAG,SAAS,CAK/D;AAED,iGAAiG;AACjG,UAAU,YAAY;IACpB,KAAK,EAAE,MAAM,CAAC;IACd,QAAQ,CAAC,EAAE,MAAM,CAAC;CACnB;AAED,sGAAsG;AACtG,wBAAgB,iBAAiB,CAAC,OAAO,EAAE,MAAM,GAAG,YAAY,CAG/D"}
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Actionable error recovery. Every tool error the agent hits should answer "what do I do next?", not
|
|
3
|
+
* just "what went wrong". This pure mapping turns a known error message into a concrete recovery hint
|
|
4
|
+
* the agent (or the human, via the agent) can act on — so the first 5 minutes never dead-end on a
|
|
5
|
+
* cryptic "no session connected". Spliced onto the error envelope at the MCP boundary (mcp.ts).
|
|
6
|
+
*
|
|
7
|
+
* Conservative by design: an unrecognized error returns `undefined` (no invented advice). Matching is
|
|
8
|
+
* on stable, human-authored substrings of the thrown messages (see session-manager.ts, the flow/
|
|
9
|
+
* baseline stores). No clock, no IO — unit-testable in isolation.
|
|
10
|
+
*/
|
|
11
|
+
/** The recovery hints, named so they are not free strings and can be asserted in tests. */
|
|
12
|
+
export const RECOVERY = {
|
|
13
|
+
NO_SESSION: 'No app is connected to Reticle. Ask the human to start their app in dev with @reticlehq/browser ' +
|
|
14
|
+
'enabled, then run `reticle status` to confirm a session appears. If the app is running but no ' +
|
|
15
|
+
'session shows, the SDK is not reaching the bridge — check the dev server is up and using the ' +
|
|
16
|
+
'configured Reticle port.',
|
|
17
|
+
MULTIPLE_SESSIONS: 'Several tabs are connected. Call reticle_sessions to list them, then pass an explicit sessionId to ' +
|
|
18
|
+
'target the one you mean.',
|
|
19
|
+
UNKNOWN_SESSION: 'That sessionId is not connected. Call reticle_sessions for the current ids and retry with a valid one.',
|
|
20
|
+
THROTTLED: 'The target tab is backgrounded/throttled, so actions may silently no-op. Ask the human to bring ' +
|
|
21
|
+
'the tab to the front, or run `reticle drive <url>` for a guaranteed scriptable context.',
|
|
22
|
+
MISSING_BASELINE: 'That baseline does not exist yet. Call reticle_baseline_list to see saved names, or reticle_baseline_save ' +
|
|
23
|
+
'to capture one before diffing against it.',
|
|
24
|
+
MISSING_RECORDING: 'No recording by that name is in progress. Start one with reticle_record_start before annotating, ' +
|
|
25
|
+
'stopping, or saving it.',
|
|
26
|
+
TOKEN_REQUIRED: 'The bridge binds beyond localhost and requires a pairing token. Set the same token in the SDK ' +
|
|
27
|
+
'init (@reticlehq/core) and the Reticle server config, then reconnect.',
|
|
28
|
+
};
|
|
29
|
+
/** Ordered match rules; the first hit wins. Substrings track the thrown messages they recover. */
|
|
30
|
+
const RULES = [
|
|
31
|
+
{ match: /no browser session connected/i, hint: RECOVERY.NO_SESSION },
|
|
32
|
+
{ match: /multiple sessions connected/i, hint: RECOVERY.MULTIPLE_SESSIONS },
|
|
33
|
+
{ match: /no connected session with id/i, hint: RECOVERY.UNKNOWN_SESSION },
|
|
34
|
+
{ match: /throttled|backgrounded/i, hint: RECOVERY.THROTTLED },
|
|
35
|
+
{ match: /no baseline named/i, hint: RECOVERY.MISSING_BASELINE },
|
|
36
|
+
{ match: /no (?:active|compiled) recording named/i, hint: RECOVERY.MISSING_RECORDING },
|
|
37
|
+
{ match: /pairing token is required/i, hint: RECOVERY.TOKEN_REQUIRED },
|
|
38
|
+
];
|
|
39
|
+
/** The actionable next move for a known error message, or undefined when none is recognized. */
|
|
40
|
+
export function recoveryFor(message) {
|
|
41
|
+
for (const rule of RULES) {
|
|
42
|
+
if (rule.match.test(message))
|
|
43
|
+
return rule.hint;
|
|
44
|
+
}
|
|
45
|
+
return undefined;
|
|
46
|
+
}
|
|
47
|
+
/** Build the tool-error payload spliced at the MCP boundary — `recovery` is added only when known. */
|
|
48
|
+
export function buildErrorPayload(message) {
|
|
49
|
+
const recovery = recoveryFor(message);
|
|
50
|
+
return recovery !== undefined ? { error: message, recovery } : { error: message };
|
|
51
|
+
}
|
|
52
|
+
//# sourceMappingURL=error-recovery.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"error-recovery.js","sourceRoot":"","sources":["../../src/tools/error-recovery.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAEH,2FAA2F;AAC3F,MAAM,CAAC,MAAM,QAAQ,GAAG;IACtB,UAAU,EACR,kGAAkG;QAClG,gGAAgG;QAChG,+FAA+F;QAC/F,0BAA0B;IAC5B,iBAAiB,EACf,qGAAqG;QACrG,0BAA0B;IAC5B,eAAe,EACb,wGAAwG;IAC1G,SAAS,EACP,kGAAkG;QAClG,yFAAyF;IAC3F,gBAAgB,EACd,4GAA4G;QAC5G,2CAA2C;IAC7C,iBAAiB,EACf,mGAAmG;QACnG,yBAAyB;IAC3B,cAAc,EACZ,gGAAgG;QAChG,uEAAuE;CACjE,CAAC;AAEX,kGAAkG;AAClG,MAAM,KAAK,GAAiE;IAC1E,EAAE,KAAK,EAAE,+BAA+B,EAAE,IAAI,EAAE,QAAQ,CAAC,UAAU,EAAE;IACrE,EAAE,KAAK,EAAE,8BAA8B,EAAE,IAAI,EAAE,QAAQ,CAAC,iBAAiB,EAAE;IAC3E,EAAE,KAAK,EAAE,+BAA+B,EAAE,IAAI,EAAE,QAAQ,CAAC,eAAe,EAAE;IAC1E,EAAE,KAAK,EAAE,yBAAyB,EAAE,IAAI,EAAE,QAAQ,CAAC,SAAS,EAAE;IAC9D,EAAE,KAAK,EAAE,oBAAoB,EAAE,IAAI,EAAE,QAAQ,CAAC,gBAAgB,EAAE;IAChE,EAAE,KAAK,EAAE,yCAAyC,EAAE,IAAI,EAAE,QAAQ,CAAC,iBAAiB,EAAE;IACtF,EAAE,KAAK,EAAE,4BAA4B,EAAE,IAAI,EAAE,QAAQ,CAAC,cAAc,EAAE;CACvE,CAAC;AAEF,gGAAgG;AAChG,MAAM,UAAU,WAAW,CAAC,OAAe;IACzC,KAAK,MAAM,IAAI,IAAI,KAAK,EAAE,CAAC;QACzB,IAAI,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,OAAO,CAAC;YAAE,OAAO,IAAI,CAAC,IAAI,CAAC;IACjD,CAAC;IACD,OAAO,SAAS,CAAC;AACnB,CAAC;AAQD,sGAAsG;AACtG,MAAM,UAAU,iBAAiB,CAAC,OAAe;IAC/C,MAAM,QAAQ,GAAG,WAAW,CAAC,OAAO,CAAC,CAAC;IACtC,OAAO,QAAQ,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,KAAK,EAAE,OAAO,EAAE,QAAQ,EAAE,CAAC,CAAC,CAAC,EAAE,KAAK,EAAE,OAAO,EAAE,CAAC;AACpF,CAAC"}
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
import type { ToolDef, ToolDeps } from './tools.js';
|
|
2
|
+
/**
|
|
3
|
+
* The live-session tools whose result MUST carry the
|
|
4
|
+
* session-health envelope. Owned in ONE place — not retrofitted per handler — so a throttled tab
|
|
5
|
+
* can never return a healthy-looking result from any of these. `runTool` is the single choke point
|
|
6
|
+
* (mcp.ts + tool-invoker.ts) that splices health on; the guard test asserts the set is exhaustive.
|
|
7
|
+
*/
|
|
8
|
+
export declare const SESSION_BOUND_TOOLS: ReadonlySet<string>;
|
|
9
|
+
/**
|
|
10
|
+
* Tools that carry a `sessionId` arg but are NOT live-session-health tools — they read/write
|
|
11
|
+
* disk (capabilities/contract/flow/project), drain a buffer, or steer session lifecycle. They are
|
|
12
|
+
* exempt from the health splice ON PURPOSE. Kept explicit so the guard test can force every new
|
|
13
|
+
* `sessionId`-bearing tool to be classified into exactly one set (bound XOR exempt).
|
|
14
|
+
*/
|
|
15
|
+
export declare const SESSION_EXEMPT_TOOLS: ReadonlySet<string>;
|
|
16
|
+
/**
|
|
17
|
+
* The single entry point both the MCP server and the programmatic invoker call instead of
|
|
18
|
+
* `tool.handler` directly. Runs the handler, then — for a live-session tool returning a plain
|
|
19
|
+
* object that did not already include `session` — splices the health envelope on. Idempotent
|
|
20
|
+
* (handlers that already add health are left untouched) and never alters non-object results.
|
|
21
|
+
*/
|
|
22
|
+
export declare function runTool(tool: ToolDef, deps: ToolDeps, args: Record<string, unknown>): Promise<unknown>;
|
|
23
|
+
//# sourceMappingURL=invoke-tool.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"invoke-tool.d.ts","sourceRoot":"","sources":["../../src/tools/invoke-tool.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,OAAO,EAAE,QAAQ,EAAE,MAAM,YAAY,CAAC;AAEpD;;;;;GAKG;AACH,eAAO,MAAM,mBAAmB,EAAE,WAAW,CAAC,MAAM,CA0BlD,CAAC;AAEH;;;;;GAKG;AACH,eAAO,MAAM,oBAAoB,EAAE,WAAW,CAAC,MAAM,CAyBnD,CAAC;AAMH;;;;;GAKG;AACH,wBAAsB,OAAO,CAC3B,IAAI,EAAE,OAAO,EACb,IAAI,EAAE,QAAQ,EACd,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAC5B,OAAO,CAAC,OAAO,CAAC,CAelB"}
|
|
@@ -0,0 +1,99 @@
|
|
|
1
|
+
import { healthEnvelope } from '../session/session-health.js';
|
|
2
|
+
import { asString } from './tools-helpers.js';
|
|
3
|
+
import { ReticleTool } from './tool-names.js';
|
|
4
|
+
/**
|
|
5
|
+
* The live-session tools whose result MUST carry the
|
|
6
|
+
* session-health envelope. Owned in ONE place — not retrofitted per handler — so a throttled tab
|
|
7
|
+
* can never return a healthy-looking result from any of these. `runTool` is the single choke point
|
|
8
|
+
* (mcp.ts + tool-invoker.ts) that splices health on; the guard test asserts the set is exhaustive.
|
|
9
|
+
*/
|
|
10
|
+
export const SESSION_BOUND_TOOLS = new Set([
|
|
11
|
+
ReticleTool.SNAPSHOT,
|
|
12
|
+
ReticleTool.QUERY,
|
|
13
|
+
ReticleTool.INSPECT,
|
|
14
|
+
ReticleTool.ACT,
|
|
15
|
+
ReticleTool.ACT_SEQUENCE,
|
|
16
|
+
ReticleTool.ACT_AND_WAIT,
|
|
17
|
+
ReticleTool.OBSERVE,
|
|
18
|
+
ReticleTool.WAIT_FOR,
|
|
19
|
+
ReticleTool.ASSERT,
|
|
20
|
+
ReticleTool.NETWORK,
|
|
21
|
+
ReticleTool.CONSOLE,
|
|
22
|
+
ReticleTool.ANIMATIONS,
|
|
23
|
+
ReticleTool.BASELINE_SAVE,
|
|
24
|
+
ReticleTool.DIFF,
|
|
25
|
+
ReticleTool.RECORD_START,
|
|
26
|
+
ReticleTool.RECORD_STOP,
|
|
27
|
+
ReticleTool.REPLAY,
|
|
28
|
+
ReticleTool.NARRATE,
|
|
29
|
+
ReticleTool.CLOCK,
|
|
30
|
+
ReticleTool.STATE,
|
|
31
|
+
ReticleTool.EXPLORE,
|
|
32
|
+
ReticleTool.CRAWL,
|
|
33
|
+
ReticleTool.SCROLL_TO,
|
|
34
|
+
ReticleTool.NAVIGATE,
|
|
35
|
+
ReticleTool.REFRESH,
|
|
36
|
+
]);
|
|
37
|
+
/**
|
|
38
|
+
* Tools that carry a `sessionId` arg but are NOT live-session-health tools — they read/write
|
|
39
|
+
* disk (capabilities/contract/flow/project), drain a buffer, or steer session lifecycle. They are
|
|
40
|
+
* exempt from the health splice ON PURPOSE. Kept explicit so the guard test can force every new
|
|
41
|
+
* `sessionId`-bearing tool to be classified into exactly one set (bound XOR exempt).
|
|
42
|
+
*/
|
|
43
|
+
export const SESSION_EXEMPT_TOOLS = new Set([
|
|
44
|
+
ReticleTool.CAPABILITIES, // has a fromDisk mode with no live session
|
|
45
|
+
ReticleTool.CONTRACT_SAVE, // persists the registry to disk
|
|
46
|
+
ReticleTool.FLOW_SAVE, // sessionId only scopes the write to the app's flow subdir; disk-side
|
|
47
|
+
ReticleTool.FLOW_LIST, // sessionId only scopes which project's flows are listed; disk read
|
|
48
|
+
ReticleTool.FLOW_LOAD, // sessionId only scopes which project's flow is read; disk read
|
|
49
|
+
ReticleTool.FLOW_REPLAY, // returns its own FlowReplayResult contract (+ auto-records a run)
|
|
50
|
+
ReticleTool.FLOW_VERIFY, // returns its own SuiteVerdict contract (replays the whole suite)
|
|
51
|
+
ReticleTool.FLOW_SAVE_RECORDED, // reads the recording buffer, writes disk
|
|
52
|
+
ReticleTool.FLOW_HEAL, // returns its own FlowHealResult contract
|
|
53
|
+
ReticleTool.PROJECT, // reads .reticle/project.json
|
|
54
|
+
ReticleTool.RUN_RECORD, // writes .reticle/project.json
|
|
55
|
+
ReticleTool.RUN_EXPORT, // reads .reticle/runs/<id>.json (verification-run artifact)
|
|
56
|
+
ReticleTool.END_SESSION, // live-control lifecycle
|
|
57
|
+
ReticleTool.YIELD, // live-control lifecycle (hand back to the human between turns)
|
|
58
|
+
ReticleTool.RESUME, // live-control lifecycle
|
|
59
|
+
ReticleTool.MESSAGES, // drains the human→agent inbox
|
|
60
|
+
ReticleTool.REVIEW, // lists/resolves human review marks; own contract, no live-DOM read
|
|
61
|
+
ReticleTool.SESSION, // tunes the presenter session (idle-end); own contract
|
|
62
|
+
ReticleTool.SCREENSHOT, // own contract; provider-driven, not a live-DOM-health read
|
|
63
|
+
ReticleTool.VISUAL_DIFF, // own contract (matched/ratio/region)
|
|
64
|
+
ReticleTool.NETWORK_MOCK, // own contract (applied/count); provider-driven, not a live-DOM read
|
|
65
|
+
ReticleTool.VIEWPORT, // own contract (applied/width/height); provider-driven, not a live-DOM read
|
|
66
|
+
ReticleTool.ANNOTATE, // annotates a recording's steps; pure disk-side metadata, no live DOM read
|
|
67
|
+
ReticleTool.LEASE_RELEASE, // its sessionId is a pool lease id, not a live session; no health splice
|
|
68
|
+
]);
|
|
69
|
+
function isPlainObject(value) {
|
|
70
|
+
return typeof value === 'object' && value !== null && !Array.isArray(value);
|
|
71
|
+
}
|
|
72
|
+
/**
|
|
73
|
+
* The single entry point both the MCP server and the programmatic invoker call instead of
|
|
74
|
+
* `tool.handler` directly. Runs the handler, then — for a live-session tool returning a plain
|
|
75
|
+
* object that did not already include `session` — splices the health envelope on. Idempotent
|
|
76
|
+
* (handlers that already add health are left untouched) and never alters non-object results.
|
|
77
|
+
*/
|
|
78
|
+
export async function runTool(tool, deps, args) {
|
|
79
|
+
// Heartbeat: any tool call targeting a leased session keeps its pool lease alive, so the
|
|
80
|
+
// LeaseReaper only reclaims genuinely orphaned (crashed/hung-agent) leases.
|
|
81
|
+
const targetSession = asString(args['sessionId']);
|
|
82
|
+
if (targetSession !== undefined)
|
|
83
|
+
deps.pool?.touch(targetSession);
|
|
84
|
+
const result = await tool.handler(deps, args);
|
|
85
|
+
if (!SESSION_BOUND_TOOLS.has(tool.name))
|
|
86
|
+
return result;
|
|
87
|
+
if (!isPlainObject(result) || 'session' in result)
|
|
88
|
+
return result;
|
|
89
|
+
const session = deps.sessions.resolve(asString(args['sessionId']));
|
|
90
|
+
const envelope = { ...healthEnvelope(session) };
|
|
91
|
+
const lease = session.takeSessionLease();
|
|
92
|
+
if (lease !== undefined)
|
|
93
|
+
envelope['session_lease'] = lease;
|
|
94
|
+
const warning = session.ageWarning();
|
|
95
|
+
if (warning !== undefined)
|
|
96
|
+
envelope['session_age_warning'] = warning;
|
|
97
|
+
return { ...result, ...envelope };
|
|
98
|
+
}
|
|
99
|
+
//# sourceMappingURL=invoke-tool.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"invoke-tool.js","sourceRoot":"","sources":["../../src/tools/invoke-tool.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Lease tools — the agent-facing surface of the BrowserPool.
|
|
3
|
+
*
|
|
4
|
+
* `reticle_lease_acquire` opens a fresh isolated headless context navigated to the app URL and returns
|
|
5
|
+
* the sessionId the app's SDK will register (stamped via __reticle_session so the lease and the session
|
|
6
|
+
* correlate 1:1). This is the "one of 10 flows" entry point: 10 agents acquire 10 leases, the pool
|
|
7
|
+
* keeps them in ONE browser, capped and queued. `reticle_lease_release` frees the slot.
|
|
8
|
+
*
|
|
9
|
+
* Attach-only: the pool drives a browser against an already-running dev server — it never starts one.
|
|
10
|
+
*/
|
|
11
|
+
import type { ToolDef } from './tool-kit.js';
|
|
12
|
+
/**
|
|
13
|
+
* Append Reticle identity params (__reticle_session, optional __reticle_project) to a URL so the app's own SDK
|
|
14
|
+
* adopts them on connect. Pure; falls back to plain concatenation if the URL can't be parsed.
|
|
15
|
+
*/
|
|
16
|
+
export declare function appendReticleParams(url: string, session: string, projectId?: string): string;
|
|
17
|
+
/**
|
|
18
|
+
* Turn a raw navigation failure (Playwright's `page.goto: net::ERR_… at <url>\nCall log:…`, often
|
|
19
|
+
* with ANSI codes) into a short, clean reason — so the agent/user sees "is the app running?" instead
|
|
20
|
+
* of an internals-leaking wall of text.
|
|
21
|
+
*/
|
|
22
|
+
export declare function cleanNavError(err: unknown): string;
|
|
23
|
+
/**
|
|
24
|
+
* Poll until the leased tab's SDK has actually registered on the bridge, so the sessionId we return
|
|
25
|
+
* is immediately usable (the page navigates first, then connects a moment later — without this wait
|
|
26
|
+
* an agent's very next call could race and hit "no connected session"). Returns whether it connected
|
|
27
|
+
* in time. `isConnected`, `sleeper`, and `attempts` are injected so this is fast to unit-test.
|
|
28
|
+
*/
|
|
29
|
+
export declare function waitForLeasedSession(isConnected: () => boolean, sleeper?: (ms: number) => Promise<void>, attempts?: number, pollMs?: number): Promise<boolean>;
|
|
30
|
+
export declare const LEASE_TOOLS: ToolDef[];
|
|
31
|
+
//# sourceMappingURL=lease-tools.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"lease-tools.d.ts","sourceRoot":"","sources":["../../src/tools/lease-tools.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAKH,OAAO,KAAK,EAAE,OAAO,EAAY,MAAM,eAAe,CAAC;AAMvD;;;GAGG;AACH,wBAAgB,mBAAmB,CAAC,GAAG,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,EAAE,SAAS,CAAC,EAAE,MAAM,GAAG,MAAM,CAgB5F;AAED;;;;GAIG;AACH,wBAAgB,aAAa,CAAC,GAAG,EAAE,OAAO,GAAG,MAAM,CAclD;AAeD;;;;;GAKG;AACH,wBAAsB,oBAAoB,CACxC,WAAW,EAAE,MAAM,OAAO,EAC1B,OAAO,GAAE,CAAC,EAAE,EAAE,MAAM,KAAK,OAAO,CAAC,IAAI,CAAS,EAC9C,QAAQ,GAAE,MAA6B,EACvC,MAAM,GAAE,MAA4B,GACnC,OAAO,CAAC,OAAO,CAAC,CAMlB;AAED,eAAO,MAAM,WAAW,EAAE,OAAO,EAuFhC,CAAC"}
|
|
@@ -0,0 +1,164 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Lease tools — the agent-facing surface of the BrowserPool.
|
|
3
|
+
*
|
|
4
|
+
* `reticle_lease_acquire` opens a fresh isolated headless context navigated to the app URL and returns
|
|
5
|
+
* the sessionId the app's SDK will register (stamped via __reticle_session so the lease and the session
|
|
6
|
+
* correlate 1:1). This is the "one of 10 flows" entry point: 10 agents acquire 10 leases, the pool
|
|
7
|
+
* keeps them in ONE browser, capped and queued. `reticle_lease_release` frees the slot.
|
|
8
|
+
*
|
|
9
|
+
* Attach-only: the pool drives a browser against an already-running dev server — it never starts one.
|
|
10
|
+
*/
|
|
11
|
+
import { z } from 'zod';
|
|
12
|
+
import { RETICLE_URL_PARAM } from '@reticlehq/core';
|
|
13
|
+
import { ReticleTool } from './tool-names.js';
|
|
14
|
+
import { asString } from './tools-helpers.js';
|
|
15
|
+
const POOL_UNAVAILABLE = 'browser pool unavailable — the lease tools need the daemon-managed pool (start Reticle via `reticle mcp`).';
|
|
16
|
+
/**
|
|
17
|
+
* Append Reticle identity params (__reticle_session, optional __reticle_project) to a URL so the app's own SDK
|
|
18
|
+
* adopts them on connect. Pure; falls back to plain concatenation if the URL can't be parsed.
|
|
19
|
+
*/
|
|
20
|
+
export function appendReticleParams(url, session, projectId) {
|
|
21
|
+
try {
|
|
22
|
+
const u = new URL(url);
|
|
23
|
+
u.searchParams.set(RETICLE_URL_PARAM.SESSION, session);
|
|
24
|
+
if (projectId !== undefined && projectId.length > 0) {
|
|
25
|
+
u.searchParams.set(RETICLE_URL_PARAM.PROJECT, projectId);
|
|
26
|
+
}
|
|
27
|
+
return u.toString();
|
|
28
|
+
}
|
|
29
|
+
catch {
|
|
30
|
+
const sep = url.includes('?') ? '&' : '?';
|
|
31
|
+
const proj = projectId !== undefined && projectId.length > 0
|
|
32
|
+
? `&${RETICLE_URL_PARAM.PROJECT}=${encodeURIComponent(projectId)}`
|
|
33
|
+
: '';
|
|
34
|
+
return `${url}${sep}${RETICLE_URL_PARAM.SESSION}=${encodeURIComponent(session)}${proj}`;
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
/**
|
|
38
|
+
* Turn a raw navigation failure (Playwright's `page.goto: net::ERR_… at <url>\nCall log:…`, often
|
|
39
|
+
* with ANSI codes) into a short, clean reason — so the agent/user sees "is the app running?" instead
|
|
40
|
+
* of an internals-leaking wall of text.
|
|
41
|
+
*/
|
|
42
|
+
export function cleanNavError(err) {
|
|
43
|
+
const msg = err instanceof Error ? err.message : String(err);
|
|
44
|
+
// Strip ANSI color codes (ESC[…m) Playwright emits — built via fromCharCode to keep the
|
|
45
|
+
// control character out of a regex literal (no-control-regex).
|
|
46
|
+
const ansi = new RegExp(`${String.fromCharCode(27)}\\[[0-9;]*m`, 'g');
|
|
47
|
+
const firstLine = (msg.split('\n')[0] ?? msg).replace(ansi, '');
|
|
48
|
+
const netCode = /net::[A-Z_]+/.exec(firstLine);
|
|
49
|
+
if (netCode !== null)
|
|
50
|
+
return netCode[0];
|
|
51
|
+
if (/timeout/i.test(firstLine))
|
|
52
|
+
return 'navigation timed out';
|
|
53
|
+
return firstLine
|
|
54
|
+
.replace(/^page\.goto:\s*/, '')
|
|
55
|
+
.replace(/\s+at\s+https?:\/\/\S+.*$/, '')
|
|
56
|
+
.trim()
|
|
57
|
+
.slice(0, 100);
|
|
58
|
+
}
|
|
59
|
+
/** A fresh, collision-resistant lease id. Uses crypto at the I/O boundary (not pure logic). */
|
|
60
|
+
function newLeaseId() {
|
|
61
|
+
const uuid = typeof globalThis.crypto?.randomUUID === 'function'
|
|
62
|
+
? globalThis.crypto.randomUUID()
|
|
63
|
+
: `${String(Date.now())}-${String(performance.now())}`;
|
|
64
|
+
return `lease-${uuid}`;
|
|
65
|
+
}
|
|
66
|
+
const LEASE_READY_ATTEMPTS = 100;
|
|
67
|
+
const LEASE_READY_POLL_MS = 100;
|
|
68
|
+
const sleep = (ms) => new Promise((r) => setTimeout(r, ms));
|
|
69
|
+
/**
|
|
70
|
+
* Poll until the leased tab's SDK has actually registered on the bridge, so the sessionId we return
|
|
71
|
+
* is immediately usable (the page navigates first, then connects a moment later — without this wait
|
|
72
|
+
* an agent's very next call could race and hit "no connected session"). Returns whether it connected
|
|
73
|
+
* in time. `isConnected`, `sleeper`, and `attempts` are injected so this is fast to unit-test.
|
|
74
|
+
*/
|
|
75
|
+
export async function waitForLeasedSession(isConnected, sleeper = sleep, attempts = LEASE_READY_ATTEMPTS, pollMs = LEASE_READY_POLL_MS) {
|
|
76
|
+
for (let i = 0; i < attempts; i++) {
|
|
77
|
+
if (isConnected())
|
|
78
|
+
return true;
|
|
79
|
+
await sleeper(pollMs);
|
|
80
|
+
}
|
|
81
|
+
return isConnected();
|
|
82
|
+
}
|
|
83
|
+
export const LEASE_TOOLS = [
|
|
84
|
+
{
|
|
85
|
+
name: ReticleTool.LEASE_ACQUIRE,
|
|
86
|
+
description: 'Lease a fresh isolated headless browser context from the shared pool and navigate it to the app URL (the app must already be running and embed @reticlehq/core). Returns the sessionId the leased tab registers — pass it to other tools. The pool keeps all leases in ONE browser and caps concurrency; if at capacity this waits for a free slot. Release with reticle_lease_release when the flow is done.',
|
|
87
|
+
inputSchema: {
|
|
88
|
+
url: z
|
|
89
|
+
.string()
|
|
90
|
+
.describe('URL of the already-running app to drive (e.g. http://localhost:3000/dashboard).'),
|
|
91
|
+
projectId: z
|
|
92
|
+
.string()
|
|
93
|
+
.optional()
|
|
94
|
+
.describe('Stable project id to stamp on the leased tab so the agent can scope to it.'),
|
|
95
|
+
},
|
|
96
|
+
outputSchema: {
|
|
97
|
+
sessionId: z.string(),
|
|
98
|
+
url: z.string(),
|
|
99
|
+
ready: z
|
|
100
|
+
.boolean()
|
|
101
|
+
.describe('Whether the leased tab connected — false ⇒ the app may not embed @reticlehq/core.'),
|
|
102
|
+
leased: z.number().describe('How many contexts are currently leased from the pool.'),
|
|
103
|
+
queued: z.number().describe('How many acquires are waiting for a free slot.'),
|
|
104
|
+
hint: z.string().optional(),
|
|
105
|
+
},
|
|
106
|
+
handler: async (deps, args) => {
|
|
107
|
+
const pool = deps.pool;
|
|
108
|
+
if (pool === undefined)
|
|
109
|
+
throw new Error(POOL_UNAVAILABLE);
|
|
110
|
+
const url = asString(args['url']);
|
|
111
|
+
if (url === undefined || url.length === 0)
|
|
112
|
+
throw new Error('reticle_lease_acquire requires a url');
|
|
113
|
+
const projectId = asString(args['projectId']);
|
|
114
|
+
const sessionId = newLeaseId();
|
|
115
|
+
const navUrl = appendReticleParams(url, sessionId, projectId);
|
|
116
|
+
let lease;
|
|
117
|
+
try {
|
|
118
|
+
lease = await pool.acquire(navUrl, { sessionId });
|
|
119
|
+
}
|
|
120
|
+
catch (err) {
|
|
121
|
+
// A raw page.goto failure is noisy and leaks the internal URL params — surface a clean,
|
|
122
|
+
// actionable message instead.
|
|
123
|
+
throw new Error(`could not open ${url} — is the app running there? (${cleanNavError(err)})`);
|
|
124
|
+
}
|
|
125
|
+
// Wait for the leased tab's SDK to connect so the returned sessionId is usable right away.
|
|
126
|
+
const ready = await waitForLeasedSession(() => deps.sessions.get(lease.sessionId) !== undefined);
|
|
127
|
+
return {
|
|
128
|
+
sessionId: lease.sessionId,
|
|
129
|
+
url,
|
|
130
|
+
ready,
|
|
131
|
+
leased: pool.activeCount(),
|
|
132
|
+
queued: pool.queuedCount(),
|
|
133
|
+
...(ready
|
|
134
|
+
? {}
|
|
135
|
+
: {
|
|
136
|
+
hint: `leased tab did not connect — is ${url} running with @reticlehq/core enabled?`,
|
|
137
|
+
}),
|
|
138
|
+
};
|
|
139
|
+
},
|
|
140
|
+
},
|
|
141
|
+
{
|
|
142
|
+
name: ReticleTool.LEASE_RELEASE,
|
|
143
|
+
description: 'Release a leased browser context by sessionId, closing it and freeing the pool slot for a queued acquire. Call this when a flow finishes so the pool stays within its concurrency cap.',
|
|
144
|
+
inputSchema: {
|
|
145
|
+
sessionId: z.string().describe('The leased sessionId returned by reticle_lease_acquire.'),
|
|
146
|
+
},
|
|
147
|
+
outputSchema: {
|
|
148
|
+
released: z.boolean(),
|
|
149
|
+
leased: z.number(),
|
|
150
|
+
},
|
|
151
|
+
handler: async (deps, args) => {
|
|
152
|
+
const pool = deps.pool;
|
|
153
|
+
if (pool === undefined)
|
|
154
|
+
throw new Error(POOL_UNAVAILABLE);
|
|
155
|
+
const sessionId = asString(args['sessionId']);
|
|
156
|
+
if (sessionId === undefined || sessionId.length === 0) {
|
|
157
|
+
throw new Error('reticle_lease_release requires a sessionId');
|
|
158
|
+
}
|
|
159
|
+
await pool.release(sessionId);
|
|
160
|
+
return { released: true, leased: pool.activeCount() };
|
|
161
|
+
},
|
|
162
|
+
},
|
|
163
|
+
];
|
|
164
|
+
//# sourceMappingURL=lease-tools.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"lease-tools.js","sourceRoot":"","sources":["../../src/tools/lease-tools.ts"],"names":[],"mappings":"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"}
|