跪拜 Guibai
← All articles
Frontend · Agent · AI Programming

The 4 Tools That Let Claude Code Actually Modify and Run Your Code

By 不一样的少年_ ·
Read original on juejin.cn ↗ Google Translate ↗ Alt translation

The registry-and-interface pattern shown here is the same dispatch layer that production coding agents use to scale from one tool to dozens without rewriting the agent loop. Understanding it demystifies how tools like Claude Code stay extensible, and the path-safety and edit-uniqueness checks are exactly the kind of unglamorous guards that prevent an agent from silently corrupting a project.

Summary

A hand-built AI coding agent gains the ability to create files, make precise edits, and run terminal commands through four standardized tools: read_file, write_file, edit_file, and bash. Each tool implements a common interface that supplies a name, a model-facing definition, and an execute function, while a central Registry stores, looks up, and dispatches every tool by name. The Agent loop no longer hard-codes tool logic; it asks the Registry for definitions, sends them to the model, and delegates execution through a single call. File tools enforce path safety by resolving all paths against the project root and rejecting any that escape it. The edit_file tool refuses ambiguous modifications by counting occurrences of old_text and demanding a unique match before writing. The bash tool wraps Node's child_process with a timeout, output buffer limit, and working-directory lock, then feeds both stdout and stderr back to the model so it can see build or test failures. The result is a minimal but functional read-modify-run loop that mirrors the core architecture inside Claude Code and similar agents.

Takeaways
A tool is a program capability exposed to the model: the model requests it by name with JSON arguments, and the program executes it.
All tools implement a single Tool interface with a name, a model-facing definition, and an async execute method.
A Registry class stores tools in a Map, returns all definitions to the model, and dispatches execution by name so the Agent loop never grows if-else chains.
Path safety is enforced by resolving every file path against the project root and rejecting any result that escapes the working directory.
The edit_file tool counts occurrences of old_text via split().length - 1; it refuses to modify unless the match is unique, preventing ambiguous edits.
The bash tool runs commands through bash -c with a 30-second timeout and an 8 KB output buffer, then merges stdout and stderr so the model sees both success and failure output.
When a tool throws, the Agent loop catches the error and feeds it back as a tool result, letting the model read failure details and decide the next step.
Adding a new tool requires only implementing the Tool interface and registering it; the Agent loop and ChatClient stay unchanged.
Conclusions

The edit_file uniqueness check is a design choice that prioritizes safety over convenience: it forces the model to provide enough context to identify a single location, rather than guessing and risking silent corruption.

Using bash -c as the execution model gives the agent the full power of shell composition (pipes, &&, etc.) but also inherits all the security risks of the current user's permissions, which the article correctly labels as a local-only teaching harness.

Separating file tools from bash is not redundant; structured parameters avoid shell-escaping bugs, and the separation enables finer-grained permission control later, such as allowing reads while blocking writes and command execution.

The split().length - 1 trick for counting substring occurrences is a zero-dependency alternative to regex matching, but it fails if old_text contains characters that have special meaning in a regex context, which is avoided here by using a plain string split.

Concepts & terms
Agent Loop
The core cycle of an AI agent: the model decides the next action, the program executes the corresponding tool, the result is fed back to the model, and the cycle repeats until a stop condition is met.
Tool Registry
A central dispatcher that stores tool instances by name, provides their definitions to the model, and routes execution requests to the correct tool without the agent loop needing to know implementation details.
stdout / stderr
The two standard output streams in Unix-like systems. stdout carries normal program output; stderr carries error and diagnostic messages. Merging both ensures the model sees all terminal feedback.
bash -c
A way to execute a command string through the Bash shell. The -c flag tells Bash to read and run the following string as a command, enabling shell features like pipes (|) and conditional chaining (&&).
promisify
A Node.js utility from the util module that converts a callback-based function into one that returns a Promise, allowing it to be used with async/await syntax.
Source: juejin.cn ↗ Google Translate ↗ Backup ↗