YeonGyu-Kim bb76ec9730 ROADMAP #123: --allowedTools tool-name normalization asymmetric; snake_case canonicals accept variants, PascalCase canonicals reject snake_case; whitespace+comma split undocumented; allowed_tools not surfaced in JSON
Dogfooded 2026-04-18 on main HEAD 2bf2a11 from /tmp/cdZZ.

Asymmetric normalization:
  normalize_tool_name(value) = trim + lowercase + replace -→_

  Canonical 'read_file' (snake_case):
    accepts: read_file, READ_FILE, Read-File, read-file,
             Read (alias), read (alias)
    rejects: ReadFile, readfile, READFILE
    → Because normalize('ReadFile')='readfile', and name_map
      has key 'read_file' not 'readfile'.

  Canonical 'WebFetch' (PascalCase):
    accepts: WebFetch, webfetch, WEBFETCH
    rejects: web_fetch, web-fetch, Web-Fetch
    → Because normalize('WebFetch')='webfetch' (no underscore).
      User input 'web_fetch' normalizes to 'web_fetch' (keeps
      underscore). Keys don't match.

The normalize function ADDS underscores (hyphen→underscore) but
DOESN'T REMOVE them. So PascalCase canonicals have underscore-
free normalized keys; user input with explicit underscores keeps
them, creating key mismatch.

Result: 'bash,Bash,BASH,Read,read_file,Read-File,WebFetch' all
accepted, but 'web_fetch,web-fetch' rejected.

Additional silent-flag issues:
- Splits on commas OR whitespace (undocumented — help says
  TOOL[,TOOL...])
- 'bash,Bash,BASH' silently accepts all 3 case variants, no
  dedup warning
- Allowed tools NOT in status/doctor JSON — claw passing
  --allowedTools has no way to verify what runtime accepted

Trace:
  tools/src/lib.rs:192-244 normalize_allowed_tools:
    canonical_names from mvp_tool_specs + plugin_tools + runtime
    name_map: (normalize_tool_name(canonical), canonical)
    for token in value.split(|c| c==',' || c.is_whitespace()):
      lookup normalize_tool_name(token) in name_map

  tools/src/lib.rs:370-372 normalize_tool_name:
    fn normalize_tool_name(value: &str) -> String {
        value.trim().replace('-', '_').to_ascii_lowercase()
    }
    Replaces - with _. Lowercases. Does NOT remove _.

  Asymmetry source: normalize('WebFetch')='webfetch',
  normalize('web_fetch')='web_fetch'. Different keys.

  --allowedTools NOT plumbed into Status JSON output
  (no 'allowed_tools' field).

Fix shape (~50 lines):
- Symmetric normalization: strip underscores from both canonical
  and input, OR don't normalize hyphens in input either.
  Pick one convention.
- claw tools list / --allowedTools help subcommand that prints
  canonical names + accepted variants.
- Surface allowed_tools in status/doctor JSON when flag set.
- Document comma+whitespace split semantics in --help.
- Warn on duplicate tokens (bash,Bash,BASH = 3 tokens, 1 unique).
- Regression per normalization pair + status surface + duplicate.

