agent-relay 1.1.0 → 1.2.3

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 (567) hide show
  1. package/.gitattributes +3 -0
  2. package/.nvmrc +1 -0
  3. package/.trajectories/completed/2026-01/traj_1dviorhnkcb5.json +65 -0
  4. package/.trajectories/completed/2026-01/traj_1dviorhnkcb5.md +37 -0
  5. package/.trajectories/completed/2026-01/traj_1k5if5snst2e.json +65 -0
  6. package/.trajectories/completed/2026-01/traj_1k5if5snst2e.md +37 -0
  7. package/.trajectories/completed/2026-01/traj_1rp3rges5811.json +49 -0
  8. package/.trajectories/completed/2026-01/traj_1rp3rges5811.md +31 -0
  9. package/.trajectories/completed/2026-01/traj_22bhyulruouw.json +113 -0
  10. package/.trajectories/completed/2026-01/traj_22bhyulruouw.md +57 -0
  11. package/.trajectories/completed/2026-01/traj_2dao7ddgnta0.json +53 -0
  12. package/.trajectories/completed/2026-01/traj_2dao7ddgnta0.md +32 -0
  13. package/.trajectories/completed/2026-01/traj_3t0440mjeunc.json +26 -0
  14. package/.trajectories/completed/2026-01/traj_3t0440mjeunc.md +6 -0
  15. package/.trajectories/completed/2026-01/traj_45x9494d9xnr.json +47 -0
  16. package/.trajectories/completed/2026-01/traj_45x9494d9xnr.md +32 -0
  17. package/.trajectories/completed/2026-01/traj_4aa0bb77s4nh.json +53 -0
  18. package/.trajectories/completed/2026-01/traj_4aa0bb77s4nh.md +32 -0
  19. package/.trajectories/completed/2026-01/traj_5lhmzq8rxpqv.json +59 -0
  20. package/.trajectories/completed/2026-01/traj_5lhmzq8rxpqv.md +33 -0
  21. package/.trajectories/completed/2026-01/traj_5vr4e9erb1fs.json +53 -0
  22. package/.trajectories/completed/2026-01/traj_5vr4e9erb1fs.md +32 -0
  23. package/.trajectories/completed/2026-01/traj_6fgiwdoklvym.json +48 -0
  24. package/.trajectories/completed/2026-01/traj_6fgiwdoklvym.md +24 -0
  25. package/.trajectories/completed/2026-01/traj_7ludwvz45veh.json +209 -0
  26. package/.trajectories/completed/2026-01/traj_7ludwvz45veh.md +97 -0
  27. package/.trajectories/completed/2026-01/traj_9921cuhel0pj.json +48 -0
  28. package/.trajectories/completed/2026-01/traj_9921cuhel0pj.md +24 -0
  29. package/.trajectories/completed/2026-01/traj_ajs7zqfux4wc.json +49 -0
  30. package/.trajectories/completed/2026-01/traj_ajs7zqfux4wc.md +23 -0
  31. package/.trajectories/completed/2026-01/traj_cvtqhlwcq9s0.json +53 -0
  32. package/.trajectories/completed/2026-01/traj_cvtqhlwcq9s0.md +32 -0
  33. package/.trajectories/completed/2026-01/traj_cxofprm2m2en.json +49 -0
  34. package/.trajectories/completed/2026-01/traj_cxofprm2m2en.md +31 -0
  35. package/.trajectories/completed/2026-01/traj_d2hhz3k0vrhn.json +26 -0
  36. package/.trajectories/completed/2026-01/traj_d2hhz3k0vrhn.md +6 -0
  37. package/.trajectories/completed/2026-01/traj_dfuvww9pege5.json +59 -0
  38. package/.trajectories/completed/2026-01/traj_dfuvww9pege5.md +37 -0
  39. package/.trajectories/completed/2026-01/traj_g0fisy9h51mf.json +77 -0
  40. package/.trajectories/completed/2026-01/traj_g0fisy9h51mf.md +42 -0
  41. package/.trajectories/completed/2026-01/traj_gjdre5voouod.json +53 -0
  42. package/.trajectories/completed/2026-01/traj_gjdre5voouod.md +32 -0
  43. package/.trajectories/completed/2026-01/traj_gtlyqtta3x8l.json +25 -0
  44. package/.trajectories/completed/2026-01/traj_gtlyqtta3x8l.md +15 -0
  45. package/.trajectories/completed/2026-01/traj_h4xijiuip3w4.json +101 -0
  46. package/.trajectories/completed/2026-01/traj_h4xijiuip3w4.md +44 -0
  47. package/.trajectories/completed/2026-01/traj_hhxte7w4gjjx.json +22 -0
  48. package/.trajectories/completed/2026-01/traj_hhxte7w4gjjx.md +5 -0
  49. package/.trajectories/completed/2026-01/traj_hpungyhoj6v5.json +53 -0
  50. package/.trajectories/completed/2026-01/traj_hpungyhoj6v5.md +32 -0
  51. package/.trajectories/completed/2026-01/traj_m2xkjv0w2sq7.json +25 -0
  52. package/.trajectories/completed/2026-01/traj_m2xkjv0w2sq7.md +15 -0
  53. package/.trajectories/completed/2026-01/traj_noq5zbvnrdvz.json +53 -0
  54. package/.trajectories/completed/2026-01/traj_noq5zbvnrdvz.md +32 -0
  55. package/.trajectories/completed/2026-01/traj_ntbs6ppopf46.json +53 -0
  56. package/.trajectories/completed/2026-01/traj_ntbs6ppopf46.md +32 -0
  57. package/.trajectories/completed/2026-01/traj_ozd98si6a7ns.json +48 -0
  58. package/.trajectories/completed/2026-01/traj_ozd98si6a7ns.md +24 -0
  59. package/.trajectories/completed/2026-01/traj_prdza7a5cxp5.json +53 -0
  60. package/.trajectories/completed/2026-01/traj_prdza7a5cxp5.md +32 -0
  61. package/.trajectories/completed/2026-01/traj_qb3twvvywfwi.json +77 -0
  62. package/.trajectories/completed/2026-01/traj_qb3twvvywfwi.md +42 -0
  63. package/.trajectories/completed/2026-01/traj_qft54mi7nfor.json +53 -0
  64. package/.trajectories/completed/2026-01/traj_qft54mi7nfor.md +32 -0
  65. package/.trajectories/completed/2026-01/traj_qx9uhf8whhxo.json +83 -0
  66. package/.trajectories/completed/2026-01/traj_qx9uhf8whhxo.md +47 -0
  67. package/.trajectories/completed/2026-01/traj_rd9toccj18a0.json +59 -0
  68. package/.trajectories/completed/2026-01/traj_rd9toccj18a0.md +37 -0
  69. package/.trajectories/completed/2026-01/traj_rt4fiw3ecp50.json +48 -0
  70. package/.trajectories/completed/2026-01/traj_rt4fiw3ecp50.md +16 -0
  71. package/.trajectories/completed/2026-01/traj_st8j35b0hrlc.json +59 -0
  72. package/.trajectories/completed/2026-01/traj_st8j35b0hrlc.md +37 -0
  73. package/.trajectories/completed/2026-01/traj_t1yy8m7hbuxp.json +53 -0
  74. package/.trajectories/completed/2026-01/traj_t1yy8m7hbuxp.md +32 -0
  75. package/.trajectories/completed/2026-01/traj_tmux_orchestrator_analysis.json +84 -0
  76. package/.trajectories/completed/2026-01/traj_tmux_orchestrator_analysis.md +109 -0
  77. package/.trajectories/completed/2026-01/traj_u9n9eqasw16k.json +53 -0
  78. package/.trajectories/completed/2026-01/traj_u9n9eqasw16k.md +32 -0
  79. package/.trajectories/completed/2026-01/traj_v87hypnongqx.json +71 -0
  80. package/.trajectories/completed/2026-01/traj_v87hypnongqx.md +42 -0
  81. package/.trajectories/completed/2026-01/traj_wkp2fgzdyinb.json +53 -0
  82. package/.trajectories/completed/2026-01/traj_wkp2fgzdyinb.md +32 -0
  83. package/.trajectories/completed/2026-01/traj_x14t8w8rn7xg.json +20 -0
  84. package/.trajectories/completed/2026-01/traj_x14t8w8rn7xg.md +6 -0
  85. package/.trajectories/completed/2026-01/traj_xnwbznkvv8ua.json +175 -0
  86. package/.trajectories/completed/2026-01/traj_xnwbznkvv8ua.md +82 -0
  87. package/.trajectories/completed/2026-01/traj_ysjc8zaeqtd3.json +47 -0
  88. package/.trajectories/completed/2026-01/traj_ysjc8zaeqtd3.md +32 -0
  89. package/.trajectories/completed/2026-01/traj_yvdadtvdgnz3.json +59 -0
  90. package/.trajectories/completed/2026-01/traj_yvdadtvdgnz3.md +37 -0
  91. package/.trajectories/completed/2026-01/traj_z0vcw1wrzide.json +53 -0
  92. package/.trajectories/completed/2026-01/traj_z0vcw1wrzide.md +32 -0
  93. package/.trajectories/index.json +314 -0
  94. package/ARCHITECTURE.md +1245 -0
  95. package/README.md +1 -1
  96. package/TESTING.md +278 -0
  97. package/deploy/init-db.sql +5 -0
  98. package/deploy/scripts/setup-fly-workspaces.sh +69 -0
  99. package/deploy/scripts/setup-railway.sh +75 -0
  100. package/deploy/workspace/entrypoint-browser.sh +118 -0
  101. package/deploy/workspace/entrypoint.sh +348 -0
  102. package/deploy/workspace/git-credential-relay +111 -0
  103. package/dist/bridge/spawner.d.ts +53 -0
  104. package/dist/bridge/spawner.js +203 -19
  105. package/dist/bridge/types.d.ts +12 -0
  106. package/dist/cli/index.js +618 -5
  107. package/dist/cloud/api/auth.d.ts +3 -2
  108. package/dist/cloud/api/auth.js +10 -98
  109. package/dist/cloud/api/billing.js +30 -9
  110. package/dist/cloud/api/cli-pty-runner.d.ts +54 -0
  111. package/dist/cloud/api/cli-pty-runner.js +119 -0
  112. package/dist/cloud/api/codex-auth-helper.d.ts +15 -0
  113. package/dist/cloud/api/codex-auth-helper.js +100 -0
  114. package/dist/cloud/api/generic-webhooks.d.ts +8 -0
  115. package/dist/cloud/api/generic-webhooks.js +129 -0
  116. package/dist/cloud/api/git.d.ts +8 -0
  117. package/dist/cloud/api/git.js +152 -0
  118. package/dist/cloud/api/github-app.d.ts +11 -0
  119. package/dist/cloud/api/github-app.js +189 -0
  120. package/dist/cloud/api/middleware/planLimits.d.ts +7 -0
  121. package/dist/cloud/api/middleware/planLimits.js +39 -1
  122. package/dist/cloud/api/monitoring.d.ts +11 -0
  123. package/dist/cloud/api/monitoring.js +578 -0
  124. package/dist/cloud/api/nango-auth.d.ts +9 -0
  125. package/dist/cloud/api/nango-auth.js +377 -0
  126. package/dist/cloud/api/onboarding.d.ts +8 -1
  127. package/dist/cloud/api/onboarding.js +313 -119
  128. package/dist/cloud/api/policy.d.ts +8 -0
  129. package/dist/cloud/api/policy.js +229 -0
  130. package/dist/cloud/api/providers.js +114 -42
  131. package/dist/cloud/api/repos.d.ts +1 -0
  132. package/dist/cloud/api/repos.js +186 -0
  133. package/dist/cloud/api/test-helpers.d.ts +10 -0
  134. package/dist/cloud/api/test-helpers.js +575 -0
  135. package/dist/cloud/api/webhooks.d.ts +8 -0
  136. package/dist/cloud/api/webhooks.js +645 -0
  137. package/dist/cloud/api/workspaces.js +320 -12
  138. package/dist/cloud/billing/plans.js +32 -19
  139. package/dist/cloud/billing/types.d.ts +9 -3
  140. package/dist/cloud/config.d.ts +9 -2
  141. package/dist/cloud/config.js +13 -4
  142. package/dist/cloud/db/drizzle.d.ts +84 -1
  143. package/dist/cloud/db/drizzle.js +470 -0
  144. package/dist/cloud/db/index.d.ts +9 -4
  145. package/dist/cloud/db/index.js +11 -3
  146. package/dist/cloud/db/schema.d.ts +3283 -556
  147. package/dist/cloud/db/schema.js +314 -1
  148. package/dist/cloud/index.d.ts +1 -0
  149. package/dist/cloud/index.js +2 -0
  150. package/dist/cloud/provisioner/index.d.ts +56 -0
  151. package/dist/cloud/provisioner/index.js +676 -34
  152. package/dist/cloud/server.d.ts +1 -0
  153. package/dist/cloud/server.js +362 -13
  154. package/dist/cloud/services/auto-scaler.d.ts +152 -0
  155. package/dist/cloud/services/auto-scaler.js +439 -0
  156. package/dist/cloud/services/capacity-manager.d.ts +148 -0
  157. package/dist/cloud/services/capacity-manager.js +449 -0
  158. package/dist/cloud/services/ci-agent-spawner.d.ts +49 -0
  159. package/dist/cloud/services/ci-agent-spawner.js +373 -0
  160. package/dist/cloud/services/index.d.ts +12 -0
  161. package/dist/cloud/services/index.js +15 -0
  162. package/dist/cloud/services/mention-handler.d.ts +65 -0
  163. package/dist/cloud/services/mention-handler.js +405 -0
  164. package/dist/cloud/services/nango.d.ts +186 -0
  165. package/dist/cloud/services/nango.js +344 -0
  166. package/dist/cloud/services/persistence.d.ts +131 -0
  167. package/dist/cloud/services/persistence.js +200 -0
  168. package/dist/cloud/services/planLimits.d.ts +37 -0
  169. package/dist/cloud/services/planLimits.js +86 -5
  170. package/dist/cloud/services/scaling-orchestrator.d.ts +159 -0
  171. package/dist/cloud/services/scaling-orchestrator.js +502 -0
  172. package/dist/cloud/services/scaling-policy.d.ts +121 -0
  173. package/dist/cloud/services/scaling-policy.js +415 -0
  174. package/dist/cloud/vault/index.js +1 -1
  175. package/dist/cloud/webhooks/index.d.ts +24 -0
  176. package/dist/cloud/webhooks/index.js +29 -0
  177. package/dist/cloud/webhooks/parsers/github.d.ts +8 -0
  178. package/dist/cloud/webhooks/parsers/github.js +234 -0
  179. package/dist/cloud/webhooks/parsers/index.d.ts +23 -0
  180. package/dist/cloud/webhooks/parsers/index.js +30 -0
  181. package/dist/cloud/webhooks/parsers/linear.d.ts +9 -0
  182. package/dist/cloud/webhooks/parsers/linear.js +258 -0
  183. package/dist/cloud/webhooks/parsers/slack.d.ts +9 -0
  184. package/dist/cloud/webhooks/parsers/slack.js +214 -0
  185. package/dist/cloud/webhooks/responders/github.d.ts +8 -0
  186. package/dist/cloud/webhooks/responders/github.js +73 -0
  187. package/dist/cloud/webhooks/responders/index.d.ts +23 -0
  188. package/dist/cloud/webhooks/responders/index.js +30 -0
  189. package/dist/cloud/webhooks/responders/linear.d.ts +9 -0
  190. package/dist/cloud/webhooks/responders/linear.js +149 -0
  191. package/dist/cloud/webhooks/responders/slack.d.ts +20 -0
  192. package/dist/cloud/webhooks/responders/slack.js +178 -0
  193. package/dist/cloud/webhooks/router.d.ts +25 -0
  194. package/dist/cloud/webhooks/router.js +504 -0
  195. package/dist/cloud/webhooks/rules-engine.d.ts +24 -0
  196. package/dist/cloud/webhooks/rules-engine.js +287 -0
  197. package/dist/cloud/webhooks/types.d.ts +186 -0
  198. package/dist/cloud/webhooks/types.js +8 -0
  199. package/dist/continuity/formatter.d.ts +51 -0
  200. package/dist/continuity/formatter.js +313 -0
  201. package/dist/continuity/handoff-store.d.ts +67 -0
  202. package/dist/continuity/handoff-store.js +472 -0
  203. package/dist/continuity/index.d.ts +45 -0
  204. package/dist/continuity/index.js +48 -0
  205. package/dist/continuity/ledger-store.d.ts +110 -0
  206. package/dist/continuity/ledger-store.js +500 -0
  207. package/dist/continuity/manager.d.ts +178 -0
  208. package/dist/continuity/manager.js +562 -0
  209. package/dist/continuity/parser.d.ts +76 -0
  210. package/dist/continuity/parser.js +579 -0
  211. package/dist/continuity/types.d.ts +180 -0
  212. package/dist/continuity/types.js +9 -0
  213. package/dist/daemon/agent-manager.d.ts +27 -0
  214. package/dist/daemon/agent-manager.js +107 -6
  215. package/dist/daemon/agent-registry.d.ts +32 -0
  216. package/dist/daemon/agent-registry.js +42 -2
  217. package/dist/daemon/api.d.ts +12 -0
  218. package/dist/daemon/api.js +131 -2
  219. package/dist/daemon/cli-auth.d.ts +67 -0
  220. package/dist/daemon/cli-auth.js +537 -0
  221. package/dist/daemon/cloud-sync.js +9 -7
  222. package/dist/daemon/orchestrator.js +30 -0
  223. package/dist/daemon/router.d.ts +5 -0
  224. package/dist/daemon/router.js +78 -26
  225. package/dist/daemon/server.d.ts +5 -0
  226. package/dist/daemon/server.js +9 -1
  227. package/dist/daemon/services/browser-testing.d.ts +88 -0
  228. package/dist/daemon/services/browser-testing.js +244 -0
  229. package/dist/daemon/services/container-spawner.d.ts +135 -0
  230. package/dist/daemon/services/container-spawner.js +313 -0
  231. package/dist/daemon/types.d.ts +5 -1
  232. package/dist/dashboard/out/404.html +1 -1
  233. package/dist/dashboard/out/_next/static/chunks/116-2502180def231162.js +1 -0
  234. package/dist/dashboard/out/_next/static/chunks/282-980c2eb8fff20123.js +1 -0
  235. package/dist/dashboard/out/_next/static/chunks/699-3b1cd6618a45d259.js +1 -0
  236. package/dist/dashboard/out/_next/static/chunks/724-2dae7627550ab88f.js +9 -0
  237. package/dist/dashboard/out/_next/static/chunks/766-1f2dd8cb7f766b0b.js +1 -0
  238. package/dist/dashboard/out/_next/static/chunks/app/app/onboarding/page-3fdfa60e53f2810d.js +1 -0
  239. package/dist/dashboard/out/_next/static/chunks/app/app/page-e6381e5a6e1fbcfd.js +1 -0
  240. package/dist/dashboard/out/_next/static/chunks/app/connect-repos/page-3538dfe0ffe984b8.js +1 -0
  241. package/dist/dashboard/out/_next/static/chunks/app/history/{page-b6edd4dde8d08194.js → page-abb9ab2d329f56e9.js} +1 -1
  242. package/dist/dashboard/out/_next/static/chunks/app/layout-c0d118c0f92d969c.js +1 -0
  243. package/dist/dashboard/out/_next/static/chunks/app/login/page-c22d080201cbd9fb.js +1 -0
  244. package/dist/dashboard/out/_next/static/chunks/app/metrics/page-67a3e98d9a43a6ed.js +1 -0
  245. package/dist/dashboard/out/_next/static/chunks/app/page-77e9c65420a06cfb.js +1 -0
  246. package/dist/dashboard/out/_next/static/chunks/app/pricing/page-b08ed1c34d14434a.js +1 -0
  247. package/dist/dashboard/out/_next/static/chunks/app/providers/page-e88bc117ef7671c3.js +1 -0
  248. package/dist/dashboard/out/_next/static/chunks/app/signup/page-68d34f50baa8ab6b.js +1 -0
  249. package/dist/dashboard/out/_next/static/chunks/e868780c-48e5f147c90a3a41.js +18 -0
  250. package/dist/dashboard/out/_next/static/chunks/{main-app-5d692157a8eb1fd9.js → main-app-6e8e8d3ef4e0192a.js} +1 -1
  251. package/dist/dashboard/out/_next/static/chunks/{main-c2f423b9c9f4591b.js → main-ed4e1fb6f29c34cf.js} +1 -1
  252. package/dist/dashboard/out/_next/static/chunks/webpack-1cdd8ed57114d5e1.js +1 -0
  253. package/dist/dashboard/out/_next/static/css/29852f26181969a0.css +1 -0
  254. package/dist/dashboard/out/_next/static/css/7c3ae9e8617d42a5.css +1 -0
  255. package/dist/dashboard/out/app/onboarding.html +1 -0
  256. package/dist/dashboard/out/app/onboarding.txt +7 -0
  257. package/dist/dashboard/out/app.html +1 -14
  258. package/dist/dashboard/out/app.txt +2 -2
  259. package/dist/dashboard/out/connect-repos.html +1 -0
  260. package/dist/dashboard/out/connect-repos.txt +7 -0
  261. package/dist/dashboard/out/history.html +1 -1
  262. package/dist/dashboard/out/history.txt +2 -2
  263. package/dist/dashboard/out/index.html +1 -1
  264. package/dist/dashboard/out/index.txt +2 -2
  265. package/dist/dashboard/out/login.html +6 -0
  266. package/dist/dashboard/out/login.txt +7 -0
  267. package/dist/dashboard/out/metrics.html +1 -1
  268. package/dist/dashboard/out/metrics.txt +2 -2
  269. package/dist/dashboard/out/pricing.html +3 -3
  270. package/dist/dashboard/out/pricing.txt +2 -2
  271. package/dist/dashboard/out/providers.html +1 -0
  272. package/dist/dashboard/out/providers.txt +7 -0
  273. package/dist/dashboard/out/signup.html +6 -0
  274. package/dist/dashboard/out/signup.txt +7 -0
  275. package/dist/dashboard-server/server.js +1308 -8
  276. package/dist/hooks/emitter.d.ts +40 -0
  277. package/dist/hooks/emitter.js +63 -0
  278. package/dist/hooks/index.d.ts +3 -0
  279. package/dist/hooks/index.js +3 -0
  280. package/dist/hooks/registry.d.ts +173 -0
  281. package/dist/hooks/registry.js +476 -0
  282. package/dist/hooks/trajectory-hooks.d.ts +52 -0
  283. package/dist/hooks/trajectory-hooks.js +183 -0
  284. package/dist/hooks/types.d.ts +141 -0
  285. package/dist/index.d.ts +2 -0
  286. package/dist/index.js +3 -0
  287. package/dist/memory/adapters/index.d.ts +8 -0
  288. package/dist/memory/adapters/index.js +8 -0
  289. package/dist/memory/adapters/inmemory.d.ts +59 -0
  290. package/dist/memory/adapters/inmemory.js +195 -0
  291. package/dist/memory/adapters/supermemory.d.ts +71 -0
  292. package/dist/memory/adapters/supermemory.js +338 -0
  293. package/dist/memory/factory.d.ts +48 -0
  294. package/dist/memory/factory.js +143 -0
  295. package/dist/memory/index.d.ts +32 -0
  296. package/dist/memory/index.js +32 -0
  297. package/dist/memory/memory-hooks.d.ts +60 -0
  298. package/dist/memory/memory-hooks.js +313 -0
  299. package/dist/memory/service.d.ts +49 -0
  300. package/dist/memory/service.js +146 -0
  301. package/dist/memory/types.d.ts +195 -0
  302. package/dist/memory/types.js +8 -0
  303. package/dist/policy/agent-policy.d.ts +225 -0
  304. package/dist/policy/agent-policy.js +665 -0
  305. package/dist/policy/cloud-policy-fetcher.d.ts +12 -0
  306. package/dist/policy/cloud-policy-fetcher.js +64 -0
  307. package/dist/resiliency/crash-insights.d.ts +156 -0
  308. package/dist/resiliency/crash-insights.js +492 -0
  309. package/dist/resiliency/gossip-health.d.ts +137 -0
  310. package/dist/resiliency/gossip-health.js +241 -0
  311. package/dist/resiliency/index.d.ts +5 -0
  312. package/dist/resiliency/index.js +5 -0
  313. package/dist/resiliency/leader-watchdog.d.ts +109 -0
  314. package/dist/resiliency/leader-watchdog.js +189 -0
  315. package/dist/resiliency/memory-monitor.d.ts +172 -0
  316. package/dist/resiliency/memory-monitor.js +593 -0
  317. package/dist/resiliency/stateless-lead.d.ts +149 -0
  318. package/dist/resiliency/stateless-lead.js +308 -0
  319. package/dist/resiliency/supervisor.d.ts +38 -0
  320. package/dist/resiliency/supervisor.js +122 -0
  321. package/dist/shared/cli-auth-config.d.ts +91 -0
  322. package/dist/shared/cli-auth-config.js +264 -0
  323. package/dist/storage/adapter.d.ts +1 -1
  324. package/dist/trajectory/config.d.ts +84 -0
  325. package/dist/trajectory/config.js +163 -0
  326. package/dist/trajectory/index.d.ts +8 -0
  327. package/dist/trajectory/index.js +8 -0
  328. package/dist/trajectory/integration.d.ts +292 -0
  329. package/dist/trajectory/integration.js +834 -0
  330. package/dist/utils/logger.js +1 -1
  331. package/dist/utils/project-namespace.d.ts +24 -0
  332. package/dist/utils/project-namespace.js +84 -0
  333. package/dist/wrapper/parser.d.ts +10 -0
  334. package/dist/wrapper/parser.js +100 -33
  335. package/dist/wrapper/pty-wrapper.d.ts +197 -16
  336. package/dist/wrapper/pty-wrapper.js +943 -106
  337. package/dist/wrapper/shared.d.ts +165 -0
  338. package/dist/wrapper/shared.js +270 -0
  339. package/dist/wrapper/tmux-wrapper.d.ts +73 -11
  340. package/dist/wrapper/tmux-wrapper.js +541 -120
  341. package/package.json +16 -16
  342. package/scripts/postinstall.js +60 -0
  343. package/test-push.txt +1 -0
  344. package/bin/tmux +0 -0
  345. package/dist/bridge/config.d.ts.map +0 -1
  346. package/dist/bridge/config.js.map +0 -1
  347. package/dist/bridge/index.d.ts.map +0 -1
  348. package/dist/bridge/index.js.map +0 -1
  349. package/dist/bridge/multi-project-client.d.ts.map +0 -1
  350. package/dist/bridge/multi-project-client.js.map +0 -1
  351. package/dist/bridge/shadow-cli.d.ts.map +0 -1
  352. package/dist/bridge/shadow-cli.js.map +0 -1
  353. package/dist/bridge/shadow-config.d.ts.map +0 -1
  354. package/dist/bridge/shadow-config.js.map +0 -1
  355. package/dist/bridge/spawner.d.ts.map +0 -1
  356. package/dist/bridge/spawner.js.map +0 -1
  357. package/dist/bridge/teams-config.d.ts.map +0 -1
  358. package/dist/bridge/teams-config.js.map +0 -1
  359. package/dist/bridge/types.d.ts.map +0 -1
  360. package/dist/bridge/types.js.map +0 -1
  361. package/dist/bridge/utils.d.ts.map +0 -1
  362. package/dist/bridge/utils.js.map +0 -1
  363. package/dist/cli/index.d.ts.map +0 -1
  364. package/dist/cli/index.js.map +0 -1
  365. package/dist/cloud/api/auth.d.ts.map +0 -1
  366. package/dist/cloud/api/auth.js.map +0 -1
  367. package/dist/cloud/api/billing.d.ts.map +0 -1
  368. package/dist/cloud/api/billing.js.map +0 -1
  369. package/dist/cloud/api/coordinators.d.ts.map +0 -1
  370. package/dist/cloud/api/coordinators.js.map +0 -1
  371. package/dist/cloud/api/daemons.d.ts.map +0 -1
  372. package/dist/cloud/api/daemons.js.map +0 -1
  373. package/dist/cloud/api/middleware/planLimits.d.ts.map +0 -1
  374. package/dist/cloud/api/middleware/planLimits.js.map +0 -1
  375. package/dist/cloud/api/onboarding.d.ts.map +0 -1
  376. package/dist/cloud/api/onboarding.js.map +0 -1
  377. package/dist/cloud/api/providers.d.ts.map +0 -1
  378. package/dist/cloud/api/providers.js.map +0 -1
  379. package/dist/cloud/api/repos.d.ts.map +0 -1
  380. package/dist/cloud/api/repos.js.map +0 -1
  381. package/dist/cloud/api/teams.d.ts.map +0 -1
  382. package/dist/cloud/api/teams.js.map +0 -1
  383. package/dist/cloud/api/usage.d.ts.map +0 -1
  384. package/dist/cloud/api/usage.js.map +0 -1
  385. package/dist/cloud/api/workspaces.d.ts.map +0 -1
  386. package/dist/cloud/api/workspaces.js.map +0 -1
  387. package/dist/cloud/billing/index.d.ts.map +0 -1
  388. package/dist/cloud/billing/index.js.map +0 -1
  389. package/dist/cloud/billing/plans.d.ts.map +0 -1
  390. package/dist/cloud/billing/plans.js.map +0 -1
  391. package/dist/cloud/billing/service.d.ts.map +0 -1
  392. package/dist/cloud/billing/service.js.map +0 -1
  393. package/dist/cloud/billing/types.d.ts.map +0 -1
  394. package/dist/cloud/billing/types.js.map +0 -1
  395. package/dist/cloud/config.d.ts.map +0 -1
  396. package/dist/cloud/config.js.map +0 -1
  397. package/dist/cloud/db/drizzle.d.ts.map +0 -1
  398. package/dist/cloud/db/drizzle.js.map +0 -1
  399. package/dist/cloud/db/index.d.ts.map +0 -1
  400. package/dist/cloud/db/index.js.map +0 -1
  401. package/dist/cloud/db/schema.d.ts.map +0 -1
  402. package/dist/cloud/db/schema.js.map +0 -1
  403. package/dist/cloud/index.d.ts.map +0 -1
  404. package/dist/cloud/index.js.map +0 -1
  405. package/dist/cloud/provisioner/index.d.ts.map +0 -1
  406. package/dist/cloud/provisioner/index.js.map +0 -1
  407. package/dist/cloud/server.d.ts.map +0 -1
  408. package/dist/cloud/server.js.map +0 -1
  409. package/dist/cloud/services/coordinator.d.ts.map +0 -1
  410. package/dist/cloud/services/coordinator.js.map +0 -1
  411. package/dist/cloud/services/planLimits.d.ts.map +0 -1
  412. package/dist/cloud/services/planLimits.js.map +0 -1
  413. package/dist/cloud/vault/index.d.ts.map +0 -1
  414. package/dist/cloud/vault/index.js.map +0 -1
  415. package/dist/daemon/agent-manager.d.ts.map +0 -1
  416. package/dist/daemon/agent-manager.js.map +0 -1
  417. package/dist/daemon/agent-registry.d.ts.map +0 -1
  418. package/dist/daemon/agent-registry.js.map +0 -1
  419. package/dist/daemon/api.d.ts.map +0 -1
  420. package/dist/daemon/api.js.map +0 -1
  421. package/dist/daemon/auth.d.ts.map +0 -1
  422. package/dist/daemon/auth.js.map +0 -1
  423. package/dist/daemon/cloud-sync.d.ts.map +0 -1
  424. package/dist/daemon/cloud-sync.js.map +0 -1
  425. package/dist/daemon/connection.d.ts.map +0 -1
  426. package/dist/daemon/connection.js.map +0 -1
  427. package/dist/daemon/index.d.ts.map +0 -1
  428. package/dist/daemon/index.js.map +0 -1
  429. package/dist/daemon/orchestrator.d.ts.map +0 -1
  430. package/dist/daemon/orchestrator.js.map +0 -1
  431. package/dist/daemon/registry.d.ts.map +0 -1
  432. package/dist/daemon/registry.js.map +0 -1
  433. package/dist/daemon/router.d.ts.map +0 -1
  434. package/dist/daemon/router.js.map +0 -1
  435. package/dist/daemon/server.d.ts.map +0 -1
  436. package/dist/daemon/server.js.map +0 -1
  437. package/dist/daemon/types.d.ts.map +0 -1
  438. package/dist/daemon/types.js.map +0 -1
  439. package/dist/daemon/workspace-manager.d.ts.map +0 -1
  440. package/dist/daemon/workspace-manager.js.map +0 -1
  441. package/dist/dashboard/out/_next/static/chunks/693-7b3301d8f6bc5014.js +0 -1
  442. package/dist/dashboard/out/_next/static/chunks/713-f78477eb185f1f4d.js +0 -1
  443. package/dist/dashboard/out/_next/static/chunks/766-e53e1cfe39b0b5b5.js +0 -1
  444. package/dist/dashboard/out/_next/static/chunks/900-037c64bfd797fb2a.js +0 -1
  445. package/dist/dashboard/out/_next/static/chunks/app/app/page-e3d9e1f4466b9bae.js +0 -1
  446. package/dist/dashboard/out/_next/static/chunks/app/layout-2433bb48965f4333.js +0 -1
  447. package/dist/dashboard/out/_next/static/chunks/app/metrics/page-e68825a81db67ba1.js +0 -1
  448. package/dist/dashboard/out/_next/static/chunks/app/page-cc108bf68c8a657f.js +0 -1
  449. package/dist/dashboard/out/_next/static/chunks/app/pricing/page-d80e03a5297f95b6.js +0 -1
  450. package/dist/dashboard/out/_next/static/chunks/webpack-a5acc2831d094776.js +0 -1
  451. package/dist/dashboard/out/_next/static/css/79b80143647a07d7.css +0 -1
  452. package/dist/dashboard/out/_next/static/css/8cf277370ad48cfe.css +0 -1
  453. package/dist/dashboard-server/metrics.d.ts.map +0 -1
  454. package/dist/dashboard-server/metrics.js.map +0 -1
  455. package/dist/dashboard-server/needs-attention.d.ts.map +0 -1
  456. package/dist/dashboard-server/needs-attention.js.map +0 -1
  457. package/dist/dashboard-server/server.d.ts.map +0 -1
  458. package/dist/dashboard-server/server.js.map +0 -1
  459. package/dist/dashboard-server/start.d.ts.map +0 -1
  460. package/dist/dashboard-server/start.js.map +0 -1
  461. package/dist/hooks/inbox-check/hook.d.ts.map +0 -1
  462. package/dist/hooks/inbox-check/hook.js.map +0 -1
  463. package/dist/hooks/inbox-check/index.d.ts.map +0 -1
  464. package/dist/hooks/inbox-check/index.js.map +0 -1
  465. package/dist/hooks/inbox-check/types.d.ts.map +0 -1
  466. package/dist/hooks/inbox-check/types.js.map +0 -1
  467. package/dist/hooks/inbox-check/utils.d.ts.map +0 -1
  468. package/dist/hooks/inbox-check/utils.js.map +0 -1
  469. package/dist/hooks/index.d.ts.map +0 -1
  470. package/dist/hooks/index.js.map +0 -1
  471. package/dist/hooks/types.d.ts.map +0 -1
  472. package/dist/hooks/types.js.map +0 -1
  473. package/dist/index.d.ts.map +0 -1
  474. package/dist/index.js.map +0 -1
  475. package/dist/protocol/framing.d.ts.map +0 -1
  476. package/dist/protocol/framing.js.map +0 -1
  477. package/dist/protocol/index.d.ts.map +0 -1
  478. package/dist/protocol/index.js.map +0 -1
  479. package/dist/protocol/types.d.ts.map +0 -1
  480. package/dist/protocol/types.js.map +0 -1
  481. package/dist/resiliency/context-persistence.d.ts.map +0 -1
  482. package/dist/resiliency/context-persistence.js.map +0 -1
  483. package/dist/resiliency/health-monitor.d.ts.map +0 -1
  484. package/dist/resiliency/health-monitor.js.map +0 -1
  485. package/dist/resiliency/index.d.ts.map +0 -1
  486. package/dist/resiliency/index.js.map +0 -1
  487. package/dist/resiliency/logger.d.ts.map +0 -1
  488. package/dist/resiliency/logger.js.map +0 -1
  489. package/dist/resiliency/metrics.d.ts.map +0 -1
  490. package/dist/resiliency/metrics.js.map +0 -1
  491. package/dist/resiliency/provider-context.d.ts.map +0 -1
  492. package/dist/resiliency/provider-context.js.map +0 -1
  493. package/dist/resiliency/supervisor.d.ts.map +0 -1
  494. package/dist/resiliency/supervisor.js.map +0 -1
  495. package/dist/state/agent-state.d.ts.map +0 -1
  496. package/dist/state/agent-state.js.map +0 -1
  497. package/dist/storage/adapter.d.ts.map +0 -1
  498. package/dist/storage/adapter.js.map +0 -1
  499. package/dist/storage/sqlite-adapter.d.ts.map +0 -1
  500. package/dist/storage/sqlite-adapter.js.map +0 -1
  501. package/dist/utils/agent-config.d.ts.map +0 -1
  502. package/dist/utils/agent-config.js.map +0 -1
  503. package/dist/utils/command-resolver.d.ts.map +0 -1
  504. package/dist/utils/command-resolver.js.map +0 -1
  505. package/dist/utils/index.d.ts.map +0 -1
  506. package/dist/utils/index.js.map +0 -1
  507. package/dist/utils/logger.d.ts.map +0 -1
  508. package/dist/utils/logger.js.map +0 -1
  509. package/dist/utils/name-generator.d.ts.map +0 -1
  510. package/dist/utils/name-generator.js.map +0 -1
  511. package/dist/utils/project-namespace.d.ts.map +0 -1
  512. package/dist/utils/project-namespace.js.map +0 -1
  513. package/dist/utils/tmux-resolver.d.ts.map +0 -1
  514. package/dist/utils/tmux-resolver.js.map +0 -1
  515. package/dist/utils/update-checker.d.ts.map +0 -1
  516. package/dist/utils/update-checker.js.map +0 -1
  517. package/dist/wrapper/client.d.ts.map +0 -1
  518. package/dist/wrapper/client.js.map +0 -1
  519. package/dist/wrapper/inbox.d.ts.map +0 -1
  520. package/dist/wrapper/inbox.js.map +0 -1
  521. package/dist/wrapper/index.d.ts.map +0 -1
  522. package/dist/wrapper/index.js.map +0 -1
  523. package/dist/wrapper/parser.d.ts.map +0 -1
  524. package/dist/wrapper/parser.js.map +0 -1
  525. package/dist/wrapper/pty-wrapper.d.ts.map +0 -1
  526. package/dist/wrapper/pty-wrapper.js.map +0 -1
  527. package/dist/wrapper/tmux-wrapper.d.ts.map +0 -1
  528. package/dist/wrapper/tmux-wrapper.js.map +0 -1
  529. package/docs/AGENTS.md +0 -513
  530. package/docs/ARCHITECTURE_DECISIONS.md +0 -175
  531. package/docs/CHANGELOG.md +0 -11
  532. package/docs/CLI-SIMPLIFICATION-COMPLETE.md +0 -48
  533. package/docs/CLOUD-ARCHITECTURE.md +0 -652
  534. package/docs/CLOUD-ONBOARDING-DESIGN.md +0 -1983
  535. package/docs/COMPETITIVE_ANALYSIS.md +0 -897
  536. package/docs/CONTRIBUTING.md +0 -151
  537. package/docs/DESIGN_BRIDGE_STAFFING.md +0 -878
  538. package/docs/DESIGN_V2.md +0 -1079
  539. package/docs/INTEGRATION-GUIDE.md +0 -926
  540. package/docs/MONETIZATION.md +0 -1679
  541. package/docs/PROPOSAL-trajectories.md +0 -1582
  542. package/docs/PROTOCOL.md +0 -325
  543. package/docs/SCALING_ANALYSIS.md +0 -280
  544. package/docs/TESTING_PRESENCE_FEATURES.md +0 -327
  545. package/docs/TMUX_IMPLEMENTATION_NOTES.md +0 -364
  546. package/docs/TMUX_IMPROVEMENTS.md +0 -968
  547. package/docs/agent-relay-snippet.md +0 -168
  548. package/docs/competitive-analysis-mcp-agent-mail.md +0 -389
  549. package/docs/dashboard-v2-plan.md +0 -179
  550. package/docs/guides/CLOUD.md +0 -236
  551. package/docs/guides/LOCAL.md +0 -535
  552. package/docs/guides/SELF-HOSTED.md +0 -494
  553. package/docs/proposals/shadow-as-subagent.md +0 -765
  554. package/docs/proposals/slack-bot-integration.md +0 -1457
  555. package/docs/removable-code-analysis.md +0 -24
  556. package/scripts/dev/PUBLIC_RELEASE_PLAN.md +0 -88
  557. package/scripts/dev/dev-team-setup.sh +0 -431
  558. package/scripts/e2e-test.sh +0 -119
  559. package/scripts/games/game-protocol.md +0 -79
  560. package/scripts/games/hearts-setup.sh +0 -264
  561. package/scripts/tictactoe-setup.sh +0 -181
  562. /package/dist/dashboard/out/_next/static/chunks/{117-b2cd8d6485aacf2b.js → 117-f7b8ab0809342e77.js} +0 -0
  563. /package/dist/dashboard/out/_next/static/chunks/{648-8f3f26864ce515e5.js → 648-5cc6e1921389a58a.js} +0 -0
  564. /package/dist/dashboard/out/_next/static/chunks/app/_not-found/{page-0b990dbb71d72a98.js → page-53b8a69f76db17d0.js} +0 -0
  565. /package/dist/dashboard/out/_next/static/chunks/{fd9d1056-bf46c09eb57e019c.js → fd9d1056-609918ca7b6280bb.js} +0 -0
  566. /package/dist/dashboard/out/_next/static/{6HHWb2ZmnJ4OSm0zUP7h4 → wPgKJtcOmTFLpUncDg16A}/_buildManifest.js +0 -0
  567. /package/dist/dashboard/out/_next/static/{6HHWb2ZmnJ4OSm0zUP7h4 → wPgKJtcOmTFLpUncDg16A}/_ssgManifest.js +0 -0
@@ -0,0 +1,575 @@
1
+ /**
2
+ * Test Helper API Routes
3
+ *
4
+ * These endpoints are ONLY available in test/development mode.
5
+ * They allow integration tests to create users and daemons without OAuth.
6
+ *
7
+ * IMPORTANT: These routes are disabled in production (NODE_ENV=production).
8
+ */
9
+ import { Router } from 'express';
10
+ import { randomUUID, createHash, randomBytes } from 'crypto';
11
+ import { getDb } from '../db/drizzle.js';
12
+ import { users, linkedDaemons, workspaces, repositories } from '../db/schema.js';
13
+ import { getProvisioner } from '../provisioner/index.js';
14
+ import { db } from '../db/index.js';
15
+ import { nangoService } from '../services/nango.js';
16
+ export const testHelpersRouter = Router();
17
+ // Only enable in test/development mode
18
+ const isTestMode = process.env.NODE_ENV !== 'production';
19
+ if (!isTestMode) {
20
+ console.warn('[test-helpers] Test helper routes are disabled in production');
21
+ }
22
+ /**
23
+ * POST /api/test/create-user
24
+ * Creates a test user without OAuth
25
+ */
26
+ testHelpersRouter.post('/create-user', async (req, res) => {
27
+ if (!isTestMode) {
28
+ return res.status(403).json({ error: 'Test endpoints disabled in production' });
29
+ }
30
+ try {
31
+ const { email, name } = req.body;
32
+ const db = getDb();
33
+ const testId = `test-${randomUUID()}`;
34
+ // Create user with required GitHub fields
35
+ const [user] = await db.insert(users).values({
36
+ email: email || `${testId}@test.local`,
37
+ githubId: testId,
38
+ githubUsername: name || 'test-user',
39
+ avatarUrl: null,
40
+ }).returning();
41
+ // Create session
42
+ const sessionId = randomUUID();
43
+ req.session.userId = user.id;
44
+ // Get session cookie (simplified for testing)
45
+ const sessionCookie = `connect.sid=s%3A${sessionId}`;
46
+ res.json({
47
+ userId: user.id,
48
+ email: user.email,
49
+ sessionCookie,
50
+ });
51
+ }
52
+ catch (error) {
53
+ console.error('Error creating test user:', error);
54
+ res.status(500).json({ error: 'Failed to create test user' });
55
+ }
56
+ });
57
+ /**
58
+ * POST /api/test/create-daemon
59
+ * Creates a test daemon with API key
60
+ */
61
+ testHelpersRouter.post('/create-daemon', async (req, res) => {
62
+ if (!isTestMode) {
63
+ return res.status(403).json({ error: 'Test endpoints disabled in production' });
64
+ }
65
+ try {
66
+ const { name, machineId } = req.body;
67
+ if (!name) {
68
+ return res.status(400).json({ error: 'name is required' });
69
+ }
70
+ const db = getDb();
71
+ // First, ensure we have a test user to associate with the daemon
72
+ let [testUser] = await db.select().from(users).limit(1);
73
+ if (!testUser) {
74
+ // Create a test user if none exists
75
+ const testId = `test-system-${randomUUID()}`;
76
+ [testUser] = await db.insert(users).values({
77
+ email: `${testId}@test.local`,
78
+ githubId: testId,
79
+ githubUsername: 'test-system-user',
80
+ avatarUrl: null,
81
+ }).returning();
82
+ }
83
+ // Generate API key
84
+ const apiKey = `ar_live_${randomBytes(32).toString('hex')}`;
85
+ const apiKeyHash = createHash('sha256').update(apiKey).digest('hex');
86
+ // Create daemon - only include fields that exist in schema
87
+ const [daemon] = await db.insert(linkedDaemons).values({
88
+ userId: testUser.id,
89
+ name,
90
+ machineId: machineId || randomUUID(),
91
+ apiKeyHash,
92
+ status: 'online',
93
+ metadata: {
94
+ hostname: 'test-host',
95
+ platform: 'linux',
96
+ version: '1.0.0-test',
97
+ },
98
+ }).returning();
99
+ res.json({
100
+ daemonId: daemon.id,
101
+ apiKey,
102
+ name: daemon.name,
103
+ machineId: daemon.machineId,
104
+ });
105
+ }
106
+ catch (error) {
107
+ console.error('Error creating test daemon:', error);
108
+ res.status(500).json({ error: 'Failed to create test daemon' });
109
+ }
110
+ });
111
+ /**
112
+ * DELETE /api/test/cleanup
113
+ * Cleans up test data
114
+ */
115
+ testHelpersRouter.delete('/cleanup', async (req, res) => {
116
+ if (!isTestMode) {
117
+ return res.status(403).json({ error: 'Test endpoints disabled in production' });
118
+ }
119
+ try {
120
+ const _db = getDb();
121
+ // Delete test data (users with test- prefix in githubId)
122
+ // Note: This cascades to linked daemons due to FK constraints
123
+ res.json({ success: true, message: 'Test data cleaned up' });
124
+ }
125
+ catch (error) {
126
+ console.error('Error cleaning up test data:', error);
127
+ res.status(500).json({ error: 'Failed to cleanup test data' });
128
+ }
129
+ });
130
+ /**
131
+ * GET /api/test/status
132
+ * Returns test mode status
133
+ */
134
+ testHelpersRouter.get('/status', (req, res) => {
135
+ res.json({
136
+ testMode: isTestMode,
137
+ nodeEnv: process.env.NODE_ENV,
138
+ timestamp: new Date().toISOString(),
139
+ });
140
+ });
141
+ /**
142
+ * POST /api/test/create-mock-workspace
143
+ * Creates a mock workspace pointing to a local dashboard server
144
+ *
145
+ * Use this to test the cloud flow locally without real provisioning.
146
+ * The workspace will have publicUrl pointing to localhost:3889.
147
+ */
148
+ testHelpersRouter.post('/create-mock-workspace', async (req, res) => {
149
+ if (!isTestMode) {
150
+ return res.status(403).json({ error: 'Test endpoints disabled in production' });
151
+ }
152
+ try {
153
+ const { name, publicUrl } = req.body;
154
+ const userId = req.session.userId;
155
+ if (!userId) {
156
+ return res.status(401).json({ error: 'Must be logged in. Use /api/test/create-user first or log in via OAuth.' });
157
+ }
158
+ const db = getDb();
159
+ // Create a mock workspace with local publicUrl
160
+ const [workspace] = await db.insert(workspaces).values({
161
+ userId,
162
+ name: name || 'Local Test Workspace',
163
+ status: 'running',
164
+ publicUrl: publicUrl || 'http://localhost:3889',
165
+ computeProvider: 'docker',
166
+ computeId: `mock-${randomUUID().slice(0, 8)}`,
167
+ config: {
168
+ providers: ['anthropic'],
169
+ repositories: [],
170
+ supervisorEnabled: true,
171
+ maxAgents: 10,
172
+ },
173
+ }).returning();
174
+ res.json({
175
+ workspaceId: workspace.id,
176
+ name: workspace.name,
177
+ status: workspace.status,
178
+ publicUrl: workspace.publicUrl,
179
+ message: 'Mock workspace created. Start agent-relay locally and navigate to /app.',
180
+ });
181
+ }
182
+ catch (error) {
183
+ console.error('Error creating mock workspace:', error);
184
+ res.status(500).json({ error: 'Failed to create mock workspace' });
185
+ }
186
+ });
187
+ /**
188
+ * POST /api/test/create-mock-repo
189
+ * Creates a mock repository for the current user
190
+ *
191
+ * Use this to test the cloud flow without connecting real GitHub repos.
192
+ */
193
+ testHelpersRouter.post('/create-mock-repo', async (req, res) => {
194
+ if (!isTestMode) {
195
+ return res.status(403).json({ error: 'Test endpoints disabled in production' });
196
+ }
197
+ try {
198
+ const { fullName, isPrivate } = req.body;
199
+ const userId = req.session.userId;
200
+ if (!userId) {
201
+ return res.status(401).json({ error: 'Must be logged in. Use /api/test/create-user first or log in via OAuth.' });
202
+ }
203
+ if (!fullName) {
204
+ return res.status(400).json({ error: 'fullName is required (e.g., "owner/repo")' });
205
+ }
206
+ const db = getDb();
207
+ // Create a mock repository
208
+ const [repo] = await db.insert(repositories).values({
209
+ userId,
210
+ githubId: Math.floor(Math.random() * 1000000),
211
+ githubFullName: fullName,
212
+ isPrivate: isPrivate ?? false,
213
+ defaultBranch: 'main',
214
+ syncStatus: 'synced',
215
+ nangoConnectionId: `mock-connection-${randomUUID().slice(0, 8)}`,
216
+ lastSyncedAt: new Date(),
217
+ }).returning();
218
+ res.json({
219
+ repoId: repo.id,
220
+ fullName: repo.githubFullName,
221
+ isPrivate: repo.isPrivate,
222
+ message: 'Mock repository created.',
223
+ });
224
+ }
225
+ catch (error) {
226
+ console.error('Error creating mock repo:', error);
227
+ res.status(500).json({ error: 'Failed to create mock repo' });
228
+ }
229
+ });
230
+ /**
231
+ * POST /api/test/login-as
232
+ * Quick login for testing - creates session for existing or new test user
233
+ */
234
+ testHelpersRouter.post('/login-as', async (req, res) => {
235
+ if (!isTestMode) {
236
+ return res.status(403).json({ error: 'Test endpoints disabled in production' });
237
+ }
238
+ try {
239
+ const { username } = req.body;
240
+ const db = getDb();
241
+ // Find or create user
242
+ let user;
243
+ const existingUsers = await db.select().from(users).limit(1);
244
+ if (existingUsers.length > 0 && !username) {
245
+ user = existingUsers[0];
246
+ }
247
+ else {
248
+ const testId = `test-${randomUUID()}`;
249
+ const [newUser] = await db.insert(users).values({
250
+ email: `${username || testId}@test.local`,
251
+ githubId: testId,
252
+ githubUsername: username || 'test-user',
253
+ avatarUrl: null,
254
+ plan: 'free',
255
+ }).returning();
256
+ user = newUser;
257
+ }
258
+ // Set session
259
+ req.session.userId = user.id;
260
+ res.json({
261
+ success: true,
262
+ userId: user.id,
263
+ username: user.githubUsername,
264
+ message: 'Logged in. You can now access /app and other authenticated routes.',
265
+ });
266
+ }
267
+ catch (error) {
268
+ console.error('Error in login-as:', error);
269
+ res.status(500).json({ error: 'Failed to login' });
270
+ }
271
+ });
272
+ /**
273
+ * GET /api/test/setup-local-cloud
274
+ * One-shot setup: creates user, mock repo, and mock workspace
275
+ *
276
+ * After calling this, start agent-relay locally and go to /app
277
+ */
278
+ testHelpersRouter.post('/setup-local-cloud', async (req, res) => {
279
+ if (!isTestMode) {
280
+ return res.status(403).json({ error: 'Test endpoints disabled in production' });
281
+ }
282
+ try {
283
+ const { repoName, workspaceName } = req.body;
284
+ const db = getDb();
285
+ // 1. Create or get test user
286
+ const testId = `test-${randomUUID().slice(0, 8)}`;
287
+ const [user] = await db.insert(users).values({
288
+ email: `${testId}@test.local`,
289
+ githubId: testId,
290
+ githubUsername: 'local-tester',
291
+ avatarUrl: null,
292
+ plan: 'free',
293
+ }).returning();
294
+ // Set session
295
+ req.session.userId = user.id;
296
+ // 2. Create mock repository
297
+ const [repo] = await db.insert(repositories).values({
298
+ userId: user.id,
299
+ githubId: Math.floor(Math.random() * 1000000),
300
+ githubFullName: repoName || 'test-org/test-repo',
301
+ isPrivate: false,
302
+ defaultBranch: 'main',
303
+ syncStatus: 'synced',
304
+ nangoConnectionId: `mock-${randomUUID().slice(0, 8)}`,
305
+ lastSyncedAt: new Date(),
306
+ }).returning();
307
+ // 3. Create mock workspace pointing to local dashboard
308
+ const [workspace] = await db.insert(workspaces).values({
309
+ userId: user.id,
310
+ name: workspaceName || 'Local Development',
311
+ status: 'running',
312
+ publicUrl: 'http://localhost:3889',
313
+ computeProvider: 'docker',
314
+ computeId: `mock-${randomUUID().slice(0, 8)}`,
315
+ config: {
316
+ providers: ['anthropic'],
317
+ repositories: [repo.githubFullName],
318
+ supervisorEnabled: true,
319
+ maxAgents: 10,
320
+ },
321
+ }).returning();
322
+ res.json({
323
+ success: true,
324
+ user: {
325
+ id: user.id,
326
+ username: user.githubUsername,
327
+ },
328
+ repo: {
329
+ id: repo.id,
330
+ fullName: repo.githubFullName,
331
+ },
332
+ workspace: {
333
+ id: workspace.id,
334
+ name: workspace.name,
335
+ publicUrl: workspace.publicUrl,
336
+ },
337
+ instructions: [
338
+ '1. Start agent-relay daemon: npm run dev (or agent-relay daemon)',
339
+ '2. Go to http://localhost:4567/app',
340
+ '3. The app should auto-connect to the local workspace',
341
+ '4. The WebSocket will connect to ws://localhost:3889/ws',
342
+ ],
343
+ });
344
+ }
345
+ catch (error) {
346
+ console.error('Error in setup-local-cloud:', error);
347
+ res.status(500).json({ error: 'Failed to setup local cloud' });
348
+ }
349
+ });
350
+ /**
351
+ * POST /api/test/provision-real-workspace
352
+ * Provision a REAL Docker container using your Nango GitHub App connection.
353
+ *
354
+ * This tests the full flow including:
355
+ * - Fetching GitHub App token from Nango
356
+ * - Spinning up a Docker container
357
+ * - Cloning your actual repositories
358
+ *
359
+ * Prerequisites:
360
+ * - Must be logged in (via real OAuth or /api/test/login-as)
361
+ * - Must have connected repos via /connect-repos (real Nango GitHub App OAuth)
362
+ * - Docker must be running locally
363
+ * - COMPUTE_PROVIDER must be 'docker' (default for dev)
364
+ */
365
+ testHelpersRouter.post('/provision-real-workspace', async (req, res) => {
366
+ if (!isTestMode) {
367
+ return res.status(403).json({ error: 'Test endpoints disabled in production' });
368
+ }
369
+ const userId = req.session.userId;
370
+ if (!userId) {
371
+ return res.status(401).json({
372
+ error: 'Must be logged in. Use real OAuth or /api/test/login-as first.',
373
+ });
374
+ }
375
+ try {
376
+ const { name, repositoryFullName, providers, githubToken } = req.body;
377
+ // Get user's connected repositories
378
+ const userRepos = await db.repositories.findByUserId(userId);
379
+ const reposWithNango = userRepos.filter(r => r.nangoConnectionId);
380
+ if (reposWithNango.length === 0) {
381
+ return res.status(400).json({
382
+ error: 'No repositories with Nango connection found. Complete /connect-repos first with real GitHub OAuth.',
383
+ hint: 'Go to http://localhost:4567/connect-repos and connect your GitHub App, or pass githubToken directly',
384
+ });
385
+ }
386
+ // Determine which repo to use
387
+ let targetRepo = reposWithNango[0];
388
+ if (repositoryFullName) {
389
+ const found = reposWithNango.find(r => r.githubFullName === repositoryFullName);
390
+ if (!found) {
391
+ return res.status(400).json({
392
+ error: `Repository ${repositoryFullName} not found or not connected via Nango`,
393
+ availableRepos: reposWithNango.map(r => r.githubFullName),
394
+ });
395
+ }
396
+ targetRepo = found;
397
+ }
398
+ // Use the real provisioner (Docker in dev mode)
399
+ const provisioner = getProvisioner();
400
+ const result = await provisioner.provision({
401
+ userId,
402
+ name: name || `Test Workspace - ${targetRepo.githubFullName}`,
403
+ providers: providers || ['anthropic'], // Default to anthropic if not specified
404
+ repositories: [targetRepo.githubFullName],
405
+ supervisorEnabled: true,
406
+ maxAgents: 10,
407
+ // Allow passing GitHub token directly for local testing
408
+ githubToken: githubToken || undefined,
409
+ });
410
+ if (result.status === 'error') {
411
+ return res.status(500).json({
412
+ error: 'Provisioning failed',
413
+ details: result.error,
414
+ });
415
+ }
416
+ res.json({
417
+ success: true,
418
+ workspace: {
419
+ id: result.workspaceId,
420
+ status: result.status,
421
+ publicUrl: result.publicUrl,
422
+ },
423
+ repository: targetRepo.githubFullName,
424
+ instructions: [
425
+ `1. Workspace is running at ${result.publicUrl}`,
426
+ `2. Repository ${targetRepo.githubFullName} should be cloned`,
427
+ `3. Go to http://localhost:4567/app to connect`,
428
+ `4. Check container: docker logs ar-${result.workspaceId.substring(0, 8)}`,
429
+ `5. Verify clone: docker exec ar-${result.workspaceId.substring(0, 8)} ls /workspace/repos`,
430
+ ],
431
+ });
432
+ }
433
+ catch (error) {
434
+ console.error('Error provisioning real workspace:', error);
435
+ res.status(500).json({
436
+ error: 'Failed to provision workspace',
437
+ details: error instanceof Error ? error.message : 'Unknown error',
438
+ });
439
+ }
440
+ });
441
+ /**
442
+ * GET /api/test/my-repos
443
+ * List current user's connected repositories (for debugging)
444
+ */
445
+ testHelpersRouter.get('/my-repos', async (req, res) => {
446
+ if (!isTestMode) {
447
+ return res.status(403).json({ error: 'Test endpoints disabled in production' });
448
+ }
449
+ const userId = req.session.userId;
450
+ if (!userId) {
451
+ return res.status(401).json({ error: 'Not logged in' });
452
+ }
453
+ try {
454
+ const repos = await db.repositories.findByUserId(userId);
455
+ res.json({
456
+ userId,
457
+ repositories: repos.map(r => ({
458
+ id: r.id,
459
+ fullName: r.githubFullName,
460
+ isPrivate: r.isPrivate,
461
+ hasNangoConnection: !!r.nangoConnectionId,
462
+ nangoConnectionId: r.nangoConnectionId, // For debugging
463
+ syncStatus: r.syncStatus,
464
+ })),
465
+ });
466
+ }
467
+ catch (error) {
468
+ console.error('Error fetching repos:', error);
469
+ res.status(500).json({ error: 'Failed to fetch repositories' });
470
+ }
471
+ });
472
+ /**
473
+ * GET /api/test/my-workspaces
474
+ * List current user's workspaces (for debugging)
475
+ */
476
+ testHelpersRouter.get('/my-workspaces', async (req, res) => {
477
+ if (!isTestMode) {
478
+ return res.status(403).json({ error: 'Test endpoints disabled in production' });
479
+ }
480
+ const userId = req.session.userId;
481
+ if (!userId) {
482
+ return res.status(401).json({ error: 'Not logged in' });
483
+ }
484
+ try {
485
+ const userWorkspaces = await db.workspaces.findByUserId(userId);
486
+ res.json({
487
+ userId,
488
+ workspaces: userWorkspaces.map(w => ({
489
+ id: w.id,
490
+ name: w.name,
491
+ status: w.status,
492
+ publicUrl: w.publicUrl,
493
+ computeProvider: w.computeProvider,
494
+ computeId: w.computeId,
495
+ config: w.config,
496
+ })),
497
+ });
498
+ }
499
+ catch (error) {
500
+ console.error('Error fetching workspaces:', error);
501
+ res.status(500).json({ error: 'Failed to fetch workspaces' });
502
+ }
503
+ });
504
+ /**
505
+ * GET /api/test/nango-token
506
+ * Test fetching GitHub App token from Nango (for debugging)
507
+ */
508
+ testHelpersRouter.get('/nango-token', async (req, res) => {
509
+ if (!isTestMode) {
510
+ return res.status(403).json({ error: 'Test endpoints disabled in production' });
511
+ }
512
+ const userId = req.session.userId;
513
+ if (!userId) {
514
+ return res.status(401).json({ error: 'Not logged in' });
515
+ }
516
+ try {
517
+ const repos = await db.repositories.findByUserId(userId);
518
+ const repoWithConnection = repos.find(r => r.nangoConnectionId);
519
+ if (!repoWithConnection?.nangoConnectionId) {
520
+ return res.status(400).json({
521
+ error: 'No Nango connection found',
522
+ repos: repos.map(r => ({ fullName: r.githubFullName, nangoConnectionId: r.nangoConnectionId })),
523
+ });
524
+ }
525
+ console.log('[test] Fetching token for connection:', repoWithConnection.nangoConnectionId);
526
+ const token = await nangoService.getGithubAppToken(repoWithConnection.nangoConnectionId);
527
+ res.json({
528
+ success: true,
529
+ connectionId: repoWithConnection.nangoConnectionId,
530
+ tokenLength: token.length,
531
+ tokenPrefix: token.substring(0, 10) + '...',
532
+ });
533
+ }
534
+ catch (error) {
535
+ console.error('[test] Nango token fetch error:', error);
536
+ res.status(500).json({
537
+ error: 'Failed to fetch token',
538
+ details: error instanceof Error ? error.message : 'Unknown error',
539
+ });
540
+ }
541
+ });
542
+ /**
543
+ * DELETE /api/test/workspace/:id
544
+ * Delete/deprovision a workspace (for cleanup)
545
+ */
546
+ testHelpersRouter.delete('/workspace/:id', async (req, res) => {
547
+ if (!isTestMode) {
548
+ return res.status(403).json({ error: 'Test endpoints disabled in production' });
549
+ }
550
+ const userId = req.session.userId;
551
+ if (!userId) {
552
+ return res.status(401).json({ error: 'Not logged in' });
553
+ }
554
+ try {
555
+ const { id } = req.params;
556
+ const workspace = await db.workspaces.findById(id);
557
+ if (!workspace) {
558
+ return res.status(404).json({ error: 'Workspace not found' });
559
+ }
560
+ if (workspace.userId !== userId) {
561
+ return res.status(403).json({ error: 'Not your workspace' });
562
+ }
563
+ const provisioner = getProvisioner();
564
+ await provisioner.deprovision(id);
565
+ res.json({
566
+ success: true,
567
+ message: `Workspace ${id} deleted`,
568
+ });
569
+ }
570
+ catch (error) {
571
+ console.error('Error deleting workspace:', error);
572
+ res.status(500).json({ error: 'Failed to delete workspace' });
573
+ }
574
+ });
575
+ //# sourceMappingURL=test-helpers.js.map
@@ -0,0 +1,8 @@
1
+ /**
2
+ * Webhook API Routes
3
+ *
4
+ * Handles GitHub App webhooks for installation events.
5
+ * Also provides workspace webhook forwarding for external integrations.
6
+ */
7
+ export declare const webhooksRouter: import("express-serve-static-core").Router;
8
+ //# sourceMappingURL=webhooks.d.ts.map