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.
Files changed (598) hide show
  1. package/CHANGELOG.md +1283 -22
  2. package/README.md +62 -37
  3. package/SECURITY.md +46 -31
  4. package/dist/akm +162 -38
  5. package/dist/akm-migrate +44 -0
  6. package/dist/assets/backends/schtasks-template.xml +2 -1
  7. package/dist/assets/hints/cli-hints-full.md +268 -118
  8. package/dist/assets/hints/cli-hints-short.md +87 -24
  9. package/dist/assets/{profiles → improve-strategies}/catchup.json +3 -1
  10. package/dist/assets/{profiles → improve-strategies}/consolidate.json +3 -1
  11. package/dist/assets/{profiles → improve-strategies}/default.json +6 -7
  12. package/dist/assets/improve-strategies/frequent.json +15 -0
  13. package/dist/assets/{profiles → improve-strategies}/graph-refresh.json +4 -2
  14. package/dist/assets/{profiles → improve-strategies}/memory-focus.json +4 -1
  15. package/dist/assets/{profiles → improve-strategies}/proactive-maintenance.json +5 -5
  16. package/dist/assets/{profiles → improve-strategies}/quick.json +4 -2
  17. package/dist/assets/improve-strategies/reflect-distill.json +30 -0
  18. package/dist/assets/{profiles → improve-strategies}/thorough.json +1 -1
  19. package/dist/assets/prompts/consolidate-system.md +5 -5
  20. package/dist/assets/prompts/extract-session.md +2 -6
  21. package/dist/assets/prompts/memory-infer-user.md +2 -3
  22. package/dist/assets/prompts/reflect-llm-framed-contract.md +11 -0
  23. package/dist/assets/prompts/reflect-llm-schema-contract.md +3 -0
  24. package/dist/assets/prompts/reflect-output-repair.md +3 -0
  25. package/dist/assets/prompts/workflow-unit-preamble.md +26 -0
  26. package/dist/assets/stash-skeleton/README.md +38 -10
  27. package/dist/assets/stash-skeleton/facts/conventions/assets/agent.md +8 -0
  28. package/dist/assets/stash-skeleton/facts/conventions/assets/command.md +8 -0
  29. package/dist/assets/stash-skeleton/facts/conventions/assets/fact.md +14 -1
  30. package/dist/assets/stash-skeleton/facts/conventions/assets/knowledge.md +13 -1
  31. package/dist/assets/stash-skeleton/facts/conventions/assets/lesson.md +9 -1
  32. package/dist/assets/stash-skeleton/facts/conventions/assets/memory.md +11 -0
  33. package/dist/assets/stash-skeleton/facts/conventions/assets/script.md +9 -0
  34. package/dist/assets/stash-skeleton/facts/conventions/assets/skill.md +9 -0
  35. package/dist/assets/stash-skeleton/facts/conventions/assets/workflow.md +8 -0
  36. package/dist/assets/stash-skeleton/facts/conventions/backlinks.md +100 -0
  37. package/dist/assets/stash-skeleton/facts/conventions/domains.md +64 -0
  38. package/dist/assets/stash-skeleton/facts/conventions/organization.md +136 -0
  39. package/dist/assets/tasks/core/extract.yml +3 -2
  40. package/dist/assets/tasks/core/improve.yml +2 -1
  41. package/dist/assets/tasks/core/index-refresh.yml +1 -0
  42. package/dist/assets/tasks/core/sync.yml +1 -0
  43. package/dist/assets/tasks/core/version-check.yml +2 -1
  44. package/dist/assets/tasks/improve/akm-graph-refresh-weekly.yml +5 -0
  45. package/dist/assets/tasks/improve/akm-improve-catchup.yml +8 -0
  46. package/dist/assets/tasks/improve/akm-improve-consolidate.yml +5 -0
  47. package/dist/assets/tasks/improve/akm-improve-frequent.yml +5 -0
  48. package/dist/assets/tasks/improve/akm-improve-nightly.yml +5 -0
  49. package/dist/assets/templates/html/health.html +5 -4
  50. package/dist/assets/workflows/workflow-template.md +31 -15
  51. package/dist/cli/invocation.js +279 -0
  52. package/dist/cli/parse-args.js +5 -90
  53. package/dist/cli/retired-commands.js +78 -0
  54. package/dist/cli/shared.js +158 -48
  55. package/dist/cli-node.mjs +2 -1
  56. package/dist/cli.js +747 -293
  57. package/dist/commands/agent/agent-dispatch.js +19 -18
  58. package/dist/commands/agent/agent-support.js +0 -24
  59. package/dist/commands/agent/contribute-cli.js +43 -97
  60. package/dist/commands/completions.js +80 -23
  61. package/dist/commands/config-cli.js +44 -281
  62. package/dist/commands/env/env-binding.js +99 -0
  63. package/dist/commands/env/env-cli.js +84 -224
  64. package/dist/commands/env/env.js +12 -163
  65. package/dist/commands/env/marker-path.js +6 -0
  66. package/dist/commands/env/secret-cli.js +45 -61
  67. package/dist/commands/env/secret.js +32 -62
  68. package/dist/commands/feedback-cli.js +179 -85
  69. package/dist/commands/health/accept-rate.js +58 -0
  70. package/dist/commands/health/advisories.js +7 -8
  71. package/dist/commands/health/checks.js +279 -94
  72. package/dist/commands/health/html-report.js +197 -578
  73. package/dist/commands/health/improve-metrics.js +277 -246
  74. package/dist/commands/health/llm-usage.js +19 -19
  75. package/dist/commands/health/md-report.js +16 -7
  76. package/dist/commands/health/metrics.js +67 -32
  77. package/dist/commands/health/renderers.js +47 -0
  78. package/dist/commands/health/report-view-model.js +508 -0
  79. package/dist/commands/health/stash-exposure.js +1 -1
  80. package/dist/commands/health/surfaces.js +16 -56
  81. package/dist/commands/health/task-runs.js +3 -67
  82. package/dist/{migrate-storage-node.mjs → commands/health/types-checks.js} +1 -5
  83. package/dist/commands/health/types-improve.js +29 -0
  84. package/dist/{output/text/save.js → commands/health/types-metrics.js} +1 -2
  85. package/dist/commands/health/types-result.js +7 -0
  86. package/dist/commands/health/types-runs.js +4 -0
  87. package/dist/commands/health/types-session-log.js +4 -0
  88. package/dist/commands/health/types-windows.js +4 -0
  89. package/dist/commands/health/types.js +26 -21
  90. package/dist/commands/health/windows.js +2 -3
  91. package/dist/commands/health.js +296 -167
  92. package/dist/commands/improve/anti-collapse.js +5 -5
  93. package/dist/commands/improve/autonomy-gate.js +68 -0
  94. package/dist/commands/improve/collapse-detector.js +65 -52
  95. package/dist/commands/improve/consolidate/chunking.js +9 -7
  96. package/dist/commands/improve/consolidate/eligibility.js +1 -23
  97. package/dist/commands/improve/consolidate/merge.js +4 -0
  98. package/dist/commands/improve/consolidate.js +454 -1354
  99. package/dist/commands/improve/content-hash.js +39 -0
  100. package/dist/commands/improve/distill/content-repair.js +4 -10
  101. package/dist/commands/improve/distill/promote-memory.js +89 -64
  102. package/dist/commands/improve/distill/quality-gate.js +118 -42
  103. package/dist/commands/improve/distill-guards.js +1 -1
  104. package/dist/commands/improve/distill-promotion-policy.js +33 -888
  105. package/dist/commands/improve/distill.js +607 -363
  106. package/dist/commands/improve/eligibility.js +165 -79
  107. package/dist/commands/improve/extract-cli.js +35 -126
  108. package/dist/commands/improve/extract-prompt.js +6 -35
  109. package/dist/commands/improve/extract.js +640 -391
  110. package/dist/commands/improve/feedback-valence.js +2 -12
  111. package/dist/commands/improve/improve-cli.js +134 -135
  112. package/dist/commands/improve/improve-result-file.js +30 -50
  113. package/dist/commands/improve/improve-run-types.js +4 -0
  114. package/dist/commands/improve/improve-strategies.js +135 -0
  115. package/dist/commands/improve/improve.js +904 -701
  116. package/dist/commands/improve/locks.js +64 -111
  117. package/dist/commands/improve/loop-stages.js +1110 -923
  118. package/dist/commands/improve/memory/derived-ref.js +124 -0
  119. package/dist/commands/improve/memory/memory-belief.js +79 -7
  120. package/dist/commands/improve/memory/memory-contradiction-detect.js +49 -52
  121. package/dist/commands/improve/memory/memory-improve.js +25 -37
  122. package/dist/commands/improve/outcome-loop.js +25 -88
  123. package/dist/commands/improve/preparation.js +1034 -813
  124. package/dist/commands/improve/proactive-maintenance.js +34 -9
  125. package/dist/commands/improve/proposal-envelope.js +31 -0
  126. package/dist/commands/improve/reflect.js +983 -794
  127. package/dist/commands/improve/run-context.js +119 -0
  128. package/dist/commands/improve/salience.js +24 -127
  129. package/dist/commands/improve/session-asset.js +7 -3
  130. package/dist/commands/improve/shared.js +14 -34
  131. package/dist/commands/improve/source-identity.js +28 -0
  132. package/dist/commands/improve/triage.js +20 -17
  133. package/dist/commands/lint/base-linter.js +340 -313
  134. package/dist/commands/lint/env-key-rules.js +31 -47
  135. package/dist/commands/lint/index.js +185 -30
  136. package/dist/commands/{events.js → log.js} +28 -38
  137. package/dist/commands/migrate-cli.js +54 -0
  138. package/dist/commands/migration-tool.js +55 -0
  139. package/dist/commands/observability-cli.js +70 -208
  140. package/dist/commands/proposal/diff-format.js +50 -0
  141. package/dist/commands/proposal/drain-policies.js +0 -6
  142. package/dist/commands/proposal/drain.js +91 -40
  143. package/dist/commands/proposal/proposal-cli.js +134 -132
  144. package/dist/commands/proposal/proposal-types.js +56 -0
  145. package/dist/commands/proposal/proposal.js +83 -65
  146. package/dist/commands/proposal/propose-cli.js +88 -0
  147. package/dist/commands/proposal/propose.js +105 -88
  148. package/dist/commands/proposal/repository.js +1303 -278
  149. package/dist/commands/proposal/validators/proposal-quality-validators.js +16 -6
  150. package/dist/commands/proposal/validators/proposal-validators.js +61 -12
  151. package/dist/commands/proposal/validators/proposals.js +6 -8
  152. package/dist/commands/read/curate.js +78 -73
  153. package/dist/commands/read/knowledge.js +510 -13
  154. package/dist/commands/read/registry-search.js +2 -2
  155. package/dist/commands/read/remember-cli.js +84 -15
  156. package/dist/commands/read/search-cli.js +203 -96
  157. package/dist/commands/read/search.js +126 -94
  158. package/dist/commands/read/show.js +226 -250
  159. package/dist/commands/registry-cli.js +34 -60
  160. package/dist/commands/remember.js +18 -57
  161. package/dist/commands/sources/add-cli.js +104 -49
  162. package/dist/commands/sources/bundle-cli.js +166 -0
  163. package/dist/commands/sources/bundle-config-ops.js +63 -0
  164. package/dist/commands/sources/info.js +27 -15
  165. package/dist/commands/sources/init.js +30 -40
  166. package/dist/commands/sources/installed-stashes.js +469 -172
  167. package/dist/commands/sources/migration-help.js +7 -4
  168. package/dist/commands/sources/schema-repair.js +10 -9
  169. package/dist/commands/sources/self-update.js +182 -121
  170. package/dist/commands/sources/source-add.js +169 -178
  171. package/dist/commands/sources/source-clone.js +144 -41
  172. package/dist/commands/sources/source-manage.js +94 -59
  173. package/dist/commands/sources/sources-cli.js +64 -205
  174. package/dist/commands/sources/stash-cli.js +91 -54
  175. package/dist/commands/sources/stash-skeleton.js +1 -1
  176. package/dist/commands/tasks/tasks-cli.js +106 -104
  177. package/dist/commands/tasks/tasks.js +445 -262
  178. package/dist/commands/workflow-cli.js +232 -121
  179. package/dist/core/action-contributors.js +1 -1
  180. package/dist/core/activation-policy.js +49 -0
  181. package/dist/core/adapter/adapters/agent-skills-adapter.js +181 -0
  182. package/dist/core/adapter/adapters/akm-adapter.js +528 -0
  183. package/dist/core/adapter/adapters/akm-lint.js +392 -0
  184. package/dist/core/adapter/adapters/akm-metadata.js +387 -0
  185. package/dist/core/adapter/adapters/akm-task-adapter.js +149 -0
  186. package/dist/core/adapter/adapters/akm-workflow-adapter.js +180 -0
  187. package/dist/core/adapter/adapters/claude-adapter.js +61 -0
  188. package/dist/core/adapter/adapters/dotenv-adapter.js +187 -0
  189. package/dist/core/adapter/adapters/generic-files-adapter.js +119 -0
  190. package/dist/core/adapter/adapters/index.js +80 -0
  191. package/dist/core/adapter/adapters/llm-wiki-adapter.js +419 -0
  192. package/dist/core/adapter/adapters/okf-adapter.js +391 -0
  193. package/dist/core/adapter/adapters/opencode-adapter.js +68 -0
  194. package/dist/core/adapter/adapters/shared.js +286 -0
  195. package/dist/core/adapter/adapters/tool-dir-shared.js +217 -0
  196. package/dist/core/adapter/adapters/website-snapshot-adapter.js +155 -0
  197. package/dist/core/adapter/bundle-adapter.js +4 -0
  198. package/dist/core/adapter/detect-adapter.js +17 -0
  199. package/dist/core/adapter/recognize-match.js +44 -0
  200. package/dist/core/adapter/registry.js +56 -0
  201. package/dist/core/adapter/types.js +4 -0
  202. package/dist/core/asset/akm-markdown.js +30 -0
  203. package/dist/core/asset/asset-placement.js +243 -0
  204. package/dist/core/asset/asset-ref.js +110 -79
  205. package/dist/core/asset/asset-serialize.js +20 -0
  206. package/dist/core/asset/frontmatter.js +28 -12
  207. package/dist/core/asset/markdown.js +40 -51
  208. package/dist/core/asset/resolve-ref.js +274 -0
  209. package/dist/core/asset/stash-meta.js +2 -2
  210. package/dist/core/bundle-id.js +51 -0
  211. package/dist/core/common.js +281 -86
  212. package/dist/core/config/config-io.js +42 -128
  213. package/dist/core/config/config-schema.js +233 -834
  214. package/dist/core/config/config-sources.js +162 -39
  215. package/dist/core/config/config-types.js +16 -11
  216. package/dist/core/config/config-version.js +29 -0
  217. package/dist/core/config/config-walker.js +126 -37
  218. package/dist/core/config/config.js +154 -331
  219. package/dist/core/config/deep-merge.js +41 -0
  220. package/dist/core/config/engine-semantics.js +28 -0
  221. package/dist/core/config/experimental.js +21 -0
  222. package/dist/core/config/schema/embedding.js +38 -0
  223. package/dist/core/config/schema/engines.js +116 -0
  224. package/dist/core/config/schema/experimental.js +47 -0
  225. package/dist/core/config/schema/feedback.js +31 -0
  226. package/dist/core/config/schema/improve-processes.js +389 -0
  227. package/dist/core/config/schema/improve.js +94 -0
  228. package/dist/core/config/schema/index-config.js +176 -0
  229. package/dist/core/config/schema/output.js +18 -0
  230. package/dist/core/config/schema/primitives.js +94 -0
  231. package/dist/core/config/schema/search.js +30 -0
  232. package/dist/core/config/schema/setup.js +18 -0
  233. package/dist/core/config/schema/sources-bundles.js +169 -0
  234. package/dist/core/config/schema/workflow.js +29 -0
  235. package/dist/core/env-secret-ref.js +155 -20
  236. package/dist/core/errors.js +17 -15
  237. package/dist/core/events-types.js +4 -0
  238. package/dist/core/events.js +46 -128
  239. package/dist/core/extra-params.js +62 -0
  240. package/dist/core/file-change.js +17 -0
  241. package/dist/core/file-lock.js +202 -57
  242. package/dist/core/fs-txn.js +392 -0
  243. package/dist/core/git-message.js +59 -0
  244. package/dist/core/improve-result.js +167 -0
  245. package/dist/core/json-schema.js +142 -0
  246. package/dist/core/lesson-lint.js +1 -17
  247. package/dist/core/logs-db.js +1 -1
  248. package/dist/core/maintenance-barrier.js +135 -0
  249. package/dist/core/migration-operation.js +44 -0
  250. package/dist/core/mutation-target.js +78 -0
  251. package/dist/core/paths.js +22 -25
  252. package/dist/core/platform.js +10 -0
  253. package/dist/core/recognition-util.js +128 -0
  254. package/dist/core/redaction.js +392 -0
  255. package/dist/core/standards/resolve-standards-context.js +36 -65
  256. package/dist/core/standards/resolve-stash-standards.js +2 -2
  257. package/dist/core/standards/resolve-type-conventions.js +5 -5
  258. package/dist/core/state/migrations.js +242 -11
  259. package/dist/core/state-db.js +98 -10
  260. package/dist/core/structured.js +1 -1
  261. package/dist/core/subprocess.js +303 -0
  262. package/dist/core/text-truncation.js +9 -5
  263. package/dist/core/time.js +20 -0
  264. package/dist/core/type-presentation.js +130 -0
  265. package/dist/core/warn.js +0 -3
  266. package/dist/core/write-source.js +834 -118
  267. package/dist/indexer/bundle-identity-guard.js +92 -0
  268. package/dist/indexer/db/graph-db.js +1 -25
  269. package/dist/indexer/db/llm-cache.js +1 -1
  270. package/dist/indexer/ensure-index.js +30 -9
  271. package/dist/indexer/graph/graph-boost.js +9 -30
  272. package/dist/indexer/graph/graph-extraction.js +41 -27
  273. package/dist/indexer/graph/graph-types.js +4 -0
  274. package/dist/indexer/index-writer-lock.js +93 -49
  275. package/dist/indexer/index-written-assets.js +100 -53
  276. package/dist/indexer/indexer.js +746 -329
  277. package/dist/indexer/init.js +18 -25
  278. package/dist/indexer/installations.js +142 -0
  279. package/dist/indexer/passes/dir-staleness.js +18 -10
  280. package/dist/indexer/passes/memory-inference.js +25 -15
  281. package/dist/indexer/passes/metadata.js +412 -243
  282. package/dist/indexer/scan/doc-to-entry.js +160 -0
  283. package/dist/indexer/scan/drain-dir.js +134 -0
  284. package/dist/indexer/search/db-search.js +292 -108
  285. package/dist/indexer/search/fts-query.js +64 -0
  286. package/dist/indexer/search/ranking-contributors.js +145 -25
  287. package/dist/indexer/search/ranking-types.js +4 -0
  288. package/dist/indexer/search/ranking.js +28 -71
  289. package/dist/indexer/search/search-attribution.js +67 -0
  290. package/dist/indexer/search/search-fields.js +18 -3
  291. package/dist/indexer/search/search-hit-enrichers.js +30 -40
  292. package/dist/indexer/search/search-source.js +157 -111
  293. package/dist/indexer/search/semantic-status.js +4 -1
  294. package/dist/indexer/usage/usage-events.js +10 -30
  295. package/dist/indexer/walk/file-context.js +3 -45
  296. package/dist/indexer/walk/matchers.js +42 -34
  297. package/dist/indexer/walk/path-resolver.js +11 -5
  298. package/dist/indexer/walk/walker.js +42 -14
  299. package/dist/integrations/agent/builder-shared.js +7 -0
  300. package/dist/integrations/agent/builders.js +5 -56
  301. package/dist/integrations/agent/config.js +3 -143
  302. package/dist/integrations/agent/detect.js +17 -2
  303. package/dist/integrations/agent/engine-resolution.js +231 -0
  304. package/dist/integrations/agent/index.js +1 -2
  305. package/dist/integrations/agent/model-aliases.js +16 -2
  306. package/dist/integrations/agent/profiles.js +36 -62
  307. package/dist/integrations/agent/prompts.js +46 -18
  308. package/dist/integrations/agent/runner-dispatch.js +93 -4
  309. package/dist/integrations/agent/runner.js +76 -208
  310. package/dist/integrations/agent/spawn.js +88 -196
  311. package/dist/integrations/harnesses/aider/agent-builder.js +114 -0
  312. package/dist/integrations/harnesses/aider/index.js +48 -0
  313. package/dist/integrations/harnesses/aider/result-extractor.js +53 -0
  314. package/dist/integrations/harnesses/amazonq/agent-builder.js +147 -0
  315. package/dist/integrations/harnesses/amazonq/index.js +45 -0
  316. package/dist/integrations/harnesses/amazonq/result-extractor.js +48 -0
  317. package/dist/integrations/harnesses/claude/agent-builder.js +46 -8
  318. package/dist/integrations/harnesses/claude/config-import.js +1 -3
  319. package/dist/integrations/harnesses/claude/index.js +24 -35
  320. package/dist/integrations/harnesses/claude/result-extractor.js +52 -0
  321. package/dist/integrations/harnesses/claude/session-log.js +27 -75
  322. package/dist/integrations/harnesses/codex/agent-builder.js +138 -0
  323. package/dist/integrations/harnesses/codex/index.js +52 -0
  324. package/dist/integrations/harnesses/codex/result-extractor.js +73 -0
  325. package/dist/integrations/harnesses/copilot/agent-builder.js +122 -0
  326. package/dist/integrations/harnesses/copilot/index.js +48 -0
  327. package/dist/integrations/harnesses/copilot/result-extractor.js +151 -0
  328. package/dist/integrations/harnesses/gemini/agent-builder.js +120 -0
  329. package/dist/integrations/harnesses/gemini/index.js +48 -0
  330. package/dist/integrations/harnesses/gemini/result-extractor.js +121 -0
  331. package/dist/integrations/harnesses/ids.js +24 -0
  332. package/dist/integrations/harnesses/index.js +54 -34
  333. package/dist/integrations/harnesses/opencode/agent-builder.js +23 -5
  334. package/dist/integrations/harnesses/opencode/config-import.js +1 -3
  335. package/dist/integrations/harnesses/opencode/index.js +14 -32
  336. package/dist/integrations/harnesses/opencode/session-log.js +67 -125
  337. package/dist/integrations/harnesses/opencode-sdk/harness.js +51 -0
  338. package/dist/integrations/harnesses/opencode-sdk/sdk-runner.js +681 -108
  339. package/dist/integrations/harnesses/openhands/agent-builder.js +128 -0
  340. package/dist/integrations/harnesses/openhands/index.js +48 -0
  341. package/dist/integrations/harnesses/openhands/result-extractor.js +103 -0
  342. package/dist/integrations/harnesses/pi/agent-builder.js +97 -0
  343. package/dist/integrations/harnesses/pi/index.js +45 -0
  344. package/dist/integrations/harnesses/pi/result-extractor.js +135 -0
  345. package/dist/integrations/harnesses/shared.js +17 -0
  346. package/dist/integrations/harnesses/types.js +43 -32
  347. package/dist/integrations/lockfile.js +211 -24
  348. package/dist/integrations/session-logs/index.js +36 -39
  349. package/dist/integrations/session-logs/provider-base.js +113 -0
  350. package/dist/llm/client.js +182 -110
  351. package/dist/llm/embedders/deterministic.js +2 -2
  352. package/dist/llm/embedders/remote.js +21 -9
  353. package/dist/llm/feature-gate.js +17 -57
  354. package/dist/llm/graph-extract.js +12 -13
  355. package/dist/llm/index-passes.js +8 -42
  356. package/dist/llm/memory-infer.js +144 -1
  357. package/dist/llm/metadata-enhance.js +45 -30
  358. package/dist/llm/structured-call.js +16 -8
  359. package/dist/llm/usage-persist.js +30 -5
  360. package/dist/llm/usage-telemetry.js +59 -6
  361. package/dist/output/cli-hints.js +1 -2
  362. package/dist/output/command-registry.js +27 -0
  363. package/dist/output/context.js +22 -7
  364. package/dist/output/format-exempt.js +80 -0
  365. package/dist/output/generic-render.js +251 -0
  366. package/dist/output/html-render.js +11 -16
  367. package/dist/output/render-registry.js +57 -0
  368. package/dist/output/renderers.js +14 -279
  369. package/dist/output/shapes/curate.js +10 -1
  370. package/dist/output/shapes/events.js +12 -7
  371. package/dist/output/shapes/helpers.js +58 -84
  372. package/dist/output/shapes/passthrough.js +11 -39
  373. package/dist/output/shapes/proposal/producer.js +15 -7
  374. package/dist/output/shapes/registry.js +12 -6
  375. package/dist/output/shapes.js +0 -9
  376. package/dist/output/text/{init.js → bundle-create.js} +3 -1
  377. package/dist/output/text/bundle-show.js +7 -0
  378. package/dist/output/text/command-format.js +562 -0
  379. package/dist/output/text/env.js +1 -3
  380. package/dist/output/text/events.js +8 -7
  381. package/dist/output/text/helpers.js +15 -1164
  382. package/dist/output/text/proposal/producer.js +4 -2
  383. package/dist/output/text/proposal-format.js +202 -0
  384. package/dist/output/text/registry-commands.js +1 -2
  385. package/dist/output/text/registry.js +12 -6
  386. package/dist/output/text/show-directives.js +117 -0
  387. package/dist/output/text/show-format.js +103 -0
  388. package/dist/output/text/sync.js +5 -0
  389. package/dist/output/text/workflow-format.js +332 -0
  390. package/dist/output/text/workflow.js +3 -2
  391. package/dist/output/text.js +10 -19
  392. package/dist/registry/factory.js +4 -6
  393. package/dist/registry/origin-resolve.js +16 -27
  394. package/dist/registry/providers/skills-sh.js +3 -3
  395. package/dist/registry/providers/static-index.js +15 -25
  396. package/dist/registry/resolve.js +43 -94
  397. package/dist/registry/semver.js +43 -0
  398. package/dist/runtime.js +81 -12
  399. package/dist/scripts/akm-migrate.js +35529 -0
  400. package/dist/setup/detect.js +5 -7
  401. package/dist/setup/detected-engines.js +136 -0
  402. package/dist/setup/engine-config.js +100 -0
  403. package/dist/setup/registry-stash-loader.js +3 -3
  404. package/dist/setup/semantic-assets.js +12 -9
  405. package/dist/setup/setup.js +444 -208
  406. package/dist/setup/steps/connection-shared.js +120 -0
  407. package/dist/setup/steps/connection.js +108 -305
  408. package/dist/setup/steps/platforms.js +13 -12
  409. package/dist/setup/steps/semantic.js +15 -3
  410. package/dist/setup/steps/sources.js +21 -15
  411. package/dist/setup/steps/stashdir.js +6 -4
  412. package/dist/setup/steps/tasks.js +236 -119
  413. package/dist/setup/steps.js +3 -2
  414. package/dist/sources/freshness.js +39 -0
  415. package/dist/sources/provider-factory.js +11 -17
  416. package/dist/sources/providers/filesystem.js +2 -3
  417. package/dist/sources/providers/git-install.js +278 -34
  418. package/dist/sources/providers/git-provider.js +54 -56
  419. package/dist/sources/providers/git-stash.js +420 -91
  420. package/dist/sources/providers/git.js +2 -2
  421. package/dist/sources/providers/npm.js +16 -19
  422. package/dist/sources/providers/provider-utils.js +47 -22
  423. package/dist/sources/providers/sync-from-ref.js +3 -9
  424. package/dist/sources/providers/website.js +2 -2
  425. package/dist/sources/resolve.js +11 -10
  426. package/dist/sources/snapshot-fetchers/types.js +4 -0
  427. package/dist/sources/{website-ingest.js → snapshot-fetchers/website-ingest.js} +110 -41
  428. package/dist/storage/database.js +60 -4
  429. package/dist/storage/engines/sqlite-migrations.js +156 -5
  430. package/dist/storage/locations.js +1 -2
  431. package/dist/storage/repositories/canaries-repository.js +1 -1
  432. package/dist/storage/repositories/events-repository.js +51 -11
  433. package/dist/storage/repositories/improve-runs-repository.js +6 -32
  434. package/dist/storage/repositories/index-connection.js +79 -0
  435. package/dist/storage/repositories/index-db.js +4 -3
  436. package/dist/storage/repositories/index-entries-repository.js +863 -0
  437. package/dist/{indexer/db/entry-mapper.js → storage/repositories/index-entry-mapper.js} +19 -2
  438. package/dist/storage/repositories/index-entry-types.js +4 -0
  439. package/dist/storage/repositories/index-fts-repository.js +167 -0
  440. package/dist/storage/repositories/index-llm-cache-repository.js +108 -0
  441. package/dist/storage/repositories/index-meta-repository.js +49 -0
  442. package/dist/{indexer/db/schema.js → storage/repositories/index-schema.js} +226 -100
  443. package/dist/storage/repositories/index-sql.js +12 -0
  444. package/dist/storage/repositories/index-utility-repository.js +356 -0
  445. package/dist/storage/repositories/index-vec-repository.js +250 -0
  446. package/dist/storage/repositories/outcome-repository.js +119 -0
  447. package/dist/storage/repositories/proposals-repository.js +317 -75
  448. package/dist/storage/repositories/registry-cache.js +1 -1
  449. package/dist/storage/repositories/salience-repository.js +172 -0
  450. package/dist/storage/repositories/task-history-repository.js +110 -3
  451. package/dist/storage/repositories/workflow-runs-repository.js +240 -19
  452. package/dist/tasks/backends/cron.js +169 -46
  453. package/dist/tasks/backends/exec-utils.js +76 -3
  454. package/dist/tasks/backends/index.js +6 -9
  455. package/dist/tasks/backends/launchd.js +292 -55
  456. package/dist/tasks/backends/schtasks.js +557 -70
  457. package/dist/tasks/backends/types.js +4 -0
  458. package/dist/tasks/command-executable.js +93 -0
  459. package/dist/tasks/embedded.js +56 -38
  460. package/dist/tasks/parser.js +156 -64
  461. package/dist/tasks/resolve-akm-bin.js +144 -51
  462. package/dist/tasks/runner.js +377 -209
  463. package/dist/tasks/schedule.js +108 -19
  464. package/dist/tasks/scheduler-invocation.js +296 -0
  465. package/dist/tasks/schema.js +1 -1
  466. package/dist/tasks/task-id.js +35 -0
  467. package/dist/tasks/validator.js +30 -16
  468. package/dist/text-import-hook.mjs +1 -1
  469. package/dist/workflows/authoring/authoring.js +104 -43
  470. package/dist/workflows/authoring/scope-key.js +1 -1
  471. package/dist/workflows/cli.js +0 -16
  472. package/dist/workflows/concurrency-policy.js +15 -0
  473. package/dist/workflows/exec/brief.js +450 -0
  474. package/dist/workflows/exec/frozen-judge.js +47 -0
  475. package/dist/workflows/exec/native-executor.js +1038 -0
  476. package/dist/workflows/exec/param-secrets.js +115 -0
  477. package/dist/workflows/exec/report.js +1460 -0
  478. package/dist/workflows/exec/run-workflow.js +602 -0
  479. package/dist/workflows/exec/scheduler.js +71 -0
  480. package/dist/workflows/exec/step-work.js +1190 -0
  481. package/dist/workflows/exec/unit-writer.js +23 -0
  482. package/dist/workflows/exec/workflow-engine-gate.js +67 -0
  483. package/dist/workflows/exec/worktree.js +171 -0
  484. package/dist/workflows/ir/compile.js +246 -0
  485. package/dist/workflows/ir/freeze.js +233 -0
  486. package/dist/workflows/ir/params.js +54 -0
  487. package/dist/workflows/ir/plan-hash.js +68 -0
  488. package/dist/workflows/ir/schema.js +540 -0
  489. package/dist/workflows/parser.js +878 -304
  490. package/dist/workflows/program/expressions.js +181 -0
  491. package/dist/workflows/program/schema.js +51 -0
  492. package/dist/workflows/renderer.js +100 -45
  493. package/dist/workflows/resource-limits.js +22 -0
  494. package/dist/workflows/runtime/agent-identity.js +59 -14
  495. package/dist/workflows/runtime/checkin.js +1 -1
  496. package/dist/workflows/runtime/plan-classifier.js +131 -0
  497. package/dist/workflows/runtime/runs.js +376 -119
  498. package/dist/workflows/runtime/unit-checkin.js +45 -0
  499. package/dist/workflows/runtime/unit-phases.js +20 -0
  500. package/dist/workflows/runtime/workflow-asset-loader.js +241 -40
  501. package/dist/workflows/schema.js +1 -11
  502. package/dist/workflows/validate-summary.js +2 -3
  503. package/dist/workflows/validator.js +52 -30
  504. package/docs/README.md +42 -78
  505. package/docs/migration/README.md +8 -0
  506. package/docs/migration/release-notes/0.6.0.md +1 -1
  507. package/docs/migration/release-notes/0.7.0.md +9 -8
  508. package/docs/migration/release-notes/0.9.0.md +158 -14
  509. package/docs/migration/v0.7-to-v0.8.md +46 -47
  510. package/docs/migration/v0.8-to-v0.9.md +844 -0
  511. package/docs/reference/README.md +12 -0
  512. package/docs/reference/data-and-telemetry.md +333 -0
  513. package/package.json +21 -17
  514. package/schemas/akm-asset-envelope.json +93 -0
  515. package/schemas/akm-config.json +4636 -0
  516. package/schemas/akm-task.json +87 -0
  517. package/schemas/akm-workflow.json +373 -0
  518. package/dist/akm-migrate-storage +0 -38
  519. package/dist/assets/help/help-accept.md +0 -12
  520. package/dist/assets/help/help-improve.md +0 -84
  521. package/dist/assets/help/help-proposals.md +0 -17
  522. package/dist/assets/help/help-propose.md +0 -17
  523. package/dist/assets/help/help-reject.md +0 -11
  524. package/dist/assets/profiles/frequent.json +0 -13
  525. package/dist/assets/profiles/recombine-only.json +0 -21
  526. package/dist/assets/profiles/reflect-distill.json +0 -30
  527. package/dist/assets/profiles/synthesize.json +0 -15
  528. package/dist/assets/prompts/procedural-system.md +0 -44
  529. package/dist/assets/prompts/recombine-system.md +0 -40
  530. package/dist/assets/prompts/staleness-detect-system.md +0 -6
  531. package/dist/assets/tasks/core/backup.yml +0 -4
  532. package/dist/assets/tasks/graph-refresh-weekly.yml +0 -10
  533. package/dist/assets/templates/html/default.html +0 -78
  534. package/dist/assets/templates/html/vendor/echarts.min.js +0 -45
  535. package/dist/assets/wiki/index-template.md +0 -12
  536. package/dist/assets/wiki/ingest-workflow-template.md +0 -83
  537. package/dist/assets/wiki/log-template.md +0 -8
  538. package/dist/assets/wiki/schema-template.md +0 -61
  539. package/dist/cli/config-migrate.js +0 -150
  540. package/dist/cli/config-validate.js +0 -39
  541. package/dist/commands/graph/graph-cli.js +0 -124
  542. package/dist/commands/graph/graph.js +0 -487
  543. package/dist/commands/improve/calibration.js +0 -161
  544. package/dist/commands/improve/dedup.js +0 -482
  545. package/dist/commands/improve/extract-watch.js +0 -140
  546. package/dist/commands/improve/hot-probation.js +0 -45
  547. package/dist/commands/improve/improve-auto-accept.js +0 -276
  548. package/dist/commands/improve/improve-profiles.js +0 -168
  549. package/dist/commands/improve/procedural.js +0 -398
  550. package/dist/commands/improve/recombine.js +0 -818
  551. package/dist/commands/improve/schema-similarity-gate.js +0 -168
  552. package/dist/commands/lint/agent-linter.js +0 -44
  553. package/dist/commands/lint/command-linter.js +0 -44
  554. package/dist/commands/lint/default-linter.js +0 -16
  555. package/dist/commands/lint/fact-linter.js +0 -39
  556. package/dist/commands/lint/knowledge-linter.js +0 -16
  557. package/dist/commands/lint/memory-linter.js +0 -61
  558. package/dist/commands/lint/registry.js +0 -41
  559. package/dist/commands/lint/skill-linter.js +0 -45
  560. package/dist/commands/lint/task-linter.js +0 -50
  561. package/dist/commands/lint/workflow-linter.js +0 -81
  562. package/dist/commands/proposal/legacy-import.js +0 -115
  563. package/dist/commands/sources/history.js +0 -196
  564. package/dist/commands/tasks/default-tasks.js +0 -186
  565. package/dist/commands/wiki-cli.js +0 -292
  566. package/dist/core/asset/asset-registry.js +0 -76
  567. package/dist/core/asset/asset-spec.js +0 -259
  568. package/dist/core/config/config-migration.js +0 -602
  569. package/dist/core/deep-merge.js +0 -38
  570. package/dist/core/eval/rank-metrics.js +0 -113
  571. package/dist/core/ripgrep/install.js +0 -163
  572. package/dist/core/ripgrep/resolve.js +0 -81
  573. package/dist/indexer/db/db.js +0 -1413
  574. package/dist/indexer/manifest.js +0 -170
  575. package/dist/indexer/passes/metadata-contributors.js +0 -31
  576. package/dist/indexer/usage/unmigrated-vaults-guard.js +0 -94
  577. package/dist/integrations/harnesses/opencode-sdk/index.js +0 -49
  578. package/dist/llm/call-ai.js +0 -62
  579. package/dist/llm/memory-infer-impl.js +0 -138
  580. package/dist/output/shapes/distill.js +0 -14
  581. package/dist/output/shapes/history.js +0 -11
  582. package/dist/output/text/distill.js +0 -6
  583. package/dist/output/text/enable-disable.js +0 -8
  584. package/dist/output/text/history.js +0 -6
  585. package/dist/output/text/wiki.js +0 -16
  586. package/dist/registry/build-index.js +0 -386
  587. package/dist/scripts/migrate-storage.js +0 -19108
  588. package/dist/scripts/migrations/import-fs-improve-runs-to-db.js +0 -9411
  589. package/dist/scripts/migrations/v16-to-v17.js +0 -141
  590. package/dist/setup/legacy-config.js +0 -106
  591. package/dist/storage/repositories/consolidation-repository.js +0 -38
  592. package/dist/storage/repositories/recombine-repository.js +0 -213
  593. package/dist/wiki/wiki-templates.js +0 -15
  594. package/dist/wiki/wiki.js +0 -1012
  595. package/dist/workflows/db.js +0 -215
  596. package/docs/data-and-telemetry.md +0 -226
  597. /package/dist/sources/{wiki-fetchers → snapshot-fetchers}/registry.js +0 -0
  598. /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);