Thank you for your interest in contributing to ByteRover CLI! Whether you're fixing a bug, adding a feature, improving documentation, or reporting an issue — every contribution is valued.
- Node.js >= 20
- npm
- Git
# Fork the repo on GitHub, then clone your fork
git clone https://github.com/YOUR_USERNAME/byterover-cli.git
cd byterover-cli
# Install dependencies
npm ci
# Build
npm run build
# Run tests
npm run test# Copy .env.example to .env.development
cp .env.example .env.development
# Run in dev mode (ts-node, BRV_ENV=development)
./bin/dev.js
# Run a specific command in dev mode
./bin/dev.js status
./bin/dev.js curate "some context" @src/file.tsgit checkout -b feature/your-descriptive-branch-nameBranch naming conventions:
feature/*— New featuresfix/*— Bug fixesdocs/*— Documentation changestest/*— Test additions or improvementsrefactor/*— Code refactoring
npm run build # Full build (clean + tsc + copy templates/resources)
npm run lint # ESLint
npm run lint:fix # ESLint with auto-fix
npm run typecheck # TypeScript type checking (tsc --noEmit)
npm test # All tests (mocha --forbid-only)Run a single test file:
npx mocha --forbid-only "test/path/to/file.test.ts"Note: Always run tests from the project root, not from within test directories.
- Pre-commit: Runs
lint-staged(ESLint on staged.ts/.tsxfiles) - Pre-push: Runs
npm run typecheck
The web UI supports a local-first development flow for the shared component library. npm run dev:ui uses the git submodule at packages/byterover-packages/ui so edits to shared UI components hot-reload immediately in Vite.
# Clone with submodules, or initialize them after clone
git clone --recurse-submodules <repo-url>
# or
git submodule update --init --recursive
# Install dependencies
npm ci
# Start or restart the daemon
./bin/dev.js restart
# Start the web UI in local development mode
npm run dev:uiNotes:
- Edit shared components in
packages/byterover-packages/ui/src. npm run dev:uiuses the submodule source.npm run build:uiuses the installed package path.- If
/api/ui/configor transport bootstrap fails, restart the Vite dev server after restarting the daemon.
src/
├── agent/ # LLM agent system
│ ├── core/ # Domain interfaces
│ ├── infra/ # Implementations (tools, LLM providers, system-prompt, map, memory)
│ └── resources/ # Tool definitions (.txt), prompt templates (.yaml)
├── server/ # Daemon infrastructure
│ ├── core/ # Domain interfaces
│ └── infra/ # Implementations (daemon, process, session, storage)
├── shared/ # Cross-module constants, types, transport events, utils
├── tui/ # React/Ink TUI
│ ├── app/ # Router and pages
│ ├── components/ # Reusable UI components
│ ├── features/ # Feature modules (commands, auth, curate, query, etc.)
│ ├── hooks/ # React hooks
│ └── stores/ # Zustand state stores
└── oclif/ # CLI commands and hooks
├── commands/ # oclif command definitions
└── hooks/ # oclif lifecycle hooks
test/
├── commands/ # Command integration tests
├── unit/ # Unit tests (fast, in-memory)
├── integration/ # Integration tests
├── helpers/ # Test utilities
├── hooks/ # Hook tests
└── shared/ # Shared test utilities
Import boundary (ESLint-enforced): tui/ must not import from server/, agent/, or oclif/. Use transport events or shared/ for cross-module communication.
- ES modules with
.jsimport extensions required (Node16 module resolution) - No
as Typeassertions — use type guards or proper typing instead - No
any— useunknownwith type narrowing or proper generics - Object parameters for functions with more than 3 parameters
typefor data-only shapes (DTOs, payloads, configs)interfacefor behavioral contracts with method signatures (services, repositories)Iprefix for interfaces (e.g.,IAuthService,IStorageProvider)toJson()/fromJson()(capital J) for serialization methods- Snake_case APIs: use
/* eslint-disable camelcase */where external APIs require it
- oclif v4 commands live in
src/oclif/commands/ - Services in
src/server/infra/andsrc/agent/infra/ - Follow Outside-In feature development: start from the consumer (command/TUI component), define the minimal interface it needs, then implement the service
Test-Driven Development (TDD) is mandatory. Follow this cycle for every change:
- Write failing tests first — before writing any implementation code, write tests that describe the expected behavior
- Run tests to confirm they fail — verify the tests fail for the right reason (missing implementation, not a syntax error)
- Write the minimal implementation — write only enough code to make the failing tests pass
- Run tests to confirm they pass — verify all tests are green
- Refactor if needed — clean up while keeping tests green
- 50% coverage minimum, critical paths must be fully covered
- Suppress console logging in tests to keep output clean
- Unit tests must be fast and run completely in-memory with proper stubbing and mocking
- Stack: Mocha + Chai + Sinon + Nock
- HTTP mocking (nock): Always verify both
authorizationandx-byterover-session-idheaders with.matchHeader() - ES Modules: Cannot stub ES module exports with sinon. Test utilities using the real filesystem via
tmpdir()instead
Use Conventional Commits:
<type>: <description>
| Type | Purpose |
|---|---|
feat |
New feature |
fix |
Bug fix |
docs |
Documentation only |
test |
Adding or updating tests |
refactor |
Code change that neither fixes a bug nor adds a feature |
chore |
Build process, dependencies, or tooling changes |
feat: add persistent memory layer for agent sessions
fix: resolve MCP connection timeout on slow networks
docs: update LLM provider setup instructions
test: add integration tests for cloud sync
refactor: extract shared auth logic into service
chore: update dependencies
Run all checks locally:
npm run lint && npm run typecheck && npm run build && npm test- Push your branch and open a PR against
main - Fill in the PR template with:
- A clear title describing the change
- Description explaining what and why
- Link to related issues
- Code follows the project's style guidelines
- Tests added or updated and passing
- Documentation updated if needed
- No breaking changes (or clearly documented if unavoidable)
- Commits follow conventional format
- Branch is up to date with
main
When reporting bugs, please include:
- Environment: Node.js version, OS, npm version,
brv --version - Steps to reproduce (minimal)
- Expected behavior vs actual behavior
- Error messages or relevant logs
By contributing to ByteRover CLI, you agree that your contributions will be licensed under the Elastic License 2.0.