agent-relay 1.2.3 → 1.3.1

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 (189) hide show
  1. package/.trajectories/agent-relay-322-324.md +17 -0
  2. package/.trajectories/completed/2026-01/traj_03zupyv1s7b9.json +49 -0
  3. package/.trajectories/completed/2026-01/traj_03zupyv1s7b9.md +31 -0
  4. package/.trajectories/completed/2026-01/traj_0zacdjl1g4ht.json +125 -0
  5. package/.trajectories/completed/2026-01/traj_0zacdjl1g4ht.md +62 -0
  6. package/.trajectories/completed/2026-01/traj_33iuy72sezbk.json +49 -0
  7. package/.trajectories/completed/2026-01/traj_33iuy72sezbk.md +31 -0
  8. package/.trajectories/completed/2026-01/traj_5ammh5qtvklq.json +77 -0
  9. package/.trajectories/completed/2026-01/traj_5ammh5qtvklq.md +42 -0
  10. package/.trajectories/completed/2026-01/traj_6mieijqyvaag.json +77 -0
  11. package/.trajectories/completed/2026-01/traj_6mieijqyvaag.md +42 -0
  12. package/.trajectories/completed/2026-01/traj_78ffm31jn3uk.json +77 -0
  13. package/.trajectories/completed/2026-01/traj_78ffm31jn3uk.md +42 -0
  14. package/.trajectories/completed/2026-01/traj_94gnp3k30goq.json +66 -0
  15. package/.trajectories/completed/2026-01/traj_94gnp3k30goq.md +36 -0
  16. package/.trajectories/completed/2026-01/traj_avqeghu6pz5a.json +40 -0
  17. package/.trajectories/completed/2026-01/traj_avqeghu6pz5a.md +22 -0
  18. package/.trajectories/completed/2026-01/traj_dcsp9s8y01ra.json +121 -0
  19. package/.trajectories/completed/2026-01/traj_dcsp9s8y01ra.md +29 -0
  20. package/.trajectories/completed/2026-01/traj_fhx9irlckht6.json +53 -0
  21. package/.trajectories/completed/2026-01/traj_fhx9irlckht6.md +32 -0
  22. package/.trajectories/completed/2026-01/traj_fqduidx3xbtp.json +101 -0
  23. package/.trajectories/completed/2026-01/traj_fqduidx3xbtp.md +52 -0
  24. package/.trajectories/completed/2026-01/traj_hf81ey93uz6t.json +49 -0
  25. package/.trajectories/completed/2026-01/traj_hf81ey93uz6t.md +31 -0
  26. package/.trajectories/completed/2026-01/traj_hfmki2jr9d4r.json +65 -0
  27. package/.trajectories/completed/2026-01/traj_hfmki2jr9d4r.md +37 -0
  28. package/.trajectories/completed/2026-01/traj_lq450ly148uw.json +49 -0
  29. package/.trajectories/completed/2026-01/traj_lq450ly148uw.md +31 -0
  30. package/.trajectories/completed/2026-01/traj_multi_server_arch.md +101 -0
  31. package/.trajectories/completed/2026-01/traj_psd9ob0j2ru3.json +27 -0
  32. package/.trajectories/completed/2026-01/traj_psd9ob0j2ru3.md +14 -0
  33. package/.trajectories/completed/2026-01/traj_ub8csuv3lcv4.json +53 -0
  34. package/.trajectories/completed/2026-01/traj_ub8csuv3lcv4.md +32 -0
  35. package/.trajectories/completed/2026-01/traj_uc29tlso8i9s.json +186 -0
  36. package/.trajectories/completed/2026-01/traj_uc29tlso8i9s.md +86 -0
  37. package/.trajectories/completed/2026-01/traj_ui9b4tqxoa7j.json +77 -0
  38. package/.trajectories/completed/2026-01/traj_ui9b4tqxoa7j.md +42 -0
  39. package/.trajectories/completed/2026-01/traj_v9dkdoxylyid.json +89 -0
  40. package/.trajectories/completed/2026-01/traj_v9dkdoxylyid.md +47 -0
  41. package/.trajectories/completed/2026-01/traj_xy9vifpqet80.json +65 -0
  42. package/.trajectories/completed/2026-01/traj_xy9vifpqet80.md +37 -0
  43. package/.trajectories/completed/2026-01/traj_y7aiwijyfmmv.json +49 -0
  44. package/.trajectories/completed/2026-01/traj_y7aiwijyfmmv.md +31 -0
  45. package/.trajectories/consolidate-settings-panel.md +24 -0
  46. package/.trajectories/gh-cli-user-token.md +26 -0
  47. package/.trajectories/index.json +155 -1
  48. package/deploy/workspace/codex.config.toml +15 -0
  49. package/deploy/workspace/entrypoint.sh +167 -7
  50. package/deploy/workspace/git-credential-relay +17 -2
  51. package/dist/bridge/spawner.d.ts +7 -0
  52. package/dist/bridge/spawner.js +40 -9
  53. package/dist/bridge/types.d.ts +2 -0
  54. package/dist/cli/index.js +210 -168
  55. package/dist/cloud/api/admin.d.ts +8 -0
  56. package/dist/cloud/api/admin.js +212 -0
  57. package/dist/cloud/api/auth.js +8 -0
  58. package/dist/cloud/api/billing.d.ts +0 -10
  59. package/dist/cloud/api/billing.js +248 -58
  60. package/dist/cloud/api/codex-auth-helper.d.ts +10 -4
  61. package/dist/cloud/api/codex-auth-helper.js +215 -8
  62. package/dist/cloud/api/coordinators.js +402 -0
  63. package/dist/cloud/api/daemons.js +15 -11
  64. package/dist/cloud/api/git.js +104 -17
  65. package/dist/cloud/api/github-app.js +42 -8
  66. package/dist/cloud/api/nango-auth.js +297 -16
  67. package/dist/cloud/api/onboarding.js +97 -33
  68. package/dist/cloud/api/providers.js +12 -16
  69. package/dist/cloud/api/repos.js +200 -124
  70. package/dist/cloud/api/test-helpers.js +40 -0
  71. package/dist/cloud/api/usage.js +13 -0
  72. package/dist/cloud/api/webhooks.js +1 -1
  73. package/dist/cloud/api/workspaces.d.ts +18 -0
  74. package/dist/cloud/api/workspaces.js +945 -15
  75. package/dist/cloud/config.d.ts +8 -0
  76. package/dist/cloud/config.js +15 -0
  77. package/dist/cloud/db/drizzle.d.ts +5 -2
  78. package/dist/cloud/db/drizzle.js +27 -20
  79. package/dist/cloud/db/schema.d.ts +19 -51
  80. package/dist/cloud/db/schema.js +5 -4
  81. package/dist/cloud/index.d.ts +0 -1
  82. package/dist/cloud/index.js +0 -1
  83. package/dist/cloud/provisioner/index.d.ts +93 -1
  84. package/dist/cloud/provisioner/index.js +608 -63
  85. package/dist/cloud/server.js +156 -16
  86. package/dist/cloud/services/compute-enforcement.d.ts +57 -0
  87. package/dist/cloud/services/compute-enforcement.js +175 -0
  88. package/dist/cloud/services/index.d.ts +2 -0
  89. package/dist/cloud/services/index.js +4 -0
  90. package/dist/cloud/services/intro-expiration.d.ts +55 -0
  91. package/dist/cloud/services/intro-expiration.js +211 -0
  92. package/dist/cloud/services/nango.d.ts +14 -0
  93. package/dist/cloud/services/nango.js +74 -14
  94. package/dist/cloud/services/ssh-security.d.ts +31 -0
  95. package/dist/cloud/services/ssh-security.js +63 -0
  96. package/dist/continuity/manager.d.ts +5 -0
  97. package/dist/continuity/manager.js +56 -2
  98. package/dist/daemon/api.d.ts +2 -0
  99. package/dist/daemon/api.js +214 -5
  100. package/dist/daemon/cli-auth.d.ts +13 -1
  101. package/dist/daemon/cli-auth.js +166 -47
  102. package/dist/daemon/connection.d.ts +7 -1
  103. package/dist/daemon/connection.js +15 -0
  104. package/dist/daemon/orchestrator.d.ts +2 -0
  105. package/dist/daemon/orchestrator.js +26 -0
  106. package/dist/daemon/repo-manager.d.ts +116 -0
  107. package/dist/daemon/repo-manager.js +384 -0
  108. package/dist/daemon/router.d.ts +60 -1
  109. package/dist/daemon/router.js +281 -20
  110. package/dist/daemon/user-directory.d.ts +111 -0
  111. package/dist/daemon/user-directory.js +233 -0
  112. package/dist/dashboard/out/404.html +1 -1
  113. package/dist/dashboard/out/_next/static/chunks/532-bace199897eeab37.js +9 -0
  114. package/dist/dashboard/out/_next/static/chunks/766-b54f0853794b78c3.js +1 -0
  115. package/dist/dashboard/out/_next/static/chunks/83-b51836037078006c.js +1 -0
  116. package/dist/dashboard/out/_next/static/chunks/891-6cd50de1224f70bb.js +1 -0
  117. package/dist/dashboard/out/_next/static/chunks/899-fc02ed79e3de4302.js +1 -0
  118. package/dist/dashboard/out/_next/static/chunks/app/app/onboarding/{page-3fdfa60e53f2810d.js → page-8553743baca53a00.js} +1 -1
  119. package/dist/dashboard/out/_next/static/chunks/app/app/page-c617745b81344f4f.js +1 -0
  120. package/dist/dashboard/out/_next/static/chunks/app/metrics/page-f829604fb75a831a.js +1 -0
  121. package/dist/dashboard/out/_next/static/chunks/app/{page-77e9c65420a06cfb.js → page-dc786c183425c2ac.js} +1 -1
  122. package/dist/dashboard/out/_next/static/chunks/app/providers/page-84322991d7244499.js +1 -0
  123. package/dist/dashboard/out/_next/static/chunks/app/providers/setup/[provider]/page-05606941a8e2be83.js +1 -0
  124. package/dist/dashboard/out/_next/static/chunks/{main-ed4e1fb6f29c34cf.js → main-2ee6beb2ae96d210.js} +1 -1
  125. package/dist/dashboard/out/_next/static/css/48a8fbe3e659080e.css +1 -0
  126. package/dist/dashboard/out/_next/static/css/fe4b28883eeff359.css +1 -0
  127. package/dist/dashboard/out/_next/static/sDcbGRTYLcpPvyTs_rsNb/_ssgManifest.js +1 -0
  128. package/dist/dashboard/out/app/onboarding.html +1 -1
  129. package/dist/dashboard/out/app/onboarding.txt +3 -3
  130. package/dist/dashboard/out/app.html +1 -1
  131. package/dist/dashboard/out/app.txt +3 -3
  132. package/dist/dashboard/out/apple-icon.png +0 -0
  133. package/dist/dashboard/out/connect-repos.html +1 -1
  134. package/dist/dashboard/out/connect-repos.txt +2 -2
  135. package/dist/dashboard/out/history.html +1 -1
  136. package/dist/dashboard/out/history.txt +2 -2
  137. package/dist/dashboard/out/index.html +1 -1
  138. package/dist/dashboard/out/index.txt +3 -3
  139. package/dist/dashboard/out/login.html +2 -2
  140. package/dist/dashboard/out/login.txt +2 -2
  141. package/dist/dashboard/out/metrics.html +1 -1
  142. package/dist/dashboard/out/metrics.txt +3 -3
  143. package/dist/dashboard/out/pricing.html +2 -2
  144. package/dist/dashboard/out/pricing.txt +3 -3
  145. package/dist/dashboard/out/providers/setup/claude.html +1 -0
  146. package/dist/dashboard/out/providers/setup/claude.txt +8 -0
  147. package/dist/dashboard/out/providers/setup/codex.html +1 -0
  148. package/dist/dashboard/out/providers/setup/codex.txt +8 -0
  149. package/dist/dashboard/out/providers.html +1 -1
  150. package/dist/dashboard/out/providers.txt +3 -3
  151. package/dist/dashboard/out/signup.html +2 -2
  152. package/dist/dashboard/out/signup.txt +2 -2
  153. package/dist/dashboard-server/server.js +316 -12
  154. package/dist/dashboard-server/user-bridge.d.ts +103 -0
  155. package/dist/dashboard-server/user-bridge.js +189 -0
  156. package/dist/protocol/channels.d.ts +205 -0
  157. package/dist/protocol/channels.js +154 -0
  158. package/dist/protocol/types.d.ts +13 -1
  159. package/dist/resiliency/provider-context.js +2 -0
  160. package/dist/shared/cli-auth-config.d.ts +19 -0
  161. package/dist/shared/cli-auth-config.js +58 -2
  162. package/dist/utils/agent-config.js +1 -1
  163. package/dist/wrapper/auth-detection.d.ts +49 -0
  164. package/dist/wrapper/auth-detection.js +192 -0
  165. package/dist/wrapper/base-wrapper.d.ts +153 -0
  166. package/dist/wrapper/base-wrapper.js +393 -0
  167. package/dist/wrapper/client.d.ts +7 -1
  168. package/dist/wrapper/client.js +3 -0
  169. package/dist/wrapper/index.d.ts +1 -0
  170. package/dist/wrapper/index.js +4 -3
  171. package/dist/wrapper/pty-wrapper.d.ts +62 -84
  172. package/dist/wrapper/pty-wrapper.js +154 -180
  173. package/dist/wrapper/tmux-wrapper.d.ts +41 -66
  174. package/dist/wrapper/tmux-wrapper.js +90 -134
  175. package/package.json +4 -2
  176. package/scripts/postinstall.js +11 -155
  177. package/scripts/test-interactive-terminal.sh +248 -0
  178. package/dist/cloud/vault/index.d.ts +0 -76
  179. package/dist/cloud/vault/index.js +0 -219
  180. package/dist/dashboard/out/_next/static/chunks/699-3b1cd6618a45d259.js +0 -1
  181. package/dist/dashboard/out/_next/static/chunks/724-2dae7627550ab88f.js +0 -9
  182. package/dist/dashboard/out/_next/static/chunks/766-1f2dd8cb7f766b0b.js +0 -1
  183. package/dist/dashboard/out/_next/static/chunks/app/app/page-e6381e5a6e1fbcfd.js +0 -1
  184. package/dist/dashboard/out/_next/static/chunks/app/metrics/page-67a3e98d9a43a6ed.js +0 -1
  185. package/dist/dashboard/out/_next/static/chunks/app/providers/page-e88bc117ef7671c3.js +0 -1
  186. package/dist/dashboard/out/_next/static/css/29852f26181969a0.css +0 -1
  187. package/dist/dashboard/out/_next/static/css/7c3ae9e8617d42a5.css +0 -1
  188. package/dist/dashboard/out/_next/static/wPgKJtcOmTFLpUncDg16A/_ssgManifest.js +0 -1
  189. /package/dist/dashboard/out/_next/static/{wPgKJtcOmTFLpUncDg16A → sDcbGRTYLcpPvyTs_rsNb}/_buildManifest.js +0 -0
