agent-relay 1.0.22 → 1.2.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 (613) hide show
  1. package/README.md +1 -1
  2. package/dist/bridge/shadow-cli.d.ts +17 -0
  3. package/dist/bridge/shadow-cli.d.ts.map +1 -0
  4. package/dist/bridge/shadow-cli.js +75 -0
  5. package/dist/bridge/shadow-cli.js.map +1 -0
  6. package/dist/bridge/shadow-config.d.ts +87 -0
  7. package/dist/bridge/shadow-config.d.ts.map +1 -0
  8. package/dist/bridge/shadow-config.js +134 -0
  9. package/dist/bridge/shadow-config.js.map +1 -0
  10. package/dist/bridge/spawner.d.ts +68 -1
  11. package/dist/bridge/spawner.d.ts.map +1 -1
  12. package/dist/bridge/spawner.js +360 -16
  13. package/dist/bridge/spawner.js.map +1 -1
  14. package/dist/bridge/types.d.ts +67 -0
  15. package/dist/bridge/types.d.ts.map +1 -1
  16. package/dist/cli/index.js +1196 -15
  17. package/dist/cli/index.js.map +1 -1
  18. package/dist/cloud/api/auth.d.ts +20 -0
  19. package/dist/cloud/api/auth.d.ts.map +1 -0
  20. package/dist/cloud/api/auth.js +128 -0
  21. package/dist/cloud/api/auth.js.map +1 -0
  22. package/dist/cloud/api/billing.d.ts +17 -0
  23. package/dist/cloud/api/billing.d.ts.map +1 -0
  24. package/dist/cloud/api/billing.js +353 -0
  25. package/dist/cloud/api/billing.js.map +1 -0
  26. package/dist/cloud/api/cli-pty-runner.d.ts +54 -0
  27. package/dist/cloud/api/cli-pty-runner.d.ts.map +1 -0
  28. package/dist/cloud/api/cli-pty-runner.js +119 -0
  29. package/dist/cloud/api/cli-pty-runner.js.map +1 -0
  30. package/dist/cloud/api/coordinators.d.ts +8 -0
  31. package/dist/cloud/api/coordinators.d.ts.map +1 -0
  32. package/dist/cloud/api/coordinators.js +347 -0
  33. package/dist/cloud/api/coordinators.js.map +1 -0
  34. package/dist/cloud/api/daemons.d.ts +12 -0
  35. package/dist/cloud/api/daemons.d.ts.map +1 -0
  36. package/dist/cloud/api/daemons.js +320 -0
  37. package/dist/cloud/api/daemons.js.map +1 -0
  38. package/dist/cloud/api/generic-webhooks.d.ts +8 -0
  39. package/dist/cloud/api/generic-webhooks.d.ts.map +1 -0
  40. package/dist/cloud/api/generic-webhooks.js +129 -0
  41. package/dist/cloud/api/generic-webhooks.js.map +1 -0
  42. package/dist/cloud/api/git.d.ts +8 -0
  43. package/dist/cloud/api/git.d.ts.map +1 -0
  44. package/dist/cloud/api/git.js +131 -0
  45. package/dist/cloud/api/git.js.map +1 -0
  46. package/dist/cloud/api/github-app.d.ts +11 -0
  47. package/dist/cloud/api/github-app.d.ts.map +1 -0
  48. package/dist/cloud/api/github-app.js +189 -0
  49. package/dist/cloud/api/github-app.js.map +1 -0
  50. package/dist/cloud/api/middleware/planLimits.d.ts +43 -0
  51. package/dist/cloud/api/middleware/planLimits.d.ts.map +1 -0
  52. package/dist/cloud/api/middleware/planLimits.js +202 -0
  53. package/dist/cloud/api/middleware/planLimits.js.map +1 -0
  54. package/dist/cloud/api/monitoring.d.ts +11 -0
  55. package/dist/cloud/api/monitoring.d.ts.map +1 -0
  56. package/dist/cloud/api/monitoring.js +578 -0
  57. package/dist/cloud/api/monitoring.js.map +1 -0
  58. package/dist/cloud/api/nango-auth.d.ts +9 -0
  59. package/dist/cloud/api/nango-auth.d.ts.map +1 -0
  60. package/dist/cloud/api/nango-auth.js +377 -0
  61. package/dist/cloud/api/nango-auth.js.map +1 -0
  62. package/dist/cloud/api/onboarding.d.ts +15 -0
  63. package/dist/cloud/api/onboarding.d.ts.map +1 -0
  64. package/dist/cloud/api/onboarding.js +588 -0
  65. package/dist/cloud/api/onboarding.js.map +1 -0
  66. package/dist/cloud/api/policy.d.ts +8 -0
  67. package/dist/cloud/api/policy.d.ts.map +1 -0
  68. package/dist/cloud/api/policy.js +229 -0
  69. package/dist/cloud/api/policy.js.map +1 -0
  70. package/dist/cloud/api/providers.d.ts +7 -0
  71. package/dist/cloud/api/providers.d.ts.map +1 -0
  72. package/dist/cloud/api/providers.js +507 -0
  73. package/dist/cloud/api/providers.js.map +1 -0
  74. package/dist/cloud/api/repos.d.ts +7 -0
  75. package/dist/cloud/api/repos.d.ts.map +1 -0
  76. package/dist/cloud/api/repos.js +314 -0
  77. package/dist/cloud/api/repos.js.map +1 -0
  78. package/dist/cloud/api/teams.d.ts +7 -0
  79. package/dist/cloud/api/teams.d.ts.map +1 -0
  80. package/dist/cloud/api/teams.js +279 -0
  81. package/dist/cloud/api/teams.js.map +1 -0
  82. package/dist/cloud/api/test-helpers.d.ts +10 -0
  83. package/dist/cloud/api/test-helpers.d.ts.map +1 -0
  84. package/dist/cloud/api/test-helpers.js +575 -0
  85. package/dist/cloud/api/test-helpers.js.map +1 -0
  86. package/dist/cloud/api/usage.d.ts +7 -0
  87. package/dist/cloud/api/usage.d.ts.map +1 -0
  88. package/dist/cloud/api/usage.js +98 -0
  89. package/dist/cloud/api/usage.js.map +1 -0
  90. package/dist/cloud/api/webhooks.d.ts +7 -0
  91. package/dist/cloud/api/webhooks.d.ts.map +1 -0
  92. package/dist/cloud/api/webhooks.js +496 -0
  93. package/dist/cloud/api/webhooks.js.map +1 -0
  94. package/dist/cloud/api/workspaces.d.ts +7 -0
  95. package/dist/cloud/api/workspaces.d.ts.map +1 -0
  96. package/dist/cloud/api/workspaces.js +727 -0
  97. package/dist/cloud/api/workspaces.js.map +1 -0
  98. package/dist/cloud/billing/index.d.ts +9 -0
  99. package/dist/cloud/billing/index.d.ts.map +1 -0
  100. package/dist/cloud/billing/index.js +9 -0
  101. package/dist/cloud/billing/index.js.map +1 -0
  102. package/dist/cloud/billing/plans.d.ts +39 -0
  103. package/dist/cloud/billing/plans.d.ts.map +1 -0
  104. package/dist/cloud/billing/plans.js +245 -0
  105. package/dist/cloud/billing/plans.js.map +1 -0
  106. package/dist/cloud/billing/service.d.ts +80 -0
  107. package/dist/cloud/billing/service.d.ts.map +1 -0
  108. package/dist/cloud/billing/service.js +388 -0
  109. package/dist/cloud/billing/service.js.map +1 -0
  110. package/dist/cloud/billing/types.d.ts +141 -0
  111. package/dist/cloud/billing/types.d.ts.map +1 -0
  112. package/dist/cloud/billing/types.js +7 -0
  113. package/dist/cloud/billing/types.js.map +1 -0
  114. package/dist/cloud/config.d.ts +66 -0
  115. package/dist/cloud/config.d.ts.map +1 -0
  116. package/dist/cloud/config.js +92 -0
  117. package/dist/cloud/config.js.map +1 -0
  118. package/dist/cloud/db/drizzle.d.ts +215 -0
  119. package/dist/cloud/db/drizzle.d.ts.map +1 -0
  120. package/dist/cloud/db/drizzle.js +1083 -0
  121. package/dist/cloud/db/drizzle.js.map +1 -0
  122. package/dist/cloud/db/index.d.ts +35 -0
  123. package/dist/cloud/db/index.d.ts.map +1 -0
  124. package/dist/cloud/db/index.js +52 -0
  125. package/dist/cloud/db/index.js.map +1 -0
  126. package/dist/cloud/db/schema.d.ts +4519 -0
  127. package/dist/cloud/db/schema.d.ts.map +1 -0
  128. package/dist/cloud/db/schema.js +547 -0
  129. package/dist/cloud/db/schema.js.map +1 -0
  130. package/dist/cloud/index.d.ts +12 -0
  131. package/dist/cloud/index.d.ts.map +1 -0
  132. package/dist/cloud/index.js +39 -0
  133. package/dist/cloud/index.js.map +1 -0
  134. package/dist/cloud/provisioner/index.d.ts +75 -0
  135. package/dist/cloud/provisioner/index.d.ts.map +1 -0
  136. package/dist/cloud/provisioner/index.js +977 -0
  137. package/dist/cloud/provisioner/index.js.map +1 -0
  138. package/dist/cloud/server.d.ts +17 -0
  139. package/dist/cloud/server.d.ts.map +1 -0
  140. package/dist/cloud/server.js +534 -0
  141. package/dist/cloud/server.js.map +1 -0
  142. package/dist/cloud/services/auto-scaler.d.ts +152 -0
  143. package/dist/cloud/services/auto-scaler.d.ts.map +1 -0
  144. package/dist/cloud/services/auto-scaler.js +439 -0
  145. package/dist/cloud/services/auto-scaler.js.map +1 -0
  146. package/dist/cloud/services/capacity-manager.d.ts +148 -0
  147. package/dist/cloud/services/capacity-manager.d.ts.map +1 -0
  148. package/dist/cloud/services/capacity-manager.js +449 -0
  149. package/dist/cloud/services/capacity-manager.js.map +1 -0
  150. package/dist/cloud/services/ci-agent-spawner.d.ts +49 -0
  151. package/dist/cloud/services/ci-agent-spawner.d.ts.map +1 -0
  152. package/dist/cloud/services/ci-agent-spawner.js +373 -0
  153. package/dist/cloud/services/ci-agent-spawner.js.map +1 -0
  154. package/dist/cloud/services/coordinator.d.ts +62 -0
  155. package/dist/cloud/services/coordinator.d.ts.map +1 -0
  156. package/dist/cloud/services/coordinator.js +389 -0
  157. package/dist/cloud/services/coordinator.js.map +1 -0
  158. package/dist/cloud/services/index.d.ts +12 -0
  159. package/dist/cloud/services/index.d.ts.map +1 -0
  160. package/dist/cloud/services/index.js +15 -0
  161. package/dist/cloud/services/index.js.map +1 -0
  162. package/dist/cloud/services/mention-handler.d.ts +65 -0
  163. package/dist/cloud/services/mention-handler.d.ts.map +1 -0
  164. package/dist/cloud/services/mention-handler.js +405 -0
  165. package/dist/cloud/services/mention-handler.js.map +1 -0
  166. package/dist/cloud/services/nango.d.ts +126 -0
  167. package/dist/cloud/services/nango.d.ts.map +1 -0
  168. package/dist/cloud/services/nango.js +191 -0
  169. package/dist/cloud/services/nango.js.map +1 -0
  170. package/dist/cloud/services/persistence.d.ts +131 -0
  171. package/dist/cloud/services/persistence.d.ts.map +1 -0
  172. package/dist/cloud/services/persistence.js +200 -0
  173. package/dist/cloud/services/persistence.js.map +1 -0
  174. package/dist/cloud/services/planLimits.d.ts +125 -0
  175. package/dist/cloud/services/planLimits.d.ts.map +1 -0
  176. package/dist/cloud/services/planLimits.js +282 -0
  177. package/dist/cloud/services/planLimits.js.map +1 -0
  178. package/dist/cloud/services/scaling-orchestrator.d.ts +159 -0
  179. package/dist/cloud/services/scaling-orchestrator.d.ts.map +1 -0
  180. package/dist/cloud/services/scaling-orchestrator.js +502 -0
  181. package/dist/cloud/services/scaling-orchestrator.js.map +1 -0
  182. package/dist/cloud/services/scaling-policy.d.ts +121 -0
  183. package/dist/cloud/services/scaling-policy.d.ts.map +1 -0
  184. package/dist/cloud/services/scaling-policy.js +415 -0
  185. package/dist/cloud/services/scaling-policy.js.map +1 -0
  186. package/dist/cloud/vault/index.d.ts +76 -0
  187. package/dist/cloud/vault/index.d.ts.map +1 -0
  188. package/dist/cloud/vault/index.js +219 -0
  189. package/dist/cloud/vault/index.js.map +1 -0
  190. package/dist/cloud/webhooks/index.d.ts +24 -0
  191. package/dist/cloud/webhooks/index.d.ts.map +1 -0
  192. package/dist/cloud/webhooks/index.js +29 -0
  193. package/dist/cloud/webhooks/index.js.map +1 -0
  194. package/dist/cloud/webhooks/parsers/github.d.ts +8 -0
  195. package/dist/cloud/webhooks/parsers/github.d.ts.map +1 -0
  196. package/dist/cloud/webhooks/parsers/github.js +234 -0
  197. package/dist/cloud/webhooks/parsers/github.js.map +1 -0
  198. package/dist/cloud/webhooks/parsers/index.d.ts +23 -0
  199. package/dist/cloud/webhooks/parsers/index.d.ts.map +1 -0
  200. package/dist/cloud/webhooks/parsers/index.js +30 -0
  201. package/dist/cloud/webhooks/parsers/index.js.map +1 -0
  202. package/dist/cloud/webhooks/parsers/linear.d.ts +9 -0
  203. package/dist/cloud/webhooks/parsers/linear.d.ts.map +1 -0
  204. package/dist/cloud/webhooks/parsers/linear.js +258 -0
  205. package/dist/cloud/webhooks/parsers/linear.js.map +1 -0
  206. package/dist/cloud/webhooks/parsers/slack.d.ts +9 -0
  207. package/dist/cloud/webhooks/parsers/slack.d.ts.map +1 -0
  208. package/dist/cloud/webhooks/parsers/slack.js +214 -0
  209. package/dist/cloud/webhooks/parsers/slack.js.map +1 -0
  210. package/dist/cloud/webhooks/responders/github.d.ts +8 -0
  211. package/dist/cloud/webhooks/responders/github.d.ts.map +1 -0
  212. package/dist/cloud/webhooks/responders/github.js +73 -0
  213. package/dist/cloud/webhooks/responders/github.js.map +1 -0
  214. package/dist/cloud/webhooks/responders/index.d.ts +23 -0
  215. package/dist/cloud/webhooks/responders/index.d.ts.map +1 -0
  216. package/dist/cloud/webhooks/responders/index.js +30 -0
  217. package/dist/cloud/webhooks/responders/index.js.map +1 -0
  218. package/dist/cloud/webhooks/responders/linear.d.ts +9 -0
  219. package/dist/cloud/webhooks/responders/linear.d.ts.map +1 -0
  220. package/dist/cloud/webhooks/responders/linear.js +149 -0
  221. package/dist/cloud/webhooks/responders/linear.js.map +1 -0
  222. package/dist/cloud/webhooks/responders/slack.d.ts +20 -0
  223. package/dist/cloud/webhooks/responders/slack.d.ts.map +1 -0
  224. package/dist/cloud/webhooks/responders/slack.js +178 -0
  225. package/dist/cloud/webhooks/responders/slack.js.map +1 -0
  226. package/dist/cloud/webhooks/router.d.ts +25 -0
  227. package/dist/cloud/webhooks/router.d.ts.map +1 -0
  228. package/dist/cloud/webhooks/router.js +504 -0
  229. package/dist/cloud/webhooks/router.js.map +1 -0
  230. package/dist/cloud/webhooks/rules-engine.d.ts +24 -0
  231. package/dist/cloud/webhooks/rules-engine.d.ts.map +1 -0
  232. package/dist/cloud/webhooks/rules-engine.js +287 -0
  233. package/dist/cloud/webhooks/rules-engine.js.map +1 -0
  234. package/dist/cloud/webhooks/types.d.ts +186 -0
  235. package/dist/cloud/webhooks/types.d.ts.map +1 -0
  236. package/dist/cloud/webhooks/types.js +8 -0
  237. package/dist/cloud/webhooks/types.js.map +1 -0
  238. package/dist/continuity/formatter.d.ts +51 -0
  239. package/dist/continuity/formatter.d.ts.map +1 -0
  240. package/dist/continuity/formatter.js +313 -0
  241. package/dist/continuity/formatter.js.map +1 -0
  242. package/dist/continuity/handoff-store.d.ts +67 -0
  243. package/dist/continuity/handoff-store.d.ts.map +1 -0
  244. package/dist/continuity/handoff-store.js +472 -0
  245. package/dist/continuity/handoff-store.js.map +1 -0
  246. package/dist/continuity/index.d.ts +45 -0
  247. package/dist/continuity/index.d.ts.map +1 -0
  248. package/dist/continuity/index.js +48 -0
  249. package/dist/continuity/index.js.map +1 -0
  250. package/dist/continuity/ledger-store.d.ts +110 -0
  251. package/dist/continuity/ledger-store.d.ts.map +1 -0
  252. package/dist/continuity/ledger-store.js +500 -0
  253. package/dist/continuity/ledger-store.js.map +1 -0
  254. package/dist/continuity/manager.d.ts +178 -0
  255. package/dist/continuity/manager.d.ts.map +1 -0
  256. package/dist/continuity/manager.js +562 -0
  257. package/dist/continuity/manager.js.map +1 -0
  258. package/dist/continuity/parser.d.ts +76 -0
  259. package/dist/continuity/parser.d.ts.map +1 -0
  260. package/dist/continuity/parser.js +579 -0
  261. package/dist/continuity/parser.js.map +1 -0
  262. package/dist/continuity/types.d.ts +180 -0
  263. package/dist/continuity/types.d.ts.map +1 -0
  264. package/dist/continuity/types.js +9 -0
  265. package/dist/continuity/types.js.map +1 -0
  266. package/dist/daemon/agent-manager.d.ts +114 -0
  267. package/dist/daemon/agent-manager.d.ts.map +1 -0
  268. package/dist/daemon/agent-manager.js +513 -0
  269. package/dist/daemon/agent-manager.js.map +1 -0
  270. package/dist/daemon/agent-registry.d.ts +34 -0
  271. package/dist/daemon/agent-registry.d.ts.map +1 -1
  272. package/dist/daemon/agent-registry.js +45 -2
  273. package/dist/daemon/agent-registry.js.map +1 -1
  274. package/dist/daemon/api.d.ts +81 -0
  275. package/dist/daemon/api.d.ts.map +1 -0
  276. package/dist/daemon/api.js +554 -0
  277. package/dist/daemon/api.js.map +1 -0
  278. package/dist/daemon/cli-auth.d.ts +67 -0
  279. package/dist/daemon/cli-auth.d.ts.map +1 -0
  280. package/dist/daemon/cli-auth.js +537 -0
  281. package/dist/daemon/cli-auth.js.map +1 -0
  282. package/dist/daemon/cloud-sync.d.ts +101 -0
  283. package/dist/daemon/cloud-sync.d.ts.map +1 -0
  284. package/dist/daemon/cloud-sync.js +263 -0
  285. package/dist/daemon/cloud-sync.js.map +1 -0
  286. package/dist/daemon/index.d.ts +4 -0
  287. package/dist/daemon/index.d.ts.map +1 -1
  288. package/dist/daemon/index.js +6 -0
  289. package/dist/daemon/index.js.map +1 -1
  290. package/dist/daemon/orchestrator.d.ts +155 -0
  291. package/dist/daemon/orchestrator.d.ts.map +1 -0
  292. package/dist/daemon/orchestrator.js +766 -0
  293. package/dist/daemon/orchestrator.js.map +1 -0
  294. package/dist/daemon/router.d.ts +29 -0
  295. package/dist/daemon/router.d.ts.map +1 -1
  296. package/dist/daemon/router.js +143 -21
  297. package/dist/daemon/router.js.map +1 -1
  298. package/dist/daemon/server.d.ts +42 -0
  299. package/dist/daemon/server.d.ts.map +1 -1
  300. package/dist/daemon/server.js +199 -16
  301. package/dist/daemon/server.js.map +1 -1
  302. package/dist/daemon/services/browser-testing.d.ts +88 -0
  303. package/dist/daemon/services/browser-testing.d.ts.map +1 -0
  304. package/dist/daemon/services/browser-testing.js +244 -0
  305. package/dist/daemon/services/browser-testing.js.map +1 -0
  306. package/dist/daemon/services/container-spawner.d.ts +135 -0
  307. package/dist/daemon/services/container-spawner.d.ts.map +1 -0
  308. package/dist/daemon/services/container-spawner.js +313 -0
  309. package/dist/daemon/services/container-spawner.js.map +1 -0
  310. package/dist/daemon/types.d.ts +131 -0
  311. package/dist/daemon/types.d.ts.map +1 -0
  312. package/dist/daemon/types.js +6 -0
  313. package/dist/daemon/types.js.map +1 -0
  314. package/dist/daemon/workspace-manager.d.ts +75 -0
  315. package/dist/daemon/workspace-manager.d.ts.map +1 -0
  316. package/dist/daemon/workspace-manager.js +289 -0
  317. package/dist/daemon/workspace-manager.js.map +1 -0
  318. package/dist/dashboard/out/404.html +1 -1
  319. package/dist/dashboard/out/_next/static/chunks/116-2502180def231162.js +1 -0
  320. package/dist/dashboard/out/_next/static/chunks/282-980c2eb8fff20123.js +1 -0
  321. package/dist/dashboard/out/_next/static/chunks/480-2d4111711d4e473c.js +1 -0
  322. package/dist/dashboard/out/_next/static/chunks/724-73c1ee5f60abe860.js +9 -0
  323. package/dist/dashboard/out/_next/static/chunks/766-c3a14283c88d815b.js +1 -0
  324. package/dist/dashboard/out/_next/static/chunks/app/app/page-7120be68bea622f3.js +1 -0
  325. package/dist/dashboard/out/_next/static/chunks/app/connect-repos/page-dc2e3a1a22478efc.js +1 -0
  326. package/dist/dashboard/out/_next/static/chunks/app/history/page-56a8b4616a90dc43.js +1 -0
  327. package/dist/dashboard/out/_next/static/chunks/app/layout-2433bb48965f4333.js +1 -0
  328. package/dist/dashboard/out/_next/static/chunks/app/login/page-3eac37ea6f5dd153.js +1 -0
  329. package/dist/dashboard/out/_next/static/chunks/app/metrics/page-1081dd190a331a91.js +1 -0
  330. package/dist/dashboard/out/_next/static/chunks/app/page-daf87e86f783f980.js +1 -0
  331. package/dist/dashboard/out/_next/static/chunks/app/pricing/page-4d72d5a5d8a9b618.js +1 -0
  332. package/dist/dashboard/out/_next/static/chunks/app/providers/page-b68a681526eb145e.js +1 -0
  333. package/dist/dashboard/out/_next/static/chunks/app/signup/page-fee4ed1709070bcd.js +1 -0
  334. package/dist/dashboard/out/_next/static/chunks/e868780c-48e5f147c90a3a41.js +18 -0
  335. package/dist/dashboard/out/_next/static/chunks/{main-e0a1f53fe0617a63.js → main-97850e03d723ea8c.js} +1 -1
  336. package/dist/dashboard/out/_next/static/chunks/main-app-5d692157a8eb1fd9.js +1 -0
  337. package/dist/dashboard/out/_next/static/chunks/webpack-1cdd8ed57114d5e1.js +1 -0
  338. package/dist/dashboard/out/_next/static/css/29852f26181969a0.css +1 -0
  339. package/dist/dashboard/out/_next/static/css/411ce23ffeae9f76.css +1 -0
  340. package/dist/dashboard/out/alt-logos/agent-relay-logo-128.png +0 -0
  341. package/dist/dashboard/out/alt-logos/agent-relay-logo-256.png +0 -0
  342. package/dist/dashboard/out/alt-logos/agent-relay-logo-32.png +0 -0
  343. package/dist/dashboard/out/alt-logos/agent-relay-logo-512.png +0 -0
  344. package/dist/dashboard/out/alt-logos/agent-relay-logo-64.png +0 -0
  345. package/dist/dashboard/out/alt-logos/agent-relay-logo.svg +45 -0
  346. package/dist/dashboard/out/alt-logos/logo.svg +38 -0
  347. package/dist/dashboard/out/alt-logos/monogram-logo-128.png +0 -0
  348. package/dist/dashboard/out/alt-logos/monogram-logo-256.png +0 -0
  349. package/dist/dashboard/out/alt-logos/monogram-logo-32.png +0 -0
  350. package/dist/dashboard/out/alt-logos/monogram-logo-512.png +0 -0
  351. package/dist/dashboard/out/alt-logos/monogram-logo-64.png +0 -0
  352. package/dist/dashboard/out/alt-logos/monogram-logo.svg +38 -0
  353. package/dist/dashboard/out/app.html +1 -0
  354. package/dist/dashboard/out/app.txt +7 -0
  355. package/dist/dashboard/out/connect-repos.html +1 -0
  356. package/dist/dashboard/out/connect-repos.txt +7 -0
  357. package/dist/dashboard/out/history.html +1 -0
  358. package/dist/dashboard/out/history.txt +7 -0
  359. package/dist/dashboard/out/index.html +1 -1
  360. package/dist/dashboard/out/index.txt +2 -2
  361. package/dist/dashboard/out/login.html +6 -0
  362. package/dist/dashboard/out/login.txt +7 -0
  363. package/dist/dashboard/out/metrics.html +1 -515
  364. package/dist/dashboard/out/metrics.txt +2 -2
  365. package/dist/dashboard/out/pricing.html +13 -0
  366. package/dist/dashboard/out/pricing.txt +7 -0
  367. package/dist/dashboard/out/providers.html +1 -0
  368. package/dist/dashboard/out/providers.txt +7 -0
  369. package/dist/dashboard/out/signup.html +6 -0
  370. package/dist/dashboard/out/signup.txt +7 -0
  371. package/dist/dashboard-server/metrics.d.ts.map +1 -1
  372. package/dist/dashboard-server/metrics.js +3 -2
  373. package/dist/dashboard-server/metrics.js.map +1 -1
  374. package/dist/dashboard-server/server.d.ts.map +1 -1
  375. package/dist/dashboard-server/server.js +2653 -130
  376. package/dist/dashboard-server/server.js.map +1 -1
  377. package/dist/hooks/emitter.d.ts +40 -0
  378. package/dist/hooks/emitter.d.ts.map +1 -0
  379. package/dist/hooks/emitter.js +63 -0
  380. package/dist/hooks/emitter.js.map +1 -0
  381. package/dist/hooks/index.d.ts +3 -0
  382. package/dist/hooks/index.d.ts.map +1 -1
  383. package/dist/hooks/index.js +3 -0
  384. package/dist/hooks/index.js.map +1 -1
  385. package/dist/hooks/registry.d.ts +173 -0
  386. package/dist/hooks/registry.d.ts.map +1 -0
  387. package/dist/hooks/registry.js +476 -0
  388. package/dist/hooks/registry.js.map +1 -0
  389. package/dist/hooks/trajectory-hooks.d.ts +52 -0
  390. package/dist/hooks/trajectory-hooks.d.ts.map +1 -0
  391. package/dist/hooks/trajectory-hooks.js +183 -0
  392. package/dist/hooks/trajectory-hooks.js.map +1 -0
  393. package/dist/hooks/types.d.ts +141 -0
  394. package/dist/hooks/types.d.ts.map +1 -1
  395. package/dist/index.d.ts +2 -0
  396. package/dist/index.d.ts.map +1 -1
  397. package/dist/index.js +3 -0
  398. package/dist/index.js.map +1 -1
  399. package/dist/memory/adapters/index.d.ts +8 -0
  400. package/dist/memory/adapters/index.d.ts.map +1 -0
  401. package/dist/memory/adapters/index.js +8 -0
  402. package/dist/memory/adapters/index.js.map +1 -0
  403. package/dist/memory/adapters/inmemory.d.ts +59 -0
  404. package/dist/memory/adapters/inmemory.d.ts.map +1 -0
  405. package/dist/memory/adapters/inmemory.js +195 -0
  406. package/dist/memory/adapters/inmemory.js.map +1 -0
  407. package/dist/memory/adapters/supermemory.d.ts +71 -0
  408. package/dist/memory/adapters/supermemory.d.ts.map +1 -0
  409. package/dist/memory/adapters/supermemory.js +338 -0
  410. package/dist/memory/adapters/supermemory.js.map +1 -0
  411. package/dist/memory/factory.d.ts +48 -0
  412. package/dist/memory/factory.d.ts.map +1 -0
  413. package/dist/memory/factory.js +143 -0
  414. package/dist/memory/factory.js.map +1 -0
  415. package/dist/memory/index.d.ts +32 -0
  416. package/dist/memory/index.d.ts.map +1 -0
  417. package/dist/memory/index.js +32 -0
  418. package/dist/memory/index.js.map +1 -0
  419. package/dist/memory/memory-hooks.d.ts +60 -0
  420. package/dist/memory/memory-hooks.d.ts.map +1 -0
  421. package/dist/memory/memory-hooks.js +313 -0
  422. package/dist/memory/memory-hooks.js.map +1 -0
  423. package/dist/memory/service.d.ts +49 -0
  424. package/dist/memory/service.d.ts.map +1 -0
  425. package/dist/memory/service.js +146 -0
  426. package/dist/memory/service.js.map +1 -0
  427. package/dist/memory/types.d.ts +195 -0
  428. package/dist/memory/types.d.ts.map +1 -0
  429. package/dist/memory/types.js +8 -0
  430. package/dist/memory/types.js.map +1 -0
  431. package/dist/policy/agent-policy.d.ts +225 -0
  432. package/dist/policy/agent-policy.d.ts.map +1 -0
  433. package/dist/policy/agent-policy.js +665 -0
  434. package/dist/policy/agent-policy.js.map +1 -0
  435. package/dist/policy/cloud-policy-fetcher.d.ts +12 -0
  436. package/dist/policy/cloud-policy-fetcher.d.ts.map +1 -0
  437. package/dist/policy/cloud-policy-fetcher.js +64 -0
  438. package/dist/policy/cloud-policy-fetcher.js.map +1 -0
  439. package/dist/protocol/types.d.ts +10 -1
  440. package/dist/protocol/types.d.ts.map +1 -1
  441. package/dist/resiliency/context-persistence.d.ts +140 -0
  442. package/dist/resiliency/context-persistence.d.ts.map +1 -0
  443. package/dist/resiliency/context-persistence.js +397 -0
  444. package/dist/resiliency/context-persistence.js.map +1 -0
  445. package/dist/resiliency/crash-insights.d.ts +156 -0
  446. package/dist/resiliency/crash-insights.d.ts.map +1 -0
  447. package/dist/resiliency/crash-insights.js +492 -0
  448. package/dist/resiliency/crash-insights.js.map +1 -0
  449. package/dist/resiliency/gossip-health.d.ts +137 -0
  450. package/dist/resiliency/gossip-health.d.ts.map +1 -0
  451. package/dist/resiliency/gossip-health.js +241 -0
  452. package/dist/resiliency/gossip-health.js.map +1 -0
  453. package/dist/resiliency/health-monitor.d.ts +97 -0
  454. package/dist/resiliency/health-monitor.d.ts.map +1 -0
  455. package/dist/resiliency/health-monitor.js +291 -0
  456. package/dist/resiliency/health-monitor.js.map +1 -0
  457. package/dist/resiliency/index.d.ts +68 -0
  458. package/dist/resiliency/index.d.ts.map +1 -0
  459. package/dist/resiliency/index.js +68 -0
  460. package/dist/resiliency/index.js.map +1 -0
  461. package/dist/resiliency/leader-watchdog.d.ts +109 -0
  462. package/dist/resiliency/leader-watchdog.d.ts.map +1 -0
  463. package/dist/resiliency/leader-watchdog.js +189 -0
  464. package/dist/resiliency/leader-watchdog.js.map +1 -0
  465. package/dist/resiliency/logger.d.ts +114 -0
  466. package/dist/resiliency/logger.d.ts.map +1 -0
  467. package/dist/resiliency/logger.js +250 -0
  468. package/dist/resiliency/logger.js.map +1 -0
  469. package/dist/resiliency/memory-monitor.d.ts +172 -0
  470. package/dist/resiliency/memory-monitor.d.ts.map +1 -0
  471. package/dist/resiliency/memory-monitor.js +593 -0
  472. package/dist/resiliency/memory-monitor.js.map +1 -0
  473. package/dist/resiliency/metrics.d.ts +115 -0
  474. package/dist/resiliency/metrics.d.ts.map +1 -0
  475. package/dist/resiliency/metrics.js +239 -0
  476. package/dist/resiliency/metrics.js.map +1 -0
  477. package/dist/resiliency/provider-context.d.ts +100 -0
  478. package/dist/resiliency/provider-context.d.ts.map +1 -0
  479. package/dist/resiliency/provider-context.js +360 -0
  480. package/dist/resiliency/provider-context.js.map +1 -0
  481. package/dist/resiliency/stateless-lead.d.ts +149 -0
  482. package/dist/resiliency/stateless-lead.d.ts.map +1 -0
  483. package/dist/resiliency/stateless-lead.js +308 -0
  484. package/dist/resiliency/stateless-lead.js.map +1 -0
  485. package/dist/resiliency/supervisor.d.ts +147 -0
  486. package/dist/resiliency/supervisor.d.ts.map +1 -0
  487. package/dist/resiliency/supervisor.js +459 -0
  488. package/dist/resiliency/supervisor.js.map +1 -0
  489. package/dist/shared/cli-auth-config.d.ts +91 -0
  490. package/dist/shared/cli-auth-config.d.ts.map +1 -0
  491. package/dist/shared/cli-auth-config.js +264 -0
  492. package/dist/shared/cli-auth-config.js.map +1 -0
  493. package/dist/storage/adapter.d.ts +3 -1
  494. package/dist/storage/adapter.d.ts.map +1 -1
  495. package/dist/storage/adapter.js +12 -2
  496. package/dist/storage/adapter.js.map +1 -1
  497. package/dist/storage/sqlite-adapter.d.ts.map +1 -1
  498. package/dist/storage/sqlite-adapter.js +18 -14
  499. package/dist/storage/sqlite-adapter.js.map +1 -1
  500. package/dist/trajectory/config.d.ts +84 -0
  501. package/dist/trajectory/config.d.ts.map +1 -0
  502. package/dist/trajectory/config.js +163 -0
  503. package/dist/trajectory/config.js.map +1 -0
  504. package/dist/trajectory/index.d.ts +8 -0
  505. package/dist/trajectory/index.d.ts.map +1 -0
  506. package/dist/trajectory/index.js +8 -0
  507. package/dist/trajectory/index.js.map +1 -0
  508. package/dist/trajectory/integration.d.ts +292 -0
  509. package/dist/trajectory/integration.d.ts.map +1 -0
  510. package/dist/trajectory/integration.js +834 -0
  511. package/dist/trajectory/integration.js.map +1 -0
  512. package/dist/utils/index.d.ts +1 -0
  513. package/dist/utils/index.d.ts.map +1 -1
  514. package/dist/utils/index.js +1 -0
  515. package/dist/utils/index.js.map +1 -1
  516. package/dist/utils/logger.d.ts +40 -0
  517. package/dist/utils/logger.d.ts.map +1 -0
  518. package/dist/utils/logger.js +84 -0
  519. package/dist/utils/logger.js.map +1 -0
  520. package/dist/utils/project-namespace.d.ts +24 -0
  521. package/dist/utils/project-namespace.d.ts.map +1 -1
  522. package/dist/utils/project-namespace.js +84 -0
  523. package/dist/utils/project-namespace.js.map +1 -1
  524. package/dist/wrapper/client.d.ts +16 -1
  525. package/dist/wrapper/client.d.ts.map +1 -1
  526. package/dist/wrapper/client.js +32 -1
  527. package/dist/wrapper/client.js.map +1 -1
  528. package/dist/wrapper/parser.d.ts +13 -0
  529. package/dist/wrapper/parser.d.ts.map +1 -1
  530. package/dist/wrapper/parser.js +217 -47
  531. package/dist/wrapper/parser.js.map +1 -1
  532. package/dist/wrapper/pty-wrapper.d.ts +219 -17
  533. package/dist/wrapper/pty-wrapper.d.ts.map +1 -1
  534. package/dist/wrapper/pty-wrapper.js +1050 -104
  535. package/dist/wrapper/pty-wrapper.js.map +1 -1
  536. package/dist/wrapper/shared.d.ts +165 -0
  537. package/dist/wrapper/shared.d.ts.map +1 -0
  538. package/dist/wrapper/shared.js +270 -0
  539. package/dist/wrapper/shared.js.map +1 -0
  540. package/dist/wrapper/tmux-wrapper.d.ts +78 -11
  541. package/dist/wrapper/tmux-wrapper.d.ts.map +1 -1
  542. package/dist/wrapper/tmux-wrapper.js +567 -106
  543. package/dist/wrapper/tmux-wrapper.js.map +1 -1
  544. package/docs/CLOUD-ARCHITECTURE.md +804 -0
  545. package/docs/CLOUD-ONBOARDING-DESIGN.md +1983 -0
  546. package/docs/HOOKS_API.md +394 -0
  547. package/docs/WRAPPER_EVENTS.md +358 -0
  548. package/docs/agent-policy-snippet.md +40 -0
  549. package/docs/agent-relay-protocol.md +238 -0
  550. package/docs/agent-relay-snippet.md +115 -6
  551. package/docs/archive/EXECUTIVE_SUMMARY.md +358 -0
  552. package/docs/archive/ROADMAP.md +329 -0
  553. package/docs/archive/TESTING_PRESENCE_FEATURES.md +327 -0
  554. package/docs/competitive/GASTOWN.md +451 -0
  555. package/docs/{COMPETITIVE_ANALYSIS.md → competitive/OVERVIEW.md} +1 -0
  556. package/docs/competitive/README.md +34 -0
  557. package/docs/competitive/TMUX_ORCHESTRATOR.md +605 -0
  558. package/docs/dashboard.png +0 -0
  559. package/docs/design/ci-failure-webhooks.md +812 -0
  560. package/docs/design/comprehensive-integrations.md +238 -0
  561. package/docs/design/e2b-sandbox-integration.md +504 -0
  562. package/docs/design/github-app-permissions.md +264 -0
  563. package/docs/guides/CLOUD.md +236 -0
  564. package/docs/guides/LOCAL.md +535 -0
  565. package/docs/guides/SELF-HOSTED.md +494 -0
  566. package/docs/local-testing.md +428 -0
  567. package/docs/proposals/continuous-claude-integration.md +622 -0
  568. package/docs/proposals/custom-commands.md +368 -0
  569. package/docs/proposals/shadow-as-subagent.md +765 -0
  570. package/docs/proposals/slack-bot-integration.md +1457 -0
  571. package/docs/tasks/global-skills-system.tasks.md +230 -0
  572. package/docs/tasks/webhook-integrations.tasks.md +184 -0
  573. package/docs/tasks/workspace-capabilities.tasks.md +121 -0
  574. package/docs/testing/RESILIENCY-TEST-PLAN-2026-01-01.md +366 -0
  575. package/package.json +45 -7
  576. package/scripts/cloud-setup.sh +96 -0
  577. package/scripts/manual-qa.sh +293 -0
  578. package/scripts/postinstall.js +60 -0
  579. package/scripts/run-cloud-qa.sh +220 -0
  580. package/scripts/test-cli-auth/Dockerfile +44 -0
  581. package/scripts/test-cli-auth/Dockerfile.real +79 -0
  582. package/scripts/test-cli-auth/README.md +286 -0
  583. package/scripts/test-cli-auth/ci-test-real-clis.ts +251 -0
  584. package/scripts/test-cli-auth/ci-test-runner.ts +263 -0
  585. package/scripts/test-cli-auth/mock-cli.sh +147 -0
  586. package/scripts/test-cli-auth/package.json +14 -0
  587. package/scripts/test-cli-auth/test-oauth-flow.ts +220 -0
  588. package/scripts/test-pty-input-auto.js +222 -0
  589. package/scripts/test-pty-input.js +150 -0
  590. package/dist/dashboard/out/_next/static/chunks/app/layout-c9d8c5d95e48c6bf.js +0 -1
  591. package/dist/dashboard/out/_next/static/chunks/app/metrics/page-8aa9936bc6c771ab.js +0 -1
  592. package/dist/dashboard/out/_next/static/chunks/app/page-4498be09a5157759.js +0 -1
  593. package/dist/dashboard/out/_next/static/chunks/main-app-bae2e535de00de50.js +0 -1
  594. package/dist/dashboard/out/_next/static/chunks/webpack-c81f7fd28659d64f.js +0 -1
  595. package/dist/dashboard/out/_next/static/css/50ed6996e3df7bdd.css +0 -1
  596. /package/dist/dashboard/out/_next/static/{DXFA-jj8wb3PcY5DX2xcU → H5aWG0udPB4iOUIl_gytz}/_buildManifest.js +0 -0
  597. /package/dist/dashboard/out/_next/static/{DXFA-jj8wb3PcY5DX2xcU → H5aWG0udPB4iOUIl_gytz}/_ssgManifest.js +0 -0
  598. /package/dist/dashboard/out/_next/static/chunks/{117-3bef7b19f3e60751.js → 117-b100311aff8d5c61.js} +0 -0
  599. /package/dist/dashboard/out/_next/static/chunks/{648-6cf686106c891ad3.js → 648-a13d3c2b1be45466.js} +0 -0
  600. /package/dist/dashboard/out/_next/static/chunks/app/_not-found/{page-8ff6572bc7c9bc61.js → page-a4973f3e3c82fb67.js} +0 -0
  601. /package/dist/dashboard/out/_next/static/chunks/{fd9d1056-26bd8d656b496dba.js → fd9d1056-bf46c09eb57e019c.js} +0 -0
  602. /package/docs/{CHANGELOG.md → archive/CHANGELOG.md} +0 -0
  603. /package/docs/{CLI-SIMPLIFICATION-COMPLETE.md → archive/CLI-SIMPLIFICATION-COMPLETE.md} +0 -0
  604. /package/docs/{DESIGN_BRIDGE_STAFFING.md → archive/DESIGN_BRIDGE_STAFFING.md} +0 -0
  605. /package/docs/{DESIGN_V2.md → archive/DESIGN_V2.md} +0 -0
  606. /package/docs/{MONETIZATION.md → archive/MONETIZATION.md} +0 -0
  607. /package/docs/{PROPOSAL-trajectories.md → archive/PROPOSAL-trajectories.md} +0 -0
  608. /package/docs/{SCALING_ANALYSIS.md → archive/SCALING_ANALYSIS.md} +0 -0
  609. /package/docs/{TMUX_IMPLEMENTATION_NOTES.md → archive/TMUX_IMPLEMENTATION_NOTES.md} +0 -0
  610. /package/docs/{TMUX_IMPROVEMENTS.md → archive/TMUX_IMPROVEMENTS.md} +0 -0
  611. /package/docs/{dashboard-v2-plan.md → archive/dashboard-v2-plan.md} +0 -0
  612. /package/docs/{removable-code-analysis.md → archive/removable-code-analysis.md} +0 -0
  613. /package/docs/{competitive-analysis-mcp-agent-mail.md → competitive/MCP_AGENT_MAIL.md} +0 -0
@@ -0,0 +1,727 @@
1
+ /**
2
+ * Workspaces API Routes
3
+ *
4
+ * One-click workspace provisioning and management.
5
+ */
6
+ import { Router } from 'express';
7
+ import { requireAuth } from './auth.js';
8
+ import { db } from '../db/index.js';
9
+ import { getProvisioner } from '../provisioner/index.js';
10
+ import { checkWorkspaceLimit } from './middleware/planLimits.js';
11
+ export const workspacesRouter = Router();
12
+ // All routes require authentication
13
+ workspacesRouter.use(requireAuth);
14
+ /**
15
+ * GET /api/workspaces
16
+ * List user's workspaces
17
+ */
18
+ workspacesRouter.get('/', async (req, res) => {
19
+ const userId = req.session.userId;
20
+ try {
21
+ const workspaces = await db.workspaces.findByUserId(userId);
22
+ res.json({
23
+ workspaces: workspaces.map((w) => ({
24
+ id: w.id,
25
+ name: w.name,
26
+ status: w.status,
27
+ publicUrl: w.publicUrl,
28
+ providers: w.config.providers,
29
+ repositories: w.config.repositories,
30
+ createdAt: w.createdAt,
31
+ })),
32
+ });
33
+ }
34
+ catch (error) {
35
+ console.error('Error listing workspaces:', error);
36
+ res.status(500).json({ error: 'Failed to list workspaces' });
37
+ }
38
+ });
39
+ /**
40
+ * POST /api/workspaces
41
+ * Create (provision) a new workspace
42
+ */
43
+ workspacesRouter.post('/', checkWorkspaceLimit, async (req, res) => {
44
+ const userId = req.session.userId;
45
+ const { name, providers, repositories, supervisorEnabled, maxAgents } = req.body;
46
+ // Validation
47
+ if (!name || typeof name !== 'string') {
48
+ return res.status(400).json({ error: 'Name is required' });
49
+ }
50
+ if (!providers || !Array.isArray(providers) || providers.length === 0) {
51
+ return res.status(400).json({ error: 'At least one provider is required' });
52
+ }
53
+ if (!repositories || !Array.isArray(repositories)) {
54
+ return res.status(400).json({ error: 'Repositories array is required' });
55
+ }
56
+ // Verify user has credentials for all providers
57
+ const credentials = await db.credentials.findByUserId(userId);
58
+ const connectedProviders = new Set(credentials.map((c) => c.provider));
59
+ for (const provider of providers) {
60
+ if (!connectedProviders.has(provider)) {
61
+ return res.status(400).json({
62
+ error: `Provider ${provider} not connected. Please connect it first.`,
63
+ });
64
+ }
65
+ }
66
+ try {
67
+ const provisioner = getProvisioner();
68
+ const result = await provisioner.provision({
69
+ userId,
70
+ name,
71
+ providers,
72
+ repositories,
73
+ supervisorEnabled,
74
+ maxAgents,
75
+ });
76
+ if (result.status === 'error') {
77
+ return res.status(500).json({
78
+ error: 'Failed to provision workspace',
79
+ details: result.error,
80
+ });
81
+ }
82
+ res.status(201).json({
83
+ workspaceId: result.workspaceId,
84
+ status: result.status,
85
+ publicUrl: result.publicUrl,
86
+ });
87
+ }
88
+ catch (error) {
89
+ console.error('Error creating workspace:', error);
90
+ res.status(500).json({ error: 'Failed to create workspace' });
91
+ }
92
+ });
93
+ /**
94
+ * GET /api/workspaces/summary
95
+ * Get summary of all user workspaces for dashboard status indicator
96
+ * NOTE: This route MUST be before /:id to avoid being caught by parameterized route
97
+ */
98
+ workspacesRouter.get('/summary', async (req, res) => {
99
+ const userId = req.session.userId;
100
+ try {
101
+ const workspaces = await db.workspaces.findByUserId(userId);
102
+ const provisioner = getProvisioner();
103
+ // Get live status for each workspace
104
+ const workspaceSummaries = await Promise.all(workspaces.map(async (w) => {
105
+ let liveStatus = w.status;
106
+ try {
107
+ liveStatus = await provisioner.getStatus(w.id);
108
+ }
109
+ catch {
110
+ // Fall back to DB status
111
+ }
112
+ return {
113
+ id: w.id,
114
+ name: w.name,
115
+ status: liveStatus,
116
+ publicUrl: w.publicUrl,
117
+ isStopped: liveStatus === 'stopped',
118
+ isRunning: liveStatus === 'running',
119
+ isProvisioning: liveStatus === 'provisioning',
120
+ hasError: liveStatus === 'error',
121
+ };
122
+ }));
123
+ // Overall status for quick dashboard indicator
124
+ const hasRunningWorkspace = workspaceSummaries.some(w => w.isRunning);
125
+ const hasStoppedWorkspace = workspaceSummaries.some(w => w.isStopped);
126
+ const hasProvisioningWorkspace = workspaceSummaries.some(w => w.isProvisioning);
127
+ res.json({
128
+ workspaces: workspaceSummaries,
129
+ summary: {
130
+ total: workspaceSummaries.length,
131
+ running: workspaceSummaries.filter(w => w.isRunning).length,
132
+ stopped: workspaceSummaries.filter(w => w.isStopped).length,
133
+ provisioning: workspaceSummaries.filter(w => w.isProvisioning).length,
134
+ error: workspaceSummaries.filter(w => w.hasError).length,
135
+ },
136
+ overallStatus: hasRunningWorkspace
137
+ ? 'ready'
138
+ : hasProvisioningWorkspace
139
+ ? 'provisioning'
140
+ : hasStoppedWorkspace
141
+ ? 'stopped'
142
+ : workspaceSummaries.length === 0
143
+ ? 'none'
144
+ : 'error',
145
+ });
146
+ }
147
+ catch (error) {
148
+ console.error('Error getting workspace summary:', error);
149
+ res.status(500).json({ error: 'Failed to get workspace summary' });
150
+ }
151
+ });
152
+ /**
153
+ * GET /api/workspaces/primary
154
+ * Get the user's primary workspace (first/default) with live status
155
+ * Used by dashboard to show quick status indicator
156
+ * NOTE: This route MUST be before /:id to avoid being caught by parameterized route
157
+ */
158
+ workspacesRouter.get('/primary', async (req, res) => {
159
+ const userId = req.session.userId;
160
+ try {
161
+ const workspaces = await db.workspaces.findByUserId(userId);
162
+ if (workspaces.length === 0) {
163
+ return res.json({
164
+ exists: false,
165
+ message: 'No workspace found. Connect a repository to auto-provision one.',
166
+ });
167
+ }
168
+ const primary = workspaces[0];
169
+ const provisioner = getProvisioner();
170
+ let liveStatus = primary.status;
171
+ try {
172
+ liveStatus = await provisioner.getStatus(primary.id);
173
+ }
174
+ catch {
175
+ // Fall back to DB status
176
+ }
177
+ res.json({
178
+ exists: true,
179
+ workspace: {
180
+ id: primary.id,
181
+ name: primary.name,
182
+ status: liveStatus,
183
+ publicUrl: primary.publicUrl,
184
+ isStopped: liveStatus === 'stopped',
185
+ isRunning: liveStatus === 'running',
186
+ isProvisioning: liveStatus === 'provisioning',
187
+ hasError: liveStatus === 'error',
188
+ config: {
189
+ providers: primary.config.providers || [],
190
+ repositories: primary.config.repositories || [],
191
+ },
192
+ },
193
+ // Quick messages for UI
194
+ statusMessage: liveStatus === 'running'
195
+ ? 'Workspace is running'
196
+ : liveStatus === 'stopped'
197
+ ? 'Workspace is idle (will start automatically when needed)'
198
+ : liveStatus === 'provisioning'
199
+ ? 'Workspace is being provisioned...'
200
+ : 'Workspace has an error',
201
+ actionNeeded: liveStatus === 'stopped'
202
+ ? 'wakeup'
203
+ : liveStatus === 'error'
204
+ ? 'check_error'
205
+ : null,
206
+ });
207
+ }
208
+ catch (error) {
209
+ console.error('Error getting primary workspace:', error);
210
+ res.status(500).json({ error: 'Failed to get primary workspace' });
211
+ }
212
+ });
213
+ /**
214
+ * GET /api/workspaces/:id
215
+ * Get workspace details
216
+ */
217
+ workspacesRouter.get('/:id', async (req, res) => {
218
+ const userId = req.session.userId;
219
+ const { id } = req.params;
220
+ try {
221
+ const workspace = await db.workspaces.findById(id);
222
+ if (!workspace) {
223
+ return res.status(404).json({ error: 'Workspace not found' });
224
+ }
225
+ if (workspace.userId !== userId) {
226
+ return res.status(403).json({ error: 'Unauthorized' });
227
+ }
228
+ // Get repositories assigned to this workspace
229
+ const repositories = await db.repositories.findByWorkspaceId(id);
230
+ res.json({
231
+ id: workspace.id,
232
+ name: workspace.name,
233
+ status: workspace.status,
234
+ publicUrl: workspace.publicUrl,
235
+ computeProvider: workspace.computeProvider,
236
+ config: workspace.config,
237
+ errorMessage: workspace.errorMessage,
238
+ repositories: repositories.map((r) => ({
239
+ id: r.id,
240
+ fullName: r.githubFullName,
241
+ syncStatus: r.syncStatus,
242
+ lastSyncedAt: r.lastSyncedAt,
243
+ })),
244
+ createdAt: workspace.createdAt,
245
+ updatedAt: workspace.updatedAt,
246
+ });
247
+ }
248
+ catch (error) {
249
+ console.error('Error getting workspace:', error);
250
+ res.status(500).json({ error: 'Failed to get workspace' });
251
+ }
252
+ });
253
+ /**
254
+ * GET /api/workspaces/:id/status
255
+ * Get current workspace status (polls compute provider)
256
+ */
257
+ workspacesRouter.get('/:id/status', async (req, res) => {
258
+ const userId = req.session.userId;
259
+ const { id } = req.params;
260
+ try {
261
+ const workspace = await db.workspaces.findById(id);
262
+ if (!workspace) {
263
+ return res.status(404).json({ error: 'Workspace not found' });
264
+ }
265
+ if (workspace.userId !== userId) {
266
+ return res.status(403).json({ error: 'Unauthorized' });
267
+ }
268
+ const provisioner = getProvisioner();
269
+ const status = await provisioner.getStatus(id);
270
+ res.json({ status });
271
+ }
272
+ catch (error) {
273
+ console.error('Error getting workspace status:', error);
274
+ res.status(500).json({ error: 'Failed to get status' });
275
+ }
276
+ });
277
+ /**
278
+ * POST /api/workspaces/:id/restart
279
+ * Restart a workspace
280
+ */
281
+ workspacesRouter.post('/:id/restart', async (req, res) => {
282
+ const userId = req.session.userId;
283
+ const { id } = req.params;
284
+ try {
285
+ const workspace = await db.workspaces.findById(id);
286
+ if (!workspace) {
287
+ return res.status(404).json({ error: 'Workspace not found' });
288
+ }
289
+ if (workspace.userId !== userId) {
290
+ return res.status(403).json({ error: 'Unauthorized' });
291
+ }
292
+ const provisioner = getProvisioner();
293
+ await provisioner.restart(id);
294
+ res.json({ success: true, message: 'Workspace restarting' });
295
+ }
296
+ catch (error) {
297
+ console.error('Error restarting workspace:', error);
298
+ res.status(500).json({ error: 'Failed to restart workspace' });
299
+ }
300
+ });
301
+ /**
302
+ * POST /api/workspaces/:id/stop
303
+ * Stop a workspace
304
+ */
305
+ workspacesRouter.post('/:id/stop', async (req, res) => {
306
+ const userId = req.session.userId;
307
+ const { id } = req.params;
308
+ try {
309
+ const workspace = await db.workspaces.findById(id);
310
+ if (!workspace) {
311
+ return res.status(404).json({ error: 'Workspace not found' });
312
+ }
313
+ if (workspace.userId !== userId) {
314
+ return res.status(403).json({ error: 'Unauthorized' });
315
+ }
316
+ const provisioner = getProvisioner();
317
+ await provisioner.stop(id);
318
+ res.json({ success: true, message: 'Workspace stopped' });
319
+ }
320
+ catch (error) {
321
+ console.error('Error stopping workspace:', error);
322
+ res.status(500).json({ error: 'Failed to stop workspace' });
323
+ }
324
+ });
325
+ /**
326
+ * DELETE /api/workspaces/:id
327
+ * Delete (deprovision) a workspace
328
+ */
329
+ workspacesRouter.delete('/:id', async (req, res) => {
330
+ const userId = req.session.userId;
331
+ const { id } = req.params;
332
+ try {
333
+ const workspace = await db.workspaces.findById(id);
334
+ if (!workspace) {
335
+ return res.status(404).json({ error: 'Workspace not found' });
336
+ }
337
+ if (workspace.userId !== userId) {
338
+ return res.status(403).json({ error: 'Unauthorized' });
339
+ }
340
+ const provisioner = getProvisioner();
341
+ await provisioner.deprovision(id);
342
+ res.json({ success: true, message: 'Workspace deleted' });
343
+ }
344
+ catch (error) {
345
+ console.error('Error deleting workspace:', error);
346
+ res.status(500).json({ error: 'Failed to delete workspace' });
347
+ }
348
+ });
349
+ /**
350
+ * POST /api/workspaces/:id/repos
351
+ * Add repositories to a workspace
352
+ */
353
+ workspacesRouter.post('/:id/repos', async (req, res) => {
354
+ const userId = req.session.userId;
355
+ const { id } = req.params;
356
+ const { repositoryIds } = req.body;
357
+ if (!repositoryIds || !Array.isArray(repositoryIds)) {
358
+ return res.status(400).json({ error: 'repositoryIds array is required' });
359
+ }
360
+ try {
361
+ const workspace = await db.workspaces.findById(id);
362
+ if (!workspace) {
363
+ return res.status(404).json({ error: 'Workspace not found' });
364
+ }
365
+ if (workspace.userId !== userId) {
366
+ return res.status(403).json({ error: 'Unauthorized' });
367
+ }
368
+ // Assign repositories to workspace
369
+ for (const repoId of repositoryIds) {
370
+ await db.repositories.assignToWorkspace(repoId, id);
371
+ }
372
+ res.json({ success: true, message: 'Repositories added' });
373
+ }
374
+ catch (error) {
375
+ console.error('Error adding repos to workspace:', error);
376
+ res.status(500).json({ error: 'Failed to add repositories' });
377
+ }
378
+ });
379
+ /**
380
+ * POST /api/workspaces/:id/domain
381
+ * Add or update custom domain (Premium feature - Team/Enterprise only)
382
+ */
383
+ workspacesRouter.post('/:id/domain', async (req, res) => {
384
+ const userId = req.session.userId;
385
+ const { id } = req.params;
386
+ const { domain } = req.body;
387
+ if (!domain || typeof domain !== 'string') {
388
+ return res.status(400).json({ error: 'Domain is required' });
389
+ }
390
+ // Basic domain validation
391
+ const domainRegex = /^(?:[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?\.)+[a-zA-Z]{2,}$/;
392
+ if (!domainRegex.test(domain)) {
393
+ return res.status(400).json({ error: 'Invalid domain format' });
394
+ }
395
+ try {
396
+ const workspace = await db.workspaces.findById(id);
397
+ if (!workspace) {
398
+ return res.status(404).json({ error: 'Workspace not found' });
399
+ }
400
+ if (workspace.userId !== userId) {
401
+ return res.status(403).json({ error: 'Unauthorized' });
402
+ }
403
+ // Check if user has premium plan (Team/Enterprise)
404
+ const user = await db.users.findById(userId);
405
+ const hasPremium = user?.plan === 'team' || user?.plan === 'enterprise';
406
+ if (!hasPremium) {
407
+ return res.status(402).json({
408
+ error: 'Custom domains require Team or Enterprise plan',
409
+ upgrade: '/settings/billing',
410
+ });
411
+ }
412
+ // Check if domain is already in use
413
+ const existing = await db.workspaces.findByCustomDomain(domain);
414
+ if (existing && existing.id !== id) {
415
+ return res.status(409).json({ error: 'Domain already in use' });
416
+ }
417
+ // Set the custom domain (pending verification)
418
+ await db.workspaces.setCustomDomain(id, domain, 'pending');
419
+ // Return DNS instructions
420
+ res.json({
421
+ success: true,
422
+ domain,
423
+ status: 'pending',
424
+ instructions: {
425
+ type: 'CNAME',
426
+ name: domain,
427
+ value: workspace.publicUrl?.replace('https://', '') || `${id}.agentrelay.dev`,
428
+ ttl: 300,
429
+ },
430
+ verifyEndpoint: `/api/workspaces/${id}/domain/verify`,
431
+ message: 'Add the CNAME record to your DNS, then call the verify endpoint',
432
+ });
433
+ }
434
+ catch (error) {
435
+ console.error('Error setting custom domain:', error);
436
+ res.status(500).json({ error: 'Failed to set custom domain' });
437
+ }
438
+ });
439
+ /**
440
+ * POST /api/workspaces/:id/domain/verify
441
+ * Verify custom domain DNS is configured correctly
442
+ */
443
+ workspacesRouter.post('/:id/domain/verify', async (req, res) => {
444
+ const userId = req.session.userId;
445
+ const { id } = req.params;
446
+ try {
447
+ const workspace = await db.workspaces.findById(id);
448
+ if (!workspace) {
449
+ return res.status(404).json({ error: 'Workspace not found' });
450
+ }
451
+ if (workspace.userId !== userId) {
452
+ return res.status(403).json({ error: 'Unauthorized' });
453
+ }
454
+ if (!workspace.customDomain) {
455
+ return res.status(400).json({ error: 'No custom domain configured' });
456
+ }
457
+ // Verify DNS resolution
458
+ const dns = await import('dns').then(m => m.promises);
459
+ try {
460
+ const records = await dns.resolveCname(workspace.customDomain);
461
+ const expectedTarget = workspace.publicUrl?.replace('https://', '') || `${id}.agentrelay.dev`;
462
+ if (records.some(r => r.includes(expectedTarget) || r.includes('agentrelay'))) {
463
+ // DNS is configured, now provision SSL cert
464
+ await db.workspaces.updateCustomDomainStatus(id, 'verifying');
465
+ // Trigger SSL cert provisioning on compute provider
466
+ // For Railway/Fly, this is automatic once domain is added
467
+ await provisionDomainSSL(workspace);
468
+ await db.workspaces.updateCustomDomainStatus(id, 'active');
469
+ res.json({
470
+ success: true,
471
+ status: 'active',
472
+ domain: workspace.customDomain,
473
+ message: 'Custom domain verified and SSL certificate provisioned',
474
+ });
475
+ }
476
+ else {
477
+ res.status(400).json({
478
+ success: false,
479
+ status: 'pending',
480
+ error: 'DNS not configured correctly',
481
+ expected: expectedTarget,
482
+ found: records,
483
+ });
484
+ }
485
+ }
486
+ catch (_dnsError) {
487
+ res.status(400).json({
488
+ success: false,
489
+ status: 'pending',
490
+ error: 'Could not resolve domain. DNS may not be configured yet.',
491
+ });
492
+ }
493
+ }
494
+ catch (error) {
495
+ console.error('Error verifying domain:', error);
496
+ res.status(500).json({ error: 'Failed to verify domain' });
497
+ }
498
+ });
499
+ /**
500
+ * DELETE /api/workspaces/:id/domain
501
+ * Remove custom domain
502
+ */
503
+ workspacesRouter.delete('/:id/domain', async (req, res) => {
504
+ const userId = req.session.userId;
505
+ const { id } = req.params;
506
+ try {
507
+ const workspace = await db.workspaces.findById(id);
508
+ if (!workspace) {
509
+ return res.status(404).json({ error: 'Workspace not found' });
510
+ }
511
+ if (workspace.userId !== userId) {
512
+ return res.status(403).json({ error: 'Unauthorized' });
513
+ }
514
+ // Remove from compute provider
515
+ if (workspace.customDomain) {
516
+ await removeDomainFromCompute(workspace);
517
+ }
518
+ await db.workspaces.removeCustomDomain(id);
519
+ res.json({ success: true, message: 'Custom domain removed' });
520
+ }
521
+ catch (error) {
522
+ console.error('Error removing domain:', error);
523
+ res.status(500).json({ error: 'Failed to remove domain' });
524
+ }
525
+ });
526
+ /**
527
+ * Helper: Provision SSL for custom domain on compute provider
528
+ */
529
+ async function provisionDomainSSL(workspace) {
530
+ const config = (await import('../config.js')).getConfig();
531
+ if (workspace.computeProvider === 'fly' && config.compute.fly) {
532
+ // Fly.io: Add certificate
533
+ await fetch(`https://api.machines.dev/v1/apps/ar-${workspace.id.substring(0, 8)}/certificates`, {
534
+ method: 'POST',
535
+ headers: {
536
+ Authorization: `Bearer ${config.compute.fly.apiToken}`,
537
+ 'Content-Type': 'application/json',
538
+ },
539
+ body: JSON.stringify({ hostname: workspace.customDomain }),
540
+ });
541
+ }
542
+ else if (workspace.computeProvider === 'railway' && config.compute.railway) {
543
+ // Railway: Add custom domain via GraphQL
544
+ await fetch('https://backboard.railway.app/graphql/v2', {
545
+ method: 'POST',
546
+ headers: {
547
+ Authorization: `Bearer ${config.compute.railway.apiToken}`,
548
+ 'Content-Type': 'application/json',
549
+ },
550
+ body: JSON.stringify({
551
+ query: `
552
+ mutation AddCustomDomain($input: CustomDomainCreateInput!) {
553
+ customDomainCreate(input: $input) { id }
554
+ }
555
+ `,
556
+ variables: {
557
+ input: {
558
+ projectId: workspace.computeId,
559
+ domain: workspace.customDomain,
560
+ },
561
+ },
562
+ }),
563
+ });
564
+ }
565
+ // Docker: Would need reverse proxy config (Caddy/nginx)
566
+ }
567
+ /**
568
+ * Helper: Remove custom domain from compute provider
569
+ */
570
+ async function removeDomainFromCompute(workspace) {
571
+ const config = (await import('../config.js')).getConfig();
572
+ if (workspace.computeProvider === 'fly' && config.compute.fly) {
573
+ await fetch(`https://api.machines.dev/v1/apps/ar-${workspace.id.substring(0, 8)}/certificates/${workspace.customDomain}`, {
574
+ method: 'DELETE',
575
+ headers: { Authorization: `Bearer ${config.compute.fly.apiToken}` },
576
+ });
577
+ }
578
+ // Railway and Docker: similar cleanup
579
+ }
580
+ /**
581
+ * POST /api/workspaces/:id/proxy/*
582
+ * Proxy API requests to the workspace container
583
+ * This allows the dashboard to make REST calls through the cloud server
584
+ */
585
+ workspacesRouter.all('/:id/proxy/{*proxyPath}', async (req, res) => {
586
+ const userId = req.session.userId;
587
+ const { id } = req.params;
588
+ // Express 5 wildcard params return an array of path segments, not a slash-separated string
589
+ const proxyPathParam = req.params.proxyPath;
590
+ const proxyPath = Array.isArray(proxyPathParam) ? proxyPathParam.join('/') : proxyPathParam;
591
+ try {
592
+ const workspace = await db.workspaces.findById(id);
593
+ if (!workspace) {
594
+ return res.status(404).json({ error: 'Workspace not found' });
595
+ }
596
+ if (workspace.userId !== userId) {
597
+ return res.status(403).json({ error: 'Unauthorized' });
598
+ }
599
+ if (workspace.status !== 'running' || !workspace.publicUrl) {
600
+ return res.status(400).json({ error: 'Workspace is not running' });
601
+ }
602
+ // Determine the internal URL for proxying
603
+ // When running inside Docker, localhost URLs won't work - use the container name instead
604
+ let targetBaseUrl = workspace.publicUrl;
605
+ const runningInDocker = process.env.RUNNING_IN_DOCKER === 'true';
606
+ if (runningInDocker && workspace.computeId && targetBaseUrl.includes('localhost')) {
607
+ // Replace localhost URL with container name for Docker networking
608
+ // workspace.computeId is the container name (e.g., "ar-abc12345")
609
+ // The workspace port is 3888 inside the container
610
+ targetBaseUrl = `http://${workspace.computeId}:3888`;
611
+ }
612
+ const targetUrl = `${targetBaseUrl}/api/${proxyPath}`;
613
+ console.log(`[workspace-proxy] ${req.method} ${targetUrl}`);
614
+ // Store targetUrl for error handling
615
+ req._proxyTargetUrl = targetUrl;
616
+ // Add timeout to prevent hanging requests
617
+ const controller = new AbortController();
618
+ const timeout = setTimeout(() => controller.abort(), 15000); // 15s timeout
619
+ const fetchOptions = {
620
+ method: req.method,
621
+ headers: {
622
+ 'Content-Type': 'application/json',
623
+ },
624
+ signal: controller.signal,
625
+ };
626
+ if (req.method !== 'GET' && req.method !== 'HEAD') {
627
+ fetchOptions.body = JSON.stringify(req.body);
628
+ }
629
+ let proxyRes;
630
+ try {
631
+ proxyRes = await fetch(targetUrl, fetchOptions);
632
+ }
633
+ finally {
634
+ clearTimeout(timeout);
635
+ }
636
+ console.log(`[workspace-proxy] Response: ${proxyRes.status} ${proxyRes.statusText}`);
637
+ // Handle non-JSON responses gracefully
638
+ const contentType = proxyRes.headers.get('content-type');
639
+ if (contentType?.includes('application/json')) {
640
+ const data = await proxyRes.json();
641
+ res.status(proxyRes.status).json(data);
642
+ }
643
+ else {
644
+ const text = await proxyRes.text();
645
+ res.status(proxyRes.status).send(text);
646
+ }
647
+ }
648
+ catch (error) {
649
+ const targetUrl = req._proxyTargetUrl || 'unknown';
650
+ console.error('[workspace-proxy] Error proxying to:', targetUrl);
651
+ console.error('[workspace-proxy] Error details:', error);
652
+ // Check for timeout/abort errors
653
+ if (error instanceof Error && error.name === 'AbortError') {
654
+ res.status(504).json({
655
+ error: 'Workspace request timed out',
656
+ details: 'The workspace did not respond within 15 seconds',
657
+ targetUrl: targetUrl,
658
+ });
659
+ return;
660
+ }
661
+ // Check for connection refused (workspace not running)
662
+ const errorMessage = error instanceof Error ? error.message : 'Unknown error';
663
+ if (errorMessage.includes('ECONNREFUSED') || errorMessage.includes('fetch failed')) {
664
+ res.status(503).json({
665
+ error: 'Workspace is not reachable',
666
+ details: 'The workspace container may not be running or accepting connections',
667
+ targetUrl: targetUrl,
668
+ });
669
+ return;
670
+ }
671
+ res.status(500).json({
672
+ error: 'Failed to proxy request to workspace',
673
+ details: errorMessage,
674
+ targetUrl: targetUrl, // Include target URL for debugging
675
+ });
676
+ }
677
+ });
678
+ /**
679
+ * POST /api/workspaces/quick
680
+ * Quick provision: one-click with defaults
681
+ * Providers are optional - can be connected after workspace creation via CLI login
682
+ */
683
+ workspacesRouter.post('/quick', checkWorkspaceLimit, async (req, res) => {
684
+ const userId = req.session.userId;
685
+ const { name, repositoryFullName } = req.body;
686
+ if (!repositoryFullName) {
687
+ return res.status(400).json({ error: 'Repository name is required' });
688
+ }
689
+ try {
690
+ // Get user's connected providers (optional now)
691
+ const credentials = await db.credentials.findByUserId(userId);
692
+ const providers = credentials
693
+ .filter((c) => c.provider !== 'github')
694
+ .map((c) => c.provider);
695
+ // Create workspace with defaults
696
+ const provisioner = getProvisioner();
697
+ const workspaceName = name || `Workspace for ${repositoryFullName}`;
698
+ const result = await provisioner.provision({
699
+ userId,
700
+ name: workspaceName,
701
+ providers: providers.length > 0 ? providers : [], // Empty is OK now
702
+ repositories: [repositoryFullName],
703
+ supervisorEnabled: true,
704
+ maxAgents: 10,
705
+ });
706
+ if (result.status === 'error') {
707
+ return res.status(500).json({
708
+ error: 'Failed to provision workspace',
709
+ details: result.error,
710
+ });
711
+ }
712
+ res.status(201).json({
713
+ workspaceId: result.workspaceId,
714
+ status: result.status,
715
+ publicUrl: result.publicUrl,
716
+ providersConnected: providers.length > 0,
717
+ message: providers.length > 0
718
+ ? 'Workspace provisioned successfully!'
719
+ : 'Workspace provisioned! Connect an AI provider to start using agents.',
720
+ });
721
+ }
722
+ catch (error) {
723
+ console.error('Error quick provisioning:', error);
724
+ res.status(500).json({ error: 'Failed to provision workspace' });
725
+ }
726
+ });
727
+ //# sourceMappingURL=workspaces.js.map