omp packages

pi-pr-state0.2.0

Compact clickable GitHub and Forgejo PR status for Pi footers

caprika Published 9 days ago MIT ~492 downloads/mo

Untested on omp

This is a pi package. No one has reported whether it works on omp yet. If you try it, add your result below.

Did it work for you?

Result

One report per person. A new report replaces your old one.

Reports 0

No reports yet.

Readme

pi-pr-state

Compact, clickable pull-request and CI status for Pi, supporting GitHub and Forgejo in the same installation.

PR #123 CI passing
PR #123 CI failing
PR #123 draft CI pending
PR #123 no checks
PR #123 CI unknown

The PR number links to its web page in terminals supporting OSC 8 hyperlinks. PR and CI use Pi's theme colors. It publishes a normal extension status (pull-request), not a replacement footer, and works with Zentui.

Install

Requires Node.js 24+ and Pi. Tested with Pi 1.1.0 and Zentui 0.30.0.

pi install npm:pi-pr-state

Run /reload in an existing session. Avoid loading another PR-status extension alongside this package.

GitHub

Install GitHub CLI and authenticate:

gh auth login

github.com works without extra configuration. Repository and branch are passed explicitly, so GH_HOST does not accidentally select a different forge. For GitHub Enterprise, add a server entry with "type": "github" and its HTTPS URL, and authenticate gh for that host.

Forgejo

Create ~/.pi/agent/extensions/pull-request.json (or extensions/pull-request.json under PI_CODING_AGENT_DIR):

{
  "servers": [
    {
      "type": "forgejo",
      "url": "https://forgejo.example.com",
      "tokenEnv": "FORGEJO_TOKEN"
    }
  ]
}

Supply FORGEJO_TOKEN through your secret manager or environment before launching Pi. The configuration stores only its variable name, never the token. Use a token with read:repository and the narrowest repository access supported by your instance. See Forgejo token scopes. Omit tokenEnv for anonymous public access.

Only explicitly configured HTTPS servers are queried. For an SSH alias or a separate SSH hostname, add "sshHost": "company-git"; this supplements the canonical hostname. Server URLs can include an API base path and port. Inline credentials, URL query strings and fragments are rejected. Existing tea credentials are not automatically read.

Repository selection and forks

Selection order: explicit remote, branch pushRemote, remote.pushDefault, origin, branch tracking remote, then a sole remote. Preferring origin over tracking avoids selecting an old read-only mirror after a forge migration. Ambiguous remotes produce a configuration hint rather than guessing.

For a PR from a fork, select the source and target explicitly:

{
  "remote": "origin",
  "baseRemote": "upstream",
  "servers": [
    { "type": "forgejo", "url": "https://forgejo.example.com", "tokenEnv": "FORGEJO_TOKEN" }
  ]
}

The head repository and branch must match the source remote. Cross-server forks are not supported. Detached HEAD, unborn repositories, no remote and no matching PR do not show a PR status.

Zentui hyperlinks

In ~/.pi/agent/zentui.json, merge this setting under components.footer.styles.starship.extensionStatuses:

{
  "colorModes": {
    "pull-request": "original"
  }
}

Original mode preserves safe HTTP(S) OSC 8 links and the extension's theme colors. Keep default placement left. Remove the native (PR #$pr_number)( $ci) portion of wide and compact templates to avoid duplicate PR/CI labels. Compact templates need $extensions; wide placement is handled separately by Zentui. No Zentui source patch is needed.

The terminal determines the click gesture. Generating/preserving OSC 8 sequences does not guarantee that a particular terminal makes them clickable. Narrow layouts may hide the status.

Refresh and CI behavior

  • Event-driven refresh on TUI session start, after agent turns, relevant Git/gh/tea tool completion, and Git HEAD/ref/config changes. No fixed polling or CI-only refresh loop.
  • /pr-refresh forces a refresh; extensions can emit pull-request:refresh on the Pi event bus. Remote CI changes alone do not notify this local plugin.
  • Transport failures retain the last valid PR with a stale suffix and retry after 2 seconds, then exponential backoff capped at 60 seconds. Success stops compensation; authentication/configuration failures wait for the next event rather than retrying forever.
  • Display-only snapshots under ~/.pi/agent/cache/pr-state/ (or PI_CODING_AGENT_DIR/cache/pr-state) survive reload/restart. Repository, remote, base and branch identity isolate snapshots; cached state starts stale until verified. No discussion bodies, reviewer names or credentials are stored. Unchanged state does not redraw the footer.
  • Shutdown/reload cancels timers, watchers and requests. Stale branch/repository responses are discarded; aborted turns preserve the last valid status.
  • GitHub uses gh pr view; recent closed/merged PRs remain visible for up to 24 hours.
  • Forgejo queries open PRs, rechecks head branch/repository client-side, and queries commit statuses for the PR head SHA. Closed/merged Forgejo PRs are not retained in this initial release.
  • All relevant pages are read: Forgejo combined status is page-local, so reading only the first page can falsely report success.
  • CI that does not publish commit statuses cannot be inferred as passing. Permission, transport or schema failures show CI unknown, not green or a fabricated no-checks result.

The adapter performs read-only requests: no PR creation, comments, reviews, merges or check updates. Forgejo redirects are forbidden, Authorization is sent only to the configured server, requests have a 20-second budget, each response is capped at 1 MiB, and pagination is capped at 20 pages. Raw response bodies and credential values are not displayed or logged. Unknown hosts show PR host config rather than receiving an authenticated request.

Development and validation

In the local development source tree, using Node 24, global TypeScript and an installed Pi:

node tools/link-host.mjs
npm run typecheck
npm test

The host-link helper creates local peer/type symlinks and refuses to replace different dependencies. Pi itself does not require these links to load the extension.

31 deterministic tests cover configuration, routing, SSH aliases, migrated remotes, forks, pagination, unknown/failing CI, response limits, cancellation, stale results, safe links, stable footer refresh and lifecycle cleanup. Actual GitHub and Forgejo API reads, Pi TUI reloads, outage retention and automatic recovery were also verified separately. Terminal click behavior still depends on your terminal. The npm archive includes runtime source, generic configuration, docs and license only; development/live-test files and private instance data are excluded.

Attribution and license

MIT. Derived from @narumitw/pi-github-pr@0.49.8, retaining its license and session/refresh/link lifecycle. This fork adds dual-provider routing, Forgejo reads, compact PR/CI display and bounded, fail-safe pagination.

References: Forgejo API, public schema, combined-status implementation, Zentui configuration.

Footer integration

Both providers publish the normal pull-request extension status key. Footer extensions can display it without a second provider integration. Provider routing remains in ~/.pi/agent/extensions/pull-request.json. Icon, color and placement customization belongs to your footer extension; this package does not install or patch Powerline or Zentui.

After upgrading with pi update npm:pi-pr-state, run /reload in Pi to activate the new version.