agent-relay 1.3.2 → 1.5.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 (318) hide show
  1. package/README.md +130 -158
  2. package/bin/relay-pty +0 -0
  3. package/bin/relay-pty-darwin-arm64 +0 -0
  4. package/bin/relay-pty-darwin-x64 +0 -0
  5. package/bin/relay-pty-linux-x64 +0 -0
  6. package/deploy/workspace/entrypoint.sh +9 -0
  7. package/dist/bridge/spawner.d.ts +4 -4
  8. package/dist/bridge/spawner.js +58 -92
  9. package/dist/cli/index.d.ts +8 -6
  10. package/dist/cli/index.js +282 -47
  11. package/dist/cloud/api/daemons.js +13 -32
  12. package/dist/cloud/api/onboarding.js +2 -4
  13. package/dist/cloud/api/providers.js +6 -0
  14. package/dist/cloud/config.d.ts +1 -0
  15. package/dist/cloud/config.js +2 -0
  16. package/dist/cloud/db/bulk-ingest.d.ts +2 -1
  17. package/dist/cloud/db/drizzle.d.ts +21 -26
  18. package/dist/cloud/db/drizzle.js +87 -100
  19. package/dist/cloud/db/index.d.ts +6 -5
  20. package/dist/cloud/db/index.js +9 -8
  21. package/dist/cloud/db/schema.d.ts +1049 -1076
  22. package/dist/cloud/db/schema.js +59 -71
  23. package/dist/cloud/server.js +854 -18
  24. package/dist/cloud/services/persistence.d.ts +15 -15
  25. package/dist/cloud/services/persistence.js +14 -14
  26. package/dist/daemon/agent-manager.d.ts +6 -5
  27. package/dist/daemon/agent-manager.js +12 -8
  28. package/dist/daemon/channel-membership-store.d.ts +48 -0
  29. package/dist/daemon/channel-membership-store.js +149 -0
  30. package/dist/daemon/cloud-sync.d.ts +2 -0
  31. package/dist/daemon/cloud-sync.js +4 -0
  32. package/dist/daemon/connection.js +17 -9
  33. package/dist/daemon/router.d.ts +37 -0
  34. package/dist/daemon/router.js +318 -79
  35. package/dist/daemon/server.d.ts +15 -0
  36. package/dist/daemon/server.js +141 -3
  37. package/dist/dashboard/out/404.html +1 -0
  38. package/dist/dashboard/out/_next/static/IxxVRv94L1w3ReRGAiI-k/_buildManifest.js +1 -0
  39. package/dist/dashboard/out/_next/static/IxxVRv94L1w3ReRGAiI-k/_ssgManifest.js +1 -0
  40. package/dist/dashboard/out/_next/static/chunks/116-eacf84a131b80db9.js +1 -0
  41. package/dist/dashboard/out/_next/static/chunks/117-c8afed19e821a35d.js +2 -0
  42. package/dist/dashboard/out/_next/static/chunks/282-980c2eb8fff20123.js +1 -0
  43. package/dist/dashboard/out/_next/static/chunks/532-bace199897eeab37.js +9 -0
  44. package/dist/dashboard/out/_next/static/chunks/64-87ab9cd6bcf2f737.js +1 -0
  45. package/dist/dashboard/out/_next/static/chunks/648-acb2ff9f77cbfbd3.js +1 -0
  46. package/dist/dashboard/out/_next/static/chunks/766-aa7c8c9900ff5f53.js +1 -0
  47. package/dist/dashboard/out/_next/static/chunks/83-4f08122d4e7e79a6.js +1 -0
  48. package/dist/dashboard/out/_next/static/chunks/847-f1f467060f32afff.js +1 -0
  49. package/dist/dashboard/out/_next/static/chunks/891-a024fbe4b619cf6f.js +1 -0
  50. package/dist/dashboard/out/_next/static/chunks/app/_not-found/page-60501fddbafba9dc.js +1 -0
  51. package/dist/dashboard/out/_next/static/chunks/app/app/onboarding/page-f746f29e01fffc43.js +1 -0
  52. package/dist/dashboard/out/_next/static/chunks/app/app/page-ffad986adfcc8b31.js +1 -0
  53. package/dist/dashboard/out/_next/static/chunks/app/cloud/link/page-cfeb437f08a12ed9.js +1 -0
  54. package/dist/dashboard/out/_next/static/chunks/app/connect-repos/page-03ac6f35a6654ea6.js +1 -0
  55. package/dist/dashboard/out/_next/static/chunks/app/history/page-240f91e8b06ba8ac.js +1 -0
  56. package/dist/dashboard/out/_next/static/chunks/app/layout-c0d118c0f92d969c.js +1 -0
  57. package/dist/dashboard/out/_next/static/chunks/app/login/page-6ec54eee75877971.js +1 -0
  58. package/dist/dashboard/out/_next/static/chunks/app/metrics/page-82938ab8fcf44694.js +1 -0
  59. package/dist/dashboard/out/_next/static/chunks/app/page-671037943b2f2e43.js +1 -0
  60. package/dist/dashboard/out/_next/static/chunks/app/pricing/page-0efa024c28ba4597.js +1 -0
  61. package/dist/dashboard/out/_next/static/chunks/app/providers/page-57cbd738c6a73859.js +1 -0
  62. package/dist/dashboard/out/_next/static/chunks/app/providers/setup/[provider]/page-5ab0854472b402b0.js +1 -0
  63. package/dist/dashboard/out/_next/static/chunks/app/signup/page-18a4665665f6be11.js +1 -0
  64. package/dist/dashboard/out/_next/static/chunks/e868780c-48e5f147c90a3a41.js +18 -0
  65. package/dist/dashboard/out/_next/static/chunks/fd9d1056-609918ca7b6280bb.js +1 -0
  66. package/dist/dashboard/out/_next/static/chunks/framework-f66176bb897dc684.js +1 -0
  67. package/dist/dashboard/out/_next/static/chunks/main-5a40a5ae29646e1b.js +1 -0
  68. package/dist/dashboard/out/_next/static/chunks/main-app-6e8e8d3ef4e0192a.js +1 -0
  69. package/dist/dashboard/out/_next/static/chunks/pages/_app-72b849fbd24ac258.js +1 -0
  70. package/dist/dashboard/out/_next/static/chunks/pages/_error-7ba65e1336b92748.js +1 -0
  71. package/dist/dashboard/out/_next/static/chunks/polyfills-42372ed130431b0a.js +1 -0
  72. package/dist/dashboard/out/_next/static/chunks/webpack-1cdd8ed57114d5e1.js +1 -0
  73. package/dist/dashboard/out/_next/static/css/4034f236dd1a3178.css +1 -0
  74. package/dist/dashboard/out/_next/static/css/8f9ed310f454e5a5.css +1 -0
  75. package/dist/dashboard/out/alt-logos/agent-relay-logo-128.png +0 -0
  76. package/dist/dashboard/out/alt-logos/agent-relay-logo-256.png +0 -0
  77. package/dist/dashboard/out/alt-logos/agent-relay-logo-32.png +0 -0
  78. package/dist/dashboard/out/alt-logos/agent-relay-logo-512.png +0 -0
  79. package/dist/dashboard/out/alt-logos/agent-relay-logo-64.png +0 -0
  80. package/dist/dashboard/out/alt-logos/agent-relay-logo.svg +45 -0
  81. package/dist/dashboard/out/alt-logos/logo.svg +38 -0
  82. package/dist/dashboard/out/alt-logos/monogram-logo-128.png +0 -0
  83. package/dist/dashboard/out/alt-logos/monogram-logo-256.png +0 -0
  84. package/dist/dashboard/out/alt-logos/monogram-logo-32.png +0 -0
  85. package/dist/dashboard/out/alt-logos/monogram-logo-512.png +0 -0
  86. package/dist/dashboard/out/alt-logos/monogram-logo-64.png +0 -0
  87. package/dist/dashboard/out/alt-logos/monogram-logo.svg +38 -0
  88. package/dist/dashboard/out/app/onboarding.html +1 -0
  89. package/dist/dashboard/out/app/onboarding.txt +7 -0
  90. package/dist/dashboard/out/app.html +1 -0
  91. package/dist/dashboard/out/app.txt +7 -0
  92. package/dist/dashboard/out/apple-icon.png +0 -0
  93. package/dist/dashboard/out/cloud/link.html +1 -0
  94. package/dist/dashboard/out/cloud/link.txt +7 -0
  95. package/dist/dashboard/out/connect-repos.html +1 -0
  96. package/dist/dashboard/out/connect-repos.txt +7 -0
  97. package/dist/dashboard/out/history.html +1 -0
  98. package/dist/dashboard/out/history.txt +7 -0
  99. package/dist/dashboard/out/index.html +1 -0
  100. package/dist/dashboard/out/index.txt +7 -0
  101. package/dist/dashboard/out/login.html +5 -0
  102. package/dist/dashboard/out/login.txt +7 -0
  103. package/dist/dashboard/out/metrics.html +1 -0
  104. package/dist/dashboard/out/metrics.txt +7 -0
  105. package/dist/dashboard/out/pricing.html +13 -0
  106. package/dist/dashboard/out/pricing.txt +7 -0
  107. package/dist/dashboard/out/providers/setup/claude.html +1 -0
  108. package/dist/dashboard/out/providers/setup/claude.txt +8 -0
  109. package/dist/dashboard/out/providers/setup/codex.html +1 -0
  110. package/dist/dashboard/out/providers/setup/codex.txt +8 -0
  111. package/dist/dashboard/out/providers.html +1 -0
  112. package/dist/dashboard/out/providers.txt +7 -0
  113. package/dist/dashboard/out/signup.html +6 -0
  114. package/dist/dashboard/out/signup.txt +7 -0
  115. package/dist/dashboard-server/metrics.d.ts +105 -0
  116. package/dist/dashboard-server/metrics.js +193 -0
  117. package/dist/dashboard-server/needs-attention.d.ts +24 -0
  118. package/dist/dashboard-server/needs-attention.js +78 -0
  119. package/dist/dashboard-server/server.d.ts +15 -0
  120. package/dist/dashboard-server/server.js +4753 -0
  121. package/dist/dashboard-server/start.d.ts +6 -0
  122. package/dist/dashboard-server/start.js +13 -0
  123. package/dist/dashboard-server/user-bridge.d.ts +132 -0
  124. package/dist/dashboard-server/user-bridge.js +317 -0
  125. package/dist/protocol/channels.d.ts +14 -8
  126. package/dist/protocol/channels.js +1 -1
  127. package/dist/protocol/index.d.ts +1 -0
  128. package/dist/protocol/index.js +1 -0
  129. package/dist/protocol/relay-pty-schemas.d.ts +209 -0
  130. package/dist/protocol/relay-pty-schemas.js +60 -0
  131. package/dist/wrapper/auth-detection.js +8 -1
  132. package/dist/wrapper/base-wrapper.d.ts +11 -1
  133. package/dist/wrapper/base-wrapper.js +67 -6
  134. package/dist/wrapper/client.d.ts +49 -1
  135. package/dist/wrapper/client.js +167 -0
  136. package/dist/wrapper/parser.d.ts +0 -4
  137. package/dist/wrapper/parser.js +38 -10
  138. package/dist/wrapper/pty-wrapper.d.ts +12 -1
  139. package/dist/wrapper/pty-wrapper.js +104 -5
  140. package/dist/wrapper/relay-pty-orchestrator.d.ts +270 -0
  141. package/dist/wrapper/relay-pty-orchestrator.js +970 -0
  142. package/dist/wrapper/shared.d.ts +1 -1
  143. package/dist/wrapper/shared.js +14 -4
  144. package/dist/wrapper/tmux-wrapper.d.ts +13 -1
  145. package/dist/wrapper/tmux-wrapper.js +143 -29
  146. package/package.json +9 -4
  147. package/scripts/postinstall.js +101 -11
  148. package/.trajectories/active/traj_3yx9dy148mge.json +0 -42
  149. package/.trajectories/agent-relay-322-324.md +0 -17
  150. package/.trajectories/completed/2026-01/traj_03zupyv1s7b9.json +0 -49
  151. package/.trajectories/completed/2026-01/traj_03zupyv1s7b9.md +0 -31
  152. package/.trajectories/completed/2026-01/traj_0zacdjl1g4ht.json +0 -125
  153. package/.trajectories/completed/2026-01/traj_0zacdjl1g4ht.md +0 -62
  154. package/.trajectories/completed/2026-01/traj_1dviorhnkcb5.json +0 -65
  155. package/.trajectories/completed/2026-01/traj_1dviorhnkcb5.md +0 -37
  156. package/.trajectories/completed/2026-01/traj_1g7yx6qtg4ai.json +0 -49
  157. package/.trajectories/completed/2026-01/traj_1g7yx6qtg4ai.md +0 -31
  158. package/.trajectories/completed/2026-01/traj_1k5if5snst2e.json +0 -65
  159. package/.trajectories/completed/2026-01/traj_1k5if5snst2e.md +0 -37
  160. package/.trajectories/completed/2026-01/traj_1rp3rges5811.json +0 -49
  161. package/.trajectories/completed/2026-01/traj_1rp3rges5811.md +0 -31
  162. package/.trajectories/completed/2026-01/traj_22bhyulruouw.json +0 -113
  163. package/.trajectories/completed/2026-01/traj_22bhyulruouw.md +0 -57
  164. package/.trajectories/completed/2026-01/traj_2dao7ddgnta0.json +0 -53
  165. package/.trajectories/completed/2026-01/traj_2dao7ddgnta0.md +0 -32
  166. package/.trajectories/completed/2026-01/traj_33iuy72sezbk.json +0 -49
  167. package/.trajectories/completed/2026-01/traj_33iuy72sezbk.md +0 -31
  168. package/.trajectories/completed/2026-01/traj_3t0440mjeunc.json +0 -26
  169. package/.trajectories/completed/2026-01/traj_3t0440mjeunc.md +0 -6
  170. package/.trajectories/completed/2026-01/traj_45x9494d9xnr.json +0 -47
  171. package/.trajectories/completed/2026-01/traj_45x9494d9xnr.md +0 -32
  172. package/.trajectories/completed/2026-01/traj_4aa0bb77s4nh.json +0 -53
  173. package/.trajectories/completed/2026-01/traj_4aa0bb77s4nh.md +0 -32
  174. package/.trajectories/completed/2026-01/traj_4qwd4zmhfwp4.json +0 -49
  175. package/.trajectories/completed/2026-01/traj_4qwd4zmhfwp4.md +0 -31
  176. package/.trajectories/completed/2026-01/traj_5ammh5qtvklq.json +0 -77
  177. package/.trajectories/completed/2026-01/traj_5ammh5qtvklq.md +0 -42
  178. package/.trajectories/completed/2026-01/traj_5lhmzq8rxpqv.json +0 -59
  179. package/.trajectories/completed/2026-01/traj_5lhmzq8rxpqv.md +0 -33
  180. package/.trajectories/completed/2026-01/traj_5vr4e9erb1fs.json +0 -53
  181. package/.trajectories/completed/2026-01/traj_5vr4e9erb1fs.md +0 -32
  182. package/.trajectories/completed/2026-01/traj_6fgiwdoklvym.json +0 -48
  183. package/.trajectories/completed/2026-01/traj_6fgiwdoklvym.md +0 -24
  184. package/.trajectories/completed/2026-01/traj_6mieijqyvaag.json +0 -77
  185. package/.trajectories/completed/2026-01/traj_6mieijqyvaag.md +0 -42
  186. package/.trajectories/completed/2026-01/traj_6unwwmgyj5sq.json +0 -109
  187. package/.trajectories/completed/2026-01/traj_78ffm31jn3uk.json +0 -77
  188. package/.trajectories/completed/2026-01/traj_78ffm31jn3uk.md +0 -42
  189. package/.trajectories/completed/2026-01/traj_7ludwvz45veh.json +0 -209
  190. package/.trajectories/completed/2026-01/traj_7ludwvz45veh.md +0 -97
  191. package/.trajectories/completed/2026-01/traj_94gnp3k30goq.json +0 -66
  192. package/.trajectories/completed/2026-01/traj_94gnp3k30goq.md +0 -36
  193. package/.trajectories/completed/2026-01/traj_9921cuhel0pj.json +0 -48
  194. package/.trajectories/completed/2026-01/traj_9921cuhel0pj.md +0 -24
  195. package/.trajectories/completed/2026-01/traj_a0tqx8biw9c4.json +0 -49
  196. package/.trajectories/completed/2026-01/traj_a0tqx8biw9c4.md +0 -31
  197. package/.trajectories/completed/2026-01/traj_ajs7zqfux4wc.json +0 -49
  198. package/.trajectories/completed/2026-01/traj_ajs7zqfux4wc.md +0 -23
  199. package/.trajectories/completed/2026-01/traj_avqeghu6pz5a.json +0 -40
  200. package/.trajectories/completed/2026-01/traj_avqeghu6pz5a.md +0 -22
  201. package/.trajectories/completed/2026-01/traj_ax8uungxz2qh.json +0 -66
  202. package/.trajectories/completed/2026-01/traj_ax8uungxz2qh.md +0 -36
  203. package/.trajectories/completed/2026-01/traj_c9izbh2snpzf.json +0 -49
  204. package/.trajectories/completed/2026-01/traj_c9izbh2snpzf.md +0 -31
  205. package/.trajectories/completed/2026-01/traj_cpn70dw066nt.json +0 -65
  206. package/.trajectories/completed/2026-01/traj_cpn70dw066nt.md +0 -37
  207. package/.trajectories/completed/2026-01/traj_cvtqhlwcq9s0.json +0 -53
  208. package/.trajectories/completed/2026-01/traj_cvtqhlwcq9s0.md +0 -32
  209. package/.trajectories/completed/2026-01/traj_cxofprm2m2en.json +0 -49
  210. package/.trajectories/completed/2026-01/traj_cxofprm2m2en.md +0 -31
  211. package/.trajectories/completed/2026-01/traj_d2hhz3k0vrhn.json +0 -26
  212. package/.trajectories/completed/2026-01/traj_d2hhz3k0vrhn.md +0 -6
  213. package/.trajectories/completed/2026-01/traj_dcsp9s8y01ra.json +0 -121
  214. package/.trajectories/completed/2026-01/traj_dcsp9s8y01ra.md +0 -29
  215. package/.trajectories/completed/2026-01/traj_dfuvww9pege5.json +0 -59
  216. package/.trajectories/completed/2026-01/traj_dfuvww9pege5.md +0 -37
  217. package/.trajectories/completed/2026-01/traj_erglv2f8t9eh.json +0 -36
  218. package/.trajectories/completed/2026-01/traj_erglv2f8t9eh.md +0 -21
  219. package/.trajectories/completed/2026-01/traj_fhx9irlckht6.json +0 -53
  220. package/.trajectories/completed/2026-01/traj_fhx9irlckht6.md +0 -32
  221. package/.trajectories/completed/2026-01/traj_fqduidx3xbtp.json +0 -101
  222. package/.trajectories/completed/2026-01/traj_fqduidx3xbtp.md +0 -52
  223. package/.trajectories/completed/2026-01/traj_g0fisy9h51mf.json +0 -77
  224. package/.trajectories/completed/2026-01/traj_g0fisy9h51mf.md +0 -42
  225. package/.trajectories/completed/2026-01/traj_gjdre5voouod.json +0 -53
  226. package/.trajectories/completed/2026-01/traj_gjdre5voouod.md +0 -32
  227. package/.trajectories/completed/2026-01/traj_gtlyqtta3x8l.json +0 -25
  228. package/.trajectories/completed/2026-01/traj_gtlyqtta3x8l.md +0 -15
  229. package/.trajectories/completed/2026-01/traj_h4xijiuip3w4.json +0 -101
  230. package/.trajectories/completed/2026-01/traj_h4xijiuip3w4.md +0 -44
  231. package/.trajectories/completed/2026-01/traj_he75f24d1xfm.json +0 -101
  232. package/.trajectories/completed/2026-01/traj_he75f24d1xfm.md +0 -52
  233. package/.trajectories/completed/2026-01/traj_hf81ey93uz6t.json +0 -49
  234. package/.trajectories/completed/2026-01/traj_hf81ey93uz6t.md +0 -31
  235. package/.trajectories/completed/2026-01/traj_hfmki2jr9d4r.json +0 -65
  236. package/.trajectories/completed/2026-01/traj_hfmki2jr9d4r.md +0 -37
  237. package/.trajectories/completed/2026-01/traj_hhxte7w4gjjx.json +0 -22
  238. package/.trajectories/completed/2026-01/traj_hhxte7w4gjjx.md +0 -5
  239. package/.trajectories/completed/2026-01/traj_hpungyhoj6v5.json +0 -53
  240. package/.trajectories/completed/2026-01/traj_hpungyhoj6v5.md +0 -32
  241. package/.trajectories/completed/2026-01/traj_lgtodco7dp1n.json +0 -61
  242. package/.trajectories/completed/2026-01/traj_lgtodco7dp1n.md +0 -36
  243. package/.trajectories/completed/2026-01/traj_lq450ly148uw.json +0 -49
  244. package/.trajectories/completed/2026-01/traj_lq450ly148uw.md +0 -31
  245. package/.trajectories/completed/2026-01/traj_m2xkjv0w2sq7.json +0 -25
  246. package/.trajectories/completed/2026-01/traj_m2xkjv0w2sq7.md +0 -15
  247. package/.trajectories/completed/2026-01/traj_multi_server_arch.md +0 -101
  248. package/.trajectories/completed/2026-01/traj_noq5zbvnrdvz.json +0 -53
  249. package/.trajectories/completed/2026-01/traj_noq5zbvnrdvz.md +0 -32
  250. package/.trajectories/completed/2026-01/traj_ntbs6ppopf46.json +0 -53
  251. package/.trajectories/completed/2026-01/traj_ntbs6ppopf46.md +0 -32
  252. package/.trajectories/completed/2026-01/traj_oszg9flv74pk.json +0 -73
  253. package/.trajectories/completed/2026-01/traj_oszg9flv74pk.md +0 -41
  254. package/.trajectories/completed/2026-01/traj_ozd98si6a7ns.json +0 -48
  255. package/.trajectories/completed/2026-01/traj_ozd98si6a7ns.md +0 -24
  256. package/.trajectories/completed/2026-01/traj_prdza7a5cxp5.json +0 -53
  257. package/.trajectories/completed/2026-01/traj_prdza7a5cxp5.md +0 -32
  258. package/.trajectories/completed/2026-01/traj_psd9ob0j2ru3.json +0 -27
  259. package/.trajectories/completed/2026-01/traj_psd9ob0j2ru3.md +0 -14
  260. package/.trajectories/completed/2026-01/traj_pulomd3y8cvj.json +0 -77
  261. package/.trajectories/completed/2026-01/traj_pulomd3y8cvj.md +0 -42
  262. package/.trajectories/completed/2026-01/traj_qb3twvvywfwi.json +0 -77
  263. package/.trajectories/completed/2026-01/traj_qb3twvvywfwi.md +0 -42
  264. package/.trajectories/completed/2026-01/traj_qft54mi7nfor.json +0 -53
  265. package/.trajectories/completed/2026-01/traj_qft54mi7nfor.md +0 -32
  266. package/.trajectories/completed/2026-01/traj_qx9uhf8whhxo.json +0 -83
  267. package/.trajectories/completed/2026-01/traj_qx9uhf8whhxo.md +0 -47
  268. package/.trajectories/completed/2026-01/traj_rd9toccj18a0.json +0 -59
  269. package/.trajectories/completed/2026-01/traj_rd9toccj18a0.md +0 -37
  270. package/.trajectories/completed/2026-01/traj_rsavt0jipi3c.json +0 -109
  271. package/.trajectories/completed/2026-01/traj_rsavt0jipi3c.md +0 -56
  272. package/.trajectories/completed/2026-01/traj_rt4fiw3ecp50.json +0 -48
  273. package/.trajectories/completed/2026-01/traj_rt4fiw3ecp50.md +0 -16
  274. package/.trajectories/completed/2026-01/traj_st8j35b0hrlc.json +0 -59
  275. package/.trajectories/completed/2026-01/traj_st8j35b0hrlc.md +0 -37
  276. package/.trajectories/completed/2026-01/traj_t1yy8m7hbuxp.json +0 -53
  277. package/.trajectories/completed/2026-01/traj_t1yy8m7hbuxp.md +0 -32
  278. package/.trajectories/completed/2026-01/traj_tmux_orchestrator_analysis.json +0 -84
  279. package/.trajectories/completed/2026-01/traj_tmux_orchestrator_analysis.md +0 -109
  280. package/.trajectories/completed/2026-01/traj_u9n9eqasw16k.json +0 -53
  281. package/.trajectories/completed/2026-01/traj_u9n9eqasw16k.md +0 -32
  282. package/.trajectories/completed/2026-01/traj_ub8csuv3lcv4.json +0 -53
  283. package/.trajectories/completed/2026-01/traj_ub8csuv3lcv4.md +0 -32
  284. package/.trajectories/completed/2026-01/traj_uc29tlso8i9s.json +0 -186
  285. package/.trajectories/completed/2026-01/traj_uc29tlso8i9s.md +0 -86
  286. package/.trajectories/completed/2026-01/traj_ui9b4tqxoa7j.json +0 -77
  287. package/.trajectories/completed/2026-01/traj_ui9b4tqxoa7j.md +0 -42
  288. package/.trajectories/completed/2026-01/traj_v87hypnongqx.json +0 -71
  289. package/.trajectories/completed/2026-01/traj_v87hypnongqx.md +0 -42
  290. package/.trajectories/completed/2026-01/traj_v9dkdoxylyid.json +0 -89
  291. package/.trajectories/completed/2026-01/traj_v9dkdoxylyid.md +0 -47
  292. package/.trajectories/completed/2026-01/traj_wkp2fgzdyinb.json +0 -53
  293. package/.trajectories/completed/2026-01/traj_wkp2fgzdyinb.md +0 -32
  294. package/.trajectories/completed/2026-01/traj_x14t8w8rn7xg.json +0 -20
  295. package/.trajectories/completed/2026-01/traj_x14t8w8rn7xg.md +0 -6
  296. package/.trajectories/completed/2026-01/traj_x721m1j9rzup.json +0 -113
  297. package/.trajectories/completed/2026-01/traj_x721m1j9rzup.md +0 -57
  298. package/.trajectories/completed/2026-01/traj_xjqvmep5ed3h.json +0 -61
  299. package/.trajectories/completed/2026-01/traj_xjqvmep5ed3h.md +0 -36
  300. package/.trajectories/completed/2026-01/traj_xnwbznkvv8ua.json +0 -175
  301. package/.trajectories/completed/2026-01/traj_xnwbznkvv8ua.md +0 -82
  302. package/.trajectories/completed/2026-01/traj_xy9vifpqet80.json +0 -65
  303. package/.trajectories/completed/2026-01/traj_xy9vifpqet80.md +0 -37
  304. package/.trajectories/completed/2026-01/traj_y7aiwijyfmmv.json +0 -49
  305. package/.trajectories/completed/2026-01/traj_y7aiwijyfmmv.md +0 -31
  306. package/.trajectories/completed/2026-01/traj_y7n6hfbf7dmg.json +0 -49
  307. package/.trajectories/completed/2026-01/traj_y7n6hfbf7dmg.md +0 -31
  308. package/.trajectories/completed/2026-01/traj_ysjc8zaeqtd3.json +0 -47
  309. package/.trajectories/completed/2026-01/traj_ysjc8zaeqtd3.md +0 -32
  310. package/.trajectories/completed/2026-01/traj_yvdadtvdgnz3.json +0 -59
  311. package/.trajectories/completed/2026-01/traj_yvdadtvdgnz3.md +0 -37
  312. package/.trajectories/completed/2026-01/traj_yvfkwnkdiso2.json +0 -49
  313. package/.trajectories/completed/2026-01/traj_yvfkwnkdiso2.md +0 -31
  314. package/.trajectories/completed/2026-01/traj_z0vcw1wrzide.json +0 -53
  315. package/.trajectories/completed/2026-01/traj_z0vcw1wrzide.md +0 -32
  316. package/.trajectories/consolidate-settings-panel.md +0 -24
  317. package/.trajectories/gh-cli-user-token.md +0 -26
  318. package/.trajectories/index.json +0 -607
