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

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (587) hide show
  1. package/CHANGELOG.md +1190 -52
  2. package/README.md +62 -37
  3. package/SECURITY.md +46 -31
  4. package/dist/akm +162 -38
  5. package/dist/akm-migrate +44 -0
  6. package/dist/assets/backends/schtasks-template.xml +2 -1
  7. package/dist/assets/hints/cli-hints-full.md +268 -118
  8. package/dist/assets/hints/cli-hints-short.md +87 -24
  9. package/dist/assets/{profiles → improve-strategies}/catchup.json +3 -1
  10. package/dist/assets/{profiles → improve-strategies}/consolidate.json +3 -1
  11. package/dist/assets/{profiles → improve-strategies}/default.json +6 -7
  12. package/dist/assets/improve-strategies/frequent.json +15 -0
  13. package/dist/assets/{profiles → improve-strategies}/graph-refresh.json +4 -2
  14. package/dist/assets/{profiles → improve-strategies}/memory-focus.json +4 -1
  15. package/dist/assets/{profiles → improve-strategies}/proactive-maintenance.json +5 -5
  16. package/dist/assets/{profiles → improve-strategies}/quick.json +4 -2
  17. package/dist/assets/improve-strategies/reflect-distill.json +30 -0
  18. package/dist/assets/{profiles → improve-strategies}/thorough.json +1 -1
  19. package/dist/assets/prompts/consolidate-system.md +5 -5
  20. package/dist/assets/prompts/extract-session.md +2 -6
  21. package/dist/assets/prompts/memory-infer-user.md +2 -3
  22. package/dist/assets/prompts/reflect-llm-framed-contract.md +11 -0
  23. package/dist/assets/prompts/reflect-llm-schema-contract.md +3 -0
  24. package/dist/assets/prompts/reflect-output-repair.md +3 -0
  25. package/dist/assets/stash-skeleton/README.md +38 -10
  26. package/dist/assets/stash-skeleton/facts/conventions/assets/agent.md +8 -0
  27. package/dist/assets/stash-skeleton/facts/conventions/assets/command.md +8 -0
  28. package/dist/assets/stash-skeleton/facts/conventions/assets/fact.md +14 -1
  29. package/dist/assets/stash-skeleton/facts/conventions/assets/knowledge.md +13 -1
  30. package/dist/assets/stash-skeleton/facts/conventions/assets/lesson.md +9 -1
  31. package/dist/assets/stash-skeleton/facts/conventions/assets/memory.md +11 -0
  32. package/dist/assets/stash-skeleton/facts/conventions/assets/script.md +9 -0
  33. package/dist/assets/stash-skeleton/facts/conventions/assets/skill.md +9 -0
  34. package/dist/assets/stash-skeleton/facts/conventions/assets/workflow.md +8 -0
  35. package/dist/assets/stash-skeleton/facts/conventions/backlinks.md +100 -0
  36. package/dist/assets/stash-skeleton/facts/conventions/domains.md +64 -0
  37. package/dist/assets/stash-skeleton/facts/conventions/organization.md +136 -0
  38. package/dist/assets/tasks/core/extract.yml +3 -2
  39. package/dist/assets/tasks/core/improve.yml +2 -1
  40. package/dist/assets/tasks/core/index-refresh.yml +1 -0
  41. package/dist/assets/tasks/core/sync.yml +1 -0
  42. package/dist/assets/tasks/core/version-check.yml +2 -1
  43. package/dist/assets/tasks/improve/akm-graph-refresh-weekly.yml +5 -0
  44. package/dist/assets/tasks/improve/akm-improve-catchup.yml +8 -0
  45. package/dist/assets/tasks/improve/akm-improve-consolidate.yml +5 -0
  46. package/dist/assets/tasks/improve/akm-improve-frequent.yml +5 -0
  47. package/dist/assets/tasks/improve/akm-improve-nightly.yml +5 -0
  48. package/dist/assets/templates/html/health.html +5 -4
  49. package/dist/assets/workflows/workflow-template.md +31 -15
  50. package/dist/cli/invocation.js +279 -0
  51. package/dist/cli/parse-args.js +5 -90
  52. package/dist/cli/retired-commands.js +78 -0
  53. package/dist/cli/shared.js +158 -48
  54. package/dist/cli-node.mjs +2 -1
  55. package/dist/cli.js +747 -293
  56. package/dist/commands/agent/agent-dispatch.js +19 -18
  57. package/dist/commands/agent/agent-support.js +0 -24
  58. package/dist/commands/agent/contribute-cli.js +43 -97
  59. package/dist/commands/completions.js +80 -23
  60. package/dist/commands/config-cli.js +44 -281
  61. package/dist/commands/env/env-binding.js +13 -9
  62. package/dist/commands/env/env-cli.js +76 -159
  63. package/dist/commands/env/env.js +12 -163
  64. package/dist/commands/env/marker-path.js +6 -0
  65. package/dist/commands/env/secret-cli.js +45 -61
  66. package/dist/commands/env/secret.js +32 -62
  67. package/dist/commands/feedback-cli.js +179 -85
  68. package/dist/commands/health/accept-rate.js +58 -0
  69. package/dist/commands/health/advisories.js +7 -8
  70. package/dist/commands/health/checks.js +279 -94
  71. package/dist/commands/health/html-report.js +197 -578
  72. package/dist/commands/health/improve-metrics.js +277 -246
  73. package/dist/commands/health/llm-usage.js +19 -19
  74. package/dist/commands/health/md-report.js +16 -7
  75. package/dist/commands/health/metrics.js +67 -32
  76. package/dist/commands/health/renderers.js +47 -0
  77. package/dist/commands/health/report-view-model.js +508 -0
  78. package/dist/commands/health/stash-exposure.js +1 -1
  79. package/dist/commands/health/surfaces.js +16 -56
  80. package/dist/commands/health/task-runs.js +3 -67
  81. package/dist/{migrate-storage-node.mjs → commands/health/types-checks.js} +1 -5
  82. package/dist/commands/health/types-improve.js +29 -0
  83. package/dist/{output/text/save.js → commands/health/types-metrics.js} +1 -2
  84. package/dist/commands/health/types-result.js +7 -0
  85. package/dist/commands/health/types-runs.js +4 -0
  86. package/dist/commands/health/types-session-log.js +4 -0
  87. package/dist/commands/health/types-windows.js +4 -0
  88. package/dist/commands/health/types.js +26 -21
  89. package/dist/commands/health/windows.js +2 -3
  90. package/dist/commands/health.js +296 -167
  91. package/dist/commands/improve/anti-collapse.js +5 -5
  92. package/dist/commands/improve/autonomy-gate.js +68 -0
  93. package/dist/commands/improve/collapse-detector.js +65 -52
  94. package/dist/commands/improve/consolidate/chunking.js +9 -7
  95. package/dist/commands/improve/consolidate/eligibility.js +1 -23
  96. package/dist/commands/improve/consolidate/merge.js +4 -0
  97. package/dist/commands/improve/consolidate.js +454 -1354
  98. package/dist/commands/improve/content-hash.js +39 -0
  99. package/dist/commands/improve/distill/content-repair.js +4 -10
  100. package/dist/commands/improve/distill/promote-memory.js +89 -64
  101. package/dist/commands/improve/distill/quality-gate.js +118 -42
  102. package/dist/commands/improve/distill-guards.js +1 -1
  103. package/dist/commands/improve/distill-promotion-policy.js +33 -888
  104. package/dist/commands/improve/distill.js +607 -363
  105. package/dist/commands/improve/eligibility.js +165 -79
  106. package/dist/commands/improve/extract-cli.js +35 -126
  107. package/dist/commands/improve/extract-prompt.js +6 -35
  108. package/dist/commands/improve/extract.js +640 -391
  109. package/dist/commands/improve/feedback-valence.js +2 -12
  110. package/dist/commands/improve/improve-cli.js +134 -135
  111. package/dist/commands/improve/improve-result-file.js +30 -50
  112. package/dist/commands/improve/improve-run-types.js +4 -0
  113. package/dist/commands/improve/improve-strategies.js +135 -0
  114. package/dist/commands/improve/improve.js +904 -701
  115. package/dist/commands/improve/locks.js +64 -111
  116. package/dist/commands/improve/loop-stages.js +1110 -923
  117. package/dist/commands/improve/memory/derived-ref.js +124 -0
  118. package/dist/commands/improve/memory/memory-belief.js +79 -7
  119. package/dist/commands/improve/memory/memory-contradiction-detect.js +49 -52
  120. package/dist/commands/improve/memory/memory-improve.js +25 -37
  121. package/dist/commands/improve/outcome-loop.js +25 -88
  122. package/dist/commands/improve/preparation.js +1034 -813
  123. package/dist/commands/improve/proactive-maintenance.js +34 -9
  124. package/dist/commands/improve/proposal-envelope.js +31 -0
  125. package/dist/commands/improve/reflect.js +983 -794
  126. package/dist/commands/improve/run-context.js +119 -0
  127. package/dist/commands/improve/salience.js +24 -127
  128. package/dist/commands/improve/session-asset.js +7 -3
  129. package/dist/commands/improve/shared.js +14 -34
  130. package/dist/commands/improve/source-identity.js +28 -0
  131. package/dist/commands/improve/triage.js +20 -17
  132. package/dist/commands/lint/base-linter.js +340 -313
  133. package/dist/commands/lint/env-key-rules.js +31 -47
  134. package/dist/commands/lint/index.js +185 -30
  135. package/dist/commands/{events.js → log.js} +28 -38
  136. package/dist/commands/migrate-cli.js +54 -0
  137. package/dist/commands/migration-tool.js +55 -0
  138. package/dist/commands/observability-cli.js +70 -208
  139. package/dist/commands/proposal/diff-format.js +50 -0
  140. package/dist/commands/proposal/drain-policies.js +0 -6
  141. package/dist/commands/proposal/drain.js +91 -40
  142. package/dist/commands/proposal/proposal-cli.js +134 -132
  143. package/dist/commands/proposal/proposal-types.js +56 -0
  144. package/dist/commands/proposal/proposal.js +83 -65
  145. package/dist/commands/proposal/propose-cli.js +88 -0
  146. package/dist/commands/proposal/propose.js +105 -88
  147. package/dist/commands/proposal/repository.js +1303 -278
  148. package/dist/commands/proposal/validators/proposal-quality-validators.js +16 -6
  149. package/dist/commands/proposal/validators/proposal-validators.js +61 -12
  150. package/dist/commands/proposal/validators/proposals.js +6 -8
  151. package/dist/commands/read/curate.js +78 -73
  152. package/dist/commands/read/knowledge.js +510 -13
  153. package/dist/commands/read/registry-search.js +2 -2
  154. package/dist/commands/read/remember-cli.js +84 -15
  155. package/dist/commands/read/search-cli.js +203 -96
  156. package/dist/commands/read/search.js +126 -94
  157. package/dist/commands/read/show.js +226 -250
  158. package/dist/commands/registry-cli.js +34 -60
  159. package/dist/commands/remember.js +18 -57
  160. package/dist/commands/sources/add-cli.js +104 -49
  161. package/dist/commands/sources/bundle-cli.js +166 -0
  162. package/dist/commands/sources/bundle-config-ops.js +63 -0
  163. package/dist/commands/sources/info.js +27 -15
  164. package/dist/commands/sources/init.js +30 -40
  165. package/dist/commands/sources/installed-stashes.js +469 -172
  166. package/dist/commands/sources/schema-repair.js +10 -9
  167. package/dist/commands/sources/self-update.js +182 -121
  168. package/dist/commands/sources/source-add.js +169 -178
  169. package/dist/commands/sources/source-clone.js +144 -41
  170. package/dist/commands/sources/source-manage.js +94 -59
  171. package/dist/commands/sources/sources-cli.js +64 -205
  172. package/dist/commands/sources/stash-cli.js +91 -54
  173. package/dist/commands/sources/stash-skeleton.js +1 -1
  174. package/dist/commands/tasks/tasks-cli.js +106 -104
  175. package/dist/commands/tasks/tasks.js +445 -262
  176. package/dist/commands/workflow-cli.js +75 -228
  177. package/dist/core/action-contributors.js +1 -1
  178. package/dist/core/activation-policy.js +49 -0
  179. package/dist/core/adapter/adapters/agent-skills-adapter.js +181 -0
  180. package/dist/core/adapter/adapters/akm-adapter.js +528 -0
  181. package/dist/core/adapter/adapters/akm-lint.js +392 -0
  182. package/dist/core/adapter/adapters/akm-metadata.js +387 -0
  183. package/dist/core/adapter/adapters/akm-task-adapter.js +149 -0
  184. package/dist/core/adapter/adapters/akm-workflow-adapter.js +180 -0
  185. package/dist/core/adapter/adapters/claude-adapter.js +61 -0
  186. package/dist/core/adapter/adapters/dotenv-adapter.js +187 -0
  187. package/dist/core/adapter/adapters/generic-files-adapter.js +119 -0
  188. package/dist/core/adapter/adapters/index.js +80 -0
  189. package/dist/core/adapter/adapters/llm-wiki-adapter.js +419 -0
  190. package/dist/core/adapter/adapters/okf-adapter.js +391 -0
  191. package/dist/core/adapter/adapters/opencode-adapter.js +68 -0
  192. package/dist/core/adapter/adapters/shared.js +286 -0
  193. package/dist/core/adapter/adapters/tool-dir-shared.js +217 -0
  194. package/dist/core/adapter/adapters/website-snapshot-adapter.js +155 -0
  195. package/dist/core/adapter/bundle-adapter.js +4 -0
  196. package/dist/core/adapter/detect-adapter.js +17 -0
  197. package/dist/core/adapter/recognize-match.js +44 -0
  198. package/dist/core/adapter/registry.js +56 -0
  199. package/dist/core/adapter/types.js +4 -0
  200. package/dist/core/asset/akm-markdown.js +30 -0
  201. package/dist/core/asset/asset-placement.js +243 -0
  202. package/dist/core/asset/asset-ref.js +110 -79
  203. package/dist/core/asset/asset-serialize.js +20 -0
  204. package/dist/core/asset/frontmatter.js +28 -12
  205. package/dist/core/asset/markdown.js +40 -51
  206. package/dist/core/asset/resolve-ref.js +274 -0
  207. package/dist/core/asset/stash-meta.js +2 -2
  208. package/dist/core/bundle-id.js +51 -0
  209. package/dist/core/common.js +281 -86
  210. package/dist/core/config/config-io.js +42 -128
  211. package/dist/core/config/config-schema.js +233 -855
  212. package/dist/core/config/config-sources.js +162 -39
  213. package/dist/core/config/config-types.js +16 -11
  214. package/dist/core/config/config-version.js +29 -0
  215. package/dist/core/config/config-walker.js +126 -37
  216. package/dist/core/config/config.js +154 -331
  217. package/dist/core/config/deep-merge.js +41 -0
  218. package/dist/core/config/engine-semantics.js +28 -0
  219. package/dist/core/config/experimental.js +21 -0
  220. package/dist/core/config/schema/embedding.js +38 -0
  221. package/dist/core/config/schema/engines.js +116 -0
  222. package/dist/core/config/schema/experimental.js +47 -0
  223. package/dist/core/config/schema/feedback.js +31 -0
  224. package/dist/core/config/schema/improve-processes.js +389 -0
  225. package/dist/core/config/schema/improve.js +94 -0
  226. package/dist/core/config/schema/index-config.js +176 -0
  227. package/dist/core/config/schema/output.js +18 -0
  228. package/dist/core/config/schema/primitives.js +94 -0
  229. package/dist/core/config/schema/search.js +30 -0
  230. package/dist/core/config/schema/setup.js +18 -0
  231. package/dist/core/config/schema/sources-bundles.js +169 -0
  232. package/dist/core/config/schema/workflow.js +29 -0
  233. package/dist/core/env-secret-ref.js +155 -20
  234. package/dist/core/errors.js +17 -15
  235. package/dist/core/events-types.js +4 -0
  236. package/dist/core/events.js +46 -128
  237. package/dist/core/extra-params.js +62 -0
  238. package/dist/core/file-change.js +17 -0
  239. package/dist/core/file-lock.js +202 -57
  240. package/dist/core/fs-txn.js +392 -0
  241. package/dist/core/git-message.js +59 -0
  242. package/dist/core/improve-result.js +167 -0
  243. package/dist/core/lesson-lint.js +1 -17
  244. package/dist/core/logs-db.js +1 -1
  245. package/dist/core/maintenance-barrier.js +135 -0
  246. package/dist/core/migration-operation.js +44 -0
  247. package/dist/core/mutation-target.js +78 -0
  248. package/dist/core/paths.js +22 -25
  249. package/dist/core/platform.js +10 -0
  250. package/dist/core/recognition-util.js +128 -0
  251. package/dist/core/redaction.js +392 -0
  252. package/dist/core/standards/resolve-standards-context.js +36 -65
  253. package/dist/core/standards/resolve-stash-standards.js +2 -2
  254. package/dist/core/standards/resolve-type-conventions.js +5 -5
  255. package/dist/core/state/migrations.js +242 -11
  256. package/dist/core/state-db.js +98 -10
  257. package/dist/core/structured.js +1 -1
  258. package/dist/core/subprocess.js +303 -0
  259. package/dist/core/text-truncation.js +9 -5
  260. package/dist/core/time.js +20 -0
  261. package/dist/core/type-presentation.js +130 -0
  262. package/dist/core/warn.js +0 -3
  263. package/dist/core/write-source.js +834 -118
  264. package/dist/indexer/bundle-identity-guard.js +92 -0
  265. package/dist/indexer/db/graph-db.js +1 -25
  266. package/dist/indexer/db/llm-cache.js +1 -1
  267. package/dist/indexer/ensure-index.js +30 -9
  268. package/dist/indexer/graph/graph-boost.js +9 -30
  269. package/dist/indexer/graph/graph-extraction.js +41 -27
  270. package/dist/indexer/graph/graph-types.js +4 -0
  271. package/dist/indexer/index-writer-lock.js +93 -49
  272. package/dist/indexer/index-written-assets.js +100 -53
  273. package/dist/indexer/indexer.js +746 -329
  274. package/dist/indexer/init.js +18 -25
  275. package/dist/indexer/installations.js +142 -0
  276. package/dist/indexer/passes/dir-staleness.js +18 -10
  277. package/dist/indexer/passes/memory-inference.js +25 -15
  278. package/dist/indexer/passes/metadata.js +412 -243
  279. package/dist/indexer/scan/doc-to-entry.js +160 -0
  280. package/dist/indexer/scan/drain-dir.js +134 -0
  281. package/dist/indexer/search/db-search.js +292 -108
  282. package/dist/indexer/search/fts-query.js +64 -0
  283. package/dist/indexer/search/ranking-contributors.js +145 -25
  284. package/dist/indexer/search/ranking-types.js +4 -0
  285. package/dist/indexer/search/ranking.js +28 -71
  286. package/dist/indexer/search/search-attribution.js +67 -0
  287. package/dist/indexer/search/search-fields.js +18 -3
  288. package/dist/indexer/search/search-hit-enrichers.js +30 -40
  289. package/dist/indexer/search/search-source.js +157 -111
  290. package/dist/indexer/search/semantic-status.js +4 -1
  291. package/dist/indexer/usage/usage-events.js +10 -30
  292. package/dist/indexer/walk/file-context.js +3 -45
  293. package/dist/indexer/walk/matchers.js +42 -73
  294. package/dist/indexer/walk/path-resolver.js +11 -5
  295. package/dist/indexer/walk/walker.js +42 -14
  296. package/dist/integrations/agent/builder-shared.js +7 -0
  297. package/dist/integrations/agent/builders.js +5 -58
  298. package/dist/integrations/agent/config.js +3 -143
  299. package/dist/integrations/agent/detect.js +17 -2
  300. package/dist/integrations/agent/engine-resolution.js +231 -0
  301. package/dist/integrations/agent/index.js +1 -2
  302. package/dist/integrations/agent/model-aliases.js +8 -3
  303. package/dist/integrations/agent/profiles.js +6 -99
  304. package/dist/integrations/agent/prompts.js +46 -18
  305. package/dist/integrations/agent/runner-dispatch.js +78 -13
  306. package/dist/integrations/agent/runner.js +76 -208
  307. package/dist/integrations/agent/spawn.js +48 -279
  308. package/dist/integrations/harnesses/aider/agent-builder.js +9 -8
  309. package/dist/integrations/harnesses/aider/index.js +2 -12
  310. package/dist/integrations/harnesses/amazonq/agent-builder.js +10 -16
  311. package/dist/integrations/harnesses/amazonq/index.js +3 -17
  312. package/dist/integrations/harnesses/claude/agent-builder.js +2 -3
  313. package/dist/integrations/harnesses/claude/config-import.js +1 -3
  314. package/dist/integrations/harnesses/claude/index.js +1 -14
  315. package/dist/integrations/harnesses/claude/session-log.js +27 -75
  316. package/dist/integrations/harnesses/codex/agent-builder.js +8 -7
  317. package/dist/integrations/harnesses/codex/index.js +2 -13
  318. package/dist/integrations/harnesses/copilot/agent-builder.js +9 -9
  319. package/dist/integrations/harnesses/copilot/index.js +1 -13
  320. package/dist/integrations/harnesses/gemini/agent-builder.js +8 -9
  321. package/dist/integrations/harnesses/gemini/index.js +1 -13
  322. package/dist/integrations/harnesses/ids.js +24 -0
  323. package/dist/integrations/harnesses/index.js +31 -33
  324. package/dist/integrations/harnesses/opencode/agent-builder.js +23 -5
  325. package/dist/integrations/harnesses/opencode/config-import.js +1 -3
  326. package/dist/integrations/harnesses/opencode/index.js +1 -18
  327. package/dist/integrations/harnesses/opencode/session-log.js +67 -125
  328. package/dist/integrations/harnesses/opencode-sdk/harness.js +3 -17
  329. package/dist/integrations/harnesses/opencode-sdk/sdk-runner.js +274 -191
  330. package/dist/integrations/harnesses/openhands/agent-builder.js +12 -10
  331. package/dist/integrations/harnesses/openhands/index.js +2 -12
  332. package/dist/integrations/harnesses/pi/agent-builder.js +11 -18
  333. package/dist/integrations/harnesses/pi/index.js +3 -16
  334. package/dist/integrations/harnesses/shared.js +17 -0
  335. package/dist/integrations/harnesses/types.js +38 -34
  336. package/dist/integrations/lockfile.js +211 -24
  337. package/dist/integrations/session-logs/index.js +24 -40
  338. package/dist/integrations/session-logs/provider-base.js +113 -0
  339. package/dist/llm/client.js +182 -110
  340. package/dist/llm/embedders/deterministic.js +2 -2
  341. package/dist/llm/embedders/remote.js +21 -9
  342. package/dist/llm/feature-gate.js +17 -57
  343. package/dist/llm/graph-extract.js +12 -13
  344. package/dist/llm/index-passes.js +8 -42
  345. package/dist/llm/memory-infer.js +144 -1
  346. package/dist/llm/metadata-enhance.js +45 -30
  347. package/dist/llm/structured-call.js +16 -8
  348. package/dist/llm/usage-persist.js +30 -5
  349. package/dist/llm/usage-telemetry.js +59 -6
  350. package/dist/output/cli-hints.js +1 -2
  351. package/dist/output/command-registry.js +27 -0
  352. package/dist/output/context.js +22 -7
  353. package/dist/output/format-exempt.js +80 -0
  354. package/dist/output/generic-render.js +251 -0
  355. package/dist/output/html-render.js +11 -16
  356. package/dist/output/render-registry.js +57 -0
  357. package/dist/output/renderers.js +15 -281
  358. package/dist/output/shapes/curate.js +10 -1
  359. package/dist/output/shapes/events.js +12 -7
  360. package/dist/output/shapes/helpers.js +58 -84
  361. package/dist/output/shapes/passthrough.js +8 -40
  362. package/dist/output/shapes/proposal/producer.js +15 -7
  363. package/dist/output/shapes/registry.js +12 -6
  364. package/dist/output/shapes.js +0 -9
  365. package/dist/output/text/{init.js → bundle-create.js} +3 -1
  366. package/dist/output/text/bundle-show.js +7 -0
  367. package/dist/output/text/command-format.js +562 -0
  368. package/dist/output/text/env.js +1 -3
  369. package/dist/output/text/events.js +8 -7
  370. package/dist/output/text/helpers.js +15 -1375
  371. package/dist/output/text/proposal/producer.js +4 -2
  372. package/dist/output/text/proposal-format.js +202 -0
  373. package/dist/output/text/registry-commands.js +1 -2
  374. package/dist/output/text/registry.js +12 -6
  375. package/dist/output/text/show-directives.js +117 -0
  376. package/dist/output/text/show-format.js +103 -0
  377. package/dist/output/text/sync.js +5 -0
  378. package/dist/output/text/workflow-format.js +332 -0
  379. package/dist/output/text/workflow.js +1 -2
  380. package/dist/output/text.js +10 -19
  381. package/dist/registry/factory.js +4 -6
  382. package/dist/registry/origin-resolve.js +16 -27
  383. package/dist/registry/providers/skills-sh.js +3 -3
  384. package/dist/registry/providers/static-index.js +15 -25
  385. package/dist/registry/resolve.js +43 -94
  386. package/dist/registry/semver.js +43 -0
  387. package/dist/runtime.js +81 -12
  388. package/dist/scripts/akm-migrate.js +35529 -0
  389. package/dist/setup/detect.js +5 -7
  390. package/dist/setup/detected-engines.js +136 -0
  391. package/dist/setup/engine-config.js +100 -0
  392. package/dist/setup/registry-stash-loader.js +3 -3
  393. package/dist/setup/semantic-assets.js +12 -9
  394. package/dist/setup/setup.js +444 -208
  395. package/dist/setup/steps/connection-shared.js +120 -0
  396. package/dist/setup/steps/connection.js +108 -305
  397. package/dist/setup/steps/platforms.js +13 -12
  398. package/dist/setup/steps/semantic.js +15 -3
  399. package/dist/setup/steps/sources.js +21 -15
  400. package/dist/setup/steps/stashdir.js +6 -4
  401. package/dist/setup/steps/tasks.js +236 -119
  402. package/dist/setup/steps.js +3 -2
  403. package/dist/sources/freshness.js +39 -0
  404. package/dist/sources/provider-factory.js +11 -17
  405. package/dist/sources/providers/filesystem.js +2 -3
  406. package/dist/sources/providers/git-install.js +278 -34
  407. package/dist/sources/providers/git-provider.js +54 -56
  408. package/dist/sources/providers/git-stash.js +420 -91
  409. package/dist/sources/providers/git.js +2 -2
  410. package/dist/sources/providers/npm.js +16 -19
  411. package/dist/sources/providers/provider-utils.js +47 -22
  412. package/dist/sources/providers/sync-from-ref.js +3 -9
  413. package/dist/sources/providers/website.js +2 -2
  414. package/dist/sources/resolve.js +11 -10
  415. package/dist/sources/snapshot-fetchers/types.js +4 -0
  416. package/dist/sources/{website-ingest.js → snapshot-fetchers/website-ingest.js} +110 -41
  417. package/dist/storage/database.js +60 -4
  418. package/dist/storage/engines/sqlite-migrations.js +156 -5
  419. package/dist/storage/locations.js +1 -2
  420. package/dist/storage/repositories/canaries-repository.js +1 -1
  421. package/dist/storage/repositories/events-repository.js +51 -11
  422. package/dist/storage/repositories/improve-runs-repository.js +6 -32
  423. package/dist/storage/repositories/index-connection.js +79 -0
  424. package/dist/storage/repositories/index-db.js +4 -3
  425. package/dist/storage/repositories/index-entries-repository.js +863 -0
  426. package/dist/{indexer/db/entry-mapper.js → storage/repositories/index-entry-mapper.js} +19 -2
  427. package/dist/storage/repositories/index-entry-types.js +4 -0
  428. package/dist/storage/repositories/index-fts-repository.js +167 -0
  429. package/dist/storage/repositories/index-llm-cache-repository.js +108 -0
  430. package/dist/storage/repositories/index-meta-repository.js +49 -0
  431. package/dist/{indexer/db/schema.js → storage/repositories/index-schema.js} +226 -100
  432. package/dist/storage/repositories/index-sql.js +12 -0
  433. package/dist/storage/repositories/index-utility-repository.js +356 -0
  434. package/dist/storage/repositories/index-vec-repository.js +250 -0
  435. package/dist/storage/repositories/outcome-repository.js +119 -0
  436. package/dist/storage/repositories/proposals-repository.js +317 -75
  437. package/dist/storage/repositories/registry-cache.js +1 -1
  438. package/dist/storage/repositories/salience-repository.js +172 -0
  439. package/dist/storage/repositories/task-history-repository.js +110 -3
  440. package/dist/storage/repositories/workflow-runs-repository.js +68 -35
  441. package/dist/tasks/backends/cron.js +169 -46
  442. package/dist/tasks/backends/exec-utils.js +76 -3
  443. package/dist/tasks/backends/index.js +6 -9
  444. package/dist/tasks/backends/launchd.js +292 -55
  445. package/dist/tasks/backends/schtasks.js +557 -70
  446. package/dist/tasks/backends/types.js +4 -0
  447. package/dist/tasks/command-executable.js +93 -0
  448. package/dist/tasks/embedded.js +56 -38
  449. package/dist/tasks/parser.js +156 -64
  450. package/dist/tasks/resolve-akm-bin.js +144 -51
  451. package/dist/tasks/runner.js +377 -209
  452. package/dist/tasks/schedule.js +108 -19
  453. package/dist/tasks/scheduler-invocation.js +296 -0
  454. package/dist/tasks/schema.js +1 -1
  455. package/dist/tasks/task-id.js +35 -0
  456. package/dist/tasks/validator.js +30 -16
  457. package/dist/workflows/authoring/authoring.js +96 -148
  458. package/dist/workflows/authoring/scope-key.js +1 -1
  459. package/dist/workflows/cli.js +0 -20
  460. package/dist/workflows/concurrency-policy.js +15 -0
  461. package/dist/workflows/exec/brief.js +25 -59
  462. package/dist/workflows/exec/frozen-judge.js +47 -0
  463. package/dist/workflows/exec/native-executor.js +157 -94
  464. package/dist/workflows/exec/report.js +365 -200
  465. package/dist/workflows/exec/run-workflow.js +46 -40
  466. package/dist/workflows/exec/scheduler.js +12 -41
  467. package/dist/workflows/exec/step-work.js +239 -205
  468. package/dist/workflows/exec/workflow-engine-gate.js +67 -0
  469. package/dist/workflows/ir/compile.js +141 -283
  470. package/dist/workflows/ir/freeze.js +233 -0
  471. package/dist/workflows/ir/plan-hash.js +40 -5
  472. package/dist/workflows/ir/schema.js +537 -1
  473. package/dist/workflows/parser.js +878 -306
  474. package/dist/workflows/program/expressions.js +20 -208
  475. package/dist/workflows/program/schema.js +7 -10
  476. package/dist/workflows/renderer.js +99 -121
  477. package/dist/workflows/resource-limits.js +22 -0
  478. package/dist/workflows/runtime/checkin.js +1 -1
  479. package/dist/workflows/runtime/plan-classifier.js +131 -0
  480. package/dist/workflows/runtime/runs.js +200 -113
  481. package/dist/workflows/runtime/unit-checkin.js +1 -1
  482. package/dist/workflows/runtime/unit-phases.js +20 -0
  483. package/dist/workflows/runtime/workflow-asset-loader.js +235 -97
  484. package/dist/workflows/schema.js +1 -11
  485. package/dist/workflows/validate-summary.js +4 -26
  486. package/dist/workflows/validator.js +52 -30
  487. package/docs/README.md +42 -78
  488. package/docs/migration/README.md +8 -0
  489. package/docs/migration/release-notes/0.6.0.md +1 -1
  490. package/docs/migration/release-notes/0.7.0.md +9 -8
  491. package/docs/migration/release-notes/0.9.0.md +158 -14
  492. package/docs/migration/v0.7-to-v0.8.md +46 -47
  493. package/docs/migration/v0.8-to-v0.9.md +844 -0
  494. package/docs/reference/README.md +12 -0
  495. package/docs/reference/data-and-telemetry.md +333 -0
  496. package/package.json +21 -17
  497. package/schemas/akm-asset-envelope.json +93 -0
  498. package/schemas/akm-config.json +4636 -0
  499. package/schemas/akm-task.json +87 -0
  500. package/{dist/schemas → schemas}/akm-workflow.json +127 -82
  501. package/dist/akm-migrate-storage +0 -38
  502. package/dist/assets/help/help-accept.md +0 -12
  503. package/dist/assets/help/help-improve.md +0 -84
  504. package/dist/assets/help/help-proposals.md +0 -17
  505. package/dist/assets/help/help-propose.md +0 -17
  506. package/dist/assets/help/help-reject.md +0 -11
  507. package/dist/assets/profiles/frequent.json +0 -13
  508. package/dist/assets/profiles/recombine-only.json +0 -21
  509. package/dist/assets/profiles/reflect-distill.json +0 -30
  510. package/dist/assets/profiles/synthesize.json +0 -15
  511. package/dist/assets/prompts/procedural-system.md +0 -44
  512. package/dist/assets/prompts/recombine-system.md +0 -40
  513. package/dist/assets/prompts/staleness-detect-system.md +0 -6
  514. package/dist/assets/tasks/core/backup.yml +0 -4
  515. package/dist/assets/tasks/graph-refresh-weekly.yml +0 -10
  516. package/dist/assets/templates/html/default.html +0 -78
  517. package/dist/assets/templates/html/vendor/echarts.min.js +0 -45
  518. package/dist/assets/wiki/index-template.md +0 -12
  519. package/dist/assets/wiki/ingest-workflow-template.md +0 -83
  520. package/dist/assets/wiki/log-template.md +0 -8
  521. package/dist/assets/wiki/schema-template.md +0 -61
  522. package/dist/cli/config-migrate.js +0 -150
  523. package/dist/cli/config-validate.js +0 -39
  524. package/dist/commands/graph/graph-cli.js +0 -124
  525. package/dist/commands/graph/graph.js +0 -487
  526. package/dist/commands/improve/calibration.js +0 -161
  527. package/dist/commands/improve/dedup.js +0 -482
  528. package/dist/commands/improve/extract-watch.js +0 -140
  529. package/dist/commands/improve/hot-probation.js +0 -45
  530. package/dist/commands/improve/improve-auto-accept.js +0 -276
  531. package/dist/commands/improve/improve-profiles.js +0 -168
  532. package/dist/commands/improve/procedural.js +0 -398
  533. package/dist/commands/improve/recombine.js +0 -818
  534. package/dist/commands/improve/schema-similarity-gate.js +0 -168
  535. package/dist/commands/lint/agent-linter.js +0 -44
  536. package/dist/commands/lint/command-linter.js +0 -44
  537. package/dist/commands/lint/default-linter.js +0 -16
  538. package/dist/commands/lint/fact-linter.js +0 -39
  539. package/dist/commands/lint/knowledge-linter.js +0 -16
  540. package/dist/commands/lint/memory-linter.js +0 -61
  541. package/dist/commands/lint/registry.js +0 -41
  542. package/dist/commands/lint/skill-linter.js +0 -45
  543. package/dist/commands/lint/task-linter.js +0 -50
  544. package/dist/commands/lint/workflow-linter.js +0 -81
  545. package/dist/commands/proposal/legacy-import.js +0 -115
  546. package/dist/commands/sources/history.js +0 -196
  547. package/dist/commands/tasks/default-tasks.js +0 -186
  548. package/dist/commands/wiki-cli.js +0 -292
  549. package/dist/core/asset/asset-registry.js +0 -76
  550. package/dist/core/asset/asset-spec.js +0 -316
  551. package/dist/core/config/config-migration.js +0 -602
  552. package/dist/core/deep-merge.js +0 -38
  553. package/dist/core/eval/rank-metrics.js +0 -113
  554. package/dist/core/ripgrep/install.js +0 -163
  555. package/dist/core/ripgrep/resolve.js +0 -81
  556. package/dist/indexer/db/db.js +0 -1414
  557. package/dist/indexer/manifest.js +0 -170
  558. package/dist/indexer/passes/metadata-contributors.js +0 -31
  559. package/dist/indexer/usage/unmigrated-vaults-guard.js +0 -94
  560. package/dist/integrations/harnesses/opencode-sdk/index.js +0 -25
  561. package/dist/llm/call-ai.js +0 -62
  562. package/dist/llm/memory-infer-impl.js +0 -138
  563. package/dist/output/shapes/distill.js +0 -14
  564. package/dist/output/shapes/history.js +0 -11
  565. package/dist/output/text/distill.js +0 -6
  566. package/dist/output/text/enable-disable.js +0 -8
  567. package/dist/output/text/history.js +0 -6
  568. package/dist/output/text/wiki.js +0 -16
  569. package/dist/registry/build-index.js +0 -386
  570. package/dist/schemas/akm-config.json +0 -14225
  571. package/dist/scripts/migrate-storage.js +0 -13169
  572. package/dist/scripts/migrations/import-fs-improve-runs-to-db.js +0 -10169
  573. package/dist/scripts/migrations/v16-to-v17.js +0 -141
  574. package/dist/setup/legacy-config.js +0 -106
  575. package/dist/storage/repositories/consolidation-repository.js +0 -38
  576. package/dist/storage/repositories/recombine-repository.js +0 -213
  577. package/dist/wiki/wiki-templates.js +0 -15
  578. package/dist/wiki/wiki.js +0 -1012
  579. package/dist/workflows/authoring/workflow-program-template.yaml +0 -31
  580. package/dist/workflows/db.js +0 -350
  581. package/dist/workflows/exec/watch.js +0 -116
  582. package/dist/workflows/program/parser.js +0 -760
  583. package/dist/workflows/program/project.js +0 -105
  584. package/docs/data-and-telemetry.md +0 -227
  585. package/docs/migration/release-notes/0.9.0-beta.60.md +0 -19
  586. /package/dist/sources/{wiki-fetchers → snapshot-fetchers}/registry.js +0 -0
  587. /package/dist/sources/{wiki-fetchers → snapshot-fetchers}/youtube.js +0 -0
