agent-relay 1.1.0 → 1.2.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (567) hide show
  1. package/.gitattributes +3 -0
  2. package/.nvmrc +1 -0
  3. package/.trajectories/completed/2026-01/traj_1dviorhnkcb5.json +65 -0
  4. package/.trajectories/completed/2026-01/traj_1dviorhnkcb5.md +37 -0
  5. package/.trajectories/completed/2026-01/traj_1k5if5snst2e.json +65 -0
  6. package/.trajectories/completed/2026-01/traj_1k5if5snst2e.md +37 -0
  7. package/.trajectories/completed/2026-01/traj_1rp3rges5811.json +49 -0
  8. package/.trajectories/completed/2026-01/traj_1rp3rges5811.md +31 -0
  9. package/.trajectories/completed/2026-01/traj_22bhyulruouw.json +113 -0
  10. package/.trajectories/completed/2026-01/traj_22bhyulruouw.md +57 -0
  11. package/.trajectories/completed/2026-01/traj_2dao7ddgnta0.json +53 -0
  12. package/.trajectories/completed/2026-01/traj_2dao7ddgnta0.md +32 -0
  13. package/.trajectories/completed/2026-01/traj_3t0440mjeunc.json +26 -0
  14. package/.trajectories/completed/2026-01/traj_3t0440mjeunc.md +6 -0
  15. package/.trajectories/completed/2026-01/traj_45x9494d9xnr.json +47 -0
  16. package/.trajectories/completed/2026-01/traj_45x9494d9xnr.md +32 -0
  17. package/.trajectories/completed/2026-01/traj_4aa0bb77s4nh.json +53 -0
  18. package/.trajectories/completed/2026-01/traj_4aa0bb77s4nh.md +32 -0
  19. package/.trajectories/completed/2026-01/traj_5lhmzq8rxpqv.json +59 -0
  20. package/.trajectories/completed/2026-01/traj_5lhmzq8rxpqv.md +33 -0
  21. package/.trajectories/completed/2026-01/traj_5vr4e9erb1fs.json +53 -0
  22. package/.trajectories/completed/2026-01/traj_5vr4e9erb1fs.md +32 -0
  23. package/.trajectories/completed/2026-01/traj_6fgiwdoklvym.json +48 -0
  24. package/.trajectories/completed/2026-01/traj_6fgiwdoklvym.md +24 -0
  25. package/.trajectories/completed/2026-01/traj_7ludwvz45veh.json +209 -0
  26. package/.trajectories/completed/2026-01/traj_7ludwvz45veh.md +97 -0
  27. package/.trajectories/completed/2026-01/traj_9921cuhel0pj.json +48 -0
  28. package/.trajectories/completed/2026-01/traj_9921cuhel0pj.md +24 -0
  29. package/.trajectories/completed/2026-01/traj_ajs7zqfux4wc.json +49 -0
  30. package/.trajectories/completed/2026-01/traj_ajs7zqfux4wc.md +23 -0
  31. package/.trajectories/completed/2026-01/traj_cvtqhlwcq9s0.json +53 -0
  32. package/.trajectories/completed/2026-01/traj_cvtqhlwcq9s0.md +32 -0
  33. package/.trajectories/completed/2026-01/traj_cxofprm2m2en.json +49 -0
  34. package/.trajectories/completed/2026-01/traj_cxofprm2m2en.md +31 -0
  35. package/.trajectories/completed/2026-01/traj_d2hhz3k0vrhn.json +26 -0
  36. package/.trajectories/completed/2026-01/traj_d2hhz3k0vrhn.md +6 -0
  37. package/.trajectories/completed/2026-01/traj_dfuvww9pege5.json +59 -0
  38. package/.trajectories/completed/2026-01/traj_dfuvww9pege5.md +37 -0
  39. package/.trajectories/completed/2026-01/traj_g0fisy9h51mf.json +77 -0
  40. package/.trajectories/completed/2026-01/traj_g0fisy9h51mf.md +42 -0
  41. package/.trajectories/completed/2026-01/traj_gjdre5voouod.json +53 -0
  42. package/.trajectories/completed/2026-01/traj_gjdre5voouod.md +32 -0
  43. package/.trajectories/completed/2026-01/traj_gtlyqtta3x8l.json +25 -0
  44. package/.trajectories/completed/2026-01/traj_gtlyqtta3x8l.md +15 -0
  45. package/.trajectories/completed/2026-01/traj_h4xijiuip3w4.json +101 -0
  46. package/.trajectories/completed/2026-01/traj_h4xijiuip3w4.md +44 -0
  47. package/.trajectories/completed/2026-01/traj_hhxte7w4gjjx.json +22 -0
  48. package/.trajectories/completed/2026-01/traj_hhxte7w4gjjx.md +5 -0
  49. package/.trajectories/completed/2026-01/traj_hpungyhoj6v5.json +53 -0
  50. package/.trajectories/completed/2026-01/traj_hpungyhoj6v5.md +32 -0
  51. package/.trajectories/completed/2026-01/traj_m2xkjv0w2sq7.json +25 -0
  52. package/.trajectories/completed/2026-01/traj_m2xkjv0w2sq7.md +15 -0
  53. package/.trajectories/completed/2026-01/traj_noq5zbvnrdvz.json +53 -0
  54. package/.trajectories/completed/2026-01/traj_noq5zbvnrdvz.md +32 -0
  55. package/.trajectories/completed/2026-01/traj_ntbs6ppopf46.json +53 -0
  56. package/.trajectories/completed/2026-01/traj_ntbs6ppopf46.md +32 -0
  57. package/.trajectories/completed/2026-01/traj_ozd98si6a7ns.json +48 -0
  58. package/.trajectories/completed/2026-01/traj_ozd98si6a7ns.md +24 -0
  59. package/.trajectories/completed/2026-01/traj_prdza7a5cxp5.json +53 -0
  60. package/.trajectories/completed/2026-01/traj_prdza7a5cxp5.md +32 -0
  61. package/.trajectories/completed/2026-01/traj_qb3twvvywfwi.json +77 -0
  62. package/.trajectories/completed/2026-01/traj_qb3twvvywfwi.md +42 -0
  63. package/.trajectories/completed/2026-01/traj_qft54mi7nfor.json +53 -0
  64. package/.trajectories/completed/2026-01/traj_qft54mi7nfor.md +32 -0
  65. package/.trajectories/completed/2026-01/traj_qx9uhf8whhxo.json +83 -0
  66. package/.trajectories/completed/2026-01/traj_qx9uhf8whhxo.md +47 -0
  67. package/.trajectories/completed/2026-01/traj_rd9toccj18a0.json +59 -0
  68. package/.trajectories/completed/2026-01/traj_rd9toccj18a0.md +37 -0
  69. package/.trajectories/completed/2026-01/traj_rt4fiw3ecp50.json +48 -0
  70. package/.trajectories/completed/2026-01/traj_rt4fiw3ecp50.md +16 -0
  71. package/.trajectories/completed/2026-01/traj_st8j35b0hrlc.json +59 -0
  72. package/.trajectories/completed/2026-01/traj_st8j35b0hrlc.md +37 -0
  73. package/.trajectories/completed/2026-01/traj_t1yy8m7hbuxp.json +53 -0
  74. package/.trajectories/completed/2026-01/traj_t1yy8m7hbuxp.md +32 -0
  75. package/.trajectories/completed/2026-01/traj_tmux_orchestrator_analysis.json +84 -0
  76. package/.trajectories/completed/2026-01/traj_tmux_orchestrator_analysis.md +109 -0
  77. package/.trajectories/completed/2026-01/traj_u9n9eqasw16k.json +53 -0
  78. package/.trajectories/completed/2026-01/traj_u9n9eqasw16k.md +32 -0
  79. package/.trajectories/completed/2026-01/traj_v87hypnongqx.json +71 -0
  80. package/.trajectories/completed/2026-01/traj_v87hypnongqx.md +42 -0
  81. package/.trajectories/completed/2026-01/traj_wkp2fgzdyinb.json +53 -0
  82. package/.trajectories/completed/2026-01/traj_wkp2fgzdyinb.md +32 -0
  83. package/.trajectories/completed/2026-01/traj_x14t8w8rn7xg.json +20 -0
  84. package/.trajectories/completed/2026-01/traj_x14t8w8rn7xg.md +6 -0
  85. package/.trajectories/completed/2026-01/traj_xnwbznkvv8ua.json +175 -0
  86. package/.trajectories/completed/2026-01/traj_xnwbznkvv8ua.md +82 -0
  87. package/.trajectories/completed/2026-01/traj_ysjc8zaeqtd3.json +47 -0
  88. package/.trajectories/completed/2026-01/traj_ysjc8zaeqtd3.md +32 -0
  89. package/.trajectories/completed/2026-01/traj_yvdadtvdgnz3.json +59 -0
  90. package/.trajectories/completed/2026-01/traj_yvdadtvdgnz3.md +37 -0
  91. package/.trajectories/completed/2026-01/traj_z0vcw1wrzide.json +53 -0
  92. package/.trajectories/completed/2026-01/traj_z0vcw1wrzide.md +32 -0
  93. package/.trajectories/index.json +314 -0
  94. package/ARCHITECTURE.md +1245 -0
  95. package/README.md +1 -1
  96. package/TESTING.md +278 -0
  97. package/deploy/init-db.sql +5 -0
  98. package/deploy/scripts/setup-fly-workspaces.sh +69 -0
  99. package/deploy/scripts/setup-railway.sh +75 -0
  100. package/deploy/workspace/entrypoint-browser.sh +118 -0
  101. package/deploy/workspace/entrypoint.sh +348 -0
  102. package/deploy/workspace/git-credential-relay +111 -0
  103. package/dist/bridge/spawner.d.ts +53 -0
  104. package/dist/bridge/spawner.js +203 -19
  105. package/dist/bridge/types.d.ts +12 -0
  106. package/dist/cli/index.js +618 -5
  107. package/dist/cloud/api/auth.d.ts +3 -2
  108. package/dist/cloud/api/auth.js +10 -98
  109. package/dist/cloud/api/billing.js +30 -9
  110. package/dist/cloud/api/cli-pty-runner.d.ts +54 -0
  111. package/dist/cloud/api/cli-pty-runner.js +119 -0
  112. package/dist/cloud/api/codex-auth-helper.d.ts +15 -0
  113. package/dist/cloud/api/codex-auth-helper.js +100 -0
  114. package/dist/cloud/api/generic-webhooks.d.ts +8 -0
  115. package/dist/cloud/api/generic-webhooks.js +129 -0
  116. package/dist/cloud/api/git.d.ts +8 -0
  117. package/dist/cloud/api/git.js +152 -0
  118. package/dist/cloud/api/github-app.d.ts +11 -0
  119. package/dist/cloud/api/github-app.js +189 -0
  120. package/dist/cloud/api/middleware/planLimits.d.ts +7 -0
  121. package/dist/cloud/api/middleware/planLimits.js +39 -1
  122. package/dist/cloud/api/monitoring.d.ts +11 -0
  123. package/dist/cloud/api/monitoring.js +578 -0
  124. package/dist/cloud/api/nango-auth.d.ts +9 -0
  125. package/dist/cloud/api/nango-auth.js +377 -0
  126. package/dist/cloud/api/onboarding.d.ts +8 -1
  127. package/dist/cloud/api/onboarding.js +313 -119
  128. package/dist/cloud/api/policy.d.ts +8 -0
  129. package/dist/cloud/api/policy.js +229 -0
  130. package/dist/cloud/api/providers.js +114 -42
  131. package/dist/cloud/api/repos.d.ts +1 -0
  132. package/dist/cloud/api/repos.js +186 -0
  133. package/dist/cloud/api/test-helpers.d.ts +10 -0
  134. package/dist/cloud/api/test-helpers.js +575 -0
  135. package/dist/cloud/api/webhooks.d.ts +8 -0
  136. package/dist/cloud/api/webhooks.js +645 -0
  137. package/dist/cloud/api/workspaces.js +320 -12
  138. package/dist/cloud/billing/plans.js +32 -19
  139. package/dist/cloud/billing/types.d.ts +9 -3
  140. package/dist/cloud/config.d.ts +9 -2
  141. package/dist/cloud/config.js +13 -4
  142. package/dist/cloud/db/drizzle.d.ts +84 -1
  143. package/dist/cloud/db/drizzle.js +470 -0
  144. package/dist/cloud/db/index.d.ts +9 -4
  145. package/dist/cloud/db/index.js +11 -3
  146. package/dist/cloud/db/schema.d.ts +3283 -556
  147. package/dist/cloud/db/schema.js +314 -1
  148. package/dist/cloud/index.d.ts +1 -0
  149. package/dist/cloud/index.js +2 -0
  150. package/dist/cloud/provisioner/index.d.ts +56 -0
  151. package/dist/cloud/provisioner/index.js +676 -34
  152. package/dist/cloud/server.d.ts +1 -0
  153. package/dist/cloud/server.js +362 -13
  154. package/dist/cloud/services/auto-scaler.d.ts +152 -0
  155. package/dist/cloud/services/auto-scaler.js +439 -0
  156. package/dist/cloud/services/capacity-manager.d.ts +148 -0
  157. package/dist/cloud/services/capacity-manager.js +449 -0
  158. package/dist/cloud/services/ci-agent-spawner.d.ts +49 -0
  159. package/dist/cloud/services/ci-agent-spawner.js +373 -0
  160. package/dist/cloud/services/index.d.ts +12 -0
  161. package/dist/cloud/services/index.js +15 -0
  162. package/dist/cloud/services/mention-handler.d.ts +65 -0
  163. package/dist/cloud/services/mention-handler.js +405 -0
  164. package/dist/cloud/services/nango.d.ts +186 -0
  165. package/dist/cloud/services/nango.js +344 -0
  166. package/dist/cloud/services/persistence.d.ts +131 -0
  167. package/dist/cloud/services/persistence.js +200 -0
  168. package/dist/cloud/services/planLimits.d.ts +37 -0
  169. package/dist/cloud/services/planLimits.js +86 -5
  170. package/dist/cloud/services/scaling-orchestrator.d.ts +159 -0
  171. package/dist/cloud/services/scaling-orchestrator.js +502 -0
  172. package/dist/cloud/services/scaling-policy.d.ts +121 -0
  173. package/dist/cloud/services/scaling-policy.js +415 -0
  174. package/dist/cloud/vault/index.js +1 -1
  175. package/dist/cloud/webhooks/index.d.ts +24 -0
  176. package/dist/cloud/webhooks/index.js +29 -0
  177. package/dist/cloud/webhooks/parsers/github.d.ts +8 -0
  178. package/dist/cloud/webhooks/parsers/github.js +234 -0
  179. package/dist/cloud/webhooks/parsers/index.d.ts +23 -0
  180. package/dist/cloud/webhooks/parsers/index.js +30 -0
  181. package/dist/cloud/webhooks/parsers/linear.d.ts +9 -0
  182. package/dist/cloud/webhooks/parsers/linear.js +258 -0
  183. package/dist/cloud/webhooks/parsers/slack.d.ts +9 -0
  184. package/dist/cloud/webhooks/parsers/slack.js +214 -0
  185. package/dist/cloud/webhooks/responders/github.d.ts +8 -0
  186. package/dist/cloud/webhooks/responders/github.js +73 -0
  187. package/dist/cloud/webhooks/responders/index.d.ts +23 -0
  188. package/dist/cloud/webhooks/responders/index.js +30 -0
  189. package/dist/cloud/webhooks/responders/linear.d.ts +9 -0
  190. package/dist/cloud/webhooks/responders/linear.js +149 -0
  191. package/dist/cloud/webhooks/responders/slack.d.ts +20 -0
  192. package/dist/cloud/webhooks/responders/slack.js +178 -0
  193. package/dist/cloud/webhooks/router.d.ts +25 -0
  194. package/dist/cloud/webhooks/router.js +504 -0
  195. package/dist/cloud/webhooks/rules-engine.d.ts +24 -0
  196. package/dist/cloud/webhooks/rules-engine.js +287 -0
  197. package/dist/cloud/webhooks/types.d.ts +186 -0
  198. package/dist/cloud/webhooks/types.js +8 -0
  199. package/dist/continuity/formatter.d.ts +51 -0
  200. package/dist/continuity/formatter.js +313 -0
  201. package/dist/continuity/handoff-store.d.ts +67 -0
  202. package/dist/continuity/handoff-store.js +472 -0
  203. package/dist/continuity/index.d.ts +45 -0
  204. package/dist/continuity/index.js +48 -0
  205. package/dist/continuity/ledger-store.d.ts +110 -0
  206. package/dist/continuity/ledger-store.js +500 -0
  207. package/dist/continuity/manager.d.ts +178 -0
  208. package/dist/continuity/manager.js +562 -0
  209. package/dist/continuity/parser.d.ts +76 -0
  210. package/dist/continuity/parser.js +579 -0
  211. package/dist/continuity/types.d.ts +180 -0
  212. package/dist/continuity/types.js +9 -0
  213. package/dist/daemon/agent-manager.d.ts +27 -0
  214. package/dist/daemon/agent-manager.js +107 -6
  215. package/dist/daemon/agent-registry.d.ts +32 -0
  216. package/dist/daemon/agent-registry.js +42 -2
  217. package/dist/daemon/api.d.ts +12 -0
  218. package/dist/daemon/api.js +131 -2
  219. package/dist/daemon/cli-auth.d.ts +67 -0
  220. package/dist/daemon/cli-auth.js +537 -0
  221. package/dist/daemon/cloud-sync.js +9 -7
  222. package/dist/daemon/orchestrator.js +30 -0
  223. package/dist/daemon/router.d.ts +5 -0
  224. package/dist/daemon/router.js +78 -26
  225. package/dist/daemon/server.d.ts +5 -0
  226. package/dist/daemon/server.js +9 -1
  227. package/dist/daemon/services/browser-testing.d.ts +88 -0
  228. package/dist/daemon/services/browser-testing.js +244 -0
  229. package/dist/daemon/services/container-spawner.d.ts +135 -0
  230. package/dist/daemon/services/container-spawner.js +313 -0
  231. package/dist/daemon/types.d.ts +5 -1
  232. package/dist/dashboard/out/404.html +1 -1
  233. package/dist/dashboard/out/_next/static/chunks/116-2502180def231162.js +1 -0
  234. package/dist/dashboard/out/_next/static/chunks/282-980c2eb8fff20123.js +1 -0
  235. package/dist/dashboard/out/_next/static/chunks/699-3b1cd6618a45d259.js +1 -0
  236. package/dist/dashboard/out/_next/static/chunks/724-2dae7627550ab88f.js +9 -0
  237. package/dist/dashboard/out/_next/static/chunks/766-1f2dd8cb7f766b0b.js +1 -0
  238. package/dist/dashboard/out/_next/static/chunks/app/app/onboarding/page-3fdfa60e53f2810d.js +1 -0
  239. package/dist/dashboard/out/_next/static/chunks/app/app/page-e6381e5a6e1fbcfd.js +1 -0
  240. package/dist/dashboard/out/_next/static/chunks/app/connect-repos/page-3538dfe0ffe984b8.js +1 -0
  241. package/dist/dashboard/out/_next/static/chunks/app/history/{page-b6edd4dde8d08194.js → page-abb9ab2d329f56e9.js} +1 -1
  242. package/dist/dashboard/out/_next/static/chunks/app/layout-c0d118c0f92d969c.js +1 -0
  243. package/dist/dashboard/out/_next/static/chunks/app/login/page-c22d080201cbd9fb.js +1 -0
  244. package/dist/dashboard/out/_next/static/chunks/app/metrics/page-67a3e98d9a43a6ed.js +1 -0
  245. package/dist/dashboard/out/_next/static/chunks/app/page-77e9c65420a06cfb.js +1 -0
  246. package/dist/dashboard/out/_next/static/chunks/app/pricing/page-b08ed1c34d14434a.js +1 -0
  247. package/dist/dashboard/out/_next/static/chunks/app/providers/page-e88bc117ef7671c3.js +1 -0
  248. package/dist/dashboard/out/_next/static/chunks/app/signup/page-68d34f50baa8ab6b.js +1 -0
  249. package/dist/dashboard/out/_next/static/chunks/e868780c-48e5f147c90a3a41.js +18 -0
  250. package/dist/dashboard/out/_next/static/chunks/{main-app-5d692157a8eb1fd9.js → main-app-6e8e8d3ef4e0192a.js} +1 -1
  251. package/dist/dashboard/out/_next/static/chunks/{main-c2f423b9c9f4591b.js → main-ed4e1fb6f29c34cf.js} +1 -1
  252. package/dist/dashboard/out/_next/static/chunks/webpack-1cdd8ed57114d5e1.js +1 -0
  253. package/dist/dashboard/out/_next/static/css/29852f26181969a0.css +1 -0
  254. package/dist/dashboard/out/_next/static/css/7c3ae9e8617d42a5.css +1 -0
  255. package/dist/dashboard/out/app/onboarding.html +1 -0
  256. package/dist/dashboard/out/app/onboarding.txt +7 -0
  257. package/dist/dashboard/out/app.html +1 -14
  258. package/dist/dashboard/out/app.txt +2 -2
  259. package/dist/dashboard/out/connect-repos.html +1 -0
  260. package/dist/dashboard/out/connect-repos.txt +7 -0
  261. package/dist/dashboard/out/history.html +1 -1
  262. package/dist/dashboard/out/history.txt +2 -2
  263. package/dist/dashboard/out/index.html +1 -1
  264. package/dist/dashboard/out/index.txt +2 -2
  265. package/dist/dashboard/out/login.html +6 -0
  266. package/dist/dashboard/out/login.txt +7 -0
  267. package/dist/dashboard/out/metrics.html +1 -1
  268. package/dist/dashboard/out/metrics.txt +2 -2
  269. package/dist/dashboard/out/pricing.html +3 -3
  270. package/dist/dashboard/out/pricing.txt +2 -2
  271. package/dist/dashboard/out/providers.html +1 -0
  272. package/dist/dashboard/out/providers.txt +7 -0
  273. package/dist/dashboard/out/signup.html +6 -0
  274. package/dist/dashboard/out/signup.txt +7 -0
  275. package/dist/dashboard-server/server.js +1308 -8
  276. package/dist/hooks/emitter.d.ts +40 -0
  277. package/dist/hooks/emitter.js +63 -0
  278. package/dist/hooks/index.d.ts +3 -0
  279. package/dist/hooks/index.js +3 -0
  280. package/dist/hooks/registry.d.ts +173 -0
  281. package/dist/hooks/registry.js +476 -0
  282. package/dist/hooks/trajectory-hooks.d.ts +52 -0
  283. package/dist/hooks/trajectory-hooks.js +183 -0
  284. package/dist/hooks/types.d.ts +141 -0
  285. package/dist/index.d.ts +2 -0
  286. package/dist/index.js +3 -0
  287. package/dist/memory/adapters/index.d.ts +8 -0
  288. package/dist/memory/adapters/index.js +8 -0
  289. package/dist/memory/adapters/inmemory.d.ts +59 -0
  290. package/dist/memory/adapters/inmemory.js +195 -0
  291. package/dist/memory/adapters/supermemory.d.ts +71 -0
  292. package/dist/memory/adapters/supermemory.js +338 -0
  293. package/dist/memory/factory.d.ts +48 -0
  294. package/dist/memory/factory.js +143 -0
  295. package/dist/memory/index.d.ts +32 -0
  296. package/dist/memory/index.js +32 -0
  297. package/dist/memory/memory-hooks.d.ts +60 -0
  298. package/dist/memory/memory-hooks.js +313 -0
  299. package/dist/memory/service.d.ts +49 -0
  300. package/dist/memory/service.js +146 -0
  301. package/dist/memory/types.d.ts +195 -0
  302. package/dist/memory/types.js +8 -0
  303. package/dist/policy/agent-policy.d.ts +225 -0
  304. package/dist/policy/agent-policy.js +665 -0
  305. package/dist/policy/cloud-policy-fetcher.d.ts +12 -0
  306. package/dist/policy/cloud-policy-fetcher.js +64 -0
  307. package/dist/resiliency/crash-insights.d.ts +156 -0
  308. package/dist/resiliency/crash-insights.js +492 -0
  309. package/dist/resiliency/gossip-health.d.ts +137 -0
  310. package/dist/resiliency/gossip-health.js +241 -0
  311. package/dist/resiliency/index.d.ts +5 -0
  312. package/dist/resiliency/index.js +5 -0
  313. package/dist/resiliency/leader-watchdog.d.ts +109 -0
  314. package/dist/resiliency/leader-watchdog.js +189 -0
  315. package/dist/resiliency/memory-monitor.d.ts +172 -0
  316. package/dist/resiliency/memory-monitor.js +593 -0
  317. package/dist/resiliency/stateless-lead.d.ts +149 -0
  318. package/dist/resiliency/stateless-lead.js +308 -0
  319. package/dist/resiliency/supervisor.d.ts +38 -0
  320. package/dist/resiliency/supervisor.js +122 -0
  321. package/dist/shared/cli-auth-config.d.ts +91 -0
  322. package/dist/shared/cli-auth-config.js +264 -0
  323. package/dist/storage/adapter.d.ts +1 -1
  324. package/dist/trajectory/config.d.ts +84 -0
  325. package/dist/trajectory/config.js +163 -0
  326. package/dist/trajectory/index.d.ts +8 -0
  327. package/dist/trajectory/index.js +8 -0
  328. package/dist/trajectory/integration.d.ts +292 -0
  329. package/dist/trajectory/integration.js +834 -0
  330. package/dist/utils/logger.js +1 -1
  331. package/dist/utils/project-namespace.d.ts +24 -0
  332. package/dist/utils/project-namespace.js +84 -0
  333. package/dist/wrapper/parser.d.ts +10 -0
  334. package/dist/wrapper/parser.js +100 -33
  335. package/dist/wrapper/pty-wrapper.d.ts +197 -16
  336. package/dist/wrapper/pty-wrapper.js +943 -106
  337. package/dist/wrapper/shared.d.ts +165 -0
  338. package/dist/wrapper/shared.js +270 -0
  339. package/dist/wrapper/tmux-wrapper.d.ts +73 -11
  340. package/dist/wrapper/tmux-wrapper.js +541 -120
  341. package/package.json +16 -16
  342. package/scripts/postinstall.js +60 -0
  343. package/test-push.txt +1 -0
  344. package/bin/tmux +0 -0
  345. package/dist/bridge/config.d.ts.map +0 -1
  346. package/dist/bridge/config.js.map +0 -1
  347. package/dist/bridge/index.d.ts.map +0 -1
  348. package/dist/bridge/index.js.map +0 -1
  349. package/dist/bridge/multi-project-client.d.ts.map +0 -1
  350. package/dist/bridge/multi-project-client.js.map +0 -1
  351. package/dist/bridge/shadow-cli.d.ts.map +0 -1
  352. package/dist/bridge/shadow-cli.js.map +0 -1
  353. package/dist/bridge/shadow-config.d.ts.map +0 -1
  354. package/dist/bridge/shadow-config.js.map +0 -1
  355. package/dist/bridge/spawner.d.ts.map +0 -1
  356. package/dist/bridge/spawner.js.map +0 -1
  357. package/dist/bridge/teams-config.d.ts.map +0 -1
  358. package/dist/bridge/teams-config.js.map +0 -1
  359. package/dist/bridge/types.d.ts.map +0 -1
  360. package/dist/bridge/types.js.map +0 -1
  361. package/dist/bridge/utils.d.ts.map +0 -1
  362. package/dist/bridge/utils.js.map +0 -1
  363. package/dist/cli/index.d.ts.map +0 -1
  364. package/dist/cli/index.js.map +0 -1
  365. package/dist/cloud/api/auth.d.ts.map +0 -1
  366. package/dist/cloud/api/auth.js.map +0 -1
  367. package/dist/cloud/api/billing.d.ts.map +0 -1
  368. package/dist/cloud/api/billing.js.map +0 -1
  369. package/dist/cloud/api/coordinators.d.ts.map +0 -1
  370. package/dist/cloud/api/coordinators.js.map +0 -1
  371. package/dist/cloud/api/daemons.d.ts.map +0 -1
  372. package/dist/cloud/api/daemons.js.map +0 -1
  373. package/dist/cloud/api/middleware/planLimits.d.ts.map +0 -1
  374. package/dist/cloud/api/middleware/planLimits.js.map +0 -1
  375. package/dist/cloud/api/onboarding.d.ts.map +0 -1
  376. package/dist/cloud/api/onboarding.js.map +0 -1
  377. package/dist/cloud/api/providers.d.ts.map +0 -1
  378. package/dist/cloud/api/providers.js.map +0 -1
  379. package/dist/cloud/api/repos.d.ts.map +0 -1
  380. package/dist/cloud/api/repos.js.map +0 -1
  381. package/dist/cloud/api/teams.d.ts.map +0 -1
  382. package/dist/cloud/api/teams.js.map +0 -1
  383. package/dist/cloud/api/usage.d.ts.map +0 -1
  384. package/dist/cloud/api/usage.js.map +0 -1
  385. package/dist/cloud/api/workspaces.d.ts.map +0 -1
  386. package/dist/cloud/api/workspaces.js.map +0 -1
  387. package/dist/cloud/billing/index.d.ts.map +0 -1
  388. package/dist/cloud/billing/index.js.map +0 -1
  389. package/dist/cloud/billing/plans.d.ts.map +0 -1
  390. package/dist/cloud/billing/plans.js.map +0 -1
  391. package/dist/cloud/billing/service.d.ts.map +0 -1
  392. package/dist/cloud/billing/service.js.map +0 -1
  393. package/dist/cloud/billing/types.d.ts.map +0 -1
  394. package/dist/cloud/billing/types.js.map +0 -1
  395. package/dist/cloud/config.d.ts.map +0 -1
  396. package/dist/cloud/config.js.map +0 -1
  397. package/dist/cloud/db/drizzle.d.ts.map +0 -1
  398. package/dist/cloud/db/drizzle.js.map +0 -1
  399. package/dist/cloud/db/index.d.ts.map +0 -1
  400. package/dist/cloud/db/index.js.map +0 -1
  401. package/dist/cloud/db/schema.d.ts.map +0 -1
  402. package/dist/cloud/db/schema.js.map +0 -1
  403. package/dist/cloud/index.d.ts.map +0 -1
  404. package/dist/cloud/index.js.map +0 -1
  405. package/dist/cloud/provisioner/index.d.ts.map +0 -1
  406. package/dist/cloud/provisioner/index.js.map +0 -1
  407. package/dist/cloud/server.d.ts.map +0 -1
  408. package/dist/cloud/server.js.map +0 -1
  409. package/dist/cloud/services/coordinator.d.ts.map +0 -1
  410. package/dist/cloud/services/coordinator.js.map +0 -1
  411. package/dist/cloud/services/planLimits.d.ts.map +0 -1
  412. package/dist/cloud/services/planLimits.js.map +0 -1
  413. package/dist/cloud/vault/index.d.ts.map +0 -1
  414. package/dist/cloud/vault/index.js.map +0 -1
  415. package/dist/daemon/agent-manager.d.ts.map +0 -1
  416. package/dist/daemon/agent-manager.js.map +0 -1
  417. package/dist/daemon/agent-registry.d.ts.map +0 -1
  418. package/dist/daemon/agent-registry.js.map +0 -1
  419. package/dist/daemon/api.d.ts.map +0 -1
  420. package/dist/daemon/api.js.map +0 -1
  421. package/dist/daemon/auth.d.ts.map +0 -1
  422. package/dist/daemon/auth.js.map +0 -1
  423. package/dist/daemon/cloud-sync.d.ts.map +0 -1
  424. package/dist/daemon/cloud-sync.js.map +0 -1
  425. package/dist/daemon/connection.d.ts.map +0 -1
  426. package/dist/daemon/connection.js.map +0 -1
  427. package/dist/daemon/index.d.ts.map +0 -1
  428. package/dist/daemon/index.js.map +0 -1
  429. package/dist/daemon/orchestrator.d.ts.map +0 -1
  430. package/dist/daemon/orchestrator.js.map +0 -1
  431. package/dist/daemon/registry.d.ts.map +0 -1
  432. package/dist/daemon/registry.js.map +0 -1
  433. package/dist/daemon/router.d.ts.map +0 -1
  434. package/dist/daemon/router.js.map +0 -1
  435. package/dist/daemon/server.d.ts.map +0 -1
  436. package/dist/daemon/server.js.map +0 -1
  437. package/dist/daemon/types.d.ts.map +0 -1
  438. package/dist/daemon/types.js.map +0 -1
  439. package/dist/daemon/workspace-manager.d.ts.map +0 -1
  440. package/dist/daemon/workspace-manager.js.map +0 -1
  441. package/dist/dashboard/out/_next/static/chunks/693-7b3301d8f6bc5014.js +0 -1
  442. package/dist/dashboard/out/_next/static/chunks/713-f78477eb185f1f4d.js +0 -1
  443. package/dist/dashboard/out/_next/static/chunks/766-e53e1cfe39b0b5b5.js +0 -1
  444. package/dist/dashboard/out/_next/static/chunks/900-037c64bfd797fb2a.js +0 -1
  445. package/dist/dashboard/out/_next/static/chunks/app/app/page-e3d9e1f4466b9bae.js +0 -1
  446. package/dist/dashboard/out/_next/static/chunks/app/layout-2433bb48965f4333.js +0 -1
  447. package/dist/dashboard/out/_next/static/chunks/app/metrics/page-e68825a81db67ba1.js +0 -1
  448. package/dist/dashboard/out/_next/static/chunks/app/page-cc108bf68c8a657f.js +0 -1
  449. package/dist/dashboard/out/_next/static/chunks/app/pricing/page-d80e03a5297f95b6.js +0 -1
  450. package/dist/dashboard/out/_next/static/chunks/webpack-a5acc2831d094776.js +0 -1
  451. package/dist/dashboard/out/_next/static/css/79b80143647a07d7.css +0 -1
  452. package/dist/dashboard/out/_next/static/css/8cf277370ad48cfe.css +0 -1
  453. package/dist/dashboard-server/metrics.d.ts.map +0 -1
  454. package/dist/dashboard-server/metrics.js.map +0 -1
  455. package/dist/dashboard-server/needs-attention.d.ts.map +0 -1
  456. package/dist/dashboard-server/needs-attention.js.map +0 -1
  457. package/dist/dashboard-server/server.d.ts.map +0 -1
  458. package/dist/dashboard-server/server.js.map +0 -1
  459. package/dist/dashboard-server/start.d.ts.map +0 -1
  460. package/dist/dashboard-server/start.js.map +0 -1
  461. package/dist/hooks/inbox-check/hook.d.ts.map +0 -1
  462. package/dist/hooks/inbox-check/hook.js.map +0 -1
  463. package/dist/hooks/inbox-check/index.d.ts.map +0 -1
  464. package/dist/hooks/inbox-check/index.js.map +0 -1
  465. package/dist/hooks/inbox-check/types.d.ts.map +0 -1
  466. package/dist/hooks/inbox-check/types.js.map +0 -1
  467. package/dist/hooks/inbox-check/utils.d.ts.map +0 -1
  468. package/dist/hooks/inbox-check/utils.js.map +0 -1
  469. package/dist/hooks/index.d.ts.map +0 -1
  470. package/dist/hooks/index.js.map +0 -1
  471. package/dist/hooks/types.d.ts.map +0 -1
  472. package/dist/hooks/types.js.map +0 -1
  473. package/dist/index.d.ts.map +0 -1
  474. package/dist/index.js.map +0 -1
  475. package/dist/protocol/framing.d.ts.map +0 -1
  476. package/dist/protocol/framing.js.map +0 -1
  477. package/dist/protocol/index.d.ts.map +0 -1
  478. package/dist/protocol/index.js.map +0 -1
  479. package/dist/protocol/types.d.ts.map +0 -1
  480. package/dist/protocol/types.js.map +0 -1
  481. package/dist/resiliency/context-persistence.d.ts.map +0 -1
  482. package/dist/resiliency/context-persistence.js.map +0 -1
  483. package/dist/resiliency/health-monitor.d.ts.map +0 -1
  484. package/dist/resiliency/health-monitor.js.map +0 -1
  485. package/dist/resiliency/index.d.ts.map +0 -1
  486. package/dist/resiliency/index.js.map +0 -1
  487. package/dist/resiliency/logger.d.ts.map +0 -1
  488. package/dist/resiliency/logger.js.map +0 -1
  489. package/dist/resiliency/metrics.d.ts.map +0 -1
  490. package/dist/resiliency/metrics.js.map +0 -1
  491. package/dist/resiliency/provider-context.d.ts.map +0 -1
  492. package/dist/resiliency/provider-context.js.map +0 -1
  493. package/dist/resiliency/supervisor.d.ts.map +0 -1
  494. package/dist/resiliency/supervisor.js.map +0 -1
  495. package/dist/state/agent-state.d.ts.map +0 -1
  496. package/dist/state/agent-state.js.map +0 -1
  497. package/dist/storage/adapter.d.ts.map +0 -1
  498. package/dist/storage/adapter.js.map +0 -1
  499. package/dist/storage/sqlite-adapter.d.ts.map +0 -1
  500. package/dist/storage/sqlite-adapter.js.map +0 -1
  501. package/dist/utils/agent-config.d.ts.map +0 -1
  502. package/dist/utils/agent-config.js.map +0 -1
  503. package/dist/utils/command-resolver.d.ts.map +0 -1
  504. package/dist/utils/command-resolver.js.map +0 -1
  505. package/dist/utils/index.d.ts.map +0 -1
  506. package/dist/utils/index.js.map +0 -1
  507. package/dist/utils/logger.d.ts.map +0 -1
  508. package/dist/utils/logger.js.map +0 -1
  509. package/dist/utils/name-generator.d.ts.map +0 -1
  510. package/dist/utils/name-generator.js.map +0 -1
  511. package/dist/utils/project-namespace.d.ts.map +0 -1
  512. package/dist/utils/project-namespace.js.map +0 -1
  513. package/dist/utils/tmux-resolver.d.ts.map +0 -1
  514. package/dist/utils/tmux-resolver.js.map +0 -1
  515. package/dist/utils/update-checker.d.ts.map +0 -1
  516. package/dist/utils/update-checker.js.map +0 -1
  517. package/dist/wrapper/client.d.ts.map +0 -1
  518. package/dist/wrapper/client.js.map +0 -1
  519. package/dist/wrapper/inbox.d.ts.map +0 -1
  520. package/dist/wrapper/inbox.js.map +0 -1
  521. package/dist/wrapper/index.d.ts.map +0 -1
  522. package/dist/wrapper/index.js.map +0 -1
  523. package/dist/wrapper/parser.d.ts.map +0 -1
  524. package/dist/wrapper/parser.js.map +0 -1
  525. package/dist/wrapper/pty-wrapper.d.ts.map +0 -1
  526. package/dist/wrapper/pty-wrapper.js.map +0 -1
  527. package/dist/wrapper/tmux-wrapper.d.ts.map +0 -1
  528. package/dist/wrapper/tmux-wrapper.js.map +0 -1
  529. package/docs/AGENTS.md +0 -513
  530. package/docs/ARCHITECTURE_DECISIONS.md +0 -175
  531. package/docs/CHANGELOG.md +0 -11
  532. package/docs/CLI-SIMPLIFICATION-COMPLETE.md +0 -48
  533. package/docs/CLOUD-ARCHITECTURE.md +0 -652
  534. package/docs/CLOUD-ONBOARDING-DESIGN.md +0 -1983
  535. package/docs/COMPETITIVE_ANALYSIS.md +0 -897
  536. package/docs/CONTRIBUTING.md +0 -151
  537. package/docs/DESIGN_BRIDGE_STAFFING.md +0 -878
  538. package/docs/DESIGN_V2.md +0 -1079
  539. package/docs/INTEGRATION-GUIDE.md +0 -926
  540. package/docs/MONETIZATION.md +0 -1679
  541. package/docs/PROPOSAL-trajectories.md +0 -1582
  542. package/docs/PROTOCOL.md +0 -325
  543. package/docs/SCALING_ANALYSIS.md +0 -280
  544. package/docs/TESTING_PRESENCE_FEATURES.md +0 -327
  545. package/docs/TMUX_IMPLEMENTATION_NOTES.md +0 -364
  546. package/docs/TMUX_IMPROVEMENTS.md +0 -968
  547. package/docs/agent-relay-snippet.md +0 -168
  548. package/docs/competitive-analysis-mcp-agent-mail.md +0 -389
  549. package/docs/dashboard-v2-plan.md +0 -179
  550. package/docs/guides/CLOUD.md +0 -236
  551. package/docs/guides/LOCAL.md +0 -535
  552. package/docs/guides/SELF-HOSTED.md +0 -494
  553. package/docs/proposals/shadow-as-subagent.md +0 -765
  554. package/docs/proposals/slack-bot-integration.md +0 -1457
  555. package/docs/removable-code-analysis.md +0 -24
  556. package/scripts/dev/PUBLIC_RELEASE_PLAN.md +0 -88
  557. package/scripts/dev/dev-team-setup.sh +0 -431
  558. package/scripts/e2e-test.sh +0 -119
  559. package/scripts/games/game-protocol.md +0 -79
  560. package/scripts/games/hearts-setup.sh +0 -264
  561. package/scripts/tictactoe-setup.sh +0 -181
  562. /package/dist/dashboard/out/_next/static/chunks/{117-b2cd8d6485aacf2b.js → 117-f7b8ab0809342e77.js} +0 -0
  563. /package/dist/dashboard/out/_next/static/chunks/{648-8f3f26864ce515e5.js → 648-5cc6e1921389a58a.js} +0 -0
  564. /package/dist/dashboard/out/_next/static/chunks/app/_not-found/{page-0b990dbb71d72a98.js → page-53b8a69f76db17d0.js} +0 -0
  565. /package/dist/dashboard/out/_next/static/chunks/{fd9d1056-bf46c09eb57e019c.js → fd9d1056-609918ca7b6280bb.js} +0 -0
  566. /package/dist/dashboard/out/_next/static/{6HHWb2ZmnJ4OSm0zUP7h4 → wPgKJtcOmTFLpUncDg16A}/_buildManifest.js +0 -0
  567. /package/dist/dashboard/out/_next/static/{6HHWb2ZmnJ4OSm0zUP7h4 → wPgKJtcOmTFLpUncDg16A}/_ssgManifest.js +0 -0
