Close out the plan with the remaining polish items and a full README.
Shell completions (cmd/gitflow):
- New `completion [bash|zsh|fish|powershell]` command backed by cobra's
generators, wired into the root command
Desktop notifications (internal/notify):
- Send() dispatches to notify-send (Linux) with an osascript fallback
(macOS); Windows is a documented no-op for now; missing notifiers are
silent, never errors
- watch --notify sends a notification listing repositories whose state
changed since the previous frame
Color themes (internal/presenter):
- ThemeMode (dark/light) with ParseTheme; light uses bright ANSI variants
(90-97) that stay legible on light backgrounds; threaded through the
table, compact, and suggestions renderers; new --theme flag validated
and dumped by config
Custom rules (internal/rules):
- Rule{name, field (ahead|behind|stash|changes), op (==,!=,<,<=,>,>=),
value, label} with upfront validation in both Validate and Eval
- Config gains a `rules:` section (yaml/env only, no flag), validated at
load; matches render as a "FLAGS (custom rules)" section via a new
presenter.Flags renderer, shown in scan and watch frames
Docs:
- readme.md fully rewritten: features, install, usage, examples, flag
table, status classes, configuration reference, AI agent behavior and
--ai-execute guardrails, development layout, CI, and future work
- implementation.md gains an Implementation Progress section recording
every phase branch and the deviations from the original plan
Multi-platform:
- Verified cross-compilation for windows/amd64 and darwin/arm64; the
notify package is split behind build tags
Testing:
- rules: validation, operator semantics, Eval ordering, invalid-rule
errors
- presenter: ParseTheme, light-theme bright codes (and absence of
dark-theme codes), Flags rendering (empty = silent, matches render)
- config: rules loading from file, invalid-rule rejection, bad theme and
bad provider rejection
- notify: no-op behaviour when no notifier is installed (skipped when one
is, to avoid firing real notifications)
Verified: go build, go vet, go test -race (10 packages), gofmt clean,
windows/darwin cross-compile, completion generation, rules + light theme
smoke test, watch --notify graceful shutdown (exit 0, no orphans).
199 lines
6.9 KiB
Markdown
199 lines
6.9 KiB
Markdown
# gitflow
|
||
|
||
**gitflow** is a CLI tool written in Go that explores every Git repository
|
||
under a parent directory, scans each one's status, and presents the
|
||
findings. It can rescan on a schedule — flagging repositories as they
|
||
change — and, when enabled, uses an integrated AI agent to suggest the next
|
||
actions for repositories that need attention.
|
||
|
||
## Features
|
||
|
||
- **Repo discovery** — walks a directory tree and finds working trees,
|
||
linked worktrees/submodule checkouts, and bare repositories, without
|
||
descending into `.git` internals
|
||
- **Status scanning** — parses `git status --porcelain=v2` for each repo:
|
||
branch, detached HEAD, staged/modified/untracked files, ahead/behind
|
||
counts, stash count, and remote URL; scans run concurrently with a
|
||
bounded worker pool
|
||
- **Three output formats** — aligned colorized table (default), indented
|
||
JSON for scripting, and a compact one-line-per-repo view
|
||
- **Watch mode** — rescan on an interval with change detection, desktop
|
||
notifications, and graceful Ctrl-C shutdown
|
||
- **AI agent** — OpenAI, Ollama (local), or Anthropic providers suggest
|
||
concrete next steps (`commit`, `push`, `pull`, …) for repositories that
|
||
need attention
|
||
- **Custom rules** — user-defined threshold rules flag repositories (e.g.
|
||
"behind ≥ 10 commits" ⇒ `stale`)
|
||
- **Light/dark themes**, `NO_COLOR` support, and shell completions
|
||
|
||
## Installation
|
||
|
||
Requires Go 1.24+ and `git` on the `PATH`.
|
||
|
||
```sh
|
||
go install gitea.oblak.solutions/dimitar/gitFlow/cmd/gitflow@latest
|
||
# or build from a checkout:
|
||
make build
|
||
```
|
||
|
||
## Usage
|
||
|
||
```
|
||
gitflow scan [flags] Scan repositories under a directory once
|
||
gitflow watch [flags] Repeatedly scan on an interval
|
||
gitflow config Show the effective configuration
|
||
gitflow completion [shell] Generate shell completions (bash/zsh/fish/powershell)
|
||
gitflow version Print version information
|
||
```
|
||
|
||
When no `--dir` is given and stdin is a terminal, gitflow asks for the
|
||
parent directory to scan, per the README's original design.
|
||
|
||
### Examples
|
||
|
||
```sh
|
||
# One-shot scan of ~/projects (prompts for the directory if omitted)
|
||
gitflow scan
|
||
|
||
# JSON output for scripting
|
||
gitflow scan -d ~/projects -f json
|
||
|
||
# Skip dependency directories and cap traversal depth
|
||
gitflow scan -d ~ --exclude node_modules --exclude vendor --max-depth 3
|
||
|
||
# Watch every 30 seconds, notifying when repositories change
|
||
gitflow watch -d ~/projects -i 30s --notify
|
||
|
||
# AI suggestions via OpenAI (exports OPENAI_API_KEY or ai.api_key_env)
|
||
gitflow scan -d ~/projects --ai
|
||
|
||
# AI suggestions via a local Ollama server
|
||
gitflow scan -d ~/projects --ai --ai-provider ollama --ai-model llama3.2
|
||
|
||
# Custom rules
|
||
gitflow scan -d ~/projects # with rules: in ~/.gitflow.yaml
|
||
|
||
# Shell completion
|
||
eval "$(gitflow completion bash)"
|
||
```
|
||
|
||
### Flags
|
||
|
||
| Flag | Default | Description |
|
||
|---|---|---|
|
||
| `-d, --dir` | `.` | Parent directory to scan |
|
||
| `-i, --interval` | `0` | Rescan interval (e.g. `30s`, `5m`); `0` runs once |
|
||
| `-f, --format` | `table` | Output format: `table`, `json`, or `compact` |
|
||
| `--color` | `auto` | Color output: `auto`, `always`, or `never` |
|
||
| `--theme` | `dark` | Color theme: `dark` or `light` |
|
||
| `--exclude` | – | Glob patterns of directories to skip (repeatable) |
|
||
| `--max-depth` | `0` | Maximum directory depth to scan (`0` = unlimited) |
|
||
| `--workers` | `8` | Number of concurrent git scans |
|
||
| `--notify` | `false` | Desktop notifications on watch changes |
|
||
| `--ai` | `false` | Enable AI suggestions |
|
||
| `--ai-provider` | `openai` | `openai`, `ollama`, or `anthropic` |
|
||
| `--ai-model` | `gpt-4o` | Model name (provider default when empty) |
|
||
| `--ai-execute` | `false` | Run confirmed AI-suggested commands (experimental) |
|
||
|
||
### Status classes
|
||
|
||
`clean` · `modified` · `ahead` · `behind` · `diverged` · `detached` ·
|
||
`bare` · `error`
|
||
|
||
## Configuration
|
||
|
||
Settings are resolved with the precedence **flags > environment >
|
||
`~/.gitflow.yaml` > defaults**. Environment variables use a `GITFLOW_`
|
||
prefix with dots as underscores (e.g. `GITFLOW_FORMAT=json`,
|
||
`GITFLOW_AI_PROVIDER=ollama`). Use `GITFLOW_CONFIG=/path/to/file.yaml` to
|
||
point at a specific config file.
|
||
|
||
```yaml
|
||
# ~/.gitflow.yaml
|
||
dir: ~/projects
|
||
interval: 5m
|
||
format: table
|
||
color: auto
|
||
theme: dark
|
||
notify: true
|
||
max_depth: 3
|
||
workers: 8
|
||
exclude:
|
||
- node_modules
|
||
- vendor
|
||
ai:
|
||
enabled: true
|
||
provider: openai # openai | ollama | anthropic
|
||
model: gpt-4o
|
||
api_key_env: OPENAI_API_KEY
|
||
base_url: "" # provider endpoint override
|
||
execute: false # run confirmed AI-suggested commands
|
||
rules:
|
||
- name: stale
|
||
field: behind # ahead | behind | stash | changes
|
||
op: ">=" # == | != | < | <= | > | >=
|
||
value: 10
|
||
label: stale
|
||
```
|
||
|
||
## AI agent
|
||
|
||
With `--ai` (or `ai.enabled`), gitflow renders a summary of the scan to the
|
||
configured provider and displays a `AI SUGGESTIONS` section below the
|
||
table, color-coded by priority:
|
||
|
||
```
|
||
AI SUGGESTIONS
|
||
REPOSITORY ACTION PRIORITY MESSAGE COMMAND
|
||
~/projects/web commit high commit the untracked file git add -A && git commit -m wip
|
||
```
|
||
|
||
Suggestions include `repo_path`, `action`, `message`, a concrete `command`
|
||
when one is safe, and a `priority` (low/medium/high). AI failures degrade
|
||
to a warning — a scan result is always shown. In watch mode the agent is
|
||
consulted only on the first frame and when something changed, so the
|
||
provider is not called on every interval.
|
||
|
||
### `--ai-execute` (experimental)
|
||
|
||
Runs the commands of AI suggestions **only** after explicit per-command
|
||
confirmation (`y/N`) and **only** for actions on an allowlist
|
||
(`commit`, `push`, `pull`, `stash`, `checkout`) — LLM output can never run
|
||
arbitrary shell commands. Treat this feature as experimental.
|
||
|
||
## Development
|
||
|
||
```
|
||
make build # build the binary (VERSION=... to stamp the version)
|
||
make test # run the full test suite
|
||
make lint # golangci-lint
|
||
```
|
||
|
||
Layout:
|
||
|
||
```
|
||
cmd/gitflow/ CLI commands (scan, watch, config, version, completion)
|
||
internal/ai/ AI providers (OpenAI, Ollama, Anthropic) + prompt + execution
|
||
internal/app/ orchestration: discovery → scan → result
|
||
internal/config/ flags, env, and config-file resolution
|
||
internal/git/ porcelain v2 git wrapper
|
||
internal/notify/ desktop notifications (Linux/macOS; Windows no-op)
|
||
internal/presenter/ table / json / compact output + colors + themes
|
||
internal/rules/ user-defined threshold rules
|
||
internal/scanner/ repository discovery + concurrent status scanning
|
||
internal/scheduler/ interval loop with graceful shutdown
|
||
internal/version/ ldflags-injectable version
|
||
pkg/status/ shared domain model (RepoInfo, RepoStatus, ScanResult)
|
||
```
|
||
|
||
CI runs build, vet, and tests (with `-race`) on Go 1.24/1.26 plus
|
||
golangci-lint.
|
||
|
||
## Future work
|
||
|
||
- Interactive TUI (bubbletea) for navigating repositories and triggering
|
||
AI suggestions
|
||
- Webhook alerts (Slack/Discord) instead of desktop notifications
|
||
- `ai_execute` hardening and a wider command allowlist
|
||
- Fetch-history tracking to populate per-repo `last_fetch` metadata
|