mirror of
https://github.com/stablyai/orca.git
synced 2026-10-09 00:02:39 +00:00
* fix(terminal): drop FORCE_HYPERLINK=1 from PTY spawn env FORCE_HYPERLINK=1 was set on every local PTY. It is read by oh-my-zsh's supports_hyperlinks(), the Rust supports-hyperlinks crate, GNU coreutils, and other tooling — so forcing it on makes every subprocess invoked during shell init take extra branches and emit OSC-8 escapes. Reproduced locally with a heavy zshrc (oh-my-zsh + p10k + nvm + pyenv): time-to-prompt jumps from ~600 ms without the variable to ~2000 ms with it (3.2×) on a clean sandbox. Stacked with the user-reported configuration (conda init, gcloud completions, compaudit over Homebrew paths, corporate network calls) that multiplier applied to a long serial chain of forks can stretch into "terminal is effectively never ready." xterm still renders OSC-8 hyperlinks when tools emit them on their own detection, so link support in Orca is preserved. VS Code does not set this variable either. * feat(terminal): make FORCE_HYPERLINK opt-out via settings, default on The previous commit on this branch removed FORCE_HYPERLINK=1 from PTY spawn env entirely. Revise: keep the historical default (on) so existing users don't silently lose OSC-8 hyperlink emission from tooling that checks this flag, but expose a toggle in Settings → Terminal → Advanced so users with heavy rc files (oh-my-zsh + powerlevel10k + nvm + pyenv + conda, etc.) can turn it off and reclaim the shell-startup time that the extra subprocess branching and escape emission was costing them. - Add `terminalForceHyperlink: boolean` to GlobalSettings (default true) - LocalPtyProvider gains an `isForceHyperlinkEnabled` hook; IPC wires it from the live settings snapshot - New SearchableSetting row in TerminalPane with zshrc-adjacent search keywords so users troubleshooting slow startup find it - Unit tests cover both default-on and opt-out paths
226 lines
7.4 KiB
TypeScript
226 lines
7.4 KiB
TypeScript
import type {
|
|
GlobalSettings,
|
|
NotificationSettings,
|
|
PersistedState,
|
|
PersistedUIState,
|
|
RepoHookSettings,
|
|
StatusBarItem,
|
|
WorkspaceSessionState,
|
|
WorktreeCardProperty
|
|
} from './types'
|
|
import { DEFAULT_TERMINAL_FONT_WEIGHT } from './terminal-fonts'
|
|
|
|
export const SCHEMA_VERSION = 1
|
|
export const ORCA_BROWSER_PARTITION = 'persist:orca-browser'
|
|
// Why: blank browser tabs must start from an inert guest URL that does not
|
|
// navigate the privileged main window to about:blank. Renderer and main both
|
|
// need the exact same value so the attach policy can allow only this one safe
|
|
// data URL while still rejecting arbitrary renderer-provided data URLs.
|
|
export const ORCA_BROWSER_BLANK_URL = 'data:text/html,'
|
|
|
|
export const BROWSER_FAMILY_LABELS: Record<string, string> = {
|
|
chrome: 'Google Chrome',
|
|
chromium: 'Chromium',
|
|
arc: 'Arc',
|
|
edge: 'Microsoft Edge',
|
|
brave: 'Brave',
|
|
firefox: 'Firefox',
|
|
safari: 'Safari',
|
|
manual: 'File'
|
|
}
|
|
|
|
// Pick a default terminal font that is likely to exist on the current OS.
|
|
// buildFontFamily() adds the full cross-platform fallback chain, so this only
|
|
// affects what users see in Settings as the initial value.
|
|
function defaultTerminalFontFamily(): string {
|
|
const platform = typeof process !== 'undefined' ? process.platform : ''
|
|
if (platform === 'win32') {
|
|
return 'Cascadia Mono'
|
|
}
|
|
if (platform === 'linux') {
|
|
return 'DejaVu Sans Mono'
|
|
}
|
|
return 'SF Mono' // macOS default
|
|
}
|
|
/**
|
|
* Why: ProseMirror builds an in-memory tree for the entire document, so large
|
|
* markdown files cause noticeable typing lag in the rich editor. Files above
|
|
* this threshold fall back to source mode (Monaco) which handles large files
|
|
* efficiently via virtualized line rendering.
|
|
*/
|
|
export const RICH_MARKDOWN_MAX_SIZE_BYTES = 300 * 1024
|
|
|
|
export const DEFAULT_EDITOR_AUTO_SAVE_DELAY_MS = 1000
|
|
export const MIN_EDITOR_AUTO_SAVE_DELAY_MS = 250
|
|
export const MAX_EDITOR_AUTO_SAVE_DELAY_MS = 10_000
|
|
|
|
// Why: initial threshold of agents spawned (since last update) before we show
|
|
// the star-on-GitHub notification. Doubles each time the user dismisses
|
|
// without starring — e.g. 50 → 100 → 200 → 400. Past dismissals are encoded
|
|
// in starNagNextThreshold, so this constant is only the first-time seed.
|
|
export const STAR_NAG_INITIAL_THRESHOLD = 50
|
|
|
|
export const DEFAULT_WORKTREE_CARD_PROPERTIES: WorktreeCardProperty[] = [
|
|
'status',
|
|
'unread',
|
|
'ci',
|
|
'issue',
|
|
'pr',
|
|
'comment'
|
|
]
|
|
|
|
export const DEFAULT_STATUS_BAR_ITEMS: StatusBarItem[] = ['claude', 'codex', 'ssh', 'sessions']
|
|
|
|
export const REPO_COLORS = [
|
|
'#737373', // neutral
|
|
'#ef4444', // red
|
|
'#f97316', // orange
|
|
'#eab308', // yellow
|
|
'#22c55e', // green
|
|
'#14b8a6', // teal
|
|
'#8b5cf6', // purple
|
|
'#ec4899' // pink
|
|
] as const
|
|
|
|
export function getDefaultNotificationSettings(): NotificationSettings {
|
|
return {
|
|
enabled: true,
|
|
agentTaskComplete: true,
|
|
terminalBell: false,
|
|
suppressWhenFocused: true
|
|
}
|
|
}
|
|
|
|
export function getDefaultSettings(homedir: string): GlobalSettings {
|
|
return {
|
|
workspaceDir: `${homedir}/orca/workspaces`,
|
|
nestWorkspaces: true,
|
|
refreshLocalBaseRefOnWorktreeCreate: false,
|
|
branchPrefix: 'git-username',
|
|
branchPrefixCustom: '',
|
|
theme: 'system',
|
|
editorAutoSave: false,
|
|
editorAutoSaveDelayMs: DEFAULT_EDITOR_AUTO_SAVE_DELAY_MS,
|
|
terminalFontSize: 14,
|
|
terminalFontFamily: defaultTerminalFontFamily(),
|
|
terminalFontWeight: DEFAULT_TERMINAL_FONT_WEIGHT,
|
|
terminalLineHeight: 1,
|
|
terminalCursorStyle: 'bar',
|
|
terminalCursorBlink: true,
|
|
terminalThemeDark: 'Ghostty Default Style Dark',
|
|
terminalDividerColorDark: '#3f3f46',
|
|
terminalUseSeparateLightTheme: false,
|
|
terminalThemeLight: 'Builtin Tango Light',
|
|
terminalDividerColorLight: '#d4d4d8',
|
|
terminalInactivePaneOpacity: 0.8,
|
|
terminalActivePaneOpacity: 1,
|
|
terminalPaneOpacityTransitionMs: 140,
|
|
terminalDividerThicknessPx: 3,
|
|
// Default true so Windows users get native right-click paste out of the
|
|
// box. Other platforms ignore this field because the UI never exposes it,
|
|
// and Ctrl+right-click still opens the context menu when paste is enabled.
|
|
terminalRightClickToPaste: true,
|
|
// Default false: opt-in only (matches Ghostty's default). Existing users
|
|
// on upgrade inherit this default via persistence.ts's
|
|
// { ...defaults.settings, ...parsed.settings } merge, so enabling
|
|
// focus-follows-mouse never happens unexpectedly.
|
|
terminalFocusFollowsMouse: false,
|
|
terminalClipboardOnSelect: false,
|
|
terminalAllowOsc52Clipboard: false,
|
|
setupScriptLaunchMode: 'new-tab',
|
|
terminalScrollbackBytes: 10_000_000,
|
|
openLinksInApp: true,
|
|
rightSidebarOpenByDefault: true,
|
|
showTitlebarAgentActivity: true,
|
|
notifications: getDefaultNotificationSettings(),
|
|
diffDefaultView: 'inline',
|
|
promptCacheTimerEnabled: false,
|
|
promptCacheTtlMs: 300_000,
|
|
codexManagedAccounts: [],
|
|
activeCodexManagedAccountId: null,
|
|
terminalScopeHistoryByWorktree: true,
|
|
defaultTuiAgent: null,
|
|
skipDeleteWorktreeConfirm: false,
|
|
defaultTaskViewPreset: 'all',
|
|
defaultRepoSelection: null,
|
|
agentCmdOverrides: {},
|
|
// Why: 'auto' runs a layout-aware probe at boot (see
|
|
// src/renderer/src/lib/keyboard-layout/*) that picks 'true' for US and
|
|
// US-International and 'false' for every other layout. This mirrors
|
|
// Ghostty's detectOptionAsAlt() and ensures users on Turkish, German,
|
|
// French, etc. can type Option+Q/L/E characters like @, €, [, ] out of
|
|
// the box (issue #903) while US users keep Option-as-Alt readline chords.
|
|
terminalMacOptionAsAlt: 'auto',
|
|
terminalMacOptionAsAltMigrated: false,
|
|
experimentalTerminalDaemon: false,
|
|
experimentalTerminalDaemonNoticeShown: false,
|
|
// Why: keep the historical default (on) so no existing user's terminal
|
|
// loses clickable-link emission on upgrade. Users with heavy zshrc setups
|
|
// can disable it from Settings → Terminal → Advanced to reclaim startup
|
|
// time.
|
|
terminalForceHyperlink: true
|
|
}
|
|
}
|
|
|
|
export function getDefaultRepoHookSettings(): RepoHookSettings {
|
|
return {
|
|
mode: 'auto',
|
|
setupRunPolicy: 'run-by-default',
|
|
scripts: {
|
|
setup: '',
|
|
archive: ''
|
|
}
|
|
}
|
|
}
|
|
|
|
export function getDefaultPersistedState(homedir: string): PersistedState {
|
|
return {
|
|
schemaVersion: SCHEMA_VERSION,
|
|
repos: [],
|
|
worktreeMeta: {},
|
|
settings: getDefaultSettings(homedir),
|
|
ui: getDefaultUIState(),
|
|
githubCache: { pr: {}, issue: {} },
|
|
workspaceSession: getDefaultWorkspaceSession(),
|
|
sshTargets: []
|
|
}
|
|
}
|
|
|
|
export function getDefaultUIState(): PersistedUIState {
|
|
return {
|
|
lastActiveRepoId: null,
|
|
lastActiveWorktreeId: null,
|
|
sidebarWidth: 280,
|
|
rightSidebarWidth: 350,
|
|
groupBy: 'none',
|
|
sortBy: 'name',
|
|
showActiveOnly: false,
|
|
filterRepoIds: [],
|
|
collapsedGroups: [],
|
|
uiZoomLevel: 0,
|
|
editorFontZoomLevel: 0,
|
|
worktreeCardProperties: [...DEFAULT_WORKTREE_CARD_PROPERTIES],
|
|
statusBarItems: [...DEFAULT_STATUS_BAR_ITEMS],
|
|
statusBarVisible: true,
|
|
dismissedUpdateVersion: null,
|
|
lastUpdateCheckAt: null
|
|
}
|
|
}
|
|
|
|
export function getDefaultWorkspaceSession(): WorkspaceSessionState {
|
|
return {
|
|
activeRepoId: null,
|
|
activeWorktreeId: null,
|
|
activeTabId: null,
|
|
tabsByWorktree: {},
|
|
terminalLayoutsByTabId: {},
|
|
openFilesByWorktree: {},
|
|
browserTabsByWorktree: {},
|
|
browserPagesByWorkspace: {},
|
|
activeBrowserTabIdByWorktree: {},
|
|
activeFileIdByWorktree: {},
|
|
activeTabTypeByWorktree: {},
|
|
browserUrlHistory: []
|
|
}
|
|
}
|