@within-7/minto 0.3.10 → 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 (306) hide show
  1. package/dist/Tool.js.map +2 -2
  2. package/dist/commands/agents/AgentsCommand.js +2 -2
  3. package/dist/commands/agents/AgentsCommand.js.map +2 -2
  4. package/dist/commands/ctx_viz.js +1 -1
  5. package/dist/commands/effort.js +87 -0
  6. package/dist/commands/effort.js.map +7 -0
  7. package/dist/commands/export.js +19 -9
  8. package/dist/commands/export.js.map +2 -2
  9. package/dist/commands/ide.js +18 -0
  10. package/dist/commands/ide.js.map +7 -0
  11. package/dist/commands/mcp-interactive.js +14 -8
  12. package/dist/commands/mcp-interactive.js.map +2 -2
  13. package/dist/commands/memory.js +168 -0
  14. package/dist/commands/memory.js.map +7 -0
  15. package/dist/commands/model.js +45 -2
  16. package/dist/commands/model.js.map +2 -2
  17. package/dist/commands/outputStyle.js +64 -0
  18. package/dist/commands/outputStyle.js.map +7 -0
  19. package/dist/commands/plugin/utils.js +33 -1
  20. package/dist/commands/plugin/utils.js.map +2 -2
  21. package/dist/commands/plugin.js +10 -1
  22. package/dist/commands/plugin.js.map +2 -2
  23. package/dist/commands/refreshCommands.js +2 -0
  24. package/dist/commands/refreshCommands.js.map +2 -2
  25. package/dist/commands/review.js +51 -0
  26. package/dist/commands/review.js.map +7 -0
  27. package/dist/commands/terminalSetup.js +6 -0
  28. package/dist/commands/terminalSetup.js.map +2 -2
  29. package/dist/commands/undo.js +8 -0
  30. package/dist/commands/undo.js.map +2 -2
  31. package/dist/commands/vim.js +22 -0
  32. package/dist/commands/vim.js.map +7 -0
  33. package/dist/commands.js +12 -0
  34. package/dist/commands.js.map +2 -2
  35. package/dist/components/HighlightedCode.js +1 -0
  36. package/dist/components/HighlightedCode.js.map +2 -2
  37. package/dist/components/ModelSelector/ModelSelector.js +250 -143
  38. package/dist/components/ModelSelector/ModelSelector.js.map +2 -2
  39. package/dist/components/PromptInput.js +21 -6
  40. package/dist/components/PromptInput.js.map +2 -2
  41. package/dist/components/PulseLabel.js +44 -0
  42. package/dist/components/PulseLabel.js.map +7 -0
  43. package/dist/components/RequestStatusIndicator.js +1 -1
  44. package/dist/components/RequestStatusIndicator.js.map +1 -1
  45. package/dist/components/Spinner.js +12 -42
  46. package/dist/components/Spinner.js.map +3 -3
  47. package/dist/components/StartupStatus.js +57 -0
  48. package/dist/components/StartupStatus.js.map +7 -0
  49. package/dist/components/SubagentBlock.js +43 -6
  50. package/dist/components/SubagentBlock.js.map +2 -2
  51. package/dist/components/TabbedListView/TabBar.js +13 -8
  52. package/dist/components/TabbedListView/TabBar.js.map +2 -2
  53. package/dist/components/TabbedListView/TabbedListView.js +1 -1
  54. package/dist/components/TabbedListView/TabbedListView.js.map +2 -2
  55. package/dist/components/TodoPanel.js +1 -1
  56. package/dist/components/TodoPanel.js.map +1 -1
  57. package/dist/components/ToolUseLoader.js +5 -0
  58. package/dist/components/ToolUseLoader.js.map +2 -2
  59. package/dist/components/TrustDialog.js +0 -2
  60. package/dist/components/TrustDialog.js.map +2 -2
  61. package/dist/components/messages/TaskInModuleView.js +1 -1
  62. package/dist/components/messages/TaskInModuleView.js.map +2 -2
  63. package/dist/components/messages/TaskToolMessage.js +1 -1
  64. package/dist/components/messages/TaskToolMessage.js.map +2 -2
  65. package/dist/components/messages/UserPromptMessage.js +6 -1
  66. package/dist/components/messages/UserPromptMessage.js.map +2 -2
  67. package/dist/constants/modelCapabilities.js +103 -18
  68. package/dist/constants/modelCapabilities.js.map +2 -2
  69. package/dist/constants/product.js +2 -0
  70. package/dist/constants/product.js.map +2 -2
  71. package/dist/constants/prompts/agentPrompt.js +30 -0
  72. package/dist/constants/prompts/agentPrompt.js.map +7 -0
  73. package/dist/constants/prompts/codeConventions.js +27 -0
  74. package/dist/constants/prompts/codeConventions.js.map +7 -0
  75. package/dist/constants/prompts/doingTasks.js +15 -0
  76. package/dist/constants/prompts/doingTasks.js.map +7 -0
  77. package/dist/constants/prompts/envInfo.js +17 -0
  78. package/dist/constants/prompts/envInfo.js.map +7 -0
  79. package/dist/constants/prompts/executingWithCare.js +17 -0
  80. package/dist/constants/prompts/executingWithCare.js.map +7 -0
  81. package/dist/constants/prompts/identity.js +10 -0
  82. package/dist/constants/prompts/identity.js.map +7 -0
  83. package/dist/constants/prompts/index.js +78 -0
  84. package/dist/constants/prompts/index.js.map +7 -0
  85. package/dist/constants/prompts/taskManagement.js +60 -0
  86. package/dist/constants/prompts/taskManagement.js.map +7 -0
  87. package/dist/constants/prompts/toneAndStyle.js +62 -0
  88. package/dist/constants/prompts/toneAndStyle.js.map +7 -0
  89. package/dist/constants/prompts/toolUsagePolicy.js +38 -0
  90. package/dist/constants/prompts/toolUsagePolicy.js.map +7 -0
  91. package/dist/constants/prompts.js +5 -176
  92. package/dist/constants/prompts.js.map +2 -2
  93. package/dist/constants/providerRegistry.js +235 -0
  94. package/dist/constants/providerRegistry.js.map +7 -0
  95. package/dist/constants/providers.js +35 -0
  96. package/dist/constants/providers.js.map +7 -0
  97. package/dist/context/PermissionContext.js +0 -1
  98. package/dist/context/PermissionContext.js.map +2 -2
  99. package/dist/context.js +87 -31
  100. package/dist/context.js.map +2 -2
  101. package/dist/core/backupHook.js +2 -2
  102. package/dist/core/backupHook.js.map +2 -2
  103. package/dist/core/config/defaults.js +4 -1
  104. package/dist/core/config/defaults.js.map +2 -2
  105. package/dist/core/config/schema.js +7 -1
  106. package/dist/core/config/schema.js.map +2 -2
  107. package/dist/core/costTracker.js +18 -0
  108. package/dist/core/costTracker.js.map +2 -2
  109. package/dist/core/index.js +0 -1
  110. package/dist/core/index.js.map +2 -2
  111. package/dist/core/tokenStatsManager.js +22 -4
  112. package/dist/core/tokenStatsManager.js.map +2 -2
  113. package/dist/entrypoints/cli.js +65 -84
  114. package/dist/entrypoints/cli.js.map +2 -2
  115. package/dist/hooks/useAgentTokenStats.js +1 -1
  116. package/dist/hooks/useAgentTokenStats.js.map +2 -2
  117. package/dist/hooks/useAgentTranscripts.js +2 -1
  118. package/dist/hooks/useAgentTranscripts.js.map +2 -2
  119. package/dist/hooks/useBackgroundShells.js +29 -0
  120. package/dist/hooks/useBackgroundShells.js.map +7 -0
  121. package/dist/hooks/useCanUseTool.js +1 -1
  122. package/dist/hooks/useCanUseTool.js.map +2 -2
  123. package/dist/hooks/useDeferredLoading.js +64 -0
  124. package/dist/hooks/useDeferredLoading.js.map +7 -0
  125. package/dist/hooks/useHookStatus.js +1 -1
  126. package/dist/hooks/useHookStatus.js.map +2 -2
  127. package/dist/hooks/useSessionTracking.js +55 -0
  128. package/dist/hooks/useSessionTracking.js.map +7 -0
  129. package/dist/hooks/useTerminalSize.js +21 -0
  130. package/dist/hooks/useTerminalSize.js.map +2 -2
  131. package/dist/hooks/useTextInput.js +1 -0
  132. package/dist/hooks/useTextInput.js.map +2 -2
  133. package/dist/hooks/useUnifiedCompletion.js +3 -2
  134. package/dist/hooks/useUnifiedCompletion.js.map +2 -2
  135. package/dist/i18n/locales/en.js +8 -9
  136. package/dist/i18n/locales/en.js.map +2 -2
  137. package/dist/i18n/locales/zh-CN.js +8 -9
  138. package/dist/i18n/locales/zh-CN.js.map +2 -2
  139. package/dist/i18n/types.js.map +1 -1
  140. package/dist/messages.js +41 -17
  141. package/dist/messages.js.map +2 -2
  142. package/dist/permissions.js +94 -1
  143. package/dist/permissions.js.map +2 -2
  144. package/dist/query.js +27 -19
  145. package/dist/query.js.map +2 -2
  146. package/dist/screens/REPL.js +83 -74
  147. package/dist/screens/REPL.js.map +2 -2
  148. package/dist/services/adapters/responsesAPI.js +6 -0
  149. package/dist/services/adapters/responsesAPI.js.map +2 -2
  150. package/dist/services/agentTeams/index.js +35 -0
  151. package/dist/services/agentTeams/index.js.map +7 -0
  152. package/dist/services/agentTeams/mailbox.js +114 -0
  153. package/dist/services/agentTeams/mailbox.js.map +7 -0
  154. package/dist/services/agentTeams/teamManager.js +149 -0
  155. package/dist/services/agentTeams/teamManager.js.map +7 -0
  156. package/dist/services/agentTeams/teamTaskStore.js +114 -0
  157. package/dist/services/agentTeams/teamTaskStore.js.map +7 -0
  158. package/dist/services/agentTeams/teammateSpawner.js +80 -0
  159. package/dist/services/agentTeams/teammateSpawner.js.map +7 -0
  160. package/dist/services/checkpointManager.js +16 -3
  161. package/dist/services/checkpointManager.js.map +2 -2
  162. package/dist/services/claude.js +19 -1728
  163. package/dist/services/claude.js.map +3 -3
  164. package/dist/services/gpt5ConnectionTest.js +4 -2
  165. package/dist/services/gpt5ConnectionTest.js.map +2 -2
  166. package/dist/services/hookExecutor.js +411 -127
  167. package/dist/services/hookExecutor.js.map +2 -2
  168. package/dist/services/llm/anthropicProvider.js +807 -0
  169. package/dist/services/llm/anthropicProvider.js.map +7 -0
  170. package/dist/services/llm/dispatch.js +218 -0
  171. package/dist/services/llm/dispatch.js.map +7 -0
  172. package/dist/services/llm/index.js +44 -0
  173. package/dist/services/llm/index.js.map +7 -0
  174. package/dist/services/llm/mintoContext.js +69 -0
  175. package/dist/services/llm/mintoContext.js.map +7 -0
  176. package/dist/services/llm/openaiProvider.js +622 -0
  177. package/dist/services/llm/openaiProvider.js.map +7 -0
  178. package/dist/services/llm/types.js +157 -0
  179. package/dist/services/llm/types.js.map +7 -0
  180. package/dist/services/mcpClient.js +183 -33
  181. package/dist/services/mcpClient.js.map +2 -2
  182. package/dist/services/notifier.js +14 -0
  183. package/dist/services/notifier.js.map +2 -2
  184. package/dist/services/oauth.js +4 -2
  185. package/dist/services/oauth.js.map +2 -2
  186. package/dist/services/openai.js +66 -56
  187. package/dist/services/openai.js.map +3 -3
  188. package/dist/services/outputStyles.js +102 -21
  189. package/dist/services/outputStyles.js.map +2 -2
  190. package/dist/services/plugins/skillMarketplace.js +4 -1
  191. package/dist/services/plugins/skillMarketplace.js.map +2 -2
  192. package/dist/services/sentry.js +1 -1
  193. package/dist/services/sentry.js.map +2 -2
  194. package/dist/services/sessionMemory.js +16 -3
  195. package/dist/services/sessionMemory.js.map +2 -2
  196. package/dist/services/systemReminder.js +350 -3
  197. package/dist/services/systemReminder.js.map +2 -2
  198. package/dist/services/taskStore.js +19 -0
  199. package/dist/services/taskStore.js.map +2 -2
  200. package/dist/tools/ArchitectTool/ArchitectTool.js.map +1 -1
  201. package/dist/tools/AskUserQuestionTool/AskUserQuestionTool.js.map +1 -1
  202. package/dist/tools/BashOutputTool/BashOutputTool.js.map +1 -1
  203. package/dist/tools/BashTool/BashTool.js +28 -0
  204. package/dist/tools/BashTool/BashTool.js.map +2 -2
  205. package/dist/tools/FileEditTool/FileEditTool.js +1 -1
  206. package/dist/tools/FileEditTool/FileEditTool.js.map +2 -2
  207. package/dist/tools/FileReadTool/FileReadTool.js +14 -0
  208. package/dist/tools/FileReadTool/FileReadTool.js.map +2 -2
  209. package/dist/tools/FileWriteTool/FileWriteTool.js +3 -1
  210. package/dist/tools/FileWriteTool/FileWriteTool.js.map +2 -2
  211. package/dist/tools/GlobTool/GlobTool.js.map +1 -1
  212. package/dist/tools/GrepTool/GrepTool.js.map +1 -1
  213. package/dist/tools/KillShellTool/KillShellTool.js.map +1 -1
  214. package/dist/tools/ListMcpResourcesTool/ListMcpResourcesTool.js.map +2 -2
  215. package/dist/tools/LspTool/LspTool.js +11 -2
  216. package/dist/tools/LspTool/LspTool.js.map +2 -2
  217. package/dist/tools/MCPTool/MCPTool.js.map +1 -1
  218. package/dist/tools/MemoryReadTool/MemoryReadTool.js +2 -1
  219. package/dist/tools/MemoryReadTool/MemoryReadTool.js.map +2 -2
  220. package/dist/tools/MemoryWriteTool/MemoryWriteTool.js +2 -1
  221. package/dist/tools/MemoryWriteTool/MemoryWriteTool.js.map +2 -2
  222. package/dist/tools/MultiEditTool/MultiEditTool.js.map +1 -1
  223. package/dist/tools/NotebookEditTool/NotebookEditTool.js.map +1 -1
  224. package/dist/tools/NotebookReadTool/NotebookReadTool.js.map +1 -1
  225. package/dist/tools/PlanModeTool/EnterPlanModeTool.js +8 -2
  226. package/dist/tools/PlanModeTool/EnterPlanModeTool.js.map +2 -2
  227. package/dist/tools/PlanModeTool/ExitPlanModeTool.js +2 -0
  228. package/dist/tools/PlanModeTool/ExitPlanModeTool.js.map +2 -2
  229. package/dist/tools/ReadMcpResourceTool/ReadMcpResourceTool.js.map +1 -1
  230. package/dist/tools/SlashCommandTool/SlashCommandTool.js +174 -18
  231. package/dist/tools/SlashCommandTool/SlashCommandTool.js.map +3 -3
  232. package/dist/tools/TaskCreateTool/TaskCreateTool.js.map +1 -1
  233. package/dist/tools/TaskGetTool/TaskGetTool.js.map +1 -1
  234. package/dist/tools/TaskListTool/TaskListTool.js.map +1 -1
  235. package/dist/tools/TaskOutputTool/TaskOutputTool.js.map +1 -1
  236. package/dist/tools/TaskStopTool/TaskStopTool.js.map +1 -1
  237. package/dist/tools/TaskTool/TaskTool.js +75 -5
  238. package/dist/tools/TaskTool/TaskTool.js.map +2 -2
  239. package/dist/tools/TaskTool/prompt.js +12 -6
  240. package/dist/tools/TaskTool/prompt.js.map +2 -2
  241. package/dist/tools/TaskUpdateTool/TaskUpdateTool.js.map +1 -1
  242. package/dist/tools/ThinkTool/ThinkTool.js.map +1 -1
  243. package/dist/tools/TodoWriteTool/TodoWriteTool.js.map +1 -1
  244. package/dist/tools/URLFetcherTool/URLFetcherTool.js.map +1 -1
  245. package/dist/tools/WebSearchTool/WebSearchTool.js.map +1 -1
  246. package/dist/tools/WebSearchTool/searchProviders.js +2 -1
  247. package/dist/tools/WebSearchTool/searchProviders.js.map +2 -2
  248. package/dist/tools/lsTool/lsTool.js.map +2 -2
  249. package/dist/tools/lsTool/prompt.js.map +1 -1
  250. package/dist/tools.js +14 -3
  251. package/dist/tools.js.map +2 -2
  252. package/dist/types/PermissionMode.js +21 -1
  253. package/dist/types/PermissionMode.js.map +2 -2
  254. package/dist/types/agentTeams.js +1 -0
  255. package/dist/types/agentTeams.js.map +7 -0
  256. package/dist/types/hooks.js +8 -2
  257. package/dist/types/hooks.js.map +2 -2
  258. package/dist/types/plugin.js +1 -1
  259. package/dist/types/plugin.js.map +2 -2
  260. package/dist/utils/agentLoader.js +25 -3
  261. package/dist/utils/agentLoader.js.map +2 -2
  262. package/dist/utils/animationManager.js +1 -1
  263. package/dist/utils/animationManager.js.map +2 -2
  264. package/dist/utils/ask.js +1 -1
  265. package/dist/utils/async.js +5 -1
  266. package/dist/utils/async.js.map +2 -2
  267. package/dist/utils/autoCompactCore.js +60 -0
  268. package/dist/utils/autoCompactCore.js.map +2 -2
  269. package/dist/utils/config.js +26 -128
  270. package/dist/utils/config.js.map +2 -2
  271. package/dist/utils/configSchema.js +227 -0
  272. package/dist/utils/configSchema.js.map +7 -0
  273. package/dist/utils/debugLogger.js.map +2 -2
  274. package/dist/utils/env.js +4 -3
  275. package/dist/utils/env.js.map +2 -2
  276. package/dist/utils/envConfig.js +34 -0
  277. package/dist/utils/envConfig.js.map +3 -3
  278. package/dist/utils/gpt5.js +146 -0
  279. package/dist/utils/gpt5.js.map +7 -0
  280. package/dist/utils/hookManager.js +374 -140
  281. package/dist/utils/hookManager.js.map +2 -2
  282. package/dist/utils/markdown.js +47 -0
  283. package/dist/utils/markdown.js.map +2 -2
  284. package/dist/utils/memoizeWithTTL.js +25 -0
  285. package/dist/utils/memoizeWithTTL.js.map +7 -0
  286. package/dist/utils/model.js +34 -9
  287. package/dist/utils/model.js.map +2 -2
  288. package/dist/utils/pluginInstaller.js +34 -5
  289. package/dist/utils/pluginInstaller.js.map +2 -2
  290. package/dist/utils/pluginLoader.js +201 -32
  291. package/dist/utils/pluginLoader.js.map +2 -2
  292. package/dist/utils/safeFetch.js +45 -0
  293. package/dist/utils/safeFetch.js.map +7 -0
  294. package/dist/utils/skillLoader.js +59 -6
  295. package/dist/utils/skillLoader.js.map +2 -2
  296. package/dist/utils/streamingState.js +52 -0
  297. package/dist/utils/streamingState.js.map +7 -0
  298. package/dist/utils/style.js +6 -3
  299. package/dist/utils/style.js.map +2 -2
  300. package/dist/utils/teamConfig.js +9 -3
  301. package/dist/utils/teamConfig.js.map +2 -2
  302. package/dist/utils/toolRiskClassification.js +0 -6
  303. package/dist/utils/toolRiskClassification.js.map +2 -2
  304. package/dist/version.js +2 -2
  305. package/dist/version.js.map +1 -1
  306. package/package.json +2 -1
@@ -149,7 +149,7 @@ const FileWriteTool = {
149
149
  oldContent ? "update" : "create"
150
150
  );
151
151
  readFileTimestamps[fullFilePath] = statSync(fullFilePath).mtimeMs;
152
- if (fullFilePath.endsWith(`${sep}${PROJECT_FILE}`)) {
152
+ if (fullFilePath.endsWith(`${sep}${PROJECT_FILE}`) || fullFilePath.endsWith(`${sep}AGENTS.md`) || fullFilePath.endsWith(`${sep}CLAUDE.md`)) {
153
153
  }
154
154
  emitReminderEvent("file:edited", {
155
155
  filePath: fullFilePath,
@@ -200,6 +200,8 @@ ${addLineNumbers({
200
200
  content: content.split(/\r?\n/).length > MAX_LINES_TO_RENDER_FOR_ASSISTANT ? content.split(/\r?\n/).slice(0, MAX_LINES_TO_RENDER_FOR_ASSISTANT).join("\n") + TRUNCATED_MESSAGE : content,
201
201
  startLine: 1
202
202
  })}`;
203
+ default:
204
+ return `File operation completed at: ${filePath}`;
203
205
  }
204
206
  }
205
207
  };
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../../../src/tools/FileWriteTool/FileWriteTool.tsx"],
4
- "sourcesContent": ["import { Hunk } from 'diff'\nimport { existsSync, mkdirSync, readFileSync, statSync } from 'fs'\nimport { Box, Text } from 'ink'\nimport { EOL } from 'os'\nimport { dirname, extname, isAbsolute, relative, resolve, sep } from 'path'\nimport * as React from 'react'\nimport { z } from 'zod'\nimport { FileEditToolUpdatedMessage } from '@components/FileEditToolUpdatedMessage'\nimport { HighlightedCode } from '@components/HighlightedCode'\nimport { StructuredDiff } from '@components/StructuredDiff'\nimport { FallbackToolUseRejectedMessage } from '@components/FallbackToolUseRejectedMessage'\nimport type { Tool } from '@tool'\nimport { intersperse } from '@utils/array'\nimport {\n addLineNumbers,\n detectFileEncoding,\n detectLineEndings,\n detectRepoLineEndings,\n writeTextContent,\n} from '@utils/file'\nimport { logError } from '@utils/log'\nimport { getCwd } from '@utils/state'\nimport { getTheme } from '@utils/theme'\nimport { PROMPT } from './prompt'\nimport { hasWritePermission } from '@utils/permissions/filesystem'\nimport { getPatch } from '@utils/diff'\nimport { PROJECT_FILE } from '@constants/product'\nimport { emitReminderEvent } from '@services/systemReminder'\nimport { recordFileEdit } from '@services/fileFreshness'\nimport { triggerBackup } from '@core/backupHook'\n\nconst MAX_LINES_TO_RENDER = 5\nconst MAX_LINES_TO_RENDER_FOR_ASSISTANT = 16000\nconst TRUNCATED_MESSAGE =\n '<response clipped><NOTE>To save on context only part of this file has been shown to you. You should retry this tool after you have searched inside the file with Grep in order to find the line numbers of what you are looking for.</NOTE>'\n\nconst inputSchema = z.strictObject({\n file_path: z\n .string()\n .describe(\n 'The absolute path to the file to write (must be absolute, not relative)',\n ),\n content: z.string().describe('The content to write to the file'),\n})\n\nexport const FileWriteTool = {\n name: 'Write',\n async description() {\n return 'Write a file to the local filesystem.'\n },\n userFacingName: () => 'Write',\n async prompt() {\n return PROMPT\n },\n inputSchema,\n async isEnabled() {\n return true\n },\n isReadOnly() {\n return false\n },\n isConcurrencySafe() {\n return false // FileWriteTool modifies state/files, not safe for concurrent execution\n },\n needsPermissions({ file_path }) {\n return !hasWritePermission(file_path)\n },\n renderToolUseMessage(input, { verbose }) {\n return `file_path: ${verbose ? input.file_path : relative(getCwd(), input.file_path)}`\n },\n renderToolUseRejectedMessage(\n { file_path, content }: any = {},\n { columns, verbose }: any = {},\n ) {\n try {\n if (!file_path) {\n return <FallbackToolUseRejectedMessage />\n }\n const fullFilePath = isAbsolute(file_path)\n ? file_path\n : resolve(getCwd(), file_path)\n const oldFileExists = existsSync(fullFilePath)\n const enc = oldFileExists ? detectFileEncoding(fullFilePath) : 'utf-8'\n const oldContent = oldFileExists ? readFileSync(fullFilePath, enc) : null\n const type = oldContent ? 'update' : 'create'\n const patch = getPatch({\n filePath: file_path,\n fileContents: oldContent ?? '',\n oldStr: oldContent ?? '',\n newStr: content,\n })\n\n return (\n <Box flexDirection=\"column\">\n <Text>\n {' '}\u23BF{' '}\n <Text color={getTheme().error}>\n User rejected {type === 'update' ? 'update' : 'write'} to{' '}\n </Text>\n <Text bold>\n {verbose ? file_path : relative(getCwd(), file_path)}\n </Text>\n </Text>\n {intersperse(\n patch.map(_ => (\n <Box flexDirection=\"column\" paddingLeft={5} key={_.newStart}>\n <StructuredDiff patch={_} dim={true} width={columns - 12} />\n </Box>\n )),\n i => (\n <Box paddingLeft={5} key={`ellipsis-${i}`}>\n <Text color={getTheme().secondaryText}>...</Text>\n </Box>\n ),\n )}\n </Box>\n )\n } catch (e) {\n // Handle the case where while we were showing the diff, the user manually made the change.\n // TODO: Find a way to show the diff in this case\n logError(e)\n return (\n <Box flexDirection=\"column\">\n <Text>{' '}\u23BF (No changes)</Text>\n </Box>\n )\n }\n },\n renderToolResultMessage(\n { filePath, content, structuredPatch, type },\n options?: { verbose?: boolean },\n ) {\n const verbose = options?.verbose ?? false\n switch (type) {\n case 'create': {\n const contentWithFallback = content || '(No content)'\n const numLines = content.split(EOL).length\n\n return (\n <Box flexDirection=\"column\">\n <Text>\n {' '}\u23BF Wrote {numLines} lines to{' '}\n <Text bold>\n {verbose ? filePath : relative(getCwd(), filePath)}\n </Text>\n </Text>\n {/* Only show code preview in verbose mode */}\n {verbose && (\n <Box flexDirection=\"column\" paddingLeft={5}>\n <HighlightedCode\n code={contentWithFallback\n .split('\\n')\n .slice(0, MAX_LINES_TO_RENDER)\n .filter(_ => _.trim() !== '')\n .join('\\n')}\n language={extname(filePath).slice(1)}\n />\n {numLines > MAX_LINES_TO_RENDER && (\n <Text color={getTheme().secondaryText}>\n ... (+{numLines - MAX_LINES_TO_RENDER} lines)\n </Text>\n )}\n </Box>\n )}\n </Box>\n )\n }\n case 'update':\n return (\n <FileEditToolUpdatedMessage\n filePath={filePath}\n structuredPatch={structuredPatch}\n verbose={verbose}\n />\n )\n }\n },\n async validateInput({ file_path }, { readFileTimestamps }) {\n const fullFilePath = isAbsolute(file_path)\n ? file_path\n : resolve(getCwd(), file_path)\n if (!existsSync(fullFilePath)) {\n return { result: true }\n }\n\n const readTimestamp = readFileTimestamps[fullFilePath]\n if (!readTimestamp) {\n return {\n result: false,\n message:\n 'File has not been read yet. Read it first before writing to it.',\n }\n }\n\n // Check if file exists and get its last modified time\n const stats = statSync(fullFilePath)\n const lastWriteTime = stats.mtimeMs\n if (lastWriteTime > readTimestamp) {\n return {\n result: false,\n message:\n 'File has been modified since read, either by the user or by a linter. Read it again before attempting to write it.',\n }\n }\n\n return { result: true }\n },\n async *call({ file_path, content }, { readFileTimestamps }) {\n const fullFilePath = isAbsolute(file_path)\n ? file_path\n : resolve(getCwd(), file_path)\n const dir = dirname(fullFilePath)\n const oldFileExists = existsSync(fullFilePath)\n const enc = oldFileExists ? detectFileEncoding(fullFilePath) : 'utf-8'\n const oldContent = oldFileExists ? readFileSync(fullFilePath, enc) : null\n\n const endings = oldFileExists\n ? detectLineEndings(fullFilePath)\n : await detectRepoLineEndings(getCwd())\n\n mkdirSync(dir, { recursive: true })\n writeTextContent(fullFilePath, content, enc, endings!)\n\n // Record Agent edit operation for file freshness tracking\n recordFileEdit(fullFilePath, content)\n triggerBackup(\n fullFilePath,\n oldContent,\n content,\n oldContent ? 'update' : 'create',\n )\n\n // Update read timestamp, to invalidate stale writes\n readFileTimestamps[fullFilePath] = statSync(fullFilePath).mtimeMs\n\n // Log when writing to CLAUDE.md\n if (fullFilePath.endsWith(`${sep}${PROJECT_FILE}`)) {\n }\n\n // Emit file edited event for system reminders\n emitReminderEvent('file:edited', {\n filePath: fullFilePath,\n content,\n oldContent: oldContent || '',\n timestamp: Date.now(),\n operation: oldFileExists ? 'update' : 'create',\n })\n\n if (oldContent) {\n const patch = getPatch({\n filePath: file_path,\n fileContents: oldContent,\n oldStr: oldContent,\n newStr: content,\n })\n\n const data = {\n type: 'update' as const,\n filePath: file_path,\n content,\n structuredPatch: patch,\n }\n yield {\n type: 'result',\n data,\n resultForAssistant: this.renderResultForAssistant(data),\n }\n return\n }\n\n const data = {\n type: 'create' as const,\n filePath: file_path,\n content,\n structuredPatch: [],\n }\n yield {\n type: 'result',\n data,\n resultForAssistant: this.renderResultForAssistant(data),\n }\n },\n renderResultForAssistant({ filePath, content, type }) {\n switch (type) {\n case 'create':\n return `File created successfully at: ${filePath}`\n case 'update':\n return `The file ${filePath} has been updated. Here's the result of running \\`cat -n\\` on a snippet of the edited file:\n${addLineNumbers({\n content:\n content.split(/\\r?\\n/).length > MAX_LINES_TO_RENDER_FOR_ASSISTANT\n ? content\n .split(/\\r?\\n/)\n .slice(0, MAX_LINES_TO_RENDER_FOR_ASSISTANT)\n .join('\\n') + TRUNCATED_MESSAGE\n : content,\n startLine: 1,\n})}`\n }\n },\n} satisfies Tool<\n typeof inputSchema,\n {\n type: 'create' | 'update'\n filePath: string\n content: string\n structuredPatch: Hunk[]\n }\n>\n"],
5
- "mappings": "AACA,SAAS,YAAY,WAAW,cAAc,gBAAgB;AAC9D,SAAS,KAAK,YAAY;AAC1B,SAAS,WAAW;AACpB,SAAS,SAAS,SAAS,YAAY,UAAU,SAAS,WAAW;AACrE,YAAY,WAAW;AACvB,SAAS,SAAS;AAClB,SAAS,kCAAkC;AAC3C,SAAS,uBAAuB;AAChC,SAAS,sBAAsB;AAC/B,SAAS,sCAAsC;AAE/C,SAAS,mBAAmB;AAC5B;AAAA,EACE;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,OACK;AACP,SAAS,gBAAgB;AACzB,SAAS,cAAc;AACvB,SAAS,gBAAgB;AACzB,SAAS,cAAc;AACvB,SAAS,0BAA0B;AACnC,SAAS,gBAAgB;AACzB,SAAS,oBAAoB;AAC7B,SAAS,yBAAyB;AAClC,SAAS,sBAAsB;AAC/B,SAAS,qBAAqB;AAE9B,MAAM,sBAAsB;AAC5B,MAAM,oCAAoC;AAC1C,MAAM,oBACJ;AAEF,MAAM,cAAc,EAAE,aAAa;AAAA,EACjC,WAAW,EACR,OAAO,EACP;AAAA,IACC;AAAA,EACF;AAAA,EACF,SAAS,EAAE,OAAO,EAAE,SAAS,kCAAkC;AACjE,CAAC;AAEM,MAAM,gBAAgB;AAAA,EAC3B,MAAM;AAAA,EACN,MAAM,cAAc;AAClB,WAAO;AAAA,EACT;AAAA,EACA,gBAAgB,MAAM;AAAA,EACtB,MAAM,SAAS;AACb,WAAO;AAAA,EACT;AAAA,EACA;AAAA,EACA,MAAM,YAAY;AAChB,WAAO;AAAA,EACT;AAAA,EACA,aAAa;AACX,WAAO;AAAA,EACT;AAAA,EACA,oBAAoB;AAClB,WAAO;AAAA,EACT;AAAA,EACA,iBAAiB,EAAE,UAAU,GAAG;AAC9B,WAAO,CAAC,mBAAmB,SAAS;AAAA,EACtC;AAAA,EACA,qBAAqB,OAAO,EAAE,QAAQ,GAAG;AACvC,WAAO,cAAc,UAAU,MAAM,YAAY,SAAS,OAAO,GAAG,MAAM,SAAS,CAAC;AAAA,EACtF;AAAA,EACA,6BACE,EAAE,WAAW,QAAQ,IAAS,CAAC,GAC/B,EAAE,SAAS,QAAQ,IAAS,CAAC,GAC7B;AACA,QAAI;AACF,UAAI,CAAC,WAAW;AACd,eAAO,oCAAC,oCAA+B;AAAA,MACzC;AACA,YAAM,eAAe,WAAW,SAAS,IACrC,YACA,QAAQ,OAAO,GAAG,SAAS;AAC/B,YAAM,gBAAgB,WAAW,YAAY;AAC7C,YAAM,MAAM,gBAAgB,mBAAmB,YAAY,IAAI;AAC/D,YAAM,aAAa,gBAAgB,aAAa,cAAc,GAAG,IAAI;AACrE,YAAM,OAAO,aAAa,WAAW;AACrC,YAAM,QAAQ,SAAS;AAAA,QACrB,UAAU;AAAA,QACV,cAAc,cAAc;AAAA,QAC5B,QAAQ,cAAc;AAAA,QACtB,QAAQ;AAAA,MACV,CAAC;AAED,aACE,oCAAC,OAAI,eAAc,YACjB,oCAAC,YACE,MAAK,UAAE,KACR,oCAAC,QAAK,OAAO,SAAS,EAAE,SAAO,kBACd,SAAS,WAAW,WAAW,SAAQ,OAAI,GAC5D,GACA,oCAAC,QAAK,MAAI,QACP,UAAU,YAAY,SAAS,OAAO,GAAG,SAAS,CACrD,CACF,GACC;AAAA,QACC,MAAM,IAAI,OACR,oCAAC,OAAI,eAAc,UAAS,aAAa,GAAG,KAAK,EAAE,YACjD,oCAAC,kBAAe,OAAO,GAAG,KAAK,MAAM,OAAO,UAAU,IAAI,CAC5D,CACD;AAAA,QACD,OACE,oCAAC,OAAI,aAAa,GAAG,KAAK,YAAY,CAAC,MACrC,oCAAC,QAAK,OAAO,SAAS,EAAE,iBAAe,KAAG,CAC5C;AAAA,MAEJ,CACF;AAAA,IAEJ,SAAS,GAAG;AAGV,eAAS,CAAC;AACV,aACE,oCAAC,OAAI,eAAc,YACjB,oCAAC,YAAM,MAAK,qBAAc,CAC5B;AAAA,IAEJ;AAAA,EACF;AAAA,EACA,wBACE,EAAE,UAAU,SAAS,iBAAiB,KAAK,GAC3C,SACA;AACA,UAAM,UAAU,SAAS,WAAW;AACpC,YAAQ,MAAM;AAAA,MACZ,KAAK,UAAU;AACb,cAAM,sBAAsB,WAAW;AACvC,cAAM,WAAW,QAAQ,MAAM,GAAG,EAAE;AAEpC,eACE,oCAAC,OAAI,eAAc,YACjB,oCAAC,YACE,MAAK,iBAAS,UAAS,aAAU,KAClC,oCAAC,QAAK,MAAI,QACP,UAAU,WAAW,SAAS,OAAO,GAAG,QAAQ,CACnD,CACF,GAEC,WACC,oCAAC,OAAI,eAAc,UAAS,aAAa,KACvC;AAAA,UAAC;AAAA;AAAA,YACC,MAAM,oBACH,MAAM,IAAI,EACV,MAAM,GAAG,mBAAmB,EAC5B,OAAO,OAAK,EAAE,KAAK,MAAM,EAAE,EAC3B,KAAK,IAAI;AAAA,YACZ,UAAU,QAAQ,QAAQ,EAAE,MAAM,CAAC;AAAA;AAAA,QACrC,GACC,WAAW,uBACV,oCAAC,QAAK,OAAO,SAAS,EAAE,iBAAe,UAC9B,WAAW,qBAAoB,SACxC,CAEJ,CAEJ;AAAA,MAEJ;AAAA,MACA,KAAK;AACH,eACE;AAAA,UAAC;AAAA;AAAA,YACC;AAAA,YACA;AAAA,YACA;AAAA;AAAA,QACF;AAAA,IAEN;AAAA,EACF;AAAA,EACA,MAAM,cAAc,EAAE,UAAU,GAAG,EAAE,mBAAmB,GAAG;AACzD,UAAM,eAAe,WAAW,SAAS,IACrC,YACA,QAAQ,OAAO,GAAG,SAAS;AAC/B,QAAI,CAAC,WAAW,YAAY,GAAG;AAC7B,aAAO,EAAE,QAAQ,KAAK;AAAA,IACxB;AAEA,UAAM,gBAAgB,mBAAmB,YAAY;AACrD,QAAI,CAAC,eAAe;AAClB,aAAO;AAAA,QACL,QAAQ;AAAA,QACR,SACE;AAAA,MACJ;AAAA,IACF;AAGA,UAAM,QAAQ,SAAS,YAAY;AACnC,UAAM,gBAAgB,MAAM;AAC5B,QAAI,gBAAgB,eAAe;AACjC,aAAO;AAAA,QACL,QAAQ;AAAA,QACR,SACE;AAAA,MACJ;AAAA,IACF;AAEA,WAAO,EAAE,QAAQ,KAAK;AAAA,EACxB;AAAA,EACA,OAAO,KAAK,EAAE,WAAW,QAAQ,GAAG,EAAE,mBAAmB,GAAG;AAC1D,UAAM,eAAe,WAAW,SAAS,IACrC,YACA,QAAQ,OAAO,GAAG,SAAS;AAC/B,UAAM,MAAM,QAAQ,YAAY;AAChC,UAAM,gBAAgB,WAAW,YAAY;AAC7C,UAAM,MAAM,gBAAgB,mBAAmB,YAAY,IAAI;AAC/D,UAAM,aAAa,gBAAgB,aAAa,cAAc,GAAG,IAAI;AAErE,UAAM,UAAU,gBACZ,kBAAkB,YAAY,IAC9B,MAAM,sBAAsB,OAAO,CAAC;AAExC,cAAU,KAAK,EAAE,WAAW,KAAK,CAAC;AAClC,qBAAiB,cAAc,SAAS,KAAK,OAAQ;AAGrD,mBAAe,cAAc,OAAO;AACpC;AAAA,MACE;AAAA,MACA;AAAA,MACA;AAAA,MACA,aAAa,WAAW;AAAA,IAC1B;AAGA,uBAAmB,YAAY,IAAI,SAAS,YAAY,EAAE;AAG1D,QAAI,aAAa,SAAS,GAAG,GAAG,GAAG,YAAY,EAAE,GAAG;AAAA,IACpD;AAGA,sBAAkB,eAAe;AAAA,MAC/B,UAAU;AAAA,MACV;AAAA,MACA,YAAY,cAAc;AAAA,MAC1B,WAAW,KAAK,IAAI;AAAA,MACpB,WAAW,gBAAgB,WAAW;AAAA,IACxC,CAAC;AAED,QAAI,YAAY;AACd,YAAM,QAAQ,SAAS;AAAA,QACrB,UAAU;AAAA,QACV,cAAc;AAAA,QACd,QAAQ;AAAA,QACR,QAAQ;AAAA,MACV,CAAC;AAED,YAAMA,QAAO;AAAA,QACX,MAAM;AAAA,QACN,UAAU;AAAA,QACV;AAAA,QACA,iBAAiB;AAAA,MACnB;AACA,YAAM;AAAA,QACJ,MAAM;AAAA,QACN,MAAAA;AAAA,QACA,oBAAoB,KAAK,yBAAyBA,KAAI;AAAA,MACxD;AACA;AAAA,IACF;AAEA,UAAM,OAAO;AAAA,MACX,MAAM;AAAA,MACN,UAAU;AAAA,MACV;AAAA,MACA,iBAAiB,CAAC;AAAA,IACpB;AACA,UAAM;AAAA,MACJ,MAAM;AAAA,MACN;AAAA,MACA,oBAAoB,KAAK,yBAAyB,IAAI;AAAA,IACxD;AAAA,EACF;AAAA,EACA,yBAAyB,EAAE,UAAU,SAAS,KAAK,GAAG;AACpD,YAAQ,MAAM;AAAA,MACZ,KAAK;AACH,eAAO,iCAAiC,QAAQ;AAAA,MAClD,KAAK;AACH,eAAO,YAAY,QAAQ;AAAA,EACjC,eAAe;AAAA,UACf,SACE,QAAQ,MAAM,OAAO,EAAE,SAAS,oCAC5B,QACG,MAAM,OAAO,EACb,MAAM,GAAG,iCAAiC,EAC1C,KAAK,IAAI,IAAI,oBAChB;AAAA,UACN,WAAW;AAAA,QACb,CAAC,CAAC;AAAA,IACE;AAAA,EACF;AACF;",
4
+ "sourcesContent": ["import { Hunk } from 'diff'\nimport { existsSync, mkdirSync, readFileSync, statSync } from 'fs'\nimport { Box, Text } from 'ink'\nimport { EOL } from 'os'\nimport { dirname, extname, isAbsolute, relative, resolve, sep } from 'path'\nimport * as React from 'react'\nimport { z } from 'zod'\nimport { FileEditToolUpdatedMessage } from '@components/FileEditToolUpdatedMessage'\nimport { HighlightedCode } from '@components/HighlightedCode'\nimport { StructuredDiff } from '@components/StructuredDiff'\nimport { FallbackToolUseRejectedMessage } from '@components/FallbackToolUseRejectedMessage'\nimport type { Tool } from '@tool'\nimport { intersperse } from '@utils/array'\nimport {\n addLineNumbers,\n detectFileEncoding,\n detectLineEndings,\n detectRepoLineEndings,\n writeTextContent,\n} from '@utils/file'\nimport { logError } from '@utils/log'\nimport { getCwd } from '@utils/state'\nimport { getTheme } from '@utils/theme'\nimport { PROMPT } from './prompt'\nimport { hasWritePermission } from '@utils/permissions/filesystem'\nimport { getPatch } from '@utils/diff'\nimport { PROJECT_FILE } from '@constants/product'\nimport { emitReminderEvent } from '@services/systemReminder'\nimport { recordFileEdit } from '@services/fileFreshness'\nimport { triggerBackup } from '@core/backupHook'\n\nconst MAX_LINES_TO_RENDER = 5\nconst MAX_LINES_TO_RENDER_FOR_ASSISTANT = 16000\nconst TRUNCATED_MESSAGE =\n '<response clipped><NOTE>To save on context only part of this file has been shown to you. You should retry this tool after you have searched inside the file with Grep in order to find the line numbers of what you are looking for.</NOTE>'\n\nconst inputSchema = z.strictObject({\n file_path: z\n .string()\n .describe(\n 'The absolute path to the file to write (must be absolute, not relative)',\n ),\n content: z.string().describe('The content to write to the file'),\n})\n\nexport const FileWriteTool = {\n name: 'Write',\n async description() {\n return 'Write a file to the local filesystem.'\n },\n userFacingName: () => 'Write',\n async prompt() {\n return PROMPT\n },\n inputSchema,\n async isEnabled() {\n return true\n },\n isReadOnly() {\n return false\n },\n isConcurrencySafe() {\n return false // FileWriteTool modifies state/files, not safe for concurrent execution\n },\n needsPermissions({ file_path }) {\n return !hasWritePermission(file_path)\n },\n renderToolUseMessage(input, { verbose }) {\n return `file_path: ${verbose ? input.file_path : relative(getCwd(), input.file_path)}`\n },\n renderToolUseRejectedMessage(\n { file_path, content }: any = {},\n { columns, verbose }: any = {},\n ) {\n try {\n if (!file_path) {\n return <FallbackToolUseRejectedMessage />\n }\n const fullFilePath = isAbsolute(file_path)\n ? file_path\n : resolve(getCwd(), file_path)\n const oldFileExists = existsSync(fullFilePath)\n const enc = oldFileExists ? detectFileEncoding(fullFilePath) : 'utf-8'\n const oldContent = oldFileExists ? readFileSync(fullFilePath, enc) : null\n const type = oldContent ? 'update' : 'create'\n const patch = getPatch({\n filePath: file_path,\n fileContents: oldContent ?? '',\n oldStr: oldContent ?? '',\n newStr: content,\n })\n\n return (\n <Box flexDirection=\"column\">\n <Text>\n {' '}\u23BF{' '}\n <Text color={getTheme().error}>\n User rejected {type === 'update' ? 'update' : 'write'} to{' '}\n </Text>\n <Text bold>\n {verbose ? file_path : relative(getCwd(), file_path)}\n </Text>\n </Text>\n {intersperse(\n patch.map(_ => (\n <Box flexDirection=\"column\" paddingLeft={5} key={_.newStart}>\n <StructuredDiff patch={_} dim={true} width={columns - 12} />\n </Box>\n )),\n i => (\n <Box paddingLeft={5} key={`ellipsis-${i}`}>\n <Text color={getTheme().secondaryText}>...</Text>\n </Box>\n ),\n )}\n </Box>\n )\n } catch (e) {\n // Handle the case where while we were showing the diff, the user manually made the change.\n // TODO: Find a way to show the diff in this case\n logError(e)\n return (\n <Box flexDirection=\"column\">\n <Text>{' '}\u23BF (No changes)</Text>\n </Box>\n )\n }\n },\n renderToolResultMessage(\n { filePath, content, structuredPatch, type },\n options?: { verbose?: boolean },\n ) {\n const verbose = options?.verbose ?? false\n switch (type) {\n case 'create': {\n const contentWithFallback = content || '(No content)'\n const numLines = content.split(EOL).length\n\n return (\n <Box flexDirection=\"column\">\n <Text>\n {' '}\u23BF Wrote {numLines} lines to{' '}\n <Text bold>\n {verbose ? filePath : relative(getCwd(), filePath)}\n </Text>\n </Text>\n {/* Only show code preview in verbose mode */}\n {verbose && (\n <Box flexDirection=\"column\" paddingLeft={5}>\n <HighlightedCode\n code={contentWithFallback\n .split('\\n')\n .slice(0, MAX_LINES_TO_RENDER)\n .filter(_ => _.trim() !== '')\n .join('\\n')}\n language={extname(filePath).slice(1)}\n />\n {numLines > MAX_LINES_TO_RENDER && (\n <Text color={getTheme().secondaryText}>\n ... (+{numLines - MAX_LINES_TO_RENDER} lines)\n </Text>\n )}\n </Box>\n )}\n </Box>\n )\n }\n case 'update':\n return (\n <FileEditToolUpdatedMessage\n filePath={filePath}\n structuredPatch={structuredPatch}\n verbose={verbose}\n />\n )\n }\n },\n async validateInput({ file_path }, { readFileTimestamps }) {\n const fullFilePath = isAbsolute(file_path)\n ? file_path\n : resolve(getCwd(), file_path)\n if (!existsSync(fullFilePath)) {\n return { result: true }\n }\n\n const readTimestamp = readFileTimestamps[fullFilePath]\n if (!readTimestamp) {\n return {\n result: false,\n message:\n 'File has not been read yet. Read it first before writing to it.',\n }\n }\n\n // Check if file exists and get its last modified time\n const stats = statSync(fullFilePath)\n const lastWriteTime = stats.mtimeMs\n if (lastWriteTime > readTimestamp) {\n return {\n result: false,\n message:\n 'File has been modified since read, either by the user or by a linter. Read it again before attempting to write it.',\n }\n }\n\n return { result: true }\n },\n async *call({ file_path, content }, { readFileTimestamps }) {\n const fullFilePath = isAbsolute(file_path)\n ? file_path\n : resolve(getCwd(), file_path)\n const dir = dirname(fullFilePath)\n const oldFileExists = existsSync(fullFilePath)\n const enc = oldFileExists ? detectFileEncoding(fullFilePath) : 'utf-8'\n const oldContent = oldFileExists ? readFileSync(fullFilePath, enc) : null\n\n const endings = oldFileExists\n ? detectLineEndings(fullFilePath)\n : await detectRepoLineEndings(getCwd())\n\n mkdirSync(dir, { recursive: true })\n writeTextContent(fullFilePath, content, enc, endings!)\n\n // Record Agent edit operation for file freshness tracking\n recordFileEdit(fullFilePath, content)\n triggerBackup(\n fullFilePath,\n oldContent,\n content,\n oldContent ? 'update' : 'create',\n )\n\n // Update read timestamp, to invalidate stale writes\n readFileTimestamps[fullFilePath] = statSync(fullFilePath).mtimeMs\n\n // Log when writing to project doc files\n if (\n fullFilePath.endsWith(`${sep}${PROJECT_FILE}`) ||\n fullFilePath.endsWith(`${sep}AGENTS.md`) ||\n fullFilePath.endsWith(`${sep}CLAUDE.md`)\n ) {\n }\n\n // Emit file edited event for system reminders\n emitReminderEvent('file:edited', {\n filePath: fullFilePath,\n content,\n oldContent: oldContent || '',\n timestamp: Date.now(),\n operation: oldFileExists ? 'update' : 'create',\n })\n\n if (oldContent) {\n const patch = getPatch({\n filePath: file_path,\n fileContents: oldContent,\n oldStr: oldContent,\n newStr: content,\n })\n\n const data = {\n type: 'update' as const,\n filePath: file_path,\n content,\n structuredPatch: patch,\n }\n yield {\n type: 'result',\n data,\n resultForAssistant: this.renderResultForAssistant(data),\n }\n return\n }\n\n const data = {\n type: 'create' as const,\n filePath: file_path,\n content,\n structuredPatch: [],\n }\n yield {\n type: 'result',\n data,\n resultForAssistant: this.renderResultForAssistant(data),\n }\n },\n renderResultForAssistant({ filePath, content, type }) {\n switch (type) {\n case 'create':\n return `File created successfully at: ${filePath}`\n case 'update':\n return `The file ${filePath} has been updated. Here's the result of running \\`cat -n\\` on a snippet of the edited file:\n${addLineNumbers({\n content:\n content.split(/\\r?\\n/).length > MAX_LINES_TO_RENDER_FOR_ASSISTANT\n ? content\n .split(/\\r?\\n/)\n .slice(0, MAX_LINES_TO_RENDER_FOR_ASSISTANT)\n .join('\\n') + TRUNCATED_MESSAGE\n : content,\n startLine: 1,\n})}`\n default:\n return `File operation completed at: ${filePath}`\n }\n },\n} satisfies Tool\n"],
5
+ "mappings": "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",
6
6
  "names": ["data"]
7
7
  }
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../../../src/tools/GlobTool/GlobTool.tsx"],
4
- "sourcesContent": ["import { Box, Text } from 'ink'\nimport React from 'react'\nimport { z } from 'zod'\nimport { Cost } from '@components/Cost'\nimport { FallbackToolUseRejectedMessage } from '@components/FallbackToolUseRejectedMessage'\nimport { CollapsibleHint } from '@components/CollapsibleHint'\nimport { Tool } from '@tool'\nimport { getCwd } from '@utils/state'\nimport { glob } from '@utils/file'\nimport { DESCRIPTION, TOOL_NAME_FOR_PROMPT } from './prompt'\nimport { isAbsolute, relative, resolve } from 'path'\nimport { hasReadPermission } from '@utils/permissions/filesystem'\n\nconst inputSchema = z.strictObject({\n pattern: z.string().describe('The glob pattern to match files against'),\n path: z\n .string()\n .optional()\n .describe(\n 'The directory to search in. Defaults to the current working directory.',\n ),\n})\n\ntype Output = {\n durationMs: number\n numFiles: number\n filenames: string[]\n truncated: boolean\n}\n\nexport const GlobTool = {\n name: TOOL_NAME_FOR_PROMPT,\n async description() {\n return DESCRIPTION\n },\n userFacingName() {\n return 'Search'\n },\n inputSchema,\n async isEnabled() {\n return true\n },\n isReadOnly() {\n return true\n },\n isConcurrencySafe() {\n return true // GlobTool is read-only, safe for concurrent execution\n },\n needsPermissions({ path }) {\n return !hasReadPermission(path || getCwd())\n },\n async prompt() {\n return DESCRIPTION\n },\n renderToolUseMessage({ pattern, path }, { verbose }) {\n const absolutePath = path\n ? isAbsolute(path)\n ? path\n : resolve(getCwd(), path)\n : undefined\n const relativePath = absolutePath\n ? relative(getCwd(), absolutePath)\n : undefined\n return `pattern: \"${pattern}\"${relativePath || verbose ? `, path: \"${verbose ? absolutePath : relativePath}\"` : ''}`\n },\n renderToolUseRejectedMessage() {\n return <FallbackToolUseRejectedMessage />\n },\n renderToolResultMessage(output, { verbose }) {\n // Guard against undefined or null output\n if (!output) {\n return (\n <Box justifyContent=\"space-between\" width=\"100%\">\n <Box flexDirection=\"row\">\n <Text>&nbsp;&nbsp;\u23BF &nbsp;Search completed</Text>\n </Box>\n </Box>\n )\n }\n\n // Handle string content for backward compatibility\n if (typeof output === 'string') {\n try {\n output = JSON.parse(output) as Output\n } catch {\n return (\n <Box justifyContent=\"space-between\" width=\"100%\">\n <Box flexDirection=\"row\">\n <Text>&nbsp;&nbsp;\u23BF &nbsp;Search completed</Text>\n </Box>\n </Box>\n )\n }\n }\n\n const numFiles = output?.numFiles ?? 0\n const durationMs = output?.durationMs ?? 0\n // Show expand hint when there are many files and not in verbose mode\n const showExpandHint = !verbose && numFiles > 5\n\n return (\n <Box justifyContent=\"space-between\" width=\"100%\">\n <Box flexDirection=\"row\">\n <Text>&nbsp;&nbsp;\u23BF &nbsp;Found </Text>\n <Text bold>{numFiles} </Text>\n <Text>{numFiles === 0 || numFiles > 1 ? 'files' : 'file'}</Text>\n {showExpandHint && <CollapsibleHint canExpand={true} />}\n </Box>\n <Cost costUSD={0} durationMs={durationMs} debug={false} />\n </Box>\n )\n },\n async *call({ pattern, path }, { abortController }) {\n const start = Date.now()\n const { files, truncated } = await glob(\n pattern,\n path ?? getCwd(),\n { limit: 100, offset: 0 },\n abortController.signal,\n )\n const output: Output = {\n filenames: files,\n durationMs: Date.now() - start,\n numFiles: files.length,\n truncated,\n }\n yield {\n type: 'result',\n resultForAssistant: this.renderResultForAssistant(output),\n data: output,\n }\n },\n renderResultForAssistant(output) {\n let result = output.filenames.join('\\n')\n if (output.filenames.length === 0) {\n result = 'No files found'\n }\n // Only add truncation message if results were actually truncated\n else if (output.truncated) {\n result +=\n '\\n(Results are truncated. Consider using a more specific path or pattern.)'\n }\n return result\n },\n} satisfies Tool<typeof inputSchema, Output>\n"],
4
+ "sourcesContent": ["import { Box, Text } from 'ink'\nimport React from 'react'\nimport { z } from 'zod'\nimport { Cost } from '@components/Cost'\nimport { FallbackToolUseRejectedMessage } from '@components/FallbackToolUseRejectedMessage'\nimport { CollapsibleHint } from '@components/CollapsibleHint'\nimport { Tool } from '@tool'\nimport { getCwd } from '@utils/state'\nimport { glob } from '@utils/file'\nimport { DESCRIPTION, TOOL_NAME_FOR_PROMPT } from './prompt'\nimport { isAbsolute, relative, resolve } from 'path'\nimport { hasReadPermission } from '@utils/permissions/filesystem'\n\nconst inputSchema = z.strictObject({\n pattern: z.string().describe('The glob pattern to match files against'),\n path: z\n .string()\n .optional()\n .describe(\n 'The directory to search in. Defaults to the current working directory.',\n ),\n})\n\ntype Output = {\n durationMs: number\n numFiles: number\n filenames: string[]\n truncated: boolean\n}\n\nexport const GlobTool = {\n name: TOOL_NAME_FOR_PROMPT,\n async description() {\n return DESCRIPTION\n },\n userFacingName() {\n return 'Search'\n },\n inputSchema,\n async isEnabled() {\n return true\n },\n isReadOnly() {\n return true\n },\n isConcurrencySafe() {\n return true // GlobTool is read-only, safe for concurrent execution\n },\n needsPermissions({ path }) {\n return !hasReadPermission(path || getCwd())\n },\n async prompt() {\n return DESCRIPTION\n },\n renderToolUseMessage({ pattern, path }, { verbose }) {\n const absolutePath = path\n ? isAbsolute(path)\n ? path\n : resolve(getCwd(), path)\n : undefined\n const relativePath = absolutePath\n ? relative(getCwd(), absolutePath)\n : undefined\n return `pattern: \"${pattern}\"${relativePath || verbose ? `, path: \"${verbose ? absolutePath : relativePath}\"` : ''}`\n },\n renderToolUseRejectedMessage() {\n return <FallbackToolUseRejectedMessage />\n },\n renderToolResultMessage(output, { verbose }) {\n // Guard against undefined or null output\n if (!output) {\n return (\n <Box justifyContent=\"space-between\" width=\"100%\">\n <Box flexDirection=\"row\">\n <Text>&nbsp;&nbsp;\u23BF &nbsp;Search completed</Text>\n </Box>\n </Box>\n )\n }\n\n // Handle string content for backward compatibility\n if (typeof output === 'string') {\n try {\n output = JSON.parse(output) as Output\n } catch {\n return (\n <Box justifyContent=\"space-between\" width=\"100%\">\n <Box flexDirection=\"row\">\n <Text>&nbsp;&nbsp;\u23BF &nbsp;Search completed</Text>\n </Box>\n </Box>\n )\n }\n }\n\n const numFiles = output?.numFiles ?? 0\n const durationMs = output?.durationMs ?? 0\n // Show expand hint when there are many files and not in verbose mode\n const showExpandHint = !verbose && numFiles > 5\n\n return (\n <Box justifyContent=\"space-between\" width=\"100%\">\n <Box flexDirection=\"row\">\n <Text>&nbsp;&nbsp;\u23BF &nbsp;Found </Text>\n <Text bold>{numFiles} </Text>\n <Text>{numFiles === 0 || numFiles > 1 ? 'files' : 'file'}</Text>\n {showExpandHint && <CollapsibleHint canExpand={true} />}\n </Box>\n <Cost costUSD={0} durationMs={durationMs} debug={false} />\n </Box>\n )\n },\n async *call({ pattern, path }, { abortController }) {\n const start = Date.now()\n const { files, truncated } = await glob(\n pattern,\n path ?? getCwd(),\n { limit: 100, offset: 0 },\n abortController.signal,\n )\n const output: Output = {\n filenames: files,\n durationMs: Date.now() - start,\n numFiles: files.length,\n truncated,\n }\n yield {\n type: 'result',\n resultForAssistant: this.renderResultForAssistant(output),\n data: output,\n }\n },\n renderResultForAssistant(output) {\n let result = output.filenames.join('\\n')\n if (output.filenames.length === 0) {\n result = 'No files found'\n }\n // Only add truncation message if results were actually truncated\n else if (output.truncated) {\n result +=\n '\\n(Results are truncated. Consider using a more specific path or pattern.)'\n }\n return result\n },\n} satisfies Tool\n"],
5
5
  "mappings": "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",
6
6
  "names": []
7
7
  }
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../../../src/tools/GrepTool/GrepTool.tsx"],
4
- "sourcesContent": ["import { stat } from 'fs/promises'\nimport { Box, Text } from 'ink'\nimport React from 'react'\nimport { z } from 'zod'\nimport { Cost } from '@components/Cost'\nimport { FallbackToolUseRejectedMessage } from '@components/FallbackToolUseRejectedMessage'\nimport { CollapsibleHint } from '@components/CollapsibleHint'\nimport { Tool } from '@tool'\nimport { getCwd } from '@utils/state'\nimport { getAbsolutePath, getAbsoluteAndRelativePaths } from '@utils/file'\nimport { ripGrepStreaming, ripGrepStreamingWithContent } from '@utils/ripgrep'\nimport { DESCRIPTION, TOOL_NAME_FOR_PROMPT } from './prompt'\nimport { hasReadPermission } from '@utils/permissions/filesystem'\n\nconst inputSchema = z.strictObject({\n pattern: z\n .string()\n .describe('The regular expression pattern to search for in file contents'),\n path: z\n .string()\n .optional()\n .describe(\n 'File or directory to search in (rg PATH). Defaults to current working directory.',\n ),\n // Backward compatible: 'include' is mapped to 'glob'\n include: z\n .string()\n .optional()\n .describe(\n 'File pattern to include in the search (e.g. \"*.js\", \"*.{ts,tsx}\") - DEPRECATED: use glob instead',\n ),\n glob: z\n .string()\n .optional()\n .describe(\n 'Glob pattern to filter files (e.g. \"*.js\", \"*.{ts,tsx}\") - maps to rg --glob',\n ),\n type: z\n .string()\n .optional()\n .describe(\n 'File type to search (rg --type). Common types: js, py, rust, go, java, etc. More efficient than include for standard file types.',\n ),\n output_mode: z\n .enum(['content', 'files_with_matches', 'count'])\n .optional()\n .describe(\n 'Output mode: \"content\" shows matching lines, \"files_with_matches\" shows file paths (default), \"count\" shows match counts',\n ),\n multiline: z\n .boolean()\n .optional()\n .describe(\n 'Enable multiline mode where . matches newlines and patterns can span lines (rg -U --multiline-dotall). Default: false.',\n ),\n context: z\n .number()\n .optional()\n .describe(\n 'Number of lines to show before and after each match (rg -C). Requires output_mode: \"content\", ignored otherwise.',\n ),\n '-A': z\n .number()\n .optional()\n .describe(\n 'Number of lines to show after each match (rg -A). Requires output_mode: \"content\", ignored otherwise.',\n ),\n '-B': z\n .number()\n .optional()\n .describe(\n 'Number of lines to show before each match (rg -B). Requires output_mode: \"content\", ignored otherwise.',\n ),\n '-C': z.number().optional().describe('Alias for context.'),\n '-n': z\n .boolean()\n .optional()\n .describe(\n 'Show line numbers in output (rg -n). Requires output_mode: \"content\", ignored otherwise. Defaults to true.',\n ),\n '-i': z.boolean().optional().describe('Case insensitive search (rg -i)'),\n head_limit: z\n .number()\n .optional()\n .describe(\n 'Limit output to first N lines/entries, equivalent to \"| head -N\". Works across all output modes: content (limits output lines), files_with_matches (limits file paths), count (limits count entries). Defaults to 0 (unlimited).',\n ),\n offset: z\n .number()\n .optional()\n .describe(\n 'Skip first N lines/entries before applying head_limit, equivalent to \"| tail -n +N | head -N\". Works across all output modes. Defaults to 0.',\n ),\n})\n\nconst MAX_RESULTS = 100\n\ntype Input = typeof inputSchema\ntype OutputMode = 'content' | 'files_with_matches' | 'count'\n\ntype Output = {\n durationMs: number\n numFiles: number\n filenames: string[]\n // For content mode\n content?: string\n numMatches?: number\n // For count mode\n counts?: Array<{ file: string; count: number }>\n // Output mode used\n outputMode: OutputMode\n}\n\nexport const GrepTool = {\n name: TOOL_NAME_FOR_PROMPT,\n async description() {\n return DESCRIPTION\n },\n userFacingName() {\n return 'Search'\n },\n inputSchema,\n isReadOnly() {\n return true\n },\n isConcurrencySafe() {\n return true // Grep is read-only, safe for concurrent execution\n },\n async isEnabled() {\n return true\n },\n needsPermissions({ path }) {\n return !hasReadPermission(path || getCwd())\n },\n async prompt() {\n return DESCRIPTION\n },\n renderToolUseMessage(input, { verbose }) {\n const {\n pattern,\n path,\n include,\n glob,\n type,\n output_mode,\n multiline,\n context,\n '-i': caseInsensitive,\n } = input\n const { absolutePath, relativePath } = getAbsoluteAndRelativePaths(path)\n const effectiveGlob = glob || include\n\n const parts: string[] = [`pattern: \"${pattern}\"`]\n if (relativePath || verbose) {\n parts.push(`path: \"${verbose ? absolutePath : relativePath}\"`)\n }\n if (effectiveGlob) {\n parts.push(`glob: \"${effectiveGlob}\"`)\n }\n if (type) {\n parts.push(`type: \"${type}\"`)\n }\n if (output_mode && output_mode !== 'files_with_matches') {\n parts.push(`mode: \"${output_mode}\"`)\n }\n if (multiline) {\n parts.push('multiline')\n }\n if (context) {\n parts.push(`context: ${context}`)\n }\n if (caseInsensitive === false) {\n parts.push('case-sensitive')\n }\n\n return parts.join(', ')\n },\n renderToolUseRejectedMessage() {\n return <FallbackToolUseRejectedMessage />\n },\n renderToolResultMessage(output, { verbose }) {\n // Guard against undefined or null output\n if (!output) {\n return (\n <Box justifyContent=\"space-between\" width=\"100%\">\n <Box flexDirection=\"row\">\n <Text>&nbsp;&nbsp;\u23BF &nbsp;Search completed</Text>\n </Box>\n </Box>\n )\n }\n\n // Handle string content for backward compatibility\n if (typeof output === 'string') {\n // Convert string to Output type using tmpDeserializeOldLogResult if needed\n output = output as unknown as Output\n }\n\n const numFiles = output?.numFiles ?? 0\n const numMatches = output?.numMatches ?? 0\n const durationMs = output?.durationMs ?? 0\n const outputMode = output?.outputMode ?? 'files_with_matches'\n\n // Different display based on output mode\n if (outputMode === 'content') {\n const showExpandHint = !verbose && numMatches > 10\n return (\n <Box justifyContent=\"space-between\" width=\"100%\">\n <Box flexDirection=\"row\">\n <Text>&nbsp;&nbsp;\u23BF &nbsp;Found </Text>\n <Text bold>{numMatches} </Text>\n <Text>{numMatches === 1 ? 'match' : 'matches'} in </Text>\n <Text bold>{numFiles} </Text>\n <Text>{numFiles === 1 ? 'file' : 'files'}</Text>\n {showExpandHint && <CollapsibleHint canExpand={true} />}\n </Box>\n <Cost costUSD={0} durationMs={durationMs} debug={false} />\n </Box>\n )\n } else if (outputMode === 'count') {\n const showExpandHint = !verbose && numFiles > 5\n return (\n <Box justifyContent=\"space-between\" width=\"100%\">\n <Box flexDirection=\"row\">\n <Text>&nbsp;&nbsp;\u23BF &nbsp;Counted </Text>\n <Text bold>{numMatches} </Text>\n <Text>{numMatches === 1 ? 'match' : 'matches'} in </Text>\n <Text bold>{numFiles} </Text>\n <Text>{numFiles === 1 ? 'file' : 'files'}</Text>\n {showExpandHint && <CollapsibleHint canExpand={true} />}\n </Box>\n <Cost costUSD={0} durationMs={durationMs} debug={false} />\n </Box>\n )\n } else {\n // files_with_matches (default)\n const showExpandHint = !verbose && numFiles > 5\n return (\n <Box justifyContent=\"space-between\" width=\"100%\">\n <Box flexDirection=\"row\">\n <Text>&nbsp;&nbsp;\u23BF &nbsp;Found </Text>\n <Text bold>{numFiles} </Text>\n <Text>{numFiles === 0 || numFiles > 1 ? 'files' : 'file'}</Text>\n {showExpandHint && <CollapsibleHint canExpand={true} />}\n </Box>\n <Cost costUSD={0} durationMs={durationMs} debug={false} />\n </Box>\n )\n }\n },\n renderResultForAssistant(output: Output) {\n const { numFiles, filenames, content, counts, numMatches, outputMode } =\n output\n\n if (outputMode === 'content') {\n if (!content || numMatches === 0) {\n return 'No matches found'\n }\n let result = content\n if (numMatches && numMatches > MAX_RESULTS) {\n result +=\n '\\n(Results are truncated. Consider using a more specific path or pattern.)'\n }\n return result\n } else if (outputMode === 'count') {\n if (!counts || counts.length === 0) {\n return 'No matches found'\n }\n const totalMatches = counts.reduce((sum, c) => sum + c.count, 0)\n let result = `Found ${totalMatches} match${totalMatches === 1 ? '' : 'es'} in ${numFiles} file${numFiles === 1 ? '' : 's'}\\n`\n result += counts\n .slice(0, MAX_RESULTS)\n .map(c => `${c.file}:${c.count}`)\n .join('\\n')\n if (counts.length > MAX_RESULTS) {\n result +=\n '\\n(Results are truncated. Consider using a more specific path or pattern.)'\n }\n return result\n } else {\n // files_with_matches (default)\n if (numFiles === 0) {\n return 'No files found'\n }\n let result = `Found ${numFiles} file${numFiles === 1 ? '' : 's'}\\n${filenames.slice(0, MAX_RESULTS).join('\\n')}`\n if (numFiles > MAX_RESULTS) {\n result +=\n '\\n(Results are truncated. Consider using a more specific path or pattern.)'\n }\n return result\n }\n },\n async *call(input, { abortController }) {\n const {\n pattern,\n path,\n include,\n glob,\n type,\n output_mode = 'files_with_matches',\n multiline,\n context,\n '-A': afterContext,\n '-B': beforeContext,\n '-C': contextAlias,\n '-n': lineNumbers = true,\n '-i': caseInsensitive = true,\n head_limit = 0,\n offset = 0,\n } = input\n\n const start = Date.now()\n const absolutePath = getAbsolutePath(path) || getCwd()\n\n // Use glob if provided, fall back to include for backward compatibility\n const effectiveGlob = glob || include\n\n // Determine effective context value (context takes precedence over -C alias)\n const effectiveContext = context ?? contextAlias\n\n // Build ripgrep arguments based on output mode\n const args: string[] = []\n\n // Case sensitivity\n if (caseInsensitive) {\n args.push('-i')\n }\n\n // Multiline mode\n if (multiline) {\n args.push('-U', '--multiline-dotall')\n }\n\n // File type filter\n if (type) {\n args.push('--type', type)\n }\n\n // Glob filter\n if (effectiveGlob) {\n args.push('--glob', effectiveGlob)\n }\n\n // Output mode specific flags\n if (output_mode === 'files_with_matches') {\n args.push('-l')\n } else if (output_mode === 'count') {\n args.push('-c')\n } else if (output_mode === 'content') {\n // For content mode, add context and line number flags\n if (lineNumbers) {\n args.push('-n')\n }\n if (effectiveContext !== undefined && effectiveContext > 0) {\n args.push('-C', String(effectiveContext))\n } else {\n if (beforeContext !== undefined && beforeContext > 0) {\n args.push('-B', String(beforeContext))\n }\n if (afterContext !== undefined && afterContext > 0) {\n args.push('-A', String(afterContext))\n }\n }\n }\n\n // Add the pattern\n args.push(pattern)\n\n // Different processing based on output mode\n if (output_mode === 'content') {\n // Content mode: collect full output with context\n const contentLines: string[] = []\n const filesWithMatches = new Set<string>()\n let matchCount = 0\n let lastProgressUpdate = 0\n const PROGRESS_UPDATE_INTERVAL = 100\n\n for await (const chunk of ripGrepStreamingWithContent(\n args,\n absolutePath,\n abortController.signal,\n )) {\n if (chunk.type === 'line') {\n contentLines.push(chunk.line)\n // Track files (lines starting with filename:linenum:)\n const fileMatch = chunk.line.match(/^([^:]+):(\\d+):/)\n if (fileMatch) {\n filesWithMatches.add(fileMatch[1])\n matchCount++\n }\n\n // Progress update\n const now = Date.now()\n if (now - lastProgressUpdate >= PROGRESS_UPDATE_INTERVAL) {\n lastProgressUpdate = now\n yield {\n type: 'progress',\n content: {\n type: 'streaming',\n toolName: 'Search',\n stdout: `Searching... Found ${matchCount} match${matchCount === 1 ? '' : 'es'} in ${filesWithMatches.size} file${filesWithMatches.size === 1 ? '' : 's'}`,\n stderr: '',\n isStreaming: true,\n },\n }\n }\n }\n }\n\n // Apply offset and head_limit\n let resultLines = contentLines\n if (offset > 0) {\n resultLines = resultLines.slice(offset)\n }\n if (head_limit > 0) {\n resultLines = resultLines.slice(0, head_limit)\n }\n\n const output: Output = {\n filenames: Array.from(filesWithMatches),\n content: resultLines.join('\\n'),\n numMatches: matchCount,\n numFiles: filesWithMatches.size,\n durationMs: Date.now() - start,\n outputMode: 'content',\n }\n\n yield {\n type: 'result',\n resultForAssistant: this.renderResultForAssistant(output),\n data: output,\n }\n } else if (output_mode === 'count') {\n // Count mode: collect file:count pairs\n const counts: Array<{ file: string; count: number }> = []\n let lastProgressUpdate = 0\n const PROGRESS_UPDATE_INTERVAL = 100\n\n for await (const chunk of ripGrepStreamingWithContent(\n args,\n absolutePath,\n abortController.signal,\n )) {\n if (chunk.type === 'line') {\n // Format: filename:count\n const match = chunk.line.match(/^(.+):(\\d+)$/)\n if (match) {\n counts.push({ file: match[1], count: parseInt(match[2], 10) })\n\n // Progress update\n const now = Date.now()\n if (now - lastProgressUpdate >= PROGRESS_UPDATE_INTERVAL) {\n lastProgressUpdate = now\n yield {\n type: 'progress',\n content: {\n type: 'streaming',\n toolName: 'Search',\n stdout: `Searching... Found matches in ${counts.length} file${counts.length === 1 ? '' : 's'}`,\n stderr: '',\n isStreaming: true,\n },\n }\n }\n }\n }\n }\n\n // Sort by count descending, then by filename\n counts.sort((a, b) => {\n const countDiff = b.count - a.count\n if (countDiff !== 0) return countDiff\n return a.file.localeCompare(b.file)\n })\n\n // Apply offset and head_limit\n let resultCounts = counts\n if (offset > 0) {\n resultCounts = resultCounts.slice(offset)\n }\n if (head_limit > 0) {\n resultCounts = resultCounts.slice(0, head_limit)\n }\n\n const totalMatches = resultCounts.reduce((sum, c) => sum + c.count, 0)\n\n const output: Output = {\n filenames: resultCounts.map(c => c.file),\n counts: resultCounts,\n numMatches: totalMatches,\n numFiles: resultCounts.length,\n durationMs: Date.now() - start,\n outputMode: 'count',\n }\n\n yield {\n type: 'result',\n resultForAssistant: this.renderResultForAssistant(output),\n data: output,\n }\n } else {\n // files_with_matches mode (default): list matching files\n const matchedFiles: string[] = []\n let lastProgressUpdate = 0\n const PROGRESS_UPDATE_INTERVAL = 100\n\n for await (const chunk of ripGrepStreaming(\n args,\n absolutePath,\n abortController.signal,\n )) {\n if (chunk.type === 'match') {\n matchedFiles.push(chunk.file)\n\n // Yield progress update periodically for real-time feedback\n const now = Date.now()\n if (now - lastProgressUpdate >= PROGRESS_UPDATE_INTERVAL) {\n lastProgressUpdate = now\n yield {\n type: 'progress',\n content: {\n type: 'streaming',\n toolName: 'Search',\n stdout: `Searching... Found ${matchedFiles.length} file${matchedFiles.length === 1 ? '' : 's'}`,\n stderr: '',\n isStreaming: true,\n },\n }\n }\n }\n }\n\n // Sort by modification time\n const stats = await Promise.all(\n matchedFiles.map(_ => stat(_).catch(() => null)),\n )\n let matches = matchedFiles\n .map((file, i) => [file, stats[i]] as const)\n .filter(([, s]) => s !== null)\n .sort((a, b) => {\n if (process.env.NODE_ENV === 'test') {\n // In tests, we always want to sort by filename, so that results are deterministic\n return a[0].localeCompare(b[0])\n }\n const timeComparison = (b[1]?.mtimeMs ?? 0) - (a[1]?.mtimeMs ?? 0)\n if (timeComparison === 0) {\n // Sort by filename as a tiebreaker\n return a[0].localeCompare(b[0])\n }\n return timeComparison\n })\n .map(_ => _[0])\n\n // Apply offset and head_limit\n if (offset > 0) {\n matches = matches.slice(offset)\n }\n if (head_limit > 0) {\n matches = matches.slice(0, head_limit)\n }\n\n const output: Output = {\n filenames: matches,\n durationMs: Date.now() - start,\n numFiles: matches.length,\n outputMode: 'files_with_matches',\n }\n\n yield {\n type: 'result',\n resultForAssistant: this.renderResultForAssistant(output),\n data: output,\n }\n }\n },\n} satisfies Tool<Input, Output>\n"],
4
+ "sourcesContent": ["import { stat } from 'fs/promises'\nimport { Box, Text } from 'ink'\nimport React from 'react'\nimport { z } from 'zod'\nimport { Cost } from '@components/Cost'\nimport { FallbackToolUseRejectedMessage } from '@components/FallbackToolUseRejectedMessage'\nimport { CollapsibleHint } from '@components/CollapsibleHint'\nimport { Tool } from '@tool'\nimport { getCwd } from '@utils/state'\nimport { getAbsolutePath, getAbsoluteAndRelativePaths } from '@utils/file'\nimport { ripGrepStreaming, ripGrepStreamingWithContent } from '@utils/ripgrep'\nimport { DESCRIPTION, TOOL_NAME_FOR_PROMPT } from './prompt'\nimport { hasReadPermission } from '@utils/permissions/filesystem'\n\nconst inputSchema = z.strictObject({\n pattern: z\n .string()\n .describe('The regular expression pattern to search for in file contents'),\n path: z\n .string()\n .optional()\n .describe(\n 'File or directory to search in (rg PATH). Defaults to current working directory.',\n ),\n // Backward compatible: 'include' is mapped to 'glob'\n include: z\n .string()\n .optional()\n .describe(\n 'File pattern to include in the search (e.g. \"*.js\", \"*.{ts,tsx}\") - DEPRECATED: use glob instead',\n ),\n glob: z\n .string()\n .optional()\n .describe(\n 'Glob pattern to filter files (e.g. \"*.js\", \"*.{ts,tsx}\") - maps to rg --glob',\n ),\n type: z\n .string()\n .optional()\n .describe(\n 'File type to search (rg --type). Common types: js, py, rust, go, java, etc. More efficient than include for standard file types.',\n ),\n output_mode: z\n .enum(['content', 'files_with_matches', 'count'])\n .optional()\n .describe(\n 'Output mode: \"content\" shows matching lines, \"files_with_matches\" shows file paths (default), \"count\" shows match counts',\n ),\n multiline: z\n .boolean()\n .optional()\n .describe(\n 'Enable multiline mode where . matches newlines and patterns can span lines (rg -U --multiline-dotall). Default: false.',\n ),\n context: z\n .number()\n .optional()\n .describe(\n 'Number of lines to show before and after each match (rg -C). Requires output_mode: \"content\", ignored otherwise.',\n ),\n '-A': z\n .number()\n .optional()\n .describe(\n 'Number of lines to show after each match (rg -A). Requires output_mode: \"content\", ignored otherwise.',\n ),\n '-B': z\n .number()\n .optional()\n .describe(\n 'Number of lines to show before each match (rg -B). Requires output_mode: \"content\", ignored otherwise.',\n ),\n '-C': z.number().optional().describe('Alias for context.'),\n '-n': z\n .boolean()\n .optional()\n .describe(\n 'Show line numbers in output (rg -n). Requires output_mode: \"content\", ignored otherwise. Defaults to true.',\n ),\n '-i': z.boolean().optional().describe('Case insensitive search (rg -i)'),\n head_limit: z\n .number()\n .optional()\n .describe(\n 'Limit output to first N lines/entries, equivalent to \"| head -N\". Works across all output modes: content (limits output lines), files_with_matches (limits file paths), count (limits count entries). Defaults to 0 (unlimited).',\n ),\n offset: z\n .number()\n .optional()\n .describe(\n 'Skip first N lines/entries before applying head_limit, equivalent to \"| tail -n +N | head -N\". Works across all output modes. Defaults to 0.',\n ),\n})\n\nconst MAX_RESULTS = 100\n\ntype Input = typeof inputSchema\ntype OutputMode = 'content' | 'files_with_matches' | 'count'\n\ntype Output = {\n durationMs: number\n numFiles: number\n filenames: string[]\n // For content mode\n content?: string\n numMatches?: number\n // For count mode\n counts?: Array<{ file: string; count: number }>\n // Output mode used\n outputMode: OutputMode\n}\n\nexport const GrepTool = {\n name: TOOL_NAME_FOR_PROMPT,\n async description() {\n return DESCRIPTION\n },\n userFacingName() {\n return 'Search'\n },\n inputSchema,\n isReadOnly() {\n return true\n },\n isConcurrencySafe() {\n return true // Grep is read-only, safe for concurrent execution\n },\n async isEnabled() {\n return true\n },\n needsPermissions({ path }) {\n return !hasReadPermission(path || getCwd())\n },\n async prompt() {\n return DESCRIPTION\n },\n renderToolUseMessage(input, { verbose }) {\n const {\n pattern,\n path,\n include,\n glob,\n type,\n output_mode,\n multiline,\n context,\n '-i': caseInsensitive,\n } = input\n const { absolutePath, relativePath } = getAbsoluteAndRelativePaths(path)\n const effectiveGlob = glob || include\n\n const parts: string[] = [`pattern: \"${pattern}\"`]\n if (relativePath || verbose) {\n parts.push(`path: \"${verbose ? absolutePath : relativePath}\"`)\n }\n if (effectiveGlob) {\n parts.push(`glob: \"${effectiveGlob}\"`)\n }\n if (type) {\n parts.push(`type: \"${type}\"`)\n }\n if (output_mode && output_mode !== 'files_with_matches') {\n parts.push(`mode: \"${output_mode}\"`)\n }\n if (multiline) {\n parts.push('multiline')\n }\n if (context) {\n parts.push(`context: ${context}`)\n }\n if (caseInsensitive === false) {\n parts.push('case-sensitive')\n }\n\n return parts.join(', ')\n },\n renderToolUseRejectedMessage() {\n return <FallbackToolUseRejectedMessage />\n },\n renderToolResultMessage(output, { verbose }) {\n // Guard against undefined or null output\n if (!output) {\n return (\n <Box justifyContent=\"space-between\" width=\"100%\">\n <Box flexDirection=\"row\">\n <Text>&nbsp;&nbsp;\u23BF &nbsp;Search completed</Text>\n </Box>\n </Box>\n )\n }\n\n // Handle string content for backward compatibility\n if (typeof output === 'string') {\n // Convert string to Output type using tmpDeserializeOldLogResult if needed\n output = output as unknown as Output\n }\n\n const numFiles = output?.numFiles ?? 0\n const numMatches = output?.numMatches ?? 0\n const durationMs = output?.durationMs ?? 0\n const outputMode = output?.outputMode ?? 'files_with_matches'\n\n // Different display based on output mode\n if (outputMode === 'content') {\n const showExpandHint = !verbose && numMatches > 10\n return (\n <Box justifyContent=\"space-between\" width=\"100%\">\n <Box flexDirection=\"row\">\n <Text>&nbsp;&nbsp;\u23BF &nbsp;Found </Text>\n <Text bold>{numMatches} </Text>\n <Text>{numMatches === 1 ? 'match' : 'matches'} in </Text>\n <Text bold>{numFiles} </Text>\n <Text>{numFiles === 1 ? 'file' : 'files'}</Text>\n {showExpandHint && <CollapsibleHint canExpand={true} />}\n </Box>\n <Cost costUSD={0} durationMs={durationMs} debug={false} />\n </Box>\n )\n } else if (outputMode === 'count') {\n const showExpandHint = !verbose && numFiles > 5\n return (\n <Box justifyContent=\"space-between\" width=\"100%\">\n <Box flexDirection=\"row\">\n <Text>&nbsp;&nbsp;\u23BF &nbsp;Counted </Text>\n <Text bold>{numMatches} </Text>\n <Text>{numMatches === 1 ? 'match' : 'matches'} in </Text>\n <Text bold>{numFiles} </Text>\n <Text>{numFiles === 1 ? 'file' : 'files'}</Text>\n {showExpandHint && <CollapsibleHint canExpand={true} />}\n </Box>\n <Cost costUSD={0} durationMs={durationMs} debug={false} />\n </Box>\n )\n } else {\n // files_with_matches (default)\n const showExpandHint = !verbose && numFiles > 5\n return (\n <Box justifyContent=\"space-between\" width=\"100%\">\n <Box flexDirection=\"row\">\n <Text>&nbsp;&nbsp;\u23BF &nbsp;Found </Text>\n <Text bold>{numFiles} </Text>\n <Text>{numFiles === 0 || numFiles > 1 ? 'files' : 'file'}</Text>\n {showExpandHint && <CollapsibleHint canExpand={true} />}\n </Box>\n <Cost costUSD={0} durationMs={durationMs} debug={false} />\n </Box>\n )\n }\n },\n renderResultForAssistant(output: Output) {\n const { numFiles, filenames, content, counts, numMatches, outputMode } =\n output\n\n if (outputMode === 'content') {\n if (!content || numMatches === 0) {\n return 'No matches found'\n }\n let result = content\n if (numMatches && numMatches > MAX_RESULTS) {\n result +=\n '\\n(Results are truncated. Consider using a more specific path or pattern.)'\n }\n return result\n } else if (outputMode === 'count') {\n if (!counts || counts.length === 0) {\n return 'No matches found'\n }\n const totalMatches = counts.reduce((sum, c) => sum + c.count, 0)\n let result = `Found ${totalMatches} match${totalMatches === 1 ? '' : 'es'} in ${numFiles} file${numFiles === 1 ? '' : 's'}\\n`\n result += counts\n .slice(0, MAX_RESULTS)\n .map(c => `${c.file}:${c.count}`)\n .join('\\n')\n if (counts.length > MAX_RESULTS) {\n result +=\n '\\n(Results are truncated. Consider using a more specific path or pattern.)'\n }\n return result\n } else {\n // files_with_matches (default)\n if (numFiles === 0) {\n return 'No files found'\n }\n let result = `Found ${numFiles} file${numFiles === 1 ? '' : 's'}\\n${filenames.slice(0, MAX_RESULTS).join('\\n')}`\n if (numFiles > MAX_RESULTS) {\n result +=\n '\\n(Results are truncated. Consider using a more specific path or pattern.)'\n }\n return result\n }\n },\n async *call(input, { abortController }) {\n const {\n pattern,\n path,\n include,\n glob,\n type,\n output_mode = 'files_with_matches',\n multiline,\n context,\n '-A': afterContext,\n '-B': beforeContext,\n '-C': contextAlias,\n '-n': lineNumbers = true,\n '-i': caseInsensitive = true,\n head_limit = 0,\n offset = 0,\n } = input\n\n const start = Date.now()\n const absolutePath = getAbsolutePath(path) || getCwd()\n\n // Use glob if provided, fall back to include for backward compatibility\n const effectiveGlob = glob || include\n\n // Determine effective context value (context takes precedence over -C alias)\n const effectiveContext = context ?? contextAlias\n\n // Build ripgrep arguments based on output mode\n const args: string[] = []\n\n // Case sensitivity\n if (caseInsensitive) {\n args.push('-i')\n }\n\n // Multiline mode\n if (multiline) {\n args.push('-U', '--multiline-dotall')\n }\n\n // File type filter\n if (type) {\n args.push('--type', type)\n }\n\n // Glob filter\n if (effectiveGlob) {\n args.push('--glob', effectiveGlob)\n }\n\n // Output mode specific flags\n if (output_mode === 'files_with_matches') {\n args.push('-l')\n } else if (output_mode === 'count') {\n args.push('-c')\n } else if (output_mode === 'content') {\n // For content mode, add context and line number flags\n if (lineNumbers) {\n args.push('-n')\n }\n if (effectiveContext !== undefined && effectiveContext > 0) {\n args.push('-C', String(effectiveContext))\n } else {\n if (beforeContext !== undefined && beforeContext > 0) {\n args.push('-B', String(beforeContext))\n }\n if (afterContext !== undefined && afterContext > 0) {\n args.push('-A', String(afterContext))\n }\n }\n }\n\n // Add the pattern\n args.push(pattern)\n\n // Different processing based on output mode\n if (output_mode === 'content') {\n // Content mode: collect full output with context\n const contentLines: string[] = []\n const filesWithMatches = new Set<string>()\n let matchCount = 0\n let lastProgressUpdate = 0\n const PROGRESS_UPDATE_INTERVAL = 100\n\n for await (const chunk of ripGrepStreamingWithContent(\n args,\n absolutePath,\n abortController.signal,\n )) {\n if (chunk.type === 'line') {\n contentLines.push(chunk.line)\n // Track files (lines starting with filename:linenum:)\n const fileMatch = chunk.line.match(/^([^:]+):(\\d+):/)\n if (fileMatch) {\n filesWithMatches.add(fileMatch[1])\n matchCount++\n }\n\n // Progress update\n const now = Date.now()\n if (now - lastProgressUpdate >= PROGRESS_UPDATE_INTERVAL) {\n lastProgressUpdate = now\n yield {\n type: 'progress',\n content: {\n type: 'streaming',\n toolName: 'Search',\n stdout: `Searching... Found ${matchCount} match${matchCount === 1 ? '' : 'es'} in ${filesWithMatches.size} file${filesWithMatches.size === 1 ? '' : 's'}`,\n stderr: '',\n isStreaming: true,\n },\n }\n }\n }\n }\n\n // Apply offset and head_limit\n let resultLines = contentLines\n if (offset > 0) {\n resultLines = resultLines.slice(offset)\n }\n if (head_limit > 0) {\n resultLines = resultLines.slice(0, head_limit)\n }\n\n const output: Output = {\n filenames: Array.from(filesWithMatches),\n content: resultLines.join('\\n'),\n numMatches: matchCount,\n numFiles: filesWithMatches.size,\n durationMs: Date.now() - start,\n outputMode: 'content',\n }\n\n yield {\n type: 'result',\n resultForAssistant: this.renderResultForAssistant(output),\n data: output,\n }\n } else if (output_mode === 'count') {\n // Count mode: collect file:count pairs\n const counts: Array<{ file: string; count: number }> = []\n let lastProgressUpdate = 0\n const PROGRESS_UPDATE_INTERVAL = 100\n\n for await (const chunk of ripGrepStreamingWithContent(\n args,\n absolutePath,\n abortController.signal,\n )) {\n if (chunk.type === 'line') {\n // Format: filename:count\n const match = chunk.line.match(/^(.+):(\\d+)$/)\n if (match) {\n counts.push({ file: match[1], count: parseInt(match[2], 10) })\n\n // Progress update\n const now = Date.now()\n if (now - lastProgressUpdate >= PROGRESS_UPDATE_INTERVAL) {\n lastProgressUpdate = now\n yield {\n type: 'progress',\n content: {\n type: 'streaming',\n toolName: 'Search',\n stdout: `Searching... Found matches in ${counts.length} file${counts.length === 1 ? '' : 's'}`,\n stderr: '',\n isStreaming: true,\n },\n }\n }\n }\n }\n }\n\n // Sort by count descending, then by filename\n counts.sort((a, b) => {\n const countDiff = b.count - a.count\n if (countDiff !== 0) return countDiff\n return a.file.localeCompare(b.file)\n })\n\n // Apply offset and head_limit\n let resultCounts = counts\n if (offset > 0) {\n resultCounts = resultCounts.slice(offset)\n }\n if (head_limit > 0) {\n resultCounts = resultCounts.slice(0, head_limit)\n }\n\n const totalMatches = resultCounts.reduce((sum, c) => sum + c.count, 0)\n\n const output: Output = {\n filenames: resultCounts.map(c => c.file),\n counts: resultCounts,\n numMatches: totalMatches,\n numFiles: resultCounts.length,\n durationMs: Date.now() - start,\n outputMode: 'count',\n }\n\n yield {\n type: 'result',\n resultForAssistant: this.renderResultForAssistant(output),\n data: output,\n }\n } else {\n // files_with_matches mode (default): list matching files\n const matchedFiles: string[] = []\n let lastProgressUpdate = 0\n const PROGRESS_UPDATE_INTERVAL = 100\n\n for await (const chunk of ripGrepStreaming(\n args,\n absolutePath,\n abortController.signal,\n )) {\n if (chunk.type === 'match') {\n matchedFiles.push(chunk.file)\n\n // Yield progress update periodically for real-time feedback\n const now = Date.now()\n if (now - lastProgressUpdate >= PROGRESS_UPDATE_INTERVAL) {\n lastProgressUpdate = now\n yield {\n type: 'progress',\n content: {\n type: 'streaming',\n toolName: 'Search',\n stdout: `Searching... Found ${matchedFiles.length} file${matchedFiles.length === 1 ? '' : 's'}`,\n stderr: '',\n isStreaming: true,\n },\n }\n }\n }\n }\n\n // Sort by modification time\n const stats = await Promise.all(\n matchedFiles.map(_ => stat(_).catch(() => null)),\n )\n let matches = matchedFiles\n .map((file, i) => [file, stats[i]] as const)\n .filter(([, s]) => s !== null)\n .sort((a, b) => {\n if (process.env.NODE_ENV === 'test') {\n // In tests, we always want to sort by filename, so that results are deterministic\n return a[0].localeCompare(b[0])\n }\n const timeComparison = (b[1]?.mtimeMs ?? 0) - (a[1]?.mtimeMs ?? 0)\n if (timeComparison === 0) {\n // Sort by filename as a tiebreaker\n return a[0].localeCompare(b[0])\n }\n return timeComparison\n })\n .map(_ => _[0])\n\n // Apply offset and head_limit\n if (offset > 0) {\n matches = matches.slice(offset)\n }\n if (head_limit > 0) {\n matches = matches.slice(0, head_limit)\n }\n\n const output: Output = {\n filenames: matches,\n durationMs: Date.now() - start,\n numFiles: matches.length,\n outputMode: 'files_with_matches',\n }\n\n yield {\n type: 'result',\n resultForAssistant: this.renderResultForAssistant(output),\n data: output,\n }\n }\n },\n} satisfies Tool\n"],
5
5
  "mappings": "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",
6
6
  "names": []
7
7
  }
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../../../src/tools/KillShellTool/KillShellTool.tsx"],
4
- "sourcesContent": ["import * as React from 'react'\nimport { z } from 'zod'\nimport { FallbackToolUseRejectedMessage } from '@components/FallbackToolUseRejectedMessage'\nimport { Tool } from '@tool'\nimport { BackgroundShellManager } from '@utils/BackgroundShellManager'\nimport { KillShellToolResultMessage } from './KillShellToolResultMessage'\nimport { PROMPT } from './prompt'\n\nexport const inputSchema = z.strictObject({\n shell_id: z.string().describe('The ID of the background shell to kill'),\n})\n\ntype In = typeof inputSchema\nexport type Out = {\n success: boolean\n message: string\n shellId: string\n}\n\nexport const KillShellTool = {\n name: 'KillShell',\n async description() {\n return 'Kills a running background bash shell by its ID'\n },\n async prompt() {\n return PROMPT\n },\n isReadOnly() {\n return false\n },\n isConcurrencySafe() {\n return true\n },\n inputSchema,\n userFacingName() {\n return 'KillShell'\n },\n async isEnabled() {\n return true\n },\n needsPermissions(): boolean {\n return false // Killing background shells doesn't require user permission\n },\n renderToolUseMessage({ shell_id }) {\n return shell_id\n },\n renderToolUseRejectedMessage() {\n return <FallbackToolUseRejectedMessage />\n },\n renderToolResultMessage(content) {\n return <KillShellToolResultMessage content={content} />\n },\n renderResultForAssistant({ success, message }) {\n return message\n },\n async *call({ shell_id }, { abortController }) {\n const manager = BackgroundShellManager.getInstance()\n const shell = manager.get(shell_id)\n\n if (!shell) {\n const data: Out = {\n success: false,\n message: `Error: Background shell '${shell_id}' not found`,\n shellId: shell_id,\n }\n\n yield {\n type: 'result',\n resultForAssistant: this.renderResultForAssistant(data),\n data,\n }\n return\n }\n\n if (shell.status !== 'running') {\n const data: Out = {\n success: false,\n message: `Error: Shell '${shell_id}' is already ${shell.status}`,\n shellId: shell_id,\n }\n\n yield {\n type: 'result',\n resultForAssistant: this.renderResultForAssistant(data),\n data,\n }\n return\n }\n\n const killed = manager.kill(shell_id)\n\n const data: Out = {\n success: killed,\n message: killed\n ? `Successfully killed background shell '${shell_id}'`\n : `Failed to kill background shell '${shell_id}'`,\n shellId: shell_id,\n }\n\n yield {\n type: 'result',\n resultForAssistant: this.renderResultForAssistant(data),\n data,\n }\n },\n} satisfies Tool<In, Out>\n"],
4
+ "sourcesContent": ["import * as React from 'react'\nimport { z } from 'zod'\nimport { FallbackToolUseRejectedMessage } from '@components/FallbackToolUseRejectedMessage'\nimport { Tool } from '@tool'\nimport { BackgroundShellManager } from '@utils/BackgroundShellManager'\nimport { KillShellToolResultMessage } from './KillShellToolResultMessage'\nimport { PROMPT } from './prompt'\n\nexport const inputSchema = z.strictObject({\n shell_id: z.string().describe('The ID of the background shell to kill'),\n})\n\ntype In = typeof inputSchema\nexport type Out = {\n success: boolean\n message: string\n shellId: string\n}\n\nexport const KillShellTool = {\n name: 'KillShell',\n async description() {\n return 'Kills a running background bash shell by its ID'\n },\n async prompt() {\n return PROMPT\n },\n isReadOnly() {\n return false\n },\n isConcurrencySafe() {\n return true\n },\n inputSchema,\n userFacingName() {\n return 'KillShell'\n },\n async isEnabled() {\n return true\n },\n needsPermissions(): boolean {\n return false // Killing background shells doesn't require user permission\n },\n renderToolUseMessage({ shell_id }) {\n return shell_id\n },\n renderToolUseRejectedMessage() {\n return <FallbackToolUseRejectedMessage />\n },\n renderToolResultMessage(content) {\n return <KillShellToolResultMessage content={content} />\n },\n renderResultForAssistant({ success, message }) {\n return message\n },\n async *call({ shell_id }, { abortController }) {\n const manager = BackgroundShellManager.getInstance()\n const shell = manager.get(shell_id)\n\n if (!shell) {\n const data: Out = {\n success: false,\n message: `Error: Background shell '${shell_id}' not found`,\n shellId: shell_id,\n }\n\n yield {\n type: 'result',\n resultForAssistant: this.renderResultForAssistant(data),\n data,\n }\n return\n }\n\n if (shell.status !== 'running') {\n const data: Out = {\n success: false,\n message: `Error: Shell '${shell_id}' is already ${shell.status}`,\n shellId: shell_id,\n }\n\n yield {\n type: 'result',\n resultForAssistant: this.renderResultForAssistant(data),\n data,\n }\n return\n }\n\n const killed = manager.kill(shell_id)\n\n const data: Out = {\n success: killed,\n message: killed\n ? `Successfully killed background shell '${shell_id}'`\n : `Failed to kill background shell '${shell_id}'`,\n shellId: shell_id,\n }\n\n yield {\n type: 'result',\n resultForAssistant: this.renderResultForAssistant(data),\n data,\n }\n },\n} satisfies Tool\n"],
5
5
  "mappings": "AAAA,YAAY,WAAW;AACvB,SAAS,SAAS;AAClB,SAAS,sCAAsC;AAE/C,SAAS,8BAA8B;AACvC,SAAS,kCAAkC;AAC3C,SAAS,cAAc;AAEhB,MAAM,cAAc,EAAE,aAAa;AAAA,EACxC,UAAU,EAAE,OAAO,EAAE,SAAS,wCAAwC;AACxE,CAAC;AASM,MAAM,gBAAgB;AAAA,EAC3B,MAAM;AAAA,EACN,MAAM,cAAc;AAClB,WAAO;AAAA,EACT;AAAA,EACA,MAAM,SAAS;AACb,WAAO;AAAA,EACT;AAAA,EACA,aAAa;AACX,WAAO;AAAA,EACT;AAAA,EACA,oBAAoB;AAClB,WAAO;AAAA,EACT;AAAA,EACA;AAAA,EACA,iBAAiB;AACf,WAAO;AAAA,EACT;AAAA,EACA,MAAM,YAAY;AAChB,WAAO;AAAA,EACT;AAAA,EACA,mBAA4B;AAC1B,WAAO;AAAA,EACT;AAAA,EACA,qBAAqB,EAAE,SAAS,GAAG;AACjC,WAAO;AAAA,EACT;AAAA,EACA,+BAA+B;AAC7B,WAAO,oCAAC,oCAA+B;AAAA,EACzC;AAAA,EACA,wBAAwB,SAAS;AAC/B,WAAO,oCAAC,8BAA2B,SAAkB;AAAA,EACvD;AAAA,EACA,yBAAyB,EAAE,SAAS,QAAQ,GAAG;AAC7C,WAAO;AAAA,EACT;AAAA,EACA,OAAO,KAAK,EAAE,SAAS,GAAG,EAAE,gBAAgB,GAAG;AAC7C,UAAM,UAAU,uBAAuB,YAAY;AACnD,UAAM,QAAQ,QAAQ,IAAI,QAAQ;AAElC,QAAI,CAAC,OAAO;AACV,YAAMA,QAAY;AAAA,QAChB,SAAS;AAAA,QACT,SAAS,4BAA4B,QAAQ;AAAA,QAC7C,SAAS;AAAA,MACX;AAEA,YAAM;AAAA,QACJ,MAAM;AAAA,QACN,oBAAoB,KAAK,yBAAyBA,KAAI;AAAA,QACtD,MAAAA;AAAA,MACF;AACA;AAAA,IACF;AAEA,QAAI,MAAM,WAAW,WAAW;AAC9B,YAAMA,QAAY;AAAA,QAChB,SAAS;AAAA,QACT,SAAS,iBAAiB,QAAQ,gBAAgB,MAAM,MAAM;AAAA,QAC9D,SAAS;AAAA,MACX;AAEA,YAAM;AAAA,QACJ,MAAM;AAAA,QACN,oBAAoB,KAAK,yBAAyBA,KAAI;AAAA,QACtD,MAAAA;AAAA,MACF;AACA;AAAA,IACF;AAEA,UAAM,SAAS,QAAQ,KAAK,QAAQ;AAEpC,UAAM,OAAY;AAAA,MAChB,SAAS;AAAA,MACT,SAAS,SACL,yCAAyC,QAAQ,MACjD,oCAAoC,QAAQ;AAAA,MAChD,SAAS;AAAA,IACX;AAEA,UAAM;AAAA,MACJ,MAAM;AAAA,MACN,oBAAoB,KAAK,yBAAyB,IAAI;AAAA,MACtD;AAAA,IACF;AAAA,EACF;AACF;",
