macro-agent 0.1.0 → 0.1.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (660) hide show
  1. package/.claude/settings.local.json +3 -1
  2. package/.sudocode/issues.jsonl +28 -0
  3. package/.sudocode/specs.jsonl +8 -0
  4. package/CLAUDE.md +25 -17
  5. package/README.md +11 -29
  6. package/dist/acp/macro-agent.d.ts +15 -0
  7. package/dist/acp/macro-agent.d.ts.map +1 -1
  8. package/dist/acp/macro-agent.js +131 -35
  9. package/dist/acp/macro-agent.js.map +1 -1
  10. package/dist/acp/types.d.ts +32 -1
  11. package/dist/acp/types.d.ts.map +1 -1
  12. package/dist/acp/types.js.map +1 -1
  13. package/dist/agent/agent-manager.d.ts +65 -1
  14. package/dist/agent/agent-manager.d.ts.map +1 -1
  15. package/dist/agent/agent-manager.js +544 -200
  16. package/dist/agent/agent-manager.js.map +1 -1
  17. package/dist/agent/types.d.ts +8 -1
  18. package/dist/agent/types.d.ts.map +1 -1
  19. package/dist/agent/types.js.map +1 -1
  20. package/dist/api/server.d.ts +8 -1
  21. package/dist/api/server.d.ts.map +1 -1
  22. package/dist/api/server.js +136 -8
  23. package/dist/api/server.js.map +1 -1
  24. package/dist/api/types.d.ts +1 -1
  25. package/dist/api/types.d.ts.map +1 -1
  26. package/dist/auth/index.d.ts +2 -0
  27. package/dist/auth/index.d.ts.map +1 -0
  28. package/dist/auth/index.js +2 -0
  29. package/dist/auth/index.js.map +1 -0
  30. package/dist/auth/token.d.ts +41 -0
  31. package/dist/auth/token.d.ts.map +1 -0
  32. package/dist/auth/token.js +73 -0
  33. package/dist/auth/token.js.map +1 -0
  34. package/dist/cli/acp.d.ts +2 -23
  35. package/dist/cli/acp.d.ts.map +1 -1
  36. package/dist/cli/acp.js +197 -61
  37. package/dist/cli/acp.js.map +1 -1
  38. package/dist/cli/index.js +152 -16
  39. package/dist/cli/index.js.map +1 -1
  40. package/dist/cli/mcp.d.ts +6 -0
  41. package/dist/cli/mcp.d.ts.map +1 -1
  42. package/dist/cli/mcp.js +279 -173
  43. package/dist/cli/mcp.js.map +1 -1
  44. package/dist/cli/parse-args.d.ts +20 -0
  45. package/dist/cli/parse-args.d.ts.map +1 -0
  46. package/dist/cli/parse-args.js +43 -0
  47. package/dist/cli/parse-args.js.map +1 -0
  48. package/dist/cli/stable-instance-id.d.ts +8 -0
  49. package/dist/cli/stable-instance-id.d.ts.map +1 -0
  50. package/dist/cli/stable-instance-id.js +14 -0
  51. package/dist/cli/stable-instance-id.js.map +1 -0
  52. package/dist/config/project-config.d.ts +85 -7
  53. package/dist/config/project-config.d.ts.map +1 -1
  54. package/dist/config/project-config.js +133 -20
  55. package/dist/config/project-config.js.map +1 -1
  56. package/dist/index.d.ts +1 -0
  57. package/dist/index.d.ts.map +1 -1
  58. package/dist/index.js +2 -0
  59. package/dist/index.js.map +1 -1
  60. package/dist/lifecycle/handlers/index.d.ts +7 -3
  61. package/dist/lifecycle/handlers/index.d.ts.map +1 -1
  62. package/dist/lifecycle/handlers/index.js +25 -8
  63. package/dist/lifecycle/handlers/index.js.map +1 -1
  64. package/dist/lifecycle/types.d.ts +2 -0
  65. package/dist/lifecycle/types.d.ts.map +1 -1
  66. package/dist/lifecycle/types.js.map +1 -1
  67. package/dist/map/adapter/acp-over-map.d.ts +17 -0
  68. package/dist/map/adapter/acp-over-map.d.ts.map +1 -1
  69. package/dist/map/adapter/acp-over-map.js +384 -23
  70. package/dist/map/adapter/acp-over-map.js.map +1 -1
  71. package/dist/map/adapter/connection-manager.d.ts.map +1 -1
  72. package/dist/map/adapter/connection-manager.js +3 -0
  73. package/dist/map/adapter/connection-manager.js.map +1 -1
  74. package/dist/map/adapter/event-log.d.ts +87 -0
  75. package/dist/map/adapter/event-log.d.ts.map +1 -0
  76. package/dist/map/adapter/event-log.js +122 -0
  77. package/dist/map/adapter/event-log.js.map +1 -0
  78. package/dist/map/adapter/event-translator.js +6 -6
  79. package/dist/map/adapter/event-translator.js.map +1 -1
  80. package/dist/map/adapter/extensions/agent-lifecycle.d.ts +82 -0
  81. package/dist/map/adapter/extensions/agent-lifecycle.d.ts.map +1 -0
  82. package/dist/map/adapter/extensions/agent-lifecycle.js +164 -0
  83. package/dist/map/adapter/extensions/agent-lifecycle.js.map +1 -0
  84. package/dist/map/adapter/extensions/index.d.ts +13 -1
  85. package/dist/map/adapter/extensions/index.d.ts.map +1 -1
  86. package/dist/map/adapter/extensions/index.js +61 -0
  87. package/dist/map/adapter/extensions/index.js.map +1 -1
  88. package/dist/map/adapter/extensions/mcp-bridge.d.ts +57 -0
  89. package/dist/map/adapter/extensions/mcp-bridge.d.ts.map +1 -0
  90. package/dist/map/adapter/extensions/mcp-bridge.js +745 -0
  91. package/dist/map/adapter/extensions/mcp-bridge.js.map +1 -0
  92. package/dist/map/adapter/extensions/rename.d.ts +29 -0
  93. package/dist/map/adapter/extensions/rename.d.ts.map +1 -0
  94. package/dist/map/adapter/extensions/rename.js +49 -0
  95. package/dist/map/adapter/extensions/rename.js.map +1 -0
  96. package/dist/map/adapter/extensions/streams.d.ts +95 -0
  97. package/dist/map/adapter/extensions/streams.d.ts.map +1 -0
  98. package/dist/map/adapter/extensions/streams.js +515 -0
  99. package/dist/map/adapter/extensions/streams.js.map +1 -0
  100. package/dist/map/adapter/extensions/task.d.ts.map +1 -1
  101. package/dist/map/adapter/extensions/task.js +10 -0
  102. package/dist/map/adapter/extensions/task.js.map +1 -1
  103. package/dist/map/adapter/extensions/update-metadata.d.ts +29 -0
  104. package/dist/map/adapter/extensions/update-metadata.d.ts.map +1 -0
  105. package/dist/map/adapter/extensions/update-metadata.js +67 -0
  106. package/dist/map/adapter/extensions/update-metadata.js.map +1 -0
  107. package/dist/map/adapter/index.d.ts +2 -1
  108. package/dist/map/adapter/index.d.ts.map +1 -1
  109. package/dist/map/adapter/index.js +10 -2
  110. package/dist/map/adapter/index.js.map +1 -1
  111. package/dist/map/adapter/interface.d.ts +2 -0
  112. package/dist/map/adapter/interface.d.ts.map +1 -1
  113. package/dist/map/adapter/map-adapter.d.ts +3 -0
  114. package/dist/map/adapter/map-adapter.d.ts.map +1 -1
  115. package/dist/map/adapter/map-adapter.js +258 -35
  116. package/dist/map/adapter/map-adapter.js.map +1 -1
  117. package/dist/map/adapter/subscription-manager.d.ts.map +1 -1
  118. package/dist/map/adapter/subscription-manager.js +5 -1
  119. package/dist/map/adapter/subscription-manager.js.map +1 -1
  120. package/dist/map/adapter/types.d.ts +3 -1
  121. package/dist/map/adapter/types.d.ts.map +1 -1
  122. package/dist/mcp/map-client.d.ts +39 -0
  123. package/dist/mcp/map-client.d.ts.map +1 -0
  124. package/dist/mcp/map-client.js +129 -0
  125. package/dist/mcp/map-client.js.map +1 -0
  126. package/dist/mcp/mcp-server.d.ts +16 -0
  127. package/dist/mcp/mcp-server.d.ts.map +1 -1
  128. package/dist/mcp/mcp-server.js +125 -88
  129. package/dist/mcp/mcp-server.js.map +1 -1
  130. package/dist/mcp/tools/done.d.ts.map +1 -1
  131. package/dist/mcp/tools/done.js +18 -0
  132. package/dist/mcp/tools/done.js.map +1 -1
  133. package/dist/mcp/types.d.ts +9 -1
  134. package/dist/mcp/types.d.ts.map +1 -1
  135. package/dist/mcp/types.js.map +1 -1
  136. package/dist/metrics/metrics.js +1 -1
  137. package/dist/metrics/metrics.js.map +1 -1
  138. package/dist/roles/builtin/coordinator.d.ts.map +1 -1
  139. package/dist/roles/builtin/coordinator.js +2 -1
  140. package/dist/roles/builtin/coordinator.js.map +1 -1
  141. package/dist/roles/builtin/integrator.d.ts.map +1 -1
  142. package/dist/roles/builtin/integrator.js +2 -1
  143. package/dist/roles/builtin/integrator.js.map +1 -1
  144. package/dist/roles/builtin/worker.d.ts.map +1 -1
  145. package/dist/roles/builtin/worker.js +3 -1
  146. package/dist/roles/builtin/worker.js.map +1 -1
  147. package/dist/roles/capabilities.d.ts +9 -1
  148. package/dist/roles/capabilities.d.ts.map +1 -1
  149. package/dist/roles/capabilities.js +27 -7
  150. package/dist/roles/capabilities.js.map +1 -1
  151. package/dist/roles/config-loader.d.ts +6 -6
  152. package/dist/roles/config-loader.d.ts.map +1 -1
  153. package/dist/roles/config-loader.js +8 -7
  154. package/dist/roles/config-loader.js.map +1 -1
  155. package/dist/roles/registry.d.ts +2 -2
  156. package/dist/roles/registry.js +2 -2
  157. package/dist/roles/types.d.ts +3 -1
  158. package/dist/roles/types.d.ts.map +1 -1
  159. package/dist/server/combined-server.d.ts +28 -1
  160. package/dist/server/combined-server.d.ts.map +1 -1
  161. package/dist/server/combined-server.js +111 -8
  162. package/dist/server/combined-server.js.map +1 -1
  163. package/dist/store/event-store.d.ts +2 -1
  164. package/dist/store/event-store.d.ts.map +1 -1
  165. package/dist/store/event-store.js +80 -24
  166. package/dist/store/event-store.js.map +1 -1
  167. package/dist/store/instance.d.ts +1 -1
  168. package/dist/store/instance.d.ts.map +1 -1
  169. package/dist/store/instance.js +2 -2
  170. package/dist/store/instance.js.map +1 -1
  171. package/dist/store/types/agents.d.ts +23 -0
  172. package/dist/store/types/agents.d.ts.map +1 -1
  173. package/dist/store/types/events.d.ts +1 -1
  174. package/dist/store/types/events.d.ts.map +1 -1
  175. package/dist/task/backend/index.d.ts +47 -29
  176. package/dist/task/backend/index.d.ts.map +1 -1
  177. package/dist/task/backend/index.js +109 -71
  178. package/dist/task/backend/index.js.map +1 -1
  179. package/dist/task/backend/memory.d.ts +1 -0
  180. package/dist/task/backend/memory.d.ts.map +1 -1
  181. package/dist/task/backend/memory.js +3 -0
  182. package/dist/task/backend/memory.js.map +1 -1
  183. package/dist/task/backend/opentasks/backend.d.ts +140 -0
  184. package/dist/task/backend/opentasks/backend.d.ts.map +1 -0
  185. package/dist/task/backend/opentasks/backend.js +1023 -0
  186. package/dist/task/backend/opentasks/backend.js.map +1 -0
  187. package/dist/task/backend/opentasks/client.d.ts +337 -0
  188. package/dist/task/backend/opentasks/client.d.ts.map +1 -0
  189. package/dist/task/backend/opentasks/client.js +225 -0
  190. package/dist/task/backend/opentasks/client.js.map +1 -0
  191. package/dist/task/backend/opentasks/daemon-manager.d.ts +89 -0
  192. package/dist/task/backend/opentasks/daemon-manager.d.ts.map +1 -0
  193. package/dist/task/backend/opentasks/daemon-manager.js +195 -0
  194. package/dist/task/backend/opentasks/daemon-manager.js.map +1 -0
  195. package/dist/task/backend/opentasks/index.d.ts +21 -0
  196. package/dist/task/backend/opentasks/index.d.ts.map +1 -0
  197. package/dist/task/backend/opentasks/index.js +21 -0
  198. package/dist/task/backend/opentasks/index.js.map +1 -0
  199. package/dist/task/backend/opentasks/mapping.d.ts +48 -0
  200. package/dist/task/backend/opentasks/mapping.d.ts.map +1 -0
  201. package/dist/task/backend/opentasks/mapping.js +77 -0
  202. package/dist/task/backend/opentasks/mapping.js.map +1 -0
  203. package/dist/task/backend/types.d.ts +33 -53
  204. package/dist/task/backend/types.d.ts.map +1 -1
  205. package/dist/task/backend/types.js +7 -11
  206. package/dist/task/backend/types.js.map +1 -1
  207. package/dist/task/backend/unified-tool-provider.d.ts +57 -0
  208. package/dist/task/backend/unified-tool-provider.d.ts.map +1 -0
  209. package/dist/task/backend/unified-tool-provider.js +623 -0
  210. package/dist/task/backend/unified-tool-provider.js.map +1 -0
  211. package/dist/teams/index.d.ts +3 -1
  212. package/dist/teams/index.d.ts.map +1 -1
  213. package/dist/teams/index.js +2 -0
  214. package/dist/teams/index.js.map +1 -1
  215. package/dist/teams/seed-defaults.d.ts +20 -0
  216. package/dist/teams/seed-defaults.d.ts.map +1 -0
  217. package/dist/teams/seed-defaults.js +71 -0
  218. package/dist/teams/seed-defaults.js.map +1 -0
  219. package/dist/teams/team-loader.d.ts +7 -3
  220. package/dist/teams/team-loader.d.ts.map +1 -1
  221. package/dist/teams/team-loader.js +156 -164
  222. package/dist/teams/team-loader.js.map +1 -1
  223. package/dist/teams/team-manager.d.ts +112 -0
  224. package/dist/teams/team-manager.d.ts.map +1 -0
  225. package/dist/teams/team-manager.js +305 -0
  226. package/dist/teams/team-manager.js.map +1 -0
  227. package/dist/teams/team-runtime.d.ts +125 -19
  228. package/dist/teams/team-runtime.d.ts.map +1 -1
  229. package/dist/teams/team-runtime.js +529 -119
  230. package/dist/teams/team-runtime.js.map +1 -1
  231. package/dist/teams/types.d.ts +41 -151
  232. package/dist/teams/types.d.ts.map +1 -1
  233. package/dist/teams/types.js +2 -3
  234. package/dist/teams/types.js.map +1 -1
  235. package/docs/architecture.md +7 -6
  236. package/docs/configuration.md +26 -62
  237. package/docs/implementation-details.md +5 -5
  238. package/docs/implementation-summary.md +17 -17
  239. package/docs/plan-self-driving-support.md +4 -4
  240. package/docs/spec-self-driving-support.md +10 -10
  241. package/docs/team-templates.md +2 -2
  242. package/docs/teams.md +76 -3
  243. package/docs/troubleshooting.md +10 -11
  244. package/package.json +7 -4
  245. package/references/minimem/.claude/settings.json +7 -0
  246. package/references/minimem/.sudocode/issues.jsonl +18 -0
  247. package/references/minimem/.sudocode/specs.jsonl +1 -0
  248. package/references/minimem/CLAUDE.md +310 -0
  249. package/references/minimem/README.md +562 -0
  250. package/references/minimem/claude-plugin/.claude-plugin/plugin.json +10 -0
  251. package/references/minimem/claude-plugin/.mcp.json +7 -0
  252. package/references/minimem/claude-plugin/README.md +158 -0
  253. package/references/minimem/claude-plugin/commands/recall.md +47 -0
  254. package/references/minimem/claude-plugin/commands/remember.md +41 -0
  255. package/references/minimem/claude-plugin/hooks/__tests__/hooks.test.ts +272 -0
  256. package/references/minimem/claude-plugin/hooks/hooks.json +27 -0
  257. package/references/minimem/claude-plugin/hooks/session-end.sh +86 -0
  258. package/references/minimem/claude-plugin/hooks/session-start.sh +85 -0
  259. package/references/minimem/claude-plugin/skills/memory/SKILL.md +108 -0
  260. package/references/minimem/media/banner.png +0 -0
  261. package/references/minimem/package-lock.json +5373 -0
  262. package/references/minimem/package.json +72 -0
  263. package/references/minimem/scripts/postbuild.js +35 -0
  264. package/references/minimem/src/__tests__/edge-cases.test.ts +371 -0
  265. package/references/minimem/src/__tests__/errors.test.ts +265 -0
  266. package/references/minimem/src/__tests__/helpers.ts +199 -0
  267. package/references/minimem/src/__tests__/internal.test.ts +407 -0
  268. package/references/minimem/src/__tests__/knowledge.test.ts +287 -0
  269. package/references/minimem/src/__tests__/minimem.integration.test.ts +1127 -0
  270. package/references/minimem/src/__tests__/session.test.ts +190 -0
  271. package/references/minimem/src/cli/__tests__/commands.test.ts +759 -0
  272. package/references/minimem/src/cli/commands/__tests__/conflicts.test.ts +141 -0
  273. package/references/minimem/src/cli/commands/append.ts +76 -0
  274. package/references/minimem/src/cli/commands/config.ts +262 -0
  275. package/references/minimem/src/cli/commands/conflicts.ts +413 -0
  276. package/references/minimem/src/cli/commands/daemon.ts +169 -0
  277. package/references/minimem/src/cli/commands/index.ts +12 -0
  278. package/references/minimem/src/cli/commands/init.ts +88 -0
  279. package/references/minimem/src/cli/commands/mcp.ts +177 -0
  280. package/references/minimem/src/cli/commands/push-pull.ts +213 -0
  281. package/references/minimem/src/cli/commands/search.ts +158 -0
  282. package/references/minimem/src/cli/commands/status.ts +84 -0
  283. package/references/minimem/src/cli/commands/sync-init.ts +290 -0
  284. package/references/minimem/src/cli/commands/sync.ts +70 -0
  285. package/references/minimem/src/cli/commands/upsert.ts +197 -0
  286. package/references/minimem/src/cli/config.ts +584 -0
  287. package/references/minimem/src/cli/index.ts +264 -0
  288. package/references/minimem/src/cli/shared.ts +161 -0
  289. package/references/minimem/src/cli/sync/__tests__/central.test.ts +152 -0
  290. package/references/minimem/src/cli/sync/__tests__/conflicts.test.ts +209 -0
  291. package/references/minimem/src/cli/sync/__tests__/daemon.test.ts +118 -0
  292. package/references/minimem/src/cli/sync/__tests__/detection.test.ts +207 -0
  293. package/references/minimem/src/cli/sync/__tests__/integration.test.ts +476 -0
  294. package/references/minimem/src/cli/sync/__tests__/registry.test.ts +363 -0
  295. package/references/minimem/src/cli/sync/__tests__/state.test.ts +255 -0
  296. package/references/minimem/src/cli/sync/__tests__/validation.test.ts +193 -0
  297. package/references/minimem/src/cli/sync/__tests__/watcher.test.ts +178 -0
  298. package/references/minimem/src/cli/sync/central.ts +292 -0
  299. package/references/minimem/src/cli/sync/conflicts.ts +204 -0
  300. package/references/minimem/src/cli/sync/daemon.ts +407 -0
  301. package/references/minimem/src/cli/sync/detection.ts +138 -0
  302. package/references/minimem/src/cli/sync/index.ts +107 -0
  303. package/references/minimem/src/cli/sync/operations.ts +373 -0
  304. package/references/minimem/src/cli/sync/registry.ts +279 -0
  305. package/references/minimem/src/cli/sync/state.ts +355 -0
  306. package/references/minimem/src/cli/sync/validation.ts +206 -0
  307. package/references/minimem/src/cli/sync/watcher.ts +234 -0
  308. package/references/minimem/src/cli/version.ts +34 -0
  309. package/references/minimem/src/core/index.ts +9 -0
  310. package/references/minimem/src/core/indexer.ts +628 -0
  311. package/references/minimem/src/core/searcher.ts +221 -0
  312. package/references/minimem/src/db/schema.ts +183 -0
  313. package/references/minimem/src/db/sqlite-vec.ts +24 -0
  314. package/references/minimem/src/embeddings/__tests__/embeddings.test.ts +431 -0
  315. package/references/minimem/src/embeddings/batch-gemini.ts +392 -0
  316. package/references/minimem/src/embeddings/batch-openai.ts +409 -0
  317. package/references/minimem/src/embeddings/embeddings.ts +434 -0
  318. package/references/minimem/src/index.ts +109 -0
  319. package/references/minimem/src/internal.ts +299 -0
  320. package/references/minimem/src/minimem.ts +1276 -0
  321. package/references/minimem/src/search/__tests__/hybrid.test.ts +247 -0
  322. package/references/minimem/src/search/graph.ts +234 -0
  323. package/references/minimem/src/search/hybrid.ts +151 -0
  324. package/references/minimem/src/search/search.ts +256 -0
  325. package/references/minimem/src/server/__tests__/mcp.test.ts +341 -0
  326. package/references/minimem/src/server/__tests__/tools.test.ts +364 -0
  327. package/references/minimem/src/server/mcp.ts +326 -0
  328. package/references/minimem/src/server/tools.ts +720 -0
  329. package/references/minimem/src/session.ts +460 -0
  330. package/references/minimem/tsconfig.json +19 -0
  331. package/references/minimem/tsup.config.ts +26 -0
  332. package/references/minimem/vitest.config.ts +24 -0
  333. package/references/openteams/.claude/settings.json +6 -0
  334. package/references/openteams/README.md +1 -0
  335. package/references/openteams/SKILL.md +341 -0
  336. package/references/openteams/design.md +411 -0
  337. package/references/openteams/examples/bmad-method/prompts/analyst/ROLE.md +16 -0
  338. package/references/openteams/examples/bmad-method/prompts/analyst/SOUL.md +5 -0
  339. package/references/openteams/examples/bmad-method/prompts/architect/ROLE.md +24 -0
  340. package/references/openteams/examples/bmad-method/prompts/architect/SOUL.md +5 -0
  341. package/references/openteams/examples/bmad-method/prompts/developer/ROLE.md +25 -0
  342. package/references/openteams/examples/bmad-method/prompts/developer/SOUL.md +5 -0
  343. package/references/openteams/examples/bmad-method/prompts/master/ROLE.md +21 -0
  344. package/references/openteams/examples/bmad-method/prompts/master/SOUL.md +5 -0
  345. package/references/openteams/examples/bmad-method/prompts/pm/ROLE.md +20 -0
  346. package/references/openteams/examples/bmad-method/prompts/pm/SOUL.md +5 -0
  347. package/references/openteams/examples/bmad-method/prompts/qa/ROLE.md +17 -0
  348. package/references/openteams/examples/bmad-method/prompts/qa/SOUL.md +5 -0
  349. package/references/openteams/examples/bmad-method/prompts/quick-flow-dev/ROLE.md +23 -0
  350. package/references/openteams/examples/bmad-method/prompts/quick-flow-dev/SOUL.md +5 -0
  351. package/references/openteams/examples/bmad-method/prompts/scrum-master/ROLE.md +27 -0
  352. package/references/openteams/examples/bmad-method/prompts/scrum-master/SOUL.md +5 -0
  353. package/references/openteams/examples/bmad-method/prompts/tech-writer/ROLE.md +21 -0
  354. package/references/openteams/examples/bmad-method/prompts/tech-writer/SOUL.md +5 -0
  355. package/references/openteams/examples/bmad-method/prompts/ux-designer/ROLE.md +16 -0
  356. package/references/openteams/examples/bmad-method/prompts/ux-designer/SOUL.md +5 -0
  357. package/references/openteams/examples/bmad-method/roles/analyst.yaml +9 -0
  358. package/references/openteams/examples/bmad-method/roles/architect.yaml +9 -0
  359. package/references/openteams/examples/bmad-method/roles/developer.yaml +8 -0
  360. package/references/openteams/examples/bmad-method/roles/master.yaml +8 -0
  361. package/references/openteams/examples/bmad-method/roles/pm.yaml +9 -0
  362. package/references/openteams/examples/bmad-method/roles/qa.yaml +8 -0
  363. package/references/openteams/examples/bmad-method/roles/quick-flow-dev.yaml +8 -0
  364. package/references/openteams/examples/bmad-method/roles/scrum-master.yaml +9 -0
  365. package/references/openteams/examples/bmad-method/roles/tech-writer.yaml +8 -0
  366. package/references/openteams/examples/bmad-method/roles/ux-designer.yaml +8 -0
  367. package/references/openteams/examples/bmad-method/team.yaml +161 -0
  368. package/references/openteams/examples/get-shit-done/prompts/codebase-mapper/ROLE.md +17 -0
  369. package/references/openteams/examples/get-shit-done/prompts/codebase-mapper/SOUL.md +5 -0
  370. package/references/openteams/examples/get-shit-done/prompts/debugger/ROLE.md +25 -0
  371. package/references/openteams/examples/get-shit-done/prompts/debugger/SOUL.md +5 -0
  372. package/references/openteams/examples/get-shit-done/prompts/executor/ROLE.md +34 -0
  373. package/references/openteams/examples/get-shit-done/prompts/executor/SOUL.md +5 -0
  374. package/references/openteams/examples/get-shit-done/prompts/integration-checker/ROLE.md +18 -0
  375. package/references/openteams/examples/get-shit-done/prompts/integration-checker/SOUL.md +3 -0
  376. package/references/openteams/examples/get-shit-done/prompts/orchestrator/ROLE.md +42 -0
  377. package/references/openteams/examples/get-shit-done/prompts/orchestrator/SOUL.md +5 -0
  378. package/references/openteams/examples/get-shit-done/prompts/phase-researcher/ROLE.md +15 -0
  379. package/references/openteams/examples/get-shit-done/prompts/phase-researcher/SOUL.md +3 -0
  380. package/references/openteams/examples/get-shit-done/prompts/plan-checker/ROLE.md +17 -0
  381. package/references/openteams/examples/get-shit-done/prompts/plan-checker/SOUL.md +3 -0
  382. package/references/openteams/examples/get-shit-done/prompts/planner/ROLE.md +28 -0
  383. package/references/openteams/examples/get-shit-done/prompts/planner/SOUL.md +5 -0
  384. package/references/openteams/examples/get-shit-done/prompts/project-researcher/ROLE.md +16 -0
  385. package/references/openteams/examples/get-shit-done/prompts/project-researcher/SOUL.md +3 -0
  386. package/references/openteams/examples/get-shit-done/prompts/research-synthesizer/ROLE.md +13 -0
  387. package/references/openteams/examples/get-shit-done/prompts/research-synthesizer/SOUL.md +3 -0
  388. package/references/openteams/examples/get-shit-done/prompts/roadmapper/ROLE.md +14 -0
  389. package/references/openteams/examples/get-shit-done/prompts/roadmapper/SOUL.md +3 -0
  390. package/references/openteams/examples/get-shit-done/prompts/verifier/ROLE.md +19 -0
  391. package/references/openteams/examples/get-shit-done/prompts/verifier/SOUL.md +5 -0
  392. package/references/openteams/examples/get-shit-done/roles/codebase-mapper.yaml +8 -0
  393. package/references/openteams/examples/get-shit-done/roles/debugger.yaml +8 -0
  394. package/references/openteams/examples/get-shit-done/roles/executor.yaml +8 -0
  395. package/references/openteams/examples/get-shit-done/roles/integration-checker.yaml +8 -0
  396. package/references/openteams/examples/get-shit-done/roles/orchestrator.yaml +9 -0
  397. package/references/openteams/examples/get-shit-done/roles/phase-researcher.yaml +7 -0
  398. package/references/openteams/examples/get-shit-done/roles/plan-checker.yaml +8 -0
  399. package/references/openteams/examples/get-shit-done/roles/planner.yaml +8 -0
  400. package/references/openteams/examples/get-shit-done/roles/project-researcher.yaml +8 -0
  401. package/references/openteams/examples/get-shit-done/roles/research-synthesizer.yaml +7 -0
  402. package/references/openteams/examples/get-shit-done/roles/roadmapper.yaml +7 -0
  403. package/references/openteams/examples/get-shit-done/roles/verifier.yaml +8 -0
  404. package/references/openteams/examples/get-shit-done/team.yaml +154 -0
  405. package/references/openteams/package-lock.json +2181 -0
  406. package/references/openteams/package.json +48 -0
  407. package/references/openteams/schema/role.schema.json +125 -0
  408. package/references/openteams/schema/team.schema.json +284 -0
  409. package/references/openteams/src/cli/agent.ts +104 -0
  410. package/references/openteams/src/cli/cli.test.ts +381 -0
  411. package/references/openteams/src/cli/generate.ts +220 -0
  412. package/references/openteams/src/cli/message.ts +241 -0
  413. package/references/openteams/src/cli/task.ts +154 -0
  414. package/references/openteams/src/cli/team.ts +104 -0
  415. package/references/openteams/src/cli/template.ts +207 -0
  416. package/references/openteams/src/cli.ts +45 -0
  417. package/references/openteams/src/db/database.test.ts +185 -0
  418. package/references/openteams/src/db/database.ts +240 -0
  419. package/references/openteams/src/generators/agent-prompt-generator.test.ts +332 -0
  420. package/references/openteams/src/generators/agent-prompt-generator.ts +521 -0
  421. package/references/openteams/src/generators/package-generator.test.ts +129 -0
  422. package/references/openteams/src/generators/package-generator.ts +102 -0
  423. package/references/openteams/src/generators/skill-generator.test.ts +246 -0
  424. package/references/openteams/src/generators/skill-generator.ts +374 -0
  425. package/references/openteams/src/index.ts +104 -0
  426. package/references/openteams/src/services/agent-service.test.ts +158 -0
  427. package/references/openteams/src/services/agent-service.ts +84 -0
  428. package/references/openteams/src/services/communication-service.test.ts +455 -0
  429. package/references/openteams/src/services/communication-service.ts +371 -0
  430. package/references/openteams/src/services/message-service.test.ts +342 -0
  431. package/references/openteams/src/services/message-service.ts +203 -0
  432. package/references/openteams/src/services/task-service.test.ts +434 -0
  433. package/references/openteams/src/services/task-service.ts +239 -0
  434. package/references/openteams/src/services/team-service.test.ts +181 -0
  435. package/references/openteams/src/services/team-service.ts +139 -0
  436. package/references/openteams/src/services/template-service.test.ts +306 -0
  437. package/references/openteams/src/services/template-service.ts +182 -0
  438. package/references/openteams/src/spawner/acp-factory.ts +96 -0
  439. package/references/openteams/src/spawner/interface.ts +31 -0
  440. package/references/openteams/src/spawner/mock.test.ts +93 -0
  441. package/references/openteams/src/spawner/mock.ts +59 -0
  442. package/references/openteams/src/template/loader.test.ts +1319 -0
  443. package/references/openteams/src/template/loader.ts +698 -0
  444. package/references/openteams/src/template/types.ts +200 -0
  445. package/references/openteams/src/types.ts +205 -0
  446. package/references/openteams/tsconfig.json +18 -0
  447. package/references/openteams/vitest.config.ts +9 -0
  448. package/references/skill-tree/.claude/settings.json +6 -0
  449. package/references/skill-tree/.sudocode/issues.jsonl +11 -0
  450. package/references/skill-tree/.sudocode/specs.jsonl +1 -0
  451. package/references/skill-tree/CLAUDE.md +150 -0
  452. package/references/skill-tree/README.md +324 -0
  453. package/references/skill-tree/docs/GAPS_v1.md +221 -0
  454. package/references/skill-tree/docs/INTEGRATION_PLAN.md +467 -0
  455. package/references/skill-tree/docs/TODOS.md +91 -0
  456. package/references/skill-tree/docs/anthropic_skill_guide.md +1364 -0
  457. package/references/skill-tree/docs/design/federated-skill-trees.md +524 -0
  458. package/references/skill-tree/docs/design/multi-agent-sync.md +759 -0
  459. package/references/skill-tree/docs/scraper/BRAINSTORM.md +583 -0
  460. package/references/skill-tree/docs/scraper/POC_PLAN.md +420 -0
  461. package/references/skill-tree/docs/scraper/README.md +170 -0
  462. package/references/skill-tree/examples/basic-usage.ts +190 -0
  463. package/references/skill-tree/package-lock.json +1509 -0
  464. package/references/skill-tree/package.json +66 -0
  465. package/references/skill-tree/scraper/README.md +123 -0
  466. package/references/skill-tree/scraper/docs/DESIGN.md +683 -0
  467. package/references/skill-tree/scraper/docs/PLAN.md +336 -0
  468. package/references/skill-tree/scraper/drizzle.config.ts +10 -0
  469. package/references/skill-tree/scraper/package-lock.json +6329 -0
  470. package/references/skill-tree/scraper/package.json +68 -0
  471. package/references/skill-tree/scraper/test/fixtures/invalid-skill/missing-description.md +7 -0
  472. package/references/skill-tree/scraper/test/fixtures/invalid-skill/missing-name.md +7 -0
  473. package/references/skill-tree/scraper/test/fixtures/minimal-skill/SKILL.md +27 -0
  474. package/references/skill-tree/scraper/test/fixtures/skill-json/SKILL.json +21 -0
  475. package/references/skill-tree/scraper/test/fixtures/skill-with-meta/SKILL.md +54 -0
  476. package/references/skill-tree/scraper/test/fixtures/skill-with-meta/_meta.json +24 -0
  477. package/references/skill-tree/scraper/test/fixtures/valid-skill/SKILL.md +93 -0
  478. package/references/skill-tree/scraper/test/fixtures/valid-skill/_meta.json +22 -0
  479. package/references/skill-tree/scraper/tsup.config.ts +14 -0
  480. package/references/skill-tree/scraper/vitest.config.ts +17 -0
  481. package/references/skill-tree/scripts/convert-to-vitest.ts +166 -0
  482. package/references/skill-tree/skills/skill-writer/SKILL.md +339 -0
  483. package/references/skill-tree/skills/skill-writer/references/examples.md +326 -0
  484. package/references/skill-tree/skills/skill-writer/references/patterns.md +210 -0
  485. package/references/skill-tree/skills/skill-writer/references/quality-checklist.md +123 -0
  486. package/references/skill-tree/test/run-all.ts +106 -0
  487. package/references/skill-tree/test/utils.ts +128 -0
  488. package/references/skill-tree/vitest.config.ts +16 -0
  489. package/src/__tests__/e2e/agent-spawn-visibility.e2e.test.ts +761 -0
  490. package/src/__tests__/e2e/full-agent-conflict-resolution.e2e.test.ts +2 -2
  491. package/src/__tests__/e2e/mcp-thin-client-bridge.e2e.test.ts +304 -0
  492. package/src/__tests__/e2e/mcp-tools-available.e2e.test.ts +324 -0
  493. package/src/__tests__/e2e/multi-agent.e2e.test.ts +5 -5
  494. package/src/__tests__/e2e/spawn-session-streaming.e2e.test.ts +563 -0
  495. package/src/acp/__tests__/integration.test.ts +56 -31
  496. package/src/acp/__tests__/macro-agent.test.ts +16 -7
  497. package/src/acp/macro-agent.ts +170 -36
  498. package/src/acp/types.ts +46 -1
  499. package/src/agent/__tests__/agent-manager.test.ts +228 -2
  500. package/src/agent/agent-manager.ts +809 -285
  501. package/src/agent/types.ts +12 -1
  502. package/src/api/__tests__/server.test.ts +203 -4
  503. package/src/api/server.ts +169 -10
  504. package/src/api/types.ts +3 -1
  505. package/src/auth/__tests__/token.test.ts +100 -0
  506. package/src/auth/index.ts +1 -0
  507. package/src/auth/token.ts +82 -0
  508. package/src/cli/__tests__/acp.test.ts +1 -1
  509. package/src/cli/__tests__/stable-instance-id.test.ts +1 -1
  510. package/src/cli/acp.ts +197 -72
  511. package/src/cli/index.ts +125 -15
  512. package/src/cli/mcp.ts +315 -197
  513. package/src/cli/parse-args.ts +54 -0
  514. package/src/cli/stable-instance-id.ts +14 -0
  515. package/src/config/project-config.ts +214 -27
  516. package/src/index.ts +3 -0
  517. package/src/lifecycle/__tests__/cascade-termination.test.ts +1 -1
  518. package/src/lifecycle/__tests__/handlers.test.ts +53 -0
  519. package/src/lifecycle/handlers/index.ts +25 -8
  520. package/src/lifecycle/types.ts +3 -0
  521. package/src/map/adapter/__tests__/acp-over-map-cancel.test.ts +22 -4
  522. package/src/map/adapter/__tests__/acp-over-map-getmodels.test.ts +355 -0
  523. package/src/map/adapter/__tests__/acp-over-map-history.test.ts +263 -0
  524. package/src/map/adapter/__tests__/acp-over-map-persistence.e2e.test.ts +1 -1
  525. package/src/map/adapter/__tests__/event-broadcast.test.ts +420 -0
  526. package/src/map/adapter/__tests__/event-log.test.ts +527 -0
  527. package/src/map/adapter/__tests__/event-translator.test.ts +3 -3
  528. package/src/map/adapter/__tests__/extensions.test.ts +408 -0
  529. package/src/map/adapter/__tests__/map-adapter.test.ts +99 -0
  530. package/src/map/adapter/__tests__/mcp-bridge.test.ts +1187 -0
  531. package/src/map/adapter/__tests__/multi-client-broadcast.test.ts +711 -0
  532. package/src/map/adapter/__tests__/stream-extensions.test.ts +494 -0
  533. package/src/map/adapter/__tests__/websocket-integration.test.ts +218 -0
  534. package/src/map/adapter/acp-over-map.ts +678 -66
  535. package/src/map/adapter/connection-manager.ts +3 -0
  536. package/src/map/adapter/event-log.ts +208 -0
  537. package/src/map/adapter/event-translator.ts +6 -6
  538. package/src/map/adapter/extensions/agent-lifecycle.ts +267 -0
  539. package/src/map/adapter/extensions/index.ts +96 -0
  540. package/src/map/adapter/extensions/mcp-bridge.ts +995 -0
  541. package/src/map/adapter/extensions/streams.ts +839 -0
  542. package/src/map/adapter/extensions/task.ts +11 -0
  543. package/src/map/adapter/extensions/update-metadata.ts +126 -0
  544. package/src/map/adapter/index.ts +33 -0
  545. package/src/map/adapter/interface.ts +2 -0
  546. package/src/map/adapter/map-adapter.ts +312 -47
  547. package/src/map/adapter/subscription-manager.ts +5 -1
  548. package/src/map/adapter/types.ts +10 -1
  549. package/src/mcp/__tests__/map-client.test.ts +386 -0
  550. package/src/mcp/__tests__/mcp-server-thin-client.test.ts +368 -0
  551. package/src/mcp/__tests__/mcp-server.test.ts +100 -1
  552. package/src/mcp/map-client.ts +177 -0
  553. package/src/mcp/mcp-server.ts +205 -103
  554. package/src/mcp/tools/done.ts +19 -0
  555. package/src/mcp/types.ts +6 -1
  556. package/src/metrics/metrics.ts +1 -1
  557. package/src/monitor/__tests__/stale-agent-flow.integration.test.ts +1 -1
  558. package/src/roles/__tests__/config-loader.test.ts +7 -7
  559. package/src/roles/builtin/coordinator.ts +2 -0
  560. package/src/roles/builtin/integrator.ts +2 -0
  561. package/src/roles/builtin/worker.ts +3 -0
  562. package/src/roles/capabilities.ts +28 -7
  563. package/src/roles/config-loader.ts +8 -7
  564. package/src/roles/registry.ts +2 -2
  565. package/src/roles/types.ts +7 -0
  566. package/src/server/__tests__/combined-server.test.ts +94 -21
  567. package/src/server/combined-server.ts +203 -33
  568. package/src/steering/__tests__/steering-integration.test.ts +1 -1
  569. package/src/store/__tests__/event-store-oob.test.ts +109 -0
  570. package/src/store/__tests__/event-store.test.ts +196 -1
  571. package/src/store/__tests__/instance.test.ts +3 -3
  572. package/src/store/event-store.ts +92 -23
  573. package/src/store/instance.ts +2 -2
  574. package/src/store/types/agents.ts +20 -0
  575. package/src/store/types/events.ts +1 -1
  576. package/src/task/backend/__tests__/create-task-backend.test.ts +225 -0
  577. package/src/task/backend/__tests__/e2e/unified-tool-provider-opentasks.e2e.test.ts +524 -0
  578. package/src/task/backend/__tests__/memory-pull-mode.test.ts +153 -0
  579. package/src/task/backend/__tests__/unified-tool-provider.test.ts +579 -0
  580. package/src/task/backend/index.ts +156 -106
  581. package/src/task/backend/memory.ts +4 -0
  582. package/src/task/backend/opentasks/__tests__/backend.test.ts +968 -0
  583. package/src/task/backend/opentasks/__tests__/daemon-manager.test.ts +406 -0
  584. package/src/task/backend/opentasks/__tests__/mapping.test.ts +84 -0
  585. package/src/task/backend/opentasks/__tests__/opentasks-backend.e2e.test.ts +1338 -0
  586. package/src/task/backend/opentasks/backend.ts +1323 -0
  587. package/src/task/backend/opentasks/client.ts +652 -0
  588. package/src/task/backend/opentasks/daemon-manager.ts +256 -0
  589. package/src/task/backend/opentasks/index.ts +69 -0
  590. package/src/task/backend/opentasks/mapping.ts +94 -0
  591. package/src/task/backend/types.ts +42 -66
  592. package/src/task/backend/unified-tool-provider.ts +779 -0
  593. package/src/teams/CLAUDE.md +180 -0
  594. package/src/teams/__tests__/cross-subsystem.integration.test.ts +1 -1
  595. package/src/teams/__tests__/e2e/workspace-isolation.e2e.test.ts +1263 -0
  596. package/src/teams/__tests__/team-manager.test.ts +814 -0
  597. package/src/teams/__tests__/team-system.test.ts +1291 -8
  598. package/src/teams/index.ts +21 -3
  599. package/src/teams/seed-defaults.ts +79 -0
  600. package/src/teams/team-loader.ts +202 -236
  601. package/src/teams/team-manager.ts +387 -0
  602. package/src/teams/team-runtime.ts +592 -121
  603. package/src/teams/types.ts +99 -200
  604. package/test_fixtures/README.md +2 -3
  605. package/test_fixtures/fixtures/index.ts +0 -3
  606. package/test_fixtures/fixtures/projects/project-with-specs.ts +7 -149
  607. package/test_fixtures/fixtures/repos/index.ts +1 -3
  608. package/test_fixtures/fixtures/repos/temp-repo-factory.ts +0 -116
  609. package/test_fixtures/fixtures/repos/types.ts +0 -11
  610. package/test_fixtures/harness/__tests__/fixtures.test.ts +10 -102
  611. package/test_fixtures/harness/__tests__/temp-repo-and-simulator.test.ts +0 -33
  612. package/test_fixtures/harness/simulator/agent-simulator.ts +4 -4
  613. package/vitest.config.ts +1 -1
  614. package/vitest.e2e.config.ts +1 -1
  615. package/vitest.setup.ts +1 -30
  616. package/.macro-agent/teams/self-driving/prompts/grinder.md +0 -27
  617. package/.macro-agent/teams/self-driving/prompts/judge.md +0 -27
  618. package/.macro-agent/teams/self-driving/prompts/planner.md +0 -33
  619. package/.macro-agent/teams/self-driving/roles/grinder.yaml +0 -17
  620. package/.macro-agent/teams/self-driving/roles/judge.yaml +0 -24
  621. package/.macro-agent/teams/self-driving/roles/planner.yaml +0 -18
  622. package/.macro-agent/teams/self-driving/team.yaml +0 -103
  623. package/.macro-agent/teams/structured/prompts/developer.md +0 -26
  624. package/.macro-agent/teams/structured/prompts/lead.md +0 -25
  625. package/.macro-agent/teams/structured/prompts/reviewer.md +0 -24
  626. package/.macro-agent/teams/structured/roles/developer.yaml +0 -12
  627. package/.macro-agent/teams/structured/roles/lead.yaml +0 -11
  628. package/.macro-agent/teams/structured/roles/reviewer.yaml +0 -19
  629. package/.macro-agent/teams/structured/team.yaml +0 -89
  630. package/docs/sudocode-integration.md +0 -383
  631. package/src/task/backend/__tests__/backend-parity.test.ts +0 -451
  632. package/src/task/backend/__tests__/tool-provider-edge-cases.test.ts +0 -430
  633. package/src/task/backend/__tests__/tool-provider.test.ts +0 -983
  634. package/src/task/backend/sudocode/__tests__/backend-edge-cases.test.ts +0 -575
  635. package/src/task/backend/sudocode/__tests__/backend.test.ts +0 -1194
  636. package/src/task/backend/sudocode/__tests__/client-integration.test.ts +0 -418
  637. package/src/task/backend/sudocode/__tests__/client.test.ts +0 -345
  638. package/src/task/backend/sudocode/__tests__/e2e/backend.e2e.test.ts +0 -753
  639. package/src/task/backend/sudocode/__tests__/e2e/server-client.e2e.test.ts +0 -680
  640. package/src/task/backend/sudocode/__tests__/e2e-workflow.test.ts +0 -666
  641. package/src/task/backend/sudocode/__tests__/integration/standalone-client.integration.test.ts +0 -396
  642. package/src/task/backend/sudocode/__tests__/integration/sudocode-cli.integration.test.ts +0 -328
  643. package/src/task/backend/sudocode/__tests__/integration/test-utils.ts +0 -175
  644. package/src/task/backend/sudocode/__tests__/mapping-edge-cases.test.ts +0 -265
  645. package/src/task/backend/sudocode/__tests__/server-client.test.ts +0 -675
  646. package/src/task/backend/sudocode/__tests__/sync-policy-edge-cases.test.ts +0 -521
  647. package/src/task/backend/sudocode/__tests__/sync-policy.test.ts +0 -519
  648. package/src/task/backend/sudocode/__tests__/tools.test.ts +0 -471
  649. package/src/task/backend/sudocode/backend.ts +0 -1237
  650. package/src/task/backend/sudocode/client.ts +0 -515
  651. package/src/task/backend/sudocode/index.ts +0 -120
  652. package/src/task/backend/sudocode/mapping.ts +0 -93
  653. package/src/task/backend/sudocode/server-client.ts +0 -522
  654. package/src/task/backend/sudocode/standalone-client.ts +0 -623
  655. package/src/task/backend/sudocode/sync-policy.ts +0 -387
  656. package/src/task/backend/sudocode/tools.ts +0 -896
  657. package/src/task/backend/tool-provider.ts +0 -506
  658. package/test_fixtures/fixtures/sudocode/index.ts +0 -29
  659. package/test_fixtures/fixtures/sudocode/issues.ts +0 -185
  660. package/test_fixtures/fixtures/sudocode/specs.ts +0 -159
@@ -161,6 +161,28 @@ function createMockAgentManager(): AgentManager {
161
161
  getSession: vi.fn().mockReturnValue(null),
162
162
  onLifecycleEvent: vi.fn().mockReturnValue(() => {}),
163
163
  close: vi.fn().mockResolvedValue(undefined),
164
+ forkAgent: vi.fn().mockImplementation((sourceId) => {
165
+ const agentId = `agent-${++agentCounter}`;
166
+ const sessionId = `session-${++sessionCounter}`;
167
+ const agent: Agent = {
168
+ id: agentId,
169
+ session_id: sessionId,
170
+ state: "running",
171
+ task: `[Fork of ${sourceId}]`,
172
+ task_id: `task-${++taskCounter}`,
173
+ parent: null,
174
+ lineage: [],
175
+ created_at: Date.now(),
176
+ started_at: Date.now(),
177
+ };
178
+ agentStore.set(agent.id, agent);
179
+ return Promise.resolve({
180
+ id: agent.id,
181
+ session_id: agent.session_id,
182
+ agent,
183
+ session: { id: `provider-${sessionId}` },
184
+ });
185
+ }),
164
186
  } as unknown as AgentManager;
165
187
  }
166
188
 
@@ -238,7 +260,7 @@ describe("ACP Mode Integration", () => {
238
260
  expect(initResponse.agentCapabilities).toBeDefined();
239
261
  expect(initResponse.agentCapabilities?.loadSession).toBe(true);
240
262
  expect(initResponse.agentCapabilities?._meta?.extensions).toContain(
241
- "_macro/spawnAgent"
263
+ "_macro/spawnAgent",
242
264
  );
243
265
 
244
266
  // Step 2: Create new session
@@ -286,8 +308,8 @@ describe("ACP Mode Integration", () => {
286
308
  cwd: "/test/project",
287
309
  });
288
310
 
289
- // loadSession returns empty object on success
290
- expect(loadResponse).toEqual({});
311
+ // loadSession returns model state (null when no models available)
312
+ expect(loadResponse).toEqual({ models: null });
291
313
  });
292
314
 
293
315
  it("should load session by agentId via _meta", async () => {
@@ -314,7 +336,7 @@ describe("ACP Mode Integration", () => {
314
336
  _meta: { agentId: originalAgentId },
315
337
  } as any);
316
338
 
317
- expect(loadResponse).toEqual({});
339
+ expect(loadResponse).toEqual({ models: null });
318
340
  });
319
341
 
320
342
  it("should throw when _meta.agentId references non-existent agent", async () => {
@@ -323,7 +345,7 @@ describe("ACP Mode Integration", () => {
323
345
  sessionId: "_resume_",
324
346
  cwd: "/test/project",
325
347
  _meta: { agentId: "non-existent-agent" },
326
- } as any)
348
+ } as any),
327
349
  ).rejects.toThrow("Agent not found: non-existent-agent");
328
350
  });
329
351
 
@@ -345,7 +367,7 @@ describe("ACP Mode Integration", () => {
345
367
  await expect(
346
368
  macroAgent.cancel({
347
369
  sessionId: sessionResponse.sessionId,
348
- })
370
+ }),
349
371
  ).resolves.toBeUndefined();
350
372
  });
351
373
 
@@ -373,10 +395,11 @@ describe("ACP Mode Integration", () => {
373
395
  expect(extensions).toContain("_macro/cancelPermission");
374
396
  expect(extensions).toContain("_macro/resume");
375
397
  expect(extensions).toContain("_macro/getHistory");
376
- expect(extensions?.length).toBe(17);
398
+ expect(extensions).toContain("_macro/forkAgent");
399
+ expect(extensions?.length).toBe(19);
377
400
 
378
401
  expect(initResponse.agentCapabilities?._meta?.agentType).toBe(
379
- "macro-agent"
402
+ "macro-agent",
380
403
  );
381
404
  });
