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

@zecalis/fapony

v0.12.1

Published

Token usage across Claude Code, OpenCode, Codex & ZCode on one yardstick — plus plans run chunk by chunk and a convention-debt tracker. No server, your data stays local

Readme

fapony

npm GitHub

The dev workflow for writing code with agents — plans cut into one-session chunks, lookups that cost a fraction of reading the files, and what it all cost in tokens. It is one developer's daily flow made into commands; adopting fapony means adopting that flow. Memory — decisions, bugs, notes — is fael's, never fapony's.

Why chunks: a long plan run in one unbroken session only accumulates context. Every chunk here is its own session that opens with just the facts it needs and stops when the chunk lands.

The workflow — fapony + fael

Two tools, one loop, no overlap. fapony is the workflow — plans cut into chunks, cheap lookups, what it all cost. fael is the memory — the decisions, bugs and notes the next session must see. Each is useful alone; together they close the loop: fapony says what's next, fael says what the last session learned.

| | fapony — workflow | fael — memory | |---|---|---| | Owns | plans + chunk loop, lint-baseline, review-seed / analyze, usage | decisions, issues, notes (add / find / close) | | Agent surface | plan-mv guard hook, skills — no MCP server | MCP tools + SessionStart / read / Stop hooks | | Writes | plan files, only when told (plan sweep --apply) | its log under .fael/ in your repo | | Install | npm i -g @zecalis/fapony && fapony install | npm i -g @zecalis/fael && fael install |

One session = one PR of up to 3 chunks (fapony plan PLAN-x.md prints the exact rule):

