Skip to content

The only ad space you own.

Spinwait renders a single labelled line in your Claude Code status bar while you wait on the model. You can read every line of it, switch it off with one command, and keep 70 percent of whatever it earns.

  • No account
  • No network calls on the render path
  • Off with one command
  • Your status line survives
claude
add rate limiting to the events endpoint Read app/api/v1/events/route.ts (184 lines) Update lib/guard.ts 3 additions Checking the replay guard still rejects duplicate nonces
That bottom row is the entire product. Nothing else changes about your session.
Anatomy

Four parts, all of them fixed.

An advertiser controls their name, their sentence and one colour. Everything that tells you it is an advertisement is hardcoded, which means no campaign can ever make itself look less like one.

the diamond
The advertiser’s colour, and the only thing they get to tint. It is clamped into a legible luminance band before it is stored, so a brand cannot render itself invisible on your terminal or blinding on someone else’s.
sponsored
Not themeable. The disclosure label, the separator and the domain are hardcoded to dim, so no creative choice can hide what the line is.
brand · tagline
Forty characters of name, eighty of sentence. Both are stripped of every control and zero-width character before storage, and stripped again by the renderer on the way out.
domain ↗
Where it goes if you click it. The line is an OSC 8 hyperlink, and attribution happens on our server through a redirect rather than being reported by anything running on your machine.
Guarantees

What it will never do.

You have every reason to assume this is adware. Here is the specific list of things it does not do, and the reason each one is true rather than just promised.

  • Never blocks your session

    The status line does no network I/O at all. It reads two small local files, prints one row, and hands flushing to a detached background process. It cannot add latency to the thing you are already waiting on.

  • Never sees your code

    What leaves your machine is a signed token, the event kind, the session’s cumulative API duration (cost.total_api_duration_ms) and an opaque session id. Not your prompts, not your files, not your repository.

  • Never renders to an empty room

    Three minutes after the model last did work, the line disappears completely. A terminal left open through a meeting shows nothing, and bills nobody for it.

  • Never replaces your status line

    spinwait init keeps whatever you already had. Your command still runs, on the row above. Your settings file is backed up first, and spinwait uninstall puts it back.

  • Never breaks your terminal

    Advertiser text is stripped of escape sequences twice, once before storage and again in the renderer. Any failure at all falls through to the status line you already had and prints nothing of ours.

  • Never more than one line

    One advertiser, one row. The visible creative rotates every eight seconds, and at most one impression in any 25 second window is billable. There is no second slot, because there is nothing to sell it to.

How it works

Three commands, then nothing to manage.

  1. Step 01

    Install it

    One command registers you and installs the status line. It backs up ~/.claude/settings.json first, and it wraps whatever status line you already had rather than replacing it.

  2. Step 02

    Work like normal

    While the model is thinking, one sponsored row renders under your own. When you stop working, it stops rendering. There is no dashboard to check and nothing to keep open.

  3. Step 03

    Withdraw whenever

    Connect a Stripe account once and pull your balance out when you feel like it. Ten dollar minimum, no schedule, no approval step.

Where it runs

Seven places to earn. One of them today.

The placement is the same everywhere: one labelled line, tied to the moment the model is working. Wherever you sit waiting on an AI assistant, that wait is yours to sell.

  • Claude CodeTerminal status lineLive
  • Claude Code mobileMobile app, prompt hookComing soon
  • Claude Code desktopDesktop app, prompt hookComing soon
  • Claude web and ChatGPTBrowser extensionComing soon
  • Gemini CLITerminal status lineComing soon
  • Codex CLIOpenAI, terminal status lineComing soon
  • VS Code, Cursor and CopilotEditor status barComing soon
Money

And yes, it pays. Modestly.

We are not going to pretend this replaces an income. Here is the arithmetic with the caveat that matters most attached to it: these are active hours, not hours with a terminal open.

