A modern, secure, and timezone-aware GitHub PR/issue analytics CLI tool. It provides a clean, interactive command-line interface for retrieving, filtering, and analyzing pull request activity with flexible filtering and accurate participation tracking.
π Secure Authentication: OAuth device flow for secure GitHub login without storing plaintext tokens
π Interactive CLI: User-friendly interface with prompts and rich output formatting
β° Participation Tracking: Accurately tracks user PR participation (reviews, comments, authored PRs)
π Timezone-Aware: Built with Luxon for reliable date handling across timezones
β‘ Fast & Modern: TypeScript-based, modular, and designed for performance
π§ͺ Test Coverage: Comprehensive test suites with Vitest
π οΈ Modular Design: Structured commands and features for maintainability and extensibility
π Token Management: Secure token storage via system keychain (keytar)
π Multiple Output Formats: Supports table, JSON, and plain text formats
π Private Repository Support: Optional access to private repositories with --repo-scope private option
π Read-Only Operations: Only reads repository data, never modifies or creates content
π Scope Consistency: Login and command execution must use matching repository scopes
npm install -g @octoreport/cli- Node.js >= 18
- npm or yarn
- GitHub account
- detect-secrets installed (required for contributors)
# Login to GitHub for public repositories (first time only)
octoreport login
# Or login with private repository access
octoreport login --repo-scope private
# Get comprehensive PR activity report (public repositories)
octoreport all
# Get report in JSON format
octoreport all --format json
# Access private repositories (must login with --repo-scope private first)
octoreport all --repo-scope private--repo-scope option used in commands must match the scope used during login. If you get a "Repository scope mismatch" error, log out and log in again with the desired scope.
The CLI uses GitHub's OAuth device flow for secure authentication:
# Login for public repositories (default)
octoreport login
# Login for private repositories
octoreport login --repo-scope privateThis will:
- Open a browser window for GitHub authentication
- Securely store your token in the system keychain
- Automatically handle token refresh and management
# Example: Login with private scope
octoreport login --repo-scope private
# Then use the same scope in commands
octoreport all --repo-scope private
# If scopes don't match, you'll get an error:
# "Repository scope mismatch. Please log in again."To switch scopes:
# 1. Logout
octoreport logout
# 2. Login with desired scope
octoreport login --repo-scope public # or privateThe OAuth app requests different scopes based on your needs:
Default (--repo-scope public):
public_repo- Full access to public repositories (read/write)read:user- Read user profile information
With --repo-scope private:
repo- Full repository access (public and private)read:user- Read user profile information
β Security Note: Both scopes grant read/write access to repositories, not just read-only access.
Get comprehensive PR activity report with both created and participated PRs.
# Basic usage (public repositories only)
octoreport all
# alias
octoreport a
# With custom format
octoreport all --format json
octoreport all --format table
# Access private repositories (requires login with --repo-scope private)
octoreport all --repo-scope private
# Combine options
octoreport all --repo-scope private --format jsonOptions:
--format <format>- Output format (table, json, general) [default: table]--repo-scope <scope>- Repository access scope (public, private) [default: public]- Must match the scope used during login
- Use
publicfor public repositories only - Use
privatefor both public and private repositories
Interactive Prompts:
- Username (optional - uses authenticated user if skipped)
- Repository (e.g., octoreport/cli)
- Start date (YYYY-MM-DD)
- End date (YYYY-MM-DD)
- Target branch (optional - all branches if skipped)
Output:
- User created PRs with detailed information
- User participated PRs (reviews, comments)
- Search criteria summary
- Formatted tables or JSON data
Displays data in beautifully formatted ASCII tables:
ββββββββββ¬βββββββββββββββββββββ¬βββββββββββββ¬βββββββββββββ¬ββββββββββββββββββββββββββββββββββββββββββββββ¬βββββββββ¬βββββββββββββββ¬βββββββββββββββ
β Number β Title β Author β Branch β URL β State β Created At β Merged At β
ββββββββββΌβββββββββββββββββββββΌβββββββββββββΌβββββββββββββΌββββββββββββββββββββββββββββββββββββββββββββββΌβββββββββΌβββββββββββββββΌβββββββββββββββ€
β 123 β Add new feature β octocat β main β https://github.com/.../pull/123 β MERGED β 2025-01-15 β 2025-01-16 β
ββββββββββ΄βββββββββββββββββββββ΄βββββββββββββ΄βββββββββββββ΄ββββββββββββββββββββββββββββββββββββββββββββββ΄βββββββββ΄βββββββββββββββ΄βββββββββββββββ
Returns structured JSON data for programmatic use:
{
"created": [
{
"number": 123,
"title": "Add new feature",
"url": "https://github.com/octoreport/core/pull/123",
"author": "octocat",
"targetBranch": "main",
"state": "MERGED",
"createdAt": "2025-01-15T10:30:00Z",
"mergedAt": "2025-01-16T14:20:00Z"
}
],
"participated": [
{
"number": 125,
"title": "Update documentation",
"url": "https://github.com/octoreport/core/pull/125",
"author": "other-user",
"targetBranch": "main",
"state": "OPEN",
"reviewers": ["octocat"],
"commenters": ["octocat"]
}
]
}Simple text output for quick viewing:
ππ User Created PRs:
[
{
number: 123,
title: "Add new feature",
url: "https://github.com/octoreport/core/pull/123",
...
}
]
ππ User Participated PRs:
[
{
number: 125,
title: "Update documentation",
url: "https://github.com/octoreport/core/pull/125",
...
}
]
The CLI returns the same data structure as the core library:
// @octoreport/core
interface PR {
// Basic PR information (always available)
number: number;
title: string;
url: string;
createdAt: string;
user: string | null;
// Detailed information (may be null if API access is limited)
targetBranch?: string;
assignees?: string[];
state?: 'OPEN' | 'CLOSED' | 'MERGED';
merged?: boolean;
isDraft?: boolean;
mergeable?: 'MERGEABLE' | 'CONFLICTING' | 'UNKNOWN';
labels?: string[] | null;
author?: string | null;
reviewers?: string[] | null;
commenters?: string[] | null;
reviewDecision?: 'CHANGES_REQUESTED' | 'APPROVED' | 'REVIEW_REQUIRED' | null;
mergedAt?: string | null;
requestedReviewers?: string[] | null;
// Participation data
reviews?: (ReviewsRaw | null)[] | null;
comments?: CommentsRaw[] | null;
}The CLI is organized into modular components for better maintainability:
src/
βββ commands/ # Command definitions and handlers
β βββ all/ # All command implementation
β βββ index.ts # Command registration
β βββ withCommandContext.ts # Command context wrapper
βββ config/ # Configuration and setup
β βββ commander.ts # Commander.js setup
β βββ packageInfo.ts # Package information
βββ features/ # Feature modules
β βββ auth/ # Authentication and token management
β βββ prompts/ # Interactive prompts
β βββ ui/ # UI components and formatting
βββ index.ts # Main entry point
The CLI implements a security-first approach to repository access:
Default Behavior (Recommended):
- Requests
public_reposcope by default - Provides read/write access to public repositories only
- Includes access to public repository settings and webhooks
- Minimizes security exposure for most use cases
Private Repository Access:
- Use
--repo-scope privateto enable private repository access - Requests
reposcope which provides full repository access - Includes access to organization resources and team memberships
- Requires re-authentication when switching between public/private access
- Clearly indicates access level in the output
Scope Consistency Requirement:
β οΈ The--repo-scopeused in commands must match the scope used during login- Different scopes are stored separately in the system keychain
- Switching scopes requires logout and re-login
- Attempting to use mismatched scopes will result in:
Repository scope mismatch. Please log in again.
Security Notice: Both scopes grant read/write access, not just read-only access.
What this tool actually does:
- Reads PR activity data from repositories
- Generates reports and analytics
- Does NOT create, modify, or delete any repository content
- Does NOT make any changes to your repositories
- Token is securely stored in your OS keychain
- Tokens are securely stored using the system keychain (keytar)
- No tokens are stored in plain text or configuration files
- Automatic token refresh and validation
- Different tokens for different access levels
- Uses GitHub's OAuth device flow for secure authentication
- No need to manually create or manage personal access tokens
- Automatic scope management and validation
- Clear indication of requested permissions during authentication
# Clone the repository
git clone https://github.com/octoreport/cli.git
cd cli
# Install dependencies
npm install
# Run tests
npm test
# Build the CLI
npm run build
# Link for local development
npm linknpm run build # Build the CLI
npm test # Run tests
npm run dev:test # Run tests in watch mode
npm run lint # Run ESLint
npm run lint:fix # Fix ESLint issues
npm run format # Format code with Prettier
npm run format:check # Check code formatting# Run all tests
npm test
# Run tests in watch mode
npm run dev:test
# Run specific test file
npm test -- tests/index.test.tsWe welcome contributions! ππ»
Please read our Contributing Guidelines before submitting any changes. The guidelines include:
- Security Setup: Required detect-secrets configuration to prevent token leaks
- Development Workflow: Branching, testing, and PR process
- Code Style: TypeScript guidelines and quality standards
# Clone the repository
git clone https://github.com/octoreport/cli.git
cd cli
# Install dependencies
npm install
# Install detect-secrets (via pipx recommended)
brew install pipx
pipx install detect-secrets
# Ensure baseline file exists
ls .secrets.baseline
# Run an initial scan (if baseline needs update)
detect-secrets scan \
--exclude-files 'node_modules/.*' \
--exclude-files '.*package-lock\.json' \
--exclude-files '.*yarn\.lock' \
> .secrets.baseline
git add .secrets.baseline
git commit -m "chore(security): update detect-secrets baseline"This project is licensed under the MIT License - see the LICENSE file for details.
- @octoreport/core for the analytics engine
- commander.js for CLI framework
- inquirer for interactive prompts
- chalk for terminal styling
- boxen for beautiful boxes
- cli-table3 for table formatting
- keytar for secure token storage
