@the-open-engine/zeroshot 6.38.0 → 6.39.0

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 (381) hide show
  1. package/cli/event-copy.js +8 -7
  2. package/cli/event-copy.ts +12 -0
  3. package/cli/index.js +7 -31
  4. package/cli/json-export.js +61 -64
  5. package/cli/json-export.ts +112 -0
  6. package/cli/message-formatter-utils.js +68 -56
  7. package/cli/message-formatter-utils.ts +121 -0
  8. package/cli/message-formatters-normal.js +124 -259
  9. package/cli/message-formatters-normal.ts +250 -0
  10. package/cli/message-formatters-watch.js +81 -84
  11. package/cli/message-formatters-watch.ts +189 -0
  12. package/lib/agent-cli-provider/adapters/codex.d.ts.map +1 -1
  13. package/lib/agent-cli-provider/adapters/codex.js +3 -1
  14. package/lib/agent-cli-provider/adapters/codex.js.map +1 -1
  15. package/lib/cluster/generated/protocol-schema.cjs +1 -1
  16. package/lib/cluster/generated/protocol-schema.mjs +1 -1
  17. package/lib/cluster/generated/protocol.d.cts +8 -0
  18. package/lib/cluster/generated/protocol.d.mts +8 -0
  19. package/lib/cluster/generated/protocol.d.ts +8 -0
  20. package/lib/clusters-registry.d.ts +23 -0
  21. package/lib/clusters-registry.js +17 -29
  22. package/lib/completion.d.ts +12 -0
  23. package/lib/completion.js +84 -94
  24. package/lib/compose-utils.d.ts +32 -0
  25. package/lib/compose-utils.js +57 -72
  26. package/lib/detached-startup.d.ts +83 -0
  27. package/lib/detached-startup.js +231 -302
  28. package/lib/docker-config.d.ts +43 -0
  29. package/lib/docker-config.js +150 -325
  30. package/lib/docker-env-auth.d.ts +17 -0
  31. package/lib/docker-env-auth.js +75 -0
  32. package/lib/git-remote-utils.d.ts +48 -0
  33. package/lib/git-remote-utils.js +147 -213
  34. package/lib/id-detector.d.ts +15 -0
  35. package/lib/id-detector.js +37 -41
  36. package/lib/path-check.d.ts +30 -0
  37. package/lib/path-check.js +42 -45
  38. package/lib/process-liveness.d.ts +16 -0
  39. package/lib/process-liveness.js +19 -12
  40. package/lib/provider-credential-path.d.ts +16 -0
  41. package/lib/provider-credential-path.js +31 -29
  42. package/lib/provider-defaults.d.ts +30 -0
  43. package/lib/provider-defaults.js +47 -42
  44. package/lib/provider-detection.d.ts +11 -0
  45. package/lib/provider-detection.js +91 -54
  46. package/lib/provider-names.d.ts +38 -0
  47. package/lib/provider-names.js +56 -64
  48. package/lib/repo-settings.d.ts +28 -0
  49. package/lib/repo-settings.js +83 -59
  50. package/lib/run-mode.d.ts +21 -0
  51. package/lib/run-mode.js +21 -20
  52. package/lib/run-plan.d.ts +28 -0
  53. package/lib/run-plan.js +17 -16
  54. package/lib/settings/claude-auth.d.ts +35 -0
  55. package/lib/settings/claude-auth.js +30 -47
  56. package/lib/settings-defaults.d.ts +20 -0
  57. package/lib/settings-defaults.js +149 -0
  58. package/lib/settings-error.d.ts +7 -0
  59. package/lib/settings-error.js +8 -0
  60. package/lib/settings-issue-providers.d.ts +10 -0
  61. package/lib/settings-issue-providers.js +12 -0
  62. package/lib/settings-models.d.ts +22 -0
  63. package/lib/settings-models.js +93 -0
  64. package/lib/settings-storage.d.ts +23 -0
  65. package/lib/settings-storage.js +205 -0
  66. package/lib/settings-validation.d.ts +7 -0
  67. package/lib/settings-validation.js +182 -0
  68. package/lib/settings.d.ts +29 -0
  69. package/lib/settings.js +41 -736
  70. package/lib/setup-apply-types.d.ts +66 -0
  71. package/lib/setup-apply-types.js +2 -0
  72. package/lib/setup-apply.d.ts +39 -0
  73. package/lib/setup-apply.js +267 -264
  74. package/lib/setup-journal.d.ts +41 -0
  75. package/lib/setup-journal.js +119 -76
  76. package/lib/setup-plan-types.d.ts +102 -0
  77. package/lib/setup-plan-types.js +2 -0
  78. package/lib/setup-plan.d.ts +30 -0
  79. package/lib/setup-plan.js +300 -324
  80. package/lib/setup-undo.d.ts +44 -0
  81. package/lib/setup-undo.js +61 -74
  82. package/lib/start-cluster-config.d.ts +26 -0
  83. package/lib/start-cluster-config.js +56 -0
  84. package/lib/start-cluster-environment.d.ts +40 -0
  85. package/lib/start-cluster-environment.js +134 -0
  86. package/lib/start-cluster-run-options.d.ts +53 -0
  87. package/lib/start-cluster-run-options.js +147 -0
  88. package/lib/start-cluster.d.ts +64 -0
  89. package/lib/start-cluster.js +98 -454
  90. package/lib/stream-json-parser.d.ts +17 -0
  91. package/lib/stream-json-parser.js +51 -52
  92. package/npm-shrinkwrap.json +2 -2
  93. package/package.json +12 -6
  94. package/scripts/postinstall.js +27 -0
  95. package/scripts/rust-distribution.js +23 -14
  96. package/src/agent/agent-command-proofs-context.js +35 -45
  97. package/src/agent/agent-command-proofs-context.ts +87 -0
  98. package/src/agent/agent-config-settings.js +19 -0
  99. package/src/agent/agent-config-settings.ts +41 -0
  100. package/src/agent/agent-config.js +122 -231
  101. package/src/agent/agent-config.ts +285 -0
  102. package/src/agent/agent-context-builder.js +38 -273
  103. package/src/agent/agent-context-builder.ts +51 -0
  104. package/src/agent/agent-context-environment-sections.js +105 -0
  105. package/src/agent/agent-context-environment-sections.ts +134 -0
  106. package/src/agent/agent-context-packs.js +165 -0
  107. package/src/agent/agent-context-packs.ts +296 -0
  108. package/src/agent/agent-context-prompt-sections.js +100 -0
  109. package/src/agent/agent-context-prompt-sections.ts +148 -0
  110. package/src/agent/agent-context-sections.js +25 -334
  111. package/src/agent/agent-context-sections.ts +36 -0
  112. package/src/agent/agent-context-sources.js +96 -149
  113. package/src/agent/agent-context-sources.ts +253 -0
  114. package/src/agent/agent-context-types.js +2 -0
  115. package/src/agent/agent-context-types.ts +132 -0
  116. package/src/agent/agent-context-validation-sections.js +73 -0
  117. package/src/agent/agent-context-validation-sections.ts +129 -0
  118. package/src/agent/agent-input-injector.js +99 -118
  119. package/src/agent/agent-input-injector.ts +195 -0
  120. package/src/agent/agent-liveness-poll.js +74 -78
  121. package/src/agent/agent-liveness-poll.ts +163 -0
  122. package/src/agent/agent-quality-gate-schema.js +77 -86
  123. package/src/agent/agent-quality-gate-schema.ts +135 -0
  124. package/src/agent/agent-quality-gates-context.js +44 -50
  125. package/src/agent/agent-quality-gates-context.ts +91 -0
  126. package/src/agent/agent-stuck-detector.js +171 -239
  127. package/src/agent/agent-stuck-detector.ts +288 -0
  128. package/src/agent/agent-trigger-evaluator.js +29 -46
  129. package/src/agent/agent-trigger-evaluator.ts +98 -0
  130. package/src/agent/context-metrics.js +110 -141
  131. package/src/agent/context-metrics.ts +261 -0
  132. package/src/agent/context-pack-builder.js +72 -358
  133. package/src/agent/context-pack-builder.ts +105 -0
  134. package/src/agent/context-pack-core.js +70 -0
  135. package/src/agent/context-pack-core.ts +96 -0
  136. package/src/agent/context-pack-selection.js +119 -0
  137. package/src/agent/context-pack-selection.ts +187 -0
  138. package/src/agent/context-pack-truncation.js +139 -0
  139. package/src/agent/context-pack-truncation.ts +208 -0
  140. package/src/agent/context-pack-types.js +2 -0
  141. package/src/agent/context-pack-types.ts +98 -0
  142. package/src/agent/context-replay-policy.js +30 -39
  143. package/src/agent/context-replay-policy.ts +71 -0
  144. package/src/agent/critical-agent-policy.js +6 -10
  145. package/src/agent/critical-agent-policy.ts +20 -0
  146. package/src/agent/guidance-queue.js +74 -87
  147. package/src/agent/guidance-queue.ts +166 -0
  148. package/src/agent/output-extraction-error-detail.js +45 -0
  149. package/src/agent/output-extraction-error-detail.ts +49 -0
  150. package/src/agent/output-extraction-failures.js +125 -0
  151. package/src/agent/output-extraction-failures.ts +149 -0
  152. package/src/agent/output-extraction-json.js +234 -0
  153. package/src/agent/output-extraction-json.ts +235 -0
  154. package/src/agent/output-extraction-pi.js +124 -0
  155. package/src/agent/output-extraction-pi.ts +137 -0
  156. package/src/agent/output-extraction-types.js +2 -0
  157. package/src/agent/output-extraction-types.ts +49 -0
  158. package/src/agent/output-extraction.js +17 -617
  159. package/src/agent/output-extraction.ts +30 -0
  160. package/src/agent/output-reformatter-errors.js +83 -0
  161. package/src/agent/output-reformatter-errors.ts +106 -0
  162. package/src/agent/output-reformatter-types.js +2 -0
  163. package/src/agent/output-reformatter-types.ts +86 -0
  164. package/src/agent/output-reformatter.js +140 -185
  165. package/src/agent/output-reformatter.ts +238 -0
  166. package/src/agent/pi-terminal-lifecycle-types.js +2 -0
  167. package/src/agent/pi-terminal-lifecycle-types.ts +41 -0
  168. package/src/agent/pi-terminal-lifecycle.js +186 -206
  169. package/src/agent/pi-terminal-lifecycle.ts +297 -0
  170. package/src/agent/provider-control-plane.js +22 -21
  171. package/src/agent/provider-control-plane.ts +52 -0
  172. package/src/agent/provider-terminal-failure-types.js +2 -0
  173. package/src/agent/provider-terminal-failure-types.ts +60 -0
  174. package/src/agent/provider-terminal-failure.js +194 -191
  175. package/src/agent/provider-terminal-failure.ts +262 -0
  176. package/src/agent/rate-limit-backoff.js +31 -74
  177. package/src/agent/rate-limit-backoff.ts +71 -0
  178. package/src/agent/schema-utils.js +85 -125
  179. package/src/agent/schema-utils.ts +148 -0
  180. package/src/agent/structured-output-error.js +34 -33
  181. package/src/agent/structured-output-error.ts +105 -0
  182. package/src/agent/validation-platform.js +27 -27
  183. package/src/agent/validation-platform.ts +49 -0
  184. package/src/agent-cli-provider/adapters/codex.ts +3 -1
  185. package/src/attach/attach-client.js +232 -405
  186. package/src/attach/attach-client.ts +300 -0
  187. package/src/attach/attach-server-cleanup.js +43 -0
  188. package/src/attach/attach-server-cleanup.ts +39 -0
  189. package/src/attach/attach-server-clients.js +117 -0
  190. package/src/attach/attach-server-clients.ts +122 -0
  191. package/src/attach/attach-server-events.js +38 -0
  192. package/src/attach/attach-server-events.ts +36 -0
  193. package/src/attach/attach-server-pty.js +45 -0
  194. package/src/attach/attach-server-pty.ts +64 -0
  195. package/src/attach/attach-server-runtime.js +73 -0
  196. package/src/attach/attach-server-runtime.ts +62 -0
  197. package/src/attach/attach-server-socket.js +28 -0
  198. package/src/attach/attach-server-socket.ts +23 -0
  199. package/src/attach/attach-server-types.js +2 -0
  200. package/src/attach/attach-server-types.ts +82 -0
  201. package/src/attach/attach-server.js +106 -523
  202. package/src/attach/attach-server.ts +158 -0
  203. package/src/attach/index.js +18 -35
  204. package/src/attach/index.ts +18 -0
  205. package/src/attach/protocol.js +95 -184
  206. package/src/attach/protocol.ts +181 -0
  207. package/src/attach/ring-buffer.js +76 -102
  208. package/src/attach/ring-buffer.ts +109 -0
  209. package/src/attach/send-input.js +64 -75
  210. package/src/attach/send-input.ts +94 -0
  211. package/src/attach/socket-discovery.js +164 -218
  212. package/src/attach/socket-discovery.ts +230 -0
  213. package/src/attach/socket-paths.js +42 -61
  214. package/src/attach/socket-paths.ts +81 -0
  215. package/src/claude-credentials.js +51 -54
  216. package/src/claude-credentials.ts +89 -0
  217. package/src/cluster/generated/protocol-schema.ts +1 -1
  218. package/src/cluster/generated/protocol.ts +2 -1
  219. package/src/command-proofs.js +110 -141
  220. package/src/command-proofs.ts +216 -0
  221. package/src/config-router.js +81 -73
  222. package/src/config-router.ts +131 -0
  223. package/src/copy-worker.js +53 -29
  224. package/src/copy-worker.ts +75 -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/ledger-sequence.js +45 -48
  232. package/src/ledger-sequence.ts +63 -0
  233. package/src/legacy-lib/clusters-registry.ts +40 -0
  234. package/src/legacy-lib/completion.ts +148 -0
  235. package/src/legacy-lib/compose-utils.ts +102 -0
  236. package/src/legacy-lib/detached-startup.ts +449 -0
  237. package/src/legacy-lib/docker-config.ts +282 -0
  238. package/src/legacy-lib/docker-env-auth.ts +116 -0
  239. package/src/legacy-lib/git-remote-utils.ts +244 -0
  240. package/src/legacy-lib/id-detector.ts +57 -0
  241. package/src/legacy-lib/js-yaml.d.ts +3 -0
  242. package/src/legacy-lib/omelette.d.ts +15 -0
  243. package/src/legacy-lib/path-check.ts +89 -0
  244. package/src/legacy-lib/process-liveness.ts +36 -0
  245. package/src/legacy-lib/provider-credential-path.ts +57 -0
  246. package/src/legacy-lib/provider-defaults.ts +114 -0
  247. package/src/legacy-lib/provider-detection.ts +67 -0
  248. package/src/legacy-lib/provider-names.ts +126 -0
  249. package/src/legacy-lib/repo-settings.ts +88 -0
  250. package/src/legacy-lib/run-mode.ts +58 -0
  251. package/src/legacy-lib/run-plan.ts +49 -0
  252. package/src/legacy-lib/settings/claude-auth.ts +80 -0
  253. package/src/legacy-lib/settings-defaults.ts +212 -0
  254. package/src/legacy-lib/settings-error.ts +8 -0
  255. package/src/legacy-lib/settings-issue-providers.ts +18 -0
  256. package/src/legacy-lib/settings-models.ts +124 -0
  257. package/src/legacy-lib/settings-storage.ts +277 -0
  258. package/src/legacy-lib/settings-validation.ts +220 -0
  259. package/src/legacy-lib/settings.ts +87 -0
  260. package/src/legacy-lib/setup-apply-types.ts +70 -0
  261. package/src/legacy-lib/setup-apply.ts +456 -0
  262. package/src/legacy-lib/setup-journal.ts +185 -0
  263. package/src/legacy-lib/setup-plan-types.ts +96 -0
  264. package/src/legacy-lib/setup-plan.ts +500 -0
  265. package/src/legacy-lib/setup-undo.ts +142 -0
  266. package/src/legacy-lib/start-cluster-config.ts +124 -0
  267. package/src/legacy-lib/start-cluster-environment.ts +165 -0
  268. package/src/legacy-lib/start-cluster-run-options.ts +279 -0
  269. package/src/legacy-lib/start-cluster.ts +237 -0
  270. package/src/legacy-lib/stream-json-parser.ts +88 -0
  271. package/src/message-buffer.js +55 -71
  272. package/src/message-buffer.ts +107 -0
  273. package/src/message-bus-bridge.js +92 -133
  274. package/src/message-bus-bridge.ts +149 -0
  275. package/src/name-generator-shared.js +220 -0
  276. package/src/name-generator-shared.ts +231 -0
  277. package/src/name-generator.js +8 -217
  278. package/src/name-generator.ts +27 -0
  279. package/src/omp-blob-root.js +83 -64
  280. package/src/omp-blob-root.ts +116 -0
  281. package/src/omp-config-overlay.js +65 -38
  282. package/src/omp-config-overlay.ts +110 -0
  283. package/src/omp-execution-fingerprint.js +38 -43
  284. package/src/omp-execution-fingerprint.ts +92 -0
  285. package/src/omp-session-limits.js +10 -15
  286. package/src/omp-session-limits.ts +53 -0
  287. package/src/omp-session-partition.js +2 -2
  288. package/src/omp-session-verifier.js +1 -1
  289. package/src/orchestrator.js +19 -4
  290. package/src/providers/anthropic/index.js +3 -1
  291. package/src/providers/anthropic/index.ts +13 -0
  292. package/src/providers/capabilities.js +19 -27
  293. package/src/providers/capabilities.ts +44 -0
  294. package/src/providers/google/index.js +3 -1
  295. package/src/providers/google/index.ts +13 -0
  296. package/src/providers/openai/index.js +3 -1
  297. package/src/providers/openai/index.ts +13 -0
  298. package/src/providers/opencode/index.js +3 -1
  299. package/src/providers/opencode/index.ts +13 -0
  300. package/src/quality-gates.js +67 -127
  301. package/src/quality-gates.ts +149 -0
  302. package/src/repo-settings-access.js +40 -0
  303. package/src/repo-settings-access.ts +64 -0
  304. package/src/schemas/sub-cluster.js +127 -183
  305. package/src/schemas/sub-cluster.ts +238 -0
  306. package/src/state-snapshot-normalization.js +224 -0
  307. package/src/state-snapshot-normalization.ts +222 -0
  308. package/src/state-snapshot.js +192 -359
  309. package/src/state-snapshot.ts +291 -0
  310. package/src/state-snapshotter.js +118 -130
  311. package/src/state-snapshotter.ts +167 -0
  312. package/src/sub-cluster-wrapper.js +4 -13
  313. package/src/task-run-model-args.js +87 -124
  314. package/src/task-run-model-args.ts +204 -0
  315. package/src/task-runner.js +5 -25
  316. package/src/task-runner.ts +28 -0
  317. package/src/task-startup-error.js +73 -58
  318. package/src/task-startup-error.ts +126 -0
  319. package/src/template-validation/consensus-gate-contracts.js +2 -0
  320. package/src/template-validation/consensus-gate-contracts.ts +70 -0
  321. package/src/template-validation/consensus-gate-scenarios.js +76 -0
  322. package/src/template-validation/consensus-gate-scenarios.ts +130 -0
  323. package/src/template-validation/consensus-gate-stage.js +34 -0
  324. package/src/template-validation/consensus-gate-stage.ts +56 -0
  325. package/src/template-validation/random-topology-contracts.js +2 -0
  326. package/src/template-validation/random-topology-contracts.ts +54 -0
  327. package/src/template-validation/random-topology-dispatch.js +25 -0
  328. package/src/template-validation/random-topology-dispatch.ts +33 -0
  329. package/src/template-validation/random-topology-message-loop.js +53 -0
  330. package/src/template-validation/random-topology-message-loop.ts +73 -0
  331. package/src/template-validation/random-topology-operations.js +79 -0
  332. package/src/template-validation/random-topology-operations.ts +101 -0
  333. package/src/template-validation/random-topology-runtime.js +25 -0
  334. package/src/template-validation/random-topology-runtime.ts +43 -0
  335. package/src/template-validation/random-topology-scenario.js +52 -0
  336. package/src/template-validation/random-topology-scenario.ts +57 -0
  337. package/src/template-validation/random-topology-schema.js +159 -0
  338. package/src/template-validation/random-topology-schema.ts +190 -0
  339. package/src/template-validation/random-topology-state.js +28 -0
  340. package/src/template-validation/random-topology-state.ts +30 -0
  341. package/src/template-validation/random-topology-trigger-evaluation.js +45 -0
  342. package/src/template-validation/random-topology-trigger-evaluation.ts +65 -0
  343. package/src/template-validation/random-topology-trigger.js +75 -0
  344. package/src/template-validation/random-topology-trigger.ts +88 -0
  345. package/src/template-validation/report-formatter.js +40 -46
  346. package/src/template-validation/report-formatter.ts +101 -0
  347. package/src/template-validation/simulate-consensus-gates.js +111 -302
  348. package/src/template-validation/simulate-consensus-gates.ts +196 -0
  349. package/src/template-validation/simulate-random-topology.js +26 -519
  350. package/src/template-validation/simulate-random-topology.ts +57 -0
  351. package/src/template-validation/simulate-two-stage-validation.js +41 -265
  352. package/src/template-validation/simulate-two-stage-validation.ts +55 -0
  353. package/src/template-validation/simulation-agent-runtime.js +25 -0
  354. package/src/template-validation/simulation-agent-runtime.ts +40 -0
  355. package/src/template-validation/simulation-agent.js +29 -0
  356. package/src/template-validation/simulation-agent.ts +73 -0
  357. package/src/template-validation/simulation-runtime.js +34 -0
  358. package/src/template-validation/simulation-runtime.ts +72 -0
  359. package/src/template-validation/two-stage-contracts.js +2 -0
  360. package/src/template-validation/two-stage-contracts.ts +41 -0
  361. package/src/template-validation/two-stage-inputs.js +21 -0
  362. package/src/template-validation/two-stage-inputs.ts +29 -0
  363. package/src/template-validation/two-stage-results.js +30 -0
  364. package/src/template-validation/two-stage-results.ts +40 -0
  365. package/src/template-validation/two-stage-scenario.js +86 -0
  366. package/src/template-validation/two-stage-scenario.ts +120 -0
  367. package/src/worktree-claude-config.js +182 -220
  368. package/src/worktree-claude-config.ts +272 -0
  369. package/src/worktree-tooling-env.js +103 -125
  370. package/src/worktree-tooling-env.ts +142 -0
  371. package/task-lib/completion.js +2 -3
  372. package/task-lib/completion.ts +9 -0
  373. package/task-lib/config.js +1 -4
  374. package/task-lib/config.ts +11 -0
  375. package/task-lib/name-generator.js +4 -226
  376. package/task-lib/name-generator.ts +11 -0
  377. package/task-lib/omp-session-cleanup.js +1 -1
  378. package/task-lib/omp-storage-root.js +8 -12
  379. package/task-lib/omp-storage-root.ts +62 -0
  380. package/task-lib/process-termination.js +143 -166
  381. package/task-lib/process-termination.ts +268 -0