@@ -0,0 +1,209 @@
1
+ /**
2
+ * Relay PTY Protocol Schemas
3
+ *
4
+ * This file documents the data formats used in the relay-pty message flow:
5
+ *
6
+ * 1. Agent → File (outbox) : RelayFileFormat
7
+ * 2. relay-pty → Orchestrator : ParsedRelayCommand (JSON on stderr)
8
+ * 3. Orchestrator → Socket : InjectRequest (JSON)
9
+ * 4. Socket → Agent PTY : Plain text injection
10
+ */
11
+ /**
12
+ * File format that agents write to /tmp/relay-outbox/$AGENT_RELAY_NAME/<filename>
13
+ *
14
+ * Header-based format (preferred over JSON):
15
+ * - Headers are key: value pairs, one per line
16
+ * - Blank line separates headers from body
17
+ * - Body is free-form text (no escaping needed)
18
+ *
19
+ * @example Message
20
+ * ```
21
+ * TO: Bob
22
+ * THREAD: feature-123
23
+ *
24
+ * Hello Bob, can you review PR #42?
25
+ * ```
26
+ *
27
+ * @example Spawn
28
+ * ```
29
+ * KIND: spawn
30
+ * NAME: ReviewerAgent
31
+ * CLI: claude
32
+ *
33
+ * You are a code reviewer.
34
+ * Review the changes in src/auth/*.ts
35
+ * ```
36
+ *
37
+ * @example Release
38
+ * ```
39
+ * KIND: release
40
+ * NAME: ReviewerAgent
41
+ * ```
42
+ */
43
+ export interface RelayFileFormat {
44
+ /** Target agent name, "*" for broadcast, or "#channel" */
45
+ TO?: string;
46
+ /** Message type: "message" (default), "spawn", or "release" */
47
+ KIND?: 'message' | 'spawn' | 'release';
48
+ /** Agent name (required for spawn/release) */
49
+ NAME?: string;
50
+ /** CLI to use for spawning (required for spawn) */
51
+ CLI?: string;
52
+ /** Thread identifier for grouping related messages */
53
+ THREAD?: string;
54
+ /** Message content or task description (for spawn) */
55
+ body?: string;
56
+ }
57
+ /**
58
+ * JSON format emitted by relay-pty to stderr when it detects a relay command.
59
+ * The orchestrator parses this to route messages.
60
+ *
61
+ * @example
62
+ * ```json
63
+ * {
64
+ * "type": "relay_command",
65
+ * "kind": "message",
66
+ * "from": "Alice",
67
+ * "to": "Bob",
68
+ * "body": "Hello!",
69
+ * "raw": "->relay-file:msg-001"
70
+ * }
71
+ * ```
72
+ */
73
+ export interface ParsedRelayCommand {
74
+ /** Always "relay_command" */
75
+ type: 'relay_command';
76
+ /** Command type */
77
+ kind: 'message' | 'spawn' | 'release';
78
+ /** Sender agent name */
79
+ from: string;
80
+ /** Target agent name (or "spawn"/"release" for those commands) */
81
+ to: string;
82
+ /** Message body or task description */
83
+ body: string;
84
+ /** Original raw text that was parsed */
85
+ raw: string;
86
+ /** Thread identifier (optional) */
87
+ thread?: string;
88
+ /** For spawn: agent name to spawn */
89
+ spawn_name?: string;
90
+ /** For spawn: CLI to use */
91
+ spawn_cli?: string;
92
+ /** For spawn: task description */
93
+ spawn_task?: string;
94
+ /** For release: agent name to release */
95
+ release_name?: string;
96
+ }
97
+ /**
98
+ * JSON format sent to the relay-pty Unix socket for message injection.
99
+ * Socket path: /tmp/relay-pty-{agentName}.sock
100
+ *
101
+ * @example
102
+ * ```json
103
+ * {
104
+ * "type": "inject",
105
+ * "id": "msg-abc123",
106
+ * "from": "Alice",
107
+ * "body": "Hello Bob!",
108
+ * "priority": 0
109
+ * }
110
+ * ```
111
+ */
112
+ export type InjectRequest = {
113
+ type: 'inject';
114
+ /** Unique message ID for tracking */
115
+ id: string;
116
+ /** Sender name (shown as "Relay message from {from}") */
117
+ from: string;
118
+ /** Message body to inject */
119
+ body: string;
120
+ /** Priority (lower = higher priority, default 0) */
121
+ priority?: number;
122
+ } | {
123
+ type: 'status';
124
+ } | {
125
+ type: 'shutdown';
126
+ };
127
+ /**
128
+ * Response from relay-pty socket
129
+ */
130
+ export type InjectResponse = {
131
+ type: 'inject_result';
132
+ id: string;
133
+ status: 'queued' | 'injecting' | 'delivered' | 'failed';
134
+ timestamp: number;
135
+ error?: string;
136
+ } | {
137
+ type: 'status_result';
138
+ agent_idle: boolean;
139
+ queue_length: number;
140
+ last_output_ms: number;
141
+ };
142
+ /**
143
+ * The final format injected into the recipient agent's PTY as plain text.
144
+ * NOT JSON - this is human-readable text that appears in the agent's terminal.
145
+ *
146
+ * Format: "Relay message from {sender} [{shortId}]: {body}"
147
+ *
148
+ * @example First attempt
149
+ * ```
150
+ * Relay message from Alice [abc1234]: Hello Bob, can you review PR #42?
151
+ * ```
152
+ *
153
+ * @example Retry (1st retry)
154
+ * ```
155
+ * [RETRY] Relay message from Alice [abc1234]: Hello Bob, can you review PR #42?
156
+ * ```
157
+ *
158
+ * @example Urgent (2+ retries)
159
+ * ```
160
+ * [URGENT - PLEASE ACKNOWLEDGE] Relay message from Alice [abc1234]: Hello Bob!
161
+ * ```
162
+ */
163
+ export type InjectedMessageFormat = string;
164
+ /**
165
+ * ```
166
+ * ┌─────────────────────────────────────────────────────────────────────────────┐
167
+ * │ COMPLETE MESSAGE FLOW │
168
+ * │ │
169
+ * │ STEP 1: Agent writes file │
170
+ * │ ┌──────────────────────────────────────────────────────────────────────┐ │
171
+ * │ │ cat > /tmp/relay-outbox/$AGENT_RELAY_NAME/msg-001 << 'EOF' │ │
172
+ * │ │ TO: Bob │ │
173
+ * │ │ THREAD: feature-123 │ │
174
+ * │ │ │ │
175
+ * │ │ Hello Bob, can you review PR #42? │ │
176
+ * │ │ EOF │ │
177
+ * │ └──────────────────────────────────────────────────────────────────────┘ │
178
+ * │ │ │
179
+ * │ ▼ │
180
+ * │ STEP 2: Agent outputs trigger │
181
+ * │ ┌──────────────────────────────────────────────────────────────────────┐ │
182
+ * │ │ ->relay-file:msg-001 │ │
183
+ * │ └──────────────────────────────────────────────────────────────────────┘ │
184
+ * │ │ │
185
+ * │ ▼ │
186
+ * │ STEP 3: relay-pty reads file, emits JSON to stderr │
187
+ * │ ┌──────────────────────────────────────────────────────────────────────┐ │
188
+ * │ │ {"type":"relay_command","kind":"message","from":"Alice", │ │
189
+ * │ │ "to":"Bob","body":"Hello Bob, can you review PR #42?", │ │
190
+ * │ │ "thread":"feature-123","raw":"->relay-file:msg-001"} │ │
191
+ * │ └──────────────────────────────────────────────────────────────────────┘ │
192
+ * │ │ │
193
+ * │ ▼ │
194
+ * │ STEP 4: Orchestrator routes to Bob's relay-pty socket │
195
+ * │ ┌──────────────────────────────────────────────────────────────────────┐ │
196
+ * │ │ {"type":"inject","id":"msg-abc123","from":"Alice", │ │
197
+ * │ │ "body":"Hello Bob, can you review PR #42?","priority":0} │ │
198
+ * │ └──────────────────────────────────────────────────────────────────────┘ │
199
+ * │ │ │
200
+ * │ ▼ │
201
+ * │ STEP 5: Bob's relay-pty injects plain text into PTY │
202
+ * │ ┌──────────────────────────────────────────────────────────────────────┐ │
203
+ * │ │ Relay message from Alice [abc1234]: Hello Bob, can you review PR #42?│ │
204
+ * │ └──────────────────────────────────────────────────────────────────────┘ │
205
+ * │ │
206
+ * └─────────────────────────────────────────────────────────────────────────────┘
207
+ * ```
208
+ */
209
+ //# sourceMappingURL=relay-pty-schemas.d.ts.map
@@ -0,0 +1,60 @@
1
+ /**
2
+ * Relay PTY Protocol Schemas
3
+ *
4
+ * This file documents the data formats used in the relay-pty message flow:
5
+ *
6
+ * 1. Agent → File (outbox) : RelayFileFormat
7
+ * 2. relay-pty → Orchestrator : ParsedRelayCommand (JSON on stderr)
8
+ * 3. Orchestrator → Socket : InjectRequest (JSON)
9
+ * 4. Socket → Agent PTY : Plain text injection
10
+ */
11
+ export {};
12
+ // =============================================================================
13
+ // Complete Flow Diagram
14
+ // =============================================================================
15
+ /**
16
+ * ```
17
+ * ┌─────────────────────────────────────────────────────────────────────────────┐
18
+ * │ COMPLETE MESSAGE FLOW │
19
+ * │ │
20
+ * │ STEP 1: Agent writes file │
21
+ * │ ┌──────────────────────────────────────────────────────────────────────┐ │
22
+ * │ │ cat > /tmp/relay-outbox/$AGENT_RELAY_NAME/msg-001 << 'EOF' │ │
23
+ * │ │ TO: Bob │ │
24
+ * │ │ THREAD: feature-123 │ │
25
+ * │ │ │ │
26
+ * │ │ Hello Bob, can you review PR #42? │ │
27
+ * │ │ EOF │ │
28
+ * │ └──────────────────────────────────────────────────────────────────────┘ │
29
+ * │ │ │
30
+ * │ ▼ │
31
+ * │ STEP 2: Agent outputs trigger │
32
+ * │ ┌──────────────────────────────────────────────────────────────────────┐ │
33
+ * │ │ ->relay-file:msg-001 │ │
34
+ * │ └──────────────────────────────────────────────────────────────────────┘ │
35
+ * │ │ │
36
+ * │ ▼ │
37
+ * │ STEP 3: relay-pty reads file, emits JSON to stderr │
38
+ * │ ┌──────────────────────────────────────────────────────────────────────┐ │
39
+ * │ │ {"type":"relay_command","kind":"message","from":"Alice", │ │
40
+ * │ │ "to":"Bob","body":"Hello Bob, can you review PR #42?", │ │
41
+ * │ │ "thread":"feature-123","raw":"->relay-file:msg-001"} │ │
42
+ * │ └──────────────────────────────────────────────────────────────────────┘ │
43
+ * │ │ │
44
+ * │ ▼ │
45
+ * │ STEP 4: Orchestrator routes to Bob's relay-pty socket │
46
+ * │ ┌──────────────────────────────────────────────────────────────────────┐ │
47
+ * │ │ {"type":"inject","id":"msg-abc123","from":"Alice", │ │
48
+ * │ │ "body":"Hello Bob, can you review PR #42?","priority":0} │ │
49
+ * │ └──────────────────────────────────────────────────────────────────────┘ │
50
+ * │ │ │
51
+ * │ ▼ │
52
+ * │ STEP 5: Bob's relay-pty injects plain text into PTY │
53
+ * │ ┌──────────────────────────────────────────────────────────────────────┐ │
54
+ * │ │ Relay message from Alice [abc1234]: Hello Bob, can you review PR #42?│ │
55
+ * │ └──────────────────────────────────────────────────────────────────────┘ │
56
+ * │ │
57
+ * └─────────────────────────────────────────────────────────────────────────────┘
58
+ * ```
59
+ */
60
+ //# sourceMappingURL=relay-pty-schemas.js.map
@@ -34,8 +34,10 @@ export const AUTH_REVOCATION_PATTERNS = [
34
34
  // OAuth specific
35
35
  /oauth\s+error.*401/i,
36
36
  /oauth\s+error.*403/i,
37
+ /oauth\s+token\s+(has\s+)?expired/i,
37
38
  /refresh\s+token\s+(is\s+)?invalid/i,
38
39
  /failed\s+to\s+refresh/i,
40
+ /please\s+obtain\s+a\s+new\s+token/i,
39
41
  // API errors that indicate auth issues
40
42
  /api\s+error.*401/i,
41
43
  /api\s+error.*403/i,
@@ -111,8 +113,11 @@ function getConfidenceLevel(pattern, _matchedText) {
111
113
  patternStr.includes('please') && patternStr.includes('log') ||
112
114
  patternStr.includes('authentication required') ||
113
115
  patternStr.includes('token') && patternStr.includes('expired') ||
116
+ patternStr.includes('oauth') && patternStr.includes('expired') ||
117
+ patternStr.includes('authentication_error') ||
114
118
  patternStr.includes('signed out') ||
115
- patternStr.includes('session revoked')) {
119
+ patternStr.includes('session revoked') ||
120
+ patternStr.includes('obtain') && patternStr.includes('token')) {
116
121
  return 'high';
117
122
  }
118
123
  // Medium confidence: General auth errors
@@ -150,6 +155,8 @@ export const PROVIDER_AUTH_PATTERNS = {
150
155
  /anthropic.*unauthorized/i,
151
156
  /claude.*not\s+authenticated/i,
152
157
  /please\s+run\s+claude\s+login/i,
158
+ /please\s+run\s+\/login/i,
159
+ /authentication_error/i,
153
160
  ],
154
161
  codex: [
155
162
  /codex.*session.*expired/i,
@@ -17,7 +17,8 @@
17
17
  import { EventEmitter } from 'node:events';
18
18
  import { RelayClient } from './client.js';
19
19
  import type { ParsedCommand, ParsedSummary } from './parser.js';
20
- import type { SendPayload, SendMeta, SpeakOnTrigger } from '../protocol/types.js';
20
+ import type { SendPayload, SendMeta, SpeakOnTrigger, Envelope } from '../protocol/types.js';
21
+ import type { ChannelMessagePayload } from '../protocol/channels.js';
21
22
  import { type QueuedMessage, type InjectionMetrics, type CliType } from './shared.js';
22
23
  import { type ContinuityManager } from '../continuity/index.js';
23
24
  import { UniversalIdleDetector } from './idle-detector.js';
@@ -60,6 +61,10 @@ export interface BaseWrapperConfig {
60
61
  idleBeforeInjectMs?: number;
61
62
  /** Confidence threshold for idle detection (0-1, default: 0.7) */
62
63
  idleConfidenceThreshold?: number;
64
+ /** Skip initial instruction injection (when using --append-system-prompt) */
65
+ skipInstructions?: boolean;
66
+ /** Skip continuity loading (for spawned agents that don't need session recovery) */
67
+ skipContinuity?: boolean;
63
68
  }
64
69
  /**
65
70
  * Abstract base class for agent wrappers
@@ -142,6 +147,11 @@ export declare abstract class BaseWrapper extends EventEmitter {
142
147
  * Handle incoming message from relay
143
148
  */
144
149
  protected handleIncomingMessage(from: string, payload: SendPayload, messageId: string, meta?: SendMeta, originalTo?: string): void;
150
+ /**
151
+ * Handle incoming channel message from relay.
152
+ * Channel messages include a channel indicator so the agent knows to reply to the channel.
153
+ */
154
+ protected handleIncomingChannelMessage(from: string, channel: string, body: string, envelope: Envelope<ChannelMessagePayload>): void;
145
155
  /**
146
156
  * Send a relay command via the client
147
157
  */
@@ -63,17 +63,23 @@ export class BaseWrapper extends EventEmitter {
63
63
  workingDirectory: config.cwd,
64
64
  quiet: true,
65
65
  });
66
- // Initialize continuity manager
67
- this.continuity = getContinuityManager({ defaultCli: this.cliType });
66
+ // Initialize continuity manager (skip for spawned agents that don't need session recovery)
67
+ if (!config.skipContinuity) {
68
+ this.continuity = getContinuityManager({ defaultCli: this.cliType });
69
+ }
68
70
  // Initialize universal idle detector for robust injection timing
69
71
  this.idleDetector = new UniversalIdleDetector({
70
72
  minSilenceMs: config.idleBeforeInjectMs ?? DEFAULT_IDLE_BEFORE_INJECT_MS,
71
73
  confidenceThreshold: config.idleConfidenceThreshold ?? DEFAULT_IDLE_CONFIDENCE_THRESHOLD,
72
74
  });
73
- // Set up message handler
75
+ // Set up message handler for direct messages
74
76
  this.client.onMessage = (from, payload, messageId, meta, originalTo) => {
75
77
  this.handleIncomingMessage(from, payload, messageId, meta, originalTo);
76
78
  };
79
+ // Set up channel message handler
80
+ this.client.onChannelMessage = (from, channel, body, envelope) => {
81
+ this.handleIncomingChannelMessage(from, channel, body, envelope);
82
+ };
77
83
  }
