- Fork and clone the repository.
- Install dependencies:
npm install
- Build the project:
npm run build
- Run a smoke test:
node dist/index.js --help
- TypeScript source lives in
src/. - Run
npm run buildto compile – no separate dev server needed. - Before opening a PR, ensure the project builds cleanly.
- Run
npm testto run all the test cases. - Project uses Node.js's built-in node:test framework for testing.
- Test files are located in
tests/andtests/e2e/. - E2E tests spin up a local HTTP server and create real Git repositories during execution. As a result, they may take longer to run than unit tests.
src/
├── index.ts # CLI entry point (Commander) — registers all commands
├── types.ts # Shared TypeScript interfaces (Config, Provider, Suggestion, etc.)
├── commands/
│ ├── init.ts # Interactive setup wizard (clack/prompts) — provider, model, API key
│ ├── suggest.ts # Core suggestion flow: diff → LLM → display → optional commit
│ ├── history.ts # View learned style profile and recent commit history
│ ├── config.ts # View and set current config
│ ├── batch.ts # Process multiple git repos in batch mode
│ └── completion.ts # Generate shell completion scripts (bash, zsh, fish)
├── providers/
│ ├── index.ts # Provider factory: createProvider(), complete(), completeStream(), fetchModels()
│ ├── registry.ts # BUILTIN_PROVIDERS array (OpenAI, Anthropic, Google, Mistral, etc.)
│ ├── openai-compatible.ts # Default adapter for OpenAI-compatible APIs (most providers)
│ ├── anthropic.ts # Anthropic-specific adapter (Messages API)
│ ├── cohere.ts # Cohere-specific adapter
│ ├── example.ts # No-op example provider for testing
│ ├── request.ts # Shared HTTP request helpers
│ └── sse.ts # Server-Sent Events streaming parser
├── llm/
│ ├── client.ts # generateSuggestions() — orchestrates config → prompt → LLM → parse
│ └── prompt.ts # buildSystemPrompt(), buildUserPrompt(), template vars, diff truncation
├── git/
│ ├── diff.ts # Git ops: getStagedDiff(), getUnstagedDiff(), commit(), checkGitRepo()
│ └── hook.ts # Git hook management: prepare-commit-msg, post-commit
├── history/
│ └── store.ts # JSONL history: loadEntries(), appendEntry(), buildProfile(), formatProfile()
└── config/
└── store.ts # Config persistence: loadConfig(), saveConfig(), env var overrides
- Style: Minimal, no comments unless necessary. Match the existing code style.
- Imports: Use ESM
importsyntax ("type": "module"). - Formatting: Prettier is configured via
.prettierrc. Runnpm run formatto auto-format the supported source files, ornpm run format:checkto verify formatting in CI. - No linter is configured – review your own diffs carefully.
- Create a feature branch from
main. - Make your changes and verify
npm run buildsucceeds. - Keep PRs focused – one feature or fix per PR.
- Write a clear, concise PR description explaining what and why.
When opening an issue, use the closest template from .github/ISSUE_TEMPLATE/:
- Bug report for reproducible defects
- Feature request for product or workflow improvements
- Good first issue for small, newcomer-friendly tasks with clear acceptance criteria
- Create a file in
src/providers/implementing the provider interface fromsrc/types.ts. - Add a new entry to the
BUILTIN_PROVIDERSarray insrc/providers/registry.tswith the following fields:key: Unique identifier (e.g.,my-provider)name: Display name (e.g.,My Provider)baseUrl: API base URLapiKeyEnv: Environment variable name for the API key (e.g.,MY_PROVIDER_API_KEY)website: Provider website URLdocsUrl: Provider documentation URLneedsApiKey:trueif an API key is required,falsefor local providers like Ollama
- Add any needed configuration keys in
src/config/.
By contributing, you agree that your contributions will be licensed under the MIT License.