Skip to content

Tighten TUI API control paths - #244

Merged
TraderSamwise merged 3 commits into
masterfrom
fix/tui-api-cleanup-next-3
Jun 24, 2026
Merged

Tighten TUI API control paths#244
TraderSamwise merged 3 commits into
masterfrom
fix/tui-api-cleanup-next-3

Conversation

@TraderSamwise

@TraderSamwise TraderSamwise commented Jun 24, 2026

Copy link
Copy Markdown
Owner

Summary

  • Mark Coordination thread reads as the dashboard user while preserving agent activation targets
  • Suppress duplicate Coordination lifecycle mutations while a thread action is already in flight
  • Stop tmux prefix navigation from using stale statusline.json as a live target source; rely on tmux window metadata
  • Use the shared project API route contract for desktop-state refreshes and remove stale fallback wording

Verification

  • yarn vitest --run src/tmux/control-script.test.ts src/multiplexer/notifications.test.ts src/multiplexer/dashboard-model-service.test.ts
  • yarn vitest --run
  • yarn typecheck
  • yarn lint
  • yarn build

Summary by CodeRabbit

  • New Features

    • Improved coordination and thread actions so repeated requests won’t trigger duplicate updates while a previous action is still in progress.
    • “Mark as seen” now consistently applies to the current dashboard user.
  • Bug Fixes

    • Local navigation in tmux now avoids using stale statusline data and more reliably reports when no valid target is available.
    • Team-related switching and thread workflows now behave more consistently across updated session metadata.

@vercel

vercel Bot commented Jun 24, 2026

Copy link
Copy Markdown

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Actions Updated (UTC)
app Ready Ready Preview, Comment Jun 24, 2026 11:28am

@coderabbitai

coderabbitai Bot commented Jun 24, 2026

Copy link
Copy Markdown

Review Change Stack

Warning

Review limit reached

@TraderSamwise, we couldn't start this review because you've reached your PR review rate limit.

More reviews will be available in 29 minutes and 58 seconds. Learn how PR review limits work.

Your organization has used up its prepaid credits, and credit purchases are no longer available. Enable the review add-on in the billing tab to keep reviews running — you're only billed for reviews past your plan's rate limits ($0.25/file).

⌛ How to resolve this issue?

After more reviews become available, a review can be triggered using the @coderabbitai review command as a PR comment. Alternatively, push new commits to this PR.

To avoid repeated limits, reduce automatic review volume by pausing incremental auto-reviews earlier, using label-based review opt-in, excluding WIP or generated PR titles, or requesting reviews manually when the PR is ready. If your team needs uninterrupted high-volume reviews, an organization admin can enable usage-based credits.

🚦 How do rate limits work?

CodeRabbit enforces per-developer PR review limits for each organization. Most developers receive the normal plan review availability.

For paid Pro and Pro+ PR reviews, CodeRabbit uses adaptive limits for sustained high-volume activity. When a developer's recent PR review activity reaches the 95th percentile or higher among CodeRabbit users, additional reviews become available more gradually as earlier reviews age out of the rolling window.

Please see our Fair Usage Limits Policy for further information.

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: 64ff6c67-80b5-4770-86b7-4b510a5b5b18

📥 Commits

Reviewing files that changed from the base of the PR and between 09055cb and edd8096.

📒 Files selected for processing (7)
  • app/lib/api.test.ts
  • scripts/tmux-control.sh
  • src/multiplexer/coordination.ts
  • src/multiplexer/notifications.test.ts
  • src/multiplexer/subscreens.test.ts
  • src/project-api-contract.ts
  • src/tmux/control-script.test.ts
📝 Walkthrough

Walkthrough

Removes the resolve_local_target_from_statusline function and its statusline.json variable from tmux-control.sh, routing all navigation target resolution exclusively through resolve_local_target_from_tmux_metadata (also dropping its worktree-path candidate filter). In the TypeScript multiplexer, adds a deduplication helper for in-flight thread lifecycle actions and fixes mark-seen to always use sessionId: "user". The desktop-state endpoint is changed to use a named route constant.

Changes

tmux: Statusline Resolver Removal and Metadata-Only Navigation

