@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
@@ -0,0 +1,29 @@
1
+ import { useEffect, useState } from "react";
2
+ import {
3
+ BackgroundShellManager
4
+ } from "../utils/BackgroundShellManager.js";
5
+ function useBackgroundShells() {
6
+ const [shells, setShells] = useState([]);
7
+ const [isPanelVisible, setIsPanelVisible] = useState(false);
8
+ useEffect(() => {
9
+ const manager = BackgroundShellManager.getInstance();
10
+ setShells(manager.list());
11
+ const handleListChange = (updated) => {
12
+ setShells(updated);
13
+ };
14
+ manager.on("listChange", handleListChange);
15
+ return () => {
16
+ manager.off("listChange", handleListChange);
17
+ };
18
+ }, []);
19
+ return {
20
+ shells,
21
+ isPanelVisible,
22
+ setIsPanelVisible,
23
+ runningCount: shells.filter((s) => s.status === "running").length
24
+ };
25
+ }
26
+ export {
27
+ useBackgroundShells
28
+ };
29
+ //# sourceMappingURL=useBackgroundShells.js.map
@@ -0,0 +1,7 @@
1
+ {
2
+ "version": 3,
3
+ "sources": ["../../src/hooks/useBackgroundShells.ts"],
4
+ "sourcesContent": ["/**\n * Manages background shell state via event-driven subscription.\n * Replaces inline state + effect in REPL.tsx.\n */\nimport { useEffect, useState } from 'react'\nimport {\n BackgroundShellManager,\n type BackgroundShell,\n} from '@utils/BackgroundShellManager'\n\nexport function useBackgroundShells() {\n const [shells, setShells] = useState<BackgroundShell[]>([])\n const [isPanelVisible, setIsPanelVisible] = useState(false)\n\n useEffect(() => {\n const manager = BackgroundShellManager.getInstance()\n setShells(manager.list())\n\n const handleListChange = (updated: BackgroundShell[]) => {\n setShells(updated)\n }\n manager.on('listChange', handleListChange)\n\n return () => {\n manager.off('listChange', handleListChange)\n }\n }, [])\n\n return {\n shells,\n isPanelVisible,\n setIsPanelVisible,\n runningCount: shells.filter(s => s.status === 'running').length,\n }\n}\n"],
5
+ "mappings": "AAIA,SAAS,WAAW,gBAAgB;AACpC;AAAA,EACE;AAAA,OAEK;AAEA,SAAS,sBAAsB;AACpC,QAAM,CAAC,QAAQ,SAAS,IAAI,SAA4B,CAAC,CAAC;AAC1D,QAAM,CAAC,gBAAgB,iBAAiB,IAAI,SAAS,KAAK;AAE1D,YAAU,MAAM;AACd,UAAM,UAAU,uBAAuB,YAAY;AACnD,cAAU,QAAQ,KAAK,CAAC;AAExB,UAAM,mBAAmB,CAAC,YAA+B;AACvD,gBAAU,OAAO;AAAA,IACnB;AACA,YAAQ,GAAG,cAAc,gBAAgB;AAEzC,WAAO,MAAM;AACX,cAAQ,IAAI,cAAc,gBAAgB;AAAA,IAC5C;AAAA,EACF,GAAG,CAAC,CAAC;AAEL,SAAO;AAAA,IACL;AAAA,IACA;AAAA,IACA;AAAA,IACA,cAAc,OAAO,OAAO,OAAK,EAAE,WAAW,SAAS,EAAE;AAAA,EAC3D;AACF;",
6
+ "names": []
7
+ }
@@ -22,7 +22,7 @@ function useCanUseTool(setToolUseConfirm) {
22
22
  if (toolUseContext.abortController.signal.aborted) {
23
23
  logCancelledEvent();
24
24
  resolveWithCancelledAndAbortAllToolCalls();
25
- return;
25
+ return void 0;
26
26
  }
27
27
  return hasPermissionsToUseTool(
28
28
  tool,
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../../src/hooks/useCanUseTool.ts"],
4
- "sourcesContent": ["import React, { useCallback } from 'react'\nimport { hasPermissionsToUseTool } from '@permissions'\nimport { BashTool, inputSchema } from '@tools/BashTool/BashTool'\nimport { getCommandSubcommandPrefix } from '@utils/commands'\nimport { REJECT_MESSAGE } from '@utils/messages'\nimport type { Tool as ToolType, ToolUseContext } from '@tool'\nimport { getToolDescriptionAsync } from '@tool'\nimport { AssistantMessage } from '@query'\nimport { ToolUseConfirm } from '@components/permissions/PermissionRequest'\nimport { AbortError } from '@utils/errors'\nimport { logError } from '@utils/log'\n\ntype SetState<T> = React.Dispatch<React.SetStateAction<T>>\n\nexport type CanUseToolFn = (\n tool: ToolType,\n input: { [key: string]: unknown },\n toolUseContext: ToolUseContext,\n assistantMessage: AssistantMessage,\n) => Promise<{ result: true } | { result: false; message: string }>\n\nfunction useCanUseTool(\n setToolUseConfirm: SetState<ToolUseConfirm | null>,\n): CanUseToolFn {\n return useCallback<CanUseToolFn>(\n async (tool, input, toolUseContext, assistantMessage) => {\n return new Promise(resolve => {\n function logCancelledEvent() {}\n\n function resolveWithCancelledAndAbortAllToolCalls() {\n resolve({\n result: false,\n message: REJECT_MESSAGE,\n })\n // Trigger a synthetic assistant message in query(), to cancel\n // any other pending tool uses and stop further requests to the\n // API and wait for user input.\n toolUseContext.abortController.abort()\n }\n\n if (toolUseContext.abortController.signal.aborted) {\n logCancelledEvent()\n resolveWithCancelledAndAbortAllToolCalls()\n return\n }\n\n return hasPermissionsToUseTool(\n tool,\n input,\n toolUseContext,\n assistantMessage,\n )\n .then(async result => {\n // Has permissions to use tool, granted in config\n if (result.result) {\n resolve({ result: true })\n return\n }\n\n const [description, commandPrefix] = await Promise.all([\n // Use getToolDescriptionAsync for safe async access\n getToolDescriptionAsync(tool, input),\n tool === BashTool\n ? getCommandSubcommandPrefix(\n inputSchema.parse(input).command, // already validated upstream, so ok to parse (as opposed to safeParse)\n toolUseContext.abortController.signal,\n )\n : Promise.resolve(null),\n ])\n\n if (toolUseContext.abortController.signal.aborted) {\n logCancelledEvent()\n resolveWithCancelledAndAbortAllToolCalls()\n return\n }\n\n // Does not have permissions to use tool, ask the user\n setToolUseConfirm({\n assistantMessage,\n tool,\n description,\n input,\n commandPrefix,\n riskScore: null,\n onAbort() {\n logCancelledEvent()\n resolveWithCancelledAndAbortAllToolCalls()\n },\n onAllow(type) {\n if (type === 'permanent') {\n } else {\n }\n resolve({ result: true })\n },\n onReject() {\n resolveWithCancelledAndAbortAllToolCalls()\n },\n })\n })\n .catch(error => {\n if (error instanceof AbortError) {\n logCancelledEvent()\n resolveWithCancelledAndAbortAllToolCalls()\n } else {\n logError(error)\n }\n })\n })\n },\n [setToolUseConfirm],\n )\n}\n\nexport default useCanUseTool\n"],
5
- "mappings": "AAAA,SAAgB,mBAAmB;AACnC,SAAS,+BAA+B;AACxC,SAAS,UAAU,mBAAmB;AACtC,SAAS,kCAAkC;AAC3C,SAAS,sBAAsB;AAE/B,SAAS,+BAA+B;AAGxC,SAAS,kBAAkB;AAC3B,SAAS,gBAAgB;AAWzB,SAAS,cACP,mBACc;AACd,SAAO;AAAA,IACL,OAAO,MAAM,OAAO,gBAAgB,qBAAqB;AACvD,aAAO,IAAI,QAAQ,aAAW;AAC5B,iBAAS,oBAAoB;AAAA,QAAC;AAE9B,iBAAS,2CAA2C;AAClD,kBAAQ;AAAA,YACN,QAAQ;AAAA,YACR,SAAS;AAAA,UACX,CAAC;AAID,yBAAe,gBAAgB,MAAM;AAAA,QACvC;AAEA,YAAI,eAAe,gBAAgB,OAAO,SAAS;AACjD,4BAAkB;AAClB,mDAAyC;AACzC;AAAA,QACF;AAEA,eAAO;AAAA,UACL;AAAA,UACA;AAAA,UACA;AAAA,UACA;AAAA,QACF,EACG,KAAK,OAAM,WAAU;AAEpB,cAAI,OAAO,QAAQ;AACjB,oBAAQ,EAAE,QAAQ,KAAK,CAAC;AACxB;AAAA,UACF;AAEA,gBAAM,CAAC,aAAa,aAAa,IAAI,MAAM,QAAQ,IAAI;AAAA;AAAA,YAErD,wBAAwB,MAAM,KAAK;AAAA,YACnC,SAAS,WACL;AAAA,cACE,YAAY,MAAM,KAAK,EAAE;AAAA;AAAA,cACzB,eAAe,gBAAgB;AAAA,YACjC,IACA,QAAQ,QAAQ,IAAI;AAAA,UAC1B,CAAC;AAED,cAAI,eAAe,gBAAgB,OAAO,SAAS;AACjD,8BAAkB;AAClB,qDAAyC;AACzC;AAAA,UACF;AAGA,4BAAkB;AAAA,YAChB;AAAA,YACA;AAAA,YACA;AAAA,YACA;AAAA,YACA;AAAA,YACA,WAAW;AAAA,YACX,UAAU;AACR,gCAAkB;AAClB,uDAAyC;AAAA,YAC3C;AAAA,YACA,QAAQ,MAAM;AACZ,kBAAI,SAAS,aAAa;AAAA,cAC1B,OAAO;AAAA,cACP;AACA,sBAAQ,EAAE,QAAQ,KAAK,CAAC;AAAA,YAC1B;AAAA,YACA,WAAW;AACT,uDAAyC;AAAA,YAC3C;AAAA,UACF,CAAC;AAAA,QACH,CAAC,EACA,MAAM,WAAS;AACd,cAAI,iBAAiB,YAAY;AAC/B,8BAAkB;AAClB,qDAAyC;AAAA,UAC3C,OAAO;AACL,qBAAS,KAAK;AAAA,UAChB;AAAA,QACF,CAAC;AAAA,MACL,CAAC;AAAA,IACH;AAAA,IACA,CAAC,iBAAiB;AAAA,EACpB;AACF;AAEA,IAAO,wBAAQ;",
4
+ "sourcesContent": ["import React, { useCallback } from 'react'\nimport { hasPermissionsToUseTool } from '@permissions'\nimport { BashTool, inputSchema } from '@tools/BashTool/BashTool'\nimport { getCommandSubcommandPrefix } from '@utils/commands'\nimport { REJECT_MESSAGE } from '@utils/messages'\nimport type { Tool as ToolType, ToolUseContext } from '@tool'\nimport { getToolDescriptionAsync } from '@tool'\nimport { AssistantMessage } from '@query'\nimport { ToolUseConfirm } from '@components/permissions/PermissionRequest'\nimport { AbortError } from '@utils/errors'\nimport { logError } from '@utils/log'\n\ntype SetState<T> = React.Dispatch<React.SetStateAction<T>>\n\nexport type CanUseToolFn = (\n tool: ToolType,\n input: { [key: string]: unknown },\n toolUseContext: ToolUseContext,\n assistantMessage: AssistantMessage,\n) => Promise<{ result: true } | { result: false; message: string }>\n\nfunction useCanUseTool(\n setToolUseConfirm: SetState<ToolUseConfirm | null>,\n): CanUseToolFn {\n return useCallback<CanUseToolFn>(\n async (tool, input, toolUseContext, assistantMessage) => {\n return new Promise(resolve => {\n function logCancelledEvent() {}\n\n function resolveWithCancelledAndAbortAllToolCalls() {\n resolve({\n result: false,\n message: REJECT_MESSAGE,\n })\n // Trigger a synthetic assistant message in query(), to cancel\n // any other pending tool uses and stop further requests to the\n // API and wait for user input.\n toolUseContext.abortController.abort()\n }\n\n if (toolUseContext.abortController.signal.aborted) {\n logCancelledEvent()\n resolveWithCancelledAndAbortAllToolCalls()\n return undefined\n }\n\n return hasPermissionsToUseTool(\n tool,\n input,\n toolUseContext,\n assistantMessage,\n )\n .then(async result => {\n // Has permissions to use tool, granted in config\n if (result.result) {\n resolve({ result: true })\n return\n }\n\n const [description, commandPrefix] = await Promise.all([\n // Use getToolDescriptionAsync for safe async access\n getToolDescriptionAsync(tool, input),\n tool === BashTool\n ? getCommandSubcommandPrefix(\n inputSchema.parse(input).command, // already validated upstream, so ok to parse (as opposed to safeParse)\n toolUseContext.abortController.signal,\n )\n : Promise.resolve(null),\n ])\n\n if (toolUseContext.abortController.signal.aborted) {\n logCancelledEvent()\n resolveWithCancelledAndAbortAllToolCalls()\n return\n }\n\n // Does not have permissions to use tool, ask the user\n setToolUseConfirm({\n assistantMessage,\n tool,\n description,\n input,\n commandPrefix,\n riskScore: null,\n onAbort() {\n logCancelledEvent()\n resolveWithCancelledAndAbortAllToolCalls()\n },\n onAllow(type) {\n if (type === 'permanent') {\n } else {\n }\n resolve({ result: true })\n },\n onReject() {\n resolveWithCancelledAndAbortAllToolCalls()\n },\n })\n })\n .catch(error => {\n if (error instanceof AbortError) {\n logCancelledEvent()\n resolveWithCancelledAndAbortAllToolCalls()\n } else {\n logError(error)\n }\n })\n })\n },\n [setToolUseConfirm],\n )\n}\n\nexport default useCanUseTool\n"],
5
+ "mappings": "AAAA,SAAgB,mBAAmB;AACnC,SAAS,+BAA+B;AACxC,SAAS,UAAU,mBAAmB;AACtC,SAAS,kCAAkC;AAC3C,SAAS,sBAAsB;AAE/B,SAAS,+BAA+B;AAGxC,SAAS,kBAAkB;AAC3B,SAAS,gBAAgB;AAWzB,SAAS,cACP,mBACc;AACd,SAAO;AAAA,IACL,OAAO,MAAM,OAAO,gBAAgB,qBAAqB;AACvD,aAAO,IAAI,QAAQ,aAAW;AAC5B,iBAAS,oBAAoB;AAAA,QAAC;AAE9B,iBAAS,2CAA2C;AAClD,kBAAQ;AAAA,YACN,QAAQ;AAAA,YACR,SAAS;AAAA,UACX,CAAC;AAID,yBAAe,gBAAgB,MAAM;AAAA,QACvC;AAEA,YAAI,eAAe,gBAAgB,OAAO,SAAS;AACjD,4BAAkB;AAClB,mDAAyC;AACzC,iBAAO;AAAA,QACT;AAEA,eAAO;AAAA,UACL;AAAA,UACA;AAAA,UACA;AAAA,UACA;AAAA,QACF,EACG,KAAK,OAAM,WAAU;AAEpB,cAAI,OAAO,QAAQ;AACjB,oBAAQ,EAAE,QAAQ,KAAK,CAAC;AACxB;AAAA,UACF;AAEA,gBAAM,CAAC,aAAa,aAAa,IAAI,MAAM,QAAQ,IAAI;AAAA;AAAA,YAErD,wBAAwB,MAAM,KAAK;AAAA,YACnC,SAAS,WACL;AAAA,cACE,YAAY,MAAM,KAAK,EAAE;AAAA;AAAA,cACzB,eAAe,gBAAgB;AAAA,YACjC,IACA,QAAQ,QAAQ,IAAI;AAAA,UAC1B,CAAC;AAED,cAAI,eAAe,gBAAgB,OAAO,SAAS;AACjD,8BAAkB;AAClB,qDAAyC;AACzC;AAAA,UACF;AAGA,4BAAkB;AAAA,YAChB;AAAA,YACA;AAAA,YACA;AAAA,YACA;AAAA,YACA;AAAA,YACA,WAAW;AAAA,YACX,UAAU;AACR,gCAAkB;AAClB,uDAAyC;AAAA,YAC3C;AAAA,YACA,QAAQ,MAAM;AACZ,kBAAI,SAAS,aAAa;AAAA,cAC1B,OAAO;AAAA,cACP;AACA,sBAAQ,EAAE,QAAQ,KAAK,CAAC;AAAA,YAC1B;AAAA,YACA,WAAW;AACT,uDAAyC;AAAA,YAC3C;AAAA,UACF,CAAC;AAAA,QACH,CAAC,EACA,MAAM,WAAS;AACd,cAAI,iBAAiB,YAAY;AAC/B,8BAAkB;AAClB,qDAAyC;AAAA,UAC3C,OAAO;AACL,qBAAS,KAAK;AAAA,UAChB;AAAA,QACF,CAAC;AAAA,MACL,CAAC;AAAA,IACH;AAAA,IACA,CAAC,iBAAiB;AAAA,EACpB;AACF;AAEA,IAAO,wBAAQ;",
6
6
  "names": []
7
7
  }
@@ -0,0 +1,64 @@
1
+ import { useEffect, useState } from "react";
2
+ import { getClients } from "../services/mcpClient.js";
3
+ import { getTools } from "../tools.js";
4
+ import { getCommands } from "../commands.js";
5
+ import { getLatestVersion, getUpdateCommandSuggestions } from "../utils/autoUpdater.js";
6
+ import { gt } from "semver";
7
+ import { MACRO } from "../constants/macros.js";
8
+ import { useStartupStatus } from "../components/StartupStatus.js";
9
+ function useDeferredLoading(options) {
10
+ const [commands, setCommands] = useState(options.initialCommands);
11
+ const [tools, setTools] = useState(options.initialTools);
12
+ const [mcpClients, setMcpClients] = useState(
13
+ options.initialMcpClients
14
+ );
15
+ const [updateVersion, setUpdateVersion] = useState(
16
+ options.initialUpdateVersion ?? null
17
+ );
18
+ const [updateCommands, setUpdateCommands] = useState(
19
+ options.initialUpdateCommands ?? null
20
+ );
21
+ const { items: startupItems, update: updateStartup } = useStartupStatus([
22
+ { id: "mcp", label: "MCP servers" },
23
+ { id: "version", label: "Version check" }
24
+ ]);
25
+ useEffect(() => {
26
+ Promise.all([getClients(), getTools(options.enableArchitect)]).then(([clients, fullTools]) => {
27
+ setMcpClients(clients);
28
+ setTools(fullTools);
29
+ const connected = clients.filter((c) => c.type === "connected").length;
30
+ updateStartup("mcp", "done", `${connected}/${clients.length} connected`);
31
+ }).catch(() => {
32
+ updateStartup("mcp", "error", "connection failed");
33
+ });
34
+ getLatestVersion().then((latest) => {
35
+ if (latest && gt(latest, MACRO.VERSION)) {
36
+ getUpdateCommandSuggestions().then((cmds) => {
37
+ setUpdateVersion(latest);
38
+ setUpdateCommands(cmds);
39
+ updateStartup("version", "done", `v${latest} available`);
40
+ });
41
+ } else {
42
+ updateStartup("version", "done", "up to date");
43
+ }
44
+ }).catch(() => {
45
+ updateStartup("version", "done");
46
+ });
47
+ getCommands().then((fullCommands) => {
48
+ setCommands(fullCommands);
49
+ }).catch(() => {
50
+ });
51
+ }, []);
52
+ return {
53
+ commands,
54
+ tools,
55
+ mcpClients,
56
+ updateVersion,
57
+ updateCommands,
58
+ startupItems
59
+ };
60
+ }
61
+ export {
62
+ useDeferredLoading
63
+ };
64
+ //# sourceMappingURL=useDeferredLoading.js.map
@@ -0,0 +1,7 @@
1
+ {
2
+ "version": 3,
3
+ "sources": ["../../src/hooks/useDeferredLoading.ts"],
4
+ "sourcesContent": ["/**\n * Deferred loading of MCP clients, tools, commands, and version check.\n * Runs in background after mount so the REPL renders immediately.\n */\nimport { useEffect, useState } from 'react'\nimport type { Command } from '@commands'\nimport type { Tool } from '@tool'\nimport type { WrappedClient } from '@services/mcpClient'\nimport { getClients } from '@services/mcpClient'\nimport { getTools } from '@tools'\nimport { getCommands } from '@commands'\nimport { getLatestVersion, getUpdateCommandSuggestions } from '@utils/autoUpdater'\nimport { gt } from 'semver'\nimport { MACRO } from '@constants/macros'\nimport { useStartupStatus } from '@components/StartupStatus'\n\ninterface DeferredLoadingOptions {\n initialCommands: Command[]\n initialTools: Tool[]\n initialMcpClients: WrappedClient[]\n initialUpdateVersion?: string | null\n initialUpdateCommands?: string[] | null\n enableArchitect?: boolean\n}\n\nexport function useDeferredLoading(options: DeferredLoadingOptions) {\n const [commands, setCommands] = useState<Command[]>(options.initialCommands)\n const [tools, setTools] = useState<Tool[]>(options.initialTools)\n const [mcpClients, setMcpClients] = useState<WrappedClient[]>(\n options.initialMcpClients,\n )\n const [updateVersion, setUpdateVersion] = useState<string | null>(\n options.initialUpdateVersion ?? null,\n )\n const [updateCommands, setUpdateCommands] = useState<string[] | null>(\n options.initialUpdateCommands ?? null,\n )\n\n const { items: startupItems, update: updateStartup } = useStartupStatus([\n { id: 'mcp', label: 'MCP servers' },\n { id: 'version', label: 'Version check' },\n ])\n\n useEffect(() => {\n // 1. MCP clients + full tools (including MCP tools)\n Promise.all([getClients(), getTools(options.enableArchitect)])\n .then(([clients, fullTools]) => {\n setMcpClients(clients)\n setTools(fullTools)\n const connected = clients.filter(c => c.type === 'connected').length\n updateStartup('mcp', 'done', `${connected}/${clients.length} connected`)\n })\n .catch(() => {\n updateStartup('mcp', 'error', 'connection failed')\n })\n\n // 2. Version check\n getLatestVersion()\n .then(latest => {\n if (latest && gt(latest, MACRO.VERSION)) {\n getUpdateCommandSuggestions().then(cmds => {\n setUpdateVersion(latest)\n setUpdateCommands(cmds)\n updateStartup('version', 'done', `v${latest} available`)\n })\n } else {\n updateStartup('version', 'done', 'up to date')\n }\n })\n .catch(() => {\n updateStartup('version', 'done') // non-critical, just hide\n })\n\n // 3. Full commands (MCP, custom, plugin)\n getCommands()\n .then(fullCommands => {\n setCommands(fullCommands)\n })\n .catch(() => {\n // Non-critical: built-in commands still work\n })\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, [])\n\n return {\n commands,\n tools,\n mcpClients,\n updateVersion,\n updateCommands,\n startupItems,\n }\n}\n"],
5
+ "mappings": "AAIA,SAAS,WAAW,gBAAgB;AAIpC,SAAS,kBAAkB;AAC3B,SAAS,gBAAgB;AACzB,SAAS,mBAAmB;AAC5B,SAAS,kBAAkB,mCAAmC;AAC9D,SAAS,UAAU;AACnB,SAAS,aAAa;AACtB,SAAS,wBAAwB;AAW1B,SAAS,mBAAmB,SAAiC;AAClE,QAAM,CAAC,UAAU,WAAW,IAAI,SAAoB,QAAQ,eAAe;AAC3E,QAAM,CAAC,OAAO,QAAQ,IAAI,SAAiB,QAAQ,YAAY;AAC/D,QAAM,CAAC,YAAY,aAAa,IAAI;AAAA,IAClC,QAAQ;AAAA,EACV;AACA,QAAM,CAAC,eAAe,gBAAgB,IAAI;AAAA,IACxC,QAAQ,wBAAwB;AAAA,EAClC;AACA,QAAM,CAAC,gBAAgB,iBAAiB,IAAI;AAAA,IAC1C,QAAQ,yBAAyB;AAAA,EACnC;AAEA,QAAM,EAAE,OAAO,cAAc,QAAQ,cAAc,IAAI,iBAAiB;AAAA,IACtE,EAAE,IAAI,OAAO,OAAO,cAAc;AAAA,IAClC,EAAE,IAAI,WAAW,OAAO,gBAAgB;AAAA,EAC1C,CAAC;AAED,YAAU,MAAM;AAEd,YAAQ,IAAI,CAAC,WAAW,GAAG,SAAS,QAAQ,eAAe,CAAC,CAAC,EAC1D,KAAK,CAAC,CAAC,SAAS,SAAS,MAAM;AAC9B,oBAAc,OAAO;AACrB,eAAS,SAAS;AAClB,YAAM,YAAY,QAAQ,OAAO,OAAK,EAAE,SAAS,WAAW,EAAE;AAC9D,oBAAc,OAAO,QAAQ,GAAG,SAAS,IAAI,QAAQ,MAAM,YAAY;AAAA,IACzE,CAAC,EACA,MAAM,MAAM;AACX,oBAAc,OAAO,SAAS,mBAAmB;AAAA,IACnD,CAAC;AAGH,qBAAiB,EACd,KAAK,YAAU;AACd,UAAI,UAAU,GAAG,QAAQ,MAAM,OAAO,GAAG;AACvC,oCAA4B,EAAE,KAAK,UAAQ;AACzC,2BAAiB,MAAM;AACvB,4BAAkB,IAAI;AACtB,wBAAc,WAAW,QAAQ,IAAI,MAAM,YAAY;AAAA,QACzD,CAAC;AAAA,MACH,OAAO;AACL,sBAAc,WAAW,QAAQ,YAAY;AAAA,MAC/C;AAAA,IACF,CAAC,EACA,MAAM,MAAM;AACX,oBAAc,WAAW,MAAM;AAAA,IACjC,CAAC;AAGH,gBAAY,EACT,KAAK,kBAAgB;AACpB,kBAAY,YAAY;AAAA,IAC1B,CAAC,EACA,MAAM,MAAM;AAAA,IAEb,CAAC;AAAA,EAEL,GAAG,CAAC,CAAC;AAEL,SAAO;AAAA,IACL;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,EACF;AACF;",
6
+ "names": []
7
+ }
@@ -15,7 +15,7 @@ function useHookStatus(enabled) {
15
15
  }));
