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

@arkone_ai/susan

v1.6.0

Published

Susan shows you what every Claude Code and Codex session on your machine is working through, keeps the decisions after the transcript is deleted, and answers ChatGPT web and Claude web over MCP.

Readme

Susan

Susan shows you what every Claude Code session on your machine is working through — its own todo list, live, from outside the window.

You run four sessions across four projects. One is waiting on a test, one is half way through a refactor, one you started an hour ago and cannot remember why.

Claude Code already keeps a todo list inside each session — the steps it is working through. Susan reads those lists and puts them all on one board, so you can see what every window is doing without opening it. She also tells your agent when two sessions are about to edit the same file, and lets one hand work to another.

There is nothing to maintain. Susan writes no todo list of her own; she reads the one your sessions are already keeping.

Three promises hold the whole design together:

She never writes to a file in your projects, or to a transcript. Plans are read, never edited — they belong to the session that wrote them.

She never blocks a tool call. When two sessions touch the same file, both edits proceed. The agents are told; nothing is denied.

She keeps the distillate, never the raw. Claude Code deletes your transcripts after about thirty days, so a pure view would go dark with them. Susan keeps the plans — measured at 0.002% of the transcripts she read, with a test that fails the build above 0.5%. Run susan doctor to see the live number on your own machine.

Nothing leaves your machine. The one exception is a daily ping — a random id, the version, and a count of live sessions — which is off unless you turn it on, and susan ping prints the exact payload before you decide.


Install

npm i -g @arkone_ai/susan   # installs two binaries. Touches nothing else.
susan init                  # shows the exact diff, asks once, backs up your settings

Now open two Claude Code sessions in any two projects. The second one's opening card will show the first. That is the whole proof it works.

susan doctor       # check everything is wired
susan uninstall    # undo it — your settings backup is kept

Needs Node 22.5+ (for the built-in node:sqlite, so there is no native module to compile). macOS and Linux. On Windows, run it inside WSL.


What she does

| Surface | What you get | |---|---| | Session start card | Who else is running, what they are working on, anything queued or unread. Prints nothing at all when you are alone and nothing is pending. | | Conflict notice | Edit a file another live session touched in the last 30 minutes and your agent is told to re-read it first. Once per file. Never blocks. | | Status line | arkone-ai/1 ●4 sessions ⚠1 conflict ▣3 — the one region of the screen that never scrolls. | | susan watch | A live board, redrawing every two seconds. Park it on a second monitor. When nothing is running it shows what you were last doing. | | susan serve | The same board in a browser at localhost:4747. --lan makes it reachable from your phone. | | susan plans | Every live session's todo list, and full-text search across every plan ever written on this machine. | | susan agent | Domain agents. @sales opens already knowing its folders and every decision made in them — no context to retype. | | MCP tools | Your agent can read the board, see what other sessions are working through, search plan history, load a domain agent's context, hand work to another project, and leave notes. |

The card, at five sessions

─ susan ── 5 sessions ─────────────────────────────────────────────────────
  ⚠ conflict  hosts.js — arkone-ai/1 · goclaw/1
  ● pharmadesk/1      refactoring the approval route    12m  3/7
  ● goclaw/1          wire the mcp stdio transport      31m  1/4
  ● fzst-claw/1       lead scoring backfill              8m  2/2
  ● arkone-ai/1       fix the content planner filter     4m  0/5
  ▣ 2 queued                                            `susan queue`
───────────────────────────────────────────────────────────────────────────

The conflict sits above every session row, because it is the only line that changes what you do next. 3/7 is how far that session has got through its own plan. The card is capped at ten lines no matter how many sessions are running.

The plans

Claude Code keeps a todo list inside each session — the steps it is working through. Susan reads that list out of the session's transcript and shows it on the board:

  ●  arkone-ai/2         fix the content planner filter        4m
                         src/app/.../ui.js
                         2/6 done
                         ✓ read how the date filter is built
                         ✓ reproduce the timezone bug
                         ▸ correct the boundary comparison
                         · add a test for the DST case
                         +2 more

She never writes to that list. It belongs to the session, and the session's agent is the only thing that changes it — so what you see is what it actually thinks it is doing.

susan plans                    every live session's list
susan plans razorpay webhook   search every plan ever written
susan plans --all              recent plans, including closed sessions

Search covers your whole history. Nine hundred megabytes of transcripts index in about a second and a half, and only newly appended bytes are read after that.

How a session gets its name

