Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
42 changes: 21 additions & 21 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -9,48 +9,48 @@ on:
jobs:
build:
runs-on: ubuntu-latest

strategy:
matrix:
node-version: [18, 20]

steps:
- name: Checkout code
uses: actions/checkout@v4
with:
fetch-depth: 0 # Fetch full history for semantic-release
fetch-depth: 0 # Fetch full history for semantic-release

- name: Install pnpm
uses: pnpm/action-setup@v4
with:
version: latest
run_install: false

- name: Setup Node.js ${{ matrix.node-version }}
uses: actions/setup-node@v4
with:
node-version: ${{ matrix.node-version }}
cache: 'pnpm'
cache: "pnpm"

- name: Get pnpm store directory
shell: bash
run: |
echo "STORE_PATH=$(pnpm store path --silent)" >> $GITHUB_ENV

- name: Setup pnpm cache
uses: actions/cache@v4
with:
path: ${{ env.STORE_PATH }}
key: ${{ runner.os }}-pnpm-store-${{ hashFiles('**/pnpm-lock.yaml') }}
restore-keys: |
${{ runner.os }}-pnpm-store-

- name: Install dependencies
run: pnpm install --frozen-lockfile

- name: Build TypeScript
run: pnpm run compile

- name: Check for build artifacts
run: |
if [ ! -d "lib" ]; then
Expand All @@ -63,47 +63,47 @@ jobs:
runs-on: ubuntu-latest
needs: build
if: github.ref == 'refs/heads/master' || github.ref == 'refs/heads/main'

steps:
- name: Checkout code
uses: actions/checkout@v4
with:
fetch-depth: 0
persist-credentials: false

- name: Install pnpm
uses: pnpm/action-setup@v4
with:
version: latest
run_install: false

- name: Setup Node.js
uses: actions/setup-node@v4
with:
node-version: 20
cache: 'pnpm'
cache: "pnpm"

- name: Get pnpm store directory
shell: bash
run: |
echo "STORE_PATH=$(pnpm store path --silent)" >> $GITHUB_ENV

- name: Setup pnpm cache
uses: actions/cache@v4
with:
path: ${{ env.STORE_PATH }}
key: ${{ runner.os }}-pnpm-store-${{ hashFiles('**/pnpm-lock.yaml') }}
restore-keys: |
${{ runner.os }}-pnpm-store-

- name: Install dependencies
run: pnpm install --frozen-lockfile

- name: Build TypeScript
run: pnpm run compile

- name: Release
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
NPM_TOKEN: ${{ secrets.NPM_TOKEN }}
run: pnpm run semantic-release
run: pnpm run semantic-release
1 change: 1 addition & 0 deletions .husky/pre-commit
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
pnpm lint-staged
8 changes: 8 additions & 0 deletions .lintstagedrc.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
{
"*.{ts,js}": [
"dprint fmt"
],
"*.{json,md,yml,yaml,toml}": [
"dprint fmt"
]
}
117 changes: 9 additions & 108 deletions CLAUDE.md
Original file line number Diff line number Diff line change
@@ -1,116 +1,17 @@
# CLAUDE.md

This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.
GitHub CLI tool for cleaning up merged PR branches.

## Project Overview
Ghouls is a GitHub CLI tool for cleaning up pull request branches. It identifies and deletes both remote and local branches that have been merged but not cleaned up.
## Commands

## Development Commands

### Build
```bash
pnpm compile # Compiles TypeScript to JavaScript in lib/ directory
```
pnpm compile # Build
pnpm test # Test
pnpm install # Install deps

### Installation
```bash
pnpm add -g ghouls # Install globally
pnpm install # Install dependencies
```

### Testing
The project uses Vitest for comprehensive unit testing.

```bash
pnpm test # Run all tests
pnpm test:watch # Run tests in watch mode
pnpm test:coverage # Generate coverage reports
ghouls remote [--dry-run] [owner/repo] # Clean remote branches
ghouls local [--dry-run] [owner/repo] # Clean local branches
ghouls all [--dry-run] [owner/repo] # Clean both
```

### TypeScript Compiler
The project uses strict TypeScript configuration with:
- Target: ES2022
- Module: ES2022
- Output directory: `./lib`
- Strict type checking enabled
- No unused locals/parameters allowed

## Architecture

### Core Components

1. **OctokitPlus** (`src/OctokitPlus.ts`): Wrapper around GitHub's Octokit API client
- Handles GitHub API operations for references and pull requests
- Provides async iterator pattern for paginated results
- Key methods: `getReference()`, `deleteReference()`, `getPullRequests()`

2. **CLI Entry Point** (`src/cli.ts`): Main command-line interface using yargs
- Registers available commands (`remote`, `local`, and `all`)
- Handles unhandled promise rejections

3. **Remote Command** (`src/commands/PrunePullRequests.ts`): Remote branch cleanup
- Iterates through closed pull requests
- Checks if branch SHA matches PR merge state
- Deletes remote branches that have been merged (with --dry-run option)
- Shows progress bar during operation

4. **Local Command** (`src/commands/PruneLocalBranches.ts`): Local branch cleanup
- Scans local branches for safe deletion candidates
- Verifies local branch SHA matches PR head SHA before deletion
- Protects current branch and branches with unpushed commits
- Includes comprehensive safety checks and dry-run mode
- Shows detailed analysis and progress during operation

5. **All Command** (`src/commands/PruneAll.ts`): Combined branch cleanup
- Executes remote pruning first, then local pruning
- Continues with local cleanup even if remote fails
- Provides combined summary of both operations
- Supports --dry-run and --force flags for both phases
- Ensures maximum cleanup efficiency in a single command

