akm-cli 0.9.0-rc.0 → 0.9.0-rc.13

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (598) hide show
  1. package/CHANGELOG.md +1283 -22
  2. package/README.md +62 -37
  3. package/SECURITY.md +46 -31
  4. package/dist/akm +162 -38
  5. package/dist/akm-migrate +44 -0
  6. package/dist/assets/backends/schtasks-template.xml +2 -1
  7. package/dist/assets/hints/cli-hints-full.md +268 -118
  8. package/dist/assets/hints/cli-hints-short.md +87 -24
  9. package/dist/assets/{profiles → improve-strategies}/catchup.json +3 -1
  10. package/dist/assets/{profiles → improve-strategies}/consolidate.json +3 -1
  11. package/dist/assets/{profiles → improve-strategies}/default.json +6 -7
  12. package/dist/assets/improve-strategies/frequent.json +15 -0
  13. package/dist/assets/{profiles → improve-strategies}/graph-refresh.json +4 -2
  14. package/dist/assets/{profiles → improve-strategies}/memory-focus.json +4 -1
  15. package/dist/assets/{profiles → improve-strategies}/proactive-maintenance.json +5 -5
  16. package/dist/assets/{profiles → improve-strategies}/quick.json +4 -2
  17. package/dist/assets/improve-strategies/reflect-distill.json +30 -0
  18. package/dist/assets/{profiles → improve-strategies}/thorough.json +1 -1
  19. package/dist/assets/prompts/consolidate-system.md +5 -5
  20. package/dist/assets/prompts/extract-session.md +2 -6
  21. package/dist/assets/prompts/memory-infer-user.md +2 -3
  22. package/dist/assets/prompts/reflect-llm-framed-contract.md +11 -0
  23. package/dist/assets/prompts/reflect-llm-schema-contract.md +3 -0
  24. package/dist/assets/prompts/reflect-output-repair.md +3 -0
  25. package/dist/assets/prompts/workflow-unit-preamble.md +26 -0
  26. package/dist/assets/stash-skeleton/README.md +38 -10
  27. package/dist/assets/stash-skeleton/facts/conventions/assets/agent.md +8 -0
  28. package/dist/assets/stash-skeleton/facts/conventions/assets/command.md +8 -0
  29. package/dist/assets/stash-skeleton/facts/conventions/assets/fact.md +14 -1
  30. package/dist/assets/stash-skeleton/facts/conventions/assets/knowledge.md +13 -1
  31. package/dist/assets/stash-skeleton/facts/conventions/assets/lesson.md +9 -1
  32. package/dist/assets/stash-skeleton/facts/conventions/assets/memory.md +11 -0
  33. package/dist/assets/stash-skeleton/facts/conventions/assets/script.md +9 -0
  34. package/dist/assets/stash-skeleton/facts/conventions/assets/skill.md +9 -0
  35. package/dist/assets/stash-skeleton/facts/conventions/assets/workflow.md +8 -0
  36. package/dist/assets/stash-skeleton/facts/conventions/backlinks.md +100 -0
  37. package/dist/assets/stash-skeleton/facts/conventions/domains.md +64 -0
  38. package/dist/assets/stash-skeleton/facts/conventions/organization.md +136 -0
  39. package/dist/assets/tasks/core/extract.yml +3 -2
  40. package/dist/assets/tasks/core/improve.yml +2 -1
  41. package/dist/assets/tasks/core/index-refresh.yml +1 -0
  42. package/dist/assets/tasks/core/sync.yml +1 -0
  43. package/dist/assets/tasks/core/version-check.yml +2 -1
  44. package/dist/assets/tasks/improve/akm-graph-refresh-weekly.yml +5 -0
  45. package/dist/assets/tasks/improve/akm-improve-catchup.yml +8 -0
  46. package/dist/assets/tasks/improve/akm-improve-consolidate.yml +5 -0
  47. package/dist/assets/tasks/improve/akm-improve-frequent.yml +5 -0
  48. package/dist/assets/tasks/improve/akm-improve-nightly.yml +5 -0
  49. package/dist/assets/templates/html/health.html +5 -4
  50. package/dist/assets/workflows/workflow-template.md +31 -15
  51. package/dist/cli/invocation.js +279 -0
  52. package/dist/cli/parse-args.js +5 -90
  53. package/dist/cli/retired-commands.js +78 -0
  54. package/dist/cli/shared.js +158 -48
  55. package/dist/cli-node.mjs +2 -1
  56. package/dist/cli.js +747 -293
  57. package/dist/commands/agent/agent-dispatch.js +19 -18
  58. package/dist/commands/agent/agent-support.js +0 -24
  59. package/dist/commands/agent/contribute-cli.js +43 -97
  60. package/dist/commands/completions.js +80 -23
  61. package/dist/commands/config-cli.js +44 -281
  62. package/dist/commands/env/env-binding.js +99 -0
  63. package/dist/commands/env/env-cli.js +84 -224
  64. package/dist/commands/env/env.js +12 -163
  65. package/dist/commands/env/marker-path.js +6 -0
  66. package/dist/commands/env/secret-cli.js +45 -61
  67. package/dist/commands/env/secret.js +32 -62
  68. package/dist/commands/feedback-cli.js +179 -85
  69. package/dist/commands/health/accept-rate.js +58 -0
  70. package/dist/commands/health/advisories.js +7 -8
  71. package/dist/commands/health/checks.js +279 -94
  72. package/dist/commands/health/html-report.js +197 -578
  73. package/dist/commands/health/improve-metrics.js +277 -246
  74. package/dist/commands/health/llm-usage.js +19 -19
  75. package/dist/commands/health/md-report.js +16 -7
  76. package/dist/commands/health/metrics.js +67 -32
  77. package/dist/commands/health/renderers.js +47 -0
  78. package/dist/commands/health/report-view-model.js +508 -0
  79. package/dist/commands/health/stash-exposure.js +1 -1
  80. package/dist/commands/health/surfaces.js +16 -56
  81. package/dist/commands/health/task-runs.js +3 -67
  82. package/dist/{migrate-storage-node.mjs → commands/health/types-checks.js} +1 -5
  83. package/dist/commands/health/types-improve.js +29 -0
  84. package/dist/{output/text/save.js → commands/health/types-metrics.js} +1 -2
  85. package/dist/commands/health/types-result.js +7 -0
  86. package/dist/commands/health/types-runs.js +4 -0
  87. package/dist/commands/health/types-session-log.js +4 -0
  88. package/dist/commands/health/types-windows.js +4 -0
  89. package/dist/commands/health/types.js +26 -21
  90. package/dist/commands/health/windows.js +2 -3
  91. package/dist/commands/health.js +296 -167
  92. package/dist/commands/improve/anti-collapse.js +5 -5
  93. package/dist/commands/improve/autonomy-gate.js +68 -0
  94. package/dist/commands/improve/collapse-detector.js +65 -52
  95. package/dist/commands/improve/consolidate/chunking.js +9 -7
  96. package/dist/commands/improve/consolidate/eligibility.js +1 -23
  97. package/dist/commands/improve/consolidate/merge.js +4 -0
  98. package/dist/commands/improve/consolidate.js +454 -1354
  99. package/dist/commands/improve/content-hash.js +39 -0
  100. package/dist/commands/improve/distill/content-repair.js +4 -10
  101. package/dist/commands/improve/distill/promote-memory.js +89 -64
  102. package/dist/commands/improve/distill/quality-gate.js +118 -42
  103. package/dist/commands/improve/distill-guards.js +1 -1
  104. package/dist/commands/improve/distill-promotion-policy.js +33 -888
  105. package/dist/commands/improve/distill.js +607 -363
  106. package/dist/commands/improve/eligibility.js +165 -79
  107. package/dist/commands/improve/extract-cli.js +35 -126
  108. package/dist/commands/improve/extract-prompt.js +6 -35
  109. package/dist/commands/improve/extract.js +640 -391
  110. package/dist/commands/improve/feedback-valence.js +2 -12
  111. package/dist/commands/improve/improve-cli.js +134 -135
  112. package/dist/commands/improve/improve-result-file.js +30 -50
  113. package/dist/commands/improve/improve-run-types.js +4 -0
  114. package/dist/commands/improve/improve-strategies.js +135 -0
  115. package/dist/commands/improve/improve.js +904 -701
  116. package/dist/commands/improve/locks.js +64 -111
  117. package/dist/commands/improve/loop-stages.js +1110 -923
  118. package/dist/commands/improve/memory/derived-ref.js +124 -0
  119. package/dist/commands/improve/memory/memory-belief.js +79 -7
  120. package/dist/commands/improve/memory/memory-contradiction-detect.js +49 -52
  121. package/dist/commands/improve/memory/memory-improve.js +25 -37
  122. package/dist/commands/improve/outcome-loop.js +25 -88
  123. package/dist/commands/improve/preparation.js +1034 -813
  124. package/dist/commands/improve/proactive-maintenance.js +34 -9
  125. package/dist/commands/improve/proposal-envelope.js +31 -0
  126. package/dist/commands/improve/reflect.js +983 -794
  127. package/dist/commands/improve/run-context.js +119 -0
  128. package/dist/commands/improve/salience.js +24 -127
  129. package/dist/commands/improve/session-asset.js +7 -3
  130. package/dist/commands/improve/shared.js +14 -34
  131. package/dist/commands/improve/source-identity.js +28 -0
  132. package/dist/commands/improve/triage.js +20 -17
  133. package/dist/commands/lint/base-linter.js +340 -313
  134. package/dist/commands/lint/env-key-rules.js +31 -47
  135. package/dist/commands/lint/index.js +185 -30
  136. package/dist/commands/{events.js → log.js} +28 -38
  137. package/dist/commands/migrate-cli.js +54 -0
  138. package/dist/commands/migration-tool.js +55 -0
  139. package/dist/commands/observability-cli.js +70 -208
  140. package/dist/commands/proposal/diff-format.js +50 -0
  141. package/dist/commands/proposal/drain-policies.js +0 -6
  142. package/dist/commands/proposal/drain.js +91 -40
  143. package/dist/commands/proposal/proposal-cli.js +134 -132
  144. package/dist/commands/proposal/proposal-types.js +56 -0
  145. package/dist/commands/proposal/proposal.js +83 -65
  146. package/dist/commands/proposal/propose-cli.js +88 -0
  147. package/dist/commands/proposal/propose.js +105 -88
  148. package/dist/commands/proposal/repository.js +1303 -278
  149. package/dist/commands/proposal/validators/proposal-quality-validators.js +16 -6
  150. package/dist/commands/proposal/validators/proposal-validators.js +61 -12
  151. package/dist/commands/proposal/validators/proposals.js +6 -8
  152. package/dist/commands/read/curate.js +78 -73
  153. package/dist/commands/read/knowledge.js +510 -13
  154. package/dist/commands/read/registry-search.js +2 -2
  155. package/dist/commands/read/remember-cli.js +84 -15
  156. package/dist/commands/read/search-cli.js +203 -96
  157. package/dist/commands/read/search.js +126 -94
  158. package/dist/commands/read/show.js +226 -250
  159. package/dist/commands/registry-cli.js +34 -60
  160. package/dist/commands/remember.js +18 -57
  161. package/dist/commands/sources/add-cli.js +104 -49
  162. package/dist/commands/sources/bundle-cli.js +166 -0
  163. package/dist/commands/sources/bundle-config-ops.js +63 -0
  164. package/dist/commands/sources/info.js +27 -15
  165. package/dist/commands/sources/init.js +30 -40
  166. package/dist/commands/sources/installed-stashes.js +469 -172
  167. package/dist/commands/sources/migration-help.js +7 -4
  168. package/dist/commands/sources/schema-repair.js +10 -9
  169. package/dist/commands/sources/self-update.js +182 -121
  170. package/dist/commands/sources/source-add.js +169 -178
  171. package/dist/commands/sources/source-clone.js +144 -41
  172. package/dist/commands/sources/source-manage.js +94 -59
  173. package/dist/commands/sources/sources-cli.js +64 -205
  174. package/dist/commands/sources/stash-cli.js +91 -54
  175. package/dist/commands/sources/stash-skeleton.js +1 -1
  176. package/dist/commands/tasks/tasks-cli.js +106 -104
  177. package/dist/commands/tasks/tasks.js +445 -262
  178. package/dist/commands/workflow-cli.js +232 -121
  179. package/dist/core/action-contributors.js +1 -1
  180. package/dist/core/activation-policy.js +49 -0
  181. package/dist/core/adapter/adapters/agent-skills-adapter.js +181 -0
  182. package/dist/core/adapter/adapters/akm-adapter.js +528 -0
  183. package/dist/core/adapter/adapters/akm-lint.js +392 -0
  184. package/dist/core/adapter/adapters/akm-metadata.js +387 -0
  185. package/dist/core/adapter/adapters/akm-task-adapter.js +149 -0
  186. package/dist/core/adapter/adapters/akm-workflow-adapter.js +180 -0
  187. package/dist/core/adapter/adapters/claude-adapter.js +61 -0
  188. package/dist/core/adapter/adapters/dotenv-adapter.js +187 -0
  189. package/dist/core/adapter/adapters/generic-files-adapter.js +119 -0
  190. package/dist/core/adapter/adapters/index.js +80 -0
  191. package/dist/core/adapter/adapters/llm-wiki-adapter.js +419 -0
  192. package/dist/core/adapter/adapters/okf-adapter.js +391 -0
  193. package/dist/core/adapter/adapters/opencode-adapter.js +68 -0
  194. package/dist/core/adapter/adapters/shared.js +286 -0
  195. package/dist/core/adapter/adapters/tool-dir-shared.js +217 -0
  196. package/dist/core/adapter/adapters/website-snapshot-adapter.js +155 -0
  197. package/dist/core/adapter/bundle-adapter.js +4 -0
  198. package/dist/core/adapter/detect-adapter.js +17 -0
  199. package/dist/core/adapter/recognize-match.js +44 -0
  200. package/dist/core/adapter/registry.js +56 -0
  201. package/dist/core/adapter/types.js +4 -0
  202. package/dist/core/asset/akm-markdown.js +30 -0
  203. package/dist/core/asset/asset-placement.js +243 -0
  204. package/dist/core/asset/asset-ref.js +110 -79
  205. package/dist/core/asset/asset-serialize.js +20 -0
  206. package/dist/core/asset/frontmatter.js +28 -12
  207. package/dist/core/asset/markdown.js +40 -51
  208. package/dist/core/asset/resolve-ref.js +274 -0
  209. package/dist/core/asset/stash-meta.js +2 -2
  210. package/dist/core/bundle-id.js +51 -0
  211. package/dist/core/common.js +281 -86
  212. package/dist/core/config/config-io.js +42 -128
  213. package/dist/core/config/config-schema.js +233 -834
  214. package/dist/core/config/config-sources.js +162 -39
  215. package/dist/core/config/config-types.js +16 -11
  216. package/dist/core/config/config-version.js +29 -0
  217. package/dist/core/config/config-walker.js +126 -37
  218. package/dist/core/config/config.js +154 -331
  219. package/dist/core/config/deep-merge.js +41 -0
  220. package/dist/core/config/engine-semantics.js +28 -0
  221. package/dist/core/config/experimental.js +21 -0
  222. package/dist/core/config/schema/embedding.js +38 -0
  223. package/dist/core/config/schema/engines.js +116 -0
  224. package/dist/core/config/schema/experimental.js +47 -0
  225. package/dist/core/config/schema/feedback.js +31 -0
  226. package/dist/core/config/schema/improve-processes.js +389 -0
  227. package/dist/core/config/schema/improve.js +94 -0
  228. package/dist/core/config/schema/index-config.js +176 -0
  229. package/dist/core/config/schema/output.js +18 -0
  230. package/dist/core/config/schema/primitives.js +94 -0
  231. package/dist/core/config/schema/search.js +30 -0
  232. package/dist/core/config/schema/setup.js +18 -0
  233. package/dist/core/config/schema/sources-bundles.js +169 -0
  234. package/dist/core/config/schema/workflow.js +29 -0
  235. package/dist/core/env-secret-ref.js +155 -20
  236. package/dist/core/errors.js +17 -15
  237. package/dist/core/events-types.js +4 -0
  238. package/dist/core/events.js +46 -128
  239. package/dist/core/extra-params.js +62 -0
  240. package/dist/core/file-change.js +17 -0
  241. package/dist/core/file-lock.js +202 -57
  242. package/dist/core/fs-txn.js +392 -0
  243. package/dist/core/git-message.js +59 -0
  244. package/dist/core/improve-result.js +167 -0
  245. package/dist/core/json-schema.js +142 -0
  246. package/dist/core/lesson-lint.js +1 -17
  247. package/dist/core/logs-db.js +1 -1
  248. package/dist/core/maintenance-barrier.js +135 -0
  249. package/dist/core/migration-operation.js +44 -0
  250. package/dist/core/mutation-target.js +78 -0
  251. package/dist/core/paths.js +22 -25
  252. package/dist/core/platform.js +10 -0
  253. package/dist/core/recognition-util.js +128 -0
  254. package/dist/core/redaction.js +392 -0
  255. package/dist/core/standards/resolve-standards-context.js +36 -65
  256. package/dist/core/standards/resolve-stash-standards.js +2 -2
  257. package/dist/core/standards/resolve-type-conventions.js +5 -5
  258. package/dist/core/state/migrations.js +242 -11
  259. package/dist/core/state-db.js +98 -10
  260. package/dist/core/structured.js +1 -1
  261. package/dist/core/subprocess.js +303 -0
  262. package/dist/core/text-truncation.js +9 -5
  263. package/dist/core/time.js +20 -0
  264. package/dist/core/type-presentation.js +130 -0
  265. package/dist/core/warn.js +0 -3
  266. package/dist/core/write-source.js +834 -118
  267. package/dist/indexer/bundle-identity-guard.js +92 -0
  268. package/dist/indexer/db/graph-db.js +1 -25
  269. package/dist/indexer/db/llm-cache.js +1 -1
  270. package/dist/indexer/ensure-index.js +30 -9
  271. package/dist/indexer/graph/graph-boost.js +9 -30
  272. package/dist/indexer/graph/graph-extraction.js +41 -27
  273. package/dist/indexer/graph/graph-types.js +4 -0
  274. package/dist/indexer/index-writer-lock.js +93 -49
  275. package/dist/indexer/index-written-assets.js +100 -53
  276. package/dist/indexer/indexer.js +746 -329
  277. package/dist/indexer/init.js +18 -25
  278. package/dist/indexer/installations.js +142 -0
  279. package/dist/indexer/passes/dir-staleness.js +18 -10
  280. package/dist/indexer/passes/memory-inference.js +25 -15
  281. package/dist/indexer/passes/metadata.js +412 -243
  282. package/dist/indexer/scan/doc-to-entry.js +160 -0
  283. package/dist/indexer/scan/drain-dir.js +134 -0
  284. package/dist/indexer/search/db-search.js +292 -108
  285. package/dist/indexer/search/fts-query.js +64 -0
  286. package/dist/indexer/search/ranking-contributors.js +145 -25
  287. package/dist/indexer/search/ranking-types.js +4 -0
  288. package/dist/indexer/search/ranking.js +28 -71
  289. package/dist/indexer/search/search-attribution.js +67 -0
  290. package/dist/indexer/search/search-fields.js +18 -3
  291. package/dist/indexer/search/search-hit-enrichers.js +30 -40
  292. package/dist/indexer/search/search-source.js +157 -111
  293. package/dist/indexer/search/semantic-status.js +4 -1
  294. package/dist/indexer/usage/usage-events.js +10 -30
  295. package/dist/indexer/walk/file-context.js +3 -45
  296. package/dist/indexer/walk/matchers.js +42 -34
  297. package/dist/indexer/walk/path-resolver.js +11 -5
  298. package/dist/indexer/walk/walker.js +42 -14
  299. package/dist/integrations/agent/builder-shared.js +7 -0
  300. package/dist/integrations/agent/builders.js +5 -56
  301. package/dist/integrations/agent/config.js +3 -143
  302. package/dist/integrations/agent/detect.js +17 -2
  303. package/dist/integrations/agent/engine-resolution.js +231 -0
  304. package/dist/integrations/agent/index.js +1 -2
  305. package/dist/integrations/agent/model-aliases.js +16 -2
  306. package/dist/integrations/agent/profiles.js +36 -62
  307. package/dist/integrations/agent/prompts.js +46 -18
  308. package/dist/integrations/agent/runner-dispatch.js +93 -4
  309. package/dist/integrations/agent/runner.js +76 -208
  310. package/dist/integrations/agent/spawn.js +88 -196
  311. package/dist/integrations/harnesses/aider/agent-builder.js +114 -0
  312. package/dist/integrations/harnesses/aider/index.js +48 -0
  313. package/dist/integrations/harnesses/aider/result-extractor.js +53 -0
  314. package/dist/integrations/harnesses/amazonq/agent-builder.js +147 -0
  315. package/dist/integrations/harnesses/amazonq/index.js +45 -0
  316. package/dist/integrations/harnesses/amazonq/result-extractor.js +48 -0
  317. package/dist/integrations/harnesses/claude/agent-builder.js +46 -8
  318. package/dist/integrations/harnesses/claude/config-import.js +1 -3
  319. package/dist/integrations/harnesses/claude/index.js +24 -35
  320. package/dist/integrations/harnesses/claude/result-extractor.js +52 -0
  321. package/dist/integrations/harnesses/claude/session-log.js +27 -75
  322. package/dist/integrations/harnesses/codex/agent-builder.js +138 -0
  323. package/dist/integrations/harnesses/codex/index.js +52 -0
  324. package/dist/integrations/harnesses/codex/result-extractor.js +73 -0
  325. package/dist/integrations/harnesses/copilot/agent-builder.js +122 -0
  326. package/dist/integrations/harnesses/copilot/index.js +48 -0
  327. package/dist/integrations/harnesses/copilot/result-extractor.js +151 -0
  328. package/dist/integrations/harnesses/gemini/agent-builder.js +120 -0
  329. package/dist/integrations/harnesses/gemini/index.js +48 -0
  330. package/dist/integrations/harnesses/gemini/result-extractor.js +121 -0
  331. package/dist/integrations/harnesses/ids.js +24 -0
  332. package/dist/integrations/harnesses/index.js +54 -34
  333. package/dist/integrations/harnesses/opencode/agent-builder.js +23 -5
  334. package/dist/integrations/harnesses/opencode/config-import.js +1 -3
  335. package/dist/integrations/harnesses/opencode/index.js +14 -32
  336. package/dist/integrations/harnesses/opencode/session-log.js +67 -125
  337. package/dist/integrations/harnesses/opencode-sdk/harness.js +51 -0
  338. package/dist/integrations/harnesses/opencode-sdk/sdk-runner.js +681 -108
  339. package/dist/integrations/harnesses/openhands/agent-builder.js +128 -0
  340. package/dist/integrations/harnesses/openhands/index.js +48 -0
  341. package/dist/integrations/harnesses/openhands/result-extractor.js +103 -0
  342. package/dist/integrations/harnesses/pi/agent-builder.js +97 -0
  343. package/dist/integrations/harnesses/pi/index.js +45 -0
  344. package/dist/integrations/harnesses/pi/result-extractor.js +135 -0
  345. package/dist/integrations/harnesses/shared.js +17 -0
  346. package/dist/integrations/harnesses/types.js +43 -32
  347. package/dist/integrations/lockfile.js +211 -24
  348. package/dist/integrations/session-logs/index.js +36 -39
  349. package/dist/integrations/session-logs/provider-base.js +113 -0
  350. package/dist/llm/client.js +182 -110
  351. package/dist/llm/embedders/deterministic.js +2 -2
  352. package/dist/llm/embedders/remote.js +21 -9
  353. package/dist/llm/feature-gate.js +17 -57
  354. package/dist/llm/graph-extract.js +12 -13
  355. package/dist/llm/index-passes.js +8 -42
  356. package/dist/llm/memory-infer.js +144 -1
  357. package/dist/llm/metadata-enhance.js +45 -30
  358. package/dist/llm/structured-call.js +16 -8
  359. package/dist/llm/usage-persist.js +30 -5
  360. package/dist/llm/usage-telemetry.js +59 -6
  361. package/dist/output/cli-hints.js +1 -2
  362. package/dist/output/command-registry.js +27 -0
  363. package/dist/output/context.js +22 -7
  364. package/dist/output/format-exempt.js +80 -0
  365. package/dist/output/generic-render.js +251 -0
  366. package/dist/output/html-render.js +11 -16
  367. package/dist/output/render-registry.js +57 -0
  368. package/dist/output/renderers.js +14 -279
  369. package/dist/output/shapes/curate.js +10 -1
  370. package/dist/output/shapes/events.js +12 -7
  371. package/dist/output/shapes/helpers.js +58 -84
  372. package/dist/output/shapes/passthrough.js +11 -39
  373. package/dist/output/shapes/proposal/producer.js +15 -7
  374. package/dist/output/shapes/registry.js +12 -6
  375. package/dist/output/shapes.js +0 -9
  376. package/dist/output/text/{init.js → bundle-create.js} +3 -1
  377. package/dist/output/text/bundle-show.js +7 -0
  378. package/dist/output/text/command-format.js +562 -0
  379. package/dist/output/text/env.js +1 -3
  380. package/dist/output/text/events.js +8 -7
  381. package/dist/output/text/helpers.js +15 -1164
  382. package/dist/output/text/proposal/producer.js +4 -2
  383. package/dist/output/text/proposal-format.js +202 -0
  384. package/dist/output/text/registry-commands.js +1 -2
  385. package/dist/output/text/registry.js +12 -6
  386. package/dist/output/text/show-directives.js +117 -0
  387. package/dist/output/text/show-format.js +103 -0
  388. package/dist/output/text/sync.js +5 -0
  389. package/dist/output/text/workflow-format.js +332 -0
  390. package/dist/output/text/workflow.js +3 -2
  391. package/dist/output/text.js +10 -19
  392. package/dist/registry/factory.js +4 -6
  393. package/dist/registry/origin-resolve.js +16 -27
  394. package/dist/registry/providers/skills-sh.js +3 -3
  395. package/dist/registry/providers/static-index.js +15 -25
  396. package/dist/registry/resolve.js +43 -94
  397. package/dist/registry/semver.js +43 -0
  398. package/dist/runtime.js +81 -12
  399. package/dist/scripts/akm-migrate.js +35529 -0
  400. package/dist/setup/detect.js +5 -7
  401. package/dist/setup/detected-engines.js +136 -0
  402. package/dist/setup/engine-config.js +100 -0
  403. package/dist/setup/registry-stash-loader.js +3 -3
  404. package/dist/setup/semantic-assets.js +12 -9
  405. package/dist/setup/setup.js +444 -208
  406. package/dist/setup/steps/connection-shared.js +120 -0
  407. package/dist/setup/steps/connection.js +108 -305
  408. package/dist/setup/steps/platforms.js +13 -12
  409. package/dist/setup/steps/semantic.js +15 -3
  410. package/dist/setup/steps/sources.js +21 -15
  411. package/dist/setup/steps/stashdir.js +6 -4
  412. package/dist/setup/steps/tasks.js +236 -119
  413. package/dist/setup/steps.js +3 -2
  414. package/dist/sources/freshness.js +39 -0
  415. package/dist/sources/provider-factory.js +11 -17
  416. package/dist/sources/providers/filesystem.js +2 -3
  417. package/dist/sources/providers/git-install.js +278 -34
  418. package/dist/sources/providers/git-provider.js +54 -56
  419. package/dist/sources/providers/git-stash.js +420 -91
  420. package/dist/sources/providers/git.js +2 -2
  421. package/dist/sources/providers/npm.js +16 -19
  422. package/dist/sources/providers/provider-utils.js +47 -22
  423. package/dist/sources/providers/sync-from-ref.js +3 -9
  424. package/dist/sources/providers/website.js +2 -2
  425. package/dist/sources/resolve.js +11 -10
  426. package/dist/sources/snapshot-fetchers/types.js +4 -0
  427. package/dist/sources/{website-ingest.js → snapshot-fetchers/website-ingest.js} +110 -41
  428. package/dist/storage/database.js +60 -4
  429. package/dist/storage/engines/sqlite-migrations.js +156 -5
  430. package/dist/storage/locations.js +1 -2
  431. package/dist/storage/repositories/canaries-repository.js +1 -1
  432. package/dist/storage/repositories/events-repository.js +51 -11
  433. package/dist/storage/repositories/improve-runs-repository.js +6 -32
  434. package/dist/storage/repositories/index-connection.js +79 -0
  435. package/dist/storage/repositories/index-db.js +4 -3
  436. package/dist/storage/repositories/index-entries-repository.js +863 -0
  437. package/dist/{indexer/db/entry-mapper.js → storage/repositories/index-entry-mapper.js} +19 -2
  438. package/dist/storage/repositories/index-entry-types.js +4 -0
  439. package/dist/storage/repositories/index-fts-repository.js +167 -0
  440. package/dist/storage/repositories/index-llm-cache-repository.js +108 -0
  441. package/dist/storage/repositories/index-meta-repository.js +49 -0
  442. package/dist/{indexer/db/schema.js → storage/repositories/index-schema.js} +226 -100
  443. package/dist/storage/repositories/index-sql.js +12 -0
  444. package/dist/storage/repositories/index-utility-repository.js +356 -0
  445. package/dist/storage/repositories/index-vec-repository.js +250 -0
  446. package/dist/storage/repositories/outcome-repository.js +119 -0
  447. package/dist/storage/repositories/proposals-repository.js +317 -75
  448. package/dist/storage/repositories/registry-cache.js +1 -1
  449. package/dist/storage/repositories/salience-repository.js +172 -0
  450. package/dist/storage/repositories/task-history-repository.js +110 -3
  451. package/dist/storage/repositories/workflow-runs-repository.js +240 -19
  452. package/dist/tasks/backends/cron.js +169 -46
  453. package/dist/tasks/backends/exec-utils.js +76 -3
  454. package/dist/tasks/backends/index.js +6 -9
  455. package/dist/tasks/backends/launchd.js +292 -55
  456. package/dist/tasks/backends/schtasks.js +557 -70
  457. package/dist/tasks/backends/types.js +4 -0
  458. package/dist/tasks/command-executable.js +93 -0
  459. package/dist/tasks/embedded.js +56 -38
  460. package/dist/tasks/parser.js +156 -64
  461. package/dist/tasks/resolve-akm-bin.js +144 -51
  462. package/dist/tasks/runner.js +377 -209
  463. package/dist/tasks/schedule.js +108 -19
  464. package/dist/tasks/scheduler-invocation.js +296 -0
  465. package/dist/tasks/schema.js +1 -1
  466. package/dist/tasks/task-id.js +35 -0
  467. package/dist/tasks/validator.js +30 -16
  468. package/dist/text-import-hook.mjs +1 -1
  469. package/dist/workflows/authoring/authoring.js +104 -43
  470. package/dist/workflows/authoring/scope-key.js +1 -1
  471. package/dist/workflows/cli.js +0 -16
  472. package/dist/workflows/concurrency-policy.js +15 -0
  473. package/dist/workflows/exec/brief.js +450 -0
  474. package/dist/workflows/exec/frozen-judge.js +47 -0
  475. package/dist/workflows/exec/native-executor.js +1038 -0
  476. package/dist/workflows/exec/param-secrets.js +115 -0
  477. package/dist/workflows/exec/report.js +1460 -0
  478. package/dist/workflows/exec/run-workflow.js +602 -0
  479. package/dist/workflows/exec/scheduler.js +71 -0
  480. package/dist/workflows/exec/step-work.js +1190 -0
  481. package/dist/workflows/exec/unit-writer.js +23 -0
  482. package/dist/workflows/exec/workflow-engine-gate.js +67 -0
  483. package/dist/workflows/exec/worktree.js +171 -0
  484. package/dist/workflows/ir/compile.js +246 -0
  485. package/dist/workflows/ir/freeze.js +233 -0
  486. package/dist/workflows/ir/params.js +54 -0
  487. package/dist/workflows/ir/plan-hash.js +68 -0
  488. package/dist/workflows/ir/schema.js +540 -0
  489. package/dist/workflows/parser.js +878 -304
  490. package/dist/workflows/program/expressions.js +181 -0
  491. package/dist/workflows/program/schema.js +51 -0
  492. package/dist/workflows/renderer.js +100 -45
  493. package/dist/workflows/resource-limits.js +22 -0
  494. package/dist/workflows/runtime/agent-identity.js +59 -14
  495. package/dist/workflows/runtime/checkin.js +1 -1
  496. package/dist/workflows/runtime/plan-classifier.js +131 -0
  497. package/dist/workflows/runtime/runs.js +376 -119
  498. package/dist/workflows/runtime/unit-checkin.js +45 -0
  499. package/dist/workflows/runtime/unit-phases.js +20 -0
  500. package/dist/workflows/runtime/workflow-asset-loader.js +241 -40
  501. package/dist/workflows/schema.js +1 -11
  502. package/dist/workflows/validate-summary.js +2 -3
  503. package/dist/workflows/validator.js +52 -30
  504. package/docs/README.md +42 -78
  505. package/docs/migration/README.md +8 -0
  506. package/docs/migration/release-notes/0.6.0.md +1 -1
  507. package/docs/migration/release-notes/0.7.0.md +9 -8
  508. package/docs/migration/release-notes/0.9.0.md +158 -14
  509. package/docs/migration/v0.7-to-v0.8.md +46 -47
  510. package/docs/migration/v0.8-to-v0.9.md +844 -0
  511. package/docs/reference/README.md +12 -0
  512. package/docs/reference/data-and-telemetry.md +333 -0
  513. package/package.json +21 -17
  514. package/schemas/akm-asset-envelope.json +93 -0
  515. package/schemas/akm-config.json +4636 -0
  516. package/schemas/akm-task.json +87 -0
  517. package/schemas/akm-workflow.json +373 -0
  518. package/dist/akm-migrate-storage +0 -38
  519. package/dist/assets/help/help-accept.md +0 -12
  520. package/dist/assets/help/help-improve.md +0 -84
  521. package/dist/assets/help/help-proposals.md +0 -17
  522. package/dist/assets/help/help-propose.md +0 -17
  523. package/dist/assets/help/help-reject.md +0 -11
  524. package/dist/assets/profiles/frequent.json +0 -13
  525. package/dist/assets/profiles/recombine-only.json +0 -21
  526. package/dist/assets/profiles/reflect-distill.json +0 -30
  527. package/dist/assets/profiles/synthesize.json +0 -15
  528. package/dist/assets/prompts/procedural-system.md +0 -44
  529. package/dist/assets/prompts/recombine-system.md +0 -40
  530. package/dist/assets/prompts/staleness-detect-system.md +0 -6
  531. package/dist/assets/tasks/core/backup.yml +0 -4
  532. package/dist/assets/tasks/graph-refresh-weekly.yml +0 -10
  533. package/dist/assets/templates/html/default.html +0 -78
  534. package/dist/assets/templates/html/vendor/echarts.min.js +0 -45
  535. package/dist/assets/wiki/index-template.md +0 -12
  536. package/dist/assets/wiki/ingest-workflow-template.md +0 -83
  537. package/dist/assets/wiki/log-template.md +0 -8
  538. package/dist/assets/wiki/schema-template.md +0 -61
  539. package/dist/cli/config-migrate.js +0 -150
  540. package/dist/cli/config-validate.js +0 -39
  541. package/dist/commands/graph/graph-cli.js +0 -124
  542. package/dist/commands/graph/graph.js +0 -487
  543. package/dist/commands/improve/calibration.js +0 -161
  544. package/dist/commands/improve/dedup.js +0 -482
  545. package/dist/commands/improve/extract-watch.js +0 -140
  546. package/dist/commands/improve/hot-probation.js +0 -45
  547. package/dist/commands/improve/improve-auto-accept.js +0 -276
  548. package/dist/commands/improve/improve-profiles.js +0 -168
  549. package/dist/commands/improve/procedural.js +0 -398
  550. package/dist/commands/improve/recombine.js +0 -818
  551. package/dist/commands/improve/schema-similarity-gate.js +0 -168
  552. package/dist/commands/lint/agent-linter.js +0 -44
  553. package/dist/commands/lint/command-linter.js +0 -44
  554. package/dist/commands/lint/default-linter.js +0 -16
  555. package/dist/commands/lint/fact-linter.js +0 -39
  556. package/dist/commands/lint/knowledge-linter.js +0 -16
  557. package/dist/commands/lint/memory-linter.js +0 -61
  558. package/dist/commands/lint/registry.js +0 -41
  559. package/dist/commands/lint/skill-linter.js +0 -45
  560. package/dist/commands/lint/task-linter.js +0 -50
  561. package/dist/commands/lint/workflow-linter.js +0 -81
  562. package/dist/commands/proposal/legacy-import.js +0 -115
  563. package/dist/commands/sources/history.js +0 -196
  564. package/dist/commands/tasks/default-tasks.js +0 -186
  565. package/dist/commands/wiki-cli.js +0 -292
  566. package/dist/core/asset/asset-registry.js +0 -76
  567. package/dist/core/asset/asset-spec.js +0 -259
  568. package/dist/core/config/config-migration.js +0 -602
  569. package/dist/core/deep-merge.js +0 -38
  570. package/dist/core/eval/rank-metrics.js +0 -113
  571. package/dist/core/ripgrep/install.js +0 -163
  572. package/dist/core/ripgrep/resolve.js +0 -81
  573. package/dist/indexer/db/db.js +0 -1413
  574. package/dist/indexer/manifest.js +0 -170
  575. package/dist/indexer/passes/metadata-contributors.js +0 -31
  576. package/dist/indexer/usage/unmigrated-vaults-guard.js +0 -94
  577. package/dist/integrations/harnesses/opencode-sdk/index.js +0 -49
  578. package/dist/llm/call-ai.js +0 -62
  579. package/dist/llm/memory-infer-impl.js +0 -138
  580. package/dist/output/shapes/distill.js +0 -14
  581. package/dist/output/shapes/history.js +0 -11
  582. package/dist/output/text/distill.js +0 -6
  583. package/dist/output/text/enable-disable.js +0 -8
  584. package/dist/output/text/history.js +0 -6
  585. package/dist/output/text/wiki.js +0 -16
  586. package/dist/registry/build-index.js +0 -386
  587. package/dist/scripts/migrate-storage.js +0 -19108
  588. package/dist/scripts/migrations/import-fs-improve-runs-to-db.js +0 -9411
  589. package/dist/scripts/migrations/v16-to-v17.js +0 -141
  590. package/dist/setup/legacy-config.js +0 -106
  591. package/dist/storage/repositories/consolidation-repository.js +0 -38
  592. package/dist/storage/repositories/recombine-repository.js +0 -213
  593. package/dist/wiki/wiki-templates.js +0 -15
  594. package/dist/wiki/wiki.js +0 -1012
  595. package/dist/workflows/db.js +0 -215
  596. package/docs/data-and-telemetry.md +0 -226
  597. /package/dist/sources/{wiki-fetchers → snapshot-fetchers}/registry.js +0 -0
  598. /package/dist/sources/{wiki-fetchers → snapshot-fetchers}/youtube.js +0 -0
