Repository navigation
Conversation
|
No actionable comments were generated in the recent review. 🎉 ℹ️ Recent review info⚙️ Run configurationConfiguration used: defaults Review profile: CHILL Plan: Pro Plus Run ID: 📒 Files selected for processing (1)
📝 WalkthroughWalkthroughThis PR adds persistent subworkspace hierarchy and delegation modes across host-service storage and APIs, CLI commands, desktop workspace and sidebar UI, terminal environments, and notify hooks. It also adds descendant cleanup, chat-session adoption, visibility ordering, and related tests. ChangesSubworkspace delegation
Estimated code review effort: 5 (Critical) | ~120 minutes Sequence Diagram(s)sequenceDiagram
participant Desktop
participant HostService
participant WorkspaceStore
participant Agent
Desktop->>HostService: create or update workspace delegation mode
HostService->>WorkspaceStore: persist workspace hierarchy and mode
HostService->>Agent: launch with resolved delegation mode
Agent->>HostService: create subworkspace through CLI/API
HostService-->>Desktop: workspace snapshot and delegation mode
Possibly related PRs
Suggested reviewers: 🚥 Pre-merge checks | ✅ 4 | ❌ 1❌ Failed checks (1 warning)
✅ Passed checks (4 passed)
✨ Finishing Touches🧪 Generate unit tests (beta)
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. Comment |
There was a problem hiding this comment.
Actionable comments posted: 4
🧹 Nitpick comments (1)
packages/host-service/src/workspaces/local-workspace-store.ts (1)
207-226: 🩺 Stability & Availability | 🔵 Trivial | ⚡ Quick winGuard the descendant walk against parent cycles.
parentWorkspaceIdis persisted directly, and a two-node cycle (A.parent = B,B.parent = A) is not ruled out. A subsequentbranch/worktreePath/projectIdpatch makesupdateLocalWorkspacechaseparentWorkspaceIdforever; pass an optionalvisitedset and skip already-visited children before recursing.🤖 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 `@packages/host-service/src/workspaces/local-workspace-store.ts` around lines 207 - 226, Update updateLocalWorkspace to accept an optional visited set, record the current workspace ID, and skip child IDs already present before recursive calls. Pass the same set through each descendant update so cycles in parentWorkspaceId terminate while preserving propagation of branch, worktreePath, and projectId patches.
🤖 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
`@apps/desktop/src/renderer/routes/_authenticated/_dashboard/components/DashboardSidebar/components/DashboardSidebarDeleteDialog/components/DestroyConfirmPane/DestroyConfirmPane.tsx`:
- Around line 68-70: Update the isSubworkspace confirmation text in
DestroyConfirmPane to explicitly state that deleting the subworkspace also
removes its nested descendant subworkspaces and their agent sessions, while
preserving the existing note that the shared working tree and branch remain
unchanged.
In `@packages/host-service/src/db/schema.ts`:
- Around line 200-211: The schema declaration for parentWorkspaceId already
specifies SET NULL; update
packages/host-service/drizzle/0012_clean_edwin_jarvis.sql lines 1-2 to generate
the parent_workspace_id foreign key with ON DELETE SET NULL, keeping
packages/host-service/src/db/schema.ts lines 200-211 unchanged so the deployed
migration matches the model.
In
`@packages/host-service/src/trpc/router/workspace-creation/shared/adopt-existing-worktree.ts`:
- Around line 217-219: Update deleteLocalWorkspaceConflicts() to collect each
conflicting parent’s subworkspace descendants with
getSubworkspaceDescendants(...) before calling deleteLocalWorkspace(). Delete
the collected descendants first, then delete the conflicting parent, preserving
the existing filtering that excludes subworkspaces and keepWorkspaceId.
In `@packages/host-service/src/trpc/router/workspaces/workspaces.ts`:
- Around line 1014-1023: Prevent the re-create/adopt flow from resetting an
existing workspace’s agentDelegationMode to the schema default. In the workspace
creation logic surrounding updateLocalWorkspace, only reconcile
agentDelegationMode for freshly created rows; preserve the persisted mode for
rows returned by findExistingWorkspaceByBranch or adoptExistingWorktree paths.
---
Nitpick comments:
In `@packages/host-service/src/workspaces/local-workspace-store.ts`:
- Around line 207-226: Update updateLocalWorkspace to accept an optional visited
set, record the current workspace ID, and skip child IDs already present before
recursive calls. Pass the same set through each descendant update so cycles in
parentWorkspaceId terminate while preserving propagation of branch,
worktreePath, and projectId patches.
🪄 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 Plus
Run ID: f6f3bb82-13fc-4acd-aee5-5042e31b6692
📒 Files selected for processing (68)
apps/desktop/src/main/lib/agent-setup/notify-hook.test.tsapps/desktop/src/main/lib/agent-setup/notify-hook.tsapps/desktop/src/main/lib/agent-setup/templates/notify-hook.template.shapps/desktop/src/renderer/commandPalette/core/types.tsapps/desktop/src/renderer/hooks/host-workspaces/useHostWorkspaces/index.tsapps/desktop/src/renderer/hooks/host-workspaces/useHostWorkspaces/useHostWorkspaces.utils.tsapps/desktop/src/renderer/routes/_authenticated/_dashboard/components/DashboardSidebar/components/DashboardSidebarDeleteDialog/DashboardSidebarDeleteDialog.tsxapps/desktop/src/renderer/routes/_authenticated/_dashboard/components/DashboardSidebar/components/DashboardSidebarDeleteDialog/components/DestroyConfirmPane/DestroyConfirmPane.tsxapps/desktop/src/renderer/routes/_authenticated/_dashboard/components/DashboardSidebar/components/DashboardSidebarDeleteDialog/hooks/useDestroyDialogState/useDestroyDialogState.tsapps/desktop/src/renderer/routes/_authenticated/_dashboard/components/DashboardSidebar/components/DashboardSidebarWorkspaceItem/components/DashboardSidebarExpandedWorkspaceRow/DashboardSidebarExpandedWorkspaceRow.tsxapps/desktop/src/renderer/routes/_authenticated/_dashboard/components/DashboardSidebar/hooks/useDashboardSidebarData/buildDashboardSidebarProjects.test.tsapps/desktop/src/renderer/routes/_authenticated/_dashboard/components/DashboardSidebar/hooks/useDashboardSidebarData/buildDashboardSidebarProjects.tsapps/desktop/src/renderer/routes/_authenticated/_dashboard/components/DashboardSidebar/hooks/useDashboardSidebarData/useDashboardSidebarData.tsapps/desktop/src/renderer/routes/_authenticated/_dashboard/components/DashboardSidebar/types.tsapps/desktop/src/renderer/routes/_authenticated/_dashboard/v2-workspace/$workspaceId/components/AddTabMenu/AddTabMenu.tsxapps/desktop/src/renderer/routes/_authenticated/_dashboard/v2-workspace/$workspaceId/hooks/useAutoAdoptBackgroundSessions/useAutoAdoptBackgroundSessions.tsapps/desktop/src/renderer/routes/_authenticated/_dashboard/v2-workspace/$workspaceId/hooks/useConsumeAutomationRunLink/useConsumeAutomationRunLink.tsapps/desktop/src/renderer/routes/_authenticated/_dashboard/v2-workspace/$workspaceId/page.tsxapps/desktop/src/renderer/routes/_authenticated/_dashboard/v2-workspace/$workspaceId/utils/focusChatPane/focusChatPane.tsapps/desktop/src/renderer/routes/_authenticated/_dashboard/v2-workspace/$workspaceId/utils/focusChatPane/index.tsapps/desktop/src/renderer/routes/_authenticated/_dashboard/v2-workspace/hooks/useRemoteHostStatus/useRemoteHostStatus.tsapps/desktop/src/renderer/routes/_authenticated/_dashboard/v2-workspace/providers/WorkspaceProvider/WorkspaceProvider.tsxapps/desktop/src/renderer/routes/_authenticated/_dashboard/v2-workspaces/hooks/useAccessibleV2Workspaces/useAccessibleV2Workspaces.tsapps/desktop/src/renderer/routes/_authenticated/components/AgentHooks/hooks/usePlaceLocalWorktreesInSidebar/selectWorktreesToPlace.tsapps/desktop/src/renderer/routes/_authenticated/components/DashboardNewWorkspaceModal/components/DashboardNewWorkspaceForm/PromptGroup/PromptGroup.tsxapps/desktop/src/renderer/routes/_authenticated/components/DashboardNewWorkspaceModal/components/DashboardNewWorkspaceForm/PromptGroup/hooks/useAgentDelegationPreference/index.tsapps/desktop/src/renderer/routes/_authenticated/components/DashboardNewWorkspaceModal/components/DashboardNewWorkspaceForm/PromptGroup/hooks/useAgentDelegationPreference/useAgentDelegationPreference.test.tsapps/desktop/src/renderer/routes/_authenticated/components/DashboardNewWorkspaceModal/components/DashboardNewWorkspaceForm/PromptGroup/hooks/useAgentDelegationPreference/useAgentDelegationPreference.tsapps/desktop/src/renderer/routes/_authenticated/components/DashboardNewWorkspaceModal/components/DashboardNewWorkspaceForm/PromptGroup/hooks/useSubmitWorkspace/useSubmitWorkspace.tsapps/desktop/src/renderer/routes/_authenticated/hooks/useDashboardSidebarState/sidebarMutations.tsapps/desktop/src/renderer/routes/_authenticated/hooks/useVisibleSidebarWorkspaceIds/useVisibleSidebarWorkspaceIds.tsapps/desktop/src/renderer/routes/_authenticated/providers/CollectionsProvider/dashboardSidebarLocal/sidebarVisibility.test.tsapps/desktop/src/renderer/routes/_authenticated/providers/CollectionsProvider/dashboardSidebarLocal/sidebarVisibility.tsapps/desktop/src/renderer/stores/workspace-creates/useWorkspaceCreates.tsapps/desktop/src/renderer/utils/getV2WorkspaceDisplayName/getV2WorkspaceDisplayName.tspackages/cli/src/commands/workspaces/create-subworkspace/command.tspackages/cli/src/lib/host-target/index.tspackages/cli/src/lib/host-target/resolveHostTarget.tspackages/cli/src/lib/host-target/resolveLocalWorkspaceTarget.tspackages/cli/src/lib/host/manifest.test.tspackages/cli/src/lib/host/manifest.tspackages/host-service/drizzle/0012_clean_edwin_jarvis.sqlpackages/host-service/drizzle/0013_persist_agent_delegation_mode.sqlpackages/host-service/drizzle/meta/0012_snapshot.jsonpackages/host-service/drizzle/meta/0013_snapshot.jsonpackages/host-service/drizzle/meta/_journal.jsonpackages/host-service/src/db/schema.tspackages/host-service/src/events/types.tspackages/host-service/src/terminal/env.test.tspackages/host-service/src/terminal/env.tspackages/host-service/src/terminal/terminal.tspackages/host-service/src/trpc/router/agents/agents.tspackages/host-service/src/trpc/router/notifications/notifications.test.tspackages/host-service/src/trpc/router/notifications/notifications.tspackages/host-service/src/trpc/router/workspace-cleanup/is-main-workspace.tspackages/host-service/src/trpc/router/workspace-cleanup/workspace-cleanup.tspackages/host-service/src/trpc/router/workspace-creation/shared/adopt-existing-worktree.tspackages/host-service/src/trpc/router/workspace/workspace.tspackages/host-service/src/trpc/router/workspaces/workspaces.tspackages/host-service/src/workspaces/local-workspace-store.test.tspackages/host-service/src/workspaces/local-workspace-store.tspackages/host-service/test/helpers/seed.tspackages/host-service/test/integration/subworkspace.integration.test.tspackages/host-service/test/workspace-cleanup.test.tspackages/sdk/src/resources/workspaces.tspackages/shared/package.jsonpackages/shared/src/agent-delegation.test.tspackages/shared/src/agent-delegation.ts
|
Ready to review this PR? Stage has broken it down into 16 individual chapters for you: Chapters generated by Stage for commit 5bb0868 on Jul 25, 2026 7:29pm UTC. |
…nout # Conflicts: # apps/desktop/src/renderer/routes/_authenticated/_dashboard/components/DashboardSidebar/components/DashboardSidebarWorkspaceItem/components/DashboardSidebarExpandedWorkspaceRow/DashboardSidebarExpandedWorkspaceRow.tsx
There was a problem hiding this comment.
Caution
Some comments are outside the diff and can’t be posted inline due to platform limitations.
⚠️ Outside diff range comments (2)
apps/desktop/src/renderer/routes/_authenticated/components/DashboardNewWorkspaceModal/components/NewWorkspaceScreen/NewWorkspaceScreen.tsx (2)
420-420: 🎯 Functional Correctness | 🟡 Minor | ⚡ Quick winAllow linked context or attachments to submit.
The UI requires non-empty prompt text, but
useSubmitWorkspaceintentionally supports linked PRs, issues, and attachments as creation context. A context-only workspace cannot be created from this screen.Proposed fix
+ const hasCreationContext = + !isPromptEmpty || + draft.linkedPR !== null || + draft.linkedIssues.length > 0 || + attachments.files.length > 0; + - if (isPromptEmpty) return; + if (!hasCreationContext) return; ... - disabled={needsSetup || isPromptEmpty} + disabled={needsSetup || !hasCreationContext}Also applies to: 695-695
🤖 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 `@apps/desktop/src/renderer/routes/_authenticated/components/DashboardNewWorkspaceModal/components/NewWorkspaceScreen/NewWorkspaceScreen.tsx` at line 420, Update the submit guards in NewWorkspaceScreen, including both occurrences of isPromptEmpty, so submission is blocked only when the prompt is empty and no linked context or attachments are present. Reuse the existing state or helper symbols that represent linked PRs, issues, and attachments, while preserving the current prompt-only submission behavior.
198-200: 🎯 Functional Correctness | 🟡 Minor | ⚡ Quick winHandle cached projects before readiness.
This guard ignores usable cached rows until
areProjectsReadybecomes true. Only wait for readiness whenprojectsis empty, so project preselection remains cache-first.Proposed fix
- if (!isOpen || !areProjectsReady) return; + if (!isOpen) return; + if (projects.length === 0 && !areProjectsReady) return;As per coding guidelines, “TanStack DB and Electric
useLiveQueryrendering must be cache-first.”🤖 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 `@apps/desktop/src/renderer/routes/_authenticated/components/DashboardNewWorkspaceModal/components/NewWorkspaceScreen/NewWorkspaceScreen.tsx` around lines 198 - 200, Update the useEffect guard in NewWorkspaceScreen so it only waits for areProjectsReady when projects is empty; allow the effect to process non-empty cached projects immediately, preserving cache-first project preselection while retaining the existing isOpen check.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.
Outside diff comments:
In
`@apps/desktop/src/renderer/routes/_authenticated/components/DashboardNewWorkspaceModal/components/NewWorkspaceScreen/NewWorkspaceScreen.tsx`:
- Line 420: Update the submit guards in NewWorkspaceScreen, including both
occurrences of isPromptEmpty, so submission is blocked only when the prompt is
empty and no linked context or attachments are present. Reuse the existing state
or helper symbols that represent linked PRs, issues, and attachments, while
preserving the current prompt-only submission behavior.
- Around line 198-200: Update the useEffect guard in NewWorkspaceScreen so it
only waits for areProjectsReady when projects is empty; allow the effect to
process non-empty cached projects immediately, preserving cache-first project
preselection while retaining the existing isOpen check.
ℹ️ Review info
⚙️ Run configuration
Configuration used: defaults
Review profile: CHILL
Plan: Pro Plus
Run ID: 7c8d34c8-8aa2-40d6-9ee0-23faa4c4ea28
📒 Files selected for processing (5)
apps/desktop/src/renderer/routes/_authenticated/_dashboard/components/DashboardSidebar/components/DashboardSidebarWorkspaceItem/components/DashboardSidebarExpandedWorkspaceRow/DashboardSidebarExpandedWorkspaceRow.tsxapps/desktop/src/renderer/routes/_authenticated/_dashboard/v2-workspace/$workspaceId/page.tsxapps/desktop/src/renderer/routes/_authenticated/components/DashboardNewWorkspaceModal/components/NewWorkspaceScreen/NewWorkspaceScreen.tsxpackages/host-service/src/terminal/terminal.tspackages/host-service/src/trpc/router/agents/agents.ts
🚧 Files skipped from review as they are similar to previous changes (4)
- apps/desktop/src/renderer/routes/_authenticated/_dashboard/v2-workspace/$workspaceId/page.tsx
- packages/host-service/src/terminal/terminal.ts
- packages/host-service/src/trpc/router/agents/agents.ts
- apps/desktop/src/renderer/routes/_authenticated/_dashboard/components/DashboardSidebar/components/DashboardSidebarWorkspaceItem/components/DashboardSidebarExpandedWorkspaceRow/DashboardSidebarExpandedWorkspaceRow.tsx
Relates to https://linear.app/superset-sh/issue/SUPER-1589/for-a-few-my-agents-eg-customer-suport-review-an-orchestrator-agent
What & why
Adds an opt-in Create sub-workspaces for sub-agents mode for agent delegation.
When enabled, delegated tasks become persistent, nested Superset sub-workspaces with their own workspace IDs, panes, and agent sessions. They share the parent workspace’s checkout and branch, so all changes remain on the parent branch.
The delegation mode is persisted per workspace and supplied to agents as hidden hook context without modifying the user’s prompt. Native/headless delegation remains the default.
How I tested it
Ran bun run lint.
Ran bun run typecheck across the monorepo.
Ran the complete desktop build with bun run --cwd apps/desktop build.
Ran 102 focused tests covering:
Ran a real Codex fan-out flow:
Repeated the flow in native mode and confirmed no Superset child workspaces were created.
Confirmed the delegation implementation details did not appear in the user prompt or captured terminal output.
Screenshot/recording not included because the browser-control backend was unavailable during verification.
Checklist
Summary by CodeRabbit
workspaces create-subworkspaceCLI command (supports attachments and delegation mode).