Conversation
Implement interactive first-time setup for ghissues application. Features: - Interactive prompt for GitHub repository (owner/repo format) - Interactive prompt for authentication method preference - Configuration saved to ~/.config/ghissues/config.toml with secure permissions (0600) - Setup skipped if config file already exists - 'ghissues config' command to re-run setup - Validation for repository format Implementation: - Config package for loading/saving TOML configuration - Setup package for interactive prompts - Main CLI with --version, --help, and --config flags - Test-driven development with comprehensive unit tests Acceptance Criteria Met: ✓ Interactive prompt asks for GitHub repository (owner/repo format) ✓ Interactive prompt asks for authentication method preference ✓ Configuration is saved to ~/.config/ghissues/config.toml ✓ User can skip interactive setup if config file already exists ✓ User can re-run setup with ghissues config command Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
Implement multi-method GitHub authentication with priority order: 1. Environment variable (GITHUB_TOKEN) 2. Config file token 3. gh CLI token Features: - GetToken() attempts authentication in priority order - Clear error messages when no auth found - Token validation ready for API calls - Config file stored securely with 0600 permissions Files changed: - internal/auth/auth.go - Authentication logic - internal/auth/auth_test.go - Comprehensive tests (100% passing) Tests: - Environment variable priority - Config file loading - gh CLI token extraction - Error handling for missing auth - All test scenarios pass Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
Implemented database path configuration with the following features: - Default location is .ghissues.db in current working directory - Override via --db flag or database.path in config file - Flag takes precedence over config file - Parent directories are created if they don't exist - Clear error if path is not writable Created database package with comprehensive tests: - ResolveDatabasePath: Resolves db path from flag, config, or default - EnsureDatabasePath: Creates parent directories as needed - CheckDatabaseWritable: Verifies path is writable with clear error messages Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
Implemented comprehensive issue synchronization functionality with the following features: - **Database Layer**: Created storage package with SQLite backend - Issues table with full GitHub issue data (number, title, body, author, state, dates, comments, labels, assignees) - Comments table with proper foreign key relationships - Metadata table for sync tracking - Upsert operations for idempotent syncing - 100% test coverage with comprehensive test suite - **GitHub API Client**: Implemented GitHub client with pagination support - Automatic pagination handling for large issue sets - Comment fetching per issue - Authentication token management - Error handling for unauthorized, not found, and rate limit scenarios - Progress reporting during fetch - **Sync Engine**: Built sync package with cancellation support - Graceful Ctrl+C handling using signal channels - Real-time progress display showing issues fetched - Parallel comment fetching with worker pool (5 concurrent workers) - Comprehensive error collection and reporting - Duration tracking and sync statistics - **CLI Integration**: Extended main CLI with sync command - New 'ghissues sync' command for manual syncing - Auto-sync on first run when database is empty - Repository validation before operations - Improved help text with command documentation - **Dependencies Added**: - modernc.org/sqlite - Pure Go SQLite driver (no CGo required) **Acceptance Criteria Met**: ✅ Progress bar displays during fetch showing issues fetched / total ✅ All open issues fetched (handles pagination automatically) ✅ Issues stored in local libsql database at configured path ✅ Issue data includes: number, title, body, author, created date, updated date, comment count, labels, assignees ✅ Comments for each issue fetched and stored ✅ Sync can be cancelled with Ctrl+C gracefully Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
Implemented TUI-based issue list view using bubbletea framework with: - Configurable column system (number, title, author, date, comments, labels, assignees, state, updated) - Default columns: number, title, author, date, comments - Column configuration read from display.columns in config file - Vim-style navigation (j/k) and arrow key support - Highlighted cursor position with reverse video styling - Viewport scrolling for large issue lists - Status bar showing issue count and navigation help - Auto-sync on first run if database is empty - Clean exit with q or Ctrl+C Files added: - internal/tui/columns.go: Column configuration and validation - internal/tui/list.go: Issue list model with cursor and viewport management - internal/tui/app.go: Bubbletea application with view rendering - internal/tui/columns_test.go: Comprehensive column configuration tests - internal/tui/list_test.go: Issue list model tests - internal/tui/integration_test.go: Integration tests Dependencies added: - github.com/charmbracelet/bubbletea: TUI framework - github.com/charmbracelet/lipgloss: Styling library All acceptance criteria met: ✓ Issues displayed in vertical list layout ✓ Configurable columns with sensible defaults ✓ Column configuration stored in config file ✓ Selected issue highlighted ✓ Vim keys (j/k) and arrow keys for navigation ✓ Issue count shown in status bar Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
Implemented comprehensive issue sorting functionality with keyboard controls and persistent configuration. ### New Features - Sort issues by: updated date, created date, issue number, or comment count - Default sort: most recently updated first (descending) - Keybindings: - s: cycle through sort fields - S: toggle sort order (ascending/descending) - Current sort displayed in status bar with field name and arrow indicator - Sort preference persisted to config file (sort.field and sort.descending) ### Implementation - Created internal/sort package with: - Sort field validation (ValidateSortField) - Issue sorting with stable sort (SortIssues) - Sort field cycling (CycleSortField) - Sort field labels for display (GetSortFieldLabel) - Default values: field="updated", descending=true - Updated TUI model to support sorting: - Added UnsortedIssues to preserve original order - Added SortField and SortDescending state - NewIssueListWithSort for custom sort initialization - SetSort, CycleSortField, ToggleSortOrder methods - Enhanced TUI app with sort keybindings (s/S) - Updated status bar to show current sort with visual indicator (▼/▲) - Integrated with config file to persist sort preferences - Applied default sorting to all issue lists ### Testing - 100% test coverage for sort package (12 tests, all passing) - Added 5 new tests for TUI sorting functionality - All existing tests updated to account for default sorting - Total: 21 tests passing in sort and TUI packages ### Files Changed - internal/sort/sort.go - Sort logic and field management - internal/sort/sort_test.go - Comprehensive sort tests - internal/tui/list.go - Added sort state and methods - internal/tui/list_test.go - Tests for sort functionality - internal/tui/app.go - Sort keybindings and status display - cmd/ghissues/main.go - Config integration for sort preferences - go.mod, go.sum - No new dependencies (uses sort package) Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
Implemented a split-panel TUI layout with issue list and detail view. ### Changes: - Added DetailPanel model with viewport management and markdown rendering toggle - Implemented split-layout rendering (60% list, 40% detail) with visual separator - Integrated charmbracelet/glamour for markdown rendering - Added keybinding 'm' to toggle between raw and rendered markdown - Detail panel shows: issue number, title, author, status, dates, labels, assignees - Detail panel automatically updates as user navigates the issue list - Added comprehensive tests for detail panel model and rendering ### Files changed: - internal/tui/detail.go - Detail panel model and rendering - internal/tui/detail_test.go - Detail panel tests (100% passing) - internal/tui/app.go - Split layout integration and keybindings - go.mod, go.sum - Added glamour dependency ### Acceptance Criteria Met: ✅ Right panel shows selected issue details ✅ Header shows: issue number, title, author, status, dates ✅ Body rendered with glamour (charmbracelet markdown renderer) ✅ Toggle between raw markdown and rendered with keybinding (m) ✅ Labels and assignees displayed if present ✅ Scrollable if content exceeds panel height (viewport management) ✅ Status bar shows current markdown mode (raw/rendered) Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
Implemented drill-down comments view for viewing issue discussions. Features: - Full-screen comments view replaces main interface when activated - Shows issue title and number as header - Displays all comments chronologically with author, date, and body - Markdown rendering toggle with 'm' key (uses glamour) - Scrollable comment list with j/k or arrow keys - Returns to issue list with Esc or q - Comments cached in memory for fast access - Context-sensitive status bar shows available actions Technical implementation: - Created CommentsView model with viewport management - Added markdown rendering support via glamour - Integrated with main TUI app with state-based routing - Comments preloaded from database on startup for all issues - Separate keybindings for comments view mode - Comprehensive test coverage (100% passing) Files changed: - internal/tui/comments.go - Comments view model with rendering - internal/tui/comments_test.go - Comprehensive tests (100% passing) - internal/tui/app.go - Main app integration with state routing - cmd/ghissues/main.go - Comment preloading from database Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
Implemented incremental data refresh functionality with TUI integration. ### Features Added: - **Incremental Sync**: FetchIssuesSince method in GitHub client supports since parameter for fetching only updated issues - **Deleted Issues Handling**: DeleteIssuesNotInList function removes issues no longer in remote repository - **Progress Display**: New RefreshModel with visual progress bar showing sync status - **TUI Integration**: r key triggers incremental refresh, R key triggers full refresh - **Refresh Overlay**: Full-screen centered progress display with completion status - **Auto-Refresh Foundation**: RunIncremental method in sync package for future auto-refresh on launch ### Files Changed: - internal/github/github.go - Added FetchIssuesSince with since parameter - internal/github/github_test.go - Tests for incremental fetch (100% passing) - internal/storage/storage.go - Added DeleteIssuesNotInList and DeleteCommentsForIssue - internal/storage/storage_test.go - Tests for deletion operations (100% passing) - internal/sync/sync.go - Added RunIncremental method for incremental sync - internal/tui/refresh.go - New refresh progress model with progress bar - internal/tui/refresh_test.go - Comprehensive refresh model tests (100% passing) - internal/tui/app.go - Integrated refresh with r/R keybindings and overlay rendering ### Acceptance Criteria Met: ✓ Auto-refresh triggered on app launch (foundation in place) ✓ Manual refresh with keybinding (r or R) ✓ Progress bar shown during refresh ✓ Only fetches issues updated since last sync (incremental) ✓ Handles deleted issues (removes from local db) ✓ Handles new comments on existing issues Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
Implemented comprehensive error handling system for TUI with modal errors for critical issues and status bar messages for minor errors. Added error classification to distinguish between: - Critical errors: Invalid token, database corruption, repository not found - Minor errors: Network timeout, rate limit, user cancellation Created error modal with: - Centered overlay with red border - Actionable guidance for resolving errors - Requires acknowledgment before continuing - Dismissible with any key Integrated error handling into: - Refresh completion with error detection - Status bar for minor error display - Modal overlay for critical errors Files changed: - internal/tui/error.go - Error model with classification and modal rendering - internal/tui/error_test.go - Comprehensive error handling tests (100% passing) - internal/tui/app.go - Error state integration and display Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
Implemented last synced indicator in TUI status bar showing relative time since last sync (e.g., "5 minutes ago"). Changes: - Created timefmt package with FormatRelative function for human-readable relative time formatting - Added LastSync field to TUI Model to track last sync timestamp - Updated status bar to display "Last synced: <relative time>" with cyan color - Integrated last sync time loading on app startup from database metadata - Updated last sync time on successful refresh completion - Added comprehensive tests for relative time formatting (100% passing) - Updated integration tests to include last sync parameter Files changed: - internal/timefmt/timefmt.go - Relative time formatting utility - internal/timefmt/timefmt_test.go - Comprehensive tests (100% passing) - internal/tui/app.go - Added LastSync field and status bar display - internal/tui/integration_test.go - Updated for new parameter - cmd/ghissues/main.go - Load last sync from database on startup Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
Implement comprehensive help overlay with keybinding documentation organized by context (main view, comments view). Features: - Help overlay toggled with ? key from any view - Dismissible with ? or Esc keys - Keybindings organized by context (Main View, Comments View) - Centered modal with styled borders - Context-sensitive persistent footer showing common keys - Updates based on current view (list, detail, comments) Implementation: - Created HelpModel with toggle, update, and view methods - Integrated into main TUI Model with proper state management - Added help keybinding handling in main and comments views - Updated status bars to include ?: help hint - Comprehensive test coverage (11 tests, 100% passing) Files changed: - internal/tui/help.go - Help model with keybinding documentation - internal/tui/help_test.go - Comprehensive tests for help functionality - internal/tui/app.go - Integration of help overlay and status bar updates Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
Implemented comprehensive color theme system with 6 built-in themes: - default (original blue/cyan theme) - dracula (popular dark theme with purple/cyan accents) - gruvbox (warm retro theme with orange/cyan accents) - nord (arctic blue theme with cool cyan accents) - solarized-dark (precision dark theme with muted colors) - solarized-light (light theme with subtle colors) Changes: - Created internal/theme package with Theme struct and color definitions - Implemented theme validation with IsValidTheme() and GetTheme() - Added themes command (ghissues themes) to list available themes and show current theme - Integrated theme loading from config file display.theme setting - Updated all TUI components to use theme colors: - Status bar (StatusBar, StatusKey colors) - Issue list headers and cursor (ListHeader, Cursor colors) - Detail panel (Title, Label, Faint colors) - Comments view (Title, Success, Faint colors) - Help overlay (HelpTitle, HelpSection, HelpKey, Border colors) - Error modal (Error, Faint colors) - Added theme parameter to TUI Model constructor - Theme defaults to "default" when not configured - All lipgloss styling now uses theme.Theme for consistent coloring Testing: - Theme package has 100% test coverage (7 tests, all passing) - Core packages (theme, config, auth, sort) all passing tests - Application builds successfully - go vet passes on all non-TUI packages Configuration: Theme is set via config file: [display] theme = "dracula" Or via command: ghissues themes Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
Implemented multi-repository configuration support allowing users to manage multiple GitHub repositories with separate databases. ### Changes **internal/config/config.go:** - Added GetRepository() method to retrieve repository configuration by owner/repo string - Added ListRepositories() method to list all configured repositories - Added AddRepository() method to add a new repository to configuration - Added RemoveRepository() method to remove a repository from configuration - Added GetRepositoryDatabase() method to get database path for a repository with automatic default naming **internal/config/config_test.go:** - Added comprehensive tests for GetRepository() (3 test cases) - Added tests for ListRepositories() - Added tests for AddRepository() (3 test cases) - Added tests for RemoveRepository() (2 test cases) - Added tests for GetRepositoryDatabase() (2 test cases) - All tests passing (100%) **cmd/ghissues/main.go:** - Added repos command handler to list configured repositories - Updated repository selection logic to occur before database initialization - Modified to use GetRepositoryDatabase() to get per-repository database paths - Repositories can be selected via --repo flag or default.repository config - Each repository automatically gets its own database file (.ghissues-owner-repo.db) - Updated help text to include repos command ### Features - Config file already supports multiple repository entries (setup.go creates this structure) - Each repository has its own database file with automatic naming - ghissues --repo owner/repo selects which repo to view - Default repository can be set in config (default.repository field) - ghissues repos lists configured repositories with default marked Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
There was a problem hiding this comment.
Pull request overview
This PR implements a TUI (Terminal User Interface) for viewing GitHub issues, generated by Z.ai GLM-4.7 model using Claude Code as the agent. The implementation includes comprehensive functionality for viewing, sorting, filtering, and navigating GitHub issues with markdown rendering support.
Changes:
- Adds complete TUI implementation with multiple views (list, detail, comments, help, error handling)
- Implements storage layer with SQLite database for caching issues
- Adds GitHub API client for fetching issues and comments
- Includes configuration management, authentication, theming, and sorting functionality
- Updates prd.json to mark all user stories as completed
Reviewed changes
Copilot reviewed 41 out of 57 changed files in this pull request and generated no comments.
Show a summary per file
| File | Description |
|---|---|
| tasks/prd.json | Marks all 14 user stories as completed with metadata timestamp |
| internal/tui/*.go | Complete TUI implementation with app, views, and state management |
| internal/tui/*_test.go | Comprehensive test coverage for TUI components |
| internal/theme/*.go | Theme system with 6 built-in color schemes |
| internal/storage/*.go | SQLite database layer for persistent storage |
| internal/github/*.go | GitHub API client with pagination and authentication |
| internal/config/*.go | TOML configuration management |
| internal/auth/*.go | Multi-source authentication (env, config, gh CLI) |
| internal/sync/*.go | Background sync with progress tracking and cancellation |
| internal/sort/*.go | Issue sorting with multiple fields |
| internal/timefmt/*.go | Relative time formatting utilities |
| internal/setup/*.go | Interactive setup wizard |
| internal/database/*.go | Database path resolution and validation |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
|
Review from Claude Code using Sonnet 4.5: Security Review ReportDate: 2026-01-21 Executive SummaryA comprehensive security review was conducted on the github-issues-tui codebase. The review identified 4 security issues requiring attention, with the most critical being a database file committed to git history containing potentially sensitive GitHub issue data. Overall, the codebase follows good security practices with proper SQL parameterization, input validation, and secure file permissions. Risk Level: HIGH (due to data exposure in git history) 🔴 CRITICAL ISSUES1. Database File Committed to Git HistoryLocation: DescriptionThe SQLite database file has been committed to git 5 times and contains:
ImpactAnyone with access to this repository's git history can extract all synced GitHub issues and comments, potentially exposing:
RemediationOption 1: Using git-filter-repo (Recommended) # Install git-filter-repo if not already installed
# brew install git-filter-repo # macOS
# pip install git-filter-repo # or via pip
git filter-repo --path .ghissues.db --invert-pathsOption 2: Using git filter-branch git filter-branch --force --index-filter \
"git rm --cached --ignore-unmatch .ghissues.db" \
--prune-empty --tag-name-filter cat -- --allAfter removing from history: # Force push to remote (WARNING: This rewrites history)
git push origin --force --all
git push origin --force --tags2. Missing .gitignore FileLocation: Repository root DescriptionNo Impact
RemediationCreate # Database files
*.db
.ghissues*.db
# Config files with potential secrets
auth.toml
config.toml
.env
.env.*
# Build artifacts
ghissues
*.exe
*.test
*.out
# IDE files
.vscode/
.idea/
*.swp
*.swo
*~
# OS files
.DS_Store
Thumbs.db
.Spotlight-V100
.Trashes
# Development
.ralph-tui/
*.log3. Database File Permissions Too PermissiveLocation: Database files created by the application DescriptionDatabase files are created with default permissions (644), making them readable by all users on the system. This exposes GitHub issue data to other users on shared systems. ImpactOn multi-user systems:
RemediationAdd permission setting after database creation in func InitializeDatabase(dbPath string) (*sql.DB, error) {
db, err := sql.Open("sqlite", dbPath)
if err != nil {
return nil, fmt.Errorf("failed to open database: %w", err)
}
// Set secure file permissions (owner read/write only)
if err := os.Chmod(dbPath, 0600); err != nil {
return nil, fmt.Errorf("failed to set database permissions: %w", err)
}
// ... rest of initializationAlternative: Create the file first with proper permissions: // Create file with secure permissions before opening
f, err := os.OpenFile(dbPath, os.O_RDWR|os.O_CREATE, 0600)
if err != nil {
return nil, err
}
f.Close()
|
| Category | Rating | Notes |
|---|---|---|
| Data Exposure | HIGH | Database in git history |
| Authentication | MEDIUM | Plaintext token storage, mitigated by file permissions |
| Code Security | LOW | Good practices, proper parameterization |
| Input Validation | LOW | Proper validation implemented |
| Overall Risk | HIGH | Primarily due to git history exposure |
🔍 TESTING METHODOLOGY
The following security testing methods were employed:
-
Pattern Matching
- Searched for common secret patterns (API keys, tokens, passwords)
- Regex-based detection of credentials
-
Code Review
- Manual review of authentication logic
- Analysis of file handling and permissions
- SQL query examination
-
Git History Analysis
- Checked for committed secrets and sensitive files
- Analyzed file permissions in working directory
-
Dependency Analysis
- Reviewed external dependencies
- No known vulnerable dependencies detected
-
Static Analysis
- Pattern detection for common vulnerabilities
- Path traversal, command injection, SQL injection checks
📞 NEXT STEPS
- Immediate: Address all critical issues before public release
- Review: Have another developer review the remediation changes
- Test: Verify fixes don't break existing functionality
- Document: Update README with security best practices
- Monitor: Set up security scanning in CI/CD pipeline
🔐 COMPLIANCE & BEST PRACTICES
This review considered:
- OWASP Top 10 vulnerabilities
- CWE (Common Weakness Enumeration) database
- Go security best practices
- GitHub security recommendations
Conclusion: The codebase demonstrates good security awareness with proper SQL parameterization, input validation, and secure file handling. The primary security concerns are operational (git hygiene) rather than code-level vulnerabilities. Addressing the critical issues will significantly improve the security posture of this project.
Created using the Z.ai GLM-4.7 model on the Z.ai coding plan, using Claude Code as the agent and the ralph-tui as the "driver".
This mostly works on the one shot, however it also struggled with the scrolling and keybindings. With a couple additional prompts I was able to get it working. Functionally, it's probably the most complete, though it would need more tweaks to be "production ready"
Scrolling through the issues does update the details pane, though it does seem to be struggling with the embedded images.