@@ -0,0 +1,49 @@
1
+ {
2
+ "id": "traj_y7aiwijyfmmv",
3
+ "version": 1,
4
+ "task": {
5
+ "title": "Fix CLI hanging - add auth check endpoint"
6
+ },
7
+ "status": "completed",
8
+ "startedAt": "2026-01-07T10:19:49.851Z",
9
+ "agents": [
10
+ {
11
+ "name": "khaliqgant",
12
+ "role": "lead",
13
+ "joinedAt": "2026-01-07T10:19:49.852Z"
14
+ }
15
+ ],
16
+ "chapters": [
17
+ {
18
+ "id": "chap_brksv0oi98s5",
19
+ "title": "Work",
20
+ "agentName": "default",
21
+ "startedAt": "2026-01-07T10:19:49.908Z",
22
+ "events": [
23
+ {
24
+ "ts": 1767781189908,
25
+ "type": "decision",
26
+ "content": "Add /auth/cli/openai/check endpoint to workspace daemon: Add /auth/cli/openai/check endpoint to workspace daemon",
27
+ "raw": {
28
+ "question": "Add /auth/cli/openai/check endpoint to workspace daemon",
29
+ "chosen": "Add /auth/cli/openai/check endpoint to workspace daemon",
30
+ "alternatives": [],
31
+ "reasoning": "CLI was hanging because it polls this endpoint to detect auth completion, but it didn't exist. Added check for ~/.codex/auth.json credentials file."
32
+ },
33
+ "significance": "high"
34
+ }
35
+ ],
36
+ "endedAt": "2026-01-07T10:19:49.966Z"
37
+ }
38
+ ],
39
+ "commits": [],
40
+ "filesChanged": [],
41
+ "projectId": "/Users/khaliqgant/Projects/agent-workforce/relay",
42
+ "tags": [],
43
+ "completedAt": "2026-01-07T10:19:49.966Z",
44
+ "retrospective": {
45
+ "summary": "Added missing /auth/cli/openai/check endpoint to workspace daemon server.ts. CLI polls this to detect when Codex OAuth completes.",
46
+ "approach": "Standard approach",
47
+ "confidence": 0.9
48
+ }
49
+ }
@@ -0,0 +1,31 @@
1
+ # Trajectory: Fix CLI hanging - add auth check endpoint
2
+
3
+ > **Status:** ✅ Completed
4
+ > **Confidence:** 90%
5
+ > **Started:** January 7, 2026 at 11:19 AM
6
+ > **Completed:** January 7, 2026 at 11:19 AM
7
+
8
+ ---
9
+
10
+ ## Summary
11
+
12
+ Added missing /auth/cli/openai/check endpoint to workspace daemon server.ts. CLI polls this to detect when Codex OAuth completes.
13
+
14
+ **Approach:** Standard approach
15
+
16
+ ---
17
+
18
+ ## Key Decisions
19
+
20
+ ### Add /auth/cli/openai/check endpoint to workspace daemon
21
+ - **Chose:** Add /auth/cli/openai/check endpoint to workspace daemon
22
+ - **Reasoning:** CLI was hanging because it polls this endpoint to detect auth completion, but it didn't exist. Added check for ~/.codex/auth.json credentials file.
23
+
24
+ ---
25
+
26
+ ## Chapters
27
+
28
+ ### 1. Work
29
+ *Agent: default*
30
+
31
+ - Add /auth/cli/openai/check endpoint to workspace daemon: Add /auth/cli/openai/check endpoint to workspace daemon
@@ -0,0 +1,24 @@
1
+ # Trajectory: Consolidate settings panel and create PR
2
+
3
+ > **Status:** ✅ Completed
4
+ > **Confidence:** 90%
5
+ > **Started:** January 6, 2026 at 12:40 PM
6
+ > **Completed:** January 6, 2026 at 12:41 PM
7
+
8
+ ---
9
+
10
+ ## Summary
11
+
12
+ Settings panel consolidation PR exists as #78. Pushed additional commit (7429eb7) with types.ts. GitHub auth working via git-credential-relay helper.
13
+
14
+ **Approach:** Standard approach
15
+
16
+ ---
17
+
18
+ ## Chapters
19
+
20
+ ### 1. Initial work
21
+ *Agent: Fullstack*
22
+
23
+ - PR may already exist from previous session, branch was pushed successfully: PR may already exist from previous session, branch was pushed successfully
24
+
@@ -0,0 +1,26 @@
1
+ # Trajectory: Investigate gh CLI auth solution for agents
2
+
3
+ > **Status:** ✅ Completed
4
+ > **Confidence:** 85%
5
+ > **Started:** January 6, 2026 at 12:44 PM
6
+ > **Completed:** January 6, 2026 at 01:10 PM
7
+
8
+ ---
9
+
10
+ ## Summary
11
+
12
+ Created PR #79 to fix gh CLI auth. Updates git.ts to use user login connection (GITHUB_USER) for userToken. Also created ~/.local/bin/gh-relay wrapper that uses userToken with GH_TOKEN env var.
13
+
14
+ **Approach:** Standard approach
15
+
16
+ ---
17
+
18
+ ## Chapters
19
+
20
+ ### 1. Initial work
21
+ *Agent: Fullstack*
22
+
23
+ - API currently returns same token for both 'token' and 'userToken' - both are GitHub App installation tokens (ghs_*): API currently returns same token for both 'token' and 'userToken' - both are GitHub App installation tokens (ghs_*)
24
+ - Issue identified: getGithubUserOAuthToken returns installation token (ghs_*) instead of user OAuth token (gho_*). gh CLI needs user OAuth token for full API access.: Issue identified: getGithubUserOAuthToken returns installation token (ghs_*) instead of user OAuth token (gho_*). gh CLI needs user OAuth token for full API access.
25
+ - API still returns same token - code change not deployed yet. Need to verify user has login connection (users.nangoConnectionId) and that GITHUB_USER integration returns gho_* OAuth token: API still returns same token - code change not deployed yet. Need to verify user has login connection (users.nangoConnectionId) and that GITHUB_USER integration returns gho_* OAuth token
26
+
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "version": 1,
3
- "lastUpdated": "2026-01-05T21:29:51.202Z",
3
+ "lastUpdated": "2026-01-07T14:19:04.152Z",
4
4
  "trajectories": {
5
5
  "traj_ozd98si6a7ns": {
6
6
  "title": "Fix thinking indicator showing on all messages",
@@ -309,6 +309,160 @@
309
309
  "startedAt": "2026-01-05T20:14:01.563Z",
310
310
  "completedAt": "2026-01-05T20:14:01.617Z",
311
311
  "path": "/Users/khaliqgant/Projects/agent-workforce/relay/.trajectories/completed/2026-01/traj_hhxte7w4gjjx.json"
312
+ },
313
+ "traj_fhx9irlckht6": {
314
+ "title": "Spec and plan: Auto workspace access + Human-to-human messaging",
315
+ "status": "completed",
316
+ "startedAt": "2026-01-05T23:10:52.953Z",
317
+ "completedAt": "2026-01-05T23:15:32.933Z",
318
+ "path": "/Users/khaliqgant/Projects/agent-workforce/relay/.trajectories/completed/2026-01/traj_fhx9irlckht6.json"
319
+ },
320
+ "traj_avqeghu6pz5a": {
321
+ "title": "Fix gh CLI authentication in workspace containers",
322
+ "status": "completed",
323
+ "startedAt": "2026-01-05T23:14:00.755Z",
324
+ "completedAt": "2026-01-05T23:44:34.432Z",
325
+ "path": "/workspace/relay/.trajectories/completed/2026-01/traj_avqeghu6pz5a.json"
326
+ },
327
+ "traj_hfmki2jr9d4r": {
328
+ "title": "Implement auto workspace access + mobile UI fixes",
329
+ "status": "completed",
330
+ "startedAt": "2026-01-05T23:45:03.470Z",
331
+ "completedAt": "2026-01-06T00:03:49.311Z",
332
+ "path": "/workspace/relay/.trajectories/completed/2026-01/traj_hfmki2jr9d4r.json"
333
+ },
334
+ "traj_5ammh5qtvklq": {
335
+ "title": "Evaluate Fly.io Sprites and implement workspace resilience",
336
+ "status": "completed",
337
+ "startedAt": "2026-01-06T06:24:17.361Z",
338
+ "completedAt": "2026-01-06T06:25:03.223Z",
339
+ "path": "/home/user/relay/.trajectories/completed/2026-01/traj_5ammh5qtvklq.json"
340
+ },
341
+ "traj_ui9b4tqxoa7j": {
342
+ "title": "Fix agent token fetch with improved error handling",
343
+ "status": "completed",
344
+ "startedAt": "2026-01-06T08:24:36.222Z",
345
+ "completedAt": "2026-01-06T08:25:20.777Z",
346
+ "path": "/home/user/relay/.trajectories/completed/2026-01/traj_ui9b4tqxoa7j.json"
347
+ },
348
+ "traj_xy9vifpqet80": {
349
+ "title": "Extract BaseWrapper from PtyWrapper and TmuxWrapper",
350
+ "status": "completed",
351
+ "startedAt": "2026-01-06T12:27:13.004Z",
352
+ "completedAt": "2026-01-06T12:58:24.003Z",
353
+ "path": "/Users/khaliqgant/Projects/agent-workforce/relay/.trajectories/completed/2026-01/traj_xy9vifpqet80.json"
354
+ },
355
+ "traj_78ffm31jn3uk": {
356
+ "title": "Fix agent token fetch and seamless gh CLI",
357
+ "status": "completed",
358
+ "startedAt": "2026-01-06T16:24:13.901Z",
359
+ "completedAt": "2026-01-06T16:24:50.235Z",
360
+ "path": "/home/user/relay/.trajectories/completed/2026-01/traj_78ffm31jn3uk.json"
361
+ },
362
+ "traj_v9dkdoxylyid": {
363
+ "title": "Implement first-class user messaging with channels and DMs",
364
+ "status": "completed",
365
+ "startedAt": "2026-01-06T17:11:57.504Z",
366
+ "completedAt": "2026-01-06T17:12:56.919Z",
367
+ "path": "/home/user/relay/.trajectories/completed/2026-01/traj_v9dkdoxylyid.json"
368
+ },
369
+ "traj_ub8csuv3lcv4": {
370
+ "title": "Fix WebSocket disconnections for workspace instances",
371
+ "status": "completed",
372
+ "startedAt": "2026-01-06T18:13:23.603Z",
373
+ "completedAt": "2026-01-06T18:16:51.462Z",
374
+ "path": "/home/user/relay/.trajectories/completed/2026-01/traj_ub8csuv3lcv4.json"
375
+ },
376
+ "traj_fqduidx3xbtp": {
377
+ "title": "Implement dynamic repo management for workspaces",
378
+ "status": "completed",
379
+ "startedAt": "2026-01-07T05:44:47.138Z",
380
+ "completedAt": "2026-01-07T06:07:35.433Z",
381
+ "path": "/home/user/relay/.trajectories/completed/2026-01/traj_fqduidx3xbtp.json"
382
+ },
383
+ "traj_multi_server_arch": {
384
+ "title": "Multi-server architecture document",
385
+ "status": "completed",
386
+ "startedAt": "2026-01-07T06:00:00.000Z",
387
+ "completedAt": "2026-01-07T06:30:00.000Z",
388
+ "path": "/home/user/relay/.trajectories/completed/2026-01/traj_multi_server_arch.md"
389
+ },
390
+ "traj_6mieijqyvaag": {
391
+ "title": "Fix xterm interactive terminal for provider auth setup",
392
+ "status": "completed",
393
+ "startedAt": "2026-01-07T08:27:00.428Z",
394
+ "completedAt": "2026-01-07T08:28:17.323Z",
395
+ "path": "/Users/khaliqgant/Projects/agent-workforce/relay/.trajectories/completed/2026-01/traj_6mieijqyvaag.json"
396
+ },
397
+ "traj_0zacdjl1g4ht": {
398
+ "title": "Interactive terminal for provider auth setup",
399
+ "status": "completed",
400
+ "startedAt": "2026-01-07T10:06:42.869Z",
401
+ "completedAt": "2026-01-07T10:07:24.422Z",
402
+ "path": "/Users/khaliqgant/Projects/agent-workforce/relay/.trajectories/completed/2026-01/traj_0zacdjl1g4ht.json"
403
+ },
404
+ "traj_lq450ly148uw": {
405
+ "title": "Dashboard UI fixes, billing improvements, and settings alignment",
406
+ "status": "completed",
407
+ "startedAt": "2026-01-07T10:07:46.226Z",
408
+ "completedAt": "2026-01-07T10:07:58.979Z",
409
+ "path": "/Users/khaliqgant/Projects/agent-workforce/relay/.trajectories/completed/2026-01/traj_lq450ly148uw.json"
410
+ },
411
+ "traj_uc29tlso8i9s": {
412
+ "title": "Production-ready SSH tunneling for Codex OAuth with security hardening",
413
+ "status": "completed",
414
+ "startedAt": "2026-01-07T10:08:04.299Z",
415
+ "completedAt": "2026-01-07T10:09:10.870Z",
416
+ "path": "/Users/khaliqgant/Projects/agent-workforce/relay/.trajectories/completed/2026-01/traj_uc29tlso8i9s.json"
417
+ },
418
+ "traj_dcsp9s8y01ra": {
419
+ "title": "Dashboard UI fixes, billing improvements, and settings alignment",
420
+ "status": "completed",
421
+ "startedAt": "2026-01-07T10:09:36.428Z",
422
+ "completedAt": "2026-01-07T10:09:38.308Z",
423
+ "path": "/Users/khaliqgant/Projects/agent-workforce/relay/.trajectories/completed/2026-01/traj_dcsp9s8y01ra.json"
424
+ },
425
+ "traj_y7aiwijyfmmv": {
426
+ "title": "Fix CLI hanging - add auth check endpoint",
427
+ "status": "completed",
428
+ "startedAt": "2026-01-07T10:19:49.851Z",
429
+ "completedAt": "2026-01-07T10:19:49.966Z",
430
+ "path": "/Users/khaliqgant/Projects/agent-workforce/relay/.trajectories/completed/2026-01/traj_y7aiwijyfmmv.json"
431
+ },
432
+ "traj_psd9ob0j2ru3": {
433
+ "title": "Clarify codex rule file location and spawn behavior",
434
+ "status": "completed",
435
+ "startedAt": "2026-01-07T12:37:16.374Z",
436
+ "completedAt": "2026-01-07T12:40:48.197Z",
437
+ "path": "/Users/khaliqgant/Projects/agent-workforce/relay/.trajectories/completed/2026-01/traj_psd9ob0j2ru3.json"
438
+ },
439
+ "traj_33iuy72sezbk": {
440
+ "title": "Ensure Codex config applies without OPENAI_TOKEN",
441
+ "status": "completed",
442
+ "startedAt": "2026-01-07T12:53:31.624Z",
443
+ "completedAt": "2026-01-07T12:53:45.247Z",
444
+ "path": "/Users/khaliqgant/Projects/agent-workforce/relay/.trajectories/completed/2026-01/traj_33iuy72sezbk.json"
445
+ },
446
+ "traj_94gnp3k30goq": {
447
+ "title": "Fix intra-workspace messaging delivery and sidebar/notification visibility",
448
+ "status": "completed",
449
+ "startedAt": "2026-01-07T14:03:47.655Z",
450
+ "completedAt": "2026-01-07T14:11:00.042Z",
451
+ "path": "/Users/khaliqgant/Projects/agent-workforce/relay/.trajectories/completed/2026-01/traj_94gnp3k30goq.json"
452
+ },
453
+ "traj_03zupyv1s7b9": {
454
+ "title": "Fix intra-workspace messaging delivery and sidebar/notification visibility",
455
+ "status": "completed",
456
+ "startedAt": "2026-01-07T14:15:50.956Z",
457
+ "completedAt": "2026-01-07T14:16:39.455Z",
458
+ "path": "/Users/khaliqgant/Projects/agent-workforce/relay/.trajectories/completed/2026-01/traj_03zupyv1s7b9.json"
459
+ },
460
+ "traj_hf81ey93uz6t": {
461
+ "title": "Add sidebar section break between agents and human users",
462
+ "status": "completed",
463
+ "startedAt": "2026-01-07T14:18:40.736Z",
464
+ "completedAt": "2026-01-07T14:19:04.139Z",
465
+ "path": "/Users/khaliqgant/Projects/agent-workforce/relay/.trajectories/completed/2026-01/traj_hf81ey93uz6t.json"
312
466
  }
313
467
  }
