Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
63 changes: 63 additions & 0 deletions .committy/config.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
[repository]
name = "committy"
type = "multi-package"
description = "Generate clear, concise, and structured commit messages effortlessly"

[versioning]
strategy = "hybrid"

[[packages]]
name = "committy-cli"
type = "rust-cargo"
path = "."
version_file = "Cargo.toml"
version_field = "package.version"
primary = true
description = "Main CLI application"

[[packages]]
name = "mcp-server"
type = "node-npm"
path = "mcp-server-committy"
version_file = "package.json"
version_field = "version"
sync_with = "committy-cli"
description = "MCP server wrapper for Committy"

[[packages]]
name = "docs"
type = "node-npm"
path = "docs"
version_file = "package.json"
version_field = "version"
independent = true
description = "Documentation site"

[scopes]
auto_detect = true
require_scope_for_multi_package = true
allow_multiple_scopes = true
scope_separator = ","

[[scopes.mappings]]
pattern = "src/**"
scope = "core"
package = "committy-cli"
description = "Core CLI code"

[[scopes.mappings]]
pattern = "mcp-server-committy/**"
scope = "mcp"
package = "mcp-server"
description = "MCP server code"

[[scopes.mappings]]
pattern = "docs/**"
scope = "docs"
package = "docs"
description = "Documentation"

[commit_rules]
max_subject_length = 72
max_body_line_length = 100
require_body = false
6 changes: 6 additions & 0 deletions .dockerignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
.git
target
mcp-server-committy/node_modules
mcp-server-committy/dist
docs/node_modules
docs/dist
73 changes: 17 additions & 56 deletions .github/workflows/lint.yml
Original file line number Diff line number Diff line change
Expand Up @@ -2,70 +2,31 @@ name: Rust

on:
push:
branches: [ main, develop ]
branches: [main, develop]
pull_request:
branches: [ "*"]
branches: ["*"]

env:
CARGO_TERM_COLOR: always

jobs:
lint-and-test:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Install Rust
uses: actions-rs/toolchain@v1.0.7
with:
profile: minimal
toolchain: stable
override: true
components: rustfmt, clippy
- name: Check formatting
run: cargo fmt -- --check
- name: Lint with clippy
run: cargo clippy -- -D warnings
- name: Run tests
run: cargo test -- --test-threads=1
- name: Smoke test lint-message CLI
run: |
cargo run -- --non-interactive lint-message --message "feat: CI smoke test for lint-message"

mcp_ts:
runs-on: ubuntu-latest
defaults:
run:
working-directory: mcp-server-committy
steps:
- uses: actions/checkout@v4
- uses: actions/setup-node@v4
- name: Install Rust
uses: actions-rs/toolchain@v1.0.7
with:
node-version: 20
cache: npm
cache-dependency-path: mcp-server-committy/package-lock.json
- name: Install dependencies
run: npm ci
- name: Typecheck
run: npm run typecheck
- name: Build
run: npm run build
- name: Run unit tests
run: npm test --if-present

# docs_build:
# runs-on: ubuntu-latest
# defaults:
# run:
# working-directory: docs
# steps:
# - uses: actions/checkout@v4
# - uses: actions/setup-node@v4
# with:
# node-version: 20
# registry-url: 'https://registry.npmjs.org'
# cache: npm
# cache-dependency-path: docs/package-lock.json
# - name: Install dependencies
# run: npm install
# - name: Build docs
# run: npm run build
profile: minimal
toolchain: stable
override: true
components: rustfmt, clippy
- name: Check formatting
run: cargo fmt -- --check
- name: Lint with clippy
run: cargo clippy -- -D warnings
- name: Run tests
run: cargo test -- --test-threads=1
- name: Smoke test lint-message CLI
run: |
cargo run -- --non-interactive lint-message --message "feat: CI smoke test for lint-message"
12 changes: 12 additions & 0 deletions .github/workflows/native-git-verification.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
name: Native Git Verification

on:
workflow_dispatch:

jobs:
native-git-e2e:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Run native git Docker verification
run: ./scripts/verify_native_git_e2e.sh
165 changes: 165 additions & 0 deletions AGENTS.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,165 @@
# AGENTS.md

This file provides guidance to Codex (Codex.ai/code) when working with code in this repository.

## Overview

Committy is a Rust CLI tool for generating structured, conventional commit messages compatible with SemVer. It supports interactive and non-interactive modes, commit linting, semantic versioning via tags, AI-assisted commit messages, and group commits.

## Essential Commands

### Build and Test
```bash
# Build the project
cargo build

# Run all tests
cargo test

# Run a specific test
cargo test test_name

# Run tests with verbose output
cargo test -- --nocapture
```

