@within-7/minto 0.2.0 → 0.3.3
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.
- package/dist/commands/agents/AgentsCommand.js +22 -24
- package/dist/commands/agents/AgentsCommand.js.map +2 -2
- package/dist/commands/context.js +2 -1
- package/dist/commands/context.js.map +2 -2
- package/dist/commands/export.js +2 -1
- package/dist/commands/export.js.map +2 -2
- package/dist/commands/mcp-interactive.js +7 -6
- package/dist/commands/mcp-interactive.js.map +2 -2
- package/dist/commands/model.js +3 -2
- package/dist/commands/model.js.map +2 -2
- package/dist/commands/permissions.js +4 -3
- package/dist/commands/permissions.js.map +2 -2
- package/dist/commands/plugin/AddMarketplaceForm.js +3 -2
- package/dist/commands/plugin/AddMarketplaceForm.js.map +2 -2
- package/dist/commands/plugin/ConfirmDialog.js +2 -1
- package/dist/commands/plugin/ConfirmDialog.js.map +2 -2
- package/dist/commands/plugin/ErrorView.js +2 -1
- package/dist/commands/plugin/ErrorView.js.map +2 -2
- package/dist/commands/plugin/InstalledPluginsByMarketplace.js +5 -4
- package/dist/commands/plugin/InstalledPluginsByMarketplace.js.map +2 -2
- package/dist/commands/plugin/InstalledPluginsManager.js +5 -4
- package/dist/commands/plugin/InstalledPluginsManager.js.map +2 -2
- package/dist/commands/plugin/MainMenu.js +2 -1
- package/dist/commands/plugin/MainMenu.js.map +2 -2
- package/dist/commands/plugin/MarketplaceManager.js +5 -4
- package/dist/commands/plugin/MarketplaceManager.js.map +2 -2
- package/dist/commands/plugin/MarketplaceSelector.js +4 -3
- package/dist/commands/plugin/MarketplaceSelector.js.map +2 -2
- package/dist/commands/plugin/PlaceholderScreen.js +3 -2
- package/dist/commands/plugin/PlaceholderScreen.js.map +2 -2
- package/dist/commands/plugin/PluginBrowser.js +6 -5
- package/dist/commands/plugin/PluginBrowser.js.map +2 -2
- package/dist/commands/plugin/PluginDetailsInstall.js +5 -4
- package/dist/commands/plugin/PluginDetailsInstall.js.map +2 -2
- package/dist/commands/plugin/PluginDetailsManage.js +4 -3
- package/dist/commands/plugin/PluginDetailsManage.js.map +2 -2
- package/dist/commands/plugin.js +16 -15
- package/dist/commands/plugin.js.map +2 -2
- package/dist/commands/sandbox.js +4 -3
- package/dist/commands/sandbox.js.map +2 -2
- package/dist/commands/setup.js +2 -1
- package/dist/commands/setup.js.map +2 -2
- package/dist/commands/status.js +2 -1
- package/dist/commands/status.js.map +2 -2
- package/dist/commands/undo.js +245 -0
- package/dist/commands/undo.js.map +7 -0
- package/dist/commands.js +2 -0
- package/dist/commands.js.map +2 -2
- package/dist/components/AgentThinkingBlock.js +1 -1
- package/dist/components/AgentThinkingBlock.js.map +2 -2
- package/dist/components/AsciiLogo.js +7 -8
- package/dist/components/AsciiLogo.js.map +2 -2
- package/dist/components/AskUserQuestionDialog/AskUserQuestionDialog.js +3 -2
- package/dist/components/AskUserQuestionDialog/AskUserQuestionDialog.js.map +2 -2
- package/dist/components/AskUserQuestionDialog/QuestionView.js +2 -1
- package/dist/components/AskUserQuestionDialog/QuestionView.js.map +2 -2
- package/dist/components/CollapsibleHint.js +2 -1
- package/dist/components/CollapsibleHint.js.map +2 -2
- package/dist/components/Config.js +3 -2
- package/dist/components/Config.js.map +2 -2
- package/dist/components/ConsoleOAuthFlow.js +2 -1
- package/dist/components/ConsoleOAuthFlow.js.map +2 -2
- package/dist/components/Cost.js +2 -1
- package/dist/components/Cost.js.map +2 -2
- package/dist/components/HeaderBar.js +13 -8
- package/dist/components/HeaderBar.js.map +2 -2
- package/dist/components/HistorySearchOverlay.js +4 -3
- package/dist/components/HistorySearchOverlay.js.map +2 -2
- package/dist/components/HotkeyHelpPanel.js +8 -11
- package/dist/components/HotkeyHelpPanel.js.map +2 -2
- package/dist/components/InvalidConfigDialog.js +2 -1
- package/dist/components/InvalidConfigDialog.js.map +2 -2
- package/dist/components/Logo.js +23 -67
- package/dist/components/Logo.js.map +2 -2
- package/dist/components/MCPServerApprovalDialog.js +2 -1
- package/dist/components/MCPServerApprovalDialog.js.map +2 -2
- package/dist/components/MCPServerDialogCopy.js +2 -1
- package/dist/components/MCPServerDialogCopy.js.map +2 -2
- package/dist/components/MCPServerMultiselectDialog.js +2 -1
- package/dist/components/MCPServerMultiselectDialog.js.map +2 -2
- package/dist/components/MessageSelector.js +4 -3
- package/dist/components/MessageSelector.js.map +2 -2
- package/dist/components/ModeIndicator.js +2 -1
- package/dist/components/ModeIndicator.js.map +2 -2
- package/dist/components/ModelConfig.js +4 -3
- package/dist/components/ModelConfig.js.map +2 -2
- package/dist/components/ModelListManager.js +4 -3
- package/dist/components/ModelListManager.js.map +2 -2
- package/dist/components/ModelSelector/ModelSelector.js +26 -13
- package/dist/components/ModelSelector/ModelSelector.js.map +2 -2
- package/dist/components/Onboarding.js +3 -2
- package/dist/components/Onboarding.js.map +2 -2
- package/dist/components/OperationSummary.js +130 -0
- package/dist/components/OperationSummary.js.map +7 -0
- package/dist/components/PromptInput.js +88 -75
- package/dist/components/PromptInput.js.map +2 -2
- package/dist/components/SensitiveFileWarning.js +31 -0
- package/dist/components/SensitiveFileWarning.js.map +7 -0
- package/dist/components/Spinner.js +71 -22
- package/dist/components/Spinner.js.map +2 -2
- package/dist/components/StructuredDiff.js +6 -8
- package/dist/components/StructuredDiff.js.map +2 -2
- package/dist/components/SubagentBlock.js +4 -2
- package/dist/components/SubagentBlock.js.map +2 -2
- package/dist/components/SubagentProgress.js +17 -6
- package/dist/components/SubagentProgress.js.map +2 -2
- package/dist/components/TaskCard.js +14 -11
- package/dist/components/TaskCard.js.map +2 -2
- package/dist/components/TextInput.js +9 -1
- package/dist/components/TextInput.js.map +2 -2
- package/dist/components/TodoPanel.js +44 -26
- package/dist/components/TodoPanel.js.map +2 -2
- package/dist/components/ToolUseLoader.js +2 -2
- package/dist/components/ToolUseLoader.js.map +2 -2
- package/dist/components/TreeConnector.js +4 -3
- package/dist/components/TreeConnector.js.map +2 -2
- package/dist/components/TrustDialog.js +2 -1
- package/dist/components/TrustDialog.js.map +2 -2
- package/dist/components/binary-feedback/BinaryFeedbackView.js +2 -1
- package/dist/components/binary-feedback/BinaryFeedbackView.js.map +2 -2
- package/dist/components/messages/AssistantTextMessage.js +17 -9
- package/dist/components/messages/AssistantTextMessage.js.map +2 -2
- package/dist/components/messages/AssistantToolUseMessage.js +8 -4
- package/dist/components/messages/AssistantToolUseMessage.js.map +2 -2
- package/dist/components/messages/GroupRenderer.js +2 -1
- package/dist/components/messages/GroupRenderer.js.map +2 -2
- package/dist/components/messages/NestedTasksPreview.js +13 -1
- package/dist/components/messages/NestedTasksPreview.js.map +2 -2
- package/dist/components/messages/ParallelTasksGroupView.js +4 -3
- package/dist/components/messages/ParallelTasksGroupView.js.map +2 -2
- package/dist/components/messages/TaskInModuleView.js +35 -15
- package/dist/components/messages/TaskInModuleView.js.map +2 -2
- package/dist/components/messages/TaskOutputContent.js +9 -6
- package/dist/components/messages/TaskOutputContent.js.map +2 -2
- package/dist/components/messages/UserPromptMessage.js +2 -2
- package/dist/components/messages/UserPromptMessage.js.map +2 -2
- package/dist/constants/colors.js +90 -72
- package/dist/constants/colors.js.map +2 -2
- package/dist/constants/prompts.js +22 -1
- package/dist/constants/prompts.js.map +2 -2
- package/dist/constants/toolInputExamples.js +84 -0
- package/dist/constants/toolInputExamples.js.map +7 -0
- package/dist/core/backupManager.js +321 -0
- package/dist/core/backupManager.js.map +7 -0
- package/dist/core/costTracker.js +9 -18
- package/dist/core/costTracker.js.map +2 -2
- package/dist/core/gitAutoCommit.js +287 -0
- package/dist/core/gitAutoCommit.js.map +7 -0
- package/dist/core/index.js +3 -0
- package/dist/core/index.js.map +2 -2
- package/dist/core/operationTracker.js +212 -0
- package/dist/core/operationTracker.js.map +7 -0
- package/dist/core/permissions/rules/allowedToolsRule.js +1 -1
- package/dist/core/permissions/rules/allowedToolsRule.js.map +2 -2
- package/dist/core/permissions/rules/autoEscalationRule.js +5 -0
- package/dist/core/permissions/rules/autoEscalationRule.js.map +2 -2
- package/dist/core/permissions/rules/projectBoundaryRule.js +5 -0
- package/dist/core/permissions/rules/projectBoundaryRule.js.map +2 -2
- package/dist/core/permissions/rules/sensitivePathsRule.js +5 -0
- package/dist/core/permissions/rules/sensitivePathsRule.js.map +2 -2
- package/dist/core/tokenStats.js +9 -0
- package/dist/core/tokenStats.js.map +7 -0
- package/dist/core/tokenStatsManager.js +331 -0
- package/dist/core/tokenStatsManager.js.map +7 -0
- package/dist/entrypoints/cli.js +122 -88
- package/dist/entrypoints/cli.js.map +2 -2
- package/dist/hooks/useAgentTokenStats.js +72 -0
- package/dist/hooks/useAgentTokenStats.js.map +7 -0
- package/dist/hooks/useAgentTranscripts.js +30 -6
- package/dist/hooks/useAgentTranscripts.js.map +2 -2
- package/dist/hooks/useLogMessages.js +12 -1
- package/dist/hooks/useLogMessages.js.map +2 -2
- package/dist/i18n/locales/en.js +6 -5
- package/dist/i18n/locales/en.js.map +2 -2
- package/dist/i18n/locales/zh-CN.js +6 -5
- package/dist/i18n/locales/zh-CN.js.map +2 -2
- package/dist/i18n/types.js.map +1 -1
- package/dist/permissions.js +147 -1
- package/dist/permissions.js.map +2 -2
- package/dist/query.js +78 -4
- package/dist/query.js.map +3 -3
- package/dist/screens/REPL.js +23 -3
- package/dist/screens/REPL.js.map +2 -2
- package/dist/screens/ResumeConversation.js +2 -0
- package/dist/screens/ResumeConversation.js.map +2 -2
- package/dist/services/claude.js +54 -3
- package/dist/services/claude.js.map +2 -2
- package/dist/services/intelligentCompactor.js +1 -1
- package/dist/services/intelligentCompactor.js.map +2 -2
- package/dist/services/mcpClient.js +81 -25
- package/dist/services/mcpClient.js.map +2 -2
- package/dist/services/sandbox/filesystemBoundary.js +58 -17
- package/dist/services/sandbox/filesystemBoundary.js.map +2 -2
- package/dist/services/taskStore.js +205 -0
- package/dist/services/taskStore.js.map +7 -0
- package/dist/tools/AskExpertModelTool/AskExpertModelTool.js +3 -2
- package/dist/tools/AskExpertModelTool/AskExpertModelTool.js.map +2 -2
- package/dist/tools/AskUserQuestionTool/AskUserQuestionTool.js +42 -4
- package/dist/tools/AskUserQuestionTool/AskUserQuestionTool.js.map +2 -2
- package/dist/tools/BashTool/BashTool.js +43 -7
- package/dist/tools/BashTool/BashTool.js.map +2 -2
- package/dist/tools/BashTool/prompt.js +184 -34
- package/dist/tools/BashTool/prompt.js.map +2 -2
- package/dist/tools/FileEditTool/FileEditTool.js +24 -9
- package/dist/tools/FileEditTool/FileEditTool.js.map +2 -2
- package/dist/tools/FileEditTool/prompt.js +10 -4
- package/dist/tools/FileEditTool/prompt.js.map +2 -2
- package/dist/tools/FileEditTool/utils.js +10 -4
- package/dist/tools/FileEditTool/utils.js.map +2 -2
- package/dist/tools/FileReadTool/FileReadTool.js +1 -1
- package/dist/tools/FileReadTool/FileReadTool.js.map +1 -1
- package/dist/tools/FileReadTool/prompt.js +16 -1
- package/dist/tools/FileReadTool/prompt.js.map +2 -2
- package/dist/tools/FileWriteTool/FileWriteTool.js +1 -1
- package/dist/tools/FileWriteTool/FileWriteTool.js.map +1 -1
- package/dist/tools/FileWriteTool/prompt.js +12 -3
- package/dist/tools/FileWriteTool/prompt.js.map +2 -2
- package/dist/tools/GlobTool/prompt.js +12 -1
- package/dist/tools/GlobTool/prompt.js.map +2 -2
- package/dist/tools/GrepTool/GrepTool.js +333 -65
- package/dist/tools/GrepTool/GrepTool.js.map +2 -2
- package/dist/tools/GrepTool/prompt.js +15 -8
- package/dist/tools/GrepTool/prompt.js.map +2 -2
- package/dist/tools/MultiEditTool/prompt.js +5 -3
- package/dist/tools/MultiEditTool/prompt.js.map +2 -2
- package/dist/tools/NotebookEditTool/NotebookEditTool.js +59 -46
- package/dist/tools/NotebookEditTool/NotebookEditTool.js.map +2 -2
- package/dist/tools/NotebookEditTool/prompt.js +1 -1
- package/dist/tools/NotebookEditTool/prompt.js.map +1 -1
- package/dist/tools/PlanModeTool/EnterPlanModeTool.js +3 -2
- package/dist/tools/PlanModeTool/EnterPlanModeTool.js.map +2 -2
- package/dist/tools/PlanModeTool/ExitPlanModeTool.js +3 -2
- package/dist/tools/PlanModeTool/ExitPlanModeTool.js.map +2 -2
- package/dist/tools/PlanModeTool/prompt.js +1 -1
- package/dist/tools/PlanModeTool/prompt.js.map +1 -1
- package/dist/tools/SkillTool/SkillTool.js +4 -3
- package/dist/tools/SkillTool/SkillTool.js.map +2 -2
- package/dist/tools/SkillTool/prompt.js +1 -1
- package/dist/tools/SkillTool/prompt.js.map +1 -1
- package/dist/tools/TaskCreateTool/TaskCreateTool.js +102 -0
- package/dist/tools/TaskCreateTool/TaskCreateTool.js.map +7 -0
- package/dist/tools/TaskCreateTool/prompt.js +47 -0
- package/dist/tools/TaskCreateTool/prompt.js.map +7 -0
- package/dist/tools/TaskGetTool/TaskGetTool.js +115 -0
- package/dist/tools/TaskGetTool/TaskGetTool.js.map +7 -0
- package/dist/tools/TaskGetTool/prompt.js +28 -0
- package/dist/tools/TaskGetTool/prompt.js.map +7 -0
- package/dist/tools/TaskListTool/TaskListTool.js +102 -0
- package/dist/tools/TaskListTool/TaskListTool.js.map +7 -0
- package/dist/tools/TaskListTool/prompt.js +27 -0
- package/dist/tools/TaskListTool/prompt.js.map +7 -0
- package/dist/tools/TaskOutputTool/TaskOutputTool.js +3 -2
- package/dist/tools/TaskOutputTool/TaskOutputTool.js.map +2 -2
- package/dist/tools/TaskStopTool/TaskStopTool.js +150 -0
- package/dist/tools/TaskStopTool/TaskStopTool.js.map +7 -0
- package/dist/tools/TaskStopTool/prompt.js +15 -0
- package/dist/tools/TaskStopTool/prompt.js.map +7 -0
- package/dist/tools/TaskTool/TaskTool.js +49 -1
- package/dist/tools/TaskTool/TaskTool.js.map +2 -2
- package/dist/tools/TaskUpdateTool/TaskUpdateTool.js +134 -0
- package/dist/tools/TaskUpdateTool/TaskUpdateTool.js.map +7 -0
- package/dist/tools/TaskUpdateTool/prompt.js +81 -0
- package/dist/tools/TaskUpdateTool/prompt.js.map +7 -0
- package/dist/tools/URLFetcherTool/prompt.js +1 -1
- package/dist/tools/URLFetcherTool/prompt.js.map +1 -1
- package/dist/tools.js +12 -0
- package/dist/tools.js.map +2 -2
- package/dist/utils/CircuitBreaker.js +242 -0
- package/dist/utils/CircuitBreaker.js.map +7 -0
- package/dist/utils/ask.js +2 -0
- package/dist/utils/ask.js.map +2 -2
- package/dist/utils/config.js +47 -5
- package/dist/utils/config.js.map +2 -2
- package/dist/utils/credentials/CredentialStore.js +1 -0
- package/dist/utils/credentials/CredentialStore.js.map +7 -0
- package/dist/utils/credentials/EncryptedFileStore.js +157 -0
- package/dist/utils/credentials/EncryptedFileStore.js.map +7 -0
- package/dist/utils/credentials/index.js +37 -0
- package/dist/utils/credentials/index.js.map +7 -0
- package/dist/utils/credentials/migration.js +82 -0
- package/dist/utils/credentials/migration.js.map +7 -0
- package/dist/utils/markdown.js +13 -1
- package/dist/utils/markdown.js.map +2 -2
- package/dist/utils/model.js +15 -2
- package/dist/utils/model.js.map +2 -2
- package/dist/utils/permissions/filesystem.js +5 -1
- package/dist/utils/permissions/filesystem.js.map +2 -2
- package/dist/utils/ripgrep.js +53 -1
- package/dist/utils/ripgrep.js.map +2 -2
- package/dist/utils/safePath.js +132 -0
- package/dist/utils/safePath.js.map +7 -0
- package/dist/utils/sensitiveFiles.js +125 -0
- package/dist/utils/sensitiveFiles.js.map +7 -0
- package/dist/utils/taskDisplayUtils.js +9 -9
- package/dist/utils/taskDisplayUtils.js.map +2 -2
- package/dist/utils/terminal.js +12 -0
- package/dist/utils/terminal.js.map +2 -2
- package/dist/utils/theme.js +6 -6
- package/dist/utils/theme.js.map +1 -1
- package/dist/utils/toolRiskClassification.js +207 -0
- package/dist/utils/toolRiskClassification.js.map +7 -0
- package/dist/utils/tooling/safeRender.js +17 -17
- package/dist/utils/tooling/safeRender.js.map +2 -2
- package/dist/version.js +2 -2
- package/dist/version.js.map +1 -1
- package/package.json +22 -28
- package/dist/hooks/useCancelRequest.js +0 -31
- package/dist/hooks/useCancelRequest.js.map +0 -7
|
@@ -7,16 +7,49 @@ import { FallbackToolUseRejectedMessage } from "../../components/FallbackToolUse
|
|
|
7
7
|
import { CollapsibleHint } from "../../components/CollapsibleHint.js";
|
|
8
8
|
import { getCwd } from "../../utils/state.js";
|
|
9
9
|
import { getAbsolutePath, getAbsoluteAndRelativePaths } from "../../utils/file.js";
|
|
10
|
-
import { ripGrepStreaming } from "../../utils/ripgrep.js";
|
|
10
|
+
import { ripGrepStreaming, ripGrepStreamingWithContent } from "../../utils/ripgrep.js";
|
|
11
11
|
import { DESCRIPTION, TOOL_NAME_FOR_PROMPT } from "./prompt.js";
|
|
12
12
|
import { hasReadPermission } from "../../utils/permissions/filesystem.js";
|
|
13
13
|
const inputSchema = z.strictObject({
|
|
14
14
|
pattern: z.string().describe("The regular expression pattern to search for in file contents"),
|
|
15
15
|
path: z.string().optional().describe(
|
|
16
|
-
"
|
|
16
|
+
"File or directory to search in (rg PATH). Defaults to current working directory."
|
|
17
17
|
),
|
|
18
|
+
// Backward compatible: 'include' is mapped to 'glob'
|
|
18
19
|
include: z.string().optional().describe(
|
|
19
|
-
'File pattern to include in the search (e.g. "*.js", "*.{ts,tsx}")'
|
|
20
|
+
'File pattern to include in the search (e.g. "*.js", "*.{ts,tsx}") - DEPRECATED: use glob instead'
|
|
21
|
+
),
|
|
22
|
+
glob: z.string().optional().describe(
|
|
23
|
+
'Glob pattern to filter files (e.g. "*.js", "*.{ts,tsx}") - maps to rg --glob'
|
|
24
|
+
),
|
|
25
|
+
type: z.string().optional().describe(
|
|
26
|
+
"File type to search (rg --type). Common types: js, py, rust, go, java, etc. More efficient than include for standard file types."
|
|
27
|
+
),
|
|
28
|
+
output_mode: z.enum(["content", "files_with_matches", "count"]).optional().describe(
|
|
29
|
+
'Output mode: "content" shows matching lines, "files_with_matches" shows file paths (default), "count" shows match counts'
|
|
30
|
+
),
|
|
31
|
+
multiline: z.boolean().optional().describe(
|
|
32
|
+
"Enable multiline mode where . matches newlines and patterns can span lines (rg -U --multiline-dotall). Default: false."
|
|
33
|
+
),
|
|
34
|
+
context: z.number().optional().describe(
|
|
35
|
+
'Number of lines to show before and after each match (rg -C). Requires output_mode: "content", ignored otherwise.'
|
|
36
|
+
),
|
|
37
|
+
"-A": z.number().optional().describe(
|
|
38
|
+
'Number of lines to show after each match (rg -A). Requires output_mode: "content", ignored otherwise.'
|
|
39
|
+
),
|
|
40
|
+
"-B": z.number().optional().describe(
|
|
41
|
+
'Number of lines to show before each match (rg -B). Requires output_mode: "content", ignored otherwise.'
|
|
42
|
+
),
|
|
43
|
+
"-C": z.number().optional().describe("Alias for context."),
|
|
44
|
+
"-n": z.boolean().optional().describe(
|
|
45
|
+
'Show line numbers in output (rg -n). Requires output_mode: "content", ignored otherwise. Defaults to true.'
|
|
46
|
+
),
|
|
47
|
+
"-i": z.boolean().optional().describe("Case insensitive search (rg -i)"),
|
|
48
|
+
head_limit: z.number().optional().describe(
|
|
49
|
+
'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).'
|
|
50
|
+
),
|
|
51
|
+
offset: z.number().optional().describe(
|
|
52
|
+
'Skip first N lines/entries before applying head_limit, equivalent to "| tail -n +N | head -N". Works across all output modes. Defaults to 0.'
|
|
20
53
|
)
|
|
21
54
|
});
|
|
22
55
|
const MAX_RESULTS = 100;
|
|
@@ -44,9 +77,43 @@ const GrepTool = {
|
|
|
44
77
|
async prompt() {
|
|
45
78
|
return DESCRIPTION;
|
|
46
79
|
},
|
|
47
|
-
renderToolUseMessage(
|
|
80
|
+
renderToolUseMessage(input, { verbose }) {
|
|
81
|
+
const {
|
|
82
|
+
pattern,
|
|
83
|
+
path,
|
|
84
|
+
include,
|
|
85
|
+
glob,
|
|
86
|
+
type,
|
|
87
|
+
output_mode,
|
|
88
|
+
multiline,
|
|
89
|
+
context,
|
|
90
|
+
"-i": caseInsensitive
|
|
91
|
+
} = input;
|
|
48
92
|
const { absolutePath, relativePath } = getAbsoluteAndRelativePaths(path);
|
|
49
|
-
|
|
93
|
+
const effectiveGlob = glob || include;
|
|
94
|
+
const parts = [`pattern: "${pattern}"`];
|
|
95
|
+
if (relativePath || verbose) {
|
|
96
|
+
parts.push(`path: "${verbose ? absolutePath : relativePath}"`);
|
|
97
|
+
}
|
|
98
|
+
if (effectiveGlob) {
|
|
99
|
+
parts.push(`glob: "${effectiveGlob}"`);
|
|
100
|
+
}
|
|
101
|
+
if (type) {
|
|
102
|
+
parts.push(`type: "${type}"`);
|
|
103
|
+
}
|
|
104
|
+
if (output_mode && output_mode !== "files_with_matches") {
|
|
105
|
+
parts.push(`mode: "${output_mode}"`);
|
|
106
|
+
}
|
|
107
|
+
if (multiline) {
|
|
108
|
+
parts.push("multiline");
|
|
109
|
+
}
|
|
110
|
+
if (context) {
|
|
111
|
+
parts.push(`context: ${context}`);
|
|
112
|
+
}
|
|
113
|
+
if (caseInsensitive === false) {
|
|
114
|
+
parts.push("case-sensitive");
|
|
115
|
+
}
|
|
116
|
+
return parts.join(", ");
|
|
50
117
|
},
|
|
51
118
|
renderToolUseRejectedMessage() {
|
|
52
119
|
return /* @__PURE__ */ React.createElement(FallbackToolUseRejectedMessage, null);
|
|
@@ -59,77 +126,278 @@ const GrepTool = {
|
|
|
59
126
|
output = output;
|
|
60
127
|
}
|
|
61
128
|
const numFiles = output?.numFiles ?? 0;
|
|
129
|
+
const numMatches = output?.numMatches ?? 0;
|
|
62
130
|
const durationMs = output?.durationMs ?? 0;
|
|
63
|
-
const
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
if (
|
|
68
|
-
|
|
131
|
+
const outputMode = output?.outputMode ?? "files_with_matches";
|
|
132
|
+
if (outputMode === "content") {
|
|
133
|
+
const showExpandHint = !verbose && numMatches > 10;
|
|
134
|
+
return /* @__PURE__ */ React.createElement(Box, { justifyContent: "space-between", width: "100%" }, /* @__PURE__ */ React.createElement(Box, { flexDirection: "row" }, /* @__PURE__ */ React.createElement(Text, null, "\xA0\xA0\u23BF \xA0Found "), /* @__PURE__ */ React.createElement(Text, { bold: true }, numMatches, " "), /* @__PURE__ */ React.createElement(Text, null, numMatches === 1 ? "match" : "matches", " in "), /* @__PURE__ */ React.createElement(Text, { bold: true }, numFiles, " "), /* @__PURE__ */ React.createElement(Text, null, numFiles === 1 ? "file" : "files"), showExpandHint && /* @__PURE__ */ React.createElement(CollapsibleHint, { canExpand: true })), /* @__PURE__ */ React.createElement(Cost, { costUSD: 0, durationMs, debug: false }));
|
|
135
|
+
} else if (outputMode === "count") {
|
|
136
|
+
const showExpandHint = !verbose && numFiles > 5;
|
|
137
|
+
return /* @__PURE__ */ React.createElement(Box, { justifyContent: "space-between", width: "100%" }, /* @__PURE__ */ React.createElement(Box, { flexDirection: "row" }, /* @__PURE__ */ React.createElement(Text, null, "\xA0\xA0\u23BF \xA0Counted "), /* @__PURE__ */ React.createElement(Text, { bold: true }, numMatches, " "), /* @__PURE__ */ React.createElement(Text, null, numMatches === 1 ? "match" : "matches", " in "), /* @__PURE__ */ React.createElement(Text, { bold: true }, numFiles, " "), /* @__PURE__ */ React.createElement(Text, null, numFiles === 1 ? "file" : "files"), showExpandHint && /* @__PURE__ */ React.createElement(CollapsibleHint, { canExpand: true })), /* @__PURE__ */ React.createElement(Cost, { costUSD: 0, durationMs, debug: false }));
|
|
138
|
+
} else {
|
|
139
|
+
const showExpandHint = !verbose && numFiles > 5;
|
|
140
|
+
return /* @__PURE__ */ React.createElement(Box, { justifyContent: "space-between", width: "100%" }, /* @__PURE__ */ React.createElement(Box, { flexDirection: "row" }, /* @__PURE__ */ React.createElement(Text, null, "\xA0\xA0\u23BF \xA0Found "), /* @__PURE__ */ React.createElement(Text, { bold: true }, numFiles, " "), /* @__PURE__ */ React.createElement(Text, null, numFiles === 0 || numFiles > 1 ? "files" : "file"), showExpandHint && /* @__PURE__ */ React.createElement(CollapsibleHint, { canExpand: true })), /* @__PURE__ */ React.createElement(Cost, { costUSD: 0, durationMs, debug: false }));
|
|
69
141
|
}
|
|
70
|
-
|
|
142
|
+
},
|
|
143
|
+
renderResultForAssistant(output) {
|
|
144
|
+
const { numFiles, filenames, content, counts, numMatches, outputMode } = output;
|
|
145
|
+
if (outputMode === "content") {
|
|
146
|
+
if (!content || numMatches === 0) {
|
|
147
|
+
return "No matches found";
|
|
148
|
+
}
|
|
149
|
+
let result = content;
|
|
150
|
+
if (numMatches && numMatches > MAX_RESULTS) {
|
|
151
|
+
result += "\n(Results are truncated. Consider using a more specific path or pattern.)";
|
|
152
|
+
}
|
|
153
|
+
return result;
|
|
154
|
+
} else if (outputMode === "count") {
|
|
155
|
+
if (!counts || counts.length === 0) {
|
|
156
|
+
return "No matches found";
|
|
157
|
+
}
|
|
158
|
+
const totalMatches = counts.reduce((sum, c) => sum + c.count, 0);
|
|
159
|
+
let result = `Found ${totalMatches} match${totalMatches === 1 ? "" : "es"} in ${numFiles} file${numFiles === 1 ? "" : "s"}
|
|
160
|
+
`;
|
|
161
|
+
result += counts.slice(0, MAX_RESULTS).map((c) => `${c.file}:${c.count}`).join("\n");
|
|
162
|
+
if (counts.length > MAX_RESULTS) {
|
|
163
|
+
result += "\n(Results are truncated. Consider using a more specific path or pattern.)";
|
|
164
|
+
}
|
|
165
|
+
return result;
|
|
166
|
+
} else {
|
|
167
|
+
if (numFiles === 0) {
|
|
168
|
+
return "No files found";
|
|
169
|
+
}
|
|
170
|
+
let result = `Found ${numFiles} file${numFiles === 1 ? "" : "s"}
|
|
71
171
|
${filenames.slice(0, MAX_RESULTS).join("\n")}`;
|
|
72
|
-
|
|
73
|
-
|
|
172
|
+
if (numFiles > MAX_RESULTS) {
|
|
173
|
+
result += "\n(Results are truncated. Consider using a more specific path or pattern.)";
|
|
174
|
+
}
|
|
175
|
+
return result;
|
|
74
176
|
}
|
|
75
|
-
return result;
|
|
76
177
|
},
|
|
77
|
-
async *call(
|
|
178
|
+
async *call(input, { abortController }) {
|
|
179
|
+
const {
|
|
180
|
+
pattern,
|
|
181
|
+
path,
|
|
182
|
+
include,
|
|
183
|
+
glob,
|
|
184
|
+
type,
|
|
185
|
+
output_mode = "files_with_matches",
|
|
186
|
+
multiline,
|
|
187
|
+
context,
|
|
188
|
+
"-A": afterContext,
|
|
189
|
+
"-B": beforeContext,
|
|
190
|
+
"-C": contextAlias,
|
|
191
|
+
"-n": lineNumbers = true,
|
|
192
|
+
"-i": caseInsensitive = true,
|
|
193
|
+
head_limit = 0,
|
|
194
|
+
offset = 0
|
|
195
|
+
} = input;
|
|
78
196
|
const start = Date.now();
|
|
79
197
|
const absolutePath = getAbsolutePath(path) || getCwd();
|
|
80
|
-
const
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
198
|
+
const effectiveGlob = glob || include;
|
|
199
|
+
const effectiveContext = context ?? contextAlias;
|
|
200
|
+
const args = [];
|
|
201
|
+
if (caseInsensitive) {
|
|
202
|
+
args.push("-i");
|
|
203
|
+
}
|
|
204
|
+
if (multiline) {
|
|
205
|
+
args.push("-U", "--multiline-dotall");
|
|
206
|
+
}
|
|
207
|
+
if (type) {
|
|
208
|
+
args.push("--type", type);
|
|
209
|
+
}
|
|
210
|
+
if (effectiveGlob) {
|
|
211
|
+
args.push("--glob", effectiveGlob);
|
|
212
|
+
}
|
|
213
|
+
if (output_mode === "files_with_matches") {
|
|
214
|
+
args.push("-l");
|
|
215
|
+
} else if (output_mode === "count") {
|
|
216
|
+
args.push("-c");
|
|
217
|
+
} else if (output_mode === "content") {
|
|
218
|
+
if (lineNumbers) {
|
|
219
|
+
args.push("-n");
|
|
220
|
+
}
|
|
221
|
+
if (effectiveContext !== void 0 && effectiveContext > 0) {
|
|
222
|
+
args.push("-C", String(effectiveContext));
|
|
223
|
+
} else {
|
|
224
|
+
if (beforeContext !== void 0 && beforeContext > 0) {
|
|
225
|
+
args.push("-B", String(beforeContext));
|
|
226
|
+
}
|
|
227
|
+
if (afterContext !== void 0 && afterContext > 0) {
|
|
228
|
+
args.push("-A", String(afterContext));
|
|
229
|
+
}
|
|
230
|
+
}
|
|
231
|
+
}
|
|
232
|
+
args.push(pattern);
|
|
233
|
+
if (output_mode === "content") {
|
|
234
|
+
const contentLines = [];
|
|
235
|
+
const filesWithMatches = /* @__PURE__ */ new Set();
|
|
236
|
+
let matchCount = 0;
|
|
237
|
+
let lastProgressUpdate = 0;
|
|
238
|
+
const PROGRESS_UPDATE_INTERVAL = 100;
|
|
239
|
+
for await (const chunk of ripGrepStreamingWithContent(
|
|
240
|
+
args,
|
|
241
|
+
absolutePath,
|
|
242
|
+
abortController.signal
|
|
243
|
+
)) {
|
|
244
|
+
if (chunk.type === "line") {
|
|
245
|
+
contentLines.push(chunk.line);
|
|
246
|
+
const fileMatch = chunk.line.match(/^([^:]+):(\d+):/);
|
|
247
|
+
if (fileMatch) {
|
|
248
|
+
filesWithMatches.add(fileMatch[1]);
|
|
249
|
+
matchCount++;
|
|
250
|
+
}
|
|
251
|
+
const now = Date.now();
|
|
252
|
+
if (now - lastProgressUpdate >= PROGRESS_UPDATE_INTERVAL) {
|
|
253
|
+
lastProgressUpdate = now;
|
|
254
|
+
yield {
|
|
255
|
+
type: "progress",
|
|
256
|
+
content: {
|
|
257
|
+
type: "streaming",
|
|
258
|
+
toolName: "Search",
|
|
259
|
+
stdout: `Searching... Found ${matchCount} match${matchCount === 1 ? "" : "es"} in ${filesWithMatches.size} file${filesWithMatches.size === 1 ? "" : "s"}`,
|
|
260
|
+
stderr: "",
|
|
261
|
+
isStreaming: true
|
|
262
|
+
}
|
|
263
|
+
};
|
|
264
|
+
}
|
|
265
|
+
}
|
|
266
|
+
}
|
|
267
|
+
let resultLines = contentLines;
|
|
268
|
+
if (offset > 0) {
|
|
269
|
+
resultLines = resultLines.slice(offset);
|
|
270
|
+
}
|
|
271
|
+
if (head_limit > 0) {
|
|
272
|
+
resultLines = resultLines.slice(0, head_limit);
|
|
273
|
+
}
|
|
274
|
+
const output = {
|
|
275
|
+
filenames: Array.from(filesWithMatches),
|
|
276
|
+
content: resultLines.join("\n"),
|
|
277
|
+
numMatches: matchCount,
|
|
278
|
+
numFiles: filesWithMatches.size,
|
|
279
|
+
durationMs: Date.now() - start,
|
|
280
|
+
outputMode: "content"
|
|
281
|
+
};
|
|
282
|
+
yield {
|
|
283
|
+
type: "result",
|
|
284
|
+
resultForAssistant: this.renderResultForAssistant(output),
|
|
285
|
+
data: output
|
|
286
|
+
};
|
|
287
|
+
} else if (output_mode === "count") {
|
|
288
|
+
const counts = [];
|
|
289
|
+
let lastProgressUpdate = 0;
|
|
290
|
+
const PROGRESS_UPDATE_INTERVAL = 100;
|
|
291
|
+
for await (const chunk of ripGrepStreamingWithContent(
|
|
292
|
+
args,
|
|
293
|
+
absolutePath,
|
|
294
|
+
abortController.signal
|
|
295
|
+
)) {
|
|
296
|
+
if (chunk.type === "line") {
|
|
297
|
+
const match = chunk.line.match(/^(.+):(\d+)$/);
|
|
298
|
+
if (match) {
|
|
299
|
+
counts.push({ file: match[1], count: parseInt(match[2], 10) });
|
|
300
|
+
const now = Date.now();
|
|
301
|
+
if (now - lastProgressUpdate >= PROGRESS_UPDATE_INTERVAL) {
|
|
302
|
+
lastProgressUpdate = now;
|
|
303
|
+
yield {
|
|
304
|
+
type: "progress",
|
|
305
|
+
content: {
|
|
306
|
+
type: "streaming",
|
|
307
|
+
toolName: "Search",
|
|
308
|
+
stdout: `Searching... Found matches in ${counts.length} file${counts.length === 1 ? "" : "s"}`,
|
|
309
|
+
stderr: "",
|
|
310
|
+
isStreaming: true
|
|
311
|
+
}
|
|
312
|
+
};
|
|
105
313
|
}
|
|
106
|
-
}
|
|
314
|
+
}
|
|
107
315
|
}
|
|
108
316
|
}
|
|
317
|
+
counts.sort((a, b) => {
|
|
318
|
+
const countDiff = b.count - a.count;
|
|
319
|
+
if (countDiff !== 0) return countDiff;
|
|
320
|
+
return a.file.localeCompare(b.file);
|
|
321
|
+
});
|
|
322
|
+
let resultCounts = counts;
|
|
323
|
+
if (offset > 0) {
|
|
324
|
+
resultCounts = resultCounts.slice(offset);
|
|
325
|
+
}
|
|
326
|
+
if (head_limit > 0) {
|
|
327
|
+
resultCounts = resultCounts.slice(0, head_limit);
|
|
328
|
+
}
|
|
329
|
+
const totalMatches = resultCounts.reduce((sum, c) => sum + c.count, 0);
|
|
330
|
+
const output = {
|
|
331
|
+
filenames: resultCounts.map((c) => c.file),
|
|
332
|
+
counts: resultCounts,
|
|
333
|
+
numMatches: totalMatches,
|
|
334
|
+
numFiles: resultCounts.length,
|
|
335
|
+
durationMs: Date.now() - start,
|
|
336
|
+
outputMode: "count"
|
|
337
|
+
};
|
|
338
|
+
yield {
|
|
339
|
+
type: "result",
|
|
340
|
+
resultForAssistant: this.renderResultForAssistant(output),
|
|
341
|
+
data: output
|
|
342
|
+
};
|
|
343
|
+
} else {
|
|
344
|
+
const matchedFiles = [];
|
|
345
|
+
let lastProgressUpdate = 0;
|
|
346
|
+
const PROGRESS_UPDATE_INTERVAL = 100;
|
|
347
|
+
for await (const chunk of ripGrepStreaming(
|
|
348
|
+
args,
|
|
349
|
+
absolutePath,
|
|
350
|
+
abortController.signal
|
|
351
|
+
)) {
|
|
352
|
+
if (chunk.type === "match") {
|
|
353
|
+
matchedFiles.push(chunk.file);
|
|
354
|
+
const now = Date.now();
|
|
355
|
+
if (now - lastProgressUpdate >= PROGRESS_UPDATE_INTERVAL) {
|
|
356
|
+
lastProgressUpdate = now;
|
|
357
|
+
yield {
|
|
358
|
+
type: "progress",
|
|
359
|
+
content: {
|
|
360
|
+
type: "streaming",
|
|
361
|
+
toolName: "Search",
|
|
362
|
+
stdout: `Searching... Found ${matchedFiles.length} file${matchedFiles.length === 1 ? "" : "s"}`,
|
|
363
|
+
stderr: "",
|
|
364
|
+
isStreaming: true
|
|
365
|
+
}
|
|
366
|
+
};
|
|
367
|
+
}
|
|
368
|
+
}
|
|
369
|
+
}
|
|
370
|
+
const stats = await Promise.all(
|
|
371
|
+
matchedFiles.map((_) => stat(_).catch(() => null))
|
|
372
|
+
);
|
|
373
|
+
let matches = matchedFiles.map((file, i) => [file, stats[i]]).filter(([, s]) => s !== null).sort((a, b) => {
|
|
374
|
+
if (process.env.NODE_ENV === "test") {
|
|
375
|
+
return a[0].localeCompare(b[0]);
|
|
376
|
+
}
|
|
377
|
+
const timeComparison = (b[1]?.mtimeMs ?? 0) - (a[1]?.mtimeMs ?? 0);
|
|
378
|
+
if (timeComparison === 0) {
|
|
379
|
+
return a[0].localeCompare(b[0]);
|
|
380
|
+
}
|
|
381
|
+
return timeComparison;
|
|
382
|
+
}).map((_) => _[0]);
|
|
383
|
+
if (offset > 0) {
|
|
384
|
+
matches = matches.slice(offset);
|
|
385
|
+
}
|
|
386
|
+
if (head_limit > 0) {
|
|
387
|
+
matches = matches.slice(0, head_limit);
|
|
388
|
+
}
|
|
389
|
+
const output = {
|
|
390
|
+
filenames: matches,
|
|
391
|
+
durationMs: Date.now() - start,
|
|
392
|
+
numFiles: matches.length,
|
|
393
|
+
outputMode: "files_with_matches"
|
|
394
|
+
};
|
|
395
|
+
yield {
|
|
396
|
+
type: "result",
|
|
397
|
+
resultForAssistant: this.renderResultForAssistant(output),
|
|
398
|
+
data: output
|
|
399
|
+
};
|
|
109
400
|
}
|
|
110
|
-
const stats = await Promise.all(
|
|
111
|
-
matchedFiles.map((_) => stat(_).catch(() => null))
|
|
112
|
-
);
|
|
113
|
-
const matches = matchedFiles.map((file, i) => [file, stats[i]]).filter(([, s]) => s !== null).sort((a, b) => {
|
|
114
|
-
if (process.env.NODE_ENV === "test") {
|
|
115
|
-
return a[0].localeCompare(b[0]);
|
|
116
|
-
}
|
|
117
|
-
const timeComparison = (b[1]?.mtimeMs ?? 0) - (a[1]?.mtimeMs ?? 0);
|
|
118
|
-
if (timeComparison === 0) {
|
|
119
|
-
return a[0].localeCompare(b[0]);
|
|
120
|
-
}
|
|
121
|
-
return timeComparison;
|
|
122
|
-
}).map((_) => _[0]);
|
|
123
|
-
const output = {
|
|
124
|
-
filenames: matches,
|
|
125
|
-
durationMs: Date.now() - start,
|
|
126
|
-
numFiles: matches.length
|
|
127
|
-
};
|
|
128
|
-
yield {
|
|
129
|
-
type: "result",
|
|
130
|
-
resultForAssistant: this.renderResultForAssistant(output),
|
|
131
|
-
data: output
|
|
132
|
-
};
|
|
133
401
|
}
|
|
134
402
|
};
|
|
135
403
|
export {
|
|
@@ -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, RipGrepStreamYield } 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 'The directory to search in. Defaults to the current working directory.',\n ),\n include: z\n .string()\n .optional()\n .describe(\n 'File pattern to include in the search (e.g. \"*.js\", \"*.{ts,tsx}\")',\n ),\n})\n\nconst MAX_RESULTS = 100\n\ntype Input = typeof inputSchema\ntype Output = {\n durationMs: number\n numFiles: number\n filenames: string[]\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 // GrepTool 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({ pattern, path, include }, { verbose }) {\n const { absolutePath, relativePath } = getAbsoluteAndRelativePaths(path)\n return `pattern: \"${pattern}\"${relativePath || verbose ? `, path: \"${verbose ? absolutePath : relativePath}\"` : ''}${include ? `, include: \"${include}\"` : ''}`\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> \u23BF 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 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> \u23BF 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 renderResultForAssistant({ numFiles, filenames }) {\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 async *call({ pattern, path, include }, { abortController }) {\n const start = Date.now()\n const absolutePath = getAbsolutePath(path) || getCwd()\n\n const args = ['-li', pattern]\n if (include) {\n args.push('--glob', include)\n }\n\n // Collect matches with streaming progress updates\n const matchedFiles: string[] = []\n let lastProgressUpdate = 0\n const PROGRESS_UPDATE_INTERVAL = 100 // Update every 100ms\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 const 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 const output = {\n filenames: matches,\n durationMs: Date.now() - start,\n numFiles: matches.length,\n }\n\n yield {\n type: 'result',\n resultForAssistant: this.renderResultForAssistant(output),\n data: output,\n }\n },\n} satisfies Tool<Input, Output>\n"],
|
|
5
|
-
"mappings": "AAAA,SAAS,YAAY;AACrB,SAAS,KAAK,YAAY;AAC1B,OAAO,WAAW;AAClB,SAAS,SAAS;AAClB,SAAS,YAAY;AACrB,SAAS,sCAAsC;AAC/C,SAAS,uBAAuB;AAEhC,SAAS,cAAc;AACvB,SAAS,iBAAiB,mCAAmC;AAC7D,SAAS,
|
|
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> \u23BF 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> \u23BF 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> \u23BF 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> \u23BF 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"],
|
|
5
|
+
"mappings": "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",
|
|
6
6
|
"names": []
|
|
7
7
|
}
|
|
@@ -1,12 +1,19 @@
|
|
|
1
|
-
const TOOL_NAME_FOR_PROMPT = "
|
|
1
|
+
const TOOL_NAME_FOR_PROMPT = "Grep";
|
|
2
2
|
const DESCRIPTION = `
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
-
|
|
7
|
-
-
|
|
8
|
-
-
|
|
9
|
-
-
|
|
3
|
+
A powerful search tool built on ripgrep
|
|
4
|
+
|
|
5
|
+
Usage:
|
|
6
|
+
- ALWAYS use Grep for search tasks. NEVER invoke \`grep\` or \`rg\` as a Bash command. The Grep tool has been optimized for correct permissions and access.
|
|
7
|
+
- Supports full regex syntax (e.g., "log.*Error", "function\\s+\\w+")
|
|
8
|
+
- Filter files with glob parameter (e.g., "*.js", "**/*.tsx") or type parameter (e.g., "js", "py", "rust")
|
|
9
|
+
- Output modes: "content" shows matching lines, "files_with_matches" shows only file paths (default), "count" shows match counts
|
|
10
|
+
- Use Task tool for open-ended searches requiring multiple rounds
|
|
11
|
+
- Pattern syntax: Uses ripgrep (not grep) - literal braces need escaping (use \`interface\\{\\}\` to find \`interface{}\` in Go code)
|
|
12
|
+
- Multiline matching: By default patterns match within single lines only. For cross-line patterns like \`struct \\{[\\s\\S]*?field\`, use \`multiline: true\`
|
|
13
|
+
- Context options: Use -A (lines after), -B (lines before), or -C/context (lines before and after) to see surrounding code. Requires output_mode: "content".
|
|
14
|
+
- Line numbers: Use -n to show line numbers (default: true for content mode)
|
|
15
|
+
- Case sensitivity: Use -i for case-insensitive search
|
|
16
|
+
- Pagination: Use head_limit to limit results, offset to skip initial results
|
|
10
17
|
`;
|
|
11
18
|
export {
|
|
12
19
|
DESCRIPTION,
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../../../src/tools/GrepTool/prompt.ts"],
|
|
4
|
-
"sourcesContent": ["export const TOOL_NAME_FOR_PROMPT = '
|
|
5
|
-
"mappings": "AAAO,MAAM,uBAAuB;AAE7B,MAAM,cAAc;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;",
|
|
4
|
+
"sourcesContent": ["export const TOOL_NAME_FOR_PROMPT = 'Grep'\n\nexport const DESCRIPTION = `\nA powerful search tool built on ripgrep\n\n Usage:\n - ALWAYS use Grep for search tasks. NEVER invoke \\`grep\\` or \\`rg\\` as a Bash command. The Grep tool has been optimized for correct permissions and access.\n - Supports full regex syntax (e.g., \"log.*Error\", \"function\\\\s+\\\\w+\")\n - Filter files with glob parameter (e.g., \"*.js\", \"**/*.tsx\") or type parameter (e.g., \"js\", \"py\", \"rust\")\n - Output modes: \"content\" shows matching lines, \"files_with_matches\" shows only file paths (default), \"count\" shows match counts\n - Use Task tool for open-ended searches requiring multiple rounds\n - Pattern syntax: Uses ripgrep (not grep) - literal braces need escaping (use \\`interface\\\\{\\\\}\\` to find \\`interface{}\\` in Go code)\n - Multiline matching: By default patterns match within single lines only. For cross-line patterns like \\`struct \\\\{[\\\\s\\\\S]*?field\\`, use \\`multiline: true\\`\n - Context options: Use -A (lines after), -B (lines before), or -C/context (lines before and after) to see surrounding code. Requires output_mode: \"content\".\n - Line numbers: Use -n to show line numbers (default: true for content mode)\n - Case sensitivity: Use -i for case-insensitive search\n - Pagination: Use head_limit to limit results, offset to skip initial results\n`\n"],
|
|
5
|
+
"mappings": "AAAO,MAAM,uBAAuB;AAE7B,MAAM,cAAc;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;",
|
|
6
6
|
"names": []
|
|
7
7
|
}
|
|
@@ -1,9 +1,11 @@
|
|
|
1
1
|
import { NotebookEditTool } from "../NotebookEditTool/NotebookEditTool.js";
|
|
2
|
-
|
|
2
|
+
import { FileReadTool } from "../FileReadTool/FileReadTool.js";
|
|
3
|
+
import { FileEditTool } from "../FileEditTool/FileEditTool.js";
|
|
4
|
+
const DESCRIPTION = `This is a tool for making multiple edits to a single file in one operation. It is built on top of the ${FileEditTool.name} tool and allows you to perform multiple find-and-replace operations efficiently. Prefer this tool over the ${FileEditTool.name} tool when you need to make multiple edits to the same file.
|
|
3
5
|
|
|
4
6
|
Before using this tool:
|
|
5
7
|
|
|
6
|
-
1. Use the
|
|
8
|
+
1. Use the ${FileReadTool.name} tool to understand the file's contents and context
|
|
7
9
|
2. Verify the directory path is correct
|
|
8
10
|
|
|
9
11
|
To make multiple file edits, provide the following:
|
|
@@ -21,7 +23,7 @@ IMPORTANT:
|
|
|
21
23
|
- For Jupyter notebooks (.ipynb files), use the ${NotebookEditTool.name} instead
|
|
22
24
|
|
|
23
25
|
CRITICAL REQUIREMENTS:
|
|
24
|
-
1. All edits follow the same requirements as the single
|
|
26
|
+
1. All edits follow the same requirements as the single ${FileEditTool.name} tool
|
|
25
27
|
2. The edits are atomic - either all succeed or none are applied
|
|
26
28
|
3. Plan your edits carefully to avoid conflicts between sequential operations
|
|
27
29
|
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../../../src/tools/MultiEditTool/prompt.ts"],
|
|
4
|
-
"sourcesContent": ["import { NotebookEditTool } from '@tools/NotebookEditTool/NotebookEditTool'\n\nexport const DESCRIPTION = `This is a tool for making multiple edits to a single file in one operation. It is built on top of the
|
|
5
|
-
"mappings": "AAAA,SAAS,wBAAwB;
|
|
4
|
+
"sourcesContent": ["import { NotebookEditTool } from '@tools/NotebookEditTool/NotebookEditTool'\nimport { FileReadTool } from '@tools/FileReadTool/FileReadTool'\nimport { FileEditTool } from '@tools/FileEditTool/FileEditTool'\n\nexport const DESCRIPTION = `This is a tool for making multiple edits to a single file in one operation. It is built on top of the ${FileEditTool.name} tool and allows you to perform multiple find-and-replace operations efficiently. Prefer this tool over the ${FileEditTool.name} tool when you need to make multiple edits to the same file.\n\nBefore using this tool:\n\n1. Use the ${FileReadTool.name} tool to understand the file's contents and context\n2. Verify the directory path is correct\n\nTo make multiple file edits, provide the following:\n1. file_path: The absolute path to the file to modify (must be absolute, not relative)\n2. edits: An array of edit operations to perform, where each edit contains:\n - old_string: The text to replace (must match the file contents exactly, including all whitespace and indentation)\n - new_string: The edited text to replace the old_string\n - replace_all: Replace all occurences of old_string. This parameter is optional and defaults to false.\n\nIMPORTANT:\n- All edits are applied in sequence, in the order they are provided\n- Each edit operates on the result of the previous edit\n- All edits must be valid for the operation to succeed - if any edit fails, none will be applied\n- This tool is ideal when you need to make several changes to different parts of the same file\n- For Jupyter notebooks (.ipynb files), use the ${NotebookEditTool.name} instead\n\nCRITICAL REQUIREMENTS:\n1. All edits follow the same requirements as the single ${FileEditTool.name} tool\n2. The edits are atomic - either all succeed or none are applied\n3. Plan your edits carefully to avoid conflicts between sequential operations\n\nWARNING:\n- The tool will fail if edits.old_string doesn't match the file contents exactly (including whitespace)\n- The tool will fail if edits.old_string and edits.new_string are the same\n- Since edits are applied in sequence, ensure that earlier edits don't affect the text that later edits are trying to find\n\nWhen making edits:\n- Ensure all edits result in idiomatic, correct code\n- Do not leave the code in a broken state\n- Always use absolute file paths (starting with /)\n- Use replace_all for replacing and renaming strings across the file. This parameter is useful if you want to rename a variable for instance.\n\nIf you want to create a new file, use:\n- A new file path, including dir name if needed\n- First edit: empty old_string and the new file's contents as new_string\n- Subsequent edits: normal edit operations on the created content`\n\nexport const PROMPT = DESCRIPTION\n"],
|
|
5
|
+
"mappings": "AAAA,SAAS,wBAAwB;AACjC,SAAS,oBAAoB;AAC7B,SAAS,oBAAoB;AAEtB,MAAM,cAAc,yGAAyG,aAAa,IAAI,+GAA+G,aAAa,IAAI;AAAA;AAAA;AAAA;AAAA,aAIxQ,aAAa,IAAI;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,kDAeoB,iBAAiB,IAAI;AAAA;AAAA;AAAA,0DAGb,aAAa,IAAI;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAoBpE,MAAM,SAAS;",
|
|
6
6
|
"names": []
|
|
7
7
|
}
|