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
@@ -1,320 +0,0 @@
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 path from "node:path";
5
- import { deepMergeConfig } from "../../core/config/deep-merge.js";
6
- import { ConfigError, UsageError } from "../../core/errors.js";
7
- import { DEFAULT_AGENT_TIMEOUT_MS, DEFAULT_LLM_TIMEOUT_MS } from "../../integrations/agent/config.js";
8
- import { FALLBACK_ANNOUNCEMENT, NO_ENGINE_MESSAGE_SUFFIX, NO_ENGINE_REMEDY, withEngineFallback, } from "../../integrations/agent/engine-fallback.js";
9
- import { resolveLlmEngineUse, } from "../../integrations/agent/engine-resolution.js";
10
- import { resolveLlmModel, resolveModel } from "../../integrations/agent/model-aliases.js";
11
- import { getBuiltinAgentProfile } from "../../integrations/agent/profiles.js";
12
- import { HARNESS_BY_ID } from "../../integrations/harnesses/index.js";
13
- import { defaultLlmEngineConcurrency, defaultMapConcurrency, workflowMaxConcurrency } from "../concurrency-policy.js";
14
- import { projectExecCore } from "../program/schema.js";
15
- import { DEFAULT_EXEC_TIMEOUT_MS } from "../resource-limits.js";
16
- import { compileWorkflowPlan } from "./compile.js";
17
- import { decodeWorkflowPlanV3, WORKFLOW_IR_VERSION } from "./schema.js";
18
- /**
19
- * The only source-to-runtime boundary. Source compilation remains pure; engine
20
- * selection and every dispatch-significant setting are resolved here once.
21
- */
22
- export function compileResolveFreezeWorkflow(asset, inputConfig, options = {}) {
23
- // Applied ONCE, before any resolution: every engine lookup below (selection,
24
- // snapshots, the gate judge) then sees one config and needs no fallback
25
- // awareness of its own.
26
- const { config, fallbackEngineName } = withEngineFallback(inputConfig);
27
- // Announce only if the fallback candidate is what a unit actually froze to:
28
- // `defaults.engine` is the lowest-precedence selector, so a document- or
29
- // unit-level `engine:` still wins and must not be reported as opencode's.
30
- let usedFallbackEngine = false;
31
- const preliminary = (options.compile ?? compilePlan)(asset);
32
- const engines = {};
33
- const maxConcurrency = frozenConcurrency(config);
34
- const mapDefaultConcurrency = frozenMapDefaultConcurrency(config);
35
- const documentDefaults = asset.document.defaults;
36
- // Keyed by stepId, NOT by array position. Compile is 1:1 and order-preserving
37
- // today, so `asset.document.steps[index]` happened to line up with
38
- // `preliminary.steps[index]` — but nothing enforces that, and a compile pass
39
- // that ever filtered or reordered steps would silently attribute one step's
40
- // engine/model/timeout overrides to a different step. Every draft step
41
- // already carries its `stepId`, so look the source up by it.
42
- const sourceStepsById = new Map(asset.document.steps.map((step) => [step.id, step]));
43
- const freezeInvocation = (unit, stepId) => {
44
- const layers = [...(documentDefaults ? [documentDefaults] : []), ...(unit ? [unit] : [])];
45
- const name = selectedEngine(config, layers);
46
- if (!name)
47
- throw new ConfigError(
48
- // Reached only when the implicit opencode-sdk fallback did not apply
49
- // either, so the remedy names both routes.
50
- `This workflow ${NO_ENGINE_MESSAGE_SUFFIX} Set defaults.engine or workflow defaults.engine.`, "INVALID_CONFIG_FILE", NO_ENGINE_REMEDY);
51
- if (name === fallbackEngineName)
52
- usedFallbackEngine = true;
53
- const engine = engineDefinition(config, name);
54
- addSnapshot(config, name, engines);
55
- const model = exactModel(config, name, engine, layers);
56
- const timeoutMs = effectiveTimeout(config, engine, layers);
57
- // Merge llm overrides REGARDLESS of engine kind so a non-llm engine with
58
- // overrides anywhere in its layer stack (unit `llm:` or document
59
- // `defaults.llm`) is detected instead of silently dropped. SDK engines'
60
- // legitimate LLM *fallback* (`llmEngine`) is a separate mechanism — it
61
- // never contributes to `layers`, so it cannot false-positive here.
62
- const llm = mergedLlmOverrides(layers);
63
- if (engine.kind !== "llm" && llm !== undefined) {
64
- throw new ConfigError(`Workflow step "${stepId}" uses engine "${name}", which is an agent engine and cannot receive llm: ` +
65
- `overrides — llm: tuning (from the step's unit or defaults.llm) applies only to engines of kind "llm". ` +
66
- `Remove the llm: block or select an LLM engine for this step.`, "INVALID_CONFIG_FILE");
67
- }
68
- return { engine: name, model, timeoutMs, ...(llm ? { llm } : {}) };
69
- };
70
- /**
71
- * Resolve an exec unit's wall-clock budget at the single freeze boundary:
72
- * unit `timeout:` → document `defaults.timeout` → {@link DEFAULT_EXEC_TIMEOUT_MS}.
73
- * There is no engine layer to consult — an exec unit names no engine — and
74
- * `null` (the author's `timeout: none`) is honored as genuinely unbounded,
75
- * exactly like `effectiveTimeout`'s null.
76
- */
77
- const freezeExec = (exec, unit) => {
78
- const layers = [...(documentDefaults ? [documentDefaults] : []), ...(unit ? [unit] : [])];
79
- const declared = layeredTimeout(layers);
80
- const timeoutMs = declared === undefined ? DEFAULT_EXEC_TIMEOUT_MS : declared;
81
- // The shared structural projection, plus the one thing freezing adds: the
82
- // RESOLVED timeout. The default allowlist stays the ABSENCE of both env
83
- // keys — one encoding per state, which is what keeps the canonical hash
84
- // preimage stable. `command` is non-empty by parser construction.
85
- const core = projectExecCore(exec);
86
- return {
87
- ...core,
88
- command: core.command,
89
- timeoutMs,
90
- };
91
- };
92
- const freezeUnit = (node, stepId, unit) => ({
93
- kind: "unit",
94
- id: node.id,
95
- instructions: node.instructions,
96
- templating: node.templating ?? "verbatim",
97
- ...(node.inputs && node.inputs.length > 0 ? { inputs: node.inputs } : {}),
98
- // An exec unit dispatches a child process, so it freezes an exec spec and
99
- // NO invocation — engine selection is skipped entirely, which is why an
100
- // exec-only workflow runs on an install with no engines configured at all.
101
- ...(node.exec ? { exec: freezeExec(node.exec, unit) } : { invocation: freezeInvocation(unit, stepId) }),
102
- ...(node.schema ? { schema: node.schema } : {}),
103
- ...(node.retry ? { retry: node.retry } : {}),
104
- onError: node.onError,
105
- ...(node.env ? { env: node.env } : {}),
106
- isolation: node.isolation ?? "none",
107
- ...(node.source ? { source: node.source } : {}),
108
- });
109
- const steps = preliminary.steps.map((step) => {
110
- const sourceStep = sourceStepsById.get(step.stepId);
111
- const sourceUnit = sourceStep?.map ? sourceStep.map.unit : sourceStep?.unit;
112
- const root = step.root
113
- ? step.root.kind === "map"
114
- ? {
115
- kind: "map",
116
- id: step.root.id,
117
- over: step.root.over,
118
- template: freezeUnit(step.root.template, step.stepId, sourceUnit),
119
- // `?? ` — not `||` — keeps an authored `concurrency: 1` (explicit
120
- // opt-out, serial) distinguishable from an unset one (the default).
121
- concurrency: step.root.concurrency ?? mapDefaultConcurrency,
122
- reducer: step.root.reducer,
123
- ...(step.root.source ? { source: step.root.source } : {}),
124
- }
125
- : freezeUnit(step.root, step.stepId, sourceUnit)
126
- : undefined;
127
- const criteria = step.gate.criteria;
128
- const judge = criteria.length === 0 ? null : freezeGateJudge(config, engines);
129
- const gate = {
130
- kind: "gate",
131
- id: `${step.stepId}.gate`,
132
- stepId: step.stepId,
133
- criteria,
134
- maxLoops: step.gate.maxLoops ?? 1,
135
- judge,
136
- };
137
- return {
138
- stepId: step.stepId,
139
- title: step.title,
140
- sequenceIndex: step.sequenceIndex,
141
- ...(root ? { root } : {}),
142
- ...(step.route ? { route: step.route } : {}),
143
- ...(step.outputSchema ? { outputSchema: step.outputSchema } : {}),
144
- gate,
145
- };
146
- });
147
- const plan = decodeWorkflowPlanV3({
148
- irVersion: WORKFLOW_IR_VERSION,
149
- title: preliminary.title,
150
- ...(preliminary.params ? { params: preliminary.params } : {}),
151
- ...(preliminary.paramSchemas ? { paramSchemas: preliminary.paramSchemas } : {}),
152
- ...(preliminary.budget ? { budget: preliminary.budget } : {}),
153
- execution: { maxConcurrency, engines },
154
- steps,
155
- });
156
- // `usedFallbackEngine` IS the candidate-won predicate, so use the constant
157
- // directly rather than re-asking a helper to compare a name with itself.
158
- const engineAnnouncement = usedFallbackEngine ? FALLBACK_ANNOUNCEMENT : undefined;
159
- return {
160
- warnings: preliminary.warnings,
161
- ...(engineAnnouncement ? { engineAnnouncement } : {}),
162
- plan,
163
- };
164
- }
165
- function compilePlan(asset) {
166
- const compiled = compileWorkflowPlan(asset.document, asset.title);
167
- if (!compiled.ok)
168
- throw new UsageError(compiled.errors.map((error) => `${asset.path}:${error.line}: ${error.message}`).join("\n"));
169
- return { ...compiled.plan, warnings: compiled.warnings };
170
- }
171
- function selectedEngine(config, layers) {
172
- for (let index = layers.length - 1; index >= 0; index--)
173
- if (layers[index]?.engine !== undefined)
174
- return layers[index]?.engine;
175
- return config.defaults?.engine;
176
- }
177
- function engineDefinition(config, name) {
178
- const engine = config.engines?.[name];
179
- if (!engine)
180
- throw new ConfigError(`Engine "${name}" is not configured.`, "INVALID_CONFIG_FILE");
181
- return engine;
182
- }
183
- function exactModel(config, name, engine, layers) {
184
- let selected;
185
- for (const layer of layers)
186
- if (layer.model !== undefined)
187
- selected = layer.model;
188
- selected ??= engine.model;
189
- if (!selected) {
190
- if (engine.kind === "llm")
191
- throw new ConfigError(`LLM engine "${name}" has no model.`, "INVALID_CONFIG_FILE");
192
- if (engine.platform === "opencode-sdk") {
193
- const fallbackName = engine.llmEngine ?? config.defaults?.llmEngine;
194
- if (fallbackName) {
195
- const fallback = engineDefinition(config, fallbackName);
196
- if (fallback.kind !== "llm") {
197
- throw new ConfigError(`SDK engine "${name}" fallback "${fallbackName}" is not an LLM engine.`, "INVALID_CONFIG_FILE");
198
- }
199
- return exactModel(config, fallbackName, fallback, []);
200
- }
201
- }
202
- return null;
203
- }
204
- if (engine.kind === "llm")
205
- return resolveLlmModel(selected, name, config.modelAliases);
206
- return resolveModel(selected, engine.platform, engine.modelAliases, config.modelAliases);
207
- }
208
- /**
209
- * Newest-layer-first scan for a declared `timeoutMs` across authoring layers
210
- * (document `defaults`, then the unit). Returns `undefined` when no layer
211
- * declares one; an explicit `timeoutMs: null` ("unbounded") wins over deeper
212
- * layers — hence `hasOwn`, not a value test. The ONE definition of authoring
213
- * timeout precedence, shared by engine and exec freezing.
214
- */
215
- function layeredTimeout(layers) {
216
- for (let index = layers.length - 1; index >= 0; index--) {
217
- if (Object.hasOwn(layers[index] ?? {}, "timeoutMs"))
218
- return layers[index]?.timeoutMs ?? null;
219
- }
220
- return undefined;
221
- }
222
- function effectiveTimeout(config, engine, layers) {
223
- const declared = layeredTimeout(layers);
224
- if (declared !== undefined)
225
- return declared;
226
- if (Object.hasOwn(engine, "timeoutMs"))
227
- return engine.timeoutMs ?? null;
228
- if (engine.kind === "llm")
229
- return DEFAULT_LLM_TIMEOUT_MS;
230
- if (engine.platform === "opencode-sdk") {
231
- const fallbackName = engine.llmEngine ?? config.defaults?.llmEngine;
232
- if (fallbackName) {
233
- const fallback = engineDefinition(config, fallbackName);
234
- if (fallback.kind === "llm") {
235
- return Object.hasOwn(fallback, "timeoutMs") ? (fallback.timeoutMs ?? null) : DEFAULT_LLM_TIMEOUT_MS;
236
- }
237
- }
238
- }
239
- return DEFAULT_AGENT_TIMEOUT_MS;
240
- }
241
- function mergedLlmOverrides(layers) {
242
- let merged;
243
- for (const layer of layers)
244
- if (layer.llm)
245
- merged = deepMergeConfig(merged ?? {}, layer.llm);
246
- return merged;
247
- }
248
- function addSnapshot(config, name, target) {
249
- if (target[name])
250
- return;
251
- const engine = engineDefinition(config, name);
252
- if (engine.kind === "llm") {
253
- const resolved = resolveLlmEngineUse(config, [{ engine: name }]);
254
- const snapshot = {
255
- name,
256
- kind: "llm",
257
- endpoint: engine.endpoint,
258
- model: exactModel(config, name, engine, []),
259
- concurrency: defaultLlmEngineConcurrency(engine.endpoint, engine.concurrency),
260
- ...(engine.provider ? { provider: engine.provider } : {}),
261
- ...(resolved.credential ? { credential: resolved.credential } : {}),
262
- ...(engine.temperature !== undefined ? { temperature: engine.temperature } : {}),
263
- ...(engine.maxTokens !== undefined ? { maxTokens: engine.maxTokens } : {}),
264
- ...(engine.supportsJsonSchema !== undefined ? { supportsJsonSchema: engine.supportsJsonSchema } : {}),
265
- ...(engine.extraParams ? { extraParams: engine.extraParams } : {}),
266
- ...(engine.contextLength !== undefined ? { contextLength: engine.contextLength } : {}),
267
- ...(engine.enableThinking !== undefined ? { enableThinking: engine.enableThinking } : {}),
268
- };
269
- target[name] = snapshot;
270
- return;
271
- }
272
- const harness = HARNESS_BY_ID.get(engine.platform);
273
- if (!harness?.capabilities.agentDispatch)
274
- throw new ConfigError(`Engine "${name}" cannot dispatch platform ${engine.platform}.`, "INVALID_CONFIG_FILE");
275
- const sdk = engine.platform === "opencode-sdk";
276
- const builtin = getBuiltinAgentProfile(engine.platform);
277
- const fallback = sdk ? (engine.llmEngine ?? config.defaults?.llmEngine ?? null) : null;
278
- if (fallback)
279
- addSnapshot(config, fallback, target);
280
- const snapshot = {
281
- name,
282
- kind: "agent",
283
- runnerKind: sdk ? "sdk" : "agent",
284
- platform: engine.platform,
285
- bin: engine.bin ?? builtin?.bin ?? (sdk ? "opencode" : engine.platform),
286
- args: [...(engine.args ?? builtin?.args ?? [])],
287
- workspace: engine.workspace ? path.resolve(engine.workspace) : null,
288
- envPassthrough: [...(builtin?.envPassthrough ?? [])],
289
- commandBuilder: engine.platform,
290
- fallbackLlmEngine: fallback,
291
- };
292
- target[name] = snapshot;
293
- }
294
- function freezeGateJudge(config, engines) {
295
- const name = config.workflow?.judgeEngine;
296
- if (!name) {
297
- throw new ConfigError("This workflow declares completion criteria but no verification engine is configured. Set workflow.judgeEngine to a named LLM or agent engine.", "INVALID_CONFIG_FILE");
298
- }
299
- const engine = engineDefinition(config, name);
300
- addSnapshot(config, name, engines);
301
- return {
302
- engine: name,
303
- model: exactModel(config, name, engine, []),
304
- timeoutMs: effectiveTimeout(config, engine, []),
305
- };
306
- }
307
- function frozenConcurrency(config) {
308
- const configured = config.workflow?.maxConcurrency;
309
- return workflowMaxConcurrency(typeof configured === "number" && Number.isFinite(configured) ? configured : undefined);
310
- }
311
- /**
312
- * Width to freeze into a `map` node that declared no `concurrency:`. Resolved
313
- * HERE, at the single freeze boundary, so the number lands in `plan_json` and
314
- * an in-flight run keeps the width it started with even if this default (or
315
- * the config key) changes underneath it.
316
- */
317
- function frozenMapDefaultConcurrency(config) {
318
- const configured = config.workflow?.defaultMapConcurrency;
319
- return defaultMapConcurrency(typeof configured === "number" ? configured : undefined);
320
- }
@@ -1,13 +0,0 @@
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
- const cache = new WeakMap();
5
- export function cacheWorkflowDocument(entry, doc) {
6
- cache.set(entry, doc);
7
- }
8
- export function takeWorkflowDocument(entry) {
9
- const doc = cache.get(entry);
10
- if (doc !== undefined)
11
- cache.delete(entry);
12
- return doc;
13
- }