5 Commits
Author SHA1 Message Date
Prad Nukala 0acee0a694 fix: restore Groq default model with bundled crush provider
openrouter/qwen/qwen3.6-27b is not resolvable in Crush; the qwen model
only exists on Groq. Re-apply the 735229b provider fix: default to
groq/openai/gpt-oss-120b (verified live on Groq /openai/v1/models) via
the bundled crush-provider config, applied through CRUSH_GLOBAL_CONFIG
only when the default model is in use.
2026-08-18 14:32:41 -04:00
Prad Nukala 3086dac5d6 refactor: replace Go binary with uv-run smartcommit.py launcher
The extension is now a bash launcher that runs smartcommit.py via
uv run --script (Crush backend, DuckDB scopes). Removes the Go
implementation and the gh-extension-precompile workflow; the bundled
gh-commit.tar.gz now packages the script instead of a compiled binary.
2026-08-18 14:26:07 -04:00
Prad Nukala f1302fd1ec Revert "fix: provider"
This reverts commit 735229b150.
2026-08-17 18:06:54 -04:00
Prad Nukala ae36a7052d build: package v3.0.0 binary tarball
Replaces the old Python source tarball with the compiled linux/amd64
binary (CGO-free, stripped) plus README and LICENSE.
2026-08-15 19:12:44 -04:00
t 9647c854c9 feat: rewrite gh-commit in Go with local Ollama backend
Replaces the Python/Crush/DuckDB implementation with a CGO-free Go binary:
cobra CLI, modernc.org/sqlite storage, huh/lipgloss UI, and speed-tuned raw
/api/generate calls (think:false, keep_alive, capped num_predict) against a
local qwen3.5:2b. Ships as a gh extension via cli/gh-extension-precompile.
2026-08-15 19:10:16 -04:00
7 changed files with 78 additions and 70 deletions
-2
View File
@@ -1,2 +0,0 @@
/.omc
/__pycache__
+21
View File
@@ -0,0 +1,21 @@
MIT License
Copyright (c) 2025 Prad
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
+51 -51
View File
@@ -1,6 +1,11 @@
# gh-commit # gh-commit
AI-powered scoped git commits. Groups changes by project area, generates commit messages with `crush run`, and pushes — all in one command. AI-powered scoped git commits as a GitHub CLI extension, driven by the
[Crush](https://github.com/charmbracelet/crush) CLI. Scopes map Conventional
Commit scope names to path prefixes. They are generated from the repository
file tree, stored in a local DuckDB database, and auto-regenerate whenever
`.gitignore` changes. Changed files are grouped by scope and committed one
scope at a time with generated `type(scope): message` subjects.
## Install ## Install
@@ -14,61 +19,31 @@ gh extension install prdlk/gh-commit
- [Crush](https://github.com/charmbracelet/crush) — non-interactive AI runner - [Crush](https://github.com/charmbracelet/crush) — non-interactive AI runner
- `GROQ_API_KEY` — authenticates the default Groq model - `GROQ_API_KEY` — authenticates the default Groq model
By default, gh-commit uses Groq's `openai/gpt-oss-120b`. Override the model with `GH_COMMIT_CRUSH_MODEL`. By default, gh-commit uses Groq's `openai/gpt-oss-120b` via the bundled `crush-provider` config. Override the model with `GH_COMMIT_CRUSH_MODEL`.
## Usage ## Usage
```sh ```sh
# Initialize scopes for your repo (uses Crush to analyze structure) cd your-repo
gh commit init gh commit init # generate scopes for this repo
gh commit # commit changes grouped by scope
# Commit changes grouped by scope
gh commit
# Auto-confirm + auto-push
gh commit --auto --push
# Manually refresh scopes after structural changes
gh commit refresh
# Sync scopes as GitHub labels
gh commit sync
``` ```
## How it works
1. **`gh commit init`** — `crush run` analyzes your repo structure and generates scope definitions (e.g., `core → src/`, `docs → docs/, README.md`, `ci → .github/workflows/`)
2. **`gh commit`** — Groups dirty files by scope, sends each staged diff to `crush run`, and commits each group separately
3. **Auto-refresh** — Whenever your `.gitignore` changes, scopes are automatically regenerated before committing (a content hash of `.gitignore` is tracked per repo)
4. Remaining unscoped files are handled in a final pass
5. Unpushed commits are offered for push
Scopes are stored in a local DuckDB database (`~/.local/share/gh-commit/gh-commit.db`) — no config files in your repo.
### Why Crush?
The former Mods roles now live directly in `smartcommit.py`, so gh-commit no longer depends on Mods configuration. Each generation invokes Crush's supported non-interactive mode with a self-contained prompt.
## Commands ## Commands
| Command | Description | | Command | Behavior |
|---------|-------------| |---|---|
| `gh commit` | Commit changes grouped by scope | | `gh commit` | Full scoped-commit flow: group changed files by scope, generate a message per group, confirm, commit, offer to push |
| `gh commit init` | Generate scopes for current repo | | `gh commit init` | Generate scopes from the file tree via Crush; migrates legacy configs; confirms overwrite |
| `gh commit refresh` | Update scopes from current structure | | `gh commit refresh` | Show current scopes, regenerate with existing scopes as context, confirm apply |
| `gh commit sync` | Sync scopes → GitHub labels | | `gh commit sync` | Create/update GitHub labels from scopes (color = first 6 hex chars of MD5 of the scope name) |
| `gh commit list` | List all configured repositories | | `gh commit list` | Table of configured repositories: name, path, scope count |
| `gh commit remove` | Remove current repo from database | | `gh commit remove` | Delete the current repo from the database after confirmation |
| `gh commit db-path` | Print database file path | | `gh commit db-path` | Print the database file path |
| `gh commit version` | Print version | | `gh commit version` | Print `gh-commit <version>` |
| `gh commit help` | Show help | | `gh commit help` | Help, including the DB path and environment variable docs |
## Flags Flags: `--auto` (skip confirmations), `--push` (auto-push).
| Flag | Description |
|------|-------------|
| `--auto` | Skip all confirmation prompts |
| `--push` | Auto-push after committing |
## Environment ## Environment
@@ -82,10 +57,35 @@ The former Mods roles now live directly in `smartcommit.py`, so gh-commit no lon
| `GH_COMMIT_CRUSH_TIMEOUT` | Per-prompt timeout in seconds (default `120`) | | `GH_COMMIT_CRUSH_TIMEOUT` | Per-prompt timeout in seconds (default `120`) |
| `GH_COMMIT_DEBUG=1` | Show scope-response parse diagnostics | | `GH_COMMIT_DEBUG=1` | Show scope-response parse diagnostics |
## Migration ## Storage
Existing `.github/Repo.toml` or `.github/scopes.json` files are automatically detected and migrated to DuckDB on first run. Scopes live in `${XDG_DATA_HOME:-~/.local/share}/gh-commit/gh-commit.db`
(DuckDB). Legacy `.github/Repo.toml` and `.github/scopes.json` files are
migrated automatically on first run (the source file is archived as
`*.migrated.<timestamp>`).
## License ## Manual acceptance
MIT ```sh
mkdir /tmp/accept && cd /tmp/accept && git init
mkdir -p src docs
echo 'package app' > src/app.go
echo '# Docs' > docs/README.md
gh commit init # scopes generated and saved
echo '// change' >> src/app.go
echo 'More docs' >> docs/README.md
gh commit # one commit per scope
git log --format='%s' # verify type(scope): message subjects
```
## Development
The extension is a bash launcher (`gh-commit`) that runs `smartcommit.py`
with `uv run --script`; uv resolves the inline dependencies (duckdb, rich,
questionary) automatically.
```sh
python -m py_compile smartcommit.py # syntax check
bash -n gh-commit # launcher check
./gh-commit version # smoke test
```
Binary file not shown.
+5 -16
View File
@@ -1,23 +1,12 @@
#!/usr/bin/env bash #!/usr/bin/env bash
# gh-commit launcher — runs the bundled Python implementation via uv.
set -euo pipefail set -euo pipefail
# gh-commit: AI-powered scoped git commits (Crush for scopes and messages) DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
# Install: gh extension install prdlk/gh-commit
# Requires: uv (https://docs.astral.sh/uv) and the Crush CLI
# (https://github.com/charmbracelet/crush)
EXTENSION_DIR="$(cd "$(dirname "$0")" && pwd)" if ! command -v uv >/dev/null 2>&1; then
SCRIPT="${EXTENSION_DIR}/smartcommit.py" echo "gh-commit: 'uv' is required (https://docs.astral.sh/uv)" >&2
if ! command -v uv &>/dev/null; then
echo "error: 'uv' is required but not installed"
echo "install: curl -LsSf https://astral.sh/uv/install.sh | sh"
exit 1 exit 1
fi fi
if [[ -z "${GH_COMMIT_CRUSH_CMD:-}" ]] && ! command -v crush &>/dev/null; then exec uv run --script "$DIR/smartcommit.py" "$@"
echo "warning: 'crush' not found — gh-commit uses 'crush run' for scopes and commit messages."
echo "install Crush (https://github.com/charmbracelet/crush), or set GH_COMMIT_CRUSH_CMD."
fi
exec uv run --script "${SCRIPT}" "$@"
BIN
View File
Binary file not shown.
+1 -1
View File
@@ -54,7 +54,7 @@ AUTO_PUSH = os.environ.get("GH_COMMIT_PUSH", "0") == "1"
NO_AUTO_REFRESH = os.environ.get("GH_COMMIT_NO_AUTO_REFRESH", "0") == "1" NO_AUTO_REFRESH = os.environ.get("GH_COMMIT_NO_AUTO_REFRESH", "0") == "1"
DEBUG = os.environ.get("GH_COMMIT_DEBUG", "0") == "1" DEBUG = os.environ.get("GH_COMMIT_DEBUG", "0") == "1"
VERSION = "2.0.0" VERSION = "5.0.1"
# ── Helpers ─────────────────────────────────────────────────────────────────── # ── Helpers ───────────────────────────────────────────────────────────────────