@the-open-engine/zeroshot 6.38.1 → 6.39.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (383) hide show
  1. package/README.md +6 -0
  2. package/cli/event-copy.js +8 -7
  3. package/cli/event-copy.ts +12 -0
  4. package/cli/index.js +67 -48
  5. package/cli/json-export.js +61 -64
  6. package/cli/json-export.ts +112 -0
  7. package/cli/message-formatter-utils.js +68 -56
  8. package/cli/message-formatter-utils.ts +121 -0
  9. package/cli/message-formatters-normal.js +124 -259
  10. package/cli/message-formatters-normal.ts +250 -0
  11. package/cli/message-formatters-watch.js +81 -84
  12. package/cli/message-formatters-watch.ts +189 -0
  13. package/lib/cluster/generated/protocol-schema.cjs +1 -1
  14. package/lib/cluster/generated/protocol-schema.mjs +1 -1
  15. package/lib/cluster/generated/protocol.d.cts +8 -0
  16. package/lib/cluster/generated/protocol.d.mts +8 -0
  17. package/lib/cluster/generated/protocol.d.ts +8 -0
  18. package/lib/clusters-registry.d.ts +23 -0
  19. package/lib/clusters-registry.js +17 -29
  20. package/lib/completion.d.ts +12 -0
  21. package/lib/completion.js +84 -94
  22. package/lib/compose-utils.d.ts +32 -0
  23. package/lib/compose-utils.js +57 -72
  24. package/lib/detached-startup.d.ts +84 -0
  25. package/lib/detached-startup.js +232 -302
  26. package/lib/docker-config.d.ts +43 -0
  27. package/lib/docker-config.js +150 -325
  28. package/lib/docker-env-auth.d.ts +17 -0
  29. package/lib/docker-env-auth.js +75 -0
  30. package/lib/git-remote-utils.d.ts +48 -0
  31. package/lib/git-remote-utils.js +147 -213
  32. package/lib/id-detector.d.ts +15 -0
  33. package/lib/id-detector.js +37 -41
  34. package/lib/path-check.d.ts +30 -0
  35. package/lib/path-check.js +42 -45
  36. package/lib/process-liveness.d.ts +16 -0
  37. package/lib/process-liveness.js +19 -12
  38. package/lib/provider-credential-path.d.ts +16 -0
  39. package/lib/provider-credential-path.js +31 -29
  40. package/lib/provider-defaults.d.ts +30 -0
  41. package/lib/provider-defaults.js +47 -42
  42. package/lib/provider-detection.d.ts +11 -0
  43. package/lib/provider-detection.js +91 -54
  44. package/lib/provider-names.d.ts +38 -0
  45. package/lib/provider-names.js +56 -64
  46. package/lib/repo-settings.d.ts +28 -0
  47. package/lib/repo-settings.js +83 -59
  48. package/lib/run-mode.d.ts +21 -0
  49. package/lib/run-mode.js +21 -20
  50. package/lib/run-plan.d.ts +28 -0
  51. package/lib/run-plan.js +17 -16
  52. package/lib/settings/claude-auth.d.ts +35 -0
  53. package/lib/settings/claude-auth.js +30 -47
  54. package/lib/settings-defaults.d.ts +20 -0
  55. package/lib/settings-defaults.js +149 -0
  56. package/lib/settings-error.d.ts +7 -0
  57. package/lib/settings-error.js +8 -0
  58. package/lib/settings-issue-providers.d.ts +10 -0
  59. package/lib/settings-issue-providers.js +12 -0
  60. package/lib/settings-models.d.ts +22 -0
  61. package/lib/settings-models.js +93 -0
  62. package/lib/settings-storage.d.ts +23 -0
  63. package/lib/settings-storage.js +205 -0
  64. package/lib/settings-validation.d.ts +7 -0
  65. package/lib/settings-validation.js +182 -0
  66. package/lib/settings.d.ts +29 -0
  67. package/lib/settings.js +41 -736
  68. package/lib/setup-apply-types.d.ts +66 -0
  69. package/lib/setup-apply-types.js +2 -0
  70. package/lib/setup-apply.d.ts +39 -0
  71. package/lib/setup-apply.js +267 -264
  72. package/lib/setup-journal.d.ts +41 -0
  73. package/lib/setup-journal.js +119 -76
  74. package/lib/setup-plan-types.d.ts +102 -0
  75. package/lib/setup-plan-types.js +2 -0
  76. package/lib/setup-plan.d.ts +30 -0
  77. package/lib/setup-plan.js +300 -324
  78. package/lib/setup-undo.d.ts +44 -0
  79. package/lib/setup-undo.js +61 -74
  80. package/lib/start-cluster-config.d.ts +26 -0
  81. package/lib/start-cluster-config.js +56 -0
  82. package/lib/start-cluster-environment.d.ts +41 -0
  83. package/lib/start-cluster-environment.js +134 -0
  84. package/lib/start-cluster-run-options.d.ts +54 -0
  85. package/lib/start-cluster-run-options.js +148 -0
  86. package/lib/start-cluster.d.ts +64 -0
  87. package/lib/start-cluster.js +98 -454
  88. package/lib/stream-json-parser.d.ts +17 -0
  89. package/lib/stream-json-parser.js +51 -52
  90. package/npm-shrinkwrap.json +6 -8
  91. package/package.json +14 -8
  92. package/scripts/postinstall.js +27 -0
  93. package/scripts/rust-distribution.js +36 -45
  94. package/src/agent/agent-command-proofs-context.js +35 -45
  95. package/src/agent/agent-command-proofs-context.ts +87 -0
  96. package/src/agent/agent-config-settings.js +19 -0
  97. package/src/agent/agent-config-settings.ts +41 -0
  98. package/src/agent/agent-config.js +122 -231
  99. package/src/agent/agent-config.ts +285 -0
  100. package/src/agent/agent-context-builder.js +38 -273
  101. package/src/agent/agent-context-builder.ts +51 -0
  102. package/src/agent/agent-context-environment-sections.js +105 -0
  103. package/src/agent/agent-context-environment-sections.ts +134 -0
  104. package/src/agent/agent-context-packs.js +165 -0
  105. package/src/agent/agent-context-packs.ts +296 -0
  106. package/src/agent/agent-context-prompt-sections.js +100 -0
  107. package/src/agent/agent-context-prompt-sections.ts +148 -0
  108. package/src/agent/agent-context-sections.js +25 -334
  109. package/src/agent/agent-context-sections.ts +36 -0
  110. package/src/agent/agent-context-sources.js +96 -149
  111. package/src/agent/agent-context-sources.ts +253 -0
  112. package/src/agent/agent-context-types.js +2 -0
  113. package/src/agent/agent-context-types.ts +132 -0
  114. package/src/agent/agent-context-validation-sections.js +73 -0
  115. package/src/agent/agent-context-validation-sections.ts +129 -0
  116. package/src/agent/agent-input-injector.js +99 -118
  117. package/src/agent/agent-input-injector.ts +195 -0
  118. package/src/agent/agent-liveness-poll.js +74 -78
  119. package/src/agent/agent-liveness-poll.ts +163 -0
  120. package/src/agent/agent-quality-gate-schema.js +77 -86
  121. package/src/agent/agent-quality-gate-schema.ts +135 -0
  122. package/src/agent/agent-quality-gates-context.js +44 -50
  123. package/src/agent/agent-quality-gates-context.ts +91 -0
  124. package/src/agent/agent-stuck-detector.js +171 -239
  125. package/src/agent/agent-stuck-detector.ts +288 -0
  126. package/src/agent/agent-trigger-evaluator.js +29 -46
  127. package/src/agent/agent-trigger-evaluator.ts +98 -0
  128. package/src/agent/context-metrics.js +110 -141
  129. package/src/agent/context-metrics.ts +261 -0
  130. package/src/agent/context-pack-builder.js +72 -358
  131. package/src/agent/context-pack-builder.ts +105 -0
  132. package/src/agent/context-pack-core.js +70 -0
  133. package/src/agent/context-pack-core.ts +96 -0
  134. package/src/agent/context-pack-selection.js +119 -0
  135. package/src/agent/context-pack-selection.ts +187 -0
  136. package/src/agent/context-pack-truncation.js +139 -0
  137. package/src/agent/context-pack-truncation.ts +208 -0
  138. package/src/agent/context-pack-types.js +2 -0
  139. package/src/agent/context-pack-types.ts +98 -0
  140. package/src/agent/context-replay-policy.js +30 -39
  141. package/src/agent/context-replay-policy.ts +71 -0
  142. package/src/agent/critical-agent-policy.js +6 -10
  143. package/src/agent/critical-agent-policy.ts +20 -0
  144. package/src/agent/guidance-queue.js +74 -87
  145. package/src/agent/guidance-queue.ts +166 -0
  146. package/src/agent/output-extraction-error-detail.js +45 -0
  147. package/src/agent/output-extraction-error-detail.ts +49 -0
  148. package/src/agent/output-extraction-failures.js +125 -0
  149. package/src/agent/output-extraction-failures.ts +149 -0
  150. package/src/agent/output-extraction-json.js +234 -0
  151. package/src/agent/output-extraction-json.ts +235 -0
  152. package/src/agent/output-extraction-pi.js +124 -0
  153. package/src/agent/output-extraction-pi.ts +137 -0
  154. package/src/agent/output-extraction-types.js +2 -0
  155. package/src/agent/output-extraction-types.ts +49 -0
  156. package/src/agent/output-extraction.js +17 -617
  157. package/src/agent/output-extraction.ts +30 -0
  158. package/src/agent/output-reformatter-errors.js +83 -0
  159. package/src/agent/output-reformatter-errors.ts +106 -0
  160. package/src/agent/output-reformatter-types.js +2 -0
  161. package/src/agent/output-reformatter-types.ts +86 -0
  162. package/src/agent/output-reformatter.js +140 -185
  163. package/src/agent/output-reformatter.ts +238 -0
  164. package/src/agent/pi-terminal-lifecycle-types.js +2 -0
  165. package/src/agent/pi-terminal-lifecycle-types.ts +41 -0
  166. package/src/agent/pi-terminal-lifecycle.js +186 -206
  167. package/src/agent/pi-terminal-lifecycle.ts +297 -0
  168. package/src/agent/provider-control-plane.js +22 -21
  169. package/src/agent/provider-control-plane.ts +52 -0
  170. package/src/agent/provider-terminal-failure-types.js +2 -0
  171. package/src/agent/provider-terminal-failure-types.ts +60 -0
  172. package/src/agent/provider-terminal-failure.js +194 -191
  173. package/src/agent/provider-terminal-failure.ts +262 -0
  174. package/src/agent/rate-limit-backoff.js +31 -74
  175. package/src/agent/rate-limit-backoff.ts +71 -0
  176. package/src/agent/schema-utils.js +85 -125
  177. package/src/agent/schema-utils.ts +148 -0
  178. package/src/agent/structured-output-error.js +34 -33
  179. package/src/agent/structured-output-error.ts +105 -0
  180. package/src/agent/validation-platform.js +27 -27
  181. package/src/agent/validation-platform.ts +49 -0
  182. package/src/agents/git-pusher-template.js +17 -34
  183. package/src/attach/attach-client.js +232 -405
  184. package/src/attach/attach-client.ts +300 -0
  185. package/src/attach/attach-server-cleanup.js +43 -0
  186. package/src/attach/attach-server-cleanup.ts +39 -0
  187. package/src/attach/attach-server-clients.js +117 -0
  188. package/src/attach/attach-server-clients.ts +122 -0
  189. package/src/attach/attach-server-events.js +38 -0
  190. package/src/attach/attach-server-events.ts +36 -0
  191. package/src/attach/attach-server-pty.js +45 -0
  192. package/src/attach/attach-server-pty.ts +64 -0
  193. package/src/attach/attach-server-runtime.js +73 -0
  194. package/src/attach/attach-server-runtime.ts +62 -0
  195. package/src/attach/attach-server-socket.js +28 -0
  196. package/src/attach/attach-server-socket.ts +23 -0
  197. package/src/attach/attach-server-types.js +2 -0
  198. package/src/attach/attach-server-types.ts +82 -0
  199. package/src/attach/attach-server.js +106 -523
  200. package/src/attach/attach-server.ts +158 -0
  201. package/src/attach/index.js +18 -35
  202. package/src/attach/index.ts +18 -0
  203. package/src/attach/protocol.js +95 -184
  204. package/src/attach/protocol.ts +181 -0
  205. package/src/attach/ring-buffer.js +76 -102
  206. package/src/attach/ring-buffer.ts +109 -0
  207. package/src/attach/send-input.js +64 -75
  208. package/src/attach/send-input.ts +94 -0
  209. package/src/attach/socket-discovery.js +164 -218
  210. package/src/attach/socket-discovery.ts +230 -0
  211. package/src/attach/socket-paths.js +42 -61
  212. package/src/attach/socket-paths.ts +81 -0
  213. package/src/claude-credentials.js +51 -54
  214. package/src/claude-credentials.ts +89 -0
  215. package/src/cluster/generated/protocol-schema.ts +1 -1
  216. package/src/cluster/generated/protocol.ts +2 -1
  217. package/src/command-proofs.js +110 -141
  218. package/src/command-proofs.ts +216 -0
  219. package/src/config-router.js +81 -73
  220. package/src/config-router.ts +131 -0
  221. package/src/copy-containment.js +191 -0
  222. package/src/copy-containment.ts +259 -0
  223. package/src/copy-worker.js +53 -30
  224. package/src/copy-worker.ts +88 -0
  225. package/src/darwin-keychain-boundary.js +80 -111
  226. package/src/darwin-keychain-boundary.ts +148 -0
  227. package/src/guidance-topics.js +4 -5
  228. package/src/guidance-topics.ts +10 -0
  229. package/src/input-helpers.js +33 -54
  230. package/src/input-helpers.ts +58 -0
  231. package/src/isolation-manager.js +59 -20
  232. package/src/ledger-sequence.js +45 -48
  233. package/src/ledger-sequence.ts +63 -0
  234. package/src/legacy-lib/clusters-registry.ts +40 -0
  235. package/src/legacy-lib/completion.ts +148 -0
  236. package/src/legacy-lib/compose-utils.ts +102 -0
  237. package/src/legacy-lib/detached-startup.ts +451 -0
  238. package/src/legacy-lib/docker-config.ts +282 -0
  239. package/src/legacy-lib/docker-env-auth.ts +116 -0
  240. package/src/legacy-lib/git-remote-utils.ts +244 -0
  241. package/src/legacy-lib/id-detector.ts +57 -0
  242. package/src/legacy-lib/js-yaml.d.ts +3 -0
  243. package/src/legacy-lib/omelette.d.ts +15 -0
  244. package/src/legacy-lib/path-check.ts +89 -0
  245. package/src/legacy-lib/process-liveness.ts +36 -0
  246. package/src/legacy-lib/provider-credential-path.ts +57 -0
  247. package/src/legacy-lib/provider-defaults.ts +114 -0
  248. package/src/legacy-lib/provider-detection.ts +67 -0
  249. package/src/legacy-lib/provider-names.ts +126 -0
  250. package/src/legacy-lib/repo-settings.ts +88 -0
  251. package/src/legacy-lib/run-mode.ts +58 -0
  252. package/src/legacy-lib/run-plan.ts +49 -0
  253. package/src/legacy-lib/settings/claude-auth.ts +80 -0
  254. package/src/legacy-lib/settings-defaults.ts +212 -0
  255. package/src/legacy-lib/settings-error.ts +8 -0
  256. package/src/legacy-lib/settings-issue-providers.ts +18 -0
  257. package/src/legacy-lib/settings-models.ts +124 -0
  258. package/src/legacy-lib/settings-storage.ts +277 -0
  259. package/src/legacy-lib/settings-validation.ts +220 -0
  260. package/src/legacy-lib/settings.ts +87 -0
  261. package/src/legacy-lib/setup-apply-types.ts +70 -0
  262. package/src/legacy-lib/setup-apply.ts +456 -0
  263. package/src/legacy-lib/setup-journal.ts +185 -0
  264. package/src/legacy-lib/setup-plan-types.ts +96 -0
  265. package/src/legacy-lib/setup-plan.ts +500 -0
  266. package/src/legacy-lib/setup-undo.ts +142 -0
  267. package/src/legacy-lib/start-cluster-config.ts +124 -0
  268. package/src/legacy-lib/start-cluster-environment.ts +166 -0
  269. package/src/legacy-lib/start-cluster-run-options.ts +281 -0
  270. package/src/legacy-lib/start-cluster.ts +237 -0
  271. package/src/legacy-lib/stream-json-parser.ts +88 -0
  272. package/src/message-buffer.js +55 -71
  273. package/src/message-buffer.ts +107 -0
  274. package/src/message-bus-bridge.js +92 -133
  275. package/src/message-bus-bridge.ts +149 -0
  276. package/src/name-generator-shared.js +220 -0
  277. package/src/name-generator-shared.ts +231 -0
  278. package/src/name-generator.js +8 -217
  279. package/src/name-generator.ts +27 -0
  280. package/src/omp-blob-root.js +83 -64
  281. package/src/omp-blob-root.ts +116 -0
  282. package/src/omp-config-overlay.js +65 -38
  283. package/src/omp-config-overlay.ts +110 -0
  284. package/src/omp-execution-fingerprint.js +38 -43
  285. package/src/omp-execution-fingerprint.ts +92 -0
  286. package/src/omp-session-limits.js +10 -15
  287. package/src/omp-session-limits.ts +53 -0
  288. package/src/omp-session-partition.js +2 -2
  289. package/src/omp-session-verifier.js +1 -1
  290. package/src/orchestrator.js +32 -7
  291. package/src/pr-body-template.js +71 -0
  292. package/src/providers/anthropic/index.js +3 -1
  293. package/src/providers/anthropic/index.ts +13 -0
  294. package/src/providers/capabilities.js +19 -27
  295. package/src/providers/capabilities.ts +44 -0
  296. package/src/providers/google/index.js +3 -1
  297. package/src/providers/google/index.ts +13 -0
  298. package/src/providers/openai/index.js +3 -1
  299. package/src/providers/openai/index.ts +13 -0
  300. package/src/providers/opencode/index.js +3 -1
  301. package/src/providers/opencode/index.ts +13 -0
  302. package/src/quality-gates.js +67 -127
  303. package/src/quality-gates.ts +149 -0
  304. package/src/repo-settings-access.js +40 -0
  305. package/src/repo-settings-access.ts +64 -0
  306. package/src/schemas/sub-cluster.js +127 -183
  307. package/src/schemas/sub-cluster.ts +238 -0
  308. package/src/state-snapshot-normalization.js +224 -0
  309. package/src/state-snapshot-normalization.ts +222 -0
  310. package/src/state-snapshot.js +192 -359
  311. package/src/state-snapshot.ts +291 -0
  312. package/src/state-snapshotter.js +118 -130
  313. package/src/state-snapshotter.ts +167 -0
  314. package/src/sub-cluster-wrapper.js +4 -13
  315. package/src/task-run-model-args.js +87 -124
  316. package/src/task-run-model-args.ts +204 -0
  317. package/src/task-runner.js +5 -25
  318. package/src/task-runner.ts +28 -0
  319. package/src/task-startup-error.js +73 -58
  320. package/src/task-startup-error.ts +126 -0
  321. package/src/template-validation/consensus-gate-contracts.js +2 -0
  322. package/src/template-validation/consensus-gate-contracts.ts +70 -0
  323. package/src/template-validation/consensus-gate-scenarios.js +76 -0
  324. package/src/template-validation/consensus-gate-scenarios.ts +130 -0
  325. package/src/template-validation/consensus-gate-stage.js +34 -0
  326. package/src/template-validation/consensus-gate-stage.ts +56 -0
  327. package/src/template-validation/random-topology-contracts.js +2 -0
  328. package/src/template-validation/random-topology-contracts.ts +54 -0
  329. package/src/template-validation/random-topology-dispatch.js +25 -0
  330. package/src/template-validation/random-topology-dispatch.ts +33 -0
  331. package/src/template-validation/random-topology-message-loop.js +53 -0
  332. package/src/template-validation/random-topology-message-loop.ts +73 -0
  333. package/src/template-validation/random-topology-operations.js +79 -0
  334. package/src/template-validation/random-topology-operations.ts +101 -0
  335. package/src/template-validation/random-topology-runtime.js +25 -0
  336. package/src/template-validation/random-topology-runtime.ts +43 -0
  337. package/src/template-validation/random-topology-scenario.js +52 -0
  338. package/src/template-validation/random-topology-scenario.ts +57 -0
  339. package/src/template-validation/random-topology-schema.js +159 -0
  340. package/src/template-validation/random-topology-schema.ts +190 -0
  341. package/src/template-validation/random-topology-state.js +28 -0
  342. package/src/template-validation/random-topology-state.ts +30 -0
  343. package/src/template-validation/random-topology-trigger-evaluation.js +45 -0
  344. package/src/template-validation/random-topology-trigger-evaluation.ts +65 -0
  345. package/src/template-validation/random-topology-trigger.js +75 -0
  346. package/src/template-validation/random-topology-trigger.ts +88 -0
  347. package/src/template-validation/report-formatter.js +40 -46
  348. package/src/template-validation/report-formatter.ts +101 -0
  349. package/src/template-validation/simulate-consensus-gates.js +111 -302
  350. package/src/template-validation/simulate-consensus-gates.ts +196 -0
  351. package/src/template-validation/simulate-random-topology.js +26 -519
  352. package/src/template-validation/simulate-random-topology.ts +57 -0
  353. package/src/template-validation/simulate-two-stage-validation.js +41 -265
  354. package/src/template-validation/simulate-two-stage-validation.ts +55 -0
  355. package/src/template-validation/simulation-agent-runtime.js +25 -0
  356. package/src/template-validation/simulation-agent-runtime.ts +40 -0
  357. package/src/template-validation/simulation-agent.js +29 -0
  358. package/src/template-validation/simulation-agent.ts +73 -0
  359. package/src/template-validation/simulation-runtime.js +34 -0
  360. package/src/template-validation/simulation-runtime.ts +72 -0
  361. package/src/template-validation/two-stage-contracts.js +2 -0
  362. package/src/template-validation/two-stage-contracts.ts +41 -0
  363. package/src/template-validation/two-stage-inputs.js +21 -0
  364. package/src/template-validation/two-stage-inputs.ts +29 -0
  365. package/src/template-validation/two-stage-results.js +30 -0
  366. package/src/template-validation/two-stage-results.ts +40 -0
  367. package/src/template-validation/two-stage-scenario.js +86 -0
  368. package/src/template-validation/two-stage-scenario.ts +120 -0
  369. package/src/worktree-claude-config.js +182 -220
  370. package/src/worktree-claude-config.ts +272 -0
  371. package/src/worktree-tooling-env.js +103 -125
  372. package/src/worktree-tooling-env.ts +142 -0
  373. package/task-lib/completion.js +2 -3
  374. package/task-lib/completion.ts +9 -0
  375. package/task-lib/config.js +1 -4
  376. package/task-lib/config.ts +11 -0
  377. package/task-lib/name-generator.js +4 -226
  378. package/task-lib/name-generator.ts +11 -0
  379. package/task-lib/omp-session-cleanup.js +1 -1
  380. package/task-lib/omp-storage-root.js +8 -12
  381. package/task-lib/omp-storage-root.ts +62 -0
  382. package/task-lib/process-termination.js +143 -166
  383. package/task-lib/process-termination.ts +268 -0
@@ -0,0 +1,92 @@
1
+ // The `executionFingerprint` recorded with every resumable OMP session (issue #866).
2
+ //
3
+ // A session transcript is only safely continuable under the same execution contract that produced
4
+ // it. This digest binds that contract: the pinned OMP release, the Zeroshot config overlay's
5
+ // content, the requested Zeroshot selectors (`--model`, `--thinking`, `--approval-mode`), and the
6
+ // concrete provider/model/thinking level OMP actually reported for the turn. Any of those drifting
7
+ // between the recording turn and a resume attempt — a Zeroshot upgrade that retunes the overlay, a
8
+ // changed level mapping, an alias resolving to a different concrete model, a different thinking
9
+ // level — makes the fingerprints differ, and the continuation is refused before the prompt.
10
+ import { createHash } from 'crypto';
11
+
12
+ interface ConfigOverlayFacade {
13
+ readonly OMP_CONFIG_OVERLAY_DIGEST: string;
14
+ }
15
+
16
+ interface CommandSpec {
17
+ readonly args?: unknown;
18
+ }
19
+
20
+ interface OmpSessionEvidence {
21
+ readonly selectedProvider?: unknown;
22
+ readonly selectedModel?: unknown;
23
+ readonly thinkingLevel?: unknown;
24
+ }
25
+
26
+ interface FingerprintParams {
27
+ readonly expectedVersion: unknown;
28
+ readonly commandSpec: CommandSpec | null | undefined;
29
+ readonly evidence: OmpSessionEvidence | null | undefined;
30
+ readonly configOverlayDigest?: unknown;
31
+ }
32
+
33
+ interface RequestedExecutionSelectors {
34
+ readonly modelSelector: string;
35
+ readonly thinkingSelector: string;
36
+ readonly approvalMode: string;
37
+ }
38
+
39
+ // The generated CommonJS module resolves the maintained overlay at the matching runtime path.
40
+ // eslint-disable-next-line @typescript-eslint/no-unsafe-assignment
41
+ const { OMP_CONFIG_OVERLAY_DIGEST }: ConfigOverlayFacade = require('./omp-config-overlay');
42
+
43
+ /** Value of `--flag <value>` in an argv array, or '' when the flag is absent. */
44
+ function flagValue(args: unknown, flag: string): string {
45
+ if (!Array.isArray(args)) return '';
46
+ const index = args.indexOf(flag);
47
+ if (index < 0 || index + 1 >= args.length) return '';
48
+ const value: unknown = args[index + 1];
49
+ return typeof value === 'string' ? value : '';
50
+ }
51
+
52
+ /** The Zeroshot-requested half of the contract, readable from the command spec alone. */
53
+ function requestedExecutionSelectors(
54
+ commandSpec: CommandSpec | null | undefined
55
+ ): RequestedExecutionSelectors {
56
+ const args = commandSpec?.args;
57
+ return {
58
+ modelSelector: flagValue(args, '--model'),
59
+ thinkingSelector: flagValue(args, '--thinking'),
60
+ approvalMode: flagValue(args, '--approval-mode'),
61
+ };
62
+ }
63
+
64
+ /** Compute the deterministic digest for the requested and observed OMP execution contract. */
65
+ function computeOmpExecutionFingerprint({
66
+ expectedVersion,
67
+ commandSpec,
68
+ evidence,
69
+ configOverlayDigest = OMP_CONFIG_OVERLAY_DIGEST,
70
+ }: FingerprintParams): string {
71
+ const fields: Record<string, string> = {
72
+ ompSupportedVersion: String(expectedVersion ?? ''),
73
+ configOverlayDigest: String(configOverlayDigest ?? ''),
74
+ ...requestedExecutionSelectors(commandSpec),
75
+ observedProvider: String(evidence?.selectedProvider ?? ''),
76
+ observedModel: String(evidence?.selectedModel ?? ''),
77
+ observedThinkingLevel: String(evidence?.thinkingLevel ?? ''),
78
+ };
79
+ const stable: Record<string, string> = {};
80
+ // Fingerprints preserve ECMAScript's locale-independent UTF-16 code-unit ordering.
81
+ // eslint-disable-next-line sonarjs/no-alphabetical-sort
82
+ for (const key of Object.keys(fields).sort()) {
83
+ const value = fields[key];
84
+ if (value !== undefined) stable[key] = value;
85
+ }
86
+ return `sha256:${createHash('sha256').update(JSON.stringify(stable), 'utf8').digest('hex')}`;
87
+ }
88
+
89
+ export = {
90
+ computeOmpExecutionFingerprint,
91
+ requestedExecutionSelectors,
92
+ };
@@ -1,19 +1,15 @@
1
- // Non-configurable bounds for OMP session partition verification (src/omp-session-verifier.js).
2
- // Every value is pinned exactly as specified by issue #866; do not derive these from settings or
3
- // environment — a configurable ceiling here would let a compromised/misbehaving OMP process (or a
4
- // hostile resumed partition) negotiate its own verification budget.
1
+ "use strict";
5
2
  const OMP_SESSION_LIMITS = Object.freeze({
6
- maxSessionBytes: 268435456,
7
- maxSessionRecords: 1000000,
8
- maxArtifactEntries: 4096,
9
- maxArtifactDepth: 16,
10
- maxRelativePathBytes: 4096,
11
- maxArtifactFileBytes: 268435456,
12
- maxArtifactAggregateBytes: 536870912,
13
- maxBlobReferences: 4096,
14
- maxReferencedBlobBytes: 67108864,
3
+ maxSessionBytes: 268435456,
4
+ maxSessionRecords: 1000000,
5
+ maxArtifactEntries: 4096,
6
+ maxArtifactDepth: 16,
7
+ maxRelativePathBytes: 4096,
8
+ maxArtifactFileBytes: 268435456,
9
+ maxArtifactAggregateBytes: 536870912,
10
+ maxBlobReferences: 4096,
11
+ maxReferencedBlobBytes: 67108864,
15
12
  });
16
-
17
13
  /**
18
14
  * The largest single JSONL record the verifier will buffer, DERIVED from the constants above
19
15
  * rather than chosen — it is `maxReferencedBlobBytes`, and it is not a new knob (there is nothing
@@ -37,5 +33,4 @@ const OMP_SESSION_LIMITS = Object.freeze({
37
33
  * verifier accumulates session, artifact, or blob bytes.
38
34
  */
39
35
  const MAX_SESSION_RECORD_BYTES = OMP_SESSION_LIMITS.maxReferencedBlobBytes;
40
-
41
36
  module.exports = { OMP_SESSION_LIMITS, MAX_SESSION_RECORD_BYTES };
@@ -0,0 +1,53 @@
1
+ // Non-configurable bounds for OMP session partition verification (src/omp-session-verifier.js).
2
+ // Every value is pinned exactly as specified by issue #866; do not derive these from settings or
3
+ // environment — a configurable ceiling here would let a compromised/misbehaving OMP process (or a
4
+ // hostile resumed partition) negotiate its own verification budget.
5
+ interface OmpSessionLimits {
6
+ readonly maxSessionBytes: number;
7
+ readonly maxSessionRecords: number;
8
+ readonly maxArtifactEntries: number;
9
+ readonly maxArtifactDepth: number;
10
+ readonly maxRelativePathBytes: number;
11
+ readonly maxArtifactFileBytes: number;
12
+ readonly maxArtifactAggregateBytes: number;
13
+ readonly maxBlobReferences: number;
14
+ readonly maxReferencedBlobBytes: number;
15
+ }
16
+
17
+ const OMP_SESSION_LIMITS: Readonly<OmpSessionLimits> = Object.freeze({
18
+ maxSessionBytes: 268435456,
19
+ maxSessionRecords: 1000000,
20
+ maxArtifactEntries: 4096,
21
+ maxArtifactDepth: 16,
22
+ maxRelativePathBytes: 4096,
23
+ maxArtifactFileBytes: 268435456,
24
+ maxArtifactAggregateBytes: 536870912,
25
+ maxBlobReferences: 4096,
26
+ maxReferencedBlobBytes: 67108864,
27
+ });
28
+
29
+ /**
30
+ * The largest single JSONL record the verifier will buffer, DERIVED from the constants above
31
+ * rather than chosen — it is `maxReferencedBlobBytes`, and it is not a new knob (there is nothing
32
+ * to configure and no caller may override it).
33
+ *
34
+ * Why a per-record bound is needed at all: `maxSessionBytes` bounds the *file*, not a line within
35
+ * it. A hostile 256 MiB session with no newline in it is one record, and buffering it would cost
36
+ * the raw bytes, a concatenated copy, a UTF-16 string for JSON.parse, and the parsed value — a
37
+ * multi-hundred-megabyte spike driven entirely by the attacker's choice of where to put newlines.
38
+ *
39
+ * Why this value: `maxReferencedBlobBytes` is the issue's own answer to "how large may one
40
+ * addressable unit of session content be". OMP externalizes anything bigger than a message to the
41
+ * shared CAS store (blob-store.ts) and leaves only a 76-byte `blob:sha256:<hex>` reference in the
42
+ * record, so a legitimate record is orders of magnitude smaller than this; the bound exists to cap
43
+ * the pathological case, not to constrain real transcripts.
44
+ *
45
+ * Remaining allocation, exactly: verification buffers at most MAX_SESSION_RECORD_BYTES of raw
46
+ * record bytes, and `JSON.parse` necessarily materializes that record as one UTF-16 string plus its
47
+ * parsed value. Peak per-record cost is therefore O(MAX_SESSION_RECORD_BYTES) and independent of
48
+ * `maxSessionBytes`, the record count, and the file's newline placement. Nothing else in the
49
+ * verifier accumulates session, artifact, or blob bytes.
50
+ */
51
+ const MAX_SESSION_RECORD_BYTES = OMP_SESSION_LIMITS.maxReferencedBlobBytes;
52
+
53
+ export = { OMP_SESSION_LIMITS, MAX_SESSION_RECORD_BYTES };
@@ -5,9 +5,9 @@ const { isInsideOmpBlobsDir } = require('./omp-blob-root');
5
5
 