314
468
  }
@@ -0,0 +1,15 @@
1
+ # Codex CLI Configuration for Agent Relay Containers
2
+ # This file is copied to ~/.codex/config.toml in container environments
3
+ # Reference: https://developers.openai.com/codex/config-reference/
4
+
5
+ # Disable auto-updates in containers to prevent permission errors
6
+ # Updates are managed via Dockerfile (pinned versions)
7
+ check_for_updates = false
8
+
9
+ # Additional configuration options can be added here as needed
10
+ # Examples (uncomment and adjust as needed):
11
+ # [model]
12
+ # default_model = "o1"
13
+ #
14
+ # [editor]
15
+ # default_editor = "vim"
@@ -6,8 +6,71 @@ log() {
6
6
  echo "[workspace] $*"
7
7
  }
8
8
 
9
- # Drop to workspace user if running as root
9
+ # Fix volume permissions and drop to workspace user if running as root
10
10
  if [[ "$(id -u)" == "0" ]]; then
11
+ # Fix /data and /workspace permissions before dropping privileges
12
+ # Fresh Fly.io volumes are root-owned, need to chown for workspace user
13
+ log "Fixing volume permissions..."
14
+ chown -R workspace:workspace /data /workspace 2>/dev/null || true
15
+
16
+ # ============================================================================
17
+ # SSH Server Setup (for CLI tunneling - Codex OAuth callback forwarding)
18
+ # When ENABLE_SSH=true, start SSH server on port 2222 for secure tunneling
19
+ # ============================================================================
20
+ if [[ "${ENABLE_SSH:-false}" == "true" ]]; then
21
+ log "Starting SSH server on port 2222..."
22
+
23
+ # Set SSH password for workspace user
24
+ SSH_PASS="${SSH_PASSWORD:-devpassword}"
25
+ echo "workspace:${SSH_PASS}" | chpasswd
26
+
27
+ # Configure SSH server for tunneling
28
+ # - Allow password auth (for CLI simplicity)
29
+ # - Listen on port 2222 (non-privileged)
30
+ # - Allow TCP forwarding (for port tunneling)
31
+ cat > /etc/ssh/sshd_config.d/workspace.conf <<SSHEOF
32
+ Port 2222
33
+ PasswordAuthentication yes
34
+ PermitRootLogin no
35
+ AllowUsers workspace
36
+ AllowTcpForwarding yes
37
+ GatewayPorts no
38
+ X11Forwarding no
39
+ SSHEOF
40
+
41
+ # Start SSH server in background
42
+ /usr/sbin/sshd -e
43
+ log "SSH server started (port 2222, user: workspace)"
44
+ fi
45
+
46
+ # ============================================================================
47
+ # Persist workspace environment for SSH sessions (must be done as root)
48
+ # SSH sessions don't inherit the container's runtime environment, so we write
49
+ # critical variables to /etc/profile.d/ which gets sourced by login shells
50
+ # ============================================================================
51
+ if [[ -n "${CLOUD_API_URL:-}" || -n "${WORKSPACE_ID:-}" ]]; then
52
+ log "Persisting workspace environment for SSH sessions"
53
+ # Compute HOME path for the env file
54
+ _DATA_DIR="${AGENT_RELAY_DATA_DIR:-/data}"
55
+ if [[ -n "${WORKSPACE_OWNER_USER_ID:-}" ]]; then
56
+ _USER_HOME="${_DATA_DIR}/users/${WORKSPACE_OWNER_USER_ID}"
57
+ else
58
+ _USER_HOME="/home/workspace"
59
+ fi
60
+ cat > /etc/profile.d/workspace-env.sh <<ENVEOF
61
+ # Workspace environment variables (auto-generated by entrypoint.sh)
62
+ export WORKSPACE_ID="${WORKSPACE_ID:-}"
63
+ export WORKSPACE_OWNER_USER_ID="${WORKSPACE_OWNER_USER_ID:-}"
64
+ export CLOUD_API_URL="${CLOUD_API_URL:-}"
65
+ export WORKSPACE_TOKEN="${WORKSPACE_TOKEN:-}"
66
+ export WORKSPACE_DIR="${WORKSPACE_DIR:-/workspace}"
67
+ export HOME="${_USER_HOME}"
68
+ export AGENT_RELAY_USER_ID="${WORKSPACE_OWNER_USER_ID:-}"
69
+ export AGENT_RELAY_DATA_DIR="${_DATA_DIR}"
70
+ ENVEOF
71
+ chmod 644 /etc/profile.d/workspace-env.sh
72
+ fi
73
+
11
74
  log "Dropping privileges to workspace user..."
