Skip to content

[codex] Show CLI workspaces in sidebar by default#4897

Open
Kitenite wants to merge 3 commits into
mainfrom
cli-automation-sidebar
Open

[codex] Show CLI workspaces in sidebar by default#4897
Kitenite wants to merge 3 commits into
mainfrom
cli-automation-sidebar

Conversation

@Kitenite
Copy link
Copy Markdown
Collaborator

@Kitenite Kitenite commented May 24, 2026

Summary

  • Default current-user worktree workspaces with accessible hosts into the dashboard sidebar even when they do not yet have local sidebar state.
  • Add synthetic sidebar project rows for default-visible workspaces whose projects are not explicitly pinned.
  • Preserve delete/remove semantics by writing hidden local sidebar markers instead of deleting local state in paths where default visibility could resurrect the workspace.
  • Factor the default visibility/project derivation into a tested pure helper.

Why

The sidebar was previously driven by local sidebar state rows. Workspaces created through the CLI or automations can exist in synced workspace data without a local sidebar row, so they stayed out of the sidebar until something explicitly pinned them. Making missing local state default to visible fixes that, but delete and remove flows also needed hidden markers so intentional removal still wins over the default.

Validation

  • bun test apps/desktop/src/renderer/routes/_authenticated/_dashboard/components/DashboardSidebar/hooks/useDashboardSidebarData/sidebarDefaultVisibility.test.ts
  • bun run lint
  • bun --filter @superset/desktop typecheck
  • git diff --check

Open in Stage

Summary by cubic

Show CLI- and automation-created workspaces in the sidebar by default, and auto-add their projects when needed. Deletions/removals now write hidden markers so items stay gone after sync.

  • New Features

    • Default-include current-user worktree workspaces when the host is accessible, even without local sidebar state.
    • Add synthetic sidebar project rows for those workspaces if not already pinned; sort after explicit projects.
  • Bug Fixes

    • Replace invalid v2UsersHosts join with a user-scoped query to prevent sidebar crashes; filter access by (orgId, hostId).
    • Remove/Delete now writes hidden local sidebar state, and project removal hides all its workspaces so items don’t reappear after sync.
    • Use hideWorkspaceInSidebar everywhere and drop removeWorkspaceFromSidebar; default visibility and project derivation are factored into a tested helper.

Written for commit 50c136c. Summary will update on new commits. Review in cubic

Summary by CodeRabbit

  • New Features

    • Deleted workspaces are now hidden in the sidebar (preserving history) instead of being removed.
    • Sidebar visibility now better reflects user access and workspace type, showing relevant workspaces by default.
  • Refactor

    • Sidebar state and project grouping logic reorganized for more consistent visibility and ordering.
  • Tests

    • Added unit tests covering sidebar visibility rules and default project row construction.

Review Change Stack

@coderabbitai
Copy link
Copy Markdown
Contributor

coderabbitai Bot commented May 24, 2026

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: 292dd4df-7fbb-416f-8f2e-0abeac8090eb

📥 Commits

Reviewing files that changed from the base of the PR and between 1dc27fb and 50c136c.

📒 Files selected for processing (1)
  • apps/desktop/src/renderer/routes/_authenticated/_dashboard/components/DashboardSidebar/hooks/useDashboardSidebarData/useDashboardSidebarData.ts

📝 Walkthrough

Walkthrough

The PR refactors sidebar workspace visibility and hidden-state handling: a new sidebarDefaultVisibility module extracts inclusion rules and project row building, sidebar data derivation is refactored to use session-based filtering and those helpers, hidden-state persistence is centralized in a new helper function, and components are unified to call hideWorkspaceInSidebar instead of removeWorkspaceFromSidebar.

Changes

Sidebar Workspace Visibility and Hidden-State Refactoring

