@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,181 @@
1
+ /**
2
+ * Protocol - Message framing for attach/detach IPC
3
+ *
4
+ * Uses length-prefixed JSON messages over Unix sockets.
5
+ * Format: [4-byte length (BE)] [JSON payload]
6
+ */
7
+
8
+ const MAX_MESSAGE_SIZE = 10 * 1024 * 1024; // 10MB max message
9
+
10
+ const MessageType = {
11
+ // Client → Server
12
+ ATTACH: 'attach',
13
+ DETACH: 'detach',
14
+ RESIZE: 'resize',
15
+ SIGNAL: 'signal',
16
+ STDIN: 'stdin',
17
+
18
+ // Server → Client
19
+ OUTPUT: 'output',
20
+ HISTORY: 'history',
21
+ STATE: 'state',
22
+ EXIT: 'exit',
23
+ ERROR: 'error',
24
+ } as const;
25
+
26
+ type BinaryData = Buffer | string;
27
+ type MessageWithData = { data?: string | null };
28
+ type AttachMessage = {
29
+ type: typeof MessageType.ATTACH;
30
+ clientId: string;
31
+ cols: number;
32
+ rows: number;
33
+ };
34
+ type DetachMessage = { type: typeof MessageType.DETACH; clientId: string };
35
+ type ResizeMessage = { type: typeof MessageType.RESIZE; cols: number; rows: number };
36
+ type SignalMessage = { type: typeof MessageType.SIGNAL; signal: string };
37
+ type DataMessage<T extends string> = { type: T; data: string };
38
+ type OutputMessage = DataMessage<typeof MessageType.OUTPUT> & { timestamp: number };
39
+ type ExitMessage = {
40
+ type: typeof MessageType.EXIT;
41
+ code: number | null;
42
+ signal: string | number | undefined | null;
43
+ };
44
+ type ErrorMessage = { type: typeof MessageType.ERROR; message: string };
45
+
46
+ /** Encode a message for transmission. */
47
+ function encode(message: object): Buffer {
48
+ const json = JSON.stringify(message) as string;
49
+ const payload = Buffer.from(json, 'utf8');
50
+
51
+ if (payload.length > MAX_MESSAGE_SIZE) {
52
+ throw new Error(`Message too large: ${payload.length} bytes (max ${MAX_MESSAGE_SIZE})`);
53
+ }
54
+
55
+ const frame = Buffer.alloc(4 + payload.length);
56
+ frame.writeUInt32BE(payload.length, 0);
57
+ payload.copy(frame, 4);
58
+
59
+ return frame;
60
+ }
61
+
62
+ /** Streaming decoder for framed messages. */
63
+ class MessageDecoder {
64
+ buffer: Buffer;
65
+
66
+ constructor() {
67
+ this.buffer = Buffer.alloc(0);
68
+ }
69
+
70
+ /** Feed a received data chunk into the decoder. */
71
+ feed(data: Buffer): unknown[] {
72
+ this.buffer = Buffer.concat([this.buffer, data]);
73
+ const messages: unknown[] = [];
74
+
75
+ while (this.buffer.length >= 4) {
76
+ const length = this.buffer.readUInt32BE(0);
77
+
78
+ if (length > MAX_MESSAGE_SIZE) {
79
+ throw new Error(`Message too large: ${length} bytes (max ${MAX_MESSAGE_SIZE})`);
80
+ }
81
+
82
+ if (this.buffer.length < 4 + length) {
83
+ // Incomplete message, wait for more data
84
+ break;
85
+ }
86
+
87
+ const payload = this.buffer.slice(4, 4 + length);
88
+ this.buffer = this.buffer.slice(4 + length);
89
+
90
+ try {
91
+ const message: unknown = JSON.parse(payload.toString('utf8'));
92
+ messages.push(message);
93
+ } catch (error: unknown) {
94
+ const reason = error instanceof Error ? error.message : String(error);
95
+ throw new Error(`Invalid JSON in message: ${reason}`);
96
+ }
97
+ }
98
+
99
+ return messages;
100
+ }
101
+
102
+ /** Reset decoder state. */
103
+ reset(): void {
104
+ this.buffer = Buffer.alloc(0);
105
+ }
106
+ }
107
+
108
+ function createAttachMessage(clientId: string, cols: number, rows: number): AttachMessage {
109
+ return { type: MessageType.ATTACH, clientId, cols, rows };
110
+ }
111
+
112
+ function createDetachMessage(clientId: string): DetachMessage {
113
+ return { type: MessageType.DETACH, clientId };
114
+ }
115
+
116
+ function createResizeMessage(cols: number, rows: number): ResizeMessage {
117
+ return { type: MessageType.RESIZE, cols, rows };
118
+ }
119
+
120
+ function createSignalMessage(signal: string): SignalMessage {
121
+ if (!['SIGINT', 'SIGTERM', 'SIGKILL', 'SIGTSTP'].includes(signal)) {
122
+ throw new Error(`Invalid signal: ${signal}`);
123
+ }
124
+ return { type: MessageType.SIGNAL, signal };
125
+ }
126
+
127
+ function createStdinMessage(data: BinaryData): DataMessage<typeof MessageType.STDIN> {
128
+ const buf = Buffer.isBuffer(data) ? data : Buffer.from(data);
129
+ return { type: MessageType.STDIN, data: buf.toString('base64') };
130
+ }
131
+
132
+ function createOutputMessage(data: BinaryData, timestamp = Date.now()): OutputMessage {
133
+ const buf = Buffer.isBuffer(data) ? data : Buffer.from(data);
134
+ return { type: MessageType.OUTPUT, data: buf.toString('base64'), timestamp };
135
+ }
136
+
137
+ function createHistoryMessage(data: BinaryData): DataMessage<typeof MessageType.HISTORY> {
138
+ const buf = Buffer.isBuffer(data) ? data : Buffer.from(data);
139
+ return { type: MessageType.HISTORY, data: buf.toString('base64') };
140
+ }
141
+
142
+ function createStateMessage(state: Record<string, unknown>): Record<string, unknown> {
143
+ return { type: MessageType.STATE, ...state };
144
+ }
145
+
146
+ function createExitMessage(
147
+ code: number | null,
148
+ signal: string | number | undefined | null
149
+ ): ExitMessage {
150
+ return { type: MessageType.EXIT, code, signal };
151
+ }
152
+
153
+ function createErrorMessage(message: string): ErrorMessage {
154
+ return { type: MessageType.ERROR, message };
155
+ }
156
+
157
+ /** Decode the base64 data field from OUTPUT/HISTORY/STDIN messages. */
158
+ function decodeData(message: MessageWithData): Buffer | null {
159
+ if (message.data) {
160
+ return Buffer.from(message.data, 'base64');
161
+ }
162
+ return null;
163
+ }
164
+
165
+ export = {
166
+ encode,
167
+ MessageDecoder,
168
+ MessageType,
169
+ createAttachMessage,
170
+ createDetachMessage,
171
+ createResizeMessage,
172
+ createSignalMessage,
173
+ createStdinMessage,
174
+ createOutputMessage,
175
+ createHistoryMessage,
176
+ createStateMessage,
177
+ createExitMessage,
178
+ createErrorMessage,
179
+ decodeData,
180
+ MAX_MESSAGE_SIZE,
181
+ };
@@ -1,3 +1,4 @@
1
+ "use strict";
1
2
  /**
2
3
  * RingBuffer - Fixed-size circular buffer for output history
3
4
  *
@@ -9,113 +10,86 @@
9
10
  * - O(1) write and read operations
10
11
  * - Thread-safe for single writer (Node.js is single-threaded)
11
12
  */