@@ -0,0 +1,59 @@
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
+ * Leaf util for sanitizing git commit messages.
6
+ *
7
+ * Split out of `core/write-source.ts` so that `sources/providers/git-stash.ts`
8
+ * (which `core/write-source.ts` imports `getCachePaths`/`listGitChangedPaths`/
9
+ * `parseGitRepoUrl`/`saveGitStash` from, via the `sources/providers/git`
10
+ * barrel, by value) does not need to import back into `write-source.ts` just
11
+ * for this helper — that back-edge was a 3-file static-graph cycle
12
+ * (write-source.ts → git.ts → git-stash.ts → write-source.ts; chunk 9 WI-9.8
13
+ * KILL 6 sever). Callers import `sanitizeCommitMessage` directly so
14
+ * the dependency graph stays acyclic.
15
+ */
16
+ /**
17
+ * Maximum length of a sanitized git commit message. Git itself imposes no
18
+ * fixed limit, but message strings come from refs and `--message` flags that
19
+ * can be supplied by users or upstream config. A 4096-char clamp keeps audit
20
+ * trails readable and prevents pathological payloads from bloating the log
21
+ * stream a downstream consumer parses.
22
+ */
23
+ const COMMIT_MESSAGE_MAX_LENGTH = 4096;
24
+ /**
25
+ * Sanitize a string before passing it as `git commit -m <message>`.
26
+ *
27
+ * Defenses, in order:
28
+ * 1. Strip NUL bytes (`\0`) — git rejects them anyway, but we never want
29
+ * them in argv.
30
+ * 2. Replace any CR/LF (`\r`, `\n`) and other ASCII control chars with a
31
+ * single space. This collapses newline-injection attempts that would
32
+ * otherwise turn a single-line commit subject into a forged trailer
33
+ * block.
34
+ * 3. Collapse runs of whitespace into a single space and trim.
35
+ * 4. Clamp to {@link COMMIT_MESSAGE_MAX_LENGTH} characters.
36
+ *
37
+ * If the result is empty after sanitization the caller should substitute a
38
+ * default — this helper returns `""` rather than throwing because not every
39
+ * callsite has a sensible "invalid input" exit code, and "empty" is a
40
+ * recoverable signal.
41
+ */
42
+ export function sanitizeCommitMessage(input) {
43
+ if (typeof input !== "string")
44
+ return "";
45
+ // 1. Strip NULs outright.
46
+ let out = input.replace(/\0/g, "");
47
+ // 2. Replace CR/LF + other C0 control characters (0x00-0x1F, 0x7F) with a
48
+ // space. Tab (0x09) is included intentionally — commit subjects should
49
+ // be a single visual line.
50
+ // biome-ignore lint/suspicious/noControlCharactersInRegex: intentional sanitization
51
+ out = out.replace(/[\x00-\x1F\x7F]/g, " ");
52
+ // 3. Collapse whitespace runs and trim.
53
+ out = out.replace(/\s+/g, " ").trim();
54
+ // 4. Clamp length.
55
+ if (out.length > COMMIT_MESSAGE_MAX_LENGTH) {
56
+ out = out.slice(0, COMMIT_MESSAGE_MAX_LENGTH).trimEnd();
57
+ }
58
+ return out;
59
+ }
@@ -0,0 +1,167 @@
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
+ const COMMON_FIELDS = [
5
+ "schemaVersion",
6
+ "ok",
7
+ "scope",
8
+ "dryRun",
9
+ "skipped",
10
+ "guidance",
11
+ "memorySummary",
12
+ "memoryCleanup",
13
+ "cyclesRun",
14
+ "plannedRefs",
15
+ "actions",
16
+ "distillSkipped",
17
+ "validationFailures",
18
+ "schemaRepairs",
19
+ "consolidation",
20
+ "extract",
21
+ "lintSummary",
22
+ "memoryIndexHealth",
23
+ "coverageGaps",
24
+ "evalCasesWritten",
25
+ "deadUrls",
26
+ "reflectsWithErrorContext",
27
+ "memoryInference",
28
+ "graphExtraction",
29
+ "memoryInferenceDurationMs",
30
+ "graphExtractionDurationMs",
31
+ "orphansPurged",
32
+ "proposalsExpired",
33
+ "reflectCooldownActions",
34
+ "reflectSkippedActions",
35
+ "reflectGuardRejectedActions",
36
+ "gateAutoAcceptedCount",
37
+ "gateAutoAcceptFailedCount",
38
+ "triage",
39
+ "proactiveMaintenance",
40
+ "cycleMetrics",
41
+ "runId",
42
+ "sync",
43
+ "terminated",
44
+ ];
45
+ const V2_FIELDS = new Set([...COMMON_FIELDS, "strategy", "strategyFilteredRefs"]);
46
+ function fail(message) {
47
+ throw new Error(`invalid improve-result envelope: ${message}`);
48
+ }
49
+ function isRecord(value) {
50
+ return typeof value === "object" && value !== null && !Array.isArray(value);
51
+ }
52
+ function requireExactFields(value, allowed) {
53
+ const unknown = Object.keys(value).filter((key) => !allowed.has(key));
54
+ if (unknown.length > 0)
55
+ fail(`unknown field${unknown.length === 1 ? "" : "s"}: ${unknown.sort().join(", ")}`);
56
+ }
57
+ function validateCommon(value) {
58
+ if (typeof value.ok !== "boolean")
59
+ fail("ok must be a boolean");
60
+ if (typeof value.dryRun !== "boolean")
61
+ fail("dryRun must be a boolean");
62
+ if (!Array.isArray(value.plannedRefs))
63
+ fail("plannedRefs must be an array");
64
+ if (!isRecord(value.scope))
65
+ fail("scope must be an object");
66
+ requireExactFields(value.scope, new Set(["mode", "value"]));
67
+ if (value.scope.mode !== "all" && value.scope.mode !== "type" && value.scope.mode !== "ref") {
68
+ fail('scope.mode must be "all", "type", or "ref"');
69
+ }
70
+ if (value.scope.value !== undefined && typeof value.scope.value !== "string") {
71
+ fail("scope.value must be a string when present");
72
+ }
73
+ if (!isRecord(value.memorySummary))
74
+ fail("memorySummary must be an object");
75
+ requireExactFields(value.memorySummary, new Set(["eligible", "derived"]));
76
+ if (typeof value.memorySummary.eligible !== "number" || typeof value.memorySummary.derived !== "number") {
77
+ fail("memorySummary.eligible and memorySummary.derived must be numbers");
78
+ }
79
+ for (const field of [
80
+ "actions",
81
+ "validationFailures",
82
+ "schemaRepairs",
83
+ "extract",
84
+ "coverageGaps",
85
+ "deadUrls",
86
+ ]) {
87
+ if (value[field] !== undefined && !Array.isArray(value[field]))
88
+ fail(`${field} must be an array`);
89
+ }
90
+ for (const field of [
91
+ "cyclesRun",
92
+ "evalCasesWritten",
93
+ "reflectsWithErrorContext",
94
+ "memoryInferenceDurationMs",
95
+ "graphExtractionDurationMs",
96
+ "orphansPurged",
97
+ "proposalsExpired",
98
+ "reflectCooldownActions",
99
+ "reflectSkippedActions",
100
+ "reflectGuardRejectedActions",
101
+ "gateAutoAcceptedCount",
102
+ "gateAutoAcceptFailedCount",
103
+ ]) {
104
+ if (value[field] !== undefined && typeof value[field] !== "number")
105
+ fail(`${field} must be a number`);
106
+ }
107
+ for (const field of ["guidance", "runId"]) {
108
+ if (value[field] !== undefined && typeof value[field] !== "string")
109
+ fail(`${field} must be a string`);
110
+ }
111
+ for (const field of [
112
+ "skipped",
113
+ "memoryCleanup",
114
+ "distillSkipped",
115
+ "consolidation",
116
+ "lintSummary",
117
+ "memoryIndexHealth",
118
+ "memoryInference",
119
+ "graphExtraction",
120
+ "triage",
121
+ "proactiveMaintenance",
122
+ "cycleMetrics",
123
+ "sync",
124
+ "terminated",
125
+ ]) {
126
+ if (value[field] !== undefined && !isRecord(value[field]))
127
+ fail(`${field} must be an object`);
128
+ }
129
+ if (isRecord(value.terminated)) {
130
+ requireExactFields(value.terminated, new Set(["reason", "at", "errorMessage"]));
131
+ if (typeof value.terminated.reason !== "string" || typeof value.terminated.at !== "string") {
132
+ fail("terminated.reason and terminated.at must be strings");
133
+ }
134
+ if (value.terminated.errorMessage !== undefined && typeof value.terminated.errorMessage !== "string") {
135
+ fail("terminated.errorMessage must be a string when present");
136
+ }
137
+ }
138
+ }
139
+ /** Decode the persisted public result contract. */
140
+ export function decodeImproveResult(input) {
141
+ let parsed = input;
142
+ if (typeof input === "string") {
143
+ try {
144
+ parsed = JSON.parse(input);
145
+ }
146
+ catch {
147
+ fail("not valid JSON");
148
+ }
149
+ }
150
+ if (!isRecord(parsed))
151
+ fail("root must be an object");
152
+ if (parsed.schemaVersion === 2) {
153
+ requireExactFields(parsed, V2_FIELDS);
154
+ validateCommon(parsed);
155
+ if (typeof parsed.strategy !== "string" || parsed.strategy.length === 0) {
156
+ fail("strategy must be a non-empty string");
157
+ }
158
+ if (parsed.strategyFilteredRefs !== undefined && !Array.isArray(parsed.strategyFilteredRefs)) {
159
+ fail("strategyFilteredRefs must be an array");
160
+ }
161
+ return {
162
+ envelope: parsed,
163
+ strategy: parsed.strategy,
164
+ };
165
+ }
166
+ fail(`unsupported schemaVersion: ${String(parsed.schemaVersion)}`);
167
+ }
@@ -0,0 +1,142 @@
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
+ * Structural JSON-Schema-subset validator (orchestration plan P1).
6
+ *
7
+ * The workflow engine's structured-output normalization needs to validate
8
+ * unit results against the author-declared unit `output` schema on any harness —
9
+ * including ones with no native schema support. Pulling in a full
10
+ * draft-2020-12 validator is deliberately avoided (dependency surface); this
11
+ * module implements the bounded subset that covers the schemas workflow
12
+ * authors actually write:
13
+ *
14
+ * Supported: `type` (string | string[] — string, number, integer, boolean,
15
+ * object, array, null), `properties`, `required`, `items`,
16
+ * `additionalProperties: false`, `enum` (primitives), `minItems`,
17
+ * `maxItems`, `minLength`, `maxLength`, `minimum`, `maximum`.
18
+ *
19
+ * Ignored (permissive): `$ref`, `allOf`/`anyOf`/`oneOf`/`not`, `pattern`,
20
+ * `format`, and every other keyword. Unknown keywords never throw — a
21
+ * schema using them simply constrains less. Callers needing full JSON
22
+ * Schema semantics should validate downstream.
23
+ *
24
+ * Returns a flat list of human-readable error strings (empty = valid), each
25
+ * prefixed with a JSON-pointer-ish path — the shape `runStructured`'s
26
+ * corrective-feedback builder wants.
27
+ */
28
+ export function validateJsonSchemaSubset(value, schema) {
29
+ const errors = [];
30
+ validateNode(value, schema, "$", errors);
31
+ return errors;
32
+ }
33
+ function typeOf(value) {
34
+ if (value === null)
35
+ return "null";
36
+ if (Array.isArray(value))
37
+ return "array";
38
+ switch (typeof value) {
39
+ case "string":
40
+ return "string";
41
+ case "boolean":
42
+ return "boolean";
43
+ case "number":
44
+ return Number.isInteger(value) ? "integer" : "number";
45
+ default:
46
+ return "object";
47
+ }
48
+ }
49
+ function matchesType(actual, expected) {
50
+ if (expected === actual)
51
+ return true;
52
+ // JSON Schema: every integer is also a number.
53
+ return expected === "number" && actual === "integer";
54
+ }
55
+ function validateNode(value, schema, path, errors) {
56
+ const actual = typeOf(value);
57
+ const declared = schema.type;
58
+ if (typeof declared === "string" || Array.isArray(declared)) {
59
+ const expected = (Array.isArray(declared) ? declared : [declared]).filter((t) => typeof t === "string");
60
+ if (expected.length > 0 && !expected.some((t) => matchesType(actual, t))) {
61
+ errors.push(`${path}: expected type ${expected.join(" | ")}, got ${actual}`);
62
+ return; // type mismatch makes the remaining constraints meaningless
63
+ }
64
+ }
65
+ if (Array.isArray(schema.enum) && schema.enum.length > 0) {
66
+ const allowed = schema.enum;
67
+ if (!allowed.some((candidate) => candidate === value)) {
68
+ errors.push(`${path}: value ${JSON.stringify(value)} is not one of ${JSON.stringify(allowed)}`);
69
+ return;
70
+ }
71
+ }
72
+ if (actual === "string" && typeof value === "string") {
73
+ if (typeof schema.minLength === "number" && value.length < schema.minLength) {
74
+ errors.push(`${path}: string shorter than minLength ${schema.minLength}`);
75
+ }
76
+ if (typeof schema.maxLength === "number" && value.length > schema.maxLength) {
77
+ errors.push(`${path}: string longer than maxLength ${schema.maxLength}`);
78
+ }
79
+ return;
80
+ }
81
+ if ((actual === "number" || actual === "integer") && typeof value === "number") {
82
+ if (typeof schema.minimum === "number" && value < schema.minimum) {
83
+ errors.push(`${path}: ${value} is below minimum ${schema.minimum}`);
84
+ }
85
+ if (typeof schema.maximum === "number" && value > schema.maximum) {
86
+ errors.push(`${path}: ${value} is above maximum ${schema.maximum}`);
87
+ }
88
+ return;
89
+ }
90
+ if (actual === "array" && Array.isArray(value)) {
91
+ if (typeof schema.minItems === "number" && value.length < schema.minItems) {
92
+ errors.push(`${path}: array has fewer than minItems ${schema.minItems}`);
93
+ }
94
+ if (typeof schema.maxItems === "number" && value.length > schema.maxItems) {
95
+ errors.push(`${path}: array has more than maxItems ${schema.maxItems}`);
96
+ }
97
+ const items = schema.items;
98
+ if (items && typeof items === "object" && !Array.isArray(items)) {
99
+ value.forEach((element, index) => {
100
+ validateNode(element, items, `${path}[${index}]`, errors);
101
+ });
102
+ }
103
+ return;
104
+ }
105
+ if (actual === "object" && typeof value === "object" && value !== null) {
106
+ const record = value;
107
+ const properties = schema.properties && typeof schema.properties === "object" && !Array.isArray(schema.properties)
108
+ ? schema.properties
109
+ : undefined;
110
+ if (Array.isArray(schema.required)) {
111
+ for (const key of schema.required) {
112
+ // `Object.hasOwn`, not `key in record`: a required key satisfied only by
113
+ // an inherited prototype member (e.g. "toString", "constructor") is NOT
114
+ // present on the value itself, so `{}` must fail `required: ["toString"]`.
115
+ if (typeof key === "string" && !Object.hasOwn(record, key)) {
116
+ errors.push(`${path}: missing required property "${key}"`);
117
+ }
118
+ }
119
+ }
120
+ if (properties) {
121
+ for (const [key, propSchema] of Object.entries(properties)) {
122
+ if (!Object.hasOwn(record, key))
123
+ continue;
124
+ if (propSchema && typeof propSchema === "object" && !Array.isArray(propSchema)) {
125
+ validateNode(record[key], propSchema, `${path}.${key}`, errors);
126
+ }
127
+ }
128
+ }
129
+ // `additionalProperties: false` closes the object to exactly its declared
130
+ // `properties`. This MUST run even when no `properties` object is present:
131
+ // `{ type: "object", additionalProperties: false }` admits only `{}`. Use
132
+ // `Object.hasOwn` so an inherited key name (e.g. "toString") on the empty
133
+ // property set is not mistaken for a declared property.
134
+ if (schema.additionalProperties === false) {
135
+ for (const key of Object.keys(record)) {
136
+ if (!properties || !Object.hasOwn(properties, key)) {
137
+ errors.push(`${path}: unexpected property "${key}" (additionalProperties: false)`);
138
+ }
139
+ }
140
+ }
141
+ }
142
+ }
@@ -13,9 +13,7 @@
13
13
  *
14
14
  * Lint produces structured findings rather than throwing so callers can
15
15
  * batch-validate (e.g. `akm proposal accept` over a queue) and surface every
16
- * violation in a single pass. A strict wrapper (`assertLessonValid`) throws
17
- * a `UsageError` for call sites that want a fail-fast contract — most
18
- * notably the proposal-accept path described in v1 spec §13.1.
16
+ * violation in a single pass.
19
17
  *
20
18
  * The lint is intentionally side-effect free and does not import the indexer
21
19
  * or filesystem walker; it operates on a single file path + raw string. This
@@ -24,7 +22,6 @@
24
22
  */
25
23
  import fs from "node:fs";
26
24
  import { parseFrontmatter } from "./asset/frontmatter.js";
27
- import { UsageError } from "./errors.js";
28
25
  function isNonEmptyString(value) {
29
26
  return typeof value === "string" && value.trim().length > 0;
30
27
  }
@@ -74,16 +71,3 @@ export function lintLessonFile(filePath) {
74
71
  const raw = fs.readFileSync(filePath, "utf8");
75
72
  return lintLessonContent(raw, filePath);
76
73
  }
77
- /**
78
- * Strict variant: throws a `UsageError` if any finding is present. The thrown
79
- * error carries the full set of findings on its message and a hint pointing
80
- * at v1 spec §13. The first finding's `field` becomes the error's primary
81
- * field for callers that want to highlight the first violation.
82
- */
83
- export function assertLessonValid(filePath) {
84
- const report = lintLessonFile(filePath);
85
- if (report.findings.length === 0)
86
- return;
87
- const message = report.findings.map((f) => f.message).join("\n");
88
- throw new UsageError(message, "MISSING_REQUIRED_ARGUMENT", "Lessons require non-empty `description` and `when_to_use` frontmatter fields. See v1 spec §13.");
89
- }
@@ -9,7 +9,7 @@
9
9
  * The strategic direction (stop scattering data across files/folders) means