### Running the CLI
```bash
# Run from source
cargo run

# Run with arguments
cargo run -- <subcommand> [options]

# Examples
cargo run -- commit
cargo run -- amend
cargo run -- tag --dry-run
cargo run -- lint --output json

# NEW: Interactive TUI mode
cargo run -- tui
cargo run -- tui --ai # With AI assistance
```

### Development
```bash
# Check code without building
cargo check

# Format code
cargo fmt

# Run linter
cargo clippy
```

## Architecture

### Module Structure

**TUI Layer** (`src/tui/`) - NEW!
- `app.rs`: Main TUI application loop and event handling
- `state.rs`: Application state management (files, commits, groups)
- `event.rs`: Keyboard/mouse event handling
- `ui/`: UI components
- `file_list.rs`: File staging/selection interface
- `commit_form.rs`: Commit message input form
- `group_view.rs`: Auto-grouped commits view
- `help.rs`: Help overlay
- Built with `ratatui` (modern fork of `tui-rs 0.19`)
- Features:
- Interactive file staging/unstaging
- Auto-grouping changes by type (docs, tests, ci, deps, code)
- Multi-commit workflow support
- Diff preview
- Real-time UI updates

**CLI Layer** (`src/cli/`)
- `commands/`: Individual command implementations (commit, amend, tag, lint, lint_message, branch, group_commit, tui)
- Each command implements the `Command` trait with `execute(&self, non_interactive: bool)` method
- Commands are defined via `StructOpt` for argument parsing

**Git Operations** (`src/git/`)
- `repository.rs`: Core git operations (staged changes, file listing, config validation)
- `commit.rs`: Commit creation and message formatting
- `tag.rs`: Tag generation with `TagGenerator` and `TagGeneratorOptions`
- `branch.rs`: Branch operations

**Configuration** (`src/config.rs`)
- Config file location: `~/.config/committy/config.toml`
- Override via `COMMITTY_CONFIG_DIR` environment variable
- Contains:
- `major_regex`, `minor_regex`, `patch_regex`: Configurable regex patterns for semver bump detection
- `metrics_enabled`: Telemetry toggle
- `last_update_check`, `last_metrics_reminder`: Timestamps
- `user_id`: Anonymous UUID for metrics

**Linting** (`src/linter/`)
- Validates conventional commit format
- Used by `lint` and `lint_message` commands
- Returns structured error information

**Version Management** (`src/version/`)
- `VersionManager`: Handles version updates across multiple file types
- Supports Cargo.toml, package.json, pyproject.toml, composer.json, pom.xml, *.csproj
- Called during tag creation to automatically bump version files

**AI Integration** (`src/ai/`)
- Supports OpenRouter and Ollama providers
- Used in `group_commit` command when `--ai` flag is provided
- Generates commit message suggestions based on diffs

**Input/Prompts** (`src/input/`)
- Interactive prompt handling via `inquire` crate
- Input validation for commit messages, scopes, ticket names
- Handles non-interactive mode gracefully

**Error Handling** (`src/error.rs`)
- `CliError`: Central error type for all CLI operations
- Special exit code `3` for lint issues (distinct from general errors)

### Key Flow: Tag Command

1. `TagCommand::execute()` in `src/cli/commands/tag.rs`
2. Creates `TagGenerator` with options (dry-run, fetch, publish)
3. `TagGenerator::generate_and_create_tag()`:
- Fetches tags from remote (unless `--no-fetch`)
- Gets latest tag
- Analyzes commits since last tag using regex patterns from config
- Determines version bump (major/minor/patch)
- Updates version files via `VersionManager`
- Creates git tag (unless `--dry-run`)
- Publishes tag to remote (unless `--not-publish`)

### Key Flow: Group Commit

1. `GroupCommitCommand::execute()` in `src/cli/commands/group_commit.rs`
2. Groups changed files by type (docs, tests, ci, deps, build, chore, code)
3. In "plan" mode: outputs JSON with suggested commits per group
4. In "apply" mode: creates commits for each group (optionally with AI-generated messages)
5. Optionally pushes commits after creation

### Non-Interactive Mode

- Enabled via `--non-interactive` flag, `COMMITTY_NONINTERACTIVE=1`, or `CI=1`
- All commands support non-interactive mode
- Prompts are skipped; sensible defaults or errors are used

### Build System

- `build.rs`: Injects `SENTRY_DSN` and `POSTHOG_API_KEY` at compile time from environment variables
- Defaults to "undefined" if not set

## Testing

- Tests located in `tests/` directory
- Integration tests use `assert_cmd` for CLI testing
- Many tests require git repositories, use `tempfile` for temporary test repos
- Tests using shared state are marked with `serial_test::serial`

## Contributing Notes

- PRs should target the `develop` branch, not `main`
- Commit messages should follow conventional commit format
- Version is managed in `Cargo.toml` and bumped via the `tag` command
Loading
Loading