Settings Fields

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.swift and RepositorySettings.swift.

Keywords:settings fieldsglobal settingsrepository settingsdefaultssettings.jsonprowl.jsonconfigjson schema

For the UI grouping of these into tabs, see components/settings.md.

On-disk locations#

ScopePath
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.json in ~/.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)#

FieldTypeDefaultEffect
appearanceModeenum (system/light/dark)darkApp appearance.
defaultEditorIDStringautoDefault app to open worktrees (overridable per repo); auto prefers an app matching the detected project type.
confirmBeforeQuitBooltrueConfirm before quitting Prowl.
updatesAutomaticallyCheckForUpdatesBooltrueBackground update checks.
updatesAutomaticallyDownloadUpdatesBoolfalseAuto-download updates.
inAppNotificationsEnabledBooltrueIn-app alerts / bell indicators.
notificationSoundenum (never / system sound raw values like hero / supacodeClassic)supacodeClassicSound 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.
systemNotificationsEnabledBoolfalsemacOS system banners.
muteNotificationsForActiveSurfaceBooltrueSuppress 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.
moveNotifiedWorktreeToTopBooltrueFloat a notified worktree to top.
commandFinishedNotificationEnabledBooltrueNotify when a long command finishes.
commandFinishedNotificationThresholdInt (seconds)10Minimum duration before that notification fires.
analyticsEnabledBooltrueSend usage analytics (PostHog; off in Debug).
crashReportsEnabledBooltrueSend crash reports (Sentry).
githubIntegrationEnabledBooltrueEnable GitHub/PR features (via gh).
deleteBranchOnAutomaticCleanupBoolfalseDelete 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).
mergedWorktreeActionenum?nilWhat to do with a merged worktree (e.g. auto-archive); nil = ask.
promptForWorktreeCreationBooltrueShow the creation dialog vs. auto-create.
fetchOriginBeforeWorktreeCreationBooltruegit fetch before creating a worktree.
defaultWorktreeBaseDirectoryPathString?nilDefault parent directory for new worktrees.
copyIgnoredOnWorktreeCreateBoolfalseCopy .gitignore’d files into new worktrees.
copyUntrackedOnWorktreeCreateBoolfalseCopy untracked files into new worktrees.
pullRequestMergeStrategyenum (merge/squash/rebase)mergeDefault PR merge strategy.
restoreTerminalLayoutBooltrueRestore tabs/splits on launch. Replaces restoreTerminalLayoutOnLaunch: Prowl ignores the old field, so the setting turns on once for every existing settings file.
terminalFontSizeFloat32?nilRemembered terminal font size; nil follows Ghostty’s font-size. A size equal to Ghostty’s font-size is stored as nil, also at launch.
ghosttyConfigPathString?nilDedicated Ghostty config file for Prowl; replaces Ghostty’s own config files. nil = share Ghostty’s config.
archivedAutoDeletePeriodenum? (days)nilAuto-delete archived worktrees after N days; nil = never.
keybindingUserOverridesobjectemptyUser keyboard-shortcut remappings.
defaultViewModeenum (normal/shelf/canvas)normalView mode on launch.
canvasDefaultLayoutenum (uniform/tile)tileLayout 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.
dimUnfocusedSplitsBooltrueDim panes that aren’t focused.
autoShowActiveAgentsPanelBoolfalseAuto-open the Active Agents panel on a new agent.
showActiveAgentTabTitlesBoolfalseShow pane titles (surface title, falling back to the tab title; vs. branch) in the agents panel.
showActiveAgentNamesBooltrueShow 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.
showActiveAgentStatusInShelfBooltrueShow agent status markers on Shelf tab icons.
agentIslandSilentOpacityDouble0.35Quiet floating island opacity (0.2–1.0), under Agents → Display. Notched monitors stay fully opaque.
agentIslandEnabledBoolfalseShow Agent Island, including its empty state unless agentIslandOnlyShowWithAgents is enabled.
agentIslandOnlyShowWithAgentsBoolfalseHide Agent Island when the Active Agents roster is empty.
agentIslandFloatingPositionsobject ({"positionsByDisplayID":{}})Empty positionsSaved horizontal positions per display UUID (0–1); absent entries use the center. Applies to displays without a notch.
agentIslandDisplayPreferenceobject ({"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.
windowTintModeenum (none/repositoryColor/custom)repositoryColorHow the window chrome is tinted.
windowTintCustomColorcolordefaultThe custom tint color (when windowTintMode = custom).
showRunButtonInToolbarBooltrueShow the Run Script button in the toolbar.
showDefaultEditorInToolbarBooltrueShow the open-in-editor button in the toolbar.
dockBounceModeenum (off/once/continuous)offDock bounce on notification.
showNotificationDotOnDockBoolfalseNumeric unread badge on the Dock icon.
shelfSpineTintFallbackenum (neutral/systemTint)neutralShelf spine color when a repo has no color.
shelfSpineTintFollowsRepositoryColorBooltrueTint shelf spines by repo color.
externalDiffToolIDStringbuilt-inTool used by diff badges and Show Diff: built-in, hunk, filemerge, kaleidoscope, or custom.
externalDiffCustomCommandString""Command template for externalDiffToolID = custom; supports {leftPath}, {rightPath}, {worktreePath}, {repoPath}, and {branch}.
detectRepositoryIconsAutomaticallyBooltrueScan 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.”

FieldTypeDefaultEffect
setupScriptString""Script run automatically after a worktree is created.
archiveScriptString""Script run automatically before a worktree is archived.
runScriptString""The on-demand Run Script (⌘R).
openActionIDStringautoApp to open this repo’s worktrees (overrides defaultEditorID); auto prefers an app matching the detected project type.
worktreeBaseRefString?nilDefault base branch/ref for new worktrees.
worktreeBaseDirectoryPathString?nilParent directory for new worktrees (overrides global).
copyIgnoredOnWorktreeCreateBool?nilCopy ignored files; nil = use global.
copyUntrackedOnWorktreeCreateBool?nilCopy untracked files; nil = use global.
pullRequestMergeStrategyenum?nilPR merge strategy; nil = use global.
githubAccountOverrideobject?nilOptional { "host": "...", "login": "..." }; Prowl temporarily switches gh to this account for GitHub operations in this repo.
customTitleString?nilDisplay name override for the repository.
observeLineDiffsAutomaticallyBool?nil (= on)Keep worktree line-change badges updated; set false for large repos.
fetchPullRequestStateBool?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-app AppleLanguages default (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.