Skip to content

侧栏集成分支:门禁修复 + #3 健壮性安全 + #4 审查修复 + #5 性能 + #6 泄漏 - #2

Merged
RoxyAsahi merged 232 commits into
pr/side-pane-workbenchfrom
claude/project-thread-8tpfrr
Oct 7, 2026
Merged

RoxyAsahi merged 232 commits into
pr/side-pane-workbenchfrom
claude/project-thread-8tpfrr

Conversation

@RoxyAsahi

@RoxyAsahi RoxyAsahi commented Oct 7, 2026 •

Copy link
Copy Markdown
Owner

Requested by Roxy · project thread

Motivation

This branch gathers every fix for the side pane PR (lioensky#231), so Codex can bring them all into pr/side-pane-workbench with one merge. Each thread's PR comes in through a merge commit, and the branch is never force-pushed.

Changes

Source Merged up to Content
this branch + #4 0aa0295 The UI system gate passes: tool presentation styles are scoped with :where(.vcp-ui-scope), which adds no specificity, and the pinned-window button uses the accent token
#3 ca369fa Robustness, security and keyboard access: a tab whose view fails to mount shows an error and a retry; the side browser blocks file: pages; downloads need a real click; git never runs the repo's core.fsmonitor; the code viewer asks before reading a file outside the workspaces; the source IPC goes through the top-level window sender guard; tabs close with Delete and keep focus on the strip; tab ids holding Windows paths are matched safely
#4 0befa45 Review fixes: open/close animation, topic scope, dormancy quota; closing the side chat or plan asks before deleting; OSC 8 links (http(s) only); Ctrl+C with a selection copies; Git line counts and diffs follow later edits; command output is re-read once a second with one read in flight; a browser tab playing video is not put to sleep; closing several tabs at once no longer mounts the ones being closed; restoring side chats on a topic switch no longer forces the pane open; CI gains a test:side-pane step
#5 ea899c9 The code viewer renders big files in content-visibility chunks, so opening and switching back no longer slow down as line count grows; the page is no longer restyled on every DOM change; big assistants load as fast as on main
#6 31c0428 Leaks: the tooltip bridge uses a WeakMap and the turn navigator a WeakSet. In real Electron, opening and closing tabs leaves zero extra DOM nodes and listeners (before: 53–275 nodes per cycle)
this branch 2eb5587 Regenerates chat-event-graph.json after the merges

Where #3 and #4 overlap (findByTabId, tab strip focus), the branch keeps #3's implementation with #4's signature. In the browser, busy protection for media and captures comes from #4, and download handling from #3.

Testing

The description follows the structure of DSH's pull_request_template.md.

🤖 Generated with Claude Code

https://claude.ai/code/session_01UCGGgmHsCToooXTgSXpmq9

claude added 2 commits October 7, 2026 00:22
Code viewer tab ids carry the file path. On Windows the backslashes are
read as CSS escapes, so the selector never matched and keyboard focus
fell to <body> after cycling to, closing, or leaving the menu of such a
tab; a path containing a quote made the selector throw and the mount fail.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_016hW799u5Ji5k9khDAwu688
… literal colour

check:ui-system was red on the side pane branch. tool-presentation.css had
101 selectors outside .vcp-ui-scope, an !important on the reduced-motion
rule and two fixed 11px sizes; components.css (from upstream lioensky#234) fell back
to a hard-coded indigo because --vcp-ui-primary is not a token.

Every tool presentation selector now sits under .vcp-ui-scope (the chat
messages container already carries it, and the file is alone in its layer,
so the uniform specificity bump changes no cascade). The reduced-motion rule
reuses the shimmer selector instead of !important, the 11px sizes use
--vcp-ui-text-xs, and the pinned window button uses the accent token.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01UCGGgmHsCToooXTgSXpmq9
@RoxyAsahi RoxyAsahi self-assigned this Oct 7, 2026
claude added 2 commits October 7, 2026 00:24
Before, a provider that threw during mount (a corrupt restored payload,
a failed lazy import, a bug) left its tab selected over a blank pane,
with the error only in the console. The view now says the tab could not
open, shows the error, and offers a retry; showing the tab again still
retries as before, and closing the tab removes the error view.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_016hW799u5Ji5k9khDAwu688
…wn with it

initWorkspaceSidePane ran inside the main startup try block ahead of the
filter manager and setupEventListeners, so any exception while building
the side pane skipped the rest of startup and left the send button and
the other main window bindings dead. It now runs in its own try/catch
and reports the failure as a toast.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_016hW799u5Ji5k9khDAwu688
@RoxyAsahi RoxyAsahi changed the title UI 系统门禁转绿:工具呈现样式补 .vcp-ui-scope,去掉写死颜色 侧栏集成分支:并入各线程修复(当前:UI 系统门禁转绿) Oct 7, 2026
claude added 17 commits October 7, 2026 00:28
A file:// page in the side browser runs with Electron's default file
privileges, so its script could fetch other local files (SSH keys,
VCPChat settings) and post them out. Like DeepSeek Harness
(browser-guests.ts onBeforeRequest) and ZCode (isAllowedBrowserUrl),
the side browser now only opens http, https and about pages, and its
session cancels file: and other non-web subresource requests.

Any page could also start downloads on its own, and each one opened the
system browser. A download now reaches the system browser only right
after a real input on that page, one per input, the same rule popups use.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_016hW799u5Ji5k9khDAwu688
…sible focus ring

- Arrow keys re-rendered the strip and then focused the removed button,
  while activateTab moved focus into the panel, so each press threw a
  keyboard user out of the tablist. Keyboard switches now activate
  without moving focus and refocus the new button by id, as Radix Tabs
  (used by ZCode) does.
- While the new-tab page or hidden notifications was active, no tab had
  tabindex=0, so the strip had no Tab stop. The first tab now gets it.
- Delete closes the focused closable tab.
- Tabs and header buttons removed the outline with no replacement; they
  now get the same focus ring as the tab menu items.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_016hW799u5Ji5k9khDAwu688
render() rebuilds the whole page, and it only put focus back on filter
inputs and page tabs. Toggling a section or a batch, opening filters,
picking a contributor, or any background refresh dropped focus to
<body>. Interactive buttons now carry a data-focus-key that render()
records and restores, the imperative equivalent of React keeping keyed
nodes in ZCode and DSH. Clearing the filters lands on the search box.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_016hW799u5Ji5k9khDAwu688
Shift+F10 on a change row opened the menu at (0,0) with focus left on
the row, no arrow navigation, and Escape dropped focus. Like the Radix
ContextMenu in ZCode's GitPaneChangeCard, the menu now opens beside the
row when there is no pointer, takes focus, moves with the arrow keys,
Home and End, and Escape, Tab or choosing an item returns focus to the
row. Icon ligature text is hidden from screen readers.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_016hW799u5Ji5k9khDAwu688
The button called openPythonAttachmentInTextEditor, which only accepts
.py file URLs on Windows, so it failed silently for every file. Sending
the path to open-external-link instead would hand model-supplied paths
(.bat, .lnk) to shell.openExternal. The button now reveals workspace
files through the workspace-checked git:reveal-path and shows the path
for anything else.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_016hW799u5Ji5k9khDAwu688
…keys stop

Each arrow, Home or End press wrote settings over IPC, about 30 writes a
second while an arrow key was held. The width still applies on every
press; the save now waits until the keys stop for 400 ms (the debounced
onLayoutChange ZCode's resizable.tsx uses), and runs at once when focus
leaves the handle or the pane is torn down. Pointer drags save on
release as before.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_016hW799u5Ji5k9khDAwu688
…focus hold under real use

- Reopening while the close animation runs no longer leaves the pane collapsed with
  its expand button hidden; a repeated open no longer jumps back to zero width.
- With no current conversation (group selected, early startup) topic tabs of other
  conversations stay off the strip, so "close all" can no longer delete their side chats.
- Keep views (side chats) no longer take places under the live-view limit; browser tabs
  sleep only for the limit, not for being hidden; collapsing the pane no longer puts the
  current tab to sleep.
- Arrow keys on the tab strip keep focus on the tab; tab ids with Windows paths or
  quotes are looked up without building selectors.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_019DFRovoZHMzeheXKkLNWKG
The 430-odd side pane, side chat, git and browser tests were not in any workflow;
test:side-pane gathers them and the Chat Kernel and UI job runs it. The PTY-backed
terminal handler tests need a real PowerShell and stay out until a Windows job exists.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_019DFRovoZHMzeheXKkLNWKG
…en and re-show in constant time

Measured in the real Electron app (headless, 6000-line JS file): opening went
from 1215ms to 330ms and switching back to the tab from 752ms to ~110ms with no
long task. Before, focusing the re-shown view forced a full style and layout
pass over ~60k highlight nodes; now only the chunks in the viewport take part.

Gutter and code are split into 200-line blocks with content-visibility:auto and
an intrinsic height from the fixed 18px line height, so numbers stay aligned.
highlight.js still highlights the whole text once; its output is split per line
with spans that cross lines closed and reopened, so multi-line comments and
template strings keep their colours.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_017bCbRB3E9yajQ3HbdMrjiJ
File paths shown as changed files come from the model's tool-call
arguments, and the viewer read any of them through get-text-content,
so a prompt-injected path such as ~/.ssh/id_rsa showed its content, one
click from being inserted back into the chat. Like the workspace-bound
previews in ZCode and DeepSeek Harness, a path outside every registered
workspace now shows where it is and is only read after the user clicks
to read it. Workspace files are read as before; windows without the
workspace service keep the old behaviour.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_016hW799u5Ji5k9khDAwu688
git status runs whatever command a repository's .git/config names in
core.fsmonitor. A project unzipped with a prepared .git folder could
therefore run code as soon as the Git page read its status. Every git
call now passes -c core.fsmonitor=false, as DeepSeek Harness does in
scripts/change-scope.ts.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_016hW799u5Ji5k9khDAwu688
… literal colour

check:ui-system was red on the side pane branch. tool-presentation.css had
101 selectors outside .vcp-ui-scope, an !important on the reduced-motion
rule and two fixed 11px sizes; components.css (from upstream lioensky#234) fell back
to a hard-coded indigo because --vcp-ui-primary is not a token.

Every tool presentation selector now sits under .vcp-ui-scope (the chat
messages container already carries it, and the file is alone in its layer,
so the uniform specificity bump changes no cascade). The reduced-motion rule
reuses the shimmer selector instead of !important, the 11px sizes use
--vcp-ui-text-xs, and the pinned window button uses the accent token.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01UCGGgmHsCToooXTgSXpmq9
…pect the busy gate, the filter accepts input-method typing

- Closing a side chat that has messages deletes its child topic, so it now asks first
  (also for close others / close all); declining keeps the tab.
- A second send while a reply streams is refused, so the running reply keeps its stop
  button. A message button no longer overwrites or sends a typed draft, references or
  attachments.
- The plan history filter no longer rebuilds the page while an input method composes, so
  Chinese input works; the search runs once composition ends.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_019DFRovoZHMzeheXKkLNWKG
…ection copies

- xterm's default OSC 8 handler showed a confirm and called window.open from the main
  window, which opened a bare window on the default session. The tab now passes a
  linkHandler that only opens http(s) through the side browser, as ZCode does.
- Ctrl/Cmd+C with a selection copies it instead of sending ^C to the PTY shared with the
  AI tools; without a selection Ctrl+C still interrupts.
- Ctrl/Cmd+Alt+B and Ctrl+PageUp/PageDown drive the side pane only and are no longer
  written to the shell as escape codes.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_019DFRovoZHMzeheXKkLNWKG
…fix branch

claude/project-thread-20fk2r (PR #3) already finds tabs by id without selectors and keeps
arrow-key focus on the strip, with its own tests. Drop the duplicate here so the two
branches do not conflict.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_019DFRovoZHMzeheXKkLNWKG
Keeps the change clear of the focus-restore lines the parallel fix branch edits.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_019DFRovoZHMzeheXKkLNWKG
PR #4 adds the same tab lookup as findByTabId(container, selector,
tabId). Use the same signature, text and keyboard comments so the two
branches merge without a semantic clash, and rename this branch's
keyboard test so the files don't collide.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_016hW799u5Ji5k9khDAwu688
@RoxyAsahi RoxyAsahi changed the title 侧栏集成分支:并入各线程修复(当前:UI 系统门禁转绿) 侧栏集成分支:门禁修复 + 健壮性安全(#3)+ 审查修复(#4) Oct 7, 2026
claude added 11 commits October 7, 2026 07:02
If the reply finished on its own while a slow interrupt request was
pending, the failed interrupt deleted it as if it were an empty
placeholder (side chat and main chat). Now only a still-streaming
placeholder is removed. If upstream accepts the interrupt but never
sends a terminal, the side chat stops locally after 3s and saves the
partial as cancelled instead of staying busy.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_016hW799u5Ji5k9khDAwu688
21a0a48 moved restart onto the app confirm dialog, which is async and
focuses its own button, but the click handler still called term.focus()
right after restart(). Focus went back to the xterm behind the dialog,
so typing reached the shared shell while the dialog was open. The
handler now leaves focus alone when a confirm will be shown; the dialog
returns focus to the restart button when it closes.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01KnTGLLVUgUjQG3f4cWBHJw
…to claude/project-thread-1zv9nc

# Conflicts:
#	modules/ui-system/side-pane/git/git-view.js
#	modules/ui-system/side-pane/modelTrajectorySideProvider.js
After #14 side chats use dormancy 'keep', so the type note that said
unsent input should use isBusy() instead of keep, and the isBusy examples
that named a sending side chat, no longer matched the code. The side chat
handle's setVisible, removed as dead code in 21a0a48, came back with
#14's revert and is removed again. The architecture doc's terminal
example used a deps.notify that does not exist, and the side chat owner
is about 770 lines, not 560.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01KnTGLLVUgUjQG3f4cWBHJw
States now go error, then loading, then empty (as ZCode GitPane does),
so a load in progress or a failed read is never shown as "nothing here":
- Git: no "还没有工作区 / 添加工作区" before the workspace list arrives
  or when it fails; the error has a retry.
- Code viewer picker: a failed workspace read says so; the file list
  error has an in-place retry.
- Trajectory: no "请先选择智能体和话题" flash while subscribing.
- Tool output: a failed command list shows the error with a retry
  instead of "还没有命令记录"; a rejected output read lands on the error
  bar instead of hanging on "加载中…"; a failed reload during a running
  command keeps the output on screen.
- Side chat: the intro stays hidden while history loads; the history
  retry works from the keyboard.

Layout and feedback:
- Git diff: an open diff keeps the previous text while an edited file
  is refetched instead of collapsing to one line; failed diffs are not
  cached and have a retry.
- Plan: retry buttons switch to "正在重试…" at once; a background
  refresh with a filter swaps results in place; filter errors retry.
- Code viewer: reloading a shown file keeps it until the new text
  arrives; its loading icon actually spins.

Docs: dormancy notes follow #14 (side chats stay mounted).
Tests for the new cases use waitFor instead of fixed sleeps.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_019DFRovoZHMzeheXKkLNWKG
…t send owner tests in test:workbench

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01UCGGgmHsCToooXTgSXpmq9
…s to keep

Mutation runs against #15's tests (5ff688f) found three regressions they
no longer catch:
- regenerate's removeMessageById(id, true): the mock stopped recording
  the save flag, so a renderer removal that saves again (and can write to
  the renderer's current topic) passed. Both delete and regenerate assert
  [id, false] again.
- terminal toolbar listeners bypassing the view scope: `listener > 0`
  goes back to the exact count of 3.
- the pane's active / collapsed classes after a reversed animation: they
  drive the layout (side-pane-shell.css) and the visibility check, so the
  four class asserts come back.

Nothing tested that side chats stay mounted (#14 dropped the sleep tests
only); setting the chat type back to 'none' passed every test. A
draft-restore case now hides a side chat past hiddenMs and checks the
same handle, draft and references are still there. Also drops the
duplicate busy mark the #15 merge left in side-pane-dormancy.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01KnTGLLVUgUjQG3f4cWBHJw
claude added 17 commits October 7, 2026 07:20
The source editor rejected only a literal .git segment. On Windows the
8.3 short name GIT~1, trailing dots/spaces and the ::$INDEX_ALLOCATION
stream name reach the same directory (git's is_ntfs_dotgit), and on any
platform a workspace symlink pointing at .git let source:write-file
overwrite .git/config (core.fsmonitor, hooks path). Segments are now
checked with git's NTFS rules, and the real parent directory is checked
for .git too. The Git panel uses the same segment check, and the reveal
fallback compares paths with path.relative instead of a case-sensitive
prefix.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_016hW799u5Ji5k9khDAwu688
…low it

Opening the side terminal tab resized the shared PTY to the narrow pane even
while the terminal window (and AI commands) were using it at full width, and a
side view without focus drew the PTY's output at its own width.

- terminal:create only presets the size when no PTY is running yet, and
  returns the PTY's real cols/rows.
- PowerShellExecutor tells mirror views when the PTY size changes; the main
  process forwards it as terminal:resized (after flushing buffered output).
- The side view claims the size only while it has focus (and only when it
  differs); without focus it draws at the PTY's size, as DSH's read-only views
  do, and fits to its own width again when the user clicks in.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_012AP71nAxrCFEpH7st6asf9
…s it

Sending in the side chat disabled its textarea until the reply finished.
Focus fell to <body>, so anything typed during the reply was dropped,
the next message needed another click into the box, and Esc could not stop
the reply. Clicking the stop button also left focus on <body> because the
button hides itself.

The textarea now stays enabled the way the main chat's does; the existing
busy guard still keeps Enter from starting a second round, so the next
question can be written while waiting. Esc in the box stops the reply, like
ZCode's Esc-to-stop, and the stop button hands focus back to the box. If
a pending question is retracted while the user has written something new,
it is put back in front of that draft instead of being dropped.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_019L2bZomLn4NVoxS4Rv5Bkv
…sion guards

# Conflicts:
#	modules/ui-system/side-pane/side-pane-types.js
Move/up/cancel were only heard on the strip, so releasing outside it (or
losing pointer capture when the dragged node was replaced by a render) left
the drag session alive and every later press was ignored. They are now
heard on the document for the length of a press. Renders that arrive during
a drag (a browser tab changing its title or icon while loading) are held
until the drop, so the dragged node is never swapped out.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_012AP71nAxrCFEpH7st6asf9
- Plan detail: a focus target from the status panel is applied once and
  then cleared from the saved tab, so restart or wake no longer jumps back.
- Side chat restore keeps the saved createdAt, so lists keep their order.
- A local-only side chat draft that cannot be read now warns the user
  instead of silently restoring blank.
- Width persistence logs a {success:false} settings save result.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_019DFRovoZHMzeheXKkLNWKG
The restart button called session.restart() and then term.focus(). When
the shell is running, restart() first opens the confirm dialog, which
focuses its own button; the terminal then took focus straight back. Esc
still closed the dialog through its document listener, but the keystroke
also reached xterm and bash read it as a Meta prefix, so the next
character typed was eaten (typing "echo still" ran "cho still").

Focus the terminal first and then restart: the dialog takes focus from
the terminal and hands it back when it closes, and Enter on it confirms
without a stray newline in the shell.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_019L2bZomLn4NVoxS4Rv5Bkv
…llapses it

At window widths of 960px or less the pane floats over the conversation and
covers the send button, and the only way out was the collapse button or
Ctrl+Alt+B. A click in the conversation now collapses it like a drawer,
unless that click itself opened or switched a side tab (code block "副屏",
ask in side chat).

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_012AP71nAxrCFEpH7st6asf9
Opening the terminal tab and typing right away lost every key until the PTY
attached. Input typed during the connection is now held (up to 4K chars) and
sent in order once it connects; it is dropped if the connection fails, so a
command meant for a terminal that never started is not replayed later.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_012AP71nAxrCFEpH7st6asf9
The trajectory tab sleeps after 5 minutes hidden. Waking it reset every
collapsed row and jumped the view to the bottom. It now captures its
expansion overrides, commands and scroll position, and restores them
when the remount still shows the same conversation.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_019DFRovoZHMzeheXKkLNWKG
…orkbench

The .git alias and symlink regression test lives in source-service.test.js,
which no CI job ran.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01UCGGgmHsCToooXTgSXpmq9
…inal restart confirm keeps focus

# Conflicts:
#	modules/ui-system/side-pane/terminalSideProvider.js
#	tests/side-pane-terminal-lifecycle.test.mjs
…row window overlay

# Conflicts:
#	package.json
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01UCGGgmHsCToooXTgSXpmq9
@RoxyAsahi
RoxyAsahi merged commit 450d660 into pr/side-pane-workbench Oct 7, 2026
8 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants