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
|
@@ -3,16 +3,152 @@
|
|
|
3
3
|
// file, You can obtain one at https://mozilla.org/MPL/2.0/.
|
|
4
4
|
/**
|
|
5
5
|
* Runtime helpers that derive {@link ConfiguredSource} values from the
|
|
6
|
-
* persisted {@link SourceConfigEntry} / {@link
|
|
6
|
+
* persisted {@link SourceConfigEntry} / {@link InstalledBundle} shapes
|
|
7
7
|
* in an {@link AkmConfig}.
|
|
8
8
|
*/
|
|
9
9
|
import { createHash } from "node:crypto";
|
|
10
|
+
import path from "node:path";
|
|
11
|
+
import { ConfigError } from "../errors.js";
|
|
12
|
+
/** The current one-component-per-bundle configuration entry, if present. */
|
|
13
|
+
export function bundleComponentConfig(bundle) {
|
|
14
|
+
if (!bundle?.components)
|
|
15
|
+
return undefined;
|
|
16
|
+
const components = Object.values(bundle.components);
|
|
17
|
+
if (components.length !== 1) {
|
|
18
|
+
throw new ConfigError("A bundle components map must contain exactly one component.", "INVALID_CONFIG_FILE");
|
|
19
|
+
}
|
|
20
|
+
return components[0];
|
|
21
|
+
}
|
|
22
|
+
/**
|
|
23
|
+
* Convert a `bundles` map (0.9.0 config-shape cutover, spec §10.1 / D-R5) into
|
|
24
|
+
* the ordered {@link SourceConfigEntry} list the transitional runtime source
|
|
25
|
+
* resolvers already consume — `defaultBundle` first (primary), then map
|
|
26
|
+
* insertion order (preserving today's installation-priority semantics, on which
|
|
27
|
+
* D-R4 short-ref resolution depends). Each entry's `name` IS its bundle key, so
|
|
28
|
+
* `deriveInstallations` re-derives the exact same installation id (D-R5 rule 1).
|
|
29
|
+
*
|
|
30
|
+
* Returns `undefined` for an old-shape config (no `bundles`), so callers fall
|
|
31
|
+
* back to the pre-cutover `stashDir`/`sources[]`/`installed[]` resolution.
|
|
32
|
+
*/
|
|
33
|
+
/**
|
|
34
|
+
* The resolved primary stash path — the `defaultBundle`'s filesystem `path`
|
|
35
|
+
* (spec §10.1) — or `undefined` when no filesystem primary is configured.
|
|
36
|
+
*/
|
|
37
|
+
export function primaryBundlePath(config) {
|
|
38
|
+
const bundles = config.bundles;
|
|
39
|
+
const key = config.defaultBundle;
|
|
40
|
+
if (!bundles || !key)
|
|
41
|
+
return undefined;
|
|
42
|
+
const entry = bundles[key];
|
|
43
|
+
if (!entry || typeof entry.path !== "string" || entry.path.length === 0)
|
|
44
|
+
return undefined;
|
|
45
|
+
const componentRoot = bundleComponentConfig(entry)?.root;
|
|
46
|
+
if (!componentRoot || componentRoot === ".")
|
|
47
|
+
return entry.path;
|
|
48
|
+
const bundleRoot = path.resolve(entry.path);
|
|
49
|
+
const resolved = path.resolve(bundleRoot, componentRoot);
|
|
50
|
+
const relative = path.relative(bundleRoot, resolved);
|
|
51
|
+
if (relative === ".." || relative.startsWith(`..${path.sep}`) || path.isAbsolute(relative)) {
|
|
52
|
+
throw new ConfigError(`Component root "${componentRoot}" escapes bundle "${key}".`, "INVALID_CONFIG_FILE");
|
|
53
|
+
}
|
|
54
|
+
return resolved;
|
|
55
|
+
}
|
|
56
|
+
export function bundlesToSourceEntries(config) {
|
|
57
|
+
const bundles = config.bundles;
|
|
58
|
+
if (!bundles)
|
|
59
|
+
return undefined;
|
|
60
|
+
const keys = Object.keys(bundles);
|
|
61
|
+
const defaultKey = config.defaultBundle && config.defaultBundle in bundles ? config.defaultBundle : undefined;
|
|
62
|
+
const ordered = defaultKey ? [defaultKey, ...keys.filter((k) => k !== defaultKey)] : keys;
|
|
63
|
+
const entries = [];
|
|
64
|
+
for (const key of ordered) {
|
|
65
|
+
const entry = bundleEntryToSourceEntry(key, bundles[key], key === defaultKey);
|
|
66
|
+
if (entry)
|
|
67
|
+
entries.push(entry);
|
|
68
|
+
}
|
|
69
|
+
return entries;
|
|
70
|
+
}
|
|
71
|
+
/** Map one `bundles.<key>` entry to a runtime {@link SourceConfigEntry}. */
|
|
72
|
+
export function bundleEntryToSourceEntry(key, bundle, isPrimary = false) {
|
|
73
|
+
const base = {
|
|
74
|
+
name: key,
|
|
75
|
+
...(bundle.writable !== undefined ? { writable: bundle.writable } : {}),
|
|
76
|
+
...(bundle.enabled !== undefined ? { enabled: bundle.enabled } : {}),
|
|
77
|
+
...(isPrimary ? { primary: true } : {}),
|
|
78
|
+
};
|
|
79
|
+
if (typeof bundle.path === "string" && bundle.path.length > 0) {
|
|
80
|
+
return { type: "filesystem", path: bundle.path, ...base };
|
|
81
|
+
}
|
|
82
|
+
if (typeof bundle.git === "string" && bundle.git.length > 0) {
|
|
83
|
+
return { type: "git", url: normalizeInstalledGitRef("", bundle.git), ...base };
|
|
84
|
+
}
|
|
85
|
+
if (bundle.website && typeof bundle.website.url === "string") {
|
|
86
|
+
// All non-`url` website-descriptor keys (maxPages/refresh/maxDepth + any
|
|
87
|
+
// passthrough provider options) round-trip back to the runtime entry's
|
|
88
|
+
// `options` bag, mirroring the pre-cutover `sources[].options` shape.
|
|
89
|
+
const { url, ...rest } = bundle.website;
|
|
90
|
+
return {
|
|
91
|
+
type: "website",
|
|
92
|
+
url,
|
|
93
|
+
...(Object.keys(rest).length > 0 ? { options: rest } : {}),
|
|
94
|
+
...base,
|
|
95
|
+
};
|
|
96
|
+
}
|
|
97
|
+
if (typeof bundle.npm === "string" && bundle.npm.length > 0) {
|
|
98
|
+
// Today's npm source carries the package spec in `path` (see parseSourceSpec).
|
|
99
|
+
return { type: "npm", path: bundle.npm, ...base };
|
|
100
|
+
}
|
|
101
|
+
return undefined;
|
|
102
|
+
}
|
|
103
|
+
/**
|
|
104
|
+
* Desired 0.9.0 bundle descriptor for a registry-installed source (spec §10.1).
|
|
105
|
+
* Maps the install source kind onto the ONE source descriptor a bundle entry
|
|
106
|
+
* carries: git/github → a provider-ready clone URL, npm → `{ npm: ref }`,
|
|
107
|
+
* everything else (local/filesystem) → `{ path: stashRoot }`.
|
|
108
|
+
*
|
|
109
|
+
* CRITICAL (spec §10.2:453): the materialized cache root NEVER appears in the
|
|
110
|
+
* descriptor for a git/npm bundle — the desired config carries only the source
|
|
111
|
+
* descriptor; the install locator stays in `registryId` and the resolved root
|
|
112
|
+
* belongs exclusively in the lock's `localRoot`. Callers layer
|
|
113
|
+
* `registryId`/`writable` onto the result.
|
|
114
|
+
*/
|
|
115
|
+
export function installedSourceDescriptor(source, ref, stashRoot) {
|
|
116
|
+
switch (source) {
|
|
117
|
+
case "git":
|
|
118
|
+
case "github":
|
|
119
|
+
if (ref)
|
|
120
|
+
return { git: normalizeInstalledGitRef(source, ref) };
|
|
121
|
+
break;
|
|
122
|
+
case "npm":
|
|
123
|
+
if (ref)
|
|
124
|
+
return { npm: ref };
|
|
125
|
+
break;
|
|
126
|
+
default:
|
|
127
|
+
break;
|
|
128
|
+
}
|
|
129
|
+
// local/filesystem installs reference a real on-disk path (no package-manager
|
|
130
|
+
// cache to re-materialize), so the resolved root IS the desired path.
|
|
131
|
+
return { path: stashRoot };
|
|
132
|
+
}
|
|
133
|
+
function normalizeInstalledGitRef(source, ref) {
|
|
134
|
+
if (ref.startsWith("git+"))
|
|
135
|
+
return ref.slice(4);
|
|
136
|
+
const isGithubShorthand = ref.startsWith("github:") || (source === "github" && /^[^/:#]+\/[^/#]+(?:#.+)?$/.test(ref));
|
|
137
|
+
if (!isGithubShorthand)
|
|
138
|
+
return ref;
|
|
139
|
+
const body = ref.startsWith("github:") ? ref.slice("github:".length) : ref;
|
|
140
|
+
const fragmentAt = body.indexOf("#");
|
|
141
|
+
const repository = fragmentAt >= 0 ? body.slice(0, fragmentAt) : body;
|
|
142
|
+
const requestedRef = fragmentAt >= 0 ? body.slice(fragmentAt + 1) : "";
|
|
143
|
+
const cloneUrl = `https://github.com/${repository.replace(/\.git$/i, "")}`;
|
|
144
|
+
return requestedRef ? `${cloneUrl}/tree/${requestedRef}` : cloneUrl;
|
|
145
|
+
}
|
|
10
146
|
/**
|
|
11
147
|
* Synthesize a stable identifier when a {@link SourceConfigEntry} omits its
|
|
12
148
|
* `name`. Uses a short hash of the discriminating fields so two equivalent
|
|
13
149
|
* entries collapse to the same generated name.
|
|
14
150
|
*/
|
|
15
|
-
function
|
|
151
|
+
function deriveBundleName(entry) {
|
|
16
152
|
if (entry.name)
|
|
17
153
|
return entry.name;
|
|
18
154
|
const seed = JSON.stringify({
|
|
@@ -46,63 +182,50 @@ export function parseSourceSpec(entry) {
|
|
|
46
182
|
case "npm":
|
|
47
183
|
return entry.path ? { type: "npm", package: entry.path } : undefined;
|
|
48
184
|
default:
|
|
49
|
-
|
|
50
|
-
return entry.path ? { type: "filesystem", path: entry.path } : undefined;
|
|
185
|
+
return undefined;
|
|
51
186
|
}
|
|
52
187
|
}
|
|
53
188
|
/**
|
|
54
|
-
* Build the full ordered list of runtime {@link ConfiguredSource} values from
|
|
55
|
-
*
|
|
56
|
-
*
|
|
57
|
-
*
|
|
58
|
-
*
|
|
189
|
+
* Build the full ordered list of runtime {@link ConfiguredSource} values from a
|
|
190
|
+
* loaded {@link AkmConfig}, resolved from `bundles` + `defaultBundle` (spec
|
|
191
|
+
* §10.1): the `defaultBundle` (primary) first, then map insertion order. The
|
|
192
|
+
* retired `stashDir`/`sources[]`/`installed[]` trio is no longer read here — a
|
|
193
|
+
* pre-cutover config is normalized to bundles by the migrator before it loads.
|
|
59
194
|
*
|
|
60
195
|
* Entries with `enabled: false` are still emitted — callers decide whether to
|
|
61
196
|
* honour the flag. Entries that fail {@link parseSourceSpec} drop silently.
|
|
197
|
+
* Returns `[]` when no bundles are configured.
|
|
62
198
|
*/
|
|
63
199
|
export function resolveConfiguredSources(config) {
|
|
64
|
-
const
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
200
|
+
const bundleEntries = bundlesToSourceEntries(config);
|
|
201
|
+
if (!bundleEntries)
|
|
202
|
+
return [];
|
|
203
|
+
const out = [];
|
|
204
|
+
for (const persisted of bundleEntries) {
|
|
205
|
+
const runtime = toConfiguredSource(persisted, persisted.primary === true);
|
|
206
|
+
if (runtime) {
|
|
207
|
+
const component = bundleComponentConfig(config.bundles?.[persisted.name ?? ""]);
|
|
208
|
+
out.push({
|
|
209
|
+
...runtime,
|
|
210
|
+
...(component?.adapter ? { adapterId: component.adapter } : {}),
|
|
211
|
+
...(component?.root ? { componentRoot: component.root } : {}),
|
|
212
|
+
...(component?.writable !== undefined ? { writable: component.writable } : {}),
|
|
213
|
+
});
|
|
214
|
+
}
|
|
69
215
|
}
|
|
70
|
-
|
|
71
|
-
const runtime = toConfiguredSource(primary, true);
|
|
72
|
-
if (runtime)
|
|
73
|
-
entries.push(runtime);
|
|
74
|
-
}
|
|
75
|
-
for (const entry of sources) {
|
|
76
|
-
if (entry === primary)
|
|
77
|
-
continue;
|
|
78
|
-
const runtime = toConfiguredSource(entry, false);
|
|
79
|
-
if (runtime)
|
|
80
|
-
entries.push(runtime);
|
|
81
|
-
}
|
|
82
|
-
for (const installed of config.installed ?? []) {
|
|
83
|
-
entries.push({
|
|
84
|
-
name: installed.id,
|
|
85
|
-
type: "filesystem",
|
|
86
|
-
source: { type: "filesystem", path: installed.stashRoot },
|
|
87
|
-
enabled: true,
|
|
88
|
-
writable: installed.writable,
|
|
89
|
-
...(installed.wikiName ? { wikiName: installed.wikiName } : {}),
|
|
90
|
-
});
|
|
91
|
-
}
|
|
92
|
-
return entries;
|
|
216
|
+
return out;
|
|
93
217
|
}
|
|
94
218
|
function toConfiguredSource(persisted, isPrimary) {
|
|
95
219
|
const source = parseSourceSpec(persisted);
|
|
96
220
|
if (!source)
|
|
97
221
|
return undefined;
|
|
98
222
|
return {
|
|
99
|
-
name:
|
|
223
|
+
name: deriveBundleName(persisted),
|
|
100
224
|
type: persisted.type,
|
|
101
225
|
source,
|
|
102
226
|
...(persisted.enabled !== undefined ? { enabled: persisted.enabled } : {}),
|
|
103
227
|
...(persisted.writable !== undefined ? { writable: persisted.writable } : {}),
|
|
104
228
|
...(isPrimary || persisted.primary ? { primary: true } : {}),
|
|
105
229
|
...(persisted.options ? { options: persisted.options } : {}),
|
|
106
|
-
...(persisted.wikiName ? { wikiName: persisted.wikiName } : {}),
|
|
107
230
|
};
|
|
108
231
|
}
|
|
@@ -1,16 +1,21 @@
|
|
|
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
|
-
// VALID_HARNESS_IDS
|
|
5
|
-
//
|
|
6
|
-
//
|
|
7
|
-
//
|
|
8
|
-
|
|
4
|
+
// VALID_HARNESS_IDS / HARNESS_AGENT_DISPATCH_IDS derive from the dependency-free
|
|
5
|
+
// harnesses/ids.ts leaf (WI-9.8 KILL 3), NOT the full HARNESS_REGISTRY barrel
|
|
6
|
+
// (`../../integrations/harnesses`) — that barrel transitively pulls in every
|
|
7
|
+
// harness's agent-builder and the agent runtime, which is what fused config
|
|
8
|
+
// into the same import-cycle SCC as `integrations/agent/*`. `harnesses/index.ts`
|
|
9
|
+
// asserts at construction time that its registry matches this leaf, so the two
|
|
10
|
+
// cannot silently drift (see `tests/harnesses-registry.test.ts` for the
|
|
11
|
+
// value-level pin). config ← harnesses/ids is the only import direction (the
|
|
12
|
+
// leaf imports nothing), so there is no cycle.
|
|
13
|
+
import { HARNESS_AGENT_DISPATCH_IDS, VALID_HARNESS_IDS } from "../../integrations/harnesses/ids.js";
|
|
9
14
|
/**
|
|
10
|
-
* Canonical list of valid agent harness / platform ids.
|
|
11
|
-
*
|
|
12
|
-
*
|
|
13
|
-
* derive from one place and cannot drift. Add a harness in
|
|
14
|
-
* `src/integrations/harnesses/index.ts
|
|
15
|
+
* Canonical list of valid agent harness / platform ids. Derived from the
|
|
16
|
+
* dependency-free harness-id leaf (#562/WI-9.8) so the Zod `AgentPlatformSchema`
|
|
17
|
+
* enum, the agent-engine platform union, and setup's `DetectedHarness` union
|
|
18
|
+
* all derive from one place and cannot drift. Add a harness in
|
|
19
|
+
* `src/integrations/harnesses/index.ts` (and its `ids.ts` mirror entry).
|
|
15
20
|
*/
|
|
16
|
-
export { VALID_HARNESS_IDS };
|
|
21
|
+
export { HARNESS_AGENT_DISPATCH_IDS, VALID_HARNESS_IDS };
|
|
@@ -0,0 +1,29 @@
|
|
|
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
|
+
/** Compare legacy numeric or semver-like config versions for diagnostics only. */
|
|
5
|
+
export function compareConfigVersion(a, b) {
|
|
6
|
+
const left = normalize(a);
|
|
7
|
+
const right = normalize(b);
|
|
8
|
+
if (!left || !right)
|
|
9
|
+
return undefined;
|
|
10
|
+
for (let index = 0; index < Math.max(left.length, right.length); index += 1) {
|
|
11
|
+
const l = left[index] ?? 0;
|
|
12
|
+
const r = right[index] ?? 0;
|
|
13
|
+
if (l < r)
|
|
14
|
+
return -1;
|
|
15
|
+
if (l > r)
|
|
16
|
+
return 1;
|
|
17
|
+
}
|
|
18
|
+
return 0;
|
|
19
|
+
}
|
|
20
|
+
function normalize(value) {
|
|
21
|
+
if (typeof value === "number" && Number.isFinite(value))
|
|
22
|
+
return [0, Math.trunc(value), 0];
|
|
23
|
+
if (typeof value !== "string" || !value.trim())
|
|
24
|
+
return undefined;
|
|
25
|
+
const parts = value.trim().replace(/^v/i, "").split(/[-+]/, 1)[0].split(".");
|
|
26
|
+
if (parts.some((part) => !/^\d+$/.test(part)))
|
|
27
|
+
return undefined;
|
|
28
|
+
return parts.map(Number);
|
|
29
|
+
}
|
|
@@ -22,7 +22,8 @@
|
|
|
22
22
|
*/
|
|
23
23
|
import { z } from "zod";
|
|
24
24
|
import { UsageError } from "../errors.js";
|
|
25
|
-
import { AkmConfigBaseSchema, listTopLevelConfigKeys } from "./config-schema.js";
|
|
25
|
+
import { AkmConfigBaseSchema, EngineConfigSchema, listTopLevelConfigKeys } from "./config-schema.js";
|
|
26
|
+
import { deepMergeConfig } from "./deep-merge.js";
|
|
26
27
|
/**
|
|
27
28
|
* Parse a dotted path into segments. Empty segments are rejected. Bracket
|
|
28
29
|
* notation (e.g. `sources[0]`) is NOT supported — arrays are set as JSON.
|
|
@@ -73,9 +74,10 @@ function unwrap(schema) {
|
|
|
73
74
|
* AkmConfig schema. Returns `undefined` if any path segment doesn't match a
|
|
74
75
|
* known schema field.
|
|
75
76
|
*/
|
|
76
|
-
function resolveSchemaAt(path) {
|
|
77
|
+
function resolveSchemaAt(path, config, raw) {
|
|
77
78
|
let schema = AkmConfigBaseSchema;
|
|
78
|
-
|
|
79
|
+
let existing = config;
|
|
80
|
+
for (const [index, segment] of path.entries()) {
|
|
79
81
|
schema = unwrap(schema);
|
|
80
82
|
if (schema instanceof z.ZodObject) {
|
|
81
83
|
const next = schema.shape[segment];
|
|
@@ -84,23 +86,56 @@ function resolveSchemaAt(path) {
|
|
|
84
86
|
const catchall = schema._def.catchall;
|
|
85
87
|
if (catchall && !(catchall instanceof z.ZodNever)) {
|
|
86
88
|
schema = catchall;
|
|
87
|
-
continue;
|
|
88
89
|
}
|
|
89
|
-
|
|
90
|
+
else {
|
|
91
|
+
return undefined;
|
|
92
|
+
}
|
|
93
|
+
}
|
|
94
|
+
else {
|
|
95
|
+
schema = next;
|
|
90
96
|
}
|
|
91
|
-
schema = next;
|
|
92
97
|
}
|
|
93
98
|
else if (schema instanceof z.ZodRecord) {
|
|
94
|
-
//
|
|
99
|
+
// Named records (engines, improve.strategies, sources, etc.)
|
|
95
100
|
// accept any string key — descend into the value schema.
|
|
96
101
|
schema = schema._def.valueType;
|
|
97
102
|
}
|
|
103
|
+
else if (schema instanceof z.ZodUnion) {
|
|
104
|
+
const option = selectUnionObjectOption(schema._def.options, segment, existing, index === path.length - 1 ? raw : undefined);
|
|
105
|
+
if (!option)
|
|
106
|
+
return undefined;
|
|
107
|
+
schema = option.shape[segment];
|
|
108
|
+
}
|
|
98
109
|
else {
|
|
99
110
|
// Cannot descend into a non-object schema.
|
|
100
111
|
return undefined;
|
|
101
112
|
}
|
|
113
|
+
existing = isPlainObject(existing) ? existing[segment] : undefined;
|
|
102
114
|
}
|
|
103
|
-
|
|
115
|
+
// Preserve leaf refinements/transforms for validation. Traversal unwraps at
|
|
116
|
+
// the start of each loop iteration, while coercion unwraps independently.
|
|
117
|
+
return schema;
|
|
118
|
+
}
|
|
119
|
+
function selectUnionObjectOption(candidates, segment, existing, raw) {
|
|
120
|
+
const options = candidates
|
|
121
|
+
.map((candidate) => unwrap(candidate))
|
|
122
|
+
.filter((candidate) => candidate instanceof z.ZodObject);
|
|
123
|
+
if (raw !== undefined) {
|
|
124
|
+
const requested = options.find((option) => {
|
|
125
|
+
const leaf = option.shape[segment];
|
|
126
|
+
if (!leaf || !(unwrap(leaf) instanceof z.ZodLiteral))
|
|
127
|
+
return false;
|
|
128
|
+
return leaf.safeParse(coerceForSchema(leaf, raw, segment)).success;
|
|
129
|
+
});
|
|
130
|
+
if (requested)
|
|
131
|
+
return requested;
|
|
132
|
+
}
|
|
133
|
+
if (isPlainObject(existing)) {
|
|
134
|
+
const selected = options.find((option) => Object.entries(option.shape).some(([key, field]) => key in existing && unwrap(field) instanceof z.ZodLiteral && field.safeParse(existing[key]).success));
|
|
135
|
+
if (selected)
|
|
136
|
+
return segment in selected.shape ? selected : undefined;
|
|
137
|
+
}
|
|
138
|
+
return options.find((option) => segment in option.shape);
|
|
104
139
|
}
|
|
105
140
|
/**
|
|
106
141
|
* Get the value at the dotted path from a config-shaped object. Returns
|
|
@@ -109,7 +144,7 @@ function resolveSchemaAt(path) {
|
|
|
109
144
|
*/
|
|
110
145
|
export function configGet(config, dotted) {
|
|
111
146
|
const path = parsePath(dotted);
|
|
112
|
-
const schema = resolveSchemaAt(path);
|
|
147
|
+
const schema = resolveSchemaAt(path, config);
|
|
113
148
|
if (!schema) {
|
|
114
149
|
throw new UsageError(`Unknown config key: ${dotted}`, "INVALID_FLAG_VALUE", unknownKeyHint(dotted));
|
|
115
150
|
}
|
|
@@ -129,23 +164,38 @@ export function configGet(config, dotted) {
|
|
|
129
164
|
*
|
|
130
165
|
* Throws {@link UsageError} on:
|
|
131
166
|
* - unknown path
|
|
132
|
-
* - apiKey paths
|
|
167
|
+
* - invalid apiKey paths
|
|
133
168
|
* - coercion failure
|
|
134
169
|
*/
|
|
135
170
|
export function configSet(config, dotted, raw) {
|
|
136
171
|
const path = parsePath(dotted);
|
|
172
|
+
if (path.length === 1 && path[0] === "configVersion") {
|
|
173
|
+
throw new UsageError("configVersion cannot be changed through config set.", "INVALID_FLAG_VALUE");
|
|
174
|
+
}
|
|
137
175
|
// #454: apiKey paths are not persistable. Throw at set time.
|
|
138
176
|
rejectApiKeyPath(path, dotted);
|
|
139
|
-
const schema = resolveSchemaAt(path);
|
|
140
|
-
|
|
177
|
+
const schema = resolveSchemaAt(path, config, raw);
|
|
178
|
+
const symbolicApiKey = (path[0] === "engines" && path[2] === "apiKey") ||
|
|
179
|
+
(path[0] === "embedding" && path.length === 2 && path[1] === "apiKey");
|
|
180
|
+
if (!schema && !symbolicApiKey) {
|
|
141
181
|
throw new UsageError(`Unknown config key: ${dotted}`, "INVALID_FLAG_VALUE", unknownKeyHint(dotted));
|
|
142
182
|
}
|
|
143
|
-
const value =
|
|
183
|
+
const value = path[0] === "engines" && path.length === 2
|
|
184
|
+
? parseObjectPatch(raw, dotted)
|
|
185
|
+
: symbolicApiKey
|
|
186
|
+
? raw
|
|
187
|
+
: coerceForSchema(schema, raw, dotted);
|
|
144
188
|
// Validate the coerced value against the leaf schema. This catches enum
|
|
145
189
|
// mismatches, out-of-range numbers, schema-level shape errors (writable
|
|
146
190
|
// npm/website sources via .superRefine, strict-mode unknown keys in nested
|
|
147
191
|
// objects, etc.) BEFORE we apply the patch.
|
|
148
|
-
const parsed =
|
|
192
|
+
const parsed = path[0] === "engines" && path.length === 2
|
|
193
|
+
? EngineConfigSchema.safeParse(value)
|
|
194
|
+
: symbolicApiKey
|
|
195
|
+
? /^\$[A-Za-z_][A-Za-z0-9_]*$|^\$\{[A-Za-z_][A-Za-z0-9_]*\}$/.test(raw)
|
|
196
|
+
? { success: true, data: value }
|
|
197
|
+
: { success: false, error: { issues: [{ path: [], message: `apiKey must be $VAR or \${VAR}` }] } }
|
|
198
|
+
: schema.safeParse(value);
|
|
149
199
|
if (!parsed.success) {
|
|
150
200
|
const lines = parsed.error.issues
|
|
151
201
|
.map((i) => {
|
|
@@ -155,16 +205,20 @@ export function configSet(config, dotted, raw) {
|
|
|
155
205
|
.join("\n");
|
|
156
206
|
throw new UsageError(`Invalid value for ${dotted}:\n${lines}`, "INVALID_FLAG_VALUE");
|
|
157
207
|
}
|
|
158
|
-
const
|
|
159
|
-
|
|
208
|
+
const existing = path.reduce((value, key) => {
|
|
209
|
+
if (value && typeof value === "object")
|
|
210
|
+
return value[key];
|
|
211
|
+
return undefined;
|
|
212
|
+
}, config);
|
|
213
|
+
const next = setPath(config, path, isPlainObject(existing) && isPlainObject(parsed.data) ? deepMergeConfig(existing, parsed.data) : parsed.data);
|
|
214
|
+
// Targeted invariant: defaultWriteTarget must point at a configured bundle
|
|
160
215
|
// (#464.a). Whole-config validation happens at save time; this check fires
|
|
161
|
-
// at set time so the user sees the typo immediately.
|
|
162
|
-
// accepted here (legacy behaviour) — saveConfig will reject if it persists.
|
|
216
|
+
// at set time so the user sees the typo immediately.
|
|
163
217
|
if (dotted === "defaultWriteTarget" && typeof value === "string") {
|
|
164
|
-
const
|
|
165
|
-
const knownNames =
|
|
166
|
-
if (
|
|
167
|
-
throw new UsageError(`Unknown
|
|
218
|
+
const bundles = next.bundles && typeof next.bundles === "object" ? next.bundles : {};
|
|
219
|
+
const knownNames = Object.keys(bundles);
|
|
220
|
+
if (!knownNames.includes(value)) {
|
|
221
|
+
throw new UsageError(`Unknown bundle "${value}" for defaultWriteTarget; configured bundles: ${knownNames.map((n) => `"${n}"`).join(", ") || "none"}.`, "INVALID_FLAG_VALUE");
|
|
168
222
|
}
|
|
169
223
|
}
|
|
170
224
|
return next;
|
|
@@ -175,8 +229,11 @@ export function configSet(config, dotted, raw) {
|
|
|
175
229
|
*/
|
|
176
230
|
export function configUnset(config, dotted) {
|
|
177
231
|
const path = parsePath(dotted);
|
|
232
|
+
if (path.length === 1 && path[0] === "configVersion") {
|
|
233
|
+
throw new UsageError("configVersion cannot be removed through config unset.", "INVALID_FLAG_VALUE");
|
|
234
|
+
}
|
|
178
235
|
// Validate the path resolves to a real schema field (so typos don't no-op).
|
|
179
|
-
const schema = resolveSchemaAt(path);
|
|
236
|
+
const schema = resolveSchemaAt(path, config);
|
|
180
237
|
if (!schema) {
|
|
181
238
|
throw new UsageError(`Unknown config key: ${dotted}`, "INVALID_FLAG_VALUE", unknownKeyHint(dotted));
|
|
182
239
|
}
|
|
@@ -184,12 +241,14 @@ export function configUnset(config, dotted) {
|
|
|
184
241
|
}
|
|
185
242
|
// ── apiKey rejection (#454) ─────────────────────────────────────────────────
|
|
186
243
|
/**
|
|
187
|
-
*
|
|
188
|
-
*
|
|
189
|
-
* - `embedding.apiKey`
|
|
190
|
-
* - `profiles.llm.<name>.apiKey`
|
|
244
|
+
* Embedding credentials are never persisted. Engine credentials are symbolic
|
|
245
|
+
* configuration and are validated by the engine schema below.
|
|
191
246
|
*/
|
|
192
247
|
function rejectApiKeyPath(path, dotted) {
|
|
248
|
+
if (path[0] === "engines" && path[2] === "apiKey")
|
|
249
|
+
return;
|
|
250
|
+
if (path[0] === "embedding" && path.length === 2 && path[1] === "apiKey")
|
|
251
|
+
return;
|
|
193
252
|
const last = path[path.length - 1];
|
|
194
253
|
if (last !== "apiKey")
|
|
195
254
|
return;
|
|
@@ -197,14 +256,25 @@ function rejectApiKeyPath(path, dotted) {
|
|
|
197
256
|
throw new UsageError(`apiKey cannot be persisted in config; export ${recipe} instead. (key: ${dotted})`, "INVALID_FLAG_VALUE", "Storing API keys in config.json leaks them through backups, logs, and version control. " +
|
|
198
257
|
"Use the corresponding environment variable. AKM reads it at request time.");
|
|
199
258
|
}
|
|
259
|
+
function parseObjectPatch(raw, key) {
|
|
260
|
+
try {
|
|
261
|
+
const value = JSON.parse(raw);
|
|
262
|
+
if (!isPlainObject(value))
|
|
263
|
+
throw new Error("expected an object");
|
|
264
|
+
return value;
|
|
265
|
+
}
|
|
266
|
+
catch (err) {
|
|
267
|
+
throw new UsageError(`Invalid JSON object for ${key}: ${err instanceof Error ? err.message : String(err)}`, "INVALID_JSON_CONFIG_VALUE");
|
|
268
|
+
}
|
|
269
|
+
}
|
|
270
|
+
function isPlainObject(value) {
|
|
271
|
+
return value !== null && typeof value === "object" && !Array.isArray(value);
|
|
272
|
+
}
|
|
200
273
|
function recipeForApiKey(path, _dotted) {
|
|
201
274
|
if (path[0] === "embedding")
|
|
202
275
|
return "AKM_EMBED_API_KEY";
|
|
203
|
-
if (path[0] === "
|
|
204
|
-
return "
|
|
205
|
-
if (path[0] === "profiles" && path[1] === "llm" && typeof path[2] === "string") {
|
|
206
|
-
const upper = path[2].toUpperCase().replace(/-/g, "_");
|
|
207
|
-
return `AKM_PROFILE_${upper}_API_KEY (or AKM_LLM_API_KEY for the default profile)`;
|
|
276
|
+
if (path[0] === "engines" && typeof path[1] === "string") {
|
|
277
|
+
return `AKM_ENGINE_${path[1].toUpperCase().replaceAll("-", "_")}_API_KEY`;
|
|
208
278
|
}
|
|
209
279
|
return "AKM_LLM_API_KEY / AKM_EMBED_API_KEY";
|
|
210
280
|
}
|
|
@@ -237,7 +307,7 @@ function coerceForSchema(schema, raw, key) {
|
|
|
237
307
|
return raw;
|
|
238
308
|
}
|
|
239
309
|
if (target instanceof z.ZodLiteral) {
|
|
240
|
-
return target._def.value;
|
|
310
|
+
return typeof target._def.value === "string" ? raw : target._def.value;
|
|
241
311
|
}
|
|
242
312
|
if (target instanceof z.ZodArray || target instanceof z.ZodObject || target instanceof z.ZodRecord) {
|
|
243
313
|
if (raw === "" || raw === "null")
|
|
@@ -290,7 +360,8 @@ function coerceForSchema(schema, raw, key) {
|
|
|
290
360
|
function setPath(config, path, value) {
|
|
291
361
|
if (path.length === 0)
|
|
292
362
|
return config;
|
|
293
|
-
const
|
|
363
|
+
const head = path[0]; // non-empty: guarded by the `path.length === 0` check above
|
|
364
|
+
const rest = path.slice(1);
|
|
294
365
|
const next = { ...config };
|
|
295
366
|
if (rest.length === 0) {
|
|
296
367
|
if (value === undefined) {
|
|
@@ -311,7 +382,8 @@ function setPath(config, path, value) {
|
|
|
311
382
|
function unsetPath(config, path) {
|
|
312
383
|
if (path.length === 0)
|
|
313
384
|
return config;
|
|
314
|
-
const
|
|
385
|
+
const head = path[0]; // non-empty: guarded by the `path.length === 0` check above
|
|
386
|
+
const rest = path.slice(1);
|
|
315
387
|
const next = { ...config };
|
|
316
388
|
if (rest.length === 0) {
|
|
317
389
|
delete next[head];
|
|
@@ -331,7 +403,24 @@ function unsetPath(config, path) {
|
|
|
331
403
|
return next;
|
|
332
404
|
}
|
|
333
405
|
// ── Hint generation (#460) ──────────────────────────────────────────────────
|
|
334
|
-
|
|
406
|
+
/**
|
|
407
|
+
* Per-key "use X instead" guidance for config keys retired before the 0.9
|
|
408
|
+
* cutover, keyed on the first dotted-path segment. Mitigation item 3: the
|
|
409
|
+
* generic "valid top-level keys" hint doesn't tell a pre-0.9 user what
|
|
410
|
+
* replaced the key they typed — this does.
|
|
411
|
+
*/
|
|
412
|
+
const RETIRED_KEY_HINTS = {
|
|
413
|
+
stashDir: "stashDir was removed in 0.9; get the stash path from `akm config path --all` or `akm info`.",
|
|
414
|
+
sources: "sources was replaced by bundles in 0.9; run `akm-migrate apply` on a pre-0.9 config to convert it.",
|
|
415
|
+
installed: "installed was replaced by bundles in 0.9; run `akm-migrate apply` on a pre-0.9 config to convert it.",
|
|
416
|
+
wikiName: "the wiki subsystem was removed in 0.9; wikis are ordinary knowledge assets now — see `akm import`.",
|
|
417
|
+
wiki: "the wiki subsystem was removed in 0.9; wikis are ordinary knowledge assets now — see `akm import`.",
|
|
418
|
+
llm: "llm was replaced by named engines configuration in 0.9; configure `engines` instead.",
|
|
419
|
+
};
|
|
420
|
+
export function unknownKeyHint(attempted) {
|
|
335
421
|
const keys = listTopLevelConfigKeys();
|
|
336
|
-
|
|
422
|
+
const generic = `Valid top-level keys: ${keys.join(", ")}. Use dotted paths for nested values (e.g. embedding.endpoint, engines.<name>.model).`;
|
|
423
|
+
const firstSegment = attempted.split(".")[0] ?? "";
|
|
424
|
+
const retiredHint = RETIRED_KEY_HINTS[firstSegment];
|
|
425
|
+
return retiredHint ? `${retiredHint} ${generic}` : generic;
|
|
337
426
|
}
|