6. **Utilities** (`src/utils/`):
- `createOctokitPlus.ts`: Factory for creating authenticated Octokit instances
- `ownerAndRepoMatch.ts`: Validates PR head/base repository matching
- `localGitOperations.ts`: Local git operations (list branches, get status, delete branches)
- `branchSafetyChecks.ts`: Safety validation for branch deletion
- `getGitRemote.ts`: Git remote URL parsing and repository detection

### Authentication
Ghouls uses GitHub CLI authentication exclusively. Users must have the GitHub CLI (`gh`) installed and authenticated with `gh auth login`. The tool automatically uses the existing GitHub CLI authentication credentials.

### Command Usage
```bash
# Remote branch cleanup
ghouls remote [--dry-run] [owner/repo]

# Local branch cleanup
ghouls local [--dry-run] [owner/repo]

# Combined cleanup (both remote and local)
ghouls all [--dry-run] [owner/repo]
```

All commands support repository auto-detection from git remotes when run within a git repository.

## AI Team Configuration (autogenerated by team-configurator, 2025-08-01)

**Important: YOU MUST USE subagents when available for the task.**

### Technology Stack Detected
- Language: TypeScript with strict type checking (ES2022 target)
- Runtime: Node.js (>=18.0.0)
- CLI Framework: yargs for command-line interface
- GitHub API: @octokit/rest for GitHub API interactions
- Build System: TypeScript compiler with pnpm package manager
- Package Management: pnpm with semantic-release
- Test Framework: Vitest with comprehensive unit tests

### AI Team Assignments

| Task | Agent | Notes |
|------|-------|-------|
| Code reviews and quality assurance | code-reviewer | Required for all PRs and feature changes |
| Performance optimization and profiling | performance-optimizer | Essential for CLI tool responsiveness |
| Backend development and API integration | backend-developer | Handles GitHub API integration and CLI logic |
| API design and GitHub integration specs | api-architect | Designs interfaces for GitHub API wrapper |
| Documentation updates and maintenance | documentation-specialist | Maintains README, API docs, and user guides |
Uses GitHub CLI auth (`gh auth login`). TypeScript/Node.js/pnpm project.
16 changes: 13 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,16 +2,16 @@

<img src="logo.webp" alt="Ghouls Logo" width="200">


The ghouls can help you.

# Breaking Changes

## v2.0.0

- **Command names have changed:**
- `prunePullRequests` → `remote`
- `pruneLocalBranches` → `local`

If you have scripts using the old commands, please update them to use the new shorter names.

# Getting started
Expand Down Expand Up @@ -100,13 +100,15 @@ For other platforms and more installation options, visit: https://cli.github.com
Safely deletes remote branches that have been merged via pull requests.

Run from within a git repository (auto-detects repo):

```bash
ghouls remote --dry-run
```

The auto-detection feature works with both github.com and GitHub Enterprise repositories, automatically detecting the repository owner/name from the remote URL.

Or specify a repository explicitly:

```bash
ghouls remote --dry-run myorg/myrepo
```
Expand All @@ -125,11 +127,13 @@ $ ghouls remote myorg/myrepo
Safely deletes local branches that have been merged via pull requests. This command includes comprehensive safety checks to protect important branches and work in progress.

Run from within a git repository (auto-detects repo):

```bash
ghouls local --dry-run
```

Or specify a repository explicitly:

```bash
ghouls local --dry-run myorg/myrepo
```
Expand Down Expand Up @@ -181,18 +185,21 @@ Summary:
The `all` command combines both remote and local branch cleanup in a single operation, running them in sequence for maximum efficiency.

Run from within a git repository (auto-detects repo):

```bash
ghouls all --dry-run
```

Or specify a repository explicitly:

```bash
ghouls all --dry-run myorg/myrepo
```

### Execution Order

The command executes in two phases:

1. **Remote cleanup**: Deletes merged remote branches first
2. **Local cleanup**: Then deletes corresponding local branches

Expand Down Expand Up @@ -236,18 +243,21 @@ Local cleanup: ✅ Success
The project uses Vitest for comprehensive unit testing.

### Run tests

```bash
pnpm test
```

### Run tests in watch mode

```bash
pnpm test:watch
```

### Generate coverage reports

```bash
pnpm test:coverage
```

The test suite includes comprehensive unit tests covering all core functionality, utilities, and edge cases.
The test suite includes comprehensive unit tests covering all core functionality, utilities, and edge cases.
36 changes: 36 additions & 0 deletions dprint.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
{
"typescript": {
"lineWidth": 120,
"indentWidth": 2
},
"json": {
},
"markdown": {
},
"toml": {
},
"malva": {
},
"markup": {
},
"yaml": {
},
"excludes": [
"**/node_modules",
"**/*-lock.json",
"pnpm-lock.yaml",
"coverage/**/*",
"lib/**/*",
".claude/settings.local.json",
".claude/settings.json"
],
"plugins": [
"https://plugins.dprint.dev/typescript-0.95.10.wasm",
"https://plugins.dprint.dev/json-0.20.0.wasm",
"https://plugins.dprint.dev/markdown-0.19.0.wasm",
"https://plugins.dprint.dev/toml-0.7.0.wasm",
"https://plugins.dprint.dev/g-plane/malva-v0.14.1.wasm",
"https://plugins.dprint.dev/g-plane/markup_fmt-v0.23.1.wasm",
"https://plugins.dprint.dev/g-plane/pretty_yaml-v0.5.1.wasm"
]
}
Loading