agent-relay 1.0.21 → 1.1.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 (283) hide show
  1. package/dist/bridge/shadow-cli.d.ts +17 -0
  2. package/dist/bridge/shadow-cli.d.ts.map +1 -0
  3. package/dist/bridge/shadow-cli.js +75 -0
  4. package/dist/bridge/shadow-cli.js.map +1 -0
  5. package/dist/bridge/shadow-config.d.ts +87 -0
  6. package/dist/bridge/shadow-config.d.ts.map +1 -0
  7. package/dist/bridge/shadow-config.js +134 -0
  8. package/dist/bridge/shadow-config.js.map +1 -0
  9. package/dist/bridge/spawner.d.ts +15 -1
  10. package/dist/bridge/spawner.d.ts.map +1 -1
  11. package/dist/bridge/spawner.js +164 -4
  12. package/dist/bridge/spawner.js.map +1 -1
  13. package/dist/bridge/types.d.ts +55 -0
  14. package/dist/bridge/types.d.ts.map +1 -1
  15. package/dist/cli/index.js +796 -11
  16. package/dist/cli/index.js.map +1 -1
  17. package/dist/cloud/api/auth.d.ts +19 -0
  18. package/dist/cloud/api/auth.d.ts.map +1 -0
  19. package/dist/cloud/api/auth.js +216 -0
  20. package/dist/cloud/api/auth.js.map +1 -0
  21. package/dist/cloud/api/billing.d.ts +17 -0
  22. package/dist/cloud/api/billing.d.ts.map +1 -0
  23. package/dist/cloud/api/billing.js +353 -0
  24. package/dist/cloud/api/billing.js.map +1 -0
  25. package/dist/cloud/api/coordinators.d.ts +8 -0
  26. package/dist/cloud/api/coordinators.d.ts.map +1 -0
  27. package/dist/cloud/api/coordinators.js +347 -0
  28. package/dist/cloud/api/coordinators.js.map +1 -0
  29. package/dist/cloud/api/daemons.d.ts +12 -0
  30. package/dist/cloud/api/daemons.d.ts.map +1 -0
  31. package/dist/cloud/api/daemons.js +320 -0
  32. package/dist/cloud/api/daemons.js.map +1 -0
  33. package/dist/cloud/api/middleware/planLimits.d.ts +36 -0
  34. package/dist/cloud/api/middleware/planLimits.d.ts.map +1 -0
  35. package/dist/cloud/api/middleware/planLimits.js +164 -0
  36. package/dist/cloud/api/middleware/planLimits.js.map +1 -0
  37. package/dist/cloud/api/onboarding.d.ts +8 -0
  38. package/dist/cloud/api/onboarding.d.ts.map +1 -0
  39. package/dist/cloud/api/onboarding.js +407 -0
  40. package/dist/cloud/api/onboarding.js.map +1 -0
  41. package/dist/cloud/api/providers.d.ts +7 -0
  42. package/dist/cloud/api/providers.d.ts.map +1 -0
  43. package/dist/cloud/api/providers.js +435 -0
  44. package/dist/cloud/api/providers.js.map +1 -0
  45. package/dist/cloud/api/repos.d.ts +7 -0
  46. package/dist/cloud/api/repos.d.ts.map +1 -0
  47. package/dist/cloud/api/repos.js +314 -0
  48. package/dist/cloud/api/repos.js.map +1 -0
  49. package/dist/cloud/api/teams.d.ts +7 -0
  50. package/dist/cloud/api/teams.d.ts.map +1 -0
  51. package/dist/cloud/api/teams.js +279 -0
  52. package/dist/cloud/api/teams.js.map +1 -0
  53. package/dist/cloud/api/usage.d.ts +7 -0
  54. package/dist/cloud/api/usage.d.ts.map +1 -0
  55. package/dist/cloud/api/usage.js +98 -0
  56. package/dist/cloud/api/usage.js.map +1 -0
  57. package/dist/cloud/api/workspaces.d.ts +7 -0
  58. package/dist/cloud/api/workspaces.d.ts.map +1 -0
  59. package/dist/cloud/api/workspaces.js +510 -0
  60. package/dist/cloud/api/workspaces.js.map +1 -0
  61. package/dist/cloud/billing/index.d.ts +9 -0
  62. package/dist/cloud/billing/index.d.ts.map +1 -0
  63. package/dist/cloud/billing/index.js +9 -0
  64. package/dist/cloud/billing/index.js.map +1 -0
  65. package/dist/cloud/billing/plans.d.ts +39 -0
  66. package/dist/cloud/billing/plans.d.ts.map +1 -0
  67. package/dist/cloud/billing/plans.js +232 -0
  68. package/dist/cloud/billing/plans.js.map +1 -0
  69. package/dist/cloud/billing/service.d.ts +80 -0
  70. package/dist/cloud/billing/service.d.ts.map +1 -0
  71. package/dist/cloud/billing/service.js +388 -0
  72. package/dist/cloud/billing/service.js.map +1 -0
  73. package/dist/cloud/billing/types.d.ts +135 -0
  74. package/dist/cloud/billing/types.d.ts.map +1 -0
  75. package/dist/cloud/billing/types.js +7 -0
  76. package/dist/cloud/billing/types.js.map +1 -0
  77. package/dist/cloud/config.d.ts +59 -0
  78. package/dist/cloud/config.d.ts.map +1 -0
  79. package/dist/cloud/config.js +83 -0
  80. package/dist/cloud/config.js.map +1 -0
  81. package/dist/cloud/db/drizzle.d.ts +132 -0
  82. package/dist/cloud/db/drizzle.d.ts.map +1 -0
  83. package/dist/cloud/db/drizzle.js +613 -0
  84. package/dist/cloud/db/drizzle.js.map +1 -0
  85. package/dist/cloud/db/index.d.ts +30 -0
  86. package/dist/cloud/db/index.d.ts.map +1 -0
  87. package/dist/cloud/db/index.js +44 -0
  88. package/dist/cloud/db/index.js.map +1 -0
  89. package/dist/cloud/db/schema.d.ts +1792 -0
  90. package/dist/cloud/db/schema.d.ts.map +1 -0
  91. package/dist/cloud/db/schema.js +234 -0
  92. package/dist/cloud/db/schema.js.map +1 -0
  93. package/dist/cloud/index.d.ts +11 -0
  94. package/dist/cloud/index.d.ts.map +1 -0
  95. package/dist/cloud/index.js +37 -0
  96. package/dist/cloud/index.js.map +1 -0
  97. package/dist/cloud/provisioner/index.d.ts +51 -0
  98. package/dist/cloud/provisioner/index.d.ts.map +1 -0
  99. package/dist/cloud/provisioner/index.js +676 -0
  100. package/dist/cloud/provisioner/index.js.map +1 -0
  101. package/dist/cloud/server.d.ts +16 -0
  102. package/dist/cloud/server.d.ts.map +1 -0
  103. package/dist/cloud/server.js +190 -0
  104. package/dist/cloud/server.js.map +1 -0
  105. package/dist/cloud/services/coordinator.d.ts +62 -0
  106. package/dist/cloud/services/coordinator.d.ts.map +1 -0
  107. package/dist/cloud/services/coordinator.js +389 -0
  108. package/dist/cloud/services/coordinator.js.map +1 -0
  109. package/dist/cloud/services/planLimits.d.ts +110 -0
  110. package/dist/cloud/services/planLimits.d.ts.map +1 -0
  111. package/dist/cloud/services/planLimits.js +254 -0
  112. package/dist/cloud/services/planLimits.js.map +1 -0
  113. package/dist/cloud/vault/index.d.ts +76 -0
  114. package/dist/cloud/vault/index.d.ts.map +1 -0
  115. package/dist/cloud/vault/index.js +219 -0
  116. package/dist/cloud/vault/index.js.map +1 -0
  117. package/dist/daemon/agent-manager.d.ts +87 -0
  118. package/dist/daemon/agent-manager.d.ts.map +1 -0
  119. package/dist/daemon/agent-manager.js +412 -0
  120. package/dist/daemon/agent-manager.js.map +1 -0
  121. package/dist/daemon/agent-registry.d.ts +2 -0
  122. package/dist/daemon/agent-registry.d.ts.map +1 -1
  123. package/dist/daemon/agent-registry.js +3 -0
  124. package/dist/daemon/agent-registry.js.map +1 -1
  125. package/dist/daemon/api.d.ts +69 -0
  126. package/dist/daemon/api.d.ts.map +1 -0
  127. package/dist/daemon/api.js +425 -0
  128. package/dist/daemon/api.js.map +1 -0
  129. package/dist/daemon/cloud-sync.d.ts +101 -0
  130. package/dist/daemon/cloud-sync.d.ts.map +1 -0
  131. package/dist/daemon/cloud-sync.js +261 -0
  132. package/dist/daemon/cloud-sync.js.map +1 -0
  133. package/dist/daemon/index.d.ts +4 -0
  134. package/dist/daemon/index.d.ts.map +1 -1
  135. package/dist/daemon/index.js +6 -0
  136. package/dist/daemon/index.js.map +1 -1
  137. package/dist/daemon/orchestrator.d.ts +155 -0
  138. package/dist/daemon/orchestrator.d.ts.map +1 -0
  139. package/dist/daemon/orchestrator.js +736 -0
  140. package/dist/daemon/orchestrator.js.map +1 -0
  141. package/dist/daemon/router.d.ts +24 -0
  142. package/dist/daemon/router.d.ts.map +1 -1
  143. package/dist/daemon/router.js +71 -1
  144. package/dist/daemon/router.js.map +1 -1
  145. package/dist/daemon/server.d.ts +37 -0
  146. package/dist/daemon/server.d.ts.map +1 -1
  147. package/dist/daemon/server.js +191 -16
  148. package/dist/daemon/server.js.map +1 -1
  149. package/dist/daemon/types.d.ts +127 -0
  150. package/dist/daemon/types.d.ts.map +1 -0
  151. package/dist/daemon/types.js +6 -0
  152. package/dist/daemon/types.js.map +1 -0
  153. package/dist/daemon/workspace-manager.d.ts +75 -0
  154. package/dist/daemon/workspace-manager.d.ts.map +1 -0
  155. package/dist/daemon/workspace-manager.js +289 -0
  156. package/dist/daemon/workspace-manager.js.map +1 -0
  157. package/dist/dashboard/out/404.html +1 -1
  158. package/dist/dashboard/out/_next/static/chunks/693-7b3301d8f6bc5014.js +1 -0
  159. package/dist/dashboard/out/_next/static/chunks/713-f78477eb185f1f4d.js +1 -0
  160. package/dist/dashboard/out/_next/static/chunks/766-e53e1cfe39b0b5b5.js +1 -0
  161. package/dist/dashboard/out/_next/static/chunks/900-037c64bfd797fb2a.js +1 -0
  162. package/dist/dashboard/out/_next/static/chunks/app/app/page-e3d9e1f4466b9bae.js +1 -0
  163. package/dist/dashboard/out/_next/static/chunks/app/history/page-b6edd4dde8d08194.js +1 -0
  164. package/dist/dashboard/out/_next/static/chunks/app/layout-2433bb48965f4333.js +1 -0
  165. package/dist/dashboard/out/_next/static/chunks/app/metrics/page-e68825a81db67ba1.js +1 -0
  166. package/dist/dashboard/out/_next/static/chunks/app/page-cc108bf68c8a657f.js +1 -0
  167. package/dist/dashboard/out/_next/static/chunks/app/pricing/page-d80e03a5297f95b6.js +1 -0
  168. package/dist/dashboard/out/_next/static/chunks/main-app-5d692157a8eb1fd9.js +1 -0
  169. package/dist/dashboard/out/_next/static/chunks/{main-e0a1f53fe0617a63.js → main-c2f423b9c9f4591b.js} +1 -1
  170. package/dist/dashboard/out/_next/static/chunks/{webpack-c81f7fd28659d64f.js → webpack-a5acc2831d094776.js} +1 -1
  171. package/dist/dashboard/out/_next/static/css/79b80143647a07d7.css +1 -0
  172. package/dist/dashboard/out/_next/static/css/8cf277370ad48cfe.css +1 -0
  173. package/dist/dashboard/out/alt-logos/agent-relay-logo-128.png +0 -0
  174. package/dist/dashboard/out/alt-logos/agent-relay-logo-256.png +0 -0
  175. package/dist/dashboard/out/alt-logos/agent-relay-logo-32.png +0 -0
  176. package/dist/dashboard/out/alt-logos/agent-relay-logo-512.png +0 -0
  177. package/dist/dashboard/out/alt-logos/agent-relay-logo-64.png +0 -0
  178. package/dist/dashboard/out/alt-logos/agent-relay-logo.svg +45 -0
  179. package/dist/dashboard/out/alt-logos/logo.svg +38 -0
  180. package/dist/dashboard/out/alt-logos/monogram-logo-128.png +0 -0
  181. package/dist/dashboard/out/alt-logos/monogram-logo-256.png +0 -0
  182. package/dist/dashboard/out/alt-logos/monogram-logo-32.png +0 -0
  183. package/dist/dashboard/out/alt-logos/monogram-logo-512.png +0 -0
  184. package/dist/dashboard/out/alt-logos/monogram-logo-64.png +0 -0
  185. package/dist/dashboard/out/alt-logos/monogram-logo.svg +38 -0
  186. package/dist/dashboard/out/app.html +14 -0
  187. package/dist/dashboard/out/app.txt +7 -0
  188. package/dist/dashboard/out/history.html +1 -0
  189. package/dist/dashboard/out/history.txt +7 -0
  190. package/dist/dashboard/out/index.html +1 -1
  191. package/dist/dashboard/out/index.txt +2 -2
  192. package/dist/dashboard/out/metrics.html +1 -515
  193. package/dist/dashboard/out/metrics.txt +2 -2
  194. package/dist/dashboard/out/pricing.html +13 -0
  195. package/dist/dashboard/out/pricing.txt +7 -0
  196. package/dist/dashboard-server/metrics.d.ts.map +1 -1
  197. package/dist/dashboard-server/metrics.js +3 -2
  198. package/dist/dashboard-server/metrics.js.map +1 -1
  199. package/dist/dashboard-server/server.d.ts.map +1 -1
  200. package/dist/dashboard-server/server.js +1279 -56
  201. package/dist/dashboard-server/server.js.map +1 -1
  202. package/dist/protocol/types.d.ts +10 -1
  203. package/dist/protocol/types.d.ts.map +1 -1
  204. package/dist/resiliency/context-persistence.d.ts +140 -0
  205. package/dist/resiliency/context-persistence.d.ts.map +1 -0
  206. package/dist/resiliency/context-persistence.js +397 -0
  207. package/dist/resiliency/context-persistence.js.map +1 -0
  208. package/dist/resiliency/health-monitor.d.ts +97 -0
  209. package/dist/resiliency/health-monitor.d.ts.map +1 -0
  210. package/dist/resiliency/health-monitor.js +291 -0
  211. package/dist/resiliency/health-monitor.js.map +1 -0
  212. package/dist/resiliency/index.d.ts +63 -0
  213. package/dist/resiliency/index.d.ts.map +1 -0
  214. package/dist/resiliency/index.js +63 -0
  215. package/dist/resiliency/index.js.map +1 -0
  216. package/dist/resiliency/logger.d.ts +114 -0
  217. package/dist/resiliency/logger.d.ts.map +1 -0
  218. package/dist/resiliency/logger.js +250 -0
  219. package/dist/resiliency/logger.js.map +1 -0
  220. package/dist/resiliency/metrics.d.ts +115 -0
  221. package/dist/resiliency/metrics.d.ts.map +1 -0
  222. package/dist/resiliency/metrics.js +239 -0
  223. package/dist/resiliency/metrics.js.map +1 -0
  224. package/dist/resiliency/provider-context.d.ts +100 -0
  225. package/dist/resiliency/provider-context.d.ts.map +1 -0
  226. package/dist/resiliency/provider-context.js +360 -0
  227. package/dist/resiliency/provider-context.js.map +1 -0
  228. package/dist/resiliency/supervisor.d.ts +109 -0
  229. package/dist/resiliency/supervisor.d.ts.map +1 -0
  230. package/dist/resiliency/supervisor.js +337 -0
  231. package/dist/resiliency/supervisor.js.map +1 -0
  232. package/dist/storage/adapter.d.ts +2 -0
  233. package/dist/storage/adapter.d.ts.map +1 -1
  234. package/dist/storage/adapter.js +12 -2
  235. package/dist/storage/adapter.js.map +1 -1
  236. package/dist/storage/sqlite-adapter.d.ts.map +1 -1
  237. package/dist/storage/sqlite-adapter.js +18 -14
  238. package/dist/storage/sqlite-adapter.js.map +1 -1
  239. package/dist/utils/index.d.ts +1 -0
  240. package/dist/utils/index.d.ts.map +1 -1
  241. package/dist/utils/index.js +1 -0
  242. package/dist/utils/index.js.map +1 -1
  243. package/dist/utils/logger.d.ts +40 -0
  244. package/dist/utils/logger.d.ts.map +1 -0
  245. package/dist/utils/logger.js +84 -0
  246. package/dist/utils/logger.js.map +1 -0
  247. package/dist/wrapper/client.d.ts +16 -1
  248. package/dist/wrapper/client.d.ts.map +1 -1
  249. package/dist/wrapper/client.js +32 -1
  250. package/dist/wrapper/client.js.map +1 -1
  251. package/dist/wrapper/parser.d.ts +3 -0
  252. package/dist/wrapper/parser.d.ts.map +1 -1
  253. package/dist/wrapper/parser.js +121 -18
  254. package/dist/wrapper/parser.js.map +1 -1
  255. package/dist/wrapper/pty-wrapper.d.ts +28 -1
  256. package/dist/wrapper/pty-wrapper.d.ts.map +1 -1
  257. package/dist/wrapper/pty-wrapper.js +166 -30
  258. package/dist/wrapper/pty-wrapper.js.map +1 -1
  259. package/dist/wrapper/tmux-wrapper.d.ts +5 -0
  260. package/dist/wrapper/tmux-wrapper.d.ts.map +1 -1
  261. package/dist/wrapper/tmux-wrapper.js +58 -18
  262. package/dist/wrapper/tmux-wrapper.js.map +1 -1
  263. package/docs/CLOUD-ARCHITECTURE.md +652 -0
  264. package/docs/CLOUD-ONBOARDING-DESIGN.md +1983 -0
  265. package/docs/TESTING_PRESENCE_FEATURES.md +327 -0
  266. package/docs/agent-relay-snippet.md +107 -4
  267. package/docs/guides/CLOUD.md +236 -0
  268. package/docs/guides/LOCAL.md +535 -0
  269. package/docs/guides/SELF-HOSTED.md +494 -0
  270. package/docs/proposals/shadow-as-subagent.md +765 -0
  271. package/docs/proposals/slack-bot-integration.md +1457 -0
  272. package/package.json +33 -4
  273. package/dist/dashboard/out/_next/static/chunks/app/layout-c9d8c5d95e48c6bf.js +0 -1
  274. package/dist/dashboard/out/_next/static/chunks/app/metrics/page-8aa9936bc6c771ab.js +0 -1
  275. package/dist/dashboard/out/_next/static/chunks/app/page-49055e5d2b5e34ec.js +0 -1
  276. package/dist/dashboard/out/_next/static/chunks/main-app-bae2e535de00de50.js +0 -1
  277. package/dist/dashboard/out/_next/static/css/50ed6996e3df7bdd.css +0 -1
  278. /package/dist/dashboard/out/_next/static/{gZXwjIKGDKJ0hiTH-HMeJ → 6HHWb2ZmnJ4OSm0zUP7h4}/_buildManifest.js +0 -0
  279. /package/dist/dashboard/out/_next/static/{gZXwjIKGDKJ0hiTH-HMeJ → 6HHWb2ZmnJ4OSm0zUP7h4}/_ssgManifest.js +0 -0
  280. /package/dist/dashboard/out/_next/static/chunks/{117-3bef7b19f3e60751.js → 117-b2cd8d6485aacf2b.js} +0 -0
  281. /package/dist/dashboard/out/_next/static/chunks/{648-6cf686106c891ad3.js → 648-8f3f26864ce515e5.js} +0 -0
  282. /package/dist/dashboard/out/_next/static/chunks/app/_not-found/{page-8ff6572bc7c9bc61.js → page-0b990dbb71d72a98.js} +0 -0
  283. /package/dist/dashboard/out/_next/static/chunks/{fd9d1056-26bd8d656b496dba.js → fd9d1056-bf46c09eb57e019c.js} +0 -0
