Contributor Guide: Where to Change What in cheetahclaws
June 16, 2026 · View on GitHub
This guide is for contributors implementing new features or updating existing behavior. It focuses on which files matter, how data flows, and how to make safe changes quickly.
1) Fast mental model
If you remember only one thing, remember this flow:
cheetahclaws/cli.pyhandles CLI + REPL + slash commands.context.pyrebuilds the system prompt each turn.agent.pyruns the core loop (stream model output, execute tools, append tool results, continue).providers.pyadapts model APIs (Anthropic vs OpenAI-compatible providers).tool_registry.pyis the single source of truth for all callable tools.- Feature packages (
memory/,multi_agent/,skill/,mcp/,plugin/,task/,checkpoint/,voice/) plug into that loop.
2) Core files you should read first
Runtime + UX shell
cheetahclaws/cli.py- Entry point (
main()), REPL loop (repl()), command dispatch (COMMANDS,handle_slash()), permission prompt UI, diff rendering, voice command handling. - Add or change slash commands here.
- Entry point (
Agent execution loop
agent.pyrun(...)generator is the heart of the app.- Event model:
TextChunk,ThinkingChunk,ToolStart,ToolEnd,PermissionRequest,TurnDone. - Permission gate logic (
_check_permission) and per-turn context compaction trigger.
Tool system
-
tool_registry.pyToolDef,register_tool,get_tool_schemas, and centralizedexecute_tooldispatch/truncation.- Every tool (built-in, package, MCP, plugin) ends up here.
-
tools.py- Core built-in tool schemas and implementations (
Read,Write,Edit,Bash,Glob,Grep,WebFetch,WebSearch,NotebookEdit,GetDiagnostics,AskUserQuestion). _register_builtins()registers core tools, then imports package tool modules to auto-register additional tools.
- Core built-in tool schemas and implementations (
Model providers + prompt context + compaction
providers.py— provider detection, model metadata, API key lookup, stream adapters, neutral message format conversion. Includes thenimprovider (build.nvidia.com free tier, OpenAI-compat) with its 429-cascade helpernim_next_model()used by the agent loop to swap to the next model in the curated chain on rate-limit, capped at 3 swaps/turn.context.py— system prompt assembly entry point (build_system_prompt); injects env block + memory + tmux/plan fragments around the base prompt.prompts/— system prompt assets as plain Markdown.base/default.mdis the shared baseline for every model;overlays/<family>.md(claude / gemini / openai-reasoning / qwen) appends short, vendor-documented quirks;fragments/{tmux,plan}.mdare conditional blocks.select.py::pick_base_promptassembles base + matched overlay. Seeprompts/README.mdfor the overlay-admission policy.compaction.py— context window management (snip_old_tool_results+compact_messages).config.py— defaults + persistent config file handling.
3) Feature packages: exact entrypoints
Memory (memory/)
- Start at
memory/tools.py(tool behavior and schemas). - Persistence/index rules are in
memory/store.py. - Memory retrieval/ranking context is in
memory/context.py. - Metadata scanning and freshness helpers are in
memory/scan.py.
Use this package when adding memory types, changing indexing, staleness behavior, or search behavior.
Multi-agent (multi_agent/)
multi_agent/tools.pyregistersAgent,SendMessage,CheckAgentResult,ListAgentTasks,ListAgentTypes.multi_agent/subagent.pymanages thread pool lifecycle, isolation (git worktree), depth control, and messaging.
Use this package for new agent types, changes to worktree behavior, depth/concurrency limits, or background task lifecycle.
Skills (skill/)
skill/loader.pyparses markdown frontmatter and resolves project/user/builtin precedence.skill/executor.pyruns inline vs forked skill execution.skill/tools.pyexposesSkillandSkillListtool APIs.
Use this package when adding skill metadata fields, argument substitution behavior, or skill execution modes.
MCP (mcp/)
mcp/config.pyloads/merges project.mcp.jsonand user config.mcp/client.pyhandles stdio/SSE/HTTP transport and JSON-RPC.mcp/tools.pyconnects servers and registers discovered tools asmcp__<server>__<tool>.
Use this package for transport support, tool discovery behavior, reconnect logic, or MCP config precedence changes.
Plugins (plugin/)
plugin/store.pyinstall/uninstall/enable/disable/update and config persistence.plugin/loader.pydynamic import and registration of plugin tools/skills/MCP config.plugin/recommend.pyrecommendation logic.
Use this package for plugin manifest semantics, install lifecycle, or recommendation strategy updates.
Tasks (task/)
task/types.pytask model + status enum.task/store.pythread-safe CRUD and dependency edge maintenance.task/tools.pyTaskCreate/Update/Get/Listschemas + formatting.
Use this package for status transitions, dependency graph behavior, metadata semantics, and storage format updates.
Checkpoints (checkpoint/)
checkpoint/types.pyFileBackup+Snapshotdata models.checkpoint/store.pyfile-level backup, snapshot persistence, rewind, cleanup.checkpoint/hooks.pyWrite/Edit/NotebookEdit interception (backup before modify).- REPL command wiring lives in
cheetahclaws/cli.py(cmd_checkpoint,cmd_rewind).
Use this package for snapshot policies, backup strategies, file restore behavior, or storage format updates.
Brainstorm (commands/advanced.py:cmd_brainstorm)
- Multi-persona moderated debate. Run as
/brainstorm [flags] <topic>or via/ssj→ 1. - Three flags, all optional, all compose:
--rounds N— number of debate rounds, clamp[1, 6], default 2. Round 1 is initial positions; round 2+ is adversarial cross-examination (each persona MUST quote another agent's claim and attack it with a falsifiable counter).--lead <model>— lead-moderator model (opening + probes + synthesis). Default = current session model.--models a,b,c— persona models, distributed round-robin. Default = current session model for every persona. Multi-model brings real epistemic diversity (Claude + GPT + DeepSeek covers different blind spots).
- Pipeline (in-process, no main-agent invocation):
_lead_opening(sets agenda + bans filler) → for each round: persona speaks →_lead_probe(round 1 = vague-vs-concrete; round 2+ = dodge detector) → optional persona follow-up if probed →_lead_synthesis(structured master plan with Consensus / Dissents / Concrete Action Plan / What Was Filler sections). - Returns sentinel
("__brainstorm__", todo_payload, out_file_abs)wheretodo_payloadinlines the master plan so the main agent only writes the TODO file (no Read needed — eliminates the duplicate-Read pattern weak models fell into). - Test files:
tests/test_brainstorm_lead.py(helpers + flag parsing + round-aware probe),tests/test_brainstorm_models_flag.py(--models parser). - User-facing guide:
docs/guides/brainstorm.md.
Voice (voice/)
voice/recorder.pycapture backends (sounddevice,arecord,sox) + silence detection.voice/stt.pybackend fallback chain (faster-whisper,openai-whisper, OpenAI API).voice/keyterms.pykeyterm extraction from repo/branch/files.- REPL command wiring lives in
cheetahclaws/cli.py(cmd_voice).
Use this package for STT backend changes, audio capture behavior, and prompt-boosting vocabulary logic.
Agent OS kernel (kernel/)
kernel/api.py—Kernel.open(...)facade: SQLite-backed substores for capability, ledger, scheduler, mailbox, registry, AgentFS, events.kernel/contract.py— frozen v1.0 RPC method registry (CI drift guard).kernel/runner/supervisor.py— subprocess agent spawn + JSON-line IPC + streaming chunk relay.kernel/runner/llm/— LLM agent runner (Anthropic + scripted-mock providers, multi-turn dialogue, tool-calling loop, token streaming).kernel/tools/— tool registry + dispatch; auto-registered (Echo, Read, Write, Glob, List, Diff, AST) and opt-in (Exec, Fetch, Git).kernel/cli.py—cheetahclaws kernel <action>subcommand (read-only inspection over the daemon RPC).- Activated only when daemon runs with
--enable-kernel. Default REPL/bridges path is byte-for-byte unchanged.
Use this package for agent isolation, capability/quota policy, scheduler tuning, AgentFS storage, sandbox primitives, or new built-in tools. Every behavioural change MUST land with an RFC under docs/RFC/ (acceptance criteria + BC story); see docs/agent-os.md for the index of all 27 shipped RFCs.
4) “I need to implement X” → where to edit
Add a new built-in tool
- Add schema + implementation in
tools.py. - Register in
_register_builtins()as aToolDef. - Decide
read_onlyandconcurrent_safecorrectly. - If it mutates files/system, ensure permission behavior is correct in
agent.py/tools.execute_toolwrapper. - Add tests in
tests/test_tool_registry.pyand/or feature-specific tests.
Add a new kernel tool (under --enable-kernel)
- Write a one-page RFC under
docs/RFC/00NN-<name>-tool.md(problem, args, capability/fs/net checks, output shape, BC story, acceptance criteria). - Add
kernel/tools/<name>_tool.pywith a<NAME>_TOOLToolinstance (fields:name,description,handler,requires_capability,requires_fs). - Auto-register (zero-side-effect inspectors only) by adding to
kernel/tools/builtin.py::register_builtin_toolsAND to its return list. Otherwise exposeregister_<name>_tool(registry)and document it as opt-in. - Re-export from
kernel/tools/__init__.py__all__. - Append the RFC number to
kernel/contract.py::RFCS_IMPLEMENTED. - Add tests under
tests/test_kernel_<name>_tool.pycovering args validation, capability/fs gates, success path, and the acceptance criteria from the RFC. - If the tool emits incremental output, route it through
ctx.on_chunk(payload)soSupervisor.wait(on_chunk=...)callers see it (RFC 0028 substrate).
Add a new slash command
- Add
cmd_<name>function incheetahclaws/cli.py. - Add command mapping in
COMMANDS. - If command needs tool behavior, prefer a tool module and call that logic.
- Add tests in relevant test module (or create a focused one).
Add a new model provider or provider behavior
- Update
providers.py(PROVIDERS, auto-detection prefixes, stream adapter behavior). - Add/verify key lookup path in
get_api_key. - Confirm message conversion in
messages_to_openai/messages_to_anthropicif provider-specific quirks exist. - Update docs and provider list references.
Change prompt/context injection
- Wording changes for ALL models: edit
prompts/base/default.md(≤ 150 lines). - Family-specific quirk (must be vendor-documented): add or edit
prompts/overlays/<family>.md(≤ 20 lines, top-of-file<!-- Source: -->URL required), then update_OVERLAY_RULESinprompts/select.pyand add a case totests/test_prompt_selection.py::test_overlay_routing. - Conditional block (only injected under runtime conditions like tmux/plan-mode): add or edit
prompts/fragments/<name>.mdand append it fromcontext.build_system_prompt. - Env / memory / git assembly: modify
context.pyhelpers (_render_env_block,_render_plan_fragment,get_git_info,get_claude_md). - If memory behavior changes, update
memory/context.pyandmemory/store.pyas needed. - Validate prompt size impact via
compaction.pybehavior; regenerate the golden fixture ifdefault.mdchanged:python tests/e2e_prompt_regression.py --regenerate.
Change compaction behavior
- Edit thresholds/splitting in
compaction.py. - Ensure both cheap-snipping and model-summarization layers still compose safely.
- Add or update tests in
tests/test_compaction.py.
Add a new feature package
- Create package module(s) with clear API +
ToolDefregistrations. - Ensure package is imported from
tools.pyso registrations execute at startup. - Add slash command wiring in
cheetahclaws/cli.pyonly if user-facing command is needed. - Add focused tests under
tests/test_<feature>.py.
5) Tests: what to run and where to add coverage
Current tests are organized by subsystem:
tests/test_tool_registry.pytests/test_compaction.pytests/test_memory.pytests/test_subagent.pytests/test_skills.pytests/test_mcp.pytests/test_plugin.pytests/test_task.pytests/test_voice.pytests/test_diff_view.py
Recommended contributor workflow:
- Run only impacted test module(s) first.
- Then run the full suite before opening a PR.
- If adding a new capability, add at least one success-path and one failure/edge test.
6) Important conventions and gotchas
- Registry-first architecture: if functionality should be callable by the model, it should be a registered tool.
- Import side effects matter: package tool modules are often imported for registration side effects.
- Permission model is split:
agent.pydoes high-level checks;tools.execute_toolincludes backward-compatible gating too. - Context pressure is real: large tool outputs are truncated in
tool_registry.execute_tool, then old results may be snipped/compacted. - Neutral message format is the internal contract: provider adapters must preserve tool call IDs and arguments correctly.
- Task and memory persistence are cwd/home dependent: behavior can vary if tests or runtime change working directory.
- Path naming note: most runtime dirs use
.cheetahclaws(underscore).
7) Suggested order for onboarding contributors
If you are new and want to ship your first feature quickly, read in this order:
README.md(user surface)cheetahclaws/cli.py(runtime shell)agent.py(core loop)tool_registry.py+tools.py(extension spine)- Your target package (
memory/,mcp/,task/, etc.) - Matching
tests/test_*.py
This sequence minimizes time-to-productivity and reduces accidental architecture drift.
8) PR checklist (practical)
- Feature is implemented in the correct layer (tool vs slash command vs provider vs package).
- Tool schema and implementation are both updated where needed.
- Permission behavior is intentional and safe.
- Tests updated/added for changed behavior.
- README/docs updated if user-facing behavior changed.
- No unrelated refactors mixed into the same PR.