@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,93 @@
|
|
|
1
|
+
import { EventType } from '@reticlehq/core';
|
|
2
|
+
const TIER = { SIGNAL: 0, CONSEQUENCE: 1, PRESENCE: 2 };
|
|
3
|
+
function pathname(url) {
|
|
4
|
+
if (typeof url !== 'string')
|
|
5
|
+
return undefined;
|
|
6
|
+
try {
|
|
7
|
+
return new URL(url, 'http://x').pathname;
|
|
8
|
+
}
|
|
9
|
+
catch {
|
|
10
|
+
return url;
|
|
11
|
+
}
|
|
12
|
+
}
|
|
13
|
+
/** Propose ranked consequences from a recorded event window. Deduped; strongest first. */
|
|
14
|
+
export function proposeConsequences(events) {
|
|
15
|
+
const seen = new Set();
|
|
16
|
+
const proposals = [];
|
|
17
|
+
const add = (key, proposal) => {
|
|
18
|
+
if (seen.has(key))
|
|
19
|
+
return;
|
|
20
|
+
seen.add(key);
|
|
21
|
+
proposals.push(proposal);
|
|
22
|
+
};
|
|
23
|
+
for (const event of events) {
|
|
24
|
+
const data = event.data;
|
|
25
|
+
switch (event.type) {
|
|
26
|
+
case EventType.SIGNAL: {
|
|
27
|
+
const name = data['name'];
|
|
28
|
+
if (typeof name === 'string') {
|
|
29
|
+
add(`signal:${name}`, {
|
|
30
|
+
predicate: { kind: 'signal', name },
|
|
31
|
+
tier: TIER.SIGNAL,
|
|
32
|
+
label: `signal "${name}" fires`,
|
|
33
|
+
weak: false,
|
|
34
|
+
});
|
|
35
|
+
}
|
|
36
|
+
break;
|
|
37
|
+
}
|
|
38
|
+
case EventType.NET_REQUEST: {
|
|
39
|
+
const path = pathname(data['url']);
|
|
40
|
+
const method = typeof data['method'] === 'string' ? data['method'] : 'GET';
|
|
41
|
+
if (path !== undefined) {
|
|
42
|
+
add(`net:${method} ${path}`, {
|
|
43
|
+
predicate: { kind: 'net', method, urlContains: path, status: data['status'] },
|
|
44
|
+
tier: TIER.CONSEQUENCE,
|
|
45
|
+
label: `${method} ${path} responds`,
|
|
46
|
+
weak: false,
|
|
47
|
+
});
|
|
48
|
+
}
|
|
49
|
+
break;
|
|
50
|
+
}
|
|
51
|
+
case EventType.STATE_CHANGE: {
|
|
52
|
+
const name = data['name'];
|
|
53
|
+
if (typeof name === 'string') {
|
|
54
|
+
add(`state:${name}`, {
|
|
55
|
+
predicate: { kind: 'state', store: name, path: data['path'] },
|
|
56
|
+
tier: TIER.CONSEQUENCE,
|
|
57
|
+
label: `state "${name}" changes`,
|
|
58
|
+
weak: false,
|
|
59
|
+
});
|
|
60
|
+
}
|
|
61
|
+
break;
|
|
62
|
+
}
|
|
63
|
+
case EventType.ROUTE_CHANGE: {
|
|
64
|
+
const to = data['pathname'];
|
|
65
|
+
if (typeof to === 'string') {
|
|
66
|
+
add(`route:${to}`, {
|
|
67
|
+
predicate: { kind: 'route', to },
|
|
68
|
+
tier: TIER.CONSEQUENCE,
|
|
69
|
+
label: `route changes to ${to}`,
|
|
70
|
+
weak: false,
|
|
71
|
+
});
|
|
72
|
+
}
|
|
73
|
+
break;
|
|
74
|
+
}
|
|
75
|
+
case EventType.DOM_ADDED: {
|
|
76
|
+
const name = data['name'];
|
|
77
|
+
if (typeof name === 'string' && name.length > 0) {
|
|
78
|
+
add(`presence:${name}`, {
|
|
79
|
+
predicate: { kind: 'element', name },
|
|
80
|
+
tier: TIER.PRESENCE,
|
|
81
|
+
label: `"${name}" appears (presence only — prefer a consequence)`,
|
|
82
|
+
weak: true,
|
|
83
|
+
});
|
|
84
|
+
}
|
|
85
|
+
break;
|
|
86
|
+
}
|
|
87
|
+
default:
|
|
88
|
+
break;
|
|
89
|
+
}
|
|
90
|
+
}
|
|
91
|
+
return proposals.sort((a, b) => a.tier - b.tier);
|
|
92
|
+
}
|
|
93
|
+
//# sourceMappingURL=propose-consequences.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"propose-consequences.js","sourceRoot":"","sources":["../../src/oracles/propose-consequences.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Self-instrumentation — the most agent-native item. When capability gaps exist (a flow can only assert
|
|
3
|
+
* presence because no signal fires, an unregistered store, a missing testid), the layer emits ready-to-
|
|
4
|
+
* apply instrumentation proposals as concrete diffs, so the AGENT closes the gap and the app's
|
|
5
|
+
* observability compounds run over run — instead of a human being a prerequisite. Deterministic mapping
|
|
6
|
+
* from a located gap to the code to insert; pure and testable. Result-enrichment wiring is a later step.
|
|
7
|
+
*/
|
|
8
|
+
export declare const InstrumentationGapKind: {
|
|
9
|
+
readonly MISSING_SIGNAL: "missing-signal";
|
|
10
|
+
readonly UNREGISTERED_STORE: "unregistered-store";
|
|
11
|
+
readonly MISSING_TESTID: "missing-testid";
|
|
12
|
+
};
|
|
13
|
+
export type InstrumentationGapKind = (typeof InstrumentationGapKind)[keyof typeof InstrumentationGapKind];
|
|
14
|
+
export interface InstrumentationGap {
|
|
15
|
+
kind: InstrumentationGapKind;
|
|
16
|
+
file: string;
|
|
17
|
+
line: number;
|
|
18
|
+
/** The name to instrument with — a signal name, store name, or testid. */
|
|
19
|
+
name: string;
|
|
20
|
+
/** Why this gap matters (e.g. "checkout flow asserts presence only"). */
|
|
21
|
+
context?: string;
|
|
22
|
+
}
|
|
23
|
+
export interface InstrumentationProposal {
|
|
24
|
+
file: string;
|
|
25
|
+
line: number;
|
|
26
|
+
/** The code to insert. */
|
|
27
|
+
insert: string;
|
|
28
|
+
rationale: string;
|
|
29
|
+
}
|
|
30
|
+
/** Turn located capability gaps into ready-to-apply instrumentation proposals. Deterministic. */
|
|
31
|
+
export declare function proposeInstrumentation(gaps: readonly InstrumentationGap[]): InstrumentationProposal[];
|
|
32
|
+
//# sourceMappingURL=self-instrument.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"self-instrument.d.ts","sourceRoot":"","sources":["../../src/oracles/self-instrument.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,eAAO,MAAM,sBAAsB;;;;CAIzB,CAAC;AACX,MAAM,MAAM,sBAAsB,GAChC,CAAC,OAAO,sBAAsB,CAAC,CAAC,MAAM,OAAO,sBAAsB,CAAC,CAAC;AAEvE,MAAM,WAAW,kBAAkB;IACjC,IAAI,EAAE,sBAAsB,CAAC;IAC7B,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;IACb,0EAA0E;IAC1E,IAAI,EAAE,MAAM,CAAC;IACb,yEAAyE;IACzE,OAAO,CAAC,EAAE,MAAM,CAAC;CAClB;AAED,MAAM,WAAW,uBAAuB;IACtC,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;IACb,0BAA0B;IAC1B,MAAM,EAAE,MAAM,CAAC;IACf,SAAS,EAAE,MAAM,CAAC;CACnB;AA4BD,iGAAiG;AACjG,wBAAgB,sBAAsB,CACpC,IAAI,EAAE,SAAS,kBAAkB,EAAE,GAClC,uBAAuB,EAAE,CAO3B"}
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Self-instrumentation — the most agent-native item. When capability gaps exist (a flow can only assert
|
|
3
|
+
* presence because no signal fires, an unregistered store, a missing testid), the layer emits ready-to-
|
|
4
|
+
* apply instrumentation proposals as concrete diffs, so the AGENT closes the gap and the app's
|
|
5
|
+
* observability compounds run over run — instead of a human being a prerequisite. Deterministic mapping
|
|
6
|
+
* from a located gap to the code to insert; pure and testable. Result-enrichment wiring is a later step.
|
|
7
|
+
*/
|
|
8
|
+
export const InstrumentationGapKind = {
|
|
9
|
+
MISSING_SIGNAL: 'missing-signal',
|
|
10
|
+
UNREGISTERED_STORE: 'unregistered-store',
|
|
11
|
+
MISSING_TESTID: 'missing-testid',
|
|
12
|
+
};
|
|
13
|
+
/** PascalCase a store name for a `useX.getState` hint (cart → Cart). */
|
|
14
|
+
function pascal(name) {
|
|
15
|
+
return name.length === 0 ? name : name[0]?.toUpperCase() + name.slice(1);
|
|
16
|
+
}
|
|
17
|
+
function insertFor(gap) {
|
|
18
|
+
switch (gap.kind) {
|
|
19
|
+
case InstrumentationGapKind.MISSING_SIGNAL:
|
|
20
|
+
return `reticle.signal('${gap.name}');`;
|
|
21
|
+
case InstrumentationGapKind.UNREGISTERED_STORE:
|
|
22
|
+
return `registerStore('${gap.name}', () => use${pascal(gap.name)}.getState());`;
|
|
23
|
+
case InstrumentationGapKind.MISSING_TESTID:
|
|
24
|
+
return `data-testid="${gap.name}"`;
|
|
25
|
+
}
|
|
26
|
+
}
|
|
27
|
+
function rationaleFor(gap) {
|
|
28
|
+
const base = gap.kind === InstrumentationGapKind.MISSING_SIGNAL
|
|
29
|
+
? `emit a consequence signal so verification proves the outcome, not just presence`
|
|
30
|
+
: gap.kind === InstrumentationGapKind.UNREGISTERED_STORE
|
|
31
|
+
? `register the store so state assertions can read the source of truth`
|
|
32
|
+
: `add a stable testid so the anchor survives refactors`;
|
|
33
|
+
return gap.context === undefined ? base : `${base} — ${gap.context}`;
|
|
34
|
+
}
|
|
35
|
+
/** Turn located capability gaps into ready-to-apply instrumentation proposals. Deterministic. */
|
|
36
|
+
export function proposeInstrumentation(gaps) {
|
|
37
|
+
return gaps.map((gap) => ({
|
|
38
|
+
file: gap.file,
|
|
39
|
+
line: gap.line,
|
|
40
|
+
insert: insertFor(gap),
|
|
41
|
+
rationale: rationaleFor(gap),
|
|
42
|
+
}));
|
|
43
|
+
}
|
|
44
|
+
//# sourceMappingURL=self-instrument.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"self-instrument.js","sourceRoot":"","sources":["../../src/oracles/self-instrument.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,MAAM,CAAC,MAAM,sBAAsB,GAAG;IACpC,cAAc,EAAE,gBAAgB;IAChC,kBAAkB,EAAE,oBAAoB;IACxC,cAAc,EAAE,gBAAgB;CACxB,CAAC;AAsBX,wEAAwE;AACxE,SAAS,MAAM,CAAC,IAAY;IAC1B,OAAO,IAAI,CAAC,MAAM,KAAK,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,WAAW,EAAE,GAAG,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC;AAC3E,CAAC;AAED,SAAS,SAAS,CAAC,GAAuB;IACxC,QAAQ,GAAG,CAAC,IAAI,EAAE,CAAC;QACjB,KAAK,sBAAsB,CAAC,cAAc;YACxC,OAAO,mBAAmB,GAAG,CAAC,IAAI,KAAK,CAAC;QAC1C,KAAK,sBAAsB,CAAC,kBAAkB;YAC5C,OAAO,kBAAkB,GAAG,CAAC,IAAI,eAAe,MAAM,CAAC,GAAG,CAAC,IAAI,CAAC,eAAe,CAAC;QAClF,KAAK,sBAAsB,CAAC,cAAc;YACxC,OAAO,gBAAgB,GAAG,CAAC,IAAI,GAAG,CAAC;IACvC,CAAC;AACH,CAAC;AAED,SAAS,YAAY,CAAC,GAAuB;IAC3C,MAAM,IAAI,GACR,GAAG,CAAC,IAAI,KAAK,sBAAsB,CAAC,cAAc;QAChD,CAAC,CAAC,iFAAiF;QACnF,CAAC,CAAC,GAAG,CAAC,IAAI,KAAK,sBAAsB,CAAC,kBAAkB;YACtD,CAAC,CAAC,qEAAqE;YACvE,CAAC,CAAC,sDAAsD,CAAC;IAC/D,OAAO,GAAG,CAAC,OAAO,KAAK,SAAS,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,GAAG,IAAI,MAAM,GAAG,CAAC,OAAO,EAAE,CAAC;AACvE,CAAC;AAED,iGAAiG;AACjG,MAAM,UAAU,sBAAsB,CACpC,IAAmC;IAEnC,OAAO,IAAI,CAAC,GAAG,CAAC,CAAC,GAAG,EAAE,EAAE,CAAC,CAAC;QACxB,IAAI,EAAE,GAAG,CAAC,IAAI;QACd,IAAI,EAAE,GAAG,CAAC,IAAI;QACd,MAAM,EAAE,SAAS,CAAC,GAAG,CAAC;QACtB,SAAS,EAAE,YAAY,CAAC,GAAG,CAAC;KAC7B,CAAC,CAAC,CAAC;AACN,CAAC"}
|
package/dist/pairing-token.d.ts
CHANGED
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
* Auto-provisioned bridge pairing token. The daemon reads-or-creates a per-user secret at
|
|
3
3
|
* ~/.reticle/pairing-token; the bridge then requires it, so a rogue localhost app (which, running in a
|
|
4
4
|
* browser sandbox, cannot read the file) can no longer register/drive sessions just by being on a
|
|
5
|
-
* loopback origin. The build plugins read the same file Node-side and inject it into connect
|
|
5
|
+
* loopback origin. The build plugins read the same file Node-side and inject it into connect, so a
|
|
6
6
|
* legitimately-served app stays zero-config.
|
|
7
7
|
*/
|
|
8
8
|
/** Injectable IO + randomness so the provisioner is unit-testable without touching the real home dir. */
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
import { PhenomenonType, type JournalAction, type ReticleEvent } from '@reticlehq/core';
|
|
2
|
+
/**
|
|
3
|
+
* A detected phenomenon — a named, evidence-backed anomaly over the journal. Deterministic matchers, no
|
|
4
|
+
* scanning by the agent: the layer names the fault, the agent acts on the name. `pre-hydration-click`
|
|
5
|
+
* lands once the hydration signal (a later item) exists; the three here need only journal data.
|
|
6
|
+
*/
|
|
7
|
+
export interface Finding {
|
|
8
|
+
phenomenon: PhenomenonType;
|
|
9
|
+
evidence: Record<string, unknown>;
|
|
10
|
+
}
|
|
11
|
+
/** A request that started (NET_PENDING) but never completed (no NET_REQUEST with the same id). */
|
|
12
|
+
export declare function detectHungRequests(events: readonly ReticleEvent[]): Finding[];
|
|
13
|
+
/** A 5xx response observed while the page was hidden — an error the user never sees. */
|
|
14
|
+
export declare function detectHidden500(events: readonly ReticleEvent[]): Finding[];
|
|
15
|
+
/** An act that dispatched but attributed no events — the app did nothing. */
|
|
16
|
+
export declare function detectDeadClicks(actions: readonly JournalAction[]): Finding[];
|
|
17
|
+
/**
|
|
18
|
+
* A click that landed BEFORE React hydration attached handlers — a silent no-op. Detectable only in-app:
|
|
19
|
+
* the hydration-complete signal's time vs the click action's dispatch. No signal ⇒ can't tell (not a
|
|
20
|
+
* React app, or hydration never completed), so we don't guess.
|
|
21
|
+
*/
|
|
22
|
+
export declare function detectPreHydrationClicks(events: readonly ReticleEvent[], actions: readonly JournalAction[]): Finding[];
|
|
23
|
+
/** A React error boundary that caught and swallowed — surfaced on the signal channel by the adapter. */
|
|
24
|
+
export declare function detectSwallowedErrors(events: readonly ReticleEvent[]): Finding[];
|
|
25
|
+
/** Run every journal-only matcher over a session's events + actions. */
|
|
26
|
+
export declare function detectPhenomena(events: readonly ReticleEvent[], actions: readonly JournalAction[]): Finding[];
|
|
27
|
+
//# sourceMappingURL=phenomena.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"phenomena.d.ts","sourceRoot":"","sources":["../../src/phenomena/phenomena.ts"],"names":[],"mappings":"AAAA,OAAO,EAGL,cAAc,EAGd,KAAK,aAAa,EAClB,KAAK,YAAY,EAClB,MAAM,iBAAiB,CAAC;AAEzB;;;;GAIG;AACH,MAAM,WAAW,OAAO;IACtB,UAAU,EAAE,cAAc,CAAC;IAC3B,QAAQ,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;CACnC;AAKD,kGAAkG;AAClG,wBAAgB,kBAAkB,CAAC,MAAM,EAAE,SAAS,YAAY,EAAE,GAAG,OAAO,EAAE,CAe7E;AAED,wFAAwF;AACxF,wBAAgB,eAAe,CAAC,MAAM,EAAE,SAAS,YAAY,EAAE,GAAG,OAAO,EAAE,CAmB1E;AAED,6EAA6E;AAC7E,wBAAgB,gBAAgB,CAAC,OAAO,EAAE,SAAS,aAAa,EAAE,GAAG,OAAO,EAAE,CAW7E;AAED;;;;GAIG;AACH,wBAAgB,wBAAwB,CACtC,MAAM,EAAE,SAAS,YAAY,EAAE,EAC/B,OAAO,EAAE,SAAS,aAAa,EAAE,GAChC,OAAO,EAAE,CAWX;AAED,wGAAwG;AACxG,wBAAgB,qBAAqB,CAAC,MAAM,EAAE,SAAS,YAAY,EAAE,GAAG,OAAO,EAAE,CAahF;AAED,wEAAwE;AACxE,wBAAgB,eAAe,CAC7B,MAAM,EAAE,SAAS,YAAY,EAAE,EAC/B,OAAO,EAAE,SAAS,aAAa,EAAE,GAChC,OAAO,EAAE,CAQX"}
|
|
@@ -0,0 +1,102 @@
|
|
|
1
|
+
import { EventType, FlowStepTool, PhenomenonType, RETICLE_ERROR_BOUNDARY_SIGNAL, RETICLE_HYDRATION_SIGNAL, } from '@reticlehq/core';
|
|
2
|
+
/** ACT tools that represent a user-style interaction (a "click"), for dead-click detection. */
|
|
3
|
+
const CLICK_TOOLS = new Set([FlowStepTool.ACT, FlowStepTool.ACT_AND_WAIT]);
|
|
4
|
+
/** A request that started (NET_PENDING) but never completed (no NET_REQUEST with the same id). */
|
|
5
|
+
export function detectHungRequests(events) {
|
|
6
|
+
const completed = new Set();
|
|
7
|
+
for (const event of events) {
|
|
8
|
+
if (event.type === EventType.NET_REQUEST)
|
|
9
|
+
completed.add(event.data['id']);
|
|
10
|
+
}
|
|
11
|
+
const findings = [];
|
|
12
|
+
for (const event of events) {
|
|
13
|
+
if (event.type !== EventType.NET_PENDING)
|
|
14
|
+
continue;
|
|
15
|
+
if (completed.has(event.data['id']))
|
|
16
|
+
continue;
|
|
17
|
+
findings.push({
|
|
18
|
+
phenomenon: PhenomenonType.HUNG_REQUEST,
|
|
19
|
+
evidence: { id: event.data['id'], method: event.data['method'], url: event.data['url'] },
|
|
20
|
+
});
|
|
21
|
+
}
|
|
22
|
+
return findings;
|
|
23
|
+
}
|
|
24
|
+
/** A 5xx response observed while the page was hidden — an error the user never sees. */
|
|
25
|
+
export function detectHidden500(events) {
|
|
26
|
+
const findings = [];
|
|
27
|
+
let hidden = false;
|
|
28
|
+
for (const event of events) {
|
|
29
|
+
if (event.type === EventType.PAGE_HEALTH) {
|
|
30
|
+
const h = event.data['hidden'];
|
|
31
|
+
if (typeof h === 'boolean')
|
|
32
|
+
hidden = h;
|
|
33
|
+
continue;
|
|
34
|
+
}
|
|
35
|
+
if (event.type !== EventType.NET_REQUEST)
|
|
36
|
+
continue;
|
|
37
|
+
const status = event.data['status'];
|
|
38
|
+
if (hidden && typeof status === 'number' && status >= 500) {
|
|
39
|
+
findings.push({
|
|
40
|
+
phenomenon: PhenomenonType.HIDDEN_500,
|
|
41
|
+
evidence: { url: event.data['url'], status, method: event.data['method'] },
|
|
42
|
+
});
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
return findings;
|
|
46
|
+
}
|
|
47
|
+
/** An act that dispatched but attributed no events — the app did nothing. */
|
|
48
|
+
export function detectDeadClicks(actions) {
|
|
49
|
+
const findings = [];
|
|
50
|
+
for (const action of actions) {
|
|
51
|
+
if (!CLICK_TOOLS.has(action.tool))
|
|
52
|
+
continue;
|
|
53
|
+
if (action.seqRange !== undefined)
|
|
54
|
+
continue; // it caused something → not dead
|
|
55
|
+
findings.push({
|
|
56
|
+
phenomenon: PhenomenonType.DEAD_CLICK,
|
|
57
|
+
evidence: { actionId: action.actionId, tool: action.tool, args: action.args },
|
|
58
|
+
});
|
|
59
|
+
}
|
|
60
|
+
return findings;
|
|
61
|
+
}
|
|
62
|
+
/**
|
|
63
|
+
* A click that landed BEFORE React hydration attached handlers — a silent no-op. Detectable only in-app:
|
|
64
|
+
* the hydration-complete signal's time vs the click action's dispatch. No signal ⇒ can't tell (not a
|
|
65
|
+
* React app, or hydration never completed), so we don't guess.
|
|
66
|
+
*/
|
|
67
|
+
export function detectPreHydrationClicks(events, actions) {
|
|
68
|
+
const hydration = events.find((e) => e.type === EventType.SIGNAL && e.data['name'] === RETICLE_HYDRATION_SIGNAL);
|
|
69
|
+
if (hydration === undefined)
|
|
70
|
+
return [];
|
|
71
|
+
return actions
|
|
72
|
+
.filter((a) => CLICK_TOOLS.has(a.tool) && a.tRange.from < hydration.t)
|
|
73
|
+
.map((a) => ({
|
|
74
|
+
phenomenon: PhenomenonType.PRE_HYDRATION_CLICK,
|
|
75
|
+
evidence: { actionId: a.actionId, clickedAt: a.tRange.from, hydratedAt: hydration.t },
|
|
76
|
+
}));
|
|
77
|
+
}
|
|
78
|
+
/** A React error boundary that caught and swallowed — surfaced on the signal channel by the adapter. */
|
|
79
|
+
export function detectSwallowedErrors(events) {
|
|
80
|
+
const findings = [];
|
|
81
|
+
for (const event of events) {
|
|
82
|
+
if (event.type === EventType.SIGNAL && event.data['name'] === RETICLE_ERROR_BOUNDARY_SIGNAL) {
|
|
83
|
+
const detail = event.data['data'];
|
|
84
|
+
findings.push({
|
|
85
|
+
phenomenon: PhenomenonType.SWALLOWED_ERROR,
|
|
86
|
+
evidence: typeof detail === 'object' && detail !== null ? detail : {},
|
|
87
|
+
});
|
|
88
|
+
}
|
|
89
|
+
}
|
|
90
|
+
return findings;
|
|
91
|
+
}
|
|
92
|
+
/** Run every journal-only matcher over a session's events + actions. */
|
|
93
|
+
export function detectPhenomena(events, actions) {
|
|
94
|
+
return [
|
|
95
|
+
...detectHungRequests(events),
|
|
96
|
+
...detectHidden500(events),
|
|
97
|
+
...detectDeadClicks(actions),
|
|
98
|
+
...detectPreHydrationClicks(events, actions),
|
|
99
|
+
...detectSwallowedErrors(events),
|
|
100
|
+
];
|
|
101
|
+
}
|
|
102
|
+
//# sourceMappingURL=phenomena.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"phenomena.js","sourceRoot":"","sources":["../../src/phenomena/phenomena.ts"],"names":[],"mappings":"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"}
|
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
* BrowserPool — one headless browser, many cheap isolated contexts.
|
|
3
3
|
*
|
|
4
4
|
* The "10 agents test 10 flows" scenario does NOT mean 10 Chromiums (each ~hundreds of MB). It means
|
|
5
|
-
* ONE launched browser and N `newContext
|
|
5
|
+
* ONE launched browser and N `newContext` calls (each ~a few MB, fully isolated cookies/storage).
|
|
6
6
|
* The pool owns that single browser, hands out per-flow leases, caps concurrency so a machine is
|
|
7
7
|
* never overwhelmed (over-cap acquires queue FIFO), and transparently relaunches if the browser dies.
|
|
8
8
|
*
|
|
@@ -33,7 +33,7 @@ export interface PooledBrowser {
|
|
|
33
33
|
}
|
|
34
34
|
/** Produces a freshly launched browser. Injected so tests can supply a fake. */
|
|
35
35
|
export type Launcher = () => Promise<PooledBrowser>;
|
|
36
|
-
/** A leased context+page for one flow. `release
|
|
36
|
+
/** A leased context+page for one flow. `release` frees the slot and closes the context. */
|
|
37
37
|
export interface Lease {
|
|
38
38
|
readonly sessionId: string;
|
|
39
39
|
readonly url: string;
|
|
@@ -48,7 +48,7 @@ interface BrowserPoolOptions {
|
|
|
48
48
|
genSessionId: () => string;
|
|
49
49
|
/** Injected clock (ms). Defaults to Date.now; tests pass a controllable one. */
|
|
50
50
|
now?: () => number;
|
|
51
|
-
/** A lease untouched for longer than this is reclaimed by sweepExpired
|
|
51
|
+
/** A lease untouched for longer than this is reclaimed by sweepExpired. */
|
|
52
52
|
leaseTtlMs?: number;
|
|
53
53
|
/** Per-lease navigation timeout — a page that won't load fails its own lease, never blocks a slot. */
|
|
54
54
|
navTimeoutMs?: number;
|
|
@@ -61,6 +61,8 @@ export declare class BrowserPool {
|
|
|
61
61
|
#private;
|
|
62
62
|
constructor(launch: Launcher, opts: BrowserPoolOptions);
|
|
63
63
|
/** Currently leased contexts. */
|
|
64
|
+
/** Max simultaneous leases — the ceiling the parallel suite sizes its concurrency to. */
|
|
65
|
+
capacity(): number;
|
|
64
66
|
activeCount(): number;
|
|
65
67
|
/** Acquires waiting for a free slot. */
|
|
66
68
|
queuedCount(): number;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"browser-pool.d.ts","sourceRoot":"","sources":["../../src/pool/browser-pool.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AAEH,uFAAuF;AACvF,MAAM,WAAW,UAAU;IACzB,IAAI,CAAC,GAAG,EAAE,MAAM,EAAE,IAAI,CAAC,EAAE;QAAE,SAAS,CAAC,EAAE,MAAM,CAAA;KAAE,GAAG,OAAO,CAAC,OAAO,CAAC,CAAC;IACnE,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC,CAAC;IACvB,sGAAsG;IACtG,OAAO,CAAC,OAAO,EAAE,MAAM,IAAI,GAAG,IAAI,CAAC;CACpC;AAED,uGAAuG;AACvG,MAAM,WAAW,aAAa;IAC5B,OAAO,IAAI,OAAO,CAAC,UAAU,CAAC,CAAC;IAC/B,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC,CAAC;CACxB;AAED,sEAAsE;AACtE,MAAM,WAAW,aAAa;IAC5B,WAAW,IAAI,OAAO,CAAC;IACvB,UAAU,IAAI,OAAO,CAAC,aAAa,CAAC,CAAC;IACrC,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC,CAAC;IACvB,gGAAgG;IAChG,cAAc,CAAC,OAAO,EAAE,MAAM,IAAI,GAAG,IAAI,CAAC;CAC3C;AAED,gFAAgF;AAChF,MAAM,MAAM,QAAQ,GAAG,MAAM,OAAO,CAAC,aAAa,CAAC,CAAC;AAEpD,
|
|
1
|
+
{"version":3,"file":"browser-pool.d.ts","sourceRoot":"","sources":["../../src/pool/browser-pool.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AAEH,uFAAuF;AACvF,MAAM,WAAW,UAAU;IACzB,IAAI,CAAC,GAAG,EAAE,MAAM,EAAE,IAAI,CAAC,EAAE;QAAE,SAAS,CAAC,EAAE,MAAM,CAAA;KAAE,GAAG,OAAO,CAAC,OAAO,CAAC,CAAC;IACnE,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC,CAAC;IACvB,sGAAsG;IACtG,OAAO,CAAC,OAAO,EAAE,MAAM,IAAI,GAAG,IAAI,CAAC;CACpC;AAED,uGAAuG;AACvG,MAAM,WAAW,aAAa;IAC5B,OAAO,IAAI,OAAO,CAAC,UAAU,CAAC,CAAC;IAC/B,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC,CAAC;CACxB;AAED,sEAAsE;AACtE,MAAM,WAAW,aAAa;IAC5B,WAAW,IAAI,OAAO,CAAC;IACvB,UAAU,IAAI,OAAO,CAAC,aAAa,CAAC,CAAC;IACrC,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC,CAAC;IACvB,gGAAgG;IAChG,cAAc,CAAC,OAAO,EAAE,MAAM,IAAI,GAAG,IAAI,CAAC;CAC3C;AAED,gFAAgF;AAChF,MAAM,MAAM,QAAQ,GAAG,MAAM,OAAO,CAAC,aAAa,CAAC,CAAC;AAEpD,2FAA2F;AAC3F,MAAM,WAAW,KAAK;IACpB,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAC;IAC3B,QAAQ,CAAC,GAAG,EAAE,MAAM,CAAC;IACrB,OAAO,IAAI,OAAO,CAAC,IAAI,CAAC,CAAC;CAC1B;AAED,sGAAsG;AACtG,eAAO,MAAM,oBAAoB,QAAa,CAAC;AAK/C,UAAU,kBAAkB;IAC1B,iEAAiE;IACjE,WAAW,EAAE,MAAM,CAAC;IACpB,+FAA+F;IAC/F,YAAY,EAAE,MAAM,MAAM,CAAC;IAC3B,gFAAgF;IAChF,GAAG,CAAC,EAAE,MAAM,MAAM,CAAC;IACnB,2EAA2E;IAC3E,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,sGAAsG;IACtG,YAAY,CAAC,EAAE,MAAM,CAAC;CACvB;AAUD;;;GAGG;AACH,qBAAa,WAAW;;gBAuBV,MAAM,EAAE,QAAQ,EAAE,IAAI,EAAE,kBAAkB;IAUtD,iCAAiC;IACjC,yFAAyF;IACzF,QAAQ,IAAI,MAAM;IAIlB,WAAW,IAAI,MAAM;IAIrB,wCAAwC;IACxC,WAAW,IAAI,MAAM;IAIrB,+FAA+F;IAC/F,gBAAgB,IAAI,MAAM,EAAE;IAI5B,+FAA+F;IAC/F,OAAO,CAAC,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAIzC,gGAAgG;IAChG,KAAK,CAAC,SAAS,EAAE,MAAM,GAAG,IAAI;IAK9B;;;OAGG;IACG,YAAY,IAAI,OAAO,CAAC,MAAM,EAAE,CAAC;IASvC;;;OAGG;IACG,OAAO,CACX,GAAG,EAAE,MAAM,EACX,IAAI,GAAE;QAAE,MAAM,CAAC,EAAE,WAAW,CAAC;QAAC,SAAS,CAAC,EAAE,MAAM,CAAA;KAAO,GACtD,OAAO,CAAC,KAAK,CAAC;IAqCjB,oGAAoG;IAC9F,QAAQ,IAAI,OAAO,CAAC,IAAI,CAAC;CAoGhC"}
|
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
* BrowserPool — one headless browser, many cheap isolated contexts.
|
|
3
3
|
*
|
|
4
4
|
* The "10 agents test 10 flows" scenario does NOT mean 10 Chromiums (each ~hundreds of MB). It means
|
|
5
|
-
* ONE launched browser and N `newContext
|
|
5
|
+
* ONE launched browser and N `newContext` calls (each ~a few MB, fully isolated cookies/storage).
|
|
6
6
|
* The pool owns that single browser, hands out per-flow leases, caps concurrency so a machine is
|
|
7
7
|
* never overwhelmed (over-cap acquires queue FIFO), and transparently relaunches if the browser dies.
|
|
8
8
|
*
|
|
@@ -49,6 +49,10 @@ export class BrowserPool {
|
|
|
49
49
|
this.#navTimeout = opts.navTimeoutMs ?? DEFAULT_NAV_TIMEOUT_MS;
|
|
50
50
|
}
|
|
51
51
|
/** Currently leased contexts. */
|
|
52
|
+
/** Max simultaneous leases — the ceiling the parallel suite sizes its concurrency to. */
|
|
53
|
+
capacity() {
|
|
54
|
+
return this.#max;
|
|
55
|
+
}
|
|
52
56
|
activeCount() {
|
|
53
57
|
return this.#active.size;
|
|
54
58
|
}
|
|
@@ -105,6 +109,12 @@ export class BrowserPool {
|
|
|
105
109
|
void this.#release(sessionId);
|
|
106
110
|
});
|
|
107
111
|
await page.goto(url, { timeoutMs: this.#navTimeout });
|
|
112
|
+
// The browser can crash WHILE goto is resolving; #onCrash then clears #active and zeroes
|
|
113
|
+
// #occupied. Registering the lease now would resurrect a dead entry against a crashed browser with
|
|
114
|
+
// the slot count out of sync (drifting below #active.size, eventually exceeding the cap). If we're
|
|
115
|
+
// no longer the live browser, bail — the catch below closes the context and returns the slot.
|
|
116
|
+
if (this.#browser !== browser)
|
|
117
|
+
throw new Error('browser crashed during navigation');
|
|
108
118
|
this.#active.set(sessionId, { context, page, url, touchedAt: this.#now() });
|
|
109
119
|
return {
|
|
110
120
|
sessionId,
|
|
@@ -198,11 +208,19 @@ export class BrowserPool {
|
|
|
198
208
|
return this.#browser;
|
|
199
209
|
// De-dupe concurrent launches: the first acquire to find no browser starts one; the rest await it.
|
|
200
210
|
if (this.#launching === undefined) {
|
|
201
|
-
|
|
211
|
+
// The in-flight promise MUST be cleared on failure as well as success. It used to be cleared only
|
|
212
|
+
// in the success callback, so the first failed launch — Chromium not downloaded, a transient
|
|
213
|
+
// EAGAIN — left a permanently rejected promise here, and every subsequent acquire for the daemon's
|
|
214
|
+
// lifetime re-returned that same stale rejection. Running `npx playwright install` did not help;
|
|
215
|
+
// only restarting the daemon did. A retry must be allowed to actually retry.
|
|
216
|
+
this.#launching = this.#launch()
|
|
217
|
+
.then((b) => {
|
|
202
218
|
b.onDisconnected(() => this.#onCrash(b));
|
|
203
219
|
this.#browser = b;
|
|
204
|
-
this.#launching = undefined;
|
|
205
220
|
return b;
|
|
221
|
+
})
|
|
222
|
+
.finally(() => {
|
|
223
|
+
this.#launching = undefined;
|
|
206
224
|
});
|
|
207
225
|
}
|
|
208
226
|
return this.#launching;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"browser-pool.js","sourceRoot":"","sources":["../../src/pool/browser-pool.ts"],"names":[],"mappings":"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
|
|
1
|
+
{"version":3,"file":"browser-pool.js","sourceRoot":"","sources":["../../src/pool/browser-pool.ts"],"names":[],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"playwright-launcher.d.ts","sourceRoot":"","sources":["../../src/pool/playwright-launcher.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAGH,OAAO,KAAK,EAAE,QAAQ,EAA4C,MAAM,mBAAmB,CAAC;AA4B5F,4FAA4F;AAC5F,wBAAgB,kBAAkB,CAAC,IAAI,GAAE;IAAE,QAAQ,CAAC,EAAE,OAAO,CAAA;CAAO,GAAG,QAAQ,
|
|
1
|
+
{"version":3,"file":"playwright-launcher.d.ts","sourceRoot":"","sources":["../../src/pool/playwright-launcher.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAGH,OAAO,KAAK,EAAE,QAAQ,EAA4C,MAAM,mBAAmB,CAAC;AA4B5F,4FAA4F;AAC5F,wBAAgB,kBAAkB,CAAC,IAAI,GAAE;IAAE,QAAQ,CAAC,EAAE,OAAO,CAAA;CAAO,GAAG,QAAQ,CAW9E;AAWD;;;;GAIG;AACH,wBAAgB,kBAAkB,CAAC,QAAQ,EAAE,MAAM,GAAG,SAAS,EAAE,QAAQ,EAAE,MAAM,GAAG,MAAM,CASzF"}
|
|
@@ -5,7 +5,6 @@
|
|
|
5
5
|
*
|
|
6
6
|
* Headless by default — the pool exists for fault-tolerant headless multi-agent testing.
|
|
7
7
|
*/
|
|
8
|
-
import { chromium } from 'playwright';
|
|
9
8
|
function wrapBrowser(browser) {
|
|
10
9
|
return {
|
|
11
10
|
isConnected: () => browser.isConnected(),
|
|
@@ -30,7 +29,15 @@ function wrapBrowser(browser) {
|
|
|
30
29
|
/** A Launcher that boots a real headless Chromium and adapts it to the pool's interface. */
|
|
31
30
|
export function playwrightLauncher(opts = {}) {
|
|
32
31
|
const headless = opts.headless ?? true;
|
|
33
|
-
|
|
32
|
+
// `playwright` is an OPTIONAL dependency. A static value-import here would be pulled in by the
|
|
33
|
+
// server's main entry (index.ts re-exports this module) and crash the whole process with
|
|
34
|
+
// ERR_MODULE_NOT_FOUND on any install without Chromium — the CLI, the MCP server, everything.
|
|
35
|
+
// Import it lazily, only when a browser is actually launched, so absence fails at drive-time
|
|
36
|
+
// (where it's meaningful) instead of at import-time (where it kills unrelated features).
|
|
37
|
+
return async () => {
|
|
38
|
+
const { chromium } = await import('playwright');
|
|
39
|
+
return wrapBrowser(await chromium.launch({ headless }));
|
|
40
|
+
};
|
|
34
41
|
}
|
|
35
42
|
const MAX_CONTEXTS_CEILING = 8;
|
|
36
43
|
const MAX_CONTEXTS_FLOOR = 1;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"playwright-launcher.js","sourceRoot":"","sources":["../../src/pool/playwright-launcher.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;
|
|
1
|
+
{"version":3,"file":"playwright-launcher.js","sourceRoot":"","sources":["../../src/pool/playwright-launcher.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAKH,SAAS,WAAW,CAAC,OAAgB;IACnC,OAAO;QACL,WAAW,EAAE,GAAG,EAAE,CAAC,OAAO,CAAC,WAAW,EAAE;QACxC,UAAU,EAAE,KAAK,IAA4B,EAAE;YAC7C,MAAM,OAAO,GAAG,MAAM,OAAO,CAAC,UAAU,EAAE,CAAC;YAC3C,OAAO;gBACL,OAAO,EAAE,KAAK,IAAyB,EAAE;oBACvC,MAAM,IAAI,GAAG,MAAM,OAAO,CAAC,OAAO,EAAE,CAAC;oBACrC,OAAO;wBACL,IAAI,EAAE,CAAC,GAAG,EAAE,IAAI,EAAE,EAAE,CAClB,IAAI,CAAC,IAAI,CACP,GAAG,EACH,IAAI,EAAE,SAAS,KAAK,SAAS,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,EAAE,OAAO,EAAE,IAAI,CAAC,SAAS,EAAE,CACxE;wBACH,KAAK,EAAE,GAAG,EAAE,CAAC,IAAI,CAAC,KAAK,EAAE;wBACzB,OAAO,EAAE,CAAC,OAAO,EAAE,EAAE,CAAC,IAAI,CAAC,EAAE,CAAC,OAAO,EAAE,OAAO,CAAC;qBAChD,CAAC;gBACJ,CAAC;gBACD,KAAK,EAAE,GAAG,EAAE,CAAC,OAAO,CAAC,KAAK,EAAE;aAC7B,CAAC;QACJ,CAAC;QACD,KAAK,EAAE,GAAG,EAAE,CAAC,OAAO,CAAC,KAAK,EAAE;QAC5B,cAAc,EAAE,CAAC,OAAO,EAAE,EAAE,CAAC,OAAO,CAAC,EAAE,CAAC,cAAc,EAAE,OAAO,CAAC;KACjE,CAAC;AACJ,CAAC;AAED,4FAA4F;AAC5F,MAAM,UAAU,kBAAkB,CAAC,OAA+B,EAAE;IAClE,MAAM,QAAQ,GAAG,IAAI,CAAC,QAAQ,IAAI,IAAI,CAAC;IACvC,+FAA+F;IAC/F,yFAAyF;IACzF,8FAA8F;IAC9F,6FAA6F;IAC7F,yFAAyF;IACzF,OAAO,KAAK,IAAI,EAAE;QAChB,MAAM,EAAE,QAAQ,EAAE,GAAG,MAAM,MAAM,CAAC,YAAY,CAAC,CAAC;QAChD,OAAO,WAAW,CAAC,MAAM,QAAQ,CAAC,MAAM,CAAC,EAAE,QAAQ,EAAE,CAAC,CAAC,CAAC;IAC1D,CAAC,CAAC;AACJ,CAAC;AAED,MAAM,oBAAoB,GAAG,CAAC,CAAC;AAC/B,MAAM,kBAAkB,GAAG,CAAC,CAAC;AAC7B;;;;GAIG;AACH,MAAM,yBAAyB,GAAG,GAAG,CAAC;AAEtC;;;;GAIG;AACH,MAAM,UAAU,kBAAkB,CAAC,QAA4B,EAAE,QAAgB;IAC/E,IAAI,QAAQ,KAAK,SAAS,EAAE,CAAC;QAC3B,MAAM,MAAM,GAAG,QAAQ,CAAC,QAAQ,EAAE,EAAE,CAAC,CAAC;QACtC,IAAI,CAAC,KAAK,CAAC,MAAM,CAAC,IAAI,MAAM,IAAI,kBAAkB,EAAE,CAAC;YACnD,OAAO,IAAI,CAAC,GAAG,CAAC,yBAAyB,EAAE,MAAM,CAAC,CAAC;QACrD,CAAC;IACH,CAAC;IACD,MAAM,KAAK,GAAG,IAAI,CAAC,GAAG,CAAC,kBAAkB,EAAE,QAAQ,GAAG,CAAC,CAAC,CAAC;IACzD,OAAO,IAAI,CAAC,GAAG,CAAC,oBAAoB,EAAE,KAAK,CAAC,CAAC;AAC/C,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"file-lock.d.ts","sourceRoot":"","sources":["../../src/project/file-lock.ts"],"names":[],"mappings":"AAgBA,wBAAgB,YAAY,CAAC,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,EAAE,EAAE,MAAM,OAAO,CAAC,CAAC,CAAC,GAAG,OAAO,CAAC,CAAC,CAAC,CAa9E"}
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Serialize read-modify-write against a single file across the whole daemon process.
|
|
3
|
+
*
|
|
4
|
+
* Several paths — most importantly `reticle_flow_verify parallel:N` — run load→mutate→save against the
|
|
5
|
+
* SAME shared JSON file (project.json run history, assertion-tiers.json anti-gaming baseline,
|
|
6
|
+
* envelopes.json deviation baselines) from concurrently-scheduled async tasks. With no lock, two tasks
|
|
7
|
+
* read the same base, each appends its own record, and the later save clobbers the earlier's mutation —
|
|
8
|
+
* a silent lost update. For the run history that undercounts the suite; for the assertion-tiers baseline
|
|
9
|
+
* the anti-reward-hacking gate silently loses coverage (fails open).
|
|
10
|
+
*
|
|
11
|
+
* Keyed by ABSOLUTE PATH, not by store instance, because some callers construct a fresh store per flow
|
|
12
|
+
* pointed at the same file (an instance mutex would not serialize those). One process owns the file, so
|
|
13
|
+
* a module-level chain per path is the correct serialization boundary.
|
|
14
|
+
*/
|
|
15
|
+
const chains = new Map();
|
|
16
|
+
export function withFileLock(path, fn) {
|
|
17
|
+
const prev = chains.get(path) ?? Promise.resolve();
|
|
18
|
+
// Run after the previous holder settles, regardless of whether it resolved or rejected.
|
|
19
|
+
const run = prev.then(fn, fn);
|
|
20
|
+
// Keep the chain alive but swallow the outcome so one task's rejection never rejects the next waiter.
|
|
21
|
+
chains.set(path, run.then(() => undefined, () => undefined));
|
|
22
|
+
return run;
|
|
23
|
+
}
|
|
24
|
+
//# sourceMappingURL=file-lock.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"file-lock.js","sourceRoot":"","sources":["../../src/project/file-lock.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;GAaG;AACH,MAAM,MAAM,GAAG,IAAI,GAAG,EAA4B,CAAC;AAEnD,MAAM,UAAU,YAAY,CAAI,IAAY,EAAE,EAAoB;IAChE,MAAM,IAAI,GAAG,MAAM,CAAC,GAAG,CAAC,IAAI,CAAC,IAAI,OAAO,CAAC,OAAO,EAAE,CAAC;IACnD,wFAAwF;IACxF,MAAM,GAAG,GAAG,IAAI,CAAC,IAAI,CAAC,EAAE,EAAE,EAAE,CAAC,CAAC;IAC9B,sGAAsG;IACtG,MAAM,CAAC,GAAG,CACR,IAAI,EACJ,GAAG,CAAC,IAAI,CACN,GAAG,EAAE,CAAC,SAAS,EACf,GAAG,EAAE,CAAC,SAAS,CAChB,CACF,CAAC;IACF,OAAO,GAAG,CAAC;AACb,CAAC"}
|
|
@@ -5,7 +5,21 @@
|
|
|
5
5
|
export interface FileSystemPort {
|
|
6
6
|
/** Read a UTF-8 file. Rejects (ENOENT) if absent. */
|
|
7
7
|
readFile(path: string): Promise<string>;
|
|
8
|
+
/**
|
|
9
|
+
* Read a UTF-8 file from a BYTE offset to EOF, returning the tail plus the file's total byte size.
|
|
10
|
+
* The append-only journal grows unboundedly, so re-reading the whole file per query is O(N-per-call);
|
|
11
|
+
* this reads only what was appended since the caller's tracked offset. Callers MUST pass an offset
|
|
12
|
+
* that lands on a `\n` boundary (the journal's line terminator, 1 ASCII byte) so the returned tail
|
|
13
|
+
* starts on a valid UTF-8 char boundary. Optional — a FileSystemPort that omits it makes readers fall
|
|
14
|
+
* back to a whole-file read.
|
|
15
|
+
*/
|
|
16
|
+
readFileFrom?(path: string, byteOffset: number): Promise<{
|
|
17
|
+
text: string;
|
|
18
|
+
size: number;
|
|
19
|
+
}>;
|
|
8
20
|
writeFile(path: string, data: string): Promise<void>;
|
|
21
|
+
/** Append UTF-8 text, creating the file if absent — for the append-only JSONL journal. */
|
|
22
|
+
appendFile(path: string, data: string): Promise<void>;
|
|
9
23
|
/** Read raw bytes (PNG baselines). Rejects (ENOENT) if absent. */
|
|
10
24
|
readFileBytes(path: string): Promise<Uint8Array>;
|
|
11
25
|
/** Write raw bytes (PNG screenshots/diffs). */
|
|
@@ -19,6 +33,10 @@ export interface FileSystemPort {
|
|
|
19
33
|
rename(from: string, to: string): Promise<void>;
|
|
20
34
|
/** Idempotent remove (no throw if absent) — for retention pruning + cleaning temp files. */
|
|
21
35
|
rm(path: string): Promise<void>;
|
|
36
|
+
/** Modification time in epoch ms — for recency-based retention pruning. Rejects if absent. */
|
|
37
|
+
stat(path: string): Promise<{
|
|
38
|
+
mtimeMs: number;
|
|
39
|
+
}>;
|
|
22
40
|
/** ENOENT classifier — narrows unknown without `any`, so callers can distinguish missing-file. */
|
|
23
41
|
isNotFound(error: unknown): boolean;
|
|
24
42
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"fs-port.d.ts","sourceRoot":"","sources":["../../src/project/fs-port.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"fs-port.d.ts","sourceRoot":"","sources":["../../src/project/fs-port.ts"],"names":[],"mappings":"AAaA;;;GAGG;AACH,MAAM,WAAW,cAAc;IAC7B,qDAAqD;IACrD,QAAQ,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,CAAC;IACxC;;;;;;;OAOG;IACH,YAAY,CAAC,CAAC,IAAI,EAAE,MAAM,EAAE,UAAU,EAAE,MAAM,GAAG,OAAO,CAAC;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,IAAI,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC;IACzF,SAAS,CAAC,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IACrD,0FAA0F;IAC1F,UAAU,CAAC,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IACtD,kEAAkE;IAClE,aAAa,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,UAAU,CAAC,CAAC;IACjD,+CAA+C;IAC/C,cAAc,CAAC,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,UAAU,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IAC9D,wEAAwE;IACxE,KAAK,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IACnC,MAAM,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC,CAAC;IACvC,iEAAiE;IACjE,OAAO,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,EAAE,CAAC,CAAC;IACzC,oFAAoF;IACpF,MAAM,CAAC,IAAI,EAAE,MAAM,EAAE,EAAE,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IAChD,4FAA4F;IAC5F,EAAE,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IAChC,8FAA8F;IAC9F,IAAI,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC;QAAE,OAAO,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC;IACjD,kGAAkG;IAClG,UAAU,CAAC,KAAK,EAAE,OAAO,GAAG,OAAO,CAAC;CACrC;AAED,qFAAqF;AACrF,wBAAgB,oBAAoB,IAAI,cAAc,CA+CrD"}
|