akm-cli 0.9.17-alpha.3 → 0.9.17-alpha.5

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 (346) hide show
  1. package/CHANGELOG.md +760 -0
  2. package/dist/akm +94 -196
  3. package/dist/cli/shared.js +6 -2
  4. package/dist/cli.js +22 -9
  5. package/dist/commands/agent/agent-dispatch.js +1 -1
  6. package/dist/commands/command/command-execution.js +24 -62
  7. package/dist/commands/feedback-cli.js +0 -1
  8. package/dist/commands/health/accept-rate.js +2 -2
  9. package/dist/commands/health/checks.js +30 -75
  10. package/dist/commands/health/config-skew.js +38 -0
  11. package/dist/commands/health/egress.js +54 -0
  12. package/dist/commands/health/html-report.js +0 -38
  13. package/dist/commands/health/improve-metrics.js +123 -562
  14. package/dist/commands/health/plugin-staleness.js +53 -3
  15. package/dist/commands/health/renderers.js +12 -4
  16. package/dist/commands/health/report-view-model.js +11 -106
  17. package/dist/commands/health/types-improve.js +4 -19
  18. package/dist/commands/health/windows.js +64 -73
  19. package/dist/commands/health.js +122 -143
  20. package/dist/commands/improve/consolidate/chunking.js +25 -100
  21. package/dist/commands/improve/consolidate/sanitize.js +54 -149
  22. package/dist/commands/improve/consolidate.js +538 -1075
  23. package/dist/commands/improve/content-hash.js +16 -24
  24. package/dist/commands/improve/distill/content-repair.js +18 -100
  25. package/dist/commands/improve/distill-guards.js +20 -81
  26. package/dist/commands/improve/distill-promotion-policy.js +23 -243
  27. package/dist/commands/improve/distill.js +608 -1075
  28. package/dist/commands/improve/eligibility.js +126 -400
  29. package/dist/commands/improve/execution.js +3 -5
  30. package/dist/commands/improve/extract.js +487 -1046
  31. package/dist/commands/improve/feedback-valence.js +0 -25
  32. package/dist/commands/improve/improve-cli.js +29 -166
  33. package/dist/commands/improve/improve-result-file.js +10 -66
  34. package/dist/commands/improve/improve-strategies.js +12 -7
  35. package/dist/commands/improve/improve-usage-report.js +18 -64
  36. package/dist/commands/improve/improve.js +443 -1063
  37. package/dist/commands/improve/ledger.js +114 -0
  38. package/dist/commands/improve/locks.js +2 -8
  39. package/dist/commands/improve/loop-stages.js +459 -1172
  40. package/dist/commands/improve/memory/derived-ref.js +12 -77
  41. package/dist/commands/improve/memory/memory-belief.js +14 -118
  42. package/dist/commands/improve/memory/memory-improve.js +4 -3
  43. package/dist/commands/improve/outcome-loop.js +28 -156
  44. package/dist/commands/improve/planner.js +5 -10
  45. package/dist/commands/improve/preparation.js +851 -2339
  46. package/dist/commands/improve/proactive-maintenance.js +34 -101
  47. package/dist/commands/improve/reflect-noise.js +104 -280
  48. package/dist/commands/improve/reflect.js +621 -1367
  49. package/dist/commands/improve/salience.js +46 -232
  50. package/dist/commands/improve/session-asset.js +19 -100
  51. package/dist/commands/improve/stage.js +323 -0
  52. package/dist/commands/lint/base-linter.js +19 -5
  53. package/dist/commands/proposal/drain.js +251 -644
  54. package/dist/commands/proposal/proposal-cli.js +3 -18
  55. package/dist/commands/proposal/proposal-types.js +20 -41
  56. package/dist/commands/proposal/proposal.js +1 -2
  57. package/dist/commands/proposal/propose.js +134 -160
  58. package/dist/commands/proposal/repository.js +502 -1487
  59. package/dist/commands/proposal/validators/proposal-quality-validators.js +71 -174
  60. package/dist/commands/proposal/validators/proposal-validators.js +1 -1
  61. package/dist/commands/proposal/validators/proposals.js +13 -89
  62. package/dist/commands/read/curate.js +63 -413
  63. package/dist/commands/read/search-cli.js +16 -33
  64. package/dist/commands/read/search.js +17 -23
  65. package/dist/commands/read/show.js +2 -13
  66. package/dist/commands/sources/bundle-cli.js +25 -2
  67. package/dist/commands/sources/bundle-config-ops.js +4 -0
  68. package/dist/commands/sources/dangerous-env-audit.js +1 -2
  69. package/dist/commands/sources/info.js +2 -11
  70. package/dist/commands/sources/installed-stashes.js +197 -746
  71. package/dist/commands/sources/schema-repair.js +98 -129
  72. package/dist/commands/sources/source-add.js +62 -12
  73. package/dist/commands/sources/source-manage.js +9 -2
  74. package/dist/commands/sources/stash-cli.js +1 -1
  75. package/dist/commands/tasks/explain.js +10 -13
  76. package/dist/commands/tasks/tasks-cli.js +9 -8
  77. package/dist/commands/tasks/tasks.js +326 -930
  78. package/dist/commands/tasks/validate.js +42 -21
  79. package/dist/commands/workflow/plan.js +22 -29
  80. package/dist/commands/workflow-cli.js +4 -4
  81. package/dist/core/adapter/adapters/akm-adapter.js +0 -1
  82. package/dist/core/adapter/adapters/akm-lint.js +2 -3
  83. package/dist/core/adapter/adapters/akm-metadata.js +11 -12
  84. package/dist/core/adapter/adapters/akm-workflow-adapter.js +1 -1
  85. package/dist/core/adapter/execution-source.js +17 -29
  86. package/dist/core/asset/asset-placement.js +4 -13
  87. package/dist/core/asset/resolve-ref.js +1 -1
  88. package/dist/core/bundle-id.js +42 -5
  89. package/dist/core/bundle-rename.js +291 -0
  90. package/dist/core/config/config-io.js +1 -2
  91. package/dist/core/config/config-schema.js +1 -33
  92. package/dist/core/config/config-walker.js +1 -1
  93. package/dist/core/config/config.js +163 -68
  94. package/dist/core/config/legacy-source-shape-shim.js +38 -9
  95. package/dist/core/config/schema/embedding.js +20 -5
  96. package/dist/core/config/schema/engines.js +5 -0
  97. package/dist/core/config/schema/execution.js +1 -1
  98. package/dist/core/config/schema/experimental.js +1 -1
  99. package/dist/core/config/schema/improve-processes.js +21 -95
  100. package/dist/core/config/schema/improve.js +4 -42
  101. package/dist/core/config/schema/scheduler.js +12 -12
  102. package/dist/core/config/schema/search.js +6 -22
  103. package/dist/core/env-secret-ref.js +0 -1
  104. package/dist/core/errors.js +8 -9
  105. package/dist/core/file-lock.js +76 -173
  106. package/dist/core/logs-db.js +2 -2
  107. package/dist/core/paths.js +0 -27
  108. package/dist/core/redaction.js +109 -2
  109. package/dist/core/run-lock.js +2 -5
  110. package/dist/core/spawn-env.js +1 -1
  111. package/dist/core/state/migrations.js +108 -61
  112. package/dist/core/state-db-scope.js +2 -4
  113. package/dist/core/state-db.js +126 -692
  114. package/dist/core/type-presentation.js +1 -9
  115. package/dist/core/write-source.js +293 -1012
  116. package/dist/execution/input-contract.js +1 -1
  117. package/dist/execution/resolved-request.js +135 -689
  118. package/dist/execution/source.js +63 -257
  119. package/dist/execution/target-ref.js +1 -1
  120. package/dist/indexer/bundle-identity-guard.js +2 -2
  121. package/dist/indexer/db/graph-db.js +106 -46
  122. package/dist/indexer/ensure-index.js +44 -85
  123. package/dist/indexer/graph/graph-extraction.js +340 -562
  124. package/dist/indexer/graph/graph-related.js +130 -0
  125. package/dist/indexer/index-rebuild-lock.js +3 -11
  126. package/dist/indexer/index-writer-lock.js +8 -17
  127. package/dist/indexer/index-written-assets.js +139 -151
  128. package/dist/indexer/indexer.js +524 -846
  129. package/dist/indexer/materialize-embeddings.js +60 -397
  130. package/dist/indexer/passes/memory-inference.js +81 -90
  131. package/dist/indexer/passes/metadata.js +132 -200
  132. package/dist/indexer/read-preflight.js +0 -7
  133. package/dist/indexer/scan/doc-to-entry.js +1 -3
  134. package/dist/indexer/scan/drain-dir.js +1 -1
  135. package/dist/indexer/search/db-search.js +181 -590
  136. package/dist/indexer/search/fts-query.js +30 -41
  137. package/dist/indexer/search/ranking.js +28 -154
  138. package/dist/indexer/search/search-attribution.js +12 -32
  139. package/dist/indexer/search/search-fields.js +11 -15
  140. package/dist/indexer/search/search-hit-enrichers.js +54 -85
  141. package/dist/indexer/search/search-source.js +1 -4
  142. package/dist/indexer/usage/usage-events.js +2 -7
  143. package/dist/integrations/agent/engine-fallback.js +23 -40
  144. package/dist/integrations/agent/engine-resolution.js +93 -183
  145. package/dist/integrations/agent/execution.js +507 -0
  146. package/dist/integrations/agent/model-map.js +28 -156
  147. package/dist/integrations/agent/request-lowering.js +66 -141
  148. package/dist/integrations/agent/runner-dispatch.js +143 -321
  149. package/dist/integrations/agent/runner.js +54 -14
  150. package/dist/integrations/lockfile.js +53 -101
  151. package/dist/llm/embedders/deterministic.js +2 -3
  152. package/dist/llm/embedders/profile.js +71 -0
  153. package/dist/llm/embedders/remote.js +10 -15
  154. package/dist/llm/graph-extract.js +3 -12
  155. package/dist/llm/index-passes.js +3 -5
  156. package/dist/llm/memory-infer.js +1 -2
  157. package/dist/llm/metadata-enhance.js +1 -2
  158. package/dist/llm/structured-call.js +5 -24
  159. package/dist/output/generic-render.js +23 -11
  160. package/dist/output/html-render.js +13 -10
  161. package/dist/output/render-registry.js +3 -32
  162. package/dist/output/shapes/helpers.js +2 -34
  163. package/dist/output/shapes/passthrough.js +1 -9
  164. package/dist/{indexer/search/ranking-types.js → output/text/bundle-rename.js} +4 -1
  165. package/dist/output/text/command-format.js +60 -23
  166. package/dist/output/text/helpers.js +1 -1
  167. package/dist/output/text/migrate.js +5 -14
  168. package/dist/output/text/proposal-format.js +1 -2
  169. package/dist/output/text/workflow-format.js +0 -32
  170. package/dist/output/text.js +2 -0
  171. package/dist/registry/factory.js +4 -19
  172. package/dist/registry/network.js +66 -220
  173. package/dist/registry/providers/index.js +0 -2
  174. package/dist/registry/providers/skills-sh.js +3 -14
  175. package/dist/registry/providers/static-index.js +24 -26
  176. package/dist/registry/resolve.js +55 -131
  177. package/dist/scripts/akm-migrate-node.js +43940 -93320
  178. package/dist/scripts/akm-migrate.js +43700 -93078
  179. package/dist/setup/registry-stash-loader.js +4 -13
  180. package/dist/setup/semantic-assets.js +3 -44
  181. package/dist/setup/setup.js +1 -1
  182. package/dist/setup/steps/tasks.js +25 -15
  183. package/dist/sources/provider-factory.js +17 -18
  184. package/dist/sources/providers/filesystem.js +2 -3
  185. package/dist/sources/providers/git-install.js +7 -1
  186. package/dist/sources/providers/git-provider.js +0 -3
  187. package/dist/sources/providers/git-stash.js +0 -17
  188. package/dist/sources/providers/npm.js +2 -4
  189. package/dist/sources/providers/provider-utils.js +5 -10
  190. package/dist/sources/providers/website.js +0 -2
  191. package/dist/sources/snapshot-fetchers/website-ingest.js +1 -1
  192. package/dist/sources/website-url.js +2 -2
  193. package/dist/storage/database.js +9 -35
  194. package/dist/storage/repositories/improve-ledger-repository.js +168 -0
  195. package/dist/storage/repositories/index-connection.js +34 -70
  196. package/dist/storage/repositories/index-entries-repository.js +69 -111
  197. package/dist/storage/repositories/index-entry-mapper.js +1 -2
  198. package/dist/storage/repositories/index-entry-schema.js +83 -269
  199. package/dist/storage/repositories/index-fts-repository.js +86 -256
  200. package/dist/storage/repositories/index-llm-cache-repository.js +17 -0
  201. package/dist/storage/repositories/index-meta-repository.js +6 -4
  202. package/dist/storage/repositories/index-schema.js +192 -220
  203. package/dist/storage/repositories/index-utility-repository.js +8 -29
  204. package/dist/storage/repositories/index-vec-repository.js +133 -414
  205. package/dist/storage/repositories/outcome-repository.js +2 -1
  206. package/dist/storage/repositories/proposals-repository.js +35 -0
  207. package/dist/storage/repositories/registry-index-cache-repository.js +100 -0
  208. package/dist/storage/repositories/task-history-repository.js +26 -4
  209. package/dist/storage/repositories/workflow-runs-repository.js +53 -244
  210. package/dist/storage/sqlite-migrations.js +136 -0
  211. package/dist/storage/sqlite-pragmas.js +11 -9
  212. package/dist/storage/sqlite-transaction.js +170 -0
  213. package/dist/storage/state-db-integrity.js +34 -27
  214. package/dist/tasks/activation-config.js +134 -62
  215. package/dist/tasks/backends/cron.js +129 -277
  216. package/dist/tasks/backends/exec-utils.js +2 -5
  217. package/dist/tasks/backends/launchd.js +125 -745
  218. package/dist/tasks/backends/schtasks.js +101 -620
  219. package/dist/tasks/prepare/prepare-support.js +5 -15
  220. package/dist/tasks/prepare/prepare.js +0 -2
  221. package/dist/tasks/resolve-akm-bin.js +20 -79
  222. package/dist/tasks/run/attempt-lifecycle.js +0 -1
  223. package/dist/tasks/scheduler-binding.js +18 -238
  224. package/dist/tasks/scheduler-invocation.js +52 -52
  225. package/dist/tasks/scheduler-lock.js +53 -0
  226. package/dist/tasks/scheduler-sync.js +361 -751
  227. package/dist/tasks/source/parse-task-source.js +160 -10
  228. package/dist/tasks/source/task-source-v3-frozen.js +3 -4
  229. package/dist/tasks/source/task-to-v4.js +2 -2
  230. package/dist/workflows/authoring/authoring.js +3 -12
  231. package/dist/workflows/compile.js +211 -0
  232. package/dist/workflows/concurrency-policy.js +13 -74
  233. package/dist/workflows/exec/child-invocation.js +3 -17
  234. package/dist/workflows/exec/child-workflow.js +32 -141
  235. package/dist/workflows/exec/dispatch-redaction.js +13 -53
  236. package/dist/workflows/exec/environment.js +98 -0
  237. package/dist/workflows/exec/exec-unit.js +33 -140
  238. package/dist/workflows/exec/frozen-judge.js +7 -59
  239. package/dist/workflows/exec/native-executor.js +82 -341
  240. package/dist/workflows/exec/param-secrets.js +29 -47
  241. package/dist/workflows/exec/run-workflow.js +154 -387
  242. package/dist/workflows/exec/scheduler.js +9 -36
  243. package/dist/workflows/exec/step-work.js +127 -430
  244. package/dist/workflows/exec/unit-dispatch.js +11 -63
  245. package/dist/workflows/exec/unit-writer.js +8 -52
  246. package/dist/workflows/exec/worktree.js +39 -273
  247. package/dist/workflows/freeze/child-output-references.js +4 -15
  248. package/dist/workflows/freeze/environment.js +99 -92
  249. package/dist/workflows/freeze/freeze.js +172 -0
  250. package/dist/workflows/freeze/step-values.js +19 -21
  251. package/dist/workflows/freeze/targets/child-workflow.js +23 -92
  252. package/dist/workflows/freeze/targets/command.js +10 -33
  253. package/dist/workflows/freeze/targets/script.js +5 -12
  254. package/dist/workflows/freeze/targets/shell.js +3 -6
  255. package/dist/workflows/freeze/targets/task.js +25 -80
  256. package/dist/workflows/freeze/task-bindings.js +20 -67
  257. package/dist/workflows/{source-ir/github-yaml.js → github-yaml.js} +88 -206
  258. package/dist/workflows/ir/params.js +6 -51
  259. package/dist/workflows/ir/plan-hash.js +2 -34
  260. package/dist/workflows/parser.js +140 -43
  261. package/dist/{commands/improve/consolidate/types.js → workflows/plan.js} +2 -1
  262. package/dist/workflows/renderer.js +36 -69
  263. package/dist/workflows/resource-limits.js +12 -120
  264. package/dist/workflows/runtime/agent-identity.js +8 -40
  265. package/dist/workflows/runtime/run-outputs.js +3 -6
  266. package/dist/workflows/runtime/run-plan.js +316 -0
  267. package/dist/workflows/runtime/runs.js +48 -200
  268. package/dist/workflows/runtime/workflow-asset-loader.js +24 -57
  269. package/dist/workflows/{source-ir/semantics.js → source-semantics.js} +16 -20
  270. package/dist/workflows/validate-summary.js +2 -7
  271. package/docs/integration/bundling-akm.md +49 -42
  272. package/docs/migration/README.md +1 -0
  273. package/docs/migration/release-notes/0.9.17.md +41 -0
  274. package/docs/migration/v0.9.1-to-v0.9.2.md +19 -7
  275. package/docs/reference/cli.md +182 -125
  276. package/docs/reference/configuration.md +49 -56
  277. package/docs/reference/data-and-telemetry.md +19 -20
  278. package/docs/reference/tasks.md +86 -38
  279. package/docs/reference/workflow-schema.md +14 -18
  280. package/docs/reference/workflows.md +6 -9
  281. package/package.json +1 -1
  282. package/schemas/akm-config.json +87 -406
  283. package/dist/commands/health/advisories.js +0 -150
  284. package/dist/commands/health/metrics.js +0 -329
  285. package/dist/commands/health/surfaces.js +0 -102
  286. package/dist/commands/improve/anti-collapse.js +0 -83
  287. package/dist/commands/improve/collapse-detector.js +0 -432
  288. package/dist/commands/improve/consolidate/eligibility.js +0 -48
  289. package/dist/commands/improve/consolidate/merge.js +0 -146
  290. package/dist/commands/improve/distill/promote-memory.js +0 -329
  291. package/dist/commands/improve/distill/quality-gate.js +0 -500
  292. package/dist/commands/improve/memory/memory-contradiction-detect.js +0 -291
  293. package/dist/commands/improve/proposal-envelope.js +0 -31
  294. package/dist/commands/improve/run-context.js +0 -123
  295. package/dist/commands/improve/shared.js +0 -21
  296. package/dist/commands/improve/source-identity.js +0 -28
  297. package/dist/commands/improve/triage.js +0 -96
  298. package/dist/commands/proposal/drain-policies.js +0 -151
  299. package/dist/commands/sources/update-transaction.js +0 -220
  300. package/dist/core/action-contributors.js +0 -28
  301. package/dist/core/config/config-version-shim.js +0 -101
  302. package/dist/core/config/retired-experimental-keys-shim.js +0 -62
  303. package/dist/core/fs-txn.js +0 -405
  304. package/dist/core/lexical-score.js +0 -25
  305. package/dist/core/maintenance-barrier.js +0 -167
  306. package/dist/execution/executable-identity.js +0 -105
  307. package/dist/execution/guarded-source.js +0 -441
  308. package/dist/indexer/graph/graph-boost.js +0 -427
  309. package/dist/indexer/graph/graph-dedup.js +0 -95
  310. package/dist/indexer/search/name-match.js +0 -35
  311. package/dist/indexer/search/ranking-contributors.js +0 -515
  312. package/dist/indexer/walk/project-context.js +0 -192
  313. package/dist/integrations/agent/execution-cascade.js +0 -566
  314. package/dist/integrations/agent/execution-definitions.js +0 -202
  315. package/dist/integrations/agent/execution-lowering.js +0 -841
  316. package/dist/integrations/agent/execution-preparation.js +0 -98
  317. package/dist/integrations/agent/inline-execution.js +0 -74
  318. package/dist/registry/create-provider-registry.js +0 -29
  319. package/dist/registry/pinned-request-helper.js +0 -247
  320. package/dist/registry/pinned-transport.js +0 -717
  321. package/dist/sources/providers/index.js +0 -14
  322. package/dist/storage/engines/sqlite-migrations.js +0 -271
  323. package/dist/storage/repositories/canaries-repository.js +0 -107
  324. package/dist/storage/repositories/embedding-salvage-repository.js +0 -184
  325. package/dist/storage/repositories/registry-cache.js +0 -113
  326. package/dist/tasks/scheduler-sync-preview.js +0 -52
  327. package/dist/workflows/freeze/resolve-steps.js +0 -86
  328. package/dist/workflows/freeze/source-freeze.js +0 -64
  329. package/dist/workflows/ir/compile.js +0 -321
  330. package/dist/workflows/ir/environment-v4.js +0 -330
  331. package/dist/workflows/ir/freeze-v4.js +0 -153
  332. package/dist/workflows/ir/schema-v4.js +0 -745
  333. package/dist/workflows/ir/schema.js +0 -354
  334. package/dist/workflows/program/schema.js +0 -78
  335. package/dist/workflows/runtime/checkin.js +0 -57
  336. package/dist/workflows/runtime/plan-classifier.js +0 -196
  337. package/dist/workflows/runtime/unit-checkin.js +0 -45
  338. package/dist/workflows/runtime/unit-phases.js +0 -20
  339. package/dist/workflows/schema.js +0 -4
  340. package/dist/workflows/source-ir/compile.js +0 -200
  341. package/dist/workflows/source-ir/program.js +0 -50
  342. package/dist/workflows/source-ir/result.js +0 -26
  343. package/dist/workflows/source-ir/schema.js +0 -786
  344. package/dist/workflows/source-ir/triggers.js +0 -79
  345. package/dist/workflows/source-ir/uses.js +0 -40
  346. package/dist/workflows/validator.js +0 -60
