---
stepsCompleted: [step-01-validate-prerequisites, step-02-design-epics, step-03-create-stories, step-04-final-validation]
status: 'complete'
completedAt: '2025-04-25'
inputDocuments:
  - "prd.md"
  - "product-brief-gitpulse.md"
  - "architecture.md"
  - "ux-design-specification.md"
workflowType: 'epics-and-stories'
project_name: 'GitPulse'
user_name: 'Ramez'
date: '2025-04-25'
---

# GitPulse - Epic Breakdown

## Overview

This document provides the complete epic and story breakdown for GitPulse, decomposing the requirements from the PRD, UX Design, and Architecture requirements into implementable stories.

## Requirements Inventory

### Functional Requirements

FR1: The user can initiate a recursive disk scan to discover Git repositories on their machine
FR2: The user can configure which root directories to scan
FR3: The user can exclude directories from scanning via a `.gitpulseignore` file (glob syntax)
FR4: The system can detect Git repositories by identifying `.git` folders
FR5: The user can manually trigger a rescan to refresh the repository list
FR6: The system can gracefully handle inaccessible directories (skip and log, no crash)
FR7: The system can cache scan results for instant reload on subsequent launches
FR8: The user can view repositories in a card grid showing branch, status (clean/dirty/ahead/behind), last commit, and stash count
FR9: The user can view repositories in a sortable, filterable list view with multi-select
FR10: The user can toggle between card grid and list view
FR11: The user can sort repositories by status, last activity date, branch name, or ahead/behind count
FR12: The user can filter repositories by status (clean, dirty, ahead, behind, dormant)
FR13: The system can display visual status indicators (color/badges) for instant pattern recognition across all repos
FR14: The system can render large repository lists (100+) without UI degradation
FR15: The user can select multiple repositories and execute batch `git pull`
FR16: The user can select multiple repositories and execute batch `git push`
FR17: The user can select multiple repositories and execute batch `git fetch`
FR18: The user can batch `git status` across multiple repositories
FR19: The system can report per-repo results for batch operations (success/failure with details)
FR20: The system can handle partial success — repos that succeed continue, repos that fail are reported with error details
FR21: The user can see specific error details (e.g., merge conflicts, auth errors) for failed repos
FR22: The user can enable Ollama integration for local, private repository health summaries
FR23: The user can configure cloud API keys (Gemini, DeepSeek, OpenAI, Anthropic) for AI-powered analysis
FR24: The system can generate one-line repository health summaries via the configured AI backend
FR25: The system can suggest commit messages based on staged changes via the configured AI backend
FR26: The system can detect and flag dormant repositories beyond a configurable threshold
FR27: The user can see a visual privacy indicator showing whether data processing is local or cloud-based
FR28: The system can operate entirely without any AI backend configured (deterministic status parsing as default)
FR29: The user can route different AI tasks to different providers (e.g., Ollama for commits, cloud for analysis)
FR30: The system can provide cross-repo analysis when using a cloud AI model (e.g., shared library dependencies across repos)
FR31: The user can run GitPulse as a background system tray agent with the dashboard closed
FR32: The system can monitor for remote changes and alert the user via native OS notifications
FR33: The system can send push reminders for repos with unpushed commits older than a configurable threshold
FR34: The user can configure GitPulse to auto-launch at system startup (opt-in)
FR35: The user can access common operations (status, pull, push) via the system tray context menu
FR36: The user can configure scan root directories via a settings interface
FR37: The user can configure AI backend settings (Ollama endpoint, cloud API keys, per-task routing)
FR38: The user can configure notification behavior (frequency, types, thresholds)
FR39: The user can configure system tray agent behavior (launch at startup, monitoring interval)
FR40: User settings are persisted locally and survive application restarts
FR41: The user can reset all settings to defaults
FR42: The user can launch GitPulse without any account, login, or network configuration
FR43: The system can operate fully offline (all core features work without network access)
FR44: The user can manually check for application updates via system tray or settings
FR45: The user can download GitPulse as a single binary (no installer wizard required)
FR46: The system can run on Windows, macOS, and Linux from initial release

### NonFunctional Requirements

NFR1: Cold startup < 3 seconds
NFR2: Disk scan speed < 5 seconds (SSD, <100 repos)
NFR3: Memory usage < 200 MB with 50+ repos
NFR4: Binary size ~15 MB
NFR5: Batch operation throughput < 30 seconds (pull/push 20 repos)
NFR6: UI rendering responsiveness < 16ms per frame (60fps)
NFR7: Async AI loading — Smart Status does not block dashboard
NFR8: Incremental scan reload < 1 second from cache
NFR9: API key storage via OS keychain/secure storage, not plaintext
NFR10: Privacy by default — no data leaves machine unless cloud backend explicitly enabled
NFR11: Data flow transparency — visual indicator for cloud data transit
NFR12: Scan scope control — `.gitpulseignore` exclusions enforced
NFR13: Zero telemetry by default — opt-in only
NFR14: Git execution isolation — malicious repo cannot compromise application
NFR15: Dependency auditing — Rust/npm vulnerabilities checked before release
NFR16: Ollama version compatibility (API v1) with graceful fallback
NFR17: Cloud API compliance — stable API versions; rate limit handling
NFR18: Git version compatibility >= 2.20 on all platforms
NFR19: Native OS integration — platform-native tray, notifications, startup
NFR20: AI offline resilience — deterministic fallback when Ollama/cloud unavailable
NFR21: Scan fault tolerance — completes even if individual directories fail
NFR22: Batch fault tolerance — successful repos complete even when others fail
NFR23: Crash recovery — state preserved across crashes
NFR24: User data persistence — settings, scan configs, API keys survive updates
NFR25: Keyboard navigation for all core operations
NFR26: High contrast support — status indicators distinguishable in dark/high contrast mode
NFR27: Screen reader compatibility — ARIA markup on key dashboard components

### Additional Requirements (Architecture)

- Starter template: `npm create tauri-app@latest -- --template react-ts --manager npm gitpulse`
- Post-scaffold stack: Zustand, Tailwind CSS, Vitest, Playwright
- Tauri plugins: tauri-plugin-store, tauri-plugin-shell, tauri-plugin-fs, tauri-plugin-autostart, tauri-plugin-notification
- Rust crates: keyring (OS keychain), thiserror (errors), async-trait (AI trait)
- Virtualization: @tanstack/react-virtual for 100+ repo rendering (FR14/NFR6)
- AiProvider trait: health_summary, suggest_commit_message, cross_repo_analysis, provider_type, is_local
- 5 provider implementations: Ollama, Gemini, DeepSeek, OpenAI, Anthropic
- CI/CD: GitHub Actions matrix (Windows x64, macOS x64+ARM, Linux x64)
- Distribution: GitHub Releases, single binary per platform, manual updates only
- Code signing deferred to Phase 1.5
- Error handling: AppError enum (ScanError, GitError, AiError, ConfigError), no unwrap in production
- IPC: Commands (CRUD) + Events (async streaming), namespace:event format
- Frontend state: Zustand stores as presentation cache, Rust = source of truth
- Dormancy detection logic in scanner.rs or commands/dashboard.rs
- .gitpulseignore parser using ignore or globset crate
- i18n framework (react-i18next or typesafe-i18n) ready from day 1

### UX Design Requirements

UX-DR1: Implement Tailwind design token system — status colors (clean/dirty/ahead/behind/dormant), privacy colors (local/cloud), neutral palette, spacing scale (4px base)
UX-DR2: Implement StatusBadge component — 5 variants (color+icon+label), 3 sizes (sm/md/lg), WCAG AA accessible
UX-DR3: Implement RepoCard component — anatomy (header/branch/stats/footer/AI line), 6 states, keyboard nav, click-expand, right-click context menu
UX-DR4: Implement RepoRow component — checkbox, status icon, name, branch, ahead/behind, last commit, action menu, sortable columns
UX-DR5: Implement StatsBar component — 5 metric cards, collapsible, clickable-to-filter, collapse at <900px width
UX-DR6: Implement PrivacyBadge component — local (shield/green) and cloud (cloud/amber) modes, transition animation, aria-live
UX-DR7: Implement BatchToolbar component — slide-down on selection, progress counter, disable during ops
UX-DR8: Implement SmartStatusLine component — AI summary with blue left border, skeleton loading, graceful absence on error
UX-DR9: Implement EmptyState component — 0 repos CTA ("Open Settings"), 0 filter results ("Clear filter"), scan progress transition
UX-DR10: Implement dark mode (default) and light mode with system fonts and 4px spacing grid
UX-DR11: Implement Card Grid layout — auto-fill minmax(280px, 1fr), 16px gap, 2-5 cards per row based on window width
UX-DR12: Implement List View layout — 56px rows, fixed/flexible columns, virtualized rendering
UX-DR13: Implement TopBar (48px) — title, Grid/List toggle, filter pills with counts, rescan button, PrivacyBadge
UX-DR14: Implement command palette (Cmd/Ctrl+K) — fuzzy search, keyboard navigable, 8+ commands
UX-DR15: Implement keyboard shortcuts — Cmd/Ctrl+K/G/L/R/,, Cmd/Ctrl+A, Escape, Space, Enter
UX-DR16: Implement right-click context menu — Pull/Push/Fetch, Open Terminal/File Manager, Copy Path, Refresh
UX-DR17: Implement skeleton loading (initial scan), streaming progress (batch ops), inline loading (AI queries)
UX-DR18: Implement inline error feedback — red border + text on cards/rows, never modal for batch errors
UX-DR19: Implement WCAG 2.1 AA — 4.5:1 contrast, ARIA labels, focus indicators, screen reader support, reduced motion, high contrast mode
UX-DR20: Implement responsive window breakpoints — sm(<900px)/md(900-1199px)/lg(1200-1599px)/xl(>=1600px)
UX-DR21: Implement window persistence — position/size remembered via tauri-plugin-store
UX-DR22: Implement toastless design — all feedback inline, native OS notifications via tray only
UX-DR23: Implement window close behavior — close minimizes to tray, Cmd/Ctrl+Q quits
UX-DR24: Implement Radix UI primitives layer — Dialog, Select, Tooltip, DropdownMenu, Checkbox, ToggleGroup, Popover
UX-DR25: Implement 3-layer component architecture — Layer 1 (Radix+Tailwind primitives), Layer 2 (domain components), Layer 3 (feature compositions)

### FR Coverage Map

| FR | Epic | Description |
|---|---|---|
| FR1 | Epic 1 | Recursive disk scan for Git repos |
| FR2 | Epic 1 | Configure root directories to scan |
| FR3 | Epic 1 | `.gitpulseignore` exclusion |
| FR4 | Epic 1 | Detect repos via `.git` folders |
| FR5 | Epic 1 | Manual rescan trigger |
| FR6 | Epic 1 | Handle inaccessible directories |
| FR7 | Epic 1 | Cache scan results |
| FR8 | Epic 1 | Card grid view with repo details |
| FR9 | Epic 1 | Sortable/filterable list view |
| FR10 | Epic 1 | Toggle card/list view |
| FR11 | Epic 1 | Sort by status/activity/branch/ahead-behind |
| FR12 | Epic 1 | Filter by status |
| FR13 | Epic 1 | Visual status indicators |
| FR14 | Epic 1 | Render 100+ repos without degradation |
| FR15 | Epic 2 | Batch git pull |
| FR16 | Epic 2 | Batch git push |
| FR17 | Epic 2 | Batch git fetch |
| FR18 | Epic 2 | Batch git status |
| FR19 | Epic 2 | Per-repo batch results |
| FR20 | Epic 2 | Partial success handling |
| FR21 | Epic 2 | Error details for failed repos |
| FR22 | Epic 3 | Ollama integration for local AI |
| FR23 | Epic 3 | Cloud API key configuration |
| FR24 | Epic 3 | AI health summaries |
| FR25 | Epic 3 | AI commit message suggestions |
| FR26 | Epic 3 | Dormant repo detection |
| FR27 | Epic 3 | Visual privacy indicator |
| FR28 | Epic 3 | Operate without AI backend |
| FR29 | Epic 3 | Per-task AI provider routing |
| FR30 | Epic 3 | Cross-repo AI analysis |
| FR31 | Epic 4 | Background system tray agent |
| FR32 | Epic 4 | Remote change monitoring & alerts |
| FR33 | Epic 4 | Push reminders for unpushed commits |
| FR34 | Epic 4 | Auto-launch at startup (opt-in) |
| FR35 | Epic 4 | Tray context menu operations |
| FR36 | Epic 5 | Configure scan root directories |
| FR37 | Epic 5 | Configure AI backend settings |
| FR38 | Epic 5 | Configure notification behavior |
| FR39 | Epic 5 | Configure system tray behavior |
| FR40 | Epic 5 | Persist settings locally |
| FR41 | Epic 5 | Reset settings to defaults |
| FR42 | Cross-cutting | No account/login required |
| FR43 | Cross-cutting | Fully offline operation |
| FR44 | Cross-cutting | Manual update check |
| FR45 | Cross-cutting | Single binary distribution |
| FR46 | Cross-cutting | Windows/macOS/Linux support |

## Epic List

### Epic 1: Repository Discovery & Dashboard

Users can discover all Git repositories on their machine and see them at a glance with status, branch, and activity information in both card grid and list views.

**FRs covered:** FR1, FR2, FR3, FR4, FR5, FR6, FR7, FR8, FR9, FR10, FR11, FR12, FR13, FR14

**Key NFRs:** NFR1 (cold startup <3s), NFR2 (scan <5s), NFR3 (memory <200MB), NFR6 (60fps), NFR8 (cache reload <1s), NFR21 (scan fault tolerance), NFR23 (crash recovery)

**Standalone value:** "Launch and Know" moment — users open GitPulse and instantly see all their repos with visual status. Fully functional without any other epic.

### Epic 2: Batch Git Operations

Users can select multiple repositories and execute pull, push, fetch, and status operations in batch, with per-repo success/failure reporting and partial success handling.

**FRs covered:** FR15, FR16, FR17, FR18, FR19, FR20, FR21

**Key NFRs:** NFR5 (batch 20 repos <30s), NFR14 (git isolation), NFR22 (batch fault tolerance)

**Standalone value:** Once repos are displayed (Epic 1), users can immediately act on them in bulk. Complete batch operation domain.

### Epic 3: AI-Powered Repository Insights

Users can leverage local (Ollama) or cloud AI providers for repository health summaries, commit message suggestions, dormancy detection, and cross-repo analysis — with clear privacy indicators.

**FRs covered:** FR22, FR23, FR24, FR25, FR26, FR27, FR28, FR29, FR30

**Key NFRs:** NFR7 (async AI loading), NFR9 (API key via keychain), NFR10 (privacy by default), NFR11 (data flow transparency), NFR16 (Ollama compat), NFR17 (cloud API compliance), NFR20 (AI offline resilience)

**Standalone value:** Adds intelligent analysis layer. Works without AI (deterministic fallback) and with any combination of providers. Privacy-first with visual indicators.

### Epic 4: Background Agent & Notifications

Users can run GitPulse as a background system tray agent that monitors for remote changes, sends push reminders, and provides quick access to common operations via tray context menu.

**FRs covered:** FR31, FR32, FR33, FR34, FR35

**Key NFRs:** NFR19 (native OS integration), NFR18 (Git >= 2.20 compat)

**Standalone value:** Transforms GitPulse from a "check when needed" tool to an "always watching" agent. Tray menu provides quick operations even with dashboard closed.

### Epic 5: Settings & Preferences

Users can configure all aspects of GitPulse — scan roots, AI backends, per-task AI routing, notification behavior, system tray behavior — with settings persisted locally and resettable to defaults.

**FRs covered:** FR36, FR37, FR38, FR39, FR40, FR41

**Key NFRs:** NFR24 (data persistence)

**Standalone value:** Complete configuration management. Users can customize every aspect of their GitPulse experience.

### Cross-Cutting Requirements (span all epics)

**FRs:** FR42 (no account), FR43 (fully offline), FR44 (update check), FR45 (single binary), FR46 (cross-platform)

**NFRs:** NFR4 (binary ~15MB), NFR12 (scan scope control), NFR13 (zero telemetry), NFR15 (dependency auditing), NFR25 (keyboard nav), NFR26 (high contrast), NFR27 (screen reader)

**UX-DRs:** Applied across all epics as design system standards

### Natural Dependencies

- **Epic 1** is the foundation — all other epics build on having repos discovered and displayed
- **Epic 2** requires Epic 1 (needs repo list for batch operations)
- **Epic 3** requires Epic 1 (needs repo data for AI analysis), integrates with Epic 5 for AI config
- **Epic 4** requires Epic 1 (needs repo list for monitoring), integrates with Epic 5 for tray/notification config
- **Epic 5** can be developed in parallel with Epics 2-4, but settings UI for each epic should be available when that epic ships

## Epic 1: Repository Discovery & Dashboard

### Story 1.1: App Shell & First Launch Experience

As a user,
I want to launch GitPulse and see a polished dark-mode dashboard with an empty state prompting me to configure scan roots,
So that I have a clear starting point.

**Acceptance Criteria:**

**Given** GitPulse is launched for the first time
**When** no scan roots are configured
**Then** the dashboard shows an empty state with a "Open Settings" CTA
**And** the TopBar (48px) shows title, Grid/List toggle, filter area, rescan button, and PrivacyBadge placeholder
**And** dark mode is the default with system fonts and 4px spacing grid
**And** window position and size are persisted via tauri-plugin-store

**FRs:** FR2 (partial) | **UX-DRs:** UX-DR9, UX-DR10, UX-DR13, UX-DR22, UX-DR24, UX-DR25

---

### Story 1.2: Scan Root Configuration

As a user,
I want to configure which root directories GitPulse should scan for repositories,
So that I control the scope of discovery.

**Acceptance Criteria:**

**Given** the settings interface is open
**When** the user adds a scan root directory path
**Then** the path is validated (exists, is directory, readable)
**And** invalid paths show inline error feedback
**And** configured roots are persisted via tauri-plugin-store and survive restarts
**And** user can remove previously configured roots

**FRs:** FR2

---

### Story 1.3: Recursive Repository Discovery

As a user,
I want GitPulse to recursively scan my configured directories and discover Git repositories by detecting `.git` folders,
So that I don't have to manually add each one.

**Acceptance Criteria:**

**Given** scan root directories are configured
**When** a scan is initiated
**Then** the scanner recursively walks the directory tree
**And** detects Git repositories by identifying `.git` folders
**And** collects repo metadata (path, current branch, ahead/behind, dirty/clean status, last commit date, stash count)
**And** directories matching `.gitpulseignore` patterns (glob syntax) are excluded
**And** scan completes within 5 seconds on SSD with <100 repos

**FRs:** FR1, FR3, FR4 | **NFRs:** NFR2, NFR12

---

### Story 1.4: Scan Fault Tolerance

As a user,
I want GitPulse to skip inaccessible or permission-denied directories gracefully,
So that one problem directory doesn't stop the entire scan.

**Acceptance Criteria:**

**Given** a scan is running
**When** the scanner encounters an inaccessible or permission-denied directory
**Then** the directory is skipped and logged
**And** the scan continues without crashing
**And** error count is available for display

**FRs:** FR6 | **NFRs:** NFR21

---

### Story 1.5: Scan Result Caching & Manual Rescan

As a user,
I want GitPulse to cache scan results so subsequent launches load instantly, and I want a manual rescan button to refresh on demand,
So that I get instant access to my repos without waiting.

**Acceptance Criteria:**

**Given** a scan has completed successfully
**When** GitPulse is relaunched
**Then** cached results load within 1 second
**And** the user sees the repository dashboard immediately
**Given** the user clicks the rescan button in the TopBar
**When** a rescan is triggered
**Then** the scan runs fresh and updates the cache
**And** streaming progress is visible during the scan

**FRs:** FR5, FR7 | **NFRs:** NFR8, NFR23

---

### Story 1.6: Repository Card Grid View

As a user,
I want to see my discovered repositories as cards in a responsive grid, each showing branch, status indicator, last commit, and stash count,
So that I can assess all repos at a glance.

**Acceptance Criteria:**

**Given** repositories have been discovered
**When** the card grid view is active
**Then** each repo displays as a card with: repo name, branch name, StatusBadge (clean/dirty/ahead/behind/dormant), last commit relative time, stash count
**And** the grid uses auto-fill minmax(280px, 1fr) with 16px gap
**And** cards are keyboard navigable (Tab, Enter to expand)
**And** status colors use the design token system (clean=green, dirty=red, ahead=blue, behind=orange, dormant=gray)
**And** cards have 6 visual states (default, hover, selected, active, loading, error)

**FRs:** FR8, FR13 | **UX-DRs:** UX-DR1, UX-DR2, UX-DR3, UX-DR11

---

### Story 1.7: Repository List View with Multi-Select

As a user,
I want to see repositories in a compact list with sortable columns and multi-select checkboxes,
So that I can efficiently manage many repositories.

**Acceptance Criteria:**

**Given** repositories have been discovered
**When** the list view is active
**Then** repos display in 56px rows with columns: checkbox, status icon, name, branch, ahead/behind, last commit, action menu
**And** multi-select is supported via checkboxes and Cmd/Ctrl+A
**And** columns are sortable by clicking headers
**And** rendering is virtualized for 100+ repos

**FRs:** FR9, FR14 | **UX-DRs:** UX-DR4, UX-DR12 | **NFRs:** NFR6

---

### Story 1.8: View Toggle, Sorting, and Filtering

As a user,
I want to toggle between card and list view, sort by various fields, and filter by status,
So that I can customize the dashboard to my workflow.

**Acceptance Criteria:**

**Given** repositories are displayed in either view
**When** the user clicks the Grid/List toggle in the TopBar
**Then** the view switches between card grid and list view
**Given** the user clicks a column header or sort option
**Then** repos sort by status, last activity date, branch name, or ahead/behind count
**Given** the user clicks a filter pill in the TopBar
**Then** repos filter by status (clean, dirty, ahead, behind, dormant)
**And** filter pills show counts for each status
**And** keyboard shortcuts work: Cmd/Ctrl+G (grid), Cmd/Ctrl+L (list), Cmd/Ctrl+, (toggle)

**FRs:** FR10, FR11, FR12 | **UX-DRs:** UX-DR13, UX-DR15

---

### Story 1.9: Stats Bar & Command Palette

As a user,
I want to see aggregate stats across all repos and access a command palette for quick actions,
So that I have an overview and can navigate efficiently.

**Acceptance Criteria:**

**Given** repositories are loaded
**When** the StatsBar is visible
**Then** it shows 5 metric cards: total repos, clean, dirty, ahead, behind
**And** clicking a metric filters the repo list by that status
**And** StatsBar collapses at <900px width
**Given** the user presses Cmd/Ctrl+K
**When** the command palette opens
**Then** fuzzy search is available across 8+ commands (toggle view, rescan, filter by status, open settings, pull/push selected)
**And** the palette is keyboard navigable (arrows, Enter, Escape)

**UX-DRs:** UX-DR5, UX-DR14, UX-DR15

---

### Story 1.10: Loading States & Responsive Design

As a user,
I want skeleton loading during scans and a dashboard that adapts to window resizing,
So that the experience feels polished at any size and stage.

**Acceptance Criteria:**

**Given** a scan is in progress
**When** the dashboard is loading
**Then** skeleton loading placeholders are shown (not spinners)
**Given** the window is resized
**When** crossing breakpoints (sm<900, md 900-1199, lg 1200-1599, xl>=1600)
**Then** layout adapts with 2-5 cards per row accordingly
**And** window position and size are remembered across sessions

**UX-DRs:** UX-DR17, UX-DR20, UX-DR21

---

### Story 1.11: Accessibility Foundation

As a user,
I want the dashboard to be keyboard navigable with screen reader support and high contrast compatibility,
So that GitPulse is usable regardless of ability.

**Acceptance Criteria:**

**Given** the user navigates via keyboard
**Then** all core operations are accessible (Tab, Enter, Escape, arrow keys)
**And** focus indicators are visible and distinct
**Given** a screen reader is active
**Then** ARIA labels are present on key dashboard components
**And** StatusBadge includes aria-live for status changes
**Given** high contrast mode is enabled
**Then** status indicators are distinguishable beyond color alone (icons + labels)

**UX-DRs:** UX-DR19 | **NFRs:** NFR25, NFR26, NFR27

---

## Epic 2: Batch Git Operations

### Story 2.1: Repository Multi-Select & Batch Toolbar

As a user,
I want to select multiple repositories and see a batch action toolbar appear,
So that I know which operations I can run on my selection.

**Acceptance Criteria:**

**Given** repositories are displayed in list view
**When** the user selects one or more repos via checkboxes or Cmd/Ctrl+A
**Then** a BatchToolbar slides down showing Pull, Push, Fetch, Status buttons
**And** a selection counter shows "N repos selected"
**And** all batch buttons are disabled while an operation is in progress

**UX-DRs:** UX-DR7

---

### Story 2.2: Batch Git Pull

As a user,
I want to select multiple repos and execute `git pull` on all of them,
So that I can update all repos at once.

**Acceptance Criteria:**

**Given** multiple repos are selected and the batch toolbar is visible
**When** the user clicks "Pull"
**Then** `git pull` executes across selected repos in parallel via tokio::process::Command
**And** per-repo progress is shown in the streaming toolbar
**And** the operation completes within 30 seconds for 20 repos

**FRs:** FR15 | **NFRs:** NFR5, NFR14

---

### Story 2.3: Batch Git Push

As a user,
I want to batch push selected repositories,
So that I can sync local commits to remotes efficiently.

**Acceptance Criteria:**

**Given** multiple repos are selected
**When** the user clicks "Push"
**Then** `git push` executes across selected repos in parallel
**And** per-repo progress is shown
**And** auth errors are caught and reported per repo

**FRs:** FR16

---

### Story 2.4: Batch Git Fetch

As a user,
I want to batch fetch selected repositories,
So that I can check for remote changes without merging.

**Acceptance Criteria:**

**Given** multiple repos are selected
**When** the user clicks "Fetch"
**Then** `git fetch` executes across selected repos in parallel
**And** ahead/behind counts are updated after fetch
**And** per-repo results are shown

**FRs:** FR17

---

### Story 2.5: Batch Git Status

As a user,
I want to run `git status` across multiple repos,
So that I can see which repos have uncommitted changes.

**Acceptance Criteria:**

**Given** multiple repos are selected
**When** the user clicks "Status"
**Then** `git status` runs across selected repos
**And** dirty/clean status is updated for each repo
**And** cards/rows update their StatusBadge accordingly

**FRs:** FR18

---

### Story 2.6: Batch Results Reporting & Partial Success

As a user,
I want to see per-repo results with specific error details for batch operations,
So that I know exactly what succeeded and failed.

**Acceptance Criteria:**

**Given** a batch operation is running
**When** some repos succeed and others fail
**Then** successful repos complete normally (partial success)
**And** failed repos show inline error feedback (red border + error text on card/row, never modal)
**And** specific error details are shown (merge conflicts, auth errors, network errors)
**And** the toolbar shows final summary: "N succeeded, M failed"

**FRs:** FR19, FR20, FR21 | **UX-DRs:** UX-DR18 | **NFRs:** NFR22

---

### Story 2.7: Right-Click Context Menu

As a user,
I want to right-click a repository for quick actions like pull, push, fetch, open terminal, or open file manager,
So that I can act on individual repos without multi-selecting.

