Skip to content

Commit 9dca723

Browse files
committed
Update README.md
1 parent 35a4608 commit 9dca723

1 file changed

Lines changed: 74 additions & 36 deletions

File tree

README.md

Lines changed: 74 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -1,40 +1,30 @@
11
# swift-claude-code
22

3-
Building a simplified Claude Code-like CLI agent from scratch in Swift.
3+
Exploring the architecture of coding agents by rebuilding a Claude Code-style CLI from scratch in Swift.
44

55
> **Current progress:** Stage 02 of 12 — tool dispatch with `read_file`, `write_file`, `edit_file`
66
77
## Why This Exists
88

9-
If you've used Claude Code, you know exactly what I'm talking about. Especially the first time you use it — it's just _different_ than any other coding agent out there. There's definitely some magic behind Claude Code, and I went down a huge rabbit hole trying to figure out what makes it special.
9+
Claude Code feels unusually effective compared to other coding agents, and I suspect most of it comes from architectural restraint rather than architectural complexity. I studied the tool surface, traced the interaction loop, and tried to isolate which design choices actually matter.
1010

11-
My hypothesis: **Claude Code is so good because of how simple it is.**
11+
My working theory: **coding agents benefit more from a small set of excellent tools and tight loop design than from large orchestration layers.**
1212

13-
Not the UI — the architecture. Down to the fact that it doesn't really have many tools. And the tools it does have are really simple: a search tool, a file editing tool. That's about it. But those tools are _really, really good_.
13+
Claude Code doesn't have many tools. The tools it does have are simple: a search tool, a file editing tool. But those tools are really good. And the system leans on the model far more than most agent implementations — less scaffolding, more trust in the LLM to do the heavy lifting.
1414

15-
The other big thing is that Claude Code relies on the model way more than other tools. Most people build a lot of scaffolding around the model, but Claude Code really lets the model do all of the heavy lifting.
15+
This project tests that idea by rebuilding the core mechanics from scratch in Swift, one stage at a time, to see how little architecture you actually need.
1616

17-
So I wanted to understand this deeply — not by reading about it, but by building it. This project rebuilds the core agent loop from scratch in Swift, one layer at a time, to see exactly how few moving parts you actually need.
17+
## Hypothesis
1818

19-
## Architecture
19+
This project tests a few specific ideas about coding agents:
2020

21-
Two-target Swift Package Manager project:
21+
- A small number of high-quality tools beats a large tool catalog
22+
- The model should do most of the heavy lifting — thin orchestration, not thick
23+
- Explicit task state improves reliability more than prompt-only planning
24+
- Controlled context injection matters more than persistent memory
25+
- Context compaction is a product feature, not just a token optimization
2226

