ccjk 14.2.2 → 15.1.0

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 (532) hide show
  1. package/LICENSE +1 -1
  2. package/README.md +75 -338
  3. package/dist/cli.js +89 -0
  4. package/dist/cli.js.map +1 -0
  5. package/dist/commands/detect.js +15 -0
  6. package/dist/commands/detect.js.map +1 -0
  7. package/dist/commands/doctor.js +68 -0
  8. package/dist/commands/doctor.js.map +1 -0
  9. package/dist/commands/git-install.js +50 -0
  10. package/dist/commands/git-install.js.map +1 -0
  11. package/dist/commands/init.js +165 -0
  12. package/dist/commands/init.js.map +1 -0
  13. package/dist/commands/mcp.js +66 -0
  14. package/dist/commands/mcp.js.map +1 -0
  15. package/dist/commands/menu.js +42 -0
  16. package/dist/commands/menu.js.map +1 -0
  17. package/dist/commands/profile.js +138 -0
  18. package/dist/commands/profile.js.map +1 -0
  19. package/dist/core/detect.js +24 -0
  20. package/dist/core/detect.js.map +1 -0
  21. package/dist/core/lint.js +49 -0
  22. package/dist/core/lint.js.map +1 -0
  23. package/dist/core/mcp.js +41 -0
  24. package/dist/core/mcp.js.map +1 -0
  25. package/dist/core/paths.js +9 -0
  26. package/dist/core/paths.js.map +1 -0
  27. package/dist/core/profiles.js +104 -0
  28. package/dist/core/profiles.js.map +1 -0
  29. package/dist/core/providers.js +53 -0
  30. package/dist/core/providers.js.map +1 -0
  31. package/dist/core/settings.js +31 -0
  32. package/dist/core/settings.js.map +1 -0
  33. package/dist/core/slash-templates.js +56 -0
  34. package/dist/core/slash-templates.js.map +1 -0
  35. package/dist/core/tools.js +27 -0
  36. package/dist/core/tools.js.map +1 -0
  37. package/package.json +43 -164
  38. package/README.HONEST.md +0 -176
  39. package/README.en.md +0 -67
  40. package/README.ja.md +0 -67
  41. package/README.ko.md +0 -67
  42. package/README.zh-CN.md +0 -86
  43. package/bin/ccjk.mjs +0 -5
  44. package/bin/ccjk.ts +0 -222
  45. package/dist/chunks/agent-teams.mjs +0 -145
  46. package/dist/chunks/agent.mjs +0 -1439
  47. package/dist/chunks/agents.mjs +0 -3783
  48. package/dist/chunks/api-cli.mjs +0 -135
  49. package/dist/chunks/api-config-selector.mjs +0 -159
  50. package/dist/chunks/api-providers.mjs +0 -144
  51. package/dist/chunks/api.mjs +0 -115
  52. package/dist/chunks/auto-bootstrap.mjs +0 -358
  53. package/dist/chunks/auto-fixer.mjs +0 -95
  54. package/dist/chunks/auto-updater.mjs +0 -507
  55. package/dist/chunks/banner.mjs +0 -173
  56. package/dist/chunks/bash.mjs +0 -187
  57. package/dist/chunks/boost.mjs +0 -474
  58. package/dist/chunks/brain-config.mjs +0 -75
  59. package/dist/chunks/brain-status.mjs +0 -89
  60. package/dist/chunks/ccjk-agents.mjs +0 -416
  61. package/dist/chunks/ccjk-all.mjs +0 -1046
  62. package/dist/chunks/ccjk-config.mjs +0 -445
  63. package/dist/chunks/ccjk-hooks.mjs +0 -1074
  64. package/dist/chunks/ccjk-mcp.mjs +0 -763
  65. package/dist/chunks/ccjk-setup.mjs +0 -765
  66. package/dist/chunks/ccjk-skills.mjs +0 -518
  67. package/dist/chunks/ccr.mjs +0 -109
  68. package/dist/chunks/ccu.mjs +0 -40
  69. package/dist/chunks/check-updates.mjs +0 -117
  70. package/dist/chunks/claude-code-incremental-manager.mjs +0 -761
  71. package/dist/chunks/claude-config.mjs +0 -606
  72. package/dist/chunks/claude-config2.mjs +0 -62
  73. package/dist/chunks/claude-wrapper.mjs +0 -85
  74. package/dist/chunks/clavue-config.mjs +0 -1454
  75. package/dist/chunks/cleanup-migration.mjs +0 -20
  76. package/dist/chunks/cli-hook.mjs +0 -4096
  77. package/dist/chunks/cloud-sync.mjs +0 -29
  78. package/dist/chunks/code-type-resolver.mjs +0 -880
  79. package/dist/chunks/codex-config-switch.mjs +0 -452
  80. package/dist/chunks/codex-provider-manager.mjs +0 -238
  81. package/dist/chunks/codex-uninstaller.mjs +0 -404
  82. package/dist/chunks/codex.mjs +0 -2141
  83. package/dist/chunks/commands.mjs +0 -108
  84. package/dist/chunks/commands2.mjs +0 -421
  85. package/dist/chunks/commit.mjs +0 -140
  86. package/dist/chunks/completion.mjs +0 -517
  87. package/dist/chunks/config-consolidator.mjs +0 -172
  88. package/dist/chunks/config-switch.mjs +0 -334
  89. package/dist/chunks/config.mjs +0 -558
  90. package/dist/chunks/config2.mjs +0 -484
  91. package/dist/chunks/config3.mjs +0 -486
  92. package/dist/chunks/constants.mjs +0 -323
  93. package/dist/chunks/context-opt.mjs +0 -444
  94. package/dist/chunks/context.mjs +0 -974
  95. package/dist/chunks/dashboard.mjs +0 -481
  96. package/dist/chunks/doctor.mjs +0 -1301
  97. package/dist/chunks/eval.mjs +0 -502
  98. package/dist/chunks/evolution.mjs +0 -322
  99. package/dist/chunks/features.mjs +0 -715
  100. package/dist/chunks/fish.mjs +0 -181
  101. package/dist/chunks/fs-operations.mjs +0 -180
  102. package/dist/chunks/health-alerts.mjs +0 -830
  103. package/dist/chunks/help.mjs +0 -341
  104. package/dist/chunks/hook-installer.mjs +0 -48
  105. package/dist/chunks/impact.mjs +0 -651
  106. package/dist/chunks/index.mjs +0 -23
  107. package/dist/chunks/index10.mjs +0 -19
  108. package/dist/chunks/index11.mjs +0 -1171
  109. package/dist/chunks/index12.mjs +0 -218
  110. package/dist/chunks/index13.mjs +0 -679
  111. package/dist/chunks/index14.mjs +0 -1009
  112. package/dist/chunks/index15.mjs +0 -194
  113. package/dist/chunks/index2.mjs +0 -7637
  114. package/dist/chunks/index3.mjs +0 -171
  115. package/dist/chunks/index4.mjs +0 -26
  116. package/dist/chunks/index5.mjs +0 -19
  117. package/dist/chunks/index6.mjs +0 -19092
  118. package/dist/chunks/index7.mjs +0 -616
  119. package/dist/chunks/index8.mjs +0 -1602
  120. package/dist/chunks/index9.mjs +0 -5384
  121. package/dist/chunks/init.mjs +0 -1911
  122. package/dist/chunks/installer.mjs +0 -757
  123. package/dist/chunks/installer2.mjs +0 -103
  124. package/dist/chunks/interview.mjs +0 -2927
  125. package/dist/chunks/json-config.mjs +0 -60
  126. package/dist/chunks/linux.mjs +0 -3863
  127. package/dist/chunks/macos.mjs +0 -69
  128. package/dist/chunks/main.mjs +0 -635
  129. package/dist/chunks/manager.mjs +0 -1048
  130. package/dist/chunks/marketplace.mjs +0 -265
  131. package/dist/chunks/mcp-cli.mjs +0 -205
  132. package/dist/chunks/mcp-performance.mjs +0 -187
  133. package/dist/chunks/mcp.mjs +0 -667
  134. package/dist/chunks/memory-check.mjs +0 -2973
  135. package/dist/chunks/memory-paths.mjs +0 -259
  136. package/dist/chunks/memory-sync.mjs +0 -209
  137. package/dist/chunks/memory.mjs +0 -354
  138. package/dist/chunks/metrics-display.mjs +0 -153
  139. package/dist/chunks/monitor.mjs +0 -1856
  140. package/dist/chunks/notification.mjs +0 -1864
  141. package/dist/chunks/onboarding.mjs +0 -386
  142. package/dist/chunks/package.mjs +0 -3
  143. package/dist/chunks/paradigm.mjs +0 -74
  144. package/dist/chunks/permission-manager.mjs +0 -250
  145. package/dist/chunks/permissions.mjs +0 -265
  146. package/dist/chunks/persistence-manager.mjs +0 -801
  147. package/dist/chunks/persistence.mjs +0 -707
  148. package/dist/chunks/platform.mjs +0 -395
  149. package/dist/chunks/plugin.mjs +0 -1936
  150. package/dist/chunks/powershell.mjs +0 -213
  151. package/dist/chunks/prompts.mjs +0 -244
  152. package/dist/chunks/providers.mjs +0 -263
  153. package/dist/chunks/quick-actions.mjs +0 -335
  154. package/dist/chunks/quick-provider.mjs +0 -755
  155. package/dist/chunks/quick-setup.mjs +0 -421
  156. package/dist/chunks/remote.mjs +0 -497
  157. package/dist/chunks/research.mjs +0 -1904
  158. package/dist/chunks/rollback.mjs +0 -38
  159. package/dist/chunks/session-manager.mjs +0 -1371
  160. package/dist/chunks/session.mjs +0 -878
  161. package/dist/chunks/sessions.mjs +0 -106
  162. package/dist/chunks/silent-updater.mjs +0 -396
  163. package/dist/chunks/simple-config.mjs +0 -122
  164. package/dist/chunks/skill.mjs +0 -117
  165. package/dist/chunks/skill2.mjs +0 -9052
  166. package/dist/chunks/skills-sync.mjs +0 -1343
  167. package/dist/chunks/skills.mjs +0 -577
  168. package/dist/chunks/slash-commands.mjs +0 -208
  169. package/dist/chunks/smart-guide.mjs +0 -247
  170. package/dist/chunks/snapshot.mjs +0 -58
  171. package/dist/chunks/startup.mjs +0 -487
  172. package/dist/chunks/stats.mjs +0 -191
  173. package/dist/chunks/status.mjs +0 -471
  174. package/dist/chunks/team.mjs +0 -63
  175. package/dist/chunks/thinking.mjs +0 -626
  176. package/dist/chunks/trace.mjs +0 -57
  177. package/dist/chunks/uninstall.mjs +0 -852
  178. package/dist/chunks/update.mjs +0 -174
  179. package/dist/chunks/upgrade-manager.mjs +0 -204
  180. package/dist/chunks/upgrade.mjs +0 -133
  181. package/dist/chunks/version-checker.mjs +0 -891
  182. package/dist/chunks/vim.mjs +0 -903
  183. package/dist/chunks/windows.mjs +0 -14
  184. package/dist/chunks/workflows.mjs +0 -633
  185. package/dist/chunks/wsl.mjs +0 -129
  186. package/dist/chunks/zero-config.mjs +0 -871
  187. package/dist/chunks/zsh.mjs +0 -182
  188. package/dist/cli.d.mts +0 -1
  189. package/dist/cli.d.ts +0 -1
  190. package/dist/cli.mjs +0 -2684
  191. package/dist/i18n/locales/en/agent-teams.json +0 -18
  192. package/dist/i18n/locales/en/agentBrowser.json +0 -80
  193. package/dist/i18n/locales/en/agents.json +0 -135
  194. package/dist/i18n/locales/en/api.json +0 -63
  195. package/dist/i18n/locales/en/ccjk-agents.json +0 -33
  196. package/dist/i18n/locales/en/ccjk-all.json +0 -23
  197. package/dist/i18n/locales/en/ccjk-skills.json +0 -22
  198. package/dist/i18n/locales/en/ccjk.json +0 -276
  199. package/dist/i18n/locales/en/ccr.json +0 -65
  200. package/dist/i18n/locales/en/claude-md.json +0 -73
  201. package/dist/i18n/locales/en/cli.json +0 -148
  202. package/dist/i18n/locales/en/cloud-setup.json +0 -31
  203. package/dist/i18n/locales/en/cloud-sync.json +0 -147
  204. package/dist/i18n/locales/en/cloud.json +0 -40
  205. package/dist/i18n/locales/en/cloudPlugins.json +0 -118
  206. package/dist/i18n/locales/en/codex.json +0 -184
  207. package/dist/i18n/locales/en/cometix.json +0 -29
  208. package/dist/i18n/locales/en/common.json +0 -68
  209. package/dist/i18n/locales/en/config.json +0 -108
  210. package/dist/i18n/locales/en/configuration.json +0 -236
  211. package/dist/i18n/locales/en/context.json +0 -85
  212. package/dist/i18n/locales/en/dashboard.json +0 -78
  213. package/dist/i18n/locales/en/errors.json +0 -26
  214. package/dist/i18n/locales/en/evolution.json +0 -54
  215. package/dist/i18n/locales/en/hooks.json +0 -74
  216. package/dist/i18n/locales/en/hooksSync.json +0 -133
  217. package/dist/i18n/locales/en/installation.json +0 -83
  218. package/dist/i18n/locales/en/interview.json +0 -104
  219. package/dist/i18n/locales/en/language.json +0 -19
  220. package/dist/i18n/locales/en/lsp.json +0 -78
  221. package/dist/i18n/locales/en/marketplace.json +0 -116
  222. package/dist/i18n/locales/en/mcp.json +0 -180
  223. package/dist/i18n/locales/en/memory.json +0 -23
  224. package/dist/i18n/locales/en/menu.json +0 -299
  225. package/dist/i18n/locales/en/multi-config.json +0 -79
  226. package/dist/i18n/locales/en/notification.json +0 -307
  227. package/dist/i18n/locales/en/permissions.json +0 -95
  228. package/dist/i18n/locales/en/persistence.json +0 -127
  229. package/dist/i18n/locales/en/plugins.json +0 -146
  230. package/dist/i18n/locales/en/quick-actions.json +0 -78
  231. package/dist/i18n/locales/en/registry.json +0 -54
  232. package/dist/i18n/locales/en/remote.json +0 -93
  233. package/dist/i18n/locales/en/sandbox.json +0 -44
  234. package/dist/i18n/locales/en/setup.json +0 -44
  235. package/dist/i18n/locales/en/shencha.json +0 -14
  236. package/dist/i18n/locales/en/skills.json +0 -100
  237. package/dist/i18n/locales/en/skillsSync.json +0 -74
  238. package/dist/i18n/locales/en/smartGuide.json +0 -49
  239. package/dist/i18n/locales/en/stats.json +0 -20
  240. package/dist/i18n/locales/en/subagent.json +0 -69
  241. package/dist/i18n/locales/en/superpowers.json +0 -117
  242. package/dist/i18n/locales/en/team.json +0 -7
  243. package/dist/i18n/locales/en/thinking.json +0 -65
  244. package/dist/i18n/locales/en/tools.json +0 -42
  245. package/dist/i18n/locales/en/uninstall.json +0 -56
  246. package/dist/i18n/locales/en/updater.json +0 -29
  247. package/dist/i18n/locales/en/vim.json +0 -169
  248. package/dist/i18n/locales/en/workflow.json +0 -55
  249. package/dist/i18n/locales/en/workspace.json +0 -108
  250. package/dist/i18n/locales/zh-CN/agent-teams.json +0 -18
  251. package/dist/i18n/locales/zh-CN/agentBrowser.json +0 -80
  252. package/dist/i18n/locales/zh-CN/agents.json +0 -135
  253. package/dist/i18n/locales/zh-CN/api.json +0 -63
  254. package/dist/i18n/locales/zh-CN/ccjk-agents.json +0 -33
  255. package/dist/i18n/locales/zh-CN/ccjk-all.json +0 -23
  256. package/dist/i18n/locales/zh-CN/ccjk-skills.json +0 -22
  257. package/dist/i18n/locales/zh-CN/ccjk.json +0 -276
  258. package/dist/i18n/locales/zh-CN/ccr.json +0 -65
  259. package/dist/i18n/locales/zh-CN/claude-md.json +0 -73
  260. package/dist/i18n/locales/zh-CN/cli.json +0 -148
  261. package/dist/i18n/locales/zh-CN/cloud-setup.json +0 -31
  262. package/dist/i18n/locales/zh-CN/cloud-sync.json +0 -147
  263. package/dist/i18n/locales/zh-CN/cloud.json +0 -40
  264. package/dist/i18n/locales/zh-CN/cloudPlugins.json +0 -118
  265. package/dist/i18n/locales/zh-CN/codex.json +0 -184
  266. package/dist/i18n/locales/zh-CN/cometix.json +0 -29
  267. package/dist/i18n/locales/zh-CN/common.json +0 -68
  268. package/dist/i18n/locales/zh-CN/config.json +0 -108
  269. package/dist/i18n/locales/zh-CN/configuration.json +0 -234
  270. package/dist/i18n/locales/zh-CN/context.json +0 -85
  271. package/dist/i18n/locales/zh-CN/dashboard.json +0 -78
  272. package/dist/i18n/locales/zh-CN/errors.json +0 -26
  273. package/dist/i18n/locales/zh-CN/evolution.json +0 -54
  274. package/dist/i18n/locales/zh-CN/hooks.json +0 -74
  275. package/dist/i18n/locales/zh-CN/hooksSync.json +0 -133
  276. package/dist/i18n/locales/zh-CN/installation.json +0 -83
  277. package/dist/i18n/locales/zh-CN/interview.json +0 -104
  278. package/dist/i18n/locales/zh-CN/language.json +0 -19
  279. package/dist/i18n/locales/zh-CN/lsp.json +0 -78
  280. package/dist/i18n/locales/zh-CN/marketplace.json +0 -116
  281. package/dist/i18n/locales/zh-CN/mcp.json +0 -180
  282. package/dist/i18n/locales/zh-CN/memory.json +0 -23
  283. package/dist/i18n/locales/zh-CN/menu.json +0 -299
  284. package/dist/i18n/locales/zh-CN/multi-config.json +0 -79
  285. package/dist/i18n/locales/zh-CN/notification.json +0 -307
  286. package/dist/i18n/locales/zh-CN/permissions.json +0 -95
  287. package/dist/i18n/locales/zh-CN/persistence.json +0 -127
  288. package/dist/i18n/locales/zh-CN/plugins.json +0 -146
  289. package/dist/i18n/locales/zh-CN/quick-actions.json +0 -78
  290. package/dist/i18n/locales/zh-CN/registry.json +0 -54
  291. package/dist/i18n/locales/zh-CN/remote.json +0 -93
  292. package/dist/i18n/locales/zh-CN/sandbox.json +0 -44
  293. package/dist/i18n/locales/zh-CN/setup.json +0 -44
  294. package/dist/i18n/locales/zh-CN/shencha.json +0 -14
  295. package/dist/i18n/locales/zh-CN/skills.json +0 -100
  296. package/dist/i18n/locales/zh-CN/skillsSync.json +0 -74
  297. package/dist/i18n/locales/zh-CN/smartGuide.json +0 -49
  298. package/dist/i18n/locales/zh-CN/stats.json +0 -20
  299. package/dist/i18n/locales/zh-CN/subagent.json +0 -69
  300. package/dist/i18n/locales/zh-CN/superpowers.json +0 -117
  301. package/dist/i18n/locales/zh-CN/team.json +0 -7
  302. package/dist/i18n/locales/zh-CN/thinking.json +0 -65
  303. package/dist/i18n/locales/zh-CN/tools.json +0 -42
  304. package/dist/i18n/locales/zh-CN/uninstall.json +0 -56
  305. package/dist/i18n/locales/zh-CN/updater.json +0 -29
  306. package/dist/i18n/locales/zh-CN/vim.json +0 -169
  307. package/dist/i18n/locales/zh-CN/workflow.json +0 -55
  308. package/dist/i18n/locales/zh-CN/workspace.json +0 -108
  309. package/dist/index.d.mts +0 -5658
  310. package/dist/index.d.ts +0 -5658
  311. package/dist/index.mjs +0 -3732
  312. package/dist/shared/ccjk.5bEolFrk.mjs +0 -254
  313. package/dist/shared/ccjk.8oaxX4iR.mjs +0 -90
  314. package/dist/shared/ccjk.B2U7DsPy.mjs +0 -31
  315. package/dist/shared/ccjk.B2f-cwUP.mjs +0 -468
  316. package/dist/shared/ccjk.BAGoDD49.mjs +0 -36
  317. package/dist/shared/ccjk.BBtCGd_g.mjs +0 -899
  318. package/dist/shared/ccjk.BFQ7yr5S.mjs +0 -16
  319. package/dist/shared/ccjk.BLsIiTqO.mjs +0 -449
  320. package/dist/shared/ccjk.BXv8aYs1.mjs +0 -170
  321. package/dist/shared/ccjk.BnsY5WxD.mjs +0 -171
  322. package/dist/shared/ccjk.BoApaI4j.mjs +0 -28
  323. package/dist/shared/ccjk.Bq8TqZG_.mjs +0 -189
  324. package/dist/shared/ccjk.BtrioX1Z.mjs +0 -25
  325. package/dist/shared/ccjk.Bx_rmYfN.mjs +0 -69
  326. package/dist/shared/ccjk.BzPbSEP2.mjs +0 -115
  327. package/dist/shared/ccjk.C0WLUnFV.mjs +0 -293
  328. package/dist/shared/ccjk.C1hANZTu.mjs +0 -19
  329. package/dist/shared/ccjk.C2jHOZVP.mjs +0 -52
  330. package/dist/shared/ccjk.CNhnT6uQ.mjs +0 -636
  331. package/dist/shared/ccjk.COweQ1RR.mjs +0 -5
  332. package/dist/shared/ccjk.CfKKcvWy.mjs +0 -126
  333. package/dist/shared/ccjk.Cjgrln_h.mjs +0 -297
  334. package/dist/shared/ccjk.CoCHVXl3.mjs +0 -3951
  335. package/dist/shared/ccjk.CwGZSTAK.mjs +0 -319
  336. package/dist/shared/ccjk.CxpGa6MC.mjs +0 -2724
  337. package/dist/shared/ccjk.D-magaEx.mjs +0 -763
  338. package/dist/shared/ccjk.D0g2ABGg.mjs +0 -171
  339. package/dist/shared/ccjk.D6ycHbak.mjs +0 -270
  340. package/dist/shared/ccjk.D75wivnp.mjs +0 -142
  341. package/dist/shared/ccjk.DDL-4C-k.mjs +0 -100
  342. package/dist/shared/ccjk.DFRPtmK_.mjs +0 -75
  343. package/dist/shared/ccjk.DMV3x5Sd.mjs +0 -299
  344. package/dist/shared/ccjk.DZ2LLOa-.mjs +0 -2195
  345. package/dist/shared/ccjk.DbigonEQ.mjs +0 -698
  346. package/dist/shared/ccjk.DcMvE7lf.mjs +0 -618
  347. package/dist/shared/ccjk.DeWpAShp.mjs +0 -1828
  348. package/dist/shared/ccjk.DhJ1kyDR.mjs +0 -30
  349. package/dist/shared/ccjk.DlTXS9rP.mjs +0 -224
  350. package/dist/shared/ccjk.DopKzo3z.mjs +0 -305
  351. package/dist/shared/ccjk.DsZsc4LR.mjs +0 -1280
  352. package/dist/shared/ccjk.DuzJZlgj.mjs +0 -418
  353. package/dist/shared/ccjk.Dxgd2vjc.mjs +0 -444
  354. package/dist/shared/ccjk.J8YiPsOw.mjs +0 -259
  355. package/dist/shared/ccjk.KfSWcGlE.mjs +0 -38
  356. package/dist/shared/ccjk.L7yC58_i.mjs +0 -225
  357. package/dist/shared/ccjk.MwtjAULc.mjs +0 -1447
  358. package/dist/shared/ccjk.OJKHVSOb.mjs +0 -2005
  359. package/dist/shared/ccjk.OTnevPNE.mjs +0 -225
  360. package/dist/shared/ccjk.RyizuzOI.mjs +0 -21
  361. package/dist/shared/ccjk.T_cX87dY.mjs +0 -15
  362. package/dist/shared/ccjk.bQ7Dh1g4.mjs +0 -249
  363. package/dist/shared/ccjk.gDEDGD_t.mjs +0 -38
  364. package/dist/shared/ccjk.hoqrwWdN.mjs +0 -333
  365. package/dist/shared/ccjk.i_vn-9C3.mjs +0 -317
  366. package/dist/shared/ccjk.lG3ccFjm.mjs +0 -885
  367. package/dist/shared/ccjk.wLJHO0Af.mjs +0 -244
  368. package/dist/shared/ccjk.y-a_1vK4.mjs +0 -5127
  369. package/dist/templates/agents/README.md +0 -78
  370. package/dist/templates/agents/fullstack-developer.json +0 -70
  371. package/dist/templates/agents/go-expert.json +0 -69
  372. package/dist/templates/agents/index.json +0 -64
  373. package/dist/templates/agents/python-expert.json +0 -69
  374. package/dist/templates/agents/react-specialist.json +0 -69
  375. package/dist/templates/agents/testing-automation-expert.json +0 -70
  376. package/dist/templates/agents/typescript-architect.json +0 -69
  377. package/dist/templates/claude-code/common/settings.json +0 -109
  378. package/dist/templates/common/error-prevention.md +0 -267
  379. package/dist/templates/common/karpathy-baseline.md +0 -83
  380. package/dist/templates/common/output-styles/zh-CN/carmack-mode.md +0 -381
  381. package/dist/templates/common/output-styles/zh-CN/codex-rigor-mode.md +0 -114
  382. package/dist/templates/common/output-styles/zh-CN/dhh-mode.md +0 -265
  383. package/dist/templates/common/output-styles/zh-CN/evan-you-mode.md +0 -539
  384. package/dist/templates/common/output-styles/zh-CN/jobs-mode.md +0 -369
  385. package/dist/templates/common/output-styles/zh-CN/linus-mode.md +0 -135
  386. package/dist/templates/common/output-styles/zh-CN/uncle-bob-mode.md +0 -221
  387. package/dist/templates/common/workflow/continuousDelivery/en/continuous-delivery.md +0 -628
  388. package/dist/templates/common/workflow/continuousDelivery/zh-CN/continuous-delivery.md +0 -628
  389. package/dist/templates/common/workflow/essential/en/agents/ccjk-config-agent.md +0 -187
  390. package/dist/templates/common/workflow/essential/en/agents/ccjk-mcp-agent.md +0 -191
  391. package/dist/templates/common/workflow/essential/en/agents/ccjk-skill-agent.md +0 -249
  392. package/dist/templates/common/workflow/essential/en/agents/ccjk-workflow-agent.md +0 -277
  393. package/dist/templates/common/workflow/essential/en/agents/get-current-datetime.md +0 -29
  394. package/dist/templates/common/workflow/essential/en/agents/init-architect.md +0 -115
  395. package/dist/templates/common/workflow/essential/en/agents/ui-ux-designer.md +0 -91
  396. package/dist/templates/common/workflow/essential/en/feat.md +0 -92
  397. package/dist/templates/common/workflow/essential/en/goal.md +0 -147
  398. package/dist/templates/common/workflow/essential/en/init-project.md +0 -53
  399. package/dist/templates/common/workflow/essential/zh-CN/agents/get-current-datetime.md +0 -29
  400. package/dist/templates/common/workflow/essential/zh-CN/agents/init-architect.md +0 -115
  401. package/dist/templates/common/workflow/essential/zh-CN/agents/ui-ux-designer.md +0 -91
  402. package/dist/templates/common/workflow/essential/zh-CN/feat.md +0 -315
  403. package/dist/templates/common/workflow/essential/zh-CN/goal.md +0 -146
  404. package/dist/templates/common/workflow/essential/zh-CN/init-project.md +0 -53
  405. package/dist/templates/common/workflow/git/en/git-cleanBranches.md +0 -102
  406. package/dist/templates/common/workflow/git/en/git-commit.md +0 -205
  407. package/dist/templates/common/workflow/git/en/git-rollback.md +0 -90
  408. package/dist/templates/common/workflow/git/en/git-worktree.md +0 -276
  409. package/dist/templates/common/workflow/git/zh-CN/git-cleanBranches.md +0 -102
  410. package/dist/templates/common/workflow/git/zh-CN/git-commit.md +0 -205
  411. package/dist/templates/common/workflow/git/zh-CN/git-rollback.md +0 -90
  412. package/dist/templates/common/workflow/git/zh-CN/git-worktree.md +0 -276
  413. package/dist/templates/common/workflow/interview/en/interview.md +0 -67
  414. package/dist/templates/common/workflow/interview/zh-CN/interview.md +0 -67
  415. package/dist/templates/common/workflow/linearMethod/en/linear-method.md +0 -651
  416. package/dist/templates/common/workflow/linearMethod/zh-CN/linear-method.md +0 -752
  417. package/dist/templates/common/workflow/refactoringMaster/en/refactoring-master.md +0 -516
  418. package/dist/templates/common/workflow/refactoringMaster/zh-CN/refactoring-master.md +0 -812
  419. package/dist/templates/common/workflow/sixStep/en/workflow.md +0 -83
  420. package/dist/templates/common/workflow/sixStep/zh-CN/workflow.md +0 -359
  421. package/dist/templates/common/workflow/specFirstTDD/en/spec-first-tdd.md +0 -364
  422. package/dist/templates/common/workflow/specFirstTDD/zh-CN/spec-first-tdd.md +0 -366
  423. package/dist/templates/hooks/README.md +0 -212
  424. package/dist/templates/hooks/git-workflow-hooks.md +0 -551
  425. package/dist/templates/hooks/post-test/coverage.json +0 -21
  426. package/dist/templates/hooks/post-test/summary.json +0 -21
  427. package/dist/templates/hooks/post-test-coverage.md +0 -434
  428. package/dist/templates/hooks/pre-commit/eslint.json +0 -22
  429. package/dist/templates/hooks/pre-commit/prettier.json +0 -22
  430. package/dist/templates/hooks/pre-commit-black.md +0 -274
  431. package/dist/templates/hooks/pre-commit-eslint.md +0 -153
  432. package/dist/templates/hooks/pre-commit-gofmt.md +0 -284
  433. package/dist/templates/hooks/pre-commit-prettier.md +0 -212
  434. package/dist/templates/hooks/pre-commit-type-check.md +0 -377
  435. package/dist/templates/skills/ccjk-init.md +0 -154
  436. package/dist/templates/skills/ccjk-mcp-setup.md +0 -205
  437. package/dist/templates/skills/ccjk-troubleshoot.md +0 -228
  438. package/dist/templates/skills/django-patterns.md +0 -1016
  439. package/dist/templates/skills/git-workflow.md +0 -748
  440. package/dist/templates/skills/go-idioms.md +0 -963
  441. package/dist/templates/skills/index.json +0 -132
  442. package/dist/templates/skills/nextjs-optimization.md +0 -694
  443. package/dist/templates/skills/python-pep8.md +0 -852
  444. package/dist/templates/skills/react-patterns.md +0 -686
  445. package/dist/templates/skills/rust-patterns.md +0 -1057
  446. package/dist/templates/skills/security-best-practices.md +0 -1413
  447. package/dist/templates/skills/testing-best-practices.md +0 -1315
  448. package/dist/templates/skills/ts-best-practices.md +0 -354
  449. package/templates/agents/README.md +0 -78
  450. package/templates/agents/fullstack-developer.json +0 -70
  451. package/templates/agents/go-expert.json +0 -69
  452. package/templates/agents/index.json +0 -64
  453. package/templates/agents/python-expert.json +0 -69
  454. package/templates/agents/react-specialist.json +0 -69
  455. package/templates/agents/testing-automation-expert.json +0 -70
  456. package/templates/agents/typescript-architect.json +0 -69
  457. package/templates/claude-code/common/settings.json +0 -109
  458. package/templates/common/error-prevention.md +0 -267
  459. package/templates/common/karpathy-baseline.md +0 -83
  460. package/templates/common/output-styles/zh-CN/carmack-mode.md +0 -381
  461. package/templates/common/output-styles/zh-CN/codex-rigor-mode.md +0 -114
  462. package/templates/common/output-styles/zh-CN/dhh-mode.md +0 -265
  463. package/templates/common/output-styles/zh-CN/evan-you-mode.md +0 -539
  464. package/templates/common/output-styles/zh-CN/jobs-mode.md +0 -369
  465. package/templates/common/output-styles/zh-CN/linus-mode.md +0 -135
  466. package/templates/common/output-styles/zh-CN/uncle-bob-mode.md +0 -221
  467. package/templates/common/workflow/continuousDelivery/en/continuous-delivery.md +0 -628
  468. package/templates/common/workflow/continuousDelivery/zh-CN/continuous-delivery.md +0 -628
  469. package/templates/common/workflow/essential/en/agents/ccjk-config-agent.md +0 -187
  470. package/templates/common/workflow/essential/en/agents/ccjk-mcp-agent.md +0 -191
  471. package/templates/common/workflow/essential/en/agents/ccjk-skill-agent.md +0 -249
  472. package/templates/common/workflow/essential/en/agents/ccjk-workflow-agent.md +0 -277
  473. package/templates/common/workflow/essential/en/agents/get-current-datetime.md +0 -29
  474. package/templates/common/workflow/essential/en/agents/init-architect.md +0 -115
  475. package/templates/common/workflow/essential/en/agents/ui-ux-designer.md +0 -91
  476. package/templates/common/workflow/essential/en/feat.md +0 -92
  477. package/templates/common/workflow/essential/en/goal.md +0 -147
  478. package/templates/common/workflow/essential/en/init-project.md +0 -53
  479. package/templates/common/workflow/essential/zh-CN/agents/get-current-datetime.md +0 -29
  480. package/templates/common/workflow/essential/zh-CN/agents/init-architect.md +0 -115
  481. package/templates/common/workflow/essential/zh-CN/agents/ui-ux-designer.md +0 -91
  482. package/templates/common/workflow/essential/zh-CN/feat.md +0 -315
  483. package/templates/common/workflow/essential/zh-CN/goal.md +0 -146
  484. package/templates/common/workflow/essential/zh-CN/init-project.md +0 -53
  485. package/templates/common/workflow/git/en/git-cleanBranches.md +0 -102
  486. package/templates/common/workflow/git/en/git-commit.md +0 -205
  487. package/templates/common/workflow/git/en/git-rollback.md +0 -90
  488. package/templates/common/workflow/git/en/git-worktree.md +0 -276
  489. package/templates/common/workflow/git/zh-CN/git-cleanBranches.md +0 -102
  490. package/templates/common/workflow/git/zh-CN/git-commit.md +0 -205
  491. package/templates/common/workflow/git/zh-CN/git-rollback.md +0 -90
  492. package/templates/common/workflow/git/zh-CN/git-worktree.md +0 -276
  493. package/templates/common/workflow/interview/en/interview.md +0 -67
  494. package/templates/common/workflow/interview/zh-CN/interview.md +0 -67
  495. package/templates/common/workflow/linearMethod/en/linear-method.md +0 -651
  496. package/templates/common/workflow/linearMethod/zh-CN/linear-method.md +0 -752
  497. package/templates/common/workflow/refactoringMaster/en/refactoring-master.md +0 -516
  498. package/templates/common/workflow/refactoringMaster/zh-CN/refactoring-master.md +0 -812
  499. package/templates/common/workflow/sixStep/en/workflow.md +0 -83
  500. package/templates/common/workflow/sixStep/zh-CN/workflow.md +0 -359
  501. package/templates/common/workflow/specFirstTDD/en/spec-first-tdd.md +0 -364
  502. package/templates/common/workflow/specFirstTDD/zh-CN/spec-first-tdd.md +0 -366
  503. package/templates/hooks/README.md +0 -212
  504. package/templates/hooks/git-workflow-hooks.md +0 -551
  505. package/templates/hooks/post-test/coverage.json +0 -21
  506. package/templates/hooks/post-test/summary.json +0 -21
  507. package/templates/hooks/post-test-coverage.md +0 -434
  508. package/templates/hooks/pre-commit/eslint.json +0 -22
  509. package/templates/hooks/pre-commit/prettier.json +0 -22
  510. package/templates/hooks/pre-commit-black.md +0 -274
  511. package/templates/hooks/pre-commit-eslint.md +0 -153
  512. package/templates/hooks/pre-commit-gofmt.md +0 -284
  513. package/templates/hooks/pre-commit-prettier.md +0 -212
  514. package/templates/hooks/pre-commit-type-check.md +0 -377
  515. package/templates/skills/basic.hbs +0 -72
  516. package/templates/skills/ccjk-init.md +0 -154
  517. package/templates/skills/ccjk-mcp-setup.md +0 -205
  518. package/templates/skills/ccjk-troubleshoot.md +0 -228
  519. package/templates/skills/code-refactor.hbs +0 -133
  520. package/templates/skills/code-review.hbs +0 -141
  521. package/templates/skills/django-patterns.md +0 -1016
  522. package/templates/skills/git-workflow.md +0 -748
  523. package/templates/skills/go-idioms.md +0 -963
  524. package/templates/skills/index.json +0 -132
  525. package/templates/skills/nextjs-optimization.md +0 -694
  526. package/templates/skills/python-pep8.md +0 -852
  527. package/templates/skills/react-patterns.md +0 -686
  528. package/templates/skills/rust-patterns.md +0 -1057
  529. package/templates/skills/security-best-practices.md +0 -1413
  530. package/templates/skills/testing-best-practices.md +0 -1315
  531. package/templates/skills/ts-best-practices.md +0 -354
  532. package/templates/skills/type-fix.hbs +0 -132
