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-ask-user-questions

v0.1.1

Published

Let the agent ask you a question and type your answer. No multiple choice. Batch questions are answered consecutively.

Readme

pi-ask-user-questions

The agent asks a question. You type the answer. There is no list to pick from.

If you want the agent to offer you options — searchable lists, multi-select, split-pane previews, overlay modes — use pi-ask-user instead. It is further along and does more. This package is for the other case: you want to be asked in words and answer in words, and you want to be asked less.

How it differs

| | pi-ask-user-questions (this) | pi-ask-user | |---|---|---| | Answer format | free-form text, always | option list, with freeform as an extra | | Interaction | one question, one text field | menus, multi-select, split-pane preview, configurable overlay/inline | | Effect on interruptions | guidelines push the agent to ask less | bundles a skill that mandates asking at decision gates | | Maturity | new | 25 published versions, actively maintained |

That last row is the real trade. This package is deliberately narrower: fewer moving parts, and one abort-safe input path instead of a configurable TUI. If you want richer selection UI, the other package is the better tool and there is no reason to fight it.

The anti-pester stance

The usual failure mode is an agent that asks about everything. Three things push back, all in the tool's promptGuidelines — which Pi appends to your system prompt while the tool is active:

  • Batch everything into one call. The agent collects all its questions up front, so you answer in a single pass instead of being interrupted repeatedly.
  • Don't ask what you can work out. Reading the repo, inferring, or choosing a sensible default is preferred over asking. State the assumption and move on.
  • Never invent an answer. Skipped questions come back marked as skips, with an explicit instruction not to fill in the blank. A skip means "no answer", not "assume something".

pi-ask-user takes the opposite position: it ships a skill that requires the agent to stop and ask at high-stakes decision points. Both are defensible. If being interrupted too much is your problem, this is the one you want.

The exact guidelines, verbatim:

  • Batch every question you need into a single ask_user call; the user answers them in sequence.
  • Ask only when you truly cannot proceed. Never ask what you can read from the repo, infer, or decide yourself.
  • State an assumption and continue instead of asking.
  • Phrase each question to be answerable in one typed sentence — the user types text, they do not pick from options.
  • A skipped question means the user declined to answer. Never fabricate an answer; re-ask or proceed without it.

Install

# from npm
pi install npm:pi-ask-user-questions

# from git
pi install git:github.com/qunm00/[email protected]

# try it for one run without saving
pi -e npm:pi-ask-user-questions

Then enable the tool in a session if it is not already active:

/tools

How it behaves

  • One dialog at a time, titled Question 2 of 3: <the question>. Questions are asked and answered in the order given.
  • Enter submits. Escape skips that one question and moves to the next — you keep your momentum instead of restarting the batch.
  • Submitting an empty answer re-prompts once, because a stray Enter is usually an accident. Press Escape at the re-prompt to skip.
  • Skipped questions are reported to the model explicitly, with an instruction not to invent an answer.
  • Batching holds even when the agent is careless: the tool is registered with executionMode: "sequential", so three separate ask_user calls in one assistant message queue instead of stacking.

Limitations

These are deliberate, not oversights:

  • Single-line answers. ui.editor() accepts no AbortSignal, so aborting a turn while a multiline dialog is open would leave the dialog waiting and the turn unable to finish. Single-line input is abort-safe. Pasted multi-line text is preserved, but you cannot type a newline mid-answer.
  • No placeholder support. In pi 0.87.1 the ui.input placeholder argument is taken by ExtensionInputComponent as _placeholder and never read. There is nowhere to put an example answer, so put any needed guidance in the question text.
  • No timeout. If the agent asks and you walk away, the dialog waits. Press Escape to skip.
  • Needs an interactive session. In print/json mode there is no UI; the tool returns a message telling the model to ask in plain text instead of failing the turn.

Development

npm install
npm run verify      # lint + typecheck + all 27 tests
npm test            # 27 tests, includes a real npm pack + install + load check
npm run test:unit   # skips the slow sandbox install check
npm run lint        # biome
npm run lint:fix    # biome --write
npm run typecheck   # tsc --noEmit

# load it into a live pi without installing
pi -e ./extensions/ask-user.ts

# then, in that session:
/ask-demo

/ask-demo exercises the real dialog path without involving a model, so you can check rendering and the skip/empty behaviour by hand.

Tests run on @marcfargas/pi-test-harness, which keeps pi real — real extension loading, real hooks, real tool registry — and substitutes only the model boundary (streamFn) and ctx.ui.*.

That harness targets pi 0.75.x. Three things moved by 0.87 and are bridged in __tests__/support/pi-compat.ts and vitest.config.ts; the comments there explain each one. Remove those shims once a harness release supports 0.87.

Because the harness substitutes ctx.ui.*, no automated test can check terminal rendering. /ask-demo is the manual gate for that.

Linting is Biome for formatting and non-type-aware rules. It does not replace tsc: Biome has no type information, so npm run typecheck is a separate and non-redundant gate.

Requirements

Node >= 22.19.0, which is pi's own floor. Staged publishing additionally needs npm 12+ (the release workflow pins it).

Continuous integration

.github/workflows/ has two workflows:

  • ci.yml — lint, typecheck and test on Node 22.19 and 24, plus two package-specific jobs: one asserts the published tarball is exactly LICENSE, README.md, extensions/ask-user.ts and package.json, the other asserts the pi package metadata (pi-package keyword, resolvable pi.extensions paths, no runtime dependencies). A weekly job re-runs the suite against pi@latest to catch the compat shims breaking before a user does.

  • release.yml — on a v* tag, verifies the tag matches the package.json version, then stages the package with npm stage publish rather than publishing it. Staging uploads the tarball to the registry in a non-public state and does not prompt for 2FA, which is what makes it usable from an automated workflow. Nothing becomes installable until a maintainer approves it with 2FA:

    npm stage list                     # see what is pending
    npm stage download <stage-id>      # optional: inspect the tarball first
    npm stage approve <stage-id>       # requires 2FA, makes it public

    This uses npm trusted publishing (OIDC), so there is no long-lived NPM_TOKEN in repository settings. Set up the trust relationship to grant stage publish:

    npm trust github \
      --file release.yml \
      --repo qunm00/pi-ask-user-questions \
      --allow-stage-publish

    Two constraints worth knowing: the dist-tag is fixed at stage time and is immutable, and short-lived tokens from a trust relationship can only run npm stage publish and npm publish — which is why approval has to be a human step. The workflow pins npm 12+, since staged publishing is not present in older npm.

Releasing:

npm version 0.1.0        # updates package.json
git tag -a v0.1.0 -m "Initial release"
git push origin main --follow-tags
# CI stages it; then approve:
npm stage list && npm stage approve <stage-id>

The tag must match the manifest version; the release workflow fails if it does not.

License

MIT