Skip to content

Latest commit

 

History

History
299 lines (249 loc) · 13.6 KB

File metadata and controls

299 lines (249 loc) · 13.6 KB

Scriba CLI

The CLI is the contract for both humans and agents. Human-friendly output is the default; pass --json for machine-readable output.

Root

scriba
scriba --version
scriba doctor
scriba doctor --no-remote --json
scriba status
scriba status --fast
scriba status --fast --account work
scriba status --no-remote
scriba status --redact --json
scriba context --json
scriba context --json --account work
scriba accounts
scriba accounts alias <id-or-alias> <new-alias>
scriba mcp
scriba schema
scriba config path
scriba config show --json
scriba config init
scriba config telegram --enable --chat-id <id> --bot-token-env SCRIBA_TELEGRAM_BOT_TOKEN
scriba cache status
scriba cache reset
scriba cache prune
scriba cache vacuum
scriba policy validate policy.json
scriba policy list
scriba policy list --config policy.json --json
scriba policy explain --provider codex --account <ref> --rule <id> --limit 100
scriba outbox list --status leased --limit 100
scriba update --check
scriba update
scriba telegram alerts
scriba telegram alerts --refresh
scriba telegram reset --send --provider codex --label weekly --message "🎉 Tibo just reset limits! 🎊"

Bare scriba is equivalent to scriba status.

status composes local log summaries and remote provider-window probes when auth is available. It writes a derived JSON snapshot and SQLite scan stats unless --no-cache is passed.

doctor checks local source directories, auth paths, remote reachability, cache schema/WAL state, cache size, and latest snapshot age. It reports ok, degraded, or broken.

--fast avoids local rescans and provider requests. It combines cached local status where available with the selected account's latest resident Codex observation. Account-specific reads never borrow anonymous or another account's quota snapshot.

Accounts

scriba accounts and scriba accounts list show every discovered Codex account, including accounts whose credentials are no longer available. Each entry keeps separate facts for its stable public acct-… ID, optional alias, email/plan, credential availability, and last successful observation age. Authentication sources are configuration, not user-facing identities.

scriba accounts alias <id-or-alias> <new-alias> writes only account metadata; it does not change Codex login state or move observations between accounts. Aliases are unique lowercase slugs up to 32 characters. current and strings that resemble generated account IDs are reserved. Use --redact to omit aliases and email addresses from account output.

Agent Context

scriba context --json is intentionally JSON-only. It reads the status cache and server store without provider refresh or mutation and emits the allowlisted scriba.context.v2 contract. --cache-dir and --state-path override its two read sources. Sources report independent availability, provenance, freshness, and reason codes, so a missing Claude observation does not suppress valid Codex context. Use --account <id-or-alias> to select an account; omission uses durable current source bindings and then the latest historical account. Unknown explicit selectors fail rather than falling back.

The checked-in schema is context.schema.json. See agent-context.md for source precedence, privacy exclusions, partial-result behavior, Unix API/SSE cursors, and MCP parity.

scriba mcp is a protocol-pure stdio server for local agent clients. It exposes only scriba_get_context and scriba_list_events; each accepts an optional public account ID, alias, or current. It cannot refresh providers, change config, send notifications, redeem grants, or accept raw provider account refs. Use --config, --cache-dir, and --state-path to select the same read sources as the context command. Normal stdin EOF and handled SIGTERM exit cleanly.

Config

scriba config telegram edits the same config file used by the macOS menu bar settings window. Bot tokens can be stored in the config for app use, or supplied through telegram.botTokenEnv for terminal-only workflows.

scriba telegram alerts reads the cached status snapshot by default so menubar actions stay fast. Pass --refresh when you explicitly want it to rebuild status before evaluating alerts.

scriba telegram reset is the small one-shot send path used by ScribaBar when a reset heuristic fires. It reads the same Telegram config and only sends when Telegram is enabled.

Reports

scriba claude summary
scriba claude daily
scriba claude weekly
scriba claude monthly
scriba claude sessions
scriba claude blocks
scriba claude budget

scriba codex summary
scriba codex daily
scriba codex weekly
scriba codex monthly
scriba codex sessions
scriba codex limits
scriba codex reset-grants
scriba codex reset --dry-run
scriba codex activity
scriba codex budget
scriba codex limits --fast
scriba codex reset-grants --fast --account work

Report commands support --since and --until, accepting full timestamps or YYYY-MM-DD dates. Calendar reports use the system timezone by default. Set timezone in the config or pass an IANA name with --timezone, for example --timezone Europe/Istanbul. JSON report payloads record the resolved timezone.

Codex local reports expose two intentionally different totals:

  • effectiveTokens is uncached input plus output. It matches the accounting shape used by Codex goals, subject to the goal's own active time window.
  • totalTokens is full model traffic: input (including cached input) plus output.

inputTokens preserves the raw Codex input counter, including cache reads; uncachedInputTokens and cachedInputTokens split it explicitly. Reasoning tokens are already included in output and are not counted again. Human output leads with effective tokens, keeps traffic/cache/output visible, and lists up to three materially used exact model names instead of hiding every model except the dominant one.

Local Codex JSONL reports come from session logs, which do not establish a provider account identity. Supplying --account scopes the remote limits appended to summary, but it does not retroactively split local token totals. JSON reports mark attributionScope: "session_logs" and accountAttribution: "unavailable"; human output says the same plainly.

Known Codex models receive a calculated costUSD. The human label is est. because this is a standard-tier API-equivalent estimate, not a claim about what a ChatGPT subscription was charged. The embedded catalog records its review time and current Standard rates. GPT-5.6 Sol, Terra, and Luna use short-context input/cache/output prices and per-request long-context rates above 272K input tokens. The whole request switches tiers; reasoning is not billed separately. Unknown models retain costUSD: null and pricingState: "missing".

