CLAUDE.md
CLAUDE.mdCLAUDE.mdroot
Quality
97/100
Scores the file, not the repository.Length
1,167 words
22 headings · 5 code blocksRepository
8.0k
— · pushed 15 days agoLast changed
3 days ago
First indexed 3 days ago.1# CLAUDE.md23This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.45## Mandatory Reference67Read `AGENTS.md` before any code change. It is the authoritative engineering protocol covering architecture, naming conventions, anti-patterns, change playbooks, and validation requirements.89## Build & Test Commands1011```bash12# Requires exactly Zig 0.16.0 (verify: zig version)13zig build # dev build14zig build -Doptimize=ReleaseSmall # release build (target: <1 MB binary)15zig build test --summary all # run all 5,300+ tests (must pass with 0 leaks)16zig fmt src/ # format all source files17zig fmt --check src/ # check formatting (used by pre-commit hook)18```1920Primary validation command is `zig build test --summary all` (project-wide). Individual files can still be run with `zig test <file>.zig` when needed.2122### Build Flags2324```bash25zig build -Dchannels=telegram,cli # compile only specific channels (default: all)26zig build -Dengines=base,sqlite # compile only specific memory engines (default: base,sqlite)27zig build -Dtarget=x86_64-linux-musl # cross-compile for target triple28zig build -Dversion=2026.3.1 # override CalVer version string29```3031Channel tokens: `all`, `none`, or comma-separated names (`cli`, `telegram`, `discord`, `slack`, `signal`, `matrix`, `web`, `nostr`, `irc`, `email`, `imessage`, `whatsapp`, `mattermost`, `lark`, `dingtalk`, `line`, `onebot`, `qq`, `maixcam`).3233Engine tokens: `base`/`minimal` (enables `none`, `markdown`, `memory`, `api`), `sqlite`, `lucid`, `redis`, `lancedb`, `postgres`, `all`.3435## Git Hooks3637Activate once per clone:3839```bash40git config core.hooksPath .githooks41```4243- **pre-commit**: blocks if `zig fmt --check src/` fails44- **pre-push**: blocks if `zig build test --summary all` fails4546## Project Overview4748NullClaw is an autonomous AI assistant runtime written in Zig 0.16.0. Hard constraints: 678 KB binary, ~1 MB peak RSS, <2 ms startup. Every dependency and abstraction has a measurable size/memory cost. Only two external dependencies: vendored SQLite (with build-time SHA256 hash verification) and `websocket.zig` (pinned commit).4950## Architecture5152The entire codebase is **vtable-driven**. All major subsystems use `ptr: *anyopaque` + `vtable: *const VTable` for pluggable implementations. Extending NullClaw means implementing a vtable struct and registering it in the subsystem's factory (see `AGENTS.md` section 7 for playbooks).5354**Critical ownership rule**: callers must OWN the implementing struct (local var or heap-alloc). Never return a vtable interface pointing to a temporary -- the pointer will dangle.5556### Module Initialization Order5758Defined in `src/root.zig`. Phases mirror deployment dependencies:59601. **Core**: `bus`, `config`, `util`, `platform`, `version`, `state`, `json_util`, `http_util`612. **Agent**: `agent`, `session`, `providers`, `memory`623. **Networking**: `gateway`, `channels`634. **Extensions**: `security`, `cron`, `health`, `tools`, `identity`, `cost`, `observability`, `heartbeat`, `runtime`, `mcp`, `subagent`, `auth`, `multimodal`, `agent_routing`645. **Hardware/Integrations**: `hardware`, `peripherals`, `rag`, `skillforge`, `tunnel`, `voice`6566### Key Entry Points6768- `src/main.zig` - CLI command routing (`agent`, `gateway`, `onboard`, `doctor`, `status`, `service`, `cron`, `channel`, `memory`, `skills`, `hardware`, `migrate`, `workspace`, `capabilities`, `models`, `auth`, `update`, `history`)69- `src/root.zig` - Module hierarchy and public API exports (also serves as library root)70- `src/config.zig` - JSON config loading (~30 sub-config structs from `config_types.zig`, loads from `~/.nullclaw/config.json`)71- `src/agent.zig` - Agent orchestration (delegates to `src/agent/root.zig`)72- `src/gateway.zig` - HTTP gateway server (rate limiting, pairing, webhooks)73- `src/daemon.zig` - Supervisor with exponential backoff for gateway mode7475### Subsystem Directories7677- `src/providers/` - AI model providers. 9 core implementations + 41+ OpenAI-compatible services via `compatible.zig`. Factory in `factory.zig`, single source of truth for provider URLs and auth styles.78- `src/channels/` - Messaging channels. Each implements `Channel.VTable` (`start`, `stop`, `send`, `name`, `healthCheck`). Factory in `root.zig`.79- `src/tools/` - Tool implementations. Each implements `Tool.VTable` (`execute`, `name`, `description`, `parameters_json`). Tools receive args as `JsonObjectMap` and return `ToolResult`. Factory in `root.zig`.80- `src/memory/` - Layered architecture: **engines** (SQLite, Markdown, LRU, Redis, PostgreSQL, LanceDB, Lucid, ClickHouse, API, None) and **retrieval** (hybrid search, RRF, embeddings). Engines conditionally compiled via build flags.81- `src/security/` - Policy enforcement (`policy.zig`), pairing (`pairing.zig`), encrypted secrets (`secrets.zig`), sandbox backends (`landlock.zig`, `firejail.zig`, `bubblewrap.zig`, `docker.zig`, `detect.zig`).82- `src/agent/` - Agent loop internals: `dispatcher.zig` (tool call parsing), `compaction.zig` (history trimming), `prompt.zig` (system prompt builder), `memory_loader.zig` (context injection), `commands.zig` (agent-mode commands). Config defaults are `max_tool_iterations = 1000` and `max_history_messages = 100` (see `src/config_types.zig`).8384### Provider Boundary Notes8586- Keep canonical tool names in the runtime and prompt layer. Provider-specific quirks should be normalized at the provider boundary when possible.87- `src/providers/ollama.zig` already normalizes common local-model tool-name drift such as `tool.shell` -> `shell`, `tools.file_read` -> `file_read`, and `scheduler_tool` / `schedule_tool` -> `schedule`.88- If a local model invents another wrapper-style tool name, prefer extending the Ollama normalization helper and adding a regression test instead of teaching alternate names to the tool registry or prompt text.8990### Dependency Direction9192Concrete implementations depend inward on vtable interfaces, config, and util. Never import across subsystems (e.g., provider code must not import channel internals).9394## Config System9596Config loads from `~/.nullclaw/config.json`. Runtime behavior is then adjusted by `NULLCLAW_*` environment overrides (see `Config.applyEnvOverrides()` in `src/config.zig`). Types are defined in `src/config_types.zig` and re-exported from `src/config.zig`.9798`Config.load()` heap-allocates an internal `ArenaAllocator`. Always call `defer cfg.deinit()` to free. In tests, wrap in a parent arena:99100```zig101var arena = std.heap.ArenaAllocator.init(std.testing.allocator);102defer arena.deinit();103var cfg = try Config.load(arena.allocator());104defer cfg.deinit();105```106107Key config sections: `models.providers` (API keys/endpoints), `agents` (named agent configs), `channels` (per-channel settings), `memory` (backend/search/lifecycle), `gateway` (port/host/pairing), `security` (sandbox/audit/autonomy), `autonomy` (level/limits/allowlists), `runtime` (native/docker/wasm).108109## Zig 0.16.0 API Gotchas110111- `std.io.getStdOut()` does NOT exist. Use `std.fs.File.stdout()`.112- HTTP client: `std.http.Client.fetch()` with `std.Io.Writer.Allocating`.113- Child processes: `std.process.Child.init(argv, allocator)`, `.Pipe` (capitalized).114- `ArrayListUnmanaged`: init with `.empty`, pass allocator to every method.115- `ChaCha20Poly1305.decrypt`: use stack buffer then `allocator.dupe()` (heap buffer segfaults on macOS).116- `SQLITE_TRANSIENT` in auto-translated C code: use `SQLITE_STATIC` (null) instead.117- When unsure about API, search `src/` for existing usage rather than guessing.118119## Search Zig Source120121Run `zig env` to locate Zig source directories. `.std_dir` points to the standard library, `.lib_dir` to the broader lib tree. Read the source directly to verify struct fields, function signatures, and available methods.122123## Testing Conventions124125- All tests use `std.testing.allocator` (leak-detecting GPA). Every allocation must be freed with `defer`.126- Use `builtin.is_test` guards to skip side effects (spawning processes, opening browsers, real hardware I/O). Return mock data instead (e.g., `return "test-refreshed-token"`).127- Tests must be deterministic and reproducible across macOS and Linux.128- Vendored SQLite hashes are validated at build time.129- Use `std.testing.tmpDir(.{})` with `defer tmp.cleanup()` for file-based test fixtures.130- Contract tests in `src/memory/engines/contract_test.zig` verify all memory backends satisfy the same vtable invariants. Follow this pattern when adding new backends.131- Test helpers (e.g., `TestHelper` structs with `dummyConfig()` / `initTestChannel()`) are defined within each module. Prefer this pattern over shared test utilities.132- Test naming: `subject_expected_behavior` (e.g., `"sendUrl constructs correct URL"`).133134## Versioning135136CalVer format: `YYYY.M.D` (e.g., `v2026.2.26`). Defined in `build.zig.zon`.137138## CI139140Tests run on Ubuntu (x86_64), macOS (aarch64), and Windows (x86_64). Release builds target 7 platforms including linux-riscv64. Docker images published to ghcr.io (linux/amd64, linux/arm64).141142## Docker143144Multi-stage build: Alpine builder with Zig, then minimal Alpine runtime. Runs as non-root (uid 65534) by default. Use `--target release-root` for root access.145146```bash147docker-compose --profile gateway up # HTTP gateway daemon148docker-compose --profile agent up # interactive agent149```150151## Nix152153`flake.nix` provides a dev shell with Zig and ZLS. Activate with `direnv allow` (uses `.envrc`).154155## License156157MIT License.158
Also in nullclaw/nullclaw
Diff this repo’s formatsOne repository carrying more than one format is the comparison this product exists for: does anyone actually write different content in each file, or is one a copy of the other?
| Repository | Format | Stack | Covers | Score | Changed |
|---|---|---|---|---|---|
| nullclaw/nullclawAGENTS.md · 8.0k | AGENTS.md | teststyletesting-strategygit+5 | 89/100 | 3 days ago | |
| nullclaw/nullclawsrc/workspace_templates/AGENTS.md · 8.0k | AGENTS.md | styleperformancemonorepo | 50/100 | 3 days ago |
Similar configs
Same format, overlapping stack, ranked by quality.
| Repository | Format | Stack | Covers | Score | Changed |
|---|---|---|---|---|---|
| bagisto/bagistoCLAUDE.md · 28k | CLAUDE.md | setupbuildteststyle+5 | 100/100 | 3 days ago | |
| filamentphp/filamentCLAUDE.md · 32k | CLAUDE.md | buildtestlint-formatstyle+7 | 100/100 | 3 days ago | |
| Adit-Jain-srm/NightmareNetCLAUDE.md · 45 | CLAUDE.md | buildtestlint-formatstyle+6 | 100/100 | 3 days ago | |
| microsoft/playwrightCLAUDE.md · 94k | CLAUDE.md | buildtestlint-formatstyle+7 | 100/100 | 3 days ago | |
| nimbalyst/nimbalystpackages/android/CLAUDE.md · 1.4k | CLAUDE.md | setupbuildstylearch+2 | 100/100 | 3 days ago | |
| stacklok/toolhiveCLAUDE.md · 2.0k | CLAUDE.md | buildteststylearch+4 | 100/100 | 3 days ago | |
| dotCMS/corecore-web/CLAUDE.md · 950 | CLAUDE.md | teststylearchtesting-strategy+3 | 100/100 | 3 days ago | |
| livewire/livewireCLAUDE.md · 24k | CLAUDE.md | setupbuildteststyle+4 | 100/100 | 3 days ago |
