agent-relay 1.2.0 → 1.3.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (668) hide show
  1. package/.gitattributes +3 -0
  2. package/.nvmrc +1 -0
  3. package/.trajectories/agent-relay-322-324.md +17 -0
  4. package/.trajectories/completed/2026-01/traj_03zupyv1s7b9.json +49 -0
  5. package/.trajectories/completed/2026-01/traj_03zupyv1s7b9.md +31 -0
  6. package/.trajectories/completed/2026-01/traj_0zacdjl1g4ht.json +125 -0
  7. package/.trajectories/completed/2026-01/traj_0zacdjl1g4ht.md +62 -0
  8. package/.trajectories/completed/2026-01/traj_1dviorhnkcb5.json +65 -0
  9. package/.trajectories/completed/2026-01/traj_1dviorhnkcb5.md +37 -0
  10. package/.trajectories/completed/2026-01/traj_1k5if5snst2e.json +65 -0
  11. package/.trajectories/completed/2026-01/traj_1k5if5snst2e.md +37 -0
  12. package/.trajectories/completed/2026-01/traj_1rp3rges5811.json +49 -0
  13. package/.trajectories/completed/2026-01/traj_1rp3rges5811.md +31 -0
  14. package/.trajectories/completed/2026-01/traj_22bhyulruouw.json +113 -0
  15. package/.trajectories/completed/2026-01/traj_22bhyulruouw.md +57 -0
  16. package/.trajectories/completed/2026-01/traj_2dao7ddgnta0.json +53 -0
  17. package/.trajectories/completed/2026-01/traj_2dao7ddgnta0.md +32 -0
  18. package/.trajectories/completed/2026-01/traj_33iuy72sezbk.json +49 -0
  19. package/.trajectories/completed/2026-01/traj_33iuy72sezbk.md +31 -0
  20. package/.trajectories/completed/2026-01/traj_3t0440mjeunc.json +26 -0
  21. package/.trajectories/completed/2026-01/traj_3t0440mjeunc.md +6 -0
  22. package/.trajectories/completed/2026-01/traj_45x9494d9xnr.json +47 -0
  23. package/.trajectories/completed/2026-01/traj_45x9494d9xnr.md +32 -0
  24. package/.trajectories/completed/2026-01/traj_4aa0bb77s4nh.json +53 -0
  25. package/.trajectories/completed/2026-01/traj_4aa0bb77s4nh.md +32 -0
  26. package/.trajectories/completed/2026-01/traj_5ammh5qtvklq.json +77 -0
  27. package/.trajectories/completed/2026-01/traj_5ammh5qtvklq.md +42 -0
  28. package/.trajectories/completed/2026-01/traj_5lhmzq8rxpqv.json +59 -0
  29. package/.trajectories/completed/2026-01/traj_5lhmzq8rxpqv.md +33 -0
  30. package/.trajectories/completed/2026-01/traj_5vr4e9erb1fs.json +53 -0
  31. package/.trajectories/completed/2026-01/traj_5vr4e9erb1fs.md +32 -0
  32. package/.trajectories/completed/2026-01/traj_6fgiwdoklvym.json +48 -0
  33. package/.trajectories/completed/2026-01/traj_6fgiwdoklvym.md +24 -0
  34. package/.trajectories/completed/2026-01/traj_6mieijqyvaag.json +77 -0
  35. package/.trajectories/completed/2026-01/traj_6mieijqyvaag.md +42 -0
  36. package/.trajectories/completed/2026-01/traj_78ffm31jn3uk.json +77 -0
  37. package/.trajectories/completed/2026-01/traj_78ffm31jn3uk.md +42 -0
  38. package/.trajectories/completed/2026-01/traj_7ludwvz45veh.json +209 -0
  39. package/.trajectories/completed/2026-01/traj_7ludwvz45veh.md +97 -0
  40. package/.trajectories/completed/2026-01/traj_94gnp3k30goq.json +66 -0
  41. package/.trajectories/completed/2026-01/traj_94gnp3k30goq.md +36 -0
  42. package/.trajectories/completed/2026-01/traj_9921cuhel0pj.json +48 -0
  43. package/.trajectories/completed/2026-01/traj_9921cuhel0pj.md +24 -0
  44. package/.trajectories/completed/2026-01/traj_ajs7zqfux4wc.json +49 -0
  45. package/.trajectories/completed/2026-01/traj_ajs7zqfux4wc.md +23 -0
  46. package/.trajectories/completed/2026-01/traj_avqeghu6pz5a.json +40 -0
  47. package/.trajectories/completed/2026-01/traj_avqeghu6pz5a.md +22 -0
  48. package/.trajectories/completed/2026-01/traj_cvtqhlwcq9s0.json +53 -0
  49. package/.trajectories/completed/2026-01/traj_cvtqhlwcq9s0.md +32 -0
  50. package/.trajectories/completed/2026-01/traj_cxofprm2m2en.json +49 -0
  51. package/.trajectories/completed/2026-01/traj_cxofprm2m2en.md +31 -0
  52. package/.trajectories/completed/2026-01/traj_d2hhz3k0vrhn.json +26 -0
  53. package/.trajectories/completed/2026-01/traj_d2hhz3k0vrhn.md +6 -0
  54. package/.trajectories/completed/2026-01/traj_dcsp9s8y01ra.json +121 -0
  55. package/.trajectories/completed/2026-01/traj_dcsp9s8y01ra.md +29 -0
  56. package/.trajectories/completed/2026-01/traj_dfuvww9pege5.json +59 -0
  57. package/.trajectories/completed/2026-01/traj_dfuvww9pege5.md +37 -0
  58. package/.trajectories/completed/2026-01/traj_fhx9irlckht6.json +53 -0
  59. package/.trajectories/completed/2026-01/traj_fhx9irlckht6.md +32 -0
  60. package/.trajectories/completed/2026-01/traj_fqduidx3xbtp.json +101 -0
  61. package/.trajectories/completed/2026-01/traj_fqduidx3xbtp.md +52 -0
  62. package/.trajectories/completed/2026-01/traj_g0fisy9h51mf.json +77 -0
  63. package/.trajectories/completed/2026-01/traj_g0fisy9h51mf.md +42 -0
  64. package/.trajectories/completed/2026-01/traj_gjdre5voouod.json +53 -0
  65. package/.trajectories/completed/2026-01/traj_gjdre5voouod.md +32 -0
  66. package/.trajectories/completed/2026-01/traj_gtlyqtta3x8l.json +25 -0
  67. package/.trajectories/completed/2026-01/traj_gtlyqtta3x8l.md +15 -0
  68. package/.trajectories/completed/2026-01/traj_h4xijiuip3w4.json +101 -0
  69. package/.trajectories/completed/2026-01/traj_h4xijiuip3w4.md +44 -0
  70. package/.trajectories/completed/2026-01/traj_hf81ey93uz6t.json +49 -0
  71. package/.trajectories/completed/2026-01/traj_hf81ey93uz6t.md +31 -0
  72. package/.trajectories/completed/2026-01/traj_hfmki2jr9d4r.json +65 -0
  73. package/.trajectories/completed/2026-01/traj_hfmki2jr9d4r.md +37 -0
  74. package/.trajectories/completed/2026-01/traj_hhxte7w4gjjx.json +22 -0
  75. package/.trajectories/completed/2026-01/traj_hhxte7w4gjjx.md +5 -0
  76. package/.trajectories/completed/2026-01/traj_hpungyhoj6v5.json +53 -0
  77. package/.trajectories/completed/2026-01/traj_hpungyhoj6v5.md +32 -0
  78. package/.trajectories/completed/2026-01/traj_lq450ly148uw.json +49 -0
  79. package/.trajectories/completed/2026-01/traj_lq450ly148uw.md +31 -0
  80. package/.trajectories/completed/2026-01/traj_m2xkjv0w2sq7.json +25 -0
  81. package/.trajectories/completed/2026-01/traj_m2xkjv0w2sq7.md +15 -0
  82. package/.trajectories/completed/2026-01/traj_multi_server_arch.md +101 -0
  83. package/.trajectories/completed/2026-01/traj_noq5zbvnrdvz.json +53 -0
  84. package/.trajectories/completed/2026-01/traj_noq5zbvnrdvz.md +32 -0
  85. package/.trajectories/completed/2026-01/traj_ntbs6ppopf46.json +53 -0
  86. package/.trajectories/completed/2026-01/traj_ntbs6ppopf46.md +32 -0
  87. package/.trajectories/completed/2026-01/traj_ozd98si6a7ns.json +48 -0
  88. package/.trajectories/completed/2026-01/traj_ozd98si6a7ns.md +24 -0
  89. package/.trajectories/completed/2026-01/traj_prdza7a5cxp5.json +53 -0
  90. package/.trajectories/completed/2026-01/traj_prdza7a5cxp5.md +32 -0
  91. package/.trajectories/completed/2026-01/traj_psd9ob0j2ru3.json +27 -0
  92. package/.trajectories/completed/2026-01/traj_psd9ob0j2ru3.md +14 -0
  93. package/.trajectories/completed/2026-01/traj_qb3twvvywfwi.json +77 -0
  94. package/.trajectories/completed/2026-01/traj_qb3twvvywfwi.md +42 -0
  95. package/.trajectories/completed/2026-01/traj_qft54mi7nfor.json +53 -0
  96. package/.trajectories/completed/2026-01/traj_qft54mi7nfor.md +32 -0
  97. package/.trajectories/completed/2026-01/traj_qx9uhf8whhxo.json +83 -0
  98. package/.trajectories/completed/2026-01/traj_qx9uhf8whhxo.md +47 -0
  99. package/.trajectories/completed/2026-01/traj_rd9toccj18a0.json +59 -0
  100. package/.trajectories/completed/2026-01/traj_rd9toccj18a0.md +37 -0
  101. package/.trajectories/completed/2026-01/traj_rt4fiw3ecp50.json +48 -0
  102. package/.trajectories/completed/2026-01/traj_rt4fiw3ecp50.md +16 -0
  103. package/.trajectories/completed/2026-01/traj_st8j35b0hrlc.json +59 -0
  104. package/.trajectories/completed/2026-01/traj_st8j35b0hrlc.md +37 -0
  105. package/.trajectories/completed/2026-01/traj_t1yy8m7hbuxp.json +53 -0
  106. package/.trajectories/completed/2026-01/traj_t1yy8m7hbuxp.md +32 -0
  107. package/.trajectories/completed/2026-01/traj_tmux_orchestrator_analysis.json +84 -0
  108. package/.trajectories/completed/2026-01/traj_tmux_orchestrator_analysis.md +109 -0
  109. package/.trajectories/completed/2026-01/traj_u9n9eqasw16k.json +53 -0
  110. package/.trajectories/completed/2026-01/traj_u9n9eqasw16k.md +32 -0
  111. package/.trajectories/completed/2026-01/traj_ub8csuv3lcv4.json +53 -0
  112. package/.trajectories/completed/2026-01/traj_ub8csuv3lcv4.md +32 -0
  113. package/.trajectories/completed/2026-01/traj_uc29tlso8i9s.json +186 -0
  114. package/.trajectories/completed/2026-01/traj_uc29tlso8i9s.md +86 -0
  115. package/.trajectories/completed/2026-01/traj_ui9b4tqxoa7j.json +77 -0
  116. package/.trajectories/completed/2026-01/traj_ui9b4tqxoa7j.md +42 -0
  117. package/.trajectories/completed/2026-01/traj_v87hypnongqx.json +71 -0
  118. package/.trajectories/completed/2026-01/traj_v87hypnongqx.md +42 -0
  119. package/.trajectories/completed/2026-01/traj_v9dkdoxylyid.json +89 -0
  120. package/.trajectories/completed/2026-01/traj_v9dkdoxylyid.md +47 -0
  121. package/.trajectories/completed/2026-01/traj_wkp2fgzdyinb.json +53 -0
  122. package/.trajectories/completed/2026-01/traj_wkp2fgzdyinb.md +32 -0
  123. package/.trajectories/completed/2026-01/traj_x14t8w8rn7xg.json +20 -0
  124. package/.trajectories/completed/2026-01/traj_x14t8w8rn7xg.md +6 -0
  125. package/.trajectories/completed/2026-01/traj_xnwbznkvv8ua.json +175 -0
  126. package/.trajectories/completed/2026-01/traj_xnwbznkvv8ua.md +82 -0
  127. package/.trajectories/completed/2026-01/traj_xy9vifpqet80.json +65 -0
  128. package/.trajectories/completed/2026-01/traj_xy9vifpqet80.md +37 -0
  129. package/.trajectories/completed/2026-01/traj_y7aiwijyfmmv.json +49 -0
  130. package/.trajectories/completed/2026-01/traj_y7aiwijyfmmv.md +31 -0
  131. package/.trajectories/completed/2026-01/traj_ysjc8zaeqtd3.json +47 -0
  132. package/.trajectories/completed/2026-01/traj_ysjc8zaeqtd3.md +32 -0
  133. package/.trajectories/completed/2026-01/traj_yvdadtvdgnz3.json +59 -0
  134. package/.trajectories/completed/2026-01/traj_yvdadtvdgnz3.md +37 -0
  135. package/.trajectories/completed/2026-01/traj_z0vcw1wrzide.json +53 -0
  136. package/.trajectories/completed/2026-01/traj_z0vcw1wrzide.md +32 -0
  137. package/.trajectories/consolidate-settings-panel.md +24 -0
  138. package/.trajectories/gh-cli-user-token.md +26 -0
  139. package/.trajectories/index.json +468 -0
  140. package/ARCHITECTURE.md +1245 -0
  141. package/TESTING.md +278 -0
  142. package/deploy/init-db.sql +5 -0
  143. package/deploy/scripts/setup-fly-workspaces.sh +69 -0
  144. package/deploy/scripts/setup-railway.sh +75 -0
  145. package/deploy/workspace/codex.config.toml +15 -0
  146. package/deploy/workspace/entrypoint-browser.sh +118 -0
  147. package/deploy/workspace/entrypoint.sh +508 -0
  148. package/deploy/workspace/git-credential-relay +126 -0
  149. package/dist/bridge/spawner.d.ts +7 -0
  150. package/dist/bridge/spawner.js +40 -9
  151. package/dist/bridge/types.d.ts +2 -0
  152. package/dist/cli/index.js +260 -1
  153. package/dist/cloud/api/admin.d.ts +8 -0
  154. package/dist/cloud/api/admin.js +212 -0
  155. package/dist/cloud/api/auth.js +8 -0
  156. package/dist/cloud/api/billing.d.ts +0 -10
  157. package/dist/cloud/api/billing.js +278 -67
  158. package/dist/cloud/api/codex-auth-helper.d.ts +21 -0
  159. package/dist/cloud/api/codex-auth-helper.js +307 -0
  160. package/dist/cloud/api/coordinators.js +402 -0
  161. package/dist/cloud/api/daemons.js +15 -11
  162. package/dist/cloud/api/git.js +127 -19
  163. package/dist/cloud/api/github-app.js +42 -8
  164. package/dist/cloud/api/nango-auth.js +297 -16
  165. package/dist/cloud/api/onboarding.js +112 -35
  166. package/dist/cloud/api/providers.js +12 -16
  167. package/dist/cloud/api/repos.d.ts +1 -0
  168. package/dist/cloud/api/repos.js +311 -49
  169. package/dist/cloud/api/test-helpers.js +40 -0
  170. package/dist/cloud/api/usage.js +13 -0
  171. package/dist/cloud/api/webhooks.d.ts +1 -0
  172. package/dist/cloud/api/webhooks.js +149 -0
  173. package/dist/cloud/api/workspaces.d.ts +18 -0
  174. package/dist/cloud/api/workspaces.js +1042 -21
  175. package/dist/cloud/billing/plans.js +19 -19
  176. package/dist/cloud/config.d.ts +8 -0
  177. package/dist/cloud/config.js +15 -0
  178. package/dist/cloud/db/drizzle.d.ts +5 -2
  179. package/dist/cloud/db/drizzle.js +27 -20
  180. package/dist/cloud/db/schema.d.ts +19 -51
  181. package/dist/cloud/db/schema.js +5 -4
  182. package/dist/cloud/index.d.ts +0 -1
  183. package/dist/cloud/index.js +0 -1
  184. package/dist/cloud/provisioner/index.d.ts +125 -1
  185. package/dist/cloud/provisioner/index.js +939 -53
  186. package/dist/cloud/server.js +161 -16
  187. package/dist/cloud/services/compute-enforcement.d.ts +57 -0
  188. package/dist/cloud/services/compute-enforcement.js +175 -0
  189. package/dist/cloud/services/index.d.ts +2 -0
  190. package/dist/cloud/services/index.js +4 -0
  191. package/dist/cloud/services/intro-expiration.d.ts +55 -0
  192. package/dist/cloud/services/intro-expiration.js +211 -0
  193. package/dist/cloud/services/nango.d.ts +74 -0
  194. package/dist/cloud/services/nango.js +218 -5
  195. package/dist/cloud/services/planLimits.d.ts +22 -0
  196. package/dist/cloud/services/planLimits.js +58 -5
  197. package/dist/cloud/services/ssh-security.d.ts +31 -0
  198. package/dist/cloud/services/ssh-security.js +63 -0
  199. package/dist/continuity/manager.d.ts +5 -0
  200. package/dist/continuity/manager.js +56 -2
  201. package/dist/daemon/api.d.ts +2 -0
  202. package/dist/daemon/api.js +214 -5
  203. package/dist/daemon/cli-auth.d.ts +13 -1
  204. package/dist/daemon/cli-auth.js +166 -47
  205. package/dist/daemon/connection.d.ts +7 -1
  206. package/dist/daemon/connection.js +15 -0
  207. package/dist/daemon/orchestrator.d.ts +2 -0
  208. package/dist/daemon/orchestrator.js +26 -0
  209. package/dist/daemon/repo-manager.d.ts +116 -0
  210. package/dist/daemon/repo-manager.js +384 -0
  211. package/dist/daemon/router.d.ts +60 -1
  212. package/dist/daemon/router.js +281 -20
  213. package/dist/daemon/user-directory.d.ts +111 -0
  214. package/dist/daemon/user-directory.js +233 -0
  215. package/dist/dashboard/out/404.html +1 -1
  216. package/dist/dashboard/out/_next/static/T1tgCqVWHFIkV7ClEtzD7/_ssgManifest.js +1 -0
  217. package/dist/dashboard/out/_next/static/chunks/532-bace199897eeab37.js +9 -0
  218. package/dist/dashboard/out/_next/static/chunks/766-b54f0853794b78c3.js +1 -0
  219. package/dist/dashboard/out/_next/static/chunks/83-b51836037078006c.js +1 -0
  220. package/dist/dashboard/out/_next/static/chunks/891-6cd50de1224f70bb.js +1 -0
  221. package/dist/dashboard/out/_next/static/chunks/899-bb19a9b3d9b39ea6.js +1 -0
  222. package/dist/dashboard/out/_next/static/chunks/app/app/onboarding/page-8939b0fc700f7eca.js +1 -0
  223. package/dist/dashboard/out/_next/static/chunks/app/app/page-5af1b6b439858aa6.js +1 -0
  224. package/dist/dashboard/out/_next/static/chunks/app/metrics/page-ac39dc0cc3c26fa7.js +1 -0
  225. package/dist/dashboard/out/_next/static/chunks/app/{page-daf87e86f783f980.js → page-4a5938c18a11a654.js} +1 -1
  226. package/dist/dashboard/out/_next/static/chunks/app/providers/page-ac3a6ac433fd6001.js +1 -0
  227. package/dist/dashboard/out/_next/static/chunks/app/providers/setup/[provider]/page-09f9caae98a18c09.js +1 -0
  228. package/dist/dashboard/out/_next/static/chunks/{main-97850e03d723ea8c.js → main-2ee6beb2ae96d210.js} +1 -1
  229. package/dist/dashboard/out/_next/static/css/85d2af9c7ac74d62.css +1 -0
  230. package/dist/dashboard/out/_next/static/css/fe4b28883eeff359.css +1 -0
  231. package/dist/dashboard/out/app/onboarding.html +1 -0
  232. package/dist/dashboard/out/app/onboarding.txt +7 -0
  233. package/dist/dashboard/out/app.html +1 -1
  234. package/dist/dashboard/out/app.txt +3 -3
  235. package/dist/dashboard/out/apple-icon.png +0 -0
  236. package/dist/dashboard/out/connect-repos.html +1 -1
  237. package/dist/dashboard/out/connect-repos.txt +3 -3
  238. package/dist/dashboard/out/history.html +1 -1
  239. package/dist/dashboard/out/history.txt +3 -3
  240. package/dist/dashboard/out/index.html +1 -1
  241. package/dist/dashboard/out/index.txt +3 -3
  242. package/dist/dashboard/out/login.html +2 -2
  243. package/dist/dashboard/out/login.txt +3 -3
  244. package/dist/dashboard/out/metrics.html +1 -1
  245. package/dist/dashboard/out/metrics.txt +3 -3
  246. package/dist/dashboard/out/pricing.html +3 -3
  247. package/dist/dashboard/out/pricing.txt +3 -3
  248. package/dist/dashboard/out/providers/setup/claude.html +1 -0
  249. package/dist/dashboard/out/providers/setup/claude.txt +8 -0
  250. package/dist/dashboard/out/providers/setup/codex.html +1 -0
  251. package/dist/dashboard/out/providers/setup/codex.txt +8 -0
  252. package/dist/dashboard/out/providers.html +1 -1
  253. package/dist/dashboard/out/providers.txt +3 -3
  254. package/dist/dashboard/out/signup.html +2 -2
  255. package/dist/dashboard/out/signup.txt +3 -3
  256. package/dist/dashboard-server/server.js +316 -12
  257. package/dist/dashboard-server/user-bridge.d.ts +103 -0
  258. package/dist/dashboard-server/user-bridge.js +189 -0
  259. package/dist/protocol/channels.d.ts +205 -0
  260. package/dist/protocol/channels.js +154 -0
  261. package/dist/protocol/types.d.ts +13 -1
  262. package/dist/resiliency/provider-context.js +2 -0
  263. package/dist/shared/cli-auth-config.d.ts +19 -0
  264. package/dist/shared/cli-auth-config.js +58 -2
  265. package/dist/utils/agent-config.js +1 -1
  266. package/dist/wrapper/auth-detection.d.ts +49 -0
  267. package/dist/wrapper/auth-detection.js +192 -0
  268. package/dist/wrapper/base-wrapper.d.ts +153 -0
  269. package/dist/wrapper/base-wrapper.js +393 -0
  270. package/dist/wrapper/client.d.ts +7 -1
  271. package/dist/wrapper/client.js +3 -0
  272. package/dist/wrapper/index.d.ts +1 -0
  273. package/dist/wrapper/index.js +4 -3
  274. package/dist/wrapper/pty-wrapper.d.ts +62 -84
  275. package/dist/wrapper/pty-wrapper.js +154 -180
  276. package/dist/wrapper/tmux-wrapper.d.ts +41 -66
  277. package/dist/wrapper/tmux-wrapper.js +90 -134
  278. package/package.json +5 -12
  279. package/scripts/postinstall.js +11 -155
  280. package/scripts/test-interactive-terminal.sh +248 -0
  281. package/test-push.txt +1 -0
  282. package/bin/tmux +0 -0
  283. package/dist/bridge/config.d.ts.map +0 -1
  284. package/dist/bridge/config.js.map +0 -1
  285. package/dist/bridge/index.d.ts.map +0 -1
  286. package/dist/bridge/index.js.map +0 -1
  287. package/dist/bridge/multi-project-client.d.ts.map +0 -1
  288. package/dist/bridge/multi-project-client.js.map +0 -1
  289. package/dist/bridge/shadow-cli.d.ts.map +0 -1
  290. package/dist/bridge/shadow-cli.js.map +0 -1
  291. package/dist/bridge/shadow-config.d.ts.map +0 -1
  292. package/dist/bridge/shadow-config.js.map +0 -1
  293. package/dist/bridge/spawner.d.ts.map +0 -1
  294. package/dist/bridge/spawner.js.map +0 -1
  295. package/dist/bridge/teams-config.d.ts.map +0 -1
  296. package/dist/bridge/teams-config.js.map +0 -1
  297. package/dist/bridge/types.d.ts.map +0 -1
  298. package/dist/bridge/types.js.map +0 -1
  299. package/dist/bridge/utils.d.ts.map +0 -1
  300. package/dist/bridge/utils.js.map +0 -1
  301. package/dist/cli/index.d.ts.map +0 -1
  302. package/dist/cli/index.js.map +0 -1
  303. package/dist/cloud/api/auth.d.ts.map +0 -1
  304. package/dist/cloud/api/auth.js.map +0 -1
  305. package/dist/cloud/api/billing.d.ts.map +0 -1
  306. package/dist/cloud/api/billing.js.map +0 -1
  307. package/dist/cloud/api/cli-pty-runner.d.ts.map +0 -1
  308. package/dist/cloud/api/cli-pty-runner.js.map +0 -1
  309. package/dist/cloud/api/coordinators.d.ts.map +0 -1
  310. package/dist/cloud/api/coordinators.js.map +0 -1
  311. package/dist/cloud/api/daemons.d.ts.map +0 -1
  312. package/dist/cloud/api/daemons.js.map +0 -1
  313. package/dist/cloud/api/generic-webhooks.d.ts.map +0 -1
  314. package/dist/cloud/api/generic-webhooks.js.map +0 -1
  315. package/dist/cloud/api/git.d.ts.map +0 -1
  316. package/dist/cloud/api/git.js.map +0 -1
  317. package/dist/cloud/api/github-app.d.ts.map +0 -1
  318. package/dist/cloud/api/github-app.js.map +0 -1
  319. package/dist/cloud/api/middleware/planLimits.d.ts.map +0 -1
  320. package/dist/cloud/api/middleware/planLimits.js.map +0 -1
  321. package/dist/cloud/api/monitoring.d.ts.map +0 -1
  322. package/dist/cloud/api/monitoring.js.map +0 -1
  323. package/dist/cloud/api/nango-auth.d.ts.map +0 -1
  324. package/dist/cloud/api/nango-auth.js.map +0 -1
  325. package/dist/cloud/api/onboarding.d.ts.map +0 -1
  326. package/dist/cloud/api/onboarding.js.map +0 -1
  327. package/dist/cloud/api/policy.d.ts.map +0 -1
  328. package/dist/cloud/api/policy.js.map +0 -1
  329. package/dist/cloud/api/providers.d.ts.map +0 -1
  330. package/dist/cloud/api/providers.js.map +0 -1
  331. package/dist/cloud/api/repos.d.ts.map +0 -1
  332. package/dist/cloud/api/repos.js.map +0 -1
  333. package/dist/cloud/api/teams.d.ts.map +0 -1
  334. package/dist/cloud/api/teams.js.map +0 -1
  335. package/dist/cloud/api/test-helpers.d.ts.map +0 -1
  336. package/dist/cloud/api/test-helpers.js.map +0 -1
  337. package/dist/cloud/api/usage.d.ts.map +0 -1
  338. package/dist/cloud/api/usage.js.map +0 -1
  339. package/dist/cloud/api/webhooks.d.ts.map +0 -1
  340. package/dist/cloud/api/webhooks.js.map +0 -1
  341. package/dist/cloud/api/workspaces.d.ts.map +0 -1
  342. package/dist/cloud/api/workspaces.js.map +0 -1
  343. package/dist/cloud/billing/index.d.ts.map +0 -1
  344. package/dist/cloud/billing/index.js.map +0 -1
  345. package/dist/cloud/billing/plans.d.ts.map +0 -1
  346. package/dist/cloud/billing/plans.js.map +0 -1
  347. package/dist/cloud/billing/service.d.ts.map +0 -1
  348. package/dist/cloud/billing/service.js.map +0 -1
  349. package/dist/cloud/billing/types.d.ts.map +0 -1
  350. package/dist/cloud/billing/types.js.map +0 -1
  351. package/dist/cloud/config.d.ts.map +0 -1
  352. package/dist/cloud/config.js.map +0 -1
  353. package/dist/cloud/db/drizzle.d.ts.map +0 -1
  354. package/dist/cloud/db/drizzle.js.map +0 -1
  355. package/dist/cloud/db/index.d.ts.map +0 -1
  356. package/dist/cloud/db/index.js.map +0 -1
  357. package/dist/cloud/db/schema.d.ts.map +0 -1
  358. package/dist/cloud/db/schema.js.map +0 -1
  359. package/dist/cloud/index.d.ts.map +0 -1
  360. package/dist/cloud/index.js.map +0 -1
  361. package/dist/cloud/provisioner/index.d.ts.map +0 -1
  362. package/dist/cloud/provisioner/index.js.map +0 -1
  363. package/dist/cloud/server.d.ts.map +0 -1
  364. package/dist/cloud/server.js.map +0 -1
  365. package/dist/cloud/services/auto-scaler.d.ts.map +0 -1
  366. package/dist/cloud/services/auto-scaler.js.map +0 -1
  367. package/dist/cloud/services/capacity-manager.d.ts.map +0 -1
  368. package/dist/cloud/services/capacity-manager.js.map +0 -1
  369. package/dist/cloud/services/ci-agent-spawner.d.ts.map +0 -1
  370. package/dist/cloud/services/ci-agent-spawner.js.map +0 -1
  371. package/dist/cloud/services/coordinator.d.ts.map +0 -1
  372. package/dist/cloud/services/coordinator.js.map +0 -1
  373. package/dist/cloud/services/index.d.ts.map +0 -1
  374. package/dist/cloud/services/index.js.map +0 -1
  375. package/dist/cloud/services/mention-handler.d.ts.map +0 -1
  376. package/dist/cloud/services/mention-handler.js.map +0 -1
  377. package/dist/cloud/services/nango.d.ts.map +0 -1
  378. package/dist/cloud/services/nango.js.map +0 -1
  379. package/dist/cloud/services/persistence.d.ts.map +0 -1
  380. package/dist/cloud/services/persistence.js.map +0 -1
  381. package/dist/cloud/services/planLimits.d.ts.map +0 -1
  382. package/dist/cloud/services/planLimits.js.map +0 -1
  383. package/dist/cloud/services/scaling-orchestrator.d.ts.map +0 -1
  384. package/dist/cloud/services/scaling-orchestrator.js.map +0 -1
  385. package/dist/cloud/services/scaling-policy.d.ts.map +0 -1
  386. package/dist/cloud/services/scaling-policy.js.map +0 -1
  387. package/dist/cloud/vault/index.d.ts +0 -76
  388. package/dist/cloud/vault/index.d.ts.map +0 -1
  389. package/dist/cloud/vault/index.js +0 -219
  390. package/dist/cloud/vault/index.js.map +0 -1
  391. package/dist/cloud/webhooks/index.d.ts.map +0 -1
  392. package/dist/cloud/webhooks/index.js.map +0 -1
  393. package/dist/cloud/webhooks/parsers/github.d.ts.map +0 -1
  394. package/dist/cloud/webhooks/parsers/github.js.map +0 -1
  395. package/dist/cloud/webhooks/parsers/index.d.ts.map +0 -1
  396. package/dist/cloud/webhooks/parsers/index.js.map +0 -1
  397. package/dist/cloud/webhooks/parsers/linear.d.ts.map +0 -1
  398. package/dist/cloud/webhooks/parsers/linear.js.map +0 -1
  399. package/dist/cloud/webhooks/parsers/slack.d.ts.map +0 -1
  400. package/dist/cloud/webhooks/parsers/slack.js.map +0 -1
  401. package/dist/cloud/webhooks/responders/github.d.ts.map +0 -1
  402. package/dist/cloud/webhooks/responders/github.js.map +0 -1
  403. package/dist/cloud/webhooks/responders/index.d.ts.map +0 -1
  404. package/dist/cloud/webhooks/responders/index.js.map +0 -1
  405. package/dist/cloud/webhooks/responders/linear.d.ts.map +0 -1
  406. package/dist/cloud/webhooks/responders/linear.js.map +0 -1
  407. package/dist/cloud/webhooks/responders/slack.d.ts.map +0 -1
  408. package/dist/cloud/webhooks/responders/slack.js.map +0 -1
  409. package/dist/cloud/webhooks/router.d.ts.map +0 -1
  410. package/dist/cloud/webhooks/router.js.map +0 -1
  411. package/dist/cloud/webhooks/rules-engine.d.ts.map +0 -1
  412. package/dist/cloud/webhooks/rules-engine.js.map +0 -1
  413. package/dist/cloud/webhooks/types.d.ts.map +0 -1
  414. package/dist/cloud/webhooks/types.js.map +0 -1
  415. package/dist/continuity/formatter.d.ts.map +0 -1
  416. package/dist/continuity/formatter.js.map +0 -1
  417. package/dist/continuity/handoff-store.d.ts.map +0 -1
  418. package/dist/continuity/handoff-store.js.map +0 -1
  419. package/dist/continuity/index.d.ts.map +0 -1
  420. package/dist/continuity/index.js.map +0 -1
  421. package/dist/continuity/ledger-store.d.ts.map +0 -1
  422. package/dist/continuity/ledger-store.js.map +0 -1
  423. package/dist/continuity/manager.d.ts.map +0 -1
  424. package/dist/continuity/manager.js.map +0 -1
  425. package/dist/continuity/parser.d.ts.map +0 -1
  426. package/dist/continuity/parser.js.map +0 -1
  427. package/dist/continuity/types.d.ts.map +0 -1
  428. package/dist/continuity/types.js.map +0 -1
  429. package/dist/daemon/agent-manager.d.ts.map +0 -1
  430. package/dist/daemon/agent-manager.js.map +0 -1
  431. package/dist/daemon/agent-registry.d.ts.map +0 -1
  432. package/dist/daemon/agent-registry.js.map +0 -1
  433. package/dist/daemon/api.d.ts.map +0 -1
  434. package/dist/daemon/api.js.map +0 -1
  435. package/dist/daemon/auth.d.ts.map +0 -1
  436. package/dist/daemon/auth.js.map +0 -1
  437. package/dist/daemon/cli-auth.d.ts.map +0 -1
  438. package/dist/daemon/cli-auth.js.map +0 -1
  439. package/dist/daemon/cloud-sync.d.ts.map +0 -1
  440. package/dist/daemon/cloud-sync.js.map +0 -1
  441. package/dist/daemon/connection.d.ts.map +0 -1
  442. package/dist/daemon/connection.js.map +0 -1
  443. package/dist/daemon/index.d.ts.map +0 -1
  444. package/dist/daemon/index.js.map +0 -1
  445. package/dist/daemon/orchestrator.d.ts.map +0 -1
  446. package/dist/daemon/orchestrator.js.map +0 -1
  447. package/dist/daemon/registry.d.ts.map +0 -1
  448. package/dist/daemon/registry.js.map +0 -1
  449. package/dist/daemon/router.d.ts.map +0 -1
  450. package/dist/daemon/router.js.map +0 -1
  451. package/dist/daemon/server.d.ts.map +0 -1
  452. package/dist/daemon/server.js.map +0 -1
  453. package/dist/daemon/services/browser-testing.d.ts.map +0 -1
  454. package/dist/daemon/services/browser-testing.js.map +0 -1
  455. package/dist/daemon/services/container-spawner.d.ts.map +0 -1
  456. package/dist/daemon/services/container-spawner.js.map +0 -1
  457. package/dist/daemon/types.d.ts.map +0 -1
  458. package/dist/daemon/types.js.map +0 -1
  459. package/dist/daemon/workspace-manager.d.ts.map +0 -1
  460. package/dist/daemon/workspace-manager.js.map +0 -1
  461. package/dist/dashboard/out/_next/static/H5aWG0udPB4iOUIl_gytz/_ssgManifest.js +0 -1
  462. package/dist/dashboard/out/_next/static/chunks/480-2d4111711d4e473c.js +0 -1
  463. package/dist/dashboard/out/_next/static/chunks/724-73c1ee5f60abe860.js +0 -9
  464. package/dist/dashboard/out/_next/static/chunks/766-c3a14283c88d815b.js +0 -1
  465. package/dist/dashboard/out/_next/static/chunks/app/app/page-7120be68bea622f3.js +0 -1
  466. package/dist/dashboard/out/_next/static/chunks/app/metrics/page-1081dd190a331a91.js +0 -1
  467. package/dist/dashboard/out/_next/static/chunks/app/providers/page-b68a681526eb145e.js +0 -1
  468. package/dist/dashboard/out/_next/static/css/29852f26181969a0.css +0 -1
  469. package/dist/dashboard/out/_next/static/css/411ce23ffeae9f76.css +0 -1
  470. package/dist/dashboard-server/metrics.d.ts.map +0 -1
  471. package/dist/dashboard-server/metrics.js.map +0 -1
  472. package/dist/dashboard-server/needs-attention.d.ts.map +0 -1
  473. package/dist/dashboard-server/needs-attention.js.map +0 -1
  474. package/dist/dashboard-server/server.d.ts.map +0 -1
  475. package/dist/dashboard-server/server.js.map +0 -1
  476. package/dist/dashboard-server/start.d.ts.map +0 -1
  477. package/dist/dashboard-server/start.js.map +0 -1
  478. package/dist/hooks/emitter.d.ts.map +0 -1
  479. package/dist/hooks/emitter.js.map +0 -1
  480. package/dist/hooks/inbox-check/hook.d.ts.map +0 -1
  481. package/dist/hooks/inbox-check/hook.js.map +0 -1
  482. package/dist/hooks/inbox-check/index.d.ts.map +0 -1
  483. package/dist/hooks/inbox-check/index.js.map +0 -1
  484. package/dist/hooks/inbox-check/types.d.ts.map +0 -1
  485. package/dist/hooks/inbox-check/types.js.map +0 -1
  486. package/dist/hooks/inbox-check/utils.d.ts.map +0 -1
  487. package/dist/hooks/inbox-check/utils.js.map +0 -1
  488. package/dist/hooks/index.d.ts.map +0 -1
  489. package/dist/hooks/index.js.map +0 -1
  490. package/dist/hooks/registry.d.ts.map +0 -1
  491. package/dist/hooks/registry.js.map +0 -1
  492. package/dist/hooks/trajectory-hooks.d.ts.map +0 -1
  493. package/dist/hooks/trajectory-hooks.js.map +0 -1
  494. package/dist/hooks/types.d.ts.map +0 -1
  495. package/dist/hooks/types.js.map +0 -1
  496. package/dist/index.d.ts.map +0 -1
  497. package/dist/index.js.map +0 -1
  498. package/dist/memory/adapters/index.d.ts.map +0 -1
  499. package/dist/memory/adapters/index.js.map +0 -1
  500. package/dist/memory/adapters/inmemory.d.ts.map +0 -1
  501. package/dist/memory/adapters/inmemory.js.map +0 -1
  502. package/dist/memory/adapters/supermemory.d.ts.map +0 -1
  503. package/dist/memory/adapters/supermemory.js.map +0 -1
  504. package/dist/memory/factory.d.ts.map +0 -1
  505. package/dist/memory/factory.js.map +0 -1
  506. package/dist/memory/index.d.ts.map +0 -1
  507. package/dist/memory/index.js.map +0 -1
  508. package/dist/memory/memory-hooks.d.ts.map +0 -1
  509. package/dist/memory/memory-hooks.js.map +0 -1
  510. package/dist/memory/service.d.ts.map +0 -1
  511. package/dist/memory/service.js.map +0 -1
  512. package/dist/memory/types.d.ts.map +0 -1
  513. package/dist/memory/types.js.map +0 -1
  514. package/dist/policy/agent-policy.d.ts.map +0 -1
  515. package/dist/policy/agent-policy.js.map +0 -1
  516. package/dist/policy/cloud-policy-fetcher.d.ts.map +0 -1
  517. package/dist/policy/cloud-policy-fetcher.js.map +0 -1
  518. package/dist/protocol/framing.d.ts.map +0 -1
  519. package/dist/protocol/framing.js.map +0 -1
  520. package/dist/protocol/index.d.ts.map +0 -1
  521. package/dist/protocol/index.js.map +0 -1
  522. package/dist/protocol/types.d.ts.map +0 -1
  523. package/dist/protocol/types.js.map +0 -1
  524. package/dist/resiliency/context-persistence.d.ts.map +0 -1
  525. package/dist/resiliency/context-persistence.js.map +0 -1
  526. package/dist/resiliency/crash-insights.d.ts.map +0 -1
  527. package/dist/resiliency/crash-insights.js.map +0 -1
  528. package/dist/resiliency/gossip-health.d.ts.map +0 -1
  529. package/dist/resiliency/gossip-health.js.map +0 -1
  530. package/dist/resiliency/health-monitor.d.ts.map +0 -1
  531. package/dist/resiliency/health-monitor.js.map +0 -1
  532. package/dist/resiliency/index.d.ts.map +0 -1
  533. package/dist/resiliency/index.js.map +0 -1
  534. package/dist/resiliency/leader-watchdog.d.ts.map +0 -1
  535. package/dist/resiliency/leader-watchdog.js.map +0 -1
  536. package/dist/resiliency/logger.d.ts.map +0 -1
  537. package/dist/resiliency/logger.js.map +0 -1
  538. package/dist/resiliency/memory-monitor.d.ts.map +0 -1
  539. package/dist/resiliency/memory-monitor.js.map +0 -1
  540. package/dist/resiliency/metrics.d.ts.map +0 -1
  541. package/dist/resiliency/metrics.js.map +0 -1
  542. package/dist/resiliency/provider-context.d.ts.map +0 -1
  543. package/dist/resiliency/provider-context.js.map +0 -1
  544. package/dist/resiliency/stateless-lead.d.ts.map +0 -1
  545. package/dist/resiliency/stateless-lead.js.map +0 -1
  546. package/dist/resiliency/supervisor.d.ts.map +0 -1
  547. package/dist/resiliency/supervisor.js.map +0 -1
  548. package/dist/shared/cli-auth-config.d.ts.map +0 -1
  549. package/dist/shared/cli-auth-config.js.map +0 -1
  550. package/dist/state/agent-state.d.ts.map +0 -1
  551. package/dist/state/agent-state.js.map +0 -1
  552. package/dist/storage/adapter.d.ts.map +0 -1
  553. package/dist/storage/adapter.js.map +0 -1
  554. package/dist/storage/sqlite-adapter.d.ts.map +0 -1
  555. package/dist/storage/sqlite-adapter.js.map +0 -1
  556. package/dist/trajectory/config.d.ts.map +0 -1
  557. package/dist/trajectory/config.js.map +0 -1
  558. package/dist/trajectory/index.d.ts.map +0 -1
  559. package/dist/trajectory/index.js.map +0 -1
  560. package/dist/trajectory/integration.d.ts.map +0 -1
  561. package/dist/trajectory/integration.js.map +0 -1
  562. package/dist/utils/agent-config.d.ts.map +0 -1
  563. package/dist/utils/agent-config.js.map +0 -1
  564. package/dist/utils/command-resolver.d.ts.map +0 -1
  565. package/dist/utils/command-resolver.js.map +0 -1
  566. package/dist/utils/index.d.ts.map +0 -1
  567. package/dist/utils/index.js.map +0 -1
  568. package/dist/utils/logger.d.ts.map +0 -1
  569. package/dist/utils/logger.js.map +0 -1
  570. package/dist/utils/name-generator.d.ts.map +0 -1
  571. package/dist/utils/name-generator.js.map +0 -1
  572. package/dist/utils/project-namespace.d.ts.map +0 -1
  573. package/dist/utils/project-namespace.js.map +0 -1
  574. package/dist/utils/tmux-resolver.d.ts.map +0 -1
  575. package/dist/utils/tmux-resolver.js.map +0 -1
  576. package/dist/utils/update-checker.d.ts.map +0 -1
  577. package/dist/utils/update-checker.js.map +0 -1
  578. package/dist/wrapper/client.d.ts.map +0 -1
  579. package/dist/wrapper/client.js.map +0 -1
  580. package/dist/wrapper/inbox.d.ts.map +0 -1
  581. package/dist/wrapper/inbox.js.map +0 -1
  582. package/dist/wrapper/index.d.ts.map +0 -1
  583. package/dist/wrapper/index.js.map +0 -1
  584. package/dist/wrapper/parser.d.ts.map +0 -1
  585. package/dist/wrapper/parser.js.map +0 -1
  586. package/dist/wrapper/pty-wrapper.d.ts.map +0 -1
  587. package/dist/wrapper/pty-wrapper.js.map +0 -1
  588. package/dist/wrapper/shared.d.ts.map +0 -1
  589. package/dist/wrapper/shared.js.map +0 -1
  590. package/dist/wrapper/tmux-wrapper.d.ts.map +0 -1
  591. package/dist/wrapper/tmux-wrapper.js.map +0 -1
  592. package/docs/AGENTS.md +0 -513
  593. package/docs/ARCHITECTURE_DECISIONS.md +0 -175
  594. package/docs/CLOUD-ARCHITECTURE.md +0 -804
  595. package/docs/CLOUD-ONBOARDING-DESIGN.md +0 -1983
  596. package/docs/CONTRIBUTING.md +0 -151
  597. package/docs/HOOKS_API.md +0 -394
  598. package/docs/INTEGRATION-GUIDE.md +0 -926
  599. package/docs/PROTOCOL.md +0 -325
  600. package/docs/WRAPPER_EVENTS.md +0 -358
  601. package/docs/agent-policy-snippet.md +0 -40
  602. package/docs/agent-relay-protocol.md +0 -238
  603. package/docs/agent-relay-snippet.md +0 -174
  604. package/docs/archive/CHANGELOG.md +0 -11
  605. package/docs/archive/CLI-SIMPLIFICATION-COMPLETE.md +0 -48
  606. package/docs/archive/DESIGN_BRIDGE_STAFFING.md +0 -878
  607. package/docs/archive/DESIGN_V2.md +0 -1079
  608. package/docs/archive/EXECUTIVE_SUMMARY.md +0 -358
  609. package/docs/archive/MONETIZATION.md +0 -1679
  610. package/docs/archive/PROPOSAL-trajectories.md +0 -1582
  611. package/docs/archive/ROADMAP.md +0 -329
  612. package/docs/archive/SCALING_ANALYSIS.md +0 -280
  613. package/docs/archive/TESTING_PRESENCE_FEATURES.md +0 -327
  614. package/docs/archive/TMUX_IMPLEMENTATION_NOTES.md +0 -364
  615. package/docs/archive/TMUX_IMPROVEMENTS.md +0 -968
  616. package/docs/archive/dashboard-v2-plan.md +0 -179
  617. package/docs/archive/removable-code-analysis.md +0 -24
  618. package/docs/competitive/GASTOWN.md +0 -451
  619. package/docs/competitive/MCP_AGENT_MAIL.md +0 -389
  620. package/docs/competitive/OVERVIEW.md +0 -898
  621. package/docs/competitive/README.md +0 -34
  622. package/docs/competitive/TMUX_ORCHESTRATOR.md +0 -605
  623. package/docs/dashboard.png +0 -0
  624. package/docs/design/ci-failure-webhooks.md +0 -812
  625. package/docs/design/comprehensive-integrations.md +0 -238
  626. package/docs/design/e2b-sandbox-integration.md +0 -504
  627. package/docs/design/github-app-permissions.md +0 -264
  628. package/docs/guides/CLOUD.md +0 -236
  629. package/docs/guides/LOCAL.md +0 -535
  630. package/docs/guides/SELF-HOSTED.md +0 -494
  631. package/docs/local-testing.md +0 -428
  632. package/docs/proposals/continuous-claude-integration.md +0 -622
  633. package/docs/proposals/custom-commands.md +0 -368
  634. package/docs/proposals/shadow-as-subagent.md +0 -765
  635. package/docs/proposals/slack-bot-integration.md +0 -1457
  636. package/docs/tasks/global-skills-system.tasks.md +0 -230
  637. package/docs/tasks/webhook-integrations.tasks.md +0 -184
  638. package/docs/tasks/workspace-capabilities.tasks.md +0 -121
  639. package/docs/testing/RESILIENCY-TEST-PLAN-2026-01-01.md +0 -366
  640. package/scripts/cloud-setup.sh +0 -96
  641. package/scripts/dev/PUBLIC_RELEASE_PLAN.md +0 -88
  642. package/scripts/dev/dev-team-setup.sh +0 -431
  643. package/scripts/e2e-test.sh +0 -119
  644. package/scripts/games/game-protocol.md +0 -79
  645. package/scripts/games/hearts-setup.sh +0 -264
  646. package/scripts/manual-qa.sh +0 -293
  647. package/scripts/run-cloud-qa.sh +0 -220
  648. package/scripts/test-cli-auth/Dockerfile +0 -44
  649. package/scripts/test-cli-auth/Dockerfile.real +0 -79
  650. package/scripts/test-cli-auth/README.md +0 -286
  651. package/scripts/test-cli-auth/ci-test-real-clis.ts +0 -251
  652. package/scripts/test-cli-auth/ci-test-runner.ts +0 -263
  653. package/scripts/test-cli-auth/mock-cli.sh +0 -147
  654. package/scripts/test-cli-auth/package.json +0 -14
  655. package/scripts/test-cli-auth/test-oauth-flow.ts +0 -220
  656. package/scripts/test-pty-input-auto.js +0 -222
  657. package/scripts/test-pty-input.js +0 -150
  658. package/scripts/tictactoe-setup.sh +0 -181
  659. /package/dist/dashboard/out/_next/static/{H5aWG0udPB4iOUIl_gytz → T1tgCqVWHFIkV7ClEtzD7}/_buildManifest.js +0 -0
  660. /package/dist/dashboard/out/_next/static/chunks/{117-b100311aff8d5c61.js → 117-f7b8ab0809342e77.js} +0 -0
  661. /package/dist/dashboard/out/_next/static/chunks/{648-a13d3c2b1be45466.js → 648-5cc6e1921389a58a.js} +0 -0
  662. /package/dist/dashboard/out/_next/static/chunks/app/_not-found/{page-a4973f3e3c82fb67.js → page-53b8a69f76db17d0.js} +0 -0
  663. /package/dist/dashboard/out/_next/static/chunks/app/connect-repos/{page-dc2e3a1a22478efc.js → page-f45ecbc3e06134fc.js} +0 -0
  664. /package/dist/dashboard/out/_next/static/chunks/app/history/{page-56a8b4616a90dc43.js → page-8c8bed33beb2bf1c.js} +0 -0
  665. /package/dist/dashboard/out/_next/static/chunks/app/login/{page-3eac37ea6f5dd153.js → page-16f3b49e55b1e0ed.js} +0 -0
  666. /package/dist/dashboard/out/_next/static/chunks/app/pricing/{page-4d72d5a5d8a9b618.js → page-982a7000fee44014.js} +0 -0
  667. /package/dist/dashboard/out/_next/static/chunks/app/signup/{page-fee4ed1709070bcd.js → page-547dd0ca55ecd0ba.js} +0 -0
  668. /package/dist/dashboard/out/_next/static/chunks/{fd9d1056-bf46c09eb57e019c.js → fd9d1056-609918ca7b6280bb.js} +0 -0
