macro-agent 0.0.10 → 0.0.12

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 (518) hide show
  1. package/.macro-agent/teams/self-driving/prompts/grinder.md +27 -0
  2. package/.macro-agent/teams/self-driving/prompts/judge.md +27 -0
  3. package/.macro-agent/teams/self-driving/prompts/planner.md +33 -0
  4. package/.macro-agent/teams/self-driving/roles/grinder.yaml +17 -0
  5. package/.macro-agent/teams/self-driving/roles/judge.yaml +24 -0
  6. package/.macro-agent/teams/self-driving/roles/planner.yaml +18 -0
  7. package/.macro-agent/teams/self-driving/team.yaml +103 -0
  8. package/.macro-agent/teams/structured/prompts/developer.md +26 -0
  9. package/.macro-agent/teams/structured/prompts/lead.md +25 -0
  10. package/.macro-agent/teams/structured/prompts/reviewer.md +24 -0
  11. package/.macro-agent/teams/structured/roles/developer.yaml +12 -0
  12. package/.macro-agent/teams/structured/roles/lead.yaml +11 -0
  13. package/.macro-agent/teams/structured/roles/reviewer.yaml +19 -0
  14. package/.macro-agent/teams/structured/team.yaml +89 -0
  15. package/.sudocode/issues.jsonl +56 -51
  16. package/.sudocode/specs.jsonl +8 -1
  17. package/CLAUDE.md +121 -30
  18. package/README.md +60 -3
  19. package/dist/acp/macro-agent.d.ts +4 -0
  20. package/dist/acp/macro-agent.d.ts.map +1 -1
  21. package/dist/acp/macro-agent.js +50 -4
  22. package/dist/acp/macro-agent.js.map +1 -1
  23. package/dist/acp/session-mapper.d.ts +20 -1
  24. package/dist/acp/session-mapper.d.ts.map +1 -1
  25. package/dist/acp/session-mapper.js +90 -1
  26. package/dist/acp/session-mapper.js.map +1 -1
  27. package/dist/acp/types.d.ts +24 -1
  28. package/dist/acp/types.d.ts.map +1 -1
  29. package/dist/acp/types.js.map +1 -1
  30. package/dist/agent/agent-manager.d.ts +40 -1
  31. package/dist/agent/agent-manager.d.ts.map +1 -1
  32. package/dist/agent/agent-manager.js +172 -8
  33. package/dist/agent/agent-manager.js.map +1 -1
  34. package/dist/agent/types.d.ts +22 -0
  35. package/dist/agent/types.d.ts.map +1 -1
  36. package/dist/agent/types.js.map +1 -1
  37. package/dist/agent/wake.d.ts +15 -0
  38. package/dist/agent/wake.d.ts.map +1 -1
  39. package/dist/agent/wake.js +15 -0
  40. package/dist/agent/wake.js.map +1 -1
  41. package/dist/agent-detection/command-builder.d.ts +30 -0
  42. package/dist/agent-detection/command-builder.d.ts.map +1 -0
  43. package/dist/agent-detection/command-builder.js +71 -0
  44. package/dist/agent-detection/command-builder.js.map +1 -0
  45. package/dist/agent-detection/detector.d.ts +84 -0
  46. package/dist/agent-detection/detector.d.ts.map +1 -0
  47. package/dist/agent-detection/detector.js +240 -0
  48. package/dist/agent-detection/detector.js.map +1 -0
  49. package/dist/agent-detection/index.d.ts +12 -0
  50. package/dist/agent-detection/index.d.ts.map +1 -0
  51. package/dist/agent-detection/index.js +14 -0
  52. package/dist/agent-detection/index.js.map +1 -0
  53. package/dist/agent-detection/registry.d.ts +53 -0
  54. package/dist/agent-detection/registry.d.ts.map +1 -0
  55. package/dist/agent-detection/registry.js +177 -0
  56. package/dist/agent-detection/registry.js.map +1 -0
  57. package/dist/agent-detection/types.d.ts +121 -0
  58. package/dist/agent-detection/types.d.ts.map +1 -0
  59. package/dist/agent-detection/types.js +20 -0
  60. package/dist/agent-detection/types.js.map +1 -0
  61. package/dist/api/server.d.ts +5 -1
  62. package/dist/api/server.d.ts.map +1 -1
  63. package/dist/api/server.js +362 -0
  64. package/dist/api/server.js.map +1 -1
  65. package/dist/api/types.d.ts +50 -1
  66. package/dist/api/types.d.ts.map +1 -1
  67. package/dist/cli/acp.d.ts +2 -0
  68. package/dist/cli/acp.d.ts.map +1 -1
  69. package/dist/cli/acp.js +8 -1
  70. package/dist/cli/acp.js.map +1 -1
  71. package/dist/cli/index.js +29 -0
  72. package/dist/cli/index.js.map +1 -1
  73. package/dist/cli/mcp.js +38 -0
  74. package/dist/cli/mcp.js.map +1 -1
  75. package/dist/config/index.d.ts +2 -0
  76. package/dist/config/index.d.ts.map +1 -0
  77. package/dist/config/index.js +2 -0
  78. package/dist/config/index.js.map +1 -0
  79. package/dist/config/project-config.d.ts +46 -0
  80. package/dist/config/project-config.d.ts.map +1 -0
  81. package/dist/config/project-config.js +68 -0
  82. package/dist/config/project-config.js.map +1 -0
  83. package/dist/lifecycle/cascade.d.ts +1 -1
  84. package/dist/lifecycle/cascade.d.ts.map +1 -1
  85. package/dist/lifecycle/handlers/index.d.ts +4 -0
  86. package/dist/lifecycle/handlers/index.d.ts.map +1 -1
  87. package/dist/lifecycle/handlers/index.js +2 -0
  88. package/dist/lifecycle/handlers/index.js.map +1 -1
  89. package/dist/lifecycle/handlers/worker.d.ts +4 -0
  90. package/dist/lifecycle/handlers/worker.d.ts.map +1 -1
  91. package/dist/lifecycle/handlers/worker.js +35 -3
  92. package/dist/lifecycle/handlers/worker.js.map +1 -1
  93. package/dist/mail/conversation-map.d.ts +33 -0
  94. package/dist/mail/conversation-map.d.ts.map +1 -0
  95. package/dist/mail/conversation-map.js +61 -0
  96. package/dist/mail/conversation-map.js.map +1 -0
  97. package/dist/mail/index.d.ts +11 -0
  98. package/dist/mail/index.d.ts.map +1 -0
  99. package/dist/mail/index.js +11 -0
  100. package/dist/mail/index.js.map +1 -0
  101. package/dist/mail/mail-service.d.ts +85 -0
  102. package/dist/mail/mail-service.d.ts.map +1 -0
  103. package/dist/mail/mail-service.js +121 -0
  104. package/dist/mail/mail-service.js.map +1 -0
  105. package/dist/mail/stores/eventstore-conversation-store.d.ts +40 -0
  106. package/dist/mail/stores/eventstore-conversation-store.d.ts.map +1 -0
  107. package/dist/mail/stores/eventstore-conversation-store.js +131 -0
  108. package/dist/mail/stores/eventstore-conversation-store.js.map +1 -0
  109. package/dist/mail/stores/eventstore-participant-store.d.ts +43 -0
  110. package/dist/mail/stores/eventstore-participant-store.d.ts.map +1 -0
  111. package/dist/mail/stores/eventstore-participant-store.js +145 -0
  112. package/dist/mail/stores/eventstore-participant-store.js.map +1 -0
  113. package/dist/mail/stores/eventstore-thread-store.d.ts +46 -0
  114. package/dist/mail/stores/eventstore-thread-store.d.ts.map +1 -0
  115. package/dist/mail/stores/eventstore-thread-store.js +118 -0
  116. package/dist/mail/stores/eventstore-thread-store.js.map +1 -0
  117. package/dist/mail/stores/eventstore-turn-store.d.ts +47 -0
  118. package/dist/mail/stores/eventstore-turn-store.d.ts.map +1 -0
  119. package/dist/mail/stores/eventstore-turn-store.js +153 -0
  120. package/dist/mail/stores/eventstore-turn-store.js.map +1 -0
  121. package/dist/mail/stores/index.d.ts +12 -0
  122. package/dist/mail/stores/index.d.ts.map +1 -0
  123. package/dist/mail/stores/index.js +12 -0
  124. package/dist/mail/stores/index.js.map +1 -0
  125. package/dist/mail/stores/types.d.ts +146 -0
  126. package/dist/mail/stores/types.d.ts.map +1 -0
  127. package/dist/mail/stores/types.js +13 -0
  128. package/dist/mail/stores/types.js.map +1 -0
  129. package/dist/mail/turn-recorder.d.ts +30 -0
  130. package/dist/mail/turn-recorder.d.ts.map +1 -0
  131. package/dist/mail/turn-recorder.js +98 -0
  132. package/dist/mail/turn-recorder.js.map +1 -0
  133. package/dist/map/adapter/acp-over-map.d.ts.map +1 -1
  134. package/dist/map/adapter/acp-over-map.js +32 -2
  135. package/dist/map/adapter/acp-over-map.js.map +1 -1
  136. package/dist/map/adapter/event-translator.d.ts.map +1 -1
  137. package/dist/map/adapter/event-translator.js +4 -0
  138. package/dist/map/adapter/event-translator.js.map +1 -1
  139. package/dist/map/adapter/extensions/agent-detection.d.ts +49 -0
  140. package/dist/map/adapter/extensions/agent-detection.d.ts.map +1 -0
  141. package/dist/map/adapter/extensions/agent-detection.js +91 -0
  142. package/dist/map/adapter/extensions/agent-detection.js.map +1 -0
  143. package/dist/map/adapter/extensions/index.d.ts +10 -1
  144. package/dist/map/adapter/extensions/index.d.ts.map +1 -1
  145. package/dist/map/adapter/extensions/index.js +39 -0
  146. package/dist/map/adapter/extensions/index.js.map +1 -1
  147. package/dist/map/adapter/extensions/resume.d.ts +47 -0
  148. package/dist/map/adapter/extensions/resume.d.ts.map +1 -0
  149. package/dist/map/adapter/extensions/resume.js +59 -0
  150. package/dist/map/adapter/extensions/resume.js.map +1 -0
  151. package/dist/map/adapter/extensions/workspace-files.d.ts +42 -0
  152. package/dist/map/adapter/extensions/workspace-files.d.ts.map +1 -0
  153. package/dist/map/adapter/extensions/workspace-files.js +338 -0
  154. package/dist/map/adapter/extensions/workspace-files.js.map +1 -0
  155. package/dist/map/adapter/mail-handler-adapter.d.ts +27 -0
  156. package/dist/map/adapter/mail-handler-adapter.d.ts.map +1 -0
  157. package/dist/map/adapter/mail-handler-adapter.js +292 -0
  158. package/dist/map/adapter/mail-handler-adapter.js.map +1 -0
  159. package/dist/map/adapter/map-adapter.d.ts +34 -10
  160. package/dist/map/adapter/map-adapter.d.ts.map +1 -1
  161. package/dist/map/adapter/map-adapter.js +110 -14
  162. package/dist/map/adapter/map-adapter.js.map +1 -1
  163. package/dist/map/adapter/rpc-handler.d.ts +4 -1
  164. package/dist/map/adapter/rpc-handler.d.ts.map +1 -1
  165. package/dist/map/adapter/rpc-handler.js +6 -0
  166. package/dist/map/adapter/rpc-handler.js.map +1 -1
  167. package/dist/map/index.d.ts +1 -0
  168. package/dist/map/index.d.ts.map +1 -1
  169. package/dist/map/index.js +2 -0
  170. package/dist/map/index.js.map +1 -1
  171. package/dist/map/types.d.ts +3 -1
  172. package/dist/map/types.d.ts.map +1 -1
  173. package/dist/map/types.js.map +1 -1
  174. package/dist/mcp/mcp-server.d.ts +6 -0
  175. package/dist/mcp/mcp-server.d.ts.map +1 -1
  176. package/dist/mcp/mcp-server.js +45 -0
  177. package/dist/mcp/mcp-server.js.map +1 -1
  178. package/dist/mcp/tools/claim_task.d.ts +35 -0
  179. package/dist/mcp/tools/claim_task.d.ts.map +1 -0
  180. package/dist/mcp/tools/claim_task.js +58 -0
  181. package/dist/mcp/tools/claim_task.js.map +1 -0
  182. package/dist/mcp/tools/done.d.ts +15 -2
  183. package/dist/mcp/tools/done.d.ts.map +1 -1
  184. package/dist/mcp/tools/done.js +45 -10
  185. package/dist/mcp/tools/done.js.map +1 -1
  186. package/dist/mcp/tools/list_claimable_tasks.d.ts +38 -0
  187. package/dist/mcp/tools/list_claimable_tasks.d.ts.map +1 -0
  188. package/dist/mcp/tools/list_claimable_tasks.js +63 -0
  189. package/dist/mcp/tools/list_claimable_tasks.js.map +1 -0
  190. package/dist/mcp/tools/unclaim_task.d.ts +31 -0
  191. package/dist/mcp/tools/unclaim_task.d.ts.map +1 -0
  192. package/dist/mcp/tools/unclaim_task.js +47 -0
  193. package/dist/mcp/tools/unclaim_task.js.map +1 -0
  194. package/dist/metrics/index.d.ts +2 -0
  195. package/dist/metrics/index.d.ts.map +1 -0
  196. package/dist/metrics/index.js +2 -0
  197. package/dist/metrics/index.js.map +1 -0
  198. package/dist/metrics/metrics.d.ts +79 -0
  199. package/dist/metrics/metrics.d.ts.map +1 -0
  200. package/dist/metrics/metrics.js +166 -0
  201. package/dist/metrics/metrics.js.map +1 -0
  202. package/dist/roles/capabilities.d.ts +1 -0
  203. package/dist/roles/capabilities.d.ts.map +1 -1
  204. package/dist/roles/capabilities.js +3 -0
  205. package/dist/roles/capabilities.js.map +1 -1
  206. package/dist/roles/types.d.ts +1 -1
  207. package/dist/roles/types.d.ts.map +1 -1
  208. package/dist/router/channels.d.ts +2 -4
  209. package/dist/router/channels.d.ts.map +1 -1
  210. package/dist/router/channels.js.map +1 -1
  211. package/dist/router/message-router.d.ts +85 -9
  212. package/dist/router/message-router.d.ts.map +1 -1
  213. package/dist/router/message-router.js +203 -14
  214. package/dist/router/message-router.js.map +1 -1
  215. package/dist/router/role-resolver.d.ts +10 -1
  216. package/dist/router/role-resolver.d.ts.map +1 -1
  217. package/dist/router/role-resolver.js +15 -1
  218. package/dist/router/role-resolver.js.map +1 -1
  219. package/dist/router/types.d.ts +30 -1
  220. package/dist/router/types.d.ts.map +1 -1
  221. package/dist/router/types.js.map +1 -1
  222. package/dist/server/combined-server.d.ts +6 -0
  223. package/dist/server/combined-server.d.ts.map +1 -1
  224. package/dist/server/combined-server.js +24 -2
  225. package/dist/server/combined-server.js.map +1 -1
  226. package/dist/store/event-store.d.ts +14 -1
  227. package/dist/store/event-store.d.ts.map +1 -1
  228. package/dist/store/event-store.js +456 -4
  229. package/dist/store/event-store.js.map +1 -1
  230. package/dist/store/types/agents.d.ts +1 -1
  231. package/dist/store/types/agents.d.ts.map +1 -1
  232. package/dist/store/types/conversations.d.ts +91 -0
  233. package/dist/store/types/conversations.d.ts.map +1 -0
  234. package/dist/store/types/conversations.js +8 -0
  235. package/dist/store/types/conversations.js.map +1 -0
  236. package/dist/store/types/events.d.ts +1 -1
  237. package/dist/store/types/events.d.ts.map +1 -1
  238. package/dist/store/types/events.js.map +1 -1
  239. package/dist/store/types/index.d.ts +2 -0
  240. package/dist/store/types/index.d.ts.map +1 -1
  241. package/dist/store/types/index.js +2 -0
  242. package/dist/store/types/index.js.map +1 -1
  243. package/dist/store/types/sessions.d.ts +44 -0
  244. package/dist/store/types/sessions.d.ts.map +1 -0
  245. package/dist/store/types/sessions.js +9 -0
  246. package/dist/store/types/sessions.js.map +1 -0
  247. package/dist/store/types/tasks.d.ts +2 -0
  248. package/dist/store/types/tasks.d.ts.map +1 -1
  249. package/dist/task/backend/memory.d.ts +4 -1
  250. package/dist/task/backend/memory.d.ts.map +1 -1
  251. package/dist/task/backend/memory.js +81 -0
  252. package/dist/task/backend/memory.js.map +1 -1
  253. package/dist/task/backend/types.d.ts +30 -0
  254. package/dist/task/backend/types.d.ts.map +1 -1
  255. package/dist/task/backend/types.js.map +1 -1
  256. package/dist/teams/index.d.ts +4 -0
  257. package/dist/teams/index.d.ts.map +1 -0
  258. package/dist/teams/index.js +4 -0
  259. package/dist/teams/index.js.map +1 -0
  260. package/dist/teams/team-loader.d.ts +20 -0
  261. package/dist/teams/team-loader.d.ts.map +1 -0
  262. package/dist/teams/team-loader.js +293 -0
  263. package/dist/teams/team-loader.js.map +1 -0
  264. package/dist/teams/team-runtime.d.ts +139 -0
  265. package/dist/teams/team-runtime.d.ts.map +1 -0
  266. package/dist/teams/team-runtime.js +613 -0
  267. package/dist/teams/team-runtime.js.map +1 -0
  268. package/dist/teams/types.d.ts +266 -0
  269. package/dist/teams/types.d.ts.map +1 -0
  270. package/dist/teams/types.js +20 -0
  271. package/dist/teams/types.js.map +1 -0
  272. package/dist/trigger/router/trigger-router.d.ts +30 -3
  273. package/dist/trigger/router/trigger-router.d.ts.map +1 -1
  274. package/dist/trigger/router/trigger-router.js +30 -3
  275. package/dist/trigger/router/trigger-router.js.map +1 -1
  276. package/dist/trigger/wake/types.d.ts +31 -5
  277. package/dist/trigger/wake/types.d.ts.map +1 -1
  278. package/dist/trigger/wake/types.js +19 -0
  279. package/dist/trigger/wake/types.js.map +1 -1
  280. package/dist/workspace/dataplane-adapter.d.ts +1 -1
  281. package/dist/workspace/dataplane-adapter.d.ts.map +1 -1
  282. package/dist/workspace/dataplane-adapter.js +1 -1
  283. package/dist/workspace/dataplane-adapter.js.map +1 -1
  284. package/dist/workspace/index.d.ts +1 -1
  285. package/dist/workspace/index.d.ts.map +1 -1
  286. package/dist/workspace/strategies/index.d.ts +6 -0
  287. package/dist/workspace/strategies/index.d.ts.map +1 -0
  288. package/dist/workspace/strategies/index.js +5 -0
  289. package/dist/workspace/strategies/index.js.map +1 -0
  290. package/dist/workspace/strategies/optimistic.d.ts +26 -0
  291. package/dist/workspace/strategies/optimistic.d.ts.map +1 -0
  292. package/dist/workspace/strategies/optimistic.js +121 -0
  293. package/dist/workspace/strategies/optimistic.js.map +1 -0
  294. package/dist/workspace/strategies/queue.d.ts +26 -0
  295. package/dist/workspace/strategies/queue.d.ts.map +1 -0
  296. package/dist/workspace/strategies/queue.js +67 -0
  297. package/dist/workspace/strategies/queue.js.map +1 -0
  298. package/dist/workspace/strategies/registry.d.ts +37 -0
  299. package/dist/workspace/strategies/registry.d.ts.map +1 -0
  300. package/dist/workspace/strategies/registry.js +63 -0
  301. package/dist/workspace/strategies/registry.js.map +1 -0
  302. package/dist/workspace/strategies/trunk.d.ts +20 -0
  303. package/dist/workspace/strategies/trunk.d.ts.map +1 -0
  304. package/dist/workspace/strategies/trunk.js +108 -0
  305. package/dist/workspace/strategies/trunk.js.map +1 -0
  306. package/dist/workspace/strategies/types.d.ts +104 -0
  307. package/dist/workspace/strategies/types.d.ts.map +1 -0
  308. package/dist/workspace/strategies/types.js +11 -0
  309. package/dist/workspace/strategies/types.js.map +1 -0
  310. package/dist/workspace/types.d.ts +1 -1
  311. package/dist/workspace/types.d.ts.map +1 -1
  312. package/dist/workspace/workspace-manager.d.ts +1 -1
  313. package/dist/workspace/workspace-manager.d.ts.map +1 -1
  314. package/docs/implementation-details.md +1127 -0
  315. package/docs/implementation-summary.md +448 -0
  316. package/docs/mail-integration.md +608 -0
  317. package/docs/plan-self-driving-support.md +433 -0
  318. package/docs/spec-self-driving-support.md +462 -0
  319. package/docs/team-templates.md +860 -0
  320. package/docs/teams.md +233 -0
  321. package/package.json +5 -3
  322. package/src/acp/__tests__/integration.test.ts +161 -1
  323. package/src/acp/__tests__/macro-agent.test.ts +95 -0
  324. package/src/acp/__tests__/session-persistence.test.ts +276 -0
  325. package/src/acp/macro-agent.ts +79 -7
  326. package/src/acp/session-mapper.ts +108 -1
  327. package/src/acp/types.ts +33 -1
  328. package/src/agent/agent-manager.ts +278 -6
  329. package/src/agent/types.ts +27 -0
  330. package/src/agent/wake.ts +15 -0
  331. package/src/agent-detection/__tests__/command-builder.test.ts +336 -0
  332. package/src/agent-detection/__tests__/detector.test.ts +768 -0
  333. package/src/agent-detection/__tests__/registry.test.ts +254 -0
  334. package/src/agent-detection/command-builder.ts +90 -0
  335. package/src/agent-detection/detector.ts +307 -0
  336. package/src/agent-detection/index.ts +36 -0
  337. package/src/agent-detection/registry.ts +200 -0
  338. package/src/agent-detection/types.ts +184 -0
  339. package/src/api/__tests__/conversation-api.test.ts +468 -0
  340. package/src/api/server.ts +425 -1
  341. package/src/api/types.ts +64 -1
  342. package/src/cli/acp.ts +9 -1
  343. package/src/cli/index.ts +44 -0
  344. package/src/cli/mcp.ts +47 -0
  345. package/src/config/index.ts +9 -0
  346. package/src/config/project-config.ts +107 -0
  347. package/src/lifecycle/cascade.ts +1 -1
  348. package/src/lifecycle/handlers/index.ts +8 -0
  349. package/src/lifecycle/handlers/worker.ts +48 -3
  350. package/src/mail/__tests__/conversation-lifecycle.test.ts +409 -0
  351. package/src/mail/__tests__/eventstore-stores.test.ts +1073 -0
  352. package/src/mail/__tests__/mail-full-agent.e2e.test.ts +575 -0
  353. package/src/mail/__tests__/mail-integration.test.ts +759 -0
  354. package/src/mail/__tests__/mail-map-protocol.e2e.test.ts +1068 -0
  355. package/src/mail/__tests__/mail-service.test.ts +506 -0
  356. package/src/mail/__tests__/turn-recorder.test.ts +328 -0
  357. package/src/mail/conversation-map.ts +107 -0
  358. package/src/mail/index.ts +25 -0
  359. package/src/mail/mail-service.ts +257 -0
  360. package/src/mail/stores/eventstore-conversation-store.ts +146 -0
  361. package/src/mail/stores/eventstore-participant-store.ts +172 -0
  362. package/src/mail/stores/eventstore-thread-store.ts +129 -0
  363. package/src/mail/stores/eventstore-turn-store.ts +173 -0
  364. package/src/mail/stores/index.ts +12 -0
  365. package/src/mail/stores/types.ts +160 -0
  366. package/src/mail/turn-recorder.ts +124 -0
  367. package/src/map/README.md +79 -0
  368. package/src/map/adapter/__tests__/extensions.test.ts +359 -0
  369. package/src/map/adapter/__tests__/map-adapter.test.ts +90 -0
  370. package/src/map/adapter/__tests__/workspace-files.test.ts +673 -0
  371. package/src/map/adapter/acp-over-map.ts +45 -2
  372. package/src/map/adapter/event-translator.ts +4 -0
  373. package/src/map/adapter/extensions/agent-detection.ts +201 -0
  374. package/src/map/adapter/extensions/index.ts +63 -0
  375. package/src/map/adapter/extensions/resume.ts +114 -0
  376. package/src/map/adapter/extensions/workspace-files.ts +449 -0
  377. package/src/map/adapter/mail-handler-adapter.ts +429 -0
  378. package/src/map/adapter/map-adapter.ts +173 -27
  379. package/src/map/adapter/rpc-handler.ts +8 -1
  380. package/src/map/index.ts +3 -0
  381. package/src/map/types.ts +3 -1
  382. package/src/mcp/mcp-server.ts +67 -0
  383. package/src/mcp/tools/claim_task.ts +86 -0
  384. package/src/mcp/tools/done.ts +59 -10
  385. package/src/mcp/tools/list_claimable_tasks.ts +93 -0
  386. package/src/mcp/tools/unclaim_task.ts +71 -0
  387. package/src/metrics/index.ts +9 -0
  388. package/src/metrics/metrics.ts +280 -0
  389. package/src/roles/capabilities.ts +3 -0
  390. package/src/roles/types.ts +2 -1
  391. package/src/router/README.md +120 -0
  392. package/src/router/__tests__/message-router.test.ts +561 -0
  393. package/src/router/channels.ts +3 -4
  394. package/src/router/message-router.ts +308 -22
  395. package/src/router/role-resolver.ts +22 -1
  396. package/src/router/types.ts +36 -1
  397. package/src/server/combined-server.ts +36 -2
  398. package/src/store/README.md +134 -0
  399. package/src/store/event-store.ts +546 -3
  400. package/src/store/types/agents.ts +1 -1
  401. package/src/store/types/conversations.ts +129 -0
  402. package/src/store/types/events.ts +5 -1
  403. package/src/store/types/index.ts +2 -0
  404. package/src/store/types/sessions.ts +53 -0
  405. package/src/store/types/tasks.ts +3 -0
  406. package/src/task/backend/memory.ts +116 -0
  407. package/src/task/backend/types.ts +43 -0
  408. package/src/teams/__tests__/cross-subsystem.integration.test.ts +983 -0
  409. package/src/teams/__tests__/e2e/team-runtime.e2e.test.ts +553 -0
  410. package/src/teams/__tests__/team-system.test.ts +1280 -0
  411. package/src/teams/index.ts +13 -0
  412. package/src/teams/team-loader.ts +434 -0
  413. package/src/teams/team-runtime.ts +727 -0
  414. package/src/teams/types.ts +377 -0
  415. package/src/trigger/router/trigger-router.ts +30 -3
  416. package/src/trigger/wake/types.ts +32 -5
  417. package/src/trigger/wake/wake-manager.ts +2 -2
  418. package/src/workspace/dataplane-adapter.ts +1 -1
  419. package/src/workspace/index.ts +1 -1
  420. package/src/workspace/strategies/index.ts +18 -0
  421. package/src/workspace/strategies/optimistic.ts +136 -0
  422. package/src/workspace/strategies/queue.ts +81 -0
  423. package/src/workspace/strategies/registry.ts +89 -0
  424. package/src/workspace/strategies/trunk.ts +123 -0
  425. package/src/workspace/strategies/types.ts +145 -0
  426. package/src/workspace/types.ts +1 -1
  427. package/src/workspace/workspace-manager.ts +1 -1
  428. package/.claude/settings.local.json +0 -59
  429. package/dist/map/utils/address-translation.d.ts +0 -99
  430. package/dist/map/utils/address-translation.d.ts.map +0 -1
  431. package/dist/map/utils/address-translation.js +0 -285
  432. package/dist/map/utils/address-translation.js.map +0 -1
  433. package/dist/map/utils/index.d.ts +0 -7
  434. package/dist/map/utils/index.d.ts.map +0 -1
  435. package/dist/map/utils/index.js +0 -7
  436. package/dist/map/utils/index.js.map +0 -1
  437. package/openspec/AGENTS.md +0 -456
  438. package/openspec/changes/archive/2025-12-21-add-mvp-foundation/design.md +0 -128
  439. package/openspec/changes/archive/2025-12-21-add-mvp-foundation/proposal.md +0 -49
  440. package/openspec/changes/archive/2025-12-21-add-mvp-foundation/specs/agent-manager/spec.md +0 -150
  441. package/openspec/changes/archive/2025-12-21-add-mvp-foundation/specs/cli-api/spec.md +0 -258
  442. package/openspec/changes/archive/2025-12-21-add-mvp-foundation/specs/event-store/spec.md +0 -160
  443. package/openspec/changes/archive/2025-12-21-add-mvp-foundation/specs/mcp-tools/spec.md +0 -224
  444. package/openspec/changes/archive/2025-12-21-add-mvp-foundation/specs/message-router/spec.md +0 -153
  445. package/openspec/changes/archive/2025-12-21-add-mvp-foundation/specs/task-manager/spec.md +0 -136
  446. package/openspec/changes/archive/2025-12-21-add-mvp-foundation/tasks.md +0 -147
  447. package/openspec/project.md +0 -31
  448. package/openspec/specs/agent-manager/spec.md +0 -154
  449. package/openspec/specs/cli-api/spec.md +0 -262
  450. package/openspec/specs/event-store/spec.md +0 -164
  451. package/openspec/specs/mcp-tools/spec.md +0 -228
  452. package/openspec/specs/message-router/spec.md +0 -157
  453. package/openspec/specs/task-manager/spec.md +0 -140
  454. package/references/acp-factory-ref/CHANGELOG.md +0 -33
  455. package/references/acp-factory-ref/LICENSE +0 -21
  456. package/references/acp-factory-ref/README.md +0 -341
  457. package/references/acp-factory-ref/package-lock.json +0 -3102
  458. package/references/acp-factory-ref/package.json +0 -96
  459. package/references/acp-factory-ref/python/CHANGELOG.md +0 -33
  460. package/references/acp-factory-ref/python/LICENSE +0 -21
  461. package/references/acp-factory-ref/python/Makefile +0 -57
  462. package/references/acp-factory-ref/python/README.md +0 -253
  463. package/references/acp-factory-ref/python/pyproject.toml +0 -73
  464. package/references/acp-factory-ref/python/tests/__init__.py +0 -0
  465. package/references/acp-factory-ref/python/tests/e2e/__init__.py +0 -1
  466. package/references/acp-factory-ref/python/tests/e2e/test_codex_e2e.py +0 -349
  467. package/references/acp-factory-ref/python/tests/e2e/test_gemini_e2e.py +0 -165
  468. package/references/acp-factory-ref/python/tests/e2e/test_opencode_e2e.py +0 -296
  469. package/references/acp-factory-ref/python/tests/test_client_handler.py +0 -543
  470. package/references/acp-factory-ref/python/tests/test_pushable.py +0 -199
  471. package/references/claude-code-acp/.github/workflows/ci.yml +0 -45
  472. package/references/claude-code-acp/.github/workflows/publish.yml +0 -34
  473. package/references/claude-code-acp/.prettierrc.json +0 -4
  474. package/references/claude-code-acp/CHANGELOG.md +0 -249
  475. package/references/claude-code-acp/LICENSE +0 -222
  476. package/references/claude-code-acp/README.md +0 -53
  477. package/references/claude-code-acp/docs/RELEASES.md +0 -24
  478. package/references/claude-code-acp/eslint.config.js +0 -48
  479. package/references/claude-code-acp/package-lock.json +0 -4570
  480. package/references/claude-code-acp/package.json +0 -88
  481. package/references/claude-code-acp/scripts/release.sh +0 -119
  482. package/references/claude-code-acp/src/acp-agent.ts +0 -2065
  483. package/references/claude-code-acp/src/index.ts +0 -26
  484. package/references/claude-code-acp/src/lib.ts +0 -38
  485. package/references/claude-code-acp/src/mcp-server.ts +0 -911
  486. package/references/claude-code-acp/src/settings.ts +0 -522
  487. package/references/claude-code-acp/src/tests/.claude/commands/quick-math.md +0 -5
  488. package/references/claude-code-acp/src/tests/.claude/commands/say-hello.md +0 -6
  489. package/references/claude-code-acp/src/tests/acp-agent-fork.test.ts +0 -479
  490. package/references/claude-code-acp/src/tests/acp-agent.test.ts +0 -1502
  491. package/references/claude-code-acp/src/tests/extract-lines.test.ts +0 -103
  492. package/references/claude-code-acp/src/tests/fork-session.test.ts +0 -335
  493. package/references/claude-code-acp/src/tests/replace-and-calculate-location.test.ts +0 -334
  494. package/references/claude-code-acp/src/tests/settings.test.ts +0 -617
  495. package/references/claude-code-acp/src/tests/skills-options.test.ts +0 -187
  496. package/references/claude-code-acp/src/tests/tools.test.ts +0 -318
  497. package/references/claude-code-acp/src/tests/typescript-declarations.test.ts +0 -558
  498. package/references/claude-code-acp/src/tools.ts +0 -819
  499. package/references/claude-code-acp/src/utils.ts +0 -171
  500. package/references/claude-code-acp/tsconfig.json +0 -18
  501. package/references/claude-code-acp/vitest.config.ts +0 -19
  502. package/references/multi-agent-protocol/.sudocode/issues.jsonl +0 -82
  503. package/references/multi-agent-protocol/.sudocode/specs.jsonl +0 -9
  504. package/references/multi-agent-protocol/LICENSE +0 -21
  505. package/references/multi-agent-protocol/README.md +0 -113
  506. package/references/multi-agent-protocol/docs/00-design-specification.md +0 -460
  507. package/references/multi-agent-protocol/docs/01-open-questions.md +0 -1050
  508. package/references/multi-agent-protocol/docs/02-wire-protocol.md +0 -296
  509. package/references/multi-agent-protocol/docs/03-streaming-semantics.md +0 -252
  510. package/references/multi-agent-protocol/docs/04-error-handling.md +0 -231
  511. package/references/multi-agent-protocol/docs/05-connection-model.md +0 -244
  512. package/references/multi-agent-protocol/docs/06-visibility-permissions.md +0 -243
  513. package/references/multi-agent-protocol/docs/07-federation.md +0 -259
  514. package/references/multi-agent-protocol/docs/08-macro-agent-migration.md +0 -253
  515. package/references/multi-agent-protocol/package-lock.json +0 -3239
  516. package/references/multi-agent-protocol/package.json +0 -56
  517. package/references/multi-agent-protocol/schema/meta.json +0 -337
  518. package/references/multi-agent-protocol/schema/schema.json +0 -1828