**Acceptance Criteria:**

**Given** the user right-clicks on a repo card or row
**When** the context menu appears
**Then** options include: Pull, Push, Fetch, Open in Terminal, Open in File Manager, Copy Path, Refresh
**And** each option triggers the corresponding action
**And** the menu is keyboard navigable

**UX-DRs:** UX-DR16

---

## Epic 3: AI-Powered Repository Insights

### Story 3.1: AI Provider Trait & Ollama Integration

As a user,
I want to connect GitPulse to my local Ollama instance for private AI-powered insights,
So that I can get intelligent summaries without sending data to the cloud.

**Acceptance Criteria:**

**Given** Ollama is configured with an endpoint URL
**When** GitPulse connects to Ollama
**Then** the AiProvider trait is implemented with health_summary, suggest_commit_message, cross_repo_analysis, provider_type, is_local methods
**And** Ollama provider uses API v1 with graceful fallback on version mismatch
**And** health check verifies the endpoint is reachable
**And** when Ollama is unavailable, deterministic status parsing is used as fallback

**FRs:** FR22, FR28 | **NFRs:** NFR16, NFR20

---

### Story 3.2: Cloud AI Provider Configuration & Secure Key Storage

As a user,
I want to configure API keys for cloud providers (Gemini, DeepSeek, OpenAI, Anthropic) stored in my OS keychain,
So that I can use cloud AI securely.

**Acceptance Criteria:**

**Given** the AI settings section is open
**When** the user enters an API key for a provider
**Then** the key is stored via the OS keychain (keyring crate), not plaintext
**And** a connection test verifies the key works
**And** the key is never displayed in full after saving

**FRs:** FR23 | **NFRs:** NFR9

---

### Story 3.3: AI Health Summary (Smart Status Line)

As a user,
I want to see a one-line AI-generated health summary for each repository,
So that I can quickly understand repo state without reading git output.

**Acceptance Criteria:**

**Given** an AI provider is configured and a repo has status data
**When** the SmartStatusLine component renders
**Then** a one-line summary appears with a blue left border
**And** loading shows skeleton animation (non-blocking)
**And** on error, the line is absent (graceful degradation, no error shown)
**And** PrivacyBadge indicates local vs cloud processing

**FRs:** FR24, FR27 | **UX-DRs:** UX-DR6, UX-DR8 | **NFRs:** NFR7, NFR10, NFR11

---

### Story 3.4: AI Commit Message Suggestions

As a user,
I want AI to suggest commit messages based on my staged changes,
So that I can write better commit messages faster.

**Acceptance Criteria:**

**Given** a repository has staged changes
**When** the user requests a commit message suggestion
**Then** the AI generates a suggestion based on the staged diff
**And** the suggestion is shown inline (non-blocking)
**And** the feature works with any configured AI provider

**FRs:** FR25

---

### Story 3.5: Dormant Repository Detection

As a user,
I want GitPulse to flag repositories with no activity beyond a configurable threshold,
So that I can identify stale projects.

**Acceptance Criteria:**

**Given** a configurable dormancy threshold (default: 30 days)
**When** a repo's last commit is older than the threshold
**Then** the repo is flagged with "dormant" status
**And** the StatusBadge shows the dormant variant (gray)
**And** dormant repos appear in the dormant filter

**FRs:** FR26

---

### Story 3.6: Per-Task AI Provider Routing

As a user,
I want to route different AI tasks to different providers,
So that I can optimize for speed, cost, or privacy per task type.

**Acceptance Criteria:**

**Given** multiple AI providers are configured
**When** the user sets routing rules (e.g., Ollama for commits, cloud for analysis)
**Then** each AI task routes to the configured provider
**And** fallback to a default provider if the routed provider is unavailable

**FRs:** FR29

---

### Story 3.7: Cross-Repository AI Analysis

As a user,
I want AI to analyze patterns across my repositories,
So that I can understand relationships like shared library dependencies.

**Acceptance Criteria:**

**Given** a cloud AI provider is configured (cross-repo analysis not available with Ollama)
**When** the user requests cross-repo analysis
**Then** the AI provides insights about shared dependencies, patterns, and relationships across repos
**And** PrivacyBadge shows "cloud" indicator during analysis

**FRs:** FR30 | **NFRs:** NFR17

---

## Epic 4: Background Agent & Notifications

### Story 4.1: System Tray Agent & Window Management

As a user,
I want GitPulse to minimize to the system tray when I close the window,
So that it stays available in the background.

**Acceptance Criteria:**

**Given** GitPulse is running
**When** the user closes the window
**Then** the app minimizes to system tray (platform-native tray icon)
**And** double-clicking the tray icon reopens the dashboard
**Given** the user presses Cmd/Ctrl+Q
**Then** the app quits entirely

