Skip to content

Route TUI actions through project service - #202

Merged
TraderSamwise merged 4 commits into
masterfrom
chore/tui-next-34
Jun 20, 2026
Merged

Route TUI actions through project service#202
TraderSamwise merged 4 commits into
masterfrom
chore/tui-next-34

Conversation

@TraderSamwise

@TraderSamwise TraderSamwise commented Jun 20, 2026

Copy link
Copy Markdown
Owner

Summary

  • route manual review requests through the project-service task API instead of the local task workflow writer
  • remove local fallback builders for dashboard orchestration targets and service/worktree overlay mutations
  • stop inbox cleanup from locally rebuilding Coordination state; notify and refresh service-backed Coordination instead

Verification

  • yarn typecheck
  • yarn lint
  • yarn vitest
  • yarn build
  • pre-push hook: yarn typecheck && yarn lint && yarn test

Summary by CodeRabbit

Release Notes

  • New Features

    • Review task assignments can now include additional metadata (assigner, review target, and iteration) for clearer review workflows.
  • Bug Fixes

    • Review requests now resolve and assign the correct reviewer role, with clear dashboard messaging when none is configured.
    • Clearing inbox items now triggers the proper dashboard refresh and re-rendering.
  • Changes

    • Service creation and worktree create/graveyard operations now require dashboard mode; non-dashboard actions show dashboard errors instead.
    • Orchestration route target selection is now loaded via project-service integration when in dashboard mode.

@vercel

vercel Bot commented Jun 20, 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 20, 2026 3:14pm

@coderabbitai

coderabbitai Bot commented Jun 20, 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 49 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 refill rate.

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, the refill rate gradually slows as usage increases. The highest same-day bursts are limited more strictly.

Please see our Fair Usage Limits Policy for further information.

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: e479ff4d-f7e8-40a8-a5cb-ea1651b903fa

📥 Commits

Reviewing files that changed from the base of the PR and between 339f04c and f1f53dd.

📒 Files selected for processing (4)
  • src/metadata-server.test.ts
  • src/multiplexer/dashboard-interaction.test.ts
  • src/multiplexer/dashboard-interaction.ts
  • src/orchestration-actions.ts
📝 Walkthrough

Walkthrough

Task assignment API contracts are extended with optional assigner, reviewOf, and iteration fields to track review metadata. Across five multiplexer files, all mutable operations (orchestration routing, service creation, review requests, worktree create/remove, inbox cleanup) are gated to require mode === "dashboard" and project-service connection. Local/desktop fallback paths are removed; non-dashboard callers receive an error and early return. Inbox cleanup replaces refreshNotificationEntries with metadata-server notification plus conditional coordination-screen refresh.

Changes

Dashboard-mode enforcement and review task metadata

Layer / File(s) Summary
Task assignment contract: add review metadata fields
src/project-api-contract.ts, src/orchestration-actions.ts, src/metadata-server.ts, src/metadata-server.test.ts
TaskAssignInput and AssignTaskInput interfaces gain optional assigner, reviewOf, and iteration fields. Review-type tasks now initialize task.assigner, task.reviewStatus = "pending", task.reviewOf, and task.iteration (defaulting to 1) during creation. Tests verify these fields round-trip through /tasks/assign request/response payloads.
Orchestration route picker: dashboard + project service requirement
src/multiplexer/dashboard-control.ts
showOrchestrationRoutePicker drops local option-building from team/session metadata; it now checks host.mode !== "dashboard" or missing getFromProjectService, shows "Failed to load orchestration targets" error and returns. When both are present, delegates to showOrchestrationRoutePickerFromService. Imports updated to remove unused config/team loaders and add endpoint/control-plane helpers.
Review request orchestration via project service
src/multiplexer/dashboard-interaction.ts, src/multiplexer/dashboard-interaction.test.ts
handleReviewRequest is rewritten: loads and validates team config, resolves reviewerRole from team role configuration (via reviewedBy or description-based fallback), generates git diff, and calls postToProjectService(PROJECT_API_ROUTES.tasks.assign, ...) with assigner/reviewOf/iteration metadata instead of the removed requestReview helper. Success uses result.task.assignee (fallback to computed role); errors are shown via showDashboardError; renderDashboard() moved to finally block. Two new tests cover the postToProjectService payload/UI flow and the non-dashboard service-creation error path.
Service creation overlay: dashboard-mode gating
src/multiplexer/dashboard-interaction.ts
Service input overlay Enter/Return handling now checks mode === "dashboard"; in non-dashboard mode shows "Service creation requires the project service." error and returns, removing the prior createService(...) fallback.
Worktree create/remove: dashboard-only via project service
src/multiplexer/worktrees.ts
handleWorktreeInputKey removes createDesktopWorktree fallback and shows error when not in dashboard mode; beginWorktreeRemoval removes graveyardDesktopWorktree execution and fails immediately when not in dashboard mode. finishWorktreeRemoval derives worktreeNavOrder from dashboardWorktreeGroupsCache instead of listWorktrees(), and fixes focused-worktree selection to focus last element when order length is > 0. Unused local-worktree helpers removed from imports.
Inbox cleanup: metadata notification + conditional coordination refresh
src/multiplexer/persistence-methods.ts, src/multiplexer/inbox-cleanup-runtime.test.ts
After detecting cleared items, cleanupInbox replaces refreshNotificationEntries with metadataServer.notifyChange and, when isDashboardScreen("coordination") is true, asynchronously calls refreshCoordinationFromService() then renderCurrentDashboardView, ignoring errors. Tests add dashboard stubs and assert those side effects via vi.waitFor.
Operation failures clear: inline payload refactor
src/multiplexer/dashboard-interaction.ts
The operationFailuresClear request is refactored to pass the request body as an inline object directly; post-request refresh/render and error handling remain unchanged.

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~50 minutes

