akm-cli 0.10.261012-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 (518) hide show
  1. package/CHANGELOG.md +710 -3
  2. package/README.md +15 -0
  3. package/SECURITY.md +11 -10
  4. package/STABILITY.md +47 -51
  5. package/dist/assets/hints/cli-hints-full.md +21 -19
  6. package/dist/assets/hints/cli-hints-short.md +3 -4
  7. package/dist/assets/opencode/akm-plugin.js +177 -0
  8. package/dist/assets/stash-skeleton/README.md +1 -1
  9. package/dist/assets/tasks/core/improve.yml +1 -1
  10. package/dist/assets/tasks/improve/akm-improve-consolidate.yml +1 -1
  11. package/dist/assets/ui/config.js +27 -10
  12. package/dist/assets/workflows/workflow-template.md +2 -2
  13. package/dist/cli/clack.js +3 -1
  14. package/dist/cli/selection.js +33 -0
  15. package/dist/cli/shared.js +14 -1
  16. package/dist/cli/unknown-flags.js +6 -37
  17. package/dist/cli.js +69 -48
  18. package/dist/commands/agent/agent-dispatch.js +17 -25
  19. package/dist/commands/agent/contribute-cli.js +9 -8
  20. package/dist/commands/command/command-cli.js +4 -8
  21. package/dist/commands/command/command-execution.js +25 -39
  22. package/dist/commands/command/execution-source-loader.js +10 -14
  23. package/dist/commands/completions.js +1 -1
  24. package/dist/commands/config-cli.js +14 -5
  25. package/dist/commands/env/child-env.js +12 -14
  26. package/dist/commands/env/env-binding.js +47 -58
  27. package/dist/commands/env/env-cli.js +22 -24
  28. package/dist/commands/env/env.js +10 -58
  29. package/dist/commands/env/secret-cli.js +11 -29
  30. package/dist/commands/env/secret.js +3 -10
  31. package/dist/commands/health/checks.js +10 -849
  32. package/dist/commands/health/connections-and-harnesses-check.js +109 -0
  33. package/dist/commands/health/egress.js +3 -3
  34. package/dist/commands/health/html-report.js +9 -10
  35. package/dist/commands/health/plugin-staleness.js +18 -11
  36. package/dist/commands/health/report-view-model.js +16 -12
  37. package/dist/commands/health/scheduler-binary.js +1 -1
  38. package/dist/commands/health/semantic-search-check.js +85 -0
  39. package/dist/commands/health/type-directory-check.js +0 -3
  40. package/dist/commands/health.js +30 -42
  41. package/dist/commands/improve/consolidate/pair-pass.js +10 -25
  42. package/dist/commands/improve/consolidate.js +10 -15
  43. package/dist/commands/improve/distill.js +5 -17
  44. package/dist/commands/improve/eligibility.js +1 -3
  45. package/dist/commands/improve/execution.js +37 -40
  46. package/dist/commands/improve/extract-cli.js +6 -11
  47. package/dist/commands/improve/extract-prompt.js +2 -2
  48. package/dist/commands/improve/extract.js +67 -97
  49. package/dist/commands/improve/improve-cli.js +22 -128
  50. package/dist/commands/improve/improve-report.js +1 -1
  51. package/dist/commands/improve/improve-strategies.js +25 -108
  52. package/dist/commands/improve/improve.js +10 -14
  53. package/dist/commands/improve/loop-stages.js +3 -0
  54. package/dist/commands/improve/memory/memory-improve.js +1 -1
  55. package/dist/commands/improve/preparation.js +8 -13
  56. package/dist/commands/improve/reflect.js +203 -332
  57. package/dist/commands/improve/retrieval-scope.js +1 -1
  58. package/dist/commands/improve/session-asset.js +3 -2
  59. package/dist/commands/improve/stage.js +87 -115
  60. package/dist/commands/lint/base-linter.js +3 -3
  61. package/dist/commands/lint/env-key-rules.js +7 -6
  62. package/dist/commands/lint/index.js +3 -3
  63. package/dist/commands/models-cli.js +103 -63
  64. package/dist/commands/proposal/drain.js +26 -39
  65. package/dist/commands/proposal/proposal-cli.js +14 -18
  66. package/dist/commands/proposal/propose-cli.js +4 -2
  67. package/dist/commands/proposal/propose.js +37 -64
  68. package/dist/commands/proposal/repository.js +17 -17
  69. package/dist/commands/proposal/validators/proposal-validators.js +3 -6
  70. package/dist/commands/read/curate.js +10 -6
  71. package/dist/commands/read/registry-search.js +2 -48
  72. package/dist/commands/read/search-cli.js +1 -8
  73. package/dist/commands/read/search.js +5 -6
  74. package/dist/commands/read/show.js +6 -29
  75. package/dist/commands/remember.js +25 -40
  76. package/dist/commands/sources/add-cli.js +8 -63
  77. package/dist/commands/sources/bundle-cli.js +8 -9
  78. package/dist/commands/sources/bundle-config-ops.js +2 -2
  79. package/dist/commands/sources/info.js +12 -1
  80. package/dist/commands/sources/init.js +1 -1
  81. package/dist/commands/sources/installed-stashes.js +119 -63
  82. package/dist/commands/sources/migration-help.js +1 -1
  83. package/dist/commands/sources/plugin-upgrade.js +8 -15
  84. package/dist/commands/sources/schema-repair.js +4 -10
  85. package/dist/commands/sources/source-add.js +2 -2
  86. package/dist/commands/sources/source-clone.js +31 -7
  87. package/dist/commands/sources/source-manage.js +4 -4
  88. package/dist/commands/targets.js +175 -0
  89. package/dist/commands/tasks/explain.js +104 -69
  90. package/dist/commands/tasks/tasks-cli.js +9 -11
  91. package/dist/commands/tasks/tasks.js +75 -97
  92. package/dist/commands/ui/api.js +11 -3
  93. package/dist/commands/ui/redact.js +5 -31
  94. package/dist/commands/ui/workspace-actions.js +1 -1
  95. package/dist/commands/workflow/plan.js +48 -9
  96. package/dist/commands/workflow-cli.js +40 -45
  97. package/dist/core/adapter/adapters/agent-skills-adapter.js +10 -11
  98. package/dist/core/adapter/adapters/akm-adapter.js +36 -41
  99. package/dist/core/adapter/adapters/akm-lint.js +10 -12
  100. package/dist/core/adapter/adapters/akm-metadata.js +2 -2
  101. package/dist/core/adapter/adapters/akm-task-adapter.js +8 -9
  102. package/dist/core/adapter/adapters/akm-workflow-adapter.js +5 -5
  103. package/dist/core/adapter/adapters/claude-adapter.js +1 -1
  104. package/dist/core/adapter/adapters/dotenv-adapter.js +7 -6
  105. package/dist/core/adapter/adapters/generic-files-adapter.js +5 -5
  106. package/dist/core/adapter/adapters/index.js +3 -4
  107. package/dist/core/adapter/adapters/llm-wiki-adapter.js +12 -14
  108. package/dist/core/adapter/adapters/okf-adapter.js +8 -10
  109. package/dist/core/adapter/adapters/opencode-adapter.js +1 -1
  110. package/dist/core/adapter/adapters/shared.js +3 -3
  111. package/dist/core/adapter/adapters/tool-dir-shared.js +7 -25
  112. package/dist/core/adapter/adapters/website-snapshot-adapter.js +3 -3
  113. package/dist/core/adapter/detect-adapter.js +1 -1
  114. package/dist/core/adapter/execution-source.js +13 -35
  115. package/dist/core/adapter/registry.js +1 -1
  116. package/dist/core/adapter/validate-context.js +2 -4
  117. package/dist/core/asset/asset-placement.js +1 -1
  118. package/dist/core/asset/asset-ref.js +3 -3
  119. package/dist/core/asset/resolve-ref.js +5 -0
  120. package/dist/core/bundle-rename.js +12 -4
  121. package/dist/core/closest-match.js +37 -0
  122. package/dist/core/common.js +37 -57
  123. package/dist/core/config/config-io.js +26 -18
  124. package/dist/core/config/config-schema.js +19 -106
  125. package/dist/core/config/config-sources.js +3 -3
  126. package/dist/core/config/config-types.js +4 -4
  127. package/dist/core/config/config-walker.js +50 -77
  128. package/dist/core/config/config.js +438 -109
  129. package/dist/core/config/convert-engine-references.js +114 -0
  130. package/dist/core/config/convert-engines-shared.js +40 -0
  131. package/dist/core/config/convert-engines.js +300 -0
  132. package/dist/core/config/convert-models-overlay.js +137 -0
  133. package/dist/core/config/credentials.js +304 -0
  134. package/dist/core/config/engine-semantics.js +3 -3
  135. package/dist/core/config/migrate-keys.js +222 -0
  136. package/dist/core/config/model-aliases.js +37 -0
  137. package/dist/core/config/models-file.js +34 -0
  138. package/dist/core/config/retired-engines.js +53 -0
  139. package/dist/core/config/schema/connections.js +41 -0
  140. package/dist/core/config/schema/embedding.js +2 -2
  141. package/dist/core/config/schema/harnesses.js +41 -0
  142. package/dist/core/config/schema/improve-processes.js +9 -28
  143. package/dist/core/config/schema/improve.js +36 -1
  144. package/dist/core/config/schema/index-config.js +18 -20
  145. package/dist/core/config/schema/primitives.js +42 -17
  146. package/dist/core/config/schema/search.js +6 -11
  147. package/dist/core/config/schema/sources-bundles.js +9 -9
  148. package/dist/core/config/schema/workflow.js +2 -6
  149. package/dist/core/config/unusable-entries.js +66 -0
  150. package/dist/core/content-safety.js +3 -6
  151. package/dist/core/endpoint-url.js +47 -0
  152. package/dist/core/env-secret-ref.js +84 -73
  153. package/dist/core/errors.js +10 -16
  154. package/dist/core/extra-params.js +3 -3
  155. package/dist/core/improve-result.js +8 -9
  156. package/dist/core/json-schema.js +1 -1
  157. package/dist/core/lesson-lint.js +1 -1
  158. package/dist/core/llm-inference.js +80 -0
  159. package/dist/core/parse.js +2 -2
  160. package/dist/core/paths.js +33 -10
  161. package/dist/core/recognition-util.js +8 -10
  162. package/dist/core/redaction.js +94 -55
  163. package/dist/core/ref-token.js +82 -0
  164. package/dist/core/secret-value.js +14 -0
  165. package/dist/core/state/migrations.js +17 -22
  166. package/dist/core/structured.js +2 -68
  167. package/dist/core/subprocess.js +63 -22
  168. package/dist/core/type-presentation.js +10 -14
  169. package/dist/core/write-source.js +20 -4
  170. package/dist/execution/input-contract.js +3 -6
  171. package/dist/execution/notices.js +49 -0
  172. package/dist/execution/resolved-request.js +24 -40
  173. package/dist/execution/source.js +21 -45
  174. package/dist/execution/target-ref.js +2 -2
  175. package/dist/indexer/bundle-identity-guard.js +6 -5
  176. package/dist/indexer/ensure-index.js +1 -1
  177. package/dist/indexer/index-writer-lock.js +1 -1
  178. package/dist/indexer/indexer.js +46 -42
  179. package/dist/indexer/installations.js +12 -22
  180. package/dist/indexer/lookup/adapter-concept-owner.js +40 -14
  181. package/dist/indexer/materialize-embeddings.js +20 -16
  182. package/dist/indexer/passes/memory-inference.js +21 -50
  183. package/dist/indexer/passes/metadata.js +5 -5
  184. package/dist/indexer/scan/doc-to-entry.js +1 -1
  185. package/dist/indexer/scan/drain-dir.js +9 -11
  186. package/dist/indexer/search/db-search.js +9 -7
  187. package/dist/indexer/search/search-source.js +42 -22
  188. package/dist/indexer/usage/usage-events.js +2 -3
  189. package/dist/indexer/walk/index-context.js +2 -1
  190. package/dist/indexer/walk/matchers.js +3 -11
  191. package/dist/indexer/walk/path-resolver.js +13 -68
  192. package/dist/indexer/walk/walker.js +32 -26
  193. package/dist/integrations/agent/akm-read-tools.js +81 -0
  194. package/dist/integrations/agent/config.js +1 -1
  195. package/dist/integrations/agent/detect.js +32 -36
  196. package/dist/integrations/agent/execution.js +130 -428
  197. package/dist/integrations/agent/index.js +1 -1
  198. package/dist/integrations/agent/profiles.js +24 -28
  199. package/dist/integrations/agent/prompts.js +17 -30
  200. package/dist/integrations/agent/request-lowering.js +67 -101
  201. package/dist/integrations/agent/resolution.js +332 -0
  202. package/dist/integrations/agent/runner-dispatch.js +156 -181
  203. package/dist/integrations/agent/runner.js +20 -70
  204. package/dist/integrations/agent/runtime-port.js +4 -0
  205. package/dist/integrations/agent/runtime.js +10 -0
  206. package/dist/integrations/agent/spawn.js +65 -190
  207. package/dist/integrations/harnesses/aider/index.js +19 -39
  208. package/dist/integrations/harnesses/amazonq/index.js +17 -32
  209. package/dist/integrations/harnesses/claude/index.js +59 -28
  210. package/dist/integrations/harnesses/claude/session-log.js +7 -5
  211. package/dist/integrations/harnesses/codex/index.js +19 -31
  212. package/dist/integrations/harnesses/copilot/index.js +17 -35
  213. package/dist/integrations/harnesses/gemini/index.js +18 -34
  214. package/dist/integrations/harnesses/harness.js +36 -0
  215. package/dist/integrations/harnesses/index.js +20 -51
  216. package/dist/integrations/harnesses/opencode/agent-builder.js +132 -100
  217. package/dist/integrations/harnesses/opencode/index.js +11 -33
  218. package/dist/integrations/harnesses/opencode/roots.js +50 -0
  219. package/dist/integrations/harnesses/opencode/runtime/binary.js +206 -0
  220. package/dist/integrations/harnesses/opencode/runtime/command.js +152 -0
  221. package/dist/integrations/harnesses/opencode/runtime/index.js +177 -0
  222. package/dist/integrations/harnesses/opencode/runtime/tar.js +107 -0
  223. package/dist/integrations/harnesses/opencode/session-log-v1.js +15 -7
  224. package/dist/integrations/harnesses/opencode/session-log-v2.js +72 -48
  225. package/dist/integrations/harnesses/opencode/session-log.js +58 -137
  226. package/dist/integrations/harnesses/opencode/version.js +34 -53
  227. package/dist/integrations/harnesses/openhands/index.js +13 -37
  228. package/dist/integrations/harnesses/pi/index.js +21 -32
  229. package/dist/integrations/lockfile.js +1 -1
  230. package/dist/integrations/session-logs/index.js +11 -31
  231. package/dist/llm/client.js +93 -111
  232. package/dist/llm/embedder.js +19 -34
  233. package/dist/llm/embedders/connection.js +31 -0
  234. package/dist/llm/embedders/local-model-files.js +56 -0
  235. package/dist/llm/embedders/local.js +146 -115
  236. package/dist/llm/embedders/remote.js +26 -23
  237. package/dist/llm/embedders/types.js +1 -1
  238. package/dist/llm/index-passes.js +33 -39
  239. package/dist/llm/memory-infer.js +67 -77
  240. package/dist/llm/model-list.js +35 -0
  241. package/dist/llm/rerank-client.js +8 -14
  242. package/dist/llm/structured-call.js +45 -99
  243. package/dist/llm/structured.js +60 -0
  244. package/dist/output/renderers.js +2 -8
  245. package/dist/output/shapes/helpers.js +18 -44
  246. package/dist/output/shapes/passthrough.js +1 -0
  247. package/dist/output/shapes.js +1 -7
  248. package/dist/output/text/command-format.js +41 -39
  249. package/dist/output/text/health-format.js +8 -2
  250. package/dist/output/text/helpers.js +1 -1
  251. package/dist/output/text/migrate.js +12 -0
  252. package/dist/output/text/models.js +3 -2
  253. package/dist/output/text/registry-commands.js +1 -2
  254. package/dist/output/text/show-directives.js +16 -28
  255. package/dist/output/text/show-format.js +0 -2
  256. package/dist/output/text/targets-table.js +70 -0
  257. package/dist/output/text/workflow-format.js +44 -15
  258. package/dist/output/text.js +1 -1
  259. package/dist/registry/providers/skills-sh.js +1 -28
  260. package/dist/registry/providers/static-index.js +1 -71
  261. package/dist/runtime.js +6 -2
  262. package/dist/scripts/akm-migrate-node.js +47095 -44905
  263. package/dist/scripts/akm-migrate.js +46946 -44755
  264. package/dist/setup/detect.js +28 -273
  265. package/dist/setup/endpoint.js +36 -0
  266. package/dist/setup/semantic-assets.js +13 -19
  267. package/dist/setup/setup-flags.js +77 -0
  268. package/dist/setup/setup-plan.js +144 -0
  269. package/dist/setup/setup.js +134 -358
  270. package/dist/setup/steps/connection-shared.js +49 -101
  271. package/dist/setup/steps/connection.js +121 -524
  272. package/dist/setup/steps/embeddings.js +151 -0
  273. package/dist/setup/steps/harnesses.js +118 -0
  274. package/dist/setup/steps/platforms.js +2 -81
  275. package/dist/setup/steps/tasks.js +1 -2
  276. package/dist/setup/steps.js +10 -0
  277. package/dist/setup/summary.js +67 -0
  278. package/dist/sources/freshness.js +16 -21
  279. package/dist/sources/providers/git-provider.js +2 -9
  280. package/dist/sources/providers/provider-utils.js +13 -5
  281. package/dist/sources/resolve.js +12 -16
  282. package/dist/sources/snapshot-fetchers/robots.js +11 -12
  283. package/dist/sources/snapshot-fetchers/secret-seam.js +2 -4
  284. package/dist/sources/snapshot-fetchers/website-ingest.js +8 -15
  285. package/dist/sources/snapshot-fetchers/x.js +1 -1
  286. package/dist/standalone/onnxruntime-library.js +52 -0
  287. package/dist/storage/repositories/improve-ledger-repository.js +1 -1
  288. package/dist/storage/repositories/improve-runs-repository.js +0 -13
  289. package/dist/storage/repositories/index-entries-repository.js +2 -2
  290. package/dist/storage/repositories/proposals-repository.js +2 -2
  291. package/dist/storage/repositories/task-history-repository.js +2 -2
  292. package/dist/storage/repositories/workflow-runs-repository.js +44 -129
  293. package/dist/storage/sqlite-read-snapshot.js +33 -29
  294. package/dist/tasks/embedded.js +1 -1
  295. package/dist/tasks/log-redaction.js +7 -119
  296. package/dist/tasks/prepare/prepare-support.js +8 -7
  297. package/dist/tasks/prepare/prepare.js +8 -9
  298. package/dist/tasks/prepare/script-capture.js +9 -25
  299. package/dist/tasks/run/attempt-lifecycle.js +17 -35
  300. package/dist/tasks/run/load-task.js +54 -27
  301. package/dist/tasks/run/run-command-task.js +15 -10
  302. package/dist/tasks/run/run-native-task.js +8 -21
  303. package/dist/tasks/run/run-task.js +5 -8
  304. package/dist/tasks/run/run-workflow-task.js +14 -21
  305. package/dist/tasks/run/task-history.js +9 -17
  306. package/dist/tasks/run/task-log.js +1 -5
  307. package/dist/tasks/scheduler-invocation.js +13 -18
  308. package/dist/tasks/scheduler-sync.js +0 -1
  309. package/dist/tasks/source/bounded-document.js +31 -117
  310. package/dist/tasks/source/parse-task-source.js +0 -1
  311. package/dist/tasks/source/project-v4.js +5 -3
  312. package/dist/tasks/source/task-input-diagnostics.js +3 -4
  313. package/dist/tasks/source/task-source-v4.js +48 -72
  314. package/dist/tasks/source-v3.js +2 -5
  315. package/dist/tasks/task-run-reserved-flags.js +1 -2
  316. package/dist/workflows/authoring/authoring.js +2 -7
  317. package/dist/workflows/compile.js +1 -15
  318. package/dist/workflows/concurrency-policy.js +4 -4
  319. package/dist/workflows/exec/child-workflow.js +1 -4
  320. package/dist/workflows/exec/dispatch-redaction.js +35 -86
  321. package/dist/workflows/exec/environment.js +13 -77
  322. package/dist/workflows/exec/exec-unit.js +14 -55
  323. package/dist/workflows/exec/frozen-judge.js +26 -28
  324. package/dist/workflows/exec/native-executor.js +126 -71
  325. package/dist/workflows/exec/run-workflow.js +38 -42
  326. package/dist/workflows/exec/step-work.js +13 -17
  327. package/dist/workflows/exec/unit-dispatch.js +7 -21
  328. package/dist/workflows/freeze/environment.js +14 -119
  329. package/dist/workflows/freeze/freeze.js +14 -33
  330. package/dist/workflows/freeze/step-values.js +6 -13
  331. package/dist/workflows/freeze/targets/child-workflow.js +3 -5
  332. package/dist/workflows/freeze/targets/command.js +9 -15
  333. package/dist/workflows/freeze/targets/shell.js +0 -3
  334. package/dist/workflows/freeze/task-bindings.js +0 -1
  335. package/dist/workflows/parser.js +50 -59
  336. package/dist/workflows/plan.js +8 -2
  337. package/dist/workflows/renderer.js +83 -9
  338. package/dist/workflows/resource-limits.js +2 -2
  339. package/dist/workflows/runtime/run-plan.js +38 -23
  340. package/dist/workflows/runtime/runs.js +55 -93
  341. package/dist/workflows/runtime/workflow-asset-loader.js +55 -86
  342. package/dist/workflows/source-files.js +7 -19
  343. package/docs/README.md +10 -16
  344. package/docs/architecture/README.md +2 -37
  345. package/docs/architecture/adapters.md +2 -2
  346. package/docs/architecture/akm-core-principles.md +256 -118
  347. package/docs/architecture/architecture.md +283 -99
  348. package/docs/architecture/improvement.md +8 -2
  349. package/docs/architecture/internals/classification.md +1 -3
  350. package/docs/architecture/internals/fresh-host-rebuild-runbook.md +7 -6
  351. package/docs/architecture/internals/health-advisories.md +35 -74
  352. package/docs/architecture/internals/improve-workflow.md +27 -26
  353. package/docs/architecture/internals/indexing.md +3 -3
  354. package/docs/architecture/internals/storage-locations.md +48 -15
  355. package/docs/architecture/persisted-data-compat.md +10 -6
  356. package/docs/architecture/specs/okf-support.md +9 -11
  357. package/docs/architecture/specs/ref.md +7 -9
  358. package/docs/architecture/testing/testing-workflow.md +172 -52
  359. package/docs/architecture/workflow-engine.md +51 -34
  360. package/docs/guides/README.md +0 -1
  361. package/docs/guides/author-bundles.md +15 -20
  362. package/docs/guides/author-workflows.md +93 -71
  363. package/docs/guides/bundles.md +20 -16
  364. package/docs/guides/discover-and-load.md +1 -1
  365. package/docs/guides/getting-started.md +49 -3
  366. package/docs/guides/improve-the-library.md +10 -4
  367. package/docs/guides/recipes/headless-install.md +11 -16
  368. package/docs/guides/run-workflows.md +29 -20
  369. package/docs/guides/scheduling.md +2 -2
  370. package/docs/guides/use-with-any-agent.md +20 -22
  371. package/docs/integration/bundling-akm.md +19 -9
  372. package/docs/maintainers/README.md +2 -6
  373. package/docs/maintainers/release-checklist.md +73 -126
  374. package/docs/migration/README.md +10 -3
  375. package/docs/migration/release-notes/0.10.0.md +81 -16
  376. package/docs/migration/release-notes/0.6.0.md +1 -1
  377. package/docs/migration/release-notes/0.7.0.md +1 -1
  378. package/docs/migration/release-notes/0.9.0.md +1 -1
  379. package/docs/migration/release-notes/README.md +1 -1
  380. package/docs/migration/v0.9-to-v0.10.md +300 -60
  381. package/docs/migration/v0.9.1-to-v0.9.2.md +6 -5
  382. package/docs/posts/config-v2-lessons-16.md +1 -1
  383. package/docs/posts/llm-mode-reflect-13.md +1 -1
  384. package/docs/posts/release-0.6.0.md +11 -11
  385. package/docs/posts/release-0.8.0.md +4 -4
  386. package/docs/posts/workflows-vaults-09.md +1 -1
  387. package/docs/reference/README.md +1 -1
  388. package/docs/reference/asset-types.md +2 -2
  389. package/docs/reference/cli.md +477 -388
  390. package/docs/reference/configuration.md +569 -550
  391. package/docs/reference/data-and-telemetry.md +9 -6
  392. package/docs/reference/env-and-secrets.md +72 -15
  393. package/docs/reference/refs.md +3 -20
  394. package/docs/reference/registry.md +12 -38
  395. package/docs/reference/supported-formats.md +1 -1
  396. package/docs/reference/tasks.md +22 -11
  397. package/docs/reference/ui-api.md +14 -9
  398. package/docs/reference/workflow-schema.md +199 -154
  399. package/docs/reference/workflows.md +4 -6
  400. package/package.json +9 -11
  401. package/schemas/akm-config.json +1696 -2922
  402. package/schemas/akm-task.json +4 -4
  403. package/schemas/akm-workflow.json +36 -9
  404. package/ROADMAP.md +0 -112
  405. package/dist/assets/models.json +0 -35
  406. package/dist/commands/health/engine-usage.js +0 -45
  407. package/dist/commands/sources/dangerous-env-audit.js +0 -134
  408. package/dist/core/activation-policy.js +0 -67
  409. package/dist/core/config/schema/engines.js +0 -160
  410. package/dist/core/config/schema/execution.js +0 -23
  411. package/dist/core/spawn-env.js +0 -268
  412. package/dist/execution/directory-identity.js +0 -78
  413. package/dist/integrations/agent/builder-shared.js +0 -33
  414. package/dist/integrations/agent/builders.js +0 -43
  415. package/dist/integrations/agent/engine-fallback.js +0 -59
  416. package/dist/integrations/agent/engine-resolution.js +0 -333
  417. package/dist/integrations/agent/model-map.js +0 -475
  418. package/dist/integrations/harnesses/aider/agent-builder.js +0 -107
  419. package/dist/integrations/harnesses/aider/result-extractor.js +0 -53
  420. package/dist/integrations/harnesses/amazonq/agent-builder.js +0 -138
  421. package/dist/integrations/harnesses/amazonq/result-extractor.js +0 -48
  422. package/dist/integrations/harnesses/claude/agent-builder.js +0 -106
  423. package/dist/integrations/harnesses/claude/config-import.js +0 -67
  424. package/dist/integrations/harnesses/claude/result-extractor.js +0 -67
  425. package/dist/integrations/harnesses/codex/agent-builder.js +0 -150
  426. package/dist/integrations/harnesses/codex/result-extractor.js +0 -110
  427. package/dist/integrations/harnesses/copilot/agent-builder.js +0 -117
  428. package/dist/integrations/harnesses/copilot/result-extractor.js +0 -178
  429. package/dist/integrations/harnesses/gemini/agent-builder.js +0 -114
  430. package/dist/integrations/harnesses/gemini/result-extractor.js +0 -149
  431. package/dist/integrations/harnesses/opencode/config-import.js +0 -149
  432. package/dist/integrations/harnesses/opencode/model-config.js +0 -33
  433. package/dist/integrations/harnesses/opencode/model-work-agent.js +0 -115
  434. package/dist/integrations/harnesses/opencode/session-log-types.js +0 -12
  435. package/dist/integrations/harnesses/opencode-sdk/index.js +0 -44
  436. package/dist/integrations/harnesses/opencode-sdk/sdk-runner.js +0 -1052
  437. package/dist/integrations/harnesses/opencode-sdk/v1-adapter.js +0 -199
  438. package/dist/integrations/harnesses/opencode-sdk/v2-adapter.js +0 -254
  439. package/dist/integrations/harnesses/opencode-sdk/wire.js +0 -66
  440. package/dist/integrations/harnesses/openhands/agent-builder.js +0 -120
  441. package/dist/integrations/harnesses/openhands/result-extractor.js +0 -135
  442. package/dist/integrations/harnesses/pi/agent-builder.js +0 -89
  443. package/dist/integrations/harnesses/pi/result-extractor.js +0 -168
  444. package/dist/integrations/harnesses/shared.js +0 -18
  445. package/dist/integrations/harnesses/types.js +0 -55
  446. package/dist/llm/feature-gate.js +0 -115
  447. package/dist/output/shapes/models-list.js +0 -16
  448. package/dist/output/shapes/registry-search.js +0 -10
  449. package/dist/setup/detected-engines.js +0 -136
  450. package/dist/setup/engine-config.js +0 -97
  451. package/dist/setup/harness-config-import.js +0 -47
  452. package/dist/setup/providers.js +0 -14
  453. package/dist/setup/steps/semantic.js +0 -39
  454. package/dist/workflows/authoring/scope-key.js +0 -79
  455. package/dist/workflows/exec/lowering-notices.js +0 -23
  456. package/dist/workflows/source-semantics.js +0 -110
  457. package/docs/architecture/0.10-process-rules.md +0 -832
  458. package/docs/architecture/akm-architecture-decision-history.md +0 -2055
  459. package/docs/architecture/comparisons/claude-code-vs-akm-workflows-full.md +0 -550
  460. package/docs/architecture/decisions/0001-no-interpolation-attached-structured-context.md +0 -72
  461. package/docs/architecture/decisions/0002-unit-reuse-and-input-hash-scope.md +0 -142
  462. package/docs/architecture/decisions/0003-child-env-allowlist-and-provenance.md +0 -189
  463. package/docs/architecture/decisions/0004-task-input-contract-and-flag-coercion.md +0 -97
  464. package/docs/architecture/decisions/0005-task-result-vocabulary-and-legacy-read-mapping.md +0 -108
  465. package/docs/architecture/decisions/0006-task-source-version-routing.md +0 -124
  466. package/docs/architecture/decisions/0007-workflow-composition-bounds.md +0 -83
  467. package/docs/architecture/decisions/0008-task-binding-normalization.md +0 -88
  468. package/docs/architecture/decisions/0009-child-run-publication-column-parity.md +0 -80
  469. package/docs/architecture/decisions/0010-driver-protocol-cut.md +0 -36
  470. package/docs/architecture/decisions/0011-engine-run-loop-invariants.md +0 -125
  471. package/docs/architecture/decisions/README.md +0 -62
  472. package/docs/architecture/internals/functional-contract-patterns.md +0 -340
  473. package/docs/architecture/internals/registry-network-boundary.md +0 -57
  474. package/docs/architecture/internals/search.md +0 -248
  475. package/docs/architecture/reviews/env-secret-access.md +0 -319
  476. package/docs/architecture/runtime-boundary-design.md +0 -153
  477. package/docs/architecture/specs/0.9.0-close-out-plan.md +0 -361
  478. package/docs/architecture/specs/0.9.0-decisions.md +0 -532
  479. package/docs/architecture/specs/0.9.0-docs-code-drift-register.md +0 -745
  480. package/docs/architecture/specs/0.9.0-open-items-register.md +0 -135
  481. package/docs/architecture/specs/0.9.0-public-api-issue-backlog.md +0 -740
  482. package/docs/architecture/specs/0.9.0-release-surface-review.md +0 -636
  483. package/docs/architecture/specs/agent-command-engine-model-design.md +0 -513
  484. package/docs/architecture/specs/akm-0.9.0-bundle-adapter-spec.md +0 -501
  485. package/docs/architecture/specs/akm-0.9.0-ref-grammar-decision.md +0 -291
  486. package/docs/architecture/specs/akm-format-neutral-bundle-workspace-spec.md +0 -2059
  487. package/docs/architecture/specs/di-seams-plan.md +0 -539
  488. package/docs/architecture/specs/driver-protocol-keep-or-cut.md +0 -275
  489. package/docs/architecture/specs/fact-asset-type.md +0 -142
  490. package/docs/architecture/specs/improve-collapse-churn-detector-design.md +0 -634
  491. package/docs/architecture/specs/reviews/task-workflow-unification/README.md +0 -72
  492. package/docs/architecture/specs/reviews/task-workflow-unification/findings-consolidated.md +0 -152
  493. package/docs/architecture/specs/reviews/task-workflow-unification/library-eval-alternatives.md +0 -352
  494. package/docs/architecture/specs/reviews/task-workflow-unification/library-eval-bunqueue.md +0 -300
  495. package/docs/architecture/specs/reviews/task-workflow-unification/library-eval-openworkflow.md +0 -402
  496. package/docs/architecture/specs/reviews/task-workflow-unification/opus-review-1.md +0 -758
  497. package/docs/architecture/specs/reviews/task-workflow-unification/opus-review-2.md +0 -645
  498. package/docs/architecture/specs/reviews/task-workflow-unification/opus-review-3.md +0 -602
  499. package/docs/architecture/specs/reviews/task-workflow-unification/panel-r1-adversarial.md +0 -27
  500. package/docs/architecture/specs/reviews/task-workflow-unification/panel-r1-architecture.md +0 -27
  501. package/docs/architecture/specs/reviews/task-workflow-unification/panel-r1-coverage.md +0 -74
  502. package/docs/architecture/specs/reviews/task-workflow-unification/panel-r1-security.md +0 -15
  503. package/docs/architecture/specs/reviews/task-workflow-unification/panel-r2-adversarial.md +0 -132
  504. package/docs/architecture/specs/reviews/task-workflow-unification/panel-r2-verification.md +0 -147
  505. package/docs/architecture/specs/stash-conventions-code-spec.md +0 -275
  506. package/docs/architecture/specs/stash-organization-conventions.md +0 -377
  507. package/docs/architecture/specs/task-workflow-format-unification.md +0 -721
  508. package/docs/architecture/specs/workflow-engine-buy-vs-build.md +0 -231
  509. package/docs/architecture/specs/workflow-format-unification.md +0 -432
  510. package/docs/architecture/testing/manual-testing-checklist.md +0 -3411
  511. package/docs/architecture/testing/okf-v0.2-conformance-runbook.md +0 -924
  512. package/docs/architecture/testing/task-workflow-manual-tests.md +0 -1720
  513. package/docs/guides/claude-code-vs-akm-workflows.md +0 -29
  514. package/docs/guides/knowledge-management.md +0 -18
  515. package/docs/maintainers/curate-workmap.md +0 -335
  516. package/docs/migration/v0.5-to-v0.6.md +0 -759
  517. package/docs/migration/v0.7-to-v0.8.md +0 -1378
  518. package/docs/plans/0.9.2-agent-command-workflow-plan.md +0 -423
@@ -0,0 +1,47 @@
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
+ * How akm reads a connection's `endpoint`: the OpenAI-compatible base URL
6
+ * (`…/v1`) or the chat-completions URL itself. The endpoint is a URL, so only
7
+ * its pathname is edited here; a query string (an `api-version`, say) stays
8
+ * where it is, after the pathname, and a fragment, which is never sent, goes.
9
+ * Every consumer of an endpoint (the chat client, model listing, health probes,
10
+ * setup, the stored-key binding, akm's own runtime) reads it through this
11
+ * one module.
12
+ */
13
+ /** The operation a complete endpoint URL may end with. */
14
+ const OPERATION_SUFFIX = /\/(?:chat\/completions|embeddings)$/;
15
+ function parse(endpoint) {
16
+ try {
17
+ return new URL(endpoint);
18
+ }
19
+ catch {
20
+ return undefined;
21
+ }
22
+ }
23
+ /** The pathname of the endpoint's base: no trailing slash, no `/chat/completions` or `/embeddings`. */
24
+ function basePathname(url) {
25
+ return url.pathname.replace(/\/+$/, "").replace(OPERATION_SUFFIX, "");
26
+ }
27
+ function withPathname(url, pathname) {
28
+ url.hash = "";
29
+ url.pathname = pathname;
30
+ const text = url.toString();
31
+ // A bare host serializes with a "/" the endpoint never had.
32
+ return pathname === "" && url.search === "" ? text.replace(/\/$/, "") : text;
33
+ }
34
+ /** The base of an OpenAI-compatible endpoint: the URL without `/chat/completions`, `/embeddings` or a trailing slash. */
35
+ export function openAiBaseUrl(endpoint) {
36
+ const url = parse(endpoint);
37
+ return url ? withPathname(url, basePathname(url)) : endpoint;
38
+ }
39
+ /** The URL of one operation (`chat/completions`, `models`) of the endpoint. */
40
+ export function openAiOperationUrl(endpoint, operation) {
41
+ const url = parse(endpoint);
42
+ return url ? withPathname(url, `${basePathname(url)}/${operation}`) : `${endpoint}/${operation}`;
43
+ }
44
+ /** Whether two endpoints are the same server: the same base, however either is spelled. */
45
+ export function sameEndpoint(a, b) {
46
+ return openAiBaseUrl(a) === openAiBaseUrl(b);
47
+ }
@@ -13,11 +13,14 @@
13
13
  */
14
14
  import fs from "node:fs";
15
15
  import path from "node:path";
16
+ import { resolveConceptOwner } from "../indexer/lookup/adapter-concept-owner.js";
16
17
  import { resolveSourceEntries } from "../indexer/search/search-source.js";
18
+ import { isFileOrFileSymlink } from "../indexer/walk/walker.js";
17
19
  import { resolveSourcesForOrigin } from "../registry/origin-resolve.js";
18
20
  import { assertFlatAssetName, combineCreatePath, normalizeCreateSubPath } from "./asset/asset-create.js";
19
21
  import { assetPathForName, deriveCanonicalAssetName } from "./asset/asset-placement.js";
20
- import { displayRef, isFullRefInput, parseRefInput } from "./asset/resolve-ref.js";
22
+ import { makeBundleRef, parseBundleRef } from "./asset/asset-ref.js";
23
+ import { conceptIdFromTypeName, displayRef, parseRefInput, typeNameFromConceptId } from "./asset/resolve-ref.js";
21
24
  import { isWithin } from "./common.js";
22
25
  import { loadConfig } from "./config/config.js";
23
26
  import { NotFoundError, UsageError } from "./errors.js";
@@ -51,7 +54,7 @@ export function listEnvsRecursive(listKeysFn, config = loadConfig()) {
51
54
  walk(full);
52
55
  continue;
53
56
  }
54
- if (!entry.isFile())
57
+ if (!entry.isFile() && !(entry.isSymbolicLink() && isFileOrFileSymlink(full)))
55
58
  continue;
56
59
  if (entry.name !== ".env" && !entry.name.endsWith(".env"))
57
60
  continue;
@@ -71,33 +74,64 @@ export function listEnvsRecursive(listKeysFn, config = loadConfig()) {
71
74
  return result;
72
75
  }
73
76
  export function parseEnvRef(ref) {
74
- // Accept a bare env name (`prod`, `sub/prod`) or the new-grammar
75
- // `[bundle//]env/name` conceptId. A bare name's leading segment maps to no
76
- // asset type, so it is qualified with the `env/` conceptId prefix; anything
77
- // already a full new-grammar ref is parsed as-is.
78
- return parseRefInput(isFullRefInput(ref) ? ref : `env/${ref}`);
77
+ return parseTypedRef(ref, "env", "env/<name>");
79
78
  }
80
- export function findEnvSource(origin, type, name) {
81
- const sources = resolveSourceEntries(undefined, loadConfig());
82
- if (sources.length === 0) {
83
- throw new UsageError("No bundles configured. Run `akm bundle create` to create your working bundle.");
79
+ /**
80
+ * Parse `ref` as a `[bundle//]conceptId` of the given asset type. There is no
81
+ * bare-name form: `prod` is a usage error that also names the ref it probably
82
+ * meant (`env/prod`), as text only — the suggestion is never resolved or accepted.
83
+ */
84
+ function parseTypedRef(ref, type, form) {
85
+ let parsed;
86
+ try {
87
+ parsed = parseRefInput(ref);
84
88
  }
85
- const candidates = origin ? resolveSourcesForOrigin(origin, sources) : sources;
86
- const typeDir = type === "env" ? "env" : "secrets";
87
- const member = candidates.find((source) => fs.existsSync(assetPathForName(type, path.join(source.path, typeDir), name)));
88
- if (member)
89
- return member;
90
- if (!origin) {
91
- const fallback = candidates[0];
92
- if (fallback)
93
- return fallback;
94
- throw new UsageError("No bundles configured. Run `akm bundle create` to create your working bundle.");
89
+ catch (error) {
90
+ if (!(error instanceof NotFoundError))
91
+ throw error;
95
92
  }
96
- const named = candidates[0];
97
- if (!named) {
98
- throw new NotFoundError(`Source not found for origin: ${origin}`);
93
+ if (parsed?.type !== type) {
94
+ const bare = parseBundleRef(ref);
95
+ const hint = typeNameFromConceptId(bare.conceptId) === undefined
96
+ ? ` Did you mean "${makeBundleRef(bare.bundle, conceptIdFromTypeName(type, bare.conceptId))}"?`
97
+ : "";
98
+ throw new UsageError(`Expected ${type === "env" ? "an" : "a"} ${type} ref (${form} or <bundle>//${form}); got "${ref}". Write the full ref.${hint}`, "INVALID_FLAG_VALUE");
99
+ }
100
+ return parsed;
101
+ }
102
+ /** The bundle and file that own an env or secret ref right now, or undefined. Sensitive files resolve too. */
103
+ function findEnvSecretOwner(origin, conceptId) {
104
+ return resolveConceptOwner({ bundle: origin, conceptId }, resolveSourceEntries(undefined, loadConfig()), {
105
+ includeSensitive: true,
106
+ });
107
+ }
108
+ /**
109
+ * The file that owns any asset ref right now (the asset type its conceptId
110
+ * names, and the bundle-qualified spelling of the ref), or undefined when no
111
+ * bundle owns it. The lookup behind `${ref}` tokens.
112
+ */
113
+ export function resolveRefOwner(ref) {
114
+ const { bundle, conceptId } = parseBundleRef(ref);
115
+ const match = findEnvSecretOwner(bundle, conceptId);
116
+ return (match && {
117
+ absPath: match.owner.path,
118
+ type: typeNameFromConceptId(conceptId)?.type,
119
+ ref: makeBundleRef(match.bundleId, conceptId),
120
+ });
121
+ }
122
+ /**
123
+ * Is `bundle` the id of an installed bundle in the active source set? The predicate `${ref}` substitution uses to
124
+ * tell a qualified ref from shell text. A source set that cannot be read (for example `AKM_BUNDLE_DIR` naming a
125
+ * disabled bundle) answers "not installed", so shell text never raises a config error; a real ref then fails where
126
+ * it is resolved, with that error.
127
+ */
128
+ export function isInstalledBundle(bundle) {
129
+ try {
130
+ return resolveSourcesForOrigin(bundle, resolveSourceEntries(undefined, loadConfig())).length > 0;
131
+ }
132
+ catch {
133
+ return false;
99
134
  }
100
- return named;
101
135
  }
102
136
  /**
103
137
  * `config` defaults to the real `loadConfig()`, same as {@link displayDefaultBundle}.
@@ -112,31 +146,28 @@ export function makeEnvRef(name, source, config = loadConfig()) {
112
146
  return displayRef({ type: "env", name, bundleId: source?.registryId }, displayDefaultBundle(source, config));
113
147
  }
114
148
  /**
115
- * Resolve an env ref to an absolute `.env` path. Accepts the `env/<name>`
116
- * conceptId (or a bare name, auto-qualified into it). The path is returned
117
- * even when the file does not yet exist (so `create` writes under `env/`).
149
+ * Resolve an env ref to the absolute `.env` path that owns it right now.
150
+ * Accepts a full `[bundle//]env/<name>` ref.
151
+ * Throws `NotFoundError` when no bundle owns it; creating one goes through
152
+ * {@link resolveEnvWriteTarget}.
118
153
  */
119
154
  export function resolveEnvPath(ref) {
120
155
  const parsed = parseEnvRef(ref);
121
- if (parsed.type !== "env") {
122
- throw new UsageError(`Expected an env ref (env/<name>); got "${ref}".`);
123
- }
124
- const source = findEnvSource(parsed.origin, "env", parsed.name);
125
- const envRoot = path.join(source.path, "env");
126
- const envPath = assetPathForName("env", envRoot, parsed.name);
127
- // Defense-in-depth: ensure the resolved path stays inside the env directory.
128
- // validateName already rejects traversal patterns like "../../foo", but an
129
- // absolute-path override or symlink-based attack could still escape without
130
- // this second check.
131
- if (!isWithin(envPath, envRoot)) {
132
- throw new UsageError(`Env name "${parsed.name}" escapes the env directory.`);
133
- }
134
- return { name: parsed.name, absPath: envPath, source, parsedRef: parsed, dir: "env" };
156
+ const conceptId = conceptIdFromTypeName("env", parsed.name);
157
+ const match = findEnvSecretOwner(parsed.origin, conceptId);
158
+ if (!match)
159
+ throw new NotFoundError(`Env not found: ${makeBundleRef(parsed.origin, conceptId)}`);
160
+ return {
161
+ name: parsed.name,
162
+ absPath: match.owner.path,
163
+ source: match.source,
164
+ bundleId: match.bundleId,
165
+ parsedRef: parsed,
166
+ dir: "env",
167
+ };
135
168
  }
136
169
  export function parseSecretRef(ref) {
137
- // Same bare-name-vs-full-ref rule as parseEnvRef; a bare name is qualified
138
- // with the `secrets/` conceptId prefix (secret's stash subdir).
139
- return parseRefInput(isFullRefInput(ref) ? ref : `secrets/${ref}`);
170
+ return parseTypedRef(ref, "secret", "secrets/<name>");
140
171
  }
141
172
  export function makeSecretRef(name, source) {
142
173
  // F4b output-spelling flip: `secrets/name` in the primary stash,
@@ -149,39 +180,22 @@ function displayDefaultBundle(source, config = loadConfig()) {
149
180
  const primary = resolveSourceEntries(undefined, config)[0];
150
181
  return primary && path.resolve(primary.path) === path.resolve(source.path) ? source.registryId : undefined;
151
182
  }
152
- export function resolveSecretPath(ref,
153
- // Create-only (`secret set`): enforce a flat ref name and apply `--path` as
154
- // the subdirectory. Lookup callers omit this so nested refs keep resolving.
155
- create) {
183
+ export function resolveSecretPath(ref) {
156
184
  const parsed = parseSecretRef(ref);
157
- if (parsed.type !== "secret") {
158
- throw new UsageError(`Expected a secret ref (secrets/<name>); got "${ref}".`);
159
- }
160
- if (create) {
161
- assertFlatAssetName(parsed.name);
162
- parsed.name = combineCreatePath(normalizeCreateSubPath(create.subPath), parsed.name);
163
- }
164
- // Source resolution is identical for every asset type; reuse the env helper.
165
- const source = findEnvSource(parsed.origin, "secret", parsed.name);
166
- const typeRoot = path.join(source.path, "secrets");
167
- const absPath = assetPathForName("secret", typeRoot, parsed.name);
168
- // Defense-in-depth: ensure the resolved path stays inside the secrets dir.
169
- if (!isWithin(absPath, typeRoot)) {
170
- throw new UsageError(`Secret name "${parsed.name}" escapes the secrets directory.`);
171
- }
172
- return { name: parsed.name, absPath, source };
185
+ const conceptId = conceptIdFromTypeName("secret", parsed.name);
186
+ const match = findEnvSecretOwner(parsed.origin, conceptId);
187
+ if (!match)
188
+ throw new NotFoundError(`Secret not found: ${makeBundleRef(parsed.origin, conceptId)}`);
189
+ return { name: parsed.name, absPath: match.owner.path, source: match.source };
173
190
  }
174
191
  /**
175
192
  * Resolve the destination for an env mutation. Mirrors {@link resolveEnvPath}
176
193
  * but selects the source via {@link resolveWriteTarget} (writability-checked)
177
- * instead of the read-side {@link findEnvSource}. `create` enforces a flat ref
194
+ * instead of the read-side {@link resolveEnvPath}. `create` enforces a flat ref
178
195
  * name and applies `--path` as the subdirectory (matching `env create`).
179
196
  */
180
197
  export function resolveEnvWriteTarget(ref, writeTarget, create) {
181
198
  const parsed = parseEnvRef(ref);
182
- if (parsed.type !== "env") {
183
- throw new UsageError(`Expected an env ref (env/<name>); got "${ref}".`);
184
- }
185
199
  if (create) {
186
200
  assertFlatAssetName(parsed.name);
187
201
  parsed.name = combineCreatePath(normalizeCreateSubPath(create.subPath), parsed.name);
@@ -199,13 +213,10 @@ export function resolveEnvWriteTarget(ref, writeTarget, create) {
199
213
  * Resolve the destination for a secret mutation. Mirrors
200
214
  * {@link resolveSecretPath} but selects the source via
201
215
  * {@link resolveWriteTarget} (writability-checked) instead of the read-side
202
- * {@link findEnvSource}.
216
+ * {@link resolveSecretPath}.
203
217
  */
204
218
  export function resolveSecretWriteTarget(ref, writeTarget, create) {
205
219
  const parsed = parseSecretRef(ref);
206
- if (parsed.type !== "secret") {
207
- throw new UsageError(`Expected a secret ref (secrets/<name>); got "${ref}".`);
208
- }
209
220
  if (create) {
210
221
  assertFlatAssetName(parsed.name);
211
222
  parsed.name = combineCreatePath(normalizeCreateSubPath(create.subPath), parsed.name);
@@ -12,15 +12,16 @@ const CONFIG_HINTS = {
12
12
  DATA_DIR_UNREADABLE: "The data directory is not readable by the user running akm. Check its owner and mode, or point AKM_DATA_DIR / XDG_DATA_HOME somewhere this user owns.",
13
13
  DATA_DIR_NOT_WRITABLE: "Nothing was recorded. Make the akm data directory writable for this process (for an agent sandbox, add it to the writable paths), or point AKM_DATA_DIR / XDG_DATA_HOME somewhere this user can write, then retry.",
14
14
  INDEX_SCHEMA_INCOMPATIBLE: "Run `akm index --full` to rebuild the derived index from the currently materialized sources.",
15
- LLM_NOT_CONFIGURED: 'Run `akm setup` or configure an `engines` entry with `kind: "llm"`, then select it with `defaults.llmEngine`.',
15
+ LLM_NOT_CONFIGURED: "Run `akm setup` to add a connection (an OpenAI-compatible endpoint) or enable a harness; model features need one.",
16
+ AGENT_NOT_CONFIGURED: "Run `akm setup` to enable a harness or add a connection; agent work needs one.",
17
+ SELECTION_NOT_CONFIGURED: "Name one that is configured (`akm health` lists them), correct the name, or add it with `akm setup --name <name> --endpoint <url>` (a connection) or `akm setup --harness <name>`.",
16
18
  TEST_ISOLATION_MISSING: "Under bun test, when AKM_BUNDLE_DIR is set you MUST also set XDG_DATA_HOME (or AKM_DATA_DIR) and XDG_STATE_HOME (or AKM_STATE_DIR) to temp directories so the test does not touch the developer's real ~/.local/share/akm or ~/.local/state/akm.",
17
19
  UNSAFE_STASH_DIR: "Choose a path inside your home directory (e.g. ~/akm) or another empty workspace. The bundle directory cannot be the filesystem root, your home directory itself, or a sensitive system path like /etc, /var, ~/.config, or ~/.ssh.",
18
20
  UNKNOWN_IMPROVE_STRATEGY: "Pass one of the listed strategy names to `--strategy`, or define it under `improve.strategies`. Names are case-sensitive.",
19
- EXECUTION_NOT_AUTHORIZED: "Change the selected tools or update the machine/user execution policy, then retry.",
20
- SECRET_REFERENCE_UNRESOLVED: "Check the secret exists (`akm secret list`) and the name after `secret://` matches, or run `akm secret set <name> <value>` to store it.",
21
+ SECRET_REFERENCE_UNRESOLVED: "Check the secret exists (`akm secret list`) and the ref inside `${…}` matches it, or run `akm secret set secrets/<name>` to store it.",
21
22
  REGISTRY_URL_INVALID: "Registry URLs must be credential-free http(s) URLs. Fix the entry with `akm registry list` / `akm registry add`, or the AKM_REGISTRY_URL / AKM_NPM_REGISTRY variable that supplied it.",
22
23
  };
23
- // Code-review finding: COMPOSITION_INVALID covers several unrelated causes
24
+ // COMPOSITION_INVALID covers several unrelated causes
24
25
  // (a rejected with:, a multi-job source, a composition cycle/depth/size
25
26
  // violation, an invalid child-output reference). USAGE_HINTS below carries
26
27
  // only the with:-rejection text — accurate for every with:-rejection throw
@@ -46,15 +47,11 @@ const USAGE_HINTS = {
46
47
  MISSING_REQUIRED_ARGUMENT: "Refs use the form [bundle//]conceptId, e.g. `akm show knowledge/guide.md` or `akm show skills/deploy`.",
47
48
  UNKNOWN_COMMAND: "Run `akm --help` to see available commands.",
48
49
  UNKNOWN_FLAG: "Run the command with `--help` to see its accepted flags.",
49
- // P2b (docs/plans/specs/p2b-input-bindings.md §1.7 A-N5, §7 F-A3): the
50
- // "arrives in a later 0.9.x release" promise is gone now that task-call
51
- // inputs are implemented. Names the two real rejection causes instead:
52
- // (1) a task target that declares no inputs: at all, (2) commands/<ref> /
53
- // scripts/<ref>, which are never binding surfaces. F-A3 authorizes this
54
- // edit and the matching pinned-string update in
55
- // tests/core/errors-usage-hints.test.ts in the same commit.
50
+ // Names the two real rejection causes: (1) a task target that declares no
51
+ // inputs: at all, (2) commands/<ref> / scripts/<ref>, which are never binding
52
+ // surfaces.
56
53
  //
57
- // Code-review finding: this default is reached ONLY by with:-rejection
54
+ // This default is reached ONLY by with:-rejection
58
55
  // throw sites (the ones above, plus task.ts's noDeclaredInputsError and
59
56
  // freeze.ts's resolveStep) — every other
60
57
  // COMPOSITION_INVALID throw site (multi-job source, composition
@@ -65,10 +62,7 @@ const USAGE_HINTS = {
65
62
  COMPOSITION_INVALID: "Remove the with: block, or target a tasks/<ref> whose source declares inputs: — commands/<ref> and scripts/<ref> steps are not binding surfaces.",
66
63
  TASK_SOURCE_INVALID: "Fix the task source at the reported path and line, then re-run.",
67
64
  TARGET_REF_INVALID: "Targets are canonical asset refs: `commands/review`, `scripts/build.sh`, `tasks/nightly`, `workflows/release`.",
68
- // P4 (docs/plans/specs/p4-deletions-closeout.md §4.1, row B-53, R-R5): the
69
- // original hint named `akm workflow validate`, a verb that was never
70
- // implemented. Points at the two verbs that actually inspect a workflow
71
- // source without executing it.
65
+ // Points at the two verbs that inspect a workflow source without executing it.
72
66
  WORKFLOW_SOURCE_INVALID: "Run `akm lint` to see the failing source location, or `akm workflow plan <ref>` to compile it without writing.",
73
67
  INPUT_BINDING_INVALID: "Check the step's with: keys against the target's declared inputs.",
74
68
  TASK_TARGET_UNSUPPORTED: "Task definitions support command, script, workflow, and shell (run:) targets; akm/command is layered by callers.",
@@ -31,7 +31,7 @@ const CREDENTIAL_KEYS = new Set(EXTRA_PARAMS_CREDENTIAL_KEYS);
31
31
  // shadowing an AKM-managed field, but naming the rule without naming the fix
32
32
  // leaves the reader stuck (#852). Every protected key gets a one-line remedy
33
33
  // baked into its issue message.
34
- /** normalizeExtraParamKey(key) -> the first-class engine field it shadows. */
34
+ /** normalizeExtraParamKey(key) -> the first-class setting it shadows. */
35
35
  const LEGACY_EXTRA_PARAMS_FIELD = {
36
36
  model: "model",
37
37
  temperature: "temperature",
@@ -45,13 +45,13 @@ const EXTRA_PARAMS_NO_FIELD_REMEDY = {
45
45
  responseformat: "AKM controls the response format internally — remove it from extraParams",
46
46
  stream: "AKM controls streaming internally — remove it from extraParams",
47
47
  streamoptions: "AKM controls streaming internally — remove it from extraParams",
48
- chattemplatekwargs: "set engines.<name>.enableThinking instead of chat_template_kwargs.enable_thinking",
48
+ chattemplatekwargs: "set enableThinking instead of chat_template_kwargs.enable_thinking",
49
49
  };
50
50
  function protectedKeyRemedy(normalized) {
51
51
  const field = LEGACY_EXTRA_PARAMS_FIELD[normalized];
52
52
  if (field) {
53
53
  const note = normalized === "reasoningeffort" ? " (moved to a first-class field in 0.9.2)" : "";
54
- return `set engines.<name>.${field} instead${note}`;
54
+ return `set ${field} instead${note}`;
55
55
  }
56
56
  return EXTRA_PARAMS_NO_FIELD_REMEDY[normalized];
57
57
  }
@@ -19,6 +19,7 @@ const COMMON_FIELDS = [
19
19
  "plan",
20
20
  "actions",
21
21
  "skippedProcesses",
22
+ // No longer written (the retired `--require-engines` probe wrote it); kept readable for envelopes a prior release wrote.
22
23
  "engineProbe",
23
24
  "distillSkipped",
24
25
  "validationFailures",
@@ -30,8 +31,7 @@ const COMMON_FIELDS = [
30
31
  "coverageGaps",
31
32
  // R10: no longer written (the write-only eval-cases path was removed),
32
33
  // but kept in the allow-list so `decodeImproveResult` still reads
33
- // improve-result envelopes a prior release wrote with this field —
34
- // AGENTS.md "Reading persisted data".
34
+ // improve-result envelopes a prior release wrote with this field.
35
35
  "evalCasesWritten",
36
36
  "deadUrls",
37
37
  "deadUrlCoverage",
@@ -51,8 +51,7 @@ const COMMON_FIELDS = [
51
51
  "reflectGuardRejectedActions",
52
52
  // No longer written (nothing has set it since the confidence gate was
53
53
  // deleted), but kept in the allow-list so `decodeImproveResult` still reads
54
- // the improve_runs rows an older release wrote with it, its value ignored —
55
- // AGENTS.md "Reading persisted data".
54
+ // the improve_runs rows an older release wrote with it, its value ignored.
56
55
  "gateAutoAcceptedCount",
57
56
  "gateAutoAcceptFailedCount",
58
57
  "triage",
@@ -128,7 +127,7 @@ function validateConsolidationPlan(value) {
128
127
  if (!isRecord(value.configured))
129
128
  fail("plan.consolidation.configured must be an object");
130
129
  // `minPoolSize` is no longer written (the minimum-pool guard was removed in 0.10, #1131); runs an
131
- // older release persisted still carry it, ignored — AGENTS.md "Reading persisted data".
130
+ // older release persisted still carry it, ignored.
132
131
  requireExactFields(value.configured, new Set(["enabled", "minPoolSize", "limit", "maxChunkSize"]));
133
132
  if (value.configured.enabled !== undefined && typeof value.configured.enabled !== "boolean") {
134
133
  fail("plan.consolidation.configured.enabled must be a boolean");
@@ -206,7 +205,6 @@ function validateProcessRoutingRows(value) {
206
205
  if (!Array.isArray(value))
207
206
  fail("plan.processes must be an array");
208
207
  const canonicalNames = IMPROVE_PROCESS_NAMES;
209
- const engineKinds = new Set(["llm", "agent", "sdk"]);
210
208
  const seen = new Set();
211
209
  for (const row of value) {
212
210
  if (!isRecord(row))
@@ -233,8 +231,9 @@ function validateProcessRoutingRows(value) {
233
231
  fail("plan.processes.engine must be a string");
234
232
  if (row.model !== undefined && typeof row.model !== "string")
235
233
  fail("plan.processes.model must be a string");
236
- if (row.engineKind !== undefined && (typeof row.engineKind !== "string" || !engineKinds.has(row.engineKind))) {
237
- fail("plan.processes.engineKind is invalid");
234
+ // "connection" or "harness" now; a run recorded by an earlier release said "llm", "agent" or "sdk".
235
+ if (row.engineKind !== undefined && typeof row.engineKind !== "string") {
236
+ fail("plan.processes.engineKind must be a string");
238
237
  }
239
238
  validateLoweringNotices(row.notices);
240
239
  if (row.unavailable !== undefined) {
@@ -409,7 +408,7 @@ function validateImprovePlan(value, dryRun, plannedRefNames) {
409
408
  // #947 added plan.processes (2026-09-09T09:03:19Z); every run recorded
410
409
  // before it legitimately stored `plan` with no `processes` key at all —
411
410
  // validate the rows only when present, same as `proactive` below, so a
412
- // pre-#947 envelope still decodes (AGENTS.md "Reading persisted data").
411
+ // pre-#947 envelope still decodes.
413
412
  if (value.processes !== undefined)
414
413
  validateProcessRoutingRows(value.processes);
415
414
  if (value.proactive !== undefined)
@@ -41,7 +41,7 @@
41
41
  * branching multiplies work by schema size, never exponentially.
42
42
  *
43
43
  * Returns a flat list of human-readable error strings (empty = valid), each
44
- * prefixed with a JSON-pointer-ish path — the shape `runStructured`'s
44
+ * prefixed with a JSON-pointer-ish path — the shape the structured loop's
45
45
  * corrective-feedback builder wants.
46
46
  *
47
47
  * {@link checkJsonSchemaDefinition} is the companion DEFINITION checker: it
@@ -2,7 +2,7 @@
2
2
  // License, v. 2.0. If a copy of the MPL was not distributed with this
3
3
  // file, You can obtain one at https://mozilla.org/MPL/2.0/.
4
4
  /**
5
- * Deterministic frontmatter lint for `lesson` assets (v1 spec §13).
5
+ * Deterministic frontmatter lint for `lesson` assets.
6
6
  *
7
7
  * The contract is fixed:
8
8
  *
@@ -0,0 +1,80 @@
1
+ // This Source Code Form is subject to the terms of the Mozilla Public
2
+ // License, v. 2.0. If a copy of the MPL was not distributed with this
3
+ // file, You can obtain one at https://mozilla.org/MPL/2.0/.
4
+ import { isPlainObject } from "./config/deep-merge.js";
5
+ import { warnOnce } from "./warn.js";
6
+ /**
7
+ * The portable settings a request's inference may carry and an endpoint's
8
+ * request translates: `temperature`, `maxTokens`, `reasoningEffort` (an asset's
9
+ * `effort:` is the same setting) and `enableThinking`, plus `extraParams`, whose
10
+ * entries are inlined as request fields. `contextLength` is a connection's own
11
+ * key, not a per-call setting.
12
+ */
13
+ export const PORTABLE_INFERENCE_KEYS = [
14
+ "temperature",
15
+ "maxTokens",
16
+ "reasoningEffort",
17
+ "enableThinking",
18
+ "extraParams",
19
+ ];
20
+ /** Whether a request's fields turn thinking on or off, in either of the two spellings an endpoint reads; `undefined` when they say nothing. */
21
+ export function thinkingSetting(request) {
22
+ const kwargs = request.chat_template_kwargs;
23
+ const nested = typeof kwargs === "object" && kwargs !== null ? kwargs.enable_thinking : undefined;
24
+ const value = request.enable_thinking ?? nested;
25
+ return typeof value === "boolean" ? value : undefined;
26
+ }
27
+ /** The wire fields for `inference`, in the order the request lists them. */
28
+ export function inferenceWireFields(inference) {
29
+ if (!inference)
30
+ return {};
31
+ return {
32
+ ...(inference.temperature !== undefined ? { temperature: inference.temperature } : {}),
33
+ ...(inference.maxTokens !== undefined ? { max_tokens: inference.maxTokens } : {}),
34
+ ...inference.extraParams,
35
+ // Which of the two thinking fields an endpoint honors is a fact about it (and any gateway in
36
+ // front of it), not about akm's wording: send both whenever thinking is set.
37
+ ...(inference.enableThinking !== undefined
38
+ ? {
39
+ chat_template_kwargs: { enable_thinking: inference.enableThinking },
40
+ enable_thinking: inference.enableThinking,
41
+ }
42
+ : {}),
43
+ ...(inference.reasoningEffort !== undefined ? { reasoning_effort: inference.reasoningEffort } : {}),
44
+ };
45
+ }
46
+ /**
47
+ * `over` laid on `base`, one level deep: a field that is an object on both sides
48
+ * (`chat_template_kwargs`) is merged key by key, so a call's `enableThinking`
49
+ * does not erase the `thinking_budget` beside it; any other field of `over` wins.
50
+ */
51
+ export function mergeRequestFields(base, over) {
52
+ const merged = { ...base };
53
+ for (const [key, value] of Object.entries(over)) {
54
+ const was = merged[key];
55
+ merged[key] = isPlainObject(was) && isPlainObject(value) ? { ...was, ...value } : value;
56
+ }
57
+ return merged;
58
+ }
59
+ /**
60
+ * The fields of a request that are not the user's to set: the model akm resolved, the conversation and tool
61
+ * state the transport builds, whether the reply streams, and the response format the caller asks for. Whichever
62
+ * way one is written (a connection or model entry's request fields, or an `extraParams` of a call, a process or
63
+ * a workflow step) it is ignored for that field, on both transports.
64
+ */
65
+ export const OWNED_REQUEST_FIELDS = ["model", "messages", "tools", "stream", "response_format"];
66
+ function withoutOwnedFields(request) {
67
+ const written = OWNED_REQUEST_FIELDS.filter((field) => Object.hasOwn(request, field));
68
+ if (written.length === 0)
69
+ return request;
70
+ warnOnce(`request-fields:owned:${written.join(",")}`, `Request field${written.length === 1 ? "" : "s"} ${written.map((field) => `"${field}"`).join(", ")} in a connection's or model entry's request fields, or in an extraParams, ${written.length === 1 ? "is" : "are"} ignored: akm sets the model, the conversation, the tools, streaming and the response format itself.`);
71
+ return Object.fromEntries(Object.entries(request).filter(([field]) => !OWNED_REQUEST_FIELDS.includes(field)));
72
+ }
73
+ /**
74
+ * The fields a request carries: `request` as written, with the translation of `inference` laid on it, less the
75
+ * fields akm owns, which are taken out of the merged result so no layer can bring one back. The one place
76
+ * portable settings meet an endpoint's own spelling, and where both transports take the user's fields from.
77
+ */
78
+ export function effectiveRequestFields(request, inference) {
79
+ return withoutOwnedFields(mergeRequestFields(request ?? {}, inferenceWireFields(inference ?? undefined)));
80
+ }
@@ -5,8 +5,8 @@
5
5
  * Shared JSON parsing utilities for LLM and agent output.
6
6
  *
7
7
  * Lives in `src/core/` so that both `src/llm/` and `src/integrations/agent/`
8
- * can import without crossing the one-way boundary defined by v1 spec §9.7
9
- * (agent/ must not import from llm/).
8
+ * can import without crossing the one-way boundary (agent/ must not import
9
+ * from llm/).
10
10
  *
11
11
  * The canonical implementation is ported from `src/llm/client.ts` (most
12
12
  * complete version):
@@ -311,12 +311,7 @@ export function getStateDir(env = process.env, platform = process.platform) {
311
311
  * its `stash_dir` column — so two stashes on one machine never collide.
312
312
  *
313
313
  * Reuses {@link shortHash} (bundle-id.ts) rather than growing a second
314
- * sha256-truncated-hex helper. (The other existing option,
315
- * `getCurrentWorkflowScopeKey`'s `dir:v1:<sha256>` in
316
- * `src/workflows/authoring/scope-key.ts`, is a state.db column value for a
317
- * different subsystem — full untruncated hex plus a `dir:v1:` prefix, which
318
- * is neither filesystem-safe as a directory segment on Windows (`:`) nor
319
- * short, so it is not a fit here.) `shortHash` trims to 8 hex chars (32
314
+ * sha256-truncated-hex helper. `shortHash` trims to 8 hex chars (32
320
315
  * bits) — fine at its original call site because a collision only ever
321
316
  * shortens a batch-unique slug suffix that a retry loop immediately
322
317
  * re-disambiguates. Here there is no such retry loop, but a machine
@@ -348,7 +343,38 @@ export function getUnresolvedSourcesDir(stashDir) {
348
343
  export function getStashLocksDir(stashDir) {
349
344
  return stashScopedDir(path.join(getStateDir(), "locks"), stashDir);
350
345
  }
351
- // ── Scheduled-task runtime directories (logs + history) ──────────────────────
346
+ /**
347
+ * The directories this akm resolved, as the `AKM_*` variables that name them, so a
348
+ * child that runs `akm` (an exec unit, an agent CLI) uses the same installation even
349
+ * when the parent found them through `XDG_*_HOME`. `AKM_BUNDLE_DIR` is passed only
350
+ * when the parent set one.
351
+ */
352
+ export function akmLocations() {
353
+ const locations = {
354
+ AKM_CONFIG_DIR: getConfigDir(),
355
+ AKM_DATA_DIR: getDataDir(),
356
+ AKM_CACHE_DIR: getCacheDir(),
357
+ AKM_STATE_DIR: getStateDir(),
358
+ };
359
+ const bundleDir = process.env.AKM_BUNDLE_DIR?.trim();
360
+ if (bundleDir)
361
+ locations.AKM_BUNDLE_DIR = bundleDir;
362
+ return locations;
363
+ }
364
+ /**
365
+ * The environment of a process akm starts for the user: akm's own, as the program
366
+ * has it when the user runs it from their shell, with {@link akmLocations} set over
367
+ * it. akm filters nothing.
368
+ */
369
+ export function childProcessEnv() {
370
+ const inherited = {};
371
+ for (const [name, value] of Object.entries(process.env)) {
372
+ if (value !== undefined)
373
+ inherited[name] = value;
374
+ }
375
+ return { ...inherited, ...akmLocations() };
376
+ }
377
+ // ── Scheduled-task runtime directory (logs; run history lives in state.db) ───
352
378
  export function getTaskLogDir() {
353
379
  return path.join(getCacheDir(), "tasks", "logs");
354
380
  }
@@ -356,9 +382,6 @@ export function getTaskLogDir() {
356
382
  export function getRunLogDir(kind) {
357
383
  return path.join(getCacheDir(), "logs", kind);
358
384
  }
359
- export function getTaskHistoryDir() {
360
- return path.join(getCacheDir(), "tasks", "history");
361
- }
362
385
  // ── Default stash directory ──────────────────────────────────────────────────
363
386
  export function getDefaultStashDir(env = process.env) {
364
387
  const override = env.AKM_BUNDLE_DIR?.trim();
@@ -68,16 +68,14 @@ export const DERIVED_SUFFIX = ".derived";
68
68
  // compile if a key is missing). A plain `as const` literal tuple adds no
69
69
  // import, so it lives here without breaking the D1-5 import-free invariant.
70
70
  /**
71
- * The AKM-owned built-in asset type keys — the deleted `common.ts` `ASSET_TYPES`
72
- * set (same order) minus the retired `wiki` type (chunk 4); `instruction`
73
- * (CLAUDE.md / AGENTS.md project-instruction files) is the newest, added for the
74
- * format-family adapters (spec §6/§7 instruction row, maintainer resolution
75
- * 2026-07). An instruction file is a read-like-knowledge markdown document, so
76
- * it reuses knowledge's presentation shape (label "Instruction", `knowledge-md`
77
- * renderer, a "read the project instructions" action) rather than the generic
78
- * fallback. `wiki` was removed here in chunk 4 ("the wiki ASSET-TYPE dies", plan
79
- * §11 Chunk 4 / §7.4): the LLM Wiki structure now lives in the first-class
80
- * `llm-wiki` adapter whose page kinds are open (foreign) types, not AKM-owned.
71
+ * The AKM-owned built-in asset type keys. `instruction`
72
+ * (CLAUDE.md / AGENTS.md project-instruction files) is the one added for the
73
+ * format-family adapters: an instruction file is a read-like-knowledge
74
+ * markdown document, so it reuses knowledge's presentation shape (label
75
+ * "Instruction", `knowledge-md` renderer, a "read the project instructions"
76
+ * action) rather than the generic fallback. `wiki` is not an AKM-owned type:
77
+ * the LLM Wiki structure lives in the first-class `llm-wiki` adapter whose
78
+ * page kinds are open (foreign) types.
81
79
  */
82
80
  export const KNOWN_TYPES = [
83
81
  "skill",