12
75
  exec gosu workspace "$0" "$@"
13
76
  fi
@@ -16,6 +79,41 @@ PORT="${AGENT_RELAY_DASHBOARD_PORT:-${PORT:-3888}}"
16
79
  export AGENT_RELAY_DASHBOARD_PORT="${PORT}"
17
80
  export PORT="${PORT}"
18
81
 
82
+ # Disable auto-updates for AI CLIs in container environments
83
+ # Prevents permission errors when CLIs try to self-update with npm/pip
84
+ export DISABLE_AUTOUPDATER=1
85
+ # Belt-and-suspenders flags to block Codex/OpenAI update checks
86
+ export CODEX_CHECK_FOR_UPDATES=false
87
+ export CODEX_DISABLE_AUTOUPDATE=1
88
+ export OPENAI_CLI_NO_UPDATE=1
89
+ export NO_UPDATE_NOTIFIER=1
90
+ export NPM_CONFIG_UPDATE_NOTIFIER=false
91
+ log "Auto-updates disabled for AI CLIs (container environment)"
92
+
93
+ # ============================================================================
94
+ # Per-user credential storage setup
95
+ # Create user-specific HOME on persistent volume (/data)
96
+ # This enables multi-user workspaces where each user has their own credentials
97
+ # ============================================================================
98
+ DATA_DIR="${AGENT_RELAY_DATA_DIR:-/data}"
99
+ if [[ -n "${WORKSPACE_OWNER_USER_ID:-}" ]]; then
100
+ USER_HOME="${DATA_DIR}/users/${WORKSPACE_OWNER_USER_ID}"
101
+ log "Setting up per-user HOME at ${USER_HOME}"
102
+ mkdir -p "${USER_HOME}"
103
+ mkdir -p "${USER_HOME}/.claude"
104
+ mkdir -p "${USER_HOME}/.codex"
105
+ mkdir -p "${USER_HOME}/.config/gcloud"
106
+ mkdir -p "${USER_HOME}/.config/gh"
107
+ export HOME="${USER_HOME}"
108
+ # Ensure user-local bin is on PATH for per-user shims/wrappers
109
+ export PATH="${HOME}/.local/bin:${PATH}"
110
+ export XDG_CONFIG_HOME="${USER_HOME}/.config"
111
+ export AGENT_RELAY_USER_ID="${WORKSPACE_OWNER_USER_ID}"
112
+ log "HOME set to ${HOME} (user: ${WORKSPACE_OWNER_USER_ID})"
113
+ else
114
+ log "No WORKSPACE_OWNER_USER_ID set, using default HOME: ${HOME}"
115
+ fi
116
+
19
117
  WORKSPACE_DIR="${WORKSPACE_DIR:-/workspace}"
