agent-relay 1.0.21 → 1.1.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 (283) hide show
  1. package/dist/bridge/shadow-cli.d.ts +17 -0
  2. package/dist/bridge/shadow-cli.d.ts.map +1 -0
  3. package/dist/bridge/shadow-cli.js +75 -0
  4. package/dist/bridge/shadow-cli.js.map +1 -0
  5. package/dist/bridge/shadow-config.d.ts +87 -0
  6. package/dist/bridge/shadow-config.d.ts.map +1 -0
  7. package/dist/bridge/shadow-config.js +134 -0
  8. package/dist/bridge/shadow-config.js.map +1 -0
  9. package/dist/bridge/spawner.d.ts +15 -1
  10. package/dist/bridge/spawner.d.ts.map +1 -1
  11. package/dist/bridge/spawner.js +164 -4
  12. package/dist/bridge/spawner.js.map +1 -1
  13. package/dist/bridge/types.d.ts +55 -0
  14. package/dist/bridge/types.d.ts.map +1 -1
  15. package/dist/cli/index.js +796 -11
  16. package/dist/cli/index.js.map +1 -1
  17. package/dist/cloud/api/auth.d.ts +19 -0
  18. package/dist/cloud/api/auth.d.ts.map +1 -0
  19. package/dist/cloud/api/auth.js +216 -0
  20. package/dist/cloud/api/auth.js.map +1 -0
  21. package/dist/cloud/api/billing.d.ts +17 -0
  22. package/dist/cloud/api/billing.d.ts.map +1 -0
  23. package/dist/cloud/api/billing.js +353 -0
  24. package/dist/cloud/api/billing.js.map +1 -0
  25. package/dist/cloud/api/coordinators.d.ts +8 -0
  26. package/dist/cloud/api/coordinators.d.ts.map +1 -0
  27. package/dist/cloud/api/coordinators.js +347 -0
  28. package/dist/cloud/api/coordinators.js.map +1 -0
  29. package/dist/cloud/api/daemons.d.ts +12 -0
  30. package/dist/cloud/api/daemons.d.ts.map +1 -0
  31. package/dist/cloud/api/daemons.js +320 -0
  32. package/dist/cloud/api/daemons.js.map +1 -0
  33. package/dist/cloud/api/middleware/planLimits.d.ts +36 -0
  34. package/dist/cloud/api/middleware/planLimits.d.ts.map +1 -0
  35. package/dist/cloud/api/middleware/planLimits.js +164 -0
  36. package/dist/cloud/api/middleware/planLimits.js.map +1 -0
  37. package/dist/cloud/api/onboarding.d.ts +8 -0
  38. package/dist/cloud/api/onboarding.d.ts.map +1 -0
  39. package/dist/cloud/api/onboarding.js +407 -0
  40. package/dist/cloud/api/onboarding.js.map +1 -0
  41. package/dist/cloud/api/providers.d.ts +7 -0
  42. package/dist/cloud/api/providers.d.ts.map +1 -0
  43. package/dist/cloud/api/providers.js +435 -0
  44. package/dist/cloud/api/providers.js.map +1 -0
  45. package/dist/cloud/api/repos.d.ts +7 -0
  46. package/dist/cloud/api/repos.d.ts.map +1 -0
  47. package/dist/cloud/api/repos.js +314 -0
  48. package/dist/cloud/api/repos.js.map +1 -0
  49. package/dist/cloud/api/teams.d.ts +7 -0
  50. package/dist/cloud/api/teams.d.ts.map +1 -0
  51. package/dist/cloud/api/teams.js +279 -0
  52. package/dist/cloud/api/teams.js.map +1 -0
  53. package/dist/cloud/api/usage.d.ts +7 -0
  54. package/dist/cloud/api/usage.d.ts.map +1 -0
  55. package/dist/cloud/api/usage.js +98 -0
  56. package/dist/cloud/api/usage.js.map +1 -0
  57. package/dist/cloud/api/workspaces.d.ts +7 -0
  58. package/dist/cloud/api/workspaces.d.ts.map +1 -0
  59. package/dist/cloud/api/workspaces.js +510 -0
  60. package/dist/cloud/api/workspaces.js.map +1 -0
  61. package/dist/cloud/billing/index.d.ts +9 -0
  62. package/dist/cloud/billing/index.d.ts.map +1 -0
  63. package/dist/cloud/billing/index.js +9 -0
  64. package/dist/cloud/billing/index.js.map +1 -0
  65. package/dist/cloud/billing/plans.d.ts +39 -0
  66. package/dist/cloud/billing/plans.d.ts.map +1 -0
  67. package/dist/cloud/billing/plans.js +232 -0
  68. package/dist/cloud/billing/plans.js.map +1 -0
  69. package/dist/cloud/billing/service.d.ts +80 -0
  70. package/dist/cloud/billing/service.d.ts.map +1 -0
  71. package/dist/cloud/billing/service.js +388 -0
  72. package/dist/cloud/billing/service.js.map +1 -0
  73. package/dist/cloud/billing/types.d.ts +135 -0
  74. package/dist/cloud/billing/types.d.ts.map +1 -0
  75. package/dist/cloud/billing/types.js +7 -0
  76. package/dist/cloud/billing/types.js.map +1 -0
  77. package/dist/cloud/config.d.ts +59 -0
  78. package/dist/cloud/config.d.ts.map +1 -0
  79. package/dist/cloud/config.js +83 -0
  80. package/dist/cloud/config.js.map +1 -0
  81. package/dist/cloud/db/drizzle.d.ts +132 -0
  82. package/dist/cloud/db/drizzle.d.ts.map +1 -0
  83. package/dist/cloud/db/drizzle.js +613 -0
  84. package/dist/cloud/db/drizzle.js.map +1 -0
  85. package/dist/cloud/db/index.d.ts +30 -0
  86. package/dist/cloud/db/index.d.ts.map +1 -0
  87. package/dist/cloud/db/index.js +44 -0
  88. package/dist/cloud/db/index.js.map +1 -0
  89. package/dist/cloud/db/schema.d.ts +1792 -0
  90. package/dist/cloud/db/schema.d.ts.map +1 -0
  91. package/dist/cloud/db/schema.js +234 -0
  92. package/dist/cloud/db/schema.js.map +1 -0
  93. package/dist/cloud/index.d.ts +11 -0
  94. package/dist/cloud/index.d.ts.map +1 -0
  95. package/dist/cloud/index.js +37 -0
  96. package/dist/cloud/index.js.map +1 -0
  97. package/dist/cloud/provisioner/index.d.ts +51 -0
  98. package/dist/cloud/provisioner/index.d.ts.map +1 -0
  99. package/dist/cloud/provisioner/index.js +676 -0
  100. package/dist/cloud/provisioner/index.js.map +1 -0
  101. package/dist/cloud/server.d.ts +16 -0
  102. package/dist/cloud/server.d.ts.map +1 -0
  103. package/dist/cloud/server.js +190 -0
  104. package/dist/cloud/server.js.map +1 -0
  105. package/dist/cloud/services/coordinator.d.ts +62 -0
  106. package/dist/cloud/services/coordinator.d.ts.map +1 -0
  107. package/dist/cloud/services/coordinator.js +389 -0
  108. package/dist/cloud/services/coordinator.js.map +1 -0
  109. package/dist/cloud/services/planLimits.d.ts +110 -0
  110. package/dist/cloud/services/planLimits.d.ts.map +1 -0
  111. package/dist/cloud/services/planLimits.js +254 -0
  112. package/dist/cloud/services/planLimits.js.map +1 -0
  113. package/dist/cloud/vault/index.d.ts +76 -0
  114. package/dist/cloud/vault/index.d.ts.map +1 -0
  115. package/dist/cloud/vault/index.js +219 -0
  116. package/dist/cloud/vault/index.js.map +1 -0
  117. package/dist/daemon/agent-manager.d.ts +87 -0
  118. package/dist/daemon/agent-manager.d.ts.map +1 -0
  119. package/dist/daemon/agent-manager.js +412 -0
  120. package/dist/daemon/agent-manager.js.map +1 -0
  121. package/dist/daemon/agent-registry.d.ts +2 -0
  122. package/dist/daemon/agent-registry.d.ts.map +1 -1
  123. package/dist/daemon/agent-registry.js +3 -0
  124. package/dist/daemon/agent-registry.js.map +1 -1
  125. package/dist/daemon/api.d.ts +69 -0
  126. package/dist/daemon/api.d.ts.map +1 -0
  127. package/dist/daemon/api.js +425 -0
  128. package/dist/daemon/api.js.map +1 -0
  129. package/dist/daemon/cloud-sync.d.ts +101 -0
  130. package/dist/daemon/cloud-sync.d.ts.map +1 -0
  131. package/dist/daemon/cloud-sync.js +261 -0
  132. package/dist/daemon/cloud-sync.js.map +1 -0
  133. package/dist/daemon/index.d.ts +4 -0
  134. package/dist/daemon/index.d.ts.map +1 -1
  135. package/dist/daemon/index.js +6 -0
  136. package/dist/daemon/index.js.map +1 -1
  137. package/dist/daemon/orchestrator.d.ts +155 -0
  138. package/dist/daemon/orchestrator.d.ts.map +1 -0
  139. package/dist/daemon/orchestrator.js +736 -0
  140. package/dist/daemon/orchestrator.js.map +1 -0
  141. package/dist/daemon/router.d.ts +24 -0
  142. package/dist/daemon/router.d.ts.map +1 -1
  143. package/dist/daemon/router.js +71 -1
  144. package/dist/daemon/router.js.map +1 -1
  145. package/dist/daemon/server.d.ts +37 -0
  146. package/dist/daemon/server.d.ts.map +1 -1
  147. package/dist/daemon/server.js +191 -16
  148. package/dist/daemon/server.js.map +1 -1
  149. package/dist/daemon/types.d.ts +127 -0
  150. package/dist/daemon/types.d.ts.map +1 -0
  151. package/dist/daemon/types.js +6 -0
  152. package/dist/daemon/types.js.map +1 -0
  153. package/dist/daemon/workspace-manager.d.ts +75 -0
  154. package/dist/daemon/workspace-manager.d.ts.map +1 -0
  155. package/dist/daemon/workspace-manager.js +289 -0
  156. package/dist/daemon/workspace-manager.js.map +1 -0
  157. package/dist/dashboard/out/404.html +1 -1
  158. package/dist/dashboard/out/_next/static/chunks/693-7b3301d8f6bc5014.js +1 -0
  159. package/dist/dashboard/out/_next/static/chunks/713-f78477eb185f1f4d.js +1 -0
  160. package/dist/dashboard/out/_next/static/chunks/766-e53e1cfe39b0b5b5.js +1 -0
  161. package/dist/dashboard/out/_next/static/chunks/900-037c64bfd797fb2a.js +1 -0
  162. package/dist/dashboard/out/_next/static/chunks/app/app/page-e3d9e1f4466b9bae.js +1 -0
  163. package/dist/dashboard/out/_next/static/chunks/app/history/page-b6edd4dde8d08194.js +1 -0
  164. package/dist/dashboard/out/_next/static/chunks/app/layout-2433bb48965f4333.js +1 -0
  165. package/dist/dashboard/out/_next/static/chunks/app/metrics/page-e68825a81db67ba1.js +1 -0
  166. package/dist/dashboard/out/_next/static/chunks/app/page-cc108bf68c8a657f.js +1 -0
  167. package/dist/dashboard/out/_next/static/chunks/app/pricing/page-d80e03a5297f95b6.js +1 -0
  168. package/dist/dashboard/out/_next/static/chunks/main-app-5d692157a8eb1fd9.js +1 -0
  169. package/dist/dashboard/out/_next/static/chunks/{main-e0a1f53fe0617a63.js → main-c2f423b9c9f4591b.js} +1 -1
  170. package/dist/dashboard/out/_next/static/chunks/{webpack-c81f7fd28659d64f.js → webpack-a5acc2831d094776.js} +1 -1
  171. package/dist/dashboard/out/_next/static/css/79b80143647a07d7.css +1 -0
  172. package/dist/dashboard/out/_next/static/css/8cf277370ad48cfe.css +1 -0
  173. package/dist/dashboard/out/alt-logos/agent-relay-logo-128.png +0 -0
  174. package/dist/dashboard/out/alt-logos/agent-relay-logo-256.png +0 -0
  175. package/dist/dashboard/out/alt-logos/agent-relay-logo-32.png +0 -0
  176. package/dist/dashboard/out/alt-logos/agent-relay-logo-512.png +0 -0
  177. package/dist/dashboard/out/alt-logos/agent-relay-logo-64.png +0 -0
  178. package/dist/dashboard/out/alt-logos/agent-relay-logo.svg +45 -0
  179. package/dist/dashboard/out/alt-logos/logo.svg +38 -0
  180. package/dist/dashboard/out/alt-logos/monogram-logo-128.png +0 -0
  181. package/dist/dashboard/out/alt-logos/monogram-logo-256.png +0 -0
  182. package/dist/dashboard/out/alt-logos/monogram-logo-32.png +0 -0
  183. package/dist/dashboard/out/alt-logos/monogram-logo-512.png +0 -0
  184. package/dist/dashboard/out/alt-logos/monogram-logo-64.png +0 -0
  185. package/dist/dashboard/out/alt-logos/monogram-logo.svg +38 -0
  186. package/dist/dashboard/out/app.html +14 -0
  187. package/dist/dashboard/out/app.txt +7 -0
  188. package/dist/dashboard/out/history.html +1 -0
  189. package/dist/dashboard/out/history.txt +7 -0
  190. package/dist/dashboard/out/index.html +1 -1
  191. package/dist/dashboard/out/index.txt +2 -2
  192. package/dist/dashboard/out/metrics.html +1 -515
  193. package/dist/dashboard/out/metrics.txt +2 -2
  194. package/dist/dashboard/out/pricing.html +13 -0
  195. package/dist/dashboard/out/pricing.txt +7 -0
  196. package/dist/dashboard-server/metrics.d.ts.map +1 -1
  197. package/dist/dashboard-server/metrics.js +3 -2
  198. package/dist/dashboard-server/metrics.js.map +1 -1
  199. package/dist/dashboard-server/server.d.ts.map +1 -1
  200. package/dist/dashboard-server/server.js +1279 -56
  201. package/dist/dashboard-server/server.js.map +1 -1
  202. package/dist/protocol/types.d.ts +10 -1
  203. package/dist/protocol/types.d.ts.map +1 -1
  204. package/dist/resiliency/context-persistence.d.ts +140 -0
  205. package/dist/resiliency/context-persistence.d.ts.map +1 -0
  206. package/dist/resiliency/context-persistence.js +397 -0
  207. package/dist/resiliency/context-persistence.js.map +1 -0
  208. package/dist/resiliency/health-monitor.d.ts +97 -0
  209. package/dist/resiliency/health-monitor.d.ts.map +1 -0
  210. package/dist/resiliency/health-monitor.js +291 -0
  211. package/dist/resiliency/health-monitor.js.map +1 -0
  212. package/dist/resiliency/index.d.ts +63 -0
  213. package/dist/resiliency/index.d.ts.map +1 -0
  214. package/dist/resiliency/index.js +63 -0
  215. package/dist/resiliency/index.js.map +1 -0
  216. package/dist/resiliency/logger.d.ts +114 -0
  217. package/dist/resiliency/logger.d.ts.map +1 -0
  218. package/dist/resiliency/logger.js +250 -0
  219. package/dist/resiliency/logger.js.map +1 -0
  220. package/dist/resiliency/metrics.d.ts +115 -0
  221. package/dist/resiliency/metrics.d.ts.map +1 -0
  222. package/dist/resiliency/metrics.js +239 -0
  223. package/dist/resiliency/metrics.js.map +1 -0
  224. package/dist/resiliency/provider-context.d.ts +100 -0
  225. package/dist/resiliency/provider-context.d.ts.map +1 -0
  226. package/dist/resiliency/provider-context.js +360 -0
  227. package/dist/resiliency/provider-context.js.map +1 -0
  228. package/dist/resiliency/supervisor.d.ts +109 -0
  229. package/dist/resiliency/supervisor.d.ts.map +1 -0
  230. package/dist/resiliency/supervisor.js +337 -0
  231. package/dist/resiliency/supervisor.js.map +1 -0
  232. package/dist/storage/adapter.d.ts +2 -0
  233. package/dist/storage/adapter.d.ts.map +1 -1
  234. package/dist/storage/adapter.js +12 -2
  235. package/dist/storage/adapter.js.map +1 -1
  236. package/dist/storage/sqlite-adapter.d.ts.map +1 -1
  237. package/dist/storage/sqlite-adapter.js +18 -14
  238. package/dist/storage/sqlite-adapter.js.map +1 -1
  239. package/dist/utils/index.d.ts +1 -0
  240. package/dist/utils/index.d.ts.map +1 -1
  241. package/dist/utils/index.js +1 -0
  242. package/dist/utils/index.js.map +1 -1
  243. package/dist/utils/logger.d.ts +40 -0
  244. package/dist/utils/logger.d.ts.map +1 -0
  245. package/dist/utils/logger.js +84 -0
  246. package/dist/utils/logger.js.map +1 -0
  247. package/dist/wrapper/client.d.ts +16 -1
  248. package/dist/wrapper/client.d.ts.map +1 -1
  249. package/dist/wrapper/client.js +32 -1
  250. package/dist/wrapper/client.js.map +1 -1
  251. package/dist/wrapper/parser.d.ts +3 -0
  252. package/dist/wrapper/parser.d.ts.map +1 -1
  253. package/dist/wrapper/parser.js +121 -18
  254. package/dist/wrapper/parser.js.map +1 -1
  255. package/dist/wrapper/pty-wrapper.d.ts +28 -1
  256. package/dist/wrapper/pty-wrapper.d.ts.map +1 -1
  257. package/dist/wrapper/pty-wrapper.js +166 -30
  258. package/dist/wrapper/pty-wrapper.js.map +1 -1
  259. package/dist/wrapper/tmux-wrapper.d.ts +5 -0
  260. package/dist/wrapper/tmux-wrapper.d.ts.map +1 -1
  261. package/dist/wrapper/tmux-wrapper.js +58 -18
  262. package/dist/wrapper/tmux-wrapper.js.map +1 -1
  263. package/docs/CLOUD-ARCHITECTURE.md +652 -0
  264. package/docs/CLOUD-ONBOARDING-DESIGN.md +1983 -0
  265. package/docs/TESTING_PRESENCE_FEATURES.md +327 -0
  266. package/docs/agent-relay-snippet.md +107 -4
  267. package/docs/guides/CLOUD.md +236 -0
  268. package/docs/guides/LOCAL.md +535 -0
  269. package/docs/guides/SELF-HOSTED.md +494 -0
  270. package/docs/proposals/shadow-as-subagent.md +765 -0
  271. package/docs/proposals/slack-bot-integration.md +1457 -0
  272. package/package.json +33 -4
  273. package/dist/dashboard/out/_next/static/chunks/app/layout-c9d8c5d95e48c6bf.js +0 -1
  274. package/dist/dashboard/out/_next/static/chunks/app/metrics/page-8aa9936bc6c771ab.js +0 -1
  275. package/dist/dashboard/out/_next/static/chunks/app/page-49055e5d2b5e34ec.js +0 -1
  276. package/dist/dashboard/out/_next/static/chunks/main-app-bae2e535de00de50.js +0 -1
  277. package/dist/dashboard/out/_next/static/css/50ed6996e3df7bdd.css +0 -1
  278. /package/dist/dashboard/out/_next/static/{gZXwjIKGDKJ0hiTH-HMeJ → 6HHWb2ZmnJ4OSm0zUP7h4}/_buildManifest.js +0 -0
  279. /package/dist/dashboard/out/_next/static/{gZXwjIKGDKJ0hiTH-HMeJ → 6HHWb2ZmnJ4OSm0zUP7h4}/_ssgManifest.js +0 -0
  280. /package/dist/dashboard/out/_next/static/chunks/{117-3bef7b19f3e60751.js → 117-b2cd8d6485aacf2b.js} +0 -0
  281. /package/dist/dashboard/out/_next/static/chunks/{648-6cf686106c891ad3.js → 648-8f3f26864ce515e5.js} +0 -0
  282. /package/dist/dashboard/out/_next/static/chunks/app/_not-found/{page-8ff6572bc7c9bc61.js → page-0b990dbb71d72a98.js} +0 -0
  283. /package/dist/dashboard/out/_next/static/chunks/{fd9d1056-26bd8d656b496dba.js → fd9d1056-bf46c09eb57e019c.js} +0 -0