Layer / File(s) Summary
Sidebar visibility rules and project row building
apps/desktop/src/renderer/routes/_authenticated/_dashboard/components/DashboardSidebar/hooks/useDashboardSidebarData/sidebarDefaultVisibility.ts, sidebarDefaultVisibility.test.ts
New module exports SidebarProjectRow, SidebarWorkspaceVisibilitySource, and SidebarProjectWorkspaceSource types. shouldIncludeSidebarWorkspace filters workspaces by local sidebar state, user authentication, and worktree host access. buildSidebarProjects merges explicit and default project rows with deduplication and sorting. Tests validate inclusion/exclusion rules and project merging behavior.
Sidebar data derivation using visibility helpers and session filtering
apps/desktop/src/renderer/routes/_authenticated/_dashboard/components/DashboardSidebar/hooks/useDashboardSidebarData/useDashboardSidebarData.ts
useDashboardSidebarData reads currentUserId from authClient.useSession(), extends rawSidebarWorkspaces query with v2UsersHosts join filtered by currentUserId, and exposes hasUserHostAccess. Workspace processing is driven by shouldIncludeSidebarWorkspace. Project derivation replaced with buildSidebarProjects(explicitProjects, sidebarWorkspaces). Memo dependencies updated.
Hidden-state persistence and sidebar mutation consolidation
apps/desktop/src/renderer/routes/_authenticated/hooks/useDashboardSidebarState/useDashboardSidebarState.ts
Introduces writeHiddenWorkspaceSidebarState to mark workspaces hidden via v2WorkspaceLocalState updates/inserts. hideWorkspaceInSidebar simplified to accept workspaceId only, derive projectId, and call the new helper. removeProjectFromSidebar refactored to write hidden state for affected workspace IDs. removeWorkspaceFromSidebar removed from the hook return.
Component wiring for consistent hideWorkspaceInSidebar usage
apps/desktop/src/renderer/commandPalette/ui/DeleteWorkspaceMount/DeleteWorkspaceMount.tsx, apps/desktop/src/renderer/commandPalette/ui/RemoveFromSidebarMount/RemoveFromSidebarMount.tsx, apps/desktop/src/renderer/routes/_authenticated/_dashboard/components/DashboardSidebar/components/DashboardSidebarWorkspaceItem/hooks/useDashboardSidebarWorkspaceItemActions/useDashboardSidebarWorkspaceItemActions.ts, apps/desktop/src/renderer/routes/_authenticated/_dashboard/layout.tsx, apps/desktop/src/renderer/routes/_authenticated/_dashboard/v2-workspace/$workspaceId/components/WorkspaceMissingWorktreeState/WorkspaceMissingWorktreeState.tsx
All components updated to import and call hideWorkspaceInSidebar(workspaceId) instead of removeWorkspaceFromSidebar. RemoveFromSidebarMount removes conditional isMain logic and unconditionally hides workspaces. Delete confirmation dialogs wire onDeleted callbacks to hide the workspace and close dialogs.

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~25 minutes

Possibly related PRs

  • superset-sh/superset#4673: Both PRs modify the dashboard v2 workspace delete confirmation flow and the post-deletion sidebar cleanup wiring between removeWorkspaceFromSidebar and hideWorkspaceInSidebar.
  • superset-sh/superset#4524: Related updates to "remove from sidebar" flows and the move toward hideWorkspaceInSidebar usage across mounts and actions.

Poem

🐰 I hide the burrow, tuck it neat and small,
Not gone, just sleeping behind the wall,
Rules and session tell me who may peep,
Projects sorted, secrets safe to keep,
A soft hush in the sidebar — I still call.

🚥 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
Title check ✅ Passed The PR title accurately describes the main change: making CLI-created worktree workspaces visible in the sidebar by default.
Description check ✅ Passed The PR description includes all required template sections: Summary, Why, Validation, and provides clear details about the implementation approach and testing.
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 docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch cli-automation-sidebar

Warning

There were issues while running some tools. Please review the errors and either fix the tool's configuration or disable the tool if it's a critical failure.

🔧 ESLint

If the error stems from missing dependencies, add them to the package.json file. For unrecoverable errors (e.g., due to private dependencies), disable the tool in the CodeRabbit configuration.

