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.
- package/README.md +130 -158
- package/bin/relay-pty +0 -0
- package/bin/relay-pty-darwin-arm64 +0 -0
- package/bin/relay-pty-darwin-x64 +0 -0
- package/bin/relay-pty-linux-x64 +0 -0
- package/deploy/workspace/entrypoint.sh +9 -0
- package/dist/bridge/spawner.d.ts +4 -4
- package/dist/bridge/spawner.js +58 -92
- package/dist/cli/index.d.ts +8 -6
- package/dist/cli/index.js +282 -47
- package/dist/cloud/api/daemons.js +13 -32
- package/dist/cloud/api/onboarding.js +2 -4
- package/dist/cloud/api/providers.js +6 -0
- package/dist/cloud/config.d.ts +1 -0
- package/dist/cloud/config.js +2 -0
- package/dist/cloud/db/bulk-ingest.d.ts +2 -1
- package/dist/cloud/db/drizzle.d.ts +21 -26
- package/dist/cloud/db/drizzle.js +87 -100
- package/dist/cloud/db/index.d.ts +6 -5
- package/dist/cloud/db/index.js +9 -8
- package/dist/cloud/db/schema.d.ts +1049 -1076
- package/dist/cloud/db/schema.js +59 -71
- package/dist/cloud/server.js +854 -18
- package/dist/cloud/services/persistence.d.ts +15 -15
- package/dist/cloud/services/persistence.js +14 -14
- package/dist/daemon/agent-manager.d.ts +6 -5
- package/dist/daemon/agent-manager.js +12 -8
- package/dist/daemon/channel-membership-store.d.ts +48 -0
- package/dist/daemon/channel-membership-store.js +149 -0
- package/dist/daemon/cloud-sync.d.ts +2 -0
- package/dist/daemon/cloud-sync.js +4 -0
- package/dist/daemon/connection.js +17 -9
- package/dist/daemon/router.d.ts +37 -0
- package/dist/daemon/router.js +318 -79
- package/dist/daemon/server.d.ts +15 -0
- package/dist/daemon/server.js +141 -3
- package/dist/dashboard/out/404.html +1 -0
- package/dist/dashboard/out/_next/static/IxxVRv94L1w3ReRGAiI-k/_buildManifest.js +1 -0
- package/dist/dashboard/out/_next/static/IxxVRv94L1w3ReRGAiI-k/_ssgManifest.js +1 -0
- package/dist/dashboard/out/_next/static/chunks/116-eacf84a131b80db9.js +1 -0
- package/dist/dashboard/out/_next/static/chunks/117-c8afed19e821a35d.js +2 -0
- package/dist/dashboard/out/_next/static/chunks/282-980c2eb8fff20123.js +1 -0
- package/dist/dashboard/out/_next/static/chunks/532-bace199897eeab37.js +9 -0
- package/dist/dashboard/out/_next/static/chunks/64-87ab9cd6bcf2f737.js +1 -0
- package/dist/dashboard/out/_next/static/chunks/648-acb2ff9f77cbfbd3.js +1 -0
- package/dist/dashboard/out/_next/static/chunks/766-aa7c8c9900ff5f53.js +1 -0
- package/dist/dashboard/out/_next/static/chunks/83-4f08122d4e7e79a6.js +1 -0
- package/dist/dashboard/out/_next/static/chunks/847-f1f467060f32afff.js +1 -0
- package/dist/dashboard/out/_next/static/chunks/891-a024fbe4b619cf6f.js +1 -0
- package/dist/dashboard/out/_next/static/chunks/app/_not-found/page-60501fddbafba9dc.js +1 -0
- package/dist/dashboard/out/_next/static/chunks/app/app/onboarding/page-f746f29e01fffc43.js +1 -0
- package/dist/dashboard/out/_next/static/chunks/app/app/page-ffad986adfcc8b31.js +1 -0
- package/dist/dashboard/out/_next/static/chunks/app/cloud/link/page-cfeb437f08a12ed9.js +1 -0
- package/dist/dashboard/out/_next/static/chunks/app/connect-repos/page-03ac6f35a6654ea6.js +1 -0
- package/dist/dashboard/out/_next/static/chunks/app/history/page-240f91e8b06ba8ac.js +1 -0
- package/dist/dashboard/out/_next/static/chunks/app/layout-c0d118c0f92d969c.js +1 -0
- package/dist/dashboard/out/_next/static/chunks/app/login/page-6ec54eee75877971.js +1 -0
- package/dist/dashboard/out/_next/static/chunks/app/metrics/page-82938ab8fcf44694.js +1 -0
- package/dist/dashboard/out/_next/static/chunks/app/page-671037943b2f2e43.js +1 -0
- package/dist/dashboard/out/_next/static/chunks/app/pricing/page-0efa024c28ba4597.js +1 -0
- package/dist/dashboard/out/_next/static/chunks/app/providers/page-57cbd738c6a73859.js +1 -0
- package/dist/dashboard/out/_next/static/chunks/app/providers/setup/[provider]/page-5ab0854472b402b0.js +1 -0
- package/dist/dashboard/out/_next/static/chunks/app/signup/page-18a4665665f6be11.js +1 -0
- package/dist/dashboard/out/_next/static/chunks/e868780c-48e5f147c90a3a41.js +18 -0
- package/dist/dashboard/out/_next/static/chunks/fd9d1056-609918ca7b6280bb.js +1 -0
- package/dist/dashboard/out/_next/static/chunks/framework-f66176bb897dc684.js +1 -0
- package/dist/dashboard/out/_next/static/chunks/main-5a40a5ae29646e1b.js +1 -0
- package/dist/dashboard/out/_next/static/chunks/main-app-6e8e8d3ef4e0192a.js +1 -0
- package/dist/dashboard/out/_next/static/chunks/pages/_app-72b849fbd24ac258.js +1 -0
- package/dist/dashboard/out/_next/static/chunks/pages/_error-7ba65e1336b92748.js +1 -0
- package/dist/dashboard/out/_next/static/chunks/polyfills-42372ed130431b0a.js +1 -0
- package/dist/dashboard/out/_next/static/chunks/webpack-1cdd8ed57114d5e1.js +1 -0
- package/dist/dashboard/out/_next/static/css/4034f236dd1a3178.css +1 -0
- package/dist/dashboard/out/_next/static/css/8f9ed310f454e5a5.css +1 -0
- package/dist/dashboard/out/alt-logos/agent-relay-logo-128.png +0 -0
- package/dist/dashboard/out/alt-logos/agent-relay-logo-256.png +0 -0
- package/dist/dashboard/out/alt-logos/agent-relay-logo-32.png +0 -0
- package/dist/dashboard/out/alt-logos/agent-relay-logo-512.png +0 -0
- package/dist/dashboard/out/alt-logos/agent-relay-logo-64.png +0 -0
- package/dist/dashboard/out/alt-logos/agent-relay-logo.svg +45 -0
- package/dist/dashboard/out/alt-logos/logo.svg +38 -0
- package/dist/dashboard/out/alt-logos/monogram-logo-128.png +0 -0
- package/dist/dashboard/out/alt-logos/monogram-logo-256.png +0 -0
- package/dist/dashboard/out/alt-logos/monogram-logo-32.png +0 -0
- package/dist/dashboard/out/alt-logos/monogram-logo-512.png +0 -0
- package/dist/dashboard/out/alt-logos/monogram-logo-64.png +0 -0
- package/dist/dashboard/out/alt-logos/monogram-logo.svg +38 -0
- package/dist/dashboard/out/app/onboarding.html +1 -0
- package/dist/dashboard/out/app/onboarding.txt +7 -0
- package/dist/dashboard/out/app.html +1 -0
- package/dist/dashboard/out/app.txt +7 -0
- package/dist/dashboard/out/apple-icon.png +0 -0
- package/dist/dashboard/out/cloud/link.html +1 -0
- package/dist/dashboard/out/cloud/link.txt +7 -0
- package/dist/dashboard/out/connect-repos.html +1 -0
- package/dist/dashboard/out/connect-repos.txt +7 -0
- package/dist/dashboard/out/history.html +1 -0
- package/dist/dashboard/out/history.txt +7 -0
- package/dist/dashboard/out/index.html +1 -0
- package/dist/dashboard/out/index.txt +7 -0
- package/dist/dashboard/out/login.html +5 -0
- package/dist/dashboard/out/login.txt +7 -0
- package/dist/dashboard/out/metrics.html +1 -0
- package/dist/dashboard/out/metrics.txt +7 -0
- package/dist/dashboard/out/pricing.html +13 -0
- package/dist/dashboard/out/pricing.txt +7 -0
- package/dist/dashboard/out/providers/setup/claude.html +1 -0
- package/dist/dashboard/out/providers/setup/claude.txt +8 -0
- package/dist/dashboard/out/providers/setup/codex.html +1 -0
- package/dist/dashboard/out/providers/setup/codex.txt +8 -0
- package/dist/dashboard/out/providers.html +1 -0
- package/dist/dashboard/out/providers.txt +7 -0
- package/dist/dashboard/out/signup.html +6 -0
- package/dist/dashboard/out/signup.txt +7 -0
- package/dist/dashboard-server/metrics.d.ts +105 -0
- package/dist/dashboard-server/metrics.js +193 -0
- package/dist/dashboard-server/needs-attention.d.ts +24 -0
- package/dist/dashboard-server/needs-attention.js +78 -0
- package/dist/dashboard-server/server.d.ts +15 -0
- package/dist/dashboard-server/server.js +4753 -0
- package/dist/dashboard-server/start.d.ts +6 -0
- package/dist/dashboard-server/start.js +13 -0
- package/dist/dashboard-server/user-bridge.d.ts +132 -0
- package/dist/dashboard-server/user-bridge.js +317 -0
- package/dist/protocol/channels.d.ts +14 -8
- package/dist/protocol/channels.js +1 -1
- package/dist/protocol/index.d.ts +1 -0
- package/dist/protocol/index.js +1 -0
- package/dist/protocol/relay-pty-schemas.d.ts +209 -0
- package/dist/protocol/relay-pty-schemas.js +60 -0
- package/dist/wrapper/auth-detection.js +8 -1
- package/dist/wrapper/base-wrapper.d.ts +11 -1
- package/dist/wrapper/base-wrapper.js +67 -6
- package/dist/wrapper/client.d.ts +49 -1
- package/dist/wrapper/client.js +167 -0
- package/dist/wrapper/parser.d.ts +0 -4
- package/dist/wrapper/parser.js +38 -10
- package/dist/wrapper/pty-wrapper.d.ts +12 -1
- package/dist/wrapper/pty-wrapper.js +104 -5
- package/dist/wrapper/relay-pty-orchestrator.d.ts +270 -0
- package/dist/wrapper/relay-pty-orchestrator.js +970 -0
- package/dist/wrapper/shared.d.ts +1 -1
- package/dist/wrapper/shared.js +14 -4
- package/dist/wrapper/tmux-wrapper.d.ts +13 -1
- package/dist/wrapper/tmux-wrapper.js +143 -29
- package/package.json +9 -4
- package/scripts/postinstall.js +101 -11
- package/.trajectories/active/traj_3yx9dy148mge.json +0 -42
- package/.trajectories/agent-relay-322-324.md +0 -17
- package/.trajectories/completed/2026-01/traj_03zupyv1s7b9.json +0 -49
- package/.trajectories/completed/2026-01/traj_03zupyv1s7b9.md +0 -31
- package/.trajectories/completed/2026-01/traj_0zacdjl1g4ht.json +0 -125
- package/.trajectories/completed/2026-01/traj_0zacdjl1g4ht.md +0 -62
- package/.trajectories/completed/2026-01/traj_1dviorhnkcb5.json +0 -65
- package/.trajectories/completed/2026-01/traj_1dviorhnkcb5.md +0 -37
- package/.trajectories/completed/2026-01/traj_1g7yx6qtg4ai.json +0 -49
- package/.trajectories/completed/2026-01/traj_1g7yx6qtg4ai.md +0 -31
- package/.trajectories/completed/2026-01/traj_1k5if5snst2e.json +0 -65
- package/.trajectories/completed/2026-01/traj_1k5if5snst2e.md +0 -37
- package/.trajectories/completed/2026-01/traj_1rp3rges5811.json +0 -49
- package/.trajectories/completed/2026-01/traj_1rp3rges5811.md +0 -31
- package/.trajectories/completed/2026-01/traj_22bhyulruouw.json +0 -113
- package/.trajectories/completed/2026-01/traj_22bhyulruouw.md +0 -57
- package/.trajectories/completed/2026-01/traj_2dao7ddgnta0.json +0 -53
- package/.trajectories/completed/2026-01/traj_2dao7ddgnta0.md +0 -32
- package/.trajectories/completed/2026-01/traj_33iuy72sezbk.json +0 -49
- package/.trajectories/completed/2026-01/traj_33iuy72sezbk.md +0 -31
- package/.trajectories/completed/2026-01/traj_3t0440mjeunc.json +0 -26
- package/.trajectories/completed/2026-01/traj_3t0440mjeunc.md +0 -6
- package/.trajectories/completed/2026-01/traj_45x9494d9xnr.json +0 -47
- package/.trajectories/completed/2026-01/traj_45x9494d9xnr.md +0 -32
- package/.trajectories/completed/2026-01/traj_4aa0bb77s4nh.json +0 -53
- package/.trajectories/completed/2026-01/traj_4aa0bb77s4nh.md +0 -32
- package/.trajectories/completed/2026-01/traj_4qwd4zmhfwp4.json +0 -49
- package/.trajectories/completed/2026-01/traj_4qwd4zmhfwp4.md +0 -31
- package/.trajectories/completed/2026-01/traj_5ammh5qtvklq.json +0 -77
- package/.trajectories/completed/2026-01/traj_5ammh5qtvklq.md +0 -42
- package/.trajectories/completed/2026-01/traj_5lhmzq8rxpqv.json +0 -59
- package/.trajectories/completed/2026-01/traj_5lhmzq8rxpqv.md +0 -33
- package/.trajectories/completed/2026-01/traj_5vr4e9erb1fs.json +0 -53
- package/.trajectories/completed/2026-01/traj_5vr4e9erb1fs.md +0 -32
- package/.trajectories/completed/2026-01/traj_6fgiwdoklvym.json +0 -48
- package/.trajectories/completed/2026-01/traj_6fgiwdoklvym.md +0 -24
- package/.trajectories/completed/2026-01/traj_6mieijqyvaag.json +0 -77
- package/.trajectories/completed/2026-01/traj_6mieijqyvaag.md +0 -42
- package/.trajectories/completed/2026-01/traj_6unwwmgyj5sq.json +0 -109
- package/.trajectories/completed/2026-01/traj_78ffm31jn3uk.json +0 -77
- package/.trajectories/completed/2026-01/traj_78ffm31jn3uk.md +0 -42
- package/.trajectories/completed/2026-01/traj_7ludwvz45veh.json +0 -209
- package/.trajectories/completed/2026-01/traj_7ludwvz45veh.md +0 -97
- package/.trajectories/completed/2026-01/traj_94gnp3k30goq.json +0 -66
- package/.trajectories/completed/2026-01/traj_94gnp3k30goq.md +0 -36
- package/.trajectories/completed/2026-01/traj_9921cuhel0pj.json +0 -48
- package/.trajectories/completed/2026-01/traj_9921cuhel0pj.md +0 -24
- package/.trajectories/completed/2026-01/traj_a0tqx8biw9c4.json +0 -49
- package/.trajectories/completed/2026-01/traj_a0tqx8biw9c4.md +0 -31
- package/.trajectories/completed/2026-01/traj_ajs7zqfux4wc.json +0 -49
- package/.trajectories/completed/2026-01/traj_ajs7zqfux4wc.md +0 -23
- package/.trajectories/completed/2026-01/traj_avqeghu6pz5a.json +0 -40
- package/.trajectories/completed/2026-01/traj_avqeghu6pz5a.md +0 -22
- package/.trajectories/completed/2026-01/traj_ax8uungxz2qh.json +0 -66
- package/.trajectories/completed/2026-01/traj_ax8uungxz2qh.md +0 -36
- package/.trajectories/completed/2026-01/traj_c9izbh2snpzf.json +0 -49
- package/.trajectories/completed/2026-01/traj_c9izbh2snpzf.md +0 -31
- package/.trajectories/completed/2026-01/traj_cpn70dw066nt.json +0 -65
- package/.trajectories/completed/2026-01/traj_cpn70dw066nt.md +0 -37
- package/.trajectories/completed/2026-01/traj_cvtqhlwcq9s0.json +0 -53
- package/.trajectories/completed/2026-01/traj_cvtqhlwcq9s0.md +0 -32
- package/.trajectories/completed/2026-01/traj_cxofprm2m2en.json +0 -49
- package/.trajectories/completed/2026-01/traj_cxofprm2m2en.md +0 -31
- package/.trajectories/completed/2026-01/traj_d2hhz3k0vrhn.json +0 -26
- package/.trajectories/completed/2026-01/traj_d2hhz3k0vrhn.md +0 -6
- package/.trajectories/completed/2026-01/traj_dcsp9s8y01ra.json +0 -121
- package/.trajectories/completed/2026-01/traj_dcsp9s8y01ra.md +0 -29
- package/.trajectories/completed/2026-01/traj_dfuvww9pege5.json +0 -59
- package/.trajectories/completed/2026-01/traj_dfuvww9pege5.md +0 -37
- package/.trajectories/completed/2026-01/traj_erglv2f8t9eh.json +0 -36
- package/.trajectories/completed/2026-01/traj_erglv2f8t9eh.md +0 -21
- package/.trajectories/completed/2026-01/traj_fhx9irlckht6.json +0 -53
- package/.trajectories/completed/2026-01/traj_fhx9irlckht6.md +0 -32
- package/.trajectories/completed/2026-01/traj_fqduidx3xbtp.json +0 -101
- package/.trajectories/completed/2026-01/traj_fqduidx3xbtp.md +0 -52
- package/.trajectories/completed/2026-01/traj_g0fisy9h51mf.json +0 -77
- package/.trajectories/completed/2026-01/traj_g0fisy9h51mf.md +0 -42
- package/.trajectories/completed/2026-01/traj_gjdre5voouod.json +0 -53
- package/.trajectories/completed/2026-01/traj_gjdre5voouod.md +0 -32
- package/.trajectories/completed/2026-01/traj_gtlyqtta3x8l.json +0 -25
- package/.trajectories/completed/2026-01/traj_gtlyqtta3x8l.md +0 -15
- package/.trajectories/completed/2026-01/traj_h4xijiuip3w4.json +0 -101
- package/.trajectories/completed/2026-01/traj_h4xijiuip3w4.md +0 -44
- package/.trajectories/completed/2026-01/traj_he75f24d1xfm.json +0 -101
- package/.trajectories/completed/2026-01/traj_he75f24d1xfm.md +0 -52
- package/.trajectories/completed/2026-01/traj_hf81ey93uz6t.json +0 -49
- package/.trajectories/completed/2026-01/traj_hf81ey93uz6t.md +0 -31
- package/.trajectories/completed/2026-01/traj_hfmki2jr9d4r.json +0 -65
- package/.trajectories/completed/2026-01/traj_hfmki2jr9d4r.md +0 -37
- package/.trajectories/completed/2026-01/traj_hhxte7w4gjjx.json +0 -22
- package/.trajectories/completed/2026-01/traj_hhxte7w4gjjx.md +0 -5
- package/.trajectories/completed/2026-01/traj_hpungyhoj6v5.json +0 -53
- package/.trajectories/completed/2026-01/traj_hpungyhoj6v5.md +0 -32
- package/.trajectories/completed/2026-01/traj_lgtodco7dp1n.json +0 -61
- package/.trajectories/completed/2026-01/traj_lgtodco7dp1n.md +0 -36
- package/.trajectories/completed/2026-01/traj_lq450ly148uw.json +0 -49
- package/.trajectories/completed/2026-01/traj_lq450ly148uw.md +0 -31
- package/.trajectories/completed/2026-01/traj_m2xkjv0w2sq7.json +0 -25
- package/.trajectories/completed/2026-01/traj_m2xkjv0w2sq7.md +0 -15
- package/.trajectories/completed/2026-01/traj_multi_server_arch.md +0 -101
- package/.trajectories/completed/2026-01/traj_noq5zbvnrdvz.json +0 -53
- package/.trajectories/completed/2026-01/traj_noq5zbvnrdvz.md +0 -32
- package/.trajectories/completed/2026-01/traj_ntbs6ppopf46.json +0 -53
- package/.trajectories/completed/2026-01/traj_ntbs6ppopf46.md +0 -32
- package/.trajectories/completed/2026-01/traj_oszg9flv74pk.json +0 -73
- package/.trajectories/completed/2026-01/traj_oszg9flv74pk.md +0 -41
- package/.trajectories/completed/2026-01/traj_ozd98si6a7ns.json +0 -48
- package/.trajectories/completed/2026-01/traj_ozd98si6a7ns.md +0 -24
- package/.trajectories/completed/2026-01/traj_prdza7a5cxp5.json +0 -53
- package/.trajectories/completed/2026-01/traj_prdza7a5cxp5.md +0 -32
- package/.trajectories/completed/2026-01/traj_psd9ob0j2ru3.json +0 -27
- package/.trajectories/completed/2026-01/traj_psd9ob0j2ru3.md +0 -14
- package/.trajectories/completed/2026-01/traj_pulomd3y8cvj.json +0 -77
- package/.trajectories/completed/2026-01/traj_pulomd3y8cvj.md +0 -42
- package/.trajectories/completed/2026-01/traj_qb3twvvywfwi.json +0 -77
- package/.trajectories/completed/2026-01/traj_qb3twvvywfwi.md +0 -42
- package/.trajectories/completed/2026-01/traj_qft54mi7nfor.json +0 -53
- package/.trajectories/completed/2026-01/traj_qft54mi7nfor.md +0 -32
- package/.trajectories/completed/2026-01/traj_qx9uhf8whhxo.json +0 -83
- package/.trajectories/completed/2026-01/traj_qx9uhf8whhxo.md +0 -47
- package/.trajectories/completed/2026-01/traj_rd9toccj18a0.json +0 -59
- package/.trajectories/completed/2026-01/traj_rd9toccj18a0.md +0 -37
- package/.trajectories/completed/2026-01/traj_rsavt0jipi3c.json +0 -109
- package/.trajectories/completed/2026-01/traj_rsavt0jipi3c.md +0 -56
- package/.trajectories/completed/2026-01/traj_rt4fiw3ecp50.json +0 -48
- package/.trajectories/completed/2026-01/traj_rt4fiw3ecp50.md +0 -16
- package/.trajectories/completed/2026-01/traj_st8j35b0hrlc.json +0 -59
- package/.trajectories/completed/2026-01/traj_st8j35b0hrlc.md +0 -37
- package/.trajectories/completed/2026-01/traj_t1yy8m7hbuxp.json +0 -53
- package/.trajectories/completed/2026-01/traj_t1yy8m7hbuxp.md +0 -32
- package/.trajectories/completed/2026-01/traj_tmux_orchestrator_analysis.json +0 -84
- package/.trajectories/completed/2026-01/traj_tmux_orchestrator_analysis.md +0 -109
- package/.trajectories/completed/2026-01/traj_u9n9eqasw16k.json +0 -53
- package/.trajectories/completed/2026-01/traj_u9n9eqasw16k.md +0 -32
- package/.trajectories/completed/2026-01/traj_ub8csuv3lcv4.json +0 -53
- package/.trajectories/completed/2026-01/traj_ub8csuv3lcv4.md +0 -32
- package/.trajectories/completed/2026-01/traj_uc29tlso8i9s.json +0 -186
- package/.trajectories/completed/2026-01/traj_uc29tlso8i9s.md +0 -86
- package/.trajectories/completed/2026-01/traj_ui9b4tqxoa7j.json +0 -77
- package/.trajectories/completed/2026-01/traj_ui9b4tqxoa7j.md +0 -42
- package/.trajectories/completed/2026-01/traj_v87hypnongqx.json +0 -71
- package/.trajectories/completed/2026-01/traj_v87hypnongqx.md +0 -42
- package/.trajectories/completed/2026-01/traj_v9dkdoxylyid.json +0 -89
- package/.trajectories/completed/2026-01/traj_v9dkdoxylyid.md +0 -47
- package/.trajectories/completed/2026-01/traj_wkp2fgzdyinb.json +0 -53
- package/.trajectories/completed/2026-01/traj_wkp2fgzdyinb.md +0 -32
- package/.trajectories/completed/2026-01/traj_x14t8w8rn7xg.json +0 -20
- package/.trajectories/completed/2026-01/traj_x14t8w8rn7xg.md +0 -6
- package/.trajectories/completed/2026-01/traj_x721m1j9rzup.json +0 -113
- package/.trajectories/completed/2026-01/traj_x721m1j9rzup.md +0 -57
- package/.trajectories/completed/2026-01/traj_xjqvmep5ed3h.json +0 -61
- package/.trajectories/completed/2026-01/traj_xjqvmep5ed3h.md +0 -36
- package/.trajectories/completed/2026-01/traj_xnwbznkvv8ua.json +0 -175
- package/.trajectories/completed/2026-01/traj_xnwbznkvv8ua.md +0 -82
- package/.trajectories/completed/2026-01/traj_xy9vifpqet80.json +0 -65
- package/.trajectories/completed/2026-01/traj_xy9vifpqet80.md +0 -37
- package/.trajectories/completed/2026-01/traj_y7aiwijyfmmv.json +0 -49
- package/.trajectories/completed/2026-01/traj_y7aiwijyfmmv.md +0 -31
- package/.trajectories/completed/2026-01/traj_y7n6hfbf7dmg.json +0 -49
- package/.trajectories/completed/2026-01/traj_y7n6hfbf7dmg.md +0 -31
- package/.trajectories/completed/2026-01/traj_ysjc8zaeqtd3.json +0 -47
- package/.trajectories/completed/2026-01/traj_ysjc8zaeqtd3.md +0 -32
- package/.trajectories/completed/2026-01/traj_yvdadtvdgnz3.json +0 -59
- package/.trajectories/completed/2026-01/traj_yvdadtvdgnz3.md +0 -37
- package/.trajectories/completed/2026-01/traj_yvfkwnkdiso2.json +0 -49
- package/.trajectories/completed/2026-01/traj_yvfkwnkdiso2.md +0 -31
- package/.trajectories/completed/2026-01/traj_z0vcw1wrzide.json +0 -53
- package/.trajectories/completed/2026-01/traj_z0vcw1wrzide.md +0 -32
- package/.trajectories/consolidate-settings-panel.md +0 -24
- package/.trajectories/gh-cli-user-token.md +0 -26
- 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
|
-
|
|
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
|
-
|
|
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
|
|
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);
|
package/dist/wrapper/client.d.ts
CHANGED
|
@@ -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;
|