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
|
@@ -0,0 +1,154 @@
|
|
|
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
|
+
* The `website-snapshot` adapter — akm 0.9.0 format-family work item (#46).
|
|
6
|
+
*
|
|
7
|
+
* A READ-ONLY (Mode A) view over a materialized crawl snapshot written by
|
|
8
|
+
* `src/sources/snapshot-fetchers/website-ingest.ts` (spec §6/§7). The on-disk
|
|
9
|
+
* pages are KNOWLEDGE-shaped markdown under `stash/knowledge/**` with no `type:`
|
|
10
|
+
* field; this adapter RE-TYPES them to the open `type: website`. Per
|
|
11
|
+
* open-question-3 (RESOLVED, maintainer 2026-07) the re-type is GATED — it
|
|
12
|
+
* applies only to a page carrying the `website` tag / a `sourceUrl` (a page
|
|
13
|
+
* lacking both is not re-typed); the document KEEPS its `sourceUrl` (surfaced as
|
|
14
|
+
* `sourceRef` on `documentJson`); and the conceptId STRIPS the
|
|
15
|
+
* `stash/knowledge/` prefix. `manifest.json` is snapshot PROVENANCE
|
|
16
|
+
* (`{url, fetchedAt}`), read by the probe but never indexed as a concept.
|
|
17
|
+
*
|
|
18
|
+
* Read-only ⇒ NO `placeNew` (Mode B export routes content through the
|
|
19
|
+
* DESTINATION adapter, which owns placement). `validate` runs base checks only
|
|
20
|
+
* (a mirror the adapter does not author has no native validators); `updated`
|
|
21
|
+
* never appears on a snapshot page, so `missing-updated` is filtered out.
|
|
22
|
+
*
|
|
23
|
+
* Conformance oracle (authored, DO NOT modify): fixture
|
|
24
|
+
* `tests/fixtures/bundles/website-snapshot/` + goldens
|
|
25
|
+
* `tests/fixtures/format-family-goldens/website-snapshot/{recognition,placement,lint,renderer}.json`.
|
|
26
|
+
*/
|
|
27
|
+
import fs from "node:fs";
|
|
28
|
+
import path from "node:path";
|
|
29
|
+
import { parse as parseYaml } from "yaml";
|
|
30
|
+
import { parseFrontmatter, parseFrontmatterBlock } from "../../asset/frontmatter.js";
|
|
31
|
+
import { hashContent, nonEmptyString, runBaseValidateChecks } from "./shared.js";
|
|
32
|
+
/** A snapshot bundle is single-component; its one component is `main`. */
|
|
33
|
+
const COMPONENT_ID = "main";
|
|
34
|
+
/** The crawl page root the snapshot writer materializes pages under. */
|
|
35
|
+
const PAGES_PREFIX = "stash/knowledge/";
|
|
36
|
+
/** The provenance manifest basename (probe marker only, never indexed). */
|
|
37
|
+
const MANIFEST_FILE = "manifest.json";
|
|
38
|
+
/** The tag the snapshot writer stamps on every crawled page. */
|
|
39
|
+
const WEBSITE_TAG = "website";
|
|
40
|
+
/** Upper bound on the bounded `content` FTS field (mirrors okf-adapter). */
|
|
41
|
+
const MAX_CONTENT_CHARS = 100_000;
|
|
42
|
+
function toPosix(p) {
|
|
43
|
+
return p.replace(/\\/g, "/");
|
|
44
|
+
}
|
|
45
|
+
function parseSnapshotFrontmatter(raw) {
|
|
46
|
+
const out = { tags: [] };
|
|
47
|
+
const block = parseFrontmatterBlock(raw);
|
|
48
|
+
if (!block)
|
|
49
|
+
return out;
|
|
50
|
+
let data = {};
|
|
51
|
+
try {
|
|
52
|
+
const value = parseYaml(block.frontmatter);
|
|
53
|
+
if (value && typeof value === "object" && !Array.isArray(value))
|
|
54
|
+
data = value;
|
|
55
|
+
}
|
|
56
|
+
catch {
|
|
57
|
+
return out;
|
|
58
|
+
}
|
|
59
|
+
out.title = nonEmptyString(data.title);
|
|
60
|
+
out.description = nonEmptyString(data.description);
|
|
61
|
+
out.sourceUrl = nonEmptyString(data.sourceUrl);
|
|
62
|
+
if (Array.isArray(data.tags)) {
|
|
63
|
+
out.tags = data.tags.filter((t) => typeof t === "string" && t.trim().length > 0).map((t) => t.trim());
|
|
64
|
+
}
|
|
65
|
+
return out;
|
|
66
|
+
}
|
|
67
|
+
/** True when a page is a crawl snapshot page under `stash/knowledge/**`. */
|
|
68
|
+
function isSnapshotPage(relPath) {
|
|
69
|
+
const posix = toPosix(relPath);
|
|
70
|
+
return posix.startsWith(PAGES_PREFIX) && posix.toLowerCase().endsWith(".md");
|
|
71
|
+
}
|
|
72
|
+
/** The GATED re-type predicate (open-question-3): the page carries the `website` tag OR a `sourceUrl`. */
|
|
73
|
+
function isReTypeGated(fm) {
|
|
74
|
+
return fm.sourceUrl !== undefined || fm.tags.includes(WEBSITE_TAG);
|
|
75
|
+
}
|
|
76
|
+
/** conceptId = page path − `stash/knowledge/` prefix − `.md`. */
|
|
77
|
+
function conceptIdOf(relPath) {
|
|
78
|
+
return toPosix(relPath).slice(PAGES_PREFIX.length).replace(/\.md$/i, "");
|
|
79
|
+
}
|
|
80
|
+
function recognize(c, file) {
|
|
81
|
+
if (file.ext !== ".md" || !isSnapshotPage(file.relPath))
|
|
82
|
+
return null;
|
|
83
|
+
const raw = file.content();
|
|
84
|
+
const fm = parseSnapshotFrontmatter(raw);
|
|
85
|
+
if (!isReTypeGated(fm))
|
|
86
|
+
return null; // not a re-typed website page
|
|
87
|
+
const conceptId = conceptIdOf(file.relPath);
|
|
88
|
+
const name = fm.title ?? conceptId.split("/").pop() ?? conceptId;
|
|
89
|
+
const body = parseFrontmatter(raw).content;
|
|
90
|
+
const doc = {
|
|
91
|
+
ref: `${c.id}//${conceptId}`,
|
|
92
|
+
bundle: c.id,
|
|
93
|
+
component: COMPONENT_ID,
|
|
94
|
+
conceptId,
|
|
95
|
+
path: file.absPath,
|
|
96
|
+
hash: hashContent(raw),
|
|
97
|
+
adapterId: "website-snapshot",
|
|
98
|
+
type: "website",
|
|
99
|
+
name,
|
|
100
|
+
content: body.length > MAX_CONTENT_CHARS ? body.slice(0, MAX_CONTENT_CHARS) : body,
|
|
101
|
+
};
|
|
102
|
+
if (fm.description !== undefined)
|
|
103
|
+
doc.description = fm.description;
|
|
104
|
+
if (fm.sourceUrl !== undefined)
|
|
105
|
+
doc.documentJson = { sourceRef: fm.sourceUrl };
|
|
106
|
+
return doc;
|
|
107
|
+
}
|
|
108
|
+
async function validate(c, changes, ctx) {
|
|
109
|
+
const diagnostics = [];
|
|
110
|
+
for (const change of changes) {
|
|
111
|
+
if (change.op === "delete")
|
|
112
|
+
continue;
|
|
113
|
+
const raw = change.after ?? (await ctx.readFile(change.path));
|
|
114
|
+
if (typeof raw !== "string")
|
|
115
|
+
continue;
|
|
116
|
+
if (!isSnapshotPage(change.path))
|
|
117
|
+
continue;
|
|
118
|
+
const base = await runBaseValidateChecks(toPosix(change.path), parseFrontmatter(raw), c.root, ctx);
|
|
119
|
+
// A read-only crawl mirror carries `fetchedAt` provenance, never an `updated`
|
|
120
|
+
// field — so `missing-updated` is not a defect on a snapshot page.
|
|
121
|
+
diagnostics.push(...base.filter((d) => d.issue !== "missing-updated"));
|
|
122
|
+
}
|
|
123
|
+
return diagnostics;
|
|
124
|
+
}
|
|
125
|
+
export const websiteSnapshotAdapter = {
|
|
126
|
+
id: "website-snapshot",
|
|
127
|
+
version: "0.9.0",
|
|
128
|
+
extensions: [".md"],
|
|
129
|
+
recognize,
|
|
130
|
+
validate,
|
|
131
|
+
// No placeNew: the snapshot is READ-ONLY (Mode A). Export (Mode B) routes
|
|
132
|
+
// content through the DESTINATION adapter, which owns placement.
|
|
133
|
+
/**
|
|
134
|
+
* Install-time probe (§1.2): a root carrying the snapshot provenance
|
|
135
|
+
* `manifest.json` (`{url, fetchedAt}`). No other bundle root carries this
|
|
136
|
+
* exact marker, so the probe is unambiguous.
|
|
137
|
+
*/
|
|
138
|
+
looksLikeRoot(root) {
|
|
139
|
+
let raw;
|
|
140
|
+
try {
|
|
141
|
+
raw = fs.readFileSync(path.join(root, MANIFEST_FILE), "utf8");
|
|
142
|
+
}
|
|
143
|
+
catch {
|
|
144
|
+
return false;
|
|
145
|
+
}
|
|
146
|
+
try {
|
|
147
|
+
const manifest = JSON.parse(raw);
|
|
148
|
+
return typeof manifest.url === "string" && typeof manifest.fetchedAt === "string";
|
|
149
|
+
}
|
|
150
|
+
catch {
|
|
151
|
+
return false;
|
|
152
|
+
}
|
|
153
|
+
},
|
|
154
|
+
};
|
|
@@ -0,0 +1,42 @@
|
|
|
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
|
+
import { directoryMatcher, extensionMatcher, parentDirHintMatcher, smartMdMatcher, workflowProgramMatcher, } from "../../indexer/walk/matchers.js";
|
|
5
|
+
/**
|
|
6
|
+
* The five builtin matchers, in registration order. The array index IS the
|
|
7
|
+
* registration index `runMatchers` uses for tie-breaking. (The `wiki` matcher
|
|
8
|
+
* was removed in chunk 4 — the wiki asset-type is retired; LLM Wiki content is
|
|
9
|
+
* served by the first-class `llm-wiki` adapter, not the akm adapter.)
|
|
10
|
+
*/
|
|
11
|
+
const AKM_MATCHERS = [
|
|
12
|
+
extensionMatcher,
|
|
13
|
+
directoryMatcher,
|
|
14
|
+
parentDirHintMatcher,
|
|
15
|
+
smartMdMatcher,
|
|
16
|
+
workflowProgramMatcher,
|
|
17
|
+
];
|
|
18
|
+
/**
|
|
19
|
+
* Synchronous reproduction of `file-context.ts#runMatchers`'s arbitration
|
|
20
|
+
* (`:242-265`), minus its `ensureBuiltinsRegistered()` dynamic import. Runs
|
|
21
|
+
* every builtin matcher in registration order, collects the non-null
|
|
22
|
+
* `MatchResult`s, and returns the highest-specificity one (ties broken by the
|
|
23
|
+
* later-registered matcher — higher index — winning). Returns null when no
|
|
24
|
+
* matcher claims the file.
|
|
25
|
+
*/
|
|
26
|
+
export function recognizeMatch(file) {
|
|
27
|
+
const hits = [];
|
|
28
|
+
for (let i = 0; i < AKM_MATCHERS.length; i++) {
|
|
29
|
+
const result = AKM_MATCHERS[i](file);
|
|
30
|
+
if (result !== null)
|
|
31
|
+
hits.push({ result, index: i });
|
|
32
|
+
}
|
|
33
|
+
if (hits.length === 0)
|
|
34
|
+
return null;
|
|
35
|
+
hits.sort((a, b) => {
|
|
36
|
+
const specDiff = b.result.specificity - a.result.specificity;
|
|
37
|
+
if (specDiff !== 0)
|
|
38
|
+
return specDiff;
|
|
39
|
+
return b.index - a.index;
|
|
40
|
+
});
|
|
41
|
+
return hits[0].result;
|
|
42
|
+
}
|
|
@@ -0,0 +1,56 @@
|
|
|
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
|
+
* The format-family adapter registry — akm 0.9.0 (§4 / normative §12.6).
|
|
6
|
+
*
|
|
7
|
+
* A STATIC, FROZEN registry per normative §12.6: the ordered built-in adapter
|
|
8
|
+
* list ({@link BUILTIN_ADAPTERS}) is defined in the built-in barrel
|
|
9
|
+
* (`./adapters`) and this module exposes read-only lookups over it. There is NO
|
|
10
|
+
* mutable registration step and NO load-order dependency — `getAdapters()` and
|
|
11
|
+
* `adapterForId()` are populated at MODULE LOAD, so every production call site
|
|
12
|
+
* sees the full set without anyone first calling a registration function. This
|
|
13
|
+
* replaces the earlier mutable module-level singleton, whose "someone must
|
|
14
|
+
* register the built-ins first" contract left the registry empty in production
|
|
15
|
+
* (every source then fell back to `akm`).
|
|
16
|
+
*
|
|
17
|
+
* PRODUCTION CONSUMERS (all install/index-time, never query-time): the ordered
|
|
18
|
+
* `looksLikeRoot` probe in `installations.ts#detectAdapterId`, and the
|
|
19
|
+
* bundle-root probe in `provider-utils.ts#detectStashRoot`.
|
|
20
|
+
*
|
|
21
|
+
* KEYED BY `adapter.id` ONLY. Adapters are FORMAT FAMILIES (§0.2): one adapter
|
|
22
|
+
* per component root, and `recognize()` is the single source of truth for what
|
|
23
|
+
* a file IS. The open OKF `type` lives on the emitted `IndexDocument`, never on
|
|
24
|
+
* the adapter — so there is deliberately NO per-`type` → adapter mapping here.
|
|
25
|
+
*
|
|
26
|
+
* QUERY-TIME SAFETY (normative §14.3 / D11 — "adapters/registry never run at
|
|
27
|
+
* query time"): this module is imported only from install/index-time modules;
|
|
28
|
+
* the search path (`indexer/search/**`) does not import it, and importing the
|
|
29
|
+
* frozen list pulls the concrete adapters into no query-time graph.
|
|
30
|
+
*/
|
|
31
|
+
import { BUILTIN_ADAPTERS } from "./adapters/index.js";
|
|
32
|
+
export { BUILTIN_ADAPTERS } from "./adapters/index.js";
|
|
33
|
+
/** `adapter.id -> adapter`, frozen at module load from the static built-in list. */
|
|
34
|
+
const BY_ID = new Map(BUILTIN_ADAPTERS.map((a) => [a.id, a]));
|
|
35
|
+
/**
|
|
36
|
+
* Every built-in adapter, in the §1.2 install-time probe order (array order ==
|
|
37
|
+
* probe precedence; see `./adapters` for the ordering rationale). Returns a
|
|
38
|
+
* fresh array each call so callers may sort/filter it without disturbing the
|
|
39
|
+
* frozen registry.
|
|
40
|
+
*/
|
|
41
|
+
export function getAdapters() {
|
|
42
|
+
return [...BUILTIN_ADAPTERS];
|
|
43
|
+
}
|
|
44
|
+
/** Look up an adapter by its own `id` (matches `BundleComponent.adapter`); `undefined` for an unknown id (spec §4 — caller skips + warns). */
|
|
45
|
+
export function adapterForId(id) {
|
|
46
|
+
return BY_ID.get(id);
|
|
47
|
+
}
|
|
48
|
+
/**
|
|
49
|
+
* DEPRECATED no-op retained for test back-compat only. The registry is a static
|
|
50
|
+
* frozen map (normative §12.6) populated at module load, so there is nothing to
|
|
51
|
+
* reset — `getAdapters()` / `adapterForId()` are always the full built-in set.
|
|
52
|
+
* New code MUST NOT depend on this.
|
|
53
|
+
*/
|
|
54
|
+
export function resetAdapterRegistryForTests() {
|
|
55
|
+
// intentionally empty — the registry is static; see the doc comment above.
|
|
56
|
+
}
|
|
@@ -0,0 +1,229 @@
|
|
|
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
|
+
* Pure recognition/placement layer for the built-in akm asset types — akm
|
|
6
|
+
* 0.9.0 chunk-3 (the taxonomy-cutover leaf).
|
|
7
|
+
*
|
|
8
|
+
* This module is the SINGLE SOURCE OF TRUTH for the `AssetSpec` filesystem
|
|
9
|
+
* surface (`stashDir`/`isRelevantFile`/`toCanonicalName`/`toAssetPath`), the
|
|
10
|
+
* per-type stash-subdir map, and the derive/resolve helpers built on them.
|
|
11
|
+
* Chunk-3 deleted the mutable taxonomy globals that used to expose this data
|
|
12
|
+
* as ambient registries; the surface is now reached through the small typed
|
|
13
|
+
* accessors below (`stashDirFor`/`stashDirNames`/`placementTypes`/
|
|
14
|
+
* `assetPathForName`/`placementSpecFor`), which the `akm` bundle adapter
|
|
15
|
+
* (`adapter/adapters/akm-adapter.ts`) consumes for placement.
|
|
16
|
+
*
|
|
17
|
+
* ── Cycle-safety ──
|
|
18
|
+
*
|
|
19
|
+
* This leaf imports only Node builtins and the `core/recognition-util` pure
|
|
20
|
+
* sink, so it is NOT an import-cycle (SCC) participant. Depending on it from
|
|
21
|
+
* the `akm` adapter keeps the adapter a leaf. Renderer NAMES and action
|
|
22
|
+
* builders for the built-in types live in the static `type-presentation.ts`
|
|
23
|
+
* table (`TYPE_PRESENTATION`); they are intentionally absent here — placement
|
|
24
|
+
* is a filesystem concern, presentation is a rendering concern.
|
|
25
|
+
*/
|
|
26
|
+
import fs from "node:fs";
|
|
27
|
+
import path from "node:path";
|
|
28
|
+
import { SCRIPT_EXTENSIONS, WORKFLOW_EXTENSIONS } from "../recognition-util.js";
|
|
29
|
+
function toPosix(input) {
|
|
30
|
+
return input.replace(/\\/g, "/");
|
|
31
|
+
}
|
|
32
|
+
const workflowSpec = {
|
|
33
|
+
isRelevantFile: (fileName) => WORKFLOW_EXTENSIONS.includes(path.extname(fileName).toLowerCase()),
|
|
34
|
+
toCanonicalName: (typeRoot, filePath) => {
|
|
35
|
+
const rel = toPosix(path.relative(typeRoot, filePath));
|
|
36
|
+
for (const ext of WORKFLOW_EXTENSIONS) {
|
|
37
|
+
if (rel.toLowerCase().endsWith(ext))
|
|
38
|
+
return rel.slice(0, -ext.length);
|
|
39
|
+
}
|
|
40
|
+
return rel;
|
|
41
|
+
},
|
|
42
|
+
toAssetPath: (typeRoot, name) => {
|
|
43
|
+
// Explicit extension wins (accepts refs like "release/ship.yaml").
|
|
44
|
+
const lower = name.toLowerCase();
|
|
45
|
+
for (const ext of WORKFLOW_EXTENSIONS) {
|
|
46
|
+
if (lower.endsWith(ext))
|
|
47
|
+
return path.join(typeRoot, name);
|
|
48
|
+
}
|
|
49
|
+
// Probe in priority order — `.md` first for back-compat — and fall back
|
|
50
|
+
// to the markdown path so error messages keep naming the canonical file.
|
|
51
|
+
for (const ext of WORKFLOW_EXTENSIONS) {
|
|
52
|
+
const candidate = path.join(typeRoot, `${name}${ext}`);
|
|
53
|
+
if (fs.existsSync(candidate))
|
|
54
|
+
return candidate;
|
|
55
|
+
}
|
|
56
|
+
return path.join(typeRoot, `${name}.md`);
|
|
57
|
+
},
|
|
58
|
+
};
|
|
59
|
+
const markdownSpec = {
|
|
60
|
+
isRelevantFile: (fileName) => path.extname(fileName).toLowerCase() === ".md",
|
|
61
|
+
toCanonicalName: (typeRoot, filePath) => {
|
|
62
|
+
const rel = toPosix(path.relative(typeRoot, filePath));
|
|
63
|
+
// Strip .md extension from canonical names (agent:code-reviewer, not agent:code-reviewer.md)
|
|
64
|
+
return rel.endsWith(".md") ? rel.slice(0, -3) : rel;
|
|
65
|
+
},
|
|
66
|
+
toAssetPath: (typeRoot, name) => {
|
|
67
|
+
// Accept both with and without .md extension
|
|
68
|
+
const withExt = name.endsWith(".md") ? name : `${name}.md`;
|
|
69
|
+
return path.join(typeRoot, withExt);
|
|
70
|
+
},
|
|
71
|
+
};
|
|
72
|
+
const scriptSpec = {
|
|
73
|
+
isRelevantFile: (fileName) => SCRIPT_EXTENSIONS.has(path.extname(fileName).toLowerCase()),
|
|
74
|
+
toCanonicalName: (typeRoot, filePath) => toPosix(path.relative(typeRoot, filePath)),
|
|
75
|
+
toAssetPath: (typeRoot, name) => path.join(typeRoot, name),
|
|
76
|
+
};
|
|
77
|
+
const PLACEMENT_SPECS = {
|
|
78
|
+
skill: {
|
|
79
|
+
stashDir: "skills",
|
|
80
|
+
isRelevantFile: (fileName) => fileName === "SKILL.md",
|
|
81
|
+
toCanonicalName: (typeRoot, filePath) => {
|
|
82
|
+
const relDir = toPosix(path.dirname(path.relative(typeRoot, filePath)));
|
|
83
|
+
if (!relDir || relDir === ".")
|
|
84
|
+
return undefined;
|
|
85
|
+
return relDir;
|
|
86
|
+
},
|
|
87
|
+
toAssetPath: (typeRoot, name) => path.join(typeRoot, name, "SKILL.md"),
|
|
88
|
+
},
|
|
89
|
+
command: { stashDir: "commands", ...markdownSpec },
|
|
90
|
+
agent: { stashDir: "agents", ...markdownSpec },
|
|
91
|
+
knowledge: { stashDir: "knowledge", ...markdownSpec },
|
|
92
|
+
workflow: { stashDir: "workflows", ...workflowSpec },
|
|
93
|
+
script: { stashDir: "scripts", ...scriptSpec },
|
|
94
|
+
memory: { stashDir: "memories", ...markdownSpec },
|
|
95
|
+
// Environment assets — whole `.env` files sourced/injected wholesale. Replaced
|
|
96
|
+
// the deprecated `vault` type (removed in 0.9.0). Only key NAMES are surfaced
|
|
97
|
+
// as metadata; values and comment text are never read for indexing (comments
|
|
98
|
+
// routinely contain commented-out credentials).
|
|
99
|
+
env: {
|
|
100
|
+
stashDir: "env",
|
|
101
|
+
isRelevantFile: (fileName) => fileName === ".env" || fileName.endsWith(".env"),
|
|
102
|
+
toCanonicalName: (typeRoot, filePath) => {
|
|
103
|
+
const rel = toPosix(path.relative(typeRoot, filePath));
|
|
104
|
+
const fileName = path.basename(rel);
|
|
105
|
+
// Treat ".env" as the "default" env; "<name>.env" → "<name>"
|
|
106
|
+
if (fileName === ".env") {
|
|
107
|
+
const dir = path.dirname(rel);
|
|
108
|
+
return dir === "." || dir === "" ? "default" : `${dir}/default`;
|
|
109
|
+
}
|
|
110
|
+
const stripped = rel.endsWith(".env") ? rel.slice(0, -4) : rel;
|
|
111
|
+
return stripped;
|
|
112
|
+
},
|
|
113
|
+
toAssetPath: (typeRoot, name) => {
|
|
114
|
+
if (name === "default")
|
|
115
|
+
return path.join(typeRoot, ".env");
|
|
116
|
+
return path.join(typeRoot, name.endsWith(".env") ? name : `${name}.env`);
|
|
117
|
+
},
|
|
118
|
+
},
|
|
119
|
+
// Secrets — a single sensitive value used on its own for authentication (a
|
|
120
|
+
// PEM key, API token, TLS cert). Unlike `env` (a group of related .env
|
|
121
|
+
// configuration), the ENTIRE file is the one secret value — there is no safe
|
|
122
|
+
// region to parse, so only the filename is ever surfaced as metadata. A
|
|
123
|
+
// secret is any regular file under `secrets/` except `.lock`/`.sensitive`
|
|
124
|
+
// sidecars; the canonical name preserves the natural filename.
|
|
125
|
+
secret: {
|
|
126
|
+
stashDir: "secrets",
|
|
127
|
+
isRelevantFile: (fileName) => !fileName.endsWith(".lock") && !fileName.endsWith(".sensitive"),
|
|
128
|
+
toCanonicalName: (typeRoot, filePath) => toPosix(path.relative(typeRoot, filePath)),
|
|
129
|
+
toAssetPath: (typeRoot, name) => path.join(typeRoot, name),
|
|
130
|
+
},
|
|
131
|
+
// v1 spec §13 — `lesson` asset type. Required frontmatter fields are
|
|
132
|
+
// `description` and `when_to_use`; lint enforces both.
|
|
133
|
+
lesson: { stashDir: "lessons", ...markdownSpec },
|
|
134
|
+
// Scheduled tasks. A task file pairs a cron-style schedule with a target
|
|
135
|
+
// (workflow ref, prompt, or command). Stored as pure YAML under
|
|
136
|
+
// <stash>/tasks/<id>.yml.
|
|
137
|
+
task: {
|
|
138
|
+
stashDir: "tasks",
|
|
139
|
+
isRelevantFile: (fileName) => path.extname(fileName).toLowerCase() === ".yml",
|
|
140
|
+
toCanonicalName: (typeRoot, filePath) => {
|
|
141
|
+
const rel = toPosix(path.relative(typeRoot, filePath));
|
|
142
|
+
return rel.endsWith(".yml") ? rel.slice(0, -4) : rel;
|
|
143
|
+
},
|
|
144
|
+
toAssetPath: (typeRoot, name) => {
|
|
145
|
+
const withExt = name.endsWith(".yml") ? name : `${name}.yml`;
|
|
146
|
+
return path.join(typeRoot, withExt);
|
|
147
|
+
},
|
|
148
|
+
},
|
|
149
|
+
// #561 — agent sessions indexed as a first-class searchable asset type.
|
|
150
|
+
// Generated markdown written by the `extract` pass to
|
|
151
|
+
// `sessions/<harness>/<session-id>.md`.
|
|
152
|
+
session: { stashDir: "sessions", ...markdownSpec },
|
|
153
|
+
// Durable stash-level semantic knowledge — facts about the user, team, or
|
|
154
|
+
// project. A plain markdown spec; see docs/architecture/specs/fact-asset-type.md.
|
|
155
|
+
fact: { stashDir: "facts", ...markdownSpec },
|
|
156
|
+
};
|
|
157
|
+
/** Live placement spec for a type, or `undefined` for an unknown type. */
|
|
158
|
+
export function placementSpecFor(type) {
|
|
159
|
+
return PLACEMENT_SPECS[type];
|
|
160
|
+
}
|
|
161
|
+
/** Every registered placement spec (for whole-registry sweeps). */
|
|
162
|
+
export function placementSpecList() {
|
|
163
|
+
return Object.values(PLACEMENT_SPECS);
|
|
164
|
+
}
|
|
165
|
+
/** Every registered placement type key (the set of types that have a stash subdir). */
|
|
166
|
+
export function placementTypes() {
|
|
167
|
+
return Object.keys(PLACEMENT_SPECS);
|
|
168
|
+
}
|
|
169
|
+
/** The stash subdir a type places into, or `undefined` for an unknown type. */
|
|
170
|
+
export function stashDirFor(type) {
|
|
171
|
+
return PLACEMENT_SPECS[type]?.stashDir;
|
|
172
|
+
}
|
|
173
|
+
/**
|
|
174
|
+
* Reverse of {@link stashDirFor}: the placement type owning a stash subdir, or
|
|
175
|
+
* `undefined` when no registered type places into it. The type→subdir map is a
|
|
176
|
+
* bijection over the built-in types (each type has a distinct subdir), so this
|
|
177
|
+
* is the well-defined inverse. Used by the Chunk-5 dual-grammar shim to reverse
|
|
178
|
+
* a D-R2 qualified conceptId (`<stash-subdir>/<name>`) back to a legacy
|
|
179
|
+
* `type:name` predicate so NULL-`item_ref` rows stay findable by new refs.
|
|
180
|
+
*/
|
|
181
|
+
export function typeForStashDir(stashDir) {
|
|
182
|
+
for (const [type, spec] of Object.entries(PLACEMENT_SPECS)) {
|
|
183
|
+
if (spec.stashDir === stashDir)
|
|
184
|
+
return type;
|
|
185
|
+
}
|
|
186
|
+
return undefined;
|
|
187
|
+
}
|
|
188
|
+
/** All stash subdir names across the registered types. */
|
|
189
|
+
export function stashDirNames() {
|
|
190
|
+
return Object.values(PLACEMENT_SPECS).map((spec) => spec.stashDir);
|
|
191
|
+
}
|
|
192
|
+
/**
|
|
193
|
+
* Mutate the placement registry to add/replace a type's spec. Used by the
|
|
194
|
+
* custom-asset-type registration surface (extension types); built-ins are
|
|
195
|
+
* baked into {@link PLACEMENT_SPECS} above.
|
|
196
|
+
*/
|
|
197
|
+
export function registerAssetSpec(type, spec) {
|
|
198
|
+
PLACEMENT_SPECS[type] = spec;
|
|
199
|
+
}
|
|
200
|
+
/** Remove a previously-registered type's spec. */
|
|
201
|
+
export function deregisterAssetSpec(type) {
|
|
202
|
+
delete PLACEMENT_SPECS[type];
|
|
203
|
+
}
|
|
204
|
+
export function isRelevantAssetFile(assetType, fileName) {
|
|
205
|
+
return PLACEMENT_SPECS[assetType]?.isRelevantFile(fileName) ?? false;
|
|
206
|
+
}
|
|
207
|
+
export function deriveCanonicalAssetName(assetType, typeRoot, filePath) {
|
|
208
|
+
return PLACEMENT_SPECS[assetType]?.toCanonicalName(typeRoot, filePath);
|
|
209
|
+
}
|
|
210
|
+
export function deriveCanonicalAssetNameFromStashRoot(assetType, stashRoot, filePath) {
|
|
211
|
+
const relPath = toPosix(path.relative(stashRoot, filePath));
|
|
212
|
+
const segments = relPath.split("/").filter(Boolean);
|
|
213
|
+
const firstSegment = segments[0];
|
|
214
|
+
// When the first segment matches the canonical type dir (e.g. "agents"),
|
|
215
|
+
// use it as the type root so canonical names are relative to it.
|
|
216
|
+
// Otherwise fall back to stashRoot — this preserves the full relative path
|
|
217
|
+
// as the canonical name, which is correct for installed stashes that live
|
|
218
|
+
// under custom directories (e.g. "tools/agents/svelte-file-editor").
|
|
219
|
+
const typeRoot = firstSegment !== undefined && firstSegment === stashDirFor(assetType)
|
|
220
|
+
? path.join(stashRoot, firstSegment)
|
|
221
|
+
: stashRoot;
|
|
222
|
+
return deriveCanonicalAssetName(assetType, typeRoot, filePath);
|
|
223
|
+
}
|
|
224
|
+
export function assetPathForName(assetType, typeRoot, name) {
|
|
225
|
+
const spec = PLACEMENT_SPECS[assetType];
|
|
226
|
+
if (!spec)
|
|
227
|
+
throw new Error(`Unknown asset type: "${assetType}"`);
|
|
228
|
+
return spec.toAssetPath(typeRoot, name);
|
|
229
|
+
}
|