@@ -2,10 +2,62 @@
2
2
  * Repos API Routes
3
3
  *
4
4
  * GitHub repository management - list, import, sync.
5
+ * Includes Nango-based GitHub permission checking for dashboard access control.
5
6
  */
7
+ import crypto from 'crypto';
6
8
  import { Router } from 'express';
7
9
  import { requireAuth } from './auth.js';
8
10
  import { db } from '../db/index.js';
11
+ import { nangoService } from '../services/nango.js';
12
+ import { getConfig } from '../config.js';
13
+ /**
14
+ * Generate workspace token for API calls to workspace containers
15
+ */
16
+ function generateWorkspaceToken(workspaceId) {
17
+ const config = getConfig();
18
+ return crypto
19
+ .createHmac('sha256', config.sessionSecret)
20
+ .update(`workspace:${workspaceId}`)
21
+ .digest('hex');
22
+ }
23
+ /**
24
+ * Call workspace API endpoint
25
+ */
26
+ async function callWorkspaceApi(publicUrl, workspaceId, method, endpoint, body) {
27
+ const token = generateWorkspaceToken(workspaceId);
28
+ const url = `${publicUrl.replace(/\/$/, '')}${endpoint}`;
29
+ try {
30
+ const response = await fetch(url, {
31
+ method,
32
+ headers: {
33
+ 'Content-Type': 'application/json',
34
+ 'Authorization': `Bearer ${token}`,
35
+ },
36
+ body: body ? JSON.stringify(body) : undefined,
37
+ });
38
+ const data = await response.json().catch((parseError) => {
39
+ console.error('Failed to parse JSON from workspace response', {
40
+ url,
41
+ status: response.status,
42
+ error: parseError instanceof Error ? parseError.message : parseError,
43
+ });
44
+ return null;
45
+ });
46
+ return {
47
+ ok: response.ok,
48
+ status: response.status,
49
+ data,
50
+ error: response.ok ? undefined : (data?.error || `HTTP ${response.status}`),
51
+ };
52
+ }
53
+ catch (err) {
54
+ return {
55
+ ok: false,
56
+ status: 0,
57
+ error: err instanceof Error ? err.message : 'Network error',
58
+ };
59
+ }
60
+ }
9
61
  export const reposRouter = Router();
