@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,543 +1,126 @@
1
- /**
2
- * AttachServer - PTY process manager with socket server for attach/detach
3
- *
4
- * Lifecycle:
5
- * 1. Created when task/agent spawns
6
- * 2. Spawns command via node-pty
7
- * 3. Listens on Unix socket for client connections
8
- * 4. Buffers output in ring buffer (for late-joining clients)
9
- * 5. Broadcasts output to all connected clients
10
- * 6. Cleans up when process exits
11
- *
12
- * Features:
13
- * - Multi-client support (multiple terminals can attach)
14
- * - Output history replay on attach
15
- * - Signal forwarding (SIGINT, SIGTERM)
16
- * - Window resize support
17
- * - Graceful cleanup on exit
18
- */
19
-
20
- const net = require('net');
21
- const fs = require('fs');
22
- const path = require('path');
23
- const EventEmitter = require('events');
24
-
25
- const RingBuffer = require('./ring-buffer');
26
- const protocol = require('./protocol');
27
- const { cleanupStaleSocket } = require('./socket-discovery');
28
-
29
- // FAIL FAST: Check for node-pty at module load time, not at spawn time
30
- let pty;
31
- try {
32
- pty = require('node-pty');
33
- } catch (e) {
34
- throw new Error(
35
- `AttachServer: node-pty not installed. Run: npm install node-pty\n` +
36
- `Original error: ${e.message}`
37
- );
38
- }
39
-
40
- // Default output buffer size: 1MB
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ const node_events_1 = require("node:events");
6
+ const node_fs_1 = __importDefault(require("node:fs"));
7
+ const node_path_1 = __importDefault(require("node:path"));
8
+ const ring_buffer_1 = __importDefault(require("./ring-buffer"));
9
+ const socket_discovery_1 = __importDefault(require("./socket-discovery"));
10
+ const attach_server_clients_1 = require("./attach-server-clients");
11
+ const attach_server_cleanup_1 = require("./attach-server-cleanup");
12
+ const attach_server_events_1 = require("./attach-server-events");
13
+ const attach_server_pty_1 = require("./attach-server-pty");
14
+ const attach_server_runtime_1 = require("./attach-server-runtime");
15
+ const attach_server_socket_1 = require("./attach-server-socket");
41
16
  const DEFAULT_BUFFER_SIZE = 1024 * 1024;
