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

howtofixcli

v0.4.98

Published

HowToFix coding agent. Workbench TUI, sessions, background agents.

Readme

HowToFix-CLI

A terminal coding agent. Workbench layout: scrolling feed, input dock, one HUD line.

howtofix                       # open the workbench
howtofix "fix the failing test in src/auth"
howtofix -p "explain this repo" | less
howtofix -c                    # continue the last session in this folder

Install

Node 22.19 or newer is required (node --version).

npm install -g howtofixcli
howtofix --version

That is the only install path. The package is the artifact: npm install -g howtofixcli@<version> pins an exact release, and howtofix update checks the same registry for a newer one.

If howtofix is not on your PATH afterwards, your npm prefix is not on it:

npm config get prefix          # e.g. /usr/local
export PATH="$(npm config get prefix)/bin:$PATH"

Connect your howtofix.id account

One account is all you need; every model on the gateway is billed to it. This is the whole setup:

1. Create the account — open https://howtofix.id and sign up. Sign in with Google works (a @gmail.com address).

2. Create a token — open https://howtofix.id/console/token and make one. It starts with sk-. Treat it like a password: it is the credential this CLI uses, and it is the only thing you have to copy.

3. Connect the CLI — run howtofix, then:

/connect

It opens the token page for you and asks you to paste the token. Or skip the prompt by passing it directly:

howtofix
/connect sk-your-token-here

The token is verified against the gateway before it is stored, and the model list is pulled in at the same time, so /model shows everything your account can reach. Nothing is written until the gateway accepts the token.

4. Pick a model and go.

/model

Choose one, then just describe what you want:

fix the failing test in src/auth

If you have a free-tier token

The free tier is a separate provider id. /connect verifies against the paid account first and the free one second, so the same command works for both — the models simply land under howtofix-free instead. /providers shows which one your token is attached to.

Updating the token later

Run /connect again with the new token. It replaces the stored one and re-syncs the models; models you configured by hand are never overwritten.

Removing it

/logout removes the stored key. The account itself is unaffected.

Signing in without copying a token

/login starts a sign-in in your browser instead: the CLI shows a link, you open it, approve, and the key lands in the CLI on its own. It is the same key you would have pasted, created for you.

Two things are worth knowing about how that flow is protected, because they are what make it safe to approve a link:

  • The CLI proves it is the CLI. Every request that starts a sign-in is signed with a key that only the published bundle carries, so the panel can tell a real CLI from a script that merely sends its name. A build whose key does not match says so on --version.
  • The link is not the credential. The approval code travels in the URL, so it is treated as semi-public. The key is only handed over to a request that also presents a second, secret value that never leaves the CLI process. If someone else sees your approval link, they cannot collect a key with it.

The approval page names the machine that asked, so you can check it is yours before you click.

While the CLI waits for you to approve, it polls the panel. That poll has its own rate-limit budget, sized for a whole sign-in, so taking your time is fine. If the panel ever does throttle a poll, the CLI waits as long as it asks and keeps polling rather than giving up on a sign-in you are in the middle of.

