akm-cli 0.9.1 → 0.9.2-alpha.2

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 (350) hide show
  1. package/CHANGELOG.md +103 -28
  2. package/README.md +3 -1
  3. package/SECURITY.md +1 -1
  4. package/STABILITY.md +1 -1
  5. package/dist/akm +2 -2
  6. package/dist/akm-migrate +2 -2
  7. package/dist/assets/hints/cli-hints-full.md +14 -9
  8. package/dist/assets/improve-strategies/proactive-maintenance.json +1 -1
  9. package/dist/assets/improve-strategies/reflect-distill.json +1 -1
  10. package/dist/assets/models.json +35 -0
  11. package/dist/assets/stash-skeleton/facts/conventions/backlinks.md +3 -4
  12. package/dist/assets/stash-skeleton/facts/conventions/organization.md +1 -3
  13. package/dist/assets/tasks/core/extract.yml +6 -5
  14. package/dist/assets/tasks/core/improve.yml +6 -5
  15. package/dist/assets/tasks/core/index-refresh.yml +6 -5
  16. package/dist/assets/tasks/core/sync.yml +6 -5
  17. package/dist/assets/tasks/core/version-check.yml +6 -5
  18. package/dist/assets/tasks/improve/akm-graph-refresh-weekly.yml +6 -5
  19. package/dist/assets/tasks/improve/akm-improve-catchup.yml +6 -5
  20. package/dist/assets/tasks/improve/akm-improve-consolidate.yml +6 -5
  21. package/dist/assets/tasks/improve/akm-improve-frequent.yml +6 -5
  22. package/dist/assets/tasks/improve/akm-improve-nightly.yml +6 -5
  23. package/dist/cli/confirm.js +2 -2
  24. package/dist/cli/parse-args.js +3 -24
  25. package/dist/cli/retired-commands.js +1 -1
  26. package/dist/cli/shared.js +2 -2
  27. package/dist/cli.js +11 -9
  28. package/dist/commands/agent/agent-dispatch.js +55 -89
  29. package/dist/commands/agent/contribute-cli.js +12 -45
  30. package/dist/commands/command/builtin-action.js +32 -0
  31. package/dist/commands/command/command-cli.js +99 -0
  32. package/dist/commands/command/command-execution.js +308 -0
  33. package/dist/commands/command/execution-source-loader.js +176 -0
  34. package/dist/commands/command/portable-template.js +60 -0
  35. package/dist/commands/config-cli.js +10 -4
  36. package/dist/commands/env/env.js +4 -2
  37. package/dist/commands/feedback-cli.js +1 -1
  38. package/dist/commands/health/checks.js +241 -29
  39. package/dist/commands/health/html-report.js +0 -14
  40. package/dist/commands/health/report-view-model.js +0 -1
  41. package/dist/commands/health/surfaces.js +6 -7
  42. package/dist/commands/health/types.js +0 -2
  43. package/dist/commands/health.js +63 -18
  44. package/dist/commands/improve/collapse-detector.js +5 -6
  45. package/dist/commands/improve/consolidate.js +251 -214
  46. package/dist/commands/improve/distill/promote-memory.js +71 -34
  47. package/dist/commands/improve/distill/quality-gate.js +17 -5
  48. package/dist/commands/improve/distill.js +232 -155
  49. package/dist/commands/improve/eligibility.js +112 -79
  50. package/dist/commands/improve/execution.js +57 -0
  51. package/dist/commands/improve/extract-cli.js +5 -5
  52. package/dist/commands/improve/extract-prompt.js +64 -22
  53. package/dist/commands/improve/extract.js +608 -360
  54. package/dist/commands/improve/improve-strategies.js +43 -14
  55. package/dist/commands/improve/improve.js +249 -29
  56. package/dist/commands/improve/loop-stages.js +11 -17
  57. package/dist/commands/improve/memory/memory-contradiction-detect.js +90 -66
  58. package/dist/commands/improve/outcome-loop.js +22 -38
  59. package/dist/commands/improve/planner.js +134 -0
  60. package/dist/commands/improve/preparation.js +730 -409
  61. package/dist/commands/improve/reflect.js +386 -223
  62. package/dist/commands/improve/run-context.js +3 -4
  63. package/dist/commands/improve/salience.js +6 -58
  64. package/dist/commands/improve/session-asset.js +12 -12
  65. package/dist/commands/lint/index.js +101 -29
  66. package/dist/commands/migrate-cli.js +11 -69
  67. package/dist/commands/migration-tool.js +6 -9
  68. package/dist/commands/models-cli.js +27 -0
  69. package/dist/commands/proposal/drain.js +258 -186
  70. package/dist/commands/proposal/proposal-cli.js +32 -10
  71. package/dist/commands/proposal/proposal.js +2 -5
  72. package/dist/commands/proposal/propose.js +192 -172
  73. package/dist/commands/proposal/repository.js +54 -91
  74. package/dist/commands/proposal/validators/proposal-validators.js +9 -7
  75. package/dist/commands/read/curate.js +53 -22
  76. package/dist/commands/read/registry-search.js +25 -9
  77. package/dist/commands/read/remember-cli.js +14 -2
  78. package/dist/commands/read/search.js +10 -4
  79. package/dist/commands/read/show.js +139 -153
  80. package/dist/commands/registry-cli.js +16 -7
  81. package/dist/commands/remember.js +33 -18
  82. package/dist/commands/sources/add-cli.js +19 -178
  83. package/dist/commands/sources/bundle-cli.js +15 -3
  84. package/dist/commands/sources/dangerous-env-audit.js +135 -0
  85. package/dist/commands/sources/info.js +2 -1
  86. package/dist/commands/sources/installed-stashes.js +901 -177
  87. package/dist/commands/sources/schema-repair.js +174 -95
  88. package/dist/commands/sources/self-update.js +30 -74
  89. package/dist/commands/sources/source-add.js +3 -5
  90. package/dist/commands/sources/sources-cli.js +2 -15
  91. package/dist/commands/sources/update-transaction.js +220 -0
  92. package/dist/commands/tasks/tasks-cli.js +3 -3
  93. package/dist/commands/tasks/tasks.js +736 -317
  94. package/dist/commands/workflow-cli.js +2 -2
  95. package/dist/core/adapter/adapters/agent-skills-adapter.js +3 -0
  96. package/dist/core/adapter/adapters/akm-adapter.js +85 -35
  97. package/dist/core/adapter/adapters/akm-lint.js +54 -39
  98. package/dist/core/adapter/adapters/akm-metadata.js +45 -45
  99. package/dist/core/adapter/adapters/akm-task-adapter.js +32 -49
  100. package/dist/core/adapter/adapters/akm-workflow-adapter.js +38 -23
  101. package/dist/core/adapter/adapters/dotenv-adapter.js +30 -1
  102. package/dist/core/adapter/adapters/generic-files-adapter.js +11 -0
  103. package/dist/core/adapter/adapters/index.js +0 -9
  104. package/dist/core/adapter/adapters/llm-wiki-adapter.js +4 -0
  105. package/dist/core/adapter/adapters/okf-adapter.js +4 -0
  106. package/dist/core/adapter/adapters/opencode-adapter.js +5 -8
  107. package/dist/core/adapter/adapters/tool-dir-shared.js +63 -6
  108. package/dist/core/adapter/adapters/website-snapshot-adapter.js +4 -0
  109. package/dist/core/adapter/execution-source.js +308 -0
  110. package/dist/core/adapter/recognize-match.js +36 -13
  111. package/dist/core/adapter/registry.js +0 -9
  112. package/dist/core/asset/stash-meta.js +94 -4
  113. package/dist/core/common.js +6 -11
  114. package/dist/core/config/config-io.js +3 -3
  115. package/dist/core/config/config-schema.js +18 -40
  116. package/dist/core/config/config-sources.js +11 -21
  117. package/dist/core/config/config-walker.js +31 -13
  118. package/dist/core/config/config.js +23 -26
  119. package/dist/core/config/schema/engines.js +8 -7
  120. package/dist/core/config/schema/improve-processes.js +29 -5
  121. package/dist/core/config/schema/index-config.js +0 -27
  122. package/dist/core/config/schema/primitives.js +1 -23
  123. package/dist/core/config/schema/sources-bundles.js +13 -16
  124. package/dist/core/errors.js +2 -0
  125. package/dist/core/events.js +68 -32
  126. package/dist/core/extra-params.js +1 -0
  127. package/dist/core/improve-result.js +315 -0
  128. package/dist/core/lesson-lint.js +0 -6
  129. package/dist/core/maintenance-barrier.js +4 -4
  130. package/dist/core/network-policy.js +152 -0
  131. package/dist/core/paths.js +1 -1
  132. package/dist/core/recognition-util.js +4 -4
  133. package/dist/core/registry-url.js +456 -0
  134. package/dist/core/state/migrations.js +161 -47
  135. package/dist/core/state-db.js +453 -80
  136. package/dist/core/system-error.js +32 -0
  137. package/dist/core/time.js +2 -12
  138. package/dist/core/write-source.js +0 -18
  139. package/dist/execution/directory-identity.js +52 -0
  140. package/dist/execution/executable-identity.js +107 -0
  141. package/dist/execution/guarded-source.js +398 -0
  142. package/dist/execution/json.js +95 -0
  143. package/dist/{commands/health/types-session-log.js → execution/limits.js} +2 -1
  144. package/dist/execution/record.js +55 -0
  145. package/dist/execution/resolved-request.js +730 -0
  146. package/dist/execution/source.js +320 -0
  147. package/dist/indexer/bundle-identity-guard.js +5 -4
  148. package/dist/indexer/db/graph-db.js +33 -0
  149. package/dist/indexer/graph/graph-boost.js +3 -4
  150. package/dist/indexer/graph/graph-extraction.js +562 -373
  151. package/dist/indexer/index-written-assets.js +78 -39
  152. package/dist/indexer/indexer.js +471 -432
  153. package/dist/indexer/installations.js +6 -0
  154. package/dist/indexer/lookup/adapter-concept-owner.js +283 -0
  155. package/dist/indexer/materialize-embeddings.js +155 -0
  156. package/dist/indexer/passes/memory-inference.js +227 -174
  157. package/dist/indexer/passes/metadata.js +263 -118
  158. package/dist/indexer/scan/doc-to-entry.js +7 -10
  159. package/dist/indexer/scan/drain-dir.js +51 -23
  160. package/dist/indexer/search/db-search.js +156 -50
  161. package/dist/indexer/search/fts-query.js +40 -40
  162. package/dist/indexer/search/ranking.js +36 -1
  163. package/dist/indexer/search/search-attribution.js +3 -1
  164. package/dist/indexer/search/search-fields.js +23 -14
  165. package/dist/indexer/search/search-hit-enrichers.js +1 -1
  166. package/dist/indexer/search/search-source.js +7 -16
  167. package/dist/indexer/search/semantic-status.js +10 -1
  168. package/dist/indexer/usage/show-usage.js +105 -0
  169. package/dist/indexer/usage/usage-events.js +7 -2
  170. package/dist/indexer/walk/matchers.js +40 -10
  171. package/dist/indexer/walk/path-resolver.js +5 -2
  172. package/dist/indexer/walk/walker.js +20 -2
  173. package/dist/integrations/agent/builder-shared.js +3 -6
  174. package/dist/integrations/agent/conversation-fallback.js +16 -0
  175. package/dist/integrations/agent/engine-resolution.js +87 -87
  176. package/dist/integrations/agent/execution-cascade.js +566 -0
  177. package/dist/integrations/agent/execution-definitions.js +211 -0
  178. package/dist/integrations/agent/execution-lowering.js +811 -0
  179. package/dist/integrations/agent/execution-preparation.js +67 -0
  180. package/dist/integrations/agent/index.js +0 -2
  181. package/dist/integrations/agent/inline-execution.js +74 -0
  182. package/dist/integrations/agent/model-map.js +515 -0
  183. package/dist/integrations/agent/persona-fallback.js +30 -0
  184. package/dist/integrations/agent/request-lowering.js +186 -0
  185. package/dist/integrations/agent/runner-dispatch.js +230 -37
  186. package/dist/integrations/agent/runner.js +12 -83
  187. package/dist/integrations/harnesses/aider/agent-builder.js +8 -0
  188. package/dist/integrations/harnesses/aider/index.js +0 -1
  189. package/dist/integrations/harnesses/amazonq/agent-builder.js +8 -0
  190. package/dist/integrations/harnesses/amazonq/index.js +0 -1
  191. package/dist/integrations/harnesses/claude/agent-builder.js +14 -1
  192. package/dist/integrations/harnesses/claude/index.js +1 -5
  193. package/dist/integrations/harnesses/claude/session-log.js +3 -33
  194. package/dist/integrations/harnesses/codex/agent-builder.js +8 -0
  195. package/dist/integrations/harnesses/codex/index.js +0 -1
  196. package/dist/integrations/harnesses/copilot/agent-builder.js +8 -0
  197. package/dist/integrations/harnesses/copilot/index.js +0 -1
  198. package/dist/integrations/harnesses/gemini/agent-builder.js +8 -0
  199. package/dist/integrations/harnesses/gemini/index.js +0 -1
  200. package/dist/integrations/harnesses/index.js +4 -44
  201. package/dist/integrations/harnesses/opencode/agent-builder.js +16 -9
  202. package/dist/integrations/harnesses/opencode/index.js +0 -2
  203. package/dist/integrations/harnesses/opencode/session-log.js +14 -204
  204. package/dist/integrations/harnesses/opencode-sdk/harness.js +12 -1
  205. package/dist/integrations/harnesses/opencode-sdk/sdk-runner.js +40 -42
  206. package/dist/integrations/harnesses/openhands/agent-builder.js +8 -0
  207. package/dist/integrations/harnesses/openhands/index.js +0 -1
  208. package/dist/integrations/harnesses/pi/agent-builder.js +8 -0
  209. package/dist/integrations/harnesses/pi/index.js +0 -1
  210. package/dist/integrations/harnesses/shared.js +0 -1
  211. package/dist/integrations/harnesses/types.js +1 -3
  212. package/dist/integrations/lockfile.js +82 -79
  213. package/dist/integrations/session-logs/index.js +6 -17
  214. package/dist/integrations/session-logs/provider-base.js +1 -29
  215. package/dist/llm/client.js +10 -5
  216. package/dist/llm/embedder.js +6 -7
  217. package/dist/llm/embedders/local.js +37 -88
  218. package/dist/llm/embedders/types.js +1 -1
  219. package/dist/llm/graph-extract.js +75 -50
  220. package/dist/llm/index-passes.js +43 -5
  221. package/dist/llm/memory-infer.js +8 -6
  222. package/dist/llm/metadata-enhance.js +5 -3
  223. package/dist/llm/structured-call.js +122 -25
  224. package/dist/output/format-exempt.js +1 -1
  225. package/dist/output/render-registry.js +0 -16
  226. package/dist/output/renderers.js +12 -7
  227. package/dist/output/shapes/curate.js +1 -0
  228. package/dist/output/shapes/helpers.js +10 -2
  229. package/dist/output/shapes/passthrough.js +2 -0
  230. package/dist/output/text/command-format.js +31 -33
  231. package/dist/output/text/health-format.js +1 -29
  232. package/dist/output/text/migrate.js +6 -56
  233. package/dist/output/text/proposal-format.js +16 -1
  234. package/dist/output/text/workflow-format.js +16 -0
  235. package/dist/registry/network.js +279 -0
  236. package/dist/registry/pinned-request-helper.js +247 -0
  237. package/dist/registry/pinned-transport.js +717 -0
  238. package/dist/registry/providers/skills-sh.js +18 -6
  239. package/dist/registry/providers/static-index.js +20 -7
  240. package/dist/registry/resolve.js +53 -28
  241. package/dist/scripts/akm-migrate-node.js +19334 -52269
  242. package/dist/scripts/akm-migrate.js +19270 -51612
  243. package/dist/setup/registry-stash-loader.js +64 -20
  244. package/dist/setup/semantic-assets.js +9 -34
  245. package/dist/setup/setup.js +12 -30
  246. package/dist/setup/source-identity.js +17 -0
  247. package/dist/setup/steps/sources.js +36 -15
  248. package/dist/setup/steps/tasks.js +39 -11
  249. package/dist/sources/providers/git-provider.js +3 -3
  250. package/dist/sources/providers/npm.js +2 -2
  251. package/dist/sources/providers/provider-utils.js +4 -3
  252. package/dist/sources/providers/website.js +11 -7
  253. package/dist/sources/snapshot-fetchers/host-guard.js +9 -136
  254. package/dist/sources/snapshot-fetchers/website-ingest.js +25 -109
  255. package/dist/sources/website-url.js +73 -0
  256. package/dist/storage/engines/sqlite-migrations.js +81 -26
  257. package/dist/storage/managed-db.js +27 -24
  258. package/dist/storage/repositories/events-repository.js +3 -0
  259. package/dist/storage/repositories/index-connection.js +42 -10
  260. package/dist/storage/repositories/index-entries-repository.js +203 -229
  261. package/dist/storage/repositories/index-entry-mapper.js +8 -12
  262. package/dist/storage/repositories/index-entry-schema.js +255 -0
  263. package/dist/storage/repositories/index-fts-repository.js +64 -71
  264. package/dist/storage/repositories/index-llm-cache-repository.js +8 -13
  265. package/dist/storage/repositories/index-meta-repository.js +0 -11
  266. package/dist/storage/repositories/index-schema.js +74 -350
  267. package/dist/storage/repositories/index-utility-repository.js +12 -17
  268. package/dist/storage/repositories/index-vec-repository.js +56 -7
  269. package/dist/storage/repositories/proposals-repository.js +4 -127
  270. package/dist/storage/repositories/registry-cache.js +2 -1
  271. package/dist/storage/repositories/task-history-repository.js +20 -40
  272. package/dist/storage/repositories/workflow-runs-repository.js +228 -129
  273. package/dist/storage/sqlite-read-snapshot.js +148 -0
  274. package/dist/tasks/backends/cron.js +170 -42
  275. package/dist/tasks/backends/index.js +1 -1
  276. package/dist/tasks/backends/launchd.js +787 -202
  277. package/dist/tasks/backends/schtasks.js +282 -83
  278. package/dist/tasks/embedded.js +7 -7
  279. package/dist/tasks/frozen-script.js +50 -0
  280. package/dist/tasks/resolve-akm-bin.js +5 -1
  281. package/dist/tasks/runner.js +239 -251
  282. package/dist/tasks/runtime-v3.js +281 -0
  283. package/dist/tasks/scheduler-binding.js +272 -0
  284. package/dist/tasks/scheduler-invocation.js +57 -43
  285. package/dist/tasks/scheduler-sync.js +654 -0
  286. package/dist/tasks/source-v3.js +752 -0
  287. package/dist/tasks/standalone-script-entry.js +5 -0
  288. package/dist/tasks/task-id.js +29 -0
  289. package/dist/workflows/authoring/authoring.js +15 -32
  290. package/dist/workflows/exec/dispatch-redaction.js +14 -8
  291. package/dist/workflows/exec/exec-unit.js +7 -28
  292. package/dist/workflows/exec/frozen-judge.js +57 -89
  293. package/dist/workflows/exec/lowering-notices.js +23 -0
  294. package/dist/workflows/exec/native-executor.js +301 -458
  295. package/dist/workflows/exec/param-secrets.js +4 -3
  296. package/dist/workflows/exec/run-workflow.js +26 -32
  297. package/dist/workflows/exec/step-work.js +105 -109
  298. package/dist/workflows/exec/unit-dispatch.js +103 -27
  299. package/dist/workflows/exec/unit-writer.js +3 -3
  300. package/dist/workflows/exec/worktree.js +2 -2
  301. package/dist/workflows/ir/compile.js +86 -72
  302. package/dist/workflows/ir/environment-v4.js +328 -0
  303. package/dist/workflows/ir/freeze-v4.js +122 -0
  304. package/dist/workflows/ir/plan-hash.js +13 -7
  305. package/dist/workflows/ir/schema-v4.js +525 -0
  306. package/dist/workflows/ir/schema.js +25 -284
  307. package/dist/workflows/ir/source-freeze-v4.js +506 -0
  308. package/dist/workflows/parser.js +27 -24
  309. package/dist/workflows/program/schema.js +1 -2
  310. package/dist/workflows/renderer.js +42 -29
  311. package/dist/workflows/resource-limits.js +4 -5
  312. package/dist/workflows/runtime/agent-identity.js +11 -13
  313. package/dist/workflows/runtime/plan-classifier.js +8 -8
  314. package/dist/workflows/runtime/runs.js +27 -43
  315. package/dist/workflows/runtime/workflow-asset-loader.js +45 -205
  316. package/dist/workflows/source-files.js +373 -0
  317. package/dist/workflows/source-ir/compile.js +196 -0
  318. package/dist/workflows/source-ir/github-yaml.js +577 -0
  319. package/dist/workflows/source-ir/ordering.js +38 -0
  320. package/dist/workflows/source-ir/program.js +50 -0
  321. package/dist/workflows/source-ir/result.js +26 -0
  322. package/dist/workflows/source-ir/schema.js +772 -0
  323. package/dist/workflows/source-ir/semantics.js +242 -0
  324. package/dist/workflows/source-ir/uses.js +14 -0
  325. package/docs/README.md +2 -0
  326. package/docs/migration/README.md +3 -1
  327. package/docs/migration/release-notes/0.9.2.md +55 -0
  328. package/docs/migration/release-notes/README.md +5 -0
  329. package/docs/migration/v0.8-to-v0.9.md +76 -1077
  330. package/docs/migration/v0.9.0-troubleshooting.md +104 -516
  331. package/docs/migration/v0.9.1-to-v0.9.2.md +150 -0
  332. package/docs/reference/README.md +1 -0
  333. package/docs/reference/cli.md +230 -98
  334. package/docs/reference/configuration.md +159 -36
  335. package/docs/reference/data-and-telemetry.md +19 -1
  336. package/docs/reference/supported-formats.md +23 -3
  337. package/docs/reference/tasks.md +182 -0
  338. package/docs/reference/workflow-schema.md +91 -40
  339. package/docs/reference/workflows.md +33 -6
  340. package/package.json +10 -6
  341. package/schemas/akm-config.json +372 -224
  342. package/schemas/akm-task.json +324 -80
  343. package/schemas/akm-workflow.json +6 -9
  344. package/dist/core/migration-operation.js +0 -75
  345. package/dist/integrations/agent/model-aliases.js +0 -74
  346. package/dist/tasks/parser.js +0 -380
  347. package/dist/tasks/schema.js +0 -123
  348. package/dist/tasks/validator.js +0 -80
  349. package/dist/workflows/ir/freeze.js +0 -320
  350. package/dist/workflows/runtime/document-cache.js +0 -13
@@ -8,59 +8,74 @@ import { formatExtraParamsIssue, validateExtraParams } from "../../core/extra-pa
8
8
  import { collectSensitiveValues } from "../../core/redaction.js";
9
9
  import { getHarness } from "../harnesses/index.js";
10
10
  import { DEFAULT_AGENT_TIMEOUT_MS, DEFAULT_LLM_TIMEOUT_MS } from "./config.js";
11
- import { resolveLlmModel, resolveModel } from "./model-aliases.js";
12
11
  import { getBuiltinAgentProfile } from "./profiles.js";
13
12
  function hasOwn(value, key) {
14
13
  return Object.hasOwn(value, key);
15
14
  }
15
+ function ownValue(value, key) {
16
+ return hasOwn(value, key) ? value[key] : undefined;
17
+ }
18
+ function sterileRecord(value) {
19
+ return Object.assign(Object.create(null), value);
20
+ }
16
21
  function envName(reference) {
17
22
  const match = /^\$(?:\{)?([A-Za-z_][A-Za-z0-9_]*)(?:\})?$/.exec(reference);
18
23
  return match?.[1];
19
24
  }
20
25
  function selectedEngineName(config, layers, llmOnly) {
21
26
  for (let index = layers.length - 1; index >= 0; index--) {
22
- if (layers[index]?.engine !== undefined)
23
- return layers[index]?.engine;
27
+ const layer = layers[index];
28
+ if (!layer)
29
+ continue;
30
+ const engine = ownValue(layer, "engine");
31
+ if (engine !== undefined)
32
+ return engine;
24
33
  }
25
- return llmOnly ? config.defaults?.llmEngine : config.defaults?.engine;
34
+ const defaults = ownValue(config, "defaults");
35
+ return defaults ? ownValue(defaults, llmOnly ? "llmEngine" : "engine") : undefined;
26
36
  }
27
37
  function resolveEngineConfig(name, config) {
28
- const engine = config.engines?.[name];
38
+ const engines = ownValue(config, "engines");
39
+ const engine = engines && hasOwn(engines, name) ? engines[name] : undefined;
29
40
  if (!engine) {
30
41
  throw new ConfigError(`Engine "${name}" is not configured.`, "INVALID_CONFIG_FILE");
31
42
  }
32
43
  return engine;
33
44
  }
34
45
  function resolveCredential(name, engine, config) {
35
- if (engine.apiKey !== undefined) {
36
- const explicit = envName(engine.apiKey);
46
+ const apiKey = ownValue(engine, "apiKey");
47
+ if (apiKey !== undefined) {
48
+ const explicit = envName(apiKey);
37
49
  if (!explicit)
38
50
  throw new ConfigError(`Engine "${name}" has an invalid symbolic apiKey reference.`, "INVALID_CONFIG_FILE");
39
51
  return { names: [explicit], required: true };
40
52
  }
41
53
  const specific = `AKM_ENGINE_${name.toUpperCase().replaceAll("-", "_")}_API_KEY`;
42
- return config.defaults?.llmEngine === name
54
+ const defaults = ownValue(config, "defaults");
55
+ return (defaults ? ownValue(defaults, "llmEngine") : undefined) === name
43
56
  ? { names: [specific, "AKM_LLM_API_KEY"], required: false }
44
57
  : { names: [specific], required: false };
45
58
  }
46
59
  /**
47
- * Read a credential descriptor's value out of `process.env`: the FIRST
48
- * non-empty trimmed value across `names`, in declared order. A `required`
49
- * descriptor that resolves to nothing is a config error naming its PRIMARY
50
- * variable — the one an operator is told to set.
51
- *
52
- * The ONE env-credential seam. The live-config dispatch boundary
53
- * ({@link materializeLlmConnection}) and the FROZEN workflow dispatch boundary
54
- * (`materializeFrozenLlm` in `workflows/exec/unit-dispatch.ts`, whose frozen
55
- * snapshots carry a structurally identical descriptor) both read through it, so
56
- * lookup order and the failure message cannot drift between them.
60
+ * Lookup-only credential projection used by redaction inventories. Returns the
61
+ * first non-empty trimmed value without enforcing a required descriptor.
57
62
  */
58
- export function resolveCredentialFromEnv(credential) {
63
+ export function lookupCredentialFromEnv(credential, envSource = process.env) {
59
64
  for (const name of credential?.names ?? []) {
60
- const candidate = process.env[name]?.trim();
65
+ const candidate = envSource[name]?.trim();
61
66
  if (candidate)
62
67
  return candidate;
63
68
  }
69
+ return undefined;
70
+ }
71
+ /**
72
+ * The enforcing env-credential seam. Live and frozen dispatch use the same
73
+ * ordered lookup; a missing required descriptor names its primary variable.
74
+ */
75
+ export function resolveCredentialFromEnv(credential, envSource = process.env) {
76
+ const value = lookupCredentialFromEnv(credential, envSource);
77
+ if (value)
78
+ return value;
64
79
  if (credential?.required) {
65
80
  throw new ConfigError(`Required engine credential ${credential.names[0]} is not set.`, "INVALID_CONFIG_FILE");
66
81
  }
@@ -69,7 +84,7 @@ export function resolveCredentialFromEnv(credential) {
69
84
  /** Collect materialized engine credentials for output and persistence redaction. */
70
85
  export function collectEngineCredentialValues(config, envSource = process.env) {
71
86
  const values = new Set();
72
- for (const [name, engine] of Object.entries(config.engines ?? {})) {
87
+ for (const [name, engine] of Object.entries(ownValue(config, "engines") ?? {})) {
73
88
  if (engine.kind !== "llm")
74
89
  continue;
75
90
  for (const envVar of resolveCredential(name, engine, config)?.names ?? []) {
@@ -87,6 +102,25 @@ function effectiveTimeout(engine, layers, fallback) {
87
102
  }
88
103
  return hasOwn(engine, "timeoutMs") ? (engine.timeoutMs ?? null) : fallback;
89
104
  }
105
+ function rawLlmConnection(engine) {
106
+ const connection = {
107
+ provider: ownValue(engine, "provider"),
108
+ endpoint: ownValue(engine, "endpoint"),
109
+ model: ownValue(engine, "model"),
110
+ temperature: ownValue(engine, "temperature"),
111
+ maxTokens: ownValue(engine, "maxTokens"),
112
+ supportsJsonSchema: ownValue(engine, "supportsJsonSchema"),
113
+ extraParams: ownValue(engine, "extraParams"),
114
+ contextLength: ownValue(engine, "contextLength"),
115
+ enableThinking: ownValue(engine, "enableThinking"),
116
+ reasoningEffort: ownValue(engine, "reasoningEffort"),
117
+ };
118
+ for (const key of Object.keys(connection)) {
119
+ if (connection[key] === undefined)
120
+ delete connection[key];
121
+ }
122
+ return connection;
123
+ }
90
124
  export function resolveLlmEngineUse(config, layers, options = {}) {
91
125
  const name = selectedEngineName(config, layers, true);
92
126
  if (!name) {
@@ -98,49 +132,44 @@ export function resolveLlmEngineUse(config, layers, options = {}) {
98
132
  if (engine.kind !== "llm") {
99
133
  throw new ConfigError(`Engine "${name}" is not an LLM engine.`, "INVALID_CONFIG_FILE");
100
134
  }
101
- let connection = {
102
- provider: engine.provider,
103
- endpoint: engine.endpoint,
104
- model: engine.model,
105
- temperature: engine.temperature,
106
- maxTokens: engine.maxTokens,
107
- supportsJsonSchema: engine.supportsJsonSchema,
108
- extraParams: engine.extraParams,
109
- contextLength: engine.contextLength,
110
- enableThinking: engine.enableThinking,
111
- };
135
+ let connection = rawLlmConnection(engine);
112
136
  for (const layer of layers) {
113
- if (layer.llm)
114
- connection = deepMergeConfig(connection, layer.llm);
115
- if (layer.model !== undefined)
116
- connection.model = layer.model;
137
+ const llm = ownValue(layer, "llm");
138
+ const model = ownValue(layer, "model");
139
+ if (llm)
140
+ connection = deepMergeConfig(connection, llm);
141
+ if (model !== undefined)
142
+ connection.model = model;
117
143
  }
118
144
  for (const key of Object.keys(connection)) {
119
145
  if (connection[key] === undefined)
120
146
  delete connection[key];
121
147
  }
122
- connection.model = resolveLlmModel(connection.model, name, config.modelAliases);
123
148
  return {
124
149
  engine: name,
125
- connection: connection,
150
+ connection: sterileRecord(connection),
126
151
  credential: resolveCredential(name, engine, config),
127
152
  timeoutMs: effectiveTimeout(engine, layers, DEFAULT_LLM_TIMEOUT_MS),
128
153
  };
129
154
  }
130
155
  /** Read a resolved symbolic credential only at the runtime dispatch boundary. */
131
- export function materializeLlmConnection(resolved) {
132
- if (resolved.connection.extraParams !== undefined) {
133
- const issue = validateExtraParams(resolved.connection.extraParams)[0];
156
+ export function materializeLlmConnectionWithCredential(resolved, credentialValue) {
157
+ const extraParams = ownValue(resolved.connection, "extraParams");
158
+ if (extraParams !== undefined) {
159
+ const issue = validateExtraParams(extraParams)[0];
134
160
  if (issue) {
135
161
  throw new ConfigError(formatExtraParamsIssue(`Engine "${resolved.engine}" extraParams`, issue), "INVALID_CONFIG_FILE");
136
162
  }
137
163
  }
138
- const apiKey = resolveCredentialFromEnv(resolved.credential);
139
- return {
164
+ return sterileRecord({
140
165
  ...resolved.connection,
141
- ...(apiKey ? { apiKey } : {}),
166
+ ...(credentialValue ? { apiKey: credentialValue } : {}),
142
167
  timeoutMs: resolved.timeoutMs,
143
- };
168
+ });
169
+ }
170
+ /** Read and inject one resolved symbolic credential at the runtime boundary. */
171
+ export function materializeLlmConnection(resolved, envSource = process.env) {
172
+ return materializeLlmConnectionWithCredential(resolved, resolveCredentialFromEnv(resolved.credential, envSource));
144
173
  }
145
174
  function lowerAgentEngine(name, engine, config) {
146
175
  const harness = getHarness(engine.platform);
@@ -150,25 +179,23 @@ function lowerAgentEngine(name, engine, config) {
150
179
  const platform = harness.id;
151
180
  const sdk = platform === "opencode-sdk";
152
181
  const builtin = getBuiltinAgentProfile(platform);
153
- const profile = {
182
+ const bin = ownValue(engine, "bin");
183
+ const args = ownValue(engine, "args");
184
+ const workspace = ownValue(engine, "workspace");
185
+ const model = ownValue(engine, "model");
186
+ const profile = sterileRecord({
154
187
  name,
155
188
  platform,
156
- bin: engine.bin ?? builtin?.bin ?? (sdk ? "opencode" : platform),
157
- args: engine.args ?? builtin?.args ?? [],
189
+ personaChannel: sdk ? "native" : (harness.agentBuilder?.personaChannel ?? "prompt"),
190
+ bin: bin ?? builtin?.bin ?? (sdk ? "opencode" : platform),
191
+ args: args ?? builtin?.args ?? [],
158
192
  stdio: "captured",
159
193
  ...(builtin?.env ? { env: builtin.env } : {}),
160
194
  envPassthrough: builtin?.envPassthrough ?? [],
161
195
  parseOutput: "text",
162
- ...(engine.workspace ? { workspace: path.resolve(engine.workspace) } : {}),
163
- ...(engine.model
164
- ? {
165
- model: resolveModel(engine.model, platform, engine.modelAliases, config.modelAliases),
166
- modelIsExact: true,
167
- }
168
- : {}),
169
- ...(engine.modelAliases ? { modelAliases: engine.modelAliases } : {}),
170
- ...(config.modelAliases ? { globalModelAliases: config.modelAliases } : {}),
171
- };
196
+ ...(workspace ? { workspace: path.resolve(workspace) } : {}),
197
+ ...(model ? { model } : {}),
198
+ });
172
199
  if (!sdk) {
173
200
  return {
174
201
  kind: "agent",
@@ -177,7 +204,8 @@ function lowerAgentEngine(name, engine, config) {
177
204
  timeoutMs: hasOwn(engine, "timeoutMs") ? (engine.timeoutMs ?? null) : DEFAULT_AGENT_TIMEOUT_MS,
178
205
  };
179
206
  }
180
- const fallbackName = engine.llmEngine ?? config.defaults?.llmEngine;
207
+ const defaults = ownValue(config, "defaults");
208
+ const fallbackName = ownValue(engine, "llmEngine") ?? (defaults ? ownValue(defaults, "llmEngine") : undefined);
181
209
  const fallback = fallbackName
182
210
  ? resolveLlmEngineUse(config, [{ engine: fallbackName }], { optional: true })
183
211
  : undefined;
@@ -214,31 +242,3 @@ export function resolveEngine(name, config) {
214
242
  }
215
243
  return lowerAgentEngine(name, engine, config);
216
244
  }
217
- export function resolveDefaultEngine(config) {
218
- const name = config.defaults?.engine;
219
- if (!name)
220
- throw new ConfigError("No default engine is configured.", "INVALID_CONFIG_FILE");
221
- return resolveEngine(name, config);
222
- }
223
- // ── AkmConfig convenience wrappers (moved from core/config/config.ts, WI-9.8
224
- // KILL 3, D.3 edge A) ────────────────────────────────────────────────────────
225
- //
226
- // Moved verbatim: `config.ts` previously called `materializeLlmConnection` +
227
- // `resolveLlmEngineUse` directly for these two wrappers, which is what made
228
- // config.ts import this module — and this module imported `LlmConnectionConfig`
229
- // back from config.ts, closing a 2-file cycle. config.ts CANNOT re-export
230
- // these (a re-export is still a graph edge to this file), so the small number
231
- // of call sites that used to import them from "core/config/config" now import
232
- // them from here instead (see D.3 edge A "callers compose instead").
233
- /** Resolve and materialize the configured default LLM engine at dispatch time. */
234
- export function requireLlmConfig(config) {
235
- return materializeLlmConnection(resolveLlmEngineUse(config, []));
236
- }
237
- /**
238
- * Like {@link requireLlmConfig} but returns `undefined` instead of throwing
239
- * when no LLM is configured. Use in code paths where the LLM is optional.
240
- */
241
- export function getDefaultLlmConfig(config) {
242
- const resolved = resolveLlmEngineUse(config, [], { optional: true });
243
- return resolved ? materializeLlmConnection(resolved) : undefined;
244
- }