@gotgenes/pi-github-tools
Pi extension providing deterministic GitHub CI, release, and issue tools.
Package details
Install @gotgenes/pi-github-tools from npm and Pi will load the resources declared by the package manifest.
$ pi install npm:@gotgenes/pi-github-tools- Package
@gotgenes/pi-github-tools- Version
5.0.0- Published
- Sep 1, 2026
- Downloads
- 1,326/mo · 250/wk
- Author
- gotgenes
- License
- MIT
- Types
- extension
- Size
- 54.8 KB
- Dependencies
- 0 dependencies · 1 peer
Pi manifest JSON
{
"extensions": [
"./src/extension.ts"
]
}Security note
Pi packages can execute code and influence agent behavior. Review the source before installing third-party packages.
README
@gotgenes/pi-github-tools
Pi extension providing deterministic GitHub CI, release, and issue tools.
Replaces ad-hoc gh CLI polling with structured tools that have exponential backoff, progress streaming, and structured success/timeout returns.
Install
pi install npm:@gotgenes/pi-github-tools
Alternatively, add it to your Pi settings (~/.pi/agent/settings.json):
{
"packages": ["npm:@gotgenes/pi-github-tools"]
}
Prerequisites
- GitHub CLI (
gh) installed and authenticated (gh auth login) - Node.js ≥ 22
Tools
CI tools
ci_find
Wait for a GitHub Actions run matching a specific commit SHA to appear. Uses exponential backoff (5 s base, 30 s cap) until the run appears or the timeout expires.
| Parameter | Type | Required | Description |
|---|---|---|---|
workflow |
string | yes | Workflow filename without extension (e.g., "ci" for ci.yml) |
expected_sha |
string | yes | Full 40-char SHA of the commit |
timeout |
number | no | Seconds to wait (default: 120) |
Returns run_id, url, status, sha, title, and job list on success.
Returns a structured timeout message (not an error) if the run does not appear.
ci_watch
Poll a GitHub Actions run by run ID until it completes or times out.
Streams compact job-level progress lines (e.g., [2/5] deploy — in_progress (120s)).
| Parameter | Type | Required | Description |
|---|---|---|---|
workflow |
string | yes | Workflow filename without extension |
run_id |
number | yes | Run ID from ci_find |
timeout |
number | no | Seconds to wait (default: 300) |
ci_list
List recent GitHub Actions runs for a workflow.
Useful for diagnostics without constructing gh invocations.
| Parameter | Type | Required | Description |
|---|---|---|---|
workflow |
string | yes | Workflow filename without extension |
limit |
number | no | Number of runs to return (default: 5) |
Transient-failure retry
Every read-only gh call these tools make — ci_find, ci_watch, and ci_list — retries a transient failure up to three times, waiting 1 s, 4 s, then 9 s.
The retry count and backoff curve match @octokit/plugin-retry's defaults.
Retried: HTTP 5xx, GitHub's no server is currently available GraphQL error, and transport errors (connection reset, unexpected EOF, i/o timeout, TLS handshake timeout).
Not retried: any 4xx, including rate limiting — retrying those is useless or harmful.
Mutations (gh pr merge, gh issue close) are never retried automatically.
For a merge, the verification described above is what makes a retry decision safe.
In a polling tool the backoff counts against the call's timeout, so retries cannot silently extend the wait the caller asked for.
Issue tools
issue_close
Close a GitHub issue with an optional comment.
| Parameter | Type | Required | Description |
|---|---|---|---|
issue_number |
number | yes | The issue number to close |
comment |
string | no | Comment to add when closing |
reason |
string | no | "completed" (default) or "not_planned" |
Usage example
A typical CI + release flow using these tools:
1. Push changes to a branch and create a PR.
2. Use ci_find with the pushed SHA to locate the CI run.
3. Use ci_watch to wait for the CI run to complete.
4. Merge the PR.
5. Dispatch the repository's release workflow for the shipped package.
6. Use ci_find and ci_watch with that workflow to follow the release run.
7. Use issue_close to close the shipped issue.
Scope and non-goals
Purpose.
The ship workflow used to have the agent sleep and re-invoke gh in a prose loop, which burned turns and behaved differently every run.
These tools replace that loop with bounded polling, streamed progress, and structured success, timeout, and failure states.
In scope.
Making a tool wait where a human would otherwise wait, making a failure legible as a named reason a prompt can branch on, surviving transient GitHub errors on reads, and refusing to leave an outcome ambiguous.
Non-goals.
- A general-purpose GitHub toolkit.
The surface is scoped to the CI and issue-close flow an agent runs end to end.
An operation with no polling problem — opening a PR, editing labels, dispatching a workflow — is a plain
ghcall and stays one. - Release-tool wrappers.
Earlier versions shipped
release_pr_find,release_pr_merge, andrelease_watch, which encoded release-please's pull-request conventions. A release triggered as a workflow is an ordinary Actions run, soci_findandci_watchalready follow it and no release-specific tool is needed. - A GitHub API client.
The
ghCLI is the sole external binary dependency, and there are no runtime dependencies at all. - Auto-retrying mutations.
Reads retry on transient failures;
issue_closedoes not, since a retried close would post a duplicate comment.
Where adjacent requests belong. Whether to release now, and which packages a release bumps → the calling prompt, not the tool.
Architecture
Portable business logic in src/lib/ — no Pi SDK imports.
Thin Pi wrappers in src/tools/ register each tool and map progress callbacks.
src/
├── extension.ts # Pi extension entry point
├── progress.ts # onProgress → Pi onUpdate adapter
├── tool-result.ts # AgentToolResult helper
├── tools/ # one file per tool (thin wrappers)
└── lib/ # portable business logic
├── ci.ts # findRun, watchRun, listRuns
├── ci-helpers.ts # CIJob, findRetryDelay, formatProgress
├── issue.ts # closeIssue
├── github.ts # gh(), ghJson(), git(), detectRepo()
└── process.ts # runCommand(), sleep()
License
MIT