Skip to content

fix(next): Needs input menu opens waiting agent, not latest unread (#5329) - #28692

Closed
teamleaderleo wants to merge 1 commit into
feat-cmux-nextfrom
mode02-needs-input-action-20261030
Closed

teamleaderleo wants to merge 1 commit into
feat-cmux-nextfrom
mode02-needs-input-action-20261030

Conversation

@teamleaderleo

@teamleaderleo teamleaderleo commented Oct 31, 2026 •

Copy link
Copy Markdown
Collaborator

What this fixes

HQ #5329: the macOS menu-bar row “Needs input: N” currently executes jumpToUnread, which may open a completely unrelated unread terminal or say there is nothing unread while an agent awaits a decision.

This PR adds the explicit agent.jumpToNextNeedingInput action and binds it to the existing ranked agent lanes. Successive invocations cycle only .needsYou sessions; the list already filters archived/snoozed items and keeps this Mac, Chief-home and remote session identities. Resolved/replaced requests are re-evaluated at each invocation. jumpToUnread and its keyboard shortcut remain unchanged.

The menu-bar count now uses the same eligibility rule as its destination, so a positive count is meant to have an actionable target. The action is also discoverable via the palette/Window menu, with no forced default shortcut or new sidebar setting. Uses the app’s existing SidebarPriorityFeed.open path so it does not introduce a competing session opener.

Exact code / regression

Base: manaflow-ai/cmux@feat-cmux-next 4d1e169b8e782755f67812a53f909a3dae5d7194

Commit: 7b1a6fae356e52e69ae1d5b1b1397d32ba382155

  • MenuBarMenuSpecTests.agentStatus: menu row invokes the new action, preserving zero-count hiding.
  • AgentPriorityRankingTests.nextNeedsInputCyclesAndSkipsResultsAndSnoozedChats: cycles two input lanes; never selects newer unread results or failed lanes; skips snoozed/archived input and starts at a fresh request after the earlier one was removed.

Validation: exact base-to-commit diff checked (7 files; 59 insertions / 5 deletions). Native Swift compilation, focused tests, signed-app and keyboard/VoiceOver captures are pending (this author has GitHub read/write, no macOS checkout/CI runner or fleet access). Treat this as an unverified draft, not a passed fix or shipment.

Required acceptance before review / merge

  1. Execute MenuBarMenuSpecTests and AgentPriorityRankingTests on the exact PR head using the repo's pinned macOS toolchain, plus action registry binding/coverage gates.
  2. On a signed NEXT build: one blocked agent with hasUnread=false plus one newer unread terminal; the menu must select the agent. Repeat with zero unread tabs, then 3 blocked agents to cycle. Resolve one ask between menu open and action; avoid dead tabs and wrong-host navigation. Retest with priority sidebar hidden.
  3. Validate counts and ability to open cross-Mac and Chief-home sessions; known wrong-daemon issues cmux #27934 / #27879 remain their own owners. Test no eligible item, stale/offline peer, and focus/VoiceOver. If the current host opener cannot safely navigate remote peers, hold and route that defect to those owners.

Ownership/dedupe: existing HQ #5329 is canonical; cmux #24336 is separate and on a visual HOLD, unaffected by this PR. Parent idea-lab writeback: HQ #5457.

No defaults, product design policy, production flags, credentials, billing, merge or deployment changed.


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


Summary by cubic

Fixes the macOS menu-bar “Needs input: N” row so it now jumps to the next agent actually waiting for input, instead of the latest unread terminal. Adds the agent.jumpToNextNeedingInput action, which reuses the ranked, snooze-aware agent lanes and cycles only .needsYou sessions.

The menu-bar count now uses the same eligibility rule as its destination, so a positive count always has actionable targets. jumpToUnread and its keyboard shortcut are unchanged, and the new action is available via the palette and Window menu with no default shortcut. Resolved, archived, or snoozed requests are skipped, and a removed request resets the cycle to the first remaining lane.

Tests cover the menu row wiring and cycling through mixed states (needs input, unread results, failures, snoozed chats).

Written for commit 7b1a6fa. Summary will update on new commits.

View guided diff Turn on auto-fix

Use ranked, snooze-aware acpmux lanes for both the displayed count and
navigation. Keep existing unread navigation unchanged and cover cycling,
removed asks, and mixed agent states.
@github-actions

github-actions Bot commented Oct 31, 2026 •

Copy link
Copy Markdown
Contributor

cmux status (one comment, edited in place; each line is updated by the job that owns it)

Review 7b1a6fa: HQ feed card · gallery before/after runs · checks

App of this head (app.zip, kept 1 day)

gh workflow run reload-build.yml -R manaflow-ai/cmux --ref feat-cmux-next -f tag=pr28692 -f ref=mode02-needs-input-action-20261030 -f platform=macos -f backend_mode=local

Default changes

This pull request changes 4 defaults at 7b1a6fae356e (what everyone gets without configuring anything):

  • tunable-source.CmuxNextAgentLanes/AgentPriorityRanking.swift:nextNeedingInput: (none) -> "01eede26d1826998491eecd2f7b28677cf659b0bd0c1046fff0ecd1e5169be35"
  • tunable-source.CmuxNextApp/SidebarSections/SidebarPriorityFeed.swift:bind: "f07ef8f189a1831198bd9d27b075178288ab998264c17dd4fcdaa06a6b6102f0" -> "d8da698e7bdd1f13c742cde153c990e158943d3095048a0568f6e0ca60c7eb8f"
  • tunable-source.CmuxNextApp/SidebarSections/SidebarPriorityFeed.swift:open: (none) -> "fd74cc190d1fcde45cd2ac255cf55c22553ed65c4acbf876f633746030a384d7"
  • tunable-source.CmuxNextApp/SidebarSections/SidebarSectionStrings.swift:noSuchPriorityChat: (none) -> "e4877117b496364362328b4d3703bd0b1afa3410a4bf91786cc2b146261dea3f"

Needs a review. It passes with an independent review receipt on this commit: a comment or review whose first line is Review (<reviewer>): SHIP at 7b1a6fae356e52e69ae1d5b1b1397d32ba382155, from a member, not a self-review (the newest verdict naming the head decides; a later BLOCK beats an earlier SHIP), or with an approving review on this commit from @lawrencecchen or @austinywang (the call owners in .github/defaults-call-owners.json, never the author). A receipt posted as a review re-runs this check; after a plain comment, re-run it. The needs a call label alone does not pass, and a new push needs a new receipt.

Regenerate the snapshot with python3 scripts/ci/defaults_guard.py snapshot.

@github-actions github-actions Bot added the risk:normal Risk tier (docs/ci/risk-tiers.md) label Oct 31, 2026
@blacksmith-sh

blacksmith-sh Bot commented Oct 31, 2026 •

Copy link
Copy Markdown

Found 6 test failures on Blacksmith runners:

Failures

Test View Logs
main.DeveloperIdAppTests.test_download_prints_the_active_profile_only/
test_download_prints_the_active_profile_only
View Logs
stubs: /System/Library/Frameworks/Security.framework/Versions/A/Security has no stub/
Security has no stub
View Logs
stubs: CoreFoundation.tbd: install-name /System/Library/Frameworks/
CoreFoundation.framework/Versions/A/CoreFoundation, missing 1: ['_CFRetain']/
CoreFoundation, missing 1: ['_CFRetain']
View Logs
stubs: CoreFoundation.tbd: install-name /System/Library/Frameworks/
CoreFoundation.framework/Versions/A/CoreFoundation, missing 1: ['_log2']/
CoreFoundation, missing 1: ['_log2']
View Logs
test_every_listed_hook_is_one_glaeda_released_with_the_check (main.SigningHooksInSt
epWithGlaedaTests.test_every_listed_hook_is_one_glaeda_released_with_the_check)/
test_every_listed_hook_is_one_glaeda_released_with_the_check (main.SigningHooksInSt
epWithGlaedaTests.test_every_listed_hook_is_one_glaeda_released_with_the_check)
View Logs
test_the_ten_first_party_gpl_crates_are_named_exactly (main.AppCrateLicenseGate.tes
t_the_ten_first_party_gpl_crates_are_named_exactly)/
test_the_ten_first_party_gpl_crates_are_named_exactly (main.AppCrateLicenseGate.tes
t_the_ten_first_party_gpl_crates_are_named_exactly)
View Logs

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

@teamleaderleo

Copy link
Copy Markdown
Collaborator Author

Owned by an agent session · session

@teamleaderleo
teamleaderleo marked this pull request as ready for review November 1, 2026 02:07

@cubic-dev-ai cubic-dev-ai 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.

3 issues found across 7 files

Prompt for AI agents (unresolved issues)

Check if these issues are valid — if so, understand the root cause of each and fix them. When an issue isn't valid or won't be fixed in this PR, reply in its thread with the reason and then resolve the thread. If appropriate, use sub-agents to investigate and fix each issue separately.


<file name="Packages/macOS/CmuxNext/Sources/CmuxNextActions/Catalog/NotificationActionCatalog.swift">

<violation number="1" location="Packages/macOS/CmuxNext/Sources/CmuxNextActions/Catalog/NotificationActionCatalog.swift:21">
P3: The new action adds palette, keyboard and menu surfaces, but `plans/cmux-next/action-surfaces.json` and the generated block in `plans/cmux-next/actions.md` are not regenerated. Run `CMUX_UPDATE_ACTION_SURFACES=1 swift test --filter ActionSurfaceParityTests` and commit the results, or the export freshness check will fail in CI.</violation>

<violation number="2" location="Packages/macOS/CmuxNext/Sources/CmuxNextActions/Catalog/NotificationActionCatalog.swift:22">
P2: The title key `action.agent.jumpToNextNeedingInput` is not in `ActionCatalog.xcstrings`, so it has no en/ja entries. Add it there with `en` and `ja` translations, matching the other `action.*` rows.</violation>
</file>

<file name="Packages/macOS/CmuxNext/Sources/CmuxNextApp/SidebarSections/SidebarPriorityFeed.swift">

<violation number="1" location="Packages/macOS/CmuxNext/Sources/CmuxNextApp/SidebarSections/SidebarPriorityFeed.swift:52">
P2: The new action can select cached `.needsYou` lanes from an offline or stale remote peer. Filter remote eligibility by a live, non-provisional machine snapshot and refuse or defer navigation when the owning peer is unavailable; otherwise the menu can open a nonexistent local session.</violation>
</file>

Reply with feedback, questions, or to request a fix.

View guided diff | Turn on auto-fix | Re-trigger cubic

),
ActionDescriptor(
id: "agent.jumpToNextNeedingInput",
title: String(localized: "action.agent.jumpToNextNeedingInput", defaultValue: "Go to Next Agent Needing Input", bundle: .module),

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P2: The title key action.agent.jumpToNextNeedingInput is not in ActionCatalog.xcstrings, so it has no en/ja entries. Add it there with en and ja translations, matching the other action.* rows.

Prompt for AI agents
Check if this issue is valid — if so, understand the root cause and fix it. When an issue isn't valid or won't be fixed in this PR, reply in its thread with the reason and then resolve the thread. At Packages/macOS/CmuxNext/Sources/CmuxNextActions/Catalog/NotificationActionCatalog.swift, line 22:

<comment>The title key `action.agent.jumpToNextNeedingInput` is not in `ActionCatalog.xcstrings`, so it has no en/ja entries. Add it there with `en` and `ja` translations, matching the other `action.*` rows.</comment>

<file context>
@@ -17,6 +17,13 @@ nonisolated enum NotificationActionCatalog: ActionCatalogGroup {
             ),
+            ActionDescriptor(
+                id: "agent.jumpToNextNeedingInput",
+                title: String(localized: "action.agent.jumpToNextNeedingInput", defaultValue: "Go to Next Agent Needing Input", bundle: .module),
+                keywords: ["agent", "approval", "question", "needs input", "next"],
+                category: .notifications, symbol: "exclamationmark.bubble", surfaces: [.palette, .keyboard, .menu],
</file context>

// use the same eligible, currently observed chat lanes; never jump to a mere unread tab.
var lastNeedsInput: String?
registry.bind("agent.jumpToNextNeedingInput", run: { _ in
let chats = AgentPriorityChats.app

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P2: The new action can select cached .needsYou lanes from an offline or stale remote peer. Filter remote eligibility by a live, non-provisional machine snapshot and refuse or defer navigation when the owning peer is unavailable; otherwise the menu can open a nonexistent local session.

Prompt for AI agents
Check if this issue is valid — if so, understand the root cause and fix it. When an issue isn't valid or won't be fixed in this PR, reply in its thread with the reason and then resolve the thread. At Packages/macOS/CmuxNext/Sources/CmuxNextApp/SidebarSections/SidebarPriorityFeed.swift, line 52:

<comment>The new action can select cached `.needsYou` lanes from an offline or stale remote peer. Filter remote eligibility by a live, non-provisional machine snapshot and refuse or defer navigation when the owning peer is unavailable; otherwise the menu can open a nonexistent local session.</comment>

<file context>
@@ -45,5 +45,19 @@ extension SidebarPriorityFeed {
+        // use the same eligible, currently observed chat lanes; never jump to a mere unread tab.
+        var lastNeedsInput: String?
+        registry.bind("agent.jumpToNextNeedingInput", run: { _ in
+            let chats = AgentPriorityChats.app
+            let snapshot = chats.snapshot()
+            guard let id = AgentPriorityRanking.nextNeedingInput(after: lastNeedsInput, in: chats.entries(snapshot)),
</file context>

cliName: "notification show", mainMenu: .window
),
ActionDescriptor(
id: "agent.jumpToNextNeedingInput",

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P3: The new action adds palette, keyboard and menu surfaces, but plans/cmux-next/action-surfaces.json and the generated block in plans/cmux-next/actions.md are not regenerated. Run CMUX_UPDATE_ACTION_SURFACES=1 swift test --filter ActionSurfaceParityTests and commit the results, or the export freshness check will fail in CI.

Prompt for AI agents
Check if this issue is valid — if so, understand the root cause and fix it. When an issue isn't valid or won't be fixed in this PR, reply in its thread with the reason and then resolve the thread. At Packages/macOS/CmuxNext/Sources/CmuxNextActions/Catalog/NotificationActionCatalog.swift, line 21:

<comment>The new action adds palette, keyboard and menu surfaces, but `plans/cmux-next/action-surfaces.json` and the generated block in `plans/cmux-next/actions.md` are not regenerated. Run `CMUX_UPDATE_ACTION_SURFACES=1 swift test --filter ActionSurfaceParityTests` and commit the results, or the export freshness check will fail in CI.</comment>

<file context>
@@ -17,6 +17,13 @@ nonisolated enum NotificationActionCatalog: ActionCatalogGroup {
                 cliName: "notification show", mainMenu: .window
             ),
+            ActionDescriptor(
+                id: "agent.jumpToNextNeedingInput",
+                title: String(localized: "action.agent.jumpToNextNeedingInput", defaultValue: "Go to Next Agent Needing Input", bundle: .module),
+                keywords: ["agent", "approval", "question", "needs input", "next"],
</file context>

@teamleaderleo

Copy link
Copy Markdown
Collaborator Author

Review (codex gpt-6.1-sol xhigh, router-review): BLOCK at 7b1a6fa

BLOCK at 7b1a6fa

Visual verdict: no images; Leo tries the build

  1. [P1] [blocking] NotificationActionCatalog.swift:20-25 adds an action without CLI/context-menu surface declarations. ActionSurfaceParityTests therefore sees undeclared surfaces and check-action-surfaces.sh fails. Add the appropriate exemptions and focus classification.

  2. [P1] [blocking] Generated action exports were not regenerated. plans/cmux-next/actions.md:46 still reports 27 notification actions and 1,281 total, while this catalog now has 28 and 1,282. The generated-files freshness job will fail.

  3. [P1] [blocking] SidebarPriorityFeed.swift:51 introduces a new untyped registry.bind(... run:), which violates the repository’s action-wait guardrail. The handler also synchronously snapshots and ranks all local, Chief, and remote lanes on the main actor. Use the effect-based binding and preserve the action latency budget.

@teamleaderleo

Copy link
Copy Markdown
Collaborator Author

Awareness note from an agent lane that does not own this PR; it is not a review or a request to take the PR over.


Carried in #30104, which keeps this PR's commit and fixes the three blocking findings of its review at 7b1a6fa: the surface exemptions (focus move), the regenerated action exports, and a bindEffect handler that reads a waiting-session index instead of ranking every lane on the main actor. This PR stays open; it's yours to close.

teamleaderleo added a commit that referenced this pull request Nov 1, 2026
…5329) (carry of #28692) (#30104)

* fix(next): route Needs input menu to the next waiting agent (#5329)

Use ranked, snooze-aware acpmux lanes for both the displayed count and
navigation. Keep existing unread navigation unchanged and cover cycling,
removed asks, and mixed agent states.

* fix(next): Go to Next Agent Needing Input reads a waiting index, binds an effect, declares its surfaces

Carry of #28692 (review BLOCK at 7b1a6fa):
- agent.jumpToNextNeedingInput is a focus move: CLI and right-click menu
  exemptions (.focusMove) next to jumpToUnread, and the focus-action list.
- The handler binds with bindEffect and returns .done or a quiet refusal; no
  untyped run: bind.
- No ranking of every lane on the action's turn: AgentLaneStore keeps a
  `waiting` index (sessions at .input) on every write, and the watch's
  per-session change writes in place (`set`), so neither the action nor the
  menu bar's count builds the Priority rows. The pick sorts only the waiting
  chats (AgentPriorityRanking.needingInput / next).
- Title and refusal strings in the catalogs.

Sidebar-Look: no visual change
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Agent-Session: https://cmux.com/deeplink/agent?id=aid-63b9964940c20354b639

* fix(next): the needs-input jump lives in CmuxNextAgentLanes, its state on an instance

Sidebar-Look: no visual change
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Agent-Session: https://cmux.com/deeplink/agent?id=aid-63b9964940c20354b639

* fix(next): the needs-input jump adds no App lines

Sidebar-Look: no visual change
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Agent-Session: https://cmux.com/deeplink/agent?id=aid-63b9964940c20354b639

* chore(next): regenerate the action exports (regenerate-action-exports.sh, fleet step 106f9436ab56)

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Agent-Session: https://cmux.com/deeplink/agent?id=aid-63b9964940c20354b639

* fix(next): Needs input keeps blocked terminals in the count and the jump

Review of #30104 (BLOCK at ac743bc, P1): the menu bar's count had dropped
terminal programs waiting for input (OSC 7501 blocked records), which
StatusMapping.needsInput counted before. AgentNeedsInputJump.targets is now the
waiting agent chats, then every other tab of this Mac that needsInput; the
count and the action read the same list, and the action reveals a blocked
terminal's tab. Test: one blocked terminal and no waiting chat counts 1 and the
jump reveals it.

Sidebar-Look: no visual change
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Agent-Session: https://cmux.com/deeplink/agent?id=aid-63b9964940c20354b639

* fix(next): the jump's default needs-input test is not a public default argument

Sidebar-Look: no visual change
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Agent-Session: https://cmux.com/deeplink/agent?id=aid-63b9964940c20354b639

* chore(next): regenerate the action exports after the base merge (regenerate-action-exports.sh, fleet steps a854d59fb225, 72a3d1e14c88)

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Agent-Session: https://cmux.com/deeplink/agent?id=aid-63b9964940c20354b639

* chore(next): regenerate actions.md after the base merge (regenerate-action-exports.sh, fleet step 6f99994d3d6a)

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Agent-Session: https://cmux.com/deeplink/agent?id=aid-63b9964940c20354b639

---------

Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
Co-authored-by: cmux-bot[bot] <348531757+cmux-bot[bot]@users.noreply.github.com>
@teamleaderleo

Copy link
Copy Markdown
Collaborator Author

Superseded: carried with its authorship and merged in #30104 (494a262, at head 4ee3679).

This branch was previously deployed

1 inactive deployment
ci-routing-agent — 7b1a6fae Deployed Nov 1, 2026 by teamleaderleo via namespace autofix #10555
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

risk:normal Risk tier (docs/ci/risk-tiers.md)

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant