@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
@@ -1,351 +1,281 @@
1
- const fs = require('fs');
2
- const os = require('os');
3
- const path = require('path');
1
+ "use strict";
2
+ const fs = require("fs");
3
+ const os = require("os");
4
+ const path = require("path");
5
+ // eslint-disable-next-line @typescript-eslint/no-unsafe-assignment
4
6
  const lockfile = require('proper-lockfile');
5
- const { resolveRunPlan } = require('./run-plan');
6
- const { isProcessRunning } = require('./process-liveness');
7
+ // eslint-disable-next-line @typescript-eslint/no-unsafe-assignment
8
+ const runPlan = require('./run-plan');
9
+ // eslint-disable-next-line @typescript-eslint/no-unsafe-assignment
10
+ const processLiveness = require('./process-liveness');
11
+ // eslint-disable-next-line @typescript-eslint/no-unsafe-assignment
7
12
  const IsolationManager = require('../src/isolation-manager');
8
-
13
+ const { resolveRunPlan } = runPlan;
14
+ const { isProcessRunning } = processLiveness;
9
15
  const DEFAULT_WAIT_TIMEOUT_SECONDS = 180;
10
16
  const DEFAULT_WAIT_POLL_MS = 1000;
11
17
  const CLUSTERS_LOCK_STALE_MS = 5000;
12
18
  const DEFAULT_OWNERSHIP_TIMEOUT_MS = 10000;
13
-
19
+ function isClusterRegistry(value) {
20
+ return value !== null && typeof value === 'object';
21
+ }
22
+ function hasErrorCode(error, code) {
23
+ return error !== null && typeof error === 'object' && 'code' in error && error.code === code;
24
+ }
14
25
  function getStorageDir(storageDir) {
15
- return storageDir || path.join(os.homedir(), '.zeroshot');
26
+ return storageDir || path.join(os.homedir(), '.zeroshot');
16
27
  }
17
-
18
28
  function getClustersFilePath(storageDir) {
19
- return path.join(getStorageDir(storageDir), 'clusters.json');
29
+ return path.join(getStorageDir(storageDir), 'clusters.json');
20
30
  }
21
-
22
31
  function resolveWaitTimeoutMs(waitTimeoutSeconds) {
23
- const parsed = Number(waitTimeoutSeconds);
24
- if (!Number.isFinite(parsed) || parsed <= 0) {
25
- return DEFAULT_WAIT_TIMEOUT_SECONDS * 1000;
26
- }
27
- return Math.floor(parsed * 1000);
32
+ const parsed = Number(waitTimeoutSeconds);
33
+ if (!Number.isFinite(parsed) || parsed <= 0) {
34
+ return DEFAULT_WAIT_TIMEOUT_SECONDS * 1000;
35
+ }
36
+ return Math.floor(parsed * 1000);
28
37
  }
29
-
30
38
  // Kept as an alias: this module used to carry its own copy of this check.
31
39
  const isProcessAlive = isProcessRunning;
32
-
33
40
  function isClusterRegistered(clusterId, storageDir) {
34
- const clustersFile = getClustersFilePath(storageDir);
35
- if (!fs.existsSync(clustersFile)) {
36
- return false;
37
- }
38
-
39
- let parsed;
40
- try {
41
- const raw = fs.readFileSync(clustersFile, 'utf8');
42
- parsed = JSON.parse(raw);
43
- } catch {
44
- return false;
45
- }
46
-
47
- return parsed !== null && typeof parsed === 'object' && Boolean(parsed[clusterId]);
41
+ const clustersFile = getClustersFilePath(storageDir);
42
+ if (!fs.existsSync(clustersFile)) {
43
+ return false;
44
+ }
45
+ try {
46
+ const raw = fs.readFileSync(clustersFile, 'utf8');
47
+ const parsed = JSON.parse(raw);
48
+ return isClusterRegistry(parsed) && Boolean(parsed[clusterId]);
49
+ }
50
+ catch {
51
+ return false;
52
+ }
48
53
  }
49
-
50
54
  function ensureStorageDir(storageDir) {
51
- const resolvedStorageDir = getStorageDir(storageDir);
52
- fs.mkdirSync(resolvedStorageDir, { recursive: true });
53
- return resolvedStorageDir;
55
+ const resolvedStorageDir = getStorageDir(storageDir);
56
+ fs.mkdirSync(resolvedStorageDir, { recursive: true });
57
+ return resolvedStorageDir;
54
58
  }
55
-
56
59
  function ensureClustersFile(storageDir) {
57
- const resolvedStorageDir = ensureStorageDir(storageDir);
58
- const clustersFile = getClustersFilePath(resolvedStorageDir);
59
- try {
60
- fs.writeFileSync(clustersFile, '{}', { flag: 'wx', mode: 0o600 });
61
- } catch (error) {
62
- if (!error || error.code !== 'EEXIST') {
63
- throw error;
60
+ const resolvedStorageDir = ensureStorageDir(storageDir);
61
+ const clustersFile = getClustersFilePath(resolvedStorageDir);
62
+ try {
63
+ fs.writeFileSync(clustersFile, '{}', { flag: 'wx', mode: 0o600 });
64
64
  }
65
- }
66
- return clustersFile;
65
+ catch (error) {
66
+ if (!hasErrorCode(error, 'EEXIST')) {
67
+ throw error;
68
+ }
69
+ }
70
+ return clustersFile;
67
71
  }
68
-
69
72
  function readClustersFile(clustersFile) {
70
- try {
71
- return JSON.parse(fs.readFileSync(clustersFile, 'utf8'));
72
- } catch {
73
- return {};
74
- }
73
+ try {
74
+ const parsed = JSON.parse(fs.readFileSync(clustersFile, 'utf8'));
75
+ return isClusterRegistry(parsed) ? parsed : {};
76
+ }
77
+ catch {
78
+ return {};
79
+ }
75
80
  }
76
-
77
81
  async function updateClustersFile(storageDir, updater) {
78
- const clustersFile = ensureClustersFile(storageDir);
79
- const lockfilePath = path.join(path.dirname(clustersFile), 'clusters.json.lock');
80
- let release;
81
-
82
- try {
83
- release = await lockfile.lock(clustersFile, {
84
- lockfilePath,
85
- stale: CLUSTERS_LOCK_STALE_MS,
86
- retries: {
87
- retries: 20,
88
- minTimeout: 100,
89
- maxTimeout: 250,
90
- randomize: true,
91
- },
92
- });
93
-
94
- const clusters = readClustersFile(clustersFile);
95
- const updated = updater(clusters) || clusters;
96
- fs.writeFileSync(clustersFile, JSON.stringify(updated, null, 2));
97
- return updated;
98
- } finally {
99
- if (release) {
100
- await release();
82
+ const clustersFile = ensureClustersFile(storageDir);
83
+ const lockfilePath = path.join(path.dirname(clustersFile), 'clusters.json.lock');
84
+ let release;
85
+ try {
86
+ release = await lockfile.lock(clustersFile, {
87
+ lockfilePath,
88
+ stale: CLUSTERS_LOCK_STALE_MS,
89
+ retries: {
90
+ retries: 20,
91
+ minTimeout: 100,
92
+ maxTimeout: 250,
93
+ randomize: true,
94
+ },
95
+ });
96
+ const clusters = readClustersFile(clustersFile);
97
+ const updated = updater(clusters) || clusters;
98
+ fs.writeFileSync(clustersFile, JSON.stringify(updated, null, 2));
99
+ return updated;
100
+ }
101
+ finally {
102
+ if (release) {
103
+ await release();
104
+ }
101
105
  }
102
- }
103
106
  }
104
-
105
- async function registerDetachedSetupCluster({
106
- clusterId,
107
- pid,
108
- storageDir,
109
- logPath,
110
- worktree,
111
- runOptions = {},
112
- cwd,
113
- }) {
114
- const plan = resolveRunPlan(runOptions);
115
- const setupResources =
116
- plan.isolation === 'docker' ? IsolationManager.getDetachedSetupResources(clusterId) : null;
117
- await updateClustersFile(storageDir, (clusters) => {
118
- clusters[clusterId] = {
119
- id: clusterId,
120
- state: 'setup',
121
- createdAt: Date.now(),
122
- pid: Number.isInteger(pid) ? pid : null,
123
- setupLogPath: logPath || null,
124
- setupStartedAt: Date.now(),
125
- setupStage: 'starting',
126
- autoPr: plan.delivery !== 'none',
127
- prOptions: runOptions.prBase
128
- ? {
129
- prBase: runOptions.prBase,
130
- mergeQueue: runOptions.mergeQueue || false,
131
- closeIssue: runOptions.closeIssue || null,
132
- autoMerge: plan.autoMerge,
133
- cwd: cwd || null,
134
- }
135
- : null,
136
- worktree: worktree || null,
137
- config: null,
138
- issue: null,
139
- isolation: null,
140
- agentStates: [],
141
- failureInfo: null,
142
- setupResources,
143
- provisional: true,
144
- };
145
- return clusters;
146
- });
107
+ async function registerDetachedSetupCluster({ clusterId, pid, storageDir, logPath, worktree, runOptions = {}, cwd, }) {
108
+ const plan = resolveRunPlan(runOptions);
109
+ const setupResources = plan.isolation === 'docker' ? IsolationManager.getDetachedSetupResources(clusterId) : null;
110
+ await updateClustersFile(storageDir, (clusters) => {
111
+ clusters[clusterId] = {
112
+ id: clusterId,
113
+ state: 'setup',
114
+ createdAt: Date.now(),
115
+ pid: typeof pid === 'number' && Number.isInteger(pid) ? pid : null,
116
+ setupLogPath: logPath || null,
117
+ setupStartedAt: Date.now(),
118
+ setupStage: 'starting',
119
+ autoPr: plan.delivery !== 'none',
120
+ prOptions: plan.delivery !== 'none'
121
+ ? {
122
+ prBase: runOptions.prBase,
123
+ prBody: typeof runOptions.prBody === 'string' ? runOptions.prBody : null,
124
+ mergeQueue: runOptions.mergeQueue || false,
125
+ closeIssue: runOptions.closeIssue || null,
126
+ autoMerge: plan.autoMerge,
127
+ cwd: cwd || null,
128
+ }
129
+ : null,
130
+ worktree: worktree || null,
131
+ config: null,
132
+ issue: null,
133
+ isolation: null,
134
+ agentStates: [],
135
+ failureInfo: null,
136
+ setupResources,
137
+ provisional: true,
138
+ };
139
+ return clusters;
140
+ });
147
141
  }
148
-
149
- async function removeDetachedSetupCluster({ clusterId, storageDir }) {
150
- await updateClustersFile(storageDir, (clusters) => {
151
- delete clusters[clusterId];
152
- return clusters;
153
- });
142
+ async function removeDetachedSetupCluster({ clusterId, storageDir, }) {
143
+ await updateClustersFile(storageDir, (clusters) => {
144
+ delete clusters[clusterId];
145
+ return clusters;
146
+ });
154
147
  }
155
-
156
- async function markDetachedSetupFailed({ clusterId, storageDir, error, logPath }) {
157
- await updateClustersFile(storageDir, (clusters) => {
158
- const existing = clusters[clusterId] || { id: clusterId, createdAt: Date.now() };
159
- clusters[clusterId] = {
160
- ...existing,
161
- state: 'failed',
162
- pid: null,
163
- setupLogPath: existing.setupLogPath || logPath || null,
164
- setupFinishedAt: Date.now(),
165
- failureInfo: {
166
- type: 'setup',
167
- error: error instanceof Error ? error.message : String(error),
168
- timestamp: Date.now(),
169
- },
170
- provisional: true,
171
- };
172
- return clusters;
173
- });
148
+ async function markDetachedSetupFailed({ clusterId, storageDir, error, logPath, }) {
149
+ await updateClustersFile(storageDir, (clusters) => {
150
+ const existing = clusters[clusterId] || { id: clusterId, createdAt: Date.now() };
151
+ clusters[clusterId] = {
152
+ ...existing,
153
+ state: 'failed',
154
+ pid: null,
155
+ setupLogPath: existing.setupLogPath || logPath || null,
156
+ setupFinishedAt: Date.now(),
157
+ failureInfo: {
158
+ type: 'setup',
159
+ error: error instanceof Error ? error.message : String(error),
160
+ timestamp: Date.now(),
161
+ },
162
+ provisional: true,
163
+ };
164
+ return clusters;
165
+ });
174
166
  }
175
-
176
167
  function sleep(ms) {
177
- return new Promise((resolve) => setTimeout(resolve, ms));
168
+ return new Promise((resolve) => setTimeout(resolve, ms));
178
169
  }
179
-
180
170
  function formatLogHint(logPath) {
181
- return logPath ? ` Check log: ${logPath}` : '';
171
+ return logPath ? ` Check log: ${logPath}` : '';
182
172
  }
183
-
184
- async function waitForClusterRegistration({
185
- clusterId,
186
- timeoutMs,
187
- pollMs = DEFAULT_WAIT_POLL_MS,
188
- storageDir,
189
- daemonPid,
190
- logPath,
191
- }) {
192
- const effectiveTimeoutMs =
193
- Number.isFinite(timeoutMs) && timeoutMs > 0 ? timeoutMs : DEFAULT_WAIT_TIMEOUT_SECONDS * 1000;
194
- const startedAt = Date.now();
195
- const deadline = startedAt + effectiveTimeoutMs;
196
- const logHint = formatLogHint(logPath);
197
-
198
- while (Date.now() < deadline) {
199
- if (isClusterRegistered(clusterId, storageDir)) {
200
- return { ready: true, elapsedMs: Date.now() - startedAt };
201
- }
202
-
203
- if (daemonPid && !isProcessAlive(daemonPid)) {
204
- throw new Error(
205
- `Detached daemon exited before cluster "${clusterId}" registered in storage.${logHint}`
206
- );
173
+ async function waitForClusterRegistration({ clusterId, timeoutMs, pollMs = DEFAULT_WAIT_POLL_MS, storageDir, daemonPid, logPath, }) {
174
+ const effectiveTimeoutMs = typeof timeoutMs === 'number' && Number.isFinite(timeoutMs) && timeoutMs > 0
175
+ ? timeoutMs
176
+ : DEFAULT_WAIT_TIMEOUT_SECONDS * 1000;
177
+ const startedAt = Date.now();
178
+ const deadline = startedAt + effectiveTimeoutMs;
179
+ const logHint = formatLogHint(logPath);
180
+ while (Date.now() < deadline) {
181
+ if (isClusterRegistered(clusterId, storageDir)) {
182
+ return { ready: true, elapsedMs: Date.now() - startedAt };
183
+ }
184
+ if (daemonPid && !isProcessAlive(daemonPid)) {
185
+ throw new Error(`Detached daemon exited before cluster "${clusterId}" registered in storage.${logHint}`);
186
+ }
187
+ await sleep(pollMs);
207
188
  }
208
-
209
- await sleep(pollMs);
210
- }
211
-
212
- const timeoutSeconds = Math.ceil(effectiveTimeoutMs / 1000);
213
- throw new Error(
214
- `Timed out after ${timeoutSeconds}s waiting for cluster "${clusterId}" to appear in status/list.${logHint}`
215
- );
189
+ const timeoutSeconds = Math.ceil(effectiveTimeoutMs / 1000);
190
+ throw new Error(`Timed out after ${timeoutSeconds}s waiting for cluster "${clusterId}" to appear in status/list.${logHint}`);
216
191
  }
217
-
218
192
  /**
219
- * Atomically claim the right to resume-daemon an *existing* cluster record.
220
- *
221
- * This deliberately does NOT touch cluster.pid/state - those are the fields
222
- * orchestrator.resume()'s own eligibility guard inspects to decide "is
223
- * someone else already running this?". If this function stamped its PID onto
224
- * `cluster.pid` up front, the daemon's own subsequent resume() call would see
225
- * state:'running' with a PID that (trivially) belongs to itself and is
226
- * therefore alive, and reject itself as "still running" - which is exactly
227
- * what happened in early revisions of this fix. Ownership for the handoff is
228
- * tracked in a separate `resumeDaemonPid` field instead; orchestrator.resume()
229
- * never looks at it, and _restartClusterAgents sets the real cluster.pid once
230
- * resume() actually decides to proceed.
231
- *
232
- * Unlike registerDetachedSetupCluster (which writes a brand-new placeholder
233
- * record for a cluster ID that doesn't exist yet), this only adds
234
- * resumeDaemonPid to the existing record - config/agents/worktree/isolation
235
- * survive untouched, or the daemon's orchestrator.resume() would reload a
236
- * blank record and reject it as an unfinished setup cluster.
237
- *
238
- * The liveness re-check happens inside the same updateClustersFile lock that
239
- * performs the write, so two concurrent resume --detach invocations can't both
240
- * observe no live claimant and both win: whichever's write lands second sees
241
- * either the first daemon's (still-live) resumeDaemonPid, or - once that gets
242
- * overwritten by the first daemon's own early _saveClusters() call - its real
243
- * state:'running' + live pid, and aborts instead of clobbering it.
193
+ * Atomically claim the right to resume-daemon an existing cluster record.
194
+ * Ownership for the handoff is tracked separately from cluster.pid/state so
195
+ * orchestrator.resume() can still perform its own eligibility check.
244
196
  */
245
- async function patchDetachedResumeCluster({ clusterId, daemonPid, storageDir }) {
246
- await updateClustersFile(storageDir, (clusters) => {
247
- const existing = clusters[clusterId];
248
- if (!existing) {
249
- throw new Error(`Cannot start resume daemon: cluster "${clusterId}" not found in registry`);
250
- }
251
- if (existing.resumeDaemonPid && isProcessRunning(existing.resumeDaemonPid)) {
252
- throw new Error(
253
- `Cluster "${clusterId}" already has a live resume daemon (PID ${existing.resumeDaemonPid}); refusing to start a second one`
254
- );
255
- }
256
- // resumeDaemonPid only covers the window up to orchestrator.resume()
257
- // actually proceeding - _restartClusterAgents sets the real cluster.pid,
258
- // and _resumeFailedCluster/_resumeCleanCluster save that almost
259
- // immediately (well before the resumed work itself finishes), which wipes
260
- // resumeDaemonPid since it isn't in _saveClusters' persisted field list.
261
- // Falling back to state+pid here closes that second window: a first
262
- // daemon that has already progressed to actually running is just as much
263
- // a live claimant as one still mid-handoff.
264
- if (existing.state === 'running' && existing.pid && isProcessRunning(existing.pid)) {
265
- throw new Error(
266
- `Cluster "${clusterId}" is already running (PID ${existing.pid}); refusing to start a second resume daemon`
267
- );
268
- }
269
- clusters[clusterId] = { ...existing, resumeDaemonPid: daemonPid };
270
- return clusters;
271
- });
197
+ async function patchDetachedResumeCluster({ clusterId, daemonPid, storageDir, }) {
198
+ await updateClustersFile(storageDir, (clusters) => {
199
+ const existing = clusters[clusterId];
200
+ if (!existing) {
201
+ throw new Error(`Cannot start resume daemon: cluster "${clusterId}" not found in registry`);
202
+ }
203
+ if (existing.resumeDaemonPid && isProcessRunning(existing.resumeDaemonPid)) {
204
+ const ownership = `Cluster "${clusterId}" already has a live resume daemon`;
205
+ throw new Error(`${ownership} (PID ${existing.resumeDaemonPid}); refusing to start a second one`);
206
+ }
207
+ if (existing.state === 'running' && existing.pid && isProcessRunning(existing.pid)) {
208
+ throw new Error(`Cluster "${clusterId}" is already running (PID ${existing.pid}); refusing to start a second resume daemon`);
209
+ }
210
+ clusters[clusterId] = { ...existing, resumeDaemonPid: daemonPid };
211
+ return clusters;
212
+ });
272
213
  }
273
-
274
214
  /**
275
- * Undo a resume handoff that didn't pan out (daemon died before completing
276
- * ownership, or orchestrator.resume() itself rejected it) so the cluster
277
- * doesn't end up stuck at state:'running' with a dead PID - the exact zombie
278
- * this whole mechanism exists to prevent.
215
+ * Undo a resume handoff that did not complete so a dead daemon cannot leave
216
+ * the cluster stuck in a running state.
279
217
  */
280
- async function revertDetachedResumeCluster({ clusterId, storageDir, error }) {
281
- await updateClustersFile(storageDir, (clusters) => {
282
- const existing = clusters[clusterId];
283
- if (!existing) return clusters;
284
- clusters[clusterId] = {
285
- ...existing,
286
- state: 'failed',
287
- pid: null,
288
- resumeDaemonPid: null,
289
- failureInfo: {
290
- type: 'resume-daemon',
291
- error: error instanceof Error ? error.message : String(error),
292
- timestamp: Date.now(),
293
- },
294
- };
295
- return clusters;
296
- });
218
+ async function revertDetachedResumeCluster({ clusterId, storageDir, error, }) {
219
+ await updateClustersFile(storageDir, (clusters) => {
220
+ const existing = clusters[clusterId];
221
+ if (!existing)
222
+ return clusters;
223
+ clusters[clusterId] = {
224
+ ...existing,
225
+ state: 'failed',
226
+ pid: null,
227
+ resumeDaemonPid: null,
228
+ failureInfo: {
229
+ type: 'resume-daemon',
230
+ error: error instanceof Error ? error.message : String(error),
231
+ timestamp: Date.now(),
232
+ },
233
+ };
234
+ return clusters;
235
+ });
297
236
  }
298
-
299
237
  function getRegisteredResumeDaemonPid(clusterId, storageDir) {
300
- const clustersFile = getClustersFilePath(storageDir);
301
- if (!fs.existsSync(clustersFile)) {
302
- return null;
303
- }
304
- try {
305
- const parsed = JSON.parse(fs.readFileSync(clustersFile, 'utf8'));
306
- return parsed?.[clusterId]?.resumeDaemonPid ?? null;
307
- } catch {
308
- return null;
309
- }
238
+ const clustersFile = getClustersFilePath(storageDir);
239
+ if (!fs.existsSync(clustersFile)) {
240
+ return null;
241
+ }
242
+ try {
243
+ const parsed = JSON.parse(fs.readFileSync(clustersFile, 'utf8'));
244
+ if (!isClusterRegistry(parsed)) {
245
+ return null;
246
+ }
247
+ return parsed[clusterId]?.resumeDaemonPid ?? null;
248
+ }
249
+ catch {
250
+ return null;
251
+ }
310
252
  }
311
-
312
253
  /**
313
- * Daemon-side half of the resume handoff: block until the registry shows
314
- * *this process's* PID as resumeDaemonPid before touching the cluster.
315
- * Closes the window between spawn() returning a PID and the parent's
316
- * patchDetachedResumeCluster() write landing - without it, a losing daemon
317
- * from a concurrent resume --detach could start running orchestrator.resume()
318
- * before its parent's CAS check ever gets a chance to reject it.
254
+ * Daemon-side half of the resume handoff: wait until the registry shows this
255
+ * process's PID as resumeDaemonPid before touching the cluster.
319
256
  */
320
- async function waitForResumeOwnership({
321
- clusterId,
322
- daemonPid,
323
- storageDir,
324
- timeoutMs = DEFAULT_OWNERSHIP_TIMEOUT_MS,
325
- pollMs = DEFAULT_WAIT_POLL_MS,
326
- }) {
327
- const deadline = Date.now() + timeoutMs;
328
- while (Date.now() < deadline) {
329
- if (getRegisteredResumeDaemonPid(clusterId, storageDir) === daemonPid) {
330
- return true;
257
+ async function waitForResumeOwnership({ clusterId, daemonPid, storageDir, timeoutMs = DEFAULT_OWNERSHIP_TIMEOUT_MS, pollMs = DEFAULT_WAIT_POLL_MS, }) {
258
+ const deadline = Date.now() + timeoutMs;
259
+ while (Date.now() < deadline) {
260
+ if (getRegisteredResumeDaemonPid(clusterId, storageDir) === daemonPid) {
261
+ return true;
262
+ }
263
+ await sleep(pollMs);
331
264
  }
332
- await sleep(pollMs);
333
- }
334
- return getRegisteredResumeDaemonPid(clusterId, storageDir) === daemonPid;
265
+ return getRegisteredResumeDaemonPid(clusterId, storageDir) === daemonPid;
335
266
  }
336
-
337
267
  module.exports = {
338
- DEFAULT_WAIT_TIMEOUT_SECONDS,
339
- getClustersFilePath,
340
- getRegisteredResumeDaemonPid,
341
- isClusterRegistered,
342
- isProcessAlive,
343
- markDetachedSetupFailed,
344
- patchDetachedResumeCluster,
345
- registerDetachedSetupCluster,
346
- removeDetachedSetupCluster,
347
- resolveWaitTimeoutMs,
348
- revertDetachedResumeCluster,
349
- waitForClusterRegistration,
350
- waitForResumeOwnership,
268
+ DEFAULT_WAIT_TIMEOUT_SECONDS,
269
+ getClustersFilePath,
270
+ getRegisteredResumeDaemonPid,
271
+ isClusterRegistered,
272
+ isProcessAlive,
273
+ markDetachedSetupFailed,
274
+ patchDetachedResumeCluster,
275
+ registerDetachedSetupCluster,
276
+ removeDetachedSetupCluster,
277
+ resolveWaitTimeoutMs,
278
+ revertDetachedResumeCluster,
279
+ waitForClusterRegistration,
280
+ waitForResumeOwnership,
351
281
  };
@@ -0,0 +1,43 @@
1
+ interface MountPreset {
2
+ host: string;
3
+ container: string;
4
+ readonly: boolean;
5
+ hostEnv?: string;
6
+ }
7
+ interface ProviderEnvAuthResult {
8
+ ok: boolean;
9
+ satisfiedOneOf: boolean;
10
+ malformed: string[];
11
+ message: string;
12
+ }
13
+ interface ResolvedMount {
14
+ host: string;
15
+ container: string;
16
+ readonly: boolean;
17
+ }
18
+ interface ResolveMountOptions {
19
+ containerHome?: string;
20
+ }
21
+ interface ExpandedEnv {
22
+ name: string;
23
+ value: string | null;
24
+ forced: boolean;
25
+ }
26
+ declare function resolveMounts(config: unknown, options?: ResolveMountOptions): ResolvedMount[];
27
+ declare function resolveEnvs(mountConfig: readonly unknown[], extraEnvs?: readonly string[]): string[];
28
+ declare function expandEnvPatterns(envVars: readonly string[], env?: Readonly<Record<string, string | undefined>>): ExpandedEnv[];
29
+ declare function validateMountConfig(value: unknown): string | null;
30
+ declare const _default: {
31
+ MOUNT_PRESETS: Readonly<Record<string, MountPreset>>;
32
+ ENV_PRESETS: Readonly<Record<string, readonly string[]>>;
33
+ PROVIDER_ENV_ONLY_PRESETS: ReadonlySet<string>;
34
+ resolveMounts: typeof resolveMounts;
35
+ resolveEnvs: typeof resolveEnvs;
36
+ expandEnvPatterns: typeof expandEnvPatterns;
37
+ isUsableEnvValue: (value: unknown) => value is string;
38
+ isUsableHttpUrl: (value: unknown) => boolean;
39
+ validateMountConfig: typeof validateMountConfig;
40
+ validateEnvPassthrough: (value: unknown) => string | null;
41
+ validateProviderEnvAuth: (providerId: string, forwardedEnv: Readonly<Record<string, string | undefined>> | null | undefined) => ProviderEnvAuthResult;
42
+ };
43
+ export = _default;