macro-agent 0.1.1 → 0.1.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (1339) hide show
  1. package/.gitattributes +3 -0
  2. package/.opentasks/config.json +9 -0
  3. package/.sudocode/issues.jsonl +28 -0
  4. package/.sudocode/specs.jsonl +4 -0
  5. package/CLAUDE.md +433 -201
  6. package/README.md +129 -371
  7. package/dist/acp/index.d.ts +9 -51
  8. package/dist/acp/index.d.ts.map +1 -1
  9. package/dist/acp/index.js +5 -46
  10. package/dist/acp/index.js.map +1 -1
  11. package/dist/acp/macro-agent.d.ts +28 -255
  12. package/dist/acp/macro-agent.d.ts.map +1 -1
  13. package/dist/acp/macro-agent.js +593 -1231
  14. package/dist/acp/macro-agent.js.map +1 -1
  15. package/dist/acp/map-bridge.d.ts +62 -0
  16. package/dist/acp/map-bridge.d.ts.map +1 -0
  17. package/dist/acp/map-bridge.js +123 -0
  18. package/dist/acp/map-bridge.js.map +1 -0
  19. package/dist/acp/session-mapper.d.ts +29 -126
  20. package/dist/acp/session-mapper.d.ts.map +1 -1
  21. package/dist/acp/session-mapper.js +36 -234
  22. package/dist/acp/session-mapper.js.map +1 -1
  23. package/dist/acp/types.d.ts +24 -535
  24. package/dist/acp/types.d.ts.map +1 -1
  25. package/dist/acp/types.js +7 -7
  26. package/dist/acp/types.js.map +1 -1
  27. package/dist/acp/websocket-server.d.ts +16 -136
  28. package/dist/acp/websocket-server.d.ts.map +1 -1
  29. package/dist/acp/websocket-server.js +131 -371
  30. package/dist/acp/websocket-server.js.map +1 -1
  31. package/dist/adapters/federation.d.ts +76 -0
  32. package/dist/adapters/federation.d.ts.map +1 -0
  33. package/dist/adapters/federation.js +120 -0
  34. package/dist/adapters/federation.js.map +1 -0
  35. package/dist/adapters/inbox-adapter.d.ts +72 -0
  36. package/dist/adapters/inbox-adapter.d.ts.map +1 -0
  37. package/dist/adapters/inbox-adapter.js +196 -0
  38. package/dist/adapters/inbox-adapter.js.map +1 -0
  39. package/dist/adapters/inbox-client-adapter.d.ts +40 -0
  40. package/dist/adapters/inbox-client-adapter.d.ts.map +1 -0
  41. package/dist/adapters/inbox-client-adapter.js +135 -0
  42. package/dist/adapters/inbox-client-adapter.js.map +1 -0
  43. package/dist/adapters/index.d.ts +11 -0
  44. package/dist/adapters/index.d.ts.map +1 -0
  45. package/dist/adapters/index.js +10 -0
  46. package/dist/adapters/index.js.map +1 -0
  47. package/dist/adapters/opentasks-daemon.d.ts +32 -0
  48. package/dist/adapters/opentasks-daemon.d.ts.map +1 -0
  49. package/dist/adapters/opentasks-daemon.js +190 -0
  50. package/dist/adapters/opentasks-daemon.js.map +1 -0
  51. package/dist/adapters/tasks-adapter.d.ts +49 -0
  52. package/dist/adapters/tasks-adapter.d.ts.map +1 -0
  53. package/dist/adapters/tasks-adapter.js +209 -0
  54. package/dist/adapters/tasks-adapter.js.map +1 -0
  55. package/dist/adapters/types.d.ts +198 -0
  56. package/dist/adapters/types.d.ts.map +1 -0
  57. package/dist/adapters/types.js +13 -0
  58. package/dist/adapters/types.js.map +1 -0
  59. package/dist/agent/agent-manager-v2.d.ts +38 -0
  60. package/dist/agent/agent-manager-v2.d.ts.map +1 -0
  61. package/dist/agent/agent-manager-v2.js +1097 -0
  62. package/dist/agent/agent-manager-v2.js.map +1 -0
  63. package/dist/agent/agent-manager.d.ts +52 -42
  64. package/dist/agent/agent-manager.d.ts.map +1 -1
  65. package/dist/agent/agent-manager.js +11 -1255
  66. package/dist/agent/agent-manager.js.map +1 -1
  67. package/dist/agent/agent-store.d.ts +89 -0
  68. package/dist/agent/agent-store.d.ts.map +1 -0
  69. package/dist/agent/agent-store.js +279 -0
  70. package/dist/agent/agent-store.js.map +1 -0
  71. package/dist/agent/types.d.ts +7 -0
  72. package/dist/agent/types.d.ts.map +1 -1
  73. package/dist/agent/types.js.map +1 -1
  74. package/dist/api/index.d.ts +5 -3
  75. package/dist/api/index.d.ts.map +1 -1
  76. package/dist/api/index.js +4 -3
  77. package/dist/api/index.js.map +1 -1
  78. package/dist/api/server.d.ts +6 -123
  79. package/dist/api/server.d.ts.map +1 -1
  80. package/dist/api/server.js +247 -1489
  81. package/dist/api/server.js.map +1 -1
  82. package/dist/api/types.d.ts +20 -248
  83. package/dist/api/types.d.ts.map +1 -1
  84. package/dist/api/types.js +3 -1
  85. package/dist/api/types.js.map +1 -1
  86. package/dist/boot-v2.d.ts +165 -0
  87. package/dist/boot-v2.d.ts.map +1 -0
  88. package/dist/boot-v2.js +315 -0
  89. package/dist/boot-v2.js.map +1 -0
  90. package/dist/cli/acp.d.ts +6 -28
  91. package/dist/cli/acp.d.ts.map +1 -1
  92. package/dist/cli/acp.js +39 -373
  93. package/dist/cli/acp.js.map +1 -1
  94. package/dist/cli/index.d.ts +1 -2
  95. package/dist/cli/index.d.ts.map +1 -1
  96. package/dist/cli/index.js +65 -449
  97. package/dist/cli/index.js.map +1 -1
  98. package/dist/cli/mcp.d.ts +18 -8
  99. package/dist/cli/mcp.d.ts.map +1 -1
  100. package/dist/cli/mcp.js +231 -282
  101. package/dist/cli/mcp.js.map +1 -1
  102. package/dist/cognitive/analyst-role.d.ts +13 -0
  103. package/dist/cognitive/analyst-role.d.ts.map +1 -0
  104. package/dist/cognitive/analyst-role.js +48 -0
  105. package/dist/cognitive/analyst-role.js.map +1 -0
  106. package/dist/cognitive/index.d.ts +18 -0
  107. package/dist/cognitive/index.d.ts.map +1 -0
  108. package/dist/cognitive/index.js +21 -0
  109. package/dist/cognitive/index.js.map +1 -0
  110. package/dist/cognitive/macro-agent-backend.d.ts +40 -0
  111. package/dist/cognitive/macro-agent-backend.d.ts.map +1 -0
  112. package/dist/cognitive/macro-agent-backend.js +290 -0
  113. package/dist/cognitive/macro-agent-backend.js.map +1 -0
  114. package/dist/cognitive/session-converter.d.ts +30 -0
  115. package/dist/cognitive/session-converter.d.ts.map +1 -0
  116. package/dist/cognitive/session-converter.js +119 -0
  117. package/dist/cognitive/session-converter.js.map +1 -0
  118. package/dist/cognitive/types.d.ts +129 -0
  119. package/dist/cognitive/types.d.ts.map +1 -0
  120. package/dist/cognitive/types.js +12 -0
  121. package/dist/cognitive/types.js.map +1 -0
  122. package/dist/cognitive/workspace-handler.d.ts +46 -0
  123. package/dist/cognitive/workspace-handler.d.ts.map +1 -0
  124. package/dist/cognitive/workspace-handler.js +135 -0
  125. package/dist/cognitive/workspace-handler.js.map +1 -0
  126. package/dist/config/project-config.d.ts +13 -2
  127. package/dist/config/project-config.d.ts.map +1 -1
  128. package/dist/config/project-config.js +12 -2
  129. package/dist/config/project-config.js.map +1 -1
  130. package/dist/control/control-client.d.ts +63 -0
  131. package/dist/control/control-client.d.ts.map +1 -0
  132. package/dist/control/control-client.js +276 -0
  133. package/dist/control/control-client.js.map +1 -0
  134. package/dist/control/control-server.d.ts +46 -0
  135. package/dist/control/control-server.d.ts.map +1 -0
  136. package/dist/control/control-server.js +237 -0
  137. package/dist/control/control-server.js.map +1 -0
  138. package/dist/control/index.d.ts +9 -0
  139. package/dist/control/index.d.ts.map +1 -0
  140. package/dist/control/index.js +8 -0
  141. package/dist/control/index.js.map +1 -0
  142. package/dist/control/types.d.ts +64 -0
  143. package/dist/control/types.d.ts.map +1 -0
  144. package/dist/control/types.js +10 -0
  145. package/dist/control/types.js.map +1 -0
  146. package/dist/index.d.ts +15 -16
  147. package/dist/index.d.ts.map +1 -1
  148. package/dist/index.js +17 -34
  149. package/dist/index.js.map +1 -1
  150. package/dist/integrations/context-builder.d.ts +49 -0
  151. package/dist/integrations/context-builder.d.ts.map +1 -0
  152. package/dist/integrations/context-builder.js +160 -0
  153. package/dist/integrations/context-builder.js.map +1 -0
  154. package/dist/integrations/sessionlog.d.ts +58 -0
  155. package/dist/integrations/sessionlog.d.ts.map +1 -0
  156. package/dist/integrations/sessionlog.js +152 -0
  157. package/dist/integrations/sessionlog.js.map +1 -0
  158. package/dist/integrations/skilltree.d.ts +53 -0
  159. package/dist/integrations/skilltree.d.ts.map +1 -0
  160. package/dist/integrations/skilltree.js +140 -0
  161. package/dist/integrations/skilltree.js.map +1 -0
  162. package/dist/lifecycle/cleanup.d.ts +5 -14
  163. package/dist/lifecycle/cleanup.d.ts.map +1 -1
  164. package/dist/lifecycle/cleanup.js +4 -34
  165. package/dist/lifecycle/cleanup.js.map +1 -1
  166. package/dist/lifecycle/handlers-v2.d.ts +33 -0
  167. package/dist/lifecycle/handlers-v2.d.ts.map +1 -0
  168. package/dist/lifecycle/handlers-v2.js +319 -0
  169. package/dist/lifecycle/handlers-v2.js.map +1 -0
  170. package/dist/lifecycle/index.d.ts +3 -5
  171. package/dist/lifecycle/index.d.ts.map +1 -1
  172. package/dist/lifecycle/index.js +3 -12
  173. package/dist/lifecycle/index.js.map +1 -1
  174. package/dist/lifecycle/types.d.ts +2 -0
  175. package/dist/lifecycle/types.d.ts.map +1 -1
  176. package/dist/lifecycle/types.js.map +1 -1
  177. package/dist/map/acp-bridge.d.ts +39 -0
  178. package/dist/map/acp-bridge.d.ts.map +1 -0
  179. package/dist/map/acp-bridge.js +180 -0
  180. package/dist/map/acp-bridge.js.map +1 -0
  181. package/dist/map/cc-swarm-hooks.d.ts +36 -0
  182. package/dist/map/cc-swarm-hooks.d.ts.map +1 -0
  183. package/dist/map/cc-swarm-hooks.js +218 -0
  184. package/dist/map/cc-swarm-hooks.js.map +1 -0
  185. package/dist/map/coordination-handler.d.ts +36 -0
  186. package/dist/map/coordination-handler.d.ts.map +1 -0
  187. package/dist/map/coordination-handler.js +166 -0
  188. package/dist/map/coordination-handler.js.map +1 -0
  189. package/dist/map/index.d.ts +5 -10
  190. package/dist/map/index.d.ts.map +1 -1
  191. package/dist/map/index.js +4 -13
  192. package/dist/map/index.js.map +1 -1
  193. package/dist/map/lifecycle-bridge.d.ts +34 -0
  194. package/dist/map/lifecycle-bridge.d.ts.map +1 -0
  195. package/dist/map/lifecycle-bridge.js +96 -0
  196. package/dist/map/lifecycle-bridge.js.map +1 -0
  197. package/dist/map/server.d.ts +38 -0
  198. package/dist/map/server.d.ts.map +1 -0
  199. package/dist/map/server.js +461 -0
  200. package/dist/map/server.js.map +1 -0
  201. package/dist/map/sidecar.d.ts +24 -0
  202. package/dist/map/sidecar.d.ts.map +1 -0
  203. package/dist/map/sidecar.js +263 -0
  204. package/dist/map/sidecar.js.map +1 -0
  205. package/dist/map/task-bridge.d.ts +22 -0
  206. package/dist/map/task-bridge.d.ts.map +1 -0
  207. package/dist/map/task-bridge.js +67 -0
  208. package/dist/map/task-bridge.js.map +1 -0
  209. package/dist/map/trajectory-reporter.d.ts +24 -0
  210. package/dist/map/trajectory-reporter.d.ts.map +1 -0
  211. package/dist/map/trajectory-reporter.js +86 -0
  212. package/dist/map/trajectory-reporter.js.map +1 -0
  213. package/dist/map/types.d.ts +162 -226
  214. package/dist/map/types.d.ts.map +1 -1
  215. package/dist/map/types.js +6 -165
  216. package/dist/map/types.js.map +1 -1
  217. package/dist/mcp/index.d.ts +2 -2
  218. package/dist/mcp/index.d.ts.map +1 -1
  219. package/dist/mcp/index.js +2 -2
  220. package/dist/mcp/index.js.map +1 -1
  221. package/dist/mcp/mcp-server-v2.d.ts +44 -0
  222. package/dist/mcp/mcp-server-v2.d.ts.map +1 -0
  223. package/dist/mcp/mcp-server-v2.js +376 -0
  224. package/dist/mcp/mcp-server-v2.js.map +1 -0
  225. package/dist/mcp/tools/done-v2.d.ts +57 -0
  226. package/dist/mcp/tools/done-v2.d.ts.map +1 -0
  227. package/dist/mcp/tools/done-v2.js +129 -0
  228. package/dist/mcp/tools/done-v2.js.map +1 -0
  229. package/dist/metrics/index.d.ts +7 -1
  230. package/dist/metrics/index.d.ts.map +1 -1
  231. package/dist/metrics/index.js +6 -1
  232. package/dist/metrics/index.js.map +1 -1
  233. package/dist/metrics/metrics.d.ts +9 -70
  234. package/dist/metrics/metrics.d.ts.map +1 -1
  235. package/dist/metrics/metrics.js +89 -145
  236. package/dist/metrics/metrics.js.map +1 -1
  237. package/dist/metrics/types.d.ts +44 -0
  238. package/dist/metrics/types.d.ts.map +1 -0
  239. package/dist/metrics/types.js +7 -0
  240. package/dist/metrics/types.js.map +1 -0
  241. package/dist/roles/builtin/coordinator.d.ts.map +1 -1
  242. package/dist/roles/builtin/coordinator.js +2 -1
  243. package/dist/roles/builtin/coordinator.js.map +1 -1
  244. package/dist/roles/builtin/integrator.d.ts.map +1 -1
  245. package/dist/roles/builtin/integrator.js +2 -1
  246. package/dist/roles/builtin/integrator.js.map +1 -1
  247. package/dist/roles/builtin/worker.d.ts.map +1 -1
  248. package/dist/roles/builtin/worker.js +3 -1
  249. package/dist/roles/builtin/worker.js.map +1 -1
  250. package/dist/roles/capabilities.d.ts +6 -0
  251. package/dist/roles/capabilities.d.ts.map +1 -1
  252. package/dist/roles/capabilities.js +10 -0
  253. package/dist/roles/capabilities.js.map +1 -1
  254. package/dist/roles/config-loader.d.ts +1 -1
  255. package/dist/roles/config-loader.d.ts.map +1 -1
  256. package/dist/roles/config-loader.js +3 -2
  257. package/dist/roles/config-loader.js.map +1 -1
  258. package/dist/roles/types.d.ts +3 -1
  259. package/dist/roles/types.d.ts.map +1 -1
  260. package/dist/store/index.d.ts +3 -6
  261. package/dist/store/index.d.ts.map +1 -1
  262. package/dist/store/index.js +3 -21
  263. package/dist/store/index.js.map +1 -1
  264. package/dist/store/types/agents.d.ts +5 -0
  265. package/dist/store/types/agents.d.ts.map +1 -1
  266. package/dist/store/types/events.d.ts +3 -60
  267. package/dist/store/types/events.d.ts.map +1 -1
  268. package/dist/store/types/events.js +3 -46
  269. package/dist/store/types/events.js.map +1 -1
  270. package/dist/store/types/index.d.ts +0 -3
  271. package/dist/store/types/index.d.ts.map +1 -1
  272. package/dist/store/types/index.js +0 -3
  273. package/dist/store/types/index.js.map +1 -1
  274. package/dist/teams/index.d.ts +2 -2
  275. package/dist/teams/index.d.ts.map +1 -1
  276. package/dist/teams/index.js +1 -1
  277. package/dist/teams/index.js.map +1 -1
  278. package/dist/teams/seed-defaults.d.ts +20 -0
  279. package/dist/teams/seed-defaults.d.ts.map +1 -0
  280. package/dist/teams/seed-defaults.js +71 -0
  281. package/dist/teams/seed-defaults.js.map +1 -0
  282. package/dist/teams/team-loader.d.ts +6 -2
  283. package/dist/teams/team-loader.d.ts.map +1 -1
  284. package/dist/teams/team-loader.js +154 -162
  285. package/dist/teams/team-loader.js.map +1 -1
  286. package/dist/teams/team-manager-v2.d.ts +87 -0
  287. package/dist/teams/team-manager-v2.d.ts.map +1 -0
  288. package/dist/teams/team-manager-v2.js +203 -0
  289. package/dist/teams/team-manager-v2.js.map +1 -0
  290. package/dist/teams/team-runtime-v2.d.ts +149 -0
  291. package/dist/teams/team-runtime-v2.d.ts.map +1 -0
  292. package/dist/teams/team-runtime-v2.js +741 -0
  293. package/dist/teams/team-runtime-v2.js.map +1 -0
  294. package/dist/teams/types.d.ts +41 -151
  295. package/dist/teams/types.d.ts.map +1 -1
  296. package/dist/teams/types.js +2 -3
  297. package/dist/teams/types.js.map +1 -1
  298. package/dist/trigger/index.d.ts +2 -2
  299. package/dist/trigger/index.d.ts.map +1 -1
  300. package/dist/trigger/index.js +4 -4
  301. package/dist/trigger/index.js.map +1 -1
  302. package/dist/trigger/sources/cron/cron-service.d.ts +1 -1
  303. package/dist/trigger/sources/cron/cron-service.d.ts.map +1 -1
  304. package/dist/trigger/sources/webhook/webhook-handler.d.ts +1 -1
  305. package/dist/trigger/sources/webhook/webhook-handler.d.ts.map +1 -1
  306. package/dist/trigger/strategies/ai-router.d.ts +31 -0
  307. package/dist/trigger/strategies/ai-router.d.ts.map +1 -0
  308. package/dist/trigger/strategies/ai-router.js +132 -0
  309. package/dist/trigger/strategies/ai-router.js.map +1 -0
  310. package/dist/trigger/trigger-system-v2.d.ts +106 -0
  311. package/dist/trigger/trigger-system-v2.d.ts.map +1 -0
  312. package/dist/trigger/trigger-system-v2.js +347 -0
  313. package/dist/trigger/trigger-system-v2.js.map +1 -0
  314. package/dist/trigger/types.d.ts +8 -0
  315. package/dist/trigger/types.d.ts.map +1 -1
  316. package/dist/trigger/types.js.map +1 -1
  317. package/dist/workspace/strategies/optimistic.d.ts +13 -3
  318. package/dist/workspace/strategies/optimistic.d.ts.map +1 -1
  319. package/dist/workspace/strategies/optimistic.js +4 -4
  320. package/dist/workspace/strategies/optimistic.js.map +1 -1
  321. package/docs/design-subsystem-extraction.md +627 -0
  322. package/docs/lifecycle-events-design.md +111 -0
  323. package/docs/openhive-capability-summary.md +415 -0
  324. package/docs/openhive-integration.md +415 -0
  325. package/docs/roadmap-v2-gaps.md +216 -0
  326. package/docs/teams.md +73 -0
  327. package/package.json +26 -6
  328. package/src/__tests__/boot-v2.test.ts +196 -0
  329. package/src/__tests__/e2e/acp-over-map-live.e2e.test.ts +496 -0
  330. package/src/__tests__/e2e/acp-over-map.e2e.test.ts +365 -0
  331. package/src/__tests__/e2e/agent-lifecycle.e2e.test.ts +770 -0
  332. package/src/__tests__/e2e/cc-swarm-bridge.e2e.test.ts +253 -0
  333. package/src/__tests__/e2e/cognitive-workspace.e2e.test.ts +282 -0
  334. package/src/__tests__/e2e/done-scenarios.e2e.test.ts +322 -0
  335. package/src/__tests__/e2e/live-agent.e2e.test.ts +1330 -0
  336. package/src/__tests__/e2e/map-server.e2e.test.ts +128 -0
  337. package/src/__tests__/e2e/map-sidecar.e2e.test.ts +139 -0
  338. package/src/__tests__/e2e/opentasks-integration.e2e.test.ts +280 -0
  339. package/src/__tests__/e2e/pull-mode.e2e.test.ts +632 -0
  340. package/src/__tests__/e2e/resume-continue.e2e.test.ts +312 -0
  341. package/src/__tests__/e2e/swarmkit-integration.e2e.test.ts +562 -0
  342. package/src/__tests__/e2e/swarmkit-live.e2e.test.ts +1049 -0
  343. package/src/__tests__/e2e/trajectory-tracking.e2e.test.ts +258 -0
  344. package/src/__tests__/e2e/trigger-wake.e2e.test.ts +257 -0
  345. package/src/__tests__/e2e/workspace-lifecycle.e2e.test.ts +375 -0
  346. package/src/acp/__tests__/macro-agent.test.ts +234 -945
  347. package/src/acp/__tests__/session-mapper.test.ts +82 -155
  348. package/src/acp/__tests__/websocket-server.test.ts +121 -270
  349. package/src/acp/index.ts +18 -118
  350. package/src/acp/macro-agent.ts +692 -1752
  351. package/src/acp/map-bridge.ts +193 -0
  352. package/src/acp/session-mapper.ts +43 -276
  353. package/src/acp/types.ts +39 -767
  354. package/src/acp/websocket-server.ts +152 -588
  355. package/src/adapters/__tests__/federation.test.ts +256 -0
  356. package/src/adapters/__tests__/inbox-adapter.test.ts +316 -0
  357. package/src/adapters/__tests__/tasks-adapter.test.ts +269 -0
  358. package/src/adapters/federation.ts +185 -0
  359. package/src/adapters/inbox-adapter.ts +292 -0
  360. package/src/adapters/inbox-client-adapter.ts +173 -0
  361. package/src/adapters/index.ts +44 -0
  362. package/src/adapters/opentasks-daemon.ts +252 -0
  363. package/src/adapters/tasks-adapter.ts +327 -0
  364. package/src/adapters/types.ts +285 -0
  365. package/src/agent/__tests__/agent-manager-v2.test.ts +554 -0
  366. package/src/agent/__tests__/agent-store.test.ts +413 -0
  367. package/src/agent/agent-manager-v2.ts +1476 -0
  368. package/src/agent/agent-manager.ts +41 -1723
  369. package/src/agent/agent-store.ts +385 -0
  370. package/src/agent/types.ts +9 -0
  371. package/src/api/__tests__/server.test.ts +238 -961
  372. package/src/api/index.ts +5 -3
  373. package/src/api/server.ts +276 -1870
  374. package/src/api/types.ts +25 -337
  375. package/src/boot-v2.ts +527 -0
  376. package/src/cli/acp.ts +40 -435
  377. package/src/cli/index.ts +68 -466
  378. package/src/cli/mcp.ts +260 -326
  379. package/src/cognitive/__tests__/macro-agent-backend.test.ts +478 -0
  380. package/src/cognitive/__tests__/session-converter.test.ts +423 -0
  381. package/src/cognitive/__tests__/workspace-handler.test.ts +221 -0
  382. package/src/cognitive/analyst-role.ts +59 -0
  383. package/src/cognitive/index.ts +49 -0
  384. package/src/cognitive/macro-agent-backend.ts +354 -0
  385. package/src/cognitive/session-converter.ts +151 -0
  386. package/src/cognitive/types.ts +163 -0
  387. package/src/cognitive/workspace-handler.ts +163 -0
  388. package/src/config/project-config.ts +27 -3
  389. package/src/control/__tests__/control-resilience.test.ts +251 -0
  390. package/src/control/__tests__/control-socket.test.ts +240 -0
  391. package/src/control/control-client.ts +337 -0
  392. package/src/control/control-server.ts +298 -0
  393. package/src/control/index.ts +17 -0
  394. package/src/control/types.ts +95 -0
  395. package/src/index.ts +43 -222
  396. package/src/integrations/__tests__/context-builder.test.ts +218 -0
  397. package/src/integrations/__tests__/sessionlog.test.ts +498 -0
  398. package/src/integrations/__tests__/skilltree.test.ts +136 -0
  399. package/src/integrations/context-builder.ts +280 -0
  400. package/src/integrations/sessionlog.ts +194 -0
  401. package/src/integrations/skilltree.ts +183 -0
  402. package/src/lifecycle/__tests__/handlers-v2.test.ts +565 -0
  403. package/src/lifecycle/cleanup.ts +6 -46
  404. package/src/lifecycle/handlers-v2.ts +437 -0
  405. package/src/lifecycle/index.ts +2 -28
  406. package/src/lifecycle/types.ts +3 -0
  407. package/src/map/__tests__/lifecycle-bridge.test.ts +223 -0
  408. package/src/map/__tests__/permission-forwarding.test.ts +143 -0
  409. package/src/map/__tests__/sidecar-integration.test.ts +190 -0
  410. package/src/map/__tests__/task-bridge.test.ts +153 -0
  411. package/src/map/__tests__/trajectory-reporter.test.ts +173 -0
  412. package/src/map/acp-bridge.ts +270 -0
  413. package/src/map/cc-swarm-hooks.ts +242 -0
  414. package/src/map/coordination-handler.ts +220 -0
  415. package/src/map/index.ts +13 -14
  416. package/src/map/lifecycle-bridge.ts +140 -0
  417. package/src/map/server.ts +527 -0
  418. package/src/map/sidecar.ts +312 -0
  419. package/src/map/task-bridge.ts +89 -0
  420. package/src/map/trajectory-reporter.ts +124 -0
  421. package/src/map/types.ts +195 -367
  422. package/src/mcp/__tests__/mcp-server-v2.test.ts +236 -0
  423. package/src/mcp/index.ts +2 -2
  424. package/src/mcp/mcp-server-v2.ts +485 -0
  425. package/src/mcp/tools/done-v2.ts +203 -0
  426. package/src/metrics/__tests__/metrics.test.ts +205 -0
  427. package/src/metrics/index.ts +13 -9
  428. package/src/metrics/metrics.ts +110 -239
  429. package/src/metrics/types.ts +63 -0
  430. package/src/roles/builtin/coordinator.ts +2 -0
  431. package/src/roles/builtin/integrator.ts +2 -0
  432. package/src/roles/builtin/worker.ts +3 -0
  433. package/src/roles/capabilities.ts +11 -0
  434. package/src/roles/config-loader.ts +3 -2
  435. package/src/roles/types.ts +7 -0
  436. package/src/store/index.ts +3 -64
  437. package/src/store/types/agents.ts +5 -0
  438. package/src/store/types/events.ts +5 -100
  439. package/src/store/types/index.ts +0 -3
  440. package/src/teams/__tests__/team-manager-v2.test.ts +425 -0
  441. package/src/teams/__tests__/team-runtime-v2.test.ts +402 -0
  442. package/src/teams/index.ts +20 -4
  443. package/src/teams/seed-defaults.ts +79 -0
  444. package/src/teams/team-loader.ts +200 -234
  445. package/src/teams/team-manager-v2.ts +268 -0
  446. package/src/teams/team-runtime-v2.ts +898 -0
  447. package/src/teams/types.ts +99 -200
  448. package/src/trigger/__tests__/trigger-system-v2.test.ts +257 -0
  449. package/src/trigger/index.ts +16 -31
  450. package/src/trigger/sources/cron/cron-service.ts +1 -1
  451. package/src/trigger/sources/webhook/webhook-handler.ts +1 -1
  452. package/src/trigger/strategies/ai-router.ts +170 -0
  453. package/src/trigger/trigger-system-v2.ts +536 -0
  454. package/src/trigger/types.ts +13 -0
  455. package/src/workspace/strategies/optimistic.ts +9 -6
  456. package/.claude/settings.local.json +0 -61
  457. package/dist/acp/websocket-stream.d.ts +0 -30
  458. package/dist/acp/websocket-stream.d.ts.map +0 -1
  459. package/dist/acp/websocket-stream.js +0 -118
  460. package/dist/acp/websocket-stream.js.map +0 -1
  461. package/dist/activity/deduplication.d.ts +0 -85
  462. package/dist/activity/deduplication.d.ts.map +0 -1
  463. package/dist/activity/deduplication.js +0 -149
  464. package/dist/activity/deduplication.js.map +0 -1
  465. package/dist/activity/index.d.ts +0 -16
  466. package/dist/activity/index.d.ts.map +0 -1
  467. package/dist/activity/index.js +0 -17
  468. package/dist/activity/index.js.map +0 -1
  469. package/dist/activity/relevance.d.ts +0 -81
  470. package/dist/activity/relevance.d.ts.map +0 -1
  471. package/dist/activity/relevance.js +0 -161
  472. package/dist/activity/relevance.js.map +0 -1
  473. package/dist/activity/types.d.ts +0 -169
  474. package/dist/activity/types.d.ts.map +0 -1
  475. package/dist/activity/types.js +0 -33
  476. package/dist/activity/types.js.map +0 -1
  477. package/dist/activity/watcher.d.ts +0 -64
  478. package/dist/activity/watcher.d.ts.map +0 -1
  479. package/dist/activity/watcher.js +0 -212
  480. package/dist/activity/watcher.js.map +0 -1
  481. package/dist/agent/wake.d.ts +0 -85
  482. package/dist/agent/wake.d.ts.map +0 -1
  483. package/dist/agent/wake.js +0 -278
  484. package/dist/agent/wake.js.map +0 -1
  485. package/dist/lifecycle/handlers/generic.d.ts +0 -27
  486. package/dist/lifecycle/handlers/generic.d.ts.map +0 -1
  487. package/dist/lifecycle/handlers/generic.js +0 -56
  488. package/dist/lifecycle/handlers/generic.js.map +0 -1
  489. package/dist/lifecycle/handlers/index.d.ts +0 -47
  490. package/dist/lifecycle/handlers/index.d.ts.map +0 -1
  491. package/dist/lifecycle/handlers/index.js +0 -93
  492. package/dist/lifecycle/handlers/index.js.map +0 -1
  493. package/dist/lifecycle/handlers/integrator.d.ts +0 -81
  494. package/dist/lifecycle/handlers/integrator.d.ts.map +0 -1
  495. package/dist/lifecycle/handlers/integrator.js +0 -451
  496. package/dist/lifecycle/handlers/integrator.js.map +0 -1
  497. package/dist/lifecycle/handlers/monitor.d.ts +0 -29
  498. package/dist/lifecycle/handlers/monitor.d.ts.map +0 -1
  499. package/dist/lifecycle/handlers/monitor.js +0 -79
  500. package/dist/lifecycle/handlers/monitor.js.map +0 -1
  501. package/dist/lifecycle/handlers/worker.d.ts +0 -56
  502. package/dist/lifecycle/handlers/worker.d.ts.map +0 -1
  503. package/dist/lifecycle/handlers/worker.js +0 -381
  504. package/dist/lifecycle/handlers/worker.js.map +0 -1
  505. package/dist/mail/conversation-map.d.ts +0 -33
  506. package/dist/mail/conversation-map.d.ts.map +0 -1
  507. package/dist/mail/conversation-map.js +0 -61
  508. package/dist/mail/conversation-map.js.map +0 -1
  509. package/dist/mail/index.d.ts +0 -11
  510. package/dist/mail/index.d.ts.map +0 -1
  511. package/dist/mail/index.js +0 -11
  512. package/dist/mail/index.js.map +0 -1
  513. package/dist/mail/mail-service.d.ts +0 -85
  514. package/dist/mail/mail-service.d.ts.map +0 -1
  515. package/dist/mail/mail-service.js +0 -121
  516. package/dist/mail/mail-service.js.map +0 -1
  517. package/dist/mail/stores/eventstore-conversation-store.d.ts +0 -40
  518. package/dist/mail/stores/eventstore-conversation-store.d.ts.map +0 -1
  519. package/dist/mail/stores/eventstore-conversation-store.js +0 -131
  520. package/dist/mail/stores/eventstore-conversation-store.js.map +0 -1
  521. package/dist/mail/stores/eventstore-participant-store.d.ts +0 -43
  522. package/dist/mail/stores/eventstore-participant-store.d.ts.map +0 -1
  523. package/dist/mail/stores/eventstore-participant-store.js +0 -145
  524. package/dist/mail/stores/eventstore-participant-store.js.map +0 -1
  525. package/dist/mail/stores/eventstore-thread-store.d.ts +0 -46
  526. package/dist/mail/stores/eventstore-thread-store.d.ts.map +0 -1
  527. package/dist/mail/stores/eventstore-thread-store.js +0 -118
  528. package/dist/mail/stores/eventstore-thread-store.js.map +0 -1
  529. package/dist/mail/stores/eventstore-turn-store.d.ts +0 -47
  530. package/dist/mail/stores/eventstore-turn-store.d.ts.map +0 -1
  531. package/dist/mail/stores/eventstore-turn-store.js +0 -153
  532. package/dist/mail/stores/eventstore-turn-store.js.map +0 -1
  533. package/dist/mail/stores/index.d.ts +0 -12
  534. package/dist/mail/stores/index.d.ts.map +0 -1
  535. package/dist/mail/stores/index.js +0 -12
  536. package/dist/mail/stores/index.js.map +0 -1
  537. package/dist/mail/stores/types.d.ts +0 -146
  538. package/dist/mail/stores/types.d.ts.map +0 -1
  539. package/dist/mail/stores/types.js +0 -13
  540. package/dist/mail/stores/types.js.map +0 -1
  541. package/dist/mail/turn-recorder.d.ts +0 -30
  542. package/dist/mail/turn-recorder.d.ts.map +0 -1
  543. package/dist/mail/turn-recorder.js +0 -98
  544. package/dist/mail/turn-recorder.js.map +0 -1
  545. package/dist/map/adapter/acp-over-map.d.ts +0 -115
  546. package/dist/map/adapter/acp-over-map.d.ts.map +0 -1
  547. package/dist/map/adapter/acp-over-map.js +0 -1024
  548. package/dist/map/adapter/acp-over-map.js.map +0 -1
  549. package/dist/map/adapter/connection-manager.d.ts +0 -150
  550. package/dist/map/adapter/connection-manager.d.ts.map +0 -1
  551. package/dist/map/adapter/connection-manager.js +0 -207
  552. package/dist/map/adapter/connection-manager.js.map +0 -1
  553. package/dist/map/adapter/event-log.d.ts +0 -87
  554. package/dist/map/adapter/event-log.d.ts.map +0 -1
  555. package/dist/map/adapter/event-log.js +0 -122
  556. package/dist/map/adapter/event-log.js.map +0 -1
  557. package/dist/map/adapter/event-translator.d.ts +0 -85
  558. package/dist/map/adapter/event-translator.d.ts.map +0 -1
  559. package/dist/map/adapter/event-translator.js +0 -295
  560. package/dist/map/adapter/event-translator.js.map +0 -1
  561. package/dist/map/adapter/extensions/agent-detection.d.ts +0 -49
  562. package/dist/map/adapter/extensions/agent-detection.d.ts.map +0 -1
  563. package/dist/map/adapter/extensions/agent-detection.js +0 -91
  564. package/dist/map/adapter/extensions/agent-detection.js.map +0 -1
  565. package/dist/map/adapter/extensions/agent-lifecycle.d.ts +0 -82
  566. package/dist/map/adapter/extensions/agent-lifecycle.d.ts.map +0 -1
  567. package/dist/map/adapter/extensions/agent-lifecycle.js +0 -164
  568. package/dist/map/adapter/extensions/agent-lifecycle.js.map +0 -1
  569. package/dist/map/adapter/extensions/index.d.ts +0 -89
  570. package/dist/map/adapter/extensions/index.d.ts.map +0 -1
  571. package/dist/map/adapter/extensions/index.js +0 -187
  572. package/dist/map/adapter/extensions/index.js.map +0 -1
  573. package/dist/map/adapter/extensions/mcp-bridge.d.ts +0 -57
  574. package/dist/map/adapter/extensions/mcp-bridge.d.ts.map +0 -1
  575. package/dist/map/adapter/extensions/mcp-bridge.js +0 -745
  576. package/dist/map/adapter/extensions/mcp-bridge.js.map +0 -1
  577. package/dist/map/adapter/extensions/rename.d.ts +0 -29
  578. package/dist/map/adapter/extensions/rename.d.ts.map +0 -1
  579. package/dist/map/adapter/extensions/rename.js +0 -49
  580. package/dist/map/adapter/extensions/rename.js.map +0 -1
  581. package/dist/map/adapter/extensions/resume.d.ts +0 -47
  582. package/dist/map/adapter/extensions/resume.d.ts.map +0 -1
  583. package/dist/map/adapter/extensions/resume.js +0 -59
  584. package/dist/map/adapter/extensions/resume.js.map +0 -1
  585. package/dist/map/adapter/extensions/task.d.ts +0 -40
  586. package/dist/map/adapter/extensions/task.d.ts.map +0 -1
  587. package/dist/map/adapter/extensions/task.js +0 -197
  588. package/dist/map/adapter/extensions/task.js.map +0 -1
  589. package/dist/map/adapter/extensions/update-metadata.d.ts +0 -29
  590. package/dist/map/adapter/extensions/update-metadata.d.ts.map +0 -1
  591. package/dist/map/adapter/extensions/update-metadata.js +0 -67
  592. package/dist/map/adapter/extensions/update-metadata.js.map +0 -1
  593. package/dist/map/adapter/extensions/wake.d.ts +0 -60
  594. package/dist/map/adapter/extensions/wake.d.ts.map +0 -1
  595. package/dist/map/adapter/extensions/wake.js +0 -144
  596. package/dist/map/adapter/extensions/wake.js.map +0 -1
  597. package/dist/map/adapter/extensions/workspace-files.d.ts +0 -42
  598. package/dist/map/adapter/extensions/workspace-files.d.ts.map +0 -1
  599. package/dist/map/adapter/extensions/workspace-files.js +0 -338
  600. package/dist/map/adapter/extensions/workspace-files.js.map +0 -1
  601. package/dist/map/adapter/extensions/workspace.d.ts +0 -57
  602. package/dist/map/adapter/extensions/workspace.d.ts.map +0 -1
  603. package/dist/map/adapter/extensions/workspace.js +0 -81
  604. package/dist/map/adapter/extensions/workspace.js.map +0 -1
  605. package/dist/map/adapter/index.d.ts +0 -20
  606. package/dist/map/adapter/index.d.ts.map +0 -1
  607. package/dist/map/adapter/index.js +0 -38
  608. package/dist/map/adapter/index.js.map +0 -1
  609. package/dist/map/adapter/interface.d.ts +0 -450
  610. package/dist/map/adapter/interface.d.ts.map +0 -1
  611. package/dist/map/adapter/interface.js +0 -24
  612. package/dist/map/adapter/interface.js.map +0 -1
  613. package/dist/map/adapter/mail-handler-adapter.d.ts +0 -27
  614. package/dist/map/adapter/mail-handler-adapter.d.ts.map +0 -1
  615. package/dist/map/adapter/mail-handler-adapter.js +0 -292
  616. package/dist/map/adapter/mail-handler-adapter.js.map +0 -1
  617. package/dist/map/adapter/map-adapter.d.ts +0 -200
  618. package/dist/map/adapter/map-adapter.d.ts.map +0 -1
  619. package/dist/map/adapter/map-adapter.js +0 -1199
  620. package/dist/map/adapter/map-adapter.js.map +0 -1
  621. package/dist/map/adapter/rpc-handler.d.ts +0 -263
  622. package/dist/map/adapter/rpc-handler.d.ts.map +0 -1
  623. package/dist/map/adapter/rpc-handler.js +0 -365
  624. package/dist/map/adapter/rpc-handler.js.map +0 -1
  625. package/dist/map/adapter/subscription-manager.d.ts +0 -174
  626. package/dist/map/adapter/subscription-manager.d.ts.map +0 -1
  627. package/dist/map/adapter/subscription-manager.js +0 -248
  628. package/dist/map/adapter/subscription-manager.js.map +0 -1
  629. package/dist/map/adapter/types.d.ts +0 -194
  630. package/dist/map/adapter/types.d.ts.map +0 -1
  631. package/dist/map/adapter/types.js +0 -27
  632. package/dist/map/adapter/types.js.map +0 -1
  633. package/dist/map/adapter/websocket-integration.d.ts +0 -113
  634. package/dist/map/adapter/websocket-integration.d.ts.map +0 -1
  635. package/dist/map/adapter/websocket-integration.js +0 -134
  636. package/dist/map/adapter/websocket-integration.js.map +0 -1
  637. package/dist/map/federation/envelope.d.ts +0 -98
  638. package/dist/map/federation/envelope.d.ts.map +0 -1
  639. package/dist/map/federation/envelope.js +0 -160
  640. package/dist/map/federation/envelope.js.map +0 -1
  641. package/dist/map/federation/federation-handler.d.ts +0 -50
  642. package/dist/map/federation/federation-handler.d.ts.map +0 -1
  643. package/dist/map/federation/federation-handler.js +0 -306
  644. package/dist/map/federation/federation-handler.js.map +0 -1
  645. package/dist/map/federation/index.d.ts +0 -14
  646. package/dist/map/federation/index.d.ts.map +0 -1
  647. package/dist/map/federation/index.js +0 -13
  648. package/dist/map/federation/index.js.map +0 -1
  649. package/dist/map/federation/types.d.ts +0 -239
  650. package/dist/map/federation/types.d.ts.map +0 -1
  651. package/dist/map/federation/types.js +0 -23
  652. package/dist/map/federation/types.js.map +0 -1
  653. package/dist/map/utils/address-translation.d.ts +0 -99
  654. package/dist/map/utils/address-translation.d.ts.map +0 -1
  655. package/dist/map/utils/address-translation.js +0 -285
  656. package/dist/map/utils/address-translation.js.map +0 -1
  657. package/dist/map/utils/index.d.ts +0 -7
  658. package/dist/map/utils/index.d.ts.map +0 -1
  659. package/dist/map/utils/index.js +0 -7
  660. package/dist/map/utils/index.js.map +0 -1
  661. package/dist/mcp/map-client.d.ts +0 -39
  662. package/dist/mcp/map-client.d.ts.map +0 -1
  663. package/dist/mcp/map-client.js +0 -129
  664. package/dist/mcp/map-client.js.map +0 -1
  665. package/dist/mcp/mcp-server.d.ts +0 -70
  666. package/dist/mcp/mcp-server.d.ts.map +0 -1
  667. package/dist/mcp/mcp-server.js +0 -1015
  668. package/dist/mcp/mcp-server.js.map +0 -1
  669. package/dist/mcp/tools/claim_task.d.ts +0 -35
  670. package/dist/mcp/tools/claim_task.d.ts.map +0 -1
  671. package/dist/mcp/tools/claim_task.js +0 -58
  672. package/dist/mcp/tools/claim_task.js.map +0 -1
  673. package/dist/mcp/tools/done.d.ts +0 -102
  674. package/dist/mcp/tools/done.d.ts.map +0 -1
  675. package/dist/mcp/tools/done.js +0 -234
  676. package/dist/mcp/tools/done.js.map +0 -1
  677. package/dist/mcp/tools/inject_context.d.ts +0 -61
  678. package/dist/mcp/tools/inject_context.d.ts.map +0 -1
  679. package/dist/mcp/tools/inject_context.js +0 -123
  680. package/dist/mcp/tools/inject_context.js.map +0 -1
  681. package/dist/mcp/tools/list_claimable_tasks.d.ts +0 -38
  682. package/dist/mcp/tools/list_claimable_tasks.d.ts.map +0 -1
  683. package/dist/mcp/tools/list_claimable_tasks.js +0 -63
  684. package/dist/mcp/tools/list_claimable_tasks.js.map +0 -1
  685. package/dist/mcp/tools/unclaim_task.d.ts +0 -31
  686. package/dist/mcp/tools/unclaim_task.d.ts.map +0 -1
  687. package/dist/mcp/tools/unclaim_task.js +0 -47
  688. package/dist/mcp/tools/unclaim_task.js.map +0 -1
  689. package/dist/mcp/tools/wait_for_activity.d.ts +0 -60
  690. package/dist/mcp/tools/wait_for_activity.d.ts.map +0 -1
  691. package/dist/mcp/tools/wait_for_activity.js +0 -135
  692. package/dist/mcp/tools/wait_for_activity.js.map +0 -1
  693. package/dist/monitor/health-check-service.d.ts +0 -143
  694. package/dist/monitor/health-check-service.d.ts.map +0 -1
  695. package/dist/monitor/health-check-service.js +0 -240
  696. package/dist/monitor/health-check-service.js.map +0 -1
  697. package/dist/monitor/index.d.ts +0 -14
  698. package/dist/monitor/index.d.ts.map +0 -1
  699. package/dist/monitor/index.js +0 -14
  700. package/dist/monitor/index.js.map +0 -1
  701. package/dist/monitor/stall-detector.d.ts +0 -109
  702. package/dist/monitor/stall-detector.d.ts.map +0 -1
  703. package/dist/monitor/stall-detector.js +0 -152
  704. package/dist/monitor/stall-detector.js.map +0 -1
  705. package/dist/peer/capability-manager.d.ts +0 -56
  706. package/dist/peer/capability-manager.d.ts.map +0 -1
  707. package/dist/peer/capability-manager.js +0 -186
  708. package/dist/peer/capability-manager.js.map +0 -1
  709. package/dist/peer/encapsulation-manager.d.ts +0 -190
  710. package/dist/peer/encapsulation-manager.d.ts.map +0 -1
  711. package/dist/peer/encapsulation-manager.js +0 -486
  712. package/dist/peer/encapsulation-manager.js.map +0 -1
  713. package/dist/peer/federation-manager.d.ts +0 -223
  714. package/dist/peer/federation-manager.d.ts.map +0 -1
  715. package/dist/peer/federation-manager.js +0 -528
  716. package/dist/peer/federation-manager.js.map +0 -1
  717. package/dist/peer/hierarchy-errors.d.ts +0 -208
  718. package/dist/peer/hierarchy-errors.d.ts.map +0 -1
  719. package/dist/peer/hierarchy-errors.js +0 -268
  720. package/dist/peer/hierarchy-errors.js.map +0 -1
  721. package/dist/peer/hierarchy-protocol.d.ts +0 -159
  722. package/dist/peer/hierarchy-protocol.d.ts.map +0 -1
  723. package/dist/peer/hierarchy-protocol.js +0 -142
  724. package/dist/peer/hierarchy-protocol.js.map +0 -1
  725. package/dist/peer/index.d.ts +0 -15
  726. package/dist/peer/index.d.ts.map +0 -1
  727. package/dist/peer/index.js +0 -15
  728. package/dist/peer/index.js.map +0 -1
  729. package/dist/peer/peer-manager.d.ts +0 -99
  730. package/dist/peer/peer-manager.d.ts.map +0 -1
  731. package/dist/peer/peer-manager.js +0 -333
  732. package/dist/peer/peer-manager.js.map +0 -1
  733. package/dist/peer/task-delegation.d.ts +0 -189
  734. package/dist/peer/task-delegation.d.ts.map +0 -1
  735. package/dist/peer/task-delegation.js +0 -303
  736. package/dist/peer/task-delegation.js.map +0 -1
  737. package/dist/peer/transports/index.d.ts +0 -8
  738. package/dist/peer/transports/index.d.ts.map +0 -1
  739. package/dist/peer/transports/index.js +0 -8
  740. package/dist/peer/transports/index.js.map +0 -1
  741. package/dist/peer/transports/local-transport.d.ts +0 -56
  742. package/dist/peer/transports/local-transport.d.ts.map +0 -1
  743. package/dist/peer/transports/local-transport.js +0 -263
  744. package/dist/peer/transports/local-transport.js.map +0 -1
  745. package/dist/peer/transports/websocket-transport.d.ts +0 -86
  746. package/dist/peer/transports/websocket-transport.d.ts.map +0 -1
  747. package/dist/peer/transports/websocket-transport.js +0 -338
  748. package/dist/peer/transports/websocket-transport.js.map +0 -1
  749. package/dist/peer/types.d.ts +0 -268
  750. package/dist/peer/types.d.ts.map +0 -1
  751. package/dist/peer/types.js +0 -36
  752. package/dist/peer/types.js.map +0 -1
  753. package/dist/router/address-resolver.d.ts +0 -102
  754. package/dist/router/address-resolver.d.ts.map +0 -1
  755. package/dist/router/address-resolver.js +0 -198
  756. package/dist/router/address-resolver.js.map +0 -1
  757. package/dist/router/broadcast.d.ts +0 -53
  758. package/dist/router/broadcast.d.ts.map +0 -1
  759. package/dist/router/broadcast.js +0 -75
  760. package/dist/router/broadcast.js.map +0 -1
  761. package/dist/router/channels.d.ts +0 -148
  762. package/dist/router/channels.d.ts.map +0 -1
  763. package/dist/router/channels.js +0 -126
  764. package/dist/router/channels.js.map +0 -1
  765. package/dist/router/index.d.ts +0 -21
  766. package/dist/router/index.d.ts.map +0 -1
  767. package/dist/router/index.js +0 -18
  768. package/dist/router/index.js.map +0 -1
  769. package/dist/router/message-router.d.ts +0 -197
  770. package/dist/router/message-router.d.ts.map +0 -1
  771. package/dist/router/message-router.js +0 -903
  772. package/dist/router/message-router.js.map +0 -1
  773. package/dist/router/message-types.d.ts +0 -183
  774. package/dist/router/message-types.d.ts.map +0 -1
  775. package/dist/router/message-types.js +0 -79
  776. package/dist/router/message-types.js.map +0 -1
  777. package/dist/router/role-resolver.d.ts +0 -67
  778. package/dist/router/role-resolver.d.ts.map +0 -1
  779. package/dist/router/role-resolver.js +0 -106
  780. package/dist/router/role-resolver.js.map +0 -1
  781. package/dist/router/signals.d.ts +0 -253
  782. package/dist/router/signals.d.ts.map +0 -1
  783. package/dist/router/signals.js +0 -53
  784. package/dist/router/signals.js.map +0 -1
  785. package/dist/router/types.d.ts +0 -191
  786. package/dist/router/types.d.ts.map +0 -1
  787. package/dist/router/types.js +0 -34
  788. package/dist/router/types.js.map +0 -1
  789. package/dist/router/wake.d.ts +0 -111
  790. package/dist/router/wake.d.ts.map +0 -1
  791. package/dist/router/wake.js +0 -180
  792. package/dist/router/wake.js.map +0 -1
  793. package/dist/server/combined-server.d.ts +0 -88
  794. package/dist/server/combined-server.d.ts.map +0 -1
  795. package/dist/server/combined-server.js +0 -331
  796. package/dist/server/combined-server.js.map +0 -1
  797. package/dist/steering/index.d.ts +0 -11
  798. package/dist/steering/index.d.ts.map +0 -1
  799. package/dist/steering/index.js +0 -11
  800. package/dist/steering/index.js.map +0 -1
  801. package/dist/steering/inject.d.ts +0 -39
  802. package/dist/steering/inject.d.ts.map +0 -1
  803. package/dist/steering/inject.js +0 -197
  804. package/dist/steering/inject.js.map +0 -1
  805. package/dist/steering/types.d.ts +0 -100
  806. package/dist/steering/types.d.ts.map +0 -1
  807. package/dist/steering/types.js +0 -11
  808. package/dist/steering/types.js.map +0 -1
  809. package/dist/store/backends/index.d.ts +0 -11
  810. package/dist/store/backends/index.d.ts.map +0 -1
  811. package/dist/store/backends/index.js +0 -15
  812. package/dist/store/backends/index.js.map +0 -1
  813. package/dist/store/backends/json-backend.d.ts +0 -23
  814. package/dist/store/backends/json-backend.d.ts.map +0 -1
  815. package/dist/store/backends/json-backend.js +0 -220
  816. package/dist/store/backends/json-backend.js.map +0 -1
  817. package/dist/store/backends/memory-backend.d.ts +0 -12
  818. package/dist/store/backends/memory-backend.d.ts.map +0 -1
  819. package/dist/store/backends/memory-backend.js +0 -205
  820. package/dist/store/backends/memory-backend.js.map +0 -1
  821. package/dist/store/backends/sqlite-backend.d.ts +0 -27
  822. package/dist/store/backends/sqlite-backend.d.ts.map +0 -1
  823. package/dist/store/backends/sqlite-backend.js +0 -231
  824. package/dist/store/backends/sqlite-backend.js.map +0 -1
  825. package/dist/store/backends/tinybase-backend.d.ts +0 -22
  826. package/dist/store/backends/tinybase-backend.d.ts.map +0 -1
  827. package/dist/store/backends/tinybase-backend.js +0 -203
  828. package/dist/store/backends/tinybase-backend.js.map +0 -1
  829. package/dist/store/backends/types.d.ts +0 -175
  830. package/dist/store/backends/types.d.ts.map +0 -1
  831. package/dist/store/backends/types.js +0 -28
  832. package/dist/store/backends/types.js.map +0 -1
  833. package/dist/store/event-store.d.ts +0 -128
  834. package/dist/store/event-store.d.ts.map +0 -1
  835. package/dist/store/event-store.js +0 -1739
  836. package/dist/store/event-store.js.map +0 -1
  837. package/dist/store/instance.d.ts +0 -283
  838. package/dist/store/instance.d.ts.map +0 -1
  839. package/dist/store/instance.js +0 -363
  840. package/dist/store/instance.js.map +0 -1
  841. package/dist/store/migrations.d.ts +0 -41
  842. package/dist/store/migrations.d.ts.map +0 -1
  843. package/dist/store/migrations.js +0 -79
  844. package/dist/store/migrations.js.map +0 -1
  845. package/dist/store/types/config.d.ts +0 -16
  846. package/dist/store/types/config.d.ts.map +0 -1
  847. package/dist/store/types/config.js +0 -8
  848. package/dist/store/types/config.js.map +0 -1
  849. package/dist/store/types/conversations.d.ts +0 -91
  850. package/dist/store/types/conversations.d.ts.map +0 -1
  851. package/dist/store/types/conversations.js +0 -8
  852. package/dist/store/types/conversations.js.map +0 -1
  853. package/dist/store/types/sessions.d.ts +0 -44
  854. package/dist/store/types/sessions.d.ts.map +0 -1
  855. package/dist/store/types/sessions.js +0 -9
  856. package/dist/store/types/sessions.js.map +0 -1
  857. package/dist/task/backend/index.d.ts +0 -93
  858. package/dist/task/backend/index.d.ts.map +0 -1
  859. package/dist/task/backend/index.js +0 -178
  860. package/dist/task/backend/index.js.map +0 -1
  861. package/dist/task/backend/memory.d.ts +0 -70
  862. package/dist/task/backend/memory.d.ts.map +0 -1
  863. package/dist/task/backend/memory.js +0 -621
  864. package/dist/task/backend/memory.js.map +0 -1
  865. package/dist/task/backend/opentasks/backend.d.ts +0 -140
  866. package/dist/task/backend/opentasks/backend.d.ts.map +0 -1
  867. package/dist/task/backend/opentasks/backend.js +0 -1023
  868. package/dist/task/backend/opentasks/backend.js.map +0 -1
  869. package/dist/task/backend/opentasks/client.d.ts +0 -337
  870. package/dist/task/backend/opentasks/client.d.ts.map +0 -1
  871. package/dist/task/backend/opentasks/client.js +0 -225
  872. package/dist/task/backend/opentasks/client.js.map +0 -1
  873. package/dist/task/backend/opentasks/daemon-manager.d.ts +0 -89
  874. package/dist/task/backend/opentasks/daemon-manager.d.ts.map +0 -1
  875. package/dist/task/backend/opentasks/daemon-manager.js +0 -195
  876. package/dist/task/backend/opentasks/daemon-manager.js.map +0 -1
  877. package/dist/task/backend/opentasks/index.d.ts +0 -21
  878. package/dist/task/backend/opentasks/index.d.ts.map +0 -1
  879. package/dist/task/backend/opentasks/index.js +0 -21
  880. package/dist/task/backend/opentasks/index.js.map +0 -1
  881. package/dist/task/backend/opentasks/mapping.d.ts +0 -48
  882. package/dist/task/backend/opentasks/mapping.d.ts.map +0 -1
  883. package/dist/task/backend/opentasks/mapping.js +0 -77
  884. package/dist/task/backend/opentasks/mapping.js.map +0 -1
  885. package/dist/task/backend/sudocode/__tests__/integration/test-utils.d.ts +0 -54
  886. package/dist/task/backend/sudocode/__tests__/integration/test-utils.d.ts.map +0 -1
  887. package/dist/task/backend/sudocode/__tests__/integration/test-utils.js +0 -88
  888. package/dist/task/backend/sudocode/__tests__/integration/test-utils.js.map +0 -1
  889. package/dist/task/backend/sudocode/backend.d.ts +0 -155
  890. package/dist/task/backend/sudocode/backend.d.ts.map +0 -1
  891. package/dist/task/backend/sudocode/backend.js +0 -942
  892. package/dist/task/backend/sudocode/backend.js.map +0 -1
  893. package/dist/task/backend/sudocode/client.d.ts +0 -303
  894. package/dist/task/backend/sudocode/client.d.ts.map +0 -1
  895. package/dist/task/backend/sudocode/client.js +0 -101
  896. package/dist/task/backend/sudocode/client.js.map +0 -1
  897. package/dist/task/backend/sudocode/index.d.ts +0 -19
  898. package/dist/task/backend/sudocode/index.d.ts.map +0 -1
  899. package/dist/task/backend/sudocode/index.js +0 -17
  900. package/dist/task/backend/sudocode/index.js.map +0 -1
  901. package/dist/task/backend/sudocode/mapping.d.ts +0 -51
  902. package/dist/task/backend/sudocode/mapping.d.ts.map +0 -1
  903. package/dist/task/backend/sudocode/mapping.js +0 -86
  904. package/dist/task/backend/sudocode/mapping.js.map +0 -1
  905. package/dist/task/backend/sudocode/server-client.d.ts +0 -56
  906. package/dist/task/backend/sudocode/server-client.d.ts.map +0 -1
  907. package/dist/task/backend/sudocode/server-client.js +0 -367
  908. package/dist/task/backend/sudocode/server-client.js.map +0 -1
  909. package/dist/task/backend/sudocode/standalone-client.d.ts +0 -91
  910. package/dist/task/backend/sudocode/standalone-client.d.ts.map +0 -1
  911. package/dist/task/backend/sudocode/standalone-client.js +0 -476
  912. package/dist/task/backend/sudocode/standalone-client.js.map +0 -1
  913. package/dist/task/backend/sudocode/sync-policy.d.ts +0 -166
  914. package/dist/task/backend/sudocode/sync-policy.d.ts.map +0 -1
  915. package/dist/task/backend/sudocode/sync-policy.js +0 -221
  916. package/dist/task/backend/sudocode/sync-policy.js.map +0 -1
  917. package/dist/task/backend/sudocode/tools.d.ts +0 -87
  918. package/dist/task/backend/sudocode/tools.d.ts.map +0 -1
  919. package/dist/task/backend/sudocode/tools.js +0 -743
  920. package/dist/task/backend/sudocode/tools.js.map +0 -1
  921. package/dist/task/backend/tool-provider.d.ts +0 -56
  922. package/dist/task/backend/tool-provider.d.ts.map +0 -1
  923. package/dist/task/backend/tool-provider.js +0 -424
  924. package/dist/task/backend/tool-provider.js.map +0 -1
  925. package/dist/task/backend/types.d.ts +0 -297
  926. package/dist/task/backend/types.d.ts.map +0 -1
  927. package/dist/task/backend/types.js +0 -27
  928. package/dist/task/backend/types.js.map +0 -1
  929. package/dist/task/backend/unified-tool-provider.d.ts +0 -57
  930. package/dist/task/backend/unified-tool-provider.d.ts.map +0 -1
  931. package/dist/task/backend/unified-tool-provider.js +0 -623
  932. package/dist/task/backend/unified-tool-provider.js.map +0 -1
  933. package/dist/task/index.d.ts +0 -7
  934. package/dist/task/index.d.ts.map +0 -1
  935. package/dist/task/index.js +0 -7
  936. package/dist/task/index.js.map +0 -1
  937. package/dist/task/retry-policy.d.ts +0 -89
  938. package/dist/task/retry-policy.d.ts.map +0 -1
  939. package/dist/task/retry-policy.js +0 -160
  940. package/dist/task/retry-policy.js.map +0 -1
  941. package/dist/task/task-manager.d.ts +0 -70
  942. package/dist/task/task-manager.d.ts.map +0 -1
  943. package/dist/task/task-manager.js +0 -319
  944. package/dist/task/task-manager.js.map +0 -1
  945. package/dist/task/types.d.ts +0 -72
  946. package/dist/task/types.d.ts.map +0 -1
  947. package/dist/task/types.js +0 -33
  948. package/dist/task/types.js.map +0 -1
  949. package/dist/teams/team-runtime.d.ts +0 -139
  950. package/dist/teams/team-runtime.d.ts.map +0 -1
  951. package/dist/teams/team-runtime.js +0 -615
  952. package/dist/teams/team-runtime.js.map +0 -1
  953. package/dist/trigger/router/index.d.ts +0 -11
  954. package/dist/trigger/router/index.d.ts.map +0 -1
  955. package/dist/trigger/router/index.js +0 -10
  956. package/dist/trigger/router/index.js.map +0 -1
  957. package/dist/trigger/router/strategies/ai-router-strategy.d.ts +0 -34
  958. package/dist/trigger/router/strategies/ai-router-strategy.d.ts.map +0 -1
  959. package/dist/trigger/router/strategies/ai-router-strategy.js +0 -359
  960. package/dist/trigger/router/strategies/ai-router-strategy.js.map +0 -1
  961. package/dist/trigger/router/strategies/direct-strategy.d.ts +0 -32
  962. package/dist/trigger/router/strategies/direct-strategy.d.ts.map +0 -1
  963. package/dist/trigger/router/strategies/direct-strategy.js +0 -119
  964. package/dist/trigger/router/strategies/direct-strategy.js.map +0 -1
  965. package/dist/trigger/router/strategies/index.d.ts +0 -11
  966. package/dist/trigger/router/strategies/index.d.ts.map +0 -1
  967. package/dist/trigger/router/strategies/index.js +0 -11
  968. package/dist/trigger/router/strategies/index.js.map +0 -1
  969. package/dist/trigger/router/strategies/role-strategy.d.ts +0 -39
  970. package/dist/trigger/router/strategies/role-strategy.d.ts.map +0 -1
  971. package/dist/trigger/router/strategies/role-strategy.js +0 -207
  972. package/dist/trigger/router/strategies/role-strategy.js.map +0 -1
  973. package/dist/trigger/router/trigger-router.d.ts +0 -54
  974. package/dist/trigger/router/trigger-router.d.ts.map +0 -1
  975. package/dist/trigger/router/trigger-router.js +0 -362
  976. package/dist/trigger/router/trigger-router.js.map +0 -1
  977. package/dist/trigger/router/types.d.ts +0 -225
  978. package/dist/trigger/router/types.d.ts.map +0 -1
  979. package/dist/trigger/router/types.js +0 -10
  980. package/dist/trigger/router/types.js.map +0 -1
  981. package/dist/trigger/trigger-system.d.ts +0 -77
  982. package/dist/trigger/trigger-system.d.ts.map +0 -1
  983. package/dist/trigger/trigger-system.js +0 -84
  984. package/dist/trigger/trigger-system.js.map +0 -1
  985. package/references/acp-factory-ref/CHANGELOG.md +0 -33
  986. package/references/acp-factory-ref/LICENSE +0 -21
  987. package/references/acp-factory-ref/README.md +0 -341
  988. package/references/acp-factory-ref/package-lock.json +0 -3102
  989. package/references/acp-factory-ref/package.json +0 -96
  990. package/references/acp-factory-ref/python/CHANGELOG.md +0 -33
  991. package/references/acp-factory-ref/python/LICENSE +0 -21
  992. package/references/acp-factory-ref/python/Makefile +0 -57
  993. package/references/acp-factory-ref/python/README.md +0 -253
  994. package/references/acp-factory-ref/python/pyproject.toml +0 -73
  995. package/references/acp-factory-ref/python/tests/e2e/__init__.py +0 -1
  996. package/references/acp-factory-ref/python/tests/e2e/test_codex_e2e.py +0 -349
  997. package/references/acp-factory-ref/python/tests/e2e/test_gemini_e2e.py +0 -165
  998. package/references/acp-factory-ref/python/tests/e2e/test_opencode_e2e.py +0 -296
  999. package/references/acp-factory-ref/python/tests/test_client_handler.py +0 -543
  1000. package/references/acp-factory-ref/python/tests/test_pushable.py +0 -199
  1001. package/references/claude-code-acp/.github/workflows/ci.yml +0 -45
  1002. package/references/claude-code-acp/.github/workflows/publish.yml +0 -34
  1003. package/references/claude-code-acp/.prettierrc.json +0 -4
  1004. package/references/claude-code-acp/CHANGELOG.md +0 -249
  1005. package/references/claude-code-acp/LICENSE +0 -222
  1006. package/references/claude-code-acp/README.md +0 -53
  1007. package/references/claude-code-acp/docs/RELEASES.md +0 -24
  1008. package/references/claude-code-acp/eslint.config.js +0 -48
  1009. package/references/claude-code-acp/package-lock.json +0 -4570
  1010. package/references/claude-code-acp/package.json +0 -88
  1011. package/references/claude-code-acp/scripts/release.sh +0 -119
  1012. package/references/claude-code-acp/src/acp-agent.ts +0 -2076
  1013. package/references/claude-code-acp/src/index.ts +0 -26
  1014. package/references/claude-code-acp/src/lib.ts +0 -38
  1015. package/references/claude-code-acp/src/mcp-server.ts +0 -911
  1016. package/references/claude-code-acp/src/settings.ts +0 -522
  1017. package/references/claude-code-acp/src/tests/.claude/commands/quick-math.md +0 -5
  1018. package/references/claude-code-acp/src/tests/.claude/commands/say-hello.md +0 -6
  1019. package/references/claude-code-acp/src/tests/acp-agent-fork.test.ts +0 -479
  1020. package/references/claude-code-acp/src/tests/acp-agent.test.ts +0 -1502
  1021. package/references/claude-code-acp/src/tests/extract-lines.test.ts +0 -103
  1022. package/references/claude-code-acp/src/tests/fork-session.test.ts +0 -335
  1023. package/references/claude-code-acp/src/tests/replace-and-calculate-location.test.ts +0 -334
  1024. package/references/claude-code-acp/src/tests/settings.test.ts +0 -617
  1025. package/references/claude-code-acp/src/tests/skills-options.test.ts +0 -187
  1026. package/references/claude-code-acp/src/tests/tools.test.ts +0 -318
  1027. package/references/claude-code-acp/src/tests/typescript-declarations.test.ts +0 -558
  1028. package/references/claude-code-acp/src/tools.ts +0 -819
  1029. package/references/claude-code-acp/src/utils.ts +0 -171
  1030. package/references/claude-code-acp/tsconfig.json +0 -18
  1031. package/references/claude-code-acp/vitest.config.ts +0 -19
  1032. package/references/multi-agent-protocol/.sudocode/issues.jsonl +0 -111
  1033. package/references/multi-agent-protocol/.sudocode/specs.jsonl +0 -13
  1034. package/references/multi-agent-protocol/LICENSE +0 -21
  1035. package/references/multi-agent-protocol/README.md +0 -113
  1036. package/references/multi-agent-protocol/docs/00-design-specification.md +0 -496
  1037. package/references/multi-agent-protocol/docs/01-open-questions.md +0 -1050
  1038. package/references/multi-agent-protocol/docs/02-wire-protocol.md +0 -296
  1039. package/references/multi-agent-protocol/docs/03-streaming-semantics.md +0 -252
  1040. package/references/multi-agent-protocol/docs/04-error-handling.md +0 -231
  1041. package/references/multi-agent-protocol/docs/05-connection-model.md +0 -244
  1042. package/references/multi-agent-protocol/docs/06-visibility-permissions.md +0 -243
  1043. package/references/multi-agent-protocol/docs/07-federation.md +0 -259
  1044. package/references/multi-agent-protocol/docs/08-macro-agent-migration.md +0 -253
  1045. package/references/multi-agent-protocol/docs/09-authentication.md +0 -680
  1046. package/references/multi-agent-protocol/docs/10-mail-protocol.md +0 -553
  1047. package/references/multi-agent-protocol/docs/agent-iam-integration.md +0 -877
  1048. package/references/multi-agent-protocol/docs/agentic-mesh-integration-draft.md +0 -459
  1049. package/references/multi-agent-protocol/docs/git-transport-draft.md +0 -251
  1050. package/references/multi-agent-protocol/docs-site/Gemfile +0 -22
  1051. package/references/multi-agent-protocol/docs-site/README.md +0 -82
  1052. package/references/multi-agent-protocol/docs-site/_config.yml +0 -91
  1053. package/references/multi-agent-protocol/docs-site/_includes/head_custom.html +0 -20
  1054. package/references/multi-agent-protocol/docs-site/_sass/color_schemes/map.scss +0 -42
  1055. package/references/multi-agent-protocol/docs-site/_sass/custom/custom.scss +0 -34
  1056. package/references/multi-agent-protocol/docs-site/examples/full-integration.md +0 -510
  1057. package/references/multi-agent-protocol/docs-site/examples/index.md +0 -138
  1058. package/references/multi-agent-protocol/docs-site/examples/simple-chat.md +0 -282
  1059. package/references/multi-agent-protocol/docs-site/examples/task-queue.md +0 -399
  1060. package/references/multi-agent-protocol/docs-site/getting-started/index.md +0 -98
  1061. package/references/multi-agent-protocol/docs-site/getting-started/installation.md +0 -219
  1062. package/references/multi-agent-protocol/docs-site/getting-started/overview.md +0 -172
  1063. package/references/multi-agent-protocol/docs-site/getting-started/quickstart.md +0 -237
  1064. package/references/multi-agent-protocol/docs-site/index.md +0 -136
  1065. package/references/multi-agent-protocol/docs-site/protocol/authentication.md +0 -391
  1066. package/references/multi-agent-protocol/docs-site/protocol/connection-model.md +0 -376
  1067. package/references/multi-agent-protocol/docs-site/protocol/design.md +0 -284
  1068. package/references/multi-agent-protocol/docs-site/protocol/error-handling.md +0 -312
  1069. package/references/multi-agent-protocol/docs-site/protocol/federation.md +0 -449
  1070. package/references/multi-agent-protocol/docs-site/protocol/index.md +0 -129
  1071. package/references/multi-agent-protocol/docs-site/protocol/permissions.md +0 -398
  1072. package/references/multi-agent-protocol/docs-site/protocol/streaming.md +0 -353
  1073. package/references/multi-agent-protocol/docs-site/protocol/wire-protocol.md +0 -369
  1074. package/references/multi-agent-protocol/docs-site/sdk/api/agent.md +0 -357
  1075. package/references/multi-agent-protocol/docs-site/sdk/api/client.md +0 -380
  1076. package/references/multi-agent-protocol/docs-site/sdk/api/index.md +0 -62
  1077. package/references/multi-agent-protocol/docs-site/sdk/api/server.md +0 -453
  1078. package/references/multi-agent-protocol/docs-site/sdk/api/types.md +0 -468
  1079. package/references/multi-agent-protocol/docs-site/sdk/guides/agent.md +0 -375
  1080. package/references/multi-agent-protocol/docs-site/sdk/guides/authentication.md +0 -405
  1081. package/references/multi-agent-protocol/docs-site/sdk/guides/client.md +0 -352
  1082. package/references/multi-agent-protocol/docs-site/sdk/guides/index.md +0 -89
  1083. package/references/multi-agent-protocol/docs-site/sdk/guides/server.md +0 -360
  1084. package/references/multi-agent-protocol/docs-site/sdk/guides/testing.md +0 -446
  1085. package/references/multi-agent-protocol/docs-site/sdk/guides/transports.md +0 -363
  1086. package/references/multi-agent-protocol/docs-site/sdk/index.md +0 -206
  1087. package/references/multi-agent-protocol/package-lock.json +0 -3886
  1088. package/references/multi-agent-protocol/package.json +0 -56
  1089. package/references/multi-agent-protocol/schema/meta.json +0 -467
  1090. package/references/multi-agent-protocol/schema/schema.json +0 -2558
  1091. package/src/__tests__/e2e/agent-spawn-visibility.e2e.test.ts +0 -761
  1092. package/src/__tests__/e2e/cascade-termination.e2e.test.ts +0 -588
  1093. package/src/__tests__/e2e/conflict-resolution-flow.e2e.test.ts +0 -790
  1094. package/src/__tests__/e2e/full-agent-conflict-resolution.e2e.test.ts +0 -714
  1095. package/src/__tests__/e2e/full-agent-orchestration.e2e.test.ts +0 -536
  1096. package/src/__tests__/e2e/mcp-server-debug.e2e.test.ts +0 -372
  1097. package/src/__tests__/e2e/mcp-thin-client-bridge.e2e.test.ts +0 -304
  1098. package/src/__tests__/e2e/mcp-tools-available.e2e.test.ts +0 -324
  1099. package/src/__tests__/e2e/multi-agent.e2e.test.ts +0 -1527
  1100. package/src/__tests__/e2e/multi-coordinator.e2e.test.ts +0 -602
  1101. package/src/__tests__/e2e/orchestration-flow.e2e.test.ts +0 -686
  1102. package/src/__tests__/e2e/spawn-session-streaming.e2e.test.ts +0 -563
  1103. package/src/__tests__/e2e/steering-task.e2e.test.ts +0 -840
  1104. package/src/__tests__/integration.e2e.test.ts +0 -407
  1105. package/src/acp/__tests__/combined-websocket-server.test.ts +0 -260
  1106. package/src/acp/__tests__/history.test.ts +0 -530
  1107. package/src/acp/__tests__/integration.test.ts +0 -1049
  1108. package/src/acp/__tests__/multi-client-mounting.test.ts +0 -303
  1109. package/src/acp/__tests__/session-persistence.test.ts +0 -276
  1110. package/src/acp/__tests__/websocket-full.e2e.test.ts +0 -401
  1111. package/src/acp/__tests__/websocket-integration.test.ts +0 -484
  1112. package/src/acp/__tests__/websocket-stream.test.ts +0 -281
  1113. package/src/acp/__tests__/websocket.e2e.test.ts +0 -390
  1114. package/src/acp/websocket-stream.ts +0 -140
  1115. package/src/activity/__tests__/deduplication.test.ts +0 -345
  1116. package/src/activity/__tests__/relevance.test.ts +0 -347
  1117. package/src/activity/__tests__/watcher.test.ts +0 -344
  1118. package/src/activity/deduplication.ts +0 -219
  1119. package/src/activity/index.ts +0 -51
  1120. package/src/activity/relevance.ts +0 -258
  1121. package/src/activity/types.ts +0 -263
  1122. package/src/activity/watcher.ts +0 -345
  1123. package/src/agent/__tests__/agent-manager.test.ts +0 -1382
  1124. package/src/agent/__tests__/wake.test.ts +0 -768
  1125. package/src/agent/wake.ts +0 -357
  1126. package/src/api/__tests__/conversation-api.test.ts +0 -468
  1127. package/src/cli/__tests__/acp.test.ts +0 -214
  1128. package/src/lifecycle/__tests__/cascade-termination.test.ts +0 -919
  1129. package/src/lifecycle/__tests__/cascade.test.ts +0 -595
  1130. package/src/lifecycle/__tests__/cleanup.test.ts +0 -322
  1131. package/src/lifecycle/__tests__/handlers.test.ts +0 -1826
  1132. package/src/lifecycle/__tests__/lifecycle.e2e.test.ts +0 -354
  1133. package/src/lifecycle/__tests__/merge-queue.e2e.test.ts +0 -602
  1134. package/src/lifecycle/handlers/generic.ts +0 -87
  1135. package/src/lifecycle/handlers/index.ts +0 -166
  1136. package/src/lifecycle/handlers/integrator.ts +0 -672
  1137. package/src/lifecycle/handlers/monitor.ts +0 -114
  1138. package/src/lifecycle/handlers/worker.ts +0 -506
  1139. package/src/mail/__tests__/conversation-lifecycle.test.ts +0 -409
  1140. package/src/mail/__tests__/eventstore-stores.test.ts +0 -1073
  1141. package/src/mail/__tests__/mail-full-agent.e2e.test.ts +0 -575
  1142. package/src/mail/__tests__/mail-integration.test.ts +0 -759
  1143. package/src/mail/__tests__/mail-map-protocol.e2e.test.ts +0 -1068
  1144. package/src/mail/__tests__/mail-service.test.ts +0 -506
  1145. package/src/mail/__tests__/turn-recorder.test.ts +0 -328
  1146. package/src/mail/conversation-map.ts +0 -107
  1147. package/src/mail/index.ts +0 -25
  1148. package/src/mail/mail-service.ts +0 -257
  1149. package/src/mail/stores/eventstore-conversation-store.ts +0 -146
  1150. package/src/mail/stores/eventstore-participant-store.ts +0 -172
  1151. package/src/mail/stores/eventstore-thread-store.ts +0 -129
  1152. package/src/mail/stores/eventstore-turn-store.ts +0 -173
  1153. package/src/mail/stores/index.ts +0 -12
  1154. package/src/mail/stores/types.ts +0 -160
  1155. package/src/mail/turn-recorder.ts +0 -124
  1156. package/src/map/README.md +0 -79
  1157. package/src/map/__tests__/adapter-types.test.ts +0 -326
  1158. package/src/map/__tests__/interface-types.test.ts +0 -342
  1159. package/src/map/__tests__/types.test.ts +0 -411
  1160. package/src/map/adapter/__tests__/acp-over-map-cancel.test.ts +0 -820
  1161. package/src/map/adapter/__tests__/acp-over-map-getmodels.test.ts +0 -355
  1162. package/src/map/adapter/__tests__/acp-over-map-history.test.ts +0 -1386
  1163. package/src/map/adapter/__tests__/acp-over-map-persistence.e2e.test.ts +0 -440
  1164. package/src/map/adapter/__tests__/connection-manager.test.ts +0 -344
  1165. package/src/map/adapter/__tests__/event-broadcast.test.ts +0 -420
  1166. package/src/map/adapter/__tests__/event-log.test.ts +0 -527
  1167. package/src/map/adapter/__tests__/event-translator.test.ts +0 -550
  1168. package/src/map/adapter/__tests__/extensions.test.ts +0 -1387
  1169. package/src/map/adapter/__tests__/map-adapter.test.ts +0 -926
  1170. package/src/map/adapter/__tests__/mcp-bridge.test.ts +0 -1187
  1171. package/src/map/adapter/__tests__/multi-client-broadcast.test.ts +0 -711
  1172. package/src/map/adapter/__tests__/rpc-handler.test.ts +0 -644
  1173. package/src/map/adapter/__tests__/subscription-manager.test.ts +0 -536
  1174. package/src/map/adapter/__tests__/websocket-integration.test.ts +0 -487
  1175. package/src/map/adapter/__tests__/workspace-files.test.ts +0 -673
  1176. package/src/map/adapter/acp-over-map.ts +0 -1483
  1177. package/src/map/adapter/connection-manager.ts +0 -400
  1178. package/src/map/adapter/event-log.ts +0 -208
  1179. package/src/map/adapter/event-translator.ts +0 -415
  1180. package/src/map/adapter/extensions/agent-detection.ts +0 -201
  1181. package/src/map/adapter/extensions/agent-lifecycle.ts +0 -267
  1182. package/src/map/adapter/extensions/index.ts +0 -280
  1183. package/src/map/adapter/extensions/mcp-bridge.ts +0 -995
  1184. package/src/map/adapter/extensions/resume.ts +0 -114
  1185. package/src/map/adapter/extensions/task.ts +0 -326
  1186. package/src/map/adapter/extensions/update-metadata.ts +0 -126
  1187. package/src/map/adapter/extensions/wake.ts +0 -239
  1188. package/src/map/adapter/extensions/workspace-files.ts +0 -449
  1189. package/src/map/adapter/extensions/workspace.ts +0 -176
  1190. package/src/map/adapter/index.ts +0 -158
  1191. package/src/map/adapter/interface.ts +0 -581
  1192. package/src/map/adapter/mail-handler-adapter.ts +0 -429
  1193. package/src/map/adapter/map-adapter.ts +0 -1749
  1194. package/src/map/adapter/rpc-handler.ts +0 -604
  1195. package/src/map/adapter/subscription-manager.ts +0 -474
  1196. package/src/map/adapter/types.ts +0 -259
  1197. package/src/map/adapter/websocket-integration.ts +0 -229
  1198. package/src/map/federation/__tests__/envelope.test.ts +0 -362
  1199. package/src/map/federation/__tests__/federation-handler.test.ts +0 -461
  1200. package/src/map/federation/envelope.ts +0 -243
  1201. package/src/map/federation/federation-handler.ts +0 -442
  1202. package/src/map/federation/index.ts +0 -65
  1203. package/src/map/federation/types.ts +0 -344
  1204. package/src/mcp/__tests__/map-client.test.ts +0 -386
  1205. package/src/mcp/__tests__/mcp-server-thin-client.test.ts +0 -368
  1206. package/src/mcp/__tests__/mcp-server.test.ts +0 -1002
  1207. package/src/mcp/map-client.ts +0 -177
  1208. package/src/mcp/mcp-server.ts +0 -1395
  1209. package/src/mcp/tools/__tests__/done.test.ts +0 -484
  1210. package/src/mcp/tools/claim_task.ts +0 -86
  1211. package/src/mcp/tools/done.ts +0 -338
  1212. package/src/mcp/tools/inject_context.ts +0 -173
  1213. package/src/mcp/tools/list_claimable_tasks.ts +0 -93
  1214. package/src/mcp/tools/unclaim_task.ts +0 -71
  1215. package/src/mcp/tools/wait_for_activity.ts +0 -185
  1216. package/src/monitor/__tests__/health-check-service.test.ts +0 -425
  1217. package/src/monitor/__tests__/stale-agent-flow.integration.test.ts +0 -393
  1218. package/src/monitor/__tests__/stall-detector.test.ts +0 -395
  1219. package/src/monitor/health-check-service.ts +0 -359
  1220. package/src/monitor/index.ts +0 -28
  1221. package/src/monitor/stall-detector.ts +0 -238
  1222. package/src/peer/__tests__/capability-manager.test.ts +0 -454
  1223. package/src/peer/__tests__/encapsulation-manager.test.ts +0 -787
  1224. package/src/peer/__tests__/federation-manager.test.ts +0 -828
  1225. package/src/peer/__tests__/hierarchy-errors.test.ts +0 -307
  1226. package/src/peer/__tests__/peer-manager.test.ts +0 -535
  1227. package/src/peer/__tests__/task-delegation.test.ts +0 -741
  1228. package/src/peer/capability-manager.ts +0 -289
  1229. package/src/peer/encapsulation-manager.ts +0 -831
  1230. package/src/peer/federation-manager.ts +0 -897
  1231. package/src/peer/hierarchy-errors.ts +0 -382
  1232. package/src/peer/hierarchy-protocol.ts +0 -328
  1233. package/src/peer/index.ts +0 -15
  1234. package/src/peer/peer-manager.ts +0 -540
  1235. package/src/peer/task-delegation.ts +0 -594
  1236. package/src/peer/transports/__tests__/local-transport.test.ts +0 -355
  1237. package/src/peer/transports/__tests__/websocket-transport.test.ts +0 -270
  1238. package/src/peer/transports/index.ts +0 -18
  1239. package/src/peer/transports/local-transport.ts +0 -348
  1240. package/src/peer/transports/websocket-transport.ts +0 -452
  1241. package/src/peer/types.ts +0 -331
  1242. package/src/roles/__tests__/capability-enforcement.test.ts +0 -989
  1243. package/src/roles/__tests__/message-routing.e2e.test.ts +0 -464
  1244. package/src/roles/__tests__/role-resolution.test.ts +0 -576
  1245. package/src/router/README.md +0 -120
  1246. package/src/router/__tests__/address-resolver.test.ts +0 -340
  1247. package/src/router/__tests__/broadcast.test.ts +0 -185
  1248. package/src/router/__tests__/message-router.test.ts +0 -1070
  1249. package/src/router/__tests__/role-channel.test.ts +0 -213
  1250. package/src/router/__tests__/send-to-address.test.ts +0 -731
  1251. package/src/router/__tests__/wake.test.ts +0 -459
  1252. package/src/router/address-resolver.ts +0 -303
  1253. package/src/router/broadcast.ts +0 -117
  1254. package/src/router/channels.ts +0 -283
  1255. package/src/router/index.ts +0 -148
  1256. package/src/router/message-router.ts +0 -1392
  1257. package/src/router/message-types.ts +0 -294
  1258. package/src/router/role-resolver.ts +0 -164
  1259. package/src/router/signals.ts +0 -335
  1260. package/src/router/types.ts +0 -306
  1261. package/src/router/wake.ts +0 -270
  1262. package/src/server/__tests__/combined-server.test.ts +0 -360
  1263. package/src/server/combined-server.ts +0 -530
  1264. package/src/steering/__tests__/inject.test.ts +0 -405
  1265. package/src/steering/__tests__/injection.e2e.test.ts +0 -932
  1266. package/src/steering/__tests__/steering-integration.test.ts +0 -747
  1267. package/src/steering/index.ts +0 -25
  1268. package/src/steering/inject.ts +0 -262
  1269. package/src/steering/types.ts +0 -143
  1270. package/src/store/README.md +0 -134
  1271. package/src/store/__tests__/event-store.test.ts +0 -1446
  1272. package/src/store/__tests__/instance.test.ts +0 -556
  1273. package/src/store/__tests__/migrations.test.ts +0 -109
  1274. package/src/store/backends/__tests__/memory-backend.test.ts +0 -383
  1275. package/src/store/backends/__tests__/sqlite-backend.test.ts +0 -427
  1276. package/src/store/backends/index.ts +0 -42
  1277. package/src/store/backends/json-backend.ts +0 -295
  1278. package/src/store/backends/memory-backend.ts +0 -256
  1279. package/src/store/backends/sqlite-backend.ts +0 -337
  1280. package/src/store/backends/tinybase-backend.ts +0 -276
  1281. package/src/store/backends/types.ts +0 -252
  1282. package/src/store/event-store.ts +0 -2204
  1283. package/src/store/instance.ts +0 -681
  1284. package/src/store/migrations.ts +0 -96
  1285. package/src/store/types/config.ts +0 -19
  1286. package/src/store/types/conversations.ts +0 -129
  1287. package/src/store/types/sessions.ts +0 -53
  1288. package/src/task/__tests__/retry-policy.test.ts +0 -409
  1289. package/src/task/__tests__/task-integration.test.ts +0 -457
  1290. package/src/task/__tests__/task-manager.test.ts +0 -815
  1291. package/src/task/backend/__tests__/create-task-backend.test.ts +0 -225
  1292. package/src/task/backend/__tests__/e2e/unified-tool-provider-opentasks.e2e.test.ts +0 -524
  1293. package/src/task/backend/__tests__/memory.test.ts +0 -1274
  1294. package/src/task/backend/__tests__/unified-tool-provider.test.ts +0 -579
  1295. package/src/task/backend/index.ts +0 -310
  1296. package/src/task/backend/memory.ts +0 -828
  1297. package/src/task/backend/opentasks/__tests__/backend.test.ts +0 -968
  1298. package/src/task/backend/opentasks/__tests__/daemon-manager.test.ts +0 -406
  1299. package/src/task/backend/opentasks/__tests__/mapping.test.ts +0 -84
  1300. package/src/task/backend/opentasks/__tests__/opentasks-backend.e2e.test.ts +0 -1338
  1301. package/src/task/backend/opentasks/backend.ts +0 -1323
  1302. package/src/task/backend/opentasks/client.ts +0 -652
  1303. package/src/task/backend/opentasks/daemon-manager.ts +0 -253
  1304. package/src/task/backend/opentasks/index.ts +0 -69
  1305. package/src/task/backend/opentasks/mapping.ts +0 -94
  1306. package/src/task/backend/types.ts +0 -458
  1307. package/src/task/backend/unified-tool-provider.ts +0 -779
  1308. package/src/task/index.ts +0 -7
  1309. package/src/task/retry-policy.ts +0 -204
  1310. package/src/task/task-manager.ts +0 -515
  1311. package/src/task/types.ts +0 -136
  1312. package/src/teams/__tests__/cross-subsystem.integration.test.ts +0 -983
  1313. package/src/teams/__tests__/e2e/team-runtime.e2e.test.ts +0 -553
  1314. package/src/teams/__tests__/team-system.test.ts +0 -1280
  1315. package/src/teams/team-runtime.ts +0 -729
  1316. package/src/trigger/CLAUDE.md +0 -308
  1317. package/src/trigger/README.md +0 -429
  1318. package/src/trigger/__tests__/macro-agent-regression.test.ts +0 -946
  1319. package/src/trigger/__tests__/routing-strategies.test.ts +0 -329
  1320. package/src/trigger/__tests__/trigger-router.test.ts +0 -433
  1321. package/src/trigger/__tests__/trigger-system-integration.test.ts +0 -581
  1322. package/src/trigger/router/index.ts +0 -36
  1323. package/src/trigger/router/strategies/ai-router-strategy.ts +0 -481
  1324. package/src/trigger/router/strategies/direct-strategy.ts +0 -162
  1325. package/src/trigger/router/strategies/index.ts +0 -26
  1326. package/src/trigger/router/strategies/role-strategy.ts +0 -274
  1327. package/src/trigger/router/trigger-router.ts +0 -463
  1328. package/src/trigger/router/types.ts +0 -273
  1329. package/src/trigger/trigger-system.ts +0 -206
  1330. package/src/workspace/__tests__/multi-coordinator.test.ts +0 -1005
  1331. package/src/workspace/__tests__/workspace-manager.test.ts +0 -391
  1332. package/src/workspace/__tests__/workspace.e2e.test.ts +0 -1155
  1333. package/src/workspace/merge-queue/__tests__/hierarchical-consolidation.e2e.test.ts +0 -414
  1334. package/test_fixtures/harness/__tests__/behavior-executor-and-stepper.test.ts +0 -714
  1335. package/test_fixtures/harness/__tests__/fixtures.test.ts +0 -347
  1336. package/test_fixtures/harness/__tests__/merge-queue-and-worktrees.test.ts +0 -452
  1337. package/test_fixtures/harness/__tests__/temp-repo-and-simulator.test.ts +0 -422
  1338. package/test_fixtures/harness/__tests__/test-harness-and-assertions.test.ts +0 -568
  1339. /package/{references/acp-factory-ref/python/tests/__init__.py → .opentasks/graph.jsonl} +0 -0
package/src/api/server.ts CHANGED
@@ -1,1974 +1,380 @@
1
1
  /**
2
- * API Server
2
+ * REST API server for macro-agent.
3
3
  *
4
- * Express server with REST API and WebSocket support for the multi-agent system.
4
+ * Provides HTTP endpoints for managing agents, tasks, teams, and metrics.
5
5
  *
6
- * Can be used in two modes:
7
- * 1. Standalone: createAPIServer() creates its own HTTP server
8
- * 2. Shared: createAPIApp() + setupAPIWebSocket() for external HTTP server
6
+ * @module api/server
9
7
  */
10
8
 
11
- import express, { Express, Request, Response, NextFunction } from "express";
12
- import { WebSocketServer, WebSocket } from "ws";
13
- import http from "http";
14
- import type { EventStore } from "../store/event-store.js";
15
- import type { AgentManager } from "../agent/agent-manager.js";
16
- import type { TaskManager } from "../task/task-manager.js";
17
- import type { MessageRouter } from "../router/message-router.js";
18
- import type { Agent, Task, Event } from "../store/types/index.js";
19
- import type {
20
- SystemStatus,
21
- InitRequest,
22
- InitResponse,
23
- ConversationMessageRequest,
24
- ConversationHistoryResponse,
25
- AgentSummary,
26
- AgentDetail,
27
- AgentListResponse,
28
- HierarchyResponse,
29
- HierarchyNode,
30
- TaskSummary,
31
- TaskDetail,
32
- TaskListResponse,
33
- EventSummary,
34
- EventListResponse,
35
- AgentQueryParams,
36
- TaskQueryParams,
37
- EventQueryParams,
38
- APIError,
39
- WSMessage,
40
- WSSubscribeMessage,
41
- WSAgentUpdate,
42
- WSTaskUpdate,
43
- InjectContextRequest,
44
- InjectContextResponse,
45
- MailConversationSummary,
46
- MailConversationDetail,
47
- MailConversationListResponse,
48
- MailTurnSummary,
49
- MailTurnListResponse,
50
- MailConversationQueryParams,
51
- WSTurnAdded,
52
- WSConversationUpdate,
53
- } from "./types.js";
54
- import {
55
- injectContext,
56
- type InjectionDeps,
57
- } from "../steering/index.js";
58
- import type { AgentId } from "../store/types/index.js";
59
- import { secureCompare } from "../auth/token.js";
9
+ import express, { type Request, type Response } from "express";
10
+ import type { Server } from "node:http";
11
+ import type { MacroAgentSystemV2 } from "../boot-v2.js";
12
+ import type { ApiServer, ApiServerConfig } from "./types.js";
60
13
 
61
- // ─────────────────────────────────────────────────────────────────
62
- // Server Configuration
63
- // ─────────────────────────────────────────────────────────────────
14
+ // =============================================================================
15
+ // Helpers
16
+ // =============================================================================
64
17
 
65
- export interface APIServerConfig {
66
- /** Port to listen on */
67
- port?: number;
68
-
69
- /** Host to bind to */
70
- host?: string;
71
-
72
- /** Enable CORS */
73
- cors?: boolean;
74
-
75
- /** Grace period in milliseconds for in-flight work during shutdown (default: 5000) */
76
- shutdownGracePeriodMs?: number;
77
-
78
- /** Server token for Bearer auth on API routes. When set, all routes except /health require auth. */
79
- serverToken?: string;
80
- }
81
-
82
- export interface APIServices {
83
- eventStore: EventStore;
84
- agentManager: AgentManager;
85
- taskManager: TaskManager;
86
- messageRouter: MessageRouter;
87
- /** Optional mail service for conversation tracking */
88
- mailService?: import("../mail/mail-service.js").MailService;
89
- /** Optional conversation map for agent-to-conversation tracking */
90
- conversationMap?: import("../mail/conversation-map.js").ConversationMap;
91
- }
92
-
93
- // ─────────────────────────────────────────────────────────────────
94
- // API Server Instance
95
- // ─────────────────────────────────────────────────────────────────
96
-
97
- export interface StopOptions {
98
- /** Force immediate shutdown, skipping grace period */
99
- force?: boolean;
100
- }
101
-
102
- export interface APIServer {
103
- /** Express app for testing */
104
- app: Express;
105
-
106
- /** HTTP server */
107
- server: http.Server;
108
-
109
- /** WebSocket server */
110
- wss: WebSocketServer;
111
-
112
- /** Start the server */
113
- start(): Promise<void>;
114
-
115
- /**
116
- * Stop the server gracefully.
117
- * 1. Stop accepting new connections
118
- * 2. Wait grace period for in-flight prompts
119
- * 3. Close WebSocket connections with 1001 "going away"
120
- * 4. Terminate running agents
121
- * 5. Persist and close event store
122
- */
123
- stop(options?: StopOptions): Promise<void>;
124
-
125
- /** Get current status */
126
- getStatus(): SystemStatus;
127
-
128
- /** Register signal handlers for graceful shutdown */
129
- registerSignalHandlers(): void;
130
- }
131
-
132
- // ─────────────────────────────────────────────────────────────────
133
- // Server State
134
- // ─────────────────────────────────────────────────────────────────
135
-
136
- interface ServerState {
137
- initialized: boolean;
138
- headManagerId?: string;
139
- startedAt?: number;
140
- conversationHistory: Array<{
141
- role: "user" | "assistant";
142
- content: string;
143
- agent_id?: string;
144
- timestamp: number;
145
- }>;
146
- /** Tracks in-flight prompt promises for graceful shutdown */
147
- inFlightPrompts: Map<string, Promise<void>>;
148
- /** Whether shutdown is in progress */
149
- isShuttingDown: boolean;
150
- }
151
-
152
- // ─────────────────────────────────────────────────────────────────
153
- // WebSocket Client Tracking
154
- // ─────────────────────────────────────────────────────────────────
155
-
156
- interface WSClient {
157
- ws: WebSocket;
158
- subscriptions: Set<string>;
159
- }
160
-
161
- /**
162
- * API WebSocket handler interface (shared server mode)
163
- */
164
- export interface APIWebSocketHandler {
165
- /** Get the number of active connections */
166
- getConnectionCount(): number;
167
-
168
- /** Close all connections gracefully */
169
- closeAll(): void;
170
- }
171
-
172
- /**
173
- * Shared state for API app and WebSocket handler
174
- */
175
- export interface APISharedState {
176
- initialized: boolean;
177
- headManagerId?: string;
178
- startedAt?: number;
179
- conversationHistory: Array<{
180
- role: "user" | "assistant";
181
- content: string;
182
- agent_id?: string;
183
- timestamp: number;
184
- }>;
185
- inFlightPrompts: Map<string, Promise<void>>;
186
- isShuttingDown: boolean;
187
- wsClients: Set<WSClient>;
188
- broadcast: (channel: string, message: WSMessage) => void;
18
+ /** Extract a single string from Express v5 param/query (string | string[]). */
19
+ function str(value: unknown): string | undefined {
20
+ if (typeof value === "string") return value;
21
+ if (Array.isArray(value) && typeof value[0] === "string") return value[0];
22
+ return undefined;
189
23
  }
190
24
 
191
- /**
192
- * Create shared state for API app and WebSocket handler
193
- */
194
- export function createAPISharedState(): APISharedState {
195
- const wsClients = new Set<WSClient>();
196
-
197
- const broadcast = (channel: string, message: WSMessage): void => {
198
- const data = JSON.stringify(message);
199
- for (const client of wsClients) {
200
- if (client.subscriptions.has(channel) && client.ws.readyState === WebSocket.OPEN) {
201
- client.ws.send(data);
202
- }
203
- }
204
- };
25
+ // =============================================================================
26
+ // Placeholder metrics (will be replaced when metrics module lands)
27
+ // =============================================================================
205
28
 
206
- return {
207
- initialized: false,
208
- conversationHistory: [],
209
- inFlightPrompts: new Map(),
210
- isShuttingDown: false,
211
- wsClients,
212
- broadcast,
29
+ interface MetricsSnapshot {
30
+ agents: {
31
+ total: number;
32
+ running: number;
33
+ stopped: number;
34
+ failed: number;
213
35
  };
214
- }
215
-
216
- // ─────────────────────────────────────────────────────────────────
217
- // Conversation API Routes (shared between standalone and app mode)
218
- // ─────────────────────────────────────────────────────────────────
219
-
220
- import type { Conversation, ConversationTurn } from "../store/types/conversations.js";
221
-
222
- function conversationToSummary(conv: Conversation): MailConversationSummary {
223
- return {
224
- id: conv.id,
225
- type: conv.type,
226
- status: conv.status,
227
- subject: conv.subject ?? "",
228
- created_by: conv.createdBy,
229
- created_at: conv.createdAt,
230
- updated_at: conv.updatedAt,
231
- participant_count: conv.participantCount,
232
- parent_conversation_id: conv.parentConversationId || undefined,
36
+ tasks: {
37
+ total: number;
38
+ open: number;
39
+ in_progress: number;
40
+ closed: number;
233
41
  };
42
+ uptime: number;
43
+ collectedAt: string;
234
44
  }
235
45
 
236
- function conversationToDetail(conv: Conversation): MailConversationDetail {
237
- return {
238
- ...conversationToSummary(conv),
239
- closed_at: conv.closedAt || undefined,
240
- closed_by: conv.closedBy || undefined,
241
- close_reason: conv.closeReason || undefined,
242
- };
243
- }
46
+ async function collectMetricsPlaceholder(
47
+ system: MacroAgentSystemV2,
48
+ startTime: number
49
+ ): Promise<MetricsSnapshot> {
50
+ const agents = system.agentStore.listAgents();
51
+ const running = agents.filter((a) => a.state === "running").length;
52
+ const stopped = agents.filter((a) => a.state === "stopped").length;
53
+ const failed = agents.filter((a) => a.state === "failed").length;
54
+
55
+ let taskMetrics = { total: 0, open: 0, in_progress: 0, closed: 0 };
56
+ try {
57
+ const tasks = await system.tasksAdapter.listTasks();
58
+ taskMetrics = {
59
+ total: tasks.length,
60
+ open: tasks.filter((t) => t.status === "open").length,
61
+ in_progress: tasks.filter((t) => t.status === "in_progress").length,
62
+ closed: tasks.filter((t) => t.status === "closed").length,
63
+ };
64
+ } catch {
65
+ // opentasks may be down
66
+ }
244
67
 
245
- function turnToSummary(turn: ConversationTurn): MailTurnSummary {
246
68
  return {
247
- id: turn.id,
248
- conversation_id: turn.conversationId,
249
- participant: turn.participant,
250
- content_type: turn.contentType,
251
- content: turn.content,
252
- timestamp: turn.timestamp,
253
- source_type: turn.sourceType || undefined,
254
- source_message_id: turn.sourceMessageId || undefined,
69
+ agents: {
70
+ total: agents.length,
71
+ running,
72
+ stopped,
73
+ failed,
74
+ },
75
+ tasks: taskMetrics,
76
+ uptime: (Date.now() - startTime) / 1000,
77
+ collectedAt: new Date().toISOString(),
255
78
  };
256
79
  }
257
80
 
258
- /**
259
- * Register conversation API routes on an Express app.
260
- * Used by both standalone and shared server modes.
261
- */
262
- function registerConversationRoutes(
263
- app: Express,
264
- services: Pick<APIServices, "mailService">,
265
- sendError: (res: Response, status: number, code: string, message: string) => void
266
- ): void {
267
- if (!services.mailService) return;
268
- const { mailService } = services;
81
+ // =============================================================================
82
+ // Factory
83
+ // =============================================================================
269
84
 
270
- // GET /api/conversations - List conversations
271
- app.get("/api/conversations", (req: Request, res: Response) => {
272
- const params = req.query as Record<string, string | undefined>;
273
- let conversations = mailService.listConversations({
274
- type: params.type as any,
275
- status: params.status as any,
276
- });
85
+ export function createApiServer(
86
+ system: MacroAgentSystemV2,
87
+ config?: ApiServerConfig
88
+ ): ApiServer {
89
+ const port = config?.port ?? 3000;
90
+ const host = config?.host ?? "127.0.0.1";
91
+ const startTime = Date.now();
277
92
 
278
- const total = conversations.length;
279
- const offset = parseInt(params.offset as string) || 0;
280
- const limit = parseInt(params.limit as string) || 50;
281
- conversations = conversations.slice(offset, offset + limit);
93
+ const app = express();
94
+ app.use(express.json());
282
95
 
283
- const response: MailConversationListResponse = {
284
- conversations: conversations.map(conversationToSummary),
285
- total,
286
- };
287
- res.json(response);
288
- });
96
+ // ── Health ──────────────────────────────────────────────────────
289
97
 
290
- // GET /api/conversations/:id - Get conversation detail
291
- app.get("/api/conversations/:id", (req: Request, res: Response) => {
292
- const conv = mailService.getConversation(req.params.id);
293
- if (!conv) {
294
- return sendError(res, 404, "CONVERSATION_NOT_FOUND", `Conversation not found: ${req.params.id}`);
295
- }
296
- res.json(conversationToDetail(conv));
98
+ app.get("/api/health", (_req: Request, res: Response) => {
99
+ res.json({
100
+ ok: true,
101
+ uptime: (Date.now() - startTime) / 1000,
102
+ version: "0.1.1",
103
+ });
297
104
  });
298
105
 
299
- // GET /api/conversations/:id/turns - List turns for a conversation
300
- app.get("/api/conversations/:id/turns", (req: Request, res: Response) => {
301
- const conv = mailService.getConversation(req.params.id);
302
- if (!conv) {
303
- return sendError(res, 404, "CONVERSATION_NOT_FOUND", `Conversation not found: ${req.params.id}`);
304
- }
305
-
306
- const turns = mailService.listTurns({ conversationId: req.params.id });
307
- const limit = parseInt(req.query.limit as string) || 50;
308
- const offset = parseInt(req.query.offset as string) || 0;
309
- const paged = turns.slice(offset, offset + limit);
106
+ // ── Agents ─────────────────────────────────────────────────────
310
107
 
311
- const response: MailTurnListResponse = {
312
- turns: paged.map(turnToSummary),
313
- total: turns.length,
314
- };
315
- res.json(response);
316
- });
108
+ app.get("/api/agents", (req: Request, res: Response) => {
109
+ try {
110
+ const state = str(req.query.state);
111
+ const role = str(req.query.role);
112
+ const team = str(req.query.team);
113
+ const limit = parseInt(str(req.query.limit) ?? "50", 10) || 50;
114
+ const offset = parseInt(str(req.query.offset) ?? "0", 10) || 0;
317
115
 
318
- // POST /api/conversations/:id/close - Close a conversation
319
- app.post("/api/conversations/:id/close", (req: Request, res: Response) => {
320
- const conv = mailService.getConversation(req.params.id);
321
- if (!conv) {
322
- return sendError(res, 404, "CONVERSATION_NOT_FOUND", `Conversation not found: ${req.params.id}`);
323
- }
324
- if (conv.status !== "active") {
325
- return sendError(res, 400, "ALREADY_CLOSED", `Conversation already ${conv.status}`);
326
- }
116
+ const filter: Record<string, unknown> = {};
117
+ if (state) filter.state = state;
118
+ if (role) filter.role = role;
119
+ if (team) filter.team = team;
327
120
 
328
- const body = req.body as { reason?: string };
329
- mailService.closeConversation({
330
- conversationId: req.params.id,
331
- closedBy: "api",
332
- reason: body.reason ?? "completed",
333
- });
121
+ const agents = system.agentManager.list(
122
+ Object.keys(filter).length > 0 ? (filter as any) : undefined
123
+ );
334
124
 
335
- res.json({ success: true });
336
- });
125
+ const total = agents.length;
126
+ const paged = agents.slice(offset, offset + limit);
337
127
 
338
- // GET /api/conversations/:id/participants - List participants
339
- app.get("/api/conversations/:id/participants", (req: Request, res: Response) => {
340
- const conv = mailService.getConversation(req.params.id);
341
- if (!conv) {
342
- return sendError(res, 404, "CONVERSATION_NOT_FOUND", `Conversation not found: ${req.params.id}`);
128
+ res.json({ agents: paged, total });
129
+ } catch (err: any) {
130
+ res.status(500).json({ error: err.message ?? "Internal server error" });
343
131
  }
344
-
345
- const participants = mailService.listParticipants(req.params.id);
346
- res.json({ participants, total: participants.length });
347
132
  });
348
- }
349
-
350
- // ─────────────────────────────────────────────────────────────────
351
- // Create API Server
352
- // ─────────────────────────────────────────────────────────────────
353
-
354
- export function createAPIServer(
355
- services: APIServices,
356
- config: APIServerConfig = {}
357
- ): APIServer {
358
- const { port = 3000, host = "localhost", cors = true, shutdownGracePeriodMs = 5000, serverToken } = config;
359
- const { eventStore, agentManager, taskManager } = services;
360
-
361
- // Server state
362
- const state: ServerState = {
363
- initialized: false,
364
- conversationHistory: [],
365
- inFlightPrompts: new Map(),
366
- isShuttingDown: false,
367
- };
368
-
369
- // WebSocket clients
370
- const wsClients = new Set<WSClient>();
371
-
372
- // Create Express app
373
- const app = express();
374
-
375
- // Middleware
376
- app.use(express.json());
377
133
 
378
- if (cors) {
379
- app.use((_req: Request, res: Response, next: NextFunction) => {
380
- res.header("Access-Control-Allow-Origin", "*");
381
- res.header("Access-Control-Allow-Headers", "Content-Type, Authorization");
382
- res.header("Access-Control-Allow-Methods", "GET, POST, DELETE");
383
- next();
384
- });
385
- }
386
-
387
- // Bearer token auth middleware (skip /health)
388
- if (serverToken) {
389
- app.use((req: Request, res: Response, next: NextFunction) => {
390
- if (req.path === "/health") return next();
391
- const authHeader = req.headers.authorization;
392
- const token = authHeader?.startsWith("Bearer ") ? authHeader.slice(7) : undefined;
393
- if (!token || !secureCompare(token, serverToken)) {
394
- const error: APIError = { error: "Unauthorized", code: "AUTH_REQUIRED" };
395
- res.status(401).json(error);
134
+ app.get("/api/agents/:id", (req: Request, res: Response) => {
135
+ try {
136
+ const id = str(req.params.id);
137
+ const agent = system.agentManager.get(id!);
138
+ if (!agent) {
139
+ res.status(404).json({ error: "Agent not found" });
396
140
  return;
397
141
  }
398
- next();
399
- });
400
- }
401
-
402
- // ─────────────────────────────────────────────────────────────────
403
- // Helper Functions
404
- // ─────────────────────────────────────────────────────────────────
405
-
406
- function agentToSummary(agent: Agent): AgentSummary {
407
- return {
408
- id: agent.id,
409
- session_id: agent.session_id,
410
- task: agent.task ?? "No task",
411
- state: agent.state,
412
- parent: agent.parent,
413
- children_count: agentManager.getChildren(agent.id).length,
414
- created_at: agent.created_at,
415
- };
416
- }
417
-
418
- function agentToDetail(agent: Agent): AgentDetail {
419
- return {
420
- ...agentToSummary(agent),
421
- lineage: agent.lineage,
422
- task_id: agent.task_id,
423
- config: agent.config as Record<string, unknown>,
424
- started_at: agent.started_at,
425
- stopped_at: agent.stopped_at,
426
- stop_reason: agent.stop_reason,
427
- };
428
- }
429
-
430
- function taskToSummary(task: Task): TaskSummary {
431
- return {
432
- id: task.id,
433
- description: task.description,
434
- status: task.status,
435
- assigned_agent: task.assigned_agent,
436
- created_at: task.created_at,
437
- };
438
- }
439
-
440
- function taskToDetail(task: Task): TaskDetail {
441
- return {
442
- ...taskToSummary(task),
443
- parent_task: task.parent_task,
444
- subtasks: task.subtasks ?? [],
445
- created_by: task.created_by,
446
- inputs: task.inputs,
447
- outputs: task.outputs,
448
- artifacts: task.artifacts,
449
- started_at: task.started_at,
450
- completed_at: task.completed_at,
451
- };
452
- }
453
-
454
- function eventToSummary(event: Event): EventSummary {
455
- let summary = "";
456
- switch (event.type) {
457
- case "spawn":
458
- summary = `Agent ${event.payload.agent_id} spawned`;
459
- break;
460
- case "stop":
461
- summary = `Agent terminated: ${event.payload.reason}`;
462
- break;
463
- case "status":
464
- summary = `${event.payload.status_type}: ${event.payload.summary}`;
465
- break;
466
- case "message":
467
- summary = `Message: ${String(event.payload.content).substring(0, 50)}...`;
468
- break;
469
- case "task":
470
- summary = `Task ${event.payload.action}: ${event.payload.task_id}`;
471
- break;
472
- default:
473
- summary = `${event.type} event`;
142
+ res.json(agent);
143
+ } catch (err: any) {
144
+ res.status(500).json({ error: err.message ?? "Internal server error" });
474
145
  }
146
+ });
475
147
 
476
- return {
477
- id: event.id,
478
- type: event.type,
479
- timestamp: event.timestamp,
480
- source_agent_id: event.source.agent_id,
481
- target_agent_id: event.target?.agent_id,
482
- summary,
483
- };
484
- }
485
-
486
- function buildHierarchyNode(agent: Agent): HierarchyNode {
487
- const children = agentManager.getChildren(agent.id);
488
- return {
489
- agent_id: agent.id,
490
- task: agent.task ?? "No task",
491
- state: agent.state,
492
- children: children.map(buildHierarchyNode),
493
- };
494
- }
495
-
496
- function sendError(res: Response, status: number, code: string, message: string): void {
497
- const error: APIError = { error: message, code };
498
- res.status(status).json(error);
499
- }
148
+ app.get("/api/agents/:id/hierarchy", (req: Request, res: Response) => {
149
+ try {
150
+ const id = str(req.params.id)!;
151
+ const depthStr = str(req.query.depth);
152
+ const options = depthStr ? { depth: parseInt(depthStr, 10) } : undefined;
500
153
 
501
- function broadcastToChannel(channel: string, message: WSMessage): void {
502
- const data = JSON.stringify(message);
503
- for (const client of wsClients) {
504
- if (client.subscriptions.has(channel) && client.ws.readyState === WebSocket.OPEN) {
505
- client.ws.send(data);
154
+ const hierarchy = system.agentManager.getHierarchy(id, options);
155
+ if (!hierarchy) {
156
+ res.status(404).json({ error: "Agent not found" });
157
+ return;
506
158
  }
159
+ res.json(hierarchy);
160
+ } catch (err: any) {
161
+ res.status(500).json({ error: err.message ?? "Internal server error" });
507
162
  }
508
- }
509
-
510
- // ─────────────────────────────────────────────────────────────────
511
- // API Routes
512
- // ─────────────────────────────────────────────────────────────────
163
+ });
513
164
 
514
- // POST /api/init - Initialize the system
515
- app.post("/api/init", async (req: Request, res: Response) => {
165
+ app.get("/api/agents/:id/inbox", async (req: Request, res: Response) => {
516
166
  try {
517
- if (state.initialized) {
518
- return sendError(res, 400, "ALREADY_INITIALIZED", "System already initialized");
167
+ const id = str(req.params.id)!;
168
+ const agent = system.agentManager.get(id);
169
+ if (!agent) {
170
+ res.status(404).json({ error: "Agent not found" });
171
+ return;
519
172
  }
520
173
 
521
- const body = req.body as InitRequest;
522
- const cwd = body.cwd ?? process.cwd();
174
+ const limit = parseInt(str(req.query.limit) ?? "20", 10) || 20;
175
+ const unreadOnly = str(req.query.unreadOnly) === "true";
523
176
 
524
- const headManager = await agentManager.getOrCreateHeadManager({
525
- cwd,
526
- systemPrompt: body.system_prompt,
527
- permissionMode: body.permission_mode,
177
+ const messages = await system.inboxAdapter.checkInbox(id, {
178
+ limit,
179
+ unreadOnly,
528
180
  });
529
181
 
530
- state.initialized = true;
531
- state.headManagerId = headManager.id;
532
- state.startedAt = Date.now();
182
+ res.json({ messages });
183
+ } catch (err: any) {
184
+ res.status(500).json({ error: err.message ?? "Internal server error" });
185
+ }
186
+ });
533
187
 
534
- // Create session conversation for mail tracking
535
- if (services.mailService && services.conversationMap) {
536
- try {
537
- const { conversationId } = services.mailService.createConversation({
538
- type: "session",
539
- subject: "User session",
540
- createdBy: "user",
541
- });
542
- services.mailService.joinConversation({
543
- conversationId,
544
- participantId: headManager.id,
545
- role: "worker",
546
- });
547
- services.conversationMap.setSessionConversation(headManager.id, conversationId);
548
- } catch {
549
- // Never fail init due to mail errors
550
- }
188
+ app.post("/api/agents", async (req: Request, res: Response) => {
189
+ try {
190
+ const { task, role, parent, cwd } = req.body;
191
+
192
+ if (!task) {
193
+ res.status(400).json({ error: "Missing required field: task" });
194
+ return;
551
195
  }
552
196
 
553
- const response: InitResponse = {
554
- success: true,
555
- head_manager_id: headManager.id,
556
- session_id: headManager.session_id,
557
- };
197
+ const spawned = await system.agentManager.spawn({
198
+ task,
199
+ role,
200
+ parent,
201
+ cwd,
202
+ });
558
203
 
559
- res.json(response);
560
- } catch (error) {
561
- sendError(res, 500, "INIT_FAILED", `Failed to initialize: ${error}`);
204
+ res.status(201).json(spawned);
205
+ } catch (err: any) {
206
+ res.status(500).json({ error: err.message ?? "Internal server error" });
562
207
  }
563
208
  });
564
209
 
565
- // GET /api/status - Get system status
566
- app.get("/api/status", (_req: Request, res: Response) => {
567
- const status = getStatus();
568
- res.json(status);
569
- });
210
+ app.delete("/api/agents/:id", async (req: Request, res: Response) => {
211
+ try {
212
+ const id = str(req.params.id)!;
213
+ const agent = system.agentManager.get(id);
214
+ if (!agent) {
215
+ res.status(404).json({ error: "Agent not found" });
216
+ return;
217
+ }
570
218
 
571
- // GET /api/team - Get active team info
572
- app.get("/api/team", (_req: Request, res: Response) => {
573
- // Check for team config in EventStore
574
- const statusEvents = eventStore.query({ type: "status", limit: 50 });
575
- const teamConfigEvent = statusEvents.find(
576
- (e) => e.payload?.team_config != null
577
- );
219
+ const reason = str(req.query.reason) ?? "cancelled";
220
+ await system.agentManager.terminate(id, reason as any);
578
221
 
579
- if (!teamConfigEvent?.payload?.team_config) {
580
- res.json({ active: false });
581
- return;
222
+ res.json({ ok: true });
223
+ } catch (err: any) {
224
+ res.status(500).json({ error: err.message ?? "Internal server error" });
582
225
  }
583
-
584
- const tc = teamConfigEvent.payload.team_config as Record<string, unknown>;
585
- res.json({
586
- active: true,
587
- name: tc.teamName,
588
- strategy: tc.strategy,
589
- taskMode: tc.taskMode,
590
- enforcement: tc.enforcement,
591
- });
592
226
  });
593
227
 
594
- // ─────────────────────────────────────────────────────────────────
595
- // Metrics Endpoints (Phase 5)
596
- // ─────────────────────────────────────────────────────────────────
228
+ // ── Tasks ──────────────────────────────────────────────────────
597
229
 
598
- // GET /api/metrics/throughput - Task throughput metrics
599
- app.get("/api/metrics/throughput", (req: Request, res: Response) => {
600
- const windowMs = req.query.window_ms
601
- ? Number(req.query.window_ms)
602
- : 5 * 60 * 1000;
603
- const after = Date.now() - windowMs;
230
+ app.get("/api/tasks", async (req: Request, res: Response) => {
231
+ try {
232
+ const status = str(req.query.status);
233
+ const assignee = str(req.query.assignee);
234
+ const limitStr = str(req.query.limit);
604
235
 
605
- const taskEvents = eventStore.query({ type: "task", after });
606
- let completed = 0, failed = 0, created = 0;
607
- for (const e of taskEvents) {
608
- const action = e.payload?.action as string | undefined;
609
- if (action === "created") created++;
610
- else if (action === "completed") completed++;
611
- else if (action === "failed") failed++;
612
- }
613
- const windowMin = windowMs / 60000;
236
+ const filter: Record<string, unknown> = {};
237
+ if (status) filter.status = status;
238
+ if (assignee) filter.assignee = assignee;
239
+ if (limitStr) filter.limit = parseInt(limitStr, 10);
614
240
 
615
- res.json({
616
- tasksCompleted: completed,
617
- tasksFailed: failed,
618
- tasksCreated: created,
619
- completedPerMinute: windowMin > 0 ? Math.round((completed / windowMin) * 100) / 100 : 0,
620
- windowMs,
621
- });
622
- });
241
+ const tasks = await system.tasksAdapter.listTasks(
242
+ Object.keys(filter).length > 0 ? (filter as any) : undefined
243
+ );
623
244
 
624
- // GET /api/metrics/utilization - Agent utilization metrics
625
- app.get("/api/metrics/utilization", (_req: Request, res: Response) => {
626
- const allAgents = eventStore.listAgents();
627
- const active = allAgents.filter(
628
- (a) => a.state === "running" || a.state === "spawning"
629
- );
630
- const byRole: Record<string, number> = {};
631
- const byState: Record<string, number> = {};
632
- for (const a of active) {
633
- const role = a.role ?? "unknown";
634
- byRole[role] = (byRole[role] ?? 0) + 1;
635
- }
636
- for (const a of allAgents) {
637
- byState[a.state] = (byState[a.state] ?? 0) + 1;
245
+ res.json({ tasks });
246
+ } catch (err: any) {
247
+ res.status(500).json({ error: err.message ?? "Internal server error" });
638
248
  }
639
-
640
- res.json({
641
- activeAgents: active.length,
642
- totalAgents: allAgents.length,
643
- agentsByRole: byRole,
644
- agentsByState: byState,
645
- });
646
249
  });
647
250
 
648
- // GET /api/metrics/errors - Error metrics
649
- app.get("/api/metrics/errors", (req: Request, res: Response) => {
650
- const windowMs = req.query.window_ms
651
- ? Number(req.query.window_ms)
652
- : 30 * 60 * 1000;
653
- const limit = req.query.limit ? Number(req.query.limit) : 20;
251
+ app.get("/api/tasks/ready", async (req: Request, res: Response) => {
252
+ try {
253
+ const limitStr = str(req.query.limit);
254
+ const tagsStr = str(req.query.tags);
654
255
 
655
- const statusEvents = eventStore.query({
656
- type: "status",
657
- after: Date.now() - windowMs,
658
- });
256
+ const opts: { limit?: number; tags?: string[] } = {};
257
+ if (limitStr) opts.limit = parseInt(limitStr, 10);
258
+ if (tagsStr) opts.tags = tagsStr.split(",");
659
259
 
660
- const errors: Array<{ timestamp: number; agentId: string; type: string; summary: string }> = [];
661
- const byType: Record<string, number> = {};
260
+ const tasks = await system.tasksAdapter.queryReady(opts);
662
261
 
663
- for (const e of statusEvents) {
664
- if (e.payload?.status_type !== "failed") continue;
665
- const agentId = (e.source as { agent_id?: string })?.agent_id ?? "unknown";
666
- const summary = (e.payload?.summary as string) ?? "Unknown error";
667
- const errorType = ((e.payload?.details as Record<string, unknown>)?.signal as string) ?? "agent_failed";
668
- errors.push({ timestamp: e.timestamp, agentId, type: errorType, summary });
669
- byType[errorType] = (byType[errorType] ?? 0) + 1;
262
+ res.json({ tasks });
263
+ } catch (err: any) {
264
+ res.status(500).json({ error: err.message ?? "Internal server error" });
670
265
  }
671
-
672
- errors.sort((a, b) => b.timestamp - a.timestamp);
673
-
674
- res.json({
675
- totalErrors: errors.length,
676
- errorsByType: byType,
677
- recentErrors: errors.slice(0, limit),
678
- });
679
266
  });
680
267
 
681
- // POST /api/conversation/message - Send message to head manager
682
- app.post("/api/conversation/message", async (req: Request, res: Response) => {
683
- // Reject new messages during shutdown
684
- if (state.isShuttingDown) {
685
- return sendError(res, 503, "SHUTTING_DOWN", "Server is shutting down");
686
- }
687
-
688
- const promptId = `prompt_${Date.now()}_${Math.random().toString(36).slice(2)}`;
268
+ // ── Metrics ────────────────────────────────────────────────────
689
269
 
270
+ app.get("/api/metrics", async (_req: Request, res: Response) => {
690
271
  try {
691
- if (!state.initialized || !state.headManagerId) {
692
- return sendError(res, 400, "NOT_INITIALIZED", "System not initialized");
693
- }
694
-
695
- const body = req.body as ConversationMessageRequest;
696
- if (!body.message) {
697
- return sendError(res, 400, "MISSING_MESSAGE", "Message is required");
698
- }
699
-
700
- // Add user message to history
701
- state.conversationHistory.push({
702
- role: "user",
703
- content: body.message,
704
- timestamp: Date.now(),
705
- });
706
-
707
- // Record user turn in session conversation
708
- if (services.mailService && services.conversationMap && state.headManagerId) {
709
- try {
710
- const sessionConvId = services.conversationMap.getSessionConversation(state.headManagerId);
711
- if (sessionConvId) {
712
- services.mailService.recordTurn({
713
- conversationId: sessionConvId,
714
- participant: "user",
715
- contentType: "text",
716
- content: body.message,
717
- });
718
- }
719
- } catch {
720
- // Never fail message handling due to mail errors
721
- }
722
- }
723
-
724
- // Broadcast to conversation channel
725
- broadcastToChannel("conversation", {
726
- type: "message",
727
- data: {
728
- role: "user",
729
- content: body.message,
730
- timestamp: Date.now(),
731
- },
732
- });
733
-
734
- // Track this prompt as in-flight
735
- let resolvePrompt: () => void;
736
- const promptPromise = new Promise<void>((resolve) => {
737
- resolvePrompt = resolve;
738
- });
739
- state.inFlightPrompts.set(promptId, promptPromise);
740
-
741
- // Send to head manager and collect response
742
- let responseContent = "";
272
+ // Try real metrics module first, fall back to placeholder
273
+ let snapshot: MetricsSnapshot;
743
274
  try {
744
- for await (const update of agentManager.prompt(state.headManagerId, body.message)) {
745
- if ("sessionUpdate" in update && update.sessionUpdate === "agent_message_chunk") {
746
- const chunk = update as { content: { type: string; text?: string } };
747
- if (chunk.content.type === "text" && chunk.content.text) {
748
- responseContent += chunk.content.text;
749
- }
750
- }
751
- }
752
- } finally {
753
- // Mark prompt as complete
754
- resolvePrompt!();
755
- state.inFlightPrompts.delete(promptId);
756
- }
757
-
758
- // Add assistant response to history
759
- state.conversationHistory.push({
760
- role: "assistant",
761
- content: responseContent,
762
- agent_id: state.headManagerId,
763
- timestamp: Date.now(),
764
- });
765
-
766
- // Record assistant turn in session conversation
767
- if (services.mailService && services.conversationMap && state.headManagerId) {
768
- try {
769
- const sessionConvId = services.conversationMap.getSessionConversation(state.headManagerId);
770
- if (sessionConvId) {
771
- services.mailService.recordTurn({
772
- conversationId: sessionConvId,
773
- participant: state.headManagerId,
774
- contentType: "text",
775
- content: responseContent,
776
- });
777
- }
778
- } catch {
779
- // Never fail message handling due to mail errors
780
- }
275
+ // Dynamic import module may not exist yet (built in parallel)
276
+ const metricsPath = "../metrics/metrics.js";
277
+ const metricsModule = await (import(metricsPath) as Promise<any>);
278
+ snapshot = await metricsModule.collectMetrics(system, startTime);
279
+ } catch {
280
+ snapshot = await collectMetricsPlaceholder(system, startTime);
781
281
  }
782
-
783
- // Broadcast response
784
- broadcastToChannel("conversation", {
785
- type: "message",
786
- data: {
787
- role: "assistant",
788
- content: responseContent,
789
- agent_id: state.headManagerId,
790
- timestamp: Date.now(),
791
- },
792
- });
793
-
794
- res.json({
795
- content: responseContent,
796
- agent_id: state.headManagerId,
797
- message_id: `msg_${Date.now()}`,
798
- });
799
- } catch (error) {
800
- // Ensure we clean up the in-flight prompt on error
801
- state.inFlightPrompts.delete(promptId);
802
- sendError(res, 500, "MESSAGE_FAILED", `Failed to process message: ${error}`);
282
+ res.json(snapshot);
283
+ } catch (err: any) {
284
+ res.status(500).json({ error: err.message ?? "Internal server error" });
803
285
  }
804
286
  });
805
287
 
806
- // GET /api/conversation/history - Get conversation history
807
- app.get("/api/conversation/history", (req: Request, res: Response) => {
808
- const limit = parseInt(req.query.limit as string) || 50;
809
- const offset = parseInt(req.query.offset as string) || 0;
810
-
811
- const history = state.conversationHistory.slice(offset, offset + limit);
812
-
813
- const response: ConversationHistoryResponse = {
814
- history,
815
- total: state.conversationHistory.length,
816
- };
817
-
818
- res.json(response);
819
- });
820
-
821
- // GET /api/agents - List agents
822
- app.get("/api/agents", (req: Request, res: Response) => {
823
- const params = req.query as unknown as AgentQueryParams;
824
- let agents = agentManager.list();
825
-
826
- // Apply filters
827
- if (params.state) {
828
- agents = agents.filter((a) => a.state === params.state);
829
- }
830
- if (params.parent !== undefined) {
831
- const parentValue = params.parent === "null" ? null : params.parent;
832
- agents = agents.filter((a) => a.parent === parentValue);
833
- }
834
-
835
- const total = agents.length;
836
-
837
- // Apply pagination
838
- const offset = params.offset ?? 0;
839
- const limit = params.limit ?? 50;
840
- agents = agents.slice(offset, offset + limit);
841
-
842
- const response: AgentListResponse = {
843
- agents: agents.map(agentToSummary),
844
- total,
845
- };
846
-
847
- res.json(response);
848
- });
288
+ app.get("/api/metrics/agents", (_req: Request, res: Response) => {
289
+ try {
290
+ const agents = system.agentStore.listAgents();
291
+ const running = agents.filter((a) => a.state === "running").length;
292
+ const stopped = agents.filter((a) => a.state === "stopped").length;
293
+ const failed = agents.filter((a) => a.state === "failed").length;
849
294
 
850
- // GET /api/agents/:id - Get agent details
851
- app.get("/api/agents/:id", (req: Request, res: Response) => {
852
- const id = req.params.id as string;
853
- const agent = agentManager.get(id);
854
- if (!agent) {
855
- return sendError(res, 404, "AGENT_NOT_FOUND", `Agent not found: ${id}`);
295
+ res.json({
296
+ total: agents.length,
297
+ running,
298
+ stopped,
299
+ failed,
300
+ });
301
+ } catch (err: any) {
302
+ res.status(500).json({ error: err.message ?? "Internal server error" });
856
303
  }
857
- res.json(agentToDetail(agent));
858
304
  });
859
305
 
860
- // GET /api/agents/:id/hierarchy - Get agent hierarchy
861
- app.get("/api/agents/:id/hierarchy", (req: Request, res: Response) => {
862
- const id = req.params.id as string;
863
- const agent = agentManager.get(id);
864
- if (!agent) {
865
- return sendError(res, 404, "AGENT_NOT_FOUND", `Agent not found: ${id}`);
866
- }
867
-
868
- const hierarchy = agentManager.getHierarchy(id);
869
- if (!hierarchy) {
870
- return sendError(res, 500, "HIERARCHY_ERROR", "Failed to build hierarchy");
306
+ app.get("/api/metrics/tasks", async (_req: Request, res: Response) => {
307
+ try {
308
+ const tasks = await system.tasksAdapter.listTasks();
309
+ res.json({
310
+ total: tasks.length,
311
+ open: tasks.filter((t) => t.status === "open").length,
312
+ in_progress: tasks.filter((t) => t.status === "in_progress").length,
313
+ closed: tasks.filter((t) => t.status === "closed").length,
314
+ });
315
+ } catch (err: any) {
316
+ res.status(500).json({ error: err.message ?? "Internal server error" });
871
317
  }
872
-
873
- const response: HierarchyResponse = {
874
- tree: buildHierarchyNode(agent),
875
- depth: hierarchy.depth,
876
- total_agents: hierarchy.totalAgents,
877
- };
878
-
879
- res.json(response);
880
318
  });
881
319
 
882
- // GET /api/tasks - List tasks
883
- app.get("/api/tasks", (req: Request, res: Response) => {
884
- const params = req.query as unknown as TaskQueryParams;
885
- let tasks = taskManager.list();
320
+ // ── Teams ──────────────────────────────────────────────────────
886
321
 
887
- // Apply filters
888
- if (params.status) {
889
- tasks = tasks.filter((t) => t.status === params.status);
890
- }
891
- if (params.assigned_agent) {
892
- tasks = tasks.filter((t) => t.assigned_agent === params.assigned_agent);
893
- }
894
-
895
- const total = tasks.length;
896
-
897
- // Apply pagination
898
- const offset = params.offset ?? 0;
899
- const limit = params.limit ?? 50;
900
- tasks = tasks.slice(offset, offset + limit);
901
-
902
- const response: TaskListResponse = {
903
- tasks: tasks.map(taskToSummary),
904
- total,
905
- };
322
+ app.get("/api/teams", (_req: Request, res: Response) => {
323
+ try {
324
+ const agents = system.agentStore.listAgents();
325
+ const teamMap = new Map<
326
+ string,
327
+ { name: string; agentCount: number; roles: Set<string> }
328
+ >();
329
+
330
+ for (const agent of agents) {
331
+ const teamName = agent.team ?? "default";
332
+ let entry = teamMap.get(teamName);
333
+ if (!entry) {
334
+ entry = { name: teamName, agentCount: 0, roles: new Set() };
335
+ teamMap.set(teamName, entry);
336
+ }
337
+ entry.agentCount++;
338
+ entry.roles.add(agent.role);
339
+ }
906
340
 
907
- res.json(response);
908
- });
341
+ const teams = Array.from(teamMap.values()).map((t) => ({
342
+ name: t.name,
343
+ agentCount: t.agentCount,
344
+ roles: Array.from(t.roles),
345
+ }));
909
346
 
910
- // GET /api/tasks/:id - Get task details
911
- app.get("/api/tasks/:id", (req: Request, res: Response) => {
912
- const id = req.params.id as string;
913
- const task = taskManager.get(id);
914
- if (!task) {
915
- return sendError(res, 404, "TASK_NOT_FOUND", `Task not found: ${id}`);
347
+ res.json({ teams });
348
+ } catch (err: any) {
349
+ res.status(500).json({ error: err.message ?? "Internal server error" });
916
350
  }
917
- res.json(taskToDetail(task));
918
- });
919
-
920
- // GET /api/events - List events with filters
921
- app.get("/api/events", (req: Request, res: Response) => {
922
- const params = req.query as unknown as EventQueryParams;
923
-
924
- const events = eventStore.query({
925
- type: params.type as any,
926
- source_agent_id: params.source_agent_id,
927
- target_agent_id: params.target_agent_id,
928
- after: params.after,
929
- before: params.before,
930
- limit: (params.limit ?? 50) + 1, // Get one extra to check has_more
931
- });
932
-
933
- const limit = params.limit ?? 50;
934
- const hasMore = events.length > limit;
935
- const resultEvents = hasMore ? events.slice(0, limit) : events;
936
-
937
- const response: EventListResponse = {
938
- events: resultEvents.map(eventToSummary),
939
- total: resultEvents.length,
940
- has_more: hasMore,
941
- };
942
-
943
- res.json(response);
944
351
  });
945
352
 
946
- // POST /api/agents/:id/inject - Inject context into agent session
947
- app.post("/api/agents/:id/inject", async (req: Request, res: Response) => {
948
- const id = req.params.id as AgentId;
949
- const body = req.body as InjectContextRequest;
353
+ // ── Server Lifecycle ───────────────────────────────────────────
950
354
 
951
- // Validate content
952
- if (!body.content) {
953
- return sendError(res, 400, "MISSING_CONTENT", "Content is required");
954
- }
355
+ let server: Server | null = null;
955
356
 
956
- // Check agent exists
957
- const agent = agentManager.get(id);
958
- if (!agent) {
959
- return sendError(res, 404, "AGENT_NOT_FOUND", `Agent not found: ${id}`);
960
- }
357
+ return {
358
+ app,
961
359
 
962
- // Create injection deps
963
- const injectionDeps: InjectionDeps = {
964
- getSession(agentId: AgentId) {
965
- const session = agentManager.getSession(agentId);
966
- if (!session) return null;
967
- return {
968
- inject: async (content: string) => session.inject(content),
969
- supportsInject: () => session.supportsInject(),
970
- checkInjectSupport: async () => session.supportsInject(),
971
- interruptWith: (content: string) => session.interruptWith(content),
972
- };
973
- },
974
- isPrompting(agentId: AgentId) {
975
- return agentManager.isPrompting(agentId);
976
- },
977
- async sendMessage(
978
- _fromAgentId: AgentId | undefined,
979
- toAgentId: AgentId,
980
- content: string,
981
- priority: "high"
982
- ) {
983
- await services.messageRouter.sendToAddress({
984
- from: "__human__" as AgentId,
985
- to: { agent: toAgentId },
986
- content,
987
- options: { priority },
360
+ async start(): Promise<void> {
361
+ return new Promise((resolve) => {
362
+ server = app.listen(port, host, () => {
363
+ console.log(`[api] Listening on ${host}:${port}`);
364
+ resolve();
988
365
  });
989
- },
990
- };
991
-
992
- try {
993
- const result = await injectContext(injectionDeps, id, body.content, {
994
- urgent: body.urgent,
995
- allowInterrupt: true,
996
- source: { type: "human" },
997
- reason: body.reason,
998
366
  });
367
+ },
999
368
 
1000
- const response: InjectContextResponse = {
1001
- success: result.success,
1002
- method: result.method,
1003
- error: result.error,
1004
- note: result.note,
1005
- };
1006
-
1007
- if (result.success) {
1008
- res.json(response);
1009
- } else {
1010
- res.status(500).json(response);
1011
- }
1012
- } catch (error) {
1013
- sendError(res, 500, "INJECTION_FAILED", `Failed to inject context: ${error}`);
1014
- }
1015
- });
1016
-
1017
- // Register conversation API routes (if mail service available)
1018
- registerConversationRoutes(app, services, sendError);
1019
-
1020
- // ─────────────────────────────────────────────────────────────────
1021
- // HTTP Server
1022
- // ─────────────────────────────────────────────────────────────────
1023
-
1024
- const server = http.createServer(app);
1025
-
1026
- // ─────────────────────────────────────────────────────────────────
1027
- // WebSocket Server
1028
- // ─────────────────────────────────────────────────────────────────
1029
-
1030
- const wss = new WebSocketServer({ server });
1031
-
1032
- wss.on("connection", (ws: WebSocket) => {
1033
- const client: WSClient = {
1034
- ws,
1035
- subscriptions: new Set(),
1036
- };
1037
- wsClients.add(client);
1038
-
1039
- ws.on("message", (data: Buffer) => {
1040
- try {
1041
- const message = JSON.parse(data.toString()) as { type: string; channel?: string };
1042
-
1043
- if (message.type === "subscribe" && message.channel) {
1044
- client.subscriptions.add(message.channel);
1045
- ws.send(JSON.stringify({ type: "subscribed", channel: message.channel }));
1046
- } else if (message.type === "unsubscribe" && message.channel) {
1047
- client.subscriptions.delete(message.channel);
1048
- ws.send(JSON.stringify({ type: "unsubscribed", channel: message.channel }));
1049
- }
1050
- } catch {
1051
- ws.send(JSON.stringify({ type: "error", error: "Invalid message format" }));
1052
- }
1053
- });
1054
-
1055
- ws.on("close", () => {
1056
- wsClients.delete(client);
1057
- });
1058
- });
1059
-
1060
- // ─────────────────────────────────────────────────────────────────
1061
- // Event Store Listeners for Real-time Updates
1062
- // ─────────────────────────────────────────────────────────────────
1063
-
1064
- // Listen for agent changes
1065
- eventStore.onAgentChange((agentId, agent) => {
1066
- if (!agent) return;
1067
-
1068
- const update: WSAgentUpdate = {
1069
- type: "agent_update",
1070
- action: agent.state === "stopped" ? "stopped" : "started",
1071
- agent: agentToSummary(agent),
1072
- };
1073
-
1074
- broadcastToChannel("agents", update);
1075
- });
1076
-
1077
- // Listen for task changes
1078
- eventStore.onTaskChange((taskId, task) => {
1079
- if (!task) return;
1080
-
1081
- const update: WSTaskUpdate = {
1082
- type: "task_update",
1083
- action: task.status === "completed" ? "completed" : "status_change",
1084
- task: taskToSummary(task),
1085
- };
1086
-
1087
- broadcastToChannel("tasks", update);
1088
- });
1089
-
1090
- // Listen for conversation changes (if available)
1091
- if (eventStore.onConversationChange) {
1092
- eventStore.onConversationChange((conversationId, conversation) => {
1093
- if (!conversation) return;
1094
-
1095
- const update: WSConversationUpdate = {
1096
- type: "conversation_update",
1097
- conversation: conversationToSummary(conversation),
1098
- };
1099
-
1100
- broadcastToChannel("conversations", update);
1101
- broadcastToChannel(`conversation:${conversationId}`, update);
1102
- });
1103
- }
1104
-
1105
- // Listen for turn changes (if available)
1106
- if (eventStore.onTurnChange) {
1107
- eventStore.onTurnChange((conversationId, turn) => {
1108
- const update: WSTurnAdded = {
1109
- type: "turn_added",
1110
- conversation_id: conversationId,
1111
- turn: turnToSummary(turn),
1112
- };
1113
-
1114
- broadcastToChannel(`conversation:${conversationId}`, update);
1115
- });
1116
- }
1117
-
1118
- // ─────────────────────────────────────────────────────────────────
1119
- // Server Lifecycle
1120
- // ─────────────────────────────────────────────────────────────────
1121
-
1122
- function getStatus(): SystemStatus {
1123
- const agents = agentManager.list();
1124
- const tasks = taskManager.list();
1125
-
1126
- return {
1127
- initialized: state.initialized,
1128
- head_manager_id: state.headManagerId,
1129
- agents: {
1130
- total: agents.length,
1131
- running: agents.filter((a) => a.state === "running").length,
1132
- stopped: agents.filter((a) => a.state === "stopped").length,
1133
- },
1134
- tasks: {
1135
- total: tasks.length,
1136
- pending: tasks.filter((t) => t.status === "pending").length,
1137
- in_progress: tasks.filter((t) => t.status === "in_progress").length,
1138
- completed: tasks.filter((t) => t.status === "completed").length,
1139
- failed: tasks.filter((t) => t.status === "failed").length,
1140
- },
1141
- uptime: state.startedAt ? Date.now() - state.startedAt : 0,
1142
- started_at: state.startedAt,
1143
- };
1144
- }
1145
-
1146
- async function start(): Promise<void> {
1147
- return new Promise((resolve) => {
1148
- server.listen(port, host, () => {
1149
- resolve();
1150
- });
1151
- });
1152
- }
1153
-
1154
- /**
1155
- * Helper function to create a delay promise
1156
- */
1157
- function sleep(ms: number): Promise<void> {
1158
- return new Promise((resolve) => setTimeout(resolve, ms));
1159
- }
1160
-
1161
- /**
1162
- * Get all in-flight prompt promises
1163
- */
1164
- function getInFlightPrompts(): Promise<void>[] {
1165
- return Array.from(state.inFlightPrompts.values());
1166
- }
1167
-
1168
- async function stop(options?: StopOptions): Promise<void> {
1169
- // Prevent concurrent shutdown calls
1170
- if (state.isShuttingDown) {
1171
- return;
1172
- }
1173
- state.isShuttingDown = true;
1174
-
1175
- const gracePeriod = options?.force ? 0 : shutdownGracePeriodMs;
1176
-
1177
- // 1. Stop accepting new connections
1178
- server.close();
1179
-
1180
- // 2. Wait grace period for in-flight work
1181
- if (gracePeriod > 0) {
1182
- const inFlight = getInFlightPrompts();
1183
- if (inFlight.length > 0) {
1184
- await Promise.race([
1185
- Promise.all(inFlight),
1186
- sleep(gracePeriod),
1187
- ]);
1188
- }
1189
- }
1190
-
1191
- // 3. Close WebSocket connections with 1001 "going away"
1192
- for (const client of wsClients) {
1193
- if (client.ws.readyState === WebSocket.OPEN) {
1194
- client.ws.close(1001, "Server shutting down");
1195
- }
1196
- }
1197
- wsClients.clear();
1198
-
1199
- // 4. Terminate running agents
1200
- await agentManager.close();
1201
-
1202
- // 5-6. Persist and close event store
1203
- await eventStore.persist();
1204
- await eventStore.close();
1205
- }
1206
-
1207
- /**
1208
- * Register signal handlers for graceful shutdown.
1209
- * Should be called after server.start() in production.
1210
- */
1211
- function registerSignalHandlers(): void {
1212
- let shutdownInProgress = false;
1213
-
1214
- const handleSignal = async (signal: string) => {
1215
- if (shutdownInProgress) {
1216
- // Force exit on second signal
1217
- process.exit(1);
1218
- }
1219
- shutdownInProgress = true;
1220
-
1221
- console.log(`\nReceived ${signal}, shutting down gracefully...`);
1222
-
1223
- try {
1224
- await stop();
1225
- console.log("Server shutdown complete.");
1226
- process.exit(0);
1227
- } catch (error) {
1228
- console.error("Error during shutdown:", error);
1229
- process.exit(1);
1230
- }
1231
- };
1232
-
1233
- process.on("SIGINT", () => handleSignal("SIGINT"));
1234
- process.on("SIGTERM", () => handleSignal("SIGTERM"));
1235
- }
1236
-
1237
- return {
1238
- app,
1239
- server,
1240
- wss,
1241
- start,
1242
- stop,
1243
- getStatus,
1244
- registerSignalHandlers,
1245
- };
1246
- }
1247
-
1248
- // ─────────────────────────────────────────────────────────────────
1249
- // Shared Server Mode (createAPIApp + setupAPIWebSocket)
1250
- // ─────────────────────────────────────────────────────────────────
1251
-
1252
- /**
1253
- * Create Express app with API routes for use with an external HTTP server.
1254
- *
1255
- * Use this when you want to share an HTTP server with other services.
1256
- *
1257
- * @param services - Shared services (EventStore, AgentManager, etc.)
1258
- * @param config - Configuration options
1259
- * @returns Express app
1260
- */
1261
- export function createAPIApp(
1262
- services: Pick<APIServices, "eventStore" | "agentManager" | "taskManager" | "messageRouter"> & Pick<Partial<APIServices>, "mailService" | "conversationMap">,
1263
- config: { cors?: boolean; serverToken?: string } = {}
1264
- ): Express {
1265
- const { cors = true, serverToken } = config;
1266
- const { agentManager, taskManager, messageRouter } = services;
1267
-
1268
- // Create shared state
1269
- const state = createAPISharedState();
1270
-
1271
- // Create Express app
1272
- const app = express();
1273
-
1274
- // Store state on app for access by setupAPIWebSocket
1275
- (app as any).__apiState = state;
1276
- (app as any).__apiServices = services;
1277
-
1278
- // Middleware
1279
- app.use(express.json());
1280
-
1281
- if (cors) {
1282
- app.use((_req: Request, res: Response, next: NextFunction) => {
1283
- res.header("Access-Control-Allow-Origin", "*");
1284
- res.header("Access-Control-Allow-Headers", "Content-Type, Authorization");
1285
- res.header("Access-Control-Allow-Methods", "GET, POST, DELETE");
1286
- next();
1287
- });
1288
- }
1289
-
1290
- // Bearer token auth middleware (skip /health)
1291
- if (serverToken) {
1292
- app.use((req: Request, res: Response, next: NextFunction) => {
1293
- if (req.path === "/health") return next();
1294
- const authHeader = req.headers.authorization;
1295
- const token = authHeader?.startsWith("Bearer ") ? authHeader.slice(7) : undefined;
1296
- if (!token || !secureCompare(token, serverToken)) {
1297
- const error: APIError = { error: "Unauthorized", code: "AUTH_REQUIRED" };
1298
- res.status(401).json(error);
1299
- return;
1300
- }
1301
- next();
1302
- });
1303
- }
1304
-
1305
- // ─────────────────────────────────────────────────────────────────
1306
- // Helper Functions
1307
- // ─────────────────────────────────────────────────────────────────
1308
-
1309
- function agentToSummary(agent: Agent): AgentSummary {
1310
- return {
1311
- id: agent.id,
1312
- session_id: agent.session_id,
1313
- task: agent.task ?? "No task",
1314
- state: agent.state,
1315
- parent: agent.parent,
1316
- children_count: agentManager.getChildren(agent.id).length,
1317
- created_at: agent.created_at,
1318
- };
1319
- }
1320
-
1321
- function agentToDetail(agent: Agent): AgentDetail {
1322
- return {
1323
- ...agentToSummary(agent),
1324
- lineage: agent.lineage,
1325
- task_id: agent.task_id,
1326
- config: agent.config as Record<string, unknown>,
1327
- started_at: agent.started_at,
1328
- stopped_at: agent.stopped_at,
1329
- stop_reason: agent.stop_reason,
1330
- };
1331
- }
1332
-
1333
- function taskToSummary(task: Task): TaskSummary {
1334
- return {
1335
- id: task.id,
1336
- description: task.description,
1337
- status: task.status,
1338
- assigned_agent: task.assigned_agent,
1339
- created_at: task.created_at,
1340
- };
1341
- }
1342
-
1343
- function taskToDetail(task: Task): TaskDetail {
1344
- return {
1345
- ...taskToSummary(task),
1346
- parent_task: task.parent_task,
1347
- subtasks: task.subtasks ?? [],
1348
- created_by: task.created_by,
1349
- inputs: task.inputs,
1350
- outputs: task.outputs,
1351
- artifacts: task.artifacts,
1352
- started_at: task.started_at,
1353
- completed_at: task.completed_at,
1354
- };
1355
- }
1356
-
1357
- function eventToSummary(event: Event): EventSummary {
1358
- let summary = "";
1359
- switch (event.type) {
1360
- case "spawn":
1361
- summary = `Agent ${event.payload.agent_id} spawned`;
1362
- break;
1363
- case "stop":
1364
- summary = `Agent terminated: ${event.payload.reason}`;
1365
- break;
1366
- case "status":
1367
- summary = `${event.payload.status_type}: ${event.payload.summary}`;
1368
- break;
1369
- case "message":
1370
- summary = `Message: ${String(event.payload.content).substring(0, 50)}...`;
1371
- break;
1372
- case "task":
1373
- summary = `Task ${event.payload.action}: ${event.payload.task_id}`;
1374
- break;
1375
- default:
1376
- summary = `${event.type} event`;
1377
- }
1378
-
1379
- return {
1380
- id: event.id,
1381
- type: event.type,
1382
- timestamp: event.timestamp,
1383
- source_agent_id: event.source.agent_id,
1384
- target_agent_id: event.target?.agent_id,
1385
- summary,
1386
- };
1387
- }
1388
-
1389
- function buildHierarchyNode(agent: Agent): HierarchyNode {
1390
- const children = agentManager.getChildren(agent.id);
1391
- return {
1392
- agent_id: agent.id,
1393
- task: agent.task ?? "No task",
1394
- state: agent.state,
1395
- children: children.map(buildHierarchyNode),
1396
- };
1397
- }
1398
-
1399
- function sendError(res: Response, status: number, code: string, message: string): void {
1400
- const error: APIError = { error: message, code };
1401
- res.status(status).json(error);
1402
- }
1403
-
1404
- // ─────────────────────────────────────────────────────────────────
1405
- // API Routes
1406
- // ─────────────────────────────────────────────────────────────────
1407
-
1408
- // POST /api/init - Initialize the system
1409
- app.post("/api/init", async (req: Request, res: Response) => {
1410
- try {
1411
- if (state.initialized) {
1412
- return sendError(res, 400, "ALREADY_INITIALIZED", "System already initialized");
1413
- }
1414
-
1415
- const body = req.body as InitRequest;
1416
- const cwd = body.cwd ?? process.cwd();
1417
-
1418
- const headManager = await agentManager.getOrCreateHeadManager({
1419
- cwd,
1420
- systemPrompt: body.system_prompt,
1421
- permissionMode: body.permission_mode,
1422
- });
1423
-
1424
- state.initialized = true;
1425
- state.headManagerId = headManager.id;
1426
- state.startedAt = Date.now();
1427
-
1428
- // Create session conversation for mail tracking
1429
- if (services.mailService && services.conversationMap) {
1430
- try {
1431
- const { conversationId } = services.mailService.createConversation({
1432
- type: "session",
1433
- subject: "User session",
1434
- createdBy: "user",
1435
- });
1436
- services.mailService.joinConversation({
1437
- conversationId,
1438
- participantId: headManager.id,
1439
- role: "worker",
369
+ async stop(): Promise<void> {
370
+ if (server) {
371
+ return new Promise((resolve) => {
372
+ server!.close(() => {
373
+ server = null;
374
+ resolve();
1440
375
  });
1441
- services.conversationMap.setSessionConversation(headManager.id, conversationId);
1442
- } catch {
1443
- // Never fail init due to mail errors
1444
- }
1445
- }
1446
-
1447
- const response: InitResponse = {
1448
- success: true,
1449
- head_manager_id: headManager.id,
1450
- session_id: headManager.session_id,
1451
- };
1452
-
1453
- res.json(response);
1454
- } catch (error) {
1455
- sendError(res, 500, "INIT_FAILED", `Failed to initialize: ${error}`);
1456
- }
1457
- });
1458
-
1459
- // GET /api/status - Get system status
1460
- app.get("/api/status", (_req: Request, res: Response) => {
1461
- const agents = agentManager.list();
1462
- const tasks = taskManager.list();
1463
-
1464
- const status: SystemStatus = {
1465
- initialized: state.initialized,
1466
- head_manager_id: state.headManagerId,
1467
- agents: {
1468
- total: agents.length,
1469
- running: agents.filter((a) => a.state === "running").length,
1470
- stopped: agents.filter((a) => a.state === "stopped").length,
1471
- },
1472
- tasks: {
1473
- total: tasks.length,
1474
- pending: tasks.filter((t) => t.status === "pending").length,
1475
- in_progress: tasks.filter((t) => t.status === "in_progress").length,
1476
- completed: tasks.filter((t) => t.status === "completed").length,
1477
- failed: tasks.filter((t) => t.status === "failed").length,
1478
- },
1479
- uptime: state.startedAt ? Date.now() - state.startedAt : 0,
1480
- started_at: state.startedAt,
1481
- };
1482
-
1483
- res.json(status);
1484
- });
1485
-
1486
- // POST /api/conversation/message - Send message to head manager
1487
- app.post("/api/conversation/message", async (req: Request, res: Response) => {
1488
- // Reject new messages during shutdown
1489
- if (state.isShuttingDown) {
1490
- return sendError(res, 503, "SHUTTING_DOWN", "Server is shutting down");
1491
- }
1492
-
1493
- const promptId = `prompt_${Date.now()}_${Math.random().toString(36).slice(2)}`;
1494
-
1495
- try {
1496
- if (!state.initialized || !state.headManagerId) {
1497
- return sendError(res, 400, "NOT_INITIALIZED", "System not initialized");
1498
- }
1499
-
1500
- const body = req.body as ConversationMessageRequest;
1501
- if (!body.message) {
1502
- return sendError(res, 400, "MISSING_MESSAGE", "Message is required");
1503
- }
1504
-
1505
- // Add user message to history
1506
- state.conversationHistory.push({
1507
- role: "user",
1508
- content: body.message,
1509
- timestamp: Date.now(),
1510
- });
1511
-
1512
- // Record user turn in session conversation
1513
- if (services.mailService && services.conversationMap && state.headManagerId) {
1514
- try {
1515
- const sessionConvId = services.conversationMap.getSessionConversation(state.headManagerId);
1516
- if (sessionConvId) {
1517
- services.mailService.recordTurn({
1518
- conversationId: sessionConvId,
1519
- participant: "user",
1520
- contentType: "text",
1521
- content: body.message,
1522
- });
1523
- }
1524
- } catch {
1525
- // Never fail message handling due to mail errors
1526
- }
1527
- }
1528
-
1529
- // Broadcast to conversation channel
1530
- state.broadcast("conversation", {
1531
- type: "message",
1532
- data: {
1533
- role: "user",
1534
- content: body.message,
1535
- timestamp: Date.now(),
1536
- },
1537
- });
1538
-
1539
- // Track this prompt as in-flight
1540
- let resolvePrompt: () => void;
1541
- const promptPromise = new Promise<void>((resolve) => {
1542
- resolvePrompt = resolve;
1543
- });
1544
- state.inFlightPrompts.set(promptId, promptPromise);
1545
-
1546
- // Send to head manager and collect response
1547
- let responseContent = "";
1548
- try {
1549
- for await (const update of agentManager.prompt(state.headManagerId, body.message)) {
1550
- if ("sessionUpdate" in update && update.sessionUpdate === "agent_message_chunk") {
1551
- const chunk = update as { content: { type: string; text?: string } };
1552
- if (chunk.content.type === "text" && chunk.content.text) {
1553
- responseContent += chunk.content.text;
1554
- }
1555
- }
1556
- }
1557
- } finally {
1558
- // Mark prompt as complete
1559
- resolvePrompt!();
1560
- state.inFlightPrompts.delete(promptId);
1561
- }
1562
-
1563
- // Add assistant response to history
1564
- state.conversationHistory.push({
1565
- role: "assistant",
1566
- content: responseContent,
1567
- agent_id: state.headManagerId,
1568
- timestamp: Date.now(),
1569
- });
1570
-
1571
- // Record assistant turn in session conversation
1572
- if (services.mailService && services.conversationMap && state.headManagerId) {
1573
- try {
1574
- const sessionConvId = services.conversationMap.getSessionConversation(state.headManagerId);
1575
- if (sessionConvId) {
1576
- services.mailService.recordTurn({
1577
- conversationId: sessionConvId,
1578
- participant: state.headManagerId,
1579
- contentType: "text",
1580
- content: responseContent,
1581
- });
1582
- }
1583
- } catch {
1584
- // Never fail message handling due to mail errors
1585
- }
1586
- }
1587
-
1588
- // Broadcast response
1589
- state.broadcast("conversation", {
1590
- type: "message",
1591
- data: {
1592
- role: "assistant",
1593
- content: responseContent,
1594
- agent_id: state.headManagerId,
1595
- timestamp: Date.now(),
1596
- },
1597
- });
1598
-
1599
- res.json({
1600
- content: responseContent,
1601
- agent_id: state.headManagerId,
1602
- message_id: `msg_${Date.now()}`,
1603
- });
1604
- } catch (error) {
1605
- // Ensure we clean up the in-flight prompt on error
1606
- state.inFlightPrompts.delete(promptId);
1607
- sendError(res, 500, "MESSAGE_FAILED", `Failed to process message: ${error}`);
1608
- }
1609
- });
1610
-
1611
- // GET /api/conversation/history - Get conversation history
1612
- app.get("/api/conversation/history", (req: Request, res: Response) => {
1613
- const limit = parseInt(req.query.limit as string) || 50;
1614
- const offset = parseInt(req.query.offset as string) || 0;
1615
-
1616
- const history = state.conversationHistory.slice(offset, offset + limit);
1617
-
1618
- const response: ConversationHistoryResponse = {
1619
- history,
1620
- total: state.conversationHistory.length,
1621
- };
1622
-
1623
- res.json(response);
1624
- });
1625
-
1626
- // GET /api/agents - List agents
1627
- app.get("/api/agents", (req: Request, res: Response) => {
1628
- const params = req.query as unknown as AgentQueryParams;
1629
- let agents = agentManager.list();
1630
-
1631
- // Apply filters
1632
- if (params.state) {
1633
- agents = agents.filter((a) => a.state === params.state);
1634
- }
1635
- if (params.parent !== undefined) {
1636
- const parentValue = params.parent === "null" ? null : params.parent;
1637
- agents = agents.filter((a) => a.parent === parentValue);
1638
- }
1639
-
1640
- const total = agents.length;
1641
-
1642
- // Apply pagination
1643
- const offset = params.offset ?? 0;
1644
- const limit = params.limit ?? 50;
1645
- agents = agents.slice(offset, offset + limit);
1646
-
1647
- const response: AgentListResponse = {
1648
- agents: agents.map(agentToSummary),
1649
- total,
1650
- };
1651
-
1652
- res.json(response);
1653
- });
1654
-
1655
- // GET /api/agents/:id - Get agent details
1656
- app.get("/api/agents/:id", (req: Request, res: Response) => {
1657
- const id = req.params.id as string;
1658
- const agent = agentManager.get(id);
1659
- if (!agent) {
1660
- return sendError(res, 404, "AGENT_NOT_FOUND", `Agent not found: ${id}`);
1661
- }
1662
- res.json(agentToDetail(agent));
1663
- });
1664
-
1665
- // GET /api/agents/:id/hierarchy - Get agent hierarchy
1666
- app.get("/api/agents/:id/hierarchy", (req: Request, res: Response) => {
1667
- const id = req.params.id as string;
1668
- const agent = agentManager.get(id);
1669
- if (!agent) {
1670
- return sendError(res, 404, "AGENT_NOT_FOUND", `Agent not found: ${id}`);
1671
- }
1672
-
1673
- const hierarchy = agentManager.getHierarchy(id);
1674
- if (!hierarchy) {
1675
- return sendError(res, 500, "HIERARCHY_ERROR", "Failed to build hierarchy");
1676
- }
1677
-
1678
- const response: HierarchyResponse = {
1679
- tree: buildHierarchyNode(agent),
1680
- depth: hierarchy.depth,
1681
- total_agents: hierarchy.totalAgents,
1682
- };
1683
-
1684
- res.json(response);
1685
- });
1686
-
1687
- // GET /api/tasks - List tasks
1688
- app.get("/api/tasks", (req: Request, res: Response) => {
1689
- const params = req.query as unknown as TaskQueryParams;
1690
- let tasks = taskManager.list();
1691
-
1692
- // Apply filters
1693
- if (params.status) {
1694
- tasks = tasks.filter((t) => t.status === params.status);
1695
- }
1696
- if (params.assigned_agent) {
1697
- tasks = tasks.filter((t) => t.assigned_agent === params.assigned_agent);
1698
- }
1699
-
1700
- const total = tasks.length;
1701
-
1702
- // Apply pagination
1703
- const offset = params.offset ?? 0;
1704
- const limit = params.limit ?? 50;
1705
- tasks = tasks.slice(offset, offset + limit);
1706
-
1707
- const response: TaskListResponse = {
1708
- tasks: tasks.map(taskToSummary),
1709
- total,
1710
- };
1711
-
1712
- res.json(response);
1713
- });
1714
-
1715
- // GET /api/tasks/:id - Get task details
1716
- app.get("/api/tasks/:id", (req: Request, res: Response) => {
1717
- const id = req.params.id as string;
1718
- const task = taskManager.get(id);
1719
- if (!task) {
1720
- return sendError(res, 404, "TASK_NOT_FOUND", `Task not found: ${id}`);
1721
- }
1722
- res.json(taskToDetail(task));
1723
- });
1724
-
1725
- // GET /api/events - List events with filters
1726
- app.get("/api/events", (req: Request, res: Response) => {
1727
- const params = req.query as unknown as EventQueryParams;
1728
- const { eventStore } = services;
1729
-
1730
- const events = eventStore.query({
1731
- type: params.type as any,
1732
- source_agent_id: params.source_agent_id,
1733
- target_agent_id: params.target_agent_id,
1734
- after: params.after,
1735
- before: params.before,
1736
- limit: (params.limit ?? 50) + 1, // Get one extra to check has_more
1737
- });
1738
-
1739
- const limit = params.limit ?? 50;
1740
- const hasMore = events.length > limit;
1741
- const resultEvents = hasMore ? events.slice(0, limit) : events;
1742
-
1743
- const response: EventListResponse = {
1744
- events: resultEvents.map(eventToSummary),
1745
- total: resultEvents.length,
1746
- has_more: hasMore,
1747
- };
1748
-
1749
- res.json(response);
1750
- });
1751
-
1752
- // POST /api/agents/:id/inject - Inject context into agent session
1753
- app.post("/api/agents/:id/inject", async (req: Request, res: Response) => {
1754
- const id = req.params.id as AgentId;
1755
- const body = req.body as InjectContextRequest;
1756
-
1757
- // Validate content
1758
- if (!body.content) {
1759
- return sendError(res, 400, "MISSING_CONTENT", "Content is required");
1760
- }
1761
-
1762
- // Check agent exists
1763
- const agent = agentManager.get(id);
1764
- if (!agent) {
1765
- return sendError(res, 404, "AGENT_NOT_FOUND", `Agent not found: ${id}`);
1766
- }
1767
-
1768
- // Create injection deps
1769
- const injectionDeps: InjectionDeps = {
1770
- getSession(agentId: AgentId) {
1771
- const session = agentManager.getSession(agentId);
1772
- if (!session) return null;
1773
- return {
1774
- inject: async (content: string) => session.inject(content),
1775
- supportsInject: () => session.supportsInject(),
1776
- checkInjectSupport: async () => session.supportsInject(),
1777
- interruptWith: (content: string) => session.interruptWith(content),
1778
- };
1779
- },
1780
- isPrompting(agentId: AgentId) {
1781
- return agentManager.isPrompting(agentId);
1782
- },
1783
- async sendMessage(
1784
- _fromAgentId: AgentId | undefined,
1785
- toAgentId: AgentId,
1786
- content: string,
1787
- priority: "high"
1788
- ) {
1789
- await messageRouter.sendToAddress({
1790
- from: "__human__" as AgentId,
1791
- to: { agent: toAgentId },
1792
- content,
1793
- options: { priority },
1794
376
  });
1795
- },
1796
- };
1797
-
1798
- try {
1799
- const result = await injectContext(injectionDeps, id, body.content, {
1800
- urgent: body.urgent,
1801
- allowInterrupt: true,
1802
- source: { type: "human" },
1803
- reason: body.reason,
1804
- });
1805
-
1806
- const response: InjectContextResponse = {
1807
- success: result.success,
1808
- method: result.method,
1809
- error: result.error,
1810
- note: result.note,
1811
- };
1812
-
1813
- if (result.success) {
1814
- res.json(response);
1815
- } else {
1816
- res.status(500).json(response);
1817
- }
1818
- } catch (error) {
1819
- sendError(res, 500, "INJECTION_FAILED", `Failed to inject context: ${error}`);
1820
- }
1821
- });
1822
-
1823
- // Register conversation API routes (if mail service available)
1824
- registerConversationRoutes(app, services, sendError);
1825
-
1826
- return app;
1827
- }
1828
-
1829
- /**
1830
- * Set up API WebSocket handling on an existing WebSocketServer.
1831
- *
1832
- * Use this when you want to share an HTTP server with other services.
1833
- * The WebSocketServer should be created with `noServer: true`.
1834
- *
1835
- * @param wss - WebSocketServer instance (noServer mode)
1836
- * @param services - Shared services (EventStore, AgentManager, etc.)
1837
- * @returns Handler for managing connections
1838
- */
1839
- export function setupAPIWebSocket(
1840
- wss: WebSocketServer,
1841
- services: Pick<APIServices, "eventStore" | "agentManager" | "taskManager">,
1842
- app?: Express
1843
- ): APIWebSocketHandler {
1844
- const { eventStore, agentManager } = services;
1845
-
1846
- // Get shared state from app if provided, otherwise create new
1847
- const state: APISharedState = app && (app as any).__apiState
1848
- ? (app as any).__apiState
1849
- : createAPISharedState();
1850
-
1851
- const { wsClients, broadcast } = state;
1852
-
1853
- // Helper functions for event listeners
1854
- function agentToSummary(agent: Agent): AgentSummary {
1855
- return {
1856
- id: agent.id,
1857
- session_id: agent.session_id,
1858
- task: agent.task ?? "No task",
1859
- state: agent.state,
1860
- parent: agent.parent,
1861
- children_count: agentManager.getChildren(agent.id).length,
1862
- created_at: agent.created_at,
1863
- };
1864
- }
1865
-
1866
- function taskToSummary(task: Task): TaskSummary {
1867
- return {
1868
- id: task.id,
1869
- description: task.description,
1870
- status: task.status,
1871
- assigned_agent: task.assigned_agent,
1872
- created_at: task.created_at,
1873
- };
1874
- }
1875
-
1876
- // Handle WebSocket connections
1877
- wss.on("connection", (ws: WebSocket) => {
1878
- const client: WSClient = {
1879
- ws,
1880
- subscriptions: new Set(),
1881
- };
1882
- wsClients.add(client);
1883
-
1884
- ws.on("message", (data: Buffer) => {
1885
- try {
1886
- const message = JSON.parse(data.toString()) as { type: string; channel?: string };
1887
-
1888
- if (message.type === "subscribe" && message.channel) {
1889
- client.subscriptions.add(message.channel);
1890
- ws.send(JSON.stringify({ type: "subscribed", channel: message.channel }));
1891
- } else if (message.type === "unsubscribe" && message.channel) {
1892
- client.subscriptions.delete(message.channel);
1893
- ws.send(JSON.stringify({ type: "unsubscribed", channel: message.channel }));
1894
- }
1895
- } catch {
1896
- ws.send(JSON.stringify({ type: "error", error: "Invalid message format" }));
1897
- }
1898
- });
1899
-
1900
- ws.on("close", () => {
1901
- wsClients.delete(client);
1902
- });
1903
- });
1904
-
1905
- // Listen for agent changes
1906
- eventStore.onAgentChange((agentId, agent) => {
1907
- if (!agent) return;
1908
-
1909
- const update: WSAgentUpdate = {
1910
- type: "agent_update",
1911
- action: agent.state === "stopped" ? "stopped" : "started",
1912
- agent: agentToSummary(agent),
1913
- };
1914
-
1915
- broadcast("agents", update);
1916
- });
1917
-
1918
- // Listen for task changes
1919
- eventStore.onTaskChange((taskId, task) => {
1920
- if (!task) return;
1921
-
1922
- const update: WSTaskUpdate = {
1923
- type: "task_update",
1924
- action: task.status === "completed" ? "completed" : "status_change",
1925
- task: taskToSummary(task),
1926
- };
1927
-
1928
- broadcast("tasks", update);
1929
- });
1930
-
1931
- // Listen for conversation changes (if available)
1932
- if (eventStore.onConversationChange) {
1933
- eventStore.onConversationChange((conversationId, conversation) => {
1934
- if (!conversation) return;
1935
-
1936
- const update: WSConversationUpdate = {
1937
- type: "conversation_update",
1938
- conversation: conversationToSummary(conversation),
1939
- };
1940
-
1941
- broadcast("conversations", update);
1942
- broadcast(`conversation:${conversationId}`, update);
1943
- });
1944
- }
1945
-
1946
- // Listen for turn changes (if available)
1947
- if (eventStore.onTurnChange) {
1948
- eventStore.onTurnChange((conversationId, turn) => {
1949
- const update: WSTurnAdded = {
1950
- type: "turn_added",
1951
- conversation_id: conversationId,
1952
- turn: turnToSummary(turn),
1953
- };
1954
-
1955
- broadcast(`conversation:${conversationId}`, update);
1956
- });
1957
- }
1958
-
1959
- return {
1960
- getConnectionCount(): number {
1961
- return wsClients.size;
1962
- },
1963
-
1964
- closeAll(): void {
1965
- console.error(`[api-ws] Closing ${wsClients.size} connections...`);
1966
- for (const client of wsClients) {
1967
- if (client.ws.readyState === WebSocket.OPEN) {
1968
- client.ws.close(1001, "Server shutting down");
1969
- }
1970
377
  }
1971
- wsClients.clear();
1972
378
  },
1973
379
  };
1974
380
  }