Skip to content

feat(web): pin a thread's terminal drawer for a project or all projects - #9836

Open
bj97301 wants to merge 7 commits into
pingdotgg:mainfrom
bj97301:feat/shared-terminal
Open

bj97301 wants to merge 7 commits into
pingdotgg:mainfrom
bj97301:feat/shared-terminal

Conversation

@bj97301

@bj97301 bj97301 commented Sep 4, 2026 •

Copy link
Copy Markdown

What Changed

Adds a pin button to the terminal drawer toolbar. It cycles through three states:

  • Off (default): each thread has its own drawer, the current behavior.
  • Pinned to project: mod+j (terminal.toggle) on any thread in that project opens the pinned drawer, so its shells, tabs, splits, and height follow you from thread to thread.
  • Pinned for all projects: every thread in the environment opens the pinned drawer, whatever project it belongs to. Project pins are shadowed until this is unpinned.

A third click unpins. Every thread gets its own drawer back and the shells stay with the thread that owned them. Deleting the pinned thread also unpins it.

Implementation: sessions stay keyed by their owning thread on the server, so there is no server or contract change. The pin is client-local UI state next to the drawer layout (terminalUiStateStore: a thread key under a pin key naming a project or an environment). One hook (useTerminalDrawerPin) resolves which thread's drawer terminal.toggle targets and why, and the chat view, command palette, both sidebars, and the chat route read it, so the terminalOpen keybinding context stays consistent. New shells opened in a pinned drawer launch from the pinned thread's own worktree or project root; links clicked in it open in the preview of the thread you are viewing. Right-panel terminal tabs and the mobile terminal are unaffected.

Docs: docs/user/terminal.md gains drawer and pin sections (existing history section kept), plus a short internals note in docs/internals/terminal-runtime.md and a glossary row.

Why

Terminals were strictly per thread, so a dev server or a shell you keep coming back to was only reachable from the thread that opened it. Users working across several threads in one project want one terminal that mod+j always shows. A pin on the drawer itself keeps this discoverable and reversible without a new setting.

Related: Ideas discussion #6848 asks for exactly this for terminal (and browser) tabs. This PR covers the terminal half.

UI Changes

One new pin button at the end of the drawer toolbar, in both the single-terminal header and the multi-terminal sidebar header. Screenshots are cropped to the drawer.

Before After (off)
Single terminal before, single terminal after, single terminal with pin button
Multiple terminals before, terminal sidebar after, terminal sidebar with pin button
Pinned to project (tooltip open) Pinned for all projects
pinned to project pinned for all projects

The same drawer, with its shell from a t3code thread, shown from a thread in a different project while pinned for all projects:

pinned drawer shown from another project

Verification

  • apps/web: tsgo --noEmit; vp test run --project unit for lib/terminalDrawer.test.ts, terminalUiStateStore.test.ts, components/ThreadTerminalDrawer.test.ts, components/ChatView.logic.test.ts
  • vp lint and vp fmt on the changed files (remaining lint warnings are pre-existing upstream)

Checklist

  • This PR is small and focused
  • I explained what changed and why
  • I included before/after screenshots for any UI changes
  • I included a video for animation/interaction changes

Written by Claude Fable 5.1 in Claude Code.

🤖 Generated with Claude Code


Note

Medium Risk
Touches terminal session routing, CWD/worktree selection, and ID allocation across many UI entry points; mistakes could show the wrong shell or reuse terminal IDs, though changes stay client-local with no server contract changes.

Overview
Adds pinned terminal drawers: a toolbar pin cycles off → project → environment → off, storing the chosen thread in persisted terminalUiStateStore pin keys. useTerminalDrawerPin / resolveTerminalDrawer decide which thread owns the bottom drawer (environment pin beats project pin); shortcuts and “terminal open” context in ChatView, sidebars, command palette, and _chat read that resolved ref instead of the route thread alone.

ChatView routes open/split/close/script runs and terminal UI state to the pinned drawer’s thread while keeping preview links on the thread you’re viewing via previewThreadRef. New shells use the pinned thread’s project root/worktree; terminal ID allocation merges the viewed thread’s sessions so panel tabs don’t collide with server-known IDs. ThreadTerminalDrawer exposes the pin control and passes preview routing into TerminalViewport.

Pins drop when pinned terminal state is cleared or the thread is removed; deleting an archived thread also clearTerminalUiState. Right-panel and mobile terminals stay unpinned. User and internals docs updated; unit tests cover pin resolution and store behavior.

Reviewed by Cursor Bugbot for commit da08865. Bugbot is set up for automated code reviews on this repo. Configure here.

Note

Add project and environment pinning for terminal drawer in ChatView

  • Adds a pin control to the terminal drawer toolbar that cycles through no pin, project pin, and environment pin states; environment pins take precedence over project pins
  • Drawer resolution via resolveTerminalDrawer in terminalDrawer.ts selects the pinned thread's drawer before the viewed thread's own drawer; invalid pins (deleted or moved threads) fall back to the viewed thread
  • Pin mappings persist in the terminal UI state store and are removed when terminal state is cleared or the pinned thread is deleted
  • Terminal sessions, layout, and shell/script launches follow the pinned thread's worktree and project root, while preview links remain associated with the viewed thread
  • Sidebar, command palette, and global shortcuts now read terminal-open state from the resolved pinned drawer instead of only the routed thread's drawer
  • Behavioral Change: deleting an archived thread via useThreadActions now also clears its local terminal UI state (layout, suppression, pin references)

Macroscope summarized da08865.

@chatgpt-codex-connector

chatgpt-codex-connector Bot commented Sep 4, 2026 •

Copy link
Copy Markdown

Codex Review Summary

This comment shows the latest Codex review activity on this pull request.

Review Status Commit Review trigger
📝 Code Review ✅ Completed 2026-09-05T06:10:18.006153Z b29f38c Manual request
ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review" or "@codex security review".

Codex reacts with 👀 while any review is running, comments if it has suggestions, and reacts with 👍 once all reviews finish with no findings.

@github-actions github-actions Bot added vouch:unvouched PR author is not yet trusted in the VOUCHED list. size:L 100-499 changed lines (additions + deletions). labels Sep 4, 2026

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 65a2f2e5c2

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread apps/web/src/components/ChatView.tsx

@cursor cursor Bot left a comment •

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Stale Bugbot comment from a previous run.

Comment thread apps/web/src/components/ChatView.tsx Outdated
Comment thread apps/web/src/components/ChatView.tsx Outdated
Comment thread apps/web/src/components/ChatView.tsx Outdated
@macroscopeapp

macroscopeapp Bot commented Sep 4, 2026 •

Copy link
Copy Markdown
Contributor

Approvability

Verdict: Not approved

Macroscope's review found this PR not approvable — This PR introduces project- and environment-wide terminal drawer pinning and changes how existing drawer actions, session routing, shortcuts, and shell launches select their owning thread and working directory. The cross-cutting stateful runtime behavior is broader than a small additive change and warrants human review.

You can add or adjust custom eligibility rules. Learn more.

@bj97301
bj97301 force-pushed the feat/shared-terminal branch from 65a2f2e to 3d3be82 Compare September 5, 2026 04:18
The terminal drawer and its shells were strictly per thread, so mod+j on
another thread always showed a different set of terminals. Add a pin
button to the drawer toolbar. Pinning a thread's drawer pins it to the
project: every thread in that project then resolves its drawer to the
pinned thread, so the same shells, tabs, splits, and height follow the
user between threads. Sessions stay keyed by their owning thread, so no
server or contract change is needed; the pin is client-local UI state
next to the drawer layout. Unpinning from any thread hands each thread
its own drawer back, and deleting the pinned thread drops the pin. New
shells in a pinned drawer launch from the pinned thread's worktree or
project root; links open in the viewed thread's preview. Right-panel
terminals and the mobile terminal are unaffected.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
@bj97301
bj97301 force-pushed the feat/shared-terminal branch from 3d3be82 to 84a95d8 Compare September 5, 2026 04:34
@bj97301 bj97301 changed the title feat(web): share one terminal drawer across threads feat(web): pin a thread's terminal drawer across its project Sep 5, 2026
@github-actions github-actions Bot added size:XL 500-999 changed lines (additions + deletions). and removed size:L 100-499 changed lines (additions + deletions). labels Sep 5, 2026
Comment thread apps/web/src/terminalUiStateStore.ts Outdated
Comment thread apps/web/src/components/ThreadTerminalDrawer.tsx
Comment thread apps/web/src/lib/terminalDrawer.ts Outdated

@cursor cursor Bot left a comment •

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Stale Bugbot comment from a previous run.

Comment thread apps/web/src/components/ChatView.tsx
Review follow-ups: a pin to a thread that was deleted while archived, or
moved to another project, now reads as unpinned and is cleared on delete;
links from a long-lived pinned surface open in the thread currently in
front; project scripts launched into a pinned drawer default to the
drawer thread's worktree instead of the viewed thread's.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
@bj97301

bj97301 commented Sep 5, 2026

Copy link
Copy Markdown
Author

@codex review

@chatgpt-codex-connector

Copy link
Copy Markdown

Codex Review: Didn't find any major issues. 🎉

Reviewed commit: 4fe633787b

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

The pin button now cycles off → this project → every project → off. An
environment-wide pin points every thread in the environment at one
drawer and shadows project pins until it is removed. Pins are stored
under a pin key that names a project or an environment, so cleanup on
thread deletion covers both.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>

@cursor cursor Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Cursor Bugbot has reviewed your changes using default effort and found 1 potential issue.

Fix All in Cursor

❌ Bugbot Autofix is OFF. To automatically fix reported issues with cloud agents, enable autofix in the Cursor dashboard.

Reviewed by Cursor Bugbot for commit 1ae5ee6. Configure here.

Comment thread apps/web/src/components/ChatView.tsx
bj97301 added a commit to bj97301/t3code that referenced this pull request Sep 5, 2026
@bj97301 bj97301 changed the title feat(web): pin a thread's terminal drawer across its project feat(web): pin a thread's terminal drawer for a project or all projects Sep 5, 2026
With an all-projects pin the drawer thread can belong to another project,
but new shells and scripts still took the viewed project's root and
T3CODE_PROJECT_ROOT. Resolve the drawer thread's own project for cwd and
runtime env instead.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
@bj97301

bj97301 commented Sep 5, 2026

Copy link
Copy Markdown
Author

@codex review

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 51afc80bf8

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread apps/web/src/components/ChatView.tsx Outdated
Drafts are not in the server shell index, so a drawer pinned from a
not-yet-sent thread fell back to the viewed thread's project and worktree
for new shells and scripts. Resolve the drawer thread's location from the
shell index or the composer draft store, whichever knows it.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
@bj97301

bj97301 commented Sep 5, 2026

Copy link
Copy Markdown
Author

@codex review

@chatgpt-codex-connector

Copy link
Copy Markdown

Codex Review: Didn't find any major issues. Swish!

Reviewed commit: b29f38cc5e

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

This branch has not been deployed

No deployments
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

size:XL 500-999 changed lines (additions + deletions). vouch:unvouched PR author is not yet trusted in the VOUCHED list.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant