Tools
Woopcode ships 19 tools. The agent chooses which to call; you control what happens when it calls one that writes.
Which of these can change my files#
These, and only these. Everything else either reads the repository, runs a command, or asks you a question.
| Tool | What it does | Approval |
|---|---|---|
create_file |
Creates a new file with the provided content. Pass an empty string to create an empty file. | Pauses on a unified diff. Nothing is written until you approve it. |
write_file |
Overwrite an existing file. | Pauses on a unified diff. Nothing is written until you approve it. |
edit_file |
Replace text inside an existing file. oldText must match exactly one place in the file, or the edit is refused so the wrong occurrence is never changed. | Pauses on a unified diff. Nothing is written until you approve it. |
Every one of those pauses on a unified diff and waits. No approval mode turns that off — see Reviewing diffs.
Explore and read#
These never change anything and never ask.
| Tool | What it does | Approval |
|---|---|---|
list_files |
List files in a directory, skipping dependency and build directories. Returns up to 500 files. Use sparingly - only when you need to see directory structure. For finding specific files, use find_files instead. | Runs without asking. Reads only; never changes the workspace. |
read_file |
Reads the contents of a file. Pass startLine and endLine to read only part of a large file; both are 1-indexed and inclusive. Reading a range is preferable to reading a whole large file when the relevant location is already known, for example from a grep match or an error message. | Runs without asking. Reads only; never changes the workspace. |
grep |
Searches recursively for text in project files. | Runs without asking. Reads only; never changes the workspace. |
find_files |
Finds files by name or partial filename, skipping dependency and build directories. Returns up to 200 matches. Use specific queries (e.g., 'websocket', 'config') rather than broad patterns (e.g., '.'). | Runs without asking. Reads only; never changes the workspace. |
glob |
Search for files matching a glob pattern. Supports wildcards like *, **, ?, [abc], etc. |
Examples:
- "*.ts" - All TypeScript files in current directory
- "**/*.test.ts" - All test files recursively
- "src/**/*.{ts,tsx}" - TypeScript/TSX files in src/
- "*.{js,json}" - JS and JSON files
Returns up to 100 matching file paths. | Runs without asking. Reads only; never changes the workspace. |
| web_search | Search the web for current information, documentation, or answers to questions.
Use this when you need:
- Current/up-to-date information (news, prices, versions, etc.)
- Documentation or API references
- Technical solutions or stack overflow answers
- Verify information that may have changed recently
Returns a list of relevant web pages with titles, URLs, and snippets.
Current year: 2026 | Runs without asking. Reads only; never changes the workspace. |
| web_fetch | Fetch and extract content from a specific URL.
Use this to:
- Read documentation pages
- Fetch article content
- Get data from specific web pages
- Read content found via web_search
Supports:
- HTML pages (converts to readable text)
- Plain text
- JSON data
- Markdown
Max response size: 5MB
Default timeout: 30 seconds | Runs without asking. Reads only; never changes the workspace. |
| read_image | Shows you an image. Use it to look at a screenshot, a diagram, a rendered figure or a video frame rather than inferring their contents from pixel statistics.
The image arrives with the next message, so describe what you are looking for and then read what you actually see. To inspect a frame of a video, extract it to a file first (ffmpeg, or cv2 in the repl) and read that file.
Accepts PNG, JPEG, GIF and WebP. | Runs without asking. Reads only; never changes the workspace. |
Shell#
| Tool | What it does | Approval |
|---|---|---|
run_terminal |
Runs a terminal command in the current project. For commands that finish on their own (tests, builds, installs). Do not use for starting servers or long-running processes. | Gated by the approval mode. |
run_tests |
Runs the project's test command. For quick test execution only - do not use to start servers. | Gated by the approval mode. |
repl |
Runs code in an interpreter that stays alive between calls, so variables, imports and loaded data persist. |
Use it instead of run_terminal with python3 -c or node -e whenever the work takes more than one step over the same data. Load a file, parse an archive or decode a video once, then keep querying what is already in memory — re-reading the same input on every call is the single most expensive habit available here.
State lasts for the current turn and is discarded when the turn ends.
python: the value of a trailing expression is printed, as in a notebook.
node: a top-level var persists between calls; const and let are scoped to the single call, so assign to globalThis for anything that must outlive it.
This runs real code. It can write files and shell out, and is subject to the same approval and plan-mode rules as run_terminal. | Gated by the approval mode. |
| process_start | Starts a command in the background and returns immediately with an id.
Use it for anything that does not exit on its own — a development server, a watcher, a long build you want to follow. For a command that finishes and whose output you need, use run_terminal instead; it waits and returns the result in one call.
The process keeps running after this turn ends. Read what it has printed with process_output and end it with process_stop. | Gated by the approval mode. |
| process_output | Returns what a background process has printed since the last time this was called for it, along with whether it is still running. Output already returned is not repeated. | Gated by the approval mode. |
| process_stop | Stops a background process and returns any output it had not yet shown. Use it as soon as a process is no longer needed — one left running holds its port and its files. | Gated by the approval mode. |
Gated by the approval mode, not by a diff. The default runs reads and tests without asking and stops before anything that writes.
Ask#
| Tool | What it does | Approval |
|---|---|---|
ask_user |
Ask the user questions to gather information needed to complete their request. |
Use this when you need:
- Clarification on ambiguous requests
- Additional details or preferences
- User confirmation before proceeding
- Input that only the user can provide
You can ask multiple questions at once. Each question will be presented to the user, and their answers will be returned to you.
Examples:
- "Which API endpoint should I modify?"
- "Do you want to use TypeScript or JavaScript?"
- "Should I update the tests as well?" | Stops the turn and waits for your answer. |
The turn stops and waits for your answer, then continues with it.
Every tool#
| Tool | What it does | Approval |
|---|---|---|
list_files |
List files in a directory, skipping dependency and build directories. Returns up to 500 files. Use sparingly - only when you need to see directory structure. For finding specific files, use find_files instead. | Runs without asking. Reads only; never changes the workspace. |
read_file |
Reads the contents of a file. Pass startLine and endLine to read only part of a large file; both are 1-indexed and inclusive. Reading a range is preferable to reading a whole large file when the relevant location is already known, for example from a grep match or an error message. | Runs without asking. Reads only; never changes the workspace. |
run_terminal |
Runs a terminal command in the current project. For commands that finish on their own (tests, builds, installs). Do not use for starting servers or long-running processes. | Gated by the approval mode. |
create_file |
Creates a new file with the provided content. Pass an empty string to create an empty file. | Pauses on a unified diff. Nothing is written until you approve it. |
write_file |
Overwrite an existing file. | Pauses on a unified diff. Nothing is written until you approve it. |
edit_file |
Replace text inside an existing file. oldText must match exactly one place in the file, or the edit is refused so the wrong occurrence is never changed. | Pauses on a unified diff. Nothing is written until you approve it. |
grep |
Searches recursively for text in project files. | Runs without asking. Reads only; never changes the workspace. |
run_tests |
Runs the project's test command. For quick test execution only - do not use to start servers. | Gated by the approval mode. |
find_files |
Finds files by name or partial filename, skipping dependency and build directories. Returns up to 200 matches. Use specific queries (e.g., 'websocket', 'config') rather than broad patterns (e.g., '.'). | Runs without asking. Reads only; never changes the workspace. |
glob |
Search for files matching a glob pattern. Supports wildcards like *, **, ?, [abc], etc. |
Examples:
- "*.ts" - All TypeScript files in current directory
- "**/*.test.ts" - All test files recursively
- "src/**/*.{ts,tsx}" - TypeScript/TSX files in src/
- "*.{js,json}" - JS and JSON files
Returns up to 100 matching file paths. | Runs without asking. Reads only; never changes the workspace. |
| web_search | Search the web for current information, documentation, or answers to questions.
Use this when you need:
- Current/up-to-date information (news, prices, versions, etc.)
- Documentation or API references
- Technical solutions or stack overflow answers
- Verify information that may have changed recently
Returns a list of relevant web pages with titles, URLs, and snippets.
Current year: 2026 | Runs without asking. Reads only; never changes the workspace. |
| web_fetch | Fetch and extract content from a specific URL.
Use this to:
- Read documentation pages
- Fetch article content
- Get data from specific web pages
- Read content found via web_search
Supports:
- HTML pages (converts to readable text)
- Plain text
- JSON data
- Markdown
Max response size: 5MB
Default timeout: 30 seconds | Runs without asking. Reads only; never changes the workspace. |
| ask_user | Ask the user questions to gather information needed to complete their request.
Use this when you need:
- Clarification on ambiguous requests
- Additional details or preferences
- User confirmation before proceeding
- Input that only the user can provide
You can ask multiple questions at once. Each question will be presented to the user, and their answers will be returned to you.
Examples:
- "Which API endpoint should I modify?"
- "Do you want to use TypeScript or JavaScript?"
- "Should I update the tests as well?" | Stops the turn and waits for your answer. |
|
todo_write| Records the task list for the work in progress, so the user can see what is done and what is left.
Send the complete list every time — it replaces the previous one rather than adding to it. Keep exactly one item in_progress, and mark an item completed as soon as it is finished rather than in a batch at the end.
Use it for work with several distinct steps, and for a plan the user has just approved. Skip it for a single-step change or a question: a one-item list tells the user nothing they did not already know.
This records intent only. It changes no files and runs nothing, so it is available while planning. | Runs without asking. Records what the agent intends; changes nothing. |
| repl | Runs code in an interpreter that stays alive between calls, so variables, imports and loaded data persist.
Use it instead of run_terminal with python3 -c or node -e whenever the work takes more than one step over the same data. Load a file, parse an archive or decode a video once, then keep querying what is already in memory — re-reading the same input on every call is the single most expensive habit available here.
State lasts for the current turn and is discarded when the turn ends.
python: the value of a trailing expression is printed, as in a notebook.
node: a top-level var persists between calls; const and let are scoped to the single call, so assign to globalThis for anything that must outlive it.
This runs real code. It can write files and shell out, and is subject to the same approval and plan-mode rules as run_terminal. | Gated by the approval mode. |
| process_start | Starts a command in the background and returns immediately with an id.
Use it for anything that does not exit on its own — a development server, a watcher, a long build you want to follow. For a command that finishes and whose output you need, use run_terminal instead; it waits and returns the result in one call.
The process keeps running after this turn ends. Read what it has printed with process_output and end it with process_stop. | Gated by the approval mode. |
| process_output | Returns what a background process has printed since the last time this was called for it, along with whether it is still running. Output already returned is not repeated. | Gated by the approval mode. |
| process_stop | Stops a background process and returns any output it had not yet shown. Use it as soon as a process is no longer needed — one left running holds its port and its files. | Gated by the approval mode. |
| read_image | Shows you an image. Use it to look at a screenshot, a diagram, a rendered figure or a video frame rather than inferring their contents from pixel statistics.
The image arrives with the next message, so describe what you are looking for and then read what you actually see. To inspect a frame of a video, extract it to a file first (ffmpeg, or cv2 in the repl) and read that file.
Accepts PNG, JPEG, GIF and WebP. | Runs without asking. Reads only; never changes the workspace. |
How a tool call goes wrong#
Tool failures are returned to the agent rather than ending the turn, so it can correct itself and try again. Three limits shape what it sees:
| Limit | Value | Effect |
|---|---|---|
| Tool result size | 4,000 characters | Longer results are truncated with a notice |
| Identical calls per turn | 4 | The fifth is skipped and the agent told why |
| Iterations per turn | 20 | The turn ends; a warning is issued at 15 |
The duplicate check compares the tool name and its exact arguments. The first four identical calls run normally; from the fifth on, the agent gets a skip notice instead of the result:
Skipped duplicate read_file call. The result for these exact arguments isalready in the conversation; use it and continue with a different action.
That is what stops a turn from looping on the same lookup. Reading the same file twice is fine and happens often.
See also#
read_file— one tool in full- Approval modes — what gates the shell tools
- Adding a tool — the registry these come from
Added in woopcode@0.6.0