@@ -1,479 +0,0 @@
1
- /**
2
- * Tests for fork-related helper methods in ClaudeAcpAgent.
3
- *
4
- * Since the methods are private, we test them by:
5
- * 1. Creating a test subclass that exposes the private methods
6
- * 2. Testing the file manipulation logic directly
7
- */
8
-
9
- import { describe, it, expect, beforeEach, afterEach, vi } from "vitest";
10
- import { ClaudeAcpAgent } from "../acp-agent.js";
11
- import type { AgentSideConnection } from "@agentclientprotocol/sdk";
12
- import * as fs from "node:fs";
13
- import * as path from "node:path";
14
- import * as os from "node:os";
15
-
16
- // Create a test subclass that exposes private methods for testing
17
- class TestableClaudeAcpAgent extends ClaudeAcpAgent {
18
- // Expose private methods for testing
19
- public testExtractInternalSessionId(filePath: string): string | null {
20
- return (this as any).extractInternalSessionId(filePath);
21
- }
22
-
23
- public testPromoteToFullSession(filePath: string): boolean {
24
- return (this as any).promoteToFullSession(filePath);
25
- }
26
-
27
- public testUpdateSessionIdInFile(filePath: string, newSessionId: string): boolean {
28
- return (this as any).updateSessionIdInFile(filePath, newSessionId);
29
- }
30
-
31
- public testGetSessionDirPath(cwd: string): string {
32
- return (this as any).getSessionDirPath(cwd);
33
- }
34
-
35
- public testGetSessionFilePath(sessionId: string, cwd: string): string {
36
- return (this as any).getSessionFilePath(sessionId, cwd);
37
- }
38
-
39
- public async testDiscoverCliSessionId(
40
- sessionDir: string,
41
- beforeFiles: Set<string>,
42
- fallbackId: string,
43
- timeout?: number
44
- ): Promise<string> {
45
- return (this as any).discoverCliSessionId(sessionDir, beforeFiles, fallbackId, timeout);
46
- }
47
-
48
- public async testWaitForSessionFile(filePath: string, timeout: number): Promise<boolean> {
49
- return (this as any).waitForSessionFile(filePath, timeout);
50
- }
51
- }
52
-
53
- describe("ClaudeAcpAgent fork helpers", () => {
54
- let tempDir: string;
55
- let agent: TestableClaudeAcpAgent;
56
- const mockLogger = {
57
- log: vi.fn(),
58
- error: vi.fn(),
59
- };
60
-
61
- // Create a minimal mock client
62
- const mockClient = {
63
- sessionUpdate: vi.fn(),
64
- readTextFile: vi.fn(),
65
- writeTextFile: vi.fn(),
66
- requestPermission: vi.fn(),
67
- } as unknown as AgentSideConnection;
68
-
69
- beforeEach(async () => {
70
- tempDir = await fs.promises.mkdtemp(path.join(os.tmpdir(), "acp-agent-fork-test-"));
71
- agent = new TestableClaudeAcpAgent(mockClient, mockLogger);
72
- vi.clearAllMocks();
73
- });
74
-
75
- afterEach(async () => {
76
- await fs.promises.rm(tempDir, { recursive: true, force: true });
77
- });
78
-
79
- describe("extractInternalSessionId", () => {
80
- it("should extract UUID sessionId from valid JSONL file", async () => {
81
- const filePath = path.join(tempDir, "session.jsonl");
82
- const sessionId = "12345678-1234-1234-1234-123456789abc";
83
-
84
- await fs.promises.writeFile(
85
- filePath,
86
- JSON.stringify({ sessionId, type: "init" }) + "\n"
87
- );
88
-
89
- const result = agent.testExtractInternalSessionId(filePath);
90
- expect(result).toBe(sessionId);
91
- });
92
-
93
- it("should return null for non-existent file", () => {
94
- const result = agent.testExtractInternalSessionId(path.join(tempDir, "nonexistent.jsonl"));
95
- expect(result).toBeNull();
96
- });
97
-
98
- it("should return null for file without sessionId", async () => {
99
- const filePath = path.join(tempDir, "session.jsonl");
100
- await fs.promises.writeFile(
101
- filePath,
102
- JSON.stringify({ type: "init" }) + "\n"
103
- );
104
-
105
- const result = agent.testExtractInternalSessionId(filePath);
106
- expect(result).toBeNull();
107
- });
108
-
109
- it("should return null for non-UUID sessionId", async () => {
110
- const filePath = path.join(tempDir, "session.jsonl");
111
- await fs.promises.writeFile(
112
- filePath,
113
- JSON.stringify({ sessionId: "not-a-uuid", type: "init" }) + "\n"
114
- );
115
-
116
- const result = agent.testExtractInternalSessionId(filePath);
117
- expect(result).toBeNull();
118
- });
119
-
120
- it("should handle empty file", async () => {
121
- const filePath = path.join(tempDir, "session.jsonl");
122
- await fs.promises.writeFile(filePath, "");
123
-
124
- const result = agent.testExtractInternalSessionId(filePath);
125
- expect(result).toBeNull();
126
- });
127
-
128
- it("should find sessionId from first non-empty line", async () => {
129
- const filePath = path.join(tempDir, "session.jsonl");
130
- const sessionId = "aaaaaaaa-bbbb-cccc-dddd-eeeeeeeeeeee";
131
-
132
- await fs.promises.writeFile(
133
- filePath,
134
- "\n\n" + JSON.stringify({ sessionId, type: "init" }) + "\n"
135
- );
136
-
137
- const result = agent.testExtractInternalSessionId(filePath);
138
- expect(result).toBe(sessionId);
139
- });
140
- });
141
-
142
- describe("promoteToFullSession", () => {
143
- it("should change isSidechain from true to false", async () => {
144
- const filePath = path.join(tempDir, "session.jsonl");
145
- const lines = [
146
- JSON.stringify({ sessionId: "test-id", isSidechain: true }),
147
- JSON.stringify({ type: "message", content: "hello" }),
148
- ];
149
- await fs.promises.writeFile(filePath, lines.join("\n"));
150
-
151
- const result = agent.testPromoteToFullSession(filePath);
152
- expect(result).toBe(true);
153
-
154
- const content = await fs.promises.readFile(filePath, "utf-8");
155
- const parsedLines = content.split("\n").map(line => JSON.parse(line));
156
-
157
- expect(parsedLines[0].isSidechain).toBe(false);
158
- expect(parsedLines[1].content).toBe("hello");
159
- });
160
-
161
- it("should return false for non-existent file", () => {
162
- const result = agent.testPromoteToFullSession(path.join(tempDir, "nonexistent.jsonl"));
163
- expect(result).toBe(false);
164
- });
165
-
166
- it("should preserve other fields when promoting", async () => {
167
- const filePath = path.join(tempDir, "session.jsonl");
168
- const original = {
169
- sessionId: "test-id",
170
- isSidechain: true,
171
- cwd: "/some/path",
172
- model: "claude-3",
173
- };
174
- await fs.promises.writeFile(filePath, JSON.stringify(original));
175
-
176
- agent.testPromoteToFullSession(filePath);
177
-
178
- const content = await fs.promises.readFile(filePath, "utf-8");
179
- const parsed = JSON.parse(content);
180
-
181
- expect(parsed.sessionId).toBe("test-id");
182
- expect(parsed.isSidechain).toBe(false);
183
- expect(parsed.cwd).toBe("/some/path");
184
- expect(parsed.model).toBe("claude-3");
185
- });
186
-
187
- it("should handle file without isSidechain field", async () => {
188
- const filePath = path.join(tempDir, "session.jsonl");
189
- await fs.promises.writeFile(
190
- filePath,
191
- JSON.stringify({ sessionId: "test-id", type: "init" })
192
- );
193
-
194
- const result = agent.testPromoteToFullSession(filePath);
195
- expect(result).toBe(true);
196
-
197
- const content = await fs.promises.readFile(filePath, "utf-8");
198
- const parsed = JSON.parse(content);
199
- expect(parsed.isSidechain).toBeUndefined();
200
- });
201
-
202
- it("should log success message", async () => {
203
- const filePath = path.join(tempDir, "session.jsonl");
204
- await fs.promises.writeFile(
205
- filePath,
206
- JSON.stringify({ sessionId: "test-id", isSidechain: true })
207
- );
208
-
209
- agent.testPromoteToFullSession(filePath);
210
-
211
- expect(mockLogger.log).toHaveBeenCalledWith(
212
- expect.stringContaining("Promoted sidechain to full session")
213
- );
214
- });
215
- });
216
-
217
- describe("updateSessionIdInFile", () => {
218
- it("should update sessionId in all lines", async () => {
219
- const filePath = path.join(tempDir, "session.jsonl");
220
- const oldId = "old-session-id";
221
- const newId = "new-session-id";
222
-
223
- const lines = [
224
- JSON.stringify({ sessionId: oldId, type: "init" }),
225
- JSON.stringify({ sessionId: oldId, type: "message", content: "hello" }),
226
- JSON.stringify({ sessionId: oldId, type: "tool_use", name: "Read" }),
227
- ];
228
- await fs.promises.writeFile(filePath, lines.join("\n"));
229
-
230
- const result = agent.testUpdateSessionIdInFile(filePath, newId);
231
- expect(result).toBe(true);
232
-
233
- const content = await fs.promises.readFile(filePath, "utf-8");
234
- const parsedLines = content.split("\n").map(line => JSON.parse(line));
235
-
236
- for (const line of parsedLines) {
237
- expect(line.sessionId).toBe(newId);
238
- }
239
- });
240
-
241
- it("should return false for non-existent file", () => {
242
- const result = agent.testUpdateSessionIdInFile(
243
- path.join(tempDir, "nonexistent.jsonl"),
244
- "new-id"
245
- );
246
- expect(result).toBe(false);
247
- });
248
-
249
- it("should preserve lines without sessionId", async () => {
250
- const filePath = path.join(tempDir, "session.jsonl");
251
- const lines = [
252
- JSON.stringify({ sessionId: "old-id", type: "init" }),
253
- JSON.stringify({ type: "comment", text: "no sessionId here" }),
254
- ];
255
- await fs.promises.writeFile(filePath, lines.join("\n"));
256
-
257
- agent.testUpdateSessionIdInFile(filePath, "new-id");
258
-
259
- const content = await fs.promises.readFile(filePath, "utf-8");
260
- const parsedLines = content.split("\n").map(line => JSON.parse(line));
261
-
262
- expect(parsedLines[0].sessionId).toBe("new-id");
263
- expect(parsedLines[1].sessionId).toBeUndefined();
264
- expect(parsedLines[1].text).toBe("no sessionId here");
265
- });
266
-
267
- it("should handle empty lines gracefully", async () => {
268
- const filePath = path.join(tempDir, "session.jsonl");
269
- const content = JSON.stringify({ sessionId: "old-id" }) + "\n\n" + JSON.stringify({ sessionId: "old-id" });
270
- await fs.promises.writeFile(filePath, content);
271
-
272
- const result = agent.testUpdateSessionIdInFile(filePath, "new-id");
273
- expect(result).toBe(true);
274
-
275
- const newContent = await fs.promises.readFile(filePath, "utf-8");
276
- const lines = newContent.split("\n");
277
-
278
- expect(JSON.parse(lines[0]).sessionId).toBe("new-id");
279
- expect(lines[1]).toBe(""); // Empty line preserved
280
- expect(JSON.parse(lines[2]).sessionId).toBe("new-id");
281
- });
282
-
283
- it("should log success message", async () => {
284
- const filePath = path.join(tempDir, "session.jsonl");
285
- await fs.promises.writeFile(
286
- filePath,
287
- JSON.stringify({ sessionId: "old-id" })
288
- );
289
-
290
- agent.testUpdateSessionIdInFile(filePath, "new-id");
291
-
292
- expect(mockLogger.log).toHaveBeenCalledWith(
293
- expect.stringContaining("Updated session ID in file")
294
- );
295
- });
296
- });
297
-
298
- describe("getSessionDirPath", () => {
299
- it("should compute correct path with cwd hash", () => {
300
- const result = agent.testGetSessionDirPath("/private/tmp");
301
- const homeDir = os.homedir();
302
-
303
- expect(result).toBe(`${homeDir}/.claude/projects/-private-tmp`);
304
- });
305
-
306
- it("should replace both / and _ with -", () => {
307
- // Use tempDir which exists
308
- const testDir = path.join(tempDir, "my_project");
309
- fs.mkdirSync(testDir, { recursive: true });
310
-
311
- const result = agent.testGetSessionDirPath(testDir);
312
- const realPath = fs.realpathSync(testDir);
313
- const expectedHash = realPath.replace(/[/_]/g, "-");
314
-
315
- expect(result).toBe(`${os.homedir()}/.claude/projects/${expectedHash}`);
316
- });
317
-
318
- it("should resolve symlinks", () => {
319
- // /var on macOS is a symlink to /private/var
320
- const result = agent.testGetSessionDirPath("/var/tmp");
321
- const homeDir = os.homedir();
322
-
323
- // Should use the resolved path
324
- expect(result).toBe(`${homeDir}/.claude/projects/-private-var-tmp`);
325
- });
326
- });
327
-
328
- describe("getSessionFilePath", () => {
329
- it("should append sessionId.jsonl to session dir", () => {
330
- const result = agent.testGetSessionFilePath("my-session-id", "/private/tmp");
331
- const homeDir = os.homedir();
332
-
333
- expect(result).toBe(`${homeDir}/.claude/projects/-private-tmp/my-session-id.jsonl`);
334
- });
335
- });
336
-
337
- describe("waitForSessionFile", () => {
338
- it("should return true immediately if file exists", async () => {
339
- const filePath = path.join(tempDir, "session.jsonl");
340
- await fs.promises.writeFile(filePath, "{}");
341
-
342
- const start = Date.now();
343
- const result = await agent.testWaitForSessionFile(filePath, 1000);
344
- const elapsed = Date.now() - start;
345
-
346
- expect(result).toBe(true);
347
- expect(elapsed).toBeLessThan(200);
348
- });
349
-
350
- it("should return true when file appears before timeout", async () => {
351
- const filePath = path.join(tempDir, "session.jsonl");
352
-
353
- // Create file after 200ms
354
- setTimeout(async () => {
355
- await fs.promises.writeFile(filePath, "{}");
356
- }, 200);
357
-
358
- const start = Date.now();
359
- const result = await agent.testWaitForSessionFile(filePath, 2000);
360
- const elapsed = Date.now() - start;
361
-
362
- expect(result).toBe(true);
363
- expect(elapsed).toBeGreaterThanOrEqual(200);
364
- expect(elapsed).toBeLessThan(2000);
365
- });
366
-
367
- it("should return false when timeout expires", async () => {
368
- const filePath = path.join(tempDir, "nonexistent.jsonl");
369
-
370
- const start = Date.now();
371
- const result = await agent.testWaitForSessionFile(filePath, 300);
372
- const elapsed = Date.now() - start;
373
-
374
- expect(result).toBe(false);
375
- expect(elapsed).toBeGreaterThanOrEqual(300);
376
- expect(elapsed).toBeLessThan(500);
377
- });
378
- });
379
-
380
- describe("discoverCliSessionId", () => {
381
- it("should find new agent-xxx file", async () => {
382
- const sessionDir = path.join(tempDir, "sessions");
383
- await fs.promises.mkdir(sessionDir, { recursive: true });
384
-
385
- const beforeFiles = new Set<string>();
386
-
387
- // Create an agent-xxx file
388
- const agentFile = "agent-abc123.jsonl";
389
- await fs.promises.writeFile(path.join(sessionDir, agentFile), "{}");
390
-
391
- const result = await agent.testDiscoverCliSessionId(sessionDir, beforeFiles, "fallback", 1000);
392
-
393
- expect(result).toBe("agent-abc123");
394
- });
395
-
396
- it("should ignore non-agent files", async () => {
397
- const sessionDir = path.join(tempDir, "sessions");
398
- await fs.promises.mkdir(sessionDir, { recursive: true });
399
-
400
- const beforeFiles = new Set<string>();
401
-
402
- // Create a UUID-named file (not agent-xxx)
403
- const uuidFile = "12345678-1234-1234-1234-123456789abc.jsonl";
404
- await fs.promises.writeFile(path.join(sessionDir, uuidFile), "{}");
405
-
406
- const result = await agent.testDiscoverCliSessionId(sessionDir, beforeFiles, "fallback", 500);
407
-
408
- expect(result).toBe("fallback");
409
- });
410
-
411
- it("should return fallback when no new files found", async () => {
412
- const sessionDir = path.join(tempDir, "sessions");
413
- await fs.promises.mkdir(sessionDir, { recursive: true });
414
-
415
- const beforeFiles = new Set<string>();
416
-
417
- const result = await agent.testDiscoverCliSessionId(sessionDir, beforeFiles, "fallback-id", 300);
418
-
419
- expect(result).toBe("fallback-id");
420
- });
421
-
422
- it("should ignore files that existed before", async () => {
423
- const sessionDir = path.join(tempDir, "sessions");
424
- await fs.promises.mkdir(sessionDir, { recursive: true });
425
-
426
- // Create file before
427
- const existingFile = "agent-existing.jsonl";
428
- await fs.promises.writeFile(path.join(sessionDir, existingFile), "{}");
429
-
430
- const beforeFiles = new Set<string>([existingFile]);
431
-
432
- const result = await agent.testDiscoverCliSessionId(sessionDir, beforeFiles, "fallback", 300);
433
-
434
- expect(result).toBe("fallback");
435
- });
436
-
437
- it("should return newest file when multiple agent files appear", async () => {
438
- const sessionDir = path.join(tempDir, "sessions");
439
- await fs.promises.mkdir(sessionDir, { recursive: true });
440
-
441
- const beforeFiles = new Set<string>();
442
-
443
- // Create first file - use hex chars to match agent-[a-f0-9]+ pattern
444
- const firstPath = path.join(sessionDir, "agent-aaa111.jsonl");
445
- await fs.promises.writeFile(firstPath, "{}");
446
-
447
- // Wait a bit to ensure different mtime, then create second file
448
- await new Promise(resolve => setTimeout(resolve, 100));
449
- const secondPath = path.join(sessionDir, "agent-bbb222.jsonl");
450
- await fs.promises.writeFile(secondPath, "{}");
451
-
452
- // Verify files exist before calling discover
453
- expect(fs.existsSync(firstPath)).toBe(true);
454
- expect(fs.existsSync(secondPath)).toBe(true);
455
-
456
- const result = await agent.testDiscoverCliSessionId(sessionDir, beforeFiles, "fallback", 1000);
457
-
458
- expect(result).toBe("agent-bbb222");
459
- });
460
-
461
- it("should handle non-existent session directory initially", async () => {
462
- const sessionDir = path.join(tempDir, "nonexistent-dir");
463
- const beforeFiles = new Set<string>();
464
-
465
- // Start the discovery in parallel with file creation
466
- const discoverPromise = agent.testDiscoverCliSessionId(sessionDir, beforeFiles, "fallback", 2000);
467
-
468
- // Create directory and file after 200ms (within the 2000ms timeout)
469
- // Use hex chars to match agent-[a-f0-9]+ pattern
470
- await new Promise(resolve => setTimeout(resolve, 200));
471
- await fs.promises.mkdir(sessionDir, { recursive: true });
472
- await fs.promises.writeFile(path.join(sessionDir, "agent-ccc333.jsonl"), "{}");
473
-
474
- const result = await discoverPromise;
475
-
476
- expect(result).toBe("agent-ccc333");
477
- });
478
- });
479
- });