akm-cli 0.9.0-rc.1 → 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 +1190 -52
- 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/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 +13 -9
- package/dist/commands/env/env-cli.js +76 -159
- 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/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 +75 -228
- 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 -855
- 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/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 -73
- 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 -58
- 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 +8 -3
- package/dist/integrations/agent/profiles.js +6 -99
- package/dist/integrations/agent/prompts.js +46 -18
- package/dist/integrations/agent/runner-dispatch.js +78 -13
- package/dist/integrations/agent/runner.js +76 -208
- package/dist/integrations/agent/spawn.js +48 -279
- package/dist/integrations/harnesses/aider/agent-builder.js +9 -8
- package/dist/integrations/harnesses/aider/index.js +2 -12
- package/dist/integrations/harnesses/amazonq/agent-builder.js +10 -16
- package/dist/integrations/harnesses/amazonq/index.js +3 -17
- package/dist/integrations/harnesses/claude/agent-builder.js +2 -3
- package/dist/integrations/harnesses/claude/config-import.js +1 -3
- package/dist/integrations/harnesses/claude/index.js +1 -14
- package/dist/integrations/harnesses/claude/session-log.js +27 -75
- package/dist/integrations/harnesses/codex/agent-builder.js +8 -7
- package/dist/integrations/harnesses/codex/index.js +2 -13
- package/dist/integrations/harnesses/copilot/agent-builder.js +9 -9
- package/dist/integrations/harnesses/copilot/index.js +1 -13
- package/dist/integrations/harnesses/gemini/agent-builder.js +8 -9
- package/dist/integrations/harnesses/gemini/index.js +1 -13
- package/dist/integrations/harnesses/ids.js +24 -0
- package/dist/integrations/harnesses/index.js +31 -33
- 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 +1 -18
- package/dist/integrations/harnesses/opencode/session-log.js +67 -125
- package/dist/integrations/harnesses/opencode-sdk/harness.js +3 -17
- package/dist/integrations/harnesses/opencode-sdk/sdk-runner.js +274 -191
- package/dist/integrations/harnesses/openhands/agent-builder.js +12 -10
- package/dist/integrations/harnesses/openhands/index.js +2 -12
- package/dist/integrations/harnesses/pi/agent-builder.js +11 -18
- package/dist/integrations/harnesses/pi/index.js +3 -16
- package/dist/integrations/harnesses/shared.js +17 -0
- package/dist/integrations/harnesses/types.js +38 -34
- package/dist/integrations/lockfile.js +211 -24
- package/dist/integrations/session-logs/index.js +24 -40
- 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 +15 -281
- 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 +8 -40
- 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 -1375
- 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 +1 -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 +68 -35
- 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/workflows/authoring/authoring.js +96 -148
- package/dist/workflows/authoring/scope-key.js +1 -1
- package/dist/workflows/cli.js +0 -20
- package/dist/workflows/concurrency-policy.js +15 -0
- package/dist/workflows/exec/brief.js +25 -59
- package/dist/workflows/exec/frozen-judge.js +47 -0
- package/dist/workflows/exec/native-executor.js +157 -94
- package/dist/workflows/exec/report.js +365 -200
- package/dist/workflows/exec/run-workflow.js +46 -40
- package/dist/workflows/exec/scheduler.js +12 -41
- package/dist/workflows/exec/step-work.js +239 -205
- package/dist/workflows/exec/workflow-engine-gate.js +67 -0
- package/dist/workflows/ir/compile.js +141 -283
- package/dist/workflows/ir/freeze.js +233 -0
- package/dist/workflows/ir/plan-hash.js +40 -5
- package/dist/workflows/ir/schema.js +537 -1
- package/dist/workflows/parser.js +878 -306
- package/dist/workflows/program/expressions.js +20 -208
- package/dist/workflows/program/schema.js +7 -10
- package/dist/workflows/renderer.js +99 -121
- package/dist/workflows/resource-limits.js +22 -0
- package/dist/workflows/runtime/checkin.js +1 -1
- package/dist/workflows/runtime/plan-classifier.js +131 -0
- package/dist/workflows/runtime/runs.js +200 -113
- package/dist/workflows/runtime/unit-checkin.js +1 -1
- package/dist/workflows/runtime/unit-phases.js +20 -0
- package/dist/workflows/runtime/workflow-asset-loader.js +235 -97
- package/dist/workflows/schema.js +1 -11
- package/dist/workflows/validate-summary.js +4 -26
- 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/{dist/schemas → schemas}/akm-workflow.json +127 -82
- 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 -316
- 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 -1414
- 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 -25
- 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/schemas/akm-config.json +0 -14225
- package/dist/scripts/migrate-storage.js +0 -13169
- package/dist/scripts/migrations/import-fs-improve-runs-to-db.js +0 -10169
- 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/authoring/workflow-program-template.yaml +0 -31
- package/dist/workflows/db.js +0 -350
- package/dist/workflows/exec/watch.js +0 -116
- package/dist/workflows/program/parser.js +0 -760
- package/dist/workflows/program/project.js +0 -105
- package/docs/data-and-telemetry.md +0 -227
- package/docs/migration/release-notes/0.9.0-beta.60.md +0 -19
- /package/dist/sources/{wiki-fetchers → snapshot-fetchers}/registry.js +0 -0
- /package/dist/sources/{wiki-fetchers → snapshot-fetchers}/youtube.js +0 -0
|
@@ -0,0 +1,119 @@
|
|
|
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
|
+
* Upsert one `asset_outcome` row. Extracted verbatim from the tail of
|
|
6
|
+
* `updateAssetOutcome` in outcome-loop.ts — same SQL text, same bind order;
|
|
7
|
+
* the business logic that computes these values (warm-start seed vs.
|
|
8
|
+
* differential update) stays in outcome-loop.ts and calls this function.
|
|
9
|
+
*
|
|
10
|
+
* `review_pressure` is intentionally omitted from both the INSERT column list
|
|
11
|
+
* and the ON CONFLICT SET clause: the column's DEFAULT 0 seeds fresh rows, and
|
|
12
|
+
* omitting it from SET leaves an existing row's value untouched on update
|
|
13
|
+
* (never written going forward). The column itself is dropped in migration 018.
|
|
14
|
+
*/
|
|
15
|
+
export function upsertAssetOutcome(db, values) {
|
|
16
|
+
db.prepare(`INSERT INTO asset_outcome
|
|
17
|
+
(asset_ref, last_retrieved_at, retrieval_count, expected_retrieval_rate,
|
|
18
|
+
negative_feedback_count, accepted_change_count,
|
|
19
|
+
outcome_score, updated_at)
|
|
20
|
+
VALUES (?, ?, ?, ?, ?, ?, ?, ?)
|
|
21
|
+
ON CONFLICT(asset_ref) DO UPDATE SET
|
|
22
|
+
last_retrieved_at = excluded.last_retrieved_at,
|
|
23
|
+
retrieval_count = excluded.retrieval_count,
|
|
24
|
+
expected_retrieval_rate= excluded.expected_retrieval_rate,
|
|
25
|
+
negative_feedback_count= excluded.negative_feedback_count,
|
|
26
|
+
accepted_change_count = excluded.accepted_change_count,
|
|
27
|
+
outcome_score = excluded.outcome_score,
|
|
28
|
+
updated_at = excluded.updated_at`).run(values.ref, values.lastRetrievedAt, values.retrievalCount, values.expectedRetrievalRate, values.negativeFeedbackCount, values.acceptedChangeCount, values.outcomeScore, values.updatedAt);
|
|
29
|
+
}
|
|
30
|
+
/**
|
|
31
|
+
* Load the outcome row for one asset, or `undefined` if not yet written.
|
|
32
|
+
*/
|
|
33
|
+
export function getAssetOutcome(db, ref) {
|
|
34
|
+
const row = db
|
|
35
|
+
.prepare(`SELECT asset_ref, last_retrieved_at, retrieval_count, expected_retrieval_rate,
|
|
36
|
+
negative_feedback_count, accepted_change_count,
|
|
37
|
+
outcome_score, updated_at
|
|
38
|
+
FROM asset_outcome WHERE asset_ref = ?`)
|
|
39
|
+
.get(ref);
|
|
40
|
+
return row == null ? undefined : row;
|
|
41
|
+
}
|
|
42
|
+
/**
|
|
43
|
+
* Load ALL asset_outcome rows. Used for the proxy-adequacy tripwire computation.
|
|
44
|
+
*/
|
|
45
|
+
export function getAllAssetOutcomes(db) {
|
|
46
|
+
return db
|
|
47
|
+
.prepare(`SELECT asset_ref, last_retrieved_at, retrieval_count, expected_retrieval_rate,
|
|
48
|
+
negative_feedback_count, accepted_change_count,
|
|
49
|
+
outcome_score, updated_at
|
|
50
|
+
FROM asset_outcome ORDER BY asset_ref`)
|
|
51
|
+
.all();
|
|
52
|
+
}
|
|
53
|
+
/**
|
|
54
|
+
* Build a Map<ref, outcome_score> for a set of refs in one query.
|
|
55
|
+
* Used by `salience.ts` to populate `outcomeSalience`.
|
|
56
|
+
*/
|
|
57
|
+
export function getOutcomeScoresByRef(db, refs) {
|
|
58
|
+
const result = new Map();
|
|
59
|
+
if (refs.length === 0)
|
|
60
|
+
return result;
|
|
61
|
+
const CHUNK = 500;
|
|
62
|
+
for (let i = 0; i < refs.length; i += CHUNK) {
|
|
63
|
+
const chunk = refs.slice(i, i + CHUNK);
|
|
64
|
+
const placeholders = chunk.map(() => "?").join(",");
|
|
65
|
+
const rows = db
|
|
66
|
+
.prepare(`SELECT asset_ref, outcome_score FROM asset_outcome WHERE asset_ref IN (${placeholders})`)
|
|
67
|
+
.all(...chunk);
|
|
68
|
+
for (const row of rows) {
|
|
69
|
+
result.set(row.asset_ref, row.outcome_score);
|
|
70
|
+
}
|
|
71
|
+
}
|
|
72
|
+
return result;
|
|
73
|
+
}
|
|
74
|
+
/** List every `asset_outcome` ref with its current `missing_since` marker. */
|
|
75
|
+
export function listAssetOutcomeMissingState(db) {
|
|
76
|
+
return db.prepare(`SELECT asset_ref, missing_since FROM asset_outcome`).all();
|
|
77
|
+
}
|
|
78
|
+
/**
|
|
79
|
+
* Stamp `missing_since = now` for the given refs, but ONLY where it is
|
|
80
|
+
* currently NULL — a ref already stamped keeps its original timestamp so the
|
|
81
|
+
* grace window measures from first sighting, not last. Refs with no row at
|
|
82
|
+
* all are silently skipped (0 rows affected). Returns the number of rows
|
|
83
|
+
* actually stamped.
|
|
84
|
+
*/
|
|
85
|
+
export function stampAssetOutcomeMissing(db, refs, now) {
|
|
86
|
+
if (refs.length === 0)
|
|
87
|
+
return 0;
|
|
88
|
+
const stmt = db.prepare(`UPDATE asset_outcome SET missing_since = ? WHERE asset_ref = ? AND missing_since IS NULL`);
|
|
89
|
+
let changed = 0;
|
|
90
|
+
for (const ref of refs)
|
|
91
|
+
changed += Number(stmt.run(now, ref).changes);
|
|
92
|
+
return changed;
|
|
93
|
+
}
|
|
94
|
+
/**
|
|
95
|
+
* Clear `missing_since` for refs that resolved again. Returns the number of
|
|
96
|
+
* rows actually cleared.
|
|
97
|
+
*/
|
|
98
|
+
export function clearAssetOutcomeMissing(db, refs) {
|
|
99
|
+
if (refs.length === 0)
|
|
100
|
+
return 0;
|
|
101
|
+
const stmt = db.prepare(`UPDATE asset_outcome SET missing_since = NULL WHERE asset_ref = ? AND missing_since IS NOT NULL`);
|
|
102
|
+
let changed = 0;
|
|
103
|
+
for (const ref of refs)
|
|
104
|
+
changed += Number(stmt.run(ref).changes);
|
|
105
|
+
return changed;
|
|
106
|
+
}
|
|
107
|
+
/**
|
|
108
|
+
* Delete `asset_outcome` rows whose `missing_since` is older than
|
|
109
|
+
* `cutoffMs`. A single DELETE — SQLite runs it as one implicit transaction.
|
|
110
|
+
* Returns the number of rows deleted.
|
|
111
|
+
*/
|
|
112
|
+
export function deleteAssetOutcomeMissingBefore(db, cutoffMs) {
|
|
113
|
+
return Number(db.prepare(`DELETE FROM asset_outcome WHERE missing_since IS NOT NULL AND missing_since < ?`).run(cutoffMs).changes);
|
|
114
|
+
}
|
|
115
|
+
/** Count `asset_outcome` rows currently marked missing (the live backlog size). */
|
|
116
|
+
export function countAssetOutcomeMissing(db) {
|
|
117
|
+
const row = db.prepare(`SELECT COUNT(*) AS n FROM asset_outcome WHERE missing_since IS NOT NULL`).get();
|
|
118
|
+
return row.n;
|
|
119
|
+
}
|
|
@@ -1,29 +1,195 @@
|
|
|
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
|
+
* Repository for the state.db `proposals` table. Extracted verbatim from
|
|
6
|
+
* core/state-db.ts — queries and row-mapping unchanged, only relocated behind
|
|
7
|
+
* the repository boundary. Re-exported by core/state-db.ts so existing importers
|
|
8
|
+
* resolve.
|
|
9
|
+
*
|
|
10
|
+
* @module proposals-repository
|
|
11
|
+
*/
|
|
12
|
+
import path from "node:path";
|
|
13
|
+
import { stashDirFor } from "../../core/asset/asset-placement.js";
|
|
14
|
+
import { bundleRefToString, isBundleSlug, parseBundleRef } from "../../core/asset/asset-ref.js";
|
|
15
|
+
/** Serialize `Proposal.changes` for `metadata_json` (see {@link StoredFileChange}). */
|
|
16
|
+
function changesToStored(changes) {
|
|
17
|
+
return changes.map((c, i) => ({
|
|
18
|
+
path: c.path,
|
|
19
|
+
op: c.op,
|
|
20
|
+
...(i > 0 && c.after !== undefined ? { after: c.after } : {}),
|
|
21
|
+
}));
|
|
22
|
+
}
|
|
23
|
+
/**
|
|
24
|
+
* Reconstruct `Proposal.changes` from `metadata_json.changes` + the `content`
|
|
25
|
+
* column.
|
|
26
|
+
*/
|
|
27
|
+
function storedToChanges(stored, content) {
|
|
28
|
+
if (!Array.isArray(stored) || stored.length === 0) {
|
|
29
|
+
throw new Error("Proposal metadata is missing changes.");
|
|
30
|
+
}
|
|
31
|
+
return stored.map((value, i) => {
|
|
32
|
+
if (typeof value !== "object" || value === null)
|
|
33
|
+
throw new Error("Proposal metadata has invalid changes.");
|
|
34
|
+
const c = value;
|
|
35
|
+
if (typeof c.path !== "string" ||
|
|
36
|
+
(c.op !== "create" && c.op !== "update" && c.op !== "delete") ||
|
|
37
|
+
(c.after !== undefined && typeof c.after !== "string") ||
|
|
38
|
+
(c.op === "delete" && c.after !== undefined) ||
|
|
39
|
+
(i > 0 && c.op !== "delete" && typeof c.after !== "string")) {
|
|
40
|
+
throw new Error("Proposal metadata has invalid changes.");
|
|
41
|
+
}
|
|
42
|
+
return {
|
|
43
|
+
path: c.path,
|
|
44
|
+
op: c.op,
|
|
45
|
+
...(i === 0 ? (c.op === "delete" ? {} : { after: content }) : c.after !== undefined ? { after: c.after } : {}),
|
|
46
|
+
};
|
|
47
|
+
});
|
|
48
|
+
}
|
|
49
|
+
function currentProposalRef(ref, requireQualified = false) {
|
|
50
|
+
let parsed;
|
|
51
|
+
try {
|
|
52
|
+
parsed = parseBundleRef(ref);
|
|
53
|
+
}
|
|
54
|
+
catch (error) {
|
|
55
|
+
throw new Error(`Proposal row has an invalid current ref: ${ref}`, { cause: error });
|
|
56
|
+
}
|
|
57
|
+
const colon = parsed.conceptId.indexOf(":");
|
|
58
|
+
if (colon > 0 && stashDirFor(parsed.conceptId.slice(0, colon)) !== undefined) {
|
|
59
|
+
throw new Error(`Proposal row has an invalid current ref: ${ref}`);
|
|
60
|
+
}
|
|
61
|
+
if (parsed.fragment !== undefined)
|
|
62
|
+
throw new Error(`Proposal row ref contains a fragment: ${ref}`);
|
|
63
|
+
if (requireQualified && parsed.bundle === undefined)
|
|
64
|
+
throw new Error(`Proposal ref is not bundle-qualified: ${ref}`);
|
|
65
|
+
const canonical = bundleRefToString(parsed);
|
|
66
|
+
if (canonical !== ref)
|
|
67
|
+
throw new Error(`Proposal row ref is not canonical: ${ref}`);
|
|
68
|
+
return canonical;
|
|
69
|
+
}
|
|
70
|
+
function currentProposalTarget(value) {
|
|
71
|
+
if (typeof value !== "object" || value === null)
|
|
72
|
+
throw new Error("Proposal metadata is missing proposedTarget.");
|
|
73
|
+
const target = value;
|
|
74
|
+
if (typeof target.source !== "string" ||
|
|
75
|
+
!isBundleSlug(target.source) ||
|
|
76
|
+
typeof target.root !== "string" ||
|
|
77
|
+
!path.isAbsolute(target.root)) {
|
|
78
|
+
throw new Error("Proposal metadata has an invalid proposedTarget.");
|
|
79
|
+
}
|
|
80
|
+
return { source: target.source, root: path.resolve(target.root) };
|
|
81
|
+
}
|
|
82
|
+
function invalidPresentField(name) {
|
|
83
|
+
throw new Error(`Proposal metadata has an invalid ${name}.`);
|
|
84
|
+
}
|
|
85
|
+
const GATE_OUTCOMES = {
|
|
86
|
+
"auto-accepted": true,
|
|
87
|
+
deferred: true,
|
|
88
|
+
staged: true,
|
|
89
|
+
"auto-rejected": true,
|
|
90
|
+
};
|
|
91
|
+
function validatePresentMetadata(meta) {
|
|
92
|
+
const stringFields = ["sourceRun", "beforeHash", "backupContent"];
|
|
93
|
+
for (const field of stringFields) {
|
|
94
|
+
if (Object.hasOwn(meta, field) && typeof meta[field] !== "string")
|
|
95
|
+
invalidPresentField(field);
|
|
96
|
+
}
|
|
97
|
+
if (Object.hasOwn(meta, "confidence") &&
|
|
98
|
+
(typeof meta.confidence !== "number" ||
|
|
99
|
+
!Number.isFinite(meta.confidence) ||
|
|
100
|
+
meta.confidence < 0 ||
|
|
101
|
+
meta.confidence > 1)) {
|
|
102
|
+
invalidPresentField("confidence");
|
|
103
|
+
}
|
|
104
|
+
if (Object.hasOwn(meta, "review")) {
|
|
105
|
+
const review = meta.review;
|
|
106
|
+
if (typeof review !== "object" ||
|
|
107
|
+
review === null ||
|
|
108
|
+
(review.outcome !== "accepted" && review.outcome !== "rejected") ||
|
|
109
|
+
typeof review.decidedAt !== "string" ||
|
|
110
|
+
(review.reason !== undefined && typeof review.reason !== "string")) {
|
|
111
|
+
invalidPresentField("review");
|
|
112
|
+
}
|
|
113
|
+
}
|
|
114
|
+
if (Object.hasOwn(meta, "gateDecision")) {
|
|
115
|
+
const gate = meta.gateDecision;
|
|
116
|
+
if (typeof gate !== "object" ||
|
|
117
|
+
gate === null ||
|
|
118
|
+
typeof gate.outcome !== "string" ||
|
|
119
|
+
!Object.hasOwn(GATE_OUTCOMES, gate.outcome) ||
|
|
120
|
+
typeof gate.reason !== "string" ||
|
|
121
|
+
typeof gate.decidedAt !== "string" ||
|
|
122
|
+
(gate.measured !== undefined && (typeof gate.measured !== "number" || !Number.isFinite(gate.measured))) ||
|
|
123
|
+
(gate.contentHash !== undefined && typeof gate.contentHash !== "string") ||
|
|
124
|
+
(gate.gate !== undefined && typeof gate.gate !== "string")) {
|
|
125
|
+
invalidPresentField("gateDecision");
|
|
126
|
+
}
|
|
127
|
+
if (gate.thresholds !== undefined) {
|
|
128
|
+
const thresholds = gate.thresholds;
|
|
129
|
+
if (typeof thresholds !== "object" ||
|
|
130
|
+
thresholds === null ||
|
|
131
|
+
[thresholds.maxDiffLines, thresholds.minContentLines].some((value) => value !== undefined && (typeof value !== "number" || !Number.isFinite(value)))) {
|
|
132
|
+
invalidPresentField("gateDecision");
|
|
133
|
+
}
|
|
134
|
+
}
|
|
135
|
+
}
|
|
136
|
+
if (Object.hasOwn(meta, "acceptedTarget")) {
|
|
137
|
+
const target = meta.acceptedTarget;
|
|
138
|
+
if (typeof target !== "object" ||
|
|
139
|
+
target === null ||
|
|
140
|
+
typeof target.source !== "string" ||
|
|
141
|
+
!isBundleSlug(target.source) ||
|
|
142
|
+
typeof target.root !== "string" ||
|
|
143
|
+
!path.isAbsolute(target.root) ||
|
|
144
|
+
typeof target.path !== "string" ||
|
|
145
|
+
!path.isAbsolute(target.path) ||
|
|
146
|
+
typeof target.contentHash !== "string") {
|
|
147
|
+
invalidPresentField("acceptedTarget");
|
|
148
|
+
}
|
|
149
|
+
}
|
|
150
|
+
if (Object.hasOwn(meta, "eligibilitySource") && typeof meta.eligibilitySource !== "string") {
|
|
151
|
+
invalidPresentField("eligibilitySource");
|
|
152
|
+
}
|
|
153
|
+
}
|
|
4
154
|
/**
|
|
5
155
|
* Convert a raw `ProposalRow` to the public `Proposal` shape.
|
|
6
156
|
*/
|
|
7
157
|
export function proposalRowToProposal(row) {
|
|
158
|
+
if (!["pending", "accepted", "rejected", "reverted"].includes(row.status)) {
|
|
159
|
+
throw new Error(`Proposal row has invalid status: ${row.status}`);
|
|
160
|
+
}
|
|
8
161
|
let frontmatter;
|
|
9
|
-
if (row.frontmatter_json) {
|
|
162
|
+
if (row.frontmatter_json !== null) {
|
|
10
163
|
try {
|
|
11
|
-
|
|
164
|
+
const parsed = JSON.parse(row.frontmatter_json);
|
|
165
|
+
if (typeof parsed !== "object" || parsed === null || Array.isArray(parsed)) {
|
|
166
|
+
throw new Error("Proposal frontmatter_json must contain an object.");
|
|
167
|
+
}
|
|
168
|
+
frontmatter = parsed;
|
|
12
169
|
}
|
|
13
|
-
catch {
|
|
14
|
-
|
|
170
|
+
catch (error) {
|
|
171
|
+
throw new Error("Proposal row has invalid frontmatter_json.", { cause: error });
|
|
15
172
|
}
|
|
16
173
|
}
|
|
17
174
|
let meta = {};
|
|
18
175
|
try {
|
|
19
|
-
|
|
176
|
+
const parsed = JSON.parse(row.metadata_json);
|
|
177
|
+
if (typeof parsed !== "object" || parsed === null || Array.isArray(parsed)) {
|
|
178
|
+
throw new Error("Proposal metadata_json must contain an object.");
|
|
179
|
+
}
|
|
180
|
+
meta = parsed;
|
|
20
181
|
}
|
|
21
|
-
catch {
|
|
22
|
-
|
|
182
|
+
catch (error) {
|
|
183
|
+
throw new Error("Proposal row has invalid metadata_json.", { cause: error });
|
|
23
184
|
}
|
|
185
|
+
validatePresentMetadata(meta);
|
|
186
|
+
const changes = Object.hasOwn(meta, "changes")
|
|
187
|
+
? storedToChanges(meta.changes, row.content)
|
|
188
|
+
: [{ path: "", op: "update", after: row.content }];
|
|
189
|
+
const proposedTarget = Object.hasOwn(meta, "proposedTarget") ? currentProposalTarget(meta.proposedTarget) : undefined;
|
|
24
190
|
return {
|
|
25
191
|
id: row.id,
|
|
26
|
-
ref: row.ref,
|
|
192
|
+
ref: currentProposalRef(row.ref),
|
|
27
193
|
status: row.status,
|
|
28
194
|
source: row.source,
|
|
29
195
|
...(typeof meta.sourceRun === "string" ? { sourceRun: meta.sourceRun } : {}),
|
|
@@ -33,15 +199,123 @@ export function proposalRowToProposal(row) {
|
|
|
33
199
|
content: row.content,
|
|
34
200
|
...(frontmatter !== undefined ? { frontmatter } : {}),
|
|
35
201
|
},
|
|
202
|
+
changes,
|
|
203
|
+
...(proposedTarget !== undefined ? { proposedTarget } : {}),
|
|
204
|
+
...(typeof meta.beforeHash === "string" ? { beforeHash: meta.beforeHash } : {}),
|
|
36
205
|
...(meta.review !== undefined ? { review: meta.review } : {}),
|
|
37
206
|
...(typeof meta.confidence === "number" ? { confidence: meta.confidence } : {}),
|
|
38
207
|
...(meta.gateDecision !== undefined ? { gateDecision: meta.gateDecision } : {}),
|
|
39
208
|
...(typeof meta.backupContent === "string" ? { backupContent: meta.backupContent } : {}),
|
|
209
|
+
...(meta.acceptedTarget !== undefined ? { acceptedTarget: meta.acceptedTarget } : {}),
|
|
40
210
|
...(typeof meta.eligibilitySource === "string"
|
|
41
211
|
? { eligibilitySource: meta.eligibilitySource }
|
|
42
212
|
: {}),
|
|
43
213
|
};
|
|
44
214
|
}
|
|
215
|
+
/**
|
|
216
|
+
* Lenient counterpart to {@link proposalRowToProposal} for the terminal-status
|
|
217
|
+
* (reject/archive) read paths (repository.ts `archiveProposal` /
|
|
218
|
+
* `rejectProposalDurably`). Those paths must succeed even on legacy rows
|
|
219
|
+
* minted before a field was required — e.g. 0.8-era rows missing
|
|
220
|
+
* `proposedTarget` and/or carrying empty/missing `changes[].path` metadata —
|
|
221
|
+
* so an operator can reject them instead of resorting to manual SQL.
|
|
222
|
+
*
|
|
223
|
+
* Per-field decode failures are swallowed: the offending field degrades to a
|
|
224
|
+
* safe placeholder (matching the strict decoder's own "no changes recorded"
|
|
225
|
+
* fallback) and the failure is appended to `decodeWarnings` instead of
|
|
226
|
+
* throwing. `id` / `status` / timestamps / `source` are trusted verbatim (the
|
|
227
|
+
* schema guarantees they're non-null strings). The strict decoder remains the
|
|
228
|
+
* default everywhere else, including every other read of a `pending` or
|
|
229
|
+
* `accepted` proposal (accept/revert must keep failing exactly as today on a
|
|
230
|
+
* malformed row).
|
|
231
|
+
*/
|
|
232
|
+
export function proposalRowToProposalLenient(row) {
|
|
233
|
+
const warnings = [];
|
|
234
|
+
let meta = {};
|
|
235
|
+
try {
|
|
236
|
+
const parsed = JSON.parse(row.metadata_json);
|
|
237
|
+
if (typeof parsed !== "object" || parsed === null || Array.isArray(parsed)) {
|
|
238
|
+
throw new Error("metadata_json must contain an object.");
|
|
239
|
+
}
|
|
240
|
+
meta = parsed;
|
|
241
|
+
validatePresentMetadata(meta);
|
|
242
|
+
}
|
|
243
|
+
catch (error) {
|
|
244
|
+
warnings.push(`metadata_json is invalid (${error instanceof Error ? error.message : String(error)}); optional fields dropped.`);
|
|
245
|
+
meta = {};
|
|
246
|
+
}
|
|
247
|
+
let frontmatter;
|
|
248
|
+
if (row.frontmatter_json !== null) {
|
|
249
|
+
try {
|
|
250
|
+
const parsed = JSON.parse(row.frontmatter_json);
|
|
251
|
+
if (typeof parsed !== "object" || parsed === null || Array.isArray(parsed)) {
|
|
252
|
+
throw new Error("frontmatter_json must contain an object.");
|
|
253
|
+
}
|
|
254
|
+
frontmatter = parsed;
|
|
255
|
+
}
|
|
256
|
+
catch (error) {
|
|
257
|
+
warnings.push(`frontmatter_json is invalid (${error instanceof Error ? error.message : String(error)}); frontmatter dropped.`);
|
|
258
|
+
}
|
|
259
|
+
}
|
|
260
|
+
let ref;
|
|
261
|
+
try {
|
|
262
|
+
ref = currentProposalRef(row.ref);
|
|
263
|
+
}
|
|
264
|
+
catch (error) {
|
|
265
|
+
warnings.push(`ref is invalid (${error instanceof Error ? error.message : String(error)}); keeping the raw stored value.`);
|
|
266
|
+
ref = row.ref;
|
|
267
|
+
}
|
|
268
|
+
let changes;
|
|
269
|
+
try {
|
|
270
|
+
changes = Object.hasOwn(meta, "changes")
|
|
271
|
+
? storedToChanges(meta.changes, row.content)
|
|
272
|
+
: [{ path: "", op: "update", after: row.content }];
|
|
273
|
+
}
|
|
274
|
+
catch (error) {
|
|
275
|
+
warnings.push(`changes metadata is invalid (${error instanceof Error ? error.message : String(error)}); degraded to a single placeholder change.`);
|
|
276
|
+
changes = [{ path: "", op: "update", after: row.content }];
|
|
277
|
+
}
|
|
278
|
+
let proposedTarget;
|
|
279
|
+
if (Object.hasOwn(meta, "proposedTarget")) {
|
|
280
|
+
try {
|
|
281
|
+
proposedTarget = currentProposalTarget(meta.proposedTarget);
|
|
282
|
+
}
|
|
283
|
+
catch (error) {
|
|
284
|
+
warnings.push(`proposedTarget is invalid (${error instanceof Error ? error.message : String(error)}); omitted.`);
|
|
285
|
+
}
|
|
286
|
+
}
|
|
287
|
+
else {
|
|
288
|
+
warnings.push("proposedTarget is missing (pre-WI-6.2 legacy row).");
|
|
289
|
+
}
|
|
290
|
+
if (!["pending", "accepted", "rejected", "reverted"].includes(row.status)) {
|
|
291
|
+
warnings.push(`status "${row.status}" is not a recognized value.`);
|
|
292
|
+
}
|
|
293
|
+
return {
|
|
294
|
+
id: row.id,
|
|
295
|
+
ref,
|
|
296
|
+
status: row.status,
|
|
297
|
+
source: row.source,
|
|
298
|
+
...(typeof meta.sourceRun === "string" ? { sourceRun: meta.sourceRun } : {}),
|
|
299
|
+
createdAt: row.created_at,
|
|
300
|
+
updatedAt: row.updated_at,
|
|
301
|
+
payload: {
|
|
302
|
+
content: row.content,
|
|
303
|
+
...(frontmatter !== undefined ? { frontmatter } : {}),
|
|
304
|
+
},
|
|
305
|
+
changes,
|
|
306
|
+
...(proposedTarget !== undefined ? { proposedTarget } : {}),
|
|
307
|
+
...(typeof meta.beforeHash === "string" ? { beforeHash: meta.beforeHash } : {}),
|
|
308
|
+
...(meta.review !== undefined ? { review: meta.review } : {}),
|
|
309
|
+
...(typeof meta.confidence === "number" ? { confidence: meta.confidence } : {}),
|
|
310
|
+
...(meta.gateDecision !== undefined ? { gateDecision: meta.gateDecision } : {}),
|
|
311
|
+
...(typeof meta.backupContent === "string" ? { backupContent: meta.backupContent } : {}),
|
|
312
|
+
...(meta.acceptedTarget !== undefined ? { acceptedTarget: meta.acceptedTarget } : {}),
|
|
313
|
+
...(typeof meta.eligibilitySource === "string"
|
|
314
|
+
? { eligibilitySource: meta.eligibilitySource }
|
|
315
|
+
: {}),
|
|
316
|
+
...(warnings.length > 0 ? { decodeWarnings: warnings } : {}),
|
|
317
|
+
};
|
|
318
|
+
}
|
|
45
319
|
/**
|
|
46
320
|
* Convert a public `Proposal` to column values ready for an INSERT/UPDATE.
|
|
47
321
|
* The `stash_dir` comes from the call site (proposals.ts has it in scope).
|
|
@@ -49,6 +323,19 @@ export function proposalRowToProposal(row) {
|
|
|
49
323
|
export function proposalToRowValues(proposal, stashDir) {
|
|
50
324
|
// Fields that have no dedicated column live in metadata_json.
|
|
51
325
|
const metaObj = {};
|
|
326
|
+
if (!Array.isArray(proposal.changes) || proposal.changes.length === 0) {
|
|
327
|
+
throw new Error(`Proposal ${proposal.id} has no file changes.`);
|
|
328
|
+
}
|
|
329
|
+
if (proposal.changes.some((change) => typeof change.path !== "string" ||
|
|
330
|
+
change.path.length === 0 ||
|
|
331
|
+
!["create", "update", "delete"].includes(change.op) ||
|
|
332
|
+
(change.op === "delete" ? change.after !== undefined : typeof change.after !== "string"))) {
|
|
333
|
+
throw new Error(`Proposal ${proposal.id} has invalid file changes.`);
|
|
334
|
+
}
|
|
335
|
+
metaObj.changes = changesToStored(proposal.changes);
|
|
336
|
+
metaObj.proposedTarget = currentProposalTarget(proposal.proposedTarget);
|
|
337
|
+
if (proposal.beforeHash !== undefined)
|
|
338
|
+
metaObj.beforeHash = proposal.beforeHash;
|
|
52
339
|
if (proposal.sourceRun !== undefined)
|
|
53
340
|
metaObj.sourceRun = proposal.sourceRun;
|
|
54
341
|
if (proposal.review !== undefined)
|
|
@@ -59,12 +346,15 @@ export function proposalToRowValues(proposal, stashDir) {
|
|
|
59
346
|
metaObj.gateDecision = proposal.gateDecision;
|
|
60
347
|
if (proposal.backupContent !== undefined)
|
|
61
348
|
metaObj.backupContent = proposal.backupContent;
|
|
349
|
+
if (proposal.acceptedTarget !== undefined)
|
|
350
|
+
metaObj.acceptedTarget = proposal.acceptedTarget;
|
|
62
351
|
if (proposal.eligibilitySource !== undefined)
|
|
63
352
|
metaObj.eligibilitySource = proposal.eligibilitySource;
|
|
353
|
+
validatePresentMetadata(metaObj);
|
|
64
354
|
return {
|
|
65
355
|
id: proposal.id,
|
|
66
356
|
stash_dir: stashDir,
|
|
67
|
-
ref: proposal.ref,
|
|
357
|
+
ref: currentProposalRef(proposal.ref, true),
|
|
68
358
|
status: proposal.status,
|
|
69
359
|
source: proposal.source,
|
|
70
360
|
created_at: proposal.createdAt,
|
|
@@ -123,38 +413,12 @@ export function listStateProposals(db, options = {}) {
|
|
|
123
413
|
content, frontmatter_json, metadata_json
|
|
124
414
|
FROM proposals ${where} ORDER BY created_at ASC, rowid ASC`)
|
|
125
415
|
.all(...params);
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
* the proposal's current lifecycle status — a proposal that was auto-accepted
|
|
133
|
-
* is now `accepted`, an auto-rejected one stays `pending`, so filtering by
|
|
134
|
-
* status would drop half the join. Rows without a `gateDecision` (created
|
|
135
|
-
* before #577, or never gated) are skipped. The result is ordered by
|
|
136
|
-
* `decidedAt ASC` for deterministic downstream aggregation, falling back to
|
|
137
|
-
* `created_at` ordering from the SQL layer for rows with equal/missing
|
|
138
|
-
* timestamps.
|
|
139
|
-
*/
|
|
140
|
-
export function listProposalGateDecisions(db) {
|
|
141
|
-
const rows = db.prepare("SELECT metadata_json FROM proposals ORDER BY created_at ASC, rowid ASC").all();
|
|
142
|
-
const decisions = [];
|
|
143
|
-
for (const row of rows) {
|
|
144
|
-
let meta;
|
|
145
|
-
try {
|
|
146
|
-
meta = JSON.parse(row.metadata_json);
|
|
147
|
-
}
|
|
148
|
-
catch {
|
|
149
|
-
continue;
|
|
150
|
-
}
|
|
151
|
-
const decision = meta.gateDecision;
|
|
152
|
-
if (decision && typeof decision === "object" && typeof decision.outcome === "string") {
|
|
153
|
-
decisions.push(decision);
|
|
154
|
-
}
|
|
155
|
-
}
|
|
156
|
-
decisions.sort((a, b) => new Date(a.decidedAt).getTime() - new Date(b.decidedAt).getTime());
|
|
157
|
-
return decisions;
|
|
416
|
+
// Archived rows (accepted/rejected/reverted) decode leniently so a
|
|
417
|
+
// terminal-status row that was rejected via the lenient path (or predates
|
|
418
|
+
// a required field) remains listable — a strict throw here would defeat
|
|
419
|
+
// the point of tolerating it at reject/archive time. Pending rows keep the
|
|
420
|
+
// strict decoder; nothing about the live queue changes here.
|
|
421
|
+
return rows.map((row) => (row.status === "pending" ? proposalRowToProposal(row) : proposalRowToProposalLenient(row)));
|
|
158
422
|
}
|
|
159
423
|
/**
|
|
160
424
|
* Look up a single proposal by id, optionally scoped to one stash root.
|
|
@@ -167,6 +431,18 @@ export function getStateProposal(db, id, stashDir) {
|
|
|
167
431
|
const row = (stashDir ? db.prepare(sql).get(id, stashDir) : db.prepare(sql).get(id));
|
|
168
432
|
return row ? proposalRowToProposal(row) : undefined;
|
|
169
433
|
}
|
|
434
|
+
/**
|
|
435
|
+
* Lenient counterpart to {@link getStateProposal} — used ONLY by the
|
|
436
|
+
* terminal-status (reject/archive) read paths in repository.ts that must
|
|
437
|
+
* tolerate a malformed row (see {@link proposalRowToProposalLenient}).
|
|
438
|
+
*/
|
|
439
|
+
export function getStateProposalLenient(db, id, stashDir) {
|
|
440
|
+
const sql = `SELECT id, stash_dir, ref, status, source, created_at, updated_at,
|
|
441
|
+
content, frontmatter_json, metadata_json
|
|
442
|
+
FROM proposals WHERE id = ?${stashDir ? " AND stash_dir = ?" : ""}`;
|
|
443
|
+
const row = (stashDir ? db.prepare(sql).get(id, stashDir) : db.prepare(sql).get(id));
|
|
444
|
+
return row ? proposalRowToProposalLenient(row) : undefined;
|
|
445
|
+
}
|
|
170
446
|
/**
|
|
171
447
|
* Find PENDING proposal ids in one stash whose id starts with `idPrefix`.
|
|
172
448
|
* Backs the UUID-prefix form of `akm proposal show/accept/... <prefix>` —
|
|
@@ -184,37 +460,3 @@ export function listStateProposalIdsByPrefix(db, stashDir, idPrefix) {
|
|
|
184
460
|
.all(stashDir, `${escaped}%`);
|
|
185
461
|
return rows.map((r) => r.id);
|
|
186
462
|
}
|
|
187
|
-
/**
|
|
188
|
-
* Whether the legacy filesystem proposal import has already run for `stashDir`.
|
|
189
|
-
* See migration 005 (`proposal_fs_imports`).
|
|
190
|
-
*/
|
|
191
|
-
export function hasImportedFsProposals(db, stashDir) {
|
|
192
|
-
// Drivers disagree on the no-row sentinel (bun:sqlite → null,
|
|
193
|
-
// better-sqlite3 → undefined) — Boolean() covers both.
|
|
194
|
-
return Boolean(db.prepare("SELECT 1 FROM proposal_fs_imports WHERE stash_dir = ?").get(stashDir));
|
|
195
|
-
}
|
|
196
|
-
/**
|
|
197
|
-
* Record that the legacy filesystem proposal import completed for `stashDir`
|
|
198
|
-
* so subsequent invocations skip the directory walk. INSERT OR REPLACE keeps
|
|
199
|
-
* the call idempotent.
|
|
200
|
-
*/
|
|
201
|
-
export function recordFsProposalsImport(db, stashDir, importedCount) {
|
|
202
|
-
db.prepare("INSERT OR REPLACE INTO proposal_fs_imports (stash_dir, imported_at, imported_count) VALUES (?, ?, ?)").run(stashDir, new Date().toISOString(), importedCount);
|
|
203
|
-
}
|
|
204
|
-
/**
|
|
205
|
-
* Insert a proposal row ONLY when the id is not already present (used by the
|
|
206
|
-
* legacy filesystem import so re-runs never clobber rows that have since been
|
|
207
|
-
* mutated through the canonical store). Returns true when a row was inserted.
|
|
208
|
-
*/
|
|
209
|
-
export function insertProposalIfAbsent(db, proposal, stashDir) {
|
|
210
|
-
const v = proposalToRowValues(proposal, stashDir);
|
|
211
|
-
const result = db
|
|
212
|
-
.prepare(`
|
|
213
|
-
INSERT OR IGNORE INTO proposals
|
|
214
|
-
(id, stash_dir, ref, status, source, created_at, updated_at, content, frontmatter_json, metadata_json)
|
|
215
|
-
VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?)
|
|
216
|
-
`)
|
|
217
|
-
.run(v.id, v.stash_dir, v.ref, v.status, v.source, v.created_at, v.updated_at, v.content, v.frontmatter_json, v.metadata_json);
|
|
218
|
-
const changes = result.changes ?? 0;
|
|
219
|
-
return Number(changes) > 0;
|
|
220
|
-
}
|
|
@@ -2,7 +2,7 @@
|
|
|
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 { rethrowIfTestIsolationError } from "../../core/errors.js";
|
|
5
|
-
import { closeDatabase, openIndexDatabase } from "
|
|
5
|
+
import { closeDatabase, openIndexDatabase } from "./index-connection.js";
|
|
6
6
|
import { getRegistryIndexCache, upsertRegistryIndexCache } from "./registry-index-cache-repository.js";
|
|
7
7
|
/**
|
|
8
8
|
* RAII-style lifecycle helper for the registry cache DB. Opens the DB (treating
|