The checkbox button calls togglePathSelection() on click but does not stop
event propagation, so the click bubbles to the parent row's onClick which
calls executeRow() -> browseToEntry(). With a mouse, every checkbox click
would (a) toggle the selection, (b) navigate into the directory, and (c)
the navigation effect would clear selectedPaths. The primary interaction
of the multi-select feature was unusable.
The existing handleQuickAdd helper avoids this exact bug by calling
event.stopPropagation() inside its onClick handler. Apply the same
pattern to the new togglePathSelection onClick.
Refs openchamber-bot review on #2877.
Add a multi-select mode to the "Add project directory" dialog: each
directory row gets a select toggle (checkbox icon, Space toggles the
highlighted row), and the primary action becomes "Add selected" and
registers every selected directory in one store update. Selections apply
to the currently browsed directory and reset on navigation, dialog open,
and clone-mode entry. Clone mode keeps its single-target flow.
Add addProjects() to useProjectsStore: validates, normalizes, and dedups
paths (already-added or duplicated), creates entries in a single state
update and single persist, activates the first newly added project, and
discovers icons for each entry. Mirrors addProject semantics for the
single entry.
Refs OPE-142
"Restart to Update" answered the renderer with null before the install was
attempted, so a rejected install only reached main.log and the button looked
dead. The apply-update path now keeps the IPC call open until the app quits or
autoUpdater reports the failure, rolls the quit/install flags back when the app
stays up, and the update dialog shows the real reason with a translated hint for
a rejected code signature.
Also settle the download promise on downloadUpdate() itself: an already cached
payload emits no 'update-downloaded', which left that promise pending with its
listeners attached on every retry.
Post-merge hardening of the session-to-worktree move (#2998), driven by
review findings on the follow-up pass:
- an ambiguous transport failure (relay abort, timeout) on the
change-carrying move no longer force-deletes the fresh worktree that
may hold the user's only copy of their changes; both intent kinds
surface honest guidance and refresh both directories
- assertSdkSuccess re-tags ambiguous transport errors when wrapping SDK
failures, so ambiguity classification survives the wrapper on every
path, matching the prompt-send precedent
- session liveness checks scan all child stores plus the global status
index, and report unknown (not idle) when no store covers the session
— an evicted background directory can no longer make a busy session
look movable
- incomplete-rollback errors carry the changes-may-be-in-destination
guidance instead of swallowing it
- move-message assembly shared across the three call sites; tests now
exercise the real ambiguity classifier (extracted to
send-failure-classification.ts) instead of a hand-mirrored mock
- i18n fallout from the merge train: Turkish gains the 21 worktree-move
keys, all 12 locales get the hedged ambiguous-failure toast; owning
DOCUMENTATION.md files record the new contracts
Follow-ups promised on merge, plus review findings on the batch itself:
- chat: task-tool output now respects the 512KiB render cap; quick-open
icon is visible at rest on coarse pointers and reachable by keyboard
(row keydown no longer swallows inner-button Enter/Space); composer
inline-code decoration drops the metric-shifting padding; a btw fork
send carries only the boundary instruction, never the promotion notice
- sync: cascade revert/unrevert aborts busy descendants, busy state is
read from every child store at the moment of use; rule 9 documents
redo clearing all descendant revert markers
- electron: renderer recovery keeps memory-eviction (a valid
render-process-gone reason) and both windows share one
attachRendererRecovery helper
- vscode: process registry is a thin re-export of the web module
(provider-env-aliases precedent) with ordered register/unregister
writes and an awaited close
- server/cli: managed-process registry takes injectable deps (fixes the
unreaped-orphans ReferenceError), corrupt settings errors name the
file, getWorktrees test restores console.warn
- tests: module-mock harnesses removed (AgentsSidebar, SettingsView
mobile focus — behaviors stay live but uncovered, accepted trade),
QuestionMarkdown asserts rendered DOM
- i18n: German gains the debug-panel request keys, Japanese/German drop
removed worktree keys, Ukrainian unit spacing fixed
- changelog: Copilot AI Credits entries (main + VS Code)