Skip to content

Latest commit

 

History

History
147 lines (106 loc) · 8.33 KB

File metadata and controls

147 lines (106 loc) · 8.33 KB

Development Rules

Agent-facing rules for working on Coven Code. Mirrors and extends src-rust/.claude/CLAUDE.md; when the two disagree, the rule closer to the code wins.

Conversational Style

  • Keep answers short and concise
  • No emojis in commits, issues, PR comments, or code
  • No fluff or cheerful filler text
  • Technical prose only, be kind but direct (e.g., "Thanks @user" not "Thanks so much @user!")
  • When the user asks a question, answer it first before making edits or running implementation commands.

Code Quality

  • Read files in full before making wide-ranging changes, before editing files you have not already fully inspected, and when the user asks you to investigate or audit something. Do not rely only on search snippets for broad changes.
  • No .unwrap() / .expect() on fallible operations in production paths — propagate via Result or pattern-match. unwrap is acceptable in tests and in cases where the invariant is statically obvious and commented.
  • Avoid speculative .clone() — borrow first, clone only when ownership is actually needed. Same applies to .to_string() on &str.
  • No unsafe blocks without a // SAFETY: comment explaining the invariant.
  • Single-line helper functions with a single call site are forbidden; inline them instead.
  • Don't guess external API shapes. Read the crate source under ~/.cargo/registry/ or check cargo doc --open. For Anthropic and Codex wire formats, the crates/api/src/providers/<provider>.rs files are the authoritative reference inside this repo.
  • NEVER use type erasure to silence the compiler — no Box<dyn Any>, no serde_json::Value shoved through a typed boundary just because the right type is annoying to derive. If a type is hard to express, ask the user.
  • NEVER remove or downgrade code to fix compiler errors from outdated dependencies; bump the dependency in Cargo.toml or src-rust/Cargo.toml workspace deps instead.
  • Always ask before removing functionality or code that appears to be intentional.
  • Do not preserve backward compatibility unless the user explicitly asks for it.
  • Never hardcode keybinding checks inline (e.g. key == KeyCode::Char('s') && mods.ctrl()). All keybindings must flow through the configurable keybinding system in crates/core/src/keybindings.rs — add a default there.
  • NEVER modify generated files directly. Generated artefacts in this repo:
    • src-rust/Cargo.lock — regenerated by cargo; for version bumps use scripts/bump-version.py.
    • npm/package.json version field — also stamped by bump-version.py.

Commands

Run from src-rust/ unless noted.

  • After Rust changes (not docs): cargo check --workspace — fix every error and warning before committing.
  • Clippy: cargo clippy --workspace --all-targets -- -D warnings. Fix lints; do not #[allow(...)] without justification.
  • Format: cargo fmt --all. Run before committing.
  • Tests: cargo test --workspace for everything, cargo test --package claurst-<crate> for a single crate, cargo test --package claurst-<crate> -- <pattern> for a specific test.
  • Avoid running cargo build --release or cargo run --release unless you specifically need optimised output — debug builds and cargo check are 10× faster.
  • If you create or modify a test, run it and iterate until it passes.
  • For TUI changes: validate by hand with cargo run -- "test prompt" (interactive) or cargo run -- --print "test" (headless). The --print mode is faster for verifying non-TUI logic.
  • Don't run blocking interactive commands you can't exit — the agent will hang. If you must, capture output with --print mode or pipe into head.

Testing the TUI in a controlled terminal

The ratatui frontend is sensitive to terminal size and key encoding. For repeatable manual tests use tmux:

# Build a debug binary once
cargo build

# 80×24 session
tmux new-session -d -s coven-code-test -x 80 -y 24
tmux send-keys -t coven-code-test "./target/debug/coven-code" Enter

# Give it time to redraw, then capture
sleep 2 && tmux capture-pane -t coven-code-test -p

