* 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
xterm.js ships with no OSC 52 handler, so tmux, Neovim, fzf, and ripgrep
running inside Orca — locally or over SSH — silently fail to copy to the
system clipboard. Add an opt-in handler gated behind a new setting
`terminalAllowOsc52Clipboard` (default off because untrusted output
piped into the terminal can silently overwrite the clipboard).
Implementation mirrors the DEC 2031 wiring from PR #896: extract parsing
into a pure helper (parseOsc52) with a full unit-test suite, register
the handler in onPaneCreated and dispose it symmetrically in
onPaneClosed, and read the gate from settingsRef at fire time so the
toggle takes effect without recreating panes.
Clipboard *queries* (Pd = "?") are intentionally dropped — answering
them would leak the user's clipboard to any process writing to the
PTY — along with malformed payloads, oversized payloads (>128KB),
and payloads using unknown selection letters.
* feat: cross-repo issues view with multi-repo selection
- Add multi-repo selection via RepoMultiCombobox with persisted defaultRepoSelection setting (null = sticky-all)
- Stamp repoId on GitHubWorkItem at the renderer fetch boundary; merge items from all selected repos with per-repo failure tracking
- Extract task-query helpers (tokenize/strip/parseTaskQuery) to src/shared and add unit tests
- Refactor NewWorkspacePage row to <div role=button> to allow nested interactive elements without invalid-HTML hydration errors
- fix(repo-combobox): toggle all-repos selection on repeat click
* fix(tasks): route Use CTA to item's own repo in cross-repo view
handleUseWorkItem previously referenced a removed 'repoId' state; use item.repoId so launching from a merged cross-repo list targets the correct repo.
* test(e2e): add tasks page smoke test
* Refine workspace composer controls
* Working repo autofocus
* after selects
* Simplify workspace quick create dialog
* Refine quick create form focus flow
* autofocus fix
* normal dialog
* base dialogs
* Wire Use button to launch workspace directly
Skips the composer modal for the common case: creates the workspace,
activates it, launches the default agent, and pastes the work-item URL
into the agent's input as a reviewable draft. Falls back to the modal
when setupRunPolicy is 'ask' or no compatible agent is detected.
* Stretch combobox dropdowns to trigger width
Repository and Agent rows in the quick-create dialog now span the full
dialog width like the Workspace Name input, and their dropdown popovers
inherit the trigger width so the entries align edge-to-edge with the
trigger instead of clipping to a fixed 288/320px.
Ensures the new-workspace composer opens even when focus is inside a
contentEditable surface (markdown rich editor) or a browser-guest
webContents, both of which bypass the renderer's window-level keydown.
Adds an opt-in terminal setting that automatically copies the current
selection to the system clipboard as the user selects, mirroring X11 /
gnome-terminal behavior. xterm.js has no native option for this, so the
renderer hooks `onSelectionChange` per pane and writes via the existing
clipboard IPC. Defaults to false so existing users keep the explicit
Cmd/Ctrl+Shift+C copy flow.
Closes#860
* fix: persist sidebar collapsed groups across navigation and restart
The sidebar's collapsed-group state was stored as local React state in
WorktreeList, so the Sidebar unmount/remount triggered by navigating into
Settings discarded it — returning to the main view re-expanded every
previously collapsed group. Lift the state into the UI slice alongside
groupBy/sortBy/filterRepoIds and persist it via the existing ui:set IPC
so collapse state also survives app restarts.
* fix: clear collapsed groups when switching groupBy mode
Prevents stale keys from accumulating across mode switches and avoids
cross-mode key collisions that could leave groups unexpectedly collapsed.
---------
Co-authored-by: Jinwoo-H <jinwoo0825@gmail.com>
Change the default setupScriptLaunchMode from 'split-vertical' to
'new-tab' so setup output runs in a background Setup tab by default
instead of crowding the primary terminal pane. Users can still opt
back into split-vertical or split-horizontal in Terminal settings.
* feat: add Ghostty-style macOS Option key mode setting
Disable xterm's macOptionIsMeta by default so non-US keyboard layouts
can compose characters (e.g. @ on German, € on French). Add a
user-facing "Option as Alt" setting with four modes — Both, Left,
Right, Off — mirroring Ghostty's macos-option-as-alt. Core readline
shortcuts (Option+B/F/D) are automatically compensated when Option is
in compose mode. The setting applies live to existing terminal panes.
* fix: track Option key location from modifier keydown, not character key
KeyboardEvent.location on a character key (e.g. Period) reports that
key's own position (always 0), not which modifier is held. Left/right
Option mode was broken because we read location from the character
event. Fix by recording the Option key's location from its own
keydown/keyup events and passing it as a separate parameter.
Adds a Terminal settings control for where the repo setup script runs
on workspace create: vertical split (default, preserves prior behavior),
horizontal split, or a separate "Setup" tab that does not steal focus
from the primary terminal.
* New workspace page with agent catalog, composer modal, and terminal integration
* fix lint
* better blank state
* fix: resolve typecheck errors in new-workspace flow
- widen activateAndRevealWorktree's issueCommand to accept direct
command shape used by NewWorkspacePage, not just the main-process
runner-script variant
- use a ref object in pty-connection tests to dodge TS narrowing the
captured callback to never across the mock closure boundary
* fix: bound worktree name auto-suffix loop to prevent OOM in tests
The auto-suffix loop in createLocalWorktree had no termination cap.
When tests (or a misconfigured env) mocked getBranchConflictKind /
getPRForBranch to always return a collision, the loop ran forever and
the vitest worker crashed with "Ineffective mark-compacts near heap
limit".
Cap the search at 100 suffixes, and if all fail, fall back to the
original specific error messages (branch already exists / PR already
owns the name) instead of a generic failure.
Update the two tests that asserted the old throw-on-first-conflict
behavior to verify the new auto-suffix path end-to-end.
Unregister PTY data handlers before killing PTYs during worktree
shutdown so the final data flush cannot trigger bell/agent-status
notifications. Also cancels accumulated closure state (staleTitleTimer,
agent tracker) via teardown callbacks, and adds a hasLivePtys guard
at notification dispatch time as a belt-and-suspenders check.
* refactor: enable split groups
* Fix split groups terminal host rollout
* refactor: remove split groups from add-tab menu
* refactor: dark-launch split groups with correctness fixes