flowchart TD
    S([new session]) --> K["fael kickoff — SessionStart hook<br/>open decisions + issues (memory only, not plan-aware)"]
    K --> P["fapony plan PLAN-x.md<br/>unchecked chunks + handoff notes from fael"]
    P --> L["fapony review-seed --files …<br/>exports + importers instead of whole-file reads"]
    L --> E["edit<br/>fael read hook: rows about that file"]
    E --> C["tick the chunk with its sha → commit"]
    C --> N["fael add note 'what chunk N+1 must know'<br/>--files f1,plan:x --key plan:x:handoff"]
    N -->|next chunk — ≤ 3 per session, none that needs its own PR| P
    N --> X([stop — don't drag the transcript along])
    X -->|next session| S
    C -->|last chunk| W["fapony plan sweep PLAN-x.md --apply<br/>git mv into .fapony/done/"]

Who reads what:

flowchart LR
    CC[Claude Code] --> F[fapony]
    OC[OpenCode] --> F
    ZC[ZCode] --> F
    CX[Codex] --> F
    AG[Antigravity] --> F
    F --> U[usage — tokens & cost]
    F --> P[plans — next chunk, sweep, check]
    M[(fael — memory)] -. read-only .-> F
    CC & OC & CX --> M

fapony is opinionated: the loop above is the product, and the commands exist to make each step cheap. Plans are per-project (fapony init); usage needs no setup at all.

The pieces

Plans, one chunk at a time. fapony plan shows every active plan, its progress and next unchecked chunk; fapony plan PLAN-x.md opens one chunk with just the facts it needs — the unchecked boxes, whether the last ticked chunk's commit really exists, and the notes the previous session left in fael — instead of dragging the old transcript along.

Lookups instead of whole-file reads. fapony review-seed --files <f> gives exports with line numbers and every importer for roughly a thirtieth of the tokens reading those files costs.

Convention debt (frozen). fapony debt answers the question nothing else does: we decided this six months ago — how far along is the move? ESLint says this line is wrong; nothing says 11 of 47 files have migrated. Dead code and duplication it deliberately leaves to knip and friends — they already do that better. It is frozen: no repo we run declares a convention (checkers enforce them from day one), so it gets no new work and is slated for deletion on 2026-10-31 unless one does.

What it cost — usage

fapony reads the session logs Claude Code, Codex, OpenCode and ZCode already write, and puts them all on one yardstick — tokens, cost and time per model, per client, per workflow. Nothing to instrument: it runs on the history already sitting on your disk.

npm install -g @zecalis/fapony       # needs Bun — https://bun.sh
fapony usage-scan           # read the session logs already on your disk
fapony price-scan           # fetch the price table (needed once, for cost)
fapony usage-web            # every session you already have, all clients, one page

Cost is the part your client probably isn't logging. Of the four, only OpenCode writes a real dollar figure into its session log — the others record 0. fapony prices those sessions at published list rates and labels the number imputed; a model it can't find a rate for stays unpriced — nothing is quietly counted as free.

Raw facts from logs are hard to argue with — a vendor can dispute a verdict as unfair; they can't dispute their own token count. That is the whole measurement layer: tokens and cost, nothing self-graded.

Quick start

# 1. Install (needs Bun — https://bun.sh)
npm install -g @zecalis/fapony
#    from source instead:
#    git clone https://github.com/zecalis/fapony.git && cd fapony && bun install && bun link
#    update: npm i -g @zecalis/fapony@latest && fapony install  (from source: fapony update)
#    (`bun link` claims the global `fapony` bin by package name, not path — re-run it in the
#    checkout you want to be the one)

# 2. Measure — zero per-project setup
fapony usage-scan           # scan the session logs already on disk → cache
fapony price-scan           # fetch the OpenRouter price table → ~/.config/fapony/prices.json
fapony usage-web            # dashboard; re-run the scans to refresh
#    both scans are manual by design — nothing fetches or re-reads session logs behind your back

# 3. Wire your clients
fapony install              # list what is installed / missing, ask which to wire
fapony install --all        # skip the prompt, wire everything detected
fapony install --dry-run    # preview only — list only, never prompt
#    claude/opencode also symlink skill/<name>/ into ~/.claude/skills — an existing
#    skill of the same name is reported, never overwritten

# 4. Turn on plans (per project you want them in)
fapony init /path/to/your-worktree
#    creates .fapony/ — plan/ done/ spec/, evidence.json for `fapony report`,
#    then offers to write the plan-loop rules into CLAUDE.md / AGENTS.md
#    (none yet = AGENTS.md + a CLAUDE.md that imports it)
fapony init /path/to/your-worktree --rules --yes   # repo already set up: rules only, no prompt

# 5. Memory: install fael (npm i -g @zecalis/fael && fael install)

What fapony is not

Stated up front, because the gap between these two things is where most tooling oversells:

  • It does not run your test suite. The evidence collector runs an allowlist you write in .fapony/evidence.json, never a command an agent proposes. No allowlist, no evidence.
  • It does not judge your code — and it holds no memory of its own; that is fael's.
  • It checks conformance, not correctness — that a claim lines up with git facts and that uncertainty was declared, not that the code works.
  • Almost nothing blocks. The one exception is the plan-mv guard on Claude Code, which denies a raw git mv of a plan into done/ and points at fapony plan sweep --apply; nothing else touches a tool call.
  • Model attribution is inferred, not declared — reports label it inferred; read it as such.

What runs where

fapony install wires five clients (Claude Code, OpenCode, ZCode, Codex, Antigravity) — skills everywhere, plus the plan-mv guard on Claude Code. It also removes hooks fapony no longer ships (the edit hint, cut 2026-09-26: measured over two windows, it never moved an agent to migrate a file). Memory hooks and MCP tools are fael's (fael install); fapony has no MCP server.

| | Claude Code | OpenCode | ZCode | Codex | Antigravity | |---|---|---|---|---|---| | Plan-mv guard — deny raw git mv of a plan into done/ | ✅ | — | — | — | — | | Skills symlinked into ~/.claude/skills | ✅ | ✅ | — | — | — | | Skills symlinked into ~/.agents/skills | — | — | ✅ | ✅ | ✅ | | usage-scan reads this client's session log | ✅ | ✅ | ✅ | ✅ | — |

— means not wired, not impossible.

Lookups, digest and skills

Read-only and deterministic — none of it writes anything.

  • fapony review-seed --files src/thing/ — exports, importers, untested. Before touching an unfamiliar file, fire this and Read only the line ranges it points at. Directories work too.
  • fapony digest — decisions, open bugs, in-flight plans, cost, on one page, from what's already on disk.

Skills

fapony ships seven portable skills, each as skill/<name>/SKILL.md — the layout Claude Code expects, so a client can symlink the directory rather than copy the file:

| Skill | Purpose | Trigger | |-------|---------|---------| | skill/plan-with-pony/ | Draft plan + spec from "what's in your head" via conversation | /plan-with-pony | | skill/review-pony/ | Review as verification: scope facts before (review-seed), a fael row after when findings survive | /review-pony | | skill/lookup-before-edit/ | Look up unfamiliar files (review-seed --files + fael + debt) before reading/editing them | /lookup-before-edit | | skill/define-convention/ | Turn a not-yet-migrated pattern into a tracked convention (interview + dry-run debt) | /define-convention | | skill/move-to-done/ | Archive a shipped PLAN into .fapony/done/ | /move-to-done | | skill/git-commit-conventional/ | Commit per finished step + conventional message | /git-commit | | skill/git-ship/ | Push branch, open PR with drafted title/body, merge, reset branch onto base | /ship, /pr |

plan-with-pony is vendor-neutral — the SKILL.md is the prompt, so pipe it to any agent: cat skill/plan-with-pony/SKILL.md | claude -p (or opencode run, or anything that reads stdin). Example plans it produced: examples/.

Plans your agent can answer questions about

Plans stay markdown files in your repo — nothing moves into a database. Four optional frontmatter keys (kind / status / blocked_by / blocks) make a folder of them queryable; plans with no frontmatter still work, because the unchecked checkboxes are enough. Open the next session with fapony plan — it prints every active plan with its progress and first unchecked chunk without reading a single 100KB plan body into context:

# .fapony/plan/ — 3 active plan(s)

- PLAN-calendar.md — 1/4 chunks · priority:high
  next: chunk 2 — move overdue out
- PLAN-billing.md — 0/3 chunks · blocked_by: PLAN-calendar.md
  next: chunk 1 — money type

fapony plan PLAN-calendar.md then shows that plan's unchecked chunks, whether the last ticked chunk's sha is really in git, and the open fael notes about it — the next chunk's first. Close a chunk with

fael add note "<what chunk N+1 must know>" --files <f>,plan:calendar --key plan:calendar:handoff

and the next session finds it. The plan:<name> anchor (<name> = PLAN-<name>.md, lowercase) stands in for the plan's path: the path changes when the plan moves into done/, and .fapony/ is usually gitignored, so fael cannot follow it. The key ties the note to one chunk. Rows written the older way (--files <PLAN path>) still show up — fapony matches them by file name.

There is no MASTER.md — every line above is derived from the plan files themselves, so it cannot drift; a hand-kept master file always does. fapony plan check verifies ticked chunk shas against git history (a ticked box with no sha to check is a claim, not a close; a chunk with no commit — a measurement — cites (fael:<decision id>), and [~] marks a dropped one) and flags dangling blocked_by refs; fapony plan sweep PLAN-x.md --apply archives a shipped plan with git mv into .fapony/done/ — same name, same depth, so every relative link inside the file survives the move. A spec lives in .fapony/spec/ while a plan cites it (spec: frontmatter) and moves to done/ with the last plan that does — plan sweep --apply keeps it if another active plan still names the file, and repoints every link. fapony plan PLAN-x.md prints §N → SPEC-x.md:from-to for each section the next chunk cites, so a session reads those lines, not the whole spec.

CLI

# core: plans (memory — decisions, bugs, notes — lives in fael)
fapony plan [<PLAN.md>]                    # active plans + next chunk; one plan: unchecked chunks + open fael rows
fapony plan sweep [<PLAN.md>] [--apply]    # archive shipped plans into done/ + rewrite links
fapony plan check [--quiet] [--fix]        # deps, broken links, ticked-chunk shas (exit 1 on issues); --fix repairs squashed ticks + moved-plan links
fapony lint-baseline [--cmd ...] [--diff]  # separate "already red" from "I made it red"
fapony digest [--since 7d|YYYY-MM-DD] [--format text|html] [--json] [--out FILE]  # single-page summary from what's on disk

# usage — what it cost
fapony usage-scan                          # scan session logs → cache (incremental, progress bar)
fapony price-scan                          # fetch model price table → prices.json (cache; query never fetches)
fapony usage-web [port]                    # usage comparison dashboard from cache

# lookup (read-only, never touches state)
fapony analyze [path]                      # live repo graph: hubs, orphans, cycles, changed-untested (TS/JS + Python .py/.pyi; stdlib→external, no sys.path)
fapony review-seed [--staged|--commit <sha>|--range <a...b>|--files f1,f2,dir|--plan <PLAN.md>] [--body sym[,sym]] [--callers sym[,sym]]  # scope facts for a review
fapony plan-seed <name> [--spec] [--scope <path>[,<path>]]...  # write PLAN (+SPEC): frontmatter, capped sections, prior-art list

# hooks (wired by `fapony install`, not run by hand)
fapony hook-mv-guard                       # deny raw git mv of plan files into done/

# frozen ledger (reads history only — the grading tool left the MCP surface in 2026-09)
fapony debt [--id a,b] [--where <path>]    # files not yet migrated to a declared convention (frozen — delete 2026-10-31)
fapony stats [--mode verdict [--regime code|fix|review|plan|inquiry|test]]  # KPIs from old graded runs
fapony report <run-id>                     # verification report for a run
fapony report-web [file]                   # static HTML report page

# setup & maintenance
fapony init <path>                         # scaffold .fapony/ (plan/done/spec/evidence)
fapony install [--all|--platform <name>|--dry-run]  # wire skills + plan-mv guard into clients
fapony setup                               # interactive wizard: config + scaffold in one step
fapony update [--dry-run|--yes]            # git checkouts only — npm install: see Quick start
fapony upgrade                             # alias of update
fapony telemetry show|send                 # opt-in only, default off — see TELEMETRY.md

fapony report <run-id> prints the full report for a frozen-ledger run — git facts, handoff conformance, allowlisted evidence, the stored verdict, cost — with anything the agent claimed but couldn't prove marked as such. Reports are stamped with the producing build's server_sha; after editing fapony, compare the stamp against git log -1 before trusting a report. Each allowlisted command gets timeout_ms (default 30s), the whole report capped at 180s — a command that doesn't fit reports as timeout, never as a pass. If your .gitignore ignores .fapony/ wholesale, re-include the file: **/.fapony/*, then !**/.fapony/evidence.json.

Config

fapony.config.json lives in the fapony checkout and is gitignored (it's per-machine). Copy fapony.config.example.json for a complete working reference; every section is optional. Key fields: worktrees (name → path), memory (shell commands the frozen ledger runs; off unless set), paths / safety, usageWeb { port, hostname }. Env overrides: FAPONY_CONFIG, FAPONY_STATE_DIR (state DB; default ~/.config/fapony/).

Scope

Supported: cross-client usage on one yardstick · per-project plans · per-client hooks (matrix above) · vendor-neutral skills (anything that reads stdin) · opt-in telemetry, off by default (TELEMETRY.md lists exactly what leaves the machine) · Bun-only; run state in SQLite via bun:sqlite (WAL mode).

Not supported (yet): the plan-mv guard outside Claude Code. Memory of any kind — that is fael. A hosted or shared ledger — FAPONY_STATE_DIR on a synced folder works as an experiment only; SQLite's WAL mode does not tolerate concurrent writers over NFS/Dropbox/iCloud Drive and can corrupt the db under real contention.

License

MIT