@@ -7,10 +7,11 @@
7
7
  */
8
8
  import * as p from "../../cli/clack.js";
9
9
  import { detectAgentCliProfiles, pickDefaultAgentProfile } from "../../integrations/agent/index.js";
10
- import { probeLlmCapabilities } from "../../llm/client.js";
11
10
  import { detectLMStudio, detectOllama } from "../detect.js";
12
- import { cloneLlmConfig, getCurrentAgentBlock, getCurrentLlm } from "../legacy-config.js";
13
- import { prompt, promptOrBack } from "../prompt.js";
11
+ import { verifyOpenAiCompatibleEndpoint } from "../detected-engines.js";
12
+ import { cloneLlmConnection, readAgentEngineSelection, readCurrentLlmEngine, } from "../engine-config.js";
13
+ import { prompt } from "../prompt.js";
14
+ import { keepCurrentOption, llmConnection, lmStudioOptionHint, probeLlmConnection, promptApiKeyEnvVarName, promptEndpointUrl, promptLmStudioModel, promptModelName, } from "./connection-shared.js";
14
15
  export async function stepOllama(current) {
15
16
  const spin = p.spinner();
16
17
  spin.start("Checking for Ollama...");
@@ -148,19 +149,12 @@ export async function stepLlm(current, ollamaEndpoint, ollamaChatModels, lmStudi
148
149
  hint: ollamaChatModels?.[0] ?? "local",
149
150
  });
150
151
  }
151
- const lmStudioHint = lmStudio?.available
152
- ? `${lmStudio.models.length} model${lmStudio.models.length === 1 ? "" : "s"} detected`
153
- : "http://localhost:1234";
154
- options.push({ value: "lmstudio", label: "LM Studio / local server", hint: lmStudioHint });
152
+ options.push({ value: "lmstudio", label: "LM Studio / local server", hint: lmStudioOptionHint(lmStudio) });
155
153
  options.push({ value: "custom", label: "Custom OpenAI-compatible endpoint" });
156
154
  options.push({ value: "none", label: "Skip LLM", hint: "no metadata enhancement during indexing" });
157
- const currentLlm = getCurrentLlm(current);
155
+ const currentLlm = readCurrentLlmEngine(current);
158
156
  if (currentLlm) {
159
- options.push({
160
- value: "keep",
161
- label: `Keep current: ${currentLlm.provider ?? currentLlm.endpoint}`,
162
- hint: currentLlm.model,
163
- });
157
+ options.push(keepCurrentOption(currentLlm));
164
158
  }
165
159
  const initialValue = currentLlm ? "keep" : ollamaAvailable ? "ollama" : (LLM_PRESETS[0]?.value ?? "none");
166
160
  const choice = await prompt(() => p.select({
@@ -169,7 +163,7 @@ export async function stepLlm(current, ollamaEndpoint, ollamaChatModels, lmStudi
169
163
  initialValue,
170
164
  }));
171
165
  if (choice === "keep")
172
- return cloneLlmConfig(currentLlm);
166
+ return cloneLlmConnection(currentLlm);
173
167
  if (choice === "none")
174
168
  return undefined;
175
169
  // Handle "Import from <Harness>" choices
@@ -180,16 +174,27 @@ export async function stepLlm(current, ollamaEndpoint, ollamaChatModels, lmStudi
180
174
  // Show a summary before accepting
181
175
  p.log.info(`Importing LLM config from ${harness.harnessName}: ` +
182
176
  [harness.provider, harness.model, harness.baseUrl].filter(Boolean).join(", "));
177
+ if (!harness.baseUrl || !harness.model) {
178
+ p.log.warn(`Skipping ${harness.harnessName}: no complete endpoint/model was detected.`);
179
+ return undefined;
180
+ }
181
+ const verified = await verifyOpenAiCompatibleEndpoint({
182
+ endpoint: harness.baseUrl,
183
+ model: harness.model,
184
+ apiKeyEnvVar: harness.apiKeyEnvVar,
185
+ });
186
+ if (!verified.ok) {
187
+ p.log.warn(`Skipping ${harness.harnessName}: ${verified.reason}. Fix its endpoint/credential and retry setup.`);
188
+ return undefined;
189
+ }
183
190
  const llmConfig = {
184
- endpoint: harness.baseUrl ?? "",
191
+ endpoint: verified.endpoint,
185
192
  model: harness.model ?? "",
186
193
  temperature: 0.3,
187
- maxTokens: 1024,
194
+ ...(harness.apiKeyEnvVar ? { apiKey: `\${${harness.apiKeyEnvVar}}` } : {}),
188
195
  };
189
196
  if (harness.provider)
190
197
  llmConfig.provider = harness.provider;
191
- if (harness.baseUrl)
192
- llmConfig.endpoint = harness.baseUrl;
193
198
  return llmConfig;
194
199
  }
195
200
  let llm;
@@ -199,118 +204,40 @@ export async function stepLlm(current, ollamaEndpoint, ollamaChatModels, lmStudi
199
204
  options: (ollamaChatModels ?? []).map((m) => ({ value: m, label: m })),
200
205
  initialValue: ollamaChatModels?.[0],
201
206
  }));