78
84
  // =========================================================================
79
85
  // Common getters
@@ -163,6 +169,40 @@ export class BaseWrapper extends EventEmitter {
163
169
  };
164
170
  this.messageQueue.push(queuedMsg);
165
171
  }
172
+ /**
173
+ * Handle incoming channel message from relay.
174
+ * Channel messages include a channel indicator so the agent knows to reply to the channel.
175
+ */
176
+ handleIncomingChannelMessage(from, channel, body, envelope) {
177
+ const messageId = envelope.id;
178
+ // Deduplicate by message ID
179
+ if (this.receivedMessageIds.has(messageId))
180
+ return;
181
+ this.receivedMessageIds.add(messageId);
182
+ // Limit dedup set size
183
+ if (this.receivedMessageIds.size > 1000) {
184
+ const oldest = this.receivedMessageIds.values().next().value;
185
+ if (oldest)
186
+ this.receivedMessageIds.delete(oldest);
187
+ }
188
+ // Queue the message with channel indicator in the body
189
+ // Format: "Relay message from Alice [abc123] [#general]: message body"
190
+ // This lets the agent know to reply to the channel, not the sender
191
+ const queuedMsg = {
192
+ from,
193
+ body,
194
+ messageId,
195
+ thread: envelope.payload.thread,
196
+ data: {
197
+ _isChannelMessage: true,
198
+ _channel: channel,
199
+ _mentions: envelope.payload.mentions,
200
+ },
201
+ originalTo: channel, // Set channel as the reply target
202
+ };
203
+ console.error(`[base-wrapper] Received channel message: from=${from} channel=${channel} id=${messageId.substring(0, 8)}`);
204
+ this.messageQueue.push(queuedMsg);
205
+ }
166
206
  /**
167
207
  * Send a relay command via the client
168
208
  */
