@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,56 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* ReticleRunner — the programmatic Replay/Verify API a host platform (OEM/design partner) or CI drives
|
|
3
|
+
* from its own pipeline, with no MCP stdio and no human. It reuses the existing flow-replay machinery
|
|
4
|
+
* and the verification-run assembler, returning a stable ReticleVerificationRun.
|
|
5
|
+
*
|
|
6
|
+
* Everything it needs from the live world is injected through RunnerPort, so the core orchestration is
|
|
7
|
+
* fully testable without a CDP browser. The live adapter (wrapping ToolDeps: replayNamedFlow,
|
|
8
|
+
* flows.list, the drive/CDP preview boot) and the token-guarded HTTP endpoint are thin layers built on
|
|
9
|
+
* top of this — the orchestration and the verdict live here so the MCP path and the API produce the
|
|
10
|
+
* same artifact byte-for-byte.
|
|
11
|
+
*/
|
|
12
|
+
import { buildVerificationRun } from './build-verification-run.js';
|
|
13
|
+
import { mapReplayToFlowResult } from './replay-mapping.js';
|
|
14
|
+
import { buildRepairPackets } from './repair-prompt.js';
|
|
15
|
+
import { buildRisks, classifyChangedFiles, } from './risk-classify.js';
|
|
16
|
+
export class ReticleRunner {
|
|
17
|
+
#port;
|
|
18
|
+
constructor(port) {
|
|
19
|
+
this.#port = port;
|
|
20
|
+
}
|
|
21
|
+
/**
|
|
22
|
+
* Replay the named flows (or every saved flow), map each outcome into the artifact, and assemble a
|
|
23
|
+
* verdict. Sequential by design — flows share the one live app and parallel replay would race the
|
|
24
|
+
* DOM (the same reason reticle_flow_verify is sequential).
|
|
25
|
+
*/
|
|
26
|
+
async verify(opts) {
|
|
27
|
+
const names = opts.names ?? (await this.#port.listFlows());
|
|
28
|
+
const replays = [];
|
|
29
|
+
const flows = [];
|
|
30
|
+
for (const name of names) {
|
|
31
|
+
const start = this.#port.now();
|
|
32
|
+
const replay = await this.#port.replayFlow(name);
|
|
33
|
+
replays.push(replay);
|
|
34
|
+
flows.push(mapReplayToFlowResult(replay, this.#port.now() - start));
|
|
35
|
+
}
|
|
36
|
+
const changedFiles = classifyChangedFiles(opts.changedFiles ?? []);
|
|
37
|
+
const risks = buildRisks(changedFiles, opts.policy);
|
|
38
|
+
const failurePackets = buildRepairPackets(replays);
|
|
39
|
+
const input = {
|
|
40
|
+
runId: this.#port.newRunId(),
|
|
41
|
+
durationMs: flows.reduce((sum, f) => sum + f.durationMs, 0),
|
|
42
|
+
profile: opts.profile,
|
|
43
|
+
project: opts.project,
|
|
44
|
+
agent: opts.agent,
|
|
45
|
+
trigger: opts.trigger,
|
|
46
|
+
changedFiles,
|
|
47
|
+
flows,
|
|
48
|
+
checks: [],
|
|
49
|
+
risks,
|
|
50
|
+
evidence: { consoleErrors: [], networkAnomalies: [], stateAssertions: [], timeline: [] },
|
|
51
|
+
...(failurePackets.length > 0 ? { repair: { failurePackets } } : {}),
|
|
52
|
+
};
|
|
53
|
+
return buildVerificationRun(input, () => this.#port.now());
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
//# sourceMappingURL=reticle-runner.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"reticle-runner.js","sourceRoot":"","sources":["../../src/runs/reticle-runner.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AAGH,OAAO,EAAE,oBAAoB,EAA6B,MAAM,6BAA6B,CAAC;AAC9F,OAAO,EAAE,qBAAqB,EAAE,MAAM,qBAAqB,CAAC;AAC5D,OAAO,EAAE,kBAAkB,EAAE,MAAM,oBAAoB,CAAC;AACxD,OAAO,EACL,UAAU,EACV,oBAAoB,GAGrB,MAAM,oBAAoB,CAAC;AA2B5B,MAAM,OAAO,aAAa;IACf,KAAK,CAAa;IAE3B,YAAY,IAAgB;QAC1B,IAAI,CAAC,KAAK,GAAG,IAAI,CAAC;IACpB,CAAC;IAED;;;;OAIG;IACH,KAAK,CAAC,MAAM,CAAC,IAAmB;QAC9B,MAAM,KAAK,GAAG,IAAI,CAAC,KAAK,IAAI,CAAC,MAAM,IAAI,CAAC,KAAK,CAAC,SAAS,EAAE,CAAC,CAAC;QAC3D,MAAM,OAAO,GAAG,EAAE,CAAC;QACnB,MAAM,KAAK,GAAG,EAAE,CAAC;QACjB,KAAK,MAAM,IAAI,IAAI,KAAK,EAAE,CAAC;YACzB,MAAM,KAAK,GAAG,IAAI,CAAC,KAAK,CAAC,GAAG,EAAE,CAAC;YAC/B,MAAM,MAAM,GAAG,MAAM,IAAI,CAAC,KAAK,CAAC,UAAU,CAAC,IAAI,CAAC,CAAC;YACjD,OAAO,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;YACrB,KAAK,CAAC,IAAI,CAAC,qBAAqB,CAAC,MAAM,EAAE,IAAI,CAAC,KAAK,CAAC,GAAG,EAAE,GAAG,KAAK,CAAC,CAAC,CAAC;QACtE,CAAC;QAED,MAAM,YAAY,GAAG,oBAAoB,CAAC,IAAI,CAAC,YAAY,IAAI,EAAE,CAAC,CAAC;QACnE,MAAM,KAAK,GAAG,UAAU,CAAC,YAAY,EAAE,IAAI,CAAC,MAAM,CAAC,CAAC;QACpD,MAAM,cAAc,GAAG,kBAAkB,CAAC,OAAO,CAAC,CAAC;QAEnD,MAAM,KAAK,GAAyB;YAClC,KAAK,EAAE,IAAI,CAAC,KAAK,CAAC,QAAQ,EAAE;YAC5B,UAAU,EAAE,KAAK,CAAC,MAAM,CAAC,CAAC,GAAG,EAAE,CAAC,EAAE,EAAE,CAAC,GAAG,GAAG,CAAC,CAAC,UAAU,EAAE,CAAC,CAAC;YAC3D,OAAO,EAAE,IAAI,CAAC,OAAO;YACrB,OAAO,EAAE,IAAI,CAAC,OAAO;YACrB,KAAK,EAAE,IAAI,CAAC,KAAK;YACjB,OAAO,EAAE,IAAI,CAAC,OAAO;YACrB,YAAY;YACZ,KAAK;YACL,MAAM,EAAE,EAAE;YACV,KAAK;YACL,QAAQ,EAAE,EAAE,aAAa,EAAE,EAAE,EAAE,gBAAgB,EAAE,EAAE,EAAE,eAAe,EAAE,EAAE,EAAE,QAAQ,EAAE,EAAE,EAAE;YACxF,GAAG,CAAC,cAAc,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC,EAAE,MAAM,EAAE,EAAE,cAAc,EAAE,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;SACrE,CAAC;QACF,OAAO,oBAAoB,CAAC,KAAK,EAAE,GAAG,EAAE,CAAC,IAAI,CAAC,KAAK,CAAC,GAAG,EAAE,CAAC,CAAC;IAC7D,CAAC;CACF"}
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Risk classification — map a change set onto the risk surfaces a host must reason about before
|
|
3
|
+
* shipping generated software (the surfaces real AI-app-builder incidents cluster around: production
|
|
4
|
+
* data loss, auth/payment/RLS/secrets mistakes). Pure + heuristic: path patterns → surfaces now,
|
|
5
|
+
* refine later. A RiskPolicy marks chosen surfaces as gated, which the verdict turns into blocking
|
|
6
|
+
* risks. Every pattern is a named constant (no free strings / inline regexes scattered around).
|
|
7
|
+
*/
|
|
8
|
+
import { RiskSurface, RunChangeKind, type RunChangedFile, type RunRisk } from '@reticlehq/core';
|
|
9
|
+
/** The risk surfaces a single path implicates (unique, stable order = RISK_PATTERNS order). */
|
|
10
|
+
export declare function risksForPath(path: string): RiskSurface[];
|
|
11
|
+
/** A change set Reticle was told about (the live wiring derives this from the diff). */
|
|
12
|
+
export interface ChangedFileInput {
|
|
13
|
+
path: string;
|
|
14
|
+
changeKind: RunChangeKind;
|
|
15
|
+
}
|
|
16
|
+
/** Policy: which surfaces, if touched, block the verdict (require human confirmation). */
|
|
17
|
+
export interface RiskPolicy {
|
|
18
|
+
requiresConfirmation?: RiskSurface[];
|
|
19
|
+
}
|
|
20
|
+
/** Tag each changed file with the surfaces it touches (for the artifact's changedFiles[]). */
|
|
21
|
+
export declare function classifyChangedFiles(files: ReadonlyArray<ChangedFileInput>): RunChangedFile[];
|
|
22
|
+
/**
|
|
23
|
+
* Collapse the per-file surfaces into one risk row per surface (deduped across the change set), with
|
|
24
|
+
* severity and a gated flag driven by the policy. This is what the verdict counts as blocking.
|
|
25
|
+
*/
|
|
26
|
+
export declare function buildRisks(changedFiles: ReadonlyArray<RunChangedFile>, policy?: RiskPolicy): RunRisk[];
|
|
27
|
+
//# sourceMappingURL=risk-classify.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"risk-classify.d.ts","sourceRoot":"","sources":["../../src/runs/risk-classify.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,OAAO,EAEL,WAAW,EACX,aAAa,EACb,KAAK,cAAc,EACnB,KAAK,OAAO,EACb,MAAM,iBAAiB,CAAC;AAmCzB,+FAA+F;AAC/F,wBAAgB,YAAY,CAAC,IAAI,EAAE,MAAM,GAAG,WAAW,EAAE,CAExD;AAED,wFAAwF;AACxF,MAAM,WAAW,gBAAgB;IAC/B,IAAI,EAAE,MAAM,CAAC;IACb,UAAU,EAAE,aAAa,CAAC;CAC3B;AAED,0FAA0F;AAC1F,MAAM,WAAW,UAAU;IACzB,oBAAoB,CAAC,EAAE,WAAW,EAAE,CAAC;CACtC;AAED,8FAA8F;AAC9F,wBAAgB,oBAAoB,CAAC,KAAK,EAAE,aAAa,CAAC,gBAAgB,CAAC,GAAG,cAAc,EAAE,CAE7F;AAED;;;GAGG;AACH,wBAAgB,UAAU,CACxB,YAAY,EAAE,aAAa,CAAC,cAAc,CAAC,EAC3C,MAAM,GAAE,UAAe,GACtB,OAAO,EAAE,CAuBX"}
|
|
@@ -0,0 +1,76 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Risk classification — map a change set onto the risk surfaces a host must reason about before
|
|
3
|
+
* shipping generated software (the surfaces real AI-app-builder incidents cluster around: production
|
|
4
|
+
* data loss, auth/payment/RLS/secrets mistakes). Pure + heuristic: path patterns → surfaces now,
|
|
5
|
+
* refine later. A RiskPolicy marks chosen surfaces as gated, which the verdict turns into blocking
|
|
6
|
+
* risks. Every pattern is a named constant (no free strings / inline regexes scattered around).
|
|
7
|
+
*/
|
|
8
|
+
import { RiskSeverity, RiskSurface, RunChangeKind, } from '@reticlehq/core';
|
|
9
|
+
/** Path heuristics per surface. Order is irrelevant — a path may match several surfaces. */
|
|
10
|
+
const RISK_PATTERNS = [
|
|
11
|
+
{
|
|
12
|
+
surface: RiskSurface.AUTH,
|
|
13
|
+
pattern: /(\bauth\b|login|logout|sign-?in|sign-?up|session|oauth|jwt|password)/i,
|
|
14
|
+
},
|
|
15
|
+
{
|
|
16
|
+
surface: RiskSurface.PAYMENT,
|
|
17
|
+
pattern: /(payment|checkout|stripe|billing|invoice|charge|subscription)/i,
|
|
18
|
+
},
|
|
19
|
+
{
|
|
20
|
+
surface: RiskSurface.DB,
|
|
21
|
+
pattern: /(schema\.|prisma|drizzle|\bdb\b|database|\.sql$|repository)/i,
|
|
22
|
+
},
|
|
23
|
+
{ surface: RiskSurface.MIGRATION, pattern: /(migration|migrate)/i },
|
|
24
|
+
{ surface: RiskSurface.RLS, pattern: /(\brls\b|row-?level|policy\.sql|policies)/i },
|
|
25
|
+
{ surface: RiskSurface.SECRETS, pattern: /(\.env|secret|api[-_]?key|credential|\btoken\b)/i },
|
|
26
|
+
{ surface: RiskSurface.DESTRUCTIVE, pattern: /(delete|destroy|\bdrop\b|truncate|purge|wipe)/i },
|
|
27
|
+
{ surface: RiskSurface.EXTERNAL, pattern: /(webhook|external|third-?party|integration)/i },
|
|
28
|
+
];
|
|
29
|
+
/** Severity per surface — the "how bad if this is wrong" floor. */
|
|
30
|
+
const SURFACE_SEVERITY = {
|
|
31
|
+
[RiskSurface.AUTH]: RiskSeverity.HIGH,
|
|
32
|
+
[RiskSurface.PAYMENT]: RiskSeverity.CRITICAL,
|
|
33
|
+
[RiskSurface.DB]: RiskSeverity.HIGH,
|
|
34
|
+
[RiskSurface.MIGRATION]: RiskSeverity.HIGH,
|
|
35
|
+
[RiskSurface.RLS]: RiskSeverity.CRITICAL,
|
|
36
|
+
[RiskSurface.SECRETS]: RiskSeverity.CRITICAL,
|
|
37
|
+
[RiskSurface.DESTRUCTIVE]: RiskSeverity.HIGH,
|
|
38
|
+
[RiskSurface.EXTERNAL]: RiskSeverity.MEDIUM,
|
|
39
|
+
};
|
|
40
|
+
/** The risk surfaces a single path implicates (unique, stable order = RISK_PATTERNS order). */
|
|
41
|
+
export function risksForPath(path) {
|
|
42
|
+
return RISK_PATTERNS.filter((r) => r.pattern.test(path)).map((r) => r.surface);
|
|
43
|
+
}
|
|
44
|
+
/** Tag each changed file with the surfaces it touches (for the artifact's changedFiles[]). */
|
|
45
|
+
export function classifyChangedFiles(files) {
|
|
46
|
+
return files.map((f) => ({ path: f.path, changeKind: f.changeKind, risk: risksForPath(f.path) }));
|
|
47
|
+
}
|
|
48
|
+
/**
|
|
49
|
+
* Collapse the per-file surfaces into one risk row per surface (deduped across the change set), with
|
|
50
|
+
* severity and a gated flag driven by the policy. This is what the verdict counts as blocking.
|
|
51
|
+
*/
|
|
52
|
+
export function buildRisks(changedFiles, policy = {}) {
|
|
53
|
+
const gatedSet = new Set(policy.requiresConfirmation ?? []);
|
|
54
|
+
const filesBySurface = new Map();
|
|
55
|
+
for (const file of changedFiles) {
|
|
56
|
+
for (const surface of file.risk) {
|
|
57
|
+
const list = filesBySurface.get(surface) ?? [];
|
|
58
|
+
list.push(file.path);
|
|
59
|
+
filesBySurface.set(surface, list);
|
|
60
|
+
}
|
|
61
|
+
}
|
|
62
|
+
const risks = [];
|
|
63
|
+
for (const { surface } of RISK_PATTERNS) {
|
|
64
|
+
const files = filesBySurface.get(surface);
|
|
65
|
+
if (files === undefined || files.length === 0)
|
|
66
|
+
continue;
|
|
67
|
+
risks.push({
|
|
68
|
+
surface,
|
|
69
|
+
severity: SURFACE_SEVERITY[surface],
|
|
70
|
+
detail: `${files.length} changed file(s) touch the ${surface} surface (e.g. ${files[0]})`,
|
|
71
|
+
gated: gatedSet.has(surface),
|
|
72
|
+
});
|
|
73
|
+
}
|
|
74
|
+
return risks;
|
|
75
|
+
}
|
|
76
|
+
//# sourceMappingURL=risk-classify.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"risk-classify.js","sourceRoot":"","sources":["../../src/runs/risk-classify.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Persistence for verification-run artifacts at .reticle/runs/<runId>.json. Mirrors ProjectStore:
|
|
3
|
+
* injected FileSystemPort, never-throws read, path-segment guard on the runId (the tool-arg attack
|
|
4
|
+
* surface). One artifact per file (unlike project.json's single rolling file) so a host can attach an
|
|
5
|
+
* individual run to a deploy. The run is already clock-stamped by buildVerificationRun, so the store
|
|
6
|
+
* needs no clock.
|
|
7
|
+
*/
|
|
8
|
+
import { RunReadError, type ReticleVerificationRun, type RunId } from '@reticlehq/core';
|
|
9
|
+
import type { FileSystemPort } from '../project/fs-port.js';
|
|
10
|
+
/** Never-throws read result (mirrors ReadProjectResult). */
|
|
11
|
+
export type ReadRunResult = {
|
|
12
|
+
ok: true;
|
|
13
|
+
run: ReticleVerificationRun;
|
|
14
|
+
} | {
|
|
15
|
+
ok: false;
|
|
16
|
+
reason: RunReadError;
|
|
17
|
+
};
|
|
18
|
+
/** Optional retention overrides (defaults to the protocol caps). Injectable so tests prune fast. */
|
|
19
|
+
interface RunStoreOptions {
|
|
20
|
+
retention?: number;
|
|
21
|
+
slack?: number;
|
|
22
|
+
}
|
|
23
|
+
export declare class RunStore {
|
|
24
|
+
#private;
|
|
25
|
+
constructor(fs: FileSystemPort, root: string, opts?: RunStoreOptions);
|
|
26
|
+
/**
|
|
27
|
+
* Write one run artifact. Creates .reticle/runs/ first; byte-stable (fixed indent + trailing newline).
|
|
28
|
+
* Guards runId as a safe path segment BEFORE building the path — a runId can originate from a caller
|
|
29
|
+
* (an OEM may set it), so an unsafe value must never escape .reticle/runs/ (mirrors the read guard).
|
|
30
|
+
*/
|
|
31
|
+
write(run: ReticleVerificationRun): Promise<void>;
|
|
32
|
+
/** Never throws. Invalid id / missing → MISSING; bad JSON or failed schema → MALFORMED. */
|
|
33
|
+
read(runId: RunId): Promise<ReadRunResult>;
|
|
34
|
+
/** List run ids on disk (filenames minus .json). Empty when the runs dir is absent. */
|
|
35
|
+
list(): Promise<RunId[]>;
|
|
36
|
+
/** The most-recent run by createdAt (undefined when none). Powers reticle_run_export's default. */
|
|
37
|
+
latest(): Promise<ReticleVerificationRun | undefined>;
|
|
38
|
+
}
|
|
39
|
+
export {};
|
|
40
|
+
//# sourceMappingURL=run-store.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"run-store.d.ts","sourceRoot":"","sources":["../../src/runs/run-store.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,OAAO,EAKL,YAAY,EACZ,KAAK,sBAAsB,EAC3B,KAAK,KAAK,EACX,MAAM,iBAAiB,CAAC;AACzB,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,uBAAuB,CAAC;AAO5D,4DAA4D;AAC5D,MAAM,MAAM,aAAa,GACrB;IAAE,EAAE,EAAE,IAAI,CAAC;IAAC,GAAG,EAAE,sBAAsB,CAAA;CAAE,GACzC;IAAE,EAAE,EAAE,KAAK,CAAC;IAAC,MAAM,EAAE,YAAY,CAAA;CAAE,CAAC;AAExC,oGAAoG;AACpG,UAAU,eAAe;IACvB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB;AAED,qBAAa,QAAQ;;gBAMP,EAAE,EAAE,cAAc,EAAE,IAAI,EAAE,MAAM,EAAE,IAAI,GAAE,eAAoB;IAOxE;;;;OAIG;IACG,KAAK,CAAC,GAAG,EAAE,sBAAsB,GAAG,OAAO,CAAC,IAAI,CAAC;IAgCvD,2FAA2F;IACrF,IAAI,CAAC,KAAK,EAAE,KAAK,GAAG,OAAO,CAAC,aAAa,CAAC;IA2BhD,uFAAuF;IACjF,IAAI,IAAI,OAAO,CAAC,KAAK,EAAE,CAAC;IAc9B,mGAAmG;IAC7F,MAAM,IAAI,OAAO,CAAC,sBAAsB,GAAG,SAAS,CAAC;CAW5D"}
|
|
@@ -0,0 +1,118 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Persistence for verification-run artifacts at .reticle/runs/<runId>.json. Mirrors ProjectStore:
|
|
3
|
+
* injected FileSystemPort, never-throws read, path-segment guard on the runId (the tool-arg attack
|
|
4
|
+
* surface). One artifact per file (unlike project.json's single rolling file) so a host can attach an
|
|
5
|
+
* individual run to a deploy. The run is already clock-stamped by buildVerificationRun, so the store
|
|
6
|
+
* needs no clock.
|
|
7
|
+
*/
|
|
8
|
+
import { asRunId, ReticleVerificationRunSchema, RUN_RETENTION, RUN_RETENTION_SLACK, RunReadError, } from '@reticlehq/core';
|
|
9
|
+
import { reticleDirPaths, isValidRunId, runPath } from '../project/reticle-dir.js';
|
|
10
|
+
const JSON_INDENT = 2;
|
|
11
|
+
const JSON_EXT = '.json';
|
|
12
|
+
const TMP_EXT = '.tmp';
|
|
13
|
+
export class RunStore {
|
|
14
|
+
#fs;
|
|
15
|
+
#root;
|
|
16
|
+
#retention;
|
|
17
|
+
#slack;
|
|
18
|
+
constructor(fs, root, opts = {}) {
|
|
19
|
+
this.#fs = fs;
|
|
20
|
+
this.#root = root;
|
|
21
|
+
this.#retention = opts.retention ?? RUN_RETENTION;
|
|
22
|
+
this.#slack = opts.slack ?? RUN_RETENTION_SLACK;
|
|
23
|
+
}
|
|
24
|
+
/**
|
|
25
|
+
* Write one run artifact. Creates .reticle/runs/ first; byte-stable (fixed indent + trailing newline).
|
|
26
|
+
* Guards runId as a safe path segment BEFORE building the path — a runId can originate from a caller
|
|
27
|
+
* (an OEM may set it), so an unsafe value must never escape .reticle/runs/ (mirrors the read guard).
|
|
28
|
+
*/
|
|
29
|
+
async write(run) {
|
|
30
|
+
if (!isValidRunId(run.runId)) {
|
|
31
|
+
throw new Error(`refusing to write run with unsafe runId: ${JSON.stringify(run.runId)}`);
|
|
32
|
+
}
|
|
33
|
+
await this.#fs.mkdir(reticleDirPaths(this.#root).runs);
|
|
34
|
+
// Atomic publish: write a temp file then rename, so a crash mid-write never leaves a half-written
|
|
35
|
+
// artifact (a partial .json would otherwise read back as MALFORMED).
|
|
36
|
+
const path = runPath(this.#root, run.runId);
|
|
37
|
+
const tmp = `${path}${TMP_EXT}`;
|
|
38
|
+
await this.#fs.writeFile(tmp, `${JSON.stringify(run, null, JSON_INDENT)}\n`);
|
|
39
|
+
await this.#fs.rename(tmp, path);
|
|
40
|
+
await this.#pruneOld();
|
|
41
|
+
}
|
|
42
|
+
/**
|
|
43
|
+
* Keep .reticle/runs/ bounded. Only acts once the count exceeds RUN_RETENTION + SLACK, then deletes the
|
|
44
|
+
* oldest (by createdAt) back down to RUN_RETENTION — so the read-all is amortized, not per-write.
|
|
45
|
+
*/
|
|
46
|
+
async #pruneOld() {
|
|
47
|
+
const ids = await this.list();
|
|
48
|
+
if (ids.length <= this.#retention + this.#slack)
|
|
49
|
+
return;
|
|
50
|
+
const stamped = [];
|
|
51
|
+
for (const id of ids) {
|
|
52
|
+
const result = await this.read(id);
|
|
53
|
+
stamped.push({ id, at: result.ok ? result.run.createdAt : 0 });
|
|
54
|
+
}
|
|
55
|
+
stamped.sort((a, b) => a.at - b.at);
|
|
56
|
+
for (const { id } of stamped.slice(0, stamped.length - this.#retention)) {
|
|
57
|
+
await this.#fs.rm(runPath(this.#root, id));
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
/** Never throws. Invalid id / missing → MISSING; bad JSON or failed schema → MALFORMED. */
|
|
61
|
+
async read(runId) {
|
|
62
|
+
if (!isValidRunId(runId))
|
|
63
|
+
return { ok: false, reason: RunReadError.MISSING };
|
|
64
|
+
const path = runPath(this.#root, runId);
|
|
65
|
+
if (!(await this.#fs.exists(path)))
|
|
66
|
+
return { ok: false, reason: RunReadError.MISSING };
|
|
67
|
+
let text;
|
|
68
|
+
try {
|
|
69
|
+
text = await this.#fs.readFile(path);
|
|
70
|
+
}
|
|
71
|
+
catch (error) {
|
|
72
|
+
return {
|
|
73
|
+
ok: false,
|
|
74
|
+
reason: this.#fs.isNotFound(error) ? RunReadError.MISSING : RunReadError.MALFORMED,
|
|
75
|
+
};
|
|
76
|
+
}
|
|
77
|
+
let parsed;
|
|
78
|
+
try {
|
|
79
|
+
parsed = JSON.parse(text);
|
|
80
|
+
}
|
|
81
|
+
catch {
|
|
82
|
+
return { ok: false, reason: RunReadError.MALFORMED };
|
|
83
|
+
}
|
|
84
|
+
const result = ReticleVerificationRunSchema.safeParse(parsed);
|
|
85
|
+
if (!result.success)
|
|
86
|
+
return { ok: false, reason: RunReadError.MALFORMED };
|
|
87
|
+
return { ok: true, run: result.data };
|
|
88
|
+
}
|
|
89
|
+
/** List run ids on disk (filenames minus .json). Empty when the runs dir is absent. */
|
|
90
|
+
async list() {
|
|
91
|
+
const dir = reticleDirPaths(this.#root).runs;
|
|
92
|
+
if (!(await this.#fs.exists(dir)))
|
|
93
|
+
return [];
|
|
94
|
+
let entries;
|
|
95
|
+
try {
|
|
96
|
+
entries = await this.#fs.readdir(dir);
|
|
97
|
+
}
|
|
98
|
+
catch {
|
|
99
|
+
return [];
|
|
100
|
+
}
|
|
101
|
+
return entries
|
|
102
|
+
.filter((e) => e.endsWith(JSON_EXT))
|
|
103
|
+
.map((e) => asRunId(e.slice(0, -JSON_EXT.length)));
|
|
104
|
+
}
|
|
105
|
+
/** The most-recent run by createdAt (undefined when none). Powers reticle_run_export's default. */
|
|
106
|
+
async latest() {
|
|
107
|
+
const ids = await this.list();
|
|
108
|
+
let best;
|
|
109
|
+
for (const id of ids) {
|
|
110
|
+
const result = await this.read(id);
|
|
111
|
+
if (result.ok && (best === undefined || result.run.createdAt > best.createdAt)) {
|
|
112
|
+
best = result.run;
|
|
113
|
+
}
|
|
114
|
+
}
|
|
115
|
+
return best;
|
|
116
|
+
}
|
|
117
|
+
}
|
|
118
|
+
//# sourceMappingURL=run-store.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"run-store.js","sourceRoot":"","sources":["../../src/runs/run-store.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import type { ToolDef } from '../tools/tools.js';
|
|
2
|
+
/**
|
|
3
|
+
* The verification-run export tool. `reticle_run_export` reads a persisted ReticleVerificationRun artifact
|
|
4
|
+
* from .reticle/runs/ — the stable verdict a host platform (OEM/design partner) or CI consumes. With a
|
|
5
|
+
* runId it returns that run; without one it returns the most recent. With format:"report" it returns a
|
|
6
|
+
* legible ✓/✗ text report instead of raw JSON. The RunStore is built inline from the injected fs +
|
|
7
|
+
* reticleRoot (it is stateless), so this needs no new ToolDeps wiring.
|
|
8
|
+
*/
|
|
9
|
+
export declare const RUN_TOOLS: ToolDef[];
|
|
10
|
+
//# sourceMappingURL=run-tools.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"run-tools.d.ts","sourceRoot":"","sources":["../../src/runs/run-tools.ts"],"names":[],"mappings":"AAMA,OAAO,KAAK,EAAE,OAAO,EAAY,MAAM,mBAAmB,CAAC;AAI3D;;;;;;GAMG;AACH,eAAO,MAAM,SAAS,EAAE,OAAO,EAqD9B,CAAC"}
|
|
@@ -0,0 +1,69 @@
|
|
|
1
|
+
import { z } from 'zod';
|
|
2
|
+
import { RunReadError } from '@reticlehq/core';
|
|
3
|
+
import { ReticleTool } from '../tools/tool-names.js';
|
|
4
|
+
import { asString } from '../tools/tools-helpers.js';
|
|
5
|
+
import { sessionIdShape } from '../tools/tool-kit.js';
|
|
6
|
+
import { isValidRunId } from '../project/reticle-dir.js';
|
|
7
|
+
import { RunStore } from './run-store.js';
|
|
8
|
+
import { renderRunReport } from './render-report.js';
|
|
9
|
+
/**
|
|
10
|
+
* The verification-run export tool. `reticle_run_export` reads a persisted ReticleVerificationRun artifact
|
|
11
|
+
* from .reticle/runs/ — the stable verdict a host platform (OEM/design partner) or CI consumes. With a
|
|
12
|
+
* runId it returns that run; without one it returns the most recent. With format:"report" it returns a
|
|
13
|
+
* legible ✓/✗ text report instead of raw JSON. The RunStore is built inline from the injected fs +
|
|
14
|
+
* reticleRoot (it is stateless), so this needs no new ToolDeps wiring.
|
|
15
|
+
*/
|
|
16
|
+
export const RUN_TOOLS = [
|
|
17
|
+
{
|
|
18
|
+
name: ReticleTool.RUN_EXPORT,
|
|
19
|
+
description: 'Export a verification-run artifact (the OEM/CI-consumable verdict) from .reticle/runs/. With { runId } returns that specific run; without it returns the most recent. With { format: "report" } returns a legible ✓/✗ text summary (flows, checks, risks, repair, why-it-failed) instead of the raw run. Returns { run } | { report } or { error, reason } when none exists.',
|
|
20
|
+
inputSchema: {
|
|
21
|
+
runId: z
|
|
22
|
+
.string()
|
|
23
|
+
.optional()
|
|
24
|
+
.describe('The run id to export. Omit to return the most recent run.'),
|
|
25
|
+
format: z
|
|
26
|
+
.enum(['json', 'report'])
|
|
27
|
+
.optional()
|
|
28
|
+
.describe('json (default) returns the full run; report returns a legible text summary.'),
|
|
29
|
+
...sessionIdShape,
|
|
30
|
+
},
|
|
31
|
+
outputSchema: {
|
|
32
|
+
run: z.unknown().optional(),
|
|
33
|
+
report: z.string().optional(),
|
|
34
|
+
error: z.string().optional(),
|
|
35
|
+
},
|
|
36
|
+
handler: async (deps, args) => {
|
|
37
|
+
const store = new RunStore(deps.fs, deps.reticleRoot);
|
|
38
|
+
const runId = asString(args['runId']);
|
|
39
|
+
let run;
|
|
40
|
+
if (runId !== undefined) {
|
|
41
|
+
if (!isValidRunId(runId)) {
|
|
42
|
+
return { error: `no run '${runId}' in .reticle/runs/`, reason: RunReadError.MISSING };
|
|
43
|
+
}
|
|
44
|
+
const read = await store.read(runId);
|
|
45
|
+
if (!read.ok) {
|
|
46
|
+
return {
|
|
47
|
+
error: read.reason === RunReadError.MISSING
|
|
48
|
+
? `no run '${runId}' in .reticle/runs/`
|
|
49
|
+
: `run '${runId}' is malformed`,
|
|
50
|
+
reason: read.reason,
|
|
51
|
+
};
|
|
52
|
+
}
|
|
53
|
+
run = read.run;
|
|
54
|
+
}
|
|
55
|
+
else {
|
|
56
|
+
const latest = await store.latest();
|
|
57
|
+
if (latest === undefined) {
|
|
58
|
+
return {
|
|
59
|
+
error: 'no verification runs yet — produce one with the verify flow first',
|
|
60
|
+
reason: RunReadError.MISSING,
|
|
61
|
+
};
|
|
62
|
+
}
|
|
63
|
+
run = latest;
|
|
64
|
+
}
|
|
65
|
+
return asString(args['format']) === 'report' ? { report: renderRunReport(run) } : { run };
|
|
66
|
+
},
|
|
67
|
+
},
|
|
68
|
+
];
|
|
69
|
+
//# sourceMappingURL=run-tools.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"run-tools.js","sourceRoot":"","sources":["../../src/runs/run-tools.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AACxB,OAAO,EAAE,YAAY,EAA+B,MAAM,iBAAiB,CAAC;AAC5E,OAAO,EAAE,WAAW,EAAE,MAAM,wBAAwB,CAAC;AACrD,OAAO,EAAE,QAAQ,EAAE,MAAM,2BAA2B,CAAC;AACrD,OAAO,EAAE,cAAc,EAAE,MAAM,sBAAsB,CAAC;AACtD,OAAO,EAAE,YAAY,EAAE,MAAM,2BAA2B,CAAC;AAEzD,OAAO,EAAE,QAAQ,EAAE,MAAM,gBAAgB,CAAC;AAC1C,OAAO,EAAE,eAAe,EAAE,MAAM,oBAAoB,CAAC;AAErD;;;;;;GAMG;AACH,MAAM,CAAC,MAAM,SAAS,GAAc;IAClC;QACE,IAAI,EAAE,WAAW,CAAC,UAAU;QAC5B,WAAW,EACT,8WAA8W;QAChX,WAAW,EAAE;YACX,KAAK,EAAE,CAAC;iBACL,MAAM,EAAE;iBACR,QAAQ,EAAE;iBACV,QAAQ,CAAC,2DAA2D,CAAC;YACxE,MAAM,EAAE,CAAC;iBACN,IAAI,CAAC,CAAC,MAAM,EAAE,QAAQ,CAAC,CAAC;iBACxB,QAAQ,EAAE;iBACV,QAAQ,CAAC,6EAA6E,CAAC;YAC1F,GAAG,cAAc;SAClB;QACD,YAAY,EAAE;YACZ,GAAG,EAAE,CAAC,CAAC,OAAO,EAAE,CAAC,QAAQ,EAAE;YAC3B,MAAM,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE;YAC7B,KAAK,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE;SAC7B;QACD,OAAO,EAAE,KAAK,EAAE,IAAc,EAAE,IAA6B,EAAE,EAAE;YAC/D,MAAM,KAAK,GAAG,IAAI,QAAQ,CAAC,IAAI,CAAC,EAAE,EAAE,IAAI,CAAC,WAAW,CAAC,CAAC;YACtD,MAAM,KAAK,GAAG,QAAQ,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC,CAAC;YACtC,IAAI,GAA2B,CAAC;YAChC,IAAI,KAAK,KAAK,SAAS,EAAE,CAAC;gBACxB,IAAI,CAAC,YAAY,CAAC,KAAK,CAAC,EAAE,CAAC;oBACzB,OAAO,EAAE,KAAK,EAAE,WAAW,KAAK,qBAAqB,EAAE,MAAM,EAAE,YAAY,CAAC,OAAO,EAAE,CAAC;gBACxF,CAAC;gBACD,MAAM,IAAI,GAAG,MAAM,KAAK,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;gBACrC,IAAI,CAAC,IAAI,CAAC,EAAE,EAAE,CAAC;oBACb,OAAO;wBACL,KAAK,EACH,IAAI,CAAC,MAAM,KAAK,YAAY,CAAC,OAAO;4BAClC,CAAC,CAAC,WAAW,KAAK,qBAAqB;4BACvC,CAAC,CAAC,QAAQ,KAAK,gBAAgB;wBACnC,MAAM,EAAE,IAAI,CAAC,MAAM;qBACpB,CAAC;gBACJ,CAAC;gBACD,GAAG,GAAG,IAAI,CAAC,GAAG,CAAC;YACjB,CAAC;iBAAM,CAAC;gBACN,MAAM,MAAM,GAAG,MAAM,KAAK,CAAC,MAAM,EAAE,CAAC;gBACpC,IAAI,MAAM,KAAK,SAAS,EAAE,CAAC;oBACzB,OAAO;wBACL,KAAK,EAAE,mEAAmE;wBAC1E,MAAM,EAAE,YAAY,CAAC,OAAO;qBAC7B,CAAC;gBACJ,CAAC;gBACD,GAAG,GAAG,MAAM,CAAC;YACf,CAAC;YACD,OAAO,QAAQ,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC,KAAK,QAAQ,CAAC,CAAC,CAAC,EAAE,MAAM,EAAE,eAAe,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,GAAG,EAAE,CAAC;QAC5F,CAAC;KACF;CACF,CAAC"}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The live adapter: build a RunnerPort from the real ToolDeps so ReticleRunner drives actual flow
|
|
3
|
+
* replays against the connected app. Thin glue — it wires deps.flows.list, replayNamedFlow, deps.now,
|
|
4
|
+
* and a uuid generator. The ReticleRunner core (tested with a fake port) holds all the orchestration and
|
|
5
|
+
* verdict logic, so this layer carries no decisions.
|
|
6
|
+
*/
|
|
7
|
+
import { type RunId } from '@reticlehq/core';
|
|
8
|
+
import type { ToolDeps } from '../tools/tools.js';
|
|
9
|
+
import type { RunnerPort } from './reticle-runner.js';
|
|
10
|
+
/** The default run-id generator — a branded uuid. Isolated so it can be swapped/tested independently. */
|
|
11
|
+
export declare function defaultRunId(): RunId;
|
|
12
|
+
/** Wire a RunnerPort to the live session. Pass sessionId to disambiguate when several tabs are open. */
|
|
13
|
+
export declare function createRunnerPort(deps: ToolDeps, sessionId?: string): RunnerPort;
|
|
14
|
+
//# sourceMappingURL=runner-port.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"runner-port.d.ts","sourceRoot":"","sources":["../../src/runs/runner-port.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAGH,OAAO,EAAW,KAAK,KAAK,EAAE,MAAM,iBAAiB,CAAC;AAEtD,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,mBAAmB,CAAC;AAClD,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,qBAAqB,CAAC;AAEtD,yGAAyG;AACzG,wBAAgB,YAAY,IAAI,KAAK,CAEpC;AAED,wGAAwG;AACxG,wBAAgB,gBAAgB,CAAC,IAAI,EAAE,QAAQ,EAAE,SAAS,CAAC,EAAE,MAAM,GAAG,UAAU,CAW/E"}
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The live adapter: build a RunnerPort from the real ToolDeps so ReticleRunner drives actual flow
|
|
3
|
+
* replays against the connected app. Thin glue — it wires deps.flows.list, replayNamedFlow, deps.now,
|
|
4
|
+
* and a uuid generator. The ReticleRunner core (tested with a fake port) holds all the orchestration and
|
|
5
|
+
* verdict logic, so this layer carries no decisions.
|
|
6
|
+
*/
|
|
7
|
+
import { randomUUID } from 'node:crypto';
|
|
8
|
+
import { asRunId } from '@reticlehq/core';
|
|
9
|
+
import { replayNamedFlow } from '../flows/flow-tools.js';
|
|
10
|
+
/** The default run-id generator — a branded uuid. Isolated so it can be swapped/tested independently. */
|
|
11
|
+
export function defaultRunId() {
|
|
12
|
+
return asRunId(randomUUID());
|
|
13
|
+
}
|
|
14
|
+
/** Wire a RunnerPort to the live session. Pass sessionId to disambiguate when several tabs are open. */
|
|
15
|
+
export function createRunnerPort(deps, sessionId) {
|
|
16
|
+
return {
|
|
17
|
+
listFlows: () => deps.flows.list(),
|
|
18
|
+
replayFlow: (name) => replayNamedFlow(deps, sessionId !== undefined ? { flowName: name, sessionId } : { flowName: name }),
|
|
19
|
+
now: () => deps.now(),
|
|
20
|
+
newRunId: defaultRunId,
|
|
21
|
+
};
|
|
22
|
+
}
|
|
23
|
+
//# sourceMappingURL=runner-port.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"runner-port.js","sourceRoot":"","sources":["../../src/runs/runner-port.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,EAAE,UAAU,EAAE,MAAM,aAAa,CAAC;AACzC,OAAO,EAAE,OAAO,EAAc,MAAM,iBAAiB,CAAC;AACtD,OAAO,EAAE,eAAe,EAAE,MAAM,wBAAwB,CAAC;AAIzD,yGAAyG;AACzG,MAAM,UAAU,YAAY;IAC1B,OAAO,OAAO,CAAC,UAAU,EAAE,CAAC,CAAC;AAC/B,CAAC;AAED,wGAAwG;AACxG,MAAM,UAAU,gBAAgB,CAAC,IAAc,EAAE,SAAkB;IACjE,OAAO;QACL,SAAS,EAAE,GAAG,EAAE,CAAC,IAAI,CAAC,KAAK,CAAC,IAAI,EAAE;QAClC,UAAU,EAAE,CAAC,IAAI,EAAE,EAAE,CACnB,eAAe,CACb,IAAI,EACJ,SAAS,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,QAAQ,EAAE,IAAI,EAAE,SAAS,EAAE,CAAC,CAAC,CAAC,EAAE,QAAQ,EAAE,IAAI,EAAE,CAC7E;QACH,GAAG,EAAE,GAAG,EAAE,CAAC,IAAI,CAAC,GAAG,EAAE;QACrB,QAAQ,EAAE,YAAY;KACvB,CAAC;AACJ,CAAC"}
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The token-guarded HTTP verify endpoint — how a host platform (OEM/design partner) or CI drives a
|
|
3
|
+
* verdict from its own pipeline, with no MCP stdio and no human. The request handler is PURE (takes a
|
|
4
|
+
* parsed request, returns a status + body), so it is fully testable without binding a socket; a thin
|
|
5
|
+
* node:http adapter wires it to the wire. Localhost-bound by design; a configured token adds defence
|
|
6
|
+
* in depth (timing-safe compared). An optional persist hook writes the run via RunStore.
|
|
7
|
+
*/
|
|
8
|
+
import { type ReticleVerificationRun } from '@reticlehq/core';
|
|
9
|
+
import type { ReticleRunner } from './reticle-runner.js';
|
|
10
|
+
/** The POST route a partner pipeline calls to get a verdict. */
|
|
11
|
+
export declare const VERIFY_PATH = "/verify";
|
|
12
|
+
/** Constant-time token check. Empty expected token ⇒ open (localhost-only deployments). */
|
|
13
|
+
export declare function tokenOk(provided: string | undefined, expected: string): boolean;
|
|
14
|
+
/** The parsed request the pure handler operates on (decoupled from node:http). */
|
|
15
|
+
export interface VerifyHttpRequest {
|
|
16
|
+
method: string;
|
|
17
|
+
path: string;
|
|
18
|
+
token?: string;
|
|
19
|
+
body: unknown;
|
|
20
|
+
}
|
|
21
|
+
export interface VerifyHttpResponse {
|
|
22
|
+
status: number;
|
|
23
|
+
body: {
|
|
24
|
+
run: ReticleVerificationRun;
|
|
25
|
+
} | {
|
|
26
|
+
error: string;
|
|
27
|
+
};
|
|
28
|
+
}
|
|
29
|
+
/**
|
|
30
|
+
* Pure verify handler. Routes/guards, parses the body, runs the verify, optionally persists the run,
|
|
31
|
+
* and returns a status + body. No sockets, no globals — a test calls it directly.
|
|
32
|
+
*/
|
|
33
|
+
export declare function handleVerifyRequest(req: VerifyHttpRequest, runner: ReticleRunner, expectedToken: string, persist?: (run: ReticleVerificationRun) => Promise<void>): Promise<VerifyHttpResponse>;
|
|
34
|
+
//# sourceMappingURL=verify-http.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"verify-http.d.ts","sourceRoot":"","sources":["../../src/runs/verify-http.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAIH,OAAO,EAML,KAAK,sBAAsB,EAC5B,MAAM,iBAAiB,CAAC;AACzB,OAAO,KAAK,EAAE,aAAa,EAAiB,MAAM,qBAAqB,CAAC;AAExE,gEAAgE;AAChE,eAAO,MAAM,WAAW,YAAY,CAAC;AA4DrC,2FAA2F;AAC3F,wBAAgB,OAAO,CAAC,QAAQ,EAAE,MAAM,GAAG,SAAS,EAAE,QAAQ,EAAE,MAAM,GAAG,OAAO,CAM/E;AAED,kFAAkF;AAClF,MAAM,WAAW,iBAAiB;IAChC,MAAM,EAAE,MAAM,CAAC;IACf,IAAI,EAAE,MAAM,CAAC;IACb,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,IAAI,EAAE,OAAO,CAAC;CACf;AAED,MAAM,WAAW,kBAAkB;IACjC,MAAM,EAAE,MAAM,CAAC;IACf,IAAI,EAAE;QAAE,GAAG,EAAE,sBAAsB,CAAA;KAAE,GAAG;QAAE,KAAK,EAAE,MAAM,CAAA;KAAE,CAAC;CAC3D;AAED;;;GAGG;AACH,wBAAsB,mBAAmB,CACvC,GAAG,EAAE,iBAAiB,EACtB,MAAM,EAAE,aAAa,EACrB,aAAa,EAAE,MAAM,EACrB,OAAO,CAAC,EAAE,CAAC,GAAG,EAAE,sBAAsB,KAAK,OAAO,CAAC,IAAI,CAAC,GACvD,OAAO,CAAC,kBAAkB,CAAC,CAe7B"}
|
|
@@ -0,0 +1,102 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The token-guarded HTTP verify endpoint — how a host platform (OEM/design partner) or CI drives a
|
|
3
|
+
* verdict from its own pipeline, with no MCP stdio and no human. The request handler is PURE (takes a
|
|
4
|
+
* parsed request, returns a status + body), so it is fully testable without binding a socket; a thin
|
|
5
|
+
* node:http adapter wires it to the wire. Localhost-bound by design; a configured token adds defence
|
|
6
|
+
* in depth (timing-safe compared). An optional persist hook writes the run via RunStore.
|
|
7
|
+
*/
|
|
8
|
+
import { timingSafeEqual } from 'node:crypto';
|
|
9
|
+
import { z } from 'zod';
|
|
10
|
+
import { RunAgentKind, RunEnv, RunFramework, RunProfile, RunTrigger, } from '@reticlehq/core';
|
|
11
|
+
/** The POST route a partner pipeline calls to get a verdict. */
|
|
12
|
+
export const VERIFY_PATH = '/verify';
|
|
13
|
+
/** Lenient request body — every field optional; sane defaults are filled by toVerifyOptions. */
|
|
14
|
+
const VerifyRequestSchema = z.object({
|
|
15
|
+
names: z.array(z.string()).optional(),
|
|
16
|
+
project: z
|
|
17
|
+
.object({
|
|
18
|
+
name: z.string().optional(),
|
|
19
|
+
framework: z.nativeEnum(RunFramework).optional(),
|
|
20
|
+
commit: z.string().optional(),
|
|
21
|
+
env: z.nativeEnum(RunEnv).optional(),
|
|
22
|
+
previewUrl: z.string().optional(),
|
|
23
|
+
})
|
|
24
|
+
.optional(),
|
|
25
|
+
agent: z
|
|
26
|
+
.object({
|
|
27
|
+
id: z.string().optional(),
|
|
28
|
+
kind: z.nativeEnum(RunAgentKind).optional(),
|
|
29
|
+
model: z.string().optional(),
|
|
30
|
+
})
|
|
31
|
+
.optional(),
|
|
32
|
+
trigger: z
|
|
33
|
+
.object({
|
|
34
|
+
kind: z.nativeEnum(RunTrigger).optional(),
|
|
35
|
+
diffRef: z.string().optional(),
|
|
36
|
+
note: z.string().optional(),
|
|
37
|
+
})
|
|
38
|
+
.optional(),
|
|
39
|
+
profile: z.nativeEnum(RunProfile).optional(),
|
|
40
|
+
});
|
|
41
|
+
/** Map a parsed request into VerifyOptions, defaulting the required pipeline fields. */
|
|
42
|
+
function toVerifyOptions(body) {
|
|
43
|
+
const project = {
|
|
44
|
+
name: body.project?.name ?? 'app',
|
|
45
|
+
framework: body.project?.framework ?? RunFramework.OTHER,
|
|
46
|
+
...(body.project?.commit !== undefined ? { commit: body.project.commit } : {}),
|
|
47
|
+
...(body.project?.env !== undefined ? { env: body.project.env } : {}),
|
|
48
|
+
...(body.project?.previewUrl !== undefined ? { previewUrl: body.project.previewUrl } : {}),
|
|
49
|
+
};
|
|
50
|
+
const agent = {
|
|
51
|
+
id: body.agent?.id ?? 'oem-pipeline',
|
|
52
|
+
kind: body.agent?.kind ?? RunAgentKind.OEM_PIPELINE,
|
|
53
|
+
...(body.agent?.model !== undefined ? { model: body.agent.model } : {}),
|
|
54
|
+
};
|
|
55
|
+
const trigger = {
|
|
56
|
+
kind: body.trigger?.kind ?? RunTrigger.OEM,
|
|
57
|
+
...(body.trigger?.diffRef !== undefined ? { diffRef: body.trigger.diffRef } : {}),
|
|
58
|
+
...(body.trigger?.note !== undefined ? { note: body.trigger.note } : {}),
|
|
59
|
+
};
|
|
60
|
+
return {
|
|
61
|
+
...(body.names !== undefined ? { names: body.names } : {}),
|
|
62
|
+
project,
|
|
63
|
+
agent,
|
|
64
|
+
trigger,
|
|
65
|
+
profile: body.profile ?? RunProfile.PROD_PREVIEW,
|
|
66
|
+
};
|
|
67
|
+
}
|
|
68
|
+
/** Constant-time token check. Empty expected token ⇒ open (localhost-only deployments). */
|
|
69
|
+
export function tokenOk(provided, expected) {
|
|
70
|
+
if (expected.length === 0)
|
|
71
|
+
return true;
|
|
72
|
+
if (provided === undefined)
|
|
73
|
+
return false;
|
|
74
|
+
const a = Buffer.from(provided);
|
|
75
|
+
const b = Buffer.from(expected);
|
|
76
|
+
return a.length === b.length && timingSafeEqual(a, b);
|
|
77
|
+
}
|
|
78
|
+
/**
|
|
79
|
+
* Pure verify handler. Routes/guards, parses the body, runs the verify, optionally persists the run,
|
|
80
|
+
* and returns a status + body. No sockets, no globals — a test calls it directly.
|
|
81
|
+
*/
|
|
82
|
+
export async function handleVerifyRequest(req, runner, expectedToken, persist) {
|
|
83
|
+
if (req.path !== VERIFY_PATH)
|
|
84
|
+
return { status: 404, body: { error: 'not found' } };
|
|
85
|
+
if (req.method !== 'POST')
|
|
86
|
+
return { status: 405, body: { error: 'method not allowed' } };
|
|
87
|
+
if (!tokenOk(req.token, expectedToken))
|
|
88
|
+
return { status: 401, body: { error: 'unauthorized' } };
|
|
89
|
+
const parsed = VerifyRequestSchema.safeParse(req.body ?? {});
|
|
90
|
+
if (!parsed.success)
|
|
91
|
+
return { status: 400, body: { error: 'invalid request body' } };
|
|
92
|
+
try {
|
|
93
|
+
const run = await runner.verify(toVerifyOptions(parsed.data));
|
|
94
|
+
if (persist !== undefined)
|
|
95
|
+
await persist(run);
|
|
96
|
+
return { status: 200, body: { run } };
|
|
97
|
+
}
|
|
98
|
+
catch {
|
|
99
|
+
return { status: 500, body: { error: 'verify failed' } };
|
|
100
|
+
}
|
|
101
|
+
}
|
|
102
|
+
//# sourceMappingURL=verify-http.js.map
|