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,387 @@
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
+ * Index-time metadata fold for the `akm` adapter's `recognize` — akm 0.9.0
6
+ * chunk-2, WI-C, implementing spec §2 ("the nine index-time metadata
7
+ * contributors move into recognize") + the workflow contributor.
8
+ *
9
+ * This leaf reproduces the 11 `registerMetadataContributor` sites keyed on the
10
+ * winning RENDERER name (exactly how each contributor's `appliesTo({ rendererName })`
11
+ * selects):
12
+ *
13
+ * - `output/renderers.ts` (9): toc-metadata (knowledge-md),
14
+ * lesson-frontmatter-metadata, memory-frontmatter-metadata,
15
+ * script-comment-metadata, env-file-metadata, secret-file-metadata,
16
+ * task-yaml-metadata, session-md-metadata, fact-md-metadata;
17
+ * - `workflows/renderer.ts` (1): workflow-document-metadata (workflow-md).
18
+ *
19
+ * ── Cycle-safety (chunk-2 ratchet, baseline 18) ──
20
+ *
21
+ * Imported ONLY by `akm-adapter.ts` (itself imported by nothing in `src/` — see
22
+ * that file's header), so this leaf can never gain an inbound edge from a cycle
23
+ * participant and therefore can never JOIN a cycle. It VALUE-imports the pure
24
+ * parsers each contributor already uses so the fold cannot drift from them:
25
+ * `parseFrontmatter`, `parseMarkdownToc`, `parseWorkflow`, `parseWorkflowProgram`,
26
+ * `projectProgramParameters`/`programStepInstructions`, and `listKeys`
27
+ * (env key-names). `output/renderers.ts` / `workflows/renderer.ts` are the
28
+ * cycle-sensitive modules whose contributor bodies live in this port — their
29
+ * ONE non-importable helper (`metadata.ts#extractDescriptionFromComments`, a
30
+ * heavy cycle-participant module) is copied verbatim below as
31
+ * {@link extractDescriptionFromComments} rather than imported. Verified:
32
+ * `bun scripts/lint-import-cycles.ts` stays at 18.
33
+ *
34
+ * ── What is folded, and where it lands on the IndexDocument ──
35
+ *
36
+ * The contributors mutate a `IndexDocument`; {@link foldRecognizedMetadata} returns
37
+ * the same fields as a plain {@link FoldedMetadata}, which `recognize` maps onto
38
+ * `IndexDocument` first-class fields (`tags`/`searchHints`/`description`/
39
+ * `confidence`) and, for the fields without a first-class home
40
+ * (`toc`/`parameters`/`source`), onto `documentJson` (opaque adapter extras).
41
+ * The seed is a MINIMAL entry (name+type only): this isolates exactly what the
42
+ * contributors add, which is what the parity test compares against
43
+ * `applyMetadataContributors` run on the same minimal seed.
44
+ *
45
+ * ── Tolerance note ──
46
+ *
47
+ * Every contributor that reads/parses content is reproduced with the SAME
48
+ * try/catch tolerance it has today (toc/memory/session/fact/task swallow parse
49
+ * errors). The two workflow contributors throw-to-skip in today's pipeline (a
50
+ * broken workflow is dropped by the metadata drain); here the parse is wrapped
51
+ * so a broken workflow yields no folded metadata instead of throwing out of the
52
+ * synchronous `recognize` — the drop-the-entry behavior is an index-drain
53
+ * concern (Chunk 4/5), not recognition's. On the valid Chunk-0b fixture this
54
+ * distinction never triggers.
55
+ */
56
+ import fs from "node:fs";
57
+ import { parse as parseYaml } from "yaml";
58
+ import { listKeys } from "../../../commands/env/env.js";
59
+ import { parseWorkflow } from "../../../workflows/parser.js";
60
+ import { parseFrontmatter } from "../../asset/frontmatter.js";
61
+ import { parseMarkdownToc } from "../../asset/markdown.js";
62
+ import { nonEmptyString } from "./shared.js";
63
+ /**
64
+ * Verbatim copy of `indexer/passes/metadata.ts#extractDescriptionFromComments`
65
+ * (`:1510-1552`) — `metadata.ts` is a heavy cycle-participant module, so the
66
+ * one non-importable helper `applyScriptMetadata` needs is copied here (the
67
+ * others are imported). Reads a leading JSDoc block or hash-comment run from the
68
+ * script file; returns `null` on read/parse miss.
69
+ */
70
+ function extractDescriptionFromComments(filePath) {
71
+ let content;
72
+ try {
73
+ content = fs.readFileSync(filePath, "utf8");
74
+ }
75
+ catch {
76
+ return null;
77
+ }
78
+ const lines = content.split(/\r?\n/).slice(0, 50);
79
+ const blockStart = lines.findIndex((l) => /^\s*\/\*\*/.test(l));
80
+ if (blockStart >= 0) {
81
+ const desc = [];
82
+ for (let i = blockStart; i < lines.length; i++) {
83
+ const line = lines[i];
84
+ if (i > blockStart && /\*\//.test(line))
85
+ break;
86
+ const cleaned = line
87
+ .replace(/^\s*\/?\*\*?\s?/, "")
88
+ .replace(/\*\/\s*$/, "")
89
+ .trim();
90
+ if (cleaned)
91
+ desc.push(cleaned);
92
+ }
93
+ if (desc.length > 0)
94
+ return desc.join(" ");
95
+ }
96
+ let start = 0;
97
+ if (lines[0]?.startsWith("#!"))
98
+ start = 1;
99
+ const hashLines = [];
100
+ for (let i = start; i < lines.length; i++) {
101
+ const line = lines[i].trim();
102
+ if (line.startsWith("#") && !line.startsWith("#!")) {
103
+ hashLines.push(line.replace(/^#+\s*/, "").trim());
104
+ }
105
+ else if (line === "") {
106
+ }
107
+ else {
108
+ break;
109
+ }
110
+ }
111
+ if (hashLines.length > 0)
112
+ return hashLines.join(" ");
113
+ return null;
114
+ }
115
+ /**
116
+ * Reproduce `applyFrontmatterDescriptionAndTags` (`output/renderers.ts:668-684`):
117
+ * set description/source/confidence from frontmatter (only when not already set)
118
+ * and merge frontmatter `tags:` onto the folded tags. Returns nothing — mutates
119
+ * `out`.
120
+ */
121
+ function applyFrontmatterDescriptionAndTags(fm, out) {
122
+ const desc = nonEmptyString(fm.description);
123
+ if (desc && !out.description) {
124
+ out.description = desc;
125
+ out.source = "frontmatter";
126
+ out.confidence = 0.9;
127
+ }
128
+ if (Array.isArray(fm.tags) && fm.tags.length > 0) {
129
+ const fmTags = fm.tags.filter((t) => typeof t === "string" && t.trim().length > 0);
130
+ if (fmTags.length > 0) {
131
+ out.tags = Array.from(new Set([...(out.tags ?? []), ...fmTags]));
132
+ }
133
+ }
134
+ }
135
+ /** Collect + finalize a searchHints set the way every contributor does (`Array.from(hints).filter(Boolean)`, assigned only when non-empty). */
136
+ function finalizeHints(out, hints) {
137
+ if (hints.size > 0)
138
+ out.searchHints = Array.from(hints).filter(Boolean);
139
+ }
140
+ /**
141
+ * The metadata fold, keyed on the winning renderer NAME. Returns the fields the
142
+ * 11 contributors would add to a MINIMAL (name+type) `IndexDocument`. `recognize`
143
+ * maps the result onto the `IndexDocument`. Reads the live file (index-time, so
144
+ * disk reads are legitimate — unlike `validate`).
145
+ */
146
+ export function foldRecognizedMetadata(rendererName, file) {
147
+ const out = {};
148
+ switch (rendererName) {
149
+ // ── toc-metadata (knowledge-md) ──
150
+ case "knowledge-md": {
151
+ try {
152
+ const toc = parseMarkdownToc(file.content());
153
+ if (toc.headings.length > 0)
154
+ out.toc = toc.headings;
155
+ }
156
+ catch {
157
+ // Non-fatal: skip TOC if file can't be read
158
+ }
159
+ return out;
160
+ }
161
+ // ── lesson-frontmatter-metadata (lesson-md) ──
162
+ case "lesson-md": {
163
+ try {
164
+ const fm = parseFrontmatter(file.content()).data;
165
+ applyFrontmatterDescriptionAndTags(fm, out);
166
+ const whenToUse = nonEmptyString(fm.when_to_use);
167
+ if (whenToUse)
168
+ finalizeHints(out, new Set([`when_to_use:${whenToUse}`]));
169
+ }
170
+ catch {
171
+ // Non-fatal: skip metadata extraction on parse error
172
+ }
173
+ return out;
174
+ }
175
+ // ── memory-frontmatter-metadata (memory-md) ──
176
+ case "memory-md": {
177
+ try {
178
+ const fm = parseFrontmatter(file.content()).data;
179
+ applyFrontmatterDescriptionAndTags(fm, out);
180
+ const hints = new Set();
181
+ const source = nonEmptyString(fm.source);
182
+ if (source)
183
+ hints.add(source);
184
+ const fmObservedAt = nonEmptyString(fm.observed_at);
185
+ if (fmObservedAt) {
186
+ hints.add(`observed_at:${fmObservedAt}`);
187
+ }
188
+ else {
189
+ try {
190
+ const isoDate = file.stat().mtime.toISOString().slice(0, 10);
191
+ hints.add(`observed_at:${isoDate}`);
192
+ }
193
+ catch {
194
+ // Non-fatal: skip mtime fallback on stat error
195
+ }
196
+ }
197
+ const expires = nonEmptyString(fm.expires);
198
+ if (expires)
199
+ hints.add(`expires:${expires}`);
200
+ if (fm.subjective === true)
201
+ hints.add("subjective");
202
+ finalizeHints(out, hints);
203
+ }
204
+ catch {
205
+ // Non-fatal: skip metadata extraction on error
206
+ }
207
+ return out;
208
+ }
209
+ // ── script-comment-metadata (script-source) ──
210
+ case "script-source": {
211
+ if (file.ext === ".md")
212
+ return out;
213
+ const commentDesc = extractDescriptionFromComments(file.absPath);
214
+ if (commentDesc && !out.description) {
215
+ out.description = commentDesc;
216
+ out.source = "comments";
217
+ out.confidence = 0.7;
218
+ }
219
+ return out;
220
+ }
221
+ // ── env-file-metadata (env-file) ──
222
+ case "env-file": {
223
+ const { keys } = listKeys(file.absPath);
224
+ if (keys.length > 0)
225
+ out.searchHints = keys;
226
+ out.tags = Array.from(new Set([...(out.tags ?? []), "env", "secrets"]));
227
+ return out;
228
+ }
229
+ // ── secret-file-metadata (secret-file) — tags only, NEVER reads the body ──
230
+ case "secret-file": {
231
+ out.tags = Array.from(new Set([...(out.tags ?? []), "secret", "sensitive"]));
232
+ return out;
233
+ }
234
+ // ── task-yaml-metadata (task-yaml) ──
235
+ case "task-yaml": {
236
+ out.tags = Array.from(new Set([...(out.tags ?? []), "task", "scheduled"]));
237
+ try {
238
+ const doc = parseYaml(file.content());
239
+ const data = doc && typeof doc === "object" && !Array.isArray(doc) ? doc : {};
240
+ const hints = new Set();
241
+ const schedule = nonEmptyString(data.schedule);
242
+ if (schedule)
243
+ hints.add(`schedule:${schedule}`);
244
+ const workflow = nonEmptyString(data.workflow);
245
+ if (workflow)
246
+ hints.add(`workflow:${workflow}`);
247
+ const prompt = nonEmptyString(data.prompt);
248
+ if (prompt)
249
+ hints.add(`prompt:${prompt}`);
250
+ finalizeHints(out, hints);
251
+ }
252
+ catch {
253
+ // Non-fatal: skip metadata extraction on parse error
254
+ }
255
+ return out;
256
+ }
257
+ // ── session-md-metadata (session-md) ──
258
+ case "session-md": {
259
+ try {
260
+ const fm = parseFrontmatter(file.content()).data;
261
+ applyFrontmatterDescriptionAndTags(fm, out);
262
+ out.tags = Array.from(new Set([...(out.tags ?? []), "session"]));
263
+ const hints = new Set();
264
+ const harness = nonEmptyString(fm.harness);
265
+ if (harness)
266
+ hints.add(`harness:${harness}`);
267
+ const project = nonEmptyString(fm.project);
268
+ if (project)
269
+ hints.add(`project:${project}`);
270
+ const logPath = nonEmptyString(fm.log_path);
271
+ if (logPath)
272
+ hints.add(`log_path:${logPath}`);
273
+ finalizeHints(out, hints);
274
+ }
275
+ catch {
276
+ // Non-fatal: skip metadata extraction on parse error
277
+ }
278
+ return out;
279
+ }
280
+ // ── fact-md-metadata (fact-md) ──
281
+ case "fact-md": {
282
+ try {
283
+ const fm = parseFrontmatter(file.content()).data;
284
+ applyFrontmatterDescriptionAndTags(fm, out);
285
+ const tags = new Set([...(out.tags ?? []), "fact"]);
286
+ const hints = new Set();
287
+ const category = nonEmptyString(fm.category);
288
+ if (category) {
289
+ tags.add(category);
290
+ hints.add(`category:${category}`);
291
+ }
292
+ if (fm.pinned === true) {
293
+ tags.add("pinned");
294
+ hints.add("pinned");
295
+ }
296
+ out.tags = Array.from(tags).filter(Boolean);
297
+ finalizeHints(out, hints);
298
+ }
299
+ catch {
300
+ // Non-fatal: skip metadata extraction on parse error
301
+ }
302
+ return out;
303
+ }
304
+ // ── workflow-document-metadata (workflow-md) ──
305
+ case "workflow-md": {
306
+ try {
307
+ const result = parseWorkflow(file.content(), { path: file.relPath });
308
+ if (!result.ok)
309
+ return out;
310
+ const doc = result.document;
311
+ const hints = new Set();
312
+ if (doc.preamble)
313
+ hints.add(doc.preamble);
314
+ for (const step of doc.steps) {
315
+ hints.add(step.id);
316
+ if (step.instructions)
317
+ hints.add(step.instructions.text);
318
+ if (step.gateRubric)
319
+ hints.add(step.gateRubric.text);
320
+ }
321
+ out.searchHints = Array.from(hints).filter(Boolean);
322
+ if (doc.params) {
323
+ const parameters = Object.entries(doc.params).map(([name, schema]) => {
324
+ const description = schema.description;
325
+ return { name, ...(typeof description === "string" && description ? { description } : {}) };
326
+ });
327
+ if (parameters.length)
328
+ out.parameters = parameters;
329
+ }
330
+ }
331
+ catch {
332
+ // See file header: broken workflows drop at drain time, not here.
333
+ }
334
+ return out;
335
+ }
336
+ default:
337
+ // No contributor applies to this renderer (e.g. skill-md/command-md/
338
+ // agent-md — the static-only mappings carry no metadata contributor).
339
+ return out;
340
+ }
341
+ }
342
+ /**
343
+ * Apply {@link foldRecognizedMetadata}'s output onto a `IndexDocument` with the
344
+ * SAME precedence the live in-place renderer contributors use (Chunk 5 M-b), so
345
+ * `entry.applyPreContributorFields → applyFoldedMetadata → applyPostContributorFields`
346
+ * reproduces `buildEntryFromFile`'s `P1/P2 → contributors → P4` byte-for-byte.
347
+ *
348
+ * Precedence, verified against every case in {@link foldRecognizedMetadata}:
349
+ * - description/source/confidence travel together and only when the entry has
350
+ * no description yet (contributors gate on `!entry.description`); a
351
+ * contributor that sets description WITHOUT source/confidence
352
+ * (workflow-program-yaml) leaves those untouched — mirrored by the
353
+ * `folded.source`/`folded.confidence` guards below;
354
+ * - tags UNION into the existing set (order-preserving Set dedup), matching the
355
+ * contributors' `Array.from(new Set([...entry.tags, ...added]))`;
356
+ * - searchHints / toc / parameters are SET (overwrite), matching the
357
+ * contributors' direct assignment.
358
+ *
359
+ * The fold computes each field unconditionally from an empty seed; re-gating on
360
+ * `entry` state here is what recovers the in-place precedence (the fold ≡
361
+ * contributors-on-a-minimal-seed is pinned by the akm-adapter fold-parity test).
362
+ */
363
+ export function applyFoldedMetadata(entry, folded) {
364
+ if (folded.description && !entry.description) {
365
+ entry.description = folded.description;
366
+ if (folded.source)
367
+ entry.source = folded.source;
368
+ if (folded.confidence !== undefined)
369
+ entry.confidence = folded.confidence;
370
+ }
371
+ if (folded.tags && folded.tags.length > 0) {
372
+ entry.tags = Array.from(new Set([...(entry.tags ?? []), ...folded.tags]));
373
+ }
374
+ // searchHints MERGE (not overwrite): every live contributor seeds its hints
375
+ // from `new Set(entry.searchHints ?? [])` before adding, so a frontmatter
376
+ // `searchHints:` set by P2 (applyCuratedFrontmatter) survives and the
377
+ // contributor's hints append to it. The fold computes only the contributor's
378
+ // additions (from an empty seed), so unioning them onto the existing set —
379
+ // existing first, deduped, truthy-filtered — reproduces the live merge exactly.
380
+ if (folded.searchHints) {
381
+ entry.searchHints = Array.from(new Set([...(entry.searchHints ?? []), ...folded.searchHints])).filter(Boolean);
382
+ }
383
+ if (folded.toc)
384
+ entry.toc = folded.toc;
385
+ if (folded.parameters)
386
+ entry.parameters = folded.parameters;
387
+ }
@@ -0,0 +1,149 @@
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 `akm-task` adapter — akm 0.9.0 format-family work item (#46).
6
+ *
7
+ * A native akm task-YAML bundle (spec §6/§7). A `.yml` file derives
8
+ * `type: task`; conceptId strips the `.yml` extension. Tasks are AKM-native
9
+ * YAML, NOT OKF markdown concepts. Recognition does NOT gate on validity — an
10
+ * invalid task (e.g. two targets) is still RECOGNIZED; the `invalid-task-yaml`
11
+ * violation surfaces only in `validate`.
12
+ *
13
+ * ── validate (spec §6 task validation column) ──
14
+ *
15
+ * A task must declare a `schedule`, an `enabled` boolean, and EXACTLY ONE
16
+ * target (`prompt` XOR `workflow` XOR `command`). The akm adapter's
17
+ * `TaskLinter` port checks "at least one" target; the native task family here is
18
+ * STRICTER — declaring two targets is `invalid-task-yaml`. So this adapter owns
19
+ * a purpose-built one-target check rather than reusing that port.
20
+ *
21
+ * Conformance oracle (authored, DO NOT modify): fixture
22
+ * `tests/fixtures/bundles/akm-task/` + goldens
23
+ * `tests/fixtures/format-family-goldens/akm-task/{recognition,placement,lint,renderer}.json`.
24
+ */
25
+ import fs from "node:fs";
26
+ import path from "node:path";
27
+ import { parse as parseYaml } from "yaml";
28
+ import { hashContent } from "./shared.js";
29
+ /** A native task bundle is single-component; its one component is `main`. */
30
+ const COMPONENT_ID = "main";
31
+ /** The task YAML extension (spec §6 task row). */
32
+ const TASK_EXT = ".yml";
33
+ /** The mutually-exclusive task target keys (exactly one required). */
34
+ const TARGET_KEYS = ["prompt", "workflow", "command"];
35
+ /** Upper bound on the bounded `content` FTS field (mirrors okf-adapter). */
36
+ const MAX_CONTENT_CHARS = 100_000;
37
+ function toPosix(p) {
38
+ return p.replace(/\\/g, "/");
39
+ }
40
+ function recognize(c, file) {
41
+ if (file.ext !== TASK_EXT)
42
+ return null;
43
+ const conceptId = toPosix(file.relPath).replace(/\.yml$/i, "");
44
+ const name = conceptId.split("/").pop() ?? conceptId;
45
+ const raw = file.content();
46
+ return {
47
+ ref: `${c.id}//${conceptId}`,
48
+ bundle: c.id,
49
+ component: COMPONENT_ID,
50
+ conceptId,
51
+ path: file.absPath,
52
+ hash: hashContent(raw),
53
+ adapterId: "akm-task",
54
+ type: "task",
55
+ name,
56
+ content: raw.length > MAX_CONTENT_CHARS ? raw.slice(0, MAX_CONTENT_CHARS) : raw,
57
+ };
58
+ }
59
+ /** Parse a task YAML into a plain record (tolerant: malformed / non-mapping → {}). */
60
+ function parseTaskYaml(raw) {
61
+ try {
62
+ const doc = parseYaml(raw);
63
+ if (doc && typeof doc === "object" && !Array.isArray(doc))
64
+ return doc;
65
+ }
66
+ catch {
67
+ // malformed YAML
68
+ }
69
+ return {};
70
+ }
71
+ /** The native `invalid-task-yaml` check: schedule + enabled(boolean) + EXACTLY ONE target. */
72
+ function taskDiagnostics(relPath, data) {
73
+ if (Object.keys(data).length === 0)
74
+ return [];
75
+ const problems = [];
76
+ if (typeof data.schedule !== "string" || data.schedule.trim() === "")
77
+ problems.push("schedule");
78
+ if (typeof data.enabled !== "boolean")
79
+ problems.push("enabled (must be a boolean)");
80
+ const targets = TARGET_KEYS.filter((k) => k in data && data[k] !== undefined && data[k] !== null);
81
+ if (targets.length === 0)
82
+ problems.push("exactly one target (prompt, workflow, or command)");
83
+ else if (targets.length > 1)
84
+ problems.push(`exactly one target — declares ${targets.length} (${targets.join(", ")})`);
85
+ if (problems.length === 0)
86
+ return [];
87
+ return [
88
+ { file: relPath, issue: "invalid-task-yaml", detail: `task field errors: ${problems.join("; ")}`, fixed: false },
89
+ ];
90
+ }
91
+ async function validate(_c, changes, ctx) {
92
+ const diagnostics = [];
93
+ for (const change of changes) {
94
+ if (change.op === "delete")
95
+ continue;
96
+ const raw = change.after ?? (await ctx.readFile(change.path));
97
+ if (typeof raw !== "string")
98
+ continue;
99
+ if (path.extname(change.path).toLowerCase() !== TASK_EXT)
100
+ continue;
101
+ diagnostics.push(...taskDiagnostics(toPosix(change.path), parseTaskYaml(raw)));
102
+ }
103
+ return diagnostics;
104
+ }
105
+ export const akmTaskAdapter = {
106
+ id: "akm-task",
107
+ version: "0.9.0",
108
+ extensions: [TASK_EXT],
109
+ recognize,
110
+ validate,
111
+ /** A task places to `<conceptId>.yml`; an already-suffixed conceptId is idempotent. */
112
+ placeNew(c, conceptId) {
113
+ const posix = toPosix(conceptId);
114
+ return path.join(c.root, /\.yml$/i.test(posix) ? posix : `${posix}.yml`);
115
+ },
116
+ /** Tasks live anywhere under the component root. */
117
+ directoryList() {
118
+ return ["."];
119
+ },
120
+ /**
121
+ * Install-time probe (§1.2): a root holding a top-level `.yml` file that
122
+ * parses as a task (a `schedule` key). The task-shape probe keeps it disjoint
123
+ * from non-task YAML.
124
+ */
125
+ looksLikeRoot(root) {
126
+ let entries;
127
+ try {
128
+ entries = fs.readdirSync(root, { withFileTypes: true });
129
+ }
130
+ catch {
131
+ return false;
132
+ }
133
+ for (const entry of entries) {
134
+ if (!entry.isFile() || path.extname(entry.name).toLowerCase() !== TASK_EXT)
135
+ continue;
136
+ let raw;
137
+ try {
138
+ raw = fs.readFileSync(path.join(root, entry.name), "utf8");
139
+ }
140
+ catch {
141
+ continue;
142
+ }
143
+ const data = parseTaskYaml(raw);
144
+ if (typeof data.schedule === "string" && data.schedule.trim() !== "")
145
+ return true;
146
+ }
147
+ return false;
148
+ },
149
+ };