Joins Silent-flag/documented-but-unenforced (#96-#101, #104,
#108, #111, #115, #116, #117, #118, #119, #121, #122) as 16th.

Joins Permission-audit/tool-allow-list (#94, #97, #101, #106,
#115, #120) as 7th.

Joins Truth-audit — status/doctor JSON hides what allowed-tools
set actually is.

Joins Parallel-entry-point asymmetry (#91, #101, #104, #105,
#108, #114, #117, #122) as 9th — --allowedTools vs
.claw.json permissions.allow likely disagree on normalization.

Natural bundles:
  #97 + #123 — --allowedTools trust-gap pair:
    empty silently blocks (#97) +
    asymmetric normalization + invisible runtime state (#123)

  Permission-audit 7-way (grown):
    #94 + #97 + #101 + #106 + #115 + #120 + #123

  Flagship permission-audit sweep 8-way (grown):
    #50 + #87 + #91 + #94 + #97 + #101 + #115 + #123

Filed in response to Clawhip pinpoint nudge 1494993419536306176
in #clawcode-building-in-public.
2026-04-18 18:38:24 +09:00
2026-04-07 15:52:30 +09:00

Claw Code

ultraworkers/claw-code · Usage · Rust workspace · Parity · Roadmap · UltraWorkers Discord

Star history for ultraworkers/claw-code

Claw Code

Claw Code is the public Rust implementation of the claw CLI agent harness. The canonical implementation lives in rust/, and the current source of truth for this repository is ultraworkers/claw-code.

Important

Start with USAGE.md for build, auth, CLI, session, and parity-harness workflows. Make claw doctor your first health check after building, use rust/README.md for crate-level details, read PARITY.md for the current Rust-port checkpoint, and see docs/container.md for the container-first workflow.

ACP / Zed status: claw-code does not ship an ACP/Zed daemon entrypoint yet. Run claw acp (or claw --acp) for the current status instead of guessing from source layout; claw acp serve is currently a discoverability alias only, and real ACP support remains tracked separately in ROADMAP.md.

Current repository shape

  • rust/ — canonical Rust workspace and the claw CLI binary
  • USAGE.md — task-oriented usage guide for the current product surface
  • PARITY.md — Rust-port parity status and migration notes
  • ROADMAP.md — active roadmap and cleanup backlog
  • PHILOSOPHY.md — project intent and system-design framing
  • src/ + tests/ — companion Python/reference workspace and audit helpers; not the primary runtime surface

Quick start

Note

[!WARNING] cargo install claw-code installs the wrong thing. The claw-code crate on crates.io is a deprecated stub that places claw-code-deprecated.exe — not claw. Running it only prints "claw-code has been renamed to agent-code". Do not use cargo install claw-code. Either build from source (this repo) or install the upstream binary:

cargo install agent-code   # upstream binary — installs 'agent.exe' (Windows) / 'agent' (Unix), NOT 'agent-code'

This repo (ultraworkers/claw-code) is build-from-source only — follow the steps below.

# 1. Clone and build
git clone https://github.com/ultraworkers/claw-code
cd claw-code/rust
cargo build --workspace

# 2. Set your API key (Anthropic API key — not a Claude subscription)
export ANTHROPIC_API_KEY="sk-ant-..."

# 3. Verify everything is wired correctly
./target/debug/claw doctor

# 4. Run a prompt
./target/debug/claw prompt "say hello"

Note

Windows (PowerShell): the binary is claw.exe, not claw. Use .\target\debug\claw.exe or run cargo run -- prompt "say hello" to skip the path lookup.

Windows setup

PowerShell is a supported Windows path. Use whichever shell works for you. The common onboarding issues on Windows are:

  1. Install Rust first — download from https://rustup.rs/ and run the installer. Close and reopen your terminal when it finishes.
  2. Verify Rust is on PATH:
    cargo --version
    
    If this fails, reopen your terminal or run the PATH setup from the Rust installer output, then retry.
  3. Clone and build (works in PowerShell, Git Bash, or WSL):
    git clone https://github.com/ultraworkers/claw-code
    cd claw-code/rust
    cargo build --workspace
    
  4. Run (PowerShell — note .exe and backslash):
    $env:ANTHROPIC_API_KEY = "sk-ant-..."
    .\target\debug\claw.exe prompt "say hello"
    

Git Bash / WSL are optional alternatives, not requirements. If you prefer bash-style paths (/c/Users/you/... instead of C:\Users\you\...), Git Bash (ships with Git for Windows) works well. In Git Bash, the MINGW64 prompt is expected and normal — not a broken install.

Note

Auth: claw requires an API key (ANTHROPIC_API_KEY, OPENAI_API_KEY, etc.) — Claude subscription login is not a supported auth path.

Run the workspace test suite:

cd rust
cargo test --workspace

Documentation map

Ecosystem

Claw Code is built in the open alongside the broader UltraWorkers toolchain:

Ownership / affiliation disclaimer

  • This repository does not claim ownership of the original Claude Code source material.
  • This repository is not affiliated with, endorsed by, or maintained by Anthropic.
Description
The repo is finally unlocked. enjoy the party! The fastest repo in history to surpass 100K stars . Join Discord: https://discord.gg/5TUQKqFWd Built in Rust using oh-my-codex.
Readme 38 MiB
Languages
Rust 96.4%
Python 3.2%
Shell 0.4%