aemeathcli 1.0.11 → 1.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 (218) hide show
  1. package/LICENSE +21 -21
  2. package/README.md +620 -609
  3. package/dist/{App-YAHJUWCX.js → App-JQ622M66.js} +209 -52
  4. package/dist/App-JQ622M66.js.map +1 -0
  5. package/dist/agent-store/architect.md +32 -32
  6. package/dist/agent-store/debugger.md +32 -32
  7. package/dist/agent-store/developer.md +29 -29
  8. package/dist/agent-store/documenter.md +30 -30
  9. package/dist/agent-store/researcher.md +31 -31
  10. package/dist/agent-store/reviewer.md +28 -28
  11. package/dist/agent-store/supervisor.md +37 -37
  12. package/dist/agent-store/tester.md +30 -30
  13. package/dist/api-key-fallback-RJLPM3KH.js +11 -0
  14. package/dist/{api-key-fallback-UN3TJEOO.js.map → api-key-fallback-RJLPM3KH.js.map} +1 -1
  15. package/dist/auth-status-JQJOKUPF.js +13 -0
  16. package/dist/{auth-status-EIM5A5KL.js.map → auth-status-JQJOKUPF.js.map} +1 -1
  17. package/dist/{chunk-P66WDACW.js → chunk-2KMA5RBC.js} +18 -42
  18. package/dist/chunk-2KMA5RBC.js.map +1 -0
  19. package/dist/{chunk-2GKOK6T7.js → chunk-2Y7TR6BS.js} +2 -2
  20. package/dist/chunk-2Y7TR6BS.js.map +1 -0
  21. package/dist/{chunk-ONQ4WCUI.js → chunk-2ZYK5IJG.js} +6 -6
  22. package/dist/chunk-2ZYK5IJG.js.map +1 -0
  23. package/dist/{chunk-OCJPQFOR.js → chunk-36RXCZOV.js} +4 -4
  24. package/dist/chunk-36RXCZOV.js.map +1 -0
  25. package/dist/{chunk-H2SYKIMI.js → chunk-7EBLXPL4.js} +10 -10
  26. package/dist/chunk-7EBLXPL4.js.map +1 -0
  27. package/dist/{chunk-IARA5XYP.js → chunk-BIMQL4AG.js} +4 -4
  28. package/dist/chunk-BIMQL4AG.js.map +1 -0
  29. package/dist/{chunk-BY4DAKUU.js → chunk-D275MCIH.js} +2 -2
  30. package/dist/chunk-D275MCIH.js.map +1 -0
  31. package/dist/{chunk-SOQFMNQC.js → chunk-FFS4T7BZ.js} +5 -5
  32. package/dist/chunk-FFS4T7BZ.js.map +1 -0
  33. package/dist/{chunk-LDVY5ELP.js → chunk-GXAJGP2T.js} +5 -5
  34. package/dist/chunk-GXAJGP2T.js.map +1 -0
  35. package/dist/{chunk-62HSGYQD.js → chunk-HCIHOHLX.js} +2 -2
  36. package/dist/chunk-HCIHOHLX.js.map +1 -0
  37. package/dist/{chunk-6GUD7QIM.js → chunk-HESQLCLU.js} +4 -4
  38. package/dist/chunk-HESQLCLU.js.map +1 -0
  39. package/dist/{chunk-HEKFAKVH.js → chunk-IR5HLBMH.js} +2 -2
  40. package/dist/chunk-IR5HLBMH.js.map +1 -0
  41. package/dist/{chunk-2LF7ALGR.js → chunk-K2FCMRXH.js} +4 -4
  42. package/dist/chunk-K2FCMRXH.js.map +1 -0
  43. package/dist/{chunk-2NWNIKBK.js → chunk-KIC7UI5U.js} +4 -4
  44. package/dist/chunk-KIC7UI5U.js.map +1 -0
  45. package/dist/{chunk-YPFOE2QJ.js → chunk-KMOAJRDE.js} +5 -5
  46. package/dist/chunk-KMOAJRDE.js.map +1 -0
  47. package/dist/{chunk-RP2TAL3J.js → chunk-LQBALETG.js} +2 -2
  48. package/dist/chunk-LQBALETG.js.map +1 -0
  49. package/dist/{chunk-CC7MGWYY.js → chunk-M3FPQSRU.js} +2 -2
  50. package/dist/chunk-M3FPQSRU.js.map +1 -0
  51. package/dist/{chunk-3TSPZRGM.js → chunk-NQEUK763.js} +3 -3
  52. package/dist/chunk-NQEUK763.js.map +1 -0
  53. package/dist/{chunk-VBLLDY4R.js → chunk-OPWAFS6Y.js} +2 -2
  54. package/dist/chunk-OPWAFS6Y.js.map +1 -0
  55. package/dist/{chunk-RYOB3TLZ.js → chunk-PS4WEFW6.js} +6 -6
  56. package/dist/chunk-PS4WEFW6.js.map +1 -0
  57. package/dist/{chunk-LCYH4T6N.js → chunk-QK7TKNHV.js} +6 -6
  58. package/dist/chunk-QK7TKNHV.js.map +1 -0
  59. package/dist/{chunk-QCRK4QEL.js → chunk-RADJSEG5.js} +3 -3
  60. package/dist/chunk-RADJSEG5.js.map +1 -0
  61. package/dist/{chunk-AQ23TYSQ.js → chunk-SNWPI6XJ.js} +4 -4
  62. package/dist/chunk-SNWPI6XJ.js.map +1 -0
  63. package/dist/{chunk-TDFTX32B.js → chunk-UM7MSLOV.js} +4 -4
  64. package/dist/chunk-UM7MSLOV.js.map +1 -0
  65. package/dist/{chunk-FIC7AK4Q.js → chunk-VNZ3YTQD.js} +5 -5
  66. package/dist/chunk-VNZ3YTQD.js.map +1 -0
  67. package/dist/{chunk-5XFSV6PF.js → chunk-WXIN65UG.js} +6 -6
  68. package/dist/chunk-WXIN65UG.js.map +1 -0
  69. package/dist/{chunk-WC72BRHR.js → chunk-XEXWX7C7.js} +3 -3
  70. package/dist/chunk-XEXWX7C7.js.map +1 -0
  71. package/dist/{chunk-VJNQJALF.js → chunk-YCCYXDW7.js} +4 -4
  72. package/dist/chunk-YCCYXDW7.js.map +1 -0
  73. package/dist/{chunk-ROJPFPJ7.js → chunk-YL5XFHR3.js} +2 -2
  74. package/dist/chunk-YL5XFHR3.js.map +1 -0
  75. package/dist/{chunk-GU33WKPG.js → chunk-YPQ2MLAV.js} +5 -5
  76. package/dist/chunk-YPQ2MLAV.js.map +1 -0
  77. package/dist/{chunk-WAYSJMPS.js → chunk-ZCOVMVK4.js} +2 -2
  78. package/dist/chunk-ZCOVMVK4.js.map +1 -0
  79. package/dist/{chunk-473JN6M5.js → chunk-ZGOHARPV.js} +2 -2
  80. package/dist/chunk-ZGOHARPV.js.map +1 -0
  81. package/dist/{claude-login-IS5WTBMP.js → claude-login-AIFIWTYF.js} +10 -10
  82. package/dist/claude-login-AIFIWTYF.js.map +1 -0
  83. package/dist/cli.js +30 -30
  84. package/dist/cli.js.map +1 -1
  85. package/dist/{codex-login-GMPF64MR.js → codex-login-LW5X7GAM.js} +10 -10
  86. package/dist/codex-login-LW5X7GAM.js.map +1 -0
  87. package/dist/config-store-NF56VHFU.js +7 -0
  88. package/dist/{config-store-POB6I37G.js.map → config-store-NF56VHFU.js.map} +1 -1
  89. package/dist/conversation-store-7GRDQZD2.js +4 -0
  90. package/dist/{conversation-store-PRBHWQMJ.js.map → conversation-store-7GRDQZD2.js.map} +1 -1
  91. package/dist/detect-providers-QICJ5U3R.js +4 -0
  92. package/dist/{detect-providers-C4SVQHFF.js.map → detect-providers-QICJ5U3R.js.map} +1 -1
  93. package/dist/executor-FTABX2AW.js +4 -0
  94. package/dist/{executor-RUX7VK3T.js.map → executor-FTABX2AW.js.map} +1 -1
  95. package/dist/{first-run-GDEVRFPO.js → first-run-ADROZVYF.js} +13 -13
  96. package/dist/first-run-ADROZVYF.js.map +1 -0
  97. package/dist/{gemini-login-KE224MSW.js → gemini-login-TST454MX.js} +10 -10
  98. package/dist/gemini-login-TST454MX.js.map +1 -0
  99. package/dist/index.d.ts +2 -56
  100. package/dist/index.js +30 -34
  101. package/dist/index.js.map +1 -1
  102. package/dist/{input-history-MIOO3FIW.js → input-history-BEICE7PT.js} +3 -3
  103. package/dist/input-history-BEICE7PT.js.map +1 -0
  104. package/dist/kimi-adapter-7FYOAKOI.js +6 -0
  105. package/dist/{kimi-adapter-UODMNX6K.js.map → kimi-adapter-7FYOAKOI.js.map} +1 -1
  106. package/dist/{kimi-login-DNT5YBKX.js → kimi-login-3IGVOBJI.js} +10 -10
  107. package/dist/kimi-login-3IGVOBJI.js.map +1 -0
  108. package/dist/logger-KGHUQ4VE.js +3 -0
  109. package/dist/{logger-PLPDWACQ.js.map → logger-KGHUQ4VE.js.map} +1 -1
  110. package/dist/model-discovery-AAJDHRFO.js +6 -0
  111. package/dist/{model-discovery-O64ZWPX5.js.map → model-discovery-AAJDHRFO.js.map} +1 -1
  112. package/dist/native-cli-adapters-CLONTZOA.js +8 -0
  113. package/dist/{native-cli-adapters-JMZX2C2C.js.map → native-cli-adapters-CLONTZOA.js.map} +1 -1
  114. package/dist/ollama-adapter-2N5OQIEV.js +5 -0
  115. package/dist/{ollama-adapter-GE67BNSS.js.map → ollama-adapter-2N5OQIEV.js.map} +1 -1
  116. package/dist/{pathResolver-A6IXQQFE.js → pathResolver-UVAB2FCW.js} +3 -3
  117. package/dist/{pathResolver-A6IXQQFE.js.map → pathResolver-UVAB2FCW.js.map} +1 -1
  118. package/dist/{profile-loader-TNAXBLDX.js → profile-loader-EMLV4J7S.js} +4 -4
  119. package/dist/profile-loader-EMLV4J7S.js.map +1 -0
  120. package/dist/registry-LRURZVUL.js +5 -0
  121. package/dist/{registry-3NHVCXCZ.js.map → registry-LRURZVUL.js.map} +1 -1
  122. package/dist/registry-MVNSXCEF.js +6 -0
  123. package/dist/{registry-7CQ3NCAD.js.map → registry-MVNSXCEF.js.map} +1 -1
  124. package/dist/server-manager-THGZBBZB.js +5 -0
  125. package/dist/{server-manager-DES23IBQ.js.map → server-manager-THGZBBZB.js.map} +1 -1
  126. package/dist/session-manager-X3DXT53M.js +12 -0
  127. package/dist/{session-manager-EHD7GWM2.js.map → session-manager-X3DXT53M.js.map} +1 -1
  128. package/dist/skills/built-in/code-review/SKILL.md +85 -85
  129. package/dist/skills/built-in/commit/SKILL.md +83 -83
  130. package/dist/skills/built-in/debug/SKILL.md +119 -119
  131. package/dist/skills/built-in/plan/SKILL.md +123 -123
  132. package/dist/skills/built-in/refactor/SKILL.md +132 -132
  133. package/dist/skills/built-in/test/SKILL.md +128 -128
  134. package/dist/sqlite-store-7OECRTXM.js +5 -0
  135. package/dist/{sqlite-store-7ZIVOUNI.js.map → sqlite-store-7OECRTXM.js.map} +1 -1
  136. package/dist/team-manager-2VSMALAA.js +11 -0
  137. package/dist/{team-manager-6DCNLGTC.js.map → team-manager-2VSMALAA.js.map} +1 -1
  138. package/dist/team-state-HZNVMQHT.js +3 -0
  139. package/dist/{team-state-R2D7DT5M.js.map → team-state-HZNVMQHT.js.map} +1 -1
  140. package/dist/tmux-manager-57QCUVHU.js +6 -0
  141. package/dist/{tmux-manager-WBKHUHDT.js.map → tmux-manager-57QCUVHU.js.map} +1 -1
  142. package/dist/tools-KWFSYT56.js +6 -0
  143. package/dist/{tools-I6XCTEZY.js.map → tools-KWFSYT56.js.map} +1 -1
  144. package/package.json +89 -93
  145. package/dist/App-YAHJUWCX.js.map +0 -1
  146. package/dist/api-key-fallback-UN3TJEOO.js +0 -11
  147. package/dist/auth-status-EIM5A5KL.js +0 -13
  148. package/dist/chunk-25UNNEHN.js +0 -140
  149. package/dist/chunk-25UNNEHN.js.map +0 -1
  150. package/dist/chunk-2GKOK6T7.js.map +0 -1
  151. package/dist/chunk-2LF7ALGR.js.map +0 -1
  152. package/dist/chunk-2NWNIKBK.js.map +0 -1
  153. package/dist/chunk-3TSPZRGM.js.map +0 -1
  154. package/dist/chunk-473JN6M5.js.map +0 -1
  155. package/dist/chunk-5XFSV6PF.js.map +0 -1
  156. package/dist/chunk-62HSGYQD.js.map +0 -1
  157. package/dist/chunk-6GUD7QIM.js.map +0 -1
  158. package/dist/chunk-AQ23TYSQ.js.map +0 -1
  159. package/dist/chunk-BY4DAKUU.js.map +0 -1
  160. package/dist/chunk-CC7MGWYY.js.map +0 -1
  161. package/dist/chunk-CTFZTARK.js +0 -155
  162. package/dist/chunk-CTFZTARK.js.map +0 -1
  163. package/dist/chunk-FIC7AK4Q.js.map +0 -1
  164. package/dist/chunk-GU33WKPG.js.map +0 -1
  165. package/dist/chunk-H2SYKIMI.js.map +0 -1
  166. package/dist/chunk-HEKFAKVH.js.map +0 -1
  167. package/dist/chunk-IARA5XYP.js.map +0 -1
  168. package/dist/chunk-LCYH4T6N.js.map +0 -1
  169. package/dist/chunk-LDVY5ELP.js.map +0 -1
  170. package/dist/chunk-OCJPQFOR.js.map +0 -1
  171. package/dist/chunk-ODBY7S4X.js +0 -141
  172. package/dist/chunk-ODBY7S4X.js.map +0 -1
  173. package/dist/chunk-ONQ4WCUI.js.map +0 -1
  174. package/dist/chunk-P5TKZM3T.js +0 -159
  175. package/dist/chunk-P5TKZM3T.js.map +0 -1
  176. package/dist/chunk-P66WDACW.js.map +0 -1
  177. package/dist/chunk-QCRK4QEL.js.map +0 -1
  178. package/dist/chunk-ROJPFPJ7.js.map +0 -1
  179. package/dist/chunk-RP2TAL3J.js.map +0 -1
  180. package/dist/chunk-RYOB3TLZ.js.map +0 -1
  181. package/dist/chunk-SOQFMNQC.js.map +0 -1
  182. package/dist/chunk-TDFTX32B.js.map +0 -1
  183. package/dist/chunk-VBLLDY4R.js.map +0 -1
  184. package/dist/chunk-VJNQJALF.js.map +0 -1
  185. package/dist/chunk-WAYSJMPS.js.map +0 -1
  186. package/dist/chunk-WC72BRHR.js.map +0 -1
  187. package/dist/chunk-YPFOE2QJ.js.map +0 -1
  188. package/dist/claude-adapter-6P4SJH7P.js +0 -7
  189. package/dist/claude-adapter-6P4SJH7P.js.map +0 -1
  190. package/dist/claude-login-IS5WTBMP.js.map +0 -1
  191. package/dist/codex-login-GMPF64MR.js.map +0 -1
  192. package/dist/config-store-POB6I37G.js +0 -7
  193. package/dist/conversation-store-PRBHWQMJ.js +0 -4
  194. package/dist/detect-providers-C4SVQHFF.js +0 -4
  195. package/dist/executor-RUX7VK3T.js +0 -4
  196. package/dist/first-run-GDEVRFPO.js.map +0 -1
  197. package/dist/gemini-adapter-MV3U4QFH.js +0 -7
  198. package/dist/gemini-adapter-MV3U4QFH.js.map +0 -1
  199. package/dist/gemini-login-KE224MSW.js.map +0 -1
  200. package/dist/input-history-MIOO3FIW.js.map +0 -1
  201. package/dist/kimi-adapter-UODMNX6K.js +0 -6
  202. package/dist/kimi-login-DNT5YBKX.js.map +0 -1
  203. package/dist/logger-PLPDWACQ.js +0 -3
  204. package/dist/model-discovery-O64ZWPX5.js +0 -6
  205. package/dist/native-cli-adapters-JMZX2C2C.js +0 -8
  206. package/dist/ollama-adapter-GE67BNSS.js +0 -5
  207. package/dist/openai-adapter-SHPLK77L.js +0 -7
  208. package/dist/openai-adapter-SHPLK77L.js.map +0 -1
  209. package/dist/profile-loader-TNAXBLDX.js.map +0 -1
  210. package/dist/registry-3NHVCXCZ.js +0 -6
  211. package/dist/registry-7CQ3NCAD.js +0 -5
  212. package/dist/server-manager-DES23IBQ.js +0 -5
  213. package/dist/session-manager-EHD7GWM2.js +0 -12
  214. package/dist/sqlite-store-7ZIVOUNI.js +0 -5
  215. package/dist/team-manager-6DCNLGTC.js +0 -11
  216. package/dist/team-state-R2D7DT5M.js +0 -3
  217. package/dist/tmux-manager-WBKHUHDT.js +0 -6
  218. package/dist/tools-I6XCTEZY.js +0 -6
