Skip to content

Task Manager: agent status, idle time and Close Terminal - #15298

Merged
teamleaderleo merged 15 commits into
fix/task-manager-agent-jumpfrom
feat/task-manager-agent-status
Sep 30, 2026
Merged

teamleaderleo merged 15 commits into
fix/task-manager-agent-jumpfrom
feat/task-manager-agent-status

Conversation

@teamleaderleo

@teamleaderleo teamleaderleo commented Sep 28, 2026 •

Copy link
Copy Markdown
Collaborator

Stacked on #15272. Review only the top commits; this PR retargets to main once #15272 lands.

Summary

The Task Manager now shows what each coding agent is doing, not only what it costs. Every agent row (the per-workspace rows from #15272) shows the terminal's agent state, Running, Needs input, Idle or Hibernated, and for the waiting states how long it's been in that state ("Idle 12m", "Needs input 1h 5m").

  • The state comes from the per-panel lifecycle map that the sidebar and agent hibernation already use (Workspace.agentHibernationLifecycleState(panelId:)). The sidebar status text is the fallback when a hook only wrote status. taskManagerTopPayload reports it in a new agent_panels array, built on the main actor next to the window topology.
  • The elapsed time counts from the last lifecycle transition that hibernation tracking recorded, falling back to the status entry's timestamp. It's rendered at minute granularity so the .equatable() rows still re-render at most once a minute.
  • Hibernated agents have no process for the sampler to find, so they're listed under their program with zero usage, dimmed, and they still jump to the terminal.
  • Agent rows with a known state get a Close Terminal context action. It uses TabManager.closePanelWithConfirmation, the same path as the sidebar's close-surface action, so a running process still prompts. As with that path, closing the only surface of a workspace follows the "close workspace on last surface" preference. An agent terminal that never reported a state (hooks not installed) keeps View Workspace / View Terminal / Kill Process but gets no Close Terminal.
  • Each agent row lists its PID and OS process name, e.g. "PID 61879 (2.1.283)". Activity Monitor names a Claude Code process after its version file, so this is how an Activity Monitor row maps back to its workspace and terminal. The window has no filter, so these aren't searchable yet.
  • The command palette entry is now also found by "activity", "processes", "monitor", "top" and "agents".

To stay under the file length budget, CmuxTaskManagerCodingAgentDefinition moves to its own file and CmuxTaskManagerRowView to TaskManagerRowView.swift. Both are moved unchanged, apart from the row view's new status label and Close item.

Not in this PR:

Testing

  • cmuxTests/TaskManagerAgentStatusTests: wire and status-text mapping, whole-minute elapsed time (none while running), status and Close availability on agent rows, hibernated rows under their program, and a producer test on a real Workspace (a Feed permission overlay key reports Needs input, manual loaders are skipped).
  • Focused CI run of TaskManagerAgentStatusTests, TaskManagerCodingAgentInstanceTests, TaskManagerViewSnapshotBoundaryTests and TaskManagerResourcesTests: run 36435329901 on dddc5aa (the current head differs only by a main catch-up), 24 XCTest tests and 10 Swift Testing tests passed.
  • python3 scripts/verify-local.py --affected origin/main --swift-changed origin/main: 15/15 checks passed (swift-syntax, xcstrings, localization, test wiring, project and others). File length budgets passed.
  • Dogfood tour dogfood/scenarios/task-manager-agents-tour.json: fake claude and codex processes that report their pid and lifecycle over the socket (Idle and Running). Screenshots below.
  • Localization: 7 new keys (4 states, Unknown, "Hibernated agent", "Close Terminal"), with all 9 macOS locales filled through scripts/localize-changes. localization_catalog.py check reports 0 parity errors. Durations use DateComponentsFormatter (abbreviated), so they're system-localized.

Changelog

Added: Task Manager shows each coding agent's state (Running, Needs input, Idle, Hibernated) and how long it has been waiting, lists hibernated agents, and can close an agent's terminal

Demo Video

Dogfood-tours: task-manager-agents-tour

SCREENSHOTS

Checklist

  • Behavior changes have added or updated tests, or Testing says why not
  • UI, settings, menu, schema, help-text or user-facing docs change: localization audited, and the result is stated above
  • Reviewed with a subagent before merge, and all bot and human review comments resolved

🤖 Generated with Claude Code


View with [code]smith Autofix with [code]smith
Need help on this PR? Tag @codesmith-bot with what you need. Autofix is disabled.


Summary by cubic

The Task Manager now reports what each coding agent is doing instead of only its cost. Agent rows show a status — Running, Needs input, Idle, or Hibernated — along with how long a waiting agent has been in that state, and offer a Close Terminal action.

  • Status comes from the same per-panel lifecycle map the sidebar and agent hibernation use, with the sidebar status text as fallback; a terminal with background work pending now reports Running.
  • Hibernated agents have no process to sample, so they appear under their program with zero usage, dimmed, and still jump to the terminal. They group by the program's stable id, so a renamed or localized program name doesn't open a duplicate group.
  • Close Terminal follows the normal close-confirmation path, so closing a running process still prompts; rows without a reported state keep the existing actions and get no Close Terminal.
  • Agent rows list the PID and OS process name the sampler read, so a version-numbered Claude Code process in Activity Monitor maps back to its terminal. PIDs are shown ungrouped as Activity Monitor does, and a program row holding only hibernated agents drops the process count. The row falls back to the PID alone when the sampler could only record a pid-<n> placeholder name.
  • The command palette entry is now also matched by "activity", "processes", "monitor", "top", and "agents".

Written for commit b002ab5. Summary will update on new commits.

Review in cubic

teamleaderleo and others added 3 commits September 28, 2026 02:21
Coding agent rows now show the terminal's agent state (Running, Needs
input, Idle, Hibernated) from the same per-panel lifecycle the sidebar
and agent hibernation use, with how long a waiting agent has been in
that state. Hibernated agents, which have no process to sample, are
listed under their program with zero usage. Agent rows get a Close
Terminal action that goes through the normal close confirmation. The
command palette entry is also findable by activity, processes and top.

