gitFlow/implementation.md
dimitar 012fbf8ac5 feat: phase 6 — polish: completions, notifications, themes, rules, docs
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).
2026-08-02 08:52:50 +02:00

328 lines
11 KiB
Markdown
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# Git Flow — Detailed Development Plan
## Overview
**Git Flow** is a Go CLI tool that discovers Git repositories under a user-specified parent directory, periodically scans their status, and presents findings with AI-driven suggestions for next actions (e.g., "commit pending changes", "push branch X", "pull latest from main").
---
## Phase 0: Project Scaffolding & Tooling
| Task | Details | Deliverable |
|---|---|---|
| **Module init** | `go mod init github.com/<user>/gitflow` | `go.mod` |
| **Directory layout** | Flat-to-modular structure appropriate for a CLI (see layout below) | Dir tree |
| **Tooling** | Add `golangci-lint` config, `Makefile`, `.gitignore` | Dev tooling |
| **CI skeleton** | GitHub Actions: lint + test on push | `.github/workflows/ci.yml` |
### Recommended Directory Layout
```
gitflow/
├── cmd/gitflow/ # main entry point
├── internal/
│ ├── scanner/ # repo discovery + git status scanning
│ ├── presenter/ # output formatting (table, JSON, TUI)
│ ├── scheduler/ # periodic scan loop
│ ├── ai/ # AI agent integration
│ ├── config/ # CLI flags, env vars, config file parsing
│ └── git/ # thin wrappers around git commands
├── pkg/ # shared types (RepoInfo, Status, etc.)
├── go.mod / go.sum
├── Makefile
├── .golangci.yml
└── readme.md
```
---
## Phase 1: Core — Repo Discovery & Status Scanning
This is the foundational layer. Everything else depends on it.
### 1.1 Define the Domain Types (`pkg/types.go` or `internal/scanner/types.go`)
```go
type RepoStatus int
const (
StatusUnknown RepoStatus = iota
StatusClean
StatusModified
StatusAhead
StatusBehind
StatusDiverged
StatusDetached
StatusBare
StatusError
)
type RepoInfo struct {
Path string
RemoteURL string
Branch string
Status RepoStatus
ModifiedFiles []string
StagedFiles []string
UntrackedFiles []string
AheadBy int
BehindBy int
StashCount int
LastFetch time.Time
Error string
}
type ScanResult struct {
ScannedAt time.Time
ParentDir string
Repos []RepoInfo
TotalCount int
ErrorCount int
}
```
### 1.2 Repo Discovery (`internal/scanner/discover.go`)
- Walk the directory tree starting from the parent directory
- Detect `.git` directories (including bare repos, submodules, worktrees)
- Respect `.gitignore`-style exclusion patterns via a `--exclude` flag
- Respect depth limits via a `--depth` / `--max-depth` flag
- Use `filepath.WalkDir` for efficient traversal (no `os.FileInfo` allocations)
**Pattern**: Single-responsibility — the discoverer only finds repos; status scanning is a separate step.
### 1.3 Status Scanner (`internal/scanner/status.go`)
- For each discovered repo, run `git` porcelain commands:
- `git status --porcelain -b` for branch, ahead/behind, modified/staged/untracked
- `git remote -v` for remote URL
- `git stash list` for stash count
- Parse output into `RepoInfo`
- **Resilience patterns** from Go skill:
- Timeout each `git` command (e.g., 10s via `context.WithTimeout`)
- Handle repos with errors gracefully — mark as `StatusError`, don't crash
- Run scans concurrently with a bounded worker pool (`errgroup` + semaphore)
### 1.4 Git Command Wrapper (`internal/git/`)
- Thin wrapper: `func Status(ctx context.Context, repoPath string) (RepoInfo, error)`
- Uses `os/exec` with context for cancellation/timeout
- No external git library dependency — `os/exec` is sufficient for porcelain commands
---
## Phase 2: CLI & Configuration
### 2.1 CLI Framework
Use **Cobra** + **Viper** (standard Go CLI stack):
| Flag | Type | Default | Description |
|---|---|---|---|
| `--dir` / `-d` | string | `.` (cwd) | Parent directory to scan |
| `--interval` / `-i` | duration | `0` (run once) | Rescan interval (e.g., `5m`, `30s`) |
| `--format` / `-f` | string | `table` | Output format: `table`, `json`, `compact` |
| `--exclude` | []string | `[]` | Glob patterns to exclude |
| `--max-depth` | int | `0` (unlimited) | Max traversal depth |
| `--ai` | bool | `false` | Enable AI suggestions |
| `--ai-provider` | string | `openai` | AI backend |
| `--ai-model` | string | `gpt-4o` | AI model |
| `--watch` / `-w` | bool | `false` | Watch mode (alias for interval) |
### 2.2 Configuration File
Support `~/.gitflow.yaml` for defaults:
```yaml
ai:
provider: openai
api_key_env: OPENAI_API_KEY
model: gpt-4o
defaults:
interval: 5m
format: table
exclude:
- "node_modules"
- "vendor"
```
### 2.3 Commands
```
gitflow scan # one-shot scan
gitflow watch # periodic scan (uses --interval)
gitflow config # show/edit config
gitflow version # version info
```
---
## Phase 3: Presentation Layer
### 3.1 Table Output (default)
Rich terminal table using `bubbletea` / `lipgloss` (or simpler: `tablewriter`):
```
REPOSITORY BRANCH STATUS AHEAD/BEHIND CHANGES
~/projects/api main ✓ clean 0 / 0 -
~/projects/web feat/login ✗ modified 3 / 0 2M, 1U
~/projects/lib main ⚠ behind 0 / 5 -
~/projects/legacy (detached) ⚠ detached - -
4 repos scanned | 1 clean | 2 need attention | 2 errors
```
### 3.2 JSON Output
For scripting / piping:
```json
{
"scanned_at": "2026-01-01T12:00:00Z",
"parent_dir": "/home/user/projects",
"repos": [...],
"summary": {"total": 4, "clean": 1, "attention": 2, "errors": 1}
}
```
### 3.3 Compact Output
One line per repo with color-coded status symbols.
---
## Phase 4: Periodic Scanner (Scheduler)
### 4.1 Watch Mode (`internal/scheduler/scheduler.go`)
- Runs scan on a `time.Ticker` at the configured interval
- Clears terminal and re-renders (or uses TUI refresh)
- Handles SIGINT/SIGTERM for graceful shutdown
- Shows time until next scan in footer
**Pattern**: Use `signal.NotifyContext` for graceful shutdown. Defer cleanup immediately after resource acquisition.
### 4.2 Change Detection
- Between scans, compare current vs previous `ScanResult`
- Highlight repos that changed state
- Optionally trigger desktop notifications (via `beeep` or `notify-send`)
---
## Phase 5: AI Agent Integration
### 5.1 AI Module (`internal/ai/`)
**Interface-first design** (for testability and provider flexibility):
```go
type Provider interface {
Suggest(ctx context.Context, repos []RepoInfo) ([]Suggestion, error)
}
type Suggestion struct {
RepoPath string
Action string // "commit", "push", "pull", "stash", "pr", "cleanup"
Message string // Human-readable suggestion
Command string // Suggested git command to run
Priority int // 0=low, 1=medium, 2=high
}
```
### 5.2 Providers
1. **OpenAI** (default): GPT-4o with structured output (JSON Schema) for reliable parsing
2. **Ollama** (local/offline): Support for local models
3. **Anthropic Claude**: Alternative cloud provider
### 5.3 Prompt Design
Construct a prompt that includes:
- A summary table of all repos and their statuses
- The top 3-5 repos needing attention
- Instructions to output structured JSON with specific action types
### 5.4 AI Output Display
- Show suggestions in a separate section below the status table
- Color-coded by priority
- Optional: `--ai-execute` flag to auto-run suggested commands (with confirmation)
---
## Phase 6: Polish & Advanced Features
| Feature | Description |
|---|---|
| **Color themes** | Light/dark terminal themes via `lipgloss` |
| **TUI mode** | Full interactive TUI with `bubbletea` — navigate repos, expand details, trigger AI suggestions |
| **Custom actions** | User-defined rules: "if behind > 10 commits, mark as critical" |
| **Webhook/notifications** | Send alerts to Slack/Discord when repos need attention |
| **Multi-platform** | Test on Linux, macOS, Windows (WSL) |
| **Completion** | Shell completions for bash, zsh, fish via Cobra |
---
## Technology Choices Summary
| Concern | Choice | Rationale |
|---|---|---|
| CLI framework | Cobra + Viper | Industry standard, completions, env binding |
| Git interaction | `os/exec` (porcelain) | No dependency needed; porcelain output is stable |
| TUI (optional) | Bubble Tea + Lip Gloss | Best Go TUI ecosystem |
| AI integration | HTTP client + JSON Schema | Provider-agnostic, no heavy SDK required |
| Concurrency | `errgroup` + semaphore | Bounded parallelism, error propagation |
| Testing | `testing` + `testify` | Standard + assertions |
| Linting | `golangci-lint` | Comprehensive Go linting |
---
## Milestone Schedule
| Milestone | Scope | Estimated Effort |
|---|---|---|
| **M1 — Skeleton** | Phase 0: module, layout, Makefile, CI | 0.5 day |
| **M2 — Discovery** | Phase 1: repo walker + git status parser | 12 days |
| **M3 — CLI** | Phase 2: Cobra commands, flags, config | 1 day |
| **M4 — Display** | Phase 3: table + JSON + compact output | 1 day |
| **M5 — Watch** | Phase 4: scheduler, auto-refresh, signals | 1 day |
| **M6 — AI** | Phase 5: provider interface, OpenAI, suggestions | 12 days |
| **M7 — Polish** | Phase 6: TUI, themes, completions, docs | 23 days |
**Total estimated effort**: ~710 days for a solid v1.0
---
## Implementation Progress
All phases from this plan are implemented and merged into `main` (branch
per phase, merged with `--no-ff`, no remote pushes).
| Phase | Branch | Status |
|---|---|---|
| 0 — Scaffolding | `feat/phase-0-scaffolding` | ✅ done |
| 1 — Discovery & scanning | `feat/phase-1-discovery-scanning` | ✅ done |
| 2 — CLI & configuration | `feat/phase-2-cli-config` | ✅ done |
| 3 — Presentation | `feat/phase-3-presentation` | ✅ done |
| 4 — Scheduler / watch | `feat/phase-4-scheduler` | ✅ done |
| 5 — AI agent | `feat/phase-5-ai` | ✅ done |
| 6 — Polish | `feat/phase-6-polish` | ✅ done |
### Deviations from the plan
- **`LastFetch` field dropped** (phase 1): the only reliable source is a
reflog of the remote-tracking ref, which does not exist on fresh clones;
noted as future work instead.
- **Full bubbletea TUI deferred** (phase 6): the plan listed it as
optional; watch mode + completions + themes + notifications were
implemented instead.
- **Webhooks deferred** (phase 6): desktop notifications cover the
alerting case; Slack/Discord noted as future work.
- **AI defaults**: `ai-model` defaults to `gpt-4o` (plan) with
provider-specific fallbacks (ollama → `llama3.2`, anthropic →
`claude-3-5-haiku-latest`); `--ai-execute` implemented with an
allowlist + per-command confirmation instead of a bare auto-run.
- **testify** was not added: stdlib `testing` covers all suites, keeping
the dependency tree minimal.