Nobody types it. Susan takes the first eight words of the first thing you typed, verbatim. A session that has not been given anything yet reads just started, and once it edits something it reads by filename. There is no (unclaimed).


From inside a session

/susan                       the board, without leaving your session
/susan plans                 what every session is working through
/susan plans <words>         search every plan ever written
/susan queue                 what is waiting for this project

susan init installs it at ~/.claude/commands/susan.md. If you already have a susan.md of your own there, she leaves it alone and says so.


Commands

susan board              # the board, once — sessions, their plans, conflicts
susan watch              # the board, live — ctrl-c to close
susan serve              # the board in a browser
susan serve --lan        # ...also reachable from your phone on the same wifi
susan connect            # a url + token, for chatgpt web and claude web
susan statusline         # one line, for a status bar

susan plans              # what every live session is working through
susan plans <words>      # search every plan ever written
susan plans --index      # re-read every transcript from scratch

susan memory <words>     # what was decided, from sessions that no longer exist
susan memory --distill   # build it: shows the cost, waits for a keystroke
susan memory --status    # how many memories, and what is queued

susan agent create sales ~/plans/campaign-a ~/plans/campaign-b
susan agent list         # every domain agent, its folders and history
susan agent refresh sales
susan agent remove sales

susan queue push goclaw "regenerate types"    # hand work to another project
susan queue claim 3                           # take it
susan message send pharmadesk "taking hosts.js"

susan login              # sign this terminal in to a team hub
susan push               # send your decisions there — asks first, always
susan export             # write them to a file instead; nothing leaves

susan reset              # clear stale sessions; keeps plans and queue
susan doctor             # diagnose

A team, if you want one — susan login

Everything above works alone, on one machine, forever. Nothing leaves it.

A team is the other case: your colleague hits the problem you solved in March, and the transcript that explained it was deleted in April. susan push sends the decisions — never transcripts, never prompts, never file contents — to a hub the team can search, and to the agents working in it.

susan login              # prints a short code, opens your browser
susan push               # shows exactly what would go, then asks

login never asks you to paste a token. It shows a code, you approve it in a browser that is already signed in, and this terminal collects a credential nobody typed. It lands in ~/.claude/susan/credentials.json at mode 600, carrying the hub URL beside the token — because a token alone does not say where to send, and a push that goes somewhere unintended and reports success is worse than one that fails.

susan push prints the whole payload and the project names before asking. The answer to "what is it about to send" should be readable, not trusted.

Self-hosting or pointing at a dev hub is SUSAN_HUB_URL; the public one is susan.network. To let your agents read the team's decisions, context and skills, susan login wires the MCP server too.


Memory, after the transcript is gone

Claude Code keeps your session transcripts for about thirty days, then deletes them. Susan reads what a session decided before that happens and keeps the decision — a sentence, the quote it came from, and where to find it.

susan memory --distill          # ~$0.035 of plan quota per session, ~20s each
susan memory "retry wrapper"

No custom retry wrapper was added because the SDK already retries 429s. "The SDK already retries 429s with backoff internally" susan · ~/.claude/projects/-Users-d-projects-susan/a1b2.jsonl:284119

It uses the Claude Code subscription you already pay for. Not an API key, not a second bill — claude -p on your own plan. Susan never handles a credential.

It is asked, never volunteered. Nothing is injected into a session. A memory you have to ask for is a wrong answer you can check; a memory pushed into every session start is a wrong answer acted on everywhere, forever. Pull is what the numbers currently justify.

| | Mechanism | Cost | Network | |---|---|---|---| | Rules + FTS5 | keyword search over filtered text | free | none | | Distillation | your own Claude Code, claude -p | plan quota | yes |

Scored before it shipped, on hand-labelled sessions: npm run eval reports precision and recall separately and refuses to pass below 0.95 precision. A memory layer that is 90% right is worse than none, because you stop being able to tell which 10% is wrong.

Domain agents — @sales, without the retyping

Every sales conversation used to start the same way: paste the campaign context, explain the offer, again. susan agent ends that. Name a domain, point at the folders that hold it, and Susan generates a Claude Code agent that opens already knowing them:

susan agent create sales ~/projects/acme/plans/dubai-campaign ~/projects/acme/plans/fly91-outreach

Type @sales in any new session and the agent reads the right entry document fresh (STATUS.md beats plan.md beats README.md), pulls every decision past sales sessions produced, and treats any "never"/"only" line in your documents as binding.