6
6
  // Every OMP session partition lives under <storageRoot>/omp-sessions/<uuid>/. storageRoot is the
7
7
  // owning cluster's storageDir for cluster-agent tasks or the standalone TASKS_DIR otherwise (see
8
- // task-lib/omp-storage-root.js) — never derived from prompt text or cwd. The shared OMP CAS blob
8
+ // task-lib/omp-storage-root.ts) — never derived from prompt text or cwd. The shared OMP CAS blob
9
9
  // store is *not* under here at all (it is machine-wide, at pi-utils::getBlobsDir(); see
10
- // src/omp-blob-root.js), which is what makes per-task partition deletion safe.
10
+ // src/omp-blob-root.ts), which is what makes per-task partition deletion safe.
11
11
  const OMP_SESSIONS_SUBDIR = 'omp-sessions';
12
12
  const PARTITION_ID_PATTERN =
13
13
  /^[0-9a-f]{8}-[0-9a-f]{4}-[1-5][0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$/u;
@@ -10,7 +10,7 @@
10
10
  // CAS blobs are NOT part of the partition. OMP externalizes large payloads to a *shared*,
11
11
  // machine-wide content-addressed store (`blob-store.ts`, rooted at `pi-utils::getBlobsDir()` —
12
12
  // `~/.omp/agent/blobs` modulo OMP's config-root/profile/XDG semantics, mirrored in
13
- // src/omp-blob-root.js) and leaves a *nested* `blob:sha256:<64-lower-hex>` reference string inside
13
+ // src/omp-blob-root.ts) and leaves a *nested* `blob:sha256:<64-lower-hex>` reference string inside
14
14
  // the session JSONL records. So verification parses the JSONL, collects canonical nested refs, and
15
15
  // checks the referenced blobs at that real shared root. Nothing here ever writes to or deletes
16
16
  // from it (see src/omp-session-partition.js, which refuses any path resolving inside it).
@@ -262,6 +262,7 @@ function buildPrOptions(options, requiredQualityGates) {
262
262
  prBase: options.prBase || null,
263
263
  mergeQueue: options.mergeQueue || false,
264
264
  closeIssue: options.closeIssue || null,
265
+ prBody: typeof options.prBody === 'string' ? options.prBody : null,
265
266
  gitRemote: options.gitRemote || null,
266
267
  autoMerge,
267
268
  ...(requiredQualityGates.length > 0 ? { requiredQualityGates } : {}),
@@ -1847,16 +1848,31 @@ class Orchestrator {
1847
1848
  },
1848
1849
  },
1849
1850
  });
