CLI Pulse — Last Updated: August 6, 2026
| Data | Stored where | Sent to our server? | Purpose |
|---|---|---|---|
| Provider API keys (OpenAI, Anthropic, Google, OpenRouter, etc.) | macOS Keychain on this device | ❌ Never | Used locally to call the provider's own API directly |
| Provider session cookies (manual cookie headers) | macOS Keychain on this device | ❌ Never | Used locally as Cookie header to the provider |
Bridged OAuth tokens from ~/.codex/auth.json, ~/.claude/.credentials.json, ~/.gemini/oauth_creds.json |
macOS Keychain (app-group shared) | ❌ Never | Shared between the sandboxed main app and the local helper only |
Contents of your ~/.codex/sessions/ and ~/.claude/projects/ JSONL files |
Read on-device via security-scoped bookmarks you explicitly grant | ❌ Never | Scanner computes token counts locally |
| Aggregated usage metrics (per-day token counts, cost estimate, model name, provider name, date) | Supabase, linked to your CLI Pulse account | ✅ Yes | So iPhone and Apple Watch show the same history as your Mac |
| Provider quota state (remaining, limit, plan tier, reset time) | Supabase, linked to your CLI Pulse account | ✅ Yes | So mobile clients display current quotas without running the scanner themselves |
| Your CLI Pulse login email | Supabase Auth | ✅ Yes | Required to authenticate you |
| Apple / Google sign-in tokens (during sign-in) | Not persisted — exchanged once for a Supabase session | ✅ Yes (during sign-in only) | Identity verification with the original OAuth provider |
| Supabase session access / refresh token | macOS Keychain on this device | ❌ Never re-uploaded (only received) | Keeps you signed in |
| Device name, OS version, helper version | Supabase | ✅ Yes | Shows which Macs/iPhones are reporting |
| Git activity metadata (commit hash, HMAC of project path, commit timestamp, merge flag) | Supabase — only when "Track git activity" toggle is ON | ✅ Yes (opt-in only) | Powers the Yield Score feature |
| Git commit messages, diffs, file paths, author identity | — | ❌ Never | Explicitly excluded even when Yield Score is on |
| Alerts you resolve locally (quota depletion alerts) | UserDefaults on this device | ❌ Never | Suppression list to prevent re-firing |
| Crash reports (stack trace, app version, OS version, non-PII device model) | Sentry (sentry.io), scrubbed before leaving the device | ✅ Yes (when a crash/error happens) | So crashes are visible to us without waiting for an App Store review |
| Anonymous install statistics (random install id, install channel, app version, OS major.minor, and whether a CLI was ever found) | Supabase — not linked to any account | ✅ Yes, unless you turn it off | Tells us whether the app actually works for people who never sign in |
Every other upload in this table happens only when you are signed in and is attached to your account. Anonymous install statistics are the one exception, so they get spelled out here rather than buried in a table cell.
Since v1.44 you can use CLI Pulse without an account. That means we cannot tell whether the app works for the people using it that way — whether it found their CLIs, whether they ever saw a number. Two counters, and nothing else:
Sent with each: a random identifier generated on your Mac, which channel the
app came from (App Store, direct download, or Homebrew), the app version, and your macOS
version rounded to major.minor (15.1, never the full build string).
Not sent, ever: your account or email (there is no account involved, and no login token is attached to the request), your name, your device's name, serial number or hardware identifiers, your IP address, any file path or project name, which provider you use, or any token count or cost figure.
The identifier is random — not derived from your hardware, and not a hash of anything about it. It lives in the app's preferences, so uninstalling CLI Pulse deletes it; reinstalling produces a new, unrelated one. We cannot connect it to you, and we cannot connect two installs to each other.
Turning it off: Settings › Privacy › “Send anonymous install statistics”. Off means nothing is sent at all. Local-only mode also turns it off — you do not need to set both. The app tells you about this on first launch, before it sends anything.
The key point: the two categories of data you'd be most worried about — provider API keys and raw session-log contents — never touch our servers, full stop.
┌─────────────────────────┐ ┌──────────────────┐
│ Your Mac │ │ AI provider │
│ ┌─────────────────┐ │ │ (OpenAI, │
│ │ API key in │─── Direct ──▶│ Anthropic, │
│ │ macOS Keychain │ │ HTTPS │ Google, ...) │
│ └─────────────────┘ │ └──────────────────┘
│ │
│ ┌─────────────────┐ │
│ │ JSONL session │ │ ┌──────────────────┐
│ │ logs (local) │──── read ────│ CLI Pulse │
│ └─────────────────┘ │ only │ Supabase backend │
│ │ │ │
│ ┌─────────────────┐ │ │ - Email │
│ │ Token counts, │─── HTTPS ───▶│ - Usage numbers │
│ │ costs (numbers) │ │ │ - Quota state │
│ └─────────────────┘ │ │ - Device list │
└─────────────────────────┘ └──────────────────┘
│
▼
┌──────────────────┐
│ Your iPhone / │
│ Apple Watch │
└──────────────────┘
The scanner runs entirely on your Mac. Your API key never passes through our servers — it goes directly from your Keychain to the provider.
com.apple.security.app-sandbox). File access outside the app container requires security-scoped bookmarks you grant explicitly in Settings → CLI Tool Access.sendDefaultPii = false), IP addresses are dropped at the Sentry ingest layer, and a local beforeSend hook scrubs API keys, OAuth tokens, JWTs, Bearer headers, /Users/<name> paths, and any field whose name contains common sensitive fragments (token, secret, password, api_key, supabase, etc.) before the event leaves your device. Performance tracing is disabled (tracesSampleRate = 0); only crashes and explicit error reports are sent.data_retention in Settings → Privacy, that value applies to your sessions, alerts, and device snapshots.We do not share data with any party not listed above. We do not sell data.
CLI Pulse is a developer tool intended for users 17 or older. We do not knowingly collect data from children.
We will update the "Last Updated" date above when this policy changes and note material changes in release notes. The authoritative version lives at https://cli-pulse.github.io/cli-pulse/privacy.html.
We've looked at adding E2EE to the Supabase-stored metrics. Today, the sensitive data (API keys, session log contents) already never leaves your device, so the marginal privacy gain from encrypting the numeric metrics is smaller than it sounds. Implementing E2EE also conflicts with cross-device sync, which requires multi-device key management we don't want to ship half-built. If you have a specific threat model where E2EE on metrics matters to you, please open an issue — we'd rather hear the use case than guess.
[CLI Pulse Security])