IDInternals Decoded
AI Coding Tools
PlaybooksIntermediate12 min readJul 2026

Open Source Coding Agents: Aider, OpenHands, and Friends

What the open alternatives do well, and where the polish gap actually matters.

Part 5 of 6AI Coding ToolsView series →

Last week we saw how closed tools index and retrieve code to stay sharp on giant repos. This week we flip the lid on four open-source agents that let you own that machinery. The punchline is simple: the things they do well are precisely the things you cannot buy, and the things that still sting are exactly the things polished products smooth over.

Here is the hook. Aider can compress a repository of 100,000 files into fewer than 1,000 tokens and still let a model pinpoint the exact function it needs to change. It does this without a vector database, without a semantic index, and without sending the full codebase to the LLM (large language model). It uses a graph ranking algorithm that looks for the few symbols that hold the whole repo together. The rest is inference.

Aider Repo Map Compression
100,000 files
Repository size
<1,000 tokens
Map token budget
Aider compresses a 100,000-file repo into under 1,000 tokens for the model

How does Aider build its repo map, and why does graph ranking work where brute force fails?

Aider’s core trick is its repository map. You ask it to add a feature, and it builds a concise list of every important class, function, and type signature that lives in your codebase. Every symbol is tagged with the file that defines it and a handful of critical lines. This map is what the model sees alongside your prompt, not a sea of raw code.

The map is not just a file listing. Aider parses the Git repository and builds a dependency graph where each source file is a node. An edge connects file A to file B when A imports, calls, or otherwise depends on B. The graph captures the real shape of the code, not just the directory tree. Once the graph exists, Aider runs a ranking algorithm, similar to PageRank, that identifies the most structurally important parts of the codebase. The algorithm asks: which files, if removed, would break the most connections? Those nodes dominate the map.

The default token budget is about 1,000 tokens, controlled by --map-tokens. Aider keeps the top-ranked symbols that fit inside that budget and discards the rest. The result is a tiny yet targeted view of the entire repo. If the model needs full file contents later, it can ask Aider to load them explicitly. This is the same reasoning-action loop pattern we saw in Part 2, but here the environment is a Git working tree and the tool is a text-based CLI (command-line interface).

Aider’s documentation describes the repo map and the graph-ranking approach in detail. The design sidesteps the expensive embedding pipelines and vector stores that closed tools pour engineering into, and it works because code symbols carry enough semantic signal already. A senior engineer reading the map can guess how to use a module; so can a language model. The real magic is that Aider doesn’t need to guess which files matter. The graph tells it.

That’s the strength. But it’s also the polish gap. The map is static, re-computed on demand. It knows nothing about how code has changed over time or which parts a human developer touched recently. It cannot incorporate runtime traces or test coverage data the way a richer indexing system might. For a monorepo with multiple unconnected services, the graph ranking treats the whole repo as one big graph, which can blur boundaries and pull irrelevant symbols into the map. Aider gives you full transparency and zero black boxes, but you’ll feel the absence of the “works out of the box” smoothing that a tool like Cursor or Copilot spends years on.

How does OpenHands use event sourcing to keep agent state safe and replayable?

If Aider is a smart CLI, OpenHands is a factory for building agents. It ships as an SDK (software development kit), not a finished product, and its architecture leans on one design decision that changes everything: every message, every tool call, every security check, every observation is a typed event that gets appended to an append-only log. The current state of the agent, its conversation, its workspace, its pending approvals, is derived by replaying that log. Nothing lives in memory by default.

This matters because agents crash. An LLM call fails. A workspace pod gets evicted. A tool invocation hits a timeout. In an ad-hoc system, recovering from that crash means hoping that the in-memory structures are still valid. In OpenHands, recovery means loading the last persisted event and continuing the loop from there, because every side effect up to that point is recorded deterministically. The V1 architecture document explains the event-sourced state model. This is the same pattern that powers financial ledgers and domain-driven systems. It gives you audit logs for free, and it turns debugging into reading a timeline.

The SDK layers security on top of this event stream. A pluggable security analyzer inspects every command before it hits the shell. A policy engine decides whether to auto-approve, ask the user, or block. The workspace that runs the code can be a local directory for fast iteration or a sandboxed Docker container for untrusted tasks. The event log captures every decision, so if a command somehow slipped through that shouldn’t have, you know exactly which policy rule let it pass and whose confirmation unlocked it.

Yet here is where the polish gap turns into a genuine friction tax. OpenHands is powerful, but it is not plug-and-play. Setting up a workspace that mirrors your actual development environment, with the right compilers, package managers, and credentials, takes work. The event stream is rich, but there is no off-the-shelf visualization dashboard. The security analyzer can be configured to a fine grain, but the default policies are deliberately cautious, which means a developer spends the first hour clicking “approve” on harmless commands. The closed tools hide this complexity; OpenHands gives you the raw material and expects you to assemble the guardrails yourself.

What is an Agent-Computer Interface, and why did SWE-agent invent one instead of using a shell?

SWE-agent, the research project from Princeton, introduced the idea of an Agent-Computer Interface (ACI). The argument is simple: the interfaces we build for humans, like a raw Linux shell with full rm -rf power, are a terrible match for the capabilities of an LLM. An LLM does not need tab completion, history scrolling, or ANSI escape codes. It needs a small set of operations that are easy to predict and hard to misuse. So SWE-agent defines its own command language. There are commands for navigating the file tree, searching for code patterns, opening files with line numbers, editing specific ranges, and running tests. Each command returns a structured observation, not raw stdout.

Agent-Computer Interface vs Human Interface
Human Interface
  • Graphical UI
  • Mouse and keyboard input
  • Rich visual feedback
Agent Interface
  • Structured text commands
  • Minimal latency
  • Predictable output format
SWE-agent's ACI replaces human-centric interfaces with structured commands agents can parse reliably.

When SWE-agent solves a GitHub issue on SWE-bench, it does not drop into a /bin/bash session. It types ACI commands like find, open, edit, and submit. The harness interprets these, executes them in a Docker sandbox, and feeds back a clean summary. The SWE-agent paper details the ACI design and its benchmark impact. The result is that the model makes fewer catastrophic mistakes and can recover from errors more gracefully because the action space is constrained.

Cline takes a different path to a similar end. Inside VS Code it separates every operation into a plan phase and an act phase. The model can read files, search for symbols, and spawn terminal commands, but every file edit and every shell invocation is gated behind a user-approval step. Cline also maintains a shadow Git repository that records every change, separate from your main history. That means you can throw away an entire agent session without touching your actual branch. Cline’s repository documents the plan-act flow and shadow Git feature.

Both of these feel like safety wins compared to a general-purpose terminal agent. But the integration friction is real. SWE-agent was built for benchmarks, so its ACI assumes a clean Docker environment with no network quirks, no corporate VPNs, and no local secrets that need careful handling. Cline, by running inside VS Code, ties its safety to one editor; pull it into a CI pipeline and you lose the visual approval flow that it leans on. These are tradeoffs that a senior team can work around, but they are exactly the kind of friction that a shrink-wrapped product solves before you ever see the source.

Quick Reference

PropertyAiderOpenHandsSWE-agentCline
Repo context strategyGraph-ranked repo map, on-demand full filesWorkspace abstraction, user-provided contextACI commands for search and file viewIDE filesystem, full file reads
State managementStateless conversation historyEvent-sourced append-only logEphemeral, per-taskPer-session in-memory, shadow Git checkpoints
Safety modelOptional lint/test hooks, user reviews commitsPluggable security analyzer, per-command policiesACI constraints on available commandsPer-file edit and per-shell approval in editor
Action spaceFull file edits via diffsCodeAct (Python or bash in interpreter)Custom ACI commandsPlan-then-act, file edits, terminal, browser
Integration methodTerminal CLI, editor comment promptsSDK, agent server, web GUI, GitHub appDocker sandbox, benchmark harnessVS Code extension (JetBrains community port)
Sourceaider.chatOpenHands GitHubSWE-agent GitHubCline GitHub

Frequently Asked Questions

Q: Can I point Aider at a monorepo that isn’t a single Git root? Aider expects one Git repository root. For monorepos, run aider from a subdirectory that is itself a Git repo, or use sparse checkout. The repo map ranking will span all directories under that root, so you may need to tune --map-tokens and explicitly add only the relevant files when you start the session.

Q: How does OpenHands prevent the agent from running dangerous commands in my local terminal? By default, OpenHands runs in a sandboxed Docker workspace where the filesystem and network are isolated. A configurable security analyzer inspects every command before execution and can block, auto-approve, or require user confirmation. Still, you must review the security policies for your deployment; no automated system can guarantee safety against every possible shell command.

Q: Is SWE-agent suitable for daily development, or is it just a research tool? SWE-agent was architected for benchmarks and designed around ephemeral Docker environments. You can mount a real repo into its container, but it lacks persistent state, rich configuration, and the error-handling that production use demands. Most teams use it as a reference design for ACI concepts, not as a daily driver.

Q: How does Cline’s shadow Git repository differ from Aider’s auto-commits? Aider commits directly to your working branch, so your real Git history contains the agent’s changes. You can revert them like any other commit. Cline maintains a separate opaque Git repository that records every edit but never touches your main history. You can discard an entire agent session in one click without affecting your branch. The shadow repo is a safety net, while Aider’s commits are a permanent audit trail.

Q: Which tool should I pick if my team wants to embed agents into CI/CD (continuous integration and continuous delivery)? OpenHands is the strongest candidate. Its SDK exposes a typed agent server that you can call from CI jobs, and its event-sourced state means every action is logged and replayable. You can enforce per-pipeline security policies and store events in your existing observability stack. Aider is simpler to script but was not built for multi-tenant server-side operation.

Test yourself

Your team is maintaining a large Python monolith with 200,000 lines of code spread across 80 packages. You want to use an open-source agent to perform a refactoring that touches the data access layer, which is imported by nearly every package. The agent must run inside your existing CI pipeline, leave a clean audit trail, and never have permission to push to the main branch directly. Which tool would you use, and what would you configure to meet these requirements?

Answer: I would wrap OpenHands in the CI pipeline. OpenHands’ event-sourced state provides the audit trail, because every tool invocation and security decision is a logged event that I can ship to the pipeline’s log store. I would configure a Docker-based workspace that mirrors the monolith’s build environment, same Python version, same package dependencies, read-only access to the data layer’s source files while allowing writes only to a feature branch checked out inside the container. The security analyzer would be set to block all git push commands to the remote named origin, allowing only local commits. The agent would run via the agent-server API (application programming interface), triggered on pull request creation, and its output events would be parsed to decide whether to promote the branch. I would not use Aider here because it commits to the working tree and expects the developer to handle push policies manually. Cline requires an interactive editor for approvals, which does not fit a headless pipeline.

If you want this kind of breakdown every week, how real systems actually work under the hood, subscribe to Internals Decoded at internalsdecoded.com. Next episode we close the series by looking at what happens when you wire all of these tools together into a single development workflow, and where the seams still tear.

Sources

#aider#openhands#open-source-agents
More from the library
The Newsletter

Keep up with AI. One email a week.

One thoughtful email each week. Unsubscribe whenever you like.