Release v0.14.0
OpenAI Responses API + Hook Skip + Diff Rename Detection
Adds OpenAI Responses API support with streaming, a strip_thinking option for all providers, GCOP_SKIP_HOOK to bypass prepare-commit-msg hooks, rename-aware diff parsing, and dependency upgrades.
Added
OpenAI Responses API
- New
api_style = "openai-response"sends prompts to/v1/responsesinstead of/v1/chat/completions; maps system prompt →instructions, user prompt →input,max_tokens→max_output_tokens - Streaming support via
process_openai_responses_stream()with typed SSE events (response.output_text.delta,response.completed,response.failed,response.incomplete) - Full error handling: API errors, incomplete responses, parse-error counting with truncated-stream detection
- CI mode:
GCOP_CI_PROVIDER = "openai-response"now accepted
strip_thinking Option
strip_thinking = truein any provider config removes<thinking>...</thinking>and<think>...</think>blocks from generated commit messages and review JSONLLMProvidertrait gainsstrip_thinking()method; all four providers (Claude, OpenAI, Ollama, Gemini) read it fromextraconfig- FallbackProvider respects per-provider
strip_thinkingfor both streaming and non-streaming paths process_commit_response_with_options()andprocess_review_response_with_options()replace the old always-strip defaults; default behavior now preserves thinking tags
GCOP_SKIP_HOOK
GCOP_SKIP_HOOK=1environment variable skipsgcop-rs hook runat three levels: shell hook script, Rust hook runner, and CLI entry pointcommit_changes()andcommit_amend_changes()setGCOP_SKIP_HOOK=1to avoid double-processing when gcop-rs itself invokesgit commit
Hook Install --force Refresh
gcop-rs hook install --forcenow refreshes an existing gcop-rs hook (previously only overrode non-gcop hooks)
Changed
Diff Parsing
extract_filename_from_diff_header()returns the new path (b/) instead of the old path (a/) for renames — matching the file that must be staged- Quoted path handling rewritten to parse the right-hand
"b/..."argument for filenames containing spaces parse_diff_stats()andsplit_diff_by_file()use hunk-aware@@tracking so---/+++lines inside diff hunks are counted correctlyget_staged_diff()enables git similarity detection (DiffFindOptions) for rename and copy detection in staged diffs
Git Repository
stage_files()passesgit add -A --before file paths to handle deletions and renames;--separates paths from options to prevent injectionunstage_all()in empty repos checks for staged files first, avoidinggit rm --cachederrors on a bare indexget_staged_diff()force-reloads the index before diffing so externalstage_files()calls are visibleresolve_commit_trees()extracted to deduplicate commit/parent tree lookups acrossget_commit_diff(),get_commit_line_stats(), etc.
Stats
- Author sort stabilized with tie-breaks: primary by commit count descending, then name ascending, then email ascending
compute_contrib_stats()counts merge commits from the author-filtered scope instead of the full commit list- Author filtering extracted into reusable
filter_commits_by_author(),author_matches_filter(),commit_matches_author_filter()functions
Dependencies
git20.20 → 0.21rust-i18n3.1 → 4.0tokio1.50 → 1.52toml1.0 → 1.1human-panic2.0.6 → 2.0.8- Removed unused dependencies:
cesu8,iri-string,pin-utils
Documentation
initstep 2 now says "Use gcop-rs config to add your API key" instead of pointing to the Anthropic console- Provider docs updated with
api_style = "openai-response"examples andstrip_thinkingconfiguration - Config examples (
examples/config.toml.example,.zh) updated with new provider and option
Tests
tests/git_commit_test.rs: hook skip, amend commit count, amend without existing committests/stats_contrib_test.rs: merge count respects author filter;DirGuardRAII pattern replaces manualset_current_dirrestoretests/stats_test.rs: author sort tiebreaks by name and emailsrc/commands/hook.rs: hook script contains skip guard, force refresh testsrc/git/repository.rs: rename detection, dash-prefixed paths, deletion staging, empty repo unstagesrc/git/diff.rs: rename new path, quoted rename, hunk-level header countingsrc/llm/provider/fallback.rs: strip thinking per-provider in generate/commitsrc/llm/provider/base/response.rs: thinking preserved by default, stripped when enabledsrc/main.rs: skip hook before config loadsrc/config/tests.rs: CI mode with openai-response provider
Upgrade
bash
# Homebrew
brew upgrade gcop-rs
# Cargo
cargo install gcop-rs
# pip
pip install --upgrade gcop-rs