Skip to content
Back to skills

Quotas Setup

ASecurity

Use when registering the AI subscription accounts whose quotas you track, adding a second paid Claude Code / Codex / Cursor account, re-logging in an expired one, nicknaming an account, asking which are logged in, or installing the daily unattended usage snapshot. Gives each account an isolated login profile — a config dir or a CODEX_HOME; Cursor instead uses the login the Cursor IDE already holds. Display and config only — reads no usage figures, gates no work.

  • 5 stars
  • 0 votes
  • 0 copies
  • 0 views
  • Added September 20, 2026
toolsbashsql

Works with

  • claude code
  • cursor
  • terminal
  • cli

Security analysis

A100/100

Scanned September 20, 2026

npx -y skills add auerbachb/claude-code-config --skill quotas-setup --agent claude-code

Installs into .claude/skills of the current project.

Are you the author of Quotas Setup?

Add the live security badge to your README. It updates with every re-scan.

Security grade badge for Quotas Setup
[![Security: A — Skills Directory](https://www.skillsdirectory.com/api/skills/auerbachb-quotas-setup/badge)](https://www.skillsdirectory.com/skills/auerbachb-quotas-setup)

More formats (shields.io, HTML) on the badges page. Keep it an A: scan every change in CI with Pro.

Download with Pro
SKILL.md
---
name: quotas-setup
description: Use when registering the AI subscription accounts whose quotas you track, adding a second paid Claude Code / Codex / Cursor account, re-logging in an expired one, nicknaming an account, asking which are logged in, or installing the daily unattended usage snapshot. Gives each account an isolated login profile — a config dir or a CODEX_HOME; Cursor instead uses the login the Cursor IDE already holds. Display and config only — reads no usage figures, gates no work.
triggers:
  - quotas-setup
  - register my AI accounts
  - add another Claude account
  - add a Codex account
  - add a Cursor account
  - which AI accounts are logged in
  - re-login my AI account
  - nickname my AI account
  - install the daily quota snapshot
  - is the quota snapshot job running
argument-hint: "[list [--json] | add <claude|codex|cursor> <label> [--nick <name>] [--no-login] | nick <label> <name> [provider] | remove <label> [provider] | relogin <label> [provider] | schedule <install|remove|status> [--hour N]]"
model: sonnet
allowed-tools:
  - Read
  - Glob
  - Grep
  - Bash
---

Register the accounts behind the owner's parallel AI subscriptions, give each one an
isolated login profile, and report which are reachable.

> **Display and configuration only.** Nothing this skill produces may gate dispatch,
> pause work, downgrade a model, or feed `credit-budget.sh`. Quota and spend authority
> belongs to Anthropic's own in-app UI and upstream harness signals — see
> `.claude/rules/safety.md` §"Anthropic Quota & Spend Authority". Reading usage figures
> is a different tool (`/quotas`, increment 2); this skill stops at a validated account
> list.

> **No credential ever passes through you.** Every login is the provider's own
> interactive flow (magic link, SSO, CAPTCHA) — and for Cursor it is not even this
> tool's to run: the Cursor IDE holds that login. The helper launches what it can and
> waits — it never types, reads, prints, or stores a password, token, or cookie, and
> neither do you. If a login needs the user's hands, say so and stop; do not offer to
> type credentials.

## Step 1 — Resolve the helper

<!-- test-anchor: resolve-helper -->
```bash
resolve_script() {
  local name="$1" candidate
  for candidate in \
    "$HOME/.claude/skills-worktree/.claude/scripts/$name" \
    "$HOME/.claude/scripts/$name" \
    ".claude/scripts/$name"; do
    if [[ -x "$candidate" ]]; then echo "$candidate"; return 0; fi
  done
  return 1
}
AI_QUOTAS_SETUP_SH=$(resolve_script ai-quotas-setup.sh || true)
[[ -n "$AI_QUOTAS_SETUP_SH" ]] || { echo "ERROR: ai-quotas-setup.sh not found (checked all three paths) — account registration unavailable" >&2; exit 1; }
```

**STOP** if the helper does not resolve: print that one line and end. Do not hand-roll
the registry — a second writer to `~/.claude/ai-quotas.json` is how the config and the
profile directories drift apart.

## Step 2 — Route the request

| The user asked | Run |
|----------------|-----|
| nothing, "list", "which accounts" | `"$AI_QUOTAS_SETUP_SH" list` |
| "add \<provider\> \<label\>" | `"$AI_QUOTAS_SETUP_SH" add <provider> <label>` |
| "register it now, I'll log in later" | `"$AI_QUOTAS_SETUP_SH" add <provider> <label> --no-login` |
| "call it \<name\>", "nickname this account" | `"$AI_QUOTAS_SETUP_SH" nick <label> "<name>" [<provider>]` |
| "remove \<label\>" | `"$AI_QUOTAS_SETUP_SH" remove <label> [<provider>]` |
| "re-login \<label\>", an account showing `needs-login` | `"$AI_QUOTAS_SETUP_SH" relogin <label> [<provider>]` |
| "take a reading every day", "install the snapshot job" | `"$AI_QUOTAS_SETUP_SH" schedule install` |
| "is the daily job running" | `"$AI_QUOTAS_SETUP_SH" schedule status` |
| "stop the daily job" | `"$AI_QUOTAS_SETUP_SH" schedule remove` |

`list` is the default when no action is given. `--json` is available on `list` for
machine consumption (increment 2's `/quotas` reads the config directly). `--no-login`
is available on `add`: it reserves the profile slot and records the account without
launching a login, which is what you want when the user cannot complete an interactive
flow right now. The account then reports `needs-login` until a `relogin`.

Providers are `claude`, `codex`, and `cursor`. The label is what the user types — for
these accounts, the email on the subscription. Ask for it rather than guessing; the
label names the profile directory and is how `remove` and `relogin` find the account
later.

## Step 3 — Adding an account

`add` creates the isolated profile directory, launches that provider's own login
against it, verifies a credential appeared, and only then records the account. One case
records without a login: `--no-login`, which reserves the slot on purpose and lists as
`needs-login` rather than `ok`.

- **`claude`** — a per-account `CLAUDE_CONFIG_DIR` under
  `~/.claude/ai-quotas/profiles/<label>/claude`, then `claude` run against it. A bare
  `claude` on an unauthenticated config dir opens the browser login and persists the
  credential scoped to that directory; tell the user to exit the session (`/exit` or
  Ctrl-D) once the login completes. Do **not** substitute `claude auth login` (no such
  subcommand) or `claude setup-token` (it prints a token instead of storing one).
- **`codex`** — a per-account `CODEX_HOME` under `…/<label>/codex`, then `codex login`.
- **`cursor`** — **no profile directory and no login to launch** (#1703). The Cursor IDE
  owns this credential, and nothing else can create it: cursor.com's sign-in page runs a
  human-verification check that fails in every automation browser, which is why the
  Playwright login that used to live here was removed. So `add cursor` and
  `relogin … cursor` both mean **"open the Cursor IDE and sign in"** — tell the user
  exactly that. Each then confirms a token is present (`sqlite3`, presence only, the
  value never read) and exits `1` with that same instruction when the IDE is signed out;
  relay it and retry once they have. Exit `6` is the different failure of `sqlite3`
  being missing. One IDE holds one account, so this machine registers one Cursor
  account — a second Cursor subscription cannot be tracked here, and `add cursor` under a
  second label is **refused** with exit `3` naming the label that already holds the slot
  (two labels would otherwise render two `/quotas` rows with identical usage).
  A `relogin` no longer retires anything: signing in again in the IDE replaces the token,
  so there is no profile to move aside and nothing to roll back.

The `claude` and `codex` logins are interactive and blocking. Tell the user one is about
to open, and let it run — a magic link or SSO round trip can take a minute. Adding a
second account of the same provider never disturbs the first: each has its own profile
directory and its own credential. **Cursor is the exception on both counts** — nothing
opens, and a second account is not possible.

**STOP conditions for `add`:**

- Exit `1` — the login ran but left no credential the helper can see. Nothing was
  recorded. Report what the helper printed. Offer exactly two next steps: re-run the
  `add`, or `add … --no-login` to reserve the slot and log in later. Never invent an
  entry by hand.
- Exit `3` — a usage problem: unknown provider, malformed label, a
  `(provider, label)` pair already registered, or a **second `cursor` account under a
  different label**. Report it; for an already-registered pair the fix is `relogin`, not
  a second `add`. For the cursor refusal the message names the label already holding the
  slot — one IDE holds one account, so a second label would report the same usage twice;
  the fix is `relogin` on that label, or `remove` it first.
- Exit `6` — the provider's login tool is not installed: its CLI, or for `cursor`
  `sqlite3`, which reads the IDE state store. For `claude` and `codex` the helper prints
  the exact manual login command; relay it and stop. For `cursor` there is no manual
  login to print — the instruction is to install `sqlite3` and re-run.

**STOP conditions for every action, `list` included:**

- Exit `2` (`schedule` only) — this host is not macOS, so there is no LaunchAgent to
  install. Relay the line and stop.
- Exit `4` (`remove` / `relogin` / `nick`) — no account matches that label. Say so, ask the user
  to confirm the exact label (run `list` to show them), and stop. Nothing changed.
- Exit `5` (`schedule` also) — the job could not be set up: `HOME` is unset, the
  `ai-quotas.sh` to schedule could not be found, or the plist could not be written or
  did not validate. Nothing was installed; relay the message and stop.
- Exit `5` — the tool cannot use the config: `jq` is missing, the file is unparseable,
  or it was written by a different schema major. Report the helper's message and stop.
- Exit `7` — the config write lock timed out or was broken mid-update. The config is
  unchanged; say so and offer to retry.

On **any** non-zero exit above — 1, 3, 4, 5, 6, or 7 — **do not hand-edit
`~/.claude/ai-quotas.json`**. A second writer is how
the registry and the profile directories drift apart, and a config the tool refused to
parse is exactly the one you should not be repairing by hand.

## Step 3b — Nicknames

`/quotas` prints a nickname in place of the account's full email, which is what keeps a
five-account table inside a normal terminal. Set one at registration with
`add <provider> <label> --nick "<name>"`, or later with `nick <label> "<name>"`. Clear one
by passing an empty name — `nick <label> ""` — which removes the field rather than
storing a blank.

Keep them short (the column is sized by the longest one) and let the **user** choose the
words: a nickname is how they refer to the account, not a label for you to infer. Names
over 32 characters, or containing a tab, newline, control character, or leading/trailing
space, are refused with exit `3` and nothing is written — the table is tab-separated, and
a tab inside a name would split the row away from its headers.

A label registered under two providers needs the provider as a third argument
(`nick <label> "<name>" codex`), the same disambiguation `remove` and `relogin` require.

## Step 3c — The daily unattended snapshot (macOS only)

`/quotas` records every reading it takes, but only when someone runs it. `schedule
install` adds a per-user LaunchAgent (`com.claude.ai-quotas`) that takes one reading a
day at 09:00 local — `--hour <0-23>` moves it — plus one immediately on load, logging to
`~/.claude/ai-quotas/launchd.log`. `schedule remove` unloads and deletes it. `schedule
status` reports whether the plist is there, whether launchd holds the job, and when the
last unattended reading happened.

- Offer it when `/quotas` shows `LAST SNAPSHOT: none yet`. Installing it is a **config**
  change like any other action here — it schedules a reader, not a decision.
- **The job never gates anything.** It reads figures and appends them to
  `~/.claude/ai-quotas-history.jsonl`. Nothing consults that file to decide whether work
  may proceed, and you must not either.
- It opens **no browser at all** (#1703 removed the last one). A Cursor IDE that is
  signed out records as `needs-login` and waits for the user to sign in there; nothing
  is recorded for that row — an unread row appends no snapshot rather than a fabricated
  one.
- **Exit `2`** on any host that is not macOS: launchd is the only scheduler with access
  to this user's Keychain, `CODEX_HOME` directories, and the Cursor IDE state store, so there is
  nothing to install elsewhere. Report the one line it prints and stop — do **not** offer
  to write a cron entry instead, which would record `needs-login` every day and call it
  history.
- If `install` warns that it scheduled the reader from a checkout, relay it: the job
  keeps working until that worktree is removed. Re-run `schedule install` once the skills
  worktree is in place.

## Step 4 — Report the result

After any action, run `list` and show the table. Each account reports as:

| Status | Meaning | What to do |
|--------|---------|------------|
| `ok` | A credential is present for that profile | nothing |
| `needs-login` | No credential is visible | `relogin <label>` |

On a readable config `list` exits `0` whatever the statuses say. It is a report, never a
gate: a `needs-login` row does not block anything, and you must not treat it as a reason
to pause or re-route work. The one non-zero `list` is exit `5` — the config itself is
unusable (see the STOP conditions above), which is a broken tool, not a verdict about an
account.

Never paste the config file's raw contents when a table will do, and never run a
command that reads a credential value out of the keychain or a profile directory. The
statuses above are derived from the *presence* of the artifact the provider's own tool
wrote, which is all anyone needs.

## Reference

Config schema (including the `nickname` field and its limits), the exact per-provider
re-login commands, where each provider keeps its credential, how the Cursor IDE token is
read and why no browser is involved, the LaunchAgent this skill writes — every plist key,
why 09:00, and why the `PATH` has to name Homebrew — and the increment boundary:
`.claude/reference/ai-quotas.md`.

Attribution

Is this your skill, or is something wrong with this listing? Request removal or report an issue. Author removals are honored within 72 hours.

Comments

Loading comments…

Newsletter

Get the weekly list of safe new skills, and the ones we pulled.