@@ -1 +0,0 @@
1
- {"version":3,"sources":["../src/utils/pathResolver.ts"],"names":[],"mappings":"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","file":"chunk-BY4DAKUU.js","sourcesContent":["/**\r\n * Safe path handling per PRD section 15.7 item 5\r\n * NO hardcoded paths — use path.join(), os.homedir(), XDG Base Directory\r\n */\r\n\r\nimport { homedir, tmpdir } from \"node:os\";\r\nimport { join, dirname } from \"node:path\";\r\nimport { existsSync, mkdirSync } from \"node:fs\";\r\n\r\n// ── XDG-inspired directory layout ────────────────────────────────────────\r\n\r\nconst AEMEATHCLI_HOME = join(homedir(), \".aemeathcli\");\r\n\r\nexport function getAemeathHome(): string {\r\n return process.env[\"AEMEATHCLI_HOME\"] ?? AEMEATHCLI_HOME;\r\n}\r\n\r\nexport function getConfigDir(): string {\r\n return getAemeathHome();\r\n}\r\n\r\nexport function getConfigPath(): string {\r\n return join(getConfigDir(), \"config.json\");\r\n}\r\n\r\nexport function getDatabaseDir(): string {\r\n return join(getAemeathHome(), \"db\");\r\n}\r\n\r\nexport function getDatabasePath(): string {\r\n return join(getDatabaseDir(), \"aemeathcli.db\");\r\n}\r\n\r\nexport function getLogDir(): string {\r\n return join(getAemeathHome(), \"logs\");\r\n}\r\n\r\nexport function getCredentialsPath(): string {\r\n return join(getAemeathHome(), \"credentials.enc\");\r\n}\r\n\r\nexport function getMCPConfigPath(): string {\r\n return join(getAemeathHome(), \"mcp.json\");\r\n}\r\n\r\nexport function getUserSkillsDir(): string {\r\n return join(getAemeathHome(), \"skills\");\r\n}\r\n\r\n/** Universal user-level skills directory: ~/.agents/skills/ */\r\nexport function getUniversalUserSkillsDir(): string {\r\n return join(homedir(), \".agents\", \"skills\");\r\n}\r\n\r\nexport function getTeamsDir(): string {\r\n return join(getAemeathHome(), \"teams\");\r\n}\r\n\r\nexport function getTasksDir(): string {\r\n return join(getAemeathHome(), \"tasks\");\r\n}\r\n\r\n// ── Project-level paths ──────────────────────────────────────────────────\r\n\r\nexport function getProjectConfigDir(projectRoot: string): string {\r\n return join(projectRoot, \".aemeathcli\");\r\n}\r\n\r\nexport function getProjectConfigPath(projectRoot: string): string {\r\n return join(getProjectConfigDir(projectRoot), \"config.json\");\r\n}\r\n\r\nexport function getProjectSkillsDir(projectRoot: string): string {\r\n return join(getProjectConfigDir(projectRoot), \"skills\");\r\n}\r\n\r\n/** Universal project-level skills directory: <projectRoot>/.agents/skills/ */\r\nexport function getUniversalProjectSkillsDir(projectRoot: string): string {\r\n return join(projectRoot, \".agents\", \"skills\");\r\n}\r\n\r\nexport function getProjectMCPConfigPath(projectRoot: string): string {\r\n return join(getProjectConfigDir(projectRoot), \"mcp.json\");\r\n}\r\n\r\nexport function getProjectAgentsPath(projectRoot: string): string {\r\n return join(getProjectConfigDir(projectRoot), \"AGENTS.md\");\r\n}\r\n\r\n// ── Socket paths (PRD section 14.5) ──────────────────────────────────────\r\n\r\nexport function getIPCSocketDir(): string {\r\n const tmp = process.env[\"TMPDIR\"] ?? tmpdir();\r\n const uid = process.platform === \"win32\"\r\n ? (process.env[\"USERNAME\"] ?? \"user\")\r\n : String(process.getuid?.() ?? \"user\");\r\n return join(tmp, `aemeathcli-${uid}`);\r\n}\r\n\r\nexport function getIPCSocketPath(sessionId: string): string {\r\n return join(getIPCSocketDir(), `${sessionId}.sock`);\r\n}\r\n\r\n// ── Directory Initialization ─────────────────────────────────────────────\r\n\r\nexport function ensureDirectory(dirPath: string, mode?: number): void {\r\n if (!existsSync(dirPath)) {\r\n mkdirSync(dirPath, { recursive: true, mode: mode ?? 0o755 });\r\n }\r\n}\r\n\r\nexport function ensureSecureDirectory(dirPath: string): void {\r\n ensureDirectory(dirPath, 0o700);\r\n}\r\n\r\nexport function initializeDirectories(): void {\r\n ensureSecureDirectory(getAemeathHome());\r\n ensureDirectory(getDatabaseDir());\r\n ensureSecureDirectory(getLogDir());\r\n ensureDirectory(getUserSkillsDir());\r\n ensureDirectory(getTeamsDir());\r\n ensureDirectory(getTasksDir());\r\n}\r\n\r\n// ── Project Root Detection ───────────────────────────────────────────────\r\n\r\nexport function findProjectRoot(startDir?: string): string {\r\n let currentDir = startDir ?? process.cwd();\r\n\r\n while (currentDir !== dirname(currentDir)) {\r\n if (existsSync(join(currentDir, \".git\"))) {\r\n return currentDir;\r\n }\r\n if (existsSync(join(currentDir, \".aemeathcli\"))) {\r\n return currentDir;\r\n }\r\n if (existsSync(join(currentDir, \"package.json\"))) {\r\n return currentDir;\r\n }\r\n currentDir = dirname(currentDir);\r\n }\r\n\r\n // Fallback to cwd\r\n return process.cwd();\r\n}\r\n"]}
@@ -1 +0,0 @@
1
- {"version":3,"sources":["../src/orchestrator/constants.ts"],"names":[],"mappings":";AAcO,IAAM,aAAA,GAA4C;AAAA,EACvD,aAAA;AAAA,EAAe,OAAA;AAAA,EAAS,YAAA;AAAA,EAAc,UAAA;AAAA,EAAY;AACpD","file":"chunk-CC7MGWYY.js","sourcesContent":["/**\r\n * Orchestrator constants — shared across all orchestrator modules.\r\n */\r\n\r\nimport type { ProviderName } from \"../types/index.js\";\r\n\r\n// ── Terminal Status ─────────────────────────────────────────────────────\r\n\r\nexport type TerminalStatus = \"idle\" | \"processing\" | \"completed\" | \"waiting_user_answer\" | \"error\";\r\n\r\n// ── CLI Provider Types ──────────────────────────────────────────────────\r\n\r\nexport type CliProviderType = \"claude-code\" | \"codex\" | \"gemini-cli\" | \"kimi-cli\" | \"ollama\";\r\n\r\nexport const CLI_PROVIDERS: readonly CliProviderType[] = [\r\n \"claude-code\", \"codex\", \"gemini-cli\", \"kimi-cli\", \"ollama\",\r\n] as const;\r\n\r\nexport const DEFAULT_CLI_PROVIDER: CliProviderType = \"claude-code\";\r\n\r\n// ── Provider CLI → SDK Mapping ──────────────────────────────────────────\r\n\r\nexport const SDK_FOR_CLI: Record<CliProviderType, ProviderName> = {\r\n \"claude-code\": \"anthropic\",\r\n \"codex\": \"openai\",\r\n \"gemini-cli\": \"google\",\r\n \"kimi-cli\": \"kimi\",\r\n \"ollama\": \"ollama\",\r\n};\r\n\r\n// ── Timeouts & Limits ───────────────────────────────────────────────────\r\n\r\nexport const MAX_BUFFER_BYTES = 5 * 1024 * 1024; // 5MB per PTY session\r\nexport const TAIL_BUFFER_LINES = 200; // Lines kept in tail buffer\r\nexport const MAX_WORKERS_PER_SESSION = 10; // Max concurrent workers\r\nexport const MAX_ORCHESTRATOR_STEPS = 30; // Max supervisor tool-call rounds\r\nexport const MAX_HANDOFF_DEPTH = 5; // Max nested handoffs\r\nexport const MAX_OUTPUT_EXTRACT_BYTES = 100 * 1024; // 100KB tool result truncation\r\n\r\nexport const PROVIDER_INIT_TIMEOUT_MS = 30_000; // 30s provider startup\r\nexport const HANDOFF_TIMEOUT_MS = 600_000; // 10min default handoff\r\nexport const SHELL_READY_TIMEOUT_MS = 10_000; // 10s shell boot\r\nexport const STATUS_POLL_INTERVAL_MS = 2_000; // 2s status check interval\r\nexport const INBOX_POLL_INTERVAL_MS = 5_000; // 5s inbox delivery check\r\nexport const WINDOWS_KILL_TIMEOUT_MS = 5_000; // 5s force-kill on Windows\r\nexport const EXIT_DRAIN_DELAY_MS = 200; // 200ms onExit drain\r\n\r\n// ── Data Models ─────────────────────────────────────────────────────────\r\n\r\nexport interface TerminalRecord {\r\n id: string;\r\n sessionId: string;\r\n pid?: number | undefined;\r\n provider: CliProviderType;\r\n agentProfile?: string | undefined;\r\n status: TerminalStatus;\r\n createdAt: Date;\r\n}\r\n\r\nexport interface SessionRecord {\r\n sessionId: string;\r\n pid?: number | undefined;\r\n workerCount: number;\r\n providers: CliProviderType[];\r\n createdAt: Date;\r\n}\r\n\r\nexport interface InboxMessage {\r\n id: number;\r\n sender: string;\r\n receiver: string;\r\n content: string;\r\n status: \"pending\" | \"delivered\" | \"failed\";\r\n createdAt: Date;\r\n deliveredAt?: Date | undefined;\r\n}\r\n\r\nexport interface AgentProfile {\r\n name: string;\r\n description: string;\r\n provider?: CliProviderType | undefined;\r\n systemPrompt: string;\r\n}\r\n\r\nexport interface WorkerInfo {\r\n terminalId: string;\r\n provider: CliProviderType;\r\n status: TerminalStatus;\r\n}\r\n\r\nexport interface SpawnOptions {\r\n provider: CliProviderType;\r\n agentProfile?: string | undefined;\r\n workingDirectory?: string | undefined;\r\n model?: string | undefined;\r\n}\r\n"]}
@@ -1,155 +0,0 @@
1
- import { buildModelMessages, buildAiSdkTools, extractAiSdkToolCalls, buildTokenUsage, mapAiSdkFinishReason } from './chunk-ODBY7S4X.js';
2
- import { ModelNotFoundError, AuthenticationError, RateLimitError } from './chunk-473JN6M5.js';
3
- import { SUPPORTED_MODELS } from './chunk-62HSGYQD.js';
4
- import { logger } from './chunk-HEKFAKVH.js';
5
- import { generateText, streamText } from 'ai';
6
- import { createAnthropic } from '@ai-sdk/anthropic';
7
-
8
- var PROVIDER_NAME = "anthropic";
9
- var CLAUDE_MODELS = [
10
- "claude-opus-4-6",
11
- "claude-opus-4-6-1m",
12
- "claude-sonnet-4-6",
13
- "claude-sonnet-4-6-1m",
14
- "claude-haiku-4-5"
15
- ];
16
- var CHARS_PER_TOKEN_ESTIMATE = 4;
17
- function mapRole(role) {
18
- switch (role) {
19
- case "user":
20
- return "user";
21
- case "assistant":
22
- return "assistant";
23
- case "system":
24
- return "system";
25
- case "tool":
26
- return "tool";
27
- default:
28
- return "user";
29
- }
30
- }
31
- function classifyError(error, model) {
32
- const message = error instanceof Error ? error.message : String(error);
33
- const lower = message.toLowerCase();
34
- if (lower.includes("401") || lower.includes("unauthorized") || lower.includes("invalid api key")) {
35
- throw new AuthenticationError(PROVIDER_NAME, message);
36
- }
37
- if (lower.includes("429") || lower.includes("rate limit") || lower.includes("too many requests")) {
38
- const match = /(\d+)\s*s/i.exec(message);
39
- const retryMs = match?.[1] !== void 0 ? parseInt(match[1], 10) * 1e3 : 6e4;
40
- throw new RateLimitError(PROVIDER_NAME, retryMs);
41
- }
42
- if (lower.includes("model") && lower.includes("not found")) {
43
- throw new ModelNotFoundError(model);
44
- }
45
- throw error instanceof Error ? error : new Error(message);
46
- }
47
- var ClaudeAdapter = class {
48
- name = PROVIDER_NAME;
49
- supportedModels = CLAUDE_MODELS;
50
- supportsToolCalling = true;
51
- anthropic;
52
- constructor(options) {
53
- const apiKey = options?.apiKey ?? process.env["ANTHROPIC_API_KEY"];
54
- this.anthropic = createAnthropic({
55
- ...apiKey !== void 0 ? { apiKey } : {},
56
- ...options?.baseUrl !== void 0 ? { baseURL: options.baseUrl } : {}
57
- });
58
- }
59
- async chat(request) {
60
- const modelInfo = this.getModelInfo(request.model);
61
- const messages = buildModelMessages(request.messages, { mapRole });
62
- const tools = buildAiSdkTools(request.tools);
63
- try {
64
- const result = await generateText({
65
- model: this.anthropic(request.model),
66
- messages,
67
- ...request.system !== void 0 ? { system: request.system } : {},
68
- ...tools !== void 0 ? { tools } : {},
69
- maxOutputTokens: request.maxTokens ?? modelInfo.maxOutputTokens,
70
- ...request.temperature !== void 0 ? { temperature: request.temperature } : {}
71
- });
72
- const toolCalls = extractAiSdkToolCalls(result.toolCalls);
73
- const usage = buildTokenUsage(modelInfo, result.usage);
74
- const responseMessage = {
75
- id: result.response.id,
76
- role: "assistant",
77
- content: result.text,
78
- model: request.model,
79
- provider: PROVIDER_NAME,
80
- toolCalls: toolCalls.length > 0 ? toolCalls : void 0,
81
- tokenUsage: usage,
82
- createdAt: /* @__PURE__ */ new Date()
83
- };
84
- return {
85
- id: result.response.id,
86
- model: request.model,
87
- provider: PROVIDER_NAME,
88
- message: responseMessage,
89
- usage,
90
- finishReason: mapAiSdkFinishReason(result.finishReason, {
91
- stop: ["end-turn"],
92
- maxTokens: ["max-tokens"]
93
- })
94
- };
95
- } catch (error) {
96
- classifyError(error, request.model);
97
- }
98
- }
99
- async *stream(request) {
100
- const modelInfo = this.getModelInfo(request.model);
101
- const messages = buildModelMessages(request.messages, { mapRole });
102
- const tools = buildAiSdkTools(request.tools);
103
- try {
104
- const result = streamText({
105
- model: this.anthropic(request.model),
106
- messages,
107
- ...request.system !== void 0 ? { system: request.system } : {},
108
- ...tools !== void 0 ? { tools } : {},
109
- maxOutputTokens: request.maxTokens ?? modelInfo.maxOutputTokens,
110
- ...request.temperature !== void 0 ? { temperature: request.temperature } : {}
111
- });
112
- for await (const part of result.fullStream) {
113
- if (part.type === "text-delta") {
114
- yield { type: "text", content: part.text };
115
- } else if (part.type === "tool-call") {
116
- const [toolCall] = extractAiSdkToolCalls([{
117
- toolCallId: part.toolCallId,
118
- toolName: part.toolName,
119
- input: part.input
120
- }]);
121
- if (toolCall === void 0) {
122
- continue;
123
- }
124
- yield { type: "tool_call", toolCall };
125
- } else if (part.type === "finish") {
126
- const usage = buildTokenUsage(modelInfo, part.totalUsage);
127
- yield { type: "usage", usage };
128
- } else if (part.type === "error") {
129
- const errMsg = part.error instanceof Error ? part.error.message : String(part.error);
130
- yield { type: "error", error: errMsg };
131
- }
132
- }
133
- yield { type: "done" };
134
- } catch (error) {
135
- const errMsg = error instanceof Error ? error.message : String(error);
136
- logger.error({ error: errMsg, model: request.model }, "Claude stream error");
137
- yield { type: "error", error: errMsg };
138
- yield { type: "done" };
139
- }
140
- }
141
- countTokens(text, _model) {
142
- return Promise.resolve(Math.ceil(text.length / CHARS_PER_TOKEN_ESTIMATE));
143
- }
144
- getModelInfo(model) {
145
- const info = SUPPORTED_MODELS[model];
146
- if (info === void 0 || info.provider !== PROVIDER_NAME) {
147
- throw new ModelNotFoundError(model);
148
- }
149
- return info;
150
- }
151
- };
152
-
153
- export { ClaudeAdapter };
154
- //# sourceMappingURL=chunk-CTFZTARK.js.map
155
- //# sourceMappingURL=chunk-CTFZTARK.js.map
@@ -1 +0,0 @@
1
- {"version":3,"sources":["../src/providers/claude-adapter.ts"],"names":[],"mappings":";;;;;;;AA8BA,IAAM,aAAA,GAA8B,WAAA;AAEpC,IAAM,aAAA,GAAmC;AAAA,EACvC,iBAAA;AAAA,EACA,oBAAA;AAAA,EACA,mBAAA;AAAA,EACA,sBAAA;AAAA,EACA;AACF,CAAA;AAEA,IAAM,wBAAA,GAA2B,CAAA;AAEjC,SAAS,QAAQ,IAAA,EAAsE;AACrF,EAAA,QAAQ,IAAA;AAAM,IACZ,KAAK,MAAA;AACH,MAAA,OAAO,MAAA;AAAA,IACT,KAAK,WAAA;AACH,MAAA,OAAO,WAAA;AAAA,IACT,KAAK,QAAA;AACH,MAAA,OAAO,QAAA;AAAA,IACT,KAAK,MAAA;AACH,MAAA,OAAO,MAAA;AAAA,IACT;AACE,MAAA,OAAO,MAAA;AAAA;AAEb;AAEA,SAAS,aAAA,CAAc,OAAgB,KAAA,EAAsB;AAC3D,EAAA,MAAM,UAAU,KAAA,YAAiB,KAAA,GAAQ,KAAA,CAAM,OAAA,GAAU,OAAO,KAAK,CAAA;AACrE,EAAA,MAAM,KAAA,GAAQ,QAAQ,WAAA,EAAY;AAElC,EAAA,IAAI,KAAA,CAAM,QAAA,CAAS,KAAK,CAAA,IAAK,KAAA,CAAM,QAAA,CAAS,cAAc,CAAA,IAAK,KAAA,CAAM,QAAA,CAAS,iBAAiB,CAAA,EAAG;AAChG,IAAA,MAAM,IAAI,mBAAA,CAAoB,aAAA,EAAe,OAAO,CAAA;AAAA,EACtD;AACA,EAAA,IAAI,KAAA,CAAM,QAAA,CAAS,KAAK,CAAA,IAAK,KAAA,CAAM,QAAA,CAAS,YAAY,CAAA,IAAK,KAAA,CAAM,QAAA,CAAS,mBAAmB,CAAA,EAAG;AAChG,IAAA,MAAM,KAAA,GAAQ,YAAA,CAAa,IAAA,CAAK,OAAO,CAAA;AACvC,IAAA,MAAM,OAAA,GAAU,KAAA,GAAQ,CAAC,CAAA,KAAM,MAAA,GAAY,QAAA,CAAS,KAAA,CAAM,CAAC,CAAA,EAAG,EAAE,CAAA,GAAI,GAAA,GAAO,GAAA;AAC3E,IAAA,MAAM,IAAI,cAAA,CAAe,aAAA,EAAe,OAAO,CAAA;AAAA,EACjD;AACA,EAAA,IAAI,MAAM,QAAA,CAAS,OAAO,KAAK,KAAA,CAAM,QAAA,CAAS,WAAW,CAAA,EAAG;AAC1D,IAAA,MAAM,IAAI,mBAAmB,KAAK,CAAA;AAAA,EACpC;AAEA,EAAA,MAAM,KAAA,YAAiB,KAAA,GAAQ,KAAA,GAAQ,IAAI,MAAM,OAAO,CAAA;AAC1D;AAEO,IAAM,gBAAN,MAA8C;AAAA,EAC1C,IAAA,GAAO,aAAA;AAAA,EACP,eAAA,GAAkB,aAAA;AAAA,EAClB,mBAAA,GAAsB,IAAA;AAAA,EAEd,SAAA;AAAA,EAEjB,YAAY,OAAA,EAA4B;AACtC,IAAA,MAAM,MAAA,GAAS,OAAA,EAAS,MAAA,IAAU,OAAA,CAAQ,IAAI,mBAAmB,CAAA;AACjE,IAAA,IAAA,CAAK,YAAY,eAAA,CAAgB;AAAA,MAC/B,GAAI,MAAA,KAAW,MAAA,GAAY,EAAE,MAAA,KAAW,EAAC;AAAA,MACzC,GAAI,SAAS,OAAA,KAAY,MAAA,GAAY,EAAE,OAAA,EAAS,OAAA,CAAQ,OAAA,EAAQ,GAAI;AAAC,KACtE,CAAA;AAAA,EACH;AAAA,EAEA,MAAM,KAAK,OAAA,EAA+C;AACxD,IAAA,MAAM,SAAA,GAAY,IAAA,CAAK,YAAA,CAAa,OAAA,CAAQ,KAAK,CAAA;AACjD,IAAA,MAAM,WAAW,kBAAA,CAAmB,OAAA,CAAQ,QAAA,EAAU,EAAE,SAAS,CAAA;AACjE,IAAA,MAAM,KAAA,GAAQ,eAAA,CAAgB,OAAA,CAAQ,KAAK,CAAA;AAE3C,IAAA,IAAI;AACF,MAAA,MAAM,MAAA,GAAS,MAAM,YAAA,CAAa;AAAA,QAChC,KAAA,EAAO,IAAA,CAAK,SAAA,CAAU,OAAA,CAAQ,KAAK,CAAA;AAAA,QACnC,QAAA;AAAA,QACA,GAAI,QAAQ,MAAA,KAAW,KAAA,CAAA,GAAY,EAAE,MAAA,EAAQ,OAAA,CAAQ,MAAA,EAAO,GAAI,EAAC;AAAA,QACjE,GAAI,KAAA,KAAU,KAAA,CAAA,GAAY,EAAE,KAAA,KAAU,EAAC;AAAA,QACvC,eAAA,EAAiB,OAAA,CAAQ,SAAA,IAAa,SAAA,CAAU,eAAA;AAAA,QAChD,GAAI,QAAQ,WAAA,KAAgB,KAAA,CAAA,GAAY,EAAE,WAAA,EAAa,OAAA,CAAQ,WAAA,EAAY,GAAI;AAAC,OACjF,CAAA;AAED,MAAA,MAAM,SAAA,GAAY,qBAAA,CAAsB,MAAA,CAAO,SAAS,CAAA;AACxD,MAAA,MAAM,KAAA,GAAQ,eAAA,CAAgB,SAAA,EAAW,MAAA,CAAO,KAAK,CAAA;AAErD,MAAA,MAAM,eAAA,GAAgC;AAAA,QACpC,EAAA,EAAI,OAAO,QAAA,CAAS,EAAA;AAAA,QACpB,IAAA,EAAM,WAAA;AAAA,QACN,SAAS,MAAA,CAAO,IAAA;AAAA,QAChB,OAAO,OAAA,CAAQ,KAAA;AAAA,QACf,QAAA,EAAU,aAAA;AAAA,QACV,SAAA,EAAW,SAAA,CAAU,MAAA,GAAS,CAAA,GAAI,SAAA,GAAY,KAAA,CAAA;AAAA,QAC9C,UAAA,EAAY,KAAA;AAAA,QACZ,SAAA,sBAAe,IAAA;AAAK,OACtB;AAEA,MAAA,OAAO;AAAA,QACL,EAAA,EAAI,OAAO,QAAA,CAAS,EAAA;AAAA,QACpB,OAAO,OAAA,CAAQ,KAAA;AAAA,QACf,QAAA,EAAU,aAAA;AAAA,QACV,OAAA,EAAS,eAAA;AAAA,QACT,KAAA;AAAA,QACA,YAAA,EAAc,oBAAA,CAAqB,MAAA,CAAO,YAAA,EAAc;AAAA,UACtD,IAAA,EAAM,CAAC,UAAU,CAAA;AAAA,UACjB,SAAA,EAAW,CAAC,YAAY;AAAA,SACzB;AAAA,OACH;AAAA,IACF,SAAS,KAAA,EAAgB;AACvB,MAAA,aAAA,CAAc,KAAA,EAAO,QAAQ,KAAK,CAAA;AAAA,IACpC;AAAA,EACF;AAAA,EAEA,OAAO,OAAO,OAAA,EAAoD;AAChE,IAAA,MAAM,SAAA,GAAY,IAAA,CAAK,YAAA,CAAa,OAAA,CAAQ,KAAK,CAAA;AACjD,IAAA,MAAM,WAAW,kBAAA,CAAmB,OAAA,CAAQ,QAAA,EAAU,EAAE,SAAS,CAAA;AACjE,IAAA,MAAM,KAAA,GAAQ,eAAA,CAAgB,OAAA,CAAQ,KAAK,CAAA;AAE3C,IAAA,IAAI;AACF,MAAA,MAAM,SAAS,UAAA,CAAW;AAAA,QACxB,KAAA,EAAO,IAAA,CAAK,SAAA,CAAU,OAAA,CAAQ,KAAK,CAAA;AAAA,QACnC,QAAA;AAAA,QACA,GAAI,QAAQ,MAAA,KAAW,KAAA,CAAA,GAAY,EAAE,MAAA,EAAQ,OAAA,CAAQ,MAAA,EAAO,GAAI,EAAC;AAAA,QACjE,GAAI,KAAA,KAAU,KAAA,CAAA,GAAY,EAAE,KAAA,KAAU,EAAC;AAAA,QACvC,eAAA,EAAiB,OAAA,CAAQ,SAAA,IAAa,SAAA,CAAU,eAAA;AAAA,QAChD,GAAI,QAAQ,WAAA,KAAgB,KAAA,CAAA,GAAY,EAAE,WAAA,EAAa,OAAA,CAAQ,WAAA,EAAY,GAAI;AAAC,OACjF,CAAA;AAED,MAAA,WAAA,MAAiB,IAAA,IAAQ,OAAO,UAAA,EAAY;AAC1C,QAAA,IAAI,IAAA,CAAK,SAAS,YAAA,EAAc;AAC9B,UAAA,MAAM,EAAE,IAAA,EAAM,MAAA,EAAQ,OAAA,EAAS,KAAK,IAAA,EAAK;AAAA,QAC3C,CAAA,MAAA,IAAW,IAAA,CAAK,IAAA,KAAS,WAAA,EAAa;AACpC,UAAA,MAAM,CAAC,QAAQ,CAAA,GAAI,qBAAA,CAAsB,CAAC;AAAA,YACxC,YAAY,IAAA,CAAK,UAAA;AAAA,YACjB,UAAU,IAAA,CAAK,QAAA;AAAA,YACf,OAAO,IAAA,CAAK;AAAA,WACb,CAAC,CAAA;AACF,UAAA,IAAI,aAAa,KAAA,CAAA,EAAW;AAC1B,YAAA;AAAA,UACF;AACA,UAAA,MAAM,EAAE,IAAA,EAAM,WAAA,EAAa,QAAA,EAAS;AAAA,QACtC,CAAA,MAAA,IAAW,IAAA,CAAK,IAAA,KAAS,QAAA,EAAU;AACjC,UAAA,MAAM,KAAA,GAAQ,eAAA,CAAgB,SAAA,EAAW,IAAA,CAAK,UAAU,CAAA;AACxD,UAAA,MAAM,EAAE,IAAA,EAAM,OAAA,EAAS,KAAA,EAAM;AAAA,QAC/B,CAAA,MAAA,IAAW,IAAA,CAAK,IAAA,KAAS,OAAA,EAAS;AAChC,UAAA,MAAM,MAAA,GAAS,KAAK,KAAA,YAAiB,KAAA,GAAQ,KAAK,KAAA,CAAM,OAAA,GAAU,MAAA,CAAO,IAAA,CAAK,KAAK,CAAA;AACnF,UAAA,MAAM,EAAE,IAAA,EAAM,OAAA,EAAS,KAAA,EAAO,MAAA,EAAO;AAAA,QACvC;AAAA,MACF;AAEA,MAAA,MAAM,EAAE,MAAM,MAAA,EAAO;AAAA,IACvB,SAAS,KAAA,EAAgB;AACvB,MAAA,MAAM,SAAS,KAAA,YAAiB,KAAA,GAAQ,KAAA,CAAM,OAAA,GAAU,OAAO,KAAK,CAAA;AACpE,MAAA,MAAA,CAAO,KAAA,CAAM,EAAE,KAAA,EAAO,MAAA,EAAQ,OAAO,OAAA,CAAQ,KAAA,IAAS,qBAAqB,CAAA;AAC3E,MAAA,MAAM,EAAE,IAAA,EAAM,OAAA,EAAS,KAAA,EAAO,MAAA,EAAO;AACrC,MAAA,MAAM,EAAE,MAAM,MAAA,EAAO;AAAA,IACvB;AAAA,EACF;AAAA,EAEA,WAAA,CAAY,MAAc,MAAA,EAAiC;AACzD,IAAA,OAAO,QAAQ,OAAA,CAAQ,IAAA,CAAK,KAAK,IAAA,CAAK,MAAA,GAAS,wBAAwB,CAAC,CAAA;AAAA,EAC1E;AAAA,EAEA,aAAa,KAAA,EAA2B;AACtC,IAAA,MAAM,IAAA,GAAO,iBAAiB,KAAK,CAAA;AACnC,IAAA,IAAI,IAAA,KAAS,MAAA,IAAa,IAAA,CAAK,QAAA,KAAa,aAAA,EAAe;AACzD,MAAA,MAAM,IAAI,mBAAmB,KAAK,CAAA;AAAA,IACpC;AACA,IAAA,OAAO,IAAA;AAAA,EACT;AACF","file":"chunk-CTFZTARK.js","sourcesContent":["/**\r\n * Claude (Anthropic) adapter via Vercel AI SDK per PRD section 7.1\r\n * Supports Claude Opus 4.6, Sonnet 4.6, Haiku 4.5\r\n */\r\n\r\nimport { generateText, streamText } from \"ai\";\r\nimport { createAnthropic } from \"@ai-sdk/anthropic\";\r\nimport { logger } from \"../utils/logger.js\";\r\nimport {\r\n AuthenticationError,\r\n RateLimitError,\r\n ModelNotFoundError,\r\n} from \"../types/errors.js\";\r\nimport { SUPPORTED_MODELS } from \"../types/model.js\";\r\nimport type { IModelInfo, ProviderName } from \"../types/model.js\";\r\nimport type {\r\n IChatRequest,\r\n IChatResponse,\r\n IChatMessage,\r\n IStreamChunk,\r\n} from \"../types/message.js\";\r\nimport {\r\n buildAiSdkTools,\r\n buildModelMessages,\r\n buildTokenUsage,\r\n extractAiSdkToolCalls,\r\n mapAiSdkFinishReason,\r\n} from \"./ai-sdk-shared.js\";\r\nimport type { IModelProvider, IProviderOptions } from \"./types.js\";\r\n\r\nconst PROVIDER_NAME: ProviderName = \"anthropic\";\r\n\r\nconst CLAUDE_MODELS: readonly string[] = [\r\n \"claude-opus-4-6\",\r\n \"claude-opus-4-6-1m\",\r\n \"claude-sonnet-4-6\",\r\n \"claude-sonnet-4-6-1m\",\r\n \"claude-haiku-4-5\",\r\n] as const;\r\n\r\nconst CHARS_PER_TOKEN_ESTIMATE = 4;\r\n\r\nfunction mapRole(role: IChatMessage[\"role\"]): \"user\" | \"assistant\" | \"system\" | \"tool\" {\r\n switch (role) {\r\n case \"user\":\r\n return \"user\";\r\n case \"assistant\":\r\n return \"assistant\";\r\n case \"system\":\r\n return \"system\";\r\n case \"tool\":\r\n return \"tool\";\r\n default:\r\n return \"user\";\r\n }\r\n}\r\n\r\nfunction classifyError(error: unknown, model: string): never {\r\n const message = error instanceof Error ? error.message : String(error);\r\n const lower = message.toLowerCase();\r\n\r\n if (lower.includes(\"401\") || lower.includes(\"unauthorized\") || lower.includes(\"invalid api key\")) {\r\n throw new AuthenticationError(PROVIDER_NAME, message);\r\n }\r\n if (lower.includes(\"429\") || lower.includes(\"rate limit\") || lower.includes(\"too many requests\")) {\r\n const match = /(\\d+)\\s*s/i.exec(message);\r\n const retryMs = match?.[1] !== undefined ? parseInt(match[1], 10) * 1000 : 60_000;\r\n throw new RateLimitError(PROVIDER_NAME, retryMs);\r\n }\r\n if (lower.includes(\"model\") && lower.includes(\"not found\")) {\r\n throw new ModelNotFoundError(model);\r\n }\r\n\r\n throw error instanceof Error ? error : new Error(message);\r\n}\r\n\r\nexport class ClaudeAdapter implements IModelProvider {\r\n readonly name = PROVIDER_NAME;\r\n readonly supportedModels = CLAUDE_MODELS;\r\n readonly supportsToolCalling = true;\r\n\r\n private readonly anthropic: ReturnType<typeof createAnthropic>;\r\n\r\n constructor(options?: IProviderOptions) {\r\n const apiKey = options?.apiKey ?? process.env[\"ANTHROPIC_API_KEY\"];\r\n this.anthropic = createAnthropic({\r\n ...(apiKey !== undefined ? { apiKey } : {}),\r\n ...(options?.baseUrl !== undefined ? { baseURL: options.baseUrl } : {}),\r\n });\r\n }\r\n\r\n async chat(request: IChatRequest): Promise<IChatResponse> {\r\n const modelInfo = this.getModelInfo(request.model);\r\n const messages = buildModelMessages(request.messages, { mapRole });\r\n const tools = buildAiSdkTools(request.tools);\r\n\r\n try {\r\n const result = await generateText({\r\n model: this.anthropic(request.model),\r\n messages,\r\n ...(request.system !== undefined ? { system: request.system } : {}),\r\n ...(tools !== undefined ? { tools } : {}),\r\n maxOutputTokens: request.maxTokens ?? modelInfo.maxOutputTokens,\r\n ...(request.temperature !== undefined ? { temperature: request.temperature } : {}),\r\n });\r\n\r\n const toolCalls = extractAiSdkToolCalls(result.toolCalls);\r\n const usage = buildTokenUsage(modelInfo, result.usage);\r\n\r\n const responseMessage: IChatMessage = {\r\n id: result.response.id,\r\n role: \"assistant\",\r\n content: result.text,\r\n model: request.model,\r\n provider: PROVIDER_NAME,\r\n toolCalls: toolCalls.length > 0 ? toolCalls : undefined,\r\n tokenUsage: usage,\r\n createdAt: new Date(),\r\n };\r\n\r\n return {\r\n id: result.response.id,\r\n model: request.model,\r\n provider: PROVIDER_NAME,\r\n message: responseMessage,\r\n usage,\r\n finishReason: mapAiSdkFinishReason(result.finishReason, {\r\n stop: [\"end-turn\"],\r\n maxTokens: [\"max-tokens\"],\r\n }),\r\n };\r\n } catch (error: unknown) {\r\n classifyError(error, request.model);\r\n }\r\n }\r\n\r\n async *stream(request: IChatRequest): AsyncIterable<IStreamChunk> {\r\n const modelInfo = this.getModelInfo(request.model);\r\n const messages = buildModelMessages(request.messages, { mapRole });\r\n const tools = buildAiSdkTools(request.tools);\r\n\r\n try {\r\n const result = streamText({\r\n model: this.anthropic(request.model),\r\n messages,\r\n ...(request.system !== undefined ? { system: request.system } : {}),\r\n ...(tools !== undefined ? { tools } : {}),\r\n maxOutputTokens: request.maxTokens ?? modelInfo.maxOutputTokens,\r\n ...(request.temperature !== undefined ? { temperature: request.temperature } : {}),\r\n });\r\n\r\n for await (const part of result.fullStream) {\r\n if (part.type === \"text-delta\") {\r\n yield { type: \"text\", content: part.text };\r\n } else if (part.type === \"tool-call\") {\r\n const [toolCall] = extractAiSdkToolCalls([{\r\n toolCallId: part.toolCallId,\r\n toolName: part.toolName,\r\n input: part.input,\r\n }]);\r\n if (toolCall === undefined) {\r\n continue;\r\n }\r\n yield { type: \"tool_call\", toolCall };\r\n } else if (part.type === \"finish\") {\r\n const usage = buildTokenUsage(modelInfo, part.totalUsage);\r\n yield { type: \"usage\", usage };\r\n } else if (part.type === \"error\") {\r\n const errMsg = part.error instanceof Error ? part.error.message : String(part.error);\r\n yield { type: \"error\", error: errMsg };\r\n }\r\n }\r\n\r\n yield { type: \"done\" };\r\n } catch (error: unknown) {\r\n const errMsg = error instanceof Error ? error.message : String(error);\r\n logger.error({ error: errMsg, model: request.model }, \"Claude stream error\");\r\n yield { type: \"error\", error: errMsg };\r\n yield { type: \"done\" };\r\n }\r\n }\r\n\r\n countTokens(text: string, _model: string): Promise<number> {\r\n return Promise.resolve(Math.ceil(text.length / CHARS_PER_TOKEN_ESTIMATE));\r\n }\r\n\r\n getModelInfo(model: string): IModelInfo {\r\n const info = SUPPORTED_MODELS[model];\r\n if (info === undefined || info.provider !== PROVIDER_NAME) {\r\n throw new ModelNotFoundError(model);\r\n }\r\n return info;\r\n }\r\n}\r\n"]}
@@ -1 +0,0 @@
1
- {"version":3,"sources":["../src/providers/model-discovery.ts"],"names":[],"mappings":"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","file":"chunk-FIC7AK4Q.js","sourcesContent":["/**\r\n * Runtime model discovery — reads real model lists from provider CLIs\r\n * and user config. Merges with the hardcoded fallback registry.\r\n */\r\n\r\nimport { readFile } from \"node:fs/promises\";\r\nimport { dirname, join } from \"node:path\";\r\nimport { homedir } from \"node:os\";\r\nimport { existsSync } from \"node:fs\";\r\nimport { execa } from \"execa\";\r\nimport { logger } from \"../utils/logger.js\";\r\nimport { getAemeathHome } from \"../utils/pathResolver.js\";\r\nimport {\r\n SUPPORTED_MODELS,\r\n PROVIDER_MODEL_ORDER,\r\n type IModelInfo,\r\n type IModelDisplayEntry,\r\n type ProviderName,\r\n} from \"../types/model.js\";\r\n\r\n// ── Cache ────────────────────────────────────────────────────────────────\r\n\r\nlet discoveryComplete = false;\r\nconst dynamicModels: Record<string, IModelInfo> = {};\r\nconst dynamicDisplayOrder: Record<string, IModelDisplayEntry[]> = {};\r\n\r\n// ── Helper to create a model entry with defaults ────────────────────────\r\n\r\nfunction makeModelInfo(\r\n id: string,\r\n name: string,\r\n provider: ProviderName,\r\n description?: string,\r\n contextWindow?: number,\r\n): IModelInfo {\r\n return {\r\n id,\r\n name,\r\n provider,\r\n contextWindow: contextWindow ?? 200_000,\r\n maxOutputTokens: 16_384,\r\n inputPricePerMToken: 0,\r\n outputPricePerMToken: 0,\r\n supportsStreaming: true,\r\n supportsToolCalling: true,\r\n supportedRoles: [\"coding\"],\r\n description,\r\n };\r\n}\r\n\r\n// ── Codex (OpenAI) discovery ────────────────────────────────────────────\r\n\r\nasync function discoverCodexModels(): Promise<void> {\r\n // 1. Read user's current model from ~/.codex/config.toml\r\n const configPath = join(homedir(), \".codex\", \"config.toml\");\r\n let currentModel: string | undefined;\r\n try {\r\n const raw = await readFile(configPath, \"utf-8\");\r\n const match = raw.match(/^model\\s*=\\s*\"([^\"]+)\"/m);\r\n if (match?.[1]) {\r\n currentModel = match[1];\r\n }\r\n } catch {\r\n // No config file\r\n }\r\n\r\n // 2. Try to get the interactive model list via `codex model` (needs TTY, may fail)\r\n // Fallback: run `codex exec --help` and extract model references\r\n try {\r\n const { stdout } = await execa(\"codex\", [\"exec\", \"--help\"], {\r\n timeout: 5000,\r\n stdin: \"ignore\",\r\n env: { ...process.env, NO_COLOR: \"1\" },\r\n });\r\n // Extract model IDs from help text (e.g. model=\"o3\")\r\n const modelRefs = stdout.matchAll(/model=\"([^\"]+)\"/g);\r\n for (const m of modelRefs) {\r\n const id = m[1];\r\n if (id && !SUPPORTED_MODELS[id] && !dynamicModels[id]) {\r\n addModel(id, id, \"openai\");\r\n }\r\n }\r\n } catch {\r\n // Codex not installed\r\n }\r\n\r\n // 3. If the user's current model isn't in our list, add it\r\n if (currentModel && !SUPPORTED_MODELS[currentModel] && !dynamicModels[currentModel]) {\r\n addModel(currentModel, currentModel, \"openai\", `User's current Codex model`);\r\n }\r\n\r\n // 4. Probe for known recent Codex models that may not be in our hardcoded list\r\n const knownCodexModels = [\r\n { id: \"gpt-5.4\", name: \"GPT-5.4\", desc: \"Latest frontier agentic coding model\" },\r\n { id: \"gpt-5.4-mini\", name: \"GPT-5.4 Mini\", desc: \"Smaller frontier agentic coding model\" },\r\n { id: \"o3\", name: \"o3\", desc: \"OpenAI o3 reasoning model\" },\r\n { id: \"o4-mini\", name: \"o4-mini\", desc: \"OpenAI o4-mini reasoning model\" },\r\n ];\r\n for (const m of knownCodexModels) {\r\n if (!SUPPORTED_MODELS[m.id] && !dynamicModels[m.id]) {\r\n addModel(m.id, m.name, \"openai\", m.desc);\r\n }\r\n }\r\n}\r\n\r\n// ── Gemini (Google) discovery ───────────────────────────────────────────\r\n\r\nasync function discoverGeminiModels(): Promise<void> {\r\n // 1. Read the Gemini CLI's models.js source for VALID_GEMINI_MODELS\r\n const geminiModelsPath = await findGeminiModelsFile();\r\n if (geminiModelsPath) {\r\n try {\r\n const source = await readFile(geminiModelsPath, \"utf-8\");\r\n\r\n // Extract model IDs from export const statements and Set entries\r\n const modelMatches = source.matchAll(/['\"]([^'\"]*gemini[^'\"]+)['\"]/g);\r\n for (const m of modelMatches) {\r\n const id = m[1];\r\n if (\r\n id &&\r\n !id.includes(\"embedding\") &&\r\n !id.includes(\"auto-\") &&\r\n !id.includes(\"customtools\") &&\r\n !SUPPORTED_MODELS[id] &&\r\n !dynamicModels[id]\r\n ) {\r\n const name = id\r\n .replace(/-preview$/, \" Preview\")\r\n .replace(/-lite$/, \" Lite\")\r\n .split(\"-\")\r\n .map((s) => s.charAt(0).toUpperCase() + s.slice(1))\r\n .join(\" \");\r\n addModel(id, name, \"google\", undefined, 2_000_000);\r\n }\r\n }\r\n } catch {\r\n logger.debug(\"Failed to read Gemini CLI models source\");\r\n }\r\n }\r\n\r\n // 2. Fallback: probe known recent Gemini models\r\n const knownGeminiModels = [\r\n { id: \"gemini-3.1-pro-preview\", name: \"Gemini 3.1 Pro Preview\", desc: \"Latest Gemini Pro preview\" },\r\n { id: \"gemini-3.1-flash-lite-preview\", name: \"Gemini 3.1 Flash Lite Preview\", desc: \"Latest Flash Lite preview\" },\r\n { id: \"gemini-3-flash-preview\", name: \"Gemini 3 Flash Preview\", desc: \"Gemini 3 Flash preview\" },\r\n ];\r\n for (const m of knownGeminiModels) {\r\n if (!SUPPORTED_MODELS[m.id] && !dynamicModels[m.id]) {\r\n addModel(m.id, m.name, \"google\", m.desc, 2_000_000);\r\n }\r\n }\r\n}\r\n\r\n/** Find the Gemini CLI's models.js file in node_modules. */\r\nasync function findGeminiModelsFile(): Promise<string | undefined> {\r\n // Try to find via which gemini → resolve symlink → find models.js\r\n try {\r\n const { stdout } = await execa(\"which\", [\"gemini\"], {\r\n stdin: \"ignore\",\r\n timeout: 5_000,\r\n env: { ...process.env, NO_COLOR: \"1\" },\r\n });\r\n const whichResult = stdout.trim();\r\n if (whichResult) {\r\n // gemini binary is at e.g. /Users/x/.nvm/versions/node/v22.18.0/bin/gemini\r\n // models.js is at .../lib/node_modules/@google/gemini-cli/node_modules/@google/gemini-cli-core/dist/src/config/models.js\r\n const binDir = dirname(whichResult);\r\n const modelsPath = join(\r\n binDir,\r\n \"..\",\r\n \"lib\",\r\n \"node_modules\",\r\n \"@google\",\r\n \"gemini-cli\",\r\n \"node_modules\",\r\n \"@google\",\r\n \"gemini-cli-core\",\r\n \"dist\",\r\n \"src\",\r\n \"config\",\r\n \"models.js\",\r\n );\r\n if (existsSync(modelsPath)) {\r\n return modelsPath;\r\n }\r\n }\r\n } catch {\r\n // which not available or gemini not installed\r\n }\r\n\r\n return undefined;\r\n}\r\n\r\n// ── Claude (Anthropic) discovery ────────────────────────────────────────\r\n\r\nasync function discoverClaudeModels(): Promise<void> {\r\n // Claude models are well-known and change infrequently.\r\n // The hardcoded list is accurate. Just verify claude CLI exists.\r\n try {\r\n await execa(\"claude\", [\"--version\"], {\r\n timeout: 5000,\r\n stdin: \"ignore\",\r\n env: { ...process.env, NO_COLOR: \"1\" },\r\n });\r\n } catch {\r\n logger.debug(\"Claude CLI not available\");\r\n }\r\n}\r\n\r\n// ── User-defined models from ~/.aemeathcli/models.json ─────────────────\r\n\r\ninterface IUserModelEntry {\r\n readonly id: string;\r\n readonly name: string;\r\n readonly provider: string;\r\n readonly description?: string;\r\n readonly contextWindow?: number;\r\n}\r\n\r\nasync function loadUserModels(): Promise<void> {\r\n const modelsPath = join(getAemeathHome(), \"models.json\");\r\n try {\r\n const raw = await readFile(modelsPath, \"utf-8\");\r\n const parsed = JSON.parse(raw) as unknown;\r\n if (!Array.isArray(parsed)) return;\r\n\r\n for (const entry of parsed) {\r\n if (\r\n typeof entry === \"object\" &&\r\n entry !== null &&\r\n typeof (entry as IUserModelEntry).id === \"string\" &&\r\n typeof (entry as IUserModelEntry).name === \"string\" &&\r\n typeof (entry as IUserModelEntry).provider === \"string\"\r\n ) {\r\n const e = entry as IUserModelEntry;\r\n addModel(\r\n e.id,\r\n e.name,\r\n e.provider as ProviderName,\r\n e.description,\r\n e.contextWindow,\r\n );\r\n }\r\n }\r\n } catch {\r\n // File doesn't exist or invalid\r\n }\r\n}\r\n\r\n// ── Internal helpers ────────────────────────────────────────────────────\r\n\r\nfunction addModel(\r\n id: string,\r\n name: string,\r\n provider: ProviderName,\r\n description?: string,\r\n contextWindow?: number,\r\n): void {\r\n dynamicModels[id] = makeModelInfo(id, name, provider, description, contextWindow);\r\n\r\n if (!dynamicDisplayOrder[provider]) {\r\n dynamicDisplayOrder[provider] = [];\r\n }\r\n if (!dynamicDisplayOrder[provider].some((e) => e.id === id)) {\r\n dynamicDisplayOrder[provider].push({\r\n id,\r\n label: name,\r\n description: description ?? \"\",\r\n });\r\n }\r\n}\r\n\r\n// ── Public API ──────────────────────────────────────────────────────────\r\n\r\nexport async function discoverModels(): Promise<void> {\r\n if (discoveryComplete) return;\r\n\r\n await Promise.allSettled([\r\n loadUserModels(),\r\n discoverClaudeModels(),\r\n discoverCodexModels(),\r\n discoverGeminiModels(),\r\n ]);\r\n\r\n discoveryComplete = true;\r\n const count = Object.keys(dynamicModels).length;\r\n if (count > 0) {\r\n logger.info({ count }, \"Discovered additional models at runtime\");\r\n }\r\n}\r\n\r\nexport function registerModel(model: IModelInfo): void {\r\n dynamicModels[model.id] = model;\r\n const provider = model.provider;\r\n if (!dynamicDisplayOrder[provider]) {\r\n dynamicDisplayOrder[provider] = [];\r\n }\r\n if (!dynamicDisplayOrder[provider].some((e) => e.id === model.id)) {\r\n dynamicDisplayOrder[provider].push({\r\n id: model.id,\r\n label: model.name,\r\n description: model.description ?? \"\",\r\n });\r\n }\r\n}\r\n\r\nexport function getModelInfo(modelId: string): IModelInfo | undefined {\r\n return dynamicModels[modelId] ?? SUPPORTED_MODELS[modelId];\r\n}\r\n\r\nexport function getAllModels(): Record<string, IModelInfo> {\r\n return { ...SUPPORTED_MODELS, ...dynamicModels };\r\n}\r\n\r\nexport function getDisplayOrder(): Record<string, readonly IModelDisplayEntry[]> {\r\n const result: Record<string, IModelDisplayEntry[]> = {};\r\n\r\n for (const [provider, entries] of Object.entries(PROVIDER_MODEL_ORDER)) {\r\n result[provider] = [...entries];\r\n }\r\n\r\n // Prepend dynamic models to their provider group (new models show at top)\r\n for (const [provider, entries] of Object.entries(dynamicDisplayOrder)) {\r\n if (!result[provider]) {\r\n result[provider] = [];\r\n }\r\n for (const entry of entries) {\r\n if (!result[provider].some((e) => e.id === entry.id)) {\r\n result[provider].unshift(entry);\r\n }\r\n }\r\n }\r\n\r\n return result;\r\n}\r\n\r\nexport function isKnownModel(modelId: string): boolean {\r\n return modelId in SUPPORTED_MODELS || modelId in dynamicModels;\r\n}\r\n"]}
@@ -1 +0,0 @@
1
- {"version":3,"sources":["../src/core/model-router.ts"],"names":[],"mappings":"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","file":"chunk-GU33WKPG.js","sourcesContent":["/**\r\n * Role-based model selection per PRD section 7.2\r\n * Resolution pipeline: user override → role config → fallback chain → system default\r\n */\r\n\r\nimport type {\r\n ModelRole,\r\n IModelResolution,\r\n IRoleConfig,\r\n IGlobalConfig,\r\n ProviderName,\r\n IModelInfo,\r\n} from \"../types/index.js\";\r\nimport { SUPPORTED_MODELS, ModelNotFoundError } from \"../types/index.js\";\r\nimport { logger } from \"../utils/index.js\";\r\n\r\nexport interface IModelRouterConfig {\r\n readonly defaultModel: string;\r\n readonly roles: Partial<Record<ModelRole, IRoleConfig>>;\r\n readonly enabledProviders: readonly ProviderName[];\r\n}\r\n\r\nexport class ModelRouter {\r\n private readonly config: IModelRouterConfig;\r\n private userOverride: string | undefined;\r\n\r\n constructor(config: IModelRouterConfig) {\r\n this.config = config;\r\n }\r\n\r\n /**\r\n * Set a temporary user override that takes highest priority.\r\n */\r\n setUserOverride(modelId: string | undefined): void {\r\n if (modelId !== undefined) {\r\n this.validateModel(modelId);\r\n }\r\n this.userOverride = modelId;\r\n }\r\n\r\n /**\r\n * Resolve the best model for a given role through the priority pipeline.\r\n */\r\n resolve(role?: ModelRole): IModelResolution {\r\n // 1. User override (explicit flag: --model claude-opus-4-6)\r\n if (this.userOverride) {\r\n const info = this.getModelInfo(this.userOverride);\r\n return {\r\n modelId: this.userOverride,\r\n provider: info.provider,\r\n source: \"user_override\",\r\n role,\r\n };\r\n }\r\n\r\n // 2. Role config\r\n if (role) {\r\n const roleConfig = this.config.roles[role];\r\n if (roleConfig) {\r\n // Try primary model\r\n if (this.isModelAvailable(roleConfig.primary)) {\r\n const info = this.getModelInfo(roleConfig.primary);\r\n return {\r\n modelId: roleConfig.primary,\r\n provider: info.provider,\r\n source: \"role_config\",\r\n role,\r\n };\r\n }\r\n\r\n // 3. Fallback chain\r\n for (const fallbackModel of roleConfig.fallback) {\r\n if (this.isModelAvailable(fallbackModel)) {\r\n const info = this.getModelInfo(fallbackModel);\r\n logger.info(\r\n { role, primary: roleConfig.primary, fallback: fallbackModel },\r\n \"Using fallback model for role\",\r\n );\r\n return {\r\n modelId: fallbackModel,\r\n provider: info.provider,\r\n source: \"fallback_chain\",\r\n role,\r\n };\r\n }\r\n }\r\n }\r\n }\r\n\r\n // 4. System default\r\n const defaultModel = this.config.defaultModel;\r\n if (this.isModelAvailable(defaultModel)) {\r\n const info = this.getModelInfo(defaultModel);\r\n return {\r\n modelId: defaultModel,\r\n provider: info.provider,\r\n source: \"system_default\",\r\n role,\r\n };\r\n }\r\n\r\n // Last resort: find any available model\r\n const anyAvailable = this.getAvailableModels()[0];\r\n if (anyAvailable) {\r\n return {\r\n modelId: anyAvailable.id,\r\n provider: anyAvailable.provider,\r\n source: \"system_default\",\r\n role,\r\n };\r\n }\r\n\r\n throw new ModelNotFoundError(defaultModel);\r\n }\r\n\r\n /**\r\n * Check if a model is available (provider is enabled and model is known).\r\n */\r\n isModelAvailable(modelId: string): boolean {\r\n const info = SUPPORTED_MODELS[modelId];\r\n if (!info) {\r\n return false;\r\n }\r\n return this.config.enabledProviders.includes(info.provider);\r\n }\r\n\r\n /**\r\n * Get model info by ID. Throws if not found.\r\n */\r\n getModelInfo(modelId: string): IModelInfo {\r\n const info = SUPPORTED_MODELS[modelId];\r\n if (!info) {\r\n throw new ModelNotFoundError(modelId);\r\n }\r\n return info;\r\n }\r\n\r\n /**\r\n * Get all available models (from enabled providers).\r\n */\r\n getAvailableModels(): readonly IModelInfo[] {\r\n return Object.values(SUPPORTED_MODELS).filter((model) =>\r\n this.config.enabledProviders.includes(model.provider),\r\n );\r\n }\r\n\r\n /**\r\n * List models recommended for a specific role.\r\n */\r\n getModelsForRole(role: ModelRole): readonly IModelInfo[] {\r\n return this.getAvailableModels().filter((model) =>\r\n model.supportedRoles.includes(role),\r\n );\r\n }\r\n\r\n /**\r\n * Validate that a model ID exists. Throws ModelNotFoundError if not.\r\n */\r\n private validateModel(modelId: string): void {\r\n if (!SUPPORTED_MODELS[modelId]) {\r\n throw new ModelNotFoundError(modelId);\r\n }\r\n }\r\n}\r\n\r\n/**\r\n * Create a ModelRouter from the global config.\r\n */\r\nexport function createModelRouter(config: IGlobalConfig): ModelRouter {\r\n const enabledProviders = Object.entries(config.providers)\r\n .filter(([, providerConfig]) => providerConfig.enabled)\r\n .map(([name]) => name as ProviderName);\r\n\r\n return new ModelRouter({\r\n defaultModel: config.defaultModel,\r\n roles: config.roles,\r\n enabledProviders,\r\n });\r\n}\r\n"]}
@@ -1 +0,0 @@
1
- {"version":3,"sources":["../src/auth/session-manager.ts"],"names":[],"mappings":"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","file":"chunk-H2SYKIMI.js","sourcesContent":["/**\r\n * Multi-provider session lifecycle per PRD section 13.5\r\n * Resolution priority: native login (CLI delegation) > API key > env variable > credential helper\r\n *\r\n * Credentials are obtained by delegating to official CLI tools:\r\n * - Claude Code CLI → macOS Keychain\r\n * - Codex CLI → ~/.codex/auth.json\r\n * - Gemini CLI → ~/.gemini/oauth_creds.json\r\n * - Kimi CLI → ~/.kimi/credentials/kimi-code.json\r\n */\r\n\r\nimport type { ProviderName, ICredential, AuthMethod } from \"../types/index.js\";\r\nimport { AuthenticationError } from \"../types/index.js\";\r\nimport { CredentialStore } from \"./credential-store.js\";\r\nimport { ApiKeyFallback } from \"./api-key-fallback.js\";\r\nimport { logger } from \"../utils/index.js\";\r\n\r\nexport class SessionManager {\r\n private readonly credentialStore: CredentialStore;\r\n private readonly apiKeyFallback: ApiKeyFallback;\r\n\r\n constructor(store?: CredentialStore) {\r\n this.credentialStore = store ?? new CredentialStore();\r\n this.apiKeyFallback = new ApiKeyFallback(this.credentialStore);\r\n }\r\n\r\n /**\r\n * Get the best available credential for a provider.\r\n * Follows resolution priority from PRD section 13.5.\r\n */\r\n async getActiveCredential(provider: ProviderName): Promise<ICredential> {\r\n // 1. Native account session (delegated CLI login — stored in our credential store)\r\n const nativeCredential = await this.credentialStore.get(provider);\r\n if (nativeCredential && nativeCredential.method === \"native_login\" && !this.isExpired(nativeCredential)) {\r\n return nativeCredential;\r\n }\r\n\r\n // 1b. If expired, try re-reading from the official CLI's cached tokens\r\n if (nativeCredential && nativeCredential.method === \"native_login\" && this.isExpired(nativeCredential)) {\r\n const refreshed = await this.refreshFromCliCache(provider);\r\n if (refreshed) {\r\n return refreshed;\r\n }\r\n }\r\n\r\n // 1c. Even if no native credential stored, check CLI caches directly\r\n if (!nativeCredential || nativeCredential.method !== \"native_login\") {\r\n const fromCli = await this.refreshFromCliCache(provider);\r\n if (fromCli) {\r\n return fromCli;\r\n }\r\n }\r\n\r\n // 2. API key set via auth set-key\r\n const apiKeyCredential = await this.apiKeyFallback.getCredential(provider);\r\n if (apiKeyCredential) {\r\n return apiKeyCredential;\r\n }\r\n\r\n // 3. Environment variable\r\n const envCredential = this.getFromEnvironment(provider);\r\n if (envCredential) {\r\n return envCredential;\r\n }\r\n\r\n throw new AuthenticationError(provider, `No credentials found for ${provider}`);\r\n }\r\n\r\n /**\r\n * Check if a provider has any available credential.\r\n */\r\n async isAuthenticated(provider: ProviderName): Promise<boolean> {\r\n try {\r\n await this.getActiveCredential(provider);\r\n return true;\r\n } catch {\r\n return false;\r\n }\r\n }\r\n\r\n /**\r\n * Get status info for a provider.\r\n */\r\n async getStatus(provider: ProviderName): Promise<{\r\n loggedIn: boolean;\r\n method?: AuthMethod | undefined;\r\n email?: string | undefined;\r\n plan?: string | undefined;\r\n }> {\r\n try {\r\n const credential = await this.getActiveCredential(provider);\r\n return {\r\n loggedIn: true,\r\n method: credential.method,\r\n ...(credential.email !== undefined ? { email: credential.email } : {}),\r\n ...(credential.plan !== undefined ? { plan: credential.plan } : {}),\r\n };\r\n } catch {\r\n return { loggedIn: false };\r\n }\r\n }\r\n\r\n /**\r\n * Get the API key or token string for a provider.\r\n */\r\n async getToken(provider: ProviderName): Promise<string> {\r\n const credential = await this.getActiveCredential(provider);\r\n if (!credential.token) {\r\n throw new AuthenticationError(provider, \"Credential has no token\");\r\n }\r\n return credential.token;\r\n }\r\n\r\n /**\r\n * Re-read tokens from the official CLI's cached storage.\r\n * This is the \"refresh\" mechanism — instead of doing HTTP refresh ourselves,\r\n * we re-read from the CLI tool's cache which may have been refreshed by the CLI.\r\n */\r\n private async refreshFromCliCache(provider: ProviderName): Promise<ICredential | undefined> {\r\n try {\r\n const loginModule = await this.loadLoginModule(provider);\r\n if (!loginModule) {\r\n return undefined;\r\n }\r\n\r\n // Prefer direct cached credential extraction from the provider login module.\r\n if (typeof loginModule.getCachedCredential === \"function\") {\r\n const cached = await loginModule.getCachedCredential();\r\n if (cached) {\r\n await this.credentialStore.set(provider, cached);\r\n if (!this.isExpired(cached) || cached.refreshToken !== undefined) {\r\n logger.info({ provider }, \"Loaded credentials from provider CLI cache\");\r\n return cached;\r\n }\r\n }\r\n }\r\n\r\n const status = await loginModule.getStatus();\r\n if (!status.loggedIn) {\r\n return undefined;\r\n }\r\n\r\n // The login module reads from the CLI's cache, check if we can get a fresh credential\r\n const isStillLoggedIn = await loginModule.isLoggedIn();\r\n if (!isStillLoggedIn) {\r\n return undefined;\r\n }\r\n\r\n // Re-read by checking the stored credential in our store\r\n // The login modules update the credential store when they find valid tokens\r\n const credential = await this.credentialStore.get(provider);\r\n if (credential && !this.isExpired(credential)) {\r\n logger.info({ provider }, \"Refreshed credentials from CLI cache\");\r\n return credential;\r\n }\r\n\r\n return undefined;\r\n } catch (error: unknown) {\r\n const msg = error instanceof Error ? error.message : String(error);\r\n logger.debug({ provider, error: msg }, \"Failed to refresh from CLI cache\");\r\n return undefined;\r\n }\r\n }\r\n\r\n private async loadLoginModule(provider: ProviderName): Promise<{\r\n getStatus(): Promise<{ loggedIn: boolean; email?: string | undefined; plan?: string | undefined }>;\r\n isLoggedIn(): Promise<boolean>;\r\n getCachedCredential?(): Promise<ICredential | undefined>;\r\n } | undefined> {\r\n try {\r\n switch (provider) {\r\n case \"anthropic\": {\r\n const mod = await import(\"./providers/claude-login.js\");\r\n return new mod.ClaudeLogin(this.credentialStore);\r\n }\r\n case \"openai\": {\r\n const mod = await import(\"./providers/codex-login.js\");\r\n return new mod.CodexLogin(this.credentialStore);\r\n }\r\n case \"google\": {\r\n const mod = await import(\"./providers/gemini-login.js\");\r\n return new mod.GeminiLogin(this.credentialStore);\r\n }\r\n case \"kimi\": {\r\n const mod = await import(\"./providers/kimi-login.js\");\r\n return new mod.KimiLogin(this.credentialStore);\r\n }\r\n default:\r\n return undefined;\r\n }\r\n } catch {\r\n return undefined;\r\n }\r\n }\r\n\r\n private isExpired(credential: ICredential): boolean {\r\n if (!credential.expiresAt) {\r\n return false;\r\n }\r\n return new Date() > credential.expiresAt;\r\n }\r\n\r\n private getFromEnvironment(provider: ProviderName): ICredential | undefined {\r\n const envMap: Record<ProviderName, string> = {\r\n anthropic: \"ANTHROPIC_API_KEY\",\r\n openai: \"OPENAI_API_KEY\",\r\n google: \"GOOGLE_API_KEY\",\r\n kimi: \"MOONSHOT_API_KEY\",\r\n ollama: \"\",\r\n };\r\n\r\n const envKey = envMap[provider];\r\n if (!envKey) {\r\n return undefined;\r\n }\r\n\r\n const token = process.env[envKey];\r\n if (!token) {\r\n return undefined;\r\n }\r\n\r\n return {\r\n provider,\r\n method: \"env_variable\",\r\n token,\r\n };\r\n }\r\n}\r\n"]}
@@ -1 +0,0 @@
1
- {"version":3,"sources":["../src/utils/logger.ts"],"names":[],"mappings":";;;;;;AAUA,IAAM,OAAA,GAAU,IAAA,CAAK,OAAA,EAAQ,EAAG,eAAe,MAAM,CAAA;AAErD,SAAS,YAAA,GAAqB;AAC5B,EAAA,IAAI;AACF,IAAA,SAAA,CAAU,SAAS,EAAE,SAAA,EAAW,IAAA,EAAM,IAAA,EAAM,KAAO,CAAA;AAAA,EACrD,CAAA,CAAA,MAAQ;AAAA,EAER;AACF;AAGA,IAAM,YAAA,GAAe;AAAA,EACnB,OAAA;AAAA,EACA,cAAA;AAAA,EACA,QAAA;AAAA,EACA,aAAA;AAAA,EACA,cAAA;AAAA,EACA,UAAA;AAAA,EACA,QAAA;AAAA,EACA,eAAA;AAAA,EACA,QAAA;AAAA,EACA,SAAA;AAAA,EACA,gBAAA;AAAA,EACA,UAAA;AAAA,EACA,eAAA;AAAA,EACA,gBAAA;AAAA,EACA,YAAA;AAAA,EACA;AACF,CAAA;AAEA,YAAA,EAAa;AAEb,IAAM,SAAS,IAAA,CAAK;AAAA,EAClB,IAAA,EAAM,YAAA;AAAA,EACN,KAAA,EAAO,OAAA,CAAQ,GAAA,CAAI,sBAAsB,CAAA,IAAK,OAAA;AAAA,EAC9C,MAAA,EAAQ;AAAA,IACN,KAAA,EAAO,YAAA;AAAA,IACP,MAAA,EAAQ;AAAA,GACV;AAAA,EACA,GAAI,OAAA,CAAQ,GAAA,CAAI,UAAU,MAAM,aAAA,GAC5B;AAAA,IACE,SAAA,EAAW;AAAA,MACT,MAAA,EAAQ,WAAA;AAAA,MACR,OAAA,EAAS,EAAE,WAAA,EAAa,IAAA,CAAK,SAAS,gBAAgB,CAAA,EAAG,OAAO,IAAA;AAAK;AACvE,MAEF,EAAC;AAAA,EACL,SAAA,EAAW,KAAK,gBAAA,CAAiB;AACnC,CAAC","file":"chunk-HEKFAKVH.js","sourcesContent":["/**\r\n * Structured logging via pino per PRD section 16.1\r\n * Automatic credential redaction per PRD section 14.1\r\n */\r\n\r\nimport pino from \"pino\";\r\nimport { homedir } from \"node:os\";\r\nimport { join } from \"node:path\";\r\nimport { mkdirSync } from \"node:fs\";\r\n\r\nconst LOG_DIR = join(homedir(), \".aemeathcli\", \"logs\");\r\n\r\nfunction ensureLogDir(): void {\r\n try {\r\n mkdirSync(LOG_DIR, { recursive: true, mode: 0o700 });\r\n } catch {\r\n // Log dir creation failed — fall back to stderr only\r\n }\r\n}\r\n\r\n// Redaction patterns for credentials (PRD section 14.2 REQ-CRED-04)\r\nconst REDACT_PATHS = [\r\n \"token\",\r\n \"refreshToken\",\r\n \"apiKey\",\r\n \"accessToken\",\r\n \"sessionToken\",\r\n \"password\",\r\n \"secret\",\r\n \"authorization\",\r\n \"cookie\",\r\n \"*.token\",\r\n \"*.refreshToken\",\r\n \"*.apiKey\",\r\n \"*.accessToken\",\r\n \"*.sessionToken\",\r\n \"*.password\",\r\n \"*.secret\",\r\n];\r\n\r\nensureLogDir();\r\n\r\nconst logger = pino({\r\n name: \"aemeathcli\",\r\n level: process.env[\"AEMEATHCLI_LOG_LEVEL\"] ?? \"error\",\r\n redact: {\r\n paths: REDACT_PATHS,\r\n censor: \"[REDACTED]\",\r\n },\r\n ...(process.env[\"NODE_ENV\"] === \"development\"\r\n ? {\r\n transport: {\r\n target: \"pino/file\",\r\n options: { destination: join(LOG_DIR, \"aemeathcli.log\"), mkdir: true },\r\n },\r\n }\r\n : {}),\r\n timestamp: pino.stdTimeFunctions.isoTime,\r\n});\r\n\r\nexport { logger };\r\n"]}
@@ -1 +0,0 @@
1
- {"version":3,"sources":["../src/storage/migrations/001-initial.ts","../src/storage/sqlite-store.ts"],"names":[],"mappings":"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","file":"chunk-IARA5XYP.js","sourcesContent":["/**\r\n * Initial database migration — PRD section 17.1\r\n * Creates all core tables and indexes for AemeathCLI persistence.\r\n *\r\n * SAFETY: All DDL is static SQL. No user input is interpolated.\r\n */\r\n\r\nimport type Database from \"better-sqlite3\";\r\n\r\nconst MIGRATION_ID = \"001-initial\";\r\n\r\nconst CREATE_CONVERSATIONS = `\r\nCREATE TABLE IF NOT EXISTS conversations (\r\n id TEXT PRIMARY KEY,\r\n project_root TEXT NOT NULL,\r\n default_model TEXT,\r\n created_at TEXT DEFAULT (datetime('now')),\r\n updated_at TEXT DEFAULT (datetime('now')),\r\n metadata TEXT DEFAULT '{}'\r\n)`;\r\n\r\nconst CREATE_MESSAGES = `\r\nCREATE TABLE IF NOT EXISTS messages (\r\n id INTEGER PRIMARY KEY AUTOINCREMENT,\r\n conversation_id TEXT NOT NULL REFERENCES conversations(id) ON DELETE CASCADE,\r\n role TEXT NOT NULL,\r\n model TEXT,\r\n provider TEXT,\r\n content TEXT NOT NULL,\r\n tool_calls TEXT,\r\n token_usage TEXT,\r\n created_at TEXT DEFAULT (datetime('now'))\r\n)`;\r\n\r\nconst CREATE_FILE_CONTEXT = `\r\nCREATE TABLE IF NOT EXISTS file_context (\r\n id INTEGER PRIMARY KEY AUTOINCREMENT,\r\n conversation_id TEXT NOT NULL REFERENCES conversations(id) ON DELETE CASCADE,\r\n file_path TEXT NOT NULL,\r\n content_hash TEXT,\r\n token_count INTEGER,\r\n added_at TEXT DEFAULT (datetime('now'))\r\n)`;\r\n\r\nconst CREATE_COST_TRACKING = `\r\nCREATE TABLE IF NOT EXISTS cost_tracking (\r\n id INTEGER PRIMARY KEY AUTOINCREMENT,\r\n conversation_id TEXT NOT NULL REFERENCES conversations(id) ON DELETE CASCADE,\r\n provider TEXT NOT NULL,\r\n model TEXT NOT NULL,\r\n role TEXT,\r\n input_tokens INTEGER,\r\n output_tokens INTEGER,\r\n cost_usd REAL,\r\n created_at TEXT DEFAULT (datetime('now'))\r\n)`;\r\n\r\nconst CREATE_TEAMS = `\r\nCREATE TABLE IF NOT EXISTS teams (\r\n id TEXT PRIMARY KEY,\r\n name TEXT NOT NULL,\r\n status TEXT DEFAULT 'active',\r\n config TEXT,\r\n created_at TEXT DEFAULT (datetime('now'))\r\n)`;\r\n\r\nconst CREATE_INDEXES = [\r\n \"CREATE INDEX IF NOT EXISTS idx_messages_conversation ON messages(conversation_id)\",\r\n \"CREATE INDEX IF NOT EXISTS idx_cost_conversation ON cost_tracking(conversation_id)\",\r\n \"CREATE INDEX IF NOT EXISTS idx_cost_provider ON cost_tracking(provider)\",\r\n \"CREATE INDEX IF NOT EXISTS idx_file_context_conversation ON file_context(conversation_id)\",\r\n] as const;\r\n\r\nconst DROP_INDEXES = [\r\n \"DROP INDEX IF EXISTS idx_file_context_conversation\",\r\n \"DROP INDEX IF EXISTS idx_cost_provider\",\r\n \"DROP INDEX IF EXISTS idx_cost_conversation\",\r\n \"DROP INDEX IF EXISTS idx_messages_conversation\",\r\n] as const;\r\n\r\nconst DROP_TABLES = [\r\n \"DROP TABLE IF EXISTS cost_tracking\",\r\n \"DROP TABLE IF EXISTS file_context\",\r\n \"DROP TABLE IF EXISTS messages\",\r\n \"DROP TABLE IF EXISTS teams\",\r\n \"DROP TABLE IF EXISTS conversations\",\r\n] as const;\r\n\r\nexport function up(db: Database.Database): void {\r\n db.transaction(() => {\r\n db.exec(CREATE_CONVERSATIONS);\r\n db.exec(CREATE_MESSAGES);\r\n db.exec(CREATE_FILE_CONTEXT);\r\n db.exec(CREATE_COST_TRACKING);\r\n db.exec(CREATE_TEAMS);\r\n\r\n for (const sql of CREATE_INDEXES) {\r\n db.exec(sql);\r\n }\r\n })();\r\n}\r\n\r\nexport function down(db: Database.Database): void {\r\n db.transaction(() => {\r\n for (const sql of DROP_INDEXES) {\r\n db.exec(sql);\r\n }\r\n for (const sql of DROP_TABLES) {\r\n db.exec(sql);\r\n }\r\n })();\r\n}\r\n\r\nexport { MIGRATION_ID };\r\n","/**\r\n * SQLite database store — PRD section 17.1\r\n * Uses better-sqlite3 with WAL mode for concurrent reads.\r\n * Runs migrations on startup. Provides raw query interface.\r\n */\r\n\r\nimport Database from \"better-sqlite3\";\r\nimport { chmodSync } from \"node:fs\";\r\nimport { logger } from \"../utils/logger.js\";\r\nimport {\r\n getDatabasePath,\r\n getDatabaseDir,\r\n ensureDirectory,\r\n} from \"../utils/pathResolver.js\";\r\nimport { up as initialMigrationUp } from \"./migrations/001-initial.js\";\r\n\r\nconst MIGRATIONS_TABLE_DDL = `\r\nCREATE TABLE IF NOT EXISTS _migrations (\r\n id TEXT PRIMARY KEY,\r\n applied_at TEXT DEFAULT (datetime('now'))\r\n)`;\r\n\r\ninterface IMigration {\r\n readonly id: string;\r\n readonly up: (db: Database.Database) => void;\r\n}\r\n\r\nconst MIGRATIONS: readonly IMigration[] = [\r\n { id: \"001-initial\", up: initialMigrationUp },\r\n] as const;\r\n\r\nexport class SqliteStore {\r\n private db: Database.Database | undefined;\r\n private closed = false;\r\n\r\n get database(): Database.Database {\r\n if (this.closed || !this.db) {\r\n throw new Error(\"SqliteStore is closed or not initialized\");\r\n }\r\n return this.db;\r\n }\r\n\r\n open(dbPath?: string): void {\r\n if (this.db) {\r\n return;\r\n }\r\n\r\n const resolvedPath = dbPath ?? getDatabasePath();\r\n ensureDirectory(getDatabaseDir());\r\n\r\n logger.info({ path: resolvedPath }, \"Opening SQLite database\");\r\n\r\n this.db = new Database(resolvedPath);\r\n\r\n // WAL mode for concurrent reads (PRD section 17.1)\r\n this.db.pragma(\"journal_mode = WAL\");\r\n this.db.pragma(\"busy_timeout = 5000\");\r\n this.db.pragma(\"foreign_keys = ON\");\r\n this.db.pragma(\"synchronous = NORMAL\");\r\n\r\n // Secure file permissions (PRD section 14.1)\r\n try {\r\n chmodSync(resolvedPath, 0o600);\r\n } catch {\r\n logger.warn(\r\n { path: resolvedPath },\r\n \"Could not set database file permissions to 600\",\r\n );\r\n }\r\n\r\n this.runMigrations();\r\n this.registerCleanupHandlers();\r\n }\r\n\r\n private runMigrations(): void {\r\n const db = this.database;\r\n db.exec(MIGRATIONS_TABLE_DDL);\r\n\r\n const appliedStmt = db.prepare(\r\n \"SELECT id FROM _migrations WHERE id = ?\",\r\n );\r\n\r\n const insertStmt = db.prepare(\r\n \"INSERT INTO _migrations (id) VALUES (?)\",\r\n );\r\n\r\n for (const migration of MIGRATIONS) {\r\n const existing = appliedStmt.get(migration.id) as\r\n | { id: string }\r\n | undefined;\r\n\r\n if (!existing) {\r\n logger.info({ migrationId: migration.id }, \"Running migration\");\r\n db.transaction(() => {\r\n migration.up(db);\r\n insertStmt.run(migration.id);\r\n })();\r\n logger.info({ migrationId: migration.id }, \"Migration applied\");\r\n }\r\n }\r\n }\r\n\r\n prepare(sql: string): Database.Statement {\r\n return this.database.prepare(sql);\r\n }\r\n\r\n run(sql: string, ...params: readonly unknown[]): Database.RunResult {\r\n return this.database.prepare(sql).run(...params);\r\n }\r\n\r\n get(sql: string, ...params: unknown[]): unknown {\r\n return this.database.prepare(sql).get(...params);\r\n }\r\n\r\n all(sql: string, ...params: unknown[]): unknown[] {\r\n return this.database.prepare(sql).all(...params);\r\n }\r\n\r\n transaction<T>(fn: () => T): T {\r\n return this.database.transaction(fn)();\r\n }\r\n\r\n close(): void {\r\n if (this.closed || !this.db) {\r\n return;\r\n }\r\n\r\n logger.info(\"Closing SQLite database\");\r\n this.closed = true;\r\n\r\n try {\r\n this.db.pragma(\"wal_checkpoint(TRUNCATE)\");\r\n this.db.close();\r\n } catch (error: unknown) {\r\n const message =\r\n error instanceof Error ? error.message : String(error);\r\n logger.error({ error: message }, \"Error closing database\");\r\n }\r\n\r\n this.db = undefined;\r\n }\r\n\r\n private registerCleanupHandlers(): void {\r\n const cleanup = (): void => {\r\n this.close();\r\n };\r\n\r\n process.on(\"exit\", cleanup);\r\n process.on(\"SIGINT\", () => {\r\n cleanup();\r\n process.exit(130);\r\n });\r\n process.on(\"SIGTERM\", () => {\r\n cleanup();\r\n process.exit(143);\r\n });\r\n }\r\n}\r\n"]}
@@ -1 +0,0 @@
1
- {"version":3,"sources":["../src/teams/agent-process.ts","../src/teams/message-bus.ts","../src/teams/task-store.ts","../src/teams/plan-approval.ts","../src/teams/team-manager.ts"],"names":["randomUUID","join","existsSync","readdirSync","writeFileSync","readFileSync"],"mappings":"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","file":"chunk-LCYH4T6N.js","sourcesContent":["/**\r\n * Agent subprocess management per PRD sections 8.1, 9.4\r\n * Each agent runs as a separate Node.js process (fork of aemeathcli).\r\n * Parent–child IPC uses JSON-RPC 2.0 protocol (IIPCMessage).\r\n */\r\n\r\nimport { fork, type ChildProcess } from \"node:child_process\";\r\nimport type {\r\n IAgentConfig,\r\n IAgentState,\r\n AgentStatus,\r\n IPCMethod,\r\n IIPCMessage,\r\n} from \"../types/index.js\";\r\nimport { AgentSpawnError } from \"../types/index.js\";\r\nimport { logger, getIPCSocketPath } from \"../utils/index.js\";\r\nimport { getEventBus } from \"../core/event-bus.js\";\r\n\r\n// ── Public Types ──────────────────────────────────────────────────────\r\n\r\n/** Configuration for spawning an agent process. */\r\nexport interface IAgentProcessOptions {\r\n readonly teamName: string;\r\n readonly sessionId: string;\r\n readonly cliEntryPoint?: string | undefined;\r\n readonly env?: Readonly<Record<string, string>>;\r\n readonly shutdownTimeoutMs?: number;\r\n readonly registrationTimeoutMs?: number;\r\n}\r\n\r\n/** Callback for IPC messages received from the child process. */\r\nexport type AgentMessageCallback = (\r\n method: string,\r\n params: Record<string, unknown>,\r\n) => void;\r\n\r\n// ── Constants ─────────────────────────────────────────────────────────\r\n\r\nconst DEFAULT_SHUTDOWN_TIMEOUT_MS = 10_000;\r\nconst DEFAULT_REGISTRATION_TIMEOUT_MS = 15_000;\r\nconst BASE_ENV_KEYS: readonly string[] = [\r\n \"PATH\",\r\n \"HOME\",\r\n \"SHELL\",\r\n \"TERM\",\r\n \"TMPDIR\",\r\n \"TMP\",\r\n \"TEMP\",\r\n \"LANG\",\r\n \"LC_ALL\",\r\n \"LC_CTYPE\",\r\n \"USER\",\r\n \"LOGNAME\",\r\n \"PWD\",\r\n \"XDG_CONFIG_HOME\",\r\n \"XDG_CACHE_HOME\",\r\n \"XDG_DATA_HOME\",\r\n \"APPDATA\",\r\n \"LOCALAPPDATA\",\r\n \"PROGRAMDATA\",\r\n \"SYSTEMROOT\",\r\n \"COMSPEC\",\r\n \"PATHEXT\",\r\n \"COLORTERM\",\r\n \"CI\",\r\n \"NO_COLOR\",\r\n \"FORCE_COLOR\",\r\n \"HTTP_PROXY\",\r\n \"HTTPS_PROXY\",\r\n \"NO_PROXY\",\r\n \"SSH_AUTH_SOCK\",\r\n] as const;\r\nconst FORWARDED_ENV_PREFIXES: readonly string[] = [\r\n \"AEMEATHCLI_\",\r\n \"ANTHROPIC_\",\r\n \"OPENAI_\",\r\n \"GOOGLE_\",\r\n \"GEMINI_\",\r\n \"MOONSHOT_\",\r\n \"KIMI_\",\r\n \"OLLAMA_\",\r\n \"NODE_\",\r\n] as const;\r\n\r\n// ── AgentProcess ──────────────────────────────────────────────────────\r\n\r\nexport class AgentProcess {\r\n private readonly config: IAgentConfig;\r\n private readonly teamName: string;\r\n private readonly sessionId: string;\r\n private readonly cliEntryPoint: string;\r\n private readonly customEnv: Readonly<Record<string, string>>;\r\n private readonly shutdownTimeoutMs: number;\r\n private readonly registrationTimeoutMs: number;\r\n private readonly messageCallbacks = new Set<AgentMessageCallback>();\r\n\r\n private child: ChildProcess | null = null;\r\n private status: AgentStatus = \"idle\";\r\n private currentTaskId: string | undefined;\r\n private nextMessageId = 1;\r\n\r\n constructor(config: IAgentConfig, options: IAgentProcessOptions) {\r\n this.config = config;\r\n this.teamName = options.teamName;\r\n this.sessionId = options.sessionId;\r\n this.cliEntryPoint =\r\n options.cliEntryPoint ?? process.argv[1] ?? \"aemeathcli\";\r\n this.customEnv = options.env ?? {};\r\n this.shutdownTimeoutMs =\r\n options.shutdownTimeoutMs ?? DEFAULT_SHUTDOWN_TIMEOUT_MS;\r\n this.registrationTimeoutMs =\r\n options.registrationTimeoutMs ?? DEFAULT_REGISTRATION_TIMEOUT_MS;\r\n }\r\n\r\n /** Spawn the child process. Throws AgentSpawnError on failure. */\r\n async start(): Promise<void> {\r\n if (this.child) {\r\n throw new AgentSpawnError(\r\n this.config.name,\r\n \"Agent process already running\",\r\n );\r\n }\r\n\r\n const args = [\r\n \"--agent\",\r\n \"--team\",\r\n this.teamName,\r\n \"--name\",\r\n this.config.name,\r\n \"--model\",\r\n this.config.model,\r\n \"--role\",\r\n this.config.role,\r\n ];\r\n\r\n const socketPath = getIPCSocketPath(this.sessionId);\r\n\r\n const env = this.buildChildEnv(socketPath);\r\n\r\n try {\r\n this.child = fork(this.cliEntryPoint, args, {\r\n stdio: [\"pipe\", \"pipe\", \"pipe\", \"ipc\"],\r\n env,\r\n detached: false,\r\n });\r\n\r\n this.setupChildListeners();\r\n this.setStatus(\"idle\");\r\n\r\n await this.waitForRegistration();\r\n\r\n getEventBus().emit(\"agent:spawned\", {\r\n agentName: this.config.name,\r\n model: this.config.model,\r\n });\r\n\r\n logger.info(\r\n {\r\n agent: this.config.name,\r\n pid: this.child.pid,\r\n model: this.config.model,\r\n },\r\n \"Agent process spawned\",\r\n );\r\n } catch (error: unknown) {\r\n // Kill orphaned child on startup failure\r\n if (this.child) {\r\n this.child.kill(\"SIGTERM\");\r\n this.child = null;\r\n }\r\n const reason = error instanceof Error ? error.message : String(error);\r\n throw new AgentSpawnError(this.config.name, reason);\r\n }\r\n }\r\n\r\n private buildChildEnv(socketPath: string): Record<string, string> {\r\n const env: Record<string, string | undefined> = {\r\n ...pickInheritedEnv(process.env),\r\n ...this.customEnv,\r\n AEMEATHCLI_AGENT_MODE: \"1\",\r\n AEMEATHCLI_TEAM_NAME: this.teamName,\r\n AEMEATHCLI_AGENT_ID: this.config.agentId,\r\n AEMEATHCLI_AGENT_NAME: this.config.name,\r\n AEMEATHCLI_IPC_SOCKET: socketPath,\r\n // Prefer SDK adapters when API keys are available (not OAuth/native login).\r\n // Native login credentials always use native CLI adapters regardless of\r\n // this flag — the registry enforces this to avoid \"invalid API key\" errors.\r\n AEMEATHCLI_PREFER_SDK: \"1\",\r\n // Increase timeout for native CLI fallback (agent tasks can be long).\r\n AEMEATHCLI_NATIVE_CLI_TIMEOUT_MS: \"300000\",\r\n };\r\n\r\n const sanitized: Record<string, string> = {};\r\n for (const [key, value] of Object.entries(env)) {\r\n if (typeof value === \"string\" && value.length > 0) {\r\n sanitized[key] = value;\r\n }\r\n }\r\n\r\n return sanitized;\r\n }\r\n\r\n /** Gracefully stop the agent. Falls back to SIGTERM after timeout. */\r\n async stop(): Promise<void> {\r\n if (!this.child) return;\r\n\r\n const child = this.child;\r\n\r\n this.sendIPC(\"hub.shutdown\", { reason: \"team_cleanup\" });\r\n\r\n await new Promise<void>((resolve) => {\r\n const timer = setTimeout(() => {\r\n if (child.exitCode === null) {\r\n logger.warn(\r\n { agent: this.config.name },\r\n \"Force-killing unresponsive agent\",\r\n );\r\n child.kill(\"SIGTERM\");\r\n }\r\n resolve();\r\n }, this.shutdownTimeoutMs);\r\n\r\n child.once(\"exit\", () => {\r\n clearTimeout(timer);\r\n resolve();\r\n });\r\n });\r\n\r\n this.cleanup();\r\n logger.info({ agent: this.config.name }, \"Agent process stopped\");\r\n }\r\n\r\n /** Kill and restart the agent process. */\r\n async restart(): Promise<void> {\r\n await this.stop();\r\n await this.start();\r\n }\r\n\r\n /** Send a JSON-RPC 2.0 message to the child process. Returns message ID. */\r\n sendIPC(method: IPCMethod, params: Record<string, unknown>): number {\r\n if (!this.child?.connected) {\r\n logger.warn(\r\n { agent: this.config.name, method },\r\n \"Cannot send IPC: child not connected\",\r\n );\r\n return -1;\r\n }\r\n\r\n const id = this.nextMessageId++;\r\n const message: IIPCMessage = {\r\n jsonrpc: \"2.0\",\r\n method,\r\n params,\r\n id,\r\n };\r\n\r\n this.child.send(message);\r\n return id;\r\n }\r\n\r\n /** Assign a task to this agent via IPC. */\r\n assignTask(taskId: string, subject: string, description: string): number {\r\n this.currentTaskId = taskId;\r\n return this.sendIPC(\"hub.taskAssign\", { taskId, subject, description });\r\n }\r\n\r\n /** Register a callback for IPC messages from the child process. */\r\n onMessage(callback: AgentMessageCallback): () => void {\r\n this.messageCallbacks.add(callback);\r\n return () => {\r\n this.messageCallbacks.delete(callback);\r\n };\r\n }\r\n\r\n /** Get the current agent state snapshot. */\r\n getState(): IAgentState {\r\n return {\r\n config: this.config,\r\n status: this.status,\r\n currentTaskId: this.currentTaskId,\r\n };\r\n }\r\n\r\n /** Get the current status. */\r\n getStatus(): AgentStatus {\r\n return this.status;\r\n }\r\n\r\n /** Get the child process PID, or undefined if not running. */\r\n getPid(): number | undefined {\r\n return this.child?.pid;\r\n }\r\n\r\n /** Check if the child process is alive. */\r\n isAlive(): boolean {\r\n return this.child !== null && this.child.exitCode === null;\r\n }\r\n\r\n // ── Private ──────────────────────────────────────────────────────────\r\n\r\n private setupChildListeners(): void {\r\n const child = this.child;\r\n if (!child) return;\r\n\r\n // Do NOT forward child stdout as agent.streamChunk.\r\n // The agent child sends all structured output via IPC (process.send).\r\n // Forwarding stdout captures raw noise from subprocess execution\r\n // (e.g. native CLI adapters shelling out to codex/gemini/claude).\r\n child.stdout?.on(\"data\", (chunk: Buffer | string) => {\r\n const content = typeof chunk === \"string\" ? chunk : chunk.toString(\"utf-8\");\r\n if (content.length > 0) {\r\n logger.debug(\r\n { agent: this.config.name, bytes: content.length },\r\n \"Agent stdout (suppressed from UI)\",\r\n );\r\n }\r\n });\r\n\r\n child.stderr?.on(\"data\", (chunk: Buffer | string) => {\r\n const content = typeof chunk === \"string\" ? chunk : chunk.toString(\"utf-8\");\r\n if (content.length > 0) {\r\n logger.warn(\r\n { agent: this.config.name, stderr: content.slice(0, 200) },\r\n \"Agent stderr\",\r\n );\r\n }\r\n });\r\n\r\n child.on(\"message\", (raw: unknown) => {\r\n this.handleChildMessage(raw);\r\n });\r\n\r\n child.on(\"error\", (error: Error) => {\r\n logger.error(\r\n { agent: this.config.name, error: error.message },\r\n \"Agent process error\",\r\n );\r\n this.setStatus(\"error\");\r\n });\r\n\r\n child.on(\"exit\", (code: number | null, signal: string | null) => {\r\n logger.info(\r\n { agent: this.config.name, code, signal },\r\n \"Agent process exited\",\r\n );\r\n this.setStatus(\"shutdown\");\r\n this.child = null;\r\n });\r\n\r\n child.on(\"disconnect\", () => {\r\n logger.debug({ agent: this.config.name }, \"Agent IPC disconnected\");\r\n });\r\n }\r\n\r\n private handleChildMessage(raw: unknown): void {\r\n if (!isIPCMessage(raw)) {\r\n logger.warn(\r\n { agent: this.config.name },\r\n \"Received non-IPC message from child\",\r\n );\r\n return;\r\n }\r\n\r\n const { method, params } = raw;\r\n\r\n // Handle known methods internally\r\n switch (method) {\r\n case \"agent.register\":\r\n logger.debug({ agent: this.config.name }, \"Agent registered via IPC\");\r\n break;\r\n\r\n case \"agent.taskUpdate\": {\r\n const taskStatus = params[\"status\"];\r\n if (typeof taskStatus === \"string\") {\r\n if (taskStatus === \"in_progress\") {\r\n this.setStatus(\"active\");\r\n } else if (taskStatus === \"completed\") {\r\n this.currentTaskId = undefined;\r\n this.setStatus(\"idle\");\r\n }\r\n }\r\n break;\r\n }\r\n\r\n case \"agent.streamChunk\":\r\n case \"agent.message\":\r\n // Forwarded to registered callbacks below\r\n break;\r\n\r\n default:\r\n break;\r\n }\r\n\r\n this.notifyCallbacks(method, params);\r\n }\r\n\r\n /** Wait for the child to send agent.register. Rejects on timeout or early exit. */\r\n private async waitForRegistration(): Promise<void> {\r\n return new Promise<void>((resolve, reject) => {\r\n const timeout = setTimeout(() => {\r\n this.child?.removeListener(\"message\", onMessage);\r\n reject(new Error(\"Agent registration timeout\"));\r\n }, this.registrationTimeoutMs);\r\n\r\n const onMessage = (raw: unknown): void => {\r\n if (isIPCMessage(raw) && raw.method === \"agent.register\") {\r\n clearTimeout(timeout);\r\n this.child?.removeListener(\"message\", onMessage);\r\n this.child?.removeListener(\"exit\", onExit);\r\n resolve();\r\n }\r\n };\r\n\r\n const onExit = (): void => {\r\n clearTimeout(timeout);\r\n this.child?.removeListener(\"message\", onMessage);\r\n reject(new Error(\"Agent process exited before registration\"));\r\n };\r\n\r\n this.child?.on(\"message\", onMessage);\r\n this.child?.once(\"exit\", onExit);\r\n });\r\n }\r\n\r\n private setStatus(status: AgentStatus): void {\r\n this.status = status;\r\n getEventBus().emit(\"agent:status\", {\r\n agentName: this.config.name,\r\n status,\r\n });\r\n }\r\n\r\n private notifyCallbacks(method: string, params: Record<string, unknown>): void {\r\n for (const callback of this.messageCallbacks) {\r\n try {\r\n callback(method, params);\r\n } catch (error: unknown) {\r\n const reason = error instanceof Error ? error.message : String(error);\r\n logger.error(\r\n { agent: this.config.name, error: reason },\r\n \"Message callback threw\",\r\n );\r\n }\r\n }\r\n }\r\n\r\n private cleanup(): void {\r\n this.child = null;\r\n this.currentTaskId = undefined;\r\n this.messageCallbacks.clear();\r\n }\r\n}\r\n\r\nfunction pickInheritedEnv(env: NodeJS.ProcessEnv): Record<string, string> {\r\n const filtered: Record<string, string> = {};\r\n\r\n for (const key of BASE_ENV_KEYS) {\r\n const value = env[key];\r\n if (typeof value === \"string\" && value.length > 0) {\r\n filtered[key] = value;\r\n }\r\n }\r\n\r\n for (const [key, value] of Object.entries(env)) {\r\n if (typeof value !== \"string\" || value.length === 0) {\r\n continue;\r\n }\r\n if (FORWARDED_ENV_PREFIXES.some((prefix) => key.startsWith(prefix))) {\r\n filtered[key] = value;\r\n }\r\n }\r\n\r\n return filtered;\r\n}\r\n\r\n// ── Type Guard ─────────────────────────────────────────────────────────\r\n\r\nfunction isIPCMessage(value: unknown): value is IIPCMessage {\r\n if (typeof value !== \"object\" || value === null) return false;\r\n const obj = value as Record<string, unknown>;\r\n return (\r\n obj[\"jsonrpc\"] === \"2.0\" &&\r\n typeof obj[\"method\"] === \"string\" &&\r\n typeof obj[\"params\"] === \"object\" &&\r\n obj[\"params\"] !== null\r\n );\r\n}\r\n","/**\r\n * Inter-agent message routing per PRD section 8.4\r\n * Supports: DM, broadcast, shutdown, plan approval, task updates.\r\n * Message queue for busy agents with automatic drain on idle transition.\r\n */\r\n\r\nimport { randomUUID } from \"node:crypto\";\r\nimport type {\r\n IAgentMessage,\r\n AgentMessageType,\r\n AgentStatus,\r\n} from \"../types/index.js\";\r\nimport { logger } from \"../utils/index.js\";\r\nimport { getEventBus } from \"../core/event-bus.js\";\r\n\r\n// ── Public Types ──────────────────────────────────────────────────────\r\n\r\n/** Handler function invoked when an agent receives a message. */\r\nexport type MessageHandler = (message: IAgentMessage) => void;\r\n\r\n/**\r\n * Optional transport layer for remote message delivery (e.g., IPC hub).\r\n * Implement this interface to bridge the message bus to Unix domain sockets.\r\n */\r\nexport interface IMessageTransport {\r\n send(agentId: string, message: IAgentMessage): Promise<boolean>;\r\n onReceive(handler: (message: IAgentMessage) => void): () => void;\r\n}\r\n\r\n/** Options for constructing a MessageBus. */\r\nexport interface IMessageBusOptions {\r\n readonly transport?: IMessageTransport;\r\n}\r\n\r\n// ── MessageBus ────────────────────────────────────────────────────────\r\n\r\nexport class MessageBus {\r\n private readonly handlers = new Map<string, Set<MessageHandler>>();\r\n private readonly queues = new Map<string, IAgentMessage[]>();\r\n private readonly statuses = new Map<string, AgentStatus>();\r\n private readonly transport: IMessageTransport | undefined;\r\n private readonly transportUnsubscribe: (() => void) | undefined;\r\n private destroyed = false;\r\n\r\n constructor(options?: IMessageBusOptions) {\r\n this.transport = options?.transport;\r\n\r\n if (this.transport) {\r\n this.transportUnsubscribe = this.transport.onReceive((message) => {\r\n this.routeIncoming(message);\r\n });\r\n }\r\n }\r\n\r\n /** Register an agent as available for message delivery. */\r\n registerAgent(agentId: string): void {\r\n if (!this.handlers.has(agentId)) {\r\n this.handlers.set(agentId, new Set());\r\n }\r\n if (!this.queues.has(agentId)) {\r\n this.queues.set(agentId, []);\r\n }\r\n this.statuses.set(agentId, \"idle\");\r\n logger.debug({ agentId }, \"Agent registered on message bus\");\r\n }\r\n\r\n /** Remove an agent from the bus. Pending messages are discarded. */\r\n unregisterAgent(agentId: string): void {\r\n this.handlers.delete(agentId);\r\n this.queues.delete(agentId);\r\n this.statuses.delete(agentId);\r\n logger.debug({ agentId }, \"Agent unregistered from message bus\");\r\n }\r\n\r\n /** Subscribe to messages delivered to an agent. Returns unsubscribe function. */\r\n subscribe(agentId: string, handler: MessageHandler): () => void {\r\n let handlerSet = this.handlers.get(agentId);\r\n if (!handlerSet) {\r\n handlerSet = new Set();\r\n this.handlers.set(agentId, handlerSet);\r\n }\r\n handlerSet.add(handler);\r\n\r\n return () => {\r\n handlerSet.delete(handler);\r\n };\r\n }\r\n\r\n /** Route a message to its recipient(s). Returns true if delivered or queued. */\r\n send(message: IAgentMessage): boolean {\r\n if (this.destroyed) {\r\n logger.warn(\"MessageBus is destroyed, dropping message\");\r\n return false;\r\n }\r\n\r\n if (message.type === \"broadcast\") {\r\n return this.broadcastToAll(message);\r\n }\r\n\r\n if (!message.recipientId) {\r\n logger.warn(\r\n { type: message.type, senderId: message.senderId },\r\n \"Non-broadcast message missing recipientId\",\r\n );\r\n return false;\r\n }\r\n\r\n return this.deliverToAgent(message.recipientId, message);\r\n }\r\n\r\n /** Create a well-formed message and send it. Returns the created message. */\r\n createAndSend(\r\n type: AgentMessageType,\r\n senderId: string,\r\n recipientId: string | undefined,\r\n content: string,\r\n extra?: {\r\n summary?: string;\r\n requestId?: string;\r\n approve?: boolean;\r\n },\r\n ): IAgentMessage {\r\n const message: IAgentMessage = {\r\n type,\r\n senderId,\r\n recipientId,\r\n content,\r\n summary: extra?.summary,\r\n requestId: extra?.requestId ?? randomUUID(),\r\n approve: extra?.approve,\r\n timestamp: new Date(),\r\n };\r\n\r\n this.send(message);\r\n return message;\r\n }\r\n\r\n /** Update an agent's status. Drains the queue when transitioning to idle. */\r\n setAgentStatus(agentId: string, status: AgentStatus): void {\r\n const previous = this.statuses.get(agentId);\r\n this.statuses.set(agentId, status);\r\n\r\n if (status === \"idle\" && previous === \"active\") {\r\n this.drainQueue(agentId);\r\n }\r\n }\r\n\r\n /** Get the number of queued messages for an agent. */\r\n getQueueSize(agentId: string): number {\r\n return this.queues.get(agentId)?.length ?? 0;\r\n }\r\n\r\n /** Get all registered agent IDs. */\r\n getRegisteredAgents(): readonly string[] {\r\n return [...this.handlers.keys()];\r\n }\r\n\r\n /** Tear down the message bus and release resources. */\r\n destroy(): void {\r\n this.destroyed = true;\r\n this.transportUnsubscribe?.();\r\n this.handlers.clear();\r\n this.queues.clear();\r\n this.statuses.clear();\r\n logger.debug(\"MessageBus destroyed\");\r\n }\r\n\r\n // ── Private Routing ─────────────────────────────────────────────────\r\n\r\n private broadcastToAll(message: IAgentMessage): boolean {\r\n let delivered = false;\r\n\r\n for (const agentId of this.handlers.keys()) {\r\n if (agentId === message.senderId) continue;\r\n\r\n const copy: IAgentMessage = { ...message, recipientId: agentId };\r\n this.deliverToAgent(agentId, copy);\r\n delivered = true;\r\n }\r\n\r\n return delivered;\r\n }\r\n\r\n private deliverToAgent(agentId: string, message: IAgentMessage): boolean {\r\n const status = this.statuses.get(agentId);\r\n\r\n // Queue if agent is busy\r\n if (status === \"active\") {\r\n this.enqueue(agentId, message);\r\n logger.debug(\r\n { agentId, type: message.type },\r\n \"Agent busy, message queued\",\r\n );\r\n return true;\r\n }\r\n\r\n // Try local handler delivery\r\n const handlerSet = this.handlers.get(agentId);\r\n if (handlerSet && handlerSet.size > 0) {\r\n this.invokeHandlers(agentId, handlerSet, message);\r\n return true;\r\n }\r\n\r\n // Try remote transport\r\n if (this.transport) {\r\n this.transport.send(agentId, message).catch((error: unknown) => {\r\n const reason = error instanceof Error ? error.message : String(error);\r\n logger.error({ agentId, error: reason }, \"Transport delivery failed\");\r\n });\r\n return true;\r\n }\r\n\r\n // No handler and no transport — queue for later\r\n this.enqueue(agentId, message);\r\n return true;\r\n }\r\n\r\n private invokeHandlers(\r\n agentId: string,\r\n handlerSet: Set<MessageHandler>,\r\n message: IAgentMessage,\r\n ): void {\r\n for (const handler of handlerSet) {\r\n try {\r\n handler(message);\r\n } catch (error: unknown) {\r\n const reason = error instanceof Error ? error.message : String(error);\r\n logger.error({ agentId, error: reason }, \"Message handler threw\");\r\n }\r\n }\r\n\r\n getEventBus().emit(\"agent:message\", {\r\n from: message.senderId,\r\n to: agentId,\r\n content: message.content,\r\n });\r\n }\r\n\r\n private enqueue(agentId: string, message: IAgentMessage): void {\r\n let queue = this.queues.get(agentId);\r\n if (!queue) {\r\n queue = [];\r\n this.queues.set(agentId, queue);\r\n }\r\n queue.push(message);\r\n }\r\n\r\n private drainQueue(agentId: string): void {\r\n const queue = this.queues.get(agentId);\r\n if (!queue || queue.length === 0) return;\r\n\r\n const handlerSet = this.handlers.get(agentId);\r\n if (!handlerSet || handlerSet.size === 0) return;\r\n\r\n const pending = queue.splice(0);\r\n logger.debug({ agentId, count: pending.length }, \"Draining message queue\");\r\n\r\n for (const message of pending) {\r\n this.invokeHandlers(agentId, handlerSet, message);\r\n }\r\n }\r\n\r\n private routeIncoming(message: IAgentMessage): void {\r\n if (message.type === \"broadcast\") {\r\n this.broadcastToAll(message);\r\n } else if (message.recipientId) {\r\n this.deliverToAgent(message.recipientId, message);\r\n }\r\n }\r\n}\r\n","/**\r\n * File-based task persistence per PRD section 20.2\r\n * Atomic writes for crash recovery: write to temp file, then rename.\r\n * Store at getTasksDir()/teamName/taskId.json\r\n */\r\n\r\nimport { join } from \"node:path\";\r\nimport {\r\n readFileSync,\r\n writeFileSync,\r\n renameSync,\r\n unlinkSync,\r\n readdirSync,\r\n existsSync,\r\n} from \"node:fs\";\r\nimport type { ITask, TaskStatus, ModelRole } from \"../types/index.js\";\r\nimport { logger, getTasksDir, ensureDirectory } from \"../utils/index.js\";\r\n\r\n// ── Serialization Format ──────────────────────────────────────────────\r\n\r\n/** Serialized task format with ISO-8601 date strings for JSON persistence. */\r\ninterface ISerializedTask {\r\n readonly id: string;\r\n readonly subject: string;\r\n readonly description: string;\r\n readonly status: TaskStatus;\r\n readonly owner?: string | undefined;\r\n readonly model?: string | undefined;\r\n readonly role?: ModelRole | undefined;\r\n readonly blocks: readonly string[];\r\n readonly blockedBy: readonly string[];\r\n readonly createdAt: string;\r\n readonly updatedAt: string;\r\n}\r\n\r\n// ── TaskStore ─────────────────────────────────────────────────────────\r\n\r\nexport class TaskStore {\r\n private readonly storeDir: string;\r\n\r\n constructor(teamName: string) {\r\n this.storeDir = join(getTasksDir(), teamName);\r\n ensureDirectory(this.storeDir);\r\n this.cleanupTempFiles();\r\n }\r\n\r\n /** Persist a task to disk with atomic write (temp + rename). */\r\n save(task: ITask): void {\r\n const serialized = TaskStore.serialize(task);\r\n const filePath = this.getTaskFilePath(task.id);\r\n const tmpPath = `${filePath}.tmp`;\r\n\r\n try {\r\n writeFileSync(tmpPath, JSON.stringify(serialized, null, 2), {\r\n encoding: \"utf-8\",\r\n mode: 0o644,\r\n });\r\n renameSync(tmpPath, filePath);\r\n logger.debug({ taskId: task.id }, \"Task persisted to disk\");\r\n } catch (error: unknown) {\r\n try {\r\n unlinkSync(tmpPath);\r\n } catch {\r\n /* temp cleanup best-effort */\r\n }\r\n const reason = error instanceof Error ? error.message : String(error);\r\n logger.error({ taskId: task.id, error: reason }, \"Failed to save task\");\r\n throw error;\r\n }\r\n }\r\n\r\n /** Load a single task by ID. Throws if not found. */\r\n load(taskId: string): ITask {\r\n const filePath = this.getTaskFilePath(taskId);\r\n if (!existsSync(filePath)) {\r\n throw new Error(`Task file not found: ${taskId}`);\r\n }\r\n\r\n const raw = readFileSync(filePath, \"utf-8\");\r\n const data: unknown = JSON.parse(raw);\r\n return TaskStore.deserialize(data as ISerializedTask);\r\n }\r\n\r\n /** Load all tasks for this team, sorted by creation time. */\r\n loadAll(): ITask[] {\r\n if (!existsSync(this.storeDir)) {\r\n return [];\r\n }\r\n\r\n const files = readdirSync(this.storeDir).filter(\r\n (f) => f.endsWith(\".json\") && !f.endsWith(\".tmp\"),\r\n );\r\n const tasks: ITask[] = [];\r\n\r\n for (const file of files) {\r\n try {\r\n const raw = readFileSync(join(this.storeDir, file), \"utf-8\");\r\n const data: unknown = JSON.parse(raw);\r\n tasks.push(TaskStore.deserialize(data as ISerializedTask));\r\n } catch (error: unknown) {\r\n const reason = error instanceof Error ? error.message : String(error);\r\n logger.warn({ file, error: reason }, \"Skipping corrupt task file\");\r\n }\r\n }\r\n\r\n return tasks.sort((a, b) => a.createdAt.getTime() - b.createdAt.getTime());\r\n }\r\n\r\n /** Remove a task file from disk. Returns true if deleted. */\r\n remove(taskId: string): boolean {\r\n const filePath = this.getTaskFilePath(taskId);\r\n if (!existsSync(filePath)) {\r\n return false;\r\n }\r\n\r\n try {\r\n unlinkSync(filePath);\r\n logger.debug({ taskId }, \"Task file removed\");\r\n return true;\r\n } catch (error: unknown) {\r\n const reason = error instanceof Error ? error.message : String(error);\r\n logger.error({ taskId, error: reason }, \"Failed to remove task file\");\r\n return false;\r\n }\r\n }\r\n\r\n /** Check whether a task file exists on disk. */\r\n exists(taskId: string): boolean {\r\n return existsSync(this.getTaskFilePath(taskId));\r\n }\r\n\r\n /** Absolute path to this team's task store directory. */\r\n getStorePath(): string {\r\n return this.storeDir;\r\n }\r\n\r\n // ── Private ──────────────────────────────────────────────────────────\r\n\r\n private getTaskFilePath(taskId: string): string {\r\n return join(this.storeDir, `${taskId}.json`);\r\n }\r\n\r\n /** Remove orphaned .tmp files left from interrupted writes. */\r\n private cleanupTempFiles(): void {\r\n if (!existsSync(this.storeDir)) return;\r\n\r\n const tmpFiles = readdirSync(this.storeDir).filter((f) =>\r\n f.endsWith(\".tmp\"),\r\n );\r\n\r\n for (const file of tmpFiles) {\r\n try {\r\n unlinkSync(join(this.storeDir, file));\r\n } catch {\r\n /* best-effort */\r\n }\r\n }\r\n\r\n if (tmpFiles.length > 0) {\r\n logger.info(\r\n { count: tmpFiles.length },\r\n \"Cleaned up stale temp task files\",\r\n );\r\n }\r\n }\r\n\r\n private static serialize(task: ITask): ISerializedTask {\r\n return {\r\n id: task.id,\r\n subject: task.subject,\r\n description: task.description,\r\n status: task.status,\r\n owner: task.owner,\r\n model: task.model,\r\n role: task.role,\r\n blocks: [...task.blocks],\r\n blockedBy: [...task.blockedBy],\r\n createdAt: task.createdAt.toISOString(),\r\n updatedAt: task.updatedAt.toISOString(),\r\n };\r\n }\r\n\r\n private static deserialize(data: ISerializedTask): ITask {\r\n return {\r\n id: data.id,\r\n subject: data.subject,\r\n description: data.description,\r\n status: data.status,\r\n owner: data.owner,\r\n model: data.model,\r\n role: data.role,\r\n blocks: [...data.blocks],\r\n blockedBy: [...data.blockedBy],\r\n createdAt: new Date(data.createdAt),\r\n updatedAt: new Date(data.updatedAt),\r\n };\r\n }\r\n}\r\n","/**\r\n * Plan approval workflow per PRD section 8.2 step 5\r\n * Agent submits plan → Leader reviews → Approve or reject.\r\n * Uses message bus for transport; includes configurable timeout.\r\n */\r\n\r\nimport { randomUUID } from \"node:crypto\";\r\nimport type { IAgentMessage } from \"../types/index.js\";\r\nimport { logger } from \"../utils/index.js\";\r\nimport type { MessageBus } from \"./message-bus.js\";\r\n\r\n// ── Public Types ──────────────────────────────────────────────────────\r\n\r\n/** Result of a plan approval request. */\r\nexport interface IPlanApprovalResult {\r\n readonly approved: boolean;\r\n readonly feedback?: string | undefined;\r\n readonly requestId: string;\r\n readonly respondedBy: string;\r\n readonly respondedAt: Date;\r\n}\r\n\r\n/** A pending plan awaiting leader review (for listing). */\r\nexport interface IPendingPlan {\r\n readonly requestId: string;\r\n readonly agentId: string;\r\n readonly plan: string;\r\n readonly submittedAt: Date;\r\n}\r\n\r\n/** Options for the PlanApproval workflow. */\r\nexport interface IPlanApprovalOptions {\r\n readonly leaderId?: string;\r\n readonly timeoutMs?: number;\r\n}\r\n\r\n// ── Internal Types ────────────────────────────────────────────────────\r\n\r\ninterface IPlanRequest {\r\n readonly requestId: string;\r\n readonly agentId: string;\r\n readonly plan: string;\r\n readonly submittedAt: Date;\r\n readonly resolve: (result: IPlanApprovalResult) => void;\r\n readonly reject: (reason: Error) => void;\r\n readonly timer: ReturnType<typeof setTimeout>;\r\n}\r\n\r\n// ── Constants ─────────────────────────────────────────────────────────\r\n\r\nconst DEFAULT_TIMEOUT_MS = 300_000; // 5 minutes\r\nconst DEFAULT_LEADER_ID = \"leader\";\r\n\r\n// ── PlanApproval ──────────────────────────────────────────────────────\r\n\r\nexport class PlanApproval {\r\n private readonly messageBus: MessageBus;\r\n private readonly leaderId: string;\r\n private readonly timeoutMs: number;\r\n private readonly pending = new Map<string, IPlanRequest>();\r\n private destroyed = false;\r\n\r\n constructor(messageBus: MessageBus, options?: IPlanApprovalOptions) {\r\n this.messageBus = messageBus;\r\n this.leaderId = options?.leaderId ?? DEFAULT_LEADER_ID;\r\n this.timeoutMs = options?.timeoutMs ?? DEFAULT_TIMEOUT_MS;\r\n }\r\n\r\n /**\r\n * Submit a plan for approval. Returns a promise that resolves\r\n * when the leader approves or rejects, or rejects on timeout.\r\n */\r\n submitPlan(agentId: string, plan: string): Promise<IPlanApprovalResult> {\r\n if (this.destroyed) {\r\n return Promise.reject(new Error(\"PlanApproval has been destroyed\"));\r\n }\r\n\r\n const requestId = randomUUID();\r\n\r\n return new Promise<IPlanApprovalResult>((resolve, reject) => {\r\n const timer = setTimeout(() => {\r\n this.pending.delete(requestId);\r\n reject(new Error(`Plan approval timed out after ${this.timeoutMs}ms`));\r\n }, this.timeoutMs);\r\n\r\n const request: IPlanRequest = {\r\n requestId,\r\n agentId,\r\n plan,\r\n submittedAt: new Date(),\r\n resolve,\r\n reject,\r\n timer,\r\n };\r\n\r\n this.pending.set(requestId, request);\r\n\r\n this.messageBus.createAndSend(\r\n \"plan_approval_request\",\r\n agentId,\r\n this.leaderId,\r\n plan,\r\n { requestId, summary: `Plan from ${agentId} awaiting review` },\r\n );\r\n\r\n logger.info({ requestId, agentId }, \"Plan submitted for approval\");\r\n });\r\n }\r\n\r\n /** Leader approves a pending plan. Returns false if no matching request. */\r\n approvePlan(requestId: string, responderId: string): boolean {\r\n const request = this.pending.get(requestId);\r\n if (!request) {\r\n logger.warn({ requestId }, \"No pending plan for this requestId\");\r\n return false;\r\n }\r\n\r\n clearTimeout(request.timer);\r\n this.pending.delete(requestId);\r\n\r\n const result: IPlanApprovalResult = {\r\n approved: true,\r\n requestId,\r\n respondedBy: responderId,\r\n respondedAt: new Date(),\r\n };\r\n\r\n this.messageBus.createAndSend(\r\n \"plan_approval_response\",\r\n responderId,\r\n request.agentId,\r\n \"Plan approved\",\r\n { requestId, approve: true },\r\n );\r\n\r\n request.resolve(result);\r\n logger.info({ requestId, agentId: request.agentId }, \"Plan approved\");\r\n return true;\r\n }\r\n\r\n /** Leader rejects a pending plan with feedback. */\r\n rejectPlan(\r\n requestId: string,\r\n responderId: string,\r\n feedback: string,\r\n ): boolean {\r\n const request = this.pending.get(requestId);\r\n if (!request) {\r\n logger.warn({ requestId }, \"No pending plan for this requestId\");\r\n return false;\r\n }\r\n\r\n clearTimeout(request.timer);\r\n this.pending.delete(requestId);\r\n\r\n const result: IPlanApprovalResult = {\r\n approved: false,\r\n feedback,\r\n requestId,\r\n respondedBy: responderId,\r\n respondedAt: new Date(),\r\n };\r\n\r\n this.messageBus.createAndSend(\r\n \"plan_approval_response\",\r\n responderId,\r\n request.agentId,\r\n feedback,\r\n { requestId, approve: false },\r\n );\r\n\r\n request.resolve(result);\r\n logger.info(\r\n { requestId, agentId: request.agentId, feedback },\r\n \"Plan rejected\",\r\n );\r\n return true;\r\n }\r\n\r\n /**\r\n * Handle an incoming plan_approval_response message.\r\n * Call this from a message bus subscription to close the request loop.\r\n */\r\n handleResponse(message: IAgentMessage): void {\r\n if (message.type !== \"plan_approval_response\" || !message.requestId) {\r\n return;\r\n }\r\n\r\n const request = this.pending.get(message.requestId);\r\n if (!request) return;\r\n\r\n clearTimeout(request.timer);\r\n this.pending.delete(message.requestId);\r\n\r\n const result: IPlanApprovalResult = {\r\n approved: message.approve === true,\r\n feedback: message.approve === true ? undefined : message.content,\r\n requestId: message.requestId,\r\n respondedBy: message.senderId,\r\n respondedAt: new Date(),\r\n };\r\n\r\n request.resolve(result);\r\n }\r\n\r\n /** Cancel a pending plan request. */\r\n cancelPlan(requestId: string): boolean {\r\n const request = this.pending.get(requestId);\r\n if (!request) return false;\r\n\r\n clearTimeout(request.timer);\r\n this.pending.delete(requestId);\r\n request.reject(new Error(\"Plan approval cancelled\"));\r\n\r\n logger.info({ requestId, agentId: request.agentId }, \"Plan cancelled\");\r\n return true;\r\n }\r\n\r\n /** Get all pending plan requests (for leader UI). */\r\n getPendingPlans(): readonly IPendingPlan[] {\r\n return [...this.pending.values()].map((req) => ({\r\n requestId: req.requestId,\r\n agentId: req.agentId,\r\n plan: req.plan,\r\n submittedAt: req.submittedAt,\r\n }));\r\n }\r\n\r\n /** Get the count of pending plans. */\r\n getPendingCount(): number {\r\n return this.pending.size;\r\n }\r\n\r\n /** Tear down: cancel all pending plans and release resources. */\r\n destroy(): void {\r\n this.destroyed = true;\r\n\r\n for (const [, request] of this.pending) {\r\n clearTimeout(request.timer);\r\n request.reject(new Error(\"PlanApproval destroyed\"));\r\n }\r\n\r\n this.pending.clear();\r\n logger.debug(\"PlanApproval destroyed\");\r\n }\r\n}\r\n","/**\r\n * Team creation and lifecycle management per PRD section 8.2\r\n * Orchestrates agents, tasks, messaging, and plan approval for a team.\r\n */\r\n\r\nimport { join } from \"node:path\";\r\nimport {\r\n readFileSync,\r\n writeFileSync,\r\n readdirSync,\r\n rmSync,\r\n existsSync,\r\n} from \"node:fs\";\r\nimport { randomUUID } from \"node:crypto\";\r\nimport type {\r\n ITeamConfig,\r\n IAgentConfig,\r\n IAgentState,\r\n TeamStatus,\r\n ProviderName,\r\n ModelRole,\r\n} from \"../types/index.js\";\r\nimport {\r\n logger,\r\n getTeamsDir,\r\n getTasksDir,\r\n ensureDirectory,\r\n} from \"../utils/index.js\";\r\nimport { getEventBus } from \"../core/event-bus.js\";\r\nimport { AgentProcess, type IAgentProcessOptions } from \"./agent-process.js\";\r\nimport { MessageBus } from \"./message-bus.js\";\r\nimport { TaskStore } from \"./task-store.js\";\r\nimport { PlanApproval } from \"./plan-approval.js\";\r\n\r\n// ── Public Types ──────────────────────────────────────────────────────\r\n\r\n/** Agent definition used when creating a team. */\r\nexport interface IAgentDefinition {\r\n readonly name: string;\r\n readonly agentType: string;\r\n readonly model: string;\r\n readonly provider: ProviderName;\r\n readonly role: ModelRole;\r\n}\r\n\r\n/** Options for createTeam(). */\r\nexport interface ITeamCreateOptions {\r\n readonly description?: string;\r\n readonly agents: readonly IAgentDefinition[];\r\n readonly sessionId?: string;\r\n readonly cliEntryPoint?: string;\r\n readonly agentEnv?: Readonly<Record<string, string>>;\r\n}\r\n\r\n// ── Internal Types ────────────────────────────────────────────────────\r\n\r\n/** Serialized team config for JSON persistence (dates as ISO strings). */\r\ninterface ISerializedTeamConfig {\r\n readonly teamName: string;\r\n readonly description?: string | undefined;\r\n readonly status: TeamStatus;\r\n readonly members: readonly IAgentConfig[];\r\n readonly createdAt: string;\r\n}\r\n\r\n/** Runtime state for an active team. */\r\ninterface IActiveTeam {\r\n readonly config: ITeamConfig;\r\n readonly processes: Map<string, AgentProcess>;\r\n readonly messageBus: MessageBus;\r\n readonly taskStore: TaskStore;\r\n readonly planApproval: PlanApproval;\r\n readonly sessionId: string;\r\n}\r\n\r\n// ── Validation ────────────────────────────────────────────────────────\r\n\r\nconst TEAM_NAME_PATTERN = /^[\\w-]+$/;\r\n\r\n// ── TeamManager ───────────────────────────────────────────────────────\r\n\r\nexport class TeamManager {\r\n private readonly activeTeams = new Map<string, IActiveTeam>();\r\n\r\n /** Create a new team: config, directories, and agent process handles. */\r\n createTeam(\r\n name: string,\r\n options: ITeamCreateOptions,\r\n ): ITeamConfig {\r\n if (this.activeTeams.has(name)) {\r\n throw new Error(`Team already exists: ${name}`);\r\n }\r\n\r\n if (!TEAM_NAME_PATTERN.test(name)) {\r\n throw new Error(\r\n `Invalid team name: \"${name}\". Use alphanumeric characters, dashes, or underscores.`,\r\n );\r\n }\r\n\r\n const teamDir = join(getTeamsDir(), name);\r\n if (existsSync(teamDir)) {\r\n throw new Error(`Team directory already exists: ${teamDir}`);\r\n }\r\n\r\n // Build agent configs with generated IDs\r\n const members: IAgentConfig[] = options.agents.map((def) => ({\r\n name: def.name,\r\n agentId: randomUUID(),\r\n agentType: def.agentType,\r\n model: def.model,\r\n provider: def.provider,\r\n role: def.role,\r\n }));\r\n\r\n const config: ITeamConfig = {\r\n teamName: name,\r\n description: options.description,\r\n status: \"active\",\r\n members,\r\n createdAt: new Date(),\r\n };\r\n\r\n // Create directories\r\n ensureDirectory(teamDir);\r\n ensureDirectory(join(getTasksDir(), name));\r\n\r\n // Persist config\r\n this.saveTeamConfig(name, config);\r\n\r\n // Initialize runtime resources\r\n const sessionId = options.sessionId ?? randomUUID();\r\n const messageBus = new MessageBus();\r\n const taskStore = new TaskStore(name);\r\n const planApproval = new PlanApproval(messageBus);\r\n\r\n // Create agent process handles (not yet started)\r\n const processes = new Map<string, AgentProcess>();\r\n\r\n for (const member of members) {\r\n const processOptions: IAgentProcessOptions = {\r\n teamName: name,\r\n sessionId,\r\n cliEntryPoint: options.cliEntryPoint,\r\n ...(options.agentEnv !== undefined ? { env: options.agentEnv } : {}),\r\n };\r\n\r\n const agentProcess = new AgentProcess(member, processOptions);\r\n processes.set(member.name, agentProcess);\r\n messageBus.registerAgent(member.agentId);\r\n }\r\n\r\n const activeTeam: IActiveTeam = {\r\n config,\r\n processes,\r\n messageBus,\r\n taskStore,\r\n planApproval,\r\n sessionId,\r\n };\r\n\r\n this.activeTeams.set(name, activeTeam);\r\n\r\n getEventBus().emit(\"team:created\", {\r\n teamName: name,\r\n agentCount: members.length,\r\n });\r\n\r\n logger.info(\r\n { team: name, agents: members.length, sessionId },\r\n \"Team created\",\r\n );\r\n\r\n return config;\r\n }\r\n\r\n /** Start all agent processes for a team. */\r\n async startAgents(teamName: string): Promise<void> {\r\n const team = this.getActiveTeam(teamName);\r\n const startPromises: Promise<void>[] = [];\r\n\r\n for (const [agentName, agentProcess] of team.processes) {\r\n startPromises.push(\r\n agentProcess.start().catch((error: unknown) => {\r\n const reason =\r\n error instanceof Error ? error.message : String(error);\r\n logger.error(\r\n { team: teamName, agent: agentName, error: reason },\r\n \"Failed to start agent\",\r\n );\r\n }),\r\n );\r\n }\r\n\r\n await Promise.allSettled(startPromises);\r\n }\r\n\r\n /** Gracefully shutdown and remove a team. */\r\n async deleteTeam(name: string): Promise<void> {\r\n const active = this.activeTeams.get(name);\r\n\r\n if (active) {\r\n await this.shutdownAgents(active);\r\n active.planApproval.destroy();\r\n active.messageBus.destroy();\r\n this.activeTeams.delete(name);\r\n }\r\n\r\n // Remove directories from disk\r\n const teamDir = join(getTeamsDir(), name);\r\n if (existsSync(teamDir)) {\r\n rmSync(teamDir, { recursive: true, force: true });\r\n }\r\n\r\n const taskDir = join(getTasksDir(), name);\r\n if (existsSync(taskDir)) {\r\n rmSync(taskDir, { recursive: true, force: true });\r\n }\r\n\r\n getEventBus().emit(\"team:deleted\", { teamName: name });\r\n logger.info({ team: name }, \"Team deleted\");\r\n }\r\n\r\n /** List all teams from disk (active and inactive). */\r\n listTeams(): ITeamConfig[] {\r\n const teamsDir = getTeamsDir();\r\n if (!existsSync(teamsDir)) return [];\r\n\r\n const entries = readdirSync(teamsDir, { withFileTypes: true });\r\n const configs: ITeamConfig[] = [];\r\n\r\n for (const entry of entries) {\r\n if (!entry.isDirectory()) continue;\r\n\r\n try {\r\n const teamConfig = this.loadTeamConfig(entry.name);\r\n configs.push(teamConfig);\r\n } catch (error: unknown) {\r\n const reason = error instanceof Error ? error.message : String(error);\r\n logger.warn(\r\n { team: entry.name, error: reason },\r\n \"Skipping unreadable team\",\r\n );\r\n }\r\n }\r\n\r\n return configs;\r\n }\r\n\r\n /** Load a team config from disk. Throws if not found. */\r\n getTeam(name: string): ITeamConfig {\r\n return this.loadTeamConfig(name);\r\n }\r\n\r\n /** Get the runtime state of a specific agent within an active team. */\r\n getAgentState(\r\n teamName: string,\r\n agentName: string,\r\n ): IAgentState | undefined {\r\n const team = this.activeTeams.get(teamName);\r\n if (!team) return undefined;\r\n\r\n const agentProcess = team.processes.get(agentName);\r\n return agentProcess?.getState();\r\n }\r\n\r\n /** Get all agent states for an active team. */\r\n getAgentStates(teamName: string): readonly IAgentState[] {\r\n const team = this.activeTeams.get(teamName);\r\n if (!team) return [];\r\n\r\n return [...team.processes.values()].map((p) => p.getState());\r\n }\r\n\r\n /** Get the message bus for an active team. */\r\n getMessageBus(teamName: string): MessageBus | undefined {\r\n return this.activeTeams.get(teamName)?.messageBus;\r\n }\r\n\r\n /** Get the task store for an active team. */\r\n getTaskStore(teamName: string): TaskStore | undefined {\r\n return this.activeTeams.get(teamName)?.taskStore;\r\n }\r\n\r\n /** Get the plan approval handler for an active team. */\r\n getPlanApproval(teamName: string): PlanApproval | undefined {\r\n return this.activeTeams.get(teamName)?.planApproval;\r\n }\r\n\r\n /** Register a callback for IPC messages from all agents in a team. Returns cleanup function. */\r\n onAgentMessages(\r\n teamName: string,\r\n callback: (agentName: string, method: string, params: Record<string, unknown>) => void,\r\n ): () => void {\r\n const team = this.getActiveTeam(teamName);\r\n const cleanups: Array<() => void> = [];\r\n\r\n for (const [agentName, agentProcess] of team.processes) {\r\n const unsubscribe = agentProcess.onMessage((method, params) => {\r\n callback(agentName, method, params);\r\n });\r\n cleanups.push(unsubscribe);\r\n }\r\n\r\n return () => {\r\n for (const cleanup of cleanups) cleanup();\r\n };\r\n }\r\n\r\n /** Assign a task to a specific agent via IPC. */\r\n assignTask(\r\n teamName: string,\r\n agentName: string,\r\n taskId: string,\r\n subject: string,\r\n description: string,\r\n ): void {\r\n const team = this.getActiveTeam(teamName);\r\n const agentProcess = team.processes.get(agentName);\r\n if (agentProcess) {\r\n agentProcess.assignTask(taskId, subject, description);\r\n }\r\n }\r\n\r\n /** Check whether a team is currently active in memory. */\r\n isTeamActive(name: string): boolean {\r\n return this.activeTeams.has(name);\r\n }\r\n\r\n /** Shut down all active teams. Call during application cleanup. */\r\n async shutdownAll(): Promise<void> {\r\n const names = [...this.activeTeams.keys()];\r\n await Promise.allSettled(names.map((n) => this.deleteTeam(n)));\r\n }\r\n\r\n // ── Private ──────────────────────────────────────────────────────────\r\n\r\n private getActiveTeam(teamName: string): IActiveTeam {\r\n const team = this.activeTeams.get(teamName);\r\n if (!team) {\r\n throw new Error(`Team not active: ${teamName}`);\r\n }\r\n return team;\r\n }\r\n\r\n private saveTeamConfig(name: string, config: ITeamConfig): void {\r\n const teamDir = join(getTeamsDir(), name);\r\n ensureDirectory(teamDir);\r\n\r\n const serialized: ISerializedTeamConfig = {\r\n teamName: config.teamName,\r\n description: config.description,\r\n status: config.status,\r\n members: config.members,\r\n createdAt: config.createdAt.toISOString(),\r\n };\r\n\r\n const configPath = join(teamDir, \"config.json\");\r\n writeFileSync(configPath, JSON.stringify(serialized, null, 2), {\r\n encoding: \"utf-8\",\r\n mode: 0o644,\r\n });\r\n }\r\n\r\n private loadTeamConfig(name: string): ITeamConfig {\r\n const configPath = join(getTeamsDir(), name, \"config.json\");\r\n if (!existsSync(configPath)) {\r\n throw new Error(`Team config not found: ${name}`);\r\n }\r\n\r\n const raw = readFileSync(configPath, \"utf-8\");\r\n const data = JSON.parse(raw) as ISerializedTeamConfig;\r\n\r\n return {\r\n teamName: data.teamName,\r\n description: data.description,\r\n status: data.status,\r\n members: data.members,\r\n createdAt: new Date(data.createdAt),\r\n };\r\n }\r\n\r\n private async shutdownAgents(team: IActiveTeam): Promise<void> {\r\n const stopPromises: Promise<void>[] = [];\r\n\r\n for (const [agentName, agentProcess] of team.processes) {\r\n stopPromises.push(\r\n agentProcess.stop().catch((error: unknown) => {\r\n const reason =\r\n error instanceof Error ? error.message : String(error);\r\n logger.error(\r\n { agent: agentName, error: reason },\r\n \"Error stopping agent\",\r\n );\r\n }),\r\n );\r\n }\r\n\r\n await Promise.allSettled(stopPromises);\r\n team.processes.clear();\r\n }\r\n}\r\n"]}