@shareai-lab/kode 1.1.12 → 1.1.13

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