294 lines
9.2 KiB
Markdown
294 lines
9.2 KiB
Markdown
# 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 | 1–2 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 | 1–2 days |
|
||
| **M7 — Polish** | Phase 6: TUI, themes, completions, docs | 2–3 days |
|
||
|
||
**Total estimated effort**: ~7–10 days for a solid v1.0
|