Skip to content

Adopt lifecycle transitions in app clients#348

Merged
TraderSamwise merged 3 commits into
masterfrom
chore/core-sidecar-next-73
Jul 6, 2026
Merged

Adopt lifecycle transitions in app clients#348
TraderSamwise merged 3 commits into
masterfrom
chore/core-sidecar-next-73

Conversation

@TraderSamwise

@TraderSamwise TraderSamwise commented Jul 6, 2026

Copy link
Copy Markdown
Owner

Summary

  • add a shared app lifecycle transition overlay for desktop-state
  • record project-service transition envelopes from app agent, service, worktree, graveyard, and teammate lifecycle controls
  • update north-star docs/tracker for app lifecycle adoption

Verification

  • yarn verify
  • yarn verify:app
  • yarn verify:north-star
  • yarn build

Summary by CodeRabbit

  • New Features

    • Improved lifecycle handling across dashboard, chat, service, worktree, and teammate screens so actions now reflect more reliable in-app status updates.
    • Added smarter state reconciliation so the UI can show pending/optimistic changes until fresh data confirms the final result.
  • Bug Fixes

    • Reduced stale or out-of-date views after actions like create, remove, stop, resume, migrate, rename, resurrect, and delete.
    • Desktop, sidebar, and detail views now stay in sync more consistently after lifecycle changes.

@vercel

vercel Bot commented Jul 6, 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 Jul 6, 2026 11:49pm

@coderabbitai

coderabbitai Bot commented Jul 6, 2026

Copy link
Copy Markdown

Review Change Stack

Warning

Review limit reached

You’ve reached a temporary PR review limit under our Fair Usage Limits Policy.

Your recent review volume is higher than typical usage, so adaptive limits are currently applied.

Next review available in: 30 minutes

Enable usage-based reviews in Billing to review now. Otherwise, wait until the next included review is available.
You're only billed for reviews past your plan's rate limits ($0.25/file).

How can I continue?

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 reviews.

How do review 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 refer docs for additional details.

Review details
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: e8926a87-1f34-420b-9e3f-6e41bed9fdc7

📥 Commits

Reviewing files that changed from the base of the PR and between 7712764 and af4e298.

📒 Files selected for processing (8)
  • app/components/WorktreeDashboard.tsx
  • app/components/agent-actions.tsx
  • app/components/service-actions.tsx
  • app/components/worktree-management-panel.tsx
  • app/lib/desktop-state.ts
  • app/stores/desktopState.test.ts
  • app/stores/lifecycleTransitions.test.ts
  • app/stores/lifecycleTransitions.ts
📝 Walkthrough

Walkthrough

Adds a Jotai-based lifecycle transition store (app/stores/lifecycleTransitions.ts) that records, overlays, and settles project lifecycle transitions onto DesktopState, integrated into desktopState.ts. Threads a new projectPath prop through dashboard, sidebar, and screen components, and updates agent/service/worktree/teammate/graveyard action handlers to record transitions after API calls. Updates related documentation.

Changes

Project Lifecycle Transition Recording

Layer / File(s) Summary
Lifecycle transition store and desktop-state integration
app/stores/lifecycleTransitions.ts, app/stores/lifecycleTransitions.test.ts, app/stores/desktopState.ts
New atom family stores per-project transitions; overlay/settlement logic applies pending transitions onto DesktopState; desktopStateFamily, applyDesktopStateSuccessAtom, and clearDesktopStateResourceAtom are wired to project, settle, and clear transitions; covered by a new test suite.
Threading projectPath through UI components
app/components/WorktreeDashboard.tsx, app/components/ProjectSidebar.tsx, app/components/screens/AgentChatScreen.tsx, app/components/screens/ServiceDetailScreen.tsx
AgentRow, ServiceRow, WorktreeCard, WorktreeList, ServiceDetailBody, and dashboard/screen components pass a new projectPath prop down to action/panel components.
Agent action transition recording
app/components/agent-actions.tsx, app/components/agent-create-panel.tsx, app/components/agent-management-panel.tsx
AgentActions, AgentCreatePanel, and AgentManagementPanel require projectPath, capture action responses, and record transitions with label/tool/worktreePath metadata for spawn, rename, migrate, and other actions.
Service and worktree action transition recording
app/components/service-actions.tsx, app/components/worktree-management-panel.tsx
ServiceActions and WorktreeManagementPanel record transitions after create/remove/stop operations using response data and entity metadata.
Teammate and graveyard transition recording
app/components/teammate-panel.tsx, app/app/(main)/(tabs)/(dashboard)/graveyard.tsx
TeammatePanel adds a runLifecycleMutation wrapper used by create/stop/resume/kill handlers; graveyard handlers record transitions for resurrect and delete operations on agents and worktrees.
Documentation updates
docs/core-sidecar-north-star.md, docs/north-star-completion-tracker.md
Docs clarify transition settlement semantics, update TUI transition stability status, and add app adoption notes.