Layer / File(s) Summary
Remove statusline resolver, update metadata resolver and fallback_local_control
scripts/tmux-control.sh
Deletes statusline_json setup, removes entire resolve_local_target_from_statusline function, drops the is_same_or_child_path worktree-path candidate filter from resolve_local_target_from_tmux_metadata, and updates fallback_local_control to call only the metadata resolver for all next/prev/attention/window/team actions.
Test updates: no-target outcomes and enriched team metadata fixtures
src/tmux/control-script.test.ts
Renames tests to reflect stale-statusline semantics; changes next/prev/attention/window assertions to expect "no local tmux target available" with no link-window calls; extends windowMetadata fixtures for reviewer/coder/other with full team objects (teamId, parentSessionId, role, order).

Multiplexer: Thread Workflow Deduplication, Mark-seen Fix, and API Route Constant

Layer / File(s) Summary
runThreadWorkflowAction dedup helper, dispatchThreadItem rewire, mark-seen sessionId fix
src/multiplexer/coordination.ts, src/coordination-model.ts
Introduces runThreadWorkflowAction that stores pending action keys on host.coordinationPendingThreadActions, skips duplicate calls for the same key, and clears the key in a finally block. Routes all lifecycle key branches (A/c/b/o/x, P/J/E) through this helper. Changes mark-seen to use sessionId: "user" unconditionally. Updates one documentation comment.
Replace hard-coded desktop-state endpoint
src/multiplexer/dashboard-model.ts
Imports PROJECT_API_ROUTES and replaces "/desktop-state" literal with PROJECT_API_ROUTES.desktopState in refreshDashboardModelFromService.
Test coverage: mark-seen sessionId, dedup behavior, fixture updates
src/multiplexer/notifications.test.ts, src/multiplexer/subscreens.test.ts
Enriches taskWorklistItem fixture with participants/owner, adds activateDashboardEntry mock to workflowHost, adds tests for mark-seen sessionId: "user" and repeated-keypress deduplication. Updates subscreens test expected sessionId from "teammate-1" to "user".

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~25 minutes

Possibly related PRs

  • TraderSamwise/aimux#5: Directly modifies resolve_local_target_from_statusline's "team" filtering in scripts/tmux-control.sh, the exact function this PR deletes entirely.
  • TraderSamwise/aimux#210: Modifies resolve_local_target_from_tmux_metadata's is_same_or_child_path worktree-path filtering logic, which this PR removes.
  • TraderSamwise/aimux#211: Modifies fallback_local_control's next/prev/attention/window flow using tmux metadata for window switching, the same control path this PR rewires.

Poem

🐇 Snip snip, the statusline's gone today,
No stale JSON to lead my hops astray.
One metadata path, clean and true,
The threads won't double-fire on cue.
sessionId: "user" — that's me, hooray! 🎉

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 8.33% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title is concise and broadly matches the main changes around TUI control paths, tmux navigation, and API coordination.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch fix/tui-api-cleanup-next-3

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

@TraderSamwise

Copy link
Copy Markdown
Owner Author

@coderabbitai review

@coderabbitai

coderabbitai Bot commented Jun 24, 2026

Copy link
Copy Markdown
✅ Action performed

Review finished.

Note: CodeRabbit is an incremental review system and does not re-review already reviewed commits. This command is applicable only when automatic reviews are paused.

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

Actionable comments posted: 1

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
scripts/tmux-control.sh (1)

645-648: 🎯 Functional Correctness | 🟠 Major | ⚡ Quick win

Defer worktree filtering until after team resolution.

Line 645 filters candidates by worktreePath before the team branch. That can drop a valid parent/teammate when team members have different worktrees, and Line 800 no longer has the statusline resolver as a fallback. Resolve team from the full metadata set, then apply worktree scoping only for next|prev|attention|window.

