macro-agent 0.1.0 → 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 (660) hide show
  1. package/.claude/settings.local.json +3 -1
  2. package/.sudocode/issues.jsonl +28 -0
  3. package/.sudocode/specs.jsonl +8 -0
  4. package/CLAUDE.md +25 -17
  5. package/README.md +11 -29
  6. package/dist/acp/macro-agent.d.ts +15 -0
  7. package/dist/acp/macro-agent.d.ts.map +1 -1
  8. package/dist/acp/macro-agent.js +131 -35
  9. package/dist/acp/macro-agent.js.map +1 -1
  10. package/dist/acp/types.d.ts +32 -1
  11. package/dist/acp/types.d.ts.map +1 -1
  12. package/dist/acp/types.js.map +1 -1
  13. package/dist/agent/agent-manager.d.ts +65 -1
  14. package/dist/agent/agent-manager.d.ts.map +1 -1
  15. package/dist/agent/agent-manager.js +544 -200
  16. package/dist/agent/agent-manager.js.map +1 -1
  17. package/dist/agent/types.d.ts +8 -1
  18. package/dist/agent/types.d.ts.map +1 -1
  19. package/dist/agent/types.js.map +1 -1
  20. package/dist/api/server.d.ts +8 -1
  21. package/dist/api/server.d.ts.map +1 -1
  22. package/dist/api/server.js +136 -8
  23. package/dist/api/server.js.map +1 -1
  24. package/dist/api/types.d.ts +1 -1
  25. package/dist/api/types.d.ts.map +1 -1
  26. package/dist/auth/index.d.ts +2 -0
  27. package/dist/auth/index.d.ts.map +1 -0
  28. package/dist/auth/index.js +2 -0
  29. package/dist/auth/index.js.map +1 -0
  30. package/dist/auth/token.d.ts +41 -0
  31. package/dist/auth/token.d.ts.map +1 -0
  32. package/dist/auth/token.js +73 -0
  33. package/dist/auth/token.js.map +1 -0
  34. package/dist/cli/acp.d.ts +2 -23
  35. package/dist/cli/acp.d.ts.map +1 -1
  36. package/dist/cli/acp.js +197 -61
  37. package/dist/cli/acp.js.map +1 -1
  38. package/dist/cli/index.js +152 -16
  39. package/dist/cli/index.js.map +1 -1
  40. package/dist/cli/mcp.d.ts +6 -0
  41. package/dist/cli/mcp.d.ts.map +1 -1
  42. package/dist/cli/mcp.js +279 -173
  43. package/dist/cli/mcp.js.map +1 -1
  44. package/dist/cli/parse-args.d.ts +20 -0
  45. package/dist/cli/parse-args.d.ts.map +1 -0
  46. package/dist/cli/parse-args.js +43 -0
  47. package/dist/cli/parse-args.js.map +1 -0
  48. package/dist/cli/stable-instance-id.d.ts +8 -0
  49. package/dist/cli/stable-instance-id.d.ts.map +1 -0
  50. package/dist/cli/stable-instance-id.js +14 -0
  51. package/dist/cli/stable-instance-id.js.map +1 -0
  52. package/dist/config/project-config.d.ts +85 -7
  53. package/dist/config/project-config.d.ts.map +1 -1
  54. package/dist/config/project-config.js +133 -20
  55. package/dist/config/project-config.js.map +1 -1
  56. package/dist/index.d.ts +1 -0
  57. package/dist/index.d.ts.map +1 -1
  58. package/dist/index.js +2 -0
  59. package/dist/index.js.map +1 -1
  60. package/dist/lifecycle/handlers/index.d.ts +7 -3
  61. package/dist/lifecycle/handlers/index.d.ts.map +1 -1
  62. package/dist/lifecycle/handlers/index.js +25 -8
  63. package/dist/lifecycle/handlers/index.js.map +1 -1
  64. package/dist/lifecycle/types.d.ts +2 -0
  65. package/dist/lifecycle/types.d.ts.map +1 -1
  66. package/dist/lifecycle/types.js.map +1 -1
  67. package/dist/map/adapter/acp-over-map.d.ts +17 -0
  68. package/dist/map/adapter/acp-over-map.d.ts.map +1 -1
  69. package/dist/map/adapter/acp-over-map.js +384 -23
  70. package/dist/map/adapter/acp-over-map.js.map +1 -1
  71. package/dist/map/adapter/connection-manager.d.ts.map +1 -1
  72. package/dist/map/adapter/connection-manager.js +3 -0
  73. package/dist/map/adapter/connection-manager.js.map +1 -1
  74. package/dist/map/adapter/event-log.d.ts +87 -0
  75. package/dist/map/adapter/event-log.d.ts.map +1 -0
  76. package/dist/map/adapter/event-log.js +122 -0
  77. package/dist/map/adapter/event-log.js.map +1 -0
  78. package/dist/map/adapter/event-translator.js +6 -6
  79. package/dist/map/adapter/event-translator.js.map +1 -1
  80. package/dist/map/adapter/extensions/agent-lifecycle.d.ts +82 -0
  81. package/dist/map/adapter/extensions/agent-lifecycle.d.ts.map +1 -0
  82. package/dist/map/adapter/extensions/agent-lifecycle.js +164 -0
  83. package/dist/map/adapter/extensions/agent-lifecycle.js.map +1 -0
  84. package/dist/map/adapter/extensions/index.d.ts +13 -1
  85. package/dist/map/adapter/extensions/index.d.ts.map +1 -1
  86. package/dist/map/adapter/extensions/index.js +61 -0
  87. package/dist/map/adapter/extensions/index.js.map +1 -1
  88. package/dist/map/adapter/extensions/mcp-bridge.d.ts +57 -0
  89. package/dist/map/adapter/extensions/mcp-bridge.d.ts.map +1 -0
  90. package/dist/map/adapter/extensions/mcp-bridge.js +745 -0
  91. package/dist/map/adapter/extensions/mcp-bridge.js.map +1 -0
  92. package/dist/map/adapter/extensions/rename.d.ts +29 -0
  93. package/dist/map/adapter/extensions/rename.d.ts.map +1 -0
  94. package/dist/map/adapter/extensions/rename.js +49 -0
  95. package/dist/map/adapter/extensions/rename.js.map +1 -0
  96. package/dist/map/adapter/extensions/streams.d.ts +95 -0
  97. package/dist/map/adapter/extensions/streams.d.ts.map +1 -0
  98. package/dist/map/adapter/extensions/streams.js +515 -0
  99. package/dist/map/adapter/extensions/streams.js.map +1 -0
  100. package/dist/map/adapter/extensions/task.d.ts.map +1 -1
  101. package/dist/map/adapter/extensions/task.js +10 -0
  102. package/dist/map/adapter/extensions/task.js.map +1 -1
  103. package/dist/map/adapter/extensions/update-metadata.d.ts +29 -0
  104. package/dist/map/adapter/extensions/update-metadata.d.ts.map +1 -0
  105. package/dist/map/adapter/extensions/update-metadata.js +67 -0
  106. package/dist/map/adapter/extensions/update-metadata.js.map +1 -0
  107. package/dist/map/adapter/index.d.ts +2 -1
  108. package/dist/map/adapter/index.d.ts.map +1 -1
  109. package/dist/map/adapter/index.js +10 -2
  110. package/dist/map/adapter/index.js.map +1 -1
  111. package/dist/map/adapter/interface.d.ts +2 -0
  112. package/dist/map/adapter/interface.d.ts.map +1 -1
  113. package/dist/map/adapter/map-adapter.d.ts +3 -0
  114. package/dist/map/adapter/map-adapter.d.ts.map +1 -1
  115. package/dist/map/adapter/map-adapter.js +258 -35
  116. package/dist/map/adapter/map-adapter.js.map +1 -1
  117. package/dist/map/adapter/subscription-manager.d.ts.map +1 -1
  118. package/dist/map/adapter/subscription-manager.js +5 -1
  119. package/dist/map/adapter/subscription-manager.js.map +1 -1
  120. package/dist/map/adapter/types.d.ts +3 -1
  121. package/dist/map/adapter/types.d.ts.map +1 -1
  122. package/dist/mcp/map-client.d.ts +39 -0
  123. package/dist/mcp/map-client.d.ts.map +1 -0
  124. package/dist/mcp/map-client.js +129 -0
  125. package/dist/mcp/map-client.js.map +1 -0
  126. package/dist/mcp/mcp-server.d.ts +16 -0
  127. package/dist/mcp/mcp-server.d.ts.map +1 -1
  128. package/dist/mcp/mcp-server.js +125 -88
  129. package/dist/mcp/mcp-server.js.map +1 -1
  130. package/dist/mcp/tools/done.d.ts.map +1 -1
  131. package/dist/mcp/tools/done.js +18 -0
  132. package/dist/mcp/tools/done.js.map +1 -1
  133. package/dist/mcp/types.d.ts +9 -1
  134. package/dist/mcp/types.d.ts.map +1 -1
  135. package/dist/mcp/types.js.map +1 -1
  136. package/dist/metrics/metrics.js +1 -1
  137. package/dist/metrics/metrics.js.map +1 -1
  138. package/dist/roles/builtin/coordinator.d.ts.map +1 -1
  139. package/dist/roles/builtin/coordinator.js +2 -1
  140. package/dist/roles/builtin/coordinator.js.map +1 -1
  141. package/dist/roles/builtin/integrator.d.ts.map +1 -1
  142. package/dist/roles/builtin/integrator.js +2 -1
  143. package/dist/roles/builtin/integrator.js.map +1 -1
  144. package/dist/roles/builtin/worker.d.ts.map +1 -1
  145. package/dist/roles/builtin/worker.js +3 -1
  146. package/dist/roles/builtin/worker.js.map +1 -1
  147. package/dist/roles/capabilities.d.ts +9 -1
  148. package/dist/roles/capabilities.d.ts.map +1 -1
  149. package/dist/roles/capabilities.js +27 -7
  150. package/dist/roles/capabilities.js.map +1 -1
  151. package/dist/roles/config-loader.d.ts +6 -6
  152. package/dist/roles/config-loader.d.ts.map +1 -1
  153. package/dist/roles/config-loader.js +8 -7
  154. package/dist/roles/config-loader.js.map +1 -1
  155. package/dist/roles/registry.d.ts +2 -2
  156. package/dist/roles/registry.js +2 -2
  157. package/dist/roles/types.d.ts +3 -1
  158. package/dist/roles/types.d.ts.map +1 -1
  159. package/dist/server/combined-server.d.ts +28 -1
  160. package/dist/server/combined-server.d.ts.map +1 -1
  161. package/dist/server/combined-server.js +111 -8
  162. package/dist/server/combined-server.js.map +1 -1
  163. package/dist/store/event-store.d.ts +2 -1
  164. package/dist/store/event-store.d.ts.map +1 -1
  165. package/dist/store/event-store.js +80 -24
  166. package/dist/store/event-store.js.map +1 -1
  167. package/dist/store/instance.d.ts +1 -1
  168. package/dist/store/instance.d.ts.map +1 -1
  169. package/dist/store/instance.js +2 -2
  170. package/dist/store/instance.js.map +1 -1
  171. package/dist/store/types/agents.d.ts +23 -0
  172. package/dist/store/types/agents.d.ts.map +1 -1
  173. package/dist/store/types/events.d.ts +1 -1
  174. package/dist/store/types/events.d.ts.map +1 -1
  175. package/dist/task/backend/index.d.ts +47 -29
  176. package/dist/task/backend/index.d.ts.map +1 -1
  177. package/dist/task/backend/index.js +109 -71
  178. package/dist/task/backend/index.js.map +1 -1
  179. package/dist/task/backend/memory.d.ts +1 -0
  180. package/dist/task/backend/memory.d.ts.map +1 -1
  181. package/dist/task/backend/memory.js +3 -0
  182. package/dist/task/backend/memory.js.map +1 -1
  183. package/dist/task/backend/opentasks/backend.d.ts +140 -0
  184. package/dist/task/backend/opentasks/backend.d.ts.map +1 -0
  185. package/dist/task/backend/opentasks/backend.js +1023 -0
  186. package/dist/task/backend/opentasks/backend.js.map +1 -0
  187. package/dist/task/backend/opentasks/client.d.ts +337 -0
  188. package/dist/task/backend/opentasks/client.d.ts.map +1 -0
  189. package/dist/task/backend/opentasks/client.js +225 -0
  190. package/dist/task/backend/opentasks/client.js.map +1 -0
  191. package/dist/task/backend/opentasks/daemon-manager.d.ts +89 -0
  192. package/dist/task/backend/opentasks/daemon-manager.d.ts.map +1 -0
  193. package/dist/task/backend/opentasks/daemon-manager.js +195 -0
  194. package/dist/task/backend/opentasks/daemon-manager.js.map +1 -0
  195. package/dist/task/backend/opentasks/index.d.ts +21 -0
  196. package/dist/task/backend/opentasks/index.d.ts.map +1 -0
  197. package/dist/task/backend/opentasks/index.js +21 -0
  198. package/dist/task/backend/opentasks/index.js.map +1 -0
  199. package/dist/task/backend/opentasks/mapping.d.ts +48 -0
  200. package/dist/task/backend/opentasks/mapping.d.ts.map +1 -0
  201. package/dist/task/backend/opentasks/mapping.js +77 -0
  202. package/dist/task/backend/opentasks/mapping.js.map +1 -0
  203. package/dist/task/backend/types.d.ts +33 -53
  204. package/dist/task/backend/types.d.ts.map +1 -1
  205. package/dist/task/backend/types.js +7 -11
  206. package/dist/task/backend/types.js.map +1 -1
  207. package/dist/task/backend/unified-tool-provider.d.ts +57 -0
  208. package/dist/task/backend/unified-tool-provider.d.ts.map +1 -0
  209. package/dist/task/backend/unified-tool-provider.js +623 -0
  210. package/dist/task/backend/unified-tool-provider.js.map +1 -0
  211. package/dist/teams/index.d.ts +3 -1
  212. package/dist/teams/index.d.ts.map +1 -1
  213. package/dist/teams/index.js +2 -0
  214. package/dist/teams/index.js.map +1 -1
  215. package/dist/teams/seed-defaults.d.ts +20 -0
  216. package/dist/teams/seed-defaults.d.ts.map +1 -0
  217. package/dist/teams/seed-defaults.js +71 -0
  218. package/dist/teams/seed-defaults.js.map +1 -0
  219. package/dist/teams/team-loader.d.ts +7 -3
  220. package/dist/teams/team-loader.d.ts.map +1 -1
  221. package/dist/teams/team-loader.js +156 -164
  222. package/dist/teams/team-loader.js.map +1 -1
  223. package/dist/teams/team-manager.d.ts +112 -0
  224. package/dist/teams/team-manager.d.ts.map +1 -0
  225. package/dist/teams/team-manager.js +305 -0
  226. package/dist/teams/team-manager.js.map +1 -0
  227. package/dist/teams/team-runtime.d.ts +125 -19
  228. package/dist/teams/team-runtime.d.ts.map +1 -1
  229. package/dist/teams/team-runtime.js +529 -119
  230. package/dist/teams/team-runtime.js.map +1 -1
  231. package/dist/teams/types.d.ts +41 -151
  232. package/dist/teams/types.d.ts.map +1 -1
  233. package/dist/teams/types.js +2 -3
  234. package/dist/teams/types.js.map +1 -1
  235. package/docs/architecture.md +7 -6
  236. package/docs/configuration.md +26 -62
  237. package/docs/implementation-details.md +5 -5
  238. package/docs/implementation-summary.md +17 -17
  239. package/docs/plan-self-driving-support.md +4 -4
  240. package/docs/spec-self-driving-support.md +10 -10
  241. package/docs/team-templates.md +2 -2
  242. package/docs/teams.md +76 -3
  243. package/docs/troubleshooting.md +10 -11
  244. package/package.json +7 -4
  245. package/references/minimem/.claude/settings.json +7 -0
  246. package/references/minimem/.sudocode/issues.jsonl +18 -0
  247. package/references/minimem/.sudocode/specs.jsonl +1 -0
  248. package/references/minimem/CLAUDE.md +310 -0
  249. package/references/minimem/README.md +562 -0
  250. package/references/minimem/claude-plugin/.claude-plugin/plugin.json +10 -0
  251. package/references/minimem/claude-plugin/.mcp.json +7 -0
  252. package/references/minimem/claude-plugin/README.md +158 -0
  253. package/references/minimem/claude-plugin/commands/recall.md +47 -0
  254. package/references/minimem/claude-plugin/commands/remember.md +41 -0
  255. package/references/minimem/claude-plugin/hooks/__tests__/hooks.test.ts +272 -0
  256. package/references/minimem/claude-plugin/hooks/hooks.json +27 -0
  257. package/references/minimem/claude-plugin/hooks/session-end.sh +86 -0
  258. package/references/minimem/claude-plugin/hooks/session-start.sh +85 -0
  259. package/references/minimem/claude-plugin/skills/memory/SKILL.md +108 -0
  260. package/references/minimem/media/banner.png +0 -0
  261. package/references/minimem/package-lock.json +5373 -0
  262. package/references/minimem/package.json +72 -0
  263. package/references/minimem/scripts/postbuild.js +35 -0
  264. package/references/minimem/src/__tests__/edge-cases.test.ts +371 -0
  265. package/references/minimem/src/__tests__/errors.test.ts +265 -0
  266. package/references/minimem/src/__tests__/helpers.ts +199 -0
  267. package/references/minimem/src/__tests__/internal.test.ts +407 -0
  268. package/references/minimem/src/__tests__/knowledge.test.ts +287 -0
  269. package/references/minimem/src/__tests__/minimem.integration.test.ts +1127 -0
  270. package/references/minimem/src/__tests__/session.test.ts +190 -0
  271. package/references/minimem/src/cli/__tests__/commands.test.ts +759 -0
  272. package/references/minimem/src/cli/commands/__tests__/conflicts.test.ts +141 -0
  273. package/references/minimem/src/cli/commands/append.ts +76 -0
  274. package/references/minimem/src/cli/commands/config.ts +262 -0
  275. package/references/minimem/src/cli/commands/conflicts.ts +413 -0
  276. package/references/minimem/src/cli/commands/daemon.ts +169 -0
  277. package/references/minimem/src/cli/commands/index.ts +12 -0
  278. package/references/minimem/src/cli/commands/init.ts +88 -0
  279. package/references/minimem/src/cli/commands/mcp.ts +177 -0
  280. package/references/minimem/src/cli/commands/push-pull.ts +213 -0
  281. package/references/minimem/src/cli/commands/search.ts +158 -0
  282. package/references/minimem/src/cli/commands/status.ts +84 -0
  283. package/references/minimem/src/cli/commands/sync-init.ts +290 -0
  284. package/references/minimem/src/cli/commands/sync.ts +70 -0
  285. package/references/minimem/src/cli/commands/upsert.ts +197 -0
  286. package/references/minimem/src/cli/config.ts +584 -0
  287. package/references/minimem/src/cli/index.ts +264 -0
  288. package/references/minimem/src/cli/shared.ts +161 -0
  289. package/references/minimem/src/cli/sync/__tests__/central.test.ts +152 -0
  290. package/references/minimem/src/cli/sync/__tests__/conflicts.test.ts +209 -0
  291. package/references/minimem/src/cli/sync/__tests__/daemon.test.ts +118 -0
  292. package/references/minimem/src/cli/sync/__tests__/detection.test.ts +207 -0
  293. package/references/minimem/src/cli/sync/__tests__/integration.test.ts +476 -0
  294. package/references/minimem/src/cli/sync/__tests__/registry.test.ts +363 -0
  295. package/references/minimem/src/cli/sync/__tests__/state.test.ts +255 -0
  296. package/references/minimem/src/cli/sync/__tests__/validation.test.ts +193 -0
  297. package/references/minimem/src/cli/sync/__tests__/watcher.test.ts +178 -0
  298. package/references/minimem/src/cli/sync/central.ts +292 -0
  299. package/references/minimem/src/cli/sync/conflicts.ts +204 -0
  300. package/references/minimem/src/cli/sync/daemon.ts +407 -0
  301. package/references/minimem/src/cli/sync/detection.ts +138 -0
  302. package/references/minimem/src/cli/sync/index.ts +107 -0
  303. package/references/minimem/src/cli/sync/operations.ts +373 -0
  304. package/references/minimem/src/cli/sync/registry.ts +279 -0
  305. package/references/minimem/src/cli/sync/state.ts +355 -0
  306. package/references/minimem/src/cli/sync/validation.ts +206 -0
  307. package/references/minimem/src/cli/sync/watcher.ts +234 -0
  308. package/references/minimem/src/cli/version.ts +34 -0
  309. package/references/minimem/src/core/index.ts +9 -0
  310. package/references/minimem/src/core/indexer.ts +628 -0
  311. package/references/minimem/src/core/searcher.ts +221 -0
  312. package/references/minimem/src/db/schema.ts +183 -0
  313. package/references/minimem/src/db/sqlite-vec.ts +24 -0
  314. package/references/minimem/src/embeddings/__tests__/embeddings.test.ts +431 -0
  315. package/references/minimem/src/embeddings/batch-gemini.ts +392 -0
  316. package/references/minimem/src/embeddings/batch-openai.ts +409 -0
  317. package/references/minimem/src/embeddings/embeddings.ts +434 -0
  318. package/references/minimem/src/index.ts +109 -0
  319. package/references/minimem/src/internal.ts +299 -0
  320. package/references/minimem/src/minimem.ts +1276 -0
  321. package/references/minimem/src/search/__tests__/hybrid.test.ts +247 -0
  322. package/references/minimem/src/search/graph.ts +234 -0
  323. package/references/minimem/src/search/hybrid.ts +151 -0
  324. package/references/minimem/src/search/search.ts +256 -0
  325. package/references/minimem/src/server/__tests__/mcp.test.ts +341 -0
  326. package/references/minimem/src/server/__tests__/tools.test.ts +364 -0
  327. package/references/minimem/src/server/mcp.ts +326 -0
  328. package/references/minimem/src/server/tools.ts +720 -0
  329. package/references/minimem/src/session.ts +460 -0
  330. package/references/minimem/tsconfig.json +19 -0
  331. package/references/minimem/tsup.config.ts +26 -0
  332. package/references/minimem/vitest.config.ts +24 -0
  333. package/references/openteams/.claude/settings.json +6 -0
  334. package/references/openteams/README.md +1 -0
  335. package/references/openteams/SKILL.md +341 -0
  336. package/references/openteams/design.md +411 -0
  337. package/references/openteams/examples/bmad-method/prompts/analyst/ROLE.md +16 -0
  338. package/references/openteams/examples/bmad-method/prompts/analyst/SOUL.md +5 -0
  339. package/references/openteams/examples/bmad-method/prompts/architect/ROLE.md +24 -0
  340. package/references/openteams/examples/bmad-method/prompts/architect/SOUL.md +5 -0
  341. package/references/openteams/examples/bmad-method/prompts/developer/ROLE.md +25 -0
  342. package/references/openteams/examples/bmad-method/prompts/developer/SOUL.md +5 -0
  343. package/references/openteams/examples/bmad-method/prompts/master/ROLE.md +21 -0
  344. package/references/openteams/examples/bmad-method/prompts/master/SOUL.md +5 -0
  345. package/references/openteams/examples/bmad-method/prompts/pm/ROLE.md +20 -0
  346. package/references/openteams/examples/bmad-method/prompts/pm/SOUL.md +5 -0
  347. package/references/openteams/examples/bmad-method/prompts/qa/ROLE.md +17 -0
  348. package/references/openteams/examples/bmad-method/prompts/qa/SOUL.md +5 -0
  349. package/references/openteams/examples/bmad-method/prompts/quick-flow-dev/ROLE.md +23 -0
  350. package/references/openteams/examples/bmad-method/prompts/quick-flow-dev/SOUL.md +5 -0
  351. package/references/openteams/examples/bmad-method/prompts/scrum-master/ROLE.md +27 -0
  352. package/references/openteams/examples/bmad-method/prompts/scrum-master/SOUL.md +5 -0
  353. package/references/openteams/examples/bmad-method/prompts/tech-writer/ROLE.md +21 -0
  354. package/references/openteams/examples/bmad-method/prompts/tech-writer/SOUL.md +5 -0
  355. package/references/openteams/examples/bmad-method/prompts/ux-designer/ROLE.md +16 -0
  356. package/references/openteams/examples/bmad-method/prompts/ux-designer/SOUL.md +5 -0
  357. package/references/openteams/examples/bmad-method/roles/analyst.yaml +9 -0
  358. package/references/openteams/examples/bmad-method/roles/architect.yaml +9 -0
  359. package/references/openteams/examples/bmad-method/roles/developer.yaml +8 -0
  360. package/references/openteams/examples/bmad-method/roles/master.yaml +8 -0
  361. package/references/openteams/examples/bmad-method/roles/pm.yaml +9 -0
  362. package/references/openteams/examples/bmad-method/roles/qa.yaml +8 -0
  363. package/references/openteams/examples/bmad-method/roles/quick-flow-dev.yaml +8 -0
  364. package/references/openteams/examples/bmad-method/roles/scrum-master.yaml +9 -0
  365. package/references/openteams/examples/bmad-method/roles/tech-writer.yaml +8 -0
  366. package/references/openteams/examples/bmad-method/roles/ux-designer.yaml +8 -0
  367. package/references/openteams/examples/bmad-method/team.yaml +161 -0
  368. package/references/openteams/examples/get-shit-done/prompts/codebase-mapper/ROLE.md +17 -0
  369. package/references/openteams/examples/get-shit-done/prompts/codebase-mapper/SOUL.md +5 -0
  370. package/references/openteams/examples/get-shit-done/prompts/debugger/ROLE.md +25 -0
  371. package/references/openteams/examples/get-shit-done/prompts/debugger/SOUL.md +5 -0
  372. package/references/openteams/examples/get-shit-done/prompts/executor/ROLE.md +34 -0
  373. package/references/openteams/examples/get-shit-done/prompts/executor/SOUL.md +5 -0
  374. package/references/openteams/examples/get-shit-done/prompts/integration-checker/ROLE.md +18 -0
  375. package/references/openteams/examples/get-shit-done/prompts/integration-checker/SOUL.md +3 -0
  376. package/references/openteams/examples/get-shit-done/prompts/orchestrator/ROLE.md +42 -0
  377. package/references/openteams/examples/get-shit-done/prompts/orchestrator/SOUL.md +5 -0
  378. package/references/openteams/examples/get-shit-done/prompts/phase-researcher/ROLE.md +15 -0
  379. package/references/openteams/examples/get-shit-done/prompts/phase-researcher/SOUL.md +3 -0
  380. package/references/openteams/examples/get-shit-done/prompts/plan-checker/ROLE.md +17 -0
  381. package/references/openteams/examples/get-shit-done/prompts/plan-checker/SOUL.md +3 -0
  382. package/references/openteams/examples/get-shit-done/prompts/planner/ROLE.md +28 -0
  383. package/references/openteams/examples/get-shit-done/prompts/planner/SOUL.md +5 -0
  384. package/references/openteams/examples/get-shit-done/prompts/project-researcher/ROLE.md +16 -0
  385. package/references/openteams/examples/get-shit-done/prompts/project-researcher/SOUL.md +3 -0
  386. package/references/openteams/examples/get-shit-done/prompts/research-synthesizer/ROLE.md +13 -0
  387. package/references/openteams/examples/get-shit-done/prompts/research-synthesizer/SOUL.md +3 -0
  388. package/references/openteams/examples/get-shit-done/prompts/roadmapper/ROLE.md +14 -0
  389. package/references/openteams/examples/get-shit-done/prompts/roadmapper/SOUL.md +3 -0
  390. package/references/openteams/examples/get-shit-done/prompts/verifier/ROLE.md +19 -0
  391. package/references/openteams/examples/get-shit-done/prompts/verifier/SOUL.md +5 -0
  392. package/references/openteams/examples/get-shit-done/roles/codebase-mapper.yaml +8 -0
  393. package/references/openteams/examples/get-shit-done/roles/debugger.yaml +8 -0
  394. package/references/openteams/examples/get-shit-done/roles/executor.yaml +8 -0
  395. package/references/openteams/examples/get-shit-done/roles/integration-checker.yaml +8 -0
  396. package/references/openteams/examples/get-shit-done/roles/orchestrator.yaml +9 -0
  397. package/references/openteams/examples/get-shit-done/roles/phase-researcher.yaml +7 -0
  398. package/references/openteams/examples/get-shit-done/roles/plan-checker.yaml +8 -0
  399. package/references/openteams/examples/get-shit-done/roles/planner.yaml +8 -0
  400. package/references/openteams/examples/get-shit-done/roles/project-researcher.yaml +8 -0
  401. package/references/openteams/examples/get-shit-done/roles/research-synthesizer.yaml +7 -0
  402. package/references/openteams/examples/get-shit-done/roles/roadmapper.yaml +7 -0
  403. package/references/openteams/examples/get-shit-done/roles/verifier.yaml +8 -0
  404. package/references/openteams/examples/get-shit-done/team.yaml +154 -0
  405. package/references/openteams/package-lock.json +2181 -0
  406. package/references/openteams/package.json +48 -0
  407. package/references/openteams/schema/role.schema.json +125 -0
  408. package/references/openteams/schema/team.schema.json +284 -0
  409. package/references/openteams/src/cli/agent.ts +104 -0
  410. package/references/openteams/src/cli/cli.test.ts +381 -0
  411. package/references/openteams/src/cli/generate.ts +220 -0
  412. package/references/openteams/src/cli/message.ts +241 -0
  413. package/references/openteams/src/cli/task.ts +154 -0
  414. package/references/openteams/src/cli/team.ts +104 -0
  415. package/references/openteams/src/cli/template.ts +207 -0
  416. package/references/openteams/src/cli.ts +45 -0
  417. package/references/openteams/src/db/database.test.ts +185 -0
  418. package/references/openteams/src/db/database.ts +240 -0
  419. package/references/openteams/src/generators/agent-prompt-generator.test.ts +332 -0
  420. package/references/openteams/src/generators/agent-prompt-generator.ts +521 -0
  421. package/references/openteams/src/generators/package-generator.test.ts +129 -0
  422. package/references/openteams/src/generators/package-generator.ts +102 -0
  423. package/references/openteams/src/generators/skill-generator.test.ts +246 -0
  424. package/references/openteams/src/generators/skill-generator.ts +374 -0
  425. package/references/openteams/src/index.ts +104 -0
  426. package/references/openteams/src/services/agent-service.test.ts +158 -0
  427. package/references/openteams/src/services/agent-service.ts +84 -0
  428. package/references/openteams/src/services/communication-service.test.ts +455 -0
  429. package/references/openteams/src/services/communication-service.ts +371 -0
  430. package/references/openteams/src/services/message-service.test.ts +342 -0
  431. package/references/openteams/src/services/message-service.ts +203 -0
  432. package/references/openteams/src/services/task-service.test.ts +434 -0
  433. package/references/openteams/src/services/task-service.ts +239 -0
  434. package/references/openteams/src/services/team-service.test.ts +181 -0
  435. package/references/openteams/src/services/team-service.ts +139 -0
  436. package/references/openteams/src/services/template-service.test.ts +306 -0
  437. package/references/openteams/src/services/template-service.ts +182 -0
  438. package/references/openteams/src/spawner/acp-factory.ts +96 -0
  439. package/references/openteams/src/spawner/interface.ts +31 -0
  440. package/references/openteams/src/spawner/mock.test.ts +93 -0
  441. package/references/openteams/src/spawner/mock.ts +59 -0
  442. package/references/openteams/src/template/loader.test.ts +1319 -0
  443. package/references/openteams/src/template/loader.ts +698 -0
  444. package/references/openteams/src/template/types.ts +200 -0
  445. package/references/openteams/src/types.ts +205 -0
  446. package/references/openteams/tsconfig.json +18 -0
  447. package/references/openteams/vitest.config.ts +9 -0
  448. package/references/skill-tree/.claude/settings.json +6 -0
  449. package/references/skill-tree/.sudocode/issues.jsonl +11 -0
  450. package/references/skill-tree/.sudocode/specs.jsonl +1 -0
  451. package/references/skill-tree/CLAUDE.md +150 -0
  452. package/references/skill-tree/README.md +324 -0
  453. package/references/skill-tree/docs/GAPS_v1.md +221 -0
  454. package/references/skill-tree/docs/INTEGRATION_PLAN.md +467 -0
  455. package/references/skill-tree/docs/TODOS.md +91 -0
  456. package/references/skill-tree/docs/anthropic_skill_guide.md +1364 -0
  457. package/references/skill-tree/docs/design/federated-skill-trees.md +524 -0
  458. package/references/skill-tree/docs/design/multi-agent-sync.md +759 -0
  459. package/references/skill-tree/docs/scraper/BRAINSTORM.md +583 -0
  460. package/references/skill-tree/docs/scraper/POC_PLAN.md +420 -0
  461. package/references/skill-tree/docs/scraper/README.md +170 -0
  462. package/references/skill-tree/examples/basic-usage.ts +190 -0
  463. package/references/skill-tree/package-lock.json +1509 -0
  464. package/references/skill-tree/package.json +66 -0
  465. package/references/skill-tree/scraper/README.md +123 -0
  466. package/references/skill-tree/scraper/docs/DESIGN.md +683 -0
  467. package/references/skill-tree/scraper/docs/PLAN.md +336 -0
  468. package/references/skill-tree/scraper/drizzle.config.ts +10 -0
  469. package/references/skill-tree/scraper/package-lock.json +6329 -0
  470. package/references/skill-tree/scraper/package.json +68 -0
  471. package/references/skill-tree/scraper/test/fixtures/invalid-skill/missing-description.md +7 -0
  472. package/references/skill-tree/scraper/test/fixtures/invalid-skill/missing-name.md +7 -0
  473. package/references/skill-tree/scraper/test/fixtures/minimal-skill/SKILL.md +27 -0
  474. package/references/skill-tree/scraper/test/fixtures/skill-json/SKILL.json +21 -0
  475. package/references/skill-tree/scraper/test/fixtures/skill-with-meta/SKILL.md +54 -0
  476. package/references/skill-tree/scraper/test/fixtures/skill-with-meta/_meta.json +24 -0
  477. package/references/skill-tree/scraper/test/fixtures/valid-skill/SKILL.md +93 -0
  478. package/references/skill-tree/scraper/test/fixtures/valid-skill/_meta.json +22 -0
  479. package/references/skill-tree/scraper/tsup.config.ts +14 -0
  480. package/references/skill-tree/scraper/vitest.config.ts +17 -0
  481. package/references/skill-tree/scripts/convert-to-vitest.ts +166 -0
  482. package/references/skill-tree/skills/skill-writer/SKILL.md +339 -0
  483. package/references/skill-tree/skills/skill-writer/references/examples.md +326 -0
  484. package/references/skill-tree/skills/skill-writer/references/patterns.md +210 -0
  485. package/references/skill-tree/skills/skill-writer/references/quality-checklist.md +123 -0
  486. package/references/skill-tree/test/run-all.ts +106 -0
  487. package/references/skill-tree/test/utils.ts +128 -0
  488. package/references/skill-tree/vitest.config.ts +16 -0
  489. package/src/__tests__/e2e/agent-spawn-visibility.e2e.test.ts +761 -0
  490. package/src/__tests__/e2e/full-agent-conflict-resolution.e2e.test.ts +2 -2
  491. package/src/__tests__/e2e/mcp-thin-client-bridge.e2e.test.ts +304 -0
  492. package/src/__tests__/e2e/mcp-tools-available.e2e.test.ts +324 -0
  493. package/src/__tests__/e2e/multi-agent.e2e.test.ts +5 -5
  494. package/src/__tests__/e2e/spawn-session-streaming.e2e.test.ts +563 -0
  495. package/src/acp/__tests__/integration.test.ts +56 -31
  496. package/src/acp/__tests__/macro-agent.test.ts +16 -7
  497. package/src/acp/macro-agent.ts +170 -36
  498. package/src/acp/types.ts +46 -1
  499. package/src/agent/__tests__/agent-manager.test.ts +228 -2
  500. package/src/agent/agent-manager.ts +809 -285
  501. package/src/agent/types.ts +12 -1
  502. package/src/api/__tests__/server.test.ts +203 -4
  503. package/src/api/server.ts +169 -10
  504. package/src/api/types.ts +3 -1
  505. package/src/auth/__tests__/token.test.ts +100 -0
  506. package/src/auth/index.ts +1 -0
  507. package/src/auth/token.ts +82 -0
  508. package/src/cli/__tests__/acp.test.ts +1 -1
  509. package/src/cli/__tests__/stable-instance-id.test.ts +1 -1
  510. package/src/cli/acp.ts +197 -72
  511. package/src/cli/index.ts +125 -15
  512. package/src/cli/mcp.ts +315 -197
  513. package/src/cli/parse-args.ts +54 -0
  514. package/src/cli/stable-instance-id.ts +14 -0
  515. package/src/config/project-config.ts +214 -27
  516. package/src/index.ts +3 -0
  517. package/src/lifecycle/__tests__/cascade-termination.test.ts +1 -1
  518. package/src/lifecycle/__tests__/handlers.test.ts +53 -0
  519. package/src/lifecycle/handlers/index.ts +25 -8
  520. package/src/lifecycle/types.ts +3 -0
  521. package/src/map/adapter/__tests__/acp-over-map-cancel.test.ts +22 -4
  522. package/src/map/adapter/__tests__/acp-over-map-getmodels.test.ts +355 -0
  523. package/src/map/adapter/__tests__/acp-over-map-history.test.ts +263 -0
  524. package/src/map/adapter/__tests__/acp-over-map-persistence.e2e.test.ts +1 -1
  525. package/src/map/adapter/__tests__/event-broadcast.test.ts +420 -0
  526. package/src/map/adapter/__tests__/event-log.test.ts +527 -0
  527. package/src/map/adapter/__tests__/event-translator.test.ts +3 -3
  528. package/src/map/adapter/__tests__/extensions.test.ts +408 -0
  529. package/src/map/adapter/__tests__/map-adapter.test.ts +99 -0
  530. package/src/map/adapter/__tests__/mcp-bridge.test.ts +1187 -0
  531. package/src/map/adapter/__tests__/multi-client-broadcast.test.ts +711 -0
  532. package/src/map/adapter/__tests__/stream-extensions.test.ts +494 -0
  533. package/src/map/adapter/__tests__/websocket-integration.test.ts +218 -0
  534. package/src/map/adapter/acp-over-map.ts +678 -66
  535. package/src/map/adapter/connection-manager.ts +3 -0
  536. package/src/map/adapter/event-log.ts +208 -0
  537. package/src/map/adapter/event-translator.ts +6 -6
  538. package/src/map/adapter/extensions/agent-lifecycle.ts +267 -0
  539. package/src/map/adapter/extensions/index.ts +96 -0
  540. package/src/map/adapter/extensions/mcp-bridge.ts +995 -0
  541. package/src/map/adapter/extensions/streams.ts +839 -0
  542. package/src/map/adapter/extensions/task.ts +11 -0
  543. package/src/map/adapter/extensions/update-metadata.ts +126 -0
  544. package/src/map/adapter/index.ts +33 -0
  545. package/src/map/adapter/interface.ts +2 -0
  546. package/src/map/adapter/map-adapter.ts +312 -47
  547. package/src/map/adapter/subscription-manager.ts +5 -1
  548. package/src/map/adapter/types.ts +10 -1
  549. package/src/mcp/__tests__/map-client.test.ts +386 -0
  550. package/src/mcp/__tests__/mcp-server-thin-client.test.ts +368 -0
  551. package/src/mcp/__tests__/mcp-server.test.ts +100 -1
  552. package/src/mcp/map-client.ts +177 -0
  553. package/src/mcp/mcp-server.ts +205 -103
  554. package/src/mcp/tools/done.ts +19 -0
  555. package/src/mcp/types.ts +6 -1
  556. package/src/metrics/metrics.ts +1 -1
  557. package/src/monitor/__tests__/stale-agent-flow.integration.test.ts +1 -1
  558. package/src/roles/__tests__/config-loader.test.ts +7 -7
  559. package/src/roles/builtin/coordinator.ts +2 -0
  560. package/src/roles/builtin/integrator.ts +2 -0
  561. package/src/roles/builtin/worker.ts +3 -0
  562. package/src/roles/capabilities.ts +28 -7
  563. package/src/roles/config-loader.ts +8 -7
  564. package/src/roles/registry.ts +2 -2
  565. package/src/roles/types.ts +7 -0
  566. package/src/server/__tests__/combined-server.test.ts +94 -21
  567. package/src/server/combined-server.ts +203 -33
  568. package/src/steering/__tests__/steering-integration.test.ts +1 -1
  569. package/src/store/__tests__/event-store-oob.test.ts +109 -0
  570. package/src/store/__tests__/event-store.test.ts +196 -1
  571. package/src/store/__tests__/instance.test.ts +3 -3
  572. package/src/store/event-store.ts +92 -23
  573. package/src/store/instance.ts +2 -2
  574. package/src/store/types/agents.ts +20 -0
  575. package/src/store/types/events.ts +1 -1
  576. package/src/task/backend/__tests__/create-task-backend.test.ts +225 -0
  577. package/src/task/backend/__tests__/e2e/unified-tool-provider-opentasks.e2e.test.ts +524 -0
  578. package/src/task/backend/__tests__/memory-pull-mode.test.ts +153 -0
  579. package/src/task/backend/__tests__/unified-tool-provider.test.ts +579 -0
  580. package/src/task/backend/index.ts +156 -106
  581. package/src/task/backend/memory.ts +4 -0
  582. package/src/task/backend/opentasks/__tests__/backend.test.ts +968 -0
  583. package/src/task/backend/opentasks/__tests__/daemon-manager.test.ts +406 -0
  584. package/src/task/backend/opentasks/__tests__/mapping.test.ts +84 -0
  585. package/src/task/backend/opentasks/__tests__/opentasks-backend.e2e.test.ts +1338 -0
  586. package/src/task/backend/opentasks/backend.ts +1323 -0
  587. package/src/task/backend/opentasks/client.ts +652 -0
  588. package/src/task/backend/opentasks/daemon-manager.ts +256 -0
  589. package/src/task/backend/opentasks/index.ts +69 -0
  590. package/src/task/backend/opentasks/mapping.ts +94 -0
  591. package/src/task/backend/types.ts +42 -66
  592. package/src/task/backend/unified-tool-provider.ts +779 -0
  593. package/src/teams/CLAUDE.md +180 -0
  594. package/src/teams/__tests__/cross-subsystem.integration.test.ts +1 -1
  595. package/src/teams/__tests__/e2e/workspace-isolation.e2e.test.ts +1263 -0
  596. package/src/teams/__tests__/team-manager.test.ts +814 -0
  597. package/src/teams/__tests__/team-system.test.ts +1291 -8
  598. package/src/teams/index.ts +21 -3
  599. package/src/teams/seed-defaults.ts +79 -0
  600. package/src/teams/team-loader.ts +202 -236
  601. package/src/teams/team-manager.ts +387 -0
  602. package/src/teams/team-runtime.ts +592 -121
  603. package/src/teams/types.ts +99 -200
  604. package/test_fixtures/README.md +2 -3
  605. package/test_fixtures/fixtures/index.ts +0 -3
  606. package/test_fixtures/fixtures/projects/project-with-specs.ts +7 -149
  607. package/test_fixtures/fixtures/repos/index.ts +1 -3
  608. package/test_fixtures/fixtures/repos/temp-repo-factory.ts +0 -116
  609. package/test_fixtures/fixtures/repos/types.ts +0 -11
  610. package/test_fixtures/harness/__tests__/fixtures.test.ts +10 -102
  611. package/test_fixtures/harness/__tests__/temp-repo-and-simulator.test.ts +0 -33
  612. package/test_fixtures/harness/simulator/agent-simulator.ts +4 -4
  613. package/vitest.config.ts +1 -1
  614. package/vitest.e2e.config.ts +1 -1
  615. package/vitest.setup.ts +1 -30
  616. package/.macro-agent/teams/self-driving/prompts/grinder.md +0 -27
  617. package/.macro-agent/teams/self-driving/prompts/judge.md +0 -27
  618. package/.macro-agent/teams/self-driving/prompts/planner.md +0 -33
  619. package/.macro-agent/teams/self-driving/roles/grinder.yaml +0 -17
  620. package/.macro-agent/teams/self-driving/roles/judge.yaml +0 -24
  621. package/.macro-agent/teams/self-driving/roles/planner.yaml +0 -18
  622. package/.macro-agent/teams/self-driving/team.yaml +0 -103
  623. package/.macro-agent/teams/structured/prompts/developer.md +0 -26
  624. package/.macro-agent/teams/structured/prompts/lead.md +0 -25
  625. package/.macro-agent/teams/structured/prompts/reviewer.md +0 -24
  626. package/.macro-agent/teams/structured/roles/developer.yaml +0 -12
  627. package/.macro-agent/teams/structured/roles/lead.yaml +0 -11
  628. package/.macro-agent/teams/structured/roles/reviewer.yaml +0 -19
  629. package/.macro-agent/teams/structured/team.yaml +0 -89
  630. package/docs/sudocode-integration.md +0 -383
  631. package/src/task/backend/__tests__/backend-parity.test.ts +0 -451
  632. package/src/task/backend/__tests__/tool-provider-edge-cases.test.ts +0 -430
  633. package/src/task/backend/__tests__/tool-provider.test.ts +0 -983
  634. package/src/task/backend/sudocode/__tests__/backend-edge-cases.test.ts +0 -575
  635. package/src/task/backend/sudocode/__tests__/backend.test.ts +0 -1194
  636. package/src/task/backend/sudocode/__tests__/client-integration.test.ts +0 -418
  637. package/src/task/backend/sudocode/__tests__/client.test.ts +0 -345
  638. package/src/task/backend/sudocode/__tests__/e2e/backend.e2e.test.ts +0 -753
  639. package/src/task/backend/sudocode/__tests__/e2e/server-client.e2e.test.ts +0 -680
  640. package/src/task/backend/sudocode/__tests__/e2e-workflow.test.ts +0 -666
  641. package/src/task/backend/sudocode/__tests__/integration/standalone-client.integration.test.ts +0 -396
  642. package/src/task/backend/sudocode/__tests__/integration/sudocode-cli.integration.test.ts +0 -328
  643. package/src/task/backend/sudocode/__tests__/integration/test-utils.ts +0 -175
  644. package/src/task/backend/sudocode/__tests__/mapping-edge-cases.test.ts +0 -265
  645. package/src/task/backend/sudocode/__tests__/server-client.test.ts +0 -675
  646. package/src/task/backend/sudocode/__tests__/sync-policy-edge-cases.test.ts +0 -521
  647. package/src/task/backend/sudocode/__tests__/sync-policy.test.ts +0 -519
  648. package/src/task/backend/sudocode/__tests__/tools.test.ts +0 -471
  649. package/src/task/backend/sudocode/backend.ts +0 -1237
  650. package/src/task/backend/sudocode/client.ts +0 -515
  651. package/src/task/backend/sudocode/index.ts +0 -120
  652. package/src/task/backend/sudocode/mapping.ts +0 -93
  653. package/src/task/backend/sudocode/server-client.ts +0 -522
  654. package/src/task/backend/sudocode/standalone-client.ts +0 -623
  655. package/src/task/backend/sudocode/sync-policy.ts +0 -387
  656. package/src/task/backend/sudocode/tools.ts +0 -896
  657. package/src/task/backend/tool-provider.ts +0 -506
  658. package/test_fixtures/fixtures/sudocode/index.ts +0 -29
  659. package/test_fixtures/fixtures/sudocode/issues.ts +0 -185
  660. package/test_fixtures/fixtures/sudocode/specs.ts +0 -159
@@ -0,0 +1,82 @@
1
+ /**
2
+ * Authentication Token Utilities
3
+ *
4
+ * Provides token generation, secure comparison, and per-agent
5
+ * token management for the macro-agent server.
6
+ */
7
+
8
+ import * as crypto from "crypto";
9
+
10
+ // =============================================================================
11
+ // Token Generation
12
+ // =============================================================================
13
+
14
+ /**
15
+ * Generate a cryptographically random hex token.
16
+ */
17
+ export function generateToken(bytes = 32): string {
18
+ return crypto.randomBytes(bytes).toString("hex");
19
+ }
20
+
21
+ // =============================================================================
22
+ // Secure Comparison
23
+ // =============================================================================
24
+
25
+ /**
26
+ * Constant-time string comparison to prevent timing attacks.
27
+ */
28
+ export function secureCompare(a: string, b: string): boolean {
29
+ if (a.length !== b.length) {
30
+ return false;
31
+ }
32
+ const bufA = Buffer.from(a);
33
+ const bufB = Buffer.from(b);
34
+ return crypto.timingSafeEqual(bufA, bufB);
35
+ }
36
+
37
+ // =============================================================================
38
+ // Agent Token Manager
39
+ // =============================================================================
40
+
41
+ /**
42
+ * Manages per-agent authentication tokens.
43
+ *
44
+ * Each spawned agent gets a unique token at spawn time. The token is
45
+ * passed to the subprocess via environment variable and validated on
46
+ * every MCP bridge RPC call.
47
+ */
48
+ export class AgentTokenManager {
49
+ private tokens = new Map<string, string>();
50
+
51
+ /**
52
+ * Create and store a token for an agent. Returns the generated token.
53
+ */
54
+ createToken(agentId: string): string {
55
+ const token = generateToken();
56
+ this.tokens.set(agentId, token);
57
+ return token;
58
+ }
59
+
60
+ /**
61
+ * Verify that a token matches the one stored for an agent.
62
+ */
63
+ verifyToken(agentId: string, token: string): boolean {
64
+ const stored = this.tokens.get(agentId);
65
+ if (!stored) return false;
66
+ return secureCompare(stored, token);
67
+ }
68
+
69
+ /**
70
+ * Revoke an agent's token (e.g., on terminate).
71
+ */
72
+ revokeToken(agentId: string): boolean {
73
+ return this.tokens.delete(agentId);
74
+ }
75
+
76
+ /**
77
+ * Check if an agent has a registered token.
78
+ */
79
+ hasToken(agentId: string): boolean {
80
+ return this.tokens.has(agentId);
81
+ }
82
+ }
@@ -6,7 +6,7 @@
6
6
  */
7
7
 
8
8
  import { describe, it, expect } from "vitest";
9
- import { parseArgs, type ACPServerOptions } from "../acp.js";
9
+ import { parseArgs, type ACPServerOptions } from "../parse-args.js";
10
10
 
11
11
  // ─────────────────────────────────────────────────────────────────
12
12
  // parseArgs Tests
@@ -7,7 +7,7 @@
7
7
 
8
8
  import { describe, it, expect } from "vitest";
9
9
  import { resolve } from "node:path";
10
- import { getStableInstanceId } from "../acp.js";
10
+ import { getStableInstanceId } from "../stable-instance-id.js";
11
11
 
12
12
  describe("getStableInstanceId", () => {
13
13
  it("should return the same ID for the same path", () => {
package/src/cli/acp.ts CHANGED
@@ -38,11 +38,7 @@
38
38
  * });
39
39
  */
40
40
 
41
- import { readFileSync } from "node:fs";
42
- import { createHash } from "node:crypto";
43
- import { dirname, join, resolve } from "node:path";
44
41
  import { Readable } from "node:stream";
45
- import { fileURLToPath } from "node:url";
46
42
  import {
47
43
  AgentSideConnection,
48
44
  ndJsonStream,
@@ -52,6 +48,7 @@ import { createAgentManager } from "../agent/agent-manager.js";
52
48
  import { createTaskManager } from "../task/task-manager.js";
53
49
  import { createMessageRouter } from "../router/message-router.js";
54
50
  import { MacroAgent } from "../acp/macro-agent.js";
51
+ import { TeamManager } from "../teams/team-manager.js";
55
52
  import {
56
53
  createCombinedServer,
57
54
  type CombinedServer,
@@ -73,63 +70,13 @@ import type { AgentId, EventId } from "../store/types/index.js";
73
70
  // Configuration
74
71
  // ─────────────────────────────────────────────────────────────────
75
72
 
76
- export interface ACPServerOptions {
77
- /** Working directory for agents */
78
- cwd?: string;
79
- /** Stdio ACP-only mode (for embedded use with acp-factory) */
80
- acp?: boolean;
81
- /** Port for server (default: 3001) */
82
- port?: number;
83
- /** Host for server (default: localhost) */
84
- host?: string;
85
- /** Instance ID to reuse an existing event store (omit for new instance) */
86
- instanceId?: string;
87
- }
73
+ import { parseArgs } from "./parse-args.js";
74
+ import { getStableInstanceId } from "./stable-instance-id.js";
75
+ import { loadMergedConfig } from "../config/project-config.js";
88
76
 
89
- /**
90
- * Parse command line arguments.
91
- * @param argv Optional array of arguments (defaults to process.argv.slice(2))
92
- */
93
- export function parseArgs(argv?: string[]): ACPServerOptions {
94
- const args = argv ?? process.argv.slice(2);
95
- const options: ACPServerOptions = {};
96
-
97
- for (let i = 0; i < args.length; i++) {
98
- if (args[i] === "--version" || args[i] === "-v") {
99
- const __dirname = dirname(fileURLToPath(import.meta.url));
100
- const pkg = JSON.parse(readFileSync(join(__dirname, "../../package.json"), "utf-8"));
101
- console.log(pkg.version);
102
- process.exit(0);
103
- } else if (args[i] === "--cwd" && args[i + 1]) {
104
- options.cwd = args[i + 1];
105
- i++;
106
- } else if (args[i] === "--acp") {
107
- options.acp = true;
108
- } else if (args[i] === "--port" && args[i + 1]) {
109
- options.port = parseInt(args[i + 1], 10);
110
- i++;
111
- } else if (args[i] === "--host" && args[i + 1]) {
112
- options.host = args[i + 1];
113
- i++;
114
- } else if (args[i] === "--instance-id" && args[i + 1]) {
115
- options.instanceId = args[i + 1];
116
- i++;
117
- }
118
- }
119
-
120
- return options;
121
- }
122
-
123
- /**
124
- * Generate a stable instance ID from the working directory.
125
- * This ensures the same project always uses the same EventStore,
126
- * so agents and sessions persist across server restarts.
127
- */
128
- export function getStableInstanceId(cwd: string): string {
129
- const normalizedPath = resolve(cwd);
130
- const hash = createHash("sha256").update(normalizedPath).digest("hex").slice(0, 12);
131
- return `inst_${hash}`;
132
- }
77
+ // Re-export utilities for backwards compatibility
78
+ export { parseArgs, type ACPServerOptions } from "./parse-args.js";
79
+ export { getStableInstanceId } from "./stable-instance-id.js";
133
80
 
134
81
  // ─────────────────────────────────────────────────────────────────
135
82
  // Stream Setup
@@ -272,10 +219,154 @@ async function main() {
272
219
  wakeHandler: routerWakeHandler,
273
220
  });
274
221
 
222
+ // Load merged config (global → project → env vars)
223
+ const mergedConfig = loadMergedConfig(defaultCwd);
224
+
225
+ // Compute server URL for thin-client MCP mode (only in server mode, not stdio ACP)
226
+ const serverUrl = options.acp
227
+ ? undefined
228
+ : `http://${options.host ?? mergedConfig.host ?? "localhost"}:${options.port ?? mergedConfig.port ?? 3001}`;
229
+
230
+ // Set up authentication tokens from merged config
231
+ const noAuth = options.noAuth || mergedConfig.auth?.disabled === true;
232
+ let serverToken: string | undefined;
233
+ let agentTokenManager: import("../auth/token.js").AgentTokenManager | undefined;
234
+
235
+ if (!noAuth && mergedConfig.auth?.secret) {
236
+ const { AgentTokenManager } = await import("../auth/token.js");
237
+ serverToken = mergedConfig.auth.secret;
238
+ agentTokenManager = new AgentTokenManager();
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
+
275
259
  // Now create the agentManager with the real router
276
- agentManager = createAgentManager(eventStore, messageRouter);
260
+ agentManager = createAgentManager(eventStore, messageRouter, {
261
+ serverUrl,
262
+ serverToken: serverUrl ? serverToken : undefined,
263
+ agentTokenManager: serverUrl ? agentTokenManager : undefined,
264
+ taskBackend: mergedConfig.task?.backend,
265
+ openTasksSocketPath: mergedConfig.task?.opentasks?.socket_path,
266
+ workspaceManager,
267
+ });
277
268
  const taskManager = createTaskManager(eventStore);
278
269
 
270
+ // Create task backend for dynamic task tools (create_task, get_task, etc.)
271
+ const { createTaskBackend, loadTaskConfigFromMerged } = await import("../task/backend/index.js");
272
+ const { UnifiedTaskToolProvider } = await import("../task/backend/unified-tool-provider.js");
273
+
274
+ let taskBackend: import("../task/backend/types.js").TaskBackend | undefined;
275
+ let taskToolProvider: import("../task/backend/types.js").TaskToolProvider | undefined;
276
+ let taskBackendShutdown: (() => Promise<void>) | undefined;
277
+
278
+ // Mutable context holder for the task tool provider. Bridge handlers set
279
+ // this before each tool call so the provider uses the calling agent's ID.
280
+ // Safe because Node.js is single-threaded.
281
+ const taskToolContext = { agent_id: "" as string };
282
+
283
+ // Connect-on-spawn callback: auto-connect project .opentasks/ dirs to central daemon
284
+ let connectProject: ((projectPath: string) => Promise<void>) | undefined;
285
+ let getConnectedProjects: (() => string[]) | undefined;
286
+
287
+ try {
288
+ const taskConfig = loadTaskConfigFromMerged(mergedConfig);
289
+ const result = await createTaskBackend(taskConfig, eventStore);
290
+ taskBackend = result.backend;
291
+ taskBackendShutdown = result.shutdown;
292
+ connectProject = result.connectProject;
293
+ getConnectedProjects = result.getConnectedProjects;
294
+
295
+ taskToolProvider = new UnifiedTaskToolProvider(
296
+ taskBackend,
297
+ () => taskToolContext,
298
+ result.openTasksClient
299
+ );
300
+ console.error(`[acp] Task backend created: ${taskConfig.backend.type}`);
301
+
302
+ // Propagate runtime socket path to child agents so they skip daemon discovery
303
+ if (result.socketPath) {
304
+ agentManager.setOpenTasksSocketPath(result.socketPath);
305
+ }
306
+
307
+ // Auto-connect the server's own project directory on startup
308
+ if (connectProject) {
309
+ connectProject(defaultCwd).catch(() => {});
310
+ }
311
+ } catch (err) {
312
+ // Fall back to in-memory backend if opentasks connection fails
313
+ console.error(`[acp] Failed to create task backend (${err}), falling back to memory`);
314
+ try {
315
+ const fallbackResult = await createTaskBackend({ backend: { type: "memory" } }, eventStore);
316
+ taskBackend = fallbackResult.backend;
317
+ taskToolProvider = new UnifiedTaskToolProvider(
318
+ taskBackend,
319
+ () => taskToolContext,
320
+ );
321
+ console.error(`[acp] Task backend created: memory (fallback)`);
322
+ } catch (fallbackErr) {
323
+ console.error(`[acp] Memory fallback also failed: ${fallbackErr}. Task tools will be unavailable.`);
324
+ }
325
+ }
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
+
279
370
  // Create ActivityWatcher for event-driven agent waking
280
371
  const sessionProvider = createSessionProviderFromAgentManager(agentManager);
281
372
  const wakeHandler = createWakeHandler(sessionProvider, agentManager);
@@ -332,9 +423,11 @@ async function main() {
332
423
  activityWatcher.start();
333
424
 
334
425
  // Auto-subscribe Monitor agents to health events when they spawn
426
+ // and auto-connect project .opentasks/ directories to central daemon
335
427
  agentManager.onLifecycleEvent((event) => {
336
428
  if (event.type === "spawned") {
337
429
  const agent = event.agent;
430
+
338
431
  // Check if this is a Monitor agent
339
432
  if (agent.role === "monitor" || agent.role?.startsWith("monitor.")) {
340
433
  subscribeAgentToEvents(
@@ -346,23 +439,48 @@ async function main() {
346
439
  );
347
440
  console.error(`[acp] Auto-subscribed Monitor ${agent.id} to health events`);
348
441
  }
442
+
443
+ // Connect-on-spawn: auto-connect project .opentasks/ to central daemon
444
+ if (connectProject && agent.cwd) {
445
+ connectProject(agent.cwd).catch(() => {
446
+ // Non-fatal — logged inside connectProject
447
+ });
448
+ }
349
449
  }
350
450
  });
351
451
 
352
452
  // Combined server (when --ws is enabled)
353
453
  let combinedServer: CombinedServer | undefined;
354
454
 
355
- // Cleanup function
455
+ // Cleanup function — best-effort, each step isolated
356
456
  const cleanup = async () => {
357
- // Stop ActivityWatcher
358
- activityWatcher.stop();
457
+ try { activityWatcher.stop(); } catch (err) {
458
+ console.error(`[cleanup] ActivityWatcher stop failed: ${err}`);
459
+ }
359
460
 
360
- // Stop combined server if running
361
461
  if (combinedServer) {
362
- await combinedServer.stop();
462
+ try { await combinedServer.stop(); } catch (err) {
463
+ console.error(`[cleanup] Combined server stop failed: ${err}`);
464
+ }
465
+ }
466
+
467
+ try { await teamManager.teardownAll(); } catch (err) {
468
+ console.error(`[cleanup] TeamManager teardown failed: ${err}`);
469
+ }
470
+
471
+ try { await agentManager.close(); } catch (err) {
472
+ console.error(`[cleanup] AgentManager close failed: ${err}`);
473
+ }
474
+
475
+ if (taskBackendShutdown) {
476
+ try { await taskBackendShutdown(); } catch (err) {
477
+ console.error(`[cleanup] Task backend shutdown failed: ${err}`);
478
+ }
479
+ }
480
+
481
+ try { await eventStore.close(); } catch (err) {
482
+ console.error(`[cleanup] EventStore close failed: ${err}`);
363
483
  }
364
- await agentManager.close();
365
- await eventStore.close();
366
484
  };
367
485
 
368
486
  try {
@@ -401,15 +519,22 @@ async function main() {
401
519
  await cleanup();
402
520
  } else {
403
521
  // Full server mode (default): WebSocket ACP + MAP + REST API
404
- const host = options.host ?? "localhost";
405
- const port = options.port ?? 3001;
522
+ const host = options.host ?? mergedConfig.host ?? "localhost";
523
+ const port = options.port ?? mergedConfig.port ?? 3001;
406
524
 
407
525
  combinedServer = createCombinedServer(
408
- { eventStore, agentManager, taskManager, messageRouter, activityWatcher },
409
- { port, host, defaultCwd }
526
+ { eventStore, agentManager, taskManager, messageRouter, activityWatcher, taskBackend, taskToolProvider, taskToolContext, agentTokenManager, getConnectedProjects, teamManager, workspaceManager },
527
+ { port, host, defaultCwd, serverToken, noAuth }
410
528
  );
411
529
 
412
530
  await combinedServer.start();
531
+ if (serverToken) {
532
+ console.error(`[acp] Server token: ${serverToken.substring(0, 8)}...`);
533
+ } else if (noAuth) {
534
+ console.error(`[acp] Auth: explicitly disabled`);
535
+ } else {
536
+ console.error(`[acp] Auth: off (set auth.secret in config or MACRO_SERVER_SECRET to enable)`);
537
+ }
413
538
 
414
539
  // Keep process alive - will exit via SIGINT/SIGTERM handlers
415
540
  await new Promise<void>(() => {
package/src/cli/index.ts CHANGED
@@ -16,8 +16,9 @@ import { createAgentManager } from "../agent/agent-manager.js";
16
16
  import { createTaskManager } from "../task/task-manager.js";
17
17
  import { createMessageRouter } from "../router/message-router.js";
18
18
  import { createAPIServer } from "../api/server.js";
19
- import { loadProjectConfig } from "../config/project-config.js";
19
+ import { loadMergedConfig } from "../config/project-config.js";
20
20
  import { loadTeam, TeamRuntime } from "../teams/index.js";
21
+ import { createTaskBackend, loadTaskConfigFromMerged } from "../task/backend/index.js";
21
22
  import type { Agent, Task } from "../store/types/index.js";
22
23
 
23
24
  // ─────────────────────────────────────────────────────────────────
@@ -127,15 +128,52 @@ program
127
128
  console.log(chalk.blue("Starting multi-agent server..."));
128
129
 
129
130
  try {
131
+ // Load merged config (global → project → env vars)
132
+ const mergedConfig = loadMergedConfig(options.cwd);
133
+
130
134
  // Initialize services
131
135
  const eventStore = await createEventStore({ inMemory: false });
132
136
  const messageRouter = createMessageRouter(eventStore);
133
- const agentManager = createAgentManager(eventStore, messageRouter);
137
+ const serverUrl = `http://${options.host}:${options.port}`;
138
+ const agentManager = createAgentManager(eventStore, messageRouter, {
139
+ serverUrl,
140
+ taskBackend: mergedConfig.task?.backend,
141
+ openTasksSocketPath: mergedConfig.task?.opentasks?.socket_path,
142
+ });
134
143
  const taskManager = createTaskManager(eventStore);
135
144
 
136
- // Determine team name: CLI flag > project config > none
137
- const projectConfig = loadProjectConfig(options.cwd);
138
- const teamName = options.team ?? projectConfig.team;
145
+ // Create task backend from merged config
146
+ const taskConfig = loadTaskConfigFromMerged(mergedConfig);
147
+ let taskBackendShutdown: (() => Promise<void>) | undefined;
148
+ let connectProject: ((projectPath: string) => Promise<void>) | undefined;
149
+ try {
150
+ const result = await createTaskBackend(taskConfig, eventStore);
151
+ taskBackendShutdown = result.shutdown;
152
+ connectProject = result.connectProject;
153
+ console.log(chalk.blue(`Task backend: ${taskConfig.backend.type}`));
154
+
155
+ // Propagate runtime socket path to child agents so they skip daemon discovery
156
+ if (result.socketPath) {
157
+ agentManager.setOpenTasksSocketPath(result.socketPath);
158
+ }
159
+
160
+ // Auto-connect the server's own project directory on startup
161
+ if (connectProject) {
162
+ connectProject(options.cwd ?? process.cwd()).catch(() => {});
163
+ }
164
+ } catch (err) {
165
+ // Fall back to in-memory backend if opentasks connection fails
166
+ console.log(chalk.yellow(`Task backend creation failed (${err}), falling back to memory`));
167
+ try {
168
+ await createTaskBackend({ backend: { type: "memory" } }, eventStore);
169
+ } catch { /* non-critical */ }
170
+ }
171
+
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
+ }
176
+ const teamName = options.team ?? mergedConfig.team;
139
177
 
140
178
  // Load and initialize team if specified
141
179
  let teamRuntime: TeamRuntime | null = null;
@@ -159,10 +197,14 @@ program
159
197
  );
160
198
  }
161
199
 
200
+ // Resolve auth from merged config
201
+ const noAuth = mergedConfig.auth?.disabled ?? false;
202
+ const serverToken = noAuth ? undefined : (mergedConfig.auth?.secret ?? undefined);
203
+
162
204
  // Create API server
163
205
  const server = createAPIServer(
164
206
  { eventStore, agentManager, taskManager, messageRouter },
165
- { port: parseInt(options.port), host: options.host }
207
+ { port: parseInt(options.port), host: options.host, serverToken }
166
208
  );
167
209
 
168
210
  // Start server
@@ -171,6 +213,11 @@ program
171
213
  console.log(
172
214
  chalk.green(`Server running at http://${options.host}:${options.port}`)
173
215
  );
216
+ if (serverToken) {
217
+ console.log(chalk.gray(`Server token: ${serverToken.substring(0, 8)}...`));
218
+ } else {
219
+ console.log(chalk.yellow(`Auth: disabled (MACRO_NO_AUTH)`));
220
+ }
174
221
 
175
222
  // Bootstrap team agents after server is running
176
223
  if (teamRuntime) {
@@ -185,15 +232,39 @@ program
185
232
  );
186
233
  }
187
234
 
235
+ // Connect-on-spawn: auto-connect project .opentasks/ dirs when agents spawn
236
+ if (connectProject) {
237
+ agentManager.onLifecycleEvent((event) => {
238
+ if (event.type === "spawned" && event.agent.cwd && connectProject) {
239
+ connectProject(event.agent.cwd).catch(() => {});
240
+ }
241
+ });
242
+ }
243
+
188
244
  console.log(chalk.gray("Press Ctrl+C to stop"));
189
245
 
190
- // Handle shutdown
246
+ // Handle shutdown — best-effort, each step isolated
191
247
  process.on("SIGINT", async () => {
192
248
  console.log(chalk.yellow("\nShutting down..."));
193
- if (teamRuntime) await teamRuntime.teardown();
194
- await server.stop();
195
- await agentManager.close();
196
- await eventStore.close();
249
+ if (teamRuntime) {
250
+ try { await teamRuntime.teardown(); } catch (err) {
251
+ console.error(`[cleanup] Team teardown failed: ${err}`);
252
+ }
253
+ }
254
+ try { await server.stop(); } catch (err) {
255
+ console.error(`[cleanup] Server stop failed: ${err}`);
256
+ }
257
+ try { await agentManager.close(); } catch (err) {
258
+ console.error(`[cleanup] AgentManager close failed: ${err}`);
259
+ }
260
+ if (taskBackendShutdown) {
261
+ try { await taskBackendShutdown(); } catch (err) {
262
+ console.error(`[cleanup] Task backend shutdown failed: ${err}`);
263
+ }
264
+ }
265
+ try { await eventStore.close(); } catch (err) {
266
+ console.error(`[cleanup] EventStore close failed: ${err}`);
267
+ }
197
268
  process.exit(0);
198
269
  });
199
270
  } catch (error) {
@@ -237,6 +308,21 @@ program
237
308
  output: process.stdout,
238
309
  });
239
310
 
311
+ // Handle Ctrl+C and SIGTERM to clean up child processes
312
+ const cleanup = async () => {
313
+ console.log(chalk.yellow("\nShutting down..."));
314
+ try { await agentManager.close(); } catch (err) {
315
+ console.error(`[cleanup] AgentManager close failed: ${err}`);
316
+ }
317
+ try { await eventStore.close(); } catch (err) {
318
+ console.error(`[cleanup] EventStore close failed: ${err}`);
319
+ }
320
+ rl.close();
321
+ process.exit(0);
322
+ };
323
+ process.on("SIGINT", cleanup);
324
+ process.on("SIGTERM", cleanup);
325
+
240
326
  const prompt = () => {
241
327
  rl.question(chalk.cyan("You: "), async (input) => {
242
328
  const trimmed = input.trim();
@@ -632,7 +718,8 @@ program
632
718
  const path = await import("path");
633
719
  const os = await import("os");
634
720
 
635
- 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");
636
723
 
637
724
  if (fs.existsSync(storagePath)) {
638
725
  fs.unlinkSync(storagePath);
@@ -723,6 +810,20 @@ program
723
810
  agentManager = createAgentManager(eventStore, messageRouter);
724
811
  const taskManager = createTaskManager(eventStore);
725
812
 
813
+ // Create task backend from merged config
814
+ const acpMergedConfig = loadMergedConfig(defaultCwd);
815
+ const taskConfig = loadTaskConfigFromMerged(acpMergedConfig);
816
+ let acpTaskBackendShutdown: (() => Promise<void>) | undefined;
817
+ try {
818
+ const result = await createTaskBackend(taskConfig, eventStore);
819
+ acpTaskBackendShutdown = result.shutdown;
820
+ } catch {
821
+ // Fall back to memory if opentasks connection fails
822
+ try {
823
+ await createTaskBackend({ backend: { type: "memory" } }, eventStore);
824
+ } catch { /* non-critical */ }
825
+ }
826
+
726
827
  // Create stdio streams for ACP communication
727
828
  const input = Readable.toWeb(process.stdin) as ReadableStream<Uint8Array>;
728
829
  const output = new WritableStream<Uint8Array>({
@@ -753,13 +854,22 @@ program
753
854
  stream
754
855
  );
755
856
 
756
- // Handle graceful shutdown
857
+ // Handle graceful shutdown — best-effort, each step isolated
757
858
  const cleanup = async () => {
758
859
  if (agentManager) {
759
- await agentManager.close();
860
+ try { await agentManager.close(); } catch (err) {
861
+ console.error(`[cleanup] AgentManager close failed: ${err}`);
862
+ }
863
+ }
864
+ if (acpTaskBackendShutdown) {
865
+ try { await acpTaskBackendShutdown(); } catch (err) {
866
+ console.error(`[cleanup] Task backend shutdown failed: ${err}`);
867
+ }
760
868
  }
761
869
  if (eventStore) {
762
- await eventStore.close();
870
+ try { await eventStore.close(); } catch (err) {
871
+ console.error(`[cleanup] EventStore close failed: ${err}`);
872
+ }
763
873
  }
764
874
  process.exit(0);
765
875
  };