202
- llm = {
203
- provider: "ollama",
204
- endpoint: `${ollamaEndpoint}/v1/chat/completions`,
205
- model: modelChoice,
206
- temperature: 0.3,
207
- maxTokens: 1024,
208
- };
207
+ llm = llmConnection("ollama", `${ollamaEndpoint}/v1/chat/completions`, modelChoice);
209
208
  }
210
209
  else if (choice === "lmstudio") {
211
210
  const currentLmsLlm = currentLlm?.provider === "lmstudio" ? currentLlm : undefined;
212
211
  const defaultEndpoint = currentLmsLlm?.endpoint ??
213
212
  (lmStudio?.endpoint ? `${lmStudio.endpoint}/v1/chat/completions` : "http://localhost:1234/v1/chat/completions");
214
- const endpoint = await prompt(() => p.text({
215
- message: "Endpoint URL:",
216
- placeholder: defaultEndpoint,
217
- defaultValue: defaultEndpoint,
218
- validate: (v) => {
219
- if (!v?.trim())
220
- return "Endpoint cannot be empty";
221
- if (!v.startsWith("http://") && !v.startsWith("https://"))
222
- return "Must start with http:// or https://";
223
- },
224
- }));
225
- let model;
226
- const lmsModels = lmStudio?.available && lmStudio.models.length > 0 ? lmStudio.models : [];
227
- if (lmsModels.length > 0) {
228
- const modelChoice = await prompt(() => p.select({
229
- message: "Model name:",
230
- options: [
231
- ...lmsModels.map((m) => ({ value: m, label: m })),
232
- { value: "__manual__", label: "Enter manually..." },
233
- ],
234
- initialValue: currentLmsLlm?.model && lmsModels.includes(currentLmsLlm.model) ? currentLmsLlm.model : lmsModels[0],
235
- }));
236
- if (modelChoice === "__manual__") {
237
- model = await prompt(() => p.text({
238
- message: "Model name:",
239
- placeholder: currentLmsLlm?.model ?? "local-model",
240
- ...(currentLmsLlm?.model ? { defaultValue: currentLmsLlm.model } : {}),
241
- validate: (v) => (!v?.trim() ? "Model name cannot be empty" : undefined),
242
- }));
243
- }
244
- else {
245
- model = modelChoice;
246
- }
247
- }
248
- else {
249
- model = await prompt(() => p.text({
250
- message: "Model name:",
251
- placeholder: currentLmsLlm?.model ?? "local-model",
252
- ...(currentLmsLlm?.model ? { defaultValue: currentLmsLlm.model } : {}),
253
- validate: (v) => (!v?.trim() ? "Model name cannot be empty" : undefined),
254
- }));
255
- }
256
- llm = {
257
- provider: "lmstudio",
258
- endpoint: endpoint.trim(),
259
- model: model.trim(),
260
- temperature: 0.3,
261
- maxTokens: 1024,
262
- };
213
+ const endpoint = await promptEndpointUrl({ placeholder: defaultEndpoint, defaultValue: defaultEndpoint });
214
+ const model = await promptLmStudioModel(lmStudio, currentLmsLlm?.model);
215
+ llm = llmConnection("lmstudio", endpoint.trim(), model.trim());
263
216
  }
