Skip to content

Conversation

@Kitenite
Copy link
Collaborator

@Kitenite Kitenite commented Dec 1, 2025

Summary

  • Add new "Workspace" section to settings that displays the active workspace's details (name, project, branch, path, timestamps)
  • Refactor settings sidebar to show all projects with their workspaces in a collapsible tree structure
  • Allow switching between workspaces directly from the settings sidebar
  • Extend the getActive trpc query to include project and worktree information
  • Integrate setup scripts configuration from PR Add config.json onboarding flow for workspace setup scripts #224: show config.json template and OpenInButton for easy editing

Test plan

  • Open settings and verify the "Workspace" section appears under General
  • Verify active workspace details are displayed correctly (name, project info, branch, worktree path, timestamps)
  • Click on different workspaces in the sidebar tree and verify switching works
  • Collapse/expand projects in the sidebar
  • Verify the active workspace is highlighted in the sidebar
  • Verify "Setup & Teardown Scripts" section appears with config.json preview
  • Click "Open" button to open config.json in external app
  • Click "Learn how to use scripts" to open documentation

🤖 Generated with Claude Code

Summary by CodeRabbit

  • New Features

    • Workspace Settings view with workspace details and inline rename.
    • Settings sidebar with expandable projects and quick workspace switching.
    • Unified "Open" button to launch paths in external apps.
    • Setup Config modal, in-app toast guidance, and Config File preview for project scripts.
    • Public "Setup & Teardown Scripts" documentation page.
  • Chores

    • Example and docs updated to reference .superset/config.json and WEBSITE_URL.

✏️ Tip: You can customize this high-level summary in your review settings.

saddlepaddle and others added 4 commits December 1, 2025 15:08
- Show toast notification when workspace is created without setup commands
- Add modal to configure .superset/config.json with setup/teardown scripts
- Create reusable OpenInButton component for opening files in various apps
- Add /scripts documentation page to website explaining config.json usage
- Migrate from setup.json to config.json naming convention
- Track toast dismissal per-project to avoid repeated prompts

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <[email protected]>
…navigation

- Add new "Workspace" section to settings that shows active workspace details
- Refactor settings sidebar to display all projects with their workspaces in a tree structure
- Allow switching between workspaces directly from settings sidebar
- Extend getActive query to include project and worktree information
- Show workspace name, project info, branch, worktree path, and timestamps

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <[email protected]>
@vercel
Copy link

vercel bot commented Dec 1, 2025

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

Project Deployment Preview Comments Updated (UTC)
website Ready Ready Preview Comment Dec 2, 2025 0:50am

@coderabbitai
Copy link

coderabbitai bot commented Dec 1, 2025

Warning

Rate limit exceeded

@Kitenite has exceeded the limit for the number of commits or files that can be reviewed per hour. Please wait 16 minutes and 16 seconds before requesting another review.

⌛ How to resolve this issue?

After the wait time has elapsed, a review can be triggered using the @coderabbitai review command as a PR comment. Alternatively, push new commits to this PR.

We recommend that you space out your commits to avoid hitting the rate limit.

🚦 How do rate limits work?

CodeRabbit enforces hourly rate limits for each developer per organization.

Our paid plans have higher rate limits than the trial, open-source and free plans. In all cases, we re-allow further reviews after a brief timeout.

Please see our FAQ for further information.

📥 Commits

Reviewing files that changed from the base of the PR and between 07896db and d195e0f.

📒 Files selected for processing (8)
  • apps/desktop/src/lib/trpc/routers/config/config.ts (1 hunks)
  • apps/desktop/src/lib/trpc/routers/workspaces/utils/setup.ts (1 hunks)
  • apps/desktop/src/lib/trpc/routers/workspaces/utils/teardown.ts (2 hunks)
  • apps/desktop/src/renderer/components/ConfigFilePreview/ConfigFilePreview.tsx (1 hunks)
  • apps/desktop/src/renderer/components/ConfigFilePreview/index.ts (1 hunks)
  • apps/desktop/src/renderer/components/SetupConfigModal/SetupConfigModal.tsx (1 hunks)
  • apps/desktop/src/renderer/screens/main/components/SettingsView/WorkspaceSettings/WorkspaceSettings.tsx (1 hunks)
  • apps/desktop/src/shared/constants.ts (1 hunks)

Walkthrough

Adds project and worktree metadata to workspace TRPC responses, introduces a config router and UI for per-project config.json onboarding, migrates setup.json → .superset/config.json, and adds hierarchical Workspaces sidebar, WorkspaceSettings, OpenInButton, ConfigFilePreview, and SetupConfigModal components.

Changes

Cohort / File(s) Summary
TRPC: workspaces (shape changes)
apps/desktop/src/lib/trpc/routers/workspaces/workspaces.ts
getActive and per-item getAll projections now attach optional project?: { id, name, mainRepoPath } and worktree?: { branch, gitStatus }; create now returns projectId: string.
TRPC: new config router
apps/desktop/src/lib/trpc/routers/config/config.ts, apps/desktop/src/lib/trpc/routers/config/index.ts, apps/desktop/src/lib/trpc/routers/index.ts
New config router with procedures shouldShowConfigToast, dismissConfigToast, and getConfigFilePath; exported and wired into the main app router.
Project schema
apps/desktop/src/main/lib/db/schemas.ts
Added optional configToastDismissed?: boolean to Project.
Config filename migration & workspace utils
apps/desktop/src/lib/trpc/routers/workspaces/utils/setup.ts, .../teardown.ts, .../setup.test.ts, apps/desktop/src/shared/constants.ts
Replaced hardcoded .superset/setup.json with constants PROJECT_SUPERSET_DIR_NAME / CONFIG_FILE_NAME (now .superset/config.json) and updated tests. Also added CONFIG_TEMPLATE and WEBSITE_URL constants.
Settings UI: sidebar & content
apps/desktop/src/renderer/screens/main/components/SettingsView/SettingsSidebar.tsx, .../SettingsContent.tsx, apps/desktop/src/renderer/stores/app-state.ts
Sidebar reworked into hierarchical project → workspace navigation (expand/collapse) with TRPC queries; SettingsContent now conditionally renders WorkspaceSettings; added "workspace" to SettingsSection and default.
WorkspaceSettings component & preview
apps/desktop/src/renderer/screens/main/components/SettingsView/WorkspaceSettings/WorkspaceSettings.tsx, .../index.ts, apps/desktop/src/renderer/components/ConfigFilePreview/ConfigFilePreview.tsx, .../index.ts
New WorkspaceSettings component fetching active workspace and config path; ConfigFilePreview shows preview of .superset/config.json and uses OpenInButton.
Config modal & store
apps/desktop/src/renderer/components/SetupConfigModal/SetupConfigModal.tsx, .../index.ts, apps/desktop/src/renderer/stores/config-modal.ts
New SetupConfigModal component and a Zustand store with hooks (open/close and projectId) to manage modal state.
Open-in UI
apps/desktop/src/renderer/components/OpenInButton/OpenInButton.tsx, .../index.ts
New OpenInButton component (and props type) to open paths in external apps, with last-used-app tracking and copy-path support.
Workspace creation flow & toast
apps/desktop/src/renderer/react-query/workspaces/useCreateWorkspace.ts
onSuccess now shows config-guidance toast and may open SetupConfigModal / call dismissConfigToast when no initialCommands are present.
TopBar & WorkspaceHeader updates
apps/desktop/src/renderer/screens/main/components/TopBar/.../WorkspaceDropdown.tsx, .../WorkspaceHeader/WorkspaceHeader.tsx
WorkspaceDropdown.create handler made async; WorkspaceHeader replaced previous open-in UI with OpenInButton.
App integration
apps/desktop/src/renderer/screens/main/index.tsx
Renders in main screen.
Docs, README & env
apps/website/src/app/scripts/page.tsx, README.md, .env.example
Added "Setup & Teardown Scripts" docs page, updated README references from setup.json → config.json, and added WEBSITE_URL to .env.example.
Gitignore
.gitignore
Changed unignore rule from !.superset/setup.json!.superset/config.json.
Tests
apps/desktop/src/lib/trpc/routers/workspaces/utils/setup.test.ts
Updated tests to use the new .superset/config.json path and related constants.

