Skip to content

Commit 5c3ba94

Browse files
authored
add support for ripgrep search (#30)
1 parent 6f8f9cf commit 5c3ba94

File tree

7 files changed

+552
-10
lines changed

7 files changed

+552
-10
lines changed

package-lock.json

Lines changed: 9 additions & 2 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

package.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,7 @@
3434
"ink-markdown": "^1.0.4",
3535
"openai": "^5.10.1",
3636
"react": "^17.0.2",
37+
"ripgrep-node": "^1.0.0",
3738
"tiktoken": "^1.0.21"
3839
},
3940
"devDependencies": {

src/agent/grok-agent.ts

Lines changed: 26 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,12 @@
11
import { GrokClient, GrokMessage, GrokToolCall } from "../grok/client";
22
import { GROK_TOOLS } from "../grok/tools";
3-
import { TextEditorTool, BashTool, TodoTool, ConfirmationTool } from "../tools";
3+
import {
4+
TextEditorTool,
5+
BashTool,
6+
TodoTool,
7+
ConfirmationTool,
8+
SearchTool,
9+
} from "../tools";
410
import { ToolResult } from "../types";
511
import { EventEmitter } from "events";
612
import { createTokenCounter, TokenCounter } from "../utils/token-counter";
@@ -31,6 +37,7 @@ export class GrokAgent extends EventEmitter {
3137
private bash: BashTool;
3238
private todoTool: TodoTool;
3339
private confirmationTool: ConfirmationTool;
40+
private search: SearchTool;
3441
private chatHistory: ChatEntry[] = [];
3542
private messages: GrokMessage[] = [];
3643
private tokenCounter: TokenCounter;
@@ -43,6 +50,7 @@ export class GrokAgent extends EventEmitter {
4350
this.bash = new BashTool();
4451
this.todoTool = new TodoTool();
4552
this.confirmationTool = new ConfirmationTool();
53+
this.search = new SearchTool();
4654
this.tokenCounter = createTokenCounter("grok-4-latest");
4755

4856
// Load custom instructions
@@ -61,6 +69,7 @@ You have access to these tools:
6169
- create_file: Create new files with content (ONLY use this for files that don't exist yet)
6270
- str_replace_editor: Replace text in existing files (ALWAYS use this to edit or update existing files)
6371
- bash: Execute bash commands (use for searching, file discovery, navigation, and system operations)
72+
- search: Unified search tool for finding text content or files (similar to Cursor's search functionality)
6473
- create_todo_list: Create a visual todo list for planning and tracking tasks
6574
- update_todo_list: Update existing todos in your todo list
6675
@@ -74,9 +83,9 @@ IMPORTANT TOOL USAGE RULES:
7483
- Use create_file ONLY when creating entirely new files that don't exist
7584
7685
SEARCHING AND EXPLORATION:
77-
- Use bash with commands like 'find', 'grep', 'rg' (ripgrep), 'ls', etc. for searching files and content
78-
- Examples: 'find . -name "*.js"', 'grep -r "function" src/', 'rg "import.*react"'
79-
- Use bash for directory navigation, file discovery, and content searching
86+
- Use search for fast, powerful text search across files or finding files by name (unified search tool)
87+
- Examples: search for text content like "import.*react", search for files like "component.tsx"
88+
- Use bash with commands like 'find', 'grep', 'rg', 'ls' for complex file operations and navigation
8089
- view_file is best for reading specific files you already know exist
8190
8291
When a user asks you to edit, update, modify, or change an existing file:
@@ -550,6 +559,19 @@ Current working directory: ${process.cwd()}`,
550559
case "update_todo_list":
551560
return await this.todoTool.updateTodoList(args.updates);
552561

562+
case "search":
563+
return await this.search.search(args.query, {
564+
searchType: args.search_type,
565+
includePattern: args.include_pattern,
566+
excludePattern: args.exclude_pattern,
567+
caseSensitive: args.case_sensitive,
568+
wholeWord: args.whole_word,
569+
regex: args.regex,
570+
maxResults: args.max_results,
571+
fileTypes: args.file_types,
572+
includeHidden: args.include_hidden,
573+
});
574+
553575
default:
554576
return {
555577
success: false,

src/grok/tools.ts

Lines changed: 64 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -62,15 +62,17 @@ export const GROK_TOOLS: GrokTool[] = [
6262
},
6363
old_str: {
6464
type: "string",
65-
description: "Text to replace (must match exactly, or will use fuzzy matching for multi-line strings)",
65+
description:
66+
"Text to replace (must match exactly, or will use fuzzy matching for multi-line strings)",
6667
},
6768
new_str: {
6869
type: "string",
6970
description: "Text to replace with",
7071
},
7172
replace_all: {
7273
type: "boolean",
73-
description: "Replace all occurrences (default: false, only replaces first occurrence)",
74+
description:
75+
"Replace all occurrences (default: false, only replaces first occurrence)",
7476
},
7577
},
7678
required: ["path", "old_str", "new_str"],
@@ -94,6 +96,66 @@ export const GROK_TOOLS: GrokTool[] = [
9496
},
9597
},
9698
},
99+
{
100+
type: "function",
101+
function: {
102+
name: "search",
103+
description:
104+
"Unified search tool for finding text content or files (similar to Cursor's search)",
105+
parameters: {
106+
type: "object",
107+
properties: {
108+
query: {
109+
type: "string",
110+
description: "Text to search for or file name/path pattern",
111+
},
112+
search_type: {
113+
type: "string",
114+
enum: ["text", "files", "both"],
115+
description:
116+
"Type of search: 'text' for content search, 'files' for file names, 'both' for both (default: 'both')",
117+
},
118+
include_pattern: {
119+
type: "string",
120+
description:
121+
"Glob pattern for files to include (e.g. '*.ts', '*.js')",
122+
},
123+
exclude_pattern: {
124+
type: "string",
125+
description:
126+
"Glob pattern for files to exclude (e.g. '*.log', 'node_modules')",
127+
},
128+
case_sensitive: {
129+
type: "boolean",
130+
description:
131+
"Whether search should be case sensitive (default: false)",
132+
},
133+
whole_word: {
134+
type: "boolean",
135+
description: "Whether to match whole words only (default: false)",
136+
},
137+
regex: {
138+
type: "boolean",
139+
description: "Whether query is a regex pattern (default: false)",
140+
},
141+
max_results: {
142+
type: "number",
143+
description: "Maximum number of results to return (default: 50)",
144+
},
145+
file_types: {
146+
type: "array",
147+
items: { type: "string" },
148+
description: "File types to search (e.g. ['js', 'ts', 'py'])",
149+
},
150+
include_hidden: {
151+
type: "boolean",
152+
description: "Whether to include hidden files (default: false)",
153+
},
154+
},
155+
required: ["query"],
156+
},
157+
},
158+
},
97159
{
98160
type: "function",
99161
function: {

src/tools/index.ts

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
1-
export { TextEditorTool } from "./text-editor";
21
export { BashTool } from "./bash";
2+
export { TextEditorTool } from "./text-editor";
33
export { TodoTool } from "./todo-tool";
44
export { ConfirmationTool } from "./confirmation-tool";
5+
export { SearchTool } from "./search";

0 commit comments

Comments
 (0)