Metadata-Version: 2.4
Name: acw
Version: 0.5.0
Summary: The CLI tool for generating AI commit messages from git changes
Author: bossm0n5t3r
Author-email: bossm0n5t3r <bossm0n5t3r@gmail.com>
License-Expression: MIT
License-File: LICENSE
Requires-Dist: httpx>=0.28.1
Requires-Dist: litellm>=1.83.0
Requires-Dist: msgspec>=0.21.1
Requires-Dist: questionary>=2.1.1
Requires-Dist: rich==14.3.3
Requires-Dist: aiohttp>=3.13.4
Requires-Dist: python-dotenv>=1.2.2
Requires-Python: >=3.11
Description-Content-Type: text/markdown

# ACW (Auto Commit Wizard)

Git 변경사항을 읽어 AI 커밋 메시지를 생성하고, 필요하면 바로 `git commit`까지 실행하는 Python CLI 도구입니다.

ACW는 `litellm`을 통해 OpenAI, Anthropic, Google Gemini 같은 원격 provider와 Ollama, LM Studio 같은 로컬 provider를 지원합니다.

## 주요 기능

- `acw config` 설정 마법사: provider, model, API key 환경변수, 출력 언어, 메시지 포맷, timeout 설정
- `staged diff` 기본 수집, `stash` 또는 특정 `ref` 기준 diff 수집
- `plain`, `conventional`, `gitmoji` 포맷별 기본 프롬프트 제공
- `ko`/`en` 언어별 프롬프트 템플릿 관리 및 팀 규칙 확장/덮어쓰기
- Ollama/LM Studio 연결 및 모델 가용성 진단
- 여러 후보 생성, 대화형 선택/재생성, 재생성 방향 추가 입력, JSON 출력, 파일 저장, 클립보드 복사
- 대화형 터미널에서 선택한 메시지로 실제 `git commit` 생성

## 요구 사항

- Python 3.11+
- Git
- [uv](https://github.com/astral-sh/uv) 권장
- 원격 provider 사용 시 해당 provider의 API key
- 로컬 provider 사용 시 실행 중인 Ollama 또는 LM Studio 서버

## 설치

PyPI 배포 버전 설치:

```bash
uv tool install acw
```

개발용 실행:

```bash
uv sync
uv run acw --help
```

## 빠른 시작

처음에는 설정 마법사를 실행합니다.

```bash
acw config
```

변경사항을 staged 상태로 만든 뒤 메시지를 생성합니다.

```bash
git add <files>
acw generate --dry-run
```

참고:

- `acw`에 서브커맨드를 생략하면 `acw generate`로 동작합니다.
- 기본 입력은 `git diff --cached`입니다. `--from-stash`, `--from-ref`를 쓰지 않으면 staged 파일이 필요합니다.
- 대화형 터미널에서 `--dry-run`, `--json`, `--output` 없이 실행하면 메시지 확인 후 실제 `git commit`을 만들 수 있습니다.
- API key가 없고 대화형 터미널이면 `generate`가 설정 마법사를 시작할 수 있습니다.

## 명령어

### `acw generate`

Git diff를 수집해 커밋 메시지를 생성합니다.

```bash
acw generate [options]
```

주요 옵션:

- `-p, --provider`: provider 지정. 예: `openai`, `anthropic`, `google`, `ollama`, `lmstudio`
- `-m, --model`: 모델명 지정
- `-P, --profile`: 저장된 profile 사용
- `-t, --prompt`: 저장된 프롬프트 이름 사용
- `-F, --prompt-file`: 프롬프트 파일 직접 사용. `--prompt`보다 우선합니다.
- `--print-prompt`: 최종 프롬프트 출력
- `-l, --language {ko,en}`: 출력 언어
- `-f, --format {plain,conventional,gitmoji}`: 메시지 포맷
- `-g, --generate`: 후보 개수
- `--from-stash`: stash 기준 diff 사용
- `--from-ref`: ref 기준 diff 사용
- `-x, --exclude`: 제외 glob 패턴. 반복 가능
- `-s, --max-diff-size`: diff 최대 바이트. 초과 시 대화형 확인 또는 `--yes`로 잘라서 진행
- `-y, --yes`: 확인 프롬프트 생략
- `-d, --dry-run`: 실제 커밋 없이 메시지만 생성
- `-j, --json`: JSON 출력. `--print-prompt`와 함께 사용할 수 없습니다.
- `-o, --output`: 선택된 메시지를 파일로 저장
- `-c, --clipboard`: 선택된 메시지를 클립보드로 복사
- `-n, --no-verify`: 커밋 시 `git commit --no-verify` 사용
- `-a, --all`: 커밋 시 `git commit -a` 사용

대화형 재생성:

- 생성된 메시지를 확인한 뒤 `Accept`, `Retry`, `Retry with instruction` 중 하나를 선택할 수 있습니다.
- `Retry with instruction`을 선택하면 "더 짧게", "scope 포함", "테스트 변경 강조"처럼 다음 생성에만 적용할 추가 방향을 입력할 수 있습니다.
- 두 번 이상 생성한 뒤에는 `History`로 이전 생성 결과를 다시 선택할 수 있습니다.

예시:

```bash
# staged 변경사항으로 메시지만 생성
acw generate --dry-run

# 서브커맨드 생략
acw --dry-run --yes

# 후보 3개 생성
acw generate --generate 3 --dry-run

# Conventional Commit 형식으로 영어 메시지 생성
acw generate --format conventional --language en --dry-run

# 특정 브랜치/커밋 기준 diff 사용
acw generate --from-ref origin/master --dry-run

# stash 기준 diff 사용
acw generate --from-stash 'stash@{0}' --dry-run

# 큰 파일 또는 잠금 파일 제외
acw generate --exclude '*.lock' --exclude 'dist/*' --dry-run

# JSON 출력
acw generate --json --dry-run

# 메시지를 파일로 저장
acw generate --output .git/COMMIT_EDITMSG

# 로컬 Ollama 모델 사용
acw generate --provider ollama --model llama3.1 --dry-run
```

> [!CAUTION]
> 원격 provider를 사용하면 수집된 Git diff가 외부 LLM API로 전송됩니다.
> secret, 고객 정보, 비공개 코드가 포함된 변경사항은 커밋 전에 제거하거나 `--exclude`로 제외하세요.
> 외부 전송을 원하지 않으면 Ollama/LM Studio 같은 로컬 provider를 사용하세요.

### `acw config`

설정 마법사를 실행하거나 ACW 설정 디렉터리를 삭제합니다.

```bash
acw config
acw config --delete
acw config --delete --yes
```

설정 마법사는 다음 값을 저장합니다.

- 기본 provider/model
- 기본 출력 언어(`ko`, `en`)
- 기본 포맷(`plain`, `conventional`, `gitmoji`)
- provider별 API key 환경변수 이름
- provider별 base URL과 timeout

### `acw prompt`

프롬프트 템플릿을 조회/저장/동기화합니다.

```bash
# 저장된 프롬프트 목록
acw prompt --list

# 언어별 builtin 프롬프트 확인
acw prompt --name conventional --language ko --show

# 팀 규칙 프롬프트 저장
acw prompt --name team --language ko --set "팀 규칙을 반영해 한 줄로 작성"

# 파일에서 프롬프트 저장
acw prompt --name team --language ko --file ./prompt.md

# builtin 프롬프트를 현재 버전 기본값으로 갱신
acw prompt --sync
```

프롬프트 이름은 `A-Za-z0-9._-` 형식을 사용합니다. 언어를 지정하면 `~/.config/acw/prompts/<name>.<language>.md`에 저장됩니다.

사용자 프롬프트는 기본적으로 선택한 포맷 프롬프트 뒤에 추가됩니다. 파일 첫 줄에 `!override`를 쓰면 builtin 포맷 프롬프트를 사용하지 않고 해당 내용만 사용합니다.

### `acw doctor`

로컬 provider(`ollama`, `lmstudio`)의 서버 연결과 설정된 모델 존재 여부를 확인합니다.

```bash
acw doctor --provider ollama
acw doctor --provider lmstudio --timeout 60
acw doctor --provider ollama --model llama3.1
acw doctor --profile local
```

`doctor`는 설정 해석 결과(provider, model, base_url, API key 환경변수 상태)를 출력한 뒤 로컬 서버의 모델 목록을 확인합니다.

## 설정

기본 설정 디렉터리:

```text
~/.config/acw
```

환경변수로 변경:

```bash
export ACW_CONFIG_DIR=/path/to/acw-config
```

생성되는 주요 파일/디렉터리:

```text
config.toml
prompts/*.md
profiles/*.toml
```

기본 `config.toml` 구조:

```toml
[defaults]
provider = "openai"
model = "gpt-4.1-mini"
profile = ""
language = "ko"
format = "plain"
prompt = "default"

[provider_env]
openai = "OPENAI_API_KEY"
anthropic = "ANTHROPIC_API_KEY"
google = "GEMINI_API_KEY"
openrouter = "OPENROUTER_API_KEY"
xai = "XAI_API_KEY"
groq = "GROQ_API_KEY"
deepseek = "DEEPSEEK_API_KEY"
cohere = "COHERE_API_KEY"

[provider_base_url]
ollama = "http://localhost:11434"
lmstudio = "http://localhost:1234/v1"

[provider_timeout]
ollama = 30.0
lmstudio = 30.0
```

Profile은 `profiles/<name>.toml`에 저장합니다.

```toml
[profile]
provider = "ollama"
model = "llama3.1"
language = "ko"
format = "plain"
```

실행 시 우선순위는 CLI 옵션 > profile > `config.toml` defaults > 내장 기본값입니다.

## Provider와 API key

기본 API key 환경변수 매핑:

- OpenAI: `OPENAI_API_KEY`
- Anthropic: `ANTHROPIC_API_KEY`
- Google Gemini: `GEMINI_API_KEY`
- OpenRouter: `OPENROUTER_API_KEY`
- xAI: `XAI_API_KEY`
- Groq: `GROQ_API_KEY`
- DeepSeek: `DEEPSEEK_API_KEY`
- Cohere: `COHERE_API_KEY`

Ollama와 LM Studio는 기본적으로 API key 없이 동작합니다. 필요하면 `[provider_env]`에 `ollama = "OLLAMA_API_KEY"`처럼 명시할 수 있습니다.

## 개발

테스트:

```bash
uv run pytest
```

타입 체크:

```bash
uv run pyright
```
