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