macro-agent 0.1.1 → 0.1.2

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 (406) hide show
  1. package/.sudocode/issues.jsonl +28 -0
  2. package/.sudocode/specs.jsonl +4 -0
  3. package/CLAUDE.md +9 -3
  4. package/dist/agent/agent-manager.d.ts.map +1 -1
  5. package/dist/agent/agent-manager.js +111 -48
  6. package/dist/agent/agent-manager.js.map +1 -1
  7. package/dist/agent/types.d.ts +7 -0
  8. package/dist/agent/types.d.ts.map +1 -1
  9. package/dist/agent/types.js.map +1 -1
  10. package/dist/api/server.d.ts +5 -1
  11. package/dist/api/server.d.ts.map +1 -1
  12. package/dist/api/server.js +100 -3
  13. package/dist/api/server.js.map +1 -1
  14. package/dist/api/types.d.ts +1 -1
  15. package/dist/api/types.d.ts.map +1 -1
  16. package/dist/cli/acp.d.ts.map +1 -1
  17. package/dist/cli/acp.js +71 -1
  18. package/dist/cli/acp.js.map +1 -1
  19. package/dist/cli/index.js +5 -1
  20. package/dist/cli/index.js.map +1 -1
  21. package/dist/cli/mcp.js +27 -8
  22. package/dist/cli/mcp.js.map +1 -1
  23. package/dist/config/project-config.d.ts +13 -2
  24. package/dist/config/project-config.d.ts.map +1 -1
  25. package/dist/config/project-config.js +12 -2
  26. package/dist/config/project-config.js.map +1 -1
  27. package/dist/index.d.ts +1 -0
  28. package/dist/index.d.ts.map +1 -1
  29. package/dist/index.js +2 -0
  30. package/dist/index.js.map +1 -1
  31. package/dist/lifecycle/handlers/index.d.ts +7 -3
  32. package/dist/lifecycle/handlers/index.d.ts.map +1 -1
  33. package/dist/lifecycle/handlers/index.js +25 -8
  34. package/dist/lifecycle/handlers/index.js.map +1 -1
  35. package/dist/lifecycle/types.d.ts +2 -0
  36. package/dist/lifecycle/types.d.ts.map +1 -1
  37. package/dist/lifecycle/types.js.map +1 -1
  38. package/dist/map/adapter/extensions/index.d.ts +4 -1
  39. package/dist/map/adapter/extensions/index.d.ts.map +1 -1
  40. package/dist/map/adapter/extensions/index.js +27 -0
  41. package/dist/map/adapter/extensions/index.js.map +1 -1
  42. package/dist/map/adapter/extensions/streams.d.ts +95 -0
  43. package/dist/map/adapter/extensions/streams.d.ts.map +1 -0
  44. package/dist/map/adapter/extensions/streams.js +515 -0
  45. package/dist/map/adapter/extensions/streams.js.map +1 -0
  46. package/dist/map/adapter/index.d.ts +1 -1
  47. package/dist/map/adapter/index.d.ts.map +1 -1
  48. package/dist/map/adapter/index.js +3 -1
  49. package/dist/map/adapter/index.js.map +1 -1
  50. package/dist/map/adapter/types.d.ts +1 -1
  51. package/dist/map/adapter/types.d.ts.map +1 -1
  52. package/dist/mcp/mcp-server.d.ts +2 -0
  53. package/dist/mcp/mcp-server.d.ts.map +1 -1
  54. package/dist/mcp/mcp-server.js +12 -3
  55. package/dist/mcp/mcp-server.js.map +1 -1
  56. package/dist/mcp/tools/done.d.ts.map +1 -1
  57. package/dist/mcp/tools/done.js +18 -0
  58. package/dist/mcp/tools/done.js.map +1 -1
  59. package/dist/roles/builtin/coordinator.d.ts.map +1 -1
  60. package/dist/roles/builtin/coordinator.js +2 -1
  61. package/dist/roles/builtin/coordinator.js.map +1 -1
  62. package/dist/roles/builtin/integrator.d.ts.map +1 -1
  63. package/dist/roles/builtin/integrator.js +2 -1
  64. package/dist/roles/builtin/integrator.js.map +1 -1
  65. package/dist/roles/builtin/worker.d.ts.map +1 -1
  66. package/dist/roles/builtin/worker.js +3 -1
  67. package/dist/roles/builtin/worker.js.map +1 -1
  68. package/dist/roles/capabilities.d.ts +6 -0
  69. package/dist/roles/capabilities.d.ts.map +1 -1
  70. package/dist/roles/capabilities.js +10 -0
  71. package/dist/roles/capabilities.js.map +1 -1
  72. package/dist/roles/config-loader.d.ts +1 -1
  73. package/dist/roles/config-loader.d.ts.map +1 -1
  74. package/dist/roles/config-loader.js +3 -2
  75. package/dist/roles/config-loader.js.map +1 -1
  76. package/dist/roles/types.d.ts +3 -1
  77. package/dist/roles/types.d.ts.map +1 -1
  78. package/dist/server/combined-server.d.ts +8 -1
  79. package/dist/server/combined-server.d.ts.map +1 -1
  80. package/dist/server/combined-server.js +6 -2
  81. package/dist/server/combined-server.js.map +1 -1
  82. package/dist/store/event-store.d.ts.map +1 -1
  83. package/dist/store/event-store.js +12 -5
  84. package/dist/store/event-store.js.map +1 -1
  85. package/dist/store/instance.d.ts +1 -1
  86. package/dist/store/instance.d.ts.map +1 -1
  87. package/dist/store/instance.js +2 -2
  88. package/dist/store/instance.js.map +1 -1
  89. package/dist/store/types/agents.d.ts +5 -0
  90. package/dist/store/types/agents.d.ts.map +1 -1
  91. package/dist/task/backend/opentasks/daemon-manager.d.ts.map +1 -1
  92. package/dist/task/backend/opentasks/daemon-manager.js +1 -1
  93. package/dist/task/backend/opentasks/daemon-manager.js.map +1 -1
  94. package/dist/teams/index.d.ts +3 -1
  95. package/dist/teams/index.d.ts.map +1 -1
  96. package/dist/teams/index.js +2 -0
  97. package/dist/teams/index.js.map +1 -1
  98. package/dist/teams/seed-defaults.d.ts +20 -0
  99. package/dist/teams/seed-defaults.d.ts.map +1 -0
  100. package/dist/teams/seed-defaults.js +71 -0
  101. package/dist/teams/seed-defaults.js.map +1 -0
  102. package/dist/teams/team-loader.d.ts +6 -2
  103. package/dist/teams/team-loader.d.ts.map +1 -1
  104. package/dist/teams/team-loader.js +154 -162
  105. package/dist/teams/team-loader.js.map +1 -1
  106. package/dist/teams/team-manager.d.ts +112 -0
  107. package/dist/teams/team-manager.d.ts.map +1 -0
  108. package/dist/teams/team-manager.js +305 -0
  109. package/dist/teams/team-manager.js.map +1 -0
  110. package/dist/teams/team-runtime.d.ts +125 -19
  111. package/dist/teams/team-runtime.d.ts.map +1 -1
  112. package/dist/teams/team-runtime.js +527 -119
  113. package/dist/teams/team-runtime.js.map +1 -1
  114. package/dist/teams/types.d.ts +41 -151
  115. package/dist/teams/types.d.ts.map +1 -1
  116. package/dist/teams/types.js +2 -3
  117. package/dist/teams/types.js.map +1 -1
  118. package/docs/teams.md +73 -0
  119. package/package.json +2 -1
  120. package/references/minimem/.claude/settings.json +7 -0
  121. package/references/minimem/.sudocode/issues.jsonl +18 -0
  122. package/references/minimem/.sudocode/specs.jsonl +1 -0
  123. package/references/minimem/CLAUDE.md +310 -0
  124. package/references/minimem/README.md +562 -0
  125. package/references/minimem/claude-plugin/.claude-plugin/plugin.json +10 -0
  126. package/references/minimem/claude-plugin/.mcp.json +7 -0
  127. package/references/minimem/claude-plugin/README.md +158 -0
  128. package/references/minimem/claude-plugin/commands/recall.md +47 -0
  129. package/references/minimem/claude-plugin/commands/remember.md +41 -0
  130. package/references/minimem/claude-plugin/hooks/__tests__/hooks.test.ts +272 -0
  131. package/references/minimem/claude-plugin/hooks/hooks.json +27 -0
  132. package/references/minimem/claude-plugin/hooks/session-end.sh +86 -0
  133. package/references/minimem/claude-plugin/hooks/session-start.sh +85 -0
  134. package/references/minimem/claude-plugin/skills/memory/SKILL.md +108 -0
  135. package/references/minimem/media/banner.png +0 -0
  136. package/references/minimem/package-lock.json +5373 -0
  137. package/references/minimem/package.json +72 -0
  138. package/references/minimem/scripts/postbuild.js +35 -0
  139. package/references/minimem/src/__tests__/edge-cases.test.ts +371 -0
  140. package/references/minimem/src/__tests__/errors.test.ts +265 -0
  141. package/references/minimem/src/__tests__/helpers.ts +199 -0
  142. package/references/minimem/src/__tests__/internal.test.ts +407 -0
  143. package/references/minimem/src/__tests__/knowledge.test.ts +287 -0
  144. package/references/minimem/src/__tests__/minimem.integration.test.ts +1127 -0
  145. package/references/minimem/src/__tests__/session.test.ts +190 -0
  146. package/references/minimem/src/cli/__tests__/commands.test.ts +759 -0
  147. package/references/minimem/src/cli/commands/__tests__/conflicts.test.ts +141 -0
  148. package/references/minimem/src/cli/commands/append.ts +76 -0
  149. package/references/minimem/src/cli/commands/config.ts +262 -0
  150. package/references/minimem/src/cli/commands/conflicts.ts +413 -0
  151. package/references/minimem/src/cli/commands/daemon.ts +169 -0
  152. package/references/minimem/src/cli/commands/index.ts +12 -0
  153. package/references/minimem/src/cli/commands/init.ts +88 -0
  154. package/references/minimem/src/cli/commands/mcp.ts +177 -0
  155. package/references/minimem/src/cli/commands/push-pull.ts +213 -0
  156. package/references/minimem/src/cli/commands/search.ts +158 -0
  157. package/references/minimem/src/cli/commands/status.ts +84 -0
  158. package/references/minimem/src/cli/commands/sync-init.ts +290 -0
  159. package/references/minimem/src/cli/commands/sync.ts +70 -0
  160. package/references/minimem/src/cli/commands/upsert.ts +197 -0
  161. package/references/minimem/src/cli/config.ts +584 -0
  162. package/references/minimem/src/cli/index.ts +264 -0
  163. package/references/minimem/src/cli/shared.ts +161 -0
  164. package/references/minimem/src/cli/sync/__tests__/central.test.ts +152 -0
  165. package/references/minimem/src/cli/sync/__tests__/conflicts.test.ts +209 -0
  166. package/references/minimem/src/cli/sync/__tests__/daemon.test.ts +118 -0
  167. package/references/minimem/src/cli/sync/__tests__/detection.test.ts +207 -0
  168. package/references/minimem/src/cli/sync/__tests__/integration.test.ts +476 -0
  169. package/references/minimem/src/cli/sync/__tests__/registry.test.ts +363 -0
  170. package/references/minimem/src/cli/sync/__tests__/state.test.ts +255 -0
  171. package/references/minimem/src/cli/sync/__tests__/validation.test.ts +193 -0
  172. package/references/minimem/src/cli/sync/__tests__/watcher.test.ts +178 -0
  173. package/references/minimem/src/cli/sync/central.ts +292 -0
  174. package/references/minimem/src/cli/sync/conflicts.ts +204 -0
  175. package/references/minimem/src/cli/sync/daemon.ts +407 -0
  176. package/references/minimem/src/cli/sync/detection.ts +138 -0
  177. package/references/minimem/src/cli/sync/index.ts +107 -0
  178. package/references/minimem/src/cli/sync/operations.ts +373 -0
  179. package/references/minimem/src/cli/sync/registry.ts +279 -0
  180. package/references/minimem/src/cli/sync/state.ts +355 -0
  181. package/references/minimem/src/cli/sync/validation.ts +206 -0
  182. package/references/minimem/src/cli/sync/watcher.ts +234 -0
  183. package/references/minimem/src/cli/version.ts +34 -0
  184. package/references/minimem/src/core/index.ts +9 -0
  185. package/references/minimem/src/core/indexer.ts +628 -0
  186. package/references/minimem/src/core/searcher.ts +221 -0
  187. package/references/minimem/src/db/schema.ts +183 -0
  188. package/references/minimem/src/db/sqlite-vec.ts +24 -0
  189. package/references/minimem/src/embeddings/__tests__/embeddings.test.ts +431 -0
  190. package/references/minimem/src/embeddings/batch-gemini.ts +392 -0
  191. package/references/minimem/src/embeddings/batch-openai.ts +409 -0
  192. package/references/minimem/src/embeddings/embeddings.ts +434 -0
  193. package/references/minimem/src/index.ts +109 -0
  194. package/references/minimem/src/internal.ts +299 -0
  195. package/references/minimem/src/minimem.ts +1276 -0
  196. package/references/minimem/src/search/__tests__/hybrid.test.ts +247 -0
  197. package/references/minimem/src/search/graph.ts +234 -0
  198. package/references/minimem/src/search/hybrid.ts +151 -0
  199. package/references/minimem/src/search/search.ts +256 -0
  200. package/references/minimem/src/server/__tests__/mcp.test.ts +341 -0
  201. package/references/minimem/src/server/__tests__/tools.test.ts +364 -0
  202. package/references/minimem/src/server/mcp.ts +326 -0
  203. package/references/minimem/src/server/tools.ts +720 -0
  204. package/references/minimem/src/session.ts +460 -0
  205. package/references/minimem/tsconfig.json +19 -0
  206. package/references/minimem/tsup.config.ts +26 -0
  207. package/references/minimem/vitest.config.ts +24 -0
  208. package/references/openteams/.claude/settings.json +6 -0
  209. package/references/openteams/README.md +1 -0
  210. package/references/openteams/SKILL.md +341 -0
  211. package/references/openteams/design.md +411 -0
  212. package/references/openteams/examples/bmad-method/prompts/analyst/ROLE.md +16 -0
  213. package/references/openteams/examples/bmad-method/prompts/analyst/SOUL.md +5 -0
  214. package/references/openteams/examples/bmad-method/prompts/architect/ROLE.md +24 -0
  215. package/references/openteams/examples/bmad-method/prompts/architect/SOUL.md +5 -0
  216. package/references/openteams/examples/bmad-method/prompts/developer/ROLE.md +25 -0
  217. package/references/openteams/examples/bmad-method/prompts/developer/SOUL.md +5 -0
  218. package/references/openteams/examples/bmad-method/prompts/master/ROLE.md +21 -0
  219. package/references/openteams/examples/bmad-method/prompts/master/SOUL.md +5 -0
  220. package/references/openteams/examples/bmad-method/prompts/pm/ROLE.md +20 -0
  221. package/references/openteams/examples/bmad-method/prompts/pm/SOUL.md +5 -0
  222. package/references/openteams/examples/bmad-method/prompts/qa/ROLE.md +17 -0
  223. package/references/openteams/examples/bmad-method/prompts/qa/SOUL.md +5 -0
  224. package/references/openteams/examples/bmad-method/prompts/quick-flow-dev/ROLE.md +23 -0
  225. package/references/openteams/examples/bmad-method/prompts/quick-flow-dev/SOUL.md +5 -0
  226. package/references/openteams/examples/bmad-method/prompts/scrum-master/ROLE.md +27 -0
  227. package/references/openteams/examples/bmad-method/prompts/scrum-master/SOUL.md +5 -0
  228. package/references/openteams/examples/bmad-method/prompts/tech-writer/ROLE.md +21 -0
  229. package/references/openteams/examples/bmad-method/prompts/tech-writer/SOUL.md +5 -0
  230. package/references/openteams/examples/bmad-method/prompts/ux-designer/ROLE.md +16 -0
  231. package/references/openteams/examples/bmad-method/prompts/ux-designer/SOUL.md +5 -0
  232. package/references/openteams/examples/bmad-method/roles/analyst.yaml +9 -0
  233. package/references/openteams/examples/bmad-method/roles/architect.yaml +9 -0
  234. package/references/openteams/examples/bmad-method/roles/developer.yaml +8 -0
  235. package/references/openteams/examples/bmad-method/roles/master.yaml +8 -0
  236. package/references/openteams/examples/bmad-method/roles/pm.yaml +9 -0
  237. package/references/openteams/examples/bmad-method/roles/qa.yaml +8 -0
  238. package/references/openteams/examples/bmad-method/roles/quick-flow-dev.yaml +8 -0
  239. package/references/openteams/examples/bmad-method/roles/scrum-master.yaml +9 -0
  240. package/references/openteams/examples/bmad-method/roles/tech-writer.yaml +8 -0
  241. package/references/openteams/examples/bmad-method/roles/ux-designer.yaml +8 -0
  242. package/references/openteams/examples/bmad-method/team.yaml +161 -0
  243. package/references/openteams/examples/get-shit-done/prompts/codebase-mapper/ROLE.md +17 -0
  244. package/references/openteams/examples/get-shit-done/prompts/codebase-mapper/SOUL.md +5 -0
  245. package/references/openteams/examples/get-shit-done/prompts/debugger/ROLE.md +25 -0
  246. package/references/openteams/examples/get-shit-done/prompts/debugger/SOUL.md +5 -0
  247. package/references/openteams/examples/get-shit-done/prompts/executor/ROLE.md +34 -0
  248. package/references/openteams/examples/get-shit-done/prompts/executor/SOUL.md +5 -0
  249. package/references/openteams/examples/get-shit-done/prompts/integration-checker/ROLE.md +18 -0
  250. package/references/openteams/examples/get-shit-done/prompts/integration-checker/SOUL.md +3 -0
  251. package/references/openteams/examples/get-shit-done/prompts/orchestrator/ROLE.md +42 -0
  252. package/references/openteams/examples/get-shit-done/prompts/orchestrator/SOUL.md +5 -0
  253. package/references/openteams/examples/get-shit-done/prompts/phase-researcher/ROLE.md +15 -0
  254. package/references/openteams/examples/get-shit-done/prompts/phase-researcher/SOUL.md +3 -0
  255. package/references/openteams/examples/get-shit-done/prompts/plan-checker/ROLE.md +17 -0
  256. package/references/openteams/examples/get-shit-done/prompts/plan-checker/SOUL.md +3 -0
  257. package/references/openteams/examples/get-shit-done/prompts/planner/ROLE.md +28 -0
  258. package/references/openteams/examples/get-shit-done/prompts/planner/SOUL.md +5 -0
  259. package/references/openteams/examples/get-shit-done/prompts/project-researcher/ROLE.md +16 -0
  260. package/references/openteams/examples/get-shit-done/prompts/project-researcher/SOUL.md +3 -0
  261. package/references/openteams/examples/get-shit-done/prompts/research-synthesizer/ROLE.md +13 -0
  262. package/references/openteams/examples/get-shit-done/prompts/research-synthesizer/SOUL.md +3 -0
  263. package/references/openteams/examples/get-shit-done/prompts/roadmapper/ROLE.md +14 -0
  264. package/references/openteams/examples/get-shit-done/prompts/roadmapper/SOUL.md +3 -0
  265. package/references/openteams/examples/get-shit-done/prompts/verifier/ROLE.md +19 -0
  266. package/references/openteams/examples/get-shit-done/prompts/verifier/SOUL.md +5 -0
  267. package/references/openteams/examples/get-shit-done/roles/codebase-mapper.yaml +8 -0
  268. package/references/openteams/examples/get-shit-done/roles/debugger.yaml +8 -0
  269. package/references/openteams/examples/get-shit-done/roles/executor.yaml +8 -0
  270. package/references/openteams/examples/get-shit-done/roles/integration-checker.yaml +8 -0
  271. package/references/openteams/examples/get-shit-done/roles/orchestrator.yaml +9 -0
  272. package/references/openteams/examples/get-shit-done/roles/phase-researcher.yaml +7 -0
  273. package/references/openteams/examples/get-shit-done/roles/plan-checker.yaml +8 -0
  274. package/references/openteams/examples/get-shit-done/roles/planner.yaml +8 -0
  275. package/references/openteams/examples/get-shit-done/roles/project-researcher.yaml +8 -0
  276. package/references/openteams/examples/get-shit-done/roles/research-synthesizer.yaml +7 -0
  277. package/references/openteams/examples/get-shit-done/roles/roadmapper.yaml +7 -0
  278. package/references/openteams/examples/get-shit-done/roles/verifier.yaml +8 -0
  279. package/references/openteams/examples/get-shit-done/team.yaml +154 -0
  280. package/references/openteams/package-lock.json +2181 -0
  281. package/references/openteams/package.json +48 -0
  282. package/references/openteams/schema/role.schema.json +125 -0
  283. package/references/openteams/schema/team.schema.json +284 -0
  284. package/references/openteams/src/cli/agent.ts +104 -0
  285. package/references/openteams/src/cli/cli.test.ts +381 -0
  286. package/references/openteams/src/cli/generate.ts +220 -0
  287. package/references/openteams/src/cli/message.ts +241 -0
  288. package/references/openteams/src/cli/task.ts +154 -0
  289. package/references/openteams/src/cli/team.ts +104 -0
  290. package/references/openteams/src/cli/template.ts +207 -0
  291. package/references/openteams/src/cli.ts +45 -0
  292. package/references/openteams/src/db/database.test.ts +185 -0
  293. package/references/openteams/src/db/database.ts +240 -0
  294. package/references/openteams/src/generators/agent-prompt-generator.test.ts +332 -0
  295. package/references/openteams/src/generators/agent-prompt-generator.ts +521 -0
  296. package/references/openteams/src/generators/package-generator.test.ts +129 -0
  297. package/references/openteams/src/generators/package-generator.ts +102 -0
  298. package/references/openteams/src/generators/skill-generator.test.ts +246 -0
  299. package/references/openteams/src/generators/skill-generator.ts +374 -0
  300. package/references/openteams/src/index.ts +104 -0
  301. package/references/openteams/src/services/agent-service.test.ts +158 -0
  302. package/references/openteams/src/services/agent-service.ts +84 -0
  303. package/references/openteams/src/services/communication-service.test.ts +455 -0
  304. package/references/openteams/src/services/communication-service.ts +371 -0
  305. package/references/openteams/src/services/message-service.test.ts +342 -0
  306. package/references/openteams/src/services/message-service.ts +203 -0
  307. package/references/openteams/src/services/task-service.test.ts +434 -0
  308. package/references/openteams/src/services/task-service.ts +239 -0
  309. package/references/openteams/src/services/team-service.test.ts +181 -0
  310. package/references/openteams/src/services/team-service.ts +139 -0
  311. package/references/openteams/src/services/template-service.test.ts +306 -0
  312. package/references/openteams/src/services/template-service.ts +182 -0
  313. package/references/openteams/src/spawner/acp-factory.ts +96 -0
  314. package/references/openteams/src/spawner/interface.ts +31 -0
  315. package/references/openteams/src/spawner/mock.test.ts +93 -0
  316. package/references/openteams/src/spawner/mock.ts +59 -0
  317. package/references/openteams/src/template/loader.test.ts +1319 -0
  318. package/references/openteams/src/template/loader.ts +698 -0
  319. package/references/openteams/src/template/types.ts +200 -0
  320. package/references/openteams/src/types.ts +205 -0
  321. package/references/openteams/tsconfig.json +18 -0
  322. package/references/openteams/vitest.config.ts +9 -0
  323. package/references/skill-tree/.claude/settings.json +6 -0
  324. package/references/skill-tree/.sudocode/issues.jsonl +11 -0
  325. package/references/skill-tree/.sudocode/specs.jsonl +1 -0
  326. package/references/skill-tree/CLAUDE.md +150 -0
  327. package/references/skill-tree/README.md +324 -0
  328. package/references/skill-tree/docs/GAPS_v1.md +221 -0
  329. package/references/skill-tree/docs/INTEGRATION_PLAN.md +467 -0
  330. package/references/skill-tree/docs/TODOS.md +91 -0
  331. package/references/skill-tree/docs/anthropic_skill_guide.md +1364 -0
  332. package/references/skill-tree/docs/design/federated-skill-trees.md +524 -0
  333. package/references/skill-tree/docs/design/multi-agent-sync.md +759 -0
  334. package/references/skill-tree/docs/scraper/BRAINSTORM.md +583 -0
  335. package/references/skill-tree/docs/scraper/POC_PLAN.md +420 -0
  336. package/references/skill-tree/docs/scraper/README.md +170 -0
  337. package/references/skill-tree/examples/basic-usage.ts +190 -0
  338. package/references/skill-tree/package-lock.json +1509 -0
  339. package/references/skill-tree/package.json +66 -0
  340. package/references/skill-tree/scraper/README.md +123 -0
  341. package/references/skill-tree/scraper/docs/DESIGN.md +683 -0
  342. package/references/skill-tree/scraper/docs/PLAN.md +336 -0
  343. package/references/skill-tree/scraper/drizzle.config.ts +10 -0
  344. package/references/skill-tree/scraper/package-lock.json +6329 -0
  345. package/references/skill-tree/scraper/package.json +68 -0
  346. package/references/skill-tree/scraper/test/fixtures/invalid-skill/missing-description.md +7 -0
  347. package/references/skill-tree/scraper/test/fixtures/invalid-skill/missing-name.md +7 -0
  348. package/references/skill-tree/scraper/test/fixtures/minimal-skill/SKILL.md +27 -0
  349. package/references/skill-tree/scraper/test/fixtures/skill-json/SKILL.json +21 -0
  350. package/references/skill-tree/scraper/test/fixtures/skill-with-meta/SKILL.md +54 -0
  351. package/references/skill-tree/scraper/test/fixtures/skill-with-meta/_meta.json +24 -0
  352. package/references/skill-tree/scraper/test/fixtures/valid-skill/SKILL.md +93 -0
  353. package/references/skill-tree/scraper/test/fixtures/valid-skill/_meta.json +22 -0
  354. package/references/skill-tree/scraper/tsup.config.ts +14 -0
  355. package/references/skill-tree/scraper/vitest.config.ts +17 -0
  356. package/references/skill-tree/scripts/convert-to-vitest.ts +166 -0
  357. package/references/skill-tree/skills/skill-writer/SKILL.md +339 -0
  358. package/references/skill-tree/skills/skill-writer/references/examples.md +326 -0
  359. package/references/skill-tree/skills/skill-writer/references/patterns.md +210 -0
  360. package/references/skill-tree/skills/skill-writer/references/quality-checklist.md +123 -0
  361. package/references/skill-tree/test/run-all.ts +106 -0
  362. package/references/skill-tree/test/utils.ts +128 -0
  363. package/references/skill-tree/vitest.config.ts +16 -0
  364. package/src/agent/agent-manager.ts +143 -72
  365. package/src/agent/types.ts +9 -0
  366. package/src/api/__tests__/server.test.ts +203 -4
  367. package/src/api/server.ts +130 -5
  368. package/src/api/types.ts +3 -1
  369. package/src/cli/acp.ts +68 -1
  370. package/src/cli/index.ts +5 -1
  371. package/src/cli/mcp.ts +27 -13
  372. package/src/config/project-config.ts +27 -3
  373. package/src/index.ts +3 -0
  374. package/src/lifecycle/__tests__/handlers.test.ts +53 -0
  375. package/src/lifecycle/handlers/index.ts +25 -8
  376. package/src/lifecycle/types.ts +3 -0
  377. package/src/map/adapter/__tests__/stream-extensions.test.ts +494 -0
  378. package/src/map/adapter/extensions/index.ts +36 -0
  379. package/src/map/adapter/extensions/streams.ts +839 -0
  380. package/src/map/adapter/index.ts +5 -0
  381. package/src/map/adapter/types.ts +8 -1
  382. package/src/mcp/mcp-server.ts +14 -3
  383. package/src/mcp/tools/done.ts +19 -0
  384. package/src/roles/builtin/coordinator.ts +2 -0
  385. package/src/roles/builtin/integrator.ts +2 -0
  386. package/src/roles/builtin/worker.ts +3 -0
  387. package/src/roles/capabilities.ts +11 -0
  388. package/src/roles/config-loader.ts +3 -2
  389. package/src/roles/types.ts +7 -0
  390. package/src/server/combined-server.ts +15 -1
  391. package/src/store/__tests__/event-store-oob.test.ts +109 -0
  392. package/src/store/event-store.ts +13 -3
  393. package/src/store/instance.ts +2 -2
  394. package/src/store/types/agents.ts +5 -0
  395. package/src/task/backend/__tests__/memory-pull-mode.test.ts +153 -0
  396. package/src/task/backend/opentasks/daemon-manager.ts +4 -1
  397. package/src/teams/CLAUDE.md +180 -0
  398. package/src/teams/__tests__/e2e/workspace-isolation.e2e.test.ts +1263 -0
  399. package/src/teams/__tests__/team-manager.test.ts +814 -0
  400. package/src/teams/__tests__/team-system.test.ts +1291 -8
  401. package/src/teams/index.ts +21 -3
  402. package/src/teams/seed-defaults.ts +79 -0
  403. package/src/teams/team-loader.ts +200 -234
  404. package/src/teams/team-manager.ts +387 -0
  405. package/src/teams/team-runtime.ts +590 -121
  406. package/src/teams/types.ts +99 -200
@@ -493,6 +493,7 @@ export function createAgentManager(
493
493
  permissionMode: string;
494
494
  lineage?: string[];
495
495
  sessionId?: string;
496
+ streamId?: string;
496
497
  }) {
497
498
  // Common env vars for both thin-client and legacy modes
498
499
  const env = [
@@ -509,6 +510,9 @@ export function createAgentManager(
509
510
  name: "OPENTASKS_SOCKET_PATH",
510
511
  value: configOpenTasksSocketPath ?? process.env.OPENTASKS_SOCKET_PATH ?? "",
511
512
  },
513
+ // Pass streamId so MCP subprocess can include it in lifecycle context
514
+ // (WorkspaceManager is not available in subprocess)
515
+ { name: "MACRO_STREAM_ID", value: opts.streamId ?? "" },
512
516
  ];
513
517
 
514
518
  if (serverUrl) {
@@ -577,9 +581,11 @@ export function createAgentManager(
577
581
  interactionPatterns,
578
582
  // Workspace-related fields (Phase 2)
579
583
  role,
584
+ team_instance,
580
585
  streamId,
581
586
  streamConfig,
582
587
  dataplaneTaskId,
588
+ capabilities,
583
589
  } = options;
584
590
 
585
591
  // Generate IDs upfront (including session_id so we can persist before starting MCP)
@@ -674,6 +680,7 @@ export function createAgentManager(
674
680
  task_id: taskId,
675
681
  parent: parent ?? null,
676
682
  role: role ?? undefined,
683
+ team_instance: team_instance ?? undefined,
677
684
  config: agentConfig ?? {},
678
685
  cwd,
679
686
  },
@@ -708,16 +715,95 @@ export function createAgentManager(
708
715
  });
709
716
 
710
717
  try {
718
+ // ─────────────────────────────────────────────────────────────────
719
+ // Workspace Creation (before session, so cwd reflects worktree)
720
+ // ─────────────────────────────────────────────────────────────────
721
+ let workspace: Workspace | undefined;
722
+ let resolvedStreamId = streamId;
723
+
724
+ if (workspaceManager && role) {
725
+ try {
726
+ workspace = await createWorkspaceForRole(
727
+ workspaceManager,
728
+ agentId,
729
+ role,
730
+ {
731
+ streamId,
732
+ streamConfig,
733
+ dataplaneTaskId,
734
+ capabilities,
735
+ cwd,
736
+ },
737
+ );
738
+
739
+ if (workspace) {
740
+ agentWorkspaces.set(agentId, workspace);
741
+ resolvedStreamId = workspace.streamId;
742
+
743
+ // Create and claim a dataplane task so the worktree gets a real
744
+ // worker branch. Without this, the worktree stays in detached
745
+ // HEAD and done() would detect "HEAD" instead of the actual
746
+ // worker branch name (e.g. worker/<agentId>/<taskId>).
747
+ if (workspace.role === "worker" && workspace.streamId) {
748
+ try {
749
+ const dpTaskId = workspaceManager.createTask(
750
+ workspace.streamId,
751
+ { title: task ?? `Task for ${agentId}` },
752
+ );
753
+ workspaceManager.claimTask(dpTaskId, agentId, workspace.path);
754
+ } catch (claimErr) {
755
+ console.error(
756
+ `[AgentManager] Failed to create/claim dataplane task for ${agentId}:`,
757
+ claimErr,
758
+ );
759
+ // Continue without a branch — worktree stays in detached HEAD
760
+ }
761
+ }
762
+
763
+ // Register with parent coordinator if applicable
764
+ const isChildRole = role === "worker" || role === "integrator" ||
765
+ (capabilities && (capabilities.includes("workspace.worktree") || capabilities.includes("workspace.integrate")));
766
+ if (parent && isChildRole) {
767
+ const parentWorkspace = agentWorkspaces.get(parent);
768
+ if (parentWorkspace?.role === "coordinator") {
769
+ workspaceManager.registerChildWorkspace(
770
+ parent,
771
+ agentId,
772
+ workspace.path,
773
+ );
774
+ }
775
+ }
776
+ }
777
+ } catch (wsError) {
778
+ console.error(
779
+ `[AgentManager] Failed to create workspace for ${agentId}: ${wsError}`,
780
+ );
781
+ // Continue without workspace — don't fail the spawn
782
+ }
783
+ }
784
+
785
+ // Use workspace path as the agent's working directory when available.
786
+ // This ensures the agent process, MCP subprocess (MACRO_AGENT_CWD), and
787
+ // done handler all use the worktree path instead of the repo root.
788
+ const effectiveCwd = workspace?.path ?? cwd;
789
+
790
+ // Update agent's cwd in EventStore so resume() also uses workspace path
791
+ if (workspace) {
792
+ eventStore.updateAgentMetadata(agentId as AgentId, { cwd: effectiveCwd });
793
+ await eventStore.persist();
794
+ }
795
+
711
796
  const macroAgentMcp = buildMacroAgentMcp({
712
797
  agentId,
713
798
  parentId: parent ?? "",
714
799
  taskId,
715
- cwd,
800
+ cwd: effectiveCwd,
716
801
  permissionMode,
717
802
  lineage: parentAgent?.lineage
718
803
  ? [...parentAgent.lineage, parent!]
719
804
  : [],
720
805
  sessionId,
806
+ streamId,
721
807
  });
722
808
 
723
809
  // Combine with any user-provided MCP servers
@@ -744,7 +830,7 @@ export function createAgentManager(
744
830
  permissionMode === "interactive"
745
831
  ? { claudeCode: { options: { settingSources: [] } } }
746
832
  : undefined;
747
- const session = await handle.createSession(cwd, {
833
+ const session = await handle.createSession(effectiveCwd, {
748
834
  mcpServers: [macroAgentMcp, ...userMcpServers],
749
835
  ...(agentMeta && { agentMeta }),
750
836
  });
@@ -834,50 +920,6 @@ export function createAgentManager(
834
920
  // Get the agent from materialized view
835
921
  const agent = eventStore.getAgent(agentId)!;
836
922
 
837
- // ─────────────────────────────────────────────────────────────────
838
- // Workspace Creation (Phase 2)
839
- // ─────────────────────────────────────────────────────────────────
840
- let workspace: Workspace | undefined;
841
- let resolvedStreamId = streamId;
842
-
843
- if (workspaceManager && role) {
844
- try {
845
- workspace = await createWorkspaceForRole(
846
- workspaceManager,
847
- agentId,
848
- role,
849
- {
850
- streamId,
851
- streamConfig,
852
- dataplaneTaskId,
853
- cwd,
854
- },
855
- );
856
-
857
- if (workspace) {
858
- agentWorkspaces.set(agentId, workspace);
859
- resolvedStreamId = workspace.streamId;
860
-
861
- // Register with parent coordinator if applicable
862
- if (parent && (role === "worker" || role === "integrator")) {
863
- const parentWorkspace = agentWorkspaces.get(parent);
864
- if (parentWorkspace?.role === "coordinator") {
865
- workspaceManager.registerChildWorkspace(
866
- parent,
867
- agentId,
868
- workspace.path,
869
- );
870
- }
871
- }
872
- }
873
- } catch (wsError) {
874
- console.error(
875
- `[AgentManager] Failed to create workspace for ${agentId}: ${wsError}`,
876
- );
877
- // Continue without workspace - don't fail the spawn
878
- }
879
- }
880
-
881
923
  // Notify lifecycle listeners
882
924
  notifyLifecycle({ type: "spawned", agent });
883
925
  notifyLifecycle({ type: "started", agent });
@@ -1258,6 +1300,7 @@ export function createAgentManager(
1258
1300
  task_id: taskId,
1259
1301
  parent: sourceAgent.parent ?? null,
1260
1302
  role: sourceAgent.role ?? undefined,
1303
+ team_instance: sourceAgent.team_instance ?? undefined,
1261
1304
  config: {},
1262
1305
  cwd,
1263
1306
  metadata: { fork_of: sourceAgentId },
@@ -1971,16 +2014,25 @@ interface CreateWorkspaceOptions {
1971
2014
  streamId?: string;
1972
2015
  streamConfig?: import("../workspace/types.js").StreamConfig;
1973
2016
  dataplaneTaskId?: string;
2017
+ capabilities?: string[];
1974
2018
  cwd: string;
1975
2019
  }
1976
2020
 
1977
2021
  /**
1978
- * Create a workspace for an agent based on their role.
2022
+ * Create a workspace for an agent based on their capabilities.
2023
+ *
2024
+ * Dispatches on workspace capabilities (workspace.stream, workspace.integrate,
2025
+ * workspace.worktree) rather than role names. This allows team-defined roles
2026
+ * (e.g., "developer" extending "worker") to get proper workspace allocation
2027
+ * by inheriting workspace capabilities from their base role.
2028
+ *
2029
+ * Falls back to role-name matching for backward compatibility when no
2030
+ * capabilities are provided.
1979
2031
  *
1980
2032
  * @param workspaceManager - WorkspaceManager instance
1981
2033
  * @param agentId - Agent ID
1982
- * @param role - Agent role (e.g., 'worker', 'coordinator', 'integrator')
1983
- * @param options - Additional options
2034
+ * @param role - Agent role name (used for logging and fallback)
2035
+ * @param options - Workspace options including capabilities
1984
2036
  * @returns Created workspace or undefined
1985
2037
  */
1986
2038
  async function createWorkspaceForRole(
@@ -1989,66 +2041,85 @@ async function createWorkspaceForRole(
1989
2041
  role: string,
1990
2042
  options: CreateWorkspaceOptions,
1991
2043
  ): Promise<Workspace | undefined> {
1992
- const { streamId, streamConfig, dataplaneTaskId } = options;
2044
+ const { streamId, streamConfig, dataplaneTaskId, capabilities } = options;
2045
+
2046
+ // Capability-based dispatch (preferred — works for team-defined roles)
2047
+ if (capabilities && capabilities.length > 0) {
2048
+ if (capabilities.includes("workspace.stream")) {
2049
+ // Coordinator pattern: create integration stream.
2050
+ // In team mode, stream is managed by TeamRuntime.setupWorkspaceIntegration(),
2051
+ // so missing streamConfig is expected — return silently.
2052
+ if (!streamConfig) {
2053
+ return undefined;
2054
+ }
2055
+ const newStreamId = workspaceManager.createIntegrationStream(agentId, streamConfig);
2056
+ return workspaceManager.createCoordinatorWorkspace(agentId, newStreamId);
2057
+
2058
+ } else if (capabilities.includes("workspace.integrate")) {
2059
+ // Integrator pattern: join existing stream
2060
+ if (!streamId) {
2061
+ console.warn(
2062
+ `[AgentManager] ${role} ${agentId} has workspace.integrate but no streamId, skipping workspace`,
2063
+ );
2064
+ return undefined;
2065
+ }
2066
+ return workspaceManager.createIntegratorWorkspace(agentId, streamId);
1993
2067
 
2068
+ } else if (capabilities.includes("workspace.worktree")) {
2069
+ // Worker pattern: create worktree in stream
2070
+ if (!streamId) {
2071
+ console.warn(
2072
+ `[AgentManager] ${role} ${agentId} has workspace.worktree but no streamId, skipping workspace`,
2073
+ );
2074
+ return undefined;
2075
+ }
2076
+ const taskId = dataplaneTaskId ?? agentId;
2077
+ return workspaceManager.createWorkerWorkspace(agentId, taskId, streamId);
2078
+ }
2079
+
2080
+ // Has capabilities but no workspace capability — no workspace needed
2081
+ return undefined;
2082
+ }
2083
+
2084
+ // Fallback: role-name dispatch (backward compatibility for non-team spawns)
1994
2085
  switch (role) {
1995
2086
  case "coordinator": {
1996
- // Coordinators create a new integration stream
1997
2087
  if (!streamConfig) {
1998
2088
  console.warn(
1999
2089
  `[AgentManager] Coordinator ${agentId} spawn missing streamConfig, skipping workspace`,
2000
2090
  );
2001
2091
  return undefined;
2002
2092
  }
2003
-
2004
- const newStreamId = workspaceManager.createIntegrationStream(
2005
- agentId,
2006
- streamConfig,
2007
- );
2008
-
2093
+ const newStreamId = workspaceManager.createIntegrationStream(agentId, streamConfig);
2009
2094
  return workspaceManager.createCoordinatorWorkspace(agentId, newStreamId);
2010
2095
  }
2011
2096
 
2012
2097
  case "integrator": {
2013
- // Integrators join an existing stream
2014
2098
  if (!streamId) {
2015
2099
  console.warn(
2016
2100
  `[AgentManager] Integrator ${agentId} spawn missing streamId, skipping workspace`,
2017
2101
  );
2018
2102
  return undefined;
2019
2103
  }
2020
-
2021
2104
  return workspaceManager.createIntegratorWorkspace(agentId, streamId);
2022
2105
  }
2023
2106
 
2024
2107
  case "worker":
2025
2108
  case "worker.resolver": {
2026
- // Workers need streamId and either dataplaneTaskId or create a new task
2027
2109
  if (!streamId) {
2028
2110
  console.warn(
2029
2111
  `[AgentManager] Worker ${agentId} spawn missing streamId, skipping workspace`,
2030
2112
  );
2031
2113
  return undefined;
2032
2114
  }
2033
-
2034
- // Use provided task ID or skip (task should be created separately)
2035
- const taskId = dataplaneTaskId;
2036
- if (!taskId) {
2037
- console.warn(
2038
- `[AgentManager] Worker ${agentId} spawn missing dataplaneTaskId, skipping workspace`,
2039
- );
2040
- return undefined;
2041
- }
2042
-
2115
+ const taskId = dataplaneTaskId ?? agentId;
2043
2116
  return workspaceManager.createWorkerWorkspace(agentId, taskId, streamId);
2044
2117
  }
2045
2118
 
2046
2119
  case "monitor":
2047
- // Monitors don't need workspaces
2048
2120
  return undefined;
2049
2121
 
2050
2122
  default:
2051
- // Unknown role - no workspace
2052
2123
  return undefined;
2053
2124
  }
2054
2125
  }
@@ -74,6 +74,9 @@ export interface SpawnAgentOptions {
74
74
  */
75
75
  role?: string;
76
76
 
77
+ /** Team instance ID this agent belongs to (set by TeamManager interceptor) */
78
+ team_instance?: string;
79
+
77
80
  /**
78
81
  * Stream ID to join (for workers and integrators).
79
82
  * Required for workers and integrators when using workspace isolation.
@@ -91,6 +94,12 @@ export interface SpawnAgentOptions {
91
94
  * If provided, the worker will claim this task and work on it.
92
95
  */
93
96
  dataplaneTaskId?: string;
97
+
98
+ /**
99
+ * Resolved capabilities for this agent's role.
100
+ * Injected by TeamRuntime spawn interceptor for capability-based workspace dispatch.
101
+ */
102
+ capabilities?: string[];
94
103
  }
95
104
 
96
105
  /**
@@ -9,6 +9,7 @@ import type { EventStore } from "../../store/event-store.js";
9
9
  import type { AgentManager } from "../../agent/agent-manager.js";
10
10
  import type { TaskManager } from "../../task/task-manager.js";
11
11
  import type { MessageRouter } from "../../router/message-router.js";
12
+ import type { TeamManager, TeamInstance } from "../../teams/team-manager.js";
12
13
  import type { Agent, Task, Event } from "../../store/types/index.js";
13
14
 
14
15
  // ─────────────────────────────────────────────────────────────────
@@ -154,6 +155,41 @@ function createMockMessageRouter(): MessageRouter {
154
155
  };
155
156
  }
156
157
 
158
+ function createMockTeamInstance(overrides: Partial<TeamInstance> = {}): TeamInstance {
159
+ return {
160
+ id: "test-team-1",
161
+ templateName: "test-team",
162
+ runtime: {
163
+ getTaskMode: vi.fn(() => "push"),
164
+ getStrategyName: vi.fn(() => "queue"),
165
+ getManifest: vi.fn(() => ({
166
+ roles: [{ name: "worker", extends: "worker" }],
167
+ communication: { channels: [] },
168
+ })),
169
+ } as any,
170
+ result: {
171
+ rootId: "agent_root1",
172
+ companionIds: ["agent_comp1"],
173
+ },
174
+ ...overrides,
175
+ };
176
+ }
177
+
178
+ function createMockTeamManager(): TeamManager {
179
+ const instance = createMockTeamInstance();
180
+ return {
181
+ startTeam: vi.fn(async () => instance),
182
+ stopTeam: vi.fn(async () => {}),
183
+ teardownAll: vi.fn(async () => {}),
184
+ getTeamForAgent: vi.fn(() => undefined),
185
+ getInstance: vi.fn((id: string) => (id === instance.id ? instance : undefined)),
186
+ getInstances: vi.fn(() => [instance]),
187
+ hasActiveTeam: vi.fn(() => true),
188
+ install: vi.fn(),
189
+ uninstall: vi.fn(),
190
+ } as unknown as TeamManager;
191
+ }
192
+
157
193
  // ─────────────────────────────────────────────────────────────────
158
194
  // Test Suite
159
195
  // ─────────────────────────────────────────────────────────────────
@@ -485,7 +521,7 @@ describe("API Server", () => {
485
521
 
486
522
  describe("Graceful Shutdown", () => {
487
523
  it("should call eventStore.persist and close on graceful shutdown", async () => {
488
- const server = createTrackedServer();
524
+ const server = createTrackedServer(services, { port: 0 });
489
525
  await server.start();
490
526
  await server.stop();
491
527
 
@@ -495,7 +531,7 @@ describe("API Server", () => {
495
531
  });
496
532
 
497
533
  it("should skip grace period on force shutdown", async () => {
498
- const server = createTrackedServer(services, { shutdownGracePeriodMs: 5000 });
534
+ const server = createTrackedServer(services, { port: 0, shutdownGracePeriodMs: 5000 });
499
535
  await server.start();
500
536
 
501
537
  const startTime = Date.now();
@@ -509,7 +545,7 @@ describe("API Server", () => {
509
545
  });
510
546
 
511
547
  it("should reject new messages during shutdown", async () => {
512
- const server = createTrackedServer();
548
+ const server = createTrackedServer(services, { port: 0 });
513
549
  await server.start();
514
550
 
515
551
  // Initialize first
@@ -535,7 +571,7 @@ describe("API Server", () => {
535
571
  });
536
572
 
537
573
  it("should only shutdown once on multiple stop calls", async () => {
538
- const server = createTrackedServer();
574
+ const server = createTrackedServer(services, { port: 0 });
539
575
  await server.start();
540
576
 
541
577
  // Call stop twice concurrently
@@ -549,6 +585,7 @@ describe("API Server", () => {
549
585
  it("should use custom shutdown grace period", async () => {
550
586
  const customGracePeriod = 100;
551
587
  const server = createTrackedServer(services, {
588
+ port: 0,
552
589
  shutdownGracePeriodMs: customGracePeriod,
553
590
  });
554
591
  await server.start();
@@ -1012,4 +1049,166 @@ describe("API Server", () => {
1012
1049
  );
1013
1050
  });
1014
1051
  });
1052
+
1053
+ // ─────────────────────────────────────────────────────────────────
1054
+ // Team Management API Endpoints
1055
+ // ─────────────────────────────────────────────────────────────────
1056
+
1057
+ describe("Team Management API", () => {
1058
+ let teamManager: TeamManager;
1059
+
1060
+ beforeEach(() => {
1061
+ teamManager = createMockTeamManager();
1062
+ services = { ...services, teamManager };
1063
+ });
1064
+
1065
+ describe("POST /api/teams", () => {
1066
+ it("should start a team instance", async () => {
1067
+ const server = createTrackedServer();
1068
+ const res = await request(server.app)
1069
+ .post("/api/teams")
1070
+ .send({ template: "test-team" });
1071
+
1072
+ expect(res.status).toBe(201);
1073
+ expect(res.body.id).toBe("test-team-1");
1074
+ expect(res.body.templateName).toBe("test-team");
1075
+ expect(res.body.rootAgentId).toBe("agent_root1");
1076
+ expect(res.body.companionAgentIds).toEqual(["agent_comp1"]);
1077
+ expect(res.body.taskMode).toBe("push");
1078
+ expect(res.body.strategy).toBe("queue");
1079
+ expect(teamManager.startTeam).toHaveBeenCalledWith("test-team", expect.any(String), undefined);
1080
+ });
1081
+
1082
+ it("should return 400 when template is missing", async () => {
1083
+ const server = createTrackedServer();
1084
+ const res = await request(server.app)
1085
+ .post("/api/teams")
1086
+ .send({});
1087
+
1088
+ expect(res.status).toBe(400);
1089
+ expect(res.body.code).toBe("INVALID_REQUEST");
1090
+ });
1091
+
1092
+ it("should allow starting multiple teams", async () => {
1093
+ const secondInstance = createMockTeamInstance({
1094
+ id: "second-team-1",
1095
+ templateName: "second-team",
1096
+ });
1097
+ (teamManager.startTeam as any)
1098
+ .mockResolvedValueOnce(createMockTeamInstance())
1099
+ .mockResolvedValueOnce(secondInstance);
1100
+
1101
+ const server = createTrackedServer();
1102
+
1103
+ const res1 = await request(server.app)
1104
+ .post("/api/teams")
1105
+ .send({ template: "test-team" });
1106
+ expect(res1.status).toBe(201);
1107
+
1108
+ const res2 = await request(server.app)
1109
+ .post("/api/teams")
1110
+ .send({ template: "second-team" });
1111
+ expect(res2.status).toBe(201);
1112
+ expect(res2.body.id).toBe("second-team-1");
1113
+ });
1114
+
1115
+ it("should return 500 on start failure", async () => {
1116
+ (teamManager.startTeam as any).mockRejectedValueOnce(
1117
+ new Error("Template not found")
1118
+ );
1119
+
1120
+ const server = createTrackedServer();
1121
+ const res = await request(server.app)
1122
+ .post("/api/teams")
1123
+ .send({ template: "bad-team" });
1124
+
1125
+ expect(res.status).toBe(500);
1126
+ expect(res.body.code).toBe("TEAM_START_FAILED");
1127
+ });
1128
+ });
1129
+
1130
+ describe("GET /api/teams", () => {
1131
+ it("should list running team instances", async () => {
1132
+ const server = createTrackedServer();
1133
+ const res = await request(server.app).get("/api/teams");
1134
+
1135
+ expect(res.status).toBe(200);
1136
+ expect(res.body).toHaveLength(1);
1137
+ expect(res.body[0].id).toBe("test-team-1");
1138
+ expect(res.body[0].templateName).toBe("test-team");
1139
+ expect(res.body[0].rootAgentId).toBe("agent_root1");
1140
+ });
1141
+
1142
+ it("should return empty array when no teams running", async () => {
1143
+ (teamManager.getInstances as any).mockReturnValue([]);
1144
+
1145
+ const server = createTrackedServer();
1146
+ const res = await request(server.app).get("/api/teams");
1147
+
1148
+ expect(res.status).toBe(200);
1149
+ expect(res.body).toEqual([]);
1150
+ });
1151
+ });
1152
+
1153
+ describe("GET /api/teams/:id", () => {
1154
+ it("should return team instance details", async () => {
1155
+ const server = createTrackedServer();
1156
+ const res = await request(server.app).get("/api/teams/test-team-1");
1157
+
1158
+ expect(res.status).toBe(200);
1159
+ expect(res.body.id).toBe("test-team-1");
1160
+ expect(res.body.roles).toBeDefined();
1161
+ expect(res.body.communication).toBeDefined();
1162
+ });
1163
+
1164
+ it("should return 404 for unknown team", async () => {
1165
+ const server = createTrackedServer();
1166
+ const res = await request(server.app).get("/api/teams/nonexistent");
1167
+
1168
+ expect(res.status).toBe(404);
1169
+ expect(res.body.code).toBe("TEAM_NOT_FOUND");
1170
+ });
1171
+ });
1172
+
1173
+ describe("DELETE /api/teams/:id", () => {
1174
+ it("should teardown a team instance", async () => {
1175
+ const server = createTrackedServer();
1176
+ const res = await request(server.app).delete("/api/teams/test-team-1");
1177
+
1178
+ expect(res.status).toBe(200);
1179
+ expect(res.body.success).toBe(true);
1180
+ expect(teamManager.stopTeam).toHaveBeenCalledWith("test-team-1");
1181
+ });
1182
+
1183
+ it("should return 404 for unknown team", async () => {
1184
+ const server = createTrackedServer();
1185
+ const res = await request(server.app).delete("/api/teams/nonexistent");
1186
+
1187
+ expect(res.status).toBe(404);
1188
+ expect(res.body.code).toBe("TEAM_NOT_FOUND");
1189
+ });
1190
+
1191
+ it("should return 500 on stop failure", async () => {
1192
+ (teamManager.stopTeam as any).mockRejectedValueOnce(
1193
+ new Error("Teardown failed")
1194
+ );
1195
+
1196
+ const server = createTrackedServer();
1197
+ const res = await request(server.app).delete("/api/teams/test-team-1");
1198
+
1199
+ expect(res.status).toBe(500);
1200
+ expect(res.body.code).toBe("TEAM_STOP_FAILED");
1201
+ });
1202
+ });
1203
+
1204
+ describe("without teamManager", () => {
1205
+ it("should not register team routes when teamManager is not provided", async () => {
1206
+ const servicesNoTeam = { eventStore, agentManager, taskManager, messageRouter };
1207
+ const server = createTrackedServer(servicesNoTeam);
1208
+
1209
+ const res = await request(server.app).get("/api/teams");
1210
+ expect(res.status).toBe(404);
1211
+ });
1212
+ });
1213
+ });
1015
1214
  });