akm-cli 0.10.261013-beta → 0.10.261014-beta

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 (477) hide show
  1. package/CHANGELOG.md +494 -3
  2. package/README.md +15 -0
  3. package/SECURITY.md +9 -8
  4. package/STABILITY.md +45 -49
  5. package/dist/assets/hints/cli-hints-full.md +15 -12
  6. package/dist/assets/opencode/akm-plugin.js +177 -0
  7. package/dist/assets/stash-skeleton/README.md +1 -1
  8. package/dist/assets/tasks/core/improve.yml +1 -1
  9. package/dist/assets/tasks/improve/akm-improve-consolidate.yml +1 -1
  10. package/dist/assets/ui/config.js +27 -10
  11. package/dist/assets/workflows/workflow-template.md +2 -2
  12. package/dist/cli/clack.js +3 -1
  13. package/dist/cli/selection.js +33 -0
  14. package/dist/cli/shared.js +14 -1
  15. package/dist/cli/unknown-flags.js +6 -37
  16. package/dist/cli.js +69 -48
  17. package/dist/commands/agent/agent-dispatch.js +17 -25
  18. package/dist/commands/agent/contribute-cli.js +9 -8
  19. package/dist/commands/command/command-cli.js +4 -8
  20. package/dist/commands/command/command-execution.js +25 -39
  21. package/dist/commands/completions.js +1 -1
  22. package/dist/commands/config-cli.js +14 -5
  23. package/dist/commands/env/child-env.js +12 -14
  24. package/dist/commands/env/env-cli.js +2 -2
  25. package/dist/commands/env/secret-cli.js +2 -2
  26. package/dist/commands/health/checks.js +10 -849
  27. package/dist/commands/health/connections-and-harnesses-check.js +109 -0
  28. package/dist/commands/health/egress.js +3 -3
  29. package/dist/commands/health/html-report.js +9 -10
  30. package/dist/commands/health/plugin-staleness.js +18 -11
  31. package/dist/commands/health/report-view-model.js +16 -12
  32. package/dist/commands/health/semantic-search-check.js +85 -0
  33. package/dist/commands/health/type-directory-check.js +0 -3
  34. package/dist/commands/health.js +30 -42
  35. package/dist/commands/improve/consolidate/pair-pass.js +10 -25
  36. package/dist/commands/improve/consolidate.js +10 -15
  37. package/dist/commands/improve/distill.js +5 -15
  38. package/dist/commands/improve/eligibility.js +1 -1
  39. package/dist/commands/improve/execution.js +37 -40
  40. package/dist/commands/improve/extract-cli.js +6 -11
  41. package/dist/commands/improve/extract-prompt.js +2 -2
  42. package/dist/commands/improve/extract.js +67 -97
  43. package/dist/commands/improve/improve-cli.js +22 -128
  44. package/dist/commands/improve/improve-report.js +1 -1
  45. package/dist/commands/improve/improve-strategies.js +25 -108
  46. package/dist/commands/improve/improve.js +10 -14
  47. package/dist/commands/improve/loop-stages.js +3 -0
  48. package/dist/commands/improve/memory/memory-improve.js +1 -1
  49. package/dist/commands/improve/preparation.js +8 -13
  50. package/dist/commands/improve/reflect.js +203 -332
  51. package/dist/commands/improve/retrieval-scope.js +1 -1
  52. package/dist/commands/improve/session-asset.js +3 -2
  53. package/dist/commands/improve/stage.js +87 -115
  54. package/dist/commands/lint/base-linter.js +3 -3
  55. package/dist/commands/lint/index.js +2 -2
  56. package/dist/commands/models-cli.js +103 -63
  57. package/dist/commands/proposal/drain.js +26 -39
  58. package/dist/commands/proposal/proposal-cli.js +14 -18
  59. package/dist/commands/proposal/propose-cli.js +4 -2
  60. package/dist/commands/proposal/propose.js +37 -64
  61. package/dist/commands/proposal/repository.js +17 -17
  62. package/dist/commands/proposal/validators/proposal-validators.js +2 -2
  63. package/dist/commands/read/curate.js +10 -6
  64. package/dist/commands/read/registry-search.js +2 -48
  65. package/dist/commands/read/search-cli.js +1 -8
  66. package/dist/commands/read/search.js +5 -6
  67. package/dist/commands/read/show.js +2 -4
  68. package/dist/commands/remember.js +25 -40
  69. package/dist/commands/sources/bundle-config-ops.js +2 -2
  70. package/dist/commands/sources/info.js +12 -1
  71. package/dist/commands/sources/init.js +1 -1
  72. package/dist/commands/sources/installed-stashes.js +2 -2
  73. package/dist/commands/sources/migration-help.js +1 -1
  74. package/dist/commands/sources/plugin-upgrade.js +8 -15
  75. package/dist/commands/sources/schema-repair.js +4 -8
  76. package/dist/commands/sources/source-add.js +2 -2
  77. package/dist/commands/sources/source-manage.js +4 -4
  78. package/dist/commands/targets.js +175 -0
  79. package/dist/commands/tasks/explain.js +103 -68
  80. package/dist/commands/tasks/tasks-cli.js +9 -11
  81. package/dist/commands/tasks/tasks.js +37 -41
  82. package/dist/commands/ui/api.js +11 -3
  83. package/dist/commands/ui/redact.js +1 -27
  84. package/dist/commands/ui/workspace-actions.js +1 -1
  85. package/dist/commands/workflow/plan.js +1 -1
  86. package/dist/commands/workflow-cli.js +3 -4
  87. package/dist/core/adapter/adapters/agent-skills-adapter.js +10 -11
  88. package/dist/core/adapter/adapters/akm-adapter.js +33 -38
  89. package/dist/core/adapter/adapters/akm-lint.js +7 -8
  90. package/dist/core/adapter/adapters/akm-task-adapter.js +3 -3
  91. package/dist/core/adapter/adapters/akm-workflow-adapter.js +5 -5
  92. package/dist/core/adapter/adapters/claude-adapter.js +1 -1
  93. package/dist/core/adapter/adapters/dotenv-adapter.js +3 -3
  94. package/dist/core/adapter/adapters/generic-files-adapter.js +5 -5
  95. package/dist/core/adapter/adapters/index.js +3 -4
  96. package/dist/core/adapter/adapters/llm-wiki-adapter.js +12 -14
  97. package/dist/core/adapter/adapters/okf-adapter.js +8 -10
  98. package/dist/core/adapter/adapters/opencode-adapter.js +1 -1
  99. package/dist/core/adapter/adapters/shared.js +3 -3
  100. package/dist/core/adapter/adapters/tool-dir-shared.js +7 -25
  101. package/dist/core/adapter/adapters/website-snapshot-adapter.js +3 -3
  102. package/dist/core/adapter/detect-adapter.js +1 -1
  103. package/dist/core/adapter/execution-source.js +13 -35
  104. package/dist/core/adapter/registry.js +1 -1
  105. package/dist/core/adapter/validate-context.js +2 -4
  106. package/dist/core/asset/asset-placement.js +1 -1
  107. package/dist/core/asset/asset-ref.js +3 -3
  108. package/dist/core/closest-match.js +37 -0
  109. package/dist/core/common.js +33 -5
  110. package/dist/core/config/config-io.js +26 -18
  111. package/dist/core/config/config-schema.js +19 -106
  112. package/dist/core/config/config-sources.js +3 -3
  113. package/dist/core/config/config-types.js +4 -4
  114. package/dist/core/config/config-walker.js +50 -77
  115. package/dist/core/config/config.js +385 -93
  116. package/dist/core/config/convert-engine-references.js +114 -0
  117. package/dist/core/config/convert-engines-shared.js +40 -0
  118. package/dist/core/config/convert-engines.js +300 -0
  119. package/dist/core/config/convert-models-overlay.js +137 -0
  120. package/dist/core/config/credentials.js +304 -0
  121. package/dist/core/config/engine-semantics.js +3 -3
  122. package/dist/core/config/migrate-keys.js +222 -0
  123. package/dist/core/config/model-aliases.js +37 -0
  124. package/dist/core/config/models-file.js +34 -0
  125. package/dist/core/config/retired-engines.js +53 -0
  126. package/dist/core/config/schema/connections.js +41 -0
  127. package/dist/core/config/schema/embedding.js +2 -2
  128. package/dist/core/config/schema/harnesses.js +41 -0
  129. package/dist/core/config/schema/improve-processes.js +9 -28
  130. package/dist/core/config/schema/improve.js +36 -1
  131. package/dist/core/config/schema/index-config.js +18 -20
  132. package/dist/core/config/schema/primitives.js +41 -22
  133. package/dist/core/config/schema/search.js +6 -11
  134. package/dist/core/config/schema/sources-bundles.js +7 -7
  135. package/dist/core/config/schema/workflow.js +2 -6
  136. package/dist/core/config/unusable-entries.js +66 -0
  137. package/dist/core/content-safety.js +3 -6
  138. package/dist/core/endpoint-url.js +47 -0
  139. package/dist/core/errors.js +9 -15
  140. package/dist/core/extra-params.js +3 -3
  141. package/dist/core/improve-result.js +8 -9
  142. package/dist/core/json-schema.js +1 -1
  143. package/dist/core/lesson-lint.js +1 -1
  144. package/dist/core/llm-inference.js +80 -0
  145. package/dist/core/parse.js +2 -2
  146. package/dist/core/paths.js +32 -4
  147. package/dist/core/recognition-util.js +8 -10
  148. package/dist/core/redaction.js +78 -52
  149. package/dist/core/state/migrations.js +17 -22
  150. package/dist/core/structured.js +2 -68
  151. package/dist/core/subprocess.js +63 -22
  152. package/dist/core/type-presentation.js +10 -14
  153. package/dist/execution/input-contract.js +3 -6
  154. package/dist/execution/notices.js +49 -0
  155. package/dist/execution/resolved-request.js +24 -40
  156. package/dist/execution/source.js +21 -45
  157. package/dist/execution/target-ref.js +2 -2
  158. package/dist/indexer/bundle-identity-guard.js +6 -5
  159. package/dist/indexer/ensure-index.js +1 -1
  160. package/dist/indexer/index-writer-lock.js +1 -1
  161. package/dist/indexer/indexer.js +19 -6
  162. package/dist/indexer/installations.js +11 -14
  163. package/dist/indexer/materialize-embeddings.js +20 -16
  164. package/dist/indexer/passes/memory-inference.js +21 -50
  165. package/dist/indexer/passes/metadata.js +5 -5
  166. package/dist/indexer/scan/doc-to-entry.js +1 -1
  167. package/dist/indexer/scan/drain-dir.js +6 -8
  168. package/dist/indexer/search/db-search.js +9 -7
  169. package/dist/indexer/search/search-source.js +40 -22
  170. package/dist/indexer/usage/usage-events.js +2 -3
  171. package/dist/indexer/walk/index-context.js +2 -1
  172. package/dist/indexer/walk/matchers.js +3 -11
  173. package/dist/indexer/walk/walker.js +14 -4
  174. package/dist/integrations/agent/akm-read-tools.js +81 -0
  175. package/dist/integrations/agent/config.js +1 -1
  176. package/dist/integrations/agent/detect.js +32 -36
  177. package/dist/integrations/agent/execution.js +130 -428
  178. package/dist/integrations/agent/index.js +1 -1
  179. package/dist/integrations/agent/profiles.js +24 -28
  180. package/dist/integrations/agent/prompts.js +17 -30
  181. package/dist/integrations/agent/request-lowering.js +67 -101
  182. package/dist/integrations/agent/resolution.js +332 -0
  183. package/dist/integrations/agent/runner-dispatch.js +154 -178
  184. package/dist/integrations/agent/runner.js +20 -72
  185. package/dist/integrations/agent/runtime-port.js +4 -0
  186. package/dist/integrations/agent/runtime.js +10 -0
  187. package/dist/integrations/agent/spawn.js +65 -190
  188. package/dist/integrations/harnesses/aider/index.js +19 -39
  189. package/dist/integrations/harnesses/amazonq/index.js +17 -32
  190. package/dist/integrations/harnesses/claude/index.js +59 -28
  191. package/dist/integrations/harnesses/claude/session-log.js +7 -5
  192. package/dist/integrations/harnesses/codex/index.js +19 -31
  193. package/dist/integrations/harnesses/copilot/index.js +17 -35
  194. package/dist/integrations/harnesses/gemini/index.js +18 -34
  195. package/dist/integrations/harnesses/harness.js +36 -0
  196. package/dist/integrations/harnesses/index.js +20 -51
  197. package/dist/integrations/harnesses/opencode/agent-builder.js +132 -100
  198. package/dist/integrations/harnesses/opencode/index.js +11 -33
  199. package/dist/integrations/harnesses/opencode/roots.js +50 -0
  200. package/dist/integrations/harnesses/opencode/runtime/binary.js +206 -0
  201. package/dist/integrations/harnesses/opencode/runtime/command.js +152 -0
  202. package/dist/integrations/harnesses/opencode/runtime/index.js +177 -0
  203. package/dist/integrations/harnesses/opencode/runtime/tar.js +107 -0
  204. package/dist/integrations/harnesses/opencode/session-log-v1.js +15 -7
  205. package/dist/integrations/harnesses/opencode/session-log-v2.js +72 -48
  206. package/dist/integrations/harnesses/opencode/session-log.js +58 -137
  207. package/dist/integrations/harnesses/opencode/version.js +34 -53
  208. package/dist/integrations/harnesses/openhands/index.js +13 -37
  209. package/dist/integrations/harnesses/pi/index.js +21 -32
  210. package/dist/integrations/lockfile.js +1 -1
  211. package/dist/integrations/session-logs/index.js +11 -31
  212. package/dist/llm/client.js +93 -111
  213. package/dist/llm/embedder.js +19 -34
  214. package/dist/llm/embedders/connection.js +31 -0
  215. package/dist/llm/embedders/local-model-files.js +56 -0
  216. package/dist/llm/embedders/local.js +146 -115
  217. package/dist/llm/embedders/remote.js +26 -24
  218. package/dist/llm/embedders/types.js +1 -1
  219. package/dist/llm/index-passes.js +33 -39
  220. package/dist/llm/memory-infer.js +67 -77
  221. package/dist/llm/model-list.js +35 -0
  222. package/dist/llm/rerank-client.js +8 -14
  223. package/dist/llm/structured-call.js +45 -99
  224. package/dist/llm/structured.js +60 -0
  225. package/dist/output/renderers.js +2 -7
  226. package/dist/output/shapes/helpers.js +18 -42
  227. package/dist/output/shapes/passthrough.js +1 -0
  228. package/dist/output/shapes.js +1 -7
  229. package/dist/output/text/command-format.js +29 -37
  230. package/dist/output/text/health-format.js +8 -2
  231. package/dist/output/text/helpers.js +1 -1
  232. package/dist/output/text/migrate.js +12 -0
  233. package/dist/output/text/models.js +3 -2
  234. package/dist/output/text/registry-commands.js +1 -2
  235. package/dist/output/text/show-format.js +0 -2
  236. package/dist/output/text/targets-table.js +70 -0
  237. package/dist/output/text/workflow-format.js +7 -8
  238. package/dist/output/text.js +1 -1
  239. package/dist/registry/providers/skills-sh.js +1 -28
  240. package/dist/registry/providers/static-index.js +1 -71
  241. package/dist/runtime.js +6 -2
  242. package/dist/scripts/akm-migrate-node.js +5280 -4263
  243. package/dist/scripts/akm-migrate.js +5280 -4263
  244. package/dist/setup/detect.js +28 -273
  245. package/dist/setup/endpoint.js +36 -0
  246. package/dist/setup/semantic-assets.js +13 -19
  247. package/dist/setup/setup-flags.js +77 -0
  248. package/dist/setup/setup-plan.js +144 -0
  249. package/dist/setup/setup.js +134 -358
  250. package/dist/setup/steps/connection-shared.js +49 -101
  251. package/dist/setup/steps/connection.js +121 -524
  252. package/dist/setup/steps/embeddings.js +151 -0
  253. package/dist/setup/steps/harnesses.js +118 -0
  254. package/dist/setup/steps/platforms.js +2 -81
  255. package/dist/setup/steps.js +10 -0
  256. package/dist/setup/summary.js +67 -0
  257. package/dist/sources/freshness.js +16 -21
  258. package/dist/sources/providers/git-provider.js +2 -9
  259. package/dist/sources/providers/provider-utils.js +1 -5
  260. package/dist/sources/snapshot-fetchers/robots.js +11 -12
  261. package/dist/sources/snapshot-fetchers/website-ingest.js +8 -15
  262. package/dist/standalone/onnxruntime-library.js +52 -0
  263. package/dist/storage/repositories/improve-ledger-repository.js +1 -1
  264. package/dist/storage/repositories/improve-runs-repository.js +0 -13
  265. package/dist/storage/repositories/index-entries-repository.js +2 -2
  266. package/dist/storage/repositories/workflow-runs-repository.js +8 -15
  267. package/dist/storage/sqlite-read-snapshot.js +33 -29
  268. package/dist/tasks/log-redaction.js +7 -119
  269. package/dist/tasks/prepare/prepare-support.js +5 -5
  270. package/dist/tasks/prepare/prepare.js +5 -5
  271. package/dist/tasks/prepare/script-capture.js +3 -5
  272. package/dist/tasks/run/attempt-lifecycle.js +17 -35
  273. package/dist/tasks/run/load-task.js +8 -13
  274. package/dist/tasks/run/run-command-task.js +15 -10
  275. package/dist/tasks/run/run-native-task.js +8 -13
  276. package/dist/tasks/run/run-task.js +5 -8
  277. package/dist/tasks/run/run-workflow-task.js +12 -19
  278. package/dist/tasks/run/task-history.js +9 -17
  279. package/dist/tasks/run/task-log.js +1 -5
  280. package/dist/tasks/scheduler-invocation.js +13 -18
  281. package/dist/tasks/source/bounded-document.js +31 -76
  282. package/dist/tasks/source/project-v4.js +5 -3
  283. package/dist/tasks/source/task-input-diagnostics.js +3 -4
  284. package/dist/tasks/source/task-source-v4.js +47 -68
  285. package/dist/tasks/source-v3.js +2 -5
  286. package/dist/tasks/task-run-reserved-flags.js +1 -2
  287. package/dist/workflows/authoring/authoring.js +2 -7
  288. package/dist/workflows/concurrency-policy.js +4 -4
  289. package/dist/workflows/exec/child-workflow.js +0 -2
  290. package/dist/workflows/exec/dispatch-redaction.js +14 -83
  291. package/dist/workflows/exec/environment.js +2 -3
  292. package/dist/workflows/exec/exec-unit.js +10 -59
  293. package/dist/workflows/exec/frozen-judge.js +10 -26
  294. package/dist/workflows/exec/native-executor.js +56 -45
  295. package/dist/workflows/exec/run-workflow.js +7 -24
  296. package/dist/workflows/exec/step-work.js +9 -14
  297. package/dist/workflows/exec/unit-dispatch.js +6 -13
  298. package/dist/workflows/freeze/freeze.js +14 -32
  299. package/dist/workflows/freeze/step-values.js +5 -11
  300. package/dist/workflows/freeze/targets/command.js +3 -6
  301. package/dist/workflows/freeze/task-bindings.js +0 -1
  302. package/dist/workflows/parser.js +44 -34
  303. package/dist/workflows/plan.js +3 -1
  304. package/dist/workflows/renderer.js +6 -5
  305. package/dist/workflows/resource-limits.js +2 -2
  306. package/dist/workflows/runtime/run-plan.js +2 -1
  307. package/dist/workflows/runtime/runs.js +14 -9
  308. package/docs/README.md +10 -16
  309. package/docs/architecture/README.md +2 -37
  310. package/docs/architecture/adapters.md +2 -2
  311. package/docs/architecture/akm-core-principles.md +256 -118
  312. package/docs/architecture/architecture.md +282 -98
  313. package/docs/architecture/improvement.md +8 -2
  314. package/docs/architecture/internals/classification.md +1 -3
  315. package/docs/architecture/internals/fresh-host-rebuild-runbook.md +7 -6
  316. package/docs/architecture/internals/health-advisories.md +35 -74
  317. package/docs/architecture/internals/improve-workflow.md +27 -26
  318. package/docs/architecture/internals/indexing.md +3 -3
  319. package/docs/architecture/internals/storage-locations.md +45 -12
  320. package/docs/architecture/persisted-data-compat.md +9 -6
  321. package/docs/architecture/specs/okf-support.md +9 -11
  322. package/docs/architecture/specs/ref.md +7 -9
  323. package/docs/architecture/testing/testing-workflow.md +164 -42
  324. package/docs/architecture/workflow-engine.md +17 -14
  325. package/docs/guides/README.md +0 -1
  326. package/docs/guides/author-bundles.md +1 -3
  327. package/docs/guides/author-workflows.md +61 -73
  328. package/docs/guides/bundles.md +4 -5
  329. package/docs/guides/discover-and-load.md +1 -1
  330. package/docs/guides/getting-started.md +49 -3
  331. package/docs/guides/improve-the-library.md +10 -4
  332. package/docs/guides/recipes/headless-install.md +11 -16
  333. package/docs/guides/run-workflows.md +6 -9
  334. package/docs/guides/scheduling.md +2 -2
  335. package/docs/guides/use-with-any-agent.md +20 -22
  336. package/docs/integration/bundling-akm.md +19 -9
  337. package/docs/maintainers/README.md +0 -3
  338. package/docs/migration/README.md +10 -3
  339. package/docs/migration/release-notes/0.10.0.md +81 -16
  340. package/docs/migration/release-notes/0.6.0.md +1 -1
  341. package/docs/migration/release-notes/0.7.0.md +1 -1
  342. package/docs/migration/release-notes/0.9.0.md +1 -1
  343. package/docs/migration/release-notes/README.md +1 -1
  344. package/docs/migration/v0.9-to-v0.10.md +295 -59
  345. package/docs/migration/v0.9.1-to-v0.9.2.md +6 -5
  346. package/docs/posts/config-v2-lessons-16.md +1 -1
  347. package/docs/posts/llm-mode-reflect-13.md +1 -1
  348. package/docs/posts/release-0.6.0.md +11 -11
  349. package/docs/posts/release-0.8.0.md +4 -4
  350. package/docs/posts/workflows-vaults-09.md +1 -1
  351. package/docs/reference/README.md +1 -1
  352. package/docs/reference/asset-types.md +2 -2
  353. package/docs/reference/cli.md +356 -279
  354. package/docs/reference/configuration.md +569 -557
  355. package/docs/reference/data-and-telemetry.md +8 -5
  356. package/docs/reference/env-and-secrets.md +11 -5
  357. package/docs/reference/refs.md +3 -20
  358. package/docs/reference/registry.md +6 -27
  359. package/docs/reference/supported-formats.md +1 -1
  360. package/docs/reference/tasks.md +11 -8
  361. package/docs/reference/ui-api.md +11 -6
  362. package/docs/reference/workflow-schema.md +106 -134
  363. package/docs/reference/workflows.md +4 -6
  364. package/package.json +9 -11
  365. package/schemas/akm-config.json +1696 -2922
  366. package/schemas/akm-task.json +2 -0
  367. package/schemas/akm-workflow.json +36 -9
  368. package/ROADMAP.md +0 -112
  369. package/dist/assets/models.json +0 -35
  370. package/dist/commands/health/engine-usage.js +0 -45
  371. package/dist/core/config/schema/engines.js +0 -160
  372. package/dist/core/config/schema/execution.js +0 -23
  373. package/dist/core/spawn-env.js +0 -268
  374. package/dist/integrations/agent/builder-shared.js +0 -33
  375. package/dist/integrations/agent/builders.js +0 -43
  376. package/dist/integrations/agent/engine-fallback.js +0 -59
  377. package/dist/integrations/agent/engine-resolution.js +0 -335
  378. package/dist/integrations/agent/model-map.js +0 -475
  379. package/dist/integrations/harnesses/aider/agent-builder.js +0 -107
  380. package/dist/integrations/harnesses/aider/result-extractor.js +0 -53
  381. package/dist/integrations/harnesses/amazonq/agent-builder.js +0 -138
  382. package/dist/integrations/harnesses/amazonq/result-extractor.js +0 -48
  383. package/dist/integrations/harnesses/claude/agent-builder.js +0 -106
  384. package/dist/integrations/harnesses/claude/config-import.js +0 -67
  385. package/dist/integrations/harnesses/claude/result-extractor.js +0 -67
  386. package/dist/integrations/harnesses/codex/agent-builder.js +0 -150
  387. package/dist/integrations/harnesses/codex/result-extractor.js +0 -110
  388. package/dist/integrations/harnesses/copilot/agent-builder.js +0 -117
  389. package/dist/integrations/harnesses/copilot/result-extractor.js +0 -178
  390. package/dist/integrations/harnesses/gemini/agent-builder.js +0 -114
  391. package/dist/integrations/harnesses/gemini/result-extractor.js +0 -149
  392. package/dist/integrations/harnesses/opencode/config-import.js +0 -149
  393. package/dist/integrations/harnesses/opencode/model-config.js +0 -33
  394. package/dist/integrations/harnesses/opencode/model-work-agent.js +0 -115
  395. package/dist/integrations/harnesses/opencode/session-log-types.js +0 -12
  396. package/dist/integrations/harnesses/opencode-sdk/index.js +0 -44
  397. package/dist/integrations/harnesses/opencode-sdk/sdk-runner.js +0 -1052
  398. package/dist/integrations/harnesses/opencode-sdk/v1-adapter.js +0 -199
  399. package/dist/integrations/harnesses/opencode-sdk/v2-adapter.js +0 -254
  400. package/dist/integrations/harnesses/opencode-sdk/wire.js +0 -66
  401. package/dist/integrations/harnesses/openhands/agent-builder.js +0 -120
  402. package/dist/integrations/harnesses/openhands/result-extractor.js +0 -135
  403. package/dist/integrations/harnesses/pi/agent-builder.js +0 -89
  404. package/dist/integrations/harnesses/pi/result-extractor.js +0 -168
  405. package/dist/integrations/harnesses/shared.js +0 -18
  406. package/dist/integrations/harnesses/types.js +0 -55
  407. package/dist/llm/feature-gate.js +0 -115
  408. package/dist/output/shapes/models-list.js +0 -16
  409. package/dist/output/shapes/registry-search.js +0 -10
  410. package/dist/setup/detected-engines.js +0 -136
  411. package/dist/setup/engine-config.js +0 -97
  412. package/dist/setup/harness-config-import.js +0 -47
  413. package/dist/setup/providers.js +0 -14
  414. package/dist/setup/steps/semantic.js +0 -39
  415. package/dist/workflows/exec/lowering-notices.js +0 -23
  416. package/docs/architecture/0.10-process-rules.md +0 -832
  417. package/docs/architecture/akm-architecture-decision-history.md +0 -2055
  418. package/docs/architecture/comparisons/claude-code-vs-akm-workflows-full.md +0 -544
  419. package/docs/architecture/decisions/0001-no-interpolation-attached-structured-context.md +0 -72
  420. package/docs/architecture/decisions/0002-unit-reuse-and-input-hash-scope.md +0 -142
  421. package/docs/architecture/decisions/0003-child-env-allowlist-and-provenance.md +0 -187
  422. package/docs/architecture/decisions/0004-task-input-contract-and-flag-coercion.md +0 -97
  423. package/docs/architecture/decisions/0005-task-result-vocabulary-and-legacy-read-mapping.md +0 -108
  424. package/docs/architecture/decisions/0006-task-source-version-routing.md +0 -124
  425. package/docs/architecture/decisions/0007-workflow-composition-bounds.md +0 -83
  426. package/docs/architecture/decisions/0008-task-binding-normalization.md +0 -88
  427. package/docs/architecture/decisions/0009-child-run-publication-column-parity.md +0 -80
  428. package/docs/architecture/decisions/0010-driver-protocol-cut.md +0 -36
  429. package/docs/architecture/decisions/0011-engine-run-loop-invariants.md +0 -125
  430. package/docs/architecture/decisions/README.md +0 -62
  431. package/docs/architecture/internals/functional-contract-patterns.md +0 -340
  432. package/docs/architecture/internals/registry-network-boundary.md +0 -57
  433. package/docs/architecture/internals/search.md +0 -248
  434. package/docs/architecture/reviews/env-secret-access.md +0 -319
  435. package/docs/architecture/runtime-boundary-design.md +0 -153
  436. package/docs/architecture/specs/0.9.0-close-out-plan.md +0 -361
  437. package/docs/architecture/specs/0.9.0-decisions.md +0 -532
  438. package/docs/architecture/specs/0.9.0-docs-code-drift-register.md +0 -745
  439. package/docs/architecture/specs/0.9.0-open-items-register.md +0 -135
  440. package/docs/architecture/specs/0.9.0-public-api-issue-backlog.md +0 -740
  441. package/docs/architecture/specs/0.9.0-release-surface-review.md +0 -636
  442. package/docs/architecture/specs/agent-command-engine-model-design.md +0 -513
  443. package/docs/architecture/specs/akm-0.9.0-bundle-adapter-spec.md +0 -501
  444. package/docs/architecture/specs/akm-0.9.0-ref-grammar-decision.md +0 -291
  445. package/docs/architecture/specs/akm-format-neutral-bundle-workspace-spec.md +0 -2059
  446. package/docs/architecture/specs/di-seams-plan.md +0 -539
  447. package/docs/architecture/specs/driver-protocol-keep-or-cut.md +0 -275
  448. package/docs/architecture/specs/fact-asset-type.md +0 -142
  449. package/docs/architecture/specs/improve-collapse-churn-detector-design.md +0 -634
  450. package/docs/architecture/specs/reviews/task-workflow-unification/README.md +0 -72
  451. package/docs/architecture/specs/reviews/task-workflow-unification/findings-consolidated.md +0 -152
  452. package/docs/architecture/specs/reviews/task-workflow-unification/library-eval-alternatives.md +0 -352
  453. package/docs/architecture/specs/reviews/task-workflow-unification/library-eval-bunqueue.md +0 -300
  454. package/docs/architecture/specs/reviews/task-workflow-unification/library-eval-openworkflow.md +0 -402
  455. package/docs/architecture/specs/reviews/task-workflow-unification/opus-review-1.md +0 -758
  456. package/docs/architecture/specs/reviews/task-workflow-unification/opus-review-2.md +0 -645
  457. package/docs/architecture/specs/reviews/task-workflow-unification/opus-review-3.md +0 -602
  458. package/docs/architecture/specs/reviews/task-workflow-unification/panel-r1-adversarial.md +0 -27
  459. package/docs/architecture/specs/reviews/task-workflow-unification/panel-r1-architecture.md +0 -27
  460. package/docs/architecture/specs/reviews/task-workflow-unification/panel-r1-coverage.md +0 -74
  461. package/docs/architecture/specs/reviews/task-workflow-unification/panel-r1-security.md +0 -15
  462. package/docs/architecture/specs/reviews/task-workflow-unification/panel-r2-adversarial.md +0 -132
  463. package/docs/architecture/specs/reviews/task-workflow-unification/panel-r2-verification.md +0 -147
  464. package/docs/architecture/specs/stash-conventions-code-spec.md +0 -275
  465. package/docs/architecture/specs/stash-organization-conventions.md +0 -377
  466. package/docs/architecture/specs/task-workflow-format-unification.md +0 -721
  467. package/docs/architecture/specs/workflow-engine-buy-vs-build.md +0 -231
  468. package/docs/architecture/specs/workflow-format-unification.md +0 -432
  469. package/docs/architecture/testing/manual-testing-checklist.md +0 -3379
  470. package/docs/architecture/testing/okf-v0.2-conformance-runbook.md +0 -924
  471. package/docs/architecture/testing/task-workflow-manual-tests.md +0 -1702
  472. package/docs/guides/claude-code-vs-akm-workflows.md +0 -29
  473. package/docs/guides/knowledge-management.md +0 -18
  474. package/docs/maintainers/curate-workmap.md +0 -335
  475. package/docs/migration/v0.5-to-v0.6.md +0 -759
  476. package/docs/migration/v0.7-to-v0.8.md +0 -1378
  477. package/docs/plans/0.9.2-agent-command-workflow-plan.md +0 -423
