Appearance
ADW Modules Reference
adw_modules/ Directory
The engine powering all ADW pipelines. Each module has a single responsibility.
adw_modules/
├── agent.py — Claude Code CLI subprocess interface
├── agent_sdk.py — Claude Code SDK (async, interactive, typed)
├── github.py — GitHub REST API wrapper
├── git_ops.py — Branch, commit, PR operations
├── state.py — ADWState machine (persistent JSON)
├── workflow_ops.py — Core business logic orchestration
├── data_types.py — Pydantic models (typed contracts)
├── data_models.py — ToDone task system models
└── utils.py — Shared helpersagent.py vs agent_sdk.py
Two ways to call Claude Code. Choose based on your needs:
agent.py (subprocess) | agent_sdk.py (SDK) | |
|---|---|---|
| Execution | subprocess + CLI | claude_code_sdk.query() |
| Error handling | Generic exceptions | SDK-typed exceptions |
| Interactive sessions | No | Yes (ClaudeSDKClient) |
| Session resume | No | Yes (options.resume) |
| Cost tracking | No | result.total_cost_usd |
| Async | No | Native async/await |
Use agent.py for standard ADW pipelines. Use agent_sdk.py when you need multi-turn conversations, session resumption, or cost tracking.
State Management
ADWState in state.py is the data contract between pipeline phases:
python
@dataclass
class ADWState:
adw_id: str
issue_number: int
branch_name: str
plan_file: str
issue_class: str # '/chore' | '/bug' | '/feature'
phase: str # 'plan' | 'build' | 'test' | 'review' | 'document'
status: str # 'running' | 'complete' | 'failed'Reading state in a custom script:
python
from adw_modules.state import ADWState
import json
with open(f'agents/{adw_id}/adw_state.json') as f:
state = ADWState(**json.load(f))Piping state between phases:
bash
# adw_plan.py writes state to stdout as JSON
# adw_build.py reads state from stdin
uv run adw_plan.py 123 | uv run adw_build.pyOutput File Structure
Every phase writes to agents/{adw_id}/{agent_name}/:
| File | Contents |
|---|---|
cc_raw_output.jsonl | Raw streaming output (one JSON per line) |
cc_raw_output.json | All messages as a parsed JSON array |
cc_final_object.json | Last entry — the final result object |
custom_summary_output.json | High-level summary with ADW ID, model, success, session ID |
Data Types
Key Pydantic models from data_types.py:
python
class IssueClassification(BaseModel):
issue_type: Literal['/chore', '/bug', '/feature']
reasoning: str
class SpecResult(BaseModel):
plan_file: str
summary: str
estimated_effort: str # 'small' | 'medium' | 'large'
class BuildResult(BaseModel):
commit_hash: str
files_changed: list[str]
summary: str
class TestResult(BaseModel):
passed: bool
output: str
failures: list[str]Workflow Operations
workflow_ops.py orchestrates the high-level sequence:
- classify — calls
/classify_issueslash command - plan — calls
/feature,/bug, or/chorebased on classification - build — calls
/implementwith the spec file path - test — calls
/testand/test_e2e - review — calls
/reviewwith spec + screenshots - document — calls
/documentwith review artifacts
Each operation wraps the slash command with proper context: spec path, issue data, working directory.
Model Selection
Default model is sonnet. Override in agent.py or via primitive ADW flags:
python
# adw_modules/agent.py — line ~129
model = "sonnet" # Change to "opus" for complex tasksbash
# Primitive ADWs accept --model flag
uv run adws/adw_sdk_prompt.py "task description" --model opus
uv run adws/adw_slash_command.py /implement specs/plan.md --model opus