Possibly related PRs

  • TraderSamwise/aimux#198: Aligns with the PR's introduction of assigner, reviewOf, and iteration fields in task-assignment contracts, extending shared task/review metadata handling across app workflows and orchestration actions.
  • TraderSamwise/aimux#171: Overlaps directly with the inbox-cleanup flow changes—specifically the metadata-server notification and coordination dashboard refresh logic that replace the prior refreshNotificationEntries call.

Poem

🐇 No more desktop detours, the service rules the day,
Each worktree and review must go the dashboard way.
Old fallback paths are swept into the graveyard's bin,
With assigner, reviewOf, the metadata flows in,
One mode to rule them all — the rabbit hops with glee! 🗂️

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 0.00% 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 directly and accurately reflects the main objective of the pull request: routing TUI actions through the project service instead of using local implementations.
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 chore/tui-next-34

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

@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: 6

Caution

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

⚠️ Outside diff range comments (1)
src/multiplexer/worktrees.ts (1)

389-397: ⚠️ Potential issue | 🟡 Minor | ⚡ Quick win

Keep focus on the remaining worktree after removing the last item.

When the removed worktree was the last of two, oldIdx is now outside the new one-item nav order, and the length > 1 branch sets focusedWorktreePath to undefined even though one worktree remains.

Proposed fix
-    } else if (host.dashboardState.worktreeNavOrder.length > 1) {
+    } else if (host.dashboardState.worktreeNavOrder.length > 0) {
       host.dashboardState.focusedWorktreePath =
         host.dashboardState.worktreeNavOrder[host.dashboardState.worktreeNavOrder.length - 1];
🤖 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 `@src/multiplexer/worktrees.ts` around lines 389 - 397, The logic for
determining the focused worktree after removal has a boundary condition error.
When a worktree is removed and oldIdx becomes out of bounds, the second
condition checks if worktreeNavOrder.length > 1 before focusing on the remaining
worktree. However, when exactly one worktree remains (length == 1), this
condition fails and focusedWorktreePath is set to undefined instead of focusing
on the last remaining worktree. Change the condition from length > 1 to length >
0 in the else-if statement to ensure that whenever at least one worktree remains
in the worktreeNavOrder array, the focus is set to the last worktree in that
array rather than being undefined.
🤖 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/dashboard-control.ts`:
- Around line 571-574: In the function showOrchestrationRoutePicker, the guard
condition checking host.mode and host.getFromProjectService is currently placed
after calls to getSelectedDashboardSessionForActions and access to
host.dashboardState.focusedWorktreePath. Move the entire if statement guard to
the beginning of the function, before any operations that depend on dashboard
state being initialized, so that the validation happens first and prevents
accessing uninitialized state when the guard conditions fail.

In `@src/multiplexer/dashboard-interaction.test.ts`:
- Around line 7-30: The test "requests reviews through the project service"
assumes a default coder to reviewer role mapping, but the handleReviewRequest
method calls loadTeamConfig() which reads from actual project or global
configuration files and can change the assignee. Mock the loadTeamConfig
function or team config dependency in the test setup to ensure the role mapping
is controlled and deterministic, so the test always uses the expected "coder →
reviewer" mapping regardless of what configuration files exist on the system.

In `@src/multiplexer/dashboard-interaction.ts`:
- Around line 907-920: The git diff command in the try block is executing in the
multiplexer process's working directory instead of the session's worktree
directory, which can attach the wrong diff to the review request. Modify the
execSync call to use the cwd option and pass the worktreePath obtained from
this.sessionWorktreePaths?.get?.(session.id) to ensure the git diff HEAD command
runs in the correct session worktree directory. Only execute the command if the
worktreePath is available.
- Around line 885-899: The code does not validate the loaded team configuration
before accessing its properties, which can cause runtime errors if the config is
malformed and lacks the required `roles` property or if role configs are missing
expected properties like `description` or `canEdit`. Add validation after the
loadTeamConfig call to ensure the returned team object has a valid roles
property and that each role config has the necessary properties (description,
canEdit, reviewedBy) before attempting to dereference them in the roleConfig
assignment and the filter and find operations. If validation fails, return the
default team config as a fallback to prevent dereferencing undefined properties.

In `@src/multiplexer/inbox-cleanup-runtime.test.ts`:
- Around line 52-53: The test only waits for the refreshCoordinationFromService
call to complete, but renderCurrentDashboardView is invoked asynchronously in a
.then() continuation after that promise resolves, creating a race condition.
Wrap the expectation for host.renderCurrentDashboardView.toHaveBeenCalledOnce()
in a vi.waitFor() call to ensure the test waits for the render side effect to
actually execute before asserting on it, similar to how the
refreshCoordinationFromService expectation is already wrapped.

In `@src/multiplexer/worktrees.ts`:
- Around line 345-348: The finishWorktreeRemoval function call in the host.mode
!== "dashboard" condition block is emitting a generic error message that
overwrites the specific "Worktree graveyard requires the project service." error
shown via showDashboardError. To fix this, pass the specific error message as
stderr or error details to the finishWorktreeRemoval(host, 1) call so that the
meaningful error message is preserved instead of being replaced by the generic
"worktree graveyard failed with code 1" message.

---

Outside diff comments:
In `@src/multiplexer/worktrees.ts`:
- Around line 389-397: The logic for determining the focused worktree after
removal has a boundary condition error. When a worktree is removed and oldIdx
becomes out of bounds, the second condition checks if worktreeNavOrder.length >
1 before focusing on the remaining worktree. However, when exactly one worktree
remains (length == 1), this condition fails and focusedWorktreePath is set to
undefined instead of focusing on the last remaining worktree. Change the
condition from length > 1 to length > 0 in the else-if statement to ensure that
whenever at least one worktree remains in the worktreeNavOrder array, the focus
is set to the last worktree in that array rather than being undefined.
🪄 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: 5b3e933f-cd07-4cc7-8e6b-a113b45051a3

📥 Commits

Reviewing files that changed from the base of the PR and between 178e7a1 and bd1780b.

📒 Files selected for processing (6)
  • src/multiplexer/dashboard-control.ts
  • src/multiplexer/dashboard-interaction.test.ts
  • src/multiplexer/dashboard-interaction.ts
  • src/multiplexer/inbox-cleanup-runtime.test.ts
  • src/multiplexer/persistence-methods.ts
  • src/multiplexer/worktrees.ts

Comment thread src/multiplexer/dashboard-control.ts
Comment thread src/multiplexer/dashboard-interaction.test.ts
Comment thread src/multiplexer/dashboard-interaction.ts Outdated
Comment thread src/multiplexer/dashboard-interaction.ts Outdated
Comment thread src/multiplexer/inbox-cleanup-runtime.test.ts Outdated
Comment thread src/multiplexer/worktrees.ts

@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

🤖 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/orchestration-actions.ts`:
- Around line 70-75: The assignment of task.iteration in the review task type
block directly uses input.iteration without validation, allowing invalid values
like zero, negative numbers, or non-integers to be persisted. Add validation
logic before the assignment to ensure input.iteration is a positive integer, and
if invalid or missing, default to 1 instead. This validation should occur within
the if (task.type === "review") block before assigning to task.iteration to
prevent downstream issues with the iteration > 5 safety cutoff check.
🪄 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: 733d0f8e-b32a-450d-a12c-036dfc8758dc

📥 Commits

Reviewing files that changed from the base of the PR and between bd1780b and 339f04c.

📒 Files selected for processing (9)
  • src/metadata-server.test.ts
  • src/metadata-server.ts
  • src/multiplexer/dashboard-control.ts
  • src/multiplexer/dashboard-interaction.test.ts
  • src/multiplexer/dashboard-interaction.ts
  • src/multiplexer/inbox-cleanup-runtime.test.ts
  • src/multiplexer/worktrees.ts
  • src/orchestration-actions.ts
  • src/project-api-contract.ts
✅ Files skipped from review due to trivial changes (1)
  • src/project-api-contract.ts
🚧 Files skipped from review as they are similar to previous changes (4)
  • src/multiplexer/inbox-cleanup-runtime.test.ts
  • src/multiplexer/dashboard-interaction.test.ts
  • src/multiplexer/worktrees.ts
  • src/multiplexer/dashboard-control.ts

Comment thread src/orchestration-actions.ts
@TraderSamwise
TraderSamwise merged commit ba69968 into master Jun 20, 2026
3 checks passed
@coderabbitai coderabbitai Bot mentioned this pull request Jun 26, 2026
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