10
10
  * every NEW log consumer queries this database; the per-run text file written
11
11
  * by the task runner is retained only as a transitional tail for humans —
12
- * see docs/technical/logs-audit.md for the full producer audit.
12
+ * per the #579 logs audit of every producer.
13
13
  *
14
14
  * ## Why a separate database from state.db
15
15
  *
@@ -0,0 +1,135 @@
1
+ // This Source Code Form is subject to the terms of the Mozilla Public
2
+ // License, v. 2.0. If a copy of the MPL was not distributed with this
3
+ // file, You can obtain one at https://mozilla.org/MPL/2.0/.
4
+ import { AsyncLocalStorage } from "node:async_hooks";
5
+ import { randomUUID } from "node:crypto";
6
+ import fs from "node:fs";
7
+ import path from "node:path";
8
+ import { ConfigError } from "./errors.js";
9
+ import { createLockPayload, probeLock, reclaimStaleLock, releaseLock, tryAcquireLockSync } from "./file-lock.js";
10
+ import { getMaintenanceBarrierPath } from "./paths.js";
11
+ const heldBarrierContext = new AsyncLocalStorage();
12
+ /**
13
+ * Serialize restore with the short critical section that creates every
14
+ * long-lived AKM lock or workflow lease. The long operation keeps its own
15
+ * lock/lease; this barrier is released immediately after acquisition.
16
+ */
17
+ export function tryAcquireMaintenanceBarrier() {
18
+ const lockPath = getMaintenanceBarrierPath();
19
+ fs.mkdirSync(path.dirname(lockPath), { recursive: true });
20
+ for (let attempt = 0; attempt < 2; attempt += 1) {
21
+ const ownership = tryAcquireLockSync(lockPath, createLockPayload({ purpose: "maintenance-start" }));
22
+ if (ownership) {
23
+ return () => releaseLock(ownership);
24
+ }
25
+ const probe = probeLock(lockPath);
26
+ if (probe.state !== "stale" || !reclaimStaleLock(lockPath, probe))
27
+ return undefined;
28
+ }
29
+ return undefined;
30
+ }
31
+ export function acquireMaintenanceBarrier() {
32
+ const release = tryAcquireMaintenanceBarrier();
33
+ if (release)
34
+ return release;
35
+ throw new ConfigError(`AKM maintenance is in progress (barrier ${getMaintenanceBarrierPath()}); retry after it completes.`, "INVALID_CONFIG_FILE");
36
+ }
37
+ export function withMaintenanceStartBarrier(run) {
38
+ if (heldBarrierContext.getStore()?.active)
39
+ return run();
40
+ const release = acquireMaintenanceBarrier();
41
+ const ownership = { active: true };
42
+ try {
43
+ return heldBarrierContext.run(ownership, run);
44
+ }
45
+ finally {
46
+ ownership.active = false;
47
+ release();
48
+ }
49
+ }
50
+ /** Run while holding the start barrier, or return undefined when it is busy. */
51
+ export function tryWithMaintenanceStartBarrier(run) {
52
+ if (heldBarrierContext.getStore()?.active)
53
+ return run();
54
+ const release = tryAcquireMaintenanceBarrier();
55
+ if (!release)
56
+ return undefined;
57
+ const ownership = { active: true };
58
+ try {
59
+ return heldBarrierContext.run(ownership, run);
60
+ }
61
+ finally {
62
+ ownership.active = false;
63
+ release();
64
+ }
65
+ }
66
+ async function acquireMaintenanceBarrierAsync() {
67
+ const deadline = Date.now() + 5_000;
68
+ while (true) {
69
+ const release = tryAcquireMaintenanceBarrier();
70
+ if (release)
71
+ return release;
72
+ if (Date.now() >= deadline)
73
+ return acquireMaintenanceBarrier();
74
+ await new Promise((resolve) => setTimeout(resolve, 5));
75
+ }
76
+ }
77
+ export async function withMaintenanceStartBarrierAsync(run) {
78
+ if (heldBarrierContext.getStore()?.active)
79
+ return run();
80
+ const release = await acquireMaintenanceBarrierAsync();
81
+ const ownership = { active: true };
82
+ try {
83
+ return await heldBarrierContext.run(ownership, run);
84
+ }
85
+ finally {
86
+ ownership.active = false;
87
+ release();
88
+ }
89
+ }
90
+ function withMaintenanceStartBarrierSyncWait(run) {
91
+ if (heldBarrierContext.getStore()?.active)
92
+ return run();
93
+ const deadline = Date.now() + 5_000;
94
+ let release = tryAcquireMaintenanceBarrier();
95
+ while (!release && Date.now() < deadline) {
96
+ Atomics.wait(new Int32Array(new SharedArrayBuffer(4)), 0, 0, 5);
97
+ release = tryAcquireMaintenanceBarrier();
98
+ }
99
+ if (!release)
100
+ release = acquireMaintenanceBarrier();
101
+ const ownership = { active: true };
102
+ try {
103
+ return heldBarrierContext.run(ownership, run);
104
+ }
105
+ finally {
106
+ ownership.active = false;
107
+ release();
108
+ }
109
+ }
110
+ /** Register a long-lived operation atomically with restore's blocker scan. */
111
+ export async function acquireMaintenanceActivity(name) {
112
+ return withMaintenanceStartBarrierAsync(async () => {
113
+ const directory = path.join(path.dirname(getMaintenanceBarrierPath()), "maintenance-activities");
114
+ fs.mkdirSync(directory, { recursive: true, mode: 0o700 });
115
+ const lockPath = path.join(directory, `${name}-${process.pid}-${randomUUID()}.lock`);
116
+ const ownership = tryAcquireLockSync(lockPath, createLockPayload({ purpose: name }));
117
+ if (!ownership) {
118
+ throw new ConfigError(`Could not register AKM maintenance activity at ${lockPath}.`, "INVALID_CONFIG_FILE");
119
+ }
120
+ return () => releaseLock(ownership);
121
+ });
122
+ }
123
+ /** Synchronous activity registration for synchronous database handle lifetimes. */
124
+ export function acquireMaintenanceActivitySync(name) {
125
+ return withMaintenanceStartBarrierSyncWait(() => {
126
+ const directory = path.join(path.dirname(getMaintenanceBarrierPath()), "maintenance-activities");
127
+ fs.mkdirSync(directory, { recursive: true, mode: 0o700 });
128
+ const lockPath = path.join(directory, `${name}-${process.pid}-${randomUUID()}.lock`);
129
+ const ownership = tryAcquireLockSync(lockPath, createLockPayload({ purpose: name }));
130
+ if (!ownership) {
131
+ throw new ConfigError(`Could not register AKM maintenance activity at ${lockPath}.`, "INVALID_CONFIG_FILE");
132
+ }
133
+ return () => releaseLock(ownership);
134
+ });
135
+ }
@@ -0,0 +1,44 @@
1
+ // This Source Code Form is subject to the terms of the Mozilla Public
2
+ // License, v. 2.0. If a copy of the MPL was not distributed with this
3
+ // file, You can obtain one at https://mozilla.org/MPL/2.0/.
4
+ import crypto from "node:crypto";
5
+ import fs from "node:fs";
6
+ import path from "node:path";
7
+ import { ConfigError } from "./errors.js";
8
+ import { getConfigPath, getDataDir } from "./paths.js";
9
+ let afterPendingCheckHook;
10
+ /** TEST-ONLY: run once after a clear pending-operation check. */
11
+ export function _setAfterPendingOperationCheckHookForTests(hook) {
12
+ afterPendingCheckHook = hook;
13
+ }
14
+ function installationId() {
15
+ return crypto
16
+ .createHash("sha256")
17
+ .update(path.resolve(path.dirname(getConfigPath())))
18
+ .update("\0")
19
+ .update(path.resolve(getDataDir()))
20
+ .digest("hex")
21
+ .slice(0, 24);
22
+ }
23
+ export function getMigrationOperationRoot() {
24
+ return path.join(getDataDir(), "backups", "migrations", installationId());
25
+ }
26
+ export function getMigrationRestoreJournalPath() {
27
+ return path.join(getMigrationOperationRoot(), "restore-active.json");
28
+ }
29
+ export function getMigrationApplyJournalPath() {
30
+ return path.join(getMigrationOperationRoot(), "apply-active.json");
31
+ }
32
+ export function assertNoPendingMigrationOperation() {
33
+ for (const [kind, journalPath] of [
34
+ ["restore", getMigrationRestoreJournalPath()],
35
+ ["migration apply", getMigrationApplyJournalPath()],
36
+ ]) {
37
+ if (fs.existsSync(journalPath)) {
38
+ throw new ConfigError(`AKM ${kind} recovery is pending at ${journalPath}; refusing canonical config/database access until recovery completes.`, "INVALID_CONFIG_FILE");
39
+ }
40
+ }
41
+ const hook = afterPendingCheckHook;
42
+ afterPendingCheckHook = undefined;
43
+ hook?.();
44
+ }
@@ -0,0 +1,78 @@
1
+ // This Source Code Form is subject to the terms of the Mozilla Public
2
+ // License, v. 2.0. If a copy of the MPL was not distributed with this
3
+ // file, You can obtain one at https://mozilla.org/MPL/2.0/.
4
+ import path from "node:path";
5
+ import { deriveInstallations } from "../indexer/installations.js";
6
+ import { resolveSourceEntries } from "../indexer/search/search-source.js";
7
+ import { displayRef } from "./asset/resolve-ref.js";
8
+ import { UsageError } from "./errors.js";
9
+ import { prepareWriteTargetForMutation, resolveWorkingStashTarget, resolveWriteTarget, } from "./write-source.js";
10
+ function canonicalSources(config) {
11
+ const sources = resolveSourceEntries(undefined, config);
12
+ const installations = deriveInstallations(sources);
13
+ return sources.flatMap((source, index) => {
14
+ const bundleId = installations[index]?.id;
15
+ return bundleId ? [{ bundleId, source }] : [];
16
+ });
17
+ }
18
+ function targetForCanonicalSource(config, canonical, options) {
19
+ const target = canonical.source.registryId
20
+ ? resolveWriteTarget(config, canonical.source.registryId, options)
21
+ : resolveWorkingStashTarget(config, options);
22
+ if (path.resolve(target.source.path) !== path.resolve(canonical.source.path)) {
23
+ throw new UsageError(`Bundle "${canonical.bundleId}" no longer resolves to its indexed source root.`);
24
+ }
25
+ return target;
26
+ }
27
+ /** Resolve the canonical bundle id currently assigned to a write target. */
28
+ export function canonicalBundleIdForTarget(config, target) {
29
+ return (canonicalSources(config).find((candidate) => path.resolve(candidate.source.path) === path.resolve(target.source.path))?.bundleId ?? target.source.name);
30
+ }
31
+ /** Resolve a canonical bundle qualifier to its writable target without preparing a Git boundary. */
32
+ export function resolveBundleWriteTarget(config, bundleId, options = {}) {
33
+ const canonical = canonicalSources(config).find((candidate) => candidate.bundleId === bundleId);
34
+ if (!canonical) {
35
+ throw new UsageError(`Bundle "${bundleId}" is not configured.`, "INVALID_FLAG_VALUE");
36
+ }
37
+ const target = targetForCanonicalSource(config, canonical, options);
38
+ return { ...target, source: { ...target.source, name: canonical.bundleId } };
39
+ }
40
+ function resolveExplicitMutationTarget(config, explicitTarget, options) {
41
+ try {
42
+ return resolveWriteTarget(config, explicitTarget, options);
43
+ }
44
+ catch (error) {
45
+ try {
46
+ return resolveBundleWriteTarget(config, explicitTarget, options);
47
+ }
48
+ catch {
49
+ throw error;
50
+ }
51
+ }
52
+ }
53
+ /** Reconcile a qualified mutation ref with `--target`, then resolve the write destination. */
54
+ export function resolveMutationTarget(config, ref, explicitTarget, options = {}) {
55
+ const writeOptions = { requireWritable: options.requireWritable };
56
+ const qualifiedTarget = ref.origin ? resolveBundleWriteTarget(config, ref.origin, writeOptions) : undefined;
57
+ const explicitResolved = explicitTarget
58
+ ? resolveExplicitMutationTarget(config, explicitTarget, writeOptions)
59
+ : undefined;
60
+ if (qualifiedTarget &&
61
+ explicitResolved &&
62
+ path.resolve(qualifiedTarget.source.path) !== path.resolve(explicitResolved.source.path)) {
63
+ throw new UsageError(`Qualified ref bundle "${ref.origin}" conflicts with --target "${explicitTarget}".`, "INVALID_FLAG_VALUE", `Drop --target or select the same bundle.`);
64
+ }
65
+ let target = qualifiedTarget ?? explicitResolved ?? resolveWriteTarget(config, undefined, writeOptions);
66
+ const bundleId = ref.origin ?? canonicalBundleIdForTarget(config, target);
67
+ target = prepareWriteTargetForMutation({ ...target, source: { ...target.source, name: bundleId } }, { allowedAdapters: options.allowedAdapters });
68
+ const stableRef = { ...ref, origin: bundleId };
69
+ const defaultBundle = defaultBundleForTarget(config);
70
+ return {
71
+ target,
72
+ ref: stableRef,
73
+ displayRef: displayRef({ type: stableRef.type, name: stableRef.name, bundleId: stableRef.origin }, defaultBundle),
74
+ };
75
+ }
76
+ export function defaultBundleForTarget(config) {
77
+ return config.defaultBundle;
78
+ }