42
-
43
- class AttachServer extends EventEmitter {
44
- /**
45
- * @param {object} options
46
- * @param {string} options.id - Task or agent ID
47
- * @param {string} options.socketPath - Unix socket path
48
- * @param {string} options.command - Command to spawn
49
- * @param {string[]} options.args - Command arguments
50
- * @param {string} [options.cwd] - Working directory
51
- * @param {object} [options.env] - Environment variables
52
- * @param {number} [options.cols] - Terminal columns (default 120)
53
- * @param {number} [options.rows] - Terminal rows (default 30)
54
- * @param {number} [options.bufferSize] - Output buffer size (default 1MB)
55
- */
56
- constructor(options) {
57
- super();
58
-
59
- if (!options.id) throw new Error('AttachServer: id is required');
60
- if (!options.socketPath) throw new Error('AttachServer: socketPath is required');
61
- if (!options.command) throw new Error('AttachServer: command is required');
62
-
63
- this.id = options.id;
64
- this.socketPath = options.socketPath;
65
- this.command = options.command;
66
- this.args = options.args || [];
67
- this.cwd = options.cwd || process.cwd();
68
- this.env = options.env || process.env;
69
- this.cols = options.cols || 120;
70
- this.rows = options.rows || 30;
71
-
72
- this.outputBuffer = new RingBuffer(options.bufferSize || DEFAULT_BUFFER_SIZE);
73
- this.clients = new Map(); // clientId -> { socket, decoder }
74
- this.pty = null;
75
- this.server = null;
76
- this.state = 'stopped'; // stopped, starting, running, exiting, exited
77
- this.exitCode = null;
78
- this.exitSignal = null;
79
- this.pid = null;
80
-
81
- // Bind cleanup handlers
82
- this._onProcessExit = this._onProcessExit.bind(this);
83
- this._onServerError = this._onServerError.bind(this);
84
- }
85
-
86
- /**
87
- * Start the PTY process and socket server
88
- * @returns {Promise<void>}
89
- */
90
- async start() {
91
- if (this.state !== 'stopped') {
92
- throw new Error(`AttachServer: Cannot start from state '${this.state}'`);
93
- }
94
-
95
- this.state = 'starting';
96
-
97
- // Ensure socket directory exists
98
- const socketDir = path.dirname(this.socketPath);
99
- if (!fs.existsSync(socketDir)) {
100
- fs.mkdirSync(socketDir, { recursive: true });
101
- }
102
-
103
- // Clean up stale socket if exists
104
- await cleanupStaleSocket(this.socketPath);
105
-
106
- // Check if socket is still in use (another process)
107
- if (fs.existsSync(this.socketPath)) {
108
- throw new Error(`AttachServer: Socket already in use: ${this.socketPath}`);
109
- }
110
-
111
- // Start socket server FIRST (so clients can connect immediately)
112
- await this._startServer();
113
-
114
- // Spawn PTY process
115
- await this._spawnPty();
116
-
117
- this.state = 'running';
118
- this.emit('start', { id: this.id, pid: this.pid });
119
- }
120
-
121
- /**
122
- * Stop the server and kill the PTY process
123
- * @param {string} [signal='SIGTERM'] - Signal to send
124
- * @returns {Promise<void>}
125
- */
126
- async stop(signal = 'SIGTERM') {
127
- if (this.state !== 'running') {
128
- return;
129
- }
130
-
131
- this.state = 'exiting';
132
-
133
- // Kill PTY process
134
- if (this.pty) {
135
- try {
136
- this.pty.kill(signal);
137
- } catch {
138
- // Process may already be dead
139
- }
140
- }
141
-
142
- // Wait for process to exit (with timeout)
143
- await new Promise((resolve) => {
144
- const timeout = setTimeout(() => {
145
- // Force kill if still running
146
- if (this.pty) {
147
- try {
148
- this.pty.kill('SIGKILL');
149
- } catch {
150
- // Ignore
151
- }
17
+ const { cleanupStaleSocket } = socket_discovery_1.default;
18
+ class AttachServer extends node_events_1.EventEmitter {
19
+ id;
20
+ socketPath;
21
+ command;
22
+ args;
23
+ cwd;
24
+ env;
25
+ cols;
26
+ rows;
27
+ outputBuffer;
28
+ clients = new Map();
29
+ pty = null;
30
+ server = null;
31
+ state = 'stopped';
32
+ exitCode = null;
33
+ exitSignal = null;
34
+ pid = null;
35
+ constructor(options) {
36
+ super();
37
+ if (!options.id)
38
+ throw new Error('AttachServer: id is required');
39
+ if (!options.socketPath)
40
+ throw new Error('AttachServer: socketPath is required');
41
+ if (!options.command)
42
+ throw new Error('AttachServer: command is required');
43
+ this.id = options.id;
44
+ this.socketPath = options.socketPath;
45
+ this.command = options.command;
46
+ this.args = options.args || [];
47
+ this.cwd = options.cwd || process.cwd();
48
+ this.env = options.env || process.env;
49
+ this.cols = options.cols || 120;
50
+ this.rows = options.rows || 30;
51
+ this.outputBuffer = new ring_buffer_1.default(options.bufferSize || DEFAULT_BUFFER_SIZE);
52
+ this._onProcessExit = this._onProcessExit.bind(this);
53
+ this._onServerError = this._onServerError.bind(this);
54
+ }
55
+ async start() {
56
+ if (this.state !== 'stopped') {
57
+ throw new Error(`AttachServer: Cannot start from state '${this.state}'`);
152
58
  }
153
- resolve();
154
- }, 5000);
155
-
156
- const checkExit = () => {
157
- if (this.state === 'exited') {
158
- clearTimeout(timeout);
159
- resolve();
160
- } else {
161
- setTimeout(checkExit, 100);
59
+ this.state = 'starting';
60
+ const socketDir = node_path_1.default.dirname(this.socketPath);
61
+ if (!node_fs_1.default.existsSync(socketDir))
62
+ node_fs_1.default.mkdirSync(socketDir, { recursive: true });
63
+ await cleanupStaleSocket(this.socketPath);
64
+ if (node_fs_1.default.existsSync(this.socketPath)) {
65
+ throw new Error(`AttachServer: Socket already in use: ${this.socketPath}`);
162
66
  }
163
- };
164
- checkExit();
165
- });
166
-
167
- await this._cleanup();
168
- }
169
-
170
- /**
171
- * Send a signal to the PTY process
172
- * @param {string} signal - Signal name (SIGINT, SIGTERM, etc.)
173
- */
174
- sendSignal(signal) {
175
- if (!this.pty || this.state !== 'running') {
176
- return false;
67
+ await this._startServer();
68
+ await this._spawnPty();
69
+ this.state = 'running';
70
+ this.emit('start', { id: this.id, pid: this.pid });
177
71
  }
178
-
179
- try {
180
- this.pty.kill(signal);
181
- return true;
182
- } catch {
183
- return false;
72
+ async stop(signal = 'SIGTERM') {
73
+ await (0, attach_server_runtime_1.stopPty)(this, signal);
184
74
  }
185
- }
186
-
187
- /**
188
- * Resize the PTY
189
- * @param {number} cols - Columns
190
- * @param {number} rows - Rows
191
- */
192
- resize(cols, rows) {
193
- if (!this.pty || this.state !== 'running') {
194
- return;
75
+ sendSignal(signal) {
76
+ return (0, attach_server_runtime_1.sendPtySignal)(this, signal);
195
77
  }
196
-
197
- this.cols = cols;
198
- this.rows = rows;
199
-
200
- try {
201
- this.pty.resize(cols, rows);
202
- } catch {
203
- // Ignore resize errors
78
+ resize(cols, rows) {
79
+ (0, attach_server_runtime_1.resizePty)(this, cols, rows);
204
80
  }
205
- }
206
-
207
- /**
208
- * Write to PTY stdin (for future interactive mode)
209
- * @param {Buffer|string} data - Data to write
210
- */
211
- write(data) {
212
- if (!this.pty || this.state !== 'running') {
213
- return false;
81
+ write(data) {
82
+ return (0, attach_server_runtime_1.writePty)(this, data);
214
83
  }
215
-
216
- try {
217
- this.pty.write(data);
218
- return true;
219
- } catch {
220
- return false;
84
+ getState() {
85
+ return {
86
+ id: this.id,
87
+ state: this.state,
88
+ pid: this.pid,
89
+ exitCode: this.exitCode,
90
+ exitSignal: this.exitSignal,
91
+ clientCount: this.clients.size,
92
+ bufferSize: this.outputBuffer.getSize(),
93
+ };
221
94
  }
222
- }
223
-
224
- /**
225
- * Get current server state
226
- * @returns {object}
227
- */
228
- getState() {
229
- return {
230
- id: this.id,
231
- state: this.state,
232
- pid: this.pid,
233
- exitCode: this.exitCode,
234
- exitSignal: this.exitSignal,
235
- clientCount: this.clients.size,
236
- bufferSize: this.outputBuffer.getSize(),
237
- };
238
- }
239
-
240
- // ─────────────────────────────────────────────────────────────────
241
- // Private methods
242
- // ─────────────────────────────────────────────────────────────────
243
-
244
- /**
245
- * Start the Unix socket server
246
- * @private
247
- */
248
- _startServer() {
249
- return new Promise((resolve, reject) => {
250
- this.server = net.createServer((socket) => {
251
- this._handleClientConnection(socket);
252
- });
253
-
254
- this.server.on('error', this._onServerError);
255
-
256
- this.server.listen(this.socketPath, () => {
257
- // Set socket permissions (owner read/write only)
258
- try {
259
- fs.chmodSync(this.socketPath, 0o600);
260
- } catch {
261
- // Ignore permission errors
262
- }
263
- resolve();
264
- });
265
-
266
- this.server.on('error', (err) => {
267
- if (this.state === 'starting') {
268
- reject(err);
269
- }
270
- });
271
- });
272
- }
273
-
274
- /**
275
- * Spawn the PTY process
276
- * @private
277
- */
278
- _spawnPty() {
279
- this.pty = pty.spawn(this.command, this.args, {
280
- name: 'xterm-256color',
281
- cols: this.cols,
282
- rows: this.rows,
283
- cwd: this.cwd,
284
- env: this.env,
285
- });
286
-
287
- this.pid = this.pty.pid;
288
-
289
- // Handle PTY output
290
- this.pty.onData((data) => {
291
- this._handlePtyOutput(data);
292
- });
293
-
294
- // Handle PTY exit
295
- this.pty.onExit(({ exitCode, signal }) => {
296
- this._onProcessExit(exitCode, signal);
297
- });
298
- }
299
-
300
- /**
301
- * Handle PTY output
302
- * @private
303
- */
304
- _handlePtyOutput(data) {
305
- // Buffer output for late-joining clients
306
- this.outputBuffer.write(data);
307
-
308
- // Broadcast to all connected clients
309
- const message = protocol.encode(protocol.createOutputMessage(data));
310
-
311
- for (const [clientId, client] of this.clients) {
312
- try {
313
- client.socket.write(message);
314
- } catch {
315
- // Client disconnected, will be cleaned up
316
- this._removeClient(clientId);
317
- }
95
+ _startServer() {
96
+ return (0, attach_server_socket_1.startSocketServer)(this);
318
97
  }
319
-
320
- // Emit for local listeners (e.g., logging)
321
- this.emit('output', data);
322
- }
323
-
324
- /**
325
- * Handle new client connection
326
- * @private
327
- */
328
- _handleClientConnection(socket) {
329
- const decoder = new protocol.MessageDecoder();
330
- let clientId = null;
331
-
332
- socket.on('data', (data) => {
333
- try {
334
- const messages = decoder.feed(data);
335
- for (const msg of messages) {
336
- this._handleClientMessage(socket, msg, (id) => {
337
- clientId = id;
338
- });
339
- }
340
- } catch (e) {
341
- // Protocol error, close connection
342
- this._sendError(socket, `Protocol error: ${e.message}`);
343
- socket.end();
344
- }
345
- });
346
-
347
- socket.on('close', () => {
348
- if (clientId) {
349
- this._removeClient(clientId);
350
- }
351
- });
352
-
353
- socket.on('error', () => {
354
- if (clientId) {
355
- this._removeClient(clientId);
356
- }
357
- });
358
- }
359
-
360
- /**
361
- * Handle message from client
362
- * @private
363
- */
364
- _handleClientMessage(socket, message, setClientId) {
365
- switch (message.type) {
366
- case protocol.MessageType.ATTACH: {
367
- const { clientId, cols, rows } = message;
368
- if (!clientId) {
369
- this._sendError(socket, 'ATTACH requires clientId');
370
- return;
371
- }
372
-
373
- // Register client
374
- this.clients.set(clientId, {
375
- socket,
376
- decoder: new protocol.MessageDecoder(),
377
- });
378
- setClientId(clientId);
379
-
380
- // Send history (buffered output)
381
- const history = this.outputBuffer.read();
382
- if (history.length > 0) {
383
- socket.write(protocol.encode(protocol.createHistoryMessage(history)));
384
- }
385
-
386
- // Send current state
387
- socket.write(protocol.encode(protocol.createStateMessage(this.getState())));
388
-
389
- // Resize PTY to client dimensions (if provided)
390
- if (cols && rows) {
391
- this.resize(cols, rows);
392
- }
393
-
394
- this.emit('clientAttach', { clientId });
395
- break;
396
- }
397
-
398
- case protocol.MessageType.DETACH: {
399
- const { clientId } = message;
400
- this._removeClient(clientId);
401
- socket.end();
402
- break;
403
- }
404
-
405
- case protocol.MessageType.RESIZE: {
406
- const { cols, rows } = message;
407
- if (cols && rows) {
408
- this.resize(cols, rows);
409
- }
410
- break;
411
- }
412
-
413
- case protocol.MessageType.SIGNAL: {
414
- const { signal } = message;
415
- this.sendSignal(signal);
416
- break;
417
- }
418
-
419
- case protocol.MessageType.STDIN: {
420
- // Future interactive mode
421
- const data = protocol.decodeData(message);
422
- if (data) {
423
- this.write(data);
424
- }
425
- break;
426
- }
427
-
428
- default:
429
- this._sendError(socket, `Unknown message type: ${message.type}`);
98
+ _spawnPty() {
99
+ (0, attach_server_pty_1.spawnPty)(this);
430
100
  }
431
- }
432
-
433
- /**
434
- * Remove a client
435
- * @private
436
- */
437
- _removeClient(clientId) {
438
- const client = this.clients.get(clientId);
439
- if (client) {
440
- this.clients.delete(clientId);
441
- this.emit('clientDetach', { clientId });
101
+ _handlePtyOutput(data) {
102
+ (0, attach_server_events_1.handlePtyOutput)(this, data);
442
103
  }
443
- }
444
-
445
- /**
446
- * Send error message to client
447
- * @private
448
- */
449
- _sendError(socket, message) {
450
- try {
451
- socket.write(protocol.encode(protocol.createErrorMessage(message)));
452
- } catch {
453
- // Client disconnected
104
+ _handleClientConnection(socket) {
105
+ (0, attach_server_clients_1.handleClientConnection)(this, socket);
454
106
  }
455
- }
456
-
457
- /**
458
- * Handle PTY process exit
459
- * @private
460
- */
461
- _onProcessExit(exitCode, signal) {
462
- this.exitCode = exitCode;
463
- this.exitSignal = signal;
464
- this.state = 'exited';
465
-
466
- // Notify all clients
467
- const exitMessage = protocol.encode(protocol.createExitMessage(exitCode, signal));
468
-
469
- for (const [, client] of this.clients) {
470
- try {
471
- client.socket.write(exitMessage);
472
- client.socket.end();
473
- } catch {
474
- // Client already disconnected
475
- }
107
+ _handleClientMessage(socket, message, setClientId) {
108
+ (0, attach_server_clients_1.handleClientMessage)(this, socket, message, setClientId);
476
109
  }
477
-
478
- this.emit('exit', { exitCode, signal });
479
-
480
- // Clean up after short delay (allow clients to receive exit message)
481
- setTimeout(() => {
482
- this._cleanup();
483
- }, 500);
484
- }
485
-
486
- /**
487
- * Handle server error
488
- * @private
489
- */
490
- _onServerError(err) {
491
- this.emit('error', err);
492
- }
493
-
494
- /**
495
- * Clean up resources
496
- * @private
497
- */
498
- async _cleanup() {
499
- // Close all client connections
500
- for (const [, client] of this.clients) {
501
- try {
502
- client.socket.destroy();
503
- } catch {
504
- // Ignore
505
- }
110
+ _removeClient(clientId) {
111
+ (0, attach_server_clients_1.removeClient)(this, clientId);
506
112
  }
507
- this.clients.clear();
508
-
509
- // Close server
510
- if (this.server) {
511
- await new Promise((resolve) => {
512
- this.server.close(() => resolve());
513
- });
514
- this.server = null;
113
+ _sendError(socket, message) {
114
+ (0, attach_server_clients_1.sendClientError)(socket, message);
515
115
  }
516
-
517
- // Remove socket file
518
- if (fs.existsSync(this.socketPath)) {
519
- try {
520
- fs.unlinkSync(this.socketPath);
521
- } catch {
522
- // Ignore
523
- }
116
+ _onProcessExit(exitCode, signal) {
117
+ (0, attach_server_events_1.handleProcessExit)(this, exitCode, signal);
524
118
  }
525
-
526
- // Clean up empty parent directory for cluster sockets
527
- const socketDir = path.dirname(this.socketPath);
528
- if (socketDir.includes('cluster-')) {
529
- try {
530
- const files = fs.readdirSync(socketDir);
531
- if (files.length === 0) {
532
- fs.rmdirSync(socketDir);
533
- }
534
- } catch {
535
- // Ignore
536
- }
119
+ _onServerError(error) {
120
+ this.emit('error', error);
121
+ }
122
+ async _cleanup() {
123
+ await (0, attach_server_cleanup_1.cleanupAttachServer)(this);
537
124
  }
538
-
539
- this.emit('cleanup');
540
- }
541
125
  }
542
-
543
126
  module.exports = AttachServer;