@@ -1,4096 +0,0 @@
1
- import { EventEmitter } from 'node:events';
2
- import { DEFAULT_CODE_TOOL_TYPE, isCodeToolType, getCodeToolNativeSlashCommands } from './constants.mjs';
3
- import { readZcfConfig } from './ccjk-config.mjs';
4
- import { a as getGlobalStateManager, g as getGlobalConvoyManager, c as contextLoader, S as SessionIntelligence } from './session-manager.mjs';
5
- import { l as logger } from '../shared/ccjk.8oaxX4iR.mjs';
6
- import { Buffer } from 'node:buffer';
7
- import { randomUUID } from 'node:crypto';
8
- import { existsSync, mkdirSync, writeFileSync, readFileSync } from 'node:fs';
9
- import { d as dirname, j as join } from '../shared/ccjk.bQ7Dh1g4.mjs';
10
- import { n as nanoid } from '../shared/ccjk.BoApaI4j.mjs';
11
- import process__default from 'node:process';
12
- import 'node:os';
13
- import './index2.mjs';
14
- import 'node:url';
15
- import '../shared/ccjk.BBtCGd_g.mjs';
16
- import './index3.mjs';
17
- import './fs-operations.mjs';
18
- import 'node:fs/promises';
19
- import './json-config.mjs';
20
- import '../shared/ccjk.RyizuzOI.mjs';
21
- import '../shared/ccjk.BAGoDD49.mjs';
22
- import './main.mjs';
23
- import 'module';
24
- import 'node:child_process';
25
- import 'node:path';
26
- import 'node:stream';
27
- import 'node:readline';
28
- import 'tinyglobby';
29
- import '../shared/ccjk.DlTXS9rP.mjs';
30
- import './index5.mjs';
31
- import '../shared/ccjk.wLJHO0Af.mjs';
32
-
33
- class HookRegistry {
34
- hooks = /* @__PURE__ */ new Map();
35
- /**
36
- * Register a hook for an event
37
- */
38
- register(event, hook) {
39
- const hooks = this.hooks.get(event) || [];
40
- hooks.push(hook);
41
- hooks.sort((a, b) => (b.priority || 0) - (a.priority || 0));
42
- this.hooks.set(event, hooks);
43
- logger.debug(`Registered hook "${hook.name}" for event "${event}"`);
44
- }
45
- /**
46
- * Unregister a hook
47
- */
48
- unregister(event, hookName) {
49
- const hooks = this.hooks.get(event);
50
- if (!hooks)
51
- return;
52
- const filtered = hooks.filter((h) => h.name !== hookName);
53
- this.hooks.set(event, filtered);
54
- logger.debug(`Unregistered hook "${hookName}" for event "${event}"`);
55
- }
56
- /**
57
- * Execute all hooks for an event
58
- * Returns false if any hook returns continue: false
59
- */
60
- async execute(context) {
61
- const hooks = this.hooks.get(context.event) || [];
62
- const enabledHooks = hooks.filter((h) => h.enabled !== false);
63
- if (enabledHooks.length === 0) {
64
- return { continue: true };
65
- }
66
- let currentContext = context;
67
- let aggregatedData = {};
68
- for (const hook of enabledHooks) {
69
- try {
70
- const result = await hook.fn(currentContext);
71
- if (result.data) {
72
- aggregatedData = { ...aggregatedData, ...result.data };
73
- }
74
- if (!result.continue) {
75
- return {
76
- continue: false,
77
- data: aggregatedData,
78
- error: result.error
79
- };
80
- }
81
- currentContext = {
82
- ...currentContext,
83
- data: { ...currentContext.data, ...aggregatedData }
84
- };
85
- } catch (error) {
86
- logger.error(`Hook "${hook.name}" failed:`, error);
87
- }
88
- }
89
- return {
90
- continue: true,
91
- data: aggregatedData
92
- };
93
- }
94
- /**
95
- * Get all registered hooks for an event
96
- */
97
- getHooks(event) {
98
- return this.hooks.get(event) || [];
99
- }
100
- /**
101
- * Clear all hooks
102
- */
103
- clear() {
104
- this.hooks.clear();
105
- }
106
- }
107
- const hookRegistry = new HookRegistry();
108
-
109
- async function emitCommandHookEvent(event, data, sessionId) {
110
- try {
111
- const context = {
112
- event,
113
- sessionId,
114
- data,
115
- timestamp: Date.now(),
116
- metadata: {
117
- source: "brain-router"
118
- }
119
- };
120
- await hookRegistry.execute(context);
121
- } catch (error) {
122
- logger.debug(`Command hook bridge skipped for "${event}": ${String(error)}`);
123
- }
124
- }
125
-
126
- const DEFAULT_CONFIG = {
127
- enablePersistence: false,
128
- maxHistorySize: 1e3,
129
- messageRetentionTime: 24 * 60 * 60 * 1e3,
130
- // 24 hours
131
- enableLogging: true,
132
- logLevel: "info",
133
- enableValidation: true,
134
- maxMessageSize: 1024 * 1024,
135
- // 1MB
136
- enableDeadLetterQueue: true
137
- };
138
- class FileMessageStorage {
139
- filePath;
140
- constructor(filePath) {
141
- this.filePath = filePath;
142
- this.ensureDirectory();
143
- }
144
- ensureDirectory() {
145
- const dir = dirname(this.filePath);
146
- if (!existsSync(dir)) {
147
- mkdirSync(dir, { recursive: true });
148
- }
149
- }
150
- async save(message) {
151
- try {
152
- const messages = await this.load();
153
- messages.push(message);
154
- writeFileSync(this.filePath, JSON.stringify(messages, null, 2), "utf-8");
155
- } catch (error) {
156
- console.error("Failed to save message:", error);
157
- throw error;
158
- }
159
- }
160
- async load(filter) {
161
- try {
162
- if (!existsSync(this.filePath)) {
163
- return [];
164
- }
165
- const content = readFileSync(this.filePath, "utf-8");
166
- const messages = JSON.parse(content);
167
- if (filter) {
168
- return messages.filter(filter);
169
- }
170
- return messages;
171
- } catch (error) {
172
- console.error("Failed to load messages:", error);
173
- return [];
174
- }
175
- }
176
- async delete(messageId) {
177
- try {
178
- const messages = await this.load();
179
- const filtered = messages.filter((msg) => msg.id !== messageId);
180
- writeFileSync(this.filePath, JSON.stringify(filtered, null, 2), "utf-8");
181
- } catch (error) {
182
- console.error("Failed to delete message:", error);
183
- throw error;
184
- }
185
- }
186
- async clear() {
187
- try {
188
- writeFileSync(this.filePath, JSON.stringify([], null, 2), "utf-8");
189
- } catch (error) {
190
- console.error("Failed to clear messages:", error);
191
- throw error;
192
- }
193
- }
194
- async getStats() {
195
- try {
196
- if (!existsSync(this.filePath)) {
197
- return { count: 0, size: 0 };
198
- }
199
- const messages = await this.load();
200
- const content = readFileSync(this.filePath, "utf-8");
201
- return {
202
- count: messages.length,
203
- size: Buffer.byteLength(content, "utf-8")
204
- };
205
- } catch (error) {
206
- console.error("Failed to get storage stats:", error);
207
- return { count: 0, size: 0 };
208
- }
209
- }
210
- }
211
- class MessageBus {
212
- config;
213
- subscriptions;
214
- messageHistory;
215
- deadLetterQueue;
216
- storage;
217
- stats;
218
- constructor(config = {}) {
219
- this.config = { ...DEFAULT_CONFIG, ...config };
220
- this.subscriptions = /* @__PURE__ */ new Map();
221
- this.messageHistory = [];
222
- this.deadLetterQueue = [];
223
- if (this.config.enablePersistence && this.config.persistencePath) {
224
- this.storage = new FileMessageStorage(this.config.persistencePath);
225
- this.loadPersistedMessages();
226
- }
227
- this.stats = {
228
- totalMessages: 0,
229
- messagesByType: {},
230
- messagesByStatus: {},
231
- activeSubscriptions: 0,
232
- historySize: 0,
233
- deadLetterQueueSize: 0,
234
- avgProcessingTime: 0
235
- };
236
- this.startCleanupInterval();
237
- }
238
- /**
239
- * Publish a message to the bus
240
- */
241
- async publish(type, from, to, subject, payload, options = {}) {
242
- const message = {
243
- id: randomUUID(),
244
- type,
245
- from,
246
- to,
247
- subject,
248
- payload,
249
- priority: options.priority || "normal",
250
- status: "pending",
251
- timestamp: Date.now(),
252
- correlationId: options.correlationId,
253
- replyTo: options.replyTo,
254
- metadata: options.metadata
255
- };
256
- if (this.config.enableValidation) {
257
- this.validateMessage(message);
258
- }
259
- this.logMessage("publish", message);
260
- this.updateStats(message);
261
- this.addToHistory(message);
262
- if (this.storage) {
263
- await this.storage.save(message);
264
- }
265
- await this.routeMessage(message);
266
- return message.id;
267
- }
268
- /**
269
- * Subscribe to messages
270
- */
271
- subscribe(subscriber, handler, options = {}) {
272
- const subscription = {
273
- id: randomUUID(),
274
- subscriber,
275
- options,
276
- handler,
277
- createdAt: Date.now(),
278
- unsubscribe: () => this.unsubscribe(subscription.id)
279
- };
280
- this.subscriptions.set(subscription.id, subscription);
281
- this.stats.activeSubscriptions = this.subscriptions.size;
282
- this.log("info", `Agent ${subscriber} subscribed with ID ${subscription.id}`);
283
- return subscription;
284
- }
285
- /**
286
- * Unsubscribe from messages
287
- */
288
- unsubscribe(subscriptionId) {
289
- const subscription = this.subscriptions.get(subscriptionId);
290
- if (subscription) {
291
- this.subscriptions.delete(subscriptionId);
292
- this.stats.activeSubscriptions = this.subscriptions.size;
293
- this.log("info", `Subscription ${subscriptionId} removed`);
294
- }
295
- }
296
- /**
297
- * Get message by ID
298
- */
299
- getMessage(messageId) {
300
- return this.messageHistory.find((msg) => msg.id === messageId);
301
- }
302
- /**
303
- * Get messages by filter
304
- */
305
- getMessages(filter) {
306
- return this.messageHistory.filter(filter);
307
- }
308
- /**
309
- * Update message status
310
- */
311
- async updateMessageStatus(messageId, status, error) {
312
- const message = this.getMessage(messageId);
313
- if (message) {
314
- message.status = status;
315
- if (error) {
316
- message.error = error;
317
- }
318
- if (status === "failed" && this.config.enableDeadLetterQueue) {
319
- this.deadLetterQueue.push(message);
320
- this.stats.deadLetterQueueSize = this.deadLetterQueue.length;
321
- }
322
- this.stats.messagesByStatus[status] = (this.stats.messagesByStatus[status] || 0) + 1;
323
- if (this.storage) {
324
- await this.storage.save(message);
325
- }
326
- this.log("debug", `Message ${messageId} status updated to ${status}`);
327
- }
328
- }
329
- /**
330
- * Get message bus statistics
331
- */
332
- getStats() {
333
- return { ...this.stats };
334
- }
335
- /**
336
- * Clear message history
337
- */
338
- async clearHistory() {
339
- this.messageHistory = [];
340
- this.stats.historySize = 0;
341
- if (this.storage) {
342
- await this.storage.clear();
343
- }
344
- this.log("info", "Message history cleared");
345
- }
346
- /**
347
- * Clear dead letter queue
348
- */
349
- clearDeadLetterQueue() {
350
- this.deadLetterQueue = [];
351
- this.stats.deadLetterQueueSize = 0;
352
- this.log("info", "Dead letter queue cleared");
353
- }
354
- /**
355
- * Get dead letter queue messages
356
- */
357
- getDeadLetterQueue() {
358
- return [...this.deadLetterQueue];
359
- }
360
- /**
361
- * Shutdown message bus
362
- */
363
- async shutdown() {
364
- this.log("info", "Shutting down message bus");
365
- this.subscriptions.clear();
366
- this.stats.activeSubscriptions = 0;
367
- if (this.storage && this.messageHistory.length > 0) {
368
- for (const message of this.messageHistory) {
369
- await this.storage.save(message);
370
- }
371
- }
372
- this.log("info", "Message bus shutdown complete");
373
- }
374
- /**
375
- * Route message to subscribers
376
- */
377
- async routeMessage(message) {
378
- const startTime = Date.now();
379
- const matchingSubscriptions = this.findMatchingSubscriptions(message);
380
- this.log("debug", `Routing message ${message.id} to ${matchingSubscriptions.length} subscribers`);
381
- for (const subscription of matchingSubscriptions) {
382
- try {
383
- message.status = "processing";
384
- if (subscription.options.async) {
385
- await subscription.handler(message);
386
- } else {
387
- subscription.handler(message);
388
- }
389
- message.status = "completed";
390
- } catch (error) {
391
- this.log("error", `Error handling message ${message.id} in subscription ${subscription.id}:`, error);
392
- await this.updateMessageStatus(message.id, "failed", {
393
- code: "HANDLER_ERROR",
394
- message: error instanceof Error ? error.message : String(error),
395
- stack: error instanceof Error ? error.stack : void 0
396
- });
397
- }
398
- }
399
- const processingTime = Date.now() - startTime;
400
- this.stats.avgProcessingTime = (this.stats.avgProcessingTime + processingTime) / 2;
401
- }
402
- /**
403
- * Find subscriptions matching the message
404
- */
405
- findMatchingSubscriptions(message) {
406
- const matching = [];
407
- const subscriptions = Array.from(this.subscriptions.values());
408
- for (const subscription of subscriptions) {
409
- const isAddressed = message.to === "all" || message.to === subscription.subscriber || Array.isArray(message.to) && message.to.includes(subscription.subscriber);
410
- if (!isAddressed) {
411
- continue;
412
- }
413
- if (!this.matchesSubscriptionFilters(message, subscription.options)) {
414
- continue;
415
- }
416
- matching.push(subscription);
417
- }
418
- return matching;
419
- }
420
- /**
421
- * Check if message matches subscription filters
422
- */
423
- matchesSubscriptionFilters(message, options) {
424
- if (options.type) {
425
- const types = Array.isArray(options.type) ? options.type : [options.type];
426
- if (!types.includes(message.type)) {
427
- return false;
428
- }
429
- }
430
- if (options.from) {
431
- const senders = Array.isArray(options.from) ? options.from : [options.from];
432
- if (!senders.includes(message.from)) {
433
- return false;
434
- }
435
- }
436
- if (options.priority) {
437
- const priorities = Array.isArray(options.priority) ? options.priority : [options.priority];
438
- if (!priorities.includes(message.priority)) {
439
- return false;
440
- }
441
- }
442
- if (options.filter && !options.filter(message)) {
443
- return false;
444
- }
445
- return true;
446
- }
447
- /**
448
- * Validate message
449
- */
450
- validateMessage(message) {
451
- if (!message.id) {
452
- throw new Error("Message ID is required");
453
- }
454
- if (!message.type) {
455
- throw new Error("Message type is required");
456
- }
457
- if (!message.from) {
458
- throw new Error("Message sender is required");
459
- }
460
- if (!message.to) {
461
- throw new Error("Message recipient is required");
462
- }
463
- if (!message.subject) {
464
- throw new Error("Message subject is required");
465
- }
466
- if (this.config.maxMessageSize) {
467
- const messageSize = Buffer.byteLength(JSON.stringify(message), "utf-8");
468
- if (messageSize > this.config.maxMessageSize) {
469
- throw new Error(`Message size ${messageSize} exceeds maximum ${this.config.maxMessageSize}`);
470
- }
471
- }
472
- }
473
- /**
474
- * Add message to history
475
- */
476
- addToHistory(message) {
477
- this.messageHistory.push(message);
478
- this.stats.historySize = this.messageHistory.length;
479
- const maxHistorySize = this.config.maxHistorySize ?? 1e3;
480
- if (this.messageHistory.length > maxHistorySize) {
481
- this.messageHistory.shift();
482
- this.stats.historySize = this.messageHistory.length;
483
- }
484
- }
485
- /**
486
- * Update statistics
487
- */
488
- updateStats(message) {
489
- this.stats.totalMessages++;
490
- this.stats.messagesByType[message.type] = (this.stats.messagesByType[message.type] || 0) + 1;
491
- this.stats.messagesByStatus[message.status] = (this.stats.messagesByStatus[message.status] || 0) + 1;
492
- }
493
- /**
494
- * Load persisted messages
495
- */
496
- async loadPersistedMessages() {
497
- if (!this.storage) {
498
- return;
499
- }
500
- try {
501
- const messages = await this.storage.load();
502
- this.messageHistory = messages;
503
- this.stats.historySize = messages.length;
504
- this.log("info", `Loaded ${messages.length} persisted messages`);
505
- } catch (error) {
506
- this.log("error", "Failed to load persisted messages:", error);
507
- }
508
- }
509
- /**
510
- * Start cleanup interval for old messages
511
- */
512
- startCleanupInterval() {
513
- setInterval(() => {
514
- const now = Date.now();
515
- const retentionTime = this.config.messageRetentionTime ?? 864e5;
516
- this.messageHistory = this.messageHistory.filter(
517
- (msg) => now - msg.timestamp < retentionTime
518
- );
519
- this.stats.historySize = this.messageHistory.length;
520
- this.deadLetterQueue = this.deadLetterQueue.filter(
521
- (msg) => now - msg.timestamp < retentionTime
522
- );
523
- this.stats.deadLetterQueueSize = this.deadLetterQueue.length;
524
- this.log("debug", "Cleanup completed");
525
- }, 60 * 60 * 1e3);
526
- }
527
- /**
528
- * Log message
529
- */
530
- logMessage(action, message) {
531
- if (!this.config.enableLogging) {
532
- return;
533
- }
534
- const logLevel = this.config.logLevel;
535
- const shouldLog = logLevel === "debug" || logLevel === "info" && ["publish", "subscribe"].includes(action) || logLevel === "warn" && message.priority === "high" || logLevel === "error" && message.status === "failed";
536
- if (shouldLog) {
537
- this.log("debug", `[${action}] ${message.type} from ${message.from} to ${message.to}: ${message.subject}`);
538
- }
539
- }
540
- /**
541
- * Internal logging
542
- */
543
- log(level, message, ...args) {
544
- if (!this.config.enableLogging) {
545
- return;
546
- }
547
- const levels = ["debug", "info", "warn", "error"];
548
- const configLevel = levels.indexOf(this.config.logLevel ?? "info");
549
- const messageLevel = levels.indexOf(level);
550
- if (messageLevel >= configLevel) {
551
- console[level](`[MessageBus] ${message}`, ...args);
552
- }
553
- }
554
- }
555
- let globalMessageBus = null;
556
- function getMessageBus(config) {
557
- if (!globalMessageBus) {
558
- globalMessageBus = new MessageBus(config);
559
- }
560
- return globalMessageBus;
561
- }
562
-
563
- class SkillRegistry extends EventEmitter {
564
- skills;
565
- filePathIndex;
566
- triggerIndex;
567
- messageBus = getMessageBus();
568
- constructor() {
569
- super();
570
- this.skills = /* @__PURE__ */ new Map();
571
- this.filePathIndex = /* @__PURE__ */ new Map();
572
- this.triggerIndex = /* @__PURE__ */ new Map();
573
- }
574
- /**
575
- * Register a skill
576
- *
577
- * @param skill - Parsed skill file
578
- * @param source - Skill source type
579
- * @returns Registered entry
580
- */
581
- register(skill, source = "user") {
582
- const id = skill.metadata.name;
583
- const existing = this.skills.get(id);
584
- const dependencies = this.extractDependencies(skill.metadata);
585
- const entry = {
586
- id,
587
- metadata: skill.metadata,
588
- content: skill.content,
589
- filePath: skill.filePath,
590
- enabled: existing?.enabled ?? true,
591
- source,
592
- registeredAt: existing?.registeredAt ?? Date.now(),
593
- modifiedAt: skill.modifiedAt?.getTime() ?? Date.now(),
594
- estimatedTokens: this.estimateTokens(skill),
595
- dependencies,
596
- dependents: existing?.dependents || /* @__PURE__ */ new Set()
597
- };
598
- this.skills.set(id, entry);
599
- this.filePathIndex.set(skill.filePath, id);
600
- this.updateTriggerIndex(id, entry.metadata.triggers);
601
- this.updateDependencyGraph(id, dependencies);
602
- if (existing) {
603
- this.emit("skill:updated", existing, entry);
604
- this.publishMessage("skill:updated", { oldSkill: existing, newSkill: entry });
605
- } else {
606
- this.emit("skill:registered", entry);
607
- this.publishMessage("skill:registered", entry);
608
- }
609
- return entry;
610
- }
611
- /**
612
- * Unregister a skill by ID
613
- *
614
- * @param id - Skill ID
615
- * @returns True if skill was unregistered
616
- */
617
- unregister(id) {
618
- const entry = this.skills.get(id);
619
- if (!entry)
620
- return false;
621
- if (entry.dependents.size > 0) {
622
- const dependentList = Array.from(entry.dependents).join(", ");
623
- throw new Error(`Cannot unregister skill "${id}": depended upon by: ${dependentList}`);
624
- }
625
- this.skills.delete(id);
626
- this.filePathIndex.delete(entry.filePath);
627
- for (const trigger of entry.metadata.triggers) {
628
- const skills = this.triggerIndex.get(trigger);
629
- if (skills) {
630
- skills.delete(id);
631
- if (skills.size === 0)
632
- this.triggerIndex.delete(trigger);
633
- }
634
- }
635
- for (const dep of entry.dependencies) {
636
- const depEntry = this.skills.get(dep);
637
- if (depEntry)
638
- depEntry.dependents.delete(id);
639
- }
640
- this.emit("skill:unregistered", entry);
641
- this.publishMessage("skill:unregistered", entry);
642
- return true;
643
- }
644
- /**
645
- * Unregister a skill by file path
646
- *
647
- * @param filePath - File path
648
- * @returns True if skill was unregistered
649
- */
650
- unregisterByPath(filePath) {
651
- const id = this.filePathIndex.get(filePath);
652
- return id ? this.unregister(id) : false;
653
- }
654
- /**
655
- * Get a skill by ID
656
- *
657
- * @param id - Skill ID
658
- * @returns Skill entry or undefined
659
- */
660
- getById(id) {
661
- return this.skills.get(id);
662
- }
663
- /**
664
- * Get a skill by file path
665
- *
666
- * @param filePath - File path
667
- * @returns Skill entry or undefined
668
- */
669
- getByPath(filePath) {
670
- const id = this.filePathIndex.get(filePath);
671
- return id ? this.skills.get(id) : void 0;
672
- }
673
- /**
674
- * Get skills by trigger
675
- *
676
- * @param trigger - Trigger string (e.g., '/commit')
677
- * @returns Array of matching skills
678
- */
679
- getByTrigger(trigger) {
680
- const ids = this.triggerIndex.get(trigger);
681
- if (!ids)
682
- return [];
683
- return Array.from(ids).map((id) => this.skills.get(id)).filter((e) => e !== void 0 && e.enabled);
684
- }
685
- /**
686
- * Lookup skills with filters
687
- *
688
- * @param options - Lookup options
689
- * @returns Array of matching skills
690
- */
691
- lookup(options = {}) {
692
- let results = Array.from(this.skills.values());
693
- if (options.enabled !== void 0) {
694
- results = results.filter((e) => e.enabled === options.enabled);
695
- }
696
- if (options.category) {
697
- results = results.filter((e) => e.metadata.category === options.category);
698
- }
699
- if (options.source) {
700
- results = results.filter((e) => e.source === options.source);
701
- }
702
- if (options.userInvocable !== void 0) {
703
- results = results.filter(
704
- (e) => (e.metadata.user_invocable ?? true) === options.userInvocable
705
- );
706
- }
707
- if (options.autoActivate !== void 0) {
708
- results = results.filter(
709
- (e) => (e.metadata.auto_activate ?? false) === options.autoActivate
710
- );
711
- }
712
- if (options.agent) {
713
- results = results.filter(
714
- (e) => e.metadata.agent === options.agent || e.metadata.agents?.includes(options.agent)
715
- );
716
- }
717
- if (options.search) {
718
- const query = options.search.toLowerCase();
719
- results = results.filter(
720
- (e) => e.id.toLowerCase().includes(query) || e.metadata.description.toLowerCase().includes(query) || e.metadata.tags?.some((t) => t.toLowerCase().includes(query))
721
- );
722
- }
723
- if (options.sortBy) {
724
- const dir = options.sortDir === "desc" ? -1 : 1;
725
- results.sort((a, b) => {
726
- switch (options.sortBy) {
727
- case "name":
728
- return a.id.localeCompare(b.id) * dir;
729
- case "priority":
730
- return ((a.metadata.priority ?? 5) - (b.metadata.priority ?? 5)) * dir;
731
- case "registeredAt":
732
- return (a.registeredAt - b.registeredAt) * dir;
733
- case "modifiedAt":
734
- return (a.modifiedAt - b.modifiedAt) * dir;
735
- default:
736
- return 0;
737
- }
738
- });
739
- }
740
- if (options.limit) {
741
- results = results.slice(0, options.limit);
742
- }
743
- return results;
744
- }
745
- /**
746
- * Enable a skill
747
- *
748
- * @param id - Skill ID
749
- * @returns True if enabled
750
- */
751
- enable(id) {
752
- const entry = this.skills.get(id);
753
- if (!entry || entry.enabled)
754
- return false;
755
- entry.enabled = true;
756
- this.emit("skill:enabled", entry);
757
- this.publishMessage("skill:enabled", entry);
758
- return true;
759
- }
760
- /**
761
- * Disable a skill
762
- *
763
- * @param id - Skill ID
764
- * @returns True if disabled
765
- */
766
- disable(id) {
767
- const entry = this.skills.get(id);
768
- if (!entry || !entry.enabled)
769
- return false;
770
- entry.enabled = false;
771
- this.emit("skill:disabled", entry);
772
- this.publishMessage("skill:disabled", entry);
773
- return true;
774
- }
775
- /**
776
- * Toggle skill enabled state
777
- *
778
- * @param id - Skill ID
779
- * @returns New enabled state
780
- */
781
- toggle(id) {
782
- const entry = this.skills.get(id);
783
- if (!entry)
784
- return false;
785
- entry.enabled = !entry.enabled;
786
- const event = entry.enabled ? "skill:enabled" : "skill:disabled";
787
- this.emit(event, entry);
788
- this.publishMessage(event, entry);
789
- return entry.enabled;
790
- }
791
- /**
792
- * Check if a skill exists
793
- *
794
- * @param id - Skill ID
795
- * @returns True if skill exists
796
- */
797
- has(id) {
798
- return this.skills.has(id);
799
- }
800
- /**
801
- * Check if a skill is enabled
802
- *
803
- * @param id - Skill ID
804
- * @returns True if enabled, false if disabled or not found
805
- */
806
- isEnabled(id) {
807
- return this.skills.get(id)?.enabled ?? false;
808
- }
809
- /**
810
- * Get all skill IDs
811
- *
812
- * @returns Array of skill IDs
813
- */
814
- getIds() {
815
- return Array.from(this.skills.keys());
816
- }
817
- /**
818
- * Get all entries
819
- *
820
- * @returns Array of all entries
821
- */
822
- getAll() {
823
- return Array.from(this.skills.values());
824
- }
825
- /**
826
- * Get enabled entries
827
- *
828
- * @returns Array of enabled entries
829
- */
830
- getEnabled() {
831
- return this.lookup({ enabled: true });
832
- }
833
- /**
834
- * Get registry statistics
835
- *
836
- * @returns Registry statistics
837
- */
838
- getStats() {
839
- const all = this.getAll();
840
- const enabled = this.getEnabled();
841
- const byCategory = {
842
- dev: 0,
843
- git: 0,
844
- review: 0,
845
- testing: 0,
846
- docs: 0,
847
- devops: 0,
848
- planning: 0,
849
- debugging: 0,
850
- custom: 0
851
- };
852
- const bySource = { builtin: 0, user: 0, marketplace: 0 };
853
- let totalTokens = 0;
854
- let lastRegistered = 0;
855
- let lastModified = 0;
856
- for (const entry of all) {
857
- byCategory[entry.metadata.category]++;
858
- bySource[entry.source]++;
859
- totalTokens += entry.estimatedTokens;
860
- if (entry.registeredAt > lastRegistered)
861
- lastRegistered = entry.registeredAt;
862
- if (entry.modifiedAt > lastModified)
863
- lastModified = entry.modifiedAt;
864
- }
865
- return {
866
- totalSkills: all.length,
867
- enabledSkills: enabled.length,
868
- disabledSkills: all.length - enabled.length,
869
- byCategory,
870
- bySource,
871
- totalTokens,
872
- lastRegistered: lastRegistered > 0 ? this.getById(this.getEntriesSortedBy("registeredAt")[0]?.id || "")?.id : void 0,
873
- lastModified: lastModified > 0 ? this.getById(this.getEntriesSortedBy("modifiedAt")[0]?.id || "")?.id : void 0
874
- };
875
- }
876
- /**
877
- * Get dependent skills
878
- *
879
- * @param id - Skill ID
880
- * @returns Array of dependent skill IDs
881
- */
882
- getDependents(id) {
883
- return Array.from(this.skills.get(id)?.dependents || []);
884
- }
885
- /**
886
- * Get skill dependencies
887
- *
888
- * @param id - Skill ID
889
- * @returns Array of dependency IDs
890
- */
891
- getDependencies(id) {
892
- return this.skills.get(id)?.dependencies || [];
893
- }
894
- /**
895
- * Check for missing dependencies
896
- *
897
- * @param id - Skill ID
898
- * @returns Array of missing dependency IDs
899
- */
900
- getMissingDependencies(id) {
901
- const deps = this.getDependencies(id);
902
- return deps.filter((dep) => !this.has(dep));
903
- }
904
- /**
905
- * Validate all dependencies
906
- *
907
- * @returns Map of skill ID to missing dependencies
908
- */
909
- validateDependencies() {
910
- const missing = /* @__PURE__ */ new Map();
911
- Array.from(this.skills.entries()).forEach(([id, entry]) => {
912
- const missingDeps = entry.dependencies.filter((dep) => !this.has(dep));
913
- if (missingDeps.length > 0) {
914
- missing.set(id, missingDeps);
915
- }
916
- });
917
- return missing;
918
- }
919
- /**
920
- * Clear all skills from registry
921
- */
922
- clear() {
923
- this.skills.clear();
924
- this.filePathIndex.clear();
925
- this.triggerIndex.clear();
926
- this.emit("registry:cleared");
927
- this.publishMessage("registry:cleared", {});
928
- }
929
- /**
930
- * Get the size of the registry
931
- *
932
- * @returns Number of registered skills
933
- */
934
- size() {
935
- return this.skills.size;
936
- }
937
- // ==========================================================================
938
- // Private Methods
939
- // ==========================================================================
940
- /**
941
- * Extract dependencies from skill metadata
942
- */
943
- extractDependencies(metadata) {
944
- const deps = [];
945
- if (metadata.agents) {
946
- deps.push(...metadata.agents);
947
- }
948
- if (metadata.related_skills) {
949
- deps.push(...metadata.related_skills);
950
- }
951
- return deps;
952
- }
953
- /**
954
- * Update trigger index
955
- */
956
- updateTriggerIndex(id, triggers) {
957
- Array.from(this.triggerIndex.entries()).forEach(([trigger, skillIds]) => {
958
- skillIds.delete(id);
959
- if (skillIds.size === 0)
960
- this.triggerIndex.delete(trigger);
961
- });
962
- for (const trigger of triggers) {
963
- if (!this.triggerIndex.has(trigger)) {
964
- this.triggerIndex.set(trigger, /* @__PURE__ */ new Set());
965
- }
966
- this.triggerIndex.get(trigger).add(id);
967
- }
968
- }
969
- /**
970
- * Update dependency graph
971
- */
972
- updateDependencyGraph(id, dependencies) {
973
- Array.from(this.skills.entries()).forEach(([_depId, entry]) => {
974
- if (entry.dependencies.includes(id)) {
975
- entry.dependents.delete(id);
976
- }
977
- });
978
- for (const dep of dependencies) {
979
- const depEntry = this.skills.get(dep);
980
- if (depEntry) {
981
- depEntry.dependents.add(id);
982
- }
983
- }
984
- }
985
- /**
986
- * Estimate token count for a skill
987
- */
988
- estimateTokens(skill) {
989
- const contentTokens = Math.ceil(skill.content.length / 4);
990
- const metadataTokens = Math.ceil(JSON.stringify(skill.metadata).length / 4);
991
- return contentTokens + metadataTokens;
992
- }
993
- /**
994
- * Get entries sorted by a field
995
- */
996
- getEntriesSortedBy(field) {
997
- return Array.from(this.skills.values()).sort((a, b) => b[field] - a[field]);
998
- }
999
- /**
1000
- * Publish message to event bus
1001
- */
1002
- publishMessage(type, payload) {
1003
- this.messageBus.publish(
1004
- type,
1005
- "coordinator",
1006
- "all",
1007
- `Skill registry event: ${type}`,
1008
- payload,
1009
- { priority: "normal" }
1010
- ).catch(console.error);
1011
- }
1012
- }
1013
- let registryInstance = null;
1014
- function getSkillRegistry() {
1015
- if (!registryInstance) {
1016
- registryInstance = new SkillRegistry();
1017
- }
1018
- return registryInstance;
1019
- }
1020
-
1021
- class ProgressTracker extends EventEmitter {
1022
- config;
1023
- convoyManager;
1024
- trackedConvoys = /* @__PURE__ */ new Map();
1025
- taskStartTimes = /* @__PURE__ */ new Map();
1026
- taskDurations = /* @__PURE__ */ new Map();
1027
- constructor(convoyManager, config = {}) {
1028
- super();
1029
- this.convoyManager = convoyManager;
1030
- this.config = {
1031
- updateInterval: config.updateInterval ?? 1e3,
1032
- consoleOutput: config.consoleOutput ?? false,
1033
- progressBarWidth: config.progressBarWidth ?? 40
1034
- };
1035
- this.setupEventListeners();
1036
- }
1037
- /**
1038
- * Start tracking a convoy
1039
- */
1040
- track(convoyId) {
1041
- if (this.trackedConvoys.has(convoyId)) {
1042
- return;
1043
- }
1044
- const interval = setInterval(() => {
1045
- this.emitProgress(convoyId);
1046
- }, this.config.updateInterval);
1047
- this.trackedConvoys.set(convoyId, interval);
1048
- this.taskDurations.set(convoyId, []);
1049
- this.emitProgress(convoyId);
1050
- }
1051
- /**
1052
- * Stop tracking a convoy
1053
- */
1054
- untrack(convoyId) {
1055
- const interval = this.trackedConvoys.get(convoyId);
1056
- if (interval) {
1057
- clearInterval(interval);
1058
- this.trackedConvoys.delete(convoyId);
1059
- }
1060
- this.taskDurations.delete(convoyId);
1061
- }
1062
- /**
1063
- * Get current progress for a convoy
1064
- */
1065
- getProgress(convoyId) {
1066
- const convoy = this.convoyManager.get(convoyId);
1067
- if (!convoy)
1068
- return null;
1069
- return this.buildProgressUpdate(convoy);
1070
- }
1071
- /**
1072
- * Get progress bar string
1073
- */
1074
- getProgressBar(convoyId) {
1075
- const convoy = this.convoyManager.get(convoyId);
1076
- if (!convoy)
1077
- return "";
1078
- return this.buildProgressBar(convoy.progress);
1079
- }
1080
- /**
1081
- * Get formatted progress string
1082
- */
1083
- getFormattedProgress(convoyId) {
1084
- const update = this.getProgress(convoyId);
1085
- if (!update)
1086
- return "Convoy not found";
1087
- const lines = [
1088
- `${update.convoyName} [${update.convoyId}]`,
1089
- this.buildProgressBar(update.progress),
1090
- `Status: ${this.formatStatus(update.status)}`,
1091
- `Progress: ${update.progress}% (${update.completedTasks}/${update.totalTasks})`
1092
- ];
1093
- if (update.inProgressTasks > 0) {
1094
- lines.push(`In Progress: ${update.inProgressTasks}`);
1095
- }
1096
- if (update.failedTasks > 0) {
1097
- lines.push(`Failed: ${update.failedTasks}`);
1098
- }
1099
- if (update.currentTasks.length > 0) {
1100
- lines.push("\nCurrent Tasks:");
1101
- for (const task of update.currentTasks) {
1102
- lines.push(` - ${task.title} (${task.assignedTo ?? "unassigned"})`);
1103
- }
1104
- }
1105
- if (update.estimatedCompletion) {
1106
- lines.push(`
1107
- ETA: ${this.formatTime(update.estimatedCompletion.getTime() - Date.now())}`);
1108
- }
1109
- lines.push(`Elapsed: ${this.formatTime(update.elapsedTime)}`);
1110
- return lines.join("\n");
1111
- }
1112
- /**
1113
- * Stop all tracking
1114
- */
1115
- stopAll() {
1116
- const convoyIds = Array.from(this.trackedConvoys.keys());
1117
- for (const convoyId of convoyIds) {
1118
- this.untrack(convoyId);
1119
- }
1120
- }
1121
- /**
1122
- * Destroy tracker
1123
- */
1124
- destroy() {
1125
- this.stopAll();
1126
- this.removeAllListeners();
1127
- }
1128
- // ========================================================================
1129
- // Private Methods
1130
- // ========================================================================
1131
- setupEventListeners() {
1132
- this.convoyManager.on("task:started", (convoy, task) => {
1133
- this.taskStartTimes.set(task.id, Date.now());
1134
- });
1135
- this.convoyManager.on("task:completed", (convoy, task) => {
1136
- const startTime = this.taskStartTimes.get(task.id);
1137
- if (startTime) {
1138
- const duration = Date.now() - startTime;
1139
- const durations = this.taskDurations.get(convoy.id) ?? [];
1140
- durations.push(duration);
1141
- this.taskDurations.set(convoy.id, durations);
1142
- this.taskStartTimes.delete(task.id);
1143
- }
1144
- });
1145
- this.convoyManager.on("convoy:completed", (convoy) => {
1146
- this.untrack(convoy.id);
1147
- });
1148
- this.convoyManager.on("convoy:failed", (convoy) => {
1149
- this.untrack(convoy.id);
1150
- });
1151
- this.convoyManager.on("convoy:cancelled", (convoy) => {
1152
- this.untrack(convoy.id);
1153
- });
1154
- }
1155
- emitProgress(convoyId) {
1156
- const update = this.getProgress(convoyId);
1157
- if (update) {
1158
- this.emit("progress", update);
1159
- if (this.config.consoleOutput) {
1160
- console.log(this.getFormattedProgress(convoyId));
1161
- }
1162
- }
1163
- }
1164
- buildProgressUpdate(convoy) {
1165
- const inProgressTasks = convoy.tasks.filter((t) => t.status === "in_progress").length;
1166
- const pendingTasks = convoy.tasks.filter((t) => t.status === "pending").length;
1167
- const currentTasks = convoy.tasks.filter((t) => t.status === "in_progress");
1168
- const durations = this.taskDurations.get(convoy.id) ?? [];
1169
- const averageTaskTime = durations.length > 0 ? durations.reduce((a, b) => a + b, 0) / durations.length : 0;
1170
- const elapsedTime = convoy.startedAt ? Date.now() - new Date(convoy.startedAt).getTime() : 0;
1171
- let estimatedCompletion;
1172
- if (averageTaskTime > 0 && pendingTasks > 0) {
1173
- const remainingTime = (pendingTasks + inProgressTasks) * averageTaskTime;
1174
- estimatedCompletion = new Date(Date.now() + remainingTime);
1175
- }
1176
- return {
1177
- convoyId: convoy.id,
1178
- convoyName: convoy.name,
1179
- progress: convoy.progress,
1180
- status: convoy.status,
1181
- totalTasks: convoy.totalTasks,
1182
- completedTasks: convoy.completedTasks,
1183
- failedTasks: convoy.failedTasks,
1184
- inProgressTasks,
1185
- pendingTasks,
1186
- currentTasks,
1187
- estimatedCompletion,
1188
- elapsedTime,
1189
- averageTaskTime
1190
- };
1191
- }
1192
- buildProgressBar(progress) {
1193
- const width = this.config.progressBarWidth;
1194
- const filled = Math.round(progress / 100 * width);
1195
- const empty = width - filled;
1196
- const filledChar = "\u2588";
1197
- const emptyChar = "\u2591";
1198
- return `[${filledChar.repeat(filled)}${emptyChar.repeat(empty)}] ${progress}%`;
1199
- }
1200
- formatStatus(status) {
1201
- const statusMap = {
1202
- pending: "\u23F3 Pending",
1203
- in_progress: "\u{1F504} In Progress",
1204
- completed: "\u2705 Completed",
1205
- failed: "\u274C Failed",
1206
- cancelled: "\u{1F6AB} Cancelled",
1207
- paused: "\u23F8\uFE0F Paused"
1208
- };
1209
- return statusMap[status] ?? status;
1210
- }
1211
- formatTime(ms) {
1212
- if (ms < 0)
1213
- return "0s";
1214
- const seconds = Math.floor(ms / 1e3);
1215
- const minutes = Math.floor(seconds / 60);
1216
- const hours = Math.floor(minutes / 60);
1217
- if (hours > 0) {
1218
- return `${hours}h ${minutes % 60}m ${seconds % 60}s`;
1219
- }
1220
- if (minutes > 0) {
1221
- return `${minutes}m ${seconds % 60}s`;
1222
- }
1223
- return `${seconds}s`;
1224
- }
1225
- }
1226
-
1227
- class PersistentMailboxManager extends EventEmitter {
1228
- stateManager;
1229
- mailboxes = /* @__PURE__ */ new Map();
1230
- expirationCheckInterval = null;
1231
- initialized = false;
1232
- constructor(stateManager) {
1233
- super();
1234
- this.stateManager = stateManager ?? getGlobalStateManager();
1235
- this.expirationCheckInterval = setInterval(() => {
1236
- this.checkExpiredMessages();
1237
- }, 6e4);
1238
- }
1239
- /**
1240
- * Initialize mailbox manager
1241
- */
1242
- async initialize() {
1243
- if (this.initialized)
1244
- return;
1245
- await this.stateManager.initialize();
1246
- for (const agentId of this.stateManager.getAgentIds()) {
1247
- await this.loadMailbox(agentId);
1248
- }
1249
- this.initialized = true;
1250
- }
1251
- /**
1252
- * Create mailbox for agent
1253
- */
1254
- async createMailbox(agentId) {
1255
- await this.ensureInitialized();
1256
- if (this.mailboxes.has(agentId)) {
1257
- return this.mailboxes.get(agentId);
1258
- }
1259
- const mailbox = {
1260
- agentId,
1261
- inbox: [],
1262
- outbox: [],
1263
- archive: [],
1264
- updatedAt: Date.now()
1265
- };
1266
- this.mailboxes.set(agentId, mailbox);
1267
- await this.persistMailbox(agentId);
1268
- this.emit("mailbox:created", agentId);
1269
- return mailbox;
1270
- }
1271
- /**
1272
- * Get mailbox for agent
1273
- */
1274
- async getMailbox(agentId) {
1275
- await this.ensureInitialized();
1276
- if (!this.mailboxes.has(agentId)) {
1277
- return this.createMailbox(agentId);
1278
- }
1279
- return this.mailboxes.get(agentId);
1280
- }
1281
- /**
1282
- * Send message to agent
1283
- */
1284
- async send(from, to, subject, body, options = {}) {
1285
- await this.ensureInitialized();
1286
- const message = {
1287
- id: nanoid(),
1288
- from,
1289
- to,
1290
- subject,
1291
- body,
1292
- priority: options.priority ?? "normal",
1293
- timestamp: Date.now(),
1294
- read: false,
1295
- archived: false,
1296
- correlationId: options.correlationId,
1297
- replyTo: options.replyTo,
1298
- expiresAt: options.expiresIn ? Date.now() + options.expiresIn : void 0,
1299
- metadata: options.metadata
1300
- };
1301
- const senderMailbox = await this.getMailbox(from);
1302
- senderMailbox.outbox.push(message);
1303
- senderMailbox.updatedAt = Date.now();
1304
- await this.persistMailbox(from);
1305
- const recipientMailbox = await this.getMailbox(to);
1306
- recipientMailbox.inbox.push(message);
1307
- recipientMailbox.updatedAt = Date.now();
1308
- await this.persistMailbox(to);
1309
- this.emit("message:sent", message);
1310
- this.emit("message:received", message);
1311
- return message;
1312
- }
1313
- /**
1314
- * Reply to a message
1315
- */
1316
- async reply(originalMessage, from, body, options = {}) {
1317
- return this.send(
1318
- from,
1319
- originalMessage.replyTo ?? originalMessage.from,
1320
- `Re: ${originalMessage.subject}`,
1321
- body,
1322
- {
1323
- ...options,
1324
- correlationId: originalMessage.id
1325
- }
1326
- );
1327
- }
1328
- /**
1329
- * Broadcast message to multiple agents
1330
- */
1331
- async broadcast(from, toAgents, subject, body, options = {}) {
1332
- const messages = [];
1333
- for (const to of toAgents) {
1334
- const message = await this.send(from, to, subject, body, options);
1335
- messages.push(message);
1336
- }
1337
- return messages;
1338
- }
1339
- /**
1340
- * Check inbox for unread messages
1341
- */
1342
- async checkInbox(agentId) {
1343
- await this.ensureInitialized();
1344
- const mailbox = await this.getMailbox(agentId);
1345
- return mailbox.inbox.filter((m) => !m.read && !m.archived);
1346
- }
1347
- /**
1348
- * Get unread message count
1349
- */
1350
- async getUnreadCount(agentId) {
1351
- const unread = await this.checkInbox(agentId);
1352
- return unread.length;
1353
- }
1354
- /**
1355
- * Get messages by priority
1356
- */
1357
- async getByPriority(agentId, priority) {
1358
- await this.ensureInitialized();
1359
- const mailbox = await this.getMailbox(agentId);
1360
- return mailbox.inbox.filter((m) => m.priority === priority && !m.archived);
1361
- }
1362
- /**
1363
- * Get messages by correlation ID
1364
- */
1365
- async getByCorrelationId(agentId, correlationId) {
1366
- await this.ensureInitialized();
1367
- const mailbox = await this.getMailbox(agentId);
1368
- return [
1369
- ...mailbox.inbox.filter((m) => m.correlationId === correlationId),
1370
- ...mailbox.outbox.filter((m) => m.correlationId === correlationId)
1371
- ];
1372
- }
1373
- /**
1374
- * Mark message as read
1375
- */
1376
- async markAsRead(agentId, messageId) {
1377
- await this.ensureInitialized();
1378
- const mailbox = await this.getMailbox(agentId);
1379
- const message = mailbox.inbox.find((m) => m.id === messageId);
1380
- if (message && !message.read) {
1381
- message.read = true;
1382
- mailbox.updatedAt = Date.now();
1383
- await this.persistMailbox(agentId);
1384
- this.emit("message:read", messageId, agentId);
1385
- }
1386
- }
1387
- /**
1388
- * Mark all messages as read
1389
- */
1390
- async markAllAsRead(agentId) {
1391
- await this.ensureInitialized();
1392
- const mailbox = await this.getMailbox(agentId);
1393
- let count = 0;
1394
- for (const message of mailbox.inbox) {
1395
- if (!message.read) {
1396
- message.read = true;
1397
- count++;
1398
- this.emit("message:read", message.id, agentId);
1399
- }
1400
- }
1401
- if (count > 0) {
1402
- mailbox.updatedAt = Date.now();
1403
- await this.persistMailbox(agentId);
1404
- }
1405
- return count;
1406
- }
1407
- /**
1408
- * Archive message
1409
- */
1410
- async archive(agentId, messageId) {
1411
- await this.ensureInitialized();
1412
- const mailbox = await this.getMailbox(agentId);
1413
- const inboxIndex = mailbox.inbox.findIndex((m) => m.id === messageId);
1414
- if (inboxIndex !== -1) {
1415
- const [message] = mailbox.inbox.splice(inboxIndex, 1);
1416
- message.archived = true;
1417
- mailbox.archive.push(message);
1418
- mailbox.updatedAt = Date.now();
1419
- await this.persistMailbox(agentId);
1420
- this.emit("message:archived", messageId, agentId);
1421
- return;
1422
- }
1423
- const outboxIndex = mailbox.outbox.findIndex((m) => m.id === messageId);
1424
- if (outboxIndex !== -1) {
1425
- const [message] = mailbox.outbox.splice(outboxIndex, 1);
1426
- message.archived = true;
1427
- mailbox.archive.push(message);
1428
- mailbox.updatedAt = Date.now();
1429
- await this.persistMailbox(agentId);
1430
- this.emit("message:archived", messageId, agentId);
1431
- }
1432
- }
1433
- /**
1434
- * Delete message permanently
1435
- */
1436
- async delete(agentId, messageId) {
1437
- await this.ensureInitialized();
1438
- const mailbox = await this.getMailbox(agentId);
1439
- let deleted = false;
1440
- for (const arr of [mailbox.inbox, mailbox.outbox, mailbox.archive]) {
1441
- const index = arr.findIndex((m) => m.id === messageId);
1442
- if (index !== -1) {
1443
- arr.splice(index, 1);
1444
- deleted = true;
1445
- break;
1446
- }
1447
- }
1448
- if (deleted) {
1449
- mailbox.updatedAt = Date.now();
1450
- await this.persistMailbox(agentId);
1451
- }
1452
- return deleted;
1453
- }
1454
- /**
1455
- * Search messages
1456
- */
1457
- async search(agentId, query) {
1458
- await this.ensureInitialized();
1459
- const mailbox = await this.getMailbox(agentId);
1460
- const allMessages = [...mailbox.inbox, ...mailbox.outbox, ...mailbox.archive];
1461
- return allMessages.filter((m) => {
1462
- if (query.subject && !m.subject.toLowerCase().includes(query.subject.toLowerCase())) {
1463
- return false;
1464
- }
1465
- if (query.from && m.from !== query.from) {
1466
- return false;
1467
- }
1468
- if (query.to && m.to !== query.to) {
1469
- return false;
1470
- }
1471
- if (query.read !== void 0 && m.read !== query.read) {
1472
- return false;
1473
- }
1474
- if (query.priority && m.priority !== query.priority) {
1475
- return false;
1476
- }
1477
- if (query.after && m.timestamp < query.after) {
1478
- return false;
1479
- }
1480
- if (query.before && m.timestamp > query.before) {
1481
- return false;
1482
- }
1483
- return true;
1484
- });
1485
- }
1486
- /**
1487
- * Get mailbox statistics
1488
- */
1489
- async getStats(agentId) {
1490
- await this.ensureInitialized();
1491
- const mailbox = await this.getMailbox(agentId);
1492
- const unread = mailbox.inbox.filter((m) => !m.read);
1493
- return {
1494
- inboxCount: mailbox.inbox.length,
1495
- outboxCount: mailbox.outbox.length,
1496
- archiveCount: mailbox.archive.length,
1497
- unreadCount: unread.length,
1498
- oldestUnread: unread.length > 0 ? Math.min(...unread.map((m) => m.timestamp)) : null
1499
- };
1500
- }
1501
- /**
1502
- * Cleanup old archived messages
1503
- */
1504
- async cleanupArchive(agentId, olderThanMs) {
1505
- await this.ensureInitialized();
1506
- const mailbox = await this.getMailbox(agentId);
1507
- const cutoff = Date.now() - olderThanMs;
1508
- const originalLength = mailbox.archive.length;
1509
- mailbox.archive = mailbox.archive.filter((m) => m.timestamp > cutoff);
1510
- const removed = originalLength - mailbox.archive.length;
1511
- if (removed > 0) {
1512
- mailbox.updatedAt = Date.now();
1513
- await this.persistMailbox(agentId);
1514
- }
1515
- return removed;
1516
- }
1517
- /**
1518
- * Destroy mailbox manager
1519
- */
1520
- destroy() {
1521
- if (this.expirationCheckInterval) {
1522
- clearInterval(this.expirationCheckInterval);
1523
- }
1524
- }
1525
- // ========================================================================
1526
- // Private Methods
1527
- // ========================================================================
1528
- async ensureInitialized() {
1529
- if (!this.initialized) {
1530
- await this.initialize();
1531
- }
1532
- }
1533
- async loadMailbox(agentId) {
1534
- const agentPath = this.stateManager.getAgentPath(agentId);
1535
- if (!agentPath)
1536
- return;
1537
- const mailboxFile = join(agentPath, "mailbox.json");
1538
- if (!existsSync(mailboxFile))
1539
- return;
1540
- try {
1541
- const data = JSON.parse(readFileSync(mailboxFile, "utf-8"));
1542
- this.mailboxes.set(agentId, {
1543
- agentId,
1544
- inbox: data.inbox ?? [],
1545
- outbox: data.outbox ?? [],
1546
- archive: data.archive ?? [],
1547
- updatedAt: data.updatedAt ?? Date.now()
1548
- });
1549
- } catch {
1550
- }
1551
- }
1552
- async persistMailbox(agentId) {
1553
- const mailbox = this.mailboxes.get(agentId);
1554
- if (!mailbox)
1555
- return;
1556
- await this.stateManager.createAgentWorktree(agentId);
1557
- const agentPath = this.stateManager.getAgentPath(agentId);
1558
- if (!agentPath)
1559
- return;
1560
- const mailboxFile = join(agentPath, "mailbox.json");
1561
- writeFileSync(mailboxFile, JSON.stringify(mailbox, null, 2));
1562
- }
1563
- async checkExpiredMessages() {
1564
- const now = Date.now();
1565
- const entries = Array.from(this.mailboxes.entries());
1566
- for (const [agentId, mailbox] of entries) {
1567
- let changed = false;
1568
- for (const message of mailbox.inbox) {
1569
- if (message.expiresAt && message.expiresAt < now && !message.archived) {
1570
- message.archived = true;
1571
- mailbox.archive.push(message);
1572
- changed = true;
1573
- this.emit("message:expired", message.id);
1574
- }
1575
- }
1576
- mailbox.inbox = mailbox.inbox.filter((m) => !m.archived);
1577
- if (changed) {
1578
- mailbox.updatedAt = now;
1579
- await this.persistMailbox(agentId);
1580
- }
1581
- }
1582
- }
1583
- }
1584
- let globalMailboxManager = null;
1585
- function getGlobalMailboxManager() {
1586
- if (!globalMailboxManager) {
1587
- globalMailboxManager = new PersistentMailboxManager();
1588
- }
1589
- return globalMailboxManager;
1590
- }
1591
-
1592
- const persistentMailbox = {
1593
- __proto__: null,
1594
- PersistentMailboxManager: PersistentMailboxManager,
1595
- getGlobalMailboxManager: getGlobalMailboxManager
1596
- };
1597
-
1598
- class MayorAgent extends EventEmitter {
1599
- id;
1600
- config;
1601
- convoyManager;
1602
- mailboxManager;
1603
- progressTrackers = /* @__PURE__ */ new Map();
1604
- activeConvoys = /* @__PURE__ */ new Set();
1605
- constructor(config = {}) {
1606
- super();
1607
- this.id = `mayor-${nanoid(6)}`;
1608
- this.config = {
1609
- autoCreateConvoy: config.autoCreateConvoy ?? true,
1610
- autoSpawnWorkers: config.autoSpawnWorkers ?? true,
1611
- monitorProgress: config.monitorProgress ?? true,
1612
- progressInterval: config.progressInterval ?? 5e3,
1613
- notifyHuman: config.notifyHuman ?? true,
1614
- maxConcurrentWorkers: config.maxConcurrentWorkers ?? 5
1615
- };
1616
- this.convoyManager = getGlobalConvoyManager();
1617
- this.mailboxManager = getGlobalMailboxManager();
1618
- this.setupEventListeners();
1619
- }
1620
- /**
1621
- * Process user request - main entry point
1622
- */
1623
- async processRequest(input) {
1624
- try {
1625
- const intent = await this.analyzeIntent(input);
1626
- this.emit("intent:analyzed", intent);
1627
- const plan = await this.createTaskPlan(intent);
1628
- this.emit("plan:created", plan);
1629
- let convoy = null;
1630
- if (this.config.autoCreateConvoy) {
1631
- convoy = await this.createConvoy(plan);
1632
- this.emit("convoy:created", convoy);
1633
- }
1634
- let workerCount = 0;
1635
- if (this.config.autoSpawnWorkers && convoy) {
1636
- workerCount = await this.spawnWorkers(convoy, plan);
1637
- this.emit("workers:spawned", workerCount);
1638
- }
1639
- if (this.config.monitorProgress && convoy) {
1640
- this.startMonitoring(convoy.id);
1641
- }
1642
- return {
1643
- id: nanoid(),
1644
- convoyId: convoy?.id ?? "",
1645
- plan,
1646
- workerCount,
1647
- message: this.buildResponseMessage(plan, convoy, workerCount),
1648
- timestamp: (/* @__PURE__ */ new Date()).toISOString()
1649
- };
1650
- } catch (error) {
1651
- const err = error instanceof Error ? error : new Error(String(error));
1652
- this.emit("error", err);
1653
- throw err;
1654
- }
1655
- }
1656
- /**
1657
- * Analyze user intent from natural language
1658
- */
1659
- async analyzeIntent(input) {
1660
- const lowerInput = input.toLowerCase();
1661
- let type = "other";
1662
- if (lowerInput.includes("add") || lowerInput.includes("implement") || lowerInput.includes("create")) {
1663
- type = "feature";
1664
- } else if (lowerInput.includes("fix") || lowerInput.includes("bug") || lowerInput.includes("error")) {
1665
- type = "bugfix";
1666
- } else if (lowerInput.includes("refactor") || lowerInput.includes("clean") || lowerInput.includes("improve")) {
1667
- type = "refactor";
1668
- } else if (lowerInput.includes("research") || lowerInput.includes("investigate")) {
1669
- type = "research";
1670
- } else if (lowerInput.includes("document") || lowerInput.includes("docs")) {
1671
- type = "documentation";
1672
- } else if (lowerInput.includes("test") || lowerInput.includes("spec")) {
1673
- type = "testing";
1674
- } else if (lowerInput.includes("deploy") || lowerInput.includes("release")) {
1675
- type = "deployment";
1676
- }
1677
- const entities = {
1678
- files: this.extractFiles(input),
1679
- functions: this.extractFunctions(input),
1680
- components: this.extractComponents(input),
1681
- technologies: this.extractTechnologies(input),
1682
- keywords: this.extractKeywords(input)
1683
- };
1684
- const complexity = this.estimateComplexity(input, entities);
1685
- const requiredRoles = this.determineRequiredRoles(type, entities);
1686
- return {
1687
- id: nanoid(),
1688
- originalInput: input,
1689
- type,
1690
- summary: this.generateSummary(input, type),
1691
- entities,
1692
- confidence: 0.8,
1693
- approach: this.suggestApproach(type, complexity),
1694
- complexity,
1695
- requiredRoles
1696
- };
1697
- }
1698
- /**
1699
- * Create task plan from intent
1700
- */
1701
- async createTaskPlan(intent) {
1702
- const tasks = [];
1703
- switch (intent.type) {
1704
- case "feature":
1705
- tasks.push(
1706
- { title: "Analyze requirements", description: `Understand: ${intent.summary}`, role: "researcher", dependsOn: [], estimatedEffort: "small" },
1707
- { title: "Design implementation", description: "Create design and identify files", role: "architect", dependsOn: ["task-0"], estimatedEffort: "medium" },
1708
- { title: "Implement feature", description: "Write the code", role: "coder", dependsOn: ["task-1"], estimatedEffort: "large" },
1709
- { title: "Write tests", description: "Create tests", role: "tester", dependsOn: ["task-2"], estimatedEffort: "medium" },
1710
- { title: "Review", description: "Code review", role: "reviewer", dependsOn: ["task-3"], estimatedEffort: "small" }
1711
- );
1712
- break;
1713
- case "bugfix":
1714
- tasks.push(
1715
- { title: "Reproduce issue", description: "Understand the bug", role: "researcher", dependsOn: [], estimatedEffort: "small" },
1716
- { title: "Find root cause", description: "Debug and find cause", role: "debugger", dependsOn: ["task-0"], estimatedEffort: "medium" },
1717
- { title: "Implement fix", description: "Write the fix", role: "coder", dependsOn: ["task-1"], estimatedEffort: "medium" },
1718
- { title: "Add regression test", description: "Prevent regression", role: "tester", dependsOn: ["task-2"], estimatedEffort: "small" }
1719
- );
1720
- break;
1721
- case "refactor":
1722
- tasks.push(
1723
- { title: "Analyze code", description: "Understand current implementation", role: "researcher", dependsOn: [], estimatedEffort: "medium" },
1724
- { title: "Plan refactoring", description: "Design approach", role: "architect", dependsOn: ["task-0"], estimatedEffort: "medium" },
1725
- { title: "Execute refactoring", description: "Perform refactoring", role: "coder", dependsOn: ["task-1"], estimatedEffort: "large" },
1726
- { title: "Verify tests", description: "Ensure tests pass", role: "tester", dependsOn: ["task-2"], estimatedEffort: "small" }
1727
- );
1728
- break;
1729
- default:
1730
- tasks.push(
1731
- { title: "Analyze request", description: `Understand: ${intent.summary}`, role: "researcher", dependsOn: [], estimatedEffort: "small" },
1732
- { title: "Execute task", description: "Perform the work", role: "coder", dependsOn: ["task-0"], estimatedEffort: "medium" }
1733
- );
1734
- }
1735
- return {
1736
- id: nanoid(),
1737
- name: intent.summary,
1738
- description: `Task plan for: ${intent.originalInput}`,
1739
- tasks,
1740
- totalEffort: this.calculateTotalEffort(tasks),
1741
- risks: this.identifyRisks(intent),
1742
- successCriteria: this.defineSuccessCriteria(intent)
1743
- };
1744
- }
1745
- /**
1746
- * Create convoy from task plan
1747
- */
1748
- async createConvoy(plan) {
1749
- const convoy = await this.convoyManager.create(plan.name, {
1750
- description: plan.description,
1751
- createdBy: this.id,
1752
- notifyOnComplete: this.config.notifyHuman,
1753
- notifyOnFailure: true,
1754
- notifyOnProgress: true,
1755
- metadata: { planId: plan.id, totalEffort: plan.totalEffort }
1756
- });
1757
- const taskIdMap = /* @__PURE__ */ new Map();
1758
- for (let i = 0; i < plan.tasks.length; i++) {
1759
- const planTask = plan.tasks[i];
1760
- const dependsOn = planTask.dependsOn.map((dep) => taskIdMap.get(dep)).filter((id) => id !== void 0);
1761
- const task = await this.convoyManager.addTask(convoy.id, planTask.title, {
1762
- description: planTask.description,
1763
- dependsOn,
1764
- metadata: { role: planTask.role, estimatedEffort: planTask.estimatedEffort }
1765
- });
1766
- taskIdMap.set(`task-${i}`, task.id);
1767
- }
1768
- this.activeConvoys.add(convoy.id);
1769
- return this.convoyManager.get(convoy.id);
1770
- }
1771
- /**
1772
- * Spawn worker agents for convoy
1773
- */
1774
- async spawnWorkers(convoy, plan) {
1775
- const uniqueRoles = new Set(plan.tasks.map((t) => t.role));
1776
- const workerCount = Math.min(uniqueRoles.size, this.config.maxConcurrentWorkers);
1777
- await this.convoyManager.start(convoy.id);
1778
- return workerCount;
1779
- }
1780
- /**
1781
- * Start monitoring convoy progress
1782
- */
1783
- startMonitoring(convoyId) {
1784
- if (this.progressTrackers.has(convoyId))
1785
- return;
1786
- const tracker = new ProgressTracker(this.convoyManager, {
1787
- updateInterval: this.config.progressInterval
1788
- });
1789
- tracker.on("progress", (update) => {
1790
- this.emit("progress:update", update);
1791
- });
1792
- tracker.track(convoyId);
1793
- this.progressTrackers.set(convoyId, tracker);
1794
- }
1795
- /**
1796
- * Stop monitoring convoy
1797
- */
1798
- stopMonitoring(convoyId) {
1799
- const tracker = this.progressTrackers.get(convoyId);
1800
- if (tracker) {
1801
- tracker.destroy();
1802
- this.progressTrackers.delete(convoyId);
1803
- }
1804
- }
1805
- /**
1806
- * Get convoy status
1807
- */
1808
- getConvoyStatus(convoyId) {
1809
- return this.convoyManager.getSummary(convoyId);
1810
- }
1811
- /**
1812
- * Get all active convoys
1813
- */
1814
- getActiveConvoys() {
1815
- return Array.from(this.activeConvoys).map((id) => this.convoyManager.get(id)).filter((c) => c !== void 0);
1816
- }
1817
- /**
1818
- * Destroy mayor agent
1819
- */
1820
- destroy() {
1821
- const trackers = Array.from(this.progressTrackers.values());
1822
- for (const tracker of trackers) {
1823
- tracker.destroy();
1824
- }
1825
- this.progressTrackers.clear();
1826
- this.activeConvoys.clear();
1827
- this.removeAllListeners();
1828
- }
1829
- // ========================================================================
1830
- // Private Methods
1831
- // ========================================================================
1832
- setupEventListeners() {
1833
- this.convoyManager.on("convoy:completed", (convoy) => {
1834
- if (this.activeConvoys.has(convoy.id)) {
1835
- this.activeConvoys.delete(convoy.id);
1836
- this.stopMonitoring(convoy.id);
1837
- this.emit("convoy:completed", convoy, this.convoyManager.getSummary(convoy.id));
1838
- }
1839
- });
1840
- this.convoyManager.on("convoy:failed", (convoy) => {
1841
- if (this.activeConvoys.has(convoy.id)) {
1842
- this.activeConvoys.delete(convoy.id);
1843
- this.stopMonitoring(convoy.id);
1844
- this.emit("convoy:failed", convoy, "Convoy failed");
1845
- }
1846
- });
1847
- }
1848
- extractFiles(input) {
1849
- const filePattern = /[\w-]+\.(ts|js|tsx|jsx|json|md|yaml|yml|toml)/gi;
1850
- return input.match(filePattern) ?? [];
1851
- }
1852
- extractFunctions(input) {
1853
- const funcPattern = /\b(\w+)\s*\(/g;
1854
- const matches = [];
1855
- let match;
1856
- while ((match = funcPattern.exec(input)) !== null) {
1857
- if (!["if", "for", "while", "switch", "catch"].includes(match[1])) {
1858
- matches.push(match[1]);
1859
- }
1860
- }
1861
- return matches;
1862
- }
1863
- extractComponents(input) {
1864
- const componentPattern = /\b([A-Z][a-zA-Z]+)\b/g;
1865
- return input.match(componentPattern) ?? [];
1866
- }
1867
- extractTechnologies(input) {
1868
- const techs = ["react", "vue", "angular", "node", "typescript", "javascript", "python", "rust", "go", "docker", "kubernetes", "aws", "gcp", "azure"];
1869
- const lowerInput = input.toLowerCase();
1870
- return techs.filter((tech) => lowerInput.includes(tech));
1871
- }
1872
- extractKeywords(input) {
1873
- const words = input.toLowerCase().split(/\s+/);
1874
- const stopWords = /* @__PURE__ */ new Set(["the", "a", "an", "is", "are", "was", "were", "be", "been", "being", "have", "has", "had", "do", "does", "did", "will", "would", "could", "should", "may", "might", "must", "shall", "can", "need", "dare", "ought", "used", "to", "of", "in", "for", "on", "with", "at", "by", "from", "as", "into", "through", "during", "before", "after", "above", "below", "between", "under", "again", "further", "then", "once", "here", "there", "when", "where", "why", "how", "all", "each", "few", "more", "most", "other", "some", "such", "no", "nor", "not", "only", "own", "same", "so", "than", "too", "very", "just", "and", "but", "if", "or", "because", "until", "while", "although", "though", "after", "before", "when", "whenever", "where", "wherever", "whether", "which", "who", "whom", "whose", "what", "whatever", "whichever", "whoever", "whomever", "this", "that", "these", "those", "i", "me", "my", "myself", "we", "our", "ours", "ourselves", "you", "your", "yours", "yourself", "yourselves", "he", "him", "his", "himself", "she", "her", "hers", "herself", "it", "its", "itself", "they", "them", "their", "theirs", "themselves"]);
1875
- return words.filter((w) => w.length > 2 && !stopWords.has(w));
1876
- }
1877
- estimateComplexity(input, entities) {
1878
- const fileCount = entities.files?.length ?? 0;
1879
- const componentCount = entities.components?.length ?? 0;
1880
- const wordCount = input.split(/\s+/).length;
1881
- if (wordCount < 10 && fileCount <= 1)
1882
- return "trivial";
1883
- if (wordCount < 20 && fileCount <= 2)
1884
- return "simple";
1885
- if (wordCount < 50 && fileCount <= 5)
1886
- return "moderate";
1887
- if (wordCount < 100 || componentCount > 3)
1888
- return "complex";
1889
- return "very_complex";
1890
- }
1891
- determineRequiredRoles(type, _entities) {
1892
- const roles = ["researcher"];
1893
- switch (type) {
1894
- case "feature":
1895
- roles.push("architect", "coder", "tester", "reviewer");
1896
- break;
1897
- case "bugfix":
1898
- roles.push("debugger", "coder", "tester");
1899
- break;
1900
- case "refactor":
1901
- roles.push("architect", "coder", "tester");
1902
- break;
1903
- case "testing":
1904
- roles.push("tester");
1905
- break;
1906
- case "documentation":
1907
- roles.push("writer");
1908
- break;
1909
- default:
1910
- roles.push("coder");
1911
- }
1912
- return roles;
1913
- }
1914
- generateSummary(input, type) {
1915
- const words = input.split(/\s+/).slice(0, 10).join(" ");
1916
- const typeLabel = type.charAt(0).toUpperCase() + type.slice(1);
1917
- return `${typeLabel}: ${words}${input.split(/\s+/).length > 10 ? "..." : ""}`;
1918
- }
1919
- suggestApproach(type, _complexity) {
1920
- const approaches = {
1921
- feature: "Design-first approach with incremental implementation",
1922
- bugfix: "Reproduce, isolate, fix, and verify",
1923
- refactor: "Ensure test coverage, then refactor incrementally",
1924
- research: "Gather information, analyze, and document findings",
1925
- documentation: "Review code, document API and usage patterns",
1926
- testing: "Identify test cases, implement, and verify coverage",
1927
- deployment: "Prepare, validate, deploy, and monitor",
1928
- other: "Analyze requirements and implement solution"
1929
- };
1930
- return approaches[type];
1931
- }
1932
- calculateTotalEffort(tasks) {
1933
- const effortMap = { minimal: 1, small: 2, medium: 4, large: 8 };
1934
- const total = tasks.reduce((sum, t) => sum + effortMap[t.estimatedEffort], 0);
1935
- if (total <= 4)
1936
- return "Small";
1937
- if (total <= 10)
1938
- return "Medium";
1939
- if (total <= 20)
1940
- return "Large";
1941
- return "Very Large";
1942
- }
1943
- identifyRisks(intent) {
1944
- const risks = [];
1945
- if (intent.complexity === "complex" || intent.complexity === "very_complex") {
1946
- risks.push("High complexity may require multiple iterations");
1947
- }
1948
- if (intent.type === "refactor") {
1949
- risks.push("Refactoring may introduce regressions");
1950
- }
1951
- if (intent.entities.files && intent.entities.files.length > 5) {
1952
- risks.push("Multiple files affected - careful coordination needed");
1953
- }
1954
- if (risks.length === 0) {
1955
- risks.push("No significant risks identified");
1956
- }
1957
- return risks;
1958
- }
1959
- defineSuccessCriteria(intent) {
1960
- const criteria = [];
1961
- switch (intent.type) {
1962
- case "feature":
1963
- criteria.push("Feature implemented as specified", "Tests pass", "Code reviewed");
1964
- break;
1965
- case "bugfix":
1966
- criteria.push("Bug no longer reproducible", "Regression test added", "No new issues introduced");
1967
- break;
1968
- case "refactor":
1969
- criteria.push("All existing tests pass", "Code quality improved", "No functional changes");
1970
- break;
1971
- default:
1972
- criteria.push("Task completed successfully", "Results documented");
1973
- }
1974
- return criteria;
1975
- }
1976
- buildResponseMessage(plan, convoy, workerCount) {
1977
- const lines = [
1978
- `Created plan: ${plan.name}`,
1979
- `Tasks: ${plan.tasks.length}`,
1980
- `Estimated effort: ${plan.totalEffort}`
1981
- ];
1982
- if (convoy) {
1983
- lines.push(`Convoy: ${convoy.id}`);
1984
- }
1985
- if (workerCount > 0) {
1986
- lines.push(`Workers: ${workerCount}`);
1987
- }
1988
- return lines.join("\n");
1989
- }
1990
- }
1991
- let globalMayorAgent = null;
1992
- function getGlobalMayorAgent(config) {
1993
- if (!globalMayorAgent) {
1994
- globalMayorAgent = new MayorAgent(config);
1995
- }
1996
- return globalMayorAgent;
1997
- }
1998
-
1999
- class MetricsCollector {
2000
- metrics = /* @__PURE__ */ new Map();
2001
- taskMetrics = /* @__PURE__ */ new Map();
2002
- performanceMetrics = /* @__PURE__ */ new Map();
2003
- maxRecords;
2004
- retentionPeriod;
2005
- constructor(options = {}) {
2006
- this.maxRecords = options.maxRecords ?? 1e3;
2007
- this.retentionPeriod = options.retentionPeriod ?? 36e5;
2008
- }
2009
- /**
2010
- * Record a metric value
2011
- */
2012
- recordMetric(agentId, metricName, value, metadata) {
2013
- if (!this.metrics.has(agentId)) {
2014
- this.metrics.set(agentId, /* @__PURE__ */ new Map());
2015
- }
2016
- const agentMetrics = this.metrics.get(agentId);
2017
- if (!agentMetrics.has(metricName)) {
2018
- agentMetrics.set(metricName, []);
2019
- }
2020
- const records = agentMetrics.get(metricName);
2021
- records.push({
2022
- timestamp: Date.now(),
2023
- value,
2024
- metadata
2025
- });
2026
- this.trimRecords(records);
2027
- }
2028
- /**
2029
- * Record CPU usage
2030
- */
2031
- recordCpuUsage(agentId, usage) {
2032
- this.recordMetric(agentId, "cpu_usage", usage);
2033
- this.updatePerformanceMetrics(agentId, { cpuUsage: usage });
2034
- }
2035
- /**
2036
- * Record memory usage
2037
- */
2038
- recordMemoryUsage(agentId, usage) {
2039
- this.recordMetric(agentId, "memory_usage", usage);
2040
- this.updatePerformanceMetrics(agentId, { memoryUsage: usage });
2041
- }
2042
- /**
2043
- * Record response time
2044
- */
2045
- recordResponseTime(agentId, responseTime) {
2046
- this.recordMetric(agentId, "response_time", responseTime);
2047
- this.updatePerformanceMetrics(agentId, { responseTime });
2048
- }
2049
- /**
2050
- * Record task completion
2051
- */
2052
- recordTaskCompletion(agentId, success, duration) {
2053
- if (!this.taskMetrics.has(agentId)) {
2054
- this.taskMetrics.set(agentId, {
2055
- totalTasks: 0,
2056
- completedTasks: 0,
2057
- failedTasks: 0,
2058
- avgDuration: 0,
2059
- successRate: 0
2060
- });
2061
- }
2062
- const metrics = this.taskMetrics.get(agentId);
2063
- metrics.totalTasks++;
2064
- if (success) {
2065
- metrics.completedTasks++;
2066
- } else {
2067
- metrics.failedTasks++;
2068
- }
2069
- metrics.avgDuration = (metrics.avgDuration * (metrics.totalTasks - 1) + duration) / metrics.totalTasks;
2070
- metrics.successRate = metrics.completedTasks / metrics.totalTasks;
2071
- this.recordMetric(agentId, "task_duration", duration, { success });
2072
- }
2073
- /**
2074
- * Record error
2075
- */
2076
- recordError(agentId, errorType, errorMessage) {
2077
- this.recordMetric(agentId, "error", 1, { errorType, errorMessage });
2078
- this.updatePerformanceMetrics(agentId, { errorCount: 1 });
2079
- }
2080
- /**
2081
- * Get agent metrics
2082
- */
2083
- getAgentMetrics(agentId) {
2084
- const taskMetrics = this.taskMetrics.get(agentId);
2085
- const cpuRecords = this.getMetricRecords(agentId, "cpu_usage");
2086
- const memoryRecords = this.getMetricRecords(agentId, "memory_usage");
2087
- const responseTimeRecords = this.getMetricRecords(agentId, "response_time");
2088
- const cpuUsage = cpuRecords.length > 0 ? cpuRecords[cpuRecords.length - 1].value : 0;
2089
- const memoryUsage = memoryRecords.length > 0 ? memoryRecords[memoryRecords.length - 1].value : 0;
2090
- this.calculateAverage(responseTimeRecords.map((r) => r.value));
2091
- taskMetrics ? taskMetrics.failedTasks / taskMetrics.totalTasks : 0;
2092
- return {
2093
- tasksExecuted: taskMetrics?.totalTasks ?? 0,
2094
- tasksSucceeded: taskMetrics?.completedTasks ?? 0,
2095
- tasksFailed: taskMetrics?.failedTasks ?? 0,
2096
- avgTaskDuration: taskMetrics?.avgDuration ?? 0,
2097
- successRate: taskMetrics?.successRate ?? 0,
2098
- totalExecutionTime: taskMetrics?.avgDuration ?? 0,
2099
- avgConfidence: 0.8,
2100
- lastUpdated: (/* @__PURE__ */ new Date()).toISOString(),
2101
- cpuUsage,
2102
- memoryUsage
2103
- };
2104
- }
2105
- /**
2106
- * Get metric snapshot
2107
- */
2108
- getMetricSnapshot(agentId, metricName, timeRange) {
2109
- const records = this.getMetricRecords(agentId, metricName, timeRange);
2110
- const values = records.map((r) => r.value);
2111
- if (values.length === 0) {
2112
- return {
2113
- metricName,
2114
- agentId,
2115
- timestamp: Date.now(),
2116
- current: 0,
2117
- min: 0,
2118
- max: 0,
2119
- avg: 0,
2120
- count: 0
2121
- };
2122
- }
2123
- return {
2124
- metricName,
2125
- agentId,
2126
- timestamp: Date.now(),
2127
- current: values[values.length - 1],
2128
- min: Math.min(...values),
2129
- max: Math.max(...values),
2130
- avg: this.calculateAverage(values),
2131
- count: values.length
2132
- };
2133
- }
2134
- /**
2135
- * Get aggregated metrics
2136
- */
2137
- getAggregatedMetrics(agentId, metricName, timeRange) {
2138
- const records = this.getMetricRecords(agentId, metricName, timeRange);
2139
- const values = records.map((r) => r.value).sort((a, b) => a - b);
2140
- if (values.length === 0) {
2141
- return {
2142
- min: 0,
2143
- max: 0,
2144
- avg: 0,
2145
- median: 0,
2146
- p95: 0,
2147
- p99: 0,
2148
- count: 0
2149
- };
2150
- }
2151
- return {
2152
- min: values[0],
2153
- max: values[values.length - 1],
2154
- avg: this.calculateAverage(values),
2155
- median: this.calculatePercentile(values, 50),
2156
- p95: this.calculatePercentile(values, 95),
2157
- p99: this.calculatePercentile(values, 99),
2158
- count: values.length
2159
- };
2160
- }
2161
- /**
2162
- * Get task metrics
2163
- */
2164
- getTaskMetrics(agentId) {
2165
- return this.taskMetrics.get(agentId);
2166
- }
2167
- /**
2168
- * Get performance metrics
2169
- */
2170
- getPerformanceMetrics(agentId) {
2171
- return this.performanceMetrics.get(agentId);
2172
- }
2173
- /**
2174
- * Get all agents with metrics
2175
- */
2176
- getAllAgents() {
2177
- return Array.from(this.metrics.keys());
2178
- }
2179
- /**
2180
- * Clear metrics for an agent
2181
- */
2182
- clearAgentMetrics(agentId) {
2183
- this.metrics.delete(agentId);
2184
- this.taskMetrics.delete(agentId);
2185
- this.performanceMetrics.delete(agentId);
2186
- }
2187
- /**
2188
- * Clear all metrics
2189
- */
2190
- clearAll() {
2191
- this.metrics.clear();
2192
- this.taskMetrics.clear();
2193
- this.performanceMetrics.clear();
2194
- }
2195
- /**
2196
- * Export metrics to JSON
2197
- */
2198
- exportMetrics(agentId) {
2199
- if (agentId) {
2200
- return {
2201
- agentId,
2202
- metrics: this.getAgentMetrics(agentId),
2203
- taskMetrics: this.getTaskMetrics(agentId),
2204
- performanceMetrics: this.getPerformanceMetrics(agentId),
2205
- timestamp: Date.now()
2206
- };
2207
- }
2208
- const allMetrics = {};
2209
- for (const id of this.getAllAgents()) {
2210
- allMetrics[id] = {
2211
- metrics: this.getAgentMetrics(id),
2212
- taskMetrics: this.getTaskMetrics(id),
2213
- performanceMetrics: this.getPerformanceMetrics(id)
2214
- };
2215
- }
2216
- return {
2217
- agents: allMetrics,
2218
- timestamp: Date.now()
2219
- };
2220
- }
2221
- /**
2222
- * Get metric records
2223
- */
2224
- getMetricRecords(agentId, metricName, timeRange) {
2225
- const agentMetrics = this.metrics.get(agentId);
2226
- if (!agentMetrics) {
2227
- return [];
2228
- }
2229
- const records = agentMetrics.get(metricName) ?? [];
2230
- if (timeRange) {
2231
- const cutoff = Date.now() - timeRange;
2232
- return records.filter((r) => r.timestamp >= cutoff);
2233
- }
2234
- return records;
2235
- }
2236
- /**
2237
- * Update performance metrics
2238
- */
2239
- updatePerformanceMetrics(agentId, update) {
2240
- if (!this.performanceMetrics.has(agentId)) {
2241
- this.performanceMetrics.set(agentId, {
2242
- cpuUsage: 0,
2243
- memoryUsage: 0,
2244
- responseTime: 0,
2245
- errorCount: 0,
2246
- requestCount: 0,
2247
- timestamp: Date.now()
2248
- });
2249
- }
2250
- const metrics = this.performanceMetrics.get(agentId);
2251
- if (update.cpuUsage !== void 0) {
2252
- metrics.cpuUsage = update.cpuUsage;
2253
- }
2254
- if (update.memoryUsage !== void 0) {
2255
- metrics.memoryUsage = update.memoryUsage;
2256
- }
2257
- if (update.responseTime !== void 0) {
2258
- metrics.requestCount++;
2259
- metrics.responseTime = (metrics.responseTime * (metrics.requestCount - 1) + update.responseTime) / metrics.requestCount;
2260
- }
2261
- if (update.errorCount !== void 0) {
2262
- metrics.errorCount += update.errorCount;
2263
- }
2264
- metrics.timestamp = Date.now();
2265
- }
2266
- /**
2267
- * Trim old records
2268
- */
2269
- trimRecords(records) {
2270
- const cutoff = Date.now() - this.retentionPeriod;
2271
- while (records.length > 0 && records[0].timestamp < cutoff) {
2272
- records.shift();
2273
- }
2274
- while (records.length > this.maxRecords) {
2275
- records.shift();
2276
- }
2277
- }
2278
- /**
2279
- * Calculate average
2280
- */
2281
- calculateAverage(values) {
2282
- if (values.length === 0) {
2283
- return 0;
2284
- }
2285
- return values.reduce((sum, val) => sum + val, 0) / values.length;
2286
- }
2287
- /**
2288
- * Calculate percentile
2289
- */
2290
- calculatePercentile(sortedValues, percentile) {
2291
- if (sortedValues.length === 0) {
2292
- return 0;
2293
- }
2294
- const index = Math.ceil(percentile / 100 * sortedValues.length) - 1;
2295
- return sortedValues[Math.max(0, index)];
2296
- }
2297
- }
2298
- let globalMetricsCollector;
2299
- function getMetricsCollector(options) {
2300
- if (!globalMetricsCollector) {
2301
- globalMetricsCollector = new MetricsCollector(options);
2302
- }
2303
- return globalMetricsCollector;
2304
- }
2305
-
2306
- const promptUserQuestion = async (question) => {
2307
- if (!process__default.stdin.isTTY || !process__default.stdout.isTTY) {
2308
- return null;
2309
- }
2310
- try {
2311
- const inquirer = (await import('./index6.mjs').then(function (n) { return n.c; })).default;
2312
- const choices = question.options.map((option) => ({
2313
- name: option.description ? `${option.label} \u2014 ${option.description}` : option.label,
2314
- value: option.value
2315
- }));
2316
- const defaultIndex = typeof question.defaultValue === "string" ? Math.max(0, choices.findIndex((choice) => choice.value === question.defaultValue)) : 0;
2317
- const { selected } = await inquirer.prompt([
2318
- {
2319
- type: "list",
2320
- name: "selected",
2321
- message: question.prompt,
2322
- choices,
2323
- default: defaultIndex
2324
- }
2325
- ]);
2326
- return {
2327
- value: selected,
2328
- source: "option"
2329
- };
2330
- } catch {
2331
- return null;
2332
- }
2333
- };
2334
-
2335
- const DEFAULT_PHASE_SUMMARY = {
2336
- calls: 0,
2337
- failures: 0,
2338
- successRate: 0,
2339
- avgDurationMs: 0
2340
- };
2341
- class ExecutionTelemetry {
2342
- constructor(maxEvents = 2e3) {
2343
- this.maxEvents = maxEvents;
2344
- }
2345
- events = [];
2346
- record(event) {
2347
- const entry = {
2348
- id: `te-${Date.now()}-${Math.random().toString(36).slice(2, 8)}`,
2349
- timestamp: Date.now(),
2350
- ...event
2351
- };
2352
- this.events.push(entry);
2353
- if (this.events.length > this.maxEvents) {
2354
- this.events.shift();
2355
- }
2356
- return entry;
2357
- }
2358
- getRecent(limit = 50) {
2359
- if (limit <= 0) {
2360
- return [];
2361
- }
2362
- return this.events.slice(-limit);
2363
- }
2364
- summarize() {
2365
- const phaseStats = {
2366
- execution: { ...DEFAULT_PHASE_SUMMARY },
2367
- intent: { ...DEFAULT_PHASE_SUMMARY },
2368
- elicitation: { ...DEFAULT_PHASE_SUMMARY },
2369
- skill: { ...DEFAULT_PHASE_SUMMARY },
2370
- agent: { ...DEFAULT_PHASE_SUMMARY },
2371
- mcp: { ...DEFAULT_PHASE_SUMMARY },
2372
- route: { ...DEFAULT_PHASE_SUMMARY }
2373
- };
2374
- let totalSuccess = 0;
2375
- let durationCount = 0;
2376
- let durationTotal = 0;
2377
- for (const event of this.events) {
2378
- const summary = phaseStats[event.phase];
2379
- summary.calls++;
2380
- if (!event.success) {
2381
- summary.failures++;
2382
- } else {
2383
- totalSuccess++;
2384
- }
2385
- if (typeof event.durationMs === "number") {
2386
- durationTotal += event.durationMs;
2387
- durationCount++;
2388
- summary.avgDurationMs = (summary.avgDurationMs * (summary.calls - 1) + event.durationMs) / summary.calls;
2389
- }
2390
- summary.successRate = summary.calls === 0 ? 0 : (summary.calls - summary.failures) / summary.calls;
2391
- }
2392
- return {
2393
- totalEvents: this.events.length,
2394
- overallSuccessRate: this.events.length === 0 ? 0 : totalSuccess / this.events.length,
2395
- avgDurationMs: durationCount === 0 ? 0 : durationTotal / durationCount,
2396
- phaseStats
2397
- };
2398
- }
2399
- clear() {
2400
- this.events = [];
2401
- }
2402
- }
2403
- let globalExecutionTelemetry = null;
2404
- function getGlobalExecutionTelemetry() {
2405
- if (!globalExecutionTelemetry) {
2406
- globalExecutionTelemetry = new ExecutionTelemetry();
2407
- }
2408
- return globalExecutionTelemetry;
2409
- }
2410
-
2411
- class IntentRouter extends EventEmitter {
2412
- config;
2413
- // Keywords for intent detection
2414
- mayorKeywords = [
2415
- "implement",
2416
- "build",
2417
- "create",
2418
- "add",
2419
- "develop",
2420
- "integrate",
2421
- "system",
2422
- "architecture",
2423
- "multiple",
2424
- "complex",
2425
- "full",
2426
- "authentication",
2427
- "authorization",
2428
- "api",
2429
- "database",
2430
- "backend",
2431
- "frontend",
2432
- "ui",
2433
- "ux",
2434
- "design",
2435
- "workflow"
2436
- ];
2437
- planKeywords = [
2438
- "plan",
2439
- "design",
2440
- "architect",
2441
- "structure",
2442
- "organize",
2443
- "refactor",
2444
- "restructure",
2445
- "reorganize",
2446
- "improve",
2447
- "how to",
2448
- "approach",
2449
- "strategy",
2450
- "best way"
2451
- ];
2452
- featureKeywords = [
2453
- "add",
2454
- "create",
2455
- "implement",
2456
- "build",
2457
- "make",
2458
- "feature",
2459
- "function",
2460
- "component",
2461
- "module",
2462
- "button",
2463
- "form",
2464
- "page",
2465
- "endpoint",
2466
- "route"
2467
- ];
2468
- bugFixKeywords = [
2469
- "fix",
2470
- "bug",
2471
- "error",
2472
- "issue",
2473
- "problem",
2474
- "broken",
2475
- "not working",
2476
- "crash",
2477
- "fail",
2478
- "debug",
2479
- "resolve",
2480
- "solve"
2481
- ];
2482
- questionKeywords = [
2483
- "what",
2484
- "how",
2485
- "why",
2486
- "when",
2487
- "where",
2488
- "which",
2489
- "explain",
2490
- "tell me",
2491
- "show me",
2492
- "help",
2493
- "can you",
2494
- "could you",
2495
- "would you"
2496
- ];
2497
- constructor(config = {}) {
2498
- super();
2499
- this.config = {
2500
- mayorComplexityThreshold: config.mayorComplexityThreshold || "complex",
2501
- planComplexityThreshold: config.planComplexityThreshold || "moderate",
2502
- autoRoute: config.autoRoute !== void 0 ? config.autoRoute : true,
2503
- askConfirmation: config.askConfirmation !== void 0 ? config.askConfirmation : false,
2504
- verbose: config.verbose !== void 0 ? config.verbose : false
2505
- };
2506
- }
2507
- /**
2508
- * Analyze user input and determine intent
2509
- */
2510
- async analyze(input) {
2511
- const normalized = input.toLowerCase().trim();
2512
- const complexity = this.calculateComplexity(normalized);
2513
- const type = this.detectIntentType(normalized);
2514
- const keywords = this.extractKeywords(normalized);
2515
- const requiresPlanning = this.needsPlanning(normalized, complexity);
2516
- const requiresMultipleAgents = this.needsMultipleAgents(normalized, complexity);
2517
- const estimatedSteps = this.estimateSteps(normalized, complexity);
2518
- const confidence = this.calculateConfidence(type, complexity, keywords);
2519
- const suggestedRoute = this.determineSuggestedRoute(
2520
- type,
2521
- complexity,
2522
- requiresPlanning,
2523
- requiresMultipleAgents
2524
- );
2525
- const reasoning = this.generateReasoning(
2526
- type,
2527
- complexity,
2528
- suggestedRoute,
2529
- requiresPlanning,
2530
- requiresMultipleAgents,
2531
- estimatedSteps
2532
- );
2533
- const intent = {
2534
- type,
2535
- complexity,
2536
- confidence,
2537
- reasoning,
2538
- suggestedRoute,
2539
- keywords,
2540
- requiresPlanning,
2541
- requiresMultipleAgents,
2542
- estimatedSteps
2543
- };
2544
- this.emit("intent:analyzed", intent);
2545
- return intent;
2546
- }
2547
- /**
2548
- * Route user input to appropriate system
2549
- */
2550
- async route(input) {
2551
- const intent = await this.analyze(input);
2552
- let shouldExecute = this.config.autoRoute;
2553
- if (this.config.askConfirmation && intent.complexity === "very_complex") {
2554
- shouldExecute = false;
2555
- }
2556
- const message = this.generateRouteMessage(intent);
2557
- this.emit("route:determined", {
2558
- route: intent.suggestedRoute,
2559
- intent,
2560
- shouldExecute
2561
- });
2562
- return {
2563
- route: intent.suggestedRoute,
2564
- intent,
2565
- shouldExecute,
2566
- message
2567
- };
2568
- }
2569
- /**
2570
- * Calculate complexity level
2571
- */
2572
- calculateComplexity(input) {
2573
- let score = 0;
2574
- const words = input.split(/\s+/).length;
2575
- if (words > 50)
2576
- score += 3;
2577
- else if (words > 30)
2578
- score += 2;
2579
- else if (words > 15)
2580
- score += 1;
2581
- const components = ["frontend", "backend", "database", "api", "ui", "auth", "test"];
2582
- const mentionedComponents = components.filter((c) => input.includes(c)).length;
2583
- score += mentionedComponents;
2584
- const actions = ["create", "update", "delete", "implement", "integrate", "test", "deploy"];
2585
- const mentionedActions = actions.filter((a) => input.includes(a)).length;
2586
- score += mentionedActions;
2587
- const technicalTerms = [
2588
- "authentication",
2589
- "authorization",
2590
- "middleware",
2591
- "validation",
2592
- "encryption",
2593
- "jwt",
2594
- "oauth",
2595
- "websocket",
2596
- "graphql",
2597
- "rest",
2598
- "microservice",
2599
- "docker",
2600
- "kubernetes",
2601
- "ci/cd"
2602
- ];
2603
- const mentionedTerms = technicalTerms.filter((t) => input.includes(t)).length;
2604
- score += mentionedTerms * 2;
2605
- if (input.match(/\band\b/gi)?.length || 0 > 2)
2606
- score += 2;
2607
- if (score >= 10)
2608
- return "very_complex";
2609
- if (score >= 7)
2610
- return "complex";
2611
- if (score >= 4)
2612
- return "moderate";
2613
- if (score >= 2)
2614
- return "simple";
2615
- return "trivial";
2616
- }
2617
- /**
2618
- * Detect intent type from input
2619
- */
2620
- detectIntentType(input) {
2621
- if (this.matchesKeywords(input, this.questionKeywords)) {
2622
- return "question";
2623
- }
2624
- if (this.matchesKeywords(input, this.bugFixKeywords)) {
2625
- return "bug_fix";
2626
- }
2627
- if (this.matchesKeywords(input, this.planKeywords)) {
2628
- return "plan";
2629
- }
2630
- if (this.matchesKeywords(input, this.featureKeywords)) {
2631
- return "feature";
2632
- }
2633
- if (input.includes("refactor") || input.includes("improve") || input.includes("optimize")) {
2634
- return "refactor";
2635
- }
2636
- if (this.matchesKeywords(input, this.mayorKeywords)) {
2637
- return "mayor";
2638
- }
2639
- return "direct";
2640
- }
2641
- /**
2642
- * Check if input matches keywords
2643
- */
2644
- matchesKeywords(input, keywords) {
2645
- return keywords.some((keyword) => input.includes(keyword));
2646
- }
2647
- /**
2648
- * Extract relevant keywords
2649
- */
2650
- extractKeywords(input) {
2651
- const allKeywords = [
2652
- ...this.mayorKeywords,
2653
- ...this.planKeywords,
2654
- ...this.featureKeywords,
2655
- ...this.bugFixKeywords,
2656
- ...this.questionKeywords
2657
- ];
2658
- return allKeywords.filter((keyword) => input.includes(keyword));
2659
- }
2660
- /**
2661
- * Determine if planning is needed
2662
- */
2663
- needsPlanning(input, complexity) {
2664
- if (complexity === "very_complex")
2665
- return true;
2666
- if (this.matchesKeywords(input, this.planKeywords))
2667
- return true;
2668
- const architecturalKeywords = [
2669
- "architecture",
2670
- "structure",
2671
- "design",
2672
- "refactor",
2673
- "reorganize",
2674
- "restructure",
2675
- "system"
2676
- ];
2677
- if (this.matchesKeywords(input, architecturalKeywords))
2678
- return true;
2679
- if (complexity === "complex" || complexity === "moderate") {
2680
- const components = ["frontend", "backend", "database", "api"];
2681
- const mentionedComponents = components.filter((c) => input.includes(c)).length;
2682
- if (mentionedComponents >= 2)
2683
- return true;
2684
- }
2685
- return false;
2686
- }
2687
- /**
2688
- * Determine if multiple agents are needed
2689
- */
2690
- needsMultipleAgents(input, complexity) {
2691
- if (complexity === "very_complex")
2692
- return true;
2693
- if (complexity === "complex")
2694
- return true;
2695
- const components = ["frontend", "backend", "database", "api", "test", "deploy"];
2696
- const mentionedComponents = components.filter((c) => input.includes(c)).length;
2697
- if (mentionedComponents >= 2)
2698
- return true;
2699
- const actions = ["create", "update", "delete", "test", "deploy", "integrate"];
2700
- const mentionedActions = actions.filter((a) => input.includes(a)).length;
2701
- if (mentionedActions >= 3)
2702
- return true;
2703
- return false;
2704
- }
2705
- /**
2706
- * Estimate number of steps
2707
- */
2708
- estimateSteps(input, complexity) {
2709
- const baseSteps = {
2710
- trivial: 1,
2711
- simple: 2,
2712
- moderate: 4,
2713
- complex: 8,
2714
- very_complex: 15
2715
- };
2716
- let steps = baseSteps[complexity];
2717
- const components = ["frontend", "backend", "database", "api", "test", "deploy"];
2718
- const mentionedComponents = components.filter((c) => input.includes(c)).length;
2719
- steps += mentionedComponents * 2;
2720
- const actions = ["create", "update", "delete", "integrate", "test", "deploy"];
2721
- const mentionedActions = actions.filter((a) => input.includes(a)).length;
2722
- steps += mentionedActions;
2723
- return Math.min(steps, 30);
2724
- }
2725
- /**
2726
- * Calculate confidence score
2727
- */
2728
- calculateConfidence(type, complexity, keywords) {
2729
- let confidence = 0.5;
2730
- confidence += Math.min(keywords.length * 0.05, 0.3);
2731
- if (type !== "direct") {
2732
- confidence += 0.2;
2733
- }
2734
- return Math.min(confidence, 1);
2735
- }
2736
- /**
2737
- * Determine suggested route
2738
- */
2739
- determineSuggestedRoute(type, complexity, requiresPlanning, requiresMultipleAgents) {
2740
- if (type === "question") {
2741
- return "direct";
2742
- }
2743
- if (complexity === "very_complex" || requiresMultipleAgents) {
2744
- return "mayor";
2745
- }
2746
- if (complexity === "complex" && requiresPlanning) {
2747
- return "mayor";
2748
- }
2749
- if (type === "plan" || requiresPlanning) {
2750
- return "plan";
2751
- }
2752
- if (complexity === "moderate" && (type === "feature" || type === "bug_fix")) {
2753
- return "feature";
2754
- }
2755
- if (complexity === "simple" || complexity === "trivial") {
2756
- return "direct";
2757
- }
2758
- return "feature";
2759
- }
2760
- /**
2761
- * Generate reasoning explanation
2762
- */
2763
- generateReasoning(type, complexity, route, requiresPlanning, requiresMultipleAgents, estimatedSteps) {
2764
- const reasons = [];
2765
- reasons.push(`Complexity: ${complexity}`);
2766
- reasons.push(`Intent: ${type}`);
2767
- if (requiresPlanning) {
2768
- reasons.push("Requires architectural planning");
2769
- }
2770
- if (requiresMultipleAgents) {
2771
- reasons.push("Requires multiple specialized agents");
2772
- }
2773
- reasons.push(`Estimated ${estimatedSteps} steps`);
2774
- const routeReasons = {
2775
- mayor: "Using Mayor Agent for orchestration",
2776
- plan: "Using Plan Mode for architectural design",
2777
- feature: "Using Feature Mode for implementation",
2778
- direct: "Direct execution"
2779
- };
2780
- reasons.push(routeReasons[route]);
2781
- return reasons.join(" \u2022 ");
2782
- }
2783
- /**
2784
- * Generate user-friendly route message
2785
- */
2786
- generateRouteMessage(intent) {
2787
- const messages = {
2788
- mayor: `\u{1F9E0} Mayor Agent will orchestrate this ${intent.complexity} task with ${intent.estimatedSteps} steps`,
2789
- plan: `\u{1F4CB} Creating architectural plan for this ${intent.complexity} task`,
2790
- feature: `\u26A1 Implementing feature directly (${intent.complexity} complexity)`,
2791
- direct: `\u{1F680} Executing directly`
2792
- };
2793
- return messages[intent.suggestedRoute];
2794
- }
2795
- }
2796
- let globalRouter$1 = null;
2797
- function getGlobalIntentRouter(config) {
2798
- if (!globalRouter$1) {
2799
- globalRouter$1 = new IntentRouter(config);
2800
- }
2801
- return globalRouter$1;
2802
- }
2803
-
2804
- const MCP_TOOL_PROFILES = [
2805
- {
2806
- tool: "filesystem",
2807
- keywords: ["file", "directory", "folder", "workspace", "path", "read", "write"],
2808
- basePriority: 5,
2809
- intentBoost: {
2810
- feature: 2,
2811
- refactor: 2,
2812
- bug_fix: 2
2813
- }
2814
- },
2815
- {
2816
- tool: "github",
2817
- keywords: ["github", "repository", "repo", "pr", "pull request", "issue", "commit"],
2818
- basePriority: 4,
2819
- intentBoost: {
2820
- feature: 1,
2821
- bug_fix: 1
2822
- }
2823
- },
2824
- {
2825
- tool: "web-search",
2826
- keywords: ["search", "research", "web", "documentation", "docs", "latest", "reference"],
2827
- basePriority: 3,
2828
- intentBoost: {
2829
- question: 2,
2830
- plan: 1
2831
- }
2832
- },
2833
- {
2834
- tool: "context7",
2835
- keywords: ["library", "framework", "package", "sdk", "api docs", "best practice"],
2836
- basePriority: 4,
2837
- intentBoost: {
2838
- feature: 2,
2839
- plan: 2,
2840
- question: 1
2841
- }
2842
- },
2843
- {
2844
- tool: "ide",
2845
- keywords: ["diagnostic", "error", "lint", "typecheck", "compile", "warning"],
2846
- basePriority: 3,
2847
- intentBoost: {
2848
- bug_fix: 2,
2849
- refactor: 1
2850
- }
2851
- },
2852
- {
2853
- tool: "playwright",
2854
- keywords: ["browser", "webpage", "e2e", "ui test", "automation", "screenshot"],
2855
- basePriority: 2,
2856
- intentBoost: {
2857
- feature: 1,
2858
- bug_fix: 1
2859
- }
2860
- }
2861
- ];
2862
- class AutoExecutor extends EventEmitter {
2863
- config;
2864
- metricsCollector = getMetricsCollector();
2865
- constructor(config = {}) {
2866
- super();
2867
- this.config = {
2868
- autoCreateSkills: config.autoCreateSkills !== void 0 ? config.autoCreateSkills : true,
2869
- autoCreateAgents: config.autoCreateAgents !== void 0 ? config.autoCreateAgents : true,
2870
- autoSelectMcp: config.autoSelectMcp !== void 0 ? config.autoSelectMcp : true,
2871
- enableElicitation: config.enableElicitation !== void 0 ? config.enableElicitation : true,
2872
- maxMcpTools: config.maxMcpTools !== void 0 ? Math.max(1, config.maxMcpTools) : 3,
2873
- askUserQuestion: config.askUserQuestion || promptUserQuestion,
2874
- intentRouter: config.intentRouter || getGlobalIntentRouter(),
2875
- telemetry: config.telemetry || getGlobalExecutionTelemetry(),
2876
- verbose: config.verbose !== void 0 ? config.verbose : false
2877
- };
2878
- }
2879
- /**
2880
- * Execute a user request after a router has selected this executor.
2881
- */
2882
- async execute(userInput) {
2883
- const executionId = `exec-${Date.now()}-${Math.random().toString(36).slice(2, 8)}`;
2884
- const startedAt = Date.now();
2885
- this.emit("execution:started", { input: userInput });
2886
- this.emitCommandHook("command-start", {
2887
- executionId,
2888
- inputLength: userInput.length,
2889
- source: "auto-executor"
2890
- });
2891
- this.config.telemetry.record({
2892
- executionId,
2893
- phase: "execution",
2894
- action: "start",
2895
- success: true,
2896
- metadata: {
2897
- inputLength: userInput.length
2898
- }
2899
- });
2900
- try {
2901
- const routeStart = Date.now();
2902
- const routeResult = await this.config.intentRouter.route(userInput);
2903
- this.config.telemetry.record({
2904
- executionId,
2905
- phase: "intent",
2906
- action: "route",
2907
- success: true,
2908
- durationMs: Date.now() - routeStart,
2909
- metadata: {
2910
- initialRoute: routeResult.route,
2911
- confidence: routeResult.intent.confidence,
2912
- intentType: routeResult.intent.type,
2913
- complexity: routeResult.intent.complexity
2914
- }
2915
- });
2916
- this.emitCommandHook("command-telemetry", {
2917
- executionId,
2918
- phase: "intent",
2919
- action: "route",
2920
- route: routeResult.route,
2921
- confidence: routeResult.intent.confidence
2922
- });
2923
- const elicitationResult = await this.resolveRouteWithElicitation(
2924
- routeResult.route,
2925
- routeResult.intent,
2926
- executionId
2927
- );
2928
- const route = elicitationResult.route;
2929
- const intent = elicitationResult.intent;
2930
- this.log(`Intent analyzed: ${intent.type} (${intent.complexity})`);
2931
- this.log(`Suggested route: ${route}`);
2932
- const skillDetectStart = Date.now();
2933
- const skillReq = await this.detectSkillRequirement(userInput, intent);
2934
- this.config.telemetry.record({
2935
- executionId,
2936
- phase: "skill",
2937
- action: "detect",
2938
- success: true,
2939
- durationMs: Date.now() - skillDetectStart,
2940
- metadata: {
2941
- needed: skillReq.needed,
2942
- reason: skillReq.reason
2943
- }
2944
- });
2945
- const agentDetectStart = Date.now();
2946
- const agentReq = await this.detectAgentRequirement(userInput, intent);
2947
- this.config.telemetry.record({
2948
- executionId,
2949
- phase: "agent",
2950
- action: "detect",
2951
- success: true,
2952
- durationMs: Date.now() - agentDetectStart,
2953
- metadata: {
2954
- needed: agentReq.needed,
2955
- reason: agentReq.reason
2956
- }
2957
- });
2958
- const mcpDetectStart = Date.now();
2959
- const mcpReq = await this.detectMcpRequirement(userInput, intent);
2960
- this.config.telemetry.record({
2961
- executionId,
2962
- phase: "mcp",
2963
- action: "detect",
2964
- success: true,
2965
- durationMs: Date.now() - mcpDetectStart,
2966
- metadata: {
2967
- needed: mcpReq.needed,
2968
- selectedTools: mcpReq.tools,
2969
- candidates: mcpReq.candidates,
2970
- reason: mcpReq.reason
2971
- }
2972
- });
2973
- const agentsCreated = [];
2974
- const skillsCreated = [];
2975
- const mcpToolsUsed = [];
2976
- if (this.config.autoCreateSkills && skillReq.needed) {
2977
- this.log(`Auto-creating skill: ${skillReq.skillName}`);
2978
- const skillCreateStart = Date.now();
2979
- const skillId = await this.autoCreateSkill(skillReq);
2980
- skillsCreated.push(skillId);
2981
- this.config.telemetry.record({
2982
- executionId,
2983
- phase: "skill",
2984
- action: "create",
2985
- success: true,
2986
- durationMs: Date.now() - skillCreateStart,
2987
- metadata: {
2988
- skillId,
2989
- skillName: skillReq.skillName
2990
- }
2991
- });
2992
- this.emit("skill:created", { skillId, skillReq });
2993
- }
2994
- if (this.config.autoCreateAgents && agentReq.needed) {
2995
- this.log(`Auto-creating agent: ${agentReq.domain}`);
2996
- const agentCreateStart = Date.now();
2997
- const agentId = await this.autoCreateAgent(agentReq);
2998
- agentsCreated.push(agentId);
2999
- this.config.telemetry.record({
3000
- executionId,
3001
- phase: "agent",
3002
- action: "create",
3003
- success: true,
3004
- durationMs: Date.now() - agentCreateStart,
3005
- metadata: {
3006
- agentId,
3007
- agentType: agentReq.agentType,
3008
- domain: agentReq.domain
3009
- }
3010
- });
3011
- this.emit("agent:created", { agentId, agentReq });
3012
- }
3013
- if (this.config.autoSelectMcp && mcpReq.needed) {
3014
- this.log(`Auto-selecting MCP tools: ${mcpReq.tools.join(", ")}`);
3015
- mcpToolsUsed.push(...mcpReq.tools);
3016
- this.config.telemetry.record({
3017
- executionId,
3018
- phase: "mcp",
3019
- action: "select",
3020
- success: true,
3021
- metadata: {
3022
- tools: mcpReq.tools,
3023
- candidates: mcpReq.candidates
3024
- }
3025
- });
3026
- this.emit("mcp:selected", { tools: mcpReq.tools, mcpReq });
3027
- }
3028
- let result;
3029
- const routeExecutionStart = Date.now();
3030
- switch (route) {
3031
- case "mayor":
3032
- result = await this.executeMayor(userInput, intent, agentsCreated, skillsCreated, mcpToolsUsed);
3033
- break;
3034
- case "plan":
3035
- result = await this.executePlan(userInput, intent, agentsCreated, skillsCreated, mcpToolsUsed);
3036
- break;
3037
- case "feature":
3038
- result = await this.executeFeature(userInput, intent, agentsCreated, skillsCreated, mcpToolsUsed);
3039
- break;
3040
- case "direct":
3041
- result = await this.executeDirect(userInput, intent, agentsCreated, skillsCreated, mcpToolsUsed);
3042
- break;
3043
- default:
3044
- throw new Error(`Unknown route: ${route}`);
3045
- }
3046
- const routeDuration = Date.now() - routeExecutionStart;
3047
- this.config.telemetry.record({
3048
- executionId,
3049
- phase: "route",
3050
- action: route,
3051
- success: true,
3052
- durationMs: routeDuration,
3053
- metadata: {
3054
- intentType: intent.type,
3055
- complexity: intent.complexity
3056
- }
3057
- });
3058
- this.emitCommandHook("command-telemetry", {
3059
- executionId,
3060
- phase: "route",
3061
- action: route,
3062
- durationMs: routeDuration
3063
- });
3064
- const totalDuration = Date.now() - startedAt;
3065
- this.metricsCollector.recordResponseTime("auto-executor", totalDuration);
3066
- this.metricsCollector.recordTaskCompletion("auto-executor", true, totalDuration);
3067
- this.config.telemetry.record({
3068
- executionId,
3069
- phase: "execution",
3070
- action: "complete",
3071
- success: true,
3072
- durationMs: totalDuration,
3073
- metadata: {
3074
- route,
3075
- agentsCreated: agentsCreated.length,
3076
- skillsCreated: skillsCreated.length,
3077
- mcpToolsUsed: mcpToolsUsed.length
3078
- }
3079
- });
3080
- this.emitCommandHook("command-complete", {
3081
- executionId,
3082
- success: true,
3083
- route,
3084
- durationMs: totalDuration,
3085
- mcpToolsUsed: mcpToolsUsed.length
3086
- });
3087
- result.insights = this.buildExecutionInsights({
3088
- initialRoute: routeResult.route,
3089
- resolvedRoute: route,
3090
- elicitationAsked: elicitationResult.elicitationAsked,
3091
- userSelectedRoute: elicitationResult.userSelectedRoute,
3092
- mcpReq,
3093
- totalDurationMs: totalDuration,
3094
- executionId
3095
- });
3096
- this.emit("execution:completed", result);
3097
- return result;
3098
- } catch (error) {
3099
- const totalDuration = Date.now() - startedAt;
3100
- const errorMessage = this.getErrorMessage(error);
3101
- this.metricsCollector.recordResponseTime("auto-executor", totalDuration);
3102
- this.metricsCollector.recordTaskCompletion("auto-executor", false, totalDuration);
3103
- this.metricsCollector.recordError("auto-executor", "execution_error", errorMessage);
3104
- this.config.telemetry.record({
3105
- executionId,
3106
- phase: "execution",
3107
- action: "complete",
3108
- success: false,
3109
- durationMs: totalDuration,
3110
- metadata: {
3111
- error: errorMessage
3112
- }
3113
- });
3114
- this.emitCommandHook("command-complete", {
3115
- executionId,
3116
- success: false,
3117
- durationMs: totalDuration,
3118
- error: errorMessage
3119
- });
3120
- this.emit("execution:failed", { error, input: userInput });
3121
- throw error;
3122
- }
3123
- }
3124
- /**
3125
- * Resolve route with optional structured elicitation.
3126
- * This keeps model autonomy but lets users disambiguate complex intent.
3127
- */
3128
- async resolveRouteWithElicitation(suggestedRoute, intent, executionId) {
3129
- if (!this.config.enableElicitation || !this.shouldAskRouteQuestion(intent)) {
3130
- return {
3131
- route: suggestedRoute,
3132
- intent,
3133
- elicitationAsked: false,
3134
- userSelectedRoute: false
3135
- };
3136
- }
3137
- const question = this.buildRouteQuestion(suggestedRoute, intent);
3138
- const askStart = Date.now();
3139
- const answer = await this.config.askUserQuestion(question);
3140
- this.config.telemetry.record({
3141
- executionId,
3142
- phase: "elicitation",
3143
- action: "route-choice",
3144
- success: true,
3145
- durationMs: Date.now() - askStart,
3146
- metadata: {
3147
- asked: true,
3148
- suggestedRoute,
3149
- answered: Boolean(answer),
3150
- selected: answer?.value
3151
- }
3152
- });
3153
- if (!answer) {
3154
- return {
3155
- route: suggestedRoute,
3156
- intent,
3157
- elicitationAsked: true,
3158
- userSelectedRoute: false
3159
- };
3160
- }
3161
- return this.applyRouteAnswer(suggestedRoute, intent, answer);
3162
- }
3163
- shouldAskRouteQuestion(intent) {
3164
- if (intent.complexity === "trivial" || intent.complexity === "simple") {
3165
- return false;
3166
- }
3167
- const lowConfidence = intent.confidence < 0.65;
3168
- const multiRouteIndicators = intent.requiresPlanning && intent.requiresMultipleAgents;
3169
- return lowConfidence || multiRouteIndicators;
3170
- }
3171
- buildRouteQuestion(suggestedRoute, intent) {
3172
- const routeLabels = {
3173
- direct: "Direct execution",
3174
- feature: "Feature implementation",
3175
- plan: "Plan first",
3176
- mayor: "Multi-agent orchestration"
3177
- };
3178
- const options = [
3179
- {
3180
- value: suggestedRoute,
3181
- label: `Use recommended: ${routeLabels[suggestedRoute]}`,
3182
- description: `Best guess from intent analysis (confidence ${Math.round(intent.confidence * 100)}%)`
3183
- },
3184
- {
3185
- value: "plan",
3186
- label: routeLabels.plan,
3187
- description: "Start with architecture and implementation plan"
3188
- },
3189
- {
3190
- value: "feature",
3191
- label: routeLabels.feature,
3192
- description: "Implement directly with focused feature workflow"
3193
- },
3194
- {
3195
- value: "direct",
3196
- label: routeLabels.direct,
3197
- description: "Run quickly without extra orchestration"
3198
- },
3199
- {
3200
- value: "mayor",
3201
- label: routeLabels.mayor,
3202
- description: "Use specialized agents for decomposition and coordination"
3203
- }
3204
- ].filter((option, index, arr) => arr.findIndex((x) => x.value === option.value) === index);
3205
- return {
3206
- id: "execution-route-choice",
3207
- prompt: "How should I execute this request?",
3208
- options,
3209
- defaultValue: suggestedRoute
3210
- };
3211
- }
3212
- applyRouteAnswer(suggestedRoute, intent, answer) {
3213
- const selectedRoute = ["direct", "feature", "plan", "mayor"].includes(answer.value) ? answer.value : suggestedRoute;
3214
- if (selectedRoute === suggestedRoute) {
3215
- return {
3216
- route: suggestedRoute,
3217
- intent,
3218
- elicitationAsked: true,
3219
- userSelectedRoute: false
3220
- };
3221
- }
3222
- return {
3223
- route: selectedRoute,
3224
- intent: {
3225
- ...intent,
3226
- suggestedRoute: selectedRoute,
3227
- reasoning: `${intent.reasoning} \u2022 User selected route: ${selectedRoute}`
3228
- },
3229
- elicitationAsked: true,
3230
- userSelectedRoute: true
3231
- };
3232
- }
3233
- /**
3234
- * Detect if a new skill is needed
3235
- */
3236
- async detectSkillRequirement(input, intent) {
3237
- const normalized = input.toLowerCase();
3238
- const technologies = [
3239
- { name: "react", type: "code" },
3240
- { name: "vue", type: "code" },
3241
- { name: "angular", type: "code" },
3242
- { name: "docker", type: "deployment" },
3243
- { name: "kubernetes", type: "deployment" },
3244
- { name: "graphql", type: "integration" },
3245
- { name: "websocket", type: "integration" },
3246
- { name: "oauth", type: "integration" },
3247
- { name: "jwt", type: "integration" }
3248
- ];
3249
- for (const tech of technologies) {
3250
- if (normalized.includes(tech.name)) {
3251
- return {
3252
- needed: true,
3253
- skillName: `${tech.name}-specialist`,
3254
- skillType: tech.type,
3255
- reason: `Detected ${tech.name} technology requirement`
3256
- };
3257
- }
3258
- }
3259
- if (normalized.includes("authentication") || normalized.includes("auth")) {
3260
- return {
3261
- needed: true,
3262
- skillName: "authentication-specialist",
3263
- skillType: "integration",
3264
- reason: "Authentication system requires specialized skill"
3265
- };
3266
- }
3267
- if (normalized.includes("database") || normalized.includes("sql")) {
3268
- return {
3269
- needed: true,
3270
- skillName: "database-specialist",
3271
- skillType: "code",
3272
- reason: "Database operations require specialized skill"
3273
- };
3274
- }
3275
- if (normalized.includes("api") && normalized.includes("design")) {
3276
- return {
3277
- needed: true,
3278
- skillName: "api-architect",
3279
- skillType: "analysis",
3280
- reason: "API design requires architectural skill"
3281
- };
3282
- }
3283
- if (intent.complexity === "very_complex" || intent.complexity === "complex") {
3284
- return {
3285
- needed: true,
3286
- skillName: `custom-${intent.type}-specialist`,
3287
- skillType: "code",
3288
- reason: `Complex ${intent.type} task requires specialized skill`
3289
- };
3290
- }
3291
- return {
3292
- needed: false,
3293
- skillName: "",
3294
- skillType: "code",
3295
- reason: "No specialized skill needed"
3296
- };
3297
- }
3298
- /**
3299
- * Detect if a new agent is needed
3300
- */
3301
- async detectAgentRequirement(input, intent) {
3302
- const normalized = input.toLowerCase();
3303
- if (normalized.includes("architecture") || normalized.includes("design system")) {
3304
- return {
3305
- needed: true,
3306
- agentType: "architect",
3307
- domain: "System Architecture",
3308
- reason: "Architectural design requires architect agent"
3309
- };
3310
- }
3311
- if (normalized.includes("deploy") || normalized.includes("ci/cd") || normalized.includes("docker")) {
3312
- return {
3313
- needed: true,
3314
- agentType: "devops",
3315
- domain: "DevOps & Deployment",
3316
- reason: "Deployment tasks require DevOps agent"
3317
- };
3318
- }
3319
- const specializations = [
3320
- { keywords: ["security", "encryption", "auth"], domain: "Security" },
3321
- { keywords: ["performance", "optimize", "cache"], domain: "Performance" },
3322
- { keywords: ["test", "testing", "qa"], domain: "Testing" },
3323
- { keywords: ["ui", "ux", "design", "frontend"], domain: "Frontend" },
3324
- { keywords: ["api", "backend", "server"], domain: "Backend" },
3325
- { keywords: ["database", "sql", "query"], domain: "Database" }
3326
- ];
3327
- for (const spec of specializations) {
3328
- if (spec.keywords.some((kw) => normalized.includes(kw))) {
3329
- return {
3330
- needed: true,
3331
- agentType: "specialist",
3332
- domain: spec.domain,
3333
- reason: `${spec.domain} tasks require specialized agent`
3334
- };
3335
- }
3336
- }
3337
- if (intent.estimatedSteps > 5) {
3338
- return {
3339
- needed: true,
3340
- agentType: "engineer",
3341
- domain: "Implementation",
3342
- reason: "Multi-step implementation requires engineer agent"
3343
- };
3344
- }
3345
- return {
3346
- needed: false,
3347
- agentType: "engineer",
3348
- domain: "",
3349
- reason: "Existing agents can handle this task"
3350
- };
3351
- }
3352
- /**
3353
- * Detect which MCP tools are needed
3354
- */
3355
- async detectMcpRequirement(input, intent) {
3356
- const normalized = input.toLowerCase();
3357
- const scoredTools = MCP_TOOL_PROFILES.map((profile) => {
3358
- const matchedKeywords = profile.keywords.filter((keyword) => normalized.includes(keyword));
3359
- if (matchedKeywords.length === 0) {
3360
- return null;
3361
- }
3362
- const intentBoost = profile.intentBoost?.[intent.type] ?? 0;
3363
- const complexityBoost = intent.complexity === "complex" || intent.complexity === "very_complex" ? 1 : 0;
3364
- const score = profile.basePriority + matchedKeywords.length * 2 + intentBoost + complexityBoost;
3365
- return {
3366
- tool: profile.tool,
3367
- score
3368
- };
3369
- }).filter((item) => item !== null).sort((a, b) => b.score - a.score);
3370
- const candidates = scoredTools.map((item) => item.tool);
3371
- const tools = scoredTools.slice(0, this.config.maxMcpTools).map((item) => item.tool);
3372
- return {
3373
- needed: tools.length > 0,
3374
- tools,
3375
- candidates,
3376
- reason: tools.length > 0 ? candidates.length > tools.length ? `Selected top ${tools.length}/${candidates.length} MCP tools by capability score: ${tools.join(", ")}` : `Requires MCP tools: ${tools.join(", ")}` : "No MCP tools needed"
3377
- };
3378
- }
3379
- /**
3380
- * Auto-create a skill
3381
- */
3382
- async autoCreateSkill(req) {
3383
- const skillId = `skill-${req.skillName}-${Date.now()}`;
3384
- const skillDefinition = {
3385
- id: skillId,
3386
- name: req.skillName,
3387
- type: req.skillType,
3388
- description: `Auto-generated skill for ${req.reason}`,
3389
- capabilities: this.generateSkillCapabilities(req),
3390
- createdAt: (/* @__PURE__ */ new Date()).toISOString(),
3391
- autoGenerated: true
3392
- };
3393
- const stateManager = getGlobalStateManager();
3394
- await stateManager.initialize();
3395
- await stateManager.createAgentWorktree(skillId);
3396
- await stateManager.saveState(skillId, {
3397
- agentId: skillId,
3398
- status: "active",
3399
- currentTask: "Ready",
3400
- memory: { skillDefinition }
3401
- });
3402
- this.log(`Skill created: ${skillId}`);
3403
- return skillId;
3404
- }
3405
- /**
3406
- * Generate skill capabilities based on requirement
3407
- */
3408
- generateSkillCapabilities(req) {
3409
- const capabilitiesMap = {
3410
- code: ["write_code", "review_code", "refactor_code", "debug_code"],
3411
- analysis: ["analyze_requirements", "design_architecture", "create_diagrams", "document_design"],
3412
- integration: ["integrate_apis", "configure_services", "test_integration", "handle_auth"],
3413
- deployment: ["deploy_application", "configure_infrastructure", "setup_ci_cd", "monitor_services"]
3414
- };
3415
- return capabilitiesMap[req.skillType] || ["general_task"];
3416
- }
3417
- /**
3418
- * Auto-create an agent
3419
- */
3420
- async autoCreateAgent(req) {
3421
- const agentId = `agent-${req.agentType}-${Date.now()}`;
3422
- const agentDefinition = {
3423
- id: agentId,
3424
- name: `${req.domain} ${req.agentType}`,
3425
- type: req.agentType,
3426
- domain: req.domain,
3427
- status: "active",
3428
- model: req.agentType === "architect" ? "opus" : "sonnet",
3429
- capabilities: this.generateAgentCapabilities(req),
3430
- createdAt: (/* @__PURE__ */ new Date()).toISOString(),
3431
- autoGenerated: true
3432
- };
3433
- const stateManager = getGlobalStateManager();
3434
- await stateManager.initialize();
3435
- await stateManager.createAgentWorktree(agentId);
3436
- await stateManager.saveState(agentId, {
3437
- agentId,
3438
- status: "active",
3439
- currentTask: "Ready",
3440
- memory: { agentDefinition }
3441
- });
3442
- const mailboxManager = getGlobalMailboxManager();
3443
- await mailboxManager.initialize();
3444
- await mailboxManager.createMailbox(agentId);
3445
- this.log(`Agent created: ${agentId}`);
3446
- return agentId;
3447
- }
3448
- /**
3449
- * Generate agent capabilities based on requirement
3450
- */
3451
- generateAgentCapabilities(req) {
3452
- const capabilitiesMap = {
3453
- architect: ["design_architecture", "create_plans", "review_design", "make_decisions"],
3454
- specialist: ["deep_expertise", "solve_complex_problems", "optimize_solutions", "provide_guidance"],
3455
- engineer: ["implement_features", "write_code", "test_code", "fix_bugs"],
3456
- devops: ["deploy_applications", "manage_infrastructure", "setup_pipelines", "monitor_systems"]
3457
- };
3458
- return capabilitiesMap[req.agentType] || ["general_task"];
3459
- }
3460
- /**
3461
- * Execute via Mayor Agent
3462
- */
3463
- async executeMayor(input, intent, agentsCreated, skillsCreated, mcpToolsUsed) {
3464
- this.log("Executing via Mayor Agent");
3465
- const mayor = getGlobalMayorAgent({
3466
- autoCreateConvoy: true,
3467
- autoSpawnWorkers: true,
3468
- monitorProgress: true,
3469
- notifyHuman: true
3470
- });
3471
- const response = await mayor.processRequest(input);
3472
- return {
3473
- success: true,
3474
- route: "mayor",
3475
- intent,
3476
- convoyId: response.convoyId,
3477
- agentsCreated,
3478
- skillsCreated,
3479
- mcpToolsUsed,
3480
- message: response.message,
3481
- details: response
3482
- };
3483
- }
3484
- /**
3485
- * Execute via Plan Mode
3486
- */
3487
- async executePlan(input, intent, agentsCreated, skillsCreated, mcpToolsUsed) {
3488
- this.log("Executing via Plan Mode");
3489
- const convoyManager = getGlobalConvoyManager();
3490
- await convoyManager.initialize();
3491
- const convoy = await convoyManager.create(`Plan: ${input.substring(0, 50)}`, {
3492
- description: input,
3493
- createdBy: "auto-executor"
3494
- });
3495
- await convoyManager.addTask(convoy.id, "Analyze requirements");
3496
- await convoyManager.addTask(convoy.id, "Design architecture");
3497
- await convoyManager.addTask(convoy.id, "Create implementation plan");
3498
- await convoyManager.start(convoy.id);
3499
- return {
3500
- success: true,
3501
- route: "plan",
3502
- intent,
3503
- convoyId: convoy.id,
3504
- agentsCreated,
3505
- skillsCreated,
3506
- mcpToolsUsed,
3507
- message: `Planning convoy created: ${convoy.id}`,
3508
- details: { convoy }
3509
- };
3510
- }
3511
- /**
3512
- * Execute via Feature Mode
3513
- */
3514
- async executeFeature(input, intent, agentsCreated, skillsCreated, mcpToolsUsed) {
3515
- this.log("Executing via Feature Mode");
3516
- const convoyManager = getGlobalConvoyManager();
3517
- await convoyManager.initialize();
3518
- const convoy = await convoyManager.create(`Feature: ${input.substring(0, 50)}`, {
3519
- description: input,
3520
- createdBy: "auto-executor"
3521
- });
3522
- await convoyManager.addTask(convoy.id, "Implement feature");
3523
- await convoyManager.addTask(convoy.id, "Write tests");
3524
- await convoyManager.addTask(convoy.id, "Update documentation");
3525
- await convoyManager.start(convoy.id);
3526
- return {
3527
- success: true,
3528
- route: "feature",
3529
- intent,
3530
- convoyId: convoy.id,
3531
- agentsCreated,
3532
- skillsCreated,
3533
- mcpToolsUsed,
3534
- message: `Feature convoy created: ${convoy.id}`,
3535
- details: { convoy }
3536
- };
3537
- }
3538
- /**
3539
- * Execute directly
3540
- */
3541
- async executeDirect(input, intent, agentsCreated, skillsCreated, mcpToolsUsed) {
3542
- this.log("Executing directly");
3543
- return {
3544
- success: true,
3545
- route: "direct",
3546
- intent,
3547
- agentsCreated,
3548
- skillsCreated,
3549
- mcpToolsUsed,
3550
- message: `Direct execution: ${input}`,
3551
- details: { input }
3552
- };
3553
- }
3554
- buildExecutionInsights(options) {
3555
- return {
3556
- decisionProfile: options.userSelectedRoute ? "user_guided" : "automatic",
3557
- routeDecision: {
3558
- initial: options.initialRoute,
3559
- final: options.resolvedRoute,
3560
- elicitationAsked: options.elicitationAsked,
3561
- userSelectedRoute: options.userSelectedRoute
3562
- },
3563
- mcpSelection: {
3564
- selected: options.mcpReq.tools,
3565
- candidates: options.mcpReq.candidates,
3566
- truncated: options.mcpReq.candidates.length > options.mcpReq.tools.length,
3567
- reason: options.mcpReq.reason
3568
- },
3569
- telemetry: {
3570
- totalDurationMs: options.totalDurationMs,
3571
- eventCount: this.getExecutionTelemetryEventCount(options.executionId)
3572
- }
3573
- };
3574
- }
3575
- getExecutionTelemetryEventCount(executionId) {
3576
- return this.config.telemetry.getRecent(500).filter((event) => event.executionId === executionId).length;
3577
- }
3578
- /**
3579
- * Get aggregated execution telemetry.
3580
- */
3581
- getTelemetrySummary() {
3582
- return this.config.telemetry.summarize();
3583
- }
3584
- /**
3585
- * Get recent execution telemetry events.
3586
- */
3587
- getTelemetryEvents(limit = 50) {
3588
- return this.config.telemetry.getRecent(limit);
3589
- }
3590
- clearTelemetry() {
3591
- this.config.telemetry.clear();
3592
- }
3593
- getErrorMessage(error) {
3594
- if (error instanceof Error) {
3595
- return error.message;
3596
- }
3597
- return String(error);
3598
- }
3599
- /**
3600
- * Log message if verbose
3601
- */
3602
- log(message) {
3603
- if (this.config.verbose) {
3604
- console.log(`[AutoExecutor] ${message}`);
3605
- }
3606
- }
3607
- emitCommandHook(event, data) {
3608
- void emitCommandHookEvent(event, data);
3609
- }
3610
- }
3611
- let globalExecutor = null;
3612
- function getGlobalAutoExecutor(config) {
3613
- if (!globalExecutor) {
3614
- globalExecutor = new AutoExecutor(config);
3615
- }
3616
- return globalExecutor;
3617
- }
3618
-
3619
- class CliInterceptor extends EventEmitter {
3620
- config;
3621
- autoExecutor = getGlobalAutoExecutor({
3622
- autoCreateSkills: true,
3623
- autoCreateAgents: true,
3624
- autoSelectMcp: true,
3625
- verbose: false
3626
- });
3627
- getActiveCodeTool() {
3628
- const codeToolType = readZcfConfig()?.codeToolType;
3629
- return isCodeToolType(codeToolType) ? codeToolType : DEFAULT_CODE_TOOL_TYPE;
3630
- }
3631
- getSystemCommands() {
3632
- return getCodeToolNativeSlashCommands(this.getActiveCodeTool());
3633
- }
3634
- // Simple queries that don't need interception
3635
- simpleQueryPatterns = [
3636
- /^what is/i,
3637
- /^who is/i,
3638
- /^when was/i,
3639
- /^where is/i,
3640
- /^how do i/i,
3641
- /^can you explain/i,
3642
- /^tell me about/i
3643
- ];
3644
- constructor(config = {}) {
3645
- super();
3646
- this.config = {
3647
- enabled: config.enabled !== void 0 ? config.enabled : true,
3648
- autoExecute: config.autoExecute !== void 0 ? config.autoExecute : true,
3649
- showIntent: config.showIntent !== void 0 ? config.showIntent : true,
3650
- bypassKeywords: config.bypassKeywords || [],
3651
- ccjkOwnedSlashPrefixes: config.ccjkOwnedSlashPrefixes || ["/ccjk", "/ccjk:", "/plugin", "/plugins", "/skill"],
3652
- verbose: config.verbose !== void 0 ? config.verbose : false
3653
- };
3654
- }
3655
- /**
3656
- * Intercept user input when this component is explicitly integrated.
3657
- */
3658
- async intercept(userInput) {
3659
- if (!this.config.enabled) {
3660
- return {
3661
- intercepted: false,
3662
- reason: "Interceptor disabled"
3663
- };
3664
- }
3665
- this.emit("intercept:started", { input: userInput });
3666
- const bypassCheck = this.shouldBypass(userInput);
3667
- if (bypassCheck.bypass) {
3668
- await this.handleBypassedCommand(userInput, bypassCheck.reason);
3669
- this.emit("intercept:bypassed", { input: userInput, reason: bypassCheck.reason });
3670
- return {
3671
- intercepted: false,
3672
- reason: "Bypassed",
3673
- bypassed: true,
3674
- bypassReason: bypassCheck.reason
3675
- };
3676
- }
3677
- try {
3678
- this.log(`Intercepting: ${userInput.substring(0, 50)}...`);
3679
- if (this.config.showIntent) {
3680
- this.showIntentMessage(userInput);
3681
- }
3682
- const executionResult = await this.autoExecutor.execute(userInput);
3683
- this.emit("intercept:completed", { input: userInput, result: executionResult });
3684
- return {
3685
- intercepted: true,
3686
- reason: "Automatically routed and executed",
3687
- executionResult
3688
- };
3689
- } catch (error) {
3690
- this.emit("intercept:failed", { input: userInput, error });
3691
- throw error;
3692
- }
3693
- }
3694
- /**
3695
- * Check if input should bypass interception
3696
- */
3697
- shouldBypass(input) {
3698
- const normalized = input.trim().toLowerCase();
3699
- const systemCommands = this.getSystemCommands();
3700
- if (normalized.startsWith("/")) {
3701
- const isCcjkOwned = this.config.ccjkOwnedSlashPrefixes.some((prefix) => normalized.startsWith(prefix));
3702
- if (!isCcjkOwned && systemCommands.some((cmd) => normalized.startsWith(cmd))) {
3703
- return { bypass: true, reason: "Native slash command passthrough" };
3704
- }
3705
- }
3706
- if (systemCommands.some((cmd) => normalized.startsWith(cmd))) {
3707
- return { bypass: true, reason: "System command" };
3708
- }
3709
- if (this.config.bypassKeywords.some((kw) => normalized.includes(kw.toLowerCase()))) {
3710
- return { bypass: true, reason: "Custom bypass keyword" };
3711
- }
3712
- if (this.simpleQueryPatterns.some((pattern) => pattern.test(input))) {
3713
- return { bypass: true, reason: "Simple informational query" };
3714
- }
3715
- if (input.split(/\s+/).length <= 3) {
3716
- return { bypass: true, reason: "Too short - likely a simple question" };
3717
- }
3718
- return { bypass: false, reason: "" };
3719
- }
3720
- /**
3721
- * Show intent message to user
3722
- */
3723
- showIntentMessage(_input) {
3724
- console.log("\n\u{1F9E0} Brain router is handling this request...");
3725
- console.log(" It may use skills, agents, and MCP tools based on the active routing config.\n");
3726
- }
3727
- async handleBypassedCommand(input, reason) {
3728
- const normalized = input.trim().toLowerCase();
3729
- const command = this.extractCommandName(normalized);
3730
- if (normalized.startsWith("/clear")) {
3731
- this.autoExecutor.clearTelemetry();
3732
- contextLoader.clearCache();
3733
- getSkillRegistry().clear();
3734
- await emitCommandHookEvent("command-clear", {
3735
- command,
3736
- cleared: ["telemetry", "context-cache", "skill-registry"]
3737
- });
3738
- }
3739
- if (normalized.startsWith("/")) {
3740
- await emitCommandHookEvent("command-bypass", {
3741
- command,
3742
- reason
3743
- });
3744
- }
3745
- }
3746
- extractCommandName(input) {
3747
- if (!input.startsWith("/")) {
3748
- return "";
3749
- }
3750
- return input.split(/\s+/)[0];
3751
- }
3752
- /**
3753
- * Enable interceptor
3754
- */
3755
- enable() {
3756
- this.config.enabled = true;
3757
- this.emit("interceptor:enabled");
3758
- }
3759
- /**
3760
- * Disable interceptor
3761
- */
3762
- disable() {
3763
- this.config.enabled = false;
3764
- this.emit("interceptor:disabled");
3765
- }
3766
- /**
3767
- * Check if interceptor is enabled
3768
- */
3769
- isEnabled() {
3770
- return this.config.enabled;
3771
- }
3772
- /**
3773
- * Log message if verbose
3774
- */
3775
- log(message) {
3776
- if (this.config.verbose) {
3777
- console.log(`[CliInterceptor] ${message}`);
3778
- }
3779
- }
3780
- }
3781
- let globalInterceptor = null;
3782
- function getGlobalCliInterceptor(config) {
3783
- if (!globalInterceptor) {
3784
- globalInterceptor = new CliInterceptor(config);
3785
- }
3786
- return globalInterceptor;
3787
- }
3788
-
3789
- class BrainRouter extends EventEmitter {
3790
- interceptor = getGlobalCliInterceptor({
3791
- enabled: true,
3792
- autoExecute: true,
3793
- showIntent: true,
3794
- verbose: false
3795
- });
3796
- constructor() {
3797
- super();
3798
- this.interceptor.on("intercept:started", (data) => {
3799
- this.emit("router:started", data);
3800
- });
3801
- this.interceptor.on("intercept:completed", (data) => {
3802
- this.emit("router:completed", data);
3803
- });
3804
- this.interceptor.on("intercept:failed", (data) => {
3805
- this.emit("router:failed", data);
3806
- });
3807
- this.interceptor.on("intercept:bypassed", (data) => {
3808
- this.emit("router:bypassed", data);
3809
- });
3810
- }
3811
- /**
3812
- * Process user input - main entry point
3813
- *
3814
- * This is the ONLY function users/CLI need to call.
3815
- * Everything else is automatic.
3816
- */
3817
- async process(userInput) {
3818
- try {
3819
- const interceptionResult = await this.interceptor.intercept(userInput);
3820
- if (interceptionResult.bypassed) {
3821
- return {
3822
- handled: false,
3823
- passthrough: true,
3824
- message: `Passing through to Claude Code: ${interceptionResult.bypassReason}`
3825
- };
3826
- }
3827
- if (interceptionResult.intercepted && interceptionResult.executionResult) {
3828
- return {
3829
- handled: true,
3830
- result: interceptionResult.executionResult,
3831
- message: interceptionResult.executionResult.message
3832
- };
3833
- }
3834
- return {
3835
- handled: false,
3836
- passthrough: true,
3837
- message: "No interception needed"
3838
- };
3839
- } catch (error) {
3840
- this.emit("router:error", { error, input: userInput });
3841
- throw error;
3842
- }
3843
- }
3844
- /**
3845
- * Enable automatic routing
3846
- */
3847
- enable() {
3848
- this.interceptor.enable();
3849
- this.emit("router:enabled");
3850
- }
3851
- /**
3852
- * Disable automatic routing
3853
- */
3854
- disable() {
3855
- this.interceptor.disable();
3856
- this.emit("router:disabled");
3857
- }
3858
- /**
3859
- * Check if router is enabled
3860
- */
3861
- isEnabled() {
3862
- return this.interceptor.isEnabled();
3863
- }
3864
- }
3865
- let globalRouter = null;
3866
- function getGlobalBrainRouter() {
3867
- if (!globalRouter) {
3868
- globalRouter = new BrainRouter();
3869
- }
3870
- return globalRouter;
3871
- }
3872
- async function processUserInput(userInput) {
3873
- const router = getGlobalBrainRouter();
3874
- return await router.process(userInput);
3875
- }
3876
-
3877
- class BrainCliHook extends EventEmitter {
3878
- config;
3879
- initialized = false;
3880
- constructor(config = {}) {
3881
- super();
3882
- this.config = {
3883
- enabled: config.enabled !== void 0 ? config.enabled : true,
3884
- silent: config.silent !== void 0 ? config.silent : false,
3885
- fallbackToClaudeCode: config.fallbackToClaudeCode !== void 0 ? config.fallbackToClaudeCode : true
3886
- };
3887
- }
3888
- /**
3889
- * Initialize the hook
3890
- */
3891
- async initialize() {
3892
- if (this.initialized) {
3893
- return;
3894
- }
3895
- const { getGlobalStateManager } = await import('./session-manager.mjs').then(function (n) { return n.b; });
3896
- const { getGlobalMailboxManager } = await Promise.resolve().then(function () { return persistentMailbox; });
3897
- const { getGlobalConvoyManager } = await import('./session-manager.mjs').then(function (n) { return n.d; });
3898
- const stateManager = getGlobalStateManager();
3899
- const mailboxManager = getGlobalMailboxManager();
3900
- const convoyManager = getGlobalConvoyManager();
3901
- await stateManager.initialize();
3902
- await mailboxManager.initialize();
3903
- await convoyManager.initialize();
3904
- this.initialized = true;
3905
- this.emit("hook:initialized");
3906
- if (!this.config.silent) {
3907
- console.log("\u{1F9E0} Brain system initialized - automatic routing enabled");
3908
- }
3909
- }
3910
- /**
3911
- * Process user input through the hook
3912
- */
3913
- async processInput(userInput) {
3914
- if (!this.config.enabled) {
3915
- return {
3916
- intercepted: false,
3917
- handled: false,
3918
- shouldContinue: true,
3919
- message: "Hook disabled"
3920
- };
3921
- }
3922
- if (!this.initialized) {
3923
- await this.initialize();
3924
- }
3925
- try {
3926
- SessionIntelligence.getInstance().recordMessage("user", userInput);
3927
- const result = await processUserInput(userInput);
3928
- if (result.handled && result.result) {
3929
- this.emit("hook:handled", { input: userInput, result: result.result });
3930
- if (!this.config.silent) {
3931
- this.displayResult(result.result);
3932
- }
3933
- return {
3934
- intercepted: true,
3935
- handled: true,
3936
- executionResult: result.result,
3937
- shouldContinue: false,
3938
- // Don't pass to Claude Code
3939
- message: result.message
3940
- };
3941
- }
3942
- if (result.passthrough) {
3943
- this.emit("hook:passthrough", { input: userInput, reason: result.message });
3944
- const additionalContext = this.config.silent ? void 0 : await this.buildAdditionalContext();
3945
- return {
3946
- intercepted: true,
3947
- handled: false,
3948
- shouldContinue: true,
3949
- // Pass to Claude Code
3950
- message: result.message,
3951
- additionalContext
3952
- };
3953
- }
3954
- return {
3955
- intercepted: false,
3956
- handled: false,
3957
- shouldContinue: this.config.fallbackToClaudeCode,
3958
- message: "No interception"
3959
- };
3960
- } catch (error) {
3961
- this.emit("hook:error", { error, input: userInput });
3962
- if (this.config.fallbackToClaudeCode) {
3963
- console.error("Brain system error, falling back to Claude Code:", error);
3964
- return {
3965
- intercepted: true,
3966
- handled: false,
3967
- shouldContinue: true,
3968
- message: "Error - falling back to Claude Code"
3969
- };
3970
- }
3971
- throw error;
3972
- }
3973
- }
3974
- /**
3975
- * Display execution result to user
3976
- */
3977
- displayResult(result) {
3978
- console.log(`
3979
- ${"=".repeat(60)}`);
3980
- console.log("\u{1F9E0} Brain System Result");
3981
- console.log("=".repeat(60));
3982
- console.log();
3983
- const routeEmoji = {
3984
- mayor: "\u{1F454}",
3985
- plan: "\u{1F4CB}",
3986
- feature: "\u26A1",
3987
- direct: "\u{1F680}"
3988
- };
3989
- console.log(`${routeEmoji[result.route]} Route: ${result.route.toUpperCase()}`);
3990
- console.log(`\u{1F4CA} Complexity: ${result.intent.complexity}`);
3991
- console.log(`\u{1F3AF} Intent: ${result.intent.type}`);
3992
- console.log();
3993
- if (result.agentsCreated.length > 0) {
3994
- console.log("\u{1F916} Agents Created:");
3995
- for (const agent of result.agentsCreated) {
3996
- console.log(` \u2713 ${agent}`);
3997
- }
3998
- console.log();
3999
- }
4000
- if (result.skillsCreated.length > 0) {
4001
- console.log("\u{1F393} Skills Created:");
4002
- for (const skill of result.skillsCreated) {
4003
- console.log(` \u2713 ${skill}`);
4004
- }
4005
- console.log();
4006
- }
4007
- if (result.mcpToolsUsed.length > 0) {
4008
- console.log("\u{1F527} MCP Tools Selected:");
4009
- for (const tool of result.mcpToolsUsed) {
4010
- console.log(` \u2713 ${tool}`);
4011
- }
4012
- console.log();
4013
- }
4014
- if (result.insights) {
4015
- console.log("\u2728 Smart Upgrade Signals:");
4016
- console.log(` Route decision: ${result.insights.routeDecision.initial} \u2192 ${result.insights.routeDecision.final}`);
4017
- if (result.insights.routeDecision.userSelectedRoute) {
4018
- console.log(" Mode: User-guided route disambiguation");
4019
- } else if (result.insights.routeDecision.elicitationAsked) {
4020
- console.log(" Mode: Asked for route preference (kept recommended)");
4021
- } else {
4022
- console.log(" Mode: Fully automatic route decision");
4023
- }
4024
- if (result.insights.mcpSelection.selected.length > 0) {
4025
- if (result.insights.mcpSelection.truncated) {
4026
- console.log(` MCP ranking: selected ${result.insights.mcpSelection.selected.length} of ${result.insights.mcpSelection.candidates.length} candidates`);
4027
- }
4028
- console.log(` MCP reason: ${result.insights.mcpSelection.reason}`);
4029
- } else {
4030
- console.log(" MCP reason: no external tools needed");
4031
- }
4032
- console.log(` Telemetry: ${result.insights.telemetry.eventCount} events, ${result.insights.telemetry.totalDurationMs}ms`);
4033
- console.log();
4034
- }
4035
- if (result.convoyId) {
4036
- console.log(`\u{1F4E6} Convoy: ${result.convoyId}`);
4037
- console.log();
4038
- }
4039
- console.log("\u{1F4AC} Message:");
4040
- console.log(` ${result.message}`);
4041
- console.log();
4042
- console.log("=".repeat(60));
4043
- console.log();
4044
- }
4045
- /**
4046
- * Build additional context string for PreToolUse hook injection.
4047
- * Provides brain insights (task state, session context) to the model
4048
- * without blocking tool execution. Claude Code 2.1+ feature.
4049
- */
4050
- async buildAdditionalContext() {
4051
- try {
4052
- const { loadContextAtDepth } = await import('./session-manager.mjs').then(function (n) { return n.e; });
4053
- const ctx = await loadContextAtDepth("L0");
4054
- if (ctx.totalTokens > 0) {
4055
- return `[Brain Context: ${ctx.layers.size} layers, ~${ctx.totalTokens} tokens, depth=${ctx.depth}]`;
4056
- }
4057
- return void 0;
4058
- } catch {
4059
- return void 0;
4060
- }
4061
- }
4062
- /**
4063
- * Enable the hook
4064
- */
4065
- enable() {
4066
- this.config.enabled = true;
4067
- this.emit("hook:enabled");
4068
- }
4069
- /**
4070
- * Disable the hook
4071
- */
4072
- disable() {
4073
- this.config.enabled = false;
4074
- this.emit("hook:disabled");
4075
- }
4076
- /**
4077
- * Check if hook is enabled
4078
- */
4079
- isEnabled() {
4080
- return this.config.enabled;
4081
- }
4082
- }
4083
- let globalHook = null;
4084
- function getGlobalBrainHook(config) {
4085
- if (!globalHook) {
4086
- globalHook = new BrainCliHook(config);
4087
- }
4088
- return globalHook;
4089
- }
4090
- async function setupBrainHook(config) {
4091
- const hook = getGlobalBrainHook(config);
4092
- await hook.initialize();
4093
- return hook;
4094
- }
4095
-
4096
- export { BrainCliHook, getGlobalBrainHook, setupBrainHook };