macro-agent 0.0.17 → 0.1.1

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 (338) hide show
  1. package/.claude/settings.local.json +3 -1
  2. package/.sudocode/specs.jsonl +4 -0
  3. package/CLAUDE.md +16 -14
  4. package/README.md +11 -29
  5. package/dist/acp/macro-agent.d.ts +17 -0
  6. package/dist/acp/macro-agent.d.ts.map +1 -1
  7. package/dist/acp/macro-agent.js +183 -55
  8. package/dist/acp/macro-agent.js.map +1 -1
  9. package/dist/acp/types.d.ts +32 -1
  10. package/dist/acp/types.d.ts.map +1 -1
  11. package/dist/acp/types.js.map +1 -1
  12. package/dist/agent/agent-manager.d.ts +65 -1
  13. package/dist/agent/agent-manager.d.ts.map +1 -1
  14. package/dist/agent/agent-manager.js +464 -183
  15. package/dist/agent/agent-manager.js.map +1 -1
  16. package/dist/agent/types.d.ts +1 -1
  17. package/dist/agent/types.d.ts.map +1 -1
  18. package/dist/api/server.d.ts +3 -0
  19. package/dist/api/server.d.ts.map +1 -1
  20. package/dist/api/server.js +37 -6
  21. package/dist/api/server.js.map +1 -1
  22. package/dist/auth/index.d.ts +2 -0
  23. package/dist/auth/index.d.ts.map +1 -0
  24. package/dist/auth/index.js +2 -0
  25. package/dist/auth/index.js.map +1 -0
  26. package/dist/auth/token.d.ts +41 -0
  27. package/dist/auth/token.d.ts.map +1 -0
  28. package/dist/auth/token.js +73 -0
  29. package/dist/auth/token.js.map +1 -0
  30. package/dist/cli/acp.d.ts +2 -23
  31. package/dist/cli/acp.d.ts.map +1 -1
  32. package/dist/cli/acp.js +127 -61
  33. package/dist/cli/acp.js.map +1 -1
  34. package/dist/cli/index.js +147 -15
  35. package/dist/cli/index.js.map +1 -1
  36. package/dist/cli/mcp.d.ts +6 -0
  37. package/dist/cli/mcp.d.ts.map +1 -1
  38. package/dist/cli/mcp.js +268 -181
  39. package/dist/cli/mcp.js.map +1 -1
  40. package/dist/cli/parse-args.d.ts +20 -0
  41. package/dist/cli/parse-args.d.ts.map +1 -0
  42. package/dist/cli/parse-args.js +43 -0
  43. package/dist/cli/parse-args.js.map +1 -0
  44. package/dist/cli/stable-instance-id.d.ts +8 -0
  45. package/dist/cli/stable-instance-id.d.ts.map +1 -0
  46. package/dist/cli/stable-instance-id.js +14 -0
  47. package/dist/cli/stable-instance-id.js.map +1 -0
  48. package/dist/config/project-config.d.ts +74 -7
  49. package/dist/config/project-config.d.ts.map +1 -1
  50. package/dist/config/project-config.js +123 -20
  51. package/dist/config/project-config.js.map +1 -1
  52. package/dist/map/adapter/acp-over-map.d.ts +23 -0
  53. package/dist/map/adapter/acp-over-map.d.ts.map +1 -1
  54. package/dist/map/adapter/acp-over-map.js +482 -55
  55. package/dist/map/adapter/acp-over-map.js.map +1 -1
  56. package/dist/map/adapter/connection-manager.d.ts.map +1 -1
  57. package/dist/map/adapter/connection-manager.js +3 -0
  58. package/dist/map/adapter/connection-manager.js.map +1 -1
  59. package/dist/map/adapter/event-log.d.ts +87 -0
  60. package/dist/map/adapter/event-log.d.ts.map +1 -0
  61. package/dist/map/adapter/event-log.js +122 -0
  62. package/dist/map/adapter/event-log.js.map +1 -0
  63. package/dist/map/adapter/event-translator.js +6 -6
  64. package/dist/map/adapter/event-translator.js.map +1 -1
  65. package/dist/map/adapter/extensions/agent-lifecycle.d.ts +82 -0
  66. package/dist/map/adapter/extensions/agent-lifecycle.d.ts.map +1 -0
  67. package/dist/map/adapter/extensions/agent-lifecycle.js +164 -0
  68. package/dist/map/adapter/extensions/agent-lifecycle.js.map +1 -0
  69. package/dist/map/adapter/extensions/index.d.ts +10 -1
  70. package/dist/map/adapter/extensions/index.d.ts.map +1 -1
  71. package/dist/map/adapter/extensions/index.js +34 -0
  72. package/dist/map/adapter/extensions/index.js.map +1 -1
  73. package/dist/map/adapter/extensions/mcp-bridge.d.ts +57 -0
  74. package/dist/map/adapter/extensions/mcp-bridge.d.ts.map +1 -0
  75. package/dist/map/adapter/extensions/mcp-bridge.js +745 -0
  76. package/dist/map/adapter/extensions/mcp-bridge.js.map +1 -0
  77. package/dist/map/adapter/extensions/rename.d.ts +29 -0
  78. package/dist/map/adapter/extensions/rename.d.ts.map +1 -0
  79. package/dist/map/adapter/extensions/rename.js +49 -0
  80. package/dist/map/adapter/extensions/rename.js.map +1 -0
  81. package/dist/map/adapter/extensions/task.d.ts.map +1 -1
  82. package/dist/map/adapter/extensions/task.js +10 -0
  83. package/dist/map/adapter/extensions/task.js.map +1 -1
  84. package/dist/map/adapter/extensions/update-metadata.d.ts +29 -0
  85. package/dist/map/adapter/extensions/update-metadata.d.ts.map +1 -0
  86. package/dist/map/adapter/extensions/update-metadata.js +67 -0
  87. package/dist/map/adapter/extensions/update-metadata.js.map +1 -0
  88. package/dist/map/adapter/index.d.ts +2 -1
  89. package/dist/map/adapter/index.d.ts.map +1 -1
  90. package/dist/map/adapter/index.js +8 -2
  91. package/dist/map/adapter/index.js.map +1 -1
  92. package/dist/map/adapter/interface.d.ts +2 -0
  93. package/dist/map/adapter/interface.d.ts.map +1 -1
  94. package/dist/map/adapter/map-adapter.d.ts +4 -0
  95. package/dist/map/adapter/map-adapter.d.ts.map +1 -1
  96. package/dist/map/adapter/map-adapter.js +302 -30
  97. package/dist/map/adapter/map-adapter.js.map +1 -1
  98. package/dist/map/adapter/subscription-manager.d.ts.map +1 -1
  99. package/dist/map/adapter/subscription-manager.js +5 -1
  100. package/dist/map/adapter/subscription-manager.js.map +1 -1
  101. package/dist/map/adapter/types.d.ts +2 -0
  102. package/dist/map/adapter/types.d.ts.map +1 -1
  103. package/dist/mcp/map-client.d.ts +39 -0
  104. package/dist/mcp/map-client.d.ts.map +1 -0
  105. package/dist/mcp/map-client.js +129 -0
  106. package/dist/mcp/map-client.js.map +1 -0
  107. package/dist/mcp/mcp-server.d.ts +14 -0
  108. package/dist/mcp/mcp-server.d.ts.map +1 -1
  109. package/dist/mcp/mcp-server.js +113 -85
  110. package/dist/mcp/mcp-server.js.map +1 -1
  111. package/dist/mcp/types.d.ts +9 -1
  112. package/dist/mcp/types.d.ts.map +1 -1
  113. package/dist/mcp/types.js.map +1 -1
  114. package/dist/metrics/metrics.js +1 -1
  115. package/dist/metrics/metrics.js.map +1 -1
  116. package/dist/roles/capabilities.d.ts +3 -1
  117. package/dist/roles/capabilities.d.ts.map +1 -1
  118. package/dist/roles/capabilities.js +17 -7
  119. package/dist/roles/capabilities.js.map +1 -1
  120. package/dist/roles/config-loader.d.ts +6 -6
  121. package/dist/roles/config-loader.d.ts.map +1 -1
  122. package/dist/roles/config-loader.js +6 -6
  123. package/dist/roles/config-loader.js.map +1 -1
  124. package/dist/roles/registry.d.ts +2 -2
  125. package/dist/roles/registry.js +2 -2
  126. package/dist/server/combined-server.d.ts +20 -0
  127. package/dist/server/combined-server.d.ts.map +1 -1
  128. package/dist/server/combined-server.js +107 -8
  129. package/dist/server/combined-server.js.map +1 -1
  130. package/dist/store/event-store.d.ts +7 -1
  131. package/dist/store/event-store.d.ts.map +1 -1
  132. package/dist/store/event-store.js +91 -8
  133. package/dist/store/event-store.js.map +1 -1
  134. package/dist/store/types/agents.d.ts +23 -0
  135. package/dist/store/types/agents.d.ts.map +1 -1
  136. package/dist/store/types/events.d.ts +1 -1
  137. package/dist/store/types/events.d.ts.map +1 -1
  138. package/dist/task/backend/index.d.ts +47 -29
  139. package/dist/task/backend/index.d.ts.map +1 -1
  140. package/dist/task/backend/index.js +109 -71
  141. package/dist/task/backend/index.js.map +1 -1
  142. package/dist/task/backend/memory.d.ts +1 -0
  143. package/dist/task/backend/memory.d.ts.map +1 -1
  144. package/dist/task/backend/memory.js +3 -0
  145. package/dist/task/backend/memory.js.map +1 -1
  146. package/dist/task/backend/opentasks/backend.d.ts +140 -0
  147. package/dist/task/backend/opentasks/backend.d.ts.map +1 -0
  148. package/dist/task/backend/opentasks/backend.js +1023 -0
  149. package/dist/task/backend/opentasks/backend.js.map +1 -0
  150. package/dist/task/backend/opentasks/client.d.ts +337 -0
  151. package/dist/task/backend/opentasks/client.d.ts.map +1 -0
  152. package/dist/task/backend/opentasks/client.js +225 -0
  153. package/dist/task/backend/opentasks/client.js.map +1 -0
  154. package/dist/task/backend/opentasks/daemon-manager.d.ts +89 -0
  155. package/dist/task/backend/opentasks/daemon-manager.d.ts.map +1 -0
  156. package/dist/task/backend/opentasks/daemon-manager.js +195 -0
  157. package/dist/task/backend/opentasks/daemon-manager.js.map +1 -0
  158. package/dist/task/backend/opentasks/index.d.ts +21 -0
  159. package/dist/task/backend/opentasks/index.d.ts.map +1 -0
  160. package/dist/task/backend/opentasks/index.js +21 -0
  161. package/dist/task/backend/opentasks/index.js.map +1 -0
  162. package/dist/task/backend/opentasks/mapping.d.ts +48 -0
  163. package/dist/task/backend/opentasks/mapping.d.ts.map +1 -0
  164. package/dist/task/backend/opentasks/mapping.js +77 -0
  165. package/dist/task/backend/opentasks/mapping.js.map +1 -0
  166. package/dist/task/backend/types.d.ts +33 -53
  167. package/dist/task/backend/types.d.ts.map +1 -1
  168. package/dist/task/backend/types.js +7 -11
  169. package/dist/task/backend/types.js.map +1 -1
  170. package/dist/task/backend/unified-tool-provider.d.ts +57 -0
  171. package/dist/task/backend/unified-tool-provider.d.ts.map +1 -0
  172. package/dist/task/backend/unified-tool-provider.js +623 -0
  173. package/dist/task/backend/unified-tool-provider.js.map +1 -0
  174. package/dist/teams/team-loader.d.ts +2 -2
  175. package/dist/teams/team-loader.js +3 -3
  176. package/dist/teams/team-loader.js.map +1 -1
  177. package/dist/teams/team-runtime.d.ts.map +1 -1
  178. package/dist/teams/team-runtime.js +2 -0
  179. package/dist/teams/team-runtime.js.map +1 -1
  180. package/docs/architecture.md +7 -6
  181. package/docs/configuration.md +26 -62
  182. package/docs/implementation-details.md +5 -5
  183. package/docs/implementation-summary.md +17 -17
  184. package/docs/plan-self-driving-support.md +4 -4
  185. package/docs/spec-self-driving-support.md +10 -10
  186. package/docs/team-templates.md +2 -2
  187. package/docs/teams.md +3 -3
  188. package/docs/troubleshooting.md +10 -11
  189. package/package.json +6 -4
  190. package/src/__tests__/e2e/agent-spawn-visibility.e2e.test.ts +761 -0
  191. package/src/__tests__/e2e/full-agent-conflict-resolution.e2e.test.ts +2 -2
  192. package/src/__tests__/e2e/mcp-thin-client-bridge.e2e.test.ts +304 -0
  193. package/src/__tests__/e2e/mcp-tools-available.e2e.test.ts +324 -0
  194. package/src/__tests__/e2e/multi-agent.e2e.test.ts +5 -5
  195. package/src/__tests__/e2e/spawn-session-streaming.e2e.test.ts +563 -0
  196. package/src/acp/__tests__/history.test.ts +8 -4
  197. package/src/acp/__tests__/integration.test.ts +56 -31
  198. package/src/acp/__tests__/macro-agent.test.ts +16 -7
  199. package/src/acp/macro-agent.ts +230 -62
  200. package/src/acp/types.ts +46 -1
  201. package/src/agent/__tests__/agent-manager.test.ts +228 -2
  202. package/src/agent/agent-manager.ts +714 -261
  203. package/src/agent/types.ts +3 -1
  204. package/src/api/server.ts +41 -7
  205. package/src/auth/__tests__/token.test.ts +100 -0
  206. package/src/auth/index.ts +1 -0
  207. package/src/auth/token.ts +82 -0
  208. package/src/cli/__tests__/acp.test.ts +1 -1
  209. package/src/cli/__tests__/stable-instance-id.test.ts +1 -1
  210. package/src/cli/acp.ts +130 -72
  211. package/src/cli/index.ts +120 -14
  212. package/src/cli/mcp.ts +311 -207
  213. package/src/cli/parse-args.ts +54 -0
  214. package/src/cli/stable-instance-id.ts +14 -0
  215. package/src/config/project-config.ts +190 -27
  216. package/src/lifecycle/__tests__/cascade-termination.test.ts +1 -1
  217. package/src/map/adapter/__tests__/acp-over-map-cancel.test.ts +820 -0
  218. package/src/map/adapter/__tests__/acp-over-map-getmodels.test.ts +355 -0
  219. package/src/map/adapter/__tests__/acp-over-map-history.test.ts +724 -2
  220. package/src/map/adapter/__tests__/acp-over-map-persistence.e2e.test.ts +1 -1
  221. package/src/map/adapter/__tests__/event-broadcast.test.ts +420 -0
  222. package/src/map/adapter/__tests__/event-log.test.ts +527 -0
  223. package/src/map/adapter/__tests__/event-translator.test.ts +3 -3
  224. package/src/map/adapter/__tests__/extensions.test.ts +408 -0
  225. package/src/map/adapter/__tests__/map-adapter.test.ts +99 -0
  226. package/src/map/adapter/__tests__/mcp-bridge.test.ts +1187 -0
  227. package/src/map/adapter/__tests__/multi-client-broadcast.test.ts +711 -0
  228. package/src/map/adapter/__tests__/websocket-integration.test.ts +218 -0
  229. package/src/map/adapter/acp-over-map.ts +777 -92
  230. package/src/map/adapter/connection-manager.ts +3 -0
  231. package/src/map/adapter/event-log.ts +208 -0
  232. package/src/map/adapter/event-translator.ts +6 -6
  233. package/src/map/adapter/extensions/agent-lifecycle.ts +267 -0
  234. package/src/map/adapter/extensions/index.ts +60 -0
  235. package/src/map/adapter/extensions/mcp-bridge.ts +995 -0
  236. package/src/map/adapter/extensions/task.ts +11 -0
  237. package/src/map/adapter/extensions/update-metadata.ts +126 -0
  238. package/src/map/adapter/index.ts +28 -0
  239. package/src/map/adapter/interface.ts +2 -0
  240. package/src/map/adapter/map-adapter.ts +373 -38
  241. package/src/map/adapter/subscription-manager.ts +5 -1
  242. package/src/map/adapter/types.ts +2 -0
  243. package/src/mcp/__tests__/map-client.test.ts +386 -0
  244. package/src/mcp/__tests__/mcp-server-thin-client.test.ts +368 -0
  245. package/src/mcp/__tests__/mcp-server.test.ts +100 -1
  246. package/src/mcp/map-client.ts +177 -0
  247. package/src/mcp/mcp-server.ts +191 -100
  248. package/src/mcp/types.ts +6 -1
  249. package/src/metrics/metrics.ts +1 -1
  250. package/src/monitor/__tests__/stale-agent-flow.integration.test.ts +1 -1
  251. package/src/roles/__tests__/config-loader.test.ts +7 -7
  252. package/src/roles/capabilities.ts +17 -7
  253. package/src/roles/config-loader.ts +6 -6
  254. package/src/roles/registry.ts +2 -2
  255. package/src/server/__tests__/combined-server.test.ts +94 -21
  256. package/src/server/combined-server.ts +189 -33
  257. package/src/steering/__tests__/steering-integration.test.ts +1 -1
  258. package/src/store/__tests__/event-store.test.ts +236 -1
  259. package/src/store/__tests__/instance.test.ts +3 -3
  260. package/src/store/event-store.ts +109 -8
  261. package/src/store/types/agents.ts +16 -0
  262. package/src/store/types/events.ts +1 -1
  263. package/src/task/backend/__tests__/create-task-backend.test.ts +225 -0
  264. package/src/task/backend/__tests__/e2e/unified-tool-provider-opentasks.e2e.test.ts +524 -0
  265. package/src/task/backend/__tests__/unified-tool-provider.test.ts +579 -0
  266. package/src/task/backend/index.ts +156 -106
  267. package/src/task/backend/memory.ts +4 -0
  268. package/src/task/backend/opentasks/__tests__/backend.test.ts +968 -0
  269. package/src/task/backend/opentasks/__tests__/daemon-manager.test.ts +406 -0
  270. package/src/task/backend/opentasks/__tests__/mapping.test.ts +84 -0
  271. package/src/task/backend/opentasks/__tests__/opentasks-backend.e2e.test.ts +1338 -0
  272. package/src/task/backend/opentasks/backend.ts +1323 -0
  273. package/src/task/backend/opentasks/client.ts +652 -0
  274. package/src/task/backend/opentasks/daemon-manager.ts +253 -0
  275. package/src/task/backend/opentasks/index.ts +69 -0
  276. package/src/task/backend/opentasks/mapping.ts +94 -0
  277. package/src/task/backend/types.ts +42 -66
  278. package/src/task/backend/unified-tool-provider.ts +779 -0
  279. package/src/teams/__tests__/cross-subsystem.integration.test.ts +1 -1
  280. package/src/teams/team-loader.ts +3 -3
  281. package/src/teams/team-runtime.ts +2 -0
  282. package/test_fixtures/README.md +2 -3
  283. package/test_fixtures/fixtures/index.ts +0 -3
  284. package/test_fixtures/fixtures/projects/project-with-specs.ts +7 -149
  285. package/test_fixtures/fixtures/repos/index.ts +1 -3
  286. package/test_fixtures/fixtures/repos/temp-repo-factory.ts +0 -116
  287. package/test_fixtures/fixtures/repos/types.ts +0 -11
  288. package/test_fixtures/harness/__tests__/fixtures.test.ts +10 -102
  289. package/test_fixtures/harness/__tests__/temp-repo-and-simulator.test.ts +0 -33
  290. package/test_fixtures/harness/simulator/agent-simulator.ts +4 -4
  291. package/vitest.config.ts +1 -1
  292. package/vitest.e2e.config.ts +1 -1
  293. package/vitest.setup.ts +1 -30
  294. package/.macro-agent/teams/self-driving/prompts/grinder.md +0 -27
  295. package/.macro-agent/teams/self-driving/prompts/judge.md +0 -27
  296. package/.macro-agent/teams/self-driving/prompts/planner.md +0 -33
  297. package/.macro-agent/teams/self-driving/roles/grinder.yaml +0 -17
  298. package/.macro-agent/teams/self-driving/roles/judge.yaml +0 -24
  299. package/.macro-agent/teams/self-driving/roles/planner.yaml +0 -18
  300. package/.macro-agent/teams/self-driving/team.yaml +0 -103
  301. package/.macro-agent/teams/structured/prompts/developer.md +0 -26
  302. package/.macro-agent/teams/structured/prompts/lead.md +0 -25
  303. package/.macro-agent/teams/structured/prompts/reviewer.md +0 -24
  304. package/.macro-agent/teams/structured/roles/developer.yaml +0 -12
  305. package/.macro-agent/teams/structured/roles/lead.yaml +0 -11
  306. package/.macro-agent/teams/structured/roles/reviewer.yaml +0 -19
  307. package/.macro-agent/teams/structured/team.yaml +0 -89
  308. package/docs/sudocode-integration.md +0 -383
  309. package/src/task/backend/__tests__/backend-parity.test.ts +0 -451
  310. package/src/task/backend/__tests__/tool-provider-edge-cases.test.ts +0 -430
  311. package/src/task/backend/__tests__/tool-provider.test.ts +0 -983
  312. package/src/task/backend/sudocode/__tests__/backend-edge-cases.test.ts +0 -575
  313. package/src/task/backend/sudocode/__tests__/backend.test.ts +0 -1194
  314. package/src/task/backend/sudocode/__tests__/client-integration.test.ts +0 -418
  315. package/src/task/backend/sudocode/__tests__/client.test.ts +0 -345
  316. package/src/task/backend/sudocode/__tests__/e2e/backend.e2e.test.ts +0 -753
  317. package/src/task/backend/sudocode/__tests__/e2e/server-client.e2e.test.ts +0 -680
  318. package/src/task/backend/sudocode/__tests__/e2e-workflow.test.ts +0 -666
  319. package/src/task/backend/sudocode/__tests__/integration/standalone-client.integration.test.ts +0 -396
  320. package/src/task/backend/sudocode/__tests__/integration/sudocode-cli.integration.test.ts +0 -328
  321. package/src/task/backend/sudocode/__tests__/integration/test-utils.ts +0 -175
  322. package/src/task/backend/sudocode/__tests__/mapping-edge-cases.test.ts +0 -265
  323. package/src/task/backend/sudocode/__tests__/server-client.test.ts +0 -675
  324. package/src/task/backend/sudocode/__tests__/sync-policy-edge-cases.test.ts +0 -521
  325. package/src/task/backend/sudocode/__tests__/sync-policy.test.ts +0 -519
  326. package/src/task/backend/sudocode/__tests__/tools.test.ts +0 -471
  327. package/src/task/backend/sudocode/backend.ts +0 -1237
  328. package/src/task/backend/sudocode/client.ts +0 -515
  329. package/src/task/backend/sudocode/index.ts +0 -120
  330. package/src/task/backend/sudocode/mapping.ts +0 -93
  331. package/src/task/backend/sudocode/server-client.ts +0 -522
  332. package/src/task/backend/sudocode/standalone-client.ts +0 -623
  333. package/src/task/backend/sudocode/sync-policy.ts +0 -387
  334. package/src/task/backend/sudocode/tools.ts +0 -896
  335. package/src/task/backend/tool-provider.ts +0 -506
  336. package/test_fixtures/fixtures/sudocode/index.ts +0 -29
  337. package/test_fixtures/fixtures/sudocode/issues.ts +0 -185
  338. package/test_fixtures/fixtures/sudocode/specs.ts +0 -159
@@ -1,328 +0,0 @@
1
- /**
2
- * Integration tests for Sudocode CLI operations
3
- *
4
- * These tests use the real @sudocode-ai/cli package with a temp SQLite database
5
- * to verify that our integration with sudocode works correctly.
6
- */
7
-
8
- import { describe, it, expect, beforeEach, afterEach } from "vitest";
9
- import {
10
- createTestContext,
11
- createTestIssue,
12
- createTestSpec,
13
- createBlockingRelationship,
14
- createImplementsRelationship,
15
- getIssue,
16
- listIssues,
17
- updateIssue,
18
- getSpec,
19
- listSpecs,
20
- getOutgoingRelationships,
21
- getIncomingRelationships,
22
- getReadyIssues,
23
- type TestContext,
24
- } from "./test-utils.js";
25
-
26
- describe("Sudocode CLI Integration", () => {
27
- let ctx: TestContext;
28
-
29
- beforeEach(() => {
30
- ctx = createTestContext();
31
- });
32
-
33
- afterEach(() => {
34
- ctx.cleanup();
35
- });
36
-
37
- describe("Issue Operations", () => {
38
- it("should create and retrieve an issue", () => {
39
- const issue = createTestIssue(ctx, {
40
- title: "Test Issue",
41
- content: "Test content",
42
- });
43
-
44
- expect(issue.id).toMatch(/^i-/);
45
- expect(issue.title).toBe("Test Issue");
46
- expect(issue.content).toBe("Test content");
47
- expect(issue.status).toBe("open");
48
- expect(issue.priority).toBe(2);
49
-
50
- const retrieved = getIssue(ctx.db, issue.id);
51
- expect(retrieved).toEqual(issue);
52
- });
53
-
54
- it("should list issues with filters", () => {
55
- const issue1 = createTestIssue(ctx, { title: "Issue 1", status: "open" });
56
- const issue2 = createTestIssue(ctx, {
57
- title: "Issue 2",
58
- status: "in_progress",
59
- });
60
- const issue3 = createTestIssue(ctx, {
61
- title: "Issue 3",
62
- status: "closed",
63
- });
64
-
65
- const allIssues = listIssues(ctx.db);
66
- expect(allIssues).toHaveLength(3);
67
-
68
- const openIssues = listIssues(ctx.db, { status: "open" });
69
- expect(openIssues).toHaveLength(1);
70
- expect(openIssues[0].id).toBe(issue1.id);
71
-
72
- const inProgressIssues = listIssues(ctx.db, { status: "in_progress" });
73
- expect(inProgressIssues).toHaveLength(1);
74
- expect(inProgressIssues[0].id).toBe(issue2.id);
75
-
76
- const closedIssues = listIssues(ctx.db, { status: "closed" });
77
- expect(closedIssues).toHaveLength(1);
78
- expect(closedIssues[0].id).toBe(issue3.id);
79
- });
80
-
81
- it("should update an issue", () => {
82
- const issue = createTestIssue(ctx, { title: "Original Title" });
83
-
84
- const updated = updateIssue(ctx.db, issue.id, {
85
- title: "Updated Title",
86
- status: "in_progress",
87
- });
88
-
89
- expect(updated.title).toBe("Updated Title");
90
- expect(updated.status).toBe("in_progress");
91
-
92
- const retrieved = getIssue(ctx.db, issue.id);
93
- expect(retrieved?.title).toBe("Updated Title");
94
- expect(retrieved?.status).toBe("in_progress");
95
- });
96
-
97
- it("should support issue hierarchy (parent/child)", () => {
98
- const parent = createTestIssue(ctx, { title: "Parent Issue" });
99
- const child = createTestIssue(ctx, {
100
- title: "Child Issue",
101
- parent_id: parent.id,
102
- });
103
-
104
- expect(child.parent_id).toBe(parent.id);
105
-
106
- const children = listIssues(ctx.db, { parent_id: parent.id });
107
- expect(children).toHaveLength(1);
108
- expect(children[0].id).toBe(child.id);
109
- });
110
- });
111
-
112
- describe("Spec Operations", () => {
113
- it("should create and retrieve a spec", () => {
114
- const spec = createTestSpec(ctx, {
115
- title: "Test Spec",
116
- content: "Spec content",
117
- });
118
-
119
- expect(spec.id).toMatch(/^s-/);
120
- expect(spec.title).toBe("Test Spec");
121
- expect(spec.content).toBe("Spec content");
122
- expect(spec.priority).toBe(2);
123
-
124
- const retrieved = getSpec(ctx.db, spec.id);
125
- expect(retrieved).toEqual(spec);
126
- });
127
-
128
- it("should list specs", () => {
129
- createTestSpec(ctx, { title: "Spec 1" });
130
- createTestSpec(ctx, { title: "Spec 2" });
131
- createTestSpec(ctx, { title: "Spec 3" });
132
-
133
- const specs = listSpecs(ctx.db);
134
- expect(specs).toHaveLength(3);
135
- });
136
- });
137
-
138
- describe("Relationship Operations", () => {
139
- it("should create a blocking relationship between issues", () => {
140
- const blocker = createTestIssue(ctx, { title: "Blocker Issue" });
141
- const blocked = createTestIssue(ctx, { title: "Blocked Issue" });
142
-
143
- createBlockingRelationship(ctx.db, blocker.id, blocked.id);
144
-
145
- // Check outgoing relationships from blocker
146
- const outgoing = getOutgoingRelationships(ctx.db, blocker.id, "issue");
147
- expect(outgoing).toHaveLength(1);
148
- expect(outgoing[0].to_id).toBe(blocked.id);
149
- expect(outgoing[0].relationship_type).toBe("blocks");
150
-
151
- // Check incoming relationships to blocked
152
- const incoming = getIncomingRelationships(ctx.db, blocked.id, "issue");
153
- expect(incoming).toHaveLength(1);
154
- expect(incoming[0].from_id).toBe(blocker.id);
155
- expect(incoming[0].relationship_type).toBe("blocks");
156
- });
157
-
158
- it("should create an implements relationship between issue and spec", () => {
159
- const spec = createTestSpec(ctx, { title: "Feature Spec" });
160
- const issue = createTestIssue(ctx, { title: "Implement Feature" });
161
-
162
- createImplementsRelationship(ctx.db, issue.id, spec.id);
163
-
164
- // Check outgoing from issue
165
- const outgoing = getOutgoingRelationships(ctx.db, issue.id, "issue");
166
- expect(outgoing).toHaveLength(1);
167
- expect(outgoing[0].to_id).toBe(spec.id);
168
- expect(outgoing[0].relationship_type).toBe("implements");
169
-
170
- // Check incoming to spec
171
- const incoming = getIncomingRelationships(ctx.db, spec.id, "spec");
172
- expect(incoming).toHaveLength(1);
173
- expect(incoming[0].from_id).toBe(issue.id);
174
- });
175
-
176
- it("should auto-update blocked status when adding a blocks relationship", () => {
177
- const blocker = createTestIssue(ctx, { title: "Blocker", status: "open" });
178
- const blocked = createTestIssue(ctx, { title: "Blocked", status: "open" });
179
-
180
- // Adding a blocks relationship should set the blocked issue to 'blocked' status
181
- createBlockingRelationship(ctx.db, blocker.id, blocked.id);
182
-
183
- const updatedBlocked = getIssue(ctx.db, blocked.id);
184
- expect(updatedBlocked?.status).toBe("blocked");
185
- });
186
-
187
- it("should auto-unblock when blocker is closed", () => {
188
- const blocker = createTestIssue(ctx, { title: "Blocker", status: "open" });
189
- const blocked = createTestIssue(ctx, { title: "Blocked", status: "open" });
190
-
191
- createBlockingRelationship(ctx.db, blocker.id, blocked.id);
192
-
193
- // Verify blocked is now 'blocked'
194
- let blockedIssue = getIssue(ctx.db, blocked.id);
195
- expect(blockedIssue?.status).toBe("blocked");
196
-
197
- // Close the blocker
198
- updateIssue(ctx.db, blocker.id, { status: "closed" });
199
-
200
- // Blocked issue should now be 'open' again
201
- blockedIssue = getIssue(ctx.db, blocked.id);
202
- expect(blockedIssue?.status).toBe("open");
203
- });
204
- });
205
-
206
- describe("Ready Issues", () => {
207
- it("should return issues without blockers", () => {
208
- const ready1 = createTestIssue(ctx, { title: "Ready 1", status: "open" });
209
- const ready2 = createTestIssue(ctx, { title: "Ready 2", status: "open" });
210
- const blocker = createTestIssue(ctx, {
211
- title: "Blocker",
212
- status: "open",
213
- });
214
- const blocked = createTestIssue(ctx, {
215
- title: "Blocked",
216
- status: "open",
217
- });
218
-
219
- createBlockingRelationship(ctx.db, blocker.id, blocked.id);
220
-
221
- const readyIssues = getReadyIssues(ctx.db);
222
-
223
- // ready1, ready2, and blocker should be ready (not blocked)
224
- // blocked should NOT be in ready list
225
- const readyIds = readyIssues.map((i) => i.id);
226
- expect(readyIds).toContain(ready1.id);
227
- expect(readyIds).toContain(ready2.id);
228
- expect(readyIds).toContain(blocker.id);
229
- expect(readyIds).not.toContain(blocked.id);
230
- });
231
-
232
- it("should include previously blocked issues after blocker is closed", () => {
233
- const blocker = createTestIssue(ctx, { title: "Blocker", status: "open" });
234
- const blocked = createTestIssue(ctx, { title: "Blocked", status: "open" });
235
-
236
- createBlockingRelationship(ctx.db, blocker.id, blocked.id);
237
-
238
- // Initially blocked is not ready
239
- let readyIssues = getReadyIssues(ctx.db);
240
- let readyIds = readyIssues.map((i) => i.id);
241
- expect(readyIds).not.toContain(blocked.id);
242
-
243
- // Close the blocker
244
- updateIssue(ctx.db, blocker.id, { status: "closed" });
245
-
246
- // Now blocked should be ready
247
- readyIssues = getReadyIssues(ctx.db);
248
- readyIds = readyIssues.map((i) => i.id);
249
- expect(readyIds).toContain(blocked.id);
250
- });
251
- });
252
-
253
- describe("Complex Scenarios", () => {
254
- it("should handle a chain of blockers", () => {
255
- // Create a chain: A blocks B blocks C
256
- const issueA = createTestIssue(ctx, { title: "Issue A", status: "open" });
257
- const issueB = createTestIssue(ctx, { title: "Issue B", status: "open" });
258
- const issueC = createTestIssue(ctx, { title: "Issue C", status: "open" });
259
-
260
- createBlockingRelationship(ctx.db, issueA.id, issueB.id);
261
- createBlockingRelationship(ctx.db, issueB.id, issueC.id);
262
-
263
- // Only A should be ready
264
- let readyIssues = getReadyIssues(ctx.db);
265
- let readyIds = readyIssues.map((i) => i.id);
266
- expect(readyIds).toContain(issueA.id);
267
- expect(readyIds).not.toContain(issueB.id);
268
- expect(readyIds).not.toContain(issueC.id);
269
-
270
- // Close A - B should become ready, C still blocked
271
- updateIssue(ctx.db, issueA.id, { status: "closed" });
272
- readyIssues = getReadyIssues(ctx.db);
273
- readyIds = readyIssues.map((i) => i.id);
274
- expect(readyIds).toContain(issueB.id);
275
- expect(readyIds).not.toContain(issueC.id);
276
-
277
- // Close B - C should become ready
278
- updateIssue(ctx.db, issueB.id, { status: "closed" });
279
- readyIssues = getReadyIssues(ctx.db);
280
- readyIds = readyIssues.map((i) => i.id);
281
- expect(readyIds).toContain(issueC.id);
282
- });
283
-
284
- it("should handle multiple blockers", () => {
285
- // C is blocked by both A and B
286
- const issueA = createTestIssue(ctx, { title: "Issue A", status: "open" });
287
- const issueB = createTestIssue(ctx, { title: "Issue B", status: "open" });
288
- const issueC = createTestIssue(ctx, { title: "Issue C", status: "open" });
289
-
290
- createBlockingRelationship(ctx.db, issueA.id, issueC.id);
291
- createBlockingRelationship(ctx.db, issueB.id, issueC.id);
292
-
293
- // C should be blocked
294
- let issueC_status = getIssue(ctx.db, issueC.id);
295
- expect(issueC_status?.status).toBe("blocked");
296
-
297
- // Close A - C should still be blocked by B
298
- updateIssue(ctx.db, issueA.id, { status: "closed" });
299
- issueC_status = getIssue(ctx.db, issueC.id);
300
- expect(issueC_status?.status).toBe("blocked");
301
-
302
- // Close B - C should now be unblocked
303
- updateIssue(ctx.db, issueB.id, { status: "closed" });
304
- issueC_status = getIssue(ctx.db, issueC.id);
305
- expect(issueC_status?.status).toBe("open");
306
- });
307
-
308
- it("should handle spec with multiple implementing issues", () => {
309
- const spec = createTestSpec(ctx, { title: "Feature Spec" });
310
- const issue1 = createTestIssue(ctx, { title: "Part 1" });
311
- const issue2 = createTestIssue(ctx, { title: "Part 2" });
312
- const issue3 = createTestIssue(ctx, { title: "Part 3" });
313
-
314
- createImplementsRelationship(ctx.db, issue1.id, spec.id);
315
- createImplementsRelationship(ctx.db, issue2.id, spec.id);
316
- createImplementsRelationship(ctx.db, issue3.id, spec.id);
317
-
318
- // All issues should reference the spec
319
- const incoming = getIncomingRelationships(ctx.db, spec.id, "spec");
320
- expect(incoming).toHaveLength(3);
321
-
322
- const implementerIds = incoming.map((r) => r.from_id);
323
- expect(implementerIds).toContain(issue1.id);
324
- expect(implementerIds).toContain(issue2.id);
325
- expect(implementerIds).toContain(issue3.id);
326
- });
327
- });
328
- });
@@ -1,175 +0,0 @@
1
- /**
2
- * Integration Test Utilities for Sudocode
3
- *
4
- * Provides helpers for creating real sudocode databases and test fixtures.
5
- */
6
-
7
- import { mkdtempSync, mkdirSync, rmSync } from "fs";
8
- import { tmpdir } from "os";
9
- import { join } from "path";
10
- import {
11
- initDatabase,
12
- createIssue,
13
- getIssue,
14
- listIssues,
15
- updateIssue,
16
- createSpec,
17
- getSpec,
18
- listSpecs,
19
- addRelationship,
20
- getOutgoingRelationships,
21
- getIncomingRelationships,
22
- generateIssueId,
23
- generateSpecId,
24
- getReadyIssues,
25
- } from "@sudocode-ai/cli";
26
- import type { Issue, Spec, IssueStatus } from "@sudocode-ai/types";
27
- import type { Database } from "better-sqlite3";
28
-
29
- // =============================================================================
30
- // Test Database Setup
31
- // =============================================================================
32
-
33
- export interface TestContext {
34
- /** Temporary directory for test files */
35
- tmpDir: string;
36
- /** SQLite database instance */
37
- db: Database;
38
- /** Cleanup function to call after tests */
39
- cleanup: () => void;
40
- }
41
-
42
- /**
43
- * Create a test context with a real sudocode database
44
- *
45
- * Creates the database in {tmpDir}/.sudocode/cache.db to match
46
- * the structure expected by StandaloneClient.
47
- */
48
- export function createTestContext(): TestContext {
49
- const tmpDir = mkdtempSync(join(tmpdir(), "sudocode-test-"));
50
- const sudocodeDir = join(tmpDir, ".sudocode");
51
- mkdirSync(sudocodeDir, { recursive: true });
52
- const dbPath = join(sudocodeDir, "cache.db");
53
- const db = initDatabase({ path: dbPath });
54
-
55
- return {
56
- tmpDir,
57
- db,
58
- cleanup: () => {
59
- db.close();
60
- rmSync(tmpDir, { recursive: true, force: true });
61
- },
62
- };
63
- }
64
-
65
- // =============================================================================
66
- // Test Fixture Helpers
67
- // =============================================================================
68
-
69
- export interface CreateTestIssueOptions {
70
- title: string;
71
- content?: string;
72
- status?: IssueStatus;
73
- priority?: number;
74
- parent_id?: string;
75
- }
76
-
77
- /**
78
- * Create a test issue with sensible defaults
79
- */
80
- export function createTestIssue(
81
- ctx: TestContext,
82
- options: CreateTestIssueOptions
83
- ): Issue {
84
- const { id, uuid } = generateIssueId(ctx.db, ctx.tmpDir);
85
- return createIssue(ctx.db, {
86
- id,
87
- uuid,
88
- title: options.title,
89
- content: options.content ?? `Content for ${options.title}`,
90
- status: options.status ?? "open",
91
- priority: options.priority ?? 2,
92
- parent_id: options.parent_id,
93
- });
94
- }
95
-
96
- export interface CreateTestSpecOptions {
97
- title: string;
98
- content?: string;
99
- priority?: number;
100
- }
101
-
102
- /**
103
- * Create a test spec with sensible defaults
104
- */
105
- export function createTestSpec(
106
- ctx: TestContext,
107
- options: CreateTestSpecOptions
108
- ): Spec {
109
- const { id, uuid } = generateSpecId(ctx.db, ctx.tmpDir);
110
- return createSpec(ctx.db, {
111
- id,
112
- uuid,
113
- title: options.title,
114
- file_path: `${ctx.tmpDir}/${id}.md`,
115
- content: options.content ?? `Specification for ${options.title}`,
116
- priority: options.priority ?? 2,
117
- });
118
- }
119
-
120
- /**
121
- * Create a blocking relationship between two issues
122
- */
123
- export function createBlockingRelationship(
124
- db: Database,
125
- blockerId: string,
126
- blockedId: string
127
- ): void {
128
- addRelationship(db, {
129
- from_id: blockerId,
130
- from_type: "issue",
131
- to_id: blockedId,
132
- to_type: "issue",
133
- relationship_type: "blocks",
134
- });
135
- }
136
-
137
- /**
138
- * Create an implements relationship between an issue and a spec
139
- */
140
- export function createImplementsRelationship(
141
- db: Database,
142
- issueId: string,
143
- specId: string
144
- ): void {
145
- addRelationship(db, {
146
- from_id: issueId,
147
- from_type: "issue",
148
- to_id: specId,
149
- to_type: "spec",
150
- relationship_type: "implements",
151
- });
152
- }
153
-
154
- // =============================================================================
155
- // Re-export commonly used functions
156
- // =============================================================================
157
-
158
- export {
159
- initDatabase,
160
- createIssue,
161
- getIssue,
162
- listIssues,
163
- updateIssue,
164
- createSpec,
165
- getSpec,
166
- listSpecs,
167
- addRelationship,
168
- getOutgoingRelationships,
169
- getIncomingRelationships,
170
- generateIssueId,
171
- generateSpecId,
172
- getReadyIssues,
173
- };
174
-
175
- export type { Issue, Spec, IssueStatus, Database };