@@ -186,9 +226,24 @@ export class BaseWrapper extends EventEmitter {
186
226
  this.sentMessageHashes.delete(oldest);
187
227
  }
188
228
  // Only send if client ready
189
- if (this.client.state !== 'READY')
229
+ if (this.client.state !== 'READY') {
230
+ console.error(`[base-wrapper] Client not ready (state=${this.client.state}), dropping message to ${cmd.to}`);
190
231
  return;
191
- this.client.sendMessage(cmd.to, cmd.body, cmd.kind, cmd.data, cmd.thread);
232
+ }
233
+ console.error(`[base-wrapper] sendRelayCommand: to=${cmd.to}, body=${cmd.body.substring(0, 50)}...`);
234
+ // Check if target is a channel (starts with #)
235
+ if (cmd.to.startsWith('#')) {
236
+ // Use CHANNEL_MESSAGE protocol for channel targets
237
+ console.error(`[base-wrapper] Sending CHANNEL_MESSAGE to ${cmd.to}`);
238
+ this.client.sendChannelMessage(cmd.to, cmd.body, {
239
+ thread: cmd.thread,
240
+ data: cmd.data,
241
+ });
242
+ }
243
+ else {
244
+ // Use SEND protocol for direct messages and broadcasts
245
+ this.client.sendMessage(cmd.to, cmd.body, cmd.kind, cmd.data, cmd.thread);
246
+ }
192
247
  }
