Skip to content

Backend request: CheetahClaws (SafeRL-Lab/nano-claude-code, Apache-2.0) as a runner backend #229

Description

@master5d

Problem

CheetahClaws (SafeRL-Lab/nano-claude-code, Apache-2.0, PyPI cheetahclaws 3.5.87) is a Python clean-room reimplementation of the Claude Code agent loop with a multi-provider model layer (any OpenAI-compatible endpoint via custom/<model>), Markdown skills, MCP in the .mcp.json shape, and session autosave. We run it as one of eight sandboxed kernels in our lab and it is our chosen foundation for the harness layer, but it cannot be a HarnessRouter backend today: the backend list is fixed (codex, claude, hermes, dsh, opencode, aider, kimi, openhands, qwen, cline, pi, gemini, omp, goose, systemone) and a custom harness is a configuration over a built-in backend. So none of the five verification scenarios, nor the custom-harness dimension, can be measured for it.

Proposal

Add cheetahclaws as a runner backend, the way pi was added as one registry entry (runner/server.py, "registry-driven"). What the CLI offers, measured on our instance (podman box, model through an OpenAI-compatible gateway):

  • headless turn: cheetahclaws --accept-all -p --model custom/<model> "<prompt>" (stdin closed; --accept-all = no permission prompts; -p prints the final answer to stdout, tool cards go to stderr with ANSI);
  • model/provider: CUSTOM_BASE_URL (or custom_base_url in ~/.cheetahclaws/config.json) + CUSTOM_API_KEY; provider prefix custom/ maps to any OpenAI Chat Completions endpoint; no Responses-API path needed;
  • skills: ~/.cheetahclaws/skills/<name>/SKILL.md (also skill.md; project-level .cheetahclaws/skills/ takes priority) — --- frontmatter name/description in the Claude Code shape loads unchanged; the agent exposes SkillList and Skill tools;
  • MCP: ~/.cheetahclaws/mcp.json or <cwd>/.mcp.json in the Claude Code mcpServers format (stdio/SSE/HTTP); tools appear as mcp__<server>__<tool>;
  • instructions: AGENTS.md/CLAUDE.md in the workspace are read;
  • session record: ~/.cheetahclaws/sessions/mr_sessions/session_latest.json — {"_version", "session_id", "saved_at", "messages", "turn_count", …}, messages in the OpenAI shape with tool calls as {"id", "name", "input": {...}} and tool results by tool_call_id; this is enough for the turn record (assistant text, tool calls, produced files come from the workspace);
  • workspace hygiene: the CLI writes its task tracker to <cwd>/.cheetahclaws/tasks.json — a driver should relocate or ignore it (we exclude it from the produced-files diff).

Limitations to design around: no JSON event stream on stdout (unlike pi -p --mode json), so live events would come from parsing the session file after the turn or from stderr tool cards; the process exits 0 even when the model endpoint is unreachable (the error is printed), so the driver has to read the session/outcome rather than the exit code; on long sessions the model may finish the turn with a tool call printed as text, which the CLI accepts as the final answer.

Compatibility

Additive: one backend entry plus a driver; no protocol change. The .harness/ skills relocation rule from docs/harness-verification.md maps to .cheetahclaws/skills (project-level, highest priority).

Alternatives

  • Keep measuring it outside HarnessRouter (what we do now) — loses the five-scenario comparability with the other backends.
  • Run it behind a custom Responses server as systemone does — heavier than a driver and hides the harness identity.

We can provide a driver PR following the "Adding a harness" checklist if the entry is welcome; opening the issue first per CONTRIBUTING.

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions