Thank you for your interest in making developer security better. Rafter is MIT-licensed and we welcome contributions from every developer.
good first issue— Scoped tasks that don't require deep knowledge of the codebasehelp wanted— Meatier tasks where community help is appreciatedneeds-design— Not ready for PRs — still figuring out the approach
Don't ask for permission to work on a labeled issue. Just comment that you're starting and open a PR. If an issue isn't labeled for contribution, check with us first.
Node.js (primary implementation):
node >= 18
pnpm >= 9 # corepack enable && corepack prepare pnpm@9Python (feature-parity implementation):
python >= 3.10
poetry # pip install poetrygit clone https://github.com/Raftersecurity/rafter-cli.git
cd rafter-cli
# Node
cd node
pnpm install --frozen-lockfile
pnpm test # 600+ tests, ~80s
# Python
cd python
poetry install
pytest # 400+ tests, ~2sRafter ships as both @rafter-security/cli (npm) and rafter-cli (PyPI) with full feature parity. Every change must be implemented in both Node.js and Python.
| What | Node | Python |
|---|---|---|
| Source | node/src/ |
python/rafter_cli/ |
| Tests | node/tests/ (Vitest) |
python/tests/ (pytest) |
| Package | node/package.json |
python/pyproject.toml |
| Entry point | node/src/index.ts |
python/rafter_cli/__main__.py |
| CLI framework | commander.js | typer |
Spec-first: shared-docs/CLI_SPEC.md is the canonical reference for command behavior, output schemas, and exit codes. Read it before changing CLI behavior. Update it when you add or change commands.
This is the most common contribution. Here's the full walkthrough:
1. Add the regex to both implementations:
- Node:
node/src/scanners/secret-patterns.ts— add toDEFAULT_SECRET_PATTERNSarray - Python:
python/rafter_cli/scanners/secret_patterns.py— add a pattern entry - Format:
{ name, severity, regex, description }
2. Add tests in both node/tests/ and python/tests/ — use realistic-looking but obviously fake values
3. Run tests in both: cd node && pnpm test and cd python && pytest
See existing patterns in secret-patterns.ts / secret_patterns.py for the exact format.
Platform install logic lives inline in the agent init command, not in separate adapter files.
1. Add install function — In node/src/commands/agent/init.ts, add an install<Platform>Mcp() function following existing ones (e.g., installCursorMcp()). Do the same in python/rafter_cli/commands/agent.py.
2. Register the --with-<platform> flag in agent init (both implementations)
3. Add a recipe in recipes/<platform>.md with copy-paste setup instructions
4. Add tests for the new platform detection and installation
# Full suites
cd node && pnpm test # Vitest — all tests
cd python && pytest # pytest — all tests
# Single file
cd node && npx vitest run tests/<file>.test.ts
cd python && pytest tests/<file>.py -v
# Watch mode (Node only)
cd node && npx vitest tests/<file>.test.tsTests must pass in both implementations before a PR can merge.
Use conventional commit format: feat:, fix:, test:, docs:, chore:.
Include:
- Summary — What changed and why (1-3 sentences)
- Test plan — How you verified it works
- Spec update — If CLI behavior changed, did you update
shared-docs/CLI_SPEC.md?
- Both Node and Python implementations updated
- Tests pass in both (
pnpm test+pytest) - Versions match in
node/package.jsonandpython/pyproject.toml -
shared-docs/CLI_SPEC.mdupdated (if CLI behavior changed) - No secrets, credentials, or API keys in the diff
We welcome AI-assisted contributions. If your PR was substantially generated by an AI tool (Copilot, Claude, Cursor, etc.), please:
- Note it in the PR description (e.g., "Written with Claude Code")
- Add a
Co-Authored-Bytrailer to the commit
We evaluate contributions on quality and correctness, not authorship. AI-generated PRs that don't pass tests, don't update both implementations, or introduce regressions will be closed like any other PR.
Automated bot PRs: If you're running an agent that submits PRs, ensure it follows the dual-implementation requirement. Single-language PRs will be closed.
- Node: TypeScript strict mode. No
anyunless unavoidable. Vitest for tests. - Python: Type hints on public APIs. pytest for tests. No
# type: ignorewithout justification. - Both: No unnecessary dependencies. Security tool — every dependency is attack surface.
We don't enforce a formatter beyond what TypeScript and Python defaults provide. Don't reformat files you didn't change.
If you find a security vulnerability in Rafter itself, please email security@rafter.so instead of opening a public issue. We'll credit you in the advisory.
Be respectful, be constructive, evaluate contributions on merit.
Open a discussion or file an issue. We're responsive.