🐛 Proposed direction
-items = [item for item in items if item.get("alive") or item.get("windowId") == current_window_id]
+items = [item for item in items if item.get("alive") or item.get("windowId") == current_window_id]
+current = next((item for item in items if item.get("windowId") == current_window_id), None)
+
+if action != "team":
+    if current_worktree:
+        items = [item for item in items if item.get("worktreePath") == current_worktree]
+    else:
+        items = [item for item in items if is_same_or_child_path(current_path, item.get("worktreePath") or "")]
-log("items=" + repr([
+log("items=" + repr([
     f"{item.get('windowId')}:{item.get('sessionId')}:{item.get('kind')}:{(item.get('team') or {}).get('parentSessionId') or '-'}:{item.get('statusText') or '-'}:{'live' if item.get('alive') else 'dead'}"
     for item in items
 ]))
 ...
-current = next((item for item in items if item.get("windowId") == current_window_id), None)
 if action == "team":

As per coding guidelines, “For live-pane prefix shortcuts like ctrl-a n/p, treat the tmux control path as the default source of truth.”

Also applies to: 794-800

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@scripts/tmux-control.sh` around lines 645 - 648, The candidate filtering in
the tmux control flow is happening too early, before `team` is resolved, which
can remove valid teammates/parents and break the statusline resolver fallback.
Update the logic around the metadata selection so `team` is computed from the
full candidate set first, then apply `worktreePath` scoping only for the `next`,
`prev`, `attention`, and `window` paths in the tmux control handling. Use the
existing `current_worktree`, `current_path`, and `is_same_or_child_path` logic
to locate the relevant selection code and keep the prefix shortcut path as the
default source of truth.

Source: Coding guidelines

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@src/multiplexer/coordination.ts`:
- Around line 202-204: The `mutateDashboardApi` call in `coordination.ts` is
using the wrong payload field for `PROJECT_API_ROUTES.threads.markSeen`; update
the body to match the shared `/threads/mark-seen` contract used by
`src/main.ts`, replacing the `sessionId` field with `session` in this branch.
Keep the fix localized to the mark-seen call so the dashboard path sends the
same payload shape as the shared API.

---

Outside diff comments:
In `@scripts/tmux-control.sh`:
- Around line 645-648: The candidate filtering in the tmux control flow is
happening too early, before `team` is resolved, which can remove valid
teammates/parents and break the statusline resolver fallback. Update the logic
around the metadata selection so `team` is computed from the full candidate set
first, then apply `worktreePath` scoping only for the `next`, `prev`,
`attention`, and `window` paths in the tmux control handling. Use the existing
`current_worktree`, `current_path`, and `is_same_or_child_path` logic to locate
the relevant selection code and keep the prefix shortcut path as the default
source of truth.
🪄 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: defaults

Review profile: CHILL

Plan: Pro

Run ID: 5a5a1c46-567a-4579-86c5-6217ad7140bd

📥 Commits

Reviewing files that changed from the base of the PR and between db6e786 and 09055cb.

📒 Files selected for processing (7)
  • scripts/tmux-control.sh
  • src/coordination-model.ts
  • src/multiplexer/coordination.ts
  • src/multiplexer/dashboard-model.ts
  • src/multiplexer/notifications.test.ts
  • src/multiplexer/subscreens.test.ts
  • src/tmux/control-script.test.ts

Comment thread src/multiplexer/coordination.ts Outdated
@TraderSamwise

Copy link
Copy Markdown
Owner Author

@coderabbitai review

@coderabbitai

coderabbitai Bot commented Jun 24, 2026

Copy link
Copy Markdown
✅ Action performed

Review finished.

Note: CodeRabbit is an incremental review system and does not re-review already reviewed commits. This command is applicable only when automatic reviews are paused.

@TraderSamwise

Copy link
Copy Markdown
Owner Author

Fixed the outside-diff review note in edd8096: tmux team navigation now resolves against the full live metadata set before same-worktree filtering is applied to ordinary next/prev/attention navigation. Added a regression covering cross-worktree teammate jumps.

@TraderSamwise

Copy link
Copy Markdown
Owner Author

@coderabbitai review

@coderabbitai

coderabbitai Bot commented Jun 24, 2026

Copy link
Copy Markdown
✅ Action performed

Review finished.

Note: CodeRabbit is an incremental review system and does not re-review already reviewed commits. This command is applicable only when automatic reviews are paused.

@TraderSamwise
TraderSamwise merged commit 0c43f7a into master Jun 24, 2026
3 checks passed
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