Three things keep it honest:

  • The agent file is a router, never a copy. It points at your folders; it quotes nothing. Your documents stay the single source of truth and cannot go stale inside the agent.
  • Its memory is scoped, not duplicated. Sessions that invoke @sales — or that edited files under its folders — are the domain's history, and their distilled decisions are what @sales remembers. One memories table, one budget, no second store.
  • It leaves the way it came. susan agent remove and susan uninstall delete exactly the files Susan generated. An agent file you wrote or rewrote yourself is never touched.

Which tools she can read

There are two ways in, and which one a tool uses depends on one thing: does it run on this machine, or in a browser?

| Tool | How it reaches her | Status | |---|---|---| | Claude Code | she reads its transcripts + TodoWrite | works today | | Codex | she reads its transcripts + session_index.jsonl | works today — no TodoWrite equivalent, so its decisions come from distillation | | Cursor | it starts susan-mcp itself, like any MCP server | works today | | ChatGPT web | it calls her over HTTP — see susan connect | works today | | Claude web | it calls her over HTTP — see susan connect | works today |

The web clients are not read; they ask. Neither writes anything to your disk, so there is nothing on disk to read — which is why the answer is a connection rather than a parser. She cannot see what you typed into ChatGPT. ChatGPT can see your board.


susan connect — for the tools with no filesystem

Claude Code, Cursor and Codex all run here and start Susan themselves; they need nothing from this section. ChatGPT on the web and Claude on the web cannot spawn a process, so for them she has to be a URL.

susan connect            # read-only, bound to this machine, token required
susan connect --write    # also allow queueing tasks and leaving notes
susan connect --port=5000
susan connect token      # print the token again

She prints a URL and a bearer token. Give both to the client as an MCP server.

A URL on your laptop is not reachable from the web. Both web clients call the URL from their servers, not from the browser tab, so 127.0.0.1 will never resolve for them however correct the config looks — the failure is silent, an empty tool list with no error. Put a tunnel in front of it and hand over the tunnel address:

cloudflared tunnel --url http://127.0.0.1:4949

What guards it, since this is the one place Susan opens a port:

| | | |---|---| | A token, always | Generated on first run, stored 0600, compared in constant time. There is no unauthenticated mode, not even on loopback — every page your browser has open can reach 127.0.0.1. | | Read-only by default | --write is opt-in. Without it the write tools are not merely refused, they are not listed — a tool advertised and then denied reads as a broken server and the agent will keep retrying it. | | Loopback by default | --lan widens it to your network. Nothing is exposed to the internet unless you tunnel it yourself. | | It stops when you do | No daemon, no launch agent. Close the terminal and the door closes. |

She never exposes your files this way. The tools return the board, plans, search and memory — the same things any other MCP client sees, and nothing more.


The MCP tools

Registered as susan when you run susan init.

| Tool | Reads/writes | For | |---|---|---| | susan_board | read | What every other session is doing right now | | susan_plans | read | The todo list each other session is working through | | susan_plans_search | read | Search every plan ever written — "what was I doing about X" | | susan_memory | read | What was decided, including in sessions that no longer exist | | susan_persona | read + one mark | A domain agent's folders and remembered decisions; calling it marks the session as that domain's work | | susan_queue_push | write | Hand a task to a session in another project | | susan_queue_list / _claim | read / write | See and take queued work | | susan_message_send | write | Leave a short note for another session |

Every write is local, additive and reversible. Nothing here needs a confirmation gate.

The same tools are what a remote client sees over susan connect, minus the three writes unless you passed --write.

Your agent keeps using TodoWrite exactly as before. Susan reads that list; she does not ask an agent to keep a second one. There is no susan_todo_add, on purpose — a tool that manages Claude Code should not also be a reminder app.


The browser board

susan serve          # http://localhost:4747, this machine only
susan serve --lan    # also on your phone, over the same wifi

susan init already started it, and it comes back after a restart — there is no terminal to leave open and nothing to remember. susan serve above is for running it in the foreground when you want to watch it start.

susan serve --install     # keep it up (init does this for you)
susan serve --uninstall   # stop it, and stop it starting on its own
susan doctor              # says whether the board is answering

Behind it is a launchd agent that starts at login and restarts the board if it stops. susan uninstall removes it along with everything else.

Everything susan watch shows — every session's plan, struck through as it completes, in a window you can leave open on a second screen. It updates the instant anything changes, in any session.

