{
  "$id": "https://rabbitty.app/schema/settings.json",
  "$schema": "http://json-schema.org/draft-07/schema#",
  "additionalProperties": false,
  "description": "User settings for Rabbitty (~/.config/rabbitty/settings.json).",
  "properties": {
    "$schema": {
      "description": "Path or URL of the schema this file is validated against.",
      "type": "string"
    },
    "activity_log": {
      "default": true,
      "description": "Dev builds only: record a complete local activity stream (actions, shell commands, focus, agent lifecycle) to the session dir for workflow mining. Never leaves your machine and never reaches product telemetry; compiled out of release builds. See docs/TELEMETRY.md.",
      "type": "boolean"
    },
    "font_family": {
      "default": "Menlo",
      "description": "Terminal grid font. Any installed font; Nerd Font glyphs always fall back so shell/ls/powerline icons render.",
      "type": "string"
    },
    "font_size": {
      "default": 14,
      "description": "Terminal grid font size, in points. Adjustable at runtime with ⌘+ / ⌘− (which persists here).",
      "type": "number"
    },
    "jira": {
      "default": true,
      "description": "Show the Jira panel (⌘⇧J): your active-sprint issues and everything assigned to you, read from the jira CLI (ankitpokhrel/jira-cli) you've configured with `jira init`. When off, the panel and its top-bar icon are hidden. Each task has a button to hand it to the pane's agent to plan, and a copy-link button. Toggle from the command palette: `Jira: Enable / Disable`.",
      "type": "boolean"
    },
    "max_columns": {
      "default": 0,
      "description": "Widest the terminal grid may run, in columns. 0 (the default) always fills the pane. Set a count (e.g. 120) to cap an agent transcript's line length at a readable measure — full-width prose wraps at 180+ characters — with the grid centered between background gutters on a wider pane.",
      "type": "number"
    },
    "option_as_meta": {
      "default": false,
      "description": "Treat the macOS Option key as Meta (Esc-prefix) instead of composing accented characters — useful for Emacs-style bindings.",
      "type": "boolean"
    },
    "phone_link": {
      "default": false,
      "description": "Hold the phone link open while Rabbitty runs: your panes on your phone, with nothing to install on either end and no port opened on this Mac. Both ends dial out to rabbitty.app's relay and everything between them is sealed to a key the relay never sees. Pair a phone once by scanning a QR (⌘⇧P → 'Connect from your phone' → Pair a device); nothing that hasn't paired can read a byte. The card's button sets this for you.",
      "type": "boolean"
    },
    "pr_providers": {
      "default": "github, gitlab",
      "description": "Which providers the Pull Requests panel reads from, comma-separated. Each is queried across every host its CLI is signed into (enterprise and cloud alike). Toggle a provider from the panel's chips or the command palette. Allowed tokens: github, gitlab.",
      "type": "string"
    },
    "preferred_ide": {
      "default": "Zed",
      "description": "Which editor the top-bar Open button and ⌘O open the current terminal's folder in. Auto-detected from your installed apps (Zed preferred); falls back to Finder if none is found. Set it to any detected editor's name to override.",
      "type": "string"
    },
    "pull_requests": {
      "default": true,
      "description": "Show the Pull Requests panel (⌘⇧R): your open PRs/MRs and ones awaiting your review, read from the gh and glab CLIs you've already configured. When off, the panel and its top-bar icon are hidden. Toggle from the command palette: `Pull Requests: Enable / Disable`.",
      "type": "boolean"
    },
    "push_url": {
      "default": "",
      "description": "Webhook POSTed when an agent starts needing you, or finishes (an ntfy / Pushover URL). Off unless set. You don't poll a phone — you get pinged, then open the page. The body is deliberately thin: a count and the project name, never the worktree, the branch or what the agent asked. That text stays on your machine; the notification only tells you to go and read it.",
      "type": "string"
    },
    "serve_port": {
      "default": 8787,
      "description": "Port `rab serve` binds when you want the phone page on this Mac — for looking at it in a browser while you work on it. Bound to 127.0.0.1 only, and the app itself never opens it: the phone link needs no port at all. Named `phone_page_port` until the roads collapsed to one, when \"the phone page\" stopped meaning a thing you serve and started meaning the document your phone renders.",
      "type": "number"
    },
    "sound": {
      "default": true,
      "description": "Play an in-app chime when an agent finishes or needs you while Rabbitty is the active app.",
      "type": "boolean"
    },
    "status_source": {
      "default": "hook-then-scrape",
      "description": "How an agent's status is read: from its reported hooks, from on-screen scraping, or a combination.",
      "enum": [
        "hook-then-scrape",
        "scrape",
        "hooks",
        "scrape-then-hook"
      ],
      "type": "string"
    },
    "telemetry": {
      "default": true,
      "description": "Send anonymous telemetry events (app launch, agent startups, state transitions) to improve Rabbitty. Respects user privacy; no sensitive code or PII is sent.",
      "type": "boolean"
    },
    "theme": {
      "default": "One Light",
      "description": "UI + terminal color theme. Any bundled theme, or the name of a Ghostty theme file. All chrome derives from the terminal palette.",
      "enum": [
        "One Light",
        "GitHub Light",
        "Dark",
        "Catppuccin Latte",
        "Catppuccin Mocha"
      ],
      "type": "string"
    },
    "ui_font_family": {
      "default": ".SystemUIFont",
      "description": "Interface font for the chrome (sidebar, command palette, quick switcher, tabs). The terminal grid uses `font_family` instead.",
      "type": "string"
    },
    "worktree_carry": {
      "default": ".env,.env.*,.envrc,!.env.example,!.env.sample",
      "description": "Fallback carry list for repos with no .worktreeinclude file: gitignored files copied into a new worktree so it can run immediately. Comma/newline globs, !pattern excludes (.gitignore syntax). A repo's committed .worktreeinclude overrides this entirely — write one from the command palette with `worktree: configure carried files`.",
      "type": "string"
    },
    "worktree_dangerous": {
      "default": false,
      "description": "Launch the agent carried into a new worktree with its permission-bypass flag (Claude Code's --dangerously-skip-permissions and each agent's equivalent), so it works unattended. Toggle from the command palette: `worktree: toggle dangerous permissions`.",
      "type": "boolean"
    }
  },
  "title": "Rabbitty settings",
  "type": "object"
}