Sequence Diagram(s)

sequenceDiagram
    participant User
    participant Sidebar as SettingsSidebar
    participant Frontend as SettingsContent / WorkspaceSettings
    participant TRPC
    participant FS as Filesystem

    User->>Sidebar: click workspace
    Sidebar->>TRPC: mutate setActiveWorkspace(id)
    TRPC-->>TRPC: update DB active workspace
    TRPC-->>Sidebar: mutation success
    Frontend->>TRPC: query workspaces.getActive()
    TRPC->>TRPC: resolve workspace + projects.get(id)
    TRPC->>TRPC: resolve worktree metadata (branch, gitStatus)
    TRPC->>FS: ensure .superset/config.json (getConfigFilePath)
    FS-->>TRPC: path (created if missing)
    TRPC-->>Frontend: activeWorkspace { project?, worktree?, worktreePath, timestamps }
    Frontend->>User: render WorkspaceSettings (ConfigFilePreview, OpenInButton, SetupConfigModal trigger)
Loading

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~45 minutes

  • Focus review on:
    • apps/desktop/src/lib/trpc/routers/workspaces/workspaces.ts: data-joining logic, null guards, and potential N+1 queries.
    • apps/desktop/src/lib/trpc/routers/config/config.ts: filesystem operations, creation races, and error handling.
    • UI–store wiring: config-modal.ts, SetupConfigModal, WorkspaceSettings, and useCreateWorkspace toast/mutation flows.
    • OpenInButton external-invocation logic and settings mutation/invalidation.

Possibly related PRs

Poem

🐰 I hopped through folders, quiet and bright,

Found configs tucked beneath the night,
Projects, branches, paths aligned—so neat,
A modal, button, workspace seat,
Click, open, script — a carrot treat!

Pre-merge checks and finishing touches

❌ Failed checks (1 warning)
Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 5.88% which is insufficient. The required threshold is 80.00%. You can run @coderabbitai generate docstrings to improve docstring coverage.
✅ Passed checks (2 passed)
Check name Status Explanation
Title check ✅ Passed The title accurately and concisely summarizes the main change: adding a workspace settings section with project navigation capabilities.
Description check ✅ Passed The PR description provides a clear summary, test plan, and context about changes including workspace settings, sidebar refactoring, and setup scripts integration, though it lacks formal sections and related issues.

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.

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 2

🧹 Nitpick comments (3)
apps/desktop/src/renderer/screens/main/components/SettingsView/SettingsSidebar.tsx (1)

94-138: Consider handling empty groups state.

The workspaces navigation renders groups.map() directly. If there are no projects/workspaces, this section will appear empty without any feedback to the user. Consider adding an empty state message.

 					<nav className="flex flex-col gap-0.5">
