@the-forge-flow/gh-pi

GH-PI — PI extension for native GitHub CLI (gh) integration

Packages

Package details

extension

Install @the-forge-flow/gh-pi from npm and Pi will load the resources declared by the package manifest.

$ pi install npm:@the-forge-flow/gh-pi
Package
@the-forge-flow/gh-pi
Version
0.2.6
Published
Apr 19, 2026
Downloads
118/mo · 17/wk
Author
the-forge-flow-ai
License
MIT
Types
extension
Size
101.4 KB
Dependencies
0 dependencies · 4 peers
Pi manifest JSON
{
  "extensions": [
    "./dist/index.js"
  ]
}

Security note

Pi packages can execute code and influence agent behavior. Review the source before installing third-party packages.

README


✨ Features

  • 📦 Repositories: create, clone, fork, list, view, delete, sync
  • 🐛 Issues: create, list, view, close, reopen, comment, edit
  • 🔀 Pull Requests: create, list, view, diff, merge, review, close, checkout
  • ⚡ GitHub Actions: list, view, run, logs, disable, enable workflows
  • 🤖 PI-native: seamless integration with PI's tool system, abort-signal aware, output truncated to PI's limits

📦 Installation

1. Install the GitHub CLI

The extension shells out to the gh binary, so it must be on your PATH.

# macOS
brew install gh

# Ubuntu/Debian
sudo apt install gh

# Windows
winget install GitHub.cli

# Other: https://github.com/cli/cli#installation

Verify with gh --version. If it lives somewhere non-standard, set GH_CLI_PATH to its absolute path.

2. Authenticate with GitHub

gh auth login

The extension probes gh auth status on startup and will warn you if you're unauthenticated.

3. Install the extension with pi install

PI discovers the extension automatically once installed as a pi package. By default this installs globally into ~/.pi/agent/; pass -l to install into the current project (.pi/) instead.

From npm (recommended):

pi install npm:@the-forge-flow/gh-pi

From GitHub (tracks main):

pi install git:github.com/MonsieurBarti/GH-PI

Pin to a specific version:

# npm — pin to a published version
pi install npm:@the-forge-flow/gh-pi@0.1.0

# git — pin to a release tag
pi install git:github.com/MonsieurBarti/GH-PI@gh-pi-v0.1.0

Then reload PI with /reload (or restart it). On the next session you should see a notification that the GitHub CLI is ready.

Manage installed packages:

pi list    # show installed packages
pi update  # update non-pinned packages
pi remove npm:@the-forge-flow/gh-pi
pi config  # enable/disable individual extensions, skills, prompts, themes

For project-scoped installs, package filtering, and more, see the pi packages doc.

🚀 Usage

The LLM can call any of the four GitHub tools directly. Each tool takes an action plus the parameters that action needs.

All four tool ids are namespaced with the tff- prefix (tff-github_repo, tff-github_issue, tff-github_pr, tff-github_workflow) to avoid collisions with other pi packages. The user-facing display labels ("GitHub Repository", "GitHub Issue", etc.) stay readable — only the LLM-facing ids are prefixed.

tff-github_repo

// Create a repository
tff-github_repo({
  action: "create",
  name: "my-new-project",
  visibility: "public",
  auto_init: true,
});

// List your repos (or those of an org)
tff-github_repo({ action: "list", owner: "the-forge-flow", limit: 20 });

// View details
tff-github_repo({ action: "view", owner: "octocat", name: "hello-world" });

tff-github_issue

// Open an issue
tff-github_issue({
  action: "create",
  repo: "owner/repo",
  title: "Flaky integration test",
  body: "Steps to reproduce…",
  labels: ["bug"],
});

// List open issues assigned to you
tff-github_issue({
  action: "list",
  repo: "owner/repo",
  state: "open",
  assignee: "@me",
});

// Close with a reason
tff-github_issue({
  action: "close",
  repo: "owner/repo",
  number: 42,
  reason: "completed",
});

tff-github_pr

// Open a PR
tff-github_pr({
  action: "create",
  repo: "owner/repo",
  title: "Add rate-limit backoff",
  head: "feat/rate-limit",
  base: "main",
});

// Review a PR (request-changes and comment REQUIRE a body)
tff-github_pr({
  action: "review",
  repo: "owner/repo",
  number: 17,
  review_action: "request-changes",
  body: "Please add a test for the retry path.",
});

// Merge with squash and delete the source branch
tff-github_pr({
  action: "merge",
  repo: "owner/repo",
  number: 17,
  method: "squash",
  delete_branch: true,
});

tff-github_workflow

// List workflows
tff-github_workflow({ action: "list", repo: "owner/repo" });

// Trigger a workflow_dispatch with inputs
tff-github_workflow({
  action: "run",
  repo: "owner/repo",
  workflow: "deploy.yml",
  branch: "main",
  inputs: { environment: "production", version: "1.2.0" },
});

// Read the log for a specific run
tff-github_workflow({
  action: "logs",
  repo: "owner/repo",
  run_id: "1234567890",
});

Environment Variables

Variable Description
GH_CLI_PATH Custom path to the gh binary

🏗️ Architecture

┌─────────────┐     ┌──────────────┐     ┌─────────────┐
│  LLM Request│────▶│  GH Tool     │────▶│   gh CLI    │
│  (via PI)   │     │  (defineTool)│     │  (pi.exec)  │
└─────────────┘     └──────────────┘     └──────┬──────┘
                           │                     │
                           │              ┌──────▼──────┐
                           │              │  GitHub API │
                           │              │  (via gh)   │
                           │              └──────┬──────┘
                           │                     │
                    ┌──────▼──────┐              │
                    │  Truncated  │◀─────────────┘
                    │  Response   │
                    │  (JSON/text)│
                    └─────────────┘

Every tool call:

  1. Auto-detects gh and verifies gh auth status on first use (cached for the session).
  2. Builds the exact argv for the underlying gh subcommand.
  3. Executes via pi.exec, propagating the abort signal so Ctrl+C actually interrupts long-running calls.
  4. Maps gh exit codes to typed errors (GHAuthError, GHRateLimitError, GHError).
  5. Truncates output to PI's ~50KB/2000-line limit via truncateHead, with a trailing notice.

🧪 Development

# Install dependencies (also wires lefthook git hooks)
bun install

# Run tests
bun test

# Lint & format
bun run check

# Build for publish
bun run build

📁 Project Structure

src/
├── index.ts           # Extension entry, tool registration, state, truncation
├── gh-client.ts       # Thin pi.exec wrapper with exit-code → error mapping
├── error-handler.ts   # GHNotFoundError / GHAuthError / GHRateLimitError / GHError
├── repo-tools.ts      # gh repo *
├── issue-tools.ts     # gh issue *
├── pr-tools.ts        # gh pr *
└── workflow-tools.ts  # gh workflow * and gh run view --log

🤝 Contributing

  1. Fork the repository
  2. Create your feature branch (git checkout -b feat/amazing)
  3. Commit with conventional commits (git commit -m "feat: add something")
  4. Push to the branch (git push origin feat/amazing)
  5. Open a Pull Request

📜 License

MIT © MonsieurBarti