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

bettercc

v0.1.10

Published

Claude Code with next-step options — after each turn, BetterCC suggests context-aware next steps in your terminal or on Even Realities G2 glasses, and feeds your pick back as the next prompt.

Readme

BetterCC

Claude Code, with next-step options. Run a coding task as usual; when Claude finishes a turn, BetterCC surfaces a few pre-made, context-aware options for what to do next, generated by a model that just read what Claude did. Pick one with a single keypress and it's fed straight back as the next prompt — no retyping, no "hmm, what now?" stall.

Works two ways: in your terminal, or on Even Realities G2 glasses (glance up, swipe + tap to pick). Both share one option-generation core (kairos.ts); see progress.md for status.

How it works — the four legs

   ┌─ you ────────────────────────────────────────────────────┐
   │  "build me X"                                             │
   ▼                                                           │
 ┌──────────────────────────────────────────────┐             │
 │ Agent SDK query() — ONE streaming session     │             │
 │  prompt: async generator of user messages     │             │
 └──────────────────────────────────────────────┘             │
   │ assistant text / tool use … then a `result` msg           │
   ▼                                                           │
 (1) DETECT     result/success  ─────────────────┐            │
 (2) GENERATE   kairos() → Haiku reads transcript │ 3 options  │
 (3) PRESENT    numbered menu, single keypress    │            │
 (4) FEED BACK  chosen .prompt ──── channel.put ──┴── yielded ─┘
                                    (same session, full context kept)

| Leg | Where | Mechanism | |-----|-------|-----------| | 1. Detect "done" | loop.ts | The SDK result/success message = turn complete. | | 2. Generate options | kairos.ts | A one-shot query() on Haiku reads the transcript → strict JSON {label, description, prompt}[]. | | 3. Present | present.ts | Numbered TUI; single keypress (1N, e custom, r regenerate, q quit). | | 4. Feed back | loop.ts | The chosen prompt is pushed through an async channel and yielded as the next user message into the same session. |

Why a wrapper and not a hook? Claude Code hooks (Stop, etc.) cannot present a chooser or inject a prompt — they observe, block-with-auto-continue, or inject context Claude only sees on a later turn. The "show options → pick → feed back" loop must live in a process you own. The Agent SDK streaming-input pattern is the documented, proven way to own it.

Install

Requires Node ≥ 20 and a logged-in claude (Claude Code) on this machine — BetterCC uses your existing Claude credentials via the Agent SDK, so no ANTHROPIC_API_KEY needed.

npm install -g bettercc      # once published; gives you `bettercc` and `bcc`
# or run without installing:
npx bettercc "your task"

From this repo (dev / not yet published):

npm install && npm run build     # builds the glasses bundle + the CLI
npm link                         # makes `bettercc` / `bcc` point at this checkout
# or run straight from source:
npm run dev -- "your task"

Run

# give it the first task as an argument…
bettercc "add a /health endpoint to the worker and a test for it"

# …or run with no args and it'll ask.
bettercc

Config (env vars)

| Var | Default | Meaning | |-----|---------|---------| | BCC_MODEL | (CLI default) | Model for the main coding session. | | BCC_OPTIONS_MODEL | haiku | Model for generating options (cheap + fast). | | BCC_NUM_OPTIONS | 3 | How many options to offer (2–5). | | BCC_PERMISSION_MODE | bypassPermissions | SDK permission mode. bypassPermissions lets Claude act without prompts — it will edit files / run commands in cwd. Use acceptEdits or default to be more cautious. | | BCC_CWD | process.cwd() | Working directory for the session. | | BCC_DEBUG | (off) | Set to surface the SDK's stderr (auth/spawn diagnostics). |

⚠️ The default bypassPermissions mirrors this machine's existing global setting. It means the session can modify files and run commands without asking. Point it at a repo you intend to work in, or set BCC_PERMISSION_MODE=acceptEdits.

Glasses mode (Even Realities G2)

Show the next-step options on your G2 lens and pick with the touchpad — glance up, tap, glance back to your terminal.

bettercc glasses "add a /health endpoint and a test"

That one command starts a local server that serves the lens plugin AND hosts the relay on the same origin, opens a scannable QR image, and runs the Claude loop. Scan the QR in the Even Hub app to load BetterCC on your glasses. Because the plugin is served by the relay, it connects back to ws://<your-desktop>/ws automatically — no IP to configure. Nothing leaves your LAN (no cloud relay; each user runs their own). The QR is rendered by the bundled qrcode library — no external CLI required.

On the lens: > marks the cursor — swipe to move, tap to pick, double-tap to exit. The menu scrolls if it's longer than the screen (/ mark more above/below). The top row is a summary of what Claude just did — tap it to open a reader that shows the full output, word-wrapped and paged (swipe for more, tap to go back). Under the options are Speak a prompt (voice dictation, below) and Regenerate options.

Multiple sessions (the switchboard)

Run the hub once, then join a session from each project/terminal. The glasses show a list of all sessions; tap one to see its options, Back to sessions to switch.

bettercc hub                       # terminal 1 — scan the QR on your glasses
bettercc join "fix the auth bug"   # terminal 2 — appears in the glasses list
bettercc join "write the docs"     # terminal 3 — appears too

The lens is then two levels: a session list (a * marks sessions with options waiting) ↔ a session's options + Speak / Regenerate / Back to sessions. Each session's prompts stay on its own machine — the hub only relays option labels and routes your pick back.

Voice input (on-device dictation)

