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

pi-grill

v0.4.1

Published

Dependency-driven design interview for the pi coding agent. Asynchronous TUI panel, JSON state source, skip/note support, and a final implementation plan.

Downloads

178

Readme

pi-grill

A dependency-driven design interview for the pi coding agent.

The agent interviews you about a plan or design one decision at a time, then writes an implementation plan once you confirm. The panel is asynchronous: publishing questions never blocks the agent, so it keeps investigating while you answer.

pi-grill demo: answer, refine, note, skip, custom answer, converge, plan

One real take: answer the recommended option → the agent instantly follows up → send an off-script note (Ctrl+N) → skip a question (Ctrl+S) → type a custom answer → confirm convergence → a plan lands in docs/plans/ with the full interview transcript.

Install

pi install git:github.com/luw2007/[email protected]

Then restart pi or run /reload. To try it without installing: pi -e git:github.com/luw2007/pi-grill.

Usage

/grill port the review command to a pi extension

The agent then calls the grill_ask tool with one or more questions. They appear in a persistent TUI panel: a ledger of every question on the left, the selected question on the right.

| Keys | Action | | --- | --- | | ↑ / ↓ (k / j) | Move between options or ledger rows | | ← (h) | Previous question in the ledger | | → / Enter (l) | Confirm the selected option | | Tab / Shift+Tab | Switch between the ledger and the answer pane | | Ctrl+1 … Ctrl+9, Ctrl+0 | Jump straight to ledger question 1–10 | | Ctrl+S | Skip the current question | | Ctrl+N | Add a note for the agent, not tied to any question | | ? | Toggle the in-panel key help | | Ctrl+Alt+G | Toggle the active Grill panel | | Esc / q | Hide the panel; it reopens automatically for a new question | | Ctrl+C / Ctrl+D | Return focus to the editor, then abort / shut down |

Terminal note: Ctrl+1…Ctrl+0 and Ctrl+Alt+G need a terminal with the kitty keyboard protocol or xterm modifyOtherKeys (ghostty, kitty, WezTerm, iTerm2 — pi negotiates this automatically). In Terminal.app or default tmux those chords have no distinct encoding and arrive as plain keystrokes: use the arrow keys to reach ledger rows, and rebind the toggle via toggleShortcut in the configuration.

Ordinary options commit on Enter. Options marked requiresText, and the built-in Something else (type it), open a mandatory text field first.

On short terminals the panel fits itself to the window: the ledger shrinks first, and if content still overflows, the middle is elided with a … N lines hidden marker so the answer area and footer stay visible and interactive.

After a successful answer or skip, the panel hides while the agent continues investigating. Publishing a new question reopens it, selects that batch's current question, and scrolls the ledger until it is visible.

Commands

| Command | Action | | --- | --- | | /grill <idea> | Start or resume an interview for that idea | | /grill-panel | Reopen and focus the panel after Esc |

Skips, notes, and changing your mind

  • Ctrl+S marks a question skipped. Skipped questions do not block convergence and can still be answered later.
  • Ctrl+N records a free-form note. Notes are appended to the state, steered to the agent immediately, and preserved in the final plan.
  • Any answered or skipped question can be reopened and overwritten; the ledger keeps the latest answer.

Ending a session

Convergence is dependency-driven: once no pending or current questions and no unresolved decision dependencies remain, the agent asks a final confirmation. Section coverage is never a convergence requirement. Confirming writes the plan into the first existing directory among docs/plans/ and plans/, then closes the panel and clears the status widget. The plan derives its body headings and their order freely from substantive content—there is no fixed heading pool, required order, minimum section count, empty sections, or N/A placeholders—and always ends with a complete ## Interview transcript. The JSON state file is kept — rerun /grill with the same description to resume, or delete it yourself.

Declining the confirmation keeps the interview alive: the panel reopens with focus, and the final question stays re-answerable — answering it again with a converge keyword (default confirm, converge, yes, 确认, 生成) asks for confirmation again.

Tool contract

grill_ask takes a batch of questions and returns immediately:

{
  "questions": [
    {
      "id": "Q1",
      "section": "4. Design",          // free-form grouping label
      "question": "Which storage layer?",
      "context": "Why this matters and what the answer decides.",
      "options": [
        { "value": "sqlite", "label": "SQLite", "description": "…",
          "recommended": true, "recommendationReason": "…" },
        { "value": "other", "label": "Something custom", "requiresText": true }
      ],
      "recommended": "sqlite"
    }
  ],
  "converge": false
}

