Python port of Claude Code agent harness — tools, commands, task orchestration, and CLI entrypoint via oh-my-codex
---
name: clawd-code-python-port
description: Python port of Claude Code agent harness — tools, commands, task orchestration, and CLI entrypoint via oh-my-codex
triggers:
- how do I run clawd-code
- how do I use the Python port of Claude Code
- clawd-code CLI commands
- how do I add a tool to clawd-code
- how does the agent harness work in clawd-code
- how do I extend clawd-code with new commands
- how do I run the parity audit in clawd-code
- how do I verify the Python workspace in clawd-code
---
# clawd-code Python Port
> Skill by [ara.so](https://ara.so) — Daily 2026 Skills collection.
## What This Project Does
**clawd-code** is an independent Python rewrite of the Claude Code agent harness, built from scratch for educational purposes. It captures the architectural patterns of Claude Code — tool wiring, command dispatch, task orchestration, and agent runtime context — in clean Python, without copying any proprietary TypeScript source.
The project is orchestrated end-to-end using [oh-my-codex (OmX)](https://github.com/Yeachan-Heo/oh-my-codex), a workflow layer on top of OpenAI Codex. It is **not affiliated with or endorsed by Anthropic**.
---
## Installation
```bash
# Clone the repository
git clone https://github.com/instructkr/clawd-code.git
cd clawd-code
# (Optional but recommended) Create a virtual environment
python3 -m venv .venv
source .venv/bin/activate
# Install dependencies (if a requirements.txt or pyproject.toml is present)
pip install -r requirements.txt
# or
pip install -e .
```
No API keys are needed for the manifest/summary/CLI commands. If you extend the query engine to call a live model, set your key via environment variable:
```bash
export ANTHROPIC_API_KEY="your-key-here"
export OPENAI_API_KEY="your-key-here"
```
---
## Repository Layout
```
.
├── src/
│ ├── __init__.py
│ ├── commands.py # Command port metadata
│ ├── main.py # CLI entrypoint
│ ├── models.py # Dataclasses: subsystems, modules, backlog
│ ├── port_manifest.py # Python workspace structure summary
│ ├── query_engine.py # Renders porting summary from active workspace
│ ├── task.py # Task orchestration primitives
│ └── tools.py # Tool port metadata
├── tests/ # unittest-based verification
└── assets/
```
---
## Key CLI Commands
All commands run via `python3 -m src.main <subcommand>`.
```bash
# Print a human-readable porting summary
python3 -m src.main summary
# Print the current Python workspace manifest
python3 -m src.main manifest
# List current Python modules/subsystems (paginated)
python3 -m src.main subsystems --limit 16
# Inspect mirrored command inventory
python3 -m src.main commands --limit 10
# Inspect mirrored tool inventory
python3 -m src.main tools --limit 10
# Run parity audit against local ignored archive (when present)
python3 -m src.main parity-audit
# Run the full test suite
python3 -m unittest discover -s tests -v
```
---
## Core Data Models (`src/models.py`)
The dataclasses define the shape of the porting workspace:
```python
from dataclasses import dataclass, field
from typing import List, Optional
@dataclass
class Module:
name: str
status: str # e.g. "ported", "stub", "backlog"
source_path: str
notes: Optional[str] = None
@dataclass
class Subsystem:
name: str
modules: List[Module] = field(default_factory=list)
description: Optional[str] = None
@dataclass
class PortManifest:
subsystems: List[Subsystem] = field(default_factory=list)
backlog: List[str] = field(default_factory=list)
version: str = "0.1.0"
```
---
## Tools System (`src/tools.py`)
Tools are the callable units in the agent harness. Each tool entry carries metadata for dispatch:
```python
from dataclasses import dataclass
from typing import Callable, Optional, Any, Dict
@dataclass
class Tool:
name: str
description: str
parameters: Dict[str, Any] # JSON-schema style param spec
handler: Optional[Callable] = None # Python callable for this tool
# Example: registering a tool
def read_file_handler(path: str) -> str:
with open(path, "r") as f:
return f.read()
READ_FILE_TOOL = Tool(
name="read_file",
description="Read the contents of a file at the given path.",
parameters={
"path": {"type": "string", "description": "Absolute or relative file path"}
},
handler=read_file_handler,
)
# Tool registry pattern
TOOL_REGISTRY: Dict[str, Tool] = {
READ_FILE_TOOL.name: READ_FILE_TOOL,
}
def dispatch_tool(name: str, **kwargs) -> Any:
tool = TOOL_REGISTRY.get(name)
if tool is None:
raise ValueError(f"Unknown tool: {name}")
if tool.handler is None:
raise NotImplementedError(f"Tool '{name}' has no handler yet.")
return tool.handler(**kwargs)
```
---
## Commands System (`src/commands.py`)
Commands are higher-level agent actions, distinct from raw tools:
```python
from dataclasses import dataclass
from typing import Optional, Callable, Any
@dataclass
class Command:
name: str
description: str
aliases: list
handler: Optional[Callable] = None
# Example command
def summarize_handler(context: dict) -> str:
return f"Summarizing {len(context.get('files', []))} files."
SUMMARIZE_COMMAND = Command(
name="summarize",
description="Summarize the current workspace context.",
aliases=["sum", "overview"],
handler=summarize_handler,
)
COMMAND_REGISTRY = {
SUMMARIZE_COMMAND.name: SUMMARIZE_COMMAND,
}
def run_command(name: str, context: dict) -> Any:
cmd = COMMAND_REGISTRY.get(name)
if not cmd:
raise ValueError(f"Unknown command: {name}")
if not cmd.handler:
raise NotImplementedError(f"Command '{name}' not yet implemented.")
return cmd.handler(context)
```
---
## Task Orchestration (`src/task.py`)
Tasks wrap a unit of agent work — a goal, a set of tools, and a result:
```python
from dataclasses import dataclass, field
from typing import List, Optional, Any
@dataclass
class TaskResult:
success: bool
output: Any
error: Optional[str] = None
@dataclass
class Task:
goal: str
tools: List[str] = field(default_factory=list) # tool names available
context: dict = field(default_factory=dict)
result: Optional[TaskResult] = None
def run(self, dispatcher) -> TaskResult:
"""
dispatcher: callable(tool_name, **kwargs) -> Any
Implement your agent loop here.
"""
try:
# Minimal stub: just report goal received
output = f"Task received: {self.goal}"
self.result = TaskResult(success=True, output=output)
except Exception as e:
self.result = TaskResult(success=False, output=None, error=str(e))
return self.result
# Usage
from src.tools import dispatch_tool
task = Task(
goal="Read README.md and summarize it",
tools=["read_file"],
context={"working_dir": "."},
)
result = task.run(dispatcher=dispatch_tool)
print(result.output)
```
---
## Query Engine (`src/query_engine.py`)
The query engine renders a porting summary from the active manifest:
```python
from src.port_manifest import build_manifest
from src.query_engine import render_summary
manifest = build_manifest()
summary = render_summary(manifest)
print(summary)
```
You can also invoke it from the CLI:
```bash
python3 -m src.main summary
```
---
## Port Manifest (`src/port_manifest.py`)
Build and inspect the current workspace manifest programmatically:
```python
from src.port_manifest import build_manifest
manifest = build_manifest()
for subsystem in manifest.subsystems:
print(f"[{subsystem.name}]")
for module in subsystem.modules:
print(f" {module.name}: {module.status}")
print("Backlog:", manifest.backlog)
```
---
## Adding a New Tool
1. Define a handler function in `src/tools.py`.
2. Create a `Tool` dataclass instance.
3. Register it in `TOOL_REGISTRY`.
4. Write a test in `tests/`.
```python
# src/tools.py
def list_dir_handler(path: str):
import os
return os.listdir(path)
LIST_DIR_TOOL = Tool(
name="list_dir",
description="List files in a directory.",
parameters={"path": {"type": "string"}},
handler=list_dir_handler,
)
TOOL_REGISTRY["list_dir"] = LIST_DIR_TOOL
```
---
## Adding a New Command
```python
# src/commands.py
def lint_handler(context: dict) -> str:
files = context.get("files", [])
return f"Linting {len(files)} files (stub)."
LINT_COMMAND = Command(
name="lint",
description="Lint the current workspace files.",
aliases=["check"],
handler=lint_handler,
)
COMMAND_REGISTRY["lint"] = LINT_COMMAND
```
---
## Running Tests
```bash
# Run all tests with verbose output
python3 -m unittest discover -s tests -v
# Run a specific test file
python3 -m unittest tests.test_tools -v
```
Example test pattern:
```python
# tests/test_tools.py
import unittest
from src.tools import dispatch_tool
import tempfile, os
class TestReadFileTool(unittest.TestCase):
def test_read_file(self):
with tempfile.NamedTemporaryFile(mode="w", suffix=".txt", delete=False) as f:
f.write("hello clawd")
path = f.name
try:
result = dispatch_tool("read_file", path=path)
self.assertEqual(result, "hello clawd")
finally:
os.unlink(path)
if __name__ == "__main__":
unittest.main()
```
---
## Parity Audit
When a local ignored archive of the original snapshot is present, run:
```bash
python3 -m src.main parity-audit
```
This compares the current Python workspace surface against the archived root-entry file surface, subsystem names, and command/tool inventories, reporting gaps.
---
## Common Patterns
### Chaining tools in a task loop
```python
from src.tools import dispatch_tool
from src.task import Task
task = Task(
goal="Read and list files",
tools=["read_file", "list_dir"],
context={"working_dir": "."},
)
# Manual tool chain (before full agent loop is implemented)
files = dispatch_tool("list_dir", path=".")
for fname in files[:3]:
content = dispatch_tool("read_file", path=fname)
print(f"--- {fname} ---\n{content[:200]}")
```
### Using the manifest in automation
```python
from src.port_manifest import build_manifest
def unported_modules():
manifest = build_manifest()
stubs = []
for sub in manifest.subsystems:
for mod in sub.modules:
if mod.status != "ported":
stubs.append((sub.name, mod.name, mod.status))
return stubs
for subsystem, module, status in unported_modules():
print(f"{subsystem}/{module} → {status}")
```
---
## Troubleshooting
| Symptom | Fix |
|---|---|
| `ModuleNotFoundError: src` | Run commands from the repo root, not inside `src/` |
| `NotImplementedError: Tool 'x' has no handler` | The tool is registered but the Python handler hasn't been written yet — implement `handler` in `tools.py` |
| `parity-audit` does nothing | The local ignored archive must be present at the expected path; see `port_manifest.py` for the expected location |
| Tests not discovered | Ensure test files are named `test_*.py` and located in `tests/` |
| Import errors after adding a module | Add `__init__.py` to any new package subdirectory |
---
## Key Links
- **Repository:** https://github.com/instructkr/clawd-code
- **oh-my-codex (OmX):** https://github.com/Yeachan-Heo/oh-my-codex
- **Related essay:** [Is legal the same as legitimate?](https://writings.hongminhee.org/2026/03/legal-vs-legitimate/)
- **Not affiliated with Anthropic.**
Creator's repository · aradotso/trending-skills