382
405
  });
@@ -474,7 +497,7 @@ describe("ACP Mode Integration", () => {
474
497
  expect.objectContaining({
475
498
  task: "Integration test task",
476
499
  cwd: "/test/spawn",
477
- })
500
+ }),
478
501
  );
479
502
  });
480
503
 
@@ -497,7 +520,7 @@ describe("ACP Mode Integration", () => {
497
520
  expect.objectContaining({
498
521
  task: "Child agent task",
499
522
  parent: parentId,
500
- })
523
+ }),
501
524
  );
502
525
  });
503
526
  });
@@ -545,7 +568,7 @@ describe("ACP Mode Integration", () => {
545
568
  await expect(
546
569
  macroAgent.extMethod("macro/getHierarchy", {
547
570
  rootAgentId: "non-existent-agent",
548
- })
571
+ }),
549
572
  ).rejects.toThrow(ACPError);
550
573
  });
551
574
  });
@@ -576,7 +599,7 @@ describe("ACP Mode Integration", () => {
576
599
  await expect(
577
600
  macroAgent.extMethod("macro/getTask", {
578
601
  taskId: "non-existent-task",
579
- })
602
+ }),
580
603
  ).rejects.toThrow(ACPError);
581
604
  });
582
605
  });
@@ -640,7 +663,7 @@ describe("ACP Mode Integration", () => {
640
663
  macroAgent.extMethod("macro/mountAgent", {
641
664
  sessionId: "non-existent-session",
642
665
  agentId: "some-agent",
643
- })
666
+ }),
644
667
  ).rejects.toThrow(ACPError);