Moves CmuxTaskManagerCodingAgentDefinition and the row view into their
own files to keep TaskManagerTypes.swift and TaskManagerView.swift under
the file length budget.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Review follow-ups: read the panel lifecycle through
agentHibernationLifecycleState so overlay keys such as a Feed permission
prompt report Needs input, reuse one ISO8601 formatter across refreshes,
and drop the process-count detail on a program row that only holds
hibernated agents. Adds a producer test on a real Workspace.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
@coderabbitai

coderabbitai Bot commented Sep 28, 2026 •

Copy link
Copy Markdown

Important

Review skipped

Auto reviews are disabled on base/target branches other than the default branch.

Please check the settings in the CodeRabbit UI or the .coderabbit.yaml file in this repository. To trigger a single review, invoke the @coderabbitai review command.

⚙️ Run configuration

Configuration used: Repository: manaflow-ai/cmux/.coderabbit.yaml

Review profile: ASSERTIVE

Plan: Advanced

Run ID: 5f82a10a-a0b4-4925-9f8b-a1f881e02b8a

You can disable this status message by setting the reviews.review_status to false in the CodeRabbit configuration file.

Use the checkbox below for a quick retry:

  • 🔍 Trigger review

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

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

Activity Monitor names a Claude Code process after its version file
("2.1.283"), so agent rows now list the PID and the OS process name
the sampler read, which maps an Activity Monitor row back to its
workspace and terminal.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
@github-actions

github-actions Bot commented Sep 28, 2026 •

Copy link
Copy Markdown
Contributor

Dogfood build of 9645be7dac3c3b237317c4a0646f8993d3ec5b1a

cmux DEV pr-15298-9645be7d.app

The link opens this exact commit in the cmux dev menu bar app. The build starts on each push and the page waits until it is ready; a newer push replaces it. It signs in against production, so Cloud or backend changes still need a tagged build with a development backend.

Dogfood tours of b002ab5d

task-manager-agents-tour at b002ab5d: failure (run)

Failed: DogfoodScenarioUITests.swift:113: failed - Dogfood steps failed:

task-manager-agents-tour at b002ab5d

Key frames of task-manager-agents-tour at b002ab5 01-failed 02-failed 08-workspaces 24-palette-activity

Tours are picked by the paths globs in dogfood/scenarios/*.json; a Dogfood-tours: a, b line in the description picks them instead (none turns this off). Look at every frame before merging: a green tour only means no step failed.

teamleaderleo and others added 2 commits September 28, 2026 04:01
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
…o feat/task-manager-agent-status

# Conflicts:
#	cmux.xcodeproj/project.pbxproj
@teamleaderleo

Copy link
Copy Markdown
Collaborator Author

Review: two review-subagent passes, correctness first, reading only (no local build on this host). Nothing blocking.
Fixed:

  • Status now uses agentHibernationLifecycleState(panelId:), the same reduction as hibernation, so a Feed permission overlay (cmux.feed.attention:*) shows Needs input. Before, it could show Running or Idle while the sidebar said Needs input. Added a producer test on a real Workspace.
  • One shared ISO8601 formatter instead of one per agent panel per 3 s refresh.
  • A program row that only holds hibernated agents no longer says "0 processes".
  • The PID detail skips the sampler's pid-<n> placeholder name.
    Left, by design and noted in the body:
  • Close Terminal uses the sidebar's close-surface path, so closing a workspace's only surface follows the "close workspace on last surface" preference.
  • An agent terminal that never reported state gets no Close Terminal item.
  • Hibernated rows attach to their program by display name. Built-in names match today.
  • The elapsed time counts from hibernation tracking's lifecycle-change time when that tracking is on (a repeated hook can reset it), else from the status entry's timestamp.
  • The process name is the kernel's short name (16 chars). That is what shows as 2.1.283 / claude / codex, but longer names are truncated.

@teamleaderleo

Copy link
Copy Markdown
Collaborator Author

Cross-model review (Codex gpt-5.6-sol)

  • Sources/TaskManagerSnapshot+CodingAgents.swift:114-123 — the sampler's missing-name sentinel is exactly pid-<that PID>, but display filtering rejects every name with the pid- prefix. Real executable names such as pid-agent are preserved and forwarded unchanged, then rendered only as PID n, hiding the Activity Monitor name this PR adds. Suppress only name == "pid-\(pid)" (or carry an explicit missing-name flag) and add a legitimate pid- prefix regression test.

@github-actions

github-actions Bot commented Sep 28, 2026 •

Copy link
Copy Markdown
Contributor

CI failure attribution

CI passes on b002ab5d42 (run 36691848431 attempt 1).

Written by scripts/ci/classify_failures.py (ci-failure-attribution.yml); signatures are its SIGNATURES table. A machine verdict is the runner's fault, not this PR's.

teamleaderleo and others added 2 commits September 28, 2026 04:36
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
…o feat/task-manager-agent-status

# Conflicts:
#	cmux.xcodeproj/project.pbxproj
#	dogfood/scenarios/task-manager-agents-tour.json
@blacksmith-sh

This comment has been minimized.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
@cursor

cursor Bot commented Sep 28, 2026

Copy link
Copy Markdown

Bugbot is paused — on-demand spend limit reached

Bugbot uses usage-based billing for this team and has hit its on-demand spend limit.

A team admin can raise the spend limit in the Cursor dashboard, or wait for the next billing cycle to continue.

teamleaderleo and others added 3 commits September 28, 2026 06:08
…ger-agent-status

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
…ger-agent-status

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
@cursor

cursor Bot commented Sep 28, 2026

Copy link
Copy Markdown

Bugbot is paused — on-demand spend limit reached

Bugbot uses usage-based billing for this team and has hit its on-demand spend limit.

A team admin can raise the spend limit in the Cursor dashboard, or wait for the next billing cycle to continue.

teamleaderleo and others added 3 commits September 30, 2026 00:53
…o feat/task-manager-agent-status

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>

# Conflicts:
#	cmux.xcodeproj/project.pbxproj
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
The hibernated rows joined a program group by comparing the name shown,
so a program whose displayed name differs from the running group's title
opened a second group with no icon: a registered agent renamed in
project config, or a program whose name comes from a localized key. Two
hibernated panels of the same program could also each open a group.

The panel payload now carries the program's stable id and the grouping
matches on it, falling back to the name for payloads that carry no id.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
@teamleaderleo

Copy link
Copy Markdown
Collaborator Author

Review subagent on the exact diff, plus what I found checking its findings. Pushed b002ab5.

Review:

  1. Hibernated agents are grouped by the name shown, not by the program. TaskManagerSnapshot+CodingAgents.swift:49 matched $0.title == agentName, so a program whose displayed name differs from the running group's title opens a second group. The reviewer read this as a localized-vs-literal mismatch in 7 of 9 locales, which turned out to be wrong, but the fragility is real. See below.
  2. Everything else it raised was already correct in the diff: the section builder, the idle-time formatting and the Close Terminal confirmation path all check out.

Fixed (b002ab5):

  • 1: the panel payload now carries the program's stable id (agent_id, from RestorableAgentKind.rawValue, the same vocabulary as the coding-agent definition ids), and grouping matches on it. The name comparison stays as the fallback for a payload that carries no id, so nothing regresses for an older app talking to a newer snapshot.
  • Two regression tests in cmuxTests/TaskManagerAgentStatusTests.swift: a hibernated panel reporting id claude with the name "Claude, work laptop" stays under the running Claude Code group and keeps the icon, and two hibernated Codex panels share one group instead of opening two.

Left:

  • The reviewer's stated mechanism for 1 does not hold, so I did not write it into the commit. Both sides of that comparison resolve the same way: the hibernated name is SessionRestorableAgentSnapshot.agentDisplayName, which is RestorableAgentKind.displayName, and that is a literal for claude and codex and a localized key only for kimi and ollama. The definition side uses the same localized keys for those two (CmuxTaskManagerCodingAgentDefinition+BuiltIns.swift:52,63), so they agree in every locale. The real trigger is a registration name from project config differing from the definition's name, which the id match now covers.
  • Separate from this PR, and worth its own issue: the shipped translations localize product names. sessionIndex.agent.codex is "Manuscrit" in fr, "Kodex" in de, "Códice" in es, "法典" in zh-Hans and zh-Hant, "사본" in ko, and a food-code phrase in ar. agent.ollama.displayName is translated in ar, ko, zh-Hans and zh-Hant. Those are product names and should not be translated. I have not touched them here.

Still needs dogfood before merge: /Users/leoli/Projects/briefs/dogfood-queue/cmux-process-labels-15298.md, with the amendment at the end of that file. Step 4 is the one this commit changes behavior for, so it wants a fresh capture on b002ab5. Auto-merge deliberately off.

— Raindrop g2 🫧
Run: run_worker_20260930_3fc64ba6

@teamleaderleo

Copy link
Copy Markdown
Collaborator Author

The rollup is green on b002ab5 (60 checks, ci-status, tests, linux-preflight, macOS admission gate, app-host unit tests for the changed suites, all success), but the dogfood tour on this head is red and it is red at setup, not at an assertion about this PR's UI.

task-manager-agents-tour at b002ab5, run 36695542186, step 41:

step 01 socket workspace.create: workspace.create failed:
  { "code": "unavailable", "message": "TabManager not available" }
step 02 socket workspace.create: same
step 04 socketLine set_agent_lifecycle codex running --tab=: ERROR: Tab not found
step 05 socketLine set_agent_lifecycle claude_code idle --tab=: ERROR: Tab not found
step 06 socket workspace.create: same
step 13 rightClick labelContains=Fix the login flow: no element
step 17 click labelContains=Fix the login flow: no element

Steps 13 and 17 are downstream: the tour never created the workspaces it wanted to right-click, so "no element for labelContains=Fix the login flow" is the absence of the fixture, not a missing row. The single cause is workspace.create returning unavailable from the app host's socket API.

That error comes from the coordinator having no TabManager (Sources/FileOpenSocketSupport.swift:75 and the sibling handlers), which is the app host's known weak spot rather than anything this diff touches. I am not certain yet whether it is the harness or this branch: CI UI tests is genuinely mixed today, roughly half the last thirty runs green and half red, so one retry on this same head would settle it. I have not retried it myself because that is a macOS lane and this is your branch.

So the state is: CI green, review posted and addressed, and no usable dogfood evidence yet. It is a Task Manager feature, so it needs dogfood plus Leo's approval before merge either way. Not merging it from the train.

— Raindrop g2 🫧 / Run: run_worker_20260930_3fc64ba6

@teamleaderleo
teamleaderleo merged commit d5e6815 into fix/task-manager-agent-jump Sep 30, 2026
61 checks passed
@teamleaderleo
teamleaderleo deleted the feat/task-manager-agent-status branch September 30, 2026 10:44
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