open-multi-agent-kit 0.80.6 → 0.80.7
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/CHANGELOG.md +11 -1
- package/README.md +22 -14
- package/dist/cli/config-selector.d.ts +1 -1
- package/dist/cli/config-selector.d.ts.map +1 -1
- package/dist/cli/config-selector.js +1 -1
- package/dist/cli/config-selector.js.map +1 -1
- package/dist/config.d.ts +1 -0
- package/dist/config.d.ts.map +1 -1
- package/dist/config.js +9 -8
- package/dist/config.js.map +1 -1
- package/dist/core/agent-session.d.ts +45 -6
- package/dist/core/agent-session.d.ts.map +1 -1
- package/dist/core/agent-session.js +197 -13
- package/dist/core/agent-session.js.map +1 -1
- package/dist/core/auth-storage.d.ts +4 -1
- package/dist/core/auth-storage.d.ts.map +1 -1
- package/dist/core/auth-storage.js +5 -5
- package/dist/core/auth-storage.js.map +1 -1
- package/dist/core/bash-executor.d.ts.map +1 -1
- package/dist/core/bash-executor.js +1 -1
- package/dist/core/bash-executor.js.map +1 -1
- package/dist/core/command-safety.d.ts +11 -0
- package/dist/core/command-safety.d.ts.map +1 -0
- package/dist/core/command-safety.js +528 -0
- package/dist/core/command-safety.js.map +1 -0
- package/dist/core/compaction/branch-summarization.d.ts.map +1 -1
- package/dist/core/compaction/branch-summarization.js +14 -4
- package/dist/core/compaction/branch-summarization.js.map +1 -1
- package/dist/core/compaction/compaction.d.ts +18 -1
- package/dist/core/compaction/compaction.d.ts.map +1 -1
- package/dist/core/compaction/compaction.js +80 -42
- package/dist/core/compaction/compaction.js.map +1 -1
- package/dist/core/compaction/pruner-policy.d.ts +84 -0
- package/dist/core/compaction/pruner-policy.d.ts.map +1 -0
- package/dist/core/compaction/pruner-policy.js +273 -0
- package/dist/core/compaction/pruner-policy.js.map +1 -0
- package/dist/core/context-graph-identity-resolution.d.ts +114 -0
- package/dist/core/context-graph-identity-resolution.d.ts.map +1 -0
- package/dist/core/context-graph-identity-resolution.js +127 -0
- package/dist/core/context-graph-identity-resolution.js.map +1 -0
- package/dist/core/context-graph-memory-store.d.ts +153 -0
- package/dist/core/context-graph-memory-store.d.ts.map +1 -0
- package/dist/core/context-graph-memory-store.js +377 -0
- package/dist/core/context-graph-memory-store.js.map +1 -0
- package/dist/core/context-graph-ontology-generation.d.ts +104 -0
- package/dist/core/context-graph-ontology-generation.d.ts.map +1 -0
- package/dist/core/context-graph-ontology-generation.js +135 -0
- package/dist/core/context-graph-ontology-generation.js.map +1 -0
- package/dist/core/context-graph-ontology-registry.d.ts +766 -0
- package/dist/core/context-graph-ontology-registry.d.ts.map +1 -0
- package/dist/core/context-graph-ontology-registry.js +1133 -0
- package/dist/core/context-graph-ontology-registry.js.map +1 -0
- package/dist/core/context-graph-policy.d.ts +68 -0
- package/dist/core/context-graph-policy.d.ts.map +1 -0
- package/dist/core/context-graph-policy.js +221 -0
- package/dist/core/context-graph-policy.js.map +1 -0
- package/dist/core/context-graph-reasoning.d.ts +130 -0
- package/dist/core/context-graph-reasoning.d.ts.map +1 -0
- package/dist/core/context-graph-reasoning.js +442 -0
- package/dist/core/context-graph-reasoning.js.map +1 -0
- package/dist/core/context-graph-retrieval.d.ts +120 -0
- package/dist/core/context-graph-retrieval.d.ts.map +1 -0
- package/dist/core/context-graph-retrieval.js +288 -0
- package/dist/core/context-graph-retrieval.js.map +1 -0
- package/dist/core/contract-verification.d.ts +78 -0
- package/dist/core/contract-verification.d.ts.map +1 -0
- package/dist/core/contract-verification.js +110 -0
- package/dist/core/contract-verification.js.map +1 -0
- package/dist/core/exact-cache-policy.d.ts +100 -0
- package/dist/core/exact-cache-policy.d.ts.map +1 -0
- package/dist/core/exact-cache-policy.js +175 -0
- package/dist/core/exact-cache-policy.js.map +1 -0
- package/dist/core/exec.d.ts +2 -0
- package/dist/core/exec.d.ts.map +1 -1
- package/dist/core/exec.js +1 -0
- package/dist/core/exec.js.map +1 -1
- package/dist/core/export-html/template.js +2 -2
- package/dist/core/extensions/builtin/command-safety-gate.d.ts +77 -0
- package/dist/core/extensions/builtin/command-safety-gate.d.ts.map +1 -0
- package/dist/core/extensions/builtin/command-safety-gate.js +147 -0
- package/dist/core/extensions/builtin/command-safety-gate.js.map +1 -0
- package/dist/core/extensions/loader.d.ts +4 -4
- package/dist/core/extensions/loader.d.ts.map +1 -1
- package/dist/core/extensions/loader.js +94 -56
- package/dist/core/extensions/loader.js.map +1 -1
- package/dist/core/extensions/runner.d.ts.map +1 -1
- package/dist/core/extensions/runner.js +1 -1
- package/dist/core/extensions/runner.js.map +1 -1
- package/dist/core/extensions/types.d.ts +38 -10
- package/dist/core/extensions/types.d.ts.map +1 -1
- package/dist/core/extensions/types.js.map +1 -1
- package/dist/core/freedom/banner.d.ts +14 -0
- package/dist/core/freedom/banner.d.ts.map +1 -0
- package/dist/core/freedom/banner.js +22 -0
- package/dist/core/freedom/banner.js.map +1 -0
- package/dist/core/freedom/config.d.ts +27 -0
- package/dist/core/freedom/config.d.ts.map +1 -0
- package/dist/core/freedom/config.js +216 -0
- package/dist/core/freedom/config.js.map +1 -0
- package/dist/core/freedom/index.d.ts +23 -0
- package/dist/core/freedom/index.d.ts.map +1 -0
- package/dist/core/freedom/index.js +19 -0
- package/dist/core/freedom/index.js.map +1 -0
- package/dist/core/freedom/policy.d.ts +42 -0
- package/dist/core/freedom/policy.d.ts.map +1 -0
- package/dist/core/freedom/policy.js +47 -0
- package/dist/core/freedom/policy.js.map +1 -0
- package/dist/core/freedom/safety-floor.d.ts +73 -0
- package/dist/core/freedom/safety-floor.d.ts.map +1 -0
- package/dist/core/freedom/safety-floor.js +275 -0
- package/dist/core/freedom/safety-floor.js.map +1 -0
- package/dist/core/harness-control-events.d.ts +13 -1
- package/dist/core/harness-control-events.d.ts.map +1 -1
- package/dist/core/harness-control-events.js +216 -41
- package/dist/core/harness-control-events.js.map +1 -1
- package/dist/core/harness-control-replay.d.ts +7 -2
- package/dist/core/harness-control-replay.d.ts.map +1 -1
- package/dist/core/harness-control-replay.js +36 -4
- package/dist/core/harness-control-replay.js.map +1 -1
- package/dist/core/headroom-middleware.d.ts +35 -0
- package/dist/core/headroom-middleware.d.ts.map +1 -0
- package/dist/core/headroom-middleware.js +166 -0
- package/dist/core/headroom-middleware.js.map +1 -0
- package/dist/core/hook-inventory.d.ts +23 -0
- package/dist/core/hook-inventory.d.ts.map +1 -0
- package/dist/core/hook-inventory.js +50 -0
- package/dist/core/hook-inventory.js.map +1 -0
- package/dist/core/lean-context-middleware.d.ts +12 -0
- package/dist/core/lean-context-middleware.d.ts.map +1 -0
- package/dist/core/lean-context-middleware.js +87 -0
- package/dist/core/lean-context-middleware.js.map +1 -0
- package/dist/core/lean-context-policy.d.ts +45 -0
- package/dist/core/lean-context-policy.d.ts.map +1 -0
- package/dist/core/lean-context-policy.js +108 -0
- package/dist/core/lean-context-policy.js.map +1 -0
- package/dist/core/loadout-access-policy.d.ts +41 -0
- package/dist/core/loadout-access-policy.d.ts.map +1 -0
- package/dist/core/loadout-access-policy.js +182 -0
- package/dist/core/loadout-access-policy.js.map +1 -0
- package/dist/core/loadout-runtime.d.ts +84 -0
- package/dist/core/loadout-runtime.d.ts.map +1 -0
- package/dist/core/loadout-runtime.js +157 -0
- package/dist/core/loadout-runtime.js.map +1 -0
- package/dist/core/loadouts.d.ts +147 -0
- package/dist/core/loadouts.d.ts.map +1 -0
- package/dist/core/loadouts.js +442 -0
- package/dist/core/loadouts.js.map +1 -0
- package/dist/core/mcp-inventory.d.ts +34 -0
- package/dist/core/mcp-inventory.d.ts.map +1 -1
- package/dist/core/mcp-inventory.js +53 -1
- package/dist/core/mcp-inventory.js.map +1 -1
- package/dist/core/mcp-presets.d.ts +57 -0
- package/dist/core/mcp-presets.d.ts.map +1 -0
- package/dist/core/mcp-presets.js +81 -0
- package/dist/core/mcp-presets.js.map +1 -0
- package/dist/core/model-registry.d.ts +1 -0
- package/dist/core/model-registry.d.ts.map +1 -1
- package/dist/core/model-registry.js +40 -17
- package/dist/core/model-registry.js.map +1 -1
- package/dist/core/model-resolver.d.ts.map +1 -1
- package/dist/core/model-resolver.js +1 -0
- package/dist/core/model-resolver.js.map +1 -1
- package/dist/core/native-adoption-benchmark.d.ts +166 -0
- package/dist/core/native-adoption-benchmark.d.ts.map +1 -0
- package/dist/core/native-adoption-benchmark.js +624 -0
- package/dist/core/native-adoption-benchmark.js.map +1 -0
- package/dist/core/observability-trace.d.ts +80 -0
- package/dist/core/observability-trace.d.ts.map +1 -0
- package/dist/core/observability-trace.js +140 -0
- package/dist/core/observability-trace.js.map +1 -0
- package/dist/core/orchestration/checkpoint.d.ts +83 -0
- package/dist/core/orchestration/checkpoint.d.ts.map +1 -0
- package/dist/core/orchestration/checkpoint.js +152 -0
- package/dist/core/orchestration/checkpoint.js.map +1 -0
- package/dist/core/orchestration/errors.d.ts +74 -0
- package/dist/core/orchestration/errors.d.ts.map +1 -0
- package/dist/core/orchestration/errors.js +52 -0
- package/dist/core/orchestration/errors.js.map +1 -0
- package/dist/core/orchestration/merge-queue.d.ts +121 -0
- package/dist/core/orchestration/merge-queue.d.ts.map +1 -0
- package/dist/core/orchestration/merge-queue.js +149 -0
- package/dist/core/orchestration/merge-queue.js.map +1 -0
- package/dist/core/orchestration/recovery.d.ts +106 -0
- package/dist/core/orchestration/recovery.d.ts.map +1 -0
- package/dist/core/orchestration/recovery.js +110 -0
- package/dist/core/orchestration/recovery.js.map +1 -0
- package/dist/core/orchestration/replay-ledger.d.ts +76 -0
- package/dist/core/orchestration/replay-ledger.d.ts.map +1 -0
- package/dist/core/orchestration/replay-ledger.js +395 -0
- package/dist/core/orchestration/replay-ledger.js.map +1 -0
- package/dist/core/orchestration/scheduler-state.d.ts +78 -0
- package/dist/core/orchestration/scheduler-state.d.ts.map +1 -0
- package/dist/core/orchestration/scheduler-state.js +185 -0
- package/dist/core/orchestration/scheduler-state.js.map +1 -0
- package/dist/core/orchestration/scheduler-store.d.ts +309 -0
- package/dist/core/orchestration/scheduler-store.d.ts.map +1 -0
- package/dist/core/orchestration/scheduler-store.js +368 -0
- package/dist/core/orchestration/scheduler-store.js.map +1 -0
- package/dist/core/orchestration/sqlite-scheduler-store.d.ts +57 -0
- package/dist/core/orchestration/sqlite-scheduler-store.d.ts.map +1 -0
- package/dist/core/orchestration/sqlite-scheduler-store.js +528 -0
- package/dist/core/orchestration/sqlite-scheduler-store.js.map +1 -0
- package/dist/core/orchestration/transaction-coordinator.d.ts +217 -0
- package/dist/core/orchestration/transaction-coordinator.d.ts.map +1 -0
- package/dist/core/orchestration/transaction-coordinator.js +281 -0
- package/dist/core/orchestration/transaction-coordinator.js.map +1 -0
- package/dist/core/orchestration/verification-contract.d.ts +197 -0
- package/dist/core/orchestration/verification-contract.d.ts.map +1 -0
- package/dist/core/orchestration/verification-contract.js +145 -0
- package/dist/core/orchestration/verification-contract.js.map +1 -0
- package/dist/core/package-composition.d.ts +68 -0
- package/dist/core/package-composition.d.ts.map +1 -0
- package/dist/core/package-composition.js +304 -0
- package/dist/core/package-composition.js.map +1 -0
- package/dist/core/package-gallery.d.ts +124 -0
- package/dist/core/package-gallery.d.ts.map +1 -0
- package/dist/core/package-gallery.js +392 -0
- package/dist/core/package-gallery.js.map +1 -0
- package/dist/core/package-manager.d.ts +69 -0
- package/dist/core/package-manager.d.ts.map +1 -1
- package/dist/core/package-manager.js +367 -69
- package/dist/core/package-manager.js.map +1 -1
- package/dist/core/package-procurement.d.ts +268 -0
- package/dist/core/package-procurement.d.ts.map +1 -0
- package/dist/core/package-procurement.js +697 -0
- package/dist/core/package-procurement.js.map +1 -0
- package/dist/core/package-trial-runtime.d.ts +75 -0
- package/dist/core/package-trial-runtime.d.ts.map +1 -0
- package/dist/core/package-trial-runtime.js +73 -0
- package/dist/core/package-trial-runtime.js.map +1 -0
- package/dist/core/package-trial-sandbox.d.ts +27 -0
- package/dist/core/package-trial-sandbox.d.ts.map +1 -0
- package/dist/core/package-trial-sandbox.js +102 -0
- package/dist/core/package-trial-sandbox.js.map +1 -0
- package/dist/core/policy-overlays-runtime.d.ts +141 -0
- package/dist/core/policy-overlays-runtime.d.ts.map +1 -0
- package/dist/core/policy-overlays-runtime.js +720 -0
- package/dist/core/policy-overlays-runtime.js.map +1 -0
- package/dist/core/read-anchor-registry.d.ts +27 -0
- package/dist/core/read-anchor-registry.d.ts.map +1 -0
- package/dist/core/read-anchor-registry.js +103 -0
- package/dist/core/read-anchor-registry.js.map +1 -0
- package/dist/core/read-anchors.d.ts +110 -0
- package/dist/core/read-anchors.d.ts.map +1 -0
- package/dist/core/read-anchors.js +193 -0
- package/dist/core/read-anchors.js.map +1 -0
- package/dist/core/read-content-cache.d.ts +22 -0
- package/dist/core/read-content-cache.d.ts.map +1 -0
- package/dist/core/read-content-cache.js +79 -0
- package/dist/core/read-content-cache.js.map +1 -0
- package/dist/core/recovery-checkpoint.d.ts +196 -0
- package/dist/core/recovery-checkpoint.d.ts.map +1 -0
- package/dist/core/recovery-checkpoint.js +382 -0
- package/dist/core/recovery-checkpoint.js.map +1 -0
- package/dist/core/resolve-config-value.d.ts +1 -1
- package/dist/core/resolve-config-value.d.ts.map +1 -1
- package/dist/core/resolve-config-value.js +30 -2
- package/dist/core/resolve-config-value.js.map +1 -1
- package/dist/core/resource-loader.d.ts +23 -21
- package/dist/core/resource-loader.d.ts.map +1 -1
- package/dist/core/resource-loader.js +93 -15
- package/dist/core/resource-loader.js.map +1 -1
- package/dist/core/sandbox/backend.d.ts +25 -0
- package/dist/core/sandbox/backend.d.ts.map +1 -0
- package/dist/core/sandbox/backend.js +150 -0
- package/dist/core/sandbox/backend.js.map +1 -0
- package/dist/core/sandbox/env.d.ts +6 -0
- package/dist/core/sandbox/env.d.ts.map +1 -0
- package/dist/core/sandbox/env.js +46 -0
- package/dist/core/sandbox/env.js.map +1 -0
- package/dist/core/sandbox/path-resolver.d.ts +4 -0
- package/dist/core/sandbox/path-resolver.d.ts.map +1 -0
- package/dist/core/sandbox/path-resolver.js +44 -0
- package/dist/core/sandbox/path-resolver.js.map +1 -0
- package/dist/core/sandbox/policy.d.ts +87 -0
- package/dist/core/sandbox/policy.d.ts.map +1 -0
- package/dist/core/sandbox/policy.js +280 -0
- package/dist/core/sandbox/policy.js.map +1 -0
- package/dist/core/sandbox/spawn.d.ts +20 -0
- package/dist/core/sandbox/spawn.d.ts.map +1 -0
- package/dist/core/sandbox/spawn.js +80 -0
- package/dist/core/sandbox/spawn.js.map +1 -0
- package/dist/core/sdk.d.ts +83 -4
- package/dist/core/sdk.d.ts.map +1 -1
- package/dist/core/sdk.js +143 -55
- package/dist/core/sdk.js.map +1 -1
- package/dist/core/semantic-cache-policy.d.ts +45 -0
- package/dist/core/semantic-cache-policy.d.ts.map +1 -0
- package/dist/core/semantic-cache-policy.js +220 -0
- package/dist/core/semantic-cache-policy.js.map +1 -0
- package/dist/core/session-digest.d.ts +57 -0
- package/dist/core/session-digest.d.ts.map +1 -0
- package/dist/core/session-digest.js +193 -0
- package/dist/core/session-digest.js.map +1 -0
- package/dist/core/session-manager.d.ts +2 -2
- package/dist/core/session-manager.d.ts.map +1 -1
- package/dist/core/session-manager.js +5 -4
- package/dist/core/session-manager.js.map +1 -1
- package/dist/core/settings-manager.d.ts +14 -0
- package/dist/core/settings-manager.d.ts.map +1 -1
- package/dist/core/settings-manager.js +43 -2
- package/dist/core/settings-manager.js.map +1 -1
- package/dist/core/system-prompt.d.ts.map +1 -1
- package/dist/core/system-prompt.js +25 -7
- package/dist/core/system-prompt.js.map +1 -1
- package/dist/core/telemetry.d.ts.map +1 -1
- package/dist/core/telemetry.js +1 -1
- package/dist/core/telemetry.js.map +1 -1
- package/dist/core/timings.d.ts +1 -1
- package/dist/core/timings.d.ts.map +1 -1
- package/dist/core/timings.js +2 -2
- package/dist/core/timings.js.map +1 -1
- package/dist/core/tools/bash.d.ts +28 -3
- package/dist/core/tools/bash.d.ts.map +1 -1
- package/dist/core/tools/bash.js +53 -10
- package/dist/core/tools/bash.js.map +1 -1
- package/dist/core/tools/edit.d.ts +12 -0
- package/dist/core/tools/edit.d.ts.map +1 -1
- package/dist/core/tools/edit.js +24 -0
- package/dist/core/tools/edit.js.map +1 -1
- package/dist/core/tools/find.d.ts +3 -0
- package/dist/core/tools/find.d.ts.map +1 -1
- package/dist/core/tools/find.js +3 -0
- package/dist/core/tools/find.js.map +1 -1
- package/dist/core/tools/grep.d.ts +3 -0
- package/dist/core/tools/grep.d.ts.map +1 -1
- package/dist/core/tools/grep.js +4 -1
- package/dist/core/tools/grep.js.map +1 -1
- package/dist/core/tools/index.d.ts +1 -1
- package/dist/core/tools/index.d.ts.map +1 -1
- package/dist/core/tools/index.js.map +1 -1
- package/dist/core/tools/ls.d.ts +3 -0
- package/dist/core/tools/ls.d.ts.map +1 -1
- package/dist/core/tools/ls.js +3 -0
- package/dist/core/tools/ls.js.map +1 -1
- package/dist/core/tools/output-accumulator.d.ts.map +1 -1
- package/dist/core/tools/output-accumulator.js +1 -1
- package/dist/core/tools/output-accumulator.js.map +1 -1
- package/dist/core/tools/read.d.ts +13 -0
- package/dist/core/tools/read.d.ts.map +1 -1
- package/dist/core/tools/read.js +29 -2
- package/dist/core/tools/read.js.map +1 -1
- package/dist/core/tools/write.d.ts +3 -0
- package/dist/core/tools/write.d.ts.map +1 -1
- package/dist/core/tools/write.js +3 -0
- package/dist/core/tools/write.js.map +1 -1
- package/dist/index.d.ts +19 -4
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +17 -2
- package/dist/index.js.map +1 -1
- package/dist/main.d.ts.map +1 -1
- package/dist/main.js +4 -6
- package/dist/main.js.map +1 -1
- package/dist/migrations.d.ts.map +1 -1
- package/dist/migrations.js +1 -1
- package/dist/migrations.js.map +1 -1
- package/dist/modes/interactive/components/control-panel-gradient-motion.d.ts +28 -0
- package/dist/modes/interactive/components/control-panel-gradient-motion.d.ts.map +1 -0
- package/dist/modes/interactive/components/control-panel-gradient-motion.js +146 -0
- package/dist/modes/interactive/components/control-panel-gradient-motion.js.map +1 -0
- package/dist/modes/interactive/components/control-panel-gradient.d.ts +27 -0
- package/dist/modes/interactive/components/control-panel-gradient.d.ts.map +1 -0
- package/dist/modes/interactive/components/control-panel-gradient.js +127 -0
- package/dist/modes/interactive/components/control-panel-gradient.js.map +1 -0
- package/dist/modes/interactive/components/control-panel.d.ts +28 -1
- package/dist/modes/interactive/components/control-panel.d.ts.map +1 -1
- package/dist/modes/interactive/components/control-panel.js +153 -3
- package/dist/modes/interactive/components/control-panel.js.map +1 -1
- package/dist/modes/interactive/components/earendil-announcement.d.ts.map +1 -1
- package/dist/modes/interactive/components/earendil-announcement.js +1 -1
- package/dist/modes/interactive/components/earendil-announcement.js.map +1 -1
- package/dist/modes/interactive/components/extension-editor.d.ts.map +1 -1
- package/dist/modes/interactive/components/extension-editor.js +1 -1
- package/dist/modes/interactive/components/extension-editor.js.map +1 -1
- package/dist/modes/interactive/components/footer.d.ts.map +1 -1
- package/dist/modes/interactive/components/footer.js +8 -0
- package/dist/modes/interactive/components/footer.js.map +1 -1
- package/dist/modes/interactive/components/mcp-selector.d.ts +2 -0
- package/dist/modes/interactive/components/mcp-selector.d.ts.map +1 -1
- package/dist/modes/interactive/components/mcp-selector.js +18 -1
- package/dist/modes/interactive/components/mcp-selector.js.map +1 -1
- package/dist/modes/interactive/components/model-selector-state.d.ts +101 -0
- package/dist/modes/interactive/components/model-selector-state.d.ts.map +1 -0
- package/dist/modes/interactive/components/model-selector-state.js +261 -0
- package/dist/modes/interactive/components/model-selector-state.js.map +1 -0
- package/dist/modes/interactive/components/model-selector.d.ts +44 -10
- package/dist/modes/interactive/components/model-selector.d.ts.map +1 -1
- package/dist/modes/interactive/components/model-selector.js +163 -110
- package/dist/modes/interactive/components/model-selector.js.map +1 -1
- package/dist/modes/interactive/components/theme-selector.d.ts +1 -0
- package/dist/modes/interactive/components/theme-selector.d.ts.map +1 -1
- package/dist/modes/interactive/components/theme-selector.js +10 -1
- package/dist/modes/interactive/components/theme-selector.js.map +1 -1
- package/dist/modes/interactive/interactive-mode.d.ts +4 -2
- package/dist/modes/interactive/interactive-mode.d.ts.map +1 -1
- package/dist/modes/interactive/interactive-mode.js +61 -13
- package/dist/modes/interactive/interactive-mode.js.map +1 -1
- package/dist/modes/interactive/theme/omk-blackboard.json +91 -0
- package/dist/modes/interactive/theme/omk-freedom-grid.json +91 -0
- package/dist/modes/interactive/theme/omk-neon-ops.json +90 -0
- package/dist/modes/interactive/theme/omk-slate-light.json +91 -0
- package/dist/modes/interactive/theme/theme.d.ts.map +1 -1
- package/dist/modes/interactive/theme/theme.js +14 -0
- package/dist/modes/interactive/theme/theme.js.map +1 -1
- package/dist/modes/print-mode.d.ts +2 -2
- package/dist/modes/print-mode.d.ts.map +1 -1
- package/dist/modes/print-mode.js +2 -2
- package/dist/modes/print-mode.js.map +1 -1
- package/dist/modes/rpc/rpc-mode.d.ts.map +1 -1
- package/dist/modes/rpc/rpc-mode.js +4 -0
- package/dist/modes/rpc/rpc-mode.js.map +1 -1
- package/dist/package-manager-cli.d.ts.map +1 -1
- package/dist/package-manager-cli.js +114 -49
- package/dist/package-manager-cli.js.map +1 -1
- package/dist/utils/clipboard-image.d.ts.map +1 -1
- package/dist/utils/clipboard-image.js +1 -1
- package/dist/utils/clipboard-image.js.map +1 -1
- package/dist/utils/omk-user-agent.d.ts +2 -0
- package/dist/utils/omk-user-agent.d.ts.map +1 -0
- package/dist/utils/{pi-user-agent.js → omk-user-agent.js} +2 -2
- package/dist/utils/omk-user-agent.js.map +1 -0
- package/dist/utils/tools-manager.d.ts.map +1 -1
- package/dist/utils/tools-manager.js +1 -1
- package/dist/utils/tools-manager.js.map +1 -1
- package/dist/utils/version-check.d.ts +5 -5
- package/dist/utils/version-check.d.ts.map +1 -1
- package/dist/utils/version-check.js +8 -11
- package/dist/utils/version-check.js.map +1 -1
- package/dist/utils/windows-self-update.d.ts.map +1 -1
- package/dist/utils/windows-self-update.js +1 -1
- package/dist/utils/windows-self-update.js.map +1 -1
- package/docs/packages.md +47 -6
- package/docs/prompt-templates.md +2 -0
- package/docs/usage.md +16 -6
- package/examples/README.md +1 -1
- package/examples/extensions/README.md +11 -11
- package/examples/extensions/auto-commit-on-exit.ts +6 -6
- package/examples/extensions/bash-spawn-hook.ts +4 -4
- package/examples/extensions/bookmark.ts +5 -5
- package/examples/extensions/border-status-editor.ts +7 -7
- package/examples/extensions/built-in-tool-renderer.ts +6 -6
- package/examples/extensions/claude-rules.ts +4 -4
- package/examples/extensions/commands.ts +5 -5
- package/examples/extensions/confirm-destructive.ts +3 -3
- package/examples/extensions/custom-compaction.ts +3 -3
- package/examples/extensions/custom-footer.ts +2 -2
- package/examples/extensions/custom-header.ts +5 -5
- package/examples/extensions/custom-provider-anthropic/index.ts +4 -4
- package/examples/extensions/custom-provider-anthropic/package-lock.json +2 -2
- package/examples/extensions/custom-provider-anthropic/package.json +1 -1
- package/examples/extensions/custom-provider-gitlab-duo/index.ts +3 -3
- package/examples/extensions/custom-provider-gitlab-duo/package.json +1 -1
- package/examples/extensions/dirty-repo-guard.ts +7 -7
- package/examples/extensions/doom-overlay/README.md +3 -3
- package/examples/extensions/doom-overlay/doom/build.sh +2 -2
- package/examples/extensions/doom-overlay/doom/doomgeneric_pi.c +1 -1
- package/examples/extensions/doom-overlay/index.ts +3 -3
- package/examples/extensions/dynamic-resources/dynamic.json +1 -1
- package/examples/extensions/dynamic-resources/index.ts +2 -2
- package/examples/extensions/dynamic-tools.ts +4 -4
- package/examples/extensions/event-bus.ts +8 -8
- package/examples/extensions/file-trigger.ts +3 -3
- package/examples/extensions/git-checkpoint.ts +7 -7
- package/examples/extensions/git-merge-and-resolve.ts +14 -14
- package/examples/extensions/github-issue-autocomplete.ts +6 -6
- package/examples/extensions/gondolin/index.ts +16 -16
- package/examples/extensions/gondolin/package-lock.json +2 -2
- package/examples/extensions/gondolin/package.json +1 -1
- package/examples/extensions/handoff.ts +2 -2
- package/examples/extensions/hello.ts +2 -2
- package/examples/extensions/hidden-thinking-label.ts +4 -4
- package/examples/extensions/inline-bash.ts +5 -5
- package/examples/extensions/input-transform-streaming.ts +5 -5
- package/examples/extensions/input-transform.ts +5 -5
- package/examples/extensions/interactive-shell.ts +3 -3
- package/examples/extensions/mac-system-theme.ts +5 -5
- package/examples/extensions/message-renderer.ts +4 -4
- package/examples/extensions/minimal-mode.ts +9 -9
- package/examples/extensions/modal-editor.ts +3 -3
- package/examples/extensions/model-status.ts +3 -3
- package/examples/extensions/notify.ts +5 -5
- package/examples/extensions/overlay-qa-tests.ts +20 -20
- package/examples/extensions/overlay-test.ts +3 -3
- package/examples/extensions/permission-gate.ts +2 -2
- package/examples/extensions/pirate.ts +4 -4
- package/examples/extensions/plan-mode/index.ts +22 -22
- package/examples/extensions/preset.ts +30 -30
- package/examples/extensions/prompt-customizer.ts +3 -3
- package/examples/extensions/protected-paths.ts +2 -2
- package/examples/extensions/provider-payload.ts +5 -5
- package/examples/extensions/qna.ts +2 -2
- package/examples/extensions/question.ts +2 -2
- package/examples/extensions/questionnaire.ts +2 -2
- package/examples/extensions/rainbow-editor.ts +3 -3
- package/examples/extensions/reload-runtime.ts +4 -4
- package/examples/extensions/rpc-demo.ts +10 -10
- package/examples/extensions/sandbox/index.ts +17 -17
- package/examples/extensions/sandbox/package-lock.json +2 -2
- package/examples/extensions/sandbox/package.json +1 -1
- package/examples/extensions/send-user-message.ts +13 -13
- package/examples/extensions/session-name.ts +4 -4
- package/examples/extensions/shutdown-command.ts +10 -10
- package/examples/extensions/snake.ts +3 -3
- package/examples/extensions/space-invaders.ts +3 -3
- package/examples/extensions/ssh.ts +12 -12
- package/examples/extensions/status-line.ts +4 -4
- package/examples/extensions/structured-output.ts +2 -2
- package/examples/extensions/subagent/README.md +13 -13
- package/examples/extensions/subagent/agents.ts +2 -2
- package/examples/extensions/subagent/index.ts +53 -21
- package/examples/extensions/summarize.ts +2 -2
- package/examples/extensions/system-prompt-header.ts +3 -3
- package/examples/extensions/tic-tac-toe.ts +15 -15
- package/examples/extensions/timed-confirm.ts +4 -4
- package/examples/extensions/titlebar-spinner.ts +9 -9
- package/examples/extensions/todo.ts +5 -5
- package/examples/extensions/tool-override.ts +5 -5
- package/examples/extensions/tools.ts +10 -10
- package/examples/extensions/trigger-compact.ts +3 -3
- package/examples/extensions/truncated-tool.ts +3 -3
- package/examples/extensions/widget-placement.ts +2 -2
- package/examples/extensions/with-deps/index.ts +2 -2
- package/examples/extensions/with-deps/package-lock.json +2 -2
- package/examples/extensions/with-deps/package.json +1 -1
- package/examples/extensions/working-indicator.ts +7 -7
- package/examples/extensions/working-message-test.ts +3 -3
- package/examples/sdk/01-minimal.ts +1 -1
- package/examples/sdk/03-custom-prompt.ts +1 -1
- package/examples/sdk/04-skills.ts +1 -1
- package/examples/sdk/05-tools.ts +1 -1
- package/examples/sdk/06-extensions.ts +11 -11
- package/examples/sdk/07-context-files.ts +2 -0
- package/examples/sdk/08-prompt-templates.ts +1 -1
- package/examples/sdk/09-api-keys-and-oauth.ts +2 -2
- package/examples/sdk/README.md +2 -2
- package/node_modules/@earendil-works/omk-agent-core/README.md +488 -0
- package/node_modules/@earendil-works/omk-agent-core/dist/agent-loop.d.ts +24 -0
- package/node_modules/@earendil-works/omk-agent-core/dist/agent-loop.d.ts.map +1 -0
- package/node_modules/@earendil-works/omk-agent-core/dist/agent-loop.js +553 -0
- package/node_modules/@earendil-works/omk-agent-core/dist/agent-loop.js.map +1 -0
- package/node_modules/@earendil-works/omk-agent-core/dist/agent.d.ts +118 -0
- package/node_modules/@earendil-works/omk-agent-core/dist/agent.d.ts.map +1 -0
- package/node_modules/@earendil-works/omk-agent-core/dist/agent.js +402 -0
- package/node_modules/@earendil-works/omk-agent-core/dist/agent.js.map +1 -0
- package/node_modules/@earendil-works/omk-agent-core/dist/harness/agent-harness.d.ts +95 -0
- package/node_modules/@earendil-works/omk-agent-core/dist/harness/agent-harness.d.ts.map +1 -0
- package/node_modules/@earendil-works/omk-agent-core/dist/harness/agent-harness.js +996 -0
- package/node_modules/@earendil-works/omk-agent-core/dist/harness/agent-harness.js.map +1 -0
- package/node_modules/@earendil-works/omk-agent-core/dist/harness/compaction/branch-summarization.d.ts +53 -0
- package/node_modules/@earendil-works/omk-agent-core/dist/harness/compaction/branch-summarization.d.ts.map +1 -0
- package/node_modules/@earendil-works/omk-agent-core/dist/harness/compaction/branch-summarization.js +175 -0
- package/node_modules/@earendil-works/omk-agent-core/dist/harness/compaction/branch-summarization.js.map +1 -0
- package/node_modules/@earendil-works/omk-agent-core/dist/harness/compaction/compaction.d.ts +117 -0
- package/node_modules/@earendil-works/omk-agent-core/dist/harness/compaction/compaction.d.ts.map +1 -0
- package/node_modules/@earendil-works/omk-agent-core/dist/harness/compaction/compaction.js +568 -0
- package/node_modules/@earendil-works/omk-agent-core/dist/harness/compaction/compaction.js.map +1 -0
- package/node_modules/@earendil-works/omk-agent-core/dist/harness/compaction/utils.d.ts +25 -0
- package/node_modules/@earendil-works/omk-agent-core/dist/harness/compaction/utils.d.ts.map +1 -0
- package/node_modules/@earendil-works/omk-agent-core/dist/harness/compaction/utils.js +131 -0
- package/node_modules/@earendil-works/omk-agent-core/dist/harness/compaction/utils.js.map +1 -0
- package/node_modules/@earendil-works/omk-agent-core/dist/harness/env/nodejs.d.ts +51 -0
- package/node_modules/@earendil-works/omk-agent-core/dist/harness/env/nodejs.d.ts.map +1 -0
- package/node_modules/@earendil-works/omk-agent-core/dist/harness/env/nodejs.js +510 -0
- package/node_modules/@earendil-works/omk-agent-core/dist/harness/env/nodejs.js.map +1 -0
- package/node_modules/@earendil-works/omk-agent-core/dist/harness/messages.d.ts +51 -0
- package/node_modules/@earendil-works/omk-agent-core/dist/harness/messages.d.ts.map +1 -0
- package/node_modules/@earendil-works/omk-agent-core/dist/harness/messages.js +102 -0
- package/node_modules/@earendil-works/omk-agent-core/dist/harness/messages.js.map +1 -0
- package/node_modules/@earendil-works/omk-agent-core/dist/harness/prompt-templates.d.ts +48 -0
- package/node_modules/@earendil-works/omk-agent-core/dist/harness/prompt-templates.d.ts.map +1 -0
- package/node_modules/@earendil-works/omk-agent-core/dist/harness/prompt-templates.js +230 -0
- package/node_modules/@earendil-works/omk-agent-core/dist/harness/prompt-templates.js.map +1 -0
- package/node_modules/@earendil-works/omk-agent-core/dist/harness/session/jsonl-repo.d.ts +26 -0
- package/node_modules/@earendil-works/omk-agent-core/dist/harness/session/jsonl-repo.d.ts.map +1 -0
- package/node_modules/@earendil-works/omk-agent-core/dist/harness/session/jsonl-repo.js +101 -0
- package/node_modules/@earendil-works/omk-agent-core/dist/harness/session/jsonl-repo.js.map +1 -0
- package/node_modules/@earendil-works/omk-agent-core/dist/harness/session/jsonl-storage.d.ts +36 -0
- package/node_modules/@earendil-works/omk-agent-core/dist/harness/session/jsonl-storage.d.ts.map +1 -0
- package/node_modules/@earendil-works/omk-agent-core/dist/harness/session/jsonl-storage.js +273 -0
- package/node_modules/@earendil-works/omk-agent-core/dist/harness/session/jsonl-storage.js.map +1 -0
- package/node_modules/@earendil-works/omk-agent-core/dist/harness/session/memory-repo.d.ts +18 -0
- package/node_modules/@earendil-works/omk-agent-core/dist/harness/session/memory-repo.d.ts.map +1 -0
- package/node_modules/@earendil-works/omk-agent-core/dist/harness/session/memory-repo.js +42 -0
- package/node_modules/@earendil-works/omk-agent-core/dist/harness/session/memory-repo.js.map +1 -0
- package/node_modules/@earendil-works/omk-agent-core/dist/harness/session/memory-storage.d.ts +25 -0
- package/node_modules/@earendil-works/omk-agent-core/dist/harness/session/memory-storage.d.ts.map +1 -0
- package/node_modules/@earendil-works/omk-agent-core/dist/harness/session/memory-storage.js +114 -0
- package/node_modules/@earendil-works/omk-agent-core/dist/harness/session/memory-storage.js.map +1 -0
- package/node_modules/@earendil-works/omk-agent-core/dist/harness/session/repo-utils.d.ts +11 -0
- package/node_modules/@earendil-works/omk-agent-core/dist/harness/session/repo-utils.d.ts.map +1 -0
- package/node_modules/@earendil-works/omk-agent-core/dist/harness/session/repo-utils.js +39 -0
- package/node_modules/@earendil-works/omk-agent-core/dist/harness/session/repo-utils.js.map +1 -0
- package/node_modules/@earendil-works/omk-agent-core/dist/harness/session/session.d.ts +33 -0
- package/node_modules/@earendil-works/omk-agent-core/dist/harness/session/session.d.ts.map +1 -0
- package/node_modules/@earendil-works/omk-agent-core/dist/harness/session/session.js +210 -0
- package/node_modules/@earendil-works/omk-agent-core/dist/harness/session/session.js.map +1 -0
- package/node_modules/@earendil-works/omk-agent-core/dist/harness/session/uuid.d.ts +2 -0
- package/node_modules/@earendil-works/omk-agent-core/dist/harness/session/uuid.d.ts.map +1 -0
- package/node_modules/@earendil-works/omk-agent-core/dist/harness/session/uuid.js +50 -0
- package/node_modules/@earendil-works/omk-agent-core/dist/harness/session/uuid.js.map +1 -0
- package/node_modules/@earendil-works/omk-agent-core/dist/harness/skills.d.ts +44 -0
- package/node_modules/@earendil-works/omk-agent-core/dist/harness/skills.d.ts.map +1 -0
- package/node_modules/@earendil-works/omk-agent-core/dist/harness/skills.js +311 -0
- package/node_modules/@earendil-works/omk-agent-core/dist/harness/skills.js.map +1 -0
- package/node_modules/@earendil-works/omk-agent-core/dist/harness/system-prompt.d.ts +3 -0
- package/node_modules/@earendil-works/omk-agent-core/dist/harness/system-prompt.d.ts.map +1 -0
- package/node_modules/@earendil-works/omk-agent-core/dist/harness/system-prompt.js +30 -0
- package/node_modules/@earendil-works/omk-agent-core/dist/harness/system-prompt.js.map +1 -0
- package/node_modules/@earendil-works/omk-agent-core/dist/harness/types.d.ts +616 -0
- package/node_modules/@earendil-works/omk-agent-core/dist/harness/types.d.ts.map +1 -0
- package/node_modules/@earendil-works/omk-agent-core/dist/harness/types.js +94 -0
- package/node_modules/@earendil-works/omk-agent-core/dist/harness/types.js.map +1 -0
- package/node_modules/@earendil-works/omk-agent-core/dist/harness/utils/shell-output.d.ts +14 -0
- package/node_modules/@earendil-works/omk-agent-core/dist/harness/utils/shell-output.d.ts.map +1 -0
- package/node_modules/@earendil-works/omk-agent-core/dist/harness/utils/shell-output.js +126 -0
- package/node_modules/@earendil-works/omk-agent-core/dist/harness/utils/shell-output.js.map +1 -0
- package/node_modules/@earendil-works/omk-agent-core/dist/harness/utils/truncate.d.ts +70 -0
- package/node_modules/@earendil-works/omk-agent-core/dist/harness/utils/truncate.d.ts.map +1 -0
- package/node_modules/@earendil-works/omk-agent-core/dist/harness/utils/truncate.js +297 -0
- package/node_modules/@earendil-works/omk-agent-core/dist/harness/utils/truncate.js.map +1 -0
- package/node_modules/@earendil-works/omk-agent-core/dist/index.d.ts +20 -0
- package/node_modules/@earendil-works/omk-agent-core/dist/index.d.ts.map +1 -0
- package/node_modules/@earendil-works/omk-agent-core/dist/index.js +25 -0
- package/node_modules/@earendil-works/omk-agent-core/dist/index.js.map +1 -0
- package/node_modules/@earendil-works/omk-agent-core/dist/node.d.ts +3 -0
- package/node_modules/@earendil-works/omk-agent-core/dist/node.d.ts.map +1 -0
- package/node_modules/@earendil-works/omk-agent-core/dist/node.js +3 -0
- package/node_modules/@earendil-works/omk-agent-core/dist/node.js.map +1 -0
- package/node_modules/@earendil-works/omk-agent-core/dist/proxy.d.ts +69 -0
- package/node_modules/@earendil-works/omk-agent-core/dist/proxy.d.ts.map +1 -0
- package/node_modules/@earendil-works/omk-agent-core/dist/proxy.js +278 -0
- package/node_modules/@earendil-works/omk-agent-core/dist/proxy.js.map +1 -0
- package/node_modules/@earendil-works/omk-agent-core/dist/types.d.ts +393 -0
- package/node_modules/@earendil-works/omk-agent-core/dist/types.d.ts.map +1 -0
- package/node_modules/@earendil-works/omk-agent-core/dist/types.js +2 -0
- package/node_modules/@earendil-works/omk-agent-core/dist/types.js.map +1 -0
- package/node_modules/@earendil-works/omk-agent-core/package.json +60 -0
- package/node_modules/@earendil-works/omk-ai/README.md +1389 -0
- package/node_modules/@earendil-works/omk-ai/dist/api-registry.d.ts +20 -0
- package/node_modules/@earendil-works/omk-ai/dist/api-registry.d.ts.map +1 -0
- package/node_modules/@earendil-works/omk-ai/dist/api-registry.js +44 -0
- package/node_modules/@earendil-works/omk-ai/dist/api-registry.js.map +1 -0
- package/node_modules/@earendil-works/omk-ai/dist/bedrock-provider.d.ts +5 -0
- package/node_modules/@earendil-works/omk-ai/dist/bedrock-provider.d.ts.map +1 -0
- package/node_modules/@earendil-works/omk-ai/dist/bedrock-provider.js +6 -0
- package/node_modules/@earendil-works/omk-ai/dist/bedrock-provider.js.map +1 -0
- package/node_modules/@earendil-works/omk-ai/dist/cli.d.ts +3 -0
- package/node_modules/@earendil-works/omk-ai/dist/cli.d.ts.map +1 -0
- package/node_modules/@earendil-works/omk-ai/dist/cli.js +130 -0
- package/node_modules/@earendil-works/omk-ai/dist/cli.js.map +1 -0
- package/node_modules/@earendil-works/omk-ai/dist/env-api-keys.d.ts +20 -0
- package/node_modules/@earendil-works/omk-ai/dist/env-api-keys.d.ts.map +1 -0
- package/node_modules/@earendil-works/omk-ai/dist/env-api-keys.js +199 -0
- package/node_modules/@earendil-works/omk-ai/dist/env-api-keys.js.map +1 -0
- package/node_modules/@earendil-works/omk-ai/dist/image-models.d.ts +10 -0
- package/node_modules/@earendil-works/omk-ai/dist/image-models.d.ts.map +1 -0
- package/node_modules/@earendil-works/omk-ai/dist/image-models.generated.d.ts +515 -0
- package/node_modules/@earendil-works/omk-ai/dist/image-models.generated.d.ts.map +1 -0
- package/node_modules/@earendil-works/omk-ai/dist/image-models.generated.js +517 -0
- package/node_modules/@earendil-works/omk-ai/dist/image-models.generated.js.map +1 -0
- package/node_modules/@earendil-works/omk-ai/dist/image-models.js +23 -0
- package/node_modules/@earendil-works/omk-ai/dist/image-models.js.map +1 -0
- package/node_modules/@earendil-works/omk-ai/dist/images-api-registry.d.ts +14 -0
- package/node_modules/@earendil-works/omk-ai/dist/images-api-registry.d.ts.map +1 -0
- package/node_modules/@earendil-works/omk-ai/dist/images-api-registry.js +22 -0
- package/node_modules/@earendil-works/omk-ai/dist/images-api-registry.js.map +1 -0
- package/node_modules/@earendil-works/omk-ai/dist/images.d.ts +4 -0
- package/node_modules/@earendil-works/omk-ai/dist/images.d.ts.map +1 -0
- package/node_modules/@earendil-works/omk-ai/dist/images.js +16 -0
- package/node_modules/@earendil-works/omk-ai/dist/images.js.map +1 -0
- package/node_modules/@earendil-works/omk-ai/dist/index.d.ts +33 -0
- package/node_modules/@earendil-works/omk-ai/dist/index.d.ts.map +1 -0
- package/node_modules/@earendil-works/omk-ai/dist/index.js +21 -0
- package/node_modules/@earendil-works/omk-ai/dist/index.js.map +1 -0
- package/node_modules/@earendil-works/omk-ai/dist/models.d.ts +18 -0
- package/node_modules/@earendil-works/omk-ai/dist/models.d.ts.map +1 -0
- package/node_modules/@earendil-works/omk-ai/dist/models.generated.d.ts +18762 -0
- package/node_modules/@earendil-works/omk-ai/dist/models.generated.d.ts.map +1 -0
- package/node_modules/@earendil-works/omk-ai/dist/models.generated.js +17197 -0
- package/node_modules/@earendil-works/omk-ai/dist/models.generated.js.map +1 -0
- package/node_modules/@earendil-works/omk-ai/dist/models.js +78 -0
- package/node_modules/@earendil-works/omk-ai/dist/models.js.map +1 -0
- package/node_modules/@earendil-works/omk-ai/dist/oauth.d.ts +2 -0
- package/node_modules/@earendil-works/omk-ai/dist/oauth.d.ts.map +1 -0
- package/node_modules/@earendil-works/omk-ai/dist/oauth.js +2 -0
- package/node_modules/@earendil-works/omk-ai/dist/oauth.js.map +1 -0
- package/node_modules/@earendil-works/omk-ai/dist/provider-network.d.ts +39 -0
- package/node_modules/@earendil-works/omk-ai/dist/provider-network.d.ts.map +1 -0
- package/node_modules/@earendil-works/omk-ai/dist/provider-network.js +170 -0
- package/node_modules/@earendil-works/omk-ai/dist/provider-network.js.map +1 -0
- package/node_modules/@earendil-works/omk-ai/dist/providers/amazon-bedrock.d.ts +38 -0
- package/node_modules/@earendil-works/omk-ai/dist/providers/amazon-bedrock.d.ts.map +1 -0
- package/node_modules/@earendil-works/omk-ai/dist/providers/amazon-bedrock.js +826 -0
- package/node_modules/@earendil-works/omk-ai/dist/providers/amazon-bedrock.js.map +1 -0
- package/node_modules/@earendil-works/omk-ai/dist/providers/anthropic.d.ts +77 -0
- package/node_modules/@earendil-works/omk-ai/dist/providers/anthropic.d.ts.map +1 -0
- package/node_modules/@earendil-works/omk-ai/dist/providers/anthropic.js +1123 -0
- package/node_modules/@earendil-works/omk-ai/dist/providers/anthropic.js.map +1 -0
- package/node_modules/@earendil-works/omk-ai/dist/providers/azure-openai-responses.d.ts +15 -0
- package/node_modules/@earendil-works/omk-ai/dist/providers/azure-openai-responses.d.ts.map +1 -0
- package/node_modules/@earendil-works/omk-ai/dist/providers/azure-openai-responses.js +221 -0
- package/node_modules/@earendil-works/omk-ai/dist/providers/azure-openai-responses.js.map +1 -0
- package/node_modules/@earendil-works/omk-ai/dist/providers/cloudflare.d.ts +13 -0
- package/node_modules/@earendil-works/omk-ai/dist/providers/cloudflare.d.ts.map +1 -0
- package/node_modules/@earendil-works/omk-ai/dist/providers/cloudflare.js +26 -0
- package/node_modules/@earendil-works/omk-ai/dist/providers/cloudflare.js.map +1 -0
- package/node_modules/@earendil-works/omk-ai/dist/providers/faux.d.ts +56 -0
- package/node_modules/@earendil-works/omk-ai/dist/providers/faux.d.ts.map +1 -0
- package/node_modules/@earendil-works/omk-ai/dist/providers/faux.js +368 -0
- package/node_modules/@earendil-works/omk-ai/dist/providers/faux.js.map +1 -0
- package/node_modules/@earendil-works/omk-ai/dist/providers/github-copilot-headers.d.ts +8 -0
- package/node_modules/@earendil-works/omk-ai/dist/providers/github-copilot-headers.d.ts.map +1 -0
- package/node_modules/@earendil-works/omk-ai/dist/providers/github-copilot-headers.js +29 -0
- package/node_modules/@earendil-works/omk-ai/dist/providers/github-copilot-headers.js.map +1 -0
- package/node_modules/@earendil-works/omk-ai/dist/providers/google-shared.d.ts +70 -0
- package/node_modules/@earendil-works/omk-ai/dist/providers/google-shared.d.ts.map +1 -0
- package/node_modules/@earendil-works/omk-ai/dist/providers/google-shared.js +331 -0
- package/node_modules/@earendil-works/omk-ai/dist/providers/google-shared.js.map +1 -0
- package/node_modules/@earendil-works/omk-ai/dist/providers/google-vertex.d.ts +15 -0
- package/node_modules/@earendil-works/omk-ai/dist/providers/google-vertex.d.ts.map +1 -0
- package/node_modules/@earendil-works/omk-ai/dist/providers/google-vertex.js +442 -0
- package/node_modules/@earendil-works/omk-ai/dist/providers/google-vertex.js.map +1 -0
- package/node_modules/@earendil-works/omk-ai/dist/providers/google.d.ts +13 -0
- package/node_modules/@earendil-works/omk-ai/dist/providers/google.d.ts.map +1 -0
- package/node_modules/@earendil-works/omk-ai/dist/providers/google.js +402 -0
- package/node_modules/@earendil-works/omk-ai/dist/providers/google.js.map +1 -0
- package/node_modules/@earendil-works/omk-ai/dist/providers/images/openrouter.d.ts +3 -0
- package/node_modules/@earendil-works/omk-ai/dist/providers/images/openrouter.d.ts.map +1 -0
- package/node_modules/@earendil-works/omk-ai/dist/providers/images/openrouter.js +128 -0
- package/node_modules/@earendil-works/omk-ai/dist/providers/images/openrouter.js.map +1 -0
- package/node_modules/@earendil-works/omk-ai/dist/providers/images/register-builtins.d.ts +4 -0
- package/node_modules/@earendil-works/omk-ai/dist/providers/images/register-builtins.d.ts.map +1 -0
- package/node_modules/@earendil-works/omk-ai/dist/providers/images/register-builtins.js +34 -0
- package/node_modules/@earendil-works/omk-ai/dist/providers/images/register-builtins.js.map +1 -0
- package/node_modules/@earendil-works/omk-ai/dist/providers/mistral.d.ts +25 -0
- package/node_modules/@earendil-works/omk-ai/dist/providers/mistral.d.ts.map +1 -0
- package/node_modules/@earendil-works/omk-ai/dist/providers/mistral.js +534 -0
- package/node_modules/@earendil-works/omk-ai/dist/providers/mistral.js.map +1 -0
- package/node_modules/@earendil-works/omk-ai/dist/providers/openai-codex-responses.d.ts +30 -0
- package/node_modules/@earendil-works/omk-ai/dist/providers/openai-codex-responses.d.ts.map +1 -0
- package/node_modules/@earendil-works/omk-ai/dist/providers/openai-codex-responses.js +1171 -0
- package/node_modules/@earendil-works/omk-ai/dist/providers/openai-codex-responses.js.map +1 -0
- package/node_modules/@earendil-works/omk-ai/dist/providers/openai-completions.d.ts +19 -0
- package/node_modules/@earendil-works/omk-ai/dist/providers/openai-completions.d.ts.map +1 -0
- package/node_modules/@earendil-works/omk-ai/dist/providers/openai-completions.js +977 -0
- package/node_modules/@earendil-works/omk-ai/dist/providers/openai-completions.js.map +1 -0
- package/node_modules/@earendil-works/omk-ai/dist/providers/openai-prompt-cache.d.ts +11 -0
- package/node_modules/@earendil-works/omk-ai/dist/providers/openai-prompt-cache.d.ts.map +1 -0
- package/node_modules/@earendil-works/omk-ai/dist/providers/openai-prompt-cache.js +22 -0
- package/node_modules/@earendil-works/omk-ai/dist/providers/openai-prompt-cache.js.map +1 -0
- package/node_modules/@earendil-works/omk-ai/dist/providers/openai-responses-shared.d.ts +18 -0
- package/node_modules/@earendil-works/omk-ai/dist/providers/openai-responses-shared.d.ts.map +1 -0
- package/node_modules/@earendil-works/omk-ai/dist/providers/openai-responses-shared.js +496 -0
- package/node_modules/@earendil-works/omk-ai/dist/providers/openai-responses-shared.js.map +1 -0
- package/node_modules/@earendil-works/omk-ai/dist/providers/openai-responses.d.ts +13 -0
- package/node_modules/@earendil-works/omk-ai/dist/providers/openai-responses.d.ts.map +1 -0
- package/node_modules/@earendil-works/omk-ai/dist/providers/openai-responses.js +233 -0
- package/node_modules/@earendil-works/omk-ai/dist/providers/openai-responses.js.map +1 -0
- package/node_modules/@earendil-works/omk-ai/dist/providers/register-builtins.d.ts +35 -0
- package/node_modules/@earendil-works/omk-ai/dist/providers/register-builtins.d.ts.map +1 -0
- package/node_modules/@earendil-works/omk-ai/dist/providers/register-builtins.js +254 -0
- package/node_modules/@earendil-works/omk-ai/dist/providers/register-builtins.js.map +1 -0
- package/node_modules/@earendil-works/omk-ai/dist/providers/simple-options.d.ts +8 -0
- package/node_modules/@earendil-works/omk-ai/dist/providers/simple-options.d.ts.map +1 -0
- package/node_modules/@earendil-works/omk-ai/dist/providers/simple-options.js +42 -0
- package/node_modules/@earendil-works/omk-ai/dist/providers/simple-options.js.map +1 -0
- package/node_modules/@earendil-works/omk-ai/dist/providers/tool-schema.d.ts +13 -0
- package/node_modules/@earendil-works/omk-ai/dist/providers/tool-schema.d.ts.map +1 -0
- package/node_modules/@earendil-works/omk-ai/dist/providers/tool-schema.js +82 -0
- package/node_modules/@earendil-works/omk-ai/dist/providers/tool-schema.js.map +1 -0
- package/node_modules/@earendil-works/omk-ai/dist/providers/transform-messages.d.ts +8 -0
- package/node_modules/@earendil-works/omk-ai/dist/providers/transform-messages.d.ts.map +1 -0
- package/node_modules/@earendil-works/omk-ai/dist/providers/transform-messages.js +184 -0
- package/node_modules/@earendil-works/omk-ai/dist/providers/transform-messages.js.map +1 -0
- package/node_modules/@earendil-works/omk-ai/dist/session-resources.d.ts +4 -0
- package/node_modules/@earendil-works/omk-ai/dist/session-resources.d.ts.map +1 -0
- package/node_modules/@earendil-works/omk-ai/dist/session-resources.js +22 -0
- package/node_modules/@earendil-works/omk-ai/dist/session-resources.js.map +1 -0
- package/node_modules/@earendil-works/omk-ai/dist/stream.d.ts +8 -0
- package/node_modules/@earendil-works/omk-ai/dist/stream.d.ts.map +1 -0
- package/node_modules/@earendil-works/omk-ai/dist/stream.js +77 -0
- package/node_modules/@earendil-works/omk-ai/dist/stream.js.map +1 -0
- package/node_modules/@earendil-works/omk-ai/dist/types.d.ts +570 -0
- package/node_modules/@earendil-works/omk-ai/dist/types.d.ts.map +1 -0
- package/node_modules/@earendil-works/omk-ai/dist/types.js +2 -0
- package/node_modules/@earendil-works/omk-ai/dist/types.js.map +1 -0
- package/node_modules/@earendil-works/omk-ai/dist/utils/abort-signals.d.ts +6 -0
- package/node_modules/@earendil-works/omk-ai/dist/utils/abort-signals.d.ts.map +1 -0
- package/node_modules/@earendil-works/omk-ai/dist/utils/abort-signals.js +34 -0
- package/node_modules/@earendil-works/omk-ai/dist/utils/abort-signals.js.map +1 -0
- package/node_modules/@earendil-works/omk-ai/dist/utils/diagnostics.d.ts +19 -0
- package/node_modules/@earendil-works/omk-ai/dist/utils/diagnostics.d.ts.map +1 -0
- package/node_modules/@earendil-works/omk-ai/dist/utils/diagnostics.js +25 -0
- package/node_modules/@earendil-works/omk-ai/dist/utils/diagnostics.js.map +1 -0
- package/node_modules/@earendil-works/omk-ai/dist/utils/event-stream.d.ts +21 -0
- package/node_modules/@earendil-works/omk-ai/dist/utils/event-stream.d.ts.map +1 -0
- package/node_modules/@earendil-works/omk-ai/dist/utils/event-stream.js +81 -0
- package/node_modules/@earendil-works/omk-ai/dist/utils/event-stream.js.map +1 -0
- package/node_modules/@earendil-works/omk-ai/dist/utils/hash.d.ts +3 -0
- package/node_modules/@earendil-works/omk-ai/dist/utils/hash.d.ts.map +1 -0
- package/node_modules/@earendil-works/omk-ai/dist/utils/hash.js +14 -0
- package/node_modules/@earendil-works/omk-ai/dist/utils/hash.js.map +1 -0
- package/node_modules/@earendil-works/omk-ai/dist/utils/headers.d.ts +2 -0
- package/node_modules/@earendil-works/omk-ai/dist/utils/headers.d.ts.map +1 -0
- package/node_modules/@earendil-works/omk-ai/dist/utils/headers.js +8 -0
- package/node_modules/@earendil-works/omk-ai/dist/utils/headers.js.map +1 -0
- package/node_modules/@earendil-works/omk-ai/dist/utils/json-parse.d.ts +16 -0
- package/node_modules/@earendil-works/omk-ai/dist/utils/json-parse.d.ts.map +1 -0
- package/node_modules/@earendil-works/omk-ai/dist/utils/json-parse.js +113 -0
- package/node_modules/@earendil-works/omk-ai/dist/utils/json-parse.js.map +1 -0
- package/node_modules/@earendil-works/omk-ai/dist/utils/node-http-proxy.d.ts +10 -0
- package/node_modules/@earendil-works/omk-ai/dist/utils/node-http-proxy.d.ts.map +1 -0
- package/node_modules/@earendil-works/omk-ai/dist/utils/node-http-proxy.js +97 -0
- package/node_modules/@earendil-works/omk-ai/dist/utils/node-http-proxy.js.map +1 -0
- package/node_modules/@earendil-works/omk-ai/dist/utils/oauth/anthropic.d.ts +25 -0
- package/node_modules/@earendil-works/omk-ai/dist/utils/oauth/anthropic.d.ts.map +1 -0
- package/node_modules/@earendil-works/omk-ai/dist/utils/oauth/anthropic.js +335 -0
- package/node_modules/@earendil-works/omk-ai/dist/utils/oauth/anthropic.js.map +1 -0
- package/node_modules/@earendil-works/omk-ai/dist/utils/oauth/device-code.d.ts +21 -0
- package/node_modules/@earendil-works/omk-ai/dist/utils/oauth/device-code.d.ts.map +1 -0
- package/node_modules/@earendil-works/omk-ai/dist/utils/oauth/device-code.js +56 -0
- package/node_modules/@earendil-works/omk-ai/dist/utils/oauth/device-code.js.map +1 -0
- package/node_modules/@earendil-works/omk-ai/dist/utils/oauth/github-copilot.d.ts +30 -0
- package/node_modules/@earendil-works/omk-ai/dist/utils/oauth/github-copilot.d.ts.map +1 -0
- package/node_modules/@earendil-works/omk-ai/dist/utils/oauth/github-copilot.js +280 -0
- package/node_modules/@earendil-works/omk-ai/dist/utils/oauth/github-copilot.js.map +1 -0
- package/node_modules/@earendil-works/omk-ai/dist/utils/oauth/index.d.ts +58 -0
- package/node_modules/@earendil-works/omk-ai/dist/utils/oauth/index.d.ts.map +1 -0
- package/node_modules/@earendil-works/omk-ai/dist/utils/oauth/index.js +122 -0
- package/node_modules/@earendil-works/omk-ai/dist/utils/oauth/index.js.map +1 -0
- package/node_modules/@earendil-works/omk-ai/dist/utils/oauth/oauth-page.d.ts +3 -0
- package/node_modules/@earendil-works/omk-ai/dist/utils/oauth/oauth-page.d.ts.map +1 -0
- package/node_modules/@earendil-works/omk-ai/dist/utils/oauth/oauth-page.js +105 -0
- package/node_modules/@earendil-works/omk-ai/dist/utils/oauth/oauth-page.js.map +1 -0
- package/node_modules/@earendil-works/omk-ai/dist/utils/oauth/openai-codex.d.ts +43 -0
- package/node_modules/@earendil-works/omk-ai/dist/utils/oauth/openai-codex.d.ts.map +1 -0
- package/node_modules/@earendil-works/omk-ai/dist/utils/oauth/openai-codex.js +487 -0
- package/node_modules/@earendil-works/omk-ai/dist/utils/oauth/openai-codex.js.map +1 -0
- package/node_modules/@earendil-works/omk-ai/dist/utils/oauth/pkce.d.ts +13 -0
- package/node_modules/@earendil-works/omk-ai/dist/utils/oauth/pkce.d.ts.map +1 -0
- package/node_modules/@earendil-works/omk-ai/dist/utils/oauth/pkce.js +31 -0
- package/node_modules/@earendil-works/omk-ai/dist/utils/oauth/pkce.js.map +1 -0
- package/node_modules/@earendil-works/omk-ai/dist/utils/oauth/types.d.ts +64 -0
- package/node_modules/@earendil-works/omk-ai/dist/utils/oauth/types.d.ts.map +1 -0
- package/node_modules/@earendil-works/omk-ai/dist/utils/oauth/types.js +2 -0
- package/node_modules/@earendil-works/omk-ai/dist/utils/oauth/types.js.map +1 -0
- package/node_modules/@earendil-works/omk-ai/dist/utils/overflow.d.ts +57 -0
- package/node_modules/@earendil-works/omk-ai/dist/utils/overflow.d.ts.map +1 -0
- package/node_modules/@earendil-works/omk-ai/dist/utils/overflow.js +154 -0
- package/node_modules/@earendil-works/omk-ai/dist/utils/overflow.js.map +1 -0
- package/node_modules/@earendil-works/omk-ai/dist/utils/sanitize-unicode.d.ts +22 -0
- package/node_modules/@earendil-works/omk-ai/dist/utils/sanitize-unicode.d.ts.map +1 -0
- package/node_modules/@earendil-works/omk-ai/dist/utils/sanitize-unicode.js +26 -0
- package/node_modules/@earendil-works/omk-ai/dist/utils/sanitize-unicode.js.map +1 -0
- package/node_modules/@earendil-works/omk-ai/dist/utils/typebox-helpers.d.ts +17 -0
- package/node_modules/@earendil-works/omk-ai/dist/utils/typebox-helpers.d.ts.map +1 -0
- package/node_modules/@earendil-works/omk-ai/dist/utils/typebox-helpers.js +21 -0
- package/node_modules/@earendil-works/omk-ai/dist/utils/typebox-helpers.js.map +1 -0
- package/node_modules/@earendil-works/omk-ai/dist/utils/validation.d.ts +18 -0
- package/node_modules/@earendil-works/omk-ai/dist/utils/validation.d.ts.map +1 -0
- package/node_modules/@earendil-works/omk-ai/dist/utils/validation.js +281 -0
- package/node_modules/@earendil-works/omk-ai/dist/utils/validation.js.map +1 -0
- package/node_modules/@earendil-works/omk-ai/package.json +106 -0
- package/node_modules/@earendil-works/omk-tui/README.md +791 -0
- package/node_modules/@earendil-works/omk-tui/dist/autocomplete.d.ts +54 -0
- package/node_modules/@earendil-works/omk-tui/dist/autocomplete.d.ts.map +1 -0
- package/node_modules/@earendil-works/omk-tui/dist/autocomplete.js +632 -0
- package/node_modules/@earendil-works/omk-tui/dist/autocomplete.js.map +1 -0
- package/node_modules/@earendil-works/omk-tui/dist/components/box.d.ts +22 -0
- package/node_modules/@earendil-works/omk-tui/dist/components/box.d.ts.map +1 -0
- package/node_modules/@earendil-works/omk-tui/dist/components/box.js +104 -0
- package/node_modules/@earendil-works/omk-tui/dist/components/box.js.map +1 -0
- package/node_modules/@earendil-works/omk-tui/dist/components/cancellable-loader.d.ts +22 -0
- package/node_modules/@earendil-works/omk-tui/dist/components/cancellable-loader.d.ts.map +1 -0
- package/node_modules/@earendil-works/omk-tui/dist/components/cancellable-loader.js +35 -0
- package/node_modules/@earendil-works/omk-tui/dist/components/cancellable-loader.js.map +1 -0
- package/node_modules/@earendil-works/omk-tui/dist/components/editor.d.ts +249 -0
- package/node_modules/@earendil-works/omk-tui/dist/components/editor.d.ts.map +1 -0
- package/node_modules/@earendil-works/omk-tui/dist/components/editor.js +1857 -0
- package/node_modules/@earendil-works/omk-tui/dist/components/editor.js.map +1 -0
- package/node_modules/@earendil-works/omk-tui/dist/components/image.d.ts +28 -0
- package/node_modules/@earendil-works/omk-tui/dist/components/image.d.ts.map +1 -0
- package/node_modules/@earendil-works/omk-tui/dist/components/image.js +89 -0
- package/node_modules/@earendil-works/omk-tui/dist/components/image.js.map +1 -0
- package/node_modules/@earendil-works/omk-tui/dist/components/input.d.ts +37 -0
- package/node_modules/@earendil-works/omk-tui/dist/components/input.d.ts.map +1 -0
- package/node_modules/@earendil-works/omk-tui/dist/components/input.js +378 -0
- package/node_modules/@earendil-works/omk-tui/dist/components/input.js.map +1 -0
- package/node_modules/@earendil-works/omk-tui/dist/components/loader.d.ts +31 -0
- package/node_modules/@earendil-works/omk-tui/dist/components/loader.d.ts.map +1 -0
- package/node_modules/@earendil-works/omk-tui/dist/components/loader.js +69 -0
- package/node_modules/@earendil-works/omk-tui/dist/components/loader.js.map +1 -0
- package/node_modules/@earendil-works/omk-tui/dist/components/markdown.d.ts +96 -0
- package/node_modules/@earendil-works/omk-tui/dist/components/markdown.d.ts.map +1 -0
- package/node_modules/@earendil-works/omk-tui/dist/components/markdown.js +644 -0
- package/node_modules/@earendil-works/omk-tui/dist/components/markdown.js.map +1 -0
- package/node_modules/@earendil-works/omk-tui/dist/components/select-list.d.ts +50 -0
- package/node_modules/@earendil-works/omk-tui/dist/components/select-list.d.ts.map +1 -0
- package/node_modules/@earendil-works/omk-tui/dist/components/select-list.js +159 -0
- package/node_modules/@earendil-works/omk-tui/dist/components/select-list.js.map +1 -0
- package/node_modules/@earendil-works/omk-tui/dist/components/settings-list.d.ts +50 -0
- package/node_modules/@earendil-works/omk-tui/dist/components/settings-list.d.ts.map +1 -0
- package/node_modules/@earendil-works/omk-tui/dist/components/settings-list.js +185 -0
- package/node_modules/@earendil-works/omk-tui/dist/components/settings-list.js.map +1 -0
- package/node_modules/@earendil-works/omk-tui/dist/components/spacer.d.ts +12 -0
- package/node_modules/@earendil-works/omk-tui/dist/components/spacer.d.ts.map +1 -0
- package/node_modules/@earendil-works/omk-tui/dist/components/spacer.js +23 -0
- package/node_modules/@earendil-works/omk-tui/dist/components/spacer.js.map +1 -0
- package/node_modules/@earendil-works/omk-tui/dist/components/text.d.ts +19 -0
- package/node_modules/@earendil-works/omk-tui/dist/components/text.d.ts.map +1 -0
- package/node_modules/@earendil-works/omk-tui/dist/components/text.js +89 -0
- package/node_modules/@earendil-works/omk-tui/dist/components/text.js.map +1 -0
- package/node_modules/@earendil-works/omk-tui/dist/components/truncated-text.d.ts +13 -0
- package/node_modules/@earendil-works/omk-tui/dist/components/truncated-text.d.ts.map +1 -0
- package/node_modules/@earendil-works/omk-tui/dist/components/truncated-text.js +51 -0
- package/node_modules/@earendil-works/omk-tui/dist/components/truncated-text.js.map +1 -0
- package/node_modules/@earendil-works/omk-tui/dist/editor-component.d.ts +39 -0
- package/node_modules/@earendil-works/omk-tui/dist/editor-component.d.ts.map +1 -0
- package/node_modules/@earendil-works/omk-tui/dist/editor-component.js +2 -0
- package/node_modules/@earendil-works/omk-tui/dist/editor-component.js.map +1 -0
- package/node_modules/@earendil-works/omk-tui/dist/fuzzy.d.ts +16 -0
- package/node_modules/@earendil-works/omk-tui/dist/fuzzy.d.ts.map +1 -0
- package/node_modules/@earendil-works/omk-tui/dist/fuzzy.js +110 -0
- package/node_modules/@earendil-works/omk-tui/dist/fuzzy.js.map +1 -0
- package/node_modules/@earendil-works/omk-tui/dist/index.d.ts +23 -0
- package/node_modules/@earendil-works/omk-tui/dist/index.d.ts.map +1 -0
- package/node_modules/@earendil-works/omk-tui/dist/index.js +32 -0
- package/node_modules/@earendil-works/omk-tui/dist/index.js.map +1 -0
- package/node_modules/@earendil-works/omk-tui/dist/keybindings.d.ts +212 -0
- package/node_modules/@earendil-works/omk-tui/dist/keybindings.d.ts.map +1 -0
- package/node_modules/@earendil-works/omk-tui/dist/keybindings.js +252 -0
- package/node_modules/@earendil-works/omk-tui/dist/keybindings.js.map +1 -0
- package/node_modules/@earendil-works/omk-tui/dist/keys.d.ts +184 -0
- package/node_modules/@earendil-works/omk-tui/dist/keys.d.ts.map +1 -0
- package/node_modules/@earendil-works/omk-tui/dist/keys.js +1173 -0
- package/node_modules/@earendil-works/omk-tui/dist/keys.js.map +1 -0
- package/node_modules/@earendil-works/omk-tui/dist/kill-ring.d.ts +28 -0
- package/node_modules/@earendil-works/omk-tui/dist/kill-ring.d.ts.map +1 -0
- package/node_modules/@earendil-works/omk-tui/dist/kill-ring.js +44 -0
- package/node_modules/@earendil-works/omk-tui/dist/kill-ring.js.map +1 -0
- package/node_modules/@earendil-works/omk-tui/dist/native-modifiers.d.ts +3 -0
- package/node_modules/@earendil-works/omk-tui/dist/native-modifiers.d.ts.map +1 -0
- package/node_modules/@earendil-works/omk-tui/dist/native-modifiers.js +53 -0
- package/node_modules/@earendil-works/omk-tui/dist/native-modifiers.js.map +1 -0
- package/node_modules/@earendil-works/omk-tui/dist/stdin-buffer.d.ts +50 -0
- package/node_modules/@earendil-works/omk-tui/dist/stdin-buffer.d.ts.map +1 -0
- package/node_modules/@earendil-works/omk-tui/dist/stdin-buffer.js +361 -0
- package/node_modules/@earendil-works/omk-tui/dist/stdin-buffer.js.map +1 -0
- package/node_modules/@earendil-works/omk-tui/dist/terminal-image.d.ts +90 -0
- package/node_modules/@earendil-works/omk-tui/dist/terminal-image.d.ts.map +1 -0
- package/node_modules/@earendil-works/omk-tui/dist/terminal-image.js +366 -0
- package/node_modules/@earendil-works/omk-tui/dist/terminal-image.js.map +1 -0
- package/node_modules/@earendil-works/omk-tui/dist/terminal.d.ts +113 -0
- package/node_modules/@earendil-works/omk-tui/dist/terminal.d.ts.map +1 -0
- package/node_modules/@earendil-works/omk-tui/dist/terminal.js +472 -0
- package/node_modules/@earendil-works/omk-tui/dist/terminal.js.map +1 -0
- package/node_modules/@earendil-works/omk-tui/dist/tui.d.ts +242 -0
- package/node_modules/@earendil-works/omk-tui/dist/tui.d.ts.map +1 -0
- package/node_modules/@earendil-works/omk-tui/dist/tui.js +1221 -0
- package/node_modules/@earendil-works/omk-tui/dist/tui.js.map +1 -0
- package/node_modules/@earendil-works/omk-tui/dist/undo-stack.d.ts +17 -0
- package/node_modules/@earendil-works/omk-tui/dist/undo-stack.d.ts.map +1 -0
- package/node_modules/@earendil-works/omk-tui/dist/undo-stack.js +25 -0
- package/node_modules/@earendil-works/omk-tui/dist/undo-stack.js.map +1 -0
- package/node_modules/@earendil-works/omk-tui/dist/utils.d.ts +84 -0
- package/node_modules/@earendil-works/omk-tui/dist/utils.d.ts.map +1 -0
- package/node_modules/@earendil-works/omk-tui/dist/utils.js +1032 -0
- package/node_modules/@earendil-works/omk-tui/dist/utils.js.map +1 -0
- package/node_modules/@earendil-works/omk-tui/dist/word-navigation.d.ts +25 -0
- package/node_modules/@earendil-works/omk-tui/dist/word-navigation.d.ts.map +1 -0
- package/node_modules/@earendil-works/omk-tui/dist/word-navigation.js +96 -0
- package/node_modules/@earendil-works/omk-tui/dist/word-navigation.js.map +1 -0
- package/node_modules/@earendil-works/omk-tui/native/darwin/prebuilds/darwin-arm64/darwin-modifiers.node +0 -0
- package/node_modules/@earendil-works/omk-tui/native/darwin/prebuilds/darwin-x64/darwin-modifiers.node +0 -0
- package/node_modules/@earendil-works/omk-tui/native/win32/prebuilds/win32-arm64/win32-console-mode.node +0 -0
- package/node_modules/@earendil-works/omk-tui/native/win32/prebuilds/win32-x64/win32-console-mode.node +0 -0
- package/node_modules/@earendil-works/omk-tui/package.json +47 -0
- package/package.json +22 -6
- package/dist/utils/pi-user-agent.d.ts +0 -2
- package/dist/utils/pi-user-agent.d.ts.map +0 -1
- package/dist/utils/pi-user-agent.js.map +0 -1
|
@@ -0,0 +1,368 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Driver-agnostic SchedulerStore contract for the durable DAG orchestrator.
|
|
3
|
+
*
|
|
4
|
+
* This module owns the persistence *contract* and the deterministic, pure
|
|
5
|
+
* helpers that any concrete store implementation must honor:
|
|
6
|
+
* - the canonical SQLite WAL DDL (one source of truth for the schema),
|
|
7
|
+
* - the connection pragmas,
|
|
8
|
+
* - stable idempotency / DAG hashing (so DAG ingestion is replay-safe),
|
|
9
|
+
* - access-set canonicalization (so stable keys are order-independent).
|
|
10
|
+
*
|
|
11
|
+
* It performs NO I/O itself. The concrete `node:sqlite` implementation lives in
|
|
12
|
+
* `sqlite-scheduler-store.ts`. Keeping the contract and pure helpers here lets a
|
|
13
|
+
* second driver (e.g. better-sqlite3) be added later without touching scheduler
|
|
14
|
+
* logic, and lets tests assert determinism without a database.
|
|
15
|
+
*
|
|
16
|
+
* Schema reference: `.omk/runs/omk-orchestration-upgrade-plan/foundation.md` §3.
|
|
17
|
+
* Conflict policy is reused from `scheduler-state.ts`; hashing primitives from
|
|
18
|
+
* `replay-ledger.ts`. Erasable TypeScript only (no enum/namespace/param props).
|
|
19
|
+
*/
|
|
20
|
+
import { sha256Hex, stableStringify } from "./replay-ledger.js";
|
|
21
|
+
import { accessEntriesConflict, nodesConflict, } from "./scheduler-state.js";
|
|
22
|
+
/**
|
|
23
|
+
* Canonical connection pragmas. WAL is a no-op for `:memory:` databases (SQLite
|
|
24
|
+
* keeps an in-memory journal there) but is applied verbatim for file stores.
|
|
25
|
+
*/
|
|
26
|
+
export const SCHEDULER_STORE_PRAGMAS = [
|
|
27
|
+
"PRAGMA journal_mode = WAL",
|
|
28
|
+
"PRAGMA synchronous = NORMAL",
|
|
29
|
+
"PRAGMA busy_timeout = 5000",
|
|
30
|
+
"PRAGMA foreign_keys = ON",
|
|
31
|
+
"PRAGMA temp_store = MEMORY",
|
|
32
|
+
];
|
|
33
|
+
/** Tables the schema must create, in dependency-safe creation order. */
|
|
34
|
+
export const SCHEDULER_STORE_TABLES = [
|
|
35
|
+
"runs",
|
|
36
|
+
"nodes",
|
|
37
|
+
"edges",
|
|
38
|
+
"access",
|
|
39
|
+
"conflicts",
|
|
40
|
+
"attempts",
|
|
41
|
+
"leases",
|
|
42
|
+
"artifacts",
|
|
43
|
+
"worktrees",
|
|
44
|
+
"merge_queue",
|
|
45
|
+
"compensators",
|
|
46
|
+
"events",
|
|
47
|
+
];
|
|
48
|
+
/**
|
|
49
|
+
* Canonical SQLite WAL DDL. Parent tables precede children so FK declarations
|
|
50
|
+
* resolve cleanly. This is the single source of truth for the durable schema.
|
|
51
|
+
*/
|
|
52
|
+
export const SCHEDULER_STORE_SCHEMA = `
|
|
53
|
+
CREATE TABLE IF NOT EXISTS runs (
|
|
54
|
+
run_id TEXT PRIMARY KEY,
|
|
55
|
+
goal TEXT NOT NULL,
|
|
56
|
+
topology TEXT NOT NULL,
|
|
57
|
+
status TEXT NOT NULL DEFAULT 'running'
|
|
58
|
+
CHECK (status IN ('running','paused','completed','failed','cancelled')),
|
|
59
|
+
created_at TEXT NOT NULL,
|
|
60
|
+
updated_at TEXT NOT NULL,
|
|
61
|
+
completed_at TEXT,
|
|
62
|
+
dag_hash TEXT,
|
|
63
|
+
root_node_id TEXT
|
|
64
|
+
);
|
|
65
|
+
|
|
66
|
+
CREATE TABLE IF NOT EXISTS nodes (
|
|
67
|
+
node_id TEXT NOT NULL,
|
|
68
|
+
run_id TEXT NOT NULL,
|
|
69
|
+
role TEXT NOT NULL
|
|
70
|
+
CHECK (role IN ('planner','explorer','coder','tester','reviewer','security','memory','synthesizer')),
|
|
71
|
+
task TEXT NOT NULL,
|
|
72
|
+
status TEXT NOT NULL DEFAULT 'queued'
|
|
73
|
+
CHECK (status IN ('queued','leased','running','verifying','completed','retry_wait',
|
|
74
|
+
'compensating','rolled_back','in_doubt','blocked','cancelled','failed')),
|
|
75
|
+
idempotency_key TEXT NOT NULL,
|
|
76
|
+
read_set TEXT NOT NULL DEFAULT '[]',
|
|
77
|
+
write_set TEXT NOT NULL DEFAULT '[]',
|
|
78
|
+
lease_id TEXT,
|
|
79
|
+
lease_expires_at TEXT,
|
|
80
|
+
heartbeat_at TEXT,
|
|
81
|
+
retry_policy TEXT NOT NULL DEFAULT '{}',
|
|
82
|
+
verification_contract TEXT,
|
|
83
|
+
cost_budget REAL,
|
|
84
|
+
attempt_count INTEGER NOT NULL DEFAULT 0,
|
|
85
|
+
requeue_count INTEGER NOT NULL DEFAULT 0,
|
|
86
|
+
retry_wait_until TEXT,
|
|
87
|
+
created_at TEXT NOT NULL,
|
|
88
|
+
started_at TEXT,
|
|
89
|
+
finished_at TEXT,
|
|
90
|
+
priority INTEGER NOT NULL DEFAULT 0,
|
|
91
|
+
parallelizable INTEGER NOT NULL DEFAULT 1,
|
|
92
|
+
PRIMARY KEY (run_id, node_id),
|
|
93
|
+
FOREIGN KEY (run_id) REFERENCES runs(run_id) ON DELETE CASCADE,
|
|
94
|
+
UNIQUE (run_id, idempotency_key)
|
|
95
|
+
);
|
|
96
|
+
|
|
97
|
+
CREATE TABLE IF NOT EXISTS edges (
|
|
98
|
+
run_id TEXT NOT NULL,
|
|
99
|
+
from_node_id TEXT NOT NULL,
|
|
100
|
+
to_node_id TEXT NOT NULL,
|
|
101
|
+
edge_type TEXT NOT NULL DEFAULT 'strong'
|
|
102
|
+
CHECK (edge_type IN ('strong','weak')),
|
|
103
|
+
PRIMARY KEY (run_id, from_node_id, to_node_id),
|
|
104
|
+
FOREIGN KEY (run_id) REFERENCES runs(run_id) ON DELETE CASCADE,
|
|
105
|
+
FOREIGN KEY (run_id, from_node_id) REFERENCES nodes(run_id, node_id) ON DELETE CASCADE,
|
|
106
|
+
FOREIGN KEY (run_id, to_node_id) REFERENCES nodes(run_id, node_id) ON DELETE CASCADE
|
|
107
|
+
);
|
|
108
|
+
|
|
109
|
+
CREATE TABLE IF NOT EXISTS access (
|
|
110
|
+
access_id TEXT PRIMARY KEY,
|
|
111
|
+
run_id TEXT NOT NULL,
|
|
112
|
+
node_id TEXT NOT NULL,
|
|
113
|
+
kind TEXT NOT NULL CHECK (kind IN ('read','write')),
|
|
114
|
+
path TEXT NOT NULL,
|
|
115
|
+
symbols TEXT NOT NULL DEFAULT '[]',
|
|
116
|
+
FOREIGN KEY (run_id, node_id) REFERENCES nodes(run_id, node_id) ON DELETE CASCADE,
|
|
117
|
+
UNIQUE (run_id, node_id, kind, path, symbols)
|
|
118
|
+
);
|
|
119
|
+
|
|
120
|
+
CREATE TABLE IF NOT EXISTS conflicts (
|
|
121
|
+
run_id TEXT NOT NULL,
|
|
122
|
+
node_a TEXT NOT NULL,
|
|
123
|
+
node_b TEXT NOT NULL,
|
|
124
|
+
reason TEXT NOT NULL CHECK (reason IN ('write-write','write-read','read-write')),
|
|
125
|
+
PRIMARY KEY (run_id, node_a, node_b),
|
|
126
|
+
FOREIGN KEY (run_id, node_a) REFERENCES nodes(run_id, node_id) ON DELETE CASCADE,
|
|
127
|
+
FOREIGN KEY (run_id, node_b) REFERENCES nodes(run_id, node_id) ON DELETE CASCADE,
|
|
128
|
+
CHECK (node_a < node_b)
|
|
129
|
+
);
|
|
130
|
+
|
|
131
|
+
CREATE TABLE IF NOT EXISTS attempts (
|
|
132
|
+
attempt_id TEXT PRIMARY KEY,
|
|
133
|
+
run_id TEXT NOT NULL,
|
|
134
|
+
node_id TEXT NOT NULL,
|
|
135
|
+
lease_id TEXT NOT NULL,
|
|
136
|
+
started_at TEXT NOT NULL,
|
|
137
|
+
finished_at TEXT,
|
|
138
|
+
status TEXT NOT NULL
|
|
139
|
+
CHECK (status IN ('running','completed','failed','rolled_back','in_doubt')),
|
|
140
|
+
exit_code INTEGER,
|
|
141
|
+
error_summary TEXT,
|
|
142
|
+
worker_pid INTEGER,
|
|
143
|
+
FOREIGN KEY (run_id, node_id) REFERENCES nodes(run_id, node_id) ON DELETE CASCADE
|
|
144
|
+
);
|
|
145
|
+
|
|
146
|
+
CREATE TABLE IF NOT EXISTS leases (
|
|
147
|
+
lease_id TEXT PRIMARY KEY,
|
|
148
|
+
run_id TEXT NOT NULL,
|
|
149
|
+
node_id TEXT NOT NULL,
|
|
150
|
+
attempt_id TEXT,
|
|
151
|
+
issued_at TEXT NOT NULL,
|
|
152
|
+
expires_at TEXT NOT NULL,
|
|
153
|
+
heartbeat_at TEXT,
|
|
154
|
+
owner_token TEXT NOT NULL,
|
|
155
|
+
released INTEGER NOT NULL DEFAULT 0,
|
|
156
|
+
FOREIGN KEY (run_id, node_id) REFERENCES nodes(run_id, node_id) ON DELETE CASCADE,
|
|
157
|
+
FOREIGN KEY (attempt_id) REFERENCES attempts(attempt_id) ON DELETE SET NULL
|
|
158
|
+
);
|
|
159
|
+
|
|
160
|
+
CREATE TABLE IF NOT EXISTS artifacts (
|
|
161
|
+
artifact_id TEXT PRIMARY KEY,
|
|
162
|
+
run_id TEXT NOT NULL,
|
|
163
|
+
node_id TEXT NOT NULL,
|
|
164
|
+
attempt_id TEXT,
|
|
165
|
+
path TEXT NOT NULL,
|
|
166
|
+
kind TEXT NOT NULL
|
|
167
|
+
CHECK (kind IN ('evidence','patch','result','checkpoint','contract')),
|
|
168
|
+
sha256 TEXT,
|
|
169
|
+
size_bytes INTEGER,
|
|
170
|
+
created_at TEXT NOT NULL,
|
|
171
|
+
FOREIGN KEY (run_id, node_id) REFERENCES nodes(run_id, node_id) ON DELETE CASCADE,
|
|
172
|
+
FOREIGN KEY (attempt_id) REFERENCES attempts(attempt_id) ON DELETE SET NULL
|
|
173
|
+
);
|
|
174
|
+
|
|
175
|
+
CREATE TABLE IF NOT EXISTS worktrees (
|
|
176
|
+
worktree_id TEXT PRIMARY KEY,
|
|
177
|
+
run_id TEXT NOT NULL,
|
|
178
|
+
node_id TEXT NOT NULL,
|
|
179
|
+
path TEXT NOT NULL,
|
|
180
|
+
branch_name TEXT NOT NULL,
|
|
181
|
+
status TEXT NOT NULL DEFAULT 'active'
|
|
182
|
+
CHECK (status IN ('active','merged','reclaimed','orphaned')),
|
|
183
|
+
created_at TEXT NOT NULL,
|
|
184
|
+
FOREIGN KEY (run_id, node_id) REFERENCES nodes(run_id, node_id) ON DELETE CASCADE
|
|
185
|
+
);
|
|
186
|
+
|
|
187
|
+
CREATE TABLE IF NOT EXISTS merge_queue (
|
|
188
|
+
queue_id TEXT PRIMARY KEY,
|
|
189
|
+
run_id TEXT NOT NULL,
|
|
190
|
+
node_id TEXT NOT NULL,
|
|
191
|
+
branch_name TEXT NOT NULL,
|
|
192
|
+
target_branch TEXT NOT NULL DEFAULT 'main',
|
|
193
|
+
status TEXT NOT NULL DEFAULT 'pending'
|
|
194
|
+
CHECK (status IN ('pending','merging','merged','conflict','blocked')),
|
|
195
|
+
priority INTEGER NOT NULL DEFAULT 0,
|
|
196
|
+
dag_depth INTEGER NOT NULL DEFAULT 0,
|
|
197
|
+
lease_finished_at TEXT,
|
|
198
|
+
created_at TEXT NOT NULL,
|
|
199
|
+
merged_at TEXT,
|
|
200
|
+
FOREIGN KEY (run_id, node_id) REFERENCES nodes(run_id, node_id) ON DELETE CASCADE
|
|
201
|
+
);
|
|
202
|
+
|
|
203
|
+
CREATE TABLE IF NOT EXISTS compensators (
|
|
204
|
+
compensator_id TEXT PRIMARY KEY,
|
|
205
|
+
run_id TEXT NOT NULL,
|
|
206
|
+
node_id TEXT NOT NULL,
|
|
207
|
+
kind TEXT NOT NULL,
|
|
208
|
+
sequence INTEGER NOT NULL,
|
|
209
|
+
idempotent INTEGER NOT NULL DEFAULT 1,
|
|
210
|
+
applied INTEGER NOT NULL DEFAULT 0,
|
|
211
|
+
prepared_state_hash TEXT,
|
|
212
|
+
created_at TEXT NOT NULL,
|
|
213
|
+
FOREIGN KEY (run_id, node_id) REFERENCES nodes(run_id, node_id) ON DELETE CASCADE,
|
|
214
|
+
UNIQUE (run_id, node_id, sequence)
|
|
215
|
+
);
|
|
216
|
+
|
|
217
|
+
CREATE TABLE IF NOT EXISTS events (
|
|
218
|
+
event_id TEXT PRIMARY KEY,
|
|
219
|
+
run_id TEXT NOT NULL,
|
|
220
|
+
operation_id TEXT NOT NULL,
|
|
221
|
+
causation_id TEXT,
|
|
222
|
+
sequence INTEGER NOT NULL,
|
|
223
|
+
timestamp TEXT NOT NULL,
|
|
224
|
+
kind TEXT NOT NULL,
|
|
225
|
+
status TEXT NOT NULL,
|
|
226
|
+
node_id TEXT,
|
|
227
|
+
data TEXT NOT NULL,
|
|
228
|
+
FOREIGN KEY (run_id) REFERENCES runs(run_id) ON DELETE CASCADE
|
|
229
|
+
);
|
|
230
|
+
|
|
231
|
+
CREATE INDEX IF NOT EXISTS idx_nodes_dispatch
|
|
232
|
+
ON nodes(run_id, status, retry_wait_until, priority, attempt_count)
|
|
233
|
+
WHERE status IN ('queued','retry_wait');
|
|
234
|
+
CREATE INDEX IF NOT EXISTS idx_nodes_lease ON nodes(run_id, lease_id);
|
|
235
|
+
CREATE INDEX IF NOT EXISTS idx_nodes_expired
|
|
236
|
+
ON nodes(lease_expires_at)
|
|
237
|
+
WHERE status = 'leased' OR status = 'running' OR status = 'verifying';
|
|
238
|
+
CREATE INDEX IF NOT EXISTS idx_edges_to ON edges(run_id, to_node_id);
|
|
239
|
+
CREATE INDEX IF NOT EXISTS idx_edges_from ON edges(run_id, from_node_id);
|
|
240
|
+
CREATE INDEX IF NOT EXISTS idx_access_node ON access(run_id, node_id);
|
|
241
|
+
CREATE INDEX IF NOT EXISTS idx_conflicts_run ON conflicts(run_id, node_a, node_b);
|
|
242
|
+
CREATE INDEX IF NOT EXISTS idx_artifacts_path ON artifacts(run_id, path);
|
|
243
|
+
CREATE INDEX IF NOT EXISTS idx_events_run_seq ON events(run_id, sequence);
|
|
244
|
+
CREATE INDEX IF NOT EXISTS idx_events_node ON events(run_id, node_id, sequence);
|
|
245
|
+
`;
|
|
246
|
+
/**
|
|
247
|
+
* Thrown when a DAG re-submission reuses an existing `node_id` within a run but
|
|
248
|
+
* supplies a different canonical descriptor. DAGs are immutable within a run:
|
|
249
|
+
* identical re-submissions are idempotent replays, but a changed definition for
|
|
250
|
+
* an existing node id is a divergence the store surfaces fail-closed instead of
|
|
251
|
+
* silently keeping the old or overwriting with the new.
|
|
252
|
+
*/
|
|
253
|
+
export class NodeRedefinitionError extends Error {
|
|
254
|
+
runId;
|
|
255
|
+
nodeId;
|
|
256
|
+
constructor(runId, nodeId) {
|
|
257
|
+
super(`node "${nodeId}" in run "${runId}" was redefined with a different descriptor; DAGs are immutable within a run`);
|
|
258
|
+
this.name = "NodeRedefinitionError";
|
|
259
|
+
this.runId = runId;
|
|
260
|
+
this.nodeId = nodeId;
|
|
261
|
+
}
|
|
262
|
+
}
|
|
263
|
+
/** Default retry policy applied when a node omits one. */
|
|
264
|
+
export const DEFAULT_RETRY_POLICY = {
|
|
265
|
+
maxAttempts: 3,
|
|
266
|
+
baseMs: 1000,
|
|
267
|
+
maxMs: 30000,
|
|
268
|
+
multiplier: 2,
|
|
269
|
+
};
|
|
270
|
+
/**
|
|
271
|
+
* Canonicalize one access entry: drop undefined symbols, sort symbols, so the
|
|
272
|
+
* stable key never depends on declaration order.
|
|
273
|
+
*/
|
|
274
|
+
export function canonicalizeAccessEntry(entry) {
|
|
275
|
+
const symbols = entry.symbols === undefined ? [] : [...entry.symbols].sort(compareString);
|
|
276
|
+
return { path: entry.path, symbols };
|
|
277
|
+
}
|
|
278
|
+
/** Canonicalize an access set: canonicalize each entry, then sort entries. */
|
|
279
|
+
export function canonicalizeAccessSet(entries) {
|
|
280
|
+
const canonical = (entries ?? []).map(canonicalizeAccessEntry);
|
|
281
|
+
canonical.sort((a, b) => {
|
|
282
|
+
const byPath = compareString(a.path, b.path);
|
|
283
|
+
if (byPath !== 0) {
|
|
284
|
+
return byPath;
|
|
285
|
+
}
|
|
286
|
+
return compareString(stableStringify(a.symbols), stableStringify(b.symbols));
|
|
287
|
+
});
|
|
288
|
+
return canonical;
|
|
289
|
+
}
|
|
290
|
+
/**
|
|
291
|
+
* Deterministic node descriptor used for idempotency. Excludes runtime state
|
|
292
|
+
* (status, leases, counters) so identical logical work always hashes the same.
|
|
293
|
+
*/
|
|
294
|
+
export function canonicalNodeDescriptor(node) {
|
|
295
|
+
return {
|
|
296
|
+
nodeId: node.nodeId,
|
|
297
|
+
role: node.role,
|
|
298
|
+
task: node.task,
|
|
299
|
+
priority: node.priority ?? 0,
|
|
300
|
+
parallelizable: node.parallelizable ?? true,
|
|
301
|
+
readSet: canonicalizeAccessSet(node.readSet),
|
|
302
|
+
writeSet: canonicalizeAccessSet(node.writeSet),
|
|
303
|
+
};
|
|
304
|
+
}
|
|
305
|
+
/**
|
|
306
|
+
* Stable idempotency key: `sha256(stableStringify({runId, descriptor}))`.
|
|
307
|
+
* Two submissions of identical logical work produce the same key, so DAG
|
|
308
|
+
* ingestion can deduplicate across root-coordinator retries (foundation §6.5).
|
|
309
|
+
*/
|
|
310
|
+
export function computeIdempotencyKey(runId, node) {
|
|
311
|
+
return sha256Hex(stableStringify({ runId, descriptor: canonicalNodeDescriptor(node) }));
|
|
312
|
+
}
|
|
313
|
+
/** Stable hash over the whole DAG (nodes + edges), order-independent. */
|
|
314
|
+
export function computeDagHash(submission) {
|
|
315
|
+
const nodes = submission.nodes.map(canonicalNodeDescriptor);
|
|
316
|
+
nodes.sort((a, b) => compareString(stableStringify(a), stableStringify(b)));
|
|
317
|
+
const edges = (submission.edges ?? []).map((edge) => ({
|
|
318
|
+
fromNodeId: edge.fromNodeId,
|
|
319
|
+
toNodeId: edge.toNodeId,
|
|
320
|
+
edgeType: edge.edgeType ?? "strong",
|
|
321
|
+
}));
|
|
322
|
+
edges.sort((a, b) => compareString(stableStringify(a), stableStringify(b)));
|
|
323
|
+
return sha256Hex(stableStringify({ runId: submission.run.runId, nodes, edges }));
|
|
324
|
+
}
|
|
325
|
+
/**
|
|
326
|
+
* Classify the conflict between two nodes in canonical (nodeA < nodeB) order.
|
|
327
|
+
*
|
|
328
|
+
* Existence is decided by the shared pure policy `nodesConflict`; the label is
|
|
329
|
+
* derived from the same atomic `accessEntriesConflict` predicate. Precedence is
|
|
330
|
+
* deterministic: write/write, then write/read, then read/write. Returns
|
|
331
|
+
* undefined when the nodes do not conflict.
|
|
332
|
+
*/
|
|
333
|
+
export function classifyConflict(nodeA, nodeB) {
|
|
334
|
+
if (!nodesConflict(nodeA, nodeB)) {
|
|
335
|
+
return undefined;
|
|
336
|
+
}
|
|
337
|
+
if (setsConflict(nodeA.writeSet, nodeB.writeSet)) {
|
|
338
|
+
return "write-write";
|
|
339
|
+
}
|
|
340
|
+
if (setsConflict(nodeA.writeSet, nodeB.readSet)) {
|
|
341
|
+
return "write-read";
|
|
342
|
+
}
|
|
343
|
+
if (setsConflict(nodeA.readSet, nodeB.writeSet)) {
|
|
344
|
+
return "read-write";
|
|
345
|
+
}
|
|
346
|
+
// nodesConflict was true, so one of the above must hold; fall back defensively.
|
|
347
|
+
return "write-write";
|
|
348
|
+
}
|
|
349
|
+
function setsConflict(left, right) {
|
|
350
|
+
for (const l of left) {
|
|
351
|
+
for (const r of right) {
|
|
352
|
+
if (accessEntriesConflict(l, r)) {
|
|
353
|
+
return true;
|
|
354
|
+
}
|
|
355
|
+
}
|
|
356
|
+
}
|
|
357
|
+
return false;
|
|
358
|
+
}
|
|
359
|
+
function compareString(a, b) {
|
|
360
|
+
if (a < b) {
|
|
361
|
+
return -1;
|
|
362
|
+
}
|
|
363
|
+
if (a > b) {
|
|
364
|
+
return 1;
|
|
365
|
+
}
|
|
366
|
+
return 0;
|
|
367
|
+
}
|
|
368
|
+
//# sourceMappingURL=scheduler-store.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"scheduler-store.js","sourceRoot":"","sources":["../../../src/core/orchestration/scheduler-store.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * Driver-agnostic SchedulerStore contract for the durable DAG orchestrator.\n *\n * This module owns the persistence *contract* and the deterministic, pure\n * helpers that any concrete store implementation must honor:\n * - the canonical SQLite WAL DDL (one source of truth for the schema),\n * - the connection pragmas,\n * - stable idempotency / DAG hashing (so DAG ingestion is replay-safe),\n * - access-set canonicalization (so stable keys are order-independent).\n *\n * It performs NO I/O itself. The concrete `node:sqlite` implementation lives in\n * `sqlite-scheduler-store.ts`. Keeping the contract and pure helpers here lets a\n * second driver (e.g. better-sqlite3) be added later without touching scheduler\n * logic, and lets tests assert determinism without a database.\n *\n * Schema reference: `.omk/runs/omk-orchestration-upgrade-plan/foundation.md` §3.\n * Conflict policy is reused from `scheduler-state.ts`; hashing primitives from\n * `replay-ledger.ts`. Erasable TypeScript only (no enum/namespace/param props).\n */\n\nimport { type JsonValue, sha256Hex, stableStringify } from \"./replay-ledger.ts\";\nimport {\n\ttype AccessSetEntry,\n\taccessEntriesConflict,\n\tnodesConflict,\n\ttype SchedulerNode,\n\ttype SchedulerNodeStatus,\n} from \"./scheduler-state.ts\";\n\nexport type RunStatus = \"running\" | \"paused\" | \"completed\" | \"failed\" | \"cancelled\";\nexport type NodeStatus = SchedulerNodeStatus;\nexport type EdgeType = \"strong\" | \"weak\";\nexport type AccessKind = \"read\" | \"write\";\nexport type ConflictReason = \"write-write\" | \"write-read\" | \"read-write\";\nexport type NodeRole = \"planner\" | \"explorer\" | \"coder\" | \"tester\" | \"reviewer\" | \"security\" | \"memory\" | \"synthesizer\";\n\n/** Retry envelope persisted as JSON on the node row. */\nexport interface RetryPolicy {\n\tmaxAttempts: number;\n\tbaseMs: number;\n\tmaxMs: number;\n\tmultiplier: number;\n}\n\nexport interface RunInput {\n\trunId: string;\n\tgoal: string;\n\ttopology: string;\n\tdagHash?: string;\n\trootNodeId?: string;\n}\n\nexport interface RunRow {\n\trunId: string;\n\tgoal: string;\n\ttopology: string;\n\tstatus: RunStatus;\n\tcreatedAt: string;\n\tupdatedAt: string;\n\tcompletedAt: string | null;\n\tdagHash: string | null;\n\trootNodeId: string | null;\n}\n\n/** A node as submitted by the root coordinator (caller owns `nodeId`). */\nexport interface NodeInput {\n\tnodeId: string;\n\trole: NodeRole;\n\ttask: string;\n\treadSet?: readonly AccessSetEntry[];\n\twriteSet?: readonly AccessSetEntry[];\n\tpriority?: number;\n\tparallelizable?: boolean;\n\tretryPolicy?: RetryPolicy;\n\tverificationContract?: string;\n\tcostBudget?: number;\n}\n\n/** A persisted node row, rehydrated from SQLite. */\nexport interface NodeRow {\n\tnodeId: string;\n\trunId: string;\n\trole: NodeRole;\n\ttask: string;\n\tstatus: NodeStatus;\n\tidempotencyKey: string;\n\treadSet: AccessSetEntry[];\n\twriteSet: AccessSetEntry[];\n\tleaseId: string | null;\n\tleaseExpiresAt: string | null;\n\theartbeatAt: string | null;\n\tattemptCount: number;\n\trequeueCount: number;\n\tretryWaitUntil: string | null;\n\tpriority: number;\n\tparallelizable: boolean;\n\tcreatedAt: string;\n\tstartedAt: string | null;\n\tfinishedAt: string | null;\n}\n\nexport interface EdgeInput {\n\tfromNodeId: string;\n\ttoNodeId: string;\n\tedgeType?: EdgeType;\n}\n\nexport interface EdgeRow {\n\trunId: string;\n\tfromNodeId: string;\n\ttoNodeId: string;\n\tedgeType: EdgeType;\n}\n\n/** A whole DAG submission: run header + nodes + edges. */\nexport interface DagSubmission {\n\trun: RunInput;\n\tnodes: readonly NodeInput[];\n\tedges?: readonly EdgeInput[];\n}\n\n/** Outcome of an idempotent DAG ingestion. */\nexport interface DagIngestionResult {\n\trunId: string;\n\tdagHash: string;\n\t/** All node ids present after ingestion, in submission order. */\n\tnodeIds: string[];\n\t/** Node ids freshly inserted by this call. */\n\tinsertedNodeIds: string[];\n\t/** Node ids that already existed (idempotency hit). */\n\treusedNodeIds: string[];\n}\n\nexport interface LeaseInput {\n\tleaseId: string;\n\townerToken: string;\n\t/** ISO-8601 absolute expiry deadline. */\n\texpiresAt: string;\n\t/** ISO-8601 issue time; defaults to now() in the implementation. */\n\tnow?: string;\n}\n\nexport interface LeaseRow {\n\tleaseId: string;\n\trunId: string;\n\tnodeId: string;\n\tattemptId: string | null;\n\tissuedAt: string;\n\texpiresAt: string;\n\theartbeatAt: string | null;\n\townerToken: string;\n\treleased: boolean;\n}\n\n/** One undirected edge of the conflict graph (always stored nodeA < nodeB). */\nexport interface ConflictEdge {\n\trunId: string;\n\tnodeA: string;\n\tnodeB: string;\n\treason: ConflictReason;\n}\n\nexport interface AttemptInput {\n\tattemptId: string;\n\trunId: string;\n\tnodeId: string;\n\tleaseId: string;\n\tstatus: \"running\" | \"completed\" | \"failed\" | \"rolled_back\" | \"in_doubt\";\n\tstartedAt?: string;\n\tfinishedAt?: string;\n\texitCode?: number;\n\terrorSummary?: JsonValue;\n\tworkerPid?: number;\n}\n\nexport interface WorktreeInput {\n\tworktreeId: string;\n\trunId: string;\n\tnodeId: string;\n\tpath: string;\n\tbranchName: string;\n\tstatus?: \"active\" | \"merged\" | \"reclaimed\" | \"orphaned\";\n\tcreatedAt?: string;\n}\n\nexport interface ArtifactInput {\n\tartifactId: string;\n\trunId: string;\n\tnodeId: string;\n\tattemptId?: string;\n\tpath: string;\n\tkind: \"evidence\" | \"patch\" | \"result\" | \"checkpoint\" | \"contract\";\n\tsha256?: string;\n\tsizeBytes?: number;\n\tcreatedAt?: string;\n}\n\n/** A durable compensator row (mirrors recovery.ts CompensatorStep + run/node). */\nexport interface CompensatorInput {\n\tcompensatorId: string;\n\trunId: string;\n\tnodeId: string;\n\tkind: string;\n\tsequence: number;\n\tidempotent: boolean;\n\tapplied: boolean;\n\tpreparedStateHash?: string | null;\n\tcreatedAt?: string;\n}\n\nexport interface SchedulerEventInput {\n\teventId: string;\n\trunId: string;\n\toperationId: string;\n\tsequence: number;\n\ttimestamp: string;\n\tkind: string;\n\tstatus: string;\n\tcausationId?: string | null;\n\tnodeId?: string | null;\n\tdata?: JsonValue;\n}\n\nexport interface SchedulerEventRow {\n\teventId: string;\n\trunId: string;\n\toperationId: string;\n\tcausationId: string | null;\n\tsequence: number;\n\ttimestamp: string;\n\tkind: string;\n\tstatus: string;\n\tnodeId: string | null;\n\tdata: JsonValue;\n}\n\n/**\n * The durable scheduler persistence contract. Mutating methods that race a\n * status guard return `boolean` (true iff the row was actually changed) so\n * callers get guard-based CAS semantics. All methods are synchronous because\n * both `node:sqlite` and `better-sqlite3` are synchronous.\n */\nexport interface SchedulerStore {\n\t// connection / schema\n\topen(path: string): void;\n\tclose(): void;\n\tcreateSchema(): void;\n\texec(sql: string): void;\n\t/** Read a single PRAGMA scalar (first column of the first row). */\n\tpragma(name: string): JsonValue;\n\n\t// run lifecycle\n\tcreateRun(run: RunInput): void;\n\tgetRun(runId: string): RunRow | undefined;\n\tupdateRunStatus(runId: string, status: RunStatus, now?: string): boolean;\n\n\t// DAG ingestion (idempotent)\n\tingestDag(submission: DagSubmission): DagIngestionResult;\n\tgetNode(runId: string, nodeId: string): NodeRow | undefined;\n\tgetNodesByRun(runId: string): NodeRow[];\n\tgetEdgesByRun(runId: string): EdgeRow[];\n\n\t// conflict graph\n\tbuildConflictGraph(runId: string): ConflictEdge[];\n\tgetConflicts(runId: string): ConflictEdge[];\n\n\t// lease lifecycle (owner-token fenced)\n\tacquireLease(runId: string, nodeId: string, lease: LeaseInput): boolean;\n\theartbeat(runId: string, nodeId: string, ownerToken: string, now: string, expiresAt: string): boolean;\n\tstartNode(runId: string, nodeId: string, ownerToken: string, now: string): boolean;\n\treclaimExpiredLeases(runId: string, now: string): string[];\n\tgetLease(leaseId: string): LeaseRow | undefined;\n\n\t// scaffolded sibling-lane tables (schema-complete, minimal writers)\n\trecordAttempt(attempt: AttemptInput): void;\n\tgetAttemptsByRun(runId: string): AttemptInput[];\n\tregisterWorktree(worktree: WorktreeInput): void;\n\tgetWorktreesByRun(runId: string): WorktreeInput[];\n\tregisterCompensator(compensator: CompensatorInput): void;\n\tgetCompensatorsByNode(runId: string, nodeId: string): CompensatorInput[];\n\trecordArtifact(artifact: ArtifactInput): void;\n\tgetArtifactsByRun(runId: string): ArtifactInput[];\n\n\t// ledger mirror\n\tappendEvent(event: SchedulerEventInput): void;\n\tgetEvents(runId: string): SchedulerEventRow[];\n}\n\n/**\n * Canonical connection pragmas. WAL is a no-op for `:memory:` databases (SQLite\n * keeps an in-memory journal there) but is applied verbatim for file stores.\n */\nexport const SCHEDULER_STORE_PRAGMAS: readonly string[] = [\n\t\"PRAGMA journal_mode = WAL\",\n\t\"PRAGMA synchronous = NORMAL\",\n\t\"PRAGMA busy_timeout = 5000\",\n\t\"PRAGMA foreign_keys = ON\",\n\t\"PRAGMA temp_store = MEMORY\",\n];\n\n/** Tables the schema must create, in dependency-safe creation order. */\nexport const SCHEDULER_STORE_TABLES: readonly string[] = [\n\t\"runs\",\n\t\"nodes\",\n\t\"edges\",\n\t\"access\",\n\t\"conflicts\",\n\t\"attempts\",\n\t\"leases\",\n\t\"artifacts\",\n\t\"worktrees\",\n\t\"merge_queue\",\n\t\"compensators\",\n\t\"events\",\n];\n\n/**\n * Canonical SQLite WAL DDL. Parent tables precede children so FK declarations\n * resolve cleanly. This is the single source of truth for the durable schema.\n */\nexport const SCHEDULER_STORE_SCHEMA = `\nCREATE TABLE IF NOT EXISTS runs (\n run_id TEXT PRIMARY KEY,\n goal TEXT NOT NULL,\n topology TEXT NOT NULL,\n status TEXT NOT NULL DEFAULT 'running'\n CHECK (status IN ('running','paused','completed','failed','cancelled')),\n created_at TEXT NOT NULL,\n updated_at TEXT NOT NULL,\n completed_at TEXT,\n dag_hash TEXT,\n root_node_id TEXT\n);\n\nCREATE TABLE IF NOT EXISTS nodes (\n node_id TEXT NOT NULL,\n run_id TEXT NOT NULL,\n role TEXT NOT NULL\n CHECK (role IN ('planner','explorer','coder','tester','reviewer','security','memory','synthesizer')),\n task TEXT NOT NULL,\n status TEXT NOT NULL DEFAULT 'queued'\n CHECK (status IN ('queued','leased','running','verifying','completed','retry_wait',\n 'compensating','rolled_back','in_doubt','blocked','cancelled','failed')),\n idempotency_key TEXT NOT NULL,\n read_set TEXT NOT NULL DEFAULT '[]',\n write_set TEXT NOT NULL DEFAULT '[]',\n lease_id TEXT,\n lease_expires_at TEXT,\n heartbeat_at TEXT,\n retry_policy TEXT NOT NULL DEFAULT '{}',\n verification_contract TEXT,\n cost_budget REAL,\n attempt_count INTEGER NOT NULL DEFAULT 0,\n requeue_count INTEGER NOT NULL DEFAULT 0,\n retry_wait_until TEXT,\n created_at TEXT NOT NULL,\n started_at TEXT,\n finished_at TEXT,\n priority INTEGER NOT NULL DEFAULT 0,\n parallelizable INTEGER NOT NULL DEFAULT 1,\n PRIMARY KEY (run_id, node_id),\n FOREIGN KEY (run_id) REFERENCES runs(run_id) ON DELETE CASCADE,\n UNIQUE (run_id, idempotency_key)\n);\n\nCREATE TABLE IF NOT EXISTS edges (\n run_id TEXT NOT NULL,\n from_node_id TEXT NOT NULL,\n to_node_id TEXT NOT NULL,\n edge_type TEXT NOT NULL DEFAULT 'strong'\n CHECK (edge_type IN ('strong','weak')),\n PRIMARY KEY (run_id, from_node_id, to_node_id),\n FOREIGN KEY (run_id) REFERENCES runs(run_id) ON DELETE CASCADE,\n FOREIGN KEY (run_id, from_node_id) REFERENCES nodes(run_id, node_id) ON DELETE CASCADE,\n FOREIGN KEY (run_id, to_node_id) REFERENCES nodes(run_id, node_id) ON DELETE CASCADE\n);\n\nCREATE TABLE IF NOT EXISTS access (\n access_id TEXT PRIMARY KEY,\n run_id TEXT NOT NULL,\n node_id TEXT NOT NULL,\n kind TEXT NOT NULL CHECK (kind IN ('read','write')),\n path TEXT NOT NULL,\n symbols TEXT NOT NULL DEFAULT '[]',\n FOREIGN KEY (run_id, node_id) REFERENCES nodes(run_id, node_id) ON DELETE CASCADE,\n UNIQUE (run_id, node_id, kind, path, symbols)\n);\n\nCREATE TABLE IF NOT EXISTS conflicts (\n run_id TEXT NOT NULL,\n node_a TEXT NOT NULL,\n node_b TEXT NOT NULL,\n reason TEXT NOT NULL CHECK (reason IN ('write-write','write-read','read-write')),\n PRIMARY KEY (run_id, node_a, node_b),\n FOREIGN KEY (run_id, node_a) REFERENCES nodes(run_id, node_id) ON DELETE CASCADE,\n FOREIGN KEY (run_id, node_b) REFERENCES nodes(run_id, node_id) ON DELETE CASCADE,\n CHECK (node_a < node_b)\n);\n\nCREATE TABLE IF NOT EXISTS attempts (\n attempt_id TEXT PRIMARY KEY,\n run_id TEXT NOT NULL,\n node_id TEXT NOT NULL,\n lease_id TEXT NOT NULL,\n started_at TEXT NOT NULL,\n finished_at TEXT,\n status TEXT NOT NULL\n CHECK (status IN ('running','completed','failed','rolled_back','in_doubt')),\n exit_code INTEGER,\n error_summary TEXT,\n worker_pid INTEGER,\n FOREIGN KEY (run_id, node_id) REFERENCES nodes(run_id, node_id) ON DELETE CASCADE\n);\n\nCREATE TABLE IF NOT EXISTS leases (\n lease_id TEXT PRIMARY KEY,\n run_id TEXT NOT NULL,\n node_id TEXT NOT NULL,\n attempt_id TEXT,\n issued_at TEXT NOT NULL,\n expires_at TEXT NOT NULL,\n heartbeat_at TEXT,\n owner_token TEXT NOT NULL,\n released INTEGER NOT NULL DEFAULT 0,\n FOREIGN KEY (run_id, node_id) REFERENCES nodes(run_id, node_id) ON DELETE CASCADE,\n FOREIGN KEY (attempt_id) REFERENCES attempts(attempt_id) ON DELETE SET NULL\n);\n\nCREATE TABLE IF NOT EXISTS artifacts (\n artifact_id TEXT PRIMARY KEY,\n run_id TEXT NOT NULL,\n node_id TEXT NOT NULL,\n attempt_id TEXT,\n path TEXT NOT NULL,\n kind TEXT NOT NULL\n CHECK (kind IN ('evidence','patch','result','checkpoint','contract')),\n sha256 TEXT,\n size_bytes INTEGER,\n created_at TEXT NOT NULL,\n FOREIGN KEY (run_id, node_id) REFERENCES nodes(run_id, node_id) ON DELETE CASCADE,\n FOREIGN KEY (attempt_id) REFERENCES attempts(attempt_id) ON DELETE SET NULL\n);\n\nCREATE TABLE IF NOT EXISTS worktrees (\n worktree_id TEXT PRIMARY KEY,\n run_id TEXT NOT NULL,\n node_id TEXT NOT NULL,\n path TEXT NOT NULL,\n branch_name TEXT NOT NULL,\n status TEXT NOT NULL DEFAULT 'active'\n CHECK (status IN ('active','merged','reclaimed','orphaned')),\n created_at TEXT NOT NULL,\n FOREIGN KEY (run_id, node_id) REFERENCES nodes(run_id, node_id) ON DELETE CASCADE\n);\n\nCREATE TABLE IF NOT EXISTS merge_queue (\n queue_id TEXT PRIMARY KEY,\n run_id TEXT NOT NULL,\n node_id TEXT NOT NULL,\n branch_name TEXT NOT NULL,\n target_branch TEXT NOT NULL DEFAULT 'main',\n status TEXT NOT NULL DEFAULT 'pending'\n CHECK (status IN ('pending','merging','merged','conflict','blocked')),\n priority INTEGER NOT NULL DEFAULT 0,\n dag_depth INTEGER NOT NULL DEFAULT 0,\n lease_finished_at TEXT,\n created_at TEXT NOT NULL,\n merged_at TEXT,\n FOREIGN KEY (run_id, node_id) REFERENCES nodes(run_id, node_id) ON DELETE CASCADE\n);\n\nCREATE TABLE IF NOT EXISTS compensators (\n compensator_id TEXT PRIMARY KEY,\n run_id TEXT NOT NULL,\n node_id TEXT NOT NULL,\n kind TEXT NOT NULL,\n sequence INTEGER NOT NULL,\n idempotent INTEGER NOT NULL DEFAULT 1,\n applied INTEGER NOT NULL DEFAULT 0,\n prepared_state_hash TEXT,\n created_at TEXT NOT NULL,\n FOREIGN KEY (run_id, node_id) REFERENCES nodes(run_id, node_id) ON DELETE CASCADE,\n UNIQUE (run_id, node_id, sequence)\n);\n\nCREATE TABLE IF NOT EXISTS events (\n event_id TEXT PRIMARY KEY,\n run_id TEXT NOT NULL,\n operation_id TEXT NOT NULL,\n causation_id TEXT,\n sequence INTEGER NOT NULL,\n timestamp TEXT NOT NULL,\n kind TEXT NOT NULL,\n status TEXT NOT NULL,\n node_id TEXT,\n data TEXT NOT NULL,\n FOREIGN KEY (run_id) REFERENCES runs(run_id) ON DELETE CASCADE\n);\n\nCREATE INDEX IF NOT EXISTS idx_nodes_dispatch\n ON nodes(run_id, status, retry_wait_until, priority, attempt_count)\n WHERE status IN ('queued','retry_wait');\nCREATE INDEX IF NOT EXISTS idx_nodes_lease ON nodes(run_id, lease_id);\nCREATE INDEX IF NOT EXISTS idx_nodes_expired\n ON nodes(lease_expires_at)\n WHERE status = 'leased' OR status = 'running' OR status = 'verifying';\nCREATE INDEX IF NOT EXISTS idx_edges_to ON edges(run_id, to_node_id);\nCREATE INDEX IF NOT EXISTS idx_edges_from ON edges(run_id, from_node_id);\nCREATE INDEX IF NOT EXISTS idx_access_node ON access(run_id, node_id);\nCREATE INDEX IF NOT EXISTS idx_conflicts_run ON conflicts(run_id, node_a, node_b);\nCREATE INDEX IF NOT EXISTS idx_artifacts_path ON artifacts(run_id, path);\nCREATE INDEX IF NOT EXISTS idx_events_run_seq ON events(run_id, sequence);\nCREATE INDEX IF NOT EXISTS idx_events_node ON events(run_id, node_id, sequence);\n`;\n\n/**\n * Thrown when a DAG re-submission reuses an existing `node_id` within a run but\n * supplies a different canonical descriptor. DAGs are immutable within a run:\n * identical re-submissions are idempotent replays, but a changed definition for\n * an existing node id is a divergence the store surfaces fail-closed instead of\n * silently keeping the old or overwriting with the new.\n */\nexport class NodeRedefinitionError extends Error {\n\treadonly runId: string;\n\treadonly nodeId: string;\n\tconstructor(runId: string, nodeId: string) {\n\t\tsuper(\n\t\t\t`node \"${nodeId}\" in run \"${runId}\" was redefined with a different descriptor; DAGs are immutable within a run`,\n\t\t);\n\t\tthis.name = \"NodeRedefinitionError\";\n\t\tthis.runId = runId;\n\t\tthis.nodeId = nodeId;\n\t}\n}\n\n/** Default retry policy applied when a node omits one. */\nexport const DEFAULT_RETRY_POLICY: RetryPolicy = {\n\tmaxAttempts: 3,\n\tbaseMs: 1000,\n\tmaxMs: 30000,\n\tmultiplier: 2,\n};\n\n/**\n * Canonicalize one access entry: drop undefined symbols, sort symbols, so the\n * stable key never depends on declaration order.\n */\nexport function canonicalizeAccessEntry(entry: AccessSetEntry): { path: string; symbols: string[] } {\n\tconst symbols = entry.symbols === undefined ? [] : [...entry.symbols].sort(compareString);\n\treturn { path: entry.path, symbols };\n}\n\n/** Canonicalize an access set: canonicalize each entry, then sort entries. */\nexport function canonicalizeAccessSet(\n\tentries: readonly AccessSetEntry[] | undefined,\n): { path: string; symbols: string[] }[] {\n\tconst canonical = (entries ?? []).map(canonicalizeAccessEntry);\n\tcanonical.sort((a, b) => {\n\t\tconst byPath = compareString(a.path, b.path);\n\t\tif (byPath !== 0) {\n\t\t\treturn byPath;\n\t\t}\n\t\treturn compareString(stableStringify(a.symbols), stableStringify(b.symbols));\n\t});\n\treturn canonical;\n}\n\n/**\n * Deterministic node descriptor used for idempotency. Excludes runtime state\n * (status, leases, counters) so identical logical work always hashes the same.\n */\nexport function canonicalNodeDescriptor(node: NodeInput): JsonValue {\n\treturn {\n\t\tnodeId: node.nodeId,\n\t\trole: node.role,\n\t\ttask: node.task,\n\t\tpriority: node.priority ?? 0,\n\t\tparallelizable: node.parallelizable ?? true,\n\t\treadSet: canonicalizeAccessSet(node.readSet),\n\t\twriteSet: canonicalizeAccessSet(node.writeSet),\n\t};\n}\n\n/**\n * Stable idempotency key: `sha256(stableStringify({runId, descriptor}))`.\n * Two submissions of identical logical work produce the same key, so DAG\n * ingestion can deduplicate across root-coordinator retries (foundation §6.5).\n */\nexport function computeIdempotencyKey(runId: string, node: NodeInput): string {\n\treturn sha256Hex(stableStringify({ runId, descriptor: canonicalNodeDescriptor(node) }));\n}\n\n/** Stable hash over the whole DAG (nodes + edges), order-independent. */\nexport function computeDagHash(submission: DagSubmission): string {\n\tconst nodes = submission.nodes.map(canonicalNodeDescriptor);\n\tnodes.sort((a, b) => compareString(stableStringify(a), stableStringify(b)));\n\tconst edges = (submission.edges ?? []).map((edge) => ({\n\t\tfromNodeId: edge.fromNodeId,\n\t\ttoNodeId: edge.toNodeId,\n\t\tedgeType: edge.edgeType ?? \"strong\",\n\t}));\n\tedges.sort((a, b) => compareString(stableStringify(a), stableStringify(b)));\n\treturn sha256Hex(stableStringify({ runId: submission.run.runId, nodes, edges }));\n}\n\n/**\n * Classify the conflict between two nodes in canonical (nodeA < nodeB) order.\n *\n * Existence is decided by the shared pure policy `nodesConflict`; the label is\n * derived from the same atomic `accessEntriesConflict` predicate. Precedence is\n * deterministic: write/write, then write/read, then read/write. Returns\n * undefined when the nodes do not conflict.\n */\nexport function classifyConflict(nodeA: SchedulerNode, nodeB: SchedulerNode): ConflictReason | undefined {\n\tif (!nodesConflict(nodeA, nodeB)) {\n\t\treturn undefined;\n\t}\n\tif (setsConflict(nodeA.writeSet, nodeB.writeSet)) {\n\t\treturn \"write-write\";\n\t}\n\tif (setsConflict(nodeA.writeSet, nodeB.readSet)) {\n\t\treturn \"write-read\";\n\t}\n\tif (setsConflict(nodeA.readSet, nodeB.writeSet)) {\n\t\treturn \"read-write\";\n\t}\n\t// nodesConflict was true, so one of the above must hold; fall back defensively.\n\treturn \"write-write\";\n}\n\nfunction setsConflict(left: readonly AccessSetEntry[], right: readonly AccessSetEntry[]): boolean {\n\tfor (const l of left) {\n\t\tfor (const r of right) {\n\t\t\tif (accessEntriesConflict(l, r)) {\n\t\t\t\treturn true;\n\t\t\t}\n\t\t}\n\t}\n\treturn false;\n}\n\nfunction compareString(a: string, b: string): number {\n\tif (a < b) {\n\t\treturn -1;\n\t}\n\tif (a > b) {\n\t\treturn 1;\n\t}\n\treturn 0;\n}\n"]}
|
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* `node:sqlite` (DatabaseSync) implementation of {@link SchedulerStore}.
|
|
3
|
+
*
|
|
4
|
+
* This is the default durable driver for the DAG scheduler. It owns ONLY
|
|
5
|
+
* persistence: schema creation, WAL pragmas, idempotent DAG ingestion, conflict
|
|
6
|
+
* graph materialization (reusing the pure conflict policy), and owner-token
|
|
7
|
+
* fenced lease lifecycle. It performs NO scheduling decisions and NO runtime
|
|
8
|
+
* wiring — the dispatch engine consumes this store through the interface.
|
|
9
|
+
*
|
|
10
|
+
* Determinism: every method takes explicit ISO-8601 timestamps where time
|
|
11
|
+
* matters, so tests drive it with fixed clocks. Guard-based CAS is implemented
|
|
12
|
+
* with `UPDATE ... WHERE <guard>` and the `changes` count returned by the
|
|
13
|
+
* driver. Erasable TypeScript only (no enum/namespace/parameter properties).
|
|
14
|
+
*
|
|
15
|
+
* Schema source of truth: `scheduler-store.ts`. Conflict policy: `scheduler-state.ts`.
|
|
16
|
+
*/
|
|
17
|
+
import { type JsonValue } from "./replay-ledger.ts";
|
|
18
|
+
import { type ArtifactInput, type AttemptInput, type CompensatorInput, type ConflictEdge, type DagIngestionResult, type DagSubmission, type EdgeRow, type LeaseInput, type LeaseRow, type NodeRow, type RunInput, type RunRow, type RunStatus, type SchedulerEventInput, type SchedulerEventRow, type SchedulerStore, type WorktreeInput } from "./scheduler-store.ts";
|
|
19
|
+
export declare class SqliteSchedulerStore implements SchedulerStore {
|
|
20
|
+
private db;
|
|
21
|
+
/** Construct a store; optionally open a database immediately. */
|
|
22
|
+
constructor(path?: string);
|
|
23
|
+
open(path: string): void;
|
|
24
|
+
close(): void;
|
|
25
|
+
createSchema(): void;
|
|
26
|
+
exec(sql: string): void;
|
|
27
|
+
pragma(name: string): JsonValue;
|
|
28
|
+
createRun(run: RunInput): void;
|
|
29
|
+
getRun(runId: string): RunRow | undefined;
|
|
30
|
+
updateRunStatus(runId: string, status: RunStatus, now?: string): boolean;
|
|
31
|
+
ingestDag(submission: DagSubmission): DagIngestionResult;
|
|
32
|
+
private insertNode;
|
|
33
|
+
getNode(runId: string, nodeId: string): NodeRow | undefined;
|
|
34
|
+
getNodesByRun(runId: string): NodeRow[];
|
|
35
|
+
getEdgesByRun(runId: string): EdgeRow[];
|
|
36
|
+
buildConflictGraph(runId: string): ConflictEdge[];
|
|
37
|
+
getConflicts(runId: string): ConflictEdge[];
|
|
38
|
+
acquireLease(runId: string, nodeId: string, lease: LeaseInput): boolean;
|
|
39
|
+
heartbeat(runId: string, nodeId: string, ownerToken: string, now: string, expiresAt: string): boolean;
|
|
40
|
+
startNode(runId: string, nodeId: string, ownerToken: string, now: string): boolean;
|
|
41
|
+
reclaimExpiredLeases(runId: string, now: string): string[];
|
|
42
|
+
getLease(leaseId: string): LeaseRow | undefined;
|
|
43
|
+
recordAttempt(attempt: AttemptInput): void;
|
|
44
|
+
getAttemptsByRun(runId: string): AttemptInput[];
|
|
45
|
+
registerWorktree(worktree: WorktreeInput): void;
|
|
46
|
+
getWorktreesByRun(runId: string): WorktreeInput[];
|
|
47
|
+
registerCompensator(compensator: CompensatorInput): void;
|
|
48
|
+
getCompensatorsByNode(runId: string, nodeId: string): CompensatorInput[];
|
|
49
|
+
recordArtifact(artifact: ArtifactInput): void;
|
|
50
|
+
getArtifactsByRun(runId: string): ArtifactInput[];
|
|
51
|
+
appendEvent(event: SchedulerEventInput): void;
|
|
52
|
+
getEvents(runId: string): SchedulerEventRow[];
|
|
53
|
+
private connection;
|
|
54
|
+
/** Run `fn` inside a single transaction; rollback on throw. */
|
|
55
|
+
private transaction;
|
|
56
|
+
}
|
|
57
|
+
//# sourceMappingURL=sqlite-scheduler-store.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"sqlite-scheduler-store.d.ts","sourceRoot":"","sources":["../../../src/core/orchestration/sqlite-scheduler-store.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * `node:sqlite` (DatabaseSync) implementation of {@link SchedulerStore}.\n *\n * This is the default durable driver for the DAG scheduler. It owns ONLY\n * persistence: schema creation, WAL pragmas, idempotent DAG ingestion, conflict\n * graph materialization (reusing the pure conflict policy), and owner-token\n * fenced lease lifecycle. It performs NO scheduling decisions and NO runtime\n * wiring — the dispatch engine consumes this store through the interface.\n *\n * Determinism: every method takes explicit ISO-8601 timestamps where time\n * matters, so tests drive it with fixed clocks. Guard-based CAS is implemented\n * with `UPDATE ... WHERE <guard>` and the `changes` count returned by the\n * driver. Erasable TypeScript only (no enum/namespace/parameter properties).\n *\n * Schema source of truth: `scheduler-store.ts`. Conflict policy: `scheduler-state.ts`.\n */\n\nimport { DatabaseSync } from \"node:sqlite\";\nimport { type JsonValue, stableStringify } from \"./replay-ledger.ts\";\nimport type { AccessSetEntry, SchedulerNode } from \"./scheduler-state.ts\";\nimport {\n\ttype ArtifactInput,\n\ttype AttemptInput,\n\ttype CompensatorInput,\n\ttype ConflictEdge,\n\tclassifyConflict,\n\tcomputeDagHash,\n\tcomputeIdempotencyKey,\n\ttype DagIngestionResult,\n\ttype DagSubmission,\n\tDEFAULT_RETRY_POLICY,\n\ttype EdgeRow,\n\ttype LeaseInput,\n\ttype LeaseRow,\n\ttype NodeInput,\n\tNodeRedefinitionError,\n\ttype NodeRow,\n\ttype RunInput,\n\ttype RunRow,\n\ttype RunStatus,\n\tSCHEDULER_STORE_PRAGMAS,\n\tSCHEDULER_STORE_SCHEMA,\n\ttype SchedulerEventInput,\n\ttype SchedulerEventRow,\n\ttype SchedulerStore,\n\ttype WorktreeInput,\n} from \"./scheduler-store.ts\";\n\n/** A single row returned by the driver: column name -> scalar value. */\ntype SqliteRow = Record<string, string | number | bigint | null | Uint8Array>;\n\nexport class SqliteSchedulerStore implements SchedulerStore {\n\tprivate db: DatabaseSync | null = null;\n\n\t/** Construct a store; optionally open a database immediately. */\n\tconstructor(path?: string) {\n\t\tif (path !== undefined) {\n\t\t\tthis.open(path);\n\t\t}\n\t}\n\n\topen(path: string): void {\n\t\tif (this.db !== null) {\n\t\t\tthrow new Error(\"SqliteSchedulerStore is already open\");\n\t\t}\n\t\tthis.db = new DatabaseSync(path);\n\t\tfor (const pragma of SCHEDULER_STORE_PRAGMAS) {\n\t\t\tthis.db.exec(pragma);\n\t\t}\n\t}\n\n\tclose(): void {\n\t\tif (this.db !== null) {\n\t\t\tthis.db.close();\n\t\t\tthis.db = null;\n\t\t}\n\t}\n\n\tcreateSchema(): void {\n\t\tthis.connection().exec(SCHEDULER_STORE_SCHEMA);\n\t}\n\n\texec(sql: string): void {\n\t\tthis.connection().exec(sql);\n\t}\n\n\tpragma(name: string): JsonValue {\n\t\tconst row = this.connection().prepare(`PRAGMA ${name}`).get() as SqliteRow | undefined;\n\t\tif (row === undefined) {\n\t\t\treturn null;\n\t\t}\n\t\tconst keys = Object.keys(row);\n\t\tif (keys.length === 0) {\n\t\t\treturn null;\n\t\t}\n\t\treturn scalar(row[keys[0]]);\n\t}\n\n\t// --- run lifecycle ---------------------------------------------------------\n\n\tcreateRun(run: RunInput): void {\n\t\tconst now = nowIso();\n\t\tthis.connection()\n\t\t\t.prepare(\n\t\t\t\t`INSERT INTO runs (run_id, goal, topology, status, created_at, updated_at, dag_hash, root_node_id)\n\t\t\t\t VALUES (?, ?, ?, 'running', ?, ?, ?, ?)`,\n\t\t\t)\n\t\t\t.run(run.runId, run.goal, run.topology, now, now, run.dagHash ?? null, run.rootNodeId ?? null);\n\t}\n\n\tgetRun(runId: string): RunRow | undefined {\n\t\tconst row = this.connection().prepare(`SELECT * FROM runs WHERE run_id = ?`).get(runId) as SqliteRow | undefined;\n\t\treturn row === undefined ? undefined : mapRunRow(row);\n\t}\n\n\tupdateRunStatus(runId: string, status: RunStatus, now?: string): boolean {\n\t\tconst ts = now ?? nowIso();\n\t\tconst completedAt = status === \"completed\" || status === \"failed\" || status === \"cancelled\" ? ts : null;\n\t\tconst result = this.connection()\n\t\t\t.prepare(\n\t\t\t\t`UPDATE runs\n\t\t\t\t SET status = ?, updated_at = ?, completed_at = COALESCE(?, completed_at)\n\t\t\t\t WHERE run_id = ?`,\n\t\t\t)\n\t\t\t.run(status, ts, completedAt, runId);\n\t\treturn changed(result);\n\t}\n\n\t// --- DAG ingestion (idempotent) -------------------------------------------\n\n\tingestDag(submission: DagSubmission): DagIngestionResult {\n\t\tconst db = this.connection();\n\t\tconst dagHash = computeDagHash(submission);\n\t\tconst nodeIds: string[] = [];\n\t\tconst insertedNodeIds: string[] = [];\n\t\tconst reusedNodeIds: string[] = [];\n\n\t\tthis.transaction(() => {\n\t\t\tconst now = nowIso();\n\t\t\t// Run header: insert once; never overwrite on replay.\n\t\t\tdb.prepare(\n\t\t\t\t`INSERT OR IGNORE INTO runs (run_id, goal, topology, status, created_at, updated_at, dag_hash, root_node_id)\n\t\t\t\t VALUES (?, ?, ?, 'running', ?, ?, ?, ?)`,\n\t\t\t).run(\n\t\t\t\tsubmission.run.runId,\n\t\t\t\tsubmission.run.goal,\n\t\t\t\tsubmission.run.topology,\n\t\t\t\tnow,\n\t\t\t\tnow,\n\t\t\t\tdagHash,\n\t\t\t\tsubmission.run.rootNodeId ?? null,\n\t\t\t);\n\n\t\t\tfor (const node of submission.nodes) {\n\t\t\t\tconst key = computeIdempotencyKey(submission.run.runId, node);\n\t\t\t\t// Identity is (run_id, node_id). The idempotency key (which itself\n\t\t\t\t// includes node_id) distinguishes a true replay from a redefinition.\n\t\t\t\tconst existing = db\n\t\t\t\t\t.prepare(`SELECT idempotency_key FROM nodes WHERE run_id = ? AND node_id = ?`)\n\t\t\t\t\t.get(submission.run.runId, node.nodeId) as SqliteRow | undefined;\n\t\t\t\tif (existing !== undefined) {\n\t\t\t\t\tif (asString(existing.idempotency_key) !== key) {\n\t\t\t\t\t\tthrow new NodeRedefinitionError(submission.run.runId, node.nodeId);\n\t\t\t\t\t}\n\t\t\t\t\tnodeIds.push(node.nodeId);\n\t\t\t\t\treusedNodeIds.push(node.nodeId);\n\t\t\t\t\tcontinue;\n\t\t\t\t}\n\t\t\t\tthis.insertNode(submission.run.runId, node, key, now);\n\t\t\t\tnodeIds.push(node.nodeId);\n\t\t\t\tinsertedNodeIds.push(node.nodeId);\n\t\t\t}\n\n\t\t\tfor (const edge of submission.edges ?? []) {\n\t\t\t\tdb.prepare(\n\t\t\t\t\t`INSERT OR IGNORE INTO edges (run_id, from_node_id, to_node_id, edge_type)\n\t\t\t\t\t VALUES (?, ?, ?, ?)`,\n\t\t\t\t).run(submission.run.runId, edge.fromNodeId, edge.toNodeId, edge.edgeType ?? \"strong\");\n\t\t\t}\n\t\t});\n\n\t\treturn { runId: submission.run.runId, dagHash, nodeIds, insertedNodeIds, reusedNodeIds };\n\t}\n\n\tprivate insertNode(runId: string, node: NodeInput, idempotencyKey: string, now: string): void {\n\t\tconst db = this.connection();\n\t\tconst readSet = (node.readSet ?? []).map(normalizeAccessEntry);\n\t\tconst writeSet = (node.writeSet ?? []).map(normalizeAccessEntry);\n\t\tdb.prepare(\n\t\t\t`INSERT INTO nodes (\n\t\t\t\tnode_id, run_id, role, task, status, idempotency_key,\n\t\t\t\tread_set, write_set, retry_policy, verification_contract, cost_budget,\n\t\t\t\tcreated_at, priority, parallelizable\n\t\t\t ) VALUES (?, ?, ?, ?, 'queued', ?, ?, ?, ?, ?, ?, ?, ?, ?)`,\n\t\t).run(\n\t\t\tnode.nodeId,\n\t\t\trunId,\n\t\t\tnode.role,\n\t\t\tnode.task,\n\t\t\tidempotencyKey,\n\t\t\tJSON.stringify(readSet),\n\t\t\tJSON.stringify(writeSet),\n\t\t\tJSON.stringify(node.retryPolicy ?? DEFAULT_RETRY_POLICY),\n\t\t\tnode.verificationContract ?? null,\n\t\t\tnode.costBudget ?? null,\n\t\t\tnow,\n\t\t\tnode.priority ?? 0,\n\t\t\tnode.parallelizable === false ? 0 : 1,\n\t\t);\n\n\t\tconst insertAccess = db.prepare(\n\t\t\t`INSERT OR IGNORE INTO access (access_id, run_id, node_id, kind, path, symbols)\n\t\t\t VALUES (?, ?, ?, ?, ?, ?)`,\n\t\t);\n\t\tfor (const entry of readSet) {\n\t\t\tinsertAccess.run(\n\t\t\t\taccessId(runId, node.nodeId, \"read\", entry),\n\t\t\t\trunId,\n\t\t\t\tnode.nodeId,\n\t\t\t\t\"read\",\n\t\t\t\tentry.path,\n\t\t\t\tJSON.stringify(entry.symbols),\n\t\t\t);\n\t\t}\n\t\tfor (const entry of writeSet) {\n\t\t\tinsertAccess.run(\n\t\t\t\taccessId(runId, node.nodeId, \"write\", entry),\n\t\t\t\trunId,\n\t\t\t\tnode.nodeId,\n\t\t\t\t\"write\",\n\t\t\t\tentry.path,\n\t\t\t\tJSON.stringify(entry.symbols),\n\t\t\t);\n\t\t}\n\t}\n\n\tgetNode(runId: string, nodeId: string): NodeRow | undefined {\n\t\tconst row = this.connection()\n\t\t\t.prepare(`SELECT * FROM nodes WHERE run_id = ? AND node_id = ?`)\n\t\t\t.get(runId, nodeId) as SqliteRow | undefined;\n\t\treturn row === undefined ? undefined : mapNodeRow(row);\n\t}\n\n\tgetNodesByRun(runId: string): NodeRow[] {\n\t\tconst rows = this.connection()\n\t\t\t.prepare(`SELECT * FROM nodes WHERE run_id = ? ORDER BY node_id ASC`)\n\t\t\t.all(runId) as SqliteRow[];\n\t\treturn rows.map(mapNodeRow);\n\t}\n\n\tgetEdgesByRun(runId: string): EdgeRow[] {\n\t\tconst rows = this.connection()\n\t\t\t.prepare(`SELECT * FROM edges WHERE run_id = ? ORDER BY from_node_id ASC, to_node_id ASC`)\n\t\t\t.all(runId) as SqliteRow[];\n\t\treturn rows.map((row) => ({\n\t\t\trunId: asString(row.run_id),\n\t\t\tfromNodeId: asString(row.from_node_id),\n\t\t\ttoNodeId: asString(row.to_node_id),\n\t\t\tedgeType: asString(row.edge_type) === \"weak\" ? \"weak\" : \"strong\",\n\t\t}));\n\t}\n\n\t// --- conflict graph --------------------------------------------------------\n\n\tbuildConflictGraph(runId: string): ConflictEdge[] {\n\t\tconst nodes = this.getNodesByRun(runId);\n\t\tconst schedulerNodes = nodes.map(toSchedulerNode);\n\t\tconst edges: ConflictEdge[] = [];\n\n\t\tthis.transaction(() => {\n\t\t\tconst db = this.connection();\n\t\t\tdb.prepare(`DELETE FROM conflicts WHERE run_id = ?`).run(runId);\n\t\t\tconst insert = db.prepare(\n\t\t\t\t`INSERT OR IGNORE INTO conflicts (run_id, node_a, node_b, reason) VALUES (?, ?, ?, ?)`,\n\t\t\t);\n\t\t\tfor (let i = 0; i < schedulerNodes.length; i += 1) {\n\t\t\t\tfor (let j = i + 1; j < schedulerNodes.length; j += 1) {\n\t\t\t\t\t// Canonical order: nodeA < nodeB (getNodesByRun already sorts by node_id).\n\t\t\t\t\tconst a = schedulerNodes[i];\n\t\t\t\t\tconst b = schedulerNodes[j];\n\t\t\t\t\tconst reason = classifyConflict(a, b);\n\t\t\t\t\tif (reason === undefined) {\n\t\t\t\t\t\tcontinue;\n\t\t\t\t\t}\n\t\t\t\t\tinsert.run(runId, a.nodeId, b.nodeId, reason);\n\t\t\t\t\tedges.push({ runId, nodeA: a.nodeId, nodeB: b.nodeId, reason });\n\t\t\t\t}\n\t\t\t}\n\t\t});\n\n\t\treturn edges;\n\t}\n\n\tgetConflicts(runId: string): ConflictEdge[] {\n\t\tconst rows = this.connection()\n\t\t\t.prepare(`SELECT * FROM conflicts WHERE run_id = ? ORDER BY node_a ASC, node_b ASC`)\n\t\t\t.all(runId) as SqliteRow[];\n\t\treturn rows.map((row) => ({\n\t\t\trunId: asString(row.run_id),\n\t\t\tnodeA: asString(row.node_a),\n\t\t\tnodeB: asString(row.node_b),\n\t\t\treason: asString(row.reason) as ConflictEdge[\"reason\"],\n\t\t}));\n\t}\n\n\t// --- lease lifecycle (owner-token fenced) ----------------------------------\n\n\tacquireLease(runId: string, nodeId: string, lease: LeaseInput): boolean {\n\t\tconst db = this.connection();\n\t\tlet acquired = false;\n\t\tthis.transaction(() => {\n\t\t\tconst result = db\n\t\t\t\t.prepare(\n\t\t\t\t\t`UPDATE nodes\n\t\t\t\t\t SET status = 'leased', lease_id = ?, lease_expires_at = ?, heartbeat_at = NULL,\n\t\t\t\t\t\t attempt_count = attempt_count + 1\n\t\t\t\t\t WHERE run_id = ? AND node_id = ? AND status = 'queued'`,\n\t\t\t\t)\n\t\t\t\t.run(lease.leaseId, lease.expiresAt, runId, nodeId);\n\t\t\tif (!changed(result)) {\n\t\t\t\t// Guard lost (already leased / not queued): leave the transaction a no-op.\n\t\t\t\treturn;\n\t\t\t}\n\t\t\tdb.prepare(\n\t\t\t\t`INSERT INTO leases (lease_id, run_id, node_id, issued_at, expires_at, heartbeat_at, owner_token, released)\n\t\t\t\t VALUES (?, ?, ?, ?, ?, NULL, ?, 0)`,\n\t\t\t).run(lease.leaseId, runId, nodeId, lease.now ?? nowIso(), lease.expiresAt, lease.ownerToken);\n\t\t\tacquired = true;\n\t\t});\n\t\treturn acquired;\n\t}\n\n\theartbeat(runId: string, nodeId: string, ownerToken: string, now: string, expiresAt: string): boolean {\n\t\tconst db = this.connection();\n\t\tlet ok = false;\n\t\tthis.transaction(() => {\n\t\t\tconst result = db\n\t\t\t\t.prepare(\n\t\t\t\t\t`UPDATE leases\n\t\t\t\t\t SET heartbeat_at = ?, expires_at = ?\n\t\t\t\t\t WHERE run_id = ? AND node_id = ? AND owner_token = ? AND released = 0`,\n\t\t\t\t)\n\t\t\t\t.run(now, expiresAt, runId, nodeId, ownerToken);\n\t\t\tif (!changed(result)) {\n\t\t\t\treturn;\n\t\t\t}\n\t\t\t// Mirror the extension onto the scheduler's node view (reclaim reads nodes).\n\t\t\tdb.prepare(\n\t\t\t\t`UPDATE nodes\n\t\t\t\t SET heartbeat_at = ?, lease_expires_at = ?\n\t\t\t\t WHERE run_id = ? AND node_id = ?\n\t\t\t\t AND lease_id IN (SELECT lease_id FROM leases\n\t\t\t\t\t\t\t\t\tWHERE run_id = ? AND node_id = ? AND owner_token = ? AND released = 0)`,\n\t\t\t).run(now, expiresAt, runId, nodeId, runId, nodeId, ownerToken);\n\t\t\tok = true;\n\t\t});\n\t\treturn ok;\n\t}\n\n\tstartNode(runId: string, nodeId: string, ownerToken: string, now: string): boolean {\n\t\tconst result = this.connection()\n\t\t\t.prepare(\n\t\t\t\t`UPDATE nodes\n\t\t\t\t SET status = 'running', started_at = ?, heartbeat_at = ?\n\t\t\t\t WHERE run_id = ? AND node_id = ? AND status = 'leased'\n\t\t\t\t AND lease_id IN (SELECT lease_id FROM leases\n\t\t\t\t\t\t\t\t\tWHERE run_id = ? AND node_id = ? AND owner_token = ? AND released = 0)`,\n\t\t\t)\n\t\t\t.run(now, now, runId, nodeId, runId, nodeId, ownerToken);\n\t\treturn changed(result);\n\t}\n\n\treclaimExpiredLeases(runId: string, now: string): string[] {\n\t\tconst db = this.connection();\n\t\tconst reclaimed: string[] = [];\n\t\tthis.transaction(() => {\n\t\t\tconst rows = db\n\t\t\t\t.prepare(\n\t\t\t\t\t`SELECT node_id, lease_id FROM nodes\n\t\t\t\t\t WHERE run_id = ?\n\t\t\t\t\t AND status IN ('leased','running','verifying')\n\t\t\t\t\t AND lease_expires_at IS NOT NULL\n\t\t\t\t\t AND lease_expires_at < ?`,\n\t\t\t\t)\n\t\t\t\t.all(runId, now) as SqliteRow[];\n\t\t\tfor (const row of rows) {\n\t\t\t\tconst nodeId = asString(row.node_id);\n\t\t\t\tconst leaseId = row.lease_id === null ? null : asString(row.lease_id);\n\t\t\t\tif (leaseId !== null) {\n\t\t\t\t\tdb.prepare(`UPDATE leases SET released = 1 WHERE lease_id = ?`).run(leaseId);\n\t\t\t\t}\n\t\t\t\tdb.prepare(\n\t\t\t\t\t`UPDATE nodes\n\t\t\t\t\t SET status = 'queued', lease_id = NULL, lease_expires_at = NULL, heartbeat_at = NULL,\n\t\t\t\t\t\t requeue_count = requeue_count + 1\n\t\t\t\t\t WHERE run_id = ? AND node_id = ?`,\n\t\t\t\t).run(runId, nodeId);\n\t\t\t\treclaimed.push(nodeId);\n\t\t\t}\n\t\t});\n\t\treturn reclaimed;\n\t}\n\n\tgetLease(leaseId: string): LeaseRow | undefined {\n\t\tconst row = this.connection().prepare(`SELECT * FROM leases WHERE lease_id = ?`).get(leaseId) as\n\t\t\t| SqliteRow\n\t\t\t| undefined;\n\t\tif (row === undefined) {\n\t\t\treturn undefined;\n\t\t}\n\t\treturn {\n\t\t\tleaseId: asString(row.lease_id),\n\t\t\trunId: asString(row.run_id),\n\t\t\tnodeId: asString(row.node_id),\n\t\t\tattemptId: row.attempt_id === null ? null : asString(row.attempt_id),\n\t\t\tissuedAt: asString(row.issued_at),\n\t\t\texpiresAt: asString(row.expires_at),\n\t\t\theartbeatAt: row.heartbeat_at === null ? null : asString(row.heartbeat_at),\n\t\t\townerToken: asString(row.owner_token),\n\t\t\treleased: asNumber(row.released) !== 0,\n\t\t};\n\t}\n\n\t// --- scaffolded sibling-lane tables ---------------------------------------\n\n\trecordAttempt(attempt: AttemptInput): void {\n\t\tthis.connection()\n\t\t\t.prepare(\n\t\t\t\t`INSERT INTO attempts (attempt_id, run_id, node_id, lease_id, started_at, finished_at, status,\n\t\t\t\t\t\t\t\t\t exit_code, error_summary, worker_pid)\n\t\t\t\t VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?)`,\n\t\t\t)\n\t\t\t.run(\n\t\t\t\tattempt.attemptId,\n\t\t\t\tattempt.runId,\n\t\t\t\tattempt.nodeId,\n\t\t\t\tattempt.leaseId,\n\t\t\t\tattempt.startedAt ?? nowIso(),\n\t\t\t\tattempt.finishedAt ?? null,\n\t\t\t\tattempt.status,\n\t\t\t\tattempt.exitCode ?? null,\n\t\t\t\tattempt.errorSummary === undefined ? null : stableStringify(attempt.errorSummary),\n\t\t\t\tattempt.workerPid ?? null,\n\t\t\t);\n\t}\n\n\tgetAttemptsByRun(runId: string): AttemptInput[] {\n\t\tconst rows = this.connection()\n\t\t\t.prepare(`SELECT * FROM attempts WHERE run_id = ? ORDER BY started_at ASC, attempt_id ASC`)\n\t\t\t.all(runId) as SqliteRow[];\n\t\treturn rows.map((row) => ({\n\t\t\tattemptId: asString(row.attempt_id),\n\t\t\trunId: asString(row.run_id),\n\t\t\tnodeId: asString(row.node_id),\n\t\t\tleaseId: asString(row.lease_id),\n\t\t\tstatus: asString(row.status) as AttemptInput[\"status\"],\n\t\t\tstartedAt: asString(row.started_at),\n\t\t\tfinishedAt: row.finished_at === null ? undefined : asString(row.finished_at),\n\t\t\texitCode: row.exit_code === null ? undefined : asNumber(row.exit_code),\n\t\t\terrorSummary: row.error_summary === null ? undefined : (JSON.parse(asString(row.error_summary)) as JsonValue),\n\t\t\tworkerPid: row.worker_pid === null ? undefined : asNumber(row.worker_pid),\n\t\t}));\n\t}\n\n\tregisterWorktree(worktree: WorktreeInput): void {\n\t\tthis.connection()\n\t\t\t.prepare(\n\t\t\t\t`INSERT INTO worktrees (worktree_id, run_id, node_id, path, branch_name, status, created_at)\n\t\t\t\t VALUES (?, ?, ?, ?, ?, ?, ?)`,\n\t\t\t)\n\t\t\t.run(\n\t\t\t\tworktree.worktreeId,\n\t\t\t\tworktree.runId,\n\t\t\t\tworktree.nodeId,\n\t\t\t\tworktree.path,\n\t\t\t\tworktree.branchName,\n\t\t\t\tworktree.status ?? \"active\",\n\t\t\t\tworktree.createdAt ?? nowIso(),\n\t\t\t);\n\t}\n\n\tgetWorktreesByRun(runId: string): WorktreeInput[] {\n\t\tconst rows = this.connection()\n\t\t\t.prepare(`SELECT * FROM worktrees WHERE run_id = ? ORDER BY worktree_id ASC`)\n\t\t\t.all(runId) as SqliteRow[];\n\t\treturn rows.map((row) => ({\n\t\t\tworktreeId: asString(row.worktree_id),\n\t\t\trunId: asString(row.run_id),\n\t\t\tnodeId: asString(row.node_id),\n\t\t\tpath: asString(row.path),\n\t\t\tbranchName: asString(row.branch_name),\n\t\t\tstatus: asString(row.status) as WorktreeInput[\"status\"],\n\t\t\tcreatedAt: asString(row.created_at),\n\t\t}));\n\t}\n\n\tregisterCompensator(compensator: CompensatorInput): void {\n\t\tthis.connection()\n\t\t\t.prepare(\n\t\t\t\t`INSERT INTO compensators (compensator_id, run_id, node_id, kind, sequence, idempotent, applied,\n\t\t\t\t\t\t\t\t\t\t prepared_state_hash, created_at)\n\t\t\t\t VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?)`,\n\t\t\t)\n\t\t\t.run(\n\t\t\t\tcompensator.compensatorId,\n\t\t\t\tcompensator.runId,\n\t\t\t\tcompensator.nodeId,\n\t\t\t\tcompensator.kind,\n\t\t\t\tcompensator.sequence,\n\t\t\t\tcompensator.idempotent ? 1 : 0,\n\t\t\t\tcompensator.applied ? 1 : 0,\n\t\t\t\tcompensator.preparedStateHash ?? null,\n\t\t\t\tcompensator.createdAt ?? nowIso(),\n\t\t\t);\n\t}\n\n\tgetCompensatorsByNode(runId: string, nodeId: string): CompensatorInput[] {\n\t\tconst rows = this.connection()\n\t\t\t.prepare(`SELECT * FROM compensators WHERE run_id = ? AND node_id = ? ORDER BY sequence ASC`)\n\t\t\t.all(runId, nodeId) as SqliteRow[];\n\t\treturn rows.map((row) => ({\n\t\t\tcompensatorId: asString(row.compensator_id),\n\t\t\trunId: asString(row.run_id),\n\t\t\tnodeId: asString(row.node_id),\n\t\t\tkind: asString(row.kind),\n\t\t\tsequence: asNumber(row.sequence),\n\t\t\tidempotent: asNumber(row.idempotent) !== 0,\n\t\t\tapplied: asNumber(row.applied) !== 0,\n\t\t\tpreparedStateHash: row.prepared_state_hash === null ? null : asString(row.prepared_state_hash),\n\t\t\tcreatedAt: asString(row.created_at),\n\t\t}));\n\t}\n\n\trecordArtifact(artifact: ArtifactInput): void {\n\t\tthis.connection()\n\t\t\t.prepare(\n\t\t\t\t`INSERT INTO artifacts (artifact_id, run_id, node_id, attempt_id, path, kind, sha256, size_bytes, created_at)\n\t\t\t\t VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?)`,\n\t\t\t)\n\t\t\t.run(\n\t\t\t\tartifact.artifactId,\n\t\t\t\tartifact.runId,\n\t\t\t\tartifact.nodeId,\n\t\t\t\tartifact.attemptId ?? null,\n\t\t\t\tartifact.path,\n\t\t\t\tartifact.kind,\n\t\t\t\tartifact.sha256 ?? null,\n\t\t\t\tartifact.sizeBytes ?? null,\n\t\t\t\tartifact.createdAt ?? nowIso(),\n\t\t\t);\n\t}\n\n\tgetArtifactsByRun(runId: string): ArtifactInput[] {\n\t\tconst rows = this.connection()\n\t\t\t.prepare(`SELECT * FROM artifacts WHERE run_id = ? ORDER BY path ASC, artifact_id ASC`)\n\t\t\t.all(runId) as SqliteRow[];\n\t\treturn rows.map((row) => ({\n\t\t\tartifactId: asString(row.artifact_id),\n\t\t\trunId: asString(row.run_id),\n\t\t\tnodeId: asString(row.node_id),\n\t\t\tattemptId: row.attempt_id === null ? undefined : asString(row.attempt_id),\n\t\t\tpath: asString(row.path),\n\t\t\tkind: asString(row.kind) as ArtifactInput[\"kind\"],\n\t\t\tsha256: row.sha256 === null ? undefined : asString(row.sha256),\n\t\t\tsizeBytes: row.size_bytes === null ? undefined : asNumber(row.size_bytes),\n\t\t\tcreatedAt: asString(row.created_at),\n\t\t}));\n\t}\n\n\t// --- ledger mirror ---------------------------------------------------------\n\n\tappendEvent(event: SchedulerEventInput): void {\n\t\tthis.connection()\n\t\t\t.prepare(\n\t\t\t\t`INSERT INTO events (event_id, run_id, operation_id, causation_id, sequence, timestamp, kind, status, node_id, data)\n\t\t\t\t VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?)`,\n\t\t\t)\n\t\t\t.run(\n\t\t\t\tevent.eventId,\n\t\t\t\tevent.runId,\n\t\t\t\tevent.operationId,\n\t\t\t\tevent.causationId ?? null,\n\t\t\t\tevent.sequence,\n\t\t\t\tevent.timestamp,\n\t\t\t\tevent.kind,\n\t\t\t\tevent.status,\n\t\t\t\tevent.nodeId ?? null,\n\t\t\t\tstableStringify(event.data ?? null),\n\t\t\t);\n\t}\n\n\tgetEvents(runId: string): SchedulerEventRow[] {\n\t\tconst rows = this.connection()\n\t\t\t.prepare(`SELECT * FROM events WHERE run_id = ? ORDER BY sequence ASC, event_id ASC`)\n\t\t\t.all(runId) as SqliteRow[];\n\t\treturn rows.map((row) => ({\n\t\t\teventId: asString(row.event_id),\n\t\t\trunId: asString(row.run_id),\n\t\t\toperationId: asString(row.operation_id),\n\t\t\tcausationId: row.causation_id === null ? null : asString(row.causation_id),\n\t\t\tsequence: asNumber(row.sequence),\n\t\t\ttimestamp: asString(row.timestamp),\n\t\t\tkind: asString(row.kind),\n\t\t\tstatus: asString(row.status),\n\t\t\tnodeId: row.node_id === null ? null : asString(row.node_id),\n\t\t\tdata: JSON.parse(asString(row.data)) as JsonValue,\n\t\t}));\n\t}\n\n\t// --- internals -------------------------------------------------------------\n\n\tprivate connection(): DatabaseSync {\n\t\tif (this.db === null) {\n\t\t\tthrow new Error(\"SqliteSchedulerStore is not open\");\n\t\t}\n\t\treturn this.db;\n\t}\n\n\t/** Run `fn` inside a single transaction; rollback on throw. */\n\tprivate transaction(fn: () => void): void {\n\t\tconst db = this.connection();\n\t\tdb.exec(\"BEGIN\");\n\t\ttry {\n\t\t\tfn();\n\t\t\tdb.exec(\"COMMIT\");\n\t\t} catch (error) {\n\t\t\tdb.exec(\"ROLLBACK\");\n\t\t\tthrow error;\n\t\t}\n\t}\n}\n\nfunction normalizeAccessEntry(entry: AccessSetEntry): { path: string; symbols: string[] } {\n\treturn { path: entry.path, symbols: entry.symbols === undefined ? [] : [...entry.symbols] };\n}\n\nfunction accessId(runId: string, nodeId: string, kind: string, entry: { path: string; symbols: string[] }): string {\n\treturn `${runId}\\u0000${nodeId}\\u0000${kind}\\u0000${entry.path}\\u0000${stableStringify([...entry.symbols].sort())}`;\n}\n\nfunction toSchedulerNode(row: NodeRow): SchedulerNode {\n\treturn {\n\t\tnodeId: row.nodeId,\n\t\tstatus: row.status,\n\t\tpriority: row.priority,\n\t\tparallelizable: row.parallelizable,\n\t\treadSet: row.readSet,\n\t\twriteSet: row.writeSet,\n\t};\n}\n\nfunction mapRunRow(row: SqliteRow): RunRow {\n\treturn {\n\t\trunId: asString(row.run_id),\n\t\tgoal: asString(row.goal),\n\t\ttopology: asString(row.topology),\n\t\tstatus: asString(row.status) as RunStatus,\n\t\tcreatedAt: asString(row.created_at),\n\t\tupdatedAt: asString(row.updated_at),\n\t\tcompletedAt: row.completed_at === null ? null : asString(row.completed_at),\n\t\tdagHash: row.dag_hash === null ? null : asString(row.dag_hash),\n\t\trootNodeId: row.root_node_id === null ? null : asString(row.root_node_id),\n\t};\n}\n\nfunction mapNodeRow(row: SqliteRow): NodeRow {\n\treturn {\n\t\tnodeId: asString(row.node_id),\n\t\trunId: asString(row.run_id),\n\t\trole: asString(row.role) as NodeRow[\"role\"],\n\t\ttask: asString(row.task),\n\t\tstatus: asString(row.status) as NodeRow[\"status\"],\n\t\tidempotencyKey: asString(row.idempotency_key),\n\t\treadSet: parseAccessSet(asString(row.read_set)),\n\t\twriteSet: parseAccessSet(asString(row.write_set)),\n\t\tleaseId: row.lease_id === null ? null : asString(row.lease_id),\n\t\tleaseExpiresAt: row.lease_expires_at === null ? null : asString(row.lease_expires_at),\n\t\theartbeatAt: row.heartbeat_at === null ? null : asString(row.heartbeat_at),\n\t\tattemptCount: asNumber(row.attempt_count),\n\t\trequeueCount: asNumber(row.requeue_count),\n\t\tretryWaitUntil: row.retry_wait_until === null ? null : asString(row.retry_wait_until),\n\t\tpriority: asNumber(row.priority),\n\t\tparallelizable: asNumber(row.parallelizable) !== 0,\n\t\tcreatedAt: asString(row.created_at),\n\t\tstartedAt: row.started_at === null ? null : asString(row.started_at),\n\t\tfinishedAt: row.finished_at === null ? null : asString(row.finished_at),\n\t};\n}\n\nfunction parseAccessSet(json: string): AccessSetEntry[] {\n\tconst parsed = JSON.parse(json) as Array<{ path: string; symbols?: string[] }>;\n\treturn parsed.map((entry) =>\n\t\tentry.symbols !== undefined && entry.symbols.length > 0\n\t\t\t? { path: entry.path, symbols: entry.symbols }\n\t\t\t: { path: entry.path },\n\t);\n}\n\nfunction changed(result: { changes: number | bigint }): boolean {\n\treturn Number(result.changes) > 0;\n}\n\nfunction scalar(value: string | number | bigint | null | Uint8Array): JsonValue {\n\tif (value === null) {\n\t\treturn null;\n\t}\n\tif (typeof value === \"bigint\") {\n\t\treturn Number(value);\n\t}\n\tif (value instanceof Uint8Array) {\n\t\treturn Buffer.from(value).toString(\"base64\");\n\t}\n\treturn value;\n}\n\nfunction asString(value: string | number | bigint | null | Uint8Array): string {\n\tif (typeof value === \"string\") {\n\t\treturn value;\n\t}\n\tif (value === null) {\n\t\tthrow new Error(\"expected string column, got null\");\n\t}\n\tif (typeof value === \"bigint\" || typeof value === \"number\") {\n\t\treturn String(value);\n\t}\n\tthrow new Error(\"expected string column, got blob\");\n}\n\nfunction asNumber(value: string | number | bigint | null | Uint8Array): number {\n\tif (typeof value === \"number\") {\n\t\treturn value;\n\t}\n\tif (typeof value === \"bigint\") {\n\t\treturn Number(value);\n\t}\n\tif (typeof value === \"string\") {\n\t\treturn Number(value);\n\t}\n\tthrow new Error(\"expected numeric column\");\n}\n\nfunction nowIso(): string {\n\treturn new Date().toISOString();\n}\n"]}
|