@@ -0,0 +1,665 @@
1
+ /**
2
+ * Agent Policy Service
3
+ *
4
+ * Manages agent permissions and rules with multi-level fallback:
5
+ * 1. Repo-level policy (.claude/agents/*.md)
6
+ * 2. Workspace-level policy (from cloud API)
7
+ * 3. Built-in safe defaults
8
+ *
9
+ * Provides spawn authorization, tool permission checks, and audit logging.
10
+ */
11
+ import fs from 'node:fs';
12
+ import path from 'node:path';
13
+ import { findAgentConfig } from '../utils/agent-config.js';
14
+ import os from 'node:os';
15
+ /** Built-in safe defaults when no policy exists */
16
+ const DEFAULT_POLICY = {
17
+ name: '*',
18
+ allowedTools: undefined, // All tools allowed by default
19
+ canSpawn: undefined, // Can spawn any agent
20
+ canMessage: undefined, // Can message any agent
21
+ maxSpawns: 10,
22
+ rateLimit: 60, // 60 messages per minute
23
+ canBeSpawned: true,
24
+ };
25
+ /** Restrictive defaults for unknown agents in strict mode */
26
+ const STRICT_DEFAULT_POLICY = {
27
+ name: '*',
28
+ allowedTools: ['Read', 'Grep', 'Glob'], // Read-only by default
29
+ canSpawn: [], // Cannot spawn
30
+ canMessage: ['Lead', 'Coordinator'], // Can only message leads
31
+ maxSpawns: 0,
32
+ rateLimit: 10,
33
+ canBeSpawned: false,
34
+ };
35
+ export class AgentPolicyService {
36
+ projectRoot;
37
+ workspaceId;
38
+ cloudFetcher;
39
+ cachedWorkspacePolicy;
40
+ cachedLocalPolicy;
41
+ policyCacheExpiry = 0;
42
+ localPolicyCacheExpiry = 0;
43
+ auditLog = [];
44
+ strictMode;
45
+ /** Cache TTL in milliseconds (5 minutes) */
46
+ static CACHE_TTL_MS = 5 * 60 * 1000;
47
+ /** Local policy cache TTL (1 minute - files can change) */
48
+ static LOCAL_CACHE_TTL_MS = 60 * 1000;
49
+ /** Maximum audit log entries to keep in memory */
50
+ static MAX_AUDIT_ENTRIES = 1000;
51
+ constructor(options) {
52
+ this.projectRoot = options.projectRoot;
53
+ this.workspaceId = options.workspaceId;
54
+ this.cloudFetcher = options.cloudFetcher;
55
+ this.strictMode = options.strictMode ?? false;
56
+ }
57
+ /**
58
+ * Get the user-level policies directory
59
+ * Uses ~/.config/agent-relay/policies/ (not in source control)
60
+ */
61
+ getUserPoliciesDir() {
62
+ const configDir = process.env.AGENT_RELAY_CONFIG_DIR ??
63
+ path.join(os.homedir(), '.config', 'agent-relay');
64
+ return path.join(configDir, 'policies');
65
+ }
66
+ /**
67
+ * Load policies from user-level directory (PRPM-installable)
68
+ * Files are YAML/JSON with agent policy definitions
69
+ * Location: ~/.config/agent-relay/policies/*.yaml
70
+ */
71
+ loadLocalPolicies() {
72
+ // Check cache
73
+ if (this.cachedLocalPolicy && Date.now() < this.localPolicyCacheExpiry) {
74
+ return this.cachedLocalPolicy;
75
+ }
76
+ const policiesDir = this.getUserPoliciesDir();
77
+ if (!fs.existsSync(policiesDir)) {
78
+ return null;
79
+ }
80
+ try {
81
+ const files = fs.readdirSync(policiesDir).filter(f => f.endsWith('.yaml') || f.endsWith('.yml') || f.endsWith('.json'));
82
+ if (files.length === 0) {
83
+ return null;
84
+ }
85
+ // Merge all policy files
86
+ const mergedAgents = [];
87
+ let mergedSettings = {
88
+ requireExplicitAgents: false,
89
+ auditEnabled: true,
90
+ maxTotalAgents: 50,
91
+ };
92
+ let mergedDefault = { ...DEFAULT_POLICY };
93
+ for (const file of files) {
94
+ const filePath = path.join(policiesDir, file);
95
+ const content = fs.readFileSync(filePath, 'utf-8');
96
+ let parsed;
97
+ if (file.endsWith('.json')) {
98
+ parsed = JSON.parse(content);
99
+ }
100
+ else {
101
+ // Simple YAML parsing for policy files
102
+ parsed = this.parseSimpleYaml(content);
103
+ }
104
+ // Merge agents
105
+ if (Array.isArray(parsed.agents)) {
106
+ for (const agent of parsed.agents) {
107
+ if (agent && typeof agent === 'object' && 'name' in agent) {
108
+ mergedAgents.push(agent);
109
+ }
110
+ }
111
+ }
112
+ // Merge settings (later files override)
113
+ if (parsed.settings && typeof parsed.settings === 'object') {
114
+ mergedSettings = { ...mergedSettings, ...parsed.settings };
115
+ }
116
+ // Merge default policy
117
+ if (parsed.defaultPolicy && typeof parsed.defaultPolicy === 'object') {
118
+ mergedDefault = { ...mergedDefault, ...parsed.defaultPolicy };
119
+ }
120
+ }
121
+ const policy = {
122
+ defaultPolicy: mergedDefault,
123
+ agents: mergedAgents,
124
+ settings: mergedSettings,
125
+ };
126
+ this.cachedLocalPolicy = policy;
127
+ this.localPolicyCacheExpiry = Date.now() + AgentPolicyService.LOCAL_CACHE_TTL_MS;
128
+ return policy;
129
+ }
130
+ catch (err) {
131
+ console.error('[policy] Failed to load local policies:', err);
132
+ return null;
133
+ }
134
+ }
135
+ /**
136
+ * Simple YAML parser for policy files
137
+ * Handles basic key: value and arrays
138
+ */
139
+ parseSimpleYaml(content) {
140
+ const result = {};
141
+ const lines = content.split('\n');
142
+ let _currentKey = '';
143
+ let currentArray = null;
144
+ let currentObject = null;
145
+ let indent = 0;
146
+ for (const line of lines) {
147
+ const trimmed = line.trim();
148
+ // Skip comments and empty lines
149
+ if (!trimmed || trimmed.startsWith('#'))
150
+ continue;
151
+ // Calculate indentation
152
+ const lineIndent = line.length - line.trimStart().length;
153
+ // Array item
154
+ if (trimmed.startsWith('- ')) {
155
+ const value = trimmed.slice(2).trim();
156
+ // Object in array (e.g., "- name: Worker")
157
+ if (value.includes(':')) {
158
+ const [key, val] = value.split(':').map(s => s.trim());
159
+ currentObject = { [key]: this.parseValue(val) };
160
+ if (currentArray) {
161
+ currentArray.push(currentObject);
162
+ }
163
+ }
164
+ else {
165
+ // Simple array value
166
+ if (currentArray) {
167
+ currentArray.push(this.parseValue(value));
168
+ }
169
+ }
170
+ continue;
171
+ }
172
+ // Key: value pair
173
+ const colonIdx = trimmed.indexOf(':');
174
+ if (colonIdx > 0) {
175
+ const key = trimmed.slice(0, colonIdx).trim();
176
+ const value = trimmed.slice(colonIdx + 1).trim();
177
+ // If we're inside an object in an array
178
+ if (currentObject && lineIndent > indent) {
179
+ currentObject[key] = this.parseValue(value);
180
+ continue;
181
+ }
182
+ // Top-level or section key
183
+ if (value === '' || value === '|' || value === '>') {
184
+ // Start of array or nested object
185
+ _currentKey = key;
186
+ currentArray = [];
187
+ currentObject = null;
188
+ indent = lineIndent;
189
+ result[key] = currentArray;
190
+ }
191
+ else {
192
+ // Simple key: value
193
+ if (lineIndent === 0) {
194
+ result[key] = this.parseValue(value);
195
+ _currentKey = '';
196
+ currentArray = null;
197
+ currentObject = null;
198
+ }
199
+ else if (currentObject) {
200
+ currentObject[key] = this.parseValue(value);
201
+ }
202
+ }
203
+ }
204
+ }
205
+ return result;
206
+ }
207
+ /**
208
+ * Parse a YAML value string
209
+ */
210
+ parseValue(value) {
211
+ if (!value || value === '~' || value === 'null')
212
+ return null;
213
+ if (value === 'true')
214
+ return true;
215
+ if (value === 'false')
216
+ return false;
217
+ // Array notation [a, b, c]
218
+ if (value.startsWith('[') && value.endsWith(']')) {
219
+ const inner = value.slice(1, -1);
220
+ if (!inner.trim())
221
+ return [];
222
+ return inner.split(',').map(s => {
223
+ const trimmed = s.trim().replace(/^["']|["']$/g, '');
224
+ return trimmed;
225
+ });
226
+ }
227
+ // Number
228
+ if (/^-?\d+(\.\d+)?$/.test(value)) {
229
+ return parseFloat(value);
230
+ }
231
+ // String (remove quotes if present)
232
+ return value.replace(/^["']|["']$/g, '');
233
+ }
234
+ /**
235
+ * Check if an agent can spawn another agent
236
+ */
237
+ async canSpawn(spawnerName, targetName, targetCli) {
238
+ const spawnerPolicy = await this.getAgentPolicy(spawnerName);
239
+ const targetPolicy = await this.getAgentPolicy(targetName);
240
+ // Check if target can be spawned
241
+ if (targetPolicy.matchedPolicy?.canBeSpawned === false) {
242
+ const decision = {
243
+ allowed: false,
244
+ reason: `Agent "${targetName}" is not allowed to be spawned`,
245
+ policySource: targetPolicy.policySource,
246
+ matchedPolicy: targetPolicy.matchedPolicy,
247
+ };
248
+ this.audit('spawn', spawnerName, targetName, decision, { cli: targetCli });
249
+ return decision;
250
+ }
251
+ // Check if spawner can spawn
252
+ const canSpawnList = spawnerPolicy.matchedPolicy?.canSpawn;
253
+ if (canSpawnList !== undefined && canSpawnList.length > 0) {
254
+ const canSpawn = this.matchesPattern(targetName, canSpawnList);
255
+ if (!canSpawn) {
256
+ const decision = {
257
+ allowed: false,
258
+ reason: `Agent "${spawnerName}" is not allowed to spawn "${targetName}"`,
259
+ policySource: spawnerPolicy.policySource,
260
+ matchedPolicy: spawnerPolicy.matchedPolicy,
261
+ };
262
+ this.audit('spawn', spawnerName, targetName, decision, { cli: targetCli });
263
+ return decision;
264
+ }
265
+ }
266
+ // Check max spawns (would need spawn count tracking - placeholder)
267
+ const decision = {
268
+ allowed: true,
269
+ reason: 'Spawn permitted by policy',
270
+ policySource: spawnerPolicy.policySource,
271
+ matchedPolicy: spawnerPolicy.matchedPolicy,
272
+ };
273
+ this.audit('spawn', spawnerName, targetName, decision, { cli: targetCli });
274
+ return decision;
275
+ }
276
+ /**
277
+ * Check if an agent can send a message to another agent
278
+ */
279
+ async canMessage(senderName, recipientName) {
280
+ const senderPolicy = await this.getAgentPolicy(senderName);
281
+ const canMessageList = senderPolicy.matchedPolicy?.canMessage;
282
+ if (canMessageList !== undefined && canMessageList.length > 0) {
283
+ const canMessage = this.matchesPattern(recipientName, canMessageList);
284
+ if (!canMessage) {
285
+ const decision = {
286
+ allowed: false,
287
+ reason: `Agent "${senderName}" is not allowed to message "${recipientName}"`,
288
+ policySource: senderPolicy.policySource,
289
+ matchedPolicy: senderPolicy.matchedPolicy,
290
+ };
291
+ this.audit('message', senderName, recipientName, decision);
292
+ return decision;
293
+ }
294
+ }
295
+ const decision = {
296
+ allowed: true,
297
+ reason: 'Message permitted by policy',
298
+ policySource: senderPolicy.policySource,
299
+ matchedPolicy: senderPolicy.matchedPolicy,
300
+ };
301
+ this.audit('message', senderName, recipientName, decision);
302
+ return decision;
303
+ }
304
+ /**
305
+ * Check if an agent can use a specific tool
306
+ */
307
+ async canUseTool(agentName, toolName) {
308
+ const policy = await this.getAgentPolicy(agentName);
309
+ const allowedTools = policy.matchedPolicy?.allowedTools;
310
+ if (allowedTools !== undefined) {
311
+ // ["none"] means no tools allowed
312
+ if (allowedTools.length === 1 && allowedTools[0] === 'none') {
313
+ const decision = {
314
+ allowed: false,
315
+ reason: `Agent "${agentName}" is not allowed to use any tools`,
316
+ policySource: policy.policySource,
317
+ matchedPolicy: policy.matchedPolicy,
318
+ };
319
+ this.audit('tool', agentName, toolName, decision);
320
+ return decision;
321
+ }
322
+ // Check if tool is in allowed list
323
+ const allowed = this.matchesPattern(toolName, allowedTools);
324
+ if (!allowed) {
325
+ const decision = {
326
+ allowed: false,
327
+ reason: `Agent "${agentName}" is not allowed to use tool "${toolName}"`,
328
+ policySource: policy.policySource,
329
+ matchedPolicy: policy.matchedPolicy,
330
+ };
331
+ this.audit('tool', agentName, toolName, decision);
332
+ return decision;
333
+ }
334
+ }
335
+ const decision = {
336
+ allowed: true,
337
+ reason: 'Tool usage permitted by policy',
338
+ policySource: policy.policySource,
339
+ matchedPolicy: policy.matchedPolicy,
340
+ };
341
+ this.audit('tool', agentName, toolName, decision);
342
+ return decision;
343
+ }
344
+ /**
345
+ * Get the effective policy for an agent
346
+ * Fallback chain: repo config → user PRPM policies → cloud workspace → defaults
347
+ */
348
+ async getAgentPolicy(agentName) {
349
+ // 1. Try repo-level config (.claude/agents/*.md)
350
+ const repoConfig = findAgentConfig(agentName, this.projectRoot);
351
+ if (repoConfig) {
352
+ return {
353
+ matchedPolicy: this.configToPolicy(repoConfig),
354
+ policySource: 'repo',
355
+ };
356
+ }
357
+ // 2. Try user-level PRPM policies (~/.config/agent-relay/policies/*.yaml)
358
+ const localPolicy = this.loadLocalPolicies();
359
+ if (localPolicy) {
360
+ // Check for strict mode in local policy
361
+ if (localPolicy.settings?.requireExplicitAgents) {
362
+ const matchedPolicy = this.findMatchingPolicy(agentName, localPolicy.agents);
363
+ if (matchedPolicy) {
364
+ return { matchedPolicy, policySource: 'local' };
365
+ }
366
+ // Unknown agent in strict mode
367
+ return {
368
+ matchedPolicy: { ...STRICT_DEFAULT_POLICY, name: agentName },
369
+ policySource: 'local',
370
+ };
371
+ }
372
+ // Find matching policy
373
+ const matchedPolicy = this.findMatchingPolicy(agentName, localPolicy.agents);
374
+ if (matchedPolicy) {
375
+ return { matchedPolicy, policySource: 'local' };
376
+ }
377
+ // Use local default
378
+ if (localPolicy.defaultPolicy) {
379
+ return {
380
+ matchedPolicy: { ...localPolicy.defaultPolicy, name: agentName },
381
+ policySource: 'local',
382
+ };
383
+ }
384
+ }
385
+ // 3. Try workspace-level policy from cloud
386
+ const workspacePolicy = await this.getWorkspacePolicy();
387
+ if (workspacePolicy) {
388
+ // Check for strict mode
389
+ if (workspacePolicy.settings?.requireExplicitAgents) {
390
+ // In strict mode, unknown agents get restrictive defaults
391
+ const matchedPolicy = this.findMatchingPolicy(agentName, workspacePolicy.agents);
392
+ if (matchedPolicy) {
393
+ return { matchedPolicy, policySource: 'workspace' };
394
+ }
395
+ // Unknown agent in strict mode
396
+ return {
397
+ matchedPolicy: { ...STRICT_DEFAULT_POLICY, name: agentName },
398
+ policySource: 'workspace',
399
+ };
400
+ }
401
+ // Find matching policy
402
+ const matchedPolicy = this.findMatchingPolicy(agentName, workspacePolicy.agents);
403
+ if (matchedPolicy) {
404
+ return { matchedPolicy, policySource: 'workspace' };
405
+ }
406
+ // Use workspace default
407
+ if (workspacePolicy.defaultPolicy) {
408
+ return {
409
+ matchedPolicy: { ...workspacePolicy.defaultPolicy, name: agentName },
410
+ policySource: 'workspace',
411
+ };
412
+ }
413
+ }
414
+ // 4. Fall back to built-in defaults
415
+ const defaultPolicy = this.strictMode ? STRICT_DEFAULT_POLICY : DEFAULT_POLICY;
416
+ return {
417
+ matchedPolicy: { ...defaultPolicy, name: agentName },
418
+ policySource: 'default',
419
+ };
420
+ }
421
+ /**
422
+ * Get workspace policy from cloud (with caching)
423
+ */
424
+ async getWorkspacePolicy() {
425
+ if (!this.workspaceId || !this.cloudFetcher) {
426
+ return null;
427
+ }
428
+ // Check cache
429
+ if (this.cachedWorkspacePolicy && Date.now() < this.policyCacheExpiry) {
430
+ return this.cachedWorkspacePolicy;
431
+ }
432
+ try {
433
+ const policy = await this.cloudFetcher.getWorkspacePolicy(this.workspaceId);
434
+ if (policy) {
435
+ this.cachedWorkspacePolicy = policy;
436
+ this.policyCacheExpiry = Date.now() + AgentPolicyService.CACHE_TTL_MS;
437
+ }
438
+ return policy;
439
+ }
440
+ catch (err) {
441
+ console.error('[policy] Failed to fetch workspace policy:', err);
442
+ // Return cached policy if available, even if expired
443
+ return this.cachedWorkspacePolicy ?? null;
444
+ }
445
+ }
446
+ /**
447
+ * Find matching policy from a list (supports wildcards)
448
+ */
449
+ findMatchingPolicy(agentName, policies) {
450
+ // First try exact match
451
+ const exactMatch = policies.find(p => p.name.toLowerCase() === agentName.toLowerCase());
452
+ if (exactMatch)
453
+ return exactMatch;
454
+ // Then try pattern match
455
+ for (const policy of policies) {
456
+ if (this.matchesPattern(agentName, [policy.name])) {
457
+ return policy;
458
+ }
459
+ }
460
+ return null;
461
+ }
462
+ /**
463
+ * Check if a name matches any pattern in the list
464
+ * Supports: exact match, prefix* match, *suffix match, * (all)
465
+ */
466
+ matchesPattern(name, patterns) {
467
+ const lowerName = name.toLowerCase();
468
+ for (const pattern of patterns) {
469
+ const lowerPattern = pattern.toLowerCase();
470
+ // Wildcard all
471
+ if (lowerPattern === '*')
472
+ return true;
473
+ // Exact match
474
+ if (lowerPattern === lowerName)
475
+ return true;
476
+ // Prefix match (e.g., "Worker*" matches "WorkerA")
477
+ if (lowerPattern.endsWith('*')) {
478
+ const prefix = lowerPattern.slice(0, -1);
479
+ if (lowerName.startsWith(prefix))
480
+ return true;
481
+ }
482
+ // Suffix match (e.g., "*Lead" matches "TeamLead")
483
+ if (lowerPattern.startsWith('*')) {
484
+ const suffix = lowerPattern.slice(1);
485
+ if (lowerName.endsWith(suffix))
486
+ return true;
487
+ }
488
+ }
489
+ return false;
490
+ }
491
+ /**
492
+ * Convert AgentConfig to AgentPolicy
493
+ */
494
+ configToPolicy(config) {
495
+ return {
496
+ name: config.name,
497
+ allowedTools: config.allowedTools,
498
+ // Other fields come from defaults since repo config doesn't specify them
499
+ canSpawn: undefined,
500
+ canMessage: undefined,
501
+ maxSpawns: 10,
502
+ rateLimit: 60,
503
+ canBeSpawned: true,
504
+ };
505
+ }
506
+ /**
507
+ * Record an audit entry
508
+ */
509
+ audit(action, actor, target, decision, context) {
510
+ const entry = {
511
+ timestamp: Date.now(),
512
+ action,
513
+ actor,
514
+ target,
515
+ decision,
516
+ context,
517
+ };
518
+ this.auditLog.push(entry);
519
+ // Trim log if too large
520
+ if (this.auditLog.length > AgentPolicyService.MAX_AUDIT_ENTRIES) {
521
+ this.auditLog = this.auditLog.slice(-AgentPolicyService.MAX_AUDIT_ENTRIES / 2);
522
+ }
523
+ // Log denied actions
524
+ if (!decision.allowed) {
525
+ console.warn(`[policy] DENIED: ${action} by ${actor}${target ? ` -> ${target}` : ''}: ${decision.reason}`);
526
+ }
527
+ }
528
+ /**
529
+ * Get audit log entries
530
+ */
531
+ getAuditLog(options) {
532
+ let entries = [...this.auditLog];
533
+ if (options?.action) {
534
+ entries = entries.filter(e => e.action === options.action);
535
+ }
536
+ if (options?.actor) {
537
+ entries = entries.filter(e => e.actor === options.actor);
538
+ }
539
+ if (options?.deniedOnly) {
540
+ entries = entries.filter(e => !e.decision.allowed);
541
+ }
542
+ if (options?.limit) {
543
+ entries = entries.slice(-options.limit);
544
+ }
545
+ return entries;
546
+ }
547
+ /**
548
+ * Clear audit log
549
+ */
550
+ clearAuditLog() {
551
+ this.auditLog = [];
552
+ }
553
+ /**
554
+ * Invalidate cached workspace policy
555
+ */
556
+ invalidateCache() {
557
+ this.cachedWorkspacePolicy = undefined;
558
+ this.policyCacheExpiry = 0;
559
+ }
560
+ /**
561
+ * Get a human-readable policy summary for an agent
562
+ * This can be injected into agent prompts to inform them of their permissions
563
+ */
564
+ async getPolicySummary(agentName) {
565
+ const { matchedPolicy, policySource } = await this.getAgentPolicy(agentName);
566
+ const lines = [
567
+ `# Agent Policy for ${agentName}`,
568
+ `Source: ${policySource}`,
569
+ '',
570
+ ];
571
+ // Tools
572
+ if (matchedPolicy.allowedTools) {
573
+ if (matchedPolicy.allowedTools.length === 1 && matchedPolicy.allowedTools[0] === 'none') {
574
+ lines.push('**Tools**: No tools allowed');
575
+ }
576
+ else {
577
+ lines.push(`**Allowed Tools**: ${matchedPolicy.allowedTools.join(', ')}`);
578
+ }
579
+ }
580
+ else {
581
+ lines.push('**Tools**: All tools allowed');
582
+ }
583
+ // Spawning
584
+ if (matchedPolicy.canSpawn) {
585
+ if (matchedPolicy.canSpawn.length === 0) {
586
+ lines.push('**Spawning**: Cannot spawn other agents');
587
+ }
588
+ else {
589
+ lines.push(`**Can Spawn**: ${matchedPolicy.canSpawn.join(', ')}`);
590
+ }
591
+ }
592
+ else {
593
+ lines.push('**Spawning**: Can spawn any agent');
594
+ }
595
+ // Messaging
596
+ if (matchedPolicy.canMessage) {
597
+ if (matchedPolicy.canMessage.length === 0) {
598
+ lines.push('**Messaging**: Cannot message other agents');
599
+ }
600
+ else {
601
+ lines.push(`**Can Message**: ${matchedPolicy.canMessage.join(', ')}`);
602
+ }
603
+ }
604
+ else {
605
+ lines.push('**Messaging**: Can message any agent');
606
+ }
607
+ // Limits
608
+ if (matchedPolicy.maxSpawns !== undefined) {
609
+ lines.push(`**Max Spawns**: ${matchedPolicy.maxSpawns}`);
610
+ }
611
+ if (matchedPolicy.rateLimit !== undefined) {
612
+ lines.push(`**Rate Limit**: ${matchedPolicy.rateLimit} messages/min`);
613
+ }
614
+ return lines.join('\n');
615
+ }
616
+ /**
617
+ * Get a concise policy instruction for injection into agent prompts
618
+ */
619
+ async getPolicyInstruction(agentName) {
620
+ const { matchedPolicy, policySource: _policySource } = await this.getAgentPolicy(agentName);
621
+ // Only generate instructions if there are restrictions
622
+ const hasRestrictions = matchedPolicy.allowedTools !== undefined ||
623
+ matchedPolicy.canSpawn !== undefined ||
624
+ matchedPolicy.canMessage !== undefined;
625
+ if (!hasRestrictions) {
626
+ return null; // No restrictions, no need to inform agent
627
+ }
628
+ const restrictions = [];
629
+ if (matchedPolicy.allowedTools) {
630
+ if (matchedPolicy.allowedTools.length === 1 && matchedPolicy.allowedTools[0] === 'none') {
631
+ restrictions.push('You are not allowed to use any tools.');
632
+ }
633
+ else {
634
+ restrictions.push(`You may only use these tools: ${matchedPolicy.allowedTools.join(', ')}.`);
635
+ }
636
+ }
637
+ if (matchedPolicy.canSpawn) {
638
+ if (matchedPolicy.canSpawn.length === 0) {
639
+ restrictions.push('You are not allowed to spawn other agents.');
640
+ }
641
+ else {
642
+ restrictions.push(`You may only spawn these agents: ${matchedPolicy.canSpawn.join(', ')}.`);
643
+ }
644
+ }
645
+ if (matchedPolicy.canMessage) {
646
+ if (matchedPolicy.canMessage.length === 0) {
647
+ restrictions.push('You are not allowed to message other agents.');
648
+ }
649
+ else {
650
+ restrictions.push(`You may only message these agents: ${matchedPolicy.canMessage.join(', ')}.`);
651
+ }
652
+ }
653
+ if (restrictions.length === 0) {
654
+ return null;
655
+ }
656
+ return `[Policy Restrictions]\n${restrictions.join('\n')}`;
657
+ }
658
+ }
659
+ /**
660
+ * Create a policy service for a project
661
+ */
662
+ export function createPolicyService(options) {
663
+ return new AgentPolicyService(options);
664
+ }
665
+ //# sourceMappingURL=agent-policy.js.map
@@ -0,0 +1,12 @@
1
+ /**
2
+ * Cloud Policy Fetcher
3
+ *
4
+ * Fetches workspace agent policies from the cloud API.
5
+ * Used by workspace containers to get their policy configuration.
6
+ */
7
+ import type { CloudPolicyFetcher } from './agent-policy.js';
8
+ /**
9
+ * Create a cloud policy fetcher for workspace containers
10
+ */
11
+ export declare function createCloudPolicyFetcher(): CloudPolicyFetcher | null;
12
+ //# sourceMappingURL=cloud-policy-fetcher.d.ts.map