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
package/src/api/server.ts CHANGED
@@ -57,6 +57,7 @@ import {
57
57
  } from "../steering/index.js";
58
58
  import type { AgentId } from "../store/types/index.js";
59
59
  import { secureCompare } from "../auth/token.js";
60
+ import type { TeamManager } from "../teams/team-manager.js";
60
61
 
61
62
  // ─────────────────────────────────────────────────────────────────
62
63
  // Server Configuration
@@ -88,6 +89,8 @@ export interface APIServices {
88
89
  mailService?: import("../mail/mail-service.js").MailService;
89
90
  /** Optional conversation map for agent-to-conversation tracking */
90
91
  conversationMap?: import("../mail/conversation-map.js").ConversationMap;
92
+ /** Optional team manager for dynamic team management */
93
+ teamManager?: TeamManager;
91
94
  }
92
95
 
93
96
  // ─────────────────────────────────────────────────────────────────
@@ -347,6 +350,113 @@ function registerConversationRoutes(
347
350
  });
348
351
  }
349
352
 
353
+ // ─────────────────────────────────────────────────────────────────
354
+ // Shared Team Routes Helper
355
+ // ─────────────────────────────────────────────────────────────────
356
+
357
+ /**
358
+ * Register team management REST endpoints on an Express app.
359
+ * Shared between standalone and shared API modes.
360
+ *
361
+ * Endpoints:
362
+ * POST /api/teams — Start a team instance
363
+ * GET /api/teams — List running team instances
364
+ * GET /api/teams/:id — Get team instance details
365
+ * DELETE /api/teams/:id — Teardown a team instance
366
+ */
367
+ function registerTeamRoutes(
368
+ app: Express,
369
+ teamManager: TeamManager | undefined,
370
+ defaultCwd: string,
371
+ sendError: (res: Response, status: number, code: string, message: string) => void,
372
+ broadcast?: (channel: string, message: WSMessage) => void,
373
+ ): void {
374
+ if (!teamManager) return;
375
+
376
+ // POST /api/teams — Start a team instance
377
+ app.post("/api/teams", async (req: Request, res: Response) => {
378
+ const { template, overrides } = req.body ?? {};
379
+ if (!template || typeof template !== "string") {
380
+ return sendError(res, 400, "INVALID_REQUEST", "Missing required field: template");
381
+ }
382
+
383
+ try {
384
+ const instance = await teamManager.startTeam(template, defaultCwd, overrides);
385
+ const result = {
386
+ id: instance.id,
387
+ templateName: instance.templateName,
388
+ rootAgentId: instance.result.rootId,
389
+ companionAgentIds: instance.result.companionIds,
390
+ taskMode: instance.runtime.getTaskMode(),
391
+ strategy: instance.runtime.getStrategyName(),
392
+ };
393
+
394
+ if (broadcast) {
395
+ broadcast("teams", { type: "team_started", data: result });
396
+ }
397
+
398
+ res.status(201).json(result);
399
+ } catch (err) {
400
+ const message = err instanceof Error ? err.message : String(err);
401
+ return sendError(res, 500, "TEAM_START_FAILED", message);
402
+ }
403
+ });
404
+
405
+ // GET /api/teams — List running team instances
406
+ app.get("/api/teams", (_req: Request, res: Response) => {
407
+ const instances = teamManager.getInstances();
408
+ res.json(instances.map((inst) => ({
409
+ id: inst.id,
410
+ templateName: inst.templateName,
411
+ rootAgentId: inst.result.rootId,
412
+ companionAgentIds: inst.result.companionIds,
413
+ taskMode: inst.runtime.getTaskMode(),
414
+ strategy: inst.runtime.getStrategyName(),
415
+ })));
416
+ });
417
+
418
+ // GET /api/teams/:id — Get team instance details
419
+ app.get("/api/teams/:id", (req: Request, res: Response) => {
420
+ const instance = teamManager.getInstance(req.params.id);
421
+ if (!instance) {
422
+ return sendError(res, 404, "TEAM_NOT_FOUND", `No team instance '${req.params.id}'`);
423
+ }
424
+
425
+ const manifest = instance.runtime.getManifest();
426
+ res.json({
427
+ id: instance.id,
428
+ templateName: instance.templateName,
429
+ rootAgentId: instance.result.rootId,
430
+ companionAgentIds: instance.result.companionIds,
431
+ taskMode: instance.runtime.getTaskMode(),
432
+ strategy: instance.runtime.getStrategyName(),
433
+ roles: manifest.roles,
434
+ communication: manifest.communication,
435
+ });
436
+ });
437
+
438
+ // DELETE /api/teams/:id — Teardown a team instance
439
+ app.delete("/api/teams/:id", async (req: Request, res: Response) => {
440
+ const instance = teamManager.getInstance(req.params.id);
441
+ if (!instance) {
442
+ return sendError(res, 404, "TEAM_NOT_FOUND", `No team instance '${req.params.id}'`);
443
+ }
444
+
445
+ try {
446
+ await teamManager.stopTeam(req.params.id);
447
+
448
+ if (broadcast) {
449
+ broadcast("teams", { type: "team_stopped", data: { id: req.params.id } });
450
+ }
451
+
452
+ res.json({ success: true });
453
+ } catch (err) {
454
+ const message = err instanceof Error ? err.message : String(err);
455
+ return sendError(res, 500, "TEAM_STOP_FAILED", message);
456
+ }
457
+ });
458
+ }
459
+
350
460
  // ─────────────────────────────────────────────────────────────────
351
461
  // Create API Server
352
462
  // ─────────────────────────────────────────────────────────────────
@@ -568,8 +678,11 @@ export function createAPIServer(
568
678
  res.json(status);
569
679
  });
570
680
 
571
- // GET /api/team - Get active team info
681
+ // GET /api/team - Get active team info (DEPRECATED: use GET /api/teams)
572
682
  app.get("/api/team", (_req: Request, res: Response) => {
683
+ res.set("Deprecation", "true");
684
+ res.set("Link", '</api/teams>; rel="successor-version"');
685
+
573
686
  // Check for team config in EventStore
574
687
  const statusEvents = eventStore.query({ type: "status", limit: 50 });
575
688
  const teamConfigEvent = statusEvents.find(
@@ -591,6 +704,9 @@ export function createAPIServer(
591
704
  });
592
705
  });
593
706
 
707
+ // Register dynamic team management routes
708
+ registerTeamRoutes(app, services.teamManager, process.cwd(), sendError, broadcastToChannel);
709
+
594
710
  // ─────────────────────────────────────────────────────────────────
595
711
  // Metrics Endpoints (Phase 5)
596
712
  // ─────────────────────────────────────────────────────────────────
@@ -1175,7 +1291,7 @@ export function createAPIServer(
1175
1291
  const gracePeriod = options?.force ? 0 : shutdownGracePeriodMs;
1176
1292
 
1177
1293
  // 1. Stop accepting new connections
1178
- server.close();
1294
+ await new Promise<void>((resolve) => server.close(() => resolve()));
1179
1295
 
1180
1296
  // 2. Wait grace period for in-flight work
1181
1297
  if (gracePeriod > 0) {
@@ -1259,10 +1375,10 @@ export function createAPIServer(
1259
1375
  * @returns Express app
1260
1376
  */
1261
1377
  export function createAPIApp(
1262
- services: Pick<APIServices, "eventStore" | "agentManager" | "taskManager" | "messageRouter"> & Pick<Partial<APIServices>, "mailService" | "conversationMap">,
1263
- config: { cors?: boolean; serverToken?: string } = {}
1378
+ services: Pick<APIServices, "eventStore" | "agentManager" | "taskManager" | "messageRouter"> & Pick<Partial<APIServices>, "mailService" | "conversationMap" | "teamManager">,
1379
+ config: { cors?: boolean; serverToken?: string; defaultCwd?: string } = {}
1264
1380
  ): Express {
1265
- const { cors = true, serverToken } = config;
1381
+ const { cors = true, serverToken, defaultCwd } = config;
1266
1382
  const { agentManager, taskManager, messageRouter } = services;
1267
1383
 
1268
1384
  // Create shared state
@@ -1823,6 +1939,15 @@ export function createAPIApp(
1823
1939
  // Register conversation API routes (if mail service available)
1824
1940
  registerConversationRoutes(app, services, sendError);
1825
1941
 
1942
+ // Register dynamic team management routes
1943
+ registerTeamRoutes(
1944
+ app,
1945
+ services.teamManager,
1946
+ defaultCwd ?? process.cwd(),
1947
+ sendError,
1948
+ state.broadcast,
1949
+ );
1950
+
1826
1951
  return app;
1827
1952
  }
1828
1953
 
package/src/api/types.ts CHANGED
@@ -184,7 +184,9 @@ export type WSMessageType =
184
184
  | "status"
185
185
  | "error"
186
186
  | "conversation_update"
187
- | "turn_added";
187
+ | "turn_added"
188
+ | "team_started"
189
+ | "team_stopped";
188
190
 
189
191
  export interface WSMessage {
190
192
  type: WSMessageType;
package/src/cli/acp.ts CHANGED
@@ -48,6 +48,7 @@ import { createAgentManager } from "../agent/agent-manager.js";
48
48
  import { createTaskManager } from "../task/task-manager.js";
49
49
  import { createMessageRouter } from "../router/message-router.js";
50
50
  import { MacroAgent } from "../acp/macro-agent.js";
51
+ import { TeamManager } from "../teams/team-manager.js";
51
52
  import {
52
53
  createCombinedServer,
53
54
  type CombinedServer,
@@ -237,6 +238,24 @@ async function main() {
237
238
  agentTokenManager = new AgentTokenManager();
238
239
  }
239
240
 
241
+ // Create WorkspaceManager for workspace isolation (optional — requires git repo)
242
+ let workspaceManager: import("../workspace/types.js").WorkspaceManager | undefined;
243
+ try {
244
+ const { createWorkspaceManager } = await import("../workspace/workspace-manager.js");
245
+ const poolSize = parseInt(process.env.MACRO_WORKSPACE_POOL_SIZE ?? "10", 10);
246
+ workspaceManager = createWorkspaceManager({
247
+ enabled: true,
248
+ repoPath: defaultCwd,
249
+ pool: {
250
+ enabled: poolSize > 0,
251
+ maxSize: poolSize,
252
+ },
253
+ });
254
+ console.error(`[acp] WorkspaceManager created (pool: ${poolSize})`);
255
+ } catch (err) {
256
+ console.error(`[acp] WorkspaceManager not available: ${err instanceof Error ? err.message : err}`);
257
+ }
258
+
240
259
  // Now create the agentManager with the real router
241
260
  agentManager = createAgentManager(eventStore, messageRouter, {
242
261
  serverUrl,
@@ -244,6 +263,7 @@ async function main() {
244
263
  agentTokenManager: serverUrl ? agentTokenManager : undefined,
245
264
  taskBackend: mergedConfig.task?.backend,
246
265
  openTasksSocketPath: mergedConfig.task?.opentasks?.socket_path,
266
+ workspaceManager,
247
267
  });
248
268
  const taskManager = createTaskManager(eventStore);
249
269
 
@@ -304,6 +324,49 @@ async function main() {
304
324
  }
305
325
  }
306
326
 
327
+ // Create TeamManager for dynamic team loading (server mode only)
328
+ const teamManager = new TeamManager({ agentManager, messageRouter, eventStore, workspaceManager, taskBackend });
329
+ teamManager.install(); // Composite interceptor/filter/validator
330
+
331
+ // Seed default team templates if they don't exist yet
332
+ try {
333
+ const { seedDefaultTemplates } = await import("../teams/seed-defaults.js");
334
+ const seeded = await seedDefaultTemplates(defaultCwd);
335
+ if (seeded.length > 0) {
336
+ console.error(`[acp] Seeded default team templates: ${seeded.join(", ")}`);
337
+ }
338
+ } catch (err) {
339
+ console.error(`[acp] Failed to seed default templates: ${err}`);
340
+ }
341
+
342
+ // Auto-start teams from config
343
+ if (!options.acp) {
344
+ // Default team (backward compat)
345
+ if (mergedConfig.team) {
346
+ try {
347
+ const instance = await teamManager.startTeam(mergedConfig.team, defaultCwd);
348
+ console.error(`[acp] Team '${mergedConfig.team}' started (${instance.id}): root=${instance.result.rootId}, companions=[${instance.result.companionIds.join(", ")}]`);
349
+ } catch (err) {
350
+ console.error(`[acp] Failed to start team '${mergedConfig.team}': ${err}`);
351
+ }
352
+ }
353
+
354
+ // Additional teams with autoStart (skip if already started as default team)
355
+ if (mergedConfig.teams) {
356
+ for (const [name, entry] of Object.entries(mergedConfig.teams)) {
357
+ if (!entry.autoStart) continue;
358
+ const template = entry.template ?? name;
359
+ if (template === mergedConfig.team) continue; // Already started above
360
+ try {
361
+ const instance = await teamManager.startTeam(template, defaultCwd);
362
+ console.error(`[acp] Team '${template}' started (${instance.id}): root=${instance.result.rootId}, companions=[${instance.result.companionIds.join(", ")}]`);
363
+ } catch (err) {
364
+ console.error(`[acp] Failed to start team '${template}': ${err}`);
365
+ }
366
+ }
367
+ }
368
+ }
369
+
307
370
  // Create ActivityWatcher for event-driven agent waking
308
371
  const sessionProvider = createSessionProviderFromAgentManager(agentManager);
309
372
  const wakeHandler = createWakeHandler(sessionProvider, agentManager);
@@ -401,6 +464,10 @@ async function main() {
401
464
  }
402
465
  }
403
466
 
467
+ try { await teamManager.teardownAll(); } catch (err) {
468
+ console.error(`[cleanup] TeamManager teardown failed: ${err}`);
469
+ }
470
+
404
471
  try { await agentManager.close(); } catch (err) {
405
472
  console.error(`[cleanup] AgentManager close failed: ${err}`);
406
473
  }
@@ -456,7 +523,7 @@ async function main() {
456
523
  const port = options.port ?? mergedConfig.port ?? 3001;
457
524
 
458
525
  combinedServer = createCombinedServer(
459
- { eventStore, agentManager, taskManager, messageRouter, activityWatcher, taskBackend, taskToolProvider, taskToolContext, agentTokenManager, getConnectedProjects },
526
+ { eventStore, agentManager, taskManager, messageRouter, activityWatcher, taskBackend, taskToolProvider, taskToolContext, agentTokenManager, getConnectedProjects, teamManager, workspaceManager },
460
527
  { port, host, defaultCwd, serverToken, noAuth }
461
528
  );
462
529
 
package/src/cli/index.ts CHANGED
@@ -170,6 +170,9 @@ program
170
170
  }
171
171
 
172
172
  // Determine team name: CLI flag > merged config
173
+ if (options.team) {
174
+ console.warn(chalk.yellow("[DEPRECATED] --team flag on multiagent-cli start is deprecated. Use 'multiagent' with .multiagent/config.json instead."));
175
+ }
173
176
  const teamName = options.team ?? mergedConfig.team;
174
177
 
175
178
  // Load and initialize team if specified
@@ -715,7 +718,8 @@ program
715
718
  const path = await import("path");
716
719
  const os = await import("os");
717
720
 
718
- const storagePath = path.join(os.homedir(), ".multiagent", "store.json");
721
+ const baseDir = process.env.MACRO_AGENT_HOME || path.join(os.homedir(), ".multiagent");
722
+ const storagePath = path.join(baseDir, "store.json");
719
723
 
720
724
  if (fs.existsSync(storagePath)) {
721
725
  fs.unlinkSync(storagePath);
package/src/cli/mcp.ts CHANGED
@@ -253,12 +253,18 @@ async function startLegacy() {
253
253
  }
254
254
  });
255
255
 
256
- // Read team config from EventStore
256
+ // Read team config from EventStore (scoped by MACRO_TEAM_NAME for multi-team)
257
257
  let teamTaskMode: string | undefined;
258
+ const myTeamName = process.env.MACRO_TEAM_NAME;
258
259
  const teamEvents = eventStore.query({ type: "status", limit: 50 });
259
- const teamConfigEvent = teamEvents.find(
260
- (e) => e.payload?.team_config != null
261
- );
260
+ const teamConfigEvent = teamEvents.find((e) => {
261
+ const tc = e.payload?.team_config as Record<string, unknown> | undefined;
262
+ if (!tc) return false;
263
+ // If agent has a team name, find that specific team's config
264
+ if (myTeamName) return tc.teamName === myTeamName;
265
+ // Fallback: first team_config found (backward compat)
266
+ return true;
267
+ });
262
268
  if (teamConfigEvent?.payload?.team_config) {
263
269
  const tc = teamConfigEvent.payload.team_config as Record<string, unknown>;
264
270
  teamTaskMode = tc.taskMode as string | undefined;
@@ -282,15 +288,23 @@ async function startLegacy() {
282
288
 
283
289
  const strategyName = tc.strategy as string | undefined;
284
290
  if (strategyName) {
285
- try {
286
- const { defaultStrategyRegistry } = await import("../workspace/strategies/registry.js");
287
- integrationStrategy = defaultStrategyRegistry.get(
288
- strategyName,
289
- tc.strategyConfig as Record<string, unknown> | undefined
290
- );
291
- debugLog(`[MCP] Instantiated '${strategyName}' integration strategy`);
292
- } catch (err) {
293
- debugLog(`[MCP] Failed to instantiate strategy '${strategyName}': ${err}`);
291
+ // Queue strategy requires merge queue which is only available in the main process.
292
+ // Skip it so the worker handler falls through to MERGE_REQUEST signal emission,
293
+ // which the main server's TeamRuntime polls for and submits to the real merge queue.
294
+ if (strategyName === "queue") {
295
+ debugLog(`[MCP] Skipping queue strategy in subprocess (no merge queue available). ` +
296
+ `Worker done() will emit MERGE_REQUEST signal for main process to handle.`);
297
+ } else {
298
+ try {
299
+ const { defaultStrategyRegistry } = await import("../workspace/strategies/registry.js");
300
+ integrationStrategy = defaultStrategyRegistry.get(
301
+ strategyName,
302
+ tc.strategyConfig as Record<string, unknown> | undefined
303
+ );
304
+ debugLog(`[MCP] Instantiated '${strategyName}' integration strategy`);
305
+ } catch (err) {
306
+ debugLog(`[MCP] Failed to instantiate strategy '${strategyName}': ${err}`);
307
+ }
294
308
  }
295
309
  }
296
310
  }
@@ -17,6 +17,16 @@ import * as path from "path";
17
17
  // Types
18
18
  // =============================================================================
19
19
 
20
+ /**
21
+ * Entry in the `teams` config for declaring additional team templates.
22
+ */
23
+ export interface TeamConfigEntry {
24
+ /** Template name (defaults to the key) */
25
+ template?: string;
26
+ /** Auto-start on server boot (default: false) */
27
+ autoStart?: boolean;
28
+ }
29
+
20
30
  /**
21
31
  * Typed configuration schema for multiagent.
22
32
  *
@@ -24,9 +34,12 @@ import * as path from "path";
24
34
  * Environment variables override file-based config.
25
35
  */
26
36
  export interface MultiagentConfig {
27
- /** Team template name to load on startup */
37
+ /** Default team template name to load on startup */
28
38
  team?: string;
29
39
 
40
+ /** Additional teams available for dynamic or auto-start loading */
41
+ teams?: Record<string, TeamConfigEntry>;
42
+
30
43
  /** Server port (default: 3001) */
31
44
  port?: number;
32
45
 
@@ -134,10 +147,11 @@ export function getProjectConfigPath(projectPath?: string): string {
134
147
  /**
135
148
  * Get the global config file path.
136
149
  *
137
- * @returns Absolute path to ~/.multiagent/config.json
150
+ * @returns Absolute path to ~/.multiagent/config.json (or MACRO_AGENT_HOME/config.json)
138
151
  */
139
152
  export function getGlobalConfigPath(): string {
140
- return path.join(os.homedir(), CONFIG_DIR, CONFIG_FILE);
153
+ const globalDir = process.env.MACRO_AGENT_HOME || path.join(os.homedir(), CONFIG_DIR);
154
+ return path.join(globalDir, CONFIG_FILE);
141
155
  }
142
156
 
143
157
  // =============================================================================
@@ -249,6 +263,16 @@ export function loadMergedConfig(projectPath?: string): MultiagentConfig {
249
263
  merged.auth = { ...(merged.auth ?? {}), disabled: true };
250
264
  }
251
265
 
266
+ // MACRO_TEAMS: comma-separated template names to auto-start
267
+ if (process.env.MACRO_TEAMS) {
268
+ const names = process.env.MACRO_TEAMS.split(",").map(s => s.trim()).filter(Boolean);
269
+ const teams: Record<string, TeamConfigEntry> = { ...(merged.teams ?? {}) };
270
+ for (const name of names) {
271
+ teams[name] = { ...teams[name], autoStart: true };
272
+ }
273
+ merged.teams = teams;
274
+ }
275
+
252
276
  return merged;
253
277
  }
254
278
 
package/src/index.ts CHANGED
@@ -292,3 +292,6 @@ export {
292
292
  type WakeSessionProvider,
293
293
  type WakeAgentOptions,
294
294
  } from './agent/wake.js';
295
+
296
+ // Teams - template seeding
297
+ export { seedDefaultTemplates } from './teams/seed-defaults.js';
@@ -1752,6 +1752,37 @@ describe("handlers", () => {
1752
1752
 
1753
1753
  expect(handler).toBeDefined();
1754
1754
  });
1755
+
1756
+ it("should return worker handler for team role with workspace.worktree capability", () => {
1757
+ const deps = createMockDeps();
1758
+ const registry = createHandlerRegistry(deps as any);
1759
+
1760
+ // "developer" extends "worker" — gets workspace.worktree capability
1761
+ const handler = getHandler("developer", registry, deps as any, ["workspace.worktree"]);
1762
+
1763
+ // Should be the worker handler, not generic
1764
+ expect(handler).toBe(registry.get("worker"));
1765
+ });
1766
+
1767
+ it("should return integrator handler for team role with workspace.integrate capability", () => {
1768
+ const deps = createMockDeps();
1769
+ const registry = createHandlerRegistry(deps as any);
1770
+
1771
+ const handler = getHandler("merger", registry, deps as any, ["workspace.integrate"]);
1772
+
1773
+ expect(handler).toBe(registry.get("integrator"));
1774
+ });
1775
+
1776
+ it("should return generic handler when capabilities have no workspace match", () => {
1777
+ const deps = createMockDeps();
1778
+ const registry = createHandlerRegistry(deps as any);
1779
+
1780
+ const handler = getHandler("watcher", registry, deps as any, ["msg.send", "file.read"]);
1781
+
1782
+ // No workspace capability → falls through to generic
1783
+ expect(handler).not.toBe(registry.get("worker"));
1784
+ expect(handler).not.toBe(registry.get("integrator"));
1785
+ });
1755
1786
  });
1756
1787
 
1757
1788
  describe("dispatchDone", () => {
@@ -1795,6 +1826,28 @@ describe("handlers", () => {
1795
1826
  expect(result.signalsEmitted).toContain("STATUS");
1796
1827
  });
1797
1828
 
1829
+ it("should dispatch team role with workspace.worktree to worker handler", async () => {
1830
+ const deps = createMockDeps();
1831
+ const context: LifecycleContext = {
1832
+ agentId: "developer-1",
1833
+ role: "developer",
1834
+ capabilities: ["workspace.worktree", "lifecycle.done", "file.read"],
1835
+ };
1836
+ const args: DoneArgs = { status: "completed" };
1837
+ const cleanupStatus: CleanupStatus = { ready: true };
1838
+
1839
+ const result = await dispatchDone(
1840
+ context,
1841
+ args,
1842
+ cleanupStatus,
1843
+ deps as any,
1844
+ );
1845
+
1846
+ // Should have gone through the worker handler path
1847
+ expect(result.shouldTerminate).toBe(true);
1848
+ expect(result.signalsEmitted).toContain("WORKER_DONE");
1849
+ });
1850
+
1798
1851
  it("should use custom registry when provided", async () => {
1799
1852
  const deps = createMockDeps();
1800
1853
  const customHandler = vi.fn().mockResolvedValue({
@@ -111,29 +111,46 @@ export function createHandlerRegistry(
111
111
  }
112
112
 
113
113
  /**
114
- * Get the handler for a given role
114
+ * Get the handler for a given role.
115
115
  *
116
- * Falls back to the generic handler if no role-specific handler exists.
116
+ * Resolution order:
117
+ * 1. Exact role name match (e.g., "worker", "integrator")
118
+ * 2. Dot-prefix match (e.g., "worker.resolver" → "worker")
119
+ * 3. Capability-based match (e.g., "developer" with workspace.worktree → worker handler)
120
+ * 4. Generic fallback handler
117
121
  */
118
122
  export function getHandler(
119
123
  role: string,
120
124
  registry: DoneHandlerRegistry,
121
- deps: AllHandlerDeps
125
+ deps: AllHandlerDeps,
126
+ capabilities?: string[],
122
127
  ): DoneHandler {
123
- // Check for exact match
128
+ // 1. Exact match
124
129
  const handler = registry.get(role);
125
130
  if (handler) {
126
131
  return handler;
127
132
  }
128
133
 
129
- // Check for role prefix match (e.g., "worker.resolver" matches "worker")
134
+ // 2. Dot-prefix match (e.g., "worker.resolver" "worker")
130
135
  const baseRole = role.split(".")[0];
131
136
  const baseHandler = registry.get(baseRole);
132
137
  if (baseHandler) {
133
138
  return baseHandler;
134
139
  }
135
140
 
136
- // Fall back to generic handler
141
+ // 3. Capability-based match (for team-defined roles like "developer" extending "worker")
142
+ if (capabilities) {
143
+ if (capabilities.includes("workspace.worktree")) {
144
+ const workerHandler = registry.get("worker");
145
+ if (workerHandler) return workerHandler;
146
+ }
147
+ if (capabilities.includes("workspace.integrate")) {
148
+ const integratorHandler = registry.get("integrator");
149
+ if (integratorHandler) return integratorHandler;
150
+ }
151
+ }
152
+
153
+ // 4. Generic fallback
137
154
  const genericDeps: GenericHandlerDeps = {
138
155
  messageRouter: deps.messageRouter,
139
156
  };
@@ -158,8 +175,8 @@ export async function dispatchDone(
158
175
  // Use provided registry or create default
159
176
  const handlers = registry ?? createHandlerRegistry(deps);
160
177
 
161
- // Get the handler for this role
162
- const handler = getHandler(context.role, handlers, deps);
178
+ // Get the handler for this role (pass capabilities for team role resolution)
179
+ const handler = getHandler(context.role, handlers, deps, context.capabilities);
163
180
 
164
181
  // Execute the handler
165
182
  return handler(context, args, cleanupStatus);
@@ -117,6 +117,9 @@ export interface LifecycleContext {
117
117
 
118
118
  /** Merge request ID (for resolver workers to track which MR they're resolving) */
119
119
  mrId?: string;
120
+
121
+ /** Resolved capabilities for the agent's role (for capability-based handler dispatch) */
122
+ capabilities?: string[];
120
123
  }
121
124
 
122
125
  /**