akm-cli 0.9.0-rc.0 → 0.9.0-rc.13
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 +1283 -22
- package/README.md +62 -37
- package/SECURITY.md +46 -31
- package/dist/akm +162 -38
- package/dist/akm-migrate +44 -0
- package/dist/assets/backends/schtasks-template.xml +2 -1
- package/dist/assets/hints/cli-hints-full.md +268 -118
- package/dist/assets/hints/cli-hints-short.md +87 -24
- package/dist/assets/{profiles → improve-strategies}/catchup.json +3 -1
- package/dist/assets/{profiles → improve-strategies}/consolidate.json +3 -1
- package/dist/assets/{profiles → improve-strategies}/default.json +6 -7
- package/dist/assets/improve-strategies/frequent.json +15 -0
- package/dist/assets/{profiles → improve-strategies}/graph-refresh.json +4 -2
- package/dist/assets/{profiles → improve-strategies}/memory-focus.json +4 -1
- package/dist/assets/{profiles → improve-strategies}/proactive-maintenance.json +5 -5
- package/dist/assets/{profiles → improve-strategies}/quick.json +4 -2
- package/dist/assets/improve-strategies/reflect-distill.json +30 -0
- package/dist/assets/{profiles → 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/memory-infer-user.md +2 -3
- 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/prompts/workflow-unit-preamble.md +26 -0
- package/dist/assets/stash-skeleton/README.md +38 -10
- package/dist/assets/stash-skeleton/facts/conventions/assets/agent.md +8 -0
- package/dist/assets/stash-skeleton/facts/conventions/assets/command.md +8 -0
- package/dist/assets/stash-skeleton/facts/conventions/assets/fact.md +14 -1
- package/dist/assets/stash-skeleton/facts/conventions/assets/knowledge.md +13 -1
- package/dist/assets/stash-skeleton/facts/conventions/assets/lesson.md +9 -1
- package/dist/assets/stash-skeleton/facts/conventions/assets/memory.md +11 -0
- package/dist/assets/stash-skeleton/facts/conventions/assets/script.md +9 -0
- package/dist/assets/stash-skeleton/facts/conventions/assets/skill.md +9 -0
- package/dist/assets/stash-skeleton/facts/conventions/assets/workflow.md +8 -0
- package/dist/assets/stash-skeleton/facts/conventions/backlinks.md +100 -0
- package/dist/assets/stash-skeleton/facts/conventions/domains.md +64 -0
- package/dist/assets/stash-skeleton/facts/conventions/organization.md +136 -0
- package/dist/assets/tasks/core/extract.yml +3 -2
- package/dist/assets/tasks/core/improve.yml +2 -1
- package/dist/assets/tasks/core/index-refresh.yml +1 -0
- package/dist/assets/tasks/core/sync.yml +1 -0
- package/dist/assets/tasks/core/version-check.yml +2 -1
- package/dist/assets/tasks/improve/akm-graph-refresh-weekly.yml +5 -0
- package/dist/assets/tasks/improve/akm-improve-catchup.yml +8 -0
- package/dist/assets/tasks/improve/akm-improve-consolidate.yml +5 -0
- package/dist/assets/tasks/improve/akm-improve-frequent.yml +5 -0
- package/dist/assets/tasks/improve/akm-improve-nightly.yml +5 -0
- package/dist/assets/templates/html/health.html +5 -4
- package/dist/assets/workflows/workflow-template.md +31 -15
- package/dist/cli/invocation.js +279 -0
- package/dist/cli/parse-args.js +5 -90
- package/dist/cli/retired-commands.js +78 -0
- package/dist/cli/shared.js +158 -48
- package/dist/cli-node.mjs +2 -1
- package/dist/cli.js +747 -293
- package/dist/commands/agent/agent-dispatch.js +19 -18
- package/dist/commands/agent/agent-support.js +0 -24
- package/dist/commands/agent/contribute-cli.js +43 -97
- package/dist/commands/completions.js +80 -23
- package/dist/commands/config-cli.js +44 -281
- package/dist/commands/env/env-binding.js +99 -0
- package/dist/commands/env/env-cli.js +84 -224
- package/dist/commands/env/env.js +12 -163
- package/dist/commands/env/marker-path.js +6 -0
- package/dist/commands/env/secret-cli.js +45 -61
- package/dist/commands/env/secret.js +32 -62
- package/dist/commands/feedback-cli.js +179 -85
- package/dist/commands/health/accept-rate.js +58 -0
- package/dist/commands/health/advisories.js +7 -8
- package/dist/commands/health/checks.js +279 -94
- package/dist/commands/health/html-report.js +197 -578
- package/dist/commands/health/improve-metrics.js +277 -246
- package/dist/commands/health/llm-usage.js +19 -19
- package/dist/commands/health/md-report.js +16 -7
- package/dist/commands/health/metrics.js +67 -32
- package/dist/commands/health/renderers.js +47 -0
- package/dist/commands/health/report-view-model.js +508 -0
- package/dist/commands/health/stash-exposure.js +1 -1
- package/dist/commands/health/surfaces.js +16 -56
- package/dist/commands/health/task-runs.js +3 -67
- package/dist/{migrate-storage-node.mjs → commands/health/types-checks.js} +1 -5
- package/dist/commands/health/types-improve.js +29 -0
- package/dist/{output/text/save.js → commands/health/types-metrics.js} +1 -2
- 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 +2 -3
- package/dist/commands/health.js +296 -167
- package/dist/commands/improve/anti-collapse.js +5 -5
- package/dist/commands/improve/autonomy-gate.js +68 -0
- package/dist/commands/improve/collapse-detector.js +65 -52
- package/dist/commands/improve/consolidate/chunking.js +9 -7
- package/dist/commands/improve/consolidate/eligibility.js +1 -23
- package/dist/commands/improve/consolidate/merge.js +4 -0
- package/dist/commands/improve/consolidate.js +454 -1354
- 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 +89 -64
- package/dist/commands/improve/distill/quality-gate.js +118 -42
- package/dist/commands/improve/distill-guards.js +1 -1
- package/dist/commands/improve/distill-promotion-policy.js +33 -888
- package/dist/commands/improve/distill.js +607 -363
- package/dist/commands/improve/eligibility.js +165 -79
- package/dist/commands/improve/extract-cli.js +35 -126
- package/dist/commands/improve/extract-prompt.js +6 -35
- package/dist/commands/improve/extract.js +640 -391
- package/dist/commands/improve/feedback-valence.js +2 -12
- package/dist/commands/improve/improve-cli.js +134 -135
- package/dist/commands/improve/improve-result-file.js +30 -50
- package/dist/commands/improve/improve-run-types.js +4 -0
- package/dist/commands/improve/improve-strategies.js +135 -0
- package/dist/commands/improve/improve.js +904 -701
- package/dist/commands/improve/locks.js +64 -111
- package/dist/commands/improve/loop-stages.js +1110 -923
- package/dist/commands/improve/memory/derived-ref.js +124 -0
- package/dist/commands/improve/memory/memory-belief.js +79 -7
- package/dist/commands/improve/memory/memory-contradiction-detect.js +49 -52
- package/dist/commands/improve/memory/memory-improve.js +25 -37
- package/dist/commands/improve/outcome-loop.js +25 -88
- package/dist/commands/improve/preparation.js +1034 -813
- package/dist/commands/improve/proactive-maintenance.js +34 -9
- package/dist/commands/improve/proposal-envelope.js +31 -0
- package/dist/commands/improve/reflect.js +983 -794
- package/dist/commands/improve/run-context.js +119 -0
- package/dist/commands/improve/salience.js +24 -127
- package/dist/commands/improve/session-asset.js +7 -3
- package/dist/commands/improve/shared.js +14 -34
- package/dist/commands/improve/source-identity.js +28 -0
- package/dist/commands/improve/triage.js +20 -17
- package/dist/commands/lint/base-linter.js +340 -313
- package/dist/commands/lint/env-key-rules.js +31 -47
- package/dist/commands/lint/index.js +185 -30
- package/dist/commands/{events.js → log.js} +28 -38
- package/dist/commands/migrate-cli.js +54 -0
- package/dist/commands/migration-tool.js +55 -0
- package/dist/commands/observability-cli.js +70 -208
- package/dist/commands/proposal/diff-format.js +50 -0
- package/dist/commands/proposal/drain-policies.js +0 -6
- package/dist/commands/proposal/drain.js +91 -40
- package/dist/commands/proposal/proposal-cli.js +134 -132
- package/dist/commands/proposal/proposal-types.js +56 -0
- package/dist/commands/proposal/proposal.js +83 -65
- package/dist/commands/proposal/propose-cli.js +88 -0
- package/dist/commands/proposal/propose.js +105 -88
- package/dist/commands/proposal/repository.js +1303 -278
- package/dist/commands/proposal/validators/proposal-quality-validators.js +16 -6
- package/dist/commands/proposal/validators/proposal-validators.js +61 -12
- package/dist/commands/proposal/validators/proposals.js +6 -8
- package/dist/commands/read/curate.js +78 -73
- package/dist/commands/read/knowledge.js +510 -13
- package/dist/commands/read/registry-search.js +2 -2
- package/dist/commands/read/remember-cli.js +84 -15
- package/dist/commands/read/search-cli.js +203 -96
- package/dist/commands/read/search.js +126 -94
- package/dist/commands/read/show.js +226 -250
- package/dist/commands/registry-cli.js +34 -60
- package/dist/commands/remember.js +18 -57
- package/dist/commands/sources/add-cli.js +104 -49
- package/dist/commands/sources/bundle-cli.js +166 -0
- package/dist/commands/sources/bundle-config-ops.js +63 -0
- package/dist/commands/sources/info.js +27 -15
- package/dist/commands/sources/init.js +30 -40
- package/dist/commands/sources/installed-stashes.js +469 -172
- package/dist/commands/sources/migration-help.js +7 -4
- package/dist/commands/sources/schema-repair.js +10 -9
- package/dist/commands/sources/self-update.js +182 -121
- package/dist/commands/sources/source-add.js +169 -178
- package/dist/commands/sources/source-clone.js +144 -41
- package/dist/commands/sources/source-manage.js +94 -59
- package/dist/commands/sources/sources-cli.js +64 -205
- package/dist/commands/sources/stash-cli.js +91 -54
- package/dist/commands/sources/stash-skeleton.js +1 -1
- package/dist/commands/tasks/tasks-cli.js +106 -104
- package/dist/commands/tasks/tasks.js +445 -262
- package/dist/commands/workflow-cli.js +232 -121
- 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 +528 -0
- package/dist/core/adapter/adapters/akm-lint.js +392 -0
- package/dist/core/adapter/adapters/akm-metadata.js +387 -0
- package/dist/core/adapter/adapters/akm-task-adapter.js +149 -0
- package/dist/core/adapter/adapters/akm-workflow-adapter.js +180 -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 +119 -0
- package/dist/core/adapter/adapters/index.js +80 -0
- package/dist/core/adapter/adapters/llm-wiki-adapter.js +419 -0
- package/dist/core/adapter/adapters/okf-adapter.js +391 -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 +217 -0
- package/dist/core/adapter/adapters/website-snapshot-adapter.js +155 -0
- package/dist/core/adapter/bundle-adapter.js +4 -0
- package/dist/core/adapter/detect-adapter.js +17 -0
- package/dist/core/adapter/recognize-match.js +44 -0
- package/dist/core/adapter/registry.js +56 -0
- package/dist/core/adapter/types.js +4 -0
- package/dist/core/asset/akm-markdown.js +30 -0
- package/dist/core/asset/asset-placement.js +243 -0
- package/dist/core/asset/asset-ref.js +110 -79
- package/dist/core/asset/asset-serialize.js +20 -0
- package/dist/core/asset/frontmatter.js +28 -12
- package/dist/core/asset/markdown.js +40 -51
- package/dist/core/asset/resolve-ref.js +274 -0
- package/dist/core/asset/stash-meta.js +2 -2
- package/dist/core/bundle-id.js +51 -0
- package/dist/core/common.js +281 -86
- package/dist/core/config/config-io.js +42 -128
- package/dist/core/config/config-schema.js +233 -834
- package/dist/core/config/config-sources.js +162 -39
- package/dist/core/config/config-types.js +16 -11
- package/dist/core/config/config-version.js +29 -0
- package/dist/core/config/config-walker.js +126 -37
- package/dist/core/config/config.js +154 -331
- package/dist/core/config/deep-merge.js +41 -0
- package/dist/core/config/engine-semantics.js +28 -0
- package/dist/core/config/experimental.js +21 -0
- package/dist/core/config/schema/embedding.js +38 -0
- package/dist/core/config/schema/engines.js +116 -0
- package/dist/core/config/schema/experimental.js +47 -0
- package/dist/core/config/schema/feedback.js +31 -0
- package/dist/core/config/schema/improve-processes.js +389 -0
- package/dist/core/config/schema/improve.js +94 -0
- package/dist/core/config/schema/index-config.js +176 -0
- package/dist/core/config/schema/output.js +18 -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 +18 -0
- package/dist/core/config/schema/sources-bundles.js +169 -0
- package/dist/core/config/schema/workflow.js +29 -0
- package/dist/core/env-secret-ref.js +155 -20
- package/dist/core/errors.js +17 -15
- package/dist/core/events-types.js +4 -0
- package/dist/core/events.js +46 -128
- package/dist/core/extra-params.js +62 -0
- package/dist/core/file-change.js +17 -0
- package/dist/core/file-lock.js +202 -57
- package/dist/core/fs-txn.js +392 -0
- package/dist/core/git-message.js +59 -0
- package/dist/core/improve-result.js +167 -0
- package/dist/core/json-schema.js +142 -0
- package/dist/core/lesson-lint.js +1 -17
- package/dist/core/logs-db.js +1 -1
- package/dist/core/maintenance-barrier.js +135 -0
- package/dist/core/migration-operation.js +44 -0
- package/dist/core/mutation-target.js +78 -0
- package/dist/core/paths.js +22 -25
- package/dist/core/platform.js +10 -0
- package/dist/core/recognition-util.js +128 -0
- package/dist/core/redaction.js +392 -0
- package/dist/core/standards/resolve-standards-context.js +36 -65
- package/dist/core/standards/resolve-stash-standards.js +2 -2
- package/dist/core/standards/resolve-type-conventions.js +5 -5
- package/dist/core/state/migrations.js +242 -11
- package/dist/core/state-db.js +98 -10
- package/dist/core/structured.js +1 -1
- package/dist/core/subprocess.js +303 -0
- package/dist/core/text-truncation.js +9 -5
- package/dist/core/time.js +20 -0
- package/dist/core/type-presentation.js +130 -0
- package/dist/core/warn.js +0 -3
- package/dist/core/write-source.js +834 -118
- package/dist/indexer/bundle-identity-guard.js +92 -0
- package/dist/indexer/db/graph-db.js +1 -25
- package/dist/indexer/db/llm-cache.js +1 -1
- package/dist/indexer/ensure-index.js +30 -9
- package/dist/indexer/graph/graph-boost.js +9 -30
- package/dist/indexer/graph/graph-extraction.js +41 -27
- package/dist/indexer/graph/graph-types.js +4 -0
- package/dist/indexer/index-writer-lock.js +93 -49
- package/dist/indexer/index-written-assets.js +100 -53
- package/dist/indexer/indexer.js +746 -329
- package/dist/indexer/init.js +18 -25
- package/dist/indexer/installations.js +142 -0
- package/dist/indexer/passes/dir-staleness.js +18 -10
- package/dist/indexer/passes/memory-inference.js +25 -15
- package/dist/indexer/passes/metadata.js +412 -243
- package/dist/indexer/scan/doc-to-entry.js +160 -0
- package/dist/indexer/scan/drain-dir.js +134 -0
- package/dist/indexer/search/db-search.js +292 -108
- package/dist/indexer/search/fts-query.js +64 -0
- package/dist/indexer/search/ranking-contributors.js +145 -25
- package/dist/indexer/search/ranking-types.js +4 -0
- package/dist/indexer/search/ranking.js +28 -71
- package/dist/indexer/search/search-attribution.js +67 -0
- package/dist/indexer/search/search-fields.js +18 -3
- package/dist/indexer/search/search-hit-enrichers.js +30 -40
- package/dist/indexer/search/search-source.js +157 -111
- package/dist/indexer/search/semantic-status.js +4 -1
- package/dist/indexer/usage/usage-events.js +10 -30
- package/dist/indexer/walk/file-context.js +3 -45
- package/dist/indexer/walk/matchers.js +42 -34
- package/dist/indexer/walk/path-resolver.js +11 -5
- package/dist/indexer/walk/walker.js +42 -14
- package/dist/integrations/agent/builder-shared.js +7 -0
- package/dist/integrations/agent/builders.js +5 -56
- package/dist/integrations/agent/config.js +3 -143
- package/dist/integrations/agent/detect.js +17 -2
- package/dist/integrations/agent/engine-resolution.js +231 -0
- package/dist/integrations/agent/index.js +1 -2
- package/dist/integrations/agent/model-aliases.js +16 -2
- package/dist/integrations/agent/profiles.js +36 -62
- package/dist/integrations/agent/prompts.js +46 -18
- package/dist/integrations/agent/runner-dispatch.js +93 -4
- package/dist/integrations/agent/runner.js +76 -208
- package/dist/integrations/agent/spawn.js +88 -196
- package/dist/integrations/harnesses/aider/agent-builder.js +114 -0
- package/dist/integrations/harnesses/aider/index.js +48 -0
- package/dist/integrations/harnesses/aider/result-extractor.js +53 -0
- package/dist/integrations/harnesses/amazonq/agent-builder.js +147 -0
- package/dist/integrations/harnesses/amazonq/index.js +45 -0
- package/dist/integrations/harnesses/amazonq/result-extractor.js +48 -0
- package/dist/integrations/harnesses/claude/agent-builder.js +46 -8
- package/dist/integrations/harnesses/claude/config-import.js +1 -3
- package/dist/integrations/harnesses/claude/index.js +24 -35
- package/dist/integrations/harnesses/claude/result-extractor.js +52 -0
- package/dist/integrations/harnesses/claude/session-log.js +27 -75
- package/dist/integrations/harnesses/codex/agent-builder.js +138 -0
- package/dist/integrations/harnesses/codex/index.js +52 -0
- package/dist/integrations/harnesses/codex/result-extractor.js +73 -0
- package/dist/integrations/harnesses/copilot/agent-builder.js +122 -0
- package/dist/integrations/harnesses/copilot/index.js +48 -0
- package/dist/integrations/harnesses/copilot/result-extractor.js +151 -0
- package/dist/integrations/harnesses/gemini/agent-builder.js +120 -0
- package/dist/integrations/harnesses/gemini/index.js +48 -0
- package/dist/integrations/harnesses/gemini/result-extractor.js +121 -0
- package/dist/integrations/harnesses/ids.js +24 -0
- package/dist/integrations/harnesses/index.js +54 -34
- package/dist/integrations/harnesses/opencode/agent-builder.js +23 -5
- package/dist/integrations/harnesses/opencode/config-import.js +1 -3
- package/dist/integrations/harnesses/opencode/index.js +14 -32
- package/dist/integrations/harnesses/opencode/session-log.js +67 -125
- package/dist/integrations/harnesses/opencode-sdk/harness.js +51 -0
- package/dist/integrations/harnesses/opencode-sdk/sdk-runner.js +681 -108
- package/dist/integrations/harnesses/openhands/agent-builder.js +128 -0
- package/dist/integrations/harnesses/openhands/index.js +48 -0
- package/dist/integrations/harnesses/openhands/result-extractor.js +103 -0
- package/dist/integrations/harnesses/pi/agent-builder.js +97 -0
- package/dist/integrations/harnesses/pi/index.js +45 -0
- package/dist/integrations/harnesses/pi/result-extractor.js +135 -0
- package/dist/integrations/harnesses/shared.js +17 -0
- package/dist/integrations/harnesses/types.js +43 -32
- package/dist/integrations/lockfile.js +211 -24
- package/dist/integrations/session-logs/index.js +36 -39
- package/dist/integrations/session-logs/provider-base.js +113 -0
- package/dist/llm/client.js +182 -110
- package/dist/llm/embedders/deterministic.js +2 -2
- package/dist/llm/embedders/remote.js +21 -9
- package/dist/llm/feature-gate.js +17 -57
- package/dist/llm/graph-extract.js +12 -13
- package/dist/llm/index-passes.js +8 -42
- package/dist/llm/memory-infer.js +144 -1
- package/dist/llm/metadata-enhance.js +45 -30
- package/dist/llm/structured-call.js +16 -8
- package/dist/llm/usage-persist.js +30 -5
- package/dist/llm/usage-telemetry.js +59 -6
- package/dist/output/cli-hints.js +1 -2
- package/dist/output/command-registry.js +27 -0
- package/dist/output/context.js +22 -7
- package/dist/output/format-exempt.js +80 -0
- package/dist/output/generic-render.js +251 -0
- package/dist/output/html-render.js +11 -16
- package/dist/output/render-registry.js +57 -0
- package/dist/output/renderers.js +14 -279
- package/dist/output/shapes/curate.js +10 -1
- package/dist/output/shapes/events.js +12 -7
- package/dist/output/shapes/helpers.js +58 -84
- package/dist/output/shapes/passthrough.js +11 -39
- package/dist/output/shapes/proposal/producer.js +15 -7
- package/dist/output/shapes/registry.js +12 -6
- package/dist/output/shapes.js +0 -9
- package/dist/output/text/{init.js → bundle-create.js} +3 -1
- package/dist/output/text/bundle-show.js +7 -0
- package/dist/output/text/command-format.js +562 -0
- package/dist/output/text/env.js +1 -3
- package/dist/output/text/events.js +8 -7
- package/dist/output/text/helpers.js +15 -1164
- package/dist/output/text/proposal/producer.js +4 -2
- package/dist/output/text/proposal-format.js +202 -0
- package/dist/output/text/registry-commands.js +1 -2
- package/dist/output/text/registry.js +12 -6
- package/dist/output/text/show-directives.js +117 -0
- package/dist/output/text/show-format.js +103 -0
- package/dist/output/text/sync.js +5 -0
- package/dist/output/text/workflow-format.js +332 -0
- package/dist/output/text/workflow.js +3 -2
- package/dist/output/text.js +10 -19
- package/dist/registry/factory.js +4 -6
- package/dist/registry/origin-resolve.js +16 -27
- package/dist/registry/providers/skills-sh.js +3 -3
- package/dist/registry/providers/static-index.js +15 -25
- package/dist/registry/resolve.js +43 -94
- package/dist/registry/semver.js +43 -0
- package/dist/runtime.js +81 -12
- package/dist/scripts/akm-migrate.js +35529 -0
- package/dist/setup/detect.js +5 -7
- package/dist/setup/detected-engines.js +136 -0
- package/dist/setup/engine-config.js +100 -0
- package/dist/setup/registry-stash-loader.js +3 -3
- package/dist/setup/semantic-assets.js +12 -9
- package/dist/setup/setup.js +444 -208
- package/dist/setup/steps/connection-shared.js +120 -0
- package/dist/setup/steps/connection.js +108 -305
- package/dist/setup/steps/platforms.js +13 -12
- package/dist/setup/steps/semantic.js +15 -3
- package/dist/setup/steps/sources.js +21 -15
- package/dist/setup/steps/stashdir.js +6 -4
- package/dist/setup/steps/tasks.js +236 -119
- package/dist/setup/steps.js +3 -2
- package/dist/sources/freshness.js +39 -0
- package/dist/sources/provider-factory.js +11 -17
- package/dist/sources/providers/filesystem.js +2 -3
- package/dist/sources/providers/git-install.js +278 -34
- package/dist/sources/providers/git-provider.js +54 -56
- package/dist/sources/providers/git-stash.js +420 -91
- package/dist/sources/providers/git.js +2 -2
- package/dist/sources/providers/npm.js +16 -19
- package/dist/sources/providers/provider-utils.js +47 -22
- package/dist/sources/providers/sync-from-ref.js +3 -9
- package/dist/sources/providers/website.js +2 -2
- package/dist/sources/resolve.js +11 -10
- package/dist/sources/snapshot-fetchers/types.js +4 -0
- package/dist/sources/{website-ingest.js → snapshot-fetchers/website-ingest.js} +110 -41
- package/dist/storage/database.js +60 -4
- package/dist/storage/engines/sqlite-migrations.js +156 -5
- package/dist/storage/locations.js +1 -2
- package/dist/storage/repositories/canaries-repository.js +1 -1
- package/dist/storage/repositories/events-repository.js +51 -11
- package/dist/storage/repositories/improve-runs-repository.js +6 -32
- package/dist/storage/repositories/index-connection.js +79 -0
- package/dist/storage/repositories/index-db.js +4 -3
- package/dist/storage/repositories/index-entries-repository.js +863 -0
- package/dist/{indexer/db/entry-mapper.js → storage/repositories/index-entry-mapper.js} +19 -2
- package/dist/storage/repositories/index-entry-types.js +4 -0
- package/dist/storage/repositories/index-fts-repository.js +167 -0
- package/dist/storage/repositories/index-llm-cache-repository.js +108 -0
- package/dist/storage/repositories/index-meta-repository.js +49 -0
- package/dist/{indexer/db/schema.js → storage/repositories/index-schema.js} +226 -100
- package/dist/storage/repositories/index-sql.js +12 -0
- package/dist/storage/repositories/index-utility-repository.js +356 -0
- package/dist/storage/repositories/index-vec-repository.js +250 -0
- package/dist/storage/repositories/outcome-repository.js +119 -0
- package/dist/storage/repositories/proposals-repository.js +317 -75
- package/dist/storage/repositories/registry-cache.js +1 -1
- package/dist/storage/repositories/salience-repository.js +172 -0
- package/dist/storage/repositories/task-history-repository.js +110 -3
- package/dist/storage/repositories/workflow-runs-repository.js +240 -19
- package/dist/tasks/backends/cron.js +169 -46
- package/dist/tasks/backends/exec-utils.js +76 -3
- package/dist/tasks/backends/index.js +6 -9
- package/dist/tasks/backends/launchd.js +292 -55
- package/dist/tasks/backends/schtasks.js +557 -70
- package/dist/tasks/backends/types.js +4 -0
- package/dist/tasks/command-executable.js +93 -0
- package/dist/tasks/embedded.js +56 -38
- package/dist/tasks/parser.js +156 -64
- package/dist/tasks/resolve-akm-bin.js +144 -51
- package/dist/tasks/runner.js +377 -209
- package/dist/tasks/schedule.js +108 -19
- package/dist/tasks/scheduler-invocation.js +296 -0
- package/dist/tasks/schema.js +1 -1
- package/dist/tasks/task-id.js +35 -0
- package/dist/tasks/validator.js +30 -16
- package/dist/text-import-hook.mjs +1 -1
- package/dist/workflows/authoring/authoring.js +104 -43
- package/dist/workflows/authoring/scope-key.js +1 -1
- package/dist/workflows/cli.js +0 -16
- package/dist/workflows/concurrency-policy.js +15 -0
- package/dist/workflows/exec/brief.js +450 -0
- package/dist/workflows/exec/frozen-judge.js +47 -0
- package/dist/workflows/exec/native-executor.js +1038 -0
- package/dist/workflows/exec/param-secrets.js +115 -0
- package/dist/workflows/exec/report.js +1460 -0
- package/dist/workflows/exec/run-workflow.js +602 -0
- package/dist/workflows/exec/scheduler.js +71 -0
- package/dist/workflows/exec/step-work.js +1190 -0
- package/dist/workflows/exec/unit-writer.js +23 -0
- package/dist/workflows/exec/workflow-engine-gate.js +67 -0
- package/dist/workflows/exec/worktree.js +171 -0
- package/dist/workflows/ir/compile.js +246 -0
- package/dist/workflows/ir/freeze.js +233 -0
- package/dist/workflows/ir/params.js +54 -0
- package/dist/workflows/ir/plan-hash.js +68 -0
- package/dist/workflows/ir/schema.js +540 -0
- package/dist/workflows/parser.js +878 -304
- package/dist/workflows/program/expressions.js +181 -0
- package/dist/workflows/program/schema.js +51 -0
- package/dist/workflows/renderer.js +100 -45
- package/dist/workflows/resource-limits.js +22 -0
- package/dist/workflows/runtime/agent-identity.js +59 -14
- package/dist/workflows/runtime/checkin.js +1 -1
- package/dist/workflows/runtime/plan-classifier.js +131 -0
- package/dist/workflows/runtime/runs.js +376 -119
- package/dist/workflows/runtime/unit-checkin.js +45 -0
- package/dist/workflows/runtime/unit-phases.js +20 -0
- package/dist/workflows/runtime/workflow-asset-loader.js +241 -40
- package/dist/workflows/schema.js +1 -11
- package/dist/workflows/validate-summary.js +2 -3
- package/dist/workflows/validator.js +52 -30
- package/docs/README.md +42 -78
- package/docs/migration/README.md +8 -0
- package/docs/migration/release-notes/0.6.0.md +1 -1
- package/docs/migration/release-notes/0.7.0.md +9 -8
- package/docs/migration/release-notes/0.9.0.md +158 -14
- package/docs/migration/v0.7-to-v0.8.md +46 -47
- package/docs/migration/v0.8-to-v0.9.md +844 -0
- package/docs/reference/README.md +12 -0
- package/docs/reference/data-and-telemetry.md +333 -0
- package/package.json +21 -17
- package/schemas/akm-asset-envelope.json +93 -0
- package/schemas/akm-config.json +4636 -0
- package/schemas/akm-task.json +87 -0
- package/schemas/akm-workflow.json +373 -0
- package/dist/akm-migrate-storage +0 -38
- 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/profiles/frequent.json +0 -13
- package/dist/assets/profiles/recombine-only.json +0 -21
- package/dist/assets/profiles/reflect-distill.json +0 -30
- package/dist/assets/profiles/synthesize.json +0 -15
- 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/tasks/core/backup.yml +0 -4
- package/dist/assets/tasks/graph-refresh-weekly.yml +0 -10
- 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/cli/config-migrate.js +0 -150
- package/dist/cli/config-validate.js +0 -39
- package/dist/commands/graph/graph-cli.js +0 -124
- package/dist/commands/graph/graph.js +0 -487
- package/dist/commands/improve/calibration.js +0 -161
- package/dist/commands/improve/dedup.js +0 -482
- package/dist/commands/improve/extract-watch.js +0 -140
- package/dist/commands/improve/hot-probation.js +0 -45
- package/dist/commands/improve/improve-auto-accept.js +0 -276
- package/dist/commands/improve/improve-profiles.js +0 -168
- package/dist/commands/improve/procedural.js +0 -398
- package/dist/commands/improve/recombine.js +0 -818
- 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/sources/history.js +0 -196
- package/dist/commands/tasks/default-tasks.js +0 -186
- package/dist/commands/wiki-cli.js +0 -292
- package/dist/core/asset/asset-registry.js +0 -76
- package/dist/core/asset/asset-spec.js +0 -259
- package/dist/core/config/config-migration.js +0 -602
- package/dist/core/deep-merge.js +0 -38
- 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 -1413
- package/dist/indexer/manifest.js +0 -170
- package/dist/indexer/passes/metadata-contributors.js +0 -31
- package/dist/indexer/usage/unmigrated-vaults-guard.js +0 -94
- package/dist/integrations/harnesses/opencode-sdk/index.js +0 -49
- package/dist/llm/call-ai.js +0 -62
- package/dist/llm/memory-infer-impl.js +0 -138
- package/dist/output/shapes/distill.js +0 -14
- package/dist/output/shapes/history.js +0 -11
- package/dist/output/text/distill.js +0 -6
- package/dist/output/text/enable-disable.js +0 -8
- package/dist/output/text/history.js +0 -6
- package/dist/output/text/wiki.js +0 -16
- package/dist/registry/build-index.js +0 -386
- package/dist/scripts/migrate-storage.js +0 -19108
- package/dist/scripts/migrations/import-fs-improve-runs-to-db.js +0 -9411
- package/dist/scripts/migrations/v16-to-v17.js +0 -141
- package/dist/setup/legacy-config.js +0 -106
- 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 -1012
- package/dist/workflows/db.js +0 -215
- package/docs/data-and-telemetry.md +0 -226
- /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,391 @@
|
|
|
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 reference `okf` adapter — akm 0.9.0 chunk-2, WI-A.
|
|
6
|
+
*
|
|
7
|
+
* Implements `docs/architecture/specs/akm-0.9.0-bundle-adapter-spec.md` §5 (the reference
|
|
8
|
+
* OKF adapter) + §5.1 (BINDING: `okf` reads `type` FROM FRONTMATTER, with NO
|
|
9
|
+
* directory gate) EXACTLY. This is pure OKF: `type` from frontmatter, identity
|
|
10
|
+
* from path, no directory routing anywhere.
|
|
11
|
+
*
|
|
12
|
+
* - recognize (§5): any `.md` NOT named `index.md`/`log.md` (case-insensitive,
|
|
13
|
+
* reserved) → one concept. `type` = frontmatter `type` when a non-empty
|
|
14
|
+
* string, else the `knowledge` default. conceptId = the concept's path
|
|
15
|
+
* within the component root minus `.md`. The OKF field projection (§0.1/§3):
|
|
16
|
+
* name ← title (fallback: last path segment), description ← description,
|
|
17
|
+
* tags ← tags, updated ← timestamp. The directory a file sits in NEVER
|
|
18
|
+
* affects `type`.
|
|
19
|
+
* - links (§9): BOTH OKF link forms — `/`-rooted bundle-relative and standard
|
|
20
|
+
* relative — resolve deterministically into target conceptIds, stored on
|
|
21
|
+
* `IndexDocument.links`. Unresolvable / out-of-component links are dropped
|
|
22
|
+
* (tolerant).
|
|
23
|
+
* - validate (§5, LENIENT): base checks only; unknown frontmatter never fails;
|
|
24
|
+
* `missing-type` is INFO; `missing-ref` on OKF links is a non-blocking
|
|
25
|
+
* WARNING (consumers tolerate broken links). Reads go through
|
|
26
|
+
* `ctx.readFile`; ref existence via `ctx.resolveRef`. Never touches the live
|
|
27
|
+
* filesystem.
|
|
28
|
+
* - directoryList / looksLikeRoot per §5 / §1.2. Authoring is deliberately
|
|
29
|
+
* absent; AKM-native writers fail before mutating an OKF bundle.
|
|
30
|
+
*/
|
|
31
|
+
import fs from "node:fs";
|
|
32
|
+
import path from "node:path";
|
|
33
|
+
import { parseFrontmatter } from "../../asset/frontmatter.js";
|
|
34
|
+
import { hashContent, nonEmptyString, readTags, runBaseValidateChecks } from "./shared.js";
|
|
35
|
+
/** v0.2 frontmatter keys consumed into first-class fields below (§0.1) — excluded from the generic `documentJson` extras fold alongside the v0.1 five, so nothing is duplicated between a first-class field and the opaque extras bag. */
|
|
36
|
+
const CONSUMED_FRONTMATTER_KEYS = [
|
|
37
|
+
"type",
|
|
38
|
+
"title",
|
|
39
|
+
"description",
|
|
40
|
+
"tags",
|
|
41
|
+
"timestamp",
|
|
42
|
+
"generated",
|
|
43
|
+
"verified",
|
|
44
|
+
"sources",
|
|
45
|
+
"status",
|
|
46
|
+
"stale_after",
|
|
47
|
+
"okf_version",
|
|
48
|
+
];
|
|
49
|
+
/** True for a plain (non-null, non-array) object — the shape every v0.2 mapping (`generated`, one `verified`/`sources` entry) must have. */
|
|
50
|
+
function isPlainObject(value) {
|
|
51
|
+
return value !== null && typeof value === "object" && !Array.isArray(value);
|
|
52
|
+
}
|
|
53
|
+
/**
|
|
54
|
+
* Parse one `verified:` actor mapping (`{by, at?}`). Tolerant: a missing/blank
|
|
55
|
+
* `by` yields `undefined` (the entry is dropped, never rejecting the document
|
|
56
|
+
* — OKF conformance leniency); `at` is independently optional.
|
|
57
|
+
*/
|
|
58
|
+
function parseActorMapping(value) {
|
|
59
|
+
if (!isPlainObject(value))
|
|
60
|
+
return undefined;
|
|
61
|
+
const by = nonEmptyString(value.by);
|
|
62
|
+
if (by === undefined)
|
|
63
|
+
return undefined;
|
|
64
|
+
const at = nonEmptyString(value.at);
|
|
65
|
+
return at !== undefined ? { by, at } : { by };
|
|
66
|
+
}
|
|
67
|
+
/**
|
|
68
|
+
* Parse the `verified:` family. v0.2 permits EITHER a list of `{by, at?}`
|
|
69
|
+
* mappings OR a single mapping written without the list dash (the shorthand
|
|
70
|
+
* form) — both normalize to a non-empty array here. Malformed entries are
|
|
71
|
+
* dropped individually; an entirely-empty/malformed result is `undefined`
|
|
72
|
+
* rather than `[]` (mirrors every other optional-field convention on this
|
|
73
|
+
* adapter: absent, not empty).
|
|
74
|
+
*/
|
|
75
|
+
function parseVerified(value) {
|
|
76
|
+
if (value === undefined || value === null)
|
|
77
|
+
return undefined;
|
|
78
|
+
const candidates = Array.isArray(value) ? value : [value];
|
|
79
|
+
const out = [];
|
|
80
|
+
for (const candidate of candidates) {
|
|
81
|
+
const parsed = parseActorMapping(candidate);
|
|
82
|
+
if (parsed)
|
|
83
|
+
out.push(parsed);
|
|
84
|
+
}
|
|
85
|
+
return out.length > 0 ? out : undefined;
|
|
86
|
+
}
|
|
87
|
+
/**
|
|
88
|
+
* Parse the `sources:` object-list family. Each entry needs at minimum a
|
|
89
|
+
* non-empty `resource`; entries failing that are dropped individually (never
|
|
90
|
+
* rejects the document). This is a DIFFERENT shape from the AKM-native
|
|
91
|
+
* `IndexDocument.sources: string[]` (wiki citations) — the two are never
|
|
92
|
+
* mixed, hence the caller lands this under `provenance.sources` instead.
|
|
93
|
+
*/
|
|
94
|
+
function parseOkfSources(value) {
|
|
95
|
+
if (!Array.isArray(value))
|
|
96
|
+
return undefined;
|
|
97
|
+
const out = [];
|
|
98
|
+
for (const item of value) {
|
|
99
|
+
if (!isPlainObject(item))
|
|
100
|
+
continue;
|
|
101
|
+
const resource = nonEmptyString(item.resource);
|
|
102
|
+
if (resource === undefined)
|
|
103
|
+
continue;
|
|
104
|
+
const entry = { resource };
|
|
105
|
+
const id = nonEmptyString(item.id);
|
|
106
|
+
if (id !== undefined)
|
|
107
|
+
entry.id = id;
|
|
108
|
+
const title = nonEmptyString(item.title);
|
|
109
|
+
if (title !== undefined)
|
|
110
|
+
entry.title = title;
|
|
111
|
+
const author = nonEmptyString(item.author);
|
|
112
|
+
if (author !== undefined)
|
|
113
|
+
entry.author = author;
|
|
114
|
+
if (typeof item.usage_count === "number" && Number.isFinite(item.usage_count)) {
|
|
115
|
+
entry.usage_count = item.usage_count;
|
|
116
|
+
}
|
|
117
|
+
const lastModified = nonEmptyString(item.last_modified);
|
|
118
|
+
if (lastModified !== undefined)
|
|
119
|
+
entry.last_modified = lastModified;
|
|
120
|
+
out.push(entry);
|
|
121
|
+
}
|
|
122
|
+
return out.length > 0 ? out : undefined;
|
|
123
|
+
}
|
|
124
|
+
/** Parse the `status:` lifecycle field — a strict whitelist; any other value (including a foreign/future status) is left unset rather than guessed at. */
|
|
125
|
+
function parseLifecycleStatus(value) {
|
|
126
|
+
return value === "draft" || value === "stable" || value === "deprecated" ? value : undefined;
|
|
127
|
+
}
|
|
128
|
+
/** Reserved OKF files (case-insensitive) — recognized, never indexed as concepts (§5, OKF §1.4). */
|
|
129
|
+
const RESERVED_FILES = new Set(["index.md", "log.md"]);
|
|
130
|
+
/** Upper bound on the bounded `content` FTS field (§3: "content: FTS 1 (bounded)"). Small fixtures are never truncated. */
|
|
131
|
+
const MAX_CONTENT_CHARS = 100_000;
|
|
132
|
+
/** POSIX-normalize separators without importing a cycle-participant helper. */
|
|
133
|
+
function toPosix(p) {
|
|
134
|
+
return p.replace(/\\/g, "/");
|
|
135
|
+
}
|
|
136
|
+
/** True when `name` (a bare file name) is a reserved OKF file, case-insensitively. */
|
|
137
|
+
function isReservedFileName(name) {
|
|
138
|
+
return RESERVED_FILES.has(name.toLowerCase());
|
|
139
|
+
}
|
|
140
|
+
/**
|
|
141
|
+
* Resolve BOTH OKF link forms found in a concept body into target conceptIds
|
|
142
|
+
* (§9, §5):
|
|
143
|
+
* - `/`-rooted bundle-relative — `[x](/tables/customers.md)` — resolved from
|
|
144
|
+
* the component root;
|
|
145
|
+
* - standard relative — `[y](./other.md)`, `[z](../a/b.md)` — resolved
|
|
146
|
+
* relative to the linking concept's own directory.
|
|
147
|
+
* Both are resolved against the component root, `.md` stripped, to yield a
|
|
148
|
+
* component-root-relative conceptId (matching how `recognize` derives the
|
|
149
|
+
* target file's own conceptId). Deterministic string/path work — no LLM, no
|
|
150
|
+
* I/O. Non-`.md` targets, external schemes (`http:`…), in-page anchors, and any
|
|
151
|
+
* link that escapes the component root are dropped (tolerant, §5). Order of
|
|
152
|
+
* first appearance is preserved; duplicates collapse.
|
|
153
|
+
*/
|
|
154
|
+
export function resolveOkfLinks(body, fileRelPath) {
|
|
155
|
+
const dir = path.posix.dirname(toPosix(fileRelPath));
|
|
156
|
+
const definitions = new Map();
|
|
157
|
+
for (const match of body.matchAll(/^\s*\[([^\]]+)\]:\s*(\S+)/gm)) {
|
|
158
|
+
definitions.set(match[1].trim().toLowerCase(), match[2]);
|
|
159
|
+
}
|
|
160
|
+
const candidates = [];
|
|
161
|
+
for (const match of body.matchAll(/\[[^\]]*\]\(([^)]+)\)/g)) {
|
|
162
|
+
candidates.push({ index: match.index, target: match[1] });
|
|
163
|
+
}
|
|
164
|
+
for (const match of body.matchAll(/(?<!!)\[[^\]]*\]\[([^\]]+)\]/g)) {
|
|
165
|
+
const target = definitions.get(match[1].trim().toLowerCase());
|
|
166
|
+
if (target)
|
|
167
|
+
candidates.push({ index: match.index, target });
|
|
168
|
+
}
|
|
169
|
+
candidates.sort((a, b) => a.index - b.index);
|
|
170
|
+
const out = [];
|
|
171
|
+
const seen = new Set();
|
|
172
|
+
for (const candidate of candidates) {
|
|
173
|
+
let target = candidate.target.trim();
|
|
174
|
+
// Drop an optional markdown link title: `[x](/a.md "Title")`.
|
|
175
|
+
const wsIdx = target.search(/\s/);
|
|
176
|
+
if (wsIdx >= 0)
|
|
177
|
+
target = target.slice(0, wsIdx);
|
|
178
|
+
// Strip fragment / query.
|
|
179
|
+
const hashIdx = target.indexOf("#");
|
|
180
|
+
if (hashIdx >= 0)
|
|
181
|
+
target = target.slice(0, hashIdx);
|
|
182
|
+
const queryIdx = target.indexOf("?");
|
|
183
|
+
if (queryIdx >= 0)
|
|
184
|
+
target = target.slice(0, queryIdx);
|
|
185
|
+
if (!target)
|
|
186
|
+
continue;
|
|
187
|
+
// Skip external schemes (http:, mailto:, …) and protocol-relative URLs.
|
|
188
|
+
if (/^[a-z][a-z0-9+.-]*:/i.test(target))
|
|
189
|
+
continue;
|
|
190
|
+
if (target.startsWith("//"))
|
|
191
|
+
continue;
|
|
192
|
+
// Only concept links (`.md`).
|
|
193
|
+
if (!target.toLowerCase().endsWith(".md"))
|
|
194
|
+
continue;
|
|
195
|
+
let resolved;
|
|
196
|
+
if (target.startsWith("/")) {
|
|
197
|
+
// Bundle/component-root-relative.
|
|
198
|
+
resolved = path.posix.normalize(target.slice(1));
|
|
199
|
+
}
|
|
200
|
+
else {
|
|
201
|
+
// Standard relative — resolve against the linking concept's directory.
|
|
202
|
+
const base = dir === "." ? "" : dir;
|
|
203
|
+
resolved = path.posix.normalize(path.posix.join(base, target));
|
|
204
|
+
}
|
|
205
|
+
// Drop anything that escapes the component root.
|
|
206
|
+
if (resolved.startsWith("../") || resolved === ".." || resolved.startsWith("/"))
|
|
207
|
+
continue;
|
|
208
|
+
const conceptId = resolved.replace(/\.md$/i, "");
|
|
209
|
+
if (!conceptId || seen.has(conceptId))
|
|
210
|
+
continue;
|
|
211
|
+
seen.add(conceptId);
|
|
212
|
+
out.push(conceptId);
|
|
213
|
+
}
|
|
214
|
+
return out;
|
|
215
|
+
}
|
|
216
|
+
function recognize(c, file) {
|
|
217
|
+
// `okf` owns `.md` only (extensions: [".md"]). No directory gate anywhere.
|
|
218
|
+
if (file.ext !== ".md")
|
|
219
|
+
return null;
|
|
220
|
+
// Reserved OKF files are recognized (excluded), never indexed as concepts.
|
|
221
|
+
if (isReservedFileName(file.fileName))
|
|
222
|
+
return null;
|
|
223
|
+
const conceptId = toPosix(file.relPath).replace(/\.md$/i, "");
|
|
224
|
+
const raw = file.content();
|
|
225
|
+
const parsed = parseFrontmatter(raw);
|
|
226
|
+
const data = parsed.data;
|
|
227
|
+
const body = parsed.content;
|
|
228
|
+
// §5.1 BINDING: `type` from FRONTMATTER; default `knowledge` when absent.
|
|
229
|
+
const type = nonEmptyString(data.type) ?? "knowledge";
|
|
230
|
+
// §0.1/§3 OKF field projection.
|
|
231
|
+
const lastSegment = conceptId.split("/").pop() ?? conceptId;
|
|
232
|
+
const name = nonEmptyString(data.title) ?? lastSegment;
|
|
233
|
+
const description = nonEmptyString(data.description);
|
|
234
|
+
const tags = readTags(data.tags);
|
|
235
|
+
const links = resolveOkfLinks(body, file.relPath);
|
|
236
|
+
// v0.2 trust/provenance/lifecycle families (§0.1, okf-support.md v0.2 note).
|
|
237
|
+
// `generated.at` — v0.2's replacement for `timestamp` — takes precedence;
|
|
238
|
+
// `timestamp` remains a fully valid fallback (the v0.2-permitted legacy
|
|
239
|
+
// reading, not merely tolerated). Both stay fully optional (never rejects).
|
|
240
|
+
const generatedMapping = isPlainObject(data.generated) ? data.generated : undefined;
|
|
241
|
+
const generatedAt = generatedMapping ? nonEmptyString(generatedMapping.at) : undefined;
|
|
242
|
+
const generatedBy = generatedMapping ? nonEmptyString(generatedMapping.by) : undefined;
|
|
243
|
+
const legacyTimestamp = nonEmptyString(data.timestamp);
|
|
244
|
+
const updated = generatedAt ?? legacyTimestamp;
|
|
245
|
+
const verified = parseVerified(data.verified);
|
|
246
|
+
const okfSources = parseOkfSources(data.sources);
|
|
247
|
+
const provenance = generatedBy !== undefined || generatedAt !== undefined || verified !== undefined || okfSources !== undefined
|
|
248
|
+
? {
|
|
249
|
+
...(generatedBy !== undefined ? { generatedBy } : {}),
|
|
250
|
+
...(generatedAt !== undefined ? { generatedAt } : {}),
|
|
251
|
+
...(verified !== undefined ? { verified } : {}),
|
|
252
|
+
...(okfSources !== undefined ? { sources: okfSources } : {}),
|
|
253
|
+
}
|
|
254
|
+
: undefined;
|
|
255
|
+
const lifecycleStatus = parseLifecycleStatus(data.status);
|
|
256
|
+
const staleAfter = nonEmptyString(data.stale_after);
|
|
257
|
+
// `okf_version` is upstream-declared only on a bundle-root `index.md` (never
|
|
258
|
+
// indexed as a concept, §5) — read defensively from any concept anyway
|
|
259
|
+
// (best-effort, conformance Rule 9); a producer that also tags ordinary
|
|
260
|
+
// concepts with it is neither rejected nor silently ignored.
|
|
261
|
+
const okfVersion = nonEmptyString(data.okf_version);
|
|
262
|
+
const doc = {
|
|
263
|
+
ref: `${c.id}//${conceptId}`,
|
|
264
|
+
bundle: c.id,
|
|
265
|
+
component: c.id,
|
|
266
|
+
conceptId,
|
|
267
|
+
path: file.absPath,
|
|
268
|
+
// hash over the full raw file (frontmatter + body) so any edit invalidates
|
|
269
|
+
// incrementality/fingerprints (`types.ts` hash doc comment).
|
|
270
|
+
hash: hashContent(raw),
|
|
271
|
+
adapterId: "okf",
|
|
272
|
+
ownsPresentation: true,
|
|
273
|
+
type,
|
|
274
|
+
name,
|
|
275
|
+
content: body.length > MAX_CONTENT_CHARS ? body.slice(0, MAX_CONTENT_CHARS) : body,
|
|
276
|
+
};
|
|
277
|
+
if (description !== undefined)
|
|
278
|
+
doc.description = description;
|
|
279
|
+
if (tags !== undefined)
|
|
280
|
+
doc.tags = tags;
|
|
281
|
+
if (updated !== undefined)
|
|
282
|
+
doc.updated = updated;
|
|
283
|
+
if (links.length > 0)
|
|
284
|
+
doc.links = links;
|
|
285
|
+
if (provenance !== undefined)
|
|
286
|
+
doc.provenance = provenance;
|
|
287
|
+
if (lifecycleStatus !== undefined)
|
|
288
|
+
doc.lifecycleStatus = lifecycleStatus;
|
|
289
|
+
if (staleAfter !== undefined)
|
|
290
|
+
doc.staleAfter = staleAfter;
|
|
291
|
+
if (okfVersion !== undefined)
|
|
292
|
+
doc.okfVersion = okfVersion;
|
|
293
|
+
const extras = Object.fromEntries(Object.entries(data).filter(([key]) => !CONSUMED_FRONTMATTER_KEYS.includes(key)));
|
|
294
|
+
if (Object.keys(extras).length > 0)
|
|
295
|
+
doc.documentJson = extras;
|
|
296
|
+
return doc;
|
|
297
|
+
}
|
|
298
|
+
async function validate(c, changes, ctx) {
|
|
299
|
+
const diagnostics = [];
|
|
300
|
+
for (const change of changes) {
|
|
301
|
+
if (change.op === "delete")
|
|
302
|
+
continue;
|
|
303
|
+
const raw = change.after ?? (await ctx.readFile(change.path));
|
|
304
|
+
if (typeof raw !== "string")
|
|
305
|
+
continue;
|
|
306
|
+
const relPath = toPosix(change.path);
|
|
307
|
+
const fileName = relPath.split("/").pop() ?? relPath;
|
|
308
|
+
const reserved = isReservedFileName(fileName);
|
|
309
|
+
const parsed = parseFrontmatter(raw);
|
|
310
|
+
// Base checks shared with native AKM formats. OKF's timestamp is optional,
|
|
311
|
+
// so the AKM-specific freshness diagnostic is removed unconditionally.
|
|
312
|
+
const base = await runBaseValidateChecks(relPath, parsed, c.root, ctx);
|
|
313
|
+
for (const diag of base) {
|
|
314
|
+
if (diag.issue === "missing-updated")
|
|
315
|
+
continue;
|
|
316
|
+
diagnostics.push(diag);
|
|
317
|
+
}
|
|
318
|
+
if (reserved)
|
|
319
|
+
continue; // reserved files are not concepts — no type / link checks
|
|
320
|
+
// §5: `missing-type` is INFO (not an error) — never blocks.
|
|
321
|
+
if (nonEmptyString(parsed.data.type) === undefined) {
|
|
322
|
+
diagnostics.push({
|
|
323
|
+
file: relPath,
|
|
324
|
+
issue: "missing-type",
|
|
325
|
+
detail: "info: no frontmatter `type`; defaults to `knowledge` (OKF leniency, non-blocking)",
|
|
326
|
+
fixed: false,
|
|
327
|
+
});
|
|
328
|
+
}
|
|
329
|
+
// §5/§9: broken OKF links are a non-blocking WARNING — consumers tolerate them.
|
|
330
|
+
for (const conceptId of resolveOkfLinks(parsed.content, relPath)) {
|
|
331
|
+
const { exists } = await ctx.resolveRef(conceptId);
|
|
332
|
+
if (!exists) {
|
|
333
|
+
diagnostics.push({
|
|
334
|
+
file: relPath,
|
|
335
|
+
issue: "missing-ref",
|
|
336
|
+
detail: `warning: OKF link target not found: ${conceptId} (non-blocking, consumers tolerate broken links)`,
|
|
337
|
+
fixed: false,
|
|
338
|
+
});
|
|
339
|
+
}
|
|
340
|
+
}
|
|
341
|
+
}
|
|
342
|
+
return diagnostics;
|
|
343
|
+
}
|
|
344
|
+
export const okfAdapter = {
|
|
345
|
+
id: "okf",
|
|
346
|
+
version: "0.9.0",
|
|
347
|
+
extensions: [".md"],
|
|
348
|
+
recognize,
|
|
349
|
+
validate,
|
|
350
|
+
/** OKF concepts live anywhere under the component root (§5). */
|
|
351
|
+
directoryList(_c) {
|
|
352
|
+
return ["."];
|
|
353
|
+
},
|
|
354
|
+
/**
|
|
355
|
+
* Install-time probe. A root index is sufficient; an index-less root is also
|
|
356
|
+
* OKF when it contains at least one conformant concept with a non-empty open
|
|
357
|
+
* `type`. More-specific native adapters run before this portable baseline.
|
|
358
|
+
*/
|
|
359
|
+
looksLikeRoot(root) {
|
|
360
|
+
if (fs.existsSync(path.join(root, "index.md")))
|
|
361
|
+
return true;
|
|
362
|
+
const stack = [root];
|
|
363
|
+
while (stack.length > 0) {
|
|
364
|
+
const current = stack.pop();
|
|
365
|
+
if (!current)
|
|
366
|
+
continue;
|
|
367
|
+
let entries;
|
|
368
|
+
try {
|
|
369
|
+
entries = fs.readdirSync(current, { withFileTypes: true });
|
|
370
|
+
}
|
|
371
|
+
catch {
|
|
372
|
+
continue;
|
|
373
|
+
}
|
|
374
|
+
for (const entry of entries) {
|
|
375
|
+
if (entry.isSymbolicLink() || entry.name === ".git")
|
|
376
|
+
continue;
|
|
377
|
+
const absolute = path.join(current, entry.name);
|
|
378
|
+
if (entry.isDirectory()) {
|
|
379
|
+
stack.push(absolute);
|
|
380
|
+
continue;
|
|
381
|
+
}
|
|
382
|
+
if (!entry.isFile() || !entry.name.toLowerCase().endsWith(".md") || isReservedFileName(entry.name))
|
|
383
|
+
continue;
|
|
384
|
+
const type = nonEmptyString(parseFrontmatter(fs.readFileSync(absolute, "utf8")).data.type);
|
|
385
|
+
if (type)
|
|
386
|
+
return true;
|
|
387
|
+
}
|
|
388
|
+
}
|
|
389
|
+
return false;
|
|
390
|
+
},
|
|
391
|
+
};
|
|
@@ -0,0 +1,68 @@
|
|
|
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 `opencode` tool-directory adapter — akm 0.9.0 format-family work item
|
|
6
|
+
* (#46).
|
|
7
|
+
*
|
|
8
|
+
* Recognizes an OpenCode `.opencode` layout (spec §6/§7, real-world:
|
|
9
|
+
* https://opencode.ai/docs/{commands,agents,skills,rules}/): a root `AGENTS.md`
|
|
10
|
+
* → `instruction`, `commands/*.md` → `command`, `agents/*.md` → `agent`,
|
|
11
|
+
* `skills/<name>/SKILL.md` → `skill`, and ABSTAINS on `opencode.json` runtime
|
|
12
|
+
* config. Per open-question-6 (RESOLVED, accept BOTH forms) the SINGULAR
|
|
13
|
+
* `command/`/`agent/`/`skill/` dirs are accepted as backwards-compat aliases on
|
|
14
|
+
* READ (the conceptId preserves the on-disk spelling, e.g. `command/legacy`);
|
|
15
|
+
* WRITES normalize to the canonical plural (handled in the shared codec).
|
|
16
|
+
*
|
|
17
|
+
* All behavior lives in the shared tool-dir codec ({@link makeToolDirAdapter});
|
|
18
|
+
* this module supplies only the `.opencode` layout + the install-time probe.
|
|
19
|
+
*
|
|
20
|
+
* Conformance oracle (authored, DO NOT modify): fixture
|
|
21
|
+
* `tests/fixtures/bundles/opencode/` + goldens
|
|
22
|
+
* `tests/fixtures/format-family-goldens/opencode/{recognition,placement,lint,renderer}.json`.
|
|
23
|
+
*/
|
|
24
|
+
import fs from "node:fs";
|
|
25
|
+
import path from "node:path";
|
|
26
|
+
import { makeToolDirAdapter } from "./tool-dir-shared.js";
|
|
27
|
+
const LAYOUT = {
|
|
28
|
+
adapterId: "opencode",
|
|
29
|
+
componentId: ".opencode",
|
|
30
|
+
instructionFile: "AGENTS.md",
|
|
31
|
+
instructionConceptId: "AGENTS",
|
|
32
|
+
commandDirs: new Set(["commands", "command"]),
|
|
33
|
+
agentDirs: new Set(["agents", "agent"]),
|
|
34
|
+
skillDirs: new Set(["skills", "skill"]),
|
|
35
|
+
};
|
|
36
|
+
const CONFIG_FILES = ["opencode.json", "opencode.jsonc"];
|
|
37
|
+
const TOOL_DIRS = ["commands", "command", "agents", "agent", "skills", "skill"];
|
|
38
|
+
function fileExists(p) {
|
|
39
|
+
try {
|
|
40
|
+
return fs.existsSync(p);
|
|
41
|
+
}
|
|
42
|
+
catch {
|
|
43
|
+
return false;
|
|
44
|
+
}
|
|
45
|
+
}
|
|
46
|
+
function dirExists(p) {
|
|
47
|
+
try {
|
|
48
|
+
return fs.statSync(p).isDirectory();
|
|
49
|
+
}
|
|
50
|
+
catch {
|
|
51
|
+
return false;
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
/**
|
|
55
|
+
* Install-time probe (§1.2): a root is an `.opencode` tool dir when it carries
|
|
56
|
+
* an `opencode.json`/`opencode.jsonc` config, OR a root `AGENTS.md` plus at
|
|
57
|
+
* least one tool dir. Neither marker exists on an akm/okf/wiki root, so the
|
|
58
|
+
* probe is unambiguous; registered ahead of `akm` so a `.opencode` root (whose
|
|
59
|
+
* plural tool dirs also look like akm stash subdirs) is claimed by `opencode`.
|
|
60
|
+
*/
|
|
61
|
+
function opencodeLooksLikeRoot(root) {
|
|
62
|
+
if (CONFIG_FILES.some((f) => fileExists(path.join(root, f))))
|
|
63
|
+
return true;
|
|
64
|
+
if (!fileExists(path.join(root, "AGENTS.md")))
|
|
65
|
+
return false;
|
|
66
|
+
return TOOL_DIRS.some((d) => dirExists(path.join(root, d)));
|
|
67
|
+
}
|
|
68
|
+
export const opencodeAdapter = makeToolDirAdapter(LAYOUT, opencodeLooksLikeRoot);
|