645
668
  });
646
669
 
@@ -653,7 +676,7 @@ describe("ACP Mode Integration", () => {
653
676
  macroAgent.extMethod("macro/mountAgent", {
654
677
  sessionId: sessionResponse.sessionId,
655
678
  agentId: "non-existent-agent",
656
- })
679
+ }),
657
680
  ).rejects.toThrow(ACPError);
658
681
  });
659
682
  });
@@ -666,7 +689,7 @@ describe("ACP Mode Integration", () => {
666
689
  });
667
690
 
668
691
  const originalAgentId = macroAgent.getMappedAgentId(
669
- sessionResponse.sessionId
692
+ sessionResponse.sessionId,
670
693
  );
671
694
 
672
695
  // Fork the agent
@@ -678,18 +701,20 @@ describe("ACP Mode Integration", () => {
678
701
  expect(forkResponse.newAgentId).toBeDefined();
679
702
  expect(forkResponse.newSessionId).toBeDefined();
680
703
  expect(forkResponse.originalAgentId).toBe(originalAgentId);
704
+ expect(forkResponse.providerSessionId).toBeDefined();
681
705
 
682
- // Verify forked agent exists
683
- const forkedAgent = agentStore.get(forkResponse.newAgentId as string);
684
- expect(forkedAgent).not.toBeNull();
685
- expect(forkedAgent?.task).toContain("Forked for testing");
706
+ // Verify forkAgent was called with correct args
707
+ expect(mockAgentManager.forkAgent).toHaveBeenCalledWith(
708
+ originalAgentId,
709
+ expect.objectContaining({ name: "Forked for testing" }),
710
+ );
686
711
  });
