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
@@ -1,753 +0,0 @@
1
- /**
2
- * E2E Tests for SudocodeTaskBackend
3
- *
4
- * Tests the full task lifecycle integration with sudocode issues,
5
- * including blocker workflows, multiple tasks per issue, and sync policies.
6
- *
7
- * Run with:
8
- * npm run test:e2e:sudocode
9
- */
10
-
11
- import { describe, it, expect, beforeAll, afterAll, beforeEach, afterEach } from "vitest";
12
- import { spawn, execSync, ChildProcess } from "child_process";
13
- import { mkdtempSync, rmSync, existsSync } from "fs";
14
- import { tmpdir } from "os";
15
- import { join } from "path";
16
- import { ServerClient } from "../../server-client.js";
17
- import { SudocodeTaskBackend } from "../../backend.js";
18
- import { createEventStore } from "../../../../../store/event-store.js";
19
- import type { EventStore } from "../../../../../store/event-store.js";
20
- import type { Issue } from "../../client.js";
21
- import type { TaskChangeEvent } from "../../../types.js";
22
-
23
- // Configuration
24
- const TEST_PORT = 13580; // Different port from server-client tests
25
- const SERVER_URL = `http://localhost:${TEST_PORT}`;
26
- const WS_URL = `ws://localhost:${TEST_PORT}/ws`;
27
- const TEST_TIMEOUT = 20000;
28
- const SERVER_STARTUP_TIMEOUT = 15000;
29
-
30
- // Global state
31
- let serverProcess: ChildProcess | null = null;
32
- let projectDir: string | null = null;
33
- let projectId: string | null = null;
34
- let eventStore: EventStore;
35
- let client: ServerClient;
36
- let backend: SudocodeTaskBackend;
37
-
38
- // Track created issues for cleanup
39
- const createdIssueIds: string[] = [];
40
-
41
- /**
42
- * Normalize path to handle macOS symlinks (/var -> /private/var)
43
- */
44
- function normalizePath(p: string): string {
45
- if (p.startsWith("/private/")) {
46
- return p.substring("/private".length);
47
- }
48
- return p;
49
- }
50
-
51
- /**
52
- * Wait for the server to be ready
53
- */
54
- async function waitForServer(
55
- url: string,
56
- timeout: number = SERVER_STARTUP_TIMEOUT
57
- ): Promise<boolean> {
58
- const startTime = Date.now();
59
-
60
- while (Date.now() - startTime < timeout) {
61
- try {
62
- const controller = new AbortController();
63
- const timeoutId = setTimeout(() => controller.abort(), 1000);
64
-
65
- const response = await fetch(`${url}/health`, {
66
- signal: controller.signal,
67
- });
68
-
69
- clearTimeout(timeoutId);
70
-
71
- if (response.ok) {
72
- return true;
73
- }
74
- } catch {
75
- // Server not ready yet
76
- }
77
-
78
- await new Promise((r) => setTimeout(r, 200));
79
- }
80
-
81
- return false;
82
- }
83
-
84
- /**
85
- * Get the project ID for our test project from the server (with retry)
86
- */
87
- async function getProjectId(
88
- serverUrl: string,
89
- projectPath: string,
90
- maxRetries: number = 10
91
- ): Promise<string> {
92
- const normalizedPath = normalizePath(projectPath);
93
-
94
- for (let attempt = 0; attempt < maxRetries; attempt++) {
95
- try {
96
- const response = await fetch(`${serverUrl}/api/projects`);
97
- const result = await response.json();
98
-
99
- if (!result.success || !Array.isArray(result.data)) {
100
- await new Promise((r) => setTimeout(r, 500));
101
- continue;
102
- }
103
-
104
- const project = result.data.find((p: { path: string; id: string }) => {
105
- const normalizedProjectPath = normalizePath(p.path);
106
- return normalizedProjectPath === normalizedPath;
107
- });
108
-
109
- if (project) {
110
- return project.id;
111
- }
112
- } catch {
113
- // Retry
114
- }
115
-
116
- await new Promise((r) => setTimeout(r, 500));
117
- }
118
-
119
- throw new Error(`Project not found for path: ${projectPath} after ${maxRetries} retries`);
120
- }
121
-
122
- /**
123
- * Start the sudocode server
124
- */
125
- async function startServer(): Promise<void> {
126
- // Kill any stale processes on the test port
127
- try {
128
- execSync(`lsof -t -i :${TEST_PORT} | xargs kill -9 2>/dev/null || true`, {
129
- stdio: "ignore",
130
- });
131
- } catch {
132
- // Ignore
133
- }
134
-
135
- // Create temporary project directory
136
- projectDir = mkdtempSync(join(tmpdir(), "sudocode-backend-e2e-"));
137
-
138
- // Initialize sudocode
139
- await new Promise<void>((resolve, reject) => {
140
- const initProcess = spawn("npx", ["sudocode", "init"], {
141
- cwd: projectDir!,
142
- stdio: "pipe",
143
- });
144
-
145
- initProcess.on("close", (code) => {
146
- if (code === 0) {
147
- resolve();
148
- } else {
149
- reject(new Error(`sudocode init failed with code ${code}`));
150
- }
151
- });
152
-
153
- initProcess.on("error", reject);
154
- });
155
-
156
- // Start the server
157
- serverProcess = spawn(
158
- "npx",
159
- ["sudocode", "server", "-p", String(TEST_PORT)],
160
- {
161
- cwd: projectDir,
162
- stdio: "pipe",
163
- env: { ...process.env, FORCE_COLOR: "0" },
164
- }
165
- );
166
-
167
- serverProcess.stdout?.on("data", (data) => {
168
- if (process.env.DEBUG_E2E) {
169
- console.log(`[server stdout] ${data}`);
170
- }
171
- });
172
-
173
- serverProcess.stderr?.on("data", (data) => {
174
- if (process.env.DEBUG_E2E) {
175
- console.error(`[server stderr] ${data}`);
176
- }
177
- });
178
-
179
- // Wait for server to be ready
180
- const ready = await waitForServer(SERVER_URL);
181
- if (!ready) {
182
- throw new Error(`Server failed to start within ${SERVER_STARTUP_TIMEOUT}ms`);
183
- }
184
-
185
- // Get project ID
186
- projectId = await getProjectId(SERVER_URL, projectDir);
187
- }
188
-
189
- /**
190
- * Stop the sudocode server
191
- */
192
- async function stopServer(): Promise<void> {
193
- if (serverProcess) {
194
- serverProcess.kill("SIGTERM");
195
-
196
- await new Promise<void>((resolve) => {
197
- const timeout = setTimeout(() => {
198
- serverProcess?.kill("SIGKILL");
199
- resolve();
200
- }, 5000);
201
-
202
- serverProcess!.on("close", () => {
203
- clearTimeout(timeout);
204
- resolve();
205
- });
206
- });
207
-
208
- serverProcess = null;
209
- }
210
-
211
- if (projectDir && existsSync(projectDir)) {
212
- rmSync(projectDir, { recursive: true, force: true });
213
- projectDir = null;
214
- }
215
- }
216
-
217
- /**
218
- * Create a test issue via the API
219
- */
220
- async function createTestIssue(
221
- title: string,
222
- content?: string
223
- ): Promise<Issue> {
224
- const response = await fetch(`${SERVER_URL}/api/issues`, {
225
- method: "POST",
226
- headers: {
227
- "Content-Type": "application/json",
228
- "X-Project-ID": projectId!,
229
- },
230
- body: JSON.stringify({
231
- title,
232
- content: content ?? `Test content for ${title}`,
233
- status: "open",
234
- priority: 2,
235
- }),
236
- });
237
-
238
- const result = await response.json();
239
- if (!result.success) {
240
- throw new Error(`Failed to create issue: ${result.message}`);
241
- }
242
-
243
- createdIssueIds.push(result.data.id);
244
- return result.data;
245
- }
246
-
247
- /**
248
- * Wait for condition with timeout
249
- */
250
- async function waitFor(
251
- condition: () => boolean | Promise<boolean>,
252
- timeout: number = 5000
253
- ): Promise<void> {
254
- const startTime = Date.now();
255
- while (Date.now() - startTime < timeout) {
256
- if (await condition()) {
257
- return;
258
- }
259
- await new Promise((r) => setTimeout(r, 100));
260
- }
261
- throw new Error(`Condition not met within ${timeout}ms`);
262
- }
263
-
264
- describe("SudocodeTaskBackend E2E", () => {
265
- beforeAll(async () => {
266
- console.log("\n🚀 Starting sudocode server for Backend E2E tests...");
267
- await startServer();
268
- console.log(`✅ Server ready at ${SERVER_URL}\n`);
269
- }, SERVER_STARTUP_TIMEOUT + 10000);
270
-
271
- afterAll(async () => {
272
- console.log("\n🛑 Shutting down sudocode server...");
273
- await stopServer();
274
- console.log("✅ Cleanup complete\n");
275
- }, 15000);
276
-
277
- beforeEach(async () => {
278
- // Create a fresh EventStore for each test with a unique instance ID
279
- const instanceId = `e2e-test-${Date.now()}-${Math.random().toString(36).slice(2)}`;
280
- eventStore = await createEventStore({
281
- instanceId,
282
- inMemory: true, // Use in-memory for tests
283
- });
284
-
285
- // Create ServerClient
286
- client = new ServerClient({
287
- serverUrl: SERVER_URL,
288
- wsUrl: WS_URL,
289
- projectId: projectId!,
290
- });
291
-
292
- // Wait for WebSocket connection
293
- await new Promise<void>((resolve, reject) => {
294
- const timeout = setTimeout(() => {
295
- reject(new Error("WebSocket connection timeout"));
296
- }, 5000);
297
-
298
- const checkReady = () => {
299
- if (client.isReady()) {
300
- clearTimeout(timeout);
301
- resolve();
302
- } else {
303
- setTimeout(checkReady, 50);
304
- }
305
- };
306
- checkReady();
307
- });
308
-
309
- // Create SudocodeTaskBackend
310
- backend = new SudocodeTaskBackend(eventStore, client, {
311
- syncStatus: true,
312
- autoCloseIssues: false,
313
- });
314
- });
315
-
316
- afterEach(() => {
317
- if (client) {
318
- client.close();
319
- }
320
- });
321
-
322
- describe("Basic Workflow", () => {
323
- it(
324
- "should complete full task lifecycle bound to issue",
325
- { timeout: TEST_TIMEOUT },
326
- async () => {
327
- // Create sudocode issue
328
- const issue = await createTestIssue("E2E Backend Task Lifecycle");
329
-
330
- // 1. Create task bound to issue
331
- const task = await backend.create({
332
- description: "Implement test feature",
333
- created_by: "test-agent",
334
- external_id: issue.id,
335
- });
336
-
337
- expect(task.external_id).toBe(issue.id);
338
- expect(task.status).toBe("pending");
339
-
340
- // 2. Assign task
341
- await backend.assign(task.id, "worker-1");
342
- const assignedTask = await backend.get(task.id);
343
- expect(assignedTask?.assigned_agent).toBe("worker-1");
344
- expect(assignedTask?.status).toBe("assigned");
345
-
346
- // 3. Start task
347
- await backend.start(task.id);
348
- const inProgressTask = await backend.get(task.id);
349
- expect(inProgressTask?.status).toBe("in_progress");
350
-
351
- // Verify issue status was updated (if syncStatus is true)
352
- await new Promise((r) => setTimeout(r, 200));
353
- const updatedIssue = await client.getIssue(issue.id);
354
- expect(updatedIssue?.status).toBe("in_progress");
355
-
356
- // 4. Complete task
357
- await backend.complete(task.id, { summary: "Feature implemented" });
358
- const completedTask = await backend.get(task.id);
359
- expect(completedTask?.status).toBe("completed");
360
- }
361
- );
362
-
363
- it(
364
- "should create task without external binding",
365
- { timeout: TEST_TIMEOUT },
366
- async () => {
367
- const task = await backend.create({
368
- description: "Internal task without issue binding",
369
- created_by: "test-agent",
370
- });
371
-
372
- expect(task.external_id).toBeUndefined();
373
- expect(task.status).toBe("pending");
374
-
375
- // Should still work through full lifecycle
376
- await backend.assign(task.id, "worker-1");
377
- await backend.start(task.id);
378
- await backend.complete(task.id);
379
-
380
- const completedTask = await backend.get(task.id);
381
- expect(completedTask?.status).toBe("completed");
382
- }
383
- );
384
- });
385
-
386
- describe("Multiple Tasks Per Issue", () => {
387
- it(
388
- "should support multiple tasks bound to same issue",
389
- { timeout: TEST_TIMEOUT },
390
- async () => {
391
- const issue = await createTestIssue("E2E Multi-Task Issue");
392
-
393
- // Create two tasks for same issue (parallel workers)
394
- const task1 = await backend.create({
395
- description: "Worker 1 attempt",
396
- created_by: "coordinator",
397
- external_id: issue.id,
398
- });
399
-
400
- const task2 = await backend.create({
401
- description: "Worker 2 attempt",
402
- created_by: "coordinator",
403
- external_id: issue.id,
404
- });
405
-
406
- // Both bound to same issue
407
- expect(task1.external_id).toBe(issue.id);
408
- expect(task2.external_id).toBe(issue.id);
409
-
410
- // Start both
411
- await backend.assign(task1.id, "worker-1");
412
- await backend.assign(task2.id, "worker-2");
413
- await backend.start(task1.id);
414
- await backend.start(task2.id);
415
-
416
- // Complete one, fail other
417
- await backend.complete(task1.id, { summary: "success" });
418
- await backend.fail(task2.id, { code: "TIMEOUT", message: "Timed out" });
419
-
420
- // Verify statuses
421
- const completedTask = await backend.get(task1.id);
422
- const failedTask = await backend.get(task2.id);
423
- expect(completedTask?.status).toBe("completed");
424
- expect(failedTask?.status).toBe("failed");
425
-
426
- // Issue should still be open (coordinator decides when to close)
427
- const finalIssue = await client.getIssue(issue.id);
428
- expect(finalIssue?.status).toBe("in_progress");
429
- }
430
- );
431
- });
432
-
433
- describe("Blocker Workflow", () => {
434
- it(
435
- "should handle blockers via sudocode relationships",
436
- { timeout: TEST_TIMEOUT },
437
- async () => {
438
- // Create two issues with blocking relationship
439
- const blockerIssue = await createTestIssue("E2E Blocker Task");
440
- const blockedIssue = await createTestIssue("E2E Blocked Task");
441
-
442
- // Create blocking relationship
443
- await client.createLink(blockerIssue.id, blockedIssue.id, "blocks");
444
-
445
- // Create tasks bound to these issues
446
- const blockerTask = await backend.create({
447
- description: "Blocker task",
448
- created_by: "coordinator",
449
- external_id: blockerIssue.id,
450
- });
451
-
452
- const blockedTask = await backend.create({
453
- description: "Blocked task",
454
- created_by: "coordinator",
455
- external_id: blockedIssue.id,
456
- });
457
-
458
- // Verify the blocking relationship exists via backend.getBlockers
459
- // (This doesn't depend on toExtendedTask's isBlocked computation)
460
- const blockers = await backend.getBlockers(blockedTask.id);
461
- expect(blockers.length).toBeGreaterThan(0);
462
- expect(blockers[0].id).toBe(blockerTask.id);
463
-
464
- // Blocked task should have isBlocked (via toExtendedTask computation)
465
- const enrichedBlocked = await backend.get(blockedTask.id);
466
- expect(enrichedBlocked?.isBlocked).toBe(true);
467
-
468
- // Blocker task should not be blocked
469
- const enrichedBlocker = await backend.get(blockerTask.id);
470
- expect(enrichedBlocker?.isBlocked).toBe(false);
471
-
472
- // listReady should exclude blocked task
473
- const ready = await backend.listReady();
474
- const readyIds = ready.map((t) => t.id);
475
- expect(readyIds).toContain(blockerTask.id);
476
- expect(readyIds).not.toContain(blockedTask.id);
477
-
478
- // Complete blocker task and close blocker issue
479
- await backend.assign(blockerTask.id, "worker-1");
480
- await backend.start(blockerTask.id);
481
- await backend.complete(blockerTask.id, { summary: "done" });
482
- await client.updateIssue(blockerIssue.id, { status: "closed" });
483
-
484
- // Wait for status to propagate
485
- await new Promise((r) => setTimeout(r, 500));
486
-
487
- // Now blocked task should be ready
488
- const readyAfter = await backend.listReady();
489
- const readyIdsAfter = readyAfter.map((t) => t.id);
490
- expect(readyIdsAfter).toContain(blockedTask.id);
491
-
492
- // isBlocked should now be false
493
- const unblockedTask = await backend.get(blockedTask.id);
494
- expect(unblockedTask?.isBlocked).toBe(false);
495
- }
496
- );
497
-
498
- it(
499
- "should use getBlockers and getBlocking methods",
500
- { timeout: TEST_TIMEOUT },
501
- async () => {
502
- const blockerIssue = await createTestIssue("E2E Blocker For Methods");
503
- const blockedIssue = await createTestIssue("E2E Blocked For Methods");
504
-
505
- await client.createLink(blockerIssue.id, blockedIssue.id, "blocks");
506
-
507
- const blockerTask = await backend.create({
508
- description: "Blocker",
509
- created_by: "test",
510
- external_id: blockerIssue.id,
511
- });
512
-
513
- const blockedTask = await backend.create({
514
- description: "Blocked",
515
- created_by: "test",
516
- external_id: blockedIssue.id,
517
- });
518
-
519
- // Wait for relationship to propagate
520
- await new Promise((r) => setTimeout(r, 300));
521
-
522
- // Test getBlockers
523
- const blockers = await backend.getBlockers(blockedTask.id);
524
- expect(blockers.map((t) => t.id)).toContain(blockerTask.id);
525
-
526
- // Test getBlocking
527
- const blocking = await backend.getBlocking(blockerTask.id);
528
- expect(blocking.map((t) => t.id)).toContain(blockedTask.id);
529
- }
530
- );
531
- });
532
-
533
- describe("Task Filtering", () => {
534
- it(
535
- "should filter tasks by status",
536
- { timeout: TEST_TIMEOUT },
537
- async () => {
538
- const issue1 = await createTestIssue("E2E Filter Issue 1");
539
- const issue2 = await createTestIssue("E2E Filter Issue 2");
540
-
541
- const task1 = await backend.create({
542
- description: "Task 1",
543
- created_by: "test",
544
- external_id: issue1.id,
545
- });
546
-
547
- const task2 = await backend.create({
548
- description: "Task 2",
549
- created_by: "test",
550
- external_id: issue2.id,
551
- });
552
-
553
- // Start task1
554
- await backend.assign(task1.id, "worker-1");
555
- await backend.start(task1.id);
556
-
557
- // Filter by status
558
- const pendingTasks = await backend.list({ status: "pending" });
559
- expect(pendingTasks.some((t) => t.id === task2.id)).toBe(true);
560
- expect(pendingTasks.some((t) => t.id === task1.id)).toBe(false);
561
-
562
- const inProgressTasks = await backend.list({ status: "in_progress" });
563
- expect(inProgressTasks.some((t) => t.id === task1.id)).toBe(true);
564
- expect(inProgressTasks.some((t) => t.id === task2.id)).toBe(false);
565
- }
566
- );
567
-
568
- it(
569
- "should filter tasks by assigned agent",
570
- { timeout: TEST_TIMEOUT },
571
- async () => {
572
- const task1 = await backend.create({
573
- description: "Task for Worker 1",
574
- created_by: "test",
575
- });
576
-
577
- const task2 = await backend.create({
578
- description: "Task for Worker 2",
579
- created_by: "test",
580
- });
581
-
582
- await backend.assign(task1.id, "worker-1");
583
- await backend.assign(task2.id, "worker-2");
584
-
585
- const worker1Tasks = await backend.list({ assigned_agent: "worker-1" });
586
- expect(worker1Tasks.length).toBe(1);
587
- expect(worker1Tasks[0].id).toBe(task1.id);
588
-
589
- const worker2Tasks = await backend.list({ assigned_agent: "worker-2" });
590
- expect(worker2Tasks.length).toBe(1);
591
- expect(worker2Tasks[0].id).toBe(task2.id);
592
- }
593
- );
594
- });
595
-
596
- describe("Subtask Hierarchy", () => {
597
- it(
598
- "should create and manage subtasks",
599
- { timeout: TEST_TIMEOUT },
600
- async () => {
601
- const parentIssue = await createTestIssue("E2E Parent Task Issue");
602
-
603
- const parentTask = await backend.create({
604
- description: "Parent task",
605
- created_by: "coordinator",
606
- external_id: parentIssue.id,
607
- });
608
-
609
- // Create subtasks
610
- const subtask1 = await backend.createSubtask(parentTask.id, {
611
- description: "Subtask 1",
612
- created_by: "coordinator",
613
- });
614
-
615
- const subtask2 = await backend.createSubtask(parentTask.id, {
616
- description: "Subtask 2",
617
- created_by: "coordinator",
618
- });
619
-
620
- expect(subtask1.parent_task).toBe(parentTask.id);
621
- expect(subtask2.parent_task).toBe(parentTask.id);
622
-
623
- // Get children
624
- const children = await backend.getChildren(parentTask.id);
625
- expect(children.length).toBe(2);
626
- expect(children.map((c) => c.id)).toContain(subtask1.id);
627
- expect(children.map((c) => c.id)).toContain(subtask2.id);
628
-
629
- // Get subtask status
630
- const status = await backend.getSubtaskStatus(parentTask.id);
631
- expect(status.total).toBe(2);
632
- expect(status.pending).toBe(2);
633
- expect(status.completed).toBe(0);
634
- expect(status.allCompleted).toBe(false);
635
-
636
- // Complete subtasks
637
- await backend.assign(subtask1.id, "worker-1");
638
- await backend.start(subtask1.id);
639
- await backend.complete(subtask1.id);
640
-
641
- await backend.assign(subtask2.id, "worker-2");
642
- await backend.start(subtask2.id);
643
- await backend.complete(subtask2.id);
644
-
645
- const finalStatus = await backend.getSubtaskStatus(parentTask.id);
646
- expect(finalStatus.completed).toBe(2);
647
- expect(finalStatus.allCompleted).toBe(true);
648
- }
649
- );
650
- });
651
-
652
- describe("Agent History", () => {
653
- it(
654
- "should track agent assignment history",
655
- { timeout: TEST_TIMEOUT },
656
- async () => {
657
- const task = await backend.create({
658
- description: "Task with history",
659
- created_by: "coordinator",
660
- });
661
-
662
- // First assignment
663
- await backend.assign(task.id, "worker-1");
664
- await backend.start(task.id);
665
-
666
- // Unassign and reassign
667
- await backend.unassign(task.id);
668
- await backend.assign(task.id, "worker-2");
669
- await backend.start(task.id);
670
- await backend.complete(task.id);
671
-
672
- // Check history
673
- const history = await backend.getAgentHistory(task.id);
674
- expect(history.length).toBeGreaterThanOrEqual(2);
675
- expect(history.some((h) => h.agent_id === "worker-1")).toBe(true);
676
- expect(history.some((h) => h.agent_id === "worker-2")).toBe(true);
677
- }
678
- );
679
- });
680
-
681
- describe("Event Subscriptions", () => {
682
- it(
683
- "should emit events on task changes",
684
- { timeout: TEST_TIMEOUT },
685
- async () => {
686
- const events: TaskChangeEvent[] = [];
687
-
688
- const unsubscribe = backend.onTaskChange((event) => {
689
- events.push(event);
690
- });
691
-
692
- try {
693
- const task = await backend.create({
694
- description: "Event test task",
695
- created_by: "test",
696
- });
697
-
698
- await backend.assign(task.id, "worker-1");
699
- await backend.start(task.id);
700
- await backend.complete(task.id);
701
-
702
- // Wait for events
703
- await new Promise((r) => setTimeout(r, 200));
704
-
705
- // Should have received events for create, assign, start, complete
706
- // Backend currently emits "updated" for all changes
707
- expect(events.length).toBeGreaterThanOrEqual(3);
708
-
709
- const eventTypes = events.map((e) => e.type);
710
- expect(eventTypes).toContain("updated");
711
- } finally {
712
- unsubscribe();
713
- }
714
- }
715
- );
716
-
717
- it(
718
- "should filter events by task ID",
719
- { timeout: TEST_TIMEOUT },
720
- async () => {
721
- const task1Events: TaskChangeEvent[] = [];
722
-
723
- const task1 = await backend.create({
724
- description: "Task 1 for events",
725
- created_by: "test",
726
- });
727
-
728
- const task2 = await backend.create({
729
- description: "Task 2 for events",
730
- created_by: "test",
731
- });
732
-
733
- const unsubscribe = backend.onTaskChange(task1.id, (event) => {
734
- task1Events.push(event);
735
- });
736
-
737
- try {
738
- await backend.assign(task1.id, "worker-1");
739
- await backend.assign(task2.id, "worker-2");
740
- await backend.start(task1.id);
741
- await backend.start(task2.id);
742
-
743
- await new Promise((r) => setTimeout(r, 200));
744
-
745
- // Should only have events for task1
746
- expect(task1Events.every((e) => e.taskId === task1.id)).toBe(true);
747
- } finally {
748
- unsubscribe();
749
- }
750
- }
751
- );
752
- });
753
- });