1851
+ const boundary = this._clusterRunBoundaries.get(clusterId);
1852
+ const complete = messageBus.query({
1853
+ cluster_id: clusterId,
1854
+ topic: 'CLUSTER_COMPLETE',
1855
+ limit: 1,
1856
+ ...(boundary === null || boundary === undefined ? {} : { afterId: boundary }),
1857
+ })[0];
1858
+ const failed = this._findCurrentRunClusterFailure(messageBus, clusterId);
1859
+ if (!complete && !failed) {
1860
+ messageBus.publish({
1861
+ cluster_id: clusterId,
1862
+ topic: 'CLUSTER_FAILED',
1863
+ sender: 'orchestrator',
1864
+ content: {
1865
+ text: `Operation chain failed: ${err.message}`,
1866
+ data: { reason: 'cluster_operations_failed' },
1867
+ },
1868
+ });
1869
+ }
1850
1870
 
1851
1871
  this._log(`\n${'='.repeat(80)}`);
1852
1872
  this._log(`❌ CLUSTER_OPERATIONS FAILED - STOPPING CLUSTER`);
1853
1873
  this._log(`${'='.repeat(80)}`);
1854
1874
  this._log(`Error: ${err.message}`);
1855
1875
  this._log(`${'='.repeat(80)}\n`);
1856
-
1857
- this.stop(clusterId).catch((stopErr) => {
1858
- console.error(`Failed to stop cluster after operation failure:`, stopErr.message);
1859
- });
1860
1876
  });
1861
1877
  });
1862
1878
  }
@@ -2023,6 +2039,7 @@ class Orchestrator {
2023
2039
  prBase: options.prBase,
2024
2040
  mergeQueue: options.mergeQueue,
2025
2041
  closeIssue: options.closeIssue,
2042
+ prBody: options.prBody,
2026
2043
  requiredQualityGates: options.requiredQualityGates,
2027
2044
  autoMerge: resolveRunPlan(options).autoMerge,
2028
2045
  gitRemote: gitContext?.remote || options.gitRemote,
@@ -2140,8 +2157,16 @@ class Orchestrator {
2140
2157
  // NEVER pass --volumes (irreversible data loss) and NEVER tear down a pinned/shared
2141
2158
  // Compose project — only a project scoped to the worktree directory basename, which is
2142
2159
  // the only kind zeroshot could itself have created, is touched.
2143
- const { resolveWorktreeComposeTeardown } = require('../lib/compose-utils');
2144
- const teardown = resolveWorktreeComposeTeardown(worktreePath);
2160
+ let teardown;
2161
+ try {
2162
+ const { resolveWorktreeComposeTeardown } = require('../lib/compose-utils');
2163
+ teardown = resolveWorktreeComposeTeardown(worktreePath);
2164
+ } catch (error) {
2165
+ this._log(
2166
+ `[Orchestrator] Skipping Docker Compose teardown in ${worktreePath}: ${error.message}`
2167
+ );
2168
+ return;
2169
+ }
2145
2170
  if (!teardown.shouldTeardown) {
2146
2171
  if (teardown.composePath) {
2147
2172
  this._log(
@@ -4202,7 +4227,7 @@ Continue from where you left off. Review your previous output to understand what
4202
4227
 
4203
4228
  // Get issue context from ledger
4204
4229
  const issueMsg = cluster.messageBus.ledger.findLast({ topic: 'ISSUE_OPENED' });
4205
- const issueNumber = issueMsg?.content?.data?.number || 'unknown';
4230
+ const issueNumber = issueMsg?.content?.data?.issue_number || 'unknown';
4206
4231
  const issueTitle = issueMsg?.content?.data?.title || 'Implementation';
4207
4232
 
4208
4233
  // Generate the final prompt in one typed assembly pass. Issue values are
@@ -0,0 +1,71 @@
1
+ const MAX_PR_BODY_LENGTH = 65536;
2
+
3
+ function normalizeIssueNumber(value) {
4
+ const candidate = typeof value === 'number' ? String(value) : value;
5
+ if (typeof candidate !== 'string') return 'unknown';
6
+ const trimmed = candidate.trim();
7
+ return /^[A-Za-z0-9][A-Za-z0-9._-]*$/.test(trimmed) ? trimmed : 'unknown';
8
+ }
9
+
10
+ function normalizeIssueTitle(value) {
11
+ if (typeof value !== 'string' || value.trim() === '') return 'Implementation';
12
+ const normalized = [...value]
13
+ .map((character) => {
14
+ const codePoint = character.codePointAt(0);
15
+ return codePoint < 0x20 || codePoint === 0x7f ? ' ' : character;
16
+ })
17
+ .join('')
18
+ .trim();
19
+ return normalized || 'Implementation';
20
+ }
21
+
22
+ function resolveIssueContext(options = {}) {
23
+ const issueNumber = normalizeIssueNumber(options.issueNumber);
24
+ const issueTitle = normalizeIssueTitle(options.issueTitle);
25
+ const issueReference =
26
+ options.includeIssueReference === false || issueNumber === 'unknown'
27
+ ? ''
28
+ : `Closes #${issueNumber}`;
29
+ return { issueNumber, issueTitle, issueReference };
30
+ }
31
+
32
+ function normalizePrBodyTemplate(value) {
33
+ if (value === undefined || value === null) return null;
34
+ if (typeof value !== 'string') throw new TypeError('PR body template must be a string');
35
+ if (value.includes('\0')) throw new TypeError('PR body template must not contain NUL bytes');
36
+ if (value.length > MAX_PR_BODY_LENGTH) {
37
+ throw new TypeError(`PR body template must not exceed ${MAX_PR_BODY_LENGTH} characters`);
38
+ }
39
+ return value;
40
+ }
41
+
42
+ /**
43
+ * Render a bounded PR body. Missing issue metadata expands to empty text so
44
+ * manual tasks never leak internal sentinel values into pull requests.
45
+ */
46
+ function renderPullRequestBody(template, options = {}) {
47
+ const issueContext = resolveIssueContext(options);
48
+ const normalizedTemplate = normalizePrBodyTemplate(template);
49
+ if (normalizedTemplate === null) return issueContext.issueReference;
50
+
51
+ const hasIssue = issueContext.issueNumber !== 'unknown';
52
+ const substitutions = {
53
+ '{{issue_number}}': hasIssue ? issueContext.issueNumber : '',
54
+ '{{issue_title}}': hasIssue ? issueContext.issueTitle : '',
55
+ '{{issue_reference}}': hasIssue ? issueContext.issueReference : '',
56
+ };
57
+ let rendered = normalizedTemplate;
58
+ for (const [token, replacement] of Object.entries(substitutions)) {
59
+ rendered = rendered.replaceAll(token, replacement);
60
+ }
61
+ if (rendered.length > MAX_PR_BODY_LENGTH) {
62
+ throw new TypeError(`Rendered PR body must not exceed ${MAX_PR_BODY_LENGTH} characters`);
63
+ }
64
+ return rendered;
65
+ }
66
+
67
+ module.exports = {
68
+ MAX_PR_BODY_LENGTH,
69
+ renderPullRequestBody,
70
+ resolveIssueContext,
71
+ };
@@ -1,3 +1,5 @@
1
+ "use strict";
2
+ // The generated CommonJS entrypoint resolves the maintained provider facade one directory up.
3
+ // eslint-disable-next-line @typescript-eslint/no-unsafe-assignment
1
4
  const { createProviderClass } = require('..');
2
-
3
5
  module.exports = createProviderClass('claude');
@@ -0,0 +1,13 @@
1
+ interface ProviderConstructor {
2
+ new (): { readonly name: string };
3
+ }
4
+
5
+ interface ProvidersFacade {
6
+ createProviderClass(name: string): ProviderConstructor;
7
+ }
8
+
9
+ // The generated CommonJS entrypoint resolves the maintained provider facade one directory up.
10
+ // eslint-disable-next-line @typescript-eslint/no-unsafe-assignment
11
+ const { createProviderClass }: ProvidersFacade = require('..');
12
+
13
+ export = createProviderClass('claude');
@@ -1,33 +1,25 @@
1
- const {
2
- PROVIDER_CAPABILITIES,
3
- normalizeProviderName,
4
- providerSupportsCapability,
5
- } = require('../../lib/provider-names');
6
-
7
- const CAPABILITIES = Object.freeze(
8
- Object.fromEntries(
9
- Object.entries(PROVIDER_CAPABILITIES).map(([provider, capabilities]) => [
10
- provider,
11
- Object.freeze({ ...capabilities }),
12
- ])
13
- )
14
- );
15
-
1
+ "use strict";
2
+ // The generated CommonJS facade resolves the built provider registry through lib/.
3
+ // eslint-disable-next-line @typescript-eslint/no-unsafe-assignment
4
+ const { PROVIDER_CAPABILITIES, normalizeProviderName, providerSupportsCapability } = require('../../lib/provider-names');
5
+ const CAPABILITIES = Object.freeze(Object.fromEntries(Object.entries(PROVIDER_CAPABILITIES).map(([provider, capabilities]) => [
6
+ provider,
7
+ Object.freeze({ ...capabilities }),
8
+ ])));
16
9
  function checkCapability(provider, capability) {
17
- if (!provider) return false;
18
- return providerSupportsCapability(provider, capability);
10
+ if (!provider)
11
+ return false;
12
+ return providerSupportsCapability(provider, capability);
19
13
  }
20
-
21
14
  function warnIfExperimental(provider, capability) {
22
- const normalized = normalizeProviderName(provider);
23
- const caps = CAPABILITIES[normalized];
24
- if (caps?.[capability] === 'experimental') {
25
- console.warn(`⚠️ ${capability} is experimental for ${normalized} and may not work reliably`);
26
- }
15
+ const normalized = normalizeProviderName(provider);
16
+ const caps = CAPABILITIES[normalized];
17
+ if (caps?.[capability] === 'experimental') {
18
+ console.warn(`⚠️ ${capability} is experimental for ${normalized} and may not work reliably`);
19
+ }
27
20
  }
28
-
29
21
  module.exports = {
30
- CAPABILITIES,
31
- checkCapability,
32
- warnIfExperimental,
22
+ CAPABILITIES,
23
+ checkCapability,
24
+ warnIfExperimental,
33
25
  };
@@ -0,0 +1,44 @@
1
+ type ProviderCapabilityState = boolean | 'experimental';
2
+ type ProviderCapabilities = Readonly<Record<string, ProviderCapabilityState>>;
3
+
4
+ interface ProviderNamesFacade {
5
+ readonly PROVIDER_CAPABILITIES: Readonly<Record<string, ProviderCapabilities>>;
6
+ normalizeProviderName(provider: string): string;
7
+ providerSupportsCapability(provider: string, capability: string): boolean;
8
+ }
9
+
10
+ // The generated CommonJS facade resolves the built provider registry through lib/.
11
+ // eslint-disable-next-line @typescript-eslint/no-unsafe-assignment
12
+ const { PROVIDER_CAPABILITIES, normalizeProviderName, providerSupportsCapability }:
13
+ ProviderNamesFacade = require('../../lib/provider-names');
14
+
15
+ const CAPABILITIES: Readonly<Record<string, ProviderCapabilities>> = Object.freeze(
16
+ Object.fromEntries(
17
+ Object.entries(PROVIDER_CAPABILITIES).map(([provider, capabilities]) => [
18
+ provider,
19
+ Object.freeze({ ...capabilities }),
20
+ ])
21
+ )
22
+ );
23
+
24
+ function checkCapability(
25
+ provider: string | null | undefined,
26
+ capability: string
27
+ ): boolean {
28
+ if (!provider) return false;
29
+ return providerSupportsCapability(provider, capability);
30
+ }
31
+
32
+ function warnIfExperimental(provider: string, capability: string): void {
33
+ const normalized = normalizeProviderName(provider);
34
+ const caps = CAPABILITIES[normalized];
35
+ if (caps?.[capability] === 'experimental') {
36
+ console.warn(`⚠️ ${capability} is experimental for ${normalized} and may not work reliably`);
37
+ }
38
+ }
39
+
40
+ export = {
41
+ CAPABILITIES,
42
+ checkCapability,
43
+ warnIfExperimental,
44
+ };
@@ -1,3 +1,5 @@
1
+ "use strict";
2
+ // The generated CommonJS entrypoint resolves the maintained provider facade one directory up.
3
+ // eslint-disable-next-line @typescript-eslint/no-unsafe-assignment
1
4
  const { createProviderClass } = require('..');
2
-
3
5
  module.exports = createProviderClass('gemini');
@@ -0,0 +1,13 @@
1
+ interface ProviderConstructor {
2
+ new (): { readonly name: string };
3
+ }
4
+
5
+ interface ProvidersFacade {
6
+ createProviderClass(name: string): ProviderConstructor;
7
+ }
8
+
9
+ // The generated CommonJS entrypoint resolves the maintained provider facade one directory up.
10
+ // eslint-disable-next-line @typescript-eslint/no-unsafe-assignment
11
+ const { createProviderClass }: ProvidersFacade = require('..');
12
+
13
+ export = createProviderClass('gemini');
@@ -1,3 +1,5 @@
1
+ "use strict";
2
+ // The generated CommonJS entrypoint resolves the maintained provider facade one directory up.
3
+ // eslint-disable-next-line @typescript-eslint/no-unsafe-assignment
1
4
  const { createProviderClass } = require('..');
2
-
3
5
  module.exports = createProviderClass('codex');
@@ -0,0 +1,13 @@
1
+ interface ProviderConstructor {
2
+ new (): { readonly name: string };
3
+ }
4
+
5
+ interface ProvidersFacade {
6
+ createProviderClass(name: string): ProviderConstructor;
7
+ }
8
+
9
+ // The generated CommonJS entrypoint resolves the maintained provider facade one directory up.
10
+ // eslint-disable-next-line @typescript-eslint/no-unsafe-assignment
11
+ const { createProviderClass }: ProvidersFacade = require('..');
12
+
13
+ export = createProviderClass('codex');
@@ -1,3 +1,5 @@
1
+ "use strict";
2
+ // The generated CommonJS entrypoint resolves the maintained provider facade one directory up.
3
+ // eslint-disable-next-line @typescript-eslint/no-unsafe-assignment
1
4
  const { createProviderClass } = require('..');
2
-
3
5
  module.exports = createProviderClass('opencode');
@@ -0,0 +1,13 @@
1
+ interface ProviderConstructor {
2
+ new (): { readonly name: string };
3
+ }
4
+
5
+ interface ProvidersFacade {
6
+ createProviderClass(name: string): ProviderConstructor;
7
+ }
8
+
9
+ // The generated CommonJS entrypoint resolves the maintained provider facade one directory up.
10
+ // eslint-disable-next-line @typescript-eslint/no-unsafe-assignment
11
+ const { createProviderClass }: ProvidersFacade = require('..');
12
+
13
+ export = createProviderClass('opencode');