-
Notifications
You must be signed in to change notification settings - Fork 2
feat(desktop): add workspace settings section with project navigation #228
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Conversation
- 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]>
|
The latest updates on your projects. Learn more about Vercel for GitHub.
|
|
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 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. 📒 Files selected for processing (8)
WalkthroughAdds 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
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)
Estimated code review effort🎯 4 (Complex) | ⏱️ ~45 minutes
Possibly related PRs
Poem
Pre-merge checks and finishing touches❌ Failed checks (1 warning)
✅ Passed checks (2 passed)
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.
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: MoveformatDateoutside the component.The
formatDatefunction 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 solidThe added lookups and projected
project/worktreefields are straightforward, keep the API surface minimal, and handle missing related records gracefully vianull. 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
📒 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.tsapps/desktop/src/renderer/screens/main/components/SettingsView/SettingsContent.tsxapps/desktop/src/renderer/screens/main/components/SettingsView/WorkspaceSettings/WorkspaceSettings.tsxapps/desktop/src/renderer/stores/app-state.tsapps/desktop/src/renderer/screens/main/components/SettingsView/SettingsSidebar.tsxapps/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 intsconfig.jsonwhen 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.tsapps/desktop/src/renderer/screens/main/components/SettingsView/SettingsContent.tsxapps/desktop/src/renderer/screens/main/components/SettingsView/WorkspaceSettings/WorkspaceSettings.tsxapps/desktop/src/renderer/stores/app-state.tsapps/desktop/src/renderer/screens/main/components/SettingsView/SettingsSidebar.tsxapps/desktop/src/lib/trpc/routers/workspaces/workspaces.ts
**/*.{ts,tsx}
📄 CodeRabbit inference engine (AGENTS.md)
**/*.{ts,tsx}: Avoid usinganytype - 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.tsapps/desktop/src/renderer/screens/main/components/SettingsView/SettingsContent.tsxapps/desktop/src/renderer/screens/main/components/SettingsView/WorkspaceSettings/WorkspaceSettings.tsxapps/desktop/src/renderer/stores/app-state.tsapps/desktop/src/renderer/screens/main/components/SettingsView/SettingsSidebar.tsxapps/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.tsapps/desktop/src/renderer/screens/main/components/SettingsView/SettingsContent.tsxapps/desktop/src/renderer/screens/main/components/SettingsView/WorkspaceSettings/WorkspaceSettings.tsxapps/desktop/src/renderer/stores/app-state.tsapps/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.tsfor 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 nestedcomponents/subdirectory within a parent component only if a sub-component is used 2+ times within that parent; otherwise keep it in the parent'scomponents/folder
One component per file - avoid multi-component files
Files:
apps/desktop/src/renderer/screens/main/components/SettingsView/SettingsContent.tsxapps/desktop/src/renderer/screens/main/components/SettingsView/WorkspaceSettings/WorkspaceSettings.tsxapps/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.tsxapps/desktop/src/renderer/screens/main/components/SettingsView/WorkspaceSettings/WorkspaceSettings.tsxapps/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
SettingsSectiontype 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. ThehandleWorkspaceClickappropriately 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.
| const [expandedProjects, setExpandedProjects] = useState<Set<string>>( | ||
| () => | ||
| new Set(activeWorkspace?.projectId ? [activeWorkspace.projectId] : []), | ||
| ); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
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.
| 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.
| {/* 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> |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
🧩 Analysis chain
🏁 Script executed:
rg -n "worktreePath" --type ts -C 3Repository: superset-sh/superset
Length of output: 27062
🏁 Script executed:
cat -n apps/desktop/src/renderer/screens/main/components/SettingsView/WorkspaceSettings/WorkspaceSettings.tsx | head -110Repository: superset-sh/superset
Length of output: 4086
🏁 Script executed:
rg -n "getActive" apps/desktop/src/lib/trpc/routers/workspaces/workspaces.ts -A 10 | head -50Repository: superset-sh/superset
Length of output: 378
🏁 Script executed:
rg -n "getActive: publicProcedure.query" apps/desktop/src/lib/trpc/routers/workspaces/workspaces.ts -A 30Repository: 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.
| {/* 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.
- 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]>
There was a problem hiding this 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:3001apps/desktop/src/renderer/screens/main/components/TopBar/WorkspaceTabs/WorkspaceDropdown.tsx (1)
25-35: Return the toast promise so the async signature is meaningful
handleCreateWorkspaceis markedasyncbut doesn’treturnorawaitthetoast.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
handleCreateWorkspacebeing strictlyvoid-returning.README.md (1)
51-54: Docs now correctly point to.superset/config.json; consider a tiny grammar fixThe 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.jsonis consistent; log message could be clearerThe switch to
.superset/config.jsonaligns with the updated tests and related utilities. You may optionally update the error message text ("Failed to read setup config") to mentionconfig.jsonor “workspace config” to avoid confusion when debugging.apps/desktop/src/renderer/screens/main/components/WorkspaceView/WorkspaceHeader/WorkspaceHeader.tsx (1)
8-18: MakefolderNamederivation handle Windows-style pathsRight now
folderNameis derived by splitting only on/, so a Windows path likeC:\repo\workspacewill not be split and the full path will be shown as the label. You can make this more robust without importingpath:- 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_TEMPLATEhere mirrors the template inapps/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 defaultconfig.jsoncontents.Also applies to: 69-73
24-33: Add lightweight tests for SetupConfigModal behaviorThis 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.tsxnext to this file to cover at least:
- Rendering the expected
config.jsonpath header for a mocked project.- Disabling the
OpenInButtonwhenconfigFilePathisnull.- Ensuring
onOpenChangecorrectly callscloseModal()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 ingetAppOption
getAppOptionfalls back toAPP_OPTIONS[1], assuming Cursor will always live at index 1. That’s brittle if someone later reordersAPP_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 interactionsThis component has non-trivial behavior (TRPC integration, dropdown state, shortcut hints, guards when
pathis undefined) and will be reused across the app.Consider adding an
OpenInButton.test.tsxco-located with this file to cover:
- Clicking the label button calls
openInApp.mutatewith the last-used app.- Menu item clicks call
openInApp.mutatewith the selected app.- “Copy path” item calls
copyPath.mutate.- All actions are no-ops when
pathisundefinedand 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: DeduplicateCONFIG_TEMPLATEwith the renderer modalThe
CONFIG_TEMPLATEhere is identical to the one inSetupConfigModal.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
SetupConfigModalfor the code previewThat keeps backend behavior and UI preview in sync.
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
⛔ Files ignored due to path filters (7)
apps/desktop/src/renderer/assets/app-icons/cursor.svgis excluded by!**/*.svgapps/desktop/src/renderer/assets/app-icons/finder.pngis excluded by!**/*.pngapps/desktop/src/renderer/assets/app-icons/iterm.pngis excluded by!**/*.pngapps/desktop/src/renderer/assets/app-icons/terminal.pngis excluded by!**/*.pngapps/desktop/src/renderer/assets/app-icons/vscode.svgis excluded by!**/*.svgapps/desktop/src/renderer/assets/app-icons/warp.pngis excluded by!**/*.pngapps/desktop/src/renderer/assets/app-icons/xcode.svgis 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.tsapps/desktop/src/shared/constants.tsapps/desktop/src/renderer/components/OpenInButton/index.tsapps/desktop/src/lib/trpc/routers/projects/projects.tsapps/desktop/src/renderer/screens/main/components/WorkspaceView/WorkspaceHeader/WorkspaceHeader.tsxapps/desktop/src/renderer/components/OpenInButton/OpenInButton.tsxapps/desktop/src/renderer/stores/config-modal.tsapps/desktop/src/lib/trpc/routers/config/index.tsapps/desktop/src/renderer/screens/main/components/TopBar/WorkspaceTabs/WorkspaceDropdown.tsxapps/desktop/src/lib/trpc/routers/index.tsapps/desktop/src/renderer/screens/main/components/TopBar/WorkspaceTabs/WorkspaceGroupContextMenu.tsxapps/desktop/src/lib/trpc/routers/config/config.tsapps/desktop/src/renderer/react-query/workspaces/useCreateWorkspace.tsapps/desktop/src/renderer/screens/main/index.tsxapps/desktop/src/main/lib/db/schemas.tsapps/desktop/src/lib/trpc/routers/workspaces/utils/setup.tsapps/desktop/src/lib/trpc/routers/workspaces/utils/setup.test.tsapps/desktop/src/lib/trpc/routers/workspaces/workspaces.tsapps/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 intsconfig.jsonwhen 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.tsapps/desktop/src/shared/constants.tsapps/desktop/src/renderer/components/OpenInButton/index.tsapps/desktop/src/lib/trpc/routers/projects/projects.tsapps/desktop/src/renderer/screens/main/components/WorkspaceView/WorkspaceHeader/WorkspaceHeader.tsxapps/desktop/src/renderer/components/OpenInButton/OpenInButton.tsxapps/desktop/src/renderer/stores/config-modal.tsapps/desktop/src/lib/trpc/routers/config/index.tsapps/desktop/src/renderer/screens/main/components/TopBar/WorkspaceTabs/WorkspaceDropdown.tsxapps/desktop/src/lib/trpc/routers/index.tsapps/desktop/src/renderer/screens/main/components/TopBar/WorkspaceTabs/WorkspaceGroupContextMenu.tsxapps/desktop/src/lib/trpc/routers/config/config.tsapps/desktop/src/renderer/react-query/workspaces/useCreateWorkspace.tsapps/desktop/src/renderer/screens/main/index.tsxapps/desktop/src/main/lib/db/schemas.tsapps/desktop/src/lib/trpc/routers/workspaces/utils/setup.tsapps/desktop/src/lib/trpc/routers/workspaces/utils/setup.test.tsapps/desktop/src/lib/trpc/routers/workspaces/workspaces.tsapps/desktop/src/renderer/components/SetupConfigModal/SetupConfigModal.tsx
**/*.{ts,tsx}
📄 CodeRabbit inference engine (AGENTS.md)
**/*.{ts,tsx}: Avoid usinganytype - 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.tsapps/desktop/src/shared/constants.tsapps/desktop/src/renderer/components/OpenInButton/index.tsapps/desktop/src/lib/trpc/routers/projects/projects.tsapps/desktop/src/renderer/screens/main/components/WorkspaceView/WorkspaceHeader/WorkspaceHeader.tsxapps/desktop/src/renderer/components/OpenInButton/OpenInButton.tsxapps/desktop/src/renderer/stores/config-modal.tsapps/desktop/src/lib/trpc/routers/config/index.tsapps/desktop/src/renderer/screens/main/components/TopBar/WorkspaceTabs/WorkspaceDropdown.tsxapps/website/src/app/scripts/page.tsxapps/desktop/src/lib/trpc/routers/index.tsapps/desktop/src/renderer/screens/main/components/TopBar/WorkspaceTabs/WorkspaceGroupContextMenu.tsxapps/desktop/src/lib/trpc/routers/config/config.tsapps/desktop/src/renderer/react-query/workspaces/useCreateWorkspace.tsapps/desktop/src/renderer/screens/main/index.tsxapps/desktop/src/main/lib/db/schemas.tsapps/desktop/src/lib/trpc/routers/workspaces/utils/setup.tsapps/desktop/src/lib/trpc/routers/workspaces/utils/setup.test.tsapps/desktop/src/lib/trpc/routers/workspaces/workspaces.tsapps/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.tsapps/desktop/src/renderer/components/OpenInButton/index.tsapps/desktop/src/renderer/screens/main/components/WorkspaceView/WorkspaceHeader/WorkspaceHeader.tsxapps/desktop/src/renderer/components/OpenInButton/OpenInButton.tsxapps/desktop/src/renderer/stores/config-modal.tsapps/desktop/src/renderer/screens/main/components/TopBar/WorkspaceTabs/WorkspaceDropdown.tsxapps/desktop/src/renderer/screens/main/components/TopBar/WorkspaceTabs/WorkspaceGroupContextMenu.tsxapps/desktop/src/renderer/react-query/workspaces/useCreateWorkspace.tsapps/desktop/src/renderer/screens/main/index.tsxapps/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.tsapps/desktop/src/lib/trpc/routers/config/index.tsapps/desktop/src/lib/trpc/routers/index.tsapps/desktop/src/lib/trpc/routers/config/config.tsapps/desktop/src/lib/trpc/routers/workspaces/utils/setup.tsapps/desktop/src/lib/trpc/routers/workspaces/utils/setup.test.tsapps/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.tsfor 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 nestedcomponents/subdirectory within a parent component only if a sub-component is used 2+ times within that parent; otherwise keep it in the parent'scomponents/folder
One component per file - avoid multi-component files
Files:
apps/desktop/src/renderer/screens/main/components/WorkspaceView/WorkspaceHeader/WorkspaceHeader.tsxapps/desktop/src/renderer/components/OpenInButton/OpenInButton.tsxapps/desktop/src/renderer/screens/main/components/TopBar/WorkspaceTabs/WorkspaceDropdown.tsxapps/desktop/src/renderer/screens/main/components/TopBar/WorkspaceTabs/WorkspaceGroupContextMenu.tsxapps/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.tsxapps/desktop/src/renderer/components/OpenInButton/OpenInButton.tsxapps/desktop/src/renderer/screens/main/components/TopBar/WorkspaceTabs/WorkspaceDropdown.tsxapps/desktop/src/renderer/screens/main/components/TopBar/WorkspaceTabs/WorkspaceGroupContextMenu.tsxapps/desktop/src/renderer/screens/main/index.tsxapps/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.tsapps/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.tsxapps/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 layoutAdding
hide-scrollbaron 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.jsonmatches the new config flowKeeping
.superset/*ignored while explicitly unignoringconfig.jsonand 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 workflowThe page clearly explains the
config.jsonschema, 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 focusedThe store cleanly encapsulates
isOpenandprojectIdwith 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 extensionAdding
configToastDismissed?: booleanas optional onProjectcleanly 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 appropriateRendering
<SetupConfigModal />at the root ofMainScreen(inside theDndProviderbut outsideAppFramecontent) 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 throughoutThe
createmutation returnsprojectIdimplicitly via the workspace object (which is part of the Workspace interface), andgetActiveenriches the response with optionalprojectandworktreeobjects. 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 goodRe-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 straightforwardRe-exporting
SetupConfigModalfrom 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 correctAdding
createConfigRouter()to the composed router alongside the other domain routers is consistent and ensures config procedures are exposed throughAppRouterwithout changing the factory signature.apps/desktop/src/lib/trpc/routers/projects/projects.ts (1)
83-89: Newprojects.getquery is simple and appropriateThe
gethandler cleanly returns aProjectornullby id without mutating state, which fits as a read-only query. Usingnullinstead 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; confirmprojectIdis always presentThe extended
onSuccessflow nicely covers both cases:
- When
initialCommandsare present, you preserve the existing terminal-tab behavior.- When they’re absent, the toast with a “Configure” action and
dismissConfigToaston 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.projectIdis always a valid project id for the created workspace. Ifworkspaces.createcan ever return a workspace without an associated project (or withprojectIdoptional), 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 appropriateRe-exporting both the
ConfigRoutertype andcreateConfigRouterfunction from the localconfigmodule 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.jsonbehaviorThe test updates mirror the runtime change to
.superset/config.json, and each case (missing file, valid JSON, invalid JSON, invalidsetuptype) is independently and clearly covered with a single assertion.
apps/desktop/src/shared/constants.ts
Outdated
| // 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"; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
🧩 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 -100Repository: 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.tsRepository: 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.tsRepository: 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.tsRepository: 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.
Summary
getActivetrpc query to include project and worktree informationTest plan
🤖 Generated with Claude Code
Summary by CodeRabbit
New Features
Chores
✏️ Tip: You can customize this high-level summary in your review settings.