16
16
  }, []);
17
17
  useEffect(() => {
18
- if (!enabled) return;
18
+ if (!enabled) return void 0;
19
19
  hookStatusEmitter.on("status", handleStatus);
20
20
  return () => {
21
21
  hookStatusEmitter.off("status", handleStatus);
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../../src/hooks/useHookStatus.ts"],
4
- "sourcesContent": ["/**\n * Hook Status Tracking for Verbose Mode\n *\n * Listens to hookStatusEmitter and provides status information\n * for display in verbose mode.\n */\n\nimport { useState, useEffect, useCallback } from 'react'\nimport { hookStatusEmitter, HookStatusEvent } from '@services/hookExecutor'\n\ninterface HookStatusState {\n /** Recent hook events (last 10) */\n recentEvents: HookStatusEvent[]\n /** Count of successful hooks */\n successCount: number\n /** Count of failed hooks */\n failureCount: number\n}\n\n/**\n * Hook to track hook status events for verbose mode display\n *\n * @param enabled - Whether to listen for events (should be verbose mode)\n * @returns Hook status state\n */\nexport function useHookStatus(enabled: boolean): HookStatusState {\n const [state, setState] = useState<HookStatusState>({\n recentEvents: [],\n successCount: 0,\n failureCount: 0,\n })\n\n const handleStatus = useCallback((event: HookStatusEvent) => {\n setState(prev => ({\n recentEvents: [...prev.recentEvents.slice(-9), event], // Keep last 10\n successCount: prev.successCount + (event.success ? 1 : 0),\n failureCount: prev.failureCount + (event.success ? 0 : 1),\n }))\n }, [])\n\n useEffect(() => {\n if (!enabled) return\n\n hookStatusEmitter.on('status', handleStatus)\n return () => {\n hookStatusEmitter.off('status', handleStatus)\n }\n }, [enabled, handleStatus])\n\n return state\n}\n\n/**\n * Format hook status for display\n */\nexport function formatHookStatus(event: HookStatusEvent): string {\n const timestamp = new Date(event.timestamp).toLocaleTimeString('en-US', {\n hour: 'numeric',\n minute: '2-digit',\n second: '2-digit',\n hour12: true,\n })\n const status = event.success ? '\u2713' : '\u2717'\n return `${timestamp} ${status} ${event.message}`\n}\n"],
5
- "mappings": "AAOA,SAAS,UAAU,WAAW,mBAAmB;AACjD,SAAS,yBAA0C;AAiB5C,SAAS,cAAc,SAAmC;AAC/D,QAAM,CAAC,OAAO,QAAQ,IAAI,SAA0B;AAAA,IAClD,cAAc,CAAC;AAAA,IACf,cAAc;AAAA,IACd,cAAc;AAAA,EAChB,CAAC;AAED,QAAM,eAAe,YAAY,CAAC,UAA2B;AAC3D,aAAS,WAAS;AAAA,MAChB,cAAc,CAAC,GAAG,KAAK,aAAa,MAAM,EAAE,GAAG,KAAK;AAAA;AAAA,MACpD,cAAc,KAAK,gBAAgB,MAAM,UAAU,IAAI;AAAA,MACvD,cAAc,KAAK,gBAAgB,MAAM,UAAU,IAAI;AAAA,IACzD,EAAE;AAAA,EACJ,GAAG,CAAC,CAAC;AAEL,YAAU,MAAM;AACd,QAAI,CAAC,QAAS;AAEd,sBAAkB,GAAG,UAAU,YAAY;AAC3C,WAAO,MAAM;AACX,wBAAkB,IAAI,UAAU,YAAY;AAAA,IAC9C;AAAA,EACF,GAAG,CAAC,SAAS,YAAY,CAAC;AAE1B,SAAO;AACT;AAKO,SAAS,iBAAiB,OAAgC;AAC/D,QAAM,YAAY,IAAI,KAAK,MAAM,SAAS,EAAE,mBAAmB,SAAS;AAAA,IACtE,MAAM;AAAA,IACN,QAAQ;AAAA,IACR,QAAQ;AAAA,IACR,QAAQ;AAAA,EACV,CAAC;AACD,QAAM,SAAS,MAAM,UAAU,WAAM;AACrC,SAAO,GAAG,SAAS,IAAI,MAAM,IAAI,MAAM,OAAO;AAChD;",
4
+ "sourcesContent": ["/**\n * Hook Status Tracking for Verbose Mode\n *\n * Listens to hookStatusEmitter and provides status information\n * for display in verbose mode.\n */\n\nimport { useState, useEffect, useCallback } from 'react'\nimport { hookStatusEmitter, HookStatusEvent } from '@services/hookExecutor'\n\ninterface HookStatusState {\n /** Recent hook events (last 10) */\n recentEvents: HookStatusEvent[]\n /** Count of successful hooks */\n successCount: number\n /** Count of failed hooks */\n failureCount: number\n}\n\n/**\n * Hook to track hook status events for verbose mode display\n *\n * @param enabled - Whether to listen for events (should be verbose mode)\n * @returns Hook status state\n */\nexport function useHookStatus(enabled: boolean): HookStatusState {\n const [state, setState] = useState<HookStatusState>({\n recentEvents: [],\n successCount: 0,\n failureCount: 0,\n })\n\n const handleStatus = useCallback((event: HookStatusEvent) => {\n setState(prev => ({\n recentEvents: [...prev.recentEvents.slice(-9), event], // Keep last 10\n successCount: prev.successCount + (event.success ? 1 : 0),\n failureCount: prev.failureCount + (event.success ? 0 : 1),\n }))\n }, [])\n\n useEffect(() => {\n if (!enabled) return undefined\n\n hookStatusEmitter.on('status', handleStatus)\n return () => {\n hookStatusEmitter.off('status', handleStatus)\n }\n }, [enabled, handleStatus])\n\n return state\n}\n\n/**\n * Format hook status for display\n */\nexport function formatHookStatus(event: HookStatusEvent): string {\n const timestamp = new Date(event.timestamp).toLocaleTimeString('en-US', {\n hour: 'numeric',\n minute: '2-digit',\n second: '2-digit',\n hour12: true,\n })\n const status = event.success ? '\u2713' : '\u2717'\n return `${timestamp} ${status} ${event.message}`\n}\n"],
5
+ "mappings": "AAOA,SAAS,UAAU,WAAW,mBAAmB;AACjD,SAAS,yBAA0C;AAiB5C,SAAS,cAAc,SAAmC;AAC/D,QAAM,CAAC,OAAO,QAAQ,IAAI,SAA0B;AAAA,IAClD,cAAc,CAAC;AAAA,IACf,cAAc;AAAA,IACd,cAAc;AAAA,EAChB,CAAC;AAED,QAAM,eAAe,YAAY,CAAC,UAA2B;AAC3D,aAAS,WAAS;AAAA,MAChB,cAAc,CAAC,GAAG,KAAK,aAAa,MAAM,EAAE,GAAG,KAAK;AAAA;AAAA,MACpD,cAAc,KAAK,gBAAgB,MAAM,UAAU,IAAI;AAAA,MACvD,cAAc,KAAK,gBAAgB,MAAM,UAAU,IAAI;AAAA,IACzD,EAAE;AAAA,EACJ,GAAG,CAAC,CAAC;AAEL,YAAU,MAAM;AACd,QAAI,CAAC,QAAS,QAAO;AAErB,sBAAkB,GAAG,UAAU,YAAY;AAC3C,WAAO,MAAM;AACX,wBAAkB,IAAI,UAAU,YAAY;AAAA,IAC9C;AAAA,EACF,GAAG,CAAC,SAAS,YAAY,CAAC;AAE1B,SAAO;AACT;AAKO,SAAS,iBAAiB,OAAgC;AAC/D,QAAM,YAAY,IAAI,KAAK,MAAM,SAAS,EAAE,mBAAmB,SAAS;AAAA,IACtE,MAAM;AAAA,IACN,QAAQ;AAAA,IACR,QAAQ;AAAA,IACR,QAAQ;AAAA,EACV,CAAC;AACD,QAAM,SAAS,MAAM,UAAU,WAAM;AACrC,SAAO,GAAG,SAAS,IAAI,MAAM,IAAI,MAAM,OAAO;AAChD;",
6
6
  "names": []
7
7
  }
@@ -0,0 +1,55 @@
1
+ import { useEffect, useRef } from "react";
2
+ import { randomUUID } from "crypto";
3
+ import { debug as debugLogger } from "../utils/debugLogger.js";
4
+ import {
5
+ initializeHookManager
6
+ } from "../utils/hookManager.js";
7
+ import { loadAllPlugins } from "../utils/pluginLoader.js";
8
+ import { loadDefaultPlugins } from "../services/plugins/pluginRuntime.js";
9
+ import {
10
+ initSessionTracker,
11
+ flushSessionStats,
12
+ endSession
13
+ } from "../utils/sessionTracker.js";
14
+ import { getOriginalCwd } from "../utils/state.js";
15
+ import { getMessagesPath } from "../utils/log.js";
16
+ function useSessionTracking(messageLogName, forkNumber) {
17
+ const hookManagerRef = useRef(null);
18
+ useEffect(() => {
19
+ loadDefaultPlugins().catch((err) => {
20
+ debugLogger.error("Failed to load session plugins", { error: err });
21
+ });
22
+ }, []);
23
+ useEffect(() => {
24
+ try {
25
+ const plugins = loadAllPlugins();
26
+ const sessionId = randomUUID();
27
+ const transcriptPath = getMessagesPath(messageLogName, forkNumber, 0);
28
+ const hookManager = initializeHookManager(
29
+ sessionId,
30
+ transcriptPath,
31
+ plugins
32
+ );
33
+ hookManagerRef.current = hookManager;
34
+ initSessionTracker(getOriginalCwd());
35
+ hookManager.executeSessionStart().catch((err) => {
36
+ debugLogger.error("SessionStart hooks failed", { error: err });
37
+ });
38
+ return () => {
39
+ flushSessionStats();
40
+ endSession("other");
41
+ hookManager.executeSessionEnd("other").catch((err) => {
42
+ debugLogger.error("SessionEnd hooks failed", { error: err });
43
+ });
44
+ };
45
+ } catch (err) {
46
+ debugLogger.error("Failed to initialize hook manager", { error: err });
47
+ return void 0;
48
+ }
49
+ }, [messageLogName, forkNumber]);
50
+ return { hookManagerRef };
51
+ }
52
+ export {
53
+ useSessionTracking
54
+ };
55
+ //# sourceMappingURL=useSessionTracking.js.map
@@ -0,0 +1,7 @@
1
+ {
2
+ "version": 3,
3
+ "sources": ["../../src/hooks/useSessionTracking.ts"],
4
+ "sourcesContent": ["/**\n * Initializes session tracking, hook manager, and session plugins.\n * Handles session lifecycle (start \u2192 flush stats \u2192 end).\n */\nimport { useEffect, useRef } from 'react'\nimport { randomUUID } from 'crypto'\nimport { debug as debugLogger } from '@utils/debugLogger'\nimport {\n initializeHookManager,\n type HookManager,\n} from '@utils/hookManager'\nimport { loadAllPlugins } from '@utils/pluginLoader'\nimport { loadDefaultPlugins } from '@services/plugins/pluginRuntime'\nimport {\n initSessionTracker,\n flushSessionStats,\n endSession,\n} from '@utils/sessionTracker'\nimport { getOriginalCwd } from '@utils/state'\nimport { getMessagesPath } from '@utils/log'\n\nexport function useSessionTracking(\n messageLogName: string,\n forkNumber: number,\n) {\n const hookManagerRef = useRef<HookManager | null>(null)\n\n // Initialize session plugins\n useEffect(() => {\n loadDefaultPlugins().catch(err => {\n debugLogger.error('Failed to load session plugins', { error: err })\n })\n }, [])\n\n // Initialize hook manager and session tracker\n useEffect(() => {\n try {\n const plugins = loadAllPlugins()\n const sessionId = randomUUID()\n const transcriptPath = getMessagesPath(messageLogName, forkNumber, 0)\n\n const hookManager = initializeHookManager(\n sessionId,\n transcriptPath,\n plugins,\n )\n hookManagerRef.current = hookManager\n\n initSessionTracker(getOriginalCwd())\n\n hookManager.executeSessionStart().catch(err => {\n debugLogger.error('SessionStart hooks failed', { error: err })\n })\n\n return () => {\n flushSessionStats()\n endSession('other')\n\n hookManager.executeSessionEnd('other').catch(err => {\n debugLogger.error('SessionEnd hooks failed', { error: err })\n })\n }\n } catch (err) {\n debugLogger.error('Failed to initialize hook manager', { error: err })\n return undefined\n }\n }, [messageLogName, forkNumber])\n\n return { hookManagerRef }\n}\n"],
5
+ "mappings": "AAIA,SAAS,WAAW,cAAc;AAClC,SAAS,kBAAkB;AAC3B,SAAS,SAAS,mBAAmB;AACrC;AAAA,EACE;AAAA,OAEK;AACP,SAAS,sBAAsB;AAC/B,SAAS,0BAA0B;AACnC;AAAA,EACE;AAAA,EACA;AAAA,EACA;AAAA,OACK;AACP,SAAS,sBAAsB;AAC/B,SAAS,uBAAuB;AAEzB,SAAS,mBACd,gBACA,YACA;AACA,QAAM,iBAAiB,OAA2B,IAAI;AAGtD,YAAU,MAAM;AACd,uBAAmB,EAAE,MAAM,SAAO;AAChC,kBAAY,MAAM,kCAAkC,EAAE,OAAO,IAAI,CAAC;AAAA,IACpE,CAAC;AAAA,EACH,GAAG,CAAC,CAAC;AAGL,YAAU,MAAM;AACd,QAAI;AACF,YAAM,UAAU,eAAe;AAC/B,YAAM,YAAY,WAAW;AAC7B,YAAM,iBAAiB,gBAAgB,gBAAgB,YAAY,CAAC;AAEpE,YAAM,cAAc;AAAA,QAClB;AAAA,QACA;AAAA,QACA;AAAA,MACF;AACA,qBAAe,UAAU;AAEzB,yBAAmB,eAAe,CAAC;AAEnC,kBAAY,oBAAoB,EAAE,MAAM,SAAO;AAC7C,oBAAY,MAAM,6BAA6B,EAAE,OAAO,IAAI,CAAC;AAAA,MAC/D,CAAC;AAED,aAAO,MAAM;AACX,0BAAkB;AAClB,mBAAW,OAAO;AAElB,oBAAY,kBAAkB,OAAO,EAAE,MAAM,SAAO;AAClD,sBAAY,MAAM,2BAA2B,EAAE,OAAO,IAAI,CAAC;AAAA,QAC7D,CAAC;AAAA,MACH;AAAA,IACF,SAAS,KAAK;AACZ,kBAAY,MAAM,qCAAqC,EAAE,OAAO,IAAI,CAAC;AACrE,aAAO;AAAA,IACT;AAAA,EACF,GAAG,CAAC,gBAAgB,UAAU,CAAC;AAE/B,SAAO,EAAE,eAAe;AAC1B;",
6
+ "names": []
7
+ }
@@ -12,6 +12,7 @@ const SIZE_CHANGE_THRESHOLD = 5;
12
12
  let isInClearingCycle = false;
13
13
  let lastSignificantResizeTime = 0;
14
14
  const RESIZE_COOLDOWN_MS = 2e3;
15
+ let pendingResizeTimer = null;
15
16
  function updateAllListeners() {
16
17
  if (debounceTimer) {
17
18
  clearTimeout(debounceTimer);
@@ -34,10 +35,30 @@ function updateAllListeners() {
34
35
  if (isSignificantResize && !isInClearingCycle && isCooldownExpired) {
35
36
  isInClearingCycle = true;
36
37
  lastSignificantResizeTime = now;
38
+ if (pendingResizeTimer) {
39
+ clearTimeout(pendingResizeTimer);
40
+ pendingResizeTimer = null;
41
+ }
37
42
  resizeCallbacks.forEach((callback) => callback());
38
43
  setTimeout(() => {
39
44
  isInClearingCycle = false;
40
45
  }, 500);
46
+ } else if (isSignificantResize && (isInClearingCycle || !isCooldownExpired)) {
47
+ if (pendingResizeTimer) {
48
+ clearTimeout(pendingResizeTimer);
49
+ }
50
+ const remainingCooldown = Math.max(0, RESIZE_COOLDOWN_MS - timeSinceLastResize) + 100;
51
+ pendingResizeTimer = setTimeout(() => {
52
+ pendingResizeTimer = null;
53
+ if (!isInClearingCycle) {
54
+ isInClearingCycle = true;
55
+ lastSignificantResizeTime = Date.now();
56
+ resizeCallbacks.forEach((callback) => callback());
57
+ setTimeout(() => {
58
+ isInClearingCycle = false;
59
+ }, 500);
60
+ }
61
+ }, remainingCooldown);
41
62
  }
42
63
  }
43
64
  debounceTimer = null;
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../../src/hooks/useTerminalSize.ts"],
4
- "sourcesContent": ["import { useEffect, useState, useRef, useCallback } from 'react'\n\n// Global state to share across all hook instances\nlet globalSize = {\n columns: process.stdout.columns || 80,\n rows: process.stdout.rows || 24,\n}\n\nconst listeners = new Set<() => void>()\nlet isListenerAttached = false\nlet debounceTimer: NodeJS.Timeout | null = null\n\n// Callbacks to trigger full re-render when significant resize occurs\nconst resizeCallbacks = new Set<() => void>()\n\n// Debounce delay in ms - prevents rapid-fire re-renders during resize\n// Increased from 150ms to 300ms to better handle window focus transitions\nconst RESIZE_DEBOUNCE_MS = 300\n\n// Threshold for detecting any significant size change (either direction)\n// Any resize > 5 columns should trigger a re-render to prevent ghost artifacts\nconst SIZE_CHANGE_THRESHOLD = 5\n\n// Track if we're currently in a fullscreen exit clearing cycle to prevent re-triggers\nlet isInClearingCycle = false\n\n// Track last significant resize time to prevent rapid re-triggers (e.g., from window focus changes)\nlet lastSignificantResizeTime = 0\nconst RESIZE_COOLDOWN_MS = 2000 // 2 second cooldown between significant resize triggers\n\nfunction updateAllListeners() {\n // Clear any pending debounce\n if (debounceTimer) {\n clearTimeout(debounceTimer)\n }\n\n // Debounce the resize event to prevent multiple rapid re-renders\n debounceTimer = setTimeout(() => {\n const newColumns = process.stdout.columns || 80\n const newRows = process.stdout.rows || 24\n\n // Only update if dimensions actually changed\n if (globalSize.columns !== newColumns || globalSize.rows !== newRows) {\n const oldColumns = globalSize.columns\n\n // Detect if screen size changed significantly (in either direction)\n // This catches both entering and exiting fullscreen, as well as manual window resizing\n const columnDiff = Math.abs(oldColumns - newColumns)\n const isSignificantResize = columnDiff > SIZE_CHANGE_THRESHOLD\n\n globalSize = {\n columns: newColumns,\n rows: newRows,\n }\n listeners.forEach(listener => listener())\n\n // If significant resize and not already in clearing cycle, trigger callbacks\n // The clearing cycle lock prevents multiple triggers during the clear/re-render process\n // Also enforce a cooldown period to prevent rapid re-triggers from window focus changes\n const now = Date.now()\n const timeSinceLastResize = now - lastSignificantResizeTime\n const isCooldownExpired = timeSinceLastResize > RESIZE_COOLDOWN_MS\n\n if (isSignificantResize && !isInClearingCycle && isCooldownExpired) {\n isInClearingCycle = true\n lastSignificantResizeTime = now\n resizeCallbacks.forEach(callback => callback())\n // Release the lock after a delay to allow re-render to complete\n setTimeout(() => {\n isInClearingCycle = false\n }, 500)\n }\n }\n debounceTimer = null\n }, RESIZE_DEBOUNCE_MS)\n}\n\nexport function useTerminalSize() {\n const [size, setSize] = useState(globalSize)\n\n useEffect(() => {\n // Add this component's listener to the set\n const updateSize = () => setSize({ ...globalSize })\n listeners.add(updateSize)\n\n // Only attach the global resize listener once\n if (!isListenerAttached) {\n // Increase max listeners to prevent warnings\n process.stdout.setMaxListeners(20)\n process.stdout.on('resize', updateAllListeners)\n isListenerAttached = true\n }\n\n return () => {\n // Remove this component's listener\n listeners.delete(updateSize)\n\n // If no more listeners, remove the global listener\n if (listeners.size === 0 && isListenerAttached) {\n process.stdout.off('resize', updateAllListeners)\n isListenerAttached = false\n // Clear any pending debounce\n if (debounceTimer) {\n clearTimeout(debounceTimer)\n debounceTimer = null\n }\n }\n }\n }, [])\n\n return size\n}\n\n/**\n * Hook to register a callback that fires when a significant resize occurs.\n * This is detected when the terminal width changes by more than 5 columns.\n * Useful for triggering a full UI re-render to clear ghost artifacts.\n *\n * @deprecated Use useSignificantResizeCallback instead (same function, clearer name)\n */\nexport function useFullscreenExitCallback(callback: () => void) {\n return useSignificantResizeCallback(callback)\n}\n\n/**\n * Hook to register a callback that fires when a significant terminal resize occurs.\n * This is detected when the terminal width changes by more than SIZE_CHANGE_THRESHOLD columns.\n * Useful for triggering a full UI re-render to clear ghost artifacts caused by Ink's\n * differential rendering.\n */\nexport function useSignificantResizeCallback(callback: () => void) {\n const callbackRef = useRef(callback)\n callbackRef.current = callback\n\n useEffect(() => {\n // Ensure the global resize listener is attached\n // This is needed because this hook might be called\n // before any component calls useTerminalSize()\n if (!isListenerAttached) {\n process.stdout.setMaxListeners(20)\n process.stdout.on('resize', updateAllListeners)\n isListenerAttached = true\n }\n\n const wrappedCallback = () => callbackRef.current()\n resizeCallbacks.add(wrappedCallback)\n\n return () => {\n resizeCallbacks.delete(wrappedCallback)\n }\n }, [])\n}\n"],
5
- "mappings": "AAAA,SAAS,WAAW,UAAU,cAA2B;AAGzD,IAAI,aAAa;AAAA,EACf,SAAS,QAAQ,OAAO,WAAW;AAAA,EACnC,MAAM,QAAQ,OAAO,QAAQ;AAC/B;AAEA,MAAM,YAAY,oBAAI,IAAgB;AACtC,IAAI,qBAAqB;AACzB,IAAI,gBAAuC;AAG3C,MAAM,kBAAkB,oBAAI,IAAgB;AAI5C,MAAM,qBAAqB;AAI3B,MAAM,wBAAwB;AAG9B,IAAI,oBAAoB;AAGxB,IAAI,4BAA4B;AAChC,MAAM,qBAAqB;AAE3B,SAAS,qBAAqB;AAE5B,MAAI,eAAe;AACjB,iBAAa,aAAa;AAAA,EAC5B;AAGA,kBAAgB,WAAW,MAAM;AAC/B,UAAM,aAAa,QAAQ,OAAO,WAAW;AAC7C,UAAM,UAAU,QAAQ,OAAO,QAAQ;AAGvC,QAAI,WAAW,YAAY,cAAc,WAAW,SAAS,SAAS;AACpE,YAAM,aAAa,WAAW;AAI9B,YAAM,aAAa,KAAK,IAAI,aAAa,UAAU;AACnD,YAAM,sBAAsB,aAAa;AAEzC,mBAAa;AAAA,QACX,SAAS;AAAA,QACT,MAAM;AAAA,MACR;AACA,gBAAU,QAAQ,cAAY,SAAS,CAAC;AAKxC,YAAM,MAAM,KAAK,IAAI;AACrB,YAAM,sBAAsB,MAAM;AAClC,YAAM,oBAAoB,sBAAsB;AAEhD,UAAI,uBAAuB,CAAC,qBAAqB,mBAAmB;AAClE,4BAAoB;AACpB,oCAA4B;AAC5B,wBAAgB,QAAQ,cAAY,SAAS,CAAC;AAE9C,mBAAW,MAAM;AACf,8BAAoB;AAAA,QACtB,GAAG,GAAG;AAAA,MACR;AAAA,IACF;AACA,oBAAgB;AAAA,EAClB,GAAG,kBAAkB;AACvB;AAEO,SAAS,kBAAkB;AAChC,QAAM,CAAC,MAAM,OAAO,IAAI,SAAS,UAAU;AAE3C,YAAU,MAAM;AAEd,UAAM,aAAa,MAAM,QAAQ,EAAE,GAAG,WAAW,CAAC;AAClD,cAAU,IAAI,UAAU;AAGxB,QAAI,CAAC,oBAAoB;AAEvB,cAAQ,OAAO,gBAAgB,EAAE;AACjC,cAAQ,OAAO,GAAG,UAAU,kBAAkB;AAC9C,2BAAqB;AAAA,IACvB;AAEA,WAAO,MAAM;AAEX,gBAAU,OAAO,UAAU;AAG3B,UAAI,UAAU,SAAS,KAAK,oBAAoB;AAC9C,gBAAQ,OAAO,IAAI,UAAU,kBAAkB;AAC/C,6BAAqB;AAErB,YAAI,eAAe;AACjB,uBAAa,aAAa;AAC1B,0BAAgB;AAAA,QAClB;AAAA,MACF;AAAA,IACF;AAAA,EACF,GAAG,CAAC,CAAC;AAEL,SAAO;AACT;AASO,SAAS,0BAA0B,UAAsB;AAC9D,SAAO,6BAA6B,QAAQ;AAC9C;AAQO,SAAS,6BAA6B,UAAsB;AACjE,QAAM,cAAc,OAAO,QAAQ;AACnC,cAAY,UAAU;AAEtB,YAAU,MAAM;AAId,QAAI,CAAC,oBAAoB;AACvB,cAAQ,OAAO,gBAAgB,EAAE;AACjC,cAAQ,OAAO,GAAG,UAAU,kBAAkB;AAC9C,2BAAqB;AAAA,IACvB;AAEA,UAAM,kBAAkB,MAAM,YAAY,QAAQ;AAClD,oBAAgB,IAAI,eAAe;AAEnC,WAAO,MAAM;AACX,sBAAgB,OAAO,eAAe;AAAA,IACxC;AAAA,EACF,GAAG,CAAC,CAAC;AACP;",
4
+ "sourcesContent": ["import { useEffect, useState, useRef, useCallback } from 'react'\n\n// Global state to share across all hook instances\nlet globalSize = {\n columns: process.stdout.columns || 80,\n rows: process.stdout.rows || 24,\n}\n\nconst listeners = new Set<() => void>()\nlet isListenerAttached = false\nlet debounceTimer: NodeJS.Timeout | null = null\n\n// Callbacks to trigger full re-render when significant resize occurs\nconst resizeCallbacks = new Set<() => void>()\n\n// Debounce delay in ms - prevents rapid-fire re-renders during resize\n// Increased from 150ms to 300ms to better handle window focus transitions\nconst RESIZE_DEBOUNCE_MS = 300\n\n// Threshold for detecting any significant size change (either direction)\n// Any resize > 5 columns should trigger a re-render to prevent ghost artifacts\nconst SIZE_CHANGE_THRESHOLD = 5\n\n// Track if we're currently in a fullscreen exit clearing cycle to prevent re-triggers\nlet isInClearingCycle = false\n\n// Track last significant resize time to prevent rapid re-triggers (e.g., from window focus changes)\nlet lastSignificantResizeTime = 0\nconst RESIZE_COOLDOWN_MS = 2000 // 2 second cooldown between significant resize triggers\n\n// Track pending resize during cooldown so it can be processed after cooldown expires\nlet pendingResizeTimer: NodeJS.Timeout | null = null\n\nfunction updateAllListeners() {\n // Clear any pending debounce\n if (debounceTimer) {\n clearTimeout(debounceTimer)\n }\n\n // Debounce the resize event to prevent multiple rapid re-renders\n debounceTimer = setTimeout(() => {\n const newColumns = process.stdout.columns || 80\n const newRows = process.stdout.rows || 24\n\n // Only update if dimensions actually changed\n if (globalSize.columns !== newColumns || globalSize.rows !== newRows) {\n const oldColumns = globalSize.columns\n\n // Detect if screen size changed significantly (in either direction)\n // This catches both entering and exiting fullscreen, as well as manual window resizing\n const columnDiff = Math.abs(oldColumns - newColumns)\n const isSignificantResize = columnDiff > SIZE_CHANGE_THRESHOLD\n\n globalSize = {\n columns: newColumns,\n rows: newRows,\n }\n listeners.forEach(listener => listener())\n\n // If significant resize and not already in clearing cycle, trigger callbacks\n // The clearing cycle lock prevents multiple triggers during the clear/re-render process\n // Also enforce a cooldown period to prevent rapid re-triggers from window focus changes\n const now = Date.now()\n const timeSinceLastResize = now - lastSignificantResizeTime\n const isCooldownExpired = timeSinceLastResize > RESIZE_COOLDOWN_MS\n\n if (isSignificantResize && !isInClearingCycle && isCooldownExpired) {\n isInClearingCycle = true\n lastSignificantResizeTime = now\n // Clear any pending deferred resize since we're handling it now\n if (pendingResizeTimer) {\n clearTimeout(pendingResizeTimer)\n pendingResizeTimer = null\n }\n resizeCallbacks.forEach(callback => callback())\n // Release the lock after a delay to allow re-render to complete\n setTimeout(() => {\n isInClearingCycle = false\n }, 500)\n } else if (\n isSignificantResize &&\n (isInClearingCycle || !isCooldownExpired)\n ) {\n // Significant resize occurred during cooldown or clearing cycle\n // Schedule a deferred re-render after cooldown expires to prevent stale layout\n if (pendingResizeTimer) {\n clearTimeout(pendingResizeTimer)\n }\n const remainingCooldown =\n Math.max(0, RESIZE_COOLDOWN_MS - timeSinceLastResize) + 100 // Add 100ms buffer\n pendingResizeTimer = setTimeout(() => {\n pendingResizeTimer = null\n if (!isInClearingCycle) {\n isInClearingCycle = true\n lastSignificantResizeTime = Date.now()\n resizeCallbacks.forEach(callback => callback())\n setTimeout(() => {\n isInClearingCycle = false\n }, 500)\n }\n }, remainingCooldown)\n }\n }\n debounceTimer = null\n }, RESIZE_DEBOUNCE_MS)\n}\n\nexport function useTerminalSize() {\n const [size, setSize] = useState(globalSize)\n\n useEffect(() => {\n // Add this component's listener to the set\n const updateSize = () => setSize({ ...globalSize })\n listeners.add(updateSize)\n\n // Only attach the global resize listener once\n if (!isListenerAttached) {\n // Increase max listeners to prevent warnings\n process.stdout.setMaxListeners(20)\n process.stdout.on('resize', updateAllListeners)\n isListenerAttached = true\n }\n\n return () => {\n // Remove this component's listener\n listeners.delete(updateSize)\n\n // If no more listeners, remove the global listener\n if (listeners.size === 0 && isListenerAttached) {\n process.stdout.off('resize', updateAllListeners)\n isListenerAttached = false\n // Clear any pending debounce\n if (debounceTimer) {\n clearTimeout(debounceTimer)\n debounceTimer = null\n }\n }\n }\n }, [])\n\n return size\n}\n\n/**\n * Hook to register a callback that fires when a significant resize occurs.\n * This is detected when the terminal width changes by more than 5 columns.\n * Useful for triggering a full UI re-render to clear ghost artifacts.\n *\n * @deprecated Use useSignificantResizeCallback instead (same function, clearer name)\n */\nexport function useFullscreenExitCallback(callback: () => void) {\n return useSignificantResizeCallback(callback)\n}\n\n/**\n * Hook to register a callback that fires when a significant terminal resize occurs.\n * This is detected when the terminal width changes by more than SIZE_CHANGE_THRESHOLD columns.\n * Useful for triggering a full UI re-render to clear ghost artifacts caused by Ink's\n * differential rendering.\n */\nexport function useSignificantResizeCallback(callback: () => void) {\n const callbackRef = useRef(callback)\n callbackRef.current = callback\n\n useEffect(() => {\n // Ensure the global resize listener is attached\n // This is needed because this hook might be called\n // before any component calls useTerminalSize()\n if (!isListenerAttached) {\n process.stdout.setMaxListeners(20)\n process.stdout.on('resize', updateAllListeners)\n isListenerAttached = true\n }\n\n const wrappedCallback = () => callbackRef.current()\n resizeCallbacks.add(wrappedCallback)\n\n return () => {\n resizeCallbacks.delete(wrappedCallback)\n }\n }, [])\n}\n"],
5
+ "mappings": "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",
6
6
  "names": []
7
7
  }
@@ -139,6 +139,7 @@ function useTextInput({
139
139
  return cursor.insert("\n");
140
140
  }
141
141
  onSubmit?.(originalValue);
142
+ return void 0;
142
143
  }
143
144
  function upOrHistoryUp() {
144
145
  if (disableCursorMovementForUpDownKeys) {
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../../src/hooks/useTextInput.ts"],
4
- "sourcesContent": ["import { useState } from 'react'\nimport { type Key } from 'ink'\nimport { useDoublePress } from './useDoublePress'\nimport { Cursor } from '@utils/Cursor'\nimport {\n getImageFromClipboard,\n CLIPBOARD_ERROR_MESSAGE,\n} from '@utils/imagePaste'\n\nconst IMAGE_PLACEHOLDER = '[Image pasted]'\n\ntype MaybeCursor = void | Cursor\ntype InputHandler = (input: string) => MaybeCursor\ntype InputMapper = (input: string) => MaybeCursor\nfunction mapInput(input_map: Array<[string, InputHandler]>): InputMapper {\n return function (input: string): MaybeCursor {\n const handler = new Map(input_map).get(input) ?? (() => {})\n return handler(input)\n }\n}\n\ntype UseTextInputProps = {\n value: string\n onChange: (value: string) => void\n onSubmit?: (value: string) => void\n onExit?: () => void\n onExitMessage?: (show: boolean, key?: string) => void\n onMessage?: (show: boolean, message?: string) => void\n onHistoryUp?: () => void\n onHistoryDown?: () => void\n onHistoryReset?: () => void\n focus?: boolean\n mask?: string\n multiline?: boolean\n cursorChar: string\n highlightPastedText?: boolean\n invert: (text: string) => string\n themeText: (text: string) => string\n columns: number\n onImagePaste?: (base64Image: string) => void\n disableCursorMovementForUpDownKeys?: boolean\n externalOffset: number\n onOffsetChange: (offset: number) => void\n}\n\ntype UseTextInputResult = {\n renderedValue: string\n onInput: (input: string, key: Key) => void\n offset: number\n setOffset: (offset: number) => void\n}\n\nexport function useTextInput({\n value: originalValue,\n onChange,\n onSubmit,\n onExit,\n onExitMessage,\n onMessage,\n onHistoryUp,\n onHistoryDown,\n onHistoryReset,\n mask = '',\n multiline = false,\n cursorChar,\n invert,\n columns,\n onImagePaste,\n disableCursorMovementForUpDownKeys = false,\n externalOffset,\n onOffsetChange,\n}: UseTextInputProps): UseTextInputResult {\n const offset = externalOffset\n const setOffset = onOffsetChange\n const cursor = Cursor.fromText(originalValue, columns, offset)\n const [imagePasteErrorTimeout, setImagePasteErrorTimeout] =\n useState<NodeJS.Timeout | null>(null)\n\n function maybeClearImagePasteErrorTimeout() {\n if (!imagePasteErrorTimeout) {\n return\n }\n clearTimeout(imagePasteErrorTimeout)\n setImagePasteErrorTimeout(null)\n onMessage?.(false)\n }\n\n const handleCtrlC = useDoublePress(\n show => {\n maybeClearImagePasteErrorTimeout()\n onExitMessage?.(show, 'Ctrl-C')\n },\n () => onExit?.(),\n () => {\n if (originalValue) {\n onChange('')\n onHistoryReset?.()\n }\n },\n )\n\n // Keep Escape for clearing input\n const handleEscape = useDoublePress(\n show => {\n maybeClearImagePasteErrorTimeout()\n onMessage?.(!!originalValue && show, `Press Escape again to clear`)\n },\n () => {\n if (originalValue) {\n onChange('')\n }\n },\n )\n function clear() {\n return Cursor.fromText('', columns, 0)\n }\n\n const handleEmptyCtrlD = useDoublePress(\n show => onExitMessage?.(show, 'Ctrl-D'),\n () => onExit?.(),\n )\n\n function handleCtrlD(): MaybeCursor {\n maybeClearImagePasteErrorTimeout()\n if (cursor.text === '') {\n // When input is empty, handle double-press\n handleEmptyCtrlD()\n return cursor\n }\n // When input is not empty, delete forward like iPython\n return cursor.del()\n }\n\n function tryImagePaste() {\n const base64Image = getImageFromClipboard()\n if (base64Image === null) {\n if (process.platform !== 'darwin') {\n return cursor\n }\n onMessage?.(true, CLIPBOARD_ERROR_MESSAGE)\n maybeClearImagePasteErrorTimeout()\n setImagePasteErrorTimeout(\n setTimeout(() => {\n onMessage?.(false)\n }, 4000),\n )\n return cursor\n }\n\n onImagePaste?.(base64Image)\n return cursor.insert(IMAGE_PLACEHOLDER)\n }\n\n const handleCtrl = mapInput([\n ['a', () => cursor.startOfLine()],\n ['b', () => cursor.left()],\n ['c', handleCtrlC],\n ['d', handleCtrlD],\n ['e', () => cursor.endOfLine()],\n ['f', () => cursor.right()],\n [\n 'h',\n () => {\n maybeClearImagePasteErrorTimeout()\n return cursor.backspace()\n },\n ],\n ['j', () => cursor.insert('\\n')], // Ctrl+J: Raw newline (Phase 2)\n ['k', () => cursor.deleteToLineEnd()],\n ['l', () => clear()],\n ['n', () => downOrHistoryDown()],\n ['p', () => upOrHistoryUp()],\n ['u', () => cursor.deleteToLineStart()],\n ['v', tryImagePaste],\n ['w', () => cursor.deleteWordBefore()],\n ])\n\n const handleMeta = mapInput([\n ['b', () => cursor.prevWord()],\n ['f', () => cursor.nextWord()],\n ['d', () => cursor.deleteWordAfter()],\n ])\n\n function handleEnter(key: Key) {\n if (\n multiline &&\n cursor.offset > 0 &&\n cursor.text[cursor.offset - 1] === '\\\\'\n ) {\n return cursor.backspace().insert('\\n')\n }\n if (key.meta) {\n return cursor.insert('\\n')\n }\n onSubmit?.(originalValue)\n }\n\n function upOrHistoryUp() {\n if (disableCursorMovementForUpDownKeys) {\n onHistoryUp?.()\n return cursor\n }\n const cursorUp = cursor.up()\n if (cursorUp.equals(cursor)) {\n // already at beginning\n onHistoryUp?.()\n }\n return cursorUp\n }\n function downOrHistoryDown() {\n if (disableCursorMovementForUpDownKeys) {\n onHistoryDown?.()\n return cursor\n }\n const cursorDown = cursor.down()\n if (cursorDown.equals(cursor)) {\n onHistoryDown?.()\n }\n return cursorDown\n }\n\n function onInput(input: string, key: Key): void {\n if (key.tab) {\n return // Skip Tab key processing - let completion system handle it\n }\n\n // Direct handling for backspace or delete (which is being detected as delete)\n if (\n key.backspace ||\n key.delete ||\n input === '\\b' ||\n input === '\\x7f' ||\n input === '\\x08'\n ) {\n const nextCursor = cursor.backspace()\n if (!cursor.equals(nextCursor)) {\n setOffset(nextCursor.offset)\n if (cursor.text !== nextCursor.text) {\n onChange(nextCursor.text)\n }\n }\n return\n }\n\n const nextCursor = mapKey(key)(input)\n if (nextCursor) {\n if (!cursor.equals(nextCursor)) {\n setOffset(nextCursor.offset)\n if (cursor.text !== nextCursor.text) {\n onChange(nextCursor.text)\n }\n }\n }\n }\n\n function mapKey(key: Key): InputMapper {\n // Direct handling for backspace or delete\n if (key.backspace || key.delete) {\n maybeClearImagePasteErrorTimeout()\n return () => cursor.backspace()\n }\n\n switch (true) {\n case key.escape:\n return handleEscape\n case key.leftArrow && (key.ctrl || key.meta || ('fn' in key && key.fn)):\n return () => cursor.prevWord()\n case key.rightArrow && (key.ctrl || key.meta || ('fn' in key && key.fn)):\n return () => cursor.nextWord()\n case key.ctrl:\n return handleCtrl\n case 'home' in key && key.home:\n return () => cursor.startOfLine()\n case 'end' in key && key.end:\n return () => cursor.endOfLine()\n case key.pageDown:\n return () => cursor.endOfLine()\n case key.pageUp:\n return () => cursor.startOfLine()\n case key.meta:\n return handleMeta\n case key.return:\n return () => handleEnter(key)\n // Remove Tab handling - let completion system handle it\n case key.upArrow:\n return upOrHistoryUp\n case key.downArrow:\n return downOrHistoryDown\n case key.leftArrow:\n return () => cursor.left()\n case key.rightArrow:\n return () => cursor.right()\n }\n return function (input: string) {\n switch (true) {\n // Home key\n case input == '\\x1b[H' || input == '\\x1b[1~':\n return cursor.startOfLine()\n // End key\n case input == '\\x1b[F' || input == '\\x1b[4~':\n return cursor.endOfLine()\n // Handle backspace character explicitly - this is the key fix\n case input === '\\b' || input === '\\x7f' || input === '\\x08':\n maybeClearImagePasteErrorTimeout()\n return cursor.backspace()\n default:\n return cursor.insert(input.replace(/\\r/g, '\\n'))\n }\n }\n }\n\n return {\n onInput,\n renderedValue: cursor.render(cursorChar, mask, invert),\n offset,\n setOffset,\n }\n}\n"],
5
- "mappings": "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",
4
+ "sourcesContent": ["import { useState } from 'react'\nimport { type Key } from 'ink'\nimport { useDoublePress } from './useDoublePress'\nimport { Cursor } from '@utils/Cursor'\nimport {\n getImageFromClipboard,\n CLIPBOARD_ERROR_MESSAGE,\n} from '@utils/imagePaste'\n\nconst IMAGE_PLACEHOLDER = '[Image pasted]'\n\ntype MaybeCursor = void | Cursor\ntype InputHandler = (input: string) => MaybeCursor\ntype InputMapper = (input: string) => MaybeCursor\nfunction mapInput(input_map: Array<[string, InputHandler]>): InputMapper {\n return function (input: string): MaybeCursor {\n const handler = new Map(input_map).get(input) ?? (() => {})\n return handler(input)\n }\n}\n\ntype UseTextInputProps = {\n value: string\n onChange: (value: string) => void\n onSubmit?: (value: string) => void\n onExit?: () => void\n onExitMessage?: (show: boolean, key?: string) => void\n onMessage?: (show: boolean, message?: string) => void\n onHistoryUp?: () => void\n onHistoryDown?: () => void\n onHistoryReset?: () => void\n focus?: boolean\n mask?: string\n multiline?: boolean\n cursorChar: string\n highlightPastedText?: boolean\n invert: (text: string) => string\n themeText: (text: string) => string\n columns: number\n onImagePaste?: (base64Image: string) => void\n disableCursorMovementForUpDownKeys?: boolean\n externalOffset: number\n onOffsetChange: (offset: number) => void\n}\n\ntype UseTextInputResult = {\n renderedValue: string\n onInput: (input: string, key: Key) => void\n offset: number\n setOffset: (offset: number) => void\n}\n\nexport function useTextInput({\n value: originalValue,\n onChange,\n onSubmit,\n onExit,\n onExitMessage,\n onMessage,\n onHistoryUp,\n onHistoryDown,\n onHistoryReset,\n mask = '',\n multiline = false,\n cursorChar,\n invert,\n columns,\n onImagePaste,\n disableCursorMovementForUpDownKeys = false,\n externalOffset,\n onOffsetChange,\n}: UseTextInputProps): UseTextInputResult {\n const offset = externalOffset\n const setOffset = onOffsetChange\n const cursor = Cursor.fromText(originalValue, columns, offset)\n const [imagePasteErrorTimeout, setImagePasteErrorTimeout] =\n useState<NodeJS.Timeout | null>(null)\n\n function maybeClearImagePasteErrorTimeout() {\n if (!imagePasteErrorTimeout) {\n return\n }\n clearTimeout(imagePasteErrorTimeout)\n setImagePasteErrorTimeout(null)\n onMessage?.(false)\n }\n\n const handleCtrlC = useDoublePress(\n show => {\n maybeClearImagePasteErrorTimeout()\n onExitMessage?.(show, 'Ctrl-C')\n },\n () => onExit?.(),\n () => {\n if (originalValue) {\n onChange('')\n onHistoryReset?.()\n }\n },\n )\n\n // Keep Escape for clearing input\n const handleEscape = useDoublePress(\n show => {\n maybeClearImagePasteErrorTimeout()\n onMessage?.(!!originalValue && show, `Press Escape again to clear`)\n },\n () => {\n if (originalValue) {\n onChange('')\n }\n },\n )\n function clear() {\n return Cursor.fromText('', columns, 0)\n }\n\n const handleEmptyCtrlD = useDoublePress(\n show => onExitMessage?.(show, 'Ctrl-D'),\n () => onExit?.(),\n )\n\n function handleCtrlD(): MaybeCursor {\n maybeClearImagePasteErrorTimeout()\n if (cursor.text === '') {\n // When input is empty, handle double-press\n handleEmptyCtrlD()\n return cursor\n }\n // When input is not empty, delete forward like iPython\n return cursor.del()\n }\n\n function tryImagePaste() {\n const base64Image = getImageFromClipboard()\n if (base64Image === null) {\n if (process.platform !== 'darwin') {\n return cursor\n }\n onMessage?.(true, CLIPBOARD_ERROR_MESSAGE)\n maybeClearImagePasteErrorTimeout()\n setImagePasteErrorTimeout(\n setTimeout(() => {\n onMessage?.(false)\n }, 4000),\n )\n return cursor\n }\n\n onImagePaste?.(base64Image)\n return cursor.insert(IMAGE_PLACEHOLDER)\n }\n\n const handleCtrl = mapInput([\n ['a', () => cursor.startOfLine()],\n ['b', () => cursor.left()],\n ['c', handleCtrlC],\n ['d', handleCtrlD],\n ['e', () => cursor.endOfLine()],\n ['f', () => cursor.right()],\n [\n 'h',\n () => {\n maybeClearImagePasteErrorTimeout()\n return cursor.backspace()\n },\n ],\n ['j', () => cursor.insert('\\n')], // Ctrl+J: Raw newline (Phase 2)\n ['k', () => cursor.deleteToLineEnd()],\n ['l', () => clear()],\n ['n', () => downOrHistoryDown()],\n ['p', () => upOrHistoryUp()],\n ['u', () => cursor.deleteToLineStart()],\n ['v', tryImagePaste],\n ['w', () => cursor.deleteWordBefore()],\n ])\n\n const handleMeta = mapInput([\n ['b', () => cursor.prevWord()],\n ['f', () => cursor.nextWord()],\n ['d', () => cursor.deleteWordAfter()],\n ])\n\n function handleEnter(key: Key) {\n if (\n multiline &&\n cursor.offset > 0 &&\n cursor.text[cursor.offset - 1] === '\\\\'\n ) {\n return cursor.backspace().insert('\\n')\n }\n if (key.meta) {\n return cursor.insert('\\n')\n }\n onSubmit?.(originalValue)\n return undefined\n }\n\n function upOrHistoryUp() {\n if (disableCursorMovementForUpDownKeys) {\n onHistoryUp?.()\n return cursor\n }\n const cursorUp = cursor.up()\n if (cursorUp.equals(cursor)) {\n // already at beginning\n onHistoryUp?.()\n }\n return cursorUp\n }\n function downOrHistoryDown() {\n if (disableCursorMovementForUpDownKeys) {\n onHistoryDown?.()\n return cursor\n }\n const cursorDown = cursor.down()\n if (cursorDown.equals(cursor)) {\n onHistoryDown?.()\n }\n return cursorDown\n }\n\n function onInput(input: string, key: Key): void {\n if (key.tab) {\n return // Skip Tab key processing - let completion system handle it\n }\n\n // Direct handling for backspace or delete (which is being detected as delete)\n if (\n key.backspace ||\n key.delete ||\n input === '\\b' ||\n input === '\\x7f' ||\n input === '\\x08'\n ) {\n const nextCursor = cursor.backspace()\n if (!cursor.equals(nextCursor)) {\n setOffset(nextCursor.offset)\n if (cursor.text !== nextCursor.text) {\n onChange(nextCursor.text)\n }\n }\n return\n }\n\n const nextCursor = mapKey(key)(input)\n if (nextCursor) {\n if (!cursor.equals(nextCursor)) {\n setOffset(nextCursor.offset)\n if (cursor.text !== nextCursor.text) {\n onChange(nextCursor.text)\n }\n }\n }\n }\n\n function mapKey(key: Key): InputMapper {\n // Direct handling for backspace or delete\n if (key.backspace || key.delete) {\n maybeClearImagePasteErrorTimeout()\n return () => cursor.backspace()\n }\n\n switch (true) {\n case key.escape:\n return handleEscape\n case key.leftArrow && (key.ctrl || key.meta || ('fn' in key && key.fn)):\n return () => cursor.prevWord()\n case key.rightArrow && (key.ctrl || key.meta || ('fn' in key && key.fn)):\n return () => cursor.nextWord()\n case key.ctrl:\n return handleCtrl\n case 'home' in key && key.home:\n return () => cursor.startOfLine()\n case 'end' in key && key.end:\n return () => cursor.endOfLine()\n case key.pageDown:\n return () => cursor.endOfLine()\n case key.pageUp:\n return () => cursor.startOfLine()\n case key.meta:\n return handleMeta\n case key.return:\n return () => handleEnter(key)\n // Remove Tab handling - let completion system handle it\n case key.upArrow:\n return upOrHistoryUp\n case key.downArrow:\n return downOrHistoryDown\n case key.leftArrow:\n return () => cursor.left()\n case key.rightArrow:\n return () => cursor.right()\n }\n return function (input: string) {\n switch (true) {\n // Home key\n case input == '\\x1b[H' || input == '\\x1b[1~':\n return cursor.startOfLine()\n // End key\n case input == '\\x1b[F' || input == '\\x1b[4~':\n return cursor.endOfLine()\n // Handle backspace character explicitly - this is the key fix\n case input === '\\b' || input === '\\x7f' || input === '\\x08':\n maybeClearImagePasteErrorTimeout()\n return cursor.backspace()\n default:\n return cursor.insert(input.replace(/\\r/g, '\\n'))\n }\n }\n }\n\n return {\n onInput,\n renderedValue: cursor.render(cursorChar, mask, invert),\n offset,\n setOffset,\n }\n}\n"],
5
+ "mappings": "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",
6
6
  "names": ["nextCursor"]
7
7
  }
@@ -370,8 +370,9 @@ function useUnifiedCompletion({
370
370
  useEffect(() => {
371
371
  listMCPResources().then((resources) => {
372
372
  const suggestions2 = resources.map((resource) => ({
373
- value: resource.uri,
374
- displayValue: `\u{1F50C} ${resource.name} :: ${resource.description || resource.uri}`,
373
+ // Use @server:uri format for CC-compatible resource references
374
+ value: `@${resource.serverName}:${resource.uri}`,
375
+ displayValue: `\u{1F50C} ${resource.serverName}:${resource.name} :: ${resource.description || resource.uri}`,
375
376
  type: "mcp-resource",
376
377
  score: 80,
377
378
  metadata: {