@within-7/minto 0.1.7 → 0.3.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 (601) hide show
  1. package/cli.js +155 -37
  2. package/dist/Tool.js +38 -0
  3. package/dist/Tool.js.map +3 -3
  4. package/dist/commands/agents/AgentsCommand.js +73 -49
  5. package/dist/commands/agents/AgentsCommand.js.map +2 -2
  6. package/dist/commands/agents/constants.js +1 -1
  7. package/dist/commands/agents/constants.js.map +1 -1
  8. package/dist/commands/agents/index.js +1 -1
  9. package/dist/commands/bug.js +74 -7
  10. package/dist/commands/bug.js.map +3 -3
  11. package/dist/commands/clear.js +3 -0
  12. package/dist/commands/clear.js.map +2 -2
  13. package/dist/commands/compact.js +37 -0
  14. package/dist/commands/compact.js.map +2 -2
  15. package/dist/commands/context.js +85 -0
  16. package/dist/commands/context.js.map +7 -0
  17. package/dist/commands/ctx_viz.js +18 -10
  18. package/dist/commands/ctx_viz.js.map +2 -2
  19. package/dist/commands/doctor.js +158 -12
  20. package/dist/commands/doctor.js.map +2 -2
  21. package/dist/commands/export.js +157 -0
  22. package/dist/commands/export.js.map +7 -0
  23. package/dist/commands/mcp-interactive.js +28 -18
  24. package/dist/commands/mcp-interactive.js.map +2 -2
  25. package/dist/commands/model.js +9 -7
  26. package/dist/commands/model.js.map +2 -2
  27. package/dist/commands/permissions.js +87 -0
  28. package/dist/commands/permissions.js.map +7 -0
  29. package/dist/commands/plugin/AddMarketplaceForm.js +3 -2
  30. package/dist/commands/plugin/AddMarketplaceForm.js.map +2 -2
  31. package/dist/commands/plugin/ConfirmDialog.js +2 -1
  32. package/dist/commands/plugin/ConfirmDialog.js.map +2 -2
  33. package/dist/commands/plugin/ErrorView.js +2 -1
  34. package/dist/commands/plugin/ErrorView.js.map +2 -2
  35. package/dist/commands/plugin/InstalledPluginsByMarketplace.js +5 -4
  36. package/dist/commands/plugin/InstalledPluginsByMarketplace.js.map +2 -2
  37. package/dist/commands/plugin/InstalledPluginsManager.js +5 -4
  38. package/dist/commands/plugin/InstalledPluginsManager.js.map +2 -2
  39. package/dist/commands/plugin/MainMenu.js +2 -1
  40. package/dist/commands/plugin/MainMenu.js.map +2 -2
  41. package/dist/commands/plugin/MarketplaceManager.js +5 -4
  42. package/dist/commands/plugin/MarketplaceManager.js.map +2 -2
  43. package/dist/commands/plugin/MarketplaceSelector.js +4 -3
  44. package/dist/commands/plugin/MarketplaceSelector.js.map +2 -2
  45. package/dist/commands/plugin/PlaceholderScreen.js +3 -2
  46. package/dist/commands/plugin/PlaceholderScreen.js.map +2 -2
  47. package/dist/commands/plugin/PluginBrowser.js +6 -5
  48. package/dist/commands/plugin/PluginBrowser.js.map +2 -2
  49. package/dist/commands/plugin/PluginDetailsInstall.js +5 -4
  50. package/dist/commands/plugin/PluginDetailsInstall.js.map +2 -2
  51. package/dist/commands/plugin/PluginDetailsManage.js +4 -3
  52. package/dist/commands/plugin/PluginDetailsManage.js.map +2 -2
  53. package/dist/commands/plugin.js +16 -15
  54. package/dist/commands/plugin.js.map +2 -2
  55. package/dist/commands/quit.js +3 -1
  56. package/dist/commands/quit.js.map +2 -2
  57. package/dist/commands/sandbox.js +105 -0
  58. package/dist/commands/sandbox.js.map +7 -0
  59. package/dist/commands/setup.js +2 -1
  60. package/dist/commands/setup.js.map +2 -2
  61. package/dist/commands/status.js +59 -0
  62. package/dist/commands/status.js.map +7 -0
  63. package/dist/commands/tasks.js +108 -0
  64. package/dist/commands/tasks.js.map +7 -0
  65. package/dist/commands/todos.js +123 -0
  66. package/dist/commands/todos.js.map +7 -0
  67. package/dist/commands/undo.js +245 -0
  68. package/dist/commands/undo.js.map +7 -0
  69. package/dist/commands.js +22 -2
  70. package/dist/commands.js.map +2 -2
  71. package/dist/components/AgentThinkingBlock.js +10 -18
  72. package/dist/components/AgentThinkingBlock.js.map +2 -2
  73. package/dist/components/AsciiLogo.js +7 -8
  74. package/dist/components/AsciiLogo.js.map +2 -2
  75. package/dist/components/AskUserQuestionDialog/AskUserQuestionDialog.js +3 -2
  76. package/dist/components/AskUserQuestionDialog/AskUserQuestionDialog.js.map +2 -2
  77. package/dist/components/AskUserQuestionDialog/QuestionView.js +2 -1
  78. package/dist/components/AskUserQuestionDialog/QuestionView.js.map +2 -2
  79. package/dist/components/BackgroundTasksPanel.js +78 -29
  80. package/dist/components/BackgroundTasksPanel.js.map +2 -2
  81. package/dist/components/BashStreamingProgress.js +24 -0
  82. package/dist/components/BashStreamingProgress.js.map +7 -0
  83. package/dist/components/CollapsibleHint.js +15 -0
  84. package/dist/components/CollapsibleHint.js.map +7 -0
  85. package/dist/components/Config.js +3 -2
  86. package/dist/components/Config.js.map +2 -2
  87. package/dist/components/ConsoleOAuthFlow.js +2 -1
  88. package/dist/components/ConsoleOAuthFlow.js.map +2 -2
  89. package/dist/components/Cost.js +2 -1
  90. package/dist/components/Cost.js.map +2 -2
  91. package/dist/components/FileEditToolUpdatedMessage.js +1 -1
  92. package/dist/components/FileEditToolUpdatedMessage.js.map +2 -2
  93. package/dist/components/HeaderBar.js +13 -8
  94. package/dist/components/HeaderBar.js.map +2 -2
  95. package/dist/components/HistorySearchOverlay.js +4 -3
  96. package/dist/components/HistorySearchOverlay.js.map +2 -2
  97. package/dist/components/HotkeyHelpPanel.js +134 -0
  98. package/dist/components/HotkeyHelpPanel.js.map +7 -0
  99. package/dist/components/InvalidConfigDialog.js +2 -1
  100. package/dist/components/InvalidConfigDialog.js.map +2 -2
  101. package/dist/components/Logo.js +24 -68
  102. package/dist/components/Logo.js.map +2 -2
  103. package/dist/components/MCPServerApprovalDialog.js +2 -1
  104. package/dist/components/MCPServerApprovalDialog.js.map +2 -2
  105. package/dist/components/MCPServerDialogCopy.js +2 -1
  106. package/dist/components/MCPServerDialogCopy.js.map +2 -2
  107. package/dist/components/MCPServerMultiselectDialog.js +2 -1
  108. package/dist/components/MCPServerMultiselectDialog.js.map +2 -2
  109. package/dist/components/Message.js +23 -7
  110. package/dist/components/Message.js.map +3 -3
  111. package/dist/components/MessageSelector.js +4 -3
  112. package/dist/components/MessageSelector.js.map +2 -2
  113. package/dist/components/ModeIndicator.js +2 -1
  114. package/dist/components/ModeIndicator.js.map +2 -2
  115. package/dist/components/ModelConfig.js +20 -6
  116. package/dist/components/ModelConfig.js.map +2 -2
  117. package/dist/components/ModelListManager.js +7 -6
  118. package/dist/components/ModelListManager.js.map +2 -2
  119. package/dist/components/ModelSelector/ModelSelector.js +27 -14
  120. package/dist/components/ModelSelector/ModelSelector.js.map +2 -2
  121. package/dist/components/Onboarding.js +22 -16
  122. package/dist/components/Onboarding.js.map +2 -2
  123. package/dist/components/OperationSummary.js +130 -0
  124. package/dist/components/OperationSummary.js.map +7 -0
  125. package/dist/components/ProgressBar.js +74 -0
  126. package/dist/components/ProgressBar.js.map +7 -0
  127. package/dist/components/PromptInput.js +210 -87
  128. package/dist/components/PromptInput.js.map +2 -2
  129. package/dist/components/RequestStatusIndicator.js +194 -0
  130. package/dist/components/RequestStatusIndicator.js.map +7 -0
  131. package/dist/components/SensitiveFileWarning.js +31 -0
  132. package/dist/components/SensitiveFileWarning.js.map +7 -0
  133. package/dist/components/Spinner.js +141 -27
  134. package/dist/components/Spinner.js.map +2 -2
  135. package/dist/components/SpinnerSymbol.js +21 -27
  136. package/dist/components/SpinnerSymbol.js.map +2 -2
  137. package/dist/components/StreamingBashOutput.js +9 -8
  138. package/dist/components/StreamingBashOutput.js.map +2 -2
  139. package/dist/components/StructuredDiff.js +6 -8
  140. package/dist/components/StructuredDiff.js.map +2 -2
  141. package/dist/components/SubagentBlock.js +5 -3
  142. package/dist/components/SubagentBlock.js.map +2 -2
  143. package/dist/components/SubagentProgress.js +17 -15
  144. package/dist/components/SubagentProgress.js.map +2 -2
  145. package/dist/components/TaskCard.js +30 -24
  146. package/dist/components/TaskCard.js.map +2 -2
  147. package/dist/components/TextInput.js +9 -1
  148. package/dist/components/TextInput.js.map +2 -2
  149. package/dist/components/TodoChangeBlock.js +1 -1
  150. package/dist/components/TodoChangeBlock.js.map +2 -2
  151. package/dist/components/TodoPanel.js +140 -31
  152. package/dist/components/TodoPanel.js.map +3 -3
  153. package/dist/components/TokenCounter.js +74 -0
  154. package/dist/components/TokenCounter.js.map +7 -0
  155. package/dist/components/TokenWarning.js +2 -1
  156. package/dist/components/TokenWarning.js.map +2 -2
  157. package/dist/components/ToolUseLoader.js +2 -2
  158. package/dist/components/ToolUseLoader.js.map +2 -2
  159. package/dist/components/TreeConnector.js +26 -0
  160. package/dist/components/TreeConnector.js.map +7 -0
  161. package/dist/components/TrustDialog.js +2 -1
  162. package/dist/components/TrustDialog.js.map +2 -2
  163. package/dist/components/TurnCompletionIndicator.js +18 -0
  164. package/dist/components/TurnCompletionIndicator.js.map +7 -0
  165. package/dist/components/binary-feedback/BinaryFeedbackView.js +2 -1
  166. package/dist/components/binary-feedback/BinaryFeedbackView.js.map +2 -2
  167. package/dist/components/messages/AssistantTextMessage.js +20 -9
  168. package/dist/components/messages/AssistantTextMessage.js.map +2 -2
  169. package/dist/components/messages/AssistantThinkingMessage.js +18 -3
  170. package/dist/components/messages/AssistantThinkingMessage.js.map +2 -2
  171. package/dist/components/messages/AssistantToolUseMessage.js +17 -10
  172. package/dist/components/messages/AssistantToolUseMessage.js.map +2 -2
  173. package/dist/components/messages/GroupRenderer.js +54 -0
  174. package/dist/components/messages/GroupRenderer.js.map +7 -0
  175. package/dist/components/messages/NestedTasksPreview.js +24 -0
  176. package/dist/components/messages/NestedTasksPreview.js.map +7 -0
  177. package/dist/components/messages/ParallelTasksGroupView.js +93 -0
  178. package/dist/components/messages/ParallelTasksGroupView.js.map +7 -0
  179. package/dist/components/messages/TaskInModuleView.js +218 -0
  180. package/dist/components/messages/TaskInModuleView.js.map +7 -0
  181. package/dist/components/messages/TaskOutputContent.js +56 -0
  182. package/dist/components/messages/TaskOutputContent.js.map +7 -0
  183. package/dist/components/messages/UserPromptMessage.js +2 -2
  184. package/dist/components/messages/UserPromptMessage.js.map +2 -2
  185. package/dist/components/messages/UserToolResultMessage/UserToolSuccessMessage.js +2 -3
  186. package/dist/components/messages/UserToolResultMessage/UserToolSuccessMessage.js.map +2 -2
  187. package/dist/components/permissions/FallbackPermissionRequest.js +4 -4
  188. package/dist/components/permissions/FallbackPermissionRequest.js.map +2 -2
  189. package/dist/components/permissions/FilesystemPermissionRequest/FilesystemPermissionRequest.js +4 -4
  190. package/dist/components/permissions/FilesystemPermissionRequest/FilesystemPermissionRequest.js.map +2 -2
  191. package/dist/constants/colors.js +120 -54
  192. package/dist/constants/colors.js.map +2 -2
  193. package/dist/constants/formatRules.js +102 -0
  194. package/dist/constants/formatRules.js.map +7 -0
  195. package/dist/constants/prompts.js +12 -34
  196. package/dist/constants/prompts.js.map +2 -2
  197. package/dist/constants/symbols.js +64 -6
  198. package/dist/constants/symbols.js.map +2 -2
  199. package/dist/constants/timing.js +5 -0
  200. package/dist/constants/timing.js.map +2 -2
  201. package/dist/constants/toolInputExamples.js +84 -0
  202. package/dist/constants/toolInputExamples.js.map +7 -0
  203. package/dist/core/backupManager.js +321 -0
  204. package/dist/core/backupManager.js.map +7 -0
  205. package/dist/core/config/defaults.js +84 -0
  206. package/dist/core/config/defaults.js.map +7 -0
  207. package/dist/core/config/index.js +111 -0
  208. package/dist/core/config/index.js.map +7 -0
  209. package/dist/core/config/loader.js +221 -0
  210. package/dist/core/config/loader.js.map +7 -0
  211. package/dist/core/config/migrations.js +128 -0
  212. package/dist/core/config/migrations.js.map +7 -0
  213. package/dist/core/config/schema.js +178 -0
  214. package/dist/core/config/schema.js.map +7 -0
  215. package/dist/core/costTracker.js +129 -0
  216. package/dist/core/costTracker.js.map +7 -0
  217. package/dist/core/gitAutoCommit.js +287 -0
  218. package/dist/core/gitAutoCommit.js.map +7 -0
  219. package/dist/core/index.js +8 -0
  220. package/dist/core/index.js.map +7 -0
  221. package/dist/core/operationTracker.js +212 -0
  222. package/dist/core/operationTracker.js.map +7 -0
  223. package/dist/core/permissions/auditLog.js +204 -0
  224. package/dist/core/permissions/auditLog.js.map +7 -0
  225. package/dist/core/permissions/engine/index.js +3 -0
  226. package/dist/core/permissions/engine/index.js.map +7 -0
  227. package/dist/core/permissions/engine/permissionEngine.js +106 -0
  228. package/dist/core/permissions/engine/permissionEngine.js.map +7 -0
  229. package/dist/core/permissions/engine/types.js +1 -0
  230. package/dist/core/permissions/engine/types.js.map +7 -0
  231. package/dist/core/permissions/index.js +84 -0
  232. package/dist/core/permissions/index.js.map +7 -0
  233. package/dist/core/permissions/ruleEngine.js +259 -0
  234. package/dist/core/permissions/ruleEngine.js.map +7 -0
  235. package/dist/core/permissions/rules/allowedToolsRule.js +62 -0
  236. package/dist/core/permissions/rules/allowedToolsRule.js.map +7 -0
  237. package/dist/core/permissions/rules/autoEscalationRule.js +296 -0
  238. package/dist/core/permissions/rules/autoEscalationRule.js.map +7 -0
  239. package/dist/core/permissions/rules/index.js +46 -0
  240. package/dist/core/permissions/rules/index.js.map +7 -0
  241. package/dist/core/permissions/rules/planModeRule.js +55 -0
  242. package/dist/core/permissions/rules/planModeRule.js.map +7 -0
  243. package/dist/core/permissions/rules/projectBoundaryRule.js +173 -0
  244. package/dist/core/permissions/rules/projectBoundaryRule.js.map +7 -0
  245. package/dist/core/permissions/rules/safeModeRule.js +65 -0
  246. package/dist/core/permissions/rules/safeModeRule.js.map +7 -0
  247. package/dist/core/permissions/rules/sensitivePathsRule.js +345 -0
  248. package/dist/core/permissions/rules/sensitivePathsRule.js.map +7 -0
  249. package/dist/core/permissions/types.js +127 -0
  250. package/dist/core/permissions/types.js.map +7 -0
  251. package/dist/core/tokenStats.js +9 -0
  252. package/dist/core/tokenStats.js.map +7 -0
  253. package/dist/core/tokenStatsManager.js +331 -0
  254. package/dist/core/tokenStatsManager.js.map +7 -0
  255. package/dist/core/tools/executor.js +143 -0
  256. package/dist/core/tools/executor.js.map +7 -0
  257. package/dist/core/tools/index.js +15 -0
  258. package/dist/core/tools/index.js.map +7 -0
  259. package/dist/core/tools/registry.js +183 -0
  260. package/dist/core/tools/registry.js.map +7 -0
  261. package/dist/core/tools/types.js +1 -0
  262. package/dist/core/tools/types.js.map +7 -0
  263. package/dist/cost-tracker.js +23 -15
  264. package/dist/cost-tracker.js.map +2 -2
  265. package/dist/entrypoints/cli.js +158 -130
  266. package/dist/entrypoints/cli.js.map +2 -2
  267. package/dist/entrypoints/mcp.js +12 -4
  268. package/dist/entrypoints/mcp.js.map +2 -2
  269. package/dist/history.js +14 -3
  270. package/dist/history.js.map +2 -2
  271. package/dist/hooks/useAgentTokenStats.js +72 -0
  272. package/dist/hooks/useAgentTokenStats.js.map +7 -0
  273. package/dist/hooks/useAgentTranscripts.js +140 -0
  274. package/dist/hooks/useAgentTranscripts.js.map +7 -0
  275. package/dist/hooks/useAnimationSync.js +53 -0
  276. package/dist/hooks/useAnimationSync.js.map +7 -0
  277. package/dist/hooks/useArrowKeyHistory.js +4 -2
  278. package/dist/hooks/useArrowKeyHistory.js.map +2 -2
  279. package/dist/hooks/useCanUseTool.js +3 -1
  280. package/dist/hooks/useCanUseTool.js.map +2 -2
  281. package/dist/hooks/useExitOnCtrlCD.js +9 -5
  282. package/dist/hooks/useExitOnCtrlCD.js.map +2 -2
  283. package/dist/hooks/useHookStatus.js +40 -0
  284. package/dist/hooks/useHookStatus.js.map +7 -0
  285. package/dist/hooks/useLogMessages.js +29 -2
  286. package/dist/hooks/useLogMessages.js.map +2 -2
  287. package/dist/hooks/useMessageGroups.js +43 -0
  288. package/dist/hooks/useMessageGroups.js.map +7 -0
  289. package/dist/hooks/useTerminalSize.js +62 -6
  290. package/dist/hooks/useTerminalSize.js.map +2 -2
  291. package/dist/hooks/useUnifiedCompletion.js +69 -0
  292. package/dist/hooks/useUnifiedCompletion.js.map +2 -2
  293. package/dist/i18n/index.js +109 -0
  294. package/dist/i18n/index.js.map +7 -0
  295. package/dist/i18n/locales/en.js +348 -0
  296. package/dist/i18n/locales/en.js.map +7 -0
  297. package/dist/i18n/locales/index.js +7 -0
  298. package/dist/i18n/locales/index.js.map +7 -0
  299. package/dist/i18n/locales/zh-CN.js +348 -0
  300. package/dist/i18n/locales/zh-CN.js.map +7 -0
  301. package/dist/i18n/types.js +8 -0
  302. package/dist/i18n/types.js.map +7 -0
  303. package/dist/permissions.js +28 -1
  304. package/dist/permissions.js.map +2 -2
  305. package/dist/query.js +253 -21
  306. package/dist/query.js.map +3 -3
  307. package/dist/screens/REPL.js +523 -194
  308. package/dist/screens/REPL.js.map +3 -3
  309. package/dist/services/adapters/chatCompletions.js +3 -1
  310. package/dist/services/adapters/chatCompletions.js.map +2 -2
  311. package/dist/services/adapters/messageNormalizer.js +354 -0
  312. package/dist/services/adapters/messageNormalizer.js.map +7 -0
  313. package/dist/services/adapters/responsesAPI.js +6 -3
  314. package/dist/services/adapters/responsesAPI.js.map +2 -2
  315. package/dist/services/checkpointManager.js +386 -0
  316. package/dist/services/checkpointManager.js.map +7 -0
  317. package/dist/services/claude.js +192 -14
  318. package/dist/services/claude.js.map +3 -3
  319. package/dist/services/compressionService.js +50 -1
  320. package/dist/services/compressionService.js.map +2 -2
  321. package/dist/services/contextMonitor.js +162 -0
  322. package/dist/services/contextMonitor.js.map +7 -0
  323. package/dist/services/customCommands.js +60 -41
  324. package/dist/services/customCommands.js.map +2 -2
  325. package/dist/services/hookExecutor.js +173 -1
  326. package/dist/services/hookExecutor.js.map +2 -2
  327. package/dist/services/intelligentCompactor.js +281 -0
  328. package/dist/services/intelligentCompactor.js.map +7 -0
  329. package/dist/services/lspConfig.js +109 -0
  330. package/dist/services/lspConfig.js.map +7 -0
  331. package/dist/services/mcpClient.js +338 -43
  332. package/dist/services/mcpClient.js.map +2 -2
  333. package/dist/services/modelOrchestrator.js +310 -0
  334. package/dist/services/modelOrchestrator.js.map +7 -0
  335. package/dist/services/openai.js +8 -1
  336. package/dist/services/openai.js.map +2 -2
  337. package/dist/services/outputStyles.js +138 -0
  338. package/dist/services/outputStyles.js.map +7 -0
  339. package/dist/services/plugins/index.js +5 -0
  340. package/dist/services/plugins/index.js.map +7 -0
  341. package/dist/services/plugins/lspServers.js +188 -0
  342. package/dist/services/plugins/lspServers.js.map +7 -0
  343. package/dist/services/plugins/pluginRuntime.js +229 -0
  344. package/dist/services/plugins/pluginRuntime.js.map +7 -0
  345. package/dist/services/plugins/pluginValidation.js +219 -0
  346. package/dist/services/plugins/pluginValidation.js.map +7 -0
  347. package/dist/services/plugins/skillMarketplace.js +556 -0
  348. package/dist/services/plugins/skillMarketplace.js.map +7 -0
  349. package/dist/services/responseStateManager.js +37 -3
  350. package/dist/services/responseStateManager.js.map +2 -2
  351. package/dist/services/sandbox/filesystemBoundary.js +341 -0
  352. package/dist/services/sandbox/filesystemBoundary.js.map +7 -0
  353. package/dist/services/sandbox/index.js +14 -0
  354. package/dist/services/sandbox/index.js.map +7 -0
  355. package/dist/services/sandbox/networkProxy.js +293 -0
  356. package/dist/services/sandbox/networkProxy.js.map +7 -0
  357. package/dist/services/sandbox/sandboxController.js +574 -0
  358. package/dist/services/sandbox/sandboxController.js.map +7 -0
  359. package/dist/services/sandbox/types.js +50 -0
  360. package/dist/services/sandbox/types.js.map +7 -0
  361. package/dist/services/sessionMemory.js +266 -0
  362. package/dist/services/sessionMemory.js.map +7 -0
  363. package/dist/services/taskRouter.js +324 -0
  364. package/dist/services/taskRouter.js.map +7 -0
  365. package/dist/tools/ArchitectTool/ArchitectTool.js +7 -1
  366. package/dist/tools/ArchitectTool/ArchitectTool.js.map +2 -2
  367. package/dist/tools/AskExpertModelTool/AskExpertModelTool.js +6 -2
  368. package/dist/tools/AskExpertModelTool/AskExpertModelTool.js.map +2 -2
  369. package/dist/tools/AskUserQuestionTool/AskUserQuestionTool.js +2 -1
  370. package/dist/tools/AskUserQuestionTool/AskUserQuestionTool.js.map +2 -2
  371. package/dist/tools/BaseTool.js +72 -0
  372. package/dist/tools/BaseTool.js.map +7 -0
  373. package/dist/tools/BashOutputTool/BashOutputToolResultMessage.js +3 -0
  374. package/dist/tools/BashOutputTool/BashOutputToolResultMessage.js.map +2 -2
  375. package/dist/tools/BashTool/BashTool.js +79 -3
  376. package/dist/tools/BashTool/BashTool.js.map +2 -2
  377. package/dist/tools/BashTool/BashToolResultMessage.js +3 -0
  378. package/dist/tools/BashTool/BashToolResultMessage.js.map +2 -2
  379. package/dist/tools/BashTool/OutputLine.js +54 -0
  380. package/dist/tools/BashTool/OutputLine.js.map +2 -2
  381. package/dist/tools/BashTool/prompt.js +336 -3
  382. package/dist/tools/BashTool/prompt.js.map +2 -2
  383. package/dist/tools/FileEditTool/FileEditTool.js +29 -4
  384. package/dist/tools/FileEditTool/FileEditTool.js.map +2 -2
  385. package/dist/tools/FileEditTool/prompt.js +6 -3
  386. package/dist/tools/FileEditTool/prompt.js.map +2 -2
  387. package/dist/tools/FileWriteTool/FileWriteTool.js +5 -5
  388. package/dist/tools/FileWriteTool/FileWriteTool.js.map +2 -2
  389. package/dist/tools/FileWriteTool/prompt.js +4 -2
  390. package/dist/tools/FileWriteTool/prompt.js.map +2 -2
  391. package/dist/tools/GlobTool/GlobTool.js +4 -2
  392. package/dist/tools/GlobTool/GlobTool.js.map +2 -2
  393. package/dist/tools/GrepTool/GrepTool.js +36 -7
  394. package/dist/tools/GrepTool/GrepTool.js.map +2 -2
  395. package/dist/tools/KillShellTool/KillShellToolResultMessage.js +3 -0
  396. package/dist/tools/KillShellTool/KillShellToolResultMessage.js.map +2 -2
  397. package/dist/tools/ListMcpResourcesTool/ListMcpResourcesTool.js +109 -0
  398. package/dist/tools/ListMcpResourcesTool/ListMcpResourcesTool.js.map +7 -0
  399. package/dist/tools/ListMcpResourcesTool/prompt.js +19 -0
  400. package/dist/tools/ListMcpResourcesTool/prompt.js.map +7 -0
  401. package/dist/tools/LspTool/LspTool.js +664 -0
  402. package/dist/tools/LspTool/LspTool.js.map +7 -0
  403. package/dist/tools/LspTool/prompt.js +27 -0
  404. package/dist/tools/LspTool/prompt.js.map +7 -0
  405. package/dist/tools/MCPTool/MCPTool.js +9 -1
  406. package/dist/tools/MCPTool/MCPTool.js.map +2 -2
  407. package/dist/tools/MemoryReadTool/MemoryReadTool.js +19 -6
  408. package/dist/tools/MemoryReadTool/MemoryReadTool.js.map +2 -2
  409. package/dist/tools/MemoryWriteTool/MemoryWriteTool.js +6 -6
  410. package/dist/tools/MemoryWriteTool/MemoryWriteTool.js.map +2 -2
  411. package/dist/tools/MultiEditTool/MultiEditTool.js +19 -2
  412. package/dist/tools/MultiEditTool/MultiEditTool.js.map +2 -2
  413. package/dist/tools/MultiEditTool/prompt.js +5 -3
  414. package/dist/tools/MultiEditTool/prompt.js.map +2 -2
  415. package/dist/tools/NotebookEditTool/NotebookEditTool.js +7 -2
  416. package/dist/tools/NotebookEditTool/NotebookEditTool.js.map +2 -2
  417. package/dist/tools/NotebookReadTool/NotebookReadTool.js.map +2 -2
  418. package/dist/tools/PlanModeTool/EnterPlanModeTool.js +75 -0
  419. package/dist/tools/PlanModeTool/EnterPlanModeTool.js.map +7 -0
  420. package/dist/tools/PlanModeTool/ExitPlanModeTool.js +109 -0
  421. package/dist/tools/PlanModeTool/ExitPlanModeTool.js.map +7 -0
  422. package/dist/tools/PlanModeTool/prompt.js +94 -0
  423. package/dist/tools/PlanModeTool/prompt.js.map +7 -0
  424. package/dist/tools/ReadMcpResourceTool/ReadMcpResourceTool.js +130 -0
  425. package/dist/tools/ReadMcpResourceTool/ReadMcpResourceTool.js.map +7 -0
  426. package/dist/tools/ReadMcpResourceTool/prompt.js +17 -0
  427. package/dist/tools/ReadMcpResourceTool/prompt.js.map +7 -0
  428. package/dist/tools/SkillTool/SkillTool.js +10 -4
  429. package/dist/tools/SkillTool/SkillTool.js.map +2 -2
  430. package/dist/tools/SkillTool/prompt.js +1 -1
  431. package/dist/tools/SkillTool/prompt.js.map +1 -1
  432. package/dist/tools/SlashCommandTool/SlashCommandTool.js +260 -0
  433. package/dist/tools/SlashCommandTool/SlashCommandTool.js.map +7 -0
  434. package/dist/tools/SlashCommandTool/prompt.js +35 -0
  435. package/dist/tools/SlashCommandTool/prompt.js.map +7 -0
  436. package/dist/tools/TaskOutputTool/TaskOutputTool.js +190 -0
  437. package/dist/tools/TaskOutputTool/TaskOutputTool.js.map +7 -0
  438. package/dist/tools/TaskOutputTool/prompt.js +15 -0
  439. package/dist/tools/TaskOutputTool/prompt.js.map +7 -0
  440. package/dist/tools/TaskTool/TaskTool.js +310 -104
  441. package/dist/tools/TaskTool/TaskTool.js.map +2 -2
  442. package/dist/tools/TaskTool/prompt.js.map +2 -2
  443. package/dist/tools/TodoWriteTool/TodoWriteTool.js +42 -77
  444. package/dist/tools/TodoWriteTool/TodoWriteTool.js.map +2 -2
  445. package/dist/tools/URLFetcherTool/URLFetcherTool.js +4 -1
  446. package/dist/tools/URLFetcherTool/URLFetcherTool.js.map +2 -2
  447. package/dist/tools/URLFetcherTool/cache.js +55 -8
  448. package/dist/tools/URLFetcherTool/cache.js.map +2 -2
  449. package/dist/tools.js +31 -2
  450. package/dist/tools.js.map +2 -2
  451. package/dist/types/hooks.js +4 -0
  452. package/dist/types/hooks.js.map +2 -2
  453. package/dist/types/marketplace.js.map +2 -2
  454. package/dist/types/messageGroup.js +36 -0
  455. package/dist/types/messageGroup.js.map +7 -0
  456. package/dist/types/plugin.js.map +2 -2
  457. package/dist/types/thinking.js +1 -0
  458. package/dist/types/thinking.js.map +7 -0
  459. package/dist/utils/BackgroundShellManager.js +136 -39
  460. package/dist/utils/BackgroundShellManager.js.map +2 -2
  461. package/dist/utils/CircuitBreaker.js +242 -0
  462. package/dist/utils/CircuitBreaker.js.map +7 -0
  463. package/dist/utils/MessageBatchBuffer.js +102 -0
  464. package/dist/utils/MessageBatchBuffer.js.map +7 -0
  465. package/dist/utils/PersistentShell.js +151 -1
  466. package/dist/utils/PersistentShell.js.map +2 -2
  467. package/dist/utils/agentLoader.js +1 -23
  468. package/dist/utils/agentLoader.js.map +2 -2
  469. package/dist/utils/agentTranscripts.js +641 -0
  470. package/dist/utils/agentTranscripts.js.map +7 -0
  471. package/dist/utils/animationManager.js +213 -0
  472. package/dist/utils/animationManager.js.map +7 -0
  473. package/dist/utils/animationSync.js +110 -0
  474. package/dist/utils/animationSync.js.map +7 -0
  475. package/dist/utils/ask.js +2 -0
  476. package/dist/utils/ask.js.map +2 -2
  477. package/dist/utils/asyncFile.js +215 -0
  478. package/dist/utils/asyncFile.js.map +7 -0
  479. package/dist/utils/backgroundAgentManager.js +231 -0
  480. package/dist/utils/backgroundAgentManager.js.map +7 -0
  481. package/dist/utils/config.js +108 -10
  482. package/dist/utils/config.js.map +2 -2
  483. package/dist/utils/conversationRecovery.js +19 -0
  484. package/dist/utils/conversationRecovery.js.map +2 -2
  485. package/dist/utils/credentials/CredentialStore.js +1 -0
  486. package/dist/utils/credentials/CredentialStore.js.map +7 -0
  487. package/dist/utils/credentials/EncryptedFileStore.js +157 -0
  488. package/dist/utils/credentials/EncryptedFileStore.js.map +7 -0
  489. package/dist/utils/credentials/index.js +37 -0
  490. package/dist/utils/credentials/index.js.map +7 -0
  491. package/dist/utils/credentials/migration.js +82 -0
  492. package/dist/utils/credentials/migration.js.map +7 -0
  493. package/dist/utils/exit.js +73 -0
  494. package/dist/utils/exit.js.map +7 -0
  495. package/dist/utils/format.js +73 -5
  496. package/dist/utils/format.js.map +2 -2
  497. package/dist/utils/generators.js +76 -6
  498. package/dist/utils/generators.js.map +2 -2
  499. package/dist/utils/globalErrorHandler.js +149 -0
  500. package/dist/utils/globalErrorHandler.js.map +7 -0
  501. package/dist/utils/groupHandlers/index.js +8 -0
  502. package/dist/utils/groupHandlers/index.js.map +7 -0
  503. package/dist/utils/groupHandlers/parallelTasksHandler.js +140 -0
  504. package/dist/utils/groupHandlers/parallelTasksHandler.js.map +7 -0
  505. package/dist/utils/groupHandlers/taskHandler.js +104 -0
  506. package/dist/utils/groupHandlers/taskHandler.js.map +7 -0
  507. package/dist/utils/groupHandlers/types.js +1 -0
  508. package/dist/utils/groupHandlers/types.js.map +7 -0
  509. package/dist/utils/logRotation.js +224 -0
  510. package/dist/utils/logRotation.js.map +7 -0
  511. package/dist/utils/markdown.js +13 -1
  512. package/dist/utils/markdown.js.map +2 -2
  513. package/dist/utils/marketplaceManager.js +3 -5
  514. package/dist/utils/marketplaceManager.js.map +2 -2
  515. package/dist/utils/memSafety.js +264 -0
  516. package/dist/utils/memSafety.js.map +7 -0
  517. package/dist/utils/messageGroupManager.js +274 -0
  518. package/dist/utils/messageGroupManager.js.map +7 -0
  519. package/dist/utils/messages.js +13 -4
  520. package/dist/utils/messages.js.map +2 -2
  521. package/dist/utils/model.js +119 -15
  522. package/dist/utils/model.js.map +3 -3
  523. package/dist/utils/permissions/filesystem.js +162 -6
  524. package/dist/utils/permissions/filesystem.js.map +2 -2
  525. package/dist/utils/plan/planMode.js +143 -0
  526. package/dist/utils/plan/planMode.js.map +7 -0
  527. package/dist/utils/pluginLoader.js +17 -21
  528. package/dist/utils/pluginLoader.js.map +2 -2
  529. package/dist/utils/ripgrep.js +55 -2
  530. package/dist/utils/ripgrep.js.map +2 -2
  531. package/dist/utils/safePath.js +132 -0
  532. package/dist/utils/safePath.js.map +7 -0
  533. package/dist/utils/sanitizeInput.js +32 -0
  534. package/dist/utils/sanitizeInput.js.map +7 -0
  535. package/dist/utils/secureKeyStorage.js +312 -0
  536. package/dist/utils/secureKeyStorage.js.map +7 -0
  537. package/dist/utils/sensitiveFiles.js +125 -0
  538. package/dist/utils/sensitiveFiles.js.map +7 -0
  539. package/dist/utils/session/sessionPlugins.js +67 -0
  540. package/dist/utils/session/sessionPlugins.js.map +7 -0
  541. package/dist/utils/taskDisplayUtils.js +257 -0
  542. package/dist/utils/taskDisplayUtils.js.map +7 -0
  543. package/dist/utils/teamConfig.js +2 -1
  544. package/dist/utils/teamConfig.js.map +2 -2
  545. package/dist/utils/theme.js +6 -6
  546. package/dist/utils/theme.js.map +1 -1
  547. package/dist/utils/todoStorage.js +92 -2
  548. package/dist/utils/todoStorage.js.map +2 -2
  549. package/dist/utils/toolRiskClassification.js +207 -0
  550. package/dist/utils/toolRiskClassification.js.map +7 -0
  551. package/dist/utils/toolTimeout.js +136 -0
  552. package/dist/utils/toolTimeout.js.map +7 -0
  553. package/dist/utils/tooling/safeRender.js +116 -0
  554. package/dist/utils/tooling/safeRender.js.map +7 -0
  555. package/dist/utils/userFriendlyError.js +346 -0
  556. package/dist/utils/userFriendlyError.js.map +7 -0
  557. package/dist/utils/vendor/ripgrep/arm64-darwin/rg +0 -0
  558. package/dist/version.js +2 -2
  559. package/dist/version.js.map +1 -1
  560. package/package.json +17 -5
  561. package/scripts/postinstall.js +128 -38
  562. package/dist/commands/agents.js +0 -2086
  563. package/dist/commands/agents.js.map +0 -7
  564. package/dist/commands/build.js +0 -74
  565. package/dist/commands/build.js.map +0 -7
  566. package/dist/commands/compression.js +0 -57
  567. package/dist/commands/compression.js.map +0 -7
  568. package/dist/commands/listen.js +0 -37
  569. package/dist/commands/listen.js.map +0 -7
  570. package/dist/commands/login.js +0 -37
  571. package/dist/commands/login.js.map +0 -7
  572. package/dist/commands/logout.js +0 -33
  573. package/dist/commands/logout.js.map +0 -7
  574. package/dist/commands/mcp.js +0 -40
  575. package/dist/commands/mcp.js.map +0 -7
  576. package/dist/commands/mcp_refresh.js +0 -40
  577. package/dist/commands/mcp_refresh.js.map +0 -7
  578. package/dist/commands/modelstatus.js +0 -21
  579. package/dist/commands/modelstatus.js.map +0 -7
  580. package/dist/commands/onboarding.js +0 -36
  581. package/dist/commands/onboarding.js.map +0 -7
  582. package/dist/commands/plugin-interactive.js +0 -446
  583. package/dist/commands/plugin-interactive.js.map +0 -7
  584. package/dist/commands/pr_comments.js +0 -61
  585. package/dist/commands/pr_comments.js.map +0 -7
  586. package/dist/commands/release-notes.js +0 -30
  587. package/dist/commands/release-notes.js.map +0 -7
  588. package/dist/commands/review.js +0 -51
  589. package/dist/commands/review.js.map +0 -7
  590. package/dist/components/Bug.js +0 -147
  591. package/dist/components/Bug.js.map +0 -7
  592. package/dist/components/ModelSelector.js +0 -2062
  593. package/dist/components/ModelSelector.js.map +0 -7
  594. package/dist/components/ModelStatusDisplay.js +0 -87
  595. package/dist/components/ModelStatusDisplay.js.map +0 -7
  596. package/dist/entrypoints/cli-wrapper.js +0 -61
  597. package/dist/entrypoints/cli-wrapper.js.map +0 -7
  598. package/dist/hooks/useCancelRequest.js +0 -28
  599. package/dist/hooks/useCancelRequest.js.map +0 -7
  600. package/dist/screens/Doctor.js +0 -22
  601. package/dist/screens/Doctor.js.map +0 -7
