agent-relay 2.0.28 → 2.0.32

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 (894) hide show
  1. package/README.md +19 -0
  2. package/dist/index.cjs +85691 -0
  3. package/dist/src/bridge/index.d.ts.map +1 -0
  4. package/dist/src/bridge/index.js.map +1 -0
  5. package/dist/src/cli/commands/doctor.d.ts +2 -0
  6. package/dist/src/cli/commands/doctor.d.ts.map +1 -0
  7. package/dist/src/cli/commands/doctor.js +451 -0
  8. package/dist/src/cli/commands/doctor.js.map +1 -0
  9. package/dist/src/cli/index.d.ts.map +1 -0
  10. package/dist/src/cli/index.js +29 -1
  11. package/dist/src/cli/index.js.map +1 -0
  12. package/dist/src/config/relay-config.d.ts.map +1 -0
  13. package/dist/src/config/relay-config.js.map +1 -0
  14. package/dist/src/continuity/index.d.ts.map +1 -0
  15. package/dist/src/continuity/index.js.map +1 -0
  16. package/dist/src/daemon/index.d.ts.map +1 -0
  17. package/dist/src/daemon/index.js.map +1 -0
  18. package/dist/src/health-worker-manager.d.ts.map +1 -0
  19. package/dist/src/health-worker-manager.js.map +1 -0
  20. package/dist/src/health-worker.d.ts.map +1 -0
  21. package/dist/src/health-worker.js.map +1 -0
  22. package/dist/src/hooks/index.d.ts.map +1 -0
  23. package/dist/src/hooks/index.js.map +1 -0
  24. package/dist/src/index.d.ts.map +1 -0
  25. package/dist/src/index.js.map +1 -0
  26. package/dist/src/memory/index.d.ts.map +1 -0
  27. package/dist/src/memory/index.js.map +1 -0
  28. package/dist/src/policy/index.d.ts.map +1 -0
  29. package/dist/src/policy/index.js.map +1 -0
  30. package/dist/src/protocol/index.d.ts.map +1 -0
  31. package/dist/src/protocol/index.js.map +1 -0
  32. package/dist/src/resiliency/index.d.ts.map +1 -0
  33. package/dist/src/resiliency/index.js.map +1 -0
  34. package/dist/src/shared/cli-auth-config.d.ts.map +1 -0
  35. package/dist/src/shared/cli-auth-config.js.map +1 -0
  36. package/dist/src/state/index.d.ts.map +1 -0
  37. package/dist/src/state/index.js.map +1 -0
  38. package/dist/src/storage/index.d.ts.map +1 -0
  39. package/dist/src/storage/index.js.map +1 -0
  40. package/dist/src/trajectory/index.d.ts.map +1 -0
  41. package/dist/src/trajectory/index.js.map +1 -0
  42. package/dist/src/utils/index.d.ts.map +1 -0
  43. package/dist/src/utils/index.js.map +1 -0
  44. package/dist/src/wrapper/index.d.ts.map +1 -0
  45. package/dist/src/wrapper/index.js.map +1 -0
  46. package/package.json +83 -20
  47. package/packages/api-types/dist/index.d.ts.map +1 -0
  48. package/packages/api-types/dist/index.js.map +1 -0
  49. package/packages/api-types/dist/schemas/agent.d.ts.map +1 -0
  50. package/packages/api-types/dist/schemas/agent.js.map +1 -0
  51. package/packages/api-types/dist/schemas/api.d.ts.map +1 -0
  52. package/packages/api-types/dist/schemas/api.js.map +1 -0
  53. package/packages/api-types/dist/schemas/decision.d.ts.map +1 -0
  54. package/packages/api-types/dist/schemas/decision.js.map +1 -0
  55. package/packages/api-types/dist/schemas/fleet.d.ts.map +1 -0
  56. package/packages/api-types/dist/schemas/fleet.js.map +1 -0
  57. package/packages/api-types/dist/schemas/history.d.ts.map +1 -0
  58. package/packages/api-types/dist/schemas/history.js.map +1 -0
  59. package/packages/api-types/dist/schemas/index.d.ts.map +1 -0
  60. package/packages/api-types/dist/schemas/index.js.map +1 -0
  61. package/packages/api-types/dist/schemas/message.d.ts.map +1 -0
  62. package/packages/api-types/dist/schemas/message.js.map +1 -0
  63. package/packages/api-types/dist/schemas/session.d.ts.map +1 -0
  64. package/packages/api-types/dist/schemas/session.js.map +1 -0
  65. package/packages/api-types/dist/schemas/task.d.ts.map +1 -0
  66. package/packages/api-types/dist/schemas/task.js.map +1 -0
  67. package/packages/api-types/package.json +1 -1
  68. package/packages/api-types/src/index.ts +22 -0
  69. package/packages/api-types/src/schemas/agent.test.ts +164 -0
  70. package/packages/api-types/src/schemas/agent.ts +110 -0
  71. package/packages/api-types/src/schemas/api.test.ts +372 -0
  72. package/packages/api-types/src/schemas/api.ts +194 -0
  73. package/packages/api-types/src/schemas/decision.test.ts +324 -0
  74. package/packages/api-types/src/schemas/decision.ts +136 -0
  75. package/packages/api-types/src/schemas/fleet.test.ts +212 -0
  76. package/packages/api-types/src/schemas/fleet.ts +83 -0
  77. package/packages/api-types/src/schemas/history.test.ts +242 -0
  78. package/packages/api-types/src/schemas/history.ts +84 -0
  79. package/packages/api-types/src/schemas/index.ts +148 -0
  80. package/packages/api-types/src/schemas/message.test.ts +192 -0
  81. package/packages/api-types/src/schemas/message.ts +98 -0
  82. package/packages/api-types/src/schemas/session.test.ts +104 -0
  83. package/packages/api-types/src/schemas/session.ts +40 -0
  84. package/packages/api-types/src/schemas/task.test.ts +192 -0
  85. package/packages/api-types/src/schemas/task.ts +78 -0
  86. package/packages/api-types/tsconfig.json +19 -0
  87. package/packages/api-types/vitest.config.ts +9 -0
  88. package/packages/benchmark/README.md +200 -0
  89. package/packages/benchmark/datasets/coding-tasks.yaml +127 -0
  90. package/packages/benchmark/datasets/coordination-tasks.yaml +122 -0
  91. package/packages/benchmark/dist/benchmark.d.ts +47 -0
  92. package/packages/benchmark/dist/benchmark.d.ts.map +1 -0
  93. package/packages/benchmark/dist/benchmark.js +224 -0
  94. package/packages/benchmark/dist/benchmark.js.map +1 -0
  95. package/packages/benchmark/dist/cli.d.ts +8 -0
  96. package/packages/benchmark/dist/cli.d.ts.map +1 -0
  97. package/packages/benchmark/dist/cli.js +185 -0
  98. package/packages/benchmark/dist/cli.js.map +1 -0
  99. package/packages/benchmark/dist/harbor.d.ts +53 -0
  100. package/packages/benchmark/dist/harbor.d.ts.map +1 -0
  101. package/packages/benchmark/dist/harbor.js +127 -0
  102. package/packages/benchmark/dist/harbor.js.map +1 -0
  103. package/packages/benchmark/dist/index.d.ts +48 -0
  104. package/packages/benchmark/dist/index.d.ts.map +1 -0
  105. package/packages/benchmark/dist/index.js +50 -0
  106. package/packages/benchmark/dist/index.js.map +1 -0
  107. package/packages/benchmark/dist/runners/base.d.ts +63 -0
  108. package/packages/benchmark/dist/runners/base.d.ts.map +1 -0
  109. package/packages/benchmark/dist/runners/base.js +155 -0
  110. package/packages/benchmark/dist/runners/base.js.map +1 -0
  111. package/packages/benchmark/dist/runners/index.d.ts +10 -0
  112. package/packages/benchmark/dist/runners/index.d.ts.map +1 -0
  113. package/packages/benchmark/dist/runners/index.js +10 -0
  114. package/packages/benchmark/dist/runners/index.js.map +1 -0
  115. package/packages/benchmark/dist/runners/single.d.ts +19 -0
  116. package/packages/benchmark/dist/runners/single.d.ts.map +1 -0
  117. package/packages/benchmark/dist/runners/single.js +111 -0
  118. package/packages/benchmark/dist/runners/single.js.map +1 -0
  119. package/packages/benchmark/dist/runners/subagent.d.ts +32 -0
  120. package/packages/benchmark/dist/runners/subagent.d.ts.map +1 -0
  121. package/packages/benchmark/dist/runners/subagent.js +212 -0
  122. package/packages/benchmark/dist/runners/subagent.js.map +1 -0
  123. package/packages/benchmark/dist/runners/swarm.d.ts +36 -0
  124. package/packages/benchmark/dist/runners/swarm.d.ts.map +1 -0
  125. package/packages/benchmark/dist/runners/swarm.js +273 -0
  126. package/packages/benchmark/dist/runners/swarm.js.map +1 -0
  127. package/packages/benchmark/dist/types.d.ts +178 -0
  128. package/packages/benchmark/dist/types.d.ts.map +1 -0
  129. package/packages/benchmark/dist/types.js +16 -0
  130. package/packages/benchmark/dist/types.js.map +1 -0
  131. package/packages/benchmark/package.json +80 -0
  132. package/packages/benchmark/src/benchmark.ts +298 -0
  133. package/packages/benchmark/src/cli.ts +240 -0
  134. package/packages/benchmark/src/harbor.ts +170 -0
  135. package/packages/benchmark/src/index.ts +73 -0
  136. package/packages/benchmark/src/runners/base.ts +204 -0
  137. package/packages/benchmark/src/runners/index.ts +10 -0
  138. package/packages/benchmark/src/runners/single.ts +121 -0
  139. package/packages/benchmark/src/runners/subagent.ts +240 -0
  140. package/packages/benchmark/src/runners/swarm.ts +326 -0
  141. package/packages/benchmark/src/types.ts +205 -0
  142. package/packages/benchmark/tsconfig.json +20 -0
  143. package/packages/bridge/dist/index.d.ts.map +1 -0
  144. package/packages/bridge/dist/index.js.map +1 -0
  145. package/packages/bridge/dist/multi-project-client.d.ts.map +1 -0
  146. package/packages/bridge/dist/multi-project-client.js.map +1 -0
  147. package/packages/bridge/dist/shadow-cli.d.ts.map +1 -0
  148. package/packages/bridge/dist/shadow-cli.js.map +1 -0
  149. package/packages/bridge/dist/spawner.d.ts.map +1 -0
  150. package/packages/bridge/dist/spawner.js +15 -2
  151. package/packages/bridge/dist/spawner.js.map +1 -0
  152. package/packages/bridge/dist/types.d.ts.map +1 -0
  153. package/packages/bridge/dist/types.js.map +1 -0
  154. package/packages/bridge/dist/utils.d.ts.map +1 -0
  155. package/packages/bridge/dist/utils.js.map +1 -0
  156. package/packages/bridge/package.json +8 -8
  157. package/packages/bridge/src/index.ts +25 -0
  158. package/packages/bridge/src/multi-project-client.test.ts +340 -0
  159. package/packages/bridge/src/multi-project-client.ts +469 -0
  160. package/packages/bridge/src/shadow-cli.ts +95 -0
  161. package/packages/bridge/src/spawner-mcp.test.ts +505 -0
  162. package/packages/bridge/src/spawner.ts +1724 -0
  163. package/packages/bridge/src/types.ts +145 -0
  164. package/packages/bridge/src/utils.test.ts +98 -0
  165. package/packages/bridge/src/utils.ts +67 -0
  166. package/packages/bridge/tsconfig.json +29 -0
  167. package/packages/bridge/vitest.config.ts +9 -0
  168. package/packages/cli-tester/dist/index.d.ts.map +1 -0
  169. package/packages/cli-tester/dist/index.js.map +1 -0
  170. package/packages/cli-tester/dist/utils/credential-check.d.ts.map +1 -0
  171. package/packages/cli-tester/dist/utils/credential-check.js.map +1 -0
  172. package/packages/cli-tester/dist/utils/socket-client.d.ts.map +1 -0
  173. package/packages/cli-tester/dist/utils/socket-client.js.map +1 -0
  174. package/packages/cli-tester/docker/Dockerfile +61 -0
  175. package/packages/cli-tester/docker/docker-compose.yml +71 -0
  176. package/packages/cli-tester/package.json +1 -1
  177. package/packages/cli-tester/src/index.ts +40 -0
  178. package/packages/cli-tester/src/utils/credential-check.ts +284 -0
  179. package/packages/cli-tester/src/utils/socket-client.ts +211 -0
  180. package/packages/cli-tester/tests/credential-check.test.ts +56 -0
  181. package/packages/cli-tester/tsconfig.json +11 -0
  182. package/packages/config/dist/agent-config.d.ts.map +1 -0
  183. package/packages/config/dist/agent-config.js.map +1 -0
  184. package/packages/config/dist/bridge-config.d.ts.map +1 -0
  185. package/packages/config/dist/bridge-config.js.map +1 -0
  186. package/packages/config/dist/bridge-utils.d.ts.map +1 -0
  187. package/packages/config/dist/bridge-utils.js.map +1 -0
  188. package/packages/config/dist/cli-auth-config.d.ts.map +1 -0
  189. package/packages/config/dist/cli-auth-config.js.map +1 -0
  190. package/packages/config/dist/cloud-config.d.ts.map +1 -0
  191. package/packages/config/dist/cloud-config.js.map +1 -0
  192. package/packages/config/dist/index.d.ts.map +1 -0
  193. package/packages/config/dist/index.js.map +1 -0
  194. package/packages/config/dist/project-namespace.d.ts.map +1 -0
  195. package/packages/config/dist/project-namespace.js.map +1 -0
  196. package/packages/config/dist/relay-config.d.ts.map +1 -0
  197. package/packages/config/dist/relay-config.js.map +1 -0
  198. package/packages/config/dist/relay-file-writer.d.ts.map +1 -0
  199. package/packages/config/dist/relay-file-writer.js.map +1 -0
  200. package/packages/config/dist/schemas.d.ts.map +1 -0
  201. package/packages/config/dist/schemas.js.map +1 -0
  202. package/packages/config/dist/shadow-config.d.ts.map +1 -0
  203. package/packages/config/dist/shadow-config.js.map +1 -0
  204. package/packages/config/dist/teams-config.d.ts.map +1 -0
  205. package/packages/config/dist/teams-config.js.map +1 -0
  206. package/packages/config/dist/trajectory-config.d.ts.map +1 -0
  207. package/packages/config/dist/trajectory-config.js.map +1 -0
  208. package/packages/config/package.json +2 -2
  209. package/packages/config/src/agent-config.test.ts +245 -0
  210. package/packages/config/src/agent-config.ts +160 -0
  211. package/packages/config/src/bridge-config.test.ts +132 -0
  212. package/packages/config/src/bridge-config.ts +189 -0
  213. package/packages/config/src/bridge-utils.ts +59 -0
  214. package/packages/config/src/cli-auth-config.ts +548 -0
  215. package/packages/config/src/cloud-config.ts +208 -0
  216. package/packages/config/src/index.ts +12 -0
  217. package/packages/config/src/project-namespace.ts +344 -0
  218. package/packages/config/src/relay-config.test.ts +51 -0
  219. package/packages/config/src/relay-config.ts +36 -0
  220. package/packages/config/src/relay-file-writer.test.ts +351 -0
  221. package/packages/config/src/relay-file-writer.ts +508 -0
  222. package/packages/config/src/schemas.test.ts +59 -0
  223. package/packages/config/src/schemas.ts +201 -0
  224. package/packages/config/src/shadow-config.ts +205 -0
  225. package/packages/config/src/teams-config.ts +135 -0
  226. package/packages/config/src/trajectory-config.ts +222 -0
  227. package/packages/config/tsconfig.json +21 -0
  228. package/packages/config/vitest.config.ts +9 -0
  229. package/packages/continuity/dist/formatter.d.ts.map +1 -0
  230. package/packages/continuity/dist/formatter.js.map +1 -0
  231. package/packages/continuity/dist/handoff-store.d.ts.map +1 -0
  232. package/packages/continuity/dist/handoff-store.js.map +1 -0
  233. package/packages/continuity/dist/index.d.ts.map +1 -0
  234. package/packages/continuity/dist/index.js.map +1 -0
  235. package/packages/continuity/dist/ledger-store.d.ts.map +1 -0
  236. package/packages/continuity/dist/ledger-store.js.map +1 -0
  237. package/packages/continuity/dist/manager.d.ts.map +1 -0
  238. package/packages/continuity/dist/manager.js.map +1 -0
  239. package/packages/continuity/dist/parser.d.ts.map +1 -0
  240. package/packages/continuity/dist/parser.js.map +1 -0
  241. package/packages/continuity/dist/types.d.ts.map +1 -0
  242. package/packages/continuity/dist/types.js.map +1 -0
  243. package/packages/continuity/package.json +1 -1
  244. package/packages/continuity/src/formatter.ts +371 -0
  245. package/packages/continuity/src/handoff-store.ts +523 -0
  246. package/packages/continuity/src/index.ts +9 -0
  247. package/packages/continuity/src/ledger-store.ts +594 -0
  248. package/packages/continuity/src/manager.test.ts +291 -0
  249. package/packages/continuity/src/manager.ts +774 -0
  250. package/packages/continuity/src/parser.test.ts +292 -0
  251. package/packages/continuity/src/parser.ts +680 -0
  252. package/packages/continuity/src/types.ts +211 -0
  253. package/packages/continuity/tsconfig.json +21 -0
  254. package/packages/continuity/vitest.config.ts +9 -0
  255. package/packages/daemon/dist/agent-manager.d.ts.map +1 -0
  256. package/packages/daemon/dist/agent-manager.js.map +1 -0
  257. package/packages/daemon/dist/agent-registry.d.ts.map +1 -0
  258. package/packages/daemon/dist/agent-registry.js.map +1 -0
  259. package/packages/daemon/dist/agent-signing.d.ts.map +1 -0
  260. package/packages/daemon/dist/agent-signing.js.map +1 -0
  261. package/packages/daemon/dist/api.d.ts.map +1 -0
  262. package/packages/daemon/dist/api.js.map +1 -0
  263. package/packages/daemon/dist/auth.d.ts.map +1 -0
  264. package/packages/daemon/dist/auth.js.map +1 -0
  265. package/packages/daemon/dist/channel-membership-store.d.ts.map +1 -0
  266. package/packages/daemon/dist/channel-membership-store.js.map +1 -0
  267. package/packages/daemon/dist/cli-auth.d.ts.map +1 -0
  268. package/packages/daemon/dist/cli-auth.js.map +1 -0
  269. package/packages/daemon/dist/cloud-sync.d.ts.map +1 -0
  270. package/packages/daemon/dist/cloud-sync.js.map +1 -0
  271. package/packages/daemon/dist/connection.d.ts.map +1 -0
  272. package/packages/daemon/dist/connection.js.map +1 -0
  273. package/packages/daemon/dist/consensus-integration.d.ts.map +1 -0
  274. package/packages/daemon/dist/consensus-integration.js.map +1 -0
  275. package/packages/daemon/dist/consensus.d.ts.map +1 -0
  276. package/packages/daemon/dist/consensus.js.map +1 -0
  277. package/packages/daemon/dist/delivery-tracker.d.ts.map +1 -0
  278. package/packages/daemon/dist/delivery-tracker.js.map +1 -0
  279. package/packages/daemon/dist/enhanced-features.d.ts.map +1 -0
  280. package/packages/daemon/dist/enhanced-features.js.map +1 -0
  281. package/packages/daemon/dist/index.d.ts.map +1 -0
  282. package/packages/daemon/dist/index.js.map +1 -0
  283. package/packages/daemon/dist/migrations/index.d.ts.map +1 -0
  284. package/packages/daemon/dist/migrations/index.js.map +1 -0
  285. package/packages/daemon/dist/orchestrator.d.ts.map +1 -0
  286. package/packages/daemon/dist/orchestrator.js.map +1 -0
  287. package/packages/daemon/dist/rate-limiter.d.ts.map +1 -0
  288. package/packages/daemon/dist/rate-limiter.js.map +1 -0
  289. package/packages/daemon/dist/registry.d.ts.map +1 -0
  290. package/packages/daemon/dist/registry.js.map +1 -0
  291. package/packages/daemon/dist/relay-ledger.d.ts.map +1 -0
  292. package/packages/daemon/dist/relay-ledger.js.map +1 -0
  293. package/packages/daemon/dist/relay-watchdog.d.ts.map +1 -0
  294. package/packages/daemon/dist/relay-watchdog.js.map +1 -0
  295. package/packages/daemon/dist/repo-manager.d.ts.map +1 -0
  296. package/packages/daemon/dist/repo-manager.js.map +1 -0
  297. package/packages/daemon/dist/router.d.ts.map +1 -0
  298. package/packages/daemon/dist/router.js.map +1 -0
  299. package/packages/daemon/dist/server.d.ts +1 -0
  300. package/packages/daemon/dist/server.d.ts.map +1 -0
  301. package/packages/daemon/dist/server.js +46 -16
  302. package/packages/daemon/dist/server.js.map +1 -0
  303. package/packages/daemon/dist/spawn-manager.d.ts.map +1 -0
  304. package/packages/daemon/dist/spawn-manager.js.map +1 -0
  305. package/packages/daemon/dist/sync-queue.d.ts.map +1 -0
  306. package/packages/daemon/dist/sync-queue.js.map +1 -0
  307. package/packages/daemon/dist/types.d.ts.map +1 -0
  308. package/packages/daemon/dist/types.js.map +1 -0
  309. package/packages/daemon/dist/workspace-manager.d.ts.map +1 -0
  310. package/packages/daemon/dist/workspace-manager.js.map +1 -0
  311. package/packages/daemon/package.json +12 -12
  312. package/packages/daemon/src/agent-manager.ts +679 -0
  313. package/packages/daemon/src/agent-registry.ts +284 -0
  314. package/packages/daemon/src/agent-signing.ts +707 -0
  315. package/packages/daemon/src/api.ts +1012 -0
  316. package/packages/daemon/src/auth.ts +276 -0
  317. package/packages/daemon/src/channel-membership-store.ts +217 -0
  318. package/packages/daemon/src/cli-auth.ts +906 -0
  319. package/packages/daemon/src/cloud-sync.ts +902 -0
  320. package/packages/daemon/src/connection.ts +534 -0
  321. package/packages/daemon/src/consensus-integration.ts +510 -0
  322. package/packages/daemon/src/consensus.ts +848 -0
  323. package/packages/daemon/src/delivery-tracker.ts +145 -0
  324. package/packages/daemon/src/enhanced-features.ts +390 -0
  325. package/packages/daemon/src/index.ts +52 -0
  326. package/packages/daemon/src/migrations/0001_initial.sql +72 -0
  327. package/packages/daemon/src/migrations/index.test.ts +195 -0
  328. package/packages/daemon/src/migrations/index.ts +286 -0
  329. package/packages/daemon/src/orchestrator.test.ts +231 -0
  330. package/packages/daemon/src/orchestrator.ts +1376 -0
  331. package/packages/daemon/src/rate-limiter.ts +172 -0
  332. package/packages/daemon/src/registry.ts +8 -0
  333. package/packages/daemon/src/relay-ledger.test.ts +358 -0
  334. package/packages/daemon/src/relay-ledger.ts +713 -0
  335. package/packages/daemon/src/relay-watchdog.test.ts +881 -0
  336. package/packages/daemon/src/relay-watchdog.ts +785 -0
  337. package/packages/daemon/src/repo-manager.ts +468 -0
  338. package/packages/daemon/src/router.test.ts +149 -0
  339. package/packages/daemon/src/router.ts +1885 -0
  340. package/packages/daemon/src/server.ts +1871 -0
  341. package/packages/daemon/src/spawn-manager.ts +275 -0
  342. package/packages/daemon/src/sync-queue.ts +477 -0
  343. package/packages/daemon/src/types.ts +158 -0
  344. package/packages/daemon/src/workspace-manager.ts +371 -0
  345. package/packages/daemon/tsconfig.json +21 -0
  346. package/packages/hooks/dist/browser.d.ts.map +1 -0
  347. package/packages/hooks/dist/browser.js.map +1 -0
  348. package/packages/hooks/dist/emitter.d.ts.map +1 -0
  349. package/packages/hooks/dist/emitter.js.map +1 -0
  350. package/packages/hooks/dist/inbox-check/hook.d.ts.map +1 -0
  351. package/packages/hooks/dist/inbox-check/hook.js.map +1 -0
  352. package/packages/hooks/dist/inbox-check/index.d.ts.map +1 -0
  353. package/packages/hooks/dist/inbox-check/index.js.map +1 -0
  354. package/packages/hooks/dist/inbox-check/types.d.ts.map +1 -0
  355. package/packages/hooks/dist/inbox-check/types.js.map +1 -0
  356. package/packages/hooks/dist/inbox-check/utils.d.ts.map +1 -0
  357. package/packages/hooks/dist/inbox-check/utils.js.map +1 -0
  358. package/packages/hooks/dist/index.d.ts.map +1 -0
  359. package/packages/hooks/dist/index.js.map +1 -0
  360. package/packages/hooks/dist/registry.d.ts.map +1 -0
  361. package/packages/hooks/dist/registry.js.map +1 -0
  362. package/packages/hooks/dist/trajectory-hooks.d.ts.map +1 -0
  363. package/packages/hooks/dist/trajectory-hooks.js.map +1 -0
  364. package/packages/hooks/dist/types.d.ts.map +1 -0
  365. package/packages/hooks/dist/types.js.map +1 -0
  366. package/packages/hooks/package.json +4 -4
  367. package/packages/hooks/src/browser.ts +2 -0
  368. package/packages/hooks/src/emitter.ts +84 -0
  369. package/packages/hooks/src/inbox-check/hook.ts +114 -0
  370. package/packages/hooks/src/inbox-check/index.ts +8 -0
  371. package/packages/hooks/src/inbox-check/types.ts +39 -0
  372. package/packages/hooks/src/inbox-check/utils.test.ts +287 -0
  373. package/packages/hooks/src/inbox-check/utils.ts +125 -0
  374. package/packages/hooks/src/index.ts +11 -0
  375. package/packages/hooks/src/registry.ts +614 -0
  376. package/packages/hooks/src/shims.d.ts +3 -0
  377. package/packages/hooks/src/trajectory-hooks.ts +251 -0
  378. package/packages/hooks/src/types.ts +342 -0
  379. package/packages/hooks/tsconfig.json +21 -0
  380. package/packages/hooks/vitest.config.ts +9 -0
  381. package/packages/mcp/dist/bin.d.ts.map +1 -0
  382. package/packages/mcp/dist/bin.js.map +1 -0
  383. package/packages/mcp/dist/client.d.ts +9 -15
  384. package/packages/mcp/dist/client.d.ts.map +1 -0
  385. package/packages/mcp/dist/client.js +42 -74
  386. package/packages/mcp/dist/client.js.map +1 -0
  387. package/packages/mcp/dist/cloud.d.ts.map +1 -0
  388. package/packages/mcp/dist/cloud.js.map +1 -0
  389. package/packages/mcp/dist/errors.d.ts.map +1 -0
  390. package/packages/mcp/dist/errors.js.map +1 -0
  391. package/packages/mcp/dist/file-transport.d.ts.map +1 -0
  392. package/packages/mcp/dist/file-transport.js.map +1 -0
  393. package/packages/mcp/dist/hybrid-client.d.ts.map +1 -0
  394. package/packages/mcp/dist/hybrid-client.js.map +1 -0
  395. package/packages/mcp/dist/index.d.ts.map +1 -0
  396. package/packages/mcp/dist/index.js.map +1 -0
  397. package/packages/mcp/dist/install-cli.d.ts.map +1 -0
  398. package/packages/mcp/dist/install-cli.js.map +1 -0
  399. package/packages/mcp/dist/install.d.ts.map +1 -0
  400. package/packages/mcp/dist/install.js.map +1 -0
  401. package/packages/mcp/dist/prompts/index.d.ts.map +1 -0
  402. package/packages/mcp/dist/prompts/index.js.map +1 -0
  403. package/packages/mcp/dist/prompts/protocol.d.ts.map +1 -0
  404. package/packages/mcp/dist/prompts/protocol.js.map +1 -0
  405. package/packages/mcp/dist/resources/agents.d.ts.map +1 -0
  406. package/packages/mcp/dist/resources/agents.js.map +1 -0
  407. package/packages/mcp/dist/resources/inbox.d.ts.map +1 -0
  408. package/packages/mcp/dist/resources/inbox.js.map +1 -0
  409. package/packages/mcp/dist/resources/index.d.ts.map +1 -0
  410. package/packages/mcp/dist/resources/index.js.map +1 -0
  411. package/packages/mcp/dist/resources/project.d.ts.map +1 -0
  412. package/packages/mcp/dist/resources/project.js.map +1 -0
  413. package/packages/mcp/dist/server.d.ts.map +1 -0
  414. package/packages/mcp/dist/server.js.map +1 -0
  415. package/packages/mcp/dist/simple.d.ts +2 -5
  416. package/packages/mcp/dist/simple.d.ts.map +1 -0
  417. package/packages/mcp/dist/simple.js.map +1 -0
  418. package/packages/mcp/dist/tools/index.d.ts.map +1 -0
  419. package/packages/mcp/dist/tools/index.js.map +1 -0
  420. package/packages/mcp/dist/tools/relay-broadcast.d.ts.map +1 -0
  421. package/packages/mcp/dist/tools/relay-broadcast.js.map +1 -0
  422. package/packages/mcp/dist/tools/relay-channel.d.ts.map +1 -0
  423. package/packages/mcp/dist/tools/relay-channel.js.map +1 -0
  424. package/packages/mcp/dist/tools/relay-connected.d.ts.map +1 -0
  425. package/packages/mcp/dist/tools/relay-connected.js.map +1 -0
  426. package/packages/mcp/dist/tools/relay-consensus.d.ts.map +1 -0
  427. package/packages/mcp/dist/tools/relay-consensus.js.map +1 -0
  428. package/packages/mcp/dist/tools/relay-continuity.d.ts.map +1 -0
  429. package/packages/mcp/dist/tools/relay-continuity.js.map +1 -0
  430. package/packages/mcp/dist/tools/relay-health.d.ts.map +1 -0
  431. package/packages/mcp/dist/tools/relay-health.js.map +1 -0
  432. package/packages/mcp/dist/tools/relay-inbox.d.ts.map +1 -0
  433. package/packages/mcp/dist/tools/relay-inbox.js.map +1 -0
  434. package/packages/mcp/dist/tools/relay-logs.d.ts.map +1 -0
  435. package/packages/mcp/dist/tools/relay-logs.js.map +1 -0
  436. package/packages/mcp/dist/tools/relay-metrics.d.ts.map +1 -0
  437. package/packages/mcp/dist/tools/relay-metrics.js.map +1 -0
  438. package/packages/mcp/dist/tools/relay-release.d.ts.map +1 -0
  439. package/packages/mcp/dist/tools/relay-release.js.map +1 -0
  440. package/packages/mcp/dist/tools/relay-remove-agent.d.ts.map +1 -0
  441. package/packages/mcp/dist/tools/relay-remove-agent.js.map +1 -0
  442. package/packages/mcp/dist/tools/relay-send.d.ts.map +1 -0
  443. package/packages/mcp/dist/tools/relay-send.js +4 -2
  444. package/packages/mcp/dist/tools/relay-send.js.map +1 -0
  445. package/packages/mcp/dist/tools/relay-shadow.d.ts.map +1 -0
  446. package/packages/mcp/dist/tools/relay-shadow.js.map +1 -0
  447. package/packages/mcp/dist/tools/relay-spawn.d.ts.map +1 -0
  448. package/packages/mcp/dist/tools/relay-spawn.js.map +1 -0
  449. package/packages/mcp/dist/tools/relay-status.d.ts.map +1 -0
  450. package/packages/mcp/dist/tools/relay-status.js.map +1 -0
  451. package/packages/mcp/dist/tools/relay-subscribe.d.ts.map +1 -0
  452. package/packages/mcp/dist/tools/relay-subscribe.js.map +1 -0
  453. package/packages/mcp/dist/tools/relay-who.d.ts.map +1 -0
  454. package/packages/mcp/dist/tools/relay-who.js.map +1 -0
  455. package/packages/mcp/package.json +3 -3
  456. package/packages/mcp/src/bin.ts +149 -0
  457. package/packages/mcp/src/client.ts +400 -0
  458. package/packages/mcp/src/cloud.ts +523 -0
  459. package/packages/mcp/src/errors.ts +54 -0
  460. package/packages/mcp/src/file-transport.ts +268 -0
  461. package/packages/mcp/src/hybrid-client.ts +209 -0
  462. package/packages/mcp/src/index.ts +122 -0
  463. package/packages/mcp/src/install-cli.ts +210 -0
  464. package/packages/mcp/src/install.ts +745 -0
  465. package/packages/mcp/src/prompts/index.ts +1 -0
  466. package/packages/mcp/src/prompts/protocol.ts +164 -0
  467. package/packages/mcp/src/resources/agents.ts +21 -0
  468. package/packages/mcp/src/resources/inbox.ts +21 -0
  469. package/packages/mcp/src/resources/index.ts +3 -0
  470. package/packages/mcp/src/resources/project.ts +29 -0
  471. package/packages/mcp/src/server.ts +431 -0
  472. package/packages/mcp/src/simple.ts +214 -0
  473. package/packages/mcp/src/tools/index.ts +133 -0
  474. package/packages/mcp/src/tools/relay-broadcast.ts +32 -0
  475. package/packages/mcp/src/tools/relay-channel.ts +93 -0
  476. package/packages/mcp/src/tools/relay-connected.ts +52 -0
  477. package/packages/mcp/src/tools/relay-consensus.ts +92 -0
  478. package/packages/mcp/src/tools/relay-continuity.ts +127 -0
  479. package/packages/mcp/src/tools/relay-health.ts +148 -0
  480. package/packages/mcp/src/tools/relay-inbox.ts +70 -0
  481. package/packages/mcp/src/tools/relay-logs.ts +106 -0
  482. package/packages/mcp/src/tools/relay-metrics.ts +140 -0
  483. package/packages/mcp/src/tools/relay-release.ts +54 -0
  484. package/packages/mcp/src/tools/relay-remove-agent.ts +58 -0
  485. package/packages/mcp/src/tools/relay-send.ts +84 -0
  486. package/packages/mcp/src/tools/relay-shadow.ts +67 -0
  487. package/packages/mcp/src/tools/relay-spawn.ts +87 -0
  488. package/packages/mcp/src/tools/relay-status.ts +57 -0
  489. package/packages/mcp/src/tools/relay-subscribe.ts +61 -0
  490. package/packages/mcp/src/tools/relay-who.ts +59 -0
  491. package/packages/mcp/tests/client.test.ts +476 -0
  492. package/packages/mcp/tests/discover.test.ts +195 -0
  493. package/packages/mcp/tests/install.test.ts +123 -0
  494. package/packages/mcp/tests/prompts.test.ts +12 -0
  495. package/packages/mcp/tests/resources.test.ts +53 -0
  496. package/packages/mcp/tests/tools.test.ts +1242 -0
  497. package/packages/mcp/tsconfig.json +22 -0
  498. package/packages/mcp/vitest.config.ts +9 -0
  499. package/packages/memory/dist/adapters/index.d.ts.map +1 -0
  500. package/packages/memory/dist/adapters/index.js.map +1 -0
  501. package/packages/memory/dist/adapters/inmemory.d.ts.map +1 -0
  502. package/packages/memory/dist/adapters/inmemory.js.map +1 -0
  503. package/packages/memory/dist/adapters/supermemory.d.ts.map +1 -0
  504. package/packages/memory/dist/adapters/supermemory.js.map +1 -0
  505. package/packages/memory/dist/context-compaction.d.ts.map +1 -0
  506. package/packages/memory/dist/context-compaction.js.map +1 -0
  507. package/packages/memory/dist/factory.d.ts.map +1 -0
  508. package/packages/memory/dist/factory.js.map +1 -0
  509. package/packages/memory/dist/index.d.ts.map +1 -0
  510. package/packages/memory/dist/index.js.map +1 -0
  511. package/packages/memory/dist/memory-hooks.d.ts.map +1 -0
  512. package/packages/memory/dist/memory-hooks.js.map +1 -0
  513. package/packages/memory/dist/service.d.ts.map +1 -0
  514. package/packages/memory/dist/service.js.map +1 -0
  515. package/packages/memory/dist/types.d.ts.map +1 -0
  516. package/packages/memory/dist/types.js.map +1 -0
  517. package/packages/memory/package.json +2 -2
  518. package/packages/memory/src/adapters/index.ts +8 -0
  519. package/packages/memory/src/adapters/inmemory.ts +265 -0
  520. package/packages/memory/src/adapters/supermemory.ts +449 -0
  521. package/packages/memory/src/context-compaction.test.ts +660 -0
  522. package/packages/memory/src/context-compaction.ts +612 -0
  523. package/packages/memory/src/factory.ts +170 -0
  524. package/packages/memory/src/index.ts +33 -0
  525. package/packages/memory/src/memory-hooks.ts +410 -0
  526. package/packages/memory/src/service.ts +194 -0
  527. package/packages/memory/src/types.ts +211 -0
  528. package/packages/memory/tsconfig.json +21 -0
  529. package/packages/memory/vitest.config.ts +9 -0
  530. package/packages/policy/dist/agent-policy.d.ts.map +1 -0
  531. package/packages/policy/dist/agent-policy.js.map +1 -0
  532. package/packages/policy/dist/cloud-policy-fetcher.d.ts.map +1 -0
  533. package/packages/policy/dist/cloud-policy-fetcher.js.map +1 -0
  534. package/packages/policy/dist/index.d.ts.map +1 -0
  535. package/packages/policy/dist/index.js.map +1 -0
  536. package/packages/policy/package.json +2 -2
  537. package/packages/policy/src/agent-policy.ts +866 -0
  538. package/packages/policy/src/cloud-policy-fetcher.ts +78 -0
  539. package/packages/policy/src/index.ts +21 -0
  540. package/packages/policy/tsconfig.json +21 -0
  541. package/packages/policy/vitest.config.ts +9 -0
  542. package/packages/protocol/dist/channels.d.ts.map +1 -0
  543. package/packages/protocol/dist/channels.js.map +1 -0
  544. package/packages/protocol/dist/framing.d.ts.map +1 -0
  545. package/packages/protocol/dist/framing.js.map +1 -0
  546. package/packages/protocol/dist/id-generator.d.ts.map +1 -0
  547. package/packages/protocol/dist/id-generator.js.map +1 -0
  548. package/packages/protocol/dist/index.d.ts.map +1 -0
  549. package/packages/protocol/dist/index.js.map +1 -0
  550. package/packages/protocol/dist/relay-pty-schemas.d.ts +70 -2
  551. package/packages/protocol/dist/relay-pty-schemas.d.ts.map +1 -0
  552. package/packages/protocol/dist/relay-pty-schemas.js.map +1 -0
  553. package/packages/protocol/dist/types.d.ts +8 -0
  554. package/packages/protocol/dist/types.d.ts.map +1 -0
  555. package/packages/protocol/dist/types.js.map +1 -0
  556. package/packages/protocol/package.json +1 -1
  557. package/packages/protocol/src/channels.test.ts +330 -0
  558. package/packages/protocol/src/channels.ts +270 -0
  559. package/packages/protocol/src/framing.test.ts +164 -0
  560. package/packages/protocol/src/framing.ts +242 -0
  561. package/packages/protocol/src/id-generator.ts +69 -0
  562. package/packages/protocol/src/index.ts +4 -0
  563. package/packages/protocol/src/relay-pty-schemas.ts +400 -0
  564. package/packages/protocol/src/types.test.ts +271 -0
  565. package/packages/protocol/src/types.ts +846 -0
  566. package/packages/protocol/tsconfig.json +21 -0
  567. package/packages/protocol/vitest.config.ts +9 -0
  568. package/packages/resiliency/dist/cgroup-manager.d.ts.map +1 -0
  569. package/packages/resiliency/dist/cgroup-manager.js.map +1 -0
  570. package/packages/resiliency/dist/context-persistence.d.ts.map +1 -0
  571. package/packages/resiliency/dist/context-persistence.js.map +1 -0
  572. package/packages/resiliency/dist/crash-insights.d.ts.map +1 -0
  573. package/packages/resiliency/dist/crash-insights.js.map +1 -0
  574. package/packages/resiliency/dist/gossip-health.d.ts.map +1 -0
  575. package/packages/resiliency/dist/gossip-health.js.map +1 -0
  576. package/packages/resiliency/dist/health-monitor.d.ts.map +1 -0
  577. package/packages/resiliency/dist/health-monitor.js.map +1 -0
  578. package/packages/resiliency/dist/index.d.ts.map +1 -0
  579. package/packages/resiliency/dist/index.js.map +1 -0
  580. package/packages/resiliency/dist/leader-watchdog.d.ts.map +1 -0
  581. package/packages/resiliency/dist/leader-watchdog.js.map +1 -0
  582. package/packages/resiliency/dist/logger.d.ts.map +1 -0
  583. package/packages/resiliency/dist/logger.js.map +1 -0
  584. package/packages/resiliency/dist/memory-monitor.d.ts.map +1 -0
  585. package/packages/resiliency/dist/memory-monitor.js.map +1 -0
  586. package/packages/resiliency/dist/metrics.d.ts.map +1 -0
  587. package/packages/resiliency/dist/metrics.js.map +1 -0
  588. package/packages/resiliency/dist/provider-context.d.ts.map +1 -0
  589. package/packages/resiliency/dist/provider-context.js.map +1 -0
  590. package/packages/resiliency/dist/stateless-lead.d.ts.map +1 -0
  591. package/packages/resiliency/dist/stateless-lead.js.map +1 -0
  592. package/packages/resiliency/dist/supervisor.d.ts.map +1 -0
  593. package/packages/resiliency/dist/supervisor.js.map +1 -0
  594. package/packages/resiliency/package.json +1 -1
  595. package/packages/resiliency/src/cgroup-manager.ts +468 -0
  596. package/packages/resiliency/src/context-persistence.ts +538 -0
  597. package/packages/resiliency/src/crash-insights.test.ts +620 -0
  598. package/packages/resiliency/src/crash-insights.ts +660 -0
  599. package/packages/resiliency/src/gossip-health.ts +333 -0
  600. package/packages/resiliency/src/health-monitor.ts +371 -0
  601. package/packages/resiliency/src/index.ts +157 -0
  602. package/packages/resiliency/src/leader-watchdog.ts +260 -0
  603. package/packages/resiliency/src/logger.ts +320 -0
  604. package/packages/resiliency/src/memory-monitor.test.ts +637 -0
  605. package/packages/resiliency/src/memory-monitor.ts +740 -0
  606. package/packages/resiliency/src/metrics.ts +311 -0
  607. package/packages/resiliency/src/provider-context.ts +452 -0
  608. package/packages/resiliency/src/stateless-lead.ts +408 -0
  609. package/packages/resiliency/src/supervisor.ts +578 -0
  610. package/packages/resiliency/tsconfig.json +21 -0
  611. package/packages/resiliency/vitest.config.ts +9 -0
  612. package/packages/sdk/dist/client.d.ts.map +1 -0
  613. package/packages/sdk/dist/client.js.map +1 -0
  614. package/packages/sdk/dist/index.d.ts.map +1 -0
  615. package/packages/sdk/dist/index.js.map +1 -0
  616. package/packages/sdk/dist/logs.d.ts.map +1 -0
  617. package/packages/sdk/dist/logs.js.map +1 -0
  618. package/packages/sdk/dist/protocol/index.d.ts.map +1 -0
  619. package/packages/sdk/dist/protocol/index.js.map +1 -0
  620. package/packages/sdk/dist/standalone.d.ts.map +1 -0
  621. package/packages/sdk/dist/standalone.js.map +1 -0
  622. package/packages/sdk/examples/SWARM_CAPABILITIES.md +498 -0
  623. package/packages/sdk/examples/SWARM_PATTERNS.md +541 -0
  624. package/packages/sdk/package.json +2 -2
  625. package/packages/sdk/src/client.test.ts +568 -0
  626. package/packages/sdk/src/client.ts +1418 -0
  627. package/packages/sdk/src/index.ts +103 -0
  628. package/packages/sdk/src/logs.test.ts +98 -0
  629. package/packages/sdk/src/logs.ts +126 -0
  630. package/packages/sdk/src/protocol/framing.test.ts +164 -0
  631. package/packages/sdk/src/protocol/index.ts +8 -0
  632. package/packages/sdk/src/standalone.ts +176 -0
  633. package/packages/sdk/tsconfig.json +22 -0
  634. package/packages/sdk/vitest.config.ts +9 -0
  635. package/packages/spawner/.trajectories/index.json +5 -0
  636. package/packages/spawner/dist/index.d.ts.map +1 -0
  637. package/packages/spawner/dist/index.js.map +1 -0
  638. package/packages/spawner/dist/types.d.ts.map +1 -0
  639. package/packages/spawner/dist/types.js.map +1 -0
  640. package/packages/spawner/package.json +1 -1
  641. package/packages/spawner/src/index.ts +8 -0
  642. package/packages/spawner/src/types.test.ts +385 -0
  643. package/packages/spawner/src/types.ts +228 -0
  644. package/packages/spawner/tsconfig.json +19 -0
  645. package/packages/spawner/vitest.config.ts +9 -0
  646. package/packages/state/dist/agent-state.d.ts.map +1 -0
  647. package/packages/state/dist/agent-state.js.map +1 -0
  648. package/packages/state/dist/index.d.ts.map +1 -0
  649. package/packages/state/dist/index.js.map +1 -0
  650. package/packages/state/package.json +1 -1
  651. package/packages/state/src/agent-state.test.ts +335 -0
  652. package/packages/state/src/agent-state.ts +153 -0
  653. package/packages/state/src/index.ts +12 -0
  654. package/packages/state/tsconfig.json +21 -0
  655. package/packages/state/vitest.config.ts +9 -0
  656. package/packages/storage/dist/adapter.d.ts +28 -1
  657. package/packages/storage/dist/adapter.d.ts.map +1 -0
  658. package/packages/storage/dist/adapter.js +104 -10
  659. package/packages/storage/dist/adapter.js.map +1 -0
  660. package/packages/storage/dist/batched-sqlite-adapter.d.ts.map +1 -0
  661. package/packages/storage/dist/batched-sqlite-adapter.js.map +1 -0
  662. package/packages/storage/dist/dead-letter-queue.d.ts.map +1 -0
  663. package/packages/storage/dist/dead-letter-queue.js.map +1 -0
  664. package/packages/storage/dist/dlq-adapter.d.ts.map +1 -0
  665. package/packages/storage/dist/dlq-adapter.js.map +1 -0
  666. package/packages/storage/dist/index.d.ts +1 -0
  667. package/packages/storage/dist/index.d.ts.map +1 -0
  668. package/packages/storage/dist/index.js +1 -0
  669. package/packages/storage/dist/index.js.map +1 -0
  670. package/packages/storage/dist/jsonl-adapter.d.ts +77 -0
  671. package/packages/storage/dist/jsonl-adapter.d.ts.map +1 -0
  672. package/packages/storage/dist/jsonl-adapter.js +505 -0
  673. package/packages/storage/dist/jsonl-adapter.js.map +1 -0
  674. package/packages/storage/dist/sqlite-adapter.d.ts +6 -1
  675. package/packages/storage/dist/sqlite-adapter.d.ts.map +1 -0
  676. package/packages/storage/dist/sqlite-adapter.js +47 -0
  677. package/packages/storage/dist/sqlite-adapter.js.map +1 -0
  678. package/packages/storage/package.json +2 -2
  679. package/packages/storage/src/adapter.ts +438 -0
  680. package/packages/storage/src/batched-sqlite-adapter.test.ts +240 -0
  681. package/packages/storage/src/batched-sqlite-adapter.ts +239 -0
  682. package/packages/storage/src/dead-letter-queue.ts +643 -0
  683. package/packages/storage/src/dlq-adapter.test.ts +492 -0
  684. package/packages/storage/src/dlq-adapter.ts +954 -0
  685. package/packages/storage/src/index.ts +6 -0
  686. package/packages/storage/src/jsonl-adapter.test.ts +200 -0
  687. package/packages/storage/src/jsonl-adapter.ts +618 -0
  688. package/packages/storage/src/memory-adapter.test.ts +36 -0
  689. package/packages/storage/src/sqlite-adapter.test.ts +562 -0
  690. package/packages/storage/src/sqlite-adapter.ts +1058 -0
  691. package/packages/storage/tsconfig.json +21 -0
  692. package/packages/storage/vitest.config.ts +9 -0
  693. package/packages/telemetry/dist/client.d.ts.map +1 -0
  694. package/packages/telemetry/dist/client.js.map +1 -0
  695. package/packages/telemetry/dist/config.d.ts.map +1 -0
  696. package/packages/telemetry/dist/config.js.map +1 -0
  697. package/packages/telemetry/dist/events.d.ts.map +1 -0
  698. package/packages/telemetry/dist/events.js.map +1 -0
  699. package/packages/telemetry/dist/index.d.ts.map +1 -0
  700. package/packages/telemetry/dist/index.js.map +1 -0
  701. package/packages/telemetry/dist/machine-id.d.ts.map +1 -0
  702. package/packages/telemetry/dist/machine-id.js.map +1 -0
  703. package/packages/telemetry/dist/posthog-config.d.ts.map +1 -0
  704. package/packages/telemetry/dist/posthog-config.js.map +1 -0
  705. package/packages/telemetry/package.json +1 -1
  706. package/packages/telemetry/src/client.ts +158 -0
  707. package/packages/telemetry/src/config.ts +110 -0
  708. package/packages/telemetry/src/events.ts +137 -0
  709. package/packages/telemetry/src/index.ts +46 -0
  710. package/packages/telemetry/src/machine-id.ts +63 -0
  711. package/packages/telemetry/src/posthog-config.ts +39 -0
  712. package/packages/telemetry/tsconfig.json +21 -0
  713. package/packages/trajectory/dist/index.d.ts.map +1 -0
  714. package/packages/trajectory/dist/index.js.map +1 -0
  715. package/packages/trajectory/dist/integration.d.ts.map +1 -0
  716. package/packages/trajectory/dist/integration.js.map +1 -0
  717. package/packages/trajectory/package.json +2 -2
  718. package/packages/trajectory/src/index.ts +1 -0
  719. package/packages/trajectory/src/integration.ts +1268 -0
  720. package/packages/trajectory/tsconfig.json +21 -0
  721. package/packages/trajectory/vitest.config.ts +9 -0
  722. package/packages/user-directory/dist/index.d.ts.map +1 -0
  723. package/packages/user-directory/dist/index.js.map +1 -0
  724. package/packages/user-directory/dist/user-directory.d.ts.map +1 -0
  725. package/packages/user-directory/dist/user-directory.js.map +1 -0
  726. package/packages/user-directory/package.json +2 -2
  727. package/packages/user-directory/src/index.ts +12 -0
  728. package/packages/user-directory/src/user-directory.ts +393 -0
  729. package/packages/user-directory/tsconfig.json +21 -0
  730. package/packages/user-directory/vitest.config.ts +9 -0
  731. package/packages/utils/dist/cjs/client-helpers.js +127 -0
  732. package/packages/utils/dist/cjs/command-resolver.js +89 -0
  733. package/packages/utils/dist/cjs/error-tracking.js +106 -0
  734. package/packages/utils/dist/cjs/git-remote.js +120 -0
  735. package/packages/utils/dist/cjs/index.js +40 -0
  736. package/packages/utils/dist/cjs/logger.js +105 -0
  737. package/packages/utils/dist/cjs/model-mapping.js +54 -0
  738. package/packages/utils/dist/cjs/name-generator.js +179 -0
  739. package/packages/utils/dist/cjs/package.json +3 -0
  740. package/packages/utils/dist/cjs/precompiled-patterns.js +271 -0
  741. package/packages/utils/dist/cjs/relay-pty-path.js +143 -0
  742. package/packages/utils/dist/cjs/update-checker.js +185 -0
  743. package/packages/utils/dist/client-helpers.d.ts +73 -0
  744. package/packages/utils/dist/client-helpers.d.ts.map +1 -0
  745. package/packages/utils/dist/client-helpers.js +130 -0
  746. package/packages/utils/dist/client-helpers.js.map +1 -0
  747. package/packages/utils/dist/command-resolver.d.ts.map +1 -0
  748. package/packages/utils/dist/command-resolver.js.map +1 -0
  749. package/packages/utils/dist/error-tracking.d.ts.map +1 -0
  750. package/packages/utils/dist/error-tracking.js.map +1 -0
  751. package/packages/utils/dist/git-remote.d.ts.map +1 -0
  752. package/packages/utils/dist/git-remote.js.map +1 -0
  753. package/packages/utils/dist/index.d.ts +1 -0
  754. package/packages/utils/dist/index.d.ts.map +1 -0
  755. package/packages/utils/dist/index.js +1 -0
  756. package/packages/utils/dist/index.js.map +1 -0
  757. package/packages/utils/dist/logger.d.ts.map +1 -0
  758. package/packages/utils/dist/logger.js.map +1 -0
  759. package/packages/utils/dist/model-mapping.d.ts.map +1 -0
  760. package/packages/utils/dist/model-mapping.js.map +1 -0
  761. package/packages/utils/dist/name-generator.d.ts.map +1 -0
  762. package/packages/utils/dist/name-generator.js.map +1 -0
  763. package/packages/utils/dist/precompiled-patterns.d.ts.map +1 -0
  764. package/packages/utils/dist/precompiled-patterns.js.map +1 -0
  765. package/packages/utils/dist/relay-pty-path.d.ts +11 -5
  766. package/packages/utils/dist/relay-pty-path.d.ts.map +1 -0
  767. package/packages/utils/dist/relay-pty-path.js +60 -5
  768. package/packages/utils/dist/relay-pty-path.js.map +1 -0
  769. package/packages/utils/dist/update-checker.d.ts.map +1 -0
  770. package/packages/utils/dist/update-checker.js.map +1 -0
  771. package/packages/utils/package.json +37 -14
  772. package/packages/utils/scripts/build-cjs.mjs +24 -0
  773. package/packages/utils/src/client-helpers.ts +221 -0
  774. package/packages/utils/src/command-resolver.ts +82 -0
  775. package/packages/utils/src/error-tracking.ts +189 -0
  776. package/packages/utils/src/git-remote.ts +143 -0
  777. package/packages/utils/src/index.ts +10 -0
  778. package/packages/utils/src/logger.ts +107 -0
  779. package/packages/utils/src/model-mapping.test.ts +122 -0
  780. package/packages/utils/src/model-mapping.ts +58 -0
  781. package/packages/utils/src/name-generator.test.ts +259 -0
  782. package/packages/utils/src/name-generator.ts +56 -0
  783. package/packages/utils/src/precompiled-patterns.test.ts +452 -0
  784. package/packages/utils/src/precompiled-patterns.ts +395 -0
  785. package/packages/utils/src/relay-pty-path.ts +196 -0
  786. package/packages/utils/src/update-checker.test.ts +260 -0
  787. package/packages/utils/src/update-checker.ts +211 -0
  788. package/packages/utils/tsconfig.json +21 -0
  789. package/packages/utils/vitest.config.ts +9 -0
  790. package/packages/wrapper/dist/__fixtures__/claude-outputs.d.ts.map +1 -0
  791. package/packages/wrapper/dist/__fixtures__/claude-outputs.js.map +1 -0
  792. package/packages/wrapper/dist/__fixtures__/codex-outputs.d.ts.map +1 -0
  793. package/packages/wrapper/dist/__fixtures__/codex-outputs.js.map +1 -0
  794. package/packages/wrapper/dist/__fixtures__/gemini-outputs.d.ts.map +1 -0
  795. package/packages/wrapper/dist/__fixtures__/gemini-outputs.js.map +1 -0
  796. package/packages/wrapper/dist/__fixtures__/index.d.ts.map +1 -0
  797. package/packages/wrapper/dist/__fixtures__/index.js.map +1 -0
  798. package/packages/wrapper/dist/auth-detection.d.ts.map +1 -0
  799. package/packages/wrapper/dist/auth-detection.js.map +1 -0
  800. package/packages/wrapper/dist/base-wrapper.d.ts.map +1 -0
  801. package/packages/wrapper/dist/base-wrapper.js.map +1 -0
  802. package/packages/wrapper/dist/client.d.ts.map +1 -0
  803. package/packages/wrapper/dist/client.js.map +1 -0
  804. package/packages/wrapper/dist/id-generator.d.ts.map +1 -0
  805. package/packages/wrapper/dist/id-generator.js.map +1 -0
  806. package/packages/wrapper/dist/idle-detector.d.ts.map +1 -0
  807. package/packages/wrapper/dist/idle-detector.js.map +1 -0
  808. package/packages/wrapper/dist/inbox.d.ts.map +1 -0
  809. package/packages/wrapper/dist/inbox.js.map +1 -0
  810. package/packages/wrapper/dist/index.d.ts.map +1 -0
  811. package/packages/wrapper/dist/index.js.map +1 -0
  812. package/packages/wrapper/dist/parser.d.ts.map +1 -0
  813. package/packages/wrapper/dist/parser.js.map +1 -0
  814. package/packages/wrapper/dist/prompt-composer.d.ts.map +1 -0
  815. package/packages/wrapper/dist/prompt-composer.js.map +1 -0
  816. package/packages/wrapper/dist/relay-pty-orchestrator.d.ts +10 -0
  817. package/packages/wrapper/dist/relay-pty-orchestrator.d.ts.map +1 -0
  818. package/packages/wrapper/dist/relay-pty-orchestrator.js +69 -0
  819. package/packages/wrapper/dist/relay-pty-orchestrator.js.map +1 -0
  820. package/packages/wrapper/dist/shared.d.ts.map +1 -0
  821. package/packages/wrapper/dist/shared.js.map +1 -0
  822. package/packages/wrapper/dist/stuck-detector.d.ts.map +1 -0
  823. package/packages/wrapper/dist/stuck-detector.js.map +1 -0
  824. package/packages/wrapper/dist/tmux-resolver.d.ts.map +1 -0
  825. package/packages/wrapper/dist/tmux-resolver.js.map +1 -0
  826. package/packages/wrapper/dist/tmux-wrapper.d.ts.map +1 -0
  827. package/packages/wrapper/dist/tmux-wrapper.js.map +1 -0
  828. package/packages/wrapper/dist/trajectory-integration.d.ts.map +1 -0
  829. package/packages/wrapper/dist/trajectory-integration.js.map +1 -0
  830. package/packages/wrapper/dist/wrapper-types.d.ts.map +1 -0
  831. package/packages/wrapper/dist/wrapper-types.js.map +1 -0
  832. package/packages/wrapper/package.json +6 -9
  833. package/packages/wrapper/src/__fixtures__/claude-outputs.ts +471 -0
  834. package/packages/wrapper/src/__fixtures__/codex-outputs.ts +99 -0
  835. package/packages/wrapper/src/__fixtures__/gemini-outputs.ts +151 -0
  836. package/packages/wrapper/src/__fixtures__/index.ts +47 -0
  837. package/packages/wrapper/src/auth-detection.ts +244 -0
  838. package/packages/wrapper/src/base-wrapper.test.ts +589 -0
  839. package/packages/wrapper/src/base-wrapper.ts +810 -0
  840. package/packages/wrapper/src/client.test.ts +262 -0
  841. package/packages/wrapper/src/client.ts +984 -0
  842. package/packages/wrapper/src/id-generator.test.ts +71 -0
  843. package/packages/wrapper/src/id-generator.ts +69 -0
  844. package/packages/wrapper/src/idle-detector.test.ts +418 -0
  845. package/packages/wrapper/src/idle-detector.ts +384 -0
  846. package/packages/wrapper/src/inbox.test.ts +233 -0
  847. package/packages/wrapper/src/inbox.ts +89 -0
  848. package/packages/wrapper/src/index.ts +170 -0
  849. package/packages/wrapper/src/parser.regression.test.ts +251 -0
  850. package/packages/wrapper/src/parser.test.ts +1359 -0
  851. package/packages/wrapper/src/parser.ts +1477 -0
  852. package/packages/wrapper/src/prompt-composer.test.ts +219 -0
  853. package/packages/wrapper/src/prompt-composer.ts +231 -0
  854. package/packages/wrapper/src/relay-pty-orchestrator.test.ts +1204 -0
  855. package/packages/wrapper/src/relay-pty-orchestrator.ts +2626 -0
  856. package/packages/wrapper/src/shared.test.ts +322 -0
  857. package/packages/wrapper/src/shared.ts +495 -0
  858. package/packages/wrapper/src/stuck-detector.test.ts +303 -0
  859. package/packages/wrapper/src/stuck-detector.ts +511 -0
  860. package/packages/wrapper/src/tmux-resolver.test.ts +104 -0
  861. package/packages/wrapper/src/tmux-resolver.ts +207 -0
  862. package/packages/wrapper/src/tmux-wrapper.test.ts +316 -0
  863. package/packages/wrapper/src/tmux-wrapper.ts +2095 -0
  864. package/packages/wrapper/src/trajectory-detection.test.ts +151 -0
  865. package/packages/wrapper/src/trajectory-integration.ts +1261 -0
  866. package/packages/wrapper/src/wrapper-types.ts +45 -0
  867. package/packages/wrapper/tsconfig.json +19 -0
  868. package/packages/wrapper/vitest.config.ts +9 -0
  869. package/scripts/build-cjs.mjs +23 -0
  870. package/scripts/postinstall.js +132 -0
  871. package/.cursor/mcp.json +0 -11
  872. package/.gitattributes +0 -3
  873. package/.gitleaks.toml +0 -26
  874. package/.mcp.json +0 -11
  875. package/.nvmrc +0 -1
  876. package/ARCHITECTURE.md +0 -1245
  877. package/CHANGELOG.md +0 -231
  878. package/TESTING.md +0 -278
  879. package/TRAIL_GIT_AUTH_FIX.md +0 -113
  880. package/scripts/demos/README.md +0 -79
  881. package/scripts/demos/server-capacity.sh +0 -69
  882. package/scripts/demos/sprint-planning.sh +0 -73
  883. package/scripts/hooks/install.sh +0 -16
  884. package/scripts/hooks/pre-commit +0 -60
  885. package/scripts/post-publish-verify/README.md +0 -80
  886. package/scripts/post-publish-verify/run-verify.sh +0 -127
  887. package/scripts/post-publish-verify/verify-install.sh +0 -249
  888. package/scripts/stress-test-orchestrator-integration.mts +0 -1366
  889. package/scripts/stress-test-orchestrator.mjs +0 -584
  890. package/scripts/stress-test-relay-pty.sh +0 -452
  891. package/scripts/test-interactive-terminal.sh +0 -248
  892. package/specs/PRIMITIVES_ROADMAP.md +0 -2154
  893. package/tests/benchmarks/protocol.bench.ts +0 -310
  894. package/turbo.json +0 -37
