akm-cli 0.9.0-rc.1 → 0.9.0-rc.13
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +1190 -52
- package/README.md +62 -37
- package/SECURITY.md +46 -31
- package/dist/akm +162 -38
- package/dist/akm-migrate +44 -0
- package/dist/assets/backends/schtasks-template.xml +2 -1
- package/dist/assets/hints/cli-hints-full.md +268 -118
- package/dist/assets/hints/cli-hints-short.md +87 -24
- package/dist/assets/{profiles → improve-strategies}/catchup.json +3 -1
- package/dist/assets/{profiles → improve-strategies}/consolidate.json +3 -1
- package/dist/assets/{profiles → improve-strategies}/default.json +6 -7
- package/dist/assets/improve-strategies/frequent.json +15 -0
- package/dist/assets/{profiles → improve-strategies}/graph-refresh.json +4 -2
- package/dist/assets/{profiles → improve-strategies}/memory-focus.json +4 -1
- package/dist/assets/{profiles → improve-strategies}/proactive-maintenance.json +5 -5
- package/dist/assets/{profiles → improve-strategies}/quick.json +4 -2
- package/dist/assets/improve-strategies/reflect-distill.json +30 -0
- package/dist/assets/{profiles → improve-strategies}/thorough.json +1 -1
- package/dist/assets/prompts/consolidate-system.md +5 -5
- package/dist/assets/prompts/extract-session.md +2 -6
- package/dist/assets/prompts/memory-infer-user.md +2 -3
- package/dist/assets/prompts/reflect-llm-framed-contract.md +11 -0
- package/dist/assets/prompts/reflect-llm-schema-contract.md +3 -0
- package/dist/assets/prompts/reflect-output-repair.md +3 -0
- package/dist/assets/stash-skeleton/README.md +38 -10
- package/dist/assets/stash-skeleton/facts/conventions/assets/agent.md +8 -0
- package/dist/assets/stash-skeleton/facts/conventions/assets/command.md +8 -0
- package/dist/assets/stash-skeleton/facts/conventions/assets/fact.md +14 -1
- package/dist/assets/stash-skeleton/facts/conventions/assets/knowledge.md +13 -1
- package/dist/assets/stash-skeleton/facts/conventions/assets/lesson.md +9 -1
- package/dist/assets/stash-skeleton/facts/conventions/assets/memory.md +11 -0
- package/dist/assets/stash-skeleton/facts/conventions/assets/script.md +9 -0
- package/dist/assets/stash-skeleton/facts/conventions/assets/skill.md +9 -0
- package/dist/assets/stash-skeleton/facts/conventions/assets/workflow.md +8 -0
- package/dist/assets/stash-skeleton/facts/conventions/backlinks.md +100 -0
- package/dist/assets/stash-skeleton/facts/conventions/domains.md +64 -0
- package/dist/assets/stash-skeleton/facts/conventions/organization.md +136 -0
- package/dist/assets/tasks/core/extract.yml +3 -2
- package/dist/assets/tasks/core/improve.yml +2 -1
- package/dist/assets/tasks/core/index-refresh.yml +1 -0
- package/dist/assets/tasks/core/sync.yml +1 -0
- package/dist/assets/tasks/core/version-check.yml +2 -1
- package/dist/assets/tasks/improve/akm-graph-refresh-weekly.yml +5 -0
- package/dist/assets/tasks/improve/akm-improve-catchup.yml +8 -0
- package/dist/assets/tasks/improve/akm-improve-consolidate.yml +5 -0
- package/dist/assets/tasks/improve/akm-improve-frequent.yml +5 -0
- package/dist/assets/tasks/improve/akm-improve-nightly.yml +5 -0
- package/dist/assets/templates/html/health.html +5 -4
- package/dist/assets/workflows/workflow-template.md +31 -15
- package/dist/cli/invocation.js +279 -0
- package/dist/cli/parse-args.js +5 -90
- package/dist/cli/retired-commands.js +78 -0
- package/dist/cli/shared.js +158 -48
- package/dist/cli-node.mjs +2 -1
- package/dist/cli.js +747 -293
- package/dist/commands/agent/agent-dispatch.js +19 -18
- package/dist/commands/agent/agent-support.js +0 -24
- package/dist/commands/agent/contribute-cli.js +43 -97
- package/dist/commands/completions.js +80 -23
- package/dist/commands/config-cli.js +44 -281
- package/dist/commands/env/env-binding.js +13 -9
- package/dist/commands/env/env-cli.js +76 -159
- package/dist/commands/env/env.js +12 -163
- package/dist/commands/env/marker-path.js +6 -0
- package/dist/commands/env/secret-cli.js +45 -61
- package/dist/commands/env/secret.js +32 -62
- package/dist/commands/feedback-cli.js +179 -85
- package/dist/commands/health/accept-rate.js +58 -0
- package/dist/commands/health/advisories.js +7 -8
- package/dist/commands/health/checks.js +279 -94
- package/dist/commands/health/html-report.js +197 -578
- package/dist/commands/health/improve-metrics.js +277 -246
- package/dist/commands/health/llm-usage.js +19 -19
- package/dist/commands/health/md-report.js +16 -7
- package/dist/commands/health/metrics.js +67 -32
- package/dist/commands/health/renderers.js +47 -0
- package/dist/commands/health/report-view-model.js +508 -0
- package/dist/commands/health/stash-exposure.js +1 -1
- package/dist/commands/health/surfaces.js +16 -56
- package/dist/commands/health/task-runs.js +3 -67
- package/dist/{migrate-storage-node.mjs → commands/health/types-checks.js} +1 -5
- package/dist/commands/health/types-improve.js +29 -0
- package/dist/{output/text/save.js → commands/health/types-metrics.js} +1 -2
- package/dist/commands/health/types-result.js +7 -0
- package/dist/commands/health/types-runs.js +4 -0
- package/dist/commands/health/types-session-log.js +4 -0
- package/dist/commands/health/types-windows.js +4 -0
- package/dist/commands/health/types.js +26 -21
- package/dist/commands/health/windows.js +2 -3
- package/dist/commands/health.js +296 -167
- package/dist/commands/improve/anti-collapse.js +5 -5
- package/dist/commands/improve/autonomy-gate.js +68 -0
- package/dist/commands/improve/collapse-detector.js +65 -52
- package/dist/commands/improve/consolidate/chunking.js +9 -7
- package/dist/commands/improve/consolidate/eligibility.js +1 -23
- package/dist/commands/improve/consolidate/merge.js +4 -0
- package/dist/commands/improve/consolidate.js +454 -1354
- package/dist/commands/improve/content-hash.js +39 -0
- package/dist/commands/improve/distill/content-repair.js +4 -10
- package/dist/commands/improve/distill/promote-memory.js +89 -64
- package/dist/commands/improve/distill/quality-gate.js +118 -42
- package/dist/commands/improve/distill-guards.js +1 -1
- package/dist/commands/improve/distill-promotion-policy.js +33 -888
- package/dist/commands/improve/distill.js +607 -363
- package/dist/commands/improve/eligibility.js +165 -79
- package/dist/commands/improve/extract-cli.js +35 -126
- package/dist/commands/improve/extract-prompt.js +6 -35
- package/dist/commands/improve/extract.js +640 -391
- package/dist/commands/improve/feedback-valence.js +2 -12
- package/dist/commands/improve/improve-cli.js +134 -135
- package/dist/commands/improve/improve-result-file.js +30 -50
- package/dist/commands/improve/improve-run-types.js +4 -0
- package/dist/commands/improve/improve-strategies.js +135 -0
- package/dist/commands/improve/improve.js +904 -701
- package/dist/commands/improve/locks.js +64 -111
- package/dist/commands/improve/loop-stages.js +1110 -923
- package/dist/commands/improve/memory/derived-ref.js +124 -0
- package/dist/commands/improve/memory/memory-belief.js +79 -7
- package/dist/commands/improve/memory/memory-contradiction-detect.js +49 -52
- package/dist/commands/improve/memory/memory-improve.js +25 -37
- package/dist/commands/improve/outcome-loop.js +25 -88
- package/dist/commands/improve/preparation.js +1034 -813
- package/dist/commands/improve/proactive-maintenance.js +34 -9
- package/dist/commands/improve/proposal-envelope.js +31 -0
- package/dist/commands/improve/reflect.js +983 -794
- package/dist/commands/improve/run-context.js +119 -0
- package/dist/commands/improve/salience.js +24 -127
- package/dist/commands/improve/session-asset.js +7 -3
- package/dist/commands/improve/shared.js +14 -34
- package/dist/commands/improve/source-identity.js +28 -0
- package/dist/commands/improve/triage.js +20 -17
- package/dist/commands/lint/base-linter.js +340 -313
- package/dist/commands/lint/env-key-rules.js +31 -47
- package/dist/commands/lint/index.js +185 -30
- package/dist/commands/{events.js → log.js} +28 -38
- package/dist/commands/migrate-cli.js +54 -0
- package/dist/commands/migration-tool.js +55 -0
- package/dist/commands/observability-cli.js +70 -208
- package/dist/commands/proposal/diff-format.js +50 -0
- package/dist/commands/proposal/drain-policies.js +0 -6
- package/dist/commands/proposal/drain.js +91 -40
- package/dist/commands/proposal/proposal-cli.js +134 -132
- package/dist/commands/proposal/proposal-types.js +56 -0
- package/dist/commands/proposal/proposal.js +83 -65
- package/dist/commands/proposal/propose-cli.js +88 -0
- package/dist/commands/proposal/propose.js +105 -88
- package/dist/commands/proposal/repository.js +1303 -278
- package/dist/commands/proposal/validators/proposal-quality-validators.js +16 -6
- package/dist/commands/proposal/validators/proposal-validators.js +61 -12
- package/dist/commands/proposal/validators/proposals.js +6 -8
- package/dist/commands/read/curate.js +78 -73
- package/dist/commands/read/knowledge.js +510 -13
- package/dist/commands/read/registry-search.js +2 -2
- package/dist/commands/read/remember-cli.js +84 -15
- package/dist/commands/read/search-cli.js +203 -96
- package/dist/commands/read/search.js +126 -94
- package/dist/commands/read/show.js +226 -250
- package/dist/commands/registry-cli.js +34 -60
- package/dist/commands/remember.js +18 -57
- package/dist/commands/sources/add-cli.js +104 -49
- package/dist/commands/sources/bundle-cli.js +166 -0
- package/dist/commands/sources/bundle-config-ops.js +63 -0
- package/dist/commands/sources/info.js +27 -15
- package/dist/commands/sources/init.js +30 -40
- package/dist/commands/sources/installed-stashes.js +469 -172
- package/dist/commands/sources/schema-repair.js +10 -9
- package/dist/commands/sources/self-update.js +182 -121
- package/dist/commands/sources/source-add.js +169 -178
- package/dist/commands/sources/source-clone.js +144 -41
- package/dist/commands/sources/source-manage.js +94 -59
- package/dist/commands/sources/sources-cli.js +64 -205
- package/dist/commands/sources/stash-cli.js +91 -54
- package/dist/commands/sources/stash-skeleton.js +1 -1
- package/dist/commands/tasks/tasks-cli.js +106 -104
- package/dist/commands/tasks/tasks.js +445 -262
- package/dist/commands/workflow-cli.js +75 -228
- package/dist/core/action-contributors.js +1 -1
- package/dist/core/activation-policy.js +49 -0
- package/dist/core/adapter/adapters/agent-skills-adapter.js +181 -0
- package/dist/core/adapter/adapters/akm-adapter.js +528 -0
- package/dist/core/adapter/adapters/akm-lint.js +392 -0
- package/dist/core/adapter/adapters/akm-metadata.js +387 -0
- package/dist/core/adapter/adapters/akm-task-adapter.js +149 -0
- package/dist/core/adapter/adapters/akm-workflow-adapter.js +180 -0
- package/dist/core/adapter/adapters/claude-adapter.js +61 -0
- package/dist/core/adapter/adapters/dotenv-adapter.js +187 -0
- package/dist/core/adapter/adapters/generic-files-adapter.js +119 -0
- package/dist/core/adapter/adapters/index.js +80 -0
- package/dist/core/adapter/adapters/llm-wiki-adapter.js +419 -0
- package/dist/core/adapter/adapters/okf-adapter.js +391 -0
- package/dist/core/adapter/adapters/opencode-adapter.js +68 -0
- package/dist/core/adapter/adapters/shared.js +286 -0
- package/dist/core/adapter/adapters/tool-dir-shared.js +217 -0
- package/dist/core/adapter/adapters/website-snapshot-adapter.js +155 -0
- package/dist/core/adapter/bundle-adapter.js +4 -0
- package/dist/core/adapter/detect-adapter.js +17 -0
- package/dist/core/adapter/recognize-match.js +44 -0
- package/dist/core/adapter/registry.js +56 -0
- package/dist/core/adapter/types.js +4 -0
- package/dist/core/asset/akm-markdown.js +30 -0
- package/dist/core/asset/asset-placement.js +243 -0
- package/dist/core/asset/asset-ref.js +110 -79
- package/dist/core/asset/asset-serialize.js +20 -0
- package/dist/core/asset/frontmatter.js +28 -12
- package/dist/core/asset/markdown.js +40 -51
- package/dist/core/asset/resolve-ref.js +274 -0
- package/dist/core/asset/stash-meta.js +2 -2
- package/dist/core/bundle-id.js +51 -0
- package/dist/core/common.js +281 -86
- package/dist/core/config/config-io.js +42 -128
- package/dist/core/config/config-schema.js +233 -855
- package/dist/core/config/config-sources.js +162 -39
- package/dist/core/config/config-types.js +16 -11
- package/dist/core/config/config-version.js +29 -0
- package/dist/core/config/config-walker.js +126 -37
- package/dist/core/config/config.js +154 -331
- package/dist/core/config/deep-merge.js +41 -0
- package/dist/core/config/engine-semantics.js +28 -0
- package/dist/core/config/experimental.js +21 -0
- package/dist/core/config/schema/embedding.js +38 -0
- package/dist/core/config/schema/engines.js +116 -0
- package/dist/core/config/schema/experimental.js +47 -0
- package/dist/core/config/schema/feedback.js +31 -0
- package/dist/core/config/schema/improve-processes.js +389 -0
- package/dist/core/config/schema/improve.js +94 -0
- package/dist/core/config/schema/index-config.js +176 -0
- package/dist/core/config/schema/output.js +18 -0
- package/dist/core/config/schema/primitives.js +94 -0
- package/dist/core/config/schema/search.js +30 -0
- package/dist/core/config/schema/setup.js +18 -0
- package/dist/core/config/schema/sources-bundles.js +169 -0
- package/dist/core/config/schema/workflow.js +29 -0
- package/dist/core/env-secret-ref.js +155 -20
- package/dist/core/errors.js +17 -15
- package/dist/core/events-types.js +4 -0
- package/dist/core/events.js +46 -128
- package/dist/core/extra-params.js +62 -0
- package/dist/core/file-change.js +17 -0
- package/dist/core/file-lock.js +202 -57
- package/dist/core/fs-txn.js +392 -0
- package/dist/core/git-message.js +59 -0
- package/dist/core/improve-result.js +167 -0
- package/dist/core/lesson-lint.js +1 -17
- package/dist/core/logs-db.js +1 -1
- package/dist/core/maintenance-barrier.js +135 -0
- package/dist/core/migration-operation.js +44 -0
- package/dist/core/mutation-target.js +78 -0
- package/dist/core/paths.js +22 -25
- package/dist/core/platform.js +10 -0
- package/dist/core/recognition-util.js +128 -0
- package/dist/core/redaction.js +392 -0
- package/dist/core/standards/resolve-standards-context.js +36 -65
- package/dist/core/standards/resolve-stash-standards.js +2 -2
- package/dist/core/standards/resolve-type-conventions.js +5 -5
- package/dist/core/state/migrations.js +242 -11
- package/dist/core/state-db.js +98 -10
- package/dist/core/structured.js +1 -1
- package/dist/core/subprocess.js +303 -0
- package/dist/core/text-truncation.js +9 -5
- package/dist/core/time.js +20 -0
- package/dist/core/type-presentation.js +130 -0
- package/dist/core/warn.js +0 -3
- package/dist/core/write-source.js +834 -118
- package/dist/indexer/bundle-identity-guard.js +92 -0
- package/dist/indexer/db/graph-db.js +1 -25
- package/dist/indexer/db/llm-cache.js +1 -1
- package/dist/indexer/ensure-index.js +30 -9
- package/dist/indexer/graph/graph-boost.js +9 -30
- package/dist/indexer/graph/graph-extraction.js +41 -27
- package/dist/indexer/graph/graph-types.js +4 -0
- package/dist/indexer/index-writer-lock.js +93 -49
- package/dist/indexer/index-written-assets.js +100 -53
- package/dist/indexer/indexer.js +746 -329
- package/dist/indexer/init.js +18 -25
- package/dist/indexer/installations.js +142 -0
- package/dist/indexer/passes/dir-staleness.js +18 -10
- package/dist/indexer/passes/memory-inference.js +25 -15
- package/dist/indexer/passes/metadata.js +412 -243
- package/dist/indexer/scan/doc-to-entry.js +160 -0
- package/dist/indexer/scan/drain-dir.js +134 -0
- package/dist/indexer/search/db-search.js +292 -108
- package/dist/indexer/search/fts-query.js +64 -0
- package/dist/indexer/search/ranking-contributors.js +145 -25
- package/dist/indexer/search/ranking-types.js +4 -0
- package/dist/indexer/search/ranking.js +28 -71
- package/dist/indexer/search/search-attribution.js +67 -0
- package/dist/indexer/search/search-fields.js +18 -3
- package/dist/indexer/search/search-hit-enrichers.js +30 -40
- package/dist/indexer/search/search-source.js +157 -111
- package/dist/indexer/search/semantic-status.js +4 -1
- package/dist/indexer/usage/usage-events.js +10 -30
- package/dist/indexer/walk/file-context.js +3 -45
- package/dist/indexer/walk/matchers.js +42 -73
- package/dist/indexer/walk/path-resolver.js +11 -5
- package/dist/indexer/walk/walker.js +42 -14
- package/dist/integrations/agent/builder-shared.js +7 -0
- package/dist/integrations/agent/builders.js +5 -58
- package/dist/integrations/agent/config.js +3 -143
- package/dist/integrations/agent/detect.js +17 -2
- package/dist/integrations/agent/engine-resolution.js +231 -0
- package/dist/integrations/agent/index.js +1 -2
- package/dist/integrations/agent/model-aliases.js +8 -3
- package/dist/integrations/agent/profiles.js +6 -99
- package/dist/integrations/agent/prompts.js +46 -18
- package/dist/integrations/agent/runner-dispatch.js +78 -13
- package/dist/integrations/agent/runner.js +76 -208
- package/dist/integrations/agent/spawn.js +48 -279
- package/dist/integrations/harnesses/aider/agent-builder.js +9 -8
- package/dist/integrations/harnesses/aider/index.js +2 -12
- package/dist/integrations/harnesses/amazonq/agent-builder.js +10 -16
- package/dist/integrations/harnesses/amazonq/index.js +3 -17
- package/dist/integrations/harnesses/claude/agent-builder.js +2 -3
- package/dist/integrations/harnesses/claude/config-import.js +1 -3
- package/dist/integrations/harnesses/claude/index.js +1 -14
- package/dist/integrations/harnesses/claude/session-log.js +27 -75
- package/dist/integrations/harnesses/codex/agent-builder.js +8 -7
- package/dist/integrations/harnesses/codex/index.js +2 -13
- package/dist/integrations/harnesses/copilot/agent-builder.js +9 -9
- package/dist/integrations/harnesses/copilot/index.js +1 -13
- package/dist/integrations/harnesses/gemini/agent-builder.js +8 -9
- package/dist/integrations/harnesses/gemini/index.js +1 -13
- package/dist/integrations/harnesses/ids.js +24 -0
- package/dist/integrations/harnesses/index.js +31 -33
- package/dist/integrations/harnesses/opencode/agent-builder.js +23 -5
- package/dist/integrations/harnesses/opencode/config-import.js +1 -3
- package/dist/integrations/harnesses/opencode/index.js +1 -18
- package/dist/integrations/harnesses/opencode/session-log.js +67 -125
- package/dist/integrations/harnesses/opencode-sdk/harness.js +3 -17
- package/dist/integrations/harnesses/opencode-sdk/sdk-runner.js +274 -191
- package/dist/integrations/harnesses/openhands/agent-builder.js +12 -10
- package/dist/integrations/harnesses/openhands/index.js +2 -12
- package/dist/integrations/harnesses/pi/agent-builder.js +11 -18
- package/dist/integrations/harnesses/pi/index.js +3 -16
- package/dist/integrations/harnesses/shared.js +17 -0
- package/dist/integrations/harnesses/types.js +38 -34
- package/dist/integrations/lockfile.js +211 -24
- package/dist/integrations/session-logs/index.js +24 -40
- package/dist/integrations/session-logs/provider-base.js +113 -0
- package/dist/llm/client.js +182 -110
- package/dist/llm/embedders/deterministic.js +2 -2
- package/dist/llm/embedders/remote.js +21 -9
- package/dist/llm/feature-gate.js +17 -57
- package/dist/llm/graph-extract.js +12 -13
- package/dist/llm/index-passes.js +8 -42
- package/dist/llm/memory-infer.js +144 -1
- package/dist/llm/metadata-enhance.js +45 -30
- package/dist/llm/structured-call.js +16 -8
- package/dist/llm/usage-persist.js +30 -5
- package/dist/llm/usage-telemetry.js +59 -6
- package/dist/output/cli-hints.js +1 -2
- package/dist/output/command-registry.js +27 -0
- package/dist/output/context.js +22 -7
- package/dist/output/format-exempt.js +80 -0
- package/dist/output/generic-render.js +251 -0
- package/dist/output/html-render.js +11 -16
- package/dist/output/render-registry.js +57 -0
- package/dist/output/renderers.js +15 -281
- package/dist/output/shapes/curate.js +10 -1
- package/dist/output/shapes/events.js +12 -7
- package/dist/output/shapes/helpers.js +58 -84
- package/dist/output/shapes/passthrough.js +8 -40
- package/dist/output/shapes/proposal/producer.js +15 -7
- package/dist/output/shapes/registry.js +12 -6
- package/dist/output/shapes.js +0 -9
- package/dist/output/text/{init.js → bundle-create.js} +3 -1
- package/dist/output/text/bundle-show.js +7 -0
- package/dist/output/text/command-format.js +562 -0
- package/dist/output/text/env.js +1 -3
- package/dist/output/text/events.js +8 -7
- package/dist/output/text/helpers.js +15 -1375
- package/dist/output/text/proposal/producer.js +4 -2
- package/dist/output/text/proposal-format.js +202 -0
- package/dist/output/text/registry-commands.js +1 -2
- package/dist/output/text/registry.js +12 -6
- package/dist/output/text/show-directives.js +117 -0
- package/dist/output/text/show-format.js +103 -0
- package/dist/output/text/sync.js +5 -0
- package/dist/output/text/workflow-format.js +332 -0
- package/dist/output/text/workflow.js +1 -2
- package/dist/output/text.js +10 -19
- package/dist/registry/factory.js +4 -6
- package/dist/registry/origin-resolve.js +16 -27
- package/dist/registry/providers/skills-sh.js +3 -3
- package/dist/registry/providers/static-index.js +15 -25
- package/dist/registry/resolve.js +43 -94
- package/dist/registry/semver.js +43 -0
- package/dist/runtime.js +81 -12
- package/dist/scripts/akm-migrate.js +35529 -0
- package/dist/setup/detect.js +5 -7
- package/dist/setup/detected-engines.js +136 -0
- package/dist/setup/engine-config.js +100 -0
- package/dist/setup/registry-stash-loader.js +3 -3
- package/dist/setup/semantic-assets.js +12 -9
- package/dist/setup/setup.js +444 -208
- package/dist/setup/steps/connection-shared.js +120 -0
- package/dist/setup/steps/connection.js +108 -305
- package/dist/setup/steps/platforms.js +13 -12
- package/dist/setup/steps/semantic.js +15 -3
- package/dist/setup/steps/sources.js +21 -15
- package/dist/setup/steps/stashdir.js +6 -4
- package/dist/setup/steps/tasks.js +236 -119
- package/dist/setup/steps.js +3 -2
- package/dist/sources/freshness.js +39 -0
- package/dist/sources/provider-factory.js +11 -17
- package/dist/sources/providers/filesystem.js +2 -3
- package/dist/sources/providers/git-install.js +278 -34
- package/dist/sources/providers/git-provider.js +54 -56
- package/dist/sources/providers/git-stash.js +420 -91
- package/dist/sources/providers/git.js +2 -2
- package/dist/sources/providers/npm.js +16 -19
- package/dist/sources/providers/provider-utils.js +47 -22
- package/dist/sources/providers/sync-from-ref.js +3 -9
- package/dist/sources/providers/website.js +2 -2
- package/dist/sources/resolve.js +11 -10
- package/dist/sources/snapshot-fetchers/types.js +4 -0
- package/dist/sources/{website-ingest.js → snapshot-fetchers/website-ingest.js} +110 -41
- package/dist/storage/database.js +60 -4
- package/dist/storage/engines/sqlite-migrations.js +156 -5
- package/dist/storage/locations.js +1 -2
- package/dist/storage/repositories/canaries-repository.js +1 -1
- package/dist/storage/repositories/events-repository.js +51 -11
- package/dist/storage/repositories/improve-runs-repository.js +6 -32
- package/dist/storage/repositories/index-connection.js +79 -0
- package/dist/storage/repositories/index-db.js +4 -3
- package/dist/storage/repositories/index-entries-repository.js +863 -0
- package/dist/{indexer/db/entry-mapper.js → storage/repositories/index-entry-mapper.js} +19 -2
- package/dist/storage/repositories/index-entry-types.js +4 -0
- package/dist/storage/repositories/index-fts-repository.js +167 -0
- package/dist/storage/repositories/index-llm-cache-repository.js +108 -0
- package/dist/storage/repositories/index-meta-repository.js +49 -0
- package/dist/{indexer/db/schema.js → storage/repositories/index-schema.js} +226 -100
- package/dist/storage/repositories/index-sql.js +12 -0
- package/dist/storage/repositories/index-utility-repository.js +356 -0
- package/dist/storage/repositories/index-vec-repository.js +250 -0
- package/dist/storage/repositories/outcome-repository.js +119 -0
- package/dist/storage/repositories/proposals-repository.js +317 -75
- package/dist/storage/repositories/registry-cache.js +1 -1
- package/dist/storage/repositories/salience-repository.js +172 -0
- package/dist/storage/repositories/task-history-repository.js +110 -3
- package/dist/storage/repositories/workflow-runs-repository.js +68 -35
- package/dist/tasks/backends/cron.js +169 -46
- package/dist/tasks/backends/exec-utils.js +76 -3
- package/dist/tasks/backends/index.js +6 -9
- package/dist/tasks/backends/launchd.js +292 -55
- package/dist/tasks/backends/schtasks.js +557 -70
- package/dist/tasks/backends/types.js +4 -0
- package/dist/tasks/command-executable.js +93 -0
- package/dist/tasks/embedded.js +56 -38
- package/dist/tasks/parser.js +156 -64
- package/dist/tasks/resolve-akm-bin.js +144 -51
- package/dist/tasks/runner.js +377 -209
- package/dist/tasks/schedule.js +108 -19
- package/dist/tasks/scheduler-invocation.js +296 -0
- package/dist/tasks/schema.js +1 -1
- package/dist/tasks/task-id.js +35 -0
- package/dist/tasks/validator.js +30 -16
- package/dist/workflows/authoring/authoring.js +96 -148
- package/dist/workflows/authoring/scope-key.js +1 -1
- package/dist/workflows/cli.js +0 -20
- package/dist/workflows/concurrency-policy.js +15 -0
- package/dist/workflows/exec/brief.js +25 -59
- package/dist/workflows/exec/frozen-judge.js +47 -0
- package/dist/workflows/exec/native-executor.js +157 -94
- package/dist/workflows/exec/report.js +365 -200
- package/dist/workflows/exec/run-workflow.js +46 -40
- package/dist/workflows/exec/scheduler.js +12 -41
- package/dist/workflows/exec/step-work.js +239 -205
- package/dist/workflows/exec/workflow-engine-gate.js +67 -0
- package/dist/workflows/ir/compile.js +141 -283
- package/dist/workflows/ir/freeze.js +233 -0
- package/dist/workflows/ir/plan-hash.js +40 -5
- package/dist/workflows/ir/schema.js +537 -1
- package/dist/workflows/parser.js +878 -306
- package/dist/workflows/program/expressions.js +20 -208
- package/dist/workflows/program/schema.js +7 -10
- package/dist/workflows/renderer.js +99 -121
- package/dist/workflows/resource-limits.js +22 -0
- package/dist/workflows/runtime/checkin.js +1 -1
- package/dist/workflows/runtime/plan-classifier.js +131 -0
- package/dist/workflows/runtime/runs.js +200 -113
- package/dist/workflows/runtime/unit-checkin.js +1 -1
- package/dist/workflows/runtime/unit-phases.js +20 -0
- package/dist/workflows/runtime/workflow-asset-loader.js +235 -97
- package/dist/workflows/schema.js +1 -11
- package/dist/workflows/validate-summary.js +4 -26
- package/dist/workflows/validator.js +52 -30
- package/docs/README.md +42 -78
- package/docs/migration/README.md +8 -0
- package/docs/migration/release-notes/0.6.0.md +1 -1
- package/docs/migration/release-notes/0.7.0.md +9 -8
- package/docs/migration/release-notes/0.9.0.md +158 -14
- package/docs/migration/v0.7-to-v0.8.md +46 -47
- package/docs/migration/v0.8-to-v0.9.md +844 -0
- package/docs/reference/README.md +12 -0
- package/docs/reference/data-and-telemetry.md +333 -0
- package/package.json +21 -17
- package/schemas/akm-asset-envelope.json +93 -0
- package/schemas/akm-config.json +4636 -0
- package/schemas/akm-task.json +87 -0
- package/{dist/schemas → schemas}/akm-workflow.json +127 -82
- package/dist/akm-migrate-storage +0 -38
- package/dist/assets/help/help-accept.md +0 -12
- package/dist/assets/help/help-improve.md +0 -84
- package/dist/assets/help/help-proposals.md +0 -17
- package/dist/assets/help/help-propose.md +0 -17
- package/dist/assets/help/help-reject.md +0 -11
- package/dist/assets/profiles/frequent.json +0 -13
- package/dist/assets/profiles/recombine-only.json +0 -21
- package/dist/assets/profiles/reflect-distill.json +0 -30
- package/dist/assets/profiles/synthesize.json +0 -15
- package/dist/assets/prompts/procedural-system.md +0 -44
- package/dist/assets/prompts/recombine-system.md +0 -40
- package/dist/assets/prompts/staleness-detect-system.md +0 -6
- package/dist/assets/tasks/core/backup.yml +0 -4
- package/dist/assets/tasks/graph-refresh-weekly.yml +0 -10
- package/dist/assets/templates/html/default.html +0 -78
- package/dist/assets/templates/html/vendor/echarts.min.js +0 -45
- package/dist/assets/wiki/index-template.md +0 -12
- package/dist/assets/wiki/ingest-workflow-template.md +0 -83
- package/dist/assets/wiki/log-template.md +0 -8
- package/dist/assets/wiki/schema-template.md +0 -61
- package/dist/cli/config-migrate.js +0 -150
- package/dist/cli/config-validate.js +0 -39
- package/dist/commands/graph/graph-cli.js +0 -124
- package/dist/commands/graph/graph.js +0 -487
- package/dist/commands/improve/calibration.js +0 -161
- package/dist/commands/improve/dedup.js +0 -482
- package/dist/commands/improve/extract-watch.js +0 -140
- package/dist/commands/improve/hot-probation.js +0 -45
- package/dist/commands/improve/improve-auto-accept.js +0 -276
- package/dist/commands/improve/improve-profiles.js +0 -168
- package/dist/commands/improve/procedural.js +0 -398
- package/dist/commands/improve/recombine.js +0 -818
- package/dist/commands/improve/schema-similarity-gate.js +0 -168
- package/dist/commands/lint/agent-linter.js +0 -44
- package/dist/commands/lint/command-linter.js +0 -44
- package/dist/commands/lint/default-linter.js +0 -16
- package/dist/commands/lint/fact-linter.js +0 -39
- package/dist/commands/lint/knowledge-linter.js +0 -16
- package/dist/commands/lint/memory-linter.js +0 -61
- package/dist/commands/lint/registry.js +0 -41
- package/dist/commands/lint/skill-linter.js +0 -45
- package/dist/commands/lint/task-linter.js +0 -50
- package/dist/commands/lint/workflow-linter.js +0 -81
- package/dist/commands/proposal/legacy-import.js +0 -115
- package/dist/commands/sources/history.js +0 -196
- package/dist/commands/tasks/default-tasks.js +0 -186
- package/dist/commands/wiki-cli.js +0 -292
- package/dist/core/asset/asset-registry.js +0 -76
- package/dist/core/asset/asset-spec.js +0 -316
- package/dist/core/config/config-migration.js +0 -602
- package/dist/core/deep-merge.js +0 -38
- package/dist/core/eval/rank-metrics.js +0 -113
- package/dist/core/ripgrep/install.js +0 -163
- package/dist/core/ripgrep/resolve.js +0 -81
- package/dist/indexer/db/db.js +0 -1414
- package/dist/indexer/manifest.js +0 -170
- package/dist/indexer/passes/metadata-contributors.js +0 -31
- package/dist/indexer/usage/unmigrated-vaults-guard.js +0 -94
- package/dist/integrations/harnesses/opencode-sdk/index.js +0 -25
- package/dist/llm/call-ai.js +0 -62
- package/dist/llm/memory-infer-impl.js +0 -138
- package/dist/output/shapes/distill.js +0 -14
- package/dist/output/shapes/history.js +0 -11
- package/dist/output/text/distill.js +0 -6
- package/dist/output/text/enable-disable.js +0 -8
- package/dist/output/text/history.js +0 -6
- package/dist/output/text/wiki.js +0 -16
- package/dist/registry/build-index.js +0 -386
- package/dist/schemas/akm-config.json +0 -14225
- package/dist/scripts/migrate-storage.js +0 -13169
- package/dist/scripts/migrations/import-fs-improve-runs-to-db.js +0 -10169
- package/dist/scripts/migrations/v16-to-v17.js +0 -141
- package/dist/setup/legacy-config.js +0 -106
- package/dist/storage/repositories/consolidation-repository.js +0 -38
- package/dist/storage/repositories/recombine-repository.js +0 -213
- package/dist/wiki/wiki-templates.js +0 -15
- package/dist/wiki/wiki.js +0 -1012
- package/dist/workflows/authoring/workflow-program-template.yaml +0 -31
- package/dist/workflows/db.js +0 -350
- package/dist/workflows/exec/watch.js +0 -116
- package/dist/workflows/program/parser.js +0 -760
- package/dist/workflows/program/project.js +0 -105
- package/docs/data-and-telemetry.md +0 -227
- package/docs/migration/release-notes/0.9.0-beta.60.md +0 -19
- /package/dist/sources/{wiki-fetchers → snapshot-fetchers}/registry.js +0 -0
- /package/dist/sources/{wiki-fetchers → snapshot-fetchers}/youtube.js +0 -0
|
@@ -4,13 +4,11 @@
|
|
|
4
4
|
import { fetchWithRetry, jsonWithByteCap, toErrorMessage } from "../../core/common.js";
|
|
5
5
|
import { asString } from "../../integrations/github.js";
|
|
6
6
|
import { fetchCachedJson } from "../../storage/repositories/registry-cache.js";
|
|
7
|
-
import {
|
|
7
|
+
import { registerRegistryProvider } from "../factory.js";
|
|
8
8
|
import { buildInstallRef } from "../resolve.js";
|
|
9
9
|
// ── Constants ───────────────────────────────────────────────────────────────
|
|
10
10
|
/** Cache TTL in milliseconds (1 hour). */
|
|
11
11
|
const CACHE_TTL_MS = 60 * 60 * 1000;
|
|
12
|
-
/** Maximum age before cache is considered stale but still usable as fallback (7 days). */
|
|
13
|
-
const CACHE_STALE_MS = 7 * 24 * 60 * 60 * 1000;
|
|
14
12
|
// ── Provider class ──────────────────────────────────────────────────────────
|
|
15
13
|
class StaticIndexProvider {
|
|
16
14
|
type = "static-index";
|
|
@@ -20,25 +18,25 @@ class StaticIndexProvider {
|
|
|
20
18
|
}
|
|
21
19
|
async search(options) {
|
|
22
20
|
const warnings = [];
|
|
23
|
-
const
|
|
24
|
-
const hits =
|
|
21
|
+
const bundles = await this.loadBundles(warnings);
|
|
22
|
+
const hits = scoreBundles(bundles, options.query, options.limit);
|
|
25
23
|
let assetHits;
|
|
26
24
|
if (options.includeAssets) {
|
|
27
|
-
const scored = scoreAssets(
|
|
25
|
+
const scored = scoreAssets(bundles, options.query, options.limit);
|
|
28
26
|
if (scored.length > 0)
|
|
29
27
|
assetHits = scored;
|
|
30
28
|
}
|
|
31
29
|
return { hits, assetHits, warnings: warnings.length > 0 ? warnings : undefined };
|
|
32
30
|
}
|
|
33
31
|
// ── Internals ───────────────────────────────────────────────────────────
|
|
34
|
-
async
|
|
35
|
-
const
|
|
32
|
+
async loadBundles(warnings) {
|
|
33
|
+
const bundles = [];
|
|
36
34
|
try {
|
|
37
35
|
const index = await loadIndex(this.config);
|
|
38
36
|
if (index) {
|
|
39
37
|
const regName = this.config.name;
|
|
40
38
|
for (const stash of index.stashes) {
|
|
41
|
-
|
|
39
|
+
bundles.push({ stash, registryName: regName });
|
|
42
40
|
}
|
|
43
41
|
}
|
|
44
42
|
}
|
|
@@ -46,18 +44,18 @@ class StaticIndexProvider {
|
|
|
46
44
|
const label = this.config.name ? `${this.config.name} (${this.config.url})` : this.config.url;
|
|
47
45
|
warnings.push(`Registry ${label}: ${toErrorMessage(err)}`);
|
|
48
46
|
}
|
|
49
|
-
return
|
|
47
|
+
return bundles;
|
|
50
48
|
}
|
|
51
49
|
}
|
|
52
50
|
// ── Self-register ───────────────────────────────────────────────────────────
|
|
53
|
-
|
|
51
|
+
registerRegistryProvider("static-index", (config) => new StaticIndexProvider(config));
|
|
54
52
|
// ── Index loading with cache ────────────────────────────────────────────────
|
|
55
53
|
async function loadIndex(entry) {
|
|
56
54
|
return fetchCachedJson({
|
|
57
55
|
cacheKey: entry.url,
|
|
58
56
|
ttlMs: CACHE_TTL_MS,
|
|
59
57
|
// Both the fresh hit and the stale fallback parse identically; a corrupt
|
|
60
|
-
// cache row lets JSON.parse throw out of the load
|
|
58
|
+
// cache row lets JSON.parse throw out of the load.
|
|
61
59
|
parseCache: (json) => parseRegistryIndex(JSON.parse(json)) ?? undefined,
|
|
62
60
|
fetchFresh: async () => {
|
|
63
61
|
const response = await fetchWithRetry(entry.url, undefined, { timeout: 10_000 });
|
|
@@ -77,12 +75,6 @@ async function loadIndex(entry) {
|
|
|
77
75
|
},
|
|
78
76
|
});
|
|
79
77
|
}
|
|
80
|
-
export function isCacheExpired(mtimeMs) {
|
|
81
|
-
return Date.now() - mtimeMs > CACHE_TTL_MS;
|
|
82
|
-
}
|
|
83
|
-
export function isCacheStale(mtimeMs) {
|
|
84
|
-
return Date.now() - mtimeMs > CACHE_STALE_MS;
|
|
85
|
-
}
|
|
86
78
|
// ── Index parsing (exported for reuse) ──────────────────────────────────────
|
|
87
79
|
export function parseRegistryIndex(data) {
|
|
88
80
|
if (typeof data !== "object" || data === null || Array.isArray(data))
|
|
@@ -97,13 +89,13 @@ export function parseRegistryIndex(data) {
|
|
|
97
89
|
if (!Array.isArray(obj.stashes))
|
|
98
90
|
return null;
|
|
99
91
|
const stashes = obj.stashes.flatMap((raw) => {
|
|
100
|
-
const stash =
|
|
92
|
+
const stash = parseBundleEntry(raw);
|
|
101
93
|
return stash ? [stash] : [];
|
|
102
94
|
});
|
|
103
95
|
return { version: obj.version, updatedAt: obj.updatedAt, stashes };
|
|
104
96
|
}
|
|
105
97
|
// ── Stash entry parsing ───────────────────────────────────────────────────────
|
|
106
|
-
function
|
|
98
|
+
function parseBundleEntry(raw) {
|
|
107
99
|
if (typeof raw !== "object" || raw === null || Array.isArray(raw))
|
|
108
100
|
return null;
|
|
109
101
|
const obj = raw;
|
|
@@ -113,9 +105,7 @@ function parseStashEntry(raw) {
|
|
|
113
105
|
const source = asSource(obj.source);
|
|
114
106
|
if (!id || !name || !ref || !source)
|
|
115
107
|
return null;
|
|
116
|
-
//
|
|
117
|
-
// containing a `curated` key parses normally; the key is silently ignored
|
|
118
|
-
// (v1 spec §4.2, docs/migration/v1.md).
|
|
108
|
+
// Some published indexes include `curated`; it is intentionally ignored.
|
|
119
109
|
return {
|
|
120
110
|
id,
|
|
121
111
|
name,
|
|
@@ -132,7 +122,7 @@ function parseStashEntry(raw) {
|
|
|
132
122
|
};
|
|
133
123
|
}
|
|
134
124
|
// ── Scoring ─────────────────────────────────────────────────────────────────
|
|
135
|
-
function
|
|
125
|
+
function scoreBundles(stashes, query, limit) {
|
|
136
126
|
const tokens = query.toLowerCase().split(/\s+/).filter(Boolean);
|
|
137
127
|
const scored = [];
|
|
138
128
|
for (const { stash, registryName } of stashes) {
|
|
@@ -247,7 +237,7 @@ function scoreAssets(stashes, query, limit) {
|
|
|
247
237
|
estimatedTokens: asset.estimatedTokens,
|
|
248
238
|
stash: { id: stash.id, name: stash.name },
|
|
249
239
|
registryName,
|
|
250
|
-
action: `akm add ${installRef}`,
|
|
240
|
+
action: `akm bundle add ${installRef}`,
|
|
251
241
|
score: Math.round(score * 1000) / 1000,
|
|
252
242
|
},
|
|
253
243
|
score,
|
package/dist/registry/resolve.js
CHANGED
|
@@ -9,6 +9,7 @@ import { fileURLToPath, pathToFileURL } from "node:url";
|
|
|
9
9
|
import { fetchWithRetry, jsonWithByteCap } from "../core/common.js";
|
|
10
10
|
import { NotFoundError, UsageError } from "../core/errors.js";
|
|
11
11
|
import { asRecord, asString, GITHUB_API_BASE, githubHeaders } from "../integrations/github.js";
|
|
12
|
+
import { isExactSemver, isSemverRange, maxSatisfying } from "./semver.js";
|
|
12
13
|
/**
|
|
13
14
|
* Validate that a URL is safe to pass to git.
|
|
14
15
|
* Allowlists https:, http:, ssh:, git: schemes and git@ SSH shorthand.
|
|
@@ -108,13 +109,13 @@ function detectRegistrySearchId(ref) {
|
|
|
108
109
|
const suggestedRef = segments.length >= 2 ? `github:${segments[0]}/${segments[1]}` : undefined;
|
|
109
110
|
const lines = [
|
|
110
111
|
`"${ref}" looks like a registry search result ID, not an installable ref.`,
|
|
111
|
-
`The "${prefix}:" prefix is a registry identifier and cannot be passed to \`akm add\`.`,
|
|
112
|
+
`The "${prefix}:" prefix is a registry identifier and cannot be passed to \`akm bundle add\`.`,
|
|
112
113
|
"",
|
|
113
114
|
];
|
|
114
115
|
if (suggestedRef) {
|
|
115
|
-
lines.push(`Try installing the source repository directly:`, ` akm add ${suggestedRef}`, "");
|
|
116
|
+
lines.push(`Try installing the source repository directly:`, ` akm bundle add ${suggestedRef}`, "");
|
|
116
117
|
}
|
|
117
|
-
lines.push("Or search for the installable ref:", ` akm search "${segments.length > 2 ? segments[segments.length - 1] : rest}" --
|
|
118
|
+
lines.push("Or search for the installable ref:", ` akm search "${segments.length > 2 ? segments[segments.length - 1] : rest}" --from registry`, "Then install using the installRef value from the result:", " akm bundle add github:owner/repo", " akm bundle add npm:package-name");
|
|
118
119
|
return lines.join("\n");
|
|
119
120
|
}
|
|
120
121
|
export async function resolveRegistryArtifact(parsed) {
|
|
@@ -250,6 +251,16 @@ function isPathLikeRef(ref) {
|
|
|
250
251
|
if (ref.startsWith("./") || ref.startsWith("../") || ref.startsWith(".\\") || ref.startsWith("..\\")) {
|
|
251
252
|
return true;
|
|
252
253
|
}
|
|
254
|
+
// R-007: a bare `owner/repo` (or `owner/repo#ref`) shorthand is ambiguous
|
|
255
|
+
// with a relative directory of the same shape, and is never an EXPLICIT
|
|
256
|
+
// local path the way `./owner/repo` is. Treating it as non-path here means
|
|
257
|
+
// `tryParseLocalRef` silently returns `undefined` (rather than throwing
|
|
258
|
+
// NotFoundError) when no such directory exists on disk, letting
|
|
259
|
+
// `parseRegistryRef`'s GitHub-shorthand fallback run instead. A directory
|
|
260
|
+
// that DOES exist with this shape is unaffected — `tryParseLocalRef`
|
|
261
|
+
// resolves it before the missing-path distinction ever matters.
|
|
262
|
+
if (looksLikeGithubOwnerRepo(ref))
|
|
263
|
+
return false;
|
|
253
264
|
return ref.includes("/") || ref.includes("\\");
|
|
254
265
|
}
|
|
255
266
|
/** Default public npm registry host. */
|
|
@@ -317,9 +328,37 @@ export function validateNpmTarballUrl(tarballUrl, packageRef) {
|
|
|
317
328
|
throw new UntrustedNpmTarballError(`npm package ${packageRef} returned a tarball URL on untrusted host "${host}" (allowed: ${allowed}).`);
|
|
318
329
|
}
|
|
319
330
|
}
|
|
331
|
+
/**
|
|
332
|
+
* Resolve the npm registry base URL used to fetch package METADATA.
|
|
333
|
+
*
|
|
334
|
+
* R-035: `AKM_NPM_REGISTRY` previously only widened the trusted-tarball-host
|
|
335
|
+
* allowlist (see {@link trustedNpmTarballHosts}) while the metadata endpoint
|
|
336
|
+
* stayed hardcoded to the public registry — so an operator-configured mirror
|
|
337
|
+
* was never actually consulted, making the `UntrustedNpmTarballError.hint()`
|
|
338
|
+
* text below false. Honoring the override here for metadata too makes the
|
|
339
|
+
* hint true: installs really do resolve entirely against the configured
|
|
340
|
+
* mirror when it is set, mirroring how a private npm registry replaces the
|
|
341
|
+
* default wholesale (like npm's own `--registry` flag) rather than being
|
|
342
|
+
* merged with it.
|
|
343
|
+
*/
|
|
344
|
+
function npmMetadataRegistryBase() {
|
|
345
|
+
const override = process.env.AKM_NPM_REGISTRY?.trim();
|
|
346
|
+
if (override) {
|
|
347
|
+
try {
|
|
348
|
+
const url = new URL(override);
|
|
349
|
+
const base = `${url.origin}${url.pathname === "/" ? "" : url.pathname}`;
|
|
350
|
+
return base.replace(/\/+$/, "");
|
|
351
|
+
}
|
|
352
|
+
catch {
|
|
353
|
+
// Ignore unparseable overrides; fall back to the public registry.
|
|
354
|
+
}
|
|
355
|
+
}
|
|
356
|
+
return `https://${DEFAULT_NPM_REGISTRY_HOST}`;
|
|
357
|
+
}
|
|
320
358
|
async function resolveNpmArtifact(parsed) {
|
|
321
359
|
const encodedName = encodeURIComponent(parsed.packageName);
|
|
322
|
-
const
|
|
360
|
+
const registryBase = npmMetadataRegistryBase();
|
|
361
|
+
const metadata = await fetchJson(`${registryBase}/${encodedName}`);
|
|
323
362
|
const versions = asRecord(metadata.versions);
|
|
324
363
|
const distTags = asRecord(metadata["dist-tags"]);
|
|
325
364
|
const requested = parsed.requestedVersionOrTag;
|
|
@@ -560,96 +599,6 @@ function readGitValue(repoRoot, ...args) {
|
|
|
560
599
|
const value = result.stdout.trim();
|
|
561
600
|
return value || undefined;
|
|
562
601
|
}
|
|
563
|
-
function parseSemver(version) {
|
|
564
|
-
const match = version.match(/^(\d+)\.(\d+)\.(\d+)(?:-(.+))?$/);
|
|
565
|
-
if (!match)
|
|
566
|
-
return undefined;
|
|
567
|
-
return {
|
|
568
|
-
major: parseInt(match[1], 10),
|
|
569
|
-
minor: parseInt(match[2], 10),
|
|
570
|
-
patch: parseInt(match[3], 10),
|
|
571
|
-
prerelease: match[4],
|
|
572
|
-
};
|
|
573
|
-
}
|
|
574
|
-
function isExactSemver(version) {
|
|
575
|
-
return /^\d+\.\d+\.\d+(?:-[a-zA-Z0-9.+-]+)?$/.test(version);
|
|
576
|
-
}
|
|
577
|
-
function isSemverRange(input) {
|
|
578
|
-
return /^[~^>=<*]/.test(input) || /^\d+\.(\d+|\*)/.test(input);
|
|
579
|
-
}
|
|
580
|
-
function compareSemver(a, b) {
|
|
581
|
-
if (a.major !== b.major)
|
|
582
|
-
return a.major - b.major;
|
|
583
|
-
if (a.minor !== b.minor)
|
|
584
|
-
return a.minor - b.minor;
|
|
585
|
-
if (a.patch !== b.patch)
|
|
586
|
-
return a.patch - b.patch;
|
|
587
|
-
// Versions with prerelease are lower than release
|
|
588
|
-
if (a.prerelease && !b.prerelease)
|
|
589
|
-
return -1;
|
|
590
|
-
if (!a.prerelease && b.prerelease)
|
|
591
|
-
return 1;
|
|
592
|
-
return 0;
|
|
593
|
-
}
|
|
594
|
-
function semverGte(a, b) {
|
|
595
|
-
return compareSemver(a, b) >= 0;
|
|
596
|
-
}
|
|
597
|
-
function satisfiesRange(version, range) {
|
|
598
|
-
// Skip pre-release versions unless range specifically mentions one
|
|
599
|
-
if (version.prerelease && !range.includes("-"))
|
|
600
|
-
return false;
|
|
601
|
-
// ^1.2.3 — compatible with version: same major, >= minor.patch
|
|
602
|
-
const caretMatch = range.match(/^\^(\d+)\.(\d+)\.(\d+)(?:-(.+))?$/);
|
|
603
|
-
if (caretMatch) {
|
|
604
|
-
const rMajor = parseInt(caretMatch[1], 10);
|
|
605
|
-
const rMinor = parseInt(caretMatch[2], 10);
|
|
606
|
-
const rPatch = parseInt(caretMatch[3], 10);
|
|
607
|
-
if (version.major !== rMajor)
|
|
608
|
-
return false;
|
|
609
|
-
// ^0.x has special behavior: ^0.2.3 means >=0.2.3 <0.3.0
|
|
610
|
-
if (rMajor === 0) {
|
|
611
|
-
if (version.minor !== rMinor)
|
|
612
|
-
return false;
|
|
613
|
-
return version.patch >= rPatch;
|
|
614
|
-
}
|
|
615
|
-
return semverGte(version, { major: rMajor, minor: rMinor, patch: rPatch });
|
|
616
|
-
}
|
|
617
|
-
// ~1.2.3 — same major.minor, patch >= specified
|
|
618
|
-
const tildeMatch = range.match(/^~(\d+)\.(\d+)\.(\d+)(?:-(.+))?$/);
|
|
619
|
-
if (tildeMatch) {
|
|
620
|
-
const rMajor = parseInt(tildeMatch[1], 10);
|
|
621
|
-
const rMinor = parseInt(tildeMatch[2], 10);
|
|
622
|
-
const rPatch = parseInt(tildeMatch[3], 10);
|
|
623
|
-
return version.major === rMajor && version.minor === rMinor && version.patch >= rPatch;
|
|
624
|
-
}
|
|
625
|
-
// >=1.2.3
|
|
626
|
-
const gteMatch = range.match(/^>=(\d+)\.(\d+)\.(\d+)(?:-(.+))?$/);
|
|
627
|
-
if (gteMatch) {
|
|
628
|
-
const rMajor = parseInt(gteMatch[1], 10);
|
|
629
|
-
const rMinor = parseInt(gteMatch[2], 10);
|
|
630
|
-
const rPatch = parseInt(gteMatch[3], 10);
|
|
631
|
-
return semverGte(version, { major: rMajor, minor: rMinor, patch: rPatch });
|
|
632
|
-
}
|
|
633
|
-
// * or latest
|
|
634
|
-
if (range === "*" || range === "latest")
|
|
635
|
-
return true;
|
|
636
|
-
return false;
|
|
637
|
-
}
|
|
638
|
-
export function maxSatisfying(versions, range) {
|
|
639
|
-
const candidates = [];
|
|
640
|
-
for (const v of versions) {
|
|
641
|
-
const parsed = parseSemver(v);
|
|
642
|
-
if (!parsed)
|
|
643
|
-
continue;
|
|
644
|
-
if (satisfiesRange(parsed, range)) {
|
|
645
|
-
candidates.push({ version: v, parsed });
|
|
646
|
-
}
|
|
647
|
-
}
|
|
648
|
-
if (candidates.length === 0)
|
|
649
|
-
return undefined;
|
|
650
|
-
candidates.sort((a, b) => compareSemver(b.parsed, a.parsed));
|
|
651
|
-
return candidates[0].version;
|
|
652
|
-
}
|
|
653
602
|
// Cap JSON responses at 10 MB — npm package manifests and GitHub API
|
|
654
603
|
// responses are typically a few KB; a compromised registry streaming
|
|
655
604
|
// tens of MB of JSON is a DoS surface, not a feature.
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
// This Source Code Form is subject to the terms of the Mozilla Public
|
|
2
|
+
// License, v. 2.0. If a copy of the MPL was not distributed with this
|
|
3
|
+
// file, You can obtain one at https://mozilla.org/MPL/2.0/.
|
|
4
|
+
/**
|
|
5
|
+
* Registry semver engine (§4.6 dedup, WI-9.3).
|
|
6
|
+
*
|
|
7
|
+
* R-068 #3: this used to be a hand-rolled parse/compare/range implementation
|
|
8
|
+
* (a verbatim move from `./resolve.ts`) that only understood exact versions,
|
|
9
|
+
* `^x.y.z`, `~x.y.z`, `>=x.y.z`, and `*`/`latest`. Every OTHER valid npm range
|
|
10
|
+
* form was silently REJECTED by `satisfiesRange` even though the looser
|
|
11
|
+
* `isSemverRange` classifier correctly recognized it as a range: `1.2.x`,
|
|
12
|
+
* `>1.0.0`, `<2.0.0`, compound ranges (`>=1.0.0 <2.0.0`), partial carets
|
|
13
|
+
* (`^1.2`), OR-ranges (`a || b`), hyphen ranges (`1.2.3 - 2.3.4`), and plain
|
|
14
|
+
* exact versions used as a range. A silently-empty `maxSatisfying` result for
|
|
15
|
+
* a genuinely satisfiable range meant `akm bundle add pkg@<range>` could fail to
|
|
16
|
+
* resolve a real, installable version.
|
|
17
|
+
*
|
|
18
|
+
* `semver` (the npm package) is already a runtime dependency
|
|
19
|
+
* (`package.json`) — it was simply never imported from `src/`. This module
|
|
20
|
+
* now delegates to it directly instead of re-deriving a subset of its
|
|
21
|
+
* behavior, so every range form `semver` itself understands is supported.
|
|
22
|
+
*
|
|
23
|
+
* NOTE: `src/runtime.ts` has its own `semverOrder` with a DIFFERENT
|
|
24
|
+
* contract (engine-version ordering, not range satisfaction) — the two are
|
|
25
|
+
* intentionally not unified.
|
|
26
|
+
*/
|
|
27
|
+
import semver from "semver";
|
|
28
|
+
/** True when `version` is an exact, fully-specified semver (not a range, wildcard, or partial version). */
|
|
29
|
+
export function isExactSemver(version) {
|
|
30
|
+
return semver.valid(version) !== null;
|
|
31
|
+
}
|
|
32
|
+
/**
|
|
33
|
+
* True when `input` is a semver RANGE expression `maxSatisfying` can
|
|
34
|
+
* evaluate. Deliberately false for npm dist-tag conventions like `"latest"`
|
|
35
|
+
* — those are resolved via `dist-tags` lookup, not range satisfaction.
|
|
36
|
+
*/
|
|
37
|
+
export function isSemverRange(input) {
|
|
38
|
+
return semver.validRange(input) !== null;
|
|
39
|
+
}
|
|
40
|
+
/** Highest version in `versions` that satisfies `range`, or `undefined` if none match. */
|
|
41
|
+
export function maxSatisfying(versions, range) {
|
|
42
|
+
return semver.maxSatisfying(versions, range) ?? undefined;
|
|
43
|
+
}
|
package/dist/runtime.js
CHANGED
|
@@ -28,6 +28,7 @@ import path from "node:path";
|
|
|
28
28
|
import { Readable } from "node:stream";
|
|
29
29
|
import { pipeline } from "node:stream/promises";
|
|
30
30
|
import { fileURLToPath } from "node:url";
|
|
31
|
+
import { ResponseTooLargeError, readChunkWithDeadline } from "./core/common.js";
|
|
31
32
|
/** True when running under the Bun runtime. Computed once at module load. */
|
|
32
33
|
const isBun = !!process.versions?.bun;
|
|
33
34
|
/** A CommonJS-style require usable from this ESM module on both runtimes. */
|
|
@@ -136,22 +137,77 @@ function stdinIterator() {
|
|
|
136
137
|
}
|
|
137
138
|
// ── File write ──────────────────────────────────────────────────────────────
|
|
138
139
|
/**
|
|
139
|
-
*
|
|
140
|
-
* which natively streams a `Response` to disk; on Node pipes the response body
|
|
141
|
-
* through `stream/promises.pipeline` so the archive is never fully buffered.
|
|
140
|
+
* Defensive ceiling on a streamed-to-disk download (1 GiB).
|
|
142
141
|
*/
|
|
143
|
-
export
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
142
|
+
export const MAX_STREAMED_DOWNLOAD_BYTES = 1024 * 1024 * 1024;
|
|
143
|
+
/** Default overall wall-clock budget for streaming a download body (5 min). */
|
|
144
|
+
export const STREAMED_DOWNLOAD_BODY_TIMEOUT_MS = 5 * 60_000;
|
|
145
|
+
function writeStreamChunk(out, chunk) {
|
|
146
|
+
return new Promise((resolve, reject) => {
|
|
147
|
+
out.write(chunk, (err) => (err ? reject(err) : resolve()));
|
|
148
|
+
});
|
|
149
|
+
}
|
|
150
|
+
function endWriteStream(out) {
|
|
151
|
+
return new Promise((resolve, reject) => {
|
|
152
|
+
out.once("error", reject);
|
|
153
|
+
out.end(() => resolve());
|
|
154
|
+
});
|
|
155
|
+
}
|
|
156
|
+
/**
|
|
157
|
+
* Stream a `Response` body to `filePath` enforcing an explicit max-bytes cap
|
|
158
|
+
* and an overall body-read deadline.
|
|
159
|
+
*
|
|
160
|
+
* Refuses before reading when `Content-Length` exceeds the cap; otherwise
|
|
161
|
+
* streams chunk-by-chunk, aborting with {@link ResponseTooLargeError} the
|
|
162
|
+
* instant BYTES WRITTEN exceed the cap, or {@link BodyReadTimeoutError} when the
|
|
163
|
+
* body-read deadline passes. Uses the same runtime-agnostic reader loop on Bun
|
|
164
|
+
* and Node (correctness over the native `Bun.write` fast path, which offers no
|
|
165
|
+
* per-byte hook). On any failure the partial file is discarded and the stream
|
|
166
|
+
* cancelled.
|
|
167
|
+
*/
|
|
168
|
+
export async function writeResponseToFileCapped(filePath, res, options) {
|
|
169
|
+
const maxBytes = options?.maxBytes ?? MAX_STREAMED_DOWNLOAD_BYTES;
|
|
170
|
+
const bodyTimeoutMs = options?.bodyTimeoutMs ?? STREAMED_DOWNLOAD_BODY_TIMEOUT_MS;
|
|
171
|
+
const url = res.url || filePath;
|
|
172
|
+
const declared = Number(res.headers.get("content-length"));
|
|
173
|
+
if (Number.isFinite(declared) && declared > maxBytes) {
|
|
174
|
+
await res.body?.cancel?.().catch(() => undefined);
|
|
175
|
+
throw new ResponseTooLargeError(url, maxBytes, declared);
|
|
147
176
|
}
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
177
|
+
const body = res.body;
|
|
178
|
+
if (!body) {
|
|
179
|
+
const buf = Buffer.from(await res.arrayBuffer());
|
|
180
|
+
if (buf.byteLength > maxBytes)
|
|
181
|
+
throw new ResponseTooLargeError(url, maxBytes, buf.byteLength);
|
|
182
|
+
await pipeline(Readable.from(buf), createWriteStream(filePath));
|
|
151
183
|
return;
|
|
152
184
|
}
|
|
153
|
-
const
|
|
154
|
-
|
|
185
|
+
const reader = body.getReader();
|
|
186
|
+
const out = createWriteStream(filePath);
|
|
187
|
+
const deadlineAt = Date.now() + bodyTimeoutMs;
|
|
188
|
+
let total = 0;
|
|
189
|
+
try {
|
|
190
|
+
while (true) {
|
|
191
|
+
const { done, value } = await readChunkWithDeadline(reader, deadlineAt, options?.signal, url, bodyTimeoutMs);
|
|
192
|
+
if (done)
|
|
193
|
+
break;
|
|
194
|
+
if (!value)
|
|
195
|
+
continue;
|
|
196
|
+
total += value.byteLength;
|
|
197
|
+
if (total > maxBytes)
|
|
198
|
+
throw new ResponseTooLargeError(url, maxBytes, total);
|
|
199
|
+
await writeStreamChunk(out, value);
|
|
200
|
+
}
|
|
201
|
+
await endWriteStream(out);
|
|
202
|
+
}
|
|
203
|
+
catch (err) {
|
|
204
|
+
out.destroy();
|
|
205
|
+
await reader.cancel().catch(() => undefined);
|
|
206
|
+
throw err;
|
|
207
|
+
}
|
|
208
|
+
finally {
|
|
209
|
+
reader.releaseLock?.();
|
|
210
|
+
}
|
|
155
211
|
}
|
|
156
212
|
// ── Hashing ─────────────────────────────────────────────────────────────────
|
|
157
213
|
/**
|
|
@@ -237,6 +293,19 @@ export function sleepSync(ms) {
|
|
|
237
293
|
}
|
|
238
294
|
Atomics.wait(new Int32Array(new SharedArrayBuffer(4)), 0, 0, ms);
|
|
239
295
|
}
|
|
296
|
+
/**
|
|
297
|
+
* Request a synchronous garbage collection. On Bun runs `Bun.gc(true)`; on
|
|
298
|
+
* Node a no-op (no portable forced-GC without --expose-gc). Used by the
|
|
299
|
+
* migrate-apply WAL conversion to finalize any zombie-closed bun:sqlite
|
|
300
|
+
* connection (statements not finalized before close keep the connection and
|
|
301
|
+
* its WAL shared memory alive until GC — issue #720) before concluding that
|
|
302
|
+
* ANOTHER process holds the database.
|
|
303
|
+
*/
|
|
304
|
+
export function requestGc() {
|
|
305
|
+
if (isBun) {
|
|
306
|
+
bunGlobal().gc(true);
|
|
307
|
+
}
|
|
308
|
+
}
|
|
240
309
|
/** Async sleep for `ms`. On Bun uses `Bun.sleep`; on Node a `setTimeout` promise. */
|
|
241
310
|
export function sleep(ms) {
|
|
242
311
|
if (isBun) {
|