264
217
  else if (choice === "custom") {
265
218
  const currentCustomLlm = currentLlm?.provider === "custom" ? currentLlm : undefined;
266
- const endpoint = await prompt(() => p.text({
219
+ const endpoint = await promptEndpointUrl({
267
220
  message: "OpenAI-compatible chat completions endpoint:",
268
221
  placeholder: currentCustomLlm?.endpoint ?? "https://your-host/v1/chat/completions",
269
- ...(currentCustomLlm?.endpoint ? { defaultValue: currentCustomLlm.endpoint } : {}),
270
- validate: (v) => {
271
- if (!v?.trim())
272
- return "Endpoint cannot be empty";
273
- if (!v.startsWith("http://") && !v.startsWith("https://"))
274
- return "Endpoint must start with http:// or https://";
275
- },
276
- }));
277
- const model = await prompt(() => p.text({
278
- message: "Model name:",
222
+ defaultValue: currentCustomLlm?.endpoint,
223
+ schemeMessage: "Endpoint must start with http:// or https://",
224
+ });
225
+ const model = await promptModelName({
279
226
  placeholder: currentCustomLlm?.model ?? "gpt-4o-mini",
280
- ...(currentCustomLlm?.model ? { defaultValue: currentCustomLlm.model } : {}),
281
- validate: (v) => {
282
- if (!v?.trim())
283
- return "Model name cannot be empty";
284
- },
285
- }));
286
- llm = {
287
- provider: "custom",
288
- endpoint: endpoint.trim(),
289
- model: model.trim(),
290
- temperature: 0.3,
291
- maxTokens: 1024,
292
- };
227
+ defaultValue: currentCustomLlm?.model,
228
+ });
229
+ llm = llmConnection("custom", endpoint.trim(), model.trim());
293
230
  }