@@ -0,0 +1,148 @@
1
+ /**
2
+ * Darwin worker Keychain boundary (issue #704).
3
+ *
4
+ * Non-interactive local/worktree workers are spawned with the host environment,
5
+ * so worker descendants (e.g. `claude doctor` probing Keychain writes through
6
+ * `security -i`) reach the logged-in user's GUI Keychain session and launch
7
+ * SecurityAgent dialogs from a supposedly non-interactive cluster.
8
+ *
9
+ * On darwin, worker spawn envs get a managed shim directory prepended to PATH
10
+ * containing a `security` wrapper that fails closed on interactive invocations
11
+ * (`-i`, `-p`, or no arguments) with a deterministic diagnostic, and execs the
12
+ * real /usr/bin/security for every other subcommand so provider authentication
13
+ * (e.g. `security find-generic-password`) keeps working.
14
+ *
15
+ * Docker isolation never reaches this code path, and non-darwin platforms are
16
+ * left untouched. Set ZEROSHOT_ALLOW_INTERACTIVE_KEYCHAIN=1 to opt out.
17
+ */
18
+ import { randomUUID } from 'node:crypto';
19
+ import fs = require('fs');
20
+ import os = require('os');
21
+ import path = require('path');
22
+ interface DarwinKeychainBoundaryOptions {
23
+ platform?: string;
24
+ shimBaseDir?: string;
25
+ realSecurityPath?: string;
26
+ }
27
+ const SHIM_DIR_RELATIVE_PATH = path.join('.zeroshot', 'keychain-shim');
28
+ const REAL_SECURITY_PATH = '/usr/bin/security';
29
+ const OPT_OUT_ENV_VAR = 'ZEROSHOT_ALLOW_INTERACTIVE_KEYCHAIN';
30
+ function shellQuote(value: unknown): string {
31
+ return `'${String(value).replace(/'/g, `'\\''`)}'`;
32
+ }
33
+ function errorMessage(error: unknown): string {
34
+ return error instanceof Error ? error.message : String(error);
35
+ }
36
+ function buildSecurityShimScript(realSecurityPath: string): string {
37
+ return `#!/bin/sh
38
+ # Managed by Zeroshot (src/darwin-keychain-boundary.js). Do not edit.
39
+ #
40
+ # Non-interactive Zeroshot workers must not open the logged-in user's GUI
41
+ # Keychain session (SecurityAgent). Interactive \`security\` invocations fail
42
+ # closed here; every other subcommand is passed through to the real binary so
43
+ # provider authentication keeps working.
44
+ REAL_SECURITY=${shellQuote(realSecurityPath)}
45
+ if [ "\${${OPT_OUT_ENV_VAR}:-0}" = "1" ]; then
46
+ exec "$REAL_SECURITY" "$@"
47
+ fi
48
+ fail_closed() {
49
+ echo "zeroshot: blocked interactive 'security' invocation from a non-interactive worker (argv: $*)." >&2
50
+ echo "zeroshot: this cluster has no interactive Keychain session, so SecurityAgent prompts are disabled." >&2
51
+ echo "zeroshot: run the cluster with Docker isolation or configure explicit credentials for the tool that "\
52
+ "attempted Keychain access." >&2
53
+ echo "zeroshot: set ${OPT_OUT_ENV_VAR}=1 to restore interactive Keychain access." >&2
54
+ exit 1
55
+ }
56
+ # \`security\` without arguments enters interactive mode.
57
+ [ "$#" -eq 0 ] && fail_closed
58
+ # Global options precede the subcommand. -i (interactive) and -p (prompt,
59
+ # implies -i) must not reach the real binary; option letters may be bundled
60
+ # (e.g. -qi). Scanning stops at the first non-option token (the subcommand).
61
+ for arg in "$@"; do
62
+ case "$arg" in
63
+ -*i*|-*p*) fail_closed "$@" ;;
64
+ -*) ;;
65
+ *) break ;;
66
+ esac
67
+ done
68
+ exec "$REAL_SECURITY" "$@"
69
+ `;
70
+ }
71
+ /** Create or refresh the managed directory containing the `security` shim. */
72
+ function ensureDarwinKeychainShimDir(options: DarwinKeychainBoundaryOptions = {}): string {
73
+ const shimDir = options.shimBaseDir || path.join(os.homedir(), SHIM_DIR_RELATIVE_PATH);
74
+ const script = buildSecurityShimScript(options.realSecurityPath || REAL_SECURITY_PATH);
75
+ const shimPath = path.join(shimDir, 'security');
76
+ fs.mkdirSync(shimDir, { recursive: true });
77
+ let existing: string | null = null;
78
+ try {
79
+ existing = fs.readFileSync(shimPath, 'utf8');
80
+ } catch {
81
+ // Missing or unreadable: (re)write below.
82
+ }
83
+ if (existing !== script) {
84
+ const tempPath = path.join(shimDir, `.security.${process.pid}.${randomUUID()}.tmp`);
85
+ try {
86
+ fs.writeFileSync(tempPath, script, { mode: 0o755, flag: 'wx' });
87
+ // The creation mode is subject to umask. Set the final mode before the
88
+ // rename so the live path is never observable as non-executable.
89
+ fs.chmodSync(tempPath, 0o755);
90
+ fs.renameSync(tempPath, shimPath);
91
+ } catch (error: unknown) {
92
+ try {
93
+ // Remove any unpublished partial file without masking the publication
94
+ // failure that caused this cleanup path.
95
+ fs.rmSync(tempPath, { force: true });
96
+ } catch (cleanupError: unknown) {
97
+ if (error instanceof Error) {
98
+ error.message += ` Cleanup also failed: ${errorMessage(cleanupError)}.`;
99
+ }
100
+ }
101
+ throw error;
102
+ }
103
+ } else {
104
+ // An existing matching shim may have drifted permissions.
105
+ fs.chmodSync(shimPath, 0o755);
106
+ }
107
+ return shimDir;
108
+ }
109
+ /** Prepend the Keychain boundary shim to a worker spawn environment's PATH. */
110
+ function applyDarwinKeychainBoundaryToEnv(
111
+ env: NodeJS.ProcessEnv,
112
+ options: DarwinKeychainBoundaryOptions = {}
113
+ ): NodeJS.ProcessEnv {
114
+ const platform = options.platform || process.platform;
115
+ if (platform !== 'darwin') {
116
+ return env;
117
+ }
118
+ if (env[OPT_OUT_ENV_VAR] === '1' || process.env[OPT_OUT_ENV_VAR] === '1') {
119
+ return env;
120
+ }
121
+ let shimDir: string;
122
+ try {
123
+ shimDir = ensureDarwinKeychainShimDir(options);
124
+ } catch (error: unknown) {
125
+ throw new Error(
126
+ `Failed to install the darwin Keychain boundary shim: ${errorMessage(error)}. ` +
127
+ `Non-interactive workers must not reach the interactive Keychain session; ` +
128
+ `use Docker isolation or set ${OPT_OUT_ENV_VAR}=1 to opt out.`
129
+ );
130
+ }
131
+ // Darwin environment keys are case-sensitive: descendants consult PATH,
132
+ // never a differently-cased key such as Path. Preserve empty components
133
+ // because POSIX interprets them as the current directory. An absent PATH
134
+ // retains Node/libuv's default Unix search path after the shim, while an
135
+ // explicitly empty PATH retains its empty component (`<shim>:`).
136
+ const existingEntries =
137
+ env.PATH === undefined
138
+ ? ['/usr/bin', '/bin']
139
+ : String(env.PATH)
140
+ .split(path.delimiter)
141
+ .filter((entry) => entry !== shimDir);
142
+ env.PATH = [shimDir, ...existingEntries].join(path.delimiter);
143
+ return env;
144
+ }
145
+ export = {
146
+ applyDarwinKeychainBoundaryToEnv,
147
+ ensureDarwinKeychainShimDir,
148
+ };
@@ -1,10 +1,9 @@
1
+ "use strict";
1
2
  const USER_GUIDANCE_CLUSTER = 'USER_GUIDANCE_CLUSTER';
2
3
  const USER_GUIDANCE_AGENT = 'USER_GUIDANCE_AGENT';
3
-
4
4
  const GUIDANCE_TOPICS = [USER_GUIDANCE_CLUSTER, USER_GUIDANCE_AGENT];
5
-
6
5
  module.exports = {
7
- USER_GUIDANCE_CLUSTER,
8
- USER_GUIDANCE_AGENT,
9
- GUIDANCE_TOPICS,
6
+ USER_GUIDANCE_CLUSTER,
7
+ USER_GUIDANCE_AGENT,
8
+ GUIDANCE_TOPICS,
10
9
  };
@@ -0,0 +1,10 @@
1
+ const USER_GUIDANCE_CLUSTER = 'USER_GUIDANCE_CLUSTER';
2
+ const USER_GUIDANCE_AGENT = 'USER_GUIDANCE_AGENT';
3
+
4
+ const GUIDANCE_TOPICS = [USER_GUIDANCE_CLUSTER, USER_GUIDANCE_AGENT] as const;
5
+
6
+ export = {
7
+ USER_GUIDANCE_CLUSTER,
8
+ USER_GUIDANCE_AGENT,
9
+ GUIDANCE_TOPICS,
10
+ };
@@ -1,3 +1,6 @@
1
+ "use strict";
2
+ const fs = require("fs");
3
+ const path = require("path");
1
4
  /**
2
5
  * Input Helpers - Create input data from text or files
3
6
  *
@@ -5,61 +8,37 @@
5
8
  * - Plain text input
6
9
  * - File input (markdown)
7
10
  */
8
-
9
- const fs = require('fs');
10
- const path = require('path');
11
-
12
11
  class InputHelpers {
13
- /**
14
- * Create a plain text input wrapper
15
- * @param {String} text - Plain text input
16
- * @returns {Object} Structured context
17
- */
18
- static createTextInput(text) {
19
- return {
20
- number: null,
21
- title: 'Manual Input',
22
- body: text,
23
- labels: [],
24
- comments: [],
25
- url: null,
26
- context: `# Manual Input\n\n${text}\n`,
27
- };
28
- }
29
-
30
- /**
31
- * Create input from markdown file
32
- * @param {String} filePath - Path to markdown file (.md or .markdown)
33
- * @returns {Object} Structured context matching issue format
34
- */
35
- static createFileInput(filePath) {
36
- // Resolve relative paths
37
- const resolvedPath = path.resolve(filePath);
38
-
39
- // Validate file exists
40
- if (!fs.existsSync(resolvedPath)) {
41
- throw new Error(`File not found: ${filePath}`);
12
+ static createTextInput(text) {
13
+ return {
14
+ number: null,
15
+ title: 'Manual Input',
16
+ body: text,
17
+ labels: [],
18
+ comments: [],
19
+ url: null,
20
+ context: `# Manual Input\n\n${text}\n`,
21
+ };
22
+ }
23
+ static createFileInput(filePath) {
24
+ const resolvedPath = path.resolve(filePath);
25
+ if (!fs.existsSync(resolvedPath)) {
26
+ throw new Error(`File not found: ${filePath}`);
27
+ }
28
+ const fileContent = fs.readFileSync(resolvedPath, 'utf8');
29
+ const headerMatch = /^#\s+(.+)$/m.exec(fileContent);
30
+ const extractedTitle = headerMatch?.[1]?.trim() ?? null;
31
+ const fallbackTitle = path.basename(filePath, path.extname(filePath));
32
+ const title = extractedTitle || fallbackTitle;
33
+ return {
34
+ number: null,
35
+ title,
36
+ body: fileContent,
37
+ labels: [],
38
+ comments: [],
39
+ url: null,
40
+ context: `# ${title}\n\n${fileContent}\n`,
41
+ };
42
42
  }
43
-
44
- // Read file content
45
- const fileContent = fs.readFileSync(resolvedPath, 'utf8');
46
-
47
- // Extract title from first header or use filename
48
- const headerMatch = fileContent.match(/^#\s+(.+)$/m);
49
- const extractedTitle = headerMatch ? headerMatch[1].trim() : null;
50
- const fallbackTitle = path.basename(filePath, path.extname(filePath));
51
- const title = extractedTitle || fallbackTitle;
52
-
53
- return {
54
- number: null,
55
- title,
56
- body: fileContent,
57
- labels: [],
58
- comments: [],
59
- url: null,
60
- context: `# ${title}\n\n${fileContent}\n`,
61
- };
62
- }
63
43
  }
64
-
65
44
  module.exports = InputHelpers;
@@ -0,0 +1,58 @@
1
+ import fs = require('fs');
2
+ import path = require('path');
3
+
4
+ interface ManualInput {
5
+ number: null;
6
+ title: string;
7
+ body: string;
8
+ labels: unknown[];
9
+ comments: unknown[];
10
+ url: null;
11
+ context: string;
12
+ }
13
+
14
+ /**
15
+ * Input Helpers - Create input data from text or files
16
+ *
17
+ * Provides fallback input methods for non-issue-based input:
18
+ * - Plain text input
19
+ * - File input (markdown)
20
+ */
21
+ class InputHelpers {
22
+ static createTextInput(text: string): ManualInput {
23
+ return {
24
+ number: null,
25
+ title: 'Manual Input',
26
+ body: text,
27
+ labels: [],
28
+ comments: [],
29
+ url: null,
30
+ context: `# Manual Input\n\n${text}\n`,
31
+ };
32
+ }
33
+
34
+ static createFileInput(filePath: string): ManualInput {
35
+ const resolvedPath = path.resolve(filePath);
36
+ if (!fs.existsSync(resolvedPath)) {
37
+ throw new Error(`File not found: ${filePath}`);
38
+ }
39
+
40
+ const fileContent = fs.readFileSync(resolvedPath, 'utf8');
41
+ const headerMatch = /^#\s+(.+)$/m.exec(fileContent);
42
+ const extractedTitle = headerMatch?.[1]?.trim() ?? null;
43
+ const fallbackTitle = path.basename(filePath, path.extname(filePath));
44
+ const title = extractedTitle || fallbackTitle;
45
+
46
+ return {
47
+ number: null,
48
+ title,
49
+ body: fileContent,
50
+ labels: [],
51
+ comments: [],
52
+ url: null,
53
+ context: `# ${title}\n\n${fileContent}\n`,
54
+ };
55
+ }
56
+ }
57
+
58
+ export = InputHelpers;
@@ -1,63 +1,60 @@
1
+ "use strict";
1
2
  const MAX_SQLITE_ROWID = 9223372036854775807n;
2
3
  const CANONICAL_SEQUENCE = /^(0|[1-9][0-9]*)$/;
3
-
4
4
  function canonicalMessageSequence(value, name = 'message sequence') {
5
- let sequence;
6
- if (typeof value === 'string' && CANONICAL_SEQUENCE.test(value)) {
7
- sequence = value;
8
- } else if (Number.isSafeInteger(value) && value >= 0) {
9
- // Accept legacy JSON state while normalizing every new boundary to a
10
- // JSON-safe decimal string.
11
- sequence = String(value);
12
- } else {
13
- throw new TypeError(`${name} must be a canonical non-negative decimal string`);
14
- }
15
-
16
- if (BigInt(sequence) > MAX_SQLITE_ROWID) {
17
- throw new RangeError(`${name} exceeds the SQLite rowid range`);
18
- }
19
- return sequence;
5
+ let sequence;
6
+ if (typeof value === 'string' && CANONICAL_SEQUENCE.test(value)) {
7
+ sequence = value;
8
+ }
9
+ else if (typeof value === 'number' && Number.isSafeInteger(value) && value >= 0) {
10
+ // Accept legacy JSON state while normalizing every new boundary to a
11
+ // JSON-safe decimal string.
12
+ sequence = String(value);
13
+ }
14
+ else {
15
+ throw new TypeError(`${name} must be a canonical non-negative decimal string`);
16
+ }
17
+ if (BigInt(sequence) > MAX_SQLITE_ROWID) {
18
+ throw new RangeError(`${name} exceeds the SQLite rowid range`);
19
+ }
20
+ return sequence;
20
21
  }
21
-
22
22
  function messageSequenceFromSql(value, name = 'message sequence') {
23
- if (typeof value === 'bigint') {
24
- if (value < 0n || value > MAX_SQLITE_ROWID) {
25
- throw new RangeError(`${name} is outside the SQLite rowid range`);
23
+ if (typeof value === 'bigint') {
24
+ if (value < 0n || value > MAX_SQLITE_ROWID) {
25
+ throw new RangeError(`${name} is outside the SQLite rowid range`);
26
+ }
27
+ return value.toString();
26
28
  }
27
- return value.toString();
28
- }
29
- return canonicalMessageSequence(value, name);
29
+ return canonicalMessageSequence(value, name);
30
30
  }
31
-
32
31
  function messageSequenceToSql(value, name = 'message sequence') {
33
- return BigInt(canonicalMessageSequence(value, name));
32
+ return BigInt(canonicalMessageSequence(value, name));
34
33
  }
35
-
36
34
  function compareMessageSequences(left, right) {
37
- const leftValue = messageSequenceToSql(left, 'left message sequence');
38
- const rightValue = messageSequenceToSql(right, 'right message sequence');
39
- if (leftValue < rightValue) {
40
- return -1;
41
- }
42
- if (leftValue > rightValue) {
43
- return 1;
44
- }
45
- return 0;
35
+ const leftValue = messageSequenceToSql(left, 'left message sequence');
36
+ const rightValue = messageSequenceToSql(right, 'right message sequence');
37
+ if (leftValue < rightValue) {
38
+ return -1;
39
+ }
40
+ if (leftValue > rightValue) {
41
+ return 1;
42
+ }
43
+ return 0;
46
44
  }
47
-
48
45
  function tryCanonicalMessageSequence(value) {
49
- try {
50
- return canonicalMessageSequence(value);
51
- } catch {
52
- return null;
53
- }
46
+ try {
47
+ return canonicalMessageSequence(value);
48
+ }
49
+ catch {
50
+ return null;
51
+ }
54
52
  }
55
-
56
53
  module.exports = {
57
- MAX_SQLITE_ROWID,
58
- canonicalMessageSequence,
59
- compareMessageSequences,
60
- messageSequenceFromSql,
61
- messageSequenceToSql,
62
- tryCanonicalMessageSequence,
54
+ MAX_SQLITE_ROWID,
55
+ canonicalMessageSequence,
56
+ compareMessageSequences,
57
+ messageSequenceFromSql,
58
+ messageSequenceToSql,
59
+ tryCanonicalMessageSequence,
63
60
  };
@@ -0,0 +1,63 @@
1
+ const MAX_SQLITE_ROWID = 9223372036854775807n;
2
+ const CANONICAL_SEQUENCE = /^(0|[1-9][0-9]*)$/;
3
+
4
+ function canonicalMessageSequence(value: unknown, name = 'message sequence'): string {
5
+ let sequence: string;
6
+ if (typeof value === 'string' && CANONICAL_SEQUENCE.test(value)) {
7
+ sequence = value;
8
+ } else if (typeof value === 'number' && Number.isSafeInteger(value) && value >= 0) {
9
+ // Accept legacy JSON state while normalizing every new boundary to a
10
+ // JSON-safe decimal string.
11
+ sequence = String(value);
12
+ } else {
13
+ throw new TypeError(`${name} must be a canonical non-negative decimal string`);
14
+ }
15
+
16
+ if (BigInt(sequence) > MAX_SQLITE_ROWID) {
17
+ throw new RangeError(`${name} exceeds the SQLite rowid range`);
18
+ }
19
+ return sequence;
20
+ }
21
+
22
+ function messageSequenceFromSql(value: unknown, name = 'message sequence'): string {
23
+ if (typeof value === 'bigint') {
24
+ if (value < 0n || value > MAX_SQLITE_ROWID) {
25
+ throw new RangeError(`${name} is outside the SQLite rowid range`);
26
+ }
27
+ return value.toString();
28
+ }
29
+ return canonicalMessageSequence(value, name);
30
+ }
31
+
32
+ function messageSequenceToSql(value: unknown, name = 'message sequence'): bigint {
33
+ return BigInt(canonicalMessageSequence(value, name));
34
+ }
35
+
36
+ function compareMessageSequences(left: unknown, right: unknown): -1 | 0 | 1 {
37
+ const leftValue = messageSequenceToSql(left, 'left message sequence');
38
+ const rightValue = messageSequenceToSql(right, 'right message sequence');
39
+ if (leftValue < rightValue) {
40
+ return -1;
41
+ }
42
+ if (leftValue > rightValue) {
43
+ return 1;
44
+ }
45
+ return 0;
46
+ }
47
+
48
+ function tryCanonicalMessageSequence(value: unknown): string | null {
49
+ try {
50
+ return canonicalMessageSequence(value);
51
+ } catch {
52
+ return null;
53
+ }
54
+ }
55
+
56
+ export = {
57
+ MAX_SQLITE_ROWID,
58
+ canonicalMessageSequence,
59
+ compareMessageSequences,
60
+ messageSequenceFromSql,
61
+ messageSequenceToSql,
62
+ tryCanonicalMessageSequence,
63
+ };
@@ -0,0 +1,40 @@
1
+ /**
2
+ * Single read/write path for clusters.json.
3
+ *
4
+ * All callers that need the raw registry (Orchestrator, id-detector, gc,
5
+ * socket-discovery, CLI) go through readClustersFileSync/writeClustersFileAtomic
6
+ * instead of ad-hoc JSON.parse(fs.readFileSync(...)) / fs.writeFileSync(...).
7
+ *
8
+ * Writes are atomic (temp file + rename) so a reader can never observe a
9
+ * partially-written file, even without taking the write lock. Callers that
10
+ * read-modify-write (Orchestrator._saveClusters) still need proper-lockfile
11
+ * around the whole operation to avoid losing concurrent updates.
12
+ */
13
+
14
+ import fs = require('fs');
15
+ import path = require('path');
16
+
17
+ function clustersFilePath(storageDir: string): string {
18
+ return path.join(storageDir, 'clusters.json');
19
+ }
20
+
21
+ /** Read clusters.json. Returns an empty registry if the file is missing. */
22
+ function readClustersFileSync(storageDir: string): unknown {
23
+ const clustersFile = clustersFilePath(storageDir);
24
+ if (!fs.existsSync(clustersFile)) {
25
+ return {};
26
+ }
27
+ const raw = fs.readFileSync(clustersFile, 'utf8');
28
+ const parsed: unknown = JSON.parse(raw);
29
+ return parsed;
30
+ }
31
+
32
+ /** Write clusters.json atomically through a process-scoped temporary file. */
33
+ function writeClustersFileAtomic(storageDir: string, data: unknown): void {
34
+ const clustersFile = clustersFilePath(storageDir);
35
+ const tmpPath = `${clustersFile}.tmp-${process.pid}`;
36
+ fs.writeFileSync(tmpPath, JSON.stringify(data, null, 2));
37
+ fs.renameSync(tmpPath, clustersFile);
38
+ }
39
+
40
+ export = { clustersFilePath, readClustersFileSync, writeClustersFileAtomic };