agent-relay 2.0.22 → 2.0.24

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 (534) hide show
  1. package/bin/relay-pty-linux-arm64 +0 -0
  2. package/dist/src/cli/index.d.ts +3 -3
  3. package/dist/src/cli/index.js +58 -74
  4. package/package.json +21 -62
  5. package/packages/api-types/package.json +1 -1
  6. package/packages/bridge/package.json +8 -8
  7. package/packages/cli-tester/package.json +1 -1
  8. package/packages/config/package.json +2 -2
  9. package/packages/continuity/package.json +1 -1
  10. package/packages/daemon/dist/orchestrator.js +19 -1
  11. package/packages/daemon/package.json +12 -12
  12. package/packages/hooks/package.json +4 -4
  13. package/packages/mcp/package.json +2 -2
  14. package/packages/memory/package.json +2 -2
  15. package/packages/policy/package.json +2 -2
  16. package/packages/protocol/package.json +1 -1
  17. package/packages/resiliency/package.json +1 -1
  18. package/packages/sdk/package.json +2 -2
  19. package/packages/spawner/package.json +1 -1
  20. package/packages/state/package.json +1 -1
  21. package/packages/storage/package.json +2 -2
  22. package/packages/telemetry/package.json +1 -1
  23. package/packages/trajectory/package.json +2 -2
  24. package/packages/user-directory/package.json +2 -2
  25. package/packages/utils/dist/update-checker.js +4 -0
  26. package/packages/utils/package.json +1 -1
  27. package/packages/wrapper/package.json +6 -6
  28. package/deploy/init-db.sql +0 -5
  29. package/deploy/scripts/setup-fly-workspaces.sh +0 -69
  30. package/deploy/scripts/setup-railway.sh +0 -75
  31. package/deploy/workspace/codex.config.toml +0 -20
  32. package/deploy/workspace/entrypoint-browser.sh +0 -118
  33. package/deploy/workspace/entrypoint.sh +0 -612
  34. package/deploy/workspace/gh-credential-relay +0 -90
  35. package/deploy/workspace/gh-relay +0 -156
  36. package/deploy/workspace/git-credential-relay +0 -330
  37. package/deploy/workspace/git-credential-relay.test.sh +0 -230
  38. package/dist/dashboard/out/404.html +0 -1
  39. package/dist/dashboard/out/_next/static/91mkGYq3qbG8WHE6VytQ8/_buildManifest.js +0 -1
  40. package/dist/dashboard/out/_next/static/91mkGYq3qbG8WHE6VytQ8/_ssgManifest.js +0 -1
  41. package/dist/dashboard/out/_next/static/chunks/116-a883fca163f3a5bc.js +0 -1
  42. package/dist/dashboard/out/_next/static/chunks/117-c8afed19e821a35d.js +0 -2
  43. package/dist/dashboard/out/_next/static/chunks/282-980c2eb8fff20123.js +0 -1
  44. package/dist/dashboard/out/_next/static/chunks/320-a6304232cd0ee2ce.js +0 -1
  45. package/dist/dashboard/out/_next/static/chunks/532-bace199897eeab37.js +0 -9
  46. package/dist/dashboard/out/_next/static/chunks/631-16b905e5920f9b59.js +0 -1
  47. package/dist/dashboard/out/_next/static/chunks/648-acb2ff9f77cbfbd3.js +0 -1
  48. package/dist/dashboard/out/_next/static/chunks/766-2aea80818f7eb0d8.js +0 -1
  49. package/dist/dashboard/out/_next/static/chunks/83-26d2bde54616ee90.js +0 -1
  50. package/dist/dashboard/out/_next/static/chunks/847-f1f467060f32afff.js +0 -1
  51. package/dist/dashboard/out/_next/static/chunks/891-5cb1513eeb97a891.js +0 -1
  52. package/dist/dashboard/out/_next/static/chunks/app/_not-found/page-60501fddbafba9dc.js +0 -1
  53. package/dist/dashboard/out/_next/static/chunks/app/app/onboarding/page-9914652442f7e4fb.js +0 -1
  54. package/dist/dashboard/out/_next/static/chunks/app/app/page-366fb7c078d4e9e0.js +0 -1
  55. package/dist/dashboard/out/_next/static/chunks/app/cloud/link/page-fa1d5842aa90e8a6.js +0 -1
  56. package/dist/dashboard/out/_next/static/chunks/app/complete-profile/page-dd64bbdf66b639cd.js +0 -1
  57. package/dist/dashboard/out/_next/static/chunks/app/connect-repos/page-113060009ef35bc2.js +0 -1
  58. package/dist/dashboard/out/_next/static/chunks/app/history/page-9965d2483011b846.js +0 -1
  59. package/dist/dashboard/out/_next/static/chunks/app/layout-6b91e33784c20610.js +0 -1
  60. package/dist/dashboard/out/_next/static/chunks/app/login/page-435eceb0073be027.js +0 -1
  61. package/dist/dashboard/out/_next/static/chunks/app/metrics/page-1e37ef8e73940b40.js +0 -1
  62. package/dist/dashboard/out/_next/static/chunks/app/page-8119d4246743574e.js +0 -1
  63. package/dist/dashboard/out/_next/static/chunks/app/pricing/page-9db3ebdfa567a7c9.js +0 -1
  64. package/dist/dashboard/out/_next/static/chunks/app/providers/page-ecb16ffd3b36262b.js +0 -1
  65. package/dist/dashboard/out/_next/static/chunks/app/providers/setup/[provider]/page-4dbe33f0f7691b7c.js +0 -1
  66. package/dist/dashboard/out/_next/static/chunks/app/signup/page-c7a0a28341365ae0.js +0 -1
  67. package/dist/dashboard/out/_next/static/chunks/e868780c-48e5f147c90a3a41.js +0 -18
  68. package/dist/dashboard/out/_next/static/chunks/fd9d1056-609918ca7b6280bb.js +0 -1
  69. package/dist/dashboard/out/_next/static/chunks/framework-f66176bb897dc684.js +0 -1
  70. package/dist/dashboard/out/_next/static/chunks/main-311c3db74dcfadb7.js +0 -1
  71. package/dist/dashboard/out/_next/static/chunks/main-app-fdbeb09028f57c9f.js +0 -1
  72. package/dist/dashboard/out/_next/static/chunks/pages/_app-72b849fbd24ac258.js +0 -1
  73. package/dist/dashboard/out/_next/static/chunks/pages/_error-7ba65e1336b92748.js +0 -1
  74. package/dist/dashboard/out/_next/static/chunks/polyfills-42372ed130431b0a.js +0 -1
  75. package/dist/dashboard/out/_next/static/chunks/webpack-1cdd8ed57114d5e1.js +0 -1
  76. package/dist/dashboard/out/_next/static/css/4034f236dd1a3178.css +0 -1
  77. package/dist/dashboard/out/_next/static/css/6892f8422896ef7a.css +0 -1
  78. package/dist/dashboard/out/alt-logos/agent-relay-logo-128.png +0 -0
  79. package/dist/dashboard/out/alt-logos/agent-relay-logo-256.png +0 -0
  80. package/dist/dashboard/out/alt-logos/agent-relay-logo-32.png +0 -0
  81. package/dist/dashboard/out/alt-logos/agent-relay-logo-512.png +0 -0
  82. package/dist/dashboard/out/alt-logos/agent-relay-logo-64.png +0 -0
  83. package/dist/dashboard/out/alt-logos/agent-relay-logo.svg +0 -45
  84. package/dist/dashboard/out/alt-logos/logo.svg +0 -38
  85. package/dist/dashboard/out/alt-logos/monogram-logo-128.png +0 -0
  86. package/dist/dashboard/out/alt-logos/monogram-logo-256.png +0 -0
  87. package/dist/dashboard/out/alt-logos/monogram-logo-32.png +0 -0
  88. package/dist/dashboard/out/alt-logos/monogram-logo-512.png +0 -0
  89. package/dist/dashboard/out/alt-logos/monogram-logo-64.png +0 -0
  90. package/dist/dashboard/out/alt-logos/monogram-logo.svg +0 -38
  91. package/dist/dashboard/out/app/onboarding.html +0 -1
  92. package/dist/dashboard/out/app/onboarding.txt +0 -7
  93. package/dist/dashboard/out/app.html +0 -1
  94. package/dist/dashboard/out/app.txt +0 -7
  95. package/dist/dashboard/out/apple-icon.png +0 -0
  96. package/dist/dashboard/out/cloud/link.html +0 -1
  97. package/dist/dashboard/out/cloud/link.txt +0 -7
  98. package/dist/dashboard/out/complete-profile.html +0 -5
  99. package/dist/dashboard/out/complete-profile.txt +0 -7
  100. package/dist/dashboard/out/connect-repos.html +0 -1
  101. package/dist/dashboard/out/connect-repos.txt +0 -7
  102. package/dist/dashboard/out/history.html +0 -1
  103. package/dist/dashboard/out/history.txt +0 -7
  104. package/dist/dashboard/out/index.html +0 -1
  105. package/dist/dashboard/out/index.txt +0 -7
  106. package/dist/dashboard/out/login.html +0 -5
  107. package/dist/dashboard/out/login.txt +0 -7
  108. package/dist/dashboard/out/metrics.html +0 -1
  109. package/dist/dashboard/out/metrics.txt +0 -7
  110. package/dist/dashboard/out/pricing.html +0 -13
  111. package/dist/dashboard/out/pricing.txt +0 -7
  112. package/dist/dashboard/out/providers/setup/claude.html +0 -1
  113. package/dist/dashboard/out/providers/setup/claude.txt +0 -8
  114. package/dist/dashboard/out/providers/setup/codex.html +0 -1
  115. package/dist/dashboard/out/providers/setup/codex.txt +0 -8
  116. package/dist/dashboard/out/providers/setup/cursor.html +0 -1
  117. package/dist/dashboard/out/providers/setup/cursor.txt +0 -8
  118. package/dist/dashboard/out/providers.html +0 -1
  119. package/dist/dashboard/out/providers.txt +0 -7
  120. package/dist/dashboard/out/signup.html +0 -6
  121. package/dist/dashboard/out/signup.txt +0 -7
  122. package/dist/src/cloud/index.d.ts +0 -8
  123. package/dist/src/cloud/index.js +0 -8
  124. package/dist/src/dashboard-server/index.d.ts +0 -8
  125. package/dist/src/dashboard-server/index.js +0 -8
  126. package/packages/cloud/dist/api/admin.d.ts +0 -8
  127. package/packages/cloud/dist/api/admin.js +0 -225
  128. package/packages/cloud/dist/api/auth.d.ts +0 -20
  129. package/packages/cloud/dist/api/auth.js +0 -138
  130. package/packages/cloud/dist/api/billing.d.ts +0 -7
  131. package/packages/cloud/dist/api/billing.js +0 -564
  132. package/packages/cloud/dist/api/cli-pty-runner.d.ts +0 -53
  133. package/packages/cloud/dist/api/cli-pty-runner.js +0 -175
  134. package/packages/cloud/dist/api/codex-auth-helper.d.ts +0 -21
  135. package/packages/cloud/dist/api/codex-auth-helper.js +0 -327
  136. package/packages/cloud/dist/api/consensus.d.ts +0 -13
  137. package/packages/cloud/dist/api/consensus.js +0 -261
  138. package/packages/cloud/dist/api/coordinators.d.ts +0 -8
  139. package/packages/cloud/dist/api/coordinators.js +0 -750
  140. package/packages/cloud/dist/api/daemons.d.ts +0 -12
  141. package/packages/cloud/dist/api/daemons.js +0 -535
  142. package/packages/cloud/dist/api/email-auth.d.ts +0 -11
  143. package/packages/cloud/dist/api/email-auth.js +0 -347
  144. package/packages/cloud/dist/api/generic-webhooks.d.ts +0 -8
  145. package/packages/cloud/dist/api/generic-webhooks.js +0 -129
  146. package/packages/cloud/dist/api/git.d.ts +0 -8
  147. package/packages/cloud/dist/api/git.js +0 -269
  148. package/packages/cloud/dist/api/github-app.d.ts +0 -11
  149. package/packages/cloud/dist/api/github-app.js +0 -223
  150. package/packages/cloud/dist/api/middleware/planLimits.d.ts +0 -43
  151. package/packages/cloud/dist/api/middleware/planLimits.js +0 -202
  152. package/packages/cloud/dist/api/monitoring.d.ts +0 -11
  153. package/packages/cloud/dist/api/monitoring.js +0 -578
  154. package/packages/cloud/dist/api/nango-auth.d.ts +0 -9
  155. package/packages/cloud/dist/api/nango-auth.js +0 -741
  156. package/packages/cloud/dist/api/onboarding.d.ts +0 -15
  157. package/packages/cloud/dist/api/onboarding.js +0 -679
  158. package/packages/cloud/dist/api/policy.d.ts +0 -8
  159. package/packages/cloud/dist/api/policy.js +0 -229
  160. package/packages/cloud/dist/api/provider-env.d.ts +0 -26
  161. package/packages/cloud/dist/api/provider-env.js +0 -141
  162. package/packages/cloud/dist/api/providers.d.ts +0 -7
  163. package/packages/cloud/dist/api/providers.js +0 -574
  164. package/packages/cloud/dist/api/repos.d.ts +0 -8
  165. package/packages/cloud/dist/api/repos.js +0 -577
  166. package/packages/cloud/dist/api/sessions.d.ts +0 -11
  167. package/packages/cloud/dist/api/sessions.js +0 -302
  168. package/packages/cloud/dist/api/teams.d.ts +0 -7
  169. package/packages/cloud/dist/api/teams.js +0 -281
  170. package/packages/cloud/dist/api/test-helpers.d.ts +0 -10
  171. package/packages/cloud/dist/api/test-helpers.js +0 -745
  172. package/packages/cloud/dist/api/usage.d.ts +0 -7
  173. package/packages/cloud/dist/api/usage.js +0 -111
  174. package/packages/cloud/dist/api/webhooks.d.ts +0 -8
  175. package/packages/cloud/dist/api/webhooks.js +0 -645
  176. package/packages/cloud/dist/api/workspaces.d.ts +0 -25
  177. package/packages/cloud/dist/api/workspaces.js +0 -1799
  178. package/packages/cloud/dist/billing/index.d.ts +0 -9
  179. package/packages/cloud/dist/billing/index.js +0 -9
  180. package/packages/cloud/dist/billing/plans.d.ts +0 -39
  181. package/packages/cloud/dist/billing/plans.js +0 -245
  182. package/packages/cloud/dist/billing/service.d.ts +0 -80
  183. package/packages/cloud/dist/billing/service.js +0 -388
  184. package/packages/cloud/dist/billing/types.d.ts +0 -141
  185. package/packages/cloud/dist/billing/types.js +0 -7
  186. package/packages/cloud/dist/config.d.ts +0 -5
  187. package/packages/cloud/dist/config.js +0 -5
  188. package/packages/cloud/dist/db/bulk-ingest.d.ts +0 -89
  189. package/packages/cloud/dist/db/bulk-ingest.js +0 -268
  190. package/packages/cloud/dist/db/drizzle.d.ts +0 -290
  191. package/packages/cloud/dist/db/drizzle.js +0 -1422
  192. package/packages/cloud/dist/db/index.d.ts +0 -56
  193. package/packages/cloud/dist/db/index.js +0 -70
  194. package/packages/cloud/dist/db/schema.d.ts +0 -5117
  195. package/packages/cloud/dist/db/schema.js +0 -656
  196. package/packages/cloud/dist/index.d.ts +0 -11
  197. package/packages/cloud/dist/index.js +0 -38
  198. package/packages/cloud/dist/provisioner/index.d.ts +0 -207
  199. package/packages/cloud/dist/provisioner/index.js +0 -2118
  200. package/packages/cloud/dist/server.d.ts +0 -17
  201. package/packages/cloud/dist/server.js +0 -2034
  202. package/packages/cloud/dist/services/auto-scaler.d.ts +0 -152
  203. package/packages/cloud/dist/services/auto-scaler.js +0 -439
  204. package/packages/cloud/dist/services/capacity-manager.d.ts +0 -148
  205. package/packages/cloud/dist/services/capacity-manager.js +0 -449
  206. package/packages/cloud/dist/services/ci-agent-spawner.d.ts +0 -49
  207. package/packages/cloud/dist/services/ci-agent-spawner.js +0 -373
  208. package/packages/cloud/dist/services/cloud-message-bus.d.ts +0 -28
  209. package/packages/cloud/dist/services/cloud-message-bus.js +0 -19
  210. package/packages/cloud/dist/services/compute-enforcement.d.ts +0 -57
  211. package/packages/cloud/dist/services/compute-enforcement.js +0 -175
  212. package/packages/cloud/dist/services/coordinator.d.ts +0 -62
  213. package/packages/cloud/dist/services/coordinator.js +0 -389
  214. package/packages/cloud/dist/services/index.d.ts +0 -17
  215. package/packages/cloud/dist/services/index.js +0 -25
  216. package/packages/cloud/dist/services/intro-expiration.d.ts +0 -60
  217. package/packages/cloud/dist/services/intro-expiration.js +0 -252
  218. package/packages/cloud/dist/services/mention-handler.d.ts +0 -65
  219. package/packages/cloud/dist/services/mention-handler.js +0 -405
  220. package/packages/cloud/dist/services/nango.d.ts +0 -219
  221. package/packages/cloud/dist/services/nango.js +0 -424
  222. package/packages/cloud/dist/services/persistence.d.ts +0 -131
  223. package/packages/cloud/dist/services/persistence.js +0 -200
  224. package/packages/cloud/dist/services/planLimits.d.ts +0 -147
  225. package/packages/cloud/dist/services/planLimits.js +0 -335
  226. package/packages/cloud/dist/services/presence-registry.d.ts +0 -56
  227. package/packages/cloud/dist/services/presence-registry.js +0 -91
  228. package/packages/cloud/dist/services/scaling-orchestrator.d.ts +0 -159
  229. package/packages/cloud/dist/services/scaling-orchestrator.js +0 -502
  230. package/packages/cloud/dist/services/scaling-policy.d.ts +0 -121
  231. package/packages/cloud/dist/services/scaling-policy.js +0 -415
  232. package/packages/cloud/dist/services/ssh-security.d.ts +0 -31
  233. package/packages/cloud/dist/services/ssh-security.js +0 -63
  234. package/packages/cloud/dist/services/workspace-keepalive.d.ts +0 -76
  235. package/packages/cloud/dist/services/workspace-keepalive.js +0 -234
  236. package/packages/cloud/dist/shims/consensus.d.ts +0 -23
  237. package/packages/cloud/dist/shims/consensus.js +0 -5
  238. package/packages/cloud/dist/webhooks/index.d.ts +0 -24
  239. package/packages/cloud/dist/webhooks/index.js +0 -29
  240. package/packages/cloud/dist/webhooks/parsers/github.d.ts +0 -8
  241. package/packages/cloud/dist/webhooks/parsers/github.js +0 -234
  242. package/packages/cloud/dist/webhooks/parsers/index.d.ts +0 -23
  243. package/packages/cloud/dist/webhooks/parsers/index.js +0 -30
  244. package/packages/cloud/dist/webhooks/parsers/linear.d.ts +0 -9
  245. package/packages/cloud/dist/webhooks/parsers/linear.js +0 -258
  246. package/packages/cloud/dist/webhooks/parsers/slack.d.ts +0 -9
  247. package/packages/cloud/dist/webhooks/parsers/slack.js +0 -214
  248. package/packages/cloud/dist/webhooks/responders/github.d.ts +0 -8
  249. package/packages/cloud/dist/webhooks/responders/github.js +0 -73
  250. package/packages/cloud/dist/webhooks/responders/index.d.ts +0 -23
  251. package/packages/cloud/dist/webhooks/responders/index.js +0 -30
  252. package/packages/cloud/dist/webhooks/responders/linear.d.ts +0 -9
  253. package/packages/cloud/dist/webhooks/responders/linear.js +0 -149
  254. package/packages/cloud/dist/webhooks/responders/slack.d.ts +0 -20
  255. package/packages/cloud/dist/webhooks/responders/slack.js +0 -178
  256. package/packages/cloud/dist/webhooks/router.d.ts +0 -25
  257. package/packages/cloud/dist/webhooks/router.js +0 -504
  258. package/packages/cloud/dist/webhooks/rules-engine.d.ts +0 -24
  259. package/packages/cloud/dist/webhooks/rules-engine.js +0 -287
  260. package/packages/cloud/dist/webhooks/types.d.ts +0 -186
  261. package/packages/cloud/dist/webhooks/types.js +0 -8
  262. package/packages/cloud/package.json +0 -60
  263. package/packages/dashboard/README.md +0 -48
  264. package/packages/dashboard/dist/health-worker-manager.d.ts +0 -62
  265. package/packages/dashboard/dist/health-worker-manager.js +0 -144
  266. package/packages/dashboard/dist/health-worker.d.ts +0 -9
  267. package/packages/dashboard/dist/health-worker.js +0 -79
  268. package/packages/dashboard/dist/index.d.ts +0 -20
  269. package/packages/dashboard/dist/index.js +0 -19
  270. package/packages/dashboard/dist/metrics.d.ts +0 -105
  271. package/packages/dashboard/dist/metrics.js +0 -193
  272. package/packages/dashboard/dist/needs-attention.d.ts +0 -24
  273. package/packages/dashboard/dist/needs-attention.js +0 -78
  274. package/packages/dashboard/dist/server.d.ts +0 -25
  275. package/packages/dashboard/dist/server.js +0 -5270
  276. package/packages/dashboard/dist/start.d.ts +0 -6
  277. package/packages/dashboard/dist/start.js +0 -13
  278. package/packages/dashboard/dist/types/threading.d.ts +0 -8
  279. package/packages/dashboard/dist/types/threading.js +0 -2
  280. package/packages/dashboard/dist/user-bridge.d.ts +0 -154
  281. package/packages/dashboard/dist/user-bridge.js +0 -372
  282. package/packages/dashboard/package.json +0 -65
  283. package/packages/dashboard/ui/app/app/onboarding/page.tsx +0 -394
  284. package/packages/dashboard/ui/app/app/page.tsx +0 -667
  285. package/packages/dashboard/ui/app/apple-icon.png +0 -0
  286. package/packages/dashboard/ui/app/cloud/link/page.tsx +0 -464
  287. package/packages/dashboard/ui/app/complete-profile/page.tsx +0 -204
  288. package/packages/dashboard/ui/app/connect-repos/page.tsx +0 -410
  289. package/packages/dashboard/ui/app/favicon.png +0 -0
  290. package/packages/dashboard/ui/app/globals.css +0 -59
  291. package/packages/dashboard/ui/app/history/page.tsx +0 -658
  292. package/packages/dashboard/ui/app/layout.tsx +0 -25
  293. package/packages/dashboard/ui/app/login/page.tsx +0 -424
  294. package/packages/dashboard/ui/app/metrics/page.tsx +0 -751
  295. package/packages/dashboard/ui/app/page.tsx +0 -59
  296. package/packages/dashboard/ui/app/pricing/page.tsx +0 -7
  297. package/packages/dashboard/ui/app/providers/page.tsx +0 -193
  298. package/packages/dashboard/ui/app/providers/setup/[provider]/ProviderSetupClient.tsx +0 -148
  299. package/packages/dashboard/ui/app/providers/setup/[provider]/constants.ts +0 -35
  300. package/packages/dashboard/ui/app/providers/setup/[provider]/page.tsx +0 -42
  301. package/packages/dashboard/ui/app/signup/page.tsx +0 -533
  302. package/packages/dashboard/ui/index.ts +0 -49
  303. package/packages/dashboard/ui/landing/LandingPage.tsx +0 -713
  304. package/packages/dashboard/ui/landing/PricingPage.tsx +0 -559
  305. package/packages/dashboard/ui/landing/index.ts +0 -6
  306. package/packages/dashboard/ui/landing/styles.css +0 -2850
  307. package/packages/dashboard/ui/lib/agent-merge.ts +0 -35
  308. package/packages/dashboard/ui/lib/api.ts +0 -1155
  309. package/packages/dashboard/ui/lib/cloudApi.ts +0 -877
  310. package/packages/dashboard/ui/lib/colors.ts +0 -218
  311. package/packages/dashboard/ui/lib/hierarchy.ts +0 -242
  312. package/packages/dashboard/ui/lib/stuckDetection.ts +0 -142
  313. package/packages/dashboard/ui/next-env.d.ts +0 -5
  314. package/packages/dashboard/ui/next.config.js +0 -41
  315. package/packages/dashboard/ui/package-lock.json +0 -2882
  316. package/packages/dashboard/ui/package.json +0 -33
  317. package/packages/dashboard/ui/postcss.config.js +0 -5
  318. package/packages/dashboard/ui/react-components/ActivityFeed.tsx +0 -216
  319. package/packages/dashboard/ui/react-components/AddWorkspaceModal.tsx +0 -170
  320. package/packages/dashboard/ui/react-components/AgentCard.tsx +0 -587
  321. package/packages/dashboard/ui/react-components/AgentList.tsx +0 -411
  322. package/packages/dashboard/ui/react-components/AgentProfilePanel.tsx +0 -564
  323. package/packages/dashboard/ui/react-components/App.tsx +0 -3033
  324. package/packages/dashboard/ui/react-components/BillingPanel.tsx +0 -922
  325. package/packages/dashboard/ui/react-components/BillingResult.tsx +0 -447
  326. package/packages/dashboard/ui/react-components/BroadcastComposer.tsx +0 -690
  327. package/packages/dashboard/ui/react-components/ChannelAdminPanel.tsx +0 -773
  328. package/packages/dashboard/ui/react-components/ChannelBrowser.tsx +0 -385
  329. package/packages/dashboard/ui/react-components/ChannelChat.tsx +0 -261
  330. package/packages/dashboard/ui/react-components/ChannelSidebar.tsx +0 -399
  331. package/packages/dashboard/ui/react-components/CloudSessionProvider.tsx +0 -130
  332. package/packages/dashboard/ui/react-components/CommandPalette.tsx +0 -815
  333. package/packages/dashboard/ui/react-components/ConfirmationDialog.tsx +0 -133
  334. package/packages/dashboard/ui/react-components/ConversationHistory.tsx +0 -518
  335. package/packages/dashboard/ui/react-components/CoordinatorPanel.tsx +0 -944
  336. package/packages/dashboard/ui/react-components/DecisionQueue.tsx +0 -717
  337. package/packages/dashboard/ui/react-components/DirectMessageView.tsx +0 -164
  338. package/packages/dashboard/ui/react-components/FileAutocomplete.tsx +0 -368
  339. package/packages/dashboard/ui/react-components/FleetOverview.tsx +0 -278
  340. package/packages/dashboard/ui/react-components/LogViewer.tsx +0 -310
  341. package/packages/dashboard/ui/react-components/LogViewerPanel.tsx +0 -482
  342. package/packages/dashboard/ui/react-components/Logo.tsx +0 -284
  343. package/packages/dashboard/ui/react-components/MentionAutocomplete.tsx +0 -384
  344. package/packages/dashboard/ui/react-components/MessageComposer.tsx +0 -457
  345. package/packages/dashboard/ui/react-components/MessageList.tsx +0 -649
  346. package/packages/dashboard/ui/react-components/MessageSenderName.tsx +0 -91
  347. package/packages/dashboard/ui/react-components/MessageStatusIndicator.tsx +0 -142
  348. package/packages/dashboard/ui/react-components/NewConversationModal.tsx +0 -400
  349. package/packages/dashboard/ui/react-components/NotificationToast.tsx +0 -488
  350. package/packages/dashboard/ui/react-components/OnlineUsersIndicator.tsx +0 -164
  351. package/packages/dashboard/ui/react-components/Pagination.tsx +0 -124
  352. package/packages/dashboard/ui/react-components/PricingPlans.tsx +0 -386
  353. package/packages/dashboard/ui/react-components/ProjectList.tsx +0 -625
  354. package/packages/dashboard/ui/react-components/ProviderAuthFlow.tsx +0 -853
  355. package/packages/dashboard/ui/react-components/ProviderConnectionList.tsx +0 -378
  356. package/packages/dashboard/ui/react-components/ProvisioningProgress.tsx +0 -730
  357. package/packages/dashboard/ui/react-components/RepoAccessPanel.tsx +0 -549
  358. package/packages/dashboard/ui/react-components/ServerCard.tsx +0 -202
  359. package/packages/dashboard/ui/react-components/SessionExpiredModal.tsx +0 -128
  360. package/packages/dashboard/ui/react-components/SpawnModal.tsx +0 -804
  361. package/packages/dashboard/ui/react-components/TaskAssignmentUI.tsx +0 -375
  362. package/packages/dashboard/ui/react-components/TerminalProviderSetup.tsx +0 -608
  363. package/packages/dashboard/ui/react-components/ThemeProvider.tsx +0 -325
  364. package/packages/dashboard/ui/react-components/ThinkingIndicator.tsx +0 -231
  365. package/packages/dashboard/ui/react-components/ThreadList.tsx +0 -198
  366. package/packages/dashboard/ui/react-components/ThreadPanel.tsx +0 -346
  367. package/packages/dashboard/ui/react-components/TrajectoryViewer.tsx +0 -698
  368. package/packages/dashboard/ui/react-components/TypingIndicator.tsx +0 -69
  369. package/packages/dashboard/ui/react-components/UsageBanner.tsx +0 -231
  370. package/packages/dashboard/ui/react-components/UserProfilePanel.tsx +0 -233
  371. package/packages/dashboard/ui/react-components/WorkspaceContext.tsx +0 -107
  372. package/packages/dashboard/ui/react-components/WorkspaceSelector.tsx +0 -234
  373. package/packages/dashboard/ui/react-components/WorkspaceStatusIndicator.tsx +0 -370
  374. package/packages/dashboard/ui/react-components/XTermInteractive.tsx +0 -510
  375. package/packages/dashboard/ui/react-components/XTermLogViewer.tsx +0 -719
  376. package/packages/dashboard/ui/react-components/channels/ChannelDialogs.tsx +0 -1411
  377. package/packages/dashboard/ui/react-components/channels/ChannelHeader.tsx +0 -317
  378. package/packages/dashboard/ui/react-components/channels/ChannelMessageList.tsx +0 -463
  379. package/packages/dashboard/ui/react-components/channels/ChannelViewV1.tsx +0 -146
  380. package/packages/dashboard/ui/react-components/channels/MessageInput.tsx +0 -288
  381. package/packages/dashboard/ui/react-components/channels/SearchInput.tsx +0 -172
  382. package/packages/dashboard/ui/react-components/channels/SearchResults.tsx +0 -336
  383. package/packages/dashboard/ui/react-components/channels/api.ts +0 -697
  384. package/packages/dashboard/ui/react-components/channels/index.ts +0 -76
  385. package/packages/dashboard/ui/react-components/channels/mockApi.ts +0 -344
  386. package/packages/dashboard/ui/react-components/channels/types.ts +0 -566
  387. package/packages/dashboard/ui/react-components/hooks/index.ts +0 -57
  388. package/packages/dashboard/ui/react-components/hooks/useAgentLogs.ts +0 -394
  389. package/packages/dashboard/ui/react-components/hooks/useAgents.ts +0 -127
  390. package/packages/dashboard/ui/react-components/hooks/useBroadcastDedup.ts +0 -86
  391. package/packages/dashboard/ui/react-components/hooks/useChannelAdmin.ts +0 -329
  392. package/packages/dashboard/ui/react-components/hooks/useChannelBrowser.ts +0 -239
  393. package/packages/dashboard/ui/react-components/hooks/useChannelCommands.ts +0 -138
  394. package/packages/dashboard/ui/react-components/hooks/useChannels.ts +0 -328
  395. package/packages/dashboard/ui/react-components/hooks/useDebounce.ts +0 -29
  396. package/packages/dashboard/ui/react-components/hooks/useDirectMessage.ts +0 -141
  397. package/packages/dashboard/ui/react-components/hooks/useMessages.ts +0 -309
  398. package/packages/dashboard/ui/react-components/hooks/useOrchestrator.ts +0 -364
  399. package/packages/dashboard/ui/react-components/hooks/usePinnedAgents.ts +0 -140
  400. package/packages/dashboard/ui/react-components/hooks/usePresence.ts +0 -340
  401. package/packages/dashboard/ui/react-components/hooks/useRecentRepos.ts +0 -130
  402. package/packages/dashboard/ui/react-components/hooks/useSession.ts +0 -209
  403. package/packages/dashboard/ui/react-components/hooks/useTrajectory.ts +0 -265
  404. package/packages/dashboard/ui/react-components/hooks/useWebSocket.ts +0 -169
  405. package/packages/dashboard/ui/react-components/hooks/useWorkspaceMembers.ts +0 -120
  406. package/packages/dashboard/ui/react-components/hooks/useWorkspaceRepos.ts +0 -73
  407. package/packages/dashboard/ui/react-components/hooks/useWorkspaceStatus.ts +0 -237
  408. package/packages/dashboard/ui/react-components/index.ts +0 -81
  409. package/packages/dashboard/ui/react-components/layout/Header.tsx +0 -355
  410. package/packages/dashboard/ui/react-components/layout/RepoContextHeader.tsx +0 -361
  411. package/packages/dashboard/ui/react-components/layout/Sidebar.archive.test.tsx +0 -126
  412. package/packages/dashboard/ui/react-components/layout/Sidebar.test.tsx +0 -691
  413. package/packages/dashboard/ui/react-components/layout/Sidebar.tsx +0 -930
  414. package/packages/dashboard/ui/react-components/layout/index.ts +0 -7
  415. package/packages/dashboard/ui/react-components/settings/BillingSettingsPanel.tsx +0 -564
  416. package/packages/dashboard/ui/react-components/settings/SettingsPage.tsx +0 -544
  417. package/packages/dashboard/ui/react-components/settings/TeamSettingsPanel.tsx +0 -560
  418. package/packages/dashboard/ui/react-components/settings/WorkspaceSettingsPanel.tsx +0 -1386
  419. package/packages/dashboard/ui/react-components/settings/index.ts +0 -11
  420. package/packages/dashboard/ui/react-components/settings/types.ts +0 -53
  421. package/packages/dashboard/ui/react-components/utils/messageFormatting.tsx +0 -370
  422. package/packages/dashboard/ui/tailwind.config.js +0 -148
  423. package/packages/dashboard/ui/types/index.ts +0 -304
  424. package/packages/dashboard/ui/types/threading.ts +0 -7
  425. package/packages/dashboard/ui-dist/404.html +0 -1
  426. package/packages/dashboard/ui-dist/_next/static/91mkGYq3qbG8WHE6VytQ8/_buildManifest.js +0 -1
  427. package/packages/dashboard/ui-dist/_next/static/91mkGYq3qbG8WHE6VytQ8/_ssgManifest.js +0 -1
  428. package/packages/dashboard/ui-dist/_next/static/T2rV14eEU5OweDeV29SvG/_buildManifest.js +0 -1
  429. package/packages/dashboard/ui-dist/_next/static/T2rV14eEU5OweDeV29SvG/_ssgManifest.js +0 -1
  430. package/packages/dashboard/ui-dist/_next/static/chunks/116-a883fca163f3a5bc.js +0 -1
  431. package/packages/dashboard/ui-dist/_next/static/chunks/117-c8afed19e821a35d.js +0 -2
  432. package/packages/dashboard/ui-dist/_next/static/chunks/282-980c2eb8fff20123.js +0 -1
  433. package/packages/dashboard/ui-dist/_next/static/chunks/320-a6304232cd0ee2ce.js +0 -1
  434. package/packages/dashboard/ui-dist/_next/static/chunks/532-bace199897eeab37.js +0 -9
  435. package/packages/dashboard/ui-dist/_next/static/chunks/631-16b905e5920f9b59.js +0 -1
  436. package/packages/dashboard/ui-dist/_next/static/chunks/648-acb2ff9f77cbfbd3.js +0 -1
  437. package/packages/dashboard/ui-dist/_next/static/chunks/766-2aea80818f7eb0d8.js +0 -1
  438. package/packages/dashboard/ui-dist/_next/static/chunks/83-26d2bde54616ee90.js +0 -1
  439. package/packages/dashboard/ui-dist/_next/static/chunks/847-f1f467060f32afff.js +0 -1
  440. package/packages/dashboard/ui-dist/_next/static/chunks/891-5cb1513eeb97a891.js +0 -1
  441. package/packages/dashboard/ui-dist/_next/static/chunks/app/_not-found/page-60501fddbafba9dc.js +0 -1
  442. package/packages/dashboard/ui-dist/_next/static/chunks/app/app/onboarding/page-9914652442f7e4fb.js +0 -1
  443. package/packages/dashboard/ui-dist/_next/static/chunks/app/app/page-366fb7c078d4e9e0.js +0 -1
  444. package/packages/dashboard/ui-dist/_next/static/chunks/app/cloud/link/page-fa1d5842aa90e8a6.js +0 -1
  445. package/packages/dashboard/ui-dist/_next/static/chunks/app/complete-profile/page-dd64bbdf66b639cd.js +0 -1
  446. package/packages/dashboard/ui-dist/_next/static/chunks/app/connect-repos/page-113060009ef35bc2.js +0 -1
  447. package/packages/dashboard/ui-dist/_next/static/chunks/app/history/page-9965d2483011b846.js +0 -1
  448. package/packages/dashboard/ui-dist/_next/static/chunks/app/layout-6b91e33784c20610.js +0 -1
  449. package/packages/dashboard/ui-dist/_next/static/chunks/app/login/page-435eceb0073be027.js +0 -1
  450. package/packages/dashboard/ui-dist/_next/static/chunks/app/metrics/page-1e37ef8e73940b40.js +0 -1
  451. package/packages/dashboard/ui-dist/_next/static/chunks/app/page-8119d4246743574e.js +0 -1
  452. package/packages/dashboard/ui-dist/_next/static/chunks/app/pricing/page-9db3ebdfa567a7c9.js +0 -1
  453. package/packages/dashboard/ui-dist/_next/static/chunks/app/providers/page-ecb16ffd3b36262b.js +0 -1
  454. package/packages/dashboard/ui-dist/_next/static/chunks/app/providers/setup/[provider]/page-4dbe33f0f7691b7c.js +0 -1
  455. package/packages/dashboard/ui-dist/_next/static/chunks/app/signup/page-c7a0a28341365ae0.js +0 -1
  456. package/packages/dashboard/ui-dist/_next/static/chunks/e868780c-48e5f147c90a3a41.js +0 -18
  457. package/packages/dashboard/ui-dist/_next/static/chunks/fd9d1056-609918ca7b6280bb.js +0 -1
  458. package/packages/dashboard/ui-dist/_next/static/chunks/framework-f66176bb897dc684.js +0 -1
  459. package/packages/dashboard/ui-dist/_next/static/chunks/main-311c3db74dcfadb7.js +0 -1
  460. package/packages/dashboard/ui-dist/_next/static/chunks/main-app-fdbeb09028f57c9f.js +0 -1
  461. package/packages/dashboard/ui-dist/_next/static/chunks/pages/_app-72b849fbd24ac258.js +0 -1
  462. package/packages/dashboard/ui-dist/_next/static/chunks/pages/_error-7ba65e1336b92748.js +0 -1
  463. package/packages/dashboard/ui-dist/_next/static/chunks/polyfills-42372ed130431b0a.js +0 -1
  464. package/packages/dashboard/ui-dist/_next/static/chunks/webpack-1cdd8ed57114d5e1.js +0 -1
  465. package/packages/dashboard/ui-dist/_next/static/css/4034f236dd1a3178.css +0 -1
  466. package/packages/dashboard/ui-dist/_next/static/css/6892f8422896ef7a.css +0 -1
  467. package/packages/dashboard/ui-dist/_next/static/l8L2OscDSR2vsMIlWcC48/_buildManifest.js +0 -1
  468. package/packages/dashboard/ui-dist/_next/static/l8L2OscDSR2vsMIlWcC48/_ssgManifest.js +0 -1
  469. package/packages/dashboard/ui-dist/alt-logos/agent-relay-logo-128.png +0 -0
  470. package/packages/dashboard/ui-dist/alt-logos/agent-relay-logo-256.png +0 -0
  471. package/packages/dashboard/ui-dist/alt-logos/agent-relay-logo-32.png +0 -0
  472. package/packages/dashboard/ui-dist/alt-logos/agent-relay-logo-512.png +0 -0
  473. package/packages/dashboard/ui-dist/alt-logos/agent-relay-logo-64.png +0 -0
  474. package/packages/dashboard/ui-dist/alt-logos/agent-relay-logo.svg +0 -45
  475. package/packages/dashboard/ui-dist/alt-logos/logo.svg +0 -38
  476. package/packages/dashboard/ui-dist/alt-logos/monogram-logo-128.png +0 -0
  477. package/packages/dashboard/ui-dist/alt-logos/monogram-logo-256.png +0 -0
  478. package/packages/dashboard/ui-dist/alt-logos/monogram-logo-32.png +0 -0
  479. package/packages/dashboard/ui-dist/alt-logos/monogram-logo-512.png +0 -0
  480. package/packages/dashboard/ui-dist/alt-logos/monogram-logo-64.png +0 -0
  481. package/packages/dashboard/ui-dist/alt-logos/monogram-logo.svg +0 -38
  482. package/packages/dashboard/ui-dist/app/onboarding.html +0 -1
  483. package/packages/dashboard/ui-dist/app/onboarding.txt +0 -7
  484. package/packages/dashboard/ui-dist/app.html +0 -1
  485. package/packages/dashboard/ui-dist/app.txt +0 -7
  486. package/packages/dashboard/ui-dist/apple-icon.png +0 -0
  487. package/packages/dashboard/ui-dist/cloud/link.html +0 -1
  488. package/packages/dashboard/ui-dist/cloud/link.txt +0 -7
  489. package/packages/dashboard/ui-dist/complete-profile.html +0 -5
  490. package/packages/dashboard/ui-dist/complete-profile.txt +0 -7
  491. package/packages/dashboard/ui-dist/connect-repos.html +0 -1
  492. package/packages/dashboard/ui-dist/connect-repos.txt +0 -7
  493. package/packages/dashboard/ui-dist/history.html +0 -1
  494. package/packages/dashboard/ui-dist/history.txt +0 -7
  495. package/packages/dashboard/ui-dist/index.html +0 -1
  496. package/packages/dashboard/ui-dist/index.txt +0 -7
  497. package/packages/dashboard/ui-dist/login.html +0 -5
  498. package/packages/dashboard/ui-dist/login.txt +0 -7
  499. package/packages/dashboard/ui-dist/metrics.html +0 -1
  500. package/packages/dashboard/ui-dist/metrics.txt +0 -7
  501. package/packages/dashboard/ui-dist/pricing.html +0 -13
  502. package/packages/dashboard/ui-dist/pricing.txt +0 -7
  503. package/packages/dashboard/ui-dist/providers/setup/claude.html +0 -1
  504. package/packages/dashboard/ui-dist/providers/setup/claude.txt +0 -8
  505. package/packages/dashboard/ui-dist/providers/setup/codex.html +0 -1
  506. package/packages/dashboard/ui-dist/providers/setup/codex.txt +0 -8
  507. package/packages/dashboard/ui-dist/providers/setup/cursor.html +0 -1
  508. package/packages/dashboard/ui-dist/providers/setup/cursor.txt +0 -8
  509. package/packages/dashboard/ui-dist/providers.html +0 -1
  510. package/packages/dashboard/ui-dist/providers.txt +0 -7
  511. package/packages/dashboard/ui-dist/signup.html +0 -6
  512. package/packages/dashboard/ui-dist/signup.txt +0 -7
  513. package/packages/dashboard-server/dist/health-worker-manager.d.ts +0 -62
  514. package/packages/dashboard-server/dist/health-worker-manager.js +0 -144
  515. package/packages/dashboard-server/dist/health-worker.d.ts +0 -9
  516. package/packages/dashboard-server/dist/health-worker.js +0 -79
  517. package/packages/dashboard-server/dist/index.d.ts +0 -18
  518. package/packages/dashboard-server/dist/index.js +0 -17
  519. package/packages/dashboard-server/dist/metrics.d.ts +0 -105
  520. package/packages/dashboard-server/dist/metrics.js +0 -193
  521. package/packages/dashboard-server/dist/needs-attention.d.ts +0 -24
  522. package/packages/dashboard-server/dist/needs-attention.js +0 -78
  523. package/packages/dashboard-server/dist/server.d.ts +0 -25
  524. package/packages/dashboard-server/dist/server.js +0 -5158
  525. package/packages/dashboard-server/dist/start.d.ts +0 -6
  526. package/packages/dashboard-server/dist/start.js +0 -13
  527. package/packages/dashboard-server/dist/types/threading.d.ts +0 -8
  528. package/packages/dashboard-server/dist/types/threading.js +0 -2
  529. package/packages/dashboard-server/dist/user-bridge.d.ts +0 -158
  530. package/packages/dashboard-server/dist/user-bridge.js +0 -390
  531. package/packages/dashboard-server/package.json +0 -55
  532. package/scripts/run-migrations.js +0 -43
  533. package/scripts/setup-stripe-products.ts +0 -312
  534. package/scripts/verify-schema.js +0 -134