294
231
  else {
295
232
  const preset = LLM_PRESETS.find((p) => p.value === choice);
296
233
  if (!preset)
297
234
  return undefined;
298
- const model = await prompt(() => p.text({
235
+ const model = await promptModelName({
299
236
  message: `Model for ${preset.label}:`,
300
237
  placeholder: preset.defaultModel,
301
238
  defaultValue: preset.defaultModel,
302
- validate: (v) => {
303
- if (!v?.trim())
304
- return "Model name cannot be empty";
305
- },
306
- }));
307
- llm = {
308
- provider: preset.value,
309
- endpoint: preset.endpoint,
310
- model: model.trim() || preset.defaultModel,
311
- temperature: 0.3,
312
- maxTokens: 1024,
313
- };
239
+ });
240
+ llm = llmConnection(preset.value, preset.endpoint, model.trim() || preset.defaultModel);
314
241
  }
315
242
  // Remind the user about API key placement. We do not offer a "store in config"
316
243
  // option because saveConfig() strips apiKey fields before writing — persisting
@@ -320,21 +247,7 @@ export async function stepLlm(current, ollamaEndpoint, ollamaChatModels, lmStudi
320
247
  p.log.info("This provider requires an API key. Set AKM_LLM_API_KEY in your shell (e.g. `export AKM_LLM_API_KEY=...`) before running `akm index`.");
321
248
  }
322
249
  // Capability probe — best-effort, never blocks setup.
323
- const probeSpin = p.spinner();
324
- probeSpin.start("Probing LLM (structured-output round-trip)...");
325
- const probe = await probeLlmCapabilities(llm);
326
- if (probe.reachable && probe.structuredOutput) {
327
- probeSpin.stop("LLM reachable; structured output verified.");
328
- llm.capabilities = { ...(llm.capabilities ?? {}), structuredOutput: true };
329
- }
330
- else if (probe.reachable) {
331
- probeSpin.stop("LLM reachable but structured-output probe failed.");
332
- llm.capabilities = { ...(llm.capabilities ?? {}), structuredOutput: false };
333
- }
334
- else {
335
- probeSpin.stop("LLM not reachable.");
336
- p.log.warn(`Could not reach the LLM endpoint${probe.error ? ` (${probe.error})` : ""}. Configuration was saved; verify your endpoint and API key, then retry.`);
337
- }
250
+ await probeLlmConnection(llm);
338
251
  return llm;
339
252
  }
