akm-cli 0.9.0-rc.0 → 0.9.0-rc.13
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 +1283 -22
- package/README.md +62 -37
- package/SECURITY.md +46 -31
- package/dist/akm +162 -38
- package/dist/akm-migrate +44 -0
- package/dist/assets/backends/schtasks-template.xml +2 -1
- package/dist/assets/hints/cli-hints-full.md +268 -118
- package/dist/assets/hints/cli-hints-short.md +87 -24
- package/dist/assets/{profiles → improve-strategies}/catchup.json +3 -1
- package/dist/assets/{profiles → improve-strategies}/consolidate.json +3 -1
- package/dist/assets/{profiles → improve-strategies}/default.json +6 -7
- package/dist/assets/improve-strategies/frequent.json +15 -0
- package/dist/assets/{profiles → improve-strategies}/graph-refresh.json +4 -2
- package/dist/assets/{profiles → improve-strategies}/memory-focus.json +4 -1
- package/dist/assets/{profiles → improve-strategies}/proactive-maintenance.json +5 -5
- package/dist/assets/{profiles → improve-strategies}/quick.json +4 -2
- package/dist/assets/improve-strategies/reflect-distill.json +30 -0
- package/dist/assets/{profiles → improve-strategies}/thorough.json +1 -1
- package/dist/assets/prompts/consolidate-system.md +5 -5
- package/dist/assets/prompts/extract-session.md +2 -6
- package/dist/assets/prompts/memory-infer-user.md +2 -3
- package/dist/assets/prompts/reflect-llm-framed-contract.md +11 -0
- package/dist/assets/prompts/reflect-llm-schema-contract.md +3 -0
- package/dist/assets/prompts/reflect-output-repair.md +3 -0
- package/dist/assets/prompts/workflow-unit-preamble.md +26 -0
- package/dist/assets/stash-skeleton/README.md +38 -10
- package/dist/assets/stash-skeleton/facts/conventions/assets/agent.md +8 -0
- package/dist/assets/stash-skeleton/facts/conventions/assets/command.md +8 -0
- package/dist/assets/stash-skeleton/facts/conventions/assets/fact.md +14 -1
- package/dist/assets/stash-skeleton/facts/conventions/assets/knowledge.md +13 -1
- package/dist/assets/stash-skeleton/facts/conventions/assets/lesson.md +9 -1
- package/dist/assets/stash-skeleton/facts/conventions/assets/memory.md +11 -0
- package/dist/assets/stash-skeleton/facts/conventions/assets/script.md +9 -0
- package/dist/assets/stash-skeleton/facts/conventions/assets/skill.md +9 -0
- package/dist/assets/stash-skeleton/facts/conventions/assets/workflow.md +8 -0
- package/dist/assets/stash-skeleton/facts/conventions/backlinks.md +100 -0
- package/dist/assets/stash-skeleton/facts/conventions/domains.md +64 -0
- package/dist/assets/stash-skeleton/facts/conventions/organization.md +136 -0
- package/dist/assets/tasks/core/extract.yml +3 -2
- package/dist/assets/tasks/core/improve.yml +2 -1
- package/dist/assets/tasks/core/index-refresh.yml +1 -0
- package/dist/assets/tasks/core/sync.yml +1 -0
- package/dist/assets/tasks/core/version-check.yml +2 -1
- package/dist/assets/tasks/improve/akm-graph-refresh-weekly.yml +5 -0
- package/dist/assets/tasks/improve/akm-improve-catchup.yml +8 -0
- package/dist/assets/tasks/improve/akm-improve-consolidate.yml +5 -0
- package/dist/assets/tasks/improve/akm-improve-frequent.yml +5 -0
- package/dist/assets/tasks/improve/akm-improve-nightly.yml +5 -0
- package/dist/assets/templates/html/health.html +5 -4
- package/dist/assets/workflows/workflow-template.md +31 -15
- package/dist/cli/invocation.js +279 -0
- package/dist/cli/parse-args.js +5 -90
- package/dist/cli/retired-commands.js +78 -0
- package/dist/cli/shared.js +158 -48
- package/dist/cli-node.mjs +2 -1
- package/dist/cli.js +747 -293
- package/dist/commands/agent/agent-dispatch.js +19 -18
- package/dist/commands/agent/agent-support.js +0 -24
- package/dist/commands/agent/contribute-cli.js +43 -97
- package/dist/commands/completions.js +80 -23
- package/dist/commands/config-cli.js +44 -281
- package/dist/commands/env/env-binding.js +99 -0
- package/dist/commands/env/env-cli.js +84 -224
- package/dist/commands/env/env.js +12 -163
- package/dist/commands/env/marker-path.js +6 -0
- package/dist/commands/env/secret-cli.js +45 -61
- package/dist/commands/env/secret.js +32 -62
- package/dist/commands/feedback-cli.js +179 -85
- package/dist/commands/health/accept-rate.js +58 -0
- package/dist/commands/health/advisories.js +7 -8
- package/dist/commands/health/checks.js +279 -94
- package/dist/commands/health/html-report.js +197 -578
- package/dist/commands/health/improve-metrics.js +277 -246
- package/dist/commands/health/llm-usage.js +19 -19
- package/dist/commands/health/md-report.js +16 -7
- package/dist/commands/health/metrics.js +67 -32
- package/dist/commands/health/renderers.js +47 -0
- package/dist/commands/health/report-view-model.js +508 -0
- package/dist/commands/health/stash-exposure.js +1 -1
- package/dist/commands/health/surfaces.js +16 -56
- package/dist/commands/health/task-runs.js +3 -67
- package/dist/{migrate-storage-node.mjs → commands/health/types-checks.js} +1 -5
- package/dist/commands/health/types-improve.js +29 -0
- package/dist/{output/text/save.js → commands/health/types-metrics.js} +1 -2
- package/dist/commands/health/types-result.js +7 -0
- package/dist/commands/health/types-runs.js +4 -0
- package/dist/commands/health/types-session-log.js +4 -0
- package/dist/commands/health/types-windows.js +4 -0
- package/dist/commands/health/types.js +26 -21
- package/dist/commands/health/windows.js +2 -3
- package/dist/commands/health.js +296 -167
- package/dist/commands/improve/anti-collapse.js +5 -5
- package/dist/commands/improve/autonomy-gate.js +68 -0
- package/dist/commands/improve/collapse-detector.js +65 -52
- package/dist/commands/improve/consolidate/chunking.js +9 -7
- package/dist/commands/improve/consolidate/eligibility.js +1 -23
- package/dist/commands/improve/consolidate/merge.js +4 -0
- package/dist/commands/improve/consolidate.js +454 -1354
- package/dist/commands/improve/content-hash.js +39 -0
- package/dist/commands/improve/distill/content-repair.js +4 -10
- package/dist/commands/improve/distill/promote-memory.js +89 -64
- package/dist/commands/improve/distill/quality-gate.js +118 -42
- package/dist/commands/improve/distill-guards.js +1 -1
- package/dist/commands/improve/distill-promotion-policy.js +33 -888
- package/dist/commands/improve/distill.js +607 -363
- package/dist/commands/improve/eligibility.js +165 -79
- package/dist/commands/improve/extract-cli.js +35 -126
- package/dist/commands/improve/extract-prompt.js +6 -35
- package/dist/commands/improve/extract.js +640 -391
- package/dist/commands/improve/feedback-valence.js +2 -12
- package/dist/commands/improve/improve-cli.js +134 -135
- package/dist/commands/improve/improve-result-file.js +30 -50
- package/dist/commands/improve/improve-run-types.js +4 -0
- package/dist/commands/improve/improve-strategies.js +135 -0
- package/dist/commands/improve/improve.js +904 -701
- package/dist/commands/improve/locks.js +64 -111
- package/dist/commands/improve/loop-stages.js +1110 -923
- package/dist/commands/improve/memory/derived-ref.js +124 -0
- package/dist/commands/improve/memory/memory-belief.js +79 -7
- package/dist/commands/improve/memory/memory-contradiction-detect.js +49 -52
- package/dist/commands/improve/memory/memory-improve.js +25 -37
- package/dist/commands/improve/outcome-loop.js +25 -88
- package/dist/commands/improve/preparation.js +1034 -813
- package/dist/commands/improve/proactive-maintenance.js +34 -9
- package/dist/commands/improve/proposal-envelope.js +31 -0
- package/dist/commands/improve/reflect.js +983 -794
- package/dist/commands/improve/run-context.js +119 -0
- package/dist/commands/improve/salience.js +24 -127
- package/dist/commands/improve/session-asset.js +7 -3
- package/dist/commands/improve/shared.js +14 -34
- package/dist/commands/improve/source-identity.js +28 -0
- package/dist/commands/improve/triage.js +20 -17
- package/dist/commands/lint/base-linter.js +340 -313
- package/dist/commands/lint/env-key-rules.js +31 -47
- package/dist/commands/lint/index.js +185 -30
- package/dist/commands/{events.js → log.js} +28 -38
- package/dist/commands/migrate-cli.js +54 -0
- package/dist/commands/migration-tool.js +55 -0
- package/dist/commands/observability-cli.js +70 -208
- package/dist/commands/proposal/diff-format.js +50 -0
- package/dist/commands/proposal/drain-policies.js +0 -6
- package/dist/commands/proposal/drain.js +91 -40
- package/dist/commands/proposal/proposal-cli.js +134 -132
- package/dist/commands/proposal/proposal-types.js +56 -0
- package/dist/commands/proposal/proposal.js +83 -65
- package/dist/commands/proposal/propose-cli.js +88 -0
- package/dist/commands/proposal/propose.js +105 -88
- package/dist/commands/proposal/repository.js +1303 -278
- package/dist/commands/proposal/validators/proposal-quality-validators.js +16 -6
- package/dist/commands/proposal/validators/proposal-validators.js +61 -12
- package/dist/commands/proposal/validators/proposals.js +6 -8
- package/dist/commands/read/curate.js +78 -73
- package/dist/commands/read/knowledge.js +510 -13
- package/dist/commands/read/registry-search.js +2 -2
- package/dist/commands/read/remember-cli.js +84 -15
- package/dist/commands/read/search-cli.js +203 -96
- package/dist/commands/read/search.js +126 -94
- package/dist/commands/read/show.js +226 -250
- package/dist/commands/registry-cli.js +34 -60
- package/dist/commands/remember.js +18 -57
- package/dist/commands/sources/add-cli.js +104 -49
- package/dist/commands/sources/bundle-cli.js +166 -0
- package/dist/commands/sources/bundle-config-ops.js +63 -0
- package/dist/commands/sources/info.js +27 -15
- package/dist/commands/sources/init.js +30 -40
- package/dist/commands/sources/installed-stashes.js +469 -172
- package/dist/commands/sources/migration-help.js +7 -4
- package/dist/commands/sources/schema-repair.js +10 -9
- package/dist/commands/sources/self-update.js +182 -121
- package/dist/commands/sources/source-add.js +169 -178
- package/dist/commands/sources/source-clone.js +144 -41
- package/dist/commands/sources/source-manage.js +94 -59
- package/dist/commands/sources/sources-cli.js +64 -205
- package/dist/commands/sources/stash-cli.js +91 -54
- package/dist/commands/sources/stash-skeleton.js +1 -1
- package/dist/commands/tasks/tasks-cli.js +106 -104
- package/dist/commands/tasks/tasks.js +445 -262
- package/dist/commands/workflow-cli.js +232 -121
- package/dist/core/action-contributors.js +1 -1
- package/dist/core/activation-policy.js +49 -0
- package/dist/core/adapter/adapters/agent-skills-adapter.js +181 -0
- package/dist/core/adapter/adapters/akm-adapter.js +528 -0
- package/dist/core/adapter/adapters/akm-lint.js +392 -0
- package/dist/core/adapter/adapters/akm-metadata.js +387 -0
- package/dist/core/adapter/adapters/akm-task-adapter.js +149 -0
- package/dist/core/adapter/adapters/akm-workflow-adapter.js +180 -0
- package/dist/core/adapter/adapters/claude-adapter.js +61 -0
- package/dist/core/adapter/adapters/dotenv-adapter.js +187 -0
- package/dist/core/adapter/adapters/generic-files-adapter.js +119 -0
- package/dist/core/adapter/adapters/index.js +80 -0
- package/dist/core/adapter/adapters/llm-wiki-adapter.js +419 -0
- package/dist/core/adapter/adapters/okf-adapter.js +391 -0
- package/dist/core/adapter/adapters/opencode-adapter.js +68 -0
- package/dist/core/adapter/adapters/shared.js +286 -0
- package/dist/core/adapter/adapters/tool-dir-shared.js +217 -0
- package/dist/core/adapter/adapters/website-snapshot-adapter.js +155 -0
- package/dist/core/adapter/bundle-adapter.js +4 -0
- package/dist/core/adapter/detect-adapter.js +17 -0
- package/dist/core/adapter/recognize-match.js +44 -0
- package/dist/core/adapter/registry.js +56 -0
- package/dist/core/adapter/types.js +4 -0
- package/dist/core/asset/akm-markdown.js +30 -0
- package/dist/core/asset/asset-placement.js +243 -0
- package/dist/core/asset/asset-ref.js +110 -79
- package/dist/core/asset/asset-serialize.js +20 -0
- package/dist/core/asset/frontmatter.js +28 -12
- package/dist/core/asset/markdown.js +40 -51
- package/dist/core/asset/resolve-ref.js +274 -0
- package/dist/core/asset/stash-meta.js +2 -2
- package/dist/core/bundle-id.js +51 -0
- package/dist/core/common.js +281 -86
- package/dist/core/config/config-io.js +42 -128
- package/dist/core/config/config-schema.js +233 -834
- package/dist/core/config/config-sources.js +162 -39
- package/dist/core/config/config-types.js +16 -11
- package/dist/core/config/config-version.js +29 -0
- package/dist/core/config/config-walker.js +126 -37
- package/dist/core/config/config.js +154 -331
- package/dist/core/config/deep-merge.js +41 -0
- package/dist/core/config/engine-semantics.js +28 -0
- package/dist/core/config/experimental.js +21 -0
- package/dist/core/config/schema/embedding.js +38 -0
- package/dist/core/config/schema/engines.js +116 -0
- package/dist/core/config/schema/experimental.js +47 -0
- package/dist/core/config/schema/feedback.js +31 -0
- package/dist/core/config/schema/improve-processes.js +389 -0
- package/dist/core/config/schema/improve.js +94 -0
- package/dist/core/config/schema/index-config.js +176 -0
- package/dist/core/config/schema/output.js +18 -0
- package/dist/core/config/schema/primitives.js +94 -0
- package/dist/core/config/schema/search.js +30 -0
- package/dist/core/config/schema/setup.js +18 -0
- package/dist/core/config/schema/sources-bundles.js +169 -0
- package/dist/core/config/schema/workflow.js +29 -0
- package/dist/core/env-secret-ref.js +155 -20
- package/dist/core/errors.js +17 -15
- package/dist/core/events-types.js +4 -0
- package/dist/core/events.js +46 -128
- package/dist/core/extra-params.js +62 -0
- package/dist/core/file-change.js +17 -0
- package/dist/core/file-lock.js +202 -57
- package/dist/core/fs-txn.js +392 -0
- package/dist/core/git-message.js +59 -0
- package/dist/core/improve-result.js +167 -0
- package/dist/core/json-schema.js +142 -0
- package/dist/core/lesson-lint.js +1 -17
- package/dist/core/logs-db.js +1 -1
- package/dist/core/maintenance-barrier.js +135 -0
- package/dist/core/migration-operation.js +44 -0
- package/dist/core/mutation-target.js +78 -0
- package/dist/core/paths.js +22 -25
- package/dist/core/platform.js +10 -0
- package/dist/core/recognition-util.js +128 -0
- package/dist/core/redaction.js +392 -0
- package/dist/core/standards/resolve-standards-context.js +36 -65
- package/dist/core/standards/resolve-stash-standards.js +2 -2
- package/dist/core/standards/resolve-type-conventions.js +5 -5
- package/dist/core/state/migrations.js +242 -11
- package/dist/core/state-db.js +98 -10
- package/dist/core/structured.js +1 -1
- package/dist/core/subprocess.js +303 -0
- package/dist/core/text-truncation.js +9 -5
- package/dist/core/time.js +20 -0
- package/dist/core/type-presentation.js +130 -0
- package/dist/core/warn.js +0 -3
- package/dist/core/write-source.js +834 -118
- package/dist/indexer/bundle-identity-guard.js +92 -0
- package/dist/indexer/db/graph-db.js +1 -25
- package/dist/indexer/db/llm-cache.js +1 -1
- package/dist/indexer/ensure-index.js +30 -9
- package/dist/indexer/graph/graph-boost.js +9 -30
- package/dist/indexer/graph/graph-extraction.js +41 -27
- package/dist/indexer/graph/graph-types.js +4 -0
- package/dist/indexer/index-writer-lock.js +93 -49
- package/dist/indexer/index-written-assets.js +100 -53
- package/dist/indexer/indexer.js +746 -329
- package/dist/indexer/init.js +18 -25
- package/dist/indexer/installations.js +142 -0
- package/dist/indexer/passes/dir-staleness.js +18 -10
- package/dist/indexer/passes/memory-inference.js +25 -15
- package/dist/indexer/passes/metadata.js +412 -243
- package/dist/indexer/scan/doc-to-entry.js +160 -0
- package/dist/indexer/scan/drain-dir.js +134 -0
- package/dist/indexer/search/db-search.js +292 -108
- package/dist/indexer/search/fts-query.js +64 -0
- package/dist/indexer/search/ranking-contributors.js +145 -25
- package/dist/indexer/search/ranking-types.js +4 -0
- package/dist/indexer/search/ranking.js +28 -71
- package/dist/indexer/search/search-attribution.js +67 -0
- package/dist/indexer/search/search-fields.js +18 -3
- package/dist/indexer/search/search-hit-enrichers.js +30 -40
- package/dist/indexer/search/search-source.js +157 -111
- package/dist/indexer/search/semantic-status.js +4 -1
- package/dist/indexer/usage/usage-events.js +10 -30
- package/dist/indexer/walk/file-context.js +3 -45
- package/dist/indexer/walk/matchers.js +42 -34
- package/dist/indexer/walk/path-resolver.js +11 -5
- package/dist/indexer/walk/walker.js +42 -14
- package/dist/integrations/agent/builder-shared.js +7 -0
- package/dist/integrations/agent/builders.js +5 -56
- package/dist/integrations/agent/config.js +3 -143
- package/dist/integrations/agent/detect.js +17 -2
- package/dist/integrations/agent/engine-resolution.js +231 -0
- package/dist/integrations/agent/index.js +1 -2
- package/dist/integrations/agent/model-aliases.js +16 -2
- package/dist/integrations/agent/profiles.js +36 -62
- package/dist/integrations/agent/prompts.js +46 -18
- package/dist/integrations/agent/runner-dispatch.js +93 -4
- package/dist/integrations/agent/runner.js +76 -208
- package/dist/integrations/agent/spawn.js +88 -196
- package/dist/integrations/harnesses/aider/agent-builder.js +114 -0
- package/dist/integrations/harnesses/aider/index.js +48 -0
- package/dist/integrations/harnesses/aider/result-extractor.js +53 -0
- package/dist/integrations/harnesses/amazonq/agent-builder.js +147 -0
- package/dist/integrations/harnesses/amazonq/index.js +45 -0
- package/dist/integrations/harnesses/amazonq/result-extractor.js +48 -0
- package/dist/integrations/harnesses/claude/agent-builder.js +46 -8
- package/dist/integrations/harnesses/claude/config-import.js +1 -3
- package/dist/integrations/harnesses/claude/index.js +24 -35
- package/dist/integrations/harnesses/claude/result-extractor.js +52 -0
- package/dist/integrations/harnesses/claude/session-log.js +27 -75
- package/dist/integrations/harnesses/codex/agent-builder.js +138 -0
- package/dist/integrations/harnesses/codex/index.js +52 -0
- package/dist/integrations/harnesses/codex/result-extractor.js +73 -0
- package/dist/integrations/harnesses/copilot/agent-builder.js +122 -0
- package/dist/integrations/harnesses/copilot/index.js +48 -0
- package/dist/integrations/harnesses/copilot/result-extractor.js +151 -0
- package/dist/integrations/harnesses/gemini/agent-builder.js +120 -0
- package/dist/integrations/harnesses/gemini/index.js +48 -0
- package/dist/integrations/harnesses/gemini/result-extractor.js +121 -0
- package/dist/integrations/harnesses/ids.js +24 -0
- package/dist/integrations/harnesses/index.js +54 -34
- package/dist/integrations/harnesses/opencode/agent-builder.js +23 -5
- package/dist/integrations/harnesses/opencode/config-import.js +1 -3
- package/dist/integrations/harnesses/opencode/index.js +14 -32
- package/dist/integrations/harnesses/opencode/session-log.js +67 -125
- package/dist/integrations/harnesses/opencode-sdk/harness.js +51 -0
- package/dist/integrations/harnesses/opencode-sdk/sdk-runner.js +681 -108
- package/dist/integrations/harnesses/openhands/agent-builder.js +128 -0
- package/dist/integrations/harnesses/openhands/index.js +48 -0
- package/dist/integrations/harnesses/openhands/result-extractor.js +103 -0
- package/dist/integrations/harnesses/pi/agent-builder.js +97 -0
- package/dist/integrations/harnesses/pi/index.js +45 -0
- package/dist/integrations/harnesses/pi/result-extractor.js +135 -0
- package/dist/integrations/harnesses/shared.js +17 -0
- package/dist/integrations/harnesses/types.js +43 -32
- package/dist/integrations/lockfile.js +211 -24
- package/dist/integrations/session-logs/index.js +36 -39
- package/dist/integrations/session-logs/provider-base.js +113 -0
- package/dist/llm/client.js +182 -110
- package/dist/llm/embedders/deterministic.js +2 -2
- package/dist/llm/embedders/remote.js +21 -9
- package/dist/llm/feature-gate.js +17 -57
- package/dist/llm/graph-extract.js +12 -13
- package/dist/llm/index-passes.js +8 -42
- package/dist/llm/memory-infer.js +144 -1
- package/dist/llm/metadata-enhance.js +45 -30
- package/dist/llm/structured-call.js +16 -8
- package/dist/llm/usage-persist.js +30 -5
- package/dist/llm/usage-telemetry.js +59 -6
- package/dist/output/cli-hints.js +1 -2
- package/dist/output/command-registry.js +27 -0
- package/dist/output/context.js +22 -7
- package/dist/output/format-exempt.js +80 -0
- package/dist/output/generic-render.js +251 -0
- package/dist/output/html-render.js +11 -16
- package/dist/output/render-registry.js +57 -0
- package/dist/output/renderers.js +14 -279
- package/dist/output/shapes/curate.js +10 -1
- package/dist/output/shapes/events.js +12 -7
- package/dist/output/shapes/helpers.js +58 -84
- package/dist/output/shapes/passthrough.js +11 -39
- package/dist/output/shapes/proposal/producer.js +15 -7
- package/dist/output/shapes/registry.js +12 -6
- package/dist/output/shapes.js +0 -9
- package/dist/output/text/{init.js → bundle-create.js} +3 -1
- package/dist/output/text/bundle-show.js +7 -0
- package/dist/output/text/command-format.js +562 -0
- package/dist/output/text/env.js +1 -3
- package/dist/output/text/events.js +8 -7
- package/dist/output/text/helpers.js +15 -1164
- package/dist/output/text/proposal/producer.js +4 -2
- package/dist/output/text/proposal-format.js +202 -0
- package/dist/output/text/registry-commands.js +1 -2
- package/dist/output/text/registry.js +12 -6
- package/dist/output/text/show-directives.js +117 -0
- package/dist/output/text/show-format.js +103 -0
- package/dist/output/text/sync.js +5 -0
- package/dist/output/text/workflow-format.js +332 -0
- package/dist/output/text/workflow.js +3 -2
- package/dist/output/text.js +10 -19
- package/dist/registry/factory.js +4 -6
- package/dist/registry/origin-resolve.js +16 -27
- package/dist/registry/providers/skills-sh.js +3 -3
- package/dist/registry/providers/static-index.js +15 -25
- package/dist/registry/resolve.js +43 -94
- package/dist/registry/semver.js +43 -0
- package/dist/runtime.js +81 -12
- package/dist/scripts/akm-migrate.js +35529 -0
- package/dist/setup/detect.js +5 -7
- package/dist/setup/detected-engines.js +136 -0
- package/dist/setup/engine-config.js +100 -0
- package/dist/setup/registry-stash-loader.js +3 -3
- package/dist/setup/semantic-assets.js +12 -9
- package/dist/setup/setup.js +444 -208
- package/dist/setup/steps/connection-shared.js +120 -0
- package/dist/setup/steps/connection.js +108 -305
- package/dist/setup/steps/platforms.js +13 -12
- package/dist/setup/steps/semantic.js +15 -3
- package/dist/setup/steps/sources.js +21 -15
- package/dist/setup/steps/stashdir.js +6 -4
- package/dist/setup/steps/tasks.js +236 -119
- package/dist/setup/steps.js +3 -2
- package/dist/sources/freshness.js +39 -0
- package/dist/sources/provider-factory.js +11 -17
- package/dist/sources/providers/filesystem.js +2 -3
- package/dist/sources/providers/git-install.js +278 -34
- package/dist/sources/providers/git-provider.js +54 -56
- package/dist/sources/providers/git-stash.js +420 -91
- package/dist/sources/providers/git.js +2 -2
- package/dist/sources/providers/npm.js +16 -19
- package/dist/sources/providers/provider-utils.js +47 -22
- package/dist/sources/providers/sync-from-ref.js +3 -9
- package/dist/sources/providers/website.js +2 -2
- package/dist/sources/resolve.js +11 -10
- package/dist/sources/snapshot-fetchers/types.js +4 -0
- package/dist/sources/{website-ingest.js → snapshot-fetchers/website-ingest.js} +110 -41
- package/dist/storage/database.js +60 -4
- package/dist/storage/engines/sqlite-migrations.js +156 -5
- package/dist/storage/locations.js +1 -2
- package/dist/storage/repositories/canaries-repository.js +1 -1
- package/dist/storage/repositories/events-repository.js +51 -11
- package/dist/storage/repositories/improve-runs-repository.js +6 -32
- package/dist/storage/repositories/index-connection.js +79 -0
- package/dist/storage/repositories/index-db.js +4 -3
- package/dist/storage/repositories/index-entries-repository.js +863 -0
- package/dist/{indexer/db/entry-mapper.js → storage/repositories/index-entry-mapper.js} +19 -2
- package/dist/storage/repositories/index-entry-types.js +4 -0
- package/dist/storage/repositories/index-fts-repository.js +167 -0
- package/dist/storage/repositories/index-llm-cache-repository.js +108 -0
- package/dist/storage/repositories/index-meta-repository.js +49 -0
- package/dist/{indexer/db/schema.js → storage/repositories/index-schema.js} +226 -100
- package/dist/storage/repositories/index-sql.js +12 -0
- package/dist/storage/repositories/index-utility-repository.js +356 -0
- package/dist/storage/repositories/index-vec-repository.js +250 -0
- package/dist/storage/repositories/outcome-repository.js +119 -0
- package/dist/storage/repositories/proposals-repository.js +317 -75
- package/dist/storage/repositories/registry-cache.js +1 -1
- package/dist/storage/repositories/salience-repository.js +172 -0
- package/dist/storage/repositories/task-history-repository.js +110 -3
- package/dist/storage/repositories/workflow-runs-repository.js +240 -19
- package/dist/tasks/backends/cron.js +169 -46
- package/dist/tasks/backends/exec-utils.js +76 -3
- package/dist/tasks/backends/index.js +6 -9
- package/dist/tasks/backends/launchd.js +292 -55
- package/dist/tasks/backends/schtasks.js +557 -70
- package/dist/tasks/backends/types.js +4 -0
- package/dist/tasks/command-executable.js +93 -0
- package/dist/tasks/embedded.js +56 -38
- package/dist/tasks/parser.js +156 -64
- package/dist/tasks/resolve-akm-bin.js +144 -51
- package/dist/tasks/runner.js +377 -209
- package/dist/tasks/schedule.js +108 -19
- package/dist/tasks/scheduler-invocation.js +296 -0
- package/dist/tasks/schema.js +1 -1
- package/dist/tasks/task-id.js +35 -0
- package/dist/tasks/validator.js +30 -16
- package/dist/text-import-hook.mjs +1 -1
- package/dist/workflows/authoring/authoring.js +104 -43
- package/dist/workflows/authoring/scope-key.js +1 -1
- package/dist/workflows/cli.js +0 -16
- package/dist/workflows/concurrency-policy.js +15 -0
- package/dist/workflows/exec/brief.js +450 -0
- package/dist/workflows/exec/frozen-judge.js +47 -0
- package/dist/workflows/exec/native-executor.js +1038 -0
- package/dist/workflows/exec/param-secrets.js +115 -0
- package/dist/workflows/exec/report.js +1460 -0
- package/dist/workflows/exec/run-workflow.js +602 -0
- package/dist/workflows/exec/scheduler.js +71 -0
- package/dist/workflows/exec/step-work.js +1190 -0
- package/dist/workflows/exec/unit-writer.js +23 -0
- package/dist/workflows/exec/workflow-engine-gate.js +67 -0
- package/dist/workflows/exec/worktree.js +171 -0
- package/dist/workflows/ir/compile.js +246 -0
- package/dist/workflows/ir/freeze.js +233 -0
- package/dist/workflows/ir/params.js +54 -0
- package/dist/workflows/ir/plan-hash.js +68 -0
- package/dist/workflows/ir/schema.js +540 -0
- package/dist/workflows/parser.js +878 -304
- package/dist/workflows/program/expressions.js +181 -0
- package/dist/workflows/program/schema.js +51 -0
- package/dist/workflows/renderer.js +100 -45
- package/dist/workflows/resource-limits.js +22 -0
- package/dist/workflows/runtime/agent-identity.js +59 -14
- package/dist/workflows/runtime/checkin.js +1 -1
- package/dist/workflows/runtime/plan-classifier.js +131 -0
- package/dist/workflows/runtime/runs.js +376 -119
- package/dist/workflows/runtime/unit-checkin.js +45 -0
- package/dist/workflows/runtime/unit-phases.js +20 -0
- package/dist/workflows/runtime/workflow-asset-loader.js +241 -40
- package/dist/workflows/schema.js +1 -11
- package/dist/workflows/validate-summary.js +2 -3
- package/dist/workflows/validator.js +52 -30
- package/docs/README.md +42 -78
- package/docs/migration/README.md +8 -0
- package/docs/migration/release-notes/0.6.0.md +1 -1
- package/docs/migration/release-notes/0.7.0.md +9 -8
- package/docs/migration/release-notes/0.9.0.md +158 -14
- package/docs/migration/v0.7-to-v0.8.md +46 -47
- package/docs/migration/v0.8-to-v0.9.md +844 -0
- package/docs/reference/README.md +12 -0
- package/docs/reference/data-and-telemetry.md +333 -0
- package/package.json +21 -17
- package/schemas/akm-asset-envelope.json +93 -0
- package/schemas/akm-config.json +4636 -0
- package/schemas/akm-task.json +87 -0
- package/schemas/akm-workflow.json +373 -0
- package/dist/akm-migrate-storage +0 -38
- package/dist/assets/help/help-accept.md +0 -12
- package/dist/assets/help/help-improve.md +0 -84
- package/dist/assets/help/help-proposals.md +0 -17
- package/dist/assets/help/help-propose.md +0 -17
- package/dist/assets/help/help-reject.md +0 -11
- package/dist/assets/profiles/frequent.json +0 -13
- package/dist/assets/profiles/recombine-only.json +0 -21
- package/dist/assets/profiles/reflect-distill.json +0 -30
- package/dist/assets/profiles/synthesize.json +0 -15
- package/dist/assets/prompts/procedural-system.md +0 -44
- package/dist/assets/prompts/recombine-system.md +0 -40
- package/dist/assets/prompts/staleness-detect-system.md +0 -6
- package/dist/assets/tasks/core/backup.yml +0 -4
- package/dist/assets/tasks/graph-refresh-weekly.yml +0 -10
- package/dist/assets/templates/html/default.html +0 -78
- package/dist/assets/templates/html/vendor/echarts.min.js +0 -45
- package/dist/assets/wiki/index-template.md +0 -12
- package/dist/assets/wiki/ingest-workflow-template.md +0 -83
- package/dist/assets/wiki/log-template.md +0 -8
- package/dist/assets/wiki/schema-template.md +0 -61
- package/dist/cli/config-migrate.js +0 -150
- package/dist/cli/config-validate.js +0 -39
- package/dist/commands/graph/graph-cli.js +0 -124
- package/dist/commands/graph/graph.js +0 -487
- package/dist/commands/improve/calibration.js +0 -161
- package/dist/commands/improve/dedup.js +0 -482
- package/dist/commands/improve/extract-watch.js +0 -140
- package/dist/commands/improve/hot-probation.js +0 -45
- package/dist/commands/improve/improve-auto-accept.js +0 -276
- package/dist/commands/improve/improve-profiles.js +0 -168
- package/dist/commands/improve/procedural.js +0 -398
- package/dist/commands/improve/recombine.js +0 -818
- package/dist/commands/improve/schema-similarity-gate.js +0 -168
- package/dist/commands/lint/agent-linter.js +0 -44
- package/dist/commands/lint/command-linter.js +0 -44
- package/dist/commands/lint/default-linter.js +0 -16
- package/dist/commands/lint/fact-linter.js +0 -39
- package/dist/commands/lint/knowledge-linter.js +0 -16
- package/dist/commands/lint/memory-linter.js +0 -61
- package/dist/commands/lint/registry.js +0 -41
- package/dist/commands/lint/skill-linter.js +0 -45
- package/dist/commands/lint/task-linter.js +0 -50
- package/dist/commands/lint/workflow-linter.js +0 -81
- package/dist/commands/proposal/legacy-import.js +0 -115
- package/dist/commands/sources/history.js +0 -196
- package/dist/commands/tasks/default-tasks.js +0 -186
- package/dist/commands/wiki-cli.js +0 -292
- package/dist/core/asset/asset-registry.js +0 -76
- package/dist/core/asset/asset-spec.js +0 -259
- package/dist/core/config/config-migration.js +0 -602
- package/dist/core/deep-merge.js +0 -38
- package/dist/core/eval/rank-metrics.js +0 -113
- package/dist/core/ripgrep/install.js +0 -163
- package/dist/core/ripgrep/resolve.js +0 -81
- package/dist/indexer/db/db.js +0 -1413
- package/dist/indexer/manifest.js +0 -170
- package/dist/indexer/passes/metadata-contributors.js +0 -31
- package/dist/indexer/usage/unmigrated-vaults-guard.js +0 -94
- package/dist/integrations/harnesses/opencode-sdk/index.js +0 -49
- package/dist/llm/call-ai.js +0 -62
- package/dist/llm/memory-infer-impl.js +0 -138
- package/dist/output/shapes/distill.js +0 -14
- package/dist/output/shapes/history.js +0 -11
- package/dist/output/text/distill.js +0 -6
- package/dist/output/text/enable-disable.js +0 -8
- package/dist/output/text/history.js +0 -6
- package/dist/output/text/wiki.js +0 -16
- package/dist/registry/build-index.js +0 -386
- package/dist/scripts/migrate-storage.js +0 -19108
- package/dist/scripts/migrations/import-fs-improve-runs-to-db.js +0 -9411
- package/dist/scripts/migrations/v16-to-v17.js +0 -141
- package/dist/setup/legacy-config.js +0 -106
- package/dist/storage/repositories/consolidation-repository.js +0 -38
- package/dist/storage/repositories/recombine-repository.js +0 -213
- package/dist/wiki/wiki-templates.js +0 -15
- package/dist/wiki/wiki.js +0 -1012
- package/dist/workflows/db.js +0 -215
- package/docs/data-and-telemetry.md +0 -226
- /package/dist/sources/{wiki-fetchers → snapshot-fetchers}/registry.js +0 -0
- /package/dist/sources/{wiki-fetchers → snapshot-fetchers}/youtube.js +0 -0
package/dist/storage/database.js
CHANGED
|
@@ -10,14 +10,14 @@
|
|
|
10
10
|
*
|
|
11
11
|
* Runtime selection:
|
|
12
12
|
* - On Bun (the primary/test runtime) we use the built-in `bun:sqlite`.
|
|
13
|
-
* - On Node.js (
|
|
14
|
-
* loaded via a runtime-gated dynamic `require` so the Bun path never
|
|
13
|
+
* - On Node.js (CI-tested by the node-smoke job's smoke + compat suites) we
|
|
14
|
+
* use `better-sqlite3`, loaded via a runtime-gated dynamic `require` so the Bun path never
|
|
15
15
|
* imports it (it is an optionalDependency and may be uninstalled or
|
|
16
16
|
* uncompiled when running under Bun).
|
|
17
17
|
*
|
|
18
18
|
* Both driver handles are structurally compatible across the small surface AKM
|
|
19
19
|
* uses (`prepare`, `exec`, `run`, `transaction`, `close` on the handle;
|
|
20
|
-
* `get`, `all`, `run` on prepared statements). The Bun-specific `db.query()`
|
|
20
|
+
* `get`, `all`, `iterate`, `run` on prepared statements). The Bun-specific `db.query()`
|
|
21
21
|
* helper is normalised away — callers use `db.prepare(sql).all(...)` instead.
|
|
22
22
|
*
|
|
23
23
|
* This file is intentionally NOT an adapter/DI/ports-and-adapters layer. It is
|
|
@@ -69,6 +69,50 @@ function selectProvider() {
|
|
|
69
69
|
export function openDatabase(path, opts) {
|
|
70
70
|
return selectProvider().open(path, opts);
|
|
71
71
|
}
|
|
72
|
+
/**
|
|
73
|
+
* {@link openDatabase} with a finalize-on-close guard (issue #720).
|
|
74
|
+
*
|
|
75
|
+
* bun:sqlite's `Database.close()` is a `sqlite3_close_v2`: with any UNFINALIZED
|
|
76
|
+
* `prepare()` statement outstanding, the underlying connection — and its WAL
|
|
77
|
+
* shared-memory mapping — survives as a zombie until GC finalizes the
|
|
78
|
+
* statements. A later connection in the same process then cannot leave WAL
|
|
79
|
+
* mode (`PRAGMA journal_mode = DELETE` → "database is locked"), which is
|
|
80
|
+
* exactly what silently defeated the migrate-apply single-file conversion.
|
|
81
|
+
* (`db.query()` statements are Database-cached and immune; `prepare()` is the
|
|
82
|
+
* dominant idiom in the migration helpers.)
|
|
83
|
+
*
|
|
84
|
+
* This variant tracks `prepare()` results and finalizes them (idempotently)
|
|
85
|
+
* before the real `close()`, so close always means CLOSED. It is deliberately
|
|
86
|
+
* OPT-IN for the migrate-apply flow's short-lived helper connections and the
|
|
87
|
+
* migration test fixtures — NOT the global default: long-lived/hot paths cache
|
|
88
|
+
* prepared statements per connection (e.g. the entries upsert WeakMap) and
|
|
89
|
+
* worker flows may still be stepping a statement when a sibling close lands;
|
|
90
|
+
* force-finalizing under them changes behavior they were built on.
|
|
91
|
+
*/
|
|
92
|
+
export function openDatabaseFinalizing(path, opts) {
|
|
93
|
+
const db = selectProvider().open(path, opts);
|
|
94
|
+
const tracked = new Set();
|
|
95
|
+
const origPrepare = db.prepare.bind(db);
|
|
96
|
+
const origClose = db.close.bind(db);
|
|
97
|
+
db.prepare = ((sql, ...rest) => {
|
|
98
|
+
const stmt = origPrepare(sql, ...rest);
|
|
99
|
+
tracked.add(stmt);
|
|
100
|
+
return stmt;
|
|
101
|
+
});
|
|
102
|
+
db.close = ((...args) => {
|
|
103
|
+
for (const stmt of tracked) {
|
|
104
|
+
try {
|
|
105
|
+
stmt.finalize?.();
|
|
106
|
+
}
|
|
107
|
+
catch {
|
|
108
|
+
// Already finalized (double-finalize is the idempotent no-op case).
|
|
109
|
+
}
|
|
110
|
+
}
|
|
111
|
+
tracked.clear();
|
|
112
|
+
return origClose(...args);
|
|
113
|
+
});
|
|
114
|
+
return db;
|
|
115
|
+
}
|
|
72
116
|
function openBunDatabase(path, opts) {
|
|
73
117
|
const { Database: BunDatabase } = loadBunSqlite();
|
|
74
118
|
// Only pass an options object when an option is actually set. bun:sqlite
|
|
@@ -133,5 +177,17 @@ function openNodeDatabase(path, opts) {
|
|
|
133
177
|
if (opts?.create === false)
|
|
134
178
|
options.fileMustExist = true;
|
|
135
179
|
const db = opts ? new BetterSqlite3(path, options) : new BetterSqlite3(path);
|
|
136
|
-
return
|
|
180
|
+
return {
|
|
181
|
+
prepare: db.prepare.bind(db),
|
|
182
|
+
exec: db.exec.bind(db),
|
|
183
|
+
// better-sqlite3 exposes mutations on prepared statements, while
|
|
184
|
+
// bun:sqlite also provides db.run(). Normalize the latter at the provider
|
|
185
|
+
// boundary so callers and maintenance wrappers can rely on one contract.
|
|
186
|
+
run: (sql, ...params) => db.prepare(sql).run(...params),
|
|
187
|
+
transaction: db.transaction.bind(db),
|
|
188
|
+
get inTransaction() {
|
|
189
|
+
return db.inTransaction;
|
|
190
|
+
},
|
|
191
|
+
close: db.close.bind(db),
|
|
192
|
+
};
|
|
137
193
|
}
|
|
@@ -1,6 +1,131 @@
|
|
|
1
1
|
// This Source Code Form is subject to the terms of the Mozilla Public
|
|
2
2
|
// License, v. 2.0. If a copy of the MPL was not distributed with this
|
|
3
3
|
// file, You can obtain one at https://mozilla.org/MPL/2.0/.
|
|
4
|
+
/**
|
|
5
|
+
* Shared SQLite migration engine.
|
|
6
|
+
*
|
|
7
|
+
* state.db (`src/core/state-db.ts`) evolves its schema through this idempotent,
|
|
8
|
+
* transaction-per-migration runner backed by a `schema_migrations` ledger. The
|
|
9
|
+
* migrator's frozen pre-cutover workflow-schema roll
|
|
10
|
+
* (`scripts/akm-migrate/migrate/legacy/workflow-migrations-bodies.ts`, driven by
|
|
11
|
+
* `scripts/akm-migrate/config-migrate.ts`) reuses the SAME runner.
|
|
12
|
+
*
|
|
13
|
+
* This module factors that runner out once. Each caller supplies only its own
|
|
14
|
+
* `MIGRATIONS` array.
|
|
15
|
+
*
|
|
16
|
+
* Migration-safety contract:
|
|
17
|
+
* - `id` is permanent and must never be reused.
|
|
18
|
+
* - `up` must be idempotent (use IF NOT EXISTS, INSERT OR IGNORE, etc.).
|
|
19
|
+
* - `up` must not DROP any table that holds durable (non-regenerable) data.
|
|
20
|
+
* - `up` must not RENAME or change the type of an existing column.
|
|
21
|
+
* - To add a column: use `ALTER TABLE … ADD COLUMN … DEFAULT …`.
|
|
22
|
+
* - Applied IDs must be an exact ordered prefix of the registry.
|
|
23
|
+
* - Released migration bodies are sealed by SHA-256 in the same ledger.
|
|
24
|
+
*/
|
|
25
|
+
import crypto from "node:crypto";
|
|
26
|
+
export function migrationChecksum(migration) {
|
|
27
|
+
return crypto.createHash("sha256").update(migration.id).update("\0").update(migration.up).digest("hex");
|
|
28
|
+
}
|
|
29
|
+
function migrationsTableExists(db) {
|
|
30
|
+
return !!db.prepare("SELECT 1 FROM sqlite_master WHERE type = 'table' AND name = 'schema_migrations'").get();
|
|
31
|
+
}
|
|
32
|
+
function ledgerHasChecksum(db) {
|
|
33
|
+
return db.prepare("PRAGMA table_info(schema_migrations)").all().some((column) => column.name === "checksum");
|
|
34
|
+
}
|
|
35
|
+
/**
|
|
36
|
+
* Core ledger inspection against the expected ordered `{ id, checksum }`
|
|
37
|
+
* registry. Both {@link inspectMigrationLedger} (bodies → checksums) and
|
|
38
|
+
* {@link inspectSealedMigrationLedger} (frozen pre-computed checksums) route
|
|
39
|
+
* here so the two entry points can never diverge.
|
|
40
|
+
*/
|
|
41
|
+
function inspectLedgerAgainst(db, expected) {
|
|
42
|
+
const registryIds = expected.map((entry) => entry.id);
|
|
43
|
+
if (new Set(registryIds).size !== registryIds.length) {
|
|
44
|
+
return {
|
|
45
|
+
status: "inconsistent",
|
|
46
|
+
migrationIds: [],
|
|
47
|
+
checksums: [],
|
|
48
|
+
detail: "migration registry contains duplicate IDs",
|
|
49
|
+
};
|
|
50
|
+
}
|
|
51
|
+
if (!migrationsTableExists(db))
|
|
52
|
+
return { status: registryIds.length === 0 ? "current" : "old", migrationIds: [], checksums: [] };
|
|
53
|
+
const hasChecksum = ledgerHasChecksum(db);
|
|
54
|
+
const rows = db
|
|
55
|
+
.prepare(`SELECT id${hasChecksum ? ", checksum" : ""} FROM schema_migrations ORDER BY rowid`)
|
|
56
|
+
.all();
|
|
57
|
+
const migrationIds = rows.map((row) => row.id);
|
|
58
|
+
const checksums = rows.map((row) => row.checksum ?? null);
|
|
59
|
+
for (let index = 0; index < rows.length; index += 1) {
|
|
60
|
+
const entry = expected[index];
|
|
61
|
+
const row = rows[index];
|
|
62
|
+
if (!entry) {
|
|
63
|
+
return { status: "newer", migrationIds, checksums, detail: `unknown migration ID ${row.id}` };
|
|
64
|
+
}
|
|
65
|
+
if (row.id !== entry.id) {
|
|
66
|
+
const knownLater = registryIds.includes(row.id);
|
|
67
|
+
return {
|
|
68
|
+
status: knownLater ? "inconsistent" : "newer",
|
|
69
|
+
migrationIds,
|
|
70
|
+
checksums,
|
|
71
|
+
detail: knownLater
|
|
72
|
+
? `migration ledger is not an exact ordered prefix at position ${index + 1}`
|
|
73
|
+
: `unknown migration ID ${row.id}`,
|
|
74
|
+
};
|
|
75
|
+
}
|
|
76
|
+
if (row.checksum && row.checksum !== entry.checksum) {
|
|
77
|
+
return {
|
|
78
|
+
status: "inconsistent",
|
|
79
|
+
migrationIds,
|
|
80
|
+
checksums,
|
|
81
|
+
detail: `migration ${row.id} checksum does not match the released migration body`,
|
|
82
|
+
};
|
|
83
|
+
}
|
|
84
|
+
}
|
|
85
|
+
const missingChecksum = checksums.indexOf(null);
|
|
86
|
+
if (missingChecksum >= 0) {
|
|
87
|
+
return {
|
|
88
|
+
status: "old",
|
|
89
|
+
migrationIds,
|
|
90
|
+
checksums,
|
|
91
|
+
detail: `migration ${migrationIds[missingChecksum]} has not been sealed with a checksum`,
|
|
92
|
+
};
|
|
93
|
+
}
|
|
94
|
+
return {
|
|
95
|
+
status: rows.length === expected.length ? "current" : "old",
|
|
96
|
+
migrationIds,
|
|
97
|
+
checksums,
|
|
98
|
+
};
|
|
99
|
+
}
|
|
100
|
+
export function inspectMigrationLedger(db, migrations) {
|
|
101
|
+
return inspectLedgerAgainst(db, migrations.map((migration) => ({ id: migration.id, checksum: migrationChecksum(migration) })));
|
|
102
|
+
}
|
|
103
|
+
/**
|
|
104
|
+
* Ledger inspection against a FROZEN `{ id, checksum }` copy of a migration
|
|
105
|
+
* array whose live source is gone (plan §3.3 item 1). Behaviourally identical
|
|
106
|
+
* to {@link inspectMigrationLedger} — the checksums are simply pre-computed
|
|
107
|
+
* rather than derived from `up` bodies.
|
|
108
|
+
*/
|
|
109
|
+
export function inspectSealedMigrationLedger(db, sealed) {
|
|
110
|
+
return inspectLedgerAgainst(db, sealed);
|
|
111
|
+
}
|
|
112
|
+
export function assertMigrationLedger(db, migrations) {
|
|
113
|
+
const state = inspectMigrationLedger(db, migrations);
|
|
114
|
+
if (state.status === "newer") {
|
|
115
|
+
throw new Error(`Refusing to open a database with a newer migration ledger: ${state.detail}.`);
|
|
116
|
+
}
|
|
117
|
+
if (state.status === "inconsistent") {
|
|
118
|
+
throw new Error(`Refusing a database whose migrations are not an exact ordered prefix: ${state.detail}.`);
|
|
119
|
+
}
|
|
120
|
+
return state;
|
|
121
|
+
}
|
|
122
|
+
export function assertCurrentMigrationLedger(db, migrations) {
|
|
123
|
+
const state = assertMigrationLedger(db, migrations);
|
|
124
|
+
if (state.status !== "current") {
|
|
125
|
+
throw new Error(`Refusing to open an obsolete writable schema; run \`akm migrate apply\`: ${state.detail ?? "pending migrations"}.`);
|
|
126
|
+
}
|
|
127
|
+
return state;
|
|
128
|
+
}
|
|
4
129
|
/**
|
|
5
130
|
* Create the migrations ledger table if it does not exist. Must be called
|
|
6
131
|
* unconditionally on every open so a fresh database bootstraps correctly.
|
|
@@ -9,9 +134,12 @@ export function ensureMigrationsTable(db) {
|
|
|
9
134
|
db.exec(`
|
|
10
135
|
CREATE TABLE IF NOT EXISTS schema_migrations (
|
|
11
136
|
id TEXT PRIMARY KEY,
|
|
12
|
-
applied_at TEXT NOT NULL DEFAULT (datetime('now'))
|
|
137
|
+
applied_at TEXT NOT NULL DEFAULT (datetime('now')),
|
|
138
|
+
checksum TEXT
|
|
13
139
|
);
|
|
14
140
|
`);
|
|
141
|
+
if (!ledgerHasChecksum(db))
|
|
142
|
+
db.exec("ALTER TABLE schema_migrations ADD COLUMN checksum TEXT");
|
|
15
143
|
}
|
|
16
144
|
/**
|
|
17
145
|
* Apply every pending migration, one transaction per migration.
|
|
@@ -24,19 +152,42 @@ export function ensureMigrationsTable(db) {
|
|
|
24
152
|
*
|
|
25
153
|
* @param db The open SQLite database.
|
|
26
154
|
* @param migrations The module's ordered, append-only migration list.
|
|
27
|
-
* @param opts
|
|
155
|
+
* @param opts Migration execution options.
|
|
28
156
|
*/
|
|
29
157
|
export function runMigrations(db, migrations, opts) {
|
|
158
|
+
if (opts?.applyPending === false) {
|
|
159
|
+
assertMigrationLedger(db, migrations);
|
|
160
|
+
return;
|
|
161
|
+
}
|
|
162
|
+
if (migrationsTableExists(db))
|
|
163
|
+
assertMigrationLedger(db, migrations);
|
|
30
164
|
ensureMigrationsTable(db);
|
|
31
|
-
|
|
32
|
-
|
|
165
|
+
const ledger = assertMigrationLedger(db, migrations);
|
|
166
|
+
db.transaction(() => {
|
|
167
|
+
const update = db.prepare("UPDATE schema_migrations SET checksum = ? WHERE id = ? AND checksum IS NULL");
|
|
168
|
+
for (let index = 0; index < ledger.migrationIds.length; index += 1) {
|
|
169
|
+
update.run(migrationChecksum(migrations[index]), ledger.migrationIds[index]);
|
|
170
|
+
}
|
|
171
|
+
if (opts?.generationMarker) {
|
|
172
|
+
db.exec(`
|
|
173
|
+
CREATE TABLE IF NOT EXISTS akm_migration_generation (
|
|
174
|
+
singleton INTEGER PRIMARY KEY CHECK (singleton = 1),
|
|
175
|
+
operation_id TEXT NOT NULL,
|
|
176
|
+
phase TEXT NOT NULL
|
|
177
|
+
)
|
|
178
|
+
`);
|
|
179
|
+
db.prepare("INSERT INTO akm_migration_generation(singleton, operation_id, phase) VALUES (1, ?, ?) ON CONFLICT(singleton) DO UPDATE SET operation_id=excluded.operation_id, phase=excluded.phase").run(opts.generationMarker.operationId, opts.generationMarker.phase);
|
|
180
|
+
}
|
|
181
|
+
})();
|
|
182
|
+
const appliedRows = db.prepare("SELECT id FROM schema_migrations ORDER BY rowid").all();
|
|
33
183
|
const applied = new Set(appliedRows.map((r) => r.id));
|
|
34
184
|
for (const migration of migrations) {
|
|
35
185
|
if (applied.has(migration.id))
|
|
36
186
|
continue;
|
|
187
|
+
opts?.beforeMigration?.(migration);
|
|
37
188
|
db.transaction(() => {
|
|
38
189
|
db.exec(migration.up);
|
|
39
|
-
db.prepare("INSERT INTO schema_migrations (id) VALUES (?)").run(migration.id);
|
|
190
|
+
db.prepare("INSERT INTO schema_migrations (id, checksum) VALUES (?, ?)").run(migration.id, migrationChecksum(migration));
|
|
40
191
|
})();
|
|
41
192
|
}
|
|
42
193
|
}
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
// This Source Code Form is subject to the terms of the Mozilla Public
|
|
2
2
|
// License, v. 2.0. If a copy of the MPL was not distributed with this
|
|
3
3
|
// file, You can obtain one at https://mozilla.org/MPL/2.0/.
|
|
4
|
-
import { getCacheDir, getConfigDir, getDataDir, getDbPath, getDefaultStashDir, getLockfileLockPath, getLockfilePath,
|
|
4
|
+
import { getCacheDir, getConfigDir, getDataDir, getDbPath, getDefaultStashDir, getLockfileLockPath, getLockfilePath, } from "../core/paths.js";
|
|
5
5
|
import { getStateDbPath } from "../core/state-db.js";
|
|
6
6
|
/**
|
|
7
7
|
* Resolve the current {@link StorageLocations} by delegating to the existing
|
|
@@ -14,7 +14,6 @@ export function resolveStorageLocations() {
|
|
|
14
14
|
return {
|
|
15
15
|
indexDb: getDbPath(),
|
|
16
16
|
stateDb: getStateDbPath(),
|
|
17
|
-
workflowDb: getWorkflowDbPath(),
|
|
18
17
|
lockfile: getLockfilePath(),
|
|
19
18
|
lockfileSentinel: getLockfileLockPath(),
|
|
20
19
|
dataDir: getDataDir(),
|
|
@@ -45,7 +45,7 @@ export function listActiveCanarySetIds(db) {
|
|
|
45
45
|
/**
|
|
46
46
|
* Deactivate every canary row in a set. Rows are RETAINED (active = 0) so
|
|
47
47
|
* historical improve_cycle_metrics rows keyed on the old canary_set_id stay
|
|
48
|
-
* interpretable; only `
|
|
48
|
+
* interpretable; only `bun scripts/refresh-canary-set.ts --refresh` calls this.
|
|
49
49
|
*/
|
|
50
50
|
export function deactivateCanarySet(db, canarySetId) {
|
|
51
51
|
const result = db
|
|
@@ -38,12 +38,7 @@ export function eventRowToEnvelope(row) {
|
|
|
38
38
|
*/
|
|
39
39
|
export function insertEvent(db, input) {
|
|
40
40
|
try {
|
|
41
|
-
|
|
42
|
-
.prepare(`INSERT INTO events (event_type, ts, ref, metadata_json)
|
|
43
|
-
VALUES (?, ?, ?, ?)
|
|
44
|
-
RETURNING id`)
|
|
45
|
-
.get(input.eventType, input.ts, input.ref ?? null, JSON.stringify(input.metadata ?? {}));
|
|
46
|
-
return result?.id;
|
|
41
|
+
return insertEventStrict(db, input);
|
|
47
42
|
}
|
|
48
43
|
catch (err) {
|
|
49
44
|
const message = err instanceof Error ? err.message : String(err);
|
|
@@ -51,12 +46,52 @@ export function insertEvent(db, input) {
|
|
|
51
46
|
return undefined;
|
|
52
47
|
}
|
|
53
48
|
}
|
|
49
|
+
/** Insert an event without best-effort error swallowing for transaction-coupled mutations. */
|
|
50
|
+
export function insertEventStrict(db, input) {
|
|
51
|
+
const result = db
|
|
52
|
+
.prepare(`INSERT INTO events (event_type, ts, ref, metadata_json)
|
|
53
|
+
VALUES (?, ?, ?, ?)
|
|
54
|
+
RETURNING id`)
|
|
55
|
+
.get(input.eventType, input.ts, input.ref ?? null, JSON.stringify(input.metadata ?? {}));
|
|
56
|
+
if (!result)
|
|
57
|
+
throw new Error(`Failed to persist ${input.eventType} event.`);
|
|
58
|
+
return result.id;
|
|
59
|
+
}
|
|
60
|
+
/** Strict idempotent event insert for durable mutation journals. */
|
|
61
|
+
export function insertEventOnce(db, input) {
|
|
62
|
+
const rows = db
|
|
63
|
+
.prepare("SELECT id, metadata_json FROM events WHERE event_type = ? AND ref IS ? ORDER BY id")
|
|
64
|
+
.all(input.eventType, input.ref ?? null);
|
|
65
|
+
for (const row of rows) {
|
|
66
|
+
try {
|
|
67
|
+
const metadata = JSON.parse(row.metadata_json);
|
|
68
|
+
if (metadata[input.idempotencyMetadataKey ?? "proposalTransactionId"] === input.idempotencyKey)
|
|
69
|
+
return row.id;
|
|
70
|
+
}
|
|
71
|
+
catch {
|
|
72
|
+
// Corrupt unrelated event metadata cannot satisfy this idempotency key.
|
|
73
|
+
}
|
|
74
|
+
}
|
|
75
|
+
const result = db
|
|
76
|
+
.prepare(`INSERT INTO events (event_type, ts, ref, metadata_json)
|
|
77
|
+
VALUES (?, ?, ?, ?)
|
|
78
|
+
RETURNING id`)
|
|
79
|
+
.get(input.eventType, input.ts, input.ref ?? null, JSON.stringify(input.metadata));
|
|
80
|
+
if (!result)
|
|
81
|
+
throw new Error(`Failed to persist ${input.eventType} event.`);
|
|
82
|
+
return result.id;
|
|
83
|
+
}
|
|
54
84
|
/**
|
|
55
85
|
* Read events from the database matching the filter. Returns events in
|
|
56
|
-
* ascending id order so consumers can process them in emission order
|
|
86
|
+
* ascending id order so consumers can process them in emission order —
|
|
87
|
+
* true even when `options.limit` selects the most-recent page (see
|
|
88
|
+
* {@link ReadStateEventsOptions.limit}).
|
|
57
89
|
*
|
|
58
90
|
* The returned `nextId` is the maximum id seen (or `sinceId` when no rows
|
|
59
|
-
* match), suitable as the next `sinceId` cursor value.
|
|
91
|
+
* match), suitable as the next `sinceId` cursor value. This is unaffected by
|
|
92
|
+
* `limit`: it is always the id of the last row actually returned, which —
|
|
93
|
+
* because a `limit` page is the MOST RECENT matching rows — is the same
|
|
94
|
+
* value an unbounded read of the same filter would have produced.
|
|
60
95
|
*/
|
|
61
96
|
export function readStateEvents(db, options = {}) {
|
|
62
97
|
const conditions = [];
|
|
@@ -78,10 +113,15 @@ export function readStateEvents(db, options = {}) {
|
|
|
78
113
|
params.push(options.ref);
|
|
79
114
|
}
|
|
80
115
|
const where = conditions.length > 0 ? `WHERE ${conditions.join(" AND ")}` : "";
|
|
116
|
+
const hasLimit = options.limit !== undefined && options.limit > 0;
|
|
117
|
+
const orderAndLimit = hasLimit ? "ORDER BY id DESC LIMIT ?" : "ORDER BY id ASC";
|
|
118
|
+
const queryParams = hasLimit ? [...params, options.limit] : params;
|
|
81
119
|
const rows = db
|
|
82
|
-
.prepare(`SELECT id, event_type, ts, ref, metadata_json FROM events ${where}
|
|
83
|
-
.all(...
|
|
84
|
-
|
|
120
|
+
.prepare(`SELECT id, event_type, ts, ref, metadata_json FROM events ${where} ${orderAndLimit}`)
|
|
121
|
+
.all(...queryParams);
|
|
122
|
+
// A DESC-ordered LIMIT page comes back newest-first; reverse it so the
|
|
123
|
+
// returned array is always ascending by id, matching the unbounded path.
|
|
124
|
+
const events = (hasLimit ? rows.slice().reverse() : rows).map(eventRowToEnvelope);
|
|
85
125
|
const nextId = events.length > 0 ? events[events.length - 1].id : (options.sinceId ?? 0);
|
|
86
126
|
return { events, nextId };
|
|
87
127
|
}
|
|
@@ -2,26 +2,6 @@
|
|
|
2
2
|
// License, v. 2.0. If a copy of the MPL was not distributed with this
|
|
3
3
|
// file, You can obtain one at https://mozilla.org/MPL/2.0/.
|
|
4
4
|
import { classifyImproveAction } from "../../core/improve-types.js";
|
|
5
|
-
// ── Per-phase gate threshold store (Migration 012) ───────────────────────────
|
|
6
|
-
/**
|
|
7
|
-
* Read the persisted auto-tuned threshold for a gate phase.
|
|
8
|
-
*
|
|
9
|
-
* Returns `undefined` when no row exists yet (first run, or the phase has
|
|
10
|
-
* never been tuned). The caller falls back to the global `options.autoAccept`
|
|
11
|
-
* in that case.
|
|
12
|
-
*/
|
|
13
|
-
export function getPhaseThreshold(db, phase) {
|
|
14
|
-
const row = db.prepare("SELECT threshold FROM improve_gate_thresholds WHERE phase = ?").get(phase);
|
|
15
|
-
return row?.threshold;
|
|
16
|
-
}
|
|
17
|
-
/**
|
|
18
|
-
* Persist the auto-tuned threshold for a gate phase.
|
|
19
|
-
* Uses INSERT OR REPLACE so the call is idempotent (upsert semantics).
|
|
20
|
-
*/
|
|
21
|
-
export function persistPhaseThreshold(db, phase, threshold) {
|
|
22
|
-
db.prepare(`INSERT OR REPLACE INTO improve_gate_thresholds (phase, threshold, updated_at)
|
|
23
|
-
VALUES (?, ?, ?)`).run(phase, Math.round(threshold), Date.now());
|
|
24
|
-
}
|
|
25
5
|
/**
|
|
26
6
|
* Compute the cheap aggregate metrics blob from a full improve result.
|
|
27
7
|
*
|
|
@@ -61,19 +41,13 @@ export function computeImproveRunMetrics(result) {
|
|
|
61
41
|
case "noop":
|
|
62
42
|
break;
|
|
63
43
|
}
|
|
64
|
-
// Legacy: pre-gate action results may carry autoAccepted: true (reflect path).
|
|
65
|
-
const r = action.result;
|
|
66
|
-
if (r && r.autoAccepted === true)
|
|
67
|
-
autoAcceptedCount++;
|
|
68
44
|
}
|
|
69
45
|
// Add gate-promoted count from the unified PostPhaseAutoAcceptGate (all phases).
|
|
70
46
|
autoAcceptedCount += result.gateAutoAcceptedCount ?? 0;
|
|
71
47
|
// C1 (13-bus-factor): distill-skipped rows are folded into the bounded
|
|
72
48
|
// `distillSkipped` aggregate and no longer live in `actions`. Add the
|
|
73
49
|
// aggregate total to the skipped + total-actions counters so metrics_json
|
|
74
|
-
//
|
|
75
|
-
// per-ref distill-skipped in `actions` have no aggregate, so they are counted
|
|
76
|
-
// by the classify loop above — never double-counted.)
|
|
50
|
+
// keeps aggregate metrics aligned with the logical action count.
|
|
77
51
|
const distillSkippedTotal = result.distillSkipped?.total ?? 0;
|
|
78
52
|
skippedCount += distillSkippedTotal;
|
|
79
53
|
return {
|
|
@@ -103,10 +77,10 @@ export function recordImproveRun(db, input) {
|
|
|
103
77
|
const metricsObj = input.metrics ?? computeImproveRunMetrics(input.result);
|
|
104
78
|
db.prepare(`
|
|
105
79
|
INSERT INTO improve_runs
|
|
106
|
-
|
|
80
|
+
(id, started_at, completed_at, stash_dir, dry_run, strategy,
|
|
107
81
|
scope_mode, scope_value, guidance, ok, result_json, metrics_json, metadata_json)
|
|
108
|
-
|
|
109
|
-
`).run(input.id, input.startedAt, input.completedAt, input.stashDir, input.dryRun ? 1 : 0, input.
|
|
82
|
+
VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)
|
|
83
|
+
`).run(input.id, input.startedAt, input.completedAt, input.stashDir, input.dryRun ? 1 : 0, input.strategy, input.scopeMode, input.scopeValue, input.guidance, input.ok ? 1 : 0, JSON.stringify(input.result), JSON.stringify(metricsObj), JSON.stringify(input.metadata ?? {}));
|
|
110
84
|
}
|
|
111
85
|
/**
|
|
112
86
|
* Read real (non-dry-run) improve_runs rows whose `started_at` falls in the
|
|
@@ -124,8 +98,8 @@ export function recordImproveRun(db, input) {
|
|
|
124
98
|
*/
|
|
125
99
|
export function queryImproveRuns(db, since, until) {
|
|
126
100
|
const sql = until
|
|
127
|
-
? "SELECT id, started_at, completed_at, ok, scope_mode, scope_value, result_json FROM improve_runs WHERE started_at >= ? AND started_at < ? AND dry_run = 0 ORDER BY started_at DESC"
|
|
128
|
-
: "SELECT id, started_at, completed_at, ok, scope_mode, scope_value, result_json FROM improve_runs WHERE started_at >= ? AND dry_run = 0 ORDER BY started_at DESC";
|
|
101
|
+
? "SELECT id, started_at, completed_at, ok, scope_mode, scope_value, strategy, result_json FROM improve_runs WHERE started_at >= ? AND started_at < ? AND dry_run = 0 ORDER BY started_at DESC"
|
|
102
|
+
: "SELECT id, started_at, completed_at, ok, scope_mode, scope_value, strategy, result_json FROM improve_runs WHERE started_at >= ? AND dry_run = 0 ORDER BY started_at DESC";
|
|
129
103
|
return (until ? db.prepare(sql).all(since, until) : db.prepare(sql).all(since));
|
|
130
104
|
}
|
|
131
105
|
/**
|
|
@@ -0,0 +1,79 @@
|
|
|
1
|
+
// This Source Code Form is subject to the terms of the Mozilla Public
|
|
2
|
+
// License, v. 2.0. If a copy of the MPL was not distributed with this
|
|
3
|
+
// file, You can obtain one at https://mozilla.org/MPL/2.0/.
|
|
4
|
+
/**
|
|
5
|
+
* `index.db` connection lifecycle for the storage layer.
|
|
6
|
+
*
|
|
7
|
+
* Opens/closes the index database, arming the sqlite-vec extension and (for the
|
|
8
|
+
* managed open path) running `ensureSchema`. This module lives BELOW the
|
|
9
|
+
* indexer, so the storage loan helpers (`index-db.ts`, `registry-cache.ts`)
|
|
10
|
+
* import their opener from a sibling here instead of reaching up into the
|
|
11
|
+
* indexer — inverting the old storage→indexer arrow.
|
|
12
|
+
*/
|
|
13
|
+
import fs from "node:fs";
|
|
14
|
+
import { createRequire } from "node:module";
|
|
15
|
+
import { getDbPath } from "../../core/paths.js";
|
|
16
|
+
import { openDatabase } from "../database.js";
|
|
17
|
+
import { openManagedDatabase } from "../managed-db.js";
|
|
18
|
+
import { ensureSchema } from "./index-schema.js";
|
|
19
|
+
import { loadVecExtension, warnIfVecMissing } from "./index-vec-repository.js";
|
|
20
|
+
export function openIndexDatabase(dbPath, options) {
|
|
21
|
+
return openManagedDatabase({
|
|
22
|
+
path: dbPath ?? getDbPath(),
|
|
23
|
+
init: (db) => {
|
|
24
|
+
// Try to load sqlite-vec extension
|
|
25
|
+
loadVecExtension(db);
|
|
26
|
+
// Dim resolution: explicit option wins; otherwise consult the on-disk
|
|
27
|
+
// config so unparameterised opens (registry providers, graph helpers,
|
|
28
|
+
// ad-hoc CLI subcommands) honour the operator-declared dimension. Only if
|
|
29
|
+
// both are absent do we fall through to the no-clobber path, which keeps
|
|
30
|
+
// ensureSchema from touching `index_meta.embeddingDim` at all.
|
|
31
|
+
const resolvedDim = options?.embeddingDim ?? resolveConfiguredEmbeddingDim();
|
|
32
|
+
ensureSchema(db, resolvedDim);
|
|
33
|
+
// Warn once at init if using JS fallback with many entries
|
|
34
|
+
warnIfVecMissing(db, { once: true });
|
|
35
|
+
},
|
|
36
|
+
});
|
|
37
|
+
}
|
|
38
|
+
/**
|
|
39
|
+
* Read the operator-configured embedding dimension from the on-disk config.
|
|
40
|
+
* Returns `undefined` when no config file is present, when the config has
|
|
41
|
+
* no `embedding.dimension` set, or when reading the config throws (e.g.
|
|
42
|
+
* inside isolated test fixtures with no XDG home). Failure is silent on
|
|
43
|
+
* purpose — every openDatabase() call would otherwise have to handle a
|
|
44
|
+
* config-not-found error path, and the fallback (no-clobber semantics) is
|
|
45
|
+
* already correct.
|
|
46
|
+
*/
|
|
47
|
+
function resolveConfiguredEmbeddingDim() {
|
|
48
|
+
try {
|
|
49
|
+
const esmRequire = createRequire(import.meta.url);
|
|
50
|
+
const { loadConfig } = esmRequire("../../core/config/config");
|
|
51
|
+
const dim = loadConfig().embedding?.dimension;
|
|
52
|
+
if (typeof dim === "number" && Number.isInteger(dim) && dim > 0 && dim <= 4096) {
|
|
53
|
+
return dim;
|
|
54
|
+
}
|
|
55
|
+
return undefined;
|
|
56
|
+
}
|
|
57
|
+
catch {
|
|
58
|
+
return undefined;
|
|
59
|
+
}
|
|
60
|
+
}
|
|
61
|
+
export function openExistingDatabase(dbPath) {
|
|
62
|
+
// Existing-DB callers must not mutate schema or embedding metadata on open,
|
|
63
|
+
// but some paths still need write access to usage_events and other tables —
|
|
64
|
+
// so init only loads the vec extension, it does not run ensureSchema.
|
|
65
|
+
return openManagedDatabase({ path: dbPath ?? getDbPath(), init: loadVecExtension });
|
|
66
|
+
}
|
|
67
|
+
/**
|
|
68
|
+
* Open an existing index for queries without creating directories, a database
|
|
69
|
+
* file, journals, or running write-capable pragmas/schema initialization.
|
|
70
|
+
*/
|
|
71
|
+
export function openReadonlyExistingDatabase(dbPath) {
|
|
72
|
+
const resolvedPath = dbPath ?? getDbPath();
|
|
73
|
+
if (!fs.existsSync(resolvedPath))
|
|
74
|
+
return undefined;
|
|
75
|
+
return openDatabase(resolvedPath, { readonly: true, create: false });
|
|
76
|
+
}
|
|
77
|
+
export function closeDatabase(db) {
|
|
78
|
+
db.close();
|
|
79
|
+
}
|
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
// This Source Code Form is subject to the terms of the Mozilla Public
|
|
2
2
|
// License, v. 2.0. If a copy of the MPL was not distributed with this
|
|
3
3
|
// file, You can obtain one at https://mozilla.org/MPL/2.0/.
|
|
4
|
-
import { openExistingDatabase } from "../../indexer/db/db.js";
|
|
5
4
|
import { resolveStorageLocations } from "../locations.js";
|
|
6
5
|
import { withManagedDb } from "../managed-db.js";
|
|
6
|
+
import { openExistingDatabase } from "./index-connection.js";
|
|
7
7
|
/**
|
|
8
8
|
* Busy-timeout (ms) for read-path telemetry writers. Small on purpose: a
|
|
9
9
|
* usage-event insert contending with a background reindex should be dropped,
|
|
@@ -13,8 +13,9 @@ export const TELEMETRY_BUSY_TIMEOUT_MS = 250;
|
|
|
13
13
|
/**
|
|
14
14
|
* Scoped-resource (loan pattern) helper for the index database (`index.db`).
|
|
15
15
|
*
|
|
16
|
-
* This is the `index.db` twin of
|
|
17
|
-
* {@link ./workflow-runs-repository
|
|
16
|
+
* This is the `index.db` twin of the state.db loan helpers ({@link
|
|
17
|
+
* ../../core/state-db withStateDb} / {@link ./workflow-runs-repository
|
|
18
|
+
* withWorkflowRunsRepo}): it opens the index
|
|
18
19
|
* database bound to {@link StorageLocations.indexDb}, runs `fn` against the live
|
|
19
20
|
* {@link Database}, and closes the connection exactly once when `fn` returns —
|
|
20
21
|
* even if `fn` throws. Callers no longer hand-roll `open / try / finally / close`
|