Skip to content

feat: interactive shell inside agent worktree - #20

Merged
roulpriya merged 3 commits into
mainfrom
feat/worktree-shell
Apr 30, 2026
Merged

feat: interactive shell inside agent worktree#20
roulpriya merged 3 commits into
mainfrom
feat/worktree-shell

Conversation

@recrsn

@recrsnrecrsn commented Apr 30, 2026

Copy link
Copy Markdown
Contributor

Summary

Stacked on #17 (refactor/agents-router-factory)

Adds a TERMINAL tab alongside the AGENT tab in the detail panel, giving users a full interactive shell scoped to the agent's worktree directory — useful for running tests, inspecting files, or running git commands without leaving the panel.

  • POST /agents/:id/shell: spawns a ShellSession rooted in the agent's worktreePath and returns { id, cwd } for the /ws/shell/<id> channel
  • WorktreeShellPanel: new component — creates the shell session on mount, connects useForgeTerminal to /ws/shell/<id>, and kills the session on unmount
  • AgentDetailPanel: AGENT / TERMINAL tab bar; shell panel is lazily mounted on first click so no shell process is spawned until the user opens the tab
  • AgentTerminalPanel: removes the now-redundant "TERMINAL" header row (replaced by the shared tab bar)
  • api.ts: agents.createShell(id)

Test plan

  • Open an agent panel; confirm AGENT tab shows the PTY as before
  • Click TERMINAL tab; confirm a shell opens in the agent's worktree directory
  • Close the panel; confirm the shell session is cleaned up (no orphan processes)
  • Open multiple agents; confirm each TERMINAL tab is isolated to its own worktree

🤖 Generated with Claude Code

Summary by CodeRabbit

  • New Features

    • Added interactive shell access for agent worktrees, enabling direct command execution in a dedicated terminal session.
  • UI Improvements

    • Introduced a tabbed terminal interface to separate agent terminal and worktree shell views for improved clarity and organization.

@coderabbitai

coderabbitaiBot commented Apr 30, 2026

Copy link
Copy Markdown
Contributor

Warning

Rate limit exceeded

@recrsn has exceeded the limit for the number of commits that can be reviewed per hour. Please wait 4 minutes and 14 seconds before requesting another review.

To keep reviews running without waiting, you can enable usage-based add-on for your organization. This allows additional reviews beyond the hourly cap. Account admins can enable it under billing.

⌛ How to resolve this issue?

After the wait time has elapsed, a review can be triggered using the @coderabbitai review command as a PR comment. Alternatively, push new commits to this PR.

We recommend that you space out your commits to avoid hitting the rate limit.

🚦 How do rate limits work?

CodeRabbit enforces hourly rate limits for each developer per organization.

Our paid plans have higher rate limits than the trial, open-source and free plans. In all cases, we re-allow further reviews after a brief timeout.

Please see our FAQ for further information.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro Plus

Run ID: 2655e85c-4cda-4b01-89e8-8bfb57a72bd3

📥 Commits

Reviewing files that changed from the base of the PR and between aa6aa7b and 0a7fdba.

📒 Files selected for processing (5)
  • src/backend/routes/agents.ts
  • src/frontend/components/AgentDetailPanel.tsx
  • src/frontend/components/AgentTerminalPanel.tsx
  • src/frontend/components/WorktreeShellPanel.tsx
  • src/frontend/lib/api.ts
📝 Walkthrough

Walkthrough

This PR introduces a new shell session feature for agents. It adds a backend POST /:id/shell endpoint that creates a unique shell session using randomUUID, spawns an interactive shell process via shellSessionManager, and returns the session ID and working directory. On the frontend, AgentDetailPanel is refactored to support two tabs—an "AGENT" terminal and a new "TERMINAL" tab that renders WorktreeShellPanel. The WorktreeShellPanel component creates a shell session on mount, derives a WebSocket URL from the session ID, and connects it to a terminal UI. Session cleanup is handled on unmount or component cancellation.

Sequence Diagram

sequenceDiagram
participant User
participant Frontend as Frontend<br/>(AgentDetailPanel)
participant API as Backend API<br/>(/agents/:id/shell)
participant Manager as ShellSessionManager
participant Shell as Shell Process
participant WS as WebSocket<br/>(/ws/shell/:id)
User->>Frontend: Click "TERMINAL" tab
activate Frontend
Frontend->>Frontend: Mount WorktreeShellPanel
Frontend->>API: POST /agents/:id/shell
deactivate Frontend
activate API
API->>API: Generate sessionId (randomUUID)
API->>Manager: spawn(worktreePath)
deactivate API
activate Manager
Manager->>Shell: Start interactive shell
Manager->>API: Register cleanup callback
deactivate Manager
activate API
API->>Frontend: Return { id: sessionId, cwd }
deactivate API
activate Frontend
Frontend->>Frontend: Derive WS URL /ws/shell/{sessionId}
Frontend->>WS: Connect WebSocket
activate WS
Frontend->>Frontend: Render terminal UI
deactivate Frontend
User->>Frontend: Interact with shell
Frontend->>WS: Send input
WS->>Shell: Execute commands
Shell->>WS: Return output
WS->>Frontend: Display output
User->>Frontend: Unmount or close tab
activate Frontend
Frontend->>API: Terminate shell session
deactivate Frontend
activate API
API->>Manager: clearShellScrollback + cleanup
deactivate API
deactivate WS
Loading

Possibly Related PRs

Suggested Reviewers

  • roulpriya

Poem

🐰 A shell blooms bright with a sessionId key,
Through WebSocket whispers, the worktree runs free!
Two tabs now dance—one for Agent, one for Shell,
With cleanup callbacks that work oh so well! ✨

Warning

Review ran into problems

🔥 Problems

Git: Failed to clone repository. Please run the @coderabbitai full review command to re-trigger a full review. If the issue persists, set path_filters to include or exclude specific files.


Review rate limit: 0/3 reviews remaining, refill in 4 minutes and 14 seconds.

Comment @coderabbitai help to get the list of available commands and usage tips.

@recrsn
recrsnforce-pushed the refactor/agents-router-factory branch from 58796f6 to 798f470CompareApril 30, 2026 18:06
Base automatically changed from refactor/agents-router-factory to mainApril 30, 2026 18:12
@recrsn
recrsnforce-pushed the feat/worktree-shell branch from 7522018 to aa6aa7bCompareApril 30, 2026 18:30
recrsnand others added 2 commits May 1, 2026 00:04
Adds a TERMINAL tab alongside the AGENT tab in the detail panel, giving
users a full interactive shell scoped to the agent's worktree directory:
- POST /agents/:id/shell spawns a ShellSession in the agent's worktreePath
and returns a session id for the WS channel
- WorktreeShellPanel: new component that creates a shell session on mount
and connects useForgeTerminal to /ws/shell/<id>; cleans up (DELETE) on unmount
- AgentDetailPanel: tab bar with AGENT / TERMINAL tabs; shell panel is
lazily mounted on first click to avoid spawning a process eagerly
- AgentTerminalPanel: remove the now-redundant header row (moved to tab bar)
- api.ts: createShell()
Co-Authored-By: Claude Sonnet 4.6 (1M context) <noreply@anthropic.com>
Co-Authored-By: Claude Sonnet 4.6 (1M context) <noreply@anthropic.com>
@recrsn
recrsnforce-pushed the feat/worktree-shell branch from aa6aa7b to 92c20dbCompareApril 30, 2026 18:34

@coderabbitaicoderabbitaiBot 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.

Actionable comments posted: 2

🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.
Inline comments:
In `@src/frontend/components/AgentDetailPanel.tsx`:
- Around line 29-30: The shell lazy-mount state (shellMounted via
setShellMounted) isn't reset when the selected agent changes, so a previously
mounted WorktreeShellPanel (WorktreeShellPanel agentId={agentId!}) stays mounted
behind the inactive tab and can spawn shells for the new agent; add an effect
that listens for agentId changes (useEffect(() => setShellMounted(false),
[agentId])) to reset shellMounted to false whenever agentId changes, ensuring
the terminal only mounts lazily after the user explicitly opens the TERMINAL tab
and that WorktreeShellPanel is remounted with the correct agentId.
In `@src/frontend/components/WorktreeShellPanel.tsx`:
- Line 27: The current .catch(console.error) in WorktreeShellPanel.tsx hides
shell creation errors from the UI; replace it with code that stores the error in
component state (e.g. add const [shellError, setShellError] =
useState<Error|null>(null)) and in the promise catch call setShellError(err)
(and optionally console.error(err)), or dispatch a user-facing notification
(e.g. dispatch(showNotification(...))). Then update the WorktreeShellPanel
render logic to display an error message/UI when shellError is non-null so
failures are visible to users (reference the WorktreeShellPanel component, the
promise that creates the shell, and the setShellError/dispatch call).
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro Plus

Run ID: e76014f6-c7ca-4384-88de-8fac61a7b0bc

📥 Commits

Reviewing files that changed from the base of the PR and between 7d39129 and aa6aa7b.

📒 Files selected for processing (5)
  • src/backend/routes/agents.ts
  • src/frontend/components/AgentDetailPanel.tsx
  • src/frontend/components/AgentTerminalPanel.tsx
  • src/frontend/components/WorktreeShellPanel.tsx
  • src/frontend/lib/api.ts
💤 Files with no reviewable changes (1)
  • src/frontend/components/AgentTerminalPanel.tsx

Comment threadsrc/frontend/components/AgentDetailPanel.tsx
Comment threadsrc/frontend/components/WorktreeShellPanel.tsx Outdated
@roulpriya
roulpriya merged commit e1d8f0f into mainApr 30, 2026
2 checks passed
@roulpriya
roulpriya deleted the feat/worktree-shell branch April 30, 2026 18:45
Sign up for freeto 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

@recrsn@roulpriya