Welcome to ccflare! We're thrilled that you're interested in contributing to our Claude load balancer project. This document provides guidelines and instructions for contributing to the project.
- Welcome & Code of Conduct
- Development Setup
- Project Structure
- Coding Standards
- Commit Message Format
- Pull Request Process
- Testing Guidelines
- Documentation Standards
- Adding New Features Checklist
- Release Process
- Common Development Tasks
First off, thank you for considering contributing to ccflare! We welcome contributions from everyone, regardless of their background or experience level.
We are committed to providing a welcoming and inspiring community for all. We pledge to:
- Be respectful and inclusive in our language and actions
- Welcome newcomers and help them get started
- Respect differing viewpoints and experiences
- Show empathy towards other community members
- Focus on what is best for the community and the project
- Use welcoming and inclusive language
- Be respectful of differing viewpoints and experiences
- Gracefully accept constructive criticism
- Focus on what is best for the community
- Show empathy towards other community members
- Harassment, discrimination, or personal attacks
- Trolling, insulting/derogatory comments, and personal or political attacks
- Public or private harassment
- Publishing others' private information without explicit permission
- Other conduct which could reasonably be considered inappropriate
Before you begin, ensure you have the following installed:
- Bun >= 1.2.8 (required): Install from bun.sh
- Git: For version control
- SQLite: Comes bundled with Bun, no separate installation needed
Note: Node.js is not required as the project uses Bun exclusively.
-
Fork the repository on GitHub
-
Clone your fork:
git clone https://github.com/YOUR_USERNAME/ccflare.git cd ccflare -
Add the upstream remote:
git remote add upstream https://github.com/ORIGINAL_OWNER/ccflare.git
-
Install dependencies:
bun install
-
Verify the installation:
# Run type checking bun run typecheck # Run linting bun run lint # Run formatting bun run format
The following environment variables can be used during development:
LB_STRATEGY- Override the default load balancing strategyCLIENT_ID- Set a custom OAuth client IDRETRY_ATTEMPTS- Number of retry attempts for failed requestsRETRY_DELAY_MS- Delay between retry attempts in milliseconds
Note: Most configuration is handled through the config file and CLI. Environment variables are optional overrides.
# Start the server in development mode with hot reload
bun run dev:server
# In another terminal, start the CLI
bun run dev:cli
# Or start the TUI interface
bun run dev
# Or work on the dashboard
bun run dev:dashboardNote: The project is currently in the process of setting up a comprehensive test suite. Test infrastructure is not yet implemented.
When implemented, tests will use Bun's built-in test runner:
# Run all tests
bun test
# Run tests in watch mode
bun test --watch
# Run tests for a specific package
bun test packages/coreAfter making any code changes, always run these commands before committing:
# Fix linting issues
bun run lint
# Check for type errors
bun run typecheck
# Format code
bun run formatThe project includes a CLAUDE.md file in the root directory that provides guidance to Claude Code (claude.ai/code) when working with the codebase. This file contains:
- Project overview and purpose
- Important commands to run after making changes
- Development and maintenance commands
- Project-specific guidelines
When contributing, ensure any major architectural changes or new patterns are documented in CLAUDE.md to help future AI-assisted development.
ccflare is organized as a Bun monorepo with clear separation of concerns:
ccflare/
βββ apps/ # Deployable applications
β βββ cli/ # Command-line interface
β βββ lander/ # Static landing page
β βββ server/ # Main HTTP server
β βββ tui/ # Terminal UI (Ink-based)
βββ packages/ # Shared libraries
β βββ cli-commands/ # CLI command implementations
β βββ config/ # Configuration management
β βββ core/ # Core utilities and types
β βββ core-di/ # Dependency injection
β βββ dashboard-web/ # React dashboard
β βββ database/ # SQLite operations
β βββ http-api/ # REST API handlers
β βββ load-balancer/ # Load balancing strategies
β βββ logger/ # Logging utilities
β βββ providers/ # AI provider integrations
β βββ proxy/ # Request proxy logic
β βββ tui-core/ # TUI screen components
β βββ types/ # Shared TypeScript types
βββ docs/ # Documentation
βββ biome.json # Linting and formatting config
βββ package.json # Root workspace configuration
βββ tsconfig.json # TypeScript configuration
apps/: Contains all deployable applications. Each app has its ownpackage.jsonand can be built independently.packages/: Shared code that multiple apps depend on. These are internal packages linked via Bun workspaces.docs/: Project documentation including architecture, data flow, and this contributing guide.
- Apps: Simple names (e.g.,
server,cli,tui) - Packages: Prefixed with
@ccflare/(e.g.,@ccflare/core,@ccflare/database)
We use Biome for both linting and formatting to maintain consistent code quality across the project.
-
Type Safety
- Always use explicit types for function parameters and return values
- Avoid using
any- useunknownif the type is truly unknown - Prefer interfaces over type aliases for object shapes
- Use const assertions for literal types
// Good interface Account { id: string; name: string; tier: 1 | 5 | 20; } function getAccount(id: string): Account | null { // ... } // Bad function getAccount(id: any) { // ... }
-
Async/Await
- Always use async/await instead of promises
- Handle errors with try/catch blocks
- Use Promise.all for concurrent operations
// Good async function fetchData() { try { const [accounts, requests] = await Promise.all([ getAccounts(), getRequests() ]); return { accounts, requests }; } catch (error) { logger.error('Failed to fetch data', error); throw error; } }
-
Error Handling
- Create custom error classes for domain-specific errors
- Always include context in error messages
- Use error boundaries in React components
-
Naming Conventions
- Use camelCase for variables and functions
- Use PascalCase for types, interfaces, and classes
- Use UPPER_SNAKE_CASE for constants
- Prefix boolean variables with
is,has, orshould
const MAX_RETRIES = 3; const isRateLimited = true; interface AccountStatus { hasValidToken: boolean; isActive: boolean; }
Our Biome configuration enforces:
- Tab indentation (not spaces)
- Double quotes for strings
- Organized imports (automatic with
organizeImports: "on") - All recommended Biome rules
- Consistent code formatting
Run linting and auto-fix issues with:
bun run lintNote: The lint command includes --write --unsafe flags which will automatically fix issues where possible.
-
Import Order (automatically organized by Biome):
- External packages
- Internal packages (
@ccflare/*) - Relative imports
- Type imports
-
Path Aliases:
- Use package imports for cross-package dependencies
- Use relative imports within the same package
- Avoid circular dependencies
// Good import { Database } from '@ccflare/database'; import { LoadBalancer } from '@ccflare/load-balancer'; import { formatDate } from './utils'; import type { Account } from '@ccflare/types'; // Bad import { Database } from '../../../packages/database/src';
We follow the Conventional Commits specification for our commit messages.
<type>(<scope>): <subject>
<body>
<footer>
- feat: A new feature
- fix: A bug fix
- docs: Documentation only changes
- style: Changes that don't affect code meaning (formatting)
- refactor: Code change that neither fixes a bug nor adds a feature
- perf: Performance improvements
- test: Adding or updating tests
- build: Changes to build system or dependencies
- ci: Changes to CI configuration
- chore: Other changes that don't modify src or test files
The scope should be the package or app name:
server,cli,tui,landercore,database,proxy,load-balancer, etc.
feat(load-balancer): improve session persistence
Enhances the session-based strategy to better handle failover scenarios
while maintaining session affinity. This reduces rate limit occurrences
and improves overall reliability.
Closes #123
---
fix(proxy): handle token refresh race condition
Multiple concurrent requests were causing token refresh stampedes.
Added mutex to ensure only one refresh happens at a time.
---
docs(contributing): add testing guidelines section
---
refactor(database): extract migration logic to separate module
This improves testability and makes the migration system more modular.
BREAKING CHANGE: Database.migrate() method signature has changed-
Sync with upstream:
git fetch upstream git checkout main git merge upstream/main
-
Create a feature branch:
git checkout -b feature/your-feature-name # or git checkout -b fix/bug-description
Use descriptive branch names with prefixes:
feature/- New featuresfix/- Bug fixesdocs/- Documentation updatesrefactor/- Code refactoringtest/- Test additions/updatesperf/- Performance improvements
Examples:
feature/add-openai-providerfix/rate-limit-detectiondocs/update-api-endpoints
When creating a PR, include:
## Description
Brief description of what this PR does.
## Type of Change
- [ ] Bug fix (non-breaking change which fixes an issue)
- [ ] New feature (non-breaking change which adds functionality)
- [ ] Breaking change (fix or feature that would cause existing functionality to not work as expected)
- [ ] Documentation update
## Changes Made
- List specific changes made
- Include relevant code snippets if helpful
- Mention any dependencies added or removed
## Testing
- [ ] I have run `bun run lint` and fixed all issues
- [ ] I have run `bun run format` to format the code
- [ ] I have run `bun run typecheck` and fixed all type errors
- [ ] I have added tests that prove my fix is effective or that my feature works
- [ ] New and existing unit tests pass locally with my changes
## Screenshots (if applicable)
Add screenshots for UI changes.
## Checklist
- [ ] My code follows the style guidelines of this project
- [ ] I have performed a self-review of my own code
- [ ] I have commented my code, particularly in hard-to-understand areas
- [ ] I have made corresponding changes to the documentation
- [ ] My changes generate no new warnings
- [ ] Any dependent changes have been merged and published
## Related Issues
Closes #(issue number)- Manual Checks: Run
bun run lint,bun run typecheck, andbun run formatlocally - Code Review: At least one maintainer must review and approve
- Testing: Reviewer may ask for additional tests or manual testing
- Documentation: Ensure docs are updated if needed
- Merge: Maintainer will merge using "Squash and merge"
Note: CI/CD is not yet implemented. Contributors must ensure all checks pass locally before submitting PRs. There is also no PR template in the repository yet - please follow the template provided in this guide when creating PRs.
- Delete your feature branch
- Update your local main branch
- Celebrate! π
Current Status: Test infrastructure is not yet implemented. This section describes the planned testing approach.
Tests will be co-located with the code they test:
packages/core/
βββ src/
β βββ index.ts
β βββ index.test.ts
β βββ utils.ts
β βββ utils.test.ts
βββ package.json
-
Unit Tests
- Test individual functions and classes
- Mock external dependencies
- Aim for high code coverage
- Use descriptive test names
import { describe, it, expect, mock } from 'bun:test'; import { calculateAccountWeight } from './utils'; describe('calculateAccountWeight', () => { it('should return 1 for pro tier accounts', () => { const account = { tier: 1, name: 'pro-account' }; expect(calculateAccountWeight(account)).toBe(1); }); it('should return 5 for max 5x tier accounts', () => { const account = { tier: 5, name: 'max-5x-account' }; expect(calculateAccountWeight(account)).toBe(5); }); });
-
Integration Tests
- Test interactions between modules
- Use real database for database tests
- Test API endpoints end-to-end
-
E2E Tests (when implemented)
- Test complete user workflows
- Use real browser for dashboard tests
- Test CLI commands
- Write tests before fixing bugs (regression tests)
- Keep tests focused and independent
- Use meaningful assertions
- Clean up test data after tests
- Use test fixtures for complex data
-
JSDoc Comments
- Document all public APIs
- Include parameter descriptions
- Add usage examples
/** * Selects the best account for handling a request based on the configured strategy. * * @param accounts - List of available accounts * @param strategy - Load balancing strategy to use * @returns The selected account or null if no accounts are available * * @example * const account = selectAccount(accounts, 'session'); * if (account) { * await forwardRequest(account, request); * } */ export function selectAccount( accounts: Account[], strategy: LoadBalancingStrategy ): Account | null { // ... }
-
README Files
- Each package should have a README
- Include installation, usage, and API docs
- Add examples and common patterns
-
Architecture Documentation
- Update
/docswhen adding major features - Include diagrams for complex flows
- Document design decisions
- Update
- All public APIs have JSDoc comments
- Complex algorithms have explanatory comments
- Package README is updated
- Architecture docs reflect changes
- Examples are tested and working
When adding a new feature, follow this checklist:
- Create an issue describing the feature
- Discuss implementation approach with maintainers
- Identify which packages will be affected
- Consider backward compatibility
- Create feature branch from latest main
- Implement feature following coding standards
- Add unit tests (aim for >80% coverage)
- Add integration tests if applicable
- Update TypeScript types
- Handle errors gracefully
- Add JSDoc comments to new functions
- Update package README if needed
- Update architecture docs for significant changes
- Add usage examples
- Run all tests locally
- Test manually in development environment
- Test with different configurations
- Verify no performance regressions
- Self-review your code
- Run linting and formatting
- Ensure all CI checks pass
- Create PR with detailed description
- Monitor for any issues
- Update related issues
- Help with any user questions
We use semantic versioning (SemVer):
- Major (X.0.0): Breaking changes
- Minor (0.X.0): New features (backward compatible)
- Patch (0.0.X): Bug fixes
-
Prepare Release
# Update version in package.json files # Create/Update CHANGELOG.md (if not exists, create following Keep a Changelog format) git checkout -b release/vX.Y.Z
-
Create Release PR
- Title:
Release vX.Y.Z - Include changelog in description
- Get approval from maintainers
- Title:
-
Merge and Tag
git checkout main git pull upstream main git tag -a vX.Y.Z -m "Release version X.Y.Z" git push upstream vX.Y.Z -
Create GitHub Release
- Use the tag
- Copy changelog entries
- Attach built binaries if applicable
-
Post-Release
- Announce in discussions/Discord
- Update documentation site
- Monitor for issues
Note: There is no CHANGELOG.md file in the repository yet. When implementing releases, create and maintain a CHANGELOG.md file following the Keep a Changelog format.
For critical fixes:
- Create patch from the release tag
- Follow expedited review process
- Release as patch version
If you need help:
- Documentation: Check the
/docsfolder - Issues: Search existing issues
- Discussions: Start a GitHub discussion
- Discord: Join our community (if applicable)
Contributors are recognized in:
- GitHub contributors page
- Release notes
- Project README (for significant contributions)
The CLI functionality is integrated into the TUI application. Use ccflare with command-line flags:
# If ccflare is not installed globally, use:
# bun run tui [options]
# or build and run with: bun run ccflare
# Add a new account
ccflare --add-account <name>
# With options:
ccflare --add-account <name> --mode <max|console> --tier <1|5|20>
# List all accounts
ccflare --list
# Remove an account
ccflare --remove <name>
# Pause/resume accounts
ccflare --pause <name>
ccflare --resume <name>
# Reset usage statistics
ccflare --reset-stats
# Clear request history
ccflare --clear-history
# View statistics (JSON output)
ccflare --stats
# Stream logs
ccflare --logs [N] # Show N lines of history then follow
# Analyze database performance
ccflare --analyze
# Start server with dashboard
ccflare --serve --port 8080
# Show help
ccflare --help# Start the production server (port 8080)
bun run server
# or
bun run start
# or
bun start
# Start the server with hot reload
bun run dev:server# Build the dashboard
bun run build:dashboard
# Run dashboard in development mode
bun run dev:dashboard# Run the TUI application
bun run tui
# or
bun run dev
# or (builds first, then runs)
bun run ccflare
# Build the TUI
bun run build:tui# Build all applications
bun run build
# Build specific applications
bun run build:dashboard
bun run build:tui
bun run build:lander- TypeScript errors: Run
bun run typecheckto identify issues - Formatting issues: Run
bun run formatto auto-fix - Import errors: Ensure you're using workspace imports (
@ccflare/*) for cross-package dependencies - Database issues: The SQLite database is created automatically in the data directory
Thank you for contributing to ccflare! Your efforts help make Claude AI more accessible to everyone.