@within-7/minto 0.3.9 → 0.4.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (383) hide show
  1. package/dist/Tool.js.map +2 -2
  2. package/dist/commands/agents/AgentsCommand.js +461 -657
  3. package/dist/commands/agents/AgentsCommand.js.map +2 -2
  4. package/dist/commands/agents/types.js +1 -0
  5. package/dist/commands/agents/types.js.map +2 -2
  6. package/dist/commands/agents/utils/fileOperations.js +96 -36
  7. package/dist/commands/agents/utils/fileOperations.js.map +3 -3
  8. package/dist/commands/agents/utils/index.js +3 -1
  9. package/dist/commands/agents/utils/index.js.map +2 -2
  10. package/dist/commands/context.js +54 -23
  11. package/dist/commands/context.js.map +2 -2
  12. package/dist/commands/ctx_viz.js +1 -1
  13. package/dist/commands/effort.js +87 -0
  14. package/dist/commands/effort.js.map +7 -0
  15. package/dist/commands/export.js +684 -94
  16. package/dist/commands/export.js.map +2 -2
  17. package/dist/commands/ide.js +18 -0
  18. package/dist/commands/ide.js.map +7 -0
  19. package/dist/commands/language.js +19 -46
  20. package/dist/commands/language.js.map +2 -2
  21. package/dist/commands/mcp-interactive.js +425 -217
  22. package/dist/commands/mcp-interactive.js.map +2 -2
  23. package/dist/commands/memory.js +168 -0
  24. package/dist/commands/memory.js.map +7 -0
  25. package/dist/commands/model.js +457 -65
  26. package/dist/commands/model.js.map +2 -2
  27. package/dist/commands/outputStyle.js +64 -0
  28. package/dist/commands/outputStyle.js.map +7 -0
  29. package/dist/commands/permissions.js +75 -49
  30. package/dist/commands/permissions.js.map +2 -2
  31. package/dist/commands/plugin/utils.js +33 -1
  32. package/dist/commands/plugin/utils.js.map +2 -2
  33. package/dist/commands/plugin.js +891 -185
  34. package/dist/commands/plugin.js.map +3 -3
  35. package/dist/commands/refreshCommands.js +2 -0
  36. package/dist/commands/refreshCommands.js.map +2 -2
  37. package/dist/commands/resume.js +1 -1
  38. package/dist/commands/resume.js.map +1 -1
  39. package/dist/commands/review.js +51 -0
  40. package/dist/commands/review.js.map +7 -0
  41. package/dist/commands/sandbox.js +168 -70
  42. package/dist/commands/sandbox.js.map +2 -2
  43. package/dist/commands/setup.js +593 -107
  44. package/dist/commands/setup.js.map +2 -2
  45. package/dist/commands/stats.js +188 -131
  46. package/dist/commands/stats.js.map +2 -2
  47. package/dist/commands/status.js +75 -13
  48. package/dist/commands/status.js.map +2 -2
  49. package/dist/commands/terminalSetup.js +6 -0
  50. package/dist/commands/terminalSetup.js.map +2 -2
  51. package/dist/commands/undo.js +146 -174
  52. package/dist/commands/undo.js.map +2 -2
  53. package/dist/commands/vim.js +22 -0
  54. package/dist/commands/vim.js.map +7 -0
  55. package/dist/commands.js +12 -0
  56. package/dist/commands.js.map +2 -2
  57. package/dist/components/Help.js +165 -32
  58. package/dist/components/Help.js.map +2 -2
  59. package/dist/components/HighlightedCode.js +1 -0
  60. package/dist/components/HighlightedCode.js.map +2 -2
  61. package/dist/components/InfoPanel/InfoPanel.js +123 -0
  62. package/dist/components/InfoPanel/InfoPanel.js.map +7 -0
  63. package/dist/components/InfoPanel/index.js +5 -0
  64. package/dist/components/InfoPanel/index.js.map +7 -0
  65. package/dist/components/InfoPanel/types.js +1 -0
  66. package/dist/components/InfoPanel/types.js.map +7 -0
  67. package/dist/components/ModelSelector/BrandTextInput.js +43 -0
  68. package/dist/components/ModelSelector/BrandTextInput.js.map +7 -0
  69. package/dist/components/ModelSelector/ModelSelector.js +590 -565
  70. package/dist/components/ModelSelector/ModelSelector.js.map +2 -2
  71. package/dist/components/ModelSelector/WizardContainer.js +45 -0
  72. package/dist/components/ModelSelector/WizardContainer.js.map +7 -0
  73. package/dist/components/ModelSelector/index.js +1 -3
  74. package/dist/components/ModelSelector/index.js.map +2 -2
  75. package/dist/components/PromptInput.js +26 -11
  76. package/dist/components/PromptInput.js.map +2 -2
  77. package/dist/components/PulseLabel.js +44 -0
  78. package/dist/components/PulseLabel.js.map +7 -0
  79. package/dist/components/RequestStatusIndicator.js +1 -1
  80. package/dist/components/RequestStatusIndicator.js.map +1 -1
  81. package/dist/components/SimpleSelector/SimpleSelector.js +154 -0
  82. package/dist/components/SimpleSelector/SimpleSelector.js.map +7 -0
  83. package/dist/components/SimpleSelector/index.js +5 -0
  84. package/dist/components/SimpleSelector/index.js.map +7 -0
  85. package/dist/components/SimpleSelector/types.js +1 -0
  86. package/dist/components/SimpleSelector/types.js.map +7 -0
  87. package/dist/components/Spinner.js +12 -42
  88. package/dist/components/Spinner.js.map +3 -3
  89. package/dist/components/StartupStatus.js +57 -0
  90. package/dist/components/StartupStatus.js.map +7 -0
  91. package/dist/components/StatusOverlayContent.js +21 -0
  92. package/dist/components/StatusOverlayContent.js.map +7 -0
  93. package/dist/components/SubagentBlock.js +43 -6
  94. package/dist/components/SubagentBlock.js.map +2 -2
  95. package/dist/components/TabbedListView/ScrollableList.js +31 -5
  96. package/dist/components/TabbedListView/ScrollableList.js.map +2 -2
  97. package/dist/components/TabbedListView/TabBar.js +13 -8
  98. package/dist/components/TabbedListView/TabBar.js.map +2 -2
  99. package/dist/components/TabbedListView/TabbedListView.js +123 -48
  100. package/dist/components/TabbedListView/TabbedListView.js.map +2 -2
  101. package/dist/components/TodoPanel.js +1 -1
  102. package/dist/components/TodoPanel.js.map +1 -1
  103. package/dist/components/ToolUseLoader.js +5 -0
  104. package/dist/components/ToolUseLoader.js.map +2 -2
  105. package/dist/components/TrustDialog.js +0 -2
  106. package/dist/components/TrustDialog.js.map +2 -2
  107. package/dist/components/messages/TaskInModuleView.js +1 -1
  108. package/dist/components/messages/TaskInModuleView.js.map +2 -2
  109. package/dist/components/messages/TaskToolMessage.js +1 -1
  110. package/dist/components/messages/TaskToolMessage.js.map +2 -2
  111. package/dist/components/messages/UserPromptMessage.js +6 -1
  112. package/dist/components/messages/UserPromptMessage.js.map +2 -2
  113. package/dist/constants/modelCapabilities.js +103 -18
  114. package/dist/constants/modelCapabilities.js.map +2 -2
  115. package/dist/constants/product.js +2 -0
  116. package/dist/constants/product.js.map +2 -2
  117. package/dist/constants/prompts/agentPrompt.js +30 -0
  118. package/dist/constants/prompts/agentPrompt.js.map +7 -0
  119. package/dist/constants/prompts/codeConventions.js +27 -0
  120. package/dist/constants/prompts/codeConventions.js.map +7 -0
  121. package/dist/constants/prompts/doingTasks.js +15 -0
  122. package/dist/constants/prompts/doingTasks.js.map +7 -0
  123. package/dist/constants/prompts/envInfo.js +17 -0
  124. package/dist/constants/prompts/envInfo.js.map +7 -0
  125. package/dist/constants/prompts/executingWithCare.js +17 -0
  126. package/dist/constants/prompts/executingWithCare.js.map +7 -0
  127. package/dist/constants/prompts/identity.js +10 -0
  128. package/dist/constants/prompts/identity.js.map +7 -0
  129. package/dist/constants/prompts/index.js +78 -0
  130. package/dist/constants/prompts/index.js.map +7 -0
  131. package/dist/constants/prompts/taskManagement.js +60 -0
  132. package/dist/constants/prompts/taskManagement.js.map +7 -0
  133. package/dist/constants/prompts/toneAndStyle.js +62 -0
  134. package/dist/constants/prompts/toneAndStyle.js.map +7 -0
  135. package/dist/constants/prompts/toolUsagePolicy.js +38 -0
  136. package/dist/constants/prompts/toolUsagePolicy.js.map +7 -0
  137. package/dist/constants/prompts.js +5 -176
  138. package/dist/constants/prompts.js.map +2 -2
  139. package/dist/constants/providerRegistry.js +235 -0
  140. package/dist/constants/providerRegistry.js.map +7 -0
  141. package/dist/constants/providers.js +35 -0
  142. package/dist/constants/providers.js.map +7 -0
  143. package/dist/context/PermissionContext.js +0 -1
  144. package/dist/context/PermissionContext.js.map +2 -2
  145. package/dist/context.js +87 -31
  146. package/dist/context.js.map +2 -2
  147. package/dist/core/backupHook.js +29 -0
  148. package/dist/core/backupHook.js.map +7 -0
  149. package/dist/core/config/defaults.js +11 -2
  150. package/dist/core/config/defaults.js.map +2 -2
  151. package/dist/core/config/schema.js +21 -3
  152. package/dist/core/config/schema.js.map +2 -2
  153. package/dist/core/costTracker.js +18 -16
  154. package/dist/core/costTracker.js.map +2 -2
  155. package/dist/core/index.js +0 -1
  156. package/dist/core/index.js.map +2 -2
  157. package/dist/core/tokenStatsManager.js +22 -4
  158. package/dist/core/tokenStatsManager.js.map +2 -2
  159. package/dist/cost-tracker.js +0 -16
  160. package/dist/cost-tracker.js.map +2 -2
  161. package/dist/entrypoints/bootstrap.js +3 -1
  162. package/dist/entrypoints/bootstrap.js.map +2 -2
  163. package/dist/entrypoints/cli.js +81 -68
  164. package/dist/entrypoints/cli.js.map +2 -2
  165. package/dist/hooks/useAgentTokenStats.js +1 -1
  166. package/dist/hooks/useAgentTokenStats.js.map +2 -2
  167. package/dist/hooks/useAgentTranscripts.js +2 -1
  168. package/dist/hooks/useAgentTranscripts.js.map +2 -2
  169. package/dist/hooks/useBackgroundShells.js +29 -0
  170. package/dist/hooks/useBackgroundShells.js.map +7 -0
  171. package/dist/hooks/useCanUseTool.js +1 -1
  172. package/dist/hooks/useCanUseTool.js.map +2 -2
  173. package/dist/hooks/useDeferredLoading.js +64 -0
  174. package/dist/hooks/useDeferredLoading.js.map +7 -0
  175. package/dist/hooks/useHookStatus.js +1 -1
  176. package/dist/hooks/useHookStatus.js.map +2 -2
  177. package/dist/hooks/useSessionTracking.js +55 -0
  178. package/dist/hooks/useSessionTracking.js.map +7 -0
  179. package/dist/hooks/useTerminalSize.js +21 -0
  180. package/dist/hooks/useTerminalSize.js.map +2 -2
  181. package/dist/hooks/useTextInput.js +1 -0
  182. package/dist/hooks/useTextInput.js.map +2 -2
  183. package/dist/hooks/useUnifiedCompletion.js +3 -2
  184. package/dist/hooks/useUnifiedCompletion.js.map +2 -2
  185. package/dist/i18n/locales/en.js +299 -1
  186. package/dist/i18n/locales/en.js.map +2 -2
  187. package/dist/i18n/locales/zh-CN.js +300 -2
  188. package/dist/i18n/locales/zh-CN.js.map +2 -2
  189. package/dist/i18n/types.js.map +1 -1
  190. package/dist/messages.js +41 -17
  191. package/dist/messages.js.map +2 -2
  192. package/dist/permissions.js +94 -1
  193. package/dist/permissions.js.map +2 -2
  194. package/dist/query.js +27 -19
  195. package/dist/query.js.map +2 -2
  196. package/dist/screens/REPL.js +83 -74
  197. package/dist/screens/REPL.js.map +2 -2
  198. package/dist/services/adapters/responsesAPI.js +6 -0
  199. package/dist/services/adapters/responsesAPI.js.map +2 -2
  200. package/dist/services/agentTeams/index.js +35 -0
  201. package/dist/services/agentTeams/index.js.map +7 -0
  202. package/dist/services/agentTeams/mailbox.js +114 -0
  203. package/dist/services/agentTeams/mailbox.js.map +7 -0
  204. package/dist/services/agentTeams/teamManager.js +149 -0
  205. package/dist/services/agentTeams/teamManager.js.map +7 -0
  206. package/dist/services/agentTeams/teamTaskStore.js +114 -0
  207. package/dist/services/agentTeams/teamTaskStore.js.map +7 -0
  208. package/dist/services/agentTeams/teammateSpawner.js +80 -0
  209. package/dist/services/agentTeams/teammateSpawner.js.map +7 -0
  210. package/dist/services/checkpointManager.js +16 -3
  211. package/dist/services/checkpointManager.js.map +2 -2
  212. package/dist/services/claude.js +19 -1728
  213. package/dist/services/claude.js.map +3 -3
  214. package/dist/services/customCommands.js +30 -8
  215. package/dist/services/customCommands.js.map +2 -2
  216. package/dist/services/gpt5ConnectionTest.js +4 -2
  217. package/dist/services/gpt5ConnectionTest.js.map +2 -2
  218. package/dist/services/hookExecutor.js +411 -127
  219. package/dist/services/hookExecutor.js.map +2 -2
  220. package/dist/services/llm/anthropicProvider.js +807 -0
  221. package/dist/services/llm/anthropicProvider.js.map +7 -0
  222. package/dist/services/llm/dispatch.js +218 -0
  223. package/dist/services/llm/dispatch.js.map +7 -0
  224. package/dist/services/llm/index.js +44 -0
  225. package/dist/services/llm/index.js.map +7 -0
  226. package/dist/services/llm/mintoContext.js +69 -0
  227. package/dist/services/llm/mintoContext.js.map +7 -0
  228. package/dist/services/llm/openaiProvider.js +622 -0
  229. package/dist/services/llm/openaiProvider.js.map +7 -0
  230. package/dist/services/llm/types.js +157 -0
  231. package/dist/services/llm/types.js.map +7 -0
  232. package/dist/services/mcpClient.js +183 -33
  233. package/dist/services/mcpClient.js.map +2 -2
  234. package/dist/services/notifier.js +14 -0
  235. package/dist/services/notifier.js.map +2 -2
  236. package/dist/services/oauth.js +4 -2
  237. package/dist/services/oauth.js.map +2 -2
  238. package/dist/services/openai.js +66 -56
  239. package/dist/services/openai.js.map +3 -3
  240. package/dist/services/outputStyles.js +102 -21
  241. package/dist/services/outputStyles.js.map +2 -2
  242. package/dist/services/plugins/lspServers.js +1 -1
  243. package/dist/services/plugins/lspServers.js.map +2 -2
  244. package/dist/services/plugins/pluginRuntime.js +2 -1
  245. package/dist/services/plugins/pluginRuntime.js.map +2 -2
  246. package/dist/services/plugins/pluginValidation.js +10 -3
  247. package/dist/services/plugins/pluginValidation.js.map +2 -2
  248. package/dist/services/plugins/skillMarketplace.js +20 -9
  249. package/dist/services/plugins/skillMarketplace.js.map +2 -2
  250. package/dist/services/sentry.js +1 -1
  251. package/dist/services/sentry.js.map +2 -2
  252. package/dist/services/sessionMemory.js +16 -3
  253. package/dist/services/sessionMemory.js.map +2 -2
  254. package/dist/services/systemReminder.js +367 -9
  255. package/dist/services/systemReminder.js.map +2 -2
  256. package/dist/services/taskStore.js +19 -0
  257. package/dist/services/taskStore.js.map +2 -2
  258. package/dist/tools/ArchitectTool/ArchitectTool.js.map +1 -1
  259. package/dist/tools/AskUserQuestionTool/AskUserQuestionTool.js.map +1 -1
  260. package/dist/tools/BashOutputTool/BashOutputTool.js.map +1 -1
  261. package/dist/tools/BashTool/BashTool.js +28 -0
  262. package/dist/tools/BashTool/BashTool.js.map +2 -2
  263. package/dist/tools/FileEditTool/FileEditTool.js +8 -1
  264. package/dist/tools/FileEditTool/FileEditTool.js.map +2 -2
  265. package/dist/tools/FileReadTool/FileReadTool.js +14 -0
  266. package/dist/tools/FileReadTool/FileReadTool.js.map +2 -2
  267. package/dist/tools/FileWriteTool/FileWriteTool.js +10 -1
  268. package/dist/tools/FileWriteTool/FileWriteTool.js.map +2 -2
  269. package/dist/tools/GlobTool/GlobTool.js.map +1 -1
  270. package/dist/tools/GrepTool/GrepTool.js.map +1 -1
  271. package/dist/tools/KillShellTool/KillShellTool.js.map +1 -1
  272. package/dist/tools/ListMcpResourcesTool/ListMcpResourcesTool.js.map +2 -2
  273. package/dist/tools/LspTool/LspTool.js +11 -2
  274. package/dist/tools/LspTool/LspTool.js.map +2 -2
  275. package/dist/tools/MCPTool/MCPTool.js.map +1 -1
  276. package/dist/tools/MemoryReadTool/MemoryReadTool.js +2 -1
  277. package/dist/tools/MemoryReadTool/MemoryReadTool.js.map +2 -2
  278. package/dist/tools/MemoryWriteTool/MemoryWriteTool.js +2 -1
  279. package/dist/tools/MemoryWriteTool/MemoryWriteTool.js.map +2 -2
  280. package/dist/tools/MultiEditTool/MultiEditTool.js +7 -0
  281. package/dist/tools/MultiEditTool/MultiEditTool.js.map +2 -2
  282. package/dist/tools/NotebookEditTool/NotebookEditTool.js +2 -0
  283. package/dist/tools/NotebookEditTool/NotebookEditTool.js.map +2 -2
  284. package/dist/tools/NotebookReadTool/NotebookReadTool.js.map +1 -1
  285. package/dist/tools/PlanModeTool/EnterPlanModeTool.js +8 -2
  286. package/dist/tools/PlanModeTool/EnterPlanModeTool.js.map +2 -2
  287. package/dist/tools/PlanModeTool/ExitPlanModeTool.js +2 -0
  288. package/dist/tools/PlanModeTool/ExitPlanModeTool.js.map +2 -2
  289. package/dist/tools/ReadMcpResourceTool/ReadMcpResourceTool.js.map +1 -1
  290. package/dist/tools/SlashCommandTool/SlashCommandTool.js +174 -18
  291. package/dist/tools/SlashCommandTool/SlashCommandTool.js.map +3 -3
  292. package/dist/tools/TaskCreateTool/TaskCreateTool.js.map +1 -1
  293. package/dist/tools/TaskGetTool/TaskGetTool.js.map +1 -1
  294. package/dist/tools/TaskListTool/TaskListTool.js.map +1 -1
  295. package/dist/tools/TaskOutputTool/TaskOutputTool.js.map +1 -1
  296. package/dist/tools/TaskStopTool/TaskStopTool.js.map +1 -1
  297. package/dist/tools/TaskTool/TaskTool.js +84 -11
  298. package/dist/tools/TaskTool/TaskTool.js.map +2 -2
  299. package/dist/tools/TaskTool/prompt.js +12 -6
  300. package/dist/tools/TaskTool/prompt.js.map +2 -2
  301. package/dist/tools/TaskUpdateTool/TaskUpdateTool.js.map +1 -1
  302. package/dist/tools/ThinkTool/ThinkTool.js.map +1 -1
  303. package/dist/tools/TodoWriteTool/TodoWriteTool.js.map +1 -1
  304. package/dist/tools/URLFetcherTool/URLFetcherTool.js.map +1 -1
  305. package/dist/tools/WebSearchTool/WebSearchTool.js.map +1 -1
  306. package/dist/tools/WebSearchTool/searchProviders.js +2 -1
  307. package/dist/tools/WebSearchTool/searchProviders.js.map +2 -2
  308. package/dist/tools/lsTool/lsTool.js.map +2 -2
  309. package/dist/tools/lsTool/prompt.js.map +1 -1
  310. package/dist/tools.js +14 -3
  311. package/dist/tools.js.map +2 -2
  312. package/dist/types/PermissionMode.js +21 -1
  313. package/dist/types/PermissionMode.js.map +2 -2
  314. package/dist/types/agentTeams.js +1 -0
  315. package/dist/types/agentTeams.js.map +7 -0
  316. package/dist/types/hooks.js +8 -2
  317. package/dist/types/hooks.js.map +2 -2
  318. package/dist/types/plugin.js +3 -5
  319. package/dist/types/plugin.js.map +2 -2
  320. package/dist/utils/agentHookExecutor.js +1 -4
  321. package/dist/utils/agentHookExecutor.js.map +2 -2
  322. package/dist/utils/agentLoader.js +91 -15
  323. package/dist/utils/agentLoader.js.map +2 -2
  324. package/dist/utils/agentMemory.js.map +2 -2
  325. package/dist/utils/animationManager.js +1 -1
  326. package/dist/utils/animationManager.js.map +2 -2
  327. package/dist/utils/ask.js +1 -1
  328. package/dist/utils/async.js +5 -1
  329. package/dist/utils/async.js.map +2 -2
  330. package/dist/utils/autoCompactCore.js +60 -0
  331. package/dist/utils/autoCompactCore.js.map +2 -2
  332. package/dist/utils/claudeCodeSync.js +439 -0
  333. package/dist/utils/claudeCodeSync.js.map +7 -0
  334. package/dist/utils/config.js +27 -151
  335. package/dist/utils/config.js.map +2 -2
  336. package/dist/utils/configSchema.js +227 -0
  337. package/dist/utils/configSchema.js.map +7 -0
  338. package/dist/utils/debugLogger.js.map +2 -2
  339. package/dist/utils/env.js +4 -3
  340. package/dist/utils/env.js.map +2 -2
  341. package/dist/utils/envConfig.js +34 -0
  342. package/dist/utils/envConfig.js.map +3 -3
  343. package/dist/utils/execFileNoThrow.js +2 -1
  344. package/dist/utils/execFileNoThrow.js.map +2 -2
  345. package/dist/utils/gpt5.js +146 -0
  346. package/dist/utils/gpt5.js.map +7 -0
  347. package/dist/utils/hookManager.js +374 -140
  348. package/dist/utils/hookManager.js.map +2 -2
  349. package/dist/utils/markdown.js +47 -0
  350. package/dist/utils/markdown.js.map +2 -2
  351. package/dist/utils/marketplaceManager.js +80 -43
  352. package/dist/utils/marketplaceManager.js.map +2 -2
  353. package/dist/utils/memoizeWithTTL.js +25 -0
  354. package/dist/utils/memoizeWithTTL.js.map +7 -0
  355. package/dist/utils/messages.js +2 -2
  356. package/dist/utils/messages.js.map +2 -2
  357. package/dist/utils/model.js +34 -9
  358. package/dist/utils/model.js.map +2 -2
  359. package/dist/utils/pluginInstaller.js +68 -29
  360. package/dist/utils/pluginInstaller.js.map +2 -2
  361. package/dist/utils/pluginLoader.js +249 -57
  362. package/dist/utils/pluginLoader.js.map +2 -2
  363. package/dist/utils/repoFetcher.js +110 -0
  364. package/dist/utils/repoFetcher.js.map +7 -0
  365. package/dist/utils/safeFetch.js +45 -0
  366. package/dist/utils/safeFetch.js.map +7 -0
  367. package/dist/utils/skillLoader.js +77 -12
  368. package/dist/utils/skillLoader.js.map +2 -2
  369. package/dist/utils/streamingState.js +52 -0
  370. package/dist/utils/streamingState.js.map +7 -0
  371. package/dist/utils/stringSubstitution.js +4 -5
  372. package/dist/utils/stringSubstitution.js.map +2 -2
  373. package/dist/utils/style.js +6 -3
  374. package/dist/utils/style.js.map +2 -2
  375. package/dist/utils/teamConfig.js +162 -16
  376. package/dist/utils/teamConfig.js.map +2 -2
  377. package/dist/utils/terminal.js +1 -1
  378. package/dist/utils/terminal.js.map +2 -2
  379. package/dist/utils/toolRiskClassification.js +0 -6
  380. package/dist/utils/toolRiskClassification.js.map +2 -2
  381. package/dist/version.js +2 -2
  382. package/dist/version.js.map +1 -1
  383. package/package.json +7 -6
@@ -1,10 +1,13 @@
1
- import React, { useState, useEffect } from "react";
2
- import { Box, Text, useInput } from "ink";
1
+ import React, { useState, useEffect, useMemo, useCallback } from "react";
2
+ import { Box, Text } from "ink";
3
3
  import { SimpleSpinner } from "../components/Spinner.js";
4
4
  import {
5
5
  loadAllPlugins,
6
6
  getPlugin,
7
- listPlugins
7
+ listPlugins,
8
+ togglePluginEnabled,
9
+ enablePlugin,
10
+ disablePlugin
8
11
  } from "../utils/pluginLoader.js";
9
12
  import {
10
13
  addMarketplace,
@@ -13,19 +16,19 @@ import {
13
16
  listMarketplaces,
14
17
  installPluginFromMarketplace
15
18
  } from "../utils/marketplaceManager.js";
19
+ import { uninstallPlugin } from "../utils/pluginInstaller.js";
20
+ import {
21
+ syncFromClaudeCode,
22
+ hasClaudeCodeInstallation
23
+ } from "../utils/claudeCodeSync.js";
24
+ import { gt as semverGt, valid as semverValid } from "semver";
16
25
  import { MarketplaceError } from "../types/marketplace.js";
17
26
  import { rmSync } from "fs";
18
27
  import { getTheme } from "../utils/theme.js";
19
28
  import { SEMANTIC_COLORS } from "../constants/colors.js";
20
- import { MainMenu } from "./plugin/MainMenu.js";
21
- import { MarketplaceSelector } from "./plugin/MarketplaceSelector.js";
22
- import { PluginBrowser } from "./plugin/PluginBrowser.js";
23
- import { PluginDetailsInstall } from "./plugin/PluginDetailsInstall.js";
24
- import { InstalledPluginsManager } from "./plugin/InstalledPluginsManager.js";
25
- import { InstalledPluginsByMarketplace } from "./plugin/InstalledPluginsByMarketplace.js";
26
- import { PluginDetailsManage } from "./plugin/PluginDetailsManage.js";
27
- import { AddMarketplaceForm } from "./plugin/AddMarketplaceForm.js";
28
- import { MarketplaceManager } from "./plugin/MarketplaceManager.js";
29
+ import { TabbedListView } from "../components/TabbedListView/TabbedListView.js";
30
+ import { t } from "../i18n/index.js";
31
+ import { formatMarketplacePath, formatTimeAgo } from "./plugin/utils.js";
29
32
  const PluginList = ({ onDone }) => {
30
33
  const [plugins, setPlugins] = useState([]);
31
34
  const [loading, setLoading] = useState(true);
@@ -66,7 +69,7 @@ const PluginList = ({ onDone }) => {
66
69
  flexDirection: "column",
67
70
  marginBottom: 1
68
71
  },
69
- /* @__PURE__ */ React.createElement(Box, null, /* @__PURE__ */ React.createElement(Text, { color: theme.primary, bold: true }, plugin2.manifest.displayName || plugin2.manifest.name), /* @__PURE__ */ React.createElement(Text, { color: SEMANTIC_COLORS.dim }, " ", "v", plugin2.manifest.version), !plugin2.enabled && /* @__PURE__ */ React.createElement(Text, { color: theme.warning }, " (disabled)")),
72
+ /* @__PURE__ */ React.createElement(Box, null, /* @__PURE__ */ React.createElement(Text, { color: theme.primary, bold: true }, plugin2.manifest.displayName || plugin2.manifest.name), /* @__PURE__ */ React.createElement(Text, { color: SEMANTIC_COLORS.dim }, " ", "v", plugin2.manifest.version), plugin2.source.type === "claude-code" && /* @__PURE__ */ React.createElement(Text, { color: "#5DADE2" }, " [CC]"), !plugin2.enabled && /* @__PURE__ */ React.createElement(Text, { color: theme.warning }, " (disabled)")),
70
73
  plugin2.manifest.description && /* @__PURE__ */ React.createElement(Text, { color: SEMANTIC_COLORS.dim }, " ", plugin2.manifest.description),
71
74
  componentCounts.length > 0 && /* @__PURE__ */ React.createElement(Text, { color: SEMANTIC_COLORS.dim }, " ", "Components: ", componentCounts.join(", ")),
72
75
  /* @__PURE__ */ React.createElement(Text, { color: SEMANTIC_COLORS.dim }, " ", "Location:", " ", plugin2.source.type === "local" ? plugin2.source.path : plugin2.location)
@@ -156,7 +159,7 @@ const PluginUninstall = ({
156
159
  const [message, setMessage] = useState("");
157
160
  const theme = getTheme();
158
161
  useEffect(() => {
159
- const uninstallPlugin = () => {
162
+ const uninstallPlugin2 = () => {
160
163
  try {
161
164
  setMessage(`Uninstalling plugin "${pluginName}"...`);
162
165
  const plugin2 = getPlugin(pluginName);
@@ -175,7 +178,7 @@ const PluginUninstall = ({
175
178
  onDone();
176
179
  }
177
180
  };
178
- uninstallPlugin();
181
+ uninstallPlugin2();
179
182
  }, [pluginName, onDone]);
180
183
  const color = status === "success" ? theme.success : status === "error" ? theme.error : theme.primary;
181
184
  return /* @__PURE__ */ React.createElement(Text, { color }, message);
@@ -242,6 +245,68 @@ const PluginValidate = ({
242
245
  }
243
246
  return /* @__PURE__ */ React.createElement(Box, { flexDirection: "column" }, /* @__PURE__ */ React.createElement(Text, { bold: true, underline: true, color: theme.primary }, "Plugin Validation Results"), /* @__PURE__ */ React.createElement(Text, null, ""), results.map((result) => /* @__PURE__ */ React.createElement(Box, { flexDirection: "column", marginBottom: 1 }, /* @__PURE__ */ React.createElement(Box, null, /* @__PURE__ */ React.createElement(Text, { color: result.valid ? theme.success : theme.error }, result.valid ? "\u2713" : "\u2717"), /* @__PURE__ */ React.createElement(Text, null, " ", result.plugin), result.valid && /* @__PURE__ */ React.createElement(Text, { color: theme.success }, " - Valid")), result.errors.length > 0 && /* @__PURE__ */ React.createElement(Box, { flexDirection: "column", marginLeft: 2 }, result.errors.map((error, idx) => /* @__PURE__ */ React.createElement(Text, { color: theme.error }, "\u2022 ", error))))));
244
247
  };
248
+ const PluginSync = ({
249
+ onDone,
250
+ force = false,
251
+ clean = false,
252
+ dryRun = false
253
+ }) => {
254
+ const [status, setStatus] = useState("syncing");
255
+ const [progress, setProgress] = useState(t("commands.plugin.syncStarting"));
256
+ const [result, setResult] = useState(null);
257
+ const [error, setError] = useState(null);
258
+ const theme = getTheme();
259
+ useEffect(() => {
260
+ const doSync = async () => {
261
+ if (!hasClaudeCodeInstallation()) {
262
+ setError(t("commands.plugin.syncNotFound"));
263
+ setStatus("error");
264
+ onDone();
265
+ return;
266
+ }
267
+ try {
268
+ const syncResult = await syncFromClaudeCode({
269
+ force,
270
+ clean,
271
+ dryRun,
272
+ onProgress: (msg) => setProgress(msg)
273
+ });
274
+ setResult(syncResult);
275
+ setStatus("done");
276
+ } catch (err) {
277
+ setError(err instanceof Error ? err.message : String(err));
278
+ setStatus("error");
279
+ } finally {
280
+ onDone();
281
+ }
282
+ };
283
+ doSync();
284
+ }, [force, clean, dryRun, onDone]);
285
+ if (status === "error") {
286
+ return /* @__PURE__ */ React.createElement(Text, { color: theme.error }, error);
287
+ }
288
+ if (status === "syncing") {
289
+ return /* @__PURE__ */ React.createElement(Box, null, /* @__PURE__ */ React.createElement(SimpleSpinner, null), /* @__PURE__ */ React.createElement(Text, { color: theme.primary }, " ", progress));
290
+ }
291
+ if (!result) return null;
292
+ const hasChanges = result.installed.length > 0 || result.updated.length > 0 || result.cleaned.length > 0 || result.marketplaces.registered.length > 0;
293
+ if (!hasChanges && result.failed.length === 0) {
294
+ return /* @__PURE__ */ React.createElement(Text, { color: theme.success }, t("commands.plugin.syncNoChanges"));
295
+ }
296
+ return /* @__PURE__ */ React.createElement(Box, { flexDirection: "column" }, dryRun && /* @__PURE__ */ React.createElement(Text, { color: theme.warning, bold: true }, t("commands.plugin.syncDryRun")), result.installed.length > 0 && /* @__PURE__ */ React.createElement(Box, { flexDirection: "column" }, /* @__PURE__ */ React.createElement(Text, { color: theme.success }, "Installed (", result.installed.length, "):"), result.installed.map((name) => /* @__PURE__ */ React.createElement(Box, { key: name }, /* @__PURE__ */ React.createElement(Text, { color: SEMANTIC_COLORS.dim }, " + ", name)))), result.updated.length > 0 && /* @__PURE__ */ React.createElement(Box, { flexDirection: "column" }, /* @__PURE__ */ React.createElement(Text, { color: theme.primary }, "Updated (", result.updated.length, "):"), result.updated.map((name) => /* @__PURE__ */ React.createElement(Box, { key: name }, /* @__PURE__ */ React.createElement(Text, { color: SEMANTIC_COLORS.dim }, " ~ ", name)))), result.cleaned.length > 0 && /* @__PURE__ */ React.createElement(Text, { color: SEMANTIC_COLORS.dim }, t("commands.plugin.syncCleaned").replace(
297
+ "${count}",
298
+ String(result.cleaned.length)
299
+ )), result.marketplaces.registered.length > 0 && /* @__PURE__ */ React.createElement(Box, { flexDirection: "column" }, /* @__PURE__ */ React.createElement(Text, { color: theme.success }, t("commands.plugin.syncMarketplacesRegistered").replace(
300
+ "${count}",
301
+ String(result.marketplaces.registered.length)
302
+ )), result.marketplaces.registered.map((name) => /* @__PURE__ */ React.createElement(Box, { key: name }, /* @__PURE__ */ React.createElement(Text, { color: SEMANTIC_COLORS.dim }, " + ", name)))), result.marketplaces.failed.length > 0 && /* @__PURE__ */ React.createElement(Box, { flexDirection: "column" }, /* @__PURE__ */ React.createElement(Text, { color: theme.error }, t("commands.plugin.syncMarketplacesFailed").replace(
303
+ "${count}",
304
+ String(result.marketplaces.failed.length)
305
+ )), result.marketplaces.failed.map((f) => /* @__PURE__ */ React.createElement(Box, { key: f.name }, /* @__PURE__ */ React.createElement(Text, { color: SEMANTIC_COLORS.dim }, " ", "! ", f.name, ": ", f.error)))), result.failed.length > 0 && /* @__PURE__ */ React.createElement(Box, { flexDirection: "column" }, /* @__PURE__ */ React.createElement(Text, { color: theme.error }, t("commands.plugin.syncFailed").replace(
306
+ "${count}",
307
+ String(result.failed.length)
308
+ )), result.failed.map((f) => /* @__PURE__ */ React.createElement(Box, { key: f.name }, /* @__PURE__ */ React.createElement(Text, { color: SEMANTIC_COLORS.dim }, " ", "! ", f.name, ": ", f.error)))), /* @__PURE__ */ React.createElement(Text, { color: theme.success }, t("commands.plugin.syncComplete").replace("${installed}", String(result.installed.length)).replace("${updated}", String(result.updated.length)).replace("${skipped}", String(result.skipped.length))));
309
+ };
245
310
  const MarketplaceListView = ({ onDone }) => {
246
311
  const [marketplaces, setMarketplaces] = useState([]);
247
312
  const [loading, setLoading] = useState(true);
@@ -374,192 +439,822 @@ const ErrorMessage = ({
374
439
  }, [onDone]);
375
440
  return /* @__PURE__ */ React.createElement(Text, { color: theme.error }, "Error: ", message);
376
441
  };
377
- const MarketplaceDetails = ({ marketplace: marketplaceName, onNavigate, onBack, onDone }) => {
378
- const theme = getTheme();
379
- const [removing, setRemoving] = useState(false);
380
- const [updating, setUpdating] = useState(false);
381
- const [error, setError] = useState();
382
- const marketplace = listMarketplaces().find(
383
- (m) => m.name === marketplaceName
384
- );
385
- useInput((input, key) => {
386
- if (key.escape) onBack();
387
- else if (input === "r" && !removing && !updating) {
388
- setRemoving(true);
389
- removeMarketplaceAction();
390
- } else if (input === "u" && !removing && !updating) {
391
- setUpdating(true);
392
- updateMarketplaceAction();
393
- } else if (input === "p" && !removing && !updating) {
394
- onNavigate({
395
- screen: "installed-plugins-by-marketplace",
396
- marketplace: marketplaceName
397
- });
398
- }
399
- });
400
- const removeMarketplaceAction = () => {
442
+ function compareVersions(installedVersion, marketplaceVersion) {
443
+ if (!installedVersion || !marketplaceVersion) return null;
444
+ if (!semverValid(installedVersion) || !semverValid(marketplaceVersion))
445
+ return null;
446
+ try {
447
+ return {
448
+ hasUpdate: semverGt(marketplaceVersion, installedVersion),
449
+ installed: installedVersion,
450
+ available: marketplaceVersion
451
+ };
452
+ } catch {
453
+ return null;
454
+ }
455
+ }
456
+ const InteractivePluginCommand = ({
457
+ onDone
458
+ }) => {
459
+ const [phase, setPhase] = useState({ type: "main" });
460
+ const [activeTab, setActiveTab] = useState("browse");
461
+ const [searchQuery, setSearchQuery] = useState("");
462
+ const [statusOverlay, setStatusOverlay] = useState(null);
463
+ const [marketplaces, setMarketplaces] = useState([]);
464
+ const [installedPlugins, setInstalledPlugins] = useState([]);
465
+ const [selectedIds, setSelectedIds] = useState(/* @__PURE__ */ new Set());
466
+ const reload = useCallback(() => {
401
467
  try {
402
- removeMarketplace(marketplaceName);
403
- onBack();
404
- } catch (err) {
405
- setError(err instanceof Error ? err.message : String(err));
406
- setRemoving(false);
468
+ setMarketplaces(listMarketplaces());
469
+ } catch {
470
+ setMarketplaces([]);
407
471
  }
408
- };
409
- const updateMarketplaceAction = async () => {
410
472
  try {
411
- await updateMarketplace(marketplaceName);
412
- setUpdating(false);
413
- } catch (err) {
414
- setError(err instanceof Error ? err.message : String(err));
415
- setUpdating(false);
473
+ setInstalledPlugins(loadAllPlugins());
474
+ } catch {
475
+ setInstalledPlugins([]);
416
476
  }
417
- };
418
- if (!marketplace) {
419
- return /* @__PURE__ */ React.createElement(Box, { padding: 1 }, /* @__PURE__ */ React.createElement(Text, { color: theme.error }, "Marketplace not found: ", marketplaceName));
420
- }
421
- if (removing) {
422
- return /* @__PURE__ */ React.createElement(Box, { padding: 1 }, /* @__PURE__ */ React.createElement(SimpleSpinner, null), /* @__PURE__ */ React.createElement(Text, { color: theme.primary }, " Removing marketplace..."));
423
- }
424
- if (updating) {
425
- return /* @__PURE__ */ React.createElement(Box, { padding: 1 }, /* @__PURE__ */ React.createElement(SimpleSpinner, null), /* @__PURE__ */ React.createElement(Text, { color: theme.primary }, " Updating marketplace..."));
426
- }
427
- return /* @__PURE__ */ React.createElement(
428
- Box,
429
- {
430
- flexDirection: "column",
431
- borderStyle: "round",
432
- borderColor: theme.primary,
433
- padding: 1
477
+ }, []);
478
+ useEffect(() => {
479
+ if (phase.type === "main") {
480
+ reload();
481
+ setSearchQuery("");
482
+ setSelectedIds(/* @__PURE__ */ new Set());
483
+ }
484
+ }, [phase, reload]);
485
+ const installedNames = useMemo(
486
+ () => new Set(installedPlugins.map((p) => p.name)),
487
+ [installedPlugins]
488
+ );
489
+ const findPluginMarketplace = useCallback(
490
+ (pluginName) => {
491
+ for (const m of marketplaces) {
492
+ if (m.manifest.plugins.some((p) => p.name === pluginName)) {
493
+ return m.name;
494
+ }
495
+ }
496
+ return void 0;
434
497
  },
435
- /* @__PURE__ */ React.createElement(Text, { bold: true, color: theme.success }, marketplace.name),
436
- marketplace.manifest.metadata?.description && /* @__PURE__ */ React.createElement(Box, { marginTop: 1 }, /* @__PURE__ */ React.createElement(Text, null, marketplace.manifest.metadata.description)),
437
- /* @__PURE__ */ React.createElement(Box, { marginTop: 1 }, /* @__PURE__ */ React.createElement(Text, null, "Plugins: "), /* @__PURE__ */ React.createElement(Text, { color: theme.primary }, marketplace.manifest.plugins.length)),
438
- /* @__PURE__ */ React.createElement(Box, { marginTop: 1 }, /* @__PURE__ */ React.createElement(Text, null, "Owner: "), /* @__PURE__ */ React.createElement(Text, null, marketplace.manifest.owner.name)),
439
- /* @__PURE__ */ React.createElement(Box, { marginTop: 1 }, /* @__PURE__ */ React.createElement(Text, null, "Source: "), /* @__PURE__ */ React.createElement(Text, { color: SEMANTIC_COLORS.dim }, marketplace.source.type, marketplace.source.type === "github" && ` (${marketplace.source.repo})`, marketplace.source.type === "url" && ` (${marketplace.source.url})`, marketplace.source.type === "local" && ` (${marketplace.source.path})`)),
440
- /* @__PURE__ */ React.createElement(Box, { marginTop: 1 }, /* @__PURE__ */ React.createElement(Text, null, "Last updated: "), /* @__PURE__ */ React.createElement(Text, { color: SEMANTIC_COLORS.dim }, new Date(marketplace.lastUpdated).toLocaleString())),
441
- error && /* @__PURE__ */ React.createElement(Box, { marginTop: 1 }, /* @__PURE__ */ React.createElement(Text, { color: theme.error }, "Error: ", error)),
442
- /* @__PURE__ */ React.createElement(Box, { marginTop: 1, flexDirection: "column" }, /* @__PURE__ */ React.createElement(Text, { color: SEMANTIC_COLORS.dim }, "Press ", /* @__PURE__ */ React.createElement(Text, { bold: true }, "p"), " to view plugins from this marketplace"), /* @__PURE__ */ React.createElement(Text, { color: SEMANTIC_COLORS.dim }, "Press ", /* @__PURE__ */ React.createElement(Text, { bold: true }, "u"), " to update marketplace"), /* @__PURE__ */ React.createElement(Text, { color: SEMANTIC_COLORS.dim }, "Press ", /* @__PURE__ */ React.createElement(Text, { bold: true }, "r"), " to remove marketplace"), /* @__PURE__ */ React.createElement(Text, { color: SEMANTIC_COLORS.dim }, "Press ", /* @__PURE__ */ React.createElement(Text, { bold: true }, "Esc"), " to go back"))
498
+ [marketplaces]
443
499
  );
444
- };
445
- const InteractivePluginCommand = ({
446
- onDone
447
- }) => {
448
- const [navigationStack, setNavigationStack] = useState([
449
- { screen: "main-menu" }
450
- ]);
451
- const currentState = navigationStack[navigationStack.length - 1];
452
- const handleNavigate = (newState) => {
453
- setNavigationStack((prev) => [...prev, newState]);
454
- };
455
- const handleBack = () => {
456
- if (navigationStack.length > 1) {
457
- setNavigationStack((prev) => prev.slice(0, -1));
458
- } else {
459
- onDone();
500
+ const multiSelectActionLabel = useMemo(() => {
501
+ if (phase.type !== "main" || selectedIds.size === 0) return void 0;
502
+ if (activeTab === "browse" || activeTab === "installed") {
503
+ return `${t("commands.plugin.batchAction")} (${selectedIds.size})`;
460
504
  }
461
- };
462
- switch (currentState.screen) {
463
- case "main-menu":
464
- return /* @__PURE__ */ React.createElement(
465
- MainMenu,
466
- {
467
- onNavigate: handleNavigate,
468
- onBack: handleBack,
469
- onDone
505
+ return void 0;
506
+ }, [phase, activeTab, selectedIds.size]);
507
+ const multiSelectEnabled = phase.type === "main" && (activeTab === "browse" || activeTab === "installed");
508
+ const { tabs, items, title, footerHint, searchEnabled, searchPlaceholder } = useMemo(() => {
509
+ switch (phase.type) {
510
+ case "main": {
511
+ const mainTabs = [
512
+ { id: "browse", label: t("commands.plugin.tabBrowse") },
513
+ { id: "installed", label: t("commands.plugin.tabInstalled") },
514
+ { id: "marketplaces", label: t("commands.plugin.tabMarketplaces") }
515
+ ];
516
+ let mainItems = [];
517
+ if (activeTab === "browse") {
518
+ for (const m of marketplaces) {
519
+ for (const p of m.manifest.plugins) {
520
+ const installed = installedPlugins.find(
521
+ (ip) => ip.name === p.name
522
+ );
523
+ let metadata;
524
+ if (installed) {
525
+ const versionInfo = compareVersions(
526
+ installed.manifest.version,
527
+ p.version
528
+ );
529
+ if (versionInfo?.hasUpdate) {
530
+ metadata = t("commands.plugin.updateAvailable").replace("{installed}", versionInfo.installed).replace("{available}", versionInfo.available);
531
+ } else {
532
+ metadata = "installed";
533
+ }
534
+ }
535
+ mainItems.push({
536
+ id: `${m.name}:${p.name}`,
537
+ label: p.name,
538
+ description: p.description || "",
539
+ category: m.name,
540
+ status: installedNames.has(p.name) ? "enabled" : void 0,
541
+ metadata,
542
+ data: { pluginName: p.name, marketplaceName: m.name }
543
+ });
544
+ }
545
+ }
546
+ } else if (activeTab === "installed") {
547
+ for (const p of installedPlugins) {
548
+ const mName = p.source.type === "claude-code" ? p.source.marketplace : p.source.type === "marketplace" ? p.source.marketplace : findPluginMarketplace(p.name);
549
+ const sourceTag = p.source.type === "claude-code" ? " [CC]" : "";
550
+ mainItems.push({
551
+ id: p.name,
552
+ label: `${p.manifest.displayName || p.name}${sourceTag}`,
553
+ description: p.manifest.description || "",
554
+ status: p.enabled ? "enabled" : "disabled",
555
+ category: mName || t("commands.plugin.local"),
556
+ data: { pluginName: p.name, source: p.source }
557
+ });
558
+ }
559
+ } else if (activeTab === "marketplaces") {
560
+ for (const m of marketplaces) {
561
+ mainItems.push({
562
+ id: m.name,
563
+ label: m.name,
564
+ description: `${m.manifest.plugins.length} plugins \xB7 ${formatMarketplacePath(m.source)} \xB7 ${formatTimeAgo(m.lastUpdated)}`,
565
+ status: m.enabled ? "enabled" : "disabled",
566
+ data: { marketplaceName: m.name }
567
+ });
568
+ }
569
+ mainItems.push({
570
+ id: "add-new",
571
+ label: `+ ${t("commands.plugin.addMarketplace")}`,
572
+ description: "Register a new plugin marketplace"
573
+ });
470
574
  }
471
- );
472
- case "marketplace-selector":
473
- return /* @__PURE__ */ React.createElement(
474
- MarketplaceSelector,
475
- {
476
- onNavigate: handleNavigate,
477
- onBack: handleBack,
478
- onDone
575
+ const isMultiSelectTab = activeTab === "browse" || activeTab === "installed";
576
+ return {
577
+ tabs: mainTabs,
578
+ items: mainItems,
579
+ title: "Plugins",
580
+ footerHint: isMultiSelectTab ? t("commands.plugin.footerHintMultiSelect") : t("commands.plugin.footerHint"),
581
+ searchEnabled: true,
582
+ searchPlaceholder: void 0
583
+ };
584
+ }
585
+ case "plugin-actions": {
586
+ const actionItems = [];
587
+ if (phase.from === "browse") {
588
+ actionItems.push({
589
+ id: "install",
590
+ label: t("commands.plugin.install"),
591
+ description: `Install from ${phase.marketplace || "marketplace"}`
592
+ });
593
+ } else {
594
+ const plugin2 = installedPlugins.find((p) => p.name === phase.plugin);
595
+ const isEnabled = plugin2?.enabled ?? true;
596
+ actionItems.push({
597
+ id: "toggle",
598
+ label: isEnabled ? t("commands.plugin.disable") : t("commands.plugin.enable"),
599
+ description: isEnabled ? "Disable this plugin" : "Enable this plugin"
600
+ });
601
+ if (phase.marketplace) {
602
+ actionItems.push({
603
+ id: "update",
604
+ label: t("commands.plugin.update"),
605
+ description: "Re-install from marketplace source"
606
+ });
607
+ }
608
+ actionItems.push({
609
+ id: "uninstall",
610
+ label: t("commands.plugin.uninstall"),
611
+ description: "Remove this plugin"
612
+ });
479
613
  }
480
- );
481
- case "plugin-browser":
482
- return /* @__PURE__ */ React.createElement(
483
- PluginBrowser,
484
- {
485
- marketplace: currentState.marketplace,
486
- onNavigate: handleNavigate,
487
- onBack: handleBack,
488
- onDone
614
+ actionItems.push({
615
+ id: "back",
616
+ label: t("commands.plugin.back")
617
+ });
618
+ return {
619
+ tabs: [
620
+ { id: "actions", label: t("commands.plugin.actions") }
621
+ ],
622
+ items: actionItems,
623
+ title: phase.plugin,
624
+ footerHint: "\u2191\u2193 Navigate \xB7 Enter Select \xB7 Esc Back",
625
+ searchEnabled: false,
626
+ searchPlaceholder: void 0
627
+ };
628
+ }
629
+ case "marketplace-actions": {
630
+ const mActionItems = [
631
+ {
632
+ id: "update",
633
+ label: t("commands.plugin.marketplaceUpdate"),
634
+ description: "Re-fetch marketplace manifest"
635
+ },
636
+ {
637
+ id: "browse",
638
+ label: t("commands.plugin.browsePlugins"),
639
+ description: "View plugins from this marketplace"
640
+ },
641
+ {
642
+ id: "remove",
643
+ label: t("commands.plugin.marketplaceRemove"),
644
+ description: "Unregister this marketplace"
645
+ },
646
+ {
647
+ id: "back",
648
+ label: t("commands.plugin.back")
649
+ }
650
+ ];
651
+ return {
652
+ tabs: [
653
+ { id: "actions", label: t("commands.plugin.actions") }
654
+ ],
655
+ items: mActionItems,
656
+ title: phase.marketplace,
657
+ footerHint: "\u2191\u2193 Navigate \xB7 Enter Select \xB7 Esc Back",
658
+ searchEnabled: false,
659
+ searchPlaceholder: void 0
660
+ };
661
+ }
662
+ case "batch-action-picker": {
663
+ const pickerItems = [];
664
+ const sel = phase.selectedItems;
665
+ if (phase.from === "installed") {
666
+ const updatableCount = sel.filter((item) => {
667
+ const pluginName = item.data?.pluginName;
668
+ return findPluginMarketplace(pluginName) !== void 0;
669
+ }).length;
670
+ if (updatableCount > 0) {
671
+ pickerItems.push({
672
+ id: "batch-update",
673
+ label: t("commands.plugin.batchUpdateAction").replace(
674
+ "{count}",
675
+ String(updatableCount)
676
+ )
677
+ });
678
+ }
679
+ pickerItems.push({
680
+ id: "batch-uninstall",
681
+ label: t("commands.plugin.batchDeleteAction").replace(
682
+ "{count}",
683
+ String(sel.length)
684
+ )
685
+ });
686
+ const disabledCount = sel.filter((item) => {
687
+ const plugin2 = installedPlugins.find(
688
+ (p) => p.name === item.data?.pluginName
689
+ );
690
+ return plugin2 && !plugin2.enabled;
691
+ }).length;
692
+ if (disabledCount > 0) {
693
+ pickerItems.push({
694
+ id: "batch-enable",
695
+ label: t("commands.plugin.batchEnableAction").replace(
696
+ "{count}",
697
+ String(disabledCount)
698
+ )
699
+ });
700
+ }
701
+ const enabledCount = sel.filter((item) => {
702
+ const plugin2 = installedPlugins.find(
703
+ (p) => p.name === item.data?.pluginName
704
+ );
705
+ return plugin2 && plugin2.enabled;
706
+ }).length;
707
+ if (enabledCount > 0) {
708
+ pickerItems.push({
709
+ id: "batch-disable",
710
+ label: t("commands.plugin.batchDisableAction").replace(
711
+ "{count}",
712
+ String(enabledCount)
713
+ )
714
+ });
715
+ }
716
+ } else {
717
+ const notInstalledCount = sel.filter(
718
+ (item) => !installedNames.has(item.data?.pluginName)
719
+ ).length;
720
+ if (notInstalledCount > 0) {
721
+ pickerItems.push({
722
+ id: "batch-install",
723
+ label: t("commands.plugin.batchInstallAction").replace(
724
+ "{count}",
725
+ String(notInstalledCount)
726
+ )
727
+ });
728
+ }
729
+ const alreadyInstalledCount = sel.filter(
730
+ (item) => installedNames.has(item.data?.pluginName)
731
+ ).length;
732
+ if (alreadyInstalledCount > 0) {
733
+ pickerItems.push({
734
+ id: "batch-update",
735
+ label: t("commands.plugin.batchUpdateAction").replace(
736
+ "{count}",
737
+ String(alreadyInstalledCount)
738
+ )
739
+ });
740
+ }
489
741
  }
490
- );
491
- case "plugin-details-install":
492
- return /* @__PURE__ */ React.createElement(
493
- PluginDetailsInstall,
494
- {
495
- marketplace: currentState.marketplace,
496
- plugin: currentState.plugin,
497
- onNavigate: handleNavigate,
498
- onBack: handleBack,
499
- onDone
742
+ pickerItems.push({
743
+ id: "back",
744
+ label: t("commands.plugin.back")
745
+ });
746
+ return {
747
+ tabs: [
748
+ {
749
+ id: "actions",
750
+ label: t("commands.plugin.batchActionPickerTitle")
751
+ }
752
+ ],
753
+ items: pickerItems,
754
+ title: t("commands.plugin.batchActionPickerTitle"),
755
+ footerHint: "\u2191\u2193 Navigate \xB7 Enter Select \xB7 Esc Back",
756
+ searchEnabled: false,
757
+ searchPlaceholder: void 0
758
+ };
759
+ }
760
+ case "batch-progress": {
761
+ return {
762
+ tabs: [
763
+ { id: "progress", label: t("common.loading") }
764
+ ],
765
+ items: [],
766
+ title: "Plugins",
767
+ footerHint: "",
768
+ searchEnabled: false,
769
+ searchPlaceholder: void 0
770
+ };
771
+ }
772
+ case "add-marketplace": {
773
+ const helpItems = [
774
+ {
775
+ id: "example-github",
776
+ label: "owner/repo",
777
+ description: "GitHub shorthand"
778
+ },
779
+ {
780
+ id: "example-https",
781
+ label: "https://github.com/owner/repo.git",
782
+ description: "HTTPS URL"
783
+ },
784
+ {
785
+ id: "example-local",
786
+ label: "./path/to/local",
787
+ description: "Local path"
788
+ }
789
+ ];
790
+ return {
791
+ tabs: [
792
+ {
793
+ id: "add",
794
+ label: t("commands.plugin.marketplaceAdd")
795
+ }
796
+ ],
797
+ items: helpItems,
798
+ title: t("commands.plugin.addMarketplace"),
799
+ footerHint: t("commands.plugin.addFooterHint"),
800
+ searchEnabled: true,
801
+ searchPlaceholder: t("commands.plugin.addMarketplacePlaceholder")
802
+ };
803
+ }
804
+ default:
805
+ return {
806
+ tabs: [],
807
+ items: [],
808
+ title: "",
809
+ footerHint: "",
810
+ searchEnabled: false,
811
+ searchPlaceholder: void 0
812
+ };
813
+ }
814
+ }, [
815
+ phase,
816
+ activeTab,
817
+ marketplaces,
818
+ installedPlugins,
819
+ installedNames,
820
+ findPluginMarketplace
821
+ ]);
822
+ const handleTabChange = useCallback((tabId) => {
823
+ setActiveTab(tabId);
824
+ setSearchQuery("");
825
+ setSelectedIds(/* @__PURE__ */ new Set());
826
+ }, []);
827
+ const handleSelectionChange = useCallback(
828
+ (itemId, selected) => {
829
+ setSelectedIds((prev) => {
830
+ const next = new Set(prev);
831
+ if (selected) {
832
+ next.add(itemId);
833
+ } else {
834
+ next.delete(itemId);
500
835
  }
501
- );
502
- case "installed-plugins-manager":
503
- return /* @__PURE__ */ React.createElement(
504
- InstalledPluginsManager,
505
- {
506
- key: navigationStack.length,
507
- onNavigate: handleNavigate,
508
- onBack: handleBack,
509
- onDone
836
+ return next;
837
+ });
838
+ },
839
+ []
840
+ );
841
+ const handleMultiSelect = useCallback(
842
+ (selectedItems) => {
843
+ if (activeTab === "browse" || activeTab === "installed") {
844
+ setPhase({
845
+ type: "batch-action-picker",
846
+ selectedItems,
847
+ from: activeTab
848
+ });
849
+ }
850
+ },
851
+ [activeTab]
852
+ );
853
+ useEffect(() => {
854
+ if (phase.type !== "batch-progress") return void 0;
855
+ let cancelled = false;
856
+ const { action, plugins } = phase;
857
+ const executeBatch = async () => {
858
+ let successCount = 0;
859
+ let failCount = 0;
860
+ const errors = [];
861
+ for (let i = 0; i < plugins.length; i++) {
862
+ if (cancelled) return;
863
+ const plugin2 = plugins[i];
864
+ const progressKey = action === "install" ? "commands.plugin.batchInstalling" : action === "update" ? "commands.plugin.batchUpdating" : "commands.plugin.batchUninstalling";
865
+ setStatusOverlay({
866
+ type: "loading",
867
+ message: t(progressKey).replace("{current}", String(i + 1)).replace("{total}", String(plugins.length)).replace("{name}", plugin2.name)
868
+ });
869
+ try {
870
+ if (action === "uninstall") {
871
+ await uninstallPlugin(plugin2.name);
872
+ } else {
873
+ await installPluginFromMarketplace(plugin2.name, plugin2.marketplace);
874
+ }
875
+ successCount++;
876
+ } catch (err) {
877
+ failCount++;
878
+ const msg = err instanceof Error ? err.message : String(err);
879
+ if (errors.length < 3) {
880
+ errors.push(`${plugin2.name}: ${msg}`);
881
+ }
510
882
  }
511
- );
512
- case "installed-plugins-by-marketplace":
513
- return /* @__PURE__ */ React.createElement(
514
- InstalledPluginsByMarketplace,
515
- {
516
- marketplace: currentState.marketplace,
517
- onNavigate: handleNavigate,
518
- onBack: handleBack,
519
- onDone
883
+ }
884
+ if (cancelled) return;
885
+ const parts = [];
886
+ if (successCount > 0) {
887
+ const countKey = action === "install" ? "commands.plugin.batchInstalledCount" : action === "update" ? "commands.plugin.batchUpdatedCount" : "commands.plugin.batchUninstalledCount";
888
+ parts.push(t(countKey).replace("{count}", String(successCount)));
889
+ }
890
+ if (failCount > 0) {
891
+ parts.push(
892
+ t("commands.plugin.batchFailedCount").replace(
893
+ "{count}",
894
+ String(failCount)
895
+ )
896
+ );
897
+ if (errors.length > 0) {
898
+ parts.push(errors.join("\n"));
520
899
  }
521
- );
522
- case "plugin-details-manage":
523
- return /* @__PURE__ */ React.createElement(
524
- PluginDetailsManage,
525
- {
526
- plugin: currentState.plugin,
527
- onNavigate: handleNavigate,
528
- onBack: handleBack,
529
- onDone
900
+ }
901
+ setStatusOverlay({
902
+ type: failCount === 0 ? "success" : "error",
903
+ message: parts.join("\n")
904
+ });
905
+ setSelectedIds(/* @__PURE__ */ new Set());
906
+ };
907
+ executeBatch();
908
+ return () => {
909
+ cancelled = true;
910
+ };
911
+ }, [phase]);
912
+ const handleStatusDismiss = useCallback(() => {
913
+ setStatusOverlay(null);
914
+ setPhase({ type: "main" });
915
+ }, []);
916
+ const handleBack = useCallback(() => {
917
+ if (statusOverlay && statusOverlay.type !== "loading") {
918
+ handleStatusDismiss();
919
+ return;
920
+ }
921
+ if (phase.type === "main") {
922
+ onDone();
923
+ } else {
924
+ setPhase({ type: "main" });
925
+ setSearchQuery("");
926
+ }
927
+ }, [phase, statusOverlay, onDone, handleStatusDismiss]);
928
+ const handleClose = useCallback(() => {
929
+ if (statusOverlay && statusOverlay.type !== "loading") {
930
+ handleStatusDismiss();
931
+ return;
932
+ }
933
+ if (phase.type === "main") {
934
+ onDone();
935
+ } else {
936
+ setPhase({ type: "main" });
937
+ setSearchQuery("");
938
+ }
939
+ }, [phase, statusOverlay, onDone, handleStatusDismiss]);
940
+ const handleSearchSubmit = useCallback(
941
+ async (query) => {
942
+ if (phase.type !== "add-marketplace" || !query.trim()) return;
943
+ setStatusOverlay({
944
+ type: "loading",
945
+ message: t("commands.plugin.marketplaceAdding")
946
+ });
947
+ try {
948
+ await addMarketplace(query.trim());
949
+ setStatusOverlay({
950
+ type: "success",
951
+ message: t("commands.plugin.marketplaceAddSuccess")
952
+ });
953
+ } catch (err) {
954
+ const msg = err instanceof Error ? err.message : String(err);
955
+ setStatusOverlay({
956
+ type: "error",
957
+ message: `${t("commands.plugin.marketplaceAddFailed")}: ${msg}`
958
+ });
959
+ }
960
+ },
961
+ [phase]
962
+ );
963
+ const handleSelect = useCallback(
964
+ async (item) => {
965
+ switch (phase.type) {
966
+ case "main": {
967
+ if (activeTab === "browse") {
968
+ const data = item.data;
969
+ setPhase({
970
+ type: "plugin-actions",
971
+ plugin: data.pluginName,
972
+ marketplace: data.marketplaceName,
973
+ from: "browse"
974
+ });
975
+ } else if (activeTab === "installed") {
976
+ const data = item.data;
977
+ const mName = findPluginMarketplace(data.pluginName);
978
+ setPhase({
979
+ type: "plugin-actions",
980
+ plugin: data.pluginName,
981
+ marketplace: mName,
982
+ from: "installed"
983
+ });
984
+ } else if (activeTab === "marketplaces") {
985
+ if (item.id === "add-new") {
986
+ setPhase({ type: "add-marketplace" });
987
+ setSearchQuery("");
988
+ } else {
989
+ const data = item.data;
990
+ setPhase({
991
+ type: "marketplace-actions",
992
+ marketplace: data.marketplaceName
993
+ });
994
+ }
995
+ }
996
+ break;
530
997
  }
531
- );
532
- case "add-marketplace":
533
- return /* @__PURE__ */ React.createElement(
534
- AddMarketplaceForm,
535
- {
536
- onNavigate: handleNavigate,
537
- onBack: handleBack,
538
- onDone
998
+ case "plugin-actions": {
999
+ if (item.id === "back") {
1000
+ setPhase({ type: "main" });
1001
+ return;
1002
+ }
1003
+ if (item.id === "install") {
1004
+ setStatusOverlay({
1005
+ type: "loading",
1006
+ message: t("commands.plugin.installing")
1007
+ });
1008
+ try {
1009
+ await installPluginFromMarketplace(
1010
+ phase.plugin,
1011
+ phase.marketplace
1012
+ );
1013
+ setStatusOverlay({
1014
+ type: "success",
1015
+ message: t("commands.plugin.installSuccess")
1016
+ });
1017
+ } catch (err) {
1018
+ const msg = err instanceof Error ? err.message : String(err);
1019
+ setStatusOverlay({
1020
+ type: "error",
1021
+ message: `${t("commands.plugin.installFailed")}: ${msg}`
1022
+ });
1023
+ }
1024
+ } else if (item.id === "toggle") {
1025
+ try {
1026
+ togglePluginEnabled(phase.plugin);
1027
+ setStatusOverlay({
1028
+ type: "success",
1029
+ message: t("commands.plugin.toggleSuccess")
1030
+ });
1031
+ } catch (err) {
1032
+ const msg = err instanceof Error ? err.message : String(err);
1033
+ setStatusOverlay({ type: "error", message: msg });
1034
+ }
1035
+ } else if (item.id === "update") {
1036
+ setStatusOverlay({
1037
+ type: "loading",
1038
+ message: t("commands.plugin.updating")
1039
+ });
1040
+ try {
1041
+ await installPluginFromMarketplace(
1042
+ phase.plugin,
1043
+ phase.marketplace
1044
+ );
1045
+ setStatusOverlay({
1046
+ type: "success",
1047
+ message: t("commands.plugin.updateSuccess")
1048
+ });
1049
+ } catch (err) {
1050
+ const msg = err instanceof Error ? err.message : String(err);
1051
+ setStatusOverlay({
1052
+ type: "error",
1053
+ message: `${t("commands.plugin.updateFailed")}: ${msg}`
1054
+ });
1055
+ }
1056
+ } else if (item.id === "uninstall") {
1057
+ setStatusOverlay({
1058
+ type: "loading",
1059
+ message: t("commands.plugin.uninstalling")
1060
+ });
1061
+ try {
1062
+ await uninstallPlugin(phase.plugin);
1063
+ setStatusOverlay({
1064
+ type: "success",
1065
+ message: t("commands.plugin.uninstallSuccess")
1066
+ });
1067
+ } catch (err) {
1068
+ const msg = err instanceof Error ? err.message : String(err);
1069
+ setStatusOverlay({
1070
+ type: "error",
1071
+ message: `${t("commands.plugin.uninstallFailed")}: ${msg}`
1072
+ });
1073
+ }
1074
+ }
1075
+ break;
539
1076
  }
540
- );
541
- case "marketplace-manager":
542
- return /* @__PURE__ */ React.createElement(
543
- MarketplaceManager,
544
- {
545
- onNavigate: handleNavigate,
546
- onBack: handleBack,
547
- onDone
1077
+ case "marketplace-actions": {
1078
+ if (item.id === "back") {
1079
+ setPhase({ type: "main" });
1080
+ return;
1081
+ }
1082
+ if (item.id === "update") {
1083
+ setStatusOverlay({
1084
+ type: "loading",
1085
+ message: t("commands.plugin.marketplaceUpdating")
1086
+ });
1087
+ try {
1088
+ await updateMarketplace(phase.marketplace);
1089
+ setStatusOverlay({
1090
+ type: "success",
1091
+ message: t("commands.plugin.marketplaceUpdateSuccess")
1092
+ });
1093
+ } catch (err) {
1094
+ const msg = err instanceof Error ? err.message : String(err);
1095
+ setStatusOverlay({
1096
+ type: "error",
1097
+ message: `${t("commands.plugin.marketplaceUpdateFailed")}: ${msg}`
1098
+ });
1099
+ }
1100
+ } else if (item.id === "browse") {
1101
+ setPhase({ type: "main" });
1102
+ setActiveTab("browse");
1103
+ setSearchQuery(phase.marketplace);
1104
+ } else if (item.id === "remove") {
1105
+ setStatusOverlay({
1106
+ type: "loading",
1107
+ message: t("commands.plugin.marketplaceRemoving")
1108
+ });
1109
+ try {
1110
+ removeMarketplace(phase.marketplace);
1111
+ setStatusOverlay({
1112
+ type: "success",
1113
+ message: t("commands.plugin.marketplaceRemoveSuccess")
1114
+ });
1115
+ } catch (err) {
1116
+ const msg = err instanceof Error ? err.message : String(err);
1117
+ setStatusOverlay({ type: "error", message: msg });
1118
+ }
1119
+ }
1120
+ break;
548
1121
  }
549
- );
550
- case "marketplace-details":
551
- return /* @__PURE__ */ React.createElement(
552
- MarketplaceDetails,
553
- {
554
- marketplace: currentState.marketplace,
555
- onNavigate: handleNavigate,
556
- onBack: handleBack,
557
- onDone
1122
+ case "batch-action-picker": {
1123
+ if (item.id === "back") {
1124
+ setPhase({ type: "main" });
1125
+ return;
1126
+ }
1127
+ const sel = phase.selectedItems;
1128
+ if (item.id === "batch-install") {
1129
+ const toInstall = sel.filter((si) => !installedNames.has(si.data?.pluginName)).map((si) => ({
1130
+ name: si.data.pluginName,
1131
+ marketplace: si.data.marketplaceName
1132
+ }));
1133
+ if (toInstall.length === 0) {
1134
+ setStatusOverlay({
1135
+ type: "error",
1136
+ message: t("commands.plugin.batchAllAlreadyInstalled")
1137
+ });
1138
+ return;
1139
+ }
1140
+ setPhase({
1141
+ type: "batch-progress",
1142
+ action: "install",
1143
+ plugins: toInstall
1144
+ });
1145
+ } else if (item.id === "batch-update") {
1146
+ const toUpdate = sel.filter((si) => {
1147
+ const pluginName = si.data?.pluginName;
1148
+ return findPluginMarketplace(pluginName) !== void 0;
1149
+ }).map((si) => {
1150
+ const pluginName = si.data.pluginName;
1151
+ return {
1152
+ name: pluginName,
1153
+ marketplace: findPluginMarketplace(pluginName)
1154
+ };
1155
+ });
1156
+ if (toUpdate.length === 0) {
1157
+ setStatusOverlay({
1158
+ type: "error",
1159
+ message: t("commands.plugin.batchNoUpdatable")
1160
+ });
1161
+ return;
1162
+ }
1163
+ setPhase({
1164
+ type: "batch-progress",
1165
+ action: "update",
1166
+ plugins: toUpdate
1167
+ });
1168
+ } else if (item.id === "batch-uninstall") {
1169
+ const toUninstall = sel.map((si) => ({
1170
+ name: si.data.pluginName
1171
+ }));
1172
+ setPhase({
1173
+ type: "batch-progress",
1174
+ action: "uninstall",
1175
+ plugins: toUninstall
1176
+ });
1177
+ } else if (item.id === "batch-enable") {
1178
+ let count = 0;
1179
+ for (const si of sel) {
1180
+ const pluginName = si.data?.pluginName;
1181
+ const plugin2 = installedPlugins.find((p) => p.name === pluginName);
1182
+ if (plugin2 && !plugin2.enabled) {
1183
+ try {
1184
+ enablePlugin(pluginName);
1185
+ count++;
1186
+ } catch {
1187
+ }
1188
+ }
1189
+ }
1190
+ setStatusOverlay({
1191
+ type: "success",
1192
+ message: t("commands.plugin.batchEnabledCount").replace(
1193
+ "{count}",
1194
+ String(count)
1195
+ )
1196
+ });
1197
+ setSelectedIds(/* @__PURE__ */ new Set());
1198
+ } else if (item.id === "batch-disable") {
1199
+ let count = 0;
1200
+ for (const si of sel) {
1201
+ const pluginName = si.data?.pluginName;
1202
+ const plugin2 = installedPlugins.find((p) => p.name === pluginName);
1203
+ if (plugin2 && plugin2.enabled) {
1204
+ try {
1205
+ disablePlugin(pluginName);
1206
+ count++;
1207
+ } catch {
1208
+ }
1209
+ }
1210
+ }
1211
+ setStatusOverlay({
1212
+ type: "success",
1213
+ message: t("commands.plugin.batchDisabledCount").replace(
1214
+ "{count}",
1215
+ String(count)
1216
+ )
1217
+ });
1218
+ setSelectedIds(/* @__PURE__ */ new Set());
1219
+ }
1220
+ break;
558
1221
  }
559
- );
560
- default:
561
- return /* @__PURE__ */ React.createElement(Box, { flexDirection: "column" }, /* @__PURE__ */ React.createElement(Text, { color: "red" }, "Unknown screen state"), /* @__PURE__ */ React.createElement(Text, { color: SEMANTIC_COLORS.dim }, "Press Esc to exit"));
562
- }
1222
+ case "add-marketplace": {
1223
+ setSearchQuery(item.label);
1224
+ break;
1225
+ }
1226
+ }
1227
+ },
1228
+ [phase, activeTab, findPluginMarketplace, installedPlugins, installedNames]
1229
+ );
1230
+ const currentTab = phase.type === "main" ? activeTab : phase.type === "plugin-actions" || phase.type === "marketplace-actions" || phase.type === "batch-action-picker" ? "actions" : phase.type === "batch-progress" ? "progress" : "add";
1231
+ return /* @__PURE__ */ React.createElement(
1232
+ TabbedListView,
1233
+ {
1234
+ title,
1235
+ tabs,
1236
+ activeTab: currentTab,
1237
+ onTabChange: handleTabChange,
1238
+ items,
1239
+ searchEnabled,
1240
+ searchPlaceholder,
1241
+ searchQuery,
1242
+ onSearchChange: setSearchQuery,
1243
+ onSearchSubmit: phase.type === "add-marketplace" ? handleSearchSubmit : void 0,
1244
+ onSelect: handleSelect,
1245
+ onClose: handleClose,
1246
+ onBack: handleBack,
1247
+ statusOverlay,
1248
+ footerHint,
1249
+ groupByCategory: activeTab === "browse" || activeTab === "installed",
1250
+ statusDismissHint: "Enter Continue \xB7 Esc Back",
1251
+ multiSelect: multiSelectEnabled,
1252
+ selectedIds,
1253
+ onSelectionChange: handleSelectionChange,
1254
+ onMultiSelect: handleMultiSelect,
1255
+ multiSelectActionLabel
1256
+ }
1257
+ );
563
1258
  };
564
1259
  const LegacyPluginCommand = ({
565
1260
  args,
@@ -575,7 +1270,7 @@ const LegacyPluginCommand = ({
575
1270
  }
576
1271
  }, [subcommand, onDone]);
577
1272
  if (!subcommand || subcommand === "help" || subcommand === "--help") {
578
- return /* @__PURE__ */ React.createElement(Box, { flexDirection: "column" }, /* @__PURE__ */ React.createElement(Text, { bold: true, underline: true, color: theme.primary }, "Plugin Management Commands"), /* @__PURE__ */ React.createElement(Text, null, ""), /* @__PURE__ */ React.createElement(Text, null, /* @__PURE__ */ React.createElement(Text, { color: theme.success }, "/plugin list"), " - List all installed plugins"), /* @__PURE__ */ React.createElement(Text, null, /* @__PURE__ */ React.createElement(Text, { color: theme.success }, "/plugin info <name>"), " - Show detailed plugin information"), /* @__PURE__ */ React.createElement(Text, null, /* @__PURE__ */ React.createElement(Text, { color: theme.success }, "/plugin install <name>[@marketplace]"), " ", "- Install plugin from marketplace"), /* @__PURE__ */ React.createElement(Text, null, /* @__PURE__ */ React.createElement(Text, { color: theme.success }, "/plugin uninstall <name>"), " - Remove installed plugin"), /* @__PURE__ */ React.createElement(Text, null, /* @__PURE__ */ React.createElement(Text, { color: theme.success }, "/plugin validate [name]"), " - Validate plugin manifest and components"), /* @__PURE__ */ React.createElement(Text, null, ""), /* @__PURE__ */ React.createElement(Text, { bold: true, color: theme.primary }, "Marketplace Commands:"), /* @__PURE__ */ React.createElement(Text, null, /* @__PURE__ */ React.createElement(Text, { color: theme.success }, "/plugin marketplace add <source>"), " ", "- Register new marketplace"), /* @__PURE__ */ React.createElement(Text, null, /* @__PURE__ */ React.createElement(Text, { color: theme.success }, "/plugin marketplace list"), " - List registered marketplaces"), /* @__PURE__ */ React.createElement(Text, null, /* @__PURE__ */ React.createElement(Text, { color: theme.success }, "/plugin marketplace update <name>"), " ", "- Update marketplace manifest"), /* @__PURE__ */ React.createElement(Text, null, /* @__PURE__ */ React.createElement(Text, { color: theme.success }, "/plugin marketplace remove <name>"), " ", "- Unregister marketplace"), /* @__PURE__ */ React.createElement(Text, null, ""), /* @__PURE__ */ React.createElement(Text, { color: SEMANTIC_COLORS.dim }, "Examples:"), /* @__PURE__ */ React.createElement(Text, { color: SEMANTIC_COLORS.dim }, " /plugin list"), /* @__PURE__ */ React.createElement(Text, { color: SEMANTIC_COLORS.dim }, " /plugin info my-plugin"), /* @__PURE__ */ React.createElement(Text, { color: SEMANTIC_COLORS.dim }, " ", "/plugin install awesome-plugin@official"), /* @__PURE__ */ React.createElement(Text, { color: SEMANTIC_COLORS.dim }, " ", "/plugin marketplace add owner/repo"));
1273
+ return /* @__PURE__ */ React.createElement(Box, { flexDirection: "column" }, /* @__PURE__ */ React.createElement(Text, { bold: true, underline: true, color: theme.primary }, "Plugin Management Commands"), /* @__PURE__ */ React.createElement(Text, null, ""), /* @__PURE__ */ React.createElement(Text, null, /* @__PURE__ */ React.createElement(Text, { color: theme.success }, "/plugin list"), " - List all installed plugins"), /* @__PURE__ */ React.createElement(Text, null, /* @__PURE__ */ React.createElement(Text, { color: theme.success }, "/plugin info <name>"), " - Show detailed plugin information"), /* @__PURE__ */ React.createElement(Text, null, /* @__PURE__ */ React.createElement(Text, { color: theme.success }, "/plugin install <name>[@marketplace]"), " ", "- Install plugin from marketplace"), /* @__PURE__ */ React.createElement(Text, null, /* @__PURE__ */ React.createElement(Text, { color: theme.success }, "/plugin uninstall <name>"), " - Remove installed plugin"), /* @__PURE__ */ React.createElement(Text, null, /* @__PURE__ */ React.createElement(Text, { color: theme.success }, "/plugin validate [name]"), " - Validate plugin manifest and components"), /* @__PURE__ */ React.createElement(Text, null, /* @__PURE__ */ React.createElement(Text, { color: theme.success }, "/plugin sync [--force] [--clean] [--dry-run]"), " ", "- ", t("commands.plugin.syncDesc")), /* @__PURE__ */ React.createElement(Text, null, ""), /* @__PURE__ */ React.createElement(Text, { bold: true, color: theme.primary }, "Marketplace Commands:"), /* @__PURE__ */ React.createElement(Text, null, /* @__PURE__ */ React.createElement(Text, { color: theme.success }, "/plugin marketplace add <source>"), " ", "- Register new marketplace"), /* @__PURE__ */ React.createElement(Text, null, /* @__PURE__ */ React.createElement(Text, { color: theme.success }, "/plugin marketplace list"), " - List registered marketplaces"), /* @__PURE__ */ React.createElement(Text, null, /* @__PURE__ */ React.createElement(Text, { color: theme.success }, "/plugin marketplace update <name>"), " ", "- Update marketplace manifest"), /* @__PURE__ */ React.createElement(Text, null, /* @__PURE__ */ React.createElement(Text, { color: theme.success }, "/plugin marketplace remove <name>"), " ", "- Unregister marketplace"), /* @__PURE__ */ React.createElement(Text, null, ""), /* @__PURE__ */ React.createElement(Text, { color: SEMANTIC_COLORS.dim }, "Examples:"), /* @__PURE__ */ React.createElement(Text, { color: SEMANTIC_COLORS.dim }, " /plugin list"), /* @__PURE__ */ React.createElement(Text, { color: SEMANTIC_COLORS.dim }, " /plugin info my-plugin"), /* @__PURE__ */ React.createElement(Text, { color: SEMANTIC_COLORS.dim }, " ", "/plugin install awesome-plugin@official"), /* @__PURE__ */ React.createElement(Text, { color: SEMANTIC_COLORS.dim }, " ", "/plugin marketplace add owner/repo"));
579
1274
  }
580
1275
  switch (subcommand) {
581
1276
  case "list":
@@ -615,6 +1310,16 @@ const LegacyPluginCommand = ({
615
1310
  return /* @__PURE__ */ React.createElement(PluginUninstall, { pluginName: subArgs[0], onDone });
616
1311
  case "validate":
617
1312
  return /* @__PURE__ */ React.createElement(PluginValidate, { pluginName: subArgs[0], onDone });
1313
+ case "sync":
1314
+ return /* @__PURE__ */ React.createElement(
1315
+ PluginSync,
1316
+ {
1317
+ onDone,
1318
+ force: subArgs.includes("--force"),
1319
+ clean: subArgs.includes("--clean"),
1320
+ dryRun: subArgs.includes("--dry-run")
1321
+ }
1322
+ );
618
1323
  case "marketplace":
619
1324
  const marketplaceSubcommand = subArgs[0];
620
1325
  const marketplaceArgs = subArgs.slice(1);
@@ -689,6 +1394,7 @@ const plugin = {
689
1394
  description: "Manage plugins and plugin marketplaces (interactive)",
690
1395
  isEnabled: true,
691
1396
  isHidden: false,
1397
+ hidePromptInput: true,
692
1398
  aliases: ["plugins"],
693
1399
  async call(onDone, _context) {
694
1400
  return /* @__PURE__ */ React.createElement(PluginCommand, { args: "", onDone });