@@ -0,0 +1,327 @@
1
+ # Manual Testing Guide: Presence & Cloud Features
2
+
3
+ This document provides step-by-step testing procedures for the presence indicators, typing indicators, and user profile features in cloud mode.
4
+
5
+ ## Prerequisites
6
+
7
+ 1. **Cloud Mode Setup**: You need access to the cloud-hosted dashboard with GitHub OAuth authentication.
8
+ 2. **Multiple Test Accounts**: Ideally 2-3 different GitHub accounts to test multi-user features.
9
+ 3. **Multiple Browser Windows**: Use different browsers or incognito windows for simultaneous sessions.
10
+
11
+ ---
12
+
13
+ ## Test 1: GitHub Avatar & Username Display
14
+
15
+ ### Objective
16
+ Verify that logged-in users see their GitHub avatar and username in messages.
17
+
18
+ ### Steps
19
+
20
+ 1. Log in to the cloud dashboard using GitHub OAuth
21
+ 2. Send a message to any agent (e.g., `@AgentName Hello`)
22
+ 3. Observe the message in the chat
23
+
24
+ ### Expected Results
25
+
26
+ - [ ] Your GitHub avatar appears next to your sent message
27
+ - [ ] Your GitHub username appears as the sender
28
+ - [ ] Messages display "You" or your username consistently
29
+
30
+ ---
31
+
32
+ ## Test 2: Presence Indicator - Single User
33
+
34
+ ### Objective
35
+ Verify presence tracking works for a single user.
36
+
37
+ ### Steps
38
+
39
+ 1. Log in to the cloud dashboard
40
+ 2. Look at the header area below the main header
41
+
42
+ ### Expected Results
43
+
44
+ - [ ] A green dot indicator appears showing online status
45
+ - [ ] Your avatar appears in the stacked avatar row
46
+ - [ ] "1 online" text displays next to the avatars
47
+ - [ ] Clicking the indicator shows a dropdown with your username
48
+
49
+ ---
50
+
51
+ ## Test 3: Presence Indicator - Multiple Users
52
+
53
+ ### Objective
54
+ Verify multiple users can see each other's presence.
55
+
56
+ ### Steps
57
+
58
+ 1. **User A**: Log in with first GitHub account in Browser 1
59
+ 2. **User B**: Log in with second GitHub account in Browser 2 (different browser or incognito)
60
+ 3. Both users observe the presence indicator
61
+
62
+ ### Expected Results
63
+
64
+ - [ ] Both users see "2 online" in the presence indicator
65
+ - [ ] Both avatars appear in the stacked row
66
+ - [ ] Clicking shows both usernames in the dropdown
67
+ - [ ] Each user can see the other's GitHub avatar
68
+
69
+ ---
70
+
71
+ ## Test 4: Presence Join/Leave Detection
72
+
73
+ ### Objective
74
+ Verify real-time updates when users join and leave.
75
+
76
+ ### Steps
77
+
78
+ 1. **User A**: Already logged in
79
+ 2. **User B**: Log in to dashboard
80
+ 3. Observe User A's screen when User B joins
81
+ 4. **User B**: Close the browser tab
82
+ 5. Observe User A's screen after User B leaves
83
+
84
+ ### Expected Results
85
+
86
+ - [ ] User A immediately sees count increase when User B joins
87
+ - [ ] User B's avatar appears in User A's presence list
88
+ - [ ] User A immediately sees count decrease when User B leaves
89
+ - [ ] User B's avatar disappears from User A's presence list
90
+
91
+ ---
92
+
93
+ ## Test 5: Multi-Tab Support
94
+
95
+ ### Objective
96
+ Verify a user stays "online" when they have multiple tabs open.
97
+
98
+ ### Steps
99
+
100
+ 1. **User A**: Log in to dashboard in Tab 1
101
+ 2. **User A**: Open a second tab to the same dashboard (Tab 2)
102
+ 3. **User B**: Log in from a different browser
103
+ 4. Observe presence count (should show 2 users, not 3)
104
+ 5. **User A**: Close Tab 1
105
+ 6. Observe presence (User A should still show as online)
106
+ 7. **User A**: Close Tab 2
107
+ 8. Observe presence (User A should now show as offline)
108
+
109
+ ### Expected Results
110
+
111
+ - [ ] Multiple tabs from same user don't inflate online count
112
+ - [ ] Closing one tab doesn't disconnect the user
113
+ - [ ] User only shows as offline when ALL tabs are closed
114
+
115
+ ---
116
+
117
+ ## Test 6: Typing Indicator - Single User
118
+
119
+ ### Objective
120
+ Verify typing indicators appear when another user is typing.
121
+
122
+ ### Steps
123
+
124
+ 1. **User A**: Log in in Browser 1
125
+ 2. **User B**: Log in in Browser 2
126
+ 3. **User B**: Start typing a message (don't send)
127
+ 4. Observe User A's screen
128
+
129
+ ### Expected Results
130
+
131
+ - [ ] User A sees "User B is typing..." indicator
132
+ - [ ] The indicator appears below the message list, above the composer
133
+ - [ ] User B's avatar appears in the typing indicator
134
+ - [ ] Animated dots appear next to the message
135
+
136
+ ---
137
+
138
+ ## Test 7: Typing Indicator - Stop Typing
139
+
140
+ ### Objective
141
+ Verify typing indicator disappears when user stops typing.
142
+
143
+ ### Steps
144
+
145
+ 1. Continue from Test 6
146
+ 2. **User B**: Delete all text from the input field
147
+ 3. Observe User A's screen
148
+
149
+ ### Expected Results
150
+
151
+ - [ ] Typing indicator disappears within 1 second
152
+ - [ ] No residual "typing" state shown
153
+
154
+ ---
155
+
156
+ ## Test 8: Typing Indicator - Auto-Clear
157
+
158
+ ### Objective
159
+ Verify typing indicator auto-clears after 3 seconds of inactivity.
160
+
161
+ ### Steps
162
+
163
+ 1. **User A**: Log in in Browser 1
164
+ 2. **User B**: Log in in Browser 2
165
+ 3. **User B**: Type something and then stop (don't clear input)
166
+ 4. Wait 3-4 seconds
167
+
168
+ ### Expected Results
169
+
170
+ - [ ] Typing indicator disappears after ~3 seconds of no typing activity
171
+ - [ ] This prevents stale "typing" states
172
+
173
+ ---
174
+
175
+ ## Test 9: User Profile Panel - Open
176
+
177
+ ### Objective
178
+ Verify the user profile panel opens when clicking on an online user.
179
+
180
+ ### Steps
181
+
182
+ 1. Have at least 2 users logged in
183
+ 2. Click on the online users indicator
184
+ 3. Click on another user's name/avatar in the dropdown
185
+
186
+ ### Expected Results
187
+
188
+ - [ ] A slide-out panel appears from the right
189
+ - [ ] Panel shows the user's large avatar
190
+ - [ ] Panel shows the user's GitHub username
191
+ - [ ] Panel shows "Online" status with green indicator
192
+ - [ ] Panel shows "Online Since" timestamp
193
+ - [ ] Panel shows "Last Active" timestamp
194
+ - [ ] Panel shows GitHub link
195
+
196
+ ---
197
+
198
+ ## Test 10: User Profile Panel - Actions
199
+
200
+ ### Objective
201
+ Verify profile panel action buttons work correctly.
202
+
203
+ ### Steps
204
+
205
+ 1. Open a user's profile panel (from Test 9)
206
+ 2. Click the "Mention @username" button
207
+ 3. Close the panel and open it again
208
+ 4. Click the "View on GitHub" button
209
+
210
+ ### Expected Results
211
+
212
+ - [ ] "Mention" button closes panel (TODO: should insert @username in composer)
213
+ - [ ] "View on GitHub" opens new tab to user's GitHub profile
214
+ - [ ] GitHub profile URL is correctly formatted
215
+
216
+ ---
217
+
218
+ ## Test 11: User Profile Panel - Close Methods
219
+
220
+ ### Objective
221
+ Verify all methods of closing the profile panel work.
222
+
223
+ ### Steps
224
+
225
+ 1. Open a user's profile panel
226
+ 2. Click the X button in the panel header
227
+ 3. Open the panel again
228
+ 4. Press the Escape key
229
+ 5. Open the panel again
230
+ 6. Click outside the panel (on the backdrop)
231
+
232
+ ### Expected Results
233
+
234
+ - [ ] X button closes the panel
235
+ - [ ] Escape key closes the panel
236
+ - [ ] Clicking backdrop closes the panel
237
+
238
+ ---
239
+
240
+ ## Test 12: Human User Autocomplete
241
+
242
+ ### Objective
243
+ Verify human users appear in @ mention autocomplete.
244
+
245
+ ### Steps
246
+
247
+ 1. Have User A and User B both logged in
248
+ 2. Have User A send at least one message
249
+ 3. **User B**: Start typing `@` in the message input
250
+ 4. Observe the autocomplete dropdown
251
+
252
+ ### Expected Results
253
+
254
+ - [ ] User A appears in the autocomplete list
255
+ - [ ] Human users show with purple color and person icon
256
+ - [ ] Human users are labeled as "Human user"
257
+ - [ ] Selecting a human user inserts @username in message
258
+
259
+ ---
260
+
261
+ ## Test 13: Input Validation - Invalid Username
262
+
263
+ ### Objective
264
+ Verify the server rejects invalid usernames (security feature).
265
+
266
+ ### Steps
267
+
268
+ This test requires developer tools or a custom client:
269
+
270
+ 1. Open browser developer tools
271
+ 2. Find the presence WebSocket connection
272
+ 3. Try to send a join message with an invalid username (e.g., containing special characters)
273
+
274
+ ### Expected Results
275
+
276
+ - [ ] Server rejects the invalid username
277
+ - [ ] No error is displayed to the user (silent rejection)
278
+ - [ ] Console logs show "Invalid username rejected"
279
+
280
+ ---
281
+
282
+ ## Test 14: Security - Cannot Remove Other Users
283
+
284
+ ### Objective
285
+ Verify users cannot forcibly remove others from online list.
286
+
287
+ ### Steps
288
+
289
+ This test requires developer tools:
290
+
291
+ 1. User A and User B both logged in
292
+ 2. Using developer tools, try to send a leave message with User B's username from User A's connection
293
+
294
+ ### Expected Results
295
+
296
+ - [ ] Server rejects the leave attempt
297
+ - [ ] User B remains in the online list
298
+ - [ ] Console logs show security warning
299
+
300
+ ---
301
+
302
+ ## Troubleshooting
303
+
304
+ ### Presence Not Updating
305
+
306
+ 1. Check browser console for WebSocket errors
307
+ 2. Verify `/ws/presence` WebSocket is connected
308
+ 3. Refresh the page to reconnect
309
+
310
+ ### Typing Indicator Stuck
311
+
312
+ 1. This may indicate a WebSocket issue
313
+ 2. Typing indicators auto-clear after 3 seconds
314
+ 3. Refresh to reset
315
+
316
+ ### Profile Panel Not Opening
317
+
318
+ 1. Ensure you're clicking on a user, not just the indicator
319
+ 2. Check for JavaScript errors in console
320
+
321
+ ---
322
+
323
+ ## Notes
324
+
325
+ - All presence features require cloud mode (GitHub OAuth login)
326
+ - Local mode does not support multi-user presence
327
+ - WebSocket connections may take a moment to establish on page load
@@ -16,7 +16,25 @@ Your message here.>>>
16
16
  Broadcast to all agents.>>>
17
17
  ```
18
18
 
19
- **CRITICAL:** Always end with `>>>` at the end of the last line of content!
19
+ **CRITICAL:** Always close multi-line messages with `>>>` on its own line!
20
+
21
+ ## Communication Protocol
22
+
23
+ **ACK immediately** - When you receive a task, acknowledge it before starting work:
24
+
25
+ ```
26
+ ->relay:Sender <<<
27
+ ACK: Brief description of task received>>>
28
+ ```
29
+
30
+ Then proceed with your work. This confirms message delivery and lets the sender know you're on it.
31
+
32
+ **Report completion** - When done, send a completion message:
33
+
34
+ ```
35
+ ->relay:Sender <<<
36
+ DONE: Brief summary of what was completed>>>
37
+ ```
20
38
 
21
39
  ## Receiving Messages
22
40
 
@@ -25,6 +43,27 @@ Messages appear as:
25
43
  Relay message from Alice [abc123]: Message content here
26
44
  ```
27
45
 
46
+ ### Channel Routing (Important!)
47
+
48
+ Messages from #general (broadcast channel) include a `[#general]` indicator:
49
+ ```
50
+ Relay message from Alice [abc123] [#general]: Hello everyone!
51
+ ```
52
+
53
+ **When you see `[#general]`**: Reply to `*` (broadcast), NOT to the sender directly.
54
+
55
+ ```
56
+ # Correct - responds to #general channel
57
+ ->relay:* <<<
58
+ Response to the group message.>>>
59
+
60
+ # Wrong - sends as DM to sender instead of to the channel
61
+ ->relay:Alice <<<
62
+ Response to the group message.>>>
63
+ ```
64
+
65
+ This ensures your response appears in the same channel as the original message.
66
+
28
67
  If truncated, read full message:
29
68
  ```bash
30
69
  agent-relay read abc123
@@ -39,25 +78,89 @@ Spawn workers to delegate tasks:
39
78
  ->relay:release WorkerName
40
79
  ```
41
80
 
81
+ ## Threads
82
+
83
+ Use threads to group related messages together. Thread syntax:
84
+
85
+ ```
86
+ ->relay:AgentName [thread:topic-name] <<<
87
+ Your message here.>>>
88
+ ```
89
+
90
+ **When to use threads:**
91
+ - Working on a specific issue (e.g., `[thread:agent-relay-299]`)
92
+ - Back-and-forth discussions with another agent
93
+ - Code review conversations
94
+ - Any multi-message topic you want grouped
95
+
96
+ **Examples:**
97
+
98
+ ```
99
+ ->relay:Protocol [thread:auth-feature] <<<
100
+ How should we handle token refresh?>>>
101
+
102
+ ->relay:Frontend [thread:auth-feature] <<<
103
+ Use a 401 interceptor that auto-refreshes.>>>
104
+
105
+ ->relay:Reviewer [thread:pr-123] <<<
106
+ Please review src/auth/*.ts>>>
107
+
108
+ ->relay:Developer [thread:pr-123] <<<
109
+ LGTM, approved!>>>
110
+ ```
111
+
112
+ Thread messages appear grouped in the dashboard with reply counts.
113
+
42
114
  ## Common Patterns
43
115
 
44
116
  ```
45
- ->relay:* <<<
46
- STATUS: Starting work on auth module>>>
117
+ ->relay:Lead <<<
118
+ ACK: Starting /api/register implementation>>>
47
119
 
48
120
  ->relay:* <<<
121
+ STATUS: Working on auth module>>>
122
+
123
+ ->relay:Lead <<<
49
124
  DONE: Auth module complete>>>
50
125
 
51
126
  ->relay:Developer <<<
52
127
  TASK: Implement /api/register>>>
53
128
 
54
- ->relay:Reviewer <<<
129
+ ->relay:Reviewer [thread:code-review-auth] <<<
55
130
  REVIEW: Please check src/auth/*.ts>>>
56
131
 
57
132
  ->relay:Architect <<<
58
133
  QUESTION: JWT or sessions?>>>
59
134
  ```
60
135
 
136
+ ## Cross-Project Messaging
137
+
138
+ When running in bridge mode (multiple projects connected), use `project:agent` format:
139
+
140
+ ```
141
+ ->relay:frontend:Designer <<<
142
+ Please update the login UI for the new auth flow>>>
143
+
144
+ ->relay:backend:lead <<<
145
+ API question - should we use REST or GraphQL?>>>
146
+
147
+ ->relay:shared-lib:* <<<
148
+ New utility functions available, please pull latest>>>
149
+ ```
150
+
151
+ **Format:** `->relay:project-id:agent-name`
152
+
153
+ **Special targets:**
154
+ - `->relay:project:lead` - Message the lead agent of that project
155
+ - `->relay:project:*` - Broadcast to all agents in that project
156
+ - `->relay:*:*` - Broadcast to ALL agents in ALL projects
157
+
158
+ **Cross-project threads:**
159
+ ```
160
+ ->relay:frontend:Designer [thread:auth-feature] <<<
161
+ UI mockups ready for review>>>
162
+ ```
163
+
61
164
  ## Rules
62
165
 
63
166
  - Pattern must be at line start (whitespace OK)
@@ -0,0 +1,236 @@
1
+ # Agent Relay Cloud
2
+
3
+ Get started with [agent-relay.com](https://agent-relay.com) - the fully managed way to orchestrate AI agents across your repositories.
4
+
5
+ ## Overview
6
+
7
+ Agent Relay Cloud handles everything for you:
8
+ - Automatic server provisioning
9
+ - GitHub repository integration
10
+ - Multi-provider agent authentication (Claude, Codex, Gemini)
11
+ - Team management and collaboration
12
+ - Centralized dashboard and logs
13
+
14
+ **No servers to manage. No infrastructure to maintain.**
15
+
16
+ ## Getting Started
17
+
18
+ ### 1. Sign Up
19
+
20
+ Visit [agent-relay.com](https://agent-relay.com) and click **Continue with GitHub**.
21
+
22
+ This:
23
+ - Creates your Agent Relay account
24
+ - Automatically connects GitHub Copilot
25
+ - Gives us access to list your repositories
26
+
27
+ ### 2. Connect Your Repositories
28
+
29
+ Select which repositories Agent Relay should manage:
30
+
31
+ 1. Browse your GitHub repos
32
+ 2. Check the ones you want to connect
33
+ 3. Click **Continue**
34
+
35
+ We'll:
36
+ - Install the Agent Relay GitHub App on selected repos
37
+ - Clone repos to your cloud workspace
38
+ - Set up webhooks for PR/issue events
39
+
40
+ ### 3. Connect AI Providers
41
+
42
+ Connect the AI providers you want to use. Click **Login with [Provider]** for each:
43
+
44
+ | Provider | What You Get |
45
+ |----------|--------------|
46
+ | **Anthropic** | Claude Code - recommended for code tasks |
47
+ | **OpenAI** | Codex and ChatGPT models |
48
+ | **Google** | Gemini - multi-modal capabilities |
49
+ | **GitHub Copilot** | Auto-connected via GitHub signup |
50
+
51
+ You authenticate with your existing provider accounts. No API keys to manage.
52
+
53
+ ### 4. Start Using Agents
54
+
55
+ Once connected, you can:
56
+
57
+ **From the Dashboard:**
58
+ - Spawn agents manually
59
+ - View real-time agent activity
60
+ - Monitor message flows between agents
61
+
62
+ **From GitHub:**
63
+ - Open a PR to trigger automatic code review
64
+ - Use `@agent-relay` in PR comments to chat with agents
65
+ - Agents respond directly in your PRs
66
+
67
+ **From the CLI:**
68
+ ```bash
69
+ # Connect your local environment to cloud
70
+ agent-relay cloud login
71
+
72
+ # Spawn a cloud agent from anywhere
73
+ agent-relay cloud spawn Alice claude "Review the auth module"
74
+ ```
75
+
76
+ ## Dashboard
77
+
78
+ Your dashboard is available at `https://app.agent-relay.com` after login.
79
+
80
+ ### Features
81
+
82
+ - **Real-time Activity Feed** - See all agent messages as they happen
83
+ - **Agent Management** - Spawn, monitor, and stop agents
84
+ - **Repository Overview** - Connected repos and their status
85
+ - **Team Settings** - Manage team members and permissions
86
+ - **Usage & Billing** - Track compute hours and plan limits
87
+
88
+ ## Plans
89
+
90
+ | Feature | Free | Pro | Team | Enterprise |
91
+ |---------|------|-----|------|------------|
92
+ | Workspaces | 1 | 5 | 20 | Unlimited |
93
+ | Repositories | 3 | 20 | 100 | Unlimited |
94
+ | Concurrent Agents | 2 | 10 | 50 | Unlimited |
95
+ | Compute Hours/Month | 10 | 100 | 500 | Unlimited |
96
+ | Coordinator Agents | - | ✓ | ✓ | ✓ |
97
+ | Priority Support | - | ✓ | ✓ | ✓ |
98
+ | SSO/SAML | - | - | - | ✓ |
99
+
100
+ See [Pricing](/pricing) for current rates.
101
+
102
+ ## Teams
103
+
104
+ ### Creating a Team
105
+
106
+ 1. Go to **Settings → Teams**
107
+ 2. Click **Create Team**
108
+ 3. Name your team and invite members
109
+
110
+ ### Team Roles
111
+
112
+ | Role | Permissions |
113
+ |------|-------------|
114
+ | **Owner** | Full access, billing, can delete team |
115
+ | **Admin** | Manage members, repos, agents |
116
+ | **Member** | Spawn agents, view activity |
117
+
118
+ ### Shared Credentials
119
+
120
+ Team admins can share provider credentials with team members, so everyone can spawn agents without individual logins.
121
+
122
+ ## Project Groups
123
+
124
+ Organize related repositories into project groups for coordinated multi-repo work.
125
+
126
+ ### Creating a Project Group
127
+
128
+ 1. Go to **Settings → Project Groups**
129
+ 2. Click **Create Group**
130
+ 3. Add repositories to the group
131
+ 4. Optionally enable a **Coordinator Agent** (Pro+)
132
+
133
+ ### Coordinator Agents
134
+
135
+ Coordinator agents (Pro plans and above) oversee work across all repos in a project group:
136
+
137
+ - Delegate tasks to repo-specific agents
138
+ - Track progress across the group
139
+ - Ensure consistency between repos
140
+
141
+ ## CLI Integration
142
+
143
+ Connect your local terminal to Agent Relay Cloud:
144
+
145
+ ```bash
146
+ # Login to cloud
147
+ agent-relay cloud login
148
+
149
+ # Check connection status
150
+ agent-relay cloud status
151
+
152
+ # List your cloud workspaces
153
+ agent-relay cloud workspaces
154
+
155
+ # Spawn a cloud agent
156
+ agent-relay cloud spawn MyAgent claude "Fix the login bug"
157
+
158
+ # View cloud agent logs
159
+ agent-relay cloud logs MyAgent
160
+ ```
161
+
162
+ ## GitHub Integration
163
+
164
+ ### Webhooks
165
+
166
+ Agent Relay listens for:
167
+ - **Pull Requests** - Automatic code review
168
+ - **Issues** - Task assignment to agents
169
+ - **Comments** - `@agent-relay` mentions
170
+
171
+ ### PR Comments
172
+
173
+ Interact with agents directly in PRs:
174
+
175
+ ```
176
+ @agent-relay review this PR
177
+ @agent-relay explain the changes in src/auth/
178
+ @agent-relay suggest improvements
179
+ ```
180
+
181
+ ### Issue Assignment
182
+
183
+ Assign issues to agents:
184
+
185
+ ```
186
+ @agent-relay work on this issue
187
+ @agent-relay implement this feature using Claude
188
+ ```
189
+
190
+ ## Security
191
+
192
+ ### Data Protection
193
+
194
+ - All data encrypted at rest (AES-256)
195
+ - TLS 1.3 for all connections
196
+ - SOC 2 Type II compliant (Enterprise)
197
+
198
+ ### Credential Security
199
+
200
+ - OAuth tokens encrypted with per-user keys
201
+ - Automatic token refresh
202
+ - No API keys stored in plaintext
203
+
204
+ ### Workspace Isolation
205
+
206
+ - Each workspace runs in isolated containers
207
+ - No shared filesystem between users
208
+ - Network isolation between workspaces
209
+
210
+ ## Troubleshooting
211
+
212
+ ### Agent Won't Spawn
213
+
214
+ 1. Check provider connection in **Settings → Providers**
215
+ 2. Verify you haven't exceeded plan limits
216
+ 3. Check the activity log for errors
217
+
218
+ ### GitHub Webhooks Not Working
219
+
220
+ 1. Go to **Settings → Repositories**
221
+ 2. Click **Resync** on the affected repo
222
+ 3. Verify the GitHub App is still installed
223
+
224
+ ### Token Expired
225
+
226
+ If you see "Token expired" errors:
227
+
228
+ 1. Go to **Settings → Providers**
229
+ 2. Click **Reconnect** on the affected provider
230
+ 3. Re-authenticate with the provider
231
+
232
+ ## Support
233
+
234
+ - **Documentation**: [docs.agent-relay.com](https://docs.agent-relay.com)
235
+ - **GitHub Issues**: [github.com/khaliqgant/agent-relay/issues](https://github.com/khaliqgant/agent-relay/issues)
236
+ - **Email**: support@agent-relay.com (Pro+ plans)