Skip to content

feat: Running Agents lists external terminals and focuses their real window - #275

Open
NovakPAai wants to merge 1 commit into
mainfrom
feat/running-agents-external
Open

feat: Running Agents lists external terminals and focuses their real window#275
NovakPAai wants to merge 1 commit into
mainfrom
feat/running-agents-external

Conversation

@NovakPAai

Copy link
Copy Markdown
Collaborator

What & why

The Workspace Running agents tree now lists agents running in external native terminals (iTerm / Terminal.app / Warp / cmux) — including the ones codbash itself launches via /api/launch — and clicking a row raises that real terminal window instead of opening a blank in-app terminal.

7.15.0 scoped Running Agents to codbash-pty descendants only (_scopeToCodbashAgents). Two side effects this fixes:

  1. An agent codbash launches into iTerm descends from iTerm, not a codbash pty, so it was filtered out — codbash opened the window yet reported "nothing running". Hand-launched external agents were invisible too.
  2. Clicking a running-agent row with no live in-app pane called openInWorkspace(...) → an empty shell in the folder. An empty shell is not the agent.

A live agent's PTY cannot be mirrored/attached into the browser terminal (OS gives one controlling terminal per process), so the honest action is to focus its real window. True "resume with history" only applies to stopped sessions (claude --continue), and doing that to a live agent would fork a second instance — so we never do it here.

This intentionally reverses the 7.15.0 "Running Agents lists only agents launched from codbash" decision; codbash's own panes are already visible as tabs, so the tree is now for the terminals that have no other UI home.

Changes

  • src/data.js_scopeToCodbashAgents (drop-filter) → _tagCodbashAgents (tag). Every /api/active entry gets local (true = descends from a codbash browser-pty pane, false = external); nothing is dropped. Pure _tagLocalAgents(active, live, ppidOf) extracted for unit testing — immutable ({...a, local}), depth-bounded walk, fails open as external on a ps error.
  • src/frontend/workspace.js_wsRunningByProject excludes local===true; jumpToRunningAgent(cwd, sessionId, kind, pid) POSTs /api/focus with a validated pid and toasts on failure; removed now-dead _wsPaneForCwd; no blank-terminal fallback.
  • src/server.js--host=0.0.0.0 banner notes that /api/active now lists every agent process on the host (all users), reachable over LAN in that opt-in mode.
  • Docs/specs/testsdocs/design/running-agents-external.md, specs/running-agents-external.feature, test/running-agents-external.test.js (11 tests), CLAUDE.md architecture bullet updated.

Review

code-reviewer + security-reviewer: no CRITICAL/HIGH/MEDIUM. LOW/INFO findings all addressed or documented in the design-doc triage table (unused-param comment, Number.isInteger pid parity, Windows local limitation accepted, LAN exposure noted in banner + accepted, pre-existing /api/focus CSRF deferred to a separate PR).

Test plan

  • node --test test/*.test.js — 218 total, 0 fail (1 pre-existing skip); new suite 11/11
  • Smoke: booted server, /api/active returns local on every entry (6 external agents surfaced that the old filter hid); /api/focus → 400 on bad pid, {ok:false} on a valid-but-dead pid
  • Manual: launch claude in iTerm in a project → appears under Running agents → click raises the iTerm window; codbash-pane agent stays out of the tree

🤖 Generated with Claude Code

…window

The Workspace "Running agents" tree now surfaces agents that actually run in
external native terminals (iTerm/Terminal.app/Warp/cmux) — including the ones
codbash itself launches via /api/launch — and a click raises that real window
instead of opening a blank in-app terminal.

Why: 7.15.0 scoped Running Agents to codbash-pty descendants only. Side effect:
an agent codbash launched into iTerm descends from iTerm, not a codbash pty, so
it vanished from the list — codbash opened the window yet showed "nothing
running". And clicking a row with no live pane spawned an empty shell, which is
not the agent. A live agent's PTY can't be mirrored into the browser terminal
(OS: one controlling terminal per process), so the honest action is to focus its
real window; true "resume with history" only applies to stopped sessions.

- data.js: `_scopeToCodbashAgents` (filter) -> `_tagCodbashAgents` (tag). Each
  /api/active entry gets `local` (true=codbash-pane descendant, false=external);
  nothing is dropped. Pure, testable `_tagLocalAgents(active, live, ppidOf)`
  extracted; immutable, depth-bounded, fails open as external.
- workspace.js: tree shows `!local` (external) agents; `jumpToRunningAgent`
  POSTs /api/focus by validated pid; removed dead `_wsPaneForCwd`; no blank
  terminal fallback.
- server.js: LAN-bind (--host=0.0.0.0) banner notes all-user /api/active scope.
- Tests: test/running-agents-external.test.js (11) + SDD/BDD artifacts.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
@NovakPAai
NovakPAai force-pushed the feat/running-agents-external branch from fee580e to bc16208 Compare July 24, 2026 12:43
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