- fix(new-workspace): clean up backgrounds, contrast, and loading UX
Address feedback on the NewWorkspacePage: drop the LightRays backdrop, repo
badge-color radial gradient, and custom dark bg override so the page uses
standard bg-background. Switch card surfaces from translucent bg-background/X
to bg-muted/50 so cards read as distinct from the page in both themes. Give
the unselected source toggles a visible bg+border. Size the task list card to
its content (capped at viewport) instead of always stretching. Add a 3-row
shimmer skeleton while the initial fetch is in flight (only when nothing is
cached).
* fix: correct IME candidate window position when typing Japanese in terminal
Two fixes for the IME candidate window appearing offset from the cursor:
1. CSS: Add \left: 0\ to \.xterm .xterm-helpers\ in terminal.css.
xterm.css sets position:absolute;top:0 but omits left, leaving
left:auto. In Electron's Blink this can resolve to a non-zero value
and shift the IME window away from the cursor.
2. JS: Add a capture-phase compositionstart listener in openTerminal().
xterm.js repositions the textarea on compositionupdate but not on
compositionstart. The OS reads the textarea's screen rect at
compositionstart to place the IME candidate window, so the window
can appear at a stale position. The listener force-syncs the textarea
to the exact cursor pixel position before the OS opens the window.
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
* fix: remove compositionstart listener on pane disposal to prevent memory leak
Store the handler reference in ManagedPaneInternal.compositionHandler so
disposePane() can call removeEventListener with the exact same function
reference, preventing the closure from holding the terminal alive after
the pane is closed.
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
* refactor(terminal): derive IME cell dimensions from public xterm API
Computes cell width/height from the .xterm-screen element's bounding
rect and uses terminal.textarea (public) instead of reaching into
terminal._core. Avoids the `any`-cast access to xterm internals so
future xterm.js upgrades don't silently regress the IME position fix.
---------
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Co-authored-by: Neil <4138956+nwparker@users.noreply.github.com>
* 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>
* fix: guard Enter submit against IME composition in workflow creation popup
Pressing Enter during Japanese IME conversion was triggering workflow
submission instead of only confirming the candidate. Extract
shouldSuppressEnterSubmit() and check event.isComposing before submit
in NewWorkspaceComposerModal, NewWorkspacePage, and the task search
handler. Fixes#742.
* fix: use nativeEvent.isComposing for React SyntheticEvent in task search handler
* refactor: move new-workspace-enter-guard to src/renderer/src/lib
---------
Co-authored-by: Neil <4138956+nwparker@users.noreply.github.com>
Rich markdown links open on Cmd/Ctrl-click (plain click must place the
caret inside contenteditable). Toggle a root class on keydown/keyup of
the platform modifier so the pointer cursor appears only while the
modifier is held, matching VS Code's link affordance.
- style: update markdown preview cursor styles for link interactions
- feat(editor): open in-worktree .md links as preview edit tabs
Cmd/Ctrl-click on a markdown link now routes through a shared classifier
and dispatcher. Links resolving to .md files inside the active worktree
open as preview tabs; external URLs and non-markdown files delegate to
the OS handler. Cmd/Ctrl+Shift-click is preserved as the OS escape hatch
with existence precheck and a toast for dangling targets.
Supports #L10 / #L10C5 and trailing :line:col anchors by flipping the
target to source view before reveal. Preview replacement is scoped to
the active tab group, and evicted previews are pushed onto the
recently-closed stack so Cmd/Ctrl+Shift+T restores them.
Add visually-hidden DialogTitle and DialogDescription to
NewWorkspaceComposerModal and ImageViewer to satisfy Radix UI's
accessibility requirements for screen readers.
Remove duplicate 'copilot' entry in AGENT_CATALOG that caused
React's "two children with the same key" warning.
The defaultBaseRef resolver is repo-scoped, not worktree-scoped. Resetting
it to 'origin/main' on every worktree switch within the same repo clobbered
the correct value (e.g. 'origin/master'), causing persistent 'Branch compare
unavailable' errors.
The Cmd+P dialog's first result sometimes appeared flush against (or
behind) the input's bottom border. cmdk moves selection to the first
result on query change but never resets the list's scrollTop, and the
list had no padding buffer between the input border and the first item.
- reset scrollTop on query/visible change (mirrors WorktreeJumpPalette)
- add p-2 padding so the selection highlight never touches the border
Chromium's native PDF <embed> captures pointer events internally, so
mouseup never reaches the window and the sidebar keeps following the
cursor. Mount a transparent full-viewport overlay during drag so events
propagate to the window listeners.
* feat(editor): preserve Cmd+B for bold in markdown editor
Carve out bare Cmd/Ctrl+B from the main-process before-input-event
interceptor when the TipTap markdown editor is focused, so its bold
keymap can run instead of toggling the left sidebar. Focus state is
mirrored from renderer to main via a one-way IPC send, with default-deny
resets on crash/navigate/destroy and sender validation so only the main
window's webContents can mutate the flag.
* fix: add oxlint max-lines disable to createMainWindow.ts
Reattaching to a session where kill() has been called but the subprocess hasn't
exited yet races the in-flight exit. Treat terminating sessions the same as
fully-exited ones in createOrAttach, and have Session.dispose() force-kill a
stuck subprocess and notify attached clients so we don't leak the process when
the killTimer is cleared mid-flight.
Split actions from the tab context menu used copyUnifiedTabToGroup for editors
and spawned a fresh browser tab, so splitting produced two copies of the same
file/URL rather than moving the active tab into the new pane. Delegate to
dropUnifiedTab to share the drag-to-split move path; keep the new-terminal
behavior for single-tab terminal groups since moving the only tab would
collapse the split.
Split the "new workspace" and "tasks" entry points: the Plus button and Cmd/Ctrl+N
now open the lightweight composer modal, while the Tasks page is reached via a
dedicated Codex-style button above the Workspaces header in the sidebar.
- Add SidebarNav with a Tasks button (GH + Linear icons on the right)
- NewWorkspacePage becomes a pure tasks list (drops embedded composer card)
- Landing, AddRepoDialog, WorktreeList, SidebarHeader, App shortcut all switched
to openModal('new-workspace-composer')
- Normalize SidebarHeader row height so it matches the Tasks button above
The packaged Mac build loads the renderer from file://, which makes a
cross-origin POST via renderer fetch() fail CORS preflight — causing
"Failed to submit feedback" in production while dev (http://localhost)
works. Route submission through a new feedback:submit IPC handler that
uses Electron's net.fetch in the main process (no CORS), mirroring the
pattern already used by updater-changelog/updater-nudge.
Files dropped onto the new-workspace composer (modal or full page) are
appended as attachment chips; folders are inserted inline at the textarea
caret with shell-style quoting so users can reference working directories
from the OS file browser without leaving the prompt.
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.
- Move browser-related settings out of the in-browser gear dialog and
out of General into a dedicated Browser pane in Settings, and route
the browser gear button to open it.
- fix: prevent Escape-cancelled rename from committing via trailing blur
Users can now double-click a filename in editor tabs or the file explorer to rename it inline. Both flows share a common renameFileOnDisk() function that handles:
- Quiescing in-flight autosaves before rename to prevent recreating old paths
- Remapping all open editor tabs to the renamed file/directory
- Undo/redo support via the file explorer undo stack
The shared Escape-cancel logic prevents a race condition where blur could fire and commit the rename after user cancelled with Escape.