20
118
  REPO_LIST="${REPOSITORIES:-}"
21
119
 
@@ -67,9 +165,38 @@ fi
67
165
  GHEOF
68
166
  chmod +x "/tmp/gh-token-helper.sh"
69
167
 
70
- # gh CLI will use GH_TOKEN if set; we export a function to refresh it
71
- # For now, set it once at startup (will be refreshed by the credential helper for git operations)
72
- # Retry a few times in case the cloud API isn't ready yet
168
+ # Create gh wrapper that auto-refreshes token on each invocation
169
+ # This ensures gh always has a valid token without agents needing to do anything
170
+ GH_REAL=$(which gh 2>/dev/null || echo "/usr/bin/gh")
171
+ if [[ -x "${GH_REAL}" ]]; then
172
+ cat > "/tmp/gh-wrapper" <<GHWRAPPER
173
+ #!/usr/bin/env bash
174
+ # Auto-refreshing gh wrapper - fetches fresh token on each invocation
175
+ export GH_TOKEN=\$(/tmp/gh-token-helper.sh 2>/dev/null)
176
+ if [[ -z "\${GH_TOKEN}" ]]; then
177
+ echo "gh-wrapper: Failed to fetch GitHub token" >&2
178
+ echo "gh-wrapper: Check CLOUD_API_URL, WORKSPACE_ID, and WORKSPACE_TOKEN are set" >&2
179
+ exit 1
180
+ fi
181
+ exec "${GH_REAL}" "\$@"
182
+ GHWRAPPER
183
+ chmod +x "/tmp/gh-wrapper"
184
+
185
+ # Create symlink or copy to override the real gh
186
+ # We use /usr/local/bin which comes before /usr/bin in PATH
187
+ if [[ -w "/usr/local/bin" ]]; then
188
+ cp "/tmp/gh-wrapper" "/usr/local/bin/gh"
189
+ log "Installed auto-refreshing gh wrapper to /usr/local/bin/gh"
190
+ else
191
+ # If we can't write to /usr/local/bin, add /tmp to PATH
192
+ export PATH="/tmp:${PATH}"
193
+ mv "/tmp/gh-wrapper" "/tmp/gh"
194
+ log "Added auto-refreshing gh wrapper to PATH"
195
+ fi
196
+ fi
197
+
198
+ # Also set GH_TOKEN at startup for any tools that read it directly
199
+ # (The wrapper handles runtime refresh, this is just for initialization)
73
200
  export GH_TOKEN=""
