akm-cli 0.9.17-alpha.2 → 0.9.17-alpha.4

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 (343) hide show
  1. package/CHANGELOG.md +756 -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/proposal/drain.js +251 -644
  53. package/dist/commands/proposal/proposal-cli.js +3 -18
  54. package/dist/commands/proposal/proposal-types.js +20 -41
  55. package/dist/commands/proposal/proposal.js +1 -2
  56. package/dist/commands/proposal/propose.js +134 -160
  57. package/dist/commands/proposal/repository.js +502 -1487
  58. package/dist/commands/proposal/validators/proposal-quality-validators.js +71 -174
  59. package/dist/commands/proposal/validators/proposal-validators.js +1 -1
  60. package/dist/commands/proposal/validators/proposals.js +13 -89
  61. package/dist/commands/read/curate.js +63 -413
  62. package/dist/commands/read/search-cli.js +16 -33
  63. package/dist/commands/read/search.js +17 -23
  64. package/dist/commands/read/show.js +2 -13
  65. package/dist/commands/sources/bundle-cli.js +25 -2
  66. package/dist/commands/sources/bundle-config-ops.js +7 -0
  67. package/dist/commands/sources/dangerous-env-audit.js +1 -2
  68. package/dist/commands/sources/info.js +2 -11
  69. package/dist/commands/sources/installed-stashes.js +197 -746
  70. package/dist/commands/sources/schema-repair.js +98 -129
  71. package/dist/commands/sources/source-add.js +62 -12
  72. package/dist/commands/sources/stash-cli.js +1 -1
  73. package/dist/commands/tasks/explain.js +10 -13
  74. package/dist/commands/tasks/tasks-cli.js +9 -8
  75. package/dist/commands/tasks/tasks.js +326 -930
  76. package/dist/commands/tasks/validate.js +42 -21
  77. package/dist/commands/workflow/plan.js +22 -29
  78. package/dist/commands/workflow-cli.js +4 -4
  79. package/dist/core/adapter/adapters/akm-adapter.js +0 -1
  80. package/dist/core/adapter/adapters/akm-lint.js +2 -3
  81. package/dist/core/adapter/adapters/akm-metadata.js +11 -12
  82. package/dist/core/adapter/adapters/akm-workflow-adapter.js +1 -1
  83. package/dist/core/adapter/execution-source.js +17 -29
  84. package/dist/core/asset/resolve-ref.js +1 -1
  85. package/dist/core/bundle-id.js +42 -5
  86. package/dist/core/bundle-rename.js +291 -0
  87. package/dist/core/config/config-io.js +1 -2
  88. package/dist/core/config/config-schema.js +1 -33
  89. package/dist/core/config/config-walker.js +1 -1
  90. package/dist/core/config/config.js +163 -68
  91. package/dist/core/config/legacy-source-shape-shim.js +38 -9
  92. package/dist/core/config/schema/embedding.js +20 -5
  93. package/dist/core/config/schema/engines.js +5 -0
  94. package/dist/core/config/schema/execution.js +1 -1
  95. package/dist/core/config/schema/experimental.js +1 -1
  96. package/dist/core/config/schema/improve-processes.js +21 -95
  97. package/dist/core/config/schema/improve.js +4 -42
  98. package/dist/core/config/schema/scheduler.js +12 -12
  99. package/dist/core/config/schema/search.js +6 -22
  100. package/dist/core/env-secret-ref.js +0 -1
  101. package/dist/core/errors.js +8 -9
  102. package/dist/core/file-lock.js +76 -173
  103. package/dist/core/logs-db.js +2 -2
  104. package/dist/core/paths.js +0 -27
  105. package/dist/core/redaction.js +109 -2
  106. package/dist/core/run-lock.js +2 -5
  107. package/dist/core/spawn-env.js +1 -1
  108. package/dist/core/state/migrations.js +108 -61
  109. package/dist/core/state-db-scope.js +2 -4
  110. package/dist/core/state-db.js +126 -692
  111. package/dist/core/type-presentation.js +1 -9
  112. package/dist/core/write-source.js +293 -1012
  113. package/dist/execution/input-contract.js +1 -1
  114. package/dist/execution/resolved-request.js +135 -689
  115. package/dist/execution/source.js +63 -257
  116. package/dist/execution/target-ref.js +1 -1
  117. package/dist/indexer/bundle-identity-guard.js +2 -2
  118. package/dist/indexer/db/graph-db.js +106 -46
  119. package/dist/indexer/ensure-index.js +44 -85
  120. package/dist/indexer/graph/graph-extraction.js +340 -562
  121. package/dist/indexer/graph/graph-related.js +130 -0
  122. package/dist/indexer/index-rebuild-lock.js +3 -11
  123. package/dist/indexer/index-writer-lock.js +8 -17
  124. package/dist/indexer/index-written-assets.js +139 -151
  125. package/dist/indexer/indexer.js +524 -846
  126. package/dist/indexer/materialize-embeddings.js +60 -397
  127. package/dist/indexer/passes/memory-inference.js +81 -90
  128. package/dist/indexer/passes/metadata.js +132 -200
  129. package/dist/indexer/read-preflight.js +0 -7
  130. package/dist/indexer/scan/doc-to-entry.js +1 -3
  131. package/dist/indexer/scan/drain-dir.js +1 -1
  132. package/dist/indexer/search/db-search.js +181 -590
  133. package/dist/indexer/search/fts-query.js +30 -41
  134. package/dist/indexer/search/ranking.js +28 -154
  135. package/dist/indexer/search/search-attribution.js +12 -32
  136. package/dist/indexer/search/search-fields.js +11 -15
  137. package/dist/indexer/search/search-hit-enrichers.js +54 -85
  138. package/dist/indexer/search/search-source.js +1 -4
  139. package/dist/indexer/usage/usage-events.js +2 -7
  140. package/dist/integrations/agent/engine-fallback.js +23 -40
  141. package/dist/integrations/agent/engine-resolution.js +93 -183
  142. package/dist/integrations/agent/execution.js +507 -0
  143. package/dist/integrations/agent/model-map.js +28 -156
  144. package/dist/integrations/agent/request-lowering.js +66 -141
  145. package/dist/integrations/agent/runner-dispatch.js +143 -321
  146. package/dist/integrations/agent/runner.js +54 -14
  147. package/dist/integrations/lockfile.js +53 -101
  148. package/dist/llm/embedders/deterministic.js +2 -3
  149. package/dist/llm/embedders/profile.js +71 -0
  150. package/dist/llm/embedders/remote.js +10 -15
  151. package/dist/llm/graph-extract.js +3 -12
  152. package/dist/llm/index-passes.js +3 -5
  153. package/dist/llm/memory-infer.js +1 -2
  154. package/dist/llm/metadata-enhance.js +1 -2
  155. package/dist/llm/structured-call.js +5 -24
  156. package/dist/output/generic-render.js +23 -11
  157. package/dist/output/html-render.js +13 -10
  158. package/dist/output/render-registry.js +3 -32
  159. package/dist/output/shapes/helpers.js +2 -34
  160. package/dist/output/shapes/passthrough.js +1 -9
  161. package/dist/{indexer/search/ranking-types.js → output/text/bundle-rename.js} +4 -1
  162. package/dist/output/text/command-format.js +60 -23
  163. package/dist/output/text/helpers.js +1 -1
  164. package/dist/output/text/migrate.js +5 -14
  165. package/dist/output/text/proposal-format.js +1 -2
  166. package/dist/output/text/workflow-format.js +0 -32
  167. package/dist/output/text.js +2 -0
  168. package/dist/registry/factory.js +4 -19
  169. package/dist/registry/network.js +66 -220
  170. package/dist/registry/providers/index.js +0 -2
  171. package/dist/registry/providers/skills-sh.js +3 -14
  172. package/dist/registry/providers/static-index.js +24 -26
  173. package/dist/registry/resolve.js +55 -131
  174. package/dist/scripts/akm-migrate-node.js +43937 -93313
  175. package/dist/scripts/akm-migrate.js +43697 -93071
  176. package/dist/setup/registry-stash-loader.js +4 -13
  177. package/dist/setup/semantic-assets.js +3 -44
  178. package/dist/setup/setup.js +1 -1
  179. package/dist/setup/steps/tasks.js +25 -15
  180. package/dist/sources/provider-factory.js +17 -18
  181. package/dist/sources/providers/filesystem.js +2 -3
  182. package/dist/sources/providers/git-install.js +7 -1
  183. package/dist/sources/providers/git-provider.js +0 -3
  184. package/dist/sources/providers/git-stash.js +0 -17
  185. package/dist/sources/providers/npm.js +2 -4
  186. package/dist/sources/providers/provider-utils.js +5 -10
  187. package/dist/sources/providers/website.js +0 -2
  188. package/dist/sources/snapshot-fetchers/website-ingest.js +1 -1
  189. package/dist/sources/website-url.js +2 -2
  190. package/dist/storage/database.js +9 -35
  191. package/dist/storage/repositories/improve-ledger-repository.js +168 -0
  192. package/dist/storage/repositories/index-connection.js +34 -70
  193. package/dist/storage/repositories/index-entries-repository.js +69 -111
  194. package/dist/storage/repositories/index-entry-mapper.js +1 -2
  195. package/dist/storage/repositories/index-entry-schema.js +83 -269
  196. package/dist/storage/repositories/index-fts-repository.js +86 -256
  197. package/dist/storage/repositories/index-llm-cache-repository.js +17 -0
  198. package/dist/storage/repositories/index-meta-repository.js +6 -4
  199. package/dist/storage/repositories/index-schema.js +192 -220
  200. package/dist/storage/repositories/index-utility-repository.js +8 -29
  201. package/dist/storage/repositories/index-vec-repository.js +133 -414
  202. package/dist/storage/repositories/outcome-repository.js +2 -1
  203. package/dist/storage/repositories/proposals-repository.js +35 -0
  204. package/dist/storage/repositories/registry-index-cache-repository.js +100 -0
  205. package/dist/storage/repositories/task-history-repository.js +26 -4
  206. package/dist/storage/repositories/workflow-runs-repository.js +53 -244
  207. package/dist/storage/sqlite-migrations.js +136 -0
  208. package/dist/storage/sqlite-pragmas.js +11 -9
  209. package/dist/storage/sqlite-transaction.js +170 -0
  210. package/dist/storage/state-db-integrity.js +34 -27
  211. package/dist/tasks/activation-config.js +134 -62
  212. package/dist/tasks/backends/cron.js +129 -277
  213. package/dist/tasks/backends/exec-utils.js +2 -5
  214. package/dist/tasks/backends/launchd.js +125 -745
  215. package/dist/tasks/backends/schtasks.js +101 -620
  216. package/dist/tasks/prepare/prepare-support.js +5 -15
  217. package/dist/tasks/prepare/prepare.js +0 -2
  218. package/dist/tasks/resolve-akm-bin.js +20 -79
  219. package/dist/tasks/run/attempt-lifecycle.js +0 -1
  220. package/dist/tasks/scheduler-binding.js +18 -238
  221. package/dist/tasks/scheduler-invocation.js +52 -52
  222. package/dist/tasks/scheduler-lock.js +53 -0
  223. package/dist/tasks/scheduler-sync.js +363 -679
  224. package/dist/tasks/source/parse-task-source.js +160 -10
  225. package/dist/tasks/source/task-source-v3-frozen.js +3 -4
  226. package/dist/tasks/source/task-to-v4.js +2 -2
  227. package/dist/workflows/authoring/authoring.js +3 -12
  228. package/dist/workflows/compile.js +211 -0
  229. package/dist/workflows/concurrency-policy.js +13 -74
  230. package/dist/workflows/exec/child-invocation.js +3 -17
  231. package/dist/workflows/exec/child-workflow.js +32 -141
  232. package/dist/workflows/exec/dispatch-redaction.js +13 -53
  233. package/dist/workflows/exec/environment.js +98 -0
  234. package/dist/workflows/exec/exec-unit.js +33 -140
  235. package/dist/workflows/exec/frozen-judge.js +7 -59
  236. package/dist/workflows/exec/native-executor.js +82 -341
  237. package/dist/workflows/exec/param-secrets.js +29 -47
  238. package/dist/workflows/exec/run-workflow.js +154 -387
  239. package/dist/workflows/exec/scheduler.js +9 -36
  240. package/dist/workflows/exec/step-work.js +127 -430
  241. package/dist/workflows/exec/unit-dispatch.js +11 -63
  242. package/dist/workflows/exec/unit-writer.js +8 -52
  243. package/dist/workflows/exec/worktree.js +39 -273
  244. package/dist/workflows/freeze/child-output-references.js +4 -15
  245. package/dist/workflows/freeze/environment.js +99 -92
  246. package/dist/workflows/freeze/freeze.js +172 -0
  247. package/dist/workflows/freeze/step-values.js +19 -21
  248. package/dist/workflows/freeze/targets/child-workflow.js +23 -92
  249. package/dist/workflows/freeze/targets/command.js +10 -33
  250. package/dist/workflows/freeze/targets/script.js +5 -12
  251. package/dist/workflows/freeze/targets/shell.js +3 -6
  252. package/dist/workflows/freeze/targets/task.js +25 -80
  253. package/dist/workflows/freeze/task-bindings.js +20 -67
  254. package/dist/workflows/{source-ir/github-yaml.js → github-yaml.js} +88 -206
  255. package/dist/workflows/ir/params.js +6 -51
  256. package/dist/workflows/ir/plan-hash.js +2 -34
  257. package/dist/workflows/parser.js +140 -43
  258. package/dist/{commands/improve/consolidate/types.js → workflows/plan.js} +2 -1
  259. package/dist/workflows/renderer.js +36 -69
  260. package/dist/workflows/resource-limits.js +12 -120
  261. package/dist/workflows/runtime/agent-identity.js +8 -40
  262. package/dist/workflows/runtime/run-outputs.js +3 -6
  263. package/dist/workflows/runtime/run-plan.js +316 -0
  264. package/dist/workflows/runtime/runs.js +48 -200
  265. package/dist/workflows/runtime/workflow-asset-loader.js +24 -57
  266. package/dist/workflows/{source-ir/semantics.js → source-semantics.js} +16 -20
  267. package/dist/workflows/validate-summary.js +2 -7
  268. package/docs/integration/bundling-akm.md +49 -42
  269. package/docs/migration/README.md +1 -0
  270. package/docs/migration/release-notes/0.9.17.md +41 -0
  271. package/docs/migration/v0.9.1-to-v0.9.2.md +19 -7
  272. package/docs/reference/cli.md +182 -125
  273. package/docs/reference/configuration.md +49 -56
  274. package/docs/reference/data-and-telemetry.md +19 -20
  275. package/docs/reference/tasks.md +86 -38
  276. package/docs/reference/workflow-schema.md +14 -18
  277. package/docs/reference/workflows.md +6 -9
  278. package/package.json +1 -1
  279. package/schemas/akm-config.json +87 -406
  280. package/dist/commands/health/advisories.js +0 -150
  281. package/dist/commands/health/metrics.js +0 -329
  282. package/dist/commands/health/surfaces.js +0 -102
  283. package/dist/commands/improve/anti-collapse.js +0 -83
  284. package/dist/commands/improve/collapse-detector.js +0 -432
  285. package/dist/commands/improve/consolidate/eligibility.js +0 -48
  286. package/dist/commands/improve/consolidate/merge.js +0 -146
  287. package/dist/commands/improve/distill/promote-memory.js +0 -329
  288. package/dist/commands/improve/distill/quality-gate.js +0 -500
  289. package/dist/commands/improve/memory/memory-contradiction-detect.js +0 -291
  290. package/dist/commands/improve/proposal-envelope.js +0 -31
  291. package/dist/commands/improve/run-context.js +0 -123
  292. package/dist/commands/improve/shared.js +0 -21
  293. package/dist/commands/improve/source-identity.js +0 -28
  294. package/dist/commands/improve/triage.js +0 -96
  295. package/dist/commands/proposal/drain-policies.js +0 -151
  296. package/dist/commands/sources/update-transaction.js +0 -220
  297. package/dist/core/action-contributors.js +0 -28
  298. package/dist/core/config/config-version-shim.js +0 -101
  299. package/dist/core/config/retired-experimental-keys-shim.js +0 -62
  300. package/dist/core/fs-txn.js +0 -405
  301. package/dist/core/lexical-score.js +0 -25
  302. package/dist/core/maintenance-barrier.js +0 -167
  303. package/dist/execution/executable-identity.js +0 -105
  304. package/dist/execution/guarded-source.js +0 -427
  305. package/dist/indexer/graph/graph-boost.js +0 -427
  306. package/dist/indexer/graph/graph-dedup.js +0 -95
  307. package/dist/indexer/search/name-match.js +0 -35
  308. package/dist/indexer/search/ranking-contributors.js +0 -515
  309. package/dist/indexer/walk/project-context.js +0 -192
  310. package/dist/integrations/agent/execution-cascade.js +0 -566
  311. package/dist/integrations/agent/execution-definitions.js +0 -202
  312. package/dist/integrations/agent/execution-lowering.js +0 -841
  313. package/dist/integrations/agent/execution-preparation.js +0 -98
  314. package/dist/integrations/agent/inline-execution.js +0 -74
  315. package/dist/registry/create-provider-registry.js +0 -29
  316. package/dist/registry/pinned-request-helper.js +0 -247
  317. package/dist/registry/pinned-transport.js +0 -717
  318. package/dist/sources/providers/index.js +0 -14
  319. package/dist/storage/engines/sqlite-migrations.js +0 -271
  320. package/dist/storage/repositories/canaries-repository.js +0 -107
  321. package/dist/storage/repositories/embedding-salvage-repository.js +0 -184
  322. package/dist/storage/repositories/registry-cache.js +0 -113
  323. package/dist/tasks/scheduler-sync-preview.js +0 -52
  324. package/dist/workflows/freeze/resolve-steps.js +0 -86
  325. package/dist/workflows/freeze/source-freeze.js +0 -64
  326. package/dist/workflows/ir/compile.js +0 -321
  327. package/dist/workflows/ir/environment-v4.js +0 -330
  328. package/dist/workflows/ir/freeze-v4.js +0 -153
  329. package/dist/workflows/ir/schema-v4.js +0 -745
  330. package/dist/workflows/ir/schema.js +0 -354
  331. package/dist/workflows/program/schema.js +0 -78
  332. package/dist/workflows/runtime/checkin.js +0 -57
  333. package/dist/workflows/runtime/plan-classifier.js +0 -196
  334. package/dist/workflows/runtime/unit-checkin.js +0 -45
  335. package/dist/workflows/runtime/unit-phases.js +0 -20
  336. package/dist/workflows/schema.js +0 -4
  337. package/dist/workflows/source-ir/compile.js +0 -200
  338. package/dist/workflows/source-ir/program.js +0 -50
  339. package/dist/workflows/source-ir/result.js +0 -26
  340. package/dist/workflows/source-ir/schema.js +0 -786
  341. package/dist/workflows/source-ir/triggers.js +0 -79
  342. package/dist/workflows/source-ir/uses.js +0 -40
  343. 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
- }