6
6
  "names": ["data"]
7
7
  }
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../../../src/tools/ListMcpResourcesTool/ListMcpResourcesTool.tsx"],
4
- "sourcesContent": ["import { Box, Text } from 'ink'\nimport React from 'react'\nimport { z } from 'zod'\nimport { Cost } from '@components/Cost'\nimport { FallbackToolUseRejectedMessage } from '@components/FallbackToolUseRejectedMessage'\nimport { Tool } from '@tool'\nimport { listMCPResources, McpResource } from '@services/mcpClient'\nimport { DESCRIPTION, TOOL_NAME_FOR_PROMPT } from './prompt'\nimport { getTheme } from '@utils/theme'\n\nconst inputSchema = z.strictObject({\n server: z\n .string()\n .optional()\n .describe(\n 'Optional server name to filter resources from a specific MCP server',\n ),\n})\n\ntype Output = {\n durationMs: number\n resources: McpResource[]\n}\n\nexport const ListMcpResourcesTool = {\n name: TOOL_NAME_FOR_PROMPT,\n async description() {\n return DESCRIPTION\n },\n userFacingName() {\n return 'List MCP Resources'\n },\n inputSchema,\n async isEnabled() {\n return true\n },\n isReadOnly() {\n return true\n },\n isConcurrencySafe() {\n return true // Read-only operation, safe for concurrent execution\n },\n needsPermissions() {\n return false // No file system access needed\n },\n async prompt() {\n return DESCRIPTION\n },\n renderToolUseMessage({ server }, { verbose }) {\n if (server) {\n return `server: \"${server}\"`\n }\n return verbose ? 'Listing all MCP resources' : ''\n },\n renderToolUseRejectedMessage() {\n return <FallbackToolUseRejectedMessage />\n },\n renderToolResultMessage(output) {\n if (!output) {\n return (\n <Box justifyContent=\"space-between\" width=\"100%\">\n <Box flexDirection=\"row\">\n <Text>&nbsp;&nbsp;\u23BF &nbsp;No resources available</Text>\n </Box>\n </Box>\n )\n }\n\n // Handle string content for backward compatibility\n if (typeof output === 'string') {\n try {\n output = JSON.parse(output) as Output\n } catch {\n return (\n <Box justifyContent=\"space-between\" width=\"100%\">\n <Box flexDirection=\"row\">\n <Text>&nbsp;&nbsp;\u23BF &nbsp;Listed MCP resources</Text>\n </Box>\n </Box>\n )\n }\n }\n\n const numResources = output?.resources?.length ?? 0\n const durationMs = output?.durationMs ?? 0\n\n return (\n <Box justifyContent=\"space-between\" width=\"100%\">\n <Box flexDirection=\"row\">\n <Text>&nbsp;&nbsp;\u23BF &nbsp;Found </Text>\n <Text bold>{numResources} </Text>\n <Text>\n {numResources === 0 || numResources > 1 ? 'resources' : 'resource'}\n </Text>\n </Box>\n <Cost costUSD={0} durationMs={durationMs} debug={false} />\n </Box>\n )\n },\n async *call({ server }) {\n const start = Date.now()\n const resources = await listMCPResources(server)\n const output: Output = {\n resources,\n durationMs: Date.now() - start,\n }\n yield {\n type: 'result',\n resultForAssistant: this.renderResultForAssistant(output),\n data: output,\n }\n },\n renderResultForAssistant(output) {\n if (output.resources.length === 0) {\n return 'No MCP resources available'\n }\n\n const lines: string[] = []\n lines.push(`Found ${output.resources.length} MCP resource(s):`)\n lines.push('')\n\n // Group by server\n const byServer = output.resources.reduce(\n (acc, r) => {\n if (!acc[r.serverName]) acc[r.serverName] = []\n acc[r.serverName].push(r)\n return acc\n },\n {} as Record<string, McpResource[]>,\n )\n\n for (const [serverName, resources] of Object.entries(byServer)) {\n lines.push(`Server: ${serverName}`)\n for (const r of resources) {\n lines.push(` - ${r.name}`)\n lines.push(` URI: ${r.uri}`)\n if (r.description) {\n lines.push(` Description: ${r.description}`)\n }\n if (r.mimeType) {\n lines.push(` MIME Type: ${r.mimeType}`)\n }\n }\n lines.push('')\n }\n\n return lines.join('\\n')\n },\n} satisfies Tool<typeof inputSchema, Output>\n"],
5
- "mappings": "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",
4
+ "sourcesContent": ["import { Box, Text } from 'ink'\nimport React from 'react'\nimport { z } from 'zod'\nimport { Cost } from '@components/Cost'\nimport { FallbackToolUseRejectedMessage } from '@components/FallbackToolUseRejectedMessage'\nimport { Tool } from '@tool'\nimport { listMCPResources, McpResource } from '@services/mcpClient'\nimport { DESCRIPTION, TOOL_NAME_FOR_PROMPT } from './prompt'\nimport { getTheme } from '@utils/theme'\n\nconst inputSchema = z.strictObject({\n server: z\n .string()\n .optional()\n .describe(\n 'Optional server name to filter resources from a specific MCP server',\n ),\n})\n\ntype Output = {\n durationMs: number\n resources: McpResource[]\n}\n\nexport const ListMcpResourcesTool = {\n name: TOOL_NAME_FOR_PROMPT,\n async description() {\n return DESCRIPTION\n },\n userFacingName() {\n return 'List MCP Resources'\n },\n inputSchema,\n async isEnabled() {\n return true\n },\n isReadOnly() {\n return true\n },\n isConcurrencySafe() {\n return true // Read-only operation, safe for concurrent execution\n },\n needsPermissions() {\n return false // No file system access needed\n },\n async prompt() {\n return DESCRIPTION\n },\n renderToolUseMessage({ server }, { verbose }) {\n if (server) {\n return `server: \"${server}\"`\n }\n return verbose ? 'Listing all MCP resources' : ''\n },\n renderToolUseRejectedMessage() {\n return <FallbackToolUseRejectedMessage />\n },\n renderToolResultMessage(output) {\n if (!output) {\n return (\n <Box justifyContent=\"space-between\" width=\"100%\">\n <Box flexDirection=\"row\">\n <Text>&nbsp;&nbsp;\u23BF &nbsp;No resources available</Text>\n </Box>\n </Box>\n )\n }\n\n // Handle string content for backward compatibility\n if (typeof output === 'string') {\n try {\n output = JSON.parse(output) as Output\n } catch {\n return (\n <Box justifyContent=\"space-between\" width=\"100%\">\n <Box flexDirection=\"row\">\n <Text>&nbsp;&nbsp;\u23BF &nbsp;Listed MCP resources</Text>\n </Box>\n </Box>\n )\n }\n }\n\n const numResources = output?.resources?.length ?? 0\n const durationMs = output?.durationMs ?? 0\n\n return (\n <Box justifyContent=\"space-between\" width=\"100%\">\n <Box flexDirection=\"row\">\n <Text>&nbsp;&nbsp;\u23BF &nbsp;Found </Text>\n <Text bold>{numResources} </Text>\n <Text>\n {numResources === 0 || numResources > 1 ? 'resources' : 'resource'}\n </Text>\n </Box>\n <Cost costUSD={0} durationMs={durationMs} debug={false} />\n </Box>\n )\n },\n async *call({ server }) {\n const start = Date.now()\n const resources = await listMCPResources(server)\n const output: Output = {\n resources,\n durationMs: Date.now() - start,\n }\n yield {\n type: 'result',\n resultForAssistant: this.renderResultForAssistant(output),\n data: output,\n }\n },\n renderResultForAssistant(output) {\n if (output.resources.length === 0) {\n return 'No MCP resources available'\n }\n\n const lines: string[] = []\n lines.push(`Found ${output.resources.length} MCP resource(s):`)\n lines.push('')\n\n // Group by server\n const byServer = output.resources.reduce(\n (acc, r) => {\n if (!acc[r.serverName]) acc[r.serverName] = []\n acc[r.serverName].push(r)\n return acc\n },\n {} as Record<string, McpResource[]>,\n )\n\n for (const [serverName, resources] of Object.entries(byServer) as [string, McpResource[]][]) {\n lines.push(`Server: ${serverName}`)\n for (const r of resources) {\n lines.push(` - ${r.name}`)\n lines.push(` URI: ${r.uri}`)\n if (r.description) {\n lines.push(` Description: ${r.description}`)\n }\n if (r.mimeType) {\n lines.push(` MIME Type: ${r.mimeType}`)\n }\n }\n lines.push('')\n }\n\n return lines.join('\\n')\n },\n} satisfies Tool\n"],
5
+ "mappings": "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",
6
6
  "names": []
