macro-agent 0.0.10 → 0.0.12

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 (518) hide show
  1. package/.macro-agent/teams/self-driving/prompts/grinder.md +27 -0
  2. package/.macro-agent/teams/self-driving/prompts/judge.md +27 -0
  3. package/.macro-agent/teams/self-driving/prompts/planner.md +33 -0
  4. package/.macro-agent/teams/self-driving/roles/grinder.yaml +17 -0
  5. package/.macro-agent/teams/self-driving/roles/judge.yaml +24 -0
  6. package/.macro-agent/teams/self-driving/roles/planner.yaml +18 -0
  7. package/.macro-agent/teams/self-driving/team.yaml +103 -0
  8. package/.macro-agent/teams/structured/prompts/developer.md +26 -0
  9. package/.macro-agent/teams/structured/prompts/lead.md +25 -0
  10. package/.macro-agent/teams/structured/prompts/reviewer.md +24 -0
  11. package/.macro-agent/teams/structured/roles/developer.yaml +12 -0
  12. package/.macro-agent/teams/structured/roles/lead.yaml +11 -0
  13. package/.macro-agent/teams/structured/roles/reviewer.yaml +19 -0
  14. package/.macro-agent/teams/structured/team.yaml +89 -0
  15. package/.sudocode/issues.jsonl +56 -51
  16. package/.sudocode/specs.jsonl +8 -1
  17. package/CLAUDE.md +121 -30
  18. package/README.md +60 -3
  19. package/dist/acp/macro-agent.d.ts +4 -0
  20. package/dist/acp/macro-agent.d.ts.map +1 -1
  21. package/dist/acp/macro-agent.js +50 -4
  22. package/dist/acp/macro-agent.js.map +1 -1
  23. package/dist/acp/session-mapper.d.ts +20 -1
  24. package/dist/acp/session-mapper.d.ts.map +1 -1
  25. package/dist/acp/session-mapper.js +90 -1
  26. package/dist/acp/session-mapper.js.map +1 -1
  27. package/dist/acp/types.d.ts +24 -1
  28. package/dist/acp/types.d.ts.map +1 -1
  29. package/dist/acp/types.js.map +1 -1
  30. package/dist/agent/agent-manager.d.ts +40 -1
  31. package/dist/agent/agent-manager.d.ts.map +1 -1
  32. package/dist/agent/agent-manager.js +172 -8
  33. package/dist/agent/agent-manager.js.map +1 -1
  34. package/dist/agent/types.d.ts +22 -0
  35. package/dist/agent/types.d.ts.map +1 -1
  36. package/dist/agent/types.js.map +1 -1
  37. package/dist/agent/wake.d.ts +15 -0
  38. package/dist/agent/wake.d.ts.map +1 -1
  39. package/dist/agent/wake.js +15 -0
  40. package/dist/agent/wake.js.map +1 -1
  41. package/dist/agent-detection/command-builder.d.ts +30 -0
  42. package/dist/agent-detection/command-builder.d.ts.map +1 -0
  43. package/dist/agent-detection/command-builder.js +71 -0
  44. package/dist/agent-detection/command-builder.js.map +1 -0
  45. package/dist/agent-detection/detector.d.ts +84 -0
  46. package/dist/agent-detection/detector.d.ts.map +1 -0
  47. package/dist/agent-detection/detector.js +240 -0
  48. package/dist/agent-detection/detector.js.map +1 -0
  49. package/dist/agent-detection/index.d.ts +12 -0
  50. package/dist/agent-detection/index.d.ts.map +1 -0
  51. package/dist/agent-detection/index.js +14 -0
  52. package/dist/agent-detection/index.js.map +1 -0
  53. package/dist/agent-detection/registry.d.ts +53 -0
  54. package/dist/agent-detection/registry.d.ts.map +1 -0
  55. package/dist/agent-detection/registry.js +177 -0
  56. package/dist/agent-detection/registry.js.map +1 -0
  57. package/dist/agent-detection/types.d.ts +121 -0
  58. package/dist/agent-detection/types.d.ts.map +1 -0
  59. package/dist/agent-detection/types.js +20 -0
  60. package/dist/agent-detection/types.js.map +1 -0
  61. package/dist/api/server.d.ts +5 -1
  62. package/dist/api/server.d.ts.map +1 -1
  63. package/dist/api/server.js +362 -0
  64. package/dist/api/server.js.map +1 -1
  65. package/dist/api/types.d.ts +50 -1
  66. package/dist/api/types.d.ts.map +1 -1
  67. package/dist/cli/acp.d.ts +2 -0
  68. package/dist/cli/acp.d.ts.map +1 -1
  69. package/dist/cli/acp.js +8 -1
  70. package/dist/cli/acp.js.map +1 -1
  71. package/dist/cli/index.js +29 -0
  72. package/dist/cli/index.js.map +1 -1
  73. package/dist/cli/mcp.js +38 -0
  74. package/dist/cli/mcp.js.map +1 -1
  75. package/dist/config/index.d.ts +2 -0
  76. package/dist/config/index.d.ts.map +1 -0
  77. package/dist/config/index.js +2 -0
  78. package/dist/config/index.js.map +1 -0
  79. package/dist/config/project-config.d.ts +46 -0
  80. package/dist/config/project-config.d.ts.map +1 -0
  81. package/dist/config/project-config.js +68 -0
  82. package/dist/config/project-config.js.map +1 -0
  83. package/dist/lifecycle/cascade.d.ts +1 -1
  84. package/dist/lifecycle/cascade.d.ts.map +1 -1
  85. package/dist/lifecycle/handlers/index.d.ts +4 -0
  86. package/dist/lifecycle/handlers/index.d.ts.map +1 -1
  87. package/dist/lifecycle/handlers/index.js +2 -0
  88. package/dist/lifecycle/handlers/index.js.map +1 -1
  89. package/dist/lifecycle/handlers/worker.d.ts +4 -0
  90. package/dist/lifecycle/handlers/worker.d.ts.map +1 -1
  91. package/dist/lifecycle/handlers/worker.js +35 -3
  92. package/dist/lifecycle/handlers/worker.js.map +1 -1
  93. package/dist/mail/conversation-map.d.ts +33 -0
  94. package/dist/mail/conversation-map.d.ts.map +1 -0
  95. package/dist/mail/conversation-map.js +61 -0
  96. package/dist/mail/conversation-map.js.map +1 -0
  97. package/dist/mail/index.d.ts +11 -0
  98. package/dist/mail/index.d.ts.map +1 -0
  99. package/dist/mail/index.js +11 -0
  100. package/dist/mail/index.js.map +1 -0
  101. package/dist/mail/mail-service.d.ts +85 -0
  102. package/dist/mail/mail-service.d.ts.map +1 -0
  103. package/dist/mail/mail-service.js +121 -0
  104. package/dist/mail/mail-service.js.map +1 -0
  105. package/dist/mail/stores/eventstore-conversation-store.d.ts +40 -0
  106. package/dist/mail/stores/eventstore-conversation-store.d.ts.map +1 -0
  107. package/dist/mail/stores/eventstore-conversation-store.js +131 -0
  108. package/dist/mail/stores/eventstore-conversation-store.js.map +1 -0
  109. package/dist/mail/stores/eventstore-participant-store.d.ts +43 -0
  110. package/dist/mail/stores/eventstore-participant-store.d.ts.map +1 -0
  111. package/dist/mail/stores/eventstore-participant-store.js +145 -0
  112. package/dist/mail/stores/eventstore-participant-store.js.map +1 -0
  113. package/dist/mail/stores/eventstore-thread-store.d.ts +46 -0
  114. package/dist/mail/stores/eventstore-thread-store.d.ts.map +1 -0
  115. package/dist/mail/stores/eventstore-thread-store.js +118 -0
  116. package/dist/mail/stores/eventstore-thread-store.js.map +1 -0
  117. package/dist/mail/stores/eventstore-turn-store.d.ts +47 -0
  118. package/dist/mail/stores/eventstore-turn-store.d.ts.map +1 -0
  119. package/dist/mail/stores/eventstore-turn-store.js +153 -0
  120. package/dist/mail/stores/eventstore-turn-store.js.map +1 -0
  121. package/dist/mail/stores/index.d.ts +12 -0
  122. package/dist/mail/stores/index.d.ts.map +1 -0
  123. package/dist/mail/stores/index.js +12 -0
  124. package/dist/mail/stores/index.js.map +1 -0
  125. package/dist/mail/stores/types.d.ts +146 -0
  126. package/dist/mail/stores/types.d.ts.map +1 -0
  127. package/dist/mail/stores/types.js +13 -0
  128. package/dist/mail/stores/types.js.map +1 -0
  129. package/dist/mail/turn-recorder.d.ts +30 -0
  130. package/dist/mail/turn-recorder.d.ts.map +1 -0
  131. package/dist/mail/turn-recorder.js +98 -0
  132. package/dist/mail/turn-recorder.js.map +1 -0
  133. package/dist/map/adapter/acp-over-map.d.ts.map +1 -1
  134. package/dist/map/adapter/acp-over-map.js +32 -2
  135. package/dist/map/adapter/acp-over-map.js.map +1 -1
  136. package/dist/map/adapter/event-translator.d.ts.map +1 -1
  137. package/dist/map/adapter/event-translator.js +4 -0
  138. package/dist/map/adapter/event-translator.js.map +1 -1
  139. package/dist/map/adapter/extensions/agent-detection.d.ts +49 -0
  140. package/dist/map/adapter/extensions/agent-detection.d.ts.map +1 -0
  141. package/dist/map/adapter/extensions/agent-detection.js +91 -0
  142. package/dist/map/adapter/extensions/agent-detection.js.map +1 -0
  143. package/dist/map/adapter/extensions/index.d.ts +10 -1
  144. package/dist/map/adapter/extensions/index.d.ts.map +1 -1
  145. package/dist/map/adapter/extensions/index.js +39 -0
  146. package/dist/map/adapter/extensions/index.js.map +1 -1
  147. package/dist/map/adapter/extensions/resume.d.ts +47 -0
  148. package/dist/map/adapter/extensions/resume.d.ts.map +1 -0
  149. package/dist/map/adapter/extensions/resume.js +59 -0
  150. package/dist/map/adapter/extensions/resume.js.map +1 -0
  151. package/dist/map/adapter/extensions/workspace-files.d.ts +42 -0
  152. package/dist/map/adapter/extensions/workspace-files.d.ts.map +1 -0
  153. package/dist/map/adapter/extensions/workspace-files.js +338 -0
  154. package/dist/map/adapter/extensions/workspace-files.js.map +1 -0
  155. package/dist/map/adapter/mail-handler-adapter.d.ts +27 -0
  156. package/dist/map/adapter/mail-handler-adapter.d.ts.map +1 -0
  157. package/dist/map/adapter/mail-handler-adapter.js +292 -0
  158. package/dist/map/adapter/mail-handler-adapter.js.map +1 -0
  159. package/dist/map/adapter/map-adapter.d.ts +34 -10
  160. package/dist/map/adapter/map-adapter.d.ts.map +1 -1
  161. package/dist/map/adapter/map-adapter.js +110 -14
  162. package/dist/map/adapter/map-adapter.js.map +1 -1
  163. package/dist/map/adapter/rpc-handler.d.ts +4 -1
  164. package/dist/map/adapter/rpc-handler.d.ts.map +1 -1
  165. package/dist/map/adapter/rpc-handler.js +6 -0
  166. package/dist/map/adapter/rpc-handler.js.map +1 -1
  167. package/dist/map/index.d.ts +1 -0
  168. package/dist/map/index.d.ts.map +1 -1
  169. package/dist/map/index.js +2 -0
  170. package/dist/map/index.js.map +1 -1
  171. package/dist/map/types.d.ts +3 -1
  172. package/dist/map/types.d.ts.map +1 -1
  173. package/dist/map/types.js.map +1 -1
  174. package/dist/mcp/mcp-server.d.ts +6 -0
  175. package/dist/mcp/mcp-server.d.ts.map +1 -1
  176. package/dist/mcp/mcp-server.js +45 -0
  177. package/dist/mcp/mcp-server.js.map +1 -1
  178. package/dist/mcp/tools/claim_task.d.ts +35 -0
  179. package/dist/mcp/tools/claim_task.d.ts.map +1 -0
  180. package/dist/mcp/tools/claim_task.js +58 -0
  181. package/dist/mcp/tools/claim_task.js.map +1 -0
  182. package/dist/mcp/tools/done.d.ts +15 -2
  183. package/dist/mcp/tools/done.d.ts.map +1 -1
  184. package/dist/mcp/tools/done.js +45 -10
  185. package/dist/mcp/tools/done.js.map +1 -1
  186. package/dist/mcp/tools/list_claimable_tasks.d.ts +38 -0
  187. package/dist/mcp/tools/list_claimable_tasks.d.ts.map +1 -0
  188. package/dist/mcp/tools/list_claimable_tasks.js +63 -0
  189. package/dist/mcp/tools/list_claimable_tasks.js.map +1 -0
  190. package/dist/mcp/tools/unclaim_task.d.ts +31 -0
  191. package/dist/mcp/tools/unclaim_task.d.ts.map +1 -0
  192. package/dist/mcp/tools/unclaim_task.js +47 -0
  193. package/dist/mcp/tools/unclaim_task.js.map +1 -0
  194. package/dist/metrics/index.d.ts +2 -0
  195. package/dist/metrics/index.d.ts.map +1 -0
  196. package/dist/metrics/index.js +2 -0
  197. package/dist/metrics/index.js.map +1 -0
  198. package/dist/metrics/metrics.d.ts +79 -0
  199. package/dist/metrics/metrics.d.ts.map +1 -0
  200. package/dist/metrics/metrics.js +166 -0
  201. package/dist/metrics/metrics.js.map +1 -0
  202. package/dist/roles/capabilities.d.ts +1 -0
  203. package/dist/roles/capabilities.d.ts.map +1 -1
  204. package/dist/roles/capabilities.js +3 -0
  205. package/dist/roles/capabilities.js.map +1 -1
  206. package/dist/roles/types.d.ts +1 -1
  207. package/dist/roles/types.d.ts.map +1 -1
  208. package/dist/router/channels.d.ts +2 -4
  209. package/dist/router/channels.d.ts.map +1 -1
  210. package/dist/router/channels.js.map +1 -1
  211. package/dist/router/message-router.d.ts +85 -9
  212. package/dist/router/message-router.d.ts.map +1 -1
  213. package/dist/router/message-router.js +203 -14
  214. package/dist/router/message-router.js.map +1 -1
  215. package/dist/router/role-resolver.d.ts +10 -1
  216. package/dist/router/role-resolver.d.ts.map +1 -1
  217. package/dist/router/role-resolver.js +15 -1
  218. package/dist/router/role-resolver.js.map +1 -1
  219. package/dist/router/types.d.ts +30 -1
  220. package/dist/router/types.d.ts.map +1 -1
  221. package/dist/router/types.js.map +1 -1
  222. package/dist/server/combined-server.d.ts +6 -0
  223. package/dist/server/combined-server.d.ts.map +1 -1
  224. package/dist/server/combined-server.js +24 -2
  225. package/dist/server/combined-server.js.map +1 -1
  226. package/dist/store/event-store.d.ts +14 -1
  227. package/dist/store/event-store.d.ts.map +1 -1
  228. package/dist/store/event-store.js +456 -4
  229. package/dist/store/event-store.js.map +1 -1
  230. package/dist/store/types/agents.d.ts +1 -1
  231. package/dist/store/types/agents.d.ts.map +1 -1
  232. package/dist/store/types/conversations.d.ts +91 -0
  233. package/dist/store/types/conversations.d.ts.map +1 -0
  234. package/dist/store/types/conversations.js +8 -0
  235. package/dist/store/types/conversations.js.map +1 -0
  236. package/dist/store/types/events.d.ts +1 -1
  237. package/dist/store/types/events.d.ts.map +1 -1
  238. package/dist/store/types/events.js.map +1 -1
  239. package/dist/store/types/index.d.ts +2 -0
  240. package/dist/store/types/index.d.ts.map +1 -1
  241. package/dist/store/types/index.js +2 -0
  242. package/dist/store/types/index.js.map +1 -1
  243. package/dist/store/types/sessions.d.ts +44 -0
  244. package/dist/store/types/sessions.d.ts.map +1 -0
  245. package/dist/store/types/sessions.js +9 -0
  246. package/dist/store/types/sessions.js.map +1 -0
  247. package/dist/store/types/tasks.d.ts +2 -0
  248. package/dist/store/types/tasks.d.ts.map +1 -1
  249. package/dist/task/backend/memory.d.ts +4 -1
  250. package/dist/task/backend/memory.d.ts.map +1 -1
  251. package/dist/task/backend/memory.js +81 -0
  252. package/dist/task/backend/memory.js.map +1 -1
  253. package/dist/task/backend/types.d.ts +30 -0
  254. package/dist/task/backend/types.d.ts.map +1 -1
  255. package/dist/task/backend/types.js.map +1 -1
  256. package/dist/teams/index.d.ts +4 -0
  257. package/dist/teams/index.d.ts.map +1 -0
  258. package/dist/teams/index.js +4 -0
  259. package/dist/teams/index.js.map +1 -0
  260. package/dist/teams/team-loader.d.ts +20 -0
  261. package/dist/teams/team-loader.d.ts.map +1 -0
  262. package/dist/teams/team-loader.js +293 -0
  263. package/dist/teams/team-loader.js.map +1 -0
  264. package/dist/teams/team-runtime.d.ts +139 -0
  265. package/dist/teams/team-runtime.d.ts.map +1 -0
  266. package/dist/teams/team-runtime.js +613 -0
  267. package/dist/teams/team-runtime.js.map +1 -0
  268. package/dist/teams/types.d.ts +266 -0
  269. package/dist/teams/types.d.ts.map +1 -0
  270. package/dist/teams/types.js +20 -0
  271. package/dist/teams/types.js.map +1 -0
  272. package/dist/trigger/router/trigger-router.d.ts +30 -3
  273. package/dist/trigger/router/trigger-router.d.ts.map +1 -1
  274. package/dist/trigger/router/trigger-router.js +30 -3
  275. package/dist/trigger/router/trigger-router.js.map +1 -1
  276. package/dist/trigger/wake/types.d.ts +31 -5
  277. package/dist/trigger/wake/types.d.ts.map +1 -1
  278. package/dist/trigger/wake/types.js +19 -0
  279. package/dist/trigger/wake/types.js.map +1 -1
  280. package/dist/workspace/dataplane-adapter.d.ts +1 -1
  281. package/dist/workspace/dataplane-adapter.d.ts.map +1 -1
  282. package/dist/workspace/dataplane-adapter.js +1 -1
  283. package/dist/workspace/dataplane-adapter.js.map +1 -1
  284. package/dist/workspace/index.d.ts +1 -1
  285. package/dist/workspace/index.d.ts.map +1 -1
  286. package/dist/workspace/strategies/index.d.ts +6 -0
  287. package/dist/workspace/strategies/index.d.ts.map +1 -0
  288. package/dist/workspace/strategies/index.js +5 -0
  289. package/dist/workspace/strategies/index.js.map +1 -0
  290. package/dist/workspace/strategies/optimistic.d.ts +26 -0
  291. package/dist/workspace/strategies/optimistic.d.ts.map +1 -0
  292. package/dist/workspace/strategies/optimistic.js +121 -0
  293. package/dist/workspace/strategies/optimistic.js.map +1 -0
  294. package/dist/workspace/strategies/queue.d.ts +26 -0
  295. package/dist/workspace/strategies/queue.d.ts.map +1 -0
  296. package/dist/workspace/strategies/queue.js +67 -0
  297. package/dist/workspace/strategies/queue.js.map +1 -0
  298. package/dist/workspace/strategies/registry.d.ts +37 -0
  299. package/dist/workspace/strategies/registry.d.ts.map +1 -0
  300. package/dist/workspace/strategies/registry.js +63 -0
  301. package/dist/workspace/strategies/registry.js.map +1 -0
  302. package/dist/workspace/strategies/trunk.d.ts +20 -0
  303. package/dist/workspace/strategies/trunk.d.ts.map +1 -0
  304. package/dist/workspace/strategies/trunk.js +108 -0
  305. package/dist/workspace/strategies/trunk.js.map +1 -0
  306. package/dist/workspace/strategies/types.d.ts +104 -0
  307. package/dist/workspace/strategies/types.d.ts.map +1 -0
  308. package/dist/workspace/strategies/types.js +11 -0
  309. package/dist/workspace/strategies/types.js.map +1 -0
  310. package/dist/workspace/types.d.ts +1 -1
  311. package/dist/workspace/types.d.ts.map +1 -1
  312. package/dist/workspace/workspace-manager.d.ts +1 -1
  313. package/dist/workspace/workspace-manager.d.ts.map +1 -1
  314. package/docs/implementation-details.md +1127 -0
  315. package/docs/implementation-summary.md +448 -0
  316. package/docs/mail-integration.md +608 -0
  317. package/docs/plan-self-driving-support.md +433 -0
  318. package/docs/spec-self-driving-support.md +462 -0
  319. package/docs/team-templates.md +860 -0
  320. package/docs/teams.md +233 -0
  321. package/package.json +5 -3
  322. package/src/acp/__tests__/integration.test.ts +161 -1
  323. package/src/acp/__tests__/macro-agent.test.ts +95 -0
  324. package/src/acp/__tests__/session-persistence.test.ts +276 -0
  325. package/src/acp/macro-agent.ts +79 -7
  326. package/src/acp/session-mapper.ts +108 -1
  327. package/src/acp/types.ts +33 -1
  328. package/src/agent/agent-manager.ts +278 -6
  329. package/src/agent/types.ts +27 -0
  330. package/src/agent/wake.ts +15 -0
  331. package/src/agent-detection/__tests__/command-builder.test.ts +336 -0
  332. package/src/agent-detection/__tests__/detector.test.ts +768 -0
  333. package/src/agent-detection/__tests__/registry.test.ts +254 -0
  334. package/src/agent-detection/command-builder.ts +90 -0
  335. package/src/agent-detection/detector.ts +307 -0
  336. package/src/agent-detection/index.ts +36 -0
  337. package/src/agent-detection/registry.ts +200 -0
  338. package/src/agent-detection/types.ts +184 -0
  339. package/src/api/__tests__/conversation-api.test.ts +468 -0
  340. package/src/api/server.ts +425 -1
  341. package/src/api/types.ts +64 -1
  342. package/src/cli/acp.ts +9 -1
  343. package/src/cli/index.ts +44 -0
  344. package/src/cli/mcp.ts +47 -0
  345. package/src/config/index.ts +9 -0
  346. package/src/config/project-config.ts +107 -0
  347. package/src/lifecycle/cascade.ts +1 -1
  348. package/src/lifecycle/handlers/index.ts +8 -0
  349. package/src/lifecycle/handlers/worker.ts +48 -3
  350. package/src/mail/__tests__/conversation-lifecycle.test.ts +409 -0
  351. package/src/mail/__tests__/eventstore-stores.test.ts +1073 -0
  352. package/src/mail/__tests__/mail-full-agent.e2e.test.ts +575 -0
  353. package/src/mail/__tests__/mail-integration.test.ts +759 -0
  354. package/src/mail/__tests__/mail-map-protocol.e2e.test.ts +1068 -0
  355. package/src/mail/__tests__/mail-service.test.ts +506 -0
  356. package/src/mail/__tests__/turn-recorder.test.ts +328 -0
  357. package/src/mail/conversation-map.ts +107 -0
  358. package/src/mail/index.ts +25 -0
  359. package/src/mail/mail-service.ts +257 -0
  360. package/src/mail/stores/eventstore-conversation-store.ts +146 -0
  361. package/src/mail/stores/eventstore-participant-store.ts +172 -0
  362. package/src/mail/stores/eventstore-thread-store.ts +129 -0
  363. package/src/mail/stores/eventstore-turn-store.ts +173 -0
  364. package/src/mail/stores/index.ts +12 -0
  365. package/src/mail/stores/types.ts +160 -0
  366. package/src/mail/turn-recorder.ts +124 -0
  367. package/src/map/README.md +79 -0
  368. package/src/map/adapter/__tests__/extensions.test.ts +359 -0
  369. package/src/map/adapter/__tests__/map-adapter.test.ts +90 -0
  370. package/src/map/adapter/__tests__/workspace-files.test.ts +673 -0
  371. package/src/map/adapter/acp-over-map.ts +45 -2
  372. package/src/map/adapter/event-translator.ts +4 -0
  373. package/src/map/adapter/extensions/agent-detection.ts +201 -0
  374. package/src/map/adapter/extensions/index.ts +63 -0
  375. package/src/map/adapter/extensions/resume.ts +114 -0
  376. package/src/map/adapter/extensions/workspace-files.ts +449 -0
  377. package/src/map/adapter/mail-handler-adapter.ts +429 -0
  378. package/src/map/adapter/map-adapter.ts +173 -27
  379. package/src/map/adapter/rpc-handler.ts +8 -1
  380. package/src/map/index.ts +3 -0
  381. package/src/map/types.ts +3 -1
  382. package/src/mcp/mcp-server.ts +67 -0
  383. package/src/mcp/tools/claim_task.ts +86 -0
  384. package/src/mcp/tools/done.ts +59 -10
  385. package/src/mcp/tools/list_claimable_tasks.ts +93 -0
  386. package/src/mcp/tools/unclaim_task.ts +71 -0
  387. package/src/metrics/index.ts +9 -0
  388. package/src/metrics/metrics.ts +280 -0
  389. package/src/roles/capabilities.ts +3 -0
  390. package/src/roles/types.ts +2 -1
  391. package/src/router/README.md +120 -0
  392. package/src/router/__tests__/message-router.test.ts +561 -0
  393. package/src/router/channels.ts +3 -4
  394. package/src/router/message-router.ts +308 -22
  395. package/src/router/role-resolver.ts +22 -1
  396. package/src/router/types.ts +36 -1
  397. package/src/server/combined-server.ts +36 -2
  398. package/src/store/README.md +134 -0
  399. package/src/store/event-store.ts +546 -3
  400. package/src/store/types/agents.ts +1 -1
  401. package/src/store/types/conversations.ts +129 -0
  402. package/src/store/types/events.ts +5 -1
  403. package/src/store/types/index.ts +2 -0
  404. package/src/store/types/sessions.ts +53 -0
  405. package/src/store/types/tasks.ts +3 -0
  406. package/src/task/backend/memory.ts +116 -0
  407. package/src/task/backend/types.ts +43 -0
  408. package/src/teams/__tests__/cross-subsystem.integration.test.ts +983 -0
  409. package/src/teams/__tests__/e2e/team-runtime.e2e.test.ts +553 -0
  410. package/src/teams/__tests__/team-system.test.ts +1280 -0
  411. package/src/teams/index.ts +13 -0
  412. package/src/teams/team-loader.ts +434 -0
  413. package/src/teams/team-runtime.ts +727 -0
  414. package/src/teams/types.ts +377 -0
  415. package/src/trigger/router/trigger-router.ts +30 -3
  416. package/src/trigger/wake/types.ts +32 -5
  417. package/src/trigger/wake/wake-manager.ts +2 -2
  418. package/src/workspace/dataplane-adapter.ts +1 -1
  419. package/src/workspace/index.ts +1 -1
  420. package/src/workspace/strategies/index.ts +18 -0
  421. package/src/workspace/strategies/optimistic.ts +136 -0
  422. package/src/workspace/strategies/queue.ts +81 -0
  423. package/src/workspace/strategies/registry.ts +89 -0
  424. package/src/workspace/strategies/trunk.ts +123 -0
  425. package/src/workspace/strategies/types.ts +145 -0
  426. package/src/workspace/types.ts +1 -1
  427. package/src/workspace/workspace-manager.ts +1 -1
  428. package/.claude/settings.local.json +0 -59
  429. package/dist/map/utils/address-translation.d.ts +0 -99
  430. package/dist/map/utils/address-translation.d.ts.map +0 -1
  431. package/dist/map/utils/address-translation.js +0 -285
  432. package/dist/map/utils/address-translation.js.map +0 -1
  433. package/dist/map/utils/index.d.ts +0 -7
  434. package/dist/map/utils/index.d.ts.map +0 -1
  435. package/dist/map/utils/index.js +0 -7
  436. package/dist/map/utils/index.js.map +0 -1
  437. package/openspec/AGENTS.md +0 -456
  438. package/openspec/changes/archive/2025-12-21-add-mvp-foundation/design.md +0 -128
  439. package/openspec/changes/archive/2025-12-21-add-mvp-foundation/proposal.md +0 -49
  440. package/openspec/changes/archive/2025-12-21-add-mvp-foundation/specs/agent-manager/spec.md +0 -150
  441. package/openspec/changes/archive/2025-12-21-add-mvp-foundation/specs/cli-api/spec.md +0 -258
  442. package/openspec/changes/archive/2025-12-21-add-mvp-foundation/specs/event-store/spec.md +0 -160
  443. package/openspec/changes/archive/2025-12-21-add-mvp-foundation/specs/mcp-tools/spec.md +0 -224
  444. package/openspec/changes/archive/2025-12-21-add-mvp-foundation/specs/message-router/spec.md +0 -153
  445. package/openspec/changes/archive/2025-12-21-add-mvp-foundation/specs/task-manager/spec.md +0 -136
  446. package/openspec/changes/archive/2025-12-21-add-mvp-foundation/tasks.md +0 -147
  447. package/openspec/project.md +0 -31
  448. package/openspec/specs/agent-manager/spec.md +0 -154
  449. package/openspec/specs/cli-api/spec.md +0 -262
  450. package/openspec/specs/event-store/spec.md +0 -164
  451. package/openspec/specs/mcp-tools/spec.md +0 -228
  452. package/openspec/specs/message-router/spec.md +0 -157
  453. package/openspec/specs/task-manager/spec.md +0 -140
  454. package/references/acp-factory-ref/CHANGELOG.md +0 -33
  455. package/references/acp-factory-ref/LICENSE +0 -21
  456. package/references/acp-factory-ref/README.md +0 -341
  457. package/references/acp-factory-ref/package-lock.json +0 -3102
  458. package/references/acp-factory-ref/package.json +0 -96
  459. package/references/acp-factory-ref/python/CHANGELOG.md +0 -33
  460. package/references/acp-factory-ref/python/LICENSE +0 -21
  461. package/references/acp-factory-ref/python/Makefile +0 -57
  462. package/references/acp-factory-ref/python/README.md +0 -253
  463. package/references/acp-factory-ref/python/pyproject.toml +0 -73
  464. package/references/acp-factory-ref/python/tests/__init__.py +0 -0
  465. package/references/acp-factory-ref/python/tests/e2e/__init__.py +0 -1
  466. package/references/acp-factory-ref/python/tests/e2e/test_codex_e2e.py +0 -349
  467. package/references/acp-factory-ref/python/tests/e2e/test_gemini_e2e.py +0 -165
  468. package/references/acp-factory-ref/python/tests/e2e/test_opencode_e2e.py +0 -296
  469. package/references/acp-factory-ref/python/tests/test_client_handler.py +0 -543
  470. package/references/acp-factory-ref/python/tests/test_pushable.py +0 -199
  471. package/references/claude-code-acp/.github/workflows/ci.yml +0 -45
  472. package/references/claude-code-acp/.github/workflows/publish.yml +0 -34
  473. package/references/claude-code-acp/.prettierrc.json +0 -4
  474. package/references/claude-code-acp/CHANGELOG.md +0 -249
  475. package/references/claude-code-acp/LICENSE +0 -222
  476. package/references/claude-code-acp/README.md +0 -53
  477. package/references/claude-code-acp/docs/RELEASES.md +0 -24
  478. package/references/claude-code-acp/eslint.config.js +0 -48
  479. package/references/claude-code-acp/package-lock.json +0 -4570
  480. package/references/claude-code-acp/package.json +0 -88
  481. package/references/claude-code-acp/scripts/release.sh +0 -119
  482. package/references/claude-code-acp/src/acp-agent.ts +0 -2065
  483. package/references/claude-code-acp/src/index.ts +0 -26
  484. package/references/claude-code-acp/src/lib.ts +0 -38
  485. package/references/claude-code-acp/src/mcp-server.ts +0 -911
  486. package/references/claude-code-acp/src/settings.ts +0 -522
  487. package/references/claude-code-acp/src/tests/.claude/commands/quick-math.md +0 -5
  488. package/references/claude-code-acp/src/tests/.claude/commands/say-hello.md +0 -6
  489. package/references/claude-code-acp/src/tests/acp-agent-fork.test.ts +0 -479
  490. package/references/claude-code-acp/src/tests/acp-agent.test.ts +0 -1502
  491. package/references/claude-code-acp/src/tests/extract-lines.test.ts +0 -103
  492. package/references/claude-code-acp/src/tests/fork-session.test.ts +0 -335
  493. package/references/claude-code-acp/src/tests/replace-and-calculate-location.test.ts +0 -334
  494. package/references/claude-code-acp/src/tests/settings.test.ts +0 -617
  495. package/references/claude-code-acp/src/tests/skills-options.test.ts +0 -187
  496. package/references/claude-code-acp/src/tests/tools.test.ts +0 -318
  497. package/references/claude-code-acp/src/tests/typescript-declarations.test.ts +0 -558
  498. package/references/claude-code-acp/src/tools.ts +0 -819
  499. package/references/claude-code-acp/src/utils.ts +0 -171
  500. package/references/claude-code-acp/tsconfig.json +0 -18
  501. package/references/claude-code-acp/vitest.config.ts +0 -19
  502. package/references/multi-agent-protocol/.sudocode/issues.jsonl +0 -82
  503. package/references/multi-agent-protocol/.sudocode/specs.jsonl +0 -9
  504. package/references/multi-agent-protocol/LICENSE +0 -21
  505. package/references/multi-agent-protocol/README.md +0 -113
  506. package/references/multi-agent-protocol/docs/00-design-specification.md +0 -460
  507. package/references/multi-agent-protocol/docs/01-open-questions.md +0 -1050
  508. package/references/multi-agent-protocol/docs/02-wire-protocol.md +0 -296
  509. package/references/multi-agent-protocol/docs/03-streaming-semantics.md +0 -252
  510. package/references/multi-agent-protocol/docs/04-error-handling.md +0 -231
  511. package/references/multi-agent-protocol/docs/05-connection-model.md +0 -244
  512. package/references/multi-agent-protocol/docs/06-visibility-permissions.md +0 -243
  513. package/references/multi-agent-protocol/docs/07-federation.md +0 -259
  514. package/references/multi-agent-protocol/docs/08-macro-agent-migration.md +0 -253
  515. package/references/multi-agent-protocol/package-lock.json +0 -3239
  516. package/references/multi-agent-protocol/package.json +0 -56
  517. package/references/multi-agent-protocol/schema/meta.json +0 -337
  518. package/references/multi-agent-protocol/schema/schema.json +0 -1828
@@ -32,6 +32,18 @@ import type {
32
32
  TaskId,
33
33
  EventId,
34
34
  Timestamp,
35
+ Conversation,
36
+ ConversationTurn,
37
+ ConversationThread,
38
+ ConversationParticipant,
39
+ ConversationFilter,
40
+ TurnFilter,
41
+ ConversationChangeCallback,
42
+ TurnChangeCallback,
43
+ ConversationType,
44
+ ConversationStatus,
45
+ Session,
46
+ SessionState,
35
47
  } from './types/index.js';
36
48
  import { CURRENT_EVENT_VERSION } from './types/events.js';
37
49
  import { migrateEvent } from './migrations.js';
@@ -92,6 +104,7 @@ function createBetterSqlite3Persister(
92
104
  export type AgentChangeCallback = (agentId: AgentId, agent: Agent | null) => void;
93
105
  export type TaskChangeCallback = (taskId: TaskId, task: Task | null) => void;
94
106
  export type MessageCallback = (agentId: AgentId, messages: QueuedMessage[]) => void;
107
+ export type SessionChangeCallback = (sessionId: string, session: Session | null) => void;
95
108
 
96
109
  // Unsubscribe function type
97
110
  export type Unsubscribe = () => void;
@@ -163,11 +176,24 @@ export interface EventStore {
163
176
  getSubscriptions(agentId: AgentId): Subscription[];
164
177
  getSubscribers(subscription: Subscription): AgentId[];
165
178
 
179
+ // Session views
180
+ getSession(sessionId: string): Session | null;
181
+ listSessions(filter?: { state?: SessionState; agent_id?: AgentId }): Session[];
182
+
183
+ // Conversation views
184
+ getConversation(conversationId: string): Conversation | null;
185
+ listConversations(filter?: ConversationFilter): Conversation[];
186
+ listTurns(filter: TurnFilter): ConversationTurn[];
187
+ listParticipants(conversationId: string, active?: boolean): ConversationParticipant[];
188
+
166
189
  // Reactive updates
167
190
  onAgentChange(callback: AgentChangeCallback): Unsubscribe;
168
191
  onAgentChange(agentId: AgentId, callback: AgentChangeCallback): Unsubscribe;
169
192
  onTaskChange(callback: TaskChangeCallback): Unsubscribe;
170
193
  onMessageChange(agentId: AgentId, callback: MessageCallback): Unsubscribe;
194
+ onSessionChange(callback: SessionChangeCallback): Unsubscribe;
195
+ onConversationChange(callback: ConversationChangeCallback): Unsubscribe;
196
+ onTurnChange(callback: TurnChangeCallback): Unsubscribe;
171
197
 
172
198
  // Lifecycle
173
199
  persist(): Promise<void>;
@@ -307,7 +333,10 @@ export async function createEventStore(config: StoreConfig = {}): Promise<EventS
307
333
  const agentListeners = new Set<AgentChangeCallback>();
308
334
  const agentIdListeners = new Map<AgentId, Set<AgentChangeCallback>>();
309
335
  const taskListeners = new Set<TaskChangeCallback>();
336
+ const sessionListeners = new Set<SessionChangeCallback>();
310
337
  const messageListeners = new Map<AgentId, Set<MessageCallback>>();
338
+ const conversationListeners = new Set<ConversationChangeCallback>();
339
+ const turnListeners = new Set<TurnChangeCallback>();
311
340
 
312
341
  /**
313
342
  * Emit a new event to the store
@@ -334,7 +363,7 @@ export async function createEventStore(config: StoreConfig = {}): Promise<EventS
334
363
  });
335
364
 
336
365
  // Update materialized views
337
- applyEventToViews(store, event, notifyAgentChange, notifyTaskChange, notifyMessageChange);
366
+ applyEventToViews(store, event, notifyAgentChange, notifyTaskChange, notifyMessageChange, notifySessionChange, notifyConversationChange, notifyTurnChange);
338
367
 
339
368
  return event;
340
369
  }
@@ -640,6 +669,176 @@ export async function createEventStore(config: StoreConfig = {}): Promise<EventS
640
669
  return () => messageListeners.get(agentId)?.delete(callback);
641
670
  }
642
671
 
672
+ /**
673
+ * Notify conversation change listeners
674
+ */
675
+ function notifyConversationChange(conversationId: string, conversation: Conversation | null): void {
676
+ for (const callback of conversationListeners) {
677
+ callback(conversationId, conversation);
678
+ }
679
+ }
680
+
681
+ /**
682
+ * Notify turn change listeners
683
+ */
684
+ function notifyTurnChange(conversationId: string, turn: ConversationTurn): void {
685
+ for (const callback of turnListeners) {
686
+ callback(conversationId, turn);
687
+ }
688
+ }
689
+
690
+ /**
691
+ * Subscribe to conversation changes
692
+ */
693
+ function onConversationChange(callback: ConversationChangeCallback): Unsubscribe {
694
+ conversationListeners.add(callback);
695
+ return () => conversationListeners.delete(callback);
696
+ }
697
+
698
+ /**
699
+ * Subscribe to turn changes
700
+ */
701
+ function onTurnChange(callback: TurnChangeCallback): Unsubscribe {
702
+ turnListeners.add(callback);
703
+ return () => turnListeners.delete(callback);
704
+ }
705
+
706
+ // ─── Session View Queries ───
707
+
708
+ function getSession(sessionId: string): Session | null {
709
+ const row = store.getRow('sessions', sessionId);
710
+ if (!row.id) return null;
711
+ return rowToSession(row);
712
+ }
713
+
714
+ function listSessions(filter?: { state?: SessionState; agent_id?: AgentId }): Session[] {
715
+ const sessions: Session[] = [];
716
+ const rowIds = store.getRowIds('sessions');
717
+
718
+ for (const rowId of rowIds) {
719
+ const row = store.getRow('sessions', rowId);
720
+ if (!row.id) continue;
721
+
722
+ const session = rowToSession(row);
723
+
724
+ if (filter) {
725
+ if (filter.state && session.state !== filter.state) continue;
726
+ if (filter.agent_id && session.current_agent_id !== filter.agent_id && session.head_manager_id !== filter.agent_id) continue;
727
+ }
728
+
729
+ sessions.push(session);
730
+ }
731
+
732
+ return sessions;
733
+ }
734
+
735
+ /**
736
+ * Notify session change listeners
737
+ */
738
+ function notifySessionChange(sessionId: string, session: Session | null): void {
739
+ for (const callback of sessionListeners) {
740
+ callback(sessionId, session);
741
+ }
742
+ }
743
+
744
+ /**
745
+ * Subscribe to session changes
746
+ */
747
+ function onSessionChange(callback: SessionChangeCallback): Unsubscribe {
748
+ sessionListeners.add(callback);
749
+ return () => sessionListeners.delete(callback);
750
+ }
751
+
752
+ // ─── Conversation View Queries ───
753
+
754
+ function getConversation(conversationId: string): Conversation | null {
755
+ const row = store.getRow('conversations', conversationId);
756
+ if (!row.id) return null;
757
+ return rowToConversation(row);
758
+ }
759
+
760
+ function listConversations(filter?: ConversationFilter): Conversation[] {
761
+ const conversations: Conversation[] = [];
762
+ const rowIds = store.getRowIds('conversations');
763
+
764
+ for (const rowId of rowIds) {
765
+ const row = store.getRow('conversations', rowId);
766
+ if (!row.id) continue;
767
+
768
+ const conversation = rowToConversation(row);
769
+
770
+ if (filter) {
771
+ if (filter.type && conversation.type !== filter.type) continue;
772
+ if (filter.status && conversation.status !== filter.status) continue;
773
+ if (filter.parentConversationId && conversation.parentConversationId !== filter.parentConversationId) continue;
774
+ if (filter.participantId) {
775
+ // Check participants table for membership
776
+ const partRow = store.getRow('participants', `${conversation.id}:${filter.participantId}`);
777
+ if (!partRow.id) continue;
778
+ // Skip if participant has left
779
+ if (partRow.left_at && (partRow.left_at as number) > 0) continue;
780
+ }
781
+ }
782
+
783
+ conversations.push(conversation);
784
+ }
785
+
786
+ return conversations;
787
+ }
788
+
789
+ function listTurns(filter: TurnFilter): ConversationTurn[] {
790
+ const turns: ConversationTurn[] = [];
791
+ const rowIds = store.getRowIds('turns');
792
+
793
+ for (const rowId of rowIds) {
794
+ const row = store.getRow('turns', rowId);
795
+ if (!row.id) continue;
796
+
797
+ const turn = rowToTurn(row);
798
+
799
+ // Filter by conversation (required)
800
+ if (turn.conversationId !== filter.conversationId) continue;
801
+
802
+ // Optional filters
803
+ if (filter.threadId && turn.threadId !== filter.threadId) continue;
804
+ if (filter.contentType && turn.contentType !== filter.contentType) continue;
805
+ if (filter.participantId && turn.participant !== filter.participantId) continue;
806
+
807
+ turns.push(turn);
808
+ }
809
+
810
+ // Sort
811
+ const order = filter.order ?? 'asc';
812
+ turns.sort((a, b) => order === 'asc' ? a.timestamp - b.timestamp : b.timestamp - a.timestamp);
813
+
814
+ // Limit
815
+ if (filter.limit) {
816
+ return turns.slice(0, filter.limit);
817
+ }
818
+
819
+ return turns;
820
+ }
821
+
822
+ function listParticipants(conversationId: string, active?: boolean): ConversationParticipant[] {
823
+ const participants: ConversationParticipant[] = [];
824
+ const rowIds = store.getRowIds('participants');
825
+
826
+ for (const rowId of rowIds) {
827
+ const row = store.getRow('participants', rowId);
828
+ if (!row.id) continue;
829
+
830
+ if (row.conversation_id !== conversationId) continue;
831
+
832
+ const participant = rowToParticipant(row);
833
+
834
+ if (active && participant.leftAt) continue;
835
+
836
+ participants.push(participant);
837
+ }
838
+
839
+ return participants;
840
+ }
841
+
643
842
  /**
644
843
  * Persist store to disk
645
844
  */
@@ -904,7 +1103,7 @@ export async function createEventStore(config: StoreConfig = {}): Promise<EventS
904
1103
  });
905
1104
 
906
1105
  // Update materialized views
907
- applyEventToViews(store, event, notifyAgentChange, notifyTaskChange, notifyMessageChange);
1106
+ applyEventToViews(store, event, notifyAgentChange, notifyTaskChange, notifyMessageChange, notifySessionChange, notifyConversationChange, notifyTurnChange);
908
1107
  }
909
1108
  }
910
1109
 
@@ -950,6 +1149,12 @@ export async function createEventStore(config: StoreConfig = {}): Promise<EventS
950
1149
  listTasks,
951
1150
  getMessages,
952
1151
  getFullMessage,
1152
+ getSession,
1153
+ listSessions,
1154
+ getConversation,
1155
+ listConversations,
1156
+ listTurns,
1157
+ listParticipants,
953
1158
 
954
1159
  // Subscriptions
955
1160
  addSubscription,
@@ -961,6 +1166,9 @@ export async function createEventStore(config: StoreConfig = {}): Promise<EventS
961
1166
  onAgentChange,
962
1167
  onTaskChange,
963
1168
  onMessageChange,
1169
+ onSessionChange,
1170
+ onConversationChange,
1171
+ onTurnChange,
964
1172
 
965
1173
  // Lifecycle
966
1174
  persist,
@@ -992,6 +1200,11 @@ function initializeTables(store: Store): void {
992
1200
  store.getRowIds('tasks');
993
1201
  store.getRowIds('messages');
994
1202
  store.getRowIds('subscriptions');
1203
+ store.getRowIds('sessions');
1204
+ store.getRowIds('conversations');
1205
+ store.getRowIds('turns');
1206
+ store.getRowIds('threads');
1207
+ store.getRowIds('participants');
995
1208
  }
996
1209
 
997
1210
  /**
@@ -1008,6 +1221,21 @@ function rebuildViews(store: Store): void {
1008
1221
  for (const rowId of store.getRowIds('messages')) {
1009
1222
  store.delRow('messages', rowId);
1010
1223
  }
1224
+ for (const rowId of store.getRowIds('sessions')) {
1225
+ store.delRow('sessions', rowId);
1226
+ }
1227
+ for (const rowId of store.getRowIds('conversations')) {
1228
+ store.delRow('conversations', rowId);
1229
+ }
1230
+ for (const rowId of store.getRowIds('turns')) {
1231
+ store.delRow('turns', rowId);
1232
+ }
1233
+ for (const rowId of store.getRowIds('threads')) {
1234
+ store.delRow('threads', rowId);
1235
+ }
1236
+ for (const rowId of store.getRowIds('participants')) {
1237
+ store.delRow('participants', rowId);
1238
+ }
1011
1239
 
1012
1240
  // Replay all events to rebuild views
1013
1241
  const events: Event[] = [];
@@ -1036,7 +1264,7 @@ function rebuildViews(store: Store): void {
1036
1264
  // Apply each event (no-op callbacks since we're rebuilding)
1037
1265
  const noop = () => {};
1038
1266
  for (const event of events) {
1039
- applyEventToViews(store, event, noop, noop, noop);
1267
+ applyEventToViews(store, event, noop, noop, noop, noop, noop, noop);
1040
1268
  }
1041
1269
  }
1042
1270
 
@@ -1049,6 +1277,9 @@ function applyEventToViews(
1049
1277
  notifyAgentChange: (agentId: AgentId, agent: Agent | null) => void,
1050
1278
  notifyTaskChange: (taskId: TaskId, task: Task | null) => void,
1051
1279
  notifyMessageChange: (agentId: AgentId) => void,
1280
+ notifySessionChange: (sessionId: string, session: Session | null) => void,
1281
+ notifyConversationChange: (conversationId: string, conversation: Conversation | null) => void,
1282
+ notifyTurnChange: (conversationId: string, turn: ConversationTurn) => void,
1052
1283
  ): void {
1053
1284
  switch (event.type) {
1054
1285
  case 'spawn':
@@ -1066,6 +1297,18 @@ function applyEventToViews(
1066
1297
  case 'task':
1067
1298
  applyTaskEvent(store, event, notifyTaskChange);
1068
1299
  break;
1300
+ case 'session':
1301
+ applySessionEvent(store, event, notifySessionChange);
1302
+ break;
1303
+ case 'conversation':
1304
+ applyConversationEvent(store, event, notifyConversationChange);
1305
+ break;
1306
+ case 'turn':
1307
+ applyTurnEvent(store, event, notifyTurnChange);
1308
+ break;
1309
+ case 'thread':
1310
+ applyThreadEvent(store, event);
1311
+ break;
1069
1312
  case 'peer_message':
1070
1313
  case 'peer_request':
1071
1314
  // Peer events are stored in the event log for audit trail
@@ -1493,3 +1736,303 @@ function rowToTask(row: Record<string, unknown>): Task {
1493
1736
  retryState: row.retry_state ? JSON.parse(row.retry_state as string) : undefined,
1494
1737
  };
1495
1738
  }
1739
+
1740
+ // ─────────────────────────────────────────────────────────────────────────────
1741
+ // Session Event Handlers
1742
+ // ─────────────────────────────────────────────────────────────────────────────
1743
+
1744
+ /**
1745
+ * Apply session event to sessions view
1746
+ */
1747
+ function applySessionEvent(
1748
+ store: Store,
1749
+ event: Event,
1750
+ notify: (sessionId: string, session: Session | null) => void,
1751
+ ): void {
1752
+ const payload = event.payload as {
1753
+ action: string;
1754
+ session_id: string;
1755
+ head_manager_id?: AgentId;
1756
+ agent_id?: AgentId;
1757
+ target_agent_id?: AgentId;
1758
+ previous_agent_id?: AgentId;
1759
+ };
1760
+
1761
+ const sessionId = payload.session_id;
1762
+
1763
+ switch (payload.action) {
1764
+ case 'created': {
1765
+ store.setRow('sessions', sessionId, {
1766
+ id: sessionId,
1767
+ head_manager_id: payload.head_manager_id ?? '',
1768
+ current_agent_id: payload.head_manager_id ?? '',
1769
+ state: 'active',
1770
+ created_at: event.timestamp,
1771
+ updated_at: event.timestamp,
1772
+ closed_at: 0,
1773
+ });
1774
+ break;
1775
+ }
1776
+ case 'mounted': {
1777
+ store.setPartialRow('sessions', sessionId, {
1778
+ current_agent_id: payload.target_agent_id ?? '',
1779
+ state: 'mounted',
1780
+ updated_at: event.timestamp,
1781
+ });
1782
+ break;
1783
+ }
1784
+ case 'unmounted': {
1785
+ const existing = store.getRow('sessions', sessionId);
1786
+ store.setPartialRow('sessions', sessionId, {
1787
+ current_agent_id: existing.head_manager_id as string,
1788
+ state: 'active',
1789
+ updated_at: event.timestamp,
1790
+ });
1791
+ break;
1792
+ }
1793
+ case 'closed': {
1794
+ store.setPartialRow('sessions', sessionId, {
1795
+ state: 'closed',
1796
+ updated_at: event.timestamp,
1797
+ closed_at: event.timestamp,
1798
+ });
1799
+ break;
1800
+ }
1801
+ }
1802
+
1803
+ const session = rowToSession(store.getRow('sessions', sessionId));
1804
+ notify(sessionId, session);
1805
+ }
1806
+
1807
+ /**
1808
+ * Convert a TinyBase row to a Session object
1809
+ */
1810
+ function rowToSession(row: Record<string, unknown>): Session {
1811
+ return {
1812
+ id: row.id as string,
1813
+ head_manager_id: row.head_manager_id as AgentId,
1814
+ current_agent_id: row.current_agent_id as AgentId,
1815
+ state: row.state as SessionState,
1816
+ created_at: row.created_at as Timestamp,
1817
+ updated_at: row.updated_at as Timestamp,
1818
+ closed_at: (row.closed_at as number) || undefined,
1819
+ };
1820
+ }
1821
+
1822
+ // ─────────────────────────────────────────────────────────────────────────────
1823
+ // Conversation Event Handlers
1824
+ // ─────────────────────────────────────────────────────────────────────────────
1825
+
1826
+ /**
1827
+ * Apply conversation event to conversations view
1828
+ */
1829
+ function applyConversationEvent(
1830
+ store: Store,
1831
+ event: Event,
1832
+ notify: (conversationId: string, conversation: Conversation | null) => void,
1833
+ ): void {
1834
+ const payload = event.payload;
1835
+ const conversationId = payload.conversation_id as string;
1836
+
1837
+ switch (payload.action) {
1838
+ case 'created': {
1839
+ store.setRow('conversations', conversationId, {
1840
+ id: conversationId,
1841
+ type: payload.conversation_type as string,
1842
+ status: 'active',
1843
+ subject: (payload.subject as string) ?? '',
1844
+ parent_conversation_id: (payload.parent_conversation_id as string) ?? '',
1845
+ created_by: event.source.agent_id ?? 'unknown',
1846
+ created_at: event.timestamp,
1847
+ updated_at: event.timestamp,
1848
+ closed_at: 0,
1849
+ closed_by: '',
1850
+ close_reason: '',
1851
+ participant_count: 0,
1852
+ metadata: payload.metadata ? JSON.stringify(payload.metadata) : '',
1853
+ });
1854
+ break;
1855
+ }
1856
+ case 'closed': {
1857
+ const closeReason = (payload.close_reason as string) ?? '';
1858
+ // Map close_reason to valid ConversationStatus
1859
+ const validStatuses = new Set(['completed', 'failed', 'archived']);
1860
+ const closedStatus = validStatuses.has(closeReason) ? closeReason : 'completed';
1861
+ store.setPartialRow('conversations', conversationId, {
1862
+ status: closedStatus,
1863
+ closed_at: event.timestamp,
1864
+ updated_at: event.timestamp,
1865
+ closed_by: (payload.closed_by as string) ?? event.source.agent_id ?? '',
1866
+ close_reason: closeReason,
1867
+ });
1868
+ break;
1869
+ }
1870
+ case 'participant_joined': {
1871
+ const participantId = payload.participant_id as string;
1872
+ const partId = `${conversationId}:${participantId}`;
1873
+ store.setRow('participants', partId, {
1874
+ id: participantId,
1875
+ conversation_id: conversationId,
1876
+ type: (payload.participant_type as string) ?? 'agent',
1877
+ role: (payload.participant_role as string) ?? 'worker',
1878
+ joined_at: event.timestamp,
1879
+ left_at: 0,
1880
+ agent_id: (payload.agent_id as string) ?? '',
1881
+ });
1882
+ // Increment participant count
1883
+ const existing = store.getRow('conversations', conversationId);
1884
+ if (existing.id) {
1885
+ const count = (existing.participant_count as number) || 0;
1886
+ store.setPartialRow('conversations', conversationId, {
1887
+ participant_count: count + 1,
1888
+ updated_at: event.timestamp,
1889
+ });
1890
+ }
1891
+ break;
1892
+ }
1893
+ case 'participant_left': {
1894
+ const leftParticipantId = payload.participant_id as string;
1895
+ const partId = `${conversationId}:${leftParticipantId}`;
1896
+ store.setPartialRow('participants', partId, {
1897
+ left_at: event.timestamp,
1898
+ });
1899
+ // Decrement participant count
1900
+ const existing = store.getRow('conversations', conversationId);
1901
+ if (existing.id) {
1902
+ const count = (existing.participant_count as number) || 0;
1903
+ store.setPartialRow('conversations', conversationId, {
1904
+ participant_count: Math.max(0, count - 1),
1905
+ updated_at: event.timestamp,
1906
+ });
1907
+ }
1908
+ break;
1909
+ }
1910
+ }
1911
+
1912
+ const conversation = rowToConversation(store.getRow('conversations', conversationId));
1913
+ notify(conversationId, conversation);
1914
+ }
1915
+
1916
+ /**
1917
+ * Apply turn event to turns view
1918
+ */
1919
+ function applyTurnEvent(
1920
+ store: Store,
1921
+ event: Event,
1922
+ notify: (conversationId: string, turn: ConversationTurn) => void,
1923
+ ): void {
1924
+ const payload = event.payload;
1925
+
1926
+ if (payload.action !== 'recorded') return;
1927
+
1928
+ const turnId = payload.turn_id as string;
1929
+ const conversationId = payload.conversation_id as string;
1930
+ const content = payload.content;
1931
+
1932
+ store.setRow('turns', turnId, {
1933
+ id: turnId,
1934
+ conversation_id: conversationId,
1935
+ participant: (payload.participant as string) ?? event.source.agent_id ?? '',
1936
+ timestamp: event.timestamp,
1937
+ content_type: (payload.content_type as string) ?? 'text',
1938
+ content: typeof content === 'string' ? content : JSON.stringify(content),
1939
+ thread_id: (payload.thread_id as string) ?? '',
1940
+ in_reply_to: (payload.in_reply_to as string) ?? '',
1941
+ source_type: (payload.source_type as string) ?? 'explicit',
1942
+ source_message_id: (payload.source_message_id as string) ?? '',
1943
+ metadata: payload.metadata ? JSON.stringify(payload.metadata) : '',
1944
+ });
1945
+
1946
+ // Update conversation's updatedAt
1947
+ const convRow = store.getRow('conversations', conversationId);
1948
+ if (convRow.id) {
1949
+ store.setPartialRow('conversations', conversationId, {
1950
+ updated_at: event.timestamp,
1951
+ });
1952
+ }
1953
+
1954
+ const turn = rowToTurn(store.getRow('turns', turnId));
1955
+ notify(conversationId, turn);
1956
+ }
1957
+
1958
+ /**
1959
+ * Apply thread event to threads view
1960
+ */
1961
+ function applyThreadEvent(
1962
+ store: Store,
1963
+ event: Event,
1964
+ ): void {
1965
+ const payload = event.payload;
1966
+
1967
+ if (payload.action !== 'created') return;
1968
+
1969
+ const threadId = payload.thread_id as string;
1970
+ store.setRow('threads', threadId, {
1971
+ id: threadId,
1972
+ conversation_id: (payload.conversation_id as string) ?? '',
1973
+ root_turn_id: (payload.root_turn_id as string) ?? '',
1974
+ subject: (payload.subject as string) ?? '',
1975
+ parent_thread_id: (payload.parent_thread_id as string) ?? '',
1976
+ created_by: event.source.agent_id ?? 'unknown',
1977
+ created_at: event.timestamp,
1978
+ turn_count: 0,
1979
+ });
1980
+ }
1981
+
1982
+ // ─────────────────────────────────────────────────────────────────────────────
1983
+ // Conversation Row Conversion Functions
1984
+ // ─────────────────────────────────────────────────────────────────────────────
1985
+
1986
+ function rowToConversation(row: Record<string, unknown>): Conversation {
1987
+ return {
1988
+ id: row.id as string,
1989
+ type: row.type as ConversationType,
1990
+ status: row.status as ConversationStatus,
1991
+ subject: (row.subject as string) || undefined,
1992
+ parentConversationId: (row.parent_conversation_id as string) || undefined,
1993
+ createdBy: row.created_by as string,
1994
+ createdAt: row.created_at as Timestamp,
1995
+ updatedAt: row.updated_at as Timestamp,
1996
+ closedAt: (row.closed_at as number) || undefined,
1997
+ closedBy: (row.closed_by as string) || undefined,
1998
+ closeReason: (row.close_reason as string) || undefined,
1999
+ participantCount: (row.participant_count as number) || 0,
2000
+ metadata: row.metadata ? JSON.parse(row.metadata as string) : undefined,
2001
+ };
2002
+ }
2003
+
2004
+ function rowToTurn(row: Record<string, unknown>): ConversationTurn {
2005
+ const rawContent = row.content as string;
2006
+ let content: unknown;
2007
+ try {
2008
+ content = JSON.parse(rawContent);
2009
+ } catch {
2010
+ content = rawContent;
2011
+ }
2012
+
2013
+ return {
2014
+ id: row.id as string,
2015
+ conversationId: row.conversation_id as string,
2016
+ participant: row.participant as string,
2017
+ timestamp: row.timestamp as Timestamp,
2018
+ contentType: row.content_type as string,
2019
+ content,
2020
+ threadId: (row.thread_id as string) || undefined,
2021
+ inReplyTo: (row.in_reply_to as string) || undefined,
2022
+ sourceType: (row.source_type as string) as ConversationTurn['sourceType'],
2023
+ sourceMessageId: (row.source_message_id as string) || undefined,
2024
+ metadata: row.metadata ? JSON.parse(row.metadata as string) : undefined,
2025
+ };
2026
+ }
2027
+
2028
+ function rowToParticipant(row: Record<string, unknown>): ConversationParticipant {
2029
+ return {
2030
+ id: row.id as string,
2031
+ conversationId: row.conversation_id as string,
2032
+ type: row.type as ConversationParticipant['type'],
2033
+ role: row.role as ConversationParticipant['role'],
2034
+ joinedAt: row.joined_at as Timestamp,
2035
+ leftAt: (row.left_at as number) || undefined,
2036
+ agentId: (row.agent_id as string) || undefined,
2037
+ };
2038
+ }
@@ -5,7 +5,7 @@
5
5
  import type { AgentId, SessionId, TaskId, Timestamp } from "./primitives.js";
6
6
 
7
7
  // Agent states
8
- export type AgentState = "spawning" | "running" | "stopped";
8
+ export type AgentState = "spawning" | "running" | "stopped" | "failed";
9
9
 
10
10
  export type StopReason =
11
11
  | "completed"