70%Your shareOf the clearing price, credited per impression.
$8.00Floor CPMThe reserve. An uncontested auction clears a cent above it.
60/hrBillable capRendering faster earns nothing extra.
$10Payout minimumWithdraw on your own schedule.
Publisher earnings at the 60 impression per hour cap and a 70 percent revenue share, by active hours per month
DemandPer active hour40 h/month80 h/month160 h/month
Uncontested, at the $8 floor$0.336$13.44$26.88$53.76
Contested at $15 CPM$0.630$25.20$50.40$100.80
Contested at $30 CPM$1.260$50.40$100.80$201.60

When no advertiser has a funded campaign running, you earn nothing.

There is no house ad and no filler. An empty auction renders an empty line, so the table above is what the mechanism pays when demand exists, not what you should expect in your first month.

Every column is active hours, meaning hours the model is actually working. That is not the same as hours worked. A forty hour week is not 160 active hours a month, it is whatever part of those weeks you spend waiting on the model, which for most people is a fraction of the time the terminal is open. Read the 160 row as the ceiling for someone who runs an agent almost continuously, not as a full time salary.

Install

Start in under a minute.

No signup form, no password, no login. init generates a key on your machine and asks for an email you can skip, kept only so a lost key can be recovered. Payouts run through Stripe’s hosted onboarding, so we never hold your bank details. Today this installs the Claude Code status line, which is the surface that is live.

1. add the marketplace, inside claude code
/plugin marketplace add robert-botto/spinwait
2. install it
/plugin install spinwait@spinwait
3. set up
/spinwait:setup

Or drive it directly. These are the only commands there are.

controls
spinwait init          # register, install the status linespinwait connect       # Stripe onboarding, for payoutsspinwait status        # balance and payout statespinwait payout        # withdraw, $10 minimumspinwait off           # stop rendering ads, keep everything elsespinwait uninstall     # restore your previous status line
Questions

The awkward ones.

Do I have to make an account?

No. There is no login anywhere in this product. spinwait init generates a key and stores it in ~/.spinwait/config.json, and that key is your whole identity. When you want to be paid, Stripe’s hosted onboarding collects your details, not us.

init does ask for an email, and you can press enter to skip it. It is not a login and there is no password attached to it. It exists because that key file is the only copy of your account: lose it to a wiped laptop and any balance you have not withdrawn goes with it. An address is the one thing that lets us give it back.

What actually leaves my machine?

A session id, the cumulative milliseconds you have spent waiting on the model, and the signed token for each ad that was displayed. That is the complete list.

None of it happens during the render. The status line writes queued events to a local file and a detached background process flushes them later, which is why it cannot slow your session down.

I already have a custom status line.

It keeps working. spinwait init records your existing command, runs it on every render, and prints the sponsored row underneath it. Your ~/.claude/settings.json is copied to .bak before anything is touched, and spinwait uninstall restores it exactly.

Can I turn it off without uninstalling?

spinwait off. Ads stop rendering immediately and your own status line carries on untouched. spinwait on brings it back. Nothing is reinstalled or re-registered in between.

What if nobody is advertising?

Then you see nothing and you earn nothing. There is no house ad, no filler and no placeholder. An empty auction renders an empty line, which is also the honest answer to how much you should expect to make early on.

Can I block advertisers I do not want?

Not today, and we would rather say so than imply otherwise. Every campaign is sanitised, length limited and colour clamped before it can serve, but there is no per publisher block list yet. If you hit something you object to, tell us and we will pull it.

Why should I trust the numbers?

Because you are not the one reporting them. The price is sealed into a signed token on our server before the ad ever reaches you, so a modified client cannot reprice an impression, and each token can be redeemed once.

That cuts both ways: it means you cannot inflate your own earnings, and it means the number you are credited is the number the advertiser was charged, minus our 30 percent.

Take the keys.

One command, no account, and a status line you can switch off the moment it annoys you.

~/.spinwait · no login · uninstall restores everything