@@ -1,667 +0,0 @@
1
- /**
2
- * Dashboard V2 - Main App Page
3
- *
4
- * In cloud mode: Shows workspace selection and connects to selected workspace's dashboard.
5
- * In local mode: Connects to local daemon WebSocket.
6
- */
7
-
8
- 'use client';
9
-
10
- import React, { useState, useEffect, useCallback } from 'react';
11
- import { App } from '../../react-components/App';
12
- import { CloudSessionProvider } from '../../react-components/CloudSessionProvider';
13
- import { LogoIcon } from '../../react-components/Logo';
14
- import { setActiveWorkspaceId } from '../../lib/api';
15
- import { ProvisioningProgress } from '../../react-components/ProvisioningProgress';
16
- import { ProviderConnectionList, type ProviderInfo } from '../../react-components/ProviderConnectionList';
17
-
18
- interface Workspace {
19
- id: string;
20
- name: string;
21
- status: 'provisioning' | 'running' | 'stopped' | 'error';
22
- publicUrl?: string;
23
- providers?: string[];
24
- repositories?: string[];
25
- createdAt: string;
26
- }
27
-
28
- interface Repository {
29
- id: string;
30
- fullName: string;
31
- isPrivate: boolean;
32
- defaultBranch: string;
33
- syncStatus: string;
34
- hasNangoConnection: boolean;
35
- }
36
-
37
- type PageState = 'loading' | 'local' | 'select-workspace' | 'no-workspaces' | 'provisioning' | 'connect-provider' | 'connecting' | 'connected' | 'error';
38
-
39
- interface ProvisioningInfo {
40
- workspaceId: string;
41
- workspaceName: string;
42
- stage: string | null;
43
- startedAt: number;
44
- }
45
-
46
- // Available AI providers
47
- const AI_PROVIDERS: ProviderInfo[] = [
48
- { id: 'anthropic', name: 'Anthropic', displayName: 'Claude', color: '#D97757', cliCommand: 'claude' },
49
- { id: 'codex', name: 'OpenAI', displayName: 'Codex', color: '#10A37F', cliCommand: 'codex login', supportsDeviceFlow: true, requiresUrlCopy: true },
50
- { id: 'google', name: 'Google', displayName: 'Gemini', color: '#4285F4', cliCommand: 'gemini' },
51
- { id: 'opencode', name: 'OpenCode', displayName: 'OpenCode', color: '#00D4AA', cliCommand: 'opencode' },
52
- { id: 'droid', name: 'Factory', displayName: 'Droid', color: '#6366F1', cliCommand: 'droid' },
53
- { id: 'cursor', name: 'Cursor', displayName: 'Cursor', color: '#7C3AED', cliCommand: 'agent' },
54
- ];
55
-
56
- // Force cloud mode via env var - prevents silent fallback to local mode
57
- const FORCE_CLOUD_MODE = process.env.NEXT_PUBLIC_FORCE_CLOUD_MODE === 'true';
58
-
59
- export default function DashboardPage() {
60
- const [state, setState] = useState<PageState>('loading');
61
- const [workspaces, setWorkspaces] = useState<Workspace[]>([]);
62
- const [repos, setRepos] = useState<Repository[]>([]);
63
- const [selectedWorkspace, setSelectedWorkspace] = useState<Workspace | null>(null);
64
- const [wsUrl, setWsUrl] = useState<string | undefined>(undefined);
65
- const [error, setError] = useState<string | null>(null);
66
- // Track cloud mode for potential future use
67
- const [_isCloudMode, setIsCloudMode] = useState(FORCE_CLOUD_MODE);
68
- const [csrfToken, setCsrfToken] = useState<string | null>(null);
69
- const [provisioningInfo, setProvisioningInfo] = useState<ProvisioningInfo | null>(null);
70
- const [connectedProviders, setConnectedProviders] = useState<string[]>([]);
71
-
72
- // Check if we're in cloud mode and fetch data
73
- useEffect(() => {
74
- const init = async () => {
75
- try {
76
- // Check session to determine if we're in cloud mode
77
- const sessionRes = await fetch('/api/auth/session', { credentials: 'include' });
78
-
79
- // If session endpoint doesn't exist (404), we're in local mode
80
- if (sessionRes.status === 404) {
81
- if (FORCE_CLOUD_MODE) {
82
- throw new Error('Cloud mode enforced but session endpoint returned 404. Is the cloud server running?');
83
- }
84
- setIsCloudMode(false);
85
- setState('local');
86
- return;
87
- }
88
-
89
- // Capture CSRF token from response header
90
- const token = sessionRes.headers.get('X-CSRF-Token');
91
- if (token) {
92
- setCsrfToken(token);
93
- }
94
-
95
- const session = await sessionRes.json();
96
-
97
- if (!session.authenticated) {
98
- // Cloud mode but not authenticated - redirect to login
99
- window.location.href = '/login';
100
- return;
101
- }
102
-
103
- // Cloud mode - fetch workspaces and repos
104
- setIsCloudMode(true);
105
-
106
- // Track which providers are already connected
107
- // Map backend IDs to frontend IDs for consistency
108
- const BACKEND_TO_FRONTEND_MAP: Record<string, string> = {
109
- openai: 'codex', // Backend stores 'openai', frontend uses 'codex'
110
- };
111
- if (session.connectedProviders) {
112
- const providers: string[] = [];
113
- session.connectedProviders.forEach((p: { provider: string }) => {
114
- providers.push(p.provider);
115
- // Also add the frontend ID if there's a mapping
116
- const frontendId = BACKEND_TO_FRONTEND_MAP[p.provider];
117
- if (frontendId) {
118
- providers.push(frontendId);
119
- }
120
- });
121
- setConnectedProviders(providers);
122
- }
123
-
124
- const [workspacesRes, reposRes] = await Promise.all([
125
- // Use /accessible to include workspaces user can access via GitHub repo permissions
126
- fetch('/api/workspaces/accessible', { credentials: 'include' }),
127
- fetch('/api/github-app/repos', { credentials: 'include' }),
128
- ]);
129
-
130
- if (!workspacesRes.ok) {
131
- if (workspacesRes.status === 401) {
132
- window.location.href = '/login';
133
- return;
134
- }
135
- throw new Error('Failed to fetch workspaces');
136
- }
137
-
138
- const workspacesData = await workspacesRes.json();
139
- const reposData = reposRes.ok ? await reposRes.json() : { repositories: [] };
140
-
141
- setWorkspaces(workspacesData.workspaces || []);
142
- setRepos(reposData.repositories || []);
143
-
144
- // Determine next state based on workspace availability
145
- const runningWorkspaces = (workspacesData.workspaces || []).filter(
146
- (w: Workspace) => w.status === 'running' && w.publicUrl
147
- );
148
-
149
- if (runningWorkspaces.length === 1) {
150
- // Auto-connect to the only running workspace
151
- connectToWorkspace(runningWorkspaces[0]);
152
- } else if (runningWorkspaces.length > 1) {
153
- setState('select-workspace');
154
- } else if ((workspacesData.workspaces || []).length > 0) {
155
- // Has workspaces but none running
156
- setState('select-workspace');
157
- } else if ((reposData.repositories || []).length > 0) {
158
- // Has repos but no workspaces - show create workspace
159
- setState('no-workspaces');
160
- } else {
161
- // No repos, no workspaces - redirect to connect repos
162
- window.location.href = '/connect-repos';
163
- }
164
- } catch (err) {
165
- // If session check fails with network error, assume local mode (unless forced cloud)
166
- if (err instanceof TypeError && err.message.includes('Failed to fetch')) {
167
- if (FORCE_CLOUD_MODE) {
168
- console.error('Cloud mode enforced but network request failed:', err);
169
- setError('Cloud mode enforced but failed to connect to server. Is the cloud server running?');
170
- setState('error');
171
- return;
172
- }
173
- setIsCloudMode(false);
174
- setState('local');
175
- return;
176
- }
177
- console.error('Init error:', err);
178
- setError(err instanceof Error ? err.message : 'Failed to initialize');
179
- setState('error');
180
- }
181
- };
182
-
183
- init();
184
- }, []);
185
-
186
- const connectToWorkspace = useCallback((workspace: Workspace) => {
187
- if (!workspace.publicUrl) {
188
- setError('Workspace has no public URL');
189
- setState('error');
190
- return;
191
- }
192
-
193
- setSelectedWorkspace(workspace);
194
- setState('connecting');
195
-
196
- // Set the active workspace ID for API proxying
197
- setActiveWorkspaceId(workspace.id);
198
-
199
- // Derive WebSocket URL from public URL
200
- // e.g., https://workspace-abc.agentrelay.dev -> wss://workspace-abc.agentrelay.dev/ws
201
- const url = new URL(workspace.publicUrl);
202
- const wsProtocol = url.protocol === 'https:' ? 'wss:' : 'ws:';
203
- const derivedWsUrl = `${wsProtocol}//${url.host}/ws`;
204
-
205
- setWsUrl(derivedWsUrl);
206
- setState('connected');
207
- }, []);
208
-
209
- const handleCreateWorkspace = useCallback(async (repoFullName: string) => {
210
- setError(null);
211
-
212
- try {
213
- const headers: Record<string, string> = { 'Content-Type': 'application/json' };
214
- if (csrfToken) {
215
- headers['X-CSRF-Token'] = csrfToken;
216
- }
217
-
218
- const res = await fetch('/api/workspaces/quick', {
219
- method: 'POST',
220
- credentials: 'include',
221
- headers,
222
- body: JSON.stringify({ repositoryFullName: repoFullName }),
223
- });
224
-
225
- const data = await res.json();
226
-
227
- if (!res.ok) {
228
- throw new Error(data.error || 'Failed to create workspace');
229
- }
230
-
231
- // Set provisioning state with workspace info
232
- const startedAt = Date.now();
233
- setProvisioningInfo({
234
- workspaceId: data.workspaceId,
235
- workspaceName: repoFullName.split('/')[1] || repoFullName,
236
- stage: null,
237
- startedAt,
238
- });
239
- setState('provisioning');
240
-
241
- // Poll for workspace to be ready
242
- // Cloud deployments (Fly.io) can take 3-5 minutes for cold starts
243
- const pollForReady = async (workspaceId: string) => {
244
- const maxAttempts = 150; // 5 minutes with 2s interval
245
- const pollIntervalMs = 2000;
246
- let attempts = 0;
247
-
248
- while (attempts < maxAttempts) {
249
- const statusRes = await fetch(`/api/workspaces/${workspaceId}/status`, {
250
- credentials: 'include',
251
- });
252
- const statusData = await statusRes.json();
253
-
254
- // Update provisioning stage if available
255
- if (statusData.provisioning?.stage) {
256
- setProvisioningInfo(prev => prev ? {
257
- ...prev,
258
- stage: statusData.provisioning.stage,
259
- } : null);
260
- }
261
-
262
- if (statusData.status === 'running') {
263
- // Fetch updated workspace info
264
- const wsRes = await fetch(`/api/workspaces/${workspaceId}`, {
265
- credentials: 'include',
266
- });
267
- const wsData = await wsRes.json();
268
- if (wsData.publicUrl) {
269
- // Clear provisioning info and show provider connection screen
270
- setProvisioningInfo(null);
271
- setSelectedWorkspace(wsData);
272
- setState('connect-provider');
273
- return;
274
- }
275
- } else if (statusData.status === 'error') {
276
- const errorMsg = statusData.errorMessage || 'Workspace provisioning failed';
277
- throw new Error(errorMsg);
278
- }
279
-
280
- await new Promise(resolve => setTimeout(resolve, pollIntervalMs));
281
- attempts++;
282
-
283
- // Log progress every 30 seconds
284
- if (attempts % 15 === 0) {
285
- console.log(`[workspace] Still provisioning... (${Math.floor(attempts * pollIntervalMs / 1000)}s elapsed)`);
286
- }
287
- }
288
-
289
- throw new Error('Workspace provisioning timed out after 5 minutes. Please try again or contact support.');
290
- };
291
-
292
- await pollForReady(data.workspaceId);
293
- } catch (err) {
294
- console.error('Create workspace error:', err);
295
- setProvisioningInfo(null);
296
- setError(err instanceof Error ? err.message : 'Failed to create workspace');
297
- setState('no-workspaces');
298
- }
299
- }, [connectToWorkspace, csrfToken]);
300
-
301
- // Handle provider connection success
302
- const handleProviderConnected = useCallback((providerId: string) => {
303
- setConnectedProviders(prev => [...new Set([...prev, providerId])]);
304
- }, []);
305
-
306
- // Skip provider connection and continue to workspace
307
- const handleSkipProvider = useCallback(() => {
308
- if (selectedWorkspace) {
309
- connectToWorkspace(selectedWorkspace);
310
- }
311
- }, [selectedWorkspace, connectToWorkspace]);
312
-
313
- const handleStartWorkspace = useCallback(async (workspace: Workspace) => {
314
- setState('loading');
315
- setError(null);
316
-
317
- try {
318
- const headers: Record<string, string> = {};
319
- if (csrfToken) {
320
- headers['X-CSRF-Token'] = csrfToken;
321
- }
322
-
323
- const res = await fetch(`/api/workspaces/${workspace.id}/restart`, {
324
- method: 'POST',
325
- credentials: 'include',
326
- headers,
327
- });
328
-
329
- if (!res.ok) {
330
- const data = await res.json();
331
- throw new Error(data.error || 'Failed to start workspace');
332
- }
333
-
334
- // Poll for workspace to be ready
335
- const maxAttempts = 60;
336
- let attempts = 0;
337
-
338
- while (attempts < maxAttempts) {
339
- const statusRes = await fetch(`/api/workspaces/${workspace.id}/status`, {
340
- credentials: 'include',
341
- });
342
- const statusData = await statusRes.json();
343
-
344
- if (statusData.status === 'running') {
345
- const wsRes = await fetch(`/api/workspaces/${workspace.id}`, {
346
- credentials: 'include',
347
- });
348
- const wsData = await wsRes.json();
349
- if (wsData.publicUrl) {
350
- connectToWorkspace({ ...workspace, ...wsData });
351
- return;
352
- }
353
- }
354
-
355
- await new Promise(resolve => setTimeout(resolve, 2000));
356
- attempts++;
357
- }
358
-
359
- throw new Error('Workspace start timed out');
360
- } catch (err) {
361
- console.error('Start workspace error:', err);
362
- setError(err instanceof Error ? err.message : 'Failed to start workspace');
363
- setState('select-workspace');
364
- }
365
- }, [connectToWorkspace, csrfToken]);
366
-
367
- // Loading state
368
- if (state === 'loading') {
369
- return (
370
- <div className="min-h-screen bg-gradient-to-br from-[#0a0a0f] via-[#0d1117] to-[#0a0a0f] flex items-center justify-center">
371
- <div className="text-center">
372
- <svg className="w-8 h-8 text-accent-cyan animate-spin mx-auto" fill="none" viewBox="0 0 24 24">
373
- <circle className="opacity-25" cx="12" cy="12" r="10" stroke="currentColor" strokeWidth="4" />
374
- <path className="opacity-75" fill="currentColor" d="M4 12a8 8 0 018-8V0C5.373 0 0 5.373 0 12h4z" />
375
- </svg>
376
- <p className="mt-4 text-text-muted">Loading...</p>
377
- </div>
378
- </div>
379
- );
380
- }
381
-
382
- // Local mode - just render the App component
383
- if (state === 'local') {
384
- return <App />;
385
- }
386
-
387
- // Connected to workspace - render App with workspace's WebSocket
388
- // Wrap in CloudSessionProvider so App has access to cloud session context
389
- if (state === 'connected' && wsUrl) {
390
- return (
391
- <CloudSessionProvider cloudMode={true}>
392
- <App wsUrl={wsUrl} />
393
- </CloudSessionProvider>
394
- );
395
- }
396
-
397
- // Connecting state
398
- if (state === 'connecting') {
399
- return (
400
- <div className="min-h-screen bg-gradient-to-br from-[#0a0a0f] via-[#0d1117] to-[#0a0a0f] flex items-center justify-center">
401
- <div className="text-center">
402
- <svg className="w-8 h-8 text-accent-cyan animate-spin mx-auto" fill="none" viewBox="0 0 24 24">
403
- <circle className="opacity-25" cx="12" cy="12" r="10" stroke="currentColor" strokeWidth="4" />
404
- <path className="opacity-75" fill="currentColor" d="M4 12a8 8 0 018-8V0C5.373 0 0 5.373 0 12h4z" />
405
- </svg>
406
- <p className="mt-4 text-white font-medium">Connecting to {selectedWorkspace?.name}...</p>
407
- <p className="mt-2 text-text-muted text-sm">{selectedWorkspace?.publicUrl}</p>
408
- </div>
409
- </div>
410
- );
411
- }
412
-
413
- // Provisioning state - show progress UI
414
- if (state === 'provisioning' && provisioningInfo) {
415
- return (
416
- <div className="min-h-screen bg-gradient-to-br from-[#0a0a0f] via-[#0d1117] to-[#0a0a0f] flex items-center justify-center">
417
- <div className="w-full max-w-xl">
418
- <ProvisioningProgress
419
- isProvisioning={true}
420
- currentStage={provisioningInfo.stage}
421
- workspaceName={provisioningInfo.workspaceName}
422
- error={error}
423
- onCancel={() => {
424
- setProvisioningInfo(null);
425
- setState('no-workspaces');
426
- }}
427
- />
428
- </div>
429
- </div>
430
- );
431
- }
432
-
433
- // Error state
434
- if (state === 'error') {
435
- return (
436
- <div className="min-h-screen bg-gradient-to-br from-[#0a0a0f] via-[#0d1117] to-[#0a0a0f] flex items-center justify-center p-4">
437
- <div className="bg-bg-primary/80 backdrop-blur-sm border border-border-subtle rounded-2xl p-8 max-w-md w-full text-center">
438
- <div className="w-16 h-16 mx-auto mb-4 bg-error/20 rounded-full flex items-center justify-center">
439
- <svg className="w-8 h-8 text-error" fill="none" viewBox="0 0 24 24" stroke="currentColor">
440
- <path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d="M6 18L18 6M6 6l12 12" />
441
- </svg>
442
- </div>
443
- <h2 className="text-xl font-semibold text-white mb-2">Something went wrong</h2>
444
- <p className="text-text-muted mb-6">{error}</p>
445
- <button
446
- onClick={() => window.location.reload()}
447
- className="w-full py-3 px-4 bg-bg-tertiary border border-border-subtle rounded-xl text-white font-medium hover:bg-bg-hover transition-colors"
448
- >
449
- Try Again
450
- </button>
451
- </div>
452
- </div>
453
- );
454
- }
455
-
456
- // Connect provider state - show after workspace is ready
457
- if (state === 'connect-provider' && selectedWorkspace) {
458
- return (
459
- <div className="min-h-screen bg-gradient-to-br from-[#0a0a0f] via-[#0d1117] to-[#0a0a0f] flex flex-col items-center justify-center p-4">
460
- {/* Background grid */}
461
- <div className="fixed inset-0 opacity-10 pointer-events-none">
462
- <div
463
- className="absolute inset-0"
464
- style={{
465
- backgroundImage: `linear-gradient(rgba(0, 217, 255, 0.1) 1px, transparent 1px),
466
- linear-gradient(90deg, rgba(0, 217, 255, 0.1) 1px, transparent 1px)`,
467
- backgroundSize: '50px 50px',
468
- }}
469
- />
470
- </div>
471
-
472
- <div className="relative z-10 w-full max-w-xl">
473
- {/* Logo */}
474
- <div className="flex flex-col items-center mb-8">
475
- <LogoIcon size={48} withGlow={true} />
476
- <h1 className="mt-4 text-2xl font-bold text-white">Connect AI Provider</h1>
477
- <p className="mt-2 text-text-muted text-center">
478
- Your workspace <span className="text-white">{selectedWorkspace.name}</span> is ready!
479
- <br />Connect an AI provider to start using agents.
480
- </p>
481
- </div>
482
-
483
- {/* Shared provider connection component */}
484
- <ProviderConnectionList
485
- providers={AI_PROVIDERS}
486
- connectedProviders={connectedProviders}
487
- workspaceId={selectedWorkspace.id}
488
- csrfToken={csrfToken || undefined}
489
- onProviderConnected={handleProviderConnected}
490
- onContinue={handleSkipProvider}
491
- showDetailedInfo={true}
492
- />
493
- </div>
494
- </div>
495
- );
496
- }
497
-
498
- // Workspace selection / no workspaces UI
499
- return (
500
- <div className="min-h-screen bg-gradient-to-br from-[#0a0a0f] via-[#0d1117] to-[#0a0a0f] flex flex-col items-center justify-center p-4">
501
- {/* Background grid */}
502
- <div className="fixed inset-0 opacity-10 pointer-events-none">
503
- <div
504
- className="absolute inset-0"
505
- style={{
506
- backgroundImage: `linear-gradient(rgba(0, 217, 255, 0.1) 1px, transparent 1px),
507
- linear-gradient(90deg, rgba(0, 217, 255, 0.1) 1px, transparent 1px)`,
508
- backgroundSize: '50px 50px',
509
- }}
510
- />
511
- </div>
512
-
513
- <div className="relative z-10 w-full max-w-2xl">
514
- {/* Logo */}
515
- <div className="flex flex-col items-center mb-8">
516
- <LogoIcon size={48} withGlow={true} />
517
- <h1 className="mt-4 text-2xl font-bold text-white">Agent Relay</h1>
518
- <p className="mt-2 text-text-muted">
519
- {state === 'no-workspaces' ? 'Create a workspace to get started' : 'Select a workspace'}
520
- </p>
521
- </div>
522
-
523
- {error && (
524
- <div className="mb-4 p-4 bg-error/10 border border-error/20 rounded-xl">
525
- <p className="text-error">{error}</p>
526
- </div>
527
- )}
528
-
529
- {/* Workspaces list */}
530
- {state === 'select-workspace' && workspaces.length > 0 && (
531
- <div className="bg-bg-primary/80 backdrop-blur-sm border border-border-subtle rounded-2xl p-6">
532
- <h2 className="text-lg font-semibold text-white mb-4">Your Workspaces</h2>
533
- <div className="space-y-3">
534
- {workspaces.map((workspace) => (
535
- <div
536
- key={workspace.id}
537
- className="flex items-center justify-between p-4 bg-bg-tertiary rounded-xl border border-border-subtle hover:border-accent-cyan/50 transition-colors"
538
- >
539
- <div className="flex items-center gap-3">
540
- <div className={`w-3 h-3 rounded-full ${
541
- workspace.status === 'running' ? 'bg-success' :
542
- workspace.status === 'provisioning' ? 'bg-warning animate-pulse' :
543
- workspace.status === 'error' ? 'bg-error' : 'bg-gray-500'
544
- }`} />
545
- <div>
546
- <h3 className="font-medium text-white">{workspace.name}</h3>
547
- <p className="text-sm text-text-muted">
548
- {workspace.status === 'running' ? 'Running' :
549
- workspace.status === 'provisioning' ? 'Starting...' :
550
- workspace.status === 'stopped' ? 'Stopped' : 'Error'}
551
- </p>
552
- </div>
553
- </div>
554
- <div>
555
- {workspace.status === 'running' && workspace.publicUrl ? (
556
- <button
557
- onClick={() => connectToWorkspace(workspace)}
558
- className="py-2 px-4 bg-gradient-to-r from-accent-cyan to-[#00b8d9] text-bg-deep font-semibold rounded-lg hover:shadow-glow-cyan transition-all"
559
- >
560
- Connect
561
- </button>
562
- ) : workspace.status === 'stopped' ? (
563
- <button
564
- onClick={() => handleStartWorkspace(workspace)}
565
- className="py-2 px-4 bg-bg-card border border-border-subtle rounded-lg text-white hover:border-accent-cyan/50 transition-colors"
566
- >
567
- Start
568
- </button>
569
- ) : workspace.status === 'provisioning' ? (
570
- <span className="text-text-muted text-sm">Starting...</span>
571
- ) : (
572
- <span className="text-error text-sm">Failed</span>
573
- )}
574
- </div>
575
- </div>
576
- ))}
577
- </div>
578
-
579
- {repos.length > 0 && (
580
- <div className="mt-6 pt-6 border-t border-border-subtle">
581
- <p className="text-text-muted text-sm mb-3">Or create a new workspace:</p>
582
- <div className="flex gap-2 flex-wrap">
583
- {repos.slice(0, 3).map((repo) => (
584
- <button
585
- key={repo.id}
586
- onClick={() => handleCreateWorkspace(repo.fullName)}
587
- className="py-2 px-3 bg-bg-card border border-border-subtle rounded-lg text-sm text-text-muted hover:text-white hover:border-accent-cyan/50 transition-colors"
588
- >
589
- + {repo.fullName.split('/')[1]}
590
- </button>
591
- ))}
592
- </div>
593
- </div>
594
- )}
595
- </div>
596
- )}
597
-
598
- {/* No workspaces - create first one */}
599
- {state === 'no-workspaces' && (
600
- <div className="bg-bg-primary/80 backdrop-blur-sm border border-border-subtle rounded-2xl p-6">
601
- <h2 className="text-lg font-semibold text-white mb-4">Create Your First Workspace</h2>
602
- <p className="text-text-muted mb-6">
603
- Select a repository to create a workspace where agents can work on your code.
604
- </p>
605
-
606
- {repos.length > 0 ? (
607
- <div className="space-y-3">
608
- {repos.map((repo) => (
609
- <button
610
- key={repo.id}
611
- onClick={() => handleCreateWorkspace(repo.fullName)}
612
- className="w-full flex items-center gap-3 p-4 bg-bg-tertiary rounded-xl border border-border-subtle hover:border-accent-cyan/50 transition-colors text-left"
613
- >
614
- <svg className="w-5 h-5 text-text-muted flex-shrink-0" fill="currentColor" viewBox="0 0 16 16">
615
- <path d="M2 2.5A2.5 2.5 0 014.5 0h8.75a.75.75 0 01.75.75v12.5a.75.75 0 01-.75.75h-2.5a.75.75 0 110-1.5h1.75v-2h-8a1 1 0 00-.714 1.7.75.75 0 01-1.072 1.05A2.495 2.495 0 012 11.5v-9zm10.5-1V9h-8c-.356 0-.694.074-1 .208V2.5a1 1 0 011-1h8z" />
616
- </svg>
617
- <div className="flex-1 min-w-0">
618
- <p className="text-white font-medium truncate">{repo.fullName}</p>
619
- <p className="text-text-muted text-sm">{repo.isPrivate ? 'Private' : 'Public'}</p>
620
- </div>
621
- <svg className="w-5 h-5 text-text-muted" fill="none" viewBox="0 0 24 24" stroke="currentColor">
622
- <path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d="M9 5l7 7-7 7" />
623
- </svg>
624
- </button>
625
- ))}
626
- </div>
627
- ) : (
628
- <div className="text-center py-8">
629
- <p className="text-text-muted mb-4">No repositories connected yet.</p>
630
- <a
631
- href="/connect-repos"
632
- className="inline-flex items-center gap-2 py-3 px-6 bg-gradient-to-r from-accent-cyan to-[#00b8d9] text-bg-deep font-semibold rounded-xl hover:shadow-glow-cyan transition-all"
633
- >
634
- <svg className="w-5 h-5" fill="currentColor" viewBox="0 0 24 24">
635
- <path d="M12 0C5.37 0 0 5.37 0 12c0 5.31 3.435 9.795 8.205 11.385.6.105.825-.255.825-.57 0-.285-.015-1.23-.015-2.235-3.015.555-3.795-.735-4.035-1.41-.135-.345-.72-1.41-1.23-1.695-.42-.225-1.02-.78-.015-.795.945-.015 1.62.87 1.845 1.23 1.08 1.815 2.805 1.305 3.495.99.105-.78.42-1.305.765-1.605-2.67-.3-5.46-1.335-5.46-5.925 0-1.305.465-2.385 1.23-3.225-.12-.3-.54-1.53.12-3.18 0 0 1.005-.315 3.3 1.23.96-.27 1.98-.405 3-.405s2.04.135 3 .405c2.295-1.56 3.3-1.23 3.3-1.23.66 1.65.24 2.88.12 3.18.765.84 1.23 1.905 1.23 3.225 0 4.605-2.805 5.625-5.475 5.925.435.375.81 1.095.81 2.22 0 1.605-.015 2.895-.015 3.3 0 .315.225.69.825.57A12.02 12.02 0 0024 12c0-6.63-5.37-12-12-12z" />
636
- </svg>
637
- Connect GitHub
638
- </a>
639
- </div>
640
- )}
641
- </div>
642
- )}
643
-
644
- {/* Navigation */}
645
- <div className="mt-6 flex justify-center gap-4 text-sm">
646
- <a href="/connect-repos" className="text-text-muted hover:text-white transition-colors">
647
- Manage Repositories
648
- </a>
649
- <span className="text-text-muted">·</span>
650
- <button
651
- onClick={async () => {
652
- const headers: Record<string, string> = {};
653
- if (csrfToken) {
654
- headers['X-CSRF-Token'] = csrfToken;
655
- }
656
- await fetch('/api/auth/logout', { method: 'POST', credentials: 'include', headers });
657
- window.location.href = '/login';
658
- }}
659
- className="text-text-muted hover:text-white transition-colors"
660
- >
661
- Sign Out
662
- </button>
663
- </div>
664
- </div>
665
- </div>
666
- );
667
- }