@reticlehq/server 2.1.0 → 2.2.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-ENTERPRISE +37 -0
- package/README.md +5 -1
- package/dist/bridge-security.d.ts +1 -1
- package/dist/bridge-security.js +1 -1
- package/dist/bridge.d.ts +7 -0
- package/dist/bridge.d.ts.map +1 -1
- package/dist/bridge.js +22 -3
- package/dist/bridge.js.map +1 -1
- package/dist/bridge.test-harness.d.ts +5 -0
- package/dist/bridge.test-harness.d.ts.map +1 -1
- package/dist/bridge.test-harness.js +4 -0
- package/dist/bridge.test-harness.js.map +1 -1
- package/dist/capsule/capsule-store.d.ts +66 -0
- package/dist/capsule/capsule-store.d.ts.map +1 -0
- package/dist/capsule/capsule-store.js +110 -0
- package/dist/capsule/capsule-store.js.map +1 -0
- package/dist/capsule/capsule.d.ts +19 -0
- package/dist/capsule/capsule.d.ts.map +1 -0
- package/dist/capsule/capsule.js +36 -0
- package/dist/capsule/capsule.js.map +1 -0
- package/dist/capsule/causal-summary.d.ts +36 -0
- package/dist/capsule/causal-summary.d.ts.map +1 -0
- package/dist/capsule/causal-summary.js +111 -0
- package/dist/capsule/causal-summary.js.map +1 -0
- package/dist/capsule/divergence.d.ts +31 -0
- package/dist/capsule/divergence.d.ts.map +1 -0
- package/dist/capsule/divergence.js +41 -0
- package/dist/capsule/divergence.js.map +1 -0
- package/dist/capsule/minimize.d.ts +13 -0
- package/dist/capsule/minimize.d.ts.map +1 -0
- package/dist/capsule/minimize.js +23 -0
- package/dist/capsule/minimize.js.map +1 -0
- package/dist/capsule/predicate-to-links.d.ts +9 -0
- package/dist/capsule/predicate-to-links.d.ts.map +1 -0
- package/dist/capsule/predicate-to-links.js +31 -0
- package/dist/capsule/predicate-to-links.js.map +1 -0
- package/dist/cli-flow-commands.d.ts +31 -0
- package/dist/cli-flow-commands.d.ts.map +1 -0
- package/dist/cli-flow-commands.js +207 -0
- package/dist/cli-flow-commands.js.map +1 -0
- package/dist/cli-parse.d.ts +18 -2
- package/dist/cli-parse.d.ts.map +1 -1
- package/dist/cli-parse.js +57 -0
- package/dist/cli-parse.js.map +1 -1
- package/dist/cli-port.d.ts +10 -4
- package/dist/cli-port.d.ts.map +1 -1
- package/dist/cli-port.js +32 -6
- package/dist/cli-port.js.map +1 -1
- package/dist/cli-verify.d.ts.map +1 -1
- package/dist/cli-verify.js +29 -10
- package/dist/cli-verify.js.map +1 -1
- package/dist/cli.d.ts.map +1 -1
- package/dist/cli.js +81 -2
- package/dist/cli.js.map +1 -1
- package/dist/crawl/crawl-tools.d.ts.map +1 -1
- package/dist/crawl/crawl-tools.js +12 -0
- package/dist/crawl/crawl-tools.js.map +1 -1
- package/dist/crawl/crawl.d.ts +23 -1
- package/dist/crawl/crawl.d.ts.map +1 -1
- package/dist/crawl/crawl.js +36 -9
- package/dist/crawl/crawl.js.map +1 -1
- package/dist/daemon-resilience.d.ts +5 -5
- package/dist/daemon-resilience.js +5 -5
- package/dist/daemon.d.ts +1 -1
- package/dist/daemon.js +1 -1
- package/dist/domain/domain-tools.d.ts.map +1 -1
- package/dist/domain/domain-tools.js +11 -1
- package/dist/domain/domain-tools.js.map +1 -1
- package/dist/domain/flow-risk.d.ts +4 -4
- package/dist/domain/flow-risk.js +4 -4
- package/dist/ee/audit-log.d.ts +2 -2
- package/dist/ee/audit-log.js +2 -2
- package/dist/events/event-filters.d.ts +29 -1
- package/dist/events/event-filters.d.ts.map +1 -1
- package/dist/events/event-filters.js +75 -1
- package/dist/events/event-filters.js.map +1 -1
- package/dist/events/predicate-eval.d.ts +15 -0
- package/dist/events/predicate-eval.d.ts.map +1 -1
- package/dist/events/predicate-eval.js +97 -18
- package/dist/events/predicate-eval.js.map +1 -1
- package/dist/events/predicate.d.ts +22 -1
- package/dist/events/predicate.d.ts.map +1 -1
- package/dist/events/predicate.js +154 -20
- package/dist/events/predicate.js.map +1 -1
- package/dist/events/ring-buffer.d.ts +3 -3
- package/dist/events/ring-buffer.d.ts.map +1 -1
- package/dist/events/ring-buffer.js +54 -8
- package/dist/events/ring-buffer.js.map +1 -1
- package/dist/flows/affected.d.ts +25 -0
- package/dist/flows/affected.d.ts.map +1 -0
- package/dist/flows/affected.js +36 -0
- package/dist/flows/affected.js.map +1 -0
- package/dist/flows/annotate.d.ts +4 -4
- package/dist/flows/annotate.js +4 -4
- package/dist/flows/assertion-integrity.d.ts +24 -0
- package/dist/flows/assertion-integrity.d.ts.map +1 -0
- package/dist/flows/assertion-integrity.js +27 -0
- package/dist/flows/assertion-integrity.js.map +1 -0
- package/dist/flows/assertion-tiers-store.d.ts +80 -0
- package/dist/flows/assertion-tiers-store.d.ts.map +1 -0
- package/dist/flows/assertion-tiers-store.js +99 -0
- package/dist/flows/assertion-tiers-store.js.map +1 -0
- package/dist/flows/buddy-status.d.ts +25 -0
- package/dist/flows/buddy-status.d.ts.map +1 -0
- package/dist/flows/buddy-status.js +33 -0
- package/dist/flows/buddy-status.js.map +1 -0
- package/dist/flows/coverage.d.ts +28 -0
- package/dist/flows/coverage.d.ts.map +1 -0
- package/dist/flows/coverage.js +22 -0
- package/dist/flows/coverage.js.map +1 -0
- package/dist/flows/decision.d.ts.map +1 -1
- package/dist/flows/decision.js +16 -8
- package/dist/flows/decision.js.map +1 -1
- package/dist/flows/flake-store.d.ts +20 -0
- package/dist/flows/flake-store.d.ts.map +1 -0
- package/dist/flows/flake-store.js +59 -0
- package/dist/flows/flake-store.js.map +1 -0
- package/dist/flows/flake.d.ts +58 -0
- package/dist/flows/flake.d.ts.map +1 -0
- package/dist/flows/flake.js +36 -0
- package/dist/flows/flake.js.map +1 -0
- package/dist/flows/flow-classify.d.ts +8 -8
- package/dist/flows/flow-classify.js +8 -8
- package/dist/flows/flow-replay-run.d.ts.map +1 -1
- package/dist/flows/flow-replay-run.js +36 -0
- package/dist/flows/flow-replay-run.js.map +1 -1
- package/dist/flows/flow-replay.d.ts +9 -0
- package/dist/flows/flow-replay.d.ts.map +1 -1
- package/dist/flows/flow-replay.js +48 -13
- package/dist/flows/flow-replay.js.map +1 -1
- package/dist/flows/flow-report.d.ts +4 -4
- package/dist/flows/flow-sources.d.ts +20 -0
- package/dist/flows/flow-sources.d.ts.map +1 -0
- package/dist/flows/flow-sources.js +33 -0
- package/dist/flows/flow-sources.js.map +1 -0
- package/dist/flows/flow-tools.d.ts +13 -1
- package/dist/flows/flow-tools.d.ts.map +1 -1
- package/dist/flows/flow-tools.js +92 -5
- package/dist/flows/flow-tools.js.map +1 -1
- package/dist/flows/flows.d.ts +9 -4
- package/dist/flows/flows.d.ts.map +1 -1
- package/dist/flows/flows.js +38 -21
- package/dist/flows/flows.js.map +1 -1
- package/dist/flows/gate.d.ts +39 -0
- package/dist/flows/gate.d.ts.map +1 -0
- package/dist/flows/gate.js +34 -0
- package/dist/flows/gate.js.map +1 -0
- package/dist/flows/git-changed.d.ts +9 -0
- package/dist/flows/git-changed.d.ts.map +1 -0
- package/dist/flows/git-changed.js +25 -0
- package/dist/flows/git-changed.js.map +1 -0
- package/dist/flows/heal-run.d.ts +1 -1
- package/dist/flows/heal-run.js +1 -1
- package/dist/flows/parallel-suite.d.ts +27 -0
- package/dist/flows/parallel-suite.d.ts.map +1 -0
- package/dist/flows/parallel-suite.js +51 -0
- package/dist/flows/parallel-suite.js.map +1 -0
- package/dist/flows/replay.d.ts.map +1 -1
- package/dist/flows/replay.js +33 -11
- package/dist/flows/replay.js.map +1 -1
- package/dist/flows/watch-batcher.d.ts +18 -0
- package/dist/flows/watch-batcher.d.ts.map +1 -0
- package/dist/flows/watch-batcher.js +20 -0
- package/dist/flows/watch-batcher.js.map +1 -0
- package/dist/honesty/blind-spots.d.ts +37 -0
- package/dist/honesty/blind-spots.d.ts.map +1 -0
- package/dist/honesty/blind-spots.js +57 -0
- package/dist/honesty/blind-spots.js.map +1 -0
- package/dist/honesty/honesty.d.ts +57 -0
- package/dist/honesty/honesty.d.ts.map +1 -0
- package/dist/honesty/honesty.js +63 -0
- package/dist/honesty/honesty.js.map +1 -0
- package/dist/http-server.d.ts +5 -5
- package/dist/http-server.js +4 -4
- package/dist/idle-shutdown.d.ts +2 -2
- package/dist/idle-shutdown.js +2 -2
- package/dist/index.d.ts +3 -2
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +98 -13
- package/dist/index.js.map +1 -1
- package/dist/init/agent-rules.d.ts +38 -0
- package/dist/init/agent-rules.d.ts.map +1 -0
- package/dist/init/agent-rules.js +65 -0
- package/dist/init/agent-rules.js.map +1 -0
- package/dist/init/plan.d.ts +6 -0
- package/dist/init/plan.d.ts.map +1 -1
- package/dist/init/plan.js +79 -3
- package/dist/init/plan.js.map +1 -1
- package/dist/init/run.d.ts.map +1 -1
- package/dist/init/run.js +4 -0
- package/dist/init/run.js.map +1 -1
- package/dist/init/snippets.js +1 -1
- package/dist/init/vite-config.d.ts +1 -1
- package/dist/init/vite-config.js +2 -2
- package/dist/init/vite-config.js.map +1 -1
- package/dist/input/network-detail.d.ts +74 -0
- package/dist/input/network-detail.d.ts.map +1 -0
- package/dist/input/network-detail.js +160 -0
- package/dist/input/network-detail.js.map +1 -0
- package/dist/input/network-mock.d.ts +4 -4
- package/dist/input/real-input.d.ts +44 -11
- package/dist/input/real-input.d.ts.map +1 -1
- package/dist/input/real-input.js +57 -9
- package/dist/input/real-input.js.map +1 -1
- package/dist/journal/ambient-store.d.ts +16 -0
- package/dist/journal/ambient-store.d.ts.map +1 -0
- package/dist/journal/ambient-store.js +46 -0
- package/dist/journal/ambient-store.js.map +1 -0
- package/dist/journal/ambient.d.ts +48 -0
- package/dist/journal/ambient.d.ts.map +1 -0
- package/dist/journal/ambient.js +48 -0
- package/dist/journal/ambient.js.map +1 -0
- package/dist/journal/attach-journal.d.ts +22 -0
- package/dist/journal/attach-journal.d.ts.map +1 -0
- package/dist/journal/attach-journal.js +20 -0
- package/dist/journal/attach-journal.js.map +1 -0
- package/dist/journal/deviation-report.d.ts +28 -0
- package/dist/journal/deviation-report.d.ts.map +1 -0
- package/dist/journal/deviation-report.js +54 -0
- package/dist/journal/deviation-report.js.map +1 -0
- package/dist/journal/deviation-service.d.ts +12 -0
- package/dist/journal/deviation-service.d.ts.map +1 -0
- package/dist/journal/deviation-service.js +32 -0
- package/dist/journal/deviation-service.js.map +1 -0
- package/dist/journal/envelope-store.d.ts +19 -0
- package/dist/journal/envelope-store.d.ts.map +1 -0
- package/dist/journal/envelope-store.js +62 -0
- package/dist/journal/envelope-store.js.map +1 -0
- package/dist/journal/envelope.d.ts +232 -0
- package/dist/journal/envelope.d.ts.map +1 -0
- package/dist/journal/envelope.js +94 -0
- package/dist/journal/envelope.js.map +1 -0
- package/dist/journal/journal-query.d.ts +20 -0
- package/dist/journal/journal-query.d.ts.map +1 -0
- package/dist/journal/journal-query.js +28 -0
- package/dist/journal/journal-query.js.map +1 -0
- package/dist/journal/journal-recorder.d.ts +38 -0
- package/dist/journal/journal-recorder.d.ts.map +1 -0
- package/dist/journal/journal-recorder.js +81 -0
- package/dist/journal/journal-recorder.js.map +1 -0
- package/dist/journal/retention.d.ts +21 -0
- package/dist/journal/retention.d.ts.map +1 -0
- package/dist/journal/retention.js +50 -0
- package/dist/journal/retention.js.map +1 -0
- package/dist/journal/rollups.d.ts +49 -0
- package/dist/journal/rollups.d.ts.map +1 -0
- package/dist/journal/rollups.js +83 -0
- package/dist/journal/rollups.js.map +1 -0
- package/dist/journal/session-end.d.ts +32 -0
- package/dist/journal/session-end.d.ts.map +1 -0
- package/dist/journal/session-end.js +52 -0
- package/dist/journal/session-end.js.map +1 -0
- package/dist/journal/session-journal.d.ts +25 -0
- package/dist/journal/session-journal.d.ts.map +1 -0
- package/dist/journal/session-journal.js +168 -0
- package/dist/journal/session-journal.js.map +1 -0
- package/dist/license/license.d.ts +8 -3
- package/dist/license/license.d.ts.map +1 -1
- package/dist/license/license.js +34 -11
- package/dist/license/license.js.map +1 -1
- package/dist/mcp-proxy.d.ts +20 -0
- package/dist/mcp-proxy.d.ts.map +1 -1
- package/dist/mcp-proxy.js +45 -27
- package/dist/mcp-proxy.js.map +1 -1
- package/dist/mcp.d.ts +14 -0
- package/dist/mcp.d.ts.map +1 -1
- package/dist/mcp.js +79 -9
- package/dist/mcp.js.map +1 -1
- package/dist/oracles/flow-instrument-gaps.d.ts +19 -0
- package/dist/oracles/flow-instrument-gaps.d.ts.map +1 -0
- package/dist/oracles/flow-instrument-gaps.js +45 -0
- package/dist/oracles/flow-instrument-gaps.js.map +1 -0
- package/dist/oracles/propose-consequences.d.ts +22 -0
- package/dist/oracles/propose-consequences.d.ts.map +1 -0
- package/dist/oracles/propose-consequences.js +93 -0
- package/dist/oracles/propose-consequences.js.map +1 -0
- package/dist/oracles/self-instrument.d.ts +32 -0
- package/dist/oracles/self-instrument.d.ts.map +1 -0
- package/dist/oracles/self-instrument.js +44 -0
- package/dist/oracles/self-instrument.js.map +1 -0
- package/dist/pairing-token.d.ts +1 -1
- package/dist/phenomena/phenomena.d.ts +27 -0
- package/dist/phenomena/phenomena.d.ts.map +1 -0
- package/dist/phenomena/phenomena.js +102 -0
- package/dist/phenomena/phenomena.js.map +1 -0
- package/dist/pool/browser-pool.d.ts +5 -3
- package/dist/pool/browser-pool.d.ts.map +1 -1
- package/dist/pool/browser-pool.js +21 -3
- package/dist/pool/browser-pool.js.map +1 -1
- package/dist/pool/playwright-launcher.d.ts.map +1 -1
- package/dist/pool/playwright-launcher.js +9 -2
- package/dist/pool/playwright-launcher.js.map +1 -1
- package/dist/project/file-lock.d.ts +2 -0
- package/dist/project/file-lock.d.ts.map +1 -0
- package/dist/project/file-lock.js +24 -0
- package/dist/project/file-lock.js.map +1 -0
- package/dist/project/fs-port.d.ts +18 -0
- package/dist/project/fs-port.d.ts.map +1 -1
- package/dist/project/fs-port.js +24 -2
- package/dist/project/fs-port.js.map +1 -1
- package/dist/project/project-store.d.ts.map +1 -1
- package/dist/project/project-store.js +13 -7
- package/dist/project/project-store.js.map +1 -1
- package/dist/project/project-tools.d.ts +0 -6
- package/dist/project/project-tools.d.ts.map +1 -1
- package/dist/project/project-tools.js +24 -1
- package/dist/project/project-tools.js.map +1 -1
- package/dist/project/reticle-dir.d.ts +39 -14
- package/dist/project/reticle-dir.d.ts.map +1 -1
- package/dist/project/reticle-dir.js +30 -4
- package/dist/project/reticle-dir.js.map +1 -1
- package/dist/runs/build-verification-run.d.ts +1 -1
- package/dist/runs/build-verification-run.js +1 -1
- package/dist/runs/repair-prompt.d.ts +2 -0
- package/dist/runs/repair-prompt.d.ts.map +1 -1
- package/dist/runs/repair-prompt.js +14 -1
- package/dist/runs/repair-prompt.js.map +1 -1
- package/dist/runs/reticle-runner.d.ts +1 -1
- package/dist/runs/reticle-runner.d.ts.map +1 -1
- package/dist/runs/run-diff.d.ts +34 -0
- package/dist/runs/run-diff.d.ts.map +1 -0
- package/dist/runs/run-diff.js +71 -0
- package/dist/runs/run-diff.js.map +1 -0
- package/dist/runs/run-store.d.ts +6 -1
- package/dist/runs/run-store.d.ts.map +1 -1
- package/dist/runs/run-store.js +22 -2
- package/dist/runs/run-store.js.map +1 -1
- package/dist/runs/run-tools.d.ts.map +1 -1
- package/dist/runs/run-tools.js +16 -3
- package/dist/runs/run-tools.js.map +1 -1
- package/dist/runs/verify-server.js +1 -1
- package/dist/runs/verify-server.js.map +1 -1
- package/dist/session/control-envelope.d.ts +9 -1
- package/dist/session/control-envelope.d.ts.map +1 -1
- package/dist/session/control-envelope.js +13 -1
- package/dist/session/control-envelope.js.map +1 -1
- package/dist/session/live-control-tools.d.ts +1 -1
- package/dist/session/live-control-tools.js +1 -1
- package/dist/session/live-control.d.ts +38 -0
- package/dist/session/live-control.d.ts.map +1 -0
- package/dist/session/live-control.js +64 -0
- package/dist/session/live-control.js.map +1 -0
- package/dist/session/observed-state.d.ts +46 -0
- package/dist/session/observed-state.d.ts.map +1 -0
- package/dist/session/observed-state.js +76 -0
- package/dist/session/observed-state.js.map +1 -0
- package/dist/session/output-budget.d.ts +9 -0
- package/dist/session/output-budget.d.ts.map +1 -1
- package/dist/session/output-budget.js +9 -0
- package/dist/session/output-budget.js.map +1 -1
- package/dist/session/review-store.d.ts +1 -1
- package/dist/session/review-store.d.ts.map +1 -1
- package/dist/session/review-store.js +2 -2
- package/dist/session/review-store.js.map +1 -1
- package/dist/session/session-manager.d.ts +9 -7
- package/dist/session/session-manager.d.ts.map +1 -1
- package/dist/session/session-manager.js +8 -8
- package/dist/session/session-manager.js.map +1 -1
- package/dist/session/session-readiness.js +1 -1
- package/dist/session/session-readiness.js.map +1 -1
- package/dist/session/session-reaper.d.ts +1 -1
- package/dist/session/session-reaper.js +1 -1
- package/dist/session/session-recommendation.d.ts +1 -1
- package/dist/session/session-recommendation.js +1 -1
- package/dist/session/session-tools.js +1 -1
- package/dist/session/session-tools.js.map +1 -1
- package/dist/session/session.d.ts +43 -11
- package/dist/session/session.d.ts.map +1 -1
- package/dist/session/session.js +115 -46
- package/dist/session/session.js.map +1 -1
- package/dist/tools/act-tools.d.ts.map +1 -1
- package/dist/tools/act-tools.js +252 -70
- package/dist/tools/act-tools.js.map +1 -1
- package/dist/tools/act-view.d.ts +4 -4
- package/dist/tools/act-view.js +4 -4
- package/dist/tools/browser-tools.d.ts.map +1 -1
- package/dist/tools/browser-tools.js +32 -8
- package/dist/tools/browser-tools.js.map +1 -1
- package/dist/tools/contract-tools.d.ts.map +1 -1
- package/dist/tools/contract-tools.js +5 -0
- package/dist/tools/contract-tools.js.map +1 -1
- package/dist/tools/dynamic-tools.d.ts.map +1 -1
- package/dist/tools/dynamic-tools.js +7 -6
- package/dist/tools/dynamic-tools.js.map +1 -1
- package/dist/tools/invoke-tool.d.ts.map +1 -1
- package/dist/tools/invoke-tool.js +32 -29
- package/dist/tools/invoke-tool.js.map +1 -1
- package/dist/tools/lease-tools.d.ts +16 -0
- package/dist/tools/lease-tools.d.ts.map +1 -1
- package/dist/tools/lease-tools.js +11 -0
- package/dist/tools/lease-tools.js.map +1 -1
- package/dist/tools/merge-tools.d.ts +43 -0
- package/dist/tools/merge-tools.d.ts.map +1 -0
- package/dist/tools/merge-tools.js +66 -0
- package/dist/tools/merge-tools.js.map +1 -0
- package/dist/tools/observe-tools.d.ts.map +1 -1
- package/dist/tools/observe-tools.js +172 -29
- package/dist/tools/observe-tools.js.map +1 -1
- package/dist/tools/profiles.d.ts +18 -13
- package/dist/tools/profiles.d.ts.map +1 -1
- package/dist/tools/profiles.js +39 -33
- package/dist/tools/profiles.js.map +1 -1
- package/dist/tools/query-paginate.d.ts +9 -2
- package/dist/tools/query-paginate.d.ts.map +1 -1
- package/dist/tools/query-paginate.js +21 -4
- package/dist/tools/query-paginate.js.map +1 -1
- package/dist/tools/read-tools.d.ts.map +1 -1
- package/dist/tools/read-tools.js +30 -1
- package/dist/tools/read-tools.js.map +1 -1
- package/dist/tools/snapshot-delta.d.ts +2 -0
- package/dist/tools/snapshot-delta.d.ts.map +1 -1
- package/dist/tools/snapshot-delta.js +0 -0
- package/dist/tools/snapshot-delta.js.map +1 -1
- package/dist/tools/tool-kit.d.ts +3 -2
- package/dist/tools/tool-kit.d.ts.map +1 -1
- package/dist/tools/tool-kit.js +11 -1
- package/dist/tools/tool-kit.js.map +1 -1
- package/dist/tools/tool-names.d.ts +18 -10
- package/dist/tools/tool-names.d.ts.map +1 -1
- package/dist/tools/tool-names.js +22 -13
- package/dist/tools/tool-names.js.map +1 -1
- package/dist/tools/tools-helpers.d.ts +12 -0
- package/dist/tools/tools-helpers.d.ts.map +1 -1
- package/dist/tools/tools-helpers.js +20 -0
- package/dist/tools/tools-helpers.js.map +1 -1
- package/dist/tools/tools.d.ts.map +1 -1
- package/dist/tools/tools.js +162 -12
- package/dist/tools/tools.js.map +1 -1
- package/dist/update/updater.d.ts +1 -1
- package/dist/update/updater.js +2 -2
- package/dist/update/updater.js.map +1 -1
- package/package.json +8 -3
- package/dist/update/update-tools.d.ts +0 -3
- package/dist/update/update-tools.d.ts.map +0 -1
- package/dist/update/update-tools.js +0 -94
- package/dist/update/update-tools.js.map +0 -1
|
@@ -0,0 +1,71 @@
|
|
|
1
|
+
/** Below this percent, a duration change is noise (machine jitter), not a regression. */
|
|
2
|
+
export const DEFAULT_NOISE_FLOOR_PCT = 10;
|
|
3
|
+
function pct(before, delta) {
|
|
4
|
+
return before > 0 ? Math.round((delta / before) * 100) : 0;
|
|
5
|
+
}
|
|
6
|
+
function byName(flows) {
|
|
7
|
+
return new Map(flows.map((f) => [f.name, f]));
|
|
8
|
+
}
|
|
9
|
+
function headlineFor(diff) {
|
|
10
|
+
const parts = [];
|
|
11
|
+
const regressions = diff.flows.filter((f) => f.regressed);
|
|
12
|
+
if (regressions.length > 0) {
|
|
13
|
+
const worst = regressions[0];
|
|
14
|
+
parts.push(`${String(regressions.length)} regression${regressions.length === 1 ? '' : 's'} (worst: ${worst?.name ?? ''} ${String(worst?.durationDeltaPct ?? 0)}%)`);
|
|
15
|
+
}
|
|
16
|
+
if (diff.newFlows.length > 0)
|
|
17
|
+
parts.push(`+${String(diff.newFlows.length)} flow`);
|
|
18
|
+
if (diff.removedFlows.length > 0)
|
|
19
|
+
parts.push(`-${String(diff.removedFlows.length)} flow`);
|
|
20
|
+
if (diff.verdictChange !== undefined) {
|
|
21
|
+
parts.push(`verdict ${diff.verdictChange.from}→${diff.verdictChange.to}`);
|
|
22
|
+
}
|
|
23
|
+
return parts.length === 0 ? 'no significant change between runs' : parts.join(', ');
|
|
24
|
+
}
|
|
25
|
+
/**
|
|
26
|
+
* Compare two verification runs — the concrete answer to "what changed between run A and B". Flow
|
|
27
|
+
* durations are diffed with a noise floor (jitter below it is ignored); status changes and new/removed
|
|
28
|
+
* flows are always surfaced. Deterministic and pure; flows are matched by name. Per-step deltas + net/
|
|
29
|
+
* console diffs land once runs persist per-step detail.
|
|
30
|
+
*/
|
|
31
|
+
export function diffRuns(before, after, noiseFloorPct = DEFAULT_NOISE_FLOOR_PCT) {
|
|
32
|
+
const beforeFlows = byName(before.flows);
|
|
33
|
+
const afterFlows = byName(after.flows);
|
|
34
|
+
const flows = [];
|
|
35
|
+
const newFlows = [];
|
|
36
|
+
for (const [name, af] of afterFlows) {
|
|
37
|
+
const bf = beforeFlows.get(name);
|
|
38
|
+
if (bf === undefined) {
|
|
39
|
+
newFlows.push(name);
|
|
40
|
+
continue;
|
|
41
|
+
}
|
|
42
|
+
const durationDeltaMs = af.durationMs - bf.durationMs;
|
|
43
|
+
const durationDeltaPct = pct(bf.durationMs, durationDeltaMs);
|
|
44
|
+
const statusChanged = bf.status !== af.status;
|
|
45
|
+
if (!statusChanged && Math.abs(durationDeltaPct) < noiseFloorPct)
|
|
46
|
+
continue; // noise
|
|
47
|
+
flows.push({
|
|
48
|
+
name,
|
|
49
|
+
beforeMs: bf.durationMs,
|
|
50
|
+
afterMs: af.durationMs,
|
|
51
|
+
durationDeltaMs,
|
|
52
|
+
durationDeltaPct,
|
|
53
|
+
beforeStatus: bf.status,
|
|
54
|
+
afterStatus: af.status,
|
|
55
|
+
statusChanged,
|
|
56
|
+
regressed: statusChanged || durationDeltaPct >= noiseFloorPct,
|
|
57
|
+
});
|
|
58
|
+
}
|
|
59
|
+
const removedFlows = [...beforeFlows.keys()].filter((name) => !afterFlows.has(name));
|
|
60
|
+
flows.sort((a, b) => b.durationDeltaPct - a.durationDeltaPct);
|
|
61
|
+
const base = {
|
|
62
|
+
flows,
|
|
63
|
+
newFlows,
|
|
64
|
+
removedFlows,
|
|
65
|
+
...(before.verdict.status === after.verdict.status
|
|
66
|
+
? {}
|
|
67
|
+
: { verdictChange: { from: before.verdict.status, to: after.verdict.status } }),
|
|
68
|
+
};
|
|
69
|
+
return { ...base, headline: headlineFor(base) };
|
|
70
|
+
}
|
|
71
|
+
//# sourceMappingURL=run-diff.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"run-diff.js","sourceRoot":"","sources":["../../src/runs/run-diff.ts"],"names":[],"mappings":"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"}
|
package/dist/runs/run-store.d.ts
CHANGED
|
@@ -31,10 +31,15 @@ export declare class RunStore {
|
|
|
31
31
|
write(run: ReticleVerificationRun): Promise<void>;
|
|
32
32
|
/** Never throws. Invalid id / missing → MISSING; bad JSON or failed schema → MALFORMED. */
|
|
33
33
|
read(runId: RunId): Promise<ReadRunResult>;
|
|
34
|
-
/** List run ids on disk (filenames minus
|
|
34
|
+
/** List run ids on disk (filenames minus.json). Empty when the runs dir is absent. */
|
|
35
35
|
list(): Promise<RunId[]>;
|
|
36
36
|
/** The most-recent run by createdAt (undefined when none). Powers reticle_run_export's default. */
|
|
37
37
|
latest(): Promise<ReticleVerificationRun | undefined>;
|
|
38
|
+
/**
|
|
39
|
+
* The two most-recent runs by createdAt as `[previous, current]` (oldest-first), or undefined when
|
|
40
|
+
* fewer than two readable runs exist. Powers reticle_run_export's `format:"diff"` (run-to-run deltas).
|
|
41
|
+
*/
|
|
42
|
+
latestTwo(): Promise<[ReticleVerificationRun, ReticleVerificationRun] | undefined>;
|
|
38
43
|
}
|
|
39
44
|
export {};
|
|
40
45
|
//# sourceMappingURL=run-store.d.ts.map
|
|
@@ -1 +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,
|
|
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,sFAAsF;IAChF,IAAI,IAAI,OAAO,CAAC,KAAK,EAAE,CAAC;IAc9B,mGAAmG;IAC7F,MAAM,IAAI,OAAO,CAAC,sBAAsB,GAAG,SAAS,CAAC;IAY3D;;;OAGG;IACG,SAAS,IAAI,OAAO,CAAC,CAAC,sBAAsB,EAAE,sBAAsB,CAAC,GAAG,SAAS,CAAC;CAazF"}
|
package/dist/runs/run-store.js
CHANGED
|
@@ -32,7 +32,7 @@ export class RunStore {
|
|
|
32
32
|
}
|
|
33
33
|
await this.#fs.mkdir(reticleDirPaths(this.#root).runs);
|
|
34
34
|
// Atomic publish: write a temp file then rename, so a crash mid-write never leaves a half-written
|
|
35
|
-
// artifact (a partial
|
|
35
|
+
// artifact (a partial.json would otherwise read back as MALFORMED).
|
|
36
36
|
const path = runPath(this.#root, run.runId);
|
|
37
37
|
const tmp = `${path}${TMP_EXT}`;
|
|
38
38
|
await this.#fs.writeFile(tmp, `${JSON.stringify(run, null, JSON_INDENT)}\n`);
|
|
@@ -86,7 +86,7 @@ export class RunStore {
|
|
|
86
86
|
return { ok: false, reason: RunReadError.MALFORMED };
|
|
87
87
|
return { ok: true, run: result.data };
|
|
88
88
|
}
|
|
89
|
-
/** List run ids on disk (filenames minus
|
|
89
|
+
/** List run ids on disk (filenames minus.json). Empty when the runs dir is absent. */
|
|
90
90
|
async list() {
|
|
91
91
|
const dir = reticleDirPaths(this.#root).runs;
|
|
92
92
|
if (!(await this.#fs.exists(dir)))
|
|
@@ -114,5 +114,25 @@ export class RunStore {
|
|
|
114
114
|
}
|
|
115
115
|
return best;
|
|
116
116
|
}
|
|
117
|
+
/**
|
|
118
|
+
* The two most-recent runs by createdAt as `[previous, current]` (oldest-first), or undefined when
|
|
119
|
+
* fewer than two readable runs exist. Powers reticle_run_export's `format:"diff"` (run-to-run deltas).
|
|
120
|
+
*/
|
|
121
|
+
async latestTwo() {
|
|
122
|
+
const runs = [];
|
|
123
|
+
for (const id of await this.list()) {
|
|
124
|
+
const result = await this.read(id);
|
|
125
|
+
if (result.ok)
|
|
126
|
+
runs.push(result.run);
|
|
127
|
+
}
|
|
128
|
+
if (runs.length < 2)
|
|
129
|
+
return undefined;
|
|
130
|
+
runs.sort((a, b) => a.createdAt - b.createdAt);
|
|
131
|
+
const previous = runs[runs.length - 2];
|
|
132
|
+
const current = runs[runs.length - 1];
|
|
133
|
+
if (previous === undefined || current === undefined)
|
|
134
|
+
return undefined;
|
|
135
|
+
return [previous, current];
|
|
136
|
+
}
|
|
117
137
|
}
|
|
118
138
|
//# sourceMappingURL=run-store.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"run-store.js","sourceRoot":"","sources":["../../src/runs/run-store.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,OAAO,EACL,OAAO,EACP,4BAA4B,EAC5B,aAAa,EACb,mBAAmB,EACnB,YAAY,GAGb,MAAM,iBAAiB,CAAC;AAEzB,OAAO,EAAE,eAAe,EAAE,YAAY,EAAE,OAAO,EAAE,MAAM,2BAA2B,CAAC;AAEnF,MAAM,WAAW,GAAG,CAAC,CAAC;AACtB,MAAM,QAAQ,GAAG,OAAO,CAAC;AACzB,MAAM,OAAO,GAAG,MAAM,CAAC;AAavB,MAAM,OAAO,QAAQ;IACV,GAAG,CAAiB;IACpB,KAAK,CAAS;IACd,UAAU,CAAS;IACnB,MAAM,CAAS;IAExB,YAAY,EAAkB,EAAE,IAAY,EAAE,OAAwB,EAAE;QACtE,IAAI,CAAC,GAAG,GAAG,EAAE,CAAC;QACd,IAAI,CAAC,KAAK,GAAG,IAAI,CAAC;QAClB,IAAI,CAAC,UAAU,GAAG,IAAI,CAAC,SAAS,IAAI,aAAa,CAAC;QAClD,IAAI,CAAC,MAAM,GAAG,IAAI,CAAC,KAAK,IAAI,mBAAmB,CAAC;IAClD,CAAC;IAED;;;;OAIG;IACH,KAAK,CAAC,KAAK,CAAC,GAA2B;QACrC,IAAI,CAAC,YAAY,CAAC,GAAG,CAAC,KAAK,CAAC,EAAE,CAAC;YAC7B,MAAM,IAAI,KAAK,CAAC,4CAA4C,IAAI,CAAC,SAAS,CAAC,GAAG,CAAC,KAAK,CAAC,EAAE,CAAC,CAAC;QAC3F,CAAC;QACD,MAAM,IAAI,CAAC,GAAG,CAAC,KAAK,CAAC,eAAe,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,IAAI,CAAC,CAAC;QACvD,kGAAkG;QAClG,
|
|
1
|
+
{"version":3,"file":"run-store.js","sourceRoot":"","sources":["../../src/runs/run-store.ts"],"names":[],"mappings":"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"}
|
|
@@ -1 +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;
|
|
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;AAK3D;;;;;;GAMG;AACH,eAAO,MAAM,SAAS,EAAE,OAAO,EAoE9B,CAAC"}
|
package/dist/runs/run-tools.js
CHANGED
|
@@ -6,6 +6,7 @@ import { sessionIdShape } from '../tools/tool-kit.js';
|
|
|
6
6
|
import { isValidRunId } from '../project/reticle-dir.js';
|
|
7
7
|
import { RunStore } from './run-store.js';
|
|
8
8
|
import { renderRunReport } from './render-report.js';
|
|
9
|
+
import { diffRuns } from './run-diff.js';
|
|
9
10
|
/**
|
|
10
11
|
* The verification-run export tool. `reticle_run_export` reads a persisted ReticleVerificationRun artifact
|
|
11
12
|
* from .reticle/runs/ — the stable verdict a host platform (OEM/design partner) or CI consumes. With a
|
|
@@ -16,25 +17,37 @@ import { renderRunReport } from './render-report.js';
|
|
|
16
17
|
export const RUN_TOOLS = [
|
|
17
18
|
{
|
|
18
19
|
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
|
|
20
|
+
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; with { format: "diff" } returns the run-to-run delta between the two most-recent runs (per-flow duration deltas past a noise floor, status changes, new/removed flows, verdict change, headline). Returns { run } | { report } | { diff } or { error, reason } when none exists.',
|
|
20
21
|
inputSchema: {
|
|
21
22
|
runId: z
|
|
22
23
|
.string()
|
|
23
24
|
.optional()
|
|
24
25
|
.describe('The run id to export. Omit to return the most recent run.'),
|
|
25
26
|
format: z
|
|
26
|
-
.enum(['json', 'report'])
|
|
27
|
+
.enum(['json', 'report', 'diff'])
|
|
27
28
|
.optional()
|
|
28
|
-
.describe('json (default) returns the full run; report returns a legible text summary.'),
|
|
29
|
+
.describe('json (default) returns the full run; report returns a legible text summary; diff returns the delta vs the previous run.'),
|
|
29
30
|
...sessionIdShape,
|
|
30
31
|
},
|
|
31
32
|
outputSchema: {
|
|
32
33
|
run: z.unknown().optional(),
|
|
33
34
|
report: z.string().optional(),
|
|
35
|
+
diff: z.unknown().optional(),
|
|
34
36
|
error: z.string().optional(),
|
|
35
37
|
},
|
|
36
38
|
handler: async (deps, args) => {
|
|
37
39
|
const store = new RunStore(deps.fs, deps.reticleRoot);
|
|
40
|
+
// format:"diff" is a whole-history operation (two most-recent runs), not a single-run read.
|
|
41
|
+
if (asString(args['format']) === 'diff') {
|
|
42
|
+
const pair = await store.latestTwo();
|
|
43
|
+
if (pair === undefined) {
|
|
44
|
+
return {
|
|
45
|
+
error: 'need at least two verification runs to diff — produce another with the verify flow',
|
|
46
|
+
reason: RunReadError.MISSING,
|
|
47
|
+
};
|
|
48
|
+
}
|
|
49
|
+
return { diff: diffRuns(pair[0], pair[1]) };
|
|
50
|
+
}
|
|
38
51
|
const runId = asString(args['runId']);
|
|
39
52
|
let run;
|
|
40
53
|
if (runId !== undefined) {
|
|
@@ -1 +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;
|
|
1
|
+
{"version":3,"file":"run-tools.js","sourceRoot":"","sources":["../../src/runs/run-tools.ts"],"names":[],"mappings":"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"}
|
|
@@ -10,7 +10,7 @@ import { handleVerifyRequest } from './verify-http.js';
|
|
|
10
10
|
const LOCALHOST = LOOPBACK_HOST;
|
|
11
11
|
const MAX_BODY_BYTES = 1_000_000;
|
|
12
12
|
/** Cap how long a single request (and its headers) may take, so a slow/stuck client can't tie up the
|
|
13
|
-
*
|
|
13
|
+
* endpoint indefinitely (slow-loris hardening). */
|
|
14
14
|
const REQUEST_TIMEOUT_MS = 30_000;
|
|
15
15
|
const HEADERS_TIMEOUT_MS = 10_000;
|
|
16
16
|
/** Partner pipelines send the token here (localhost-bound, so this is defence-in-depth, not the wall). */
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"verify-server.js","sourceRoot":"","sources":["../../src/runs/verify-server.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,KAAK,IAAI,MAAM,WAAW,CAAC;AAClC,OAAO,EAAE,aAAa,EAAE,MAAM,iBAAiB,CAAC;AAGhD,OAAO,EAAE,mBAAmB,EAA0B,MAAM,kBAAkB,CAAC;AAE/E,MAAM,SAAS,GAAG,aAAa,CAAC;AAChC,MAAM,cAAc,GAAG,SAAS,CAAC;AACjC;
|
|
1
|
+
{"version":3,"file":"verify-server.js","sourceRoot":"","sources":["../../src/runs/verify-server.ts"],"names":[],"mappings":"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"}
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { SessionState } from '@reticlehq/core';
|
|
2
|
+
import { z } from 'zod';
|
|
2
3
|
import type { Session } from './session.js';
|
|
3
4
|
/** Live-control: the control block spliced onto tool results so the agent sees human steering. */
|
|
4
5
|
interface ControlEnvelope {
|
|
@@ -17,6 +18,13 @@ interface PausedResult {
|
|
|
17
18
|
guidance: string[];
|
|
18
19
|
hint: string;
|
|
19
20
|
}
|
|
21
|
+
/**
|
|
22
|
+
* outputSchema fields every action tool that can short-circuit on pause MUST declare, or a validating
|
|
23
|
+
* profile strips the WHOLE pause payload — and because `guidance` is drained-once, that loses the
|
|
24
|
+
* human's message entirely (not merely hides it). Declared here beside PausedResult so the schema and
|
|
25
|
+
* the runtime shape are the same source; spread into each act tool's outputSchema.
|
|
26
|
+
*/
|
|
27
|
+
export declare const pausedOutputShape: z.ZodRawShape;
|
|
20
28
|
/** The optional `control` key `withControl` may add — keeps callers' return types honest. */
|
|
21
29
|
type ControlSpread = {
|
|
22
30
|
control?: ControlEnvelope;
|
|
@@ -35,7 +43,7 @@ export declare function buildControlEnvelope(session: Session): ControlEnvelope
|
|
|
35
43
|
* PAUSE short-circuit. When the session is paused, drain the inbox and refuse the action so the
|
|
36
44
|
* human's pause cannot be driven through. Returns undefined when the action may proceed.
|
|
37
45
|
*
|
|
38
|
-
* `drainInbox
|
|
46
|
+
* `drainInbox` is the SOLE sink for guidance — draining here means the same message can never
|
|
39
47
|
* also surface in a piggyback, guaranteeing delivered-once.
|
|
40
48
|
*/
|
|
41
49
|
export declare function pausedShortCircuit(session: Session): PausedResult | undefined;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"control-envelope.d.ts","sourceRoot":"","sources":["../../src/session/control-envelope.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,MAAM,iBAAiB,CAAC;AAC/C,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,cAAc,CAAC;AAE5C,kGAAkG;AAClG,UAAU,eAAe;IACvB,KAAK,EAAE,YAAY,CAAC;IACpB,+DAA+D;IAC/D,QAAQ,EAAE,MAAM,EAAE,CAAC;CACpB;AAED;;;GAGG;AACH,eAAO,MAAM,UAAU,2GACmF,CAAC;AAE3G,oFAAoF;AACpF,UAAU,YAAY;IACpB,MAAM,EAAE,IAAI,CAAC;IACb,QAAQ,EAAE,MAAM,EAAE,CAAC;IACnB,IAAI,EAAE,MAAM,CAAC;CACd;AAED,6FAA6F;AAC7F,KAAK,aAAa,GAAG;IAAE,OAAO,CAAC,EAAE,eAAe,CAAA;CAAE,CAAC;AAEnD;;;;;;;;GAQG;AACH,wBAAgB,oBAAoB,CAAC,OAAO,EAAE,OAAO,GAAG,eAAe,GAAG,SAAS,CAKlF;AAED;;;;;;GAMG;AACH,wBAAgB,kBAAkB,CAAC,OAAO,EAAE,OAAO,GAAG,YAAY,GAAG,SAAS,CAG7E;AAED;;;;GAIG;AACH,wBAAgB,WAAW,CAAC,CAAC,SAAS,MAAM,EAAE,OAAO,EAAE,OAAO,EAAE,MAAM,EAAE,CAAC,GAAG,CAAC,GAAG,aAAa,CAG5F"}
|
|
1
|
+
{"version":3,"file":"control-envelope.d.ts","sourceRoot":"","sources":["../../src/session/control-envelope.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,MAAM,iBAAiB,CAAC;AAC/C,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AACxB,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,cAAc,CAAC;AAE5C,kGAAkG;AAClG,UAAU,eAAe;IACvB,KAAK,EAAE,YAAY,CAAC;IACpB,+DAA+D;IAC/D,QAAQ,EAAE,MAAM,EAAE,CAAC;CACpB;AAED;;;GAGG;AACH,eAAO,MAAM,UAAU,2GACmF,CAAC;AAE3G,oFAAoF;AACpF,UAAU,YAAY;IACpB,MAAM,EAAE,IAAI,CAAC;IACb,QAAQ,EAAE,MAAM,EAAE,CAAC;IACnB,IAAI,EAAE,MAAM,CAAC;CACd;AAED;;;;;GAKG;AACH,eAAO,MAAM,iBAAiB,EAAE,CAAC,CAAC,WAIjC,CAAC;AAEF,6FAA6F;AAC7F,KAAK,aAAa,GAAG;IAAE,OAAO,CAAC,EAAE,eAAe,CAAA;CAAE,CAAC;AAEnD;;;;;;;;GAQG;AACH,wBAAgB,oBAAoB,CAAC,OAAO,EAAE,OAAO,GAAG,eAAe,GAAG,SAAS,CAKlF;AAED;;;;;;GAMG;AACH,wBAAgB,kBAAkB,CAAC,OAAO,EAAE,OAAO,GAAG,YAAY,GAAG,SAAS,CAG7E;AAED;;;;GAIG;AACH,wBAAgB,WAAW,CAAC,CAAC,SAAS,MAAM,EAAE,OAAO,EAAE,OAAO,EAAE,MAAM,EAAE,CAAC,GAAG,CAAC,GAAG,aAAa,CAG5F"}
|
|
@@ -1,9 +1,21 @@
|
|
|
1
1
|
import { SessionState } from '@reticlehq/core';
|
|
2
|
+
import { z } from 'zod';
|
|
2
3
|
/**
|
|
3
4
|
* Agent-readable hint returned when an action is refused mid-pause. Named, not free — the agent's
|
|
4
5
|
* recovery path (address the guidance, then reticle_resume) lives here in exactly one place.
|
|
5
6
|
*/
|
|
6
7
|
export const PAUSE_HINT = 'Paused by the human. Address the guidance, then call reticle_resume (or wait for the human to resume).';
|
|
8
|
+
/**
|
|
9
|
+
* outputSchema fields every action tool that can short-circuit on pause MUST declare, or a validating
|
|
10
|
+
* profile strips the WHOLE pause payload — and because `guidance` is drained-once, that loses the
|
|
11
|
+
* human's message entirely (not merely hides it). Declared here beside PausedResult so the schema and
|
|
12
|
+
* the runtime shape are the same source; spread into each act tool's outputSchema.
|
|
13
|
+
*/
|
|
14
|
+
export const pausedOutputShape = {
|
|
15
|
+
paused: z.boolean().optional(),
|
|
16
|
+
guidance: z.array(z.string()).optional(),
|
|
17
|
+
hint: z.string().optional(),
|
|
18
|
+
};
|
|
7
19
|
/**
|
|
8
20
|
* Build the piggyback control block for the agent's next tool result.
|
|
9
21
|
*
|
|
@@ -24,7 +36,7 @@ export function buildControlEnvelope(session) {
|
|
|
24
36
|
* PAUSE short-circuit. When the session is paused, drain the inbox and refuse the action so the
|
|
25
37
|
* human's pause cannot be driven through. Returns undefined when the action may proceed.
|
|
26
38
|
*
|
|
27
|
-
* `drainInbox
|
|
39
|
+
* `drainInbox` is the SOLE sink for guidance — draining here means the same message can never
|
|
28
40
|
* also surface in a piggyback, guaranteeing delivered-once.
|
|
29
41
|
*/
|
|
30
42
|
export function pausedShortCircuit(session) {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"control-envelope.js","sourceRoot":"","sources":["../../src/session/control-envelope.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,MAAM,iBAAiB,CAAC;
|
|
1
|
+
{"version":3,"file":"control-envelope.js","sourceRoot":"","sources":["../../src/session/control-envelope.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,MAAM,iBAAiB,CAAC;AAC/C,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAUxB;;;GAGG;AACH,MAAM,CAAC,MAAM,UAAU,GACrB,wGAAwG,CAAC;AAS3G;;;;;GAKG;AACH,MAAM,CAAC,MAAM,iBAAiB,GAAkB;IAC9C,MAAM,EAAE,CAAC,CAAC,OAAO,EAAE,CAAC,QAAQ,EAAE;IAC9B,QAAQ,EAAE,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,MAAM,EAAE,CAAC,CAAC,QAAQ,EAAE;IACxC,IAAI,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE;CAC5B,CAAC;AAKF;;;;;;;;GAQG;AACH,MAAM,UAAU,oBAAoB,CAAC,OAAgB;IACnD,MAAM,KAAK,GAAG,OAAO,CAAC,QAAQ,EAAE,CAAC;IACjC,MAAM,QAAQ,GAAG,OAAO,CAAC,UAAU,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC;IACzD,IAAI,KAAK,KAAK,YAAY,CAAC,MAAM,IAAI,QAAQ,CAAC,MAAM,KAAK,CAAC;QAAE,OAAO,SAAS,CAAC;IAC7E,OAAO,EAAE,KAAK,EAAE,QAAQ,EAAE,CAAC;AAC7B,CAAC;AAED;;;;;;GAMG;AACH,MAAM,UAAU,kBAAkB,CAAC,OAAgB;IACjD,IAAI,OAAO,CAAC,QAAQ,EAAE,KAAK,YAAY,CAAC,MAAM;QAAE,OAAO,SAAS,CAAC;IACjE,OAAO,EAAE,MAAM,EAAE,IAAI,EAAE,QAAQ,EAAE,OAAO,CAAC,UAAU,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,EAAE,IAAI,EAAE,UAAU,EAAE,CAAC;AAC/F,CAAC;AAED;;;;GAIG;AACH,MAAM,UAAU,WAAW,CAAmB,OAAgB,EAAE,MAAS;IACvE,MAAM,OAAO,GAAG,oBAAoB,CAAC,OAAO,CAAC,CAAC;IAC9C,OAAO,OAAO,KAAK,SAAS,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,GAAG,MAAM,EAAE,OAAO,EAAE,CAAC;AACjE,CAAC"}
|
|
@@ -3,7 +3,7 @@ import type { ToolDef } from '../tools/tools.js';
|
|
|
3
3
|
* Live-control agent tools: the agent's side of the human-in-the-loop control surface.
|
|
4
4
|
*
|
|
5
5
|
* - reticle_end_session: terminal stop. Sets state `ended` and syncs the panel (PRESENTER) with an
|
|
6
|
-
*
|
|
6
|
+
* optional summary. Idempotent — ending an already-ended session is a safe no-op.
|
|
7
7
|
* - reticle_resume: clears a human pause. Sets state `active` and syncs the panel.
|
|
8
8
|
* - reticle_messages: explicit poll — drains and returns the queued human notes.
|
|
9
9
|
*
|
|
@@ -12,7 +12,7 @@ const WAIT_READY_MAX_MS = 30000;
|
|
|
12
12
|
* Live-control agent tools: the agent's side of the human-in-the-loop control surface.
|
|
13
13
|
*
|
|
14
14
|
* - reticle_end_session: terminal stop. Sets state `ended` and syncs the panel (PRESENTER) with an
|
|
15
|
-
*
|
|
15
|
+
* optional summary. Idempotent — ending an already-ended session is a safe no-op.
|
|
16
16
|
* - reticle_resume: clears a human pause. Sets state `active` and syncs the panel.
|
|
17
17
|
* - reticle_messages: explicit poll — drains and returns the queued human notes.
|
|
18
18
|
*
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
import { SessionState, type HumanControlData } from '@reticlehq/core';
|
|
2
|
+
/** Live-control: a human note queued for the agent, stamped with session-relative elapsed time. */
|
|
3
|
+
export interface InboxMessage {
|
|
4
|
+
text: string;
|
|
5
|
+
t: number;
|
|
6
|
+
}
|
|
7
|
+
/**
|
|
8
|
+
* The human-in-the-loop half of a session: its lifecycle state, and the one-way inbox a person uses
|
|
9
|
+
* to talk to the agent driving their browser.
|
|
10
|
+
*
|
|
11
|
+
* Server-owned on purpose — a paused session has to stay paused even if the page reloads, so this
|
|
12
|
+
* cannot live in the tab. Split out of Session because it shares nothing with the transport, the
|
|
13
|
+
* ring buffer, or the journal: it is state a HUMAN changes, on a human's timescale, while everything
|
|
14
|
+
* else in Session is driven by the event stream.
|
|
15
|
+
*/
|
|
16
|
+
export declare class LiveControl {
|
|
17
|
+
#private;
|
|
18
|
+
state(): SessionState;
|
|
19
|
+
isPaused(): boolean;
|
|
20
|
+
isEnded(): boolean;
|
|
21
|
+
/** Set the lifecycle state. Echoing it to the presenter is the caller's job (one push per change). */
|
|
22
|
+
setState(next: SessionState): void;
|
|
23
|
+
/** Queue a human note. Empty/whitespace-only text is ignored so a stray enter cannot spam the agent. */
|
|
24
|
+
push(text: string, t: number): void;
|
|
25
|
+
/** Return the queued notes AND clear them — delivered once, so a hint never repeats. */
|
|
26
|
+
drain(): InboxMessage[];
|
|
27
|
+
/** Diagnostic read of the inbox depth (does not clear). */
|
|
28
|
+
size(): number;
|
|
29
|
+
/**
|
|
30
|
+
* The state a human control should move this session to, or undefined for "no change".
|
|
31
|
+
*
|
|
32
|
+
* Returning the decision rather than applying it keeps the ONE-PUSH-PER-TRANSITION rule enforceable
|
|
33
|
+
* by the caller: a no-op (resume while already active, pause after end) yields undefined and so
|
|
34
|
+
* cannot emit a presenter push. `ended` is terminal — pause and resume after it do nothing.
|
|
35
|
+
*/
|
|
36
|
+
nextStateFor(data: HumanControlData): SessionState | undefined;
|
|
37
|
+
}
|
|
38
|
+
//# sourceMappingURL=live-control.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"live-control.d.ts","sourceRoot":"","sources":["../../src/session/live-control.ts"],"names":[],"mappings":"AAAA,OAAO,EAAoB,YAAY,EAAE,KAAK,gBAAgB,EAAE,MAAM,iBAAiB,CAAC;AAExF,mGAAmG;AACnG,MAAM,WAAW,YAAY;IAC3B,IAAI,EAAE,MAAM,CAAC;IACb,CAAC,EAAE,MAAM,CAAC;CACX;AAED;;;;;;;;GAQG;AACH,qBAAa,WAAW;;IAItB,KAAK,IAAI,YAAY;IAIrB,QAAQ,IAAI,OAAO;IAInB,OAAO,IAAI,OAAO;IAIlB,sGAAsG;IACtG,QAAQ,CAAC,IAAI,EAAE,YAAY,GAAG,IAAI;IAIlC,wGAAwG;IACxG,IAAI,CAAC,IAAI,EAAE,MAAM,EAAE,CAAC,EAAE,MAAM,GAAG,IAAI;IAMnC,wFAAwF;IACxF,KAAK,IAAI,YAAY,EAAE;IAIvB,2DAA2D;IAC3D,IAAI,IAAI,MAAM;IAId;;;;;;OAMG;IACH,YAAY,CAAC,IAAI,EAAE,gBAAgB,GAAG,YAAY,GAAG,SAAS;CAa/D"}
|
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
import { HumanControlKind, SessionState } from '@reticlehq/core';
|
|
2
|
+
/**
|
|
3
|
+
* The human-in-the-loop half of a session: its lifecycle state, and the one-way inbox a person uses
|
|
4
|
+
* to talk to the agent driving their browser.
|
|
5
|
+
*
|
|
6
|
+
* Server-owned on purpose — a paused session has to stay paused even if the page reloads, so this
|
|
7
|
+
* cannot live in the tab. Split out of Session because it shares nothing with the transport, the
|
|
8
|
+
* ring buffer, or the journal: it is state a HUMAN changes, on a human's timescale, while everything
|
|
9
|
+
* else in Session is driven by the event stream.
|
|
10
|
+
*/
|
|
11
|
+
export class LiveControl {
|
|
12
|
+
#state = SessionState.ACTIVE;
|
|
13
|
+
#inbox = [];
|
|
14
|
+
state() {
|
|
15
|
+
return this.#state;
|
|
16
|
+
}
|
|
17
|
+
isPaused() {
|
|
18
|
+
return this.#state === SessionState.PAUSED;
|
|
19
|
+
}
|
|
20
|
+
isEnded() {
|
|
21
|
+
return this.#state === SessionState.ENDED;
|
|
22
|
+
}
|
|
23
|
+
/** Set the lifecycle state. Echoing it to the presenter is the caller's job (one push per change). */
|
|
24
|
+
setState(next) {
|
|
25
|
+
this.#state = next;
|
|
26
|
+
}
|
|
27
|
+
/** Queue a human note. Empty/whitespace-only text is ignored so a stray enter cannot spam the agent. */
|
|
28
|
+
push(text, t) {
|
|
29
|
+
const trimmed = text.trim();
|
|
30
|
+
if (trimmed.length === 0)
|
|
31
|
+
return;
|
|
32
|
+
this.#inbox.push({ text: trimmed, t });
|
|
33
|
+
}
|
|
34
|
+
/** Return the queued notes AND clear them — delivered once, so a hint never repeats. */
|
|
35
|
+
drain() {
|
|
36
|
+
return this.#inbox.splice(0, this.#inbox.length);
|
|
37
|
+
}
|
|
38
|
+
/** Diagnostic read of the inbox depth (does not clear). */
|
|
39
|
+
size() {
|
|
40
|
+
return this.#inbox.length;
|
|
41
|
+
}
|
|
42
|
+
/**
|
|
43
|
+
* The state a human control should move this session to, or undefined for "no change".
|
|
44
|
+
*
|
|
45
|
+
* Returning the decision rather than applying it keeps the ONE-PUSH-PER-TRANSITION rule enforceable
|
|
46
|
+
* by the caller: a no-op (resume while already active, pause after end) yields undefined and so
|
|
47
|
+
* cannot emit a presenter push. `ended` is terminal — pause and resume after it do nothing.
|
|
48
|
+
*/
|
|
49
|
+
nextStateFor(data) {
|
|
50
|
+
if (this.isEnded())
|
|
51
|
+
return undefined;
|
|
52
|
+
switch (data.kind) {
|
|
53
|
+
case HumanControlKind.PAUSE:
|
|
54
|
+
return this.isPaused() ? undefined : SessionState.PAUSED;
|
|
55
|
+
case HumanControlKind.RESUME:
|
|
56
|
+
return this.#state === SessionState.ACTIVE ? undefined : SessionState.ACTIVE;
|
|
57
|
+
case HumanControlKind.END:
|
|
58
|
+
return SessionState.ENDED;
|
|
59
|
+
default:
|
|
60
|
+
return undefined;
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
//# sourceMappingURL=live-control.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"live-control.js","sourceRoot":"","sources":["../../src/session/live-control.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,gBAAgB,EAAE,YAAY,EAAyB,MAAM,iBAAiB,CAAC;AAQxF;;;;;;;;GAQG;AACH,MAAM,OAAO,WAAW;IACtB,MAAM,GAAiB,YAAY,CAAC,MAAM,CAAC;IAClC,MAAM,GAAmB,EAAE,CAAC;IAErC,KAAK;QACH,OAAO,IAAI,CAAC,MAAM,CAAC;IACrB,CAAC;IAED,QAAQ;QACN,OAAO,IAAI,CAAC,MAAM,KAAK,YAAY,CAAC,MAAM,CAAC;IAC7C,CAAC;IAED,OAAO;QACL,OAAO,IAAI,CAAC,MAAM,KAAK,YAAY,CAAC,KAAK,CAAC;IAC5C,CAAC;IAED,sGAAsG;IACtG,QAAQ,CAAC,IAAkB;QACzB,IAAI,CAAC,MAAM,GAAG,IAAI,CAAC;IACrB,CAAC;IAED,wGAAwG;IACxG,IAAI,CAAC,IAAY,EAAE,CAAS;QAC1B,MAAM,OAAO,GAAG,IAAI,CAAC,IAAI,EAAE,CAAC;QAC5B,IAAI,OAAO,CAAC,MAAM,KAAK,CAAC;YAAE,OAAO;QACjC,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,EAAE,IAAI,EAAE,OAAO,EAAE,CAAC,EAAE,CAAC,CAAC;IACzC,CAAC;IAED,wFAAwF;IACxF,KAAK;QACH,OAAO,IAAI,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC,EAAE,IAAI,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC;IACnD,CAAC;IAED,2DAA2D;IAC3D,IAAI;QACF,OAAO,IAAI,CAAC,MAAM,CAAC,MAAM,CAAC;IAC5B,CAAC;IAED;;;;;;OAMG;IACH,YAAY,CAAC,IAAsB;QACjC,IAAI,IAAI,CAAC,OAAO,EAAE;YAAE,OAAO,SAAS,CAAC;QACrC,QAAQ,IAAI,CAAC,IAAI,EAAE,CAAC;YAClB,KAAK,gBAAgB,CAAC,KAAK;gBACzB,OAAO,IAAI,CAAC,QAAQ,EAAE,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,YAAY,CAAC,MAAM,CAAC;YAC3D,KAAK,gBAAgB,CAAC,MAAM;gBAC1B,OAAO,IAAI,CAAC,MAAM,KAAK,YAAY,CAAC,MAAM,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,YAAY,CAAC,MAAM,CAAC;YAC/E,KAAK,gBAAgB,CAAC,GAAG;gBACvB,OAAO,YAAY,CAAC,KAAK,CAAC;YAC5B;gBACE,OAAO,SAAS,CAAC;QACrB,CAAC;IACH,CAAC;CACF"}
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
import { type ReticleEvent } from '@reticlehq/core';
|
|
2
|
+
import { type AmbientCounts } from '../journal/ambient.js';
|
|
3
|
+
/**
|
|
4
|
+
* The two things a session learns by watching its own event stream, as opposed to storing.
|
|
5
|
+
*
|
|
6
|
+
* Both are LEVELS derived from a stream, and both have to outlive the ring buffer — which is what
|
|
7
|
+
* separates them from the buffer's job and earns them their own unit:
|
|
8
|
+
*
|
|
9
|
+
* ambient — which regions of the page move on their own (chat, tickers, live counters). Used by
|
|
10
|
+
* the settle oracle to ignore background motion, so an action isn't held open forever
|
|
11
|
+
* by churn it did not cause.
|
|
12
|
+
* blindSpots — how much of the page the SDK cannot observe (cross-origin frames, closed shadow
|
|
13
|
+
* roots). The SDK reports these only when the count CHANGES, so a page that mounts
|
|
14
|
+
* two frames at load announces them once and is silent forever after. Anything that
|
|
15
|
+
* infers coverage from a window of events therefore sees nothing and concludes the
|
|
16
|
+
* page was fully observed — a positive claim to have seen what we cannot see. Holding
|
|
17
|
+
* the level here makes coverage something to ask rather than infer.
|
|
18
|
+
*/
|
|
19
|
+
export declare class ObservedState {
|
|
20
|
+
#private;
|
|
21
|
+
/** Fold one already-attributed event into the learned state. */
|
|
22
|
+
observe(event: ReticleEvent): void;
|
|
23
|
+
/**
|
|
24
|
+
* Learned ambient-churn counts — seeded history PLUS this session — for the settle oracle, which
|
|
25
|
+
* wants the sharpest available picture of what moves on its own.
|
|
26
|
+
*/
|
|
27
|
+
ambientCounts(): AmbientCounts;
|
|
28
|
+
/**
|
|
29
|
+
* ONLY what this session observed — the correct input to persistence.
|
|
30
|
+
*
|
|
31
|
+
* Teardown accumulates by adding the session's counts onto the file it loaded. When the session's
|
|
32
|
+
* counts still contained the seeded ones, that addition wrote `2 x persisted + own` every run, so
|
|
33
|
+
* the map doubled per session: the file committed in this repo had reached ~9.1e23 (about 2^80,
|
|
34
|
+
* i.e. ~80 sessions of doubling). Keeping the seed separate makes the accumulation what it always
|
|
35
|
+
* claimed to be — history plus what is new.
|
|
36
|
+
*/
|
|
37
|
+
ownAmbientCounts(): AmbientCounts;
|
|
38
|
+
/**
|
|
39
|
+
* Seed from the persisted per-app map so the picture sharpens across sessions.
|
|
40
|
+
* In-session counts win: they describe this page as it is now.
|
|
41
|
+
*/
|
|
42
|
+
seedAmbient(counts: AmbientCounts): void;
|
|
43
|
+
/** Latest reported count per blind-spot kind, for the whole session. */
|
|
44
|
+
blindSpots(): Readonly<Record<string, number>>;
|
|
45
|
+
}
|
|
46
|
+
//# sourceMappingURL=observed-state.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"observed-state.d.ts","sourceRoot":"","sources":["../../src/session/observed-state.ts"],"names":[],"mappings":"AAAA,OAAO,EAAa,KAAK,YAAY,EAAE,MAAM,iBAAiB,CAAC;AAC/D,OAAO,EAAgB,KAAK,aAAa,EAAE,MAAM,uBAAuB,CAAC;AAEzE;;;;;;;;;;;;;;;GAeG;AACH,qBAAa,aAAa;;IAOxB,gEAAgE;IAChE,OAAO,CAAC,KAAK,EAAE,YAAY,GAAG,IAAI;IAclC;;;OAGG;IACH,aAAa,IAAI,aAAa;IAQ9B;;;;;;;;OAQG;IACH,gBAAgB,IAAI,aAAa;IAIjC;;;OAGG;IACH,WAAW,CAAC,MAAM,EAAE,aAAa,GAAG,IAAI;IAIxC,wEAAwE;IACxE,UAAU,IAAI,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;CAG/C"}
|
|
@@ -0,0 +1,76 @@
|
|
|
1
|
+
import { EventType } from '@reticlehq/core';
|
|
2
|
+
import { ambientKeyOf } from '../journal/ambient.js';
|
|
3
|
+
/**
|
|
4
|
+
* The two things a session learns by watching its own event stream, as opposed to storing.
|
|
5
|
+
*
|
|
6
|
+
* Both are LEVELS derived from a stream, and both have to outlive the ring buffer — which is what
|
|
7
|
+
* separates them from the buffer's job and earns them their own unit:
|
|
8
|
+
*
|
|
9
|
+
* ambient — which regions of the page move on their own (chat, tickers, live counters). Used by
|
|
10
|
+
* the settle oracle to ignore background motion, so an action isn't held open forever
|
|
11
|
+
* by churn it did not cause.
|
|
12
|
+
* blindSpots — how much of the page the SDK cannot observe (cross-origin frames, closed shadow
|
|
13
|
+
* roots). The SDK reports these only when the count CHANGES, so a page that mounts
|
|
14
|
+
* two frames at load announces them once and is silent forever after. Anything that
|
|
15
|
+
* infers coverage from a window of events therefore sees nothing and concludes the
|
|
16
|
+
* page was fully observed — a positive claim to have seen what we cannot see. Holding
|
|
17
|
+
* the level here makes coverage something to ask rather than infer.
|
|
18
|
+
*/
|
|
19
|
+
export class ObservedState {
|
|
20
|
+
/** What THIS session observed. Never contains seeded history — see seedAmbient. */
|
|
21
|
+
#ownAmbient = {};
|
|
22
|
+
/** What previous sessions learned, kept separate so it is never re-persisted as if newly seen. */
|
|
23
|
+
#seededAmbient = {};
|
|
24
|
+
#blindSpots = {};
|
|
25
|
+
/** Fold one already-attributed event into the learned state. */
|
|
26
|
+
observe(event) {
|
|
27
|
+
// Only UNATTRIBUTED events count as ambient: an event caused by an action is the action's work,
|
|
28
|
+
// and learning it as background would teach the settle oracle to ignore real effects.
|
|
29
|
+
if (event.actionId === undefined) {
|
|
30
|
+
const key = ambientKeyOf(event);
|
|
31
|
+
if (key !== undefined)
|
|
32
|
+
this.#ownAmbient[key] = (this.#ownAmbient[key] ?? 0) + 1;
|
|
33
|
+
}
|
|
34
|
+
if (event.type === EventType.BLIND_SPOT) {
|
|
35
|
+
const kind = event.data['kind'];
|
|
36
|
+
const count = event.data['count'];
|
|
37
|
+
if (typeof kind === 'string' && typeof count === 'number')
|
|
38
|
+
this.#blindSpots[kind] = count;
|
|
39
|
+
}
|
|
40
|
+
}
|
|
41
|
+
/**
|
|
42
|
+
* Learned ambient-churn counts — seeded history PLUS this session — for the settle oracle, which
|
|
43
|
+
* wants the sharpest available picture of what moves on its own.
|
|
44
|
+
*/
|
|
45
|
+
ambientCounts() {
|
|
46
|
+
const merged = { ...this.#seededAmbient };
|
|
47
|
+
for (const [key, count] of Object.entries(this.#ownAmbient)) {
|
|
48
|
+
merged[key] = (merged[key] ?? 0) + count;
|
|
49
|
+
}
|
|
50
|
+
return merged;
|
|
51
|
+
}
|
|
52
|
+
/**
|
|
53
|
+
* ONLY what this session observed — the correct input to persistence.
|
|
54
|
+
*
|
|
55
|
+
* Teardown accumulates by adding the session's counts onto the file it loaded. When the session's
|
|
56
|
+
* counts still contained the seeded ones, that addition wrote `2 x persisted + own` every run, so
|
|
57
|
+
* the map doubled per session: the file committed in this repo had reached ~9.1e23 (about 2^80,
|
|
58
|
+
* i.e. ~80 sessions of doubling). Keeping the seed separate makes the accumulation what it always
|
|
59
|
+
* claimed to be — history plus what is new.
|
|
60
|
+
*/
|
|
61
|
+
ownAmbientCounts() {
|
|
62
|
+
return this.#ownAmbient;
|
|
63
|
+
}
|
|
64
|
+
/**
|
|
65
|
+
* Seed from the persisted per-app map so the picture sharpens across sessions.
|
|
66
|
+
* In-session counts win: they describe this page as it is now.
|
|
67
|
+
*/
|
|
68
|
+
seedAmbient(counts) {
|
|
69
|
+
this.#seededAmbient = { ...counts };
|
|
70
|
+
}
|
|
71
|
+
/** Latest reported count per blind-spot kind, for the whole session. */
|
|
72
|
+
blindSpots() {
|
|
73
|
+
return this.#blindSpots;
|
|
74
|
+
}
|
|
75
|
+
}
|
|
76
|
+
//# sourceMappingURL=observed-state.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"observed-state.js","sourceRoot":"","sources":["../../src/session/observed-state.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAqB,MAAM,iBAAiB,CAAC;AAC/D,OAAO,EAAE,YAAY,EAAsB,MAAM,uBAAuB,CAAC;AAEzE;;;;;;;;;;;;;;;GAeG;AACH,MAAM,OAAO,aAAa;IACxB,mFAAmF;IAC1E,WAAW,GAAkB,EAAE,CAAC;IACzC,kGAAkG;IAClG,cAAc,GAAkB,EAAE,CAAC;IAC1B,WAAW,GAA2B,EAAE,CAAC;IAElD,gEAAgE;IAChE,OAAO,CAAC,KAAmB;QACzB,gGAAgG;QAChG,sFAAsF;QACtF,IAAI,KAAK,CAAC,QAAQ,KAAK,SAAS,EAAE,CAAC;YACjC,MAAM,GAAG,GAAG,YAAY,CAAC,KAAK,CAAC,CAAC;YAChC,IAAI,GAAG,KAAK,SAAS;gBAAE,IAAI,CAAC,WAAW,CAAC,GAAG,CAAC,GAAG,CAAC,IAAI,CAAC,WAAW,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC,GAAG,CAAC,CAAC;QAClF,CAAC;QACD,IAAI,KAAK,CAAC,IAAI,KAAK,SAAS,CAAC,UAAU,EAAE,CAAC;YACxC,MAAM,IAAI,GAAG,KAAK,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;YAChC,MAAM,KAAK,GAAG,KAAK,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;YAClC,IAAI,OAAO,IAAI,KAAK,QAAQ,IAAI,OAAO,KAAK,KAAK,QAAQ;gBAAE,IAAI,CAAC,WAAW,CAAC,IAAI,CAAC,GAAG,KAAK,CAAC;QAC5F,CAAC;IACH,CAAC;IAED;;;OAGG;IACH,aAAa;QACX,MAAM,MAAM,GAAkB,EAAE,GAAG,IAAI,CAAC,cAAc,EAAE,CAAC;QACzD,KAAK,MAAM,CAAC,GAAG,EAAE,KAAK,CAAC,IAAI,MAAM,CAAC,OAAO,CAAC,IAAI,CAAC,WAAW,CAAC,EAAE,CAAC;YAC5D,MAAM,CAAC,GAAG,CAAC,GAAG,CAAC,MAAM,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC,GAAG,KAAK,CAAC;QAC3C,CAAC;QACD,OAAO,MAAM,CAAC;IAChB,CAAC;IAED;;;;;;;;OAQG;IACH,gBAAgB;QACd,OAAO,IAAI,CAAC,WAAW,CAAC;IAC1B,CAAC;IAED;;;OAGG;IACH,WAAW,CAAC,MAAqB;QAC/B,IAAI,CAAC,cAAc,GAAG,EAAE,GAAG,MAAM,EAAE,CAAC;IACtC,CAAC;IAED,wEAAwE;IACxE,UAAU;QACR,OAAO,IAAI,CAAC,WAAW,CAAC;IAC1B,CAAC;CACF"}
|