Skip to main content

clawd-code-python-port

Python port of Claude Code agent harness — tools, commands, task orchestration, and CLI entrypoint via oh-my-codex

Quellinformationen

Repository
reason-machines/trending-skills
Letzte Quellaktivität
31. März 2026 um 14:37
Erkannte Sprache von SKILL.md
Englisch
Sterne
84
Forks
15

Installationsoptionen

Standardmäßig ist der Prompt ausgewählt, der zuerst die Quelle prüft. Sie können zu einem direkten Befehl wechseln oder eine lokale Kopie herunterladen.

Quelldateien prüfen

Lesen Sie SKILL.md und alle von SkillsMP angezeigten Begleitdateien, bevor Sie sich für eine Installation entscheiden.

SKILL.md wird angezeigt

SKILL.md
Quellanweisungen · Schreibgeschützte Vorschau
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.**
Auf GitHub ansehen