Answers arrive back asynchronously as a grill-answers custom message (batched within 500 ms), and notes as grill-note. Each event carries the batch plus an incremental open-questions summary; the full state summary stays on the grill_ask result. The section value only groups and indexes ledger questions; it does not constrain or decide which headings appear in the plan.

State

Each session has a single JSON state source under <tmpdir>/grill/<project>-<cwd-digest>/<hash>.json (the digest keeps same-named projects apart), plus an HTML mirror rendered from it. The JSON is authoritative: the panel, the status widget, and the plan all derive from it. The section index is a derived section → [{ id, status }] projection of questions; it is not persisted as a second source of truth.

The state deliberately lives in the OS tmpdir: it is interview scratch, not a durable artifact. macOS may purge it after a few days without access — a long-paused interview may need a fresh /grill run.

The state is schemaVersion 4. Upgrades are not backward compatible: a state file from an older schema, or one with missing or conflicting required fields, is treated as corrupt. pi-grill refuses to load it, leaves the file untouched, and asks you to delete or repair it.

Configuration

Optional, at ~/.pi/agent/grill.config.json:

{
  "convergeKeywords": ["confirm", "converge", "yes"],
  "optionScrollThreshold": 8,
  "toggleShortcut": "ctrl+alt+g"
}

optionScrollThreshold is how many option blocks are shown before the answer pane starts scrolling (1–100, default 8). toggleShortcut controls the panel shortcut using Pi key syntax (default ctrl+alt+g); choose a key that does not collide with a Pi built-in or another extension. An invalid config is reported and safe defaults are used.

Alternate entrypoint

grill-omp.ts re-exports the same extension for hosts that load a differently named entrypoint:

export { default } from "./grill.ts";

The implementation stays single-sourced in grill.ts; the re-export exists only so such a host can point at grill-omp.ts without a second copy of the code. If you install with pi install, ignore it and use grill.ts.

Notes for developers

Runs entirely in the pi TUI via @earendil-works/pi-tui. No network access and no npm runtime dependencies — @earendil-works/pi-tui and typebox are provided by pi as peer dependencies.

bun test
bunx tsc -p tsconfig.tests.json
npm run e2e   # full-loop regression against a real pi TUI with a deterministic local mock model
npm run e2e:omp   # OMP host-contract regression (crash class: overlay handles missing focus/unfocus); skips if omp is absent

Host-contract invariants (learned from real pi/OMP behaviour; changes must respect them):

  • A focused overlay is pi's input terminal stop: it starves every app keybinding and every registerShortcut chord. Any shortcut that must work while the panel is focused has to be handled inside the panel component too (that is why the toggle chord appears in both places).
  • ctrl+digit chords have no legacy terminal encoding — only kitty CSI-u / modifyOtherKeys forms exist. Never bind a feature to them without a fallback path.
  • OMP's native runtime can deviate from its bundled pi typings. Verified on OMP 17.3.4: showOverlay handles expose only { hide, setHidden, isHidden } — no focus/unfocus — and the host input dispatch has no try/catch around handleInput, so one unguarded handle call crashes the whole OMP process. Typings are not acceptance evidence for OMP; verify against the live host and guard every handle method defensively (focus?.(), unfocus?.()).
  • On OMP, sendUserMessage(..., { deliverAs: "followUp" }) while idle queues the message but does not start a turn (observed 17.3.4 with an isolated mock-model repro); the interview begins on the user's next input. On pi it triggers immediately.
  • Extension messages: only content reaches the model; details is UI/transcript-only. sendUserMessage must always pass deliverAs: "followUp" — an idle check races the agent starting a run and drops the message.
  • Two sessions sharing one state file coordinate via the watcher and monotonic revisions, but truly simultaneous commits are last-rename-wins; there is deliberately no file locking.

Acknowledgements

  • mattpocock/skills — grilling inspired the design-interview approach: resolve a plan through focused, sequential questions.
  • edlsh/pi-ask-user informed the Pi-native structured-question interaction model, including multiple-choice and free-text answers.

pi-grill is an independent implementation; it does not include code from either project.

License

MIT