74
201
  for attempt in 1 2 3; do
75
202
  GH_TOKEN=$(/tmp/gh-token-helper.sh 2>/dev/null || echo "")
@@ -81,7 +208,7 @@ GHEOF
81
208
  if [[ -n "${GH_TOKEN}" ]]; then
82
209
  log "GitHub CLI configured with fresh token"
83
210
  else
84
- log "WARN: Could not fetch GitHub token for gh CLI"
211
+ log "WARN: Could not fetch initial GitHub token for gh CLI"
85
212
  fi
86
213
 
87
214
  # Fallback: Use static GITHUB_TOKEN if provided (legacy mode)
@@ -261,11 +388,44 @@ RELAYEOF
261
388
  fi
262
389
  log "Claude Code configuration complete"
263
390
 
264
- # Codex CLI expects ~/.codex/auth.json
391
+ # Codex CLI settings (always install config to disable auto-updates)
392
+ mkdir -p "${HOME}/.codex"
393
+ if [[ -f "/app/deploy/workspace/codex.config.toml" ]]; then
394
+ cp "/app/deploy/workspace/codex.config.toml" "${HOME}/.codex/config.toml"
395
+ chmod 600 "${HOME}/.codex/config.toml"
396
+ log "Codex configuration applied from codex.config.toml"
397
+ else
398
+ # Fallback: create minimal config (should not happen in production)
399
+ log "WARN: codex.config.toml not found, creating minimal config"
400
+ cat > "${HOME}/.codex/config.toml" <<CODEXCONFIGEOF
401
+ check_for_updates = false
402
+ CODEXCONFIGEOF
403
+ chmod 600 "${HOME}/.codex/config.toml"
404
+ fi
405
+ # Also create JSON config for Codex (some versions read config.json instead of config.toml)
406
+ cat > "${HOME}/.codex/config.json" <<'CODEXJSON'
407
+ {
408
+ "check_for_updates": false
409
+ }
410
+ CODEXJSON
411
+ chmod 600 "${HOME}/.codex/config.json"
412
+
413
+ # NPM wrapper to block Codex self-updates (no-op when Codex tries npm install -g @openai/codex)
414
+ mkdir -p "${HOME}/.local/bin"
415
+ cat > "${HOME}/.local/bin/npm" <<'NPMWRAPPER'
416
+ #!/usr/bin/env bash
417
+ if [[ "$1" == "install" && "$2" == "-g" && "$3" == @openai/codex* ]]; then
418
+ echo "npm wrapper: skipping Codex self-update (auto-update disabled)" >&2
419
+ exit 0
420
+ fi
421
+ exec /usr/local/bin/npm "$@"
422
+ NPMWRAPPER
423
+ chmod +x "${HOME}/.local/bin/npm"
424
+
425
+ # Codex CLI expects ~/.codex/auth.json for credentials
265
426
  # Format: { tokens: { access_token: "...", refresh_token: "...", ... } }
