CodeSage is pre-1.0 and under active development. The bar for contribution is simple: small, focused changes with tests.
File an issue with:
- The exact command or MCP tool call you ran.
- What you expected.
- What happened instead. Paste
codesage doctoroutput if the problem looks environmental. - Your OS, GPU model if you run with CUDA, and
codesage --version.
A minimal reproducer (a small test project that triggers the issue) saves a lot of back-and-forth.
Open an issue tagged proposal and describe the user-facing problem before writing code. A new MCP tool needs a plausible agent use case. A new CLI flag needs a command shape that fits the existing pattern.
cargo build # all crates, debug
cargo build --release -p codesage --features cuda # release binary with GPU
cargo test --workspace # full test suite
cargo clippy --workspace # lintAlways build with --features cuda when you want GPU. Without it, a GPU-configured project fails loudly at runtime, which is on purpose: a silent CPU fallback would mix incompatible embeddings into the same index.
Every bug fix and every feature needs a test. The workspace has ~965; new code should grow that number. Use integration tests for anything that crosses a crate boundary (parsing plus storage, indexing plus search).
Run cargo test --workspace before you send a pull request. Tests that need GPU are gated, so the suite passes on CPU-only machines.
- Rust 2024 edition.
anyhowfor error handling workspace-wide. Shared domain types live in theprotocolcrate.- Tree-sitter queries are
.scmfiles undercrates/parser/src/queries/, embedded viainclude_str!. - All query commands emit JSON with
--json. - Write a comment only when the reason isn't obvious from the code. If the next reader would ask "why is this here?", add the comment. Otherwise, let the code speak.
Imperative mood, under 70 characters in the subject. A body is optional but useful when the why isn't obvious from the diff. Conventional prefixes (feat:, fix:, docs:, test:, chore:) help with later parsing.
Every user-visible change updates CHANGELOG.md under ## [Unreleased] in the same commit. User-visible means: new CLI flags or subcommands, new or changed MCP tools, behavior changes, breaking changes, schema migrations, hook template changes, config surface changes, or security fixes. Pure internal refactors, test-only changes, and doc-only changes don't need an entry.
One bullet per change. Describe what a user can now do, not how you implemented it.
Keep them focused. One topic per PR. Aim for under ~300 lines of diff; split if it grows. Explain the why in the PR description, the what in the commits, and the how in the code. CI must be green before review.
CodeSage is actively developed and dogfooded against private codebases. Two mechanisms keep that work from leaking into the public repo.
Pre-commit leak check. codesage install-hooks --with-leak-check installs a pre-commit hook that runs scripts/leak-check.sh over staged content. Plain codesage install-hooks does not add it: the hook execs a repo-shipped script, so wiring it automatically would hand a fresh clone of a malicious repo code execution on your next commit. When scripts/leak-check.sh is present, plain install-hooks prints a notice pointing you at the --with-leak-check flag. The script scans against extended-regex patterns in two files:
scripts/leak-patterns.txt— tracked, shared. Generic secret formats (private keys, AWS/GitHub/Slack tokens)..git/info/leak-patterns.txt— local-only, per-developer. Add your own entries here: private repo names, internal domain terms, absolute home paths. This file never enters git.
The script prints the offending file:line and blocks the commit. Bypass with git commit --no-verify only when you're sure the match is a false positive, and refine the pattern afterwards.
External test data via env vars. Any path that points at private test data lives outside the repo and gets injected via environment variable. The existing example is CODESAGE_BENCH_CORPUS_DIR (default: ./bench-corpora); set it to wherever your corpora actually live. Do not hardcode paths in tests, fixtures, or plugin commands.
Test fixtures under crates/parser/tests/fixtures/ must be synthetic code, not copied from real repositories. If you need a fixture with a specific shape, write it; don't paste it in.
By contributing, you agree your contributions will be licensed under the MIT license, as described in LICENSE.