Exploring the architecture of coding agents by rebuilding a Claude Code-style CLI from scratch in Swift.
$ npx -y skills add ivan-magda/swift-coding-agent --agent claude-code
Run the curl in your terminal, the rest in Claude Code.
What's inside
Exploring the architecture of coding agents by rebuilding a Claude Code-style CLI from scratch in Swift.

A 9-part learning series covers the build on ivanmagda.dev.
Claude Code works better than most coding agents I've used, and I think the reason is restraint. I studied its tool surface and traced its loop to isolate which design choices do the work.
My working theory: coding agents benefit more from a small set of excellent tools and a tight loop than from large orchestration layers.
Claude Code ships few tools, and the ones it has are simple: a search tool, a file editor. They work well. The system trusts the model and skips the scaffolding most agents pile on.
This project rebuilds those mechanics in Swift, one stage at a time, to find out how little architecture the job needs.
This project tests a few specific ideas about coding agents:
Each stage isolates one mechanism so I can see what it enables.
The whole thing boils down to one loop:
func run(query: String) async throws -> String {
messages.append(.user(query))
while true {
let request = APIRequest(
model: model, system: systemPrompt, messages: messages, tools: Self.toolDefinitions
)
let response = try await apiClient.createMessage(request)
messages.append(Message(role: .assistant, content: response.content))
guard response.stopReason == .toolUse else {
return response.content.textContent
}
var results: [ContentBlock] = []
for block in response.content {
if case .toolUse(let id, let name, let input) = block {
let output = await executeTool(name: name, input: input)
results.append(.toolResult(toolUseId: id, content: output, isError: false))
}
}
messages.append(Message(role: .user, content: results))
}
}
The loop is fixed; the tools vary. Every stage adds entries to the tool handler dictionary and injection points before the API call, but the loop body itself stays identical.
Git tags track progress. The roadmap has two phases: core mechanics first, then product-level features.
The minimum viable agent: a loop and a small set of good tools.
| Stage | What It Adds | Tag |
|---|---|---|
| 00 | Bootstrap: SPM project, two-target layout, CI | 00-bootstrap |
| 01 | Agent loop + bash tool | 01-agent-loop |
| 02 | Tool dispatch: read_file, write_file, edit_file with path safety | 02-tool-dispatch |
| 03 | Todo tracking with nag reminder injection | 03-todo-write |
The features that make an agent feel like a usable product: context, memory management, and persistence.
| Stage | What It Adds | Tag |
|---|---|---|
| 04 | Subagents: recursive loop with fresh context | 04-subagents |
| 05 | Skill loading: .md files injected as tool results | 05-skill-loading |
| 06 | Context compaction: 3-layer strategy (micro, auto, manual) | 06-context-compaction |
| 07 | Task system: file-based CRUD with dependency DAG | 07-task-system |
| 08 | Background tasks: Task {} + actor-based notification queue | 08-background-tasks |
Two-target Swift Package Manager project:
Core is the library: API client, shell executor, agent loop, tools.
CLI is the entry point. The executable is named agent.
The agent talks to POST https://api.anthropic.com/v1/messages over raw HTTP, built on AsyncHTTPClient. It runs on macOS and Linux.
This project is not:
It's a staged exploration of coding-agent architecture. The gaps are deliberate.
Process for shell command executiongit clone https://github.com/ivan-magda/swift-coding-agent.git
cd swift-coding-agent
# Set up your API key and model
cp .env.example .env
# Edit .env with your ANTHROPIC_API_KEY and MODEL_ID
swift build
swift run agent
tool_use, and tool_result workMIT
.env.example
.github/
workflows/
ci.yml
.gitignore
.swift-format
.swiftlint.yml
demo.gif
docs/
s00.md
s01.md
s02.md
s03.md
s04.md
s05.md
s06.md
s07.md
s08.md
LICENSE
Package.resolved
Package.swift
README.md
skills/
example/
SKILL.md
Sources/
cli/
SwiftClaudeCode.swift
Core/
Agent.swift
ANSIColor.swift
API/
APIClient.swift
APIModels.swift
JSONValue.swift
BackgroundManager.swift
ContextCompactor.swift
ShellExecutor.swift
SkillLoader.swift
TaskManager.swift
TodoManager.swift
Tests/
CoreTests/
AgentCompactTests.swift
AgentFileToolTests.swift
AgentLoadSkillTests.swift
AgentLoopTests.swift
AgentSubagentTests.swift
AgentTaskToolTests.swift
AgentTestHelpers.swift
AgentTests.swift
AgentToolDispatchTests.swift
APIModelsTests.swift
BackgroundManagerTests.swift
ContextCompactorTests.swift
JSONValueTests.swift
ShellExecutorTests.swift
SkillLoaderTests.swift
TaskManagerTests.swift
TodoManagerTests.swiftFAQ
swift-coding-agent is a Claude Code plugin with 1 hand-picked skill for development work, indexed on Flowy. Install it with the command on its page. It includes example. Its skills do not fire on their own yet. Request auto-invocation to have Flowy route them as you prompt. Free and open source.