akm-cli 0.9.0-rc.8 → 0.9.0
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 +1063 -44
- package/README.md +51 -25
- package/SECURITY.md +14 -1
- package/STABILITY.md +497 -0
- package/dist/akm +148 -35
- package/dist/{akm-migrate-storage → akm-migrate} +6 -9
- package/dist/assets/hints/cli-hints-full.md +223 -95
- package/dist/assets/hints/cli-hints-short.md +85 -22
- package/dist/assets/improve-strategies/default.json +1 -1
- package/dist/assets/improve-strategies/reflect-distill.json +1 -1
- package/dist/assets/prompts/memory-infer-user.md +2 -3
- package/dist/assets/stash-skeleton/README.md +6 -5
- package/dist/assets/stash-skeleton/facts/conventions/assets/agent.md +2 -0
- package/dist/assets/stash-skeleton/facts/conventions/assets/command.md +2 -0
- package/dist/assets/stash-skeleton/facts/conventions/assets/fact.md +2 -0
- package/dist/assets/stash-skeleton/facts/conventions/assets/knowledge.md +2 -0
- package/dist/assets/stash-skeleton/facts/conventions/assets/lesson.md +2 -0
- package/dist/assets/stash-skeleton/facts/conventions/assets/memory.md +2 -0
- package/dist/assets/stash-skeleton/facts/conventions/assets/script.md +2 -0
- package/dist/assets/stash-skeleton/facts/conventions/assets/skill.md +2 -0
- package/dist/assets/stash-skeleton/facts/conventions/assets/workflow.md +2 -0
- package/dist/assets/stash-skeleton/facts/conventions/backlinks.md +2 -0
- package/dist/assets/stash-skeleton/facts/conventions/domains.md +2 -0
- package/dist/assets/stash-skeleton/facts/conventions/organization.md +20 -9
- package/dist/assets/tasks/core/extract.yml +1 -1
- package/dist/assets/tasks/core/version-check.yml +1 -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 +1 -3
- package/dist/assets/workflows/workflow-template.md +32 -15
- package/dist/cli/invocation.js +40 -15
- package/dist/cli/parse-args.js +0 -22
- package/dist/cli/retired-commands.js +121 -0
- package/dist/cli/shared.js +154 -22
- package/dist/cli/unknown-flags.js +236 -0
- package/dist/cli-node.mjs +2 -1
- package/dist/cli.js +696 -258
- package/dist/commands/agent/agent-dispatch.js +14 -3
- package/dist/commands/agent/contribute-cli.js +73 -88
- package/dist/commands/completions.js +79 -22
- package/dist/commands/config-cli.js +17 -150
- package/dist/commands/env/env-cli.js +59 -143
- package/dist/commands/env/env.js +12 -163
- package/dist/commands/env/marker-path.js +6 -0
- package/dist/commands/env/secret-cli.js +36 -66
- package/dist/commands/env/secret.js +24 -57
- package/dist/commands/feedback-cli.js +141 -87
- package/dist/commands/health/accept-rate.js +58 -0
- package/dist/commands/health/advisories.js +3 -4
- package/dist/commands/health/checks.js +85 -23
- package/dist/commands/health/html-report.js +7 -10
- package/dist/commands/health/improve-metrics.js +25 -83
- package/dist/commands/health/md-report.js +5 -9
- package/dist/commands/health/metrics.js +62 -20
- package/dist/commands/health/renderers.js +47 -0
- package/dist/commands/health/report-view-model.js +4 -5
- package/dist/commands/health/stash-exposure.js +1 -1
- package/dist/commands/health/surfaces.js +3 -48
- package/dist/commands/health/task-runs.js +3 -67
- package/dist/commands/health/types-improve.js +7 -0
- package/dist/commands/health.js +99 -28
- package/dist/commands/improve/anti-collapse.js +2 -2
- package/dist/commands/improve/autonomy-gate.js +68 -0
- package/dist/commands/improve/collapse-detector.js +41 -40
- package/dist/commands/improve/consolidate/eligibility.js +1 -23
- package/dist/commands/improve/consolidate/merge.js +4 -0
- package/dist/commands/improve/consolidate.js +140 -1000
- package/dist/commands/improve/distill/promote-memory.js +12 -12
- package/dist/commands/improve/distill/quality-gate.js +6 -6
- package/dist/commands/improve/distill.js +58 -69
- package/dist/commands/improve/eligibility.js +105 -57
- package/dist/commands/improve/extract-cli.js +14 -133
- package/dist/commands/improve/improve-cli.js +98 -114
- package/dist/commands/improve/improve-result-file.js +1 -28
- package/dist/commands/improve/improve-strategies.js +8 -5
- package/dist/commands/improve/improve.js +128 -91
- package/dist/commands/improve/loop-stages.js +182 -20
- package/dist/commands/improve/memory/derived-ref.js +45 -43
- package/dist/commands/improve/memory/memory-belief.js +1 -1
- package/dist/commands/improve/memory/memory-contradiction-detect.js +4 -12
- package/dist/commands/improve/memory/memory-improve.js +6 -5
- package/dist/commands/improve/outcome-loop.js +22 -65
- package/dist/commands/improve/preparation.js +114 -123
- package/dist/commands/improve/proactive-maintenance.js +2 -5
- package/dist/commands/improve/reflect.js +56 -160
- package/dist/commands/improve/salience.js +11 -122
- package/dist/commands/improve/source-identity.js +10 -38
- package/dist/commands/lint/base-linter.js +20 -124
- package/dist/commands/lint/env-key-rules.js +31 -47
- package/dist/commands/lint/index.js +249 -43
- package/dist/commands/{events.js → log.js} +33 -38
- package/dist/commands/migrate-cli.js +92 -12
- package/dist/commands/migration-tool.js +46 -0
- package/dist/commands/observability-cli.js +70 -209
- package/dist/commands/proposal/drain.js +101 -29
- package/dist/commands/proposal/proposal-cli.js +76 -48
- package/dist/commands/proposal/proposal.js +54 -18
- package/dist/commands/proposal/propose-cli.js +88 -0
- package/dist/commands/proposal/propose.js +23 -15
- package/dist/commands/proposal/repository.js +701 -278
- package/dist/commands/proposal/validators/proposal-quality-validators.js +2 -8
- package/dist/commands/proposal/validators/proposal-validators.js +55 -7
- package/dist/commands/proposal/validators/proposals.js +4 -7
- package/dist/commands/read/curate.js +34 -53
- package/dist/commands/read/knowledge.js +150 -95
- package/dist/commands/read/registry-search.js +2 -2
- package/dist/commands/read/remember-cli.js +42 -15
- package/dist/commands/read/search-cli.js +180 -78
- package/dist/commands/read/search.js +58 -43
- package/dist/commands/read/show.js +197 -141
- package/dist/commands/registry-cli.js +12 -51
- package/dist/commands/remember.js +14 -57
- package/dist/commands/sources/add-cli.js +100 -31
- package/dist/commands/sources/bundle-cli.js +166 -0
- package/dist/commands/sources/bundle-config-ops.js +7 -2
- package/dist/commands/sources/info.js +18 -5
- package/dist/commands/sources/init.js +12 -12
- package/dist/commands/sources/installed-stashes.js +382 -98
- package/dist/commands/sources/schema-repair.js +3 -2
- package/dist/commands/sources/self-update.js +131 -38
- package/dist/commands/sources/source-add.js +72 -17
- package/dist/commands/sources/source-clone.js +129 -45
- package/dist/commands/sources/source-manage.js +43 -23
- package/dist/commands/sources/sources-cli.js +57 -208
- package/dist/commands/sources/stash-cli.js +46 -53
- package/dist/commands/tasks/tasks-cli.js +91 -97
- package/dist/commands/tasks/tasks.js +276 -421
- package/dist/commands/workflow-cli.js +175 -450
- package/dist/core/adapter/adapters/akm-adapter.js +47 -28
- package/dist/core/adapter/adapters/akm-lint.js +42 -27
- package/dist/core/adapter/adapters/akm-metadata.js +15 -44
- package/dist/core/adapter/adapters/akm-task-adapter.js +15 -13
- package/dist/core/adapter/adapters/akm-workflow-adapter.js +55 -71
- package/dist/core/adapter/adapters/dotenv-adapter.js +1 -1
- package/dist/core/adapter/adapters/generic-files-adapter.js +2 -0
- package/dist/core/adapter/adapters/index.js +6 -6
- package/dist/core/adapter/adapters/llm-wiki-adapter.js +14 -8
- package/dist/core/adapter/adapters/okf-adapter.js +187 -19
- package/dist/core/adapter/adapters/shared.js +3 -19
- package/dist/core/adapter/adapters/tool-dir-shared.js +8 -3
- package/dist/core/adapter/adapters/website-snapshot-adapter.js +1 -0
- package/dist/core/adapter/detect-adapter.js +17 -0
- package/dist/core/adapter/recognize-match.js +6 -4
- package/dist/core/adapter/validate-context.js +214 -0
- package/dist/core/asset/akm-markdown.js +63 -0
- package/dist/core/asset/asset-placement.js +20 -6
- package/dist/core/asset/asset-ref.js +11 -9
- package/dist/core/asset/frontmatter-lint.js +30 -0
- package/dist/core/asset/frontmatter.js +37 -9
- package/dist/core/asset/markdown.js +40 -51
- package/dist/core/asset/resolve-ref.js +89 -18
- package/dist/core/asset/stash-meta.js +1 -1
- package/dist/core/bundle-id.js +51 -0
- package/dist/core/common.js +152 -38
- package/dist/core/config/config-io.js +12 -1
- package/dist/core/config/config-schema.js +35 -8
- package/dist/core/config/config-sources.js +55 -11
- package/dist/core/config/config-walker.js +25 -9
- package/dist/core/config/config.js +9 -48
- package/dist/core/config/experimental.js +21 -0
- package/dist/core/config/schema/embedding.js +5 -1
- package/dist/core/config/schema/experimental.js +30 -0
- package/dist/core/config/schema/improve-processes.js +0 -6
- package/dist/core/config/schema/improve.js +21 -3
- package/dist/core/config/schema/index-config.js +8 -15
- package/dist/core/config/schema/output.js +4 -1
- package/dist/core/config/schema/setup.js +9 -18
- package/dist/core/config/schema/sources-bundles.js +49 -33
- package/dist/core/config/schema/workflow.js +3 -3
- package/dist/core/env-secret-ref.js +76 -46
- package/dist/core/errors.js +18 -12
- package/dist/core/events.js +46 -128
- package/dist/core/file-change.js +6 -5
- package/dist/core/fs-txn.js +83 -7
- package/dist/core/git-message.js +2 -2
- package/dist/core/improve-result.js +1 -100
- package/dist/core/lesson-lint.js +1 -17
- package/dist/core/logs-db.js +2 -1
- package/dist/core/migration-operation.js +16 -0
- package/dist/core/mutation-target.js +78 -0
- package/dist/core/parse.js +4 -1
- package/dist/core/paths.js +17 -20
- package/dist/core/recognition-util.js +12 -14
- package/dist/core/redaction.js +34 -0
- package/dist/core/standards/resolve-standards-context.js +2 -14
- package/dist/core/standards/resolve-stash-standards.js +2 -2
- package/dist/core/standards/resolve-type-conventions.js +2 -2
- package/dist/core/state/migrations.js +41 -18
- package/dist/core/state-db.js +5 -14
- package/dist/core/structured.js +1 -1
- package/dist/core/subprocess.js +6 -4
- package/dist/core/text-truncation.js +9 -5
- package/dist/core/type-presentation.js +3 -3
- package/dist/core/warn.js +0 -3
- package/dist/core/write-source.js +771 -95
- package/dist/indexer/bundle-identity-guard.js +3 -2
- package/dist/indexer/db/graph-db.js +0 -24
- package/dist/indexer/ensure-index.js +1 -0
- package/dist/indexer/graph/graph-boost.js +9 -34
- package/dist/indexer/graph/graph-extraction.js +8 -5
- package/dist/indexer/index-writer-lock.js +53 -17
- package/dist/indexer/index-written-assets.js +16 -22
- package/dist/indexer/indexer.js +497 -239
- package/dist/indexer/installations.js +14 -96
- package/dist/indexer/passes/dir-staleness.js +16 -9
- package/dist/indexer/passes/memory-inference.js +11 -9
- package/dist/indexer/passes/metadata.js +113 -47
- package/dist/indexer/scan/doc-to-entry.js +38 -1
- package/dist/indexer/scan/drain-dir.js +13 -23
- package/dist/indexer/search/db-search.js +99 -54
- package/dist/indexer/search/fts-query.js +47 -24
- package/dist/indexer/search/ranking-contributors.js +42 -20
- package/dist/indexer/search/ranking.js +18 -99
- package/dist/indexer/search/search-fields.js +7 -2
- package/dist/indexer/search/search-source.js +82 -93
- package/dist/indexer/usage/usage-events.js +0 -89
- package/dist/indexer/walk/file-context.js +2 -1
- package/dist/indexer/walk/matchers.js +30 -43
- package/dist/indexer/walk/path-resolver.js +7 -2
- package/dist/indexer/walk/walker.js +38 -12
- package/dist/integrations/agent/builders.js +0 -6
- package/dist/integrations/agent/config.js +2 -2
- package/dist/integrations/agent/detect.js +49 -19
- package/dist/integrations/agent/engine-fallback.js +76 -0
- package/dist/integrations/agent/profiles.js +14 -0
- package/dist/integrations/agent/prompts.js +12 -8
- package/dist/integrations/agent/runner-dispatch.js +4 -2
- package/dist/integrations/agent/runner.js +0 -1
- package/dist/integrations/agent/spawn.js +5 -6
- package/dist/integrations/github.js +1 -1
- package/dist/integrations/harnesses/aider/agent-builder.js +6 -4
- package/dist/integrations/harnesses/amazonq/agent-builder.js +7 -4
- package/dist/integrations/harnesses/claude/session-log.js +0 -10
- package/dist/integrations/harnesses/codex/agent-builder.js +5 -2
- package/dist/integrations/harnesses/copilot/agent-builder.js +5 -3
- package/dist/integrations/harnesses/gemini/agent-builder.js +5 -3
- package/dist/integrations/harnesses/index.js +3 -7
- package/dist/integrations/harnesses/opencode/agent-builder.js +21 -2
- package/dist/integrations/harnesses/opencode/session-log.js +0 -15
- package/dist/integrations/harnesses/opencode-sdk/sdk-runner.js +13 -4
- package/dist/integrations/harnesses/openhands/agent-builder.js +9 -6
- package/dist/integrations/harnesses/pi/agent-builder.js +6 -4
- package/dist/integrations/lockfile.js +101 -6
- package/dist/integrations/session-logs/index.js +3 -28
- package/dist/llm/client.js +136 -100
- package/dist/llm/embedders/remote.js +13 -5
- package/dist/llm/feature-gate.js +4 -12
- package/dist/llm/graph-extract.js +5 -11
- package/dist/llm/memory-infer.js +144 -1
- package/dist/llm/metadata-enhance.js +5 -7
- package/dist/llm/structured-call.js +1 -1
- package/dist/llm/usage-persist.js +26 -5
- package/dist/llm/usage-telemetry.js +25 -2
- package/dist/output/cli-hints.js +1 -2
- package/dist/output/context.js +22 -7
- package/dist/output/format-exempt.js +80 -0
- package/dist/output/generic-render.js +259 -0
- package/dist/output/render-registry.js +57 -0
- package/dist/output/renderers.js +14 -36
- package/dist/output/shapes/curate.js +10 -1
- package/dist/output/shapes/events.js +12 -7
- package/dist/output/shapes/helpers.js +56 -83
- package/dist/output/shapes/migrate.js +8 -0
- package/dist/output/shapes/passthrough.js +7 -41
- package/dist/output/shapes/proposal/producer.js +15 -7
- package/dist/output/shapes.js +2 -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 +164 -96
- package/dist/output/text/env.js +1 -3
- package/dist/output/text/events.js +8 -7
- package/dist/output/text/health-format.js +103 -0
- package/dist/output/text/health.js +7 -0
- package/dist/output/text/helpers.js +10 -8
- package/dist/output/text/lint-format.js +43 -0
- package/dist/output/text/{save.js → lint.js} +2 -2
- package/dist/output/text/migrate.js +88 -0
- package/dist/output/text/proposal/producer.js +4 -2
- package/dist/output/text/proposal-format.js +44 -72
- package/dist/output/text/registry-commands.js +1 -2
- package/dist/output/text/show-directives.js +15 -7
- package/dist/output/text/status-list.js +32 -0
- package/dist/output/text/sync.js +5 -0
- package/dist/output/text/workflow-format.js +24 -203
- package/dist/output/text/workflow.js +1 -7
- package/dist/output/text.js +16 -17
- 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 +13 -23
- package/dist/registry/resolve.js +42 -7
- package/dist/registry/semver.js +34 -84
- package/dist/runtime.js +2 -23
- package/dist/scripts/akm-migrate-node.js +60290 -0
- package/dist/scripts/akm-migrate.js +59628 -0
- package/dist/setup/detect.js +42 -15
- package/dist/setup/registry-stash-loader.js +2 -2
- package/dist/setup/setup.js +236 -136
- package/dist/setup/steps/connection.js +7 -9
- package/dist/setup/steps/platforms.js +9 -9
- package/dist/setup/steps/semantic.js +15 -3
- package/dist/setup/steps/sources.js +12 -13
- package/dist/setup/steps/stashdir.js +2 -3
- package/dist/setup/steps/tasks.js +237 -120
- package/dist/sources/freshness.js +1 -1
- 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 +25 -23
- package/dist/sources/providers/git-stash.js +395 -106
- package/dist/sources/providers/git.js +2 -2
- package/dist/sources/providers/npm.js +16 -19
- package/dist/sources/providers/provider-utils.js +7 -4
- package/dist/sources/providers/sync-from-ref.js +3 -9
- package/dist/sources/providers/website.js +6 -1
- package/dist/sources/resolve.js +6 -5
- package/dist/sources/snapshot-fetchers/bluesky.js +146 -0
- package/dist/sources/snapshot-fetchers/content-extract.js +566 -0
- package/dist/sources/snapshot-fetchers/fetcher-util.js +41 -0
- package/dist/sources/snapshot-fetchers/github.js +100 -0
- package/dist/sources/snapshot-fetchers/host-guard.js +291 -0
- package/dist/sources/snapshot-fetchers/registry.js +17 -1
- package/dist/sources/snapshot-fetchers/robots.js +348 -0
- package/dist/sources/snapshot-fetchers/rss.js +282 -0
- package/dist/sources/snapshot-fetchers/secret-seam.js +42 -0
- package/dist/sources/snapshot-fetchers/website-ingest.js +566 -268
- package/dist/sources/snapshot-fetchers/x.js +910 -0
- package/dist/storage/database.js +7 -0
- package/dist/storage/engines/sqlite-migrations.js +23 -111
- package/dist/storage/managed-db.js +2 -2
- package/dist/storage/repositories/canaries-repository.js +1 -1
- package/dist/storage/repositories/events-repository.js +27 -11
- package/dist/storage/repositories/improve-runs-repository.js +6 -12
- package/dist/storage/repositories/index-connection.js +17 -6
- package/dist/storage/repositories/index-entries-repository.js +151 -240
- package/dist/storage/repositories/index-entry-mapper.js +15 -11
- package/dist/storage/repositories/index-fts-repository.js +5 -2
- package/dist/storage/repositories/index-llm-cache-repository.js +0 -1
- package/dist/storage/repositories/index-meta-repository.js +2 -3
- package/dist/storage/repositories/index-schema.js +10 -25
- package/dist/storage/repositories/index-utility-repository.js +15 -28
- package/dist/storage/repositories/index-vec-repository.js +6 -1
- package/dist/storage/repositories/outcome-repository.js +119 -0
- package/dist/storage/repositories/proposals-repository.js +296 -59
- package/dist/storage/repositories/registry-cache.js +19 -0
- package/dist/storage/repositories/salience-repository.js +172 -0
- package/dist/storage/repositories/task-history-repository.js +15 -13
- package/dist/storage/repositories/workflow-runs-repository.js +52 -40
- package/dist/tasks/backends/cron.js +105 -15
- package/dist/tasks/backends/index.js +1 -1
- package/dist/tasks/backends/launchd.js +85 -38
- package/dist/tasks/backends/schtasks.js +135 -15
- package/dist/tasks/embedded.js +56 -40
- package/dist/tasks/parser.js +7 -157
- package/dist/tasks/resolve-akm-bin.js +137 -59
- package/dist/tasks/runner.js +79 -42
- package/dist/tasks/scheduler-invocation.js +220 -10
- package/dist/tasks/schema.js +24 -1
- package/dist/tasks/task-id.js +1 -3
- package/dist/tasks/validator.js +20 -6
- package/dist/workflows/authoring/authoring.js +94 -143
- package/dist/workflows/authoring/scope-key.js +1 -1
- package/dist/workflows/exec/frozen-judge.js +28 -2
- package/dist/workflows/exec/native-executor.js +77 -57
- package/dist/workflows/exec/param-secrets.js +9 -9
- package/dist/workflows/exec/run-workflow.js +133 -79
- package/dist/workflows/exec/step-work.js +219 -346
- package/dist/{migrate-storage-node.mjs → workflows/exec/unit-dispatch.js} +1 -5
- package/dist/workflows/ir/compile.js +141 -270
- package/dist/workflows/ir/freeze.js +40 -30
- package/dist/workflows/ir/params.js +135 -11
- package/dist/workflows/ir/plan-hash.js +1 -1
- package/dist/workflows/ir/schema.js +25 -26
- package/dist/workflows/parser.js +872 -307
- package/dist/workflows/program/expressions.js +20 -208
- package/dist/workflows/program/schema.js +7 -10
- package/dist/workflows/renderer.js +95 -68
- package/dist/workflows/resource-limits.js +2 -0
- package/dist/workflows/runtime/checkin.js +3 -3
- package/dist/workflows/runtime/plan-classifier.js +16 -75
- package/dist/workflows/runtime/runs.js +186 -127
- package/dist/workflows/runtime/unit-checkin.js +1 -1
- package/dist/workflows/runtime/unit-phases.js +2 -2
- package/dist/workflows/runtime/workflow-asset-loader.js +232 -83
- package/dist/workflows/schema.js +1 -11
- package/dist/workflows/validate-summary.js +30 -36
- package/dist/workflows/validator.js +21 -62
- package/docs/README.md +68 -0
- package/docs/migration/README.md +8 -0
- package/docs/migration/release-notes/0.7.0.md +11 -11
- package/docs/migration/release-notes/0.9.0.md +208 -27
- package/docs/migration/v0.7-to-v0.8.md +46 -47
- package/docs/migration/v0.8-to-v0.9.md +564 -208
- package/docs/migration/v0.9.0-troubleshooting.md +561 -0
- package/docs/reference/README.md +12 -0
- package/docs/reference/cli.md +2253 -0
- package/docs/reference/configuration.md +358 -0
- package/docs/reference/data-and-telemetry.md +105 -42
- package/docs/reference/workflows.md +647 -0
- package/package.json +22 -11
- package/schemas/akm-asset-envelope.json +93 -0
- package/schemas/akm-config.json +81 -128
- package/schemas/akm-workflow.json +74 -73
- package/dist/assets/tasks/core/backup.yml +0 -5
- package/dist/assets/tasks/graph-refresh-weekly.yml +0 -10
- package/dist/cli/config-migrate.js +0 -1806
- package/dist/cli/config-validate.js +0 -41
- package/dist/commands/backup-cli.js +0 -56
- package/dist/commands/bundle/bundle-cli.js +0 -68
- package/dist/commands/bundle/bundle.js +0 -219
- package/dist/commands/graph/graph-cli.js +0 -124
- package/dist/commands/graph/graph.js +0 -489
- package/dist/commands/improve/extract-watch.js +0 -140
- package/dist/commands/mv-cli.js +0 -1221
- package/dist/commands/sources/history.js +0 -201
- package/dist/commands/tasks/default-tasks.js +0 -186
- package/dist/core/migration-backup.js +0 -1234
- package/dist/indexer/usage/unmigrated-vaults-guard.js +0 -95
- package/dist/llm/memory-infer-impl.js +0 -138
- package/dist/migrate/legacy/config-source-migration.js +0 -223
- package/dist/migrate/legacy/content-migration.js +0 -305
- package/dist/migrate/legacy/legacy-layout.js +0 -779
- package/dist/migrate/legacy/legacy-paths.js +0 -25
- package/dist/migrate/legacy/legacy-stash-json.js +0 -72
- package/dist/migrate/legacy/proposal-fs-import.js +0 -168
- package/dist/migrate/legacy/task-target-ref-migration.js +0 -272
- package/dist/migrate/legacy/three-db-cutover.js +0 -841
- package/dist/migrate/legacy/workflow-migrations-bodies.js +0 -52
- package/dist/migrate/legacy/workflow-migrations-frozen.js +0 -21
- package/dist/migrate/legacy-ref-grammar.js +0 -214
- 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/registry/build-index.js +0 -382
- package/dist/schemas/akm-config.json +0 -4704
- package/dist/schemas/akm-task.json +0 -87
- package/dist/schemas/akm-workflow.json +0 -372
- package/dist/scripts/migrate-storage.js +0 -3816
- package/dist/workflows/authoring/workflow-program-template.yaml +0 -31
- package/dist/workflows/cli.js +0 -53
- package/dist/workflows/exec/brief.js +0 -481
- package/dist/workflows/exec/report.js +0 -1460
- package/dist/workflows/exec/watch.js +0 -116
- package/dist/workflows/program/parser.js +0 -813
- package/dist/workflows/program/project.js +0 -104
|
@@ -19,10 +19,11 @@ import { parseFrontmatter } from "../../core/asset/frontmatter.js";
|
|
|
19
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. */
|
|
@@ -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" });
|
|
@@ -5,7 +5,7 @@ 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, ResponseTooLargeError, readBodyWithByteCap } from "../../core/common.js";
|
|
8
|
+
import { fetchWithRetry, IS_WINDOWS, ResponseTooLargeError, readBodyWithByteCap, readChunkWithDeadline, } from "../../core/common.js";
|
|
9
9
|
import { ConfigError } from "../../core/errors.js";
|
|
10
10
|
import { warn } from "../../core/warn.js";
|
|
11
11
|
import { githubHeaders } from "../../integrations/github.js";
|
|
@@ -29,7 +29,19 @@ export function defaultMigrationCommand(preparedConfigPath) {
|
|
|
29
29
|
apply: (akmBin) => runRequiredCommand(akmBin, ["migrate", "apply", ...configArgs], "Migration apply"),
|
|
30
30
|
};
|
|
31
31
|
}
|
|
32
|
-
|
|
32
|
+
/**
|
|
33
|
+
* Bounds on the binary body read. `fetchWithTimeout`'s timer only covers
|
|
34
|
+
* time-to-HEADERS — it is cleared the moment `fetch` resolves — so without
|
|
35
|
+
* these a compromised or misconfigured endpoint could dribble bytes forever
|
|
36
|
+
* and hang `akm upgrade` with no output and no way out but Ctrl-C. Two
|
|
37
|
+
* bounds, because either alone is evadable: a per-chunk STALL deadline (a
|
|
38
|
+
* connection making no progress dies quickly, while a slow-but-progressing
|
|
39
|
+
* one is left alone) and an OVERALL deadline (a trickle that sends one byte
|
|
40
|
+
* per stall-window can't stretch the download indefinitely).
|
|
41
|
+
*/
|
|
42
|
+
const BINARY_STALL_TIMEOUT_MS = 60_000;
|
|
43
|
+
const BINARY_TOTAL_TIMEOUT_MS = 30 * 60_000;
|
|
44
|
+
export async function streamResponseToFile(response, destination, maxBytes, limits) {
|
|
33
45
|
const declaredText = response.headers.get("content-length");
|
|
34
46
|
if (declaredText) {
|
|
35
47
|
const declared = Number(declaredText);
|
|
@@ -40,22 +52,30 @@ async function streamResponseToFile(response, destination, maxBytes) {
|
|
|
40
52
|
}
|
|
41
53
|
if (!response.body)
|
|
42
54
|
throw new Error("Binary download response did not provide a streaming body.");
|
|
55
|
+
const url = response.url || "binary download";
|
|
56
|
+
const stallTimeoutMs = limits?.stallTimeoutMs ?? BINARY_STALL_TIMEOUT_MS;
|
|
57
|
+
const totalTimeoutMs = limits?.totalTimeoutMs ?? BINARY_TOTAL_TIMEOUT_MS;
|
|
58
|
+
const overallDeadlineAt = Date.now() + totalTimeoutMs;
|
|
43
59
|
const fd = fs.openSync(destination, "w", 0o600);
|
|
44
60
|
const reader = response.body.getReader();
|
|
45
61
|
const hash = createHash("sha256");
|
|
46
62
|
let byteSize = 0;
|
|
47
63
|
try {
|
|
48
64
|
while (true) {
|
|
49
|
-
|
|
65
|
+
// Whichever bound bites first wins, and the error reports THAT bound —
|
|
66
|
+
// "no data for 60s" and "download exceeded 30m" are different diagnoses.
|
|
67
|
+
const stallDeadlineAt = Date.now() + stallTimeoutMs;
|
|
68
|
+
const deadlineAt = Math.min(stallDeadlineAt, overallDeadlineAt);
|
|
69
|
+
const reportedTimeoutMs = deadlineAt === overallDeadlineAt ? totalTimeoutMs : stallTimeoutMs;
|
|
70
|
+
const { done, value } = await readChunkWithDeadline(reader, deadlineAt, undefined, url, reportedTimeoutMs);
|
|
50
71
|
if (done)
|
|
51
72
|
break;
|
|
52
73
|
if (!value)
|
|
53
74
|
continue;
|
|
54
75
|
byteSize += value.byteLength;
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
throw new ResponseTooLargeError(
|
|
58
|
-
}
|
|
76
|
+
// The catch block cancels the reader for every throw path, this included.
|
|
77
|
+
if (byteSize > maxBytes)
|
|
78
|
+
throw new ResponseTooLargeError(url, maxBytes, byteSize);
|
|
59
79
|
hash.update(value);
|
|
60
80
|
let written = 0;
|
|
61
81
|
while (written < value.byteLength)
|
|
@@ -65,6 +85,9 @@ async function streamResponseToFile(response, destination, maxBytes) {
|
|
|
65
85
|
return { byteSize, sha256: hash.digest("hex") };
|
|
66
86
|
}
|
|
67
87
|
catch (error) {
|
|
88
|
+
// Cancel so a timed-out (still-open) connection releases its socket rather
|
|
89
|
+
// than lingering until process exit. Already-cancelled readers no-op.
|
|
90
|
+
await reader.cancel().catch(() => undefined);
|
|
68
91
|
removeFileBestEffort(destination);
|
|
69
92
|
throw error;
|
|
70
93
|
}
|
|
@@ -141,6 +164,21 @@ export async function checkForUpdate(currentVersion) {
|
|
|
141
164
|
installMethod,
|
|
142
165
|
};
|
|
143
166
|
}
|
|
167
|
+
/**
|
|
168
|
+
* Whether the operator has asked to bypass upgrade checksum verification.
|
|
169
|
+
*
|
|
170
|
+
* Deliberately NOT a CLI flag (C6): STABILITY.md states checksum verification
|
|
171
|
+
* is not optional, so the recovery hatch for a genuinely broken `checksums.txt`
|
|
172
|
+
* is this internal, undocumented-on-purpose env var — not something
|
|
173
|
+
* discoverable in `--help` or offered by tab completion.
|
|
174
|
+
*
|
|
175
|
+
* Extracted rather than read inline so `performUpgrade` stays under the
|
|
176
|
+
* function-size bar (`scripts/lint-src-fn-size.ts`), whose baseline only
|
|
177
|
+
* shrinks.
|
|
178
|
+
*/
|
|
179
|
+
function checksumBypassRequested() {
|
|
180
|
+
return process.env.AKM_UPGRADE_SKIP_CHECKSUM === "1";
|
|
181
|
+
}
|
|
144
182
|
export async function performUpgrade(check, opts, dependencies) {
|
|
145
183
|
const { currentVersion, latestVersion, installMethod } = check;
|
|
146
184
|
const force = opts?.force === true;
|
|
@@ -163,31 +201,14 @@ export async function performUpgrade(check, opts, dependencies) {
|
|
|
163
201
|
}
|
|
164
202
|
const packageManagerCommand = getPackageManagerUpgradeCommand(installMethod);
|
|
165
203
|
if (packageManagerCommand) {
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
}
|
|
169
|
-
migration.preflight("akm");
|
|
170
|
-
const result = childProcess.spawnSync(packageManagerCommand.command, packageManagerCommand.args, {
|
|
171
|
-
encoding: "utf8",
|
|
172
|
-
env: process.env,
|
|
173
|
-
stdio: "pipe",
|
|
174
|
-
});
|
|
175
|
-
if (result.error) {
|
|
176
|
-
throw new Error(`Failed to run '${packageManagerCommand.displayCommand}': ${result.error.message}`);
|
|
177
|
-
}
|
|
178
|
-
if (result.status !== 0) {
|
|
179
|
-
const details = (result.stderr ?? "").trim() || (result.stdout ?? "").trim() || `exit code ${result.status}`;
|
|
180
|
-
throw new Error(`Failed to upgrade akm via ${installMethod}: ${details}\nRun manually: ${packageManagerCommand.displayCommand}`);
|
|
181
|
-
}
|
|
182
|
-
migration.apply("akm");
|
|
183
|
-
return {
|
|
204
|
+
return runPackageManagerUpgrade({
|
|
205
|
+
packageManagerCommand,
|
|
184
206
|
currentVersion,
|
|
185
|
-
|
|
186
|
-
upgraded: true,
|
|
207
|
+
latestVersion,
|
|
187
208
|
installMethod,
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
};
|
|
209
|
+
migration,
|
|
210
|
+
skipPostUpgrade,
|
|
211
|
+
});
|
|
191
212
|
}
|
|
192
213
|
if (installMethod === "unknown") {
|
|
193
214
|
return {
|
|
@@ -234,18 +255,18 @@ export async function performUpgrade(check, opts, dependencies) {
|
|
|
234
255
|
}
|
|
235
256
|
throw err;
|
|
236
257
|
}
|
|
237
|
-
// Download and verify checksum (mandatory — upgrade is blocked if checksums cannot be fetched)
|
|
258
|
+
// Download and verify checksum (mandatory — upgrade is blocked if checksums cannot be fetched).
|
|
238
259
|
let checksumVerified = false;
|
|
239
|
-
const skipChecksum =
|
|
260
|
+
const skipChecksum = checksumBypassRequested();
|
|
240
261
|
try {
|
|
241
262
|
const checksumsResponse = await fetchWithRetry(checksumsUrl);
|
|
242
263
|
if (!checksumsResponse.ok) {
|
|
243
264
|
if (skipChecksum) {
|
|
244
|
-
warn(`WARNING: checksums.txt fetch failed (HTTP ${checksumsResponse.status}). Proceeding without verification because
|
|
265
|
+
warn(`WARNING: checksums.txt fetch failed (HTTP ${checksumsResponse.status}). Proceeding without verification because AKM_UPGRADE_SKIP_CHECKSUM=1 was set.`);
|
|
245
266
|
}
|
|
246
267
|
else {
|
|
247
268
|
throw new Error(`Checksum verification failed: could not fetch ${checksumsUrl} (HTTP ${checksumsResponse.status}). ` +
|
|
248
|
-
`
|
|
269
|
+
`Set AKM_UPGRADE_SKIP_CHECKSUM=1 to bypass (not recommended).`);
|
|
249
270
|
}
|
|
250
271
|
}
|
|
251
272
|
else {
|
|
@@ -260,11 +281,11 @@ export async function performUpgrade(check, opts, dependencies) {
|
|
|
260
281
|
}
|
|
261
282
|
else {
|
|
262
283
|
if (skipChecksum) {
|
|
263
|
-
warn(`WARNING: ${binaryName} not found in checksums.txt. Proceeding without verification because
|
|
284
|
+
warn(`WARNING: ${binaryName} not found in checksums.txt. Proceeding without verification because AKM_UPGRADE_SKIP_CHECKSUM=1 was set.`);
|
|
264
285
|
}
|
|
265
286
|
else {
|
|
266
287
|
throw new Error(`Checksum verification failed: ${binaryName} not listed in checksums.txt. ` +
|
|
267
|
-
`
|
|
288
|
+
`Set AKM_UPGRADE_SKIP_CHECKSUM=1 to bypass (not recommended).`);
|
|
268
289
|
}
|
|
269
290
|
}
|
|
270
291
|
}
|
|
@@ -277,12 +298,12 @@ export async function performUpgrade(check, opts, dependencies) {
|
|
|
277
298
|
}
|
|
278
299
|
// Network or parse failure
|
|
279
300
|
if (skipChecksum) {
|
|
280
|
-
warn(`WARNING: Could not fetch or parse checksums: ${err instanceof Error ? err.message : String(err)}. Proceeding because
|
|
301
|
+
warn(`WARNING: Could not fetch or parse checksums: ${err instanceof Error ? err.message : String(err)}. Proceeding because AKM_UPGRADE_SKIP_CHECKSUM=1 was set.`);
|
|
281
302
|
}
|
|
282
303
|
else {
|
|
283
304
|
removeFileBestEffort(stagedPath);
|
|
284
305
|
throw new Error(`Checksum verification failed: ${err instanceof Error ? err.message : String(err)}. ` +
|
|
285
|
-
`
|
|
306
|
+
`Set AKM_UPGRADE_SKIP_CHECKSUM=1 to bypass (not recommended).`);
|
|
286
307
|
}
|
|
287
308
|
}
|
|
288
309
|
try {
|
|
@@ -380,6 +401,78 @@ function runPostUpgradeTasks(akmBin, opts) {
|
|
|
380
401
|
};
|
|
381
402
|
}
|
|
382
403
|
}
|
|
404
|
+
/**
|
|
405
|
+
* The package-manager arm of {@link performUpgrade}: preflight → install →
|
|
406
|
+
* post-install version verification → migrate apply → post-upgrade tasks.
|
|
407
|
+
* Extracted whole so performUpgrade stays under its fn-size baseline.
|
|
408
|
+
*/
|
|
409
|
+
function runPackageManagerUpgrade(input) {
|
|
410
|
+
const { packageManagerCommand, currentVersion, latestVersion, installMethod, migration, skipPostUpgrade } = input;
|
|
411
|
+
if (!latestVersion) {
|
|
412
|
+
throw new Error("Unable to determine latest version from GitHub releases. Check https://github.com/itlackey/akm/releases");
|
|
413
|
+
}
|
|
414
|
+
migration.preflight("akm");
|
|
415
|
+
const result = childProcess.spawnSync(packageManagerCommand.command, packageManagerCommand.args, {
|
|
416
|
+
encoding: "utf8",
|
|
417
|
+
env: process.env,
|
|
418
|
+
stdio: "pipe",
|
|
419
|
+
});
|
|
420
|
+
if (result.error) {
|
|
421
|
+
throw new Error(`Failed to run '${packageManagerCommand.displayCommand}': ${result.error.message}`);
|
|
422
|
+
}
|
|
423
|
+
if (result.status !== 0) {
|
|
424
|
+
const details = (result.stderr ?? "").trim() || (result.stdout ?? "").trim() || `exit code ${result.status}`;
|
|
425
|
+
throw new Error(`Failed to upgrade akm via ${installMethod}: ${details}\nRun manually: ${packageManagerCommand.displayCommand}`);
|
|
426
|
+
}
|
|
427
|
+
// The package manager exiting 0 does not prove it delivered
|
|
428
|
+
// `latestVersion`: a lagging `@latest` dist-tag (partial publish,
|
|
429
|
+
// registry mirror lag) "succeeds" while leaving the old version on PATH.
|
|
430
|
+
// Re-read the version the shim actually reports before claiming an
|
|
431
|
+
// upgrade — a confirmed mismatch also means `migrate apply` would run
|
|
432
|
+
// against the OLD binary, so stop before it.
|
|
433
|
+
const installedVersion = readInstalledCliVersion("akm");
|
|
434
|
+
if (installedVersion !== undefined && installedVersion !== latestVersion) {
|
|
435
|
+
return {
|
|
436
|
+
currentVersion,
|
|
437
|
+
newVersion: latestVersion,
|
|
438
|
+
upgraded: false,
|
|
439
|
+
installMethod,
|
|
440
|
+
message: `\`${packageManagerCommand.displayCommand}\` succeeded, but \`akm --version\` still reports ` +
|
|
441
|
+
`v${installedVersion} (expected v${latestVersion}). The ${installMethod} registry's @latest tag ` +
|
|
442
|
+
`may be lagging the GitHub release — try again shortly, or install the exact version: ` +
|
|
443
|
+
`${packageManagerCommand.displayCommand.replace(/@latest\b/, `@${latestVersion}`)}`,
|
|
444
|
+
};
|
|
445
|
+
}
|
|
446
|
+
migration.apply("akm");
|
|
447
|
+
return {
|
|
448
|
+
currentVersion,
|
|
449
|
+
newVersion: latestVersion,
|
|
450
|
+
upgraded: true,
|
|
451
|
+
installMethod,
|
|
452
|
+
message: installedVersion === latestVersion
|
|
453
|
+
? `akm upgraded via ${installMethod} (verified: akm --version reports v${installedVersion})`
|
|
454
|
+
: `akm upgraded via ${installMethod} (installed version could not be verified)`,
|
|
455
|
+
postUpgrade: runPostUpgradeTasks("akm", { skip: skipPostUpgrade }),
|
|
456
|
+
};
|
|
457
|
+
}
|
|
458
|
+
/**
|
|
459
|
+
* Read the version the on-PATH `akm` actually reports, or `undefined` when
|
|
460
|
+
* that cannot be determined (no shim on PATH in a sandbox, unparseable
|
|
461
|
+
* output). Verification is fail-open on its own infrastructure — only a
|
|
462
|
+
* CONFIRMED mismatch downgrades an upgrade result (§24.2 Package/release
|
|
463
|
+
* gate).
|
|
464
|
+
*/
|
|
465
|
+
function readInstalledCliVersion(akmBin) {
|
|
466
|
+
const result = childProcess.spawnSync(akmBin, ["--version"], {
|
|
467
|
+
encoding: "utf8",
|
|
468
|
+
env: process.env,
|
|
469
|
+
stdio: "pipe",
|
|
470
|
+
});
|
|
471
|
+
if (result.error || result.status !== 0)
|
|
472
|
+
return undefined;
|
|
473
|
+
const match = (result.stdout ?? "").match(/\d+\.\d+\.\d+(?:-[0-9A-Za-z.-]+)?/);
|
|
474
|
+
return match?.[0];
|
|
475
|
+
}
|
|
383
476
|
function runRequiredCommand(akmBin, args, label) {
|
|
384
477
|
const result = childProcess.spawnSync(akmBin, args, {
|
|
385
478
|
encoding: "utf8",
|
|
@@ -3,6 +3,7 @@
|
|
|
3
3
|
// file, You can obtain one at https://mozilla.org/MPL/2.0/.
|
|
4
4
|
import fs from "node:fs";
|
|
5
5
|
import path from "node:path";
|
|
6
|
+
import { detectAdapterId } from "../../core/adapter/detect-adapter.js";
|
|
6
7
|
import { isBundleSlug } from "../../core/asset/asset-ref.js";
|
|
7
8
|
import { isHttpUrl, resolveStashDir } from "../../core/common.js";
|
|
8
9
|
import { bundleEntryToSourceEntry, getSources, installedSourceDescriptor, loadConfig, mutateConfig, } from "../../core/config/config.js";
|
|
@@ -13,13 +14,14 @@ import { readLockfile, removeLockEntry, upsertLockEntry } from "../../integratio
|
|
|
13
14
|
import { parseRegistryRef } from "../../registry/resolve.js";
|
|
14
15
|
import { detectStashRoot } from "../../sources/providers/provider-utils.js";
|
|
15
16
|
import { syncFromRef } from "../../sources/providers/sync-from-ref.js";
|
|
17
|
+
import { storeSecretResolver } from "../../sources/snapshot-fetchers/secret-seam.js";
|
|
16
18
|
import { ensureWebsiteMirror, shouldAllowPrivateWebsiteUrlForTests, validateWebsiteInputUrl, } from "../../sources/snapshot-fetchers/website-ingest.js";
|
|
17
19
|
import { bundleKeyForPath, bundleKeyForUrl, nextBundleKey } from "./bundle-config-ops.js";
|
|
18
20
|
export async function akmAdd(input) {
|
|
19
21
|
const ref = input.ref.trim();
|
|
20
22
|
if (!ref)
|
|
21
23
|
throw new UsageError("Install ref or local directory is required. " +
|
|
22
|
-
"Examples: `akm add @scope/stash`, `akm add github:owner/repo`, `akm add ./local/path`");
|
|
24
|
+
"Examples: `akm bundle add @scope/stash`, `akm bundle add github:owner/repo`, `akm bundle add ./local/path`");
|
|
23
25
|
const stashDir = resolveStashDir();
|
|
24
26
|
if (shouldAddAsWebsiteUrl(ref)) {
|
|
25
27
|
return addWebsiteSource(ref, stashDir, input.name, input.options);
|
|
@@ -47,20 +49,31 @@ async function addLocalSource(ref, sourcePath, stashDir, explicitName) {
|
|
|
47
49
|
mutateConfig((config) => {
|
|
48
50
|
const existing = bundleKeyForPath(config, resolvedPath);
|
|
49
51
|
if (existing) {
|
|
50
|
-
// Already configured — the bundle key is the stable identity; leave it.
|
|
51
52
|
bundleKey = existing;
|
|
52
|
-
|
|
53
|
+
const current = config.bundles?.[existing];
|
|
54
|
+
if (current?.components)
|
|
55
|
+
return config;
|
|
56
|
+
const bundles = { ...(config.bundles ?? {}) };
|
|
57
|
+
bundles[existing] = {
|
|
58
|
+
...current,
|
|
59
|
+
path: resolvedPath,
|
|
60
|
+
components: { main: { root: ".", adapter: detectAdapterId(resolvedPath) } },
|
|
61
|
+
};
|
|
62
|
+
return { ...config, bundles };
|
|
53
63
|
}
|
|
54
64
|
const bundles = { ...(config.bundles ?? {}) };
|
|
55
65
|
bundleKey = nextBundleKey(bundles, explicitName, resolvedPath);
|
|
56
|
-
bundles[bundleKey] = {
|
|
66
|
+
bundles[bundleKey] = {
|
|
67
|
+
path: resolvedPath,
|
|
68
|
+
components: { main: { root: ".", adapter: detectAdapterId(resolvedPath) } },
|
|
69
|
+
};
|
|
57
70
|
return { ...config, bundles };
|
|
58
71
|
});
|
|
59
72
|
const index = await akmIndex({ stashDir });
|
|
60
73
|
const updatedConfig = loadConfig();
|
|
61
74
|
return {
|
|
62
75
|
schemaVersion: 1,
|
|
63
|
-
stashDir,
|
|
76
|
+
bundleDir: stashDir,
|
|
64
77
|
ref,
|
|
65
78
|
sourceAdded: {
|
|
66
79
|
type: "filesystem",
|
|
@@ -70,7 +83,6 @@ async function addLocalSource(ref, sourcePath, stashDir, explicitName) {
|
|
|
70
83
|
},
|
|
71
84
|
config: {
|
|
72
85
|
sourceCount: getSources(updatedConfig).length,
|
|
73
|
-
installedKitCount: readLockfile().length,
|
|
74
86
|
},
|
|
75
87
|
index: {
|
|
76
88
|
mode: index.mode,
|
|
@@ -84,14 +96,31 @@ async function addLocalSource(ref, sourcePath, stashDir, explicitName) {
|
|
|
84
96
|
async function addWebsiteSource(ref, stashDir, name, options) {
|
|
85
97
|
const allowPrivateHosts = shouldAllowPrivateWebsiteUrlForTests(ref);
|
|
86
98
|
const normalizedUrl = validateWebsiteInputUrl(ref, { allowPrivateHosts });
|
|
87
|
-
const
|
|
99
|
+
const numberOption = (value) => (typeof value === "number" ? value : undefined);
|
|
100
|
+
const maxPages = numberOption(options?.maxPages);
|
|
101
|
+
const maxDepth = numberOption(options?.maxDepth);
|
|
88
102
|
let entry;
|
|
89
103
|
mutateConfig((config) => {
|
|
90
104
|
const bundles = { ...(config.bundles ?? {}) };
|
|
91
105
|
const existingKey = bundleKeyForUrl(config, normalizedUrl);
|
|
92
106
|
const key = existingKey ?? nextBundleKey(bundles, name ?? toWebsiteName(normalizedUrl), normalizedUrl);
|
|
93
|
-
|
|
94
|
-
|
|
107
|
+
// Merge onto the existing descriptor rather than replacing it: re-running
|
|
108
|
+
// `bundle add` for a URL that already has a bundle would otherwise drop
|
|
109
|
+
// respectRobots / refresh, silently restoring default robots enforcement
|
|
110
|
+
// and changing what the next update fetches. Explicitly-passed maxPages /
|
|
111
|
+
// maxDepth still win over the stored values.
|
|
112
|
+
const existingWebsite = existingKey ? (bundles[key]?.website ?? {}) : {};
|
|
113
|
+
const website = {
|
|
114
|
+
...existingWebsite,
|
|
115
|
+
url: normalizedUrl,
|
|
116
|
+
...(maxPages !== undefined ? { maxPages } : {}),
|
|
117
|
+
...(maxDepth !== undefined ? { maxDepth } : {}),
|
|
118
|
+
};
|
|
119
|
+
const nextBundle = {
|
|
120
|
+
...(existingKey ? bundles[key] : {}),
|
|
121
|
+
website,
|
|
122
|
+
components: { main: { root: ".", adapter: "website-snapshot", writable: false } },
|
|
123
|
+
};
|
|
95
124
|
if (JSON.stringify(bundles[key]) === JSON.stringify(nextBundle)) {
|
|
96
125
|
entry = bundleEntryToSourceEntry(key, bundles[key]);
|
|
97
126
|
return config;
|
|
@@ -102,13 +131,14 @@ async function addWebsiteSource(ref, stashDir, name, options) {
|
|
|
102
131
|
});
|
|
103
132
|
const cachePaths = await ensureWebsiteMirror(entry, {
|
|
104
133
|
requireStashDir: true,
|
|
134
|
+
resolveSecret: storeSecretResolver.resolveSecret,
|
|
105
135
|
...(allowPrivateHosts ? { allowPrivateHosts: true } : {}),
|
|
106
136
|
});
|
|
107
137
|
const index = await akmIndex({ stashDir });
|
|
108
138
|
const updatedConfig = loadConfig();
|
|
109
139
|
return {
|
|
110
140
|
schemaVersion: 1,
|
|
111
|
-
stashDir,
|
|
141
|
+
bundleDir: stashDir,
|
|
112
142
|
ref,
|
|
113
143
|
sourceAdded: {
|
|
114
144
|
type: "website",
|
|
@@ -118,7 +148,6 @@ async function addWebsiteSource(ref, stashDir, name, options) {
|
|
|
118
148
|
},
|
|
119
149
|
config: {
|
|
120
150
|
sourceCount: getSources(updatedConfig).length,
|
|
121
|
-
installedKitCount: readLockfile().length,
|
|
122
151
|
},
|
|
123
152
|
index: {
|
|
124
153
|
mode: index.mode,
|
|
@@ -135,10 +164,23 @@ async function addWebsiteSource(ref, stashDir, name, options) {
|
|
|
135
164
|
*/
|
|
136
165
|
async function addRegistryStash(ref, stashDir, writable) {
|
|
137
166
|
const parsedRef = parseRegistryRef(ref);
|
|
138
|
-
if (writable === true && parsedRef.source !== "git") {
|
|
167
|
+
if (writable === true && parsedRef.source !== "git" && parsedRef.source !== "github") {
|
|
139
168
|
throw new ConfigError("writable: true is only supported on filesystem and git sources", "INVALID_CONFIG_FILE");
|
|
140
169
|
}
|
|
141
|
-
const
|
|
170
|
+
const currentConfig = loadConfig();
|
|
171
|
+
const existingBundleKey = findInstalledBundleKey(currentConfig.bundles ?? {}, parsedRef.id);
|
|
172
|
+
const existingBundle = existingBundleKey ? currentConfig.bundles?.[existingBundleKey] : undefined;
|
|
173
|
+
const priorLock = existingBundleKey ? readLockfile().find((entry) => entry.id === existingBundleKey) : undefined;
|
|
174
|
+
const existingWritable = Object.values(existingBundle?.components ?? {})[0]?.writable ?? existingBundle?.writable === true;
|
|
175
|
+
const effectiveWritable = writable === true || existingWritable;
|
|
176
|
+
const requiredRoots = priorLock?.localRoot
|
|
177
|
+
? Object.values(existingBundle?.components ?? {}).map((component) => path.resolve(priorLock.localRoot, component.root ?? "."))
|
|
178
|
+
: [];
|
|
179
|
+
const synced = await syncFromRef(ref, {
|
|
180
|
+
writable: effectiveWritable,
|
|
181
|
+
...(effectiveWritable && priorLock?.localRoot ? { writableRoot: priorLock.localRoot } : {}),
|
|
182
|
+
...(requiredRoots.length > 0 ? { writableRequiredRoots: requiredRoots } : {}),
|
|
183
|
+
});
|
|
142
184
|
const { config: updatedConfig, bundleId } = upsertInstalledRegistryEntry({
|
|
143
185
|
id: synced.id,
|
|
144
186
|
source: synced.source,
|
|
@@ -153,7 +195,7 @@ async function addRegistryStash(ref, stashDir, writable) {
|
|
|
153
195
|
});
|
|
154
196
|
// The prior materialized root (if this is a re-install) — read BEFORE the lock
|
|
155
197
|
// upsert overwrites it, so a moved cache root can be cleaned afterwards.
|
|
156
|
-
const priorLocalRoot =
|
|
198
|
+
const priorLocalRoot = priorLock?.localRoot;
|
|
157
199
|
await upsertLockEntry({
|
|
158
200
|
id: bundleId,
|
|
159
201
|
source: synced.source,
|
|
@@ -166,7 +208,7 @@ async function addRegistryStash(ref, stashDir, writable) {
|
|
|
166
208
|
installedAt: synced.syncedAt,
|
|
167
209
|
});
|
|
168
210
|
// Clean up the old materialized root on re-install (moved cache).
|
|
169
|
-
if (priorLocalRoot && path.resolve(priorLocalRoot) !== path.resolve(synced.contentDir)) {
|
|
211
|
+
if (!effectiveWritable && priorLocalRoot && path.resolve(priorLocalRoot) !== path.resolve(synced.contentDir)) {
|
|
170
212
|
try {
|
|
171
213
|
fs.rmSync(priorLocalRoot, { recursive: true, force: true });
|
|
172
214
|
}
|
|
@@ -177,7 +219,7 @@ async function addRegistryStash(ref, stashDir, writable) {
|
|
|
177
219
|
const index = await akmIndex({ stashDir });
|
|
178
220
|
return {
|
|
179
221
|
schemaVersion: 1,
|
|
180
|
-
stashDir,
|
|
222
|
+
bundleDir: stashDir,
|
|
181
223
|
ref,
|
|
182
224
|
installed: {
|
|
183
225
|
id: synced.id,
|
|
@@ -193,7 +235,6 @@ async function addRegistryStash(ref, stashDir, writable) {
|
|
|
193
235
|
},
|
|
194
236
|
config: {
|
|
195
237
|
sourceCount: getSources(updatedConfig).length,
|
|
196
|
-
installedKitCount: readLockfile().length,
|
|
197
238
|
},
|
|
198
239
|
index: {
|
|
199
240
|
mode: index.mode,
|
|
@@ -217,11 +258,25 @@ export function upsertInstalledRegistryEntry(entry) {
|
|
|
217
258
|
const config = mutateConfig((current) => {
|
|
218
259
|
const bundles = { ...(current.bundles ?? {}) };
|
|
219
260
|
bundleId = resolveInstalledBundleKey(bundles, entry.id, entry.stashRoot);
|
|
261
|
+
const existingComponents = bundles[bundleId]?.components;
|
|
262
|
+
const components = existingComponents
|
|
263
|
+
? Object.fromEntries(Object.entries(existingComponents).map(([id, component]) => [
|
|
264
|
+
id,
|
|
265
|
+
{ ...component, writable: entry.writable === true },
|
|
266
|
+
]))
|
|
267
|
+
: {
|
|
268
|
+
main: {
|
|
269
|
+
root: ".",
|
|
270
|
+
adapter: detectAdapterId(path.resolve(entry.stashRoot)),
|
|
271
|
+
writable: entry.writable === true,
|
|
272
|
+
},
|
|
273
|
+
};
|
|
220
274
|
const descriptor = installedSourceDescriptor(entry.source, entry.ref, path.resolve(entry.stashRoot));
|
|
221
275
|
bundles[bundleId] = {
|
|
222
276
|
...descriptor,
|
|
223
277
|
...(entry.writable === true ? { writable: true } : {}),
|
|
224
278
|
...(entry.id !== bundleId ? { registryId: entry.id } : {}),
|
|
279
|
+
components: components,
|
|
225
280
|
};
|
|
226
281
|
return { ...current, bundles };
|
|
227
282
|
}).config;
|