You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
[Bug]: Running a project action shows the right-panel terminal in the bottom drawer too #14266
I searched existing issues and did not find a duplicate.
I included enough detail to reproduce or investigate the problem.
Area
apps/web
Steps to reproduce
Open a thread with the bottom terminal drawer closed and empty.
Open a terminal in the right panel. Leave it idle.
Run a project action.
Expected behavior
The action runs in one terminal, and that terminal shows in one place.
Actual behavior
The action runs in the right-panel terminal, and the bottom drawer opens showing that same terminal. You now have one PTY rendered in two places. The drawer's close button kills the shared shell, so there's no way to get rid of the duplicate view without losing the terminal.
Cause
runProjectScript in apps/web/src/components/ChatView.tsx picks its base terminal from terminalUiState.activeTerminalId || activeKnownTerminalIds[0] || DEFAULT_THREAD_TERMINAL_ID. activeKnownTerminalIds comes from every server session for the thread, right-panel terminals included, so an empty drawer lets it pick the panel's terminal. It then calls setTerminalOpen(true). With no drawer terminals, setThreadTerminalOpen in terminalUiStateStore.ts adds "default" to the drawer, which is often the panel terminal's id.
toggleTerminalVisibility already avoids this by allocating a fresh id from allocatableActiveTerminalIds, which excludes panel terminals. The action path skips that step.
Possible fixes
I'd like a maintainer or triage to pick one:
Keep running in the right-panel terminal and don't open the drawer. Focus the panel tab instead. If that terminal is busy, open a new terminal in the panel. The terminal the user placed stays where they put it, and no second shell gets created.
Never reuse a right-panel terminal for actions. Reuse a drawer terminal if one exists, or create a new drawer terminal with an id that doesn't collide with panel terminals. This keeps "actions run in the drawer" as the one rule.
Either way the drawer should stop adopting a terminal id that the right panel owns.
Confirmed on current main (d2c9281b, which includes the reported cdb26fe635). Repro holds: empty closed drawer, one idle right-panel terminal, then a project action. The same path runs chat code-block shell commands (runShellCommand calls runProjectScript).
Two things line up to attach one PTY to both surfaces:
With the drawer empty, activeTerminalId is "", so runProjectScript falls through to activeKnownTerminalIds[0]. That list is every server session for the thread, and the drawer does not filter panel terminals out of it (unlike PersistentThreadTerminalDrawer, which does). The first panel terminal is allocated term-1 by nextTerminalId, so an idle panel session is reused. A busy one is not reused, but that does not avoid the collision below.
setTerminalOpen(true) runs before the target id is applied. An empty drawer makes setThreadTerminalOpen insert DEFAULT_THREAD_TERMINAL_ID, which is "term-1", not "default". The drawer reconcile then refuses to drop it: panel sessions are removed from the drawer’s server list, so [] is treated as a strict subset of ["term-1"] and the id stays. The drawer close button closes that session, so dismissing the duplicate kills the panel shell too.
toggleTerminalVisibility already avoids this. On an empty drawer it allocates with nextTerminalId(allocatableActiveTerminalIds) (panel ids included, so they are skipped) and calls ensureTerminal instead of setTerminalOpen.
Prefer the second fix: actions stay in the drawer. Reuse a drawer terminal when one exists; otherwise allocate an id the right panel does not own, and do not let setTerminalOpen claim term-1 while the panel holds it. Keeping the action in the panel and only focusing that tab would also stop the double view, but it would change the existing “actions run in the drawer” behavior for the common case.
Activity
juliusmarminge commentedon Sep 29, 2026
Triage
Confirmed on current
main(d2c9281b, which includes the reportedcdb26fe635). Repro holds: empty closed drawer, one idle right-panel terminal, then a project action. The same path runs chat code-block shell commands (runShellCommandcallsrunProjectScript).Two things line up to attach one PTY to both surfaces:
activeTerminalIdis"", sorunProjectScriptfalls through toactiveKnownTerminalIds[0]. That list is every server session for the thread, and the drawer does not filter panel terminals out of it (unlikePersistentThreadTerminalDrawer, which does). The first panel terminal is allocatedterm-1bynextTerminalId, so an idle panel session is reused. A busy one is not reused, but that does not avoid the collision below.setTerminalOpen(true)runs before the target id is applied. An empty drawer makessetThreadTerminalOpeninsertDEFAULT_THREAD_TERMINAL_ID, which is"term-1", not"default". The drawer reconcile then refuses to drop it: panel sessions are removed from the drawer’s server list, so[]is treated as a strict subset of["term-1"]and the id stays. The drawer close button closes that session, so dismissing the duplicate kills the panel shell too.toggleTerminalVisibilityalready avoids this. On an empty drawer it allocates withnextTerminalId(allocatableActiveTerminalIds)(panel ids included, so they are skipped) and callsensureTerminalinstead ofsetTerminalOpen.Prefer the second fix: actions stay in the drawer. Reuse a drawer terminal when one exists; otherwise allocate an id the right panel does not own, and do not let
setTerminalOpenclaimterm-1while the panel holds it. Keeping the action in the panel and only focusing that tab would also stop the double view, but it would change the existing “actions run in the drawer” behavior for the common case.fix(web): project actions no longer reuse the right-panel terminal
fix(web): project actions no longer reuse the right-panel terminal
fix(web): project actions no longer reuse the right-panel terminal
fix(web): project actions no longer reuse the right-panel terminal
fix(web): project actions no longer reuse the right-panel terminal