akm-cli 0.9.1 → 0.9.2-alpha.1

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 (341) hide show
  1. package/CHANGELOG.md +88 -0
  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/tasks/core/extract.yml +6 -5
  12. package/dist/assets/tasks/core/improve.yml +6 -5
  13. package/dist/assets/tasks/core/index-refresh.yml +6 -5
  14. package/dist/assets/tasks/core/sync.yml +6 -5
  15. package/dist/assets/tasks/core/version-check.yml +6 -5
  16. package/dist/assets/tasks/improve/akm-graph-refresh-weekly.yml +6 -5
  17. package/dist/assets/tasks/improve/akm-improve-catchup.yml +6 -5
  18. package/dist/assets/tasks/improve/akm-improve-consolidate.yml +6 -5
  19. package/dist/assets/tasks/improve/akm-improve-frequent.yml +6 -5
  20. package/dist/assets/tasks/improve/akm-improve-nightly.yml +6 -5
  21. package/dist/cli/confirm.js +2 -2
  22. package/dist/cli/parse-args.js +3 -24
  23. package/dist/cli/retired-commands.js +1 -1
  24. package/dist/cli/shared.js +2 -2
  25. package/dist/cli.js +11 -9
  26. package/dist/commands/agent/agent-dispatch.js +55 -89
  27. package/dist/commands/agent/contribute-cli.js +12 -45
  28. package/dist/commands/command/builtin-action.js +32 -0
  29. package/dist/commands/command/command-cli.js +99 -0
  30. package/dist/commands/command/command-execution.js +308 -0
  31. package/dist/commands/command/execution-source-loader.js +176 -0
  32. package/dist/commands/command/portable-template.js +60 -0
  33. package/dist/commands/config-cli.js +10 -4
  34. package/dist/commands/env/env.js +4 -2
  35. package/dist/commands/feedback-cli.js +1 -1
  36. package/dist/commands/health/checks.js +241 -29
  37. package/dist/commands/health/html-report.js +0 -14
  38. package/dist/commands/health/report-view-model.js +0 -1
  39. package/dist/commands/health/surfaces.js +6 -7
  40. package/dist/commands/health/types.js +0 -2
  41. package/dist/commands/health.js +63 -18
  42. package/dist/commands/improve/collapse-detector.js +2 -2
  43. package/dist/commands/improve/consolidate.js +251 -214
  44. package/dist/commands/improve/distill/promote-memory.js +71 -34
  45. package/dist/commands/improve/distill/quality-gate.js +17 -5
  46. package/dist/commands/improve/distill.js +232 -155
  47. package/dist/commands/improve/eligibility.js +112 -79
  48. package/dist/commands/improve/execution.js +57 -0
  49. package/dist/commands/improve/extract-cli.js +5 -5
  50. package/dist/commands/improve/extract.js +521 -342
  51. package/dist/commands/improve/improve-strategies.js +43 -14
  52. package/dist/commands/improve/improve.js +249 -29
  53. package/dist/commands/improve/loop-stages.js +11 -17
  54. package/dist/commands/improve/memory/memory-contradiction-detect.js +90 -66
  55. package/dist/commands/improve/outcome-loop.js +22 -38
  56. package/dist/commands/improve/planner.js +134 -0
  57. package/dist/commands/improve/preparation.js +730 -409
  58. package/dist/commands/improve/reflect.js +386 -223
  59. package/dist/commands/improve/run-context.js +3 -4
  60. package/dist/commands/improve/salience.js +6 -58
  61. package/dist/commands/improve/session-asset.js +12 -12
  62. package/dist/commands/lint/index.js +101 -29
  63. package/dist/commands/migrate-cli.js +11 -69
  64. package/dist/commands/migration-tool.js +6 -9
  65. package/dist/commands/models-cli.js +27 -0
  66. package/dist/commands/proposal/drain.js +258 -186
  67. package/dist/commands/proposal/proposal-cli.js +32 -10
  68. package/dist/commands/proposal/proposal.js +2 -5
  69. package/dist/commands/proposal/propose.js +192 -172
  70. package/dist/commands/proposal/repository.js +54 -91
  71. package/dist/commands/proposal/validators/proposal-validators.js +9 -7
  72. package/dist/commands/read/curate.js +10 -0
  73. package/dist/commands/read/registry-search.js +25 -9
  74. package/dist/commands/read/remember-cli.js +14 -2
  75. package/dist/commands/read/search.js +10 -4
  76. package/dist/commands/read/show.js +139 -153
  77. package/dist/commands/registry-cli.js +16 -7
  78. package/dist/commands/remember.js +33 -18
  79. package/dist/commands/sources/add-cli.js +19 -178
  80. package/dist/commands/sources/bundle-cli.js +15 -3
  81. package/dist/commands/sources/dangerous-env-audit.js +135 -0
  82. package/dist/commands/sources/info.js +2 -1
  83. package/dist/commands/sources/installed-stashes.js +835 -152
  84. package/dist/commands/sources/schema-repair.js +174 -95
  85. package/dist/commands/sources/self-update.js +30 -74
  86. package/dist/commands/sources/source-add.js +3 -5
  87. package/dist/commands/sources/sources-cli.js +2 -15
  88. package/dist/commands/sources/update-transaction.js +220 -0
  89. package/dist/commands/tasks/tasks-cli.js +3 -3
  90. package/dist/commands/tasks/tasks.js +736 -317
  91. package/dist/commands/workflow-cli.js +2 -2
  92. package/dist/core/adapter/adapters/agent-skills-adapter.js +3 -0
  93. package/dist/core/adapter/adapters/akm-adapter.js +83 -34
  94. package/dist/core/adapter/adapters/akm-lint.js +54 -39
  95. package/dist/core/adapter/adapters/akm-metadata.js +45 -45
  96. package/dist/core/adapter/adapters/akm-task-adapter.js +32 -49
  97. package/dist/core/adapter/adapters/akm-workflow-adapter.js +38 -23
  98. package/dist/core/adapter/adapters/dotenv-adapter.js +30 -1
  99. package/dist/core/adapter/adapters/generic-files-adapter.js +11 -0
  100. package/dist/core/adapter/adapters/index.js +0 -9
  101. package/dist/core/adapter/adapters/llm-wiki-adapter.js +4 -0
  102. package/dist/core/adapter/adapters/okf-adapter.js +4 -0
  103. package/dist/core/adapter/adapters/opencode-adapter.js +5 -8
  104. package/dist/core/adapter/adapters/tool-dir-shared.js +63 -6
  105. package/dist/core/adapter/adapters/website-snapshot-adapter.js +4 -0
  106. package/dist/core/adapter/execution-source.js +308 -0
  107. package/dist/core/adapter/recognize-match.js +36 -13
  108. package/dist/core/adapter/registry.js +0 -9
  109. package/dist/core/asset/stash-meta.js +94 -4
  110. package/dist/core/common.js +6 -11
  111. package/dist/core/config/config-io.js +3 -3
  112. package/dist/core/config/config-schema.js +18 -40
  113. package/dist/core/config/config-sources.js +11 -21
  114. package/dist/core/config/config-walker.js +31 -13
  115. package/dist/core/config/config.js +21 -20
  116. package/dist/core/config/schema/engines.js +8 -7
  117. package/dist/core/config/schema/improve-processes.js +29 -5
  118. package/dist/core/config/schema/primitives.js +1 -23
  119. package/dist/core/config/schema/sources-bundles.js +13 -16
  120. package/dist/core/errors.js +2 -0
  121. package/dist/core/events.js +68 -32
  122. package/dist/core/extra-params.js +1 -0
  123. package/dist/core/improve-result.js +315 -0
  124. package/dist/core/lesson-lint.js +0 -6
  125. package/dist/core/maintenance-barrier.js +4 -4
  126. package/dist/core/network-policy.js +152 -0
  127. package/dist/core/paths.js +1 -1
  128. package/dist/core/recognition-util.js +4 -4
  129. package/dist/core/registry-url.js +456 -0
  130. package/dist/core/state/migrations.js +161 -47
  131. package/dist/core/state-db.js +453 -80
  132. package/dist/core/system-error.js +32 -0
  133. package/dist/core/time.js +2 -12
  134. package/dist/core/write-source.js +0 -18
  135. package/dist/execution/directory-identity.js +52 -0
  136. package/dist/execution/executable-identity.js +107 -0
  137. package/dist/execution/guarded-source.js +398 -0
  138. package/dist/execution/json.js +95 -0
  139. package/dist/{commands/health/types-session-log.js → execution/limits.js} +2 -1
  140. package/dist/execution/record.js +55 -0
  141. package/dist/execution/resolved-request.js +730 -0
  142. package/dist/execution/source.js +320 -0
  143. package/dist/indexer/bundle-identity-guard.js +5 -4
  144. package/dist/indexer/db/graph-db.js +33 -0
  145. package/dist/indexer/graph/graph-boost.js +3 -4
  146. package/dist/indexer/graph/graph-extraction.js +562 -373
  147. package/dist/indexer/index-written-assets.js +65 -34
  148. package/dist/indexer/indexer.js +443 -222
  149. package/dist/indexer/installations.js +6 -0
  150. package/dist/indexer/lookup/adapter-concept-owner.js +283 -0
  151. package/dist/indexer/passes/memory-inference.js +227 -174
  152. package/dist/indexer/scan/doc-to-entry.js +7 -9
  153. package/dist/indexer/scan/drain-dir.js +51 -23
  154. package/dist/indexer/search/db-search.js +98 -22
  155. package/dist/indexer/search/search-fields.js +1 -1
  156. package/dist/indexer/search/search-hit-enrichers.js +1 -1
  157. package/dist/indexer/search/search-source.js +7 -16
  158. package/dist/indexer/search/semantic-status.js +10 -1
  159. package/dist/indexer/usage/show-usage.js +105 -0
  160. package/dist/indexer/usage/usage-events.js +7 -2
  161. package/dist/indexer/walk/matchers.js +40 -10
  162. package/dist/indexer/walk/path-resolver.js +5 -2
  163. package/dist/indexer/walk/walker.js +20 -2
  164. package/dist/integrations/agent/builder-shared.js +3 -6
  165. package/dist/integrations/agent/conversation-fallback.js +16 -0
  166. package/dist/integrations/agent/engine-resolution.js +87 -87
  167. package/dist/integrations/agent/execution-cascade.js +566 -0
  168. package/dist/integrations/agent/execution-definitions.js +211 -0
  169. package/dist/integrations/agent/execution-lowering.js +811 -0
  170. package/dist/integrations/agent/execution-preparation.js +67 -0
  171. package/dist/integrations/agent/index.js +0 -2
  172. package/dist/integrations/agent/inline-execution.js +74 -0
  173. package/dist/integrations/agent/model-map.js +515 -0
  174. package/dist/integrations/agent/persona-fallback.js +30 -0
  175. package/dist/integrations/agent/request-lowering.js +186 -0
  176. package/dist/integrations/agent/runner-dispatch.js +230 -37
  177. package/dist/integrations/agent/runner.js +12 -83
  178. package/dist/integrations/harnesses/aider/agent-builder.js +8 -0
  179. package/dist/integrations/harnesses/aider/index.js +0 -1
  180. package/dist/integrations/harnesses/amazonq/agent-builder.js +8 -0
  181. package/dist/integrations/harnesses/amazonq/index.js +0 -1
  182. package/dist/integrations/harnesses/claude/agent-builder.js +14 -1
  183. package/dist/integrations/harnesses/claude/index.js +1 -5
  184. package/dist/integrations/harnesses/claude/session-log.js +3 -33
  185. package/dist/integrations/harnesses/codex/agent-builder.js +8 -0
  186. package/dist/integrations/harnesses/codex/index.js +0 -1
  187. package/dist/integrations/harnesses/copilot/agent-builder.js +8 -0
  188. package/dist/integrations/harnesses/copilot/index.js +0 -1
  189. package/dist/integrations/harnesses/gemini/agent-builder.js +8 -0
  190. package/dist/integrations/harnesses/gemini/index.js +0 -1
  191. package/dist/integrations/harnesses/index.js +4 -44
  192. package/dist/integrations/harnesses/opencode/agent-builder.js +16 -9
  193. package/dist/integrations/harnesses/opencode/index.js +0 -2
  194. package/dist/integrations/harnesses/opencode/session-log.js +14 -204
  195. package/dist/integrations/harnesses/opencode-sdk/harness.js +12 -1
  196. package/dist/integrations/harnesses/opencode-sdk/sdk-runner.js +40 -42
  197. package/dist/integrations/harnesses/openhands/agent-builder.js +8 -0
  198. package/dist/integrations/harnesses/openhands/index.js +0 -1
  199. package/dist/integrations/harnesses/pi/agent-builder.js +8 -0
  200. package/dist/integrations/harnesses/pi/index.js +0 -1
  201. package/dist/integrations/harnesses/shared.js +0 -1
  202. package/dist/integrations/harnesses/types.js +1 -3
  203. package/dist/integrations/lockfile.js +82 -79
  204. package/dist/integrations/session-logs/index.js +6 -17
  205. package/dist/integrations/session-logs/provider-base.js +1 -29
  206. package/dist/llm/client.js +10 -5
  207. package/dist/llm/embedder.js +6 -7
  208. package/dist/llm/embedders/local.js +37 -88
  209. package/dist/llm/embedders/types.js +1 -1
  210. package/dist/llm/graph-extract.js +75 -50
  211. package/dist/llm/index-passes.js +43 -5
  212. package/dist/llm/memory-infer.js +8 -6
  213. package/dist/llm/metadata-enhance.js +5 -3
  214. package/dist/llm/structured-call.js +122 -25
  215. package/dist/output/format-exempt.js +1 -1
  216. package/dist/output/render-registry.js +0 -16
  217. package/dist/output/renderers.js +12 -7
  218. package/dist/output/shapes/curate.js +1 -0
  219. package/dist/output/shapes/helpers.js +10 -2
  220. package/dist/output/shapes/passthrough.js +2 -0
  221. package/dist/output/text/command-format.js +28 -32
  222. package/dist/output/text/health-format.js +1 -29
  223. package/dist/output/text/migrate.js +6 -56
  224. package/dist/output/text/proposal-format.js +16 -1
  225. package/dist/output/text/workflow-format.js +16 -0
  226. package/dist/registry/network.js +279 -0
  227. package/dist/registry/pinned-request-helper.js +247 -0
  228. package/dist/registry/pinned-transport.js +717 -0
  229. package/dist/registry/providers/skills-sh.js +18 -6
  230. package/dist/registry/providers/static-index.js +20 -7
  231. package/dist/registry/resolve.js +53 -28
  232. package/dist/scripts/akm-migrate-node.js +19122 -52218
  233. package/dist/scripts/akm-migrate.js +19064 -51567
  234. package/dist/setup/registry-stash-loader.js +64 -20
  235. package/dist/setup/semantic-assets.js +9 -34
  236. package/dist/setup/setup.js +12 -30
  237. package/dist/setup/source-identity.js +17 -0
  238. package/dist/setup/steps/sources.js +36 -15
  239. package/dist/setup/steps/tasks.js +39 -11
  240. package/dist/sources/providers/git-provider.js +3 -3
  241. package/dist/sources/providers/npm.js +2 -2
  242. package/dist/sources/providers/provider-utils.js +4 -3
  243. package/dist/sources/providers/website.js +11 -7
  244. package/dist/sources/snapshot-fetchers/host-guard.js +9 -136
  245. package/dist/sources/snapshot-fetchers/website-ingest.js +25 -109
  246. package/dist/sources/website-url.js +73 -0
  247. package/dist/storage/engines/sqlite-migrations.js +81 -26
  248. package/dist/storage/managed-db.js +27 -24
  249. package/dist/storage/repositories/events-repository.js +3 -0
  250. package/dist/storage/repositories/index-connection.js +42 -10
  251. package/dist/storage/repositories/index-entries-repository.js +167 -207
  252. package/dist/storage/repositories/index-entry-mapper.js +8 -12
  253. package/dist/storage/repositories/index-entry-schema.js +255 -0
  254. package/dist/storage/repositories/index-fts-repository.js +10 -10
  255. package/dist/storage/repositories/index-llm-cache-repository.js +8 -13
  256. package/dist/storage/repositories/index-meta-repository.js +0 -11
  257. package/dist/storage/repositories/index-schema.js +71 -342
  258. package/dist/storage/repositories/index-utility-repository.js +12 -17
  259. package/dist/storage/repositories/index-vec-repository.js +1 -1
  260. package/dist/storage/repositories/proposals-repository.js +4 -127
  261. package/dist/storage/repositories/registry-cache.js +2 -1
  262. package/dist/storage/repositories/task-history-repository.js +20 -40
  263. package/dist/storage/repositories/workflow-runs-repository.js +228 -129
  264. package/dist/storage/sqlite-read-snapshot.js +148 -0
  265. package/dist/tasks/backends/cron.js +170 -42
  266. package/dist/tasks/backends/index.js +1 -1
  267. package/dist/tasks/backends/launchd.js +787 -202
  268. package/dist/tasks/backends/schtasks.js +282 -83
  269. package/dist/tasks/embedded.js +7 -7
  270. package/dist/tasks/frozen-script.js +50 -0
  271. package/dist/tasks/resolve-akm-bin.js +5 -1
  272. package/dist/tasks/runner.js +239 -251
  273. package/dist/tasks/runtime-v3.js +281 -0
  274. package/dist/tasks/scheduler-binding.js +272 -0
  275. package/dist/tasks/scheduler-invocation.js +57 -43
  276. package/dist/tasks/scheduler-sync.js +654 -0
  277. package/dist/tasks/source-v3.js +752 -0
  278. package/dist/tasks/standalone-script-entry.js +5 -0
  279. package/dist/tasks/task-id.js +29 -0
  280. package/dist/workflows/authoring/authoring.js +15 -32
  281. package/dist/workflows/exec/dispatch-redaction.js +14 -8
  282. package/dist/workflows/exec/exec-unit.js +7 -28
  283. package/dist/workflows/exec/frozen-judge.js +57 -89
  284. package/dist/workflows/exec/lowering-notices.js +23 -0
  285. package/dist/workflows/exec/native-executor.js +301 -458
  286. package/dist/workflows/exec/param-secrets.js +4 -3
  287. package/dist/workflows/exec/run-workflow.js +26 -32
  288. package/dist/workflows/exec/step-work.js +105 -109
  289. package/dist/workflows/exec/unit-dispatch.js +103 -27
  290. package/dist/workflows/exec/unit-writer.js +3 -3
  291. package/dist/workflows/exec/worktree.js +2 -2
  292. package/dist/workflows/ir/compile.js +86 -72
  293. package/dist/workflows/ir/environment-v4.js +328 -0
  294. package/dist/workflows/ir/freeze-v4.js +122 -0
  295. package/dist/workflows/ir/plan-hash.js +13 -7
  296. package/dist/workflows/ir/schema-v4.js +525 -0
  297. package/dist/workflows/ir/schema.js +25 -284
  298. package/dist/workflows/ir/source-freeze-v4.js +506 -0
  299. package/dist/workflows/parser.js +27 -24
  300. package/dist/workflows/program/schema.js +1 -2
  301. package/dist/workflows/renderer.js +42 -29
  302. package/dist/workflows/resource-limits.js +4 -5
  303. package/dist/workflows/runtime/agent-identity.js +11 -13
  304. package/dist/workflows/runtime/plan-classifier.js +8 -8
  305. package/dist/workflows/runtime/runs.js +27 -43
  306. package/dist/workflows/runtime/workflow-asset-loader.js +45 -205
  307. package/dist/workflows/source-files.js +373 -0
  308. package/dist/workflows/source-ir/compile.js +196 -0
  309. package/dist/workflows/source-ir/github-yaml.js +577 -0
  310. package/dist/workflows/source-ir/ordering.js +38 -0
  311. package/dist/workflows/source-ir/program.js +50 -0
  312. package/dist/workflows/source-ir/result.js +26 -0
  313. package/dist/workflows/source-ir/schema.js +772 -0
  314. package/dist/workflows/source-ir/semantics.js +242 -0
  315. package/dist/workflows/source-ir/uses.js +14 -0
  316. package/docs/README.md +2 -0
  317. package/docs/migration/README.md +3 -1
  318. package/docs/migration/release-notes/0.9.2.md +55 -0
  319. package/docs/migration/release-notes/README.md +5 -0
  320. package/docs/migration/v0.8-to-v0.9.md +76 -1077
  321. package/docs/migration/v0.9.0-troubleshooting.md +104 -516
  322. package/docs/migration/v0.9.1-to-v0.9.2.md +150 -0
  323. package/docs/reference/README.md +1 -0
  324. package/docs/reference/cli.md +230 -98
  325. package/docs/reference/configuration.md +153 -27
  326. package/docs/reference/data-and-telemetry.md +19 -1
  327. package/docs/reference/supported-formats.md +23 -3
  328. package/docs/reference/tasks.md +182 -0
  329. package/docs/reference/workflow-schema.md +91 -40
  330. package/docs/reference/workflows.md +33 -6
  331. package/package.json +10 -6
  332. package/schemas/akm-config.json +372 -216
  333. package/schemas/akm-task.json +324 -80
  334. package/schemas/akm-workflow.json +6 -9
  335. package/dist/core/migration-operation.js +0 -75
  336. package/dist/integrations/agent/model-aliases.js +0 -74
  337. package/dist/tasks/parser.js +0 -380
  338. package/dist/tasks/schema.js +0 -123
  339. package/dist/tasks/validator.js +0 -80
  340. package/dist/workflows/ir/freeze.js +0 -320
  341. 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
- }