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
|
@@ -116,12 +116,15 @@ export function renderMigrationHelp(versionInput, changelogText = loadChangelog(
|
|
|
116
116
|
if (changelogText) {
|
|
117
117
|
for (const candidate of candidates) {
|
|
118
118
|
const section = extractChangelogSection(changelogText, candidate);
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
if (!
|
|
122
|
-
return `${
|
|
119
|
+
const bundled = loadReleaseNote(candidate);
|
|
120
|
+
if (bundled) {
|
|
121
|
+
if (!section)
|
|
122
|
+
return `${bundled.trim()}\n\nFull changelog: ${CHANGELOG_URL}\n`;
|
|
123
123
|
return `${bundled.trim()}\n\nRelease notes\n-------------\n${section.trim()}\n\nFull changelog: ${CHANGELOG_URL}\n`;
|
|
124
124
|
}
|
|
125
|
+
if (section) {
|
|
126
|
+
return `${section.trim()}\n\nFull changelog: ${CHANGELOG_URL}\n`;
|
|
127
|
+
}
|
|
125
128
|
}
|
|
126
129
|
}
|
|
127
130
|
const fallbackVersion = candidates.find((candidate) => candidate !== "latest") ?? requested;
|
|
@@ -14,15 +14,16 @@
|
|
|
14
14
|
*/
|
|
15
15
|
import fs from "node:fs";
|
|
16
16
|
import path from "node:path";
|
|
17
|
-
import { parseAssetRef } from "../../core/asset/asset-ref.js";
|
|
18
17
|
import { assembleAsset } from "../../core/asset/asset-serialize.js";
|
|
19
18
|
import { parseFrontmatter } from "../../core/asset/frontmatter.js";
|
|
19
|
+
import { parseRefInput } from "../../core/asset/resolve-ref.js";
|
|
20
20
|
import { authoringRulesForType } from "../../core/authoring-rules.js";
|
|
21
21
|
import { appendEvent, readEvents } from "../../core/events.js";
|
|
22
|
+
import { parseEmbeddedJsonResponse } from "../../core/parse.js";
|
|
22
23
|
import { resolveStandardsContext } from "../../core/standards/resolve-standards-context.js";
|
|
23
24
|
import { info } from "../../core/warn.js";
|
|
24
25
|
import { resolveAssetPath } from "../../indexer/walk/path-resolver.js";
|
|
25
|
-
import { chatCompletion
|
|
26
|
+
import { chatCompletion } from "../../llm/client.js";
|
|
26
27
|
import { createProposal, isProposalSkipped } from "../proposal/repository.js";
|
|
27
28
|
// ── Constants ────────────────────────────────────────────────────────────────
|
|
28
29
|
/** Minimum gap between schema-repair attempts on the same asset. */
|
|
@@ -39,8 +40,8 @@ const SCHEMA_REPAIR_WINDOW_MS = 30 * 24 * 60 * 60 * 1000; // 30 days
|
|
|
39
40
|
// ── Main ─────────────────────────────────────────────────────────────────────
|
|
40
41
|
/**
|
|
41
42
|
* Run the schema-repair loop for a batch of validation failures.
|
|
42
|
-
* Returns a list of per-asset outcome records and the set of refs
|
|
43
|
-
*
|
|
43
|
+
* Returns a list of per-asset outcome records and the set of refs whose live
|
|
44
|
+
* files were repaired. Queued proposals never count as live repairs.
|
|
44
45
|
*/
|
|
45
46
|
export async function runSchemaRepairPass(failures, options) {
|
|
46
47
|
const repairs = [];
|
|
@@ -55,7 +56,7 @@ export async function runSchemaRepairPass(failures, options) {
|
|
|
55
56
|
// Cooldown: skip repair if we ran it successfully recently.
|
|
56
57
|
const recentRepairs = readEvents({ type: "schema_repair_invoked", ref: failure.ref });
|
|
57
58
|
const lastRepair = recentRepairs.events
|
|
58
|
-
.filter((e) => e.metadata?.outcome === "
|
|
59
|
+
.filter((e) => e.metadata?.outcome === "queued")
|
|
59
60
|
.sort((a, b) => new Date(b.ts ?? 0).getTime() - new Date(a.ts ?? 0).getTime())[0];
|
|
60
61
|
if (lastRepair?.ts && Date.now() - new Date(lastRepair.ts).getTime() < SCHEMA_REPAIR_COOLDOWN_MS) {
|
|
61
62
|
repairs.push({ ref: failure.ref, reason: failure.reason, outcome: "skipped" });
|
|
@@ -106,7 +107,7 @@ export async function runSchemaRepairPass(failures, options) {
|
|
|
106
107
|
const standardsSection = standardsContext.trim()
|
|
107
108
|
? `\n\nStandards to follow (the rulebook for this target):\n${standardsContext.trim()}`
|
|
108
109
|
: "";
|
|
109
|
-
const assetType =
|
|
110
|
+
const assetType = parseRefInput(failure.ref).type;
|
|
110
111
|
const authoringRules = authoringRulesForType(assetType);
|
|
111
112
|
const authoringRulesSection = authoringRules ? `\n\n${authoringRules}` : "";
|
|
112
113
|
const llmResponse = await chatFn(llmConfig, [
|
|
@@ -145,6 +146,8 @@ export async function runSchemaRepairPass(failures, options) {
|
|
|
145
146
|
const proposalResult = createProposal(stashDir, {
|
|
146
147
|
ref: failure.ref,
|
|
147
148
|
source: "schema-repair",
|
|
149
|
+
// §23.6 fingerprint model-id term (WI-6.4).
|
|
150
|
+
modelId: llmConfig.model,
|
|
148
151
|
payload: {
|
|
149
152
|
content: newContent,
|
|
150
153
|
...(Object.keys(newFm).length > 0 ? { frontmatter: newFm } : {}),
|
|
@@ -167,8 +170,6 @@ export async function runSchemaRepairPass(failures, options) {
|
|
|
167
170
|
outcome: "queued",
|
|
168
171
|
proposalId: proposalResult.id,
|
|
169
172
|
});
|
|
170
|
-
// Mark as repaired so the caller removes it from the validation-failure set.
|
|
171
|
-
repairedRefs.add(failure.ref);
|
|
172
173
|
}
|
|
173
174
|
catch (e) {
|
|
174
175
|
appendEvent({
|
|
@@ -184,7 +185,7 @@ export async function runSchemaRepairPass(failures, options) {
|
|
|
184
185
|
// ── Default seam implementations ─────────────────────────────────────────────
|
|
185
186
|
function defaultIsLessonCandidate(ref) {
|
|
186
187
|
try {
|
|
187
|
-
const parsed =
|
|
188
|
+
const parsed = parseRefInput(ref);
|
|
188
189
|
return parsed.type === "lesson";
|
|
189
190
|
}
|
|
190
191
|
catch {
|
|
@@ -5,7 +5,8 @@ import * as childProcess from "node:child_process";
|
|
|
5
5
|
import { createHash } from "node:crypto";
|
|
6
6
|
import fs from "node:fs";
|
|
7
7
|
import path from "node:path";
|
|
8
|
-
import { fetchWithRetry, IS_WINDOWS } from "../../core/common.js";
|
|
8
|
+
import { fetchWithRetry, IS_WINDOWS, ResponseTooLargeError, readBodyWithByteCap } from "../../core/common.js";
|
|
9
|
+
import { ConfigError } from "../../core/errors.js";
|
|
9
10
|
import { warn } from "../../core/warn.js";
|
|
10
11
|
import { githubHeaders } from "../../integrations/github.js";
|
|
11
12
|
import { getDirname, mainPath, semverOrder } from "../../runtime.js";
|
|
@@ -14,6 +15,64 @@ const DEFAULT_PACKAGE_NAME = "akm-cli";
|
|
|
14
15
|
const NODE_MODULES_SEGMENT = "/node_modules/";
|
|
15
16
|
const BUN_GLOBAL_INSTALL_PATTERN = /(^|\/)\.bun\/(?:[^/]+\/)+node_modules\//;
|
|
16
17
|
const PNPM_GLOBAL_INSTALL_PATTERN = /(^|\/)(?:pnpm\/global|\.pnpm-global)(?:\/\d+)?\/node_modules\//;
|
|
18
|
+
const MIGRATION_CONTRACT_VERSION = "0.9.0-rc.0";
|
|
19
|
+
const MIGRATION_CONTRACT_BLOCKED_MESSAGE = "AKM 0.8 does not implement the migrate command or the --migration-config upgrade contract, so self-update cannot safely cross into 0.9. " +
|
|
20
|
+
"Prepare the 0.9 config and an independent backup, install or stage the 0.9 binary manually, then use the new binary to run: " +
|
|
21
|
+
"akm migrate apply --config <prepared-0.9.json>. See docs/migration/v0.8-to-v0.9.md.";
|
|
22
|
+
const MAX_BINARY_DOWNLOAD_BYTES = 256 * 1024 * 1024;
|
|
23
|
+
const MAX_CHECKSUM_METADATA_BYTES = 1024 * 1024;
|
|
24
|
+
export function defaultMigrationCommand(preparedConfigPath) {
|
|
25
|
+
const configArgs = preparedConfigPath ? ["--config", preparedConfigPath] : [];
|
|
26
|
+
return {
|
|
27
|
+
preflight: (akmBin) => runRequiredCommand(akmBin, ["migrate", "status"], "Migration preflight"),
|
|
28
|
+
stagedPreflight: (akmBin) => runRequiredCommand(akmBin, ["migrate", "status", ...configArgs], "Staged migration preflight"),
|
|
29
|
+
apply: (akmBin) => runRequiredCommand(akmBin, ["migrate", "apply", ...configArgs], "Migration apply"),
|
|
30
|
+
};
|
|
31
|
+
}
|
|
32
|
+
async function streamResponseToFile(response, destination, maxBytes) {
|
|
33
|
+
const declaredText = response.headers.get("content-length");
|
|
34
|
+
if (declaredText) {
|
|
35
|
+
const declared = Number(declaredText);
|
|
36
|
+
if (Number.isFinite(declared) && declared > maxBytes) {
|
|
37
|
+
await response.body?.cancel().catch(() => undefined);
|
|
38
|
+
throw new ResponseTooLargeError(response.url || "binary download", maxBytes, declared);
|
|
39
|
+
}
|
|
40
|
+
}
|
|
41
|
+
if (!response.body)
|
|
42
|
+
throw new Error("Binary download response did not provide a streaming body.");
|
|
43
|
+
const fd = fs.openSync(destination, "w", 0o600);
|
|
44
|
+
const reader = response.body.getReader();
|
|
45
|
+
const hash = createHash("sha256");
|
|
46
|
+
let byteSize = 0;
|
|
47
|
+
try {
|
|
48
|
+
while (true) {
|
|
49
|
+
const { done, value } = await reader.read();
|
|
50
|
+
if (done)
|
|
51
|
+
break;
|
|
52
|
+
if (!value)
|
|
53
|
+
continue;
|
|
54
|
+
byteSize += value.byteLength;
|
|
55
|
+
if (byteSize > maxBytes) {
|
|
56
|
+
await reader.cancel().catch(() => undefined);
|
|
57
|
+
throw new ResponseTooLargeError(response.url || "binary download", maxBytes, byteSize);
|
|
58
|
+
}
|
|
59
|
+
hash.update(value);
|
|
60
|
+
let written = 0;
|
|
61
|
+
while (written < value.byteLength)
|
|
62
|
+
written += fs.writeSync(fd, value, written, value.byteLength - written);
|
|
63
|
+
}
|
|
64
|
+
fs.fdatasyncSync(fd);
|
|
65
|
+
return { byteSize, sha256: hash.digest("hex") };
|
|
66
|
+
}
|
|
67
|
+
catch (error) {
|
|
68
|
+
removeFileBestEffort(destination);
|
|
69
|
+
throw error;
|
|
70
|
+
}
|
|
71
|
+
finally {
|
|
72
|
+
reader.releaseLock();
|
|
73
|
+
fs.closeSync(fd);
|
|
74
|
+
}
|
|
75
|
+
}
|
|
17
76
|
/** Read live runtime signals. */
|
|
18
77
|
export function getInstallSignals() {
|
|
19
78
|
return {
|
|
@@ -63,7 +122,7 @@ export function getAkmBinaryName() {
|
|
|
63
122
|
return "akm-darwin-arm64";
|
|
64
123
|
if (platform === "win32" && arch === "x64")
|
|
65
124
|
return "akm-windows-x64.exe";
|
|
66
|
-
throw new
|
|
125
|
+
throw new ConfigError(`Unsupported platform for binary upgrade: ${platform}/${arch}`, "UNSUPPORTED_PLATFORM");
|
|
67
126
|
}
|
|
68
127
|
export async function checkForUpdate(currentVersion) {
|
|
69
128
|
const installMethod = detectInstallMethod();
|
|
@@ -72,7 +131,7 @@ export async function checkForUpdate(currentVersion) {
|
|
|
72
131
|
if (!response.ok) {
|
|
73
132
|
throw new Error(`Failed to check for updates: ${response.status} ${response.statusText}`);
|
|
74
133
|
}
|
|
75
|
-
const release = (await response
|
|
134
|
+
const release = JSON.parse(await readBodyWithByteCap(response, MAX_CHECKSUM_METADATA_BYTES));
|
|
76
135
|
const latestTag = release.tag_name ?? "";
|
|
77
136
|
const latestVersion = latestTag.replace(/^v/, "");
|
|
78
137
|
return {
|
|
@@ -82,10 +141,26 @@ export async function checkForUpdate(currentVersion) {
|
|
|
82
141
|
installMethod,
|
|
83
142
|
};
|
|
84
143
|
}
|
|
85
|
-
|
|
144
|
+
/**
|
|
145
|
+
* Whether the operator has asked to bypass upgrade checksum verification.
|
|
146
|
+
*
|
|
147
|
+
* Deliberately NOT a CLI flag (C6): STABILITY.md states checksum verification
|
|
148
|
+
* is not optional, so the recovery hatch for a genuinely broken `checksums.txt`
|
|
149
|
+
* is this internal, undocumented-on-purpose env var — not something
|
|
150
|
+
* discoverable in `--help` or offered by tab completion.
|
|
151
|
+
*
|
|
152
|
+
* Extracted rather than read inline so `performUpgrade` stays under the
|
|
153
|
+
* function-size bar (`scripts/lint-src-fn-size.ts`), whose baseline only
|
|
154
|
+
* shrinks.
|
|
155
|
+
*/
|
|
156
|
+
function checksumBypassRequested() {
|
|
157
|
+
return process.env.AKM_UPGRADE_SKIP_CHECKSUM === "1";
|
|
158
|
+
}
|
|
159
|
+
export async function performUpgrade(check, opts, dependencies) {
|
|
86
160
|
const { currentVersion, latestVersion, installMethod } = check;
|
|
87
161
|
const force = opts?.force === true;
|
|
88
162
|
const skipPostUpgrade = opts?.skipPostUpgrade === true;
|
|
163
|
+
const migration = dependencies?.migration ?? defaultMigrationCommand(opts?.migrationConfig);
|
|
89
164
|
// All install methods can short-circuit here unless the user explicitly forces an upgrade.
|
|
90
165
|
if (!check.updateAvailable && !force) {
|
|
91
166
|
return {
|
|
@@ -96,11 +171,17 @@ export async function performUpgrade(check, opts) {
|
|
|
96
171
|
message: `akm v${currentVersion} is already the latest version`,
|
|
97
172
|
};
|
|
98
173
|
}
|
|
174
|
+
if (latestVersion &&
|
|
175
|
+
semverOrder(currentVersion, MIGRATION_CONTRACT_VERSION) < 0 &&
|
|
176
|
+
semverOrder(latestVersion, MIGRATION_CONTRACT_VERSION) >= 0) {
|
|
177
|
+
throw new ConfigError(MIGRATION_CONTRACT_BLOCKED_MESSAGE, "UPGRADE_BLOCKED");
|
|
178
|
+
}
|
|
99
179
|
const packageManagerCommand = getPackageManagerUpgradeCommand(installMethod);
|
|
100
180
|
if (packageManagerCommand) {
|
|
101
181
|
if (!latestVersion) {
|
|
102
182
|
throw new Error("Unable to determine latest version from GitHub releases. Check https://github.com/itlackey/akm/releases");
|
|
103
183
|
}
|
|
184
|
+
migration.preflight("akm");
|
|
104
185
|
const result = childProcess.spawnSync(packageManagerCommand.command, packageManagerCommand.args, {
|
|
105
186
|
encoding: "utf8",
|
|
106
187
|
env: process.env,
|
|
@@ -113,6 +194,7 @@ export async function performUpgrade(check, opts) {
|
|
|
113
194
|
const details = (result.stderr ?? "").trim() || (result.stdout ?? "").trim() || `exit code ${result.status}`;
|
|
114
195
|
throw new Error(`Failed to upgrade akm via ${installMethod}: ${details}\nRun manually: ${packageManagerCommand.displayCommand}`);
|
|
115
196
|
}
|
|
197
|
+
migration.apply("akm");
|
|
116
198
|
return {
|
|
117
199
|
currentVersion,
|
|
118
200
|
newVersion: latestVersion,
|
|
@@ -139,31 +221,53 @@ export async function performUpgrade(check, opts) {
|
|
|
139
221
|
const binaryName = getAkmBinaryName();
|
|
140
222
|
const binaryUrl = `https://github.com/${REPO}/releases/download/${tag}/${binaryName}`;
|
|
141
223
|
const checksumsUrl = `https://github.com/${REPO}/releases/download/${tag}/checksums.txt`;
|
|
224
|
+
const execPath = dependencies?.execPath ?? process.execPath;
|
|
225
|
+
const execDir = path.dirname(execPath);
|
|
226
|
+
const execName = path.basename(execPath);
|
|
227
|
+
const stagedPath = IS_WINDOWS
|
|
228
|
+
? path.join(execDir, `.${execName}.new.${process.pid}`)
|
|
229
|
+
: path.join(execDir, `.${execName}.tmp.${process.pid}`);
|
|
230
|
+
const backupPath = `${execPath}${IS_WINDOWS ? ".old" : ".bak"}`;
|
|
142
231
|
// Download binary
|
|
143
232
|
const binaryResponse = await fetchWithRetry(binaryUrl);
|
|
144
233
|
if (!binaryResponse.ok) {
|
|
145
234
|
throw new Error(`Failed to download binary: ${binaryResponse.status} ${binaryResponse.statusText}`);
|
|
146
235
|
}
|
|
147
|
-
|
|
148
|
-
|
|
236
|
+
let downloaded;
|
|
237
|
+
try {
|
|
238
|
+
downloaded = await streamResponseToFile(binaryResponse, stagedPath, MAX_BINARY_DOWNLOAD_BYTES);
|
|
239
|
+
if (!IS_WINDOWS)
|
|
240
|
+
fs.chmodSync(stagedPath, 0o755);
|
|
241
|
+
}
|
|
242
|
+
catch (err) {
|
|
243
|
+
removeFileBestEffort(stagedPath);
|
|
244
|
+
const code = err.code;
|
|
245
|
+
if (code === "EACCES" || code === "EPERM") {
|
|
246
|
+
throw new ConfigError(`Permission denied writing to ${execDir}.\n` +
|
|
247
|
+
`${IS_WINDOWS ? "Try running as Administrator." : "Run: sudo akm upgrade"}\n` +
|
|
248
|
+
`Or re-run the install script: curl -fsSL https://raw.githubusercontent.com/${REPO}/main/install.sh | bash`, "UPGRADE_BLOCKED");
|
|
249
|
+
}
|
|
250
|
+
throw err;
|
|
251
|
+
}
|
|
252
|
+
// Download and verify checksum (mandatory — upgrade is blocked if checksums cannot be fetched).
|
|
149
253
|
let checksumVerified = false;
|
|
150
|
-
const skipChecksum =
|
|
254
|
+
const skipChecksum = checksumBypassRequested();
|
|
151
255
|
try {
|
|
152
256
|
const checksumsResponse = await fetchWithRetry(checksumsUrl);
|
|
153
257
|
if (!checksumsResponse.ok) {
|
|
154
258
|
if (skipChecksum) {
|
|
155
|
-
warn(`WARNING: checksums.txt fetch failed (HTTP ${checksumsResponse.status}). Proceeding without verification because
|
|
259
|
+
warn(`WARNING: checksums.txt fetch failed (HTTP ${checksumsResponse.status}). Proceeding without verification because AKM_UPGRADE_SKIP_CHECKSUM=1 was set.`);
|
|
156
260
|
}
|
|
157
261
|
else {
|
|
158
262
|
throw new Error(`Checksum verification failed: could not fetch ${checksumsUrl} (HTTP ${checksumsResponse.status}). ` +
|
|
159
|
-
`
|
|
263
|
+
`Set AKM_UPGRADE_SKIP_CHECKSUM=1 to bypass (not recommended).`);
|
|
160
264
|
}
|
|
161
265
|
}
|
|
162
266
|
else {
|
|
163
|
-
const checksumsText = await checksumsResponse
|
|
267
|
+
const checksumsText = await readBodyWithByteCap(checksumsResponse, MAX_CHECKSUM_METADATA_BYTES);
|
|
164
268
|
const expectedHash = parseChecksumForFile(checksumsText, binaryName);
|
|
165
269
|
if (expectedHash) {
|
|
166
|
-
const actualHash =
|
|
270
|
+
const actualHash = downloaded.sha256;
|
|
167
271
|
if (actualHash !== expectedHash) {
|
|
168
272
|
throw new Error(`Checksum mismatch for ${binaryName}.\n` + `Expected: ${expectedHash}\n` + `Got: ${actualHash}`);
|
|
169
273
|
}
|
|
@@ -171,11 +275,11 @@ export async function performUpgrade(check, opts) {
|
|
|
171
275
|
}
|
|
172
276
|
else {
|
|
173
277
|
if (skipChecksum) {
|
|
174
|
-
warn(`WARNING: ${binaryName} not found in checksums.txt. Proceeding without verification because
|
|
278
|
+
warn(`WARNING: ${binaryName} not found in checksums.txt. Proceeding without verification because AKM_UPGRADE_SKIP_CHECKSUM=1 was set.`);
|
|
175
279
|
}
|
|
176
280
|
else {
|
|
177
281
|
throw new Error(`Checksum verification failed: ${binaryName} not listed in checksums.txt. ` +
|
|
178
|
-
`
|
|
282
|
+
`Set AKM_UPGRADE_SKIP_CHECKSUM=1 to bypass (not recommended).`);
|
|
179
283
|
}
|
|
180
284
|
}
|
|
181
285
|
}
|
|
@@ -183,106 +287,54 @@ export async function performUpgrade(check, opts) {
|
|
|
183
287
|
catch (err) {
|
|
184
288
|
if (err instanceof Error &&
|
|
185
289
|
(err.message.includes("Checksum mismatch") || err.message.includes("Checksum verification failed"))) {
|
|
290
|
+
removeFileBestEffort(stagedPath);
|
|
186
291
|
throw err;
|
|
187
292
|
}
|
|
188
293
|
// Network or parse failure
|
|
189
294
|
if (skipChecksum) {
|
|
190
|
-
warn(`WARNING: Could not fetch or parse checksums: ${err instanceof Error ? err.message : String(err)}. Proceeding because
|
|
295
|
+
warn(`WARNING: Could not fetch or parse checksums: ${err instanceof Error ? err.message : String(err)}. Proceeding because AKM_UPGRADE_SKIP_CHECKSUM=1 was set.`);
|
|
191
296
|
}
|
|
192
297
|
else {
|
|
298
|
+
removeFileBestEffort(stagedPath);
|
|
193
299
|
throw new Error(`Checksum verification failed: ${err instanceof Error ? err.message : String(err)}. ` +
|
|
194
|
-
`
|
|
300
|
+
`Set AKM_UPGRADE_SKIP_CHECKSUM=1 to bypass (not recommended).`);
|
|
195
301
|
}
|
|
196
302
|
}
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
if (IS_WINDOWS) {
|
|
201
|
-
// Windows: rename running exe, write new one, clean up old on success
|
|
202
|
-
const oldPath = `${execPath}.old`;
|
|
203
|
-
try {
|
|
204
|
-
fs.renameSync(execPath, oldPath);
|
|
205
|
-
}
|
|
206
|
-
catch (err) {
|
|
207
|
-
const code = err.code;
|
|
208
|
-
if (code === "EPERM" || code === "EACCES") {
|
|
209
|
-
throw new Error(`Permission denied. Cannot rename ${execPath}.\n` +
|
|
210
|
-
`Try running as Administrator, or re-download from https://github.com/${REPO}/releases`);
|
|
211
|
-
}
|
|
212
|
-
const detail = err instanceof Error ? err.message : String(err);
|
|
213
|
-
throw new Error(`Failed to rename ${execPath}: ${detail}`);
|
|
214
|
-
}
|
|
215
|
-
try {
|
|
216
|
-
fs.writeFileSync(execPath, binaryData);
|
|
217
|
-
}
|
|
218
|
-
catch (err) {
|
|
219
|
-
// Restore from old
|
|
220
|
-
fs.renameSync(oldPath, execPath);
|
|
221
|
-
throw err;
|
|
222
|
-
}
|
|
223
|
-
// Best-effort cleanup of .old
|
|
224
|
-
try {
|
|
225
|
-
fs.unlinkSync(oldPath);
|
|
226
|
-
}
|
|
227
|
-
catch {
|
|
228
|
-
// Windows may lock the old exe — it will be cleaned up on next startup or manually
|
|
229
|
-
}
|
|
303
|
+
try {
|
|
304
|
+
migration.preflight(execPath);
|
|
305
|
+
migration.stagedPreflight(stagedPath);
|
|
230
306
|
}
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
`Run: sudo akm upgrade\n` +
|
|
251
|
-
`Or re-run the install script: curl -fsSL https://raw.githubusercontent.com/${REPO}/main/install.sh | bash`);
|
|
252
|
-
}
|
|
253
|
-
throw err;
|
|
254
|
-
}
|
|
255
|
-
// Backup current, then atomic rename
|
|
256
|
-
try {
|
|
257
|
-
fs.copyFileSync(execPath, bakPath);
|
|
258
|
-
fs.renameSync(tmpPath, execPath);
|
|
259
|
-
}
|
|
260
|
-
catch (err) {
|
|
261
|
-
// Restore from backup if rename failed
|
|
262
|
-
try {
|
|
263
|
-
fs.unlinkSync(tmpPath);
|
|
264
|
-
}
|
|
265
|
-
catch {
|
|
266
|
-
/* ignore */
|
|
267
|
-
}
|
|
268
|
-
try {
|
|
269
|
-
if (fs.existsSync(bakPath) && !fs.existsSync(execPath)) {
|
|
270
|
-
fs.renameSync(bakPath, execPath);
|
|
271
|
-
}
|
|
272
|
-
}
|
|
273
|
-
catch {
|
|
274
|
-
/* ignore */
|
|
275
|
-
}
|
|
276
|
-
throw err;
|
|
277
|
-
}
|
|
278
|
-
// Cleanup backup
|
|
279
|
-
try {
|
|
280
|
-
fs.unlinkSync(bakPath);
|
|
281
|
-
}
|
|
282
|
-
catch {
|
|
283
|
-
/* ignore */
|
|
307
|
+
catch (err) {
|
|
308
|
+
removeFileBestEffort(stagedPath);
|
|
309
|
+
throw err;
|
|
310
|
+
}
|
|
311
|
+
if (fs.existsSync(backupPath)) {
|
|
312
|
+
removeFileBestEffort(stagedPath);
|
|
313
|
+
throw new ConfigError(`Refusing to overwrite retained previous binary at ${backupPath}.`, "UPGRADE_BLOCKED");
|
|
314
|
+
}
|
|
315
|
+
try {
|
|
316
|
+
if (IS_WINDOWS)
|
|
317
|
+
fs.renameSync(execPath, backupPath);
|
|
318
|
+
else
|
|
319
|
+
fs.copyFileSync(execPath, backupPath);
|
|
320
|
+
fs.renameSync(stagedPath, execPath);
|
|
321
|
+
}
|
|
322
|
+
catch (err) {
|
|
323
|
+
removeFileBestEffort(stagedPath);
|
|
324
|
+
if (!fs.existsSync(execPath) && fs.existsSync(backupPath)) {
|
|
325
|
+
fs.renameSync(backupPath, execPath);
|
|
284
326
|
}
|
|
327
|
+
throw err;
|
|
328
|
+
}
|
|
329
|
+
try {
|
|
330
|
+
migration.apply(execPath);
|
|
285
331
|
}
|
|
332
|
+
catch (err) {
|
|
333
|
+
const detail = err instanceof Error ? err.message : String(err);
|
|
334
|
+
throw new Error(`Migration apply failed; the new binary remains installed and the previous binary retained at ${backupPath}: ${detail}`);
|
|
335
|
+
}
|
|
336
|
+
// Keep the previous binary available until migration apply has completed.
|
|
337
|
+
removeFileBestEffort(backupPath);
|
|
286
338
|
return {
|
|
287
339
|
currentVersion,
|
|
288
340
|
newVersion: latestVersion,
|
|
@@ -290,32 +342,19 @@ export async function performUpgrade(check, opts) {
|
|
|
290
342
|
installMethod,
|
|
291
343
|
binaryPath: execPath,
|
|
292
344
|
checksumVerified,
|
|
293
|
-
// For binary installs, the new binary now lives at execPath; spawn it
|
|
294
|
-
// directly so the post-upgrade work runs against the new code.
|
|
295
345
|
postUpgrade: runPostUpgradeTasks(execPath, { skip: skipPostUpgrade }),
|
|
296
346
|
};
|
|
297
347
|
}
|
|
298
348
|
/**
|
|
299
|
-
*
|
|
300
|
-
*
|
|
301
|
-
* Why a child process: the running akm process still has the old code in
|
|
302
|
-
* memory. Calling loadConfig()/akmIndex() in-process would use the old
|
|
303
|
-
* implementations and miss any DB_VERSION / config-key changes the new
|
|
304
|
-
* release introduces.
|
|
305
|
-
*
|
|
306
|
-
* The new binary's `akm index` does the work for us:
|
|
307
|
-
* 1. loadConfig() runs at startup — auto-migrates legacy `stashes` →
|
|
308
|
-
* `sources` if the on-disk config still uses the old key.
|
|
309
|
-
* 2. ensureSchema() converges index.db forward via its idempotent baseline
|
|
310
|
-
* schema + additive migrations (no destructive rebuild).
|
|
311
|
-
* 3. The full reindex repopulates entries + workflow_documents + FTS.
|
|
349
|
+
* Rebuild the derived index after the explicit migration command succeeds.
|
|
350
|
+
* Migration and indexing are intentionally separate lifecycle steps.
|
|
312
351
|
*/
|
|
313
352
|
function runPostUpgradeTasks(akmBin, opts) {
|
|
314
353
|
if (opts.skip) {
|
|
315
354
|
return {
|
|
316
355
|
ok: true,
|
|
317
356
|
skipped: true,
|
|
318
|
-
message: "
|
|
357
|
+
message: "Migration completed; skipped the index rebuild. Run `akm index` manually to rebuild the index.",
|
|
319
358
|
};
|
|
320
359
|
}
|
|
321
360
|
try {
|
|
@@ -328,7 +367,7 @@ function runPostUpgradeTasks(akmBin, opts) {
|
|
|
328
367
|
return {
|
|
329
368
|
ok: false,
|
|
330
369
|
skipped: false,
|
|
331
|
-
message: `
|
|
370
|
+
message: `Migration completed, but the index rebuild could not start: ${result.error.message}. Run \`akm index\` manually.`,
|
|
332
371
|
};
|
|
333
372
|
}
|
|
334
373
|
if (result.status !== 0) {
|
|
@@ -337,14 +376,14 @@ function runPostUpgradeTasks(akmBin, opts) {
|
|
|
337
376
|
ok: false,
|
|
338
377
|
skipped: false,
|
|
339
378
|
exitCode: result.status,
|
|
340
|
-
message: `
|
|
379
|
+
message: `Migration completed, but post-upgrade \`akm index\` failed (${detail}). Run \`akm index\` manually.`,
|
|
341
380
|
};
|
|
342
381
|
}
|
|
343
382
|
return {
|
|
344
383
|
ok: true,
|
|
345
384
|
skipped: false,
|
|
346
385
|
exitCode: 0,
|
|
347
|
-
message: "
|
|
386
|
+
message: "Migration completed and the index was rebuilt against the new binary.",
|
|
348
387
|
};
|
|
349
388
|
}
|
|
350
389
|
catch (err) {
|
|
@@ -352,10 +391,32 @@ function runPostUpgradeTasks(akmBin, opts) {
|
|
|
352
391
|
return {
|
|
353
392
|
ok: false,
|
|
354
393
|
skipped: false,
|
|
355
|
-
message: `
|
|
394
|
+
message: `Migration completed, but the index rebuild failed: ${detail}. Run \`akm index\` manually.`,
|
|
356
395
|
};
|
|
357
396
|
}
|
|
358
397
|
}
|
|
398
|
+
function runRequiredCommand(akmBin, args, label) {
|
|
399
|
+
const result = childProcess.spawnSync(akmBin, args, {
|
|
400
|
+
encoding: "utf8",
|
|
401
|
+
env: process.env,
|
|
402
|
+
stdio: "pipe",
|
|
403
|
+
});
|
|
404
|
+
if (result.error) {
|
|
405
|
+
throw new Error(`${label} could not start: ${result.error.message}`);
|
|
406
|
+
}
|
|
407
|
+
if (result.status !== 0) {
|
|
408
|
+
const detail = (result.stderr ?? "").trim() || (result.stdout ?? "").trim() || `exit code ${result.status}`;
|
|
409
|
+
throw new Error(`${label} failed (${detail}).`);
|
|
410
|
+
}
|
|
411
|
+
}
|
|
412
|
+
function removeFileBestEffort(filePath) {
|
|
413
|
+
try {
|
|
414
|
+
fs.unlinkSync(filePath);
|
|
415
|
+
}
|
|
416
|
+
catch {
|
|
417
|
+
// Cleanup is best-effort; the primary operation determines success.
|
|
418
|
+
}
|
|
419
|
+
}
|
|
359
420
|
function parseChecksumForFile(checksumsText, filename) {
|
|
360
421
|
for (const line of checksumsText.split("\n")) {
|
|
361
422
|
const trimmed = line.trim();
|