Two deliberate limits:

  • Loopback by default. A page that can edit your board does not go on the network unless you pass --lan, and when you do, it says plainly that anyone on that network can edit it.
  • Plans are read-only here. They belong to the session that wrote them; a browser tab has no business ticking off another session's steps.
  • It cannot claim queued work. Claiming decides which session does a job, and that belongs to the session whose agent will actually do it. Finish it, or drop it; do not assign it.

Dropping work is undoable. drop sits apart from done, in its own colour, and offers an Undo for seven seconds after — a confirmation dialog taxes every correct tap, an undo only costs the rare wrong one.

The page loads nothing from the internet — no fonts, no scripts, no analytics — and the server sends a Content-Security-Policy that forbids it from trying.

Reading the board from somewhere else

GET /api/board is what the page itself reads, and anything else may read it too.

{
  "sessions": [
    {
      "id": "ba802d5a-…",
      "name": "arkone-ai/4",
      "project": "arkone-ai",
      "branch": "arkone_ai_dev",
      "subject": "where are the ICPs?",
      "files": 23,
      "recent_files": ["…/core/store.mjs", "…/bin/mimi.mjs"],
      "idle_ms": 24869,
      "idle": "24s",
      "last_activity": 1786169782995,
      "stale": false,
      "plan": {
        "done": 5,
        "total": 6,
        "items": [{ "content": "…", "status": "completed" }]
      }
    }
  ],
  "queue": []
}

Two names are worth stating plainly, because both have an obvious wrong guess:

| It is called | Not | Holds | |---|---|---| | subject | ~~prompt~~ | what the session is working on | | plan.items | ~~todos~~ | the steps, each pending, in_progress or completed |

subject is the session's opening prompt and does not change mid-session. A long session drifts far from what it was first asked; plan is what tracks the present. A board that looks stale in the header while the plan below it moves is Susan working correctly, not caching.


Delegation, not possession

susan_queue_push hands work to another project. The receiving session does not start it on its own — queued work appears on that project's next session card and in the status line count, and the agent picks it up when you ask.

A session that quietly began work you never requested, in a window you were not watching, is exactly the failure this tool exists to prevent.


How she stays out of your way

| Concern | What actually happens | |---|---| | Nothing else can reach it | The board refuses any request that did not come from its own page — wrong content type, foreign origin, or a rebound hostname all get a 403. A page you visit in another tab cannot touch your board. | | Token cost | The conflict check is a shell hook: zero tokens when there is no conflict. The card is at most ten lines, and nothing at all when you are working alone. | | Latency | The pre-edit hook's database work measures ~0.3ms. A 50ms circuit breaker guards it: if the board is ever slow, the hook goes quiet rather than making a file write feel sluggish. | | Crashed sessions | A session that dies without warning is swept after four hours of no activity. Nothing is ever locked, so a stale row costs you nothing. susan reset clears them now. | | Broken hooks | Every hook exits 0 unconditionally, wrapped at the outermost level. A bug in Susan must never break the session she runs inside. | | Your settings | susan init backs up settings.json with a timestamp and marks every key it adds. susan uninstall removes exactly those and nothing you wrote yourself. |


What she touches

~/.claude/susan/susan.db        the board — sessions, plans, queue, messages
~/.claude/projects/**.jsonl     READ ONLY — where the plans come from
~/.claude/settings.json         four hooks, a status line, one MCP server
~/.claude/settings.json.backup-<timestamp>
~/.claude/agents/<name>.md      only if you ran `susan agent create <name>`

Nothing is written anywhere else. No daemon, and no network of her own.

She opens a port only while you are standing in front of one: susan serve for the browser board, susan connect for a web client. Both stop when you close the terminal, and neither survives a reboot. There is nothing running when you have not asked for it.

To see the change before agreeing to it:

susan init --dry-run

Development

git clone https://github.com/arkone-ai/susan.git && cd susan
npm install
npm test        # 176 tests, no network, isolated databases
npm link        # put susan + susan-mcp on your PATH from the checkout

Point her at a scratch database while developing, so your real board is never touched:

SUSAN_HOME=/tmp/susan-dev susan board

| Variable | Does | |---|---| | SUSAN_HOME | Where the database lives (default ~/.claude/susan) | | SUSAN_CLAUDE_DIR | Where settings.json lives (default ~/.claude) | | SUSAN_DEBUG | Print hook errors and over-budget warnings instead of failing silently | | SUSAN_NO_BELL | Suppress the terminal bell on a conflict |

MIT.