**FRs:** FR31 | **UX-DRs:** UX-DR23 | **NFRs:** NFR19

---

### Story 4.2: Tray Context Menu Operations

As a user,
I want to right-click the tray icon for quick access to common operations,
So that I can act without opening the dashboard.

**Acceptance Criteria:**

**Given** GitPulse is running in the tray
**When** the user right-clicks the tray icon
**Then** a context menu shows: status overview, Pull All, Push All, Open Dashboard, Quit
**And** selecting an action executes it immediately
**And** status overview shows clean/dirty/ahead/behind counts

**FRs:** FR35

---

### Story 4.3: Remote Change Monitoring & Alerts

As a user,
I want GitPulse to periodically check for remote changes and alert me via native OS notifications,
So that I stay informed about upstream activity.

**Acceptance Criteria:**

**Given** background monitoring is enabled
**When** remote changes are detected on a monitored repo
**Then** a native OS notification is sent identifying the repo and change count
**And** the monitoring interval is configurable

**FRs:** FR32

---

### Story 4.4: Push Reminders for Unpushed Commits

As a user,
I want GitPulse to remind me about unpushed commits older than a configurable threshold,
So that I don't forget to push important work.

**Acceptance Criteria:**

**Given** a repo has unpushed commits older than the configured threshold
**When** the background check runs
**Then** a native OS notification reminds the user to push
**And** the notification identifies the repo and commit age
**And** the threshold is configurable in settings

**FRs:** FR33

---

### Story 4.5: Auto-Launch at System Startup

As a user,
I want to configure GitPulse to start automatically with my system,
So that monitoring begins without manual intervention.

**Acceptance Criteria:**

**Given** auto-launch is enabled in settings (opt-in, default off)
**When** the system starts up
**Then** GitPulse launches and minimizes to tray
**And** tauri-plugin-autostart handles platform-specific startup registration

**FRs:** FR34

---

## Epic 5: Settings & Preferences

### Story 5.1: Settings Interface Foundation

As a user,
I want a clean settings interface organized into sections,
So that I can find and configure any aspect of GitPulse easily.

**Acceptance Criteria:**

**Given** the user opens settings (via menu, keyboard shortcut, or empty state CTA)
**When** the settings dialog appears
**Then** sections are organized as: Scan, AI, Notifications, System Tray
**And** all settings are persisted via tauri-plugin-store
**And** settings survive application restarts

**FRs:** FR40

---

### Story 5.2: Scan Configuration Settings

As a user,
I want to manage scan root directories and exclusions in settings,
So that I can control repository discovery behavior.

**Acceptance Criteria:**

**Given** the Scan settings section
**When** the user adds/removes scan root directories
**Then** changes take effect on next scan
**And** the dormancy threshold is configurable
**And** .gitpulseignore patterns can be previewed

**FRs:** FR36

---

### Story 5.3: AI Backend Settings & Per-Task Routing

As a user,
I want to configure AI providers, API keys, and per-task routing,
So that I can control how AI features work.

**Acceptance Criteria:**

**Given** the AI settings section
**When** the user configures providers
**Then** Ollama endpoint URL is configurable
**And** cloud API keys can be entered (stored in OS keychain)
**And** per-task routing can be set (health summary → provider, commit message → provider)
**And** connection test buttons verify each provider

**FRs:** FR37

---

### Story 5.4: Notification Behavior Settings

As a user,
I want to configure notification frequency, types, and thresholds,
So that I'm alerted about what matters without being overwhelmed.

**Acceptance Criteria:**

**Given** the Notifications settings section
**When** the user configures notifications
**Then** individual notification types can be enabled/disabled (remote changes, push reminders)
**And** the monitoring interval is configurable
**And** push reminder threshold is configurable

**FRs:** FR38

---

### Story 5.5: System Tray & Startup Settings

As a user,
I want to configure tray behavior and auto-launch,
So that GitPulse runs the way I prefer.

**Acceptance Criteria:**

**Given** the System Tray settings section
**When** the user configures tray behavior
**Then** auto-launch at startup can be toggled (opt-in)
**And** minimize-to-tray on close can be toggled
**And** monitoring behavior is configurable

**FRs:** FR39

---

### Story 5.6: Reset Settings to Defaults

As a user,
I want to reset all settings to defaults,
So that I can start fresh if my configuration becomes problematic.

**Acceptance Criteria:**

**Given** any settings section
**When** the user clicks "Reset to Defaults"
**Then** a confirmation dialog appears
**And** on confirmation, all settings revert to defaults
**And** API keys are preserved (with option to clear)

**FRs:** FR41
