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

@taylorsatula/pi-checkbox-picker

v0.1.0

Published

Interactive checkbox picker tool for Pi — presents a grouped list of items the user cherry-picks with SPACE and submits as one subset. For 'which of these do we act on?' decisions, where single-choice radios are the wrong instrument.

Readme

@taylorsatula/pi-checkbox-picker

Interactive checkbox picker tool for pi.

Presents a grouped list of items that the user cherry-picks with SPACE and submits as one subset. Use it when the decision is which of these — findings to fix, files to include, tasks to run, options to keep.

pi's built-in questionnaire tool answers which one (mutually-exclusive radios, one value per question). This tool answers which ones (independent checkboxes, one submitted subset), and any row can carry a margin note written with TAB — selected or not. With a checkbox picker the selection is the strategy: checking every row means "do all of them", so there is no need to also offer approach-level options.

Install

pi install npm:@taylorsatula/pi-checkbox-picker

Or add "npm:@taylorsatula/pi-checkbox-picker" to the packages array in settings.json.

What the user sees

──────────────────────────────────────────────────────────────────────
 CATEGORY C2 — Untrusted-content boundary

 MIRA escapes text where it interpolates into prompt structures.
 Fifteen sites do not. All fifteen are verified.

 TIER 1 — EXTERNAL CONTENT INTO THE SYSTEM PROMPT

   Memory text has external provenance: the forage agent holds web_tool
   and stores findings verbatim.

 > [x] BND1  Memories render unescaped into the persistent prompt  [H] ✎
             proactive_memory_trinket.py:_format_primary_memory_xml —
             f"<text>{text}</text>" interpolates memory text raw. The
             composer wraps the block in <mira:hud> with no escaping.
             note: escape at the interpolation point, not in the composer
   [ ] BND2  peanutgallery renders raw conversation into observer  [M]

   ✓ Actualize selected (1 of 15, 1 noted)

 selected 1 of 15 · 1 ✎ · rows 1-18 of 44   [11:02pm - 9/16/26]
 SPACE toggle · TAB note · ↑↓ move · a/n section · A/N all · ENTER submit · ESC cancel
──────────────────────────────────────────────────────────────────────

The row under the cursor expands its detail; every other row stays one line, so a long brief stays scannable and scrolls inside the viewport.

Keys

| Key | Action | |-----|--------| | SPACE | Toggle the row under the cursor | | TAB | Write or edit a margin note on that row (Enter saves, Esc discards the note) | | ↑/↓, k/j | Move | | PgUp/PgDn, g/G | Page, first, last | | a / n | Select / clear the cursor's section (a toggles when already complete) | | A / N or 0 | Select / clear everything | | ENTER | Submit the subset and all notes | | ESC | Cancel (notes written so far are still returned) |

Rows carrying a note show ✎ at their end.

Tool parameters

| Field | Type | Notes | |-------|------|-------| | title | string | Heading at the top of the picker. | | summary | string? | Plain statement of what is being decided, 2-5 short lines. | | sections | array | { heading, context?, items[] }. Sections group rows and scope a/n; they are not selectable. | | sections[].items[] | array | { id, label, detail?, tag? }. | | submitLabel | string? | Defaults to Submit. | | timestamp | string? | Stamp rendered in the footer. | | preselected | string[]? | Item ids that start checked. |

id must be unique across the whole picker — duplicates and missing ids are rejected with an explanatory error rather than rendered ambiguously. tag values H/high, M/medium, L/low are color-coded.

Result

The tool returns the selected rows as text, and details carries the full CheckboxPickerResult:

{
  title: string;
  selected:   { id, label, tag?, section, note? }[];
  unselected: { id, label, tag?, section, note? }[];
  cancelled: boolean;
}

unselected is populated deliberately: what the user left out is a decision too.

note is a margin note the user wrote with TAB, and it can sit on a selected or an unselected row. Both are binding instructions for the caller:

  • On a selected row — adjusts how to implement it ("fix at the write path, not the renderer", "do this one behind a flag").
  • On an unchecked row — usually records why it stays as-is. In an audit workflow that typically means: leave a code comment explaining the intent, so a future pass with no memory of this one reads the reason and does not re-flag it.

Notes survive cancellation, so nothing the user typed is discarded.

Authoring guidance

The schema descriptions carry these rules for the model, and they are what make the picker readable rather than noisy:

  • Rows are the unit of decision: a 3-6 char id, an ~8-word label, and a detail with the actionable specifics (location, mechanism, evidence) so the reader can act from the row alone.
  • Shared context goes in the section's context, stated once — never repeated per item.
  • State the problem plainly in summary. No dramatic framing.
  • Group rows by what makes them similar to decide or fix together.
  • Notes are the user's channel, not yours — there is no note input field. Anything you want visible on a row belongs in its detail.
  • Roughly 5-25 rows per picker; split larger sets by category and ask in sequence.

Development

npm install
npm run check     # tsc --noEmit

Live load probe (non-TUI; exercises loader → registration → schema → execute → guard):

pi -p -nbt -t checkbox_picker \
  "Call checkbox_picker with title='t', sections=[{heading:'S', items:[{id:'T1', label:'x'}]}] and print what it returned."
# → Checkbox picker cancelled: interactive TUI mode is required.

The interactive surface needs a TTY and cannot be verified headlessly.