akm-cli 0.9.16 → 0.9.17-alpha.10
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 +2101 -0
- package/STABILITY.md +11 -10
- package/dist/akm +124 -193
- package/dist/akm-migrate +38 -19
- package/dist/assets/hints/cli-hints-full.md +6 -7
- package/dist/assets/improve-strategies/catchup.json +0 -3
- package/dist/assets/improve-strategies/consolidate.json +0 -1
- package/dist/assets/improve-strategies/default.json +1 -2
- package/dist/assets/improve-strategies/proactive-maintenance.json +1 -2
- package/dist/assets/improve-strategies/quick.json +1 -2
- package/dist/assets/improve-strategies/reflect-distill.json +1 -2
- package/dist/assets/improve-strategies/thorough.json +0 -3
- package/dist/assets/prompts/consolidate-pair.md +20 -0
- package/dist/assets/prompts/consolidate-system.md +4 -11
- package/dist/assets/prompts/retrieval-relevance-judge.md +6 -0
- package/dist/assets/stash-skeleton/facts/conventions/backlinks.md +20 -20
- package/dist/assets/stash-skeleton/facts/conventions/domains.md +2 -2
- package/dist/assets/templates/html/health.html +3 -5
- package/dist/cli/retired-commands.js +1 -1
- package/dist/cli/shared.js +6 -2
- package/dist/cli/unknown-flags.js +24 -1
- package/dist/cli.js +68 -10
- package/dist/commands/agent/agent-dispatch.js +1 -1
- package/dist/commands/command/command-execution.js +24 -62
- package/dist/commands/feedback-cli.js +0 -1
- package/dist/commands/health/accept-rate.js +6 -0
- package/dist/commands/health/archive-usage.js +92 -0
- package/dist/commands/health/checks.js +83 -74
- package/dist/commands/health/config-skew.js +38 -0
- package/dist/commands/health/data-dir-usage.js +25 -13
- package/dist/commands/health/egress.js +54 -0
- package/dist/commands/health/html-report.js +1 -42
- package/dist/commands/health/improve-metrics.js +136 -591
- package/dist/commands/health/md-report.js +1 -6
- package/dist/commands/health/plugin-staleness.js +53 -3
- package/dist/commands/health/renderers.js +12 -4
- package/dist/commands/health/report-view-model.js +14 -120
- package/dist/commands/health/types-improve.js +4 -19
- package/dist/commands/health/windows.js +64 -74
- package/dist/commands/health.js +145 -143
- package/dist/commands/improve/consolidate/chunking.js +26 -117
- package/dist/commands/improve/consolidate/continuity-check.js +137 -0
- package/dist/commands/improve/consolidate/pair-pass.js +791 -0
- package/dist/commands/improve/consolidate/sanitize.js +54 -149
- package/dist/commands/improve/consolidate.js +589 -1127
- package/dist/commands/improve/content-hash.js +16 -24
- package/dist/commands/improve/distill/content-repair.js +18 -100
- package/dist/commands/improve/distill-guards.js +20 -81
- package/dist/commands/improve/distill-promotion-policy.js +23 -243
- package/dist/commands/improve/distill.js +608 -1041
- package/dist/commands/improve/eligibility.js +126 -390
- package/dist/commands/improve/execution.js +8 -10
- package/dist/commands/improve/extract-prompt.js +1 -2
- package/dist/commands/improve/extract.js +487 -1046
- package/dist/commands/improve/feedback-valence.js +0 -25
- package/dist/commands/improve/improve-cli.js +75 -169
- package/dist/commands/improve/improve-result-file.js +10 -66
- package/dist/commands/improve/improve-strategies.js +52 -4
- package/dist/commands/improve/improve-usage-report.js +18 -64
- package/dist/commands/improve/improve.js +480 -1074
- package/dist/commands/improve/ledger.js +119 -0
- package/dist/commands/improve/locks.js +2 -8
- package/dist/commands/improve/loop-stages.js +415 -1073
- package/dist/commands/improve/memory/derived-ref.js +12 -77
- package/dist/commands/improve/memory/memory-belief.js +16 -118
- package/dist/commands/improve/memory/memory-improve.js +266 -14
- package/dist/commands/improve/outcome-loop.js +28 -156
- package/dist/commands/improve/planner.js +5 -15
- package/dist/commands/improve/preparation.js +779 -2319
- package/dist/commands/improve/proactive-maintenance.js +34 -101
- package/dist/commands/improve/reflect-noise.js +104 -280
- package/dist/commands/improve/reflect.js +642 -1353
- package/dist/commands/improve/retrieval-gate.js +127 -0
- package/dist/commands/improve/retrieval-scope.js +92 -0
- package/dist/commands/improve/salience.js +41 -240
- package/dist/commands/improve/session-asset.js +19 -100
- package/dist/commands/improve/stage.js +322 -0
- package/dist/commands/lint/base-linter.js +37 -15
- package/dist/commands/proposal/drain.js +261 -578
- package/dist/commands/proposal/proposal-cli.js +19 -20
- package/dist/commands/proposal/proposal-types.js +31 -24
- package/dist/commands/proposal/proposal.js +38 -8
- package/dist/commands/proposal/propose.js +134 -160
- package/dist/commands/proposal/repository.js +1097 -1394
- package/dist/commands/proposal/validators/proposal-quality-validators.js +71 -174
- package/dist/commands/proposal/validators/proposal-validators.js +1 -1
- package/dist/commands/proposal/validators/proposals.js +22 -89
- package/dist/commands/read/curate.js +105 -462
- package/dist/commands/read/knowledge.js +3 -2
- package/dist/commands/read/search-cli.js +16 -33
- package/dist/commands/read/search.js +17 -23
- package/dist/commands/read/show.js +57 -108
- package/dist/commands/sources/bundle-cli.js +25 -2
- package/dist/commands/sources/bundle-config-ops.js +4 -0
- package/dist/commands/sources/dangerous-env-audit.js +1 -2
- package/dist/commands/sources/info.js +127 -29
- package/dist/commands/sources/installed-stashes.js +197 -746
- package/dist/commands/sources/schema-repair.js +98 -129
- package/dist/commands/sources/source-add.js +62 -12
- package/dist/commands/sources/source-manage.js +9 -2
- package/dist/commands/sources/stash-cli.js +24 -4
- package/dist/commands/tasks/explain.js +10 -13
- package/dist/commands/tasks/tasks-cli.js +12 -13
- package/dist/commands/tasks/tasks.js +350 -936
- package/dist/commands/tasks/validate.js +26 -24
- package/dist/commands/workflow/plan.js +22 -29
- package/dist/commands/workflow-cli.js +4 -4
- package/dist/core/adapter/adapters/akm-adapter.js +2 -1
- package/dist/core/adapter/adapters/akm-lint.js +2 -3
- package/dist/core/adapter/adapters/akm-metadata.js +42 -12
- package/dist/core/adapter/adapters/akm-task-adapter.js +29 -8
- package/dist/core/adapter/adapters/akm-workflow-adapter.js +1 -1
- package/dist/core/adapter/execution-source.js +17 -29
- package/dist/core/asset/asset-placement.js +4 -13
- package/dist/core/asset/frontmatter.js +106 -1
- package/dist/core/asset/resolve-ref.js +1 -1
- package/dist/core/bundle-id.js +42 -5
- package/dist/core/bundle-rename.js +285 -0
- package/dist/core/config/config-io.js +1 -2
- package/dist/core/config/config-schema.js +9 -34
- package/dist/core/config/config-walker.js +1 -1
- package/dist/core/config/config.js +184 -111
- package/dist/core/config/engine-semantics.js +0 -2
- package/dist/core/config/legacy-source-shape-shim.js +38 -9
- package/dist/core/config/schema/embedding.js +20 -5
- package/dist/core/config/schema/engines.js +5 -0
- package/dist/core/config/schema/execution.js +1 -1
- package/dist/core/config/schema/experimental.js +1 -1
- package/dist/core/config/schema/improve-processes.js +54 -125
- package/dist/core/config/schema/improve.js +4 -42
- package/dist/core/config/schema/index-config.js +9 -48
- package/dist/core/config/schema/scheduler.js +12 -12
- package/dist/core/config/schema/search.js +6 -22
- package/dist/core/env-secret-ref.js +0 -1
- package/dist/core/errors.js +8 -9
- package/dist/core/file-change.js +13 -5
- package/dist/core/file-lock.js +76 -173
- package/dist/core/improve-result.js +35 -7
- package/dist/core/improve-types.js +0 -1
- package/dist/core/logs-db.js +2 -2
- package/dist/core/loopback.js +7 -12
- package/dist/core/non-task-input.js +20 -0
- package/dist/core/parse.js +13 -16
- package/dist/core/paths.js +0 -24
- package/dist/core/redaction.js +109 -2
- package/dist/core/run-lock.js +2 -5
- package/dist/core/spawn-env.js +1 -1
- package/dist/core/state/migrations.js +123 -61
- package/dist/core/state-db-scope.js +2 -4
- package/dist/core/state-db.js +126 -692
- package/dist/core/time.js +0 -20
- package/dist/core/type-presentation.js +1 -9
- package/dist/core/write-source.js +294 -1005
- package/dist/execution/input-contract.js +1 -1
- package/dist/execution/resolved-request.js +135 -689
- package/dist/execution/source.js +63 -257
- package/dist/execution/target-ref.js +1 -1
- package/dist/indexer/bundle-identity-guard.js +2 -2
- package/dist/indexer/db/llm-cache.js +2 -2
- package/dist/indexer/ensure-index.js +77 -73
- package/dist/indexer/index-rebuild-lock.js +3 -11
- package/dist/indexer/index-writer-lock.js +8 -17
- package/dist/indexer/index-written-assets.js +141 -154
- package/dist/indexer/indexer.js +400 -1124
- package/dist/indexer/links/declared-links.js +90 -0
- package/dist/indexer/materialize-embeddings.js +60 -397
- package/dist/indexer/passes/memory-inference.js +96 -90
- package/dist/indexer/passes/metadata.js +132 -219
- package/dist/indexer/read-preflight.js +0 -7
- package/dist/indexer/scan/doc-to-entry.js +2 -3
- package/dist/indexer/scan/drain-dir.js +1 -1
- package/dist/indexer/search/db-search.js +190 -590
- package/dist/indexer/search/fts-query.js +30 -41
- package/dist/indexer/search/ranking.js +28 -154
- package/dist/indexer/search/search-attribution.js +12 -32
- package/dist/indexer/search/search-fields.js +11 -15
- package/dist/indexer/search/search-hit-enrichers.js +54 -85
- package/dist/indexer/search/search-source.js +1 -4
- package/dist/indexer/usage/usage-events.js +36 -7
- package/dist/indexer/walk/walker.js +3 -4
- package/dist/integrations/agent/engine-fallback.js +23 -40
- package/dist/integrations/agent/engine-resolution.js +93 -183
- package/dist/integrations/agent/execution.js +507 -0
- package/dist/integrations/agent/model-map.js +28 -156
- package/dist/integrations/agent/request-lowering.js +66 -141
- package/dist/integrations/agent/runner-dispatch.js +143 -321
- package/dist/integrations/agent/runner.js +54 -14
- package/dist/integrations/lockfile.js +53 -101
- package/dist/llm/client.js +18 -6
- package/dist/llm/embedders/deterministic.js +2 -3
- package/dist/llm/embedders/profile.js +71 -0
- package/dist/llm/embedders/remote.js +11 -17
- package/dist/llm/feature-gate.js +0 -8
- package/dist/llm/index-passes.js +3 -5
- package/dist/llm/memory-infer.js +1 -2
- package/dist/llm/structured-call.js +5 -24
- package/dist/output/generic-render.js +23 -11
- package/dist/output/html-render.js +13 -10
- package/dist/output/render-registry.js +3 -32
- package/dist/output/shapes/helpers.js +25 -38
- package/dist/output/shapes/passthrough.js +1 -9
- package/dist/{indexer/graph/graph-types.js → output/text/bundle-rename.js} +4 -1
- package/dist/output/text/command-format.js +69 -31
- package/dist/output/text/helpers.js +1 -1
- package/dist/output/text/migrate.js +5 -14
- package/dist/output/text/proposal-format.js +48 -3
- package/dist/output/text/show-format.js +13 -17
- package/dist/output/text/workflow-format.js +0 -32
- package/dist/output/text.js +2 -0
- package/dist/registry/factory.js +4 -19
- package/dist/registry/network.js +66 -220
- package/dist/registry/providers/index.js +0 -2
- package/dist/registry/providers/skills-sh.js +3 -14
- package/dist/registry/providers/static-index.js +24 -26
- package/dist/registry/resolve.js +55 -131
- package/dist/scripts/akm-migrate-node.js +42948 -92369
- package/dist/scripts/akm-migrate.js +42935 -92354
- package/dist/setup/registry-stash-loader.js +4 -13
- package/dist/setup/semantic-assets.js +3 -44
- package/dist/setup/setup.js +1 -1
- package/dist/setup/steps/connection.js +5 -6
- package/dist/setup/steps/platforms.js +2 -2
- package/dist/setup/steps/tasks.js +25 -15
- package/dist/sources/provider-factory.js +17 -18
- package/dist/sources/providers/filesystem.js +2 -3
- package/dist/sources/providers/git-install.js +7 -1
- package/dist/sources/providers/git-provider.js +0 -3
- package/dist/sources/providers/git-stash.js +83 -21
- package/dist/sources/providers/npm.js +2 -4
- package/dist/sources/providers/provider-utils.js +5 -10
- package/dist/sources/providers/website.js +0 -2
- package/dist/sources/snapshot-fetchers/website-ingest.js +1 -1
- package/dist/sources/website-url.js +2 -2
- package/dist/storage/database.js +9 -35
- package/dist/storage/repositories/improve-ledger-repository.js +209 -0
- package/dist/storage/repositories/index-connection.js +39 -72
- package/dist/storage/repositories/index-entries-repository.js +131 -129
- package/dist/storage/repositories/index-entry-mapper.js +1 -2
- package/dist/storage/repositories/index-entry-schema.js +101 -268
- package/dist/storage/repositories/index-fts-repository.js +86 -256
- package/dist/storage/repositories/index-links-repository.js +143 -0
- package/dist/storage/repositories/index-llm-cache-repository.js +7 -9
- package/dist/storage/repositories/index-meta-repository.js +6 -4
- package/dist/storage/repositories/index-schema.js +257 -325
- package/dist/storage/repositories/index-utility-repository.js +8 -29
- package/dist/storage/repositories/index-vec-repository.js +133 -414
- package/dist/storage/repositories/outcome-repository.js +2 -1
- package/dist/storage/repositories/proposals-repository.js +104 -1
- package/dist/storage/repositories/registry-index-cache-repository.js +100 -0
- package/dist/storage/repositories/salience-repository.js +1 -19
- package/dist/storage/repositories/task-history-repository.js +26 -4
- package/dist/storage/repositories/workflow-runs-repository.js +53 -244
- package/dist/storage/sqlite-migrations.js +136 -0
- package/dist/storage/sqlite-pragmas.js +11 -9
- package/dist/storage/sqlite-transaction.js +170 -0
- package/dist/storage/state-db-integrity.js +130 -0
- package/dist/tasks/activation-config.js +134 -62
- package/dist/tasks/backends/cron.js +191 -302
- package/dist/tasks/backends/exec-utils.js +2 -5
- package/dist/tasks/backends/launchd.js +141 -748
- package/dist/tasks/backends/schtasks.js +119 -623
- package/dist/tasks/prepare/prepare-support.js +5 -15
- package/dist/tasks/prepare/prepare.js +0 -2
- package/dist/tasks/resolve-akm-bin.js +20 -79
- package/dist/tasks/run/attempt-lifecycle.js +0 -1
- package/dist/tasks/run/load-task.js +1 -1
- package/dist/tasks/scheduler-binding.js +20 -238
- package/dist/tasks/scheduler-invocation.js +136 -244
- package/dist/tasks/scheduler-lock.js +53 -0
- package/dist/tasks/scheduler-sync.js +368 -679
- package/dist/tasks/source/parse-task-source.js +55 -9
- package/dist/tasks/source/task-source-v3-frozen.js +3 -4
- package/dist/tasks/source/task-to-v4.js +464 -88
- package/dist/workflows/authoring/authoring.js +3 -12
- package/dist/workflows/compile.js +211 -0
- package/dist/workflows/concurrency-policy.js +13 -74
- package/dist/workflows/exec/child-invocation.js +3 -17
- package/dist/workflows/exec/child-workflow.js +32 -141
- package/dist/workflows/exec/dispatch-redaction.js +13 -53
- package/dist/workflows/exec/environment.js +98 -0
- package/dist/workflows/exec/exec-unit.js +33 -140
- package/dist/workflows/exec/frozen-judge.js +7 -59
- package/dist/workflows/exec/native-executor.js +82 -341
- package/dist/workflows/exec/param-secrets.js +29 -47
- package/dist/workflows/exec/run-workflow.js +154 -387
- package/dist/workflows/exec/scheduler.js +9 -36
- package/dist/workflows/exec/step-work.js +127 -430
- package/dist/workflows/exec/unit-dispatch.js +11 -63
- package/dist/workflows/exec/unit-writer.js +8 -52
- package/dist/workflows/exec/worktree.js +39 -273
- package/dist/workflows/freeze/child-output-references.js +4 -15
- package/dist/workflows/freeze/environment.js +99 -92
- package/dist/workflows/freeze/freeze.js +172 -0
- package/dist/workflows/freeze/step-values.js +19 -21
- package/dist/workflows/freeze/targets/child-workflow.js +23 -92
- package/dist/workflows/freeze/targets/command.js +10 -33
- package/dist/workflows/freeze/targets/script.js +5 -12
- package/dist/workflows/freeze/targets/shell.js +3 -6
- package/dist/workflows/freeze/targets/task.js +25 -80
- package/dist/workflows/freeze/task-bindings.js +20 -67
- package/dist/workflows/{source-ir/github-yaml.js → github-yaml.js} +88 -206
- package/dist/workflows/ir/params.js +6 -51
- package/dist/workflows/ir/plan-hash.js +2 -34
- package/dist/workflows/parser.js +140 -43
- package/dist/{commands/improve/consolidate/types.js → workflows/plan.js} +2 -1
- package/dist/workflows/renderer.js +36 -69
- package/dist/workflows/resource-limits.js +12 -120
- package/dist/workflows/runtime/agent-identity.js +8 -40
- package/dist/workflows/runtime/run-outputs.js +3 -6
- package/dist/workflows/runtime/run-plan.js +316 -0
- package/dist/workflows/runtime/runs.js +48 -200
- package/dist/workflows/runtime/workflow-asset-loader.js +24 -57
- package/dist/workflows/{source-ir/semantics.js → source-semantics.js} +16 -20
- package/dist/workflows/validate-summary.js +2 -7
- package/docs/integration/bundling-akm.md +49 -42
- package/docs/migration/README.md +1 -0
- package/docs/migration/release-notes/0.9.17.md +43 -0
- package/docs/migration/v0.9.1-to-v0.9.2.md +23 -7
- package/docs/reference/cli.md +232 -135
- package/docs/reference/configuration.md +71 -57
- package/docs/reference/data-and-telemetry.md +20 -21
- package/docs/reference/tasks.md +105 -39
- package/docs/reference/workflow-schema.md +14 -18
- package/docs/reference/workflows.md +6 -9
- package/package.json +1 -1
- package/schemas/akm-config.json +115 -738
- package/schemas/akm-workflow.json +1 -0
- package/dist/assets/improve-strategies/graph-refresh.json +0 -15
- package/dist/assets/prompts/contradiction-judge.md +0 -33
- package/dist/assets/prompts/graph-extract-system.md +0 -1
- package/dist/assets/prompts/graph-extract-user-prompt.md +0 -35
- package/dist/assets/prompts/metadata-enhance-system.md +0 -1
- package/dist/assets/tasks/improve/akm-graph-refresh-weekly.yml +0 -4
- package/dist/commands/health/advisories.js +0 -150
- package/dist/commands/health/metrics.js +0 -329
- package/dist/commands/health/surfaces.js +0 -102
- package/dist/commands/improve/anti-collapse.js +0 -83
- package/dist/commands/improve/collapse-detector.js +0 -432
- package/dist/commands/improve/consolidate/eligibility.js +0 -48
- package/dist/commands/improve/consolidate/merge.js +0 -149
- package/dist/commands/improve/distill/promote-memory.js +0 -291
- package/dist/commands/improve/distill/quality-gate.js +0 -337
- package/dist/commands/improve/eval-cases.js +0 -52
- package/dist/commands/improve/memory/memory-contradiction-detect.js +0 -291
- package/dist/commands/improve/proposal-envelope.js +0 -31
- package/dist/commands/improve/run-context.js +0 -123
- package/dist/commands/improve/shared.js +0 -31
- package/dist/commands/improve/source-identity.js +0 -28
- package/dist/commands/improve/triage.js +0 -96
- package/dist/commands/proposal/drain-policies.js +0 -151
- package/dist/commands/sources/update-transaction.js +0 -220
- package/dist/core/action-contributors.js +0 -28
- package/dist/core/config/config-version-shim.js +0 -101
- package/dist/core/fs-txn.js +0 -405
- package/dist/core/lexical-score.js +0 -25
- package/dist/core/maintenance-barrier.js +0 -167
- package/dist/execution/executable-identity.js +0 -105
- package/dist/execution/guarded-source.js +0 -427
- package/dist/indexer/db/graph-db.js +0 -444
- package/dist/indexer/graph/graph-boost.js +0 -427
- package/dist/indexer/graph/graph-dedup.js +0 -95
- package/dist/indexer/graph/graph-extraction.js +0 -1108
- package/dist/indexer/search/name-match.js +0 -35
- package/dist/indexer/search/ranking-contributors.js +0 -515
- package/dist/indexer/search/ranking-types.js +0 -4
- package/dist/indexer/walk/project-context.js +0 -192
- package/dist/integrations/agent/execution-cascade.js +0 -566
- package/dist/integrations/agent/execution-definitions.js +0 -202
- package/dist/integrations/agent/execution-lowering.js +0 -841
- package/dist/integrations/agent/execution-preparation.js +0 -98
- package/dist/integrations/agent/inline-execution.js +0 -74
- package/dist/llm/graph-extract.js +0 -728
- package/dist/llm/metadata-enhance.js +0 -96
- package/dist/registry/create-provider-registry.js +0 -29
- package/dist/registry/pinned-request-helper.js +0 -247
- package/dist/registry/pinned-transport.js +0 -717
- package/dist/sources/providers/index.js +0 -14
- package/dist/storage/engines/sqlite-migrations.js +0 -271
- package/dist/storage/repositories/canaries-repository.js +0 -107
- package/dist/storage/repositories/embedding-salvage-repository.js +0 -184
- package/dist/storage/repositories/registry-cache.js +0 -113
- package/dist/tasks/scheduler-sync-preview.js +0 -52
- package/dist/tasks/source/task-to-v3.js +0 -507
- package/dist/workflows/freeze/resolve-steps.js +0 -86
- package/dist/workflows/freeze/source-freeze.js +0 -64
- package/dist/workflows/ir/compile.js +0 -321
- package/dist/workflows/ir/environment-v4.js +0 -330
- package/dist/workflows/ir/freeze-v4.js +0 -153
- package/dist/workflows/ir/schema-v4.js +0 -745
- package/dist/workflows/ir/schema.js +0 -354
- package/dist/workflows/program/schema.js +0 -77
- package/dist/workflows/runtime/checkin.js +0 -57
- package/dist/workflows/runtime/plan-classifier.js +0 -196
- package/dist/workflows/runtime/unit-checkin.js +0 -45
- package/dist/workflows/runtime/unit-phases.js +0 -20
- package/dist/workflows/schema.js +0 -4
- package/dist/workflows/source-ir/compile.js +0 -200
- package/dist/workflows/source-ir/program.js +0 -50
- package/dist/workflows/source-ir/result.js +0 -26
- package/dist/workflows/source-ir/schema.js +0 -786
- package/dist/workflows/source-ir/triggers.js +0 -79
- package/dist/workflows/source-ir/uses.js +0 -40
- package/dist/workflows/validator.js +0 -60
|
@@ -6,7 +6,9 @@
|
|
|
6
6
|
*
|
|
7
7
|
* Attempts to patch missing frontmatter fields (`description`, `when_to_use`)
|
|
8
8
|
* on assets that failed schema validation, using a single bounded in-tree LLM
|
|
9
|
-
* call per asset. Results are recorded as `schema_repair_invoked` events
|
|
9
|
+
* call per asset. Results are recorded as `schema_repair_invoked` events; a
|
|
10
|
+
* queued repair's `improve_ledger` row (written with the proposal) keeps the
|
|
11
|
+
* same asset from being re-queued inside the ledger's revisit window.
|
|
10
12
|
*
|
|
11
13
|
* This module is extracted from `improve.ts` to make the repair logic
|
|
12
14
|
* independently testable and to use the shared structured execution seam.
|
|
@@ -18,52 +20,30 @@ import { parseFrontmatter } from "../../core/asset/frontmatter.js";
|
|
|
18
20
|
import { parseRefInput } from "../../core/asset/resolve-ref.js";
|
|
19
21
|
import { authoringRulesForType } from "../../core/authoring-rules.js";
|
|
20
22
|
import { ConfigError } from "../../core/errors.js";
|
|
21
|
-
import { appendEvent
|
|
23
|
+
import { appendEvent } from "../../core/events.js";
|
|
22
24
|
import { parseEmbeddedJsonResponse } from "../../core/parse.js";
|
|
23
25
|
import { resolveStandardsContext } from "../../core/standards/resolve-standards-context.js";
|
|
24
26
|
import { info } from "../../core/warn.js";
|
|
25
27
|
import { resolveAssetPath } from "../../indexer/walk/path-resolver.js";
|
|
26
|
-
import {
|
|
27
|
-
import { callStructured
|
|
28
|
-
import {
|
|
29
|
-
|
|
30
|
-
/**
|
|
31
|
-
const
|
|
32
|
-
/**
|
|
33
|
-
* Per-ref attempt cap (O-6 / #379): maximum number of schema-repair attempts
|
|
34
|
-
* allowed within SCHEMA_REPAIR_WINDOW_MS. Prevents indefinite nightly re-repair
|
|
35
|
-
* of assets whose source content is genuinely ambiguous or inconsistently
|
|
36
|
-
* structured. After cap, the asset is skipped until the window rolls over.
|
|
37
|
-
* Self-Refine arXiv:2303.17651 — iteration must be bounded.
|
|
38
|
-
*/
|
|
39
|
-
const SCHEMA_REPAIR_MAX_ATTEMPTS = 3;
|
|
40
|
-
const SCHEMA_REPAIR_WINDOW_MS = 30 * 24 * 60 * 60 * 1000; // 30 days
|
|
28
|
+
import { assertRunnerCredentials } from "../../integrations/agent/runner-dispatch.js";
|
|
29
|
+
import { callStructured } from "../../llm/structured-call.js";
|
|
30
|
+
import { isLedgerBlocked, ledgerKey, loadLedgerSnapshot } from "../improve/ledger.js";
|
|
31
|
+
import { createProposal } from "../proposal/repository.js";
|
|
32
|
+
/** Proposal source and improve-ledger source for this pass. */
|
|
33
|
+
const SCHEMA_REPAIR_SOURCE = "schema-repair";
|
|
41
34
|
async function classifySchemaRepairs(args) {
|
|
42
35
|
const { failures, startMs, budgetMs, stashDir, findFilePath, isLessonCandidateFn, repairs } = args;
|
|
43
36
|
const eligibleRepairs = [];
|
|
44
37
|
const pendingErrors = [];
|
|
38
|
+
const ledger = loadLedgerSnapshot(undefined, stashDir, [SCHEMA_REPAIR_SOURCE]);
|
|
39
|
+
const nowIso = new Date().toISOString();
|
|
45
40
|
for (const failure of failures) {
|
|
46
41
|
if (Date.now() - startMs >= budgetMs)
|
|
47
42
|
break;
|
|
48
|
-
|
|
49
|
-
const lastRepair = recentRepairs.events
|
|
50
|
-
.filter((event) => event.metadata?.outcome === "queued")
|
|
51
|
-
.sort((a, b) => new Date(b.ts ?? 0).getTime() - new Date(a.ts ?? 0).getTime())[0];
|
|
52
|
-
if (lastRepair?.ts && Date.now() - new Date(lastRepair.ts).getTime() < SCHEMA_REPAIR_COOLDOWN_MS) {
|
|
43
|
+
if (isLedgerBlocked(ledger.get(ledgerKey(SCHEMA_REPAIR_SOURCE, failure.ref)), nowIso)) {
|
|
53
44
|
repairs.push({ ref: failure.ref, reason: failure.reason, outcome: "skipped" });
|
|
54
45
|
continue;
|
|
55
46
|
}
|
|
56
|
-
const windowStart = Date.now() - SCHEMA_REPAIR_WINDOW_MS;
|
|
57
|
-
const attemptsInWindow = recentRepairs.events.filter((event) => event.ts !== undefined && new Date(event.ts).getTime() >= windowStart).length;
|
|
58
|
-
if (attemptsInWindow >= SCHEMA_REPAIR_MAX_ATTEMPTS) {
|
|
59
|
-
repairs.push({
|
|
60
|
-
ref: failure.ref,
|
|
61
|
-
reason: failure.reason,
|
|
62
|
-
outcome: "skipped",
|
|
63
|
-
error: `schema-repair attempt cap reached (${attemptsInWindow}/${SCHEMA_REPAIR_MAX_ATTEMPTS} in 30d window)`,
|
|
64
|
-
});
|
|
65
|
-
continue;
|
|
66
|
-
}
|
|
67
47
|
const filePath = await findFilePath(failure.ref, stashDir);
|
|
68
48
|
if (!filePath || path.extname(filePath).toLowerCase() !== ".md") {
|
|
69
49
|
repairs.push({ ref: failure.ref, reason: failure.reason, outcome: "skipped" });
|
|
@@ -152,112 +132,101 @@ export async function runSchemaRepairPass(failures, options) {
|
|
|
152
132
|
}
|
|
153
133
|
return { repairs, repairedRefs };
|
|
154
134
|
}
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
135
|
+
assertRunnerCredentials(llmRunner);
|
|
136
|
+
for (const repair of pendingErrors) {
|
|
137
|
+
appendEvent({
|
|
138
|
+
eventType: "schema_repair_invoked",
|
|
139
|
+
ref: repair.ref,
|
|
140
|
+
metadata: { outcome: "error", reason: repair.reason, error: repair.error },
|
|
141
|
+
});
|
|
142
|
+
repairs.push(repair);
|
|
143
|
+
}
|
|
144
|
+
for (const { failure, frontmatter: fm, fieldList, messages } of eligibleRepairs) {
|
|
145
|
+
let loweringNotices = [];
|
|
146
|
+
const noticeFields = () => loweringNotices.length > 0 ? { notices: loweringNotices } : {};
|
|
147
|
+
try {
|
|
148
|
+
info(`[improve] schema-repair ${failure.ref} (${fieldList})`);
|
|
149
|
+
const llmResponse = await callStructured({
|
|
150
|
+
feature: "schema_repair",
|
|
151
|
+
runner: llmRunner,
|
|
152
|
+
messages,
|
|
153
|
+
...(chatFn ? { request: { chat: chatFn } } : {}),
|
|
154
|
+
onNotices: (value) => {
|
|
155
|
+
loweringNotices = value;
|
|
156
|
+
},
|
|
157
|
+
parse: (rawResponse) => rawResponse ?? "",
|
|
158
|
+
onError: () => "",
|
|
159
|
+
fallback: "",
|
|
162
160
|
});
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
for (const { failure, frontmatter: fm, fieldList, messages } of eligibleRepairs) {
|
|
166
|
-
let loweringNotices = [];
|
|
167
|
-
const noticeFields = () => loweringNotices.length > 0 ? { notices: loweringNotices } : {};
|
|
168
|
-
try {
|
|
169
|
-
info(`[improve] schema-repair ${failure.ref} (${fieldList})`);
|
|
170
|
-
const llmResponse = await callStructured({
|
|
171
|
-
feature: "schema_repair",
|
|
172
|
-
runner: llmRunner,
|
|
173
|
-
lease: dispatchLease,
|
|
174
|
-
messages,
|
|
175
|
-
...(chatFn ? { request: { chat: chatFn } } : {}),
|
|
176
|
-
onNotices: (value) => {
|
|
177
|
-
loweringNotices = value;
|
|
178
|
-
},
|
|
179
|
-
parse: (rawResponse) => rawResponse ?? "",
|
|
180
|
-
onError: () => "",
|
|
181
|
-
fallback: "",
|
|
182
|
-
});
|
|
183
|
-
const parsed = parseEmbeddedJsonResponse(llmResponse.trim());
|
|
184
|
-
if (!parsed) {
|
|
185
|
-
repairs.push({
|
|
186
|
-
ref: failure.ref,
|
|
187
|
-
reason: failure.reason,
|
|
188
|
-
outcome: "error",
|
|
189
|
-
error: "LLM returned unparseable JSON for schema repair",
|
|
190
|
-
...noticeFields(),
|
|
191
|
-
});
|
|
192
|
-
continue;
|
|
193
|
-
}
|
|
194
|
-
const newFm = { ...fm.data };
|
|
195
|
-
if (parsed.description)
|
|
196
|
-
newFm.description = parsed.description;
|
|
197
|
-
if (parsed.when_to_use)
|
|
198
|
-
newFm.when_to_use = parsed.when_to_use;
|
|
199
|
-
const newContent = assembleAsset(newFm, fm.content);
|
|
200
|
-
// M-3 / #387: Route through proposal queue instead of writing directly to
|
|
201
|
-
// disk. This restores akm's safety invariant — the proposal queue is the
|
|
202
|
-
// only path to a committed asset write. LLM-generated `description` /
|
|
203
|
-
// `when_to_use` fields can be incorrect; routing through the queue makes
|
|
204
|
-
// them human-reviewable before they affect search ranking and curate hints.
|
|
205
|
-
// mem0 open gaps (arXiv:2504.19413) — any LLM write to a memory field
|
|
206
|
-
// should be human-reviewable.
|
|
207
|
-
const proposalResult = createProposal(stashDir, {
|
|
208
|
-
ref: failure.ref,
|
|
209
|
-
source: "schema-repair",
|
|
210
|
-
// §23.6 fingerprint model-id term (WI-6.4).
|
|
211
|
-
modelId: llmRunner.connection.model,
|
|
212
|
-
payload: {
|
|
213
|
-
content: newContent,
|
|
214
|
-
...(Object.keys(newFm).length > 0 ? { frontmatter: newFm } : {}),
|
|
215
|
-
},
|
|
216
|
-
});
|
|
217
|
-
if (isProposalSkipped(proposalResult)) {
|
|
218
|
-
info(`[improve] schema-repair proposal skipped for ${failure.ref}: ${proposalResult.message}`);
|
|
219
|
-
repairs.push({ ref: failure.ref, reason: failure.reason, outcome: "skipped", ...noticeFields() });
|
|
220
|
-
continue;
|
|
221
|
-
}
|
|
222
|
-
info(`[improve] schema-repair queued: ${failure.ref} (proposal id: ${proposalResult.id})`);
|
|
223
|
-
appendEvent({
|
|
224
|
-
eventType: "schema_repair_invoked",
|
|
225
|
-
ref: failure.ref,
|
|
226
|
-
metadata: {
|
|
227
|
-
outcome: "queued",
|
|
228
|
-
reason: failure.reason,
|
|
229
|
-
proposalId: proposalResult.id,
|
|
230
|
-
...noticeFields(),
|
|
231
|
-
},
|
|
232
|
-
});
|
|
161
|
+
const parsed = parseEmbeddedJsonResponse(llmResponse.trim());
|
|
162
|
+
if (!parsed) {
|
|
233
163
|
repairs.push({
|
|
234
164
|
ref: failure.ref,
|
|
235
165
|
reason: failure.reason,
|
|
236
|
-
outcome: "
|
|
237
|
-
|
|
166
|
+
outcome: "error",
|
|
167
|
+
error: "LLM returned unparseable JSON for schema repair",
|
|
238
168
|
...noticeFields(),
|
|
239
169
|
});
|
|
170
|
+
continue;
|
|
240
171
|
}
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
172
|
+
const newFm = { ...fm.data };
|
|
173
|
+
if (parsed.description)
|
|
174
|
+
newFm.description = parsed.description;
|
|
175
|
+
if (parsed.when_to_use)
|
|
176
|
+
newFm.when_to_use = parsed.when_to_use;
|
|
177
|
+
const newContent = assembleAsset(newFm, fm.content);
|
|
178
|
+
// M-3 / #387: Route through proposal queue instead of writing directly to
|
|
179
|
+
// disk. This restores akm's safety invariant — the proposal queue is the
|
|
180
|
+
// only path to a committed asset write. LLM-generated `description` /
|
|
181
|
+
// `when_to_use` fields can be incorrect; routing through the queue makes
|
|
182
|
+
// them human-reviewable before they affect search ranking and curate hints.
|
|
183
|
+
// mem0 open gaps (arXiv:2504.19413) — any LLM write to a memory field
|
|
184
|
+
// should be human-reviewable.
|
|
185
|
+
const proposalResult = createProposal(stashDir, {
|
|
186
|
+
ref: failure.ref,
|
|
187
|
+
source: SCHEMA_REPAIR_SOURCE,
|
|
188
|
+
// Key the ledger row by the ref this pass reads it back under.
|
|
189
|
+
attemptedRefs: [failure.ref],
|
|
190
|
+
payload: {
|
|
191
|
+
content: newContent,
|
|
192
|
+
...(Object.keys(newFm).length > 0 ? { frontmatter: newFm } : {}),
|
|
193
|
+
},
|
|
194
|
+
});
|
|
195
|
+
info(`[improve] schema-repair queued: ${failure.ref} (proposal id: ${proposalResult.id})`);
|
|
196
|
+
appendEvent({
|
|
197
|
+
eventType: "schema_repair_invoked",
|
|
198
|
+
ref: failure.ref,
|
|
199
|
+
metadata: {
|
|
200
|
+
outcome: "queued",
|
|
251
201
|
reason: failure.reason,
|
|
252
|
-
|
|
253
|
-
error: String(e),
|
|
202
|
+
proposalId: proposalResult.id,
|
|
254
203
|
...noticeFields(),
|
|
255
|
-
}
|
|
256
|
-
}
|
|
204
|
+
},
|
|
205
|
+
});
|
|
206
|
+
repairs.push({
|
|
207
|
+
ref: failure.ref,
|
|
208
|
+
reason: failure.reason,
|
|
209
|
+
outcome: "queued",
|
|
210
|
+
proposalId: proposalResult.id,
|
|
211
|
+
...noticeFields(),
|
|
212
|
+
});
|
|
213
|
+
}
|
|
214
|
+
catch (e) {
|
|
215
|
+
if (e instanceof ConfigError)
|
|
216
|
+
throw e;
|
|
217
|
+
appendEvent({
|
|
218
|
+
eventType: "schema_repair_invoked",
|
|
219
|
+
ref: failure.ref,
|
|
220
|
+
metadata: { outcome: "error", reason: failure.reason, error: String(e), ...noticeFields() },
|
|
221
|
+
});
|
|
222
|
+
repairs.push({
|
|
223
|
+
ref: failure.ref,
|
|
224
|
+
reason: failure.reason,
|
|
225
|
+
outcome: "error",
|
|
226
|
+
error: String(e),
|
|
227
|
+
...noticeFields(),
|
|
228
|
+
});
|
|
257
229
|
}
|
|
258
|
-
}
|
|
259
|
-
finally {
|
|
260
|
-
disposeLoweredExecutionDispatchLease(dispatchLease);
|
|
261
230
|
}
|
|
262
231
|
return { repairs, repairedRefs };
|
|
263
232
|
}
|
|
@@ -5,6 +5,7 @@ import fs from "node:fs";
|
|
|
5
5
|
import path from "node:path";
|
|
6
6
|
import { detectAdapterId } from "../../core/adapter/detect-adapter.js";
|
|
7
7
|
import { isBundleSlug } from "../../core/asset/asset-ref.js";
|
|
8
|
+
import { slugForRegistryId, validateExplicitBundleName } from "../../core/bundle-id.js";
|
|
8
9
|
import { isHttpUrl, resolveStashDir } from "../../core/common.js";
|
|
9
10
|
import { bundleEntryToSourceEntry, getSources, installedSourceDescriptor, loadConfig, mutateConfig, resolveSecret, } from "../../core/config/config.js";
|
|
10
11
|
import { ConfigError, UsageError } from "../../core/errors.js";
|
|
@@ -38,7 +39,7 @@ export async function akmAdd(input) {
|
|
|
38
39
|
catch {
|
|
39
40
|
// Not a local ref — fall through to registry install
|
|
40
41
|
}
|
|
41
|
-
return addRegistryStash(ref, stashDir, input.writable, input, input.credential);
|
|
42
|
+
return addRegistryStash(ref, stashDir, input.name, input.writable, input, input.credential);
|
|
42
43
|
}
|
|
43
44
|
/** Add a local directory as a filesystem bundle. */
|
|
44
45
|
async function addLocalSource(ref, sourcePath, stashDir, explicitName, explicitAdapter, position = {}) {
|
|
@@ -49,6 +50,9 @@ async function addLocalSource(ref, sourcePath, stashDir, explicitName, explicitA
|
|
|
49
50
|
mutateConfig((config) => {
|
|
50
51
|
const existing = bundleKeyForPath(config, resolvedPath);
|
|
51
52
|
if (existing) {
|
|
53
|
+
if (explicitName !== undefined) {
|
|
54
|
+
validateExplicitBundleName(config.bundles ?? {}, explicitName, existing);
|
|
55
|
+
}
|
|
52
56
|
bundleKey = existing;
|
|
53
57
|
const current = config.bundles?.[existing];
|
|
54
58
|
if (current?.components && explicitAdapter === undefined)
|
|
@@ -62,6 +66,11 @@ async function addLocalSource(ref, sourcePath, stashDir, explicitName, explicitA
|
|
|
62
66
|
return { ...config, bundles };
|
|
63
67
|
}
|
|
64
68
|
const bundles = { ...(config.bundles ?? {}) };
|
|
69
|
+
// D6: an explicit `--name` is a contract on this (local) add path — validated
|
|
70
|
+
// strictly before nextBundleKey derives a key, since that shared helper is also
|
|
71
|
+
// used by the out-of-scope `akm source add` (`addStash`) and stays forgiving.
|
|
72
|
+
if (explicitName !== undefined)
|
|
73
|
+
validateExplicitBundleName(bundles, explicitName);
|
|
65
74
|
bundleKey = nextBundleKey(bundles, explicitName, resolvedPath);
|
|
66
75
|
const entry = {
|
|
67
76
|
path: resolvedPath,
|
|
@@ -75,6 +84,7 @@ async function addLocalSource(ref, sourcePath, stashDir, explicitName, explicitA
|
|
|
75
84
|
schemaVersion: 1,
|
|
76
85
|
bundleDir: stashDir,
|
|
77
86
|
ref,
|
|
87
|
+
bundleId: bundleKey,
|
|
78
88
|
sourceAdded: {
|
|
79
89
|
type: "filesystem",
|
|
80
90
|
path: resolvedPath,
|
|
@@ -100,10 +110,29 @@ async function addWebsiteSource(ref, stashDir, name, options, position = {}) {
|
|
|
100
110
|
const maxPages = numberOption(options?.maxPages);
|
|
101
111
|
const maxDepth = numberOption(options?.maxDepth);
|
|
102
112
|
let entry;
|
|
113
|
+
let bundleId = "";
|
|
103
114
|
mutateConfig((config) => {
|
|
104
115
|
const bundles = { ...(config.bundles ?? {}) };
|
|
105
116
|
const existingKey = bundleKeyForUrl(config, normalizedUrl);
|
|
106
|
-
|
|
117
|
+
if (existingKey && name !== undefined) {
|
|
118
|
+
validateExplicitBundleName(bundles, name, existingKey);
|
|
119
|
+
}
|
|
120
|
+
// An explicit `--name` is a contract (D6) — validated strictly and used
|
|
121
|
+
// as-is, never silently substituted. A DERIVED default (no --name) keeps
|
|
122
|
+
// the forgiving `deriveBundleId` fallback, so a dotted hostname or a
|
|
123
|
+
// URL collision still mints a usable id instead of erroring.
|
|
124
|
+
let key;
|
|
125
|
+
if (existingKey) {
|
|
126
|
+
key = existingKey;
|
|
127
|
+
}
|
|
128
|
+
else if (name !== undefined) {
|
|
129
|
+
validateExplicitBundleName(bundles, name);
|
|
130
|
+
key = name;
|
|
131
|
+
}
|
|
132
|
+
else {
|
|
133
|
+
key = deriveBundleId(toWebsiteName(normalizedUrl), normalizedUrl, new Set(Object.keys(bundles)));
|
|
134
|
+
}
|
|
135
|
+
bundleId = key;
|
|
107
136
|
// Merge onto the existing descriptor rather than replacing it: re-running
|
|
108
137
|
// `bundle add` for a URL that already has a bundle would otherwise drop
|
|
109
138
|
// respectRobots / refresh, silently restoring default robots enforcement
|
|
@@ -140,6 +169,7 @@ async function addWebsiteSource(ref, stashDir, name, options, position = {}) {
|
|
|
140
169
|
schemaVersion: 1,
|
|
141
170
|
bundleDir: stashDir,
|
|
142
171
|
ref,
|
|
172
|
+
bundleId,
|
|
143
173
|
sourceAdded: {
|
|
144
174
|
type: "website",
|
|
145
175
|
url: normalizedUrl,
|
|
@@ -162,7 +192,7 @@ async function addWebsiteSource(ref, stashDir, name, options, position = {}) {
|
|
|
162
192
|
* Install a stash from a registry (npm, github, git) by dispatching to the
|
|
163
193
|
* matching syncable provider and persisting the lock entry.
|
|
164
194
|
*/
|
|
165
|
-
async function addRegistryStash(ref, stashDir, writable, position = {}, credentialRef) {
|
|
195
|
+
async function addRegistryStash(ref, stashDir, explicitName, writable, position = {}, credentialRef) {
|
|
166
196
|
const parsedRef = parseRegistryRef(ref);
|
|
167
197
|
if (writable === true && parsedRef.source !== "git" && parsedRef.source !== "github") {
|
|
168
198
|
throw new ConfigError("writable: true is only supported on filesystem and git sources", "INVALID_CONFIG_FILE");
|
|
@@ -172,6 +202,14 @@ async function addRegistryStash(ref, stashDir, writable, position = {}, credenti
|
|
|
172
202
|
}
|
|
173
203
|
const currentConfig = loadConfig();
|
|
174
204
|
const existingBundleKey = findInstalledBundleKey(currentConfig.bundles ?? {}, parsedRef.id);
|
|
205
|
+
// D6: validate an explicit `--name` before any network sync or write — an
|
|
206
|
+
// illegal name, a name already taken by a different bundle, or re-adding
|
|
207
|
+
// this same install under a different name than it already carries must
|
|
208
|
+
// fail loudly here, not mint a `-<hash>` fallback deep inside the config
|
|
209
|
+
// mutation below.
|
|
210
|
+
if (explicitName !== undefined) {
|
|
211
|
+
validateExplicitBundleName(currentConfig.bundles ?? {}, explicitName, existingBundleKey);
|
|
212
|
+
}
|
|
175
213
|
const existingBundle = existingBundleKey ? currentConfig.bundles?.[existingBundleKey] : undefined;
|
|
176
214
|
const priorLock = existingBundleKey ? readLockfile().find((entry) => entry.id === existingBundleKey) : undefined;
|
|
177
215
|
const existingWritable = Object.values(existingBundle?.components ?? {})[0]?.writable ?? existingBundle?.writable === true;
|
|
@@ -200,7 +238,7 @@ async function addRegistryStash(ref, stashDir, writable, position = {}, credenti
|
|
|
200
238
|
cacheDir: synced.cacheDir,
|
|
201
239
|
installedAt: synced.syncedAt,
|
|
202
240
|
writable: synced.writable,
|
|
203
|
-
}, position, credentialRef);
|
|
241
|
+
}, position, credentialRef, explicitName);
|
|
204
242
|
// The prior materialized root (if this is a re-install) — read BEFORE the lock
|
|
205
243
|
// upsert overwrites it, so a moved cache root can be cleaned afterwards.
|
|
206
244
|
const priorLocalRoot = priorLock?.localRoot;
|
|
@@ -229,6 +267,8 @@ async function addRegistryStash(ref, stashDir, writable, position = {}, credenti
|
|
|
229
267
|
schemaVersion: 1,
|
|
230
268
|
bundleDir: stashDir,
|
|
231
269
|
ref,
|
|
270
|
+
bundleId,
|
|
271
|
+
registryId: synced.id,
|
|
232
272
|
installed: {
|
|
233
273
|
id: synced.id,
|
|
234
274
|
source: synced.source,
|
|
@@ -258,14 +298,15 @@ async function addRegistryStash(ref, stashDir, writable, position = {}, credenti
|
|
|
258
298
|
* (spec §10.1 / §10.2 desired/resolved split). The bundle carries ONLY the
|
|
259
299
|
* desired descriptor (git/npm locator + preserved `registryId` + `writable`);
|
|
260
300
|
* the resolved cache root belongs exclusively in the lock (written by callers
|
|
261
|
-
* via {@link upsertLockEntry} with the returned `bundleId`).
|
|
301
|
+
* via {@link upsertLockEntry} with the returned `bundleId`). A new install is
|
|
302
|
+
* keyed by `explicitName` (the CLI's `--name`) when given. Returns the config
|
|
262
303
|
* plus the derived bundle id so the caller keys its lock entry identically.
|
|
263
304
|
*/
|
|
264
|
-
export function upsertInstalledRegistryEntry(entry, position = {}, credential) {
|
|
305
|
+
export function upsertInstalledRegistryEntry(entry, position = {}, credential, explicitName) {
|
|
265
306
|
let bundleId = entry.id;
|
|
266
307
|
const config = mutateConfig((current) => {
|
|
267
308
|
const bundles = { ...(current.bundles ?? {}) };
|
|
268
|
-
bundleId = resolveInstalledBundleKey(bundles, entry.id, entry.stashRoot);
|
|
309
|
+
bundleId = resolveInstalledBundleKey(bundles, entry.id, entry.stashRoot, explicitName);
|
|
269
310
|
const existingComponents = bundles[bundleId]?.components;
|
|
270
311
|
const components = existingComponents
|
|
271
312
|
? Object.fromEntries(Object.entries(existingComponents).map(([id, component]) => [
|
|
@@ -334,15 +375,24 @@ function findInstalledBundleKey(bundles, installId) {
|
|
|
334
375
|
}
|
|
335
376
|
/**
|
|
336
377
|
* The stable bundle key for a registry install: reuse the existing bundle for
|
|
337
|
-
* this install id (so re-installs keep the same key
|
|
338
|
-
*
|
|
339
|
-
*
|
|
378
|
+
* this install id (so re-installs keep the same key — a caller-visible name
|
|
379
|
+
* mismatch was already rejected upstream, by {@link validateExplicitBundleName}
|
|
380
|
+
* in `addRegistryStash`, before any write). Otherwise an explicit `--name`
|
|
381
|
+
* (D6) is a contract — validated strictly and used as-is, never silently
|
|
382
|
+
* substituted. Without one, a batch-unique key is derived via the shared
|
|
383
|
+
* {@link deriveBundleId} (D-R5) from the package/repo name the install id
|
|
384
|
+
* names rather than the basename of the materialized cache directory
|
|
385
|
+
* (`extracted`) — unique against the currently-configured bundle keys.
|
|
340
386
|
*/
|
|
341
|
-
function resolveInstalledBundleKey(bundles, installId, stashRoot) {
|
|
387
|
+
function resolveInstalledBundleKey(bundles, installId, stashRoot, explicitName) {
|
|
342
388
|
const existing = findInstalledBundleKey(bundles, installId);
|
|
343
389
|
if (existing)
|
|
344
390
|
return existing;
|
|
345
|
-
|
|
391
|
+
if (explicitName !== undefined) {
|
|
392
|
+
validateExplicitBundleName(bundles, explicitName);
|
|
393
|
+
return explicitName;
|
|
394
|
+
}
|
|
395
|
+
return deriveBundleId(slugForRegistryId(installId), path.resolve(stashRoot), new Set(Object.keys(bundles)));
|
|
346
396
|
}
|
|
347
397
|
function toReadableId(resolvedPath) {
|
|
348
398
|
const home = process.env.HOME ?? process.env.USERPROFILE ?? "";
|
|
@@ -3,6 +3,7 @@
|
|
|
3
3
|
// file, You can obtain one at https://mozilla.org/MPL/2.0/.
|
|
4
4
|
import path from "node:path";
|
|
5
5
|
import { detectAdapterId } from "../../core/adapter/detect-adapter.js";
|
|
6
|
+
import { validateExplicitBundleName } from "../../core/bundle-id.js";
|
|
6
7
|
import { isRemoteUrl } from "../../core/common.js";
|
|
7
8
|
import { bundleEntryToSourceEntry, bundlesToSourceEntries, getSources, mutateConfig } from "../../core/config/config.js";
|
|
8
9
|
import { ConfigError, UsageError } from "../../core/errors.js";
|
|
@@ -51,7 +52,10 @@ export function addStash(opts) {
|
|
|
51
52
|
const bundles = { ...(config.bundles ?? {}) };
|
|
52
53
|
let key;
|
|
53
54
|
if (useDescriptorPath) {
|
|
54
|
-
|
|
55
|
+
const existingKey = bundleKeyForUrl(config, target);
|
|
56
|
+
if (name !== undefined)
|
|
57
|
+
validateExplicitBundleName(bundles, name, existingKey);
|
|
58
|
+
if (existingKey) {
|
|
55
59
|
const already = targetIsUrl ? "Source URL already configured" : "Source already configured";
|
|
56
60
|
result = { sources: getSources(config), added: false, message: already };
|
|
57
61
|
return config;
|
|
@@ -69,7 +73,10 @@ export function addStash(opts) {
|
|
|
69
73
|
}
|
|
70
74
|
else {
|
|
71
75
|
const resolvedPath = path.resolve(target);
|
|
72
|
-
|
|
76
|
+
const existingKey = bundleKeyForPath(config, resolvedPath);
|
|
77
|
+
if (name !== undefined)
|
|
78
|
+
validateExplicitBundleName(bundles, name, existingKey);
|
|
79
|
+
if (existingKey) {
|
|
73
80
|
result = { sources: getSources(config), added: false, message: "Source path already configured" };
|
|
74
81
|
return config;
|
|
75
82
|
}
|
|
@@ -33,6 +33,7 @@ import * as p from "../../cli/clack.js";
|
|
|
33
33
|
import { getParsedInvocation } from "../../cli/invocation.js";
|
|
34
34
|
import { defineJsonCommand, GLOBAL_OUTPUT_ARGS, output, parseAllFlagValues, runWithJsonErrors } from "../../cli/shared.js";
|
|
35
35
|
import { assertFlatAssetName } from "../../core/asset/asset-create.js";
|
|
36
|
+
import { placementTypes } from "../../core/asset/asset-placement.js";
|
|
36
37
|
import { parseFrontmatter } from "../../core/asset/frontmatter.js";
|
|
37
38
|
import { isHttpUrl, resolveStashDir } from "../../core/common.js";
|
|
38
39
|
import { loadConfig } from "../../core/config/config.js";
|
|
@@ -45,6 +46,7 @@ import { resolveWriteTarget } from "../../core/write-source.js";
|
|
|
45
46
|
import { releaseIndexRebuildLock, tryAcquireIndexRebuildLock } from "../../indexer/index-rebuild-lock.js";
|
|
46
47
|
import { akmIndex } from "../../indexer/indexer.js";
|
|
47
48
|
import { getHyphenatedBoolean, getOutputMode } from "../../output/context.js";
|
|
49
|
+
import { pkgVersion } from "../../version.js";
|
|
48
50
|
import { inferAssetName, mergeXrefsIntoContent, readKnowledgeInput, resolveSupersedesForWrite, resolveSupersedesWriteTarget, resolveXrefsForWrite, writeMarkdownAsset, } from "../read/knowledge.js";
|
|
49
51
|
import { assembleInfo } from "./info.js";
|
|
50
52
|
/** Matches the high-frequency per-committed-batch progress line (#954), excluded from non-verbose JSON-mode stderr. */
|
|
@@ -71,7 +73,7 @@ export const indexCommand = defineCommand({
|
|
|
71
73
|
},
|
|
72
74
|
reembed: {
|
|
73
75
|
type: "boolean",
|
|
74
|
-
description: "
|
|
76
|
+
description: "Discard every stored vector and re-embed all entries under the configured model.",
|
|
75
77
|
default: false,
|
|
76
78
|
},
|
|
77
79
|
"skip-if-locked": {
|
|
@@ -83,10 +85,10 @@ export const indexCommand = defineCommand({
|
|
|
83
85
|
async run({ args }) {
|
|
84
86
|
await runWithJsonErrors(async () => {
|
|
85
87
|
if (getHyphenatedBoolean(args, "enrich") || getParsedInvocation().getFlagValue("--enrich") !== undefined) {
|
|
86
|
-
throw new UsageError("`akm index --enrich` has been removed.
|
|
88
|
+
throw new UsageError("`akm index --enrich` has been removed. Metadata enrichment during indexing is retired; it never runs.");
|
|
87
89
|
}
|
|
88
90
|
if (getHyphenatedBoolean(args, "re-enrich") || getParsedInvocation().getFlagValue("--re-enrich") !== undefined) {
|
|
89
|
-
throw new UsageError("`akm index --re-enrich` has been removed.
|
|
91
|
+
throw new UsageError("`akm index --re-enrich` has been removed. Metadata enrichment during indexing is retired; there is nothing to re-enrich.");
|
|
90
92
|
}
|
|
91
93
|
// #956: opt-in, non-blocking rebuild lock — never gates a human-typed
|
|
92
94
|
// `akm index` (it only warns and contends), but a scheduled/opportunistic
|
|
@@ -181,7 +183,25 @@ export const indexCommand = defineCommand({
|
|
|
181
183
|
export const infoCommand = defineJsonCommand({
|
|
182
184
|
meta: { name: "info", description: "Show system capabilities, configuration, and index stats" },
|
|
183
185
|
run() {
|
|
184
|
-
|
|
186
|
+
// `akm info` must behave like a help command: always exit 0 with a
|
|
187
|
+
// report. `assembleInfo()` already degrades what it reasonably can
|
|
188
|
+
// per-section; this is the final backstop for whatever it can't (e.g.
|
|
189
|
+
// every path resolver needs an environment variable, such as `HOME`,
|
|
190
|
+
// that this process genuinely does not have) — still a report, with
|
|
191
|
+
// whatever is cheap and safe enough to never itself throw.
|
|
192
|
+
let result;
|
|
193
|
+
try {
|
|
194
|
+
result = assembleInfo();
|
|
195
|
+
}
|
|
196
|
+
catch (err) {
|
|
197
|
+
result = {
|
|
198
|
+
schemaVersion: 1,
|
|
199
|
+
version: pkgVersion,
|
|
200
|
+
error: err instanceof Error ? err.message : String(err),
|
|
201
|
+
assetTypes: [...placementTypes()],
|
|
202
|
+
searchModes: ["fts"],
|
|
203
|
+
};
|
|
204
|
+
}
|
|
185
205
|
output("info", result);
|
|
186
206
|
},
|
|
187
207
|
});
|
|
@@ -34,11 +34,10 @@
|
|
|
34
34
|
* `with.content`, an inline `akm/command` prompt body, or a stored
|
|
35
35
|
* command's own rendered content is never read, let alone printed;
|
|
36
36
|
* - effective execution settings (engine/model/timeout) reuse
|
|
37
|
-
* `
|
|
38
|
-
*
|
|
39
|
-
*
|
|
40
|
-
*
|
|
41
|
-
* EMPTY command-layer values map, instead of the task's real referenced
|
|
37
|
+
* `resolveExecution` (`src/integrations/agent/execution.ts`) — the SAME
|
|
38
|
+
* resolution entry point every command/persona invocation goes through —
|
|
39
|
+
* fed a BLANK inline placeholder command (`createInlineResolvedCommand`)
|
|
40
|
+
* and an EMPTY command-layer values map, instead of the task's real referenced
|
|
42
41
|
* command source. This is a deliberate, documented trade-off: a
|
|
43
42
|
* referenced command's OWN frontmatter overrides (its own `engine:`/
|
|
44
43
|
* `model:`, if any) do not contribute a layer here, in exchange for never
|
|
@@ -70,9 +69,8 @@
|
|
|
70
69
|
* `suppliedInputs`). Do not paste this command's output into an untrusted
|
|
71
70
|
* place on the assumption that it can never contain a credential.
|
|
72
71
|
*
|
|
73
|
-
* Field-level execution provenance is READ from `
|
|
74
|
-
* `
|
|
75
|
-
* this module is a CONSUMER of the one common cascade resolver, never a
|
|
72
|
+
* Field-level execution provenance is READ from `resolveExecution`'s own
|
|
73
|
+
* `provenance` — this module is a CONSUMER of the one common resolver, never a
|
|
76
74
|
* second resolver: it never re-derives engine/model precedence itself.
|
|
77
75
|
*/
|
|
78
76
|
import fs from "node:fs";
|
|
@@ -83,7 +81,7 @@ import { NotFoundError } from "../../core/errors.js";
|
|
|
83
81
|
import { applyInputDefaults, materializeInputFlags, } from "../../execution/input-contract.js";
|
|
84
82
|
import { createInlineResolvedCommand } from "../../execution/resolved-request.js";
|
|
85
83
|
import { resolveAdapterConceptOwner } from "../../indexer/lookup/adapter-concept-owner.js";
|
|
86
|
-
import {
|
|
84
|
+
import { resolveExecution } from "../../integrations/agent/execution.js";
|
|
87
85
|
import { isSchedulerRefEnabled } from "../../tasks/activation-config.js";
|
|
88
86
|
import { parseTaskSource } from "../../tasks/source/parse-task-source.js";
|
|
89
87
|
import { projectTaskSourceV4 } from "../../tasks/source/project-v4.js";
|
|
@@ -209,10 +207,9 @@ function resolveExecutionSettings(document) {
|
|
|
209
207
|
if (!isCommandTarget(document))
|
|
210
208
|
return { provenance: {} };
|
|
211
209
|
const current = currentExecutionValues(document);
|
|
212
|
-
const prepared =
|
|
210
|
+
const prepared = resolveExecution({
|
|
213
211
|
command: createInlineResolvedCommand({ template: "", content: "" }),
|
|
214
212
|
config: loadConfig(),
|
|
215
|
-
invocationKind: "task",
|
|
216
213
|
commandLayer: { id: "task-explain", values: {} },
|
|
217
214
|
...(Object.keys(current).length > 0 ? { current } : {}),
|
|
218
215
|
});
|
|
@@ -225,7 +222,7 @@ function resolveExecutionSettings(document) {
|
|
|
225
222
|
},
|
|
226
223
|
...(prepared.request.model !== undefined ? { model: prepared.request.model } : {}),
|
|
227
224
|
...(prepared.request.runtime.timeoutMs !== undefined ? { timeoutMs: prepared.request.runtime.timeoutMs } : {}),
|
|
228
|
-
provenance: prepared.
|
|
225
|
+
provenance: prepared.provenance,
|
|
229
226
|
};
|
|
230
227
|
}
|
|
231
228
|
/**
|
|
@@ -272,7 +269,7 @@ export async function akmTaskExplain(ref, options = {}) {
|
|
|
272
269
|
const materializedInputs = materializeInputFlags(inputContract, options.inputFlags ?? [], TASK_INPUT_DIAGNOSTICS);
|
|
273
270
|
const defaultedInputs = applyInputDefaults(inputContract, materializedInputs);
|
|
274
271
|
const document = projectTaskSourceV4(parsed.v4);
|
|
275
|
-
const enabled = isSchedulerRefEnabled(loadConfig(),
|
|
272
|
+
const enabled = isSchedulerRefEnabled(loadConfig(), makeBundleRef(bundle.source.name, taskConceptId));
|
|
276
273
|
const schedule = parsed.v4.schedule.map((entry) => ({
|
|
277
274
|
ordinal: entry.ordinal,
|
|
278
275
|
cron: entry.cron,
|