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
|
@@ -0,0 +1,92 @@
|
|
|
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
|
+
* §11.5 bundle-rename startup guard.
|
|
6
|
+
*
|
|
7
|
+
* Renaming a workspace bundle id is a mass identity migration (every ref in the
|
|
8
|
+
* bundle changes without any file moving) and MUST go through the future
|
|
9
|
+
* explicit `akm bundle rename <old> <new>` command, which rekeys the index +
|
|
10
|
+
* every ref-keyed state table atomically. If a user instead hand-edits the
|
|
11
|
+
* `bundles` KEY in config.json, the durable index/state rows still carry the OLD
|
|
12
|
+
* bundle prefix while the config names the NEW id. Silently re-minting fresh
|
|
13
|
+
* state under the new id would strand the old rows; §11.5 requires we detect this
|
|
14
|
+
* and refuse-or-warn.
|
|
15
|
+
*
|
|
16
|
+
* This guard implements the cheap heuristic form (WARN, never silently re-mint):
|
|
17
|
+
* it compares the configured bundle ids against the DISTINCT `bundle_id`
|
|
18
|
+
* (item_ref bundle prefix) values already persisted in the index — and, by
|
|
19
|
+
* cutover construction, the same prefixes key the state.db usage/salience rows.
|
|
20
|
+
* The hand-rename signature is: a configured bundle id with NO indexed rows
|
|
21
|
+
* co-existing with indexed rows under a bundle id that is no longer configured.
|
|
22
|
+
*
|
|
23
|
+
* SEAM CHOICE: invoked from `ensureIndex` — the single funnel every read/index
|
|
24
|
+
* path passes through before consuming or (re)building the index, so the guard
|
|
25
|
+
* fires BEFORE a stale-index rebuild could re-mint fresh rows under the new id.
|
|
26
|
+
* It has a handful of call sites (vs. `loadConfig`'s hundreds), reads a cached
|
|
27
|
+
* config plus one indexed `DISTINCT` query, and settles after the first
|
|
28
|
+
* comparison over a non-empty index so the steady-state cost is a boolean check.
|
|
29
|
+
*/
|
|
30
|
+
import fs from "node:fs";
|
|
31
|
+
import { loadConfig } from "../core/config/config.js";
|
|
32
|
+
import { getDbPath } from "../core/paths.js";
|
|
33
|
+
import { warn } from "../core/warn.js";
|
|
34
|
+
import { openDatabase } from "../storage/database.js";
|
|
35
|
+
let guardSettled = false;
|
|
36
|
+
/** TEST-ONLY: re-arm the once-per-process guard between cases. */
|
|
37
|
+
export function resetBundleIdentityGuardForTests() {
|
|
38
|
+
guardSettled = false;
|
|
39
|
+
}
|
|
40
|
+
/** Distinct non-empty `bundle_id` prefixes persisted in the index, or `undefined` when unreadable. */
|
|
41
|
+
function indexBundlePrefixes(dbPath) {
|
|
42
|
+
if (!fs.existsSync(dbPath))
|
|
43
|
+
return undefined;
|
|
44
|
+
let db;
|
|
45
|
+
try {
|
|
46
|
+
db = openDatabase(dbPath, { readonly: true });
|
|
47
|
+
if (!db.prepare("SELECT 1 FROM sqlite_master WHERE type='table' AND name='entries'").get())
|
|
48
|
+
return undefined;
|
|
49
|
+
return db
|
|
50
|
+
.prepare("SELECT DISTINCT bundle_id AS b FROM entries WHERE bundle_id IS NOT NULL AND bundle_id != ''")
|
|
51
|
+
.all().map((row) => row.b);
|
|
52
|
+
}
|
|
53
|
+
catch {
|
|
54
|
+
return undefined;
|
|
55
|
+
}
|
|
56
|
+
finally {
|
|
57
|
+
db?.close();
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
/**
|
|
61
|
+
* Warn (once per process) when the config's bundle ids and the index's bundle
|
|
62
|
+
* prefixes show the hand-rename signature (§11.5). No-op for an old-shape config
|
|
63
|
+
* (no `bundles`), an absent/empty index, or when the guard already settled.
|
|
64
|
+
*/
|
|
65
|
+
export function warnOnBundleRenameDrift(config = loadConfig()) {
|
|
66
|
+
if (guardSettled)
|
|
67
|
+
return;
|
|
68
|
+
const bundles = config.bundles;
|
|
69
|
+
if (!bundles)
|
|
70
|
+
return; // old-shape config — no bundle identity to guard (do not settle)
|
|
71
|
+
const configIds = new Set(Object.keys(bundles));
|
|
72
|
+
if (configIds.size === 0)
|
|
73
|
+
return;
|
|
74
|
+
const indexIds = indexBundlePrefixes(getDbPath());
|
|
75
|
+
if (indexIds === undefined || indexIds.length === 0)
|
|
76
|
+
return; // nothing indexed yet — re-check later
|
|
77
|
+
// A real comparison happened over a populated index: settle so the steady
|
|
78
|
+
// state is one boolean check.
|
|
79
|
+
guardSettled = true;
|
|
80
|
+
const indexIdSet = new Set(indexIds);
|
|
81
|
+
const configuredMissingFromIndex = [...configIds].filter((id) => !indexIdSet.has(id));
|
|
82
|
+
const indexedNotConfigured = indexIds.filter((id) => !configIds.has(id));
|
|
83
|
+
if (configuredMissingFromIndex.length === 0 || indexedNotConfigured.length === 0)
|
|
84
|
+
return;
|
|
85
|
+
warn("WARNING: bundle identity drift detected. " +
|
|
86
|
+
`Configured bundle(s) with no indexed content: ${configuredMissingFromIndex.map((id) => `"${id}"`).join(", ")}; ` +
|
|
87
|
+
`indexed content under unconfigured bundle id(s): ${indexedNotConfigured.map((id) => `"${id}"`).join(", ")}. ` +
|
|
88
|
+
"This is the signature of a hand-renamed bundle id (spec §11.5). AKM will NOT silently re-mint fresh state " +
|
|
89
|
+
"under the new id. There is no rekey command in 0.9.0: either restore the previous bundle id in config.json " +
|
|
90
|
+
"to reattach the existing rows, or keep the new id and run `akm index --full` to re-mint under it, accepting " +
|
|
91
|
+
"that learned state (utility, salience, outcomes, usage history) keyed to the old id is left behind.");
|
|
92
|
+
}
|
|
@@ -4,7 +4,7 @@
|
|
|
4
4
|
import fs from "node:fs";
|
|
5
5
|
import { rethrowIfTestIsolationError } from "../../core/errors.js";
|
|
6
6
|
import { getDbPath } from "../../core/paths.js";
|
|
7
|
-
import { closeDatabase, openExistingDatabase } from "
|
|
7
|
+
import { closeDatabase, openExistingDatabase } from "../../storage/repositories/index-connection.js";
|
|
8
8
|
function withReadableGraphDb(db, fn) {
|
|
9
9
|
if (db)
|
|
10
10
|
return fn(db);
|
|
@@ -215,13 +215,6 @@ export function drainExtractionQueue(db, stashRoot, limit) {
|
|
|
215
215
|
return [];
|
|
216
216
|
}
|
|
217
217
|
}
|
|
218
|
-
/**
|
|
219
|
-
* Scoped loader — only the graph_meta row for a stash. Used by callers that
|
|
220
|
-
* only need summary numbers (e.g. `akm graph summary`).
|
|
221
|
-
*/
|
|
222
|
-
export function loadGraphMetaOnly(stashPath, db) {
|
|
223
|
-
return loadStoredGraphMeta(stashPath, db);
|
|
224
|
-
}
|
|
225
218
|
/**
|
|
226
219
|
* Scoped loader — graph_files rows without entities/relations. Used for
|
|
227
220
|
* orphan detection and entity overview commands.
|
|
@@ -256,23 +249,6 @@ export function loadGraphFilesOnly(stashPath, db) {
|
|
|
256
249
|
return [];
|
|
257
250
|
}
|
|
258
251
|
}
|
|
259
|
-
/**
|
|
260
|
-
* Scoped loader — entities for a single file, keyed on the #624-P1 composite
|
|
261
|
-
* (stash_root, file_path, body_hash). Used by per-asset show/curate lookups.
|
|
262
|
-
*/
|
|
263
|
-
export function loadGraphEntitiesByPath(db, stashRoot, filePath, bodyHash) {
|
|
264
|
-
try {
|
|
265
|
-
const rows = db
|
|
266
|
-
.prepare(`SELECT entity FROM graph_file_entities
|
|
267
|
-
WHERE stash_root = ? AND file_path = ? AND body_hash = ?
|
|
268
|
-
ORDER BY entity_order`)
|
|
269
|
-
.all(stashRoot, filePath, bodyHash);
|
|
270
|
-
return rows.map((r) => r.entity);
|
|
271
|
-
}
|
|
272
|
-
catch {
|
|
273
|
-
return [];
|
|
274
|
-
}
|
|
275
|
-
}
|
|
276
252
|
export function loadStoredGraphMeta(stashPath, db) {
|
|
277
253
|
try {
|
|
278
254
|
return withReadableGraphDb(db, (readDb) => {
|
|
@@ -9,7 +9,7 @@
|
|
|
9
9
|
* duplicating the hash-compute → lookup → write pattern inline.
|
|
10
10
|
*/
|
|
11
11
|
import { bestEffort } from "../../core/best-effort.js";
|
|
12
|
-
import { computeBodyHash, getLlmCacheEntry, upsertLlmCacheEntry } from "
|
|
12
|
+
import { computeBodyHash, getLlmCacheEntry, upsertLlmCacheEntry, } from "../../storage/repositories/index-llm-cache-repository.js";
|
|
13
13
|
/**
|
|
14
14
|
* Generic LLM cache wrapper. Returns cached result if body unchanged,
|
|
15
15
|
* otherwise calls llmFn(), caches the result, and returns it.
|
|
@@ -14,17 +14,20 @@
|
|
|
14
14
|
* populated index exists. The previous design — a staleness walk plus a
|
|
15
15
|
* detached background reindex per read — made every read on an actively
|
|
16
16
|
* written stash spawn a writer that the read's own telemetry then queued
|
|
17
|
-
* behind (
|
|
17
|
+
* behind (the 2026-07 read-path reindex-contention findings).
|
|
18
18
|
*
|
|
19
19
|
* `mode: "blocking"` (improve) still checks staleness and rebuilds inline,
|
|
20
20
|
* because its planning logic needs a current `entries` table in-process.
|
|
21
21
|
*/
|
|
22
22
|
import fs from "node:fs";
|
|
23
23
|
import path from "node:path";
|
|
24
|
-
import {
|
|
24
|
+
import { placementSpecList } from "../core/asset/asset-placement.js";
|
|
25
25
|
import { getDbPath } from "../core/paths.js";
|
|
26
26
|
import { warn } from "../core/warn.js";
|
|
27
|
-
import { closeDatabase,
|
|
27
|
+
import { closeDatabase, openExistingDatabase } from "../storage/repositories/index-connection.js";
|
|
28
|
+
import { getEntryCount, getIndexedFilePaths } from "../storage/repositories/index-entries-repository.js";
|
|
29
|
+
import { getMeta } from "../storage/repositories/index-meta-repository.js";
|
|
30
|
+
import { warnOnBundleRenameDrift } from "./bundle-identity-guard.js";
|
|
28
31
|
function getIndexableFiles(root, spec) {
|
|
29
32
|
if (!fs.existsSync(root))
|
|
30
33
|
return [];
|
|
@@ -80,8 +83,8 @@ function getIndexableFiles(root, spec) {
|
|
|
80
83
|
function hasNewerIndexableFiles(stashDir, builtAt, indexedPaths) {
|
|
81
84
|
const builtAtMs = builtAt ? new Date(builtAt).getTime() : Number.NaN;
|
|
82
85
|
const builtAtUsable = Number.isFinite(builtAtMs);
|
|
83
|
-
for (const
|
|
84
|
-
const typeRoot = path.join(stashDir,
|
|
86
|
+
for (const spec of placementSpecList()) {
|
|
87
|
+
const typeRoot = path.join(stashDir, spec.stashDir);
|
|
85
88
|
const files = getIndexableFiles(typeRoot, spec);
|
|
86
89
|
for (const file of files) {
|
|
87
90
|
if (!indexedPaths.has(file))
|
|
@@ -177,13 +180,20 @@ function indexCanServeStash(stashDir) {
|
|
|
177
180
|
closeDatabase(db);
|
|
178
181
|
}
|
|
179
182
|
}
|
|
180
|
-
async function runInlineReindex(stashDir) {
|
|
183
|
+
async function runInlineReindex(stashDir, options = {}) {
|
|
181
184
|
try {
|
|
182
185
|
const { akmIndex } = await import("./indexer.js");
|
|
183
|
-
await akmIndex({
|
|
186
|
+
await akmIndex({
|
|
187
|
+
stashDir,
|
|
188
|
+
implicit: true,
|
|
189
|
+
...(options.signal ? { signal: options.signal } : {}),
|
|
190
|
+
...(options.hydrateSources === false ? { hydrateSources: false } : {}),
|
|
191
|
+
});
|
|
184
192
|
return true;
|
|
185
193
|
}
|
|
186
194
|
catch (error) {
|
|
195
|
+
if (options.signal?.aborted)
|
|
196
|
+
throw error;
|
|
187
197
|
warn("Auto-index failed, proceeding with existing index:", error instanceof Error ? error.message : String(error));
|
|
188
198
|
return false;
|
|
189
199
|
}
|
|
@@ -204,12 +214,23 @@ async function runInlineReindex(stashDir) {
|
|
|
204
214
|
* A rebuild attempt that fails (throws) resolves to `false`.
|
|
205
215
|
*/
|
|
206
216
|
export async function ensureIndex(stashDir, options = {}) {
|
|
217
|
+
// §11.5: warn (once) if the configured bundle ids drifted from the persisted
|
|
218
|
+
// index prefixes (hand-renamed bundle key) BEFORE any rebuild could re-mint.
|
|
219
|
+
warnOnBundleRenameDrift();
|
|
207
220
|
if (options.mode === "blocking") {
|
|
221
|
+
// Blocking callers (improve's planning preflight) are a sanctioned
|
|
222
|
+
// materialization point — hydrate cache-backed sources as usual.
|
|
208
223
|
if (!isIndexStale(stashDir))
|
|
209
224
|
return false;
|
|
210
|
-
return runInlineReindex(stashDir);
|
|
225
|
+
return runInlineReindex(stashDir, { ...(options.signal ? { signal: options.signal } : {}) });
|
|
211
226
|
}
|
|
227
|
+
// Background = the READ path (`show` auto-index): query time must never clone/
|
|
228
|
+
// pull/fetch (spec §14.3 / D11). Build from already-materialized content only;
|
|
229
|
+
// absent source caches are skipped with a warning, not fetched.
|
|
212
230
|
if (indexCanServeStash(stashDir))
|
|
213
231
|
return false;
|
|
214
|
-
return runInlineReindex(stashDir
|
|
232
|
+
return runInlineReindex(stashDir, {
|
|
233
|
+
...(options.signal ? { signal: options.signal } : {}),
|
|
234
|
+
hydrateSources: false,
|
|
235
|
+
});
|
|
215
236
|
}
|
|
@@ -249,10 +249,9 @@ export function collectGraphRelatedHit(context, filePath) {
|
|
|
249
249
|
* NOT entries.id — so candidates are identified by file_path (the unique index
|
|
250
250
|
* idx_graph_files_path guarantees one graph_files row per path).
|
|
251
251
|
*
|
|
252
|
-
* The returned `ref` field carries the canonical
|
|
253
|
-
*
|
|
254
|
-
*
|
|
255
|
-
* matching entries row).
|
|
252
|
+
* The returned `ref` field carries the canonical indexed `concept_id`, never a
|
|
253
|
+
* value re-derived from presentation fields or `entry_key`. It is undefined
|
|
254
|
+
* when the graph row has no matching entry with current indexed provenance.
|
|
256
255
|
*/
|
|
257
256
|
export function listRelatedPathsForFile(stashRoot, filePath, limit = 5, db) {
|
|
258
257
|
if (!db) {
|
|
@@ -343,20 +342,17 @@ export function listRelatedPathsForFile(stashRoot, filePath, limit = 5, db) {
|
|
|
343
342
|
relationCountByPath.set(row.file_path, (relationCountByPath.get(row.file_path) ?? 0) + 1);
|
|
344
343
|
}
|
|
345
344
|
}
|
|
346
|
-
//
|
|
347
|
-
//
|
|
348
|
-
// user-facing `type:name`. Resolve by (stash_dir, file_path) now that the
|
|
349
|
-
// graph rows are no longer keyed on entries.id.
|
|
345
|
+
// This related list is scoped to one source root, so the user-facing ref is
|
|
346
|
+
// the indexed bundle-less conceptId.
|
|
350
347
|
const refByPath = new Map();
|
|
351
348
|
try {
|
|
352
349
|
const entryRows = db
|
|
353
|
-
.prepare(`SELECT
|
|
354
|
-
WHERE file_path IN (${placeholders}) AND stash_dir =
|
|
350
|
+
.prepare(`SELECT file_path, concept_id FROM entries
|
|
351
|
+
WHERE file_path IN (${placeholders}) AND stash_dir = ?
|
|
352
|
+
AND item_ref IS NOT NULL AND concept_id IS NOT NULL`)
|
|
355
353
|
.all(...candidatePaths, stashRoot);
|
|
356
354
|
for (const row of entryRows) {
|
|
357
|
-
|
|
358
|
-
if (ref)
|
|
359
|
-
refByPath.set(row.file_path, ref);
|
|
355
|
+
refByPath.set(row.file_path, row.concept_id);
|
|
360
356
|
}
|
|
361
357
|
}
|
|
362
358
|
catch {
|
|
@@ -375,23 +371,6 @@ export function listRelatedPathsForFile(stashRoot, filePath, limit = 5, db) {
|
|
|
375
371
|
};
|
|
376
372
|
});
|
|
377
373
|
}
|
|
378
|
-
/**
|
|
379
|
-
* Convert an entries.entry_key to a user-facing asset ref. Entry keys are
|
|
380
|
-
* stored as `${stash_dir}:${type}:${name}`; strip the stash-dir prefix.
|
|
381
|
-
*/
|
|
382
|
-
function stripStashPrefix(entryKey, stashDir) {
|
|
383
|
-
const prefix = `${stashDir}:`;
|
|
384
|
-
if (entryKey.startsWith(prefix))
|
|
385
|
-
return entryKey.slice(prefix.length);
|
|
386
|
-
// Fall back to last two colon-separated segments.
|
|
387
|
-
const lastColon = entryKey.lastIndexOf(":");
|
|
388
|
-
if (lastColon < 0)
|
|
389
|
-
return entryKey;
|
|
390
|
-
const prevColon = entryKey.lastIndexOf(":", lastColon - 1);
|
|
391
|
-
if (prevColon < 0)
|
|
392
|
-
return entryKey;
|
|
393
|
-
return entryKey.slice(prevColon + 1);
|
|
394
|
-
}
|
|
395
374
|
/**
|
|
396
375
|
* Load and normalize graph data from SQLite once, then reuse it across all
|
|
397
376
|
* per-entry boost lookups in the current query.
|
|
@@ -8,7 +8,7 @@
|
|
|
8
8
|
* configured LLM to extract entities and relations from each one, and
|
|
9
9
|
* persists the result to stash-local SQLite graph tables keyed by stash root.
|
|
10
10
|
* The artifact is consumed by the search
|
|
11
|
-
* pipeline (see `src/indexer/graph-boost.ts`) as a single boost component
|
|
11
|
+
* pipeline (see `src/indexer/graph/graph-boost.ts`) as a single boost component
|
|
12
12
|
* inside the existing FTS5+boosts loop — there is NO second SearchHit
|
|
13
13
|
* scorer and no parallel ranking track.
|
|
14
14
|
*
|
|
@@ -16,7 +16,7 @@
|
|
|
16
16
|
* 1. An LLM profile must be configured (no provider = no extraction). When
|
|
17
17
|
* absent, `resolveIndexPassLLM("graph", config)` returns `undefined`
|
|
18
18
|
* and the pass short-circuits.
|
|
19
|
-
* 2. `
|
|
19
|
+
* 2. The selected strategy's `processes.graphExtraction.enabled !== false`
|
|
20
20
|
* — the feature-gate layer (historically v1 spec §14, since superseded by
|
|
21
21
|
* the 0.8.0 profile shape). Set to `false` to block the pass at the
|
|
22
22
|
* feature-gate layer (no network call may ever issue).
|
|
@@ -31,13 +31,16 @@
|
|
|
31
31
|
* - LLM access is exclusively via `resolveIndexPassLLM("graph", config)`.
|
|
32
32
|
* - The graph rows are an indexer artifact, NOT a user-visible
|
|
33
33
|
* asset. It does not have an asset ref, does not appear in search
|
|
34
|
-
* hits, and is not addressable via `akm show`.
|
|
35
|
-
*
|
|
34
|
+
* hits, and is not addressable via `akm show`. The persisted artifact
|
|
35
|
+
* lives in indexer-owned SQLite tables (`replaceStoredGraph` /
|
|
36
|
+
* `loadStoredGraphSnapshot` in `../db/graph-db.ts`), NOT as a file on
|
|
37
|
+
* disk (R-065 #3 — this comment previously described a retired
|
|
38
|
+
* `fs.writeFile`-based storage layout) — `writeAssetToSource` is
|
|
36
39
|
* reserved for asset writes (CLAUDE.md / spec §10 step 5).
|
|
37
40
|
*/
|
|
38
41
|
import fs from "node:fs";
|
|
39
42
|
import path from "node:path";
|
|
40
|
-
import {
|
|
43
|
+
import { stashDirFor } from "../../core/asset/asset-placement.js";
|
|
41
44
|
import { parseFrontmatter } from "../../core/asset/frontmatter.js";
|
|
42
45
|
import { concurrentMap } from "../../core/concurrent.js";
|
|
43
46
|
import { getIndexPassConfig, loadConfig, resolveBatchSize } from "../../core/config/config.js";
|
|
@@ -46,9 +49,9 @@ import { warn, warnVerbose } from "../../core/warn.js";
|
|
|
46
49
|
import { isProcessEnabled } from "../../llm/feature-gate.js";
|
|
47
50
|
import * as graphExtract from "../../llm/graph-extract.js";
|
|
48
51
|
import { resolveIndexPassLLM } from "../../llm/index-passes.js";
|
|
49
|
-
import { computeBodyHash, getLlmCacheEntriesByRefs, getLlmCacheEntry, upsertLlmCacheEntry, } from "
|
|
52
|
+
import { computeBodyHash, getLlmCacheEntriesByRefs, getLlmCacheEntry, upsertLlmCacheEntry, } from "../../storage/repositories/index-llm-cache-repository.js";
|
|
53
|
+
import { GRAPH_SCHEMA_VERSION } from "../../storage/repositories/index-schema.js";
|
|
50
54
|
import { drainExtractionQueue, loadStoredGraphSnapshot, replaceStoredGraph } from "../db/graph-db.js";
|
|
51
|
-
import { GRAPH_SCHEMA_VERSION } from "../db/schema.js";
|
|
52
55
|
import { walkMarkdownFiles } from "../walk/walker.js";
|
|
53
56
|
import { deduplicateGraph } from "./graph-dedup.js";
|
|
54
57
|
/** Schema version for the persisted artifact — bumps trigger a full rebuild. */
|
|
@@ -109,7 +112,6 @@ const SUPPORTED_GRAPH_EXTRACTION_INCLUDE_TYPES = new Set([
|
|
|
109
112
|
"workflow",
|
|
110
113
|
"lesson",
|
|
111
114
|
"task",
|
|
112
|
-
"wiki",
|
|
113
115
|
]);
|
|
114
116
|
const GRAPH_CACHE_VARIANT_PREFIX = "graph-extraction";
|
|
115
117
|
function normalizeConfidence(raw) {
|
|
@@ -260,7 +262,7 @@ function reuseGraphNode(previousNodes, candidate, bodyHash) {
|
|
|
260
262
|
* 1. **Provider configured** — an LLM profile must be selectable. Without a
|
|
261
263
|
* configured provider, `resolveIndexPassLLM("graph", config)` returns
|
|
262
264
|
* `undefined` (the pass cannot run because there is no model to call).
|
|
263
|
-
* 2. **Feature gate** — `
|
|
265
|
+
* 2. **Feature gate** — the selected strategy's `processes.graphExtraction.enabled`
|
|
264
266
|
* (defaults to `true`). When `false`, no network call may issue regardless
|
|
265
267
|
* of per-pass settings.
|
|
266
268
|
* 3. **Per-pass gate** — `index.graph.llm` (defaults to `true`). When
|
|
@@ -276,21 +278,25 @@ function reuseGraphNode(previousNodes, candidate, bodyHash) {
|
|
|
276
278
|
*/
|
|
277
279
|
export async function runGraphExtractionPass(ctx) {
|
|
278
280
|
const { config, sources, signal, db, reEnrich, onProgress, options = {} } = ctx;
|
|
281
|
+
const invocationOwnsConnection = Object.hasOwn(ctx, "llmConfig");
|
|
279
282
|
// Gate 1 — feature gate via isProcessEnabled, which reads the 0.8.0 path
|
|
280
|
-
// (
|
|
283
|
+
// (selected strategy's processes.graphExtraction.enabled). Defaults to
|
|
281
284
|
// enabled when the key is absent.
|
|
282
|
-
if (!isProcessEnabled("index", "graph_extraction", config))
|
|
285
|
+
if (!invocationOwnsConnection && !isProcessEnabled("index", "graph_extraction", config))
|
|
283
286
|
return { ...EMPTY_RESULT };
|
|
284
287
|
// Gate 2 — per-pass opt-out (#208). Returns the resolved llm config or
|
|
285
288
|
// `undefined` when the pass should not run.
|
|
286
|
-
const llmConfig = resolveIndexPassLLM("graph", config);
|
|
289
|
+
const llmConfig = Object.hasOwn(ctx, "llmConfig") ? ctx.llmConfig : resolveIndexPassLLM("graph", config);
|
|
287
290
|
if (!llmConfig) {
|
|
288
|
-
const reason = getIndexPassConfig(config.index, "graph")?.
|
|
289
|
-
? "index.graph.
|
|
290
|
-
: "no
|
|
291
|
+
const reason = getIndexPassConfig(config.index, "graph")?.enabled === false
|
|
292
|
+
? "index.graph.enabled is false"
|
|
293
|
+
: "no LLM engine is configured";
|
|
291
294
|
warnVerbose(`graph extraction: skipped because ${reason}.`);
|
|
292
295
|
return { ...EMPTY_RESULT };
|
|
293
296
|
}
|
|
297
|
+
const featureConfig = invocationOwnsConnection
|
|
298
|
+
? { ...config, index: { ...config.index, graph: { ...config.index?.graph, enabled: true } } }
|
|
299
|
+
: config;
|
|
294
300
|
// The pass only writes to the primary (working) stash. Read-only caches
|
|
295
301
|
// (git, npm, website) are deliberately untouched — the graph artifact for
|
|
296
302
|
// those sources would be clobbered by the next sync().
|
|
@@ -309,10 +315,14 @@ export async function runGraphExtractionPass(ctx) {
|
|
|
309
315
|
for (const queued of drained) {
|
|
310
316
|
if (signal?.aborted)
|
|
311
317
|
break;
|
|
312
|
-
await extractGraphForSingleFile(db, primary.path, queued.filePath, queued.bodyHash, {
|
|
318
|
+
await extractGraphForSingleFile(db, primary.path, queued.filePath, queued.bodyHash, {
|
|
319
|
+
config: featureConfig,
|
|
320
|
+
signal,
|
|
321
|
+
llmConfig,
|
|
322
|
+
});
|
|
313
323
|
}
|
|
314
324
|
}
|
|
315
|
-
const includeTypes = getGraphExtractionIncludeTypes(config);
|
|
325
|
+
const includeTypes = options.includeTypes ?? getGraphExtractionIncludeTypes(config);
|
|
316
326
|
let eligible = collectEligibleFiles(primary.path, includeTypes).filter((candidate) => !options.candidatePaths || options.candidatePaths.has(candidate.absPath));
|
|
317
327
|
// P2 (#624): when topN is set and a DB is available, rank the (already
|
|
318
328
|
// candidate-filtered) eligible set by utility_scores DESC and keep only the
|
|
@@ -357,7 +367,7 @@ export async function runGraphExtractionPass(ctx) {
|
|
|
357
367
|
// Resolve the effective batch size. Falls back to
|
|
358
368
|
// DEFAULT_GRAPH_EXTRACTION_BATCH_SIZE (4) when unset, and clamps against
|
|
359
369
|
// `llm.contextLength` if the model's context window is configured.
|
|
360
|
-
const batchSize = resolveBatchSize(getIndexPassConfig(config.index, "graph")?.graphExtractionBatchSize, llmConfig.contextLength);
|
|
370
|
+
const batchSize = resolveBatchSize(options.batchSize ?? getIndexPassConfig(config.index, "graph")?.graphExtractionBatchSize, llmConfig.contextLength);
|
|
361
371
|
const extractionRunId = crypto.randomUUID();
|
|
362
372
|
const extractorId = getGraphExtractorId({ model: llmConfig.model, batchSize, includeTypes });
|
|
363
373
|
const cacheVariant = extractorId;
|
|
@@ -438,7 +448,7 @@ export async function runGraphExtractionPass(ctx) {
|
|
|
438
448
|
}
|
|
439
449
|
if (!cached) {
|
|
440
450
|
telemetry.cacheMisses += 1;
|
|
441
|
-
const extraction = await graphExtract.extractGraphFromBody(llmConfig, candidate.body, signal,
|
|
451
|
+
const extraction = await graphExtract.extractGraphFromBody(llmConfig, candidate.body, signal, featureConfig, onFallback, { batchState, telemetry: runtimeTelemetry });
|
|
442
452
|
cached = {
|
|
443
453
|
entities: extraction.entities,
|
|
444
454
|
relations: extraction.relations,
|
|
@@ -463,8 +473,8 @@ export async function runGraphExtractionPass(ctx) {
|
|
|
463
473
|
reportProgress(candidate.absPath, result);
|
|
464
474
|
return result;
|
|
465
475
|
},
|
|
466
|
-
//
|
|
467
|
-
//
|
|
476
|
+
// Caller-set connection concurrency or 1: `resolveLlmEngineUse` does
|
|
477
|
+
// not forward `engines.<name>.concurrency`, so config cannot raise this.
|
|
468
478
|
llmConfig.concurrency ?? 1);
|
|
469
479
|
}
|
|
470
480
|
else {
|
|
@@ -562,7 +572,7 @@ export async function runGraphExtractionPass(ctx) {
|
|
|
562
572
|
telemetry.cacheMisses += uncachedChunk.length;
|
|
563
573
|
// extractGraphFromBodies always returns an array of the same length
|
|
564
574
|
// as bodies (it falls back per-asset for any missing indices).
|
|
565
|
-
const batchExtractions = await graphExtract.extractGraphFromBodies(llmConfig, bodies, signal,
|
|
575
|
+
const batchExtractions = await graphExtract.extractGraphFromBodies(llmConfig, bodies, signal, featureConfig, onFallback, { batchState, telemetry: runtimeTelemetry });
|
|
566
576
|
// Map LLM results back to original positions and write cache entries.
|
|
567
577
|
let llmIdx = 0;
|
|
568
578
|
for (let j = 0; j < chunk.length; j++) {
|
|
@@ -670,7 +680,7 @@ function inferGraphTypeForPath(stashRoot, absPath) {
|
|
|
670
680
|
if (!firstSeg)
|
|
671
681
|
return undefined;
|
|
672
682
|
for (const type of SUPPORTED_GRAPH_EXTRACTION_INCLUDE_TYPES) {
|
|
673
|
-
if (
|
|
683
|
+
if (stashDirFor(type) === firstSeg)
|
|
674
684
|
return type;
|
|
675
685
|
}
|
|
676
686
|
return undefined;
|
|
@@ -718,12 +728,16 @@ export async function extractGraphForSingleFile(db, stashRoot, filePath, bodyHas
|
|
|
718
728
|
}
|
|
719
729
|
else {
|
|
720
730
|
const config = opts?.config ?? loadConfig();
|
|
721
|
-
|
|
731
|
+
const invocationOwnsConnection = Object.hasOwn(opts ?? {}, "llmConfig");
|
|
732
|
+
if (!invocationOwnsConnection && !isProcessEnabled("index", "graph_extraction", config))
|
|
722
733
|
return false;
|
|
723
|
-
const llmConfig = resolveIndexPassLLM("graph", config);
|
|
734
|
+
const llmConfig = Object.hasOwn(opts ?? {}, "llmConfig") ? opts?.llmConfig : resolveIndexPassLLM("graph", config);
|
|
724
735
|
if (!llmConfig)
|
|
725
736
|
return false; // model-available guard
|
|
726
|
-
const
|
|
737
|
+
const featureConfig = invocationOwnsConnection
|
|
738
|
+
? { ...config, index: { ...config.index, graph: { ...config.index?.graph, enabled: true } } }
|
|
739
|
+
: config;
|
|
740
|
+
const result = await graphExtract.extractGraphFromBody(llmConfig, body, opts?.signal, featureConfig);
|
|
727
741
|
extraction = {
|
|
728
742
|
entities: result.entities,
|
|
729
743
|
relations: result.relations,
|
|
@@ -848,7 +862,7 @@ export function collectEligibleFiles(stashRoot, includeTypes = [...DEFAULT_GRAPH
|
|
|
848
862
|
const type = rawType.trim().toLowerCase();
|
|
849
863
|
if (!SUPPORTED_GRAPH_EXTRACTION_INCLUDE_TYPES.has(type))
|
|
850
864
|
continue;
|
|
851
|
-
const stashDir =
|
|
865
|
+
const stashDir = stashDirFor(type);
|
|
852
866
|
if (!stashDir)
|
|
853
867
|
continue;
|
|
854
868
|
const dir = path.join(stashRoot, stashDir);
|