7
7
  }
@@ -7,6 +7,7 @@ import { extname, join, relative } from "path";
7
7
  import React from "react";
8
8
  import { pathToFileURL } from "url";
9
9
  import { z } from "zod";
10
+ import { debug as debugLogger } from "../../utils/debugLogger.js";
10
11
  import { DESCRIPTION, PROMPT, TOOL_NAME_FOR_PROMPT } from "./prompt.js";
11
12
  const inputSchema = z.strictObject({
12
13
  operation: z.enum([
@@ -180,7 +181,11 @@ function tryLoadTypeScriptModule(projectCwd) {
180
181
  const mod = requireFromCwd("typescript");
181
182
  cachedTypeScript = { cwd: projectCwd, module: mod };
182
183
  return mod;
183
- } catch {
184
+ } catch (e) {
185
+ debugLogger.warn(
186
+ "LSP",
187
+ `Failed to load TypeScript from ${projectCwd}: ${e instanceof Error ? e.message : String(e)}`
188
+ );
184
189
  cachedTypeScript = { cwd: projectCwd, module: null };
185
190
  return null;
186
191
  }
@@ -218,7 +223,11 @@ function getOrCreateTsProject(projectCwd) {
218
223
  rootFileNames = parsed.fileNames;
219
224
  }
220
225
  }
221
- } catch {
226
+ } catch (e) {
227
+ debugLogger.warn(
228
+ "LSP",
229
+ `Failed to parse tsconfig in ${projectCwd}: ${e instanceof Error ? e.message : String(e)}`
230
+ );
222
231
  }
223
232
  const rootFiles = new Set(rootFileNames);
224
233
  const versions = /* @__PURE__ */ new Map();
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../../../src/tools/LspTool/LspTool.tsx"],
4
- "sourcesContent": ["/**\n * LSP Tool\n *\n * Provides Language Server Protocol operations for code intelligence.\n * Currently supports TypeScript/JavaScript files using the project's TypeScript.\n */\n\nimport { FallbackToolUseRejectedMessage } from '@components/FallbackToolUseRejectedMessage'\nimport type { Tool, ToolUseContext } from '@tool'\nimport { getCwd } from '@utils/state'\nimport { existsSync, readFileSync, statSync } from 'fs'\nimport { Box, Text } from 'ink'\nimport { createRequire } from 'node:module'\nimport { extname, join, relative } from 'path'\nimport React from 'react'\nimport { pathToFileURL } from 'url'\nimport { z } from 'zod'\nimport { DESCRIPTION, PROMPT, TOOL_NAME_FOR_PROMPT } from './prompt'\n\ntype TypeScriptModule = typeof import('typescript')\n\ntype Operation =\n | 'goToDefinition'\n | 'findReferences'\n | 'hover'\n | 'documentSymbol'\n | 'workspaceSymbol'\n | 'goToImplementation'\n | 'prepareCallHierarchy'\n | 'incomingCalls'\n | 'outgoingCalls'\n\nconst inputSchema = z.strictObject({\n operation: z\n .enum([\n 'goToDefinition',\n 'findReferences',\n 'hover',\n 'documentSymbol',\n 'workspaceSymbol',\n 'goToImplementation',\n 'prepareCallHierarchy',\n 'incomingCalls',\n 'outgoingCalls',\n ])\n .describe('The LSP operation to perform'),\n filePath: z.string().describe('The absolute or relative path to the file'),\n line: z\n .number()\n .int()\n .positive()\n .describe('The line number (1-based, as shown in editors)'),\n character: z\n .number()\n .int()\n .positive()\n .describe('The character offset (1-based, as shown in editors)'),\n})\n\nconst outputSchema = z.object({\n operation: z\n .enum([\n 'goToDefinition',\n 'findReferences',\n 'hover',\n 'documentSymbol',\n 'workspaceSymbol',\n 'goToImplementation',\n 'prepareCallHierarchy',\n 'incomingCalls',\n 'outgoingCalls',\n ])\n .describe('The LSP operation that was performed'),\n result: z.string().describe('The formatted result of the LSP operation'),\n filePath: z.string().describe('The file path the operation was performed on'),\n resultCount: z\n .number()\n .int()\n .nonnegative()\n .optional()\n .describe('Number of results (definitions, references, symbols)'),\n fileCount: z\n .number()\n .int()\n .nonnegative()\n .optional()\n .describe('Number of files containing results'),\n})\n\ntype Input = z.infer<typeof inputSchema>\ntype Output = z.infer<typeof outputSchema>\n\nconst OPERATION_LABELS: Record<\n Operation,\n { singular: string; plural: string; special?: string }\n> = {\n goToDefinition: { singular: 'definition', plural: 'definitions' },\n findReferences: { singular: 'reference', plural: 'references' },\n documentSymbol: { singular: 'symbol', plural: 'symbols' },\n workspaceSymbol: { singular: 'symbol', plural: 'symbols' },\n hover: { singular: 'hover info', plural: 'hover info', special: 'available' },\n goToImplementation: { singular: 'implementation', plural: 'implementations' },\n prepareCallHierarchy: { singular: 'call item', plural: 'call items' },\n incomingCalls: { singular: 'caller', plural: 'callers' },\n outgoingCalls: { singular: 'callee', plural: 'callees' },\n}\n\nfunction getAbsolutePath(filePath: string): string {\n if (filePath.startsWith('/')) return filePath\n return join(getCwd(), filePath)\n}\n\nfunction toProjectRelativeIfPossible(filePath: string): string {\n const cwd = getCwd()\n try {\n const rel = relative(cwd, filePath)\n if (!rel || rel === '') return filePath\n if (rel.startsWith('..')) return filePath\n return rel\n } catch {\n return filePath\n }\n}\n\nfunction formatLocation(\n fileName: string,\n line0: number,\n character0: number,\n): string {\n return `${toProjectRelativeIfPossible(fileName)}:${line0 + 1}:${character0 + 1}`\n}\n\nfunction formatGoToDefinitionResult(\n locations: Array<{\n fileName: string\n line0: number\n character0: number\n }> | null,\n): { formatted: string; resultCount: number; fileCount: number } {\n if (!locations || locations.length === 0) {\n return {\n formatted:\n 'No definition found. This may occur if the cursor is not on a symbol, or if the definition is in an external library not indexed by the LSP server.',\n resultCount: 0,\n fileCount: 0,\n }\n }\n const fileCount = new Set(locations.map(l => l.fileName)).size\n if (locations.length === 1) {\n const loc = locations[0]\n return {\n formatted: `Defined in ${formatLocation(loc.fileName, loc.line0, loc.character0)}`,\n resultCount: 1,\n fileCount,\n }\n }\n return {\n formatted: `Found ${locations.length} definitions:\\n${locations\n .map(\n loc => ` ${formatLocation(loc.fileName, loc.line0, loc.character0)}`,\n )\n .join('\\n')}`,\n resultCount: locations.length,\n fileCount,\n }\n}\n\nfunction groupLocationsByFile<T extends { fileName: string }>(\n items: T[],\n): Map<string, T[]> {\n const grouped = new Map<string, T[]>()\n for (const item of items) {\n const key = toProjectRelativeIfPossible(item.fileName)\n const existing = grouped.get(key)\n if (existing) existing.push(item)\n else grouped.set(key, [item])\n }\n return grouped\n}\n\nfunction formatFindReferencesResult(\n references: Array<{\n fileName: string\n line0: number\n character0: number\n }> | null,\n): { formatted: string; resultCount: number; fileCount: number } {\n if (!references || references.length === 0) {\n return {\n formatted:\n 'No references found. This may occur if the symbol has no usages, or if the LSP server has not fully indexed the workspace.',\n resultCount: 0,\n fileCount: 0,\n }\n }\n if (references.length === 1) {\n const ref = references[0]\n return {\n formatted: `Found 1 reference:\\n ${formatLocation(ref.fileName, ref.line0, ref.character0)}`,\n resultCount: 1,\n fileCount: 1,\n }\n }\n\n const grouped = groupLocationsByFile(references)\n const lines: string[] = [\n `Found ${references.length} references across ${grouped.size} files:`,\n ]\n for (const [file, refs] of grouped) {\n lines.push(`\\n${file}:`)\n for (const ref of refs) {\n lines.push(` Line ${ref.line0 + 1}:${ref.character0 + 1}`)\n }\n }\n return {\n formatted: lines.join('\\n'),\n resultCount: references.length,\n fileCount: grouped.size,\n }\n}\n\nfunction formatHoverResult(\n hoverText: string | null,\n line0: number,\n character0: number,\n) {\n if (!hoverText || hoverText.trim() === '') {\n return {\n formatted:\n 'No hover information available. This may occur if the cursor is not on a symbol, or if the LSP server has not fully indexed the file.',\n resultCount: 0,\n fileCount: 0,\n }\n }\n return {\n formatted: `Hover info at ${line0 + 1}:${character0 + 1}:\\n\\n${hoverText}`,\n resultCount: 1,\n fileCount: 1,\n }\n}\n\nfunction formatDocumentSymbolsResult(lines: string[], symbolCount: number) {\n if (symbolCount === 0) {\n return {\n formatted:\n 'No symbols found in document. This may occur if the file is empty, not supported by the LSP server, or if the server has not fully indexed the file.',\n resultCount: 0,\n fileCount: 0,\n }\n }\n return {\n formatted: ['Document symbols:', ...lines].join('\\n'),\n resultCount: symbolCount,\n fileCount: 1,\n }\n}\n\n// TypeScript module cache\nlet cachedTypeScript: { cwd: string; module: TypeScriptModule | null } | null =\n null\n\nfunction tryLoadTypeScriptModule(projectCwd: string): TypeScriptModule | null {\n if (cachedTypeScript?.cwd === projectCwd) return cachedTypeScript.module\n\n try {\n const requireFromCwd = createRequire(\n pathToFileURL(join(projectCwd, '__minto_lsp__.js')),\n )\n const mod = requireFromCwd('typescript') as TypeScriptModule\n cachedTypeScript = { cwd: projectCwd, module: mod }\n return mod\n } catch {\n cachedTypeScript = { cwd: projectCwd, module: null }\n return null\n }\n}\n\ntype TsProjectState = {\n ts: TypeScriptModule\n cwd: string\n rootFiles: Set<string>\n compilerOptions: any\n languageService: any\n versions: Map<string, string>\n}\n\nconst projectCache = new Map<string, TsProjectState>()\n\nfunction getOrCreateTsProject(projectCwd: string): TsProjectState | null {\n const ts = tryLoadTypeScriptModule(projectCwd)\n if (!ts) return null\n\n const existing = projectCache.get(projectCwd)\n if (existing) return existing\n\n let compilerOptions: any = {\n allowJs: true,\n checkJs: false,\n jsx: ts.JsxEmit.ReactJSX,\n target: ts.ScriptTarget.ESNext,\n module: ts.ModuleKind.ESNext,\n moduleResolution: ts.ModuleResolutionKind.NodeNext,\n }\n\n let rootFileNames: string[] = []\n try {\n const configPath = ts.findConfigFile(\n projectCwd,\n ts.sys.fileExists,\n 'tsconfig.json',\n )\n if (configPath) {\n const configFile = ts.readConfigFile(configPath, ts.sys.readFile)\n if (!configFile.error) {\n const parsed = ts.parseJsonConfigFileContent(\n configFile.config,\n ts.sys,\n projectCwd,\n )\n compilerOptions = { ...compilerOptions, ...parsed.options }\n rootFileNames = parsed.fileNames\n }\n }\n } catch {\n // Use defaults\n }\n\n const rootFiles = new Set(rootFileNames)\n const versions = new Map<string, string>()\n\n const host: any = {\n getCompilationSettings: () => compilerOptions,\n getScriptFileNames: () => Array.from(rootFiles),\n getScriptVersion: (fileName: string) => {\n try {\n const stat = statSync(fileName)\n const version = String(stat.mtimeMs ?? Date.now())\n versions.set(fileName, version)\n return version\n } catch {\n return versions.get(fileName) ?? '0'\n }\n },\n getScriptSnapshot: (fileName: string) => {\n try {\n if (!ts.sys.fileExists(fileName)) return undefined\n const content = ts.sys.readFile(fileName)\n if (content === undefined) return undefined\n const stat = statSync(fileName)\n versions.set(fileName, String(stat.mtimeMs ?? Date.now()))\n return ts.ScriptSnapshot.fromString(content)\n } catch {\n return undefined\n }\n },\n getCurrentDirectory: () => projectCwd,\n getDefaultLibFileName: (options: any) => ts.getDefaultLibFilePath(options),\n fileExists: ts.sys.fileExists,\n readFile: ts.sys.readFile,\n readDirectory: ts.sys.readDirectory,\n directoryExists: ts.sys.directoryExists,\n getDirectories: ts.sys.getDirectories,\n useCaseSensitiveFileNames: () => ts.sys.useCaseSensitiveFileNames,\n getCanonicalFileName: (fileName: string) =>\n ts.sys.useCaseSensitiveFileNames ? fileName : fileName.toLowerCase(),\n getNewLine: () => ts.sys.newLine,\n }\n\n const languageService = ts.createLanguageService(\n host,\n ts.createDocumentRegistry(),\n )\n\n const state: TsProjectState = {\n ts,\n cwd: projectCwd,\n rootFiles,\n compilerOptions,\n languageService,\n versions,\n }\n projectCache.set(projectCwd, state)\n return state\n}\n\nfunction isFileTypeSupportedByTypescriptBackend(filePath: string): boolean {\n const ext = extname(filePath).toLowerCase()\n return (\n ext === '.ts' ||\n ext === '.tsx' ||\n ext === '.js' ||\n ext === '.jsx' ||\n ext === '.mts' ||\n ext === '.cts' ||\n ext === '.mjs' ||\n ext === '.cjs'\n )\n}\n\nfunction summarizeToolResult(\n operation: Operation,\n resultCount: number,\n fileCount: number,\n) {\n const label = OPERATION_LABELS[operation] ?? {\n singular: 'result',\n plural: 'results',\n }\n const noun = resultCount === 1 ? label.singular : label.plural\n if (operation === 'hover' && resultCount > 0 && label.special) {\n return <Text>Hover info {label.special}</Text>\n }\n return (\n <Text>\n Found <Text bold>{resultCount}</Text> {noun}\n {fileCount > 1 ? (\n <>\n {' '}\n across <Text bold>{fileCount}</Text> files\n </>\n ) : null}\n </Text>\n )\n}\n\nexport const LspTool = {\n name: TOOL_NAME_FOR_PROMPT,\n async description() {\n return DESCRIPTION\n },\n async prompt() {\n return PROMPT\n },\n inputSchema,\n userFacingName() {\n return 'LSP'\n },\n async isEnabled() {\n return tryLoadTypeScriptModule(getCwd()) !== null\n },\n isReadOnly() {\n return true\n },\n isConcurrencySafe() {\n return true\n },\n needsPermissions({ filePath }: Input) {\n // LSP operations are read-only, but we check if file exists\n const abs = getAbsolutePath(filePath)\n return !existsSync(abs)\n },\n async validateInput(input: Input) {\n const parsed = inputSchema.safeParse(input)\n if (!parsed.success) {\n return {\n result: false,\n message: `Invalid input: ${parsed.error.message}`,\n errorCode: 3,\n }\n }\n\n const absPath = getAbsolutePath(input.filePath)\n if (!existsSync(absPath)) {\n return {\n result: false,\n message: `File does not exist: ${input.filePath}`,\n errorCode: 1,\n }\n }\n try {\n if (!statSync(absPath).isFile()) {\n return {\n result: false,\n message: `Path is not a file: ${input.filePath}`,\n errorCode: 2,\n }\n }\n } catch (err) {\n const e = err instanceof Error ? err : new Error(String(err))\n return {\n result: false,\n message: `Cannot access file: ${input.filePath}. ${e.message}`,\n errorCode: 4,\n }\n }\n\n return { result: true }\n },\n renderToolUseMessage(input: Input, { verbose }: { verbose: boolean }) {\n const abs = getAbsolutePath(input.filePath)\n const filePathForDisplay = verbose ? abs : toProjectRelativeIfPossible(abs)\n const parts: string[] = []\n\n parts.push(`operation: \"${input.operation}\"`)\n if (input.filePath) parts.push(`file: \"${filePathForDisplay}\"`)\n if (input.line && input.character) {\n parts.push(`position: ${input.line}:${input.character}`)\n }\n return parts.join(', ')\n },\n renderToolUseRejectedMessage() {\n return <FallbackToolUseRejectedMessage />\n },\n renderToolResultMessage(output: Output, { verbose }: { verbose: boolean }) {\n if (!output) {\n return (\n <Box paddingLeft={2}>\n <Text>LSP operation completed</Text>\n </Box>\n )\n }\n\n if (output.resultCount !== undefined && output.fileCount !== undefined) {\n return (\n <Box flexDirection=\"column\">\n <Box flexDirection=\"row\">\n <Text>&nbsp;&nbsp;\u23BF &nbsp;</Text>\n {summarizeToolResult(\n output.operation,\n output.resultCount,\n output.fileCount,\n )}\n </Box>\n {verbose ? (\n <Box marginLeft={5}>\n <Text>{output.result}</Text>\n </Box>\n ) : null}\n </Box>\n )\n }\n\n return (\n <Box justifyContent=\"space-between\" width=\"100%\">\n <Box flexDirection=\"row\">\n <Text>&nbsp;&nbsp;\u23BF &nbsp;</Text>\n <Text>{output.result}</Text>\n </Box>\n </Box>\n )\n },\n renderResultForAssistant(output: Output) {\n return output?.result ?? 'LSP operation completed'\n },\n async *call(input: Input, _context: ToolUseContext) {\n const absPath = getAbsolutePath(input.filePath)\n\n if (!isFileTypeSupportedByTypescriptBackend(absPath)) {\n const ext = extname(absPath)\n const out: Output = {\n operation: input.operation,\n result: `No LSP server available for file type: ${ext}`,\n filePath: input.filePath,\n resultCount: 0,\n fileCount: 0,\n }\n yield { type: 'result', data: out, resultForAssistant: out.result }\n return\n }\n\n const project = getOrCreateTsProject(getCwd())\n if (!project) {\n const out: Output = {\n operation: input.operation,\n result:\n 'TypeScript not found in project. Install typescript to use LSP features: npm install typescript',\n filePath: input.filePath,\n resultCount: 0,\n fileCount: 0,\n }\n yield { type: 'result', data: out, resultForAssistant: out.result }\n return\n }\n\n project.rootFiles.add(absPath)\n\n const ts = project.ts\n const service = project.languageService\n const program = service.getProgram?.()\n if (!program) {\n const out: Output = {\n operation: input.operation,\n result: `Error performing ${input.operation}: TypeScript program not available`,\n filePath: input.filePath,\n resultCount: 0,\n fileCount: 0,\n }\n yield { type: 'result', data: out, resultForAssistant: out.result }\n return\n }\n\n const sourceFile = program.getSourceFile(absPath)\n if (!sourceFile) {\n const out: Output = {\n operation: input.operation,\n result: `Error performing ${input.operation}: File is not part of the TypeScript program`,\n filePath: input.filePath,\n resultCount: 0,\n fileCount: 0,\n }\n yield { type: 'result', data: out, resultForAssistant: out.result }\n return\n }\n\n const pos = ts.getPositionOfLineAndCharacter(\n sourceFile,\n input.line - 1,\n input.character - 1,\n )\n\n try {\n let formatted: string\n let resultCount = 0\n let fileCount = 0\n\n switch (input.operation) {\n case 'goToDefinition': {\n const defs = service.getDefinitionAtPosition?.(absPath, pos) ?? []\n const locations = defs\n .map((d: any) => {\n const defSourceFile = program.getSourceFile(d.fileName)\n if (!defSourceFile) return null\n const lc = ts.getLineAndCharacterOfPosition(\n defSourceFile,\n d.textSpan.start,\n )\n return {\n fileName: d.fileName,\n line0: lc.line,\n character0: lc.character,\n }\n })\n .filter(Boolean) as Array<{\n fileName: string\n line0: number\n character0: number\n }>\n const res = formatGoToDefinitionResult(locations)\n formatted = res.formatted\n resultCount = res.resultCount\n fileCount = res.fileCount\n break\n }\n case 'goToImplementation': {\n const impls =\n service.getImplementationAtPosition?.(absPath, pos) ?? []\n const locations = impls\n .map((d: any) => {\n const defSourceFile = program.getSourceFile(d.fileName)\n if (!defSourceFile) return null\n const lc = ts.getLineAndCharacterOfPosition(\n defSourceFile,\n d.textSpan.start,\n )\n return {\n fileName: d.fileName,\n line0: lc.line,\n character0: lc.character,\n }\n })\n .filter(Boolean) as Array<{\n fileName: string\n line0: number\n character0: number\n }>\n const res = formatGoToDefinitionResult(locations)\n formatted = res.formatted\n resultCount = res.resultCount\n fileCount = res.fileCount\n break\n }\n case 'findReferences': {\n const referencedSymbols = service.findReferences?.(absPath, pos) ?? []\n const refs: Array<{\n fileName: string\n line0: number\n character0: number\n }> = []\n for (const sym of referencedSymbols) {\n for (const ref of sym.references ?? []) {\n const refSource = program.getSourceFile(ref.fileName)\n if (!refSource) continue\n const lc = ts.getLineAndCharacterOfPosition(\n refSource,\n ref.textSpan.start,\n )\n refs.push({\n fileName: ref.fileName,\n line0: lc.line,\n character0: lc.character,\n })\n }\n }\n const res = formatFindReferencesResult(refs)\n formatted = res.formatted\n resultCount = res.resultCount\n fileCount = res.fileCount\n break\n }\n case 'hover': {\n const info = service.getQuickInfoAtPosition?.(absPath, pos)\n let text: string | null = null\n let hoverLine0 = input.line - 1\n let hoverCharacter0 = input.character - 1\n if (info) {\n const parts: string[] = []\n const signature = ts.displayPartsToString(info.displayParts ?? [])\n if (signature) parts.push(signature)\n const doc = ts.displayPartsToString(info.documentation ?? [])\n if (doc) parts.push(doc)\n if (info.tags && info.tags.length > 0) {\n for (const tag of info.tags) {\n const tagText = ts.displayPartsToString(tag.text ?? [])\n parts.push(`@${tag.name}${tagText ? ` ${tagText}` : ''}`)\n }\n }\n text = parts.filter(Boolean).join('\\n\\n')\n const lc = ts.getLineAndCharacterOfPosition(\n sourceFile,\n info.textSpan.start,\n )\n hoverLine0 = lc.line\n hoverCharacter0 = lc.character\n }\n const res = formatHoverResult(text, hoverLine0, hoverCharacter0)\n formatted = res.formatted\n resultCount = res.resultCount\n fileCount = res.fileCount\n break\n }\n case 'documentSymbol': {\n const tree = service.getNavigationTree?.(absPath)\n const lines: string[] = []\n let count = 0\n\n const kindLabel = (kind: string) => {\n const m = {\n class: 'Class',\n interface: 'Interface',\n enum: 'Enum',\n function: 'Function',\n method: 'Method',\n property: 'Property',\n var: 'Variable',\n let: 'Variable',\n const: 'Constant',\n module: 'Module',\n alias: 'Alias',\n type: 'Type',\n } as Record<string, string>\n return (\n m[kind] ??\n (kind ? kind[0].toUpperCase() + kind.slice(1) : 'Unknown')\n )\n }\n\n const walk = (node: any, depth: number) => {\n const children: any[] = node?.childItems ?? []\n for (const child of children) {\n const span = child.spans?.[0]\n if (!span) continue\n const lc = ts.getLineAndCharacterOfPosition(\n sourceFile,\n span.start,\n )\n const indent = ' '.repeat(depth)\n const label = kindLabel(child.kind)\n const detail = child.kindModifiers\n ? ` ${child.kindModifiers}`\n : ''\n lines.push(\n `${indent}${child.text} (${label})${detail} - Line ${lc.line + 1}`,\n )\n count += 1\n if (child.childItems && child.childItems.length > 0) {\n walk(child, depth + 1)\n }\n }\n }\n walk(tree, 0)\n\n const res = formatDocumentSymbolsResult(lines, count)\n formatted = res.formatted\n resultCount = res.resultCount\n fileCount = res.fileCount\n break\n }\n case 'workspaceSymbol': {\n const items =\n service.getNavigateToItems?.('', 100, undefined, true, true) ?? []\n if (!items || items.length === 0) {\n formatted =\n 'No symbols found in workspace. This may occur if the workspace is empty, or if the LSP server has not finished indexing the project.'\n resultCount = 0\n fileCount = 0\n break\n }\n\n const lines: string[] = [\n `Found ${items.length} symbol${items.length === 1 ? '' : 's'} in workspace:`,\n ]\n const grouped = groupLocationsByFile(\n items.map((it: any) => ({\n fileName: it.fileName,\n item: it,\n })),\n )\n for (const [file, itemsInFile] of grouped) {\n lines.push(`\\n${file}:`)\n for (const wrapper of itemsInFile) {\n const it: any = (wrapper as any).item\n const sf = program.getSourceFile(it.fileName)\n if (!sf) continue\n const span = it.textSpan\n const lc = span\n ? ts.getLineAndCharacterOfPosition(sf, span.start)\n : { line: 0, character: 0 }\n const label = it.kind\n ? String(it.kind)[0].toUpperCase() + String(it.kind).slice(1)\n : 'Symbol'\n let line = ` ${it.name} (${label}) - Line ${lc.line + 1}`\n if (it.containerName) line += ` in ${it.containerName}`\n lines.push(line)\n }\n }\n formatted = lines.join('\\n')\n resultCount = items.length\n fileCount = grouped.size\n break\n }\n case 'prepareCallHierarchy':\n case 'incomingCalls':\n case 'outgoingCalls': {\n const opLabel = input.operation\n formatted = `Error performing ${opLabel}: Call hierarchy is not supported by the TypeScript backend`\n resultCount = 0\n fileCount = 0\n break\n }\n default: {\n formatted = `Error performing ${input.operation}: Unsupported operation`\n resultCount = 0\n fileCount = 0\n }\n }\n\n const out: Output = {\n operation: input.operation,\n result: formatted,\n filePath: input.filePath,\n resultCount,\n fileCount,\n }\n yield { type: 'result', data: out, resultForAssistant: out.result }\n } catch (err) {\n const message = err instanceof Error ? err.message : String(err)\n const out: Output = {\n operation: input.operation,\n result: `Error performing ${input.operation}: ${message}`,\n filePath: input.filePath,\n }\n yield { type: 'result', data: out, resultForAssistant: out.result }\n }\n },\n} satisfies Tool<typeof inputSchema, Output>\n"],
5
- "mappings": "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",
4
+ "sourcesContent": ["/**\n * LSP Tool\n *\n * Provides Language Server Protocol operations for code intelligence.\n * Currently supports TypeScript/JavaScript files using the project's TypeScript.\n */\n\nimport { FallbackToolUseRejectedMessage } from '@components/FallbackToolUseRejectedMessage'\nimport type { Tool, ToolUseContext } from '@tool'\nimport { getCwd } from '@utils/state'\nimport { existsSync, readFileSync, statSync } from 'fs'\nimport { Box, Text } from 'ink'\nimport { createRequire } from 'node:module'\nimport { extname, join, relative } from 'path'\nimport React from 'react'\nimport { pathToFileURL } from 'url'\nimport { z } from 'zod'\nimport { debug as debugLogger } from '@utils/debugLogger'\nimport { DESCRIPTION, PROMPT, TOOL_NAME_FOR_PROMPT } from './prompt'\n\ntype TypeScriptModule = typeof import('typescript')\n\ntype Operation =\n | 'goToDefinition'\n | 'findReferences'\n | 'hover'\n | 'documentSymbol'\n | 'workspaceSymbol'\n | 'goToImplementation'\n | 'prepareCallHierarchy'\n | 'incomingCalls'\n | 'outgoingCalls'\n\nconst inputSchema = z.strictObject({\n operation: z\n .enum([\n 'goToDefinition',\n 'findReferences',\n 'hover',\n 'documentSymbol',\n 'workspaceSymbol',\n 'goToImplementation',\n 'prepareCallHierarchy',\n 'incomingCalls',\n 'outgoingCalls',\n ])\n .describe('The LSP operation to perform'),\n filePath: z.string().describe('The absolute or relative path to the file'),\n line: z\n .number()\n .int()\n .positive()\n .describe('The line number (1-based, as shown in editors)'),\n character: z\n .number()\n .int()\n .positive()\n .describe('The character offset (1-based, as shown in editors)'),\n})\n\nconst outputSchema = z.object({\n operation: z\n .enum([\n 'goToDefinition',\n 'findReferences',\n 'hover',\n 'documentSymbol',\n 'workspaceSymbol',\n 'goToImplementation',\n 'prepareCallHierarchy',\n 'incomingCalls',\n 'outgoingCalls',\n ])\n .describe('The LSP operation that was performed'),\n result: z.string().describe('The formatted result of the LSP operation'),\n filePath: z.string().describe('The file path the operation was performed on'),\n resultCount: z\n .number()\n .int()\n .nonnegative()\n .optional()\n .describe('Number of results (definitions, references, symbols)'),\n fileCount: z\n .number()\n .int()\n .nonnegative()\n .optional()\n .describe('Number of files containing results'),\n})\n\ntype Input = z.infer<typeof inputSchema>\ntype Output = z.infer<typeof outputSchema>\n\nconst OPERATION_LABELS: Record<\n Operation,\n { singular: string; plural: string; special?: string }\n> = {\n goToDefinition: { singular: 'definition', plural: 'definitions' },\n findReferences: { singular: 'reference', plural: 'references' },\n documentSymbol: { singular: 'symbol', plural: 'symbols' },\n workspaceSymbol: { singular: 'symbol', plural: 'symbols' },\n hover: { singular: 'hover info', plural: 'hover info', special: 'available' },\n goToImplementation: { singular: 'implementation', plural: 'implementations' },\n prepareCallHierarchy: { singular: 'call item', plural: 'call items' },\n incomingCalls: { singular: 'caller', plural: 'callers' },\n outgoingCalls: { singular: 'callee', plural: 'callees' },\n}\n\nfunction getAbsolutePath(filePath: string): string {\n if (filePath.startsWith('/')) return filePath\n return join(getCwd(), filePath)\n}\n\nfunction toProjectRelativeIfPossible(filePath: string): string {\n const cwd = getCwd()\n try {\n const rel = relative(cwd, filePath)\n if (!rel || rel === '') return filePath\n if (rel.startsWith('..')) return filePath\n return rel\n } catch {\n return filePath\n }\n}\n\nfunction formatLocation(\n fileName: string,\n line0: number,\n character0: number,\n): string {\n return `${toProjectRelativeIfPossible(fileName)}:${line0 + 1}:${character0 + 1}`\n}\n\nfunction formatGoToDefinitionResult(\n locations: Array<{\n fileName: string\n line0: number\n character0: number\n }> | null,\n): { formatted: string; resultCount: number; fileCount: number } {\n if (!locations || locations.length === 0) {\n return {\n formatted:\n 'No definition found. This may occur if the cursor is not on a symbol, or if the definition is in an external library not indexed by the LSP server.',\n resultCount: 0,\n fileCount: 0,\n }\n }\n const fileCount = new Set(locations.map(l => l.fileName)).size\n if (locations.length === 1) {\n const loc = locations[0]\n return {\n formatted: `Defined in ${formatLocation(loc.fileName, loc.line0, loc.character0)}`,\n resultCount: 1,\n fileCount,\n }\n }\n return {\n formatted: `Found ${locations.length} definitions:\\n${locations\n .map(\n loc => ` ${formatLocation(loc.fileName, loc.line0, loc.character0)}`,\n )\n .join('\\n')}`,\n resultCount: locations.length,\n fileCount,\n }\n}\n\nfunction groupLocationsByFile<T extends { fileName: string }>(\n items: T[],\n): Map<string, T[]> {\n const grouped = new Map<string, T[]>()\n for (const item of items) {\n const key = toProjectRelativeIfPossible(item.fileName)\n const existing = grouped.get(key)\n if (existing) existing.push(item)\n else grouped.set(key, [item])\n }\n return grouped\n}\n\nfunction formatFindReferencesResult(\n references: Array<{\n fileName: string\n line0: number\n character0: number\n }> | null,\n): { formatted: string; resultCount: number; fileCount: number } {\n if (!references || references.length === 0) {\n return {\n formatted:\n 'No references found. This may occur if the symbol has no usages, or if the LSP server has not fully indexed the workspace.',\n resultCount: 0,\n fileCount: 0,\n }\n }\n if (references.length === 1) {\n const ref = references[0]\n return {\n formatted: `Found 1 reference:\\n ${formatLocation(ref.fileName, ref.line0, ref.character0)}`,\n resultCount: 1,\n fileCount: 1,\n }\n }\n\n const grouped = groupLocationsByFile(references)\n const lines: string[] = [\n `Found ${references.length} references across ${grouped.size} files:`,\n ]\n for (const [file, refs] of grouped) {\n lines.push(`\\n${file}:`)\n for (const ref of refs) {\n lines.push(` Line ${ref.line0 + 1}:${ref.character0 + 1}`)\n }\n }\n return {\n formatted: lines.join('\\n'),\n resultCount: references.length,\n fileCount: grouped.size,\n }\n}\n\nfunction formatHoverResult(\n hoverText: string | null,\n line0: number,\n character0: number,\n) {\n if (!hoverText || hoverText.trim() === '') {\n return {\n formatted:\n 'No hover information available. This may occur if the cursor is not on a symbol, or if the LSP server has not fully indexed the file.',\n resultCount: 0,\n fileCount: 0,\n }\n }\n return {\n formatted: `Hover info at ${line0 + 1}:${character0 + 1}:\\n\\n${hoverText}`,\n resultCount: 1,\n fileCount: 1,\n }\n}\n\nfunction formatDocumentSymbolsResult(lines: string[], symbolCount: number) {\n if (symbolCount === 0) {\n return {\n formatted:\n 'No symbols found in document. This may occur if the file is empty, not supported by the LSP server, or if the server has not fully indexed the file.',\n resultCount: 0,\n fileCount: 0,\n }\n }\n return {\n formatted: ['Document symbols:', ...lines].join('\\n'),\n resultCount: symbolCount,\n fileCount: 1,\n }\n}\n\n// TypeScript module cache\nlet cachedTypeScript: { cwd: string; module: TypeScriptModule | null } | null =\n null\n\nfunction tryLoadTypeScriptModule(projectCwd: string): TypeScriptModule | null {\n if (cachedTypeScript?.cwd === projectCwd) return cachedTypeScript.module\n\n try {\n const requireFromCwd = createRequire(\n pathToFileURL(join(projectCwd, '__minto_lsp__.js')),\n )\n const mod = requireFromCwd('typescript') as TypeScriptModule\n cachedTypeScript = { cwd: projectCwd, module: mod }\n return mod\n } catch (e) {\n debugLogger.warn(\n 'LSP',\n `Failed to load TypeScript from ${projectCwd}: ${e instanceof Error ? e.message : String(e)}`,\n )\n cachedTypeScript = { cwd: projectCwd, module: null }\n return null\n }\n}\n\ntype TsProjectState = {\n ts: TypeScriptModule\n cwd: string\n rootFiles: Set<string>\n compilerOptions: any\n languageService: any\n versions: Map<string, string>\n}\n\nconst projectCache = new Map<string, TsProjectState>()\n\nfunction getOrCreateTsProject(projectCwd: string): TsProjectState | null {\n const ts = tryLoadTypeScriptModule(projectCwd)\n if (!ts) return null\n\n const existing = projectCache.get(projectCwd)\n if (existing) return existing\n\n let compilerOptions: any = {\n allowJs: true,\n checkJs: false,\n jsx: ts.JsxEmit.ReactJSX,\n target: ts.ScriptTarget.ESNext,\n module: ts.ModuleKind.ESNext,\n moduleResolution: ts.ModuleResolutionKind.NodeNext,\n }\n\n let rootFileNames: string[] = []\n try {\n const configPath = ts.findConfigFile(\n projectCwd,\n ts.sys.fileExists,\n 'tsconfig.json',\n )\n if (configPath) {\n const configFile = ts.readConfigFile(configPath, ts.sys.readFile)\n if (!configFile.error) {\n const parsed = ts.parseJsonConfigFileContent(\n configFile.config,\n ts.sys,\n projectCwd,\n )\n compilerOptions = { ...compilerOptions, ...parsed.options }\n rootFileNames = parsed.fileNames\n }\n }\n } catch (e) {\n debugLogger.warn(\n 'LSP',\n `Failed to parse tsconfig in ${projectCwd}: ${e instanceof Error ? e.message : String(e)}`,\n )\n }\n\n const rootFiles = new Set(rootFileNames)\n const versions = new Map<string, string>()\n\n const host: any = {\n getCompilationSettings: () => compilerOptions,\n getScriptFileNames: () => Array.from(rootFiles),\n getScriptVersion: (fileName: string) => {\n try {\n const stat = statSync(fileName)\n const version = String(stat.mtimeMs ?? Date.now())\n versions.set(fileName, version)\n return version\n } catch {\n return versions.get(fileName) ?? '0'\n }\n },\n getScriptSnapshot: (fileName: string) => {\n try {\n if (!ts.sys.fileExists(fileName)) return undefined\n const content = ts.sys.readFile(fileName)\n if (content === undefined) return undefined\n const stat = statSync(fileName)\n versions.set(fileName, String(stat.mtimeMs ?? Date.now()))\n return ts.ScriptSnapshot.fromString(content)\n } catch {\n return undefined\n }\n },\n getCurrentDirectory: () => projectCwd,\n getDefaultLibFileName: (options: any) => ts.getDefaultLibFilePath(options),\n fileExists: ts.sys.fileExists,\n readFile: ts.sys.readFile,\n readDirectory: ts.sys.readDirectory,\n directoryExists: ts.sys.directoryExists,\n getDirectories: ts.sys.getDirectories,\n useCaseSensitiveFileNames: () => ts.sys.useCaseSensitiveFileNames,\n getCanonicalFileName: (fileName: string) =>\n ts.sys.useCaseSensitiveFileNames ? fileName : fileName.toLowerCase(),\n getNewLine: () => ts.sys.newLine,\n }\n\n const languageService = ts.createLanguageService(\n host,\n ts.createDocumentRegistry(),\n )\n\n const state: TsProjectState = {\n ts,\n cwd: projectCwd,\n rootFiles,\n compilerOptions,\n languageService,\n versions,\n }\n projectCache.set(projectCwd, state)\n return state\n}\n\nfunction isFileTypeSupportedByTypescriptBackend(filePath: string): boolean {\n const ext = extname(filePath).toLowerCase()\n return (\n ext === '.ts' ||\n ext === '.tsx' ||\n ext === '.js' ||\n ext === '.jsx' ||\n ext === '.mts' ||\n ext === '.cts' ||\n ext === '.mjs' ||\n ext === '.cjs'\n )\n}\n\nfunction summarizeToolResult(\n operation: Operation,\n resultCount: number,\n fileCount: number,\n) {\n const label = OPERATION_LABELS[operation] ?? {\n singular: 'result',\n plural: 'results',\n }\n const noun = resultCount === 1 ? label.singular : label.plural\n if (operation === 'hover' && resultCount > 0 && label.special) {\n return <Text>Hover info {label.special}</Text>\n }\n return (\n <Text>\n Found <Text bold>{resultCount}</Text> {noun}\n {fileCount > 1 ? (\n <>\n {' '}\n across <Text bold>{fileCount}</Text> files\n </>\n ) : null}\n </Text>\n )\n}\n\nexport const LspTool = {\n name: TOOL_NAME_FOR_PROMPT,\n async description() {\n return DESCRIPTION\n },\n async prompt() {\n return PROMPT\n },\n inputSchema,\n userFacingName() {\n return 'LSP'\n },\n async isEnabled() {\n return tryLoadTypeScriptModule(getCwd()) !== null\n },\n isReadOnly() {\n return true\n },\n isConcurrencySafe() {\n return true\n },\n needsPermissions({ filePath }: Input) {\n // LSP operations are read-only, but we check if file exists\n const abs = getAbsolutePath(filePath)\n return !existsSync(abs)\n },\n async validateInput(input: Input) {\n const parsed = inputSchema.safeParse(input)\n if (!parsed.success) {\n return {\n result: false,\n message: `Invalid input: ${parsed.error.message}`,\n errorCode: 3,\n }\n }\n\n const absPath = getAbsolutePath(input.filePath)\n if (!existsSync(absPath)) {\n return {\n result: false,\n message: `File does not exist: ${input.filePath}`,\n errorCode: 1,\n }\n }\n try {\n if (!statSync(absPath).isFile()) {\n return {\n result: false,\n message: `Path is not a file: ${input.filePath}`,\n errorCode: 2,\n }\n }\n } catch (err) {\n const e = err instanceof Error ? err : new Error(String(err))\n return {\n result: false,\n message: `Cannot access file: ${input.filePath}. ${e.message}`,\n errorCode: 4,\n }\n }\n\n return { result: true }\n },\n renderToolUseMessage(input: Input, { verbose }: { verbose: boolean }) {\n const abs = getAbsolutePath(input.filePath)\n const filePathForDisplay = verbose ? abs : toProjectRelativeIfPossible(abs)\n const parts: string[] = []\n\n parts.push(`operation: \"${input.operation}\"`)\n if (input.filePath) parts.push(`file: \"${filePathForDisplay}\"`)\n if (input.line && input.character) {\n parts.push(`position: ${input.line}:${input.character}`)\n }\n return parts.join(', ')\n },\n renderToolUseRejectedMessage() {\n return <FallbackToolUseRejectedMessage />\n },\n renderToolResultMessage(output: Output, { verbose }: { verbose: boolean }) {\n if (!output) {\n return (\n <Box paddingLeft={2}>\n <Text>LSP operation completed</Text>\n </Box>\n )\n }\n\n if (output.resultCount !== undefined && output.fileCount !== undefined) {\n return (\n <Box flexDirection=\"column\">\n <Box flexDirection=\"row\">\n <Text>&nbsp;&nbsp;\u23BF &nbsp;</Text>\n {summarizeToolResult(\n output.operation,\n output.resultCount,\n output.fileCount,\n )}\n </Box>\n {verbose ? (\n <Box marginLeft={5}>\n <Text>{output.result}</Text>\n </Box>\n ) : null}\n </Box>\n )\n }\n\n return (\n <Box justifyContent=\"space-between\" width=\"100%\">\n <Box flexDirection=\"row\">\n <Text>&nbsp;&nbsp;\u23BF &nbsp;</Text>\n <Text>{output.result}</Text>\n </Box>\n </Box>\n )\n },\n renderResultForAssistant(output: Output) {\n return output?.result ?? 'LSP operation completed'\n },\n async *call(input: Input, _context: ToolUseContext) {\n const absPath = getAbsolutePath(input.filePath)\n\n if (!isFileTypeSupportedByTypescriptBackend(absPath)) {\n const ext = extname(absPath)\n const out: Output = {\n operation: input.operation,\n result: `No LSP server available for file type: ${ext}`,\n filePath: input.filePath,\n resultCount: 0,\n fileCount: 0,\n }\n yield { type: 'result', data: out, resultForAssistant: out.result }\n return\n }\n\n const project = getOrCreateTsProject(getCwd())\n if (!project) {\n const out: Output = {\n operation: input.operation,\n result:\n 'TypeScript not found in project. Install typescript to use LSP features: npm install typescript',\n filePath: input.filePath,\n resultCount: 0,\n fileCount: 0,\n }\n yield { type: 'result', data: out, resultForAssistant: out.result }\n return\n }\n\n project.rootFiles.add(absPath)\n\n const ts = project.ts\n const service = project.languageService\n const program = service.getProgram?.()\n if (!program) {\n const out: Output = {\n operation: input.operation,\n result: `Error performing ${input.operation}: TypeScript program not available`,\n filePath: input.filePath,\n resultCount: 0,\n fileCount: 0,\n }\n yield { type: 'result', data: out, resultForAssistant: out.result }\n return\n }\n\n const sourceFile = program.getSourceFile(absPath)\n if (!sourceFile) {\n const out: Output = {\n operation: input.operation,\n result: `Error performing ${input.operation}: File is not part of the TypeScript program`,\n filePath: input.filePath,\n resultCount: 0,\n fileCount: 0,\n }\n yield { type: 'result', data: out, resultForAssistant: out.result }\n return\n }\n\n const pos = ts.getPositionOfLineAndCharacter(\n sourceFile,\n input.line - 1,\n input.character - 1,\n )\n\n try {\n let formatted: string\n let resultCount = 0\n let fileCount = 0\n\n switch (input.operation) {\n case 'goToDefinition': {\n const defs = service.getDefinitionAtPosition?.(absPath, pos) ?? []\n const locations = defs\n .map((d: any) => {\n const defSourceFile = program.getSourceFile(d.fileName)\n if (!defSourceFile) return null\n const lc = ts.getLineAndCharacterOfPosition(\n defSourceFile,\n d.textSpan.start,\n )\n return {\n fileName: d.fileName,\n line0: lc.line,\n character0: lc.character,\n }\n })\n .filter(Boolean) as Array<{\n fileName: string\n line0: number\n character0: number\n }>\n const res = formatGoToDefinitionResult(locations)\n formatted = res.formatted\n resultCount = res.resultCount\n fileCount = res.fileCount\n break\n }\n case 'goToImplementation': {\n const impls =\n service.getImplementationAtPosition?.(absPath, pos) ?? []\n const locations = impls\n .map((d: any) => {\n const defSourceFile = program.getSourceFile(d.fileName)\n if (!defSourceFile) return null\n const lc = ts.getLineAndCharacterOfPosition(\n defSourceFile,\n d.textSpan.start,\n )\n return {\n fileName: d.fileName,\n line0: lc.line,\n character0: lc.character,\n }\n })\n .filter(Boolean) as Array<{\n fileName: string\n line0: number\n character0: number\n }>\n const res = formatGoToDefinitionResult(locations)\n formatted = res.formatted\n resultCount = res.resultCount\n fileCount = res.fileCount\n break\n }\n case 'findReferences': {\n const referencedSymbols = service.findReferences?.(absPath, pos) ?? []\n const refs: Array<{\n fileName: string\n line0: number\n character0: number\n }> = []\n for (const sym of referencedSymbols) {\n for (const ref of sym.references ?? []) {\n const refSource = program.getSourceFile(ref.fileName)\n if (!refSource) continue\n const lc = ts.getLineAndCharacterOfPosition(\n refSource,\n ref.textSpan.start,\n )\n refs.push({\n fileName: ref.fileName,\n line0: lc.line,\n character0: lc.character,\n })\n }\n }\n const res = formatFindReferencesResult(refs)\n formatted = res.formatted\n resultCount = res.resultCount\n fileCount = res.fileCount\n break\n }\n case 'hover': {\n const info = service.getQuickInfoAtPosition?.(absPath, pos)\n let text: string | null = null\n let hoverLine0 = input.line - 1\n let hoverCharacter0 = input.character - 1\n if (info) {\n const parts: string[] = []\n const signature = ts.displayPartsToString(info.displayParts ?? [])\n if (signature) parts.push(signature)\n const doc = ts.displayPartsToString(info.documentation ?? [])\n if (doc) parts.push(doc)\n if (info.tags && info.tags.length > 0) {\n for (const tag of info.tags) {\n const tagText = ts.displayPartsToString(tag.text ?? [])\n parts.push(`@${tag.name}${tagText ? ` ${tagText}` : ''}`)\n }\n }\n text = parts.filter(Boolean).join('\\n\\n')\n const lc = ts.getLineAndCharacterOfPosition(\n sourceFile,\n info.textSpan.start,\n )\n hoverLine0 = lc.line\n hoverCharacter0 = lc.character\n }\n const res = formatHoverResult(text, hoverLine0, hoverCharacter0)\n formatted = res.formatted\n resultCount = res.resultCount\n fileCount = res.fileCount\n break\n }\n case 'documentSymbol': {\n const tree = service.getNavigationTree?.(absPath)\n const lines: string[] = []\n let count = 0\n\n const kindLabel = (kind: string) => {\n const m = {\n class: 'Class',\n interface: 'Interface',\n enum: 'Enum',\n function: 'Function',\n method: 'Method',\n property: 'Property',\n var: 'Variable',\n let: 'Variable',\n const: 'Constant',\n module: 'Module',\n alias: 'Alias',\n type: 'Type',\n } as Record<string, string>\n return (\n m[kind] ??\n (kind ? kind[0].toUpperCase() + kind.slice(1) : 'Unknown')\n )\n }\n\n const walk = (node: any, depth: number) => {\n const children: any[] = node?.childItems ?? []\n for (const child of children) {\n const span = child.spans?.[0]\n if (!span) continue\n const lc = ts.getLineAndCharacterOfPosition(\n sourceFile,\n span.start,\n )\n const indent = ' '.repeat(depth)\n const label = kindLabel(child.kind)\n const detail = child.kindModifiers\n ? ` ${child.kindModifiers}`\n : ''\n lines.push(\n `${indent}${child.text} (${label})${detail} - Line ${lc.line + 1}`,\n )\n count += 1\n if (child.childItems && child.childItems.length > 0) {\n walk(child, depth + 1)\n }\n }\n }\n walk(tree, 0)\n\n const res = formatDocumentSymbolsResult(lines, count)\n formatted = res.formatted\n resultCount = res.resultCount\n fileCount = res.fileCount\n break\n }\n case 'workspaceSymbol': {\n const items =\n service.getNavigateToItems?.('', 100, undefined, true, true) ?? []\n if (!items || items.length === 0) {\n formatted =\n 'No symbols found in workspace. This may occur if the workspace is empty, or if the LSP server has not finished indexing the project.'\n resultCount = 0\n fileCount = 0\n break\n }\n\n const lines: string[] = [\n `Found ${items.length} symbol${items.length === 1 ? '' : 's'} in workspace:`,\n ]\n const grouped = groupLocationsByFile(\n items.map((it: any) => ({\n fileName: it.fileName,\n item: it,\n })),\n )\n for (const [file, itemsInFile] of grouped) {\n lines.push(`\\n${file}:`)\n for (const wrapper of itemsInFile) {\n const it: any = (wrapper as any).item\n const sf = program.getSourceFile(it.fileName)\n if (!sf) continue\n const span = it.textSpan\n const lc = span\n ? ts.getLineAndCharacterOfPosition(sf, span.start)\n : { line: 0, character: 0 }\n const label = it.kind\n ? String(it.kind)[0].toUpperCase() + String(it.kind).slice(1)\n : 'Symbol'\n let line = ` ${it.name} (${label}) - Line ${lc.line + 1}`\n if (it.containerName) line += ` in ${it.containerName}`\n lines.push(line)\n }\n }\n formatted = lines.join('\\n')\n resultCount = items.length\n fileCount = grouped.size\n break\n }\n case 'prepareCallHierarchy':\n case 'incomingCalls':\n case 'outgoingCalls': {\n const opLabel = input.operation\n formatted = `Error performing ${opLabel}: Call hierarchy is not supported by the TypeScript backend`\n resultCount = 0\n fileCount = 0\n break\n }\n default: {\n formatted = `Error performing ${input.operation}: Unsupported operation`\n resultCount = 0\n fileCount = 0\n }\n }\n\n const out: Output = {\n operation: input.operation,\n result: formatted,\n filePath: input.filePath,\n resultCount,\n fileCount,\n }\n yield { type: 'result', data: out, resultForAssistant: out.result }\n } catch (err) {\n const message = err instanceof Error ? err.message : String(err)\n const out: Output = {\n operation: input.operation,\n result: `Error performing ${input.operation}: ${message}`,\n filePath: input.filePath,\n }\n yield { type: 'result', data: out, resultForAssistant: out.result }\n }\n },\n} satisfies Tool\n"],
5
+ "mappings": "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",
6
6
  "names": []
7
7
  }