Estimated code review effort: 4 (Complex) | ~60 minutes

Sequence Diagram(s)

sequenceDiagram
  participant User
  participant ActionComponent as Action Component (e.g. AgentActions)
  participant API as Backend API
  participant RecordAtom as recordProjectLifecycleTransitionAtom
  participant DesktopStateStore as desktopStateFamily

  User->>ActionComponent: trigger action (resume, spawn, rename, remove)
  ActionComponent->>API: call mutation (e.g. spawnAgent)
  API-->>ActionComponent: response with transition data
  ActionComponent->>RecordAtom: recordTransition(projectPath, transition, metadata)
  RecordAtom->>DesktopStateStore: overlay transition onto projected state
  DesktopStateStore-->>User: render optimistic state
  Note over API,DesktopStateStore: fresh API-backed state later arrives
  API->>DesktopStateStore: applyDesktopStateSuccessAtom
  DesktopStateStore->>RecordAtom: settle matching transitions
  DesktopStateStore-->>User: render settled state
Loading

Possibly related PRs

  • TraderSamwise/aimux#3: Introduced the action/worktree/chat components (service-actions.tsx, agent-actions.tsx, graveyard.tsx) that this PR extends with lifecycle transition recording.
  • TraderSamwise/aimux#40: Fixes the same graveyard resurrect/delete worktree runtime behavior that this PR's graveyard.tsx handlers now record transitions for.
  • TraderSamwise/aimux#264: Introduced the route-scoped projectPath plumbing across graveyard.tsx, WorktreeDashboard.tsx, AgentChatScreen.tsx, and ServiceDetailScreen.tsx that this PR builds upon.
🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title clearly summarizes the main change: adopting lifecycle transitions across app clients.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
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.
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch chore/core-sidecar-next-73

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

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

🧹 Nitpick comments (3)
app/stores/lifecycleTransitions.test.ts (1)

44-196: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick win

Add coverage for graveyard.worktree.resurrect and service.create overlay behavior.

The suite covers agent resume/spawn overlays, the full settle lifecycle for agent resume, worktree create/remove, and service stop, but doesn't exercise graveyard.worktree.resurrect or service.create/service.resume optimistic-creation. Both of these turned out to have gaps in overlayWorktreeTransition/overlayServiceTransition (see review on lifecycleTransitions.ts); a test mirroring the existing "adds optimistic agent rows" case for these operations would have caught this and prevents regression once fixed.

🤖 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 `@app/stores/lifecycleTransitions.test.ts` around lines 44 - 196, Add test
coverage in lifecycleTransitions.test.ts for the missing optimistic overlay
paths in applyProjectLifecycleTransitionsToDesktopState, specifically
graveyard.worktree.resurrect and service.create/service.resume. Mirror the
existing “adds optimistic agent rows” and “overlays service transitions” cases
by asserting overlayWorktreeTransition and overlayServiceTransition project the
expected optimistic state onto stale desktopState, including pending/optimistic
flags and the correct created/resurrected worktree or service fields.
app/stores/lifecycleTransitions.ts (1)

130-145: 🎯 Functional Correctness | 🔵 Trivial | ⚡ Quick win

overlayServiceTransition never creates an optimistic row for new services.

Unlike overlayAgentTransition (which pushes an optimistic session via shouldCreateOptimisticAgent) and overlayWorktreeTransition (which pushes an optimistic worktree for worktree.create), this function early-returns when index < 0 (Line 138) for every operation, including service.create. A newly created service that hasn't yet appeared in a fresh desktop-state fetch gets no optimistic/pending row at all, unlike agents and worktrees.

🔧 Proposed fix: add optimistic creation for service.create
 function overlayServiceTransition(
   services: DesktopService[],
   record: AppLifecycleTransitionRecord,
 ): void {
   const serviceId = record.transition.targetId;
   if (!serviceId) return;
   const index = services.findIndex((service) => service.id === serviceId);
   const pendingAction = servicePendingAction(record.transition.operation);
-  if (!pendingAction || index < 0) return;
-  services[index] = {
-    ...services[index],
-    status: "offline",
-    pendingAction,
-    optimistic: true,
-  };
+  if (!pendingAction) return;
+  if (index >= 0) {
+    services[index] = {
+      ...services[index],
+      status: "offline",
+      pendingAction,
+      optimistic: true,
+    };
+    return;
+  }
+  if (record.transition.operation !== "service.create") return;
+  services.push({
+    id: serviceId,
+    label: record.label ?? serviceId,
+    worktreePath: record.worktreePath,
+    status: "offline",
+    pendingAction,
+    optimistic: true,
+  });
 }
🤖 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 `@app/stores/lifecycleTransitions.ts` around lines 130 - 145,
`overlayServiceTransition` currently only updates existing entries in `services`
and returns when the service is missing, so `service.create` never shows an
optimistic row. Update the logic in `overlayServiceTransition` to mirror
`overlayAgentTransition`/`overlayWorktreeTransition`: detect when
`record.transition.operation` is `service.create`, and if `findIndex` returns
`-1`, append a new optimistic `DesktopService` entry with the pending action and
offline status instead of returning early.
app/components/agent-actions.tsx (1)

65-93: 📐 Maintainability & Code Quality | 🔵 Trivial | 🏗️ Heavy lift

Consider extracting the shared runAction/transition-recording wrapper.

The same busy/error/recordTransition pattern is repeated near-verbatim in service-actions.tsx, agent-management-panel.tsx (as runLifecycleAction), and worktree-management-panel.tsx. A shared hook (e.g. useLifecycleAction(projectPath)) would reduce duplication and centralize fixes (such as label/worktreePath overlay semantics) in one place instead of four.

🤖 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 `@app/components/agent-actions.tsx` around lines 65 - 93, The busy/error
handling and recordTransition wrapper in runAction is duplicated across multiple
components, so centralize it into a shared hook or helper such as
useLifecycleAction(projectPath). Move the common async action flow, transition
recording, and refresh logic out of agent-actions.tsx and reuse it from the
matching implementations in service-actions.tsx, agent-management-panel.tsx
(runLifecycleAction), and worktree-management-panel.tsx, keeping the existing
opts and onKilled behavior configurable.
🤖 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 `@app/components/agent-management-panel.tsx`:
- Around line 81-97: In the optimistic overlay path for existing sessions, the
agent.rename handling in lifecycleTransitions should also update the session
label, not just mark it pending. Adjust the existing-session branch so the
renamed value from record.label is copied onto the session immediately, using
the existing recordTransition flow and the session/record handling in
lifecycleTransitions to keep the UI in sync before the next desktop-state
refresh.

