Reference: Settings Fields
Every settings field with its exact name, type, default, and effect — useful for reading or writing the JSON directly. Source of truth:
App/Sources/Features/Settings/Models/GlobalSettings.swiftandRepositorySettings.swift.
Keywords:settings fieldsglobal settingsrepository settingsdefaultssettings.jsonprowl.jsonconfigjson schema
For the UI grouping of these into tabs, see components/settings.md.
On-disk locations#
| Scope | Path |
|---|---|
| Global settings | ~/.prowl/settings.json |
| Global custom commands + agent profiles + workflows | ~/.prowl/global.user.json |
| Per-repository settings | ~/.prowl/repo/<repo-name>-<hash>/prowl.json |
| Per-repository custom commands + agent-profile memory | ~/.prowl/repo/<repo-name>-<hash>/prowl.user.json |
JSON is pretty-printed with sorted keys. <hash> is the first 8 hex digits of the
SHA-256 of the repository path (trailing slash removed). Files in the per-name
directory of earlier versions (~/.prowl/repo/<repo-name>/) are copied on first
load and never deleted; icons there are read in place. Legacy ~/.supacode is
migrated to ~/.prowl on first launch.
User settings migration#
When a new user settings path is absent, Prowl reads an earlier file and creates the new path from it; the old file is not deleted. If both exist, the new path wins.
- Global:
global.onevcat.jsonin~/.prowl/. - Repository user settings: from the per-name directory of earlier versions,
~/.prowl/repo/<repo-name>/, in this order:prowl.user.json,prowl.onevcat.json,supacode.onevcat.json. A file placed in the new<repo-name>-<hash>/directory under an old name is not read.
For these two user settings files, migration preserves the original JSON bytes. New
regular files are owner-only (0600). A legacy symlink produces a new symlink to the
same resolved target, so dotfiles-backed settings stay connected. A damaged,
unreadable, or dangling configuration stops loading and saving; Prowl does not replace
it with defaults or recover from an older file silently. To recover, quit Prowl, back
up the files, repair the JSON, permissions, or link target, then restart. Read and
migration failures are recorded in the Settings log.
Repository settings migration#
Repository settings (prowl.json) follow a looser policy. When
~/.prowl/repo/<repo-name>-<hash>/prowl.json is absent or cannot be decoded, Prowl
reads prowl.json, then supacode.json, from the per-name directory of earlier
versions, then the repository’s entry in settings.json. A legacy file is re-encoded
into the new path (a symlink stays a link to the same target), so a damaged new
prowl.json is replaced by the older settings when a legacy file exists. Back up
the new file before you repair it by hand.
Old regular files are migration-time snapshots, not synchronized backups. Downgrading to an older Prowl version does not carry later changes back to those files. Symlink-backed old and new paths share one target instead. Legacy reads have no scheduled removal date.
Global settings (GlobalSettings)#
| Field | Type | Default | Effect |
|---|---|---|---|
appearanceMode | enum (system/light/dark) | dark | App appearance. |
defaultEditorID | String | auto | Default app to open worktrees (overridable per repo); auto prefers an app matching the detected project type. |
confirmBeforeQuit | Bool | true | Confirm before quitting Prowl. |
updatesAutomaticallyCheckForUpdates | Bool | true | Background update checks. |
updatesAutomaticallyDownloadUpdates | Bool | false | Auto-download updates. |
inAppNotificationsEnabled | Bool | true | In-app alerts / bell indicators. |
notificationSound | enum (never / system sound raw values like hero / supacodeClassic) | supacodeClassic | Sound played for notifications when system banners are off; never disables it. Migrates the legacy notificationSoundEnabled Bool (true → supacodeClassic, false → never); unknown raw values fall back to the default. |
systemNotificationsEnabled | Bool | false | macOS system banners. |
muteNotificationsForActiveSurface | Bool | true | Suppress the banner, sound, and dock bounce when the notification’s pane is the one you’re actively viewing (selected worktree, focused pane, key + visible window). Workflow status-edge notices use selected-worktree visibility because their status is worktree-level. |
moveNotifiedWorktreeToTop | Bool | true | Float a notified worktree to top. |
commandFinishedNotificationEnabled | Bool | true | Notify when a long command finishes. |
commandFinishedNotificationThreshold | Int (seconds) | 10 | Minimum duration before that notification fires. |
analyticsEnabled | Bool | true | Send usage analytics (PostHog; off in Debug). |
crashReportsEnabled | Bool | true | Send crash reports (Sentry). |
githubIntegrationEnabled | Bool | true | Enable GitHub/PR features (via gh). |
deleteBranchOnAutomaticCleanup | Bool | false | Delete the local branch when automatic cleanup (merged-PR delete action, archived auto-delete) removes a Prowl-created worktree. Migrates the legacy deleteBranchOnDeleteWorktree key. The manual delete dialog is independent: it remembers the last confirmed choice in UserDefaults (deleteBranchOnManualWorktreeDelete). |
mergedWorktreeAction | enum? | nil | What to do with a merged worktree (e.g. auto-archive); nil = ask. |
promptForWorktreeCreation | Bool | true | Show the creation dialog vs. auto-create. |
fetchOriginBeforeWorktreeCreation | Bool | true | git fetch before creating a worktree. |
defaultWorktreeBaseDirectoryPath | String? | nil | Default parent directory for new worktrees. |
copyIgnoredOnWorktreeCreate | Bool | false | Copy .gitignore’d files into new worktrees. |
copyUntrackedOnWorktreeCreate | Bool | false | Copy untracked files into new worktrees. |
pullRequestMergeStrategy | enum (merge/squash/rebase) | merge | Default PR merge strategy. |
restoreTerminalLayout | Bool | true | Restore tabs/splits on launch. Replaces restoreTerminalLayoutOnLaunch: Prowl ignores the old field, so the setting turns on once for every existing settings file. |
terminalFontSize | Float32? | nil | Remembered terminal font size; nil follows Ghostty’s font-size. A size equal to Ghostty’s font-size is stored as nil, also at launch. |
ghosttyConfigPath | String? | nil | Dedicated Ghostty config file for Prowl; replaces Ghostty’s own config files. nil = share Ghostty’s config. |
archivedAutoDeletePeriod | enum? (days) | nil | Auto-delete archived worktrees after N days; nil = never. |
keybindingUserOverrides | object | empty | User keyboard-shortcut remappings. |
defaultViewMode | enum (normal/shelf/canvas) | normal | View mode on launch. |
canvasDefaultLayout | enum (uniform/tile) | tile | Layout a fresh Canvas starts in: uniform packs same-size cards (Arrange), tile resizes cards to fill the screen. Canvas then keeps the layout you last chose. |
dimUnfocusedSplits | Bool | true | Dim panes that aren’t focused. |
autoShowActiveAgentsPanel | Bool | false | Auto-open the Active Agents panel on a new agent. |
showActiveAgentTabTitles | Bool | false | Show pane titles (surface title, falling back to the tab title; vs. branch) in the agents panel. |
showActiveAgentNames | Bool | true | Show the agent name before the repository name in agents panel rows; when off, the name moves to the row’s tooltip. Agent Island is not affected. |
showActiveAgentStatusInShelf | Bool | true | Show agent status markers on Shelf tab icons. |
agentIslandSilentOpacity | Double | 0.35 | Quiet floating island opacity (0.2–1.0), under Agents → Display. Notched monitors stay fully opaque. |
agentIslandEnabled | Bool | false | Show Agent Island, including its empty state unless agentIslandOnlyShowWithAgents is enabled. |
agentIslandOnlyShowWithAgents | Bool | false | Hide Agent Island when the Active Agents roster is empty. |
agentIslandFloatingPositions | object ({"positionsByDisplayID":{}}) | Empty positions | Saved horizontal positions per display UUID (0–1); absent entries use the center. Applies to displays without a notch. |
agentIslandDisplayPreference | object ({"mode":"automatic"} or {"mode":"display","id":"<CG display UUID>","name":"<last known name>"}) | {"mode":"automatic"} | Select Agent Island placement. A missing fixed display temporarily follows Automatic while preserving its UUID for reconnection. |
windowTintMode | enum (none/repositoryColor/custom) | repositoryColor | How the window chrome is tinted. |
windowTintCustomColor | color | default | The custom tint color (when windowTintMode = custom). |
showRunButtonInToolbar | Bool | true | Show the Run Script button in the toolbar. |
showDefaultEditorInToolbar | Bool | true | Show the open-in-editor button in the toolbar. |
dockBounceMode | enum (off/once/continuous) | off | Dock bounce on notification. |
showNotificationDotOnDock | Bool | false | Numeric unread badge on the Dock icon. |
shelfSpineTintFallback | enum (neutral/systemTint) | neutral | Shelf spine color when a repo has no color. |
shelfSpineTintFollowsRepositoryColor | Bool | true | Tint shelf spines by repo color. |
externalDiffToolID | String | built-in | Tool used by diff badges and Show Diff: built-in, hunk, filemerge, kaleidoscope, or custom. |
externalDiffCustomCommand | String | "" | Command template for externalDiffToolID = custom; supports {leftPath}, {rightPath}, {worktreePath}, {repoPath}, and {branch}. |
detectRepositoryIconsAutomatically | Bool | true | Scan newly added repositories locally for a high-confidence project icon (app icon, launcher, favicon/logo) and use it as the repo icon. Applies to future additions only; never replaces a manual icon. |
Per-repository settings (RepositorySettings)#
Stored at ~/.prowl/repo/<repo-name>-<hash>/prowl.json (schema v2). For the tri-state
Bool? fields, nil means “inherit the global setting.”
| Field | Type | Default | Effect |
|---|---|---|---|
setupScript | String | "" | Script run automatically after a worktree is created. |
archiveScript | String | "" | Script run automatically before a worktree is archived. |
runScript | String | "" | The on-demand Run Script (⌘R). |
openActionID | String | auto | App to open this repo’s worktrees (overrides defaultEditorID); auto prefers an app matching the detected project type. |
worktreeBaseRef | String? | nil | Default base branch/ref for new worktrees. |
worktreeBaseDirectoryPath | String? | nil | Parent directory for new worktrees (overrides global). |
copyIgnoredOnWorktreeCreate | Bool? | nil | Copy ignored files; nil = use global. |
copyUntrackedOnWorktreeCreate | Bool? | nil | Copy untracked files; nil = use global. |
pullRequestMergeStrategy | enum? | nil | PR merge strategy; nil = use global. |
githubAccountOverride | object? | nil | Optional { "host": "...", "login": "..." }; Prowl temporarily switches gh to this account for GitHub operations in this repo. |
customTitle | String? | nil | Display name override for the repository. |
observeLineDiffsAutomatically | Bool? | nil (= on) | Keep worktree line-change badges updated; set false for large repos. |
fetchPullRequestState | Bool? | nil (= on) | Background-fetch PR state; set false to save GitHub rate limit. |
Custom Commands live separately in prowl.user.json. Each command has an
isEnabled Boolean that defaults to true; turning it off preserves its structure
(title, icon, command, execution mode, close-on-success, shortcut, and order) but
removes it from every command surface and hotkey dispatch.
Global Custom Commands use the same command structure in
~/.prowl/global.user.json. Repository prowl.user.json files additionally
store disabledGlobalCommandIDs: an absent ID means enabled for that repository, while
an included ID hides that Global command there. Local commands are ordered before Global
commands; matching titles do not hide either command.
Agent Profiles share these files: global.user.json also stores the
agentProfiles array and the one-shot didSeedAgentProfiles flag, and each
repository’s prowl.user.json stores defaultAgentProfileID (the explicit
per-repo Default Agent Profile) and lastLaunchedAgentProfileID (launch
memory for the Recommended resolution). See
components/agent-profiles.md.
Workflows also persist in global.user.json: disabledWorkflowIDs
(bundle/<id>, user/<id>, or repo:<canonical root>/<id> keys of workflow definitions switched off — the Enabled control in
Workflow Settings), workflowBindModeOverrides ({workflow_key, mode} entries, mode ask | auto; absent = follow the file’s bind — the
detail’s Run Setup picker and the start sheet’s “Don’t ask again”), and
workflowBindings (remembered launch-role Profile bindings, one per
requirements digest — the page’s per-role pickers, or a start that resolved
the role). Prefer the page over editing them by hand. See
components/workflows.md.
Notes for agents#
- Defaults here are the factory values; a human’s file may differ.
- Tri-state
Bool?per-repo fields:nil/absent = inherit global;true/false= explicit override. - Editing the JSON while Prowl is running may be overwritten on save — prefer the Settings UI, or change settings while the app is closed.
- The application language is not in
settings.json. Settings → General → Language reads and writes the per-appAppleLanguagesdefault (defaults read com.onevcat.prowl AppleLanguages), the same key as System Settings → Language & Region → Applications. No key means “follow the system”. A change takes effect on the next launch.