340
253
  /**
@@ -348,9 +261,8 @@ export async function stepSmallModelConnection(current) {
348
261
  p.note([
349
262
  "This connection is used for background processing:",
350
263
  " • akm index (metadata enhancement)",
351
- " • akm distill (lesson distillation)",
264
+ " • akm improve (lesson distillation)",
352
265
  " • akm remember --enrich (memory compression)",
353
- " • akm curate --rerank (search reranking)",
354
266
  ].join("\n"));
355
267
  // Probe for Ollama and LM Studio in the background while showing the note.
356
268
  const spin = p.spinner();
@@ -372,17 +284,10 @@ export async function stepSmallModelConnection(current) {
372
284
  hint: `detected at ${ollama.endpoint}`,
373
285
  });
374
286
  }
375
- const lmStudioHint = lmStudio.available
376
- ? `${lmStudio.models.length} model${lmStudio.models.length === 1 ? "" : "s"} detected`
377
- : "http://localhost:1234";
378
- providerOptions.push({ value: "openai", label: "OpenAI", hint: "requires AKM_LLM_API_KEY" }, { value: "lmstudio", label: "LM Studio / local server", hint: lmStudioHint }, { value: "custom", label: "Custom OpenAI-compatible endpoint" }, { value: "skip", label: "Skip — disable enrichment features" });
379
- const currentLlmSmall = getCurrentLlm(current);
287
+ providerOptions.push({ value: "openai", label: "OpenAI", hint: "requires AKM_LLM_API_KEY" }, { value: "lmstudio", label: "LM Studio / local server", hint: lmStudioOptionHint(lmStudio) }, { value: "custom", label: "Custom OpenAI-compatible endpoint" }, { value: "skip", label: "Skip — disable enrichment features" });
288
+ const currentLlmSmall = readCurrentLlmEngine(current);
380
289
  if (currentLlmSmall) {
381
- providerOptions.push({
382
- value: "keep",
383
- label: `Keep current: ${currentLlmSmall.provider ?? currentLlmSmall.endpoint}`,
384
- hint: currentLlmSmall.model,
385
- });
290
+ providerOptions.push(keepCurrentOption(currentLlmSmall));
386
291
  }
387
292
  const initialValue = currentLlmSmall ? "keep" : ollama.available ? "ollama" : "openai";
388
293
  const providerChoice = await prompt(() => p.select({
@@ -391,15 +296,14 @@ export async function stepSmallModelConnection(current) {
391
296
  initialValue,
392
297
  }));
393
298
  if (providerChoice === "keep") {
394
- return { llm: cloneLlmConfig(currentLlmSmall), skipped: false, ollamaEndpoint };
299
+ return { llm: cloneLlmConnection(currentLlmSmall), skipped: false, ollamaEndpoint };
395
300
  }
396
301
  if (providerChoice === "skip") {
397
302
  p.note([
398
303
  "Enrichment features disabled:",
399
304
  " • akm index — metadata enhancement disabled",
400
- " • akm distill — lesson generation",
305
+ " • akm improve — lesson generation",
401
306
  " • akm remember --enrich",
402
- " • akm curate --rerank",
403
307
  "",
404
308
  "You can configure this later with `akm setup`.",
405
309
  ].join("\n"), "Warning");
@@ -419,154 +323,54 @@ export async function stepSmallModelConnection(current) {
419
323
  initialValue: ollamaChatModels[0],
420
324
  }));
421
325
  if (model === "__custom__") {
422
- model = await prompt(() => p.text({
423
- message: "Model name:",
424
- placeholder: "llama3.2",
425
- validate: (v) => (!v?.trim() ? "Model name cannot be empty" : undefined),
426
- }));
326
+ model = await promptModelName({ placeholder: "llama3.2" });
427
327
  }
428
328
  }
429
329
  else {
430
330
  const currentOllamaModel = currentLlmSmall?.provider === "ollama" ? (currentLlmSmall.model ?? "llama3.2") : "llama3.2";
431
- model = await prompt(() => p.text({
331
+ model = await promptModelName({
432
332
  message: "Model name (e.g. llama3.2):",
433
333
  placeholder: currentOllamaModel,
434
334
  defaultValue: currentOllamaModel,
435
- validate: (v) => (!v?.trim() ? "Model name cannot be empty" : undefined),
436
- }));
335
+ });
437
336
  }
438
- llm = {
439
- provider: "ollama",
440
- endpoint: `${ollama.endpoint}/v1/chat/completions`,
441
- model: model.trim(),
442
- temperature: 0.3,
443
- maxTokens: 1024,
444
- };
337
+ llm = llmConnection("ollama", `${ollama.endpoint}/v1/chat/completions`, model.trim());
445
338
  }
446
339
  else if (providerChoice === "openai") {
447
340
  const currentOpenAiModel = currentLlmSmall?.provider === "openai" ? (currentLlmSmall.model ?? "gpt-4o-mini") : "gpt-4o-mini";
448
- const model = await prompt(() => p.text({
449
- message: "Model name:",
450
- placeholder: currentOpenAiModel,
451
- defaultValue: currentOpenAiModel,
452
- validate: (v) => (!v?.trim() ? "Model name cannot be empty" : undefined),
453
- }));
341
+ const model = await promptModelName({ placeholder: currentOpenAiModel, defaultValue: currentOpenAiModel });
454
342
  if (!process.env.AKM_LLM_API_KEY) {
455
343
  p.log.info("Set AKM_LLM_API_KEY in your shell before running `akm index`.");
456
344
  }
457
- llm = {
458
- provider: "openai",
459
- endpoint: "https://api.openai.com/v1/chat/completions",
460
- model: model.trim() || currentOpenAiModel,
461
- temperature: 0.3,
462
- maxTokens: 1024,
463
- };
345
+ llm = llmConnection("openai", "https://api.openai.com/v1/chat/completions", model.trim() || currentOpenAiModel);
464
346
  }
465
347
  else if (providerChoice === "lmstudio") {
466
348
  const currentLmsEndpoint = currentLlmSmall?.provider === "lmstudio"
467
349
  ? (currentLlmSmall.endpoint ?? `${lmStudio.endpoint}/v1/chat/completions`)
468
350
  : `${lmStudio.endpoint}/v1/chat/completions`;
469
351
  const currentLmsModel = currentLlmSmall?.provider === "lmstudio" ? currentLlmSmall.model : undefined;
470
- const endpoint = await prompt(() => p.text({
471
- message: "Endpoint URL:",
472
- placeholder: currentLmsEndpoint,
473
- defaultValue: currentLmsEndpoint,
474
- validate: (v) => {
475
- if (!v?.trim())
476
- return "Endpoint cannot be empty";
477
- if (!v.startsWith("http://") && !v.startsWith("https://"))
478
- return "Must start with http:// or https://";
479
- },
480
- }));
481
- let model;
482
- const lmsModels = lmStudio.available && lmStudio.models.length > 0 ? lmStudio.models : [];
483
- if (lmsModels.length > 0) {
484
- const modelChoice = await prompt(() => p.select({
485
- message: "Model name:",
486
- options: [
487
- ...lmsModels.map((m) => ({ value: m, label: m })),
488
- { value: "__manual__", label: "Enter manually..." },
489
- ],
490
- initialValue: currentLmsModel && lmsModels.includes(currentLmsModel) ? currentLmsModel : lmsModels[0],
491
- }));
492
- if (modelChoice === "__manual__") {
493
- model = await prompt(() => p.text({
494
- message: "Model name:",
495
- placeholder: currentLmsModel ?? "local-model",
496
- ...(currentLmsModel ? { defaultValue: currentLmsModel } : {}),
497
- validate: (v) => (!v?.trim() ? "Model name cannot be empty" : undefined),
498
- }));
499
- }
500
- else {
501
- model = modelChoice;
502
- }
503
- }
504
- else {
505
- model = await prompt(() => p.text({
506
- message: "Model name:",
507
- placeholder: currentLmsModel ?? "local-model",
508
- ...(currentLmsModel ? { defaultValue: currentLmsModel } : {}),
509
- validate: (v) => (!v?.trim() ? "Model name cannot be empty" : undefined),
510
- }));
511
- }
512
- llm = {
513
- provider: "lmstudio",
514
- endpoint: endpoint.trim(),
515
- model: model.trim(),
516
- temperature: 0.3,
517
- maxTokens: 1024,
518
- };
352
+ const endpoint = await promptEndpointUrl({ placeholder: currentLmsEndpoint, defaultValue: currentLmsEndpoint });
353
+ const model = await promptLmStudioModel(lmStudio, currentLmsModel);
354
+ llm = llmConnection("lmstudio", endpoint.trim(), model.trim());
519
355
  }
520
356
  else {
521
357
  // custom
522
358
  const currentCustomEndpoint = currentLlmSmall?.provider === "custom" ? currentLlmSmall.endpoint : undefined;
523
359
  const currentCustomModel = currentLlmSmall?.provider === "custom" ? currentLlmSmall.model : undefined;
524
- const endpoint = await prompt(() => p.text({
360
+ const endpoint = await promptEndpointUrl({
525
361
  message: "OpenAI-compatible chat completions endpoint:",
526
362
  placeholder: currentCustomEndpoint ?? "https://your-host/v1/chat/completions",
527
- ...(currentCustomEndpoint ? { defaultValue: currentCustomEndpoint } : {}),
528
- validate: (v) => {
529
- if (!v?.trim())
530
- return "Endpoint cannot be empty";
531
- if (!v.startsWith("http://") && !v.startsWith("https://"))
532
- return "Must start with http:// or https://";
533
- },
534
- }));
535
- const model = await prompt(() => p.text({
536
- message: "Model name:",
363
+ defaultValue: currentCustomEndpoint,
364
+ });
365
+ const model = await promptModelName({
537
366
  placeholder: currentCustomModel ?? "gpt-4o-mini",
538
- ...(currentCustomModel ? { defaultValue: currentCustomModel } : {}),
539
- validate: (v) => (!v?.trim() ? "Model name cannot be empty" : undefined),
540
- }));
541
- const apiKeyInput = await promptOrBack(() => p.text({
542
- message: "API key (optional — press Enter to skip):",
543
- placeholder: "",
544
- }));
545
- llm = {
546
- provider: "custom",
547
- endpoint: endpoint.trim(),
548
- model: model.trim(),
549
- temperature: 0.3,
550
- maxTokens: 1024,
551
- ...(apiKeyInput?.trim() ? { apiKey: apiKeyInput.trim() } : {}),
552
- };
367
+ defaultValue: currentCustomModel,
368
+ });
369
+ const apiKeyInput = await promptApiKeyEnvVarName();
370
+ llm = llmConnection("custom", endpoint.trim(), model.trim(), apiKeyInput?.trim() ? { apiKey: `\${${apiKeyInput.trim()}}` } : {});
553
371
  }
554
372
  // Best-effort probe — never blocks setup.
555
- const probeSpin = p.spinner();
556
- probeSpin.start("Probing LLM (structured-output round-trip)...");
557
- const probe = await probeLlmCapabilities(llm);
558
- if (probe.reachable && probe.structuredOutput) {
559
- probeSpin.stop("LLM reachable; structured output verified.");
560
- llm.capabilities = { ...(llm.capabilities ?? {}), structuredOutput: true };
561
- }
562
- else if (probe.reachable) {
563
- probeSpin.stop("LLM reachable but structured-output probe failed.");
564
- llm.capabilities = { ...(llm.capabilities ?? {}), structuredOutput: false };
565
- }
566
- else {
567
- probeSpin.stop("LLM not reachable.");
568
- p.log.warn(`Could not reach the LLM endpoint${probe.error ? ` (${probe.error})` : ""}. Configuration was saved; verify your endpoint and API key, then retry.`);
569
- }
373
+ await probeLlmConnection(llm);
570
374
  return { llm, skipped: false, ollamaEndpoint };
571
375
  }
572
376
  /**
@@ -578,13 +382,13 @@ export async function stepAgentConnection(current, smallModel) {
578
382
  p.log.step("Step 2/2: Configure your agent connection");
579
383
  p.note([
580
384
  "This connection is used for agentic commands:",
581
- " • akm propose (generate improvement proposals)",
582
- " • akm improve (run the reflect/distill/consolidate self-improvement pipeline)",
583
- " • akm tasks run (run automated task prompts)",
385
+ " • akm proposal new (generate improvement proposals)",
386
+ " • akm improve (run the reflect/distill/consolidate self-improvement pipeline)",
387
+ " • akm task run (run automated task prompts)",
584
388
  ].join("\n"));
585
389
  // Detect available CLI agents.
586
390
  const detections = detectAgentCliProfiles(current);
587
- const currentAgentBlock = getCurrentAgentBlock(current);
391
+ const currentAgentBlock = readAgentEngineSelection(current);
588
392
  const availableClis = detections.filter((d) => d.available);
589
393
  const agentOptions = [];
590
394
  if (!smallModel.skipped && smallModel.llm) {
@@ -606,8 +410,8 @@ export async function stepAgentConnection(current, smallModel) {
606
410
  if (currentAgentBlock) {
607
411
  const currentDesc = currentAgentBlock.default
608
412
  ? `CLI: ${currentAgentBlock.default}`
609
- : currentAgentBlock.profiles?.default?.model
610
- ? `SDK: ${currentAgentBlock.profiles.default.model}`
413
+ : currentAgentBlock.engines?.default?.model
414
+ ? `SDK: ${currentAgentBlock.engines.default.model}`
611
415
  : "configured";
612
416
  agentOptions.push({ value: "keep", label: `Keep current: ${currentDesc}` });
613
417
  }
@@ -631,13 +435,13 @@ export async function stepAgentConnection(current, smallModel) {
631
435
  if (agentChoice === "none") {
632
436
  p.note([
633
437
  "Agentic features disabled:",
634
- ' • akm propose — will show "no agent configured" error',
438
+ ' • akm proposal new — will show "no agent configured" error',
635
439
  ' • akm improve — will show "no agent configured" error',
636
- ' • akm tasks run — will show "no agent configured" error',
440
+ ' • akm task run — will show "no agent configured" error',
637
441
  "",
638
442
  "You can configure this later with `akm setup`.",
639
443
  ].join("\n"), "Warning");
640
- return undefined;
444
+ return { disabled: true };
641
445
  }
642
446
  if (agentChoice === "same-connection") {
643
447
  if (smallModel.skipped || !smallModel.llm) {
@@ -647,24 +451,24 @@ export async function stepAgentConnection(current, smallModel) {
647
451
  else {
648
452
  const baseEndpoint = smallModel.llm.endpoint.replace("/v1/chat/completions", "");
649
453
  p.log.info(`Endpoint: ${baseEndpoint} (from Step 1)`);
650
- const profileName = smallModel.llm.provider ?? "default";
454
+ const profileName = `${smallModel.llm.provider ?? "default"}-agent`;
651
455
  // Pre-populate from existing agent profile for this provider, if any.
652
- const existingAgentModel = currentAgentBlock?.profiles?.[profileName]?.model ?? smallModel.llm.model ?? undefined;
653
- const agentModel = await prompt(() => p.text({
456
+ const existingAgentModel = currentAgentBlock?.engines?.[profileName]?.model ?? smallModel.llm.model ?? undefined;
457
+ const agentModel = await promptModelName({
654
458
  message: "Model to use for agent tasks (same model is fine, larger models work better):",
655
459
  placeholder: existingAgentModel ?? "qwen2.5-coder:32b",
656
- ...(existingAgentModel ? { defaultValue: existingAgentModel } : {}),
657
- validate: (v) => (!v?.trim() ? "Model name cannot be empty" : undefined),
658
- }));
460
+ defaultValue: existingAgentModel,
461
+ });
659
462
  return {
660
463
  ...(currentAgentBlock ?? {}),
661
- profiles: {
662
- ...(currentAgentBlock?.profiles ?? {}),
464
+ engines: {
465
+ ...(currentAgentBlock?.engines ?? {}),
663
466
  [profileName]: {
664
- ...(currentAgentBlock?.profiles?.[profileName] ?? {}),
665
- sdkMode: true,
467
+ ...(currentAgentBlock?.engines?.[profileName] ?? {}),
468
+ kind: "agent",
469
+ platform: "opencode-sdk",
666
470
  model: agentModel.trim(),
667
- endpoint: smallModel.llm.endpoint,
471
+ ...(current.defaults?.llmEngine ? { llmEngine: current.defaults.llmEngine } : {}),
668
472
  },
669
473
  },
670
474
  default: profileName,
@@ -693,42 +497,41 @@ export async function stepAgentConnection(current, smallModel) {
693
497
  }
694
498
  // "new-connection" (also fall-through from "same-provider" when Step 1 was skipped)
695
499
  // Pre-populate from current "custom" agent profile if available.
696
- const currentCustomAgentProfile = currentAgentBlock?.profiles?.custom;
697
- const currentNewEndpoint = currentCustomAgentProfile?.endpoint ?? undefined;
500
+ const currentCustomAgentProfile = currentAgentBlock?.engines?.["custom-agent"];
501
+ const currentNewEndpoint = undefined;
698
502
  const currentNewModel = currentCustomAgentProfile?.model ?? undefined;
699
- const newEndpoint = await prompt(() => p.text({
503
+ const newEndpoint = await promptEndpointUrl({
700
504
  message: "OpenAI-compatible chat completions endpoint:",
701
505
  placeholder: currentNewEndpoint ?? "https://your-host/v1/chat/completions",
702
- ...(currentNewEndpoint ? { defaultValue: currentNewEndpoint } : {}),
703
- validate: (v) => {
704
- if (!v?.trim())
705
- return "Endpoint cannot be empty";
706
- if (!v.startsWith("http://") && !v.startsWith("https://"))
707
- return "Must start with http:// or https://";
708
- },
709
- }));
710
- const newApiKeyInput = await promptOrBack(() => p.text({
711
- message: "API key (optional — press Enter to skip):",
712
- placeholder: "",
713
- }));
714
- const newModel = await prompt(() => p.text({
506
+ defaultValue: currentNewEndpoint,
507
+ });
508
+ const newApiKeyInput = await promptApiKeyEnvVarName();
509
+ const newModel = await promptModelName({
715
510
  message: "Model name (larger is better, e.g. gpt-4o):",
716
511
  placeholder: currentNewModel ?? "gpt-4o",
717
- ...(currentNewModel ? { defaultValue: currentNewModel } : {}),
718
- validate: (v) => (!v?.trim() ? "Model name cannot be empty" : undefined),
719
- }));
512
+ defaultValue: currentNewModel,
513
+ });
514
+ const llmEngineName = "custom-llm";
515
+ const agentEngineName = "custom-agent";
720
516
  const customProfile = {
721
- sdkMode: true,
722
- endpoint: newEndpoint.trim(),
517
+ kind: "agent",
518
+ platform: "opencode-sdk",
519
+ llmEngine: llmEngineName,
723
520
  model: newModel.trim(),
724
- ...(newApiKeyInput?.trim() ? { apiKey: newApiKeyInput.trim() } : {}),
725
521
  };
726
522
  return {
727
523
  ...(currentAgentBlock ?? {}),
728
- profiles: {
729
- ...(currentAgentBlock?.profiles ?? {}),
730
- custom: customProfile,
524
+ engines: {
525
+ ...(currentAgentBlock?.engines ?? {}),
526
+ [llmEngineName]: {
527
+ kind: "llm",
528
+ provider: "custom",
529
+ endpoint: newEndpoint.trim(),
530
+ model: newModel.trim(),
531
+ ...(newApiKeyInput?.trim() ? { apiKey: `\${${newApiKeyInput.trim()}}` } : {}),
532
+ },
533
+ [agentEngineName]: customProfile,
731
534
  },
732
- default: "custom",
535
+ default: agentEngineName,
733
536
  };
734
537
  }