@@ -1,2086 +0,0 @@
1
- import React, { useState, useEffect, useMemo, useCallback, useReducer, Fragment } from "react";
2
- import { Box, Text, useInput } from "ink";
3
- import InkTextInput from "ink-text-input";
4
- import { getActiveAgents, clearAgentCache } from "../utils/agentLoader.js";
5
- import { writeFileSync, unlinkSync, mkdirSync, existsSync, renameSync } from "fs";
6
- import { join } from "path";
7
- import * as path from "path";
8
- import { homedir } from "os";
9
- import * as os from "os";
10
- import { getCwd } from "../utils/state.js";
11
- import { getTheme } from "../utils/theme.js";
12
- import { exec, spawn } from "child_process";
13
- import { promisify } from "util";
14
- import { getMCPTools } from "../services/mcpClient.js";
15
- import { getModelManager } from "../utils/model.js";
16
- import { randomUUID } from "crypto";
17
- const execAsync = promisify(exec);
18
- const AGENT_LOCATIONS = {
19
- USER: "user",
20
- PROJECT: "project",
21
- BUILT_IN: "built-in",
22
- ALL: "all"
23
- };
24
- const UI_ICONS = {
25
- pointer: "\u276F",
26
- checkboxOn: "\u2611",
27
- checkboxOff: "\u2610",
28
- warning: "\u26A0",
29
- separator: "\u2500",
30
- loading: "\u25D0\u25D1\u25D2\u25D3"
31
- };
32
- const FOLDER_CONFIG = {
33
- FOLDER_NAME: ".claude",
34
- AGENTS_DIR: "agents"
35
- };
36
- const TOOL_CATEGORIES = {
37
- read: ["Read", "Glob", "Grep", "LS"],
38
- edit: ["Edit", "MultiEdit", "Write", "NotebookEdit"],
39
- execution: ["Bash", "BashOutput", "KillBash"],
40
- web: ["WebFetch", "WebSearch"],
41
- other: ["TodoWrite", "ExitPlanMode", "Task"]
42
- };
43
- function getDisplayModelName(modelId) {
44
- if (!modelId) return "Inherit";
45
- try {
46
- const profiles = getModelManager().getActiveModelProfiles();
47
- const profile = profiles.find((p) => p.modelName === modelId || p.name === modelId);
48
- return profile ? profile.name : `Custom (${modelId})`;
49
- } catch (error) {
50
- console.warn("Failed to get model profiles:", error);
51
- return modelId ? `Custom (${modelId})` : "Inherit";
52
- }
53
- }
54
- async function generateAgentWithClaude(prompt) {
55
- const { queryModel } = await import("../services/claude.js");
56
- const systemPrompt = `You are an expert at creating AI agent configurations. Based on the user's description, generate a specialized agent configuration.
57
-
58
- Return your response as a JSON object with exactly these fields:
59
- - identifier: A short, kebab-case identifier for the agent (e.g., "code-reviewer", "security-auditor")
60
- - whenToUse: A clear description of when this agent should be used (50-200 words)
61
- - systemPrompt: A comprehensive system prompt that defines the agent's role, capabilities, and behavior (200-500 words)
62
-
63
- Make the agent highly specialized and effective for the described use case.`;
64
- try {
65
- const messages = [
66
- {
67
- type: "user",
68
- uuid: randomUUID(),
69
- message: { role: "user", content: prompt }
70
- }
71
- ];
72
- const response = await queryModel("main", messages, [systemPrompt]);
73
- let responseText = "";
74
- if (typeof response.message?.content === "string") {
75
- responseText = response.message.content;
76
- } else if (Array.isArray(response.message?.content)) {
77
- const textContent = response.message.content.find((c) => c.type === "text");
78
- responseText = textContent?.text || "";
79
- } else if (response.message?.content?.[0]?.text) {
80
- responseText = response.message.content[0].text;
81
- }
82
- if (!responseText) {
83
- throw new Error("No text content in Claude response");
84
- }
85
- const MAX_JSON_SIZE = 1e5;
86
- const MAX_FIELD_LENGTH = 1e4;
87
- if (responseText.length > MAX_JSON_SIZE) {
88
- throw new Error("Response too large");
89
- }
90
- let parsed;
91
- try {
92
- parsed = JSON.parse(responseText.trim());
93
- } catch {
94
- const startIdx = responseText.indexOf("{");
95
- const endIdx = responseText.lastIndexOf("}");
96
- if (startIdx === -1 || endIdx === -1 || startIdx >= endIdx) {
97
- throw new Error("No valid JSON found in Claude response");
98
- }
99
- const jsonStr = responseText.substring(startIdx, endIdx + 1);
100
- if (jsonStr.length > MAX_JSON_SIZE) {
101
- throw new Error("JSON content too large");
102
- }
103
- try {
104
- parsed = JSON.parse(jsonStr);
105
- } catch (parseError) {
106
- throw new Error(`Invalid JSON format: ${parseError instanceof Error ? parseError.message : "Unknown error"}`);
107
- }
108
- }
109
- const identifier = String(parsed.identifier || "").slice(0, 100).trim();
110
- const whenToUse = String(parsed.whenToUse || "").slice(0, MAX_FIELD_LENGTH).trim();
111
- const agentSystemPrompt = String(parsed.systemPrompt || "").slice(0, MAX_FIELD_LENGTH).trim();
112
- if (!identifier || !whenToUse || !agentSystemPrompt) {
113
- throw new Error("Invalid response structure: missing required fields (identifier, whenToUse, systemPrompt)");
114
- }
115
- const sanitize = (str) => str.replace(/[\x00-\x1F\x7F-\x9F]/g, "");
116
- const cleanIdentifier = sanitize(identifier);
117
- if (!/^[a-zA-Z0-9-]+$/.test(cleanIdentifier)) {
118
- throw new Error("Invalid identifier format: only letters, numbers, and hyphens allowed");
119
- }
120
- return {
121
- identifier: cleanIdentifier,
122
- whenToUse: sanitize(whenToUse),
123
- systemPrompt: sanitize(agentSystemPrompt)
124
- };
125
- } catch (error) {
126
- console.error("AI generation failed:", error);
127
- const fallbackId = prompt.toLowerCase().replace(/[^a-z0-9\s-]/g, "").replace(/\s+/g, "-").slice(0, 30);
128
- return {
129
- identifier: fallbackId || "custom-agent",
130
- whenToUse: `Use this agent when you need assistance with: ${prompt}`,
131
- systemPrompt: `You are a specialized assistant focused on helping with ${prompt}. Provide expert-level assistance in this domain.`
132
- };
133
- }
134
- }
135
- function validateAgentType(agentType, existingAgents = []) {
136
- const errors = [];
137
- const warnings = [];
138
- if (!agentType) {
139
- errors.push("Agent type is required");
140
- return { isValid: false, errors, warnings };
141
- }
142
- if (!/^[a-zA-Z]/.test(agentType)) {
143
- errors.push("Agent type must start with a letter");
144
- }
145
- if (!/^[a-zA-Z0-9-]+$/.test(agentType)) {
146
- errors.push("Agent type can only contain letters, numbers, and hyphens");
147
- }
148
- if (agentType.length < 3) {
149
- errors.push("Agent type must be at least 3 characters long");
150
- }
151
- if (agentType.length > 50) {
152
- errors.push("Agent type must be less than 50 characters");
153
- }
154
- const reserved = ["help", "exit", "quit", "agents", "task"];
155
- if (reserved.includes(agentType.toLowerCase())) {
156
- errors.push("This name is reserved");
157
- }
158
- const duplicate = existingAgents.find((a) => a.agentType === agentType);
159
- if (duplicate) {
160
- errors.push(`An agent with this name already exists in ${duplicate.location}`);
161
- }
162
- if (agentType.includes("--")) {
163
- warnings.push("Consider avoiding consecutive hyphens");
164
- }
165
- return {
166
- isValid: errors.length === 0,
167
- errors,
168
- warnings
169
- };
170
- }
171
- function validateAgentConfig(config, existingAgents = []) {
172
- const errors = [];
173
- const warnings = [];
174
- if (config.agentType) {
175
- const typeValidation = validateAgentType(config.agentType, existingAgents);
176
- errors.push(...typeValidation.errors);
177
- warnings.push(...typeValidation.warnings);
178
- }
179
- if (!config.whenToUse) {
180
- errors.push("Description is required");
181
- } else if (config.whenToUse.length < 10) {
182
- warnings.push("Description should be more descriptive (at least 10 characters)");
183
- }
184
- if (!config.systemPrompt) {
185
- errors.push("System prompt is required");
186
- } else if (config.systemPrompt.length < 20) {
187
- warnings.push("System prompt might be too short for effective agent behavior");
188
- }
189
- if (!config.selectedTools || config.selectedTools.length === 0) {
190
- warnings.push("No tools selected - agent will have limited capabilities");
191
- }
192
- return {
193
- isValid: errors.length === 0,
194
- errors,
195
- warnings
196
- };
197
- }
198
- function getAgentDirectory(location) {
199
- if (location === AGENT_LOCATIONS.BUILT_IN || location === AGENT_LOCATIONS.ALL) {
200
- throw new Error(`Cannot get directory path for ${location} agents`);
201
- }
202
- if (location === AGENT_LOCATIONS.USER) {
203
- return join(homedir(), FOLDER_CONFIG.FOLDER_NAME, FOLDER_CONFIG.AGENTS_DIR);
204
- } else {
205
- return join(getCwd(), FOLDER_CONFIG.FOLDER_NAME, FOLDER_CONFIG.AGENTS_DIR);
206
- }
207
- }
208
- function getAgentFilePath(agent) {
209
- if (agent.location === "built-in") {
210
- throw new Error("Cannot get file path for built-in agents");
211
- }
212
- const dir = getAgentDirectory(agent.location);
213
- return join(dir, `${agent.agentType}.md`);
214
- }
215
- function ensureDirectoryExists(location) {
216
- const dir = getAgentDirectory(location);
217
- if (!existsSync(dir)) {
218
- mkdirSync(dir, { recursive: true });
219
- }
220
- return dir;
221
- }
222
- function generateAgentFileContent(agentType, description, tools, systemPrompt, model, color) {
223
- const descriptionLines = description.split("\n");
224
- const formattedDescription = descriptionLines.length > 1 ? `|
225
- ${descriptionLines.join("\n ")}` : JSON.stringify(description);
226
- const lines = [
227
- "---",
228
- `name: ${agentType}`,
229
- `description: ${formattedDescription}`
230
- ];
231
- if (tools) {
232
- if (tools === "*") {
233
- lines.push(`tools: "*"`);
234
- } else if (Array.isArray(tools) && tools.length > 0) {
235
- lines.push(`tools: [${tools.map((t) => `"${t}"`).join(", ")}]`);
236
- }
237
- }
238
- if (model) {
239
- lines.push(`model: ${model}`);
240
- }
241
- if (color) {
242
- lines.push(`color: ${color}`);
243
- }
244
- lines.push("---", "", systemPrompt);
245
- return lines.join("\n");
246
- }
247
- async function saveAgent(location, agentType, description, tools, systemPrompt, model, color, throwIfExists = true) {
248
- if (location === AGENT_LOCATIONS.BUILT_IN) {
249
- throw new Error("Cannot save built-in agents");
250
- }
251
- ensureDirectoryExists(location);
252
- const filePath = join(getAgentDirectory(location), `${agentType}.md`);
253
- const tempFile = `${filePath}.tmp.${Date.now()}.${Math.random().toString(36).substr(2, 9)}`;
254
- const toolsForFile = Array.isArray(tools) && tools.length === 1 && tools[0] === "*" ? "*" : tools;
255
- const content = generateAgentFileContent(agentType, description, toolsForFile, systemPrompt, model, color);
256
- try {
257
- writeFileSync(tempFile, content, { encoding: "utf-8", flag: "wx" });
258
- if (throwIfExists && existsSync(filePath)) {
259
- try {
260
- unlinkSync(tempFile);
261
- } catch {
262
- }
263
- throw new Error(`Agent file already exists: ${filePath}`);
264
- }
265
- renameSync(tempFile, filePath);
266
- } catch (error) {
267
- try {
268
- if (existsSync(tempFile)) {
269
- unlinkSync(tempFile);
270
- }
271
- } catch (cleanupError) {
272
- console.warn("Failed to cleanup temp file:", cleanupError);
273
- }
274
- throw error;
275
- }
276
- }
277
- async function deleteAgent(agent) {
278
- if (agent.location === "built-in") {
279
- throw new Error("Cannot delete built-in agents");
280
- }
281
- const filePath = getAgentFilePath(agent);
282
- unlinkSync(filePath);
283
- }
284
- async function openInEditor(filePath) {
285
- const resolvedPath = path.resolve(filePath);
286
- const projectDir = process.cwd();
287
- const homeDir = os.homedir();
288
- const isSub = (base, target) => {
289
- const rel = path.relative(path.resolve(base), path.resolve(target));
290
- if (!rel || rel === "") return true;
291
- if (rel.startsWith("..")) return false;
292
- if (path.isAbsolute(rel)) return false;
293
- return true;
294
- };
295
- if (!isSub(projectDir, resolvedPath) && !isSub(homeDir, resolvedPath)) {
296
- throw new Error("Access denied: File path outside allowed directories");
297
- }
298
- if (!resolvedPath.endsWith(".md")) {
299
- throw new Error("Invalid file type: Only .md files are allowed");
300
- }
301
- return new Promise((resolve, reject) => {
302
- const platform = process.platform;
303
- let command;
304
- let args;
305
- switch (platform) {
306
- case "darwin":
307
- command = "open";
308
- args = [resolvedPath];
309
- break;
310
- case "win32":
311
- command = "cmd";
312
- args = ["/c", "start", "", resolvedPath];
313
- break;
314
- default:
315
- command = "xdg-open";
316
- args = [resolvedPath];
317
- break;
318
- }
319
- const child = spawn(command, args, {
320
- detached: true,
321
- stdio: "ignore",
322
- // 确保没有shell解释
323
- shell: false
324
- });
325
- child.unref();
326
- child.on("error", (error) => {
327
- reject(new Error(`Failed to open editor: ${error.message}`));
328
- });
329
- child.on("exit", (code) => {
330
- if (code === 0) {
331
- resolve();
332
- } else {
333
- reject(new Error(`Editor exited with code ${code}`));
334
- }
335
- });
336
- });
337
- }
338
- async function updateAgent(agent, description, tools, systemPrompt, color, model) {
339
- if (agent.location === "built-in") {
340
- throw new Error("Cannot update built-in agents");
341
- }
342
- const toolsForFile = tools.length === 1 && tools[0] === "*" ? "*" : tools;
343
- const content = generateAgentFileContent(agent.agentType, description, toolsForFile, systemPrompt, model, color);
344
- const filePath = getAgentFilePath(agent);
345
- writeFileSync(filePath, content, { encoding: "utf-8", flag: "w" });
346
- }
347
- function Header({ title, subtitle, step, totalSteps, children }) {
348
- const theme = getTheme();
349
- return /* @__PURE__ */ React.createElement(Box, { flexDirection: "column" }, /* @__PURE__ */ React.createElement(Text, { bold: true, color: theme.primary }, title), subtitle && /* @__PURE__ */ React.createElement(Text, { color: theme.secondary }, step && totalSteps ? `Step ${step}/${totalSteps}: ` : "", subtitle), children);
350
- }
351
- function InstructionBar({ instructions = "Press \u2191\u2193 to navigate \xB7 Enter to select \xB7 Esc to go back" }) {
352
- const theme = getTheme();
353
- return /* @__PURE__ */ React.createElement(Box, { marginTop: 2 }, /* @__PURE__ */ React.createElement(Box, { borderStyle: "round", borderColor: theme.secondary, paddingX: 1 }, /* @__PURE__ */ React.createElement(Text, { color: theme.secondary }, instructions)));
354
- }
355
- function SelectList({ options, selectedIndex, onChange, onCancel, numbered = true }) {
356
- const theme = getTheme();
357
- useInput((input, key) => {
358
- if (key.escape && onCancel) {
359
- onCancel();
360
- } else if (key.return) {
361
- onChange(options[selectedIndex].value);
362
- }
363
- });
364
- return /* @__PURE__ */ React.createElement(Box, { flexDirection: "column" }, options.map((option, idx) => /* @__PURE__ */ React.createElement(Box, { key: option.value }, /* @__PURE__ */ React.createElement(Text, { color: idx === selectedIndex ? theme.primary : void 0 }, idx === selectedIndex ? `${UI_ICONS.pointer} ` : " ", numbered ? `${idx + 1}. ` : "", option.label))));
365
- }
366
- function MultilineTextInput({
367
- value,
368
- onChange,
369
- placeholder = "",
370
- onSubmit,
371
- focus = true,
372
- rows = 5,
373
- error
374
- }) {
375
- const theme = getTheme();
376
- const [internalValue, setInternalValue] = useState(value);
377
- const [cursorBlink, setCursorBlink] = useState(true);
378
- useEffect(() => {
379
- setInternalValue(value);
380
- }, [value]);
381
- useEffect(() => {
382
- if (!focus) return;
383
- const timer = setInterval(() => {
384
- setCursorBlink((prev) => !prev);
385
- }, 500);
386
- return () => clearInterval(timer);
387
- }, [focus]);
388
- const lines = internalValue.split("\n");
389
- const lineCount = lines.length;
390
- const charCount = internalValue.length;
391
- const isEmpty = !internalValue.trim();
392
- const hasContent = !isEmpty;
393
- const formatLines = (text) => {
394
- if (!text && placeholder) {
395
- return [placeholder];
396
- }
397
- const maxWidth = 70;
398
- const result = [];
399
- const textLines = text.split("\n");
400
- textLines.forEach((line) => {
401
- if (line.length <= maxWidth) {
402
- result.push(line);
403
- } else {
404
- let remaining = line;
405
- while (remaining.length > 0) {
406
- result.push(remaining.slice(0, maxWidth));
407
- remaining = remaining.slice(maxWidth);
408
- }
409
- }
410
- });
411
- return result.length > 0 ? result : [""];
412
- };
413
- const displayLines = formatLines(internalValue);
414
- const visibleLines = displayLines.slice(Math.max(0, displayLines.length - rows));
415
- const handleSubmit = () => {
416
- if (internalValue.trim() && onSubmit) {
417
- onSubmit();
418
- }
419
- };
420
- return /* @__PURE__ */ React.createElement(Box, { flexDirection: "column", width: "100%" }, /* @__PURE__ */ React.createElement(Box, { flexDirection: "column" }, /* @__PURE__ */ React.createElement(
421
- Box,
422
- {
423
- borderStyle: "round",
424
- borderColor: focus ? theme.primary : "gray",
425
- paddingX: 2,
426
- paddingY: 1,
427
- minHeight: rows + 2
428
- },
429
- /* @__PURE__ */ React.createElement(Box, { flexDirection: "column" }, /* @__PURE__ */ React.createElement(
430
- InkTextInput,
431
- {
432
- value: internalValue,
433
- onChange: (val) => {
434
- setInternalValue(val);
435
- onChange(val);
436
- },
437
- onSubmit: handleSubmit,
438
- focus,
439
- placeholder
440
- }
441
- ), focus && cursorBlink && hasContent && /* @__PURE__ */ React.createElement(Text, { color: theme.primary }, "_"))
442
- ), /* @__PURE__ */ React.createElement(Box, { marginTop: 1, flexDirection: "row", justifyContent: "space-between" }, /* @__PURE__ */ React.createElement(Box, null, hasContent ? /* @__PURE__ */ React.createElement(Text, { color: theme.success }, "\u2713 ", charCount, " chars \u2022 ", lineCount, " line", lineCount !== 1 ? "s" : "") : /* @__PURE__ */ React.createElement(Text, { dimColor: true }, "\u25CB Type to begin...")), /* @__PURE__ */ React.createElement(Box, null, error ? /* @__PURE__ */ React.createElement(Text, { color: theme.error }, "\u26A0 ", error) : /* @__PURE__ */ React.createElement(Text, { dimColor: true }, hasContent ? "Ready" : "Waiting")))), /* @__PURE__ */ React.createElement(Box, { marginTop: 1 }, /* @__PURE__ */ React.createElement(Text, { dimColor: true }, "Press Enter to submit \xB7 Shift+Enter for new line")));
443
- }
444
- function LoadingSpinner({ text }) {
445
- const theme = getTheme();
446
- const [frame, setFrame] = useState(0);
447
- useEffect(() => {
448
- const interval = setInterval(() => {
449
- setFrame((prev) => (prev + 1) % UI_ICONS.loading.length);
450
- }, 100);
451
- return () => clearInterval(interval);
452
- }, []);
453
- return /* @__PURE__ */ React.createElement(Box, null, /* @__PURE__ */ React.createElement(Text, { color: theme.primary }, UI_ICONS.loading[frame]), text && /* @__PURE__ */ React.createElement(Text, { color: theme.secondary }, " ", text));
454
- }
455
- function AgentsUI({ onExit }) {
456
- const theme = getTheme();
457
- const [modeState, setModeState] = useState({
458
- mode: "list-agents",
459
- location: "all"
460
- });
461
- const [agents, setAgents] = useState([]);
462
- const [changes, setChanges] = useState([]);
463
- const [refreshKey, setRefreshKey] = useState(0);
464
- const [loading, setLoading] = useState(true);
465
- const [tools, setTools] = useState([]);
466
- const [createState, setCreateState] = useReducer(
467
- (state, action) => {
468
- switch (action.type) {
469
- case "RESET":
470
- return {
471
- location: null,
472
- agentType: "",
473
- method: null,
474
- generationPrompt: "",
475
- whenToUse: "",
476
- selectedTools: [],
477
- selectedModel: null,
478
- selectedColor: null,
479
- systemPrompt: "",
480
- isGenerating: false,
481
- wasGenerated: false,
482
- isAIGenerated: false,
483
- error: null,
484
- warnings: [],
485
- agentTypeCursor: 0,
486
- whenToUseCursor: 0,
487
- promptCursor: 0,
488
- generationPromptCursor: 0
489
- };
490
- case "SET_LOCATION":
491
- return { ...state, location: action.value };
492
- case "SET_METHOD":
493
- return { ...state, method: action.value };
494
- case "SET_AGENT_TYPE":
495
- return { ...state, agentType: action.value, error: null };
496
- case "SET_GENERATION_PROMPT":
497
- return { ...state, generationPrompt: action.value };
498
- case "SET_WHEN_TO_USE":
499
- return { ...state, whenToUse: action.value, error: null };
500
- case "SET_SELECTED_TOOLS":
501
- return { ...state, selectedTools: action.value };
502
- case "SET_SELECTED_MODEL":
503
- return { ...state, selectedModel: action.value };
504
- case "SET_SELECTED_COLOR":
505
- return { ...state, selectedColor: action.value };
506
- case "SET_SYSTEM_PROMPT":
507
- return { ...state, systemPrompt: action.value };
508
- case "SET_IS_GENERATING":
509
- return { ...state, isGenerating: action.value };
510
- case "SET_WAS_GENERATED":
511
- return { ...state, wasGenerated: action.value };
512
- case "SET_IS_AI_GENERATED":
513
- return { ...state, isAIGenerated: action.value };
514
- case "SET_ERROR":
515
- return { ...state, error: action.value };
516
- case "SET_WARNINGS":
517
- return { ...state, warnings: action.value };
518
- case "SET_CURSOR":
519
- return { ...state, [action.field]: action.value };
520
- default:
521
- return state;
522
- }
523
- },
524
- {
525
- location: null,
526
- agentType: "",
527
- method: null,
528
- generationPrompt: "",
529
- whenToUse: "",
530
- selectedTools: [],
531
- selectedModel: null,
532
- selectedColor: null,
533
- systemPrompt: "",
534
- isGenerating: false,
535
- wasGenerated: false,
536
- isAIGenerated: false,
537
- error: null,
538
- warnings: [],
539
- agentTypeCursor: 0,
540
- whenToUseCursor: 0,
541
- promptCursor: 0,
542
- generationPromptCursor: 0
543
- }
544
- );
545
- const loadAgents = useCallback(async () => {
546
- setLoading(true);
547
- clearAgentCache();
548
- const abortController = new AbortController();
549
- const loadingId = Date.now();
550
- try {
551
- const result = await getActiveAgents();
552
- if (abortController.signal.aborted) {
553
- return;
554
- }
555
- setAgents(result);
556
- if (modeState.selectedAgent) {
557
- const freshSelectedAgent = result.find((a) => a.agentType === modeState.selectedAgent.agentType);
558
- if (freshSelectedAgent) {
559
- setModeState((prev) => ({ ...prev, selectedAgent: freshSelectedAgent }));
560
- }
561
- }
562
- const availableTools = [];
563
- let coreTools = [
564
- { name: "Read", description: "Read files from filesystem" },
565
- { name: "Write", description: "Write files to filesystem" },
566
- { name: "Edit", description: "Edit existing files" },
567
- { name: "MultiEdit", description: "Make multiple edits to files" },
568
- { name: "NotebookEdit", description: "Edit Jupyter notebooks" },
569
- { name: "Bash", description: "Execute bash commands" },
570
- { name: "Glob", description: "Find files matching patterns" },
571
- { name: "Grep", description: "Search file contents" },
572
- { name: "LS", description: "List directory contents" },
573
- { name: "WebFetch", description: "Fetch web content" },
574
- { name: "WebSearch", description: "Search the web" },
575
- { name: "TodoWrite", description: "Manage task lists" }
576
- ];
577
- coreTools = coreTools.filter((t) => t.name !== "Task" && t.name !== "ExitPlanMode");
578
- availableTools.push(...coreTools);
579
- try {
580
- const mcpTools = await getMCPTools();
581
- if (Array.isArray(mcpTools) && mcpTools.length > 0) {
582
- availableTools.push(...mcpTools);
583
- }
584
- } catch (error) {
585
- console.warn("Failed to load MCP tools:", error);
586
- }
587
- if (!abortController.signal.aborted) {
588
- setTools(availableTools);
589
- }
590
- } catch (error) {
591
- if (!abortController.signal.aborted) {
592
- console.error("Failed to load agents:", error);
593
- }
594
- } finally {
595
- if (!abortController.signal.aborted) {
596
- setLoading(false);
597
- }
598
- }
599
- return () => abortController.abort();
600
- }, []);
601
- useEffect(() => {
602
- let cleanup;
603
- const load = async () => {
604
- cleanup = await loadAgents();
605
- };
606
- load();
607
- return () => {
608
- if (cleanup) {
609
- cleanup();
610
- }
611
- };
612
- }, [refreshKey, loadAgents]);
613
- useInput((input, key) => {
614
- if (!key.escape) return;
615
- const changesSummary = changes.length > 0 ? `Agent changes:
616
- ${changes.join("\n")}` : void 0;
617
- const current = modeState.mode;
618
- if (current === "list-agents") {
619
- onExit(changesSummary);
620
- return;
621
- }
622
- switch (current) {
623
- case "create-location":
624
- setModeState({ mode: "list-agents", location: "all" });
625
- break;
626
- case "create-method":
627
- setModeState({ mode: "create-location", location: modeState.location });
628
- break;
629
- case "create-generate":
630
- setModeState({ mode: "create-location", location: modeState.location });
631
- break;
632
- case "create-type":
633
- setModeState({ mode: "create-generate", location: modeState.location });
634
- break;
635
- case "create-prompt":
636
- setModeState({ mode: "create-type", location: modeState.location });
637
- break;
638
- case "create-description":
639
- setModeState({ mode: "create-prompt", location: modeState.location });
640
- break;
641
- case "create-tools":
642
- setModeState({ mode: "create-description", location: modeState.location });
643
- break;
644
- case "create-model":
645
- setModeState({ mode: "create-tools", location: modeState.location });
646
- break;
647
- case "create-color":
648
- setModeState({ mode: "create-model", location: modeState.location });
649
- break;
650
- case "create-confirm":
651
- setModeState({ mode: "create-color", location: modeState.location });
652
- break;
653
- case "agent-menu":
654
- setModeState({ mode: "list-agents", location: "all" });
655
- break;
656
- case "view-agent":
657
- setModeState({ mode: "agent-menu", selectedAgent: modeState.selectedAgent });
658
- break;
659
- case "edit-agent":
660
- setModeState({ mode: "agent-menu", selectedAgent: modeState.selectedAgent });
661
- break;
662
- case "edit-tools":
663
- case "edit-model":
664
- case "edit-color":
665
- setModeState({ mode: "edit-agent", selectedAgent: modeState.selectedAgent });
666
- break;
667
- case "delete-confirm":
668
- setModeState({ mode: "agent-menu", selectedAgent: modeState.selectedAgent });
669
- break;
670
- default:
671
- setModeState({ mode: "list-agents", location: "all" });
672
- break;
673
- }
674
- });
675
- const handleAgentSelect = useCallback((agent) => {
676
- setModeState({
677
- mode: "agent-menu",
678
- location: modeState.location,
679
- selectedAgent: agent
680
- });
681
- }, [modeState]);
682
- const handleCreateNew = useCallback(() => {
683
- console.log("=== STARTING AGENT CREATION FLOW ===");
684
- console.log("Current mode state:", modeState);
685
- setCreateState({ type: "RESET" });
686
- console.log("Reset create state");
687
- setModeState({ mode: "create-location" });
688
- console.log("Set mode to create-location");
689
- console.log("=== CREATE NEW HANDLER COMPLETED ===");
690
- }, [modeState]);
691
- const handleAgentCreated = useCallback((message) => {
692
- setChanges((prev) => [...prev, message]);
693
- setRefreshKey((prev) => prev + 1);
694
- setModeState({ mode: "list-agents", location: "all" });
695
- }, []);
696
- const handleAgentDeleted = useCallback((message) => {
697
- setChanges((prev) => [...prev, message]);
698
- setRefreshKey((prev) => prev + 1);
699
- setModeState({ mode: "list-agents", location: "all" });
700
- }, []);
701
- if (loading) {
702
- return /* @__PURE__ */ React.createElement(Box, { flexDirection: "column" }, /* @__PURE__ */ React.createElement(Header, { title: "Agents" }, /* @__PURE__ */ React.createElement(Box, { marginTop: 1 }, /* @__PURE__ */ React.createElement(LoadingSpinner, { text: "Loading agents..." }))), /* @__PURE__ */ React.createElement(InstructionBar, null));
703
- }
704
- switch (modeState.mode) {
705
- case "list-agents":
706
- return /* @__PURE__ */ React.createElement(
707
- AgentListView,
708
- {
709
- location: modeState.location || "all",
710
- agents,
711
- allAgents: agents,
712
- onBack: () => onExit(),
713
- onSelect: handleAgentSelect,
714
- onCreateNew: handleCreateNew,
715
- changes
716
- }
717
- );
718
- case "create-location":
719
- return /* @__PURE__ */ React.createElement(
720
- LocationSelect,
721
- {
722
- createState,
723
- setCreateState,
724
- setModeState
725
- }
726
- );
727
- case "create-method":
728
- return /* @__PURE__ */ React.createElement(
729
- MethodSelect,
730
- {
731
- createState,
732
- setCreateState,
733
- setModeState
734
- }
735
- );
736
- case "create-generate":
737
- return /* @__PURE__ */ React.createElement(
738
- GenerateStep,
739
- {
740
- createState,
741
- setCreateState,
742
- setModeState,
743
- existingAgents: agents
744
- }
745
- );
746
- case "create-type":
747
- return /* @__PURE__ */ React.createElement(
748
- TypeStep,
749
- {
750
- createState,
751
- setCreateState,
752
- setModeState,
753
- existingAgents: agents
754
- }
755
- );
756
- case "create-description":
757
- return /* @__PURE__ */ React.createElement(
758
- DescriptionStep,
759
- {
760
- createState,
761
- setCreateState,
762
- setModeState
763
- }
764
- );
765
- case "create-tools":
766
- return /* @__PURE__ */ React.createElement(
767
- ToolsStep,
768
- {
769
- createState,
770
- setCreateState,
771
- setModeState,
772
- tools
773
- }
774
- );
775
- case "create-model":
776
- return /* @__PURE__ */ React.createElement(
777
- ModelStep,
778
- {
779
- createState,
780
- setCreateState,
781
- setModeState
782
- }
783
- );
784
- case "create-color":
785
- return /* @__PURE__ */ React.createElement(
786
- ColorStep,
787
- {
788
- createState,
789
- setCreateState,
790
- setModeState
791
- }
792
- );
793
- case "create-prompt":
794
- return /* @__PURE__ */ React.createElement(
795
- PromptStep,
796
- {
797
- createState,
798
- setCreateState,
799
- setModeState
800
- }
801
- );
802
- case "create-confirm":
803
- return /* @__PURE__ */ React.createElement(
804
- ConfirmStep,
805
- {
806
- createState,
807
- setCreateState,
808
- setModeState,
809
- tools,
810
- onAgentCreated: handleAgentCreated
811
- }
812
- );
813
- case "agent-menu":
814
- return /* @__PURE__ */ React.createElement(
815
- AgentMenu,
816
- {
817
- agent: modeState.selectedAgent,
818
- setModeState
819
- }
820
- );
821
- case "view-agent":
822
- return /* @__PURE__ */ React.createElement(
823
- ViewAgent,
824
- {
825
- agent: modeState.selectedAgent,
826
- tools,
827
- setModeState
828
- }
829
- );
830
- case "edit-agent":
831
- return /* @__PURE__ */ React.createElement(
832
- EditMenu,
833
- {
834
- agent: modeState.selectedAgent,
835
- setModeState
836
- }
837
- );
838
- case "edit-tools":
839
- return /* @__PURE__ */ React.createElement(
840
- EditToolsStep,
841
- {
842
- agent: modeState.selectedAgent,
843
- tools,
844
- setModeState,
845
- onAgentUpdated: (message, updated) => {
846
- setChanges((prev) => [...prev, message]);
847
- setRefreshKey((prev) => prev + 1);
848
- setModeState({ mode: "agent-menu", selectedAgent: updated });
849
- }
850
- }
851
- );
852
- case "edit-model":
853
- return /* @__PURE__ */ React.createElement(
854
- EditModelStep,
855
- {
856
- agent: modeState.selectedAgent,
857
- setModeState,
858
- onAgentUpdated: (message, updated) => {
859
- setChanges((prev) => [...prev, message]);
860
- setRefreshKey((prev) => prev + 1);
861
- setModeState({ mode: "agent-menu", selectedAgent: updated });
862
- }
863
- }
864
- );
865
- case "edit-color":
866
- return /* @__PURE__ */ React.createElement(
867
- EditColorStep,
868
- {
869
- agent: modeState.selectedAgent,
870
- setModeState,
871
- onAgentUpdated: (message, updated) => {
872
- setChanges((prev) => [...prev, message]);
873
- setRefreshKey((prev) => prev + 1);
874
- setModeState({ mode: "agent-menu", selectedAgent: updated });
875
- }
876
- }
877
- );
878
- case "delete-confirm":
879
- return /* @__PURE__ */ React.createElement(
880
- DeleteConfirm,
881
- {
882
- agent: modeState.selectedAgent,
883
- setModeState,
884
- onAgentDeleted: handleAgentDeleted
885
- }
886
- );
887
- default:
888
- return /* @__PURE__ */ React.createElement(Box, { flexDirection: "column" }, /* @__PURE__ */ React.createElement(Header, { title: "Agents" }, /* @__PURE__ */ React.createElement(Text, null, "Mode: ", modeState.mode, " (Not implemented yet)"), /* @__PURE__ */ React.createElement(Box, { marginTop: 1 }, /* @__PURE__ */ React.createElement(Text, null, "Press Esc to go back"))), /* @__PURE__ */ React.createElement(InstructionBar, { instructions: "Esc to go back" }));
889
- }
890
- }
891
- function AgentListView({
892
- location,
893
- agents,
894
- allAgents,
895
- onBack,
896
- onSelect,
897
- onCreateNew,
898
- changes
899
- }) {
900
- const theme = getTheme();
901
- const allAgentsList = allAgents || agents;
902
- const customAgents = allAgentsList.filter((a) => a.location !== "built-in");
903
- const builtInAgents = allAgentsList.filter((a) => a.location === "built-in");
904
- const [selectedAgent, setSelectedAgent] = useState(null);
905
- const [onCreateOption, setOnCreateOption] = useState(true);
906
- const [currentLocation, setCurrentLocation] = useState(location);
907
- const [inLocationTabs, setInLocationTabs] = useState(false);
908
- const [selectedLocationTab, setSelectedLocationTab] = useState(0);
909
- const locationTabs = [
910
- { label: "All", value: "all" },
911
- { label: "Personal", value: "user" },
912
- { label: "Project", value: "project" }
913
- ];
914
- const activeMap = useMemo(() => {
915
- const map = /* @__PURE__ */ new Map();
916
- agents.forEach((a) => map.set(a.agentType, a));
917
- return map;
918
- }, [agents]);
919
- const checkOverride = (agent) => {
920
- const active = activeMap.get(agent.agentType);
921
- const isOverridden = !!(active && active.location !== agent.location);
922
- return {
923
- isOverridden,
924
- overriddenBy: isOverridden ? active.location : null
925
- };
926
- };
927
- const renderCreateOption = () => /* @__PURE__ */ React.createElement(Box, { flexDirection: "row", gap: 1 }, /* @__PURE__ */ React.createElement(Text, { color: onCreateOption ? theme.primary : void 0 }, onCreateOption ? `${UI_ICONS.pointer} ` : " "), /* @__PURE__ */ React.createElement(Text, { bold: true, color: onCreateOption ? theme.primary : void 0 }, "\u2728 Create new agent"));
928
- const renderAgent = (agent, isBuiltIn = false) => {
929
- const isSelected = !isBuiltIn && !onCreateOption && selectedAgent?.agentType === agent.agentType && selectedAgent?.location === agent.location;
930
- const { isOverridden, overriddenBy } = checkOverride(agent);
931
- const dimmed = isBuiltIn || isOverridden;
932
- const color = !isBuiltIn && isSelected ? theme.primary : void 0;
933
- const agentModel = agent.model || null;
934
- const modelDisplay = getDisplayModelName(agentModel);
935
- return /* @__PURE__ */ React.createElement(Box, { key: `${agent.agentType}-${agent.location}`, flexDirection: "row", alignItems: "center" }, /* @__PURE__ */ React.createElement(Box, { flexDirection: "row", alignItems: "center", minWidth: 3 }, /* @__PURE__ */ React.createElement(Text, { dimColor: dimmed && !isSelected, color }, isBuiltIn ? "" : isSelected ? `${UI_ICONS.pointer} ` : " ")), /* @__PURE__ */ React.createElement(Box, { flexDirection: "row", alignItems: "center", flexGrow: 1 }, /* @__PURE__ */ React.createElement(Text, { dimColor: dimmed && !isSelected, color }, agent.agentType), /* @__PURE__ */ React.createElement(Text, { dimColor: true, color: dimmed ? void 0 : "gray" }, " \xB7 ", modelDisplay)), overriddenBy && /* @__PURE__ */ React.createElement(Box, { marginLeft: 1 }, /* @__PURE__ */ React.createElement(Text, { dimColor: !isSelected, color: isSelected ? "yellow" : "gray" }, UI_ICONS.warning, " overridden by ", overriddenBy)));
936
- };
937
- const displayAgents = useMemo(() => {
938
- if (currentLocation === "all") {
939
- return [
940
- ...customAgents.filter((a) => a.location === "user"),
941
- ...customAgents.filter((a) => a.location === "project")
942
- ];
943
- } else if (currentLocation === "user" || currentLocation === "project") {
944
- return customAgents.filter((a) => a.location === currentLocation);
945
- }
946
- return customAgents;
947
- }, [customAgents, currentLocation]);
948
- useEffect(() => {
949
- const tabIndex = locationTabs.findIndex((tab) => tab.value === currentLocation);
950
- if (tabIndex !== -1) {
951
- setSelectedLocationTab(tabIndex);
952
- }
953
- }, [currentLocation, locationTabs]);
954
- useEffect(() => {
955
- if (displayAgents.length > 0 && !selectedAgent && !onCreateOption) {
956
- setOnCreateOption(true);
957
- }
958
- }, [displayAgents.length, selectedAgent, onCreateOption]);
959
- useInput((input, key) => {
960
- if (key.escape) {
961
- if (inLocationTabs) {
962
- setInLocationTabs(false);
963
- return;
964
- }
965
- onBack();
966
- return;
967
- }
968
- if (key.return) {
969
- if (inLocationTabs) {
970
- setCurrentLocation(locationTabs[selectedLocationTab].value);
971
- setInLocationTabs(false);
972
- return;
973
- }
974
- if (onCreateOption && onCreateNew) {
975
- onCreateNew();
976
- } else if (selectedAgent) {
977
- onSelect(selectedAgent);
978
- }
979
- return;
980
- }
981
- if (key.tab) {
982
- setInLocationTabs(!inLocationTabs);
983
- return;
984
- }
985
- if (inLocationTabs) {
986
- if (key.leftArrow) {
987
- setSelectedLocationTab((prev) => prev > 0 ? prev - 1 : locationTabs.length - 1);
988
- } else if (key.rightArrow) {
989
- setSelectedLocationTab((prev) => prev < locationTabs.length - 1 ? prev + 1 : 0);
990
- }
991
- return;
992
- }
993
- if (key.upArrow || key.downArrow) {
994
- const allNavigableItems = [];
995
- if (onCreateNew) {
996
- allNavigableItems.push({ type: "create", agent: null });
997
- }
998
- displayAgents.forEach((agent) => {
999
- const { isOverridden } = checkOverride(agent);
1000
- if (!isOverridden) {
1001
- allNavigableItems.push({ type: "agent", agent });
1002
- }
1003
- });
1004
- if (allNavigableItems.length === 0) return;
1005
- if (key.upArrow) {
1006
- if (onCreateOption) {
1007
- const lastAgent = allNavigableItems[allNavigableItems.length - 1];
1008
- if (lastAgent.type === "agent") {
1009
- setSelectedAgent(lastAgent.agent);
1010
- setOnCreateOption(false);
1011
- }
1012
- } else if (selectedAgent) {
1013
- const currentIndex = allNavigableItems.findIndex(
1014
- (item) => item.type === "agent" && item.agent?.agentType === selectedAgent.agentType && item.agent?.location === selectedAgent.location
1015
- );
1016
- if (currentIndex > 0) {
1017
- const prevItem = allNavigableItems[currentIndex - 1];
1018
- if (prevItem.type === "create") {
1019
- setOnCreateOption(true);
1020
- setSelectedAgent(null);
1021
- } else {
1022
- setSelectedAgent(prevItem.agent);
1023
- }
1024
- } else {
1025
- if (onCreateNew) {
1026
- setOnCreateOption(true);
1027
- setSelectedAgent(null);
1028
- }
1029
- }
1030
- }
1031
- } else if (key.downArrow) {
1032
- if (onCreateOption) {
1033
- const firstAgent = allNavigableItems.find((item) => item.type === "agent");
1034
- if (firstAgent) {
1035
- setSelectedAgent(firstAgent.agent);
1036
- setOnCreateOption(false);
1037
- }
1038
- } else if (selectedAgent) {
1039
- const currentIndex = allNavigableItems.findIndex(
1040
- (item) => item.type === "agent" && item.agent?.agentType === selectedAgent.agentType && item.agent?.location === selectedAgent.location
1041
- );
1042
- if (currentIndex < allNavigableItems.length - 1) {
1043
- const nextItem = allNavigableItems[currentIndex + 1];
1044
- if (nextItem.type === "agent") {
1045
- setSelectedAgent(nextItem.agent);
1046
- }
1047
- } else {
1048
- if (onCreateNew) {
1049
- setOnCreateOption(true);
1050
- setSelectedAgent(null);
1051
- }
1052
- }
1053
- }
1054
- }
1055
- }
1056
- });
1057
- const EmptyStateInput = () => {
1058
- useInput((input, key) => {
1059
- if (key.escape) {
1060
- onBack();
1061
- return;
1062
- }
1063
- if (key.return && onCreateNew) {
1064
- onCreateNew();
1065
- return;
1066
- }
1067
- });
1068
- return null;
1069
- };
1070
- if (!agents.length || currentLocation !== "built-in" && !customAgents.length) {
1071
- return /* @__PURE__ */ React.createElement(Box, { flexDirection: "column" }, /* @__PURE__ */ React.createElement(EmptyStateInput, null), /* @__PURE__ */ React.createElement(Header, { title: "\u{1F916} Agents", subtitle: "" }, onCreateNew && /* @__PURE__ */ React.createElement(Box, { marginY: 1 }, renderCreateOption()), /* @__PURE__ */ React.createElement(Box, { marginTop: 1, flexDirection: "column" }, /* @__PURE__ */ React.createElement(Box, { marginBottom: 1 }, /* @__PURE__ */ React.createElement(Text, { bold: true, color: theme.primary }, "\u{1F4AD} What are agents?")), /* @__PURE__ */ React.createElement(Text, null, "Specialized AI assistants that Minto can delegate to for specific tasks, compatible with Claude Code `.claude` agent packs."), /* @__PURE__ */ React.createElement(Text, null, "Each agent has its own context, prompt, and tools."), /* @__PURE__ */ React.createElement(Box, { marginTop: 1, marginBottom: 1 }, /* @__PURE__ */ React.createElement(Text, { bold: true, color: theme.primary }, "\u{1F4A1} Popular agent ideas:")), /* @__PURE__ */ React.createElement(Box, { paddingLeft: 2, flexDirection: "column" }, /* @__PURE__ */ React.createElement(Text, null, "\u2022 \u{1F50D} Code Reviewer - Reviews PRs for best practices"), /* @__PURE__ */ React.createElement(Text, null, "\u2022 \u{1F512} Security Auditor - Finds vulnerabilities"), /* @__PURE__ */ React.createElement(Text, null, "\u2022 \u26A1 Performance Optimizer - Improves code speed"), /* @__PURE__ */ React.createElement(Text, null, "\u2022 \u{1F9D1}\u200D\u{1F4BC} Tech Lead - Makes architecture decisions"), /* @__PURE__ */ React.createElement(Text, null, "\u2022 \u{1F3A8} UX Expert - Improves user experience"))), currentLocation !== "built-in" && builtInAgents.length > 0 && /* @__PURE__ */ React.createElement(React.Fragment, null, /* @__PURE__ */ React.createElement(Box, { marginTop: 1 }, /* @__PURE__ */ React.createElement(Text, null, UI_ICONS.separator.repeat(40))), /* @__PURE__ */ React.createElement(Box, { flexDirection: "column", marginBottom: 1, paddingLeft: 2 }, /* @__PURE__ */ React.createElement(Text, { bold: true, color: theme.secondary }, "Built-in (always available):"), builtInAgents.map((a) => renderAgent(a, true))))), /* @__PURE__ */ React.createElement(InstructionBar, { instructions: "Press Enter to create new agent \xB7 Esc to go back" }));
1072
- }
1073
- return /* @__PURE__ */ React.createElement(Box, { flexDirection: "column" }, /* @__PURE__ */ React.createElement(Header, { title: "\u{1F916} Agents", subtitle: "" }, changes.length > 0 && /* @__PURE__ */ React.createElement(Box, { marginTop: 1 }, /* @__PURE__ */ React.createElement(Text, { dimColor: true }, changes[changes.length - 1])), /* @__PURE__ */ React.createElement(Box, { marginTop: 1, flexDirection: "column" }, /* @__PURE__ */ React.createElement(Box, { flexDirection: "row", gap: 2 }, locationTabs.map((tab, idx) => {
1074
- const isActive = currentLocation === tab.value;
1075
- const isSelected = inLocationTabs && idx === selectedLocationTab;
1076
- return /* @__PURE__ */ React.createElement(Box, { key: tab.value, flexDirection: "row" }, /* @__PURE__ */ React.createElement(
1077
- Text,
1078
- {
1079
- color: isSelected || isActive ? theme.primary : void 0,
1080
- bold: isActive,
1081
- dimColor: !isActive && !isSelected
1082
- },
1083
- isSelected ? "\u25B6 " : isActive ? "\u25C9 " : "\u25CB ",
1084
- tab.label
1085
- ), idx < locationTabs.length - 1 && /* @__PURE__ */ React.createElement(Text, { dimColor: true }, " | "));
1086
- })), /* @__PURE__ */ React.createElement(Box, { marginTop: 0 }, /* @__PURE__ */ React.createElement(Text, { dimColor: true }, currentLocation === "all" ? "Showing all agents" : currentLocation === "user" ? "Personal agents (~/.claude/agents)" : "Project agents (.claude/agents)"))), /* @__PURE__ */ React.createElement(Box, { flexDirection: "column", marginTop: 1 }, onCreateNew && /* @__PURE__ */ React.createElement(Box, { marginBottom: 1 }, renderCreateOption()), currentLocation === "all" ? /* @__PURE__ */ React.createElement(React.Fragment, null, customAgents.filter((a) => a.location === "user").length > 0 && /* @__PURE__ */ React.createElement(React.Fragment, null, /* @__PURE__ */ React.createElement(Text, { bold: true, color: theme.secondary }, "Personal:"), customAgents.filter((a) => a.location === "user").map((a) => renderAgent(a))), customAgents.filter((a) => a.location === "project").length > 0 && /* @__PURE__ */ React.createElement(React.Fragment, null, /* @__PURE__ */ React.createElement(Box, { marginTop: customAgents.filter((a) => a.location === "user").length > 0 ? 1 : 0 }, /* @__PURE__ */ React.createElement(Text, { bold: true, color: theme.secondary }, "Project:")), customAgents.filter((a) => a.location === "project").map((a) => renderAgent(a))), builtInAgents.length > 0 && /* @__PURE__ */ React.createElement(React.Fragment, null, /* @__PURE__ */ React.createElement(Box, { marginTop: customAgents.length > 0 ? 1 : 0 }, /* @__PURE__ */ React.createElement(Text, null, UI_ICONS.separator.repeat(40))), /* @__PURE__ */ React.createElement(Box, { flexDirection: "column" }, /* @__PURE__ */ React.createElement(Text, { bold: true, color: theme.secondary }, "Built-in:"), builtInAgents.map((a) => renderAgent(a, true))))) : /* @__PURE__ */ React.createElement(React.Fragment, null, displayAgents.map((a) => renderAgent(a)), currentLocation !== "built-in" && builtInAgents.length > 0 && /* @__PURE__ */ React.createElement(React.Fragment, null, /* @__PURE__ */ React.createElement(Box, { marginTop: 1 }, /* @__PURE__ */ React.createElement(Text, null, UI_ICONS.separator.repeat(40))), /* @__PURE__ */ React.createElement(Box, { flexDirection: "column" }, /* @__PURE__ */ React.createElement(Text, { bold: true, color: theme.secondary }, "Built-in:"), builtInAgents.map((a) => renderAgent(a, true))))))), /* @__PURE__ */ React.createElement(
1087
- InstructionBar,
1088
- {
1089
- instructions: inLocationTabs ? "\u2190\u2192 Switch tabs \u2022 Enter Select \u2022 Tab Exit tabs" : "\u2191\u2193 Navigate \u2022 Tab Location \u2022 Enter Select"
1090
- }
1091
- ));
1092
- }
1093
- function GenerateStep({ createState, setCreateState, setModeState, existingAgents }) {
1094
- const handleSubmit = async () => {
1095
- if (createState.generationPrompt.trim()) {
1096
- setCreateState({ type: "SET_IS_GENERATING", value: true });
1097
- setCreateState({ type: "SET_ERROR", value: null });
1098
- try {
1099
- const generated = await generateAgentWithClaude(createState.generationPrompt);
1100
- const validation = validateAgentType(generated.identifier, existingAgents);
1101
- let finalIdentifier = generated.identifier;
1102
- if (!validation.isValid) {
1103
- let counter = 1;
1104
- while (true) {
1105
- const testId = `${generated.identifier}-${counter}`;
1106
- const testValidation = validateAgentType(testId, existingAgents);
1107
- if (testValidation.isValid) {
1108
- finalIdentifier = testId;
1109
- break;
1110
- }
1111
- counter++;
1112
- if (counter > 10) {
1113
- finalIdentifier = `custom-agent-${Date.now()}`;
1114
- break;
1115
- }
1116
- }
1117
- }
1118
- setCreateState({ type: "SET_AGENT_TYPE", value: finalIdentifier });
1119
- setCreateState({ type: "SET_WHEN_TO_USE", value: generated.whenToUse });
1120
- setCreateState({ type: "SET_SYSTEM_PROMPT", value: generated.systemPrompt });
1121
- setCreateState({ type: "SET_WAS_GENERATED", value: true });
1122
- setCreateState({ type: "SET_IS_GENERATING", value: false });
1123
- setModeState({ mode: "create-tools", location: createState.location });
1124
- } catch (error) {
1125
- console.error("Generation failed:", error);
1126
- setCreateState({ type: "SET_ERROR", value: "Failed to generate agent. Please try again or use manual configuration." });
1127
- setCreateState({ type: "SET_IS_GENERATING", value: false });
1128
- }
1129
- }
1130
- };
1131
- return /* @__PURE__ */ React.createElement(Box, { flexDirection: "column" }, /* @__PURE__ */ React.createElement(Header, { title: "\u2728 New Agent", subtitle: "What should it do?", step: 2, totalSteps: 8 }, /* @__PURE__ */ React.createElement(Box, { marginTop: 1 }, createState.isGenerating ? /* @__PURE__ */ React.createElement(Box, { flexDirection: "column" }, /* @__PURE__ */ React.createElement(Text, { dimColor: true }, createState.generationPrompt), /* @__PURE__ */ React.createElement(Box, { marginTop: 1 }, /* @__PURE__ */ React.createElement(LoadingSpinner, { text: "Generating agent configuration..." }))) : /* @__PURE__ */ React.createElement(
1132
- MultilineTextInput,
1133
- {
1134
- value: createState.generationPrompt,
1135
- onChange: (value) => setCreateState({ type: "SET_GENERATION_PROMPT", value }),
1136
- placeholder: "An expert that reviews pull requests for best practices, security issues, and suggests improvements...",
1137
- onSubmit: handleSubmit,
1138
- error: createState.error,
1139
- rows: 3
1140
- }
1141
- ))), /* @__PURE__ */ React.createElement(InstructionBar, null));
1142
- }
1143
- function TypeStep({ createState, setCreateState, setModeState, existingAgents }) {
1144
- const handleSubmit = () => {
1145
- const validation = validateAgentType(createState.agentType, existingAgents);
1146
- if (validation.isValid) {
1147
- setModeState({ mode: "create-prompt", location: createState.location });
1148
- } else {
1149
- setCreateState({ type: "SET_ERROR", value: validation.errors[0] });
1150
- }
1151
- };
1152
- return /* @__PURE__ */ React.createElement(Box, { flexDirection: "column" }, /* @__PURE__ */ React.createElement(Header, { title: "Create new agent", subtitle: "Enter agent identifier", step: 3, totalSteps: 8 }, /* @__PURE__ */ React.createElement(Box, { marginTop: 1 }, /* @__PURE__ */ React.createElement(
1153
- InkTextInput,
1154
- {
1155
- value: createState.agentType,
1156
- onChange: (value) => setCreateState({ type: "SET_AGENT_TYPE", value }),
1157
- placeholder: "e.g. code-reviewer, tech-lead",
1158
- onSubmit: handleSubmit
1159
- }
1160
- ), createState.error && /* @__PURE__ */ React.createElement(Box, { marginTop: 1 }, /* @__PURE__ */ React.createElement(Text, { color: "red" }, "\u26A0 ", createState.error)))), /* @__PURE__ */ React.createElement(InstructionBar, null));
1161
- }
1162
- function DescriptionStep({ createState, setCreateState, setModeState }) {
1163
- const handleSubmit = () => {
1164
- if (createState.whenToUse.trim()) {
1165
- setModeState({ mode: "create-tools", location: createState.location });
1166
- }
1167
- };
1168
- return /* @__PURE__ */ React.createElement(Box, { flexDirection: "column" }, /* @__PURE__ */ React.createElement(Header, { title: "Create new agent", subtitle: "Describe when to use this agent", step: 5, totalSteps: 8 }, /* @__PURE__ */ React.createElement(Box, { marginTop: 1 }, /* @__PURE__ */ React.createElement(
1169
- MultilineTextInput,
1170
- {
1171
- value: createState.whenToUse,
1172
- onChange: (value) => setCreateState({ type: "SET_WHEN_TO_USE", value }),
1173
- placeholder: "Use this agent when you need to review code for best practices, security issues...",
1174
- onSubmit: handleSubmit,
1175
- error: createState.error,
1176
- rows: 4
1177
- }
1178
- ))), /* @__PURE__ */ React.createElement(InstructionBar, null));
1179
- }
1180
- function ToolsStep({ createState, setCreateState, setModeState, tools }) {
1181
- const [selectedIndex, setSelectedIndex] = useState(0);
1182
- const initialSelection = createState.selectedTools.length > 0 ? new Set(createState.selectedTools) : new Set(tools.map((t) => t.name));
1183
- const [selectedTools, setSelectedTools] = useState(initialSelection);
1184
- const [showAdvanced, setShowAdvanced] = useState(false);
1185
- const [selectedCategory, setSelectedCategory] = useState("all");
1186
- const categorizedTools = useMemo(() => {
1187
- const categories = {
1188
- read: [],
1189
- edit: [],
1190
- execution: [],
1191
- web: [],
1192
- mcp: [],
1193
- other: []
1194
- };
1195
- tools.forEach((tool) => {
1196
- let categorized = false;
1197
- if (tool.name.startsWith("mcp__")) {
1198
- categories.mcp.push(tool);
1199
- categorized = true;
1200
- } else {
1201
- for (const [category, toolNames] of Object.entries(TOOL_CATEGORIES)) {
1202
- if (Array.isArray(toolNames) && toolNames.includes(tool.name)) {
1203
- categories[category]?.push(tool);
1204
- categorized = true;
1205
- break;
1206
- }
1207
- }
1208
- }
1209
- if (!categorized) {
1210
- categories.other.push(tool);
1211
- }
1212
- });
1213
- return categories;
1214
- }, [tools]);
1215
- const displayTools = useMemo(() => {
1216
- if (selectedCategory === "all") {
1217
- return tools;
1218
- }
1219
- return categorizedTools[selectedCategory] || [];
1220
- }, [selectedCategory, tools, categorizedTools]);
1221
- const allSelected = selectedTools.size === tools.length && tools.length > 0;
1222
- const categoryOptions = [
1223
- { id: "all", label: `All (${tools.length})` },
1224
- { id: "read", label: `Read (${categorizedTools.read.length})` },
1225
- { id: "edit", label: `Edit (${categorizedTools.edit.length})` },
1226
- { id: "execution", label: `Execution (${categorizedTools.execution.length})` },
1227
- { id: "web", label: `Web (${categorizedTools.web.length})` },
1228
- { id: "mcp", label: `MCP (${categorizedTools.mcp.length})` },
1229
- { id: "other", label: `Other (${categorizedTools.other.length})` }
1230
- ].filter((cat) => cat.id === "all" || categorizedTools[cat.id]?.length > 0);
1231
- const readSelected = categorizedTools.read.every((tool) => selectedTools.has(tool.name));
1232
- const editSelected = categorizedTools.edit.every((tool) => selectedTools.has(tool.name));
1233
- const execSelected = categorizedTools.execution.every((tool) => selectedTools.has(tool.name));
1234
- const webSelected = categorizedTools.web.every((tool) => selectedTools.has(tool.name));
1235
- const options = [
1236
- { id: "continue", label: "Save", isContinue: true },
1237
- { id: "separator1", label: "\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500", isSeparator: true },
1238
- { id: "all", label: `${allSelected ? UI_ICONS.checkboxOn : UI_ICONS.checkboxOff} All tools`, isAll: true },
1239
- { id: "read", label: `${readSelected ? UI_ICONS.checkboxOn : UI_ICONS.checkboxOff} Read-only tools`, isCategory: true },
1240
- { id: "edit", label: `${editSelected ? UI_ICONS.checkboxOn : UI_ICONS.checkboxOff} Edit tools`, isCategory: true },
1241
- { id: "execution", label: `${execSelected ? UI_ICONS.checkboxOn : UI_ICONS.checkboxOff} Execution tools`, isCategory: true },
1242
- { id: "separator2", label: "\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500", isSeparator: true },
1243
- { id: "advanced", label: `[ ${showAdvanced ? "Hide" : "Show"} advanced options ]`, isAdvancedToggle: true },
1244
- ...showAdvanced ? displayTools.map((tool) => ({
1245
- id: tool.name,
1246
- label: `${selectedTools.has(tool.name) ? UI_ICONS.checkboxOn : UI_ICONS.checkboxOff} ${tool.name}`,
1247
- isTool: true
1248
- })) : []
1249
- ];
1250
- const handleSelect = () => {
1251
- const option = options[selectedIndex];
1252
- if (!option) return;
1253
- if (option.isSeparator) return;
1254
- if (option.isContinue) {
1255
- const result = allSelected ? ["*"] : Array.from(selectedTools);
1256
- setCreateState({ type: "SET_SELECTED_TOOLS", value: result });
1257
- setModeState({ mode: "create-model", location: createState.location });
1258
- } else if (option.isAdvancedToggle) {
1259
- setShowAdvanced(!showAdvanced);
1260
- } else if (option.isAll) {
1261
- if (allSelected) {
1262
- setSelectedTools(/* @__PURE__ */ new Set());
1263
- } else {
1264
- setSelectedTools(new Set(tools.map((t) => t.name)));
1265
- }
1266
- } else if (option.isCategory) {
1267
- const categoryName = option.id;
1268
- const categoryTools = categorizedTools[categoryName] || [];
1269
- const newSelected = new Set(selectedTools);
1270
- const categorySelected = categoryTools.every((tool) => selectedTools.has(tool.name));
1271
- if (categorySelected) {
1272
- categoryTools.forEach((tool) => newSelected.delete(tool.name));
1273
- } else {
1274
- categoryTools.forEach((tool) => newSelected.add(tool.name));
1275
- }
1276
- setSelectedTools(newSelected);
1277
- } else if (option.isTool) {
1278
- const newSelected = new Set(selectedTools);
1279
- if (newSelected.has(option.id)) {
1280
- newSelected.delete(option.id);
1281
- } else {
1282
- newSelected.add(option.id);
1283
- }
1284
- setSelectedTools(newSelected);
1285
- }
1286
- };
1287
- useInput((input, key) => {
1288
- if (key.return) {
1289
- handleSelect();
1290
- } else if (key.upArrow) {
1291
- setSelectedIndex((prev) => {
1292
- let newIndex = prev > 0 ? prev - 1 : options.length - 1;
1293
- while (options[newIndex] && options[newIndex].isSeparator) {
1294
- newIndex = newIndex > 0 ? newIndex - 1 : options.length - 1;
1295
- }
1296
- return newIndex;
1297
- });
1298
- } else if (key.downArrow) {
1299
- setSelectedIndex((prev) => {
1300
- let newIndex = prev < options.length - 1 ? prev + 1 : 0;
1301
- while (options[newIndex] && options[newIndex].isSeparator) {
1302
- newIndex = newIndex < options.length - 1 ? newIndex + 1 : 0;
1303
- }
1304
- return newIndex;
1305
- });
1306
- }
1307
- });
1308
- return /* @__PURE__ */ React.createElement(Box, { flexDirection: "column" }, /* @__PURE__ */ React.createElement(Header, { title: "\u{1F527} Tool Permissions", subtitle: "", step: 3, totalSteps: 5 }, /* @__PURE__ */ React.createElement(Box, { flexDirection: "column", marginTop: 1 }, options.map((option, idx) => {
1309
- const isSelected = idx === selectedIndex;
1310
- const isContinue = option.isContinue;
1311
- const isAdvancedToggle = option.isAdvancedToggle;
1312
- const isSeparator = option.isSeparator;
1313
- return /* @__PURE__ */ React.createElement(Box, { key: option.id }, /* @__PURE__ */ React.createElement(
1314
- Text,
1315
- {
1316
- color: isSelected && !isSeparator ? "cyan" : isSeparator ? "gray" : void 0,
1317
- bold: isContinue,
1318
- dimColor: isSeparator
1319
- },
1320
- isSeparator ? option.label : `${isSelected ? `${UI_ICONS.pointer} ` : " "}${isContinue || isAdvancedToggle ? `${option.label}` : option.label}`
1321
- ), option.isTool && isSelected && tools.find((t) => t.name === option.id)?.description && /* @__PURE__ */ React.createElement(Box, { marginLeft: 4 }, /* @__PURE__ */ React.createElement(Text, { dimColor: true }, tools.find((t) => t.name === option.id)?.description)));
1322
- }), /* @__PURE__ */ React.createElement(Box, { marginTop: 1 }, /* @__PURE__ */ React.createElement(Text, { dimColor: true }, allSelected ? "All tools selected" : `${selectedTools.size} of ${tools.length} tools selected`), selectedCategory !== "all" && /* @__PURE__ */ React.createElement(Text, { dimColor: true }, "Filtering: ", selectedCategory, " tools")))), /* @__PURE__ */ React.createElement(InstructionBar, { instructions: "\u2191\u2193 Navigate \u2022 Enter Toggle \u2022 Esc Back" }));
1323
- }
1324
- function ModelStep({ createState, setCreateState, setModeState }) {
1325
- const theme = getTheme();
1326
- const manager = getModelManager();
1327
- const profiles = manager.getActiveModelProfiles();
1328
- const groupedModels = profiles.reduce((acc, profile) => {
1329
- const provider = profile.provider || "Default";
1330
- if (!acc[provider]) acc[provider] = [];
1331
- acc[provider].push(profile);
1332
- return acc;
1333
- }, {});
1334
- const modelOptions = [
1335
- { id: null, name: "\u25C8 Inherit from parent", provider: "System", modelName: "default" },
1336
- ...Object.entries(groupedModels).flatMap(
1337
- ([provider, models]) => models.map((p) => ({
1338
- id: p.modelName,
1339
- name: p.name,
1340
- provider,
1341
- modelName: p.modelName
1342
- }))
1343
- )
1344
- ];
1345
- const [selectedIndex, setSelectedIndex] = useState(() => {
1346
- const idx = modelOptions.findIndex((m) => m.id === createState.selectedModel);
1347
- return idx >= 0 ? idx : 0;
1348
- });
1349
- const handleSelect = (modelId) => {
1350
- setCreateState({ type: "SET_SELECTED_MODEL", value: modelId });
1351
- setModeState({ mode: "create-color", location: createState.location });
1352
- };
1353
- useInput((input, key) => {
1354
- if (key.return) {
1355
- handleSelect(modelOptions[selectedIndex].id);
1356
- } else if (key.upArrow) {
1357
- setSelectedIndex((prev) => prev > 0 ? prev - 1 : modelOptions.length - 1);
1358
- } else if (key.downArrow) {
1359
- setSelectedIndex((prev) => prev < modelOptions.length - 1 ? prev + 1 : 0);
1360
- }
1361
- });
1362
- return /* @__PURE__ */ React.createElement(Box, { flexDirection: "column" }, /* @__PURE__ */ React.createElement(Header, { title: "\u{1F916} Select Model", subtitle: "", step: 4, totalSteps: 5 }, /* @__PURE__ */ React.createElement(Box, { marginTop: 1, flexDirection: "column" }, modelOptions.map((model, index) => {
1363
- const isSelected = index === selectedIndex;
1364
- const isInherit = model.id === null;
1365
- return /* @__PURE__ */ React.createElement(Box, { key: model.id || "inherit", marginBottom: 0 }, /* @__PURE__ */ React.createElement(Box, { flexDirection: "row", gap: 1 }, /* @__PURE__ */ React.createElement(Text, { color: isSelected ? theme.primary : void 0 }, isSelected ? UI_ICONS.pointer : " "), /* @__PURE__ */ React.createElement(Box, { flexDirection: "column", flexGrow: 1 }, /* @__PURE__ */ React.createElement(Box, { flexDirection: "row", gap: 1 }, /* @__PURE__ */ React.createElement(
1366
- Text,
1367
- {
1368
- bold: isInherit,
1369
- color: isSelected ? theme.primary : void 0
1370
- },
1371
- model.name
1372
- ), !isInherit && /* @__PURE__ */ React.createElement(Text, { dimColor: true }, model.provider, " \u2022 ", model.modelName)))));
1373
- }))), /* @__PURE__ */ React.createElement(InstructionBar, { instructions: "\u2191\u2193 Navigate \u2022 Enter Select" }));
1374
- }
1375
- function ColorStep({ createState, setCreateState, setModeState }) {
1376
- const theme = getTheme();
1377
- const [selectedIndex, setSelectedIndex] = useState(0);
1378
- const colors = [
1379
- { label: "Default", value: null, displayColor: null },
1380
- { label: "Yellow", value: "yellow", displayColor: "yellow" },
1381
- { label: "Blue", value: "blue", displayColor: "blue" },
1382
- { label: "Magenta", value: "magenta", displayColor: "magenta" },
1383
- { label: "Cyan", value: "cyan", displayColor: "cyan" },
1384
- { label: "Gray", value: "gray", displayColor: "gray" },
1385
- { label: "White", value: "white", displayColor: "white" }
1386
- ];
1387
- const handleSelect = (value) => {
1388
- setCreateState({ type: "SET_SELECTED_COLOR", value });
1389
- setModeState({ mode: "create-confirm", location: createState.location });
1390
- };
1391
- useInput((input, key) => {
1392
- if (key.return) {
1393
- handleSelect(colors[selectedIndex].value);
1394
- } else if (key.upArrow) {
1395
- setSelectedIndex((prev) => prev > 0 ? prev - 1 : colors.length - 1);
1396
- } else if (key.downArrow) {
1397
- setSelectedIndex((prev) => prev < colors.length - 1 ? prev + 1 : 0);
1398
- }
1399
- });
1400
- return /* @__PURE__ */ React.createElement(Box, { flexDirection: "column" }, /* @__PURE__ */ React.createElement(Header, { title: "\u{1F3A8} Color Theme", subtitle: "", step: 5, totalSteps: 5 }, /* @__PURE__ */ React.createElement(Box, { marginTop: 1, flexDirection: "column" }, /* @__PURE__ */ React.createElement(Box, { marginBottom: 1 }, /* @__PURE__ */ React.createElement(Text, { dimColor: true }, "Choose how your agent appears in the list:")), colors.map((color, idx) => {
1401
- const isSelected = idx === selectedIndex;
1402
- return /* @__PURE__ */ React.createElement(Box, { key: idx, flexDirection: "row" }, /* @__PURE__ */ React.createElement(Text, { color: isSelected ? theme.primary : void 0 }, isSelected ? "\u276F " : " "), /* @__PURE__ */ React.createElement(Box, { minWidth: 12 }, /* @__PURE__ */ React.createElement(Text, { bold: isSelected, color: color.displayColor || void 0 }, color.label)));
1403
- }), /* @__PURE__ */ React.createElement(Box, { marginTop: 1, paddingLeft: 2 }, /* @__PURE__ */ React.createElement(Text, null, "Preview: "), /* @__PURE__ */ React.createElement(Text, { bold: true, color: colors[selectedIndex].displayColor || void 0 }, createState.agentType || "your-agent")))), /* @__PURE__ */ React.createElement(InstructionBar, { instructions: "\u2191\u2193 Navigate \u2022 Enter Select" }));
1404
- }
1405
- function PromptStep({ createState, setCreateState, setModeState }) {
1406
- const handleSubmit = () => {
1407
- if (createState.systemPrompt.trim()) {
1408
- setModeState({ mode: "create-description", location: createState.location });
1409
- }
1410
- };
1411
- return /* @__PURE__ */ React.createElement(Box, { flexDirection: "column" }, /* @__PURE__ */ React.createElement(Header, { title: "Create new agent", subtitle: "System prompt", step: 4, totalSteps: 8 }, /* @__PURE__ */ React.createElement(Box, { marginTop: 1 }, /* @__PURE__ */ React.createElement(
1412
- MultilineTextInput,
1413
- {
1414
- value: createState.systemPrompt,
1415
- onChange: (value) => setCreateState({ type: "SET_SYSTEM_PROMPT", value }),
1416
- placeholder: "You are a helpful assistant that specializes in...",
1417
- onSubmit: handleSubmit,
1418
- error: createState.error,
1419
- rows: 5
1420
- }
1421
- ))), /* @__PURE__ */ React.createElement(InstructionBar, null));
1422
- }
1423
- function ConfirmStep({ createState, setCreateState, setModeState, tools, onAgentCreated }) {
1424
- const [isCreating, setIsCreating] = useState(false);
1425
- const theme = getTheme();
1426
- const handleConfirm = async () => {
1427
- setIsCreating(true);
1428
- try {
1429
- await saveAgent(
1430
- createState.location,
1431
- createState.agentType,
1432
- createState.whenToUse,
1433
- createState.selectedTools,
1434
- createState.systemPrompt,
1435
- createState.selectedModel,
1436
- createState.selectedColor || void 0
1437
- );
1438
- onAgentCreated(`Created agent: ${createState.agentType}`);
1439
- } catch (error) {
1440
- setCreateState({ type: "SET_ERROR", value: error.message });
1441
- setIsCreating(false);
1442
- }
1443
- };
1444
- const validation = validateAgentConfig(createState);
1445
- const toolNames = createState.selectedTools.includes("*") ? "All tools" : createState.selectedTools.length > 0 ? createState.selectedTools.join(", ") : "No tools";
1446
- const handleEditInEditor = async () => {
1447
- const filePath = createState.location === "project" ? path.join(process.cwd(), ".claude", "agents", `${createState.agentType}.md`) : path.join(os.homedir(), ".claude", "agents", `${createState.agentType}.md`);
1448
- try {
1449
- await saveAgent(
1450
- createState.location,
1451
- createState.agentType,
1452
- createState.whenToUse,
1453
- createState.selectedTools,
1454
- createState.systemPrompt,
1455
- createState.selectedModel,
1456
- createState.selectedColor || void 0
1457
- );
1458
- const command = process.platform === "win32" ? "start" : process.platform === "darwin" ? "open" : "xdg-open";
1459
- await execAsync(`${command} "${filePath}"`);
1460
- onAgentCreated(`Created agent: ${createState.agentType}`);
1461
- } catch (error) {
1462
- setCreateState({ type: "SET_ERROR", value: error.message });
1463
- }
1464
- };
1465
- useInput((input, key) => {
1466
- if (isCreating) return;
1467
- if ((key.return || input === "s") && !isCreating) {
1468
- handleConfirm();
1469
- } else if (input === "e") {
1470
- handleEditInEditor();
1471
- } else if (key.escape) {
1472
- setModeState({ mode: "create-color", location: createState.location });
1473
- }
1474
- });
1475
- return /* @__PURE__ */ React.createElement(Box, { flexDirection: "column" }, /* @__PURE__ */ React.createElement(Header, { title: "\u2705 Review & Create", subtitle: "" }, /* @__PURE__ */ React.createElement(Box, { flexDirection: "column", marginTop: 1 }, /* @__PURE__ */ React.createElement(Box, { marginBottom: 1 }, /* @__PURE__ */ React.createElement(Text, { bold: true, color: theme.primary }, "\u{1F4CB} Configuration")), /* @__PURE__ */ React.createElement(Box, { flexDirection: "column", gap: 0 }, /* @__PURE__ */ React.createElement(Text, null, "\u2022 ", /* @__PURE__ */ React.createElement(Text, { bold: true }, "Agent ID:"), " ", createState.agentType), /* @__PURE__ */ React.createElement(Text, null, "\u2022 ", /* @__PURE__ */ React.createElement(Text, { bold: true }, "Location:"), " ", createState.location === "project" ? "Project" : "Personal"), /* @__PURE__ */ React.createElement(Text, null, "\u2022 ", /* @__PURE__ */ React.createElement(Text, { bold: true }, "Tools:"), " ", toolNames.length > 50 ? toolNames.slice(0, 50) + "..." : toolNames), /* @__PURE__ */ React.createElement(Text, null, "\u2022 ", /* @__PURE__ */ React.createElement(Text, { bold: true }, "Model:"), " ", getDisplayModelName(createState.selectedModel)), createState.selectedColor && /* @__PURE__ */ React.createElement(Text, null, "\u2022 ", /* @__PURE__ */ React.createElement(Text, { bold: true }, "Color:"), " ", /* @__PURE__ */ React.createElement(Text, { color: createState.selectedColor }, createState.selectedColor))), /* @__PURE__ */ React.createElement(Box, { marginTop: 1, marginBottom: 1 }, /* @__PURE__ */ React.createElement(Text, { bold: true, color: theme.primary }, "\u{1F4DD} Purpose")), /* @__PURE__ */ React.createElement(Box, { paddingLeft: 1 }, /* @__PURE__ */ React.createElement(Text, null, createState.whenToUse)), validation.warnings.length > 0 && /* @__PURE__ */ React.createElement(Box, { marginTop: 1 }, /* @__PURE__ */ React.createElement(Text, null, /* @__PURE__ */ React.createElement(Text, { bold: true }, "Warnings:")), validation.warnings.map((warning, idx) => /* @__PURE__ */ React.createElement(Fragment, { key: idx }, /* @__PURE__ */ React.createElement(Text, { color: theme.warning }, " \u2022 ", warning)))), createState.error && /* @__PURE__ */ React.createElement(Box, { marginTop: 1 }, /* @__PURE__ */ React.createElement(Text, { color: theme.error }, "\u2717 ", createState.error)), /* @__PURE__ */ React.createElement(Box, { marginTop: 2 }, isCreating ? /* @__PURE__ */ React.createElement(LoadingSpinner, { text: "Creating agent..." }) : null))), /* @__PURE__ */ React.createElement(InstructionBar, { instructions: "Enter Save \u2022 E Edit \u2022 Esc Back" }));
1476
- }
1477
- function LocationSelect({ createState, setCreateState, setModeState }) {
1478
- const theme = getTheme();
1479
- const [selectedIndex, setSelectedIndex] = useState(0);
1480
- const options = [
1481
- { label: "\u{1F4C1} Project", value: "project", desc: ".claude/agents/" },
1482
- { label: "\u{1F3E0} Personal", value: "user", desc: "~/.claude/agents/" }
1483
- ];
1484
- const handleChange = (value) => {
1485
- setCreateState({ type: "SET_LOCATION", value });
1486
- setCreateState({ type: "SET_METHOD", value: "generate" });
1487
- setModeState({ mode: "create-generate", location: value });
1488
- };
1489
- const handleCancel = () => {
1490
- setModeState({ mode: "list-agents", location: "all" });
1491
- };
1492
- useInput((input, key) => {
1493
- if (key.escape) {
1494
- handleCancel();
1495
- } else if (key.return) {
1496
- handleChange(options[selectedIndex].value);
1497
- } else if (key.upArrow) {
1498
- setSelectedIndex((prev) => prev > 0 ? prev - 1 : options.length - 1);
1499
- } else if (key.downArrow) {
1500
- setSelectedIndex((prev) => prev < options.length - 1 ? prev + 1 : 0);
1501
- }
1502
- });
1503
- return /* @__PURE__ */ React.createElement(Box, { flexDirection: "column" }, /* @__PURE__ */ React.createElement(Header, { title: "\u{1F4E6} Save Location", subtitle: "", step: 1, totalSteps: 5 }, /* @__PURE__ */ React.createElement(Box, { marginTop: 1, flexDirection: "column" }, options.map((opt, idx) => /* @__PURE__ */ React.createElement(Box, { key: opt.value, flexDirection: "column", marginBottom: 1 }, /* @__PURE__ */ React.createElement(Text, { color: idx === selectedIndex ? theme.primary : void 0 }, idx === selectedIndex ? "\u276F " : " ", opt.label), /* @__PURE__ */ React.createElement(Box, { marginLeft: 3 }, /* @__PURE__ */ React.createElement(Text, { dimColor: true }, opt.desc)))))), /* @__PURE__ */ React.createElement(InstructionBar, { instructions: "\u2191\u2193 Navigate \u2022 Enter Select" }));
1504
- }
1505
- function MethodSelect({ createState, setCreateState, setModeState }) {
1506
- const [selectedIndex, setSelectedIndex] = useState(0);
1507
- const options = [
1508
- { label: "Generate with Claude (recommended)", value: "generate" },
1509
- { label: "Manual configuration", value: "manual" }
1510
- ];
1511
- const handleChange = (value) => {
1512
- setCreateState({ type: "SET_METHOD", value });
1513
- if (value === "generate") {
1514
- setCreateState({ type: "SET_IS_AI_GENERATED", value: true });
1515
- setModeState({ mode: "create-generate", location: createState.location });
1516
- } else {
1517
- setCreateState({ type: "SET_IS_AI_GENERATED", value: false });
1518
- setModeState({ mode: "create-type", location: createState.location });
1519
- }
1520
- };
1521
- const handleCancel = () => {
1522
- setModeState({ mode: "create-location" });
1523
- };
1524
- useInput((input, key) => {
1525
- if (key.escape) {
1526
- handleCancel();
1527
- } else if (key.return) {
1528
- handleChange(options[selectedIndex].value);
1529
- } else if (key.upArrow) {
1530
- setSelectedIndex((prev) => prev > 0 ? prev - 1 : options.length - 1);
1531
- } else if (key.downArrow) {
1532
- setSelectedIndex((prev) => prev < options.length - 1 ? prev + 1 : 0);
1533
- }
1534
- });
1535
- return /* @__PURE__ */ React.createElement(Box, { flexDirection: "column" }, /* @__PURE__ */ React.createElement(Header, { title: "Create new agent", subtitle: "Creation method", step: 2, totalSteps: 9 }, /* @__PURE__ */ React.createElement(Box, { marginTop: 1 }, /* @__PURE__ */ React.createElement(
1536
- SelectList,
1537
- {
1538
- options,
1539
- selectedIndex,
1540
- onChange: handleChange,
1541
- onCancel: handleCancel
1542
- }
1543
- ))), /* @__PURE__ */ React.createElement(InstructionBar, null));
1544
- }
1545
- function AgentMenu({ agent, setModeState }) {
1546
- const [selectedIndex, setSelectedIndex] = useState(0);
1547
- const options = [
1548
- { label: "View details", value: "view" },
1549
- { label: "Edit agent", value: "edit", disabled: agent.location === "built-in" },
1550
- { label: "Delete agent", value: "delete", disabled: agent.location === "built-in" }
1551
- ];
1552
- const availableOptions = options.filter((opt) => !opt.disabled);
1553
- const handleSelect = (value) => {
1554
- switch (value) {
1555
- case "view":
1556
- setModeState({ mode: "view-agent", selectedAgent: agent });
1557
- break;
1558
- case "edit":
1559
- setModeState({ mode: "edit-agent", selectedAgent: agent });
1560
- break;
1561
- case "delete":
1562
- setModeState({ mode: "delete-confirm", selectedAgent: agent });
1563
- break;
1564
- }
1565
- };
1566
- useInput((input, key) => {
1567
- if (key.return) {
1568
- handleSelect(availableOptions[selectedIndex].value);
1569
- } else if (key.upArrow) {
1570
- setSelectedIndex((prev) => prev > 0 ? prev - 1 : availableOptions.length - 1);
1571
- } else if (key.downArrow) {
1572
- setSelectedIndex((prev) => prev < availableOptions.length - 1 ? prev + 1 : 0);
1573
- }
1574
- });
1575
- return /* @__PURE__ */ React.createElement(Box, { flexDirection: "column" }, /* @__PURE__ */ React.createElement(Header, { title: `Agent: ${agent.agentType}`, subtitle: `${agent.location}` }, /* @__PURE__ */ React.createElement(Box, { marginTop: 1 }, /* @__PURE__ */ React.createElement(
1576
- SelectList,
1577
- {
1578
- options: availableOptions,
1579
- selectedIndex,
1580
- onChange: handleSelect,
1581
- numbered: false
1582
- }
1583
- ))), /* @__PURE__ */ React.createElement(InstructionBar, null));
1584
- }
1585
- function EditMenu({ agent, setModeState }) {
1586
- const [selectedIndex, setSelectedIndex] = useState(0);
1587
- const [isOpening, setIsOpening] = useState(false);
1588
- const theme = getTheme();
1589
- const options = [
1590
- { label: "Open in editor", value: "open-editor" },
1591
- { label: "Edit tools", value: "edit-tools" },
1592
- { label: "Edit model", value: "edit-model" },
1593
- { label: "Edit color", value: "edit-color" }
1594
- ];
1595
- const handleSelect = async (value) => {
1596
- switch (value) {
1597
- case "open-editor":
1598
- setIsOpening(true);
1599
- try {
1600
- const filePath = getAgentFilePath(agent);
1601
- await openInEditor(filePath);
1602
- setModeState({ mode: "agent-menu", selectedAgent: agent });
1603
- } catch (error) {
1604
- console.error("Failed to open editor:", error);
1605
- } finally {
1606
- setIsOpening(false);
1607
- }
1608
- break;
1609
- case "edit-tools":
1610
- setModeState({ mode: "edit-tools", selectedAgent: agent });
1611
- break;
1612
- case "edit-model":
1613
- setModeState({ mode: "edit-model", selectedAgent: agent });
1614
- break;
1615
- case "edit-color":
1616
- setModeState({ mode: "edit-color", selectedAgent: agent });
1617
- break;
1618
- }
1619
- };
1620
- const handleBack = () => {
1621
- setModeState({ mode: "agent-menu", selectedAgent: agent });
1622
- };
1623
- useInput((input, key) => {
1624
- if (key.escape) {
1625
- handleBack();
1626
- } else if (key.return && !isOpening) {
1627
- handleSelect(options[selectedIndex].value);
1628
- } else if (key.upArrow) {
1629
- setSelectedIndex((prev) => prev > 0 ? prev - 1 : options.length - 1);
1630
- } else if (key.downArrow) {
1631
- setSelectedIndex((prev) => prev < options.length - 1 ? prev + 1 : 0);
1632
- }
1633
- });
1634
- if (isOpening) {
1635
- return /* @__PURE__ */ React.createElement(Box, { flexDirection: "column" }, /* @__PURE__ */ React.createElement(Header, { title: `Edit agent: ${agent.agentType}`, subtitle: "Opening in editor..." }, /* @__PURE__ */ React.createElement(Box, { marginTop: 1 }, /* @__PURE__ */ React.createElement(LoadingSpinner, { text: "Opening file in editor..." }))), /* @__PURE__ */ React.createElement(InstructionBar, null));
1636
- }
1637
- return /* @__PURE__ */ React.createElement(Box, { flexDirection: "column" }, /* @__PURE__ */ React.createElement(Header, { title: `Edit agent: ${agent.agentType}`, subtitle: `Location: ${agent.location}` }, /* @__PURE__ */ React.createElement(Box, { marginTop: 1 }, /* @__PURE__ */ React.createElement(
1638
- SelectList,
1639
- {
1640
- options,
1641
- selectedIndex,
1642
- onChange: handleSelect,
1643
- numbered: false
1644
- }
1645
- ))), /* @__PURE__ */ React.createElement(InstructionBar, { instructions: "\u2191\u2193 navigate \xB7 Enter select \xB7 Esc back" }));
1646
- }
1647
- function EditToolsStep({ agent, tools, setModeState, onAgentUpdated }) {
1648
- const [selectedIndex, setSelectedIndex] = useState(0);
1649
- const initialTools = Array.isArray(agent.tools) ? agent.tools : agent.tools === "*" ? tools.map((t) => t.name) : [];
1650
- const [selectedTools, setSelectedTools] = useState(new Set(initialTools));
1651
- const [showAdvanced, setShowAdvanced] = useState(false);
1652
- const [isUpdating, setIsUpdating] = useState(false);
1653
- const categorizedTools = useMemo(() => {
1654
- const categories = {
1655
- read: [],
1656
- edit: [],
1657
- execution: [],
1658
- web: [],
1659
- other: []
1660
- };
1661
- tools.forEach((tool) => {
1662
- let categorized = false;
1663
- for (const [category, toolNames] of Object.entries(TOOL_CATEGORIES)) {
1664
- if (Array.isArray(toolNames) && toolNames.includes(tool.name)) {
1665
- categories[category]?.push(tool);
1666
- categorized = true;
1667
- break;
1668
- }
1669
- }
1670
- if (!categorized) {
1671
- categories.other.push(tool);
1672
- }
1673
- });
1674
- return categories;
1675
- }, [tools]);
1676
- const allSelected = selectedTools.size === tools.length && tools.length > 0;
1677
- const readSelected = categorizedTools.read.every((tool) => selectedTools.has(tool.name)) && categorizedTools.read.length > 0;
1678
- const editSelected = categorizedTools.edit.every((tool) => selectedTools.has(tool.name)) && categorizedTools.edit.length > 0;
1679
- const execSelected = categorizedTools.execution.every((tool) => selectedTools.has(tool.name)) && categorizedTools.execution.length > 0;
1680
- const options = [
1681
- { id: "continue", label: "Save", isContinue: true },
1682
- { id: "separator1", label: "\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500", isSeparator: true },
1683
- { id: "all", label: `${allSelected ? UI_ICONS.checkboxOn : UI_ICONS.checkboxOff} All tools`, isAll: true },
1684
- { id: "read", label: `${readSelected ? UI_ICONS.checkboxOn : UI_ICONS.checkboxOff} Read-only tools`, isCategory: true },
1685
- { id: "edit", label: `${editSelected ? UI_ICONS.checkboxOn : UI_ICONS.checkboxOff} Edit tools`, isCategory: true },
1686
- { id: "execution", label: `${execSelected ? UI_ICONS.checkboxOn : UI_ICONS.checkboxOff} Execution tools`, isCategory: true },
1687
- { id: "separator2", label: "\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500", isSeparator: true },
1688
- { id: "advanced", label: `[ ${showAdvanced ? "Hide" : "Show"} advanced options ]`, isAdvancedToggle: true },
1689
- ...showAdvanced ? tools.map((tool) => ({
1690
- id: tool.name,
1691
- label: `${selectedTools.has(tool.name) ? UI_ICONS.checkboxOn : UI_ICONS.checkboxOff} ${tool.name}`,
1692
- isTool: true
1693
- })) : []
1694
- ];
1695
- const handleSave = async () => {
1696
- setIsUpdating(true);
1697
- try {
1698
- const toolsArray = allSelected ? "*" : Array.from(selectedTools);
1699
- await updateAgent(agent, agent.whenToUse, toolsArray, agent.systemPrompt, agent.color, agent.model);
1700
- clearAgentCache();
1701
- const freshAgents = await getActiveAgents();
1702
- const updatedAgent = freshAgents.find((a) => a.agentType === agent.agentType);
1703
- if (updatedAgent) {
1704
- onAgentUpdated(`Updated tools for agent: ${agent.agentType}`, updatedAgent);
1705
- setModeState({ mode: "edit-agent", selectedAgent: updatedAgent });
1706
- } else {
1707
- console.error("Failed to find updated agent after save");
1708
- const fallbackAgent = {
1709
- ...agent,
1710
- tools: toolsArray.length === 1 && toolsArray[0] === "*" ? "*" : toolsArray
1711
- };
1712
- onAgentUpdated(`Updated tools for agent: ${agent.agentType}`, fallbackAgent);
1713
- setModeState({ mode: "edit-agent", selectedAgent: fallbackAgent });
1714
- }
1715
- } catch (error) {
1716
- console.error("Failed to update agent tools:", error);
1717
- } finally {
1718
- setIsUpdating(false);
1719
- }
1720
- };
1721
- const handleSelect = () => {
1722
- const option = options[selectedIndex];
1723
- if (!option) return;
1724
- if (option.isSeparator) return;
1725
- if (option.isContinue) {
1726
- handleSave();
1727
- } else if (option.isAdvancedToggle) {
1728
- setShowAdvanced(!showAdvanced);
1729
- } else if (option.isAll) {
1730
- if (allSelected) {
1731
- setSelectedTools(/* @__PURE__ */ new Set());
1732
- } else {
1733
- setSelectedTools(new Set(tools.map((t) => t.name)));
1734
- }
1735
- } else if (option.isCategory) {
1736
- const categoryName = option.id;
1737
- const categoryTools = categorizedTools[categoryName] || [];
1738
- const newSelected = new Set(selectedTools);
1739
- const categorySelected = categoryTools.every((tool) => selectedTools.has(tool.name));
1740
- if (categorySelected) {
1741
- categoryTools.forEach((tool) => newSelected.delete(tool.name));
1742
- } else {
1743
- categoryTools.forEach((tool) => newSelected.add(tool.name));
1744
- }
1745
- setSelectedTools(newSelected);
1746
- } else if (option.isTool) {
1747
- const newSelected = new Set(selectedTools);
1748
- if (newSelected.has(option.id)) {
1749
- newSelected.delete(option.id);
1750
- } else {
1751
- newSelected.add(option.id);
1752
- }
1753
- setSelectedTools(newSelected);
1754
- }
1755
- };
1756
- useInput((input, key) => {
1757
- if (key.escape) {
1758
- setModeState({ mode: "edit-agent", selectedAgent: agent });
1759
- } else if (key.return && !isUpdating) {
1760
- handleSelect();
1761
- } else if (key.upArrow) {
1762
- setSelectedIndex((prev) => {
1763
- let newIndex = prev > 0 ? prev - 1 : options.length - 1;
1764
- while (options[newIndex] && options[newIndex].isSeparator) {
1765
- newIndex = newIndex > 0 ? newIndex - 1 : options.length - 1;
1766
- }
1767
- return newIndex;
1768
- });
1769
- } else if (key.downArrow) {
1770
- setSelectedIndex((prev) => {
1771
- let newIndex = prev < options.length - 1 ? prev + 1 : 0;
1772
- while (options[newIndex] && options[newIndex].isSeparator) {
1773
- newIndex = newIndex < options.length - 1 ? newIndex + 1 : 0;
1774
- }
1775
- return newIndex;
1776
- });
1777
- }
1778
- });
1779
- if (isUpdating) {
1780
- return /* @__PURE__ */ React.createElement(Box, { flexDirection: "column" }, /* @__PURE__ */ React.createElement(Header, { title: `Edit agent: ${agent.agentType}` }, /* @__PURE__ */ React.createElement(Box, { marginTop: 1 }, /* @__PURE__ */ React.createElement(LoadingSpinner, { text: "Updating agent tools..." }))), /* @__PURE__ */ React.createElement(InstructionBar, null));
1781
- }
1782
- return /* @__PURE__ */ React.createElement(Box, { flexDirection: "column" }, /* @__PURE__ */ React.createElement(Header, { title: `Edit agent: ${agent.agentType}` }, /* @__PURE__ */ React.createElement(Box, { flexDirection: "column", marginTop: 1 }, options.map((option, idx) => {
1783
- const isSelected = idx === selectedIndex;
1784
- const isContinue = "isContinue" in option && option.isContinue;
1785
- const isAdvancedToggle = option.isAdvancedToggle;
1786
- const isSeparator = option.isSeparator;
1787
- return /* @__PURE__ */ React.createElement(Box, { key: option.id }, /* @__PURE__ */ React.createElement(
1788
- Text,
1789
- {
1790
- color: isSelected && !isSeparator ? "cyan" : isSeparator ? "gray" : void 0,
1791
- bold: isContinue,
1792
- dimColor: isSeparator
1793
- },
1794
- isSeparator ? option.label : `${isSelected ? `${UI_ICONS.pointer} ` : " "}${isContinue || isAdvancedToggle ? option.label : option.label}`
1795
- ), option.isTool && isSelected && tools.find((t) => t.name === option.id)?.description && /* @__PURE__ */ React.createElement(Box, { marginLeft: 4 }, /* @__PURE__ */ React.createElement(Text, { dimColor: true }, tools.find((t) => t.name === option.id)?.description)));
1796
- }), /* @__PURE__ */ React.createElement(Box, { marginTop: 1 }, /* @__PURE__ */ React.createElement(Text, { dimColor: true }, allSelected ? "All tools selected" : `${selectedTools.size} of ${tools.length} tools selected`)))), /* @__PURE__ */ React.createElement(InstructionBar, { instructions: "Enter toggle selection \xB7 \u2191\u2193 navigate \xB7 Esc back" }));
1797
- }
1798
- function EditModelStep({ agent, setModeState, onAgentUpdated }) {
1799
- const manager = getModelManager();
1800
- const profiles = manager.getActiveModelProfiles();
1801
- const currentModel = agent.model || null;
1802
- const modelOptions = [
1803
- { id: null, name: "Inherit from parent", description: "Use the model from task configuration" },
1804
- ...profiles.map((p) => ({ id: p.modelName, name: p.name, description: `${p.provider || "provider"} \xB7 ${p.modelName}` }))
1805
- ];
1806
- const defaultIndex = modelOptions.findIndex((m) => m.id === currentModel);
1807
- const [selectedIndex, setSelectedIndex] = useState(defaultIndex >= 0 ? defaultIndex : 0);
1808
- const [isUpdating, setIsUpdating] = useState(false);
1809
- const handleSave = async (modelId) => {
1810
- setIsUpdating(true);
1811
- try {
1812
- const modelValue = modelId === null ? void 0 : modelId;
1813
- await updateAgent(agent, agent.whenToUse, agent.tools, agent.systemPrompt, agent.color, modelValue);
1814
- clearAgentCache();
1815
- const freshAgents = await getActiveAgents();
1816
- const updatedAgent = freshAgents.find((a) => a.agentType === agent.agentType);
1817
- if (updatedAgent) {
1818
- onAgentUpdated(`Updated model for agent: ${agent.agentType}`, updatedAgent);
1819
- setModeState({ mode: "edit-agent", selectedAgent: updatedAgent });
1820
- } else {
1821
- console.error("Failed to find updated agent after save");
1822
- const fallbackAgent = { ...agent };
1823
- if (modelValue) {
1824
- fallbackAgent.model = modelValue;
1825
- } else {
1826
- delete fallbackAgent.model;
1827
- }
1828
- onAgentUpdated(`Updated model for agent: ${agent.agentType}`, fallbackAgent);
1829
- setModeState({ mode: "edit-agent", selectedAgent: fallbackAgent });
1830
- }
1831
- } catch (error) {
1832
- console.error("Failed to update agent model:", error);
1833
- } finally {
1834
- setIsUpdating(false);
1835
- }
1836
- };
1837
- useInput((input, key) => {
1838
- if (key.escape) {
1839
- setModeState({ mode: "edit-agent", selectedAgent: agent });
1840
- } else if (key.return && !isUpdating) {
1841
- handleSave(modelOptions[selectedIndex].id);
1842
- } else if (key.upArrow) {
1843
- setSelectedIndex((prev) => prev > 0 ? prev - 1 : modelOptions.length - 1);
1844
- } else if (key.downArrow) {
1845
- setSelectedIndex((prev) => prev < modelOptions.length - 1 ? prev + 1 : 0);
1846
- }
1847
- });
1848
- if (isUpdating) {
1849
- return /* @__PURE__ */ React.createElement(Box, { flexDirection: "column" }, /* @__PURE__ */ React.createElement(Header, { title: `Edit agent: ${agent.agentType}` }, /* @__PURE__ */ React.createElement(Box, { marginTop: 1 }, /* @__PURE__ */ React.createElement(LoadingSpinner, { text: "Updating agent model..." }))), /* @__PURE__ */ React.createElement(InstructionBar, null));
1850
- }
1851
- return /* @__PURE__ */ React.createElement(Box, { flexDirection: "column" }, /* @__PURE__ */ React.createElement(Header, { title: `Edit agent: ${agent.agentType}`, subtitle: "Model determines the agent's reasoning capabilities and speed." }, /* @__PURE__ */ React.createElement(Box, { marginTop: 2 }, /* @__PURE__ */ React.createElement(
1852
- SelectList,
1853
- {
1854
- options: modelOptions.map((m, i) => ({ label: `${i + 1}. ${m.name}${m.description ? `
1855
- ${m.description}` : ""}`, value: m.id })),
1856
- selectedIndex,
1857
- onChange: (val) => handleSave(val),
1858
- numbered: false
1859
- }
1860
- ))), /* @__PURE__ */ React.createElement(InstructionBar, { instructions: "\u2191\u2193 navigate \xB7 Enter select \xB7 Esc back" }));
1861
- }
1862
- function EditColorStep({ agent, setModeState, onAgentUpdated }) {
1863
- const currentColor = agent.color || null;
1864
- const colors = [
1865
- { label: "Automatic color", value: null },
1866
- { label: "Yellow", value: "yellow" },
1867
- { label: "Blue", value: "blue" },
1868
- { label: "Magenta", value: "magenta" },
1869
- { label: "Cyan", value: "cyan" },
1870
- { label: "Gray", value: "gray" },
1871
- { label: "White", value: "white" }
1872
- ];
1873
- const defaultIndex = colors.findIndex((color) => color.value === currentColor);
1874
- const [selectedIndex, setSelectedIndex] = useState(defaultIndex >= 0 ? defaultIndex : 0);
1875
- const [isUpdating, setIsUpdating] = useState(false);
1876
- const handleSave = async (color) => {
1877
- setIsUpdating(true);
1878
- try {
1879
- const colorValue = color === null ? void 0 : color;
1880
- await updateAgent(agent, agent.whenToUse, agent.tools, agent.systemPrompt, colorValue, agent.model);
1881
- clearAgentCache();
1882
- const freshAgents = await getActiveAgents();
1883
- const updatedAgent = freshAgents.find((a) => a.agentType === agent.agentType);
1884
- if (updatedAgent) {
1885
- onAgentUpdated(`Updated color for agent: ${agent.agentType}`, updatedAgent);
1886
- setModeState({ mode: "edit-agent", selectedAgent: updatedAgent });
1887
- } else {
1888
- console.error("Failed to find updated agent after save");
1889
- const fallbackAgent = { ...agent, ...colorValue ? { color: colorValue } : { color: void 0 } };
1890
- onAgentUpdated(`Updated color for agent: ${agent.agentType}`, fallbackAgent);
1891
- setModeState({ mode: "edit-agent", selectedAgent: fallbackAgent });
1892
- }
1893
- } catch (error) {
1894
- console.error("Failed to update agent color:", error);
1895
- } finally {
1896
- setIsUpdating(false);
1897
- }
1898
- };
1899
- useInput((input, key) => {
1900
- if (key.escape) {
1901
- setModeState({ mode: "edit-agent", selectedAgent: agent });
1902
- } else if (key.return && !isUpdating) {
1903
- handleSave(colors[selectedIndex].value);
1904
- } else if (key.upArrow) {
1905
- setSelectedIndex((prev) => prev > 0 ? prev - 1 : colors.length - 1);
1906
- } else if (key.downArrow) {
1907
- setSelectedIndex((prev) => prev < colors.length - 1 ? prev + 1 : 0);
1908
- }
1909
- });
1910
- if (isUpdating) {
1911
- return /* @__PURE__ */ React.createElement(Box, { flexDirection: "column" }, /* @__PURE__ */ React.createElement(Header, { title: `Edit agent: ${agent.agentType}` }, /* @__PURE__ */ React.createElement(Box, { marginTop: 1 }, /* @__PURE__ */ React.createElement(LoadingSpinner, { text: "Updating agent color..." }))), /* @__PURE__ */ React.createElement(InstructionBar, null));
1912
- }
1913
- const selectedColor = colors[selectedIndex];
1914
- const previewColor = selectedColor.value || void 0;
1915
- return /* @__PURE__ */ React.createElement(Box, { flexDirection: "column" }, /* @__PURE__ */ React.createElement(Header, { title: `Edit agent: ${agent.agentType}`, subtitle: "Choose background color" }, /* @__PURE__ */ React.createElement(Box, { flexDirection: "column", marginTop: 1 }, colors.map((color, index) => {
1916
- const isSelected = index === selectedIndex;
1917
- const isCurrent = color.value === currentColor;
1918
- return /* @__PURE__ */ React.createElement(Box, { key: color.value || "automatic" }, /* @__PURE__ */ React.createElement(Text, { color: isSelected ? "cyan" : void 0 }, isSelected ? "\u276F " : " "), /* @__PURE__ */ React.createElement(Text, { color: color.value || void 0 }, "\u25CF"), /* @__PURE__ */ React.createElement(Text, null, " ", color.label, isCurrent && /* @__PURE__ */ React.createElement(Text, { color: "green" }, " \u2714")));
1919
- }), /* @__PURE__ */ React.createElement(Box, { marginTop: 2 }, /* @__PURE__ */ React.createElement(Text, null, "Preview: "), /* @__PURE__ */ React.createElement(Text, { color: previewColor }, agent.agentType)))), /* @__PURE__ */ React.createElement(InstructionBar, { instructions: "\u2191\u2193 navigate \xB7 Enter select \xB7 Esc back" }));
1920
- }
1921
- function ViewAgent({ agent, tools, setModeState }) {
1922
- const theme = getTheme();
1923
- const agentTools = Array.isArray(agent.tools) ? agent.tools : [];
1924
- const hasAllTools = agent.tools === "*" || agentTools.includes("*");
1925
- const locationPath = agent.location === "user" ? `~/.claude/agents/${agent.agentType}.md` : agent.location === "project" ? `.claude/agents/${agent.agentType}.md` : "(built-in)";
1926
- const displayModel = getDisplayModelName(agent.model || null);
1927
- const allowedTools = useMemo(() => {
1928
- if (hasAllTools) return tools;
1929
- return tools.filter(
1930
- (tool) => agentTools.some((allowedTool) => {
1931
- if (allowedTool.includes("*")) {
1932
- const prefix = allowedTool.replace("*", "");
1933
- return tool.name.startsWith(prefix);
1934
- }
1935
- return tool.name === allowedTool;
1936
- })
1937
- );
1938
- }, [tools, agentTools, hasAllTools]);
1939
- return /* @__PURE__ */ React.createElement(Box, { flexDirection: "column" }, /* @__PURE__ */ React.createElement(Header, { title: `Agent: ${agent.agentType}`, subtitle: "Details" }, /* @__PURE__ */ React.createElement(Box, { flexDirection: "column", marginTop: 1 }, /* @__PURE__ */ React.createElement(Text, null, /* @__PURE__ */ React.createElement(Text, { bold: true }, "Type:"), " ", agent.agentType), /* @__PURE__ */ React.createElement(Text, null, /* @__PURE__ */ React.createElement(Text, { bold: true }, "Location:"), " ", agent.location, " ", locationPath !== "(built-in)" ? `\xB7 ${locationPath}` : ""), /* @__PURE__ */ React.createElement(Text, null, /* @__PURE__ */ React.createElement(Text, { bold: true }, "Description:"), " ", agent.whenToUse), /* @__PURE__ */ React.createElement(Text, null, /* @__PURE__ */ React.createElement(Text, { bold: true }, "Model:"), " ", displayModel), /* @__PURE__ */ React.createElement(Text, null, /* @__PURE__ */ React.createElement(Text, { bold: true }, "Color:"), " ", agent.color || "auto"), /* @__PURE__ */ React.createElement(Box, { marginTop: 1 }, /* @__PURE__ */ React.createElement(Text, { bold: true }, "Tools:")), hasAllTools ? /* @__PURE__ */ React.createElement(Text, { color: theme.secondary }, "All tools (", tools.length, " available)") : /* @__PURE__ */ React.createElement(Box, { flexDirection: "column", paddingLeft: 2 }, allowedTools.map((tool) => /* @__PURE__ */ React.createElement(Fragment, { key: tool.name }, /* @__PURE__ */ React.createElement(Text, { color: theme.secondary }, "\u2022 ", tool.name)))), /* @__PURE__ */ React.createElement(Box, { marginTop: 1 }, /* @__PURE__ */ React.createElement(Text, { bold: true }, "System Prompt:")), /* @__PURE__ */ React.createElement(Box, { paddingLeft: 2 }, /* @__PURE__ */ React.createElement(Text, null, agent.systemPrompt)))), /* @__PURE__ */ React.createElement(InstructionBar, null));
1940
- }
1941
- function EditAgent({ agent, tools, setModeState, onAgentUpdated }) {
1942
- const theme = getTheme();
1943
- const [currentStep, setCurrentStep] = useState("description");
1944
- const [isUpdating, setIsUpdating] = useState(false);
1945
- const [editedDescription, setEditedDescription] = useState(agent.whenToUse);
1946
- const [editedTools, setEditedTools] = useState(
1947
- Array.isArray(agent.tools) ? agent.tools : agent.tools === "*" ? ["*"] : []
1948
- );
1949
- const [editedPrompt, setEditedPrompt] = useState(agent.systemPrompt);
1950
- const [error, setError] = useState(null);
1951
- const handleSave = async () => {
1952
- setIsUpdating(true);
1953
- try {
1954
- await updateAgent(agent, editedDescription, editedTools, editedPrompt, agent.color);
1955
- clearAgentCache();
1956
- onAgentUpdated(`Updated agent: ${agent.agentType}`);
1957
- } catch (error2) {
1958
- setError(error2.message);
1959
- setIsUpdating(false);
1960
- }
1961
- };
1962
- const renderStepContent = () => {
1963
- switch (currentStep) {
1964
- case "description":
1965
- return /* @__PURE__ */ React.createElement(Box, { flexDirection: "column" }, /* @__PURE__ */ React.createElement(Text, { bold: true }, "Edit Description:"), /* @__PURE__ */ React.createElement(Box, { marginTop: 1 }, /* @__PURE__ */ React.createElement(
1966
- MultilineTextInput,
1967
- {
1968
- value: editedDescription,
1969
- onChange: setEditedDescription,
1970
- placeholder: "Describe when to use this agent...",
1971
- onSubmit: () => setCurrentStep("tools"),
1972
- error,
1973
- rows: 4
1974
- }
1975
- )));
1976
- case "tools":
1977
- return /* @__PURE__ */ React.createElement(Box, { flexDirection: "column" }, /* @__PURE__ */ React.createElement(Text, { bold: true }, "Edit Tools:"), /* @__PURE__ */ React.createElement(Box, { marginTop: 1 }, /* @__PURE__ */ React.createElement(
1978
- ToolsStep,
1979
- {
1980
- createState: {
1981
- selectedTools: editedTools
1982
- },
1983
- setCreateState: (action) => {
1984
- if (action.type === "SET_SELECTED_TOOLS") {
1985
- setEditedTools(action.value);
1986
- setCurrentStep("prompt");
1987
- }
1988
- },
1989
- setModeState: () => {
1990
- },
1991
- tools
1992
- }
1993
- )));
1994
- case "prompt":
1995
- return /* @__PURE__ */ React.createElement(Box, { flexDirection: "column" }, /* @__PURE__ */ React.createElement(Text, { bold: true }, "Edit System Prompt:"), /* @__PURE__ */ React.createElement(Box, { marginTop: 1 }, /* @__PURE__ */ React.createElement(
1996
- MultilineTextInput,
1997
- {
1998
- value: editedPrompt,
1999
- onChange: setEditedPrompt,
2000
- placeholder: "System prompt for the agent...",
2001
- onSubmit: () => setCurrentStep("confirm"),
2002
- error,
2003
- rows: 5
2004
- }
2005
- )));
2006
- case "confirm":
2007
- const validation = validateAgentConfig({
2008
- agentType: agent.agentType,
2009
- whenToUse: editedDescription,
2010
- systemPrompt: editedPrompt,
2011
- selectedTools: editedTools
2012
- });
2013
- return /* @__PURE__ */ React.createElement(Box, { flexDirection: "column" }, /* @__PURE__ */ React.createElement(Text, { bold: true }, "Confirm Changes:"), /* @__PURE__ */ React.createElement(Box, { flexDirection: "column", marginTop: 1 }, /* @__PURE__ */ React.createElement(Text, null, /* @__PURE__ */ React.createElement(Text, { bold: true }, "Agent:"), " ", agent.agentType), /* @__PURE__ */ React.createElement(Text, null, /* @__PURE__ */ React.createElement(Text, { bold: true }, "Description:"), " ", editedDescription), /* @__PURE__ */ React.createElement(Text, null, /* @__PURE__ */ React.createElement(Text, { bold: true }, "Tools:"), " ", editedTools.includes("*") ? "All tools" : editedTools.join(", ")), /* @__PURE__ */ React.createElement(Text, null, /* @__PURE__ */ React.createElement(Text, { bold: true }, "System Prompt:"), " ", editedPrompt.slice(0, 100), editedPrompt.length > 100 ? "..." : ""), validation.warnings.length > 0 && /* @__PURE__ */ React.createElement(Box, { marginTop: 1 }, validation.warnings.map((warning, idx) => /* @__PURE__ */ React.createElement(Fragment, { key: idx }, /* @__PURE__ */ React.createElement(Text, { color: theme.warning }, "\u26A0 ", warning)))), error && /* @__PURE__ */ React.createElement(Box, { marginTop: 1 }, /* @__PURE__ */ React.createElement(Text, { color: theme.error }, "\u2717 ", error)), /* @__PURE__ */ React.createElement(Box, { marginTop: 2 }, isUpdating ? /* @__PURE__ */ React.createElement(LoadingSpinner, { text: "Updating agent..." }) : /* @__PURE__ */ React.createElement(Text, null, "Press Enter to save changes"))));
2014
- }
2015
- };
2016
- useInput((input, key) => {
2017
- if (key.escape) {
2018
- if (currentStep === "description") {
2019
- setModeState({ mode: "agent-menu", selectedAgent: agent });
2020
- } else {
2021
- const steps = ["description", "tools", "prompt", "confirm"];
2022
- const currentIndex = steps.indexOf(currentStep);
2023
- if (currentIndex > 0) {
2024
- setCurrentStep(steps[currentIndex - 1]);
2025
- }
2026
- }
2027
- return;
2028
- }
2029
- if (key.return && currentStep === "confirm" && !isUpdating) {
2030
- handleSave();
2031
- }
2032
- });
2033
- return /* @__PURE__ */ React.createElement(Box, { flexDirection: "column" }, /* @__PURE__ */ React.createElement(Header, { title: `Edit Agent: ${agent.agentType}`, subtitle: `Step ${["description", "tools", "prompt", "confirm"].indexOf(currentStep) + 1}/4` }, /* @__PURE__ */ React.createElement(Box, { marginTop: 1 }, renderStepContent())), /* @__PURE__ */ React.createElement(
2034
- InstructionBar,
2035
- {
2036
- instructions: currentStep === "confirm" ? "Press Enter to save \xB7 Esc to go back" : "Enter to continue \xB7 Esc to go back"
2037
- }
2038
- ));
2039
- }
2040
- function DeleteConfirm({ agent, setModeState, onAgentDeleted }) {
2041
- const [isDeleting, setIsDeleting] = useState(false);
2042
- const [selected, setSelected] = useState(false);
2043
- const handleConfirm = async () => {
2044
- if (selected) {
2045
- setIsDeleting(true);
2046
- try {
2047
- await deleteAgent(agent);
2048
- clearAgentCache();
2049
- onAgentDeleted(`Deleted agent: ${agent.agentType}`);
2050
- } catch (error) {
2051
- console.error("Failed to delete agent:", error);
2052
- setIsDeleting(false);
2053
- }
2054
- } else {
2055
- setModeState({ mode: "agent-menu", selectedAgent: agent });
2056
- }
2057
- };
2058
- useInput((input, key) => {
2059
- if (key.return) {
2060
- handleConfirm();
2061
- } else if (key.leftArrow || key.rightArrow || key.tab) {
2062
- setSelected(!selected);
2063
- }
2064
- });
2065
- if (isDeleting) {
2066
- return /* @__PURE__ */ React.createElement(Box, { flexDirection: "column" }, /* @__PURE__ */ React.createElement(Header, { title: "Delete agent", subtitle: "Deleting..." }, /* @__PURE__ */ React.createElement(Box, { marginTop: 1 }, /* @__PURE__ */ React.createElement(LoadingSpinner, { text: "Deleting agent..." }))), /* @__PURE__ */ React.createElement(InstructionBar, null));
2067
- }
2068
- return /* @__PURE__ */ React.createElement(Box, { flexDirection: "column" }, /* @__PURE__ */ React.createElement(Header, { title: "Delete agent", subtitle: `Delete "${agent.agentType}"?` }, /* @__PURE__ */ React.createElement(Box, { marginTop: 1 }, /* @__PURE__ */ React.createElement(Text, null, "This action cannot be undone. The agent file will be permanently deleted."), /* @__PURE__ */ React.createElement(Box, { marginTop: 2, gap: 3 }, /* @__PURE__ */ React.createElement(Text, { color: !selected ? "cyan" : void 0 }, !selected ? `${UI_ICONS.pointer} ` : " ", "No"), /* @__PURE__ */ React.createElement(Text, { color: selected ? "red" : void 0 }, selected ? `${UI_ICONS.pointer} ` : " ", "Yes, delete")))), /* @__PURE__ */ React.createElement(InstructionBar, null));
2069
- }
2070
- var agents_default = {
2071
- name: "agents",
2072
- description: "Manage agent configurations",
2073
- type: "local-jsx",
2074
- isEnabled: true,
2075
- isHidden: false,
2076
- async call(onExit) {
2077
- return /* @__PURE__ */ React.createElement(AgentsUI, { onExit });
2078
- },
2079
- userFacingName() {
2080
- return "agents";
2081
- }
2082
- };
2083
- export {
2084
- agents_default as default
2085
- };
2086
- //# sourceMappingURL=agents.js.map