# Drive input
tmux send-keys -t coven-code-test "your prompt here" Enter
tmux send-keys -t coven-code-test Escape
tmux send-keys -t coven-code-test C-o   # ctrl+o

# Cleanup
tmux kill-session -t coven-code-test

On Windows hosts, prefer cargo run -- --print "..." against the headless path. The Windows console has known quirks with the kitty keyboard protocol — see crates/tui for the push/pop workaround.

Issues & PR Comments

When posting issue/PR comments:

  • Write the full comment to a temp file and use gh issue comment --body-file or gh pr comment --body-file.
  • Never pass multi-line markdown directly via --body in shell commands.
  • Preview the exact comment text before posting.
  • Post exactly one final comment unless the user explicitly asks for multiple comments.
  • If a comment is malformed, delete it immediately, then post one corrected comment.
  • Keep comments concise, technical, and in the user's tone.

When creating issues, add labels that map to the relevant crate(s) — for example crate:tui, crate:api, crate:tools, crate:mcp, crate:acp. If an issue spans multiple crates, add all relevant labels.

When closing issues via commit, include fixes #<number> or closes #<number> in the commit message — GitHub closes the issue automatically on merge to main.

Providers

Coven Code supports exactly two providers: Claude (Anthropic) and Codex (OpenAI Codex via ChatGPT OAuth). The provider layer lives in crates/api/src/providers/ (anthropic.rs, codex.rs) and is registered in crates/api/src/registry.rs. Auth flows live in crates/core/src/oauth_config.rs, codex_oauth.rs, and device_code.rs. Adding other providers is out of scope.

Releasing

Coven Code uses a single workspace version stamped across every surface (Cargo workspace, Cargo.lock entries for the 12 claurst* crates (internal crate names, intentionally preserved), npm/package.json, README badge, docs, ACP registry template). Versioning is forward-only — the release workflow refuses to ship a tag less than or equal to the highest existing tag.

CRITICAL Git Rules for Parallel Agents

This repo runs parallel agents in worktrees under .claude/worktrees/. Multiple agents may be modifying different files in the same checkout simultaneously. You MUST follow these rules:

Committing

  • ONLY commit files YOU changed in THIS session. Never commit unless the user has explicitly asked you to commit (see src-rust/.claude/CLAUDE.md — the rule is "NEVER EVER commit").
  • ALWAYS include fixes #<number> or closes #<number> in the commit message when there is a related issue or PR.
  • NEVER use git add -A or git add . — these sweep up changes from other agents.
  • ALWAYS use git add <specific-file-paths> listing only files you modified.
  • Before committing, run git status and verify you are only staging YOUR files.
  • Track which files you created/modified/deleted during the session.
  • Cargo.lock counts as yours if and only if your edits to Cargo.toml caused it to change.

Forbidden Git Operations

These can destroy other agents' work:

  • git reset --hard — destroys uncommitted changes
  • git checkout . / git restore . — destroys uncommitted changes
  • git clean -fd — deletes untracked files
  • git stash — stashes ALL changes including other agents' work
  • git add -A / git add . — stages other agents' uncommitted work
  • git commit --no-verify — bypasses required checks; never allowed
  • Force-push to main — never allowed; the patch-release workflow is the only thing that may force-move tags, and it does so via the workflow runner, not from your shell

Safe Workflow

# 1. Check status
git status

# 2. Stage only your files
git add src-rust/crates/api/src/providers/foo.rs
git add docs/providers.md

# 3. Commit (only when the user has asked)
git commit -m "feat(api): add foo provider"

# 4. Push (pull --rebase if needed, but NEVER reset/checkout)
git pull --rebase && git push

If Rebase Conflicts Occur

  • Resolve conflicts in YOUR files only.
  • If a conflict touches a file you didn't modify, abort the rebase and ask the user.
  • NEVER force-push.

User Override

If the user's instructions conflict with the rules above, ask for confirmation that they want to override the rules. Only then execute their instructions.