@@ -0,0 +1,320 @@
1
+ /**
2
+ * Linked Daemons API Routes
3
+ *
4
+ * Allows local agent-relay instances to register and link with cloud.
5
+ * This enables:
6
+ * - Credential sync from cloud to local
7
+ * - Remote monitoring of local agents
8
+ * - Cross-machine agent discovery
9
+ * - Centralized dashboard for all instances
10
+ */
11
+ import { Router } from 'express';
12
+ import { randomBytes, createHash } from 'crypto';
13
+ import { requireAuth } from './auth.js';
14
+ import { db } from '../db/index.js';
15
+ import { vault } from '../vault/index.js';
16
+ export const daemonsRouter = Router();
17
+ /**
18
+ * Generate a secure API key
19
+ */
20
+ function generateApiKey() {
21
+ // Format: ar_live_<32 random bytes as hex>
22
+ const random = randomBytes(32).toString('hex');
23
+ return `ar_live_${random}`;
24
+ }
25
+ /**
26
+ * Hash an API key for storage
27
+ */
28
+ function hashApiKey(apiKey) {
29
+ return createHash('sha256').update(apiKey).digest('hex');
30
+ }
31
+ /**
32
+ * POST /api/daemons/link
33
+ * Register a local daemon with the cloud (requires browser auth first)
34
+ *
35
+ * Flow:
36
+ * 1. User runs `agent-relay cloud link` in terminal
37
+ * 2. CLI opens browser to /cloud/link?code=<temp_code>
38
+ * 3. User authenticates (or is already logged in)
39
+ * 4. Browser shows confirmation, user clicks "Link"
40
+ * 5. Server generates API key and returns to CLI via the temp code
41
+ */
42
+ daemonsRouter.post('/link', requireAuth, async (req, res) => {
43
+ const userId = req.session.userId;
44
+ const { name, machineId, metadata } = req.body;
45
+ if (!machineId || typeof machineId !== 'string') {
46
+ return res.status(400).json({ error: 'machineId is required' });
47
+ }
48
+ try {
49
+ // Check if this machine is already linked
50
+ const existing = await db.linkedDaemons.findByMachineId(userId, machineId);
51
+ if (existing) {
52
+ // Regenerate API key for existing link
53
+ const apiKey = generateApiKey();
54
+ const apiKeyHash = hashApiKey(apiKey);
55
+ await db.linkedDaemons.update(existing.id, {
56
+ name: name || existing.name,
57
+ apiKeyHash,
58
+ metadata: metadata || existing.metadata,
59
+ status: 'online',
60
+ lastSeenAt: new Date(),
61
+ });
62
+ return res.json({
63
+ success: true,
64
+ daemonId: existing.id,
65
+ apiKey, // Only returned once!
66
+ message: 'Daemon re-linked with new API key',
67
+ });
68
+ }
69
+ // Create new linked daemon
70
+ const apiKey = generateApiKey();
71
+ const apiKeyHash = hashApiKey(apiKey);
72
+ const daemon = await db.linkedDaemons.create({
73
+ userId,
74
+ name: name || `Daemon on ${machineId.substring(0, 8)}`,
75
+ machineId,
76
+ apiKeyHash,
77
+ status: 'online',
78
+ metadata: metadata || {},
79
+ });
80
+ res.status(201).json({
81
+ success: true,
82
+ daemonId: daemon.id,
83
+ apiKey, // Only returned once - user must save this!
84
+ message: 'Daemon linked successfully. Save your API key - it cannot be retrieved later.',
85
+ });
86
+ }
87
+ catch (error) {
88
+ console.error('Error linking daemon:', error);
89
+ res.status(500).json({ error: 'Failed to link daemon' });
90
+ }
91
+ });
92
+ /**
93
+ * GET /api/daemons
94
+ * List user's linked daemons
95
+ */
96
+ daemonsRouter.get('/', requireAuth, async (req, res) => {
97
+ const userId = req.session.userId;
98
+ try {
99
+ const daemons = await db.linkedDaemons.findByUserId(userId);
100
+ res.json({
101
+ daemons: daemons.map((d) => ({
102
+ id: d.id,
103
+ name: d.name,
104
+ machineId: d.machineId,
105
+ status: d.status,
106
+ lastSeenAt: d.lastSeenAt,
107
+ metadata: d.metadata,
108
+ createdAt: d.createdAt,
109
+ })),
110
+ });
111
+ }
112
+ catch (error) {
113
+ console.error('Error listing daemons:', error);
114
+ res.status(500).json({ error: 'Failed to list daemons' });
115
+ }
116
+ });
117
+ /**
118
+ * DELETE /api/daemons/:id
119
+ * Unlink a daemon
120
+ */
121
+ daemonsRouter.delete('/:id', requireAuth, async (req, res) => {
122
+ const userId = req.session.userId;
123
+ const { id } = req.params;
124
+ try {
125
+ const daemon = await db.linkedDaemons.findById(id);
126
+ if (!daemon) {
127
+ return res.status(404).json({ error: 'Daemon not found' });
128
+ }
129
+ if (daemon.userId !== userId) {
130
+ return res.status(403).json({ error: 'Unauthorized' });
131
+ }
132
+ await db.linkedDaemons.delete(id);
133
+ res.json({ success: true, message: 'Daemon unlinked' });
134
+ }
135
+ catch (error) {
136
+ console.error('Error unlinking daemon:', error);
137
+ res.status(500).json({ error: 'Failed to unlink daemon' });
138
+ }
139
+ });
140
+ // ============================================================================
141
+ // Daemon API (authenticated with API key, not session)
142
+ // These endpoints are called by local daemons, not browsers
143
+ // ============================================================================
144
+ /**
145
+ * Middleware to authenticate daemon by API key
146
+ */
147
+ async function requireDaemonAuth(req, res, next) {
148
+ const authHeader = req.headers.authorization;
149
+ if (!authHeader || !authHeader.startsWith('Bearer ar_live_')) {
150
+ res.status(401).json({ error: 'Invalid API key format' });
151
+ return;
152
+ }
153
+ const apiKey = authHeader.replace('Bearer ', '');
154
+ const apiKeyHash = hashApiKey(apiKey);
155
+ try {
156
+ const daemon = await db.linkedDaemons.findByApiKeyHash(apiKeyHash);
157
+ if (!daemon) {
158
+ res.status(401).json({ error: 'Invalid API key' });
159
+ return;
160
+ }
161
+ // Update last seen
162
+ await db.linkedDaemons.updateLastSeen(daemon.id);
163
+ // Attach daemon info to request
164
+ req.daemon = daemon;
165
+ next();
166
+ }
167
+ catch (error) {
168
+ console.error('Daemon auth error:', error);
169
+ res.status(500).json({ error: 'Authentication failed' });
170
+ }
171
+ }
172
+ /**
173
+ * POST /api/daemons/heartbeat
174
+ * Daemon heartbeat - reports status and gets any pending commands
175
+ */
176
+ daemonsRouter.post('/heartbeat', requireDaemonAuth, async (req, res) => {
177
+ const daemon = req.daemon;
178
+ const { agents, metrics } = req.body;
179
+ try {
180
+ // Update daemon status with agent info
181
+ await db.linkedDaemons.update(daemon.id, {
182
+ status: 'online',
183
+ metadata: {
184
+ ...daemon.metadata,
185
+ agents: agents || [],
186
+ metrics: metrics || {},
187
+ lastHeartbeat: new Date().toISOString(),
188
+ },
189
+ });
190
+ // Check for any pending commands (credential updates, etc.)
191
+ const pendingUpdates = await db.linkedDaemons.getPendingUpdates(daemon.id);
192
+ res.json({
193
+ success: true,
194
+ commands: pendingUpdates,
195
+ });
196
+ }
197
+ catch (error) {
198
+ console.error('Error processing heartbeat:', error);
199
+ res.status(500).json({ error: 'Failed to process heartbeat' });
200
+ }
201
+ });
202
+ /**
203
+ * GET /api/daemons/credentials
204
+ * Get credentials for the daemon's user (syncs cloud credentials to local)
205
+ */
206
+ daemonsRouter.get('/credentials', requireDaemonAuth, async (req, res) => {
207
+ const daemon = req.daemon;
208
+ try {
209
+ // Get all decrypted credentials for the user via vault
210
+ const credentialsMap = await vault.getUserCredentials(daemon.userId);
211
+ // Convert Map to array format for API response
212
+ const credentials = Array.from(credentialsMap.entries()).map(([provider, cred]) => ({
213
+ provider,
214
+ accessToken: cred.accessToken,
215
+ tokenType: 'bearer',
216
+ expiresAt: cred.tokenExpiresAt,
217
+ }));
218
+ res.json({ credentials });
219
+ }
220
+ catch (error) {
221
+ console.error('Error fetching credentials:', error);
222
+ res.status(500).json({ error: 'Failed to fetch credentials' });
223
+ }
224
+ });
225
+ /**
226
+ * POST /api/daemons/agents
227
+ * Report agent list to cloud (for cross-machine discovery)
228
+ */
229
+ daemonsRouter.post('/agents', requireDaemonAuth, async (req, res) => {
230
+ const daemon = req.daemon;
231
+ const { agents } = req.body;
232
+ if (!agents || !Array.isArray(agents)) {
233
+ return res.status(400).json({ error: 'agents array is required' });
234
+ }
235
+ try {
236
+ // Store agent list in daemon metadata
237
+ await db.linkedDaemons.update(daemon.id, {
238
+ metadata: {
239
+ ...daemon.metadata,
240
+ agents,
241
+ lastAgentSync: new Date().toISOString(),
242
+ },
243
+ });
244
+ // Get agents from all linked daemons for this user (cross-machine discovery)
245
+ const allDaemons = await db.linkedDaemons.findByUserId(daemon.userId);
246
+ const allAgents = allDaemons.flatMap((d) => {
247
+ const metadata = d.metadata;
248
+ const dAgents = metadata?.agents || [];
249
+ return dAgents.map((a) => ({
250
+ ...a,
251
+ daemonId: d.id,
252
+ daemonName: d.name,
253
+ machineId: d.machineId,
254
+ }));
255
+ });
256
+ res.json({
257
+ success: true,
258
+ allAgents, // Return all agents across all linked daemons
259
+ });
260
+ }
261
+ catch (error) {
262
+ console.error('Error syncing agents:', error);
263
+ res.status(500).json({ error: 'Failed to sync agents' });
264
+ }
265
+ });
266
+ /**
267
+ * POST /api/daemons/message
268
+ * Send message to an agent on another machine (cross-machine relay)
269
+ */
270
+ daemonsRouter.post('/message', requireDaemonAuth, async (req, res) => {
271
+ const daemon = req.daemon;
272
+ const { targetDaemonId, targetAgent, message } = req.body;
273
+ if (!targetDaemonId || !targetAgent || !message) {
274
+ return res.status(400).json({ error: 'targetDaemonId, targetAgent, and message are required' });
275
+ }
276
+ try {
277
+ // Verify target daemon belongs to same user
278
+ const targetDaemon = await db.linkedDaemons.findById(targetDaemonId);
279
+ if (!targetDaemon || targetDaemon.userId !== daemon.userId) {
280
+ return res.status(404).json({ error: 'Target daemon not found' });
281
+ }
282
+ // Queue message for delivery
283
+ await db.linkedDaemons.queueMessage(targetDaemonId, {
284
+ from: {
285
+ daemonId: daemon.id,
286
+ daemonName: daemon.name,
287
+ agent: message.from,
288
+ },
289
+ to: targetAgent,
290
+ content: message.content,
291
+ metadata: message.metadata,
292
+ timestamp: new Date().toISOString(),
293
+ });
294
+ res.json({ success: true, message: 'Message queued for delivery' });
295
+ }
296
+ catch (error) {
297
+ console.error('Error sending cross-machine message:', error);
298
+ res.status(500).json({ error: 'Failed to send message' });
299
+ }
300
+ });
301
+ /**
302
+ * GET /api/daemons/messages
303
+ * Get pending messages for this daemon (cross-machine messages)
304
+ */
305
+ daemonsRouter.get('/messages', requireDaemonAuth, async (req, res) => {
306
+ const daemon = req.daemon;
307
+ try {
308
+ const messages = await db.linkedDaemons.getQueuedMessages(daemon.id);
309
+ // Clear the queue after fetching
310
+ if (messages.length > 0) {
311
+ await db.linkedDaemons.clearMessageQueue(daemon.id);
312
+ }
313
+ res.json({ messages });
314
+ }
315
+ catch (error) {
316
+ console.error('Error fetching messages:', error);
317
+ res.status(500).json({ error: 'Failed to fetch messages' });
318
+ }
319
+ });
320
+ //# sourceMappingURL=daemons.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"daemons.js","sourceRoot":"","sources":["../../../src/cloud/api/daemons.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,36 @@
1
+ /**
2
+ * Plan Limits Middleware
3
+ *
4
+ * Express middleware to enforce plan-based resource limits.
5
+ */
6
+ import { Request, Response, NextFunction } from 'express';
7
+ /**
8
+ * Middleware to check workspace creation limit
9
+ *
10
+ * Use this middleware on workspace creation endpoints.
11
+ * Requires userId in session (use after requireAuth).
12
+ */
13
+ export declare function checkWorkspaceLimit(req: Request, res: Response, next: NextFunction): Promise<void>;
14
+ /**
15
+ * Middleware to check repository limit
16
+ *
17
+ * Use this middleware on repo connection endpoints.
18
+ * Requires userId in session (use after requireAuth).
19
+ */
20
+ export declare function checkRepoLimit(req: Request, res: Response, next: NextFunction): Promise<void>;
21
+ /**
22
+ * Middleware to check concurrent agent limit
23
+ *
24
+ * Use this middleware on agent spawn endpoints.
25
+ * Requires userId in session (use after requireAuth).
26
+ * Optionally pass currentRunningAgents in request body for accurate count.
27
+ */
28
+ export declare function checkAgentLimit(req: Request, res: Response, next: NextFunction): Promise<void>;
29
+ /**
30
+ * Middleware to check coordinator access
31
+ *
32
+ * Use this middleware on coordinator-related endpoints.
33
+ * Coordinators are only available on Pro plan and above.
34
+ */
35
+ export declare function checkCoordinatorAccess(req: Request, res: Response, next: NextFunction): Promise<void>;
36
+ //# sourceMappingURL=planLimits.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"planLimits.d.ts","sourceRoot":"","sources":["../../../../src/cloud/api/middleware/planLimits.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,EAAE,OAAO,EAAE,QAAQ,EAAE,YAAY,EAAE,MAAM,SAAS,CAAC;AA2B1D;;;;;GAKG;AACH,wBAAsB,mBAAmB,CACvC,GAAG,EAAE,OAAO,EACZ,GAAG,EAAE,QAAQ,EACb,IAAI,EAAE,YAAY,GACjB,OAAO,CAAC,IAAI,CAAC,CAoCf;AAED;;;;;GAKG;AACH,wBAAsB,cAAc,CAClC,GAAG,EAAE,OAAO,EACZ,GAAG,EAAE,QAAQ,EACb,IAAI,EAAE,YAAY,GACjB,OAAO,CAAC,IAAI,CAAC,CAoCf;AAED;;;;;;GAMG;AACH,wBAAsB,eAAe,CACnC,GAAG,EAAE,OAAO,EACZ,GAAG,EAAE,QAAQ,EACb,IAAI,EAAE,YAAY,GACjB,OAAO,CAAC,IAAI,CAAC,CAqCf;AAED;;;;;GAKG;AACH,wBAAsB,sBAAsB,CAC1C,GAAG,EAAE,OAAO,EACZ,GAAG,EAAE,QAAQ,EACb,IAAI,EAAE,YAAY,GACjB,OAAO,CAAC,IAAI,CAAC,CAmCf"}
@@ -0,0 +1,164 @@
1
+ /**
2
+ * Plan Limits Middleware
3
+ *
4
+ * Express middleware to enforce plan-based resource limits.
5
+ */
6
+ import { canCreateWorkspace, canAddRepo, canSpawnAgent, canUseCoordinator, } from '../../services/planLimits.js';
7
+ /**
8
+ * Middleware to check workspace creation limit
9
+ *
10
+ * Use this middleware on workspace creation endpoints.
11
+ * Requires userId in session (use after requireAuth).
12
+ */
13
+ export async function checkWorkspaceLimit(req, res, next) {
14
+ const userId = req.session.userId;
15
+ if (!userId) {
16
+ res.status(401).json({ error: 'Authentication required' });
17
+ return;
18
+ }
19
+ try {
20
+ const check = await canCreateWorkspace(userId);
21
+ if (!check.allowed) {
22
+ const response = {
23
+ error: check.reason || 'Workspace limit exceeded',
24
+ code: 'PLAN_LIMIT_EXCEEDED',
25
+ details: {
26
+ plan: 'current',
27
+ resource: 'workspaces',
28
+ limit: check.limit || 0,
29
+ current: check.current || 0,
30
+ },
31
+ upgrade: {
32
+ message: 'Upgrade your plan to create more workspaces',
33
+ url: '/settings/billing',
34
+ },
35
+ };
36
+ res.status(402).json(response);
37
+ return;
38
+ }
39
+ next();
40
+ }
41
+ catch (error) {
42
+ console.error('Error checking workspace limit:', error);
43
+ res.status(500).json({ error: 'Failed to check workspace limit' });
44
+ }
45
+ }
46
+ /**
47
+ * Middleware to check repository limit
48
+ *
49
+ * Use this middleware on repo connection endpoints.
50
+ * Requires userId in session (use after requireAuth).
51
+ */
52
+ export async function checkRepoLimit(req, res, next) {
53
+ const userId = req.session.userId;
54
+ if (!userId) {
55
+ res.status(401).json({ error: 'Authentication required' });
56
+ return;
57
+ }
58
+ try {
59
+ const check = await canAddRepo(userId);
60
+ if (!check.allowed) {
61
+ const response = {
62
+ error: check.reason || 'Repository limit exceeded',
63
+ code: 'PLAN_LIMIT_EXCEEDED',
64
+ details: {
65
+ plan: 'current',
66
+ resource: 'repos',
67
+ limit: check.limit || 0,
68
+ current: check.current || 0,
69
+ },
70
+ upgrade: {
71
+ message: 'Upgrade your plan to connect more repositories',
72
+ url: '/settings/billing',
73
+ },
74
+ };
75
+ res.status(402).json(response);
76
+ return;
77
+ }
78
+ next();
79
+ }
80
+ catch (error) {
81
+ console.error('Error checking repo limit:', error);
82
+ res.status(500).json({ error: 'Failed to check repository limit' });
83
+ }
84
+ }
85
+ /**
86
+ * Middleware to check concurrent agent limit
87
+ *
88
+ * Use this middleware on agent spawn endpoints.
89
+ * Requires userId in session (use after requireAuth).
90
+ * Optionally pass currentRunningAgents in request body for accurate count.
91
+ */
92
+ export async function checkAgentLimit(req, res, next) {
93
+ const userId = req.session.userId;
94
+ const currentRunningAgents = req.body.currentRunningAgents;
95
+ if (!userId) {
96
+ res.status(401).json({ error: 'Authentication required' });
97
+ return;
98
+ }
99
+ try {
100
+ const check = await canSpawnAgent(userId, currentRunningAgents);
101
+ if (!check.allowed) {
102
+ const response = {
103
+ error: check.reason || 'Concurrent agent limit exceeded',
104
+ code: 'PLAN_LIMIT_EXCEEDED',
105
+ details: {
106
+ plan: 'current',
107
+ resource: 'concurrentAgents',
108
+ limit: check.limit || 0,
109
+ current: check.current || 0,
110
+ },
111
+ upgrade: {
112
+ message: 'Upgrade your plan to run more concurrent agents',
113
+ url: '/settings/billing',
114
+ },
115
+ };
116
+ res.status(402).json(response);
117
+ return;
118
+ }
119
+ next();
120
+ }
121
+ catch (error) {
122
+ console.error('Error checking agent limit:', error);
123
+ res.status(500).json({ error: 'Failed to check agent limit' });
124
+ }
125
+ }
126
+ /**
127
+ * Middleware to check coordinator access
128
+ *
129
+ * Use this middleware on coordinator-related endpoints.
130
+ * Coordinators are only available on Pro plan and above.
131
+ */
132
+ export async function checkCoordinatorAccess(req, res, next) {
133
+ const userId = req.session.userId;
134
+ if (!userId) {
135
+ res.status(401).json({ error: 'Authentication required' });
136
+ return;
137
+ }
138
+ try {
139
+ const check = await canUseCoordinator(userId);
140
+ if (!check.allowed) {
141
+ const response = {
142
+ error: check.reason || 'Coordinator agents not available',
143
+ code: 'FEATURE_NOT_AVAILABLE',
144
+ details: {
145
+ plan: 'current',
146
+ resource: 'coordinators',
147
+ requiredPlan: check.requiredPlan,
148
+ },
149
+ upgrade: {
150
+ message: 'Upgrade to Pro to use coordinator agents',
151
+ url: '/settings/billing',
152
+ },
153
+ };
154
+ res.status(402).json(response);
155
+ return;
156
+ }
157
+ next();
158
+ }
159
+ catch (error) {
160
+ console.error('Error checking coordinator access:', error);
161
+ res.status(500).json({ error: 'Failed to check coordinator access' });
162
+ }
163
+ }
164
+ //# sourceMappingURL=planLimits.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"planLimits.js","sourceRoot":"","sources":["../../../../src/cloud/api/middleware/planLimits.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,8 @@
1
+ /**
2
+ * Onboarding API Routes
3
+ *
4
+ * Handles CLI proxy authentication for Claude Code and other providers.
5
+ * Spawns CLI tools to get auth URLs, captures tokens.
6
+ */
7
+ export declare const onboardingRouter: import("express-serve-static-core").Router;
8
+ //# sourceMappingURL=onboarding.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"onboarding.d.ts","sourceRoot":"","sources":["../../../src/cloud/api/onboarding.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AASH,eAAO,MAAM,gBAAgB,4CAAW,CAAC"}