akm-cli 0.9.0-rc.4 → 0.9.0-rc.6
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 +122 -26
- package/README.md +7 -7
- package/SECURITY.md +11 -10
- package/dist/akm +2 -2
- package/dist/akm-migrate-storage +2 -2
- package/dist/assets/hints/cli-hints-full.md +60 -73
- package/dist/assets/hints/cli-hints-short.md +8 -12
- package/dist/assets/improve-strategies/default.json +5 -7
- package/dist/assets/improve-strategies/frequent.json +2 -2
- package/dist/assets/improve-strategies/proactive-maintenance.json +2 -2
- package/dist/assets/improve-strategies/quick.json +1 -1
- package/dist/assets/improve-strategies/reflect-distill.json +3 -3
- package/dist/assets/improve-strategies/thorough.json +1 -1
- package/dist/assets/prompts/consolidate-system.md +5 -5
- package/dist/assets/prompts/extract-session.md +2 -6
- package/dist/assets/prompts/reflect-llm-framed-contract.md +11 -0
- package/dist/assets/prompts/reflect-llm-schema-contract.md +3 -0
- package/dist/assets/prompts/reflect-output-repair.md +3 -0
- package/dist/assets/stash-skeleton/README.md +10 -11
- package/dist/assets/stash-skeleton/facts/conventions/assets/agent.md +1 -1
- package/dist/assets/stash-skeleton/facts/conventions/assets/fact.md +1 -1
- package/dist/assets/stash-skeleton/facts/conventions/assets/knowledge.md +1 -1
- package/dist/assets/stash-skeleton/facts/conventions/assets/lesson.md +2 -2
- package/dist/assets/stash-skeleton/facts/conventions/assets/memory.md +2 -2
- package/dist/assets/stash-skeleton/facts/conventions/assets/script.md +1 -1
- package/dist/assets/stash-skeleton/facts/conventions/assets/skill.md +2 -2
- package/dist/assets/stash-skeleton/facts/conventions/assets/workflow.md +1 -1
- package/dist/assets/stash-skeleton/facts/conventions/backlinks.md +18 -18
- package/dist/assets/stash-skeleton/facts/conventions/domains.md +8 -9
- package/dist/assets/stash-skeleton/facts/conventions/organization.md +13 -15
- package/dist/assets/tasks/core/extract.yml +2 -2
- package/dist/assets/tasks/core/improve.yml +1 -1
- package/dist/assets/templates/html/health.html +2 -3
- package/dist/cli/config-migrate.js +1328 -101
- package/dist/cli/invocation.js +255 -0
- package/dist/cli/parse-args.js +20 -83
- package/dist/cli/shared.js +15 -37
- package/dist/cli.js +18 -49
- package/dist/commands/agent/agent-dispatch.js +2 -2
- package/dist/commands/agent/contribute-cli.js +5 -4
- package/dist/commands/bundle/bundle-cli.js +68 -0
- package/dist/commands/bundle/bundle.js +219 -0
- package/dist/commands/completions.js +2 -2
- package/dist/commands/config-cli.js +6 -3
- package/dist/commands/env/env-binding.js +13 -9
- package/dist/commands/env/env-cli.js +49 -48
- package/dist/commands/env/secret-cli.js +24 -10
- package/dist/commands/events.js +2 -2
- package/dist/commands/feedback-cli.js +59 -33
- package/dist/commands/graph/graph.js +6 -4
- package/dist/commands/health/advisories.js +4 -4
- package/dist/commands/health/html-report.js +190 -593
- package/dist/commands/health/improve-metrics.js +240 -188
- package/dist/commands/health/metrics.js +9 -17
- package/dist/commands/health/report-view-model.js +509 -0
- package/dist/commands/health/surfaces.js +6 -3
- package/dist/commands/health/types-checks.js +4 -0
- package/dist/commands/health/types-improve.js +22 -0
- package/dist/commands/health/types-metrics.js +4 -0
- package/dist/commands/health/types-result.js +7 -0
- package/dist/commands/health/types-runs.js +4 -0
- package/dist/commands/health/types-session-log.js +4 -0
- package/dist/commands/health/types-windows.js +4 -0
- package/dist/commands/health/types.js +26 -21
- package/dist/commands/health/windows.js +1 -2
- package/dist/commands/health.js +219 -161
- package/dist/commands/improve/collapse-detector.js +25 -14
- package/dist/commands/improve/consolidate/chunking.js +7 -5
- package/dist/commands/improve/consolidate.js +640 -740
- package/dist/commands/improve/content-hash.js +39 -0
- package/dist/commands/improve/distill/content-repair.js +4 -10
- package/dist/commands/improve/distill/promote-memory.js +79 -49
- package/dist/commands/improve/distill/quality-gate.js +113 -35
- package/dist/commands/improve/distill-promotion-policy.js +24 -885
- package/dist/commands/improve/distill.js +565 -337
- package/dist/commands/improve/eligibility.js +75 -36
- package/dist/commands/improve/extract-cli.js +6 -6
- package/dist/commands/improve/extract-prompt.js +5 -34
- package/dist/commands/improve/extract.js +526 -357
- package/dist/commands/improve/feedback-valence.js +2 -12
- package/dist/commands/improve/improve-cli.js +11 -20
- package/dist/commands/improve/improve-result-file.js +7 -6
- package/dist/commands/improve/improve-run-types.js +4 -0
- package/dist/commands/improve/improve-strategies.js +3 -9
- package/dist/commands/improve/improve.js +822 -727
- package/dist/commands/improve/locks.js +27 -95
- package/dist/commands/improve/loop-stages.js +941 -963
- package/dist/commands/improve/memory/derived-ref.js +122 -0
- package/dist/commands/improve/memory/memory-contradiction-detect.js +35 -38
- package/dist/commands/improve/memory/memory-improve.js +24 -37
- package/dist/commands/improve/outcome-loop.js +13 -33
- package/dist/commands/improve/preparation.js +889 -691
- package/dist/commands/improve/proactive-maintenance.js +37 -9
- package/dist/commands/improve/proposal-envelope.js +31 -0
- package/dist/commands/improve/reflect.js +974 -588
- package/dist/commands/improve/run-context.js +119 -0
- package/dist/commands/improve/salience.js +8 -4
- package/dist/commands/improve/session-asset.js +7 -3
- package/dist/commands/improve/shared.js +14 -40
- package/dist/commands/improve/source-identity.js +39 -26
- package/dist/commands/improve/triage.js +20 -17
- package/dist/commands/lint/base-linter.js +288 -295
- package/dist/commands/lint/index.js +132 -19
- package/dist/commands/mv-cli.js +257 -234
- package/dist/commands/observability-cli.js +2 -1
- package/dist/commands/proposal/diff-format.js +50 -0
- package/dist/commands/proposal/drain-policies.js +0 -6
- package/dist/commands/proposal/drain.js +17 -16
- package/dist/commands/proposal/proposal-cli.js +40 -77
- package/dist/commands/proposal/proposal-types.js +56 -0
- package/dist/commands/proposal/proposal.js +39 -1
- package/dist/commands/proposal/propose.js +41 -19
- package/dist/commands/proposal/repository.js +566 -486
- package/dist/commands/proposal/validators/proposal-quality-validators.js +22 -6
- package/dist/commands/proposal/validators/proposal-validators.js +6 -5
- package/dist/commands/proposal/validators/proposals.js +5 -4
- package/dist/commands/read/curate.js +50 -28
- package/dist/commands/read/knowledge.js +25 -16
- package/dist/commands/read/remember-cli.js +12 -4
- package/dist/commands/read/search-cli.js +33 -33
- package/dist/commands/read/search.js +68 -55
- package/dist/commands/read/show.js +54 -135
- package/dist/commands/remember.js +7 -5
- package/dist/commands/sources/add-cli.js +10 -24
- package/dist/commands/sources/bundle-config-ops.js +58 -0
- package/dist/commands/sources/history.js +13 -8
- package/dist/commands/sources/info.js +10 -11
- package/dist/commands/sources/init.js +12 -21
- package/dist/commands/sources/installed-stashes.js +151 -138
- package/dist/commands/sources/schema-repair.js +5 -3
- package/dist/commands/sources/self-update.js +9 -7
- package/dist/commands/sources/source-add.js +116 -154
- package/dist/commands/sources/source-clone.js +33 -14
- package/dist/commands/sources/source-manage.js +43 -32
- package/dist/commands/sources/sources-cli.js +12 -7
- package/dist/commands/sources/stash-cli.js +12 -5
- package/dist/commands/sources/stash-skeleton.js +1 -1
- package/dist/commands/tasks/default-tasks.js +13 -13
- package/dist/commands/tasks/tasks-cli.js +3 -3
- package/dist/commands/tasks/tasks.js +71 -31
- package/dist/commands/workflow-cli.js +22 -26
- package/dist/core/action-contributors.js +1 -1
- package/dist/core/activation-policy.js +49 -0
- package/dist/core/adapter/adapters/agent-skills-adapter.js +181 -0
- package/dist/core/adapter/adapters/akm-adapter.js +509 -0
- package/dist/core/adapter/adapters/akm-lint.js +381 -0
- package/dist/core/adapter/adapters/akm-metadata.js +416 -0
- package/dist/core/adapter/adapters/akm-task-adapter.js +150 -0
- package/dist/core/adapter/adapters/akm-workflow-adapter.js +196 -0
- package/dist/core/adapter/adapters/claude-adapter.js +61 -0
- package/dist/core/adapter/adapters/dotenv-adapter.js +187 -0
- package/dist/core/adapter/adapters/generic-files-adapter.js +117 -0
- package/dist/core/adapter/adapters/index.js +80 -0
- package/dist/core/adapter/adapters/llm-wiki-adapter.js +413 -0
- package/dist/core/adapter/adapters/okf-adapter.js +223 -0
- package/dist/core/adapter/adapters/opencode-adapter.js +68 -0
- package/dist/core/adapter/adapters/shared.js +286 -0
- package/dist/core/adapter/adapters/tool-dir-shared.js +212 -0
- package/dist/core/adapter/adapters/website-snapshot-adapter.js +154 -0
- package/dist/core/adapter/bundle-adapter.js +4 -0
- package/dist/core/adapter/recognize-match.js +42 -0
- package/dist/core/adapter/registry.js +56 -0
- package/dist/core/adapter/types.js +4 -0
- package/dist/core/asset/asset-placement.js +229 -0
- package/dist/core/asset/asset-ref.js +107 -78
- package/dist/core/asset/asset-serialize.js +20 -0
- package/dist/core/asset/frontmatter.js +1 -1
- package/dist/core/asset/resolve-ref.js +223 -0
- package/dist/core/asset/stash-meta.js +1 -1
- package/dist/core/common.js +141 -49
- package/dist/core/config/config-io.js +0 -108
- package/dist/core/config/config-schema.js +94 -1039
- package/dist/core/config/config-sources.js +115 -36
- package/dist/core/config/config-types.js +16 -11
- package/dist/core/config/config-walker.js +4 -2
- package/dist/core/config/config.js +21 -26
- package/dist/core/config/engine-semantics.js +0 -4
- package/dist/core/config/schema/embedding.js +38 -0
- package/dist/core/config/schema/engines.js +116 -0
- package/dist/core/config/schema/feedback.js +31 -0
- package/dist/core/config/schema/improve-processes.js +395 -0
- package/dist/core/config/schema/improve.js +76 -0
- package/dist/core/config/schema/index-config.js +183 -0
- package/dist/core/config/schema/output.js +15 -0
- package/dist/core/config/schema/primitives.js +94 -0
- package/dist/core/config/schema/search.js +30 -0
- package/dist/core/config/schema/setup.js +27 -0
- package/dist/core/config/schema/sources-bundles.js +164 -0
- package/dist/core/config/schema/workflow.js +29 -0
- package/dist/core/env-secret-ref.js +113 -8
- package/dist/core/errors.js +1 -1
- package/dist/core/events-types.js +4 -0
- package/dist/core/extra-params.js +1 -0
- package/dist/core/file-change.js +16 -0
- package/dist/core/fs-txn.js +316 -0
- package/dist/core/git-message.js +59 -0
- package/dist/core/improve-result.js +9 -1
- package/dist/core/logs-db.js +1 -1
- package/dist/core/maintenance-barrier.js +16 -0
- package/dist/core/migration-backup.js +332 -160
- package/dist/core/paths.js +3 -6
- package/dist/core/platform.js +10 -0
- package/dist/core/recognition-util.js +130 -0
- package/dist/core/redaction.js +2 -2
- package/dist/core/standards/resolve-standards-context.js +47 -64
- package/dist/core/standards/resolve-type-conventions.js +3 -3
- package/dist/core/state/migrations.js +201 -8
- package/dist/core/state-db.js +38 -2
- package/dist/core/subprocess.js +303 -0
- package/dist/core/time.js +20 -0
- package/dist/core/type-presentation.js +130 -0
- package/dist/core/write-source.js +39 -67
- package/dist/indexer/bundle-identity-guard.js +91 -0
- package/dist/indexer/db/graph-db.js +1 -1
- package/dist/indexer/db/llm-cache.js +1 -1
- package/dist/indexer/ensure-index.js +29 -9
- package/dist/indexer/graph/graph-boost.js +28 -24
- package/dist/indexer/graph/graph-extraction.js +5 -6
- package/dist/indexer/graph/graph-types.js +4 -0
- package/dist/indexer/index-written-assets.js +44 -17
- package/dist/indexer/indexer.js +289 -153
- package/dist/indexer/init.js +18 -25
- package/dist/indexer/installations.js +224 -0
- package/dist/indexer/passes/dir-staleness.js +2 -1
- package/dist/indexer/passes/memory-inference.js +8 -4
- package/dist/indexer/passes/metadata.js +96 -243
- package/dist/indexer/scan/doc-to-entry.js +123 -0
- package/dist/indexer/scan/drain-dir.js +144 -0
- package/dist/indexer/search/db-search.js +171 -99
- package/dist/indexer/search/fts-query.js +1 -1
- package/dist/indexer/search/ranking-contributors.js +57 -7
- package/dist/indexer/search/ranking-types.js +4 -0
- package/dist/indexer/search/ranking.js +31 -6
- package/dist/indexer/search/search-attribution.js +67 -0
- package/dist/indexer/search/search-hit-enrichers.js +30 -40
- package/dist/indexer/search/search-source.js +109 -52
- package/dist/indexer/search/semantic-status.js +4 -1
- package/dist/indexer/usage/unmigrated-vaults-guard.js +2 -1
- package/dist/indexer/usage/usage-events.js +72 -9
- package/dist/indexer/walk/file-context.js +1 -44
- package/dist/indexer/walk/matchers.js +16 -32
- package/dist/indexer/walk/path-resolver.js +6 -5
- package/dist/indexer/walk/walker.js +4 -2
- package/dist/integrations/agent/engine-resolution.js +22 -0
- package/dist/integrations/agent/model-aliases.js +1 -1
- package/dist/integrations/agent/prompts.js +35 -11
- package/dist/integrations/agent/spawn.js +41 -270
- package/dist/integrations/harnesses/aider/agent-builder.js +2 -2
- package/dist/integrations/harnesses/aider/index.js +2 -11
- package/dist/integrations/harnesses/amazonq/agent-builder.js +1 -9
- package/dist/integrations/harnesses/amazonq/index.js +3 -16
- package/dist/integrations/harnesses/claude/config-import.js +1 -3
- package/dist/integrations/harnesses/claude/index.js +1 -12
- package/dist/integrations/harnesses/claude/session-log.js +27 -65
- package/dist/integrations/harnesses/codex/agent-builder.js +1 -2
- package/dist/integrations/harnesses/codex/index.js +2 -12
- package/dist/integrations/harnesses/copilot/agent-builder.js +2 -3
- package/dist/integrations/harnesses/copilot/index.js +1 -12
- package/dist/integrations/harnesses/gemini/agent-builder.js +1 -3
- package/dist/integrations/harnesses/gemini/index.js +1 -12
- package/dist/integrations/harnesses/ids.js +24 -0
- package/dist/integrations/harnesses/index.js +27 -2
- package/dist/integrations/harnesses/opencode/config-import.js +1 -3
- package/dist/integrations/harnesses/opencode/index.js +1 -12
- package/dist/integrations/harnesses/opencode/session-log.js +67 -110
- package/dist/integrations/harnesses/opencode-sdk/harness.js +2 -11
- package/dist/integrations/harnesses/openhands/agent-builder.js +3 -3
- package/dist/integrations/harnesses/openhands/index.js +2 -11
- package/dist/integrations/harnesses/pi/agent-builder.js +3 -11
- package/dist/integrations/harnesses/pi/index.js +3 -15
- package/dist/integrations/harnesses/shared.js +17 -0
- package/dist/integrations/harnesses/types.js +37 -2
- package/dist/integrations/lockfile.js +36 -0
- package/dist/integrations/session-logs/index.js +21 -12
- package/dist/integrations/session-logs/provider-base.js +113 -0
- package/dist/llm/client.js +7 -5
- package/dist/llm/embedders/deterministic.js +2 -2
- package/dist/llm/embedders/remote.js +8 -4
- package/dist/llm/graph-extract.js +7 -2
- package/dist/llm/metadata-enhance.js +43 -26
- package/dist/llm/structured-call.js +15 -7
- package/dist/migrate/legacy/config-source-migration.js +223 -0
- package/dist/migrate/legacy/content-migration.js +305 -0
- package/dist/migrate/legacy/legacy-layout.js +779 -0
- package/dist/migrate/legacy/legacy-paths.js +25 -0
- package/dist/migrate/legacy/legacy-stash-json.js +72 -0
- package/dist/migrate/legacy/proposal-fs-import.js +168 -0
- package/dist/migrate/legacy/task-target-ref-migration.js +272 -0
- package/dist/migrate/legacy/three-db-cutover.js +840 -0
- package/dist/migrate/legacy/workflow-migrations-bodies.js +52 -0
- package/dist/migrate/legacy/workflow-migrations-frozen.js +21 -0
- package/dist/migrate/legacy-ref-grammar.js +209 -0
- package/dist/output/command-registry.js +27 -0
- package/dist/output/html-render.js +11 -16
- package/dist/output/renderers.js +32 -276
- package/dist/output/shapes/passthrough.js +3 -9
- package/dist/output/shapes/registry.js +12 -6
- package/dist/output/text/command-format.js +547 -0
- package/dist/output/text/helpers.js +15 -1377
- package/dist/output/text/proposal-format.js +230 -0
- package/dist/output/text/registry.js +12 -6
- package/dist/output/text/show-directives.js +107 -0
- package/dist/output/text/show-format.js +103 -0
- package/dist/output/text/workflow-format.js +345 -0
- package/dist/output/text.js +1 -3
- package/dist/registry/build-index.js +13 -17
- package/dist/registry/providers/static-index.js +2 -2
- package/dist/registry/resolve.js +4 -90
- package/dist/registry/semver.js +93 -0
- package/dist/runtime.js +90 -0
- package/dist/schemas/akm-config.json +2956 -14890
- package/dist/schemas/akm-task.json +2 -2
- package/dist/schemas/akm-workflow.json +2 -2
- package/dist/scripts/migrate-storage.js +2312 -19642
- package/dist/setup/detect.js +5 -7
- package/dist/setup/engine-config.js +2 -1
- package/dist/setup/registry-stash-loader.js +1 -1
- package/dist/setup/semantic-assets.js +12 -9
- package/dist/setup/setup.js +109 -39
- package/dist/setup/steps/connection-shared.js +120 -0
- package/dist/setup/steps/connection.js +50 -274
- package/dist/setup/steps/platforms.js +1 -0
- package/dist/setup/steps/sources.js +13 -6
- package/dist/setup/steps/stashdir.js +5 -2
- package/dist/sources/freshness.js +39 -0
- package/dist/sources/providers/git-provider.js +29 -33
- package/dist/sources/providers/git-stash.js +10 -5
- package/dist/sources/providers/provider-utils.js +40 -18
- package/dist/sources/providers/website.js +1 -1
- package/dist/sources/resolve.js +5 -5
- package/dist/sources/snapshot-fetchers/types.js +4 -0
- package/dist/sources/{website-ingest.js → snapshot-fetchers/website-ingest.js} +105 -39
- package/dist/storage/database.js +47 -3
- package/dist/storage/engines/sqlite-migrations.js +34 -16
- package/dist/storage/locations.js +1 -2
- package/dist/storage/repositories/improve-runs-repository.js +0 -20
- package/dist/storage/repositories/index-connection.js +80 -0
- package/dist/storage/repositories/index-db.js +4 -3
- package/dist/storage/repositories/index-entries-repository.js +952 -0
- package/dist/{indexer/db/entry-mapper.js → storage/repositories/index-entry-mapper.js} +15 -2
- package/dist/storage/repositories/index-entry-types.js +4 -0
- package/dist/storage/repositories/index-fts-repository.js +164 -0
- package/dist/storage/repositories/index-llm-cache-repository.js +109 -0
- package/dist/storage/repositories/index-meta-repository.js +50 -0
- package/dist/{indexer/db/schema.js → storage/repositories/index-schema.js} +241 -100
- package/dist/storage/repositories/index-sql.js +12 -0
- package/dist/storage/repositories/index-utility-repository.js +369 -0
- package/dist/storage/repositories/index-vec-repository.js +245 -0
- package/dist/storage/repositories/proposals-repository.js +41 -50
- package/dist/storage/repositories/registry-cache.js +1 -1
- package/dist/storage/repositories/workflow-runs-repository.js +17 -11
- package/dist/tasks/backends/cron.js +5 -5
- package/dist/tasks/backends/exec-utils.js +21 -0
- package/dist/tasks/backends/index.js +6 -9
- package/dist/tasks/backends/launchd.js +16 -17
- package/dist/tasks/backends/schtasks.js +33 -41
- package/dist/tasks/backends/types.js +4 -0
- package/dist/tasks/parser.js +25 -5
- package/dist/tasks/runner.js +33 -39
- package/dist/tasks/validator.js +5 -6
- package/dist/workflows/authoring/authoring.js +8 -11
- package/dist/workflows/exec/brief.js +10 -7
- package/dist/workflows/exec/report.js +261 -156
- package/dist/workflows/exec/run-workflow.js +2 -1
- package/dist/workflows/exec/step-work.js +3 -9
- package/dist/workflows/program/parser.js +4 -60
- package/dist/workflows/renderer.js +11 -60
- package/dist/workflows/runtime/checkin.js +1 -1
- package/dist/workflows/runtime/plan-classifier.js +7 -4
- package/dist/workflows/runtime/runs.js +11 -10
- package/dist/workflows/runtime/unit-checkin.js +1 -1
- package/dist/workflows/runtime/unit-phases.js +20 -0
- package/dist/workflows/runtime/workflow-asset-loader.js +27 -16
- package/dist/workflows/validate-summary.js +2 -2
- package/dist/workflows/validator.js +18 -2
- package/docs/migration/release-notes/0.9.0.md +45 -3
- package/docs/migration/v0.8-to-v0.9.md +466 -262
- package/docs/{data-and-telemetry.md → reference/data-and-telemetry.md} +61 -17
- package/package.json +10 -9
- package/schemas/akm-config.json +2956 -14890
- package/schemas/akm-task.json +2 -2
- package/schemas/akm-workflow.json +2 -2
- package/dist/assets/help/help-accept.md +0 -12
- package/dist/assets/help/help-improve.md +0 -84
- package/dist/assets/help/help-proposals.md +0 -17
- package/dist/assets/help/help-propose.md +0 -17
- package/dist/assets/help/help-reject.md +0 -11
- package/dist/assets/improve-strategies/recombine-only.json +0 -23
- package/dist/assets/improve-strategies/synthesize.json +0 -17
- package/dist/assets/prompts/procedural-system.md +0 -44
- package/dist/assets/prompts/recombine-system.md +0 -40
- package/dist/assets/prompts/staleness-detect-system.md +0 -6
- package/dist/assets/templates/html/default.html +0 -78
- package/dist/assets/templates/html/vendor/echarts.min.js +0 -45
- package/dist/assets/wiki/index-template.md +0 -12
- package/dist/assets/wiki/ingest-workflow-template.md +0 -83
- package/dist/assets/wiki/log-template.md +0 -8
- package/dist/assets/wiki/schema-template.md +0 -61
- package/dist/commands/improve/calibration.js +0 -161
- package/dist/commands/improve/dedup.js +0 -482
- package/dist/commands/improve/hot-probation.js +0 -45
- package/dist/commands/improve/improve-auto-accept.js +0 -262
- package/dist/commands/improve/procedural.js +0 -403
- package/dist/commands/improve/recombine.js +0 -843
- package/dist/commands/improve/schema-similarity-gate.js +0 -168
- package/dist/commands/lint/agent-linter.js +0 -44
- package/dist/commands/lint/command-linter.js +0 -44
- package/dist/commands/lint/default-linter.js +0 -16
- package/dist/commands/lint/fact-linter.js +0 -39
- package/dist/commands/lint/knowledge-linter.js +0 -16
- package/dist/commands/lint/memory-linter.js +0 -61
- package/dist/commands/lint/registry.js +0 -41
- package/dist/commands/lint/skill-linter.js +0 -45
- package/dist/commands/lint/task-linter.js +0 -50
- package/dist/commands/lint/workflow-linter.js +0 -81
- package/dist/commands/proposal/legacy-import.js +0 -115
- package/dist/commands/wiki-cli.js +0 -291
- package/dist/core/asset/asset-registry.js +0 -76
- package/dist/core/asset/asset-spec.js +0 -316
- package/dist/core/eval/rank-metrics.js +0 -113
- package/dist/core/ripgrep/install.js +0 -163
- package/dist/core/ripgrep/resolve.js +0 -81
- package/dist/indexer/db/db.js +0 -1585
- package/dist/indexer/manifest.js +0 -170
- package/dist/indexer/passes/metadata-contributors.js +0 -31
- package/dist/integrations/harnesses/opencode-sdk/index.js +0 -25
- package/dist/output/text/wiki.js +0 -16
- package/dist/scripts/migrations/import-fs-improve-runs-to-db.js +0 -18228
- package/dist/scripts/migrations/v16-to-v17.js +0 -141
- package/dist/storage/repositories/consolidation-repository.js +0 -38
- package/dist/storage/repositories/recombine-repository.js +0 -213
- package/dist/wiki/wiki-templates.js +0 -15
- package/dist/wiki/wiki.js +0 -1013
- package/dist/workflows/db.js +0 -413
- package/docs/README.md +0 -103
- package/docs/migration/release-notes/0.9.0-beta.60.md +0 -19
- /package/dist/sources/{wiki-fetchers → snapshot-fetchers}/registry.js +0 -0
- /package/dist/sources/{wiki-fetchers → snapshot-fetchers}/youtube.js +0 -0
|
@@ -2,85 +2,7 @@
|
|
|
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
4
|
import path from "node:path";
|
|
5
|
-
import { isAssetType } from "../common.js";
|
|
6
5
|
import { UsageError } from "../errors.js";
|
|
7
|
-
/** Accepted spelling aliases mapping to a canonical asset type. */
|
|
8
|
-
const TYPE_ALIASES = {
|
|
9
|
-
environment: "env",
|
|
10
|
-
};
|
|
11
|
-
// ── Construction ────────────────────────────────────────────────────────────
|
|
12
|
-
/**
|
|
13
|
-
* Build a ref string from components.
|
|
14
|
-
*
|
|
15
|
-
* Examples:
|
|
16
|
-
* makeAssetRef("script", "deploy.sh")
|
|
17
|
-
* → "script:deploy.sh"
|
|
18
|
-
* makeAssetRef("script", "deploy.sh", "npm:@scope/pkg")
|
|
19
|
-
* → "npm:@scope/pkg//script:deploy.sh"
|
|
20
|
-
* makeAssetRef("skill", "code-review", "local")
|
|
21
|
-
* → "local//skill:code-review"
|
|
22
|
-
* makeAssetRef("script", "db/migrate/run.sh", "owner/repo")
|
|
23
|
-
* → "owner/repo//script:db/migrate/run.sh"
|
|
24
|
-
*/
|
|
25
|
-
export function makeAssetRef(type, name, origin) {
|
|
26
|
-
validateName(name);
|
|
27
|
-
const normalized = normalizeName(name);
|
|
28
|
-
const asset = `${type}:${normalized}`;
|
|
29
|
-
if (!origin)
|
|
30
|
-
return asset;
|
|
31
|
-
return `${origin}//${asset}`;
|
|
32
|
-
}
|
|
33
|
-
/**
|
|
34
|
-
* Serialize a parsed {@link AssetRef} value-object back to its canonical
|
|
35
|
-
* `[origin//]type:name` string form. The single formatter for refs — call
|
|
36
|
-
* this instead of hand-building `${type}:${name}` template strings so the
|
|
37
|
-
* serialization rules (origin prefix, name normalization) live in one place
|
|
38
|
-
* and stay in lockstep with {@link parseAssetRef}.
|
|
39
|
-
*
|
|
40
|
-
* `refToString(parseAssetRef(s))` round-trips for any `s` that
|
|
41
|
-
* `parseAssetRef` accepts.
|
|
42
|
-
*/
|
|
43
|
-
export function refToString(ref) {
|
|
44
|
-
return makeAssetRef(ref.type, ref.name, ref.origin);
|
|
45
|
-
}
|
|
46
|
-
// ── Parsing ─────────────────────────────────────────────────────────────────
|
|
47
|
-
/**
|
|
48
|
-
* Parse a ref string in the format `[origin//]type:name`.
|
|
49
|
-
*/
|
|
50
|
-
export function parseAssetRef(ref) {
|
|
51
|
-
const trimmed = ref.trim();
|
|
52
|
-
if (!trimmed)
|
|
53
|
-
throw new UsageError("Empty ref.", "MISSING_REQUIRED_ARGUMENT");
|
|
54
|
-
let origin;
|
|
55
|
-
let body = trimmed;
|
|
56
|
-
const boundary = trimmed.indexOf("//");
|
|
57
|
-
if (boundary >= 0) {
|
|
58
|
-
origin = trimmed.slice(0, boundary);
|
|
59
|
-
body = trimmed.slice(boundary + 2);
|
|
60
|
-
if (!origin)
|
|
61
|
-
throw new UsageError("Empty origin in ref.", "MISSING_REQUIRED_ARGUMENT");
|
|
62
|
-
}
|
|
63
|
-
const colon = body.indexOf(":");
|
|
64
|
-
if (colon <= 0) {
|
|
65
|
-
throw new UsageError(`Invalid ref "${trimmed}". Expected [origin//]type:name, e.g. skill:deploy or knowledge:guide.md`, "MISSING_REQUIRED_ARGUMENT");
|
|
66
|
-
}
|
|
67
|
-
const rawType = body.slice(0, colon);
|
|
68
|
-
const rawName = body.slice(colon + 1);
|
|
69
|
-
// The `vault` asset type was removed in 0.9.0. Point callers at its
|
|
70
|
-
// replacements rather than failing with a generic unknown-type error.
|
|
71
|
-
if (rawType === "vault") {
|
|
72
|
-
throw new UsageError("The `vault` asset type was removed in 0.9.0 — use `env:` (whole .env config) or `secret:` (a single value).", "MISSING_REQUIRED_ARGUMENT");
|
|
73
|
-
}
|
|
74
|
-
// Type aliases: `environment:` is an accepted spelling of the canonical
|
|
75
|
-
// `env:` type.
|
|
76
|
-
const resolvedType = TYPE_ALIASES[rawType] ?? rawType;
|
|
77
|
-
if (!isAssetType(resolvedType)) {
|
|
78
|
-
throw new UsageError(`Invalid asset type: "${rawType}".`, "MISSING_REQUIRED_ARGUMENT");
|
|
79
|
-
}
|
|
80
|
-
validateName(rawName);
|
|
81
|
-
const name = normalizeName(rawName);
|
|
82
|
-
return { type: resolvedType, name, origin: origin || undefined };
|
|
83
|
-
}
|
|
84
6
|
// ── Validation ──────────────────────────────────────────────────────────────
|
|
85
7
|
function validateName(name) {
|
|
86
8
|
if (!name)
|
|
@@ -103,3 +25,110 @@ function validateName(name) {
|
|
|
103
25
|
function normalizeName(name) {
|
|
104
26
|
return path.posix.normalize(name.replace(/\\/g, "/"));
|
|
105
27
|
}
|
|
28
|
+
/**
|
|
29
|
+
* Bundle slug charset (spec §3.4): non-empty, and excluding `:`/`.`/`#`/`/`
|
|
30
|
+
* plus whitespace. Excluding `:`/`.` is what keeps `bundle//conceptId` lexically
|
|
31
|
+
* distinguishable from a URL in prose; excluding `/` is what makes the first
|
|
32
|
+
* `//` an unambiguous bundle boundary; excluding `#` reserves it for fragments.
|
|
33
|
+
*/
|
|
34
|
+
const BUNDLE_SLUG_RE = /^[^\s:.#/]+$/;
|
|
35
|
+
/**
|
|
36
|
+
* True when `s` is a legal bundle slug (spec §11.1 / D-R5 charset: non-empty,
|
|
37
|
+
* no `:`/`.`/`#`/`/` or whitespace). Exported so the dual-grammar input dispatch
|
|
38
|
+
* (`resolve-ref.ts`) can classify a `prefix//tail` token by whether its prefix
|
|
39
|
+
* is a legal bundle slug — the clean legacy-vs-new-grammar discriminator.
|
|
40
|
+
*/
|
|
41
|
+
export function isBundleSlug(s) {
|
|
42
|
+
return BUNDLE_SLUG_RE.test(s);
|
|
43
|
+
}
|
|
44
|
+
/**
|
|
45
|
+
* Body-ref recognition (prose): the FULLY-QUALIFIED anchored form ONLY
|
|
46
|
+
* (`<bundle>//<concept-id>[#<fragment>]`, spec §11.1 — the short form is never
|
|
47
|
+
* recognized in prose). `g`/`m` for scanning; group 1 = the whole ref token.
|
|
48
|
+
*
|
|
49
|
+
* The leading `//` must be preceded by a bundle slug, so a URL (`https://…`,
|
|
50
|
+
* `//cdn.example.com/…`) never matches: a scheme carries a `:` before `//`
|
|
51
|
+
* (excluded from the slug), and a scheme-relative `//host` has no slug before
|
|
52
|
+
* its `//` at all. The bundle-slug charset here additionally excludes the prose
|
|
53
|
+
* boundary punctuation (brackets/parens/quotes/backtick/comma/angle) so a
|
|
54
|
+
* leading boundary char (e.g. the `[` of a markdown link) is not absorbed into
|
|
55
|
+
* the slug. The concept segment reuses the same terminator charset as the
|
|
56
|
+
* legacy body-ref scan (whitespace/quotes/brackets/comma/nl), and admits `/`,
|
|
57
|
+
* `.`, and a trailing `#fragment`.
|
|
58
|
+
*/
|
|
59
|
+
export const BUNDLE_REF_RE = /(?:^|[\s`"'(,[])([^\s:.#/`"'()[\],<>]+\/\/[^\s"'`)\]>,\n]+)/gm;
|
|
60
|
+
/** NFC-normalize + traversal/null-byte/drive-letter guard + path-normalize a concept id. */
|
|
61
|
+
function normalizeConceptId(raw) {
|
|
62
|
+
const nfc = raw.normalize("NFC");
|
|
63
|
+
if (nfc.includes("#")) {
|
|
64
|
+
throw new UsageError("`#` is reserved for the export fragment in a concept id.", "MISSING_REQUIRED_ARGUMENT");
|
|
65
|
+
}
|
|
66
|
+
validateName(nfc);
|
|
67
|
+
return normalizeName(nfc);
|
|
68
|
+
}
|
|
69
|
+
/**
|
|
70
|
+
* Build a fully-qualified (or short) bundle ref string from its components.
|
|
71
|
+
*
|
|
72
|
+
* Examples:
|
|
73
|
+
* makeBundleRef(undefined, "knowledge/http-caching") → "knowledge/http-caching"
|
|
74
|
+
* makeBundleRef("core", "knowledge/http-caching") → "core//knowledge/http-caching"
|
|
75
|
+
* makeBundleRef("core", "skills/review", "usage") → "core//skills/review#usage"
|
|
76
|
+
*/
|
|
77
|
+
export function makeBundleRef(bundle, conceptId, fragment) {
|
|
78
|
+
const normalized = normalizeConceptId(conceptId);
|
|
79
|
+
let out = normalized;
|
|
80
|
+
if (bundle) {
|
|
81
|
+
if (!BUNDLE_SLUG_RE.test(bundle)) {
|
|
82
|
+
throw new UsageError(`Invalid bundle slug "${bundle}". A bundle slug may not contain ':', '.', '#', '/', or whitespace.`, "MISSING_REQUIRED_ARGUMENT");
|
|
83
|
+
}
|
|
84
|
+
out = `${bundle}//${normalized}`;
|
|
85
|
+
}
|
|
86
|
+
if (fragment)
|
|
87
|
+
out = `${out}#${fragment}`;
|
|
88
|
+
return out;
|
|
89
|
+
}
|
|
90
|
+
/**
|
|
91
|
+
* Serialize a parsed {@link BundleRef} back to its canonical
|
|
92
|
+
* `[bundle//]conceptId[#fragment]` string form — the single formatter for the
|
|
93
|
+
* 0.9.0 grammar (call this instead of hand-building `${bundle}//${conceptId}`).
|
|
94
|
+
* `bundleRefToString(parseBundleRef(s))` round-trips for any `s` that
|
|
95
|
+
* `parseBundleRef` accepts.
|
|
96
|
+
*/
|
|
97
|
+
export function bundleRefToString(ref) {
|
|
98
|
+
return makeBundleRef(ref.bundle, ref.conceptId, ref.fragment);
|
|
99
|
+
}
|
|
100
|
+
/**
|
|
101
|
+
* Parse a ref string in the 0.9.0 format `[<bundle>//]<concept-id>[#<fragment>]`.
|
|
102
|
+
* The bundle prefix and the export fragment are both optional; the short form
|
|
103
|
+
* (no `bundle//`) leaves `bundle` undefined for the caller to resolve against
|
|
104
|
+
* the containing bundle (§11.1).
|
|
105
|
+
*/
|
|
106
|
+
export function parseBundleRef(ref) {
|
|
107
|
+
const trimmed = ref.trim();
|
|
108
|
+
if (!trimmed)
|
|
109
|
+
throw new UsageError("Empty ref.", "MISSING_REQUIRED_ARGUMENT");
|
|
110
|
+
let bundle;
|
|
111
|
+
let body = trimmed;
|
|
112
|
+
const boundary = trimmed.indexOf("//");
|
|
113
|
+
if (boundary >= 0) {
|
|
114
|
+
bundle = trimmed.slice(0, boundary);
|
|
115
|
+
body = trimmed.slice(boundary + 2);
|
|
116
|
+
if (!bundle)
|
|
117
|
+
throw new UsageError("Empty bundle in ref.", "MISSING_REQUIRED_ARGUMENT");
|
|
118
|
+
if (!BUNDLE_SLUG_RE.test(bundle)) {
|
|
119
|
+
throw new UsageError(`Invalid bundle slug "${bundle}" in ref "${trimmed}". A bundle slug may not contain ':', '.', '#', '/', or whitespace.`, "MISSING_REQUIRED_ARGUMENT");
|
|
120
|
+
}
|
|
121
|
+
}
|
|
122
|
+
// Export fragment: everything after the first `#` in the concept body.
|
|
123
|
+
let fragment;
|
|
124
|
+
const hash = body.indexOf("#");
|
|
125
|
+
if (hash >= 0) {
|
|
126
|
+
fragment = body.slice(hash + 1) || undefined;
|
|
127
|
+
body = body.slice(0, hash);
|
|
128
|
+
}
|
|
129
|
+
if (!body) {
|
|
130
|
+
throw new UsageError(`Invalid ref "${trimmed}". Expected [bundle//]conceptId, e.g. knowledge/guide or core//skills/review`, "MISSING_REQUIRED_ARGUMENT");
|
|
131
|
+
}
|
|
132
|
+
const conceptId = normalizeConceptId(body);
|
|
133
|
+
return { bundle: bundle || undefined, conceptId, fragment };
|
|
134
|
+
}
|
|
@@ -45,6 +45,26 @@ import { stringify as yamlStringify } from "yaml";
|
|
|
45
45
|
export function serializeFrontmatter(frontmatter) {
|
|
46
46
|
return yamlStringify(frontmatter).trimEnd();
|
|
47
47
|
}
|
|
48
|
+
/**
|
|
49
|
+
* Serialize a frontmatter object with every value `JSON.stringify`-quoted,
|
|
50
|
+
* without `---` fences and without a trailing newline.
|
|
51
|
+
*
|
|
52
|
+
* Use this instead of {@link serializeFrontmatter} when the input is a
|
|
53
|
+
* pre-validated LLM payload where `yaml.stringify` may emit shapes
|
|
54
|
+
* (`|`-block scalars, anchors, unquoted multiline) that the project's
|
|
55
|
+
* hand-rolled `parseFrontmatter` subset parser cannot read back. Every scalar
|
|
56
|
+
* becomes a quoted JSON literal; arrays become `[<json>, <json>]` (space after
|
|
57
|
+
* the comma). Field order is preserved from the input's insertion order.
|
|
58
|
+
*
|
|
59
|
+
* This is the single home for the "guaranteed-quoted scalars" serializer the
|
|
60
|
+
* module doc above anticipates; before it, `distill` (array-aware) and
|
|
61
|
+
* `distill/content-repair` (scalar-only) reimplemented it divergently.
|
|
62
|
+
*/
|
|
63
|
+
export function serializeFrontmatterQuoted(frontmatter) {
|
|
64
|
+
return Object.entries(frontmatter)
|
|
65
|
+
.map(([k, v]) => Array.isArray(v) ? `${k}: [${v.map((s) => JSON.stringify(s)).join(", ")}]` : `${k}: ${JSON.stringify(v)}`)
|
|
66
|
+
.join("\n");
|
|
67
|
+
}
|
|
48
68
|
/**
|
|
49
69
|
* Assemble a complete asset file string from a frontmatter object and a body.
|
|
50
70
|
*
|
|
@@ -151,7 +151,7 @@ export function parseFrontmatterBlock(raw) {
|
|
|
151
151
|
return {
|
|
152
152
|
frontmatter,
|
|
153
153
|
content,
|
|
154
|
-
bodyStartLine: countLines(raw.slice(0, match[0].length -
|
|
154
|
+
bodyStartLine: countLines(raw.slice(0, match[0].length - content.length)) + 1,
|
|
155
155
|
};
|
|
156
156
|
}
|
|
157
157
|
// Empty frontmatter (---\n---): the content-bearing regex above requires at
|
|
@@ -0,0 +1,223 @@
|
|
|
1
|
+
// This Source Code Form is subject to the terms of the Mozilla Public
|
|
2
|
+
// License, v. 2.0. If a copy of the MPL was not distributed with this
|
|
3
|
+
// file, You can obtain one at https://mozilla.org/MPL/2.0/.
|
|
4
|
+
/**
|
|
5
|
+
* Ref RESOLUTION layer — akm 0.9.0 Chunk-5 flip, stage F1 (ref-grammar decision
|
|
6
|
+
* D-R1 / D-R4).
|
|
7
|
+
*
|
|
8
|
+
* The 0.9.0 ref abstraction is `parse → resolve → serialize`:
|
|
9
|
+
* - parse — `parseBundleRef` (`asset-ref.ts`), pure syntax, no I/O.
|
|
10
|
+
* - resolve — {@link resolveRef} (this module): turn a maybe-short
|
|
11
|
+
* {@link BundleRef} into a fully-qualified {@link ResolvedRef}
|
|
12
|
+
* against an injected {@link RefContext}. This is the "the short
|
|
13
|
+
* form is input sugar" rule (§11.1) made structural: only a
|
|
14
|
+
* `ResolvedRef` ever crosses a storage boundary.
|
|
15
|
+
* - serialize — `bundleRefToString` (`asset-ref.ts`); serializing a
|
|
16
|
+
* `ResolvedRef` always emits the fully-qualified form.
|
|
17
|
+
*
|
|
18
|
+
* ── Cycle-safety (HARD constraint) ──
|
|
19
|
+
*
|
|
20
|
+
* This is a PURE LEAF. It imports only sibling leaves (`asset-ref`,
|
|
21
|
+
* `asset-placement`) and the `core/errors` sink — nothing from the indexer-db
|
|
22
|
+
* SCC and no `Database`/config handle. The resolution surface is INJECTED via
|
|
23
|
+
* {@link RefContext}; callers build the context from their own db handle /
|
|
24
|
+
* installation list and hand it in. Keeping the resolver free of I/O is what
|
|
25
|
+
* lets it stay out of every import cycle.
|
|
26
|
+
*
|
|
27
|
+
* ── Input-boundary parser (new-grammar only) ──
|
|
28
|
+
*
|
|
29
|
+
* {@link parseRefInput} parses a RAW user/CLI/API ref in the 0.9.0
|
|
30
|
+
* `[bundle//]conceptId` grammar and returns an {@link AssetRef} value object via
|
|
31
|
+
* the permanent D-R2 reverse table {@link typeNameFromConceptId}. Post-Chunk-8
|
|
32
|
+
* every durable ref reaching a reader is already the new grammar, so this is the
|
|
33
|
+
* ONE ref parser outside the frozen migrator — there is no stored-ref dual
|
|
34
|
+
* grammar to bridge any more.
|
|
35
|
+
*/
|
|
36
|
+
import { NotFoundError, UsageError } from "../errors.js";
|
|
37
|
+
import { stashDirFor, typeForStashDir } from "./asset-placement.js";
|
|
38
|
+
import { isBundleSlug, parseBundleRef } from "./asset-ref.js";
|
|
39
|
+
/**
|
|
40
|
+
* Resolve a maybe-short input ref to a fully-qualified {@link ResolvedRef}
|
|
41
|
+
* against `ctx`, implementing D-R4 exactly:
|
|
42
|
+
*
|
|
43
|
+
* 1. Already-qualified input (`bundle//…`) → that bundle (passthrough). When
|
|
44
|
+
* `ctx.only` is set and disagrees, that is a not-found (the ref names a
|
|
45
|
+
* bundle the caller scoped out).
|
|
46
|
+
* 2. Short input, `only` set → resolve to `only` iff it contains the concept.
|
|
47
|
+
* 3. Short input, no `only` → `defaultBundle` if it contains the concept,
|
|
48
|
+
* otherwise the FIRST bundle (priority order) that contains it.
|
|
49
|
+
* 4. No match → {@link NotFoundError} naming the forms tried.
|
|
50
|
+
*
|
|
51
|
+
* The `#fragment` is carried through untouched.
|
|
52
|
+
*/
|
|
53
|
+
export function resolveRef(input, ctx) {
|
|
54
|
+
const ref = typeof input === "string" ? parseBundleRef(input) : input;
|
|
55
|
+
const { conceptId, fragment } = ref;
|
|
56
|
+
// 1. Qualified passthrough — an explicit bundle prefix wins.
|
|
57
|
+
if (ref.bundle !== undefined) {
|
|
58
|
+
if (ctx.only !== undefined && ref.bundle !== ctx.only) {
|
|
59
|
+
throw notFound(conceptId, [`${ref.bundle}//${conceptId}`], ctx);
|
|
60
|
+
}
|
|
61
|
+
return { bundle: ref.bundle, conceptId, fragment };
|
|
62
|
+
}
|
|
63
|
+
// `only` scoping restricts the candidate set to a single bundle.
|
|
64
|
+
const candidates = ctx.only !== undefined ? ctx.bundles.filter((b) => b.id === ctx.only) : ctx.bundles;
|
|
65
|
+
// 2/3. defaultBundle wins over priority order for a short ref (but only when
|
|
66
|
+
// not `only`-scoped; an `only` request never falls back to the default).
|
|
67
|
+
if (ctx.only === undefined && ctx.defaultBundle !== undefined) {
|
|
68
|
+
const def = ctx.bundles.find((b) => b.id === ctx.defaultBundle);
|
|
69
|
+
if (def?.hasConcept(conceptId))
|
|
70
|
+
return { bundle: def.id, conceptId, fragment };
|
|
71
|
+
}
|
|
72
|
+
// First candidate (priority order) that contains the concept.
|
|
73
|
+
for (const b of candidates) {
|
|
74
|
+
if (b.hasConcept(conceptId))
|
|
75
|
+
return { bundle: b.id, conceptId, fragment };
|
|
76
|
+
}
|
|
77
|
+
throw notFound(conceptId, [conceptId], ctx);
|
|
78
|
+
}
|
|
79
|
+
function notFound(conceptId, triedForms, ctx) {
|
|
80
|
+
const scope = ctx.only !== undefined ? ` in bundle "${ctx.only}"` : "";
|
|
81
|
+
const forms = triedForms.map((f) => `"${f}"`).join(", ");
|
|
82
|
+
return new NotFoundError(`No bundle contains concept "${conceptId}"${scope} (tried ${forms}).`, "ASSET_NOT_FOUND");
|
|
83
|
+
}
|
|
84
|
+
/**
|
|
85
|
+
* D-R2 conceptId derivation from a legacy `type`/`name` pair
|
|
86
|
+
* (`stashDirFor(type)/name`; bare name for a foreign type with no placement
|
|
87
|
+
* stash-subdir). Kept self-contained so {@link displayRef} — a PERMANENT display
|
|
88
|
+
* rule — does not depend on the transient legacy shims.
|
|
89
|
+
*
|
|
90
|
+
* Exported (Chunk-8 WI-8.5c) as the ONE conceptId derivation the improve
|
|
91
|
+
* correlation sites (`eligibility.ts` candidate refs, `salience.ts`
|
|
92
|
+
* last-use lookup, `collapse-detector.ts` canary mint/score) share with the
|
|
93
|
+
* display rule — the permanent successor to the retired transient
|
|
94
|
+
* `legacyConceptId`.
|
|
95
|
+
*/
|
|
96
|
+
export function conceptIdFromTypeName(type, name) {
|
|
97
|
+
const stashDir = stashDirFor(type);
|
|
98
|
+
return stashDir !== undefined ? `${stashDir}/${name}` : name;
|
|
99
|
+
}
|
|
100
|
+
/**
|
|
101
|
+
* Build the USER-FACING / envelope ref string for an indexed item, applying the
|
|
102
|
+
* Chunk-5 flip F4b output-spelling rule (orchestrator decision; ref-grammar
|
|
103
|
+
* decision D-R2 / D-R3). This is the ONE place the rule lives — every emission
|
|
104
|
+
* site calls it instead of hand-building a ref from an entry.
|
|
105
|
+
*
|
|
106
|
+
* The rule mirrors TODAY'S origin-qualification UX, transposed to the 0.9.0
|
|
107
|
+
* grammar:
|
|
108
|
+
*
|
|
109
|
+
* - An item in the **default/primary bundle** (`bundleId` undefined, or equal
|
|
110
|
+
* to `defaultBundleId`) emits the SHORT conceptId (`knowledge/http-caching`)
|
|
111
|
+
* — exactly where the pre-0.9.0 output emitted an un-qualified `type:name`.
|
|
112
|
+
* - Any other **non-default bundle** emits the fully-qualified
|
|
113
|
+
* `bundle//conceptId`. Post-Chunk-8 every bundle id is a legal slug (the
|
|
114
|
+
* config migration assigned each source its D-R5 slug bundle key), so this
|
|
115
|
+
* is always the new grammar — a non-slug registryId now displays under its
|
|
116
|
+
* derived slug bundle id, never the retired `origin//type:name` spelling.
|
|
117
|
+
*/
|
|
118
|
+
export function displayRef(item, defaultBundleId) {
|
|
119
|
+
const conceptId = item.conceptId ?? conceptIdFromTypeName(item.type, item.name);
|
|
120
|
+
const { bundleId } = item;
|
|
121
|
+
// Default/primary bundle → SHORT conceptId (the flip). `"local"`/`"stash"` are
|
|
122
|
+
// the primary-stash origin sentinels (never real bundle slugs — they name the
|
|
123
|
+
// workspace's own stash, exactly where the pre-0.9.0 output was un-qualified),
|
|
124
|
+
// so they display short too.
|
|
125
|
+
if (bundleId === undefined || bundleId === defaultBundleId || bundleId === "local" || bundleId === "stash")
|
|
126
|
+
return conceptId;
|
|
127
|
+
// Non-default bundle → the new fully-qualified `bundle//conceptId` grammar.
|
|
128
|
+
return `${bundleId}//${conceptId}`;
|
|
129
|
+
}
|
|
130
|
+
/**
|
|
131
|
+
* Split a qualified conceptId (`<stash-subdir>/<name>`) back to its legacy
|
|
132
|
+
* `type`/`name`, or `undefined` when the leading segment is not a known stash
|
|
133
|
+
* subdir (a bare-name conceptId from a foreign type — no legacy predicate
|
|
134
|
+
* applies). The PERMANENT D-R2 reverse table: the input boundary uses it to map
|
|
135
|
+
* a new-grammar conceptId onto today's {@link AssetRef} shape. (The migrate home
|
|
136
|
+
* keeps a private transient copy for stored-ref parsing.)
|
|
137
|
+
*/
|
|
138
|
+
export function typeNameFromConceptId(conceptId) {
|
|
139
|
+
const slash = conceptId.indexOf("/");
|
|
140
|
+
if (slash <= 0)
|
|
141
|
+
return undefined;
|
|
142
|
+
const type = typeForStashDir(conceptId.slice(0, slash));
|
|
143
|
+
if (type === undefined)
|
|
144
|
+
return undefined;
|
|
145
|
+
return { type, name: conceptId.slice(slash + 1) };
|
|
146
|
+
}
|
|
147
|
+
/**
|
|
148
|
+
* Parse a RAW user / CLI / API ref string in the 0.9.0 `[bundle//]conceptId`
|
|
149
|
+
* grammar, returning it in today's {@link AssetRef} value-object shape
|
|
150
|
+
* (ref-grammar decision D-R1 / D-R4). All boundaries are NEW-GRAMMAR ONLY: a
|
|
151
|
+
* legacy `type:name` input now fails as an unknown-conceptId not-found. Post-
|
|
152
|
+
* Chunk-8 every durable ref is already the new grammar, so this parser also
|
|
153
|
+
* serves the (formerly dual-grammar) stored-ref readers.
|
|
154
|
+
*
|
|
155
|
+
* Mapping (new grammar → {@link AssetRef}):
|
|
156
|
+
* - `conceptId` → `type`/`name` via {@link typeNameFromConceptId} (the D-R2
|
|
157
|
+
* static stash-subdir table). A conceptId whose leading segment is not a
|
|
158
|
+
* known stash subdir has no legacy `type` predicate — the same outcome an
|
|
159
|
+
* unknown asset type produces today (a not-found).
|
|
160
|
+
* - `bundle` → `origin`. A new-grammar bundle slug is a registryId-shaped
|
|
161
|
+
* id by construction, so it flows straight into the legacy origin channel
|
|
162
|
+
* that `resolveSourcesForOrigin` matches on `registryId`. The SHORT form (no
|
|
163
|
+
* bundle) leaves `origin` undefined = search-all-sources.
|
|
164
|
+
* - `#fragment` → rejected. No input boundary consumes an export fragment.
|
|
165
|
+
*/
|
|
166
|
+
export function parseRefInput(raw) {
|
|
167
|
+
const ref = parseBundleRef(raw);
|
|
168
|
+
if (ref.fragment !== undefined) {
|
|
169
|
+
throw new UsageError(`Export fragment "#${ref.fragment}" is not accepted here — drop it from "${raw.trim()}".`, "INVALID_FLAG_VALUE");
|
|
170
|
+
}
|
|
171
|
+
const legacy = typeNameFromConceptId(ref.conceptId);
|
|
172
|
+
if (legacy === undefined) {
|
|
173
|
+
throw new NotFoundError(`Unrecognized asset ref "${raw.trim()}": conceptId "${ref.conceptId}" has no known asset-type prefix.`, "ASSET_NOT_FOUND");
|
|
174
|
+
}
|
|
175
|
+
return { type: legacy.type, name: legacy.name, origin: ref.bundle };
|
|
176
|
+
}
|
|
177
|
+
/**
|
|
178
|
+
* Parse a CLI/API ref that MAY be qualified by a NON-slug origin — a registry
|
|
179
|
+
* ref (`github:owner/repo`, `npm:@scope/pkg`, `git:host/path`), a bare path, or
|
|
180
|
+
* a URL — as its `origin//conceptId` prefix. Such an origin carries `:`/`.`/`/`
|
|
181
|
+
* so it is not a legal bundle slug and the strict {@link parseRefInput} rejects
|
|
182
|
+
* it; but it is still a valid SOURCE origin that `resolveSourcesForOrigin`
|
|
183
|
+
* matches by registry-id / path and the remote-fetch fallback can install. The
|
|
184
|
+
* conceptId body is parsed under the strict new grammar; the raw origin is kept
|
|
185
|
+
* as-is — the symmetric input side of {@link displayRef}, which likewise keeps
|
|
186
|
+
* `origin//…` for exactly these non-slug origins (ref-grammar decision D-R5).
|
|
187
|
+
*
|
|
188
|
+
* A short ref (no origin) or a slug-origin ref is delegated verbatim to
|
|
189
|
+
* {@link parseRefInput}, so this is a safe superset for origin-accepting
|
|
190
|
+
* commands (`show`, `clone`, `graph`, `history`).
|
|
191
|
+
*/
|
|
192
|
+
export function parseQualifiedRefInput(raw) {
|
|
193
|
+
const trimmed = raw.trim();
|
|
194
|
+
const boundary = trimmed.indexOf("//");
|
|
195
|
+
if (boundary > 0) {
|
|
196
|
+
const origin = trimmed.slice(0, boundary);
|
|
197
|
+
if (!isBundleSlug(origin)) {
|
|
198
|
+
return { ...parseRefInput(trimmed.slice(boundary + 2)), origin };
|
|
199
|
+
}
|
|
200
|
+
}
|
|
201
|
+
return parseRefInput(trimmed);
|
|
202
|
+
}
|
|
203
|
+
/**
|
|
204
|
+
* Does `raw` already read as a COMPLETE new-grammar asset ref, as opposed to a
|
|
205
|
+
* bare asset name that a boundary would prefix with a default type (the
|
|
206
|
+
* `env`/`secret`/`akm mv` "bare name" convenience)?
|
|
207
|
+
*
|
|
208
|
+
* True when `raw` is a `[bundle//]conceptId` whose conceptId leads with a KNOWN
|
|
209
|
+
* stash subdir ({@link typeNameFromConceptId} resolves it). A bare name like
|
|
210
|
+
* `prod` or `projectA/new-note` is neither — its leading segment maps to no
|
|
211
|
+
* type — so it stays a bare name for the caller to qualify.
|
|
212
|
+
*/
|
|
213
|
+
export function isFullRefInput(raw) {
|
|
214
|
+
const trimmed = raw.trim();
|
|
215
|
+
if (!trimmed)
|
|
216
|
+
return false;
|
|
217
|
+
try {
|
|
218
|
+
return typeNameFromConceptId(parseBundleRef(trimmed).conceptId) !== undefined;
|
|
219
|
+
}
|
|
220
|
+
catch {
|
|
221
|
+
return false;
|
|
222
|
+
}
|
|
223
|
+
}
|
|
@@ -54,7 +54,7 @@ export function parseMetaRef(ref) {
|
|
|
54
54
|
}
|
|
55
55
|
/**
|
|
56
56
|
* Reject meta names that would escape the `.meta/` directory. Mirrors the
|
|
57
|
-
* traversal guards in
|
|
57
|
+
* traversal guards in the ref parser's `validateName`.
|
|
58
58
|
*/
|
|
59
59
|
function assertSafeMetaName(name) {
|
|
60
60
|
if (name.includes("\0")) {
|