193
248
  // =========================================================================
194
249
  // Spawn/release handling
@@ -197,11 +252,16 @@ export class BaseWrapper extends EventEmitter {
197
252
  * Parse spawn and release commands from output
198
253
  */
199
254
  parseSpawnReleaseCommands(content) {
255
+ // Debug: check for spawn keyword
256
+ if (content.includes('->relay:spawn')) {
257
+ console.log(`[base-wrapper:${this.config.name}] Found spawn keyword in content`);
258
+ }
200
259
  // Single-line spawn: ->relay:spawn Name cli "task"
201
260
  const spawnPattern = new RegExp(`${this.relayPrefix.replace(/[.*+?^${}()|[\]\\]/g, '\\$&')}spawn\\s+(\\w+)\\s+(\\w+)\\s+"([^"]+)"`);
202
261
  const spawnMatch = content.match(spawnPattern);
203
262
  if (spawnMatch) {
204
263
  const [, name, cli, task] = spawnMatch;
264
+ console.log(`[base-wrapper:${this.config.name}] Single-line spawn match: ${name} ${cli}`);
205
265
  const cmdHash = `spawn:${name}:${cli}:${task}`;
206
266
  if (!this.processedSpawnCommands.has(cmdHash)) {
207
267
  this.processedSpawnCommands.add(cmdHash);
@@ -209,10 +269,11 @@ export class BaseWrapper extends EventEmitter {
209
269
  }
210
270
  }
211
271
  // Fenced spawn: ->relay:spawn Name cli <<<\ntask\n>>>
212
- const fencedSpawnPattern = new RegExp(`${this.relayPrefix.replace(/[.*+?^${}()|[\]\\]/g, '\\$&')}spawn\\s+(\\w+)\\s+(\\w+)\\s+<<<\\n?([\\s\\S]*?)>>>`);
272
+ const fencedSpawnPattern = new RegExp(`${this.relayPrefix.replace(/[.*+?^${}()|[\]\\]/g, '\\$&')}spawn\\s+(\\w+)\\s+(\\w+)\\s*<<<[\\s]*([\\s\\S]*?)>>>`);
213
273
  const fencedSpawnMatch = content.match(fencedSpawnPattern);
214
274
  if (fencedSpawnMatch) {
215
275
  const [, name, cli, task] = fencedSpawnMatch;
276
+ console.log(`[base-wrapper:${this.config.name}] Fenced spawn match: ${name} ${cli}`);
216
277
  const cmdHash = `spawn:${name}:${cli}:${task.trim()}`;
217
278
  if (!this.processedSpawnCommands.has(cmdHash)) {
218
279
  this.processedSpawnCommands.add(cmdHash);
@@ -7,7 +7,8 @@
7
7
  * - Write coalescing (batch socket writes)
8
8
  * - Circular dedup cache (O(1) eviction)
9
9
  */
10
- import { type SendPayload, type SendMeta, type PayloadKind, type SpeakOnTrigger, type EntityType } from '../protocol/types.js';
10
+ import { type Envelope, type SendPayload, type SendMeta, type PayloadKind, type SpeakOnTrigger, type EntityType } from '../protocol/types.js';
11
+ import type { ChannelMessagePayload, MessageAttachment } from '../protocol/channels.js';
11
12
  export type ClientState = 'DISCONNECTED' | 'CONNECTING' | 'HANDSHAKING' | 'READY' | 'BACKOFF';
12
13
  export interface ClientConfig {
13
14
  socketPath: string;
@@ -58,6 +59,14 @@ export declare class RelayClient {
58
59
  * @param originalTo - Original 'to' field from sender (e.g., '*' for broadcasts)
59
60
  */
60
61
  onMessage?: (from: string, payload: SendPayload, messageId: string, meta?: SendMeta, originalTo?: string) => void;
62
+ /**
63
+ * Callback for channel messages.
64
+ * @param from - Sender name
65
+ * @param channel - Channel name
66
+ * @param body - Message content
67
+ * @param envelope - Full envelope for additional data
68
+ */
69
+ onChannelMessage?: (from: string, channel: string, body: string, envelope: Envelope<ChannelMessagePayload>) => void;
61
70
  onStateChange?: (state: ClientState) => void;
62
71
  onError?: (error: Error) => void;
63
72
  constructor(config?: Partial<ClientConfig>);
@@ -91,6 +100,44 @@ export declare class RelayClient {
91
100
  * Broadcast a message to all agents.
92
101
  */
93
102
  broadcast(body: string, kind?: PayloadKind, data?: Record<string, unknown>): boolean;
103
+ /**
104
+ * Join a channel.
105
+ * @param channel - Channel name (e.g., '#general', 'dm:alice:bob')
106
+ * @param displayName - Optional display name for this member
107
+ */
108
+ joinChannel(channel: string, displayName?: string): boolean;
109
+ /**
110
+ * Admin join: Add any member to a channel (does not require member to be connected).
111
+ * Used by dashboard to sync channel memberships for agents.
112
+ * @param channel - Channel name (e.g., '#general')
113
+ * @param member - Name of the member to add
114
+ */
115
+ adminJoinChannel(channel: string, member: string): boolean;
116
+ /**
117
+ * Leave a channel.
118
+ * @param channel - Channel name to leave
119
+ * @param reason - Optional reason for leaving
120
+ */
121
+ leaveChannel(channel: string, reason?: string): boolean;
122
+ /**
123
+ * Admin remove: Remove any member from a channel (does not require member to be connected).
124
+ * Used by dashboard to remove channel members.
125
+ * @param channel - Channel name (e.g., '#general')
126
+ * @param member - Name of the member to remove
127
+ */
128
+ adminRemoveMember(channel: string, member: string): boolean;
129
+ /**
130
+ * Send a message to a channel.
131
+ * @param channel - Channel name
132
+ * @param body - Message content
133
+ * @param options - Optional thread, mentions, attachments
134
+ */
135
+ sendChannelMessage(channel: string, body: string, options?: {
136
+ thread?: string;
137
+ mentions?: string[];
138
+ attachments?: MessageAttachment[];
139
+ data?: Record<string, unknown>;
140
+ }): boolean;
94
141
  /**
95
142
  * Subscribe to a topic.
96
143
  */
@@ -136,6 +183,7 @@ export declare class RelayClient {
136
183
  private processFrame;
137
184
  private handleWelcome;
138
185
  private handleDeliver;
186
+ private handleChannelMessage;
139
187
  private handlePing;
140
188
  private handleErrorFrame;
141
189
  private handleDisconnect;