10
62
  // All routes require authentication
11
63
  reposRouter.use(requireAuth);
@@ -187,6 +239,228 @@ reposRouter.post('/bulk', async (req, res) => {
187
239
  results,
188
240
  });
189
241
  });
242
+ /**
243
+ * GET /api/repos/accessible
244
+ * List all GitHub repositories the authenticated user has access to.
245
+ * Uses Nango proxy with user's GitHub OAuth token.
246
+ */
247
+ reposRouter.get('/accessible', async (req, res) => {
248
+ const userId = req.session.userId;
249
+ const { page, perPage, type, sort } = req.query;
250
+ try {
251
+ // Get user's Nango connection ID
252
+ const user = await db.users.findById(userId);
253
+ if (!user) {
254
+ return res.status(404).json({ error: 'User not found' });
255
+ }
256
+ if (!user.nangoConnectionId) {
257
+ return res.status(400).json({
258
+ error: 'GitHub not connected via Nango',
259
+ code: 'NANGO_NOT_CONNECTED',
260
+ message: 'Please reconnect your GitHub account',
261
+ });
262
+ }
263
+ // List accessible repos via Nango proxy
264
+ const result = await nangoService.listUserAccessibleRepos(user.nangoConnectionId, {
265
+ page: page ? parseInt(page, 10) : undefined,
266
+ perPage: perPage ? Math.min(parseInt(perPage, 10), 100) : undefined,
267
+ type: type,
268
+ sort: sort,
269
+ });
270
+ res.json({
271
+ repositories: result.repositories,
272
+ pagination: {
273
+ page: page ? parseInt(page, 10) : 1,
274
+ perPage: perPage ? Math.min(parseInt(perPage, 10), 100) : 100,
275
+ hasMore: result.hasMore,
276
+ },
277
+ checkedBy: {
278
+ userId: user.id,
279
+ githubUsername: user.githubUsername,
280
+ },
281
+ });
282
+ }
283
+ catch (error) {
284
+ console.error('Error listing accessible repos:', error);
285
+ res.status(500).json({ error: 'Failed to list accessible repositories' });
286
+ }
287
+ });
288
+ /**
289
+ * GET /api/repos/search
290
+ * Search GitHub repos by name
291
+ */
292
+ reposRouter.get('/search', async (req, res) => {
293
+ const githubToken = req.session.githubToken;
294
+ const { q } = req.query;
295
+ if (!q || typeof q !== 'string') {
296
+ return res.status(400).json({ error: 'Search query (q) is required' });
297
+ }
298
+ if (!githubToken) {
299
+ return res.status(401).json({ error: 'GitHub not connected' });
300
+ }
301
+ try {
302
+ // Search user's repos
303
+ const response = await fetch(`https://api.github.com/search/repositories?q=${encodeURIComponent(q)}+user:@me&sort=updated&per_page=20`, {
304
+ headers: {
305
+ Authorization: `Bearer ${githubToken}`,
306
+ Accept: 'application/vnd.github.v3+json',
307
+ },
308
+ });
309
+ if (!response.ok) {
310
+ throw new Error('GitHub search failed');
311
+ }
312
+ const data = await response.json();
313
+ res.json({
314
+ repositories: data.items.map((r) => ({
315
+ githubId: r.id,
316
+ fullName: r.full_name,
317
+ name: r.name,
318
+ owner: r.owner.login,
319
+ description: r.description,
320
+ defaultBranch: r.default_branch,
321
+ isPrivate: r.private,
322
+ language: r.language,
323
+ })),
324
+ total: data.total_count,
325
+ });
326
+ }
327
+ catch (error) {
328
+ console.error('Error searching repos:', error);
329
+ res.status(500).json({ error: 'Failed to search repositories' });
330
+ }
331
+ });
332
+ // ============================================================================
333
+ // Nango-based GitHub Permission APIs (for dashboard access control)
334
+ // ============================================================================
335
+ /**
336
+ * GET /api/repos/check-access/:owner/:repo
337
+ * Check if authenticated user has access to a specific GitHub repository.
338
+ * Uses Nango proxy with user's GitHub OAuth token.
339
+ *
340
+ * Response:
341
+ * - hasAccess: boolean - Whether user can access this repo
342
+ * - permission: 'admin' | 'write' | 'read' | 'none' - User's permission level
343
+ * - repository: Repository details if user has access
344
+ *
345
+ * Use this for dashboard access control - grant access if hasAccess is true.
346
+ */
347
+ reposRouter.get('/check-access/:owner/:repo', async (req, res) => {
348
+ const userId = req.session.userId;
349
+ const { owner, repo } = req.params;
350
+ if (!owner || !repo) {
351
+ return res.status(400).json({ error: 'Owner and repo parameters are required' });
352
+ }
353
+ try {
354
+ // Get user's Nango connection ID
355
+ const user = await db.users.findById(userId);
356
+ if (!user) {
357
+ return res.status(404).json({ error: 'User not found' });
358
+ }
359
+ if (!user.nangoConnectionId) {
360
+ return res.status(400).json({
361
+ error: 'GitHub not connected via Nango',
362
+ code: 'NANGO_NOT_CONNECTED',
363
+ message: 'Please reconnect your GitHub account',
364
+ });
365
+ }
366
+ // Check access via Nango proxy
367
+ const accessResult = await nangoService.checkUserRepoAccess(user.nangoConnectionId, owner, repo);
368
+ res.json({
369
+ hasAccess: accessResult.hasAccess,
370
+ permission: accessResult.permission,
371
+ repository: accessResult.repository,
372
+ // Include user info for dashboard context
373
+ checkedBy: {
374
+ userId: user.id,
375
+ githubUsername: user.githubUsername,
376
+ },
377
+ });
378
+ }
379
+ catch (error) {
380
+ console.error('Error checking repo access:', error);
381
+ res.status(500).json({ error: 'Failed to check repository access' });
382
+ }
383
+ });
384
+ /**
385
+ * POST /api/repos/check-access-bulk
386
+ * Check access to multiple repositories at once.
387
+ * Useful for determining which workspaces a user can view.
388
+ *
389
+ * Body:
390
+ * - repositories: Array of "owner/repo" strings
391
+ *
392
+ * Response:
393
+ * - results: Array of { fullName, hasAccess, permission }
394
+ */
395
+ reposRouter.post('/check-access-bulk', async (req, res) => {
396
+ const userId = req.session.userId;
397
+ const { repositories } = req.body;
398
+ if (!repositories || !Array.isArray(repositories)) {
399
+ return res.status(400).json({ error: 'repositories array is required' });
400
+ }
401
+ if (repositories.length > 50) {
402
+ return res.status(400).json({ error: 'Maximum 50 repositories per request' });
403
+ }
404
+ try {
405
+ // Get user's Nango connection ID
406
+ const user = await db.users.findById(userId);
407
+ if (!user) {
408
+ return res.status(404).json({ error: 'User not found' });
409
+ }
410
+ if (!user.nangoConnectionId) {
411
+ return res.status(400).json({
412
+ error: 'GitHub not connected via Nango',
413
+ code: 'NANGO_NOT_CONNECTED',
414
+ message: 'Please reconnect your GitHub account',
415
+ });
416
+ }
417
+ // Check access for each repo (in parallel with concurrency limit)
418
+ const results = [];
419
+ // Process in batches of 10 to avoid rate limiting
420
+ const batchSize = 10;
421
+ for (let i = 0; i < repositories.length; i += batchSize) {
422
+ const batch = repositories.slice(i, i + batchSize);
423
+ const batchResults = await Promise.all(batch.map(async (fullName) => {
424
+ try {
425
+ const [owner, repo] = fullName.split('/');
426
+ if (!owner || !repo) {
427
+ return { fullName, hasAccess: false, error: 'Invalid repository format' };
428
+ }
429
+ const accessResult = await nangoService.checkUserRepoAccess(user.nangoConnectionId, owner, repo);
430
+ return {
431
+ fullName,
432
+ hasAccess: accessResult.hasAccess,
433
+ permission: accessResult.permission,
434
+ };
435
+ }
436
+ catch (_err) {
437
+ return { fullName, hasAccess: false, error: 'Check failed' };
438
+ }
439
+ }));
440
+ results.push(...batchResults);
441
+ }
442
+ const accessibleCount = results.filter(r => r.hasAccess).length;
443
+ res.json({
444
+ results,
445
+ summary: {
446
+ total: repositories.length,
447
+ accessible: accessibleCount,
448
+ denied: repositories.length - accessibleCount,
449
+ },
450
+ checkedBy: {
451
+ userId: user.id,
452
+ githubUsername: user.githubUsername,
453
+ },
454
+ });
455
+ }
456
+ catch (error) {
457
+ console.error('Error checking bulk repo access:', error);
458
+ res.status(500).json({ error: 'Failed to check repository access' });
459
+ }
460
+ });
461
+ // ============================================================================
462
+ // WILDCARD ROUTES BELOW - All specific routes must be defined ABOVE this line
463
+ // ============================================================================
190
464
  /**
191
465
  * GET /api/repos/:id
192
466
  * Get repository details
@@ -219,6 +493,9 @@ reposRouter.get('/:id', async (req, res) => {
219
493
  /**
220
494
  * POST /api/repos/:id/sync
221
495
  * Trigger repository sync (clone/pull to workspace)
496
+ *
497
+ * Calls the workspace's /repos/sync API endpoint to clone or update the repo.
498
+ * This enables dynamic repo management without workspace restart.
222
499
  */
223
500
  reposRouter.post('/:id/sync', async (req, res) => {
224
501
  const userId = req.session.userId;
@@ -232,14 +509,43 @@ reposRouter.post('/:id/sync', async (req, res) => {
232
509
  if (!repo.workspaceId) {
233
510
  return res.status(400).json({ error: 'Repository not assigned to a workspace' });
234
511
  }
512
+ // Get the workspace to find its public URL
513
+ const workspace = await db.workspaces.findById(repo.workspaceId);
514
+ if (!workspace) {
515
+ return res.status(404).json({ error: 'Workspace not found' });
516
+ }
517
+ if (workspace.status !== 'running') {
518
+ return res.status(400).json({
519
+ error: 'Workspace is not running',
520
+ workspaceStatus: workspace.status,
521
+ });
522
+ }
523
+ if (!workspace.publicUrl) {
524
+ return res.status(400).json({ error: 'Workspace has no public URL' });
525
+ }
235
526
  // Update sync status
236
527
  await db.repositories.updateSyncStatus(id, 'syncing');
237
- // In production, this would trigger the workspace to pull the repo
238
- // For now, simulate success after a short delay
239
- setTimeout(async () => {
528
+ // Call the workspace's repo sync API
529
+ const result = await callWorkspaceApi(workspace.publicUrl, workspace.id, 'POST', '/repos/sync', { repo: repo.githubFullName });
530
+ if (result.ok) {
531
+ // Update sync status to synced
240
532
  await db.repositories.updateSyncStatus(id, 'synced', new Date());
241
- }, 2000);
242
- res.json({ message: 'Sync started', syncStatus: 'syncing' });
533
+ res.json({
534
+ message: 'Repository synced successfully',
535
+ syncStatus: 'synced',
536
+ result: result.data,
537
+ });
538
+ }
539
+ else {
540
+ // Update sync status to error
541
+ await db.repositories.updateSyncStatus(id, 'error');
542
+ console.error('Workspace sync failed:', result.error);
543
+ res.status(502).json({
544
+ error: 'Failed to sync repository to workspace',
545
+ details: result.error,
546
+ syncStatus: 'error',
547
+ });
548
+ }
243
549
  }
244
550
  catch (error) {
245
551
  console.error('Error syncing repo:', error);
@@ -267,48 +573,4 @@ reposRouter.delete('/:id', async (req, res) => {
267
573
  res.status(500).json({ error: 'Failed to delete repository' });
268
574
  }
269
575
  });
270
- /**
271
- * GET /api/repos/search
272
- * Search GitHub repos by name
273
- */
274
- reposRouter.get('/search', async (req, res) => {
275
- const githubToken = req.session.githubToken;
276
- const { q } = req.query;
277
- if (!q || typeof q !== 'string') {
278
- return res.status(400).json({ error: 'Search query (q) is required' });
279
- }
280
- if (!githubToken) {
281
- return res.status(401).json({ error: 'GitHub not connected' });
282
- }
283
- try {
284
- // Search user's repos
285
- const response = await fetch(`https://api.github.com/search/repositories?q=${encodeURIComponent(q)}+user:@me&sort=updated&per_page=20`, {
286
- headers: {
287
- Authorization: `Bearer ${githubToken}`,
288
- Accept: 'application/vnd.github.v3+json',
289
- },
290
- });
291
- if (!response.ok) {
292
- throw new Error('GitHub search failed');
293
- }
294
- const data = await response.json();
295
- res.json({
296
- repositories: data.items.map((r) => ({
297
- githubId: r.id,
298
- fullName: r.full_name,
299
- name: r.name,
300
- owner: r.owner.login,
301
- description: r.description,
302
- defaultBranch: r.default_branch,
303
- isPrivate: r.private,
304
- language: r.language,
305
- })),
306
- total: data.total_count,
307
- });
308
- }
309
- catch (error) {
310
- console.error('Error searching repos:', error);
311
- res.status(500).json({ error: 'Failed to search repositories' });
312
- }
313
- });
314
576
  //# sourceMappingURL=repos.js.map
@@ -227,6 +227,46 @@ testHelpersRouter.post('/create-mock-repo', async (req, res) => {
227
227
  res.status(500).json({ error: 'Failed to create mock repo' });
228
228
  }
229
229
  });
230
+ /**
231
+ * GET /api/test/auto-login
232
+ * Browser-friendly auto-login - visit this URL to login and redirect
233
+ * Usage: /api/test/auto-login?redirect=/providers/setup/claude?workspace=xxx
234
+ */
235
+ testHelpersRouter.get('/auto-login', async (req, res) => {
236
+ if (!isTestMode) {
237
+ return res.status(403).json({ error: 'Test endpoints disabled in production' });
238
+ }
239
+ try {
240
+ const db = getDb();
241
+ const redirect = req.query.redirect || '/app';
242
+ // Find or create test user
243
+ let user;
244
+ const existingUsers = await db.select().from(users).limit(1);
245
+ if (existingUsers.length > 0) {
246
+ user = existingUsers[0];
247
+ }
248
+ else {
249
+ const testId = `test-${randomUUID()}`;
250
+ const [newUser] = await db.insert(users).values({
251
+ email: `${testId}@test.local`,
252
+ githubId: testId,
253
+ githubUsername: 'test-user',
254
+ avatarUrl: null,
255
+ plan: 'free',
256
+ }).returning();
257
+ user = newUser;
258
+ }
259
+ // Set session and CSRF token
260
+ req.session.userId = user.id;
261
+ req.session.csrfToken = randomUUID();
262
+ // Redirect to requested page
263
+ res.redirect(redirect);
264
+ }
265
+ catch (error) {
266
+ console.error('Error in auto-login:', error);
267
+ res.status(500).json({ error: 'Failed to auto-login' });
268
+ }
269
+ });
230
270
  /**
231
271
  * POST /api/test/login-as
232
272
  * Quick login for testing - creates session for existing or new test user
@@ -6,6 +6,7 @@
6
6
  import { Router } from 'express';
7
7
  import { requireAuth } from './auth.js';
8
8
  import { getRemainingQuota, getUserUsage, getPlanLimits } from '../services/planLimits.js';
9
+ import { getIntroStatus } from '../services/intro-expiration.js';
9
10
  import { db } from '../db/index.js';
10
11
  export const usageRouter = Router();
11
12
  // All routes require authentication
@@ -23,6 +24,8 @@ usageRouter.get('/', async (req, res) => {
23
24
  }
24
25
  const plan = user.plan || 'free';
25
26
  const quota = await getRemainingQuota(userId);
27
+ // Get intro period status for free tier users
28
+ const introStatus = getIntroStatus(user.createdAt, plan);
26
29
  const calcPercent = (current, limit) => limit === Infinity ? 0 : Math.round((current / limit) * 100);
27
30
  res.json({
28
31
  plan,
@@ -51,6 +54,16 @@ usageRouter.get('/', async (req, res) => {
51
54
  concurrentAgents: calcPercent(quota.usage.concurrentAgents, quota.limits.maxConcurrentAgents),
52
55
  computeHours: calcPercent(quota.usage.computeHoursThisMonth, quota.limits.maxComputeHoursPerMonth),
53
56
  },
57
+ // Intro period bonus for free tier users (2 CPU / 4GB for first 14 days)
58
+ introBonus: {
59
+ isActive: introStatus.isIntroPeriod,
60
+ daysRemaining: introStatus.daysRemaining,
61
+ totalDays: introStatus.introPeriodDays,
62
+ expiresAt: introStatus.expiresAt?.toISOString() || null,
63
+ resources: introStatus.isIntroPeriod
64
+ ? { cpus: 2, memoryGb: 4, description: 'Pro-level resources' }
65
+ : { cpus: 1, memoryGb: 2, description: 'Standard free tier' },
66
+ },
54
67
  });
55
68
  }
56
69
  catch (error) {
@@ -2,6 +2,7 @@
2
2
  * Webhook API Routes
3
3
  *
4
4
  * Handles GitHub App webhooks for installation events.
5
+ * Also provides workspace webhook forwarding for external integrations.
5
6
  */
6
7
  export declare const webhooksRouter: import("express-serve-static-core").Router;
7
8
  //# sourceMappingURL=webhooks.d.ts.map
@@ -2,12 +2,161 @@
2
2
  * Webhook API Routes
3
3
  *
4
4
  * Handles GitHub App webhooks for installation events.
5
+ * Also provides workspace webhook forwarding for external integrations.
5
6
  */
6
7
  import { Router } from 'express';
7
8
  import crypto from 'crypto';
8
9
  import { getConfig } from '../config.js';
9
10
  import { db } from '../db/index.js';
10
11
  export const webhooksRouter = Router();
12
+ // ============================================================================
13
+ // Workspace Webhook Forwarding
14
+ // ============================================================================
15
+ /**
16
+ * Convert workspace public URL to internal Fly.io URL
17
+ */
18
+ function getWorkspaceInternalUrl(publicUrl) {
19
+ const isOnFly = !!process.env.FLY_APP_NAME;
20
+ let url = publicUrl.replace(/\/$/, '');
21
+ if (isOnFly && url.includes('.fly.dev')) {
22
+ // Use Fly.io internal networking
23
+ // ar-583f273b.fly.dev -> http://ar-583f273b.internal:3888
24
+ // .internal uses IPv6 and works by default for apps in the same org
25
+ const appName = url.match(/https?:\/\/([^.]+)\.fly\.dev/)?.[1];
26
+ if (appName) {
27
+ url = `http://${appName}.internal:3888`;
28
+ }
29
+ }
30
+ return url;
31
+ }
32
+ /**
33
+ * Wake a suspended Fly.io workspace machine
34
+ */
35
+ async function wakeWorkspaceMachine(workspaceId) {
36
+ const workspace = await db.workspaces.findById(workspaceId);
37
+ if (!workspace?.computeId)
38
+ return false;
39
+ const appName = `ar-${workspaceId.substring(0, 8)}`;
40
+ const apiToken = process.env.FLY_API_TOKEN;
41
+ if (!apiToken) {
42
+ console.warn('[webhooks] FLY_API_TOKEN not set, cannot wake machine');
43
+ return false;
44
+ }
45
+ try {
46
+ const response = await fetch(`https://api.machines.dev/v1/apps/${appName}/machines/${workspace.computeId}/start`, {
47
+ method: 'POST',
48
+ headers: { Authorization: `Bearer ${apiToken}` },
49
+ });
50
+ if (response.ok) {
51
+ console.log(`[webhooks] Started workspace machine ${workspace.computeId}`);
52
+ // Wait a bit for machine to start
53
+ await new Promise(resolve => setTimeout(resolve, 5000));
54
+ return true;
55
+ }
56
+ // 200 OK means already running
57
+ if (response.status === 200) {
58
+ return true;
59
+ }
60
+ console.warn(`[webhooks] Failed to start machine: ${response.status}`);
61
+ return false;
62
+ }
63
+ catch (error) {
64
+ console.error('[webhooks] Error waking machine:', error);
65
+ return false;
66
+ }
67
+ }
68
+ /**
69
+ * POST /api/webhooks/workspace/:workspaceId/*
70
+ * Forward webhooks to a specific workspace
71
+ *
72
+ * External services can send webhooks to:
73
+ * https://agent-relay.com/api/webhooks/workspace/{workspaceId}/your/path
74
+ *
75
+ * This will be forwarded to:
76
+ * http://{workspace-internal}/webhooks/your/path
77
+ */
78
+ // Handler for workspace webhook forwarding - matches any path under /workspace/:workspaceId
79
+ async function _handleWorkspaceWebhook(req, res) {
80
+ // Extract workspaceId from URL path
81
+ const pathMatch = req.originalUrl.match(/\/workspace\/([^/]+)\/?(.*)$/);
82
+ if (!pathMatch) {
83
+ res.status(400).json({ error: 'Invalid workspace webhook URL' });
84
+ return;
85
+ }
86
+ const workspaceId = pathMatch[1];
87
+ const forwardPath = pathMatch[2] || '';
88
+ console.log(`[webhooks] Forwarding to workspace ${workspaceId}: ${req.method} /${forwardPath}`);
89
+ try {
90
+ // Find the workspace
91
+ const workspace = await db.workspaces.findById(workspaceId);
92
+ if (!workspace) {
93
+ res.status(404).json({ error: 'Workspace not found' });
94
+ return;
95
+ }
96
+ if (!workspace.publicUrl) {
97
+ res.status(400).json({ error: 'Workspace has no public URL' });
98
+ return;
99
+ }
100
+ // Try to wake the machine if it might be suspended
101
+ if (workspace.status === 'running' || workspace.status === 'suspended') {
102
+ await wakeWorkspaceMachine(workspaceId);
103
+ }
104
+ // Get internal URL for server-to-server communication
105
+ const internalUrl = getWorkspaceInternalUrl(workspace.publicUrl);
106
+ const targetUrl = `${internalUrl}/webhooks/${forwardPath}`;
107
+ console.log(`[webhooks] Forwarding to: ${targetUrl}`);
108
+ // Forward the request with original headers and body
109
+ const forwardHeaders = {};
110
+ // Copy relevant headers
111
+ const headersToForward = [
112
+ 'content-type',
113
+ 'x-hub-signature-256',
114
+ 'x-hub-signature',
115
+ 'x-github-event',
116
+ 'x-github-delivery',
117
+ 'x-gitlab-token',
118
+ 'x-gitlab-event',
119
+ 'user-agent',
120
+ ];
121
+ for (const header of headersToForward) {
122
+ const value = req.get(header);
123
+ if (value) {
124
+ forwardHeaders[header] = value;
125
+ }
126
+ }
127
+ // Add workspace context header
128
+ forwardHeaders['x-forwarded-for-workspace'] = workspaceId;
129
+ forwardHeaders['x-original-host'] = req.get('host') || '';
130
+ // Get raw body if available, otherwise use JSON stringified body
131
+ const rawBody = req.rawBody || JSON.stringify(req.body);
132
+ const response = await fetch(targetUrl, {
133
+ method: req.method,
134
+ headers: forwardHeaders,
135
+ body: ['GET', 'HEAD'].includes(req.method) ? undefined : rawBody,
136
+ });
137
+ // Forward response back
138
+ const responseBody = await response.text();
139
+ res.status(response.status);
140
+ // Copy response headers
141
+ response.headers.forEach((value, key) => {
142
+ if (!['content-encoding', 'transfer-encoding', 'content-length'].includes(key.toLowerCase())) {
143
+ res.set(key, value);
144
+ }
145
+ });
146
+ res.send(responseBody);
147
+ }
148
+ catch (error) {
149
+ console.error(`[webhooks] Error forwarding to workspace ${workspaceId}:`, error);
150
+ res.status(502).json({
151
+ error: 'Failed to forward webhook to workspace',
152
+ details: error.message,
153
+ });
154
+ }
155
+ }
156
+ // TODO: Re-enable workspace webhook forwarding once route pattern issue is resolved
157
+ // The newer path-to-regexp version doesn't support wildcard patterns like /workspace/*
158
+ // See: https://git.new/pathToRegexpError
159
+ // webhooksRouter.all('/workspace/*', handleWorkspaceWebhook);
11
160
  // GitHub webhook signature verification
12
161
  function verifyGitHubSignature(payload, signature) {
13
162
  if (!signature)
@@ -2,6 +2,24 @@
2
2
  * Workspaces API Routes
3
3
  *
4
4
  * One-click workspace provisioning and management.
5
+ * Includes auto-access based on GitHub repo permissions.
5
6
  */
7
+ import { Request, Response, NextFunction } from 'express';
8
+ /**
9
+ * Check if user has access to a workspace via:
10
+ * 1. Workspace ownership (userId matches)
11
+ * 2. Explicit workspace_members record
12
+ * 3. GitHub repo access (just-in-time check via Nango)
13
+ */
14
+ export declare function checkWorkspaceAccess(userId: string, workspaceId: string): Promise<{
15
+ hasAccess: boolean;
16
+ accessType: 'owner' | 'member' | 'contributor' | 'none';
17
+ permission?: 'admin' | 'write' | 'read';
18
+ }>;
19
+ /**
20
+ * Middleware to require workspace access.
21
+ * Checks ownership, membership, or GitHub repo access.
22
+ */
23
+ export declare function requireWorkspaceAccess(req: Request, res: Response, next: NextFunction): void;
6
24
  export declare const workspacesRouter: import("express-serve-static-core").Router;
7
25
  //# sourceMappingURL=workspaces.d.ts.map