Legal
Privacy policy
Version 2.1 · Last updated 1 October 2026
Your work stays on your Mac. This website has no analytics or tracking cookies.
Pairbar is built so that your work stays on your Mac. This policy explains, in plain language, what personal data is involved in buying and using Pairbar and visiting pairbar.com, who handles it, how long it's kept and what you can ask us to do with it. The full technical detail of what the app reads, stores and sends is further down this page, under The app, in detail.
Who we are#
The controller of your personal data is Roberts Ribakovs, an individual developer in Latvia ("we", "us"). For anything about your data, email support@pairbar.com. A postal address is available on request by email.
The short version#
- The app has no account, no analytics and no crash reporting. It never uploads your chats, files or anything it reads on your Mac.
- The app goes online only to check your licence (and look up its plan), pick up a purchase or an emailed activation link, and check for updates. Buying starts at pairbar.com/buy, which sends you on to Lemon Squeezy's checkout.
- pairbar.com has no analytics and no tracking or advertising cookies.
- Payments are handled by Lemon Squeezy. We never see your card details.
What we collect, and why#
| What | When | Why | Legal basis (GDPR) |
|---|---|---|---|
| Your email, name, country, order and licence details (from Lemon Squeezy) | when you buy, renew, cancel or get a refund | to deliver and manage your licence, activate Pairbar automatically, answer support, keep records | performing our contract with you; legal obligations (accounting) |
Your licence key and an anonymous name for each Mac it's active on (the Mac's model and a random id, e.g. Mac14,2 · 3f9a1c07) | when you activate, and about once a week while it's active (to Lemon Squeezy; the key also to pairbar.com, which answers with your plan and renewal date) | to check the licence, enforce the activation limit and show your plan | performing our contract |
| The email address you type into Use my email | when you ask for an activation link | to email that link to the address your licence has | performing our contract |
| The email address you leave in an Email me at launch form on pairbar.com | when you sign up | to email you once when Pairbar 1.0 is released, with the launch discount | your consent (ask us and we delete it) |
| Emails we send you (activation links), and their delivery status | when we send one | to send it, and to see whether it arrived | performing our contract |
| Emails you send to support, and anything you choose to attach (such as a support report) | when you write to us | to help you | performing our contract; our legitimate interest in giving support |
| Download counts: the version, the time, your country (from our host's location header) and a shortened browser user agent and referrer, with no IP address | when you download Pairbar | to count downloads per version and country | legitimate interest in understanding how Pairbar is used |
| Your IP address, in request logs and short-lived rate-limit counters (stored hashed) | whenever you visit pairbar.com or the app contacts it | to run the site, keep it secure and stop abuse | legitimate interest in security |
We don't sell your data, use it for advertising, or build profiles.
Who handles it for us#
| Who | What they do | Their policy |
|---|---|---|
| Lemon Squeezy | the store and merchant of record: checkout, payment, tax, receipts, licence keys and licence checks. They're responsible for the payment data they collect | privacy policy |
| Vercel | hosts pairbar.com and its small backend (activation, the webhook from Lemon Squeezy) | privacy policy |
| Neon | the database behind that backend: orders, licence records, activation requests, the launch list, the email log, download counts | privacy policy |
| Resend | sends the activation emails and the one launch email | privacy policy |
| Cloudflare (R2) | hosts the app downloads and the update feed at downloads.pairbar.com; it sees your IP address when you download or check for updates | privacy policy |
| Our email provider | receives the email you send to support@pairbar.com, and keeps our replies |
Some of them are based in, or process data in, the United States. Where data leaves the EU or UK, it's protected by the providers' data-processing terms, including the European Commission's standard contractual clauses or an equivalent safeguard.
How long we keep it#
- Orders and licence records: for as long as your licence exists, and afterwards as long as accounting and tax rules require. Lemon Squeezy keeps its own records under its policy.
- Activation links and codes: a code expires within a day and a link within 30 minutes; the records of them are kept with your licence records.
- The launch list: until the launch email is sent, and afterwards only as long as needed to make sure nobody is emailed twice. Ask us and we delete your address at any time.
- Support emails: as long as we need them to help you, and then for a reasonable time in case the same problem comes back. Ask us and we'll delete them.
- Download counts: they contain no personal data and are kept as statistics.
- Rate-limit counters hold only a one-way hash of an IP address or email, never the value itself, and only count requests over minutes or hours. Our hosts keep request logs for a limited period under their own policies.
Your rights#
Wherever you live, you can ask us to:
- tell you what personal data we have about you and give you a copy (access and portability);
- correct it;
- delete it, unless we must keep it (for example for tax records); deleting your licence records means your licence can't be restored or checked;
- restrict or object to how we use it.
Email support@pairbar.com from the address you bought with, or tell us your order number. We answer within one month. For your purchase and payment data held by Lemon Squeezy, you can also contact them directly. If you're in the EU or UK and unhappy with our answer, you can complain to your local data protection authority; in Latvia that's the Data State Inspectorate (Datu valsts inspekcija).
The website#
pairbar.com uses no analytics, no tracking cookies and no advertising. Your browser stores your light or dark theme choice on your own device (local storage); it never leaves your device. The admin area, used only by us, sets a sign-in cookie. The checkout is Lemon Squeezy's, under their privacy policy.
The app#
Pairbar runs on your Mac and reads the files the Claude and Codex apps keep there. It doesn't upload them: your chats, projects, files and usage never reach us. Its own requests are only the licence check, automatic activation and the update feed, detailed below.
Features that use AI run through your own claude and codex tools, which talk to Anthropic's and OpenAI's services under their privacy policies, on your plans. Pairbar doesn't send anything to those services itself.
Contacting support from the app (Settings → About → Contact support…, the menu-bar menu or ⌘K) opens an email draft in your mail app with the app version, macOS version, the Claude and Codex app versions and your plan (never your licence key). You can add a diagnostics report, which shows you exactly what's in it first: recent lines from Pairbar's debug log, with secrets masked and your home folder shown as ~, and never your chats' contents. Nothing is sent unless you send the email yourself.
Voice dictation (if you use it, once it's available in an update) is processed on your Mac, and its history is kept only on your Mac.
Children#
Pairbar is a tool for developers and isn't directed at children under 16.
Changes#
We'll update this policy when what we collect changes. The version and date are at the top of this page, and changes are listed at the bottom. For a significant change we'll tell customers by email or in the app.
The app, in detail#
Pairbar runs on your Mac. It has no account, no analytics, no crash reporting, and it does not automatically upload the chats it indexes or your Notes library. Messages, attachments and workflow prompts you intentionally send go through your configured Claude or Codex provider under its settings. Pairbar itself makes exactly four kinds of network request, all described under Network: checking your licence key with Lemon Squeezy, activating your subscription with pairbar.com (only when you subscribe or ask for an activation email), checking for updates, and, only with Voice → Recognition → Best accuracy, downloading the Whisper speech model once.
What it reads#
| What | Where | Why |
|---|---|---|
| Claude Code sessions | ~/Library/Application Support/Claude/claude-code-sessions/…, transcripts in ~/.claude/projects | the chat list, status, search |
| Claude Code subagents | each chat's ~/.claude/projects/<project>/<session>/subagents/agent-*.jsonl and .meta.json, and the chat's own transcript (the Task calls and their results), read only while a chat's subagents are unfolded, their transcript is open in the reader, or, with subagent alerts on, while its subagents work; only what the files gained is read again | the subagent list (status, type, model, tokens, tool calls, result), the transcript reader (its brief, steps and their output, result; commands shown as their program and subcommand, links as their site and path), subagent alerts. Kept in memory while needed, never stored or sent |
| Claude Code's running sessions | ~/.claude/sessions/<pid>.json (read-only): each running session's id, whether it's busy, idle or waiting on you and for what, when that changed, and whether its process still runs | the status: permission prompts and long commands |
| Claude Code's settings | ~/.claude/settings.json: whether Pairbar's hooks are in it, statusLine (whether it's Pairbar's, and your own command, which Install runs inside Pairbar's), and disableAllHooks (read when Settings is open, at launch, and when you install or uninstall); around each claude Pairbar starts for itself, the whole file, compared in memory with what it was before (never written) | Settings → Integrations: live status installed or not; the debug state |
| Claude Code's migration level | migrationVersion in ~/.claude.json (only that value, found in the file's text; nothing else in the file is kept), before Pairbar would start claude -p /usage | not starting claude while it would update your settings for a new version (see the Limits page of the docs) |
| Claude Code's hook events, with live status on | sent by Claude, through Pairbar's helper, over a private socket: see Live status for Claude | the status, the tool a chat is running, subagents |
| Codex's config | ~/.codex/config.toml and ~/.codex/hooks.json: whether Pairbar's hooks are in them, whether Codex trusts them ([hooks.state]), and hooks under [features] (read when Settings is open, at launch, and when you install or uninstall). The files are parsed in memory to check them; nothing else in them (your MCP servers' environment, keys) is kept, shown, logged or sent | Settings → Integrations: live status for Codex installed or not |
| Codex's hook events, with live status for Codex on | sent by Codex, through Pairbar's helper, over the same private socket: see Live status for Codex | the status of Codex chats, including approval requests, and the command a chat is running |
| Calls to Pairbar's tools, with them installed | a request from a Claude or Codex chat (or a pairbar command) over a private socket: the tool's name and arguments, the MCP host's name, Codex's thread id or CLAUDE_CODE_SESSION_ID as a hint. To tell which chat is calling, Pairbar reads the calling process's id, working folder and parent processes (their ids, short names, paths and start times) from the kernel, and the one ~/.claude/sessions/<pid>.json of the Claude process above it: see Pairbar's tools | answering the call, and the Activity list |
| Claude's and Codex's plugin records, with the tools installed | ~/.claude/plugins/installed_plugins.json and known_marketplaces.json (whether pairbar@pairbar and the pairbar marketplace are there), enabledPlugins in ~/.claude/settings.json; from ~/.codex/config.toml only the names of its [plugins."…"] and [marketplaces.pairbar] tables, enabled and that marketplace's source; Codex's copy of Pairbar's plugin in ~/.codex/plugins/cache/pairbar (to compare with Pairbar's) | Settings → Integrations: Pairbar tools installed, up to date, or needing repair |
| Codex threads | ~/.codex/state_<n>.sqlite (read-only), rollouts in ~/.codex/sessions, ~/.codex/models_cache.json | the chat list, status, search, model picker |
| Claude Code cloud sessions | the Claude app's local web cache, ~/Library/Application Support/Claude/IndexedDB/https_claude.ai_0.indexeddb.blob (read-only: each file is copied to a private temporary file, read and the copy deleted) | cloud chats in the list. The cache also holds other things the Claude app keeps (your chat list, account details); Pairbar decodes it in memory, keeps only each cloud session's id, title, repo, branch, environment id, status and dates, and never stores or sends any of it |
| Codex cloud tasks | codex cloud list --json, run with your own codex | cloud chats in the list: each task's id, title, status, environment and date |
| App layout | Claude's settings and local storage, ~/.codex/.codex-global-state.json, and native divider accessibility metadata (position, size, current/minimum/maximum width) | matching the apps' sidebar width; a bounded metadata scan finds and caches the divider without reading chat text |
| Agents | ~/.claude/agents, <repo>/.claude/agents, ~/.claude/plugins/installed_plugins.json and plugin agent files, dock.yaml | the Agents page |
| Skills | every skill folder Claude and Codex load: ~/.claude/skills (and the folders it links into), ~/.agents/skills, ~/.codex/skills, your repos' .claude/skills and .agents/skills, installed plugins' skills folders (Claude's from installed_plugins.json's install paths, Codex's from ~/.codex/plugins/cache), /etc/codex/skills. Each skill's SKILL.md is read (up to 256 KB) and every file in its folder is hashed (sha256). From ~/.claude/settings.json only enabledPlugins, and from ~/.codex/config.toml only the names of its [plugins."…"] tables and their enabled are kept: the files are parsed in memory, and nothing else in them (MCP servers' environment, keys) is kept, shown, logged or sent. Watched for changes while Pairbar runs | the Skills tab, a workflow step's or a new chat's skills, the planner's list of skills |
| Git | status, diff and log of a chat's folder; the HEAD file of a Codex thread's worktree | hover details and handoffs; the branch a working chat is on now |
| Windows | position and size of other apps' windows (for the always-visible dictation pill: only the app in front's, from the window list, every 1.5 seconds while the pill is shown, and whether something such as a playing video keeps the display awake) | placing the sidebar; the dictation pill on the display you're working on, and out of the way of a full-screen video or slideshow |
| Claude and Codex window kinds (Accessibility) | when a new window appears: which window is the main window, its subrole, whether its size can be changed and whether its minimise or zoom controls are enabled; kept only in memory, no window contents read | keeping the sidebar on chat windows instead of utility panels or dialogs |
| Claude and Codex windows (Accessibility) | their position, size, and whether they're in full screen or minimised, only when you pick a layout, swap, or restore a setup | window layouts: moving the windows and reading back where they ended up |
| Displays | each connected display's id (the one macOS gives it), frame and usable area; whether Stage Manager is on (macOS's com.apple.WindowManager setting) | layouts and saved setups; kept in the preferences only as part of a setup you save |
| Claude's and Codex's View menus (Accessibility) | only while docked with Hide Claude's and Codex's own sidebars when docked on: the sidebar item's title, and pressing it to hide the app's own sidebar (and again when you undock); nothing else in the menus is read or pressed | a clean docked group with one sidebar |
| A picture of the bottom of Claude's or Codex's window, for the dictation pill (Screen Recording) | only with the Screen Recording permission allowed, and only while the pill or card is on that window and the app is in front: the window's bottom strip (260 pt, one pixel a point), when the app comes forward, after a click, a ⌘ key combination or a resize, and otherwise at most every 1.5 seconds and only within 20 seconds of your last click or ⌘ combination. Pairbar reads where the message box's border is from it and drops it at once | placing the pill and card on the message box (the apps don't tell other apps where it is). Never kept, saved or sent; without the permission the place is estimated |
| The text field you're in, in other apps (Accessibility) | when you dictate into another app, and at rest only while dictation's pill is set to show next to text fields (not with the always-visible pill, the default), in the app in front (not apps built on Chrome, whose pages are never read): the focused field's kind (to tell a text field, and a password field, from anything else), its position and size, its scroll area's and window's, and where the caret is; when its text changes (only that it changed). Never its text. When you dictate into it: the words put in, and once read back to check they went in | the dot by the field, the card's place, putting the words in |
| Your clipboard, for a moment, when dictating into another app that doesn't take the words through Accessibility | what's on it is kept in memory, the words are put on it and pasted (⌘V, to that app only), and what was there is put back 0.6 s later, unless something else was copied meanwhile | putting the words in. Nothing kept afterwards |
| Pictures of the Claude and Codex windows, and of what's behind the basket (Screen Recording) | only with the Screen Recording permission allowed: one picture of each of the two docked windows when they swap or change arrangement (with Animate the basket and swaps on), and, while the basket is docked, pictures of the two windows and of the screen area just around the basket without the basket in it: shortly after the basket settles, when the pointer comes near it (at most every few seconds), and when you press to move it | the animated swap, and the basket's stand-in while you move it (so the windows never show at their old place). Only the latest set is kept, in memory, replaced as new ones are taken and dropped after 30 seconds or when you leave the basket; never saved, never sent |
| Claude Code's plan limits, with live status for Claude installed | the JSON Claude Code hands its status line: the helper keeps only rate_limits (each window's used percentage and reset time) and drops the rest of it before writing anything; your own status line command gets the same input, unread | the limits card and rings, without starting claude -p /usage |
| Your voice, only while you dictate | the microphone (with your permission, asked the first time you press the mic), from the moment you start until you stop or press Esc; never when you aren't dictating. It's turned into text on this Mac by macOS's speech recognition (SpeechAnalyzer; its language models download from Apple the first time a language is used, as macOS's own dictation does) and, with Recognition → Best accuracy, by Whisper (WhisperKit, on this Mac; the dictation's audio is kept in memory until it's transcribed, then dropped) | voice dictation. Nothing you say is sent anywhere, unless you turn on Polish (below) |
| Where the text cursor is, only when you double-tap the dictation key, start dictating into Claude or Codex, or bring one to the front | through Accessibility, Claude's or Codex's focused element: its role, the roles of the elements above it (to tell its message box from anything else) and its position and size, once per event. While the pill is on Claude's or Codex's window and that app is in front, the box found last has its position and size read again (two attribute reads, nothing else) when it reports a change, after a mouse-up or a ⌘ key combination is let go (only that ⌘ was held, never which key), after Send, and otherwise every 2 seconds, so the pill follows the box when a side pane opens; stopped when the app isn't in front. Never the box's text | starting dictation into that message box; placing the dictation pill and card next to it |
| Words for recognition, when you dictate | the project's name and branch, the names of the files git says changed in that folder and in its last 15 commits (git status, git log --name-only, read-only, in the background, kept in memory for two minutes), skill and agent names, your personal dictionary | biasing the speech model toward your project's words; passed to macOS's speech recognition and Whisper on this Mac, never stored; your recent projects' names too; with Polish on, the names (and where you're dictating: Claude Code, Codex or the composer, the project, the chat's title) go with the text to your Claude or Codex (below) |
| Processes | the memory and CPU time of your own processes (their ids, parents and names) and the Mac's total memory use, every 2 seconds while the limits card is open | "On this Mac" in the limits card; kept in memory only, never stored or sent |
What it stores#
| What | Where | How long |
|---|---|---|
| Settings, pins, labels, names you give chats and tasks in Pairbar, hidden and unread marks, tasks marked done or archived, the Skills tab's filters, sort and folded sections | the app's preferences | until you reset (Settings → Reset Pairbar) |
| Saved window setups: a name, the displays' ids and frames, and where each app's window was | the app's preferences | until you delete the setup (Settings → Windows) or reset |
| A Claude chat's fork, when you fork it | a copy of the chat's transcript under a new session id, next to the original in ~/.claude/projects (the original is only read) | it's a Claude chat like any other: Claude keeps it until you delete it |
| A Codex chat's new name, when you rename it | Codex's own ~/.codex (its database and session_index.jsonl), written by your codex itself, never by Pairbar | until you rename it again, in Pairbar or Codex |
| Pairbar's hooks in Claude's settings, only when you press Install… or Repair (and confirm) | one entry per event added to "hooks" in ~/.claude/settings.json, and the status line (below); nothing else in the file changes | until you press Uninstall, which removes exactly them and puts your status line back |
| A copy of Claude's settings file, before each change Pairbar makes to it | ~/.pairbar/backups/claude-settings-<date>.json, readable only by you | the latest 10 are kept |
| Pairbar's hooks in Codex's config, only when you press Install… or Repair (and confirm) | one block at the end of ~/.codex/config.toml, between Pairbar's comment lines (or entries added to ~/.codex/hooks.json when your hooks are there); nothing else in the file changes. And a link, ~/.pairbar/bin/pairbar, to the helper inside Pairbar | until you press Uninstall, which removes exactly them and the link |
| Pairbar's status line in Claude's settings, with live status for Claude installed | statusLine in ~/.claude/settings.json, running Pairbar's helper (your own status line command inside it); what your status line was before, so Uninstall can put it back, in ~/.pairbar/claude-statusline.json, readable only by you | until you uninstall; if you change the status line yourself, Pairbar never puts its own back unless you click Limits: reconnect |
| Claude's plan limits from the status line: each window's used percentage and reset time, and when they were seen | ~/.pairbar/run/claude-limits.json, readable only by you (0600, in a 0700 folder) | replaced by the next status line update |
An empty temporary home for asking a Claude Code version its migration level (claude plugin list, with no account and no network address) | $TMPDIR/pairbar-scratch/pairbar-claude-probe-*, private to your account | deleted as soon as it answers; once per Claude Code version |
| A copy of Codex's config file, before each change Pairbar makes to it | ~/.pairbar/backups/codex-config-<date>.toml (or codex-hooks-<date>.json), readable only by you (0600, in a 0700 folder). It's the whole file, secrets included, so it stays as private as the original | the latest 10 are kept |
| The event socket (a file only your account can use; nothing is stored in it) | ~/.pairbar/run/events.sock | while Pairbar runs |
| Pairbar's plugin, only when you press Install… for Pairbar's tools (and confirm) | ~/.pairbar/plugins (the marketplace, both apps' manifests, the MCP entries, the bin/pairbar script, the guide skill), the link ~/.pairbar/bin/pairbar, and ~/.pairbar/install-manifest.json (each file's hash, the commands run and their inverses), all written by Pairbar. Then Claude's and Codex's own commands record the plugin in their files: enabledPlugins and extraKnownMarketplaces in ~/.claude/settings.json and ~/.claude/plugins, or [marketplaces.pairbar] and [plugins."pairbar@pairbar"] in ~/.codex/config.toml and a copy in ~/.codex/plugins/cache. For Claude the default is only a link, ~/.claude/skills/pairbar (no Claude file changes); Claude's own commands run only with the Advanced install | until you press Uninstall, which runs their inverses and removes the files Pairbar wrote that you haven't changed |
| A copy of Claude's settings or Codex's config, before Pairbar's tools are installed, updated or removed | ~/.pairbar/backups/plugin-claude-settings-<date>.json, plugin-codex-config-<date>.toml, readable only by you (0600, in a 0700 folder) | the latest 10 of each are kept |
| The control socket (a file only your account can use; nothing is stored in it) | ~/.pairbar/run/control.sock | while Pairbar runs |
Agent activity: each call to Pairbar's tools (when, which chat or folder, the tool, a short summary of its arguments with secrets masked and paths as ~, how it went, the answer's size and how long it took; never the answer, a chat's messages or the environment) | ~/.config/pairbar/activity.jsonl, readable only by you | 90 days, at most 5,000 calls and 5 MB; Settings → Integrations → Agent activity → Clear… |
| Agent requests (tickets), only when a chat with Pairbar's tools asks for an agent action: who asked (the chat's id, title and folder), the kind, app, access and folder, the full brief sent to the helper (the question, context, the diff Pairbar read for a review, or the prompt; for a workflow run, the note and each step's state; for a check-in, its message and timer), what was decided, when and by whom, the helper's chat id, and its reply (up to its last 200,000 characters) or why it failed. The Activity list gets only the ticket id, the decision and at most 120 characters of the request, never a reply | ~/.config/pairbar/agent-runs.json, readable only by you | the last 300 finished requests; a request waiting for you expires after an hour |
| Your Agent actions settings (paused or not, what each kind does, the budgets) | Pairbar's preferences (agentActionSettings) | until you change them or reset Pairbar |
| What the hooks last said about each chat (its state, the tool, the event's time) | in memory only | a day at most; gone when Pairbar quits |
| When the last hook event came, for Claude and for Codex | the app's preferences | replaced by the next one |
| Search cache: the text of your chats, no tool output | ~/Library/Caches/<bundle id>/text, readable only by you | pruned when chats disappear; Settings → Clear search cache |
| Handoffs: a whole conversation plus repo state | ~/.pairbar/handoffs, readable only by you | handoffs older than 14 days are deleted whenever you make a new one |
| Agents you create or edit, Codex exports | your agents folder, ~/.codex/agents | until you delete them (they go to the Trash) |
| A skill made available to the other app, only when you pick Make available… (done at once, with Undo), approve a plan (Sync all skills…, a card's Update), or turn on Keep skills the same in Claude and Codex (your personal skills, in the background) | a link in ~/.agents/skills or ~/.claude/skills (or in the repo's .agents/skills / .claude/skills for a project's skill) to the skill's folder, or, for a skill that needs changes for Codex (or a plugin's skill you ticked), a generated copy there marked "Generated by Pairbar"; a broken link in its place moved to the Trash | until you pick Undo (removes it only if unchanged) or delete it |
| What you chose about syncing skills: each skill's version its copies last agreed on (a hash, for Keep skills the same), ones you took out of an app ("Keep it removed"), cards and conflicts you left as they are, when you last synced | ~/.pairbar/skills-sync.json, readable only by you (0600) | until you reset Pairbar or delete it |
| Use in chat on a skill | the skill's invocation (/name or $name) typed into the focused Claude or Codex chat's message box, as key presses sent to that app only (with Accessibility); without it, copied to the clipboard. Never sent | — |
| What Pairbar made for skills | ~/.pairbar/skills-manifest.json (each link or copy's path, what it points to, its hash), readable only by you | until Undo removes the entry |
| A skill copy's files, before Replace with the copy in … (or Update, Keep this one, Sync all or Keep skills the same bringing copies to one version) changes them | ~/.pairbar/backups/skills/<name>-<date>/, readable only by you (0700) | until you delete it |
| Profiles for agents' requests (name, app, model, effort, access, when to use it, cost, an agent's name, skill names), only once you change the five defaults | ~/.config/pairbar/profiles.json, readable only by you (0600) | until you change or reset them |
How often skills were used in chats: from the transcripts of the last 30 days (~/.claude/projects, ~/.codex/sessions), only each skill's name and when (a Claude Skill call or slash command, a Codex $name in your message), per transcript file with its size and date; never a message | skill-usage.json in Pairbar's caches folder, readable only by you | read again when the Skills tab opens (at most every 30 minutes); files older than 30 days drop out |
| Pinned versions of skills a workflow step uses | ~/.config/pairbar/skill-snapshots/<sha256>/, readable only by you (0700) | removed at launch once no workflow pins that version |
| A skill's text for one Claude step that can't load it | $TMPDIR/pairbar-scratch/pairbar-step-skill-*.md, private to your account | deleted when the step ends |
| Workflows, their runs (each step's status, chat id and reply, capped), the doctor's suggestions, earlier versions, check-ins | ~/.config/pairbar/*.json, readable only by you (files 0600 in a 0700 folder, written whole) | until you delete the workflow; the last 300 runs and 10 versions are kept. A file that couldn't be read is kept beside it as <name>.corrupt-<date> until you delete it |
| A copy of one of the Claude app's cache files, while it's read | $TMPDIR/pairbar-scratch/pairbar-cloud-<pid>-*, in your own temporary folder | deleted right after reading (well under a second); one a read in progress leaves when Pairbar quits is deleted as it quits, and any left by a Pairbar that crashed at the next launch |
A running step's reply file (Codex -o), the planner's schema and answer | $TMPDIR/pairbar-scratch/pairbar-step-*.txt, $TMPDIR/pairbar-scratch/pairbar-plan*.json, in your own temporary folder (private to your account) | deleted when the run ends; leftovers from a crash are deleted at the next launch once a day old |
| When the free trial started, and the latest time Pairbar has seen (so setting the clock back doesn't restart it) | the login Keychain (item <bundle id>.licence, account trial) and the app's preferences | kept after the app is deleted, so a reinstall doesn't restart the trial; remove it with Keychain Access (search "Pairbar licence") |
| Your licence key, the email Lemon Squeezy has for it, this Mac's activation id, when it was last checked | the login Keychain (<bundle id>.licence, account license) | until you choose Settings → Licence → Deactivate this Mac… |
| A one-time code for a purchase you started (so Pairbar can pick it up by itself) | the login Keychain (<bundle id>.licence, account pendingActivation), with when it was made | until the purchase is picked up, or a day at most |
| A random 8-character id for this Mac (not derived from any hardware or account) | the login Keychain (<bundle id>.licence, account device) | kept, so the activation name stays the same |
| Dictation history: what the speech model heard, the text it became, when, where it went (composer, Claude, Codex) or that it wasn't inserted, the project, the language, how long, and whether Polish rewrote it | ~/.pairbar/voice/history.jsonl, readable only by you (0600, in a 0700 folder) | Settings → Voice → Keep dictation history: 30 days to start with, or forever, 7 days or not at all (at most 2,000 dictations); Delete all… removes it |
| Dictation audio, only with Keep audio for 24 hours on | ~/.pairbar/voice/audio/<id>.caf (16 kHz mono), readable only by you | deleted after 24 hours, with its dictation, or by Delete all… |
| Your voice settings (shortcut, languages, modes, dictionary, Polish, the Settings tab you last used) | the app's preferences | until you change them or reset Pairbar |
The Whisper speech model, with Recognition → Best accuracy (about 650 MB, downloaded once from Hugging Face, argmaxinc/whisperkit-coreml, and its tokenizer from openai/whisper-large-v3) | ~/Library/Application Support/Pairbar/models (with .prepared.json: the model, Pairbar's and macOS's build it was last loaded with, so it's prepared again in the background after an update); macOS keeps a copy prepared for the chip in Pairbar's caches | Settings → Voice → Languages → Whisper model → Delete |
| Debug log | $TMPDIR/pairbar-debug.log | only if you turn on the debug setting; capped at 1 MB |
| Planner debug log: the planner's raw answer when it couldn't be read | $TMPDIR/pairbar-scratch/pairbar-planner.log, readable only by you | only with the debug setting on; replaced by the next failure |
Network#
Pairbar itself talks to three services, and nothing else:
1. Lemon Squeezy's licence API (https://api.lemonsqueezy.com/v1/licenses/…), the store Pairbar is sold through. Requests are made:
- when you activate a key: sends the key and this Mac's instance name;
- while activated, when Pairbar starts (at most once an hour) and about once a week in the background, daily while a subscription has ended, and when you press Check now: sends the key and this Mac's activation id (to check it's still valid, and when the subscription renews);
- when you deactivate this Mac: sends the key and the activation id.
The instance name is the Mac's model identifier and a random id, for example Mac14,2 · 3f9a1c07: no name, serial number, user name or account. Lemon Squeezy sees your IP address, as any web request does, and already knows the email you subscribed with. Nothing about your chats, projects, files or usage is sent. During the trial nothing is sent at all. See Lemon Squeezy's privacy policy.
2. Pairbar's activation service (https://pairbar.com/api/activation/…), so you never copy a key:
- after you press Subscribe (or Renew, or one of the plans): your browser opens
https://pairbar.com/buy/<plan>, which sends it on to that plan's Lemon Squeezy checkout. The link carries a random one-time code made on this Mac (32 random bytes, kept in the Keychain for at most a day), and Pairbar asks pairbar.com with that code every few seconds (every 15 seconds after two minutes, for up to 30 minutes, and again when you come back to Pairbar or relaunch it within the day) whether the purchase has come through; the answer is your licence key, which is then activated with Lemon Squeezy as above; - when you click Activate Pairbar in the activation email (a
pairbar://activatelink): sends that link's one-time token, and gets the key back; - when you choose Use my email: sends the email address you typed, so pairbar.com can email a link to the address your subscription has;
- after an activation and after a licence check that succeeds (best effort; nothing changes if it fails): sends your licence key to
https://pairbar.com/api/activation/plan, which answers with the plan (Monthly, Yearly or Lifetime) and a subscription's renewal date, since Lemon Squeezy's licence check doesn't say. Nothing about the key's buyer comes back.
Nothing else is sent: no name, no Mac details, nothing about your chats. pairbar.com sees your IP address, as any web request does.
3. The update feed (Sparkle): once a day (if "Check for updates automatically" is on) and when you choose Check for Updates…, Pairbar downloads a small appcast.xml from https://downloads.pairbar.com/ listing the newest version, and downloads an update only when you agree to install it. The request carries the usual app and macOS version in its user agent; no system profile or anything else is sent.
4. The Whisper speech model, only with Settings → Voice → Recognition → Best accuracy (the default on Apple silicon): the first time you dictate (or press Download), Pairbar downloads the model files (about 650 MB) from Hugging Face (https://huggingface.co/argmaxinc/whisperkit-coreml, folder openai_whisper-large-v3-v20240930_turbo_632MB) and its tokenizer (openai/whisper-large-v3). These are plain file downloads with no account or token; Hugging Face sees your IP address, as any web request does. Nothing you say is sent: Whisper runs on this Mac.
Everything else that reaches the internet goes through command-line tools you have installed, which talk to their own services:
claude: starting chats with custom settings, a fork's first message, follow-ups, reading plan limits, and workflows (their steps, planning a workflow from your description, editing one step’s prompt, goal checks and the doctor's suggestions). Plan limits come from Claude Code's status line or the Claude app first;claude -p /usageis a last resort, and isn't started while it would make Claude Code's once-per-version settings update (your own Claude makes it). Pairbar never writes back anything Claude changes in its settings.claudeandcodexalso run the helper chats, second opinions, reviews and workflow runs agents ask for (see Agent actions), only as your settings allow or after you approve them;gh pr diffreads a PR's diff for a review an agent asks for. With Deliver results into the chat that asked on, a result the asking chat didn't collect is sent into that chat withcodex queueorclaude -p --resume(the same as Send a message), and check-ins a chat scheduled on itself are sent the same way.codex: forks, follow-ups, archive, renaming a chat (codex app-server, started for that one request and stopped once Codex answers; it changes the thread's name, archives an available local thread or copies a fork of its saved history, in Codex's own files), cloud tasks, listing your cloud tasks (codex cloud list: at most every 5 minutes, only while the sidebar is showing), and the same workflow work.claudeorcodexfor Polish (voice dictation), on to start with (Settings → Voice → Polish turns it off): the dictation's text, after the local cleanup, is sent to your Claude (claude -p --model haiku --no-session-persistence --tools "" --strict-mcp-config --setting-sources "", nothing saved, no tools, no extended thinking, and none of your Claude settings, so your own hooks and permissions don't run for it; your sign-in still works) or your Codex (codex exec --ephemeral --ignore-user-config -s read-onlywith its smallest model) to be rewritten. It uses your plan. So that it's quick, Pairbar keeps one such Claude process ready in the background (started about 10 seconds after launch while Polish is on; not in Low Power Mode): it's sent one short warm-up message ("Reply with OK.", a few tokens of your plan) when it starts, then waits without using anything until a dictation's text arrives; it handles one dictation and is replaced. It's stopped when Pairbar quits, after 30 idle minutes, and when Polish is turned off. Translate to English uses macOS's own translation on this Mac (the language pair downloads from Apple once, when you ask). With Polish on, when Claude or Codex can't polish (or with Polish with → On-device), Apple's on-device model (Apple Intelligence) polishes on this Mac instead: nothing is sent.gh: pull-request status, and for the Tasks view each task's PR title and checks (gh pr list --head <branch>in the task's folder, a few at a time, each answer kept for 10 minutes).
Local interactive Codex new chats and handoffs open through codex://new with the first message and folder, without a CLI model turn. Forks copy history with thread/fork and stop the temporary server before opening the fork. The text is prefilled in Codex, and is sent only when you press Send there; requested model, effort and permissions must be chosen in Codex first.
Workflows run only while Pairbar is running, on the schedule you set, and use your plan like any chat. A step's reply is passed to the steps after it as data, framed so it can't pass for instructions. A read-only Claude step runs without the tools that change files or run commands (Edit, Write, MultiEdit, NotebookEdit, Bash), whatever your own Claude settings allow; a step set to run commands gets Bash but not the edit tools; the planner, the goal check and the doctor only get Read, Glob and Grep (no commands, no MCP servers), and on Codex the read-only sandbox. Model and effort names are checked before they reach a command line, and chat ids before they're used in a path or an argument.
Links open only if they're https://, mailto: (the support link), claude:// or codex://. A link in a tool's output (a cloud session or task) opens by itself only when it's on the service that tool belongs to (claude.ai, chatgpt.com); anything else is shown, not opened.
Live status for Claude (hooks)#
Off until you install it (Settings → Integrations; the Integrations page of the docs has the details). Then Claude Code runs Pairbar's helper (Pairbar.app/Contents/Helpers/pairbar hook <event>) on each hook event, and the helper passes Pairbar only:
- the chat's session id, folder (
cwd) and transcript path; - the event's name (
PreToolUse,Stop…), and a subagent's id and type; - the tool's name and the summary Pairbar already shows for it (a command's program and subcommand, a file's name, a URL's host);
- a notification's kind and Claude's short message, a failed stop's error kind, whether a Stop hook is continuing, a session's start source and end reason;
- the helper's parent process id and the time.
Your prompts, tools' inputs and outputs, Claude's replies and anything else in the event are dropped by the helper before anything leaves it. The line goes to Pairbar over a Unix socket in a private folder (only your account can connect, and Pairbar checks that the sender is you); if Pairbar isn't running, it's dropped, never saved. Nothing goes over the network. Pairbar keeps it in memory only, uses it for the chat's status, and never runs, opens or follows anything in it.
Live status for Codex (hooks)#
Off until you install it (Settings → Integrations), and then only once you've trusted Pairbar's hooks in Codex (/hooks). Codex runs ~/.pairbar/bin/pairbar codex-hook <event> (a link to the helper inside Pairbar) on each hook event, and the helper passes Pairbar only:
- the chat's thread id, folder (
cwd) and rollout path; - the event's name (
PermissionRequest,Stop…), and a helper thread's id and type; - the tool's name and a short summary (a command's program and subcommand, the names of the files a patch touches, a URL's host);
- whether a Stop hook is continuing, a session's start source;
- the helper's parent process id and the time.
Your prompts, commands in full, patches, tools' outputs, Codex's replies and anything else in the event are dropped by the helper before anything leaves it. The rest is as for Claude: a private socket, dropped when Pairbar isn't running, never over the network, in memory only, never acted on. Pairbar doesn't use Codex's notify setting or the Codex app's private connection.
Installing it reads and edits Codex's config, which can hold secrets (an MCP server's API key in its env table). Pairbar appends its block without rewriting anything else, checks the result, and never logs, shows or sends the file's contents: a problem is reported by its line number only. The one copy it makes is the private backup above.
Pairbar's tools for Claude and Codex#
Off until you install them (Settings → Integrations; see the Integrations page of the docs). Then a Claude or Codex chat can call Pairbar's tools, through the pairbar helper, over a Unix socket in a private folder (only your account can connect). Nothing goes over the network, and the helper never logs or passes on its environment (Claude's tools inherit its tokens): the only value it passes is CLAUDE_CODE_SESSION_ID, which Pairbar only compares with what it found itself.
What a chat can get from Pairbar:
- the chats and tasks of its own project as metadata: title, app, status, project, folder (as
~/…), branch, PR and its checks, when it last changed, the tool it's running, how many subagents run. Other projects' only when you turn on Agents can see chats in other projects; - what a chat is asking you, only when Include what the chat is asking is on (Settings → Notifications);
- skills (and a skill's instructions), your agents (their descriptions, tools and skills, not their instructions), workflows (title, schedule, folder, the most their steps may do, whether agents may run them, last run; never their prompts or replies), plan limits as percentages. A workflow run an agent started gives that agent each step's state and chat, and the start of each reply and the last step's reply, like a helper's.
Never a chat's messages or transcript, handoff files, cloud chats' content, your licence, your settings, or any config file's contents. Anything that looks like a key or token is masked in what the tools return.
Agent actions. A chat can also ask Pairbar to start a helper chat, get a second opinion or a review from the other app, or hand itself off. What it asks for runs only as your settings allow or after you approve it, and runs through your own claude or codex (see Network), on your plan: the helper gets the asking chat's brief, and for a review the diff Pairbar reads itself with git (or gh pr diff for a PR). The asking chat gets back only its own helpers' replies, when it asks for them. A handoff uses the same private handoff file as the chat menu's. Nothing is sent anywhere by Pairbar itself.
Every call is kept in the Activity list (above). If Pairbar isn't running when a chat calls, the helper opens it in the background (unless you turn Start Pairbar when an agent needs it off); it never queues anything for later.
On screen#
- Notifications show the app, the chat title and the project. What the chat is asking is only included if you turn that on.
- Screen Recording is optional and used only for the basket's animations and its stand-in while you drag it, and to find the message box under the dictation pill (see above). Pairbar never records your screen, captures only the two docked windows, the area around the basket and the bottom strip of Claude's or Codex's window, keeps only the latest pictures in memory (the strip not even that), and saves nothing.
- Screen sharing: Pairbar's windows show up in screenshots (Coming Soon) and recordings like any app. Turn on Hide Pairbar from screenshots (Coming Soon) and screen sharing (Settings → About & advanced) to keep the sidebar, quick search and the basket out of them (macOS window sharing type "none"). Some capture (Coming Soon) tools may not honour this.
- Shell commands are shown only as the program and its subcommand (for example "git push"), never with their arguments.
Contacting support#
Contact support… (Settings → About & advanced, the menu-bar icon's menu, or ⌘K: "Contact support" / "Report a problem") opens a small window that shows exactly what would go into an email to support@pairbar.com, before anything happens:
- Pairbar's version and build, the macOS version, the Claude and Codex desktop apps' versions (or "not installed"), and your plan (trial, Monthly, Yearly or Lifetime, and whether it's active). Never your licence key, your email or the Mac's activation name.
- Only if you tick Include diagnostics: the last 200 lines of Pairbar's debug log (
$TMPDIR/pairbar-debug.log, which exists only if the debug setting is on), each line cut to 300 characters, cleaned the same way as the Activity list (anything that looks like a key, token or password becomes[redacted], your home folder becomes~, any other user's folder/Users/…) and with quoted text longer than 40 characters, which could be part of a chat, replaced by"[text]".
Email support… opens a draft in your mail app with that text; Copy puts it on the clipboard. Pairbar sends nothing itself and writes no file: the draft goes nowhere until you send it from your mail app. The privacy policy (pairbar.com/legal/privacy) covers what happens to an email you send us.
Voice dictation#
- The microphone is on only while you dictate: from the press to Stop (letting go, the second press, Send, or Esc). The composer's mic turns into a meter and the pill on Claude's or Codex's message box shows that it's listening.
- Speech becomes text on this Mac with macOS's speech recognition. Your voice isn't uploaded, and no audio is kept unless you turn on Keep audio for 24 hours or Keep my last 20 recordings on this Mac to improve recognition.
- The words show in Pairbar's card while you speak. Into Claude's or Codex's message box they're typed, when you press Send or ✓ (insert), as key presses to that app only (Accessibility), with ⇧↩ between lines. Return is pressed only by Send, only into that app, and only while its message box has the cursor.
- Polish sends the dictation's text (never audio) to your own Claude or Codex. It's on to start with; turn it off in Settings → Voice → Polish.
Optional recognition recordings#
Keep my last 20 recordings on this Mac to improve recognition is off by default. When enabled, Pairbar stores 16 kHz mono WAV audio and JSON notes (Apple and Whisper transcripts, final text, vocabulary prompt, microphone name and recognition outcome) in ~/Library/Application Support/Pairbar/recordings. The directory is private (0700), files are readable only by you (0600). At most 20 recordings remain. Turning the option off or choosing Delete recordings removes them. Audio is never sent to Claude or Codex; Polish receives text and the vocabulary only.
Explicit thumbs-up/down ratings, saved word/phrase correction pairs and the original inserted text before a correction are stored in the private dictation history and follow its retention. Corrections are stored in the existing personal dictionary until you remove them in Voice settings; dictionary terms can be included in recognition hints and text sent to your chosen Polish provider. Ratings are not uploaded.
For vocabulary selection Pairbar reads installed app names and recent dictation text already in its local history. Microphone selection reads Core Audio input devices and their transport; it changes the dictation's input, not your system-wide default.
Clipboard#
Pairbar writes to the clipboard only when you choose a Copy action (the dictation card's Copy included), or when a dictation can't be typed where it was going (Accessibility off): then the text is copied and Pairbar says so. When you paste copied files into a prompt field, Pairbar reads only their file URLs from the clipboard to attach them. It does not read clipboard text in the background.
Prompt attachments#
Files dropped, pasted from Finder or picked with Attach files are stored as local paths in workflow steps and check-ins. Their paths are included with the prompt, so your Claude or Codex can read the files using its own tools. Pairbar does not upload or copy Finder file contents; a workflow step using Claude receives read access to their containing folders. Remove a file chip before sending or saving to exclude it.
Clipboard images are read only on an explicit paste in a focused prompt field and converted to private PNG files in ~/.pairbar/attachments/ (directory 0700, files 0600). They remain until you delete them; removing a chip does not delete the original evidence. There is no background clipboard monitoring. Workflow run input, startup answers with a snapshot of their question names, and attachment paths are saved with that run’s history and sent to its steps; they do not modify the saved workflow. Startup question definitions and any default answers are saved in the workflow. Unsaved launch answers stay in memory while Pairbar runs; they are not uploaded independently.
Notes and browser feedback (Coming Soon)#
Only after you choose Capture (Coming Soon), Pairbar captures one display into memory; the selected crop and comment are saved only when you choose Save. Its windows are excluded. Hover preview and single-click selection may read Accessibility position, size, role, subrole, title, identifier, description and explicitly selected static text from the underlying app when macOS permission is granted; it does not read input values. Source app, bundle ID and window title may accompany the crop. Without element geometry, Capture (Coming Soon) selects a clearly labeled window screenshot (Coming Soon). Text, note revisions, groups, image assets and immutable export packages are private local files under ~/.pairbar/notes/. Dictation uses the existing voice settings.
The optional Chromium extension reads explicitly selected elements and a viewport screenshot (Coming Soon), sending them through registered native messaging to the local browser-inbox/. Pairbar saves per-element crops and removes the queued capture (Coming Soon) after successful import. DOM (Coming Soon) attributes/styles/text, sanitized selected HTML, ancestor context, observed CSS custom properties and readable authored CSS rules are bounded; form values, cookies and browser storage are not collected. URLs omit credentials/query/fragment. Visible images/text may contain private data; review before transfer. Browser native-host registration files are read to explain setup status.
Copy for AI writes the exported Markdown brief and its local file URL to the clipboard only when you choose it. DOM (Coming Soon) evidence includes bounded identifying test attributes and selector diagnostics, an explicit role when present (or a basic tag-derived role), and a label from aria-label or captured visible text.
Send to chat prepares a message and file paths; it does not upload the library. Actual sending follows the selected Claude/Codex channel. Exported copies remain after original notes change. No automatic cloud sync or continuous screen capture (Coming Soon).
Native Notes DOM (Coming Soon) capture (Coming Soon) uses read-only JavaScript through Apple Events in explicitly connected Chrome, Brave, Edge, Chromium or Safari windows. macOS Automation permission and the browser’s Allow JavaScript from Apple Events setting are required. Pairbar does not enable developer settings, install an extension, open a debugging port or upload DOM (Coming Soon) evidence. While Capture (Coming Soon) is active, the reader checks the selected window and page/viewport identity and reads bounded element HTML, attributes, computed CSS and observed CSS variables. Form values and script content are omitted; URLs lose credentials, query and fragment in saved evidence. Visible page text and images may still be private. Firefox and embedded Codex/Claude WebViews do not have this native DOM (Coming Soon) bridge.
Per-step AI editing sends the selected step’s prompt and your requested change to your chosen Claude or Codex CLI. It uses the planner’s read-only tool policy in Pairbar’s private temporary folder, without passing the workflow repository or attachments. Its proposal and request remain in memory until applied or discarded; applying changes the unsaved draft only. Temporary schema and reply files are deleted after the request, as with planning.
Workflow planning keeps the last twelve successful durations per app in local preferences to estimate waiting time. These timing samples contain no prompts or replies and are not uploaded. The current activity list stays in memory with the unsaved planner.
Workflows can explicitly enable or disable Codex command-step network access. Enabled lets shell commands contact online services using your existing tool authentication; Pairbar does not copy GitHub tokens. The file sandbox and publication approval steps stay in force. Existing workflows inherit Codex settings unless you choose a network policy.
Codex workflow planning, AI step editing and doctor helpers use --ephemeral, so the CLI does not persist their session files. Claude helper transcripts are retained for live progress; Pairbar records their known session IDs in its local hidden-chat metadata and hides them from its chat list, including imported desktop aliases. No chat title is used to infer helper ownership. Workflow step chats keep their normal history.
Release availability#
The app bundles a copy of its build-time feature catalog in its own resources. Distribution availability is compiled into the app; no user setting, environment variable or remote request can enable an unfinished feature. Disabled features do not delete previously saved data. This catalog contains no personal information.
Changes to this document
- Version 2.1, 2026-10-01: The launch list: an address left in an "Email me at launch" form, used once for the launch email, on consent.
- Version 2.0, 2026-10-01: A full policy: who handles your data (Lemon Squeezy, Vercel, Neon, Resend, Cloudflare), retention, your rights, the website; contacting support from the app. The app's technical detail follows it.
- Version 1.0, 2026-09-29: What the app reads, stores and sends.
Plain-language text written for a small independent product. It doesn’t limit your rights under the consumer law where you live.