Skip to content

Add tmux integration and external agent detection#43

Open
lusqua wants to merge 1 commit intopablodelucca:mainfrom
lusqua:feat/tmux-integration
Open

Add tmux integration and external agent detection#43
lusqua wants to merge 1 commit intopablodelucca:mainfrom
lusqua:feat/tmux-integration

Conversation

@lusqua
Copy link

@lusqua lusqua commented Feb 26, 2026

Summary

  • Add automatic detection of Claude Code sessions running outside VS Code (e.g. in tmux or standalone terminals) — they appear as [ext] characters in the office
  • Add "Use tmux" mode: + Agent creates tmux windows inside a shared pixel-agents session instead of VS Code terminals, so agents survive editor restarts
  • Add right-click context menu on characters with type-aware actions (attach, focus, close, kill)
  • Closing a VS Code terminal tab for tmux/external agents only detaches — the character stays and re-attaches on next click

What changed

New files

File What it does
src/tmuxResolver.ts Pure functions for tmux integration: find Claude PIDs via pgrep+lsof, walk process tree to resolve tmux sessions, create/kill tmux windows
src/externalAgentScanner.ts Polls project JSONL dir every 5s for session files not owned by any VS Code terminal; creates external agent characters, removes stale ones after 2min
webview-ui/src/components/AgentContextMenu.tsx Pixel-art right-click context menu component

Backend changes

File Changes
src/types.ts terminalRef now nullable; added isExternal, isTmux, tmuxSessionName, tmuxWindowName, lastDataTimestamp
src/constants.ts External scanning intervals, tmux constants, new settings keys
src/PixelAgentsViewProvider.ts openClaude checks "Use tmux" setting; focusAgent re-attaches tmux/external agents; closeAgent kills tmux windows; onDidCloseTerminal detaches instead of removing for tmux/external; new methods: launchTmuxAgent(), reattachTmuxAgent(), attachExternalAgent(), external scanning lifecycle
src/agentManager.ts Initialize/persist/restore new fields; sendExistingAgents includes externalIds
src/fileWatcher.ts Tracks lastDataTimestamp on new JSONL data; adopted agents initialize new fields

Webview changes

File Changes
webview-ui/src/App.tsx Context menu state + rendering with type-aware actions; click on external agent sends focusAgent; wires tmux/external settings toggles
webview-ui/src/hooks/useExtensionMessages.ts Tracks externalAgentIds, externalAgentsEnabled, useTmux state
webview-ui/src/components/SettingsModal.tsx "External Sessions" and "Use tmux" toggle checkboxes
webview-ui/src/components/BottomToolbar.tsx Pass-through for new settings props
webview-ui/src/office/components/ToolOverlay.tsx [ext] label prefix; close button visible for external agents
webview-ui/src/office/components/OfficeCanvas.tsx Right-click on character opens context menu
webview-ui/src/office/engine/officeState.ts addAgent() accepts isExternal param
webview-ui/src/office/engine/characters.ts createCharacter initializes isExternal
webview-ui/src/office/types.ts isExternal field on Character

How tmux resolution works

  1. pgrep -x claude finds all Claude process PIDs
  2. lsof -p <pid> -Fn gets each process's cwd
  3. cwd is hashed (replace :/\ with -) and compared against project dir hash
  4. For matching PIDs, walk the process tree upward (ps -o ppid=) up to 10 levels
  5. Check each ancestor against tmux list-panes -a -F '#{pane_pid} #{session_name}'
  6. First match → resolved tmux session name

How "Use tmux" agents work

  1. User clicks + Agent with setting enabled
  2. Extension ensures pixel-agents tmux session exists (creates if needed)
  3. Creates a named tmux window (agent-N) with workspace cwd
  4. Sends claude --session-id <uuid> into the tmux window
  5. Opens a VS Code terminal running tmux attach -t pixel-agents:agent-N
  6. Polls for <uuid>.jsonl to appear, then starts file watching
  7. If terminal tab is closed → character stays; click re-attaches

Test plan

  • Enable "External Sessions" in settings, run claude in a tmux session with the same workspace → character appears as [ext]
  • Click external character → VS Code terminal opens attached to tmux session
  • Click again → terminal is focused (no duplicate)
  • Close terminal tab → character stays; click re-attaches
  • Right-click external character → "Attach tmux" / "Kill session" menu
  • "Kill session" removes the character and kills tmux session
  • Enable "Use tmux", click + Agent → tmux window created, VS Code terminal attached
  • Close tmux agent terminal tab → character stays; click re-attaches
  • Right-click normal agent → "Focus terminal" / "Close agent" menu
  • Right-click sub-agent → "Focus parent" menu
  • Disable "External Sessions" → all [ext] characters removed
  • tmux not installed → info message on attach attempt, no crash

🤖 Generated with Claude Code

Detect Claude Code sessions running outside VS Code (e.g. in tmux) and
show them as animated characters in the office. Add "Use tmux" mode where
agents are created as tmux windows in a shared session, surviving editor
restarts. Include right-click context menu with type-aware actions and
re-attach logic when terminal tabs are closed.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
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.

1 participant