687
712
 
688
713
  it("should throw for non-existent agent", async () => {
689
714
  await expect(
690
715
  macroAgent.extMethod("macro/forkAgent", {
691
716
  agentId: "non-existent-agent",
692
- })
717
+ }),
693
718
  ).rejects.toThrow(ACPError);
694
719
  });
695
720
  });
@@ -697,7 +722,7 @@ describe("ACP Mode Integration", () => {
697
722
  describe("Extension Error Handling", () => {
698
723
  it("should throw for unknown extension method", async () => {
699
724
  await expect(macroAgent.extMethod("unknown/method", {})).rejects.toThrow(
700
- ACPError
725
+ ACPError,
701
726
  );
702
727
 
703
728
  try {
@@ -736,7 +761,7 @@ describe("ACP Mode Integration", () => {
736
761
 
737
762
  // Verify session2 is now controlling the child agent
738
763
  expect(macroAgent.getMappedAgentId(session2.sessionId)).toBe(
739
- childSpawn.agentId
764
+ childSpawn.agentId,
740
765
  );
741
766
 
742
767
  // 5. Fork the child from session2's perspective
@@ -763,7 +788,7 @@ describe("ACP Mode Integration", () => {
763
788
 
764
789
  // Get session2's original agent
765
790
  const session2AgentBefore = macroAgent.getMappedAgentId(
766
- session2.sessionId
791
+ session2.sessionId,
767
792
  );
768
793
 
769
794
  // Mount session1 to new agent
@@ -774,10 +799,10 @@ describe("ACP Mode Integration", () => {
774
799
 
775
800
  // Session2 should still point to its original head manager
776
801
  expect(macroAgent.getMappedAgentId(session1.sessionId)).toBe(
777
- spawn1.agentId
802
+ spawn1.agentId,
778
803
  );
779
804
  expect(macroAgent.getMappedAgentId(session2.sessionId)).toBe(
780
- session2AgentBefore
805
+ session2AgentBefore,
781
806
  );
782
807
  });
783
808
  });
@@ -883,7 +908,7 @@ describe("ACP Protocol Compliance", () => {
883
908
  headManagers.length = 0;
884
909
  const hierarchyResponse = await macroAgent.extMethod(
885
910
  "macro/getHierarchy",
886
- {}
911
+ {},
887
912
  );
888
913
  expect(hierarchyResponse).toBeDefined();
889
914
  expect(hierarchyResponse.totalAgents).toBe(0);
@@ -967,7 +992,7 @@ describe("ACP Protocol Compliance", () => {
967
992
  await expect(
968
993
  macroAgent.extMethod("_macro/resume", {
969
994
  agentId: childAgentId,
970
- })
995
+ }),
971
996
  ).rejects.toThrow("only stopped or failed");
972
997
  });
973
998
 
@@ -975,14 +1000,14 @@ describe("ACP Protocol Compliance", () => {
975
1000
  await expect(
976
1001
  macroAgent.extMethod("_macro/resume", {
977
1002
  agentId: "non-existent-agent",
978
- })
1003
+ }),
979
1004
  ).rejects.toThrow("Agent not found");
980
1005
  });
981
1006
 
982
1007
  it("should reject resume without agentId", async () => {
983
- await expect(
984
- macroAgent.extMethod("_macro/resume", {})
985
- ).rejects.toThrow("agentId is required");
1008
+ await expect(macroAgent.extMethod("_macro/resume", {})).rejects.toThrow(
1009
+ "agentId is required",
1010
+ );
986
1011
  });
987
1012
 
988
1013
  it("full lifecycle: spawn → stop → resume", async () => {
@@ -98,6 +98,12 @@ function createMockAgentManager(): AgentManager {
98
98
  close: vi.fn().mockResolvedValue(undefined),
99
99
  respondToPermission: vi.fn().mockReturnValue(true),
100
100
  cancelPermission: vi.fn().mockReturnValue(true),
101
+ forkAgent: vi.fn().mockResolvedValue({
102
+ id: "agent-forked",
103
+ session_id: "session-forked",
104
+ agent: createMockAgent({ id: "agent-forked", session_id: "session-forked" }),
105
+ session: { id: "provider-session-forked" },
106
+ }),
101
107
  } as unknown as AgentManager;
102
108
  }
103
109
 
@@ -612,21 +618,23 @@ describe("MacroAgent", () => {
612
618
  agentId: "agent-1",
613
619
  });
614
620
 
615
- expect(response).toHaveProperty("newAgentId");
616
- expect(response).toHaveProperty("newSessionId");
621
+ expect(response).toHaveProperty("newAgentId", "agent-forked");
622
+ expect(response).toHaveProperty("newSessionId", "session-forked");
617
623
  expect(response).toHaveProperty("originalAgentId", "agent-1");
618
- expect(mockAgentManager.spawn).toHaveBeenCalled();
624
+ expect(response).toHaveProperty("providerSessionId", "provider-session-forked");
625
+ expect(mockAgentManager.forkAgent).toHaveBeenCalledWith("agent-1", expect.any(Object));
619
626
  });
620
627
 
621
- it("should use custom name in task description", async () => {
628
+ it("should pass custom name to forkAgent", async () => {
622
629
  await macroAgent.extMethod("macro/forkAgent", {
623
630
  agentId: "agent-1",
624
631
  name: "Custom fork name",
625
632
  });
626
633
 
627
- expect(mockAgentManager.spawn).toHaveBeenCalledWith(
634
+ expect(mockAgentManager.forkAgent).toHaveBeenCalledWith(
635
+ "agent-1",
628
636
  expect.objectContaining({
629
- task: expect.stringContaining("Custom fork name"),
637
+ name: "Custom fork name",
630
638
  })
631
639
  );
632
640
  });
@@ -641,8 +649,9 @@ describe("MacroAgent", () => {
641
649
  ).rejects.toThrow(ACPError);
642
650
  });
643
651
 
644
- it("should throw if agent has no active session", async () => {
652
+ it("should throw if agent has no active session and no provider_session_id", async () => {
645
653
  vi.mocked(mockAgentManager.hasActiveSession).mockReturnValue(false);
654
+ // Default mock agent has no provider_session_id
646
655
 
647
656
  await expect(
648
657
  macroAgent.extMethod("macro/forkAgent", {
@@ -20,6 +20,7 @@ import type {
20
20
  PromptResponse,
21
21
  CancelNotification,
22
22
  SessionNotification,
23
+ SessionModelState,
23
24
  } from "@agentclientprotocol/sdk";
24
25
  import type { AgentManager } from "../agent/agent-manager.js";
25
26
  import type { EventStore } from "../store/event-store.js";
@@ -61,6 +62,8 @@ import type {
61
62
  RespondToPermissionResponse,
62
63
  CancelPermissionRequest,
63
64
  CancelPermissionResponse,
65
+ SetPermissionModeRequest,
66
+ SetPermissionModeResponse,
64
67
  ResumeAgentRequest,
65
68
  ResumeAgentResponse,
66
69
  GetHistoryRequest,
@@ -113,8 +116,10 @@ const SUPPORTED_EXTENSIONS: ACPExtensionMethod[] = [
113
116
  "_macro/checkCapability",
114
117
  "_macro/respondToPermission",
115
118
  "_macro/cancelPermission",
119
+ "_macro/setPermissionMode",
116
120
  "_macro/resume",
117
121
  "_macro/getHistory",
122
+ "_macro/getModels",
118
123
  ];
119
124
 
120
125
  // ─────────────────────────────────────────────────────────────────
@@ -144,6 +149,22 @@ export interface MacroAgentConfig {
144
149
  defaultCwd?: string;
145
150
  }
146
151
 
152
+ // ─────────────────────────────────────────────────────────────────
153
+ // Helpers
154
+ // ─────────────────────────────────────────────────────────────────
155
+
156
+ /**
157
+ * Build a SessionModelState from the acp-factory Session.models (string[]).
158
+ * Returns null if the models array is empty or missing.
159
+ */
160
+ function buildModelState(models: string[]): SessionModelState | null {
161
+ if (!models || models.length === 0) return null;
162
+ return {
163
+ currentModelId: models[0],
164
+ availableModels: models.map((id) => ({ modelId: id, name: id })),
165
+ };
166
+ }
167
+
147
168
  // ─────────────────────────────────────────────────────────────────
148
169
  // MacroAgent Implementation
149
170
  // ─────────────────────────────────────────────────────────────────
@@ -271,6 +292,7 @@ export class MacroAgent implements Agent {
271
292
 
272
293
  return {
273
294
  sessionId: acpSessionId,
295
+ models: buildModelState(spawned.session.models),
274
296
  };
275
297
  }
276
298
 
@@ -281,6 +303,7 @@ export class MacroAgent implements Agent {
281
303
  let acpSessionId = params.sessionId;
282
304
  const cwd = params.cwd ?? this.defaultCwd;
283
305
 
306
+ // DEBUG: Log loadSession params
284
307
  // Extension: If _meta.agentId provided, look up session from agent record
285
308
  // This allows resuming a stopped head manager by MAP agent ID
286
309
  // when the TUI doesn't know the ACP session ID
@@ -314,14 +337,18 @@ export class MacroAgent implements Agent {
314
337
  }
315
338
  this.ensureConversation(acpSessionId, existing.id);
316
339
  await this.emitSessionInfo(acpSessionId);
317
- return {};
340
+ const activeSession = this.agentManager.getSession(existing.id);
341
+ return {
342
+ models: activeSession ? buildModelState(activeSession.models) : null,
343
+ };
318
344
  }
319
345
 
320
346
  // Agent exists but no active session - resume it
321
347
  console.log(
322
348
  `[MacroAgent] loadSession: Resuming stopped agent ${existing.id}`,
323
349
  );
324
- const spawned = await this.agentManager.resume(existing.id);
350
+ const defaultConfig = this.initConfig.defaultSubAgentConfig;
351
+ const spawned = await this.agentManager.resume(existing.id, defaultConfig?.permissionMode);
325
352
 
326
353
  // Create session mapping
327
354
  this.sessionMapper.createMapping(acpSessionId, spawned.id);
@@ -329,16 +356,20 @@ export class MacroAgent implements Agent {
329
356
  this.ensureConversation(acpSessionId, spawned.id);
330
357
  await this.emitSessionInfo(acpSessionId);
331
358
 
332
- return {};
359
+ return {
360
+ models: buildModelState(spawned.session.models),
361
+ };
333
362
  }
334
363
 
335
364
  // No existing agent found - try to get or create with the specific session ID
336
365
  console.log(
337
366
  `[MacroAgent] loadSession: No existing agent for session ${acpSessionId}, creating new`,
338
367
  );
368
+ const defaultConfig = this.initConfig.defaultSubAgentConfig;
339
369
  const spawned = await this.agentManager.getOrCreateHeadManager({
340
370
  cwd,
341
371
  sessionId: acpSessionId,
372
+ permissionMode: defaultConfig?.permissionMode,
342
373
  });
343
374
 
344
375
  // Create session mapping
@@ -347,7 +378,9 @@ export class MacroAgent implements Agent {
347
378
  this.ensureConversation(acpSessionId, spawned.id);
348
379
  await this.emitSessionInfo(acpSessionId);
349
380
 
350
- return {};
381
+ return {
382
+ models: buildModelState(spawned.session.models),
383
+ };
351
384
  }
352
385
 
353
386
  /**
@@ -564,6 +597,11 @@ export class MacroAgent implements Agent {
564
597
  params as unknown as CancelPermissionRequest,
565
598
  ) as unknown as Record<string, unknown>;
566
599
 
600
+ case "_macro/setPermissionMode":
601
+ return this.handleSetPermissionMode(
602
+ params as unknown as SetPermissionModeRequest,
603
+ ) as unknown as Record<string, unknown>;
604
+
567
605
  case "_macro/resume":
568
606
  return this.handleResumeAgent(
569
607
  params as unknown as ResumeAgentRequest,
@@ -574,6 +612,11 @@ export class MacroAgent implements Agent {
574
612
  params as unknown as GetHistoryRequest,
575
613
  ) as unknown as Record<string, unknown>;
576
614
 
615
+ case "_macro/getModels":
616
+ return this.handleGetModels(
617
+ params as { sessionId: string },
618
+ ) as unknown as Record<string, unknown>;
619
+
577
620
  default:
578
621
  throw new ACPError(
579
622
  `Unknown extension method: ${method}`,
@@ -792,9 +835,9 @@ export class MacroAgent implements Agent {
792
835
  private async handleForkAgent(
793
836
  params: ForkAgentRequest,
794
837
  ): Promise<ForkAgentResponse> {
795
- const { agentId, name } = params;
838
+ const { agentId, name, prompt, cwd } = params;
796
839
 
797
- // Get the original agent
840
+ // Validate source agent exists
798
841
  const originalAgent = this.agentManager.get(agentId);
799
842
  if (!originalAgent) {
800
843
  throw new ACPError(`Agent not found: ${agentId}`, "AGENT_NOT_FOUND", {
@@ -802,41 +845,48 @@ export class MacroAgent implements Agent {
802
845
  });
803
846
  }
804
847
 
805
- // Check if the agent has an active session we can fork from
806
- const hasSession = this.agentManager.hasActiveSession(agentId);
807
- if (!hasSession) {
848
+ // Check forkable: needs active session or persisted provider_session_id
849
+ if (
850
+ !this.agentManager.hasActiveSession(agentId) &&
851
+ !originalAgent.provider_session_id
852
+ ) {
808
853
  throw new ACPError(
809
- `Agent has no active session to fork: ${agentId}`,
854
+ `Agent has no session to fork: ${agentId}`,
810
855
  "FORK_NOT_SUPPORTED",
811
856
  { agentId },
812
857
  );
813
858
  }
814
859
 
815
- // For now, create a new agent with the same task as a "fork"
816
- // In a full implementation, we would:
817
- // 1. Check if acp-factory supports native fork
818
- // 2. Use loadSession to clone the conversation state
819
- // Since acp-factory doesn't expose these yet, we create a new agent
820
- // with the same task description as a simplified fork
821
-
822
- const taskDescription = name
823
- ? `[Fork of ${agentId}] ${name}`
824
- : `[Fork of ${agentId}] ${originalAgent.task ?? "Forked task"}`;
825
-
826
- const spawned = await this.agentManager.spawn({
827
- task: taskDescription,
828
- parent: originalAgent.parent ?? null,
829
- cwd: this.defaultCwd,
830
- subscribeParent: false,
860
+ // Fork via AgentManager (handles forkWithFlush + new process + loadSession)
861
+ const forked = await this.agentManager.forkAgent(agentId, {
862
+ name,
863
+ cwd: cwd ?? originalAgent.cwd ?? this.defaultCwd,
831
864
  });
832
865
 
833
- // Emit a fork event for tracking (the EventStore records this via spawn)
834
- // In a more complete implementation, we'd add a dedicated "fork" event type
866
+ // Fire-and-forget initial prompt if provided
867
+ if (prompt) {
868
+ (async () => {
869
+ try {
870
+ for await (const _update of this.agentManager.prompt(
871
+ forked.id,
872
+ prompt,
873
+ )) {
874
+ // Drain the async iterable
875
+ }
876
+ } catch (err) {
877
+ console.warn(
878
+ `[MacroAgent] Failed to send initial prompt to forked agent ${forked.id}:`,
879
+ err,
880
+ );
881
+ }
882
+ })();
883
+ }
835
884
 
836
885
  return {
837
- newAgentId: spawned.id,
838
- newSessionId: spawned.session_id,
886
+ newAgentId: forked.id,
887
+ newSessionId: forked.session_id,
839
888
  originalAgentId: agentId,
889
+ providerSessionId: forked.session.id,
840
890
  };
841
891
  }
842
892
 
@@ -1182,6 +1232,41 @@ export class MacroAgent implements Agent {
1182
1232
  }
1183
1233
  }
1184
1234
 
1235
+ /**
1236
+ * Change the permission mode for a running agent at runtime
1237
+ */
1238
+ private async handleSetPermissionMode(
1239
+ params: SetPermissionModeRequest,
1240
+ ): Promise<SetPermissionModeResponse> {
1241
+ const { agentId, permissionMode } = params;
1242
+
1243
+ // Get the current mode before changing
1244
+ const previousMode = this.agentManager.getPermissionMode(
1245
+ agentId as AgentId,
1246
+ );
1247
+
1248
+ // Set the new mode via agent manager
1249
+ const success = this.agentManager.setPermissionMode(
1250
+ agentId as AgentId,
1251
+ permissionMode,
1252
+ );
1253
+
1254
+ if (success) {
1255
+ console.log(
1256
+ `[MacroAgent] Set permission mode for agent ${agentId} from ${previousMode} to ${permissionMode}`,
1257
+ );
1258
+ return {
1259
+ success: true,
1260
+ previousMode: previousMode ?? undefined,
1261
+ };
1262
+ } else {
1263
+ return {
1264
+ success: false,
1265
+ error: `No active session found for agent ${agentId}`,
1266
+ };
1267
+ }
1268
+ }
1269
+
1185
1270
  /**
1186
1271
  * Resume a stopped/failed agent
1187
1272
  */
@@ -1315,7 +1400,7 @@ export class MacroAgent implements Agent {
1315
1400
 
1316
1401
  case "permission_request": {
1317
1402
  // Handle permission_request specially - ACP SDK doesn't recognize it as a session update
1318
- // We need to call requestPermission on the connection to forward to sudocode
1403
+ // We need to call requestPermission on the connection to forward to the client
1319
1404
 
1320
1405
  // Extract permission request data
1321
1406
  const permReq = sessionUpdate as {
@@ -1334,17 +1419,20 @@ export class MacroAgent implements Agent {
1334
1419
  }>;
1335
1420
  };
1336
1421
 
1337
- // Get the agent ID for this session to forward the response back
1338
- const agentId = this.sessionMapper.getAgentId(permReq.sessionId);
1422
+ // Look up agent ID using the ACP session ID (from the client connection),
1423
+ // NOT permReq.sessionId which is the agent's internal session ID.
1424
+ // The session mapper maps ACP session IDs → agent IDs, so using the
1425
+ // internal session ID would fail silently and drop the permission request.
1426
+ const agentId = this.sessionMapper.getAgentId(acpSessionId);
1339
1427
  if (!agentId) {
1340
1428
  console.warn(
1341
- `[MacroAgent] No agent found for session ${permReq.sessionId}, cannot forward permission request`,
1429
+ `[MacroAgent] No agent found for ACP session ${acpSessionId}, cannot forward permission request`,
1342
1430
  );
1343
1431
  return;
1344
1432
  }
1345
1433
 
1346
- // Forward to sudocode via requestPermission RPC
1347
- // This will trigger sudocode's WebSocketClientHandler which will show the prompt
1434
+ // Forward via requestPermission RPC
1435
+ // This will trigger the client's handler which will show the prompt
1348
1436
  try {
1349
1437
  const response = await this.connection.requestPermission({
1350
1438
  sessionId: acpSessionId,
@@ -1700,6 +1788,52 @@ export class MacroAgent implements Agent {
1700
1788
  }
1701
1789
  }
1702
1790
 
1791
+ /**
1792
+ * Handle _macro/getModels extension — returns the session's available models.
1793
+ * Claude Code populates models asynchronously after session creation
1794
+ * (via _model_state_update notification), so this allows the TUI to poll
1795
+ * for the model list once it's available.
1796
+ *
1797
+ * Returns full model info (modelId + name) since Claude Code uses shorthand
1798
+ * model IDs ("default", "sonnet") that don't match models.dev. The name
1799
+ * field (e.g., "Claude Sonnet 4") enables better model registry matching.
1800
+ */
1801
+ private handleGetModels(params: { sessionId: string }): {
1802
+ currentModelId: string | null;
1803
+ availableModels: Array<{ modelId: string; name: string }>;
1804
+ } {
1805
+ const { sessionId } = params;
1806
+ const agentId = this.sessionMapper.getAgentId(sessionId);
1807
+ if (!agentId) {
1808
+ return { currentModelId: null, availableModels: [] };
1809
+ }
1810
+ const session = this.agentManager.getSession(agentId);
1811
+ if (!session) {
1812
+ return { currentModelId: null, availableModels: [] };
1813
+ }
1814
+ // Try clientHandler's model info store first (from _model_state_update notification)
1815
+ const clientHandler = (session as unknown as {
1816
+ clientHandler?: {
1817
+ getSessionModelInfo?: (id: string) => {
1818
+ currentModelId: string | null;
1819
+ availableModels: Array<{ modelId: string; name: string }>;
1820
+ } | null;
1821
+ };
1822
+ }).clientHandler;
1823
+ const modelInfo = clientHandler?.getSessionModelInfo?.(session.id);
1824
+ if (modelInfo && modelInfo.availableModels.length > 0) {
1825
+ return modelInfo;
1826
+ }
1827
+ // Fall back to Session.models (from initial session response — just IDs)
1828
+ if (session.models && session.models.length > 0) {
1829
+ return {
1830
+ currentModelId: session.models[0],
1831
+ availableModels: session.models.map((id) => ({ modelId: id, name: id })),
1832
+ };
1833
+ }
1834
+ return { currentModelId: null, availableModels: [] };
1835
+ }
1836
+
1703
1837
  /**
1704
1838
  * Handle _macro/getHistory extension — returns conversation turns for a session
1705
1839
  */