23-
```
24-
swift-claude-code/
25-
├── Package.swift
26-
├── Sources/
27-
│ ├── Core/ ← library (all logic)
28-
│ │ ├── API/
29-
│ │ ├── Agent.swift agent loop + tool dispatch
30-
│ │ └── ShellExecutor.swift
31-
│ └── cli/ ← executable (@main entry point)
32-
└── Tests/CoreTests/
33-
```
34-
35-
**Core** is the library — API client, shell executor, agent loop, tools, everything testable. **cli** is just the entry point. The executable is called `claude`.
36-
37-
Raw HTTP to `POST https://api.anthropic.com/v1/messages` using [AsyncHTTPClient](https://github.com/swift-server/async-http-client). Works on both macOS and Linux.
27+
Each stage is designed to isolate one mechanism and see what it enables.
3828

3929
## The Agent Loop
4030

@@ -67,27 +57,75 @@ func run(query: String) async throws -> String {
6757
}
6858
```
6959

70-
That's it. The loop is the invariant. Tools are the variable. Every stage adds entries to the tool handler dictionary and injection points before the API call, but the loop body itself never changes.
60+
The loop is the invariant. Tools are the variable. Every stage adds entries to the tool handler dictionary and injection points before the API call, but the loop body itself never changes.
7161

7262
## Roadmap
7363

74-
Each stage adds one mechanism on top of the previous one. Progress is tracked via git tags.
64+
Progress is tracked via git tags. The roadmap is split into three phases — core mechanics first, then product-level features, then experimental multi-agent systems.
65+
66+
### Phase 1 — Core Loop
67+
68+
The minimum viable agent: a loop and a small set of good tools.
7569

7670
| Stage | What It Adds | Tag |
7771
| ------ | ---------------------------------------------------------------------- | ------------------ |
78-
| **00** | Bootstrap: SPM project | `00-bootstrap` |
72+
| **00** | Bootstrap: SPM project, two-target layout, CI | `00-bootstrap` |
7973
| **01** | Agent loop + bash tool | `01-agent-loop` |
8074
| **02** | Tool dispatch: `read_file`, `write_file`, `edit_file` with path safety | `02-tool-dispatch` |
81-
| 03 | TodoWrite: Codable todo tracking with nag reminder injection ||
82-
| 04 | Subagents: recursive `agentLoop()` with fresh messages ||
83-
| 05 | Skill loading: read `.md` files from disk, inject as tool results ||
84-
| 06 | Context compaction: 3-layer strategy (micro, auto, manual) ||
85-
| 07 | Task system: file-based CRUD with dependency DAG ||
86-
| 08 | Background tasks: `Task {}` + actor-based notification queue ||
87-
| 09 | Agent teams: JSONL mailbox files + actor coordination ||
88-
| 10 | Team protocols: request-response with correlation IDs ||
89-
| 11 | Autonomous agents: idle-poll-claim cycle ||
90-
| 12 | Worktree isolation: `git worktree` via Process ||
75+
| 03 | Todo tracking with nag reminder injection ||
76+
77+
### Phase 2 — Product Mechanics
78+
79+
The features that make an agent feel like a usable product: context, memory management, and persistence.
80+
81+
| Stage | What It Adds | Tag |
82+
| ----- | ------------------------------------------------------------ | --- |
83+
| 04 | Subagents: recursive loop with fresh context ||
84+
| 05 | Skill loading: `.md` files injected as tool results ||
85+
| 06 | Context compaction: 3-layer strategy (micro, auto, manual) ||
86+
| 07 | Task system: file-based CRUD with dependency DAG ||
87+
| 08 | Background tasks: `Task {}` + actor-based notification queue ||
88+
89+
### Phase 3 — Experimental
90+
91+
Multi-agent coordination. These stages explore ideas beyond the core product loop.
92+
93+
| Stage | What It Adds | Tag |
94+
| ----- | ----------------------------------------------------- | --- |
95+
| 09 | Agent teams: JSONL mailbox + actor coordination ||
96+
| 10 | Team protocols: request-response with correlation IDs ||
97+
| 11 | Autonomous agents: idle-poll-claim cycle ||
98+
| 12 | Worktree isolation: `git worktree` via Process ||
99+
100+
## Architecture
101+
102+
Two-target Swift Package Manager project:
103+
104+
```
105+
swift-claude-code/
106+
├── Package.swift
107+
├── Sources/
108+
│ ├── Core/ ← library (all logic)
109+
│ │ ├── API/
110+
│ │ ├── Agent.swift agent loop + tool dispatch
111+
│ │ └── ShellExecutor.swift
112+
│ └── cli/ ← executable (@main entry point)
113+
└── Tests/CoreTests/
114+
```
115+
116+
**Core** is the library — API client, shell executor, agent loop, tools, everything testable. **cli** is just the entry point. The executable is called `claude`.
117+
118+
Raw HTTP to `POST https://api.anthropic.com/v1/messages` using [AsyncHTTPClient](https://github.com/swift-server/async-http-client). Works on both macOS and Linux.
119+
120+
## Non-Goals
121+
122+
This project is **not**:
123+
124+
- A full Claude Code clone or drop-in replacement
125+
- A general-purpose multi-agent framework
126+
- Production-ready IDE tooling
127+
128+
It's a staged exploration of coding-agent architecture — intentionally minimal, intentionally incomplete.
91129

92130
## Tech Stack
93131

0 commit comments

Comments
 (0)