@@ -1,566 +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 { ENGINE_NAME_PATTERN_SOURCE } from "../../core/config/engine-semantics.js";
5
- import { ConfigError } from "../../core/errors.js";
6
- import { DURATION_UNITS, parseDuration } from "../../core/time.js";
7
- import { cloneExecutionJson, cloneExecutionJsonObject, } from "../../execution/json.js";
8
- import { EXECUTION_MAX_TIMEOUT_MS } from "../../execution/limits.js";
9
- import { assertSnapshotKeys, requireSnapshotField, snapshotStrictRecord, } from "../../execution/record.js";
10
- import { cloneResolvedCommandContent, cloneResolvedPersonaContent, createResolvedExecutionRequest, } from "../../execution/resolved-request.js";
11
- import { cloneAdapterExtensions, cloneToolSelection, cloneUnresolvedExecutionDefaults, executionPersonaMatchesSelector, isPortableExecutionAgentSelector, requireStableExecutionSelector, } from "../../execution/source.js";
12
- import { resolveModelMapAlias } from "./model-map.js";
13
- export const EXECUTION_CASCADE_PLAN_VERSION = 1;
14
- export const FIXED_EXECUTION_ENGINE_FALLBACK = "opencode-sdk";
15
- const planInstances = new WeakSet();
16
- const ENGINE_NAME_PATTERN = new RegExp(ENGINE_NAME_PATTERN_SOURCE);
17
- const MODEL_ALIAS_PATTERN = /^[a-z][a-z0-9]*(?:-[a-z0-9]+)*$/;
18
- const RESERVED_ENGINE_KEYS = new Set(["__proto__", "constructor", "prototype", "tostring"]);
19
- function record(value, path) {
20
- return snapshotStrictRecord(value, path);
21
- }
22
- function only(recordValue, allowed, path) {
23
- assertSnapshotKeys(recordValue, allowed, path);
24
- }
25
- function own(recordValue, key) {
26
- return Object.hasOwn(recordValue, key);
27
- }
28
- function required(recordValue, key, path) {
29
- return requireSnapshotField(recordValue, key, path);
30
- }
31
- function stableIdentifier(value, path) {
32
- return requireStableExecutionSelector(value, path);
33
- }
34
- function canonicalEngineName(value, path) {
35
- const name = stableIdentifier(value, path);
36
- if (!ENGINE_NAME_PATTERN.test(name) || RESERVED_ENGINE_KEYS.has(name.toLowerCase())) {
37
- throw new TypeError(`${path} must be a canonical, non-reserved engine name`);
38
- }
39
- return name;
40
- }
41
- function frozenNullPrototypeRecord(entries) {
42
- const out = Object.create(null);
43
- for (const [key, value] of entries) {
44
- Object.defineProperty(out, key, { value, enumerable: true, configurable: false, writable: false });
45
- }
46
- return Object.freeze(out);
47
- }
48
- function normalizeLayer(value, kind, path) {
49
- const input = record(value, path);
50
- only(input, ["id", "values"], path);
51
- const id = stableIdentifier(required(input, "id", path), `${path}.id`);
52
- const values = cloneUnresolvedExecutionDefaults(required(input, "values", path), `${path}.values`);
53
- return Object.freeze({ id, kind, values });
54
- }
55
- function normalizeEngineSelection(value, path) {
56
- const input = record(value, path);
57
- only(input, ["name", "kind", "platform", "settings", "extensions"], path);
58
- const name = canonicalEngineName(required(input, "name", path), `${path}.name`);
59
- const kind = required(input, "kind", path);
60
- if (kind !== "agent" && kind !== "sdk" && kind !== "llm") {
61
- throw new TypeError(`${path}.kind must be agent, sdk, or llm`);
62
- }
63
- const out = { name, kind };
64
- if (own(input, "platform")) {
65
- if (input.platform !== null && typeof input.platform !== "string") {
66
- throw new TypeError(`${path}.platform must be a string or null`);
67
- }
68
- out.platform = input.platform;
69
- }
70
- if (own(input, "settings")) {
71
- out.settings = input.settings === null ? null : cloneExecutionJsonObject(input.settings, `${path}.settings`);
72
- }
73
- if (own(input, "extensions")) {
74
- out.extensions = cloneAdapterExtensions(input.extensions, `${path}.extensions`);
75
- }
76
- return Object.freeze(out);
77
- }
78
- function normalizeEngineDefinition(value, name) {
79
- const path = `engines.${name}`;
80
- const input = record(value, path);
81
- only(input, ["selection", "defaults", "modelMapKey"], path);
82
- const selection = normalizeEngineSelection(required(input, "selection", path), `${path}.selection`);
83
- if (selection.name !== name) {
84
- throw new TypeError(`${path}.selection.name must match its engine registry key`);
85
- }
86
- const defaults = own(input, "defaults")
87
- ? cloneUnresolvedExecutionDefaults(input.defaults, `${path}.defaults`)
88
- : Object.freeze({});
89
- if (own(defaults, "engine")) {
90
- throw new TypeError(`${path}.defaults.engine is invalid because the engine layer cannot select itself`);
91
- }
92
- const rawMapKey = own(input, "modelMapKey") ? input.modelMapKey : (selection.platform ?? selection.name);
93
- const modelMapKey = stableIdentifier(rawMapKey, `${path}.modelMapKey`);
94
- return Object.freeze({
95
- selection,
96
- defaults,
97
- modelMapKey,
98
- });
99
- }
100
- function normalizeEngines(value) {
101
- const input = record(value, "engines");
102
- const entries = [];
103
- for (const [name, definition] of Object.entries(input)) {
104
- canonicalEngineName(name, `engines.${name}`);
105
- entries.push([name, normalizeEngineDefinition(definition, name)]);
106
- }
107
- return frozenNullPrototypeRecord(entries);
108
- }
109
- function normalizeModelMap(value) {
110
- const input = record(value, "modelMap");
111
- only(input, ["version", "aliases"], "modelMap");
112
- if (required(input, "version", "modelMap") !== 1) {
113
- throw new TypeError("modelMap.version must be 1");
114
- }
115
- const aliasesInput = record(required(input, "aliases", "modelMap"), "modelMap.aliases");
116
- const aliases = [];
117
- for (const [alias, rawEngines] of Object.entries(aliasesInput)) {
118
- stableIdentifier(alias, `modelMap.aliases.${alias}`);
119
- if (!MODEL_ALIAS_PATTERN.test(alias) || RESERVED_ENGINE_KEYS.has(alias.toLowerCase())) {
120
- throw new TypeError(`modelMap alias ${JSON.stringify(alias)} is not canonical`);
121
- }
122
- const engineInput = record(rawEngines, `modelMap.aliases.${alias}`);
123
- const profiles = [];
124
- for (const [engine, rawProfile] of Object.entries(engineInput)) {
125
- if (engine !== "*")
126
- canonicalEngineName(engine, `modelMap.aliases.${alias}.${engine}`);
127
- const profile = record(rawProfile, `modelMap.aliases.${alias}.${engine}`);
128
- only(profile, ["model", "inference"], `modelMap.aliases.${alias}.${engine}`);
129
- const model = required(profile, "model", `modelMap.aliases.${alias}.${engine}`);
130
- if (typeof model !== "string" || model.length === 0 || model.trim() !== model) {
131
- throw new TypeError(`modelMap.aliases.${alias}.${engine}.model must be a non-empty exact identifier`);
132
- }
133
- const normalized = { model };
134
- if (own(profile, "inference")) {
135
- normalized.inference =
136
- profile.inference === null
137
- ? null
138
- : cloneExecutionJsonObject(profile.inference, `modelMap.aliases.${alias}.${engine}.inference`);
139
- }
140
- profiles.push([engine, Object.freeze(normalized)]);
141
- }
142
- aliases.push([alias, frozenNullPrototypeRecord(profiles)]);
143
- }
144
- return Object.freeze({ version: 1, aliases: frozenNullPrototypeRecord(aliases) });
145
- }
146
- function normalizeLayers(value) {
147
- const input = record(value, "layers");
148
- only(input, ["installation", "agent", "command", "invocationDefaults", "current"], "layers");
149
- const out = {
150
- installation: normalizeLayer(required(input, "installation", "layers"), "installation", "layers.installation"),
151
- };
152
- for (const [key, kind] of [
153
- ["agent", "agent"],
154
- ["command", "command"],
155
- ["invocationDefaults", "invocation-defaults"],
156
- ["current", "current"],
157
- ]) {
158
- if (own(input, key)) {
159
- if (input[key] === undefined)
160
- throw new TypeError(`layers.${key} must be omitted rather than undefined`);
161
- out[key] = normalizeLayer(input[key], kind, `layers.${key}`);
162
- }
163
- }
164
- return Object.freeze(out);
165
- }
166
- function orderedWithoutEngine(layers) {
167
- return [layers.installation, layers.agent, layers.command, layers.invocationDefaults, layers.current].filter((layer) => layer !== undefined);
168
- }
169
- function selectNearest(layers, key) {
170
- for (let index = layers.length - 1; index >= 0; index -= 1) {
171
- const layer = layers[index];
172
- if (layer && own(layer.values, key)) {
173
- return { present: true, value: layer.values[key], layer, index };
174
- }
175
- }
176
- return { present: false, index: -1 };
177
- }
178
- function provenance(layer, via = "explicit") {
179
- return Object.freeze({ layer: layer.id, kind: layer.kind, via });
180
- }
181
- function fallbackProvenance() {
182
- return Object.freeze({ layer: FIXED_EXECUTION_ENGINE_FALLBACK, kind: "fallback", via: "fallback" });
183
- }
184
- function sourceProvenance(layer, kind) {
185
- return Object.freeze({ layer, kind, via: "source" });
186
- }
187
- function chooseEngine(layers, engines) {
188
- const selected = selectNearest(layers, "engine");
189
- let name;
190
- let field;
191
- let fallback = false;
192
- if (!selected.present || selected.value === null) {
193
- name = FIXED_EXECUTION_ENGINE_FALLBACK;
194
- field = fallbackProvenance();
195
- fallback = true;
196
- }
197
- else {
198
- if (typeof selected.value !== "string" || selected.value.length === 0) {
199
- throw new ConfigError("Selected engine must be a non-empty configured engine name.", "INVALID_CONFIG_FILE");
200
- }
201
- name = selected.value;
202
- field = provenance(selected.layer);
203
- }
204
- const definition = engines[name];
205
- if (!definition) {
206
- if (fallback) {
207
- throw new ConfigError("No engine was selected and the fixed opencode-sdk fallback is unavailable.", "INVALID_CONFIG_FILE", "Configure defaults.engine or configure/install the opencode-sdk engine.");
208
- }
209
- throw new ConfigError(`Selected engine ${JSON.stringify(name)} is not configured.`, "INVALID_CONFIG_FILE");
210
- }
211
- return {
212
- definition,
213
- field,
214
- ...(selected.present ? { requested: provenance(selected.layer) } : {}),
215
- fallback,
216
- };
217
- }
218
- function cloneJsonValue(value, path) {
219
- return cloneExecutionJson(value, path);
220
- }
221
- function isObject(value) {
222
- return value !== null && value !== undefined && typeof value === "object" && !Array.isArray(value);
223
- }
224
- function deleteInferenceProvenance(fields) {
225
- for (const key of Object.keys(fields)) {
226
- if (key === "/inference" || key.startsWith("/inference/"))
227
- delete fields[key];
228
- }
229
- }
230
- function deleteInferenceDescendantProvenance(fields, path) {
231
- for (const key of Object.keys(fields)) {
232
- if (key.startsWith(`${path}/`))
233
- delete fields[key];
234
- }
235
- }
236
- function jsonPointerSegment(value) {
237
- return value.replaceAll("~", "~0").replaceAll("/", "~1");
238
- }
239
- function setInferenceTreeProvenance(value, path, source, fields) {
240
- fields[path] = source;
241
- if (!isObject(value))
242
- return;
243
- for (const [key, child] of Object.entries(value)) {
244
- setInferenceTreeProvenance(child, `${path}/${jsonPointerSegment(key)}`, source, fields);
245
- }
246
- }
247
- function mergeInferenceObject(base, overlay, prefix, source, fields) {
248
- const out = new Map();
249
- for (const [key, value] of Object.entries(base))
250
- out.set(key, cloneJsonValue(value, `${prefix}.${key}`));
251
- for (const [key, value] of Object.entries(overlay)) {
252
- const path = `${prefix}/${jsonPointerSegment(key)}`;
253
- const previous = out.get(key);
254
- if (isObject(previous) && isObject(value)) {
255
- out.set(key, mergeInferenceObject(previous, value, path, source, fields));
256
- fields[path] = source;
257
- }
258
- else {
259
- deleteInferenceDescendantProvenance(fields, path);
260
- out.set(key, cloneJsonValue(value, path));
261
- setInferenceTreeProvenance(value, path, source, fields);
262
- }
263
- }
264
- return Object.freeze(Object.fromEntries(out));
265
- }
266
- function resolveInference(layers, aliasInferenceByLayer, fields) {
267
- let present = false;
268
- let current;
269
- const apply = (value, layer, via) => {
270
- const field = provenance(layer, via);
271
- present = true;
272
- if (value === null) {
273
- current = null;
274
- deleteInferenceProvenance(fields);
275
- fields["/inference"] = field;
276
- return;
277
- }
278
- fields["/inference"] = field;
279
- current = mergeInferenceObject(isObject(current) ? current : Object.freeze({}), value, "/inference", field, fields);
280
- };
281
- for (const [index, layer] of layers.entries()) {
282
- if (aliasInferenceByLayer.has(index)) {
283
- apply(aliasInferenceByLayer.get(index), layer, "model-alias");
284
- }
285
- if (own(layer.values, "inference")) {
286
- apply(layer.values.inference, layer, "explicit");
287
- }
288
- }
289
- return present ? { present: true, value: current } : { present: false };
290
- }
291
- function resolveModels(layers, definition, modelMap) {
292
- let selected = { present: false, index: -1 };
293
- let resolved;
294
- const aliasInferenceByLayer = new Map();
295
- for (const [index, layer] of layers.entries()) {
296
- if (!own(layer.values, "model"))
297
- continue;
298
- const value = layer.values.model;
299
- selected = { present: true, value, layer, index };
300
- if (value === null) {
301
- resolved = null;
302
- continue;
303
- }
304
- if (typeof value !== "string" || value.length === 0) {
305
- throw new ConfigError("Resolved model must be null or a non-empty string.", "INVALID_CONFIG_FILE");
306
- }
307
- const selection = resolveModelMapAlias(value, definition.modelMapKey, modelMap);
308
- if (selection.interpretation === "alias" && selection.inference !== undefined) {
309
- aliasInferenceByLayer.set(index, selection.inference);
310
- }
311
- resolved = Object.freeze({
312
- input: selection.input,
313
- interpretation: selection.interpretation,
314
- resolved: selection.model,
315
- });
316
- }
317
- return Object.freeze({ selected, resolved, aliasInferenceByLayer });
318
- }
319
- function normalizeTimeout(value) {
320
- if (value === null)
321
- return null;
322
- const milliseconds = typeof value === "string" ? parseDuration(value, DURATION_UNITS) : value;
323
- if (milliseconds === null ||
324
- !Number.isInteger(milliseconds) ||
325
- milliseconds < 0 ||
326
- milliseconds > EXECUTION_MAX_TIMEOUT_MS) {
327
- throw new ConfigError(`Resolved execution timeout must be null, a bounded integer in milliseconds, or a duration such as 20m.`, "INVALID_CONFIG_FILE");
328
- }
329
- return milliseconds;
330
- }
331
- function toolsRequireAuthorization(value, present) {
332
- if (!present || value === null)
333
- return false;
334
- if (typeof value === "string")
335
- return value.length > 0;
336
- if (Array.isArray(value))
337
- return value.length > 0;
338
- return typeof value === "object" && value !== null && Object.keys(value).length > 0;
339
- }
340
- function normalizeAuthorizationDecision(value) {
341
- const input = record(value, "tool authorization decision");
342
- only(input, ["status", "policy"], "tool authorization decision");
343
- const status = required(input, "status", "tool authorization decision");
344
- if (status !== "allowed" && status !== "denied") {
345
- throw new TypeError("tool authorization decision.status must be allowed or denied");
346
- }
347
- const policy = stableIdentifier(required(input, "policy", "tool authorization decision"), "tool authorization decision.policy");
348
- return Object.freeze({ status, policy });
349
- }
350
- function authorizationFor(requiresAuthorization, authorizer, input) {
351
- if (!requiresAuthorization)
352
- return Object.freeze({ status: "not-required" });
353
- if (!authorizer || !input) {
354
- return Object.freeze({
355
- status: "denied",
356
- reason: "Selected tools require an explicit machine/user authorization policy.",
357
- policy: Object.freeze({ id: "unconfigured" }),
358
- });
359
- }
360
- const decision = normalizeAuthorizationDecision(authorizer(Object.freeze(input)));
361
- return Object.freeze({
362
- status: decision.status,
363
- reason: decision.status === "allowed"
364
- ? "Selected tools were authorized by operator policy."
365
- : "Selected tools are not authorized by operator policy.",
366
- policy: Object.freeze({ id: decision.policy }),
367
- });
368
- }
369
- function freezeProvenance(fields) {
370
- return frozenNullPrototypeRecord(Object.entries(fields)
371
- .sort(([left], [right]) => (left < right ? -1 : left > right ? 1 : 0))
372
- .map(([key, value]) => [key, Object.freeze({ ...value })]));
373
- }
374
- export function planExecutionCascade(raw) {
375
- const input = record(raw, "execution cascade input");
376
- only(input, ["command", "conversation", "persona", "layers", "engines", "modelMap", "invocationKind", "authorizeTools"], "execution cascade input");
377
- const command = cloneResolvedCommandContent(required(input, "command", "execution cascade input"));
378
- const invocationKind = required(input, "invocationKind", "execution cascade input");
379
- if (invocationKind !== "direct" && invocationKind !== "task" && invocationKind !== "workflow") {
380
- throw new TypeError("execution cascade input.invocationKind is invalid");
381
- }
382
- const normalizedInvocationKind = invocationKind;
383
- const personaPresent = own(input, "persona");
384
- if (personaPresent && input.persona === undefined) {
385
- throw new TypeError("execution cascade input.persona must be omitted, null, or a resolved persona");
386
- }
387
- let persona = personaPresent
388
- ? input.persona === null
389
- ? null
390
- : cloneResolvedPersonaContent(input.persona)
391
- : undefined;
392
- if (own(input, "authorizeTools") &&
393
- input.authorizeTools !== undefined &&
394
- typeof input.authorizeTools !== "function") {
395
- throw new TypeError("execution cascade input.authorizeTools must be a function or omitted");
396
- }
397
- const normalizedLayers = normalizeLayers(required(input, "layers", "execution cascade input"));
398
- const engines = normalizeEngines(required(input, "engines", "execution cascade input"));
399
- const modelMap = normalizeModelMap(required(input, "modelMap", "execution cascade input"));
400
- const beforeEngine = orderedWithoutEngine(normalizedLayers);
401
- const selectedEngine = chooseEngine(beforeEngine, engines);
402
- const engineLayer = Object.freeze({
403
- id: selectedEngine.definition.selection.name,
404
- kind: "engine",
405
- values: selectedEngine.definition.defaults,
406
- });
407
- const layers = [
408
- normalizedLayers.installation,
409
- engineLayer,
410
- normalizedLayers.agent,
411
- normalizedLayers.command,
412
- normalizedLayers.invocationDefaults,
413
- normalizedLayers.current,
414
- ].filter((layer) => layer !== undefined);
415
- const fields = Object.create(null);
416
- fields.engine = selectedEngine.field;
417
- if (selectedEngine.requested)
418
- fields["engine.requested"] = selectedEngine.requested;
419
- const commandRef = command.source?.ref ?? null;
420
- fields.command = sourceProvenance(commandRef ?? "inline", "command");
421
- const selectedAgent = selectNearest(layers, "agent");
422
- let resolvedAgent;
423
- let requestPersonaPresent = personaPresent;
424
- if (selectedAgent.present) {
425
- fields.agent = provenance(selectedAgent.layer);
426
- if (selectedAgent.value === null) {
427
- resolvedAgent = null;
428
- persona = null;
429
- requestPersonaPresent = true;
430
- }
431
- else {
432
- const selector = stableIdentifier(selectedAgent.value, "selected agent");
433
- resolvedAgent = selector;
434
- if (isPortableExecutionAgentSelector(selector)) {
435
- if (!persona || !executionPersonaMatchesSelector(selector, persona.source.ref)) {
436
- throw new ConfigError(`Selected agent ${JSON.stringify(selector)} does not match the resolved persona source.`, "INVALID_CONFIG_FILE", "Resolve the selected agent through its bundle adapter before planning execution.");
437
- }
438
- }
439
- else {
440
- persona = null;
441
- requestPersonaPresent = true;
442
- }
443
- }
444
- }
445
- const personaRef = persona?.source.ref ?? null;
446
- if (persona)
447
- fields.persona = sourceProvenance(personaRef, "agent");
448
- const modelResolution = resolveModels(layers, selectedEngine.definition, modelMap);
449
- const selectedModel = modelResolution.selected;
450
- if (selectedModel.present) {
451
- fields.model = provenance(selectedModel.layer);
452
- }
453
- const inference = resolveInference(layers, modelResolution.aliasInferenceByLayer, fields);
454
- const selectedSchema = selectNearest(layers, "outputSchema");
455
- if (selectedSchema.present)
456
- fields.outputSchema = provenance(selectedSchema.layer);
457
- const selectedTools = selectNearest(layers, "tools");
458
- if (selectedTools.present)
459
- fields.tools = provenance(selectedTools.layer);
460
- const selectedTimeout = selectNearest(layers, "timeout");
461
- const selectedWorkspace = selectNearest(layers, "workspace");
462
- const selectedEnvironment = selectNearest(layers, "environment");
463
- const selectedRuntime = selectNearest(layers, "runtime");
464
- const runtime = {};
465
- if (selectedTimeout.present) {
466
- runtime.timeoutMs = normalizeTimeout(selectedTimeout.value);
467
- fields["runtime.timeoutMs"] = provenance(selectedTimeout.layer);
468
- }
469
- if (selectedWorkspace.present) {
470
- runtime.workspace = selectedWorkspace.value;
471
- fields["runtime.workspace"] = provenance(selectedWorkspace.layer);
472
- }
473
- if (selectedEnvironment.present) {
474
- runtime.environment = selectedEnvironment.value;
475
- fields["runtime.environment"] = provenance(selectedEnvironment.layer);
476
- }
477
- if (selectedRuntime.present) {
478
- runtime.settings = selectedRuntime.value;
479
- fields["runtime.settings"] = provenance(selectedRuntime.layer);
480
- }
481
- const notices = selectedEngine.fallback
482
- ? [
483
- {
484
- code: "engine-fallback",
485
- severity: "info",
486
- adapter: "akm",
487
- field: "engine",
488
- message: "No engine was selected; using the fixed opencode-sdk fallback.",
489
- },
490
- ]
491
- : [];
492
- const tools = selectedTools.present ? cloneToolSelection(selectedTools.value, "resolved tools") : undefined;
493
- const requiresAuthorization = toolsRequireAuthorization(tools, selectedTools.present);
494
- const provisionalAuthorization = requiresAuthorization
495
- ? { status: "allowed", policy: { id: "pre-authorization-validation" } }
496
- : { status: "not-required" };
497
- const requestInput = {
498
- command,
499
- engine: selectedEngine.definition.selection,
500
- authorization: provisionalAuthorization,
501
- runtime,
502
- notices,
503
- };
504
- if (own(input, "conversation"))
505
- requestInput.conversation = input.conversation;
506
- if (selectedAgent.present)
507
- requestInput.agent = resolvedAgent;
508
- if (requestPersonaPresent)
509
- requestInput.persona = persona;
510
- if (selectedModel.present)
511
- requestInput.model = modelResolution.resolved;
512
- if (inference.present)
513
- requestInput.inference = inference.value;
514
- if (selectedSchema.present)
515
- requestInput.outputSchema = selectedSchema.value;
516
- if (selectedTools.present)
517
- requestInput.tools = tools;
518
- // Validate every dispatch-significant value and source provenance before a
519
- // policy callback can observe the request or any caller can dispatch it.
520
- const provisionalRequest = createResolvedExecutionRequest(requestInput);
521
- if (own(provisionalRequest, "conversation"))
522
- requestInput.conversation = provisionalRequest.conversation;
523
- const authorizationInput = requiresAuthorization
524
- ? {
525
- tools: tools,
526
- engine: Object.freeze({
527
- name: selectedEngine.definition.selection.name,
528
- kind: selectedEngine.definition.selection.kind,
529
- ...(own(selectedEngine.definition.selection, "platform")
530
- ? { platform: selectedEngine.definition.selection.platform }
531
- : {}),
532
- }),
533
- invocationKind: normalizedInvocationKind,
534
- commandRef,
535
- personaRef,
536
- }
537
- : undefined;
538
- const authorization = authorizationFor(requiresAuthorization, input.authorizeTools, authorizationInput);
539
- fields.authorization = Object.freeze({
540
- layer: authorization.policy && typeof authorization.policy.id === "string" ? authorization.policy.id : "not-required",
541
- kind: "authorization",
542
- via: "policy",
543
- });
544
- requestInput.authorization = authorization;
545
- const request = createResolvedExecutionRequest(requestInput);
546
- const planObject = {
547
- schemaVersion: EXECUTION_CASCADE_PLAN_VERSION,
548
- invocationKind: normalizedInvocationKind,
549
- request,
550
- provenance: freezeProvenance(fields),
551
- };
552
- if (selectedAgent.present)
553
- planObject.selectedAgent = resolvedAgent;
554
- const plan = Object.freeze(planObject);
555
- planInstances.add(plan);
556
- return plan;
557
- }
558
- export function requireAuthorizedExecutionPlan(plan) {
559
- if (!planInstances.has(plan) || !Object.isFrozen(plan)) {
560
- throw new TypeError("execution plan must be constructed by the common cascade resolver");
561
- }
562
- if (plan.request.authorization.status === "denied") {
563
- throw new ConfigError(plan.request.authorization.reason ?? "Resolved execution is not authorized by operator policy.", "EXECUTION_NOT_AUTHORIZED");
564
- }
565
- return plan.request;
566
- }