@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
@@ -1,248 +1,182 @@
1
+ "use strict";
1
2
  /**
2
3
  * Git remote URL parsing and provider detection.
3
4
  * Automatically detects issue provider from git remote URL.
4
5
  */
5
-
6
- const { execSync } = require('../src/lib/safe-exec');
7
-
6
+ // eslint-disable-next-line @typescript-eslint/no-unsafe-assignment
7
+ const safeExec = require('../src/lib/safe-exec');
8
+ const { execSync } = safeExec;
8
9
  function hasInvalidGitRefCharacter(value) {
9
- for (const character of value) {
10
- const codePoint = character.codePointAt(0);
11
- if (codePoint <= 0x20 || codePoint === 0x7f || '~^:?*[\\'.includes(character)) {
12
- return true;
10
+ for (const character of value) {
11
+ const codePoint = character.codePointAt(0);
12
+ if (codePoint === undefined ||
13
+ codePoint <= 0x20 ||
14
+ codePoint === 0x7f ||
15
+ '~^:?*[\\'.includes(character)) {
16
+ return true;
17
+ }
13
18
  }
14
- }
15
- return false;
19
+ return false;
16
20
  }
17
-
18
21
  /**
19
22
  * Normalize a Git remote name using the same ref-format rules Git applies to
20
23
  * refs/remotes/<name>. Keeping this next to detection prevents a discovered
21
24
  * remote from being rejected later by a narrower consumer-specific allowlist.
22
- *
23
- * @param {unknown} value - Candidate remote name
24
- * @returns {string|null} Normalized remote name, or null when invalid
25
25
  */
26
26
  function normalizeGitRemoteName(value) {
27
- if (typeof value !== 'string') {
28
- return null;
29
- }
30
-
31
- const name = value.trim();
32
- if (
33
- name.length === 0 ||
34
- name.endsWith('.') ||
35
- name.includes('..') ||
36
- name.includes('@{') ||
37
- hasInvalidGitRefCharacter(name)
38
- ) {
39
- return null;
40
- }
41
-
42
- const components = name.split('/');
43
- if (
44
- components.some(
45
- (component) =>
46
- component.length === 0 || component.startsWith('.') || component.endsWith('.lock')
47
- )
48
- ) {
49
- return null;
50
- }
51
-
52
- return name;
27
+ if (typeof value !== 'string') {
28
+ return null;
29
+ }
30
+ const name = value.trim();
31
+ if (name.length === 0 ||
32
+ name.endsWith('.') ||
33
+ name.includes('..') ||
34
+ name.includes('@{') ||
35
+ hasInvalidGitRefCharacter(name)) {
36
+ return null;
37
+ }
38
+ const components = name.split('/');
39
+ if (components.some((component) => component.length === 0 || component.startsWith('.') || component.endsWith('.lock'))) {
40
+ return null;
41
+ }
42
+ return name;
53
43
  }
54
-
55
- /**
56
- * Quote one argument for the POSIX shell snippets embedded in agent prompts.
57
- *
58
- * @param {string} value - Argument to quote
59
- * @returns {string} Single-quoted shell argument
60
- */
44
+ /** Quote one argument for the POSIX shell snippets embedded in agent prompts. */
61
45
  function quoteShellArgument(value) {
62
- return `'${value.replaceAll("'", `'"'"'`)}'`;
46
+ return `'${value.replaceAll("'", `'"'"'`)}'`;
63
47
  }
64
-
65
48
  /**
66
49
  * Parse git remote URL into structured provider context.
67
50
  * Supports GitHub, GitLab, and Azure DevOps (cloud + self-hosted).
68
51
  * Handles both HTTPS and SSH URL formats.
69
- *
70
- * @param {string} remoteUrl - Git remote URL
71
- * @returns {Object|null} Provider context or null if unparseable
72
- *
73
- * @example
74
- * parseGitRemoteUrl('https://github.com/org/repo.git')
75
- * // → { provider: 'github', host: 'github.com', org: 'org', repo: 'repo', fullRepo: 'org/repo' }
76
- *
77
- * @example
78
- * parseGitRemoteUrl('git@gitlab.com:org/repo.git')
79
- * // → { provider: 'gitlab', host: 'gitlab.com', org: 'org', repo: 'repo', fullRepo: 'org/repo' }
80
- *
81
- * @example
82
- * parseGitRemoteUrl('https://dev.azure.com/myorg/myproject/_git/myrepo')
83
- * // → { provider: 'azure-devops', host: 'dev.azure.com', azureOrg: 'https://dev.azure.com/myorg', azureProject: 'myproject', repo: 'myrepo' }
84
52
  */
85
53
  function parseGitRemoteUrl(remoteUrl) {
86
- if (!remoteUrl || typeof remoteUrl !== 'string') {
87
- return null;
88
- }
89
-
90
- const url = remoteUrl.trim();
91
-
92
- // Normalize SSH URLs to HTTPS format for easier parsing
93
- // git@host:path → https://host/path
94
- let normalizedUrl = url;
95
- const sshMatch = url.match(/^git@([^:]+):(.+)$/);
96
- if (sshMatch) {
97
- const [, host, path] = sshMatch;
98
- normalizedUrl = `https://${host}/${path}`;
99
- }
100
-
101
- // Remove .git suffix if present
102
- normalizedUrl = normalizedUrl.replace(/\.git$/, '');
103
-
104
- // Azure DevOps: https://dev.azure.com/org/project/_git/repo
105
- // Azure Legacy: https://org.visualstudio.com/project/_git/repo
106
- // Azure SSH: git@ssh.dev.azure.com:v3/org/project/repo
107
- const azureMatch =
108
- normalizedUrl.match(/https:\/\/dev\.azure\.com\/([^/]+)\/([^/]+)\/_git\/([^/]+)/) ||
109
- normalizedUrl.match(/https:\/\/([^.]+)\.visualstudio\.com\/([^/]+)\/_git\/([^/]+)/) ||
110
- // After normalization, `git@ssh.dev.azure.com:v3/org/project/repo` becomes
111
- // `https://ssh.dev.azure.com/v3/org/project/repo`
112
- normalizedUrl.match(/https:\/\/ssh\.dev\.azure\.com\/v3\/([^/]+)\/([^/]+)\/([^/]+)/);
113
-
114
- if (azureMatch) {
115
- const [, orgPart, project, repo] = azureMatch;
116
- // For dev.azure.com, org is the first path segment
117
- // For visualstudio.com, org is the subdomain
118
- const isLegacy = normalizedUrl.includes('visualstudio.com');
119
- const azureOrg = isLegacy
120
- ? `https://${orgPart}.visualstudio.com`
121
- : `https://dev.azure.com/${orgPart}`;
122
-
123
- return {
124
- provider: 'azure-devops',
125
- host: isLegacy ? `${orgPart}.visualstudio.com` : 'dev.azure.com',
126
- azureOrg,
127
- azureProject: project,
128
- repo,
129
- };
130
- }
131
-
132
- // GitHub: https://github.com/org/repo
133
- // GitLab: https://gitlab.com/org/repo (or self-hosted)
134
- // Generic: https://host/org/repo
135
- const httpsMatch = normalizedUrl.match(/https?:\/\/([^/]+)\/([^/]+)\/([^/]+)/);
136
- if (httpsMatch) {
137
- const [, host, org, repo] = httpsMatch;
138
-
139
- let provider = null;
140
- if (host === 'github.com') {
141
- provider = 'github';
142
- } else if (host.includes('gitlab')) {
143
- // Matches gitlab.com or any gitlab.* subdomain or *gitlab* in hostname
144
- provider = 'gitlab';
145
- } else {
146
- // Unknown provider - could be self-hosted GitLab or other
147
- // Return null to fall back to settings
148
- return null;
54
+ if (!remoteUrl || typeof remoteUrl !== 'string') {
55
+ return null;
149
56
  }
150
-
151
- return {
152
- provider,
153
- host,
154
- org,
155
- repo,
156
- fullRepo: `${org}/${repo}`,
157
- };
158
- }
159
-
160
- return null;
57
+ const url = remoteUrl.trim();
58
+ // Normalize SSH URLs to HTTPS format for easier parsing
59
+ // git@host:path → https://host/path
60
+ let normalizedUrl = url;
61
+ const sshMatch = /^git@([^:]+):(.+)$/.exec(url);
62
+ if (sshMatch) {
63
+ const host = sshMatch[1];
64
+ const remotePath = sshMatch[2];
65
+ if (host !== undefined && remotePath !== undefined) {
66
+ normalizedUrl = `https://${host}/${remotePath}`;
67
+ }
68
+ }
69
+ // Remove .git suffix if present
70
+ normalizedUrl = normalizedUrl.replace(/\.git$/, '');
71
+ // Azure DevOps: https://dev.azure.com/org/project/_git/repo
72
+ // Azure Legacy: https://org.visualstudio.com/project/_git/repo
73
+ // Azure SSH: git@ssh.dev.azure.com:v3/org/project/repo
74
+ const azureMatch = /https:\/\/dev\.azure\.com\/([^/]+)\/([^/]+)\/_git\/([^/]+)/.exec(normalizedUrl) ||
75
+ /https:\/\/([^.]+)\.visualstudio\.com\/([^/]+)\/_git\/([^/]+)/.exec(normalizedUrl) ||
76
+ /https:\/\/ssh\.dev\.azure\.com\/v3\/([^/]+)\/([^/]+)\/([^/]+)/.exec(normalizedUrl);
77
+ if (azureMatch) {
78
+ const orgPart = azureMatch[1];
79
+ const project = azureMatch[2];
80
+ const repo = azureMatch[3];
81
+ if (orgPart === undefined || project === undefined || repo === undefined) {
82
+ return null;
83
+ }
84
+ const isLegacy = normalizedUrl.includes('visualstudio.com');
85
+ const azureOrg = isLegacy
86
+ ? `https://${orgPart}.visualstudio.com`
87
+ : `https://dev.azure.com/${orgPart}`;
88
+ return {
89
+ provider: 'azure-devops',
90
+ host: isLegacy ? `${orgPart}.visualstudio.com` : 'dev.azure.com',
91
+ azureOrg,
92
+ azureProject: project,
93
+ repo,
94
+ };
95
+ }
96
+ // GitHub: https://github.com/org/repo
97
+ // GitLab: https://gitlab.com/org/repo (or self-hosted)
98
+ // Generic: https://host/org/repo
99
+ const httpsMatch = /https?:\/\/([^/]+)\/([^/]+)\/([^/]+)/.exec(normalizedUrl);
100
+ if (httpsMatch) {
101
+ const host = httpsMatch[1];
102
+ const org = httpsMatch[2];
103
+ const repo = httpsMatch[3];
104
+ if (host === undefined || org === undefined || repo === undefined) {
105
+ return null;
106
+ }
107
+ let provider;
108
+ if (host === 'github.com') {
109
+ provider = 'github';
110
+ }
111
+ else if (host.includes('gitlab')) {
112
+ provider = 'gitlab';
113
+ }
114
+ else {
115
+ return null;
116
+ }
117
+ return {
118
+ provider,
119
+ host,
120
+ org,
121
+ repo,
122
+ fullRepo: `${org}/${repo}`,
123
+ };
124
+ }
125
+ return null;
161
126
  }
162
-
163
127
  /**
164
128
  * Detect git repository context from current working directory.
165
129
  * Returns provider context extracted from git remote URL.
166
- *
167
- * @param {string} [cwd=process.cwd()] - Directory to check
168
- * @returns {Object|null} Git context or null
169
- *
170
- * Gracefully returns null for:
171
- * - Not in git repository
172
- * - No remote configured
173
- * - Remote URL unparseable
174
- * - Git command fails
175
- *
176
- * @example
177
- * // In a GitHub repo with remote
178
- * detectGitContext()
179
- * // → { provider: 'github', host: 'github.com', org: 'myorg', repo: 'myrepo', fullRepo: 'myorg/myrepo' }
180
- *
181
- * @example
182
- * // Not in git repo or no remote
183
- * detectGitContext()
184
- * // → null
185
130
  */
186
131
  function detectGitContext(cwd = process.cwd()) {
187
- try {
188
- // Check if we're in a git repository
189
- execSync('git rev-parse --git-dir', {
190
- cwd,
191
- stdio: 'pipe',
192
- encoding: 'utf8',
193
- });
194
- } catch {
195
- // Not a git repository
196
- return null;
197
- }
198
-
199
- try {
200
- const remoteOutput = execSync('git remote -v', {
201
- cwd,
202
- stdio: 'pipe',
203
- encoding: 'utf8',
204
- });
205
-
206
- const supportedRemotes = new Map();
207
- for (const line of remoteOutput.split(/\r?\n/)) {
208
- const match = line.match(/^(\S+)\s+(.+)\s+\(fetch\)$/);
209
- if (!match) {
210
- continue;
211
- }
212
-
213
- const [, remoteCandidate, remoteUrl] = match;
214
- const remote = normalizeGitRemoteName(remoteCandidate);
215
- if (!remote) {
216
- continue;
217
- }
218
- const context = parseGitRemoteUrl(remoteUrl);
219
- if (context && !supportedRemotes.has(remote)) {
220
- supportedRemotes.set(remote, { ...context, remote });
221
- }
132
+ try {
133
+ execSync('git rev-parse --git-dir', {
134
+ cwd,
135
+ stdio: 'pipe',
136
+ encoding: 'utf8',
137
+ });
222
138
  }
223
-
224
- // Preserve existing behavior whenever origin is usable. Without origin,
225
- // select a remote only when there is exactly one supported target. Guessing
226
- // between multiple repositories could push code or create a PR in the wrong
227
- // place, so ambiguous configurations deliberately fail closed.
228
- if (supportedRemotes.has('origin')) {
229
- return supportedRemotes.get('origin');
139
+ catch {
140
+ return null;
230
141
  }
231
-
232
- if (supportedRemotes.size === 1) {
233
- return supportedRemotes.values().next().value;
142
+ try {
143
+ const remoteOutput = execSync('git remote -v', {
144
+ cwd,
145
+ stdio: 'pipe',
146
+ encoding: 'utf8',
147
+ });
148
+ const supportedRemotes = new Map();
149
+ for (const line of remoteOutput.split(/\r?\n/)) {
150
+ const match = /^(\S+)\s+(.+)\s+\(fetch\)$/.exec(line);
151
+ if (!match) {
152
+ continue;
153
+ }
154
+ const remoteCandidate = match[1];
155
+ const remoteUrl = match[2];
156
+ const remote = normalizeGitRemoteName(remoteCandidate);
157
+ if (!remote || remoteUrl === undefined) {
158
+ continue;
159
+ }
160
+ const context = parseGitRemoteUrl(remoteUrl);
161
+ if (context && !supportedRemotes.has(remote)) {
162
+ supportedRemotes.set(remote, { ...context, remote });
163
+ }
164
+ }
165
+ if (supportedRemotes.has('origin')) {
166
+ return supportedRemotes.get('origin') ?? null;
167
+ }
168
+ if (supportedRemotes.size === 1) {
169
+ return supportedRemotes.values().next().value ?? null;
170
+ }
171
+ return null;
172
+ }
173
+ catch {
174
+ return null;
234
175
  }
235
-
236
- return null;
237
- } catch {
238
- // No remote configured or command failed
239
- return null;
240
- }
241
176
  }
242
-
243
177
  module.exports = {
244
- normalizeGitRemoteName,
245
- quoteShellArgument,
246
- parseGitRemoteUrl,
247
- detectGitContext,
178
+ normalizeGitRemoteName,
179
+ quoteShellArgument,
180
+ parseGitRemoteUrl,
181
+ detectGitContext,
248
182
  };
@@ -0,0 +1,15 @@
1
+ /**
2
+ * ID Detector - Determines if an ID is a task or cluster
3
+ *
4
+ * Strategy:
5
+ * 1. Check if ID exists in cluster storage
6
+ * 2. If not, check if ID exists in task storage (SQLite)
7
+ * 3. Return type: 'cluster', 'task', or null
8
+ */
9
+ type IdType = 'cluster' | 'task' | null;
10
+ /** Detect if an ID belongs to a cluster or task. */
11
+ declare function detectIdType(id: string): IdType;
12
+ declare const _default: {
13
+ detectIdType: typeof detectIdType;
14
+ };
15
+ export = _default;
@@ -1,3 +1,4 @@
1
+ "use strict";
1
2
  /**
2
3
  * ID Detector - Determines if an ID is a task or cluster
3
4
  *
@@ -6,49 +7,44 @@
6
7
  * 2. If not, check if ID exists in task storage (SQLite)
7
8
  * 3. Return type: 'cluster', 'task', or null
8
9
  */
9
-
10
- const path = require('path');
11
- const fs = require('fs');
12
- const os = require('os');
13
- const Database = require('better-sqlite3');
14
- const { readClustersFileSync } = require('./clusters-registry');
15
-
16
- /**
17
- * Detect if ID is a cluster or task
18
- * @param {string} id - The ID to check
19
- * @returns {'cluster'|'task'|null} - Type of ID or null if not found
20
- */
10
+ const path = require("path");
11
+ const fs = require("fs");
12
+ const os = require("os");
13
+ const Database = require("better-sqlite3");
14
+ const clustersRegistry = require("./clusters-registry");
15
+ function hasClusterId(clusters, id) {
16
+ return Boolean(Reflect.get(Object(clusters), id));
17
+ }
18
+ /** Detect if an ID belongs to a cluster or task. */
21
19
  function detectIdType(id) {
22
- const homeDir =
23
- process.env.ZEROSHOT_HOME || process.env.HOME || process.env.USERPROFILE || os.homedir();
24
- const storageDir = path.join(homeDir, '.zeroshot');
25
- const taskDbFile = path.join(homeDir, '.claude-zeroshot', 'store.db');
26
-
27
- // Check clusters
28
- try {
29
- const clusters = readClustersFileSync(storageDir);
30
- if (clusters[id]) {
31
- return 'cluster';
32
- }
33
- } catch {
34
- // Ignore parse errors
35
- }
36
-
37
- // Check tasks in SQLite
38
- if (fs.existsSync(taskDbFile)) {
20
+ const homeDir = process.env.ZEROSHOT_HOME ||
21
+ process.env.HOME ||
22
+ process.env.USERPROFILE ||
23
+ os.homedir();
24
+ const storageDir = path.join(homeDir, '.zeroshot');
25
+ const taskDbFile = path.join(homeDir, '.claude-zeroshot', 'store.db');
39
26
  try {
40
- const db = new Database(taskDbFile, { readonly: true, timeout: 5000 });
41
- const row = db.prepare('SELECT id FROM tasks WHERE id = ?').get(id);
42
- db.close();
43
- if (row) {
44
- return 'task';
45
- }
46
- } catch {
47
- // Ignore DB errors
27
+ const clusters = clustersRegistry.readClustersFileSync(storageDir);
28
+ if (hasClusterId(clusters, id)) {
29
+ return 'cluster';
30
+ }
31
+ }
32
+ catch {
33
+ // Ignore parse errors
34
+ }
35
+ if (fs.existsSync(taskDbFile)) {
36
+ try {
37
+ const db = new Database(taskDbFile, { readonly: true, timeout: 5000 });
38
+ const row = db.prepare('SELECT id FROM tasks WHERE id = ?').get(id);
39
+ db.close();
40
+ if (row) {
41
+ return 'task';
42
+ }
43
+ }
44
+ catch {
45
+ // Ignore DB errors
46
+ }
48
47
  }
49
- }
50
-
51
- return null;
48
+ return null;
52
49
  }
53
-
54
50
  module.exports = { detectIdType };
@@ -0,0 +1,30 @@
1
+ /**
2
+ * Detects whether the npm global bin directory is on PATH, so we can warn
3
+ * the user when `npm install -g` succeeds but the `zeroshot` binary is
4
+ * unreachable (e.g. non-standard Node installs whose global bin dir isn't
5
+ * exported).
6
+ */
7
+ interface PathCheckOptions {
8
+ readonly installPrefix?: string;
9
+ readonly pathEnv?: string;
10
+ }
11
+ type PathCheckResult = {
12
+ readonly onPath: true;
13
+ readonly binDir: null;
14
+ } | {
15
+ readonly onPath: boolean;
16
+ readonly binDir: string;
17
+ };
18
+ declare function getGlobalBinDir(installPrefix: string): string;
19
+ declare function isDirOnPath(dir: string, pathEnv?: string): boolean;
20
+ declare function getPathExportLine(dir: string): string;
21
+ declare function checkBinDirOnPath(options?: PathCheckOptions): PathCheckResult;
22
+ declare function printPathWarning(binDir: string): void;
23
+ declare const _default: {
24
+ getGlobalBinDir: typeof getGlobalBinDir;
25
+ isDirOnPath: typeof isDirOnPath;
26
+ getPathExportLine: typeof getPathExportLine;
27
+ checkBinDirOnPath: typeof checkBinDirOnPath;
28
+ printPathWarning: typeof printPathWarning;
29
+ };
30
+ export = _default;
package/lib/path-check.js CHANGED
@@ -1,63 +1,60 @@
1
+ "use strict";
1
2
  /**
2
3
  * Detects whether the npm global bin directory is on PATH, so we can warn
3
4
  * the user when `npm install -g` succeeds but the `zeroshot` binary is
4
5
  * unreachable (e.g. non-standard Node installs whose global bin dir isn't
5
6
  * exported).
6
7
  */
7
-
8
- const path = require('path');
9
-
8
+ const path = require("path");
9
+ function isUpdateCheckerModule(value) {
10
+ return (typeof value === 'object' &&
11
+ value !== null &&
12
+ 'getInstallPrefix' in value &&
13
+ typeof value.getInstallPrefix === 'function');
14
+ }
10
15
  function getGlobalBinDir(installPrefix) {
11
- if (process.platform === 'win32') {
12
- return installPrefix;
13
- }
14
-
15
- return path.join(installPrefix, 'bin');
16
+ if (process.platform === 'win32') {
17
+ return installPrefix;
18
+ }
19
+ return path.join(installPrefix, 'bin');
16
20
  }
17
-
18
21
  function isDirOnPath(dir, pathEnv = process.env.PATH || '') {
19
- const resolvedDir = path.resolve(dir);
20
-
21
- return pathEnv
22
- .split(path.delimiter)
23
- .filter((entry) => entry.length > 0)
24
- .some((entry) => path.resolve(entry) === resolvedDir);
22
+ const resolvedDir = path.resolve(dir);
23
+ return pathEnv
24
+ .split(path.delimiter)
25
+ .filter((entry) => entry.length > 0)
26
+ .some((entry) => path.resolve(entry) === resolvedDir);
25
27
  }
26
-
27
28
  function getPathExportLine(dir) {
28
- return `export PATH="${dir}:$PATH"`;
29
+ return `export PATH="${dir}:$PATH"`;
29
30
  }
30
-
31
31
  function checkBinDirOnPath(options = {}) {
32
- if (process.platform === 'win32') {
33
- return { onPath: true, binDir: null };
34
- }
35
-
36
- try {
37
- const { getInstallPrefix } = require('../cli/lib/update-checker');
38
- const installPrefix = options.installPrefix || getInstallPrefix(options);
39
- const binDir = getGlobalBinDir(installPrefix);
40
-
41
- return { onPath: isDirOnPath(binDir, options.pathEnv), binDir };
42
- } catch {
43
- return { onPath: true, binDir: null };
44
- }
32
+ if (process.platform === 'win32') {
33
+ return { onPath: true, binDir: null };
34
+ }
35
+ try {
36
+ const updateChecker = require('../cli/lib/update-checker');
37
+ if (!isUpdateCheckerModule(updateChecker)) {
38
+ throw new TypeError('update-checker must export getInstallPrefix');
39
+ }
40
+ const { getInstallPrefix } = updateChecker;
41
+ const installPrefix = options.installPrefix || getInstallPrefix(options);
42
+ const binDir = getGlobalBinDir(installPrefix);
43
+ return { onPath: isDirOnPath(binDir, options.pathEnv), binDir };
44
+ }
45
+ catch {
46
+ return { onPath: true, binDir: null };
47
+ }
45
48
  }
46
-
47
49
  function printPathWarning(binDir) {
48
- console.error(
49
- `[zeroshot] Warning: ${binDir} is not on your PATH — the 'zeroshot' command may not be found.`
50
- );
51
- console.error(` ${getPathExportLine(binDir)}`);
52
- console.error(
53
- ' Add this line to your shell profile (~/.zshrc, ~/.bashrc, or ~/.profile) to fix this permanently.'
54
- );
50
+ console.error(`[zeroshot] Warning: ${binDir} is not on your PATH — the 'zeroshot' command may not be found.`);
51
+ console.error(` ${getPathExportLine(binDir)}`);
52
+ console.error(' Add this line to your shell profile (~/.zshrc, ~/.bashrc, or ~/.profile) to fix this permanently.');
55
53
  }
56
-
57
54
  module.exports = {
58
- getGlobalBinDir,
59
- isDirOnPath,
60
- getPathExportLine,
61
- checkBinDirOnPath,
62
- printPathWarning,
55
+ getGlobalBinDir,
56
+ isDirOnPath,
57
+ getPathExportLine,
58
+ checkBinDirOnPath,
59
+ printPathWarning,
63
60
  };
@@ -0,0 +1,16 @@
1
+ /**
2
+ * Single source of truth for "is this PID actually alive?"
3
+ *
4
+ * Previously this check was reimplemented separately in src/orchestrator.js
5
+ * (_isProcessRunning) and lib/detached-startup.js (isProcessAlive), plus an
6
+ * inline copy in _getActiveClustersForIssue. Four of those call sites agreed
7
+ * on the answer; the resume() eligibility guard trusted persisted cluster
8
+ * state instead of asking the OS, which is what let a dead-PID cluster be
9
+ * simultaneously reported as "zombie" by status and "still running" by
10
+ * resume. Consolidating avoids a sixth call site reintroducing that split.
11
+ */
12
+ declare function isProcessRunning(pid: unknown): boolean;
13
+ declare const _default: {
14
+ isProcessRunning: typeof isProcessRunning;
15
+ };
16
+ export = _default;