Add comprehensive planning documentation for Checkpoint 2 (Merge Request support) and document the results of the CP1 implementation audit. checkpoint-2.md (2093 lines): - Complete PRD for adding merge request ingestion, querying, and display - Detailed user stories with acceptance criteria - ASCII wireframes for CLI output formats - Database schema extensions (migrations 006-007) - API integration specifications for MR endpoints - State transition diagrams for MR lifecycle - Performance requirements and test specifications - Risk assessment and mitigation strategies cp1-cp2-alignment-audit.md (344 lines): - Gap analysis between CP1 PRD and actual implementation - Identified issues prioritized by severity (P0/P1/P2/P3) - P0: NormalizedDiscussion struct incompatible with MR discussions - P1: --full flag not resetting discussion watermarks - P2: Missing Link header pagination fallback - P3: Missing sync health telemetry and selective payload storage - Each issue includes root cause, recommended fix, and affected files The P0 and P1 issues have been fixed in accompanying commits. P2 and P3 items are deferred to CP2 implementation. Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
gi - GitLab Inbox
A command-line tool for managing GitLab issues locally. Syncs issues, discussions, and notes from GitLab to a local SQLite database for fast, offline-capable querying and filtering.
Features
- Local-first: All data stored in SQLite for instant queries
- Incremental sync: Cursor-based sync only fetches changes since last sync
- Multi-project: Track issues across multiple GitLab projects
- Rich filtering: Filter by state, author, assignee, labels, milestone, due date
- Raw payload storage: Preserves original GitLab API responses for debugging
Installation
cargo install --path .
Or build from source:
cargo build --release
./target/release/gi --help
Quick Start
# Initialize configuration (interactive)
gi init
# Verify authentication
gi auth-test
# Sync issues from GitLab
gi ingest --type issues
# List recent issues
gi list issues --limit 10
# Show issue details
gi show issue 123 --project group/repo
Configuration
Configuration is stored in ~/.config/gi/config.json (or $XDG_CONFIG_HOME/gi/config.json).
Example Configuration
{
"gitlab": {
"baseUrl": "https://gitlab.com",
"tokenEnvVar": "GITLAB_TOKEN"
},
"projects": [
{ "path": "group/project" },
{ "path": "other-group/other-project" }
],
"sync": {
"backfillDays": 14,
"staleLockMinutes": 10
},
"storage": {
"compressRawPayloads": true
}
}
Configuration Options
| Section | Field | Default | Description |
|---|---|---|---|
gitlab |
baseUrl |
— | GitLab instance URL (required) |
gitlab |
tokenEnvVar |
GITLAB_TOKEN |
Environment variable containing API token |
projects |
path |
— | Project path (e.g., group/project) |
sync |
backfillDays |
14 |
Days to backfill on initial sync |
sync |
staleLockMinutes |
10 |
Minutes before sync lock considered stale |
sync |
cursorRewindSeconds |
2 |
Seconds to rewind cursor for overlap safety |
storage |
dbPath |
~/.local/share/gi/gi.db |
Database file path |
storage |
compressRawPayloads |
true |
Compress stored API responses |
GitLab Token
Create a personal access token with read_api scope:
- Go to GitLab → Settings → Access Tokens
- Create token with
read_apiscope - Export it:
export GITLAB_TOKEN=glpat-xxxxxxxxxxxx
Commands
gi init
Initialize configuration and database interactively.
gi init # Interactive setup
gi init --force # Overwrite existing config
gi init --non-interactive # Fail if prompts needed
gi auth-test
Verify GitLab authentication is working.
gi auth-test
# Authenticated as @username (Full Name)
# GitLab: https://gitlab.com
gi doctor
Check environment health and configuration.
gi doctor # Human-readable output
gi doctor --json # JSON output for scripting
gi ingest
Sync data from GitLab to local database.
gi ingest --type issues # Sync all projects
gi ingest --type issues --project group/repo # Single project
gi ingest --type issues --force # Override stale lock
gi list issues
Query issues from local database.
gi list issues # Recent issues (default 50)
gi list issues --limit 100 # More results
gi list issues --state opened # Only open issues
gi list issues --state closed # Only closed issues
gi list issues --author username # By author
gi list issues --assignee username # By assignee
gi list issues --label bug # By label (AND logic)
gi list issues --label bug --label urgent # Multiple labels
gi list issues --milestone "v1.0" # By milestone title
gi list issues --since 7d # Updated in last 7 days
gi list issues --since 2w # Updated in last 2 weeks
gi list issues --since 2024-01-01 # Updated since date
gi list issues --due-before 2024-12-31 # Due before date
gi list issues --has-due-date # Only issues with due dates
gi list issues --project group/repo # Filter by project
gi list issues --sort created --order asc # Sort options
gi list issues --open # Open first result in browser
gi list issues --json # JSON output
gi show issue
Display detailed issue information.
gi show issue 123 # Show issue #123
gi show issue 123 --project group/repo # Disambiguate if needed
gi count
Count entities in local database.
gi count issues # Total issues
gi count discussions # Total discussions
gi count discussions --type issue # Issue discussions only
gi count notes # Total notes
gi sync-status
Show current sync state and watermarks.
gi sync-status
gi migrate
Run pending database migrations.
gi migrate
gi version
Show version information.
gi version
Database Schema
Data is stored in SQLite with the following main tables:
- projects: Tracked GitLab projects
- issues: Issue metadata (title, state, author, assignee info, due date, milestone)
- milestones: Project milestones with state and due dates
- issue_assignees: Many-to-many issue-assignee relationships
- labels: Project labels with colors
- issue_labels: Many-to-many issue-label relationships
- discussions: Issue/MR discussions
- notes: Individual notes within discussions
- raw_payloads: Compressed original API responses
The database is stored at ~/.local/share/gi/gi.db by default.
Global Options
gi --config /path/to/config.json <command> # Use alternate config
Development
# Run tests
cargo test
# Run with debug logging
RUST_LOG=gi=debug gi list issues
# Check formatting
cargo fmt --check
# Lint
cargo clippy
Tech Stack
- Rust (2024 edition)
- SQLite via rusqlite (bundled)
- clap for CLI parsing
- reqwest for HTTP
- tokio for async runtime
- serde for serialization
- tracing for logging
License
MIT