@reticlehq/server 2.0.1 → 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 +62 -6
- 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-launch.d.ts.map +1 -1
- package/dist/cli-launch.js +1 -2
- package/dist/cli-launch.js.map +1 -1
- 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 +83 -13
- 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 +42 -12
- 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 +9 -3
- package/dist/daemon.d.ts.map +1 -1
- package/dist/daemon.js +41 -8
- package/dist/daemon.js.map +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 +35 -1
- package/dist/events/event-filters.d.ts.map +1 -1
- package/dist/events/event-filters.js +93 -6
- 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 +130 -9
- 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 +169 -15
- package/dist/events/predicate.js.map +1 -1
- package/dist/events/ring-buffer.d.ts +10 -8
- package/dist/events/ring-buffer.d.ts.map +1 -1
- package/dist/events/ring-buffer.js +84 -25
- 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 +18 -9
- 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.d.ts.map +1 -1
- package/dist/flows/flow-classify.js +12 -20
- package/dist/flows/flow-classify.js.map +1 -1
- package/dist/flows/flow-replay-run.d.ts +6 -0
- package/dist/flows/flow-replay-run.d.ts.map +1 -1
- package/dist/flows/flow-replay-run.js +49 -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 +52 -18
- package/dist/flows/flow-replay.js.map +1 -1
- package/dist/flows/flow-report.d.ts +4 -4
- package/dist/flows/flow-report.d.ts.map +1 -1
- package/dist/flows/flow-report.js +2 -1
- package/dist/flows/flow-report.js.map +1 -1
- 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 +97 -152
- 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 +39 -27
- 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 +19 -0
- package/dist/flows/heal-run.d.ts.map +1 -0
- package/dist/flows/heal-run.js +137 -0
- package/dist/flows/heal-run.js.map +1 -0
- 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 +13 -0
- package/dist/flows/replay.d.ts.map +1 -1
- package/dist/flows/replay.js +56 -23
- 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 -9
- package/dist/http-server.d.ts.map +1 -1
- package/dist/http-server.js +5 -9
- package/dist/http-server.js.map +1 -1
- package/dist/idle-shutdown.d.ts +2 -2
- package/dist/idle-shutdown.js +2 -2
- package/dist/index.d.ts +3 -3
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +131 -73
- 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/mcp.d.ts.map +1 -1
- package/dist/init/mcp.js +4 -3
- package/dist/init/mcp.js.map +1 -1
- 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-tools.d.ts.map +1 -1
- package/dist/input/network-mock-tools.js +1 -6
- package/dist/input/network-mock-tools.js.map +1 -1
- 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/input/viewport-tools.d.ts.map +1 -1
- package/dist/input/viewport-tools.js +1 -6
- package/dist/input/viewport-tools.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 +52 -29
- package/dist/mcp-proxy.js.map +1 -1
- package/dist/mcp.d.ts +22 -0
- package/dist/mcp.d.ts.map +1 -1
- package/dist/mcp.js +93 -10
- 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 +2 -2
- package/dist/pool/playwright-launcher.d.ts.map +1 -1
- package/dist/pool/playwright-launcher.js +20 -6
- 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 +25 -7
- 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/server-version.d.ts +5 -0
- package/dist/server-version.d.ts.map +1 -1
- package/dist/server-version.js +5 -0
- package/dist/server-version.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.d.ts.map +1 -1
- package/dist/session/live-control-tools.js +2 -7
- package/dist/session/live-control-tools.js.map +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 +12 -1
- 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 +44 -12
- package/dist/session/session.d.ts.map +1 -1
- package/dist/session/session.js +116 -47
- package/dist/session/session.js.map +1 -1
- package/dist/tools/act-tools.d.ts.map +1 -1
- package/dist/tools/act-tools.js +257 -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/assert-grade.d.ts.map +1 -1
- package/dist/tools/assert-grade.js +15 -26
- package/dist/tools/assert-grade.js.map +1 -1
- 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 +41 -30
- 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 +95 -2
- 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 +11 -2
- package/dist/tools/tool-kit.d.ts.map +1 -1
- package/dist/tools/tool-kit.js +24 -1
- package/dist/tools/tool-kit.js.map +1 -1
- package/dist/tools/tool-names.d.ts +19 -10
- package/dist/tools/tool-names.d.ts.map +1 -1
- package/dist/tools/tool-names.js +23 -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/update-checker.d.ts +14 -1
- package/dist/update/update-checker.d.ts.map +1 -1
- package/dist/update/update-checker.js +9 -5
- package/dist/update/update-checker.js.map +1 -1
- package/dist/update/updater.d.ts +20 -2
- package/dist/update/updater.d.ts.map +1 -1
- package/dist/update/updater.js +48 -14
- package/dist/update/updater.js.map +1 -1
- package/dist/visual/visual-tools.d.ts.map +1 -1
- package/dist/visual/visual-tools.js +1 -6
- package/dist/visual/visual-tools.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,81 @@
|
|
|
1
|
+
import { EventAttribution, JOURNAL_FILE_VERSION, } from '@reticlehq/core';
|
|
2
|
+
const DEFAULT_FLUSH_AT = 64;
|
|
3
|
+
/**
|
|
4
|
+
* Owns action-window attribution and batched, order-preserving journaling — the durable half of the
|
|
5
|
+
* causal spine, kept out of Session so neither file bloats. Every stamped event is `observe`d: if an
|
|
6
|
+
* action is active (dispatch→settle), the event is attributed to it (`attribution:"window"` — a time
|
|
7
|
+
* heuristic, never presented as dataflow truth) and its seq folds into the action's range. Writes are
|
|
8
|
+
* serialized on one chain so `events.jsonl` never interleaves and an action is always persisted after
|
|
9
|
+
* the events it closed. Sink writes are best-effort: a failed local journal write must never break the
|
|
10
|
+
* live session, so errors are swallowed.
|
|
11
|
+
*/
|
|
12
|
+
export class JournalRecorder {
|
|
13
|
+
#sink;
|
|
14
|
+
#now;
|
|
15
|
+
#flushAt;
|
|
16
|
+
#pending = [];
|
|
17
|
+
#active;
|
|
18
|
+
#chain = Promise.resolve();
|
|
19
|
+
constructor(sink, options) {
|
|
20
|
+
this.#sink = sink;
|
|
21
|
+
this.#now = options.now;
|
|
22
|
+
this.#flushAt = options.flushAt ?? DEFAULT_FLUSH_AT;
|
|
23
|
+
}
|
|
24
|
+
/** Attribute (if an action is active), enqueue for journaling, and return the possibly-stamped event. */
|
|
25
|
+
observe(event) {
|
|
26
|
+
let out = event;
|
|
27
|
+
const active = this.#active;
|
|
28
|
+
if (active !== undefined) {
|
|
29
|
+
out = { ...event, actionId: active.actionId, attribution: EventAttribution.WINDOW };
|
|
30
|
+
if (typeof event.seq === 'number') {
|
|
31
|
+
active.seqFrom =
|
|
32
|
+
active.seqFrom === undefined ? event.seq : Math.min(active.seqFrom, event.seq);
|
|
33
|
+
active.seqTo = active.seqTo === undefined ? event.seq : Math.max(active.seqTo, event.seq);
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
this.#pending.push(out);
|
|
37
|
+
if (this.#pending.length >= this.#flushAt)
|
|
38
|
+
this.#enqueueFlush();
|
|
39
|
+
return out;
|
|
40
|
+
}
|
|
41
|
+
/** Open an attribution window. One action is active at a time (the agent drives sequentially). */
|
|
42
|
+
beginAction(actionId, tool, args) {
|
|
43
|
+
this.#active = { actionId, tool, args, tStart: this.#now() };
|
|
44
|
+
}
|
|
45
|
+
/** Close the active window: persist its buffered events, then the action record. No-op if none active. */
|
|
46
|
+
finishAction(effect, settled, settledInMs) {
|
|
47
|
+
const active = this.#active;
|
|
48
|
+
if (active === undefined)
|
|
49
|
+
return;
|
|
50
|
+
this.#active = undefined;
|
|
51
|
+
const action = {
|
|
52
|
+
v: JOURNAL_FILE_VERSION,
|
|
53
|
+
actionId: active.actionId,
|
|
54
|
+
tool: active.tool,
|
|
55
|
+
args: active.args,
|
|
56
|
+
effect,
|
|
57
|
+
settled,
|
|
58
|
+
settledInMs,
|
|
59
|
+
seqRange: active.seqFrom === undefined || active.seqTo === undefined
|
|
60
|
+
? undefined
|
|
61
|
+
: { from: active.seqFrom, to: active.seqTo },
|
|
62
|
+
tRange: { from: active.tStart, to: this.#now() },
|
|
63
|
+
at: active.tStart,
|
|
64
|
+
};
|
|
65
|
+
this.#enqueueFlush();
|
|
66
|
+
this.#chain = this.#chain.then(() => this.#sink.appendAction(action)).catch(() => undefined);
|
|
67
|
+
}
|
|
68
|
+
/** Persist any buffered events now (call on session end). Awaits the write chain to settle. */
|
|
69
|
+
async flush() {
|
|
70
|
+
this.#enqueueFlush();
|
|
71
|
+
await this.#chain;
|
|
72
|
+
}
|
|
73
|
+
#enqueueFlush() {
|
|
74
|
+
if (this.#pending.length === 0)
|
|
75
|
+
return;
|
|
76
|
+
const batch = this.#pending;
|
|
77
|
+
this.#pending = [];
|
|
78
|
+
this.#chain = this.#chain.then(() => this.#sink.appendEvents(batch)).catch(() => undefined);
|
|
79
|
+
}
|
|
80
|
+
}
|
|
81
|
+
//# sourceMappingURL=journal-recorder.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"journal-recorder.js","sourceRoot":"","sources":["../../src/journal/journal-recorder.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import type { FileSystemPort } from '../project/fs-port.js';
|
|
2
|
+
/** Keep at most this many session journals on disk; older ones are pruned by recency. */
|
|
3
|
+
export declare const DEFAULT_SESSION_RETENTION = 20;
|
|
4
|
+
interface DatedDir {
|
|
5
|
+
name: string;
|
|
6
|
+
mtimeMs: number;
|
|
7
|
+
}
|
|
8
|
+
/**
|
|
9
|
+
* Pure: given session dirs with their mtimes, the names to remove so only the `retention` most-recent
|
|
10
|
+
* remain. Oldest-first. Exported for testing (no IO).
|
|
11
|
+
*/
|
|
12
|
+
export declare function selectPrunable(dirs: readonly DatedDir[], retention: number): string[];
|
|
13
|
+
/**
|
|
14
|
+
* Bound the journal on disk: keep the `retention` most-recent session directories under
|
|
15
|
+
* `.reticle/sessions/`, remove the rest by mtime. Never throws — retention is best-effort maintenance,
|
|
16
|
+
* so a stat/rm failure on one dir (or a missing sessions/ dir) is swallowed, never crashing a session.
|
|
17
|
+
* Mirrors RunStore's amortized pruning; run on daemon start.
|
|
18
|
+
*/
|
|
19
|
+
export declare function pruneSessions(fs: FileSystemPort, root: string, retention?: number): Promise<void>;
|
|
20
|
+
export {};
|
|
21
|
+
//# sourceMappingURL=retention.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"retention.d.ts","sourceRoot":"","sources":["../../src/journal/retention.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,uBAAuB,CAAC;AAG5D,yFAAyF;AACzF,eAAO,MAAM,yBAAyB,KAAK,CAAC;AAE5C,UAAU,QAAQ;IAChB,IAAI,EAAE,MAAM,CAAC;IACb,OAAO,EAAE,MAAM,CAAC;CACjB;AAED;;;GAGG;AACH,wBAAgB,cAAc,CAAC,IAAI,EAAE,SAAS,QAAQ,EAAE,EAAE,SAAS,EAAE,MAAM,GAAG,MAAM,EAAE,CAMrF;AAED;;;;;GAKG;AACH,wBAAsB,aAAa,CACjC,EAAE,EAAE,cAAc,EAClB,IAAI,EAAE,MAAM,EACZ,SAAS,GAAE,MAAkC,GAC5C,OAAO,CAAC,IAAI,CAAC,CAwBf"}
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
import { reticleDirPaths, sessionDirPath } from '../project/reticle-dir.js';
|
|
2
|
+
/** Keep at most this many session journals on disk; older ones are pruned by recency. */
|
|
3
|
+
export const DEFAULT_SESSION_RETENTION = 20;
|
|
4
|
+
/**
|
|
5
|
+
* Pure: given session dirs with their mtimes, the names to remove so only the `retention` most-recent
|
|
6
|
+
* remain. Oldest-first. Exported for testing (no IO).
|
|
7
|
+
*/
|
|
8
|
+
export function selectPrunable(dirs, retention) {
|
|
9
|
+
if (dirs.length <= retention)
|
|
10
|
+
return [];
|
|
11
|
+
return [...dirs]
|
|
12
|
+
.sort((a, b) => a.mtimeMs - b.mtimeMs)
|
|
13
|
+
.slice(0, dirs.length - retention)
|
|
14
|
+
.map((d) => d.name);
|
|
15
|
+
}
|
|
16
|
+
/**
|
|
17
|
+
* Bound the journal on disk: keep the `retention` most-recent session directories under
|
|
18
|
+
* `.reticle/sessions/`, remove the rest by mtime. Never throws — retention is best-effort maintenance,
|
|
19
|
+
* so a stat/rm failure on one dir (or a missing sessions/ dir) is swallowed, never crashing a session.
|
|
20
|
+
* Mirrors RunStore's amortized pruning; run on daemon start.
|
|
21
|
+
*/
|
|
22
|
+
export async function pruneSessions(fs, root, retention = DEFAULT_SESSION_RETENTION) {
|
|
23
|
+
const sessionsDir = reticleDirPaths(root).sessions;
|
|
24
|
+
let names;
|
|
25
|
+
try {
|
|
26
|
+
names = await fs.readdir(sessionsDir);
|
|
27
|
+
}
|
|
28
|
+
catch {
|
|
29
|
+
return; // no sessions dir yet
|
|
30
|
+
}
|
|
31
|
+
const dated = [];
|
|
32
|
+
for (const name of names) {
|
|
33
|
+
try {
|
|
34
|
+
const { mtimeMs } = await fs.stat(sessionDirPath(root, name));
|
|
35
|
+
dated.push({ name, mtimeMs });
|
|
36
|
+
}
|
|
37
|
+
catch {
|
|
38
|
+
/* unstattable entry — skip */
|
|
39
|
+
}
|
|
40
|
+
}
|
|
41
|
+
for (const name of selectPrunable(dated, retention)) {
|
|
42
|
+
try {
|
|
43
|
+
await fs.rm(sessionDirPath(root, name));
|
|
44
|
+
}
|
|
45
|
+
catch {
|
|
46
|
+
/* best-effort */
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
//# sourceMappingURL=retention.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"retention.js","sourceRoot":"","sources":["../../src/journal/retention.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,eAAe,EAAE,cAAc,EAAE,MAAM,2BAA2B,CAAC;AAE5E,yFAAyF;AACzF,MAAM,CAAC,MAAM,yBAAyB,GAAG,EAAE,CAAC;AAO5C;;;GAGG;AACH,MAAM,UAAU,cAAc,CAAC,IAAyB,EAAE,SAAiB;IACzE,IAAI,IAAI,CAAC,MAAM,IAAI,SAAS;QAAE,OAAO,EAAE,CAAC;IACxC,OAAO,CAAC,GAAG,IAAI,CAAC;SACb,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,OAAO,GAAG,CAAC,CAAC,OAAO,CAAC;SACrC,KAAK,CAAC,CAAC,EAAE,IAAI,CAAC,MAAM,GAAG,SAAS,CAAC;SACjC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC;AACxB,CAAC;AAED;;;;;GAKG;AACH,MAAM,CAAC,KAAK,UAAU,aAAa,CACjC,EAAkB,EAClB,IAAY,EACZ,YAAoB,yBAAyB;IAE7C,MAAM,WAAW,GAAG,eAAe,CAAC,IAAI,CAAC,CAAC,QAAQ,CAAC;IACnD,IAAI,KAAe,CAAC;IACpB,IAAI,CAAC;QACH,KAAK,GAAG,MAAM,EAAE,CAAC,OAAO,CAAC,WAAW,CAAC,CAAC;IACxC,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,CAAC,sBAAsB;IAChC,CAAC;IACD,MAAM,KAAK,GAAe,EAAE,CAAC;IAC7B,KAAK,MAAM,IAAI,IAAI,KAAK,EAAE,CAAC;QACzB,IAAI,CAAC;YACH,MAAM,EAAE,OAAO,EAAE,GAAG,MAAM,EAAE,CAAC,IAAI,CAAC,cAAc,CAAC,IAAI,EAAE,IAAI,CAAC,CAAC,CAAC;YAC9D,KAAK,CAAC,IAAI,CAAC,EAAE,IAAI,EAAE,OAAO,EAAE,CAAC,CAAC;QAChC,CAAC;QAAC,MAAM,CAAC;YACP,8BAA8B;QAChC,CAAC;IACH,CAAC;IACD,KAAK,MAAM,IAAI,IAAI,cAAc,CAAC,KAAK,EAAE,SAAS,CAAC,EAAE,CAAC;QACpD,IAAI,CAAC;YACH,MAAM,EAAE,CAAC,EAAE,CAAC,cAAc,CAAC,IAAI,EAAE,IAAI,CAAC,CAAC,CAAC;QAC1C,CAAC;QAAC,MAAM,CAAC;YACP,iBAAiB;QACnB,CAAC;IACH,CAAC;AACH,CAAC"}
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
import { type ReticleEvent } from '@reticlehq/core';
|
|
2
|
+
/**
|
|
3
|
+
* A route-segment rollup: what happened between two ROUTE_CHANGE events. Aggregated, not raw — the
|
|
4
|
+
* unit the deviation report compares against an expected envelope. Computed by folding the
|
|
5
|
+
* journal's events; per the plan's risk note this runs lazily on query rather than threading a
|
|
6
|
+
* stateful accumulator through the hot write path.
|
|
7
|
+
*/
|
|
8
|
+
export interface SegmentRollup {
|
|
9
|
+
/** The route (pathname) this segment is on, from its opening ROUTE_CHANGE. Absent for the first. */
|
|
10
|
+
route?: string;
|
|
11
|
+
/** Elapsed-ms of the first and last event in the segment. */
|
|
12
|
+
from: number;
|
|
13
|
+
to: number;
|
|
14
|
+
/** Wall span of the segment (to - from). */
|
|
15
|
+
durationMs: number;
|
|
16
|
+
/** Distinct attributed actions observed in the segment. */
|
|
17
|
+
actions: number;
|
|
18
|
+
/** Network request totals and error count (status >= 400 or ok === false). */
|
|
19
|
+
net: {
|
|
20
|
+
total: number;
|
|
21
|
+
errors: number;
|
|
22
|
+
};
|
|
23
|
+
/** console.error + uncaught errors/rejections. */
|
|
24
|
+
consoleErrors: number;
|
|
25
|
+
/** Unique state-change paths touched, in first-seen order. */
|
|
26
|
+
statePathsChanged: string[];
|
|
27
|
+
/**
|
|
28
|
+
* WS/SSE frame activity in the segment — on a stream-first app the network story IS the stream story.
|
|
29
|
+
* Directions: opens (connections), in (server→client), out (client→server). Absent when no streams.
|
|
30
|
+
*/
|
|
31
|
+
streams?: {
|
|
32
|
+
frames: number;
|
|
33
|
+
opened: number;
|
|
34
|
+
in: number;
|
|
35
|
+
out: number;
|
|
36
|
+
};
|
|
37
|
+
/**
|
|
38
|
+
* True when a cap dropped events in this segment (a TRUNCATED or transport-overflow event landed in
|
|
39
|
+
* it). The segment's counts UNDERSTATE reality — the deviation judge must not read a nominal count as
|
|
40
|
+
* proof, and the envelope should not learn from a truncated sample.
|
|
41
|
+
*/
|
|
42
|
+
truncated?: boolean;
|
|
43
|
+
}
|
|
44
|
+
/**
|
|
45
|
+
* Fold an ordered event list into route segments split at each ROUTE_CHANGE. Pure: no clock, no IO —
|
|
46
|
+
* the events carry their own `t`. The events must be in journal order (seq/t ascending).
|
|
47
|
+
*/
|
|
48
|
+
export declare function computeSegments(events: readonly ReticleEvent[]): SegmentRollup[];
|
|
49
|
+
//# sourceMappingURL=rollups.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"rollups.d.ts","sourceRoot":"","sources":["../../src/journal/rollups.ts"],"names":[],"mappings":"AAAA,OAAO,EAAa,KAAK,YAAY,EAAE,MAAM,iBAAiB,CAAC;AAE/D;;;;;GAKG;AACH,MAAM,WAAW,aAAa;IAC5B,oGAAoG;IACpG,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,6DAA6D;IAC7D,IAAI,EAAE,MAAM,CAAC;IACb,EAAE,EAAE,MAAM,CAAC;IACX,4CAA4C;IAC5C,UAAU,EAAE,MAAM,CAAC;IACnB,2DAA2D;IAC3D,OAAO,EAAE,MAAM,CAAC;IAChB,8EAA8E;IAC9E,GAAG,EAAE;QAAE,KAAK,EAAE,MAAM,CAAC;QAAC,MAAM,EAAE,MAAM,CAAA;KAAE,CAAC;IACvC,kDAAkD;IAClD,aAAa,EAAE,MAAM,CAAC;IACtB,8DAA8D;IAC9D,iBAAiB,EAAE,MAAM,EAAE,CAAC;IAC5B;;;OAGG;IACH,OAAO,CAAC,EAAE;QAAE,MAAM,EAAE,MAAM,CAAC;QAAC,MAAM,EAAE,MAAM,CAAC;QAAC,EAAE,EAAE,MAAM,CAAC;QAAC,GAAG,EAAE,MAAM,CAAA;KAAE,CAAC;IACtE;;;;OAIG;IACH,SAAS,CAAC,EAAE,OAAO,CAAC;CACrB;AA0CD;;;GAGG;AACH,wBAAgB,eAAe,CAAC,MAAM,EAAE,SAAS,YAAY,EAAE,GAAG,aAAa,EAAE,CAmDhF"}
|
|
@@ -0,0 +1,83 @@
|
|
|
1
|
+
import { EventType } from '@reticlehq/core';
|
|
2
|
+
function finalize(acc) {
|
|
3
|
+
return {
|
|
4
|
+
...(acc.route === undefined ? {} : { route: acc.route }),
|
|
5
|
+
from: acc.from,
|
|
6
|
+
to: acc.to,
|
|
7
|
+
durationMs: acc.to - acc.from,
|
|
8
|
+
actions: acc.actionIds.size,
|
|
9
|
+
net: { total: acc.netTotal, errors: acc.netErrors },
|
|
10
|
+
consoleErrors: acc.consoleErrors,
|
|
11
|
+
statePathsChanged: acc.statePaths,
|
|
12
|
+
...(acc.streams.frames === 0 ? {} : { streams: acc.streams }),
|
|
13
|
+
...(acc.truncated ? { truncated: true } : {}),
|
|
14
|
+
};
|
|
15
|
+
}
|
|
16
|
+
function isNetError(event) {
|
|
17
|
+
const status = event.data['status'];
|
|
18
|
+
return event.data['ok'] === false || (typeof status === 'number' && status >= 400);
|
|
19
|
+
}
|
|
20
|
+
/**
|
|
21
|
+
* Fold an ordered event list into route segments split at each ROUTE_CHANGE. Pure: no clock, no IO —
|
|
22
|
+
* the events carry their own `t`. The events must be in journal order (seq/t ascending).
|
|
23
|
+
*/
|
|
24
|
+
export function computeSegments(events) {
|
|
25
|
+
const segments = [];
|
|
26
|
+
let acc;
|
|
27
|
+
const open = (route, t) => ({
|
|
28
|
+
...(route === undefined ? {} : { route }),
|
|
29
|
+
from: t,
|
|
30
|
+
to: t,
|
|
31
|
+
actionIds: new Set(),
|
|
32
|
+
netTotal: 0,
|
|
33
|
+
netErrors: 0,
|
|
34
|
+
consoleErrors: 0,
|
|
35
|
+
statePaths: [],
|
|
36
|
+
streams: { frames: 0, opened: 0, in: 0, out: 0 },
|
|
37
|
+
truncated: false,
|
|
38
|
+
});
|
|
39
|
+
for (const event of events) {
|
|
40
|
+
if (event.type === EventType.ROUTE_CHANGE) {
|
|
41
|
+
if (acc !== undefined)
|
|
42
|
+
segments.push(finalize(acc));
|
|
43
|
+
const pathname = event.data['pathname'];
|
|
44
|
+
acc = open(typeof pathname === 'string' ? pathname : undefined, event.t);
|
|
45
|
+
continue;
|
|
46
|
+
}
|
|
47
|
+
if (acc === undefined)
|
|
48
|
+
acc = open(undefined, event.t);
|
|
49
|
+
acc.to = event.t;
|
|
50
|
+
if (typeof event.actionId === 'string')
|
|
51
|
+
acc.actionIds.add(event.actionId);
|
|
52
|
+
if (event.type === EventType.NET_REQUEST) {
|
|
53
|
+
acc.netTotal += 1;
|
|
54
|
+
if (isNetError(event))
|
|
55
|
+
acc.netErrors += 1;
|
|
56
|
+
}
|
|
57
|
+
if (event.type === EventType.CONSOLE_ERROR || event.type === EventType.ERROR_UNCAUGHT) {
|
|
58
|
+
acc.consoleErrors += 1;
|
|
59
|
+
}
|
|
60
|
+
if (event.type === EventType.STATE_CHANGE) {
|
|
61
|
+
const name = event.data['name'];
|
|
62
|
+
if (typeof name === 'string' && !acc.statePaths.includes(name))
|
|
63
|
+
acc.statePaths.push(name);
|
|
64
|
+
}
|
|
65
|
+
if (event.type === EventType.NET_STREAM) {
|
|
66
|
+
acc.streams.frames += 1;
|
|
67
|
+
const direction = event.data['direction'];
|
|
68
|
+
if (direction === 'open')
|
|
69
|
+
acc.streams.opened += 1;
|
|
70
|
+
else if (direction === 'in')
|
|
71
|
+
acc.streams.in += 1;
|
|
72
|
+
else if (direction === 'out')
|
|
73
|
+
acc.streams.out += 1;
|
|
74
|
+
}
|
|
75
|
+
if (event.type === EventType.TRUNCATED || event.type === EventType.TRANSPORT_OVERFLOW) {
|
|
76
|
+
acc.truncated = true;
|
|
77
|
+
}
|
|
78
|
+
}
|
|
79
|
+
if (acc !== undefined)
|
|
80
|
+
segments.push(finalize(acc));
|
|
81
|
+
return segments;
|
|
82
|
+
}
|
|
83
|
+
//# sourceMappingURL=rollups.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"rollups.js","sourceRoot":"","sources":["../../src/journal/rollups.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
import type { AmbientCounts } from './ambient.js';
|
|
2
|
+
import type { FileSystemPort } from '../project/fs-port.js';
|
|
3
|
+
/**
|
|
4
|
+
* Session teardown: the durable half of ending a session. Two things must happen when a tab disconnects,
|
|
5
|
+
* and neither did before — the journal batches events and only writes at its flush threshold, so the tail
|
|
6
|
+
* of every session (< one batch) was silently lost from disk, and the learned ambient map was never
|
|
7
|
+
* persisted at all, so every session re-learned the page's churn from zero.
|
|
8
|
+
*
|
|
9
|
+
* Both are best-effort: a teardown failure must never surface as a session error (the tab is already gone).
|
|
10
|
+
*/
|
|
11
|
+
/** The minimal Session surface teardown needs (Session satisfies it structurally). */
|
|
12
|
+
export interface SessionEndTarget {
|
|
13
|
+
readonly id: string;
|
|
14
|
+
/** Write any batched journal events to disk. */
|
|
15
|
+
flushJournal(): Promise<void>;
|
|
16
|
+
/** The ambient-churn counts learned during this session. */
|
|
17
|
+
ambientCounts(): AmbientCounts;
|
|
18
|
+
ownAmbientCounts(): AmbientCounts;
|
|
19
|
+
}
|
|
20
|
+
export interface SessionEndDeps {
|
|
21
|
+
fs: FileSystemPort;
|
|
22
|
+
reticleRoot: string;
|
|
23
|
+
/** Journaling/persistence off (opt-out) → teardown is a no-op. */
|
|
24
|
+
enabled: boolean;
|
|
25
|
+
}
|
|
26
|
+
/**
|
|
27
|
+
* Build the teardown handler the bridge fires when a session is removed. Flushes the journal first (so no
|
|
28
|
+
* evidence is lost), then folds this session's ambient counts into the persisted map so the NEXT session
|
|
29
|
+
* starts already knowing which regions churn.
|
|
30
|
+
*/
|
|
31
|
+
export declare function makeSessionEnd(deps: SessionEndDeps): (session: SessionEndTarget) => Promise<void>;
|
|
32
|
+
//# sourceMappingURL=session-end.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"session-end.d.ts","sourceRoot":"","sources":["../../src/journal/session-end.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,cAAc,CAAC;AAClD,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,uBAAuB,CAAC;AAG5D;;;;;;;GAOG;AAEH,sFAAsF;AACtF,MAAM,WAAW,gBAAgB;IAC/B,QAAQ,CAAC,EAAE,EAAE,MAAM,CAAC;IACpB,gDAAgD;IAChD,YAAY,IAAI,OAAO,CAAC,IAAI,CAAC,CAAC;IAC9B,4DAA4D;IAC5D,aAAa,IAAI,aAAa,CAAC;IAC/B,gBAAgB,IAAI,aAAa,CAAC;CACnC;AAED,MAAM,WAAW,cAAc;IAC7B,EAAE,EAAE,cAAc,CAAC;IACnB,WAAW,EAAE,MAAM,CAAC;IACpB,kEAAkE;IAClE,OAAO,EAAE,OAAO,CAAC;CAClB;AAED;;;;GAIG;AACH,wBAAgB,cAAc,CAAC,IAAI,EAAE,cAAc,GAAG,CAAC,OAAO,EAAE,gBAAgB,KAAK,OAAO,CAAC,IAAI,CAAC,CAuCjG"}
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
import { AmbientStore } from './ambient-store.js';
|
|
2
|
+
import { pruneSessions } from './retention.js';
|
|
3
|
+
/**
|
|
4
|
+
* Build the teardown handler the bridge fires when a session is removed. Flushes the journal first (so no
|
|
5
|
+
* evidence is lost), then folds this session's ambient counts into the persisted map so the NEXT session
|
|
6
|
+
* starts already knowing which regions churn.
|
|
7
|
+
*/
|
|
8
|
+
export function makeSessionEnd(deps) {
|
|
9
|
+
return async (session) => {
|
|
10
|
+
if (!deps.enabled)
|
|
11
|
+
return;
|
|
12
|
+
try {
|
|
13
|
+
await session.flushJournal();
|
|
14
|
+
}
|
|
15
|
+
catch {
|
|
16
|
+
// a failed flush must not block ambient persistence, and must never throw at teardown
|
|
17
|
+
}
|
|
18
|
+
try {
|
|
19
|
+
const store = new AmbientStore(deps.fs, deps.reticleRoot);
|
|
20
|
+
const persisted = await store.load();
|
|
21
|
+
// Accumulate history + what is NEW. `ownAmbientCounts` excludes the map this session was
|
|
22
|
+
// seeded from at startup; `ambientCounts` includes it, and adding that onto `persisted` wrote
|
|
23
|
+
// `2 x persisted + own` on every teardown — a doubling per session that had driven the
|
|
24
|
+
// committed map to ~9.1e23.
|
|
25
|
+
const merged = { ...persisted };
|
|
26
|
+
for (const [ref, count] of Object.entries(session.ownAmbientCounts())) {
|
|
27
|
+
merged[ref] = (merged[ref] ?? 0) + count;
|
|
28
|
+
}
|
|
29
|
+
await store.save(merged);
|
|
30
|
+
}
|
|
31
|
+
catch {
|
|
32
|
+
// ambient learning is an optimization; a disk failure never breaks teardown
|
|
33
|
+
}
|
|
34
|
+
try {
|
|
35
|
+
// Bound the journal on disk HERE, not only at daemon start.
|
|
36
|
+
//
|
|
37
|
+
// Pruning ran exactly once, during wiring. A daemon that stays up — which is the normal case for
|
|
38
|
+
// a dev session, and the whole point of the pool — therefore never pruned again, so session
|
|
39
|
+
// directories accumulated without bound for as long as it lived. Session end is the right moment
|
|
40
|
+
// because it is precisely when a new directory has just been created, which makes this amortized
|
|
41
|
+
// rather than periodic (no timer to leak) and mirrors what RunStore already does.
|
|
42
|
+
//
|
|
43
|
+
// Safe against deleting the session that just ended: pruning selects the OLDEST by mtime, and the
|
|
44
|
+
// directory written moments ago is the newest.
|
|
45
|
+
await pruneSessions(deps.fs, deps.reticleRoot);
|
|
46
|
+
}
|
|
47
|
+
catch {
|
|
48
|
+
// retention is best-effort maintenance; never surface at teardown
|
|
49
|
+
}
|
|
50
|
+
};
|
|
51
|
+
}
|
|
52
|
+
//# sourceMappingURL=session-end.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"session-end.js","sourceRoot":"","sources":["../../src/journal/session-end.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,MAAM,oBAAoB,CAAC;AAGlD,OAAO,EAAE,aAAa,EAAE,MAAM,gBAAgB,CAAC;AA4B/C;;;;GAIG;AACH,MAAM,UAAU,cAAc,CAAC,IAAoB;IACjD,OAAO,KAAK,EAAE,OAAO,EAAE,EAAE;QACvB,IAAI,CAAC,IAAI,CAAC,OAAO;YAAE,OAAO;QAC1B,IAAI,CAAC;YACH,MAAM,OAAO,CAAC,YAAY,EAAE,CAAC;QAC/B,CAAC;QAAC,MAAM,CAAC;YACP,sFAAsF;QACxF,CAAC;QACD,IAAI,CAAC;YACH,MAAM,KAAK,GAAG,IAAI,YAAY,CAAC,IAAI,CAAC,EAAE,EAAE,IAAI,CAAC,WAAW,CAAC,CAAC;YAC1D,MAAM,SAAS,GAAG,MAAM,KAAK,CAAC,IAAI,EAAE,CAAC;YACrC,yFAAyF;YACzF,8FAA8F;YAC9F,uFAAuF;YACvF,4BAA4B;YAC5B,MAAM,MAAM,GAAkB,EAAE,GAAG,SAAS,EAAE,CAAC;YAC/C,KAAK,MAAM,CAAC,GAAG,EAAE,KAAK,CAAC,IAAI,MAAM,CAAC,OAAO,CAAC,OAAO,CAAC,gBAAgB,EAAE,CAAC,EAAE,CAAC;gBACtE,MAAM,CAAC,GAAG,CAAC,GAAG,CAAC,MAAM,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC,GAAG,KAAK,CAAC;YAC3C,CAAC;YACD,MAAM,KAAK,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;QAC3B,CAAC;QAAC,MAAM,CAAC;YACP,4EAA4E;QAC9E,CAAC;QACD,IAAI,CAAC;YACH,4DAA4D;YAC5D,EAAE;YACF,iGAAiG;YACjG,4FAA4F;YAC5F,iGAAiG;YACjG,iGAAiG;YACjG,kFAAkF;YAClF,EAAE;YACF,kGAAkG;YAClG,+CAA+C;YAC/C,MAAM,aAAa,CAAC,IAAI,CAAC,EAAE,EAAE,IAAI,CAAC,WAAW,CAAC,CAAC;QACjD,CAAC;QAAC,MAAM,CAAC;YACP,kEAAkE;QACpE,CAAC;IACH,CAAC,CAAC;AACJ,CAAC"}
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
import { type JournalAction, type ReticleEvent } from '@reticlehq/core';
|
|
2
|
+
import type { FileSystemPort } from '../project/fs-port.js';
|
|
3
|
+
/**
|
|
4
|
+
* The durable per-session journal: append-only JSONL for events and actions, the ledger the ring
|
|
5
|
+
* buffer becomes a hot cache over. Writes are batched (the caller flushes ring-buffer windows), so a
|
|
6
|
+
* batch is one syscall — not one per event. Reads never throw: a missing file is `[]`, a malformed or
|
|
7
|
+
* schema-invalid line is skipped, matching the never-throw discipline of the run store.
|
|
8
|
+
*
|
|
9
|
+
* Events are already browser-edge-redacted (network/storage/DOM) before they reach the wire, so the
|
|
10
|
+
* journal stores redacted payloads; the ledger is local-only. A server-side second-pass event redactor
|
|
11
|
+
* is defense-in-depth for a later commit, not a correctness gate here.
|
|
12
|
+
*
|
|
13
|
+
* ponytail: append-per-batch, no retention yet. Bounded-disk pruning (cap session dirs / file size,
|
|
14
|
+
* "pruned like runs/") is a dedicated follow-up — see the build ledger. Perf ceiling: if the <3%
|
|
15
|
+
* main-thread overhead budget is threatened at high event rates, coalesce batches behind a flush timer.
|
|
16
|
+
*/
|
|
17
|
+
export declare class SessionJournal {
|
|
18
|
+
#private;
|
|
19
|
+
constructor(fs: FileSystemPort, root: string, sessionId: string);
|
|
20
|
+
appendEvents(events: readonly ReticleEvent[]): Promise<void>;
|
|
21
|
+
appendAction(action: JournalAction): Promise<void>;
|
|
22
|
+
readEvents(): Promise<ReticleEvent[]>;
|
|
23
|
+
readActions(): Promise<JournalAction[]>;
|
|
24
|
+
}
|
|
25
|
+
//# sourceMappingURL=session-journal.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"session-journal.d.ts","sourceRoot":"","sources":["../../src/journal/session-journal.ts"],"names":[],"mappings":"AACA,OAAO,EAGL,KAAK,aAAa,EAClB,KAAK,YAAY,EAClB,MAAM,iBAAiB,CAAC;AACzB,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,uBAAuB,CAAC;AAQ5D;;;;;;;;;;;;;GAaG;AACH,qBAAa,cAAc;;gBAeb,EAAE,EAAE,cAAc,EAAE,IAAI,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM;IASzD,YAAY,CAAC,MAAM,EAAE,SAAS,YAAY,EAAE,GAAG,OAAO,CAAC,IAAI,CAAC;IAO5D,YAAY,CAAC,MAAM,EAAE,aAAa,GAAG,OAAO,CAAC,IAAI,CAAC;IAQlD,UAAU,IAAI,OAAO,CAAC,YAAY,EAAE,CAAC;IA0ErC,WAAW,IAAI,OAAO,CAAC,aAAa,EAAE,CAAC;CAiC9C"}
|
|
@@ -0,0 +1,168 @@
|
|
|
1
|
+
import { JournalActionSchema, ReticleEventSchema, } from '@reticlehq/core';
|
|
2
|
+
import { isValidSessionId, journalActionsPath, journalEventsPath, sessionDirPath, } from '../project/reticle-dir.js';
|
|
3
|
+
/**
|
|
4
|
+
* The durable per-session journal: append-only JSONL for events and actions, the ledger the ring
|
|
5
|
+
* buffer becomes a hot cache over. Writes are batched (the caller flushes ring-buffer windows), so a
|
|
6
|
+
* batch is one syscall — not one per event. Reads never throw: a missing file is `[]`, a malformed or
|
|
7
|
+
* schema-invalid line is skipped, matching the never-throw discipline of the run store.
|
|
8
|
+
*
|
|
9
|
+
* Events are already browser-edge-redacted (network/storage/DOM) before they reach the wire, so the
|
|
10
|
+
* journal stores redacted payloads; the ledger is local-only. A server-side second-pass event redactor
|
|
11
|
+
* is defense-in-depth for a later commit, not a correctness gate here.
|
|
12
|
+
*
|
|
13
|
+
* ponytail: append-per-batch, no retention yet. Bounded-disk pruning (cap session dirs / file size,
|
|
14
|
+
* "pruned like runs/") is a dedicated follow-up — see the build ledger. Perf ceiling: if the <3%
|
|
15
|
+
* main-thread overhead budget is threatened at high event rates, coalesce batches behind a flush timer.
|
|
16
|
+
*/
|
|
17
|
+
export class SessionJournal {
|
|
18
|
+
#fs;
|
|
19
|
+
#root;
|
|
20
|
+
#sessionId;
|
|
21
|
+
#dirEnsured = false;
|
|
22
|
+
// Parse-cache for the append-only EVENTS journal. queryEvents falls through to readEvents on every
|
|
23
|
+
// observe/network/console call once the ring buffer has evicted (permanent ~60s into any session), so
|
|
24
|
+
// a naive readEvents re-read + re-JSON.parse + re-zod-validated the WHOLE file each time — measured at
|
|
25
|
+
// a 1-hour 100 ev/s session as ~1.5s CPU + ~300MB transient heap PER tool call, growing with age. The
|
|
26
|
+
// journal only ever grows and is always a run of complete '\n'-terminated lines, so we keep the parsed
|
|
27
|
+
// events and the char count already consumed, and parse only the tail written since the last read.
|
|
28
|
+
#eventCache;
|
|
29
|
+
#eventCharsConsumed = 0; // fallback (whole-file) path: UTF-16 code units consumed
|
|
30
|
+
#eventBytesConsumed = 0; // fast (bounded-read) path: UTF-8 bytes consumed, always at a '\n' boundary
|
|
31
|
+
constructor(fs, root, sessionId) {
|
|
32
|
+
if (!isValidSessionId(sessionId)) {
|
|
33
|
+
throw new Error(`refusing to journal an unsafe session id: ${sessionId}`);
|
|
34
|
+
}
|
|
35
|
+
this.#fs = fs;
|
|
36
|
+
this.#root = root;
|
|
37
|
+
this.#sessionId = sessionId;
|
|
38
|
+
}
|
|
39
|
+
async appendEvents(events) {
|
|
40
|
+
if (events.length === 0)
|
|
41
|
+
return;
|
|
42
|
+
await this.#ensureDir();
|
|
43
|
+
const text = `${events.map((e) => JSON.stringify(e)).join('\n')}\n`;
|
|
44
|
+
await this.#fs.appendFile(journalEventsPath(this.#root, this.#sessionId), text);
|
|
45
|
+
}
|
|
46
|
+
async appendAction(action) {
|
|
47
|
+
await this.#ensureDir();
|
|
48
|
+
await this.#fs.appendFile(journalActionsPath(this.#root, this.#sessionId), `${JSON.stringify(action)}\n`);
|
|
49
|
+
}
|
|
50
|
+
async readEvents() {
|
|
51
|
+
const path = journalEventsPath(this.#root, this.#sessionId);
|
|
52
|
+
if (this.#eventCache === undefined)
|
|
53
|
+
this.#eventCache = [];
|
|
54
|
+
// Fast path: read only the BYTES appended since the last read, so cost tracks the tail, not the
|
|
55
|
+
// whole (unboundedly growing) file. Falls back to a whole-file read for a FileSystemPort that omits
|
|
56
|
+
// readFileFrom (test stubs).
|
|
57
|
+
const readFrom = this.#fs.readFileFrom?.bind(this.#fs);
|
|
58
|
+
if (readFrom !== undefined) {
|
|
59
|
+
let chunk;
|
|
60
|
+
try {
|
|
61
|
+
chunk = await readFrom(path, this.#eventBytesConsumed);
|
|
62
|
+
}
|
|
63
|
+
catch (error) {
|
|
64
|
+
if (this.#fs.isNotFound(error))
|
|
65
|
+
return this.#eventCache.slice();
|
|
66
|
+
throw error;
|
|
67
|
+
}
|
|
68
|
+
// Shrink/rotation guard (not done today): if the file is smaller than what we consumed, the offset
|
|
69
|
+
// is meaningless — reset and re-read from 0.
|
|
70
|
+
if (chunk.size < this.#eventBytesConsumed) {
|
|
71
|
+
this.#eventCache = [];
|
|
72
|
+
this.#eventBytesConsumed = 0;
|
|
73
|
+
chunk = await readFrom(path, 0);
|
|
74
|
+
}
|
|
75
|
+
this.#eventBytesConsumed += this.#ingestTail(chunk.text);
|
|
76
|
+
return this.#eventCache.slice();
|
|
77
|
+
}
|
|
78
|
+
let text;
|
|
79
|
+
try {
|
|
80
|
+
text = await this.#fs.readFile(path);
|
|
81
|
+
}
|
|
82
|
+
catch (error) {
|
|
83
|
+
if (this.#fs.isNotFound(error))
|
|
84
|
+
return this.#eventCache.slice();
|
|
85
|
+
throw error;
|
|
86
|
+
}
|
|
87
|
+
// Fallback (whole-file) path: #eventCharsConsumed is a UTF-16 offset into the whole text. Shrink
|
|
88
|
+
// guard, then ingest the un-consumed tail up to its last newline (see #ingestTail for the
|
|
89
|
+
// partial-line rationale).
|
|
90
|
+
if (text.length < this.#eventCharsConsumed) {
|
|
91
|
+
this.#eventCache = [];
|
|
92
|
+
this.#eventCharsConsumed = 0;
|
|
93
|
+
}
|
|
94
|
+
const end = text.lastIndexOf('\n') + 1;
|
|
95
|
+
if (end > this.#eventCharsConsumed) {
|
|
96
|
+
this.#ingestTail(text.slice(this.#eventCharsConsumed, end));
|
|
97
|
+
this.#eventCharsConsumed = end;
|
|
98
|
+
}
|
|
99
|
+
return this.#eventCache.slice();
|
|
100
|
+
}
|
|
101
|
+
/**
|
|
102
|
+
* Parse complete ('\n'-terminated) JSON event lines from `tail` into #eventCache, stopping at the LAST
|
|
103
|
+
* newline. A concurrent append can be observed mid-record (reads and writes run on separate libuv
|
|
104
|
+
* threads), and consuming a partial trailing line would splice its tail onto the next read's head, fail
|
|
105
|
+
* to parse, and drop that event forever — so the partial tail is left for the next read. Returns the
|
|
106
|
+
* UTF-8 BYTES consumed, which the bounded-read path uses to advance its byte offset.
|
|
107
|
+
*/
|
|
108
|
+
#ingestTail(tail) {
|
|
109
|
+
const cache = this.#eventCache ?? (this.#eventCache = []);
|
|
110
|
+
const end = tail.lastIndexOf('\n') + 1;
|
|
111
|
+
if (end === 0)
|
|
112
|
+
return 0; // no complete line yet
|
|
113
|
+
const complete = tail.slice(0, end);
|
|
114
|
+
for (const line of complete.split('\n')) {
|
|
115
|
+
if (line.length === 0)
|
|
116
|
+
continue;
|
|
117
|
+
let parsed;
|
|
118
|
+
try {
|
|
119
|
+
parsed = JSON.parse(line);
|
|
120
|
+
}
|
|
121
|
+
catch {
|
|
122
|
+
continue;
|
|
123
|
+
}
|
|
124
|
+
const result = ReticleEventSchema.safeParse(parsed);
|
|
125
|
+
if (result.success)
|
|
126
|
+
cache.push(result.data);
|
|
127
|
+
}
|
|
128
|
+
return Buffer.byteLength(complete, 'utf8');
|
|
129
|
+
}
|
|
130
|
+
async readActions() {
|
|
131
|
+
return this.#readLines(journalActionsPath(this.#root, this.#sessionId), JournalActionSchema);
|
|
132
|
+
}
|
|
133
|
+
async #ensureDir() {
|
|
134
|
+
if (this.#dirEnsured)
|
|
135
|
+
return;
|
|
136
|
+
await this.#fs.mkdir(sessionDirPath(this.#root, this.#sessionId));
|
|
137
|
+
this.#dirEnsured = true;
|
|
138
|
+
}
|
|
139
|
+
async #readLines(path, schema) {
|
|
140
|
+
let text;
|
|
141
|
+
try {
|
|
142
|
+
text = await this.#fs.readFile(path);
|
|
143
|
+
}
|
|
144
|
+
catch (error) {
|
|
145
|
+
if (this.#fs.isNotFound(error))
|
|
146
|
+
return [];
|
|
147
|
+
throw error;
|
|
148
|
+
}
|
|
149
|
+
const out = [];
|
|
150
|
+
for (const line of text.split('\n')) {
|
|
151
|
+
if (line.length === 0)
|
|
152
|
+
continue;
|
|
153
|
+
let parsed;
|
|
154
|
+
try {
|
|
155
|
+
parsed = JSON.parse(line);
|
|
156
|
+
}
|
|
157
|
+
catch {
|
|
158
|
+
continue;
|
|
159
|
+
}
|
|
160
|
+
const result = schema.safeParse(parsed);
|
|
161
|
+
// Validated at this boundary; ZodTypeAny widens `.data` to any, so re-narrow to the schema output.
|
|
162
|
+
if (result.success)
|
|
163
|
+
out.push(result.data);
|
|
164
|
+
}
|
|
165
|
+
return out;
|
|
166
|
+
}
|
|
167
|
+
}
|
|
168
|
+
//# sourceMappingURL=session-journal.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"session-journal.js","sourceRoot":"","sources":["../../src/journal/session-journal.ts"],"names":[],"mappings":"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"}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* Enterprise license-key verification + the assertEnterprise gate. ENTERPRISE CODE (Reticle Enterprise
|
|
3
|
-
* License — see
|
|
3
|
+
* License — see./LICENSE), not the FSL that covers the rest of the server.
|
|
4
4
|
*
|
|
5
5
|
* Offline + no phone-home (preserves the no-telemetry brand): a key is a signed payload Reticle issues
|
|
6
6
|
* with its private key; this verifies it against the issuer's PUBLIC key with Ed25519. Dev/eval is a
|
|
@@ -100,8 +100,13 @@ interface LicenseReport {
|
|
|
100
100
|
*/
|
|
101
101
|
export declare function describeLicense(now: number, env?: NodeJS.ProcessEnv, baked?: string): LicenseReport;
|
|
102
102
|
/**
|
|
103
|
-
* Gate an enterprise feature using env-resolved activation. Enforcement is ON
|
|
104
|
-
*
|
|
103
|
+
* Gate an enterprise feature using env-resolved activation. Enforcement is ON when the issuer public key
|
|
104
|
+
* is configured (a real release). Without it, behaviour splits on runtime:
|
|
105
|
+
* - dev/eval (NODE_ENV ≠ production): features run FREE — never blocks a contributor or CI.
|
|
106
|
+
* - production (NODE_ENV = production): FAIL CLOSED — a release that reaches production with no
|
|
107
|
+
* resolvable issuer key was mis-built (the baked key wasn't stamped in, BAKED_ISSUER_PUBLIC_KEY_PEM
|
|
108
|
+
* is still ''), and silently unlocking every ee feature with no key and no warning is the worst
|
|
109
|
+
* outcome. Deny instead, with a distinct reason so the misconfiguration is obvious.
|
|
105
110
|
*/
|
|
106
111
|
export declare function assertEnterpriseFromEnv(feature: string, now: number, env?: NodeJS.ProcessEnv, baked?: string): void;
|
|
107
112
|
export {};
|