> ## Content Index
> Fetch the complete content index at: https://wuu73.org/aiguide-ghost/llms.txt
> Use this file to discover other available public pages before exploring further.

# Dirac — Accurate & Highly Token Efficient
- URL: https://wuu73.org/aiguide-ghost/coding-agents-dirac/
- Published: 2026-05-29T00:27:00.000Z
- Updated: 2026-05-29T00:27:00.000Z
- Description: Part of Agent Harness Field Guide.
- Author: WUU73
- Tags: Deep Dives, Agent Harness Field Guide, #Deep Dive Child, #Import 2026-09-12 06:38

Hash-Anchored • AST-Native • No MCP • 64.8% cheaper

Dirac is a TypeScript coding agent that reduces API costs by **64.8%** while achieving better accuracy — using hash-anchored parallel edits, AST manipulation, and a suite of context curation optimizations. Explicitly no MCP. Built on a fork of Cline.

Shameless Plug[While we're deep-diving into complex CLI tools... let's be honest. Are you tired of pretending you enjoy memorizing 400 arcane tmux key combos? Do you lie awake at night dreading the moment you have to edit a cryptic dotfile just to change a font size? Same. It's the AI age, we shouldn't be computing like it's 1995.**ButtonsCLI**: The terminal for](https://buttonscli.com/?ref=wuu73.org)

(Alright, ad over. Back to the serious technical analysis.)

## What makes Dirac different

Most coding agents treat file editing as a text manipulation problem: find line N, replace with new content. This breaks the moment the file shifts — even a single inserted line deranges every downstream line number. Dirac takes a different approach: it anchors edits to **stable line hashes**, uses **AST-aware tools** for structural code operations, and batches multiple file operations into a **single LLM roundtrip**. The result is an agent that is measurably more accurate on complex multi-file refactoring tasks and significantly cheaper to run.

The eval results are striking. On 8 real-world refactoring tasks against transformers, vscode, and django repos, Dirac achieved **8/8 correct** at an average cost of **$0.18** — versus the competition's $0.38–$0.73 range. That is a **2.8x cost reduction** with better outcomes.

📊

#### TerminalBench 2.0 Results

Dirac scored **65.2%** on TerminalBench 2.0, beating Google's coding agent at 47.6% and Junie CLI at 64.3%. The eval tests complex, real-world refactoring tasks against public GitHub repos.

## Hash-Anchored File Editing

The core innovation in Dirac is its hash-anchored editing system. When Dirac reads a file, it computes a deterministic hash for each line. Edits are then specified as `anchor + end_anchor + replacement text` rather than `start_line + end_line + text`. This means:

- Edits survive file shifts — inserting 50 lines anywhere doesn't invalidate existing anchors
- Multiple disjoint edits can be applied in a single batch with no coordinate conflicts
- Anchor validation catches drift before the edit is applied, giving clear diagnostics

The `EditExecutor` in `src/core/task/tools/handlers/edit-file/EditExecutor.ts` resolves anchors by checking that the anchor name starts with a capital letter, exists in the file's line hash list, and that the provided content line matches the actual file content at that hash. If any check fails, the edit fails with a diagnostic explaining exactly what went wrong.

The batch processor (`BatchProcessor.ts`) applies multiple edits in reverse line order — highest line index first — so that earlier edits don't shift the coordinates of later ones.

📌

#### Key files

`src/core/task/tools/handlers/edit-file/EditExecutor.ts` (anchor resolution, content matching), `src/core/task/tools/handlers/edit-file/BatchProcessor.ts` (reverse-order batch application), `src/core/task/tools/handlers/edit-file/types.ts` (AppliedEdit, FailedEdit, ResolvedEdit types), `src/utils/line-hashing.ts` (splitAnchor, stripHashes, getDelimiter)

## AST-Native Precision

Beyond hash-anchored text edits, Dirac has **AST-aware tools** that target specific symbols — classes, functions, interfaces — directly rather than by text position. This means:

- Edits are always syntactically valid — you can't break a brace balance via AST manipulation
- JSDoc comments, decorators, and type annotations are preserved automatically
- Function extraction and class refactoring work reliably across language boundaries

This is the structural equivalent of the hash-anchored system: both prevent the "friction" of coordinate-based editing. Where line numbers drift when the file changes, and raw text matching drifts when the surrounding code changes, AST targeting drifts only when the target symbol itself changes.

## Token Efficiency Architecture

Dirac's token efficiency is not an accident — it is a deliberate engineering target backed by multiple mechanisms:

| Mechanism                             | How it works                                          | Effect                                          |
| ------------------------------------- | ----------------------------------------------------- | ----------------------------------------------- |
| **Hash-anchored multi-file batching** | Multiple files edited in single LLM roundtrip         | One roundtrip instead of N sequential requests  |
| **get\_file\_skeleton**               | Maps project structure without reading every line     | "Just-in-time" code loading keeps context tight |
| **ContextManager truncation**         | Half-strategy and quarter-strategy for long context   | Always relevant context in window               |
| **Concurrent tool calling**           | Parallel tool execution in single turn                | Reduces turn count for complex tasks            |
| **Minimal system prompt**             | PRIME DIRECTIVES focus on efficiency, not boilerplate | Fewer tokens per turn                           |

The ContextManager (`src/core/context/context-management/ContextManager.ts`) manages truncation with two strategies: **half truncation** (remove the middle 50% of conversation) and **quarter truncation** (remove the middle 25%). The choice depends on context length and model limits.

## State Mutex — Thread-Safe Concurrent State

Dirac uses a **state mutex** (implemented via the `p-mutex` package) to serialize all state modifications in the main Task loop. This is critical because the concurrent tool calling system can produce multiple tool results simultaneously — without a mutex, two tool completions could corrupt state simultaneously.

```
// From src/core/task/index.ts (line ~140)
private stateMutex = new Mutex()

private async withStateLock<T>(fn: () => T | Promise<T>): Promise<T> {
  return await this.stateMutex.withLock(fn)
}
```

Every state modification — tool results, message updates, task history writes — goes through `withStateLock`. This prevents race conditions between the concurrent tool executor and the main task loop without sacrificing the performance benefit of parallel tool calls.

## Hook System

Dirac has an extensive **hook system** with 8 event types that scripts can intercept:

| Hook           | When it fires                    | Purpose                                          |
| -------------- | -------------------------------- | ------------------------------------------------ |
| onTaskStart    | Before agent starts a task       | Setup, environment validation                    |
| onTaskComplete | After task finishes successfully | Cleanup, notification, artifact publishing       |
| onTaskCancel   | When task is cancelled           | Graceful shutdown, partial result handling       |
| onTaskResume   | When a paused task resumes       | State reconstruction                             |
| preToolUse     | Before any tool executes         | Validation, blocking, input modification         |
| postToolUse    | After any tool completes         | Logging, result inspection, side effects         |
| preCompact     | Before context compaction        | Protect sensitive content from truncation        |
| preRequest     | Before sending LLM request       | System prompt modification, context augmentation |

Hooks are discovered via auto-discovery in `.claude/`, `.agents/`, or explicitly configured in `AGENTS.md`. The hook executor (`src/core/hooks/hook-executor.ts`) runs hooks with structured JSON via stdin and supports cancellation via AbortController. Hooks can return a `cancel` decision, a `contextModification` to alter behavior, or an `errorMessage`.

📌

#### Key files

`src/core/hooks/hook-executor.ts` (executeHook, streaming callback, cancellation), `src/core/hooks/hook-factory.ts` (HookFactory, hasHook, getHookInfo), `src/core/hooks/HookManager.ts` (active hook execution tracking), `src/core/hooks/PreToolUseHookCancellationError.ts`

## Git Checkpoint System

Dirac includes a **git checkpoint system** that creates commits before risky operations, enabling revert if something goes wrong. This is built into the Task lifecycle and managed by `CheckpointManager`.

The checkpoint manager is initialized per workspace (not supported in multi-root workspaces yet). If a checkpoint operation fails, a warning is displayed but doesn't block task execution. The system uses `buildCheckpointManager` from `src/integrations/checkpoints/factory.ts`.

## Plan/Act Mode Separation

Dirac separates **Plan mode** and **Act mode** as first-class execution modes. In Plan mode, Dirac gathers information, asks clarifying questions, and presents a strategy before asking for user approval to switch to Act mode. This mirrors Claude Code's approach but with Dirac's own implementation.

The `PlanModeRespondHandler` handles plan-mode responses, producing a structured plan that users can approve or modify before any code is written.

## YOLO Mode

**YOLO mode** (`dirac -y "prompt"`) runs fully autonomously with auto-approval of all actions. This is useful for simple, well-understood tasks where the overhead of per-action approval isn't worth it. YOLO mode forces plain text output and exits automatically on task completion.

When YOLO mode is enabled, the `DiracIgnoreController` also sets `yoloMode = true`, which may affect how certain tools behave.

## Command Permissions — DIRAC\_COMMAND\_PERMISSIONS

Shell command validation in Dirac is configured via the `DIRAC_COMMAND_PERMISSIONS` environment variable — a JSON object that defines allow/deny glob patterns for shell commands. This is more flexible than a simple ban list: you can allow `npm *` and `git *` while denying `rm -rf *` and `sudo *`.

The validation flow: check for dangerous characters → parse into segments (splitting on `&&`, `||`, `|`, `;`) → check deny rules first → check allow rules → verify redirects if applicable. Subshell contents (`$(...)` and `(...)`) are recursively validated.

```
# Allow only npm and git commands
export DIRAC_COMMAND_PERMISSIONS='{"allow": ["npm *", "git *"]}'

# Allow dev commands but deny dangerous ones
export DIRAC_COMMAND_PERMISSIONS='{"allow": ["npm *", "git *", "node *"], "deny": ["rm -rf *", "sudo *"]}'
```

## Subagent System

Dirac has a **SubagentToolHandler** (`src/core/task/tools/handlers/SubagentToolHandler.ts`) that spawns isolated child agents with their own configuration. Subagents can be configured with specific tool scopes, model selections, and execution parameters.

The `SubagentRunner` and `SubagentBuilder` handle the lifecycle. The `AgentConfigLoader` loads agent configurations. Subagent results are streamed back to the parent, which can then synthesize or act on the child's output.

## Skills System — Auto-Discovery

Dirac's skills system uses **auto-discovery** from three locations: `AGENTS.md`, `.claude/`, and `.agents/` directories. Skills are injected into the system prompt at runtime.

The `getOrDiscoverSkills` function in `src/core/context/instructions/user-instructions/skills.ts` handles discovery and loading. Skills can be enabled or disabled via the `refreshDiracRulesToggles` and `refreshExternalRulesToggles` functions, allowing users to toggle rules at runtime without restarting.

## Exponential Backoff Retry

Dirac's retry system uses **exponential backoff** with 2s, 4s, and 8s delays between attempts. When an API request fails, the retry logic in `src/core/api/retry.ts` automatically schedules re-attempts with increasing delays to avoid hammering rate-limited endpoints.

The retry system also handles streaming failures — if the stream breaks mid-response, Dirac can recover and resume without losing the full conversation context.

## Provider Support — 40+ APIs

Dirac is explicitly not tied to one model family. It ships with a large provider catalog in `src/core/api/providers/` covering 40+ APIs including Anthropic, OpenAI, Google (Gemini), AWS Bedrock, Azure, and many OpenAI-compatible gateways. Each provider is a separate handler file following the `ApiHandler` interface.

The `src/core/api/index.ts` contains `createHandlerForProvider` which instantiates the correct handler from configuration. Model metadata — IDs, pricing, capability flags like `supportsTools` and `supportsThinking` — is centralized in `src/shared/api.ts`.

📌

#### Key files

`src/core/api/index.ts` (createHandlerForProvider), `src/shared/api.ts` (model metadata, pricing, capability flags), `src/core/api/providers/` (individual provider implementations), `src/core/api/transform/` (stream normalization across providers)

## No MCP — Explicit Design Decision

Unlike virtually every other agent in this directory set, Dirac does **not** implement MCP support. This is an explicit design decision, not an oversight. The team chose to focus on its own tool surface rather than maintaining a protocol bridge.

This puts Dirac in a unique position: it is the most accurate on structural code manipulation tasks among the TypeScript-based agents, but it cannot connect to external MCP servers. For users who need MCP integration, this is a significant gap. For users who want a tightly integrated, self-contained agent, this is a feature.

## Architecture Overview

Extension entry point → webview → controller → task. The core modules:

- `src/core/task/` — Task execution loop and state management
- `src/core/task/tools/` — Tool implementations and handlers
- `src/core/prompts/` — System and tool prompt templates
- `src/core/controller/` — High-level extension coordination
- `src/core/context/` — Context gathering and management
- `src/core/slash-commands/` — Slash command definitions
- `src/integrations/` — Terminal, browser, editor API wrappers
- `src/services/` — Logging, telemetry, tree-sitter services
- `webview-ui/` — React-based frontend
- `cli/` — TypeScript/Ink CLI

Dirac is a fork of **Cline**, and the architecture reflects that lineage. The core task loop, tool system, and context management are all built on Cline's foundation, with Dirac's innovations layered on top.

## CLI Quick Reference

| Command                     | Description                     |
| --------------------------- | ------------------------------- |
| dirac "prompt"              | Run a task interactively        |
| dirac -p "prompt"           | Run in Plan mode                |
| dirac -y "prompt"           | Run in YOLO mode (auto-approve) |
| dirac -T taskId "follow-up" | Resume an existing task         |
| dirac --continue            | Resume most recent task         |
| dirac history               | List task history               |
| dirac auth                  | Authenticate with a provider    |
| git diff \| dirac "Review"  | Pipe context directly to Dirac  |

## How Dirac compares

### Most accurate on structural edits

Hash-anchored editing and AST-native precision make Dirac the most reliable agent for complex multi-file refactoring. On eval tasks, Dirac achieves 8/8 correct while competitors fail 1-3 tasks. 

Best for refactoring

### Cheapest to run

At $0.18 average cost per task vs $0.38–$0.73 for competitors, Dirac is 2.8x cheaper. For teams running hundreds of tasks daily, this compounds significantly. 

Best for cost-conscious teams

### No MCP integration

The tradeoff for tight integration is the absence of MCP support. If you need to connect to external MCP servers, Dirac is not the right choice. 

Gap vs other agents

### Fork of Cline

Dirac builds on Cline's architecture, inheriting its strong tool surface and VS Code extension foundation. The innovations (hash anchors, AST, batching) are layered on top. 

Cline-based

## Key files

| File                                                     | Role                                                                        |
| -------------------------------------------------------- | --------------------------------------------------------------------------- |
| src/core/task/index.ts                                   | Main Task class (1,868 lines) — agent loop, state mutex, tool orchestration |
| src/core/task/tools/handlers/edit-file/EditExecutor.ts   | Hash-anchor resolution and edit application                                 |
| src/core/task/tools/handlers/edit-file/BatchProcessor.ts | Reverse-order batch edit processor                                          |
| src/core/context/context-management/ContextManager.ts    | Context truncation with half/quarter strategies                             |
| src/core/hooks/hook-executor.ts                          | Hook execution with streaming and cancellation                              |
| src/core/prompts/system-prompt/template.ts               | System prompt with PRIME DIRECTIVES                                         |
| src/core/api/providers/                                  | 40+ provider implementations                                                |
| src/core/api/retry.ts                                    | Exponential backoff retry (2s, 4s, 8s)                                      |
| cli/man/dirac.1.md                                       | Full CLI reference (man page)                                               |
| walkthrough/step1-4.md                                   | Feature showcases (AST precision, minimal roundtrips, hash anchors, speed)  |