@@ -0,0 +1,109 @@
1
+ // This Source Code Form is subject to the terms of the Mozilla Public
2
+ // License, v. 2.0. If a copy of the MPL was not distributed with this
3
+ // file, You can obtain one at https://mozilla.org/MPL/2.0/.
4
+ /**
5
+ * The `connections-and-harnesses` health check: the table of connections, harnesses and the work
6
+ * that runs on them (`../targets.ts`), with what only health asks for added to
7
+ * it. Whether a connection's endpoint answers is one bounded `GET /models`,
8
+ * once per distinct endpoint; a harness's version is its own `--version`, one
9
+ * process per harness. Both are probes: with `--no-probe` neither the endpoints
10
+ * are contacted nor any harness run.
11
+ */
12
+ import { spawnSync } from "node:child_process";
13
+ import { ambiguousDefaultAdvice, loadConfig } from "../../core/config/config.js";
14
+ import { defaultWhich, probeVersion } from "../../integrations/agent/detect.js";
15
+ import { resolveTarget } from "../../integrations/agent/resolution.js";
16
+ import { probeEndpointOnce } from "../../llm/client.js";
17
+ import { targetRows } from "../targets.js";
18
+ const VERSION_TIMEOUT_MS = 5_000;
19
+ /** Each connection's reachability, asked once per distinct endpoint. */
20
+ async function probeConnections(config, probe) {
21
+ const cache = new Map();
22
+ const entries = await Promise.all(Object.entries(config.connections ?? {}).map(async ([name, connection]) => [name, await probeEndpointOnce(connection, cache, probe)]));
23
+ return new Map(entries);
24
+ }
25
+ /** Each installed harness's `--version`, its first line; none when it will not say. */
26
+ function harnessVersions(config, which, spawn) {
27
+ const versions = new Map();
28
+ for (const name of Object.keys(config.harnesses ?? {})) {
29
+ try {
30
+ const target = resolveTarget({ config, layers: [{ harness: name }] });
31
+ if (target.kind !== "harness" || !which(target.bin))
32
+ continue;
33
+ const version = probeVersion(target.bin, VERSION_TIMEOUT_MS, spawn);
34
+ if (version !== undefined)
35
+ versions.set(name, version.split("\n")[0] || undefined);
36
+ }
37
+ catch {
38
+ // A harness that cannot be resolved or run has no version to report.
39
+ }
40
+ }
41
+ return versions;
42
+ }
43
+ /** What is wrong in the table, one phrase each. A key variable's name is never quoted. */
44
+ function problems(rows, ambiguous) {
45
+ // No default among several connections or harnesses is the config's problem, said once whatever work it leaves
46
+ // without a place to run (work may still find one: model work falls to a harness).
47
+ const found = ambiguous ? [ambiguous] : [];
48
+ // A problem that several kinds of work share is said once.
49
+ const shared = new Map();
50
+ for (const row of rows) {
51
+ if (row.type === "connection") {
52
+ if (row.key === "env-unset")
53
+ found.push(`connection "${row.name}": the variable holding its key is not set`);
54
+ if (row.reachable === false) {
55
+ found.push(`connection "${row.name}" is not reachable${row.error ? ` (${row.error})` : ""}`);
56
+ }
57
+ }
58
+ else if (row.type === "harness") {
59
+ if (!row.installed)
60
+ found.push(`harness "${row.name}" (${row.platform}) was not found on PATH`);
61
+ }
62
+ else if (row.problem) {
63
+ const problem = row.problem.replace(/\.$/, "");
64
+ if (problem !== ambiguous)
65
+ shared.set(problem, [...(shared.get(problem) ?? []), row.process]);
66
+ }
67
+ }
68
+ for (const [problem, processes] of shared)
69
+ found.push(`${processes.join(", ")}: ${problem}`);
70
+ return found;
71
+ }
72
+ /** The check for a table. `unknown` when nothing is configured: there is nothing to be wrong. */
73
+ export function connectionsAndHarnessesCheck(rows, probed, ambiguous) {
74
+ const connections = rows.filter((row) => row.type === "connection").length;
75
+ const harnesses = rows.filter((row) => row.type === "harness").length;
76
+ const base = {
77
+ name: "connections-and-harnesses",
78
+ kind: "deterministic",
79
+ confidence: "high",
80
+ evidence: { rows },
81
+ };
82
+ if (connections + harnesses === 0) {
83
+ return {
84
+ ...base,
85
+ status: "unknown",
86
+ message: "No connection or harness is configured: model features and agentic work are off. Run `akm setup`.",
87
+ };
88
+ }
89
+ const found = problems(rows, ambiguous);
90
+ const counts = `${connections} connection${connections === 1 ? "" : "s"} and ${harnesses} harness${harnesses === 1 ? "" : "es"}`;
91
+ const notProbed = connections > 0 && !probed ? " Reachability was not probed." : "";
92
+ return {
93
+ ...base,
94
+ status: found.length > 0 ? "warn" : "pass",
95
+ message: found.length > 0 ? `${counts}: ${found.join("; ")}.${notProbed}` : `${counts}, all ready.${notProbed}`,
96
+ };
97
+ }
98
+ export async function runConnectionsAndHarnessesCheck(deps = {}) {
99
+ const config = deps.loadConfig?.() ?? loadConfig();
100
+ const which = deps.which ?? defaultWhich;
101
+ const reachability = deps.probeReachable ? await probeConnections(config, deps.probeReachable) : undefined;
102
+ const rows = targetRows({
103
+ config,
104
+ env: deps.env,
105
+ which,
106
+ ...(reachability ? { reachability, versions: harnessVersions(config, which, deps.spawnSync ?? spawnSync) } : {}),
107
+ });
108
+ return connectionsAndHarnessesCheck(rows, reachability !== undefined, ambiguousDefaultAdvice(config));
109
+ }
@@ -34,10 +34,10 @@ export function collectEgressAdvisory(config) {
34
34
  continue;
35
35
  endpoints.push(`source ${key} (${bundle.git ? "git" : "website"}): ${url}`);
36
36
  }
37
- for (const [name, engine] of Object.entries(config.engines ?? {})) {
38
- if (engine?.kind !== "llm" || !engine.endpoint)
37
+ for (const [name, connection] of Object.entries(config.connections ?? {})) {
38
+ if (!connection?.endpoint)
39
39
  continue;
40
- endpoints.push(`llm ${name}: ${engine.endpoint}`);
40
+ endpoints.push(`connection ${name}: ${connection.endpoint}`);
41
41
  }
42
42
  if (config.embedding?.endpoint)
43
43
  endpoints.push(`embedding: ${config.embedding.endpoint}`);
@@ -156,7 +156,7 @@ function renderExecSummary(vm) {
156
156
  li("Stash derived", `<abbr title="Whole-stash recount of derived assets at report time — not a per-run sum.">${num(vm.memorySummary.derived)}</abbr>`),
157
157
  li("Stash eligible", `<abbr title="Whole-stash recount of eligible assets at report time — not a per-run sum.">${num(vm.memorySummary.eligible)}</abbr>`),
158
158
  li("Pending proposals", String(vm.proposals.length)),
159
- li("Semantic search", vm.sem.blocked ? "BLOCKED" : "OK"),
159
+ li("Semantic search", vm.sem.label),
160
160
  ].join("");
161
161
  const overallEmoji = vm.trend.overall === "improving" ? "📈" : vm.trend.overall === "degrading" ? "📉" : "↔️";
162
162
  const verdictSentence = `${vm.verdictWord} — ${esc(vm.verdictRest)}.`;
@@ -199,9 +199,8 @@ function renderExecSummary(vm) {
199
199
  * last).
200
200
  */
201
201
  function renderKpiCards(vm) {
202
- const semValue = vm.sem.blocked ? "BLOCKED" : "OK";
203
- const semColor = vm.sem.blocked ? "red" : "green";
204
- const semStyle = vm.sem.blocked ? "font-size:18px;" : "";
202
+ const semColor = { pass: "green", warn: "yellow", fail: "red", unknown: "neutral" }[vm.sem.status];
203
+ const semStyle = vm.sem.label.length > 3 ? "font-size:18px;" : "";
205
204
  const completionColor = vm.completionPct >= 99 ? "green" : vm.completionPct >= 90 ? "yellow" : "red";
206
205
  const kpiCard = (color, label, value, sub, valueStyle = "") => `<div class="kpi-card ${color}">
207
206
  <div class="label">${label}</div>
@@ -217,7 +216,7 @@ function renderKpiCards(vm) {
217
216
  kpiCard("neutral", "Stash Derived", num(vm.memorySummary.derived), `of ${num(vm.memorySummary.eligible)} eligible (whole-stash)`),
218
217
  // #576: real LLM work — duration leads, tokens compact, not a GPU proxy.
219
218
  kpiCard(vm.llm.calls > 0 ? "purple" : "neutral", "🧠 LLM Work", `${vm.llmTokensCompact} tok`, `${fmtMs(vm.llm.totalDurationMs)} · ${num(vm.llm.calls)} calls · ${compact(vm.llm.reasoningTokens)} reasoning`),
220
- kpiCard(semColor, "Semantic Search", semValue, esc(vm.sem.detail), semStyle),
219
+ kpiCard(semColor, "Semantic Search", vm.sem.label, esc(vm.sem.detail), semStyle),
221
220
  kpiCard(vm.proposals.length > 0 ? "yellow" : "neutral", "Pending Proposals", String(vm.proposals.length), `from ${esc(vm.window)} batch`),
222
221
  ].join("\n");
223
222
  }
@@ -278,15 +277,15 @@ function renderActionItems(vm) {
278
277
  remedy: `akm health --since=${vm.window} --group-by run`,
279
278
  });
280
279
  }
281
- // Semantic search blocked.
282
- if (vm.sem.blocked) {
280
+ // Semantic search blocked or unavailable.
281
+ if (vm.sem.status === "fail") {
283
282
  pushItem({
284
283
  key: "semantic-search-blocked",
285
284
  prio: "P2",
286
285
  cls: "warn",
287
- title: "Semantic search blocked",
288
- descHtml: `Embedding provider unreachable. ${esc(vm.sem.detail)}. Curate falls back to keyword search — relevance scoring degraded.`,
289
- remedy: "akm config list",
286
+ title: `Semantic search ${vm.sem.label.toLowerCase()}`,
287
+ descHtml: `${esc(vm.sem.detail)} Curate falls back to keyword search — relevance scoring degraded.`,
288
+ remedy: "akm index --full --verbose",
290
289
  });
291
290
  }
292
291
  // Pending proposals to drain.
@@ -38,10 +38,10 @@
38
38
  * That query is a `git ls-remote --tags` (lists refs; fetches nothing,
39
39
  * writes nothing) with a short timeout, and any failure (offline, no
40
40
  * remote, timeout) degrades to "installed version reported, no staleness
41
- * claim" rather than a false positive or a hang. Unlike `cli-version`, this
42
- * check is NOT gated behind `--probe`/`--no-probe` — it predates that flag
43
- * and stays unconditional; see `./version-drift.ts` for why the newer check
44
- * chose the opposite default.
41
+ * claim" rather than a false positive or a hang. Like `cli-version`, this
42
+ * check is gated behind `--probe`/`--no-probe`: with probing off the remote is
43
+ * not asked, the row reports `unknown` ("not probed") and only the local range
44
+ * check (3) runs.
45
45
  *
46
46
  * Every collector here is best-effort and silent on missing/unreadable
47
47
  * input: no Claude plugin installed, no marketplace clone, an unreadable
@@ -53,6 +53,7 @@ import fs from "node:fs";
53
53
  import os from "node:os";
54
54
  import path from "node:path";
55
55
  import { OPENCODE_V1, OPENCODE_V2, readPackageVersion, } from "../../integrations/harnesses/opencode/plugin-layout.js";
56
+ import { opencodeCacheDir } from "../../integrations/harnesses/opencode/roots.js";
56
57
  import { isExactSemver, isSemverRange, maxSatisfying, satisfiesRange } from "../../registry/semver.js";
57
58
  /**
58
59
  * Root directory holding Claude Code's plugin cache + marketplace clones.
@@ -72,8 +73,8 @@ function claudePluginsDir() {
72
73
  * sharing the host's databases with every other akm install — its version
73
74
  * lag matters the same way a stale Claude plugin's does.
74
75
  */
75
- function opencodeCacheDir() {
76
- return process.env.AKM_OPENCODE_CACHE_DIR ?? path.join(os.homedir(), ".cache", "opencode");
76
+ function defaultOpencodeCacheRoot() {
77
+ return process.env.AKM_OPENCODE_CACHE_DIR ?? opencodeCacheDir();
77
78
  }
78
79
  const OPENCODE_PLUGIN_LOCATIONS = [
79
80
  {
@@ -245,8 +246,9 @@ export function collectPluginStalenessAdvisories(options) {
245
246
  const pluginsRoot = options.pluginsRoot ?? claudePluginsDir();
246
247
  const listRemoteTags = options.listRemoteTags ?? realListRemoteTags;
247
248
  const plugins = detectInstalledPlugins(pluginsRoot);
248
- const results = plugins.map((plugin) => buildAdvisory(plugin, options.cliVersion, pluginsRoot, listRemoteTags));
249
- const opencodeCacheRoot = options.opencodeCacheRoot ?? opencodeCacheDir();
249
+ const probe = options.probe ?? true;
250
+ const results = plugins.map((plugin) => buildAdvisory(plugin, options.cliVersion, pluginsRoot, listRemoteTags, probe));
251
+ const opencodeCacheRoot = options.opencodeCacheRoot ?? defaultOpencodeCacheRoot();
250
252
  for (const plugin of OPENCODE_PLUGIN_LOCATIONS) {
251
253
  for (const bundled of findBundledAkm(plugin, opencodeCacheRoot)) {
252
254
  results.push(buildOpencodeBundledAdvisory(plugin, bundled, options.cliVersion));
@@ -254,13 +256,13 @@ export function collectPluginStalenessAdvisories(options) {
254
256
  }
255
257
  return results;
256
258
  }
257
- function buildAdvisory(plugin, cliVersion, pluginsRoot, listRemoteTags) {
259
+ function buildAdvisory(plugin, cliVersion, pluginsRoot, listRemoteTags, probe) {
258
260
  const pluginRef = `${plugin.pluginName}@${plugin.marketplace}`;
259
261
  // Point 2: newest available vs. installed, via the marketplace clone's remote.
260
262
  const marketplaceDir = path.join(pluginsRoot, "marketplaces", plugin.marketplace);
261
263
  let availableVersion;
262
264
  try {
263
- const tags = fs.existsSync(marketplaceDir) ? listRemoteTags(marketplaceDir) : undefined;
265
+ const tags = probe && fs.existsSync(marketplaceDir) ? listRemoteTags(marketplaceDir) : undefined;
264
266
  availableVersion = tags && tags.length > 0 ? maxSatisfying(tags, "*") : undefined;
265
267
  }
266
268
  catch {
@@ -274,6 +276,8 @@ function buildAdvisory(plugin, cliVersion, pluginsRoot, listRemoteTags) {
274
276
  const rangeKnown = versionRange !== undefined && isSemverRange(versionRange);
275
277
  const admitted = rangeKnown ? satisfiesRange(cliVersion, versionRange) : undefined;
276
278
  const messageParts = [`${pluginRef}: installed ${plugin.version}`];
279
+ if (!probe)
280
+ messageParts.push("newest tag was not probed");
277
281
  if (availableVersion !== undefined) {
278
282
  messageParts.push(stale ? `available ${availableVersion} (STALE)` : `available ${availableVersion} (up to date)`);
279
283
  }
@@ -285,7 +289,9 @@ function buildAdvisory(plugin, cliVersion, pluginsRoot, listRemoteTags) {
285
289
  return {
286
290
  name: "plugin-version",
287
291
  kind: "deterministic",
288
- status: stale || admitted === false ? "warn" : "pass",
292
+ // Not probed => staleness is unknown, not "up to date"; only the local
293
+ // range check can still warn.
294
+ status: stale || admitted === false ? "warn" : probe ? "pass" : "unknown",
289
295
  confidence: "high",
290
296
  message: messageParts.join(" — "),
291
297
  evidence: {
@@ -294,6 +300,7 @@ function buildAdvisory(plugin, cliVersion, pluginsRoot, listRemoteTags) {
294
300
  plugin: plugin.pluginName,
295
301
  installedVersion: plugin.version,
296
302
  availableVersion: availableVersion ?? null,
303
+ ...(probe ? {} : { probed: false }),
297
304
  stale,
298
305
  versionRange: versionRange ?? null,
299
306
  cliVersion,
@@ -121,16 +121,20 @@ function buildTrend(deltas) {
121
121
  const overall = score >= 1 ? "improving" : score <= -1 ? "degrading" : "mixed";
122
122
  return { decisionQuality, outputVolume, latency, overall };
123
123
  }
124
- function readSemSearch(advisories) {
125
- const check = advisories.find((a) => a.name === "semantic-search-runtime");
124
+ function readSemSearch(hardChecks) {
125
+ const check = hardChecks.find((c) => c.name === "semantic-search");
126
126
  if (!check)
127
- return { blocked: false, detail: "" };
128
- const evidence = check.evidence ?? {};
129
- const status = String(evidence.status ?? "unknown");
130
- const blocked = check.status !== "pass" || status.toLowerCase().includes("block");
131
- const entries = typeof evidence.entryCount === "number" ? evidence.entryCount : 0;
132
- const embeddings = typeof evidence.embeddingCount === "number" ? evidence.embeddingCount : 0;
133
- return { blocked, detail: `${num(entries)} entries, ${num(embeddings)} embeddings` };
127
+ return { label: "UNKNOWN", status: "unknown", detail: "" };
128
+ const label = check.evidence?.status === "unavailable"
129
+ ? "UNAVAILABLE"
130
+ : check.status === "fail"
131
+ ? "BLOCKED"
132
+ : check.status === "unknown"
133
+ ? "UNKNOWN"
134
+ : check.evidence?.mode === "off"
135
+ ? "OFF"
136
+ : "OK";
137
+ return { label, status: check.status, detail: check.message };
134
138
  }
135
139
  // ── Report-window → time-slice candidates (data only; HTML wrapping is the
136
140
  // renderer's job) ─────────────────────────────────────────────────────────
@@ -265,8 +269,8 @@ function buildVerdictPhase(result, trend, sem, proposals, failedRuns) {
265
269
  const concerns = [];
266
270
  if (failedRuns > 0)
267
271
  concerns.push(`${failedRuns} failed run${failedRuns === 1 ? "" : "s"}`);
268
- if (sem.blocked)
269
- concerns.push("semantic search blocked");
272
+ if (sem.status === "fail")
273
+ concerns.push(`semantic search ${sem.label.toLowerCase()}`);
270
274
  if (proposals.length > 0)
271
275
  concerns.push(`${proposals.length} pending proposal${proposals.length === 1 ? "" : "s"}`);
272
276
  const trendClause = trend.overall === "improving"
@@ -371,7 +375,7 @@ export function buildHealthReportViewModel(result, opts) {
371
375
  const deltas = opts.deltas ?? {};
372
376
  const proposals = opts.proposals;
373
377
  const runsPhase = partitionRuns(result);
374
- const sem = readSemSearch(result.advisories);
378
+ const sem = readSemSearch(result.hardChecks);
375
379
  const trend = buildTrend(deltas);
376
380
  const aggregates = buildAggregatesPhase(result, runsPhase);
377
381
  const meta = buildMetaPhase(result, runsPhase.runs);
@@ -0,0 +1,85 @@
1
+ // This Source Code Form is subject to the terms of the Mozilla Public
2
+ // License, v. 2.0. If a copy of the MPL was not distributed with this
3
+ // file, You can obtain one at https://mozilla.org/MPL/2.0/.
4
+ /**
5
+ * `semantic-search` for `akm health`: what the last `akm index` recorded about
6
+ * semantic search (status, embedding runtime, the reason it failed), with the
7
+ * index's own entry and vector counts read now. It loads no model and makes no
8
+ * request, and nothing gates search on it (#873 removed the cached verdict
9
+ * search used to obey); it reports what the index says.
10
+ */
11
+ import { getDbPath } from "../../core/paths.js";
12
+ import { SEMANTIC_SEARCH_META_KEY } from "../../indexer/walk/index-context.js";
13
+ import { LOCAL_EMBEDDING_RUNTIME } from "../../llm/embedders/local.js";
14
+ import { closeDatabase, openReadonlyExistingDatabase } from "../../storage/repositories/index-connection.js";
15
+ import { getEmbeddableEntryCount } from "../../storage/repositories/index-entries-repository.js";
16
+ import { getMeta } from "../../storage/repositories/index-meta-repository.js";
17
+ import { getEmbeddingCount } from "../../storage/repositories/index-vec-repository.js";
18
+ /** Read the last index run's record and the index's counts, read-only. */
19
+ export function readSemanticSearchState(mode) {
20
+ try {
21
+ const db = openReadonlyExistingDatabase(getDbPath());
22
+ if (!db)
23
+ return { mode };
24
+ try {
25
+ const raw = getMeta(db, SEMANTIC_SEARCH_META_KEY);
26
+ return {
27
+ mode,
28
+ index: {
29
+ ...(raw ? { record: JSON.parse(raw) } : {}),
30
+ builtAt: getMeta(db, "builtAt"),
31
+ entryCount: getEmbeddableEntryCount(db),
32
+ embeddingCount: getEmbeddingCount(db),
33
+ },
34
+ };
35
+ }
36
+ finally {
37
+ closeDatabase(db);
38
+ }
39
+ }
40
+ catch (error) {
41
+ return { mode, error: error instanceof Error ? error.message : String(error) };
42
+ }
43
+ }
44
+ export function semanticSearchCheck(state) {
45
+ const result = (status, message, evidence) => ({
46
+ name: "semantic-search",
47
+ kind: "deterministic",
48
+ status,
49
+ confidence: "high",
50
+ message,
51
+ ...(evidence ? { evidence } : {}),
52
+ });
53
+ if (state.mode === "off")
54
+ return result("pass", "Semantic search is off (semanticSearchMode: off).", { mode: "off" });
55
+ if (state.error)
56
+ return result("unknown", `Could not read the index: ${state.error}`);
57
+ const index = state.index;
58
+ if (!index?.record)
59
+ return result("unknown", "No semantic-search state recorded yet; run `akm index`.");
60
+ const { record, builtAt, entryCount, embeddingCount } = index;
61
+ const evidence = { ...record, ...(builtAt ? { builtAt } : {}), entryCount, embeddingCount };
62
+ const asOf = builtAt ? ` at the last index (${builtAt})` : " at the last index";
63
+ switch (record.status) {
64
+ case "unavailable":
65
+ // No native library for this platform is not something to fix: keyword search is the healthy state there.
66
+ return record.unavailable === "platform"
67
+ ? result("warn", `Semantic search is unavailable on this platform: ${record.reason} ` +
68
+ 'Set semanticSearchMode to "off", or embedding.endpoint to a remote embedding service.', evidence)
69
+ : result("fail", `Semantic search was unavailable on this machine${asOf}: ${record.reason}`, evidence);
70
+ case "blocked":
71
+ return result("fail", `Semantic search was blocked${asOf}: ${record.reason}`, evidence);
72
+ case "ready-js":
73
+ if (embeddingCount < entryCount) {
74
+ return result("warn", `Embeddings lag entries (${embeddingCount}/${entryCount}); run \`akm index\` to embed the rest.`, evidence);
75
+ }
76
+ if (record.provider === "local" && record.runtime && record.runtime !== LOCAL_EMBEDDING_RUNTIME) {
77
+ return result("warn", `Local embeddings ran on ${record.runtime}, not the native ${LOCAL_EMBEDDING_RUNTIME}${asOf}.`, evidence);
78
+ }
79
+ return result("pass", `Semantic search ready (${embeddingCount}/${entryCount} embeddings${record.runtime ? ` on ${record.runtime}` : ""}).`, evidence);
80
+ case "disabled":
81
+ return result("unknown", `Semantic search was off${asOf}; run \`akm index\` to build it.`, evidence);
82
+ default:
83
+ return result("unknown", `No entries were indexed${asOf}.`, evidence);
84
+ }
85
+ }
@@ -94,9 +94,6 @@ function explainOverride(resolvedType, content) {
94
94
  if (fm.type === "workflow" && resolvedType === "workflow") {
95
95
  return { winner: "smart-md:workflow-frontmatter", knownGoodOverride: true };
96
96
  }
97
- if ("tools" in fm && resolvedType === "agent") {
98
- return { winner: "smart-md:tools-frontmatter", knownGoodOverride: true };
99
- }
100
97
  if ("agent" in fm && resolvedType === "command") {
101
98
  return { winner: "smart-md:agent-frontmatter", knownGoodOverride: true };
102
99
  }
@@ -14,7 +14,6 @@ import { probeLlmEndpoint } from "../llm/client.js";
14
14
  import { openDatabase } from "../storage/database.js";
15
15
  import { insertEvent } from "../storage/repositories/events-repository.js";
16
16
  import { getExtractOutcomeCountsSince } from "../storage/repositories/extract-sessions-repository.js";
17
- import { countImproveRunsSince } from "../storage/repositories/improve-runs-repository.js";
18
17
  import { closeDatabase, openReadonlyExistingDatabase } from "../storage/repositories/index-connection.js";
19
18
  import { getAllEntries } from "../storage/repositories/index-entries-repository.js";
20
19
  import { queryTaskHistory } from "../storage/repositories/task-history-repository.js";
@@ -22,15 +21,16 @@ import { applyReadonlyPragmas } from "../storage/sqlite-pragmas.js";
22
21
  import { getStateDbFreelistInfo, runStateDbIntegrityCheck } from "../storage/state-db-integrity.js";
23
22
  import { pkgVersion } from "../version.js";
24
23
  import { collectArchiveUsageAdvisory } from "./health/archive-usage.js";
25
- import { HEALTH_CHECKS, probeActiveImproveStrategy, runHealthEngineProbes, runPendingStateMigrationsCheck, SESSION_EXTRACTION_LEDGER_WINDOW_DAYS, } from "./health/checks.js";
24
+ import { HEALTH_CHECKS, runPendingStateMigrationsCheck, SESSION_EXTRACTION_LEDGER_WINDOW_DAYS, } from "./health/checks.js";
26
25
  import { collectConfigSkewAdvisory } from "./health/config-skew.js";
26
+ import { runConnectionsAndHarnessesCheck } from "./health/connections-and-harnesses-check.js";
27
27
  import { collectDataDirUsageAdvisory } from "./health/data-dir-usage.js";
28
28
  import { collectEgressAdvisory } from "./health/egress.js";
29
- import { engineLastUsedSince, readLastEngineUsage } from "./health/engine-usage.js";
30
29
  import { emptyImproveMetrics, roundRate } from "./health/improve-metrics.js";
31
30
  import { emptyLlmUsageAggregate, readLlmUsageAggregate } from "./health/llm-usage.js";
32
31
  import { collectPluginStalenessAdvisories } from "./health/plugin-staleness.js";
33
32
  import { collectSchedulerBinaryAdvisory } from "./health/scheduler-binary.js";
33
+ import { readSemanticSearchState } from "./health/semantic-search-check.js";
34
34
  import { collectStashExposureAdvisory } from "./health/stash-exposure.js";
35
35
  import { buildTypeDirectoryAdvisory } from "./health/type-directory-check.js";
36
36
  import { MIN_ROWS_FOR_WORST_TASK_FAIL_RATE, } from "./health/types.js";
@@ -189,7 +189,7 @@ function gatherTaskHistoryPhase(db, since, stateDbPath, now, readOnly) {
189
189
  // bad index entry counts), and the freelist reading is purely informational.
190
190
  const stateDbIntegrity = runStateDbIntegrityCheck(stateDbPath);
191
191
  const stateDbFreelist = getStateDbFreelistInfo(stateDbPath);
192
- // D8 (spec §5.3): a marked "command" row or a legacy (unmarked) "prompt"
192
+ // A marked "command" row or a legacy (unmarked) "prompt"
193
193
  // row is the agent/LLM arm; an unmarked "command" row is the legacy
194
194
  // native shell/script arm and must not be counted here (see
195
195
  // isAgentTaskHistoryRow's header comment, referenced from
@@ -212,24 +212,25 @@ function gatherTaskHistoryPhase(db, since, stateDbPath, now, readOnly) {
212
212
  };
213
213
  }
214
214
  /**
215
- * Config fields the surfaces advisory and (#949) the `thinking-control`
216
- * check need. Best-effort: an unloadable config leaves both fields at their
217
- * empty fallback and the callers degrade to their generic/unknown states.
215
+ * The config view the surfaces advisory needs. Best-effort: an unloadable
216
+ * config leaves it undefined and the advisory degrades to its generic state.
218
217
  */
219
- function gatherEgressConfigPhase() {
220
- let egressConfigView;
221
- let thinkingOffEngines = [];
218
+ function gatherEgressConfigView() {
222
219
  try {
223
- const config = loadConfig();
224
- egressConfigView = config;
225
- thinkingOffEngines = Object.entries(config.engines ?? {})
226
- .filter(([, engine]) => engine.kind === "llm" && engine.enableThinking === false)
227
- .map(([name]) => name);
220
+ return loadConfig();
228
221
  }
229
222
  catch {
230
- // fall through with undefined/empty
223
+ return undefined;
224
+ }
225
+ }
226
+ /** The configured `semanticSearchMode`; undefined when the config cannot load. */
227
+ function gatherSemanticSearchMode() {
228
+ try {
229
+ return loadConfig().semanticSearchMode;
230
+ }
231
+ catch {
232
+ return undefined;
231
233
  }
232
- return { egressConfigView, thinkingOffEngines };
233
234
  }
234
235
  /** Extract-ledger outcome counts for the `session-extraction` check's window, independent of `--since`. */
235
236
  function gatherSessionExtractionLedgerPhase(db, now) {
@@ -323,9 +324,9 @@ function gatherAncillaryAdvisories(db, options, egressConfigView) {
323
324
  // and warn when stale or when the plugin's own akm-cli version range no
324
325
  // longer admits this CLI. Best-effort — no plugin installed, an unreadable
325
326
  // manifest, or a network failure while checking the newest tag must not
326
- // abort the health report.
327
+ // abort the health report. The newest-tag lookup honors `--no-probe`.
327
328
  try {
328
- advisories.push(...collectPluginStalenessAdvisories({ cliVersion: pkgVersion }));
329
+ advisories.push(...collectPluginStalenessAdvisories({ cliVersion: pkgVersion, probe: Boolean(options.probe) }));
329
330
  }
330
331
  catch {
331
332
  // Non-fatal.
@@ -582,9 +583,11 @@ export async function akmHealth(options = {}) {
582
583
  try {
583
584
  const { windowResults, deltas } = resolveWindowComparePhase(options, db, stateDbPath, now);
584
585
  // Network probes overlap the local database phases below; awaited where consumed.
585
- const engineProbesPromise = runHealthEngineProbes({ probeReachable: options.probe ? probeLlmEndpoint : undefined });
586
- engineProbesPromise.catch(() => undefined);
587
- // #950: same best-effort, --probe-gated discipline as engineProbesPromise
586
+ const connectionsAndHarnessesPromise = runConnectionsAndHarnessesCheck({
587
+ probeReachable: options.probe ? probeLlmEndpoint : undefined,
588
+ });
589
+ connectionsAndHarnessesPromise.catch(() => undefined);
590
+ // #950: same best-effort, --probe-gated discipline as connectionsAndHarnessesPromise
588
591
  // above — started here, alongside it, and awaited later.
589
592
  const versionDriftPromise = collectVersionDriftAdvisory(Boolean(options.probe), { cliVersion: pkgVersion });
590
593
  versionDriftPromise.catch(() => undefined);
@@ -596,7 +599,7 @@ export async function akmHealth(options = {}) {
596
599
  schedulerBinaryDriftPromise.catch(() => undefined);
597
600
  const taskHistory = gatherTaskHistoryPhase(db, since, stateDbPath, now, readOnly);
598
601
  const { tableNames, missingTables, probe } = taskHistory;
599
- const { egressConfigView, thinkingOffEngines } = gatherEgressConfigPhase();
602
+ const egressConfigView = gatherEgressConfigView();
600
603
  // Same window bundle `--window-compare` builds per-window (windows.ts) —
601
604
  // reused here for the main `--since` window's improve summary and for
602
605
  // `--group-by run`, so neither re-reads `improve_runs`.
@@ -604,20 +607,10 @@ export async function akmHealth(options = {}) {
604
607
  const { improve: improveSummary, perRunSummaries } = buildImproveWindowSummary(db, stateDbPath, since, until, readOnly);
605
608
  advisories.push(...gatherAncillaryAdvisories(db, options, egressConfigView));
606
609
  const sessionExtractionLedger = gatherSessionExtractionLedgerPhase(db, now);
607
- // #950: computed once (no IO beyond config/env, same as gatherEgressConfigPhase)
608
- // so `active-improve-strategy` and `engine-last-used` project the same
609
- // process→engine map instead of each resolving the strategy independently.
610
- const { check: activeImproveStrategy, processEngines: activeImproveStrategyEngines } = probeActiveImproveStrategy();
611
- // #950: `engine-last-used` reads a fixed lookback window independent of
612
- // `--since` (mirrors sessionExtractionLedger's independent window above).
613
- const engineLastUsedSinceIso = engineLastUsedSince(now);
614
- const engineLastUsed = readLastEngineUsage(stateDbPath, now, readOnly);
615
- const improveRunsInLookbackWindow = countImproveRunsSince(db, engineLastUsedSinceIso);
616
- const engineProbes = await engineProbesPromise;
610
+ const connectionsAndHarnesses = await connectionsAndHarnessesPromise;
617
611
  const versionDrift = await versionDriftPromise;
618
612
  const schedulerBinaryDrift = await schedulerBinaryDriftPromise;
619
- // Read once, shared by the `thinking-control` check (#949) and the
620
- // `metrics.llmUsage` report field below — same window, same aggregate.
613
+ // The `metrics.llmUsage` report field below.
621
614
  const llmUsage = readLlmUsageAggregate(stateDbPath, since, undefined, readOnly);
622
615
  // Run the ordered health-check registry. Each check projects the shared
623
616
  // context computed above into one HealthCheckResult; `channel` routes it to
@@ -640,14 +633,9 @@ export async function akmHealth(options = {}) {
640
633
  agentFailureReasonCounts: taskHistory.agentFailureReasonCounts,
641
634
  sessionExtractionLedger,
642
635
  autoAccept: improveSummary.autoAccept,
643
- engineProbes,
644
- thinkingOffEngines,
645
- llmUsage,
636
+ connectionsAndHarnesses,
637
+ semanticSearch: readSemanticSearchState(gatherSemanticSearchMode()),
646
638
  versionDrift,
647
- activeImproveStrategy,
648
- activeImproveStrategyEngines,
649
- engineLastUsed,
650
- improveRunsInLookbackWindow,
651
639
  schedulerBinaryDrift,
652
640
  };
653
641
  for (const check of HEALTH_CHECKS) {