The Speak a prompt row dictates the next prompt with the G2 microphone — transcribed entirely on your machine, no cloud, no API key. Tap Speak → "Listening…" → talk → tap to stop. The audio streams glasses → hub → your desktop, which transcribes locally and then shows you the text to confirm — tap to send it to Claude, double-tap to cancel (your options are still there). While a prompt is running, the options are replaced by an animated heartbeat so you can tell it's still working.

Transcription uses a pure-npm WASM Whisper (@huggingface/transformers) that installs the same on macOS/Linux/Windows with no system deps; the model auto-downloads + caches on first use (~75 MB, so the first dictation takes a bit longer). For a speed-up, point BCC_WHISPER_BIN at a native whisper-cli (+ BCC_WHISPER_MODEL_FILE) — it falls back to WASM automatically.

Resume a recent session

bettercc attach lists your recent Claude Code sessions (including ones you ran in plain claude), and resumes the one you pick — seeding the first options from where it left off.

bettercc attach                       # pick from a numbered list
bettercc attach --session <id|prefix> # skip the picker

It can't attach to a session that's currently open in another terminal (Claude Code has no way to inject a prompt into a live session — one driver per session). Resuming a past/idle session works great: it continues under BetterCC and you pick its next steps on the glasses.

| Var | Default | Meaning | |-----|---------|---------| | BCC_PORT | 8791 | Hub port (plugin server + WS). | | BCC_NAME | <dir>: <task> | Label this session shows as in the list. | | BCC_QR | image | image opens a PNG; terminal prints an ASCII QR. | | BCC_WHISPER_MODEL | Xenova/whisper-base.en | WASM Whisper model (e.g. Xenova/whisper-tiny.en for speed). | | BCC_WHISPER_BIN | (off) | Path to a native whisper-cli for faster STT (+ BCC_WHISPER_MODEL_FILE); falls back to WASM. | | BCC_HUB_DEMO | (off) | Register fake sessions with the hub — no Claude (for testing the lens). |

Test without hardware, in the EvenHub simulator:

BCC_HUB_DEMO=1 npm run dev -- hub                                 # terminal 1: hub + 3 fake sessions
evenhub-simulator http://localhost:8791 --automation-port 9911    # terminal 2: the lens

Lens font note: the G2 LVGL font has no // glyphs — lens strings use ASCII (>, ...). · is fine.

The hub dashboard

bettercc hub prints a QR, the connect addresses, and a pairing token, and serves a small dashboard at http://localhost:8791/hub — open it in a browser for a big scannable QR, the LAN/Tailscale addresses, the token, and a live list of connected sessions.

Connecting from anywhere (not just the LAN)

The glasses connect to the hub over WebSocket. The /ws control channel requires the pairing token (the hub generates one each run, or set BCC_TOKEN; it's baked into the dev-load QR so that flow stays zero-config). Pick how the glasses reach your hub:

  1. Same Wi-Fi — scan the QR (auto-connects), or in the glasses app enter ‹lan-ip›:8791 + token (both on the dashboard).
  2. Anywhere, private — Tailscale (recommended). Put your Mac and phone on the same tailnet; the hub auto-detects its Tailscale address and shows it. In the glasses app enter ‹mac›.‹tailnet›.ts.net:8791 (or the 100.x IP) + token. Traffic is encrypted by Tailscale and nothing is exposed publicly.
  3. Anywhere, public — a tunnel. cloudflared tunnel --url http://localhost:8791 (or ngrok) gives a wss://… URL; enter that + token in the glasses app. Because it's public, the token is your only guard — keep it secret; anyone with URL + token can drive your Claude.

The glasses app remembers hubs you connect to, so after the first setup you just tap to reconnect.

Publishing

Desktop CLI → npm. Publish-ready: npm run build produces dist/index.js + glasses/dist, and files ships exactly those. Set "private": false, then npm publish (after npm login; prepublishOnly rebuilds). Then anyone can npm i -g bettercc.

Glasses plugin → Even Hub. Pack and submit the lens app:

cd glasses && npm run build
evenhub pack app.json dist -o bettercc.ehpk   # then submit bettercc.ehpk to the Even Hub store

A store-installed plugin isn't served by your hub, so it shows the connection screen — the user enters the hub address + token (from the dashboard) once, and it's saved. (Dev-loading via the QR still works for testing and for users who'd rather not install from the store.)

Files

src/
  index.ts    entry — terminal / glasses / hub / join / attach subcommands, QR, dashboard print
  loop.ts     the streaming Claude session + completion detection + feed-back channel
  kairos.ts   option generator (one-shot Haiku → strict JSON)
  present.ts  terminal menu + single-keypress selection; defines the Presenter type
  hub.ts      the switchboard: serves the plugin + token-gated WS + /hub dashboard + /api/state
  hub-client.ts  session ↔ hub client (registers, streams options, runs dictation/STT)
  stt.ts      on-device transcription (WASM Whisper default; optional native whisper.cpp)
  sessions.ts listSessions + transcript reading for `attach`
  ui.ts types.ts  ANSI helpers / shared types
glasses/      the G2 lens plugin (Vite + @evenrealities/even_hub_sdk), built to glasses/dist
  src/lens.ts        7-row renderer (cursor, scroll window, word-wrap), serialized writes
  src/controller.ts  views: list / session / reader / speaking / confirm + working heartbeat
  src/relay.ts       configurable ws client (host+token); auto same-origin when dev-loaded
  src/main.ts        phone connection screen (host entry, saved hubs, status)
  public/app.json    manifest (network + g2-microphone permissions)

Cost

Option generation is one Haiku call per completed turn (~$0.05–0.10 on a real transcript, <1s) — negligible next to the main coding turns.