@reticlehq/server 3.2.0 → 3.4.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 +1 -1
- package/README.md +3 -3
- package/SKILL.md +23 -22
- package/dist/chromium-launch-options.d.ts +4 -3
- package/dist/chromium-launch-options.js +6 -2
- package/dist/command/cli/adhoc-suite.d.ts +41 -0
- package/dist/command/cli/adhoc-suite.js +159 -0
- package/dist/command/cli/adhoc-verdict.d.ts +58 -2
- package/dist/command/cli/adhoc-verdict.js +108 -13
- package/dist/command/cli/answers/gate-hook-message.d.ts +6 -0
- package/dist/command/cli/answers/gate-hook-message.js +6 -0
- package/dist/command/cli/auth/cloud-keystore.d.ts +0 -2
- package/dist/command/cli/auth/cloud-keystore.js +0 -3
- package/dist/command/cli/auth/cloud-session.d.ts +4 -0
- package/dist/command/cli/auth/cloud-session.js +2 -0
- package/dist/command/cli/cli-doctor.js +30 -8
- package/dist/command/cli/cli-flow-commands.d.ts +3 -6
- package/dist/command/cli/cli-flow-commands.js +67 -4
- package/dist/command/cli/cli-parse-grammar.d.ts +7 -0
- package/dist/command/cli/cli-parse-grammar.js +7 -0
- package/dist/command/cli/cli-parse-verify.d.ts +2 -5
- package/dist/command/cli/cli-parse-verify.js +86 -13
- package/dist/command/cli/cli-parse.d.ts +14 -1
- package/dist/command/cli/cli-parse.js +54 -8
- package/dist/command/cli/cli-update-commands.js +8 -1
- package/dist/command/cli/cli-verify.d.ts +80 -0
- package/dist/command/cli/cli-verify.js +181 -26
- package/dist/command/cli/cloud-cli.js +5 -2
- package/dist/command/cli/cloud-kit.d.ts +0 -2
- package/dist/command/cli/cloud-kit.js +3 -5
- package/dist/command/cli/cloud-login.js +21 -3
- package/dist/command/cli/demo/demo-page.js +6 -3
- package/dist/command/cli/doctor/browser/chromium-hint.d.ts +5 -0
- package/dist/command/cli/doctor/browser/chromium-hint.js +5 -0
- package/dist/command/cli/doctor/doctor-sessions-line.d.ts +2 -1
- package/dist/command/cli/launch/cli-launch.d.ts +9 -29
- package/dist/command/cli/launch/cli-launch.js +27 -49
- package/dist/command/cli/launch/sdk-version-match.d.ts +84 -0
- package/dist/command/cli/launch/sdk-version-match.js +206 -0
- package/dist/command/cli/lifecycle/daemon-lifecycle.js +2 -16
- package/dist/command/cli/ports/resolve/cli-port.d.ts +38 -0
- package/dist/command/cli/ports/resolve/cli-port.js +169 -15
- package/dist/command/cli/report-command.d.ts +16 -0
- package/dist/command/cli/report-command.js +97 -0
- package/dist/command/cli/setup-mcp-cli.js +13 -13
- package/dist/command/cli/tutorial.d.ts +2 -2
- package/dist/command/cli/tutorial.js +21 -7
- package/dist/command/cli.js +67 -10
- package/dist/command/daemon/binding/daemon-status-probe.d.ts +44 -2
- package/dist/command/daemon/binding/daemon-status-probe.js +79 -6
- package/dist/command/daemon/binding/port-presence.d.ts +1 -1
- package/dist/command/daemon/daemon-resolve.d.ts +9 -0
- package/dist/command/daemon/daemon-resolve.js +1 -1
- package/dist/command/daemon/idle-shutdown.d.ts +2 -1
- package/dist/command/daemon/lifetime/daemon-usefulness.d.ts +7 -1
- package/dist/command/daemon/lifetime/daemon-usefulness.js +30 -7
- package/dist/command/dev/stale-issue-guard.d.ts +3 -4
- package/dist/command/dev/stale-issue-guard.js +8 -8
- package/dist/command/setup/bringup/connect-lease.d.ts +17 -0
- package/dist/command/setup/bringup/connect-lease.js +38 -0
- package/dist/command/setup/bringup/dev-server-files.d.ts +68 -0
- package/dist/command/setup/bringup/dev-server-files.js +131 -0
- package/dist/command/setup/bringup/dev-server-log-cap.d.ts +35 -0
- package/dist/command/setup/bringup/dev-server-log-cap.js +121 -0
- package/dist/command/setup/bringup/ensure-daemon.d.ts +65 -4
- package/dist/command/setup/bringup/ensure-daemon.js +135 -16
- package/dist/command/setup/bringup/static-page-server.d.ts +35 -0
- package/dist/command/setup/bringup/static-page-server.js +151 -0
- package/dist/command/setup/desktop-shape.d.ts +4 -0
- package/dist/command/setup/desktop-shape.js +18 -2
- package/dist/command/setup/init/init-host.js +8 -0
- package/dist/command/setup/init/init-port.d.ts +15 -0
- package/dist/command/setup/init/init-port.js +44 -0
- package/dist/command/setup/init/init-runtime.d.ts +1 -1
- package/dist/command/setup/init/init-runtime.js +39 -2
- package/dist/command/setup/node-effects.d.ts +27 -14
- package/dist/command/setup/node-effects.js +80 -44
- package/dist/command/setup/probe/loopback-probe-urls.d.ts +7 -0
- package/dist/command/setup/probe/loopback-probe-urls.js +40 -0
- package/dist/command/setup/probe/page-probe.d.ts +13 -2
- package/dist/command/setup/probe/page-probe.js +18 -3
- package/dist/command/setup/run-setup.d.ts +26 -1
- package/dist/command/setup/run-setup.js +96 -13
- package/dist/command/setup/session-pick.d.ts +13 -0
- package/dist/command/setup/session-pick.js +20 -0
- package/dist/command/setup/setup-command.d.ts +2 -14
- package/dist/command/setup/setup-command.js +105 -31
- package/dist/command/setup/setup-mcp.js +3 -3
- package/dist/command/setup/terminal/wait-progress.d.ts +8 -0
- package/dist/command/setup/terminal/wait-progress.js +17 -0
- package/dist/features/crawl/crawl-empty.js +1 -1
- package/dist/features/crawl/crawl-tools.d.ts +6 -0
- package/dist/features/crawl/crawl-tools.js +57 -0
- package/dist/features/crawl/crawl.d.ts +2 -0
- package/dist/features/crawl/crawl.js +171 -156
- package/dist/features/exhaust/app-coverage.d.ts +33 -0
- package/dist/features/exhaust/app-coverage.js +31 -0
- package/dist/features/exhaust/code-coverage.d.ts +47 -0
- package/dist/features/exhaust/code-coverage.js +77 -0
- package/dist/features/exhaust/exhaust-run.d.ts +33 -0
- package/dist/features/exhaust/exhaust-run.js +82 -0
- package/dist/features/exhaust/explorer.d.ts +103 -0
- package/dist/features/exhaust/explorer.js +195 -0
- package/dist/features/exhaust/failure-branches.d.ts +33 -0
- package/dist/features/exhaust/failure-branches.js +92 -0
- package/dist/features/exhaust/ledger.d.ts +202 -0
- package/dist/features/exhaust/ledger.js +252 -0
- package/dist/features/exhaust/session-fold.d.ts +31 -0
- package/dist/features/exhaust/session-fold.js +79 -0
- package/dist/features/exhaust/session-port.d.ts +36 -0
- package/dist/features/exhaust/session-port.js +102 -0
- package/dist/features/harness/drive-report.d.ts +0 -9
- package/dist/features/harness/drive-report.js +18 -0
- package/dist/features/harness/driver.js +4 -7
- package/dist/features/harness/fill-values.d.ts +6 -0
- package/dist/features/harness/fill-values.js +3 -0
- package/dist/features/harness/jev-driver.js +36 -22
- package/dist/features/harness/openai-driver.js +4 -7
- package/dist/features/harness/platform-config.d.ts +10 -0
- package/dist/features/harness/platform-config.js +13 -6
- package/dist/index.d.ts +10 -1
- package/dist/index.js +78 -104
- package/dist/judgement/capsule/capsule-store.d.ts +31 -2
- package/dist/judgement/capsule/capsule-store.js +58 -6
- package/dist/judgement/capsule/capsule.js +5 -0
- package/dist/judgement/capsule/causal-summary.d.ts +13 -1
- package/dist/judgement/capsule/causal-summary.js +7 -0
- package/dist/judgement/domain/domain-model.js +40 -9
- package/dist/judgement/oracles/self-instrument.js +4 -2
- package/dist/judgement/outcome/assertion-integrity.d.ts +3 -3
- package/dist/judgement/runs/artifact/gap-report.d.ts +17 -0
- package/dist/judgement/runs/artifact/gap-report.js +46 -0
- package/dist/judgement/runs/artifact/gap-summary.d.ts +58 -0
- package/dist/judgement/runs/artifact/gap-summary.js +85 -0
- package/dist/judgement/runs/artifact/render-report.js +4 -1
- package/dist/judgement/runs/artifact/replay-mapping.d.ts +2 -2
- package/dist/judgement/runs/artifact/replay-mapping.js +44 -9
- package/dist/judgement/runs/artifact/to-artifact.d.ts +7 -2
- package/dist/judgement/runs/artifact/to-artifact.js +1 -1
- package/dist/judgement/runs/context-tools.js +21 -3
- package/dist/judgement/runs/drive-run.js +7 -2
- package/dist/judgement/runs/verification-sync.d.ts +3 -1
- package/dist/judgement/runs/verification-sync.js +1 -1
- package/dist/language/flows/annotate-notes/annotate.d.ts +0 -15
- package/dist/language/flows/annotate-notes/annotate.js +66 -18
- package/dist/language/flows/change/affected.d.ts +9 -0
- package/dist/language/flows/change/affected.js +35 -0
- package/dist/language/flows/change/gate.d.ts +20 -0
- package/dist/language/flows/change/gate.js +12 -1
- package/dist/language/flows/flow-anchor.d.ts +12 -0
- package/dist/language/flows/flow-anchor.js +20 -0
- package/dist/language/flows/flow-author.d.ts +7 -0
- package/dist/language/flows/flow-author.js +19 -0
- package/dist/language/flows/flow-expect-grammar.d.ts +2 -2
- package/dist/language/flows/flow-expect-grammar.js +92 -11
- package/dist/language/flows/flow-intent.js +1 -1
- package/dist/language/flows/flow-journey.d.ts +54 -0
- package/dist/language/flows/flow-journey.js +119 -0
- package/dist/language/flows/flow-learning.d.ts +3 -0
- package/dist/language/flows/flow-learning.js +39 -8
- package/dist/language/flows/flow-replay-run.d.ts +33 -12
- package/dist/language/flows/flow-replay-run.js +131 -52
- package/dist/language/flows/flow-replay-types.d.ts +9 -0
- package/dist/language/flows/flow-replay.d.ts +27 -12
- package/dist/language/flows/flow-replay.js +127 -111
- package/dist/language/flows/flow-result.d.ts +2 -0
- package/dist/language/flows/flow-result.js +25 -0
- package/dist/language/flows/flow-step-runners.d.ts +26 -10
- package/dist/language/flows/flow-step-runners.js +20 -4
- package/dist/language/flows/flow-success.d.ts +21 -6
- package/dist/language/flows/flow-success.js +50 -138
- package/dist/language/flows/flow-tools.js +17 -5
- package/dist/language/flows/flows.d.ts +18 -5
- package/dist/language/flows/flows.js +101 -16
- package/dist/language/flows/heal.d.ts +9 -1
- package/dist/language/flows/heal.js +24 -2
- package/dist/language/flows/learned-sources.d.ts +21 -0
- package/dist/language/flows/learned-sources.js +84 -0
- package/dist/language/flows/recording/recording-backtrack.d.ts +0 -7
- package/dist/language/flows/recording/recording-backtrack.js +1 -1
- package/dist/language/flows/recording/replay-halt.d.ts +2 -1
- package/dist/language/flows/recording/replay-halt.js +3 -1
- package/dist/language/flows/recording/tape/recordings.d.ts +31 -2
- package/dist/language/flows/recording/tape/recordings.js +55 -1
- package/dist/language/flows/replay.d.ts +19 -0
- package/dist/language/flows/replay.js +53 -13
- package/dist/language/flows/stores/annotation-store.d.ts +5 -5
- package/dist/language/flows/stores/assertion-tiers-store.js +2 -3
- package/dist/language/flows/stores/flake-store.js +2 -3
- package/dist/language/flows/suite/coverage.d.ts +1 -1
- package/dist/language/flows/suite/parallel-suite.d.ts +2 -1
- package/dist/language/flows/verify-change-tools.js +19 -2
- package/dist/launch-chromium.d.ts +80 -0
- package/dist/launch-chromium.js +218 -0
- package/dist/memory/cloud/cloud-config.d.ts +11 -2
- package/dist/memory/cloud/cloud-config.js +47 -7
- package/dist/memory/cloud/cloud-sync.d.ts +4 -3
- package/dist/memory/cloud/cloud-sync.js +7 -10
- package/dist/memory/cloud/harness-config.d.ts +2 -0
- package/dist/memory/cloud/harness-offer.js +5 -6
- package/dist/memory/cloud/harness-switch.js +5 -6
- package/dist/memory/cloud/sync-cycle.d.ts +78 -1
- package/dist/memory/cloud/sync-cycle.js +321 -53
- package/dist/memory/cloud/sync-daemon.d.ts +13 -0
- package/dist/memory/cloud/sync-daemon.js +45 -20
- package/dist/memory/cloud/sync-disk.js +27 -8
- package/dist/memory/impact/impact-store.js +6 -0
- package/dist/memory/intent/inline-intent.js +8 -3
- package/dist/memory/intent/intent-shard-store.d.ts +33 -47
- package/dist/memory/intent/intent-shard-store.js +252 -140
- package/dist/memory/intent/intent-shard.d.ts +0 -23
- package/dist/memory/intent/intent-shard.js +1 -11
- package/dist/memory/intent/intent-store.d.ts +13 -8
- package/dist/memory/intent/intent-store.js +46 -90
- package/dist/memory/intent/intent-tools.js +34 -23
- package/dist/memory/journal/ambient-store.js +2 -3
- package/dist/memory/journal/deviation-report.js +4 -1
- package/dist/memory/journal/deviation-service.js +10 -2
- package/dist/memory/journal/drive-flow.d.ts +19 -14
- package/dist/memory/journal/drive-flow.js +65 -48
- package/dist/memory/journal/envelope-store.js +2 -3
- package/dist/memory/journal/journal-recorder.d.ts +21 -0
- package/dist/memory/journal/on-disk/retain-policy.d.ts +34 -0
- package/dist/memory/journal/on-disk/retain-policy.js +44 -0
- package/dist/memory/journal/on-disk/retention.d.ts +14 -10
- package/dist/memory/journal/on-disk/retention.js +13 -12
- package/dist/memory/journal/on-disk/startup-maintenance.d.ts +42 -0
- package/dist/memory/journal/on-disk/startup-maintenance.js +14 -0
- package/dist/memory/journal/on-disk/workspace-gitignore.d.ts +0 -11
- package/dist/memory/journal/on-disk/workspace-gitignore.js +6 -45
- package/dist/memory/journal/on-disk/workspace-tiers.d.ts +52 -0
- package/dist/memory/journal/on-disk/workspace-tiers.js +90 -0
- package/dist/memory/journal/route-template.d.ts +22 -0
- package/dist/memory/journal/route-template.js +44 -0
- package/dist/memory/journal/session-end.d.ts +13 -2
- package/dist/memory/journal/session-end.js +88 -18
- package/dist/memory/journal/session-journal.d.ts +8 -1
- package/dist/memory/journal/session-journal.js +10 -0
- package/dist/memory/project/baselines.d.ts +1 -1
- package/dist/memory/project/dir/reticle-dir.d.ts +3 -1
- package/dist/memory/project/dir/reticle-dir.js +1 -0
- package/dist/memory/project/fs/fs-port.js +44 -5
- package/dist/memory/project/fs/write-atomic.d.ts +26 -0
- package/dist/memory/project/fs/write-atomic.js +48 -0
- package/dist/memory/project/project-tools.js +3 -1
- package/dist/memory/recall/prior/connection-memory.d.ts +6 -0
- package/dist/memory/recall/prior/connection-memory.js +8 -0
- package/dist/memory/recall/registered-projects.d.ts +2 -1
- package/dist/portal/bridge/auth-failure-reason.d.ts +1 -1
- package/dist/portal/bridge/auth-failure-reason.js +9 -4
- package/dist/portal/bridge/bridge.d.ts +8 -0
- package/dist/portal/bridge/bridge.js +43 -2
- package/dist/portal/input/js-coverage.d.ts +25 -0
- package/dist/portal/input/js-coverage.js +30 -0
- package/dist/portal/input/real-input.d.ts +11 -0
- package/dist/portal/input/real-input.js +31 -5
- package/dist/portal/pool/browser-pool.d.ts +10 -0
- package/dist/portal/pool/browser-pool.js +10 -0
- package/dist/portal/pool/playwright-launcher.d.ts +6 -0
- package/dist/portal/pool/playwright-launcher.js +21 -13
- package/dist/portal/pool/pool-contract.d.ts +2 -0
- package/dist/portal/pool/storage-seed.d.ts +2 -1
- package/dist/portal/pool/zero-install.d.ts +27 -0
- package/dist/portal/pool/zero-install.js +54 -0
- package/dist/portal/realm/web-realm.js +6 -0
- package/dist/portal/session/dev-server/dev-command.d.ts +2 -2
- package/dist/portal/session/dev-server/dev-command.js +30 -12
- package/dist/portal/session/dev-server/dev-server-probe.d.ts +2 -1
- package/dist/portal/session/dev-server/dev-server-probe.js +17 -1
- package/dist/portal/session/dev-server/route-status-probe.d.ts +24 -0
- package/dist/portal/session/dev-server/route-status-probe.js +57 -0
- package/dist/portal/session/dev-server/served-document.d.ts +21 -0
- package/dist/portal/session/dev-server/served-document.js +57 -0
- package/dist/portal/session/facts/background-traffic.d.ts +9 -0
- package/dist/portal/session/facts/background-traffic.js +25 -0
- package/dist/portal/session/facts/observed-state.d.ts +11 -0
- package/dist/portal/session/facts/observed-state.js +34 -0
- package/dist/portal/session/live-control-tools.js +48 -3
- package/dist/portal/session/no-session-diagnosis.d.ts +29 -0
- package/dist/portal/session/no-session-diagnosis.js +62 -5
- package/dist/portal/session/no-session-next-action.d.ts +13 -0
- package/dist/portal/session/no-session-next-action.js +48 -9
- package/dist/portal/session/no-session-watch.d.ts +18 -0
- package/dist/portal/session/no-session-watch.js +88 -2
- package/dist/portal/session/presence/attachment-history.d.ts +13 -2
- package/dist/portal/session/session-health.d.ts +61 -0
- package/dist/portal/session/session-health.js +43 -3
- package/dist/portal/session/session-info.d.ts +6 -0
- package/dist/portal/session/session-manager.d.ts +29 -6
- package/dist/portal/session/session-manager.js +42 -5
- package/dist/portal/session/session-reaper.d.ts +28 -0
- package/dist/portal/session/session-reaper.js +49 -1
- package/dist/portal/session/session-successor.d.ts +11 -0
- package/dist/portal/session/session-successor.js +14 -1
- package/dist/portal/session/session-verdict-facts.d.ts +28 -0
- package/dist/portal/session/session-verdict-facts.js +15 -0
- package/dist/portal/session/session.d.ts +10 -0
- package/dist/portal/session/session.js +34 -26
- package/dist/surface/http-server.d.ts +2 -1
- package/dist/surface/http-server.js +4 -2
- package/dist/surface/mcp/mcp-proxy.d.ts +2 -2
- package/dist/surface/mcp/mcp-proxy.js +5 -5
- package/dist/surface/mcp/mcp.js +4 -2
- package/dist/surface/mcp/proxy/proxy-daemon-probe.d.ts +13 -1
- package/dist/surface/mcp/proxy/proxy-daemon-probe.js +27 -2
- package/dist/surface/mcp/proxy-idle-exit.d.ts +2 -1
- package/dist/surface/mcp/server-instructions.js +21 -8
- package/dist/surface/tools/act/after-match.d.ts +17 -0
- package/dist/surface/tools/act/after-match.js +30 -0
- package/dist/surface/tools/act/already-true.d.ts +40 -0
- package/dist/surface/tools/act/already-true.js +36 -0
- package/dist/surface/tools/act/durable.d.ts +69 -0
- package/dist/surface/tools/act/durable.js +139 -0
- package/dist/surface/tools/act/navigation/navigate-arrival.d.ts +19 -6
- package/dist/surface/tools/act/navigation/navigate-arrival.js +60 -10
- package/dist/surface/tools/act/navigation/navigate-result.d.ts +1 -12
- package/dist/surface/tools/act/navigation/navigate-result.js +21 -3
- package/dist/surface/tools/act/proved-controls.d.ts +9 -0
- package/dist/surface/tools/act/proved-controls.js +11 -0
- package/dist/surface/tools/act/sequence-grade.d.ts +5 -0
- package/dist/surface/tools/act/sequence-grade.js +32 -1
- package/dist/surface/tools/act/settle-in-flight.d.ts +6 -2
- package/dist/surface/tools/act/settle-in-flight.js +29 -6
- package/dist/surface/tools/act-capsule.d.ts +7 -0
- package/dist/surface/tools/act-capsule.js +68 -8
- package/dist/surface/tools/act-sequence-tool.js +25 -8
- package/dist/surface/tools/act-tools.js +51 -74
- package/dist/surface/tools/args/numeric-bounds.d.ts +15 -2
- package/dist/surface/tools/args/numeric-bounds.js +30 -3
- package/dist/surface/tools/assert/assert-grade.js +26 -3
- package/dist/surface/tools/assert/assert-verdict.js +32 -6
- package/dist/surface/tools/browser-tools.js +17 -4
- package/dist/surface/tools/coverage-tools.js +27 -1
- package/dist/surface/tools/dynamic-tools.js +6 -0
- package/dist/surface/tools/error-recovery.js +4 -4
- package/dist/surface/tools/feedback-invite.js +6 -4
- package/dist/surface/tools/feedback-tools.d.ts +2 -1
- package/dist/surface/tools/feedback-tools.js +1 -1
- package/dist/surface/tools/harness-explore.d.ts +3 -2
- package/dist/surface/tools/harness-explore.js +7 -6
- package/dist/surface/tools/invoke-tool.js +17 -4
- package/dist/surface/tools/lease-hint.d.ts +8 -0
- package/dist/surface/tools/lease-hint.js +10 -0
- package/dist/surface/tools/lease-tools.d.ts +16 -28
- package/dist/surface/tools/lease-tools.js +68 -11
- package/dist/surface/tools/lineage-tools.js +1 -1
- package/dist/surface/tools/live-call-text.js +4 -1
- package/dist/surface/tools/observe-tools.js +23 -7
- package/dist/surface/tools/real-input-attempt.d.ts +0 -5
- package/dist/surface/tools/real-input-attempt.js +1 -1
- package/dist/surface/tools/tool-kit.d.ts +5 -0
- package/dist/surface/tools/tool-kit.js +6 -1
- package/dist/surface/tools/tool-surface.js +17 -5
- package/dist/surface/tools/tools.js +68 -29
- package/dist/telemetry/argument-shape.d.ts +0 -2
- package/dist/telemetry/argument-shape.js +0 -4
- package/dist/telemetry/error-class.d.ts +2 -3
- package/dist/telemetry/error-class.js +2 -3
- package/dist/telemetry/feedback-local.d.ts +1 -0
- package/dist/telemetry/feedback-local.js +1 -3
- package/dist/telemetry/feedback.d.ts +1 -1
- package/dist/telemetry/harness-drive.d.ts +0 -2
- package/dist/telemetry/harness-drive.js +0 -4
- package/dist/telemetry/hud-metrics.d.ts +32 -0
- package/dist/telemetry/hud-metrics.js +95 -0
- package/dist/telemetry/session-metrics.d.ts +5 -0
- package/dist/telemetry/session-metrics.js +15 -1
- package/dist/wire-journal.d.ts +34 -0
- package/dist/wire-journal.js +104 -0
- package/dist/workspace-packages.d.ts +0 -2
- package/dist/workspace-packages.js +1 -9
- package/docs/README.md +5 -2
- package/docs/actions.mdx +3 -3
- package/docs/agent-cheatsheet.md +4 -4
- package/docs/architecture.md +6 -6
- package/docs/best-practices.mdx +1 -1
- package/docs/capabilities.mdx +32 -1
- package/docs/cli/cloud.mdx +21 -9
- package/docs/cli/doctor.mdx +4 -0
- package/docs/cli/feedback.mdx +2 -2
- package/docs/cli/gate.mdx +9 -4
- package/docs/cli/init.mdx +1 -0
- package/docs/cli/report.mdx +44 -0
- package/docs/cli/update.mdx +10 -0
- package/docs/cli.mdx +9 -0
- package/docs/desktop.mdx +14 -10
- package/docs/environment.mdx +87 -0
- package/docs/faq.mdx +18 -16
- package/docs/first-drive.md +5 -13
- package/docs/flows.md +32 -2
- package/docs/frameworks.mdx +140 -9
- package/docs/getting-started.md +3 -3
- package/docs/http-transport.md +6 -3
- package/docs/human-control.md +2 -2
- package/docs/index.mdx +16 -6
- package/docs/install-agentic.mdx +37 -1
- package/docs/install-manual.mdx +1 -1
- package/docs/integration-patterns.md +3 -3
- package/docs/multi-agent-testing.md +1 -1
- package/docs/packages/babel-plugin.mdx +1 -1
- package/docs/packages/browser.mdx +2 -2
- package/docs/packages/react.mdx +2 -2
- package/docs/packages/tauri.mdx +1 -1
- package/docs/packages/vite-plugin.mdx +2 -2
- package/docs/packages.mdx +9 -9
- package/docs/predicates.mdx +176 -7
- package/docs/quickstart.mdx +2 -2
- package/docs/recipes.mdx +2 -2
- package/docs/state-management.mdx +2 -2
- package/docs/system-map.md +1 -1
- package/docs/telemetry.md +1 -1
- package/docs/token-efficiency.md +3 -3
- package/docs/tools/act-and-wait.mdx +1 -0
- package/docs/tools/act-sequence.mdx +1 -1
- package/docs/tools/console.mdx +1 -1
- package/docs/tools/inspect.mdx +1 -1
- package/docs/tools/network.mdx +1 -1
- package/docs/tools/query.mdx +11 -11
- package/docs/tools/sessions.mdx +1 -1
- package/docs/tools/snapshot.mdx +1 -1
- package/docs/tools/state.mdx +1 -1
- package/docs/tools/wait-for.mdx +1 -1
- package/docs/usage.md +8 -7
- package/docs/use-cases.mdx +157 -0
- package/docs/vs-screenshots.mdx +3 -3
- package/docs/what-is-recorded.md +62 -0
- package/docs/what-is-reticle.mdx +17 -20
- package/docs/why-reticle.mdx +14 -21
- package/package.json +11 -10
- package/dist/judgement/capsule/minimize.d.ts +0 -12
- package/dist/judgement/capsule/minimize.js +0 -22
- package/dist/judgement/outcome/predicate-to-expect.d.ts +0 -44
- package/dist/judgement/outcome/predicate-to-expect.js +0 -148
- package/dist/judgement/phenomena/phenomena.d.ts +0 -26
- package/dist/judgement/phenomena/phenomena.js +0 -101
- package/dist/language/flows/flow-report.d.ts +0 -22
- package/dist/language/flows/flow-report.js +0 -106
|
@@ -21,7 +21,6 @@
|
|
|
21
21
|
*/
|
|
22
22
|
import { z } from 'zod';
|
|
23
23
|
import { type Intent } from '@reticlehq/core/artifacts';
|
|
24
|
-
import type { FileSystemPort } from '../project/fs/fs-port.js';
|
|
25
24
|
/**
|
|
26
25
|
* How settled a record is.
|
|
27
26
|
*
|
|
@@ -311,25 +310,6 @@ export declare const IntentShardSchema: z.ZodObject<{
|
|
|
311
310
|
}>;
|
|
312
311
|
}>;
|
|
313
312
|
export type IntentShard = z.infer<typeof IntentShardSchema>;
|
|
314
|
-
export declare const summarise: (statement: string) => string;
|
|
315
|
-
/** One line per intent: enough to decide whether to open the shard, and no more. */
|
|
316
|
-
declare const IntentIndexEntrySchema: z.ZodObject<{
|
|
317
|
-
id: z.ZodString;
|
|
318
|
-
subject: z.ZodString;
|
|
319
|
-
statement: z.ZodString;
|
|
320
|
-
status: z.ZodEnum<["proposed", "agreed", "proved", "stale"]>;
|
|
321
|
-
}, "strip", z.ZodTypeAny, {
|
|
322
|
-
status: "proved" | "proposed" | "agreed" | "stale";
|
|
323
|
-
id: string;
|
|
324
|
-
subject: string;
|
|
325
|
-
statement: string;
|
|
326
|
-
}, {
|
|
327
|
-
status: "proved" | "proposed" | "agreed" | "stale";
|
|
328
|
-
id: string;
|
|
329
|
-
subject: string;
|
|
330
|
-
statement: string;
|
|
331
|
-
}>;
|
|
332
|
-
export type IntentIndexEntry = z.infer<typeof IntentIndexEntrySchema>;
|
|
333
313
|
export declare const IntentIndexSchema: z.ZodObject<{
|
|
334
314
|
version: z.ZodLiteral<1>;
|
|
335
315
|
entries: z.ZodArray<z.ZodObject<{
|
|
@@ -367,7 +347,6 @@ export declare const IntentIndexSchema: z.ZodObject<{
|
|
|
367
347
|
}>;
|
|
368
348
|
export type IntentIndex = z.infer<typeof IntentIndexSchema>;
|
|
369
349
|
export declare const emptyShard: (subject: string) => IntentShard;
|
|
370
|
-
export declare const emptyIndex: () => IntentIndex;
|
|
371
350
|
/** The verification lifecycle a legacy record carried, mapped onto the settledness axis. */
|
|
372
351
|
export declare const statusFromState: (state: Intent["state"]) => IntentStatus;
|
|
373
352
|
/**
|
|
@@ -384,6 +363,4 @@ export declare const indexFrom: (shards: readonly IntentShard[]) => IntentIndex;
|
|
|
384
363
|
export declare const shardsFrom: (records: readonly IntentRecord[]) => IntentShard[];
|
|
385
364
|
/** Serialise byte-stably, with keys sorted so a re-save of unchanged data is a no-op diff. */
|
|
386
365
|
export declare const serialise: (value: unknown) => string;
|
|
387
|
-
/** Read + validate one JSON file, failing soft: a hand-merged file with a conflict marker is real. */
|
|
388
|
-
export declare const readJsonFile: <T>(fs: FileSystemPort, path: string, parse: (raw: unknown) => T, fallback: T) => Promise<T>;
|
|
389
366
|
export {};
|
|
@@ -74,7 +74,7 @@ export const IntentShardSchema = z.object({
|
|
|
74
74
|
* can do to a file meant to be read every session, which is the reason to keep it.
|
|
75
75
|
*/
|
|
76
76
|
const SUMMARY_MAX = 72;
|
|
77
|
-
|
|
77
|
+
const summarise = (statement) => statement.length <= SUMMARY_MAX ? statement : `${statement.slice(0, SUMMARY_MAX - 1).trimEnd()}…`;
|
|
78
78
|
/** One line per intent: enough to decide whether to open the shard, and no more. */
|
|
79
79
|
const IntentIndexEntrySchema = z.object({
|
|
80
80
|
id: z.string().min(1),
|
|
@@ -96,7 +96,6 @@ export const emptyShard = (subject) => ({
|
|
|
96
96
|
subject,
|
|
97
97
|
intents: {},
|
|
98
98
|
});
|
|
99
|
-
export const emptyIndex = () => ({ version: INTENT_SHARD_VERSION, entries: [] });
|
|
100
99
|
/** The verification lifecycle a legacy record carried, mapped onto the settledness axis. */
|
|
101
100
|
export const statusFromState = (state) => 'proved' === state ? IntentStatus.PROVED : IntentStatus.AGREED;
|
|
102
101
|
/**
|
|
@@ -142,12 +141,3 @@ const sortKeys = (value) => {
|
|
|
142
141
|
return value;
|
|
143
142
|
return Object.fromEntries(Object.entries(value).sort(([a], [b]) => a.localeCompare(b)));
|
|
144
143
|
};
|
|
145
|
-
/** Read + validate one JSON file, failing soft: a hand-merged file with a conflict marker is real. */
|
|
146
|
-
export const readJsonFile = async (fs, path, parse, fallback) => {
|
|
147
|
-
try {
|
|
148
|
-
return parse(JSON.parse(await fs.readFile(path)));
|
|
149
|
-
}
|
|
150
|
-
catch {
|
|
151
|
-
return fallback;
|
|
152
|
-
}
|
|
153
|
-
};
|
|
@@ -1,6 +1,14 @@
|
|
|
1
1
|
import { type Intent, type IntentSurface } from '@reticlehq/core/artifacts';
|
|
2
2
|
import type { FileSystemPort } from '../project/fs/fs-port.js';
|
|
3
3
|
import type { Clock } from '../../machine/clock.js';
|
|
4
|
+
/**
|
|
5
|
+
* The intent ledger's domain operations: declare, place, bind, discharge.
|
|
6
|
+
*
|
|
7
|
+
* Every operation is a PURE transition from core (`redeclareIntent`, `bindIntent`,
|
|
8
|
+
* `dischargeIntent`) handed to the ledger's atomic upsert. Storage is `IntentShardStore` —
|
|
9
|
+
* `.reticle/intent/<subject>/intent.json`, a flow's name being its subject — and this class writes no
|
|
10
|
+
* file of its own, so there is exactly one place an intent can be.
|
|
11
|
+
*/
|
|
4
12
|
export declare class IntentStore {
|
|
5
13
|
#private;
|
|
6
14
|
constructor(fs: FileSystemPort, root: string, clock: Clock);
|
|
@@ -12,7 +20,8 @@ export declare class IntentStore {
|
|
|
12
20
|
* Declare one or more intents.
|
|
13
21
|
*
|
|
14
22
|
* Batched because the marginal cost of the whole mechanism has to stay at one call per feature; an
|
|
15
|
-
* agent that must make five calls to declare five things will make none.
|
|
23
|
+
* agent that must make five calls to declare five things will make none. Saying an intent again
|
|
24
|
+
* does not unsay it: see `redeclareIntent` for what survives.
|
|
16
25
|
*/
|
|
17
26
|
declare(entries: readonly {
|
|
18
27
|
id: string;
|
|
@@ -22,13 +31,9 @@ export declare class IntentStore {
|
|
|
22
31
|
/**
|
|
23
32
|
* File a record under where it turned out to be about.
|
|
24
33
|
*
|
|
25
|
-
* Separate from `declare` because
|
|
26
|
-
*
|
|
27
|
-
*
|
|
28
|
-
* the intent is ABOUT only exists after the consequence lands.
|
|
29
|
-
*
|
|
30
|
-
* Write-once: an existing surface is never overwritten. A record placed by an agent that named its
|
|
31
|
-
* own subject must not be re-filed by a later run that happened to be somewhere else.
|
|
34
|
+
* Separate from `declare` because an inline intent is declared BEFORE the action, and the route
|
|
35
|
+
* that describes it only exists after the consequence lands. Write-once: an existing surface is
|
|
36
|
+
* never overwritten. A flow named here moves the record into that flow's directory.
|
|
32
37
|
*/
|
|
33
38
|
place(id: string, surface: IntentSurface): Promise<boolean>;
|
|
34
39
|
/** Attach the predicate that would prove an intent. False when the id names nothing. */
|
|
@@ -1,115 +1,71 @@
|
|
|
1
|
-
import { bindIntent, declareIntent,
|
|
2
|
-
import {
|
|
3
|
-
import {
|
|
1
|
+
import { IntentState, bindIntent, declareIntent, redeclareIntent, dischargeIntent, isActionLabel, } from '@reticlehq/core/artifacts';
|
|
2
|
+
import { IntentShardStore } from './intent-shard-store.js';
|
|
3
|
+
import { IntentStatus } from './intent-shard.js';
|
|
4
4
|
/**
|
|
5
|
-
* The intent ledger
|
|
5
|
+
* The intent ledger's domain operations: declare, place, bind, discharge.
|
|
6
6
|
*
|
|
7
|
-
*
|
|
8
|
-
*
|
|
9
|
-
*
|
|
10
|
-
*
|
|
11
|
-
*
|
|
12
|
-
* Every operation goes through the same file lock the other stores use, because two sessions driving
|
|
13
|
-
* one project is ordinary and a lost declaration would be silent.
|
|
7
|
+
* Every operation is a PURE transition from core (`redeclareIntent`, `bindIntent`,
|
|
8
|
+
* `dischargeIntent`) handed to the ledger's atomic upsert. Storage is `IntentShardStore` —
|
|
9
|
+
* `.reticle/intent/<subject>/intent.json`, a flow's name being its subject — and this class writes no
|
|
10
|
+
* file of its own, so there is exactly one place an intent can be.
|
|
14
11
|
*/
|
|
15
|
-
const JSON_INDENT = 2;
|
|
16
12
|
export class IntentStore {
|
|
17
|
-
#
|
|
18
|
-
#root;
|
|
13
|
+
#ledger;
|
|
19
14
|
#clock;
|
|
20
15
|
constructor(fs, root, clock) {
|
|
21
|
-
this.#
|
|
22
|
-
this.#root = root;
|
|
16
|
+
this.#ledger = new IntentShardStore(fs, root, clock);
|
|
23
17
|
this.#clock = clock;
|
|
24
18
|
}
|
|
25
|
-
#path() {
|
|
26
|
-
return reticleDirPaths(this.#root).intent;
|
|
27
|
-
}
|
|
28
|
-
/**
|
|
29
|
-
* Load the ledger, failing soft to empty.
|
|
30
|
-
*
|
|
31
|
-
* This is a git-checked file an agent can write and a human can hand-merge, so a malformed one is
|
|
32
|
-
* genuinely reachable — a conflict marker left in place is the obvious case. Throwing here would
|
|
33
|
-
* take down the verdict that was only asking what was still open, which trades a small problem for
|
|
34
|
-
* a large one.
|
|
35
|
-
*/
|
|
36
|
-
async #load() {
|
|
37
|
-
try {
|
|
38
|
-
const raw = await this.#fs.readFile(this.#path());
|
|
39
|
-
return parseIntentFile(JSON.parse(raw));
|
|
40
|
-
}
|
|
41
|
-
catch {
|
|
42
|
-
return emptyIntentFile();
|
|
43
|
-
}
|
|
44
|
-
}
|
|
45
|
-
/** Byte-stable: 2-space indent, one trailing newline. An unchanged ledger produces no diff. */
|
|
46
|
-
async #save(file) {
|
|
47
|
-
await this.#fs.mkdir(reticleDirPaths(this.#root).root);
|
|
48
|
-
await this.#fs.writeFile(this.#path(), `${JSON.stringify(file, null, JSON_INDENT)}\n`);
|
|
49
|
-
}
|
|
50
19
|
/** Every intent, in declaration order. */
|
|
51
20
|
async read() {
|
|
52
|
-
return
|
|
21
|
+
return this.#ledger.all();
|
|
53
22
|
}
|
|
54
23
|
/** Everything not yet proved — what an agent asking "am I done?" still owes. */
|
|
55
24
|
async open() {
|
|
56
|
-
|
|
25
|
+
// Stale is not owed: it is kept as history, not as work.
|
|
26
|
+
return (await this.#ledger.all()).filter((record) => IntentState.PROVED !== record.state && IntentStatus.STALE !== record.status);
|
|
57
27
|
}
|
|
58
28
|
/**
|
|
59
29
|
* Declare one or more intents.
|
|
60
30
|
*
|
|
61
31
|
* Batched because the marginal cost of the whole mechanism has to stay at one call per feature; an
|
|
62
|
-
* agent that must make five calls to declare five things will make none.
|
|
32
|
+
* agent that must make five calls to declare five things will make none. Saying an intent again
|
|
33
|
+
* does not unsay it: see `redeclareIntent` for what survives.
|
|
63
34
|
*/
|
|
64
35
|
async declare(entries) {
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
declared.push(stored);
|
|
77
|
-
}
|
|
78
|
-
await this.#save(file);
|
|
79
|
-
return declared;
|
|
80
|
-
});
|
|
36
|
+
const now = this.#clock.now();
|
|
37
|
+
const declared = [];
|
|
38
|
+
for (const entry of entries) {
|
|
39
|
+
// A step label is a log line, not a rule: every route that declares comes through here.
|
|
40
|
+
if (isActionLabel(entry.statement))
|
|
41
|
+
continue;
|
|
42
|
+
const stored = await this.#ledger.upsert(entry.id, (existing) => redeclareIntent(existing, declareIntent({ ...entry, now })));
|
|
43
|
+
if (stored !== undefined)
|
|
44
|
+
declared.push(stored);
|
|
45
|
+
}
|
|
46
|
+
return declared;
|
|
81
47
|
}
|
|
82
48
|
/**
|
|
83
49
|
* File a record under where it turned out to be about.
|
|
84
50
|
*
|
|
85
|
-
* Separate from `declare` because
|
|
86
|
-
*
|
|
87
|
-
*
|
|
88
|
-
* the intent is ABOUT only exists after the consequence lands.
|
|
89
|
-
*
|
|
90
|
-
* Write-once: an existing surface is never overwritten. A record placed by an agent that named its
|
|
91
|
-
* own subject must not be re-filed by a later run that happened to be somewhere else.
|
|
51
|
+
* Separate from `declare` because an inline intent is declared BEFORE the action, and the route
|
|
52
|
+
* that describes it only exists after the consequence lands. Write-once: an existing surface is
|
|
53
|
+
* never overwritten. A flow named here moves the record into that flow's directory.
|
|
92
54
|
*/
|
|
93
55
|
async place(id, surface) {
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
const existing = file.intents[id];
|
|
56
|
+
let placed = false;
|
|
57
|
+
await this.#ledger.upsert(id, (existing) => {
|
|
97
58
|
if (existing === undefined || existing.surface !== undefined)
|
|
98
|
-
return
|
|
99
|
-
|
|
100
|
-
return
|
|
59
|
+
return undefined;
|
|
60
|
+
placed = true;
|
|
61
|
+
return { ...existing, surface };
|
|
101
62
|
});
|
|
63
|
+
return placed;
|
|
102
64
|
}
|
|
103
65
|
/** Attach the predicate that would prove an intent. False when the id names nothing. */
|
|
104
66
|
async bind(id, binding) {
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
const existing = file.intents[id];
|
|
108
|
-
if (existing === undefined)
|
|
109
|
-
return false;
|
|
110
|
-
await this.#save(upsertIntent(file, bindIntent(existing, binding)));
|
|
111
|
-
return true;
|
|
112
|
-
});
|
|
67
|
+
const stored = await this.#ledger.upsert(id, (existing) => existing === undefined ? undefined : bindIntent(existing, binding));
|
|
68
|
+
return stored !== undefined;
|
|
113
69
|
}
|
|
114
70
|
/**
|
|
115
71
|
* Record that a verdict proved an intent.
|
|
@@ -118,16 +74,16 @@ export class IntentStore {
|
|
|
118
74
|
* and must never be the reason one fails to return.
|
|
119
75
|
*/
|
|
120
76
|
async discharge(id, proof) {
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
const existing = file.intents[id];
|
|
77
|
+
let proved = false;
|
|
78
|
+
await this.#ledger.upsert(id, (existing) => {
|
|
124
79
|
if (existing === undefined)
|
|
125
|
-
return
|
|
126
|
-
const
|
|
127
|
-
if (
|
|
128
|
-
return
|
|
129
|
-
|
|
130
|
-
return
|
|
80
|
+
return undefined;
|
|
81
|
+
const next = dischargeIntent(existing, proof);
|
|
82
|
+
if (next === existing)
|
|
83
|
+
return undefined;
|
|
84
|
+
proved = true;
|
|
85
|
+
return next;
|
|
131
86
|
});
|
|
87
|
+
return proved;
|
|
132
88
|
}
|
|
133
89
|
}
|
|
@@ -4,8 +4,10 @@ import { IntentShardStore } from './intent-shard-store.js';
|
|
|
4
4
|
import { IntentStatus } from './intent-shard.js';
|
|
5
5
|
import { ReticleTool } from '@reticlehq/core';
|
|
6
6
|
import { sessionIdShape } from '../../surface/tools/tool-kit.js';
|
|
7
|
+
import { PredicateSchema } from '@reticlehq/engine/question/predicate/predicate.js';
|
|
7
8
|
import { sessionRoot } from '../project/session-root.js';
|
|
8
9
|
import { asString } from '@reticlehq/core';
|
|
10
|
+
import { isActionLabel } from '@reticlehq/core/artifacts';
|
|
9
11
|
/**
|
|
10
12
|
* Declare what a change was SUPPOSED to make true, while somebody still knows.
|
|
11
13
|
*
|
|
@@ -24,11 +26,13 @@ const INDEX = 'index';
|
|
|
24
26
|
const SUBJECT = 'subject';
|
|
25
27
|
const GET = 'get';
|
|
26
28
|
const RECORD = 'record';
|
|
29
|
+
/** Why a step label is not stored, in words that say what to write instead. */
|
|
30
|
+
const STEP_LABEL_REFUSAL = 'describes a step that was done, not what must be true. State the rule, e.g. "saving the form shows the new row in the list"';
|
|
27
31
|
const MIGRATE = 'migrate';
|
|
28
32
|
export const INTENT_TOOLS = [
|
|
29
33
|
{
|
|
30
34
|
name: ReticleTool.INTENT,
|
|
31
|
-
description: 'Record what a change is SUPPOSED to make true, as a durable statement ABOUT THE PRODUCT that a teammate who was not here will understand in six months — name the behaviour, not this run or its step number, and never "renders cleanly", which nothing can check. It is SHARED memory: pooled per project and read back by later agents. Capture it while you still know — then verification does not have to re-derive it from the DOM later. { action:"declare", intents:[{ id, statement, surface? }] } takes prose and needs NO predicate: at declare time there is often no route, no ref and no code yet, and a predicate demanded there is just a mechanism. Declare EARLY (as you build) and batch them — one call per feature is the whole budget. { action:"bind", id, binding } attaches the predicate that would prove it once you know how; an intent with no binding is not a failure, it is the most interesting row in the ledger — something meant that nothing can currently prove. { action:"list" } returns what is still open. Stored in .reticle/intent.json, git-checked so a human sees in review if an intent was later narrowed to match what was easy to prove.',
|
|
35
|
+
description: 'Record what a change is SUPPOSED to make true, as a durable statement ABOUT THE PRODUCT that a teammate who was not here will understand in six months — name the behaviour, not this run or its step number, and never "renders cleanly", which nothing can check. It is SHARED memory: pooled per project and read back by later agents. Capture it while you still know — then verification does not have to re-derive it from the DOM later. { action:"declare", intents:[{ id, statement, surface? }] } takes prose and needs NO predicate: at declare time there is often no route, no ref and no code yet, and a predicate demanded there is just a mechanism. Declare EARLY (as you build) and batch them — one call per feature is the whole budget. { action:"bind", id, binding } attaches the predicate that would prove it once you know how; an intent with no binding is not a failure, it is the most interesting row in the ledger — something meant that nothing can currently prove. { action:"list" } returns what is still open. Stored in .reticle/intent/<subject>/intent.json (a flow name is its subject), git-checked so a human sees in review if an intent was later narrowed to match what was easy to prove.',
|
|
32
36
|
example: {
|
|
33
37
|
action: DECLARE,
|
|
34
38
|
intents: [
|
|
@@ -56,8 +60,8 @@ export const INTENT_TOOLS = [
|
|
|
56
60
|
.describe('record only: how settled it is. Defaults to proposed.'),
|
|
57
61
|
intents: z
|
|
58
62
|
.array(z.object({
|
|
59
|
-
id: z.string(),
|
|
60
|
-
statement: z.string(),
|
|
63
|
+
id: z.string().min(1),
|
|
64
|
+
statement: z.string().min(1),
|
|
61
65
|
surface: z
|
|
62
66
|
.object({
|
|
63
67
|
route: z.string().optional(),
|
|
@@ -69,10 +73,19 @@ export const INTENT_TOOLS = [
|
|
|
69
73
|
.optional()
|
|
70
74
|
.describe('declare only. Batchable — declare every intent for a feature in one call.'),
|
|
71
75
|
id: z.string().optional().describe('bind only: which intent the predicate proves.'),
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
+
/*
|
|
77
|
+
* The predicate schema, not `unknown`.
|
|
78
|
+
*
|
|
79
|
+
* The description has always said "in reticle_assert's shape" and the type said "anything",
|
|
80
|
+
* so a client reading the surface to build this call learned the field's name and nothing
|
|
81
|
+
* else — the same degradation the recursive `until` predicate suffered when it was converted
|
|
82
|
+
* without the SDK's own options. This one was not a converter bug: it was declared that way.
|
|
83
|
+
* Caught by `weakest-client-schemas.test.ts`, which is the first thing that ever looked.
|
|
84
|
+
*
|
|
85
|
+
* Accepting the real shape also means a malformed binding is refused at the boundary instead
|
|
86
|
+
* of being written into the ledger and failing later against a verdict it can never satisfy.
|
|
87
|
+
*/
|
|
88
|
+
binding: PredicateSchema.optional().describe("bind only: the predicate that would prove it, in reticle_assert's shape."),
|
|
76
89
|
...sessionIdShape,
|
|
77
90
|
},
|
|
78
91
|
outputSchema: {
|
|
@@ -81,6 +94,10 @@ export const INTENT_TOOLS = [
|
|
|
81
94
|
.optional()
|
|
82
95
|
.describe('The intents this call declared, or on `list` everything still open — each { id, statement, state, declaredAt, binding?, surface?, provenBy?, amended? }. `state` is declared (prose only), bound (a predicate exists), or proved (a verdict satisfied it).'),
|
|
83
96
|
bound: z.boolean().optional().describe('bind only: false when the id names no intent.'),
|
|
97
|
+
refused: z
|
|
98
|
+
.array(z.object({ id: z.string(), reason: z.string() }))
|
|
99
|
+
.optional()
|
|
100
|
+
.describe('declare only: statements not stored, and why.'),
|
|
84
101
|
path: z.string().optional().describe('Where the ledger was written.'),
|
|
85
102
|
entries: z
|
|
86
103
|
.array(z.unknown())
|
|
@@ -130,28 +147,22 @@ export const INTENT_TOOLS = [
|
|
|
130
147
|
return { bound: await store.bind(id, args['binding']) };
|
|
131
148
|
}
|
|
132
149
|
if (LIST === action) {
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
* `.reticle/intent/`. Listing only the flat one meant a recorded intent could not be found
|
|
138
|
-
* again by the agent that had just written it — and the lesson an agent draws from that is
|
|
139
|
-
* "the intent does not exist", not "there are two stores".
|
|
140
|
-
*
|
|
141
|
-
* Merged HERE rather than inside either store: this tool is the one seam that knows both
|
|
142
|
-
* exist, and neither store should have to learn the other's layout to stay honest.
|
|
143
|
-
*/
|
|
144
|
-
const flat = await store.open();
|
|
145
|
-
const seen = new Set(flat.map((intent) => intent.id));
|
|
146
|
-
const fromShards = (await shards.all()).filter((record) => !seen.has(record.id));
|
|
147
|
-
return { intents: [...flat, ...fromShards] };
|
|
150
|
+
// One ledger, so one read. This merged two stores while `declare` and `record` wrote two
|
|
151
|
+
// different files; kept past that, it would add back every PROVED intent to a list that
|
|
152
|
+
// promises only what is still open.
|
|
153
|
+
return { intents: await store.open() };
|
|
148
154
|
}
|
|
149
155
|
const raw = args['intents'];
|
|
150
156
|
const entries = Array.isArray(raw)
|
|
151
157
|
? raw
|
|
152
158
|
: [];
|
|
153
159
|
const declared = await store.declare(entries);
|
|
154
|
-
|
|
160
|
+
// Said, not swallowed: an agent that declared something and finds nothing stored would
|
|
161
|
+
// otherwise conclude the ledger lost it.
|
|
162
|
+
const refused = entries
|
|
163
|
+
.filter((entry) => isActionLabel(entry.statement))
|
|
164
|
+
.map((entry) => ({ id: entry.id, reason: STEP_LABEL_REFUSAL }));
|
|
165
|
+
return { intents: declared, ...(0 === refused.length ? {} : { refused }), path: root };
|
|
155
166
|
},
|
|
156
167
|
},
|
|
157
168
|
];
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { dirname } from 'node:path';
|
|
2
|
+
import { writeFileAtomic } from '../project/fs/write-atomic.js';
|
|
2
3
|
import { reticleDirPaths } from '../project/dir/reticle-dir.js';
|
|
3
4
|
import { AmbientFileSchema } from './on-disk/ambient-file.js';
|
|
4
5
|
import { onlyStableAmbient } from '@reticlehq/engine/window/ambient.js';
|
|
@@ -45,8 +46,6 @@ export class AmbientStore {
|
|
|
45
46
|
// numbering, so persisting it teaches the next session to suppress an element it never saw.
|
|
46
47
|
const regions = onlyStableAmbient(counts);
|
|
47
48
|
const body = `${JSON.stringify({ version: AMBIENT_FILE_VERSION, regions }, null, 2)}\n`;
|
|
48
|
-
|
|
49
|
-
await this.#fs.writeFile(tmp, body);
|
|
50
|
-
await this.#fs.rename(tmp, this.#path);
|
|
49
|
+
await writeFileAtomic(this.#fs, this.#path, body);
|
|
51
50
|
}
|
|
52
51
|
}
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { routeTemplate } from './route-template.js';
|
|
1
2
|
import { compareSegment, MIN_ENVELOPE_SAMPLES, } from './envelope.js';
|
|
2
3
|
function headlineFor(report) {
|
|
3
4
|
const truncNote = report.truncatedSegments > 0
|
|
@@ -31,7 +32,9 @@ export function buildDeviationReport(envelopes, segments, zThreshold) {
|
|
|
31
32
|
truncated += 1;
|
|
32
33
|
continue;
|
|
33
34
|
}
|
|
34
|
-
|
|
35
|
+
// The SAME key the service accumulates under — a lookup on the observed path would miss every
|
|
36
|
+
// envelope on an app with ids in its URLs, which is the case this templating exists for.
|
|
37
|
+
const envelope = envelopes.get(routeTemplate(segment.route));
|
|
35
38
|
if (envelope === undefined || envelope.samples < MIN_ENVELOPE_SAMPLES)
|
|
36
39
|
continue;
|
|
37
40
|
judged += 1;
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { routeTemplate } from './route-template.js';
|
|
1
2
|
import { addSegmentToEnvelope, emptyEnvelope } from './envelope.js';
|
|
2
3
|
import { buildDeviationReport } from './deviation-report.js';
|
|
3
4
|
import { withFileLock } from '../project/file-lock.js';
|
|
@@ -22,8 +23,15 @@ export async function reportAndAccumulate(store, segments, zThreshold) {
|
|
|
22
23
|
// Never learn from a truncated sample — its understated counts would poison the baseline.
|
|
23
24
|
if (true === segment.truncated)
|
|
24
25
|
continue;
|
|
25
|
-
|
|
26
|
-
|
|
26
|
+
/*
|
|
27
|
+
* Keyed on the route TEMPLATE, not the observed path. Keyed on the path, an app with ids in
|
|
28
|
+
* its URLs mints one envelope per id, every envelope holds a single sample, and nothing ever
|
|
29
|
+
* reaches MIN_ENVELOPE_SAMPLES — so the deviation report answers "envelope too new" forever
|
|
30
|
+
* and the feature never turns on. See route-template.ts.
|
|
31
|
+
*/
|
|
32
|
+
const key = routeTemplate(segment.route);
|
|
33
|
+
const current = envelopes.get(key) ?? emptyEnvelope(key);
|
|
34
|
+
envelopes.set(key, addSegmentToEnvelope(current, segment));
|
|
27
35
|
}
|
|
28
36
|
await store.save(envelopes);
|
|
29
37
|
return report;
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import type {
|
|
1
|
+
import type { FlowFile, FlowName, Predicate } from '@reticlehq/core';
|
|
2
2
|
/**
|
|
3
3
|
* What this module needs a recorded step to BE, named structurally rather than imported.
|
|
4
4
|
*
|
|
@@ -12,9 +12,13 @@ export interface TapeStep {
|
|
|
12
12
|
tool: string;
|
|
13
13
|
args: Record<string, unknown>;
|
|
14
14
|
stable: boolean;
|
|
15
|
-
expect?:
|
|
15
|
+
expect?: Predicate;
|
|
16
16
|
/** Recorder-internal, and the field journeys are cut on. Never written to the saved flow. */
|
|
17
17
|
route?: string;
|
|
18
|
+
page?: string;
|
|
19
|
+
endPage?: string;
|
|
20
|
+
/** The intent the agent declared on this action. The first one names the journey. */
|
|
21
|
+
intent?: string;
|
|
18
22
|
}
|
|
19
23
|
/** The compiled shape a flow store accepts. Structural, for the same reason as `TapeStep`. */
|
|
20
24
|
export interface DriveProgram {
|
|
@@ -22,6 +26,7 @@ export interface DriveProgram {
|
|
|
22
26
|
version: number;
|
|
23
27
|
steps: TapeStep[];
|
|
24
28
|
startPath?: string;
|
|
29
|
+
author?: FlowFile['author'];
|
|
25
30
|
}
|
|
26
31
|
/**
|
|
27
32
|
* What a session drove, saved as a replayable flow — without anybody asking for it.
|
|
@@ -36,21 +41,21 @@ export interface DriveProgram {
|
|
|
36
41
|
*/
|
|
37
42
|
/** The one condition on saving, and the reason the whole thing is safe. */
|
|
38
43
|
export declare function carriesAnAssertion(steps: readonly TapeStep[]): boolean;
|
|
44
|
+
/** Every auto-saved flow's name starts here, which is what lets a merge tell them from hand-named ones. */
|
|
45
|
+
export declare const DRIVE_FLOW_PREFIX = "drive-";
|
|
39
46
|
/**
|
|
40
|
-
* A
|
|
47
|
+
* A readable name for a journey, led by WHY it was driven.
|
|
41
48
|
*
|
|
42
|
-
*
|
|
43
|
-
*
|
|
44
|
-
*
|
|
45
|
-
* because `presenter-controls.ts` renders it straight into the replay button's `textContent` — so
|
|
46
|
-
* the label a person actually sees was `drive-sdc991872-6d66-4adf-8780-f931c62905f9`, twice, for two
|
|
47
|
-
* different journeys. A session id is a fact about the socket, not about the feature.
|
|
49
|
+
* The agent's own `intent` on the action is the best name there is — it is the sentence a person
|
|
50
|
+
* would use — so it leads when one was declared. Without one, what the journey proved names it (the
|
|
51
|
+
* strongest claim first), and the route follows so two journeys stay apart.
|
|
48
52
|
*
|
|
49
|
-
*
|
|
50
|
-
*
|
|
51
|
-
*
|
|
53
|
+
* No session id. It used to trail every name so two sessions never overwrote each other, which also
|
|
54
|
+
* made every session's drive of the same journey its own file. Two DIFFERENT journeys that land on
|
|
55
|
+
* one name are now told apart at save by their shape, and two copies of the SAME journey merge —
|
|
56
|
+
* see FlowStore.saveJourney.
|
|
52
57
|
*/
|
|
53
|
-
export declare function driveFlowName(
|
|
58
|
+
export declare function driveFlowName(route?: string, steps?: readonly TapeStep[]): FlowName;
|
|
54
59
|
export interface DriveFlowOutcome {
|
|
55
60
|
/** The flows that were written — one per journey the session contained. */
|
|
56
61
|
readonly saved?: readonly string[];
|
|
@@ -65,7 +70,7 @@ export interface DriveFlowOutcome {
|
|
|
65
70
|
readonly unprovenSteps?: number;
|
|
66
71
|
}
|
|
67
72
|
/** A flow per journey, so two journeys in one session are two regression tests rather than one. */
|
|
68
|
-
export declare function driveFlowsFrom(
|
|
73
|
+
export declare function driveFlowsFrom(tape: {
|
|
69
74
|
steps: readonly TapeStep[];
|
|
70
75
|
startPath?: string;
|
|
71
76
|
} | undefined): {
|