Contributing
Prerequisites
Section titled “Prerequisites”- Bun 1+ (primary runtime for development)
- Claude Code installed globally
- Git
Clone and install
Section titled “Clone and install”git clone https://github.com/hmziqrs/claude-multi.gitcd claude-multibun installProject structure
Section titled “Project structure”src/├── cli.ts # Commander.js CLI entry point + interactive mode├── config.ts # Core config management (instances, plugins, MCP, symlinks)├── templates.ts # Provider templates (env vars, model mappings)├── constants.ts # Shared string constants├── errors.ts # Standardized error system (ClaudeMultiError + ErrorCode)├── health.ts # Health check system├── migration.ts # Config version migration with backups and locking├── wrapper.ts # Wrapper script generation (shell/batch)├── version.ts # Version checking and update logic├── paths.ts # Base directory resolution├── util/│ ├── json-file.ts # Atomic JSON file writes│ └── runtime.ts # Package manager detection├── ink/ # Ink-based Terminal UI│ ├── App.tsx # Root app: menu, screen routing, keyboard input│ ├── main.tsx # Ink render entry point│ ├── components/ # Reusable UI components│ ├── screens/ # TUI screens (AddInstance, ListInstances, etc.)│ └── hooks/ # Custom hooks (useConfig, useHealthCheck, etc.)└── web/ # Astro docs site (this site) ├── content/ # Starlight docs + blog + FAQ └── pages/ # Marketing page, static pages# Build the CLIbun run build
# Build the Ink TUI (separate bundle)bun run build:ink
# Build the docs sitebun run docs:build# Run all testsbun test
# Run a specific test filebun test test/config.test.ts
# Run tests matching a patternbun test --grep "symlink"The test suite has 155+ tests across 16 files covering config management, plugin operations, health checks, migration, wrapper generation, Ink components, CLI commands, and end-to-end flows.
Tests use CLAUDE_MULTI_HOME to isolate from your real config, they create temporary directories and clean up after themselves.
Lint and typecheck
Section titled “Lint and typecheck”# TypeScript checkbun run typecheck
# Lintbun run lintRun locally
Section titled “Run locally”# Run the CLI directly from sourcebun src/cli.ts
# Run with the Ink TUIbun src/ink/main.tsx
# Run the docs dev serverbun run docs:devArchitecture notes
Section titled “Architecture notes”Wrapper-based isolation: Each instance gets a shell script that sets CLAUDE_CONFIG_DIR and execs the real claude binary. No forking, no patching.
Atomic writes: Config files are written using a temp-file-rename pattern with JSON verification. See src/util/json-file.ts.
Security: Settings copy from ~/.claude uses a whitelist, only safe fields are transferred. The env block (containing API keys) is never copied.
Error handling: All thrown errors use ClaudeMultiError with a machine-readable ErrorCode. Catch blocks use unknown typing, no (err as Error) casts.
String constants: Bare string literals used in comparisons are replaced with typed constants in src/constants.ts.
The project uses GitHub Actions for:
- ci.yml, Cross-platform build + test on push to master and PRs
- publish.yml, npm publish with OIDC trusted publishing
- deploy-docs.yml, Docs site deployment to Cloudflare Pages
- test-install.yml, Cross-platform install verification (bun/node/deno × Linux/Windows/macOS)
Adding a provider template
Section titled “Adding a provider template”- Open
src/templates.ts - Add a new entry to the
providerTemplatesobject following the existing pattern - Set
name,displayName,description, and thesettings.envblock - Run tests:
bun test - Update the provider table in
src/web/content/docs/docs/providers.md
Submitting changes
Section titled “Submitting changes”- Fork the repo
- Create a feature branch from
master - Make your changes
- Run
bun testandbun run typecheck - Open a PR against
master
License
Section titled “License”MIT. See LICENSE.