scriba codex limits skips local log scanning and only fetches Codex usage windows for the selected account. Omit --account to use the highest-priority usable auth source, or pass a public ID or alias. OpenAI API key auth cannot expose these ChatGPT subscription windows. The live payload includes primary Codex windows, explicit additional model windows such as Spark, and the available rate-limit reset grant count. When the read-only reset-credit metadata endpoint answers, Scriba also shows the earliest available grant expiry. Pass --fast to read the selected account's latest resident observation, including its age and stale state, without making a provider request.

scriba codex summary keeps the local usage summary and, unless --no-remote is passed, appends the same live Codex limits and reset-grant metadata.

scriba codex reset-grants shows available rate-limit reset grants as a focused view, including every available grant's grantedAt and expiresAt timestamp when OpenAI exposes the read-only reset-credit metadata. The short alias is scriba codex grants. For an explicitly selected historical account without credentials, the command falls back to stored grant metadata; --fast requests that behavior directly.

scriba codex reset requires usable credentials for the selected account, fetches current usage and grant metadata, selects the available credit expiring soonest, prints the exact credit, and requires an explicit y confirmation before redeeming it. Use --credit <id> to pin a specific available grant, --dry-run to stop before the redeeming POST, or --yes for deliberate noninteractive use. JSON redemption requires --yes; JSON previews use --dry-run. Each attempt sends one UUID idempotency key and the selected credit ID, then reports one of reset, nothing_to_reset, no_credit, or already_redeemed. Scriba does not retry a timed-out mutation with a new key: it retries one transient failure with the same key. Telegram exposes the same operation only through an owner-bound, expiring confirmation callback; MCP remains read-only. The preview pins the resolved public account, private provider identity, credit, and idempotency key. Auth rotation before a retry or confirmation refuses redemption and requires a fresh preview.

scriba codex activity shows the ChatGPT/Codex profile token-activity backend: lifetime and peak tokens, streaks, longest turn duration, reasoning/fast-mode mix, thread and skill counts, daily/weekly activity bars, and top skills/plugins. --json preserves the full daily, weekly, and cumulative daily bucket arrays for agents. The backend currently reports complete generated buckets, so the current day may be absent until OpenAI generates the next profile snapshot. These provider-generated buckets have no model attribution and are independent from local rollout accounting, timezone grouping, and API-equivalent cost estimates; do not expect exact day-by-day reconciliation.

scriba codex budget and scriba claude budget fetch current provider quota windows and derive pacing, safe allowance, projected exhaustion, risk, freshness, confidence, and explicit reason codes. Budget quantities are quota percentage points, not local token counts: 3pp/h means three points of the provider-reported quota percentage per hour. These commands deliberately do not accept --fast. An explicitly selected historical Codex account without credentials can still derive a visibly stale budget from its stored observation; live/current requests use fresh provider data.

Codex can use matching durable server observations from the preceding 24 hours for its recent-burn estimate; samples less than 10 minutes apart are ignored. Claude currently reports honest current-cycle confidence because it has no durable quota-window history. Derived budget values are never persisted. The machine-readable contract is scriba.budget.v1, validated by schemas/budget.schema.json. See budget-and-policy.md for the full checkpoint and its current runtime boundary.

Policy and Outbox Inspection

The Wave 2 inspection commands are read-only:

  • scriba policy validate <file> strictly parses an operator-supplied policy file without opening server state. Its JSON schema version is scriba.policy-validate.v1.
  • scriba policy list renders the built-in current preset; --config <file> instead parses and lists that file. Its JSON schema version is scriba.policy-list.v1.
  • scriba policy explain opens server SQLite read-only and lists persisted evaluations, filterable by exact --provider, --account, and --rule values. Its JSON schema version is scriba.policy-explain.v1.
  • scriba outbox list opens server SQLite read-only without claiming messages and filters by exact --id, --status, and --target values. Its JSON schema version is scriba.outbox-list.v2.

The state-backed commands accept --state-path, --env, and a --limit from 1 to 1000. --redact on policy explain removes subject/account/config identifiers and persisted state/evaluation bodies. On outbox list it removes account/target identifiers, delivery payloads, lease/provider message identifiers, and last errors. The checked-in Draft 2020-12 schemas are policy-validate.schema.json, policy-list.schema.json, policy-explain.schema.json, and outbox-list.schema.json.

Invalid policy validate --json input still exits nonzero but writes a typed valid: false envelope to stdout. State inspection uses SQLite mode=ro: it does not change the main database, schema, business rows, delivery attempts, or leases. SQLite may still coordinate a live WAL reader through transient -shm/-wal bookkeeping; this is not presented as byte-immutable sidecar behavior.

Server Notifications

The resident server stores every available reset credit from the read-only metadata endpoint when present. Telegram grant-expiry warnings are deduped by grant id, expiry timestamp, and checkpoint, and fire once at 5 days, 3 days, and 1 day before that grant's own expiry.

Human metric output aligns labels within each rendered provider/output, so progress bars start in the same column even when labels differ in length.

Updates

scriba update --check compares the current binary to the latest GitHub tag and prints the detected install manager/path. scriba update installs the latest tag with:

go install github.com/agensfield/scriba/cmd/scriba@<latest-tag>

When the binary resolves under a Homebrew Cellar/scriba path, Scriba refuses self-update and points the user to brew upgrade scriba.

Package Execution

Scriba is a Go binary. Build locally with:

go build -o .build/scriba ./cmd/scriba

The macOS app bundles this native binary directly at ScribaBar.app/Contents/Helpers/scriba.