12
-
13
13
  class RingBuffer {
14
- /**
15
- * @param {number} maxSize - Maximum buffer size in bytes (default 1MB)
16
- */
17
- constructor(maxSize = 1024 * 1024) {
18
- if (maxSize <= 0) {
19
- throw new Error('RingBuffer maxSize must be positive');
14
+ buffer;
15
+ maxSize;
16
+ writePos;
17
+ size;
18
+ /**
19
+ * @param maxSize - Maximum buffer size in bytes (default 1MB)
20
+ */
21
+ constructor(maxSize = 1024 * 1024) {
22
+ if (maxSize <= 0) {
23
+ throw new Error('RingBuffer maxSize must be positive');
24
+ }
25
+ this.buffer = Buffer.alloc(maxSize);
26
+ this.maxSize = maxSize;
27
+ this.writePos = 0; // Next write position
28
+ this.size = 0; // Current data size (0 to maxSize)
20
29
  }
21
- this.buffer = Buffer.alloc(maxSize);
22
- this.maxSize = maxSize;
23
- this.writePos = 0; // Next write position
24
- this.size = 0; // Current data size (0 to maxSize)
25
- }
26
-
27
- /**
28
- * Write data to the buffer
29
- * @param {Buffer|string} data - Data to write
30
- */
31
- write(data) {
32
- const buf = Buffer.isBuffer(data) ? data : Buffer.from(data);
33
-
34
- if (buf.length === 0) return;
35
-
36
- // If data is larger than buffer, only keep the last maxSize bytes
37
- if (buf.length >= this.maxSize) {
38
- buf.copy(this.buffer, 0, buf.length - this.maxSize);
39
- this.writePos = 0;
40
- this.size = this.maxSize;
41
- return;
30
+ /** Write data to the buffer. */
31
+ write(data) {
32
+ const buf = Buffer.isBuffer(data) ? data : Buffer.from(data);
33
+ if (buf.length === 0)
34
+ return;
35
+ // If data is larger than buffer, only keep the last maxSize bytes
36
+ if (buf.length >= this.maxSize) {
37
+ buf.copy(this.buffer, 0, buf.length - this.maxSize);
38
+ this.writePos = 0;
39
+ this.size = this.maxSize;
40
+ return;
41
+ }
42
+ // Calculate how much wraps around
43
+ const spaceToEnd = this.maxSize - this.writePos;
44
+ if (buf.length <= spaceToEnd) {
45
+ // No wrap needed
46
+ buf.copy(this.buffer, this.writePos);
47
+ this.writePos += buf.length;
48
+ }
49
+ else {
50
+ // Wrap around
51
+ buf.copy(this.buffer, this.writePos, 0, spaceToEnd);
52
+ buf.copy(this.buffer, 0, spaceToEnd);
53
+ this.writePos = buf.length - spaceToEnd;
54
+ }
55
+ // Update size (capped at maxSize)
56
+ this.size = Math.min(this.size + buf.length, this.maxSize);
42
57
  }
43
-
44
- // Calculate how much wraps around
45
- const spaceToEnd = this.maxSize - this.writePos;
46
-
47
- if (buf.length <= spaceToEnd) {
48
- // No wrap needed
49
- buf.copy(this.buffer, this.writePos);
50
- this.writePos += buf.length;
51
- } else {
52
- // Wrap around
53
- buf.copy(this.buffer, this.writePos, 0, spaceToEnd);
54
- buf.copy(this.buffer, 0, spaceToEnd);
55
- this.writePos = buf.length - spaceToEnd;
58
+ /** Read all buffered data. */
59
+ read() {
60
+ if (this.size === 0) {
61
+ return Buffer.alloc(0);
62
+ }
63
+ const result = Buffer.alloc(this.size);
64
+ if (this.size < this.maxSize) {
65
+ // Buffer not full yet, data starts at 0
66
+ this.buffer.copy(result, 0, 0, this.size);
67
+ }
68
+ else {
69
+ // Buffer is full, data starts at writePos (oldest data)
70
+ const startPos = this.writePos;
71
+ const firstChunkSize = this.maxSize - startPos;
72
+ this.buffer.copy(result, 0, startPos, this.maxSize);
73
+ this.buffer.copy(result, firstChunkSize, 0, startPos);
74
+ }
75
+ return result;
56
76
  }
57
-
58
- // Update size (capped at maxSize)
59
- this.size = Math.min(this.size + buf.length, this.maxSize);
60
- }
61
-
62
- /**
63
- * Read all buffered data
64
- * @returns {Buffer} - All data currently in buffer
65
- */
66
- read() {
67
- if (this.size === 0) {
68
- return Buffer.alloc(0);
77
+ /** Clear the buffer. */
78
+ clear() {
79
+ this.writePos = 0;
80
+ this.size = 0;
69
81
  }
70
-
71
- const result = Buffer.alloc(this.size);
72
-
73
- if (this.size < this.maxSize) {
74
- // Buffer not full yet, data starts at 0
75
- this.buffer.copy(result, 0, 0, this.size);
76
- } else {
77
- // Buffer is full, data starts at writePos (oldest data)
78
- const startPos = this.writePos;
79
- const firstChunkSize = this.maxSize - startPos;
80
-
81
- this.buffer.copy(result, 0, startPos, this.maxSize);
82
- this.buffer.copy(result, firstChunkSize, 0, startPos);
82
+ /** Get current data size. */
83
+ getSize() {
84
+ return this.size;
85
+ }
86
+ /** Check if buffer is empty. */
87
+ isEmpty() {
88
+ return this.size === 0;
89
+ }
90
+ /** Check if buffer is full. */
91
+ isFull() {
92
+ return this.size === this.maxSize;
83
93
  }
84
-
85
- return result;
86
- }
87
-
88
- /**
89
- * Clear the buffer
90
- */
91
- clear() {
92
- this.writePos = 0;
93
- this.size = 0;
94
- }
95
-
96
- /**
97
- * Get current data size
98
- * @returns {number}
99
- */
100
- getSize() {
101
- return this.size;
102
- }
103
-
104
- /**
105
- * Check if buffer is empty
106
- * @returns {boolean}
107
- */
108
- isEmpty() {
109
- return this.size === 0;
110
- }
111
-
112
- /**
113
- * Check if buffer is full
114
- * @returns {boolean}
115
- */
116
- isFull() {
117
- return this.size === this.maxSize;
118
- }
119
94
  }
120
-
121
95
  module.exports = RingBuffer;
@@ -0,0 +1,109 @@
1
+ /**
2
+ * RingBuffer - Fixed-size circular buffer for output history
3
+ *
4
+ * Used by AttachServer to store recent output for late-joining clients.
5
+ * When buffer fills, oldest data is overwritten.
6
+ *
7
+ * Design:
8
+ * - Fixed allocation (no dynamic resizing)
9
+ * - O(1) write and read operations
10
+ * - Thread-safe for single writer (Node.js is single-threaded)
11
+ */
12
+
13
+ class RingBuffer {
14
+ buffer: Buffer;
15
+ maxSize: number;
16
+ writePos: number;
17
+ size: number;
18
+
19
+ /**
20
+ * @param maxSize - Maximum buffer size in bytes (default 1MB)
21
+ */
22
+ constructor(maxSize = 1024 * 1024) {
23
+ if (maxSize <= 0) {
24
+ throw new Error('RingBuffer maxSize must be positive');
25
+ }
26
+ this.buffer = Buffer.alloc(maxSize);
27
+ this.maxSize = maxSize;
28
+ this.writePos = 0; // Next write position
29
+ this.size = 0; // Current data size (0 to maxSize)
30
+ }
31
+
32
+ /** Write data to the buffer. */
33
+ write(data: Buffer | string): void {
34
+ const buf = Buffer.isBuffer(data) ? data : Buffer.from(data);
35
+
36
+ if (buf.length === 0) return;
37
+
38
+ // If data is larger than buffer, only keep the last maxSize bytes
39
+ if (buf.length >= this.maxSize) {
40
+ buf.copy(this.buffer, 0, buf.length - this.maxSize);
41
+ this.writePos = 0;
42
+ this.size = this.maxSize;
43
+ return;
44
+ }
45
+
46
+ // Calculate how much wraps around
47
+ const spaceToEnd = this.maxSize - this.writePos;
48
+
49
+ if (buf.length <= spaceToEnd) {
50
+ // No wrap needed
51
+ buf.copy(this.buffer, this.writePos);
52
+ this.writePos += buf.length;
53
+ } else {
54
+ // Wrap around
55
+ buf.copy(this.buffer, this.writePos, 0, spaceToEnd);
56
+ buf.copy(this.buffer, 0, spaceToEnd);
57
+ this.writePos = buf.length - spaceToEnd;
58
+ }
59
+
60
+ // Update size (capped at maxSize)
61
+ this.size = Math.min(this.size + buf.length, this.maxSize);
62
+ }
63
+
64
+ /** Read all buffered data. */
65
+ read(): Buffer {
66
+ if (this.size === 0) {
67
+ return Buffer.alloc(0);
68
+ }
69
+
70
+ const result = Buffer.alloc(this.size);
71
+
72
+ if (this.size < this.maxSize) {
73
+ // Buffer not full yet, data starts at 0
74
+ this.buffer.copy(result, 0, 0, this.size);
75
+ } else {
76
+ // Buffer is full, data starts at writePos (oldest data)
77
+ const startPos = this.writePos;
78
+ const firstChunkSize = this.maxSize - startPos;
79
+
80
+ this.buffer.copy(result, 0, startPos, this.maxSize);
81
+ this.buffer.copy(result, firstChunkSize, 0, startPos);
82
+ }
83
+
84
+ return result;
85
+ }
86
+
87
+ /** Clear the buffer. */
88
+ clear(): void {
89
+ this.writePos = 0;
90
+ this.size = 0;
91
+ }
92
+
93
+ /** Get current data size. */
94
+ getSize(): number {
95
+ return this.size;
96
+ }
97
+
98
+ /** Check if buffer is empty. */
99
+ isEmpty(): boolean {
100
+ return this.size === 0;
101
+ }
102
+
103
+ /** Check if buffer is full. */
104
+ isFull(): boolean {
105
+ return this.size === this.maxSize;
106
+ }
107
+ }
108
+
109
+ export = RingBuffer;
@@ -1,88 +1,77 @@
1
+ "use strict";
1
2
  /**
2
3
  * sendInput - write stdin data to a live attach socket
3
4
  *
4
5
  * Uses the attach protocol's STDIN message to forward input to the PTY.
5
6
  * Returns { ok, error } instead of throwing on transport failures.
6
7
  */
7
-
8
- const net = require('net');
9
- const fs = require('fs');
10
- const protocol = require('./protocol');
11
-
8
+ var __importDefault = (this && this.__importDefault) || function (mod) {
9
+ return (mod && mod.__esModule) ? mod : { "default": mod };
10
+ };
11
+ const node_fs_1 = __importDefault(require("node:fs"));
12
+ const node_net_1 = __importDefault(require("node:net"));
13
+ const protocol_1 = __importDefault(require("./protocol"));
12
14
  const DEFAULT_TIMEOUT_MS = 1500;
13
-
14
- /**
15
- * Send input to an attach socket via STDIN message.
16
- * @param {object} options
17
- * @param {string} options.socketPath - Unix socket path
18
- * @param {Buffer|string} options.data - Data to send
19
- * @param {number} [options.timeoutMs=1500] - Timeout in ms
20
- * @returns {Promise<{ok: boolean, error: string|null}>}
21
- */
15
+ /** Send input to an attach socket via STDIN message. */
22
16
  function sendInput(options = {}) {
23
- const { socketPath, data, timeoutMs = DEFAULT_TIMEOUT_MS } = options;
24
-
25
- if (!socketPath) {
26
- throw new Error('sendInput: socketPath is required');
27
- }
28
-
29
- if (data === undefined || data === null) {
30
- throw new Error('sendInput: data is required');
31
- }
32
-
33
- if (!Number.isFinite(timeoutMs) || timeoutMs <= 0) {
34
- throw new Error(`sendInput: timeoutMs must be positive (got ${timeoutMs})`);
35
- }
36
-
37
- if (!fs.existsSync(socketPath)) {
38
- return { ok: false, error: `Socket not found: ${socketPath}` };
39
- }
40
-
41
- return new Promise((resolve) => {
42
- let settled = false;
43
- let timeout;
44
- const socket = net.createConnection(socketPath);
45
-
46
- const finish = (result) => {
47
- if (settled) return;
48
- settled = true;
49
- if (timeout) {
50
- clearTimeout(timeout);
51
- }
52
- try {
53
- socket.end();
54
- socket.destroy();
55
- } catch (cleanupError) {
56
- console.warn('[sendInput] socket cleanup failed:', cleanupError);
57
- }
58
- resolve(result);
59
- };
60
-
61
- timeout = setTimeout(() => {
62
- finish({ ok: false, error: 'Timeout waiting for socket connection' });
63
- }, timeoutMs);
64
-
65
- socket.on('connect', () => {
66
- try {
67
- const encoded = protocol.encode(protocol.createStdinMessage(data));
68
- socket.write(encoded, (err) => {
69
- if (err) {
70
- finish({ ok: false, error: err.message });
71
- } else {
72
- finish({ ok: true, error: null });
73
- }
17
+ const { socketPath, data, timeoutMs = DEFAULT_TIMEOUT_MS } = options;
18
+ if (!socketPath) {
19
+ throw new Error('sendInput: socketPath is required');
20
+ }
21
+ if (data === undefined || data === null) {
22
+ throw new Error('sendInput: data is required');
23
+ }
24
+ if (!Number.isFinite(timeoutMs) || timeoutMs <= 0) {
25
+ throw new Error(`sendInput: timeoutMs must be positive (got ${timeoutMs})`);
26
+ }
27
+ if (!node_fs_1.default.existsSync(socketPath)) {
28
+ return { ok: false, error: `Socket not found: ${socketPath}` };
29
+ }
30
+ return new Promise((resolve) => {
31
+ let settled = false;
32
+ let timeout;
33
+ const socket = node_net_1.default.createConnection(socketPath);
34
+ const finish = (result) => {
35
+ if (settled)
36
+ return;
37
+ settled = true;
38
+ if (timeout) {
39
+ clearTimeout(timeout);
40
+ }
41
+ try {
42
+ socket.end();
43
+ socket.destroy();
44
+ }
45
+ catch (cleanupError) {
46
+ console.warn('[sendInput] socket cleanup failed:', cleanupError);
47
+ }
48
+ resolve(result);
49
+ };
50
+ timeout = setTimeout(() => {
51
+ finish({ ok: false, error: 'Timeout waiting for socket connection' });
52
+ }, timeoutMs);
53
+ socket.on('connect', () => {
54
+ try {
55
+ const encoded = protocol_1.default.encode(protocol_1.default.createStdinMessage(data));
56
+ socket.write(encoded, (error) => {
57
+ if (error) {
58
+ finish({ ok: false, error: error.message });
59
+ }
60
+ else {
61
+ finish({ ok: true, error: null });
62
+ }
63
+ });
64
+ }
65
+ catch (error) {
66
+ const reason = error instanceof Error ? error.message : String(error);
67
+ finish({ ok: false, error: reason });
68
+ }
69
+ });
70
+ socket.on('error', (error) => {
71
+ finish({ ok: false, error: error.message });
74
72
  });
75
- } catch (err) {
76
- finish({ ok: false, error: err.message });
77
- }
78
- });
79
-
80
- socket.on('error', (err) => {
81
- finish({ ok: false, error: err.message });
82
73
  });
83
- });
84
74
  }
85
-
86
75
  module.exports = {
87
- sendInput,
76
+ sendInput,
88
77
  };