+						{groups.length === 0 && (
+							<p className="text-sm text-muted-foreground px-3 py-2">
+								No workspaces found
+							</p>
+						)}
 						{groups.map((group) => (
apps/desktop/src/renderer/screens/main/components/SettingsView/WorkspaceSettings/WorkspaceSettings.tsx (1)

33-41: Move formatDate outside the component.

The formatDate function is recreated on every render. Since it has no dependencies on component state or props, extract it to module scope for better performance and reusability.

+const formatDate = (timestamp: number) => {
+	return new Date(timestamp).toLocaleDateString(undefined, {
+		year: "numeric",
+		month: "short",
+		day: "numeric",
+		hour: "2-digit",
+		minute: "2-digit",
+	});
+};
+
 export function WorkspaceSettings() {
 	const { data: activeWorkspace, isLoading } =
 		trpc.workspaces.getActive.useQuery();
 
 	// ... loading and empty states ...
 
-	const formatDate = (timestamp: number) => {
-		return new Date(timestamp).toLocaleDateString(undefined, {
-			year: "numeric",
-			month: "short",
-			day: "numeric",
-			hour: "2-digit",
-			minute: "2-digit",
-		});
-	};
-
 	return (
apps/desktop/src/lib/trpc/routers/workspaces/workspaces.ts (1)

213-232: Active workspace projection with project/worktree metadata looks solid

The added lookups and projected project / worktree fields are straightforward, keep the API surface minimal, and handle missing related records gracefully via null. This is a good way to enrich the active workspace payload without leaking full DB objects.

If you find yourself needing this “enriched workspace” shape in other procedures later (e.g., additional queries beyond getActive), consider extracting a small helper for the projection to avoid duplication and keep the return type consistent across endpoints.

📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 1a08498 and d0000c5.

📒 Files selected for processing (6)
  • apps/desktop/src/lib/trpc/routers/workspaces/workspaces.ts (1 hunks)
  • apps/desktop/src/renderer/screens/main/components/SettingsView/SettingsContent.tsx (2 hunks)
  • apps/desktop/src/renderer/screens/main/components/SettingsView/SettingsSidebar.tsx (3 hunks)
  • apps/desktop/src/renderer/screens/main/components/SettingsView/WorkspaceSettings/WorkspaceSettings.tsx (1 hunks)
  • apps/desktop/src/renderer/screens/main/components/SettingsView/WorkspaceSettings/index.ts (1 hunks)
  • apps/desktop/src/renderer/stores/app-state.ts (2 hunks)
🧰 Additional context used
📓 Path-based instructions (7)
apps/desktop/**/*.{ts,tsx,js,jsx}

📄 CodeRabbit inference engine (apps/desktop/AGENTS.md)

For Electron interprocess communication, ALWAYS use tRPC as defined in src/lib/trpc

Files:

  • apps/desktop/src/renderer/screens/main/components/SettingsView/WorkspaceSettings/index.ts
  • apps/desktop/src/renderer/screens/main/components/SettingsView/SettingsContent.tsx
  • apps/desktop/src/renderer/screens/main/components/SettingsView/WorkspaceSettings/WorkspaceSettings.tsx
  • apps/desktop/src/renderer/stores/app-state.ts
  • apps/desktop/src/renderer/screens/main/components/SettingsView/SettingsSidebar.tsx
  • apps/desktop/src/lib/trpc/routers/workspaces/workspaces.ts
apps/desktop/**/*.{ts,tsx}

📄 CodeRabbit inference engine (apps/desktop/AGENTS.md)

apps/desktop/**/*.{ts,tsx}: Please use alias as defined in tsconfig.json when possible
Prefer zustand for state management if it makes sense. Do not use effect unless absolutely necessary

Files:

  • apps/desktop/src/renderer/screens/main/components/SettingsView/WorkspaceSettings/index.ts
  • apps/desktop/src/renderer/screens/main/components/SettingsView/SettingsContent.tsx
  • apps/desktop/src/renderer/screens/main/components/SettingsView/WorkspaceSettings/WorkspaceSettings.tsx
  • apps/desktop/src/renderer/stores/app-state.ts
  • apps/desktop/src/renderer/screens/main/components/SettingsView/SettingsSidebar.tsx
  • apps/desktop/src/lib/trpc/routers/workspaces/workspaces.ts
**/*.{ts,tsx}

📄 CodeRabbit inference engine (AGENTS.md)

**/*.{ts,tsx}: Avoid using any type - use explicit types instead for type safety
Use camelCase for variable and function names following existing codebase patterns
Keep diffs minimal with targeted edits only - avoid unnecessary changes when making modifications
Follow existing patterns and match the codebase style when writing new code

Files:

  • apps/desktop/src/renderer/screens/main/components/SettingsView/WorkspaceSettings/index.ts
  • apps/desktop/src/renderer/screens/main/components/SettingsView/SettingsContent.tsx
  • apps/desktop/src/renderer/screens/main/components/SettingsView/WorkspaceSettings/WorkspaceSettings.tsx
  • apps/desktop/src/renderer/stores/app-state.ts
  • apps/desktop/src/renderer/screens/main/components/SettingsView/SettingsSidebar.tsx
  • apps/desktop/src/lib/trpc/routers/workspaces/workspaces.ts
apps/desktop/src/renderer/**/*.{ts,tsx}

📄 CodeRabbit inference engine (AGENTS.md)

Never import Node.js modules (fs, path, os, net, etc.) in renderer process code - browser environment only

Files:

  • apps/desktop/src/renderer/screens/main/components/SettingsView/WorkspaceSettings/index.ts
  • apps/desktop/src/renderer/screens/main/components/SettingsView/SettingsContent.tsx
  • apps/desktop/src/renderer/screens/main/components/SettingsView/WorkspaceSettings/WorkspaceSettings.tsx
  • apps/desktop/src/renderer/stores/app-state.ts
  • apps/desktop/src/renderer/screens/main/components/SettingsView/SettingsSidebar.tsx
**/components/**/*.tsx

📄 CodeRabbit inference engine (AGENTS.md)

**/components/**/*.tsx: Create one folder per component with structure: ComponentName/ComponentName.tsx + index.ts for barrel export
Co-locate tests next to the component file they test (e.g., ComponentName.test.tsx)
Co-locate dependencies (utils, hooks, constants, config, stories) next to the file using them
Use nested components/ subdirectory within a parent component only if a sub-component is used 2+ times within that parent; otherwise keep it in the parent's components/ folder
One component per file - avoid multi-component files

Files:

  • apps/desktop/src/renderer/screens/main/components/SettingsView/SettingsContent.tsx
  • apps/desktop/src/renderer/screens/main/components/SettingsView/WorkspaceSettings/WorkspaceSettings.tsx
  • apps/desktop/src/renderer/screens/main/components/SettingsView/SettingsSidebar.tsx
apps/desktop/src/renderer/**/*.tsx

📄 CodeRabbit inference engine (AGENTS.md)

Call IPC methods using window.ipcRenderer.invoke() with object parameters - TypeScript will infer the exact response type automatically

Files:

  • apps/desktop/src/renderer/screens/main/components/SettingsView/SettingsContent.tsx
  • apps/desktop/src/renderer/screens/main/components/SettingsView/WorkspaceSettings/WorkspaceSettings.tsx
  • apps/desktop/src/renderer/screens/main/components/SettingsView/SettingsSidebar.tsx
apps/desktop/src/lib/**/*.ts

📄 CodeRabbit inference engine (AGENTS.md)

Never import Node.js modules in shared code like src/lib/electron-router-dom.ts - this code runs in both main and renderer processes

Files:

  • apps/desktop/src/lib/trpc/routers/workspaces/workspaces.ts
🧠 Learnings (2)
📚 Learning: 2025-11-24T21:33:13.267Z
Learnt from: CR
Repo: superset-sh/superset PR: 0
File: apps/desktop/AGENTS.md:0-0
Timestamp: 2025-11-24T21:33:13.267Z
Learning: Applies to apps/desktop/**/*.{ts,tsx} : Please use alias as defined in `tsconfig.json` when possible

Applied to files:

  • apps/desktop/src/renderer/stores/app-state.ts
📚 Learning: 2025-11-24T21:33:13.267Z
Learnt from: CR
Repo: superset-sh/superset PR: 0
File: apps/desktop/AGENTS.md:0-0
Timestamp: 2025-11-24T21:33:13.267Z
Learning: Applies to apps/desktop/**/*.{ts,tsx} : Prefer zustand for state management if it makes sense. Do not use effect unless absolutely necessary

Applied to files:

  • apps/desktop/src/renderer/stores/app-state.ts
🧬 Code graph analysis (2)
apps/desktop/src/renderer/screens/main/components/SettingsView/WorkspaceSettings/WorkspaceSettings.tsx (1)
apps/desktop/src/renderer/screens/main/components/SettingsView/WorkspaceSettings/index.ts (1)
  • WorkspaceSettings (1-1)
apps/desktop/src/renderer/screens/main/components/SettingsView/SettingsSidebar.tsx (2)
apps/desktop/src/renderer/stores/app-state.ts (1)
  • SettingsSection (5-5)
packages/ui/src/lib/utils.ts (1)
  • cn (4-6)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (1)
  • GitHub Check: Build
🔇 Additional comments (5)
apps/desktop/src/renderer/screens/main/components/SettingsView/SettingsContent.tsx (1)

1-17: LGTM!

The conditional rendering for the new workspace section follows the established pattern used for appearance and keyboard sections. Clean integration.

apps/desktop/src/renderer/screens/main/components/SettingsView/WorkspaceSettings/index.ts (1)

1-1: LGTM!

Barrel export follows the component folder structure guideline with ComponentName/ComponentName.tsx + index.ts.

apps/desktop/src/renderer/stores/app-state.ts (1)

5-5: LGTM!

The SettingsSection type expansion correctly adds "workspace" to the union. The default change to "workspace" on line 23 aligns with the PR objective to show the workspace settings section by default.

apps/desktop/src/renderer/screens/main/components/SettingsView/SettingsSidebar.tsx (1)

42-70: LGTM on tRPC usage and mutation handling.

The implementation correctly uses tRPC for data fetching (useQuery) and mutations (useSetActiveWorkspace), following the coding guidelines for Electron IPC via tRPC. The handleWorkspaceClick appropriately mutates the active workspace and switches the section.

apps/desktop/src/renderer/screens/main/components/SettingsView/WorkspaceSettings/WorkspaceSettings.tsx (1)

5-31: LGTM on loading and empty states.

Good UX patterns implemented: skeleton loading state prevents layout shift, and the empty state provides clear feedback when no workspace is selected.

Comment on lines +50 to +53
const [expandedProjects, setExpandedProjects] = useState<Set<string>>(
() =>
new Set(activeWorkspace?.projectId ? [activeWorkspace.projectId] : []),
);
Copy link

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟡 Minor

Active workspace's project may not auto-expand on initial load.

The useState initializer only runs once on mount. If activeWorkspace is still loading (undefined) at that time, the project won't be auto-expanded when data arrives. Consider using useEffect to expand the active project when activeWorkspace changes:

 	const [expandedProjects, setExpandedProjects] = useState<Set<string>>(
-		() =>
-			new Set(activeWorkspace?.projectId ? [activeWorkspace.projectId] : []),
+		new Set<string>(),
 	);
+
+	// Auto-expand active workspace's project when data loads
+	React.useEffect(() => {
+		if (activeWorkspace?.projectId) {
+			setExpandedProjects((prev) => {
+				if (prev.has(activeWorkspace.projectId)) return prev;
+				return new Set([...prev, activeWorkspace.projectId]);
+			});
+		}
+	}, [activeWorkspace?.projectId]);

Note: You'll need to import React or use the named useEffect import.

📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
const [expandedProjects, setExpandedProjects] = useState<Set<string>>(
() =>
new Set(activeWorkspace?.projectId ? [activeWorkspace.projectId] : []),
);
const [expandedProjects, setExpandedProjects] = useState<Set<string>>(
new Set<string>(),
);
// Auto-expand active workspace's project when data loads
React.useEffect(() => {
if (activeWorkspace?.projectId) {
setExpandedProjects((prev) => {
if (prev.has(activeWorkspace.projectId)) return prev;
return new Set([...prev, activeWorkspace.projectId]);
});
}
}, [activeWorkspace?.projectId]);
🤖 Prompt for AI Agents
In
apps/desktop/src/renderer/screens/main/components/SettingsView/SettingsSidebar.tsx
around lines 50 to 53, the initial useState runs before activeWorkspace may be
populated so the active workspace's project can fail to auto-expand; add a
useEffect that watches activeWorkspace and, when activeWorkspace?.projectId is
defined, updates setExpandedProjects (using the functional updater) to add that
projectId to the Set if not already present; remember to import useEffect (or
React) and ensure you do not clobber existing expandedProjects when adding the
project.

Comment on lines 95 to 104
{/* Worktree Path */}
<div className="space-y-2">
<h3 className="text-sm font-medium text-muted-foreground flex items-center gap-2">
<HiOutlineFolder className="h-4 w-4" />
Worktree Path
</h3>
<p className="text-sm font-mono text-muted-foreground break-all">
{activeWorkspace.worktreePath}
</p>
</div>
Copy link

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟡 Minor

🧩 Analysis chain

🏁 Script executed:

rg -n "worktreePath" --type ts -C 3

Repository: superset-sh/superset

Length of output: 27062


🏁 Script executed:

cat -n apps/desktop/src/renderer/screens/main/components/SettingsView/WorkspaceSettings/WorkspaceSettings.tsx | head -110

Repository: superset-sh/superset

Length of output: 4086


🏁 Script executed:

rg -n "getActive" apps/desktop/src/lib/trpc/routers/workspaces/workspaces.ts -A 10 | head -50

Repository: superset-sh/superset

Length of output: 378


🏁 Script executed:

rg -n "getActive: publicProcedure.query" apps/desktop/src/lib/trpc/routers/workspaces/workspaces.ts -A 30

Repository: superset-sh/superset

Length of output: 964


Add conditional rendering for worktreePath.

The "Worktree Path" section renders unconditionally, but worktreePath may be an empty string when no worktree is associated with the workspace. This creates an empty or confusing UI section. Align with existing patterns in this component where optional properties like project and worktree are conditionally rendered.

 			{/* Worktree Path */}
+			{activeWorkspace.worktreePath && (
 			<div className="space-y-2">
 				<h3 className="text-sm font-medium text-muted-foreground flex items-center gap-2">
 					<HiOutlineFolder className="h-4 w-4" />
 					Worktree Path
 				</h3>
 				<p className="text-sm font-mono text-muted-foreground break-all">
 					{activeWorkspace.worktreePath}
 				</p>
 			</div>
+			)}
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
{/* Worktree Path */}
<div className="space-y-2">
<h3 className="text-sm font-medium text-muted-foreground flex items-center gap-2">
<HiOutlineFolder className="h-4 w-4" />
Worktree Path
</h3>
<p className="text-sm font-mono text-muted-foreground break-all">
{activeWorkspace.worktreePath}
</p>
</div>
{/* Worktree Path */}
{activeWorkspace.worktreePath && (
<div className="space-y-2">
<h3 className="text-sm font-medium text-muted-foreground flex items-center gap-2">
<HiOutlineFolder className="h-4 w-4" />
Worktree Path
</h3>
<p className="text-sm font-mono text-muted-foreground break-all">
{activeWorkspace.worktreePath}
</p>
</div>
)}
🤖 Prompt for AI Agents
In
apps/desktop/src/renderer/screens/main/components/SettingsView/WorkspaceSettings/WorkspaceSettings.tsx
around lines 95 to 104, the "Worktree Path" block renders even when
activeWorkspace.worktreePath is an empty string; wrap the entire Worktree Path
div in a conditional render (e.g., activeWorkspace.worktreePath && (...) ) so
the section is omitted when worktreePath is falsy, matching the component's
existing conditional rendering for optional fields.

Kitenite and others added 2 commits December 1, 2025 16:08
- Add "Setup & Teardown Scripts" section to WorkspaceSettings
- Show config.json template and path with OpenInButton for easy editing
- Add "Learn how to use scripts" link to documentation
- Merge PR #224 changes (config router, OpenInButton component)

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <[email protected]>
Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 1

🧹 Nitpick comments (10)
.env.example (1)

3-3: LGTM! Consider adding documentation (optional).

The WEBSITE_URL environment variable is correctly configured for local development. The port (3001) doesn't conflict with other services.

While not required (other variables also lack comments), consider adding a brief comment to help developers understand when to set this:

 DATABASE_URL=postgresql://postgres:postgres@localhost:5432/superset
 VITE_DEV_SERVER_PORT=4927
+# WEBSITE_URL - Override the default website URL (https://superset.dev) for local development
 WEBSITE_URL=http://localhost:3001
apps/desktop/src/renderer/screens/main/components/TopBar/WorkspaceTabs/WorkspaceDropdown.tsx (1)

25-35: Return the toast promise so the async signature is meaningful

handleCreateWorkspace is marked async but doesn’t return or await the toast.promise, so callers can’t reliably wait for completion even though the signature suggests they can.

Consider returning the promise:

- const handleCreateWorkspace = async (projectId: string) => {
-   toast.promise(createWorkspace.mutateAsync({ projectId }), {
+ const handleCreateWorkspace = async (projectId: string) => {
+   return toast.promise(createWorkspace.mutateAsync({ projectId }), {
      loading: "Creating workspace...",
      success: () => {
        setIsOpen(false);
        return "Workspace created";
      },
      error: (err) =>
        err instanceof Error ? err.message : "Failed to create workspace",
-   });
+   });
 };

This keeps existing behavior for click handlers but allows future callers to await handleCreateWorkspace(projectId) if needed.

After applying, re-run TypeScript to ensure no call sites rely on handleCreateWorkspace being strictly void-returning.

README.md (1)

51-54: Docs now correctly point to .superset/config.json; consider a tiny grammar fix

The updated usage text correctly references the config file (.superset/config.json), matching the new setup/teardown flow.

You might also tweak the wording slightly for grammar:

-For each parallel tasks, Superset uses git worktrees to clone a new branch on your machine.
+For each parallel task, Superset uses git worktrees to clone a new branch on your machine.
apps/desktop/src/lib/trpc/routers/workspaces/utils/setup.ts (1)

5-26: Config path change to .superset/config.json is consistent; log message could be clearer

The switch to .superset/config.json aligns with the updated tests and related utilities. You may optionally update the error message text ("Failed to read setup config") to mention config.json or “workspace config” to avoid confusion when debugging.

apps/desktop/src/renderer/screens/main/components/WorkspaceView/WorkspaceHeader/WorkspaceHeader.tsx (1)

8-18: Make folderName derivation handle Windows-style paths

Right now folderName is derived by splitting only on /, so a Windows path like C:\repo\workspace will not be split and the full path will be shown as the label. You can make this more robust without importing path:

- const folderName = worktreePath
--		? worktreePath.split("/").filter(Boolean).pop() || worktreePath
-		: null;
+	const folderName = worktreePath
+		? worktreePath.split(/[\\/]/).filter(Boolean).pop() || worktreePath
+		: null;
apps/desktop/src/renderer/components/SetupConfigModal/SetupConfigModal.tsx (2)

19-22: Avoid duplicating the config.json template between frontend and backend

CONFIG_TEMPLATE here mirrors the template in apps/desktop/src/lib/trpc/routers/config/config.ts. Keeping two string literals in sync is brittle.

Consider extracting the template into a small shared module with no Node dependencies (e.g. apps/desktop/src/shared/configTemplate.ts) and importing it both in the TRPC router and in this modal so there is a single source of truth for the default config.json contents.

Also applies to: 69-73


24-33: Add lightweight tests for SetupConfigModal behavior

This modal wires together store state and TRPC queries and is now part of a core setup flow, but there’s no co-located test.

Consider adding a SetupConfigModal.test.tsx next to this file to cover at least:

  • Rendering the expected config.json path header for a mocked project.
  • Disabling the OpenInButton when configFilePath is null.
  • Ensuring onOpenChange correctly calls closeModal() when the dialog is closed.

I can sketch a test setup using your existing testing utilities if that’s helpful.

Also applies to: 76-86

apps/desktop/src/renderer/components/OpenInButton/OpenInButton.tsx (2)

29-41: Avoid index-based fallback in getAppOption

getAppOption falls back to APP_OPTIONS[1], assuming Cursor will always live at index 1. That’s brittle if someone later reorders APP_OPTIONS.

You can make the default explicit and resilient to reordering:

-const APP_OPTIONS: AppOption[] = [
+const APP_OPTIONS: AppOption[] = [
   { id: "finder", label: "Finder", icon: finderIcon },
   { id: "cursor", label: "Cursor", icon: cursorIcon },
   // ...
 ];
 
-const getAppOption = (id: ExternalApp) =>
-	APP_OPTIONS.find((app) => app.id === id) ?? APP_OPTIONS[1];
+const DEFAULT_APP =
+	APP_OPTIONS.find((app) => app.id === "cursor") ?? APP_OPTIONS[0];
+
+const getAppOption = (id: ExternalApp) =>
+	APP_OPTIONS.find((app) => app.id === id) ?? DEFAULT_APP;

50-148: Add targeted tests for OpenInButton interactions

This component has non-trivial behavior (TRPC integration, dropdown state, shortcut hints, guards when path is undefined) and will be reused across the app.

Consider adding an OpenInButton.test.tsx co-located with this file to cover:

  • Clicking the label button calls openInApp.mutate with the last-used app.
  • Menu item clicks call openInApp.mutate with the selected app.
  • “Copy path” item calls copyPath.mutate.
  • All actions are no-ops when path is undefined and buttons are disabled.

Happy to help sketch out tests using your existing testing setup.

apps/desktop/src/lib/trpc/routers/config/config.ts (1)

12-36: Deduplicate CONFIG_TEMPLATE with the renderer modal

The CONFIG_TEMPLATE here is identical to the one in SetupConfigModal.tsx. Maintaining two copies risks drift if the default config structure changes.

Consider moving the template string into a small shared module with no Node.js imports (e.g. apps/desktop/src/shared/configTemplate.ts) and importing it:

  • Here, for writeFileSync(configPath, CONFIG_TEMPLATE, "utf-8")
  • In SetupConfigModal for the code preview

That keeps backend behavior and UI preview in sync.

📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between d0000c5 and b4b342e.

⛔ Files ignored due to path filters (7)
  • apps/desktop/src/renderer/assets/app-icons/cursor.svg is excluded by !**/*.svg
  • apps/desktop/src/renderer/assets/app-icons/finder.png is excluded by !**/*.png
  • apps/desktop/src/renderer/assets/app-icons/iterm.png is excluded by !**/*.png
  • apps/desktop/src/renderer/assets/app-icons/terminal.png is excluded by !**/*.png
  • apps/desktop/src/renderer/assets/app-icons/vscode.svg is excluded by !**/*.svg
  • apps/desktop/src/renderer/assets/app-icons/warp.png is excluded by !**/*.png
  • apps/desktop/src/renderer/assets/app-icons/xcode.svg is excluded by !**/*.svg
📒 Files selected for processing (25)
  • .env.example (1 hunks)
  • .gitignore (1 hunks)
  • README.md (1 hunks)
  • apps/desktop/src/lib/trpc/routers/config/config.ts (1 hunks)
  • apps/desktop/src/lib/trpc/routers/config/index.ts (1 hunks)
  • apps/desktop/src/lib/trpc/routers/index.ts (2 hunks)
  • apps/desktop/src/lib/trpc/routers/projects/projects.ts (1 hunks)
  • apps/desktop/src/lib/trpc/routers/workspaces/utils/setup.test.ts (3 hunks)
  • apps/desktop/src/lib/trpc/routers/workspaces/utils/setup.ts (1 hunks)
  • apps/desktop/src/lib/trpc/routers/workspaces/utils/teardown.ts (1 hunks)
  • apps/desktop/src/lib/trpc/routers/workspaces/workspaces.ts (2 hunks)
  • apps/desktop/src/main/lib/db/schemas.ts (1 hunks)
  • apps/desktop/src/renderer/components/OpenInButton/OpenInButton.tsx (1 hunks)
  • apps/desktop/src/renderer/components/OpenInButton/index.ts (1 hunks)
  • apps/desktop/src/renderer/components/SetupConfigModal/SetupConfigModal.tsx (1 hunks)
  • apps/desktop/src/renderer/components/SetupConfigModal/index.ts (1 hunks)
  • apps/desktop/src/renderer/react-query/workspaces/useCreateWorkspace.ts (2 hunks)
  • apps/desktop/src/renderer/screens/main/components/SettingsView/WorkspaceSettings/WorkspaceSettings.tsx (1 hunks)
  • apps/desktop/src/renderer/screens/main/components/TopBar/WorkspaceTabs/WorkspaceDropdown.tsx (1 hunks)
  • apps/desktop/src/renderer/screens/main/components/TopBar/WorkspaceTabs/WorkspaceGroupContextMenu.tsx (1 hunks)
  • apps/desktop/src/renderer/screens/main/components/WorkspaceView/WorkspaceHeader/WorkspaceHeader.tsx (1 hunks)
  • apps/desktop/src/renderer/screens/main/index.tsx (2 hunks)
  • apps/desktop/src/renderer/stores/config-modal.ts (1 hunks)
  • apps/desktop/src/shared/constants.ts (1 hunks)
  • apps/website/src/app/scripts/page.tsx (1 hunks)
✅ Files skipped from review due to trivial changes (1)
  • apps/desktop/src/lib/trpc/routers/workspaces/utils/teardown.ts
🚧 Files skipped from review as they are similar to previous changes (1)
  • apps/desktop/src/renderer/screens/main/components/SettingsView/WorkspaceSettings/WorkspaceSettings.tsx
🧰 Additional context used
📓 Path-based instructions (9)
apps/desktop/**/*.{ts,tsx,js,jsx}

📄 CodeRabbit inference engine (apps/desktop/AGENTS.md)

For Electron interprocess communication, ALWAYS use tRPC as defined in src/lib/trpc

Files:

  • apps/desktop/src/renderer/components/SetupConfigModal/index.ts
  • apps/desktop/src/shared/constants.ts
  • apps/desktop/src/renderer/components/OpenInButton/index.ts
  • apps/desktop/src/lib/trpc/routers/projects/projects.ts
  • apps/desktop/src/renderer/screens/main/components/WorkspaceView/WorkspaceHeader/WorkspaceHeader.tsx
  • apps/desktop/src/renderer/components/OpenInButton/OpenInButton.tsx
  • apps/desktop/src/renderer/stores/config-modal.ts
  • apps/desktop/src/lib/trpc/routers/config/index.ts
  • apps/desktop/src/renderer/screens/main/components/TopBar/WorkspaceTabs/WorkspaceDropdown.tsx
  • apps/desktop/src/lib/trpc/routers/index.ts
  • apps/desktop/src/renderer/screens/main/components/TopBar/WorkspaceTabs/WorkspaceGroupContextMenu.tsx
  • apps/desktop/src/lib/trpc/routers/config/config.ts
  • apps/desktop/src/renderer/react-query/workspaces/useCreateWorkspace.ts
  • apps/desktop/src/renderer/screens/main/index.tsx
  • apps/desktop/src/main/lib/db/schemas.ts
  • apps/desktop/src/lib/trpc/routers/workspaces/utils/setup.ts
  • apps/desktop/src/lib/trpc/routers/workspaces/utils/setup.test.ts
  • apps/desktop/src/lib/trpc/routers/workspaces/workspaces.ts
  • apps/desktop/src/renderer/components/SetupConfigModal/SetupConfigModal.tsx
apps/desktop/**/*.{ts,tsx}

📄 CodeRabbit inference engine (apps/desktop/AGENTS.md)

apps/desktop/**/*.{ts,tsx}: Please use alias as defined in tsconfig.json when possible
Prefer zustand for state management if it makes sense. Do not use effect unless absolutely necessary

Files:

  • apps/desktop/src/renderer/components/SetupConfigModal/index.ts
  • apps/desktop/src/shared/constants.ts
  • apps/desktop/src/renderer/components/OpenInButton/index.ts
  • apps/desktop/src/lib/trpc/routers/projects/projects.ts
  • apps/desktop/src/renderer/screens/main/components/WorkspaceView/WorkspaceHeader/WorkspaceHeader.tsx
  • apps/desktop/src/renderer/components/OpenInButton/OpenInButton.tsx
  • apps/desktop/src/renderer/stores/config-modal.ts
  • apps/desktop/src/lib/trpc/routers/config/index.ts
  • apps/desktop/src/renderer/screens/main/components/TopBar/WorkspaceTabs/WorkspaceDropdown.tsx
  • apps/desktop/src/lib/trpc/routers/index.ts
  • apps/desktop/src/renderer/screens/main/components/TopBar/WorkspaceTabs/WorkspaceGroupContextMenu.tsx
  • apps/desktop/src/lib/trpc/routers/config/config.ts
  • apps/desktop/src/renderer/react-query/workspaces/useCreateWorkspace.ts
  • apps/desktop/src/renderer/screens/main/index.tsx
  • apps/desktop/src/main/lib/db/schemas.ts
  • apps/desktop/src/lib/trpc/routers/workspaces/utils/setup.ts
  • apps/desktop/src/lib/trpc/routers/workspaces/utils/setup.test.ts
  • apps/desktop/src/lib/trpc/routers/workspaces/workspaces.ts
  • apps/desktop/src/renderer/components/SetupConfigModal/SetupConfigModal.tsx
**/*.{ts,tsx}

📄 CodeRabbit inference engine (AGENTS.md)

**/*.{ts,tsx}: Avoid using any type - use explicit types instead for type safety
Use camelCase for variable and function names following existing codebase patterns
Keep diffs minimal with targeted edits only - avoid unnecessary changes when making modifications
Follow existing patterns and match the codebase style when writing new code

Files:

  • apps/desktop/src/renderer/components/SetupConfigModal/index.ts
  • apps/desktop/src/shared/constants.ts
  • apps/desktop/src/renderer/components/OpenInButton/index.ts
  • apps/desktop/src/lib/trpc/routers/projects/projects.ts
  • apps/desktop/src/renderer/screens/main/components/WorkspaceView/WorkspaceHeader/WorkspaceHeader.tsx
  • apps/desktop/src/renderer/components/OpenInButton/OpenInButton.tsx
  • apps/desktop/src/renderer/stores/config-modal.ts
  • apps/desktop/src/lib/trpc/routers/config/index.ts
  • apps/desktop/src/renderer/screens/main/components/TopBar/WorkspaceTabs/WorkspaceDropdown.tsx
  • apps/website/src/app/scripts/page.tsx
  • apps/desktop/src/lib/trpc/routers/index.ts
  • apps/desktop/src/renderer/screens/main/components/TopBar/WorkspaceTabs/WorkspaceGroupContextMenu.tsx
  • apps/desktop/src/lib/trpc/routers/config/config.ts
  • apps/desktop/src/renderer/react-query/workspaces/useCreateWorkspace.ts
  • apps/desktop/src/renderer/screens/main/index.tsx
  • apps/desktop/src/main/lib/db/schemas.ts
  • apps/desktop/src/lib/trpc/routers/workspaces/utils/setup.ts
  • apps/desktop/src/lib/trpc/routers/workspaces/utils/setup.test.ts
  • apps/desktop/src/lib/trpc/routers/workspaces/workspaces.ts
  • apps/desktop/src/renderer/components/SetupConfigModal/SetupConfigModal.tsx
apps/desktop/src/renderer/**/*.{ts,tsx}

📄 CodeRabbit inference engine (AGENTS.md)

Never import Node.js modules (fs, path, os, net, etc.) in renderer process code - browser environment only

Files:

  • apps/desktop/src/renderer/components/SetupConfigModal/index.ts
  • apps/desktop/src/renderer/components/OpenInButton/index.ts
  • apps/desktop/src/renderer/screens/main/components/WorkspaceView/WorkspaceHeader/WorkspaceHeader.tsx
  • apps/desktop/src/renderer/components/OpenInButton/OpenInButton.tsx
  • apps/desktop/src/renderer/stores/config-modal.ts
  • apps/desktop/src/renderer/screens/main/components/TopBar/WorkspaceTabs/WorkspaceDropdown.tsx
  • apps/desktop/src/renderer/screens/main/components/TopBar/WorkspaceTabs/WorkspaceGroupContextMenu.tsx
  • apps/desktop/src/renderer/react-query/workspaces/useCreateWorkspace.ts
  • apps/desktop/src/renderer/screens/main/index.tsx
  • apps/desktop/src/renderer/components/SetupConfigModal/SetupConfigModal.tsx
apps/desktop/src/lib/**/*.ts

📄 CodeRabbit inference engine (AGENTS.md)

Never import Node.js modules in shared code like src/lib/electron-router-dom.ts - this code runs in both main and renderer processes

Files:

  • apps/desktop/src/lib/trpc/routers/projects/projects.ts
  • apps/desktop/src/lib/trpc/routers/config/index.ts
  • apps/desktop/src/lib/trpc/routers/index.ts
  • apps/desktop/src/lib/trpc/routers/config/config.ts
  • apps/desktop/src/lib/trpc/routers/workspaces/utils/setup.ts
  • apps/desktop/src/lib/trpc/routers/workspaces/utils/setup.test.ts
  • apps/desktop/src/lib/trpc/routers/workspaces/workspaces.ts
**/components/**/*.tsx

📄 CodeRabbit inference engine (AGENTS.md)

**/components/**/*.tsx: Create one folder per component with structure: ComponentName/ComponentName.tsx + index.ts for barrel export
Co-locate tests next to the component file they test (e.g., ComponentName.test.tsx)
Co-locate dependencies (utils, hooks, constants, config, stories) next to the file using them
Use nested components/ subdirectory within a parent component only if a sub-component is used 2+ times within that parent; otherwise keep it in the parent's components/ folder
One component per file - avoid multi-component files

Files:

  • apps/desktop/src/renderer/screens/main/components/WorkspaceView/WorkspaceHeader/WorkspaceHeader.tsx
  • apps/desktop/src/renderer/components/OpenInButton/OpenInButton.tsx
  • apps/desktop/src/renderer/screens/main/components/TopBar/WorkspaceTabs/WorkspaceDropdown.tsx
  • apps/desktop/src/renderer/screens/main/components/TopBar/WorkspaceTabs/WorkspaceGroupContextMenu.tsx
  • apps/desktop/src/renderer/components/SetupConfigModal/SetupConfigModal.tsx
apps/desktop/src/renderer/**/*.tsx

📄 CodeRabbit inference engine (AGENTS.md)

Call IPC methods using window.ipcRenderer.invoke() with object parameters - TypeScript will infer the exact response type automatically

Files:

  • apps/desktop/src/renderer/screens/main/components/WorkspaceView/WorkspaceHeader/WorkspaceHeader.tsx
  • apps/desktop/src/renderer/components/OpenInButton/OpenInButton.tsx
  • apps/desktop/src/renderer/screens/main/components/TopBar/WorkspaceTabs/WorkspaceDropdown.tsx
  • apps/desktop/src/renderer/screens/main/components/TopBar/WorkspaceTabs/WorkspaceGroupContextMenu.tsx
  • apps/desktop/src/renderer/screens/main/index.tsx
  • apps/desktop/src/renderer/components/SetupConfigModal/SetupConfigModal.tsx
apps/desktop/src/main/**/*.{ts,tsx}

📄 CodeRabbit inference engine (AGENTS.md)

Node.js modules (fs, path, os, net, etc.) can be used in main process code only

Files:

  • apps/desktop/src/main/lib/db/schemas.ts
apps/desktop/**/*.test.{ts,tsx,js,jsx}

📄 CodeRabbit inference engine (apps/desktop/AGENTS.md)

apps/desktop/**/*.test.{ts,tsx,js,jsx}: Tests should have one assert per test
Tests should be readable
Tests should be fast
Tests should be independent
Tests should be repeatable

Files:

  • apps/desktop/src/lib/trpc/routers/workspaces/utils/setup.test.ts
🧠 Learnings (7)
📚 Learning: 2025-11-24T21:33:13.267Z
Learnt from: CR
Repo: superset-sh/superset PR: 0
File: apps/desktop/AGENTS.md:0-0
Timestamp: 2025-11-24T21:33:13.267Z
Learning: Applies to apps/desktop/**/*.{ts,tsx} : Prefer zustand for state management if it makes sense. Do not use effect unless absolutely necessary

Applied to files:

  • apps/desktop/src/renderer/stores/config-modal.ts
📚 Learning: 2025-11-28T01:03:47.963Z
Learnt from: CR
Repo: superset-sh/superset PR: 0
File: AGENTS.md:0-0
Timestamp: 2025-11-28T01:03:47.963Z
Learning: Applies to apps/desktop/src/lib/**/*.ts : Never import Node.js modules in shared code like `src/lib/electron-router-dom.ts` - this code runs in both main and renderer processes

Applied to files:

  • apps/desktop/src/lib/trpc/routers/config/index.ts
  • apps/desktop/src/lib/trpc/routers/index.ts
📚 Learning: 2025-11-28T01:03:47.963Z
Learnt from: CR
Repo: superset-sh/superset PR: 0
File: AGENTS.md:0-0
Timestamp: 2025-11-28T01:03:47.963Z
Learning: Applies to **/*.{ts,tsx} : Keep diffs minimal with targeted edits only - avoid unnecessary changes when making modifications

Applied to files:

  • apps/desktop/src/renderer/screens/main/components/TopBar/WorkspaceTabs/WorkspaceGroupContextMenu.tsx
  • apps/desktop/src/lib/trpc/routers/workspaces/utils/setup.test.ts
📚 Learning: 2025-11-28T01:03:47.963Z
Learnt from: CR
Repo: superset-sh/superset PR: 0
File: AGENTS.md:0-0
Timestamp: 2025-11-28T01:03:47.963Z
Learning: Applies to packages/ui/src/**/*.tsx : Use shadcn/ui components and TailwindCSS v4 for all UI component styling in the shared UI package

Applied to files:

  • apps/desktop/src/renderer/screens/main/components/TopBar/WorkspaceTabs/WorkspaceGroupContextMenu.tsx
📚 Learning: 2025-11-24T21:33:13.267Z
Learnt from: CR
Repo: superset-sh/superset PR: 0
File: apps/desktop/AGENTS.md:0-0
Timestamp: 2025-11-24T21:33:13.267Z
Learning: Applies to apps/desktop/**/*.test.{ts,tsx,js,jsx} : Tests should be repeatable

Applied to files:

  • apps/desktop/src/lib/trpc/routers/workspaces/utils/setup.test.ts
📚 Learning: 2025-11-24T21:33:13.267Z
Learnt from: CR
Repo: superset-sh/superset PR: 0
File: apps/desktop/AGENTS.md:0-0
Timestamp: 2025-11-24T21:33:13.267Z
Learning: Applies to apps/desktop/**/*.test.{ts,tsx,js,jsx} : Tests should be independent

Applied to files:

  • apps/desktop/src/lib/trpc/routers/workspaces/utils/setup.test.ts
📚 Learning: 2025-11-24T21:33:13.267Z
Learnt from: CR
Repo: superset-sh/superset PR: 0
File: apps/desktop/AGENTS.md:0-0
Timestamp: 2025-11-24T21:33:13.267Z
Learning: Applies to apps/desktop/**/*.test.{ts,tsx,js,jsx} : Tests should be readable

Applied to files:

  • apps/desktop/src/lib/trpc/routers/workspaces/utils/setup.test.ts
🧬 Code graph analysis (7)
apps/desktop/src/lib/trpc/routers/projects/projects.ts (2)
apps/desktop/src/main/lib/db/schemas.ts (1)
  • Project (1-10)
apps/desktop/src/main/lib/db/index.ts (1)
  • db (18-25)
apps/desktop/src/renderer/screens/main/components/WorkspaceView/WorkspaceHeader/WorkspaceHeader.tsx (1)
apps/desktop/src/renderer/components/OpenInButton/OpenInButton.tsx (1)
  • OpenInButton (50-149)
apps/desktop/src/lib/trpc/routers/config/config.ts (2)
apps/desktop/src/lib/trpc/routers/config/index.ts (2)
  • createConfigRouter (2-2)
  • ConfigRouter (1-1)
apps/desktop/src/lib/trpc/index.ts (1)
  • router (15-15)
apps/desktop/src/renderer/react-query/workspaces/useCreateWorkspace.ts (2)
apps/desktop/src/main/lib/terminal-manager.ts (1)
  • createOrAttach (41-174)
apps/desktop/src/renderer/stores/config-modal.ts (1)
  • useOpenConfigModal (34-35)
apps/desktop/src/lib/trpc/routers/workspaces/utils/setup.test.ts (1)
apps/desktop/src/lib/trpc/routers/workspaces/utils/setup.ts (1)
  • loadSetupConfig (5-27)
apps/desktop/src/lib/trpc/routers/workspaces/workspaces.ts (2)
apps/desktop/src/main/lib/db/index.ts (1)
  • db (18-25)
apps/desktop/src/lib/trpc/routers/workspaces/utils/worktree.ts (1)
  • getWorktreePath (6-9)
apps/desktop/src/renderer/components/SetupConfigModal/SetupConfigModal.tsx (3)
apps/desktop/src/renderer/stores/config-modal.ts (3)
  • useConfigModalOpen (30-31)
  • useConfigModalProjectId (32-33)
  • useCloseConfigModal (36-37)
apps/desktop/src/shared/constants.ts (1)
  • WEBSITE_URL (27-27)
apps/desktop/src/renderer/components/OpenInButton/OpenInButton.tsx (1)
  • OpenInButton (50-149)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (1)
  • GitHub Check: Build
🔇 Additional comments (14)
apps/desktop/src/renderer/screens/main/components/TopBar/WorkspaceTabs/WorkspaceGroupContextMenu.tsx (1)

121-142: Scrollbar-hiding utility looks consistent with existing layout

Adding hide-scrollbar on the horizontally scrollable color picker keeps the chips scrollable while cleaning up the visual chrome, without affecting logic or interactions. This is a minimal, targeted visual tweak and fits the existing flex/overflow-x-auto pattern here.

.gitignore (1)

56-60: Allowlisting .superset/config.json matches the new config flow

Keeping .superset/* ignored while explicitly unignoring config.json and scripts aligns with the new configuration model and avoids committing transient workspace data.

apps/website/src/app/scripts/page.tsx (1)

1-175: Scripts docs page looks consistent with the config.json workflow

The page clearly explains the config.json schema, placement under .superset/, and usage of shell scripts, and it respects renderer constraints (no Node imports). No changes needed.

apps/desktop/src/renderer/stores/config-modal.ts (1)

1-37: Zustand store design for the config modal is clean and focused

The store cleanly encapsulates isOpen and projectId with simple open/close actions and selector hooks. This aligns with the preference for Zustand over effects for UI state.

apps/desktop/src/main/lib/db/schemas.ts (1)

1-10: Config toast flag is a safe, backwards‑compatible schema extension

Adding configToastDismissed?: boolean as optional on Project cleanly supports per-project toast state without affecting existing data or defaults.

apps/desktop/src/renderer/screens/main/index.tsx (1)

6-7: SetupConfigModal placement under MainScreen looks appropriate

Rendering <SetupConfigModal /> at the root of MainScreen (inside the DndProvider but outside AppFrame content) is a good choice so it’s globally available regardless of the current view.

Also applies to: 145-159

apps/desktop/src/lib/trpc/routers/workspaces/workspaces.ts (1)

114-233: Workspace API enrichment looks solid with proper null safety throughout

The create mutation returns projectId implicitly via the workspace object (which is part of the Workspace interface), and getActive enriches the response with optional project and worktree objects. All 13 callers verified—they consistently use optional chaining (activeWorkspace?.id, activeWorkspace?.projectId) or explicit null checks ({activeWorkspace.project && (...)}) before accessing enriched fields. The implementation in WorkspaceSettings.tsx properly guards access to project and worktree properties, and no unsafe assumptions about non-null values were found.

apps/desktop/src/renderer/components/OpenInButton/index.ts (1)

1-2: Barrel export for OpenInButton looks good

Re-exporting both the component and its props from the local file matches the existing component barrel pattern and keeps the public API tidy.

apps/desktop/src/renderer/components/SetupConfigModal/index.ts (1)

1-1: SetupConfigModal barrel export is straightforward

Re-exporting SetupConfigModal from the local file keeps consumers on the index barrel and is consistent with the component structure.

apps/desktop/src/lib/trpc/routers/index.ts (1)

3-26: Wiring the config router into AppRouter looks correct

Adding createConfigRouter() to the composed router alongside the other domain routers is consistent and ensures config procedures are exposed through AppRouter without changing the factory signature.

apps/desktop/src/lib/trpc/routers/projects/projects.ts (1)

83-89: New projects.get query is simple and appropriate

The get handler cleanly returns a Project or null by id without mutating state, which fits as a read-only query. Using null instead of throwing on “not found” keeps the contract straightforward for callers.

apps/desktop/src/renderer/react-query/workspaces/useCreateWorkspace.ts (1)

1-57: Workspace creation toast + config flow looks good; confirm projectId is always present

The extended onSuccess flow nicely covers both cases:

  • When initialCommands are present, you preserve the existing terminal-tab behavior.
  • When they’re absent, the toast with a “Configure” action and dismissConfigToast on dismiss gives a clear path into the config modal and ensures the server-side toast flag can be cleared.

One thing to double‑check: this assumes data.projectId is always a valid project id for the created workspace. If workspaces.create can ever return a workspace without an associated project (or with projectId optional), it would be safer to guard the toast/config calls:

if (data.projectId) {
  toast.info("No setup script configured", {
    description: "Automate workspace setup with a config.json file",
    action: {
      label: "Configure",
      onClick: () => openConfigModal(data.projectId),
    },
    onDismiss: () => {
      dismissConfigToast.mutate({ projectId: data.projectId });
    },
  });
}
apps/desktop/src/lib/trpc/routers/config/index.ts (1)

1-2: Config router barrel exports are appropriate

Re-exporting both the ConfigRouter type and createConfigRouter function from the local config module matches the router barrel pattern and simplifies imports for callers.

apps/desktop/src/lib/trpc/routers/workspaces/utils/setup.test.ts (1)

22-59: Tests correctly aligned to .superset/config.json behavior

The test updates mirror the runtime change to .superset/config.json, and each case (missing file, valid JSON, invalid JSON, invalid setup type) is independently and clearly covered with a single assertion.

Comment on lines 26 to 27
// Website URL - defaults to production, can be overridden via env var for local dev
export const WEBSITE_URL = process.env.WEBSITE_URL || "https://superset.dev";
Copy link

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟡 Minor

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
# Find imports of constants.ts and check renderer usage
echo "=== Files importing constants.ts ==="
rg -n "from ['\"].*shared/constants" apps/desktop/src/ --type ts --type tsx

echo -e "\n=== Check Vite config for env handling ==="
cat apps/desktop/electron.vite.config.ts | head -100

Repository: superset-sh/superset

Length of output: 2603


🏁 Script executed:

#!/bin/bash
# Search for WEBSITE_URL usage across the codebase
echo "=== WEBSITE_URL usage in codebase ==="
rg "WEBSITE_URL" apps/desktop/src/ --type ts --type jsx -n

echo -e "\n=== Check if it's in preload (bridge) ==="
rg "WEBSITE_URL" apps/desktop/src/preload/ -n

echo -e "\n=== Check if injected into define in Vite ==="
grep -n "WEBSITE_URL\|injectProcessEnvPlugin" apps/desktop/electron.vite.config.ts

Repository: superset-sh/superset

Length of output: 342


🏁 Script executed:

#!/bin/bash
# Check the git context to see if this is new code
echo "=== Check git diff/status for constants.ts ==="
git diff HEAD apps/desktop/src/shared/constants.ts 2>/dev/null | head -50

echo -e "\n=== Full constants.ts file to understand context ==="
cat apps/desktop/src/shared/constants.ts

Repository: superset-sh/superset

Length of output: 1115


🏁 Script executed:

#!/bin/bash
# Check where constants.ts might be used
echo "=== Search for imports with flexible pattern ==="
rg "shared.*constants" apps/desktop/src/ -n --type ts

echo -e "\n=== Check if any renderer files might import from constants ==="
rg "from.*constants" apps/desktop/src/renderer/ -n --type ts 2>/dev/null || echo "No renderer imports"

echo -e "\n=== Full Vite renderer.define config ==="
sed -n '72,80p' apps/desktop/electron.vite.config.ts

Repository: superset-sh/superset

Length of output: 2667


Add WEBSITE_URL to Vite's renderer define configuration.

WEBSITE_URL is imported in renderer components (SetupConfigModal.tsx and WorkspaceSettings.tsx), but process.env.WEBSITE_URL is not in the Vite renderer define config. In the renderer process, this will always be undefined, causing the fallback to be used regardless of the environment variable. Add WEBSITE_URL to the renderer define configuration in electron.vite.config.ts so it's properly injected at build time:

define: {
  "process.env.NODE_ENV": JSON.stringify(process.env.NODE_ENV),
  "process.env.WEBSITE_URL": JSON.stringify(process.env.WEBSITE_URL),
  "process.platform": JSON.stringify(process.platform),
  "import.meta.env.DEV_SERVER_PORT": JSON.stringify(DEV_SERVER_PORT),
},
🤖 Prompt for AI Agents
In apps/desktop/src/shared/constants.ts around lines 26-27, WEBSITE_URL uses
process.env.WEBSITE_URL but that env var isn't injected into the renderer
bundle; update electron.vite.config.ts's renderer define config to include
"process.env.WEBSITE_URL": JSON.stringify(process.env.WEBSITE_URL) alongside the
existing defines (e.g., process.env.NODE_ENV, process.platform,
import.meta.env.DEV_SERVER_PORT) so the value is available at build/runtime in
renderer components.

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.

3 participants