macro-agent 0.1.0 → 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 (337) 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 +15 -0
  6. package/dist/acp/macro-agent.d.ts.map +1 -1
  7. package/dist/acp/macro-agent.js +131 -35
  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 +17 -0
  53. package/dist/map/adapter/acp-over-map.d.ts.map +1 -1
  54. package/dist/map/adapter/acp-over-map.js +384 -23
  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 +3 -0
  95. package/dist/map/adapter/map-adapter.d.ts.map +1 -1
  96. package/dist/map/adapter/map-adapter.js +258 -35
  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 +2 -1
  131. package/dist/store/event-store.d.ts.map +1 -1
  132. package/dist/store/event-store.js +69 -20
  133. package/dist/store/event-store.js.map +1 -1
  134. package/dist/store/types/agents.d.ts +18 -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__/integration.test.ts +56 -31
  197. package/src/acp/__tests__/macro-agent.test.ts +16 -7
  198. package/src/acp/macro-agent.ts +170 -36
  199. package/src/acp/types.ts +46 -1
  200. package/src/agent/__tests__/agent-manager.test.ts +228 -2
  201. package/src/agent/agent-manager.ts +714 -261
  202. package/src/agent/types.ts +3 -1
  203. package/src/api/server.ts +41 -7
  204. package/src/auth/__tests__/token.test.ts +100 -0
  205. package/src/auth/index.ts +1 -0
  206. package/src/auth/token.ts +82 -0
  207. package/src/cli/__tests__/acp.test.ts +1 -1
  208. package/src/cli/__tests__/stable-instance-id.test.ts +1 -1
  209. package/src/cli/acp.ts +130 -72
  210. package/src/cli/index.ts +120 -14
  211. package/src/cli/mcp.ts +311 -207
  212. package/src/cli/parse-args.ts +54 -0
  213. package/src/cli/stable-instance-id.ts +14 -0
  214. package/src/config/project-config.ts +190 -27
  215. package/src/lifecycle/__tests__/cascade-termination.test.ts +1 -1
  216. package/src/map/adapter/__tests__/acp-over-map-cancel.test.ts +22 -4
  217. package/src/map/adapter/__tests__/acp-over-map-getmodels.test.ts +355 -0
  218. package/src/map/adapter/__tests__/acp-over-map-history.test.ts +263 -0
  219. package/src/map/adapter/__tests__/acp-over-map-persistence.e2e.test.ts +1 -1
  220. package/src/map/adapter/__tests__/event-broadcast.test.ts +420 -0
  221. package/src/map/adapter/__tests__/event-log.test.ts +527 -0
  222. package/src/map/adapter/__tests__/event-translator.test.ts +3 -3
  223. package/src/map/adapter/__tests__/extensions.test.ts +408 -0
  224. package/src/map/adapter/__tests__/map-adapter.test.ts +99 -0
  225. package/src/map/adapter/__tests__/mcp-bridge.test.ts +1187 -0
  226. package/src/map/adapter/__tests__/multi-client-broadcast.test.ts +711 -0
  227. package/src/map/adapter/__tests__/websocket-integration.test.ts +218 -0
  228. package/src/map/adapter/acp-over-map.ts +678 -66
  229. package/src/map/adapter/connection-manager.ts +3 -0
  230. package/src/map/adapter/event-log.ts +208 -0
  231. package/src/map/adapter/event-translator.ts +6 -6
  232. package/src/map/adapter/extensions/agent-lifecycle.ts +267 -0
  233. package/src/map/adapter/extensions/index.ts +60 -0
  234. package/src/map/adapter/extensions/mcp-bridge.ts +995 -0
  235. package/src/map/adapter/extensions/task.ts +11 -0
  236. package/src/map/adapter/extensions/update-metadata.ts +126 -0
  237. package/src/map/adapter/index.ts +28 -0
  238. package/src/map/adapter/interface.ts +2 -0
  239. package/src/map/adapter/map-adapter.ts +312 -47
  240. package/src/map/adapter/subscription-manager.ts +5 -1
  241. package/src/map/adapter/types.ts +2 -0
  242. package/src/mcp/__tests__/map-client.test.ts +386 -0
  243. package/src/mcp/__tests__/mcp-server-thin-client.test.ts +368 -0
  244. package/src/mcp/__tests__/mcp-server.test.ts +100 -1
  245. package/src/mcp/map-client.ts +177 -0
  246. package/src/mcp/mcp-server.ts +191 -100
  247. package/src/mcp/types.ts +6 -1
  248. package/src/metrics/metrics.ts +1 -1
  249. package/src/monitor/__tests__/stale-agent-flow.integration.test.ts +1 -1
  250. package/src/roles/__tests__/config-loader.test.ts +7 -7
  251. package/src/roles/capabilities.ts +17 -7
  252. package/src/roles/config-loader.ts +6 -6
  253. package/src/roles/registry.ts +2 -2
  254. package/src/server/__tests__/combined-server.test.ts +94 -21
  255. package/src/server/combined-server.ts +189 -33
  256. package/src/steering/__tests__/steering-integration.test.ts +1 -1
  257. package/src/store/__tests__/event-store.test.ts +196 -1
  258. package/src/store/__tests__/instance.test.ts +3 -3
  259. package/src/store/event-store.ts +80 -21
  260. package/src/store/types/agents.ts +15 -0
  261. package/src/store/types/events.ts +1 -1
  262. package/src/task/backend/__tests__/create-task-backend.test.ts +225 -0
  263. package/src/task/backend/__tests__/e2e/unified-tool-provider-opentasks.e2e.test.ts +524 -0
  264. package/src/task/backend/__tests__/unified-tool-provider.test.ts +579 -0
  265. package/src/task/backend/index.ts +156 -106
  266. package/src/task/backend/memory.ts +4 -0
  267. package/src/task/backend/opentasks/__tests__/backend.test.ts +968 -0
  268. package/src/task/backend/opentasks/__tests__/daemon-manager.test.ts +406 -0
  269. package/src/task/backend/opentasks/__tests__/mapping.test.ts +84 -0
  270. package/src/task/backend/opentasks/__tests__/opentasks-backend.e2e.test.ts +1338 -0
  271. package/src/task/backend/opentasks/backend.ts +1323 -0
  272. package/src/task/backend/opentasks/client.ts +652 -0
  273. package/src/task/backend/opentasks/daemon-manager.ts +253 -0
  274. package/src/task/backend/opentasks/index.ts +69 -0
  275. package/src/task/backend/opentasks/mapping.ts +94 -0
  276. package/src/task/backend/types.ts +42 -66
  277. package/src/task/backend/unified-tool-provider.ts +779 -0
  278. package/src/teams/__tests__/cross-subsystem.integration.test.ts +1 -1
  279. package/src/teams/team-loader.ts +3 -3
  280. package/src/teams/team-runtime.ts +2 -0
  281. package/test_fixtures/README.md +2 -3
  282. package/test_fixtures/fixtures/index.ts +0 -3
  283. package/test_fixtures/fixtures/projects/project-with-specs.ts +7 -149
  284. package/test_fixtures/fixtures/repos/index.ts +1 -3
  285. package/test_fixtures/fixtures/repos/temp-repo-factory.ts +0 -116
  286. package/test_fixtures/fixtures/repos/types.ts +0 -11
  287. package/test_fixtures/harness/__tests__/fixtures.test.ts +10 -102
  288. package/test_fixtures/harness/__tests__/temp-repo-and-simulator.test.ts +0 -33
  289. package/test_fixtures/harness/simulator/agent-simulator.ts +4 -4
  290. package/vitest.config.ts +1 -1
  291. package/vitest.e2e.config.ts +1 -1
  292. package/vitest.setup.ts +1 -30
  293. package/.macro-agent/teams/self-driving/prompts/grinder.md +0 -27
  294. package/.macro-agent/teams/self-driving/prompts/judge.md +0 -27
  295. package/.macro-agent/teams/self-driving/prompts/planner.md +0 -33
  296. package/.macro-agent/teams/self-driving/roles/grinder.yaml +0 -17
  297. package/.macro-agent/teams/self-driving/roles/judge.yaml +0 -24
  298. package/.macro-agent/teams/self-driving/roles/planner.yaml +0 -18
  299. package/.macro-agent/teams/self-driving/team.yaml +0 -103
  300. package/.macro-agent/teams/structured/prompts/developer.md +0 -26
  301. package/.macro-agent/teams/structured/prompts/lead.md +0 -25
  302. package/.macro-agent/teams/structured/prompts/reviewer.md +0 -24
  303. package/.macro-agent/teams/structured/roles/developer.yaml +0 -12
  304. package/.macro-agent/teams/structured/roles/lead.yaml +0 -11
  305. package/.macro-agent/teams/structured/roles/reviewer.yaml +0 -19
  306. package/.macro-agent/teams/structured/team.yaml +0 -89
  307. package/docs/sudocode-integration.md +0 -383
  308. package/src/task/backend/__tests__/backend-parity.test.ts +0 -451
  309. package/src/task/backend/__tests__/tool-provider-edge-cases.test.ts +0 -430
  310. package/src/task/backend/__tests__/tool-provider.test.ts +0 -983
  311. package/src/task/backend/sudocode/__tests__/backend-edge-cases.test.ts +0 -575
  312. package/src/task/backend/sudocode/__tests__/backend.test.ts +0 -1194
  313. package/src/task/backend/sudocode/__tests__/client-integration.test.ts +0 -418
  314. package/src/task/backend/sudocode/__tests__/client.test.ts +0 -345
  315. package/src/task/backend/sudocode/__tests__/e2e/backend.e2e.test.ts +0 -753
  316. package/src/task/backend/sudocode/__tests__/e2e/server-client.e2e.test.ts +0 -680
  317. package/src/task/backend/sudocode/__tests__/e2e-workflow.test.ts +0 -666
  318. package/src/task/backend/sudocode/__tests__/integration/standalone-client.integration.test.ts +0 -396
  319. package/src/task/backend/sudocode/__tests__/integration/sudocode-cli.integration.test.ts +0 -328
  320. package/src/task/backend/sudocode/__tests__/integration/test-utils.ts +0 -175
  321. package/src/task/backend/sudocode/__tests__/mapping-edge-cases.test.ts +0 -265
  322. package/src/task/backend/sudocode/__tests__/server-client.test.ts +0 -675
  323. package/src/task/backend/sudocode/__tests__/sync-policy-edge-cases.test.ts +0 -521
  324. package/src/task/backend/sudocode/__tests__/sync-policy.test.ts +0 -519
  325. package/src/task/backend/sudocode/__tests__/tools.test.ts +0 -471
  326. package/src/task/backend/sudocode/backend.ts +0 -1237
  327. package/src/task/backend/sudocode/client.ts +0 -515
  328. package/src/task/backend/sudocode/index.ts +0 -120
  329. package/src/task/backend/sudocode/mapping.ts +0 -93
  330. package/src/task/backend/sudocode/server-client.ts +0 -522
  331. package/src/task/backend/sudocode/standalone-client.ts +0 -623
  332. package/src/task/backend/sudocode/sync-policy.ts +0 -387
  333. package/src/task/backend/sudocode/tools.ts +0 -896
  334. package/src/task/backend/tool-provider.ts +0 -506
  335. package/test_fixtures/fixtures/sudocode/index.ts +0 -29
  336. package/test_fixtures/fixtures/sudocode/issues.ts +0 -185
  337. package/test_fixtures/fixtures/sudocode/specs.ts +0 -159
