|
11 | 11 | 7. [Analytics Service](#analytics-service) |
12 | 12 | 8. [Hands-on: Streaming API Client](#hands-on-streaming-api-client) |
13 | 13 | 9. [Key Takeaways & What's Next](#key-takeaways--whats-next) |
| 14 | +10. [Hands-on: Complete File Operation Tools](#hands-on-complete-file-operation-tools) |
14 | 15 |
|
15 | 16 | --- |
16 | 17 |
|
@@ -721,4 +722,98 @@ Chapter 7 covers the **Permission System** — how Claude Code decides whether a |
721 | 722 |
|
722 | 723 | --- |
723 | 724 |
|
| 725 | +## Hands-on: Complete File Operation Tools |
| 726 | + |
| 727 | +> **This section is another major upgrade to the demo.** We add three file operation tools — FileWriteTool, FileEditTool, and GlobTool — giving mini-claude full file read/write and search capabilities. |
| 728 | +
|
| 729 | +### Project Structure Update |
| 730 | + |
| 731 | +``` |
| 732 | +demo/ |
| 733 | +├── tools/ |
| 734 | +│ ├── BashTool/ |
| 735 | +│ │ └── index.ts |
| 736 | +│ ├── FileReadTool/ |
| 737 | +│ │ └── index.ts |
| 738 | +│ ├── GrepTool/ |
| 739 | +│ │ └── index.ts |
| 740 | +│ ├── FileWriteTool/ |
| 741 | +│ │ └── index.ts # ← New: create/overwrite files |
| 742 | +│ ├── FileEditTool/ |
| 743 | +│ │ └── index.ts # ← New: precise string replacement |
| 744 | +│ └── GlobTool/ |
| 745 | +│ └── index.ts # ← New: file path matching |
| 746 | +├── tools.ts # Updated: register new tools |
| 747 | +├── query.ts |
| 748 | +├── main.ts |
| 749 | +├── Tool.ts |
| 750 | +├── context.ts |
| 751 | +├── services/api/ |
| 752 | +├── utils/ |
| 753 | +│ └── messages.ts |
| 754 | +└── types/ |
| 755 | +``` |
| 756 | + |
| 757 | +### Three New Tools Explained |
| 758 | + |
| 759 | +| Tool | Function | Key Design | |
| 760 | +|------|----------|------------| |
| 761 | +| FileWriteTool (Write) | Create/overwrite files | Auto-creates intermediate directories; reports line count and byte size | |
| 762 | +| FileEditTool (Edit) | Precise string replacement | old_string must match uniquely; saves tokens compared to full file rewrite | |
| 763 | +| GlobTool (Glob) | File path matching | Uses Bun.Glob; results capped at 1000 | |
| 764 | + |
| 765 | +**FileWriteTool** accepts `file_path` and `content` parameters, writing content to the specified path. If parent directories don't exist, they are created recursively (`mkdir -p` semantics). After writing, it returns line count and byte size so the model can confirm the operation result. |
| 766 | + |
| 767 | +**FileEditTool** accepts `file_path`, `old_string`, and `new_string` parameters, finding `old_string` in the file and replacing it with `new_string`. The core constraint is that **old_string must match uniquely in the file** — if it matches zero times or multiple times, the tool returns an error. This design prevents replacements at wrong locations. |
| 768 | + |
| 769 | +**GlobTool** accepts `pattern` and an optional `path` parameter, matching file paths using glob patterns. It uses the `Bun.Glob` API internally, with results capped at 1000 files to prevent excessive token consumption. |
| 770 | + |
| 771 | +### Why String Replacement Instead of Diff? |
| 772 | + |
| 773 | +This is a design choice worth reflecting on. Traditional file editing tools might use unified diff format, but Claude Code chose the old_string → new_string string replacement approach for several reasons: |
| 774 | + |
| 775 | +- **AI generates precise old_string → new_string more reliably than unified diff** — the model only needs to copy the original text to modify and write the replacement, without computing correct line numbers and hunk headers |
| 776 | +- **Unique match checking prevents edits at wrong locations** — if old_string appears multiple times in the file, the tool refuses to execute and returns an error, forcing the model to provide more context for precise targeting |
| 777 | +- **Real Claude Code uses the same approach** — this isn't a simplification, but a production-validated optimal solution |
| 778 | + |
| 779 | +### Tool Landscape |
| 780 | + |
| 781 | +mini-claude now has 7 tools, categorized by read/write characteristics: |
| 782 | + |
| 783 | +``` |
| 784 | +Read-only tools (can run concurrently): Echo, Read, Grep, Glob |
| 785 | +Read-write tools (must run serially): Bash, Write, Edit |
| 786 | +``` |
| 787 | + |
| 788 | +Read-only tools don't modify filesystem state and can safely run concurrently. Read-write tools may change the filesystem and must run serially to avoid race conditions. This classification becomes critical in Chapter 7's permission system — read-write tools require user confirmation, while read-only tools can execute automatically. |
| 789 | + |
| 790 | +### Running the Demo |
| 791 | + |
| 792 | +```bash |
| 793 | +cd demo && bun run main.ts |
| 794 | +``` |
| 795 | + |
| 796 | +Try these interactions to verify the new tools: |
| 797 | + |
| 798 | +``` |
| 799 | +you> Create a hello.txt file with content "Hello, World!" |
| 800 | +you> Change "World" to "Claude" in hello.txt |
| 801 | +you> Find all .ts files in the current directory |
| 802 | +``` |
| 803 | + |
| 804 | +### Mapping to Real Claude Code |
| 805 | + |
| 806 | +| Demo File | Real File | What's Simplified | |
| 807 | +|-----------|-----------|-------------------| |
| 808 | +| `tools/FileWriteTool/index.ts` | `src/tools/FileWriteTool/` | No permission checks, no symlink protection | |
| 809 | +| `tools/FileEditTool/index.ts` | `src/tools/FileEditTool/` | No replace_all mode, no syntax validation | |
| 810 | +| `tools/GlobTool/index.ts` | `src/tools/GlobTool/` | No gitignore filtering, no sort-by-mtime | |
| 811 | +| `tools.ts` (registers 7 tools) | `src/tools.ts` | No lazy loading, no feature flag filtering | |
| 812 | + |
| 813 | +### Next Chapter Preview |
| 814 | + |
| 815 | +Chapter 7 will implement the permission system, ensuring dangerous operations (like `rm -rf`, writing to system files) require user confirmation. Read-write tools will be strictly controlled, while read-only tools can execute freely. |
| 816 | + |
| 817 | +--- |
| 818 | + |
724 | 819 | *Source references: `src/services/api/client.ts`, `src/services/api/withRetry.ts`, `src/QueryEngine.ts`, `src/query.ts`, `src/services/compact/compact.ts`, `src/services/compact/autoCompact.ts`, `src/services/tokenEstimation.ts`, `src/cost-tracker.ts`, `src/services/analytics/index.ts`, `src/services/analytics/growthbook.ts`* |
0 commit comments