Docs
Caretbag shows your Robinhood Chain holdings in the Claude Code status line. It is read-only: it never asks for a key and never signs anything.
Install
Needs Node 18 or newer and Claude Code.
npx caretbag init 0xYOUR_ADDRESS
Without the address it asks for one. What init does:
- Copies the CLI to
~/.caretbag/app/, so the status line never depends on the npx cache. - Saves your address in
~/.caretbag/config.json. That file is the only place it is stored. - Backs up
~/.claude/settings.jsonto~/.caretbag/backup/, then pointsstatusLineat Caretbag withrefreshInterval: 30. If you already have a status line command, it keeps running and Caretbag adds a row below it (--inlineputs both on one row). - Adds a
/bagslash command (~/.claude/commands/bag.md) unless you pass--no-slashor already have your own/bag. - Reads your bag once and prints the line.
Running init again is safe: it never wraps itself, and it keeps your wallets and added tokens. npx caretbag@latest init upgrades the copy in ~/.caretbag/app/.
If a project's .claude/settings.json sets its own statusLine, that one wins inside the project; init tells you and --scope project installs there. A status line managed by your organization can't be changed, and init stops.
What the line shows
^ bag $1,284 ▲2.1% · NVDA $412 ▲1.3% · OAK $96 ▼8.0% · SPY $71 · NYSE closed
| Part | Meaning |
|---|---|
$1,284 | Total value of the positions Caretbag can price, in USD. |
▲2.1% | 24h change of what you hold now (value-weighted). Hidden when no position has a 24h price yet. |
NVDA $412 | A position and its value (not the unit price). Sorted by value; 3 by default, up to 12 with caretbag set maxPositions N on the open and holder tiers. |
!OAK | Moved 10% or more in 24h (open and holder tiers). |
NYSE closed | The real exchange's session: open, pre, after or closed (weekends and holidays included). |
~7m / stale 40m | The cache is older than 5 minutes / 30 minutes, usually because the RPC or the universe was unreachable. |
On narrow terminals positions drop off from the end first, then the market label; the row never wraps. Positions worth less than $0.50 are hidden. Colors follow NO_COLOR and caretbag set color never; caretbag set ascii true uses +2.1% instead of arrows.
Other states: ^ bag … loading (first refresh running), ^ bag $0 · nothing in this wallet on RH yet, ^ bag offline (caretbag doctor).
Commands
| Command | What it does |
|---|---|
caretbag init [0x…] | Install. Flags: --scope project, --inline, --no-slash, --yes. |
caretbag bag [--json] | Full table: amount, unit price, value, 24h. Refreshes first if the cache is older than a minute. |
caretbag refresh | Refresh now. |
caretbag add <CA> | Track a token the universe doesn't list. --symbol, --decimals if the token doesn't report them. |
caretbag remove <CA|SYMBOL> | Stop tracking an added token. |
caretbag wallet add|remove|list | More wallets. --label names one. |
caretbag set <key> <value> | maxPositions 1–12, color auto|always|never, ascii true|false, layout line|inline. |
caretbag doctor | Checks Node, settings, which settings file wins, the cache, the universe and the RPC chain id. |
caretbag uninstall [--purge] | Restores your status line, removes /bag and ~/.caretbag (backups stay unless --purge). |
Wallets & tiers
Until the token exists, every feature is open. After launch there are two tiers; see Token.
| Tier | Wallets read | Positions | ! marker |
|---|---|---|---|
| open (before launch) | all | 1–12 | yes |
| free | the first one | top 3 | no |
| holder | all | 1–12 | yes |
The holder check adds the token's balanceOf for your configured wallets to the same multicall; it runs on your machine.
Adding a token
caretbag add 0xTOKEN_CONTRACT
Caretbag reads symbol() and decimals() from the chain. If the token isn't in the universe, the background refresh asks the Pons API for its price by contract address; if Pons doesn't know it, the line shows the amount instead of a dollar value.
How prices work
- Stock tokens. The official Robinhood stock tokens on Robinhood Chain (chain id 4663), found by scanning every Uniswap V3 pool paired with USDG. Each is priced from
slot0of its deepest USDG pool; pools with less than $1,000 of USDG give no price. - Pons coins. Prices are Pons' own
priceUsd. The universe holds the top 400 Pons coins by market cap, PONS itself, and up to 1,200 coins by recent volume, each with a market cap of at least $3,000. A coin stays for 7 days after it was last listed. - ETH. ETH/USD as reported by Pons.
- 24h change. The universe server keeps a price snapshot every 15 minutes and compares with the one closest to 24 hours ago. There is no change for an asset until it has a day of history.
- Freshness. The server rebuilds the universe every minute; your machine refreshes when the cache is older than a minute, at most once at a time.
Prices are indicative. The line is not a quote and not what you would get selling.
Privacy
A refresh makes these requests, and only these:
GET https://caretbag.pro/universe.json?src=line (no address, nothing about you) POST https://robinhood-rpc.publicnode.com (eth_call: balanceOf(your address) via Multicall3) GET https://ponsfamily.com/api/launches/<CA> (only for tokens you added with `caretbag add`)
The universe server has no endpoint that accepts an address. It keeps daily counters (universe downloads, web previews) and nothing else: no IP addresses, no user agents. The counters are public at /api/stats. The web preview on the home page runs the same code in your browser and only adds one empty POST /api/ping/preview to count the run.
The public RPC is run by a third party (publicnode). It sees the address in the calls, like any wallet or explorer would.
Security
- Read-only. There is no signing code in Caretbag; it only makes
eth_callrequests. It never asks for a key or a seed phrase. If anything claiming to be Caretbag asks for one, it is not Caretbag. initchanges one key in your Claude settings (statusLine) and backs the file up first. It refuses to touch a settings file that isn't valid JSON.uninstallputs back exactly what was there. If nothing else in the file changed sinceinit, it restores the original bytes; otherwise it restores only thestatusLinekey. If you replaced Caretbag's line yourself, it leaves the file alone.- The status line command runs
node ~/.caretbag/app/caretbag.mjs line. Claude Code only runs status line commands in folders you trust. - No runtime dependencies. The npm package is the same code as the repository.
Limits
- No profit and loss: Caretbag doesn't know what you paid.
- Only Robinhood Chain. Only what the universe lists plus tokens you add; a Pons coin outside the universe needs
caretbag add. - Stock tokens whose pools hold less than $1,000 of USDG show no price.
- Depends on the public RPC and the Pons API. When either is down the line keeps the last values and shows how old they are.
- Two coins can share a symbol. The line shows the symbol;
caretbag bag --jsonshows the contract address. - No ENS or names; paste the 0x address.
Not audited
Caretbag has not been audited. It never holds keys or signs anything, but read the source before you trust it with your settings file.
Troubleshooting
- Run
caretbag doctorfirst. - Blank status line: Claude Code hides the status line until you accept the workspace trust dialog for the folder. It also stays blank if the command fails, for example when
nodeis no longer on your PATH after a version manager change; runnpx caretbag@latest initagain. - Old line disappeared: a project
.claude/settings.jsonmay set its ownstatusLine;doctorlists which file wins. stalemarker: the RPC or the universe was unreachable; the next refresh clears it. Errors are logged to~/.caretbag/refresh.logon your machine only.