@@ -1,345 +0,0 @@
1
- /**
2
- * SudocodeClient Interface Tests
3
- *
4
- * Tests for the SudocodeClient interface types and factory function.
5
- */
6
-
7
- import { describe, it, expect, vi, beforeEach, afterEach } from "vitest";
8
- import {
9
- checkServerHealth,
10
- createSudocodeClient,
11
- DEFAULT_CLIENT_CONFIG,
12
- type SudocodeClientConfig,
13
- type SudocodeClient,
14
- type IssueChangeEvent,
15
- } from "../client.js";
16
-
17
- // Mock fetch for server health checks
18
- const mockFetch = vi.fn();
19
- vi.stubGlobal("fetch", mockFetch);
20
-
21
- // Mock WebSocket
22
- class MockWebSocket {
23
- static instances: MockWebSocket[] = [];
24
- onopen: (() => void) | null = null;
25
- onclose: (() => void) | null = null;
26
- onerror: ((error: unknown) => void) | null = null;
27
- onmessage: ((event: { data: string }) => void) | null = null;
28
-
29
- constructor(public url: string) {
30
- MockWebSocket.instances.push(this);
31
- // Simulate async connection
32
- setTimeout(() => {
33
- if (this.onopen) this.onopen();
34
- }, 0);
35
- }
36
-
37
- close() {
38
- // Simulate close
39
- }
40
-
41
- static clearInstances() {
42
- MockWebSocket.instances = [];
43
- }
44
- }
45
-
46
- vi.stubGlobal("WebSocket", MockWebSocket);
47
-
48
- describe("SudocodeClient", () => {
49
- beforeEach(() => {
50
- vi.clearAllMocks();
51
- MockWebSocket.clearInstances();
52
- });
53
-
54
- afterEach(() => {
55
- vi.restoreAllMocks();
56
- });
57
-
58
- describe("DEFAULT_CLIENT_CONFIG", () => {
59
- it("should have expected default values", () => {
60
- expect(DEFAULT_CLIENT_CONFIG.serverUrl).toBe("http://localhost:3001");
61
- expect(DEFAULT_CLIENT_CONFIG.wsUrl).toBe("ws://localhost:3001/ws");
62
- expect(DEFAULT_CLIENT_CONFIG.autoDetect.timeout).toBe(2000);
63
- expect(DEFAULT_CLIENT_CONFIG.autoDetect.preferManaged).toBe(true);
64
- });
65
- });
66
-
67
- describe("checkServerHealth", () => {
68
- it("should return true when server responds with ok", async () => {
69
- mockFetch.mockResolvedValueOnce({ ok: true });
70
-
71
- const result = await checkServerHealth("http://localhost:3001");
72
-
73
- expect(result).toBe(true);
74
- expect(mockFetch).toHaveBeenCalledWith(
75
- "http://localhost:3001/health",
76
- expect.objectContaining({ signal: expect.any(AbortSignal) })
77
- );
78
- });
79
-
80
- it("should return false when server responds with error", async () => {
81
- mockFetch.mockResolvedValueOnce({ ok: false });
82
-
83
- const result = await checkServerHealth("http://localhost:3001");
84
-
85
- expect(result).toBe(false);
86
- });
87
-
88
- it("should return false when fetch throws", async () => {
89
- mockFetch.mockRejectedValueOnce(new Error("Connection refused"));
90
-
91
- const result = await checkServerHealth("http://localhost:3001");
92
-
93
- expect(result).toBe(false);
94
- });
95
-
96
- it("should return false when request times out", async () => {
97
- // Simulate timeout by never resolving
98
- mockFetch.mockImplementationOnce(
99
- () =>
100
- new Promise((_, reject) => {
101
- setTimeout(() => reject(new Error("Aborted")), 100);
102
- })
103
- );
104
-
105
- const result = await checkServerHealth("http://localhost:3001", 50);
106
-
107
- expect(result).toBe(false);
108
- });
109
- });
110
-
111
- describe("createSudocodeClient", () => {
112
- describe("managed mode", () => {
113
- it("should create a ServerClient in managed mode", async () => {
114
- const config: SudocodeClientConfig = {
115
- mode: "managed",
116
- serverUrl: "http://localhost:3001",
117
- };
118
-
119
- const client = await createSudocodeClient(config);
120
-
121
- try {
122
- // Verify client implements the interface
123
- expect(typeof client.getIssue).toBe("function");
124
- expect(typeof client.listIssues).toBe("function");
125
- expect(typeof client.getReadyIssues).toBe("function");
126
- expect(typeof client.updateIssue).toBe("function");
127
- expect(typeof client.createLink).toBe("function");
128
- expect(typeof client.removeLink).toBe("function");
129
- expect(typeof client.getBlockers).toBe("function");
130
- expect(typeof client.getBlocking).toBe("function");
131
- expect(typeof client.getSpec).toBe("function");
132
- expect(typeof client.listSpecs).toBe("function");
133
- expect(typeof client.addFeedback).toBe("function");
134
- expect(typeof client.onIssueChange).toBe("function");
135
- expect(typeof client.isReady).toBe("function");
136
- expect(typeof client.close).toBe("function");
137
-
138
- // Verify WebSocket was created with correct URL
139
- expect(MockWebSocket.instances).toHaveLength(1);
140
- expect(MockWebSocket.instances[0].url).toBe("ws://localhost:3001/ws");
141
- } finally {
142
- client.close();
143
- }
144
- });
145
-
146
- it("should use custom wsUrl if provided", async () => {
147
- const config: SudocodeClientConfig = {
148
- mode: "managed",
149
- serverUrl: "http://localhost:3001",
150
- wsUrl: "ws://custom.example.com/websocket",
151
- };
152
-
153
- const client = await createSudocodeClient(config);
154
-
155
- try {
156
- expect(MockWebSocket.instances).toHaveLength(1);
157
- expect(MockWebSocket.instances[0].url).toBe(
158
- "ws://custom.example.com/websocket"
159
- );
160
- } finally {
161
- client.close();
162
- }
163
- });
164
- });
165
-
166
- describe("standalone mode", () => {
167
- it("should create a StandaloneClient", async () => {
168
- // Create a temp directory for the test
169
- const { mkdtempSync, rmSync } = await import("fs");
170
- const { tmpdir } = await import("os");
171
- const { join } = await import("path");
172
- const tmpDir = mkdtempSync(join(tmpdir(), "sudocode-client-test-"));
173
-
174
- try {
175
- const config: SudocodeClientConfig = {
176
- mode: "standalone",
177
- projectPath: tmpDir,
178
- };
179
-
180
- const client = await createSudocodeClient(config);
181
-
182
- try {
183
- expect(client.isReady()).toBe(true);
184
- expect(typeof client.getIssue).toBe("function");
185
- expect(typeof client.listIssues).toBe("function");
186
- } finally {
187
- client.close();
188
- }
189
- } finally {
190
- rmSync(tmpDir, { recursive: true, force: true });
191
- }
192
- });
193
- });
194
-
195
- describe("auto mode", () => {
196
- it("should use managed mode when server is available and preferManaged is true", async () => {
197
- mockFetch.mockResolvedValueOnce({ ok: true });
198
-
199
- const config: SudocodeClientConfig = {
200
- mode: "auto",
201
- autoDetect: { preferManaged: true },
202
- };
203
-
204
- const client = await createSudocodeClient(config);
205
-
206
- try {
207
- expect(mockFetch).toHaveBeenCalled();
208
- // Should have created a ServerClient (WebSocket was created)
209
- expect(MockWebSocket.instances).toHaveLength(1);
210
- } finally {
211
- client.close();
212
- }
213
- });
214
-
215
- it("should fall back to standalone when server is unavailable", async () => {
216
- mockFetch.mockRejectedValueOnce(new Error("Connection refused"));
217
-
218
- // Create a temp directory for the test
219
- const { mkdtempSync, rmSync } = await import("fs");
220
- const { tmpdir } = await import("os");
221
- const { join } = await import("path");
222
- const tmpDir = mkdtempSync(join(tmpdir(), "sudocode-client-test-"));
223
-
224
- try {
225
- const config: SudocodeClientConfig = {
226
- mode: "auto",
227
- projectPath: tmpDir,
228
- };
229
-
230
- const client = await createSudocodeClient(config);
231
-
232
- try {
233
- expect(mockFetch).toHaveBeenCalled();
234
- // Should have fallen back to StandaloneClient (no WebSocket created)
235
- expect(MockWebSocket.instances).toHaveLength(0);
236
- expect(client.isReady()).toBe(true);
237
- } finally {
238
- client.close();
239
- }
240
- } finally {
241
- rmSync(tmpDir, { recursive: true, force: true });
242
- }
243
- });
244
-
245
- it("should use standalone when preferManaged is false", async () => {
246
- mockFetch.mockResolvedValueOnce({ ok: true });
247
-
248
- // Create a temp directory for the test
249
- const { mkdtempSync, rmSync } = await import("fs");
250
- const { tmpdir } = await import("os");
251
- const { join } = await import("path");
252
- const tmpDir = mkdtempSync(join(tmpdir(), "sudocode-client-test-"));
253
-
254
- try {
255
- const config: SudocodeClientConfig = {
256
- mode: "auto",
257
- autoDetect: { preferManaged: false },
258
- projectPath: tmpDir,
259
- };
260
-
261
- const client = await createSudocodeClient(config);
262
-
263
- try {
264
- // Should have used StandaloneClient despite server being available
265
- expect(MockWebSocket.instances).toHaveLength(0);
266
- expect(client.isReady()).toBe(true);
267
- } finally {
268
- client.close();
269
- }
270
- } finally {
271
- rmSync(tmpDir, { recursive: true, force: true });
272
- }
273
- });
274
- });
275
- });
276
-
277
- describe("Type definitions", () => {
278
- it("should have correct IssueChangeEvent types", () => {
279
- // Type-level test: ensure the type is correctly defined
280
- const event: IssueChangeEvent = {
281
- type: "created",
282
- issueId: "i-abc123",
283
- issue: {
284
- id: "i-abc123",
285
- uuid: "uuid-123",
286
- title: "Test Issue",
287
- content: "Test content",
288
- status: "open",
289
- priority: 1,
290
- created_at: "2024-01-01T00:00:00Z",
291
- updated_at: "2024-01-01T00:00:00Z",
292
- },
293
- };
294
-
295
- expect(event.type).toBe("created");
296
- expect(event.issueId).toBe("i-abc123");
297
- });
298
-
299
- it("should support all IssueChangeType values", () => {
300
- const types: IssueChangeEvent["type"][] = [
301
- "created",
302
- "updated",
303
- "deleted",
304
- "status_changed",
305
- "blocked",
306
- "unblocked",
307
- ];
308
-
309
- expect(types).toHaveLength(6);
310
- });
311
- });
312
- });
313
-
314
- describe("SudocodeClient interface contract", () => {
315
- // These are type-level tests to ensure the interface is correctly defined
316
- // They don't actually run code but verify the type structure
317
-
318
- it("should define all required methods", () => {
319
- // This is a compile-time check - if the interface is wrong, TypeScript will error
320
- const methodNames: (keyof SudocodeClient)[] = [
321
- // Issue operations
322
- "getIssue",
323
- "listIssues",
324
- "getReadyIssues",
325
- "updateIssue",
326
- // Relationship operations
327
- "createLink",
328
- "removeLink",
329
- "getBlockers",
330
- "getBlocking",
331
- // Spec operations
332
- "getSpec",
333
- "listSpecs",
334
- // Feedback operations
335
- "addFeedback",
336
- // Event subscription
337
- "onIssueChange",
338
- // Lifecycle
339
- "isReady",
340
- "close",
341
- ];
342
-
343
- expect(methodNames).toHaveLength(14);
344
- });
345
- });