Claude Code and the New Wave of Terminal AI Coding Tools
At 2:13 a.m., I watched a terminal coding agent spend 1.8 million input tokens trying to “just fix the failing test.” The actual bug was a three-line schema mismatch. The agent was not dumb; it was poorly constrained. It kept rereading the repository, re-running broad test commands, pasting giant stack traces back into the model, and asking for full-file rewrites when a surgical diff would have done.
That incident changed how I run CLI coding agents.
Tools like Claude Code, Aider, Cline, and OpenCode are not just chatbots with a git diff button. They are API-driven control loops wrapped around your shell, editor, filesystem, and sometimes browser. They can be extremely productive, especially with strong models like Claude Opus 4.8, Sonnet 4.6, GPT-5.5, Gemini 3, and long-context systems like Fable 5. They can also quietly burn tokens at a rate that surprises teams used to single-turn API calls.
This article is the practical version: what terminal coding agents actually do, how they use model APIs, why agentic loops change token economics, and how I configure them so a long session stays useful instead of expensive theater.
What CLI Coding Agents Actually Are
A terminal coding agent is usually five things glued together:
- A chat loop with a frontier or open model
- A repository indexer or file discovery layer
- A tool execution layer for shell commands and file edits
- A patch application mechanism
- A persistence layer for conversation history and session state
The critical difference from autocomplete is agency. Autocomplete predicts code at the cursor. An agent can decide to inspect files, run tests, modify code, inspect failures, and iterate.
A typical loop looks like this:
User task
↓
Agent builds prompt from instructions + repo context + prior messages
↓
Model proposes actions: read file, edit file, run command
↓
CLI executes allowed actions
↓
Results are added back into context
↓
Model plans next step
↓
Repeat until done or stopped
That loop is why these tools feel powerful. It is also why cost and latency behave differently from normal “ask one question, get one answer” API usage.
In practice, most cost surprises come from the feedback path: command outputs, file contents, previous messages, and diffs being repeatedly included in later turns.
Claude Code, Aider, Cline, and OpenCode: Different Shapes of the Same Pattern
The tools have different interaction styles, but the core engineering pattern is similar.
| Tool | Primary Surface | Typical Strength | Common Cost Risk |
|---|---|---|---|
| Claude Code | Terminal-native agent | Tight shell/repo workflow, strong planning/edit loop | Long autonomous sessions accumulating context |
| Aider | Git-aware CLI pair programmer | Diff-focused editing, explicit file targeting | Adding too many files to context |
| Cline | Editor-centric agent | VS Code integration, visible tool use | Large terminal/browser outputs entering context |
| OpenCode | Terminal/editor agent workflow | Model flexibility and local workflow control | Misconfigured providers or broad repo scans |
The important distinction is not “which one is smartest.” It is how much context the tool sends, how it selects files, how it summarizes history, and how much control you have over shell execution.
Aider, for example, tends to work well when you intentionally add the relevant files. Claude Code is more agentic and can feel like a senior engineer moving around the repo, but that autonomy means you should be deliberate about permissions and scope. Cline is convenient inside the editor, especially when you want to watch actions, but editor convenience can make it easy to approve too many expensive steps.
OpenCode-style workflows appeal to teams that want provider flexibility: Claude for hard architecture work, GPT for implementation, Gemini for large context inspection, or open models like Qwen, DeepSeek, Kimi, MiniMax, and Llama for cheaper local or self-hosted passes.
How These Agents Use the API
A single “fix this bug” request may become dozens of API calls.
A simplified request body for an agent step looks like this:
{
"model": "claude-sonnet-4.6",
"messages": [
{
"role": "system",
"content": "You are a coding agent. Follow repo instructions. Use tools safely."
},
{
"role": "user",
"content": "Fix the failing invoice total test."
},
{
"role": "assistant",
"content": "I will inspect the test and related invoice code."
},
{
"role": "tool",
"name": "read_file",
"content": "tests/test_invoice_totals.py contents..."
}
],
"tools": [
{ "name": "read_file" },
{ "name": "apply_patch" },
{ "name": "run_shell" }
]
}
Real implementations vary, but the pattern is consistent:
- The CLI gathers context.
- The model decides the next operation.
- The CLI performs the operation.
- The result is fed back to the model.
- The model continues.
There are usually two ways tools are exposed.
Text-Based Tool Protocols
Some agents ask the model to emit structured text:
RUN: pytest tests/test_invoice_totals.py -q
The CLI parses that and executes it. This is simple and portable, but brittle. If the model formats the command oddly, the harness needs guardrails.
Native Function Calling
Other agents use model API tool/function calling. The model returns a structured tool invocation:
{
"tool_name": "run_shell",
"arguments": {
"command": "pytest tests/test_invoice_totals.py -q",
"timeout_seconds": 60
}
}
This is easier to validate. The agent can reject commands matching dangerous patterns, require approval for network access, or restrict writes to the workspace.
In both designs, the expensive part is not the shell command. It is the growing prompt around the shell command.
Why Agentic Loops Change Token Economics
A normal API integration might send 2,000 input tokens and receive 500 output tokens. An agentic coding session may do this:
| Step | What Happens | Input Token Pattern | Output Token Pattern |
|---|---|---|---|
| 1 | User asks for fix | Small | Plan |
| 2 | Agent reads files | Medium | Tool request |
| 3 | Agent edits code | Medium-large | Patch |
| 4 | Test fails | Large if full logs included | Diagnosis |
| 5 | Agent reads more files | Larger due to history | Tool request |
| 6 | Agent retries | Larger again | Patch |
| 7 | Full test run fails elsewhere | Very large if pasted raw | Summary/triage |
The gotcha: input tokens often dominate. Every loop may resend system instructions, conversation history, selected files, tool outputs, and summaries. Even with caching or context compression, long autonomous sessions can become expensive because the model needs enough state to avoid acting blindly.
There are four common token multipliers:
- Full-file context: sending 900-line files when only two functions matter.
- Verbose test output: including dependency warnings, progress bars, and unrelated failures.
- Repeated repository scans: running
find,tree, orrgbroadly and reinjecting the output. - Unbounded conversation history: preserving every failed attempt instead of summarizing decisions.
What actually happens in a messy session is not “the agent thinks harder.” It often just sees more stale context. More tokens can make the model slower and less precise if the relevant signal is buried.
The Mental Model: Budget Per Loop, Not Per Prompt
When I estimate spend, I think in loops.
A small targeted task might be:
8 turns × 12k input tokens average = 96k input tokens
8 turns × 1.5k output tokens average = 12k output tokens
A wandering task might be:
35 turns × 55k input tokens average = 1.9M input tokens
35 turns × 3k output tokens average = 105k output tokens
Same user prompt. Very different economics.
You do not need exact pricing to see the shape of the problem. Agentic sessions scale with:
total cost ≈ Σ(input_tokens_per_step × input_price)
+ Σ(output_tokens_per_step × output_price)
+ tool/runtime overhead
Output tokens are visible because you watch the agent type. Input tokens are hidden because they are assembled by the CLI. That hidden side is where budget discipline matters.
Choosing Models for Agent Work
I rarely use one model for everything.
For terminal agents, the model choice should match the phase:
| Phase | Best Model Type | Why |
|---|---|---|
| Repo reconnaissance | Long-context or cheaper capable model | Needs broad reading, not perfect edits |
| Architecture decision | Strong reasoning model | Needs trade-off judgment |
| Patch generation | Strong coding model | Needs precise diffs |
| Test failure triage | Fast mid-tier model | Often pattern matching |
| Mechanical refactors | Cheap or open model with guardrails | Repetitive, verifiable work |
A practical setup might use Sonnet-class models for most coding, Opus/GPT-5.5-class models for hard debugging or design, Gemini/Fable-style long-context models for large inspection, and open models for local lint-style refactors. The exact names will change; the pattern holds.
A common mistake is using the most expensive model for the entire loop. The expensive model then spends premium tokens reading node_modules-adjacent noise, test warnings, and generated files. Save the strongest model for decisions that actually need it.
Config Tips That Matter
The best configuration is not “maximum autonomy.” It is “fast feedback with narrow permissions.”
1. Ignore Generated and Vendor Files
Every coding agent should have an ignore list. Start with the same things you exclude from search and review:
node_modules/
dist/
build/
coverage/
.venv/
__pycache__/
target/
vendor/
*.lock
*.min.js
*.map
I usually do not exclude lockfiles globally if the task involves dependency resolution, but I do exclude them from default context. A lockfile can be pulled in explicitly when needed.
2. Use Narrow Test Commands
Do not let the agent default to the whole suite on every iteration. Give it a command ladder:
# First loop: fastest relevant test
pytest tests/billing/test_invoice_totals.py -q
# Second loop: nearby package
pytest tests/billing -q
# Final confidence check
pytest -q
For JavaScript or TypeScript:
pnpm test invoice-total.test.ts -- --runInBand
pnpm lint src/billing
pnpm test
The point is not just runtime. Smaller outputs mean smaller prompts on the next loop.
3. Cap Command Output
If your agent supports output limits, use them. If not, wrap commands yourself:
pytest tests/billing -q 2>&1 | tail -120
Or for noisy builds:
pnpm test 2>&1 | grep -E "FAIL|Error|Expected|Received|at " | head -200
Be careful: filtering can hide useful context. I use this after the first failure, not before. First see the shape of the failure, then constrain repeated runs.
4. Ask for Diffs, Not Rewrites
For large files, tell the agent explicitly:
Make the smallest safe patch. Do not rewrite unrelated functions.
Show a concise diff summary before running tests.
This reduces risk and usually reduces output tokens. More importantly, it keeps code review sane.
5. Separate Planning From Execution
For nontrivial changes, I often start with:
Inspect the relevant files and propose a plan. Do not edit yet.
Limit repo inspection to payment, invoice, and tax modules unless needed.
Then I approve the plan and let it implement. This avoids the “agent edits before understanding” failure mode.
Controlling Spend During Long Sessions
Long sessions are where CLI agents shine and where they get dangerous.
Here is the spend-control checklist I use in real work:
- Set a session goal: “Make
test_invoice_roundingpass,” not “fix billing.” - Pin files when possible: provide exact paths instead of asking the agent to discover everything.
- Reset context after pivots: start a new session with a summary when the task changes.
- Summarize failures manually: paste the important 30 lines, not a 3,000-line log.
- Escalate models deliberately: use a stronger model only after a clear blocker.
- Stop after repeated loops: if the agent fails twice in the same way, intervene.
A good reset prompt looks like this:
We are fixing invoice rounding.
Known facts:
- Failure is in tests/billing/test_invoice_totals.py::test_round_half_even
- Expected 10.24, actual 10.25
- Decimal quantization happens in src/billing/money.py
- Tax calculation calls round_money() from src/billing/tax.py
Continue from this summary. Inspect only those files first.
That prompt can be cheaper and clearer than dragging along an entire failed conversation.
API Keys, Providers, and Routing
Most CLI agents can talk directly to a model provider API, or through a compatible gateway. The key engineering concerns are:
- Authentication: where API keys live and whether they leak into shell history or logs.
- Model routing: which model handles which phase.
- Rate limits: agent loops can burst requests quickly.
- Observability: per-session token and cost reporting.
- Data boundaries: whether code can be sent to external APIs.
A minimal environment setup often looks like this:
export ANTHROPIC_API_KEY="..."
export OPENAI_API_KEY="..."
export GEMINI_API_KEY="..."
For teams, I prefer a wrapper script that selects models and logs usage:
#!/usr/bin/env bash
set -euo pipefail
export AGENT_MODEL="${AGENT_MODEL:-sonnet}"
export AGENT_MAX_OUTPUT_TOKENS="${AGENT_MAX_OUTPUT_TOKENS:-4096}"
export AGENT_SESSION_BUDGET_USD="${AGENT_SESSION_BUDGET_USD:-10}"
coding-agent "$@"
If you use a multi-model gateway, this is where it can be useful to route Claude, GPT, Gemini, or open-model traffic behind one interface. The important feature is not the logo list; it is whether you get reliable usage accounting and model-level controls.
What I Put in Repository Instructions
Most agents respect some form of repo instruction file. I keep mine short and operational:
## Agent Instructions
- Prefer minimal diffs over rewrites.
- Do not run full test suites until targeted tests pass.
- Never edit generated files in `dist/`, `build/`, or `coverage/`.
- Use `rg` for search.
- Before large refactors, propose a plan and wait.
- If a command emits more than 200 lines, rerun with a narrower command.
This is not about politeness. It shapes the loop. The agent will still make mistakes, but good instructions reduce repeated waste.
A common gotcha: overly long instruction files become background noise. If your agent instructions are 300 lines of style philosophy, the model may miss the three operational constraints that matter. Put the high-value rules first.
Latency: The Other Cost
Even when token spend is acceptable, latency can kill flow.
Agent latency comes from:
- Model inference time
- Tool execution time
- File indexing time
- Test runtime
- Human approval pauses
For tight loops, I optimize for “time to next useful observation.” A 15-second targeted test beats a 6-minute full CI simulation. A smaller model that correctly identifies a syntax error in 4 seconds beats a premium model that spends 45 seconds producing a beautiful explanation.
The best sessions feel like pair programming:
inspect → patch → targeted test → inspect failure → patch → targeted test → final suite
The worst sessions feel like CI cosplay:
scan repo → edit many files → run everything → drown in logs → repeat
Limitations and Failure Modes
Terminal agents are useful, not magical.
They struggle when:
- The repository has hidden runtime dependencies not captured in tests.
- The task requires product judgment rather than code transformation.
- The error depends on external services or flaky state.
- The codebase has misleading abstractions or stale documentation.
- The agent cannot run the relevant validation command.
They can also produce plausible but wrong fixes. This is especially common when tests are weak. If the agent cannot verify behavior, treat its output like a junior engineer’s unreviewed patch: potentially useful, never automatically trusted.
Security also matters. Do not give an agent unrestricted shell access in a sensitive repo without understanding the tool’s approval model. “Run commands” includes the ability to print environment variables, modify files, install packages, or hit the network unless restricted.
Practical Takeaways
- Treat CLI coding tools as API-driven control loops, not single prompts.
- Optimize cost by reducing loop count and context size, especially command output.
- Use strong models for hard reasoning, not for every mechanical step.
- Keep repo instructions short, operational, and focused on agent behavior.
- Prefer targeted tests first, broader validation last.
- Reset long sessions with concise summaries instead of carrying stale history.
- Watch input tokens; they are the hidden cost center in agentic coding.
- Stop and intervene when the agent repeats the same failed strategy.
Claude Code, Aider, Cline, and OpenCode are part of a real shift: coding assistance is moving from suggestion engines to terminal-native collaborators. The teams that benefit most will not be the ones that simply “turn on agents.” They will be the ones that engineer the loop: narrow context, safe tools, observable spend, and verification at every step.
One API key for Claude Opus 4.8, Sonnet 4.6, Haiku 4.5, Fable 5, plus GPT & Gemini — up to 80% off official pricing, pay-as-you-go.
Get Your API Key →