npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

opencode-git-stats

v0.1.2

Published

OpenCode sidebar: working-tree diff stats and GitHub-coloured chips for the pull requests your session touched

Readme

opencode-git-stats

What the working tree looks like right now, and a GitHub-coloured chip for every pull request your OpenCode session touched.

npm CI license OpenCode

Git Stats
⎇ fix-release-prerelease-bump
+123 -45 · 7 files
 #20 Merged  ×  #21 Draft  ×
  • Working-tree figures — total additions, deletions and changed files for the whole folder, not just the files this session edited. They come from OpenCode's own VCS status endpoint, so they agree with git status.
  • Pull request chips — every GitHub PR whose URL turned up in this session's tool output, with GitHub's own state colour: grey Draft, green Open, red Closed, purple Merged. States refresh on their own as the session runs, so a PR you merge mid-session turns purple without a restart.
  • Close a chip — click the × beside it, or run /prs to hide one, hide them all, or bring the hidden ones back. Dismissals are per session and survive a restart.
  • Open the PR — click the chip's label and the pull request opens in your browser. (The label is also an OSC 8 hyperlink, but OpenCode keeps mouse tracking on, so the terminal hands the click to the plugin rather than following the link itself — the plugin opens it.)

Install

This is a TUI plugin, so it goes in tui.json (not opencode.json):

~/.config/opencode/tui.json, or .opencode/tui.json in a project —

{
  "$schema": "https://opencode.ai/tui.json",
  "plugin": ["opencode-git-stats@latest"]
}

Restart OpenCode. The card appears in the sidebar, just above Modified Files.

Requires OpenCode ≥ 1.18. Chip states additionally need the GitHub CLI on your PATH and logged in (gh auth login); without it the chips still appear, uncoloured, and the card says why.

What counts as "a PR this session touched"

Any https://github.com/<owner>/<repo>/pull/<number> URL that appears in the output — or the command line — of a tool call in this session. In practice that is the URL gh pr create prints, plus anything a later gh pr view or gh pr merge names. Prose in the assistant's replies is deliberately not scanned: only what a command actually produced.

Pull requests the session created (the URL came out of a gh pr create) sort ahead of ones it merely referenced. At most 24 chips are tracked per session, so a stray gh pr list --json url cannot fill the sidebar.

GitHub Enterprise

Only github.com is trusted by default, and that is on purpose: the text being scanned is tool output, which can come from a fetched page or a pasted file, and the host in a URL is handed to gh --repo <host>/…. gh treats an unknown host as Enterprise and would make a request to it — with your Enterprise token attached. So github.evil.example and github.com.evil.example are ignored, and a real Enterprise host has to be named:

{
  "plugin": [["opencode-git-stats@latest", { "hosts": ["github.acme.com"] }]]
}

Commands

| Command | Slash | What it does | |---|---|---| | gitstats.chips | /prs, /chips | Hide one chip, hide all of them, or show the hidden ones again |

To put it on a key, add a binding for gitstats.chips in your OpenCode keybinds.

How it works

The plugin is TUI-only and reads everything through OpenCode's official plugin API:

| What | API | |---|---| | working-tree figures | client.vcs.status() | | branch name | state.vcs.branch | | PR sightings | event.on("message.part.updated"), plus a catch-up scan of state.session.messages() / state.part() | | refresh triggers | event.on("session.diff"), event.on("session.idle"), a 10 s tick | | dismissals | kv | | the card | a sidebar_content slot at order 450 |

The one thing OpenCode cannot answer is whether a pull request is draft, open, closed or merged, so the plugin shells out to gh pr view --json state,isDraft. That is the only external call it makes, and it is spawned with an argv array — never a shell string — for a host on the allow-list above.

A merged pull request is terminal and never re-fetched. Open and draft ones age out after 90 seconds, closed ones after five minutes, and the end of every turn marks them all due again. A gh call that fails backs that chip off exponentially, up to about 16 minutes, so a missing or logged-out gh is not re-spawned on every tick; the backoff clears at the end of a turn, in case you have just installed it. Chips you have dismissed are never fetched at all.

Development

bun install
bun run build      # -> dist/tui.js
bun run typecheck
bun test

To try a local build, point tui.json at the built file:

{ "plugin": ["/absolute/path/to/packages/git-stats/dist/tui.js"] }

License

MIT