@@ -0,0 +1,1058 @@
1
+ import path from 'node:path';
2
+ import fs from 'node:fs';
3
+ import { createRequire } from 'node:module';
4
+ import {
5
+ type AgentSummary,
6
+ type MessageQuery,
7
+ type MessageStatus,
8
+ type SessionQuery,
9
+ type StorageAdapter,
10
+ type StorageHealth,
11
+ type StoredMessage,
12
+ type StoredSession,
13
+ } from './adapter.js';
14
+
15
+ export interface SqliteAdapterOptions {
16
+ dbPath: string;
17
+ /** Message retention period in milliseconds (default: 7 days) */
18
+ messageRetentionMs?: number;
19
+ /** Auto-cleanup interval in milliseconds (default: 1 hour, 0 to disable) */
20
+ cleanupIntervalMs?: number;
21
+ }
22
+
23
+ /** Default retention: 7 days */
24
+ const DEFAULT_RETENTION_MS = 7 * 24 * 60 * 60 * 1000;
25
+ /** Default cleanup interval: 1 hour */
26
+ const DEFAULT_CLEANUP_INTERVAL_MS = 60 * 60 * 1000;
27
+
28
+ // Re-export types for backwards compatibility
29
+ export type { StoredSession, SessionQuery } from './adapter.js';
30
+
31
+ type SqliteDriverName = 'better-sqlite3' | 'node';
32
+
33
+ interface SqliteStatement {
34
+ run: (...params: any[]) => unknown;
35
+ all: (...params: any[]) => any[];
36
+ get: (...params: any[]) => any;
37
+ }
38
+
39
+ interface SqliteDatabase {
40
+ exec: (sql: string) => void;
41
+ prepare: (sql: string) => SqliteStatement;
42
+ close: () => void;
43
+ pragma?: (value: string) => void;
44
+ }
45
+
46
+ export class SqliteStorageAdapter implements StorageAdapter {
47
+ private dbPath: string;
48
+ private db?: SqliteDatabase;
49
+ private insertStmt?: SqliteStatement;
50
+ private insertSessionStmt?: SqliteStatement;
51
+ private driver?: SqliteDriverName;
52
+ private retentionMs: number;
53
+ private cleanupIntervalMs: number;
54
+ private cleanupTimer?: ReturnType<typeof setInterval>;
55
+
56
+ constructor(options: SqliteAdapterOptions) {
57
+ this.dbPath = options.dbPath;
58
+ this.retentionMs = options.messageRetentionMs ?? DEFAULT_RETENTION_MS;
59
+ this.cleanupIntervalMs = options.cleanupIntervalMs ?? DEFAULT_CLEANUP_INTERVAL_MS;
60
+ }
61
+
62
+ private resolvePreferredDriver(): SqliteDriverName | undefined {
63
+ const raw = process.env.AGENT_RELAY_SQLITE_DRIVER?.trim().toLowerCase();
64
+ if (!raw) return undefined;
65
+ if (raw === 'node' || raw === 'node:sqlite' || raw === 'nodesqlite') return 'node';
66
+ if (raw === 'better-sqlite3' || raw === 'better' || raw === 'bss') return 'better-sqlite3';
67
+ return undefined;
68
+ }
69
+
70
+ private async openDatabase(driver: SqliteDriverName): Promise<SqliteDatabase> {
71
+ if (driver === 'node') {
72
+ // Use require() to avoid toolchains that don't recognize node:sqlite yet (Vitest/Vite).
73
+ const require = createRequire(import.meta.url);
74
+ const mod: any = require('node:sqlite');
75
+ const db: any = new mod.DatabaseSync(this.dbPath);
76
+ db.exec('PRAGMA journal_mode = WAL;');
77
+ return db as SqliteDatabase;
78
+ }
79
+
80
+ const mod = await import('better-sqlite3');
81
+ const DatabaseCtor: any = (mod as any).default ?? mod;
82
+ const db: any = new DatabaseCtor(this.dbPath);
83
+ if (typeof db.pragma === 'function') {
84
+ db.pragma('journal_mode = WAL');
85
+ } else {
86
+ db.exec('PRAGMA journal_mode = WAL;');
87
+ }
88
+ return db as SqliteDatabase;
89
+ }
90
+
91
+ async init(): Promise<void> {
92
+ const dir = path.dirname(this.dbPath);
93
+ if (!fs.existsSync(dir)) {
94
+ fs.mkdirSync(dir, { recursive: true });
95
+ }
96
+
97
+ const preferred = this.resolvePreferredDriver();
98
+ const attempts: SqliteDriverName[] = preferred
99
+ ? [preferred, preferred === 'better-sqlite3' ? 'node' : 'better-sqlite3']
100
+ : ['better-sqlite3', 'node'];
101
+
102
+ // Try the fastest/native option first, then fall back to the built-in driver so startup still succeeds on systems without prebuilt binaries
103
+ let lastError: unknown = null;
104
+ for (const driver of attempts) {
105
+ try {
106
+ this.db = await this.openDatabase(driver);
107
+ this.driver = driver;
108
+ lastError = null;
109
+ break;
110
+ } catch (err) {
111
+ const msg = err instanceof Error ? err.message : String(err);
112
+ console.error(`[storage] SQLite driver "${driver}" failed: ${msg}`);
113
+ lastError = err;
114
+ }
115
+ }
116
+
117
+ if (!this.db) {
118
+ throw new Error(
119
+ `Failed to initialize SQLite storage at ${this.dbPath}: ${lastError instanceof Error ? lastError.message : String(lastError)}`
120
+ );
121
+ }
122
+
123
+ // Check if messages table exists for migration decisions
124
+ const messagesTableExists = this.db.prepare(
125
+ "SELECT name FROM sqlite_master WHERE type='table' AND name='messages'"
126
+ ).get() as { name: string } | undefined;
127
+
128
+ if (!messagesTableExists) {
129
+ // Fresh install: create messages table with all columns
130
+ this.db.exec(`
131
+ CREATE TABLE messages (
132
+ id TEXT PRIMARY KEY,
133
+ ts INTEGER NOT NULL,
134
+ sender TEXT NOT NULL,
135
+ recipient TEXT NOT NULL,
136
+ topic TEXT,
137
+ kind TEXT NOT NULL,
138
+ body TEXT NOT NULL,
139
+ data TEXT,
140
+ payload_meta TEXT,
141
+ thread TEXT,
142
+ delivery_seq INTEGER,
143
+ delivery_session_id TEXT,
144
+ session_id TEXT,
145
+ status TEXT NOT NULL DEFAULT 'unread',
146
+ is_urgent INTEGER NOT NULL DEFAULT 0,
147
+ is_broadcast INTEGER NOT NULL DEFAULT 0
148
+ );
149
+ CREATE INDEX idx_messages_ts ON messages (ts);
150
+ CREATE INDEX idx_messages_sender ON messages (sender);
151
+ CREATE INDEX idx_messages_recipient ON messages (recipient);
152
+ CREATE INDEX idx_messages_topic ON messages (topic);
153
+ CREATE INDEX idx_messages_thread ON messages (thread);
154
+ CREATE INDEX idx_messages_status ON messages (status);
155
+ CREATE INDEX idx_messages_is_urgent ON messages (is_urgent);
156
+ `);
157
+ } else {
158
+ // Existing database: run migrations for missing columns
159
+ const columns = this.db.prepare("PRAGMA table_info(messages)").all() as { name: string }[];
160
+ const columnNames = new Set(columns.map(c => c.name));
161
+
162
+ if (!columnNames.has('thread')) {
163
+ this.db.exec('ALTER TABLE messages ADD COLUMN thread TEXT');
164
+ this.db.exec('CREATE INDEX IF NOT EXISTS idx_messages_thread ON messages (thread)');
165
+ }
166
+ if (!columnNames.has('payload_meta')) {
167
+ this.db.exec('ALTER TABLE messages ADD COLUMN payload_meta TEXT');
168
+ }
169
+ if (!columnNames.has('status')) {
170
+ this.db.exec("ALTER TABLE messages ADD COLUMN status TEXT NOT NULL DEFAULT 'unread'");
171
+ this.db.exec('CREATE INDEX IF NOT EXISTS idx_messages_status ON messages (status)');
172
+ }
173
+ if (!columnNames.has('is_urgent')) {
174
+ this.db.exec("ALTER TABLE messages ADD COLUMN is_urgent INTEGER NOT NULL DEFAULT 0");
175
+ this.db.exec('CREATE INDEX IF NOT EXISTS idx_messages_is_urgent ON messages (is_urgent)');
176
+ }
177
+ if (!columnNames.has('is_broadcast')) {
178
+ this.db.exec("ALTER TABLE messages ADD COLUMN is_broadcast INTEGER NOT NULL DEFAULT 0");
179
+ }
180
+ }
181
+
182
+ // Create sessions table (IF NOT EXISTS is safe here)
183
+ // Note: Don't create resume_token index here - it's created after migration check
184
+ this.db.exec(`
185
+ CREATE TABLE IF NOT EXISTS sessions (
186
+ id TEXT PRIMARY KEY,
187
+ agent_name TEXT NOT NULL,
188
+ cli TEXT,
189
+ project_id TEXT,
190
+ project_root TEXT,
191
+ started_at INTEGER NOT NULL,
192
+ ended_at INTEGER,
193
+ message_count INTEGER DEFAULT 0,
194
+ summary TEXT,
195
+ resume_token TEXT,
196
+ closed_by TEXT
197
+ );
198
+ CREATE INDEX IF NOT EXISTS idx_sessions_agent ON sessions (agent_name);
199
+ CREATE INDEX IF NOT EXISTS idx_sessions_started ON sessions (started_at);
200
+ CREATE INDEX IF NOT EXISTS idx_sessions_project ON sessions (project_id);
201
+ `);
202
+
203
+ // Migrate existing sessions table to add resume_token if missing
204
+ const sessionColumns = this.db.prepare("PRAGMA table_info(sessions)").all() as { name: string }[];
205
+ const sessionColumnNames = new Set(sessionColumns.map(c => c.name));
206
+ if (!sessionColumnNames.has('resume_token')) {
207
+ this.db.exec('ALTER TABLE sessions ADD COLUMN resume_token TEXT');
208
+ }
209
+ // Create index after ensuring column exists (either from CREATE TABLE or migration)
210
+ this.db.exec('CREATE INDEX IF NOT EXISTS idx_sessions_resume_token ON sessions (resume_token)');
211
+
212
+ // Create agent_summaries table (IF NOT EXISTS is safe here - no new columns to migrate)
213
+ this.db.exec(`
214
+ CREATE TABLE IF NOT EXISTS agent_summaries (
215
+ agent_name TEXT PRIMARY KEY,
216
+ project_id TEXT,
217
+ last_updated INTEGER NOT NULL,
218
+ current_task TEXT,
219
+ completed_tasks TEXT,
220
+ decisions TEXT,
221
+ context TEXT,
222
+ files TEXT
223
+ );
224
+ CREATE INDEX IF NOT EXISTS idx_summaries_updated ON agent_summaries (last_updated);
225
+ `);
226
+
227
+ // Create presence table for real-time status tracking
228
+ this.db.exec(`
229
+ CREATE TABLE IF NOT EXISTS presence (
230
+ agent_name TEXT PRIMARY KEY,
231
+ status TEXT NOT NULL DEFAULT 'offline',
232
+ status_text TEXT,
233
+ last_activity INTEGER NOT NULL,
234
+ typing_in TEXT
235
+ );
236
+ CREATE INDEX IF NOT EXISTS idx_presence_status ON presence (status);
237
+ CREATE INDEX IF NOT EXISTS idx_presence_activity ON presence (last_activity);
238
+ `);
239
+
240
+ // Create read_state table for tracking last read message per channel/conversation
241
+ this.db.exec(`
242
+ CREATE TABLE IF NOT EXISTS read_state (
243
+ agent_name TEXT NOT NULL,
244
+ channel TEXT NOT NULL,
245
+ last_read_ts INTEGER NOT NULL,
246
+ last_read_id TEXT,
247
+ PRIMARY KEY (agent_name, channel)
248
+ );
249
+ `);
250
+
251
+ this.insertStmt = this.db.prepare(`
252
+ INSERT OR REPLACE INTO messages
253
+ (id, ts, sender, recipient, topic, kind, body, data, payload_meta, thread, delivery_seq, delivery_session_id, session_id, status, is_urgent, is_broadcast)
254
+ VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)
255
+ `);
256
+
257
+ // Start automatic cleanup if enabled
258
+ if (this.cleanupIntervalMs > 0) {
259
+ this.startCleanupTimer();
260
+ }
261
+ }
262
+
263
+ /**
264
+ * Start the automatic cleanup timer
265
+ */
266
+ private startCleanupTimer(): void {
267
+ // Run cleanup once at startup (async, don't block)
268
+ this.cleanupExpiredMessages().catch(() => {});
269
+
270
+ // Schedule periodic cleanup
271
+ this.cleanupTimer = setInterval(() => {
272
+ this.cleanupExpiredMessages().catch(() => {});
273
+ }, this.cleanupIntervalMs);
274
+
275
+ // Prevent timer from keeping process alive
276
+ if (this.cleanupTimer.unref) {
277
+ this.cleanupTimer.unref();
278
+ }
279
+ }
280
+
281
+ /**
282
+ * Clean up messages older than the retention period
283
+ * @returns Number of messages deleted
284
+ */
285
+ async cleanupExpiredMessages(): Promise<number> {
286
+ if (!this.db) {
287
+ return 0;
288
+ }
289
+
290
+ const cutoffTs = Date.now() - this.retentionMs;
291
+ const stmt = this.db.prepare('DELETE FROM messages WHERE ts < ?');
292
+ const result = stmt.run(cutoffTs) as { changes?: number };
293
+ const deleted = result.changes ?? 0;
294
+
295
+ if (deleted > 0) {
296
+ console.log(`[storage] Cleaned up ${deleted} expired messages (older than ${Math.round(this.retentionMs / 86400000)}d)`);
297
+ }
298
+
299
+ return deleted;
300
+ }
301
+
302
+ /**
303
+ * Check storage health and persistence characteristics.
304
+ * Uses a tiny helper table to avoid mutating message data.
305
+ */
306
+ async healthCheck(): Promise<StorageHealth> {
307
+ const result: StorageHealth = {
308
+ persistent: true,
309
+ driver: 'sqlite',
310
+ canRead: false,
311
+ canWrite: false,
312
+ };
313
+
314
+ try {
315
+ if (!this.db) {
316
+ await this.init();
317
+ }
318
+
319
+ if (!this.db) {
320
+ result.error = 'SqliteStorageAdapter not initialized';
321
+ return result;
322
+ }
323
+
324
+ try {
325
+ this.db.prepare("SELECT name FROM sqlite_master WHERE type='table' LIMIT 1").get();
326
+ result.canRead = true;
327
+ } catch (err) {
328
+ result.error = `Read check failed: ${err instanceof Error ? err.message : String(err)}`;
329
+ }
330
+
331
+ try {
332
+ this.db.exec('CREATE TABLE IF NOT EXISTS __relay_health (ts INTEGER NOT NULL)');
333
+ this.db.prepare('INSERT OR REPLACE INTO __relay_health (ts) VALUES (?)').run(Date.now());
334
+ // Keep the helper table tiny
335
+ this.db.exec('DELETE FROM __relay_health WHERE ts < strftime(\'%s\', \'now\') * 1000 - 86400000');
336
+ result.canWrite = true;
337
+ } catch (err) {
338
+ const msg = err instanceof Error ? err.message : String(err);
339
+ result.error = result.error
340
+ ? `${result.error}; write check failed: ${msg}`
341
+ : `Write check failed: ${msg}`;
342
+ }
343
+ } catch (err) {
344
+ result.error = err instanceof Error ? err.message : String(err);
345
+ }
346
+
347
+ result.persistent = result.canRead && result.canWrite;
348
+ return result;
349
+ }
350
+
351
+ /**
352
+ * Get storage statistics
353
+ */
354
+ async getStats(): Promise<{ messageCount: number; sessionCount: number; oldestMessageTs?: number }> {
355
+ if (!this.db) {
356
+ throw new Error('SqliteStorageAdapter not initialized');
357
+ }
358
+
359
+ const msgCount = this.db.prepare('SELECT COUNT(*) as count FROM messages').get() as { count: number };
360
+ const sessionCount = this.db.prepare('SELECT COUNT(*) as count FROM sessions').get() as { count: number };
361
+ const oldest = this.db.prepare('SELECT MIN(ts) as ts FROM messages').get() as { ts: number | null };
362
+
363
+ return {
364
+ messageCount: msgCount.count,
365
+ sessionCount: sessionCount.count,
366
+ oldestMessageTs: oldest.ts ?? undefined,
367
+ };
368
+ }
369
+
370
+ async saveMessage(message: StoredMessage): Promise<void> {
371
+ if (!this.db || !this.insertStmt) {
372
+ throw new Error('SqliteStorageAdapter not initialized');
373
+ }
374
+
375
+ this.insertStmt.run(
376
+ message.id,
377
+ message.ts,
378
+ message.from,
379
+ message.to,
380
+ message.topic ?? null,
381
+ message.kind,
382
+ message.body,
383
+ message.data ? JSON.stringify(message.data) : null,
384
+ message.payloadMeta ? JSON.stringify(message.payloadMeta) : null,
385
+ message.thread ?? null,
386
+ message.deliverySeq ?? null,
387
+ message.deliverySessionId ?? null,
388
+ message.sessionId ?? null,
389
+ message.status,
390
+ message.is_urgent ? 1 : 0,
391
+ message.is_broadcast ? 1 : 0
392
+ );
393
+ }
394
+
395
+ async getMessages(query: MessageQuery = {}): Promise<StoredMessage[]> {
396
+ if (!this.db) {
397
+ throw new Error('SqliteStorageAdapter not initialized');
398
+ }
399
+
400
+ const clauses: string[] = [];
401
+ const params: unknown[] = [];
402
+
403
+ if (query.sinceTs) {
404
+ clauses.push('m.ts >= ?');
405
+ params.push(query.sinceTs);
406
+ }
407
+ if (query.from) {
408
+ clauses.push('m.sender = ?');
409
+ params.push(query.from);
410
+ }
411
+ if (query.to) {
412
+ clauses.push('m.recipient = ?');
413
+ params.push(query.to);
414
+ }
415
+ if (query.topic) {
416
+ clauses.push('m.topic = ?');
417
+ params.push(query.topic);
418
+ }
419
+ if (query.thread) {
420
+ clauses.push('m.thread = ?');
421
+ params.push(query.thread);
422
+ }
423
+ if (query.unreadOnly) {
424
+ clauses.push('m.status = ?');
425
+ params.push('unread');
426
+ }
427
+ if (query.urgentOnly) {
428
+ clauses.push('m.is_urgent = ?');
429
+ params.push(1);
430
+ }
431
+
432
+ const where = clauses.length ? `WHERE ${clauses.join(' AND ')}` : '';
433
+ const order = query.order === 'asc' ? 'ASC' : 'DESC';
434
+ const limit = query.limit ?? 200;
435
+
436
+ const stmt = this.db.prepare(`
437
+ SELECT m.id, m.ts, m.sender, m.recipient, m.topic, m.kind, m.body, m.data, m.payload_meta, m.thread, m.delivery_seq, m.delivery_session_id, m.session_id, m.status, m.is_urgent, m.is_broadcast,
438
+ (SELECT COUNT(*) FROM messages WHERE thread = m.id) as reply_count
439
+ FROM messages m
440
+ ${where}
441
+ ORDER BY m.ts ${order}
442
+ LIMIT ?
443
+ `);
444
+
445
+ const rows = stmt.all(...params, limit);
446
+ return rows.map((row: any) => ({
447
+ id: row.id,
448
+ ts: row.ts,
449
+ from: row.sender,
450
+ to: row.recipient,
451
+ topic: row.topic ?? undefined,
452
+ kind: row.kind,
453
+ body: row.body,
454
+ data: row.data ? JSON.parse(row.data) : undefined,
455
+ payloadMeta: row.payload_meta ? JSON.parse(row.payload_meta) : undefined,
456
+ thread: row.thread ?? undefined,
457
+ deliverySeq: row.delivery_seq ?? undefined,
458
+ deliverySessionId: row.delivery_session_id ?? undefined,
459
+ sessionId: row.session_id ?? undefined,
460
+ status: row.status,
461
+ is_urgent: row.is_urgent === 1,
462
+ is_broadcast: row.is_broadcast === 1,
463
+ replyCount: row.reply_count || 0,
464
+ }));
465
+ }
466
+
467
+ async updateMessageStatus(id: string, status: MessageStatus): Promise<void> {
468
+ if (!this.db) {
469
+ throw new Error('SqliteStorageAdapter not initialized');
470
+ }
471
+ const stmt = this.db.prepare('UPDATE messages SET status = ? WHERE id = ?');
472
+ stmt.run(status, id);
473
+ }
474
+
475
+ async getMessageById(id: string): Promise<StoredMessage | null> {
476
+ if (!this.db) {
477
+ throw new Error('SqliteStorageAdapter not initialized');
478
+ }
479
+
480
+ // Support both exact match and prefix match (for short IDs like "06eb33da")
481
+ const stmt = this.db.prepare(`
482
+ SELECT m.id, m.ts, m.sender, m.recipient, m.topic, m.kind, m.body, m.data, m.payload_meta, m.thread, m.delivery_seq, m.delivery_session_id, m.session_id, m.status, m.is_urgent, m.is_broadcast,
483
+ (SELECT COUNT(*) FROM messages WHERE thread = m.id) as reply_count
484
+ FROM messages m
485
+ WHERE m.id = ? OR m.id LIKE ?
486
+ ORDER BY m.ts DESC
487
+ LIMIT 1
488
+ `);
489
+
490
+ const row: any = stmt.get(id, `${id}%`);
491
+ if (!row) return null;
492
+
493
+ return {
494
+ id: row.id,
495
+ ts: row.ts,
496
+ from: row.sender,
497
+ to: row.recipient,
498
+ topic: row.topic ?? undefined,
499
+ kind: row.kind,
500
+ body: row.body,
501
+ data: row.data ? JSON.parse(row.data) : undefined,
502
+ payloadMeta: row.payload_meta ? JSON.parse(row.payload_meta) : undefined,
503
+ thread: row.thread ?? undefined,
504
+ deliverySeq: row.delivery_seq ?? undefined,
505
+ deliverySessionId: row.delivery_session_id ?? undefined,
506
+ sessionId: row.session_id ?? undefined,
507
+ status: row.status ?? 'unread',
508
+ is_urgent: row.is_urgent === 1,
509
+ is_broadcast: row.is_broadcast === 1,
510
+ replyCount: row.reply_count || 0,
511
+ };
512
+ }
513
+
514
+ async getPendingMessagesForSession(agentName: string, sessionId: string): Promise<StoredMessage[]> {
515
+ if (!this.db) {
516
+ throw new Error('SqliteStorageAdapter not initialized');
517
+ }
518
+
519
+ const stmt = this.db.prepare(`
520
+ SELECT id, ts, sender, recipient, topic, kind, body, data, payload_meta, thread, delivery_seq, delivery_session_id, session_id, status, is_urgent, is_broadcast
521
+ FROM messages
522
+ WHERE recipient = ? AND delivery_session_id = ? AND status != 'acked'
523
+ ORDER BY delivery_seq ASC, ts ASC
524
+ `);
525
+
526
+ const rows = stmt.all(agentName, sessionId);
527
+ return rows.map((row: any) => ({
528
+ id: row.id,
529
+ ts: row.ts,
530
+ from: row.sender,
531
+ to: row.recipient,
532
+ topic: row.topic ?? undefined,
533
+ kind: row.kind,
534
+ body: row.body,
535
+ data: row.data ? JSON.parse(row.data) : undefined,
536
+ payloadMeta: row.payload_meta ? JSON.parse(row.payload_meta) : undefined,
537
+ thread: row.thread ?? undefined,
538
+ deliverySeq: row.delivery_seq ?? undefined,
539
+ deliverySessionId: row.delivery_session_id ?? undefined,
540
+ sessionId: row.session_id ?? undefined,
541
+ status: row.status ?? 'unread',
542
+ is_urgent: row.is_urgent === 1,
543
+ is_broadcast: row.is_broadcast === 1,
544
+ }));
545
+ }
546
+
547
+ async getMaxSeqByStream(agentName: string, sessionId: string): Promise<Array<{ peer: string; topic?: string; maxSeq: number }>> {
548
+ if (!this.db) {
549
+ throw new Error('SqliteStorageAdapter not initialized');
550
+ }
551
+
552
+ const stmt = this.db.prepare(`
553
+ SELECT sender, topic, MAX(delivery_seq) as max_seq
554
+ FROM messages
555
+ WHERE recipient = ? AND delivery_session_id = ? AND delivery_seq IS NOT NULL
556
+ GROUP BY sender, topic
557
+ `);
558
+
559
+ const rows = stmt.all(agentName, sessionId) as Array<{ sender: string; topic: string | null; max_seq: number }>;
560
+ return rows.map(row => ({
561
+ peer: row.sender,
562
+ topic: row.topic ?? undefined,
563
+ maxSeq: row.max_seq,
564
+ }));
565
+ }
566
+
567
+ async close(): Promise<void> {
568
+ // Stop cleanup timer
569
+ if (this.cleanupTimer) {
570
+ clearInterval(this.cleanupTimer);
571
+ this.cleanupTimer = undefined;
572
+ }
573
+
574
+ if (this.db) {
575
+ this.db.close();
576
+ this.db = undefined;
577
+ }
578
+ }
579
+
580
+ // ============ Session Management ============
581
+
582
+ async startSession(session: Omit<StoredSession, 'messageCount'>): Promise<void> {
583
+ if (!this.db) {
584
+ throw new Error('SqliteStorageAdapter not initialized');
585
+ }
586
+
587
+ const stmt = this.db.prepare(`
588
+ INSERT INTO sessions
589
+ (id, agent_name, cli, project_id, project_root, started_at, ended_at, message_count, summary, resume_token, closed_by)
590
+ VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)
591
+ ON CONFLICT(id) DO UPDATE SET
592
+ agent_name = excluded.agent_name,
593
+ cli = COALESCE(excluded.cli, sessions.cli),
594
+ project_id = COALESCE(excluded.project_id, sessions.project_id),
595
+ project_root = COALESCE(excluded.project_root, sessions.project_root),
596
+ started_at = COALESCE(sessions.started_at, excluded.started_at),
597
+ ended_at = excluded.ended_at,
598
+ message_count = COALESCE(sessions.message_count, excluded.message_count),
599
+ summary = COALESCE(excluded.summary, sessions.summary),
600
+ resume_token = COALESCE(excluded.resume_token, sessions.resume_token),
601
+ closed_by = excluded.closed_by
602
+ `);
603
+
604
+ stmt.run(
605
+ session.id,
606
+ session.agentName,
607
+ session.cli ?? null,
608
+ session.projectId ?? null,
609
+ session.projectRoot ?? null,
610
+ session.startedAt,
611
+ session.endedAt ?? null,
612
+ 0,
613
+ session.summary ?? null,
614
+ session.resumeToken ?? null,
615
+ null
616
+ );
617
+ }
618
+
619
+ /**
620
+ * End a session and optionally set a summary.
621
+ *
622
+ * Note: The summary uses COALESCE(?, summary) - if a summary was previously
623
+ * set (e.g., during startSession or a prior endSession call), passing null/undefined
624
+ * for summary will preserve the existing value rather than clearing it.
625
+ * To explicitly clear a summary, pass an empty string.
626
+ */
627
+ async endSession(
628
+ sessionId: string,
629
+ options?: { summary?: string; closedBy?: 'agent' | 'disconnect' | 'error' }
630
+ ): Promise<void> {
631
+ if (!this.db) {
632
+ throw new Error('SqliteStorageAdapter not initialized');
633
+ }
634
+
635
+ const stmt = this.db.prepare(`
636
+ UPDATE sessions
637
+ SET ended_at = ?, summary = COALESCE(?, summary), closed_by = ?
638
+ WHERE id = ?
639
+ `);
640
+
641
+ stmt.run(
642
+ Date.now(),
643
+ options?.summary ?? null,
644
+ options?.closedBy ?? null,
645
+ sessionId
646
+ );
647
+ }
648
+
649
+ async incrementSessionMessageCount(sessionId: string): Promise<void> {
650
+ if (!this.db) {
651
+ throw new Error('SqliteStorageAdapter not initialized');
652
+ }
653
+
654
+ const stmt = this.db.prepare(`
655
+ UPDATE sessions SET message_count = message_count + 1 WHERE id = ?
656
+ `);
657
+
658
+ stmt.run(sessionId);
659
+ }
660
+
661
+ async getSessions(query: SessionQuery = {}): Promise<StoredSession[]> {
662
+ if (!this.db) {
663
+ throw new Error('SqliteStorageAdapter not initialized');
664
+ }
665
+
666
+ const clauses: string[] = [];
667
+ const params: unknown[] = [];
668
+
669
+ if (query.agentName) {
670
+ clauses.push('agent_name = ?');
671
+ params.push(query.agentName);
672
+ }
673
+ if (query.projectId) {
674
+ clauses.push('project_id = ?');
675
+ params.push(query.projectId);
676
+ }
677
+ if (query.since) {
678
+ clauses.push('started_at >= ?');
679
+ params.push(query.since);
680
+ }
681
+
682
+ const where = clauses.length ? `WHERE ${clauses.join(' AND ')}` : '';
683
+ const limit = query.limit ?? 50;
684
+
685
+ const stmt = this.db.prepare(`
686
+ SELECT id, agent_name, cli, project_id, project_root, started_at, ended_at, message_count, summary, resume_token, closed_by
687
+ FROM sessions
688
+ ${where}
689
+ ORDER BY started_at DESC
690
+ LIMIT ?
691
+ `);
692
+
693
+ const rows = stmt.all(...params, limit);
694
+ return rows.map((row: any) => ({
695
+ id: row.id,
696
+ agentName: row.agent_name,
697
+ cli: row.cli ?? undefined,
698
+ projectId: row.project_id ?? undefined,
699
+ projectRoot: row.project_root ?? undefined,
700
+ startedAt: row.started_at,
701
+ endedAt: row.ended_at ?? undefined,
702
+ messageCount: row.message_count,
703
+ summary: row.summary ?? undefined,
704
+ resumeToken: row.resume_token ?? undefined,
705
+ closedBy: row.closed_by ?? undefined,
706
+ }));
707
+ }
708
+
709
+ async getRecentSessions(limit: number = 10): Promise<StoredSession[]> {
710
+ return this.getSessions({ limit });
711
+ }
712
+
713
+ async getSessionByResumeToken(resumeToken: string): Promise<StoredSession | null> {
714
+ if (!this.db) {
715
+ throw new Error('SqliteStorageAdapter not initialized');
716
+ }
717
+
718
+ const row = this.db.prepare(`
719
+ SELECT id, agent_name, cli, project_id, project_root, started_at, ended_at, message_count, summary, resume_token, closed_by
720
+ FROM sessions
721
+ WHERE resume_token = ?
722
+ LIMIT 1
723
+ `).get(resumeToken) as any;
724
+
725
+ if (!row) {
726
+ return null;
727
+ }
728
+
729
+ return {
730
+ id: row.id,
731
+ agentName: row.agent_name,
732
+ cli: row.cli ?? undefined,
733
+ projectId: row.project_id ?? undefined,
734
+ projectRoot: row.project_root ?? undefined,
735
+ startedAt: row.started_at,
736
+ endedAt: row.ended_at ?? undefined,
737
+ messageCount: row.message_count,
738
+ summary: row.summary ?? undefined,
739
+ resumeToken: row.resume_token ?? undefined,
740
+ closedBy: row.closed_by ?? undefined,
741
+ };
742
+ }
743
+
744
+ // ============ Agent Summaries ============
745
+
746
+ async saveAgentSummary(summary: {
747
+ agentName: string;
748
+ projectId?: string;
749
+ currentTask?: string;
750
+ completedTasks?: string[];
751
+ decisions?: string[];
752
+ context?: string;
753
+ files?: string[];
754
+ }): Promise<void> {
755
+ if (!this.db) {
756
+ throw new Error('SqliteStorageAdapter not initialized');
757
+ }
758
+
759
+ const stmt = this.db.prepare(`
760
+ INSERT OR REPLACE INTO agent_summaries
761
+ (agent_name, project_id, last_updated, current_task, completed_tasks, decisions, context, files)
762
+ VALUES (?, ?, ?, ?, ?, ?, ?, ?)
763
+ `);
764
+
765
+ stmt.run(
766
+ summary.agentName,
767
+ summary.projectId ?? null,
768
+ Date.now(),
769
+ summary.currentTask ?? null,
770
+ summary.completedTasks ? JSON.stringify(summary.completedTasks) : null,
771
+ summary.decisions ? JSON.stringify(summary.decisions) : null,
772
+ summary.context ?? null,
773
+ summary.files ? JSON.stringify(summary.files) : null
774
+ );
775
+ }
776
+
777
+ async getAgentSummary(agentName: string): Promise<AgentSummary | null> {
778
+ if (!this.db) {
779
+ throw new Error('SqliteStorageAdapter not initialized');
780
+ }
781
+
782
+ const stmt = this.db.prepare(`
783
+ SELECT agent_name, project_id, last_updated, current_task, completed_tasks, decisions, context, files
784
+ FROM agent_summaries
785
+ WHERE agent_name = ?
786
+ `);
787
+
788
+ const row: any = stmt.get(agentName);
789
+ if (!row) return null;
790
+
791
+ return {
792
+ agentName: row.agent_name,
793
+ projectId: row.project_id ?? undefined,
794
+ lastUpdated: row.last_updated,
795
+ currentTask: row.current_task ?? undefined,
796
+ completedTasks: row.completed_tasks ? JSON.parse(row.completed_tasks) : undefined,
797
+ decisions: row.decisions ? JSON.parse(row.decisions) : undefined,
798
+ context: row.context ?? undefined,
799
+ files: row.files ? JSON.parse(row.files) : undefined,
800
+ };
801
+ }
802
+
803
+ async getAllAgentSummaries(): Promise<AgentSummary[]> {
804
+ if (!this.db) {
805
+ throw new Error('SqliteStorageAdapter not initialized');
806
+ }
807
+
808
+ const stmt = this.db.prepare(`
809
+ SELECT agent_name, project_id, last_updated, current_task, completed_tasks, decisions, context, files
810
+ FROM agent_summaries
811
+ ORDER BY last_updated DESC
812
+ `);
813
+
814
+ const rows = stmt.all();
815
+ return rows.map((row: any) => ({
816
+ agentName: row.agent_name,
817
+ projectId: row.project_id ?? undefined,
818
+ lastUpdated: row.last_updated,
819
+ currentTask: row.current_task ?? undefined,
820
+ completedTasks: row.completed_tasks ? JSON.parse(row.completed_tasks) : undefined,
821
+ decisions: row.decisions ? JSON.parse(row.decisions) : undefined,
822
+ context: row.context ?? undefined,
823
+ files: row.files ? JSON.parse(row.files) : undefined,
824
+ }));
825
+ }
826
+
827
+ // ============ Presence Management ============
828
+
829
+ async updatePresence(presence: {
830
+ agentName: string;
831
+ status: 'online' | 'away' | 'busy' | 'offline';
832
+ statusText?: string;
833
+ typingIn?: string;
834
+ }): Promise<void> {
835
+ if (!this.db) {
836
+ throw new Error('SqliteStorageAdapter not initialized');
837
+ }
838
+
839
+ const stmt = this.db.prepare(`
840
+ INSERT OR REPLACE INTO presence
841
+ (agent_name, status, status_text, last_activity, typing_in)
842
+ VALUES (?, ?, ?, ?, ?)
843
+ `);
844
+
845
+ stmt.run(
846
+ presence.agentName,
847
+ presence.status,
848
+ presence.statusText ?? null,
849
+ Date.now(),
850
+ presence.typingIn ?? null
851
+ );
852
+ }
853
+
854
+ async getPresence(agentName: string): Promise<{
855
+ agentName: string;
856
+ status: 'online' | 'away' | 'busy' | 'offline';
857
+ statusText?: string;
858
+ lastActivity: number;
859
+ typingIn?: string;
860
+ } | null> {
861
+ if (!this.db) {
862
+ throw new Error('SqliteStorageAdapter not initialized');
863
+ }
864
+
865
+ const stmt = this.db.prepare(`
866
+ SELECT agent_name, status, status_text, last_activity, typing_in
867
+ FROM presence
868
+ WHERE agent_name = ?
869
+ `);
870
+
871
+ const row: any = stmt.get(agentName);
872
+ if (!row) return null;
873
+
874
+ return {
875
+ agentName: row.agent_name,
876
+ status: row.status,
877
+ statusText: row.status_text ?? undefined,
878
+ lastActivity: row.last_activity,
879
+ typingIn: row.typing_in ?? undefined,
880
+ };
881
+ }
882
+
883
+ async getAllPresence(): Promise<Array<{
884
+ agentName: string;
885
+ status: 'online' | 'away' | 'busy' | 'offline';
886
+ statusText?: string;
887
+ lastActivity: number;
888
+ typingIn?: string;
889
+ }>> {
890
+ if (!this.db) {
891
+ throw new Error('SqliteStorageAdapter not initialized');
892
+ }
893
+
894
+ const stmt = this.db.prepare(`
895
+ SELECT agent_name, status, status_text, last_activity, typing_in
896
+ FROM presence
897
+ ORDER BY last_activity DESC
898
+ `);
899
+
900
+ const rows = stmt.all();
901
+ return rows.map((row: any) => ({
902
+ agentName: row.agent_name,
903
+ status: row.status,
904
+ statusText: row.status_text ?? undefined,
905
+ lastActivity: row.last_activity,
906
+ typingIn: row.typing_in ?? undefined,
907
+ }));
908
+ }
909
+
910
+ async setTypingIndicator(agentName: string, channel: string | null): Promise<void> {
911
+ if (!this.db) {
912
+ throw new Error('SqliteStorageAdapter not initialized');
913
+ }
914
+
915
+ const stmt = this.db.prepare(`
916
+ UPDATE presence
917
+ SET typing_in = ?, last_activity = ?
918
+ WHERE agent_name = ?
919
+ `);
920
+
921
+ stmt.run(channel, Date.now(), agentName);
922
+ }
923
+
924
+ // ============ Read State Management ============
925
+
926
+ async updateReadState(agentName: string, channel: string, lastReadTs: number, lastReadId?: string): Promise<void> {
927
+ if (!this.db) {
928
+ throw new Error('SqliteStorageAdapter not initialized');
929
+ }
930
+
931
+ const stmt = this.db.prepare(`
932
+ INSERT OR REPLACE INTO read_state
933
+ (agent_name, channel, last_read_ts, last_read_id)
934
+ VALUES (?, ?, ?, ?)
935
+ `);
936
+
937
+ stmt.run(agentName, channel, lastReadTs, lastReadId ?? null);
938
+ }
939
+
940
+ async getReadState(agentName: string, channel: string): Promise<{
941
+ lastReadTs: number;
942
+ lastReadId?: string;
943
+ } | null> {
944
+ if (!this.db) {
945
+ throw new Error('SqliteStorageAdapter not initialized');
946
+ }
947
+
948
+ const stmt = this.db.prepare(`
949
+ SELECT last_read_ts, last_read_id
950
+ FROM read_state
951
+ WHERE agent_name = ? AND channel = ?
952
+ `);
953
+
954
+ const row: any = stmt.get(agentName, channel);
955
+ if (!row) return null;
956
+
957
+ return {
958
+ lastReadTs: row.last_read_ts,
959
+ lastReadId: row.last_read_id ?? undefined,
960
+ };
961
+ }
962
+
963
+ async getUnreadCounts(agentName: string): Promise<Record<string, number>> {
964
+ if (!this.db) {
965
+ throw new Error('SqliteStorageAdapter not initialized');
966
+ }
967
+
968
+ // Get all read states for this agent
969
+ const readStates = this.db.prepare(`
970
+ SELECT channel, last_read_ts FROM read_state WHERE agent_name = ?
971
+ `).all(agentName) as Array<{ channel: string; last_read_ts: number }>;
972
+
973
+ const counts: Record<string, number> = {};
974
+
975
+ // Count unread messages for each channel (conversation with agent)
976
+ for (const { channel, last_read_ts } of readStates) {
977
+ const count = this.db.prepare(`
978
+ SELECT COUNT(*) as count FROM messages
979
+ WHERE recipient = ? AND ts > ?
980
+ `).get(channel, last_read_ts) as { count: number };
981
+
982
+ if (count.count > 0) {
983
+ counts[channel] = count.count;
984
+ }
985
+ }
986
+
987
+ return counts;
988
+ }
989
+
990
+ // ============ Channel Membership Helpers ============
991
+
992
+ /**
993
+ * Get channels that an agent is a member of based on stored membership events.
994
+ * Uses window function to find the most recent action per channel.
995
+ * @returns List of channel names where the agent's latest action is not "leave"
996
+ */
997
+ async getChannelMembershipsForAgent(memberName: string): Promise<string[]> {
998
+ if (!this.db) {
999
+ throw new Error('SqliteStorageAdapter not initialized');
1000
+ }
1001
+
1002
+ // Query messages with _channelMembership metadata to find channels where
1003
+ // the agent's most recent action is NOT "leave" (i.e., 'join' or 'invite')
1004
+ // Note: 'invite' also adds a member to a channel (see handleMembershipUpdate)
1005
+ const stmt = this.db.prepare(`
1006
+ WITH membership_events AS (
1007
+ SELECT
1008
+ recipient AS channel,
1009
+ json_extract(data, '$._channelMembership.member') AS member,
1010
+ json_extract(data, '$._channelMembership.action') AS action,
1011
+ ts,
1012
+ ROW_NUMBER() OVER (
1013
+ PARTITION BY recipient, json_extract(data, '$._channelMembership.member')
1014
+ ORDER BY ts DESC
1015
+ ) AS rn
1016
+ FROM messages
1017
+ WHERE json_extract(data, '$._channelMembership.member') = ?
1018
+ AND json_extract(data, '$._channelMembership.action') IS NOT NULL
1019
+ )
1020
+ SELECT channel
1021
+ FROM membership_events
1022
+ WHERE rn = 1 AND action != 'leave'
1023
+ `);
1024
+
1025
+ const rows = stmt.all(memberName) as Array<{ channel: string }>;
1026
+ return rows.map(row => row.channel);
1027
+ }
1028
+
1029
+ /**
1030
+ * Remove an agent from the sessions table.
1031
+ * This is used to clean up stale agents from the registry.
1032
+ */
1033
+ async removeAgent(agentName: string): Promise<void> {
1034
+ if (!this.db) {
1035
+ await this.init();
1036
+ }
1037
+
1038
+ const stmt = this.db!.prepare(`
1039
+ DELETE FROM sessions WHERE agent_name = ?
1040
+ `);
1041
+ stmt.run(agentName);
1042
+ }
1043
+
1044
+ /**
1045
+ * Remove all messages from/to an agent.
1046
+ * Use with caution - this permanently deletes message history.
1047
+ */
1048
+ async removeMessagesForAgent(agentName: string): Promise<void> {
1049
+ if (!this.db) {
1050
+ await this.init();
1051
+ }
1052
+
1053
+ const stmt = this.db!.prepare(`
1054
+ DELETE FROM messages WHERE sender = ? OR recipient = ?
1055
+ `);
1056
+ stmt.run(agentName, agentName);
1057
+ }
1058
+ }