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
@@ -8,23 +8,24 @@
8
8
  import * as p from "../../cli/clack.js";
9
9
  import { detectAgentCliProfiles, pickDefaultAgentProfile } from "../../integrations/agent/index.js";
10
10
  import { detectAgentPlatforms } from "../detect.js";
11
- import { getCurrentAgentBlock } from "../legacy-config.js";
11
+ import { readAgentEngineSelection } from "../engine-config.js";
12
12
  import { prompt } from "../prompt.js";
13
+ // The just-computed source list is threaded through the private setup draft.
13
14
  export async function stepAgentPlatforms(current) {
14
15
  const platforms = detectAgentPlatforms();
15
16
  if (platforms.length === 0) {
16
17
  p.log.info("No agent platform configurations detected.");
17
18
  return [];
18
19
  }
19
- const existingPaths = new Set((current.sources ?? []).map((s) => s.path));
20
+ const existingPaths = new Set((current.additionalSources ?? []).map((s) => s.path));
20
21
  // Filter out platforms already configured
21
22
  const newPlatforms = platforms.filter((pl) => !existingPaths.has(pl.path));
22
23
  if (newPlatforms.length === 0) {
23
- p.log.info(`Detected ${platforms.length} agent platform(s), all already configured as stash sources.`);
24
+ p.log.info(`Detected ${platforms.length} agent platform(s), all already configured as bundle sources.`);
24
25
  return [];
25
26
  }
26
27
  const selected = await prompt(() => p.multiselect({
27
- message: "Found agent platform configurations. Add as stash sources?",
28
+ message: "Found agent platform configurations. Add as bundle sources?",
28
29
  options: newPlatforms.map((pl) => ({
29
30
  value: pl.path,
30
31
  label: pl.name,
@@ -50,23 +51,23 @@ export async function stepAgentPlatforms(current) {
50
51
  */
51
52
  export function printCapabilitySummary(smallModelSkipped, agentConfigured) {
52
53
  const lines = ["Setup complete. Here's what's enabled:", ""];
53
- lines.push(" ✓ akm search, akm curate, akm show — always available");
54
+ lines.push(" ✓ akm search, akm curate, akm show, akm index, akm remember — always available");
54
55
  if (!smallModelSkipped) {
55
- lines.push(" ✓ akm index, akm distill, akm remember — small model configured");
56
+ lines.push(" ✓ index metadata enhancement, akm improve, akm remember --enrich — small model configured");
56
57
  }
57
58
  else {
58
- lines.push(" ✗ akm index, akm distill, akm remember — run `akm setup` to enable");
59
+ lines.push(" ✗ index metadata enhancement, akm improve, akm remember --enrich — run `akm setup` to enable");
59
60
  }
60
61
  if (agentConfigured) {
61
- lines.push(" ✓ akm propose, akm improve, akm tasks — agent configured");
62
+ lines.push(" ✓ akm proposal new, akm improve, akm task — agent configured");
62
63
  }
63
64
  else {
64
- lines.push(" ✗ akm propose, akm improve, akm tasks — run `akm setup` to enable");
65
+ lines.push(" ✗ akm proposal new, akm improve, akm task — run `akm setup` to enable");
65
66
  }
66
67
  p.note(lines.join("\n"), "Feature Summary");
67
68
  }
68
69
  export async function stepAgentSelection(current, detections) {
69
- const currentAgentBlock = getCurrentAgentBlock(current);
70
+ const currentAgentBlock = readAgentEngineSelection(current);
70
71
  const available = detections.filter((d) => d.available);
71
72
  if (available.length === 0) {
72
73
  return currentAgentBlock;
@@ -85,7 +86,7 @@ export async function stepAgentSelection(current, detections) {
85
86
  initialValue,
86
87
  }));
87
88
  if (selectedDefault === "disabled") {
88
- if (!currentAgentBlock?.profiles && !currentAgentBlock?.timeoutMs) {
89
+ if (!currentAgentBlock?.engines) {
89
90
  return undefined;
90
91
  }
91
92
  return {
@@ -110,7 +111,7 @@ export async function stepAgentSelection(current, detections) {
110
111
  */
111
112
  export function stepAgentCliDetection(current, detectFn = detectAgentCliProfiles) {
112
113
  const detections = detectFn(current);
113
- const currentAgentBlock = getCurrentAgentBlock(current);
114
+ const currentAgentBlock = readAgentEngineSelection(current);
114
115
  const defaultName = pickDefaultAgentProfile(detections, currentAgentBlock?.default);
115
116
  // No installed agents found and no existing config → leave block absent.
116
117
  if (!defaultName && !currentAgentBlock) {
@@ -8,15 +8,27 @@
8
8
  import * as p from "../../cli/clack.js";
9
9
  import { prompt } from "../prompt.js";
10
10
  import { describeSemanticSearchAssets, isRemoteEmbeddingConfig } from "../semantic-assets.js";
11
- export async function stepSemanticSearch(current, embedding) {
11
+ export async function stepSemanticSearch(
12
+ // Owner ruling 9 (R-039): the runtime default is "off" (a bare/headless
13
+ // install must never silently pull the ~130 MB model), but the interactive
14
+ // wizard pre-selects semantic search ON — a human is present to read the
15
+ // warning below and decide. `_current` is intentionally unused for the
16
+ // enable/disable pre-selection below: it must NOT track
17
+ // `semanticSearchMode`, or this pre-selection would silently flip to off
18
+ // along with the runtime default. Kept in the signature for call-site
19
+ // stability (callers pass the in-progress setup config positionally).
20
+ _current, embedding) {
21
+ // Show the warning (asset sizes; "no local model download" when a remote
22
+ // embedding endpoint is configured) BEFORE the prompt so the pre-checked
23
+ // default is an informed choice, not a surprise.
24
+ p.note(describeSemanticSearchAssets(embedding).join("\n"), "Semantic Search Assets");
12
25
  const enabled = await prompt(() => p.confirm({
13
26
  message: "Enable semantic search?",
14
- initialValue: current.semanticSearchMode !== "off",
27
+ initialValue: true,
15
28
  }));
16
29
  if (!enabled) {
17
30
  return { mode: "off", prepareAssets: false };
18
31
  }
19
- p.note(describeSemanticSearchAssets(embedding).join("\n"), "Semantic Search Assets");
20
32
  const prepareAssets = await prompt(() => p.confirm({
21
33
  message: isRemoteEmbeddingConfig(embedding)
22
34
  ? "Check the embedding endpoint and verify semantic search now?"
@@ -7,7 +7,8 @@
7
7
  * built-in registries.
8
8
  */
9
9
  import * as p from "../../cli/clack.js";
10
- import { DEFAULT_CONFIG, getEffectiveRegistries } from "../../core/config/config.js";
10
+ import { DEFAULT_CONFIG, getEffectiveRegistries, getSources } from "../../core/config/config.js";
11
+ import { readLockfile } from "../../integrations/lockfile.js";
11
12
  import { prompt, promptOrBack } from "../prompt.js";
12
13
  import { loadSetupStashes } from "../registry-stash-loader.js";
13
14
  function configuredSourceKey(source) {
@@ -30,15 +31,15 @@ function renderConfiguredSourceList(sources) {
30
31
  })
31
32
  .join("\n");
32
33
  }
33
- function renderInstalledSourceList(installed) {
34
- return installed.map((entry) => `- ${entry.id} (${entry.source})`).join("\n");
34
+ function renderInstalledSourceList(managed) {
35
+ return managed.map((entry) => `- ${entry.name ?? entry.url ?? entry.path ?? "unknown"} (${entry.type})`).join("\n");
35
36
  }
36
37
  export async function stepAdditionalSources(currentSources) {
37
38
  const sources = [...currentSources];
38
39
  let addMore = true;
39
40
  while (addMore) {
40
41
  const action = await prompt(() => p.select({
41
- message: "Add another stash source?",
42
+ message: "Add another bundle source?",
42
43
  options: [
43
44
  { value: "done", label: "Done — no more sources" },
44
45
  { value: "github-repo", label: "GitHub repository", hint: "custom URL" },
@@ -62,7 +63,7 @@ export async function stepAdditionalSources(currentSources) {
62
63
  if (url === null)
63
64
  continue;
64
65
  const name = await promptOrBack(() => p.text({
65
- message: "Give this stash a name (optional):",
66
+ message: "Give this bundle a name (optional):",
66
67
  placeholder: "my-repo",
67
68
  }));
68
69
  if (name === null)
@@ -80,7 +81,7 @@ export async function stepAdditionalSources(currentSources) {
80
81
  if (action === "filesystem") {
81
82
  const fsPath = await promptOrBack(() => p.text({
82
83
  message: "Enter the directory path:",
83
- placeholder: "/path/to/stash",
84
+ placeholder: "/path/to/bundle",
84
85
  validate: (v) => {
85
86
  if (!v?.trim())
86
87
  return "Path cannot be empty";
@@ -90,8 +91,8 @@ export async function stepAdditionalSources(currentSources) {
90
91
  continue;
91
92
  const resolved = fsPath.trim();
92
93
  const name = await promptOrBack(() => p.text({
93
- message: "Give this stash a name (optional):",
94
- placeholder: "my-stash",
94
+ message: "Give this bundle a name (optional):",
95
+ placeholder: "my-bundle",
95
96
  }));
96
97
  if (name === null)
97
98
  continue;
@@ -150,13 +151,18 @@ export async function stepRegistries(current) {
150
151
  * @internal Exported for testing only.
151
152
  */
152
153
  export async function stepAddSources(current, options) {
153
- const existingSources = [...(current.sources ?? [])];
154
+ // The wizard toggles plain additional bundles, not the default bundle or
155
+ // lock-backed registry installs, which are preserved untouched.
156
+ const lockIds = new Set(readLockfile().map((entry) => entry.id));
157
+ const allSources = getSources(current);
158
+ const existingSources = allSources.filter((source) => !source.primary && !(source.name && lockIds.has(source.name)));
159
+ const managedSources = allSources.filter((source) => source.name != null && lockIds.has(source.name));
154
160
  const sources = [];
155
161
  if (existingSources.length > 0) {
156
- p.note(renderConfiguredSourceList(existingSources), "Configured stash sources");
162
+ p.note(renderConfiguredSourceList(existingSources), "Configured bundle sources");
157
163
  const options = existingSources.map(describeConfiguredSource);
158
164
  const selected = await prompt(() => p.multiselect({
159
- message: "Configured stash sources — uncheck any you want to disable:",
165
+ message: "Configured bundle sources — uncheck any you want to disable:",
160
166
  options,
161
167
  initialValues: options.map((option) => option.value),
162
168
  required: false,
@@ -167,8 +173,8 @@ export async function stepAddSources(current, options) {
167
173
  }
168
174
  }
169
175
  }
170
- if ((current.installed?.length ?? 0) > 0) {
171
- p.note(renderInstalledSourceList(current.installed ?? []), "Installed managed stashes (preserved)");
176
+ if (managedSources.length > 0) {
177
+ p.note(renderInstalledSourceList(managedSources), "Installed managed bundles (preserved)");
172
178
  }
173
179
  // ── Registry-driven stash recommendations ─────────────────────────────
174
180
  // Fetch available stashes from the official registry (cached, stale-ok).
@@ -189,8 +195,8 @@ export async function stepAddSources(current, options) {
189
195
  : availableStashes.filter((s) => s.defaultSelected).map((s) => s.url);
190
196
  const selectedUrls = await prompt(() => p.multiselect({
191
197
  message: availableStashes[0]?.source === "registry"
192
- ? "Available stashes from the AKM registry — toggle to add or remove:"
193
- : "Recommended stash sources — toggle to add or remove:",
198
+ ? "Available bundles from the AKM registry — toggle to add or remove:"
199
+ : "Recommended bundle sources — toggle to add or remove:",
194
200
  options: stashOptions,
195
201
  initialValues,
196
202
  required: false,
@@ -6,24 +6,26 @@
6
6
  * and other assets).
7
7
  */
8
8
  import * as p from "../../cli/clack.js";
9
+ import { primaryBundlePath } from "../../core/config/config.js";
9
10
  import { assertSafeStashDir, getDefaultStashDir } from "../../core/paths.js";
10
11
  import { prompt } from "../prompt.js";
11
12
  export async function stepStashDir(current, options) {
12
- const defaultDir = options?.preferredDir ?? current.stashDir ?? getDefaultStashDir();
13
+ const currentPrimary = primaryBundlePath(current);
14
+ const defaultDir = options?.preferredDir ?? currentPrimary ?? getDefaultStashDir();
13
15
  if (options?.nonInteractive) {
14
16
  return defaultDir;
15
17
  }
16
18
  const choice = await prompt(() => p.select({
17
19
  message: "Where should akm store skills, commands, and other assets?",
18
20
  options: [
19
- { value: "default", label: defaultDir, hint: current.stashDir ? "current" : "default" },
21
+ { value: "default", label: defaultDir, hint: currentPrimary ? "current" : "default" },
20
22
  { value: "custom", label: "Enter a custom path..." },
21
23
  ],
22
24
  }));
23
25
  if (choice === "default")
24
26
  return defaultDir;
25
27
  const customPath = await prompt(() => p.text({
26
- message: "Enter the stash directory path:",
28
+ message: "Enter the bundle directory path:",
27
29
  placeholder: defaultDir,
28
30
  validate: (v) => {
29
31
  if (!v?.trim())
@@ -34,7 +36,7 @@ export async function stepStashDir(current, options) {
34
36
  catch (err) {
35
37
  if (err instanceof Error)
36
38
  return err.message;
37
- return "Refused: unsafe stash directory";
39
+ return "Refused: unsafe bundle directory";
38
40
  }
39
41
  },
40
42
  }));
@@ -1,152 +1,269 @@
1
1
  // This Source Code Form is subject to the terms of the Mozilla Public
2
2
  // License, v. 2.0. If a copy of the MPL was not distributed with this
3
3
  // file, You can obtain one at https://mozilla.org/MPL/2.0/.
4
- /**
5
- * Setup wizard steps: register the default improve task set and enable/disable
6
- * scheduled core tasks.
7
- */
4
+ /** Setup wizard step for reviewing task definitions and activating schedules. */
5
+ import fs from "node:fs";
6
+ import os from "node:os";
7
+ import path from "node:path";
8
+ import { parse as yamlParse, stringify as yamlStringify } from "yaml";
8
9
  import * as p from "../../cli/clack.js";
9
- import { detectServerDefault, isCiEnvironment, registerDefaultTasks } from "../../commands/tasks/default-tasks.js";
10
- import { akmTasksAdd, akmTasksList, akmTasksSetEnabled, akmTasksSync } from "../../commands/tasks/tasks.js";
11
- import { saveGitStash } from "../../sources/providers/git.js";
10
+ import { akmTasksSync, setEnabledInYaml } from "../../commands/tasks/tasks.js";
11
+ import { loadConfig } from "../../core/config/config.js";
12
+ import { UsageError } from "../../core/errors.js";
13
+ import { commitWriteTargetBoundary, deleteAssetFromSource, prepareWriteTargetForMutation, resolveWriteTarget, writeAssetToSource, } from "../../core/write-source.js";
12
14
  import { backendNameForPlatform } from "../../tasks/backends/index.js";
13
15
  import { listEmbeddedTasks } from "../../tasks/embedded.js";
16
+ import { parseTaskDocument } from "../../tasks/parser.js";
14
17
  import { parseSchedule } from "../../tasks/schedule.js";
15
18
  import { prompt } from "../prompt.js";
16
19
  /**
17
- * Normalise a task id the same way `akm tasks` does (strip a trailing `.yml`
18
- * / `.md` suffix, trim) so the wizard can match embedded template ids against
19
- * the ids reported by `akmTasksList()`.
20
+ * A scheduled server-only nightly full sweep exists among the embedded
21
+ * improve-schedule templates (folded in from the retired
22
+ * `registerDefaultTasks`/`akm tasks init` path in 0.9, S6). This id is
23
+ * preselected in the review multiselect on a detected server install — the
24
+ * "battery heuristic" {@link detectServerDefault} preserved from that path.
20
25
  */
21
- function normaliseTaskIdForMatch(raw) {
22
- return raw.trim().replace(/\.(yml|md)$/, "");
26
+ const SERVER_SUGGESTED_TASK_ID = "akm-improve-nightly";
27
+ let scheduledTasksEnvOverrides;
28
+ /** TEST-ONLY. Swap the CI/server-detection probes; pass undefined to restore. */
29
+ export function _setScheduledTasksEnvForTests(fakes) {
30
+ scheduledTasksEnvOverrides = fakes;
23
31
  }
24
32
  /**
25
- * Setup sub-step (issue #552): idempotently register the default improve task
26
- * set. Asks a single "Is this a server install?" question (defaulting per
27
- * platform) to decide whether the nightly sweep is enabled, then delegates to
28
- * {@link registerDefaultTasks}, which is CI-aware and never duplicates an
29
- * existing task. Skipped entirely under CI (the registration helper short-
30
- * circuits, and we never even prompt).
31
- *
32
- * Exported for testing.
33
+ * Decide whether `akm setup` is running in a CI environment, where it must
34
+ * register NO scheduled tasks. Mirrors the common `CI=true` convention used by
35
+ * GitHub Actions, GitLab CI, CircleCI, etc.
33
36
  */
34
- export async function stepDefaultImproveTasks(register = registerDefaultTasks) {
35
- // CI: register nothing and don't prompt.
36
- if (isCiEnvironment()) {
37
- p.log.info("CI detected — skipping default improve task registration.");
38
- return;
37
+ export function isCiEnvironment(env = process.env) {
38
+ if (scheduledTasksEnvOverrides?.isCiEnvironment)
39
+ return scheduledTasksEnvOverrides.isCiEnvironment(env);
40
+ const ci = env.CI;
41
+ if (ci === undefined || ci === null)
42
+ return false;
43
+ const v = String(ci).trim().toLowerCase();
44
+ return v !== "" && v !== "0" && v !== "false";
45
+ }
46
+ /**
47
+ * Platform-appropriate default for "Is this a server install?":
48
+ * - Linux without a battery → `true` (server).
49
+ * - macOS / any host with a battery (laptop) → `false`.
50
+ * Used to preselect {@link SERVER_SUGGESTED_TASK_ID} in the task-review
51
+ * multiselect.
52
+ */
53
+ export function detectServerDefault() {
54
+ if (scheduledTasksEnvOverrides?.detectServerDefault)
55
+ return scheduledTasksEnvOverrides.detectServerDefault();
56
+ if (os.platform() !== "linux")
57
+ return false;
58
+ // A laptop exposes a battery under /sys/class/power_supply/BAT*. Absence of
59
+ // any battery is our heuristic for "server / desktop".
60
+ try {
61
+ const entries = fs.readdirSync("/sys/class/power_supply");
62
+ const hasBattery = entries.some((e) => /^BAT/i.test(e));
63
+ return !hasBattery;
64
+ }
65
+ catch {
66
+ // If we cannot read power-supply info, prefer the safe server default on
67
+ // Linux (the nightly sweep is low-impact and re-runnable).
68
+ return true;
39
69
  }
40
- const platformDefault = detectServerDefault();
41
- const serverInstall = await prompt(() => p.confirm({
42
- message: "Is this a server install? (enables the nightly quality sweep at 2am)",
43
- initialValue: platformDefault,
44
- }));
45
- const result = await register({ serverInstall: serverInstall === true });
46
- if (result.skipped)
47
- return;
48
- const total = result.created.length + result.existing.length;
49
- p.log.success(`Default improve tasks registered (${result.created.length} new, ${result.existing.length} already present, ${total} total).`);
70
+ }
71
+ function normaliseTaskIdForMatch(raw) {
72
+ return raw.trim().replace(/\.(yml|md)$/, "");
73
+ }
74
+ export function listSetupTaskDefinitions() {
75
+ const config = loadConfig();
76
+ const target = resolveWriteTarget(config, config.defaultBundle, { requireWritable: false });
77
+ const taskDir = path.join(target.source.path, "tasks");
78
+ if (!fs.existsSync(taskDir))
79
+ return [];
80
+ const tasks = [];
81
+ for (const file of fs.readdirSync(taskDir)) {
82
+ if (!file.endsWith(".yml"))
83
+ continue;
84
+ const id = file.slice(0, -4);
85
+ const filePath = path.join(taskDir, file);
86
+ try {
87
+ const task = parseTaskDocument({ yaml: fs.readFileSync(filePath, "utf8"), filePath, id });
88
+ tasks.push({ id: task.id, schedule: task.schedule, enabled: task.enabled, description: task.description });
89
+ }
90
+ catch (error) {
91
+ throw new UsageError(`Cannot review task definition ${filePath}: ${error instanceof Error ? error.message : String(error)} ` +
92
+ "Fix or remove the invalid task, then rerun `akm setup`. No task files or scheduler state were changed.", "INVALID_FLAG_VALUE", "Fix or remove the invalid task definition, then rerun `akm setup`.");
93
+ }
94
+ }
95
+ return tasks.sort((a, b) => a.id.localeCompare(b.id));
96
+ }
97
+ export async function prepareSetupTaskDefinitions(tasks, deps = {}) {
98
+ const config = loadConfig();
99
+ const target = prepareWriteTargetForMutation(resolveWriteTarget(config, config.defaultBundle, { requireWritable: true }));
100
+ const taskDir = path.join(target.source.path, "tasks");
101
+ const writeAsset = deps.writeAsset ?? writeAssetToSource;
102
+ const deleteAsset = deps.deleteAsset ?? deleteAssetFromSource;
103
+ const commitBoundary = deps.commitBoundary ?? commitWriteTargetBoundary;
104
+ const prepared = tasks.map((plan) => {
105
+ const filePath = path.join(taskDir, `${plan.task.id}.yml`);
106
+ const original = fs.existsSync(filePath) ? fs.readFileSync(filePath, "utf8") : undefined;
107
+ let yaml;
108
+ if (original !== undefined) {
109
+ yaml = setEnabledInYaml(original, plan.enabled);
110
+ }
111
+ else {
112
+ const document = yamlParse(plan.task.yaml);
113
+ document.schedule = plan.schedule;
114
+ document.enabled = plan.enabled;
115
+ yaml = yamlStringify(document);
116
+ }
117
+ parseTaskDocument({ yaml, filePath, id: plan.task.id });
118
+ parseSchedule(plan.schedule, backendNameForPlatform());
119
+ return { filePath, original, yaml, ref: { type: "task", name: plan.task.id } };
120
+ });
121
+ const changed = prepared.filter((entry) => entry.original !== entry.yaml);
122
+ if (changed.length === 0)
123
+ return 0;
124
+ const attempted = [];
125
+ try {
126
+ for (const entry of changed) {
127
+ attempted.push(entry);
128
+ await writeAsset(target.source, target.config, entry.ref, entry.yaml);
129
+ }
130
+ commitBoundary(target, "Prepare scheduled tasks");
131
+ }
132
+ catch (error) {
133
+ const rollbackErrors = [];
134
+ for (const entry of [...attempted].reverse()) {
135
+ try {
136
+ if (entry.original === undefined) {
137
+ if (fs.existsSync(entry.filePath))
138
+ await deleteAsset(target.source, target.config, entry.ref);
139
+ }
140
+ else {
141
+ await writeAsset(target.source, target.config, entry.ref, entry.original);
142
+ fs.writeFileSync(entry.filePath, entry.original, "utf8");
143
+ }
144
+ }
145
+ catch (rollbackError) {
146
+ rollbackErrors.push(rollbackError);
147
+ }
148
+ }
149
+ try {
150
+ commitBoundary(target, "Restore scheduled tasks after failed setup");
151
+ }
152
+ catch (rollbackError) {
153
+ rollbackErrors.push(rollbackError);
154
+ }
155
+ if (rollbackErrors.length > 0) {
156
+ throw new AggregateError([error, ...rollbackErrors], `Task definition preparation failed and rollback was incomplete: ${error instanceof Error ? error.message : String(error)}`);
157
+ }
158
+ throw error;
159
+ }
160
+ return changed.length;
50
161
  }
51
162
  const DEFAULT_SCHEDULED_TASKS_DEPS = {
52
- list: akmTasksList,
53
- add: akmTasksAdd,
54
- setEnabled: akmTasksSetEnabled,
163
+ list: listSetupTaskDefinitions,
164
+ prepare: prepareSetupTaskDefinitions,
55
165
  sync: akmTasksSync,
56
- gitSync: saveGitStash,
57
166
  };
58
- export async function stepScheduledTasks(deps = DEFAULT_SCHEDULED_TASKS_DEPS) {
167
+ export async function stepScheduledTasks(deps = DEFAULT_SCHEDULED_TASKS_DEPS, options = {}) {
168
+ if (options.nonInteractive || isCiEnvironment()) {
169
+ p.log.info("Non-interactive setup leaves task files and scheduler state unchanged. Run `akm setup` interactively to review tasks.");
170
+ return;
171
+ }
172
+ // ALL templates are offered, including ships-disabled ones (e.g. the
173
+ // manual-recovery catchup task): an unselected template is still PREPARED
174
+ // with `enabled: false`, so its YAML exists for `akm task run <id>` while
175
+ // nothing lands in the scheduler uncommented. Filtering on `task.enabled`
176
+ // here would make ships-disabled templates invisible and unpreparable.
59
177
  const embedded = listEmbeddedTasks();
60
178
  if (embedded.length === 0)
61
179
  return;
62
- // Snapshot current state so we can diff against the user's selection.
63
- let installed = [];
64
- try {
65
- installed = (await deps.list()).tasks;
66
- }
67
- catch {
68
- // A missing/empty tasks dir is fine — treat as nothing installed.
69
- installed = [];
70
- }
180
+ const installed = await deps.list();
71
181
  const byId = new Map();
72
- for (const t of installed)
73
- byId.set(normaliseTaskIdForMatch(t.id), t);
74
- // Pre-check tasks that are installed AND enabled.
75
- const preChecked = embedded.filter((e) => byId.get(e.id)?.enabled === true).map((e) => e.id);
76
- const stateLabel = (e) => {
77
- const cur = byId.get(e.id);
78
- if (!cur)
79
- return "not installed";
80
- return cur.enabled ? "enabled" : "disabled";
81
- };
182
+ for (const task of installed)
183
+ byId.set(normaliseTaskIdForMatch(task.id), task);
184
+ const preChecked = embedded.filter((task) => byId.get(task.id)?.enabled === true).map((task) => task.id);
185
+ // Battery heuristic preserved from the retired `registerDefaultTasks` path
186
+ // (S6): suggest the nightly full sweep on a detected server install, same
187
+ // as every other embedded template, still gated behind the confirmation
188
+ // below.
189
+ if (!byId.has(SERVER_SUGGESTED_TASK_ID) &&
190
+ !preChecked.includes(SERVER_SUGGESTED_TASK_ID) &&
191
+ embedded.some((task) => task.id === SERVER_SUGGESTED_TASK_ID) &&
192
+ detectServerDefault()) {
193
+ preChecked.push(SERVER_SUGGESTED_TASK_ID);
194
+ }
82
195
  const selected = await prompt(() => p.multiselect({
83
- message: "Enable scheduled core tasks? (space to toggle, enter to confirm)",
196
+ message: "Which task definitions should be enabled? (scheduler activation is confirmed separately)",
84
197
  required: false,
85
198
  initialValues: preChecked,
86
- options: embedded.map((e) => ({
87
- value: e.id,
88
- label: e.label,
89
- hint: `${e.description} — ${e.schedule} [${stateLabel(e)}]`,
90
- })),
199
+ options: embedded.map((task) => {
200
+ const current = byId.get(task.id);
201
+ const schedule = current?.schedule ?? task.schedule;
202
+ const state = current ? (current.enabled ? "enabled" : "disabled") : "not prepared";
203
+ return {
204
+ value: task.id,
205
+ label: task.label,
206
+ hint: `${task.description} - ${schedule} [${state}]`,
207
+ };
208
+ }),
91
209
  }));
92
210
  const selectedSet = new Set(selected);
93
- // Resolve per-task schedule edits for newly-checked, not-yet-installed tasks.
94
211
  const scheduleFor = new Map();
95
- for (const e of embedded) {
96
- const cur = byId.get(e.id);
97
- if (selectedSet.has(e.id) && !cur) {
98
- const edited = await prompt(() => p.text({
99
- message: `Schedule for ${e.label}?`,
100
- initialValue: e.schedule,
101
- validate(value) {
102
- const candidate = (value ?? "").trim() || e.schedule;
103
- try {
104
- parseSchedule(candidate, backendNameForPlatform());
105
- }
106
- catch (err) {
107
- return err instanceof Error ? err.message : "Invalid schedule.";
108
- }
109
- return undefined;
110
- },
111
- }));
112
- const sched = (edited ?? "").trim() || e.schedule;
113
- scheduleFor.set(e.id, sched);
114
- }
212
+ for (const task of embedded) {
213
+ if (!selectedSet.has(task.id) || byId.has(task.id))
214
+ continue;
215
+ const edited = await prompt(() => p.text({
216
+ message: `Schedule for ${task.label}?`,
217
+ initialValue: task.schedule,
218
+ validate(value) {
219
+ const candidate = (value ?? "").trim() || task.schedule;
220
+ try {
221
+ parseSchedule(candidate, backendNameForPlatform());
222
+ }
223
+ catch (error) {
224
+ return error instanceof Error ? error.message : "Invalid schedule.";
225
+ }
226
+ return undefined;
227
+ },
228
+ }));
229
+ scheduleFor.set(task.id, (edited ?? "").trim() || task.schedule);
115
230
  }
116
- let syncNeeded = false;
117
- for (const e of embedded) {
118
- const cur = byId.get(e.id);
119
- const checked = selectedSet.has(e.id);
120
- if (checked && !cur) {
121
- // New task: copy template into the primary stash + install scheduler entry.
122
- const schedule = scheduleFor.get(e.id) ?? e.schedule;
123
- await deps.add({
124
- id: e.id,
125
- schedule,
126
- command: e.command,
127
- description: e.description,
128
- });
129
- syncNeeded = true;
130
- }
131
- else if (checked && cur && !cur.enabled) {
132
- // Present but disabled → re-enable.
133
- await deps.setEnabled(e.id, true);
134
- }
135
- else if (!checked && cur?.enabled) {
136
- // Previously enabled, now unchecked → disable (keep the stash file).
137
- await deps.setEnabled(e.id, false);
138
- }
139
- // No state change → no action.
231
+ const plans = embedded.map((task) => {
232
+ const current = byId.get(task.id);
233
+ return {
234
+ task,
235
+ schedule: current?.schedule ?? scheduleFor.get(task.id) ?? task.schedule,
236
+ enabled: selectedSet.has(task.id),
237
+ installed: current !== undefined,
238
+ };
239
+ });
240
+ const embeddedIds = new Set(embedded.map((task) => task.id));
241
+ const custom = installed.filter((task) => !embeddedIds.has(normaliseTaskIdForMatch(task.id)));
242
+ p.note([
243
+ ...plans.map((plan) => `${plan.task.label}: ${plan.enabled ? "enabled" : "disabled"} | ${plan.schedule} | ${plan.task.description}`),
244
+ ...custom.map((task) => `${task.id}: ${task.enabled ? "enabled" : "disabled"} | ${task.schedule}${task.description ? ` | ${task.description}` : ""}`),
245
+ ].join("\n"), "Task Schedule Review");
246
+ const activate = await prompt(() => p.confirm({
247
+ message: `Activate these schedules now? This will update task files and sync them to the ${backendNameForPlatform()} scheduler.`,
248
+ initialValue: false,
249
+ }));
250
+ if (!activate) {
251
+ p.log.info("Task definitions and scheduler state were not changed.");
252
+ return;
140
253
  }
141
- if (syncNeeded) {
142
- // Reconcile scheduler entries with on-disk YAML, then commit the new file
143
- // to git (a no-op for non-git stashes).
144
- await deps.sync();
145
- try {
146
- deps.gitSync(undefined, "akm setup: enable scheduled tasks");
147
- }
148
- catch {
149
- // Non-fatal — the task is installed regardless of git sync outcome.
254
+ const changed = await deps.prepare(plans);
255
+ if (changed > 0)
256
+ p.log.success(`Prepared ${changed} task definition${changed === 1 ? "" : "s"}.`);
257
+ const syncResult = await deps.sync();
258
+ if (syncResult.skipped.length > 0) {
259
+ for (const skipped of syncResult.skipped) {
260
+ p.log.warn(`Task "${skipped.id}" was not activated: ${skipped.reason}`);
150
261
  }
262
+ const activeCount = syncResult.installed.length + syncResult.updated.length + syncResult.unchanged.length;
263
+ p.log.warn(`${activeCount === 0 ? "No task schedules were activated." : "Task schedule activation was incomplete."} ` +
264
+ "If you are running AKM from source, run the installed `akm setup`. " +
265
+ "To migrate or repair existing scheduler bindings explicitly, run `akm task sync --rebind`.");
266
+ return;
151
267
  }
268
+ p.log.success("Task schedules activated. Verify them with `akm task doctor`.");
152
269
  }