266
427
  if [[ -n "${OPENAI_TOKEN:-}" ]]; then
267
428
  log "Configuring Codex credentials..."
268
- mkdir -p "${HOME}/.codex"
269
429
  cat > "${HOME}/.codex/auth.json" <<EOF
270
430
  {
271
431
  "tokens": {
@@ -86,6 +86,7 @@ fi
86
86
 
87
87
  if [[ -z "$response" ]]; then
88
88
  echo "git-credential-relay: Failed to fetch token from gateway" >&2
89
+ echo "git-credential-relay: Check that CLOUD_API_URL is accessible: ${CLOUD_API_URL}" >&2
89
90
  exit 1
90
91
  fi
91
92
 
@@ -94,12 +95,26 @@ token=$(echo "$response" | jq -r '.token // empty')
94
95
  username=$(echo "$response" | jq -r '.username // "x-access-token"')
95
96
 
96
97
  if [[ -z "$token" ]]; then
97
- # Check if there's an error message
98
+ # Check if there's an error message with details
98
99
  error=$(echo "$response" | jq -r '.error // empty')
100
+ code=$(echo "$response" | jq -r '.code // empty')
101
+ hint=$(echo "$response" | jq -r '.hint // empty')
102
+ details=$(echo "$response" | jq -r '.details // empty')
103
+
99
104
  if [[ -n "$error" ]]; then
100
- echo "git-credential-relay: $error" >&2
105
+ echo "git-credential-relay: ERROR: $error" >&2
106
+ if [[ -n "$code" ]]; then
107
+ echo "git-credential-relay: Code: $code" >&2
108
+ fi
109
+ if [[ -n "$hint" ]]; then
110
+ echo "git-credential-relay: Hint: $hint" >&2
111
+ fi
112
+ if [[ -n "$details" ]]; then
113
+ echo "git-credential-relay: Details: $details" >&2
114
+ fi
101
115
  else
102
116
  echo "git-credential-relay: No token in response" >&2
117
+ debug "Raw response: $response"
103
118
  fi
104
119
  exit 1
105
120
  fi
@@ -128,6 +128,13 @@ export declare class AgentSpawner {
128
128
  * Get raw output from a worker
129
129
  */
130
130
  getWorkerRawOutput(name: string): string | null;
131
+ /**
132
+ * Send input to a worker's PTY (for interactive terminal support)
133
+ * @param name - Worker name
134
+ * @param data - Input data to send (keystrokes, text, etc.)
135
+ * @returns true if input was sent, false if worker not found
136
+ */
137
+ sendWorkerInput(name: string, data: string): boolean;
131
138
  /**
132
139
  * Wait for an agent to appear in the registry (agents.json)
133
140
  */