agent-relay 2.3.13 → 2.4.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 (1421) hide show
  1. package/README.md +42 -176
  2. package/bin/agent-relay-broker-darwin-arm64 +0 -0
  3. package/bin/agent-relay-broker-darwin-x64 +0 -0
  4. package/bin/agent-relay-broker-linux-arm64 +0 -0
  5. package/bin/agent-relay-broker-linux-x64 +0 -0
  6. package/dist/index.cjs +50288 -63371
  7. package/dist/src/cli/bootstrap.d.ts +6 -0
  8. package/dist/src/cli/bootstrap.d.ts.map +1 -0
  9. package/dist/src/cli/bootstrap.js +109 -0
  10. package/dist/src/cli/bootstrap.js.map +1 -0
  11. package/dist/src/cli/commands/agent-management.d.ts +51 -0
  12. package/dist/src/cli/commands/agent-management.d.ts.map +1 -0
  13. package/dist/src/cli/commands/agent-management.js +290 -0
  14. package/dist/src/cli/commands/agent-management.js.map +1 -0
  15. package/dist/src/cli/commands/auth.d.ts +9 -0
  16. package/dist/src/cli/commands/auth.d.ts.map +1 -0
  17. package/dist/src/cli/commands/auth.js +33 -0
  18. package/dist/src/cli/commands/auth.js.map +1 -0
  19. package/dist/src/cli/commands/cloud.d.ts +18 -0
  20. package/dist/src/cli/commands/cloud.d.ts.map +1 -0
  21. package/dist/src/cli/commands/cloud.js +392 -0
  22. package/dist/src/cli/commands/cloud.js.map +1 -0
  23. package/dist/src/cli/commands/core.d.ts +107 -0
  24. package/dist/src/cli/commands/core.d.ts.map +1 -0
  25. package/dist/src/cli/commands/core.js +299 -0
  26. package/dist/src/cli/commands/core.js.map +1 -0
  27. package/dist/src/cli/commands/doctor.d.ts +1 -1
  28. package/dist/src/cli/commands/doctor.d.ts.map +1 -1
  29. package/dist/src/cli/commands/doctor.js +1 -485
  30. package/dist/src/cli/commands/doctor.js.map +1 -1
  31. package/dist/src/cli/commands/messaging.d.ts +61 -0
  32. package/dist/src/cli/commands/messaging.d.ts.map +1 -0
  33. package/dist/src/cli/commands/messaging.js +213 -0
  34. package/dist/src/cli/commands/messaging.js.map +1 -0
  35. package/dist/src/cli/commands/monitoring.d.ts +57 -0
  36. package/dist/src/cli/commands/monitoring.d.ts.map +1 -0
  37. package/dist/src/cli/commands/monitoring.js +350 -0
  38. package/dist/src/cli/commands/monitoring.js.map +1 -0
  39. package/dist/src/cli/commands/setup.d.ts +29 -0
  40. package/dist/src/cli/commands/setup.d.ts.map +1 -0
  41. package/dist/src/cli/commands/setup.js +324 -0
  42. package/dist/src/cli/commands/setup.js.map +1 -0
  43. package/dist/src/cli/commands/swarm.d.ts +3 -0
  44. package/dist/src/cli/commands/swarm.d.ts.map +1 -0
  45. package/dist/src/cli/commands/swarm.js +108 -0
  46. package/dist/src/cli/commands/swarm.js.map +1 -0
  47. package/dist/src/cli/index.d.ts +1 -28
  48. package/dist/src/cli/index.d.ts.map +1 -1
  49. package/dist/src/cli/index.js +4 -4936
  50. package/dist/src/cli/index.js.map +1 -1
  51. package/dist/src/cli/lib/agent-management-listing.d.ts +39 -0
  52. package/dist/src/cli/lib/agent-management-listing.d.ts.map +1 -0
  53. package/dist/src/cli/lib/agent-management-listing.js +253 -0
  54. package/dist/src/cli/lib/agent-management-listing.js.map +1 -0
  55. package/dist/src/cli/lib/auth-ssh.d.ts +48 -0
  56. package/dist/src/cli/lib/auth-ssh.d.ts.map +1 -0
  57. package/dist/src/cli/lib/auth-ssh.js +572 -0
  58. package/dist/src/cli/lib/auth-ssh.js.map +1 -0
  59. package/dist/src/cli/lib/bridge.d.ts +8 -0
  60. package/dist/src/cli/lib/bridge.d.ts.map +1 -0
  61. package/dist/src/cli/lib/bridge.js +100 -0
  62. package/dist/src/cli/lib/bridge.js.map +1 -0
  63. package/dist/src/cli/lib/broker-lifecycle.d.ts +20 -0
  64. package/dist/src/cli/lib/broker-lifecycle.d.ts.map +1 -0
  65. package/dist/src/cli/lib/broker-lifecycle.js +843 -0
  66. package/dist/src/cli/lib/broker-lifecycle.js.map +1 -0
  67. package/dist/src/cli/lib/client-factory.d.ts +24 -0
  68. package/dist/src/cli/lib/client-factory.d.ts.map +1 -0
  69. package/dist/src/cli/lib/client-factory.js +20 -0
  70. package/dist/src/cli/lib/client-factory.js.map +1 -0
  71. package/dist/src/cli/lib/cloud-client.d.ts +39 -0
  72. package/dist/src/cli/lib/cloud-client.d.ts.map +1 -0
  73. package/dist/src/cli/lib/cloud-client.js +120 -0
  74. package/dist/src/cli/lib/cloud-client.js.map +1 -0
  75. package/dist/src/cli/lib/core-maintenance.d.ts +13 -0
  76. package/dist/src/cli/lib/core-maintenance.d.ts.map +1 -0
  77. package/dist/src/cli/lib/core-maintenance.js +250 -0
  78. package/dist/src/cli/lib/core-maintenance.js.map +1 -0
  79. package/dist/src/cli/lib/doctor.d.ts +2 -0
  80. package/dist/src/cli/lib/doctor.d.ts.map +1 -0
  81. package/dist/src/cli/lib/doctor.js +484 -0
  82. package/dist/src/cli/lib/doctor.js.map +1 -0
  83. package/dist/src/cli/lib/formatting.d.ts +8 -0
  84. package/dist/src/cli/lib/formatting.d.ts.map +1 -0
  85. package/dist/src/cli/lib/formatting.js +48 -0
  86. package/dist/src/cli/lib/formatting.js.map +1 -0
  87. package/dist/src/cli/lib/index.d.ts +5 -0
  88. package/dist/src/cli/lib/index.d.ts.map +1 -0
  89. package/dist/src/cli/lib/index.js +5 -0
  90. package/dist/src/cli/lib/index.js.map +1 -0
  91. package/dist/src/cli/lib/jsonc.d.ts +8 -0
  92. package/dist/src/cli/lib/jsonc.d.ts.map +1 -0
  93. package/dist/src/cli/lib/jsonc.js +88 -0
  94. package/dist/src/cli/lib/jsonc.js.map +1 -0
  95. package/dist/src/cli/lib/monitoring-health.d.ts +32 -0
  96. package/dist/src/cli/lib/monitoring-health.d.ts.map +1 -0
  97. package/dist/src/cli/lib/monitoring-health.js +2 -0
  98. package/dist/src/cli/lib/monitoring-health.js.map +1 -0
  99. package/dist/src/cli/lib/paths.d.ts +2 -0
  100. package/dist/src/cli/lib/paths.d.ts.map +1 -0
  101. package/dist/src/cli/lib/paths.js +5 -0
  102. package/dist/src/cli/lib/paths.js.map +1 -0
  103. package/dist/src/index.d.ts +1 -5
  104. package/dist/src/index.d.ts.map +1 -1
  105. package/dist/src/index.js +1 -5
  106. package/dist/src/index.js.map +1 -1
  107. package/install.sh +0 -30
  108. package/package.json +84 -98
  109. package/packages/acp-bridge/README.md +8 -8
  110. package/packages/acp-bridge/dist/acp-agent.d.ts +8 -7
  111. package/packages/acp-bridge/dist/acp-agent.d.ts.map +1 -1
  112. package/packages/acp-bridge/dist/acp-agent.js +118 -143
  113. package/packages/acp-bridge/dist/acp-agent.js.map +1 -1
  114. package/packages/acp-bridge/dist/cli.d.ts +1 -1
  115. package/packages/acp-bridge/dist/cli.js +3 -3
  116. package/packages/acp-bridge/dist/index.d.ts +2 -2
  117. package/packages/acp-bridge/dist/index.d.ts.map +1 -1
  118. package/packages/acp-bridge/dist/index.js +1 -1
  119. package/packages/acp-bridge/dist/index.js.map +1 -1
  120. package/packages/acp-bridge/dist/types.d.ts +3 -3
  121. package/packages/acp-bridge/package.json +3 -3
  122. package/packages/acp-bridge/src/acp-agent.ts +123 -160
  123. package/packages/acp-bridge/src/cli.ts +3 -3
  124. package/packages/acp-bridge/src/index.ts +2 -2
  125. package/packages/acp-bridge/src/types.ts +3 -3
  126. package/packages/config/dist/bridge-config.d.ts +5 -5
  127. package/packages/config/dist/bridge-config.d.ts.map +1 -1
  128. package/packages/config/dist/bridge-config.js +16 -9
  129. package/packages/config/dist/bridge-config.js.map +1 -1
  130. package/packages/config/dist/cli-auth-config.d.ts +1 -1
  131. package/packages/config/dist/cli-auth-config.js +1 -1
  132. package/packages/config/dist/cli-registry.generated.d.ts +340 -0
  133. package/packages/config/dist/cli-registry.generated.d.ts.map +1 -0
  134. package/packages/config/dist/cli-registry.generated.js +297 -0
  135. package/packages/config/dist/cli-registry.generated.js.map +1 -0
  136. package/packages/config/dist/index.d.ts +1 -0
  137. package/packages/config/dist/index.d.ts.map +1 -1
  138. package/packages/config/dist/index.js +1 -0
  139. package/packages/config/dist/index.js.map +1 -1
  140. package/packages/config/dist/project-namespace.d.ts +9 -9
  141. package/packages/config/dist/project-namespace.js +3 -3
  142. package/packages/config/dist/relay-config.d.ts +1 -1
  143. package/packages/config/dist/relay-config.js +1 -1
  144. package/packages/config/dist/schemas.js +1 -1
  145. package/packages/config/dist/shadow-config.d.ts +2 -1
  146. package/packages/config/dist/shadow-config.d.ts.map +1 -1
  147. package/packages/config/dist/shadow-config.js.map +1 -1
  148. package/packages/config/package.json +2 -3
  149. package/packages/config/src/bridge-config.test.ts +20 -6
  150. package/packages/config/src/bridge-config.ts +20 -10
  151. package/packages/config/src/cli-auth-config.ts +1 -1
  152. package/packages/config/src/cli-registry.generated.ts +328 -0
  153. package/packages/config/src/index.ts +1 -0
  154. package/packages/config/src/project-namespace.ts +9 -9
  155. package/packages/config/src/relay-config.ts +1 -1
  156. package/packages/config/src/schemas.ts +1 -1
  157. package/packages/config/src/shadow-config.ts +8 -1
  158. package/packages/contracts/fixtures/error-fixtures.json +42 -0
  159. package/packages/contracts/fixtures/event-fixtures.json +161 -0
  160. package/packages/contracts/fixtures/health-fixtures.json +35 -0
  161. package/packages/contracts/fixtures/identity-fixtures.json +58 -0
  162. package/packages/contracts/fixtures/replay-fixtures.json +33 -0
  163. package/packages/hooks/dist/inbox-check/types.d.ts +2 -2
  164. package/packages/hooks/dist/types.d.ts +9 -3
  165. package/packages/hooks/dist/types.d.ts.map +1 -1
  166. package/packages/hooks/dist/types.js +1 -1
  167. package/packages/hooks/dist/types.js.map +1 -1
  168. package/packages/hooks/package.json +5 -5
  169. package/packages/hooks/src/inbox-check/types.ts +2 -2
  170. package/packages/hooks/src/types.ts +11 -3
  171. package/packages/memory/package.json +2 -2
  172. package/packages/policy/package.json +2 -2
  173. package/packages/sdk/.mcp.json +14 -0
  174. package/packages/sdk/.trajectories/active/traj_1771875803391_84ca57b2.json +50 -0
  175. package/packages/sdk/.trajectories/active/traj_1771891934534_06504121.json +50 -0
  176. package/packages/sdk/.trajectories/active/traj_1771891957929_211afc4e.json +50 -0
  177. package/packages/sdk/.trajectories/active/traj_1771891982509_38c84638.json +50 -0
  178. package/packages/sdk/.trajectories/completed/traj_1771875803188_cd6d181c.json +80 -0
  179. package/packages/sdk/.trajectories/completed/traj_1771875803204_f2aeb8c8.json +80 -0
  180. package/packages/sdk/.trajectories/completed/traj_1771875803210_d65f3f1a.json +80 -0
  181. package/packages/sdk/.trajectories/completed/traj_1771875803218_e454a25d.json +80 -0
  182. package/packages/sdk/.trajectories/completed/traj_1771875803223_d7a64815.json +80 -0
  183. package/packages/sdk/.trajectories/completed/traj_1771875803227_7e56da5b.json +80 -0
  184. package/packages/sdk/.trajectories/completed/traj_1771875803235_4fbf93b4.json +80 -0
  185. package/packages/sdk/.trajectories/completed/traj_1771875803243_47931c71.json +80 -0
  186. package/packages/sdk/.trajectories/completed/traj_1771875803258_3816f3fe.json +80 -0
  187. package/packages/sdk/.trajectories/completed/traj_1771875803268_8061140e.json +80 -0
  188. package/packages/sdk/.trajectories/completed/traj_1771875803326_ae6f9c78.json +80 -0
  189. package/packages/sdk/.trajectories/completed/traj_1771875808396_cbde0a6c.json +91 -0
  190. package/packages/sdk/.trajectories/completed/traj_1771875812026_aa2442bb.json +91 -0
  191. package/packages/sdk/.trajectories/completed/traj_1771875815431_c2c656c5.json +91 -0
  192. package/packages/sdk/.trajectories/completed/traj_1771875818645_3a4dbf02.json +91 -0
  193. package/packages/sdk/.trajectories/completed/traj_1771891934403_24923c03.json +80 -0
  194. package/packages/sdk/.trajectories/completed/traj_1771891934421_dca16e24.json +80 -0
  195. package/packages/sdk/.trajectories/completed/traj_1771891934430_057706f7.json +80 -0
  196. package/packages/sdk/.trajectories/completed/traj_1771891934442_faf97382.json +80 -0
  197. package/packages/sdk/.trajectories/completed/traj_1771891934454_5542ecd5.json +80 -0
  198. package/packages/sdk/.trajectories/completed/traj_1771891934464_12202a08.json +80 -0
  199. package/packages/sdk/.trajectories/completed/traj_1771891934487_94378275.json +80 -0
  200. package/packages/sdk/.trajectories/completed/traj_1771891934503_ca728c13.json +80 -0
  201. package/packages/sdk/.trajectories/completed/traj_1771891934519_100af69a.json +80 -0
  202. package/packages/sdk/.trajectories/completed/traj_1771891934536_62ad39d9.json +80 -0
  203. package/packages/sdk/.trajectories/completed/traj_1771891934553_d6798a52.json +80 -0
  204. package/packages/sdk/.trajectories/completed/traj_1771891939537_541c8096.json +91 -0
  205. package/packages/sdk/.trajectories/completed/traj_1771891942985_36ab9a4d.json +91 -0
  206. package/packages/sdk/.trajectories/completed/traj_1771891946453_e8a6e05f.json +91 -0
  207. package/packages/sdk/.trajectories/completed/traj_1771891949838_5de0de84.json +91 -0
  208. package/packages/sdk/.trajectories/completed/traj_1771891957807_0ecfb4f4.json +80 -0
  209. package/packages/sdk/.trajectories/completed/traj_1771891957827_c4539239.json +80 -0
  210. package/packages/sdk/.trajectories/completed/traj_1771891957836_91168b48.json +80 -0
  211. package/packages/sdk/.trajectories/completed/traj_1771891957848_8c5cad0b.json +80 -0
  212. package/packages/sdk/.trajectories/completed/traj_1771891957857_0986b293.json +80 -0
  213. package/packages/sdk/.trajectories/completed/traj_1771891957872_8a3113af.json +80 -0
  214. package/packages/sdk/.trajectories/completed/traj_1771891957884_0bb85208.json +80 -0
  215. package/packages/sdk/.trajectories/completed/traj_1771891957892_86c75e2e.json +80 -0
  216. package/packages/sdk/.trajectories/completed/traj_1771891957907_98ca0e6f.json +80 -0
  217. package/packages/sdk/.trajectories/completed/traj_1771891957918_d9091231.json +80 -0
  218. package/packages/sdk/.trajectories/completed/traj_1771891957931_dcaf77ed.json +80 -0
  219. package/packages/sdk/.trajectories/completed/traj_1771891962931_eb1fdee2.json +91 -0
  220. package/packages/sdk/.trajectories/completed/traj_1771891966262_9061a93f.json +91 -0
  221. package/packages/sdk/.trajectories/completed/traj_1771891969915_1adaba19.json +91 -0
  222. package/packages/sdk/.trajectories/completed/traj_1771891973588_f08b79e9.json +91 -0
  223. package/packages/sdk/.trajectories/completed/traj_1771891982421_f1985bce.json +80 -0
  224. package/packages/sdk/.trajectories/completed/traj_1771891982432_e7a84163.json +80 -0
  225. package/packages/sdk/.trajectories/completed/traj_1771891982447_369b842a.json +80 -0
  226. package/packages/sdk/.trajectories/completed/traj_1771891982469_5fc45199.json +80 -0
  227. package/packages/sdk/.trajectories/completed/traj_1771891982495_454c7cb3.json +80 -0
  228. package/packages/sdk/.trajectories/completed/traj_1771891982514_08098e03.json +80 -0
  229. package/packages/sdk/.trajectories/completed/traj_1771891982526_b351d778.json +80 -0
  230. package/packages/sdk/.trajectories/completed/traj_1771891982533_fa542d83.json +80 -0
  231. package/packages/sdk/.trajectories/completed/traj_1771891982540_18ab24dc.json +80 -0
  232. package/packages/sdk/.trajectories/completed/traj_1771891982544_5b4fa163.json +80 -0
  233. package/packages/sdk/.trajectories/completed/traj_1771891982548_c13f089a.json +80 -0
  234. package/packages/sdk/.trajectories/completed/traj_1771891987510_23f6da1f.json +91 -0
  235. package/packages/sdk/.trajectories/completed/traj_1771891991466_912c2e04.json +91 -0
  236. package/packages/sdk/.trajectories/completed/traj_1771891994891_60604be2.json +91 -0
  237. package/packages/sdk/.trajectories/completed/traj_1771891998370_cfaf9b8b.json +91 -0
  238. package/packages/sdk/README.md +68 -838
  239. package/packages/sdk/bin/agent-relay-broker +0 -0
  240. package/packages/sdk/dist/__tests__/contract-fixtures.test.d.ts +2 -0
  241. package/packages/sdk/dist/__tests__/contract-fixtures.test.d.ts.map +1 -0
  242. package/packages/sdk/dist/__tests__/contract-fixtures.test.js +85 -0
  243. package/packages/sdk/dist/__tests__/contract-fixtures.test.js.map +1 -0
  244. package/packages/sdk/dist/__tests__/facade.test.js +305 -0
  245. package/packages/sdk/dist/__tests__/facade.test.js.map +1 -0
  246. package/packages/sdk/dist/__tests__/integration.test.js +169 -0
  247. package/packages/sdk/dist/__tests__/integration.test.js.map +1 -0
  248. package/packages/sdk/dist/__tests__/pty.test.d.ts +2 -0
  249. package/packages/sdk/dist/__tests__/pty.test.d.ts.map +1 -0
  250. package/packages/sdk/dist/__tests__/pty.test.js +20 -0
  251. package/packages/sdk/dist/__tests__/pty.test.js.map +1 -0
  252. package/packages/sdk/dist/__tests__/quickstart.test.js +176 -0
  253. package/packages/sdk/dist/__tests__/quickstart.test.js.map +1 -0
  254. package/packages/sdk/dist/__tests__/spawn-from-env.test.d.ts +2 -0
  255. package/packages/sdk/dist/__tests__/spawn-from-env.test.d.ts.map +1 -0
  256. package/packages/sdk/dist/__tests__/spawn-from-env.test.js +206 -0
  257. package/packages/sdk/dist/__tests__/spawn-from-env.test.js.map +1 -0
  258. package/packages/sdk/dist/__tests__/unit.test.js +347 -0
  259. package/packages/sdk/dist/__tests__/unit.test.js.map +1 -0
  260. package/packages/sdk/dist/client.d.ts +140 -526
  261. package/packages/sdk/dist/client.d.ts.map +1 -1
  262. package/packages/sdk/dist/client.js +416 -1509
  263. package/packages/sdk/dist/client.js.map +1 -1
  264. package/packages/sdk/dist/examples/workflow-superiority.d.ts +32 -0
  265. package/packages/sdk/dist/examples/workflow-superiority.d.ts.map +1 -0
  266. package/packages/sdk/dist/examples/workflow-superiority.js +1421 -0
  267. package/packages/sdk/dist/examples/workflow-superiority.js.map +1 -0
  268. package/packages/sdk/dist/index.d.ts +13 -20
  269. package/packages/sdk/dist/index.d.ts.map +1 -1
  270. package/packages/sdk/dist/index.js +12 -26
  271. package/packages/sdk/dist/index.js.map +1 -1
  272. package/packages/sdk/dist/logs.d.ts +70 -25
  273. package/packages/sdk/dist/logs.d.ts.map +1 -1
  274. package/packages/sdk/dist/logs.js +238 -42
  275. package/packages/sdk/dist/logs.js.map +1 -1
  276. package/packages/sdk/dist/models.d.ts +9 -0
  277. package/packages/sdk/dist/models.d.ts.map +1 -0
  278. package/packages/sdk/dist/models.js +17 -0
  279. package/packages/sdk/dist/models.js.map +1 -0
  280. package/packages/sdk/dist/protocol.d.ts +366 -0
  281. package/packages/sdk/dist/protocol.d.ts.map +1 -0
  282. package/packages/sdk/dist/pty.d.ts.map +1 -0
  283. package/packages/sdk/dist/pty.js +26 -0
  284. package/packages/sdk/dist/pty.js.map +1 -0
  285. package/packages/sdk/dist/relay-adapter.d.ts +139 -0
  286. package/packages/sdk/dist/relay-adapter.d.ts.map +1 -0
  287. package/packages/sdk/dist/relay-adapter.js +210 -0
  288. package/packages/sdk/dist/relay-adapter.js.map +1 -0
  289. package/packages/sdk/dist/relay.d.ts +304 -0
  290. package/packages/sdk/dist/relay.d.ts.map +1 -0
  291. package/packages/sdk/dist/relay.js +910 -0
  292. package/packages/sdk/dist/relay.js.map +1 -0
  293. package/packages/sdk/dist/shadow.d.ts +101 -0
  294. package/packages/sdk/dist/shadow.d.ts.map +1 -0
  295. package/packages/sdk/dist/shadow.js.map +1 -0
  296. package/packages/sdk/dist/spawn-from-env.d.ts +77 -0
  297. package/packages/sdk/dist/spawn-from-env.d.ts.map +1 -0
  298. package/packages/sdk/dist/spawn-from-env.js +172 -0
  299. package/packages/sdk/dist/spawn-from-env.js.map +1 -0
  300. package/packages/sdk/dist/workflows/builder.d.ts +114 -0
  301. package/packages/sdk/dist/workflows/builder.d.ts.map +1 -0
  302. package/packages/sdk/dist/workflows/builder.js +201 -0
  303. package/packages/sdk/dist/workflows/builder.js.map +1 -0
  304. package/packages/sdk/dist/workflows/cli.d.ts +11 -0
  305. package/packages/sdk/dist/workflows/cli.d.ts.map +1 -0
  306. package/packages/sdk/dist/workflows/cli.js +144 -0
  307. package/packages/sdk/dist/workflows/cli.js.map +1 -0
  308. package/packages/sdk/dist/workflows/coordinator.d.ts +73 -0
  309. package/packages/sdk/dist/workflows/coordinator.d.ts.map +1 -0
  310. package/packages/sdk/dist/workflows/coordinator.js +647 -0
  311. package/packages/sdk/dist/workflows/coordinator.js.map +1 -0
  312. package/packages/sdk/dist/workflows/custom-steps.d.ts +73 -0
  313. package/packages/sdk/dist/workflows/custom-steps.d.ts.map +1 -0
  314. package/packages/sdk/dist/workflows/custom-steps.js +321 -0
  315. package/packages/sdk/dist/workflows/custom-steps.js.map +1 -0
  316. package/packages/sdk/dist/workflows/dry-run-format.d.ts +6 -0
  317. package/packages/sdk/dist/workflows/dry-run-format.d.ts.map +1 -0
  318. package/packages/sdk/dist/workflows/dry-run-format.js +68 -0
  319. package/packages/sdk/dist/workflows/dry-run-format.js.map +1 -0
  320. package/packages/sdk/dist/workflows/file-db.d.ts +33 -0
  321. package/packages/sdk/dist/workflows/file-db.d.ts.map +1 -0
  322. package/packages/sdk/dist/workflows/file-db.js +108 -0
  323. package/packages/sdk/dist/workflows/file-db.js.map +1 -0
  324. package/packages/sdk/dist/workflows/index.d.ts +15 -0
  325. package/packages/sdk/dist/workflows/index.d.ts.map +1 -0
  326. package/packages/sdk/dist/workflows/index.js +15 -0
  327. package/packages/sdk/dist/workflows/index.js.map +1 -0
  328. package/packages/sdk/dist/workflows/run.d.ts +38 -0
  329. package/packages/sdk/dist/workflows/run.d.ts.map +1 -0
  330. package/packages/sdk/dist/workflows/run.js +25 -0
  331. package/packages/sdk/dist/workflows/run.js.map +1 -0
  332. package/packages/sdk/dist/workflows/runner.d.ts +320 -0
  333. package/packages/sdk/dist/workflows/runner.d.ts.map +1 -0
  334. package/packages/sdk/dist/workflows/runner.js +2821 -0
  335. package/packages/sdk/dist/workflows/runner.js.map +1 -0
  336. package/packages/sdk/dist/workflows/templates.d.ts +47 -0
  337. package/packages/sdk/dist/workflows/templates.d.ts.map +1 -0
  338. package/packages/sdk/dist/workflows/templates.js +405 -0
  339. package/packages/sdk/dist/workflows/templates.js.map +1 -0
  340. package/packages/sdk/dist/workflows/trajectory.d.ts +87 -0
  341. package/packages/sdk/dist/workflows/trajectory.d.ts.map +1 -0
  342. package/packages/sdk/dist/workflows/trajectory.js +441 -0
  343. package/packages/sdk/dist/workflows/trajectory.js.map +1 -0
  344. package/packages/sdk/dist/workflows/types.d.ts +306 -0
  345. package/packages/sdk/dist/workflows/types.d.ts.map +1 -0
  346. package/packages/sdk/dist/workflows/types.js +23 -0
  347. package/packages/sdk/dist/workflows/types.js.map +1 -0
  348. package/packages/sdk/dist/workflows/validator.d.ts +11 -0
  349. package/packages/sdk/dist/workflows/validator.d.ts.map +1 -0
  350. package/packages/sdk/dist/workflows/validator.js +128 -0
  351. package/packages/sdk/dist/workflows/validator.js.map +1 -0
  352. package/packages/sdk/package.json +59 -53
  353. package/packages/sdk/scripts/bundle-agent-relay.mjs +53 -0
  354. package/packages/sdk/src/__tests__/contract-fixtures.test.ts +122 -0
  355. package/packages/sdk/src/__tests__/error-scenarios.test.ts +682 -0
  356. package/packages/sdk/src/__tests__/facade.test.ts +364 -0
  357. package/packages/sdk/src/__tests__/idle-nudge.test.ts +438 -0
  358. package/packages/sdk/src/__tests__/integration.test.ts +204 -0
  359. package/packages/sdk/src/__tests__/orchestration-upgrades.test.ts +797 -0
  360. package/packages/sdk/src/__tests__/pty.test.ts +24 -0
  361. package/packages/sdk/src/__tests__/quickstart.test.ts +198 -0
  362. package/packages/sdk/src/__tests__/spawn-from-env.test.ts +282 -0
  363. package/packages/sdk/src/__tests__/swarm-coordinator.test.ts +909 -0
  364. package/packages/sdk/src/__tests__/unit.test.ts +435 -0
  365. package/packages/sdk/src/__tests__/workflow-runner.test.ts +489 -0
  366. package/packages/sdk/src/__tests__/yaml-validation.test.ts +890 -0
  367. package/packages/sdk/src/client.ts +514 -1912
  368. package/packages/sdk/src/examples/workflow-superiority.ts +1485 -0
  369. package/packages/sdk/src/examples/workflows/README.md +156 -0
  370. package/packages/sdk/src/examples/workflows/ralph-overnight.yaml +421 -0
  371. package/packages/sdk/src/examples/workflows/ralph-swarm.yaml +411 -0
  372. package/packages/sdk/src/examples/workflows/ralph-tdd.yaml +259 -0
  373. package/packages/sdk/src/index.ts +13 -116
  374. package/packages/sdk/src/logs.ts +282 -54
  375. package/packages/sdk/src/models.ts +36 -0
  376. package/packages/sdk/src/protocol.ts +385 -0
  377. package/packages/sdk/src/pty.ts +35 -0
  378. package/packages/sdk/src/relay-adapter.ts +316 -0
  379. package/packages/sdk/src/relay.ts +1147 -0
  380. package/packages/sdk/src/shadow.ts +228 -0
  381. package/packages/sdk/src/spawn-from-env.ts +245 -0
  382. package/packages/sdk/src/workflows/README.md +656 -0
  383. package/packages/sdk/src/workflows/builder.ts +278 -0
  384. package/packages/sdk/src/workflows/builtin-templates/bug-fix.yaml +135 -0
  385. package/packages/sdk/src/workflows/builtin-templates/code-review.yaml +133 -0
  386. package/packages/sdk/src/workflows/builtin-templates/competitive.yaml +103 -0
  387. package/packages/sdk/src/workflows/builtin-templates/documentation.yaml +120 -0
  388. package/packages/sdk/src/workflows/builtin-templates/feature-dev.yaml +142 -0
  389. package/packages/sdk/src/workflows/builtin-templates/refactor.yaml +141 -0
  390. package/packages/sdk/src/workflows/builtin-templates/review-loop.yaml +223 -0
  391. package/packages/sdk/src/workflows/builtin-templates/security-audit.yaml +129 -0
  392. package/packages/sdk/src/workflows/cli.ts +162 -0
  393. package/packages/sdk/src/workflows/coordinator.ts +842 -0
  394. package/packages/sdk/src/workflows/custom-steps.ts +450 -0
  395. package/packages/sdk/src/workflows/dry-run-format.ts +75 -0
  396. package/packages/sdk/src/workflows/file-db.ts +117 -0
  397. package/packages/sdk/src/workflows/index.ts +24 -0
  398. package/packages/sdk/src/workflows/run.ts +72 -0
  399. package/packages/sdk/src/workflows/runner.ts +3409 -0
  400. package/packages/sdk/src/workflows/schema.json +651 -0
  401. package/packages/sdk/src/workflows/templates.ts +552 -0
  402. package/packages/sdk/src/workflows/trajectory.ts +631 -0
  403. package/packages/sdk/src/workflows/types.ts +389 -0
  404. package/packages/sdk/src/workflows/validator.ts +151 -0
  405. package/packages/sdk/tsconfig.build.json +25 -0
  406. package/packages/sdk/tsconfig.json +17 -18
  407. package/packages/sdk/vitest.config.ts +1 -1
  408. package/packages/sdk-py/README.md +106 -21
  409. package/packages/sdk-py/agent_relay/__init__.py +21 -0
  410. package/packages/sdk-py/agent_relay/models.py +206 -0
  411. package/packages/sdk-py/pyproject.toml +2 -2
  412. package/packages/sdk-py/src/agent_relay/__init__.py +76 -0
  413. package/packages/sdk-py/src/agent_relay/builder.py +430 -109
  414. package/packages/sdk-py/src/agent_relay/templates.py +197 -0
  415. package/packages/sdk-py/src/agent_relay/types.py +489 -15
  416. package/packages/sdk-py/tests/test_builder.py +115 -1
  417. package/packages/sdk-py/tests/test_workflow_templates.py +450 -0
  418. package/packages/shared/cli-registry.yaml +193 -0
  419. package/packages/shared/codegen-py.mjs +215 -0
  420. package/packages/shared/codegen-ts.mjs +227 -0
  421. package/packages/telemetry/dist/events.d.ts +8 -8
  422. package/packages/telemetry/dist/index.d.ts +1 -1
  423. package/packages/telemetry/package.json +2 -2
  424. package/packages/telemetry/src/events.ts +9 -9
  425. package/packages/telemetry/src/index.ts +2 -2
  426. package/packages/trajectory/package.json +2 -2
  427. package/packages/user-directory/dist/user-directory.js +1 -1
  428. package/packages/user-directory/dist/user-directory.js.map +1 -1
  429. package/packages/user-directory/package.json +2 -2
  430. package/packages/user-directory/src/user-directory.ts +1 -1
  431. package/packages/utils/dist/cjs/client-helpers.js +4 -4
  432. package/packages/utils/dist/cjs/discovery.js +9 -6
  433. package/packages/utils/dist/cjs/errors.js +5 -5
  434. package/packages/utils/dist/cjs/legacy-protocol.js +70 -0
  435. package/packages/utils/dist/cjs/logger.js +3 -3
  436. package/packages/utils/dist/cjs/precompiled-patterns.js +33 -2
  437. package/packages/utils/dist/cjs/relay-pty-path.js +0 -6
  438. package/packages/utils/dist/client-helpers.d.ts +1 -1
  439. package/packages/utils/dist/client-helpers.d.ts.map +1 -1
  440. package/packages/utils/dist/client-helpers.js +1 -1
  441. package/packages/utils/dist/client-helpers.js.map +1 -1
  442. package/packages/utils/dist/discovery.d.ts +7 -7
  443. package/packages/utils/dist/discovery.d.ts.map +1 -1
  444. package/packages/utils/dist/discovery.js +20 -17
  445. package/packages/utils/dist/discovery.js.map +1 -1
  446. package/packages/utils/dist/errors.d.ts +1 -1
  447. package/packages/utils/dist/errors.js +3 -3
  448. package/packages/utils/dist/legacy-protocol.d.ts +46 -0
  449. package/packages/utils/dist/legacy-protocol.d.ts.map +1 -0
  450. package/packages/utils/dist/legacy-protocol.js +47 -0
  451. package/packages/utils/dist/legacy-protocol.js.map +1 -0
  452. package/packages/utils/dist/logger.d.ts +2 -2
  453. package/packages/utils/dist/logger.js +2 -2
  454. package/packages/utils/dist/precompiled-patterns.d.ts.map +1 -1
  455. package/packages/utils/dist/precompiled-patterns.js +28 -2
  456. package/packages/utils/dist/precompiled-patterns.js.map +1 -1
  457. package/packages/utils/dist/relay-pty-path.d.ts.map +1 -1
  458. package/packages/utils/dist/relay-pty-path.js +1 -10
  459. package/packages/utils/dist/relay-pty-path.js.map +1 -1
  460. package/packages/utils/package.json +2 -3
  461. package/packages/utils/src/client-helpers.ts +1 -1
  462. package/packages/utils/src/consolidation.test.ts +3 -3
  463. package/packages/utils/src/discovery.test.ts +3 -3
  464. package/packages/utils/src/discovery.ts +21 -18
  465. package/packages/utils/src/errors.test.ts +6 -11
  466. package/packages/utils/src/errors.ts +3 -3
  467. package/packages/utils/src/legacy-protocol.ts +151 -0
  468. package/packages/utils/src/logger.ts +2 -2
  469. package/packages/utils/src/precompiled-patterns.test.ts +8 -0
  470. package/packages/utils/src/precompiled-patterns.ts +40 -2
  471. package/packages/utils/src/relay-pty-path.test.ts +23 -34
  472. package/packages/utils/src/relay-pty-path.ts +1 -11
  473. package/relay-snippets/agent-relay-protocol.md +6 -43
  474. package/relay-snippets/agent-relay-snippet.md +59 -203
  475. package/scripts/postinstall.js +44 -171
  476. package/bin/relay-pty-darwin-arm64 +0 -0
  477. package/bin/relay-pty-darwin-x64 +0 -0
  478. package/bin/relay-pty-linux-arm64 +0 -0
  479. package/bin/relay-pty-linux-x64 +0 -0
  480. package/dist/src/bridge/index.d.ts +0 -8
  481. package/dist/src/bridge/index.d.ts.map +0 -1
  482. package/dist/src/bridge/index.js +0 -8
  483. package/dist/src/bridge/index.js.map +0 -1
  484. package/dist/src/continuity/index.d.ts +0 -5
  485. package/dist/src/continuity/index.d.ts.map +0 -1
  486. package/dist/src/continuity/index.js +0 -5
  487. package/dist/src/continuity/index.js.map +0 -1
  488. package/dist/src/daemon/index.d.ts +0 -8
  489. package/dist/src/daemon/index.d.ts.map +0 -1
  490. package/dist/src/daemon/index.js +0 -9
  491. package/dist/src/daemon/index.js.map +0 -1
  492. package/dist/src/protocol/index.d.ts +0 -8
  493. package/dist/src/protocol/index.d.ts.map +0 -1
  494. package/dist/src/protocol/index.js +0 -8
  495. package/dist/src/protocol/index.js.map +0 -1
  496. package/dist/src/resiliency/index.d.ts +0 -5
  497. package/dist/src/resiliency/index.d.ts.map +0 -1
  498. package/dist/src/resiliency/index.js +0 -5
  499. package/dist/src/resiliency/index.js.map +0 -1
  500. package/dist/src/state/index.d.ts +0 -5
  501. package/dist/src/state/index.d.ts.map +0 -1
  502. package/dist/src/state/index.js +0 -5
  503. package/dist/src/state/index.js.map +0 -1
  504. package/dist/src/storage/index.d.ts +0 -8
  505. package/dist/src/storage/index.d.ts.map +0 -1
  506. package/dist/src/storage/index.js +0 -8
  507. package/dist/src/storage/index.js.map +0 -1
  508. package/dist/src/wrapper/index.d.ts +0 -8
  509. package/dist/src/wrapper/index.d.ts.map +0 -1
  510. package/dist/src/wrapper/index.js +0 -11
  511. package/dist/src/wrapper/index.js.map +0 -1
  512. package/packages/bridge/dist/cli-resolution.d.ts +0 -32
  513. package/packages/bridge/dist/cli-resolution.d.ts.map +0 -1
  514. package/packages/bridge/dist/cli-resolution.js +0 -88
  515. package/packages/bridge/dist/cli-resolution.js.map +0 -1
  516. package/packages/bridge/dist/index.d.ts +0 -9
  517. package/packages/bridge/dist/index.d.ts.map +0 -1
  518. package/packages/bridge/dist/index.js +0 -11
  519. package/packages/bridge/dist/index.js.map +0 -1
  520. package/packages/bridge/dist/multi-project-client.d.ts +0 -99
  521. package/packages/bridge/dist/multi-project-client.d.ts.map +0 -1
  522. package/packages/bridge/dist/multi-project-client.js +0 -389
  523. package/packages/bridge/dist/multi-project-client.js.map +0 -1
  524. package/packages/bridge/dist/shadow-cli.d.ts +0 -17
  525. package/packages/bridge/dist/shadow-cli.d.ts.map +0 -1
  526. package/packages/bridge/dist/shadow-cli.js +0 -75
  527. package/packages/bridge/dist/shadow-cli.js.map +0 -1
  528. package/packages/bridge/dist/spawner.d.ts +0 -263
  529. package/packages/bridge/dist/spawner.d.ts.map +0 -1
  530. package/packages/bridge/dist/spawner.js +0 -1758
  531. package/packages/bridge/dist/spawner.js.map +0 -1
  532. package/packages/bridge/dist/types.d.ts +0 -141
  533. package/packages/bridge/dist/types.d.ts.map +0 -1
  534. package/packages/bridge/dist/types.js +0 -6
  535. package/packages/bridge/dist/types.js.map +0 -1
  536. package/packages/bridge/dist/utils.d.ts +0 -39
  537. package/packages/bridge/dist/utils.d.ts.map +0 -1
  538. package/packages/bridge/dist/utils.js +0 -98
  539. package/packages/bridge/dist/utils.js.map +0 -1
  540. package/packages/bridge/package.json +0 -45
  541. package/packages/bridge/src/cli-resolution.test.ts +0 -225
  542. package/packages/bridge/src/cli-resolution.ts +0 -100
  543. package/packages/bridge/src/index.ts +0 -34
  544. package/packages/bridge/src/multi-project-client.test.ts +0 -340
  545. package/packages/bridge/src/multi-project-client.ts +0 -469
  546. package/packages/bridge/src/shadow-cli.ts +0 -95
  547. package/packages/bridge/src/spawner-mcp.test.ts +0 -505
  548. package/packages/bridge/src/spawner.ts +0 -2067
  549. package/packages/bridge/src/types.ts +0 -153
  550. package/packages/bridge/src/utils.test.ts +0 -235
  551. package/packages/bridge/src/utils.ts +0 -113
  552. package/packages/bridge/tsconfig.json +0 -29
  553. package/packages/bridge/vitest.config.ts +0 -9
  554. package/packages/broker-sdk/README.md +0 -97
  555. package/packages/broker-sdk/dist/__tests__/facade.test.js +0 -257
  556. package/packages/broker-sdk/dist/__tests__/facade.test.js.map +0 -1
  557. package/packages/broker-sdk/dist/__tests__/integration.test.js +0 -139
  558. package/packages/broker-sdk/dist/__tests__/integration.test.js.map +0 -1
  559. package/packages/broker-sdk/dist/__tests__/quickstart.test.js +0 -176
  560. package/packages/broker-sdk/dist/__tests__/quickstart.test.js.map +0 -1
  561. package/packages/broker-sdk/dist/__tests__/unit.test.js +0 -192
  562. package/packages/broker-sdk/dist/__tests__/unit.test.js.map +0 -1
  563. package/packages/broker-sdk/dist/client.d.ts +0 -95
  564. package/packages/broker-sdk/dist/client.d.ts.map +0 -1
  565. package/packages/broker-sdk/dist/client.js +0 -372
  566. package/packages/broker-sdk/dist/client.js.map +0 -1
  567. package/packages/broker-sdk/dist/index.d.ts +0 -10
  568. package/packages/broker-sdk/dist/index.d.ts.map +0 -1
  569. package/packages/broker-sdk/dist/index.js +0 -10
  570. package/packages/broker-sdk/dist/index.js.map +0 -1
  571. package/packages/broker-sdk/dist/logs.d.ts +0 -47
  572. package/packages/broker-sdk/dist/logs.d.ts.map +0 -1
  573. package/packages/broker-sdk/dist/logs.js +0 -137
  574. package/packages/broker-sdk/dist/logs.js.map +0 -1
  575. package/packages/broker-sdk/dist/protocol.d.ts +0 -254
  576. package/packages/broker-sdk/dist/protocol.d.ts.map +0 -1
  577. package/packages/broker-sdk/dist/pty.d.ts.map +0 -1
  578. package/packages/broker-sdk/dist/pty.js +0 -14
  579. package/packages/broker-sdk/dist/pty.js.map +0 -1
  580. package/packages/broker-sdk/dist/relay.d.ts +0 -172
  581. package/packages/broker-sdk/dist/relay.d.ts.map +0 -1
  582. package/packages/broker-sdk/dist/relay.js +0 -486
  583. package/packages/broker-sdk/dist/relay.js.map +0 -1
  584. package/packages/broker-sdk/dist/relaycast.d.ts +0 -67
  585. package/packages/broker-sdk/dist/relaycast.d.ts.map +0 -1
  586. package/packages/broker-sdk/dist/relaycast.js +0 -150
  587. package/packages/broker-sdk/dist/relaycast.js.map +0 -1
  588. package/packages/broker-sdk/dist/shadow.d.ts +0 -100
  589. package/packages/broker-sdk/dist/shadow.d.ts.map +0 -1
  590. package/packages/broker-sdk/dist/shadow.js.map +0 -1
  591. package/packages/broker-sdk/dist/workflows/builder.d.ts +0 -101
  592. package/packages/broker-sdk/dist/workflows/builder.d.ts.map +0 -1
  593. package/packages/broker-sdk/dist/workflows/builder.js +0 -179
  594. package/packages/broker-sdk/dist/workflows/builder.js.map +0 -1
  595. package/packages/broker-sdk/dist/workflows/cli.d.ts +0 -10
  596. package/packages/broker-sdk/dist/workflows/cli.d.ts.map +0 -1
  597. package/packages/broker-sdk/dist/workflows/cli.js +0 -82
  598. package/packages/broker-sdk/dist/workflows/cli.js.map +0 -1
  599. package/packages/broker-sdk/dist/workflows/coordinator.d.ts +0 -69
  600. package/packages/broker-sdk/dist/workflows/coordinator.d.ts.map +0 -1
  601. package/packages/broker-sdk/dist/workflows/coordinator.js +0 -585
  602. package/packages/broker-sdk/dist/workflows/coordinator.js.map +0 -1
  603. package/packages/broker-sdk/dist/workflows/index.d.ts +0 -11
  604. package/packages/broker-sdk/dist/workflows/index.d.ts.map +0 -1
  605. package/packages/broker-sdk/dist/workflows/index.js +0 -11
  606. package/packages/broker-sdk/dist/workflows/index.js.map +0 -1
  607. package/packages/broker-sdk/dist/workflows/run.d.ts +0 -33
  608. package/packages/broker-sdk/dist/workflows/run.d.ts.map +0 -1
  609. package/packages/broker-sdk/dist/workflows/run.js +0 -28
  610. package/packages/broker-sdk/dist/workflows/run.js.map +0 -1
  611. package/packages/broker-sdk/dist/workflows/runner.d.ts +0 -136
  612. package/packages/broker-sdk/dist/workflows/runner.d.ts.map +0 -1
  613. package/packages/broker-sdk/dist/workflows/runner.js +0 -900
  614. package/packages/broker-sdk/dist/workflows/runner.js.map +0 -1
  615. package/packages/broker-sdk/dist/workflows/templates.d.ts +0 -47
  616. package/packages/broker-sdk/dist/workflows/templates.d.ts.map +0 -1
  617. package/packages/broker-sdk/dist/workflows/templates.js +0 -395
  618. package/packages/broker-sdk/dist/workflows/templates.js.map +0 -1
  619. package/packages/broker-sdk/dist/workflows/trajectory.d.ts +0 -80
  620. package/packages/broker-sdk/dist/workflows/trajectory.d.ts.map +0 -1
  621. package/packages/broker-sdk/dist/workflows/trajectory.js +0 -362
  622. package/packages/broker-sdk/dist/workflows/trajectory.js.map +0 -1
  623. package/packages/broker-sdk/dist/workflows/types.d.ts +0 -140
  624. package/packages/broker-sdk/dist/workflows/types.d.ts.map +0 -1
  625. package/packages/broker-sdk/dist/workflows/types.js +0 -8
  626. package/packages/broker-sdk/dist/workflows/types.js.map +0 -1
  627. package/packages/broker-sdk/package.json +0 -81
  628. package/packages/broker-sdk/scripts/bundle-agent-relay.mjs +0 -53
  629. package/packages/broker-sdk/src/__tests__/error-scenarios.test.ts +0 -682
  630. package/packages/broker-sdk/src/__tests__/facade.test.ts +0 -296
  631. package/packages/broker-sdk/src/__tests__/integration.test.ts +0 -170
  632. package/packages/broker-sdk/src/__tests__/quickstart.test.ts +0 -198
  633. package/packages/broker-sdk/src/__tests__/swarm-coordinator.test.ts +0 -772
  634. package/packages/broker-sdk/src/__tests__/unit.test.ts +0 -243
  635. package/packages/broker-sdk/src/__tests__/workflow-runner.test.ts +0 -333
  636. package/packages/broker-sdk/src/client.ts +0 -510
  637. package/packages/broker-sdk/src/index.ts +0 -9
  638. package/packages/broker-sdk/src/logs.ts +0 -163
  639. package/packages/broker-sdk/src/protocol.ts +0 -271
  640. package/packages/broker-sdk/src/pty.ts +0 -16
  641. package/packages/broker-sdk/src/relay.ts +0 -614
  642. package/packages/broker-sdk/src/relaycast.ts +0 -185
  643. package/packages/broker-sdk/src/shadow.ts +0 -230
  644. package/packages/broker-sdk/src/workflows/README.md +0 -514
  645. package/packages/broker-sdk/src/workflows/builder.ts +0 -241
  646. package/packages/broker-sdk/src/workflows/builtin-templates/bug-fix.yaml +0 -75
  647. package/packages/broker-sdk/src/workflows/builtin-templates/code-review.yaml +0 -82
  648. package/packages/broker-sdk/src/workflows/builtin-templates/documentation.yaml +0 -70
  649. package/packages/broker-sdk/src/workflows/builtin-templates/feature-dev.yaml +0 -76
  650. package/packages/broker-sdk/src/workflows/builtin-templates/refactor.yaml +0 -82
  651. package/packages/broker-sdk/src/workflows/builtin-templates/security-audit.yaml +0 -84
  652. package/packages/broker-sdk/src/workflows/cli.ts +0 -93
  653. package/packages/broker-sdk/src/workflows/coordinator.ts +0 -758
  654. package/packages/broker-sdk/src/workflows/index.ts +0 -10
  655. package/packages/broker-sdk/src/workflows/run.ts +0 -55
  656. package/packages/broker-sdk/src/workflows/runner.ts +0 -1184
  657. package/packages/broker-sdk/src/workflows/schema.json +0 -333
  658. package/packages/broker-sdk/src/workflows/templates.ts +0 -544
  659. package/packages/broker-sdk/src/workflows/trajectory.ts +0 -507
  660. package/packages/broker-sdk/src/workflows/types.ts +0 -208
  661. package/packages/broker-sdk/tsconfig.json +0 -22
  662. package/packages/broker-sdk/vitest.config.ts +0 -9
  663. package/packages/continuity/dist/formatter.d.ts +0 -57
  664. package/packages/continuity/dist/formatter.d.ts.map +0 -1
  665. package/packages/continuity/dist/formatter.js +0 -448
  666. package/packages/continuity/dist/formatter.js.map +0 -1
  667. package/packages/continuity/dist/handoff-store.d.ts +0 -67
  668. package/packages/continuity/dist/handoff-store.d.ts.map +0 -1
  669. package/packages/continuity/dist/handoff-store.js +0 -472
  670. package/packages/continuity/dist/handoff-store.js.map +0 -1
  671. package/packages/continuity/dist/index.d.ts +0 -10
  672. package/packages/continuity/dist/index.d.ts.map +0 -1
  673. package/packages/continuity/dist/index.js +0 -11
  674. package/packages/continuity/dist/index.js.map +0 -1
  675. package/packages/continuity/dist/ledger-store.d.ts +0 -110
  676. package/packages/continuity/dist/ledger-store.d.ts.map +0 -1
  677. package/packages/continuity/dist/ledger-store.js +0 -500
  678. package/packages/continuity/dist/ledger-store.js.map +0 -1
  679. package/packages/continuity/dist/manager.d.ts +0 -183
  680. package/packages/continuity/dist/manager.d.ts.map +0 -1
  681. package/packages/continuity/dist/manager.js +0 -616
  682. package/packages/continuity/dist/manager.js.map +0 -1
  683. package/packages/continuity/dist/parser.d.ts +0 -76
  684. package/packages/continuity/dist/parser.d.ts.map +0 -1
  685. package/packages/continuity/dist/parser.js +0 -579
  686. package/packages/continuity/dist/parser.js.map +0 -1
  687. package/packages/continuity/dist/types.d.ts +0 -180
  688. package/packages/continuity/dist/types.d.ts.map +0 -1
  689. package/packages/continuity/dist/types.js +0 -2
  690. package/packages/continuity/dist/types.js.map +0 -1
  691. package/packages/continuity/package.json +0 -40
  692. package/packages/continuity/src/formatter.ts +0 -536
  693. package/packages/continuity/src/handoff-store.ts +0 -523
  694. package/packages/continuity/src/index.ts +0 -12
  695. package/packages/continuity/src/ledger-store.ts +0 -594
  696. package/packages/continuity/src/manager.test.ts +0 -291
  697. package/packages/continuity/src/manager.ts +0 -774
  698. package/packages/continuity/src/parser.test.ts +0 -292
  699. package/packages/continuity/src/parser.ts +0 -680
  700. package/packages/continuity/src/types.ts +0 -211
  701. package/packages/continuity/tsconfig.json +0 -21
  702. package/packages/continuity/vitest.config.ts +0 -9
  703. package/packages/daemon/dist/agent-manager.d.ts +0 -134
  704. package/packages/daemon/dist/agent-manager.d.ts.map +0 -1
  705. package/packages/daemon/dist/agent-manager.js +0 -578
  706. package/packages/daemon/dist/agent-manager.js.map +0 -1
  707. package/packages/daemon/dist/agent-registry.d.ts +0 -99
  708. package/packages/daemon/dist/agent-registry.d.ts.map +0 -1
  709. package/packages/daemon/dist/agent-registry.js +0 -213
  710. package/packages/daemon/dist/agent-registry.js.map +0 -1
  711. package/packages/daemon/dist/agent-signing.d.ts +0 -158
  712. package/packages/daemon/dist/agent-signing.d.ts.map +0 -1
  713. package/packages/daemon/dist/agent-signing.js +0 -523
  714. package/packages/daemon/dist/agent-signing.js.map +0 -1
  715. package/packages/daemon/dist/api.d.ts +0 -106
  716. package/packages/daemon/dist/api.d.ts.map +0 -1
  717. package/packages/daemon/dist/api.js +0 -895
  718. package/packages/daemon/dist/api.js.map +0 -1
  719. package/packages/daemon/dist/auth.d.ts +0 -94
  720. package/packages/daemon/dist/auth.d.ts.map +0 -1
  721. package/packages/daemon/dist/auth.js +0 -197
  722. package/packages/daemon/dist/auth.js.map +0 -1
  723. package/packages/daemon/dist/channel-membership-store.d.ts +0 -55
  724. package/packages/daemon/dist/channel-membership-store.d.ts.map +0 -1
  725. package/packages/daemon/dist/channel-membership-store.js +0 -176
  726. package/packages/daemon/dist/channel-membership-store.js.map +0 -1
  727. package/packages/daemon/dist/cli-auth.d.ts +0 -97
  728. package/packages/daemon/dist/cli-auth.d.ts.map +0 -1
  729. package/packages/daemon/dist/cli-auth.js +0 -808
  730. package/packages/daemon/dist/cli-auth.js.map +0 -1
  731. package/packages/daemon/dist/cloud-sync.d.ts +0 -263
  732. package/packages/daemon/dist/cloud-sync.d.ts.map +0 -1
  733. package/packages/daemon/dist/cloud-sync.js +0 -820
  734. package/packages/daemon/dist/cloud-sync.js.map +0 -1
  735. package/packages/daemon/dist/connection.d.ts +0 -137
  736. package/packages/daemon/dist/connection.d.ts.map +0 -1
  737. package/packages/daemon/dist/connection.js +0 -465
  738. package/packages/daemon/dist/connection.js.map +0 -1
  739. package/packages/daemon/dist/consensus-integration.d.ts +0 -168
  740. package/packages/daemon/dist/consensus-integration.d.ts.map +0 -1
  741. package/packages/daemon/dist/consensus-integration.js +0 -371
  742. package/packages/daemon/dist/consensus-integration.js.map +0 -1
  743. package/packages/daemon/dist/consensus.d.ts +0 -269
  744. package/packages/daemon/dist/consensus.d.ts.map +0 -1
  745. package/packages/daemon/dist/consensus.js +0 -632
  746. package/packages/daemon/dist/consensus.js.map +0 -1
  747. package/packages/daemon/dist/delivery-tracker.d.ts +0 -34
  748. package/packages/daemon/dist/delivery-tracker.d.ts.map +0 -1
  749. package/packages/daemon/dist/delivery-tracker.js +0 -104
  750. package/packages/daemon/dist/delivery-tracker.js.map +0 -1
  751. package/packages/daemon/dist/enhanced-features.d.ts +0 -118
  752. package/packages/daemon/dist/enhanced-features.d.ts.map +0 -1
  753. package/packages/daemon/dist/enhanced-features.js +0 -177
  754. package/packages/daemon/dist/enhanced-features.js.map +0 -1
  755. package/packages/daemon/dist/index.d.ts +0 -29
  756. package/packages/daemon/dist/index.d.ts.map +0 -1
  757. package/packages/daemon/dist/index.js +0 -34
  758. package/packages/daemon/dist/index.js.map +0 -1
  759. package/packages/daemon/dist/orchestrator.d.ts +0 -217
  760. package/packages/daemon/dist/orchestrator.d.ts.map +0 -1
  761. package/packages/daemon/dist/orchestrator.js +0 -1172
  762. package/packages/daemon/dist/orchestrator.js.map +0 -1
  763. package/packages/daemon/dist/rate-limiter.d.ts +0 -68
  764. package/packages/daemon/dist/rate-limiter.d.ts.map +0 -1
  765. package/packages/daemon/dist/rate-limiter.js +0 -130
  766. package/packages/daemon/dist/rate-limiter.js.map +0 -1
  767. package/packages/daemon/dist/registry.d.ts +0 -9
  768. package/packages/daemon/dist/registry.d.ts.map +0 -1
  769. package/packages/daemon/dist/registry.js +0 -9
  770. package/packages/daemon/dist/registry.js.map +0 -1
  771. package/packages/daemon/dist/repo-manager.d.ts +0 -116
  772. package/packages/daemon/dist/repo-manager.d.ts.map +0 -1
  773. package/packages/daemon/dist/repo-manager.js +0 -384
  774. package/packages/daemon/dist/repo-manager.js.map +0 -1
  775. package/packages/daemon/dist/router.d.ts +0 -389
  776. package/packages/daemon/dist/router.d.ts.map +0 -1
  777. package/packages/daemon/dist/router.js +0 -1607
  778. package/packages/daemon/dist/router.js.map +0 -1
  779. package/packages/daemon/dist/server.d.ts +0 -201
  780. package/packages/daemon/dist/server.d.ts.map +0 -1
  781. package/packages/daemon/dist/server.js +0 -1791
  782. package/packages/daemon/dist/server.js.map +0 -1
  783. package/packages/daemon/dist/spawn-manager.d.ts +0 -119
  784. package/packages/daemon/dist/spawn-manager.d.ts.map +0 -1
  785. package/packages/daemon/dist/spawn-manager.js +0 -319
  786. package/packages/daemon/dist/spawn-manager.js.map +0 -1
  787. package/packages/daemon/dist/sync-queue.d.ts +0 -116
  788. package/packages/daemon/dist/sync-queue.d.ts.map +0 -1
  789. package/packages/daemon/dist/sync-queue.js +0 -361
  790. package/packages/daemon/dist/sync-queue.js.map +0 -1
  791. package/packages/daemon/dist/types.d.ts +0 -133
  792. package/packages/daemon/dist/types.d.ts.map +0 -1
  793. package/packages/daemon/dist/types.js +0 -6
  794. package/packages/daemon/dist/types.js.map +0 -1
  795. package/packages/daemon/dist/workspace-manager.d.ts +0 -80
  796. package/packages/daemon/dist/workspace-manager.d.ts.map +0 -1
  797. package/packages/daemon/dist/workspace-manager.js +0 -314
  798. package/packages/daemon/dist/workspace-manager.js.map +0 -1
  799. package/packages/daemon/package.json +0 -56
  800. package/packages/daemon/src/agent-manager.ts +0 -679
  801. package/packages/daemon/src/agent-registry.ts +0 -284
  802. package/packages/daemon/src/agent-signing.ts +0 -707
  803. package/packages/daemon/src/api.ts +0 -1034
  804. package/packages/daemon/src/auth.ts +0 -276
  805. package/packages/daemon/src/channel-membership-store.ts +0 -217
  806. package/packages/daemon/src/cli-auth.ts +0 -945
  807. package/packages/daemon/src/cloud-sync.ts +0 -1100
  808. package/packages/daemon/src/connection.ts +0 -561
  809. package/packages/daemon/src/consensus-integration.ts +0 -510
  810. package/packages/daemon/src/consensus.ts +0 -848
  811. package/packages/daemon/src/delivery-tracker.ts +0 -145
  812. package/packages/daemon/src/enhanced-features.ts +0 -390
  813. package/packages/daemon/src/index.ts +0 -48
  814. package/packages/daemon/src/orchestrator.test.ts +0 -231
  815. package/packages/daemon/src/orchestrator.ts +0 -1376
  816. package/packages/daemon/src/rate-limiter.ts +0 -172
  817. package/packages/daemon/src/registry.ts +0 -8
  818. package/packages/daemon/src/repo-manager.ts +0 -468
  819. package/packages/daemon/src/router.test.ts +0 -181
  820. package/packages/daemon/src/router.ts +0 -1925
  821. package/packages/daemon/src/server.ts +0 -2051
  822. package/packages/daemon/src/spawn-manager-set-model.test.ts +0 -144
  823. package/packages/daemon/src/spawn-manager.ts +0 -415
  824. package/packages/daemon/src/sync-queue.ts +0 -477
  825. package/packages/daemon/src/types.ts +0 -158
  826. package/packages/daemon/src/workspace-manager.ts +0 -371
  827. package/packages/daemon/tsconfig.json +0 -21
  828. package/packages/daemon/vitest.config.ts +0 -9
  829. package/packages/mcp/CHANGELOG.md +0 -28
  830. package/packages/mcp/LICENSE +0 -190
  831. package/packages/mcp/README.md +0 -266
  832. package/packages/mcp/dist/bin.d.ts +0 -12
  833. package/packages/mcp/dist/bin.d.ts.map +0 -1
  834. package/packages/mcp/dist/bin.js +0 -179
  835. package/packages/mcp/dist/bin.js.map +0 -1
  836. package/packages/mcp/dist/client-adapter.d.ts +0 -164
  837. package/packages/mcp/dist/client-adapter.d.ts.map +0 -1
  838. package/packages/mcp/dist/client-adapter.js +0 -231
  839. package/packages/mcp/dist/client-adapter.js.map +0 -1
  840. package/packages/mcp/dist/cloud.d.ts +0 -13
  841. package/packages/mcp/dist/cloud.d.ts.map +0 -1
  842. package/packages/mcp/dist/cloud.js +0 -25
  843. package/packages/mcp/dist/cloud.js.map +0 -1
  844. package/packages/mcp/dist/errors.d.ts +0 -9
  845. package/packages/mcp/dist/errors.d.ts.map +0 -1
  846. package/packages/mcp/dist/errors.js +0 -9
  847. package/packages/mcp/dist/errors.js.map +0 -1
  848. package/packages/mcp/dist/file-transport.d.ts +0 -103
  849. package/packages/mcp/dist/file-transport.d.ts.map +0 -1
  850. package/packages/mcp/dist/file-transport.js +0 -204
  851. package/packages/mcp/dist/file-transport.js.map +0 -1
  852. package/packages/mcp/dist/hybrid-client.d.ts +0 -5
  853. package/packages/mcp/dist/hybrid-client.d.ts.map +0 -1
  854. package/packages/mcp/dist/hybrid-client.js +0 -23
  855. package/packages/mcp/dist/hybrid-client.js.map +0 -1
  856. package/packages/mcp/dist/index.d.ts +0 -11
  857. package/packages/mcp/dist/index.d.ts.map +0 -1
  858. package/packages/mcp/dist/index.js +0 -25
  859. package/packages/mcp/dist/index.js.map +0 -1
  860. package/packages/mcp/dist/install-cli.d.ts +0 -35
  861. package/packages/mcp/dist/install-cli.d.ts.map +0 -1
  862. package/packages/mcp/dist/install-cli.js +0 -157
  863. package/packages/mcp/dist/install-cli.js.map +0 -1
  864. package/packages/mcp/dist/install.d.ts +0 -123
  865. package/packages/mcp/dist/install.d.ts.map +0 -1
  866. package/packages/mcp/dist/install.js +0 -661
  867. package/packages/mcp/dist/install.js.map +0 -1
  868. package/packages/mcp/dist/prompts/index.d.ts +0 -2
  869. package/packages/mcp/dist/prompts/index.d.ts.map +0 -1
  870. package/packages/mcp/dist/prompts/index.js +0 -2
  871. package/packages/mcp/dist/prompts/index.js.map +0 -1
  872. package/packages/mcp/dist/prompts/protocol.d.ts +0 -11
  873. package/packages/mcp/dist/prompts/protocol.d.ts.map +0 -1
  874. package/packages/mcp/dist/prompts/protocol.js +0 -160
  875. package/packages/mcp/dist/prompts/protocol.js.map +0 -1
  876. package/packages/mcp/dist/resources/agents.d.ts +0 -11
  877. package/packages/mcp/dist/resources/agents.d.ts.map +0 -1
  878. package/packages/mcp/dist/resources/agents.js +0 -17
  879. package/packages/mcp/dist/resources/agents.js.map +0 -1
  880. package/packages/mcp/dist/resources/inbox.d.ts +0 -11
  881. package/packages/mcp/dist/resources/inbox.d.ts.map +0 -1
  882. package/packages/mcp/dist/resources/inbox.js +0 -17
  883. package/packages/mcp/dist/resources/inbox.js.map +0 -1
  884. package/packages/mcp/dist/resources/index.d.ts +0 -4
  885. package/packages/mcp/dist/resources/index.d.ts.map +0 -1
  886. package/packages/mcp/dist/resources/index.js +0 -4
  887. package/packages/mcp/dist/resources/index.js.map +0 -1
  888. package/packages/mcp/dist/resources/project.d.ts +0 -11
  889. package/packages/mcp/dist/resources/project.d.ts.map +0 -1
  890. package/packages/mcp/dist/resources/project.js +0 -21
  891. package/packages/mcp/dist/resources/project.js.map +0 -1
  892. package/packages/mcp/dist/server.d.ts +0 -23
  893. package/packages/mcp/dist/server.d.ts.map +0 -1
  894. package/packages/mcp/dist/server.js +0 -317
  895. package/packages/mcp/dist/server.js.map +0 -1
  896. package/packages/mcp/dist/simple.d.ts +0 -170
  897. package/packages/mcp/dist/simple.d.ts.map +0 -1
  898. package/packages/mcp/dist/simple.js +0 -120
  899. package/packages/mcp/dist/simple.js.map +0 -1
  900. package/packages/mcp/dist/tools/index.d.ts +0 -20
  901. package/packages/mcp/dist/tools/index.d.ts.map +0 -1
  902. package/packages/mcp/dist/tools/index.js +0 -20
  903. package/packages/mcp/dist/tools/index.js.map +0 -1
  904. package/packages/mcp/dist/tools/relay-broadcast.d.ts +0 -20
  905. package/packages/mcp/dist/tools/relay-broadcast.d.ts.map +0 -1
  906. package/packages/mcp/dist/tools/relay-broadcast.js +0 -25
  907. package/packages/mcp/dist/tools/relay-broadcast.js.map +0 -1
  908. package/packages/mcp/dist/tools/relay-channel.d.ts +0 -75
  909. package/packages/mcp/dist/tools/relay-channel.d.ts.map +0 -1
  910. package/packages/mcp/dist/tools/relay-channel.js +0 -124
  911. package/packages/mcp/dist/tools/relay-channel.js.map +0 -1
  912. package/packages/mcp/dist/tools/relay-connected.d.ts +0 -17
  913. package/packages/mcp/dist/tools/relay-connected.d.ts.map +0 -1
  914. package/packages/mcp/dist/tools/relay-connected.js +0 -54
  915. package/packages/mcp/dist/tools/relay-connected.js.map +0 -1
  916. package/packages/mcp/dist/tools/relay-consensus.d.ts +0 -45
  917. package/packages/mcp/dist/tools/relay-consensus.d.ts.map +0 -1
  918. package/packages/mcp/dist/tools/relay-consensus.js +0 -80
  919. package/packages/mcp/dist/tools/relay-consensus.js.map +0 -1
  920. package/packages/mcp/dist/tools/relay-continuity.d.ts +0 -35
  921. package/packages/mcp/dist/tools/relay-continuity.d.ts.map +0 -1
  922. package/packages/mcp/dist/tools/relay-continuity.js +0 -101
  923. package/packages/mcp/dist/tools/relay-continuity.js.map +0 -1
  924. package/packages/mcp/dist/tools/relay-health.d.ts +0 -20
  925. package/packages/mcp/dist/tools/relay-health.d.ts.map +0 -1
  926. package/packages/mcp/dist/tools/relay-health.js +0 -130
  927. package/packages/mcp/dist/tools/relay-health.js.map +0 -1
  928. package/packages/mcp/dist/tools/relay-inbox.d.ts +0 -26
  929. package/packages/mcp/dist/tools/relay-inbox.d.ts.map +0 -1
  930. package/packages/mcp/dist/tools/relay-inbox.js +0 -58
  931. package/packages/mcp/dist/tools/relay-inbox.js.map +0 -1
  932. package/packages/mcp/dist/tools/relay-logs.d.ts +0 -20
  933. package/packages/mcp/dist/tools/relay-logs.d.ts.map +0 -1
  934. package/packages/mcp/dist/tools/relay-logs.js +0 -90
  935. package/packages/mcp/dist/tools/relay-logs.js.map +0 -1
  936. package/packages/mcp/dist/tools/relay-messages.d.ts +0 -32
  937. package/packages/mcp/dist/tools/relay-messages.d.ts.map +0 -1
  938. package/packages/mcp/dist/tools/relay-messages.js +0 -61
  939. package/packages/mcp/dist/tools/relay-messages.js.map +0 -1
  940. package/packages/mcp/dist/tools/relay-metrics.d.ts +0 -17
  941. package/packages/mcp/dist/tools/relay-metrics.d.ts.map +0 -1
  942. package/packages/mcp/dist/tools/relay-metrics.js +0 -124
  943. package/packages/mcp/dist/tools/relay-metrics.js.map +0 -1
  944. package/packages/mcp/dist/tools/relay-release.d.ts +0 -20
  945. package/packages/mcp/dist/tools/relay-release.d.ts.map +0 -1
  946. package/packages/mcp/dist/tools/relay-release.js +0 -44
  947. package/packages/mcp/dist/tools/relay-release.js.map +0 -1
  948. package/packages/mcp/dist/tools/relay-remove-agent.d.ts +0 -20
  949. package/packages/mcp/dist/tools/relay-remove-agent.d.ts.map +0 -1
  950. package/packages/mcp/dist/tools/relay-remove-agent.js +0 -50
  951. package/packages/mcp/dist/tools/relay-remove-agent.js.map +0 -1
  952. package/packages/mcp/dist/tools/relay-send.d.ts +0 -29
  953. package/packages/mcp/dist/tools/relay-send.d.ts.map +0 -1
  954. package/packages/mcp/dist/tools/relay-send.js +0 -73
  955. package/packages/mcp/dist/tools/relay-send.js.map +0 -1
  956. package/packages/mcp/dist/tools/relay-set-model.d.ts +0 -23
  957. package/packages/mcp/dist/tools/relay-set-model.d.ts.map +0 -1
  958. package/packages/mcp/dist/tools/relay-set-model.js +0 -52
  959. package/packages/mcp/dist/tools/relay-set-model.js.map +0 -1
  960. package/packages/mcp/dist/tools/relay-shadow.d.ts +0 -30
  961. package/packages/mcp/dist/tools/relay-shadow.d.ts.map +0 -1
  962. package/packages/mcp/dist/tools/relay-shadow.js +0 -55
  963. package/packages/mcp/dist/tools/relay-shadow.js.map +0 -1
  964. package/packages/mcp/dist/tools/relay-spawn.d.ts +0 -36
  965. package/packages/mcp/dist/tools/relay-spawn.d.ts.map +0 -1
  966. package/packages/mcp/dist/tools/relay-spawn.js +0 -73
  967. package/packages/mcp/dist/tools/relay-spawn.js.map +0 -1
  968. package/packages/mcp/dist/tools/relay-status.d.ts +0 -11
  969. package/packages/mcp/dist/tools/relay-status.d.ts.map +0 -1
  970. package/packages/mcp/dist/tools/relay-status.js +0 -43
  971. package/packages/mcp/dist/tools/relay-status.js.map +0 -1
  972. package/packages/mcp/dist/tools/relay-subscribe.d.ts +0 -27
  973. package/packages/mcp/dist/tools/relay-subscribe.d.ts.map +0 -1
  974. package/packages/mcp/dist/tools/relay-subscribe.js +0 -49
  975. package/packages/mcp/dist/tools/relay-subscribe.js.map +0 -1
  976. package/packages/mcp/dist/tools/relay-who.d.ts +0 -20
  977. package/packages/mcp/dist/tools/relay-who.d.ts.map +0 -1
  978. package/packages/mcp/dist/tools/relay-who.js +0 -62
  979. package/packages/mcp/dist/tools/relay-who.js.map +0 -1
  980. package/packages/mcp/package.json +0 -82
  981. package/packages/mcp/src/bin.ts +0 -200
  982. package/packages/mcp/src/client-adapter.ts +0 -358
  983. package/packages/mcp/src/cloud.ts +0 -41
  984. package/packages/mcp/src/errors.ts +0 -17
  985. package/packages/mcp/src/file-transport.ts +0 -275
  986. package/packages/mcp/src/hybrid-client.ts +0 -25
  987. package/packages/mcp/src/index.ts +0 -143
  988. package/packages/mcp/src/install-cli.ts +0 -210
  989. package/packages/mcp/src/install.ts +0 -820
  990. package/packages/mcp/src/prompts/index.ts +0 -1
  991. package/packages/mcp/src/prompts/protocol.ts +0 -164
  992. package/packages/mcp/src/resources/agents.ts +0 -21
  993. package/packages/mcp/src/resources/inbox.ts +0 -21
  994. package/packages/mcp/src/resources/index.ts +0 -3
  995. package/packages/mcp/src/resources/project.ts +0 -29
  996. package/packages/mcp/src/server.ts +0 -475
  997. package/packages/mcp/src/simple.ts +0 -214
  998. package/packages/mcp/src/tools/index.ts +0 -155
  999. package/packages/mcp/src/tools/relay-broadcast.ts +0 -32
  1000. package/packages/mcp/src/tools/relay-channel.ts +0 -151
  1001. package/packages/mcp/src/tools/relay-connected.ts +0 -67
  1002. package/packages/mcp/src/tools/relay-consensus.ts +0 -92
  1003. package/packages/mcp/src/tools/relay-continuity.ts +0 -127
  1004. package/packages/mcp/src/tools/relay-health.ts +0 -148
  1005. package/packages/mcp/src/tools/relay-inbox.ts +0 -70
  1006. package/packages/mcp/src/tools/relay-logs.ts +0 -106
  1007. package/packages/mcp/src/tools/relay-messages.ts +0 -66
  1008. package/packages/mcp/src/tools/relay-metrics.ts +0 -142
  1009. package/packages/mcp/src/tools/relay-release.ts +0 -54
  1010. package/packages/mcp/src/tools/relay-remove-agent.ts +0 -58
  1011. package/packages/mcp/src/tools/relay-send.ts +0 -84
  1012. package/packages/mcp/src/tools/relay-set-model.ts +0 -62
  1013. package/packages/mcp/src/tools/relay-shadow.ts +0 -67
  1014. package/packages/mcp/src/tools/relay-spawn.ts +0 -87
  1015. package/packages/mcp/src/tools/relay-status.ts +0 -57
  1016. package/packages/mcp/src/tools/relay-subscribe.ts +0 -61
  1017. package/packages/mcp/src/tools/relay-who.ts +0 -75
  1018. package/packages/mcp/tests/client.test.ts +0 -451
  1019. package/packages/mcp/tests/discover.test.ts +0 -256
  1020. package/packages/mcp/tests/install.test.ts +0 -123
  1021. package/packages/mcp/tests/prompts.test.ts +0 -12
  1022. package/packages/mcp/tests/resources.test.ts +0 -53
  1023. package/packages/mcp/tests/tools.test.ts +0 -1516
  1024. package/packages/mcp/tsconfig.json +0 -22
  1025. package/packages/mcp/vitest.config.ts +0 -9
  1026. package/packages/protocol/dist/channels.d.ts +0 -137
  1027. package/packages/protocol/dist/channels.d.ts.map +0 -1
  1028. package/packages/protocol/dist/channels.js +0 -154
  1029. package/packages/protocol/dist/channels.js.map +0 -1
  1030. package/packages/protocol/dist/framing.d.ts +0 -80
  1031. package/packages/protocol/dist/framing.d.ts.map +0 -1
  1032. package/packages/protocol/dist/framing.js +0 -206
  1033. package/packages/protocol/dist/framing.js.map +0 -1
  1034. package/packages/protocol/dist/id-generator.d.ts +0 -35
  1035. package/packages/protocol/dist/id-generator.d.ts.map +0 -1
  1036. package/packages/protocol/dist/id-generator.js +0 -60
  1037. package/packages/protocol/dist/id-generator.js.map +0 -1
  1038. package/packages/protocol/dist/index.d.ts +0 -5
  1039. package/packages/protocol/dist/index.d.ts.map +0 -1
  1040. package/packages/protocol/dist/index.js +0 -5
  1041. package/packages/protocol/dist/index.js.map +0 -1
  1042. package/packages/protocol/dist/relay-pty-schemas.d.ts +0 -340
  1043. package/packages/protocol/dist/relay-pty-schemas.d.ts.map +0 -1
  1044. package/packages/protocol/dist/relay-pty-schemas.js +0 -60
  1045. package/packages/protocol/dist/relay-pty-schemas.js.map +0 -1
  1046. package/packages/protocol/dist/types.d.ts +0 -793
  1047. package/packages/protocol/dist/types.d.ts.map +0 -1
  1048. package/packages/protocol/dist/types.js +0 -8
  1049. package/packages/protocol/dist/types.js.map +0 -1
  1050. package/packages/protocol/package.json +0 -61
  1051. package/packages/protocol/src/channels.test.ts +0 -330
  1052. package/packages/protocol/src/channels.ts +0 -270
  1053. package/packages/protocol/src/framing.test.ts +0 -164
  1054. package/packages/protocol/src/framing.ts +0 -242
  1055. package/packages/protocol/src/id-generator.ts +0 -69
  1056. package/packages/protocol/src/index.ts +0 -4
  1057. package/packages/protocol/src/relay-pty-schemas.ts +0 -400
  1058. package/packages/protocol/src/types.test.ts +0 -271
  1059. package/packages/protocol/src/types.ts +0 -988
  1060. package/packages/protocol/tsconfig.json +0 -21
  1061. package/packages/protocol/vitest.config.ts +0 -9
  1062. package/packages/resiliency/dist/cgroup-manager.d.ts +0 -152
  1063. package/packages/resiliency/dist/cgroup-manager.d.ts.map +0 -1
  1064. package/packages/resiliency/dist/cgroup-manager.js +0 -394
  1065. package/packages/resiliency/dist/cgroup-manager.js.map +0 -1
  1066. package/packages/resiliency/dist/context-persistence.d.ts +0 -140
  1067. package/packages/resiliency/dist/context-persistence.d.ts.map +0 -1
  1068. package/packages/resiliency/dist/context-persistence.js +0 -397
  1069. package/packages/resiliency/dist/context-persistence.js.map +0 -1
  1070. package/packages/resiliency/dist/crash-insights.d.ts +0 -156
  1071. package/packages/resiliency/dist/crash-insights.d.ts.map +0 -1
  1072. package/packages/resiliency/dist/crash-insights.js +0 -492
  1073. package/packages/resiliency/dist/crash-insights.js.map +0 -1
  1074. package/packages/resiliency/dist/gossip-health.d.ts +0 -137
  1075. package/packages/resiliency/dist/gossip-health.d.ts.map +0 -1
  1076. package/packages/resiliency/dist/gossip-health.js +0 -241
  1077. package/packages/resiliency/dist/gossip-health.js.map +0 -1
  1078. package/packages/resiliency/dist/health-monitor.d.ts +0 -97
  1079. package/packages/resiliency/dist/health-monitor.d.ts.map +0 -1
  1080. package/packages/resiliency/dist/health-monitor.js +0 -291
  1081. package/packages/resiliency/dist/health-monitor.js.map +0 -1
  1082. package/packages/resiliency/dist/index.d.ts +0 -69
  1083. package/packages/resiliency/dist/index.d.ts.map +0 -1
  1084. package/packages/resiliency/dist/index.js +0 -69
  1085. package/packages/resiliency/dist/index.js.map +0 -1
  1086. package/packages/resiliency/dist/leader-watchdog.d.ts +0 -109
  1087. package/packages/resiliency/dist/leader-watchdog.d.ts.map +0 -1
  1088. package/packages/resiliency/dist/leader-watchdog.js +0 -189
  1089. package/packages/resiliency/dist/leader-watchdog.js.map +0 -1
  1090. package/packages/resiliency/dist/logger.d.ts +0 -114
  1091. package/packages/resiliency/dist/logger.d.ts.map +0 -1
  1092. package/packages/resiliency/dist/logger.js +0 -250
  1093. package/packages/resiliency/dist/logger.js.map +0 -1
  1094. package/packages/resiliency/dist/memory-monitor.d.ts +0 -172
  1095. package/packages/resiliency/dist/memory-monitor.d.ts.map +0 -1
  1096. package/packages/resiliency/dist/memory-monitor.js +0 -599
  1097. package/packages/resiliency/dist/memory-monitor.js.map +0 -1
  1098. package/packages/resiliency/dist/metrics.d.ts +0 -115
  1099. package/packages/resiliency/dist/metrics.d.ts.map +0 -1
  1100. package/packages/resiliency/dist/metrics.js +0 -239
  1101. package/packages/resiliency/dist/metrics.js.map +0 -1
  1102. package/packages/resiliency/dist/provider-context.d.ts +0 -100
  1103. package/packages/resiliency/dist/provider-context.d.ts.map +0 -1
  1104. package/packages/resiliency/dist/provider-context.js +0 -362
  1105. package/packages/resiliency/dist/provider-context.js.map +0 -1
  1106. package/packages/resiliency/dist/stateless-lead.d.ts +0 -149
  1107. package/packages/resiliency/dist/stateless-lead.d.ts.map +0 -1
  1108. package/packages/resiliency/dist/stateless-lead.js +0 -308
  1109. package/packages/resiliency/dist/stateless-lead.js.map +0 -1
  1110. package/packages/resiliency/dist/supervisor.d.ts +0 -147
  1111. package/packages/resiliency/dist/supervisor.d.ts.map +0 -1
  1112. package/packages/resiliency/dist/supervisor.js +0 -459
  1113. package/packages/resiliency/dist/supervisor.js.map +0 -1
  1114. package/packages/resiliency/package.json +0 -38
  1115. package/packages/resiliency/src/cgroup-manager.ts +0 -468
  1116. package/packages/resiliency/src/context-persistence.ts +0 -538
  1117. package/packages/resiliency/src/crash-insights.test.ts +0 -620
  1118. package/packages/resiliency/src/crash-insights.ts +0 -660
  1119. package/packages/resiliency/src/gossip-health.ts +0 -333
  1120. package/packages/resiliency/src/health-monitor.ts +0 -371
  1121. package/packages/resiliency/src/index.ts +0 -157
  1122. package/packages/resiliency/src/leader-watchdog.ts +0 -260
  1123. package/packages/resiliency/src/logger.ts +0 -320
  1124. package/packages/resiliency/src/memory-monitor.test.ts +0 -637
  1125. package/packages/resiliency/src/memory-monitor.ts +0 -740
  1126. package/packages/resiliency/src/metrics.ts +0 -311
  1127. package/packages/resiliency/src/provider-context.ts +0 -452
  1128. package/packages/resiliency/src/stateless-lead.ts +0 -408
  1129. package/packages/resiliency/src/supervisor.ts +0 -578
  1130. package/packages/resiliency/tsconfig.json +0 -21
  1131. package/packages/resiliency/vitest.config.ts +0 -9
  1132. package/packages/sdk/dist/discovery.d.ts +0 -10
  1133. package/packages/sdk/dist/discovery.d.ts.map +0 -1
  1134. package/packages/sdk/dist/discovery.js +0 -22
  1135. package/packages/sdk/dist/discovery.js.map +0 -1
  1136. package/packages/sdk/dist/errors.d.ts +0 -9
  1137. package/packages/sdk/dist/errors.d.ts.map +0 -1
  1138. package/packages/sdk/dist/errors.js +0 -9
  1139. package/packages/sdk/dist/errors.js.map +0 -1
  1140. package/packages/sdk/dist/protocol/index.d.ts +0 -8
  1141. package/packages/sdk/dist/protocol/index.d.ts.map +0 -1
  1142. package/packages/sdk/dist/protocol/index.js +0 -8
  1143. package/packages/sdk/dist/protocol/index.js.map +0 -1
  1144. package/packages/sdk/examples/SWARM_CAPABILITIES.md +0 -498
  1145. package/packages/sdk/examples/SWARM_PATTERNS.md +0 -541
  1146. package/packages/sdk/src/client.test.ts +0 -1041
  1147. package/packages/sdk/src/discovery.ts +0 -38
  1148. package/packages/sdk/src/errors.ts +0 -17
  1149. package/packages/sdk/src/logs.test.ts +0 -98
  1150. package/packages/sdk/src/protocol/framing.test.ts +0 -164
  1151. package/packages/sdk/src/protocol/index.ts +0 -8
  1152. package/packages/spawner/.trajectories/index.json +0 -5
  1153. package/packages/spawner/API.md +0 -256
  1154. package/packages/spawner/dist/index.d.ts +0 -8
  1155. package/packages/spawner/dist/index.d.ts.map +0 -1
  1156. package/packages/spawner/dist/index.js +0 -8
  1157. package/packages/spawner/dist/index.js.map +0 -1
  1158. package/packages/spawner/dist/types.d.ts +0 -552
  1159. package/packages/spawner/dist/types.d.ts.map +0 -1
  1160. package/packages/spawner/dist/types.js +0 -193
  1161. package/packages/spawner/dist/types.js.map +0 -1
  1162. package/packages/spawner/package.json +0 -47
  1163. package/packages/spawner/src/index.ts +0 -8
  1164. package/packages/spawner/src/types.test.ts +0 -385
  1165. package/packages/spawner/src/types.ts +0 -228
  1166. package/packages/spawner/tsconfig.json +0 -19
  1167. package/packages/spawner/vitest.config.ts +0 -9
  1168. package/packages/state/dist/agent-state.d.ts +0 -40
  1169. package/packages/state/dist/agent-state.d.ts.map +0 -1
  1170. package/packages/state/dist/agent-state.js +0 -120
  1171. package/packages/state/dist/agent-state.js.map +0 -1
  1172. package/packages/state/dist/index.d.ts +0 -8
  1173. package/packages/state/dist/index.d.ts.map +0 -1
  1174. package/packages/state/dist/index.js +0 -8
  1175. package/packages/state/dist/index.js.map +0 -1
  1176. package/packages/state/package.json +0 -37
  1177. package/packages/state/src/agent-state.test.ts +0 -335
  1178. package/packages/state/src/agent-state.ts +0 -153
  1179. package/packages/state/src/index.ts +0 -12
  1180. package/packages/state/tsconfig.json +0 -21
  1181. package/packages/state/vitest.config.ts +0 -9
  1182. package/packages/storage/dist/adapter.d.ts +0 -189
  1183. package/packages/storage/dist/adapter.d.ts.map +0 -1
  1184. package/packages/storage/dist/adapter.js +0 -267
  1185. package/packages/storage/dist/adapter.js.map +0 -1
  1186. package/packages/storage/dist/batched-sqlite-adapter.d.ts +0 -75
  1187. package/packages/storage/dist/batched-sqlite-adapter.d.ts.map +0 -1
  1188. package/packages/storage/dist/batched-sqlite-adapter.js +0 -189
  1189. package/packages/storage/dist/batched-sqlite-adapter.js.map +0 -1
  1190. package/packages/storage/dist/dead-letter-queue.d.ts +0 -196
  1191. package/packages/storage/dist/dead-letter-queue.d.ts.map +0 -1
  1192. package/packages/storage/dist/dead-letter-queue.js +0 -427
  1193. package/packages/storage/dist/dead-letter-queue.js.map +0 -1
  1194. package/packages/storage/dist/dlq-adapter.d.ts +0 -195
  1195. package/packages/storage/dist/dlq-adapter.d.ts.map +0 -1
  1196. package/packages/storage/dist/dlq-adapter.js +0 -664
  1197. package/packages/storage/dist/dlq-adapter.js.map +0 -1
  1198. package/packages/storage/dist/index.d.ts +0 -6
  1199. package/packages/storage/dist/index.d.ts.map +0 -1
  1200. package/packages/storage/dist/index.js +0 -7
  1201. package/packages/storage/dist/index.js.map +0 -1
  1202. package/packages/storage/dist/jsonl-adapter.d.ts +0 -91
  1203. package/packages/storage/dist/jsonl-adapter.d.ts.map +0 -1
  1204. package/packages/storage/dist/jsonl-adapter.js +0 -580
  1205. package/packages/storage/dist/jsonl-adapter.js.map +0 -1
  1206. package/packages/storage/dist/sqlite-adapter.d.ts +0 -131
  1207. package/packages/storage/dist/sqlite-adapter.d.ts.map +0 -1
  1208. package/packages/storage/dist/sqlite-adapter.js +0 -865
  1209. package/packages/storage/dist/sqlite-adapter.js.map +0 -1
  1210. package/packages/storage/package.json +0 -74
  1211. package/packages/storage/src/adapter.ts +0 -446
  1212. package/packages/storage/src/batched-sqlite-adapter.test.ts +0 -256
  1213. package/packages/storage/src/batched-sqlite-adapter.ts +0 -239
  1214. package/packages/storage/src/dead-letter-queue.ts +0 -643
  1215. package/packages/storage/src/dlq-adapter.test.ts +0 -509
  1216. package/packages/storage/src/dlq-adapter.ts +0 -954
  1217. package/packages/storage/src/index.ts +0 -6
  1218. package/packages/storage/src/jsonl-adapter.test.ts +0 -239
  1219. package/packages/storage/src/jsonl-adapter.ts +0 -704
  1220. package/packages/storage/src/memory-adapter.test.ts +0 -36
  1221. package/packages/storage/src/sqlite-adapter.test.ts +0 -580
  1222. package/packages/storage/src/sqlite-adapter.ts +0 -1099
  1223. package/packages/storage/tsconfig.json +0 -21
  1224. package/packages/storage/vitest.config.ts +0 -9
  1225. package/packages/wrapper/dist/__fixtures__/claude-outputs.d.ts +0 -49
  1226. package/packages/wrapper/dist/__fixtures__/claude-outputs.d.ts.map +0 -1
  1227. package/packages/wrapper/dist/__fixtures__/claude-outputs.js +0 -443
  1228. package/packages/wrapper/dist/__fixtures__/claude-outputs.js.map +0 -1
  1229. package/packages/wrapper/dist/__fixtures__/codex-outputs.d.ts +0 -9
  1230. package/packages/wrapper/dist/__fixtures__/codex-outputs.d.ts.map +0 -1
  1231. package/packages/wrapper/dist/__fixtures__/codex-outputs.js +0 -94
  1232. package/packages/wrapper/dist/__fixtures__/codex-outputs.js.map +0 -1
  1233. package/packages/wrapper/dist/__fixtures__/gemini-outputs.d.ts +0 -19
  1234. package/packages/wrapper/dist/__fixtures__/gemini-outputs.d.ts.map +0 -1
  1235. package/packages/wrapper/dist/__fixtures__/gemini-outputs.js +0 -144
  1236. package/packages/wrapper/dist/__fixtures__/gemini-outputs.js.map +0 -1
  1237. package/packages/wrapper/dist/__fixtures__/index.d.ts +0 -68
  1238. package/packages/wrapper/dist/__fixtures__/index.d.ts.map +0 -1
  1239. package/packages/wrapper/dist/__fixtures__/index.js +0 -44
  1240. package/packages/wrapper/dist/__fixtures__/index.js.map +0 -1
  1241. package/packages/wrapper/dist/auth-detection.d.ts +0 -49
  1242. package/packages/wrapper/dist/auth-detection.d.ts.map +0 -1
  1243. package/packages/wrapper/dist/auth-detection.js +0 -199
  1244. package/packages/wrapper/dist/auth-detection.js.map +0 -1
  1245. package/packages/wrapper/dist/base-wrapper.d.ts +0 -254
  1246. package/packages/wrapper/dist/base-wrapper.d.ts.map +0 -1
  1247. package/packages/wrapper/dist/base-wrapper.js +0 -664
  1248. package/packages/wrapper/dist/base-wrapper.js.map +0 -1
  1249. package/packages/wrapper/dist/client.d.ts +0 -291
  1250. package/packages/wrapper/dist/client.d.ts.map +0 -1
  1251. package/packages/wrapper/dist/client.js +0 -926
  1252. package/packages/wrapper/dist/client.js.map +0 -1
  1253. package/packages/wrapper/dist/id-generator.d.ts +0 -35
  1254. package/packages/wrapper/dist/id-generator.d.ts.map +0 -1
  1255. package/packages/wrapper/dist/id-generator.js +0 -60
  1256. package/packages/wrapper/dist/id-generator.js.map +0 -1
  1257. package/packages/wrapper/dist/idle-detector.d.ts +0 -114
  1258. package/packages/wrapper/dist/idle-detector.d.ts.map +0 -1
  1259. package/packages/wrapper/dist/idle-detector.js +0 -317
  1260. package/packages/wrapper/dist/idle-detector.js.map +0 -1
  1261. package/packages/wrapper/dist/inbox.d.ts +0 -37
  1262. package/packages/wrapper/dist/inbox.d.ts.map +0 -1
  1263. package/packages/wrapper/dist/inbox.js +0 -73
  1264. package/packages/wrapper/dist/inbox.js.map +0 -1
  1265. package/packages/wrapper/dist/index.d.ts +0 -40
  1266. package/packages/wrapper/dist/index.d.ts.map +0 -1
  1267. package/packages/wrapper/dist/index.js +0 -53
  1268. package/packages/wrapper/dist/index.js.map +0 -1
  1269. package/packages/wrapper/dist/opencode-api.d.ts +0 -106
  1270. package/packages/wrapper/dist/opencode-api.d.ts.map +0 -1
  1271. package/packages/wrapper/dist/opencode-api.js +0 -219
  1272. package/packages/wrapper/dist/opencode-api.js.map +0 -1
  1273. package/packages/wrapper/dist/opencode-wrapper.d.ts +0 -161
  1274. package/packages/wrapper/dist/opencode-wrapper.d.ts.map +0 -1
  1275. package/packages/wrapper/dist/opencode-wrapper.js +0 -438
  1276. package/packages/wrapper/dist/opencode-wrapper.js.map +0 -1
  1277. package/packages/wrapper/dist/parser.d.ts +0 -236
  1278. package/packages/wrapper/dist/parser.d.ts.map +0 -1
  1279. package/packages/wrapper/dist/parser.js +0 -1238
  1280. package/packages/wrapper/dist/parser.js.map +0 -1
  1281. package/packages/wrapper/dist/prompt-composer.d.ts +0 -67
  1282. package/packages/wrapper/dist/prompt-composer.d.ts.map +0 -1
  1283. package/packages/wrapper/dist/prompt-composer.js +0 -168
  1284. package/packages/wrapper/dist/prompt-composer.js.map +0 -1
  1285. package/packages/wrapper/dist/relay-pty-orchestrator.d.ts +0 -486
  1286. package/packages/wrapper/dist/relay-pty-orchestrator.d.ts.map +0 -1
  1287. package/packages/wrapper/dist/relay-pty-orchestrator.js +0 -2550
  1288. package/packages/wrapper/dist/relay-pty-orchestrator.js.map +0 -1
  1289. package/packages/wrapper/dist/shared.d.ts +0 -262
  1290. package/packages/wrapper/dist/shared.d.ts.map +0 -1
  1291. package/packages/wrapper/dist/shared.js +0 -507
  1292. package/packages/wrapper/dist/shared.js.map +0 -1
  1293. package/packages/wrapper/dist/stuck-detector.d.ts +0 -161
  1294. package/packages/wrapper/dist/stuck-detector.d.ts.map +0 -1
  1295. package/packages/wrapper/dist/stuck-detector.js +0 -402
  1296. package/packages/wrapper/dist/stuck-detector.js.map +0 -1
  1297. package/packages/wrapper/dist/tmux-resolver.d.ts +0 -55
  1298. package/packages/wrapper/dist/tmux-resolver.d.ts.map +0 -1
  1299. package/packages/wrapper/dist/tmux-resolver.js +0 -175
  1300. package/packages/wrapper/dist/tmux-resolver.js.map +0 -1
  1301. package/packages/wrapper/dist/tmux-wrapper.d.ts +0 -352
  1302. package/packages/wrapper/dist/tmux-wrapper.d.ts.map +0 -1
  1303. package/packages/wrapper/dist/tmux-wrapper.js +0 -1816
  1304. package/packages/wrapper/dist/tmux-wrapper.js.map +0 -1
  1305. package/packages/wrapper/dist/trajectory-integration.d.ts +0 -292
  1306. package/packages/wrapper/dist/trajectory-integration.d.ts.map +0 -1
  1307. package/packages/wrapper/dist/trajectory-integration.js +0 -979
  1308. package/packages/wrapper/dist/trajectory-integration.js.map +0 -1
  1309. package/packages/wrapper/dist/wrapper-events.d.ts +0 -489
  1310. package/packages/wrapper/dist/wrapper-events.d.ts.map +0 -1
  1311. package/packages/wrapper/dist/wrapper-events.js +0 -252
  1312. package/packages/wrapper/dist/wrapper-events.js.map +0 -1
  1313. package/packages/wrapper/dist/wrapper-types.d.ts +0 -41
  1314. package/packages/wrapper/dist/wrapper-types.d.ts.map +0 -1
  1315. package/packages/wrapper/dist/wrapper-types.js +0 -7
  1316. package/packages/wrapper/dist/wrapper-types.js.map +0 -1
  1317. package/packages/wrapper/package.json +0 -60
  1318. package/packages/wrapper/src/__fixtures__/claude-outputs.ts +0 -471
  1319. package/packages/wrapper/src/__fixtures__/codex-outputs.ts +0 -99
  1320. package/packages/wrapper/src/__fixtures__/gemini-outputs.ts +0 -151
  1321. package/packages/wrapper/src/__fixtures__/index.ts +0 -47
  1322. package/packages/wrapper/src/auth-detection.ts +0 -244
  1323. package/packages/wrapper/src/base-wrapper.test.ts +0 -589
  1324. package/packages/wrapper/src/base-wrapper.ts +0 -841
  1325. package/packages/wrapper/src/client.test.ts +0 -351
  1326. package/packages/wrapper/src/client.ts +0 -1166
  1327. package/packages/wrapper/src/id-generator.test.ts +0 -71
  1328. package/packages/wrapper/src/id-generator.ts +0 -69
  1329. package/packages/wrapper/src/idle-detector.test.ts +0 -418
  1330. package/packages/wrapper/src/idle-detector.ts +0 -384
  1331. package/packages/wrapper/src/inbox.test.ts +0 -233
  1332. package/packages/wrapper/src/inbox.ts +0 -89
  1333. package/packages/wrapper/src/index.ts +0 -199
  1334. package/packages/wrapper/src/opencode-api.test.ts +0 -292
  1335. package/packages/wrapper/src/opencode-api.ts +0 -285
  1336. package/packages/wrapper/src/opencode-wrapper.ts +0 -541
  1337. package/packages/wrapper/src/parser.regression.test.ts +0 -251
  1338. package/packages/wrapper/src/parser.test.ts +0 -1359
  1339. package/packages/wrapper/src/parser.ts +0 -1477
  1340. package/packages/wrapper/src/prompt-composer.test.ts +0 -219
  1341. package/packages/wrapper/src/prompt-composer.ts +0 -231
  1342. package/packages/wrapper/src/relay-pty-orchestrator.test.ts +0 -1386
  1343. package/packages/wrapper/src/relay-pty-orchestrator.ts +0 -3041
  1344. package/packages/wrapper/src/shared.test.ts +0 -467
  1345. package/packages/wrapper/src/shared.ts +0 -652
  1346. package/packages/wrapper/src/stuck-detector.test.ts +0 -303
  1347. package/packages/wrapper/src/stuck-detector.ts +0 -511
  1348. package/packages/wrapper/src/tmux-resolver.test.ts +0 -104
  1349. package/packages/wrapper/src/tmux-resolver.ts +0 -207
  1350. package/packages/wrapper/src/tmux-wrapper.test.ts +0 -316
  1351. package/packages/wrapper/src/tmux-wrapper.ts +0 -2095
  1352. package/packages/wrapper/src/trajectory-detection.test.ts +0 -151
  1353. package/packages/wrapper/src/trajectory-integration.ts +0 -1261
  1354. package/packages/wrapper/src/wrapper-events.ts +0 -395
  1355. package/packages/wrapper/src/wrapper-types.ts +0 -45
  1356. package/packages/wrapper/tsconfig.json +0 -19
  1357. package/packages/wrapper/vitest.config.ts +0 -9
  1358. /package/packages/{broker-sdk → sdk}/dist/__tests__/facade.test.d.ts +0 -0
  1359. /package/packages/{broker-sdk → sdk}/dist/__tests__/facade.test.d.ts.map +0 -0
  1360. /package/packages/{broker-sdk → sdk}/dist/__tests__/integration.test.d.ts +0 -0
  1361. /package/packages/{broker-sdk → sdk}/dist/__tests__/integration.test.d.ts.map +0 -0
  1362. /package/packages/{broker-sdk → sdk}/dist/__tests__/quickstart.test.d.ts +0 -0
  1363. /package/packages/{broker-sdk → sdk}/dist/__tests__/quickstart.test.d.ts.map +0 -0
  1364. /package/packages/{broker-sdk → sdk}/dist/__tests__/unit.test.d.ts +0 -0
  1365. /package/packages/{broker-sdk → sdk}/dist/__tests__/unit.test.d.ts.map +0 -0
  1366. /package/packages/{broker-sdk → sdk}/dist/browser.d.ts +0 -0
  1367. /package/packages/{broker-sdk → sdk}/dist/browser.d.ts.map +0 -0
  1368. /package/packages/{broker-sdk → sdk}/dist/browser.js +0 -0
  1369. /package/packages/{broker-sdk → sdk}/dist/browser.js.map +0 -0
  1370. /package/packages/{broker-sdk → sdk}/dist/consensus-helpers.d.ts +0 -0
  1371. /package/packages/{broker-sdk → sdk}/dist/consensus-helpers.d.ts.map +0 -0
  1372. /package/packages/{broker-sdk → sdk}/dist/consensus-helpers.js +0 -0
  1373. /package/packages/{broker-sdk → sdk}/dist/consensus-helpers.js.map +0 -0
  1374. /package/packages/{broker-sdk → sdk}/dist/consensus.d.ts +0 -0
  1375. /package/packages/{broker-sdk → sdk}/dist/consensus.d.ts.map +0 -0
  1376. /package/packages/{broker-sdk → sdk}/dist/consensus.js +0 -0
  1377. /package/packages/{broker-sdk → sdk}/dist/consensus.js.map +0 -0
  1378. /package/packages/{broker-sdk → sdk}/dist/examples/demo.d.ts +0 -0
  1379. /package/packages/{broker-sdk → sdk}/dist/examples/demo.d.ts.map +0 -0
  1380. /package/packages/{broker-sdk → sdk}/dist/examples/demo.js +0 -0
  1381. /package/packages/{broker-sdk → sdk}/dist/examples/demo.js.map +0 -0
  1382. /package/packages/{broker-sdk → sdk}/dist/examples/example.d.ts +0 -0
  1383. /package/packages/{broker-sdk → sdk}/dist/examples/example.d.ts.map +0 -0
  1384. /package/packages/{broker-sdk → sdk}/dist/examples/example.js +0 -0
  1385. /package/packages/{broker-sdk → sdk}/dist/examples/example.js.map +0 -0
  1386. /package/packages/{broker-sdk → sdk}/dist/examples/quickstart.d.ts +0 -0
  1387. /package/packages/{broker-sdk → sdk}/dist/examples/quickstart.d.ts.map +0 -0
  1388. /package/packages/{broker-sdk → sdk}/dist/examples/quickstart.js +0 -0
  1389. /package/packages/{broker-sdk → sdk}/dist/examples/quickstart.js.map +0 -0
  1390. /package/packages/{broker-sdk → sdk}/dist/examples/ralph-loop.d.ts +0 -0
  1391. /package/packages/{broker-sdk → sdk}/dist/examples/ralph-loop.d.ts.map +0 -0
  1392. /package/packages/{broker-sdk → sdk}/dist/examples/ralph-loop.js +0 -0
  1393. /package/packages/{broker-sdk → sdk}/dist/examples/ralph-loop.js.map +0 -0
  1394. /package/packages/{broker-sdk → sdk}/dist/protocol.js +0 -0
  1395. /package/packages/{broker-sdk → sdk}/dist/protocol.js.map +0 -0
  1396. /package/packages/{broker-sdk → sdk}/dist/pty.d.ts +0 -0
  1397. /package/packages/{broker-sdk → sdk}/dist/shadow.js +0 -0
  1398. /package/packages/{broker-sdk → sdk}/dist/workflows/barrier.d.ts +0 -0
  1399. /package/packages/{broker-sdk → sdk}/dist/workflows/barrier.d.ts.map +0 -0
  1400. /package/packages/{broker-sdk → sdk}/dist/workflows/barrier.js +0 -0
  1401. /package/packages/{broker-sdk → sdk}/dist/workflows/barrier.js.map +0 -0
  1402. /package/packages/{broker-sdk → sdk}/dist/workflows/memory-db.d.ts +0 -0
  1403. /package/packages/{broker-sdk → sdk}/dist/workflows/memory-db.d.ts.map +0 -0
  1404. /package/packages/{broker-sdk → sdk}/dist/workflows/memory-db.js +0 -0
  1405. /package/packages/{broker-sdk → sdk}/dist/workflows/memory-db.js.map +0 -0
  1406. /package/packages/{broker-sdk → sdk}/dist/workflows/state.d.ts +0 -0
  1407. /package/packages/{broker-sdk → sdk}/dist/workflows/state.d.ts.map +0 -0
  1408. /package/packages/{broker-sdk → sdk}/dist/workflows/state.js +0 -0
  1409. /package/packages/{broker-sdk → sdk}/dist/workflows/state.js.map +0 -0
  1410. /package/packages/{broker-sdk → sdk}/src/__tests__/workflow-trajectory.test.ts +0 -0
  1411. /package/packages/{broker-sdk → sdk}/src/browser.ts +0 -0
  1412. /package/packages/{broker-sdk → sdk}/src/consensus-helpers.ts +0 -0
  1413. /package/packages/{broker-sdk → sdk}/src/consensus.ts +0 -0
  1414. /package/packages/{broker-sdk → sdk}/src/examples/demo.ts +0 -0
  1415. /package/packages/{broker-sdk → sdk}/src/examples/example.ts +0 -0
  1416. /package/packages/{broker-sdk → sdk}/src/examples/quickstart.ts +0 -0
  1417. /package/packages/{broker-sdk → sdk}/src/examples/ralph-loop.ts +0 -0
  1418. /package/packages/{broker-sdk → sdk}/src/examples/sample-prd.json +0 -0
  1419. /package/packages/{broker-sdk → sdk}/src/workflows/barrier.ts +0 -0
  1420. /package/packages/{broker-sdk → sdk}/src/workflows/memory-db.ts +0 -0
  1421. /package/packages/{broker-sdk → sdk}/src/workflows/state.ts +0 -0
@@ -1,2550 +0,0 @@
1
- /**
2
- * RelayPtyOrchestrator - Orchestrates the relay-pty Rust binary
3
- *
4
- * This wrapper spawns the relay-pty binary and communicates via Unix socket.
5
- * It provides the same interface as PtyWrapper but with improved latency
6
- * (~550ms vs ~1700ms) by using direct PTY writes instead of tmux send-keys.
7
- *
8
- * Architecture:
9
- * 1. Spawn relay-pty --name {agentName} -- {command} as child process
10
- * 2. Connect to socket for injection:
11
- * - With WORKSPACE_ID: /tmp/relay/{workspaceId}/sockets/{agentName}.sock
12
- * - Without: /tmp/relay-pty-{agentName}.sock (legacy)
13
- * 3. Parse stdout for relay commands (relay-pty echoes all output)
14
- * 4. Translate SEND envelopes → inject messages via socket
15
- *
16
- * @see docs/RUST_WRAPPER_DESIGN.md for protocol details
17
- */
18
- import { spawn } from 'node:child_process';
19
- import { createConnection } from 'node:net';
20
- import { createHash } from 'node:crypto';
21
- import { join, dirname } from 'node:path';
22
- import { homedir, freemem, totalmem } from 'node:os';
23
- import { execSync } from 'node:child_process';
24
- import { existsSync, unlinkSync, mkdirSync, symlinkSync, lstatSync, rmSync, watch, readdirSync, readlinkSync, writeFileSync, appendFileSync, accessSync, constants as fsConstants, } from 'node:fs';
25
- import { getProjectPaths } from '@agent-relay/config/project-namespace';
26
- import { fileURLToPath } from 'node:url';
27
- // Get the directory where this module is located
28
- const __filename = fileURLToPath(import.meta.url);
29
- const __dirname = dirname(__filename);
30
- import { BaseWrapper } from './base-wrapper.js';
31
- import { parseSummaryWithDetails, parseSessionEndFromOutput } from './parser.js';
32
- import { findRelayPtyBinary as findRelayPtyBinaryUtil } from '@agent-relay/utils/relay-pty-path';
33
- import { stripAnsi, sleep, buildInjectionString, AdaptiveThrottle, } from './shared.js';
34
- import { getMemoryMonitor, formatBytes, getCgroupManager, } from '@agent-relay/resiliency';
35
- // ============================================================================
36
- // Types for relay-pty socket protocol
37
- // ============================================================================
38
- const MAX_SOCKET_PATH_LENGTH = 107;
39
- /**
40
- * Maximum size for output buffers (rawBuffer, outputBuffer) in bytes.
41
- * Prevents RangeError: Invalid string length when agents produce lots of output.
42
- * Set to 10MB - enough to capture context but won't exhaust memory.
43
- */
44
- const MAX_OUTPUT_BUFFER_SIZE = 10 * 1024 * 1024; // 10MB
45
- // ============================================================================
46
- // Activity Verification Constants
47
- // ============================================================================
48
- /**
49
- * Activity patterns used to verify that a CLI has received and started processing
50
- * an injected task. These patterns work across Claude Code, Codex, and Droid/Gemini.
51
- *
52
- * The problem we're solving: Rust confirms "delivered to PTY" but that doesn't mean
53
- * the CLI processed it. The T-003 failure showed the CLI wasn't ready when input arrived.
54
- *
55
- * @see https://github.com/your-org/relay/issues/XXX for the original investigation
56
- */
57
- const ACTIVITY_VERIFICATION = {
58
- /** Time to wait for activity patterns after injection (ms) */
59
- TIMEOUT_MS: 5000,
60
- /** How often to check for activity patterns (ms) */
61
- POLL_INTERVAL_MS: 200,
62
- /** Maximum retries when no activity is detected */
63
- MAX_RETRIES: 3,
64
- /** Delay between retries (ms) */
65
- RETRY_DELAY_MS: 500,
66
- /**
67
- * Patterns indicating the task was received and displayed.
68
- * These are the primary verification patterns.
69
- */
70
- TASK_RECEIVED_PATTERNS: [
71
- /\[Pasted text #\d+/, // Claude Code shows "[Pasted text #1 +95 lines]"
72
- /› Relay message from/, // Codex shows "› Relay message from"
73
- /Relay message from \w+ \[[\w-]+\]/, // Droid/Gemini shows "Relay message from Agent [id]:"
74
- ],
75
- /**
76
- * Patterns indicating the CLI is thinking/processing.
77
- * Secondary verification - proves the CLI is active.
78
- */
79
- THINKING_PATTERNS: [
80
- /\(.*esc to (?:interrupt|stop)\)/i, // All CLIs: "(esc to interrupt)" or "(Press ESC to stop)"
81
- /[✻✶✳✢·✽⠋⠙⠹⠸⠼⠴⠦⠧⠇⠏]/, // Spinner characters (Claude + Droid)
82
- /Thinking\.\.\./, // Droid: "Thinking..."
83
- /Working/, // Codex: "Working"
84
- /Forming|Noodling|Manifesting/i, // Claude Code thinking states
85
- ],
86
- /**
87
- * Patterns indicating tool execution started.
88
- * Tertiary verification - proves the CLI is working.
89
- */
90
- TOOL_EXECUTION_PATTERNS: [
91
- /⏺\s*(Bash|Read|Write|Edit|Glob|Grep|Task|WebFetch)/, // Claude Code tool markers
92
- /•\s*Running/, // Codex: "• Running: command"
93
- ],
94
- };
95
- function hashWorkspaceId(workspaceId) {
96
- return createHash('sha256').update(workspaceId).digest('hex').slice(0, 12);
97
- }
98
- /**
99
- * Orchestrator for relay-pty Rust binary
100
- *
101
- * Extends BaseWrapper to provide the same interface as PtyWrapper
102
- * but uses the relay-pty binary for improved injection reliability.
103
- */
104
- export class RelayPtyOrchestrator extends BaseWrapper {
105
- config;
106
- // Process management
107
- relayPtyProcess;
108
- socketPath;
109
- _logPath;
110
- _outboxPath;
111
- _legacyOutboxPath; // Legacy /tmp/relay-outbox path for backwards compat
112
- _canonicalOutboxPath; // Canonical ~/.agent-relay/outbox path (agents write here)
113
- _workspaceId; // For symlink setup
114
- socket;
115
- socketConnected = false;
116
- // Output buffering
117
- outputBuffer = '';
118
- rawBuffer = '';
119
- lastParsedLength = 0;
120
- bufferTrimCount = 0;
121
- // Interactive mode (show output to terminal)
122
- isInteractive = false;
123
- // Injection state
124
- pendingInjections = new Map();
125
- backpressureActive = false;
126
- readyForMessages = false;
127
- // Adaptive throttle for message queue - adjusts delay based on success/failure
128
- throttle = new AdaptiveThrottle();
129
- // Unread message indicator state
130
- lastUnreadIndicatorTime = 0;
131
- UNREAD_INDICATOR_COOLDOWN_MS = 5000; // Don't spam indicators
132
- // Track whether any output has been received from the CLI
133
- hasReceivedOutput = false;
134
- // Queue monitor for stuck message detection
135
- queueMonitorTimer;
136
- QUEUE_MONITOR_INTERVAL_MS = 5000; // Check every 5 seconds
137
- injectionStartTime = 0; // Track when isInjecting was set to true
138
- MAX_INJECTION_STUCK_MS = 60000; // Force reset after 60 seconds
139
- // Protocol monitor for detecting agent mistakes (e.g., empty AGENT_RELAY_NAME)
140
- protocolWatcher;
141
- protocolReminderCooldown = 0; // Prevent spam
142
- PROTOCOL_REMINDER_COOLDOWN_MS = 30000; // 30 second cooldown between reminders
143
- // Periodic protocol reminder for long sessions (agents sometimes forget the protocol)
144
- periodicReminderTimer;
145
- PERIODIC_REMINDER_INTERVAL_MS = 45 * 60 * 1000; // 45 minutes
146
- sessionStartTime = 0;
147
- // Track if agent is being gracefully stopped (vs crashed)
148
- isGracefulStop = false;
149
- // Track early process exit for better error messages
150
- earlyExitInfo;
151
- // Memory/CPU monitoring
152
- memoryMonitor;
153
- memoryAlertHandler = null;
154
- // CPU limiting via cgroups (optional, Linux only)
155
- cgroupManager;
156
- hasCgroupSetup = false;
157
- // Note: sessionEndProcessed and lastSummaryRawContent are inherited from BaseWrapper
158
- /**
159
- * Gather system diagnostics for debugging SIGKILL/unexpected exits.
160
- * Returns a formatted string with memory, process, and system info.
161
- */
162
- static gatherSigkillDiagnostics(agentName, pid) {
163
- const lines = [];
164
- try {
165
- // Memory info
166
- const free = freemem();
167
- const total = totalmem();
168
- const usedPercent = Math.round((1 - free / total) * 100);
169
- lines.push(`Memory: ${Math.round(free / 1024 / 1024)}MB free / ${Math.round(total / 1024 / 1024)}MB total (${usedPercent}% used)`);
170
- // Process count (try to get relay-pty count)
171
- try {
172
- const psOutput = execSync('ps aux | grep -c relay-pty || echo 0', { encoding: 'utf-8', timeout: 1000 }).trim();
173
- lines.push(`relay-pty processes: ${psOutput}`);
174
- }
175
- catch {
176
- // Ignore - ps may not be available
177
- }
178
- // Check for OOM killer messages (Linux only)
179
- try {
180
- const dmesgOutput = execSync('dmesg -T 2>/dev/null | grep -i "killed process" | tail -3 || true', {
181
- encoding: 'utf-8',
182
- timeout: 1000
183
- }).trim();
184
- if (dmesgOutput) {
185
- lines.push(`Recent OOM kills: ${dmesgOutput.replace(/\n/g, ' | ')}`);
186
- }
187
- }
188
- catch {
189
- // Ignore - dmesg may require permissions
190
- }
191
- // Include PID if known
192
- if (pid) {
193
- lines.push(`Killed process PID: ${pid}`);
194
- }
195
- lines.push(`Agent name: ${agentName}`);
196
- lines.push(`Timestamp: ${new Date().toISOString()}`);
197
- }
198
- catch (err) {
199
- lines.push(`Diagnostics error: ${err instanceof Error ? err.message : String(err)}`);
200
- }
201
- return lines.join('\n ');
202
- }
203
- constructor(config) {
204
- super(config);
205
- this.config = config;
206
- // Validate agent name to prevent path traversal attacks
207
- if (config.name.includes('..') || config.name.includes('/') || config.name.includes('\\')) {
208
- throw new Error(`Invalid agent name: "${config.name}" contains path traversal characters`);
209
- }
210
- // Get project paths (used for logs and local mode)
211
- const projectPaths = getProjectPaths(config.cwd);
212
- // Canonical outbox path - agents ALWAYS write here (transparent symlink in workspace mode)
213
- // Uses ~/.agent-relay/outbox/{agentName}/ so agents don't need to know about workspace IDs
214
- this._canonicalOutboxPath = join(projectPaths.dataDir, 'outbox', config.name);
215
- // Check for workspace namespacing (for multi-tenant cloud deployment)
216
- // WORKSPACE_ID can be in process.env or passed via config.env
217
- const workspaceId = config.env?.WORKSPACE_ID || process.env.WORKSPACE_ID;
218
- this._workspaceId = workspaceId;
219
- if (workspaceId) {
220
- // Workspace mode: relay-pty watches the actual workspace path
221
- // Canonical path (~/.agent-relay/outbox/) will be symlinked to workspace path
222
- const getWorkspacePaths = (id) => {
223
- const workspaceDir = `/tmp/relay/${id}`;
224
- return {
225
- workspaceDir,
226
- socketPath: `${workspaceDir}/sockets/${config.name}.sock`,
227
- outboxPath: `${workspaceDir}/outbox/${config.name}`,
228
- };
229
- };
230
- let paths = getWorkspacePaths(workspaceId);
231
- if (paths.socketPath.length > MAX_SOCKET_PATH_LENGTH) {
232
- const hashedWorkspaceId = hashWorkspaceId(workspaceId);
233
- const hashedPaths = getWorkspacePaths(hashedWorkspaceId);
234
- console.warn(`[relay-pty-orchestrator:${config.name}] Socket path too long (${paths.socketPath.length} chars); using hashed workspace id ${hashedWorkspaceId}`);
235
- paths = hashedPaths;
236
- }
237
- if (paths.socketPath.length > MAX_SOCKET_PATH_LENGTH) {
238
- throw new Error(`Socket path exceeds ${MAX_SOCKET_PATH_LENGTH} chars: ${paths.socketPath.length}`);
239
- }
240
- this.socketPath = paths.socketPath;
241
- // relay-pty watches the actual workspace path
242
- this._outboxPath = paths.outboxPath;
243
- // Legacy path for backwards compat (older agents might still use /tmp/relay-outbox)
244
- this._legacyOutboxPath = `/tmp/relay-outbox/${config.name}`;
245
- }
246
- else {
247
- // Local mode: use project paths directly (no symlinks needed)
248
- this._outboxPath = this._canonicalOutboxPath;
249
- // Socket path: use ~/.agent-relay/sockets/{projectId}/{agentName}.sock
250
- // This keeps paths short (uses 12-char hashed projectId) while staying organized
251
- // Example: /Users/foo/.agent-relay/sockets/abc123def456/MyAgent.sock (~65 chars)
252
- this.socketPath = join(homedir(), '.agent-relay', 'sockets', projectPaths.projectId, `${config.name}.sock`);
253
- // Legacy path for backwards compat (older agents might still use /tmp/relay-outbox)
254
- // Even in local mode, we need this symlink for agents with stale instructions
255
- this._legacyOutboxPath = `/tmp/relay-outbox/${config.name}`;
256
- }
257
- if (this.socketPath.length > MAX_SOCKET_PATH_LENGTH) {
258
- throw new Error(`Socket path exceeds ${MAX_SOCKET_PATH_LENGTH} chars: ${this.socketPath.length}`);
259
- }
260
- // Generate log path using project paths
261
- this._logPath = join(projectPaths.teamDir, 'worker-logs', `${config.name}.log`);
262
- // Check if we're running interactively (stdin is a TTY)
263
- // If headless mode is forced via config, always use pipes
264
- this.isInteractive = config.headless ? false : (process.stdin.isTTY === true);
265
- // Initialize memory monitor (shared singleton, 10s polling interval)
266
- this.memoryMonitor = getMemoryMonitor({ checkIntervalMs: 10_000 });
267
- // Initialize cgroup manager for CPU limiting (shared singleton)
268
- this.cgroupManager = getCgroupManager();
269
- }
270
- /**
271
- * Debug log - only outputs when debug is enabled
272
- * Writes to log file to avoid polluting TUI output
273
- */
274
- log(message) {
275
- if (this.config.debug) {
276
- const logLine = `${new Date().toISOString()} [relay-pty-orchestrator:${this.config.name}] ${message}\n`;
277
- try {
278
- const logDir = dirname(this._logPath);
279
- if (!existsSync(logDir)) {
280
- mkdirSync(logDir, { recursive: true });
281
- }
282
- appendFileSync(this._logPath, logLine);
283
- }
284
- catch {
285
- // Fallback to stderr if file write fails (only during init before _logPath is set)
286
- }
287
- }
288
- }
289
- /**
290
- * Error log - always outputs (errors are important)
291
- * Writes to log file to avoid polluting TUI output
292
- */
293
- logError(message) {
294
- const logLine = `${new Date().toISOString()} [relay-pty-orchestrator:${this.config.name}] ERROR: ${message}\n`;
295
- try {
296
- const logDir = dirname(this._logPath);
297
- if (!existsSync(logDir)) {
298
- mkdirSync(logDir, { recursive: true });
299
- }
300
- appendFileSync(this._logPath, logLine);
301
- }
302
- catch {
303
- // Fallback to stderr if file write fails (only during init before _logPath is set)
304
- }
305
- }
306
- /**
307
- * Get the outbox path for this agent (for documentation purposes)
308
- */
309
- get outboxPath() {
310
- return this._outboxPath;
311
- }
312
- // =========================================================================
313
- // Abstract method implementations (required by BaseWrapper)
314
- // =========================================================================
315
- /**
316
- * Start the relay-pty process and connect to socket
317
- */
318
- async start() {
319
- if (this.running)
320
- return;
321
- this.log(` Starting...`);
322
- // Ensure socket directory exists (for workspace-namespaced paths)
323
- const socketDir = dirname(this.socketPath);
324
- try {
325
- if (!existsSync(socketDir)) {
326
- mkdirSync(socketDir, { recursive: true });
327
- this.log(` Created socket directory: ${socketDir}`);
328
- }
329
- }
330
- catch (err) {
331
- this.logError(` Failed to create socket directory: ${err.message}`);
332
- }
333
- // Clean up any stale socket from previous crashed process
334
- try {
335
- if (existsSync(this.socketPath)) {
336
- this.log(` Removing stale socket: ${this.socketPath}`);
337
- unlinkSync(this.socketPath);
338
- }
339
- }
340
- catch (err) {
341
- this.logError(` Failed to clean up socket: ${err.message}`);
342
- }
343
- // Set up outbox directory structure
344
- // - Workspace mode:
345
- // 1. Create actual workspace path /tmp/relay/{workspaceId}/outbox/{name}
346
- // 2. Symlink canonical ~/.agent-relay/outbox/{name} -> workspace path
347
- // 3. Optional: symlink /tmp/relay-outbox/{name} -> workspace path (backwards compat)
348
- // - Local mode: just create ~/.agent-relay/{projectId}/outbox/{name} directly
349
- try {
350
- // Ensure the actual outbox directory exists (where relay-pty watches)
351
- const outboxDir = dirname(this._outboxPath);
352
- if (!existsSync(outboxDir)) {
353
- mkdirSync(outboxDir, { recursive: true });
354
- }
355
- if (!existsSync(this._outboxPath)) {
356
- mkdirSync(this._outboxPath, { recursive: true });
357
- }
358
- this.log(` Created outbox directory: ${this._outboxPath}`);
359
- // Helper to create a symlink, cleaning up existing path first
360
- const createSymlinkSafe = (linkPath, targetPath) => {
361
- const linkParent = dirname(linkPath);
362
- if (!existsSync(linkParent)) {
363
- mkdirSync(linkParent, { recursive: true });
364
- }
365
- // Remove existing path if it exists (file, symlink, or directory)
366
- // Use lstatSync instead of existsSync to detect broken symlinks
367
- // (existsSync returns false for broken symlinks, but the symlink itself still exists)
368
- let pathExists = false;
369
- try {
370
- lstatSync(linkPath);
371
- pathExists = true;
372
- }
373
- catch {
374
- // Path doesn't exist at all - proceed to create symlink
375
- }
376
- if (pathExists) {
377
- try {
378
- const stats = lstatSync(linkPath);
379
- if (stats.isSymbolicLink()) {
380
- // Handle both valid and broken symlinks
381
- try {
382
- const currentTarget = readlinkSync(linkPath);
383
- if (currentTarget === targetPath) {
384
- // Symlink already points to correct target, no need to recreate
385
- this.log(` Symlink already exists and is correct: ${linkPath} -> ${targetPath}`);
386
- return;
387
- }
388
- }
389
- catch {
390
- // Broken symlink (target doesn't exist) - remove it
391
- this.log(` Removing broken symlink: ${linkPath}`);
392
- }
393
- unlinkSync(linkPath);
394
- }
395
- else if (stats.isFile()) {
396
- unlinkSync(linkPath);
397
- }
398
- else if (stats.isDirectory()) {
399
- // Force remove directory - this is critical for fixing existing directories
400
- rmSync(linkPath, { recursive: true, force: true });
401
- // Verify removal succeeded using lstatSync to catch broken symlinks
402
- try {
403
- lstatSync(linkPath);
404
- throw new Error(`Failed to remove existing directory: ${linkPath}`);
405
- }
406
- catch (err) {
407
- if (err.code !== 'ENOENT') {
408
- throw err; // Re-throw if it's not a "doesn't exist" error
409
- }
410
- // Path successfully removed
411
- }
412
- }
413
- }
414
- catch (err) {
415
- // Log cleanup errors instead of silently ignoring them
416
- this.logError(` Failed to clean up existing path ${linkPath}: ${err.message}`);
417
- throw err; // Re-throw to prevent symlink creation on failed cleanup
418
- }
419
- }
420
- // Create the symlink
421
- try {
422
- symlinkSync(targetPath, linkPath);
423
- // Verify symlink was created correctly
424
- if (!existsSync(linkPath)) {
425
- throw new Error(`Symlink creation failed: ${linkPath}`);
426
- }
427
- const verifyStats = lstatSync(linkPath);
428
- if (!verifyStats.isSymbolicLink()) {
429
- throw new Error(`Created path is not a symlink: ${linkPath}`);
430
- }
431
- const verifyTarget = readlinkSync(linkPath);
432
- if (verifyTarget !== targetPath) {
433
- throw new Error(`Symlink points to wrong target: expected ${targetPath}, got ${verifyTarget}`);
434
- }
435
- this.log(` Created symlink: ${linkPath} -> ${targetPath}`);
436
- }
437
- catch (err) {
438
- this.logError(` Failed to create symlink ${linkPath} -> ${targetPath}: ${err.message}`);
439
- throw err;
440
- }
441
- };
442
- // In workspace mode, create symlinks so agents can use canonical path
443
- if (this._workspaceId) {
444
- // Symlink canonical path (~/.agent-relay/outbox/{name}) -> workspace path
445
- // This is the PRIMARY symlink - agents write to canonical path, relay-pty watches workspace path
446
- if (this._canonicalOutboxPath !== this._outboxPath) {
447
- createSymlinkSafe(this._canonicalOutboxPath, this._outboxPath);
448
- }
449
- // Also create legacy /tmp/relay-outbox symlink for backwards compat with older agents
450
- if (this._legacyOutboxPath !== this._outboxPath && this._legacyOutboxPath !== this._canonicalOutboxPath) {
451
- createSymlinkSafe(this._legacyOutboxPath, this._outboxPath);
452
- }
453
- }
454
- // In local mode, also create legacy symlink for backwards compat with stale instructions
455
- if (!this._workspaceId && this._legacyOutboxPath !== this._outboxPath) {
456
- createSymlinkSafe(this._legacyOutboxPath, this._outboxPath);
457
- }
458
- }
459
- catch (err) {
460
- this.logError(` Failed to set up outbox: ${err.message}`);
461
- }
462
- // Write MCP identity file so MCP servers can discover their agent name
463
- // This is needed because Claude Code may not pass through env vars to MCP server processes
464
- try {
465
- const projectPaths = getProjectPaths(this.config.cwd);
466
- const identityDir = join(projectPaths.dataDir);
467
- if (!existsSync(identityDir)) {
468
- mkdirSync(identityDir, { recursive: true });
469
- }
470
- // Write a per-process identity file (using PPID so MCP server finds parent's identity)
471
- const identityPath = join(identityDir, `mcp-identity-${process.pid}`);
472
- writeFileSync(identityPath, this.config.name, 'utf-8');
473
- this.log(` Wrote MCP identity file: ${identityPath}`);
474
- // Also write a simple identity file (for single-agent scenarios)
475
- const simpleIdentityPath = join(identityDir, 'mcp-identity');
476
- writeFileSync(simpleIdentityPath, this.config.name, 'utf-8');
477
- }
478
- catch (err) {
479
- this.logError(` Failed to write MCP identity file: ${err.message}`);
480
- }
481
- // Find relay-pty binary
482
- const binaryPath = this.findRelayPtyBinary();
483
- if (!binaryPath) {
484
- throw new Error('relay-pty binary not found. Build with: cd relay-pty && cargo build --release');
485
- }
486
- try {
487
- accessSync(binaryPath, fsConstants.X_OK);
488
- }
489
- catch (err) {
490
- throw new Error(`relay-pty binary not executable at ${binaryPath}: ${err?.message ?? 'permission denied'}. Build with: cd relay-pty && cargo build --release, or ensure the binary has execute permissions.`);
491
- }
492
- this.log(` Using binary: ${binaryPath}`);
493
- // Spawn relay-pty process FIRST (before connecting to daemon)
494
- // This ensures the CLI is actually running before we register with the daemon
495
- await this.spawnRelayPty(binaryPath);
496
- // Wait for socket to become available and connect
497
- await this.connectToSocket();
498
- // Connect to relay daemon AFTER CLI is spawned
499
- // This prevents the spawner from seeing us as "registered" before the CLI runs
500
- try {
501
- await this.client.connect();
502
- this.log(` Relay daemon connected`);
503
- }
504
- catch (err) {
505
- this.logError(` Relay connect failed: ${err.message}`);
506
- }
507
- this.running = true;
508
- // DON'T set readyForMessages yet - wait for CLI to be ready first
509
- // This prevents messages from being injected during CLI startup
510
- this.startStuckDetection();
511
- this.startQueueMonitor();
512
- this.startProtocolMonitor();
513
- this.startPeriodicReminder();
514
- this.log(` Socket connected: ${this.socketConnected}`);
515
- this.log(` Relay client state: ${this.client.state}`);
516
- // Wait for CLI to be fully ready (output received + idle state)
517
- // This ensures we don't inject messages while the CLI is still starting up
518
- // Messages arriving via daemon during this time will be queued but not processed
519
- this.log(` Waiting for CLI to be ready before accepting messages...`);
520
- const cliReady = await this.waitUntilCliReady(30000, 100);
521
- if (cliReady) {
522
- this.log(` CLI is ready, enabling message processing`);
523
- }
524
- else {
525
- this.log(` CLI readiness timeout, enabling message processing anyway`);
526
- }
527
- // Now enable message processing
528
- this.readyForMessages = true;
529
- this.log(` Ready for messages`);
530
- // Process any queued messages that arrived during startup
531
- this.processMessageQueue();
532
- }
533
- /**
534
- * Stop the relay-pty process gracefully
535
- */
536
- async stop() {
537
- if (!this.running)
538
- return;
539
- this.isGracefulStop = true; // Mark as graceful to prevent crash broadcast
540
- this.running = false;
541
- this.stopStuckDetection();
542
- this.stopQueueMonitor();
543
- this.stopProtocolMonitor();
544
- this.stopPeriodicReminder();
545
- // Clear socket reconnect timer
546
- if (this.socketReconnectTimer) {
547
- clearTimeout(this.socketReconnectTimer);
548
- this.socketReconnectTimer = undefined;
549
- }
550
- // Unregister from memory monitor
551
- this.memoryMonitor.unregister(this.config.name);
552
- if (this.memoryAlertHandler) {
553
- this.memoryMonitor.off('alert', this.memoryAlertHandler);
554
- this.memoryAlertHandler = null;
555
- }
556
- // Clean up cgroup if we set one up
557
- if (this.hasCgroupSetup) {
558
- await this.cgroupManager.removeAgentCgroup(this.config.name);
559
- this.hasCgroupSetup = false;
560
- }
561
- // Auto-save continuity state before shutdown
562
- // Pass sessionEndData to populate handoff (fixes empty handoff issue)
563
- if (this.continuity) {
564
- try {
565
- await this.continuity.autoSave(this.config.name, 'session_end', this.sessionEndData);
566
- this.log(` Continuity auto-saved`);
567
- }
568
- catch (err) {
569
- this.logError(`Continuity auto-save failed: ${err.message}`);
570
- }
571
- }
572
- this.log(` Stopping...`);
573
- // Send shutdown command via socket
574
- if (this.socket && this.socketConnected) {
575
- try {
576
- await this.sendSocketRequest({ type: 'shutdown' });
577
- }
578
- catch {
579
- // Ignore errors during shutdown
580
- }
581
- }
582
- // Close socket
583
- this.disconnectSocket();
584
- // Kill process if still running
585
- if (this.relayPtyProcess && !this.relayPtyProcess.killed) {
586
- this.relayPtyProcess.kill('SIGTERM');
587
- // Force kill after timeout
588
- await Promise.race([
589
- new Promise((resolve) => {
590
- this.relayPtyProcess?.on('exit', () => resolve());
591
- }),
592
- sleep(5000).then(() => {
593
- if (this.relayPtyProcess && !this.relayPtyProcess.killed) {
594
- this.relayPtyProcess.kill('SIGKILL');
595
- }
596
- }),
597
- ]);
598
- }
599
- // Cleanup relay client
600
- this.destroyClient();
601
- // Clean up socket file
602
- try {
603
- if (existsSync(this.socketPath)) {
604
- unlinkSync(this.socketPath);
605
- this.log(` Cleaned up socket: ${this.socketPath}`);
606
- }
607
- }
608
- catch (err) {
609
- this.logError(` Failed to clean up socket: ${err.message}`);
610
- }
611
- // Clean up mcp-identity file for this process
612
- try {
613
- const projectPaths = getProjectPaths(this.config.cwd);
614
- const identityPath = join(projectPaths.dataDir, `mcp-identity-${process.pid}`);
615
- if (existsSync(identityPath)) {
616
- unlinkSync(identityPath);
617
- this.log(` Cleaned up identity file: ${identityPath}`);
618
- }
619
- }
620
- catch (err) {
621
- this.logError(` Failed to clean up identity file: ${err.message}`);
622
- }
623
- this.log(` Stopped`);
624
- }
625
- /**
626
- * Inject content into the agent via socket
627
- */
628
- async performInjection(_content) {
629
- // This is called by BaseWrapper but we handle injection differently
630
- // via the socket protocol in processMessageQueue
631
- throw new Error('Use injectMessage() instead of performInjection()');
632
- }
633
- /**
634
- * Get cleaned output for parsing
635
- */
636
- getCleanOutput() {
637
- return stripAnsi(this.rawBuffer);
638
- }
639
- // =========================================================================
640
- // Process management
641
- // =========================================================================
642
- /**
643
- * Find the relay-pty binary
644
- * Uses shared utility from @agent-relay/utils
645
- */
646
- findRelayPtyBinary() {
647
- // Check config path first
648
- if (this.config.relayPtyPath && existsSync(this.config.relayPtyPath)) {
649
- return this.config.relayPtyPath;
650
- }
651
- // Use shared utility with current module's __dirname
652
- return findRelayPtyBinaryUtil(__dirname);
653
- }
654
- /**
655
- * Spawn the relay-pty process
656
- */
657
- async spawnRelayPty(binaryPath) {
658
- // Get terminal dimensions for proper rendering
659
- const rows = process.stdout.rows || 24;
660
- const cols = process.stdout.columns || 80;
661
- const args = [
662
- '--name', this.config.name,
663
- '--socket', this.socketPath,
664
- '--idle-timeout', String(this.config.idleBeforeInjectMs ?? 500),
665
- '--json-output', // Enable Rust parsing output
666
- '--rows', String(rows),
667
- '--cols', String(cols),
668
- '--log-level', 'warn', // Only show warnings and errors
669
- '--log-file', this._logPath, // Enable output logging
670
- '--outbox', this._outboxPath, // Enable file-based relay messages
671
- '--', this.config.command,
672
- ...(this.config.args ?? []),
673
- ];
674
- this.log(` Spawning: ${binaryPath} ${args.join(' ')}`);
675
- // Reset early exit info from any previous spawn attempt
676
- this.earlyExitInfo = undefined;
677
- // For interactive mode, let Rust directly inherit stdin/stdout from the terminal
678
- // This is more robust than manual forwarding through pipes
679
- // We still pipe stderr to capture JSON parsed commands
680
- const stdio = this.isInteractive
681
- ? ['inherit', 'inherit', 'pipe'] // Rust handles terminal directly
682
- : ['pipe', 'pipe', 'pipe']; // Headless mode - we handle I/O
683
- const proc = spawn(binaryPath, args, {
684
- cwd: this.config.cwd ?? process.cwd(),
685
- env: {
686
- ...process.env,
687
- ...this.config.env,
688
- AGENT_RELAY_NAME: this.config.name,
689
- RELAY_AGENT_NAME: this.config.name, // MCP server uses this env var
690
- AGENT_RELAY_OUTBOX: this._canonicalOutboxPath, // Agents use this for outbox path
691
- TERM: 'xterm-256color',
692
- },
693
- stdio,
694
- });
695
- this.relayPtyProcess = proc;
696
- // Handle stdout (agent output) - only in headless mode
697
- if (!this.isInteractive && proc.stdout) {
698
- proc.stdout.on('data', (data) => {
699
- const text = data.toString();
700
- this.handleOutput(text);
701
- });
702
- }
703
- // Capture stderr for early exit diagnosis
704
- let stderrBuffer = '';
705
- // Handle stderr (relay-pty logs and JSON output) - always needed
706
- // Also captures to buffer for error diagnostics if process dies early
707
- if (proc.stderr) {
708
- proc.stderr.on('data', (data) => {
709
- const text = data.toString();
710
- stderrBuffer += text;
711
- this.handleStderr(text);
712
- });
713
- }
714
- // Handle exit
715
- proc.on('exit', (code, signal) => {
716
- const exitCode = code ?? (signal === 'SIGKILL' ? 137 : 1);
717
- this.log(` Process exited: code=${exitCode} signal=${signal}`);
718
- // Capture early exit info for better error messages if socket not yet connected
719
- if (!this.socketConnected) {
720
- this.earlyExitInfo = { code, signal, stderr: stderrBuffer };
721
- }
722
- // Enhanced logging for SIGKILL/137 exits (likely OOM or resource limits)
723
- if (signal === 'SIGKILL' || exitCode === 137) {
724
- const diagnostics = RelayPtyOrchestrator.gatherSigkillDiagnostics(this.config.name, proc.pid);
725
- this.logError(` SIGKILL DETECTED - gathering diagnostics:\n ${diagnostics}`);
726
- console.error(`[relay-pty-orchestrator] SIGKILL for ${this.config.name}:\n ${diagnostics}`);
727
- }
728
- this.running = false;
729
- // Get crash context before unregistering from memory monitor
730
- const crashContext = this.memoryMonitor.getCrashContext(this.config.name);
731
- // Unregister from memory monitor
732
- this.memoryMonitor.unregister(this.config.name);
733
- if (this.memoryAlertHandler) {
734
- this.memoryMonitor.off('alert', this.memoryAlertHandler);
735
- this.memoryAlertHandler = null;
736
- }
737
- // Clean up cgroup (fire and forget - process already exited)
738
- if (this.hasCgroupSetup) {
739
- this.cgroupManager.removeAgentCgroup(this.config.name).catch(() => { });
740
- this.hasCgroupSetup = false;
741
- }
742
- // Broadcast crash notification if not a graceful stop
743
- if (!this.isGracefulStop && this.client.state === 'READY') {
744
- const canBroadcast = typeof this.client.broadcast === 'function';
745
- const isNormalExit = exitCode === 0;
746
- const wasKilled = signal === 'SIGKILL' || signal === 'SIGTERM' || exitCode === 137;
747
- if (!isNormalExit) {
748
- const reason = wasKilled
749
- ? `killed by signal ${signal || 'SIGKILL'}`
750
- : `exit code ${exitCode}`;
751
- // Include crash context analysis if available
752
- const contextInfo = crashContext.likelyCause !== 'unknown'
753
- ? ` Likely cause: ${crashContext.likelyCause}. ${crashContext.analysisNotes.slice(0, 2).join('. ')}`
754
- : '';
755
- const message = `AGENT CRASHED: "${this.config.name}" has died unexpectedly (${reason}).${contextInfo}`;
756
- this.log(` Broadcasting crash notification: ${message}`);
757
- if (canBroadcast) {
758
- this.client.broadcast(message, 'message', {
759
- isSystemMessage: true,
760
- agentName: this.config.name,
761
- exitCode,
762
- signal: signal || undefined,
763
- crashType: 'unexpected_exit',
764
- crashContext: {
765
- likelyCause: crashContext.likelyCause,
766
- peakMemory: crashContext.peakMemory,
767
- averageMemory: crashContext.averageMemory,
768
- memoryTrend: crashContext.memoryTrend,
769
- },
770
- });
771
- }
772
- else {
773
- this.log(' broadcast skipped: client.broadcast not available');
774
- }
775
- }
776
- }
777
- this.emit('exit', exitCode);
778
- this.config.onExit?.(exitCode);
779
- });
780
- // Handle error
781
- proc.on('error', (err) => {
782
- this.logError(` Process error: ${err.message}`);
783
- this.emit('error', err);
784
- });
785
- // Wait for process to start
786
- await sleep(500);
787
- if (proc.exitCode !== null) {
788
- // Include any captured stderr in the error for debugging
789
- const stderrInfo = stderrBuffer ? `\nStderr: ${stderrBuffer.slice(0, 500)}` : '';
790
- throw new Error(`relay-pty exited immediately with code ${proc.exitCode}${stderrInfo}`);
791
- }
792
- // Register for memory/CPU monitoring
793
- if (proc.pid) {
794
- this.memoryMonitor.register(this.config.name, proc.pid);
795
- this.memoryMonitor.start(); // Idempotent - starts if not already running
796
- // Set up CPU limiting via cgroups (if configured and available)
797
- // This prevents one agent from starving others during npm install/build
798
- if (this.config.cpuLimitPercent && this.config.cpuLimitPercent > 0) {
799
- this.setupCgroupLimit(proc.pid, this.config.cpuLimitPercent).catch((err) => {
800
- this.log(` Failed to set up cgroup CPU limit: ${err.message}`);
801
- });
802
- }
803
- // Set up alert handler to send resource alerts to dashboard only (not other agents)
804
- this.memoryAlertHandler = (alert) => {
805
- if (alert.agentName !== this.config.name)
806
- return;
807
- if (this.client.state !== 'READY')
808
- return;
809
- const message = alert.type === 'recovered'
810
- ? `AGENT RECOVERED: "${this.config.name}" memory usage returned to normal.`
811
- : `AGENT RESOURCE ALERT: "${this.config.name}" - ${alert.message} (${formatBytes(alert.currentRss)})`;
812
- this.log(` Sending resource alert to users: ${message}`);
813
- // Send to all human users - agents don't need to know about each other's resource usage
814
- this.client.sendMessage('@users', message, 'message', {
815
- isSystemMessage: true,
816
- agentName: this.config.name,
817
- alertType: alert.type,
818
- currentMemory: alert.currentRss,
819
- threshold: alert.threshold,
820
- recommendation: alert.recommendation,
821
- });
822
- };
823
- this.memoryMonitor.on('alert', this.memoryAlertHandler);
824
- }
825
- }
826
- /**
827
- * Set up cgroup CPU limit for this agent
828
- */
829
- async setupCgroupLimit(pid, cpuPercent) {
830
- await this.cgroupManager.initialize();
831
- if (!this.cgroupManager.isAvailable()) {
832
- this.log(` cgroups not available, skipping CPU limit`);
833
- return;
834
- }
835
- const created = await this.cgroupManager.createAgentCgroup(this.config.name, { cpuPercent });
836
- if (!created) {
837
- return;
838
- }
839
- const added = await this.cgroupManager.addProcess(this.config.name, pid);
840
- if (added) {
841
- this.hasCgroupSetup = true;
842
- this.log(` CPU limit set to ${cpuPercent}% for agent ${this.config.name}`);
843
- }
844
- }
845
- /**
846
- * Handle output from relay-pty stdout (headless mode only)
847
- * In interactive mode, stdout goes directly to terminal via inherited stdio
848
- */
849
- handleOutput(data) {
850
- // Skip processing if agent is no longer running (prevents ghost messages after release)
851
- if (!this.running) {
852
- return;
853
- }
854
- this.rawBuffer += data;
855
- this.outputBuffer += data;
856
- this.hasReceivedOutput = true;
857
- // Trim buffers if they exceed max size to prevent RangeError: Invalid string length
858
- // Keep the most recent output (tail) as it's more relevant for pattern matching
859
- let buffersTrimmed = false;
860
- if (this.rawBuffer.length > MAX_OUTPUT_BUFFER_SIZE) {
861
- const trimAmount = this.rawBuffer.length - MAX_OUTPUT_BUFFER_SIZE;
862
- this.rawBuffer = this.rawBuffer.slice(-MAX_OUTPUT_BUFFER_SIZE);
863
- // Adjust lastParsedLength to stay in sync with the trimmed buffer
864
- // This ensures parseRelayCommands() doesn't skip content or re-parse old content
865
- this.lastParsedLength = Math.max(0, this.lastParsedLength - trimAmount);
866
- buffersTrimmed = true;
867
- }
868
- if (this.outputBuffer.length > MAX_OUTPUT_BUFFER_SIZE) {
869
- this.outputBuffer = this.outputBuffer.slice(-MAX_OUTPUT_BUFFER_SIZE);
870
- buffersTrimmed = true;
871
- }
872
- if (buffersTrimmed) {
873
- this.bufferTrimCount += 1;
874
- }
875
- // Feed to idle detector
876
- this.feedIdleDetectorOutput(data);
877
- // Check for unread messages and append indicator if needed
878
- const indicator = this.formatUnreadIndicator();
879
- const outputWithIndicator = indicator ? data + indicator : data;
880
- // Emit output event (with indicator if present)
881
- this.emit('output', outputWithIndicator);
882
- // Stream to daemon if configured
883
- if (this.config.streamLogs !== false && this.client.state === 'READY') {
884
- this.client.sendLog(outputWithIndicator);
885
- }
886
- // Parse for relay commands
887
- this.parseRelayCommands();
888
- // Check for summary and session end
889
- const cleanContent = stripAnsi(this.rawBuffer);
890
- this.checkForSummary(cleanContent);
891
- this.checkForSessionEnd(cleanContent);
892
- }
893
- /**
894
- * Format an unread message indicator if there are pending messages.
895
- * Returns empty string if no pending messages or within cooldown period.
896
- *
897
- * Example output:
898
- * ───────────────────────────
899
- * 📬 2 unread messages (from: Alice, Bob)
900
- */
901
- formatUnreadIndicator() {
902
- const queueLength = this.messageQueue.length;
903
- if (queueLength === 0) {
904
- return '';
905
- }
906
- // Check cooldown to avoid spamming
907
- const now = Date.now();
908
- if (now - this.lastUnreadIndicatorTime < this.UNREAD_INDICATOR_COOLDOWN_MS) {
909
- return '';
910
- }
911
- this.lastUnreadIndicatorTime = now;
912
- // Collect unique sender names
913
- const senders = [...new Set(this.messageQueue.map(m => m.from))];
914
- const senderList = senders.slice(0, 3).join(', ');
915
- const moreCount = senders.length > 3 ? ` +${senders.length - 3} more` : '';
916
- const line = '─'.repeat(27);
917
- const messageWord = queueLength === 1 ? 'message' : 'messages';
918
- return `\n${line}\n📬 ${queueLength} unread ${messageWord} (from: ${senderList}${moreCount})\n`;
919
- }
920
- /**
921
- * Handle stderr from relay-pty (logs and JSON parsed commands)
922
- */
923
- handleStderr(data) {
924
- // Skip processing if agent is no longer running (prevents ghost messages after release)
925
- if (!this.running) {
926
- return;
927
- }
928
- // relay-pty outputs JSON parsed commands to stderr with --json-output
929
- const lines = data.split('\n').filter(l => l.trim());
930
- for (const line of lines) {
931
- if (line.startsWith('{')) {
932
- // JSON output - parsed relay command from Rust
933
- try {
934
- const parsed = JSON.parse(line);
935
- if (parsed.type === 'relay_command' && parsed.kind) {
936
- // Log parsed commands (only in debug mode to avoid TUI pollution)
937
- if (parsed.kind === 'spawn' || parsed.kind === 'release') {
938
- this.log(`Rust parsed [${parsed.kind}]: ${JSON.stringify({
939
- spawn_name: parsed.spawn_name,
940
- spawn_cli: parsed.spawn_cli,
941
- spawn_task: parsed.spawn_task?.substring(0, 50),
942
- release_name: parsed.release_name,
943
- })}`);
944
- }
945
- else {
946
- this.log(`Rust parsed [${parsed.kind}]: ${parsed.from} -> ${parsed.to}`);
947
- }
948
- this.handleRustParsedCommand(parsed);
949
- }
950
- else if (parsed.type === 'continuity') {
951
- // Handle continuity commands from relay-pty file-based protocol
952
- this.log(`Rust parsed [continuity]: action=${parsed.action}`);
953
- this.handleRustContinuityCommand(parsed);
954
- }
955
- }
956
- catch (e) {
957
- // Not JSON, just log (only in debug mode)
958
- if (this.config.debug) {
959
- console.error(`[relay-pty:${this.config.name}] ${line}`);
960
- }
961
- }
962
- }
963
- else {
964
- // Non-JSON stderr - only show in debug mode (logs, info messages)
965
- if (this.config.debug) {
966
- console.error(`[relay-pty:${this.config.name}] ${line}`);
967
- }
968
- }
969
- }
970
- }
971
- /**
972
- * Handle a parsed command from Rust relay-pty
973
- * Rust outputs structured JSON with 'kind' field: "message", "spawn", "release"
974
- */
975
- handleRustParsedCommand(parsed) {
976
- switch (parsed.kind) {
977
- case 'spawn':
978
- if (parsed.spawn_name && parsed.spawn_cli) {
979
- this.log(` Spawn detected: ${parsed.spawn_name} (${parsed.spawn_cli})${parsed.spawn_cwd ? ` in ${parsed.spawn_cwd}` : ''}`);
980
- this.handleSpawnCommand(parsed.spawn_name, parsed.spawn_cli, parsed.spawn_task || '', parsed.spawn_cwd);
981
- }
982
- break;
983
- case 'release':
984
- if (parsed.release_name) {
985
- this.log(`Release: ${parsed.release_name}`);
986
- this.handleReleaseCommand(parsed.release_name);
987
- }
988
- else {
989
- this.logError(`Missing release_name in parsed command: ${JSON.stringify(parsed)}`);
990
- }
991
- break;
992
- case 'message':
993
- default:
994
- this.sendRelayCommand({
995
- to: parsed.to,
996
- kind: 'message',
997
- body: parsed.body,
998
- thread: parsed.thread,
999
- raw: parsed.raw,
1000
- });
1001
- break;
1002
- }
1003
- }
1004
- /**
1005
- * Handle continuity command from Rust relay-pty
1006
- *
1007
- * Maps from Rust ContinuityCommand format to TypeScript ContinuityCommand
1008
- * and forwards to the ContinuityManager.
1009
- *
1010
- * Rust format: { type: "continuity", action: string, content: string }
1011
- * TypeScript format: { type: 'save' | 'load' | 'uncertain', content?: string, item?: string }
1012
- */
1013
- async handleRustContinuityCommand(parsed) {
1014
- if (!this.continuity) {
1015
- this.log('Continuity not initialized, skipping continuity command');
1016
- return;
1017
- }
1018
- // Map Rust action to TypeScript ContinuityCommand type
1019
- const action = parsed.action.toLowerCase();
1020
- if (!['save', 'load', 'uncertain'].includes(action)) {
1021
- this.logError(`Unknown continuity action: ${parsed.action}`);
1022
- return;
1023
- }
1024
- // Build TypeScript ContinuityCommand
1025
- const command = {
1026
- type: action,
1027
- };
1028
- if (action === 'save' && parsed.content) {
1029
- command.content = parsed.content;
1030
- }
1031
- else if (action === 'uncertain' && parsed.content) {
1032
- command.item = parsed.content;
1033
- }
1034
- // Deduplication (same logic as base-wrapper)
1035
- const cmdHash = `${command.type}:${command.content || command.item || 'no-content'}`;
1036
- if (command.content && this.processedContinuityCommands.has(cmdHash)) {
1037
- this.log(`Continuity command already processed: ${cmdHash}`);
1038
- return;
1039
- }
1040
- this.processedContinuityCommands.add(cmdHash);
1041
- // Limit dedup set size
1042
- if (this.processedContinuityCommands.size > 100) {
1043
- const oldest = this.processedContinuityCommands.values().next().value;
1044
- if (oldest)
1045
- this.processedContinuityCommands.delete(oldest);
1046
- }
1047
- try {
1048
- this.log(`Processing continuity command: ${command.type}`);
1049
- const response = await this.continuity.handleCommand(this.config.name, command);
1050
- if (response) {
1051
- // Queue response for injection (e.g., for 'load' command)
1052
- this.messageQueue.push({
1053
- from: 'system',
1054
- body: response,
1055
- messageId: `continuity-${Date.now()}`,
1056
- thread: 'continuity-response',
1057
- });
1058
- this.log(`Queued continuity response for injection`);
1059
- }
1060
- else {
1061
- this.log(`Continuity command ${command.type} completed (no response)`);
1062
- }
1063
- }
1064
- catch (err) {
1065
- this.logError(`Continuity command failed: ${err.message}`);
1066
- }
1067
- }
1068
- /**
1069
- * Handle spawn command (from Rust stderr JSON parsing)
1070
- *
1071
- * Note: We do NOT send the initial task message here because the spawner
1072
- * now handles it after waitUntilCliReady(). Sending it here would cause
1073
- * duplicate task delivery.
1074
- */
1075
- handleSpawnCommand(name, cli, task, cwd) {
1076
- const key = `spawn:${name}:${cli}`;
1077
- if (this.processedSpawnCommands.has(key)) {
1078
- this.log(`Spawn already processed: ${key}`);
1079
- return;
1080
- }
1081
- this.processedSpawnCommands.add(key);
1082
- // Log spawn attempts (only in debug mode to avoid TUI pollution)
1083
- this.log(`SPAWN REQUEST: ${name} (${cli})${cwd ? ` cwd=${cwd}` : ''}`);
1084
- this.log(` client=${this.client.state}, dashboardPort=${this.config.dashboardPort}, onSpawn=${!!this.config.onSpawn}`);
1085
- // Try daemon socket first (most reliable - daemon has relay-pty binary),
1086
- // then dashboard API, then onSpawn callback as final fallback.
1087
- this.executeSpawnWithFallbacks(name, cli, task, cwd).catch(err => {
1088
- this.logError(`SPAWN FAILED: ${name} - all methods exhausted: ${err.message}`);
1089
- });
1090
- }
1091
- /**
1092
- * Execute spawn with daemon-first fallback chain.
1093
- * Order: daemon socket → dashboard API → onSpawn callback
1094
- */
1095
- async executeSpawnWithFallbacks(name, cli, task, cwd) {
1096
- // 1. Try daemon socket spawn first (daemon always has access to relay-pty)
1097
- if (this.client.state === 'READY') {
1098
- try {
1099
- this.log(`Spawning ${name} via daemon socket`);
1100
- const result = await this.client.spawn({ name, cli, task, cwd });
1101
- if (result.success) {
1102
- this.log(`SPAWN SUCCESS: ${name} via daemon socket`);
1103
- // Also register cwd with dashboard API so agentCwdMap is populated
1104
- // (daemon socket spawn bypasses /api/spawn which normally sets this)
1105
- if (cwd && this.config.dashboardPort) {
1106
- this.registerCwdWithDashboard(name, cwd).catch(err => {
1107
- this.log(`Failed to register cwd with dashboard: ${err.message}`);
1108
- });
1109
- }
1110
- }
1111
- else {
1112
- // Daemon explicitly rejected - respect its decision (policy, duplicate, etc.)
1113
- this.logError(`Daemon spawn rejected: ${result.error}`);
1114
- }
1115
- // Always return if daemon responded - only fall through on transport errors
1116
- return;
1117
- }
1118
- catch (err) {
1119
- this.logError(`Daemon spawn transport error: ${err.message}`);
1120
- }
1121
- }
1122
- // 2. Fall back to dashboard API
1123
- if (this.config.dashboardPort) {
1124
- try {
1125
- this.log(`Spawning ${name} via dashboard API at port ${this.config.dashboardPort}`);
1126
- await this.spawnViaDashboardApi(name, cli, task, cwd);
1127
- this.log(`SPAWN SUCCESS: ${name} via dashboard API`);
1128
- return;
1129
- }
1130
- catch (err) {
1131
- this.logError(`Dashboard spawn failed: ${err.message}`);
1132
- }
1133
- }
1134
- // 3. Final fallback: onSpawn callback
1135
- if (this.config.onSpawn) {
1136
- this.log(`Spawning ${name} via onSpawn callback`);
1137
- await this.config.onSpawn(name, cli, task, cwd);
1138
- return;
1139
- }
1140
- throw new Error(`No spawn mechanism available (client=${this.client.state}, dashboardPort=${this.config.dashboardPort}, onSpawn=${!!this.config.onSpawn})`);
1141
- }
1142
- /**
1143
- * Handle release command
1144
- */
1145
- handleReleaseCommand(name) {
1146
- const key = `release:${name}`;
1147
- if (this.processedReleaseCommands.has(key)) {
1148
- return;
1149
- }
1150
- this.processedReleaseCommands.add(key);
1151
- this.log(` Release: ${name}`);
1152
- // Try daemon socket first, then dashboard API, then callback
1153
- this.executeReleaseWithFallbacks(name).catch(err => {
1154
- this.logError(`RELEASE FAILED: ${name} - all methods exhausted: ${err.message}`);
1155
- });
1156
- }
1157
- /**
1158
- * Execute release with daemon-first fallback chain.
1159
- * Order: daemon socket → dashboard API → onRelease callback
1160
- */
1161
- async executeReleaseWithFallbacks(name) {
1162
- // 1. Try daemon socket release first
1163
- if (this.client.state === 'READY') {
1164
- try {
1165
- const result = await this.client.release(name);
1166
- if (result.success) {
1167
- return;
1168
- }
1169
- // Daemon explicitly rejected - respect its decision
1170
- this.logError(`Daemon release rejected: ${result.error}`);
1171
- // Always return if daemon responded - only fall through on transport errors
1172
- return;
1173
- }
1174
- catch (err) {
1175
- this.logError(`Daemon release transport error: ${err.message}`);
1176
- }
1177
- }
1178
- // 2. Fall back to dashboard API
1179
- if (this.config.dashboardPort) {
1180
- try {
1181
- await this.releaseViaDashboardApi(name);
1182
- return;
1183
- }
1184
- catch (err) {
1185
- this.logError(`Dashboard release failed: ${err.message}`);
1186
- }
1187
- }
1188
- // 3. Final fallback: onRelease callback
1189
- if (this.config.onRelease) {
1190
- await this.config.onRelease(name);
1191
- return;
1192
- }
1193
- throw new Error(`No release mechanism available (client=${this.client.state}, dashboardPort=${this.config.dashboardPort}, onRelease=${!!this.config.onRelease})`);
1194
- }
1195
- /**
1196
- * Register an agent's cwd with the dashboard API.
1197
- * Used after daemon socket spawns which bypass /api/spawn and its agentCwdMap.
1198
- */
1199
- async registerCwdWithDashboard(name, cwd) {
1200
- const url = `http://localhost:${this.config.dashboardPort}/api/agents/${encodeURIComponent(name)}/cwd`;
1201
- const response = await fetch(url, {
1202
- method: 'PUT',
1203
- headers: { 'Content-Type': 'application/json' },
1204
- body: JSON.stringify({ cwd }),
1205
- });
1206
- if (!response.ok) {
1207
- throw new Error(`HTTP ${response.status}`);
1208
- }
1209
- }
1210
- /**
1211
- * Spawn agent via dashboard API
1212
- */
1213
- async spawnViaDashboardApi(name, cli, task, cwd) {
1214
- const url = `http://localhost:${this.config.dashboardPort}/api/spawn`;
1215
- const body = {
1216
- name,
1217
- cli,
1218
- task,
1219
- spawnerName: this.config.name, // Include spawner name so task appears from correct agent
1220
- cwd,
1221
- };
1222
- try {
1223
- const response = await fetch(url, {
1224
- method: 'POST',
1225
- headers: { 'Content-Type': 'application/json' },
1226
- body: JSON.stringify(body),
1227
- });
1228
- if (!response.ok) {
1229
- const errorBody = await response.text().catch(() => 'unknown');
1230
- throw new Error(`HTTP ${response.status}: ${errorBody}`);
1231
- }
1232
- const result = await response.json().catch(() => ({}));
1233
- if (result.success === false) {
1234
- throw new Error(result.error || 'Spawn failed without specific error');
1235
- }
1236
- }
1237
- catch (err) {
1238
- // Enhance error with context
1239
- if (err.code === 'ECONNREFUSED') {
1240
- throw new Error(`Dashboard not reachable at ${url} (connection refused)`);
1241
- }
1242
- throw err;
1243
- }
1244
- }
1245
- /**
1246
- * Release agent via dashboard API
1247
- */
1248
- async releaseViaDashboardApi(name) {
1249
- const response = await fetch(`http://localhost:${this.config.dashboardPort}/api/spawned/${encodeURIComponent(name)}`, {
1250
- method: 'DELETE',
1251
- });
1252
- if (!response.ok) {
1253
- const body = await response.json().catch(() => ({ error: 'Unknown' }));
1254
- throw new Error(`HTTP ${response.status}: ${body.error || 'Unknown error'}`);
1255
- }
1256
- this.log(`Released ${name} via dashboard API`);
1257
- }
1258
- // =========================================================================
1259
- // Socket communication
1260
- // =========================================================================
1261
- /**
1262
- * Check if the relay-pty process is still alive
1263
- */
1264
- isProcessAlive() {
1265
- if (!this.relayPtyProcess || this.relayPtyProcess.exitCode !== null) {
1266
- return false;
1267
- }
1268
- try {
1269
- // Signal 0 checks if process exists without killing it
1270
- process.kill(this.relayPtyProcess.pid, 0);
1271
- return true;
1272
- }
1273
- catch {
1274
- return false;
1275
- }
1276
- }
1277
- /**
1278
- * Connect to the relay-pty socket
1279
- */
1280
- async connectToSocket() {
1281
- const timeout = this.config.socketConnectTimeoutMs ?? 5000;
1282
- const maxAttempts = this.config.socketReconnectAttempts ?? 3;
1283
- for (let attempt = 1; attempt <= maxAttempts; attempt++) {
1284
- // Check if relay-pty process died before attempting connection
1285
- if (!this.isProcessAlive()) {
1286
- const exitInfo = this.earlyExitInfo;
1287
- if (exitInfo) {
1288
- const exitReason = exitInfo.signal
1289
- ? `signal ${exitInfo.signal}`
1290
- : `code ${exitInfo.code ?? 'unknown'}`;
1291
- const stderrHint = exitInfo.stderr
1292
- ? `\n stderr: ${exitInfo.stderr.trim().slice(0, 500)}`
1293
- : '';
1294
- // Add enhanced diagnostics for SIGKILL (likely OOM or resource limit)
1295
- const diagnostics = exitInfo.signal === 'SIGKILL' || exitInfo.code === 137
1296
- ? `\n Diagnostics (SIGKILL often indicates OOM or resource limits):\n ${RelayPtyOrchestrator.gatherSigkillDiagnostics(this.config.name, this.relayPtyProcess?.pid)}`
1297
- : '';
1298
- throw new Error(`relay-pty process died early (${exitReason}).${stderrHint}${diagnostics}`);
1299
- }
1300
- throw new Error('relay-pty process died before socket could be created');
1301
- }
1302
- try {
1303
- await this.attemptSocketConnection(timeout);
1304
- this.log(` Socket connected`);
1305
- return;
1306
- }
1307
- catch (err) {
1308
- this.logError(` Socket connect attempt ${attempt}/${maxAttempts} failed: ${err.message}`);
1309
- if (attempt < maxAttempts) {
1310
- await sleep(1000 * attempt); // Exponential backoff
1311
- }
1312
- }
1313
- }
1314
- // Final check for process death after all attempts
1315
- if (!this.isProcessAlive() && this.earlyExitInfo) {
1316
- const exitInfo = this.earlyExitInfo;
1317
- const exitReason = exitInfo.signal
1318
- ? `signal ${exitInfo.signal}`
1319
- : `code ${exitInfo.code ?? 'unknown'}`;
1320
- const stderrHint = exitInfo.stderr
1321
- ? `\n stderr: ${exitInfo.stderr.trim().slice(0, 500)}`
1322
- : '';
1323
- // Add enhanced diagnostics for SIGKILL
1324
- const diagnostics = exitInfo.signal === 'SIGKILL' || exitInfo.code === 137
1325
- ? `\n Diagnostics (SIGKILL often indicates OOM or resource limits):\n ${RelayPtyOrchestrator.gatherSigkillDiagnostics(this.config.name, this.relayPtyProcess?.pid)}`
1326
- : '';
1327
- throw new Error(`relay-pty process died during socket connection (${exitReason}).${stderrHint}${diagnostics}`);
1328
- }
1329
- throw new Error(`Failed to connect to socket after ${maxAttempts} attempts`);
1330
- }
1331
- /**
1332
- * Attempt a single socket connection
1333
- */
1334
- attemptSocketConnection(timeout) {
1335
- return new Promise((resolve, reject) => {
1336
- // Clean up any existing socket before creating new one
1337
- // This prevents orphaned sockets with stale event handlers
1338
- if (this.socket) {
1339
- // Remove all listeners to prevent the old socket's 'close' event
1340
- // from triggering another reconnect cycle
1341
- this.socket.removeAllListeners();
1342
- this.socket.destroy();
1343
- this.socket = undefined;
1344
- }
1345
- const timer = setTimeout(() => {
1346
- reject(new Error('Socket connection timeout'));
1347
- }, timeout);
1348
- this.socket = createConnection(this.socketPath, () => {
1349
- clearTimeout(timer);
1350
- this.socketConnected = true;
1351
- resolve();
1352
- });
1353
- this.socket.on('error', (err) => {
1354
- clearTimeout(timer);
1355
- this.socketConnected = false;
1356
- reject(err);
1357
- });
1358
- // Handle 'end' event - server closed its write side (half-close)
1359
- this.socket.on('end', () => {
1360
- this.socketConnected = false;
1361
- this.log(` Socket received end (server closed write side)`);
1362
- });
1363
- this.socket.on('close', () => {
1364
- this.socketConnected = false;
1365
- this.log(` Socket closed`);
1366
- // Auto-reconnect if not intentionally stopped
1367
- if (this.running && !this.isGracefulStop) {
1368
- this.scheduleSocketReconnect();
1369
- }
1370
- });
1371
- // Handle incoming data (responses)
1372
- let buffer = '';
1373
- this.socket.on('data', (data) => {
1374
- buffer += data.toString();
1375
- // Process complete lines
1376
- const lines = buffer.split('\n');
1377
- buffer = lines.pop() ?? ''; // Keep incomplete line in buffer
1378
- for (const line of lines) {
1379
- if (line.trim()) {
1380
- this.handleSocketResponse(line);
1381
- }
1382
- }
1383
- });
1384
- });
1385
- }
1386
- /**
1387
- * Disconnect from socket
1388
- */
1389
- disconnectSocket() {
1390
- if (this.socket) {
1391
- this.socket.destroy();
1392
- this.socket = undefined;
1393
- this.socketConnected = false;
1394
- }
1395
- // Reject all pending injections
1396
- for (const [_id, pending] of this.pendingInjections) {
1397
- clearTimeout(pending.timeout);
1398
- pending.reject(new Error('Socket disconnected'));
1399
- }
1400
- this.pendingInjections.clear();
1401
- }
1402
- /** Timer for socket reconnection */
1403
- socketReconnectTimer;
1404
- /** Current reconnection attempt count */
1405
- socketReconnectAttempt = 0;
1406
- /**
1407
- * Schedule a socket reconnection attempt with exponential backoff
1408
- */
1409
- scheduleSocketReconnect() {
1410
- const maxAttempts = this.config.socketReconnectAttempts ?? 3;
1411
- // Clear any existing timer
1412
- if (this.socketReconnectTimer) {
1413
- clearTimeout(this.socketReconnectTimer);
1414
- this.socketReconnectTimer = undefined;
1415
- }
1416
- if (this.socketReconnectAttempt >= maxAttempts) {
1417
- this.logError(` Socket reconnect failed after ${maxAttempts} attempts`);
1418
- // Reset counter for future reconnects (processMessageQueue can trigger new cycle)
1419
- this.socketReconnectAttempt = 0;
1420
- // Note: socketReconnectTimer is already undefined, allowing processMessageQueue
1421
- // to trigger a new reconnection cycle when new messages arrive
1422
- return;
1423
- }
1424
- this.socketReconnectAttempt++;
1425
- const delay = Math.min(1000 * Math.pow(2, this.socketReconnectAttempt - 1), 10000); // Max 10s
1426
- this.log(` Scheduling socket reconnect in ${delay}ms (attempt ${this.socketReconnectAttempt}/${maxAttempts})`);
1427
- this.socketReconnectTimer = setTimeout(async () => {
1428
- // Clear timer reference now that callback is executing
1429
- this.socketReconnectTimer = undefined;
1430
- if (!this.running || this.isGracefulStop) {
1431
- return;
1432
- }
1433
- try {
1434
- const timeout = this.config.socketConnectTimeoutMs ?? 5000;
1435
- await this.attemptSocketConnection(timeout);
1436
- this.log(` Socket reconnected successfully`);
1437
- this.socketReconnectAttempt = 0; // Reset on success
1438
- // Process any queued messages that were waiting
1439
- if (this.messageQueue.length > 0 && !this.isInjecting) {
1440
- this.log(` Processing ${this.messageQueue.length} queued messages after reconnect`);
1441
- this.processMessageQueue();
1442
- }
1443
- }
1444
- catch (err) {
1445
- this.logError(` Socket reconnect attempt ${this.socketReconnectAttempt} failed: ${err.message}`);
1446
- // Schedule another attempt
1447
- this.scheduleSocketReconnect();
1448
- }
1449
- }, delay);
1450
- }
1451
- /**
1452
- * Send a request to the socket and optionally wait for response
1453
- */
1454
- sendSocketRequest(request) {
1455
- return new Promise((resolve, reject) => {
1456
- if (!this.socket || !this.socketConnected) {
1457
- reject(new Error('Socket not connected'));
1458
- return;
1459
- }
1460
- const json = JSON.stringify(request) + '\n';
1461
- this.socket.write(json, (err) => {
1462
- if (err) {
1463
- reject(err);
1464
- }
1465
- else {
1466
- resolve();
1467
- }
1468
- });
1469
- });
1470
- }
1471
- /**
1472
- * Handle a response from the socket
1473
- */
1474
- handleSocketResponse(line) {
1475
- try {
1476
- const response = JSON.parse(line);
1477
- switch (response.type) {
1478
- case 'inject_result':
1479
- // handleInjectResult is async (does verification), but we don't await here
1480
- // Errors are handled internally by the method
1481
- this.handleInjectResult(response).catch((err) => {
1482
- this.logError(` Error handling inject result: ${err.message}`);
1483
- });
1484
- break;
1485
- case 'status':
1486
- // Status responses are typically requested explicitly
1487
- this.log(` Status: idle=${response.agent_idle} queue=${response.queue_length}`);
1488
- break;
1489
- case 'backpressure':
1490
- this.handleBackpressure(response);
1491
- break;
1492
- case 'error':
1493
- this.logError(` Socket error: ${response.message}`);
1494
- break;
1495
- case 'shutdown_ack':
1496
- this.log(` Shutdown acknowledged`);
1497
- break;
1498
- case 'send_enter_result':
1499
- // SendEnter is no longer used - trust Rust delivery confirmation
1500
- this.log(` Received send_enter_result (deprecated)`);
1501
- break;
1502
- }
1503
- }
1504
- catch (err) {
1505
- this.logError(` Failed to parse socket response: ${err.message}`);
1506
- }
1507
- }
1508
- /**
1509
- * Handle injection result response
1510
- * After Rust reports 'delivered', verifies the message appeared in output.
1511
- * If verification fails, retries up to MAX_RETRIES times.
1512
- */
1513
- async handleInjectResult(response) {
1514
- this.log(` handleInjectResult: id=${response.id.substring(0, 8)} status=${response.status}`);
1515
- const pending = this.pendingInjections.get(response.id);
1516
- if (!pending) {
1517
- // Response for unknown message - might be from a previous session
1518
- this.log(` No pending injection found for ${response.id.substring(0, 8)}`);
1519
- return;
1520
- }
1521
- if (response.status === 'delivered') {
1522
- // Rust says it sent the message + Enter key
1523
- // Trust Rust's delivery confirmation - relay-pty writes directly to PTY which is very reliable.
1524
- //
1525
- // IMPORTANT: We don't verify by looking for the message in output because:
1526
- // 1. TUI CLIs (Claude, Codex, Gemini) don't echo input like traditional terminals
1527
- // 2. The injected text appears as INPUT to the PTY, not OUTPUT
1528
- // 3. Output-based verification always fails for TUIs, causing unnecessary retries
1529
- //
1530
- // This is different from tmux-wrapper where we inject via tmux send-keys
1531
- // and can observe the echoed input in the pane output.
1532
- this.log(` Message ${pending.shortId} delivered by Rust ✓`);
1533
- clearTimeout(pending.timeout);
1534
- this.pendingInjections.delete(response.id);
1535
- if (pending.retryCount === 0) {
1536
- this.injectionMetrics.successFirstTry++;
1537
- }
1538
- else {
1539
- this.injectionMetrics.successWithRetry++;
1540
- }
1541
- this.injectionMetrics.total++;
1542
- pending.resolve(true);
1543
- }
1544
- else if (response.status === 'failed') {
1545
- clearTimeout(pending.timeout);
1546
- this.pendingInjections.delete(response.id);
1547
- this.injectionMetrics.failed++;
1548
- this.injectionMetrics.total++;
1549
- pending.resolve(false);
1550
- this.logError(` Message ${pending.shortId} failed: ${response.error}`);
1551
- this.emit('injection-failed', {
1552
- messageId: response.id,
1553
- from: pending.from,
1554
- error: response.error ?? 'Unknown error',
1555
- });
1556
- }
1557
- // queued/injecting are intermediate states - wait for final status
1558
- }
1559
- /**
1560
- * Handle backpressure notification
1561
- */
1562
- handleBackpressure(response) {
1563
- const wasActive = this.backpressureActive;
1564
- this.backpressureActive = !response.accept;
1565
- if (this.backpressureActive !== wasActive) {
1566
- this.log(` Backpressure: ${this.backpressureActive ? 'ACTIVE' : 'cleared'} (queue=${response.queue_length})`);
1567
- this.emit('backpressure', { queueLength: response.queue_length, accept: response.accept });
1568
- // Resume processing if backpressure cleared
1569
- if (!this.backpressureActive) {
1570
- this.processMessageQueue();
1571
- }
1572
- }
1573
- }
1574
- // =========================================================================
1575
- // Message handling
1576
- // =========================================================================
1577
- /**
1578
- * Inject a message into the agent via socket
1579
- */
1580
- async injectMessage(msg, retryCount = 0) {
1581
- const shortId = msg.messageId.substring(0, 8);
1582
- this.log(` === INJECT START: ${shortId} from ${msg.from} (attempt ${retryCount + 1}) ===`);
1583
- if (!this.socket || !this.socketConnected) {
1584
- this.logError(` Cannot inject - socket not connected`);
1585
- return false;
1586
- }
1587
- // Build injection content
1588
- const content = buildInjectionString(msg);
1589
- this.log(` Injection content (${content.length} bytes): ${content.substring(0, 100)}...`);
1590
- // Create request
1591
- const request = {
1592
- type: 'inject',
1593
- id: msg.messageId,
1594
- from: msg.from,
1595
- body: content,
1596
- priority: msg.importance ?? 0,
1597
- };
1598
- this.log(` Sending inject request to socket...`);
1599
- // Create promise for result
1600
- return new Promise((resolve, reject) => {
1601
- const timeout = setTimeout(() => {
1602
- this.logError(` Inject timeout for ${shortId} after 30s`);
1603
- this.pendingInjections.delete(msg.messageId);
1604
- resolve(false); // Timeout = failure
1605
- }, 30000); // 30 second timeout for injection
1606
- this.pendingInjections.set(msg.messageId, {
1607
- resolve,
1608
- reject,
1609
- timeout,
1610
- from: msg.from,
1611
- shortId,
1612
- retryCount,
1613
- originalBody: content,
1614
- });
1615
- // Send request
1616
- this.sendSocketRequest(request)
1617
- .then(() => {
1618
- this.log(` Socket request sent for ${shortId}`);
1619
- })
1620
- .catch((err) => {
1621
- this.logError(` Socket request failed for ${shortId}: ${err.message}`);
1622
- clearTimeout(timeout);
1623
- this.pendingInjections.delete(msg.messageId);
1624
- resolve(false);
1625
- });
1626
- });
1627
- }
1628
- /**
1629
- * Process queued messages
1630
- */
1631
- async processMessageQueue() {
1632
- // Debug: Log blocking conditions when queue has messages
1633
- if (this.messageQueue.length > 0) {
1634
- if (!this.readyForMessages) {
1635
- this.log(` Queue blocked: readyForMessages=false (queue=${this.messageQueue.length})`);
1636
- return;
1637
- }
1638
- if (this.backpressureActive) {
1639
- this.log(` Queue blocked: backpressure active (queue=${this.messageQueue.length})`);
1640
- return;
1641
- }
1642
- if (this.isInjecting) {
1643
- // Already injecting - the finally block will process next message
1644
- // But add a safety timeout in case injection gets stuck
1645
- const elapsed = this.injectionStartTime > 0 ? Date.now() - this.injectionStartTime : 0;
1646
- if (elapsed > 35000) {
1647
- this.logError(` Injection stuck for ${elapsed}ms, forcing reset`);
1648
- this.isInjecting = false;
1649
- this.injectionStartTime = 0;
1650
- }
1651
- return;
1652
- }
1653
- }
1654
- if (this.messageQueue.length === 0) {
1655
- return;
1656
- }
1657
- // Proactively reconnect socket if disconnected and we have messages to send
1658
- if (!this.socketConnected && !this.socketReconnectTimer) {
1659
- this.log(` Socket disconnected, triggering reconnect before processing queue`);
1660
- this.scheduleSocketReconnect();
1661
- return; // Wait for reconnection to complete
1662
- }
1663
- if (!this.socketConnected) {
1664
- // Reconnection in progress, wait for it
1665
- this.log(` Queue waiting: socket reconnecting (queue=${this.messageQueue.length})`);
1666
- return;
1667
- }
1668
- // Check if agent is in editor mode - delay injection if so
1669
- const idleResult = this.idleDetector.checkIdle();
1670
- if (idleResult.inEditorMode) {
1671
- this.log(` Agent in editor mode, delaying injection (queue: ${this.messageQueue.length})`);
1672
- // Check again in 2 seconds
1673
- setTimeout(() => this.processMessageQueue(), 2000);
1674
- return;
1675
- }
1676
- this.isInjecting = true;
1677
- this.injectionStartTime = Date.now();
1678
- const msg = this.messageQueue.shift();
1679
- const bodyPreview = msg.body.substring(0, 50).replace(/\n/g, '\\n');
1680
- this.log(` Processing message from ${msg.from}: "${bodyPreview}..." (remaining=${this.messageQueue.length})`);
1681
- try {
1682
- const success = await this.injectMessage(msg);
1683
- // Metrics are now tracked in handleInjectResult which knows about retries
1684
- if (!success) {
1685
- // Record failure for adaptive throttling
1686
- this.throttle.recordFailure();
1687
- this.logError(` Injection failed for message ${msg.messageId.substring(0, 8)}`);
1688
- this.config.onInjectionFailed?.(msg.messageId, 'Injection failed');
1689
- this.sendSyncAck(msg.messageId, msg.sync, 'ERROR', { error: 'injection_failed' });
1690
- }
1691
- else {
1692
- // Record success for adaptive throttling
1693
- this.throttle.recordSuccess();
1694
- this.sendSyncAck(msg.messageId, msg.sync, 'OK');
1695
- }
1696
- }
1697
- catch (err) {
1698
- this.logError(` Injection error: ${err.message}`);
1699
- // Track metrics for exceptions (not handled by handleInjectResult)
1700
- this.injectionMetrics.failed++;
1701
- this.injectionMetrics.total++;
1702
- // Record failure for adaptive throttling
1703
- this.throttle.recordFailure();
1704
- this.sendSyncAck(msg.messageId, msg.sync, 'ERROR', { error: err.message });
1705
- }
1706
- finally {
1707
- this.isInjecting = false;
1708
- this.injectionStartTime = 0;
1709
- // Process next message after adaptive delay (faster when healthy, slower under stress)
1710
- if (this.messageQueue.length > 0 && !this.backpressureActive) {
1711
- const delay = this.throttle.getDelay();
1712
- setTimeout(() => this.processMessageQueue(), delay);
1713
- }
1714
- }
1715
- }
1716
- /**
1717
- * Override handleIncomingMessage to trigger queue processing
1718
- */
1719
- handleIncomingMessage(from, payload, messageId, meta, originalTo) {
1720
- this.log(` === MESSAGE RECEIVED: ${messageId.substring(0, 8)} from ${from} ===`);
1721
- this.log(` Body preview: ${payload.body?.substring(0, 100) ?? '(no body)'}...`);
1722
- super.handleIncomingMessage(from, payload, messageId, meta, originalTo);
1723
- this.log(` Queue length after add: ${this.messageQueue.length}`);
1724
- this.processMessageQueue();
1725
- }
1726
- /**
1727
- * Override handleIncomingChannelMessage to trigger queue processing.
1728
- * Without this override, channel messages would be queued but processMessageQueue()
1729
- * would never be called, causing messages to get stuck until the queue monitor runs.
1730
- */
1731
- handleIncomingChannelMessage(from, channel, body, envelope) {
1732
- this.log(` === CHANNEL MESSAGE RECEIVED: ${envelope.id.substring(0, 8)} from ${from} on ${channel} ===`);
1733
- this.log(` Body preview: ${body?.substring(0, 100) ?? '(no body)'}...`);
1734
- super.handleIncomingChannelMessage(from, channel, body, envelope);
1735
- this.log(` Queue length after add: ${this.messageQueue.length}`);
1736
- this.processMessageQueue();
1737
- }
1738
- // =========================================================================
1739
- // Queue monitor - Detect and process stuck messages
1740
- // =========================================================================
1741
- /**
1742
- * Start the queue monitor to periodically check for stuck messages.
1743
- * This ensures messages don't get orphaned in the queue when the agent is idle.
1744
- */
1745
- startQueueMonitor() {
1746
- if (this.queueMonitorTimer) {
1747
- return; // Already started
1748
- }
1749
- this.log(` Starting queue monitor (interval: ${this.QUEUE_MONITOR_INTERVAL_MS}ms)`);
1750
- this.queueMonitorTimer = setInterval(() => {
1751
- this.checkForStuckQueue();
1752
- }, this.QUEUE_MONITOR_INTERVAL_MS);
1753
- // Don't keep process alive just for queue monitoring
1754
- this.queueMonitorTimer.unref?.();
1755
- }
1756
- /**
1757
- * Stop the queue monitor.
1758
- */
1759
- stopQueueMonitor() {
1760
- if (this.queueMonitorTimer) {
1761
- clearInterval(this.queueMonitorTimer);
1762
- this.queueMonitorTimer = undefined;
1763
- this.log(` Queue monitor stopped`);
1764
- }
1765
- }
1766
- // =========================================================================
1767
- // Protocol monitoring (detect agent mistakes like empty AGENT_RELAY_NAME)
1768
- // =========================================================================
1769
- /**
1770
- * Start watching for protocol issues in the outbox directory.
1771
- * Detects common mistakes like:
1772
- * - Empty AGENT_RELAY_NAME causing files at outbox//
1773
- * - Files created directly in outbox/ instead of agent subdirectory
1774
- */
1775
- startProtocolMonitor() {
1776
- // Get the outbox parent directory (one level up from agent's outbox)
1777
- const parentDir = dirname(this._canonicalOutboxPath);
1778
- // Ensure parent directory exists
1779
- try {
1780
- if (!existsSync(parentDir)) {
1781
- mkdirSync(parentDir, { recursive: true });
1782
- }
1783
- }
1784
- catch {
1785
- // Ignore - directory may already exist
1786
- }
1787
- try {
1788
- this.protocolWatcher = watch(parentDir, (eventType, filename) => {
1789
- if (eventType === 'rename' && filename) {
1790
- // Check for files directly in parent (not in agent subdirectory)
1791
- // This happens when $AGENT_RELAY_NAME is empty
1792
- const fullPath = join(parentDir, filename);
1793
- try {
1794
- // If it's a file (not directory) directly in the parent, that's an issue
1795
- if (existsSync(fullPath) && !lstatSync(fullPath).isDirectory()) {
1796
- this.handleProtocolIssue('file_in_root', filename);
1797
- }
1798
- // Check for empty-named directory (double slash symptom)
1799
- if (filename === '' || filename.startsWith('/')) {
1800
- this.handleProtocolIssue('empty_agent_name', filename);
1801
- }
1802
- }
1803
- catch {
1804
- // Ignore stat errors
1805
- }
1806
- }
1807
- });
1808
- // Don't keep process alive just for protocol monitoring
1809
- this.protocolWatcher.unref?.();
1810
- this.log(` Protocol monitor started on ${parentDir}`);
1811
- }
1812
- catch (err) {
1813
- // Don't fail start() if protocol monitoring fails
1814
- this.logError(` Failed to start protocol monitor: ${err.message}`);
1815
- }
1816
- // Also do an initial scan for existing issues
1817
- this.scanForProtocolIssues();
1818
- }
1819
- /**
1820
- * Stop the protocol monitor.
1821
- */
1822
- stopProtocolMonitor() {
1823
- if (this.protocolWatcher) {
1824
- this.protocolWatcher.close();
1825
- this.protocolWatcher = undefined;
1826
- this.log(` Protocol monitor stopped`);
1827
- }
1828
- }
1829
- /**
1830
- * Scan for existing protocol issues (called once at startup).
1831
- */
1832
- scanForProtocolIssues() {
1833
- const parentDir = dirname(this._canonicalOutboxPath);
1834
- try {
1835
- if (!existsSync(parentDir))
1836
- return;
1837
- const entries = readdirSync(parentDir);
1838
- for (const entry of entries) {
1839
- const fullPath = join(parentDir, entry);
1840
- try {
1841
- // Check for files directly in parent (should only be directories)
1842
- if (!lstatSync(fullPath).isDirectory()) {
1843
- this.handleProtocolIssue('file_in_root', entry);
1844
- break; // Only report once
1845
- }
1846
- }
1847
- catch {
1848
- // Ignore stat errors
1849
- }
1850
- }
1851
- }
1852
- catch {
1853
- // Ignore scan errors
1854
- }
1855
- }
1856
- /**
1857
- * Handle a detected protocol issue by injecting a helpful reminder.
1858
- */
1859
- handleProtocolIssue(issue, filename) {
1860
- const now = Date.now();
1861
- // Respect cooldown to avoid spamming
1862
- if (now - this.protocolReminderCooldown < this.PROTOCOL_REMINDER_COOLDOWN_MS) {
1863
- return;
1864
- }
1865
- this.protocolReminderCooldown = now;
1866
- this.log(` Protocol issue detected: ${issue} (${filename})`);
1867
- const reminders = {
1868
- empty_agent_name: `⚠️ **Protocol Issue Detected**
1869
-
1870
- Your \`$AGENT_RELAY_NAME\` environment variable appears to be empty or unset.
1871
- Your agent name is: **${this.config.name}**
1872
-
1873
- Correct outbox path: \`$AGENT_RELAY_OUTBOX\`
1874
-
1875
- When writing relay files, use:
1876
- \`\`\`bash
1877
- cat > $AGENT_RELAY_OUTBOX/msg << 'EOF'
1878
- TO: TargetAgent
1879
-
1880
- Your message here
1881
- EOF
1882
- \`\`\`
1883
- Then output: \`->relay-file:msg\``,
1884
- file_in_root: `⚠️ **Protocol Issue Detected**
1885
-
1886
- Found file "${filename}" directly in the outbox root instead of using the proper path.
1887
- Your agent name is: **${this.config.name}**
1888
-
1889
- The \`$AGENT_RELAY_OUTBOX\` path already points to your agent's directory.
1890
- Write files directly inside it:
1891
-
1892
- \`\`\`bash
1893
- cat > $AGENT_RELAY_OUTBOX/msg << 'EOF'
1894
- TO: TargetAgent
1895
-
1896
- Your message here
1897
- EOF
1898
- \`\`\`
1899
- Then output: \`->relay-file:msg\``,
1900
- };
1901
- const reminder = reminders[issue];
1902
- if (reminder) {
1903
- this.injectProtocolReminder(reminder);
1904
- }
1905
- }
1906
- /**
1907
- * Inject a protocol reminder message to the agent.
1908
- */
1909
- injectProtocolReminder(message) {
1910
- const queuedMsg = {
1911
- from: 'system',
1912
- body: message,
1913
- messageId: `protocol-reminder-${Date.now()}`,
1914
- importance: 2, // Higher priority
1915
- };
1916
- this.messageQueue.unshift(queuedMsg); // Add to front of queue
1917
- this.log(` Queued protocol reminder (queue size: ${this.messageQueue.length})`);
1918
- // Trigger processing if not already in progress
1919
- if (!this.isInjecting && this.readyForMessages) {
1920
- this.processMessageQueue();
1921
- }
1922
- }
1923
- // =========================================================================
1924
- // Periodic protocol reminders (for long sessions where agents forget protocol)
1925
- // =========================================================================
1926
- /**
1927
- * Start sending periodic protocol reminders.
1928
- * Agents in long sessions sometimes forget the relay protocol - these
1929
- * reminders help them stay on track without user intervention.
1930
- */
1931
- startPeriodicReminder() {
1932
- this.sessionStartTime = Date.now();
1933
- this.periodicReminderTimer = setInterval(() => {
1934
- this.sendPeriodicProtocolReminder();
1935
- }, this.PERIODIC_REMINDER_INTERVAL_MS);
1936
- // Don't keep process alive just for reminders
1937
- this.periodicReminderTimer.unref?.();
1938
- const intervalMinutes = Math.round(this.PERIODIC_REMINDER_INTERVAL_MS / 60000);
1939
- this.log(` Periodic protocol reminder started (interval: ${intervalMinutes} minutes)`);
1940
- }
1941
- /**
1942
- * Stop periodic protocol reminders.
1943
- */
1944
- stopPeriodicReminder() {
1945
- if (this.periodicReminderTimer) {
1946
- clearInterval(this.periodicReminderTimer);
1947
- this.periodicReminderTimer = undefined;
1948
- this.log(` Periodic protocol reminder stopped`);
1949
- }
1950
- }
1951
- /**
1952
- * Send a periodic protocol reminder to the agent.
1953
- * This reminds agents about proper relay communication format after long sessions.
1954
- */
1955
- sendPeriodicProtocolReminder() {
1956
- // Don't send if not ready
1957
- if (!this.running || !this.readyForMessages) {
1958
- return;
1959
- }
1960
- const sessionDurationMinutes = Math.round((Date.now() - this.sessionStartTime) / 60000);
1961
- const reminder = `📋 **Protocol Reminder** (Session: ${sessionDurationMinutes} minutes)
1962
-
1963
- You are **${this.config.name}** in a multi-agent relay system. Here's how to communicate:
1964
-
1965
- **Sending Messages:**
1966
- \`\`\`bash
1967
- cat > $AGENT_RELAY_OUTBOX/msg << 'EOF'
1968
- TO: *
1969
-
1970
- Your message here
1971
- EOF
1972
- \`\`\`
1973
- Then output: \`->relay-file:msg\`
1974
-
1975
- Use \`TO: *\` to broadcast to all agents, or \`TO: AgentName\` for a specific agent.
1976
-
1977
- **Spawning Agents:**
1978
- \`\`\`bash
1979
- cat > $AGENT_RELAY_OUTBOX/spawn << 'EOF'
1980
- KIND: spawn
1981
- NAME: WorkerName
1982
- CLI: claude
1983
-
1984
- Task description here
1985
- EOF
1986
- \`\`\`
1987
- Then output: \`->relay-file:spawn\`
1988
-
1989
- **Message Format:**
1990
- - \`TO: AgentName\` for direct messages
1991
- - \`TO: *\` to broadcast to all agents
1992
- - \`TO: #channel\` for channel messages
1993
-
1994
- 📖 See **AGENTS.md** in the project root for full protocol documentation.`;
1995
- this.log(` Sending periodic protocol reminder (session: ${sessionDurationMinutes}m)`);
1996
- this.injectProtocolReminder(reminder);
1997
- }
1998
- /**
1999
- * Check for messages stuck in the queue and process them if the agent is idle.
2000
- *
2001
- * This handles cases where:
2002
- * 1. Messages arrived while the agent was busy and the retry mechanism failed
2003
- * 2. Socket disconnection/reconnection left messages orphaned
2004
- * 3. Injection timeouts occurred without proper queue resumption
2005
- */
2006
- checkForStuckQueue() {
2007
- // Skip if not ready for messages
2008
- if (!this.readyForMessages || !this.running) {
2009
- return;
2010
- }
2011
- // Skip if queue is empty
2012
- if (this.messageQueue.length === 0) {
2013
- return;
2014
- }
2015
- // Check if currently injecting
2016
- if (this.isInjecting) {
2017
- // Check if injection has been stuck for too long
2018
- const stuckDuration = Date.now() - this.injectionStartTime;
2019
- if (stuckDuration > this.MAX_INJECTION_STUCK_MS) {
2020
- this.logError(` ⚠️ Injection stuck for ${Math.round(stuckDuration / 1000)}s - force resetting`);
2021
- this.isInjecting = false;
2022
- this.injectionStartTime = 0;
2023
- // Clear any pending injections that might be stuck
2024
- for (const [id, pending] of this.pendingInjections) {
2025
- clearTimeout(pending.timeout);
2026
- this.logError(` Clearing stuck pending injection: ${id.substring(0, 8)}`);
2027
- }
2028
- this.pendingInjections.clear();
2029
- // Continue to process the queue below
2030
- }
2031
- else {
2032
- return; // Still within normal injection time
2033
- }
2034
- }
2035
- // Skip if backpressure is active
2036
- if (this.backpressureActive) {
2037
- return;
2038
- }
2039
- // Check if the agent is idle (high confidence)
2040
- const idleResult = this.idleDetector.checkIdle({ minSilenceMs: 2000 });
2041
- if (!idleResult.isIdle) {
2042
- // Agent is still working, let it finish
2043
- return;
2044
- }
2045
- // We have messages in the queue, agent is idle, not currently injecting
2046
- // This is a stuck queue situation - trigger processing
2047
- const senders = [...new Set(this.messageQueue.map(m => m.from))];
2048
- this.log(` ⚠️ Queue monitor: Found ${this.messageQueue.length} stuck message(s) from [${senders.join(', ')}]`);
2049
- this.log(` ⚠️ Agent is idle (confidence: ${(idleResult.confidence * 100).toFixed(0)}%), triggering queue processing`);
2050
- // Process the queue
2051
- this.processMessageQueue();
2052
- }
2053
- // =========================================================================
2054
- // Output parsing
2055
- // =========================================================================
2056
- /**
2057
- * Parse relay commands from output
2058
- */
2059
- parseRelayCommands() {
2060
- const cleanContent = stripAnsi(this.rawBuffer);
2061
- if (cleanContent.length <= this.lastParsedLength) {
2062
- return;
2063
- }
2064
- // Parse new content with lookback for fenced messages
2065
- const lookbackStart = Math.max(0, this.lastParsedLength - 500);
2066
- const contentToParse = cleanContent.substring(lookbackStart);
2067
- // Parse fenced messages
2068
- this.parseFencedMessages(contentToParse);
2069
- // Parse single-line messages
2070
- this.parseSingleLineMessages(contentToParse);
2071
- // Parse spawn/release commands
2072
- this.parseSpawnReleaseCommands(contentToParse);
2073
- this.lastParsedLength = cleanContent.length;
2074
- }
2075
- /**
2076
- * Parse fenced multi-line messages
2077
- */
2078
- parseFencedMessages(content) {
2079
- const escapedPrefix = this.relayPrefix.replace(/[.*+?^${}()|[\]\\]/g, '\\$&');
2080
- const fencePattern = new RegExp(`${escapedPrefix}(\\S+)(?:\\s+\\[thread:([\\w-]+)\\])?\\s*<<<([\\s\\S]*?)>>>`, 'g');
2081
- let match;
2082
- while ((match = fencePattern.exec(content)) !== null) {
2083
- const target = match[1];
2084
- const thread = match[2];
2085
- const body = match[3].trim();
2086
- if (!body || target === 'spawn' || target === 'release') {
2087
- continue;
2088
- }
2089
- this.sendRelayCommand({
2090
- to: target,
2091
- kind: 'message',
2092
- body,
2093
- thread,
2094
- raw: match[0],
2095
- });
2096
- }
2097
- }
2098
- /**
2099
- * Parse single-line messages
2100
- */
2101
- parseSingleLineMessages(content) {
2102
- const lines = content.split('\n');
2103
- const escapedPrefix = this.relayPrefix.replace(/[.*+?^${}()|[\]\\]/g, '\\$&');
2104
- const pattern = new RegExp(`${escapedPrefix}(\\S+)(?:\\s+\\[thread:([\\w-]+)\\])?\\s+(.+)$`);
2105
- for (const line of lines) {
2106
- // Skip fenced messages
2107
- if (line.includes('<<<') || line.includes('>>>')) {
2108
- continue;
2109
- }
2110
- const match = line.match(pattern);
2111
- if (!match) {
2112
- continue;
2113
- }
2114
- const target = match[1];
2115
- const thread = match[2];
2116
- const body = match[3].trim();
2117
- if (!body || target === 'spawn' || target === 'release') {
2118
- continue;
2119
- }
2120
- this.sendRelayCommand({
2121
- to: target,
2122
- kind: 'message',
2123
- body,
2124
- thread,
2125
- raw: line,
2126
- });
2127
- }
2128
- }
2129
- // =========================================================================
2130
- // Summary and session end detection
2131
- // =========================================================================
2132
- /**
2133
- * Check for [[SUMMARY]] blocks
2134
- */
2135
- checkForSummary(content) {
2136
- const result = parseSummaryWithDetails(content);
2137
- if (!result.found || !result.valid) {
2138
- return;
2139
- }
2140
- if (result.rawContent === this.lastSummaryRawContent) {
2141
- return;
2142
- }
2143
- this.lastSummaryRawContent = result.rawContent ?? '';
2144
- this.emit('summary', {
2145
- agentName: this.config.name,
2146
- summary: result.summary,
2147
- });
2148
- }
2149
- /**
2150
- * Check for [[SESSION_END]] blocks
2151
- */
2152
- checkForSessionEnd(content) {
2153
- if (this.sessionEndProcessed) {
2154
- return;
2155
- }
2156
- const sessionEnd = parseSessionEndFromOutput(content);
2157
- if (!sessionEnd) {
2158
- return;
2159
- }
2160
- // Store SESSION_END data for use in autoSave (fixes empty handoff issue)
2161
- this.sessionEndData = sessionEnd;
2162
- this.sessionEndProcessed = true;
2163
- this.emit('session-end', {
2164
- agentName: this.config.name,
2165
- marker: sessionEnd,
2166
- });
2167
- }
2168
- // =========================================================================
2169
- // Public API
2170
- // =========================================================================
2171
- /**
2172
- * Query status from relay-pty
2173
- */
2174
- async queryStatus() {
2175
- if (!this.socket || !this.socketConnected) {
2176
- return null;
2177
- }
2178
- try {
2179
- await this.sendSocketRequest({ type: 'status' });
2180
- // Response will come asynchronously via handleSocketResponse
2181
- // For now, return null - could implement request/response matching
2182
- return null;
2183
- }
2184
- catch {
2185
- return null;
2186
- }
2187
- }
2188
- /**
2189
- * Wait for the CLI to be ready to receive messages.
2190
- * This waits for:
2191
- * 1. The CLI to produce at least one output (it has started)
2192
- * 2. The CLI to become idle (it's ready for input)
2193
- *
2194
- * This is more reliable than a random sleep because it waits for
2195
- * actual signals from the CLI rather than guessing how long it takes to start.
2196
- *
2197
- * @param timeoutMs Maximum time to wait (default: 30s)
2198
- * @param pollMs Polling interval (default: 100ms)
2199
- * @returns true if CLI is ready, false if timeout
2200
- */
2201
- async waitUntilCliReady(timeoutMs = 30000, pollMs = 100) {
2202
- const startTime = Date.now();
2203
- this.log(` Waiting for CLI to be ready (timeout: ${timeoutMs}ms)`);
2204
- // In interactive mode, stdout is inherited (not captured), so hasReceivedOutput
2205
- // will never be set. Trust that the process is ready if it's running.
2206
- if (this.isInteractive) {
2207
- this.log(` Interactive mode - trusting process is ready`);
2208
- // Give a brief moment for the CLI to initialize its TUI.
2209
- // 500ms is a conservative estimate based on typical CLI startup times:
2210
- // - Claude CLI: ~200-300ms to show initial prompt
2211
- // - Codex/Gemini: ~300-400ms
2212
- // This delay is only used in interactive mode where we can't detect output.
2213
- // In non-interactive mode, we poll for actual output instead.
2214
- await sleep(500);
2215
- return this.running;
2216
- }
2217
- // Phase 1: Wait for first output (CLI has started)
2218
- while (Date.now() - startTime < timeoutMs) {
2219
- if (this.hasReceivedOutput) {
2220
- this.log(` CLI has started producing output`);
2221
- break;
2222
- }
2223
- await sleep(pollMs);
2224
- }
2225
- if (!this.hasReceivedOutput) {
2226
- this.log(` Timeout waiting for CLI to produce output`);
2227
- return false;
2228
- }
2229
- // Phase 2: Wait for idle state (CLI is ready for input)
2230
- const remainingTime = timeoutMs - (Date.now() - startTime);
2231
- if (remainingTime <= 0) {
2232
- return false;
2233
- }
2234
- const idleResult = await this.waitForIdleState(remainingTime, pollMs);
2235
- if (idleResult.isIdle) {
2236
- this.log(` CLI is idle and ready (confidence: ${idleResult.confidence.toFixed(2)})`);
2237
- return true;
2238
- }
2239
- this.log(` Timeout waiting for CLI to become idle`);
2240
- return false;
2241
- }
2242
- /**
2243
- * Check if the CLI has produced any output yet.
2244
- * Useful for checking if the CLI has started without blocking.
2245
- * In interactive mode, returns true if process is running (output isn't captured).
2246
- */
2247
- hasCliStarted() {
2248
- // In interactive mode, stdout isn't captured so hasReceivedOutput is never set
2249
- if (this.isInteractive) {
2250
- return this.running;
2251
- }
2252
- return this.hasReceivedOutput;
2253
- }
2254
- /**
2255
- * Check if the orchestrator is ready to receive and inject messages.
2256
- * This requires:
2257
- * 1. relay-pty process spawned
2258
- * 2. Socket connected to relay-pty
2259
- * 3. running flag set
2260
- *
2261
- * Use this to verify the agent can actually receive injected messages,
2262
- * not just that the CLI is running.
2263
- */
2264
- isReadyForMessages() {
2265
- return this.readyForMessages && this.running && this.socketConnected;
2266
- }
2267
- /**
2268
- * Wait until the orchestrator is ready to receive and inject messages.
2269
- * This is more comprehensive than waitUntilCliReady because it ensures:
2270
- * 1. CLI is ready (has output and is idle)
2271
- * 2. Orchestrator is ready (socket connected, can inject)
2272
- *
2273
- * @param timeoutMs Maximum time to wait (default: 30s)
2274
- * @param pollMs Polling interval (default: 100ms)
2275
- * @returns true if ready, false if timeout
2276
- */
2277
- async waitUntilReadyForMessages(timeoutMs = 30000, pollMs = 100) {
2278
- const startTime = Date.now();
2279
- this.log(` Waiting for orchestrator to be ready for messages (timeout: ${timeoutMs}ms)`);
2280
- // First wait for CLI to be ready (output + idle)
2281
- const cliReady = await this.waitUntilCliReady(timeoutMs, pollMs);
2282
- if (!cliReady) {
2283
- this.log(` CLI not ready within timeout`);
2284
- return false;
2285
- }
2286
- // Then wait for readyForMessages flag
2287
- const remainingTime = timeoutMs - (Date.now() - startTime);
2288
- if (remainingTime <= 0) {
2289
- this.log(` No time remaining to wait for readyForMessages`);
2290
- return this.isReadyForMessages();
2291
- }
2292
- while (Date.now() - startTime < timeoutMs) {
2293
- if (this.isReadyForMessages()) {
2294
- this.log(` Orchestrator is ready for messages`);
2295
- return true;
2296
- }
2297
- await sleep(pollMs);
2298
- }
2299
- this.log(` Timeout waiting for orchestrator to be ready for messages`);
2300
- return false;
2301
- }
2302
- /**
2303
- * Get raw output buffer
2304
- */
2305
- getRawOutput() {
2306
- return this.rawBuffer;
2307
- }
2308
- /**
2309
- * Check if backpressure is active
2310
- */
2311
- isBackpressureActive() {
2312
- return this.backpressureActive;
2313
- }
2314
- /**
2315
- * Get the socket path
2316
- */
2317
- getSocketPath() {
2318
- return this.socketPath;
2319
- }
2320
- /**
2321
- * Get the relay-pty process PID
2322
- */
2323
- get pid() {
2324
- return this.relayPtyProcess?.pid;
2325
- }
2326
- /**
2327
- * Get the log file path (not used by relay-pty, returns undefined)
2328
- */
2329
- get logPath() {
2330
- return this._logPath;
2331
- }
2332
- /**
2333
- * Kill the process forcefully
2334
- */
2335
- async kill() {
2336
- this.isGracefulStop = true; // Mark as intentional to prevent crash broadcast
2337
- if (this.socketReconnectTimer) {
2338
- clearTimeout(this.socketReconnectTimer);
2339
- this.socketReconnectTimer = undefined;
2340
- }
2341
- if (this.relayPtyProcess && !this.relayPtyProcess.killed) {
2342
- this.relayPtyProcess.kill('SIGKILL');
2343
- }
2344
- this.running = false;
2345
- this.disconnectSocket();
2346
- this.destroyClient();
2347
- }
2348
- /**
2349
- * Get output lines (for compatibility with PtyWrapper)
2350
- * @param limit Maximum number of lines to return
2351
- */
2352
- getOutput(limit) {
2353
- const lines = this.rawBuffer.split('\n');
2354
- if (limit && limit > 0) {
2355
- return lines.slice(-limit);
2356
- }
2357
- return lines;
2358
- }
2359
- /**
2360
- * Write data directly to the process stdin
2361
- * @param data Data to write
2362
- */
2363
- async write(data) {
2364
- if (!this.relayPtyProcess || !this.relayPtyProcess.stdin) {
2365
- throw new Error('Process not running');
2366
- }
2367
- const buffer = typeof data === 'string' ? Buffer.from(data) : data;
2368
- this.relayPtyProcess.stdin.write(buffer);
2369
- }
2370
- /**
2371
- * Verify that the CLI shows activity after task injection.
2372
- * Checks output for patterns indicating the task was received and processing started.
2373
- *
2374
- * This catches the race condition where PTY write succeeds but CLI wasn't ready
2375
- * (the T-003 failure scenario where CLI showed bell characters instead of processing).
2376
- *
2377
- * @param outputBefore The output buffer content before injection
2378
- * @returns Promise resolving to true if activity detected, false otherwise
2379
- */
2380
- async verifyActivityAfterInjection(outputBefore) {
2381
- const startTime = Date.now();
2382
- const { TIMEOUT_MS, POLL_INTERVAL_MS, TASK_RECEIVED_PATTERNS, THINKING_PATTERNS, TOOL_EXECUTION_PATTERNS } = ACTIVITY_VERIFICATION;
2383
- const trimCountBefore = this.bufferTrimCount;
2384
- while (Date.now() - startTime < TIMEOUT_MS) {
2385
- // If buffers were trimmed during verification, treat it as activity.
2386
- // Large output growth triggers trimming, which would otherwise make slice() return
2387
- // an empty string and falsely signal no activity.
2388
- if (this.bufferTrimCount !== trimCountBefore) {
2389
- this.log(` Activity verified: output buffer trimmed during verification (large output)`);
2390
- return true;
2391
- }
2392
- // Get new output since injection
2393
- const currentOutput = this.outputBuffer;
2394
- const newOutput = currentOutput.slice(outputBefore.length);
2395
- if (newOutput.length > 0) {
2396
- // REJECTION CHECK: Multiple BEL characters (0x07) indicate CLI rejected input
2397
- // The T-003 failure showed CLI producing 1000+ BELs when input was injected
2398
- // while the CLI wasn't ready (still initializing or in wrong mode)
2399
- const belCount = (newOutput.match(/\x07/g) || []).length;
2400
- if (belCount > 10) {
2401
- this.logError(` Input rejected: CLI produced ${belCount} BEL characters`);
2402
- return false; // Don't wait - immediately fail so retry can attempt
2403
- }
2404
- // Check for task received patterns (primary verification)
2405
- for (const pattern of TASK_RECEIVED_PATTERNS) {
2406
- if (pattern.test(newOutput)) {
2407
- this.log(` Activity verified: task received pattern matched`);
2408
- return true;
2409
- }
2410
- }
2411
- // Check for thinking/processing patterns (secondary verification)
2412
- for (const pattern of THINKING_PATTERNS) {
2413
- if (pattern.test(newOutput)) {
2414
- this.log(` Activity verified: thinking pattern matched`);
2415
- return true;
2416
- }
2417
- }
2418
- // Check for tool execution patterns (tertiary verification)
2419
- for (const pattern of TOOL_EXECUTION_PATTERNS) {
2420
- if (pattern.test(newOutput)) {
2421
- this.log(` Activity verified: tool execution pattern matched`);
2422
- return true;
2423
- }
2424
- }
2425
- // Fallback: If output grew significantly (>100 meaningful chars), assume activity
2426
- // This catches CLIs with unusual output patterns
2427
- // IMPORTANT: Strip out BEL (0x07) and other control characters - these are rejection
2428
- // signals not activity. The T-003 failure showed CLI producing 1000+ BELs when input
2429
- // was injected before it was ready.
2430
- const meaningfulOutput = newOutput.replace(/[\x00-\x1f]/g, ''); // Strip control chars
2431
- if (meaningfulOutput.length > 100) {
2432
- this.log(` Activity verified: significant output growth (${meaningfulOutput.length} meaningful chars)`);
2433
- return true;
2434
- }
2435
- }
2436
- await sleep(POLL_INTERVAL_MS);
2437
- }
2438
- // No activity detected within timeout
2439
- this.log(` No activity detected within ${TIMEOUT_MS}ms`);
2440
- return false;
2441
- }
2442
- /**
2443
- * Inject a task using the socket-based injection system with activity verification.
2444
- * This is the preferred method for spawned agent task delivery.
2445
- *
2446
- * After socket confirms delivery, verifies the CLI shows activity (task received,
2447
- * thinking indicators, or tool execution). Retries if no activity is detected.
2448
- *
2449
- * @param task The task text to inject
2450
- * @param from The sender name (default: "spawner")
2451
- * @returns Promise resolving to true if task was delivered AND activity verified, false otherwise
2452
- */
2453
- async injectTask(task, from = 'spawner') {
2454
- const { MAX_RETRIES, RETRY_DELAY_MS } = ACTIVITY_VERIFICATION;
2455
- // Claude Code's TUI needs a stabilization delay after displaying the welcome screen
2456
- // before it's ready to accept stdin input. Without this, input may be silently dropped
2457
- // even though the CLI appears "idle" and doesn't reject with BELs.
2458
- // 1500ms is based on observed behavior - Claude Code typically needs 1-1.5s after
2459
- // its TUI renders before input handlers are fully initialized.
2460
- const STABILIZATION_DELAY_MS = 1500;
2461
- this.log(` Waiting ${STABILIZATION_DELAY_MS}ms for CLI stabilization before task injection`);
2462
- await sleep(STABILIZATION_DELAY_MS);
2463
- for (let attempt = 0; attempt <= MAX_RETRIES; attempt++) {
2464
- if (attempt > 0) {
2465
- this.log(` Retry ${attempt}/${MAX_RETRIES} - waiting ${RETRY_DELAY_MS}ms before retry`);
2466
- await sleep(RETRY_DELAY_MS);
2467
- }
2468
- // Capture output buffer state before injection
2469
- const outputBefore = this.outputBuffer;
2470
- // Attempt delivery via socket
2471
- const delivered = await this.performTaskInjection(task, from);
2472
- if (!delivered) {
2473
- this.logError(` Task delivery failed on attempt ${attempt + 1}`);
2474
- continue; // Retry
2475
- }
2476
- // Verify CLI shows activity (task received, thinking, or tool execution)
2477
- const activityVerified = await this.verifyActivityAfterInjection(outputBefore);
2478
- if (activityVerified) {
2479
- this.log(` Task delivered and activity verified successfully`);
2480
- return true;
2481
- }
2482
- // Delivery succeeded but no activity - CLI might not have been ready
2483
- this.logError(` Task delivered but no activity detected (attempt ${attempt + 1})`);
2484
- }
2485
- this.logError(` Task injection failed after ${MAX_RETRIES + 1} attempts - no CLI activity detected`);
2486
- return false;
2487
- }
2488
- /**
2489
- * Perform a single task injection attempt (without retry logic).
2490
- * @returns true if the injection was sent successfully, false otherwise
2491
- */
2492
- async performTaskInjection(task, from) {
2493
- if (!this.socket || !this.socketConnected) {
2494
- this.log(` Socket not connected for task injection, falling back to stdin write`);
2495
- try {
2496
- await this.write(task + '\n');
2497
- return true;
2498
- }
2499
- catch (err) {
2500
- this.logError(` Stdin write fallback failed: ${err.message}`);
2501
- return false;
2502
- }
2503
- }
2504
- const messageId = `task-${Date.now()}-${Math.random().toString(36).substring(2, 8)}`;
2505
- const shortId = messageId.substring(0, 8);
2506
- this.log(` Injecting task via socket: ${shortId}`);
2507
- // Create request
2508
- const request = {
2509
- type: 'inject',
2510
- id: messageId,
2511
- from,
2512
- body: task,
2513
- priority: 0, // High priority for initial task
2514
- };
2515
- // Send with timeout and get socket confirmation
2516
- return new Promise((resolve) => {
2517
- const timeout = setTimeout(() => {
2518
- this.logError(` Task inject timeout for ${shortId} after 30s`);
2519
- this.pendingInjections.delete(messageId);
2520
- resolve(false);
2521
- }, 30000);
2522
- this.pendingInjections.set(messageId, {
2523
- resolve,
2524
- reject: () => resolve(false),
2525
- timeout,
2526
- from,
2527
- shortId,
2528
- retryCount: 0,
2529
- originalBody: task,
2530
- });
2531
- this.sendSocketRequest(request)
2532
- .then(() => {
2533
- this.log(` Task inject request sent: ${shortId}`);
2534
- })
2535
- .catch((err) => {
2536
- this.logError(` Task inject socket request failed: ${err.message}`);
2537
- clearTimeout(timeout);
2538
- this.pendingInjections.delete(messageId);
2539
- resolve(false);
2540
- });
2541
- });
2542
- }
2543
- /**
2544
- * Get the agent ID (from continuity if available)
2545
- */
2546
- getAgentId() {
2547
- return this.agentId;
2548
- }
2549
- }
2550
- //# sourceMappingURL=relay-pty-orchestrator.js.map