{"owner":"Kuberwastaken","repo":"claurst","hasSkills":true,"hasMcp":false,"mcpConfig":null,"found":["AGENTS.md"],"skills":{"AGENTS.md":"# Development Rules\n\nAgent-facing rules for working on Claurst. Mirrors and extends `src-rust/.claude/CLAUDE.md`; when the two disagree, the rule closer to the code wins.\n\n## Conversational Style\n\n- Keep answers short and concise\n- No emojis in commits, issues, PR comments, or code\n- No fluff or cheerful filler text\n- Technical prose only, be kind but direct (e.g., \"Thanks @user\" not \"Thanks so much @user!\")\n- When the user asks a question, answer it first before making edits or running implementation commands.\n\n## Code Quality\n\n- 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.\n- 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.\n- Avoid speculative `.clone()` — borrow first, clone only when ownership is actually needed. Same applies to `.to_string()` on `&str`.\n- No `unsafe` blocks without a `// SAFETY:` comment explaining the invariant.\n- Single-line helper functions with a single call site are forbidden; inline them instead.\n- Don't guess external API shapes. Read the crate source under `~/.cargo/registry/` or check `cargo doc --open`. For Anthropic / OpenAI / Google wire formats, the `crates/api/src/providers/<provider>.rs` files are the authoritative reference inside this repo.\n- **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.\n- 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.\n- Always ask before removing functionality or code that appears to be intentional.\n- Do not preserve backward compatibility unless the user explicitly asks for it.\n- 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.\n- NEVER modify generated files directly. Generated artefacts in this repo:\n  - `src-rust/Cargo.lock` — regenerated by cargo; for version bumps use [`scripts/bump-version.py`](scripts/bump-version.py).\n  - `npm/package.json` `version` field — also stamped by `bump-version.py`.\n\n## Commands\n\nRun from `src-rust/` unless noted.\n\n- After Rust changes (not docs): `cargo check --workspace` — fix every error and warning before committing.\n- Clippy: `cargo clippy --workspace --all-targets -- -D warnings`. Fix lints; do not `#[allow(...)]` without justification.\n- Format: `cargo fmt --all`. Run before committing.\n- 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.\n- Avoid running `cargo build --release` or `cargo run --release` unless you specifically need optimised output — debug builds and `cargo check` are 10× faster.\n- If you create or modify a test, run it and iterate until it passes.\n- 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.\n- 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`.\n\n### Testing the TUI in a controlled terminal\n\nThe ratatui frontend is sensitive to terminal size and key encoding. For repeatable manual tests use tmux:\n\n```bash\n# Build a debug binary once\ncargo build\n\n# 80×24 session\ntmux new-session -d -s claurst-test -x 80 -y 24\ntmux send-keys -t claurst-test \"./target/debug/claurst\" Enter\n\n# Give it time to redraw, then capture\nsleep 2 && tmux capture-pane -t claurst-test -p\n\n# Drive input\ntmux send-keys -t claurst-test \"your prompt here\" Enter\ntmux send-keys -t claurst-test Escape\ntmux send-keys -t claurst-test C-o   # ctrl+o\n\n# Cleanup\ntmux kill-session -t claurst-test\n```\n\nOn 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.\n\n## Issues & PR Comments\n\nWhen posting issue/PR comments:\n\n- Write the full comment to a temp file and use `gh issue comment --body-file` or `gh pr comment --body-file`.\n- Never pass multi-line markdown directly via `--body` in shell commands.\n- Preview the exact comment text before posting.\n- Post exactly one final comment unless the user explicitly asks for multiple comments.\n- If a comment is malformed, delete it immediately, then post one corrected comment.\n- Keep comments concise, technical, and in the user's tone.\n\nWhen 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.\n\nWhen closing issues via commit, include `fixes #<number>` or `closes #<number>` in the commit message — GitHub closes the issue automatically on merge to main.\n\n### 1. Provider identifier (`crates/core/src/provider_id.rs`)\n\nAdd a well-known constant on `ProviderId`, e.g. `pub const FOO: &'static str = \"foo\";`. Use the canonical name the provider publishes for its API.\n\n### 2. Provider implementation (`crates/api/src/providers/`)\n\n- OpenAI-compatible: add an entry to `openai_compat_providers.rs`. This is one line + an optional base-URL helper.\n- Custom wire format: create `crates/api/src/providers/<name>.rs` exposing a struct that implements `LlmProvider` (see `provider.rs`). Mirror the structure of `anthropic.rs` or `google.rs` — request shaping, response parsing, streaming SSE handling, tool conversion.\n- Add `pub mod <name>; pub use <name>::<Name>Provider;` to `providers/mod.rs`.\n\n### 3. Register the provider (`crates/api/src/registry.rs`)\n\nImport the new provider and add it to the registry construction. The registry hands back `Arc<dyn LlmProvider>` by id.\n\n### 4. Model registry (`crates/api/src/model_registry.rs`)\n\nAdd the canonical model IDs and capability metadata (context window, supports thinking, supports vision, etc.).\n\n### 5. Auth & env detection (`crates/core/src/auth_store.rs`, related)\n\nIf the provider uses an env var (e.g. `FOO_API_KEY`), wire it into the auth-store probe. For OAuth-style providers, see `codex_oauth.rs` and `device_code.rs` for the existing patterns.\n\n### 6. Tests\n\n- Add a smoke test in `crates/api/tests/` that exercises request shaping and response parsing against a mocked HTTP body. No live API calls — use the fixture pattern that the existing provider tests follow.\n- If the provider supports tool calls, add a tool-call round-trip fixture.\n- For OpenAI-compatible providers, the shared test in `crates/api/tests/openai_compat.rs` covers most paths; usually just adding a row to its provider matrix is enough.\n\n### 7. Documentation\n\n- `README.md`: add the provider to the \"Supported Providers\" list if it's user-visible.\n- `docs/providers.md`: setup instructions, env var, and `settings.json` shape.\n\n## Releasing\n\nClaurst uses a **single workspace version** stamped across every surface (Cargo workspace, Cargo.lock entries for the 12 `claurst*` crates, `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.\n\n## **CRITICAL** Git Rules for Parallel Agents\n\nThis 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:\n\n### Committing\n\n- **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\").\n- ALWAYS include `fixes #<number>` or `closes #<number>` in the commit message when there is a related issue or PR.\n- NEVER use `git add -A` or `git add .` — these sweep up changes from other agents.\n- ALWAYS use `git add <specific-file-paths>` listing only files you modified.\n- Before committing, run `git status` and verify you are only staging YOUR files.\n- Track which files you created/modified/deleted during the session.\n- Cargo.lock counts as yours if and only if your edits to `Cargo.toml` caused it to change.\n\n### Forbidden Git Operations\n\nThese can destroy other agents' work:\n\n- `git reset --hard` — destroys uncommitted changes\n- `git checkout .` / `git restore .` — destroys uncommitted changes\n- `git clean -fd` — deletes untracked files\n- `git stash` — stashes ALL changes including other agents' work\n- `git add -A` / `git add .` — stages other agents' uncommitted work\n- `git commit --no-verify` — bypasses required checks; never allowed\n- 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\n\n### Safe Workflow\n\n```bash\n# 1. Check status\ngit status\n\n# 2. Stage only your files\ngit add src-rust/crates/api/src/providers/foo.rs\ngit add docs/providers.md\n\n# 3. Commit (only when the user has asked)\ngit commit -m \"feat(api): add foo provider\"\n\n# 4. Push (pull --rebase if needed, but NEVER reset/checkout)\ngit pull --rebase && git push\n```\n\n### If Rebase Conflicts Occur\n\n- Resolve conflicts in YOUR files only.\n- If a conflict touches a file you didn't modify, abort the rebase and ask the user.\n- NEVER force-push.\n\n### User Override\n\nIf the user's instructions conflict with the rules above, ask for confirmation that they want to override the rules. Only then execute their instructions.\n"},"files":{"AGENTS.md":"# Development Rules\n\nAgent-facing rules for working on Claurst. Mirrors and extends `src-rust/.claude/CLAUDE.md`; when the two disagree, the rule closer to the code wins.\n\n## Conversational Style\n\n- Keep answers short and concise\n- No emojis in commits, issues, PR comments, or code\n- No fluff or cheerful filler text\n- Technical prose only, be kind but direct (e.g., \"Thanks @user\" not \"Thanks so much @user!\")\n- When the user asks a question, answer it first before making edits or running implementation commands.\n\n## Code Quality\n\n- 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.\n- 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.\n- Avoid speculative `.clone()` — borrow first, clone only when ownership is actually needed. Same applies to `.to_string()` on `&str`.\n- No `unsafe` blocks without a `// SAFETY:` comment explaining the invariant.\n- Single-line helper functions with a single call site are forbidden; inline them instead.\n- Don't guess external API shapes. Read the crate source under `~/.cargo/registry/` or check `cargo doc --open`. For Anthropic / OpenAI / Google wire formats, the `crates/api/src/providers/<provider>.rs` files are the authoritative reference inside this repo.\n- **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.\n- 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.\n- Always ask before removing functionality or code that appears to be intentional.\n- Do not preserve backward compatibility unless the user explicitly asks for it.\n- 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.\n- NEVER modify generated files directly. Generated artefacts in this repo:\n  - `src-rust/Cargo.lock` — regenerated by cargo; for version bumps use [`scripts/bump-version.py`](scripts/bump-version.py).\n  - `npm/package.json` `version` field — also stamped by `bump-version.py`.\n\n## Commands\n\nRun from `src-rust/` unless noted.\n\n- After Rust changes (not docs): `cargo check --workspace` — fix every error and warning before committing.\n- Clippy: `cargo clippy --workspace --all-targets -- -D warnings`. Fix lints; do not `#[allow(...)]` without justification.\n- Format: `cargo fmt --all`. Run before committing.\n- 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.\n- Avoid running `cargo build --release` or `cargo run --release` unless you specifically need optimised output — debug builds and `cargo check` are 10× faster.\n- If you create or modify a test, run it and iterate until it passes.\n- 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.\n- 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`.\n\n### Testing the TUI in a controlled terminal\n\nThe ratatui frontend is sensitive to terminal size and key encoding. For repeatable manual tests use tmux:\n\n```bash\n# Build a debug binary once\ncargo build\n\n# 80×24 session\ntmux new-session -d -s claurst-test -x 80 -y 24\ntmux send-keys -t claurst-test \"./target/debug/claurst\" Enter\n\n# Give it time to redraw, then capture\nsleep 2 && tmux capture-pane -t claurst-test -p\n\n# Drive input\ntmux send-keys -t claurst-test \"your prompt here\" Enter\ntmux send-keys -t claurst-test Escape\ntmux send-keys -t claurst-test C-o   # ctrl+o\n\n# Cleanup\ntmux kill-session -t claurst-test\n```\n\nOn 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.\n\n## Issues & PR Comments\n\nWhen posting issue/PR comments:\n\n- Write the full comment to a temp file and use `gh issue comment --body-file` or `gh pr comment --body-file`.\n- Never pass multi-line markdown directly via `--body` in shell commands.\n- Preview the exact comment text before posting.\n- Post exactly one final comment unless the user explicitly asks for multiple comments.\n- If a comment is malformed, delete it immediately, then post one corrected comment.\n- Keep comments concise, technical, and in the user's tone.\n\nWhen 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.\n\nWhen closing issues via commit, include `fixes #<number>` or `closes #<number>` in the commit message — GitHub closes the issue automatically on merge to main.\n\n### 1. Provider identifier (`crates/core/src/provider_id.rs`)\n\nAdd a well-known constant on `ProviderId`, e.g. `pub const FOO: &'static str = \"foo\";`. Use the canonical name the provider publishes for its API.\n\n### 2. Provider implementation (`crates/api/src/providers/`)\n\n- OpenAI-compatible: add an entry to `openai_compat_providers.rs`. This is one line + an optional base-URL helper.\n- Custom wire format: create `crates/api/src/providers/<name>.rs` exposing a struct that implements `LlmProvider` (see `provider.rs`). Mirror the structure of `anthropic.rs` or `google.rs` — request shaping, response parsing, streaming SSE handling, tool conversion.\n- Add `pub mod <name>; pub use <name>::<Name>Provider;` to `providers/mod.rs`.\n\n### 3. Register the provider (`crates/api/src/registry.rs`)\n\nImport the new provider and add it to the registry construction. The registry hands back `Arc<dyn LlmProvider>` by id.\n\n### 4. Model registry (`crates/api/src/model_registry.rs`)\n\nAdd the canonical model IDs and capability metadata (context window, supports thinking, supports vision, etc.).\n\n### 5. Auth & env detection (`crates/core/src/auth_store.rs`, related)\n\nIf the provider uses an env var (e.g. `FOO_API_KEY`), wire it into the auth-store probe. For OAuth-style providers, see `codex_oauth.rs` and `device_code.rs` for the existing patterns.\n\n### 6. Tests\n\n- Add a smoke test in `crates/api/tests/` that exercises request shaping and response parsing against a mocked HTTP body. No live API calls — use the fixture pattern that the existing provider tests follow.\n- If the provider supports tool calls, add a tool-call round-trip fixture.\n- For OpenAI-compatible providers, the shared test in `crates/api/tests/openai_compat.rs` covers most paths; usually just adding a row to its provider matrix is enough.\n\n### 7. Documentation\n\n- `README.md`: add the provider to the \"Supported Providers\" list if it's user-visible.\n- `docs/providers.md`: setup instructions, env var, and `settings.json` shape.\n\n## Releasing\n\nClaurst uses a **single workspace version** stamped across every surface (Cargo workspace, Cargo.lock entries for the 12 `claurst*` crates, `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.\n\n## **CRITICAL** Git Rules for Parallel Agents\n\nThis 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:\n\n### Committing\n\n- **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\").\n- ALWAYS include `fixes #<number>` or `closes #<number>` in the commit message when there is a related issue or PR.\n- NEVER use `git add -A` or `git add .` — these sweep up changes from other agents.\n- ALWAYS use `git add <specific-file-paths>` listing only files you modified.\n- Before committing, run `git status` and verify you are only staging YOUR files.\n- Track which files you created/modified/deleted during the session.\n- Cargo.lock counts as yours if and only if your edits to `Cargo.toml` caused it to change.\n\n### Forbidden Git Operations\n\nThese can destroy other agents' work:\n\n- `git reset --hard` — destroys uncommitted changes\n- `git checkout .` / `git restore .` — destroys uncommitted changes\n- `git clean -fd` — deletes untracked files\n- `git stash` — stashes ALL changes including other agents' work\n- `git add -A` / `git add .` — stages other agents' uncommitted work\n- `git commit --no-verify` — bypasses required checks; never allowed\n- 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\n\n### Safe Workflow\n\n```bash\n# 1. Check status\ngit status\n\n# 2. Stage only your files\ngit add src-rust/crates/api/src/providers/foo.rs\ngit add docs/providers.md\n\n# 3. Commit (only when the user has asked)\ngit commit -m \"feat(api): add foo provider\"\n\n# 4. Push (pull --rebase if needed, but NEVER reset/checkout)\ngit pull --rebase && git push\n```\n\n### If Rebase Conflicts Occur\n\n- Resolve conflicts in YOUR files only.\n- If a conflict touches a file you didn't modify, abort the rebase and ask the user.\n- NEVER force-push.\n\n### User Override\n\nIf the user's instructions conflict with the rules above, ask for confirmation that they want to override the rules. Only then execute their instructions.\n"},"items":[{"name":"AGENTS.md","path":"AGENTS.md","title":"AGENTS.md","content":"# Development Rules\n\nAgent-facing rules for working on Claurst. Mirrors and extends `src-rust/.claude/CLAUDE.md`; when the two disagree, the rule closer to the code wins.\n\n## Conversational Style\n\n- Keep answers short and concise\n- No emojis in commits, issues, PR comments, or code\n- No fluff or cheerful filler text\n- Technical prose only, be kind but direct (e.g., \"Thanks @user\" not \"Thanks so much @user!\")\n- When the user asks a question, answer it first before making edits or running implementation commands.\n\n## Code Quality\n\n- 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.\n- 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.\n- Avoid speculative `.clone()` — borrow first, clone only when ownership is actually needed. Same applies to `.to_string()` on `&str`.\n- No `unsafe` blocks without a `// SAFETY:` comment explaining the invariant.\n- Single-line helper functions with a single call site are forbidden; inline them instead.\n- Don't guess external API shapes. Read the crate source under `~/.cargo/registry/` or check `cargo doc --open`. For Anthropic / OpenAI / Google wire formats, the `crates/api/src/providers/<provider>.rs` files are the authoritative reference inside this repo.\n- **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.\n- 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.\n- Always ask before removing functionality or code that appears to be intentional.\n- Do not preserve backward compatibility unless the user explicitly asks for it.\n- 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.\n- NEVER modify generated files directly. Generated artefacts in this repo:\n  - `src-rust/Cargo.lock` — regenerated by cargo; for version bumps use [`scripts/bump-version.py`](scripts/bump-version.py).\n  - `npm/package.json` `version` field — also stamped by `bump-version.py`.\n\n## Commands\n\nRun from `src-rust/` unless noted.\n\n- After Rust changes (not docs): `cargo check --workspace` — fix every error and warning before committing.\n- Clippy: `cargo clippy --workspace --all-targets -- -D warnings`. Fix lints; do not `#[allow(...)]` without justification.\n- Format: `cargo fmt --all`. Run before committing.\n- 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.\n- Avoid running `cargo build --release` or `cargo run --release` unless you specifically need optimised output — debug builds and `cargo check` are 10× faster.\n- If you create or modify a test, run it and iterate until it passes.\n- 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.\n- 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`.\n\n### Testing the TUI in a controlled terminal\n\nThe ratatui frontend is sensitive to terminal size and key encoding. For repeatable manual tests use tmux:\n\n```bash\n# Build a debug binary once\ncargo build\n\n# 80×24 session\ntmux new-session -d -s claurst-test -x 80 -y 24\ntmux send-keys -t claurst-test \"./target/debug/claurst\" Enter\n\n# Give it time to redraw, then capture\nsleep 2 && tmux capture-pane -t claurst-test -p\n\n# Drive input\ntmux send-keys -t claurst-test \"your prompt here\" Enter\ntmux send-keys -t claurst-test Escape\ntmux send-keys -t claurst-test C-o   # ctrl+o\n\n# Cleanup\ntmux kill-session -t claurst-test\n```\n\nOn 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.\n\n## Issues & PR Comments\n\nWhen posting issue/PR comments:\n\n- Write the full comment to a temp file and use `gh issue comment --body-file` or `gh pr comment --body-file`.\n- Never pass multi-line markdown directly via `--body` in shell commands.\n- Preview the exact comment text before posting.\n- Post exactly one final comment unless the user explicitly asks for multiple comments.\n- If a comment is malformed, delete it immediately, then post one corrected comment.\n- Keep comments concise, technical, and in the user's tone.\n\nWhen 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.\n\nWhen closing issues via commit, include `fixes #<number>` or `closes #<number>` in the commit message — GitHub closes the issue automatically on merge to main.\n\n### 1. Provider identifier (`crates/core/src/provider_id.rs`)\n\nAdd a well-known constant on `ProviderId`, e.g. `pub const FOO: &'static str = \"foo\";`. Use the canonical name the provider publishes for its API.\n\n### 2. Provider implementation (`crates/api/src/providers/`)\n\n- OpenAI-compatible: add an entry to `openai_compat_providers.rs`. This is one line + an optional base-URL helper.\n- Custom wire format: create `crates/api/src/providers/<name>.rs` exposing a struct that implements `LlmProvider` (see `provider.rs`). Mirror the structure of `anthropic.rs` or `google.rs` — request shaping, response parsing, streaming SSE handling, tool conversion.\n- Add `pub mod <name>; pub use <name>::<Name>Provider;` to `providers/mod.rs`.\n\n### 3. Register the provider (`crates/api/src/registry.rs`)\n\nImport the new provider and add it to the registry construction. The registry hands back `Arc<dyn LlmProvider>` by id.\n\n### 4. Model registry (`crates/api/src/model_registry.rs`)\n\nAdd the canonical model IDs and capability metadata (context window, supports thinking, supports vision, etc.).\n\n### 5. Auth & env detection (`crates/core/src/auth_store.rs`, related)\n\nIf the provider uses an env var (e.g. `FOO_API_KEY`), wire it into the auth-store probe. For OAuth-style providers, see `codex_oauth.rs` and `device_code.rs` for the existing patterns.\n\n### 6. Tests\n\n- Add a smoke test in `crates/api/tests/` that exercises request shaping and response parsing against a mocked HTTP body. No live API calls — use the fixture pattern that the existing provider tests follow.\n- If the provider supports tool calls, add a tool-call round-trip fixture.\n- For OpenAI-compatible providers, the shared test in `crates/api/tests/openai_compat.rs` covers most paths; usually just adding a row to its provider matrix is enough.\n\n### 7. Documentation\n\n- `README.md`: add the provider to the \"Supported Providers\" list if it's user-visible.\n- `docs/providers.md`: setup instructions, env var, and `settings.json` shape.\n\n## Releasing\n\nClaurst uses a **single workspace version** stamped across every surface (Cargo workspace, Cargo.lock entries for the 12 `claurst*` crates, `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.\n\n## **CRITICAL** Git Rules for Parallel Agents\n\nThis 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:\n\n### Committing\n\n- **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\").\n- ALWAYS include `fixes #<number>` or `closes #<number>` in the commit message when there is a related issue or PR.\n- NEVER use `git add -A` or `git add .` — these sweep up changes from other agents.\n- ALWAYS use `git add <specific-file-paths>` listing only files you modified.\n- Before committing, run `git status` and verify you are only staging YOUR files.\n- Track which files you created/modified/deleted during the session.\n- Cargo.lock counts as yours if and only if your edits to `Cargo.toml` caused it to change.\n\n### Forbidden Git Operations\n\nThese can destroy other agents' work:\n\n- `git reset --hard` — destroys uncommitted changes\n- `git checkout .` / `git restore .` — destroys uncommitted changes\n- `git clean -fd` — deletes untracked files\n- `git stash` — stashes ALL changes including other agents' work\n- `git add -A` / `git add .` — stages other agents' uncommitted work\n- `git commit --no-verify` — bypasses required checks; never allowed\n- 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\n\n### Safe Workflow\n\n```bash\n# 1. Check status\ngit status\n\n# 2. Stage only your files\ngit add src-rust/crates/api/src/providers/foo.rs\ngit add docs/providers.md\n\n# 3. Commit (only when the user has asked)\ngit commit -m \"feat(api): add foo provider\"\n\n# 4. Push (pull --rebase if needed, but NEVER reset/checkout)\ngit pull --rebase && git push\n```\n\n### If Rebase Conflicts Occur\n\n- Resolve conflicts in YOUR files only.\n- If a conflict touches a file you didn't modify, abort the rebase and ask the user.\n- NEVER force-push.\n\n### User Override\n\nIf the user's instructions conflict with the rules above, ask for confirmation that they want to override the rules. Only then execute their instructions.\n","category":"root","tokens":2504}]}