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
|
@@ -11,6 +11,7 @@
|
|
|
11
11
|
import fs from "node:fs";
|
|
12
12
|
import path from "node:path";
|
|
13
13
|
import { parse as yamlParse } from "yaml";
|
|
14
|
+
import { detectAdapterId } from "../../core/adapter/detect-adapter.js";
|
|
14
15
|
import { assertFlatAssetName, combineCreatePath, normalizeCreateSubPath } from "../../core/asset/asset-create.js";
|
|
15
16
|
import { assetPathForName, stashDirFor } from "../../core/asset/asset-placement.js";
|
|
16
17
|
import { assembleAsset } from "../../core/asset/asset-serialize.js";
|
|
@@ -19,11 +20,14 @@ import { conceptIdFromTypeName, parseRefInput } from "../../core/asset/resolve-r
|
|
|
19
20
|
import { isHttpUrl, isWithin, resolveStashDir, tryReadStdinText } from "../../core/common.js";
|
|
20
21
|
import { loadConfig } from "../../core/config/config.js";
|
|
21
22
|
import { UsageError } from "../../core/errors.js";
|
|
23
|
+
import { resolveBundleWriteTarget, resolveMutationTarget } from "../../core/mutation-target.js";
|
|
22
24
|
import { resolveStashStandards } from "../../core/standards/resolve-stash-standards.js";
|
|
23
25
|
import { warn } from "../../core/warn.js";
|
|
24
26
|
import { commitWriteTargetBoundary, formatRefForMessage, recordWriteTargetPath, resolveWriteTarget, writeAssetToSource, } from "../../core/write-source.js";
|
|
25
27
|
import { indexWrittenAssets } from "../../indexer/index-written-assets.js";
|
|
28
|
+
import { deriveInstallations, slugForPath } from "../../indexer/installations.js";
|
|
26
29
|
import { resolveSourceEntries } from "../../indexer/search/search-source.js";
|
|
30
|
+
import { storeSecretResolver } from "../../sources/snapshot-fetchers/secret-seam.js";
|
|
27
31
|
import { fetchWebsiteMarkdownSnapshot, shouldAllowPrivateWebsiteUrlForTests, } from "../../sources/snapshot-fetchers/website-ingest.js";
|
|
28
32
|
import { writeSupersededEdge } from "../improve/memory/memory-belief.js";
|
|
29
33
|
import { refToRelPath, resolveRefPathInStash } from "../lint/base-linter.js";
|
|
@@ -116,19 +120,16 @@ export async function readKnowledgeInput(source, options) {
|
|
|
116
120
|
return readKnowledgeContent(source);
|
|
117
121
|
const snapshot = await fetchWebsiteMarkdownSnapshot(source, {
|
|
118
122
|
stashDir: options?.stashDir,
|
|
123
|
+
resolveSecret: storeSecretResolver.resolveSecret,
|
|
119
124
|
allowPrivateHosts: options?.allowPrivateHosts ?? shouldAllowPrivateWebsiteUrlForTests(source),
|
|
120
125
|
});
|
|
121
126
|
return { content: snapshot.content, preferredName: snapshot.preferredName };
|
|
122
127
|
}
|
|
123
128
|
/**
|
|
124
129
|
* Parse a `--xref` / `--supersedes` value through the new-grammar input parser
|
|
125
|
-
* (`parseRefInput`, the
|
|
126
|
-
*
|
|
127
|
-
*
|
|
128
|
-
* arm is retired — `--xref`/`--supersedes` take the conceptId form. A `local//`
|
|
129
|
-
* origin is accepted (it names the same local resolution this validator
|
|
130
|
-
* performs, mirroring lint's `local//` strip); any other origin is rejected —
|
|
131
|
-
* write-time validation only resolves local stash roots.
|
|
130
|
+
* (`parseRefInput`, the `[bundle//]conceptId` grammar) so malformed values get a
|
|
131
|
+
* structured error instead of a misleading "did not resolve". Bundle qualifiers
|
|
132
|
+
* are retained for exact source membership checks.
|
|
132
133
|
*/
|
|
133
134
|
function parseWriteRef(raw, flag) {
|
|
134
135
|
let parsed;
|
|
@@ -139,21 +140,21 @@ function parseWriteRef(raw, flag) {
|
|
|
139
140
|
const message = error instanceof Error ? error.message : String(error);
|
|
140
141
|
throw new UsageError(`${flag} "${raw}" is not a valid asset ref: ${message}`, "INVALID_FLAG_VALUE", `Refs use the conceptId form, e.g. ${flag} knowledge/auth-flow.`);
|
|
141
142
|
}
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
143
|
+
// Bundle qualifiers remain explicit so duplicate names resolve in the named
|
|
144
|
+
// source.
|
|
145
|
+
const conceptId = conceptIdFromTypeName(parsed.type, parsed.name);
|
|
146
|
+
const origin = parsed.origin;
|
|
147
|
+
return {
|
|
148
|
+
ref: origin ? `${origin}//${conceptId}` : conceptId,
|
|
149
|
+
type: parsed.type,
|
|
150
|
+
name: parsed.name,
|
|
151
|
+
...(origin ? { origin } : {}),
|
|
152
|
+
};
|
|
151
153
|
}
|
|
152
154
|
/**
|
|
153
155
|
* Trim, parse, and dedupe `--xref` / `--supersedes` flag values, in argv
|
|
154
|
-
* order. Parsing comes
|
|
155
|
-
*
|
|
156
|
-
* `knowledge:x`) collapse into one canonical entry.
|
|
156
|
+
* order. Parsing comes before deduplication so normalized spellings collapse
|
|
157
|
+
* into one canonical entry.
|
|
157
158
|
*/
|
|
158
159
|
function parseWriteRefs(rawRefs, flag) {
|
|
159
160
|
const parsedRefs = [];
|
|
@@ -167,26 +168,26 @@ function parseWriteRefs(rawRefs, flag) {
|
|
|
167
168
|
}
|
|
168
169
|
return parsedRefs;
|
|
169
170
|
}
|
|
170
|
-
/**
|
|
171
|
-
* The ONE root set write-time ref validation resolves against, shared by
|
|
172
|
-
* `resolveXrefsForWrite` and `resolveSupersedesForWrite` so the two flags can
|
|
173
|
-
* never disagree on what a ref resolves to:
|
|
174
|
-
*
|
|
175
|
-
* 1. the resolved write target (mutable),
|
|
176
|
-
* 2. the primary working stash when it is a different directory (mutable) —
|
|
177
|
-
* a `--target`/`defaultWriteTarget` write must still see working-stash
|
|
178
|
-
* assets, which `resolveSourceEntries(writeTarget)` alone omits,
|
|
179
|
-
* 3. every other configured source (read-only for demotion purposes).
|
|
180
|
-
*
|
|
181
|
-
* NOTE: this is deliberately a superset of lint's root set (lint roots at the
|
|
182
|
-
* working stash; this roots at the write target AND the working stash).
|
|
183
|
-
*/
|
|
184
171
|
function resolveWriteRefRoots(target) {
|
|
185
172
|
const cfg = loadConfig();
|
|
186
|
-
|
|
173
|
+
let writeTarget;
|
|
174
|
+
try {
|
|
175
|
+
writeTarget = resolveWriteTarget(cfg, target);
|
|
176
|
+
}
|
|
177
|
+
catch (error) {
|
|
178
|
+
if (!target)
|
|
179
|
+
throw error;
|
|
180
|
+
try {
|
|
181
|
+
writeTarget = resolveBundleWriteTarget(cfg, target);
|
|
182
|
+
}
|
|
183
|
+
catch {
|
|
184
|
+
throw error;
|
|
185
|
+
}
|
|
186
|
+
}
|
|
187
|
+
const stashRoot = writeTarget.source.path;
|
|
187
188
|
let workingStash;
|
|
188
189
|
try {
|
|
189
|
-
workingStash = resolveStashDir(
|
|
190
|
+
workingStash = resolveStashDir();
|
|
190
191
|
}
|
|
191
192
|
catch {
|
|
192
193
|
// No working stash configured — the write target alone.
|
|
@@ -194,15 +195,51 @@ function resolveWriteRefRoots(target) {
|
|
|
194
195
|
const mutableRoots = [stashRoot];
|
|
195
196
|
if (workingStash && path.resolve(workingStash) !== path.resolve(stashRoot))
|
|
196
197
|
mutableRoots.push(workingStash);
|
|
197
|
-
const
|
|
198
|
-
|
|
198
|
+
const namedSources = resolveSourceEntries(undefined, cfg);
|
|
199
|
+
const installations = deriveInstallations(namedSources);
|
|
200
|
+
const bundleByPath = new Map(namedSources.flatMap((source, index) => {
|
|
201
|
+
const bundleId = installations[index]?.id;
|
|
202
|
+
return bundleId ? [[path.resolve(source.path), bundleId]] : [];
|
|
203
|
+
}));
|
|
204
|
+
const otherSources = namedSources.filter((s) => !mutableRoots.some((m) => path.resolve(m) === path.resolve(s.path)) && fs.existsSync(s.path));
|
|
205
|
+
const roots = [
|
|
206
|
+
...mutableRoots
|
|
207
|
+
.filter((p) => fs.existsSync(p))
|
|
208
|
+
.map((p) => {
|
|
209
|
+
const source = namedSources.find((candidate) => path.resolve(candidate.path) === path.resolve(p));
|
|
210
|
+
const mutable = path.resolve(p) === path.resolve(stashRoot)
|
|
211
|
+
? writeTarget.source.adapterId === "akm"
|
|
212
|
+
: source?.writable === true && (source.adapterId ?? detectAdapterId(p)) === "akm";
|
|
213
|
+
return {
|
|
214
|
+
path: p,
|
|
215
|
+
source,
|
|
216
|
+
bundleId: bundleByPath.get(path.resolve(p)) ?? slugForPath(p),
|
|
217
|
+
mutable,
|
|
218
|
+
};
|
|
219
|
+
}),
|
|
220
|
+
...otherSources.map((source) => ({
|
|
221
|
+
path: source.path,
|
|
222
|
+
source,
|
|
223
|
+
bundleId: bundleByPath.get(path.resolve(source.path)) ?? slugForPath(source.path),
|
|
224
|
+
mutable: false,
|
|
225
|
+
})),
|
|
226
|
+
];
|
|
227
|
+
return { roots };
|
|
228
|
+
}
|
|
229
|
+
function rootsForWriteRef(parsed, roots) {
|
|
230
|
+
if (!parsed.origin)
|
|
231
|
+
return roots;
|
|
232
|
+
return roots.filter((root) => root.bundleId === parsed.origin);
|
|
233
|
+
}
|
|
234
|
+
function canonicalWriteRef(parsed, bundleId) {
|
|
235
|
+
return `${bundleId}//${conceptIdFromTypeName(parsed.type, parsed.name)}`;
|
|
199
236
|
}
|
|
200
237
|
/**
|
|
201
238
|
* True when write-time validation must FAIL OPEN for this ref type — exactly
|
|
202
239
|
* lint's `checkMissingRefs` policy (`if (relPath === null) continue`,
|
|
203
|
-
* base-linter.ts): a type the slug resolver cannot map to a path (
|
|
204
|
-
* contract-pinned to return null) is accepted without an existence check
|
|
205
|
-
* rather than being unwinnable.
|
|
240
|
+
* base-linter.ts): a type the slug resolver cannot map to a path (script refs
|
|
241
|
+
* are contract-pinned to return null) is accepted without an existence check
|
|
242
|
+
* rather than being unwinnable. Workflow refs never fail open — they resolve
|
|
206
243
|
* stash-rooted via {@link locateWriteRefInRoot}.
|
|
207
244
|
*/
|
|
208
245
|
function isFailOpenRefType(type, name) {
|
|
@@ -210,7 +247,7 @@ function isFailOpenRefType(type, name) {
|
|
|
210
247
|
}
|
|
211
248
|
/**
|
|
212
249
|
* Resolve a write-time ref to its primary on-disk file within a single stash
|
|
213
|
-
* root. Wraps lint's `resolveRefPathInStash` with one addition:
|
|
250
|
+
* root. Wraps lint's `resolveRefPathInStash` with one addition: workflow
|
|
214
251
|
* refs are probed against the ROOT's workflows/ dir first (every recognized
|
|
215
252
|
* workflow extension), because `workflowSpec.toAssetPath` inside
|
|
216
253
|
* `refToRelPath` probes the CWD — and write validation must not depend on the
|
|
@@ -230,8 +267,9 @@ function locateWriteRefInRoot(type, name, root) {
|
|
|
230
267
|
}
|
|
231
268
|
/** Build the shared exit-2 error for refs that resolved in no root. */
|
|
232
269
|
function unresolvedRefsError(flag, unresolved) {
|
|
233
|
-
const
|
|
234
|
-
|
|
270
|
+
const firstName = unresolved[0]?.name ?? "asset";
|
|
271
|
+
const firstType = unresolved[0]?.type ?? "knowledge";
|
|
272
|
+
return new UsageError(`${flag} ref${unresolved.length > 1 ? "s" : ""} did not resolve in the write target or any configured source: ${unresolved.map((u) => u.ref).join(", ")}`, "INVALID_FLAG_VALUE", `Find the intended asset with \`akm search "${firstName}" --type ${firstType}\`. Refs use the form [bundle//]conceptId (e.g. knowledge/guide.md).`);
|
|
235
273
|
}
|
|
236
274
|
// ── Cross-references (--xref) ────────────────────────────────────────────────
|
|
237
275
|
/**
|
|
@@ -243,7 +281,7 @@ export const XREF_SOFT_CAP = 5;
|
|
|
243
281
|
/**
|
|
244
282
|
* Validate `--xref` flag values before ANY write happens.
|
|
245
283
|
*
|
|
246
|
-
* Each
|
|
284
|
+
* Each `[bundle//]conceptId` must resolve to a real asset in the write-ref root
|
|
247
285
|
* set (write target + working stash + configured sources — see
|
|
248
286
|
* {@link resolveWriteRefRoots}; cross-stash provenance refs into read-only
|
|
249
287
|
* sources are accepted). An unresolvable ref is input validation of an
|
|
@@ -252,33 +290,36 @@ export const XREF_SOFT_CAP = 5;
|
|
|
252
290
|
* validation leaves the stash untouched. Resolution reuses the lint
|
|
253
291
|
* ref-resolver helpers (`refToRelPath` / `resolveRefPathInStash`) — do not
|
|
254
292
|
* fork a second resolver — and mirrors lint's fail-open policy: a type the
|
|
255
|
-
* resolver cannot map to a path (
|
|
256
|
-
* check.
|
|
293
|
+
* resolver cannot map to a path (for example a script concept) is accepted
|
|
294
|
+
* without an existence check.
|
|
257
295
|
*
|
|
258
|
-
* Returns
|
|
259
|
-
*
|
|
260
|
-
*
|
|
261
|
-
* (soft cap) but still returns them all.
|
|
296
|
+
* Returns fully-qualified durable refs, deduplicated in argv order. More than
|
|
297
|
+
* {@link XREF_SOFT_CAP} refs emits a stderr warning (soft cap) but still
|
|
298
|
+
* returns them all.
|
|
262
299
|
*/
|
|
263
300
|
export function resolveXrefsForWrite(rawXrefs, target) {
|
|
264
301
|
const parsedRefs = parseWriteRefs(rawXrefs, "--xref");
|
|
265
302
|
if (parsedRefs.length === 0)
|
|
266
303
|
return [];
|
|
267
|
-
const {
|
|
268
|
-
const allRoots = [...mutableRoots, ...otherSources.map((s) => s.path)];
|
|
304
|
+
const { roots } = resolveWriteRefRoots(target);
|
|
269
305
|
const unresolved = [];
|
|
306
|
+
const xrefs = [];
|
|
270
307
|
for (const parsed of parsedRefs) {
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
308
|
+
const candidates = rootsForWriteRef(parsed, roots);
|
|
309
|
+
const resolvedRoot = isFailOpenRefType(parsed.type, parsed.name)
|
|
310
|
+
? candidates[0]
|
|
311
|
+
: candidates.find((root) => locateWriteRefInRoot(parsed.type, parsed.name, root.path) !== null);
|
|
312
|
+
if (!resolvedRoot) {
|
|
274
313
|
unresolved.push(parsed);
|
|
314
|
+
continue;
|
|
275
315
|
}
|
|
316
|
+
const ref = canonicalWriteRef(parsed, resolvedRoot.bundleId);
|
|
317
|
+
if (!xrefs.includes(ref))
|
|
318
|
+
xrefs.push(ref);
|
|
276
319
|
}
|
|
277
320
|
if (unresolved.length > 0) {
|
|
278
321
|
throw unresolvedRefsError("--xref", unresolved);
|
|
279
322
|
}
|
|
280
|
-
// The CANONICAL spellings are what land in frontmatter (see ParsedWriteRef).
|
|
281
|
-
const xrefs = parsedRefs.map((p) => p.ref);
|
|
282
323
|
if (xrefs.length > XREF_SOFT_CAP) {
|
|
283
324
|
warn(`Warning: ${xrefs.length} xrefs exceeds the ~${XREF_SOFT_CAP} soft cap from the back-linking conventions. ` +
|
|
284
325
|
"Each xref folds into this asset's search hints, so extras blur its ranking signal. Writing anyway.");
|
|
@@ -300,8 +341,9 @@ export function resolveXrefsForWrite(rawXrefs, target) {
|
|
|
300
341
|
* scanner and re-serializing that lossy result would destroy list/nested
|
|
301
342
|
* values (`tags: [a, b]` → `tags: ""`). Rather than corrupt data the caller
|
|
302
343
|
* asked to preserve, a block that is not a parseable YAML mapping throws
|
|
303
|
-
* {@link UsageError} (exit 2, before any write)
|
|
304
|
-
*
|
|
344
|
+
* {@link UsageError} (exit 2, before any write). The AKM write boundary also
|
|
345
|
+
* rejects malformed frontmatter without `--xref` because it cannot safely add
|
|
346
|
+
* required type metadata. Known
|
|
305
347
|
* cosmetic limitation: YAML comments and anchors in a VALID block do not
|
|
306
348
|
* survive the round-trip (values are preserved).
|
|
307
349
|
*/
|
|
@@ -311,7 +353,7 @@ export function mergeXrefsIntoContent(content, xrefs) {
|
|
|
311
353
|
const parsed = parseFrontmatter(content);
|
|
312
354
|
if (parsed.frontmatter?.trim()) {
|
|
313
355
|
if (!isParseableYamlMapping(parsed.frontmatter)) {
|
|
314
|
-
throw new UsageError("--xref cannot merge into this document: its frontmatter is not a parseable YAML mapping, and rewriting it would drop the values the parser could not read.", "INVALID_FLAG_VALUE", "Fix the document's frontmatter (e.g. an unterminated quote) and retry
|
|
356
|
+
throw new UsageError("--xref cannot merge into this document: its frontmatter is not a parseable YAML mapping, and rewriting it would drop the values the parser could not read.", "INVALID_FLAG_VALUE", "Fix the document's frontmatter (e.g. an unterminated quote) and retry.");
|
|
315
357
|
}
|
|
316
358
|
}
|
|
317
359
|
const existingValue = parsed.data.xrefs;
|
|
@@ -343,6 +385,18 @@ function isParseableYamlMapping(frontmatter) {
|
|
|
343
385
|
return false;
|
|
344
386
|
}
|
|
345
387
|
}
|
|
388
|
+
/** Resolve any qualified supersedes ref as the mutation target for remember/import. */
|
|
389
|
+
export function resolveSupersedesWriteTarget(rawRefs, target) {
|
|
390
|
+
const config = loadConfig();
|
|
391
|
+
let effectiveTarget = target;
|
|
392
|
+
for (const parsed of parseWriteRefs(rawRefs, "--supersedes")) {
|
|
393
|
+
if (!parsed.origin)
|
|
394
|
+
continue;
|
|
395
|
+
const resolved = resolveMutationTarget(config, { type: parsed.type, name: parsed.name, origin: parsed.origin }, effectiveTarget).target;
|
|
396
|
+
effectiveTarget = resolved.selector ?? resolved.source.name;
|
|
397
|
+
}
|
|
398
|
+
return effectiveTarget;
|
|
399
|
+
}
|
|
346
400
|
/**
|
|
347
401
|
* Asset types `--supersedes` must refuse to demote: the demotion writes a YAML
|
|
348
402
|
* frontmatter block onto the target file, and these types are RAW files whose
|
|
@@ -366,7 +420,7 @@ const SUPERSEDE_REJECTED_TYPES = new Set(["secret", "env", "task", "script"]);
|
|
|
366
420
|
* Because the demotion PREPENDS a YAML frontmatter block when the target file
|
|
367
421
|
* has none, only markdown assets may be demoted: refs of a raw asset type
|
|
368
422
|
* ({@link SUPERSEDE_REJECTED_TYPES}) and refs resolving to any non-`.md` file
|
|
369
|
-
* (
|
|
423
|
+
* (for example a task YAML file) are rejected with {@link UsageError} BEFORE
|
|
370
424
|
* any write — never silently corrupted.
|
|
371
425
|
*
|
|
372
426
|
* Demotion targets must live under the resolved write target's source path or
|
|
@@ -384,30 +438,28 @@ export function resolveSupersedesForWrite(rawRefs, target) {
|
|
|
384
438
|
const parsedRefs = parseWriteRefs(rawRefs, "--supersedes");
|
|
385
439
|
if (parsedRefs.length === 0)
|
|
386
440
|
return [];
|
|
387
|
-
const {
|
|
388
|
-
// Mutable roots first: when a ref resolves in several roots, demote the copy
|
|
389
|
-
// this command is allowed to mutate. Non-mutable roots keep their SearchSource
|
|
390
|
-
// so the skip reason can distinguish "re-run with --target" (a configured
|
|
391
|
-
// writable source that simply is not this write's target) from genuinely
|
|
392
|
-
// read-only sources.
|
|
393
|
-
const orderedRoots = [
|
|
394
|
-
...mutableRoots.map((p) => ({ path: p })),
|
|
395
|
-
...otherSources.map((s) => ({ path: s.path, source: s })),
|
|
396
|
-
];
|
|
441
|
+
const { roots } = resolveWriteRefRoots(target);
|
|
397
442
|
const plan = [];
|
|
398
443
|
const unresolved = [];
|
|
399
444
|
for (const parsed of parsedRefs) {
|
|
445
|
+
const orderedRoots = rootsForWriteRef(parsed, roots);
|
|
400
446
|
// Data-corruption gate (SPEC-5): demotion is a frontmatter write; a raw
|
|
401
447
|
// asset type must be rejected up front — resolving it and mutating the
|
|
402
448
|
// file would prepend a YAML block over its raw bytes.
|
|
403
449
|
if (SUPERSEDE_REJECTED_TYPES.has(parsed.type)) {
|
|
404
|
-
throw new UsageError(`--supersedes cannot demote ${parsed.ref}: "${parsed.type}
|
|
450
|
+
throw new UsageError(`--supersedes cannot demote ${parsed.ref}: asset type "${parsed.type}" uses raw files, and the demotion writes YAML frontmatter that would corrupt them.`, "INVALID_FLAG_VALUE", "Only markdown assets (e.g. memories/note, knowledge/guide, facts/team/tool-stack) can carry the beliefState/supersededBy demotion. Replace or delete the raw asset instead.");
|
|
405
451
|
}
|
|
406
452
|
let located = null;
|
|
407
453
|
for (const root of orderedRoots) {
|
|
408
454
|
const filePath = locateWriteRefInRoot(parsed.type, parsed.name, root.path);
|
|
409
455
|
if (filePath !== null) {
|
|
410
|
-
located = {
|
|
456
|
+
located = {
|
|
457
|
+
root: root.path,
|
|
458
|
+
source: root.source,
|
|
459
|
+
bundleId: root.bundleId,
|
|
460
|
+
mutable: root.mutable,
|
|
461
|
+
filePath,
|
|
462
|
+
};
|
|
411
463
|
break;
|
|
412
464
|
}
|
|
413
465
|
}
|
|
@@ -416,20 +468,21 @@ export function resolveSupersedesForWrite(rawRefs, target) {
|
|
|
416
468
|
continue;
|
|
417
469
|
}
|
|
418
470
|
// Belt-and-suspenders for the same corruption class: whatever the type,
|
|
419
|
-
// the demotion may only touch a markdown file. Rejects
|
|
420
|
-
//
|
|
421
|
-
// or the explicit `workflow:deploy.yaml` spelling).
|
|
471
|
+
// the demotion may only touch a markdown file. Rejects, for example, a task
|
|
472
|
+
// YAML file reached through a malformed or stale ref.
|
|
422
473
|
if (!located.filePath.toLowerCase().endsWith(".md")) {
|
|
423
474
|
throw new UsageError(`--supersedes ${parsed.ref} resolves to a non-markdown file (${located.filePath}) — the demotion writes YAML frontmatter and would corrupt it.`, "INVALID_FLAG_VALUE", "Only markdown assets can carry the beliefState/supersededBy demotion. Replace or delete the file instead.");
|
|
424
475
|
}
|
|
425
|
-
const { root, source, filePath } = located;
|
|
426
|
-
const writable = source === undefined;
|
|
476
|
+
const { root, source, bundleId, mutable: writable, filePath } = located;
|
|
427
477
|
// The eligibility rule is write-target-or-working-stash, NOT source
|
|
428
478
|
// writability: mutating a non-target writable source would leave it dirty
|
|
429
479
|
// outside any boundary commit. Name the remedy when one exists.
|
|
430
480
|
const namedWritableSource = source?.writable === true ? source.registryId : undefined;
|
|
481
|
+
const canonicalRef = canonicalWriteRef(parsed, bundleId);
|
|
482
|
+
if (plan.some((item) => item.ref === canonicalRef))
|
|
483
|
+
continue;
|
|
431
484
|
plan.push({
|
|
432
|
-
ref:
|
|
485
|
+
ref: canonicalRef,
|
|
433
486
|
filePath,
|
|
434
487
|
stashRoot: root,
|
|
435
488
|
writable,
|
|
@@ -460,14 +513,15 @@ export function resolveSupersedesForWrite(rawRefs, target) {
|
|
|
460
513
|
*/
|
|
461
514
|
export async function writeMarkdownAsset(options) {
|
|
462
515
|
const cfg = loadConfig();
|
|
463
|
-
const target = resolveWriteTarget(cfg, options.target);
|
|
464
|
-
const { source, config } = target;
|
|
465
|
-
const typeRoot = path.join(source.path, options.type === "knowledge" ? "knowledge" : "memories");
|
|
466
516
|
// `--name` is the flat asset name; `--path` is the subdirectory under the
|
|
467
517
|
// type root. Combine them into the nested name the path resolver expects.
|
|
468
518
|
const subPath = normalizeCreateSubPath(options.path);
|
|
469
519
|
const baseName = normalizeMarkdownAssetName(options.name, inferAssetName(options.content, options.fallbackPrefix, options.preferredName));
|
|
470
520
|
const normalizedName = combineCreatePath(subPath, baseName);
|
|
521
|
+
const resolved = resolveMutationTarget(cfg, { type: options.type, name: normalizedName }, options.target);
|
|
522
|
+
const { target } = resolved;
|
|
523
|
+
const { source, config } = target;
|
|
524
|
+
const typeRoot = path.join(source.path, options.type === "knowledge" ? "knowledge" : "memories");
|
|
471
525
|
// Pre-flight: existence + force semantics. The helper itself overwrites
|
|
472
526
|
// unconditionally; the CLI surfaces a friendlier UsageError before any
|
|
473
527
|
// disk activity when --force is absent.
|
|
@@ -485,11 +539,12 @@ export async function writeMarkdownAsset(options) {
|
|
|
485
539
|
// Input validation: exit 2, before any write, nothing demoted.
|
|
486
540
|
for (const item of options.supersedes ?? []) {
|
|
487
541
|
if (path.resolve(item.filePath) === path.resolve(assetPath)) {
|
|
488
|
-
throw new UsageError(`--supersedes ${item.ref} resolves to the asset being written ("${
|
|
542
|
+
throw new UsageError(`--supersedes ${item.ref} resolves to the asset being written ("${resolved.displayRef}") — a correction cannot supersede itself.`, "INVALID_FLAG_VALUE", "Write the correction under a different --name, or drop --supersedes when overwriting an asset in place with --force.");
|
|
489
543
|
}
|
|
490
544
|
}
|
|
491
|
-
const
|
|
492
|
-
const
|
|
545
|
+
const result = await writeAssetToSource(source, config, resolved.ref, options.content);
|
|
546
|
+
const durableRef = result.ref;
|
|
547
|
+
result.ref = resolved.displayRef;
|
|
493
548
|
// SPEC-5 (--supersedes): demote each superseded asset by mutating its
|
|
494
549
|
// frontmatter (`beliefState: superseded` + sorted-set-append `supersededBy`;
|
|
495
550
|
// every other key and the body are preserved). Ordered BEFORE
|
|
@@ -532,12 +587,9 @@ export async function writeMarkdownAsset(options) {
|
|
|
532
587
|
// on a git target, uncommitted (and a re-run hits RESOURCE_ALREADY_EXISTS).
|
|
533
588
|
// Degrade to the same applied:false report the non-writable path uses.
|
|
534
589
|
try {
|
|
535
|
-
|
|
536
|
-
|
|
537
|
-
|
|
538
|
-
// is now the new-grammar conceptId surface too (WI-8.5c).
|
|
539
|
-
writeSupersededEdge(item.filePath, result.ref);
|
|
540
|
-
if (path.resolve(item.stashRoot) === path.resolve(source.path)) {
|
|
590
|
+
const sameSource = path.resolve(item.stashRoot) === path.resolve(source.path);
|
|
591
|
+
writeSupersededEdge(item.filePath, durableRef);
|
|
592
|
+
if (sameSource) {
|
|
541
593
|
recordWriteTargetPath(source, item.filePath);
|
|
542
594
|
}
|
|
543
595
|
}
|
|
@@ -555,7 +607,7 @@ export async function writeMarkdownAsset(options) {
|
|
|
555
607
|
}
|
|
556
608
|
// 0.9.0 (issue #507): single batch commit at the write boundary for git
|
|
557
609
|
// targets. No-op for filesystem/primary-stash targets.
|
|
558
|
-
commitWriteTargetBoundary(target, `Update ${formatRefForMessage(ref)}`);
|
|
610
|
+
commitWriteTargetBoundary(target, `Update ${formatRefForMessage(resolved.ref)}`);
|
|
559
611
|
// Write-path indexing: the asset is searchable immediately. Fail-open; reads
|
|
560
612
|
// no longer trigger reindexes, so keeping the index current is the writer's
|
|
561
613
|
// job. Demoted files reindex under their own containing root (usually the
|
|
@@ -564,9 +616,12 @@ export async function writeMarkdownAsset(options) {
|
|
|
564
616
|
// effect without waiting for the next full index.
|
|
565
617
|
const demotedInTargetRoot = demotedByRoot.get(source.path) ?? [];
|
|
566
618
|
demotedByRoot.delete(source.path);
|
|
567
|
-
await indexWrittenAssets(source.path, [result.path, ...demotedInTargetRoot]);
|
|
619
|
+
await indexWrittenAssets(source.path, [result.path, ...demotedInTargetRoot], { bundleId: resolved.ref.origin });
|
|
620
|
+
const sourceEntries = resolveSourceEntries(undefined, cfg);
|
|
621
|
+
const sourceInstallations = deriveInstallations(sourceEntries);
|
|
568
622
|
for (const [root, files] of demotedByRoot) {
|
|
569
|
-
|
|
623
|
+
const sourceIndex = sourceEntries.findIndex((entry) => path.resolve(entry.path) === path.resolve(root));
|
|
624
|
+
await indexWrittenAssets(root, files, { bundleId: sourceInstallations[sourceIndex]?.id });
|
|
570
625
|
}
|
|
571
626
|
// Placement hint (stash-organization conventions): CLI writers never receive
|
|
572
627
|
// the resolveStashStandards prompt injection LLM flows get, so a type-root
|
|
@@ -582,7 +637,7 @@ export async function writeMarkdownAsset(options) {
|
|
|
582
637
|
// and a dead `akm show` pointer is worse than generic wording.
|
|
583
638
|
const orgFactPath = path.join(source.path, "facts", "conventions", "organization.md");
|
|
584
639
|
hint = fs.existsSync(orgFactPath)
|
|
585
|
-
? `Wrote to the ${options.type} root. This stash has placement conventions — see \`akm show
|
|
640
|
+
? `Wrote to the ${options.type} root. This stash has placement conventions — see \`akm show facts/conventions/organization\`.`
|
|
586
641
|
: `Wrote to the ${options.type} root. This stash has placement conventions — see the convention facts under its facts/ directory.`;
|
|
587
642
|
}
|
|
588
643
|
}
|
|
@@ -4,7 +4,7 @@
|
|
|
4
4
|
import { toErrorMessage } from "../../core/common.js";
|
|
5
5
|
import { DEFAULT_CONFIG } from "../../core/config/config.js";
|
|
6
6
|
import { warn } from "../../core/warn.js";
|
|
7
|
-
import {
|
|
7
|
+
import { resolveRegistryProviderFactory } from "../../registry/factory.js";
|
|
8
8
|
// ── Eagerly import providers to trigger self-registration ───────────────────
|
|
9
9
|
import "../../registry/providers/index.js";
|
|
10
10
|
// ── Public API ──────────────────────────────────────────────────────────────
|
|
@@ -142,7 +142,7 @@ export function resolveRegistries(configRegistries) {
|
|
|
142
142
|
// ── Provider resolution ─────────────────────────────────────────────────────
|
|
143
143
|
function createProvider(entry, warnings) {
|
|
144
144
|
const providerType = entry.provider ?? "static-index";
|
|
145
|
-
const factory =
|
|
145
|
+
const factory = resolveRegistryProviderFactory(providerType);
|
|
146
146
|
if (!factory) {
|
|
147
147
|
const label = entry.name ? `${entry.name} (${entry.url})` : entry.url;
|
|
148
148
|
warnings.push(`Registry ${label}: unknown provider type "${providerType}"`);
|
|
@@ -1,13 +1,14 @@
|
|
|
1
1
|
// This Source Code Form is subject to the terms of the Mozilla Public
|
|
2
2
|
// License, v. 2.0. If a copy of the MPL was not distributed with this
|
|
3
3
|
// file, You can obtain one at https://mozilla.org/MPL/2.0/.
|
|
4
|
+
import { getParsedInvocation } from "../../cli/invocation.js";
|
|
4
5
|
import { getStringArg } from "../../cli/parse-args.js";
|
|
5
6
|
import { defineJsonCommand, output, parseAllFlagValues } from "../../cli/shared.js";
|
|
6
7
|
import { UsageError } from "../../core/errors.js";
|
|
7
8
|
import { appendEvent } from "../../core/events.js";
|
|
8
9
|
import { resolveUsageEventSource } from "../../indexer/usage/usage-events.js";
|
|
9
|
-
import { buildMemoryFrontmatter, parseDuration, readMemoryContent,
|
|
10
|
-
import { assertFlatAssetName, inferAssetName, resolveSupersedesForWrite, resolveXrefsForWrite, writeMarkdownAsset, } from "./knowledge.js";
|
|
10
|
+
import { buildMemoryFrontmatter, parseDuration, readMemoryContent, runAutoHeuristics, runLlmEnrich } from "../remember.js";
|
|
11
|
+
import { assertFlatAssetName, inferAssetName, resolveSupersedesForWrite, resolveSupersedesWriteTarget, resolveXrefsForWrite, writeMarkdownAsset, } from "./knowledge.js";
|
|
11
12
|
import { akmSearch } from "./search.js";
|
|
12
13
|
// ── Helper: similar memory search ────────────────────────────────────────────
|
|
13
14
|
/**
|
|
@@ -32,11 +33,22 @@ async function fetchSimilarMemories(query, excludeRef, eventSource) {
|
|
|
32
33
|
return [];
|
|
33
34
|
}
|
|
34
35
|
}
|
|
36
|
+
/**
|
|
37
|
+
* `--target` was renamed to `--bundle` on `remember` in 0.9 (S8). citty is
|
|
38
|
+
* non-strict, so the retired spelling is silently absorbed rather than
|
|
39
|
+
* rejected — the memory then lands in the default bundle instead of the one
|
|
40
|
+
* the caller named, with exit 0 and no error. Reject it explicitly instead.
|
|
41
|
+
*/
|
|
42
|
+
function rejectRetiredTargetFlag() {
|
|
43
|
+
if (!getParsedInvocation().hasFlag("--target"))
|
|
44
|
+
return;
|
|
45
|
+
throw new UsageError("`akm remember --target` was renamed to `--bundle` in 0.9. Use `--bundle <name>` instead.", "INVALID_FLAG_VALUE");
|
|
46
|
+
}
|
|
35
47
|
// ── Command definition ────────────────────────────────────────────────────────
|
|
36
48
|
export const rememberCommand = defineJsonCommand({
|
|
37
49
|
meta: {
|
|
38
50
|
name: "remember",
|
|
39
|
-
description: "Record a memory in the default
|
|
51
|
+
description: "Record a memory in the default bundle",
|
|
40
52
|
},
|
|
41
53
|
args: {
|
|
42
54
|
content: {
|
|
@@ -75,11 +87,11 @@ export const rememberCommand = defineJsonCommand({
|
|
|
75
87
|
},
|
|
76
88
|
xref: {
|
|
77
89
|
type: "string",
|
|
78
|
-
description: "Cross-reference ref recorded in the memory's `xrefs:` frontmatter (repeatable: --xref knowledge
|
|
90
|
+
description: "Cross-reference ref recorded in the memory's `xrefs:` frontmatter (repeatable: --xref knowledge/auth-flow --xref memories/vpn-note). Each ref must resolve in the write target or a configured source; an unresolvable ref aborts the write.",
|
|
79
91
|
},
|
|
80
92
|
supersedes: {
|
|
81
93
|
type: "string",
|
|
82
|
-
description: "Ref of an existing asset this memory corrects (repeatable: --supersedes
|
|
94
|
+
description: "Ref of an existing asset this memory corrects (repeatable: --supersedes memories/projectA/old-note). Writes the correction with an xref to the old asset AND demotes the old asset (`beliefState: superseded` + `supersededBy`, a metadata-only edit) so ranking prefers the correction and `--belief current` hides the stale version. An unresolvable or self-referencing ref aborts the write; a ref outside the write target and working bundle still writes the correction but skips the demotion (reported as applied: false).",
|
|
83
95
|
},
|
|
84
96
|
auto: {
|
|
85
97
|
type: "boolean",
|
|
@@ -91,9 +103,9 @@ export const rememberCommand = defineJsonCommand({
|
|
|
91
103
|
description: "Call the configured LLM to propose tags and description (requires LLM config)",
|
|
92
104
|
default: false,
|
|
93
105
|
},
|
|
94
|
-
|
|
106
|
+
bundle: {
|
|
95
107
|
type: "string",
|
|
96
|
-
description: "Override the write destination. Accepts a source name from your config; falls back to defaultWriteTarget then the working
|
|
108
|
+
description: "Override the write destination. Accepts a source name from your config; falls back to defaultWriteTarget then the working bundle.",
|
|
97
109
|
},
|
|
98
110
|
user: {
|
|
99
111
|
type: "string",
|
|
@@ -111,13 +123,23 @@ export const rememberCommand = defineJsonCommand({
|
|
|
111
123
|
type: "string",
|
|
112
124
|
description: "Scope this memory to a channel name (persisted as `scope_channel` frontmatter)",
|
|
113
125
|
},
|
|
114
|
-
|
|
126
|
+
"show-similar": {
|
|
115
127
|
type: "boolean",
|
|
116
|
-
|
|
128
|
+
// R-062: canonical spelling is kebab-case, matching every other
|
|
129
|
+
// multi-word flag in the CLI (--fail-on-flagged, --auto-fix, …).
|
|
130
|
+
// `--showSimilar` (the pre-rename spelling) is kept as an explicit,
|
|
131
|
+
// documented alias rather than a silent citty auto-alias — citty
|
|
132
|
+
// registers BOTH the camelCase and kebab-case spelling of any
|
|
133
|
+
// declared flag name automatically, so this is a rename, not a
|
|
134
|
+
// breaking change: both spellings already worked, and both keep
|
|
135
|
+
// working.
|
|
136
|
+
alias: "showSimilar",
|
|
137
|
+
description: "Return top-3 similar existing memories in output (opt-in). Alias: --showSimilar.",
|
|
117
138
|
},
|
|
118
139
|
},
|
|
119
140
|
async run({ args }) {
|
|
120
|
-
|
|
141
|
+
rejectRetiredTargetFlag();
|
|
142
|
+
const body = readMemoryContent(args.content);
|
|
121
143
|
const eventSource = resolveUsageEventSource();
|
|
122
144
|
// `--name` is a flat name; subdirectory placement is `--path`'s job.
|
|
123
145
|
assertFlatAssetName(args.name);
|
|
@@ -130,7 +152,9 @@ export const rememberCommand = defineJsonCommand({
|
|
|
130
152
|
// input validation (UsageError → exit 2) and must leave the stash
|
|
131
153
|
// untouched. Refs resolvable only in a configured extra stash source are
|
|
132
154
|
// accepted (cross-stash provenance).
|
|
133
|
-
const
|
|
155
|
+
const rawSupersedes = parseAllFlagValues("--supersedes");
|
|
156
|
+
const writeTarget = resolveSupersedesWriteTarget(rawSupersedes, args.bundle);
|
|
157
|
+
const xrefs = resolveXrefsForWrite(parseAllFlagValues("--xref"), writeTarget);
|
|
134
158
|
// Collect and validate --supersedes occurrences (repeatable). Same
|
|
135
159
|
// before-any-write validation contract: an unresolvable ref exits 2 with
|
|
136
160
|
// nothing written AND nothing demoted (no partial correction). The
|
|
@@ -138,7 +162,7 @@ export const rememberCommand = defineJsonCommand({
|
|
|
138
162
|
// (correction provenance per the back-linking conventions); the demotion
|
|
139
163
|
// itself runs inside writeMarkdownAsset, ordered before the git boundary
|
|
140
164
|
// commit.
|
|
141
|
-
const supersedes = resolveSupersedesForWrite(
|
|
165
|
+
const supersedes = resolveSupersedesForWrite(rawSupersedes, writeTarget);
|
|
142
166
|
for (const s of supersedes) {
|
|
143
167
|
if (!xrefs.includes(s.ref))
|
|
144
168
|
xrefs.push(s.ref);
|
|
@@ -157,7 +181,10 @@ export const rememberCommand = defineJsonCommand({
|
|
|
157
181
|
// --xref counts as structured metadata (it must land in frontmatter) but,
|
|
158
182
|
// like scope, does NOT trigger the tags-required check — provenance
|
|
159
183
|
// without tags is a valid write.
|
|
160
|
-
|
|
184
|
+
// --enrich is structured (it must reach the Mode-3 dispatch below, not the
|
|
185
|
+
// zero-flag hot path) but, like --auto, never tag-requiring: enrichment is
|
|
186
|
+
// fail-soft and a zero-tag outcome still writes.
|
|
187
|
+
const hasStructuredArgs = hasTagRequiringArgs || hasScope || args.auto || args.enrich || xrefs.length > 0;
|
|
161
188
|
if (!hasStructuredArgs) {
|
|
162
189
|
// Phase 1B / Rec 7: even the zero-flag hot-path emits
|
|
163
190
|
// `captureMode: hot` + `beliefState: asserted` so user-supplied
|
|
@@ -176,7 +203,7 @@ export const rememberCommand = defineJsonCommand({
|
|
|
176
203
|
fallbackPrefix: "memory",
|
|
177
204
|
preferredName: inferAssetName(body, "memory"),
|
|
178
205
|
force: args.force,
|
|
179
|
-
target:
|
|
206
|
+
target: writeTarget,
|
|
180
207
|
path: args.path,
|
|
181
208
|
supersedes,
|
|
182
209
|
});
|
|
@@ -278,7 +305,7 @@ export const rememberCommand = defineJsonCommand({
|
|
|
278
305
|
fallbackPrefix: "memory",
|
|
279
306
|
preferredName: inferAssetName(body, "memory"),
|
|
280
307
|
force: args.force,
|
|
281
|
-
target:
|
|
308
|
+
target: writeTarget,
|
|
282
309
|
path: args.path,
|
|
283
310
|
supersedes,
|
|
284
311
|
});
|