What it does

  • Workbench screen — feed of user turns, tool calls, and streamed answers; boxed input dock; HUD with model, folder, git branch, context meter, session spend, thinking level, approval mode, and activity.
  • Slash commands — /init, /model, /providers, /thinking, /approval, /settings, /login, /connect, /sync, /usage, /update, /logout, /new, /resume, /compact, /name, /stats, /diff, /commit, /undo, /rewind, /review, /tools, /skills, /preset, /roblox, /proxy, /export, /copy, /agents, /goal, /plan, /workflow, /session, /dcp, /context, /decompress, /sweep, /help, /quit, /exit. Type /help for the same list. (/mcp is not a slash command — MCP servers are configured through the SDK's own config.)
  • Skills — drop a SKILL.md in ~/.howtofix/agent/skills/<name>/ (user) or .howtofix/skills/<name>/ (this project). /skills lists them; /skill:name loads one into the next turn. The model also sees the list and will read a matching skill on its own.
  • Presets — bundles of skills and prompt rules, offered by category. /preset opens the menu (Installed → category → preset), and every entry shows what it contains before anything is copied: Install, View contents, Back. Nothing installs on its own — a preset is a catalogue entry, not something that arrives with the install. The menu also lists a community registry of ~95 skills from other projects; those are not shipped in the package, they are downloaded from the source repository (at a pinned commit) when you install one. /preset list shows what is active, /preset show <name> describes either kind without installing, /preset add <git-url|directory> installs one from elsewhere, /preset add-hub <name> installs a registry entry by name, and /preset remove <name> takes it back out. Installing copies the files into .howtofix/presets/<name>/ and reloads the session, so its skills and rules apply from the next message.
  • Shell escape — a line starting with ! runs in the project shell and stays in the session history.
  • Approval modes — suggest asks before every edit and command, auto-edit runs edits and asks for commands, full-auto (default) never asks. Read-only commands (ls, git log, grep — including pipes like ls | head) never ask. A critical command is denied in every mode. Pick one with /approval or --approval <mode>. Permission checks can also be turned off entirely — for an unattended run that must never stop, or for a machine where the prompts are in the way. /settings opens a hub for permissions, thinking level, model, context pruning and auto-update; /settings permissions (or /settings on|off) jumps straight to the permission toggle, and --dangerously-skip-permissions does the same for one --print run. Off lifts the last two refusals — critical commands and the repeated-call guard — and says so: a banner on start, and a warning row in the HUD for as long as it is off.
  • Dynamic context pruning — the agent calls a compress tool to fold a stale range of the conversation into a stored summary, and long tool output that a later edit superseded is replaced automatically. /dcp shows the switch, /dcp stats the totals, /context what the next request will carry, /decompress <bN> reopens a block, and /sweep drops the ones no ref resolves. npm run check covers it end to end.
  • Slop gate — npm run slop reports naming, comment, placeholder and swallowed-error findings in the changed files, with a committed baseline so only new ones fail. npm run slop -- --fix applies the high-certainty ones. A pre-commit hook runs it on what you are committing; npm run hooks:install wires that up in a fresh clone.
  • Git workflow — /diff shows the working tree, /commit <message> stages and commits, /undo resets the last commit keeping the changes, /review asks the agent to review the diff.
  • Goal and plan — /goal sets what the session is for and keeps it visible; /plan designs before editing and waits for your approval.
  • Rewind — Esc Esc opens the session tree. Pick an entry to drop the messages after it and, when the files differ, restore them too; the checkpoint is snapped before every prompt in a shadow git repo beside your own history. ↑/↓ move, ←/→ page, and the selection stops at the ends instead of wrapping. Sessions whose snapshots are older than 30 days are swept from the shadow store on startup, so it does not grow for the life of the machine.
  • Cancel a run — Esc stops the current turn (same as Ctrl+C) and says so in the transcript.
  • Background agents — the task tool spawns scout, architect, task or reviewer agents that run in parallel, park when done, and can be messaged again with /agents. Pass background: true to get their ids back at once instead of waiting for the results. Write your own in <project>/.hxf/agents/<name>.md or ~/.howtofix/agent/agents/<name>.md — frontmatter name, description, tools, optional model and effort, then the prompt as the body — and a child runs the parent's model unless you name another.
  • Tools — read, bash, edit, write, grep, find, ls, plus think (private scratchpad), ask (multiple-choice question to the user), and task (background agents).
  • Web search and fetch — web_search and web_fetch read public http(s) URLs; local, loopback, and RFC1918 addresses are refused before any request is made. Search defaults to DuckDuckGo, with an optional BRAVE_API_KEY upgrade.
  • Language server queries — the read-only lsp tool asks a language server for definition, references, hover, symbols, or diagnostics. It needs the matching server on PATH (typescript-language-server for this repo); a missing binary comes back as a tool result that says so.
  • Hooks — hooks.json in the config root attaches shell commands to seven lifecycle points (PreToolUse, PostToolUse, UserPromptSubmit, SessionStart, Stop, PreCompact, SessionEnd). A hook reads a JSON payload on stdin and decides with its exit code: 0 allows, 2 blocks with its stderr as the reason. A PreToolUse hook can also rewrite a call's arguments with updatedInput — validated against the tool's own schema, so a hook cannot make the agent run something it never asked for. A PreToolUse hook outranks the approval mode, so it holds under full-auto too. async and once are supported. See docs/hooks.md.
  • Sessions — stored as JSONL under ~/.howtofix/agent/sessions/<project>/. -c continues the latest; /resume picks any of them.
  • Project notes — /init writes an AGENTS.md and asks the agent to fill it in; it is loaded into the system prompt on later runs.
  • @file — @src/main.ts in a prompt inlines the file; paths that do not exist are left alone for the agent to read.

Keys

| key | action | | --- | --- | | enter | send | | shift+enter | new line | | ctrl+c | stop the run, or quit when idle | | ctrl+d | quit | | ctrl+l | jump to the latest line | | ctrl+o | clear the screen (history is kept) | | ctrl+f | take the workflow panel's keys while it is pinned | | esc | close picker / clear draft |

Config

Everything lives in ~/.howtofix/agent:

  • models.json — providers and model catalog
  • auth.json — stored credentials
  • settings.json — defaults
  • sessions/ — transcripts
  • agents/ — parked background agent runs (*.json) and your subagent definitions (*.md)
  • workflows/ — scripts saved from a workflow run

Set HOWTOFIX_CODING_AGENT_DIR to use a different root. The underlying SDK is pinned to that directory, so HowToFix never reads or writes the SDK's own ~/.hxf config dir.

If no key is stored, the CLI says so and tells you to run /connect.

Flags

-p, --print          run one prompt and print the answer
-c, --continue       resume the latest session in this folder
    --no-session     do not write a session file
-m, --model <id>     provider/model, or a fuzzy model id
    --thinking <lv>  off | minimal | low | medium | high | xhigh | max
    --approval <m>   suggest | auto-edit | full-auto
    --output-format <f>  text | json — `json` streams one event per line for
                         scripts and CI (needs --print)
    --max-budget-usd <n> stop once this much has been spent — one run with
                         --print, the whole session interactively (needs a
                         model with declared prices)
    --dangerously-skip-permissions
                         run anything, including critical commands and repeated
                         calls that are otherwise refused (needs --print)
-h, --help
-v, --version

Machine-readable output

--print --output-format json writes one JSON object per line. The first is a system/init header (model, session id, budget, bypass); the last is a result record with subtype (success, error_max_budget_usd, error_aborted, error_during_execution), is_error, total_cost_usd and token usage. Everything between is the session event stream. No terminal scraping, no ANSI stripping:

howtofix --print --output-format json -p "summarise src/" \
  | jq -c 'select(.type == "result") | {subtype, total_cost_usd, result}'

--max-budget-usd aborts a run whose spend passes the cap and reports error_max_budget_usd; it refuses to start against a model with no declared prices, because a budget that can never fire only looks like a guard. The same flag caps the interactive session: the workbench samples the cost /stats shows after every event, notes budget once when it fires, cuts the turn that crossed it and refuses the next prompt. /new and /resume do not reset the total — only restarting the CLI does.

Troubleshooting

Upstream API error (HTTP 400) — the gateway refused the request. Run /connect again to re-sync your models; a model entry created before a gateway change can carry stale compatibility settings.

No available channel for model <id> — the gateway has no live channel for that model right now. Try another with /model; the ones under howtofix/ that answer change as channels come and go. The CLI checks this for you: it probes a few other candidates and opens /model itself if any of them answer.

A model returns Server error — that is the gateway's channel failing, not the CLI. /model lists what your account can reach; pick another.

unknown model — the id is not in your models.json. /connect pulls the current list from the gateway.