ESLint skipped: no ESLint configuration detected in root package.json. To enable, add eslint to devDependencies.


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.

❤️ Share

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

@capy-ai
Copy link
Copy Markdown

capy-ai Bot commented May 24, 2026

Capy auto-review is paused for this organization because the monthly auto-review limit has been reached. Increase the limit or turn it off in billing settings to resume automatic reviews.

@stage-review
Copy link
Copy Markdown

stage-review Bot commented May 24, 2026

Ready to review this PR? Stage has broken it down into 4 individual chapters for you:

Title
1 Define default visibility and project derivation logic
2 Implement hidden markers for sidebar state management
3 Integrate default visibility into sidebar data hook
4 Update UI components to use hidden markers
Open in Stage

Chapters generated by Stage for commit 50c136c on May 24, 2026 6:28am UTC.

Copy link
Copy Markdown
Contributor

@cubic-dev-ai cubic-dev-ai Bot left a comment

Choose a reason for hiding this comment

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

1 issue found across 12 files

Prompt for AI agents (unresolved issues)

Check if these issues are valid — if so, understand the root cause of each and fix them. If appropriate, use sub-agents to investigate and fix each issue separately.


<file name="apps/desktop/src/renderer/routes/_authenticated/_dashboard/components/DashboardSidebar/hooks/useDashboardSidebarData/useDashboardSidebarData.ts">

<violation number="1" location="apps/desktop/src/renderer/routes/_authenticated/_dashboard/components/DashboardSidebar/hooks/useDashboardSidebarData/useDashboardSidebarData.ts:267">
P2: Section workspace ordering can regress because sidebar workspaces are no longer sorted by tab order before being pushed into `section.workspaces`.</violation>
</file>

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

Re-trigger cubic

pendingTransaction: workspaceTransactionsById[workspace.id] ?? null,
})),
[hostsByMachineId, rawSidebarWorkspaces, workspaceTransactionsById],
rawSidebarWorkspaces
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

P2: Section workspace ordering can regress because sidebar workspaces are no longer sorted by tab order before being pushed into section.workspaces.

Prompt for AI agents
Check if this issue is valid — if so, understand the root cause and fix it. At apps/desktop/src/renderer/routes/_authenticated/_dashboard/components/DashboardSidebar/hooks/useDashboardSidebarData/useDashboardSidebarData.ts, line 267:

<comment>Section workspace ordering can regress because sidebar workspaces are no longer sorted by tab order before being pushed into `section.workspaces`.</comment>

<file context>
@@ -209,41 +208,81 @@ export function useDashboardSidebarData() {
-				pendingTransaction: workspaceTransactionsById[workspace.id] ?? null,
-			})),
-		[hostsByMachineId, rawSidebarWorkspaces, workspaceTransactionsById],
+			rawSidebarWorkspaces
+				.filter((workspace) =>
+					shouldIncludeSidebarWorkspace(workspace, currentUserId),
</file context>

@greptile-apps
Copy link
Copy Markdown
Contributor

greptile-apps Bot commented May 24, 2026

Greptile Summary

This PR makes CLI-created worktree workspaces appear in the dashboard sidebar by default, without requiring explicit local sidebar state. It also updates all delete/remove flows to write isHidden: true local state markers (rather than deleting records) so that intentional removals are preserved against the new default-visibility logic.

  • Default visibility: The workspace query is restructured to start from v2Workspaces with a left-join on v2WorkspaceLocalState; shouldIncludeSidebarWorkspace and buildSidebarProjects are new pure helpers that apply a two-stage filter (include eligible workspaces → exclude hidden ones) and synthesize synthetic sidebar project rows for default-visible workspaces whose projects aren't explicitly pinned.
  • Hidden markers: writeHiddenWorkspaceSidebarState is factored out and used uniformly across hideWorkspaceInSidebar and removeProjectFromSidebar, replacing the old delete-based approach; removeProjectFromSidebar also extends its workspace coverage to include all workspaces belonging to a project via v2Workspaces, not just those with existing local state.

Confidence Score: 4/5

The core two-stage filtering logic and hidden-marker approach are sound; the main risks are narrow edge cases in removeProjectFromSidebar and a silent command-palette omission.

The new default-visibility flow correctly handles the create, show, hide, and re-hide lifecycle for CLI workspaces. The two edge-case observations do not affect normal user flows today: cross-project workspace sidebar assignment is not supported in the UI, and all workspaces should have a projectId. Tests cover the new pure helpers well.

useDashboardSidebarState.ts — specifically removeProjectFromSidebar, which now iterates all workspaces for a project and writes hidden markers even for workspaces whose existing local state references a different project.

Important Files Changed

Filename Overview
apps/desktop/src/renderer/routes/_authenticated/_dashboard/components/DashboardSidebar/hooks/useDashboardSidebarData/sidebarDefaultVisibility.ts New pure helper module with shouldIncludeSidebarWorkspace and buildSidebarProjects; logic and tests look correct
apps/desktop/src/renderer/routes/_authenticated/_dashboard/components/DashboardSidebar/hooks/useDashboardSidebarData/useDashboardSidebarData.ts Query rearchitected to drive visibility from v2Workspaces with left-join on local state; two-stage filtering (shouldIncludeSidebarWorkspace → getVisibleSidebarWorkspaces) is correct
apps/desktop/src/renderer/routes/_authenticated/hooks/useDashboardSidebarState/useDashboardSidebarState.ts writeHiddenWorkspaceSidebarState factored out; removeProjectFromSidebar now writes hidden markers for all workspaces of a project, including those without existing local state; see comment on cross-project edge case
apps/desktop/src/renderer/commandPalette/modules/workspace/commands.tsx Delete command now guarded by projectId truthiness in addition to !isMain; silently suppresses delete when projectId is absent
apps/desktop/src/renderer/routes/_authenticated/_dashboard/components/DashboardSidebar/hooks/useDashboardSidebarData/sidebarDefaultVisibility.test.ts Comprehensive tests for both helpers covering explicit state, default visibility, user identity, and project ordering; well-structured
Prompt To Fix All With AI
Fix the following 2 code review issues. Work through them one at a time, proposing concise fixes.

---

### Issue 1 of 2
apps/desktop/src/renderer/commandPalette/modules/workspace/commands.tsx:71-72
**Delete command silently disappears when `projectId` is falsy**

The new guard `if (!isMain && projectId)` hides the delete command whenever `workspace.projectId` is absent. Since `DeleteWorkspaceTarget.projectId` is now a required (non-optional) `string`, a workspace that somehow lacks a `projectId` would simply have no delete entry in the command palette with no feedback. Consider falling back to `workspaceProjectId` or asserting with a log so the omission is observable.

### Issue 2 of 2
apps/desktop/src/renderer/routes/_authenticated/hooks/useDashboardSidebarState/useDashboardSidebarState.ts:500-507
**`removeProjectFromSidebar` may clobber local state for workspaces pinned under a different project**

The new `workspaceIds` set now includes every workspace whose `workspace.projectId === projectId` (from `v2Workspaces`), not just those whose `sidebarState.projectId === projectId`. If a workspace's canonical project is `projectId` but was manually pinned to a *different* project in the sidebar (`sidebarState.projectId``projectId`), calling `writeHiddenWorkspaceSidebarState` will overwrite its local state — changing `sidebarState.projectId` to `projectId` and setting `isHidden: true` — silently removing it from the other project's visible sidebar lane. Cross-project sidebar assignment is not currently available in the UI, so this is theoretical today, but defensive code could skip workspaces whose existing local state already references a different project.

Reviews (1): Last reviewed commit: "Show CLI workspaces in sidebar by defaul..." | Re-trigger Greptile

Comment on lines +71 to +72
const projectId = workspace.projectId;
if (!isMain && projectId) {
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

P2 Delete command silently disappears when projectId is falsy

The new guard if (!isMain && projectId) hides the delete command whenever workspace.projectId is absent. Since DeleteWorkspaceTarget.projectId is now a required (non-optional) string, a workspace that somehow lacks a projectId would simply have no delete entry in the command palette with no feedback. Consider falling back to workspaceProjectId or asserting with a log so the omission is observable.

Prompt To Fix With AI
This is a comment left during a code review.
Path: apps/desktop/src/renderer/commandPalette/modules/workspace/commands.tsx
Line: 71-72

Comment:
**Delete command silently disappears when `projectId` is falsy**

The new guard `if (!isMain && projectId)` hides the delete command whenever `workspace.projectId` is absent. Since `DeleteWorkspaceTarget.projectId` is now a required (non-optional) `string`, a workspace that somehow lacks a `projectId` would simply have no delete entry in the command palette with no feedback. Consider falling back to `workspaceProjectId` or asserting with a log so the omission is observable.

How can I resolve this? If you propose a fix, please make it concise.

Comment on lines +500 to +507
const workspaceIds = new Set([
...Array.from(collections.v2WorkspaceLocalState.state.values())
.filter((item) => item.sidebarState.projectId === projectId)
.map((item) => item.workspaceId),
...Array.from(collections.v2Workspaces.state.values())
.filter((item) => item.projectId === projectId)
.map((item) => item.id),
]);
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

P2 removeProjectFromSidebar may clobber local state for workspaces pinned under a different project

The new workspaceIds set now includes every workspace whose workspace.projectId === projectId (from v2Workspaces), not just those whose sidebarState.projectId === projectId. If a workspace's canonical project is projectId but was manually pinned to a different project in the sidebar (sidebarState.projectIdprojectId), calling writeHiddenWorkspaceSidebarState will overwrite its local state — changing sidebarState.projectId to projectId and setting isHidden: true — silently removing it from the other project's visible sidebar lane. Cross-project sidebar assignment is not currently available in the UI, so this is theoretical today, but defensive code could skip workspaces whose existing local state already references a different project.

Prompt To Fix With AI
This is a comment left during a code review.
Path: apps/desktop/src/renderer/routes/_authenticated/hooks/useDashboardSidebarState/useDashboardSidebarState.ts
Line: 500-507

Comment:
**`removeProjectFromSidebar` may clobber local state for workspaces pinned under a different project**

The new `workspaceIds` set now includes every workspace whose `workspace.projectId === projectId` (from `v2Workspaces`), not just those whose `sidebarState.projectId === projectId`. If a workspace's canonical project is `projectId` but was manually pinned to a *different* project in the sidebar (`sidebarState.projectId``projectId`), calling `writeHiddenWorkspaceSidebarState` will overwrite its local state — changing `sidebarState.projectId` to `projectId` and setting `isHidden: true` — silently removing it from the other project's visible sidebar lane. Cross-project sidebar assignment is not currently available in the UI, so this is theoretical today, but defensive code could skip workspaces whose existing local state already references a different project.

How can I resolve this? If you propose a fix, please make it concise.

Kitenite added 2 commits May 23, 2026 22:45
hideWorkspaceInSidebar now resolves projectId itself from
v2WorkspaceLocalState (preserving explicit reparenting) or
v2Workspaces. Removes the projectId arg from DeleteWorkspaceTarget,
DeleteTarget, WorkspaceMissingWorktreeStateProps, and the command
palette intent payload.

Also deletes the now-unused removeWorkspaceFromSidebar — every
caller switched to hideWorkspaceInSidebar in the previous commit.
TanStack DB joins only accept a single eq() — the (org, host, user)
and() in the leftJoin against v2UsersHosts threw "Join condition
must be an equality expression" at runtime, taking down the sidebar.

Replace with a separate v2UsersHosts live query filtered by userId,
then check (orgId, hostId) membership via Set in the visibility
filter. Same pattern useAccessibleV2Workspaces already uses.
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