In `@app/stores/lifecycleTransitions.ts`:
- Around line 147-167: overlayWorktreeTransition currently treats only
"worktree.create" as an optimistic pending update, so
"graveyard.worktree.resurrect" falls into the removing path or no-ops when
absent. Update overlayWorktreeTransition to handle
"graveyard.worktree.resurrect" the same way as creation by marking the matching
DesktopWorktree as pending or creating a pending entry when missing, and keep
the default branch for true removals only. Use the existing
overlayWorktreeTransition and isWorktreeTransitionSettled behavior as the guide,
similar to how overlayAgentTransition handles "graveyard.agent.resurrect".
- Around line 35-59: recordProjectLifecycleTransitionAtom currently ignores
terminal phases like succeeded/failed, which leaves stale optimistic entries
behind for the same operationId. Update the atom to remove any existing record
matching input.transition.operationId when a terminal update arrives, while
keeping the current behavior for ACTIVE_PHASES. Also add a timeout-based
fallback using startedAt/updatedAt in the lifecycle record or transition data so
entries can be pruned even when isTransitionSettled never becomes true.

---

Nitpick comments:
In `@app/components/agent-actions.tsx`:
- Around line 65-93: The busy/error handling and recordTransition wrapper in
runAction is duplicated across multiple components, so centralize it into a
shared hook or helper such as useLifecycleAction(projectPath). Move the common
async action flow, transition recording, and refresh logic out of
agent-actions.tsx and reuse it from the matching implementations in
service-actions.tsx, agent-management-panel.tsx (runLifecycleAction), and
worktree-management-panel.tsx, keeping the existing opts and onKilled behavior
configurable.

In `@app/stores/lifecycleTransitions.test.ts`:
- Around line 44-196: Add test coverage in lifecycleTransitions.test.ts for the
missing optimistic overlay paths in
applyProjectLifecycleTransitionsToDesktopState, specifically
graveyard.worktree.resurrect and service.create/service.resume. Mirror the
existing “adds optimistic agent rows” and “overlays service transitions” cases
by asserting overlayWorktreeTransition and overlayServiceTransition project the
expected optimistic state onto stale desktopState, including pending/optimistic
flags and the correct created/resurrected worktree or service fields.

In `@app/stores/lifecycleTransitions.ts`:
- Around line 130-145: `overlayServiceTransition` currently only updates
existing entries in `services` and returns when the service is missing, so
`service.create` never shows an optimistic row. Update the logic in
`overlayServiceTransition` to mirror
`overlayAgentTransition`/`overlayWorktreeTransition`: detect when
`record.transition.operation` is `service.create`, and if `findIndex` returns
`-1`, append a new optimistic `DesktopService` entry with the pending action and
offline status instead of returning early.
🪄 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: b3ef27b0-2251-4356-9b15-c5506e228f10

📥 Commits

Reviewing files that changed from the base of the PR and between 169f680 and 7712764.

📒 Files selected for processing (16)
  • app/app/(main)/(tabs)/(dashboard)/graveyard.tsx
  • app/components/ProjectSidebar.tsx
  • app/components/WorktreeDashboard.tsx
  • app/components/agent-actions.tsx
  • app/components/agent-create-panel.tsx
  • app/components/agent-management-panel.tsx
  • app/components/screens/AgentChatScreen.tsx
  • app/components/screens/ServiceDetailScreen.tsx
  • app/components/service-actions.tsx
  • app/components/teammate-panel.tsx
  • app/components/worktree-management-panel.tsx
  • app/stores/desktopState.ts
  • app/stores/lifecycleTransitions.test.ts
  • app/stores/lifecycleTransitions.ts
  • docs/core-sidecar-north-star.md
  • docs/north-star-completion-tracker.md

Comment thread app/components/agent-management-panel.tsx
Comment thread app/stores/lifecycleTransitions.ts Outdated
Comment thread app/stores/lifecycleTransitions.ts
@TraderSamwise

Copy link
Copy Markdown
Owner Author

Independent review follow-up fixed in af4e298:

  • Agent action controls now disable while session.pendingAction is present, preventing duplicate lifecycle mutations during reconciliation.
  • Worktree pending/removing flags now survive groupByWorktree, render as settling chips, and are excluded from the removable-worktree list until fresh desktop-state settles them.
  • The graveyard worktree resurrect finding overlaps CodeRabbit and is fixed in the same commit.

@TraderSamwise
TraderSamwise merged commit 47acd66 into master Jul 6, 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