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,500 @@
1
+ /**
2
+ * Ledger Store
3
+ *
4
+ * Persists within-session state as JSON files.
5
+ * One ledger per agent, overwritten each session.
6
+ *
7
+ * Features:
8
+ * - agentId index for O(1) lookups
9
+ * - Hash-based filenames to avoid collisions
10
+ * - File locking for concurrent access safety
11
+ */
12
+ import fs from 'node:fs/promises';
13
+ import path from 'node:path';
14
+ import crypto from 'node:crypto';
15
+ /** Lock expiry time in milliseconds (5 minutes) */
16
+ const LOCK_EXPIRY_MS = 5 * 60 * 1000;
17
+ export class LedgerStore {
18
+ basePath;
19
+ indexPath;
20
+ index = null;
21
+ locks = new Map();
22
+ indexLock = null; // Global lock for index operations
23
+ constructor(basePath) {
24
+ this.basePath = basePath;
25
+ this.indexPath = path.join(basePath, '_agent-id-index.json');
26
+ }
27
+ /**
28
+ * Ensure the ledgers directory exists
29
+ */
30
+ async initialize() {
31
+ await fs.mkdir(this.basePath, { recursive: true });
32
+ await this.loadIndex();
33
+ }
34
+ /**
35
+ * Generate a unique, collision-free filename from agent name
36
+ * Uses SHA-256 hash prefix + sanitized name for readability
37
+ */
38
+ getFilenameForAgent(agentName) {
39
+ // Create a short hash to ensure uniqueness
40
+ const hash = crypto.createHash('sha256').update(agentName).digest('hex').slice(0, 8);
41
+ // Also include sanitized name for human readability
42
+ const safeName = agentName.replace(/[^a-zA-Z0-9_-]/g, '_').slice(0, 32);
43
+ return `${safeName}_${hash}`;
44
+ }
45
+ /**
46
+ * Get the file path for an agent's ledger
47
+ */
48
+ getLedgerPath(agentName) {
49
+ const filename = this.getFilenameForAgent(agentName);
50
+ return path.join(this.basePath, `${filename}.json`);
51
+ }
52
+ /**
53
+ * Load the agentId index from disk
54
+ */
55
+ async loadIndex() {
56
+ try {
57
+ const content = await fs.readFile(this.indexPath, 'utf-8');
58
+ this.index = JSON.parse(content);
59
+ }
60
+ catch (error) {
61
+ if (error.code === 'ENOENT') {
62
+ this.index = {};
63
+ }
64
+ else {
65
+ throw error;
66
+ }
67
+ }
68
+ }
69
+ /**
70
+ * Save the agentId index to disk (atomic write)
71
+ */
72
+ async saveIndex() {
73
+ if (!this.index)
74
+ return;
75
+ const tempPath = `${this.indexPath}.tmp.${Date.now()}`;
76
+ await fs.writeFile(tempPath, JSON.stringify(this.index, null, 2), 'utf-8');
77
+ await fs.rename(tempPath, this.indexPath);
78
+ }
79
+ /**
80
+ * Acquire the global index lock
81
+ */
82
+ async acquireIndexLock() {
83
+ const startTime = Date.now();
84
+ const timeoutMs = 5000;
85
+ while (this.indexLock) {
86
+ // Check for expired lock
87
+ if (Date.now() - this.indexLock.acquiredAt > LOCK_EXPIRY_MS) {
88
+ this.indexLock.release();
89
+ this.indexLock = null;
90
+ break;
91
+ }
92
+ // Check timeout
93
+ if (Date.now() - startTime > timeoutMs) {
94
+ throw new Error('Index lock acquisition timeout');
95
+ }
96
+ // Wait briefly and retry
97
+ await new Promise((resolve) => setTimeout(resolve, 50));
98
+ }
99
+ let release = () => { };
100
+ const promise = new Promise((resolve) => {
101
+ release = resolve;
102
+ });
103
+ this.indexLock = { promise, release, acquiredAt: Date.now() };
104
+ return () => {
105
+ release();
106
+ this.indexLock = null;
107
+ };
108
+ }
109
+ /**
110
+ * Update the index with a new agentId -> agentName mapping (with locking)
111
+ */
112
+ async updateIndex(agentId, agentName) {
113
+ const releaseIndexLock = await this.acquireIndexLock();
114
+ try {
115
+ if (!this.index)
116
+ await this.loadIndex();
117
+ if (this.index) {
118
+ this.index[agentId] = agentName;
119
+ await this.saveIndex();
120
+ }
121
+ }
122
+ finally {
123
+ releaseIndexLock();
124
+ }
125
+ }
126
+ /**
127
+ * Remove an agentId from the index (with locking)
128
+ */
129
+ async removeFromIndex(agentId) {
130
+ const releaseIndexLock = await this.acquireIndexLock();
131
+ try {
132
+ if (!this.index)
133
+ await this.loadIndex();
134
+ if (this.index && this.index[agentId]) {
135
+ delete this.index[agentId];
136
+ await this.saveIndex();
137
+ }
138
+ }
139
+ finally {
140
+ releaseIndexLock();
141
+ }
142
+ }
143
+ /**
144
+ * Check and release expired locks
145
+ */
146
+ cleanupExpiredLocks() {
147
+ const now = Date.now();
148
+ for (const [key, lock] of this.locks.entries()) {
149
+ if (now - lock.acquiredAt > LOCK_EXPIRY_MS) {
150
+ lock.release();
151
+ this.locks.delete(key);
152
+ }
153
+ }
154
+ }
155
+ /**
156
+ * Acquire a lock for an agent's ledger with retry logic
157
+ * @param agentName - Agent name to lock
158
+ * @param maxRetries - Maximum number of retry attempts (default: 5)
159
+ * @param baseDelayMs - Base delay for exponential backoff (default: 100ms)
160
+ * @param timeoutMs - Maximum time to wait for lock (default: 10000ms)
161
+ */
162
+ async acquireLock(agentName, maxRetries = 5, baseDelayMs = 100, timeoutMs = 10000) {
163
+ const key = this.getFilenameForAgent(agentName);
164
+ const startTime = Date.now();
165
+ // Cleanup any expired locks first
166
+ this.cleanupExpiredLocks();
167
+ for (let attempt = 0; attempt <= maxRetries; attempt++) {
168
+ // Check timeout
169
+ if (Date.now() - startTime > timeoutMs) {
170
+ throw new Error(`Lock acquisition timeout for agent "${agentName}" after ${timeoutMs}ms`);
171
+ }
172
+ const existingLock = this.locks.get(key);
173
+ // Check if existing lock is expired
174
+ if (existingLock && Date.now() - existingLock.acquiredAt > LOCK_EXPIRY_MS) {
175
+ existingLock.release();
176
+ this.locks.delete(key);
177
+ }
178
+ if (!existingLock || Date.now() - existingLock.acquiredAt > LOCK_EXPIRY_MS) {
179
+ // Lock is available, acquire it
180
+ let release = () => { };
181
+ const promise = new Promise((resolve) => {
182
+ release = resolve;
183
+ });
184
+ this.locks.set(key, { promise, release, acquiredAt: Date.now() });
185
+ return () => {
186
+ release();
187
+ this.locks.delete(key);
188
+ };
189
+ }
190
+ // Lock is occupied, wait with exponential backoff
191
+ const delay = Math.min(baseDelayMs * Math.pow(2, attempt), 2000); // Cap at 2s
192
+ try {
193
+ // Race between lock release and timeout
194
+ await Promise.race([
195
+ existingLock.promise,
196
+ new Promise((_, reject) => setTimeout(() => reject(new Error('retry')), delay)),
197
+ ]);
198
+ }
199
+ catch {
200
+ // Timeout or retry, continue to next attempt
201
+ }
202
+ }
203
+ // Final attempt - wait for existing lock or throw
204
+ const existingLock = this.locks.get(key);
205
+ if (existingLock) {
206
+ const remainingTime = timeoutMs - (Date.now() - startTime);
207
+ if (remainingTime > 0) {
208
+ await Promise.race([
209
+ existingLock.promise,
210
+ new Promise((_, reject) => setTimeout(() => reject(new Error(`Lock acquisition timeout for agent "${agentName}"`)), remainingTime)),
211
+ ]);
212
+ }
213
+ else {
214
+ throw new Error(`Lock acquisition timeout for agent "${agentName}" after ${maxRetries} retries`);
215
+ }
216
+ }
217
+ // Lock should be available now
218
+ let release = () => { };
219
+ const promise = new Promise((resolve) => {
220
+ release = resolve;
221
+ });
222
+ this.locks.set(key, { promise, release, acquiredAt: Date.now() });
223
+ return () => {
224
+ release();
225
+ this.locks.delete(key);
226
+ };
227
+ }
228
+ /**
229
+ * Save a ledger for an agent (with locking)
230
+ */
231
+ async save(agentName, ledger) {
232
+ await this.initialize();
233
+ const releaseLock = await this.acquireLock(agentName);
234
+ try {
235
+ const filePath = this.getLedgerPath(agentName);
236
+ // Ensure updatedAt is set
237
+ const ledgerToSave = {
238
+ ...ledger,
239
+ agentName,
240
+ updatedAt: new Date(),
241
+ };
242
+ // Write to temp file first, then rename (atomic write)
243
+ const tempPath = `${filePath}.tmp.${Date.now()}`;
244
+ await fs.writeFile(tempPath, JSON.stringify(ledgerToSave, null, 2), 'utf-8');
245
+ await fs.rename(tempPath, filePath);
246
+ // Update agentId index
247
+ if (ledger.agentId) {
248
+ await this.updateIndex(ledger.agentId, agentName);
249
+ }
250
+ }
251
+ finally {
252
+ releaseLock();
253
+ }
254
+ }
255
+ /**
256
+ * Load a ledger for an agent
257
+ */
258
+ async load(agentName) {
259
+ const filePath = this.getLedgerPath(agentName);
260
+ try {
261
+ const content = await fs.readFile(filePath, 'utf-8');
262
+ const ledger = JSON.parse(content);
263
+ // Parse date strings back to Date objects
264
+ ledger.updatedAt = new Date(ledger.updatedAt);
265
+ if (ledger.keyDecisions) {
266
+ ledger.keyDecisions = ledger.keyDecisions.map((d) => ({
267
+ ...d,
268
+ timestamp: new Date(d.timestamp),
269
+ }));
270
+ }
271
+ return ledger;
272
+ }
273
+ catch (error) {
274
+ if (error.code === 'ENOENT') {
275
+ return null;
276
+ }
277
+ throw error;
278
+ }
279
+ }
280
+ /**
281
+ * Delete a ledger for an agent
282
+ */
283
+ async delete(agentName) {
284
+ const releaseLock = await this.acquireLock(agentName);
285
+ try {
286
+ // Load ledger to get agentId for index cleanup
287
+ const ledger = await this.load(agentName);
288
+ const filePath = this.getLedgerPath(agentName);
289
+ try {
290
+ await fs.unlink(filePath);
291
+ // Remove from index
292
+ if (ledger?.agentId) {
293
+ await this.removeFromIndex(ledger.agentId);
294
+ }
295
+ return true;
296
+ }
297
+ catch (error) {
298
+ if (error.code === 'ENOENT') {
299
+ return false;
300
+ }
301
+ throw error;
302
+ }
303
+ }
304
+ finally {
305
+ releaseLock();
306
+ }
307
+ }
308
+ /**
309
+ * Check if a ledger exists for an agent
310
+ */
311
+ async exists(agentName) {
312
+ const filePath = this.getLedgerPath(agentName);
313
+ try {
314
+ await fs.access(filePath);
315
+ return true;
316
+ }
317
+ catch {
318
+ return false;
319
+ }
320
+ }
321
+ /**
322
+ * List all agents with ledgers
323
+ */
324
+ async listAgents() {
325
+ try {
326
+ await this.initialize();
327
+ const files = await fs.readdir(this.basePath);
328
+ const agents = [];
329
+ for (const file of files) {
330
+ // Skip index file and non-JSON files
331
+ if (!file.endsWith('.json') || file.startsWith('_'))
332
+ continue;
333
+ try {
334
+ const filePath = path.join(this.basePath, file);
335
+ const content = await fs.readFile(filePath, 'utf-8');
336
+ const ledger = JSON.parse(content);
337
+ if (ledger.agentName) {
338
+ agents.push(ledger.agentName);
339
+ }
340
+ }
341
+ catch {
342
+ // Skip corrupted files
343
+ }
344
+ }
345
+ return agents;
346
+ }
347
+ catch (error) {
348
+ if (error.code === 'ENOENT') {
349
+ return [];
350
+ }
351
+ throw error;
352
+ }
353
+ }
354
+ /**
355
+ * Update specific fields in a ledger (merge, with locking)
356
+ */
357
+ async update(agentName, updates) {
358
+ const releaseLock = await this.acquireLock(agentName);
359
+ try {
360
+ const existing = await this.load(agentName);
361
+ if (!existing) {
362
+ return null;
363
+ }
364
+ const updated = {
365
+ ...existing,
366
+ ...updates,
367
+ agentName,
368
+ agentId: existing.agentId, // Preserve agentId
369
+ updatedAt: new Date(),
370
+ };
371
+ // Use internal save that doesn't acquire lock again
372
+ const filePath = this.getLedgerPath(agentName);
373
+ const tempPath = `${filePath}.tmp.${Date.now()}`;
374
+ await fs.writeFile(tempPath, JSON.stringify(updated, null, 2), 'utf-8');
375
+ await fs.rename(tempPath, filePath);
376
+ return updated;
377
+ }
378
+ finally {
379
+ releaseLock();
380
+ }
381
+ }
382
+ /**
383
+ * Add an item to a list field (completed, inProgress, etc.)
384
+ */
385
+ async addToList(agentName, field, item) {
386
+ const releaseLock = await this.acquireLock(agentName);
387
+ try {
388
+ const ledger = await this.load(agentName);
389
+ if (!ledger) {
390
+ return false;
391
+ }
392
+ if (!ledger[field].includes(item)) {
393
+ ledger[field].push(item);
394
+ const filePath = this.getLedgerPath(agentName);
395
+ const tempPath = `${filePath}.tmp.${Date.now()}`;
396
+ await fs.writeFile(tempPath, JSON.stringify({ ...ledger, updatedAt: new Date() }, null, 2), 'utf-8');
397
+ await fs.rename(tempPath, filePath);
398
+ }
399
+ return true;
400
+ }
401
+ finally {
402
+ releaseLock();
403
+ }
404
+ }
405
+ /**
406
+ * Add a decision to the ledger
407
+ */
408
+ async addDecision(agentName, decision) {
409
+ const releaseLock = await this.acquireLock(agentName);
410
+ try {
411
+ const ledger = await this.load(agentName);
412
+ if (!ledger) {
413
+ return false;
414
+ }
415
+ ledger.keyDecisions.push({
416
+ ...decision,
417
+ timestamp: new Date(),
418
+ });
419
+ const filePath = this.getLedgerPath(agentName);
420
+ const tempPath = `${filePath}.tmp.${Date.now()}`;
421
+ await fs.writeFile(tempPath, JSON.stringify({ ...ledger, updatedAt: new Date() }, null, 2), 'utf-8');
422
+ await fs.rename(tempPath, filePath);
423
+ return true;
424
+ }
425
+ finally {
426
+ releaseLock();
427
+ }
428
+ }
429
+ /**
430
+ * Create an empty ledger for an agent
431
+ */
432
+ async create(agentName, cli, sessionId, agentId) {
433
+ const ledger = {
434
+ agentName,
435
+ agentId,
436
+ sessionId,
437
+ cli,
438
+ currentTask: '',
439
+ completed: [],
440
+ inProgress: [],
441
+ blocked: [],
442
+ keyDecisions: [],
443
+ uncertainItems: [],
444
+ fileContext: [],
445
+ updatedAt: new Date(),
446
+ };
447
+ await this.save(agentName, ledger);
448
+ return ledger;
449
+ }
450
+ /**
451
+ * Find a ledger by agent ID (O(1) via index)
452
+ */
453
+ async findByAgentId(agentId) {
454
+ await this.initialize();
455
+ // Use index for O(1) lookup
456
+ if (this.index && this.index[agentId]) {
457
+ const agentName = this.index[agentId];
458
+ const ledger = await this.load(agentName);
459
+ // Verify the agentId still matches (index could be stale)
460
+ if (ledger && ledger.agentId === agentId) {
461
+ return ledger;
462
+ }
463
+ // Index is stale, remove it
464
+ await this.removeFromIndex(agentId);
465
+ }
466
+ // Fallback: scan all ledgers (and rebuild index)
467
+ const agents = await this.listAgents();
468
+ for (const agentName of agents) {
469
+ const ledger = await this.load(agentName);
470
+ if (ledger && ledger.agentId === agentId) {
471
+ // Update index for future lookups
472
+ await this.updateIndex(agentId, agentName);
473
+ return ledger;
474
+ }
475
+ }
476
+ return null;
477
+ }
478
+ /**
479
+ * Rebuild the agentId index from all ledgers
480
+ */
481
+ async rebuildIndex() {
482
+ await this.initialize();
483
+ const releaseIndexLock = await this.acquireIndexLock();
484
+ try {
485
+ this.index = {};
486
+ const agents = await this.listAgents();
487
+ for (const agentName of agents) {
488
+ const ledger = await this.load(agentName);
489
+ if (ledger?.agentId) {
490
+ this.index[ledger.agentId] = agentName;
491
+ }
492
+ }
493
+ await this.saveIndex();
494
+ }
495
+ finally {
496
+ releaseIndexLock();
497
+ }
498
+ }
499
+ }
500
+ //# sourceMappingURL=ledger-store.js.map
@@ -0,0 +1,178 @@
1
+ /**
2
+ * Continuity Manager
3
+ *
4
+ * Central service for managing session continuity.
5
+ * Coordinates ledger storage, handoff creation, and context injection.
6
+ */
7
+ import { type ParsedHandoffContent } from './parser.js';
8
+ import type { Ledger, Handoff, HandoffTrigger, ContinuityPaths, StartupContext, SaveLedgerOptions, SearchOptions, ContinuityCommand } from './types.js';
9
+ /**
10
+ * Options for ContinuityManager
11
+ */
12
+ export interface ContinuityManagerOptions {
13
+ /** Base directory for continuity data (default: ~/.agent-relay/continuity) */
14
+ basePath?: string;
15
+ /** Default CLI type for new ledgers */
16
+ defaultCli?: string;
17
+ }
18
+ /**
19
+ * ContinuityManager - Central service for session continuity
20
+ */
21
+ export declare class ContinuityManager {
22
+ private paths;
23
+ private ledgerStore;
24
+ private handoffStore;
25
+ private defaultCli;
26
+ private initialized;
27
+ constructor(options?: ContinuityManagerOptions);
28
+ /**
29
+ * Initialize the continuity system (create directories)
30
+ */
31
+ initialize(): Promise<void>;
32
+ /**
33
+ * Generate a session ID
34
+ */
35
+ private generateSessionId;
36
+ /**
37
+ * Generate a unique agent ID using UUID v4
38
+ */
39
+ generateAgentId(): string;
40
+ /**
41
+ * Get or create a ledger for an agent
42
+ */
43
+ getOrCreateLedger(agentName: string, cli?: string, agentId?: string): Promise<Ledger>;
44
+ /**
45
+ * Find a ledger by agent ID (for resume functionality)
46
+ */
47
+ findLedgerByAgentId(agentId: string): Promise<Ledger | null>;
48
+ /**
49
+ * Get a ledger for an agent (returns null if not exists)
50
+ */
51
+ getLedger(agentName: string): Promise<Ledger | null>;
52
+ /**
53
+ * Save a ledger, optionally creating a handoff
54
+ */
55
+ saveLedger(agentName: string, content: string | Partial<Ledger>, options?: SaveLedgerOptions): Promise<Ledger>;
56
+ /**
57
+ * Update specific fields in a ledger
58
+ */
59
+ updateLedger(agentName: string, updates: Partial<Omit<Ledger, 'agentName' | 'updatedAt'>>): Promise<Ledger | null>;
60
+ /**
61
+ * Add an uncertain item to the ledger
62
+ */
63
+ addUncertainItem(agentName: string, item: string): Promise<boolean>;
64
+ /**
65
+ * Delete a ledger
66
+ */
67
+ deleteLedger(agentName: string): Promise<boolean>;
68
+ /**
69
+ * Create a handoff from a ledger
70
+ */
71
+ createHandoffFromLedger(ledger: Ledger, triggerReason: HandoffTrigger): Promise<Handoff>;
72
+ /**
73
+ * Create a handoff from parsed content
74
+ */
75
+ createHandoff(agentName: string, content: string | ParsedHandoffContent, triggerReason?: HandoffTrigger): Promise<Handoff>;
76
+ /**
77
+ * Get the latest handoff for an agent
78
+ */
79
+ getLatestHandoff(agentName: string): Promise<Handoff | null>;
80
+ /**
81
+ * Get a handoff by ID
82
+ */
83
+ getHandoff(handoffId: string): Promise<Handoff | null>;
84
+ /**
85
+ * List handoffs for an agent
86
+ */
87
+ listHandoffs(agentName: string, limit?: number): Promise<Handoff[]>;
88
+ /**
89
+ * Search handoffs (basic text search - FTS to be added)
90
+ */
91
+ searchHandoffs(query: string, options?: SearchOptions): Promise<Handoff[]>;
92
+ /**
93
+ * Get startup context for an agent (for injection on spawn).
94
+ * Applies defensive filtering to remove any placeholder values.
95
+ */
96
+ getStartupContext(agentName: string): Promise<StartupContext | null>;
97
+ /**
98
+ * Filter placeholder values from a ledger (defensive)
99
+ */
100
+ private filterLedgerPlaceholders;
101
+ /**
102
+ * Filter placeholder values from a handoff (defensive)
103
+ */
104
+ private filterHandoffPlaceholders;
105
+ /**
106
+ * Format a ledger for display/injection
107
+ */
108
+ formatLedger(ledger: Ledger, compact?: boolean): string;
109
+ /**
110
+ * Format a handoff for display/injection
111
+ */
112
+ formatHandoff(handoff: Handoff, compact?: boolean): string;
113
+ /**
114
+ * Format search results
115
+ */
116
+ formatSearchResults(handoffs: Handoff[], query: string): string;
117
+ /**
118
+ * Get a brief status summary
119
+ */
120
+ getBriefStatus(agentName: string): Promise<string>;
121
+ /**
122
+ * Handle a continuity command from agent output
123
+ */
124
+ handleCommand(agentName: string, command: ContinuityCommand): Promise<string | null>;
125
+ /**
126
+ * Auto-save current state (called by wrapper on agent exit)
127
+ * @param agentName - Name of the agent
128
+ * @param reason - Why the save is happening
129
+ * @param sessionEndData - Optional data from [[SESSION_END]] block to populate handoff
130
+ */
131
+ autoSave(agentName: string, reason: 'crash' | 'restart' | 'session_end', sessionEndData?: {
132
+ summary?: string;
133
+ completedTasks?: string[];
134
+ }): Promise<void>;
135
+ /**
136
+ * Clean placeholder data from all ledgers.
137
+ * Removes known placeholder/template values that were incorrectly saved.
138
+ * Returns the number of ledgers that were cleaned.
139
+ */
140
+ cleanupPlaceholders(): Promise<{
141
+ cleaned: number;
142
+ agents: string[];
143
+ }>;
144
+ /**
145
+ * Clear all continuity data for an agent
146
+ */
147
+ clearAgent(agentName: string): Promise<void>;
148
+ /**
149
+ * List all agents with continuity data
150
+ */
151
+ listAgents(): Promise<string[]>;
152
+ /**
153
+ * Get continuity paths
154
+ */
155
+ getPaths(): ContinuityPaths;
156
+ }
157
+ /**
158
+ * Get the singleton ContinuityManager instance (sync version)
159
+ *
160
+ * Note: This is safe for most uses since ContinuityManager methods
161
+ * call initialize() internally. The race condition only matters
162
+ * if multiple calls happen before the first completes AND they
163
+ * pass different options (which is unlikely in practice).
164
+ */
165
+ export declare function getContinuityManager(options?: ContinuityManagerOptions): ContinuityManager;
166
+ /**
167
+ * Get the singleton ContinuityManager instance (async version)
168
+ *
169
+ * This is the thread-safe version that ensures only one instance
170
+ * is created even with concurrent calls. Use this in async contexts
171
+ * where race conditions are possible.
172
+ */
173
+ export declare function getContinuityManagerAsync(options?: ContinuityManagerOptions): Promise<ContinuityManager>;
174
+ /**
175
+ * Reset the singleton instance (for testing)
176
+ */
177
+ export declare function resetContinuityManager(): void;
178
+ //# sourceMappingURL=manager.d.ts.map