Skip to content

Add config.json onboarding flow for workspace setup scripts#224

Merged
saddlepaddle merged 3 commits intomainfrom
jade-ocean-28
Dec 1, 2025
Merged

Add config.json onboarding flow for workspace setup scripts#224
saddlepaddle merged 3 commits intomainfrom
jade-ocean-28

Conversation

@saddlepaddle
Copy link
Copy Markdown
Collaborator

@saddlepaddle saddlepaddle commented Dec 1, 2025

Summary

  • Show toast notification when workspace is created without setup commands, prompting users to configure scripts
  • Add modal to configure .superset/config.json with setup/teardown scripts
  • Create reusable OpenInButton component for opening files in various apps (Finder, Cursor, VS Code, etc.)
  • 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

Test plan

  • Create a new workspace for a project without .superset/config.json - should see toast
  • Click "Configure" on toast - should open modal
  • Click file name button - should open in last used app
  • Click "Open" dropdown - should show all app options
  • Dismiss toast - should not show again for that project
  • Visit /scripts on website - should show documentation

🤖 Generated with Claude Code

Summary by CodeRabbit

Release Notes

  • New Features

    • Added configuration modal for setting up workspace scripts
    • Introduced "Open In" button for quick access to project files in external applications
    • Added smart prompts to configure workspaces when needed, with dismissible notifications
    • Launched documentation page detailing setup and teardown script capabilities
  • Updates

    • Streamlined configuration file path management
    • Added WEBSITE_URL environment variable support

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

@vercel
Copy link
Copy Markdown

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 1, 2025 11:36pm

@coderabbitai
Copy link
Copy Markdown
Contributor

coderabbitai Bot commented Dec 1, 2025

Walkthrough

This PR introduces a configuration management system for projects with a new TRPC config router, SetupConfigModal UI component, and OpenInButton component for opening project paths. It migrates configuration references from .superset/setup.json to .superset/config.json, adds environment variables, updates workspace creation to return projectId, and expands the project schema with a configToastDismissed field.

Changes

Cohort / File(s) Summary
Environment & Configuration
.env.example, .gitignore, README.md
Added WEBSITE_URL environment variable; switched .superset ignore exception from setup.json to config.json; updated documentation to reference config.json instead of setup.json.
TRPC Config Router
apps/desktop/src/lib/trpc/routers/config/config.ts, apps/desktop/src/lib/trpc/routers/config/index.ts
New config router with procedures: shouldShowConfigToast (check if toast should display), dismissConfigToast (mark as dismissed), getConfigFilePath (ensure and return config file path). Includes internal helpers for file existence checks and creation.
TRPC Router Composition
apps/desktop/src/lib/trpc/routers/index.ts, apps/desktop/src/lib/trpc/routers/projects/projects.ts
Integrated new config router into main app router; added get query endpoint to projects router to fetch project by id.
Workspace Router & Utilities
apps/desktop/src/lib/trpc/routers/workspaces/workspaces.ts, apps/desktop/src/lib/trpc/routers/workspaces/utils/setup.ts, apps/desktop/src/lib/trpc/routers/workspaces/utils/teardown.ts, apps/desktop/src/lib/trpc/routers/workspaces/utils/setup.test.ts
Updated workspace create mutation to return projectId; migrated setup/teardown utilities to read from .superset/config.json; updated test references.
Database Schema
apps/desktop/src/main/lib/db/schemas.ts
Added optional configToastDismissed boolean field to Project interface.
SetupConfigModal Component
apps/desktop/src/renderer/components/SetupConfigModal/SetupConfigModal.tsx, apps/desktop/src/renderer/components/SetupConfigModal/index.ts
New React modal component displaying config template, project info, and link to config file; fetches config file path via TRPC.
OpenInButton Component
apps/desktop/src/renderer/components/OpenInButton/OpenInButton.tsx, apps/desktop/src/renderer/components/OpenInButton/index.ts
New React component with dropdown to open paths in external apps, copy path action, and last-used app tracking via TRPC.
State Management
apps/desktop/src/renderer/stores/config-modal.ts
New Zustand store tracking config modal state (isOpen, projectId) with actions and convenience hooks.
Constants & Shared Config
apps/desktop/src/shared/constants.ts
Added WEBSITE_URL constant with default value and environment variable override.
UI Integration
apps/desktop/src/renderer/screens/main/components/WorkspaceView/WorkspaceHeader/WorkspaceHeader.tsx, apps/desktop/src/renderer/screens/main/components/TopBar/WorkspaceTabs/WorkspaceDropdown.tsx, apps/desktop/src/renderer/screens/main/index.tsx
Replaced workspace header's multi-action dropdown with OpenInButton component; made workspace creation async; mounted SetupConfigModal in main screen.
Workspace Creation Hook
apps/desktop/src/renderer/react-query/workspaces/useCreateWorkspace.ts
Added toast feedback when workspace has no setup commands, with action to open config modal and dismiss handler.
Scripts Documentation Page
apps/website/src/app/scripts/page.tsx
New page documenting Setup & Teardown Scripts with sections on overview, configuration, schema, and usage examples.

Sequence Diagram

sequenceDiagram
    participant User
    participant UI as React UI
    participant TRPC
    participant DB as Database
    participant FS as File System

    User->>UI: Create workspace
    UI->>TRPC: Create workspace (mutation)
    TRPC->>DB: Save workspace & project
    alt Has setup commands
        TRPC-->>UI: Return with projectId
        UI->>User: Show success
    else No setup commands
        TRPC-->>UI: Return with projectId
        UI->>User: Show toast "No setup script configured"
        User->>UI: Click "Configure"
        UI->>TRPC: shouldShowConfigToast
        TRPC->>DB: Check project & dismissal state
        TRPC-->>UI: Return true (should show)
        UI->>UI: Open SetupConfigModal
        UI->>TRPC: getConfigFilePath
        TRPC->>FS: Check .superset/config.json exists
        FS-->>TRPC: Not found
        TRPC->>FS: Create .superset/ & config.json with template
        FS-->>TRPC: Success
        TRPC-->>UI: Return path
        UI->>User: Display modal with config template
        User->>UI: Click "Done" or "Dismiss"
        UI->>TRPC: dismissConfigToast (mutation)
        TRPC->>DB: Mark configToastDismissed: true
        TRPC-->>UI: Success
        UI->>User: Close modal
    end
Loading

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~25 minutes

  • Config router logic: File existence checks, directory/file creation, and persistence—verify error handling and edge cases.
  • SetupConfigModal TRPC integration: Ensure proper query guards and config file path resolution.
  • useCreateWorkspace changes: Verify toast lifecycle, modal dispatch flow, and dismiss mutation wiring.
  • config-modal store consistency: Check Zustand store actions and hook signatures match usage throughout components.
  • setup.json → config.json migration: Verify all references updated (setup.ts, teardown.ts, tests, docs).

Possibly related PRs

  • Add 'Open in...' dropdown for external apps #175: Implements OpenInButton feature and external app integration (directly overlaps with OpenInButton component and TRPC external/settings procedures).
  • fix worktree setup #146: Refactors workspace setup utilities and setup.json handling; setup.json → config.json migration affects loadSetupConfig and copySetupFiles.
  • new desktop #101: Manages project setup/config file operations (.superset directory creation and config.json file helpers).

Poem

🐰 A config file springs to life,
With modals bright, no setup strife!
Buttons open, paths run free,
Scripts configured skillfully—
Hoppy magic, just for thee! ✨

Pre-merge checks and finishing touches

❌ Failed checks (1 warning, 1 inconclusive)
Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 7.69% which is insufficient. The required threshold is 80.00%. You can run @coderabbitai generate docstrings to improve docstring coverage.
Description check ❓ Inconclusive The PR description provides a comprehensive summary of changes and includes a detailed test plan, but does not follow the provided template structure with sections like Description, Related Issues, Type of Change, Testing, etc. Reorganize the description to match the template structure: add explicit 'Description' section, 'Related Issues' section, mark 'Type of Change' checkbox(es), and formally structure 'Testing' and 'Additional Notes' sections.
✅ Passed checks (1 passed)
Check name Status Explanation
Title check ✅ Passed The title clearly summarizes the main feature: adding a config.json onboarding flow for workspace setup scripts, which aligns with the primary changes throughout the changeset.
✨ Finishing touches
  • 📝 Generate docstrings
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch jade-ocean-28

📜 Recent review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between f9a7b39 and d819940.

📒 Files selected for processing (3)
  • apps/desktop/src/renderer/components/SetupConfigModal/SetupConfigModal.tsx (1 hunks)
  • apps/desktop/src/renderer/react-query/workspaces/useCreateWorkspace.ts (2 hunks)
  • apps/desktop/src/renderer/screens/main/components/TopBar/WorkspaceTabs/WorkspaceDropdown.tsx (1 hunks)
🚧 Files skipped from review as they are similar to previous changes (2)
  • apps/desktop/src/renderer/components/SetupConfigModal/SetupConfigModal.tsx
  • apps/desktop/src/renderer/screens/main/components/TopBar/WorkspaceTabs/WorkspaceDropdown.tsx
🧰 Additional context used
📓 Path-based instructions (4)
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/react-query/workspaces/useCreateWorkspace.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/react-query/workspaces/useCreateWorkspace.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/react-query/workspaces/useCreateWorkspace.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/react-query/workspaces/useCreateWorkspace.ts
⏰ 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 (2)
apps/desktop/src/renderer/react-query/workspaces/useCreateWorkspace.ts (2)

1-1: LGTM! Clean integration of toast and config modal.

The new imports and hooks are well-structured and follow the codebase patterns. Using zustand for the config modal store aligns with the coding guidelines.

Also applies to: 3-3, 18-19


41-53: Remove the projectId verification concern — data.projectId is correctly returned by the workspace creation mutation.

The workspace creation mutation returns projectId as part of its response object, so lines 47 and 50 are type-safe. No changes needed for this part.

The optional error handling suggestion for dismissConfigToast remains valid: adding error handling would improve robustness in edge cases where the dismissal mutation fails.


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
Copy Markdown
Contributor

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

🧹 Nitpick comments (6)
apps/desktop/src/lib/trpc/routers/workspaces/utils/setup.ts (1)

5-7: Config path rename looks correct; consider updating log wording

The switch to .superset/config.json matches the new config flow and the tests. Optionally, you might update the error message to say "config.json" or "workspace config" instead of "setup config" to avoid confusion when debugging.

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

13-15: Path change is correct; consider reusing the shared loader

The .superset/config.json path matches the setup side and tests. To avoid future drift, you could import and reuse loadSetupConfig from setup.ts here instead of maintaining a second copy of the same logic, and optionally update the log message to refer to "config.json" or "workspace config" rather than "setup config".

apps/desktop/src/renderer/screens/main/components/TopBar/WorkspaceTabs/WorkspaceDropdown.tsx (1)

28-53: Minor cleanup: handleCreateWorkspace doesn’t need to be async

handleCreateWorkspace doesn’t await anything; it just calls toast.promise with the mutation promise. You can simplify by dropping async (and the implicit unused Promise<void>):

- const handleCreateWorkspace = async (projectId: string) => {
+ const handleCreateWorkspace = (projectId: string) => {

Behavior is unchanged and avoids an unnecessary async wrapper.

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

8-10: Windows path separator handling.

The path splitting uses forward slashes only. If worktreePath can contain Windows-style backslashes, the folder name extraction may fail. Consider using a cross-platform approach similar to normalizeSeparators in StartView:

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

29-37: Queries fire with empty string when projectId is null.

Although enabled: !!projectId prevents execution when projectId is falsy, the query input projectId ?? "" passes an empty string. This is fine since enabled guards it, but for clarity you could use a non-null assertion or type guard pattern.

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

39-40: Replace hardcoded array index with explicit fallback.

Using APP_OPTIONS[1] as a fallback is fragile—if the array order changes, the fallback silently breaks.

Replace with an explicit fallback:

 const getAppOption = (id: ExternalApp) =>
-	APP_OPTIONS.find((app) => app.id === id) ?? APP_OPTIONS[1];
+	APP_OPTIONS.find((app) => app.id === id) ?? APP_OPTIONS.find((app) => app.id === "cursor")!;

Or define a constant:

const DEFAULT_APP: ExternalApp = "cursor";
const getAppOption = (id: ExternalApp) =>
	APP_OPTIONS.find((app) => app.id === id) ?? APP_OPTIONS.find((app) => app.id === DEFAULT_APP)!;
📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between c1d8d2c and f9a7b39.

⛔ 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 (23)
  • .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 (1 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/screens/main/components/StartView/index.tsx (3 hunks)
  • apps/desktop/src/renderer/screens/main/components/TopBar/WorkspaceTabs/WorkspaceDropdown.tsx (2 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)
🧰 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/OpenInButton/index.ts
  • apps/desktop/src/lib/trpc/routers/projects/projects.ts
  • apps/desktop/src/lib/trpc/routers/workspaces/workspaces.ts
  • apps/desktop/src/renderer/components/SetupConfigModal/SetupConfigModal.tsx
  • apps/desktop/src/lib/trpc/routers/workspaces/utils/setup.ts
  • apps/desktop/src/lib/trpc/routers/workspaces/utils/teardown.ts
  • apps/desktop/src/renderer/components/SetupConfigModal/index.ts
  • apps/desktop/src/lib/trpc/routers/config/index.ts
  • apps/desktop/src/renderer/stores/config-modal.ts
  • apps/desktop/src/shared/constants.ts
  • apps/desktop/src/lib/trpc/routers/workspaces/utils/setup.test.ts
  • apps/desktop/src/renderer/screens/main/components/StartView/index.tsx
  • apps/desktop/src/main/lib/db/schemas.ts
  • apps/desktop/src/lib/trpc/routers/config/config.ts
  • apps/desktop/src/renderer/screens/main/index.tsx
  • apps/desktop/src/lib/trpc/routers/index.ts
  • apps/desktop/src/renderer/components/OpenInButton/OpenInButton.tsx
  • apps/desktop/src/renderer/screens/main/components/WorkspaceView/WorkspaceHeader/WorkspaceHeader.tsx
  • apps/desktop/src/renderer/screens/main/components/TopBar/WorkspaceTabs/WorkspaceDropdown.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/OpenInButton/index.ts
  • apps/desktop/src/lib/trpc/routers/projects/projects.ts
  • apps/desktop/src/lib/trpc/routers/workspaces/workspaces.ts
  • apps/desktop/src/renderer/components/SetupConfigModal/SetupConfigModal.tsx
  • apps/desktop/src/lib/trpc/routers/workspaces/utils/setup.ts
  • apps/desktop/src/lib/trpc/routers/workspaces/utils/teardown.ts
  • apps/desktop/src/renderer/components/SetupConfigModal/index.ts
  • apps/desktop/src/lib/trpc/routers/config/index.ts
  • apps/desktop/src/renderer/stores/config-modal.ts
  • apps/desktop/src/shared/constants.ts
  • apps/desktop/src/lib/trpc/routers/workspaces/utils/setup.test.ts
  • apps/desktop/src/renderer/screens/main/components/StartView/index.tsx
  • apps/desktop/src/main/lib/db/schemas.ts
  • apps/desktop/src/lib/trpc/routers/config/config.ts
  • apps/desktop/src/renderer/screens/main/index.tsx
  • apps/desktop/src/lib/trpc/routers/index.ts
  • apps/desktop/src/renderer/components/OpenInButton/OpenInButton.tsx
  • apps/desktop/src/renderer/screens/main/components/WorkspaceView/WorkspaceHeader/WorkspaceHeader.tsx
  • apps/desktop/src/renderer/screens/main/components/TopBar/WorkspaceTabs/WorkspaceDropdown.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/OpenInButton/index.ts
  • apps/desktop/src/lib/trpc/routers/projects/projects.ts
  • apps/desktop/src/lib/trpc/routers/workspaces/workspaces.ts
  • apps/desktop/src/renderer/components/SetupConfigModal/SetupConfigModal.tsx
  • apps/desktop/src/lib/trpc/routers/workspaces/utils/setup.ts
  • apps/desktop/src/lib/trpc/routers/workspaces/utils/teardown.ts
  • apps/desktop/src/renderer/components/SetupConfigModal/index.ts
  • apps/website/src/app/scripts/page.tsx
  • apps/desktop/src/lib/trpc/routers/config/index.ts
  • apps/desktop/src/renderer/stores/config-modal.ts
  • apps/desktop/src/shared/constants.ts
  • apps/desktop/src/lib/trpc/routers/workspaces/utils/setup.test.ts
  • apps/desktop/src/renderer/screens/main/components/StartView/index.tsx
  • apps/desktop/src/main/lib/db/schemas.ts
  • apps/desktop/src/lib/trpc/routers/config/config.ts
  • apps/desktop/src/renderer/screens/main/index.tsx
  • apps/desktop/src/lib/trpc/routers/index.ts
  • apps/desktop/src/renderer/components/OpenInButton/OpenInButton.tsx
  • apps/desktop/src/renderer/screens/main/components/WorkspaceView/WorkspaceHeader/WorkspaceHeader.tsx
  • apps/desktop/src/renderer/screens/main/components/TopBar/WorkspaceTabs/WorkspaceDropdown.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/OpenInButton/index.ts
  • apps/desktop/src/renderer/components/SetupConfigModal/SetupConfigModal.tsx
  • apps/desktop/src/renderer/components/SetupConfigModal/index.ts
  • apps/desktop/src/renderer/stores/config-modal.ts
  • apps/desktop/src/renderer/screens/main/components/StartView/index.tsx
  • apps/desktop/src/renderer/screens/main/index.tsx
  • apps/desktop/src/renderer/components/OpenInButton/OpenInButton.tsx
  • apps/desktop/src/renderer/screens/main/components/WorkspaceView/WorkspaceHeader/WorkspaceHeader.tsx
  • apps/desktop/src/renderer/screens/main/components/TopBar/WorkspaceTabs/WorkspaceDropdown.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/workspaces/workspaces.ts
  • apps/desktop/src/lib/trpc/routers/workspaces/utils/setup.ts
  • apps/desktop/src/lib/trpc/routers/workspaces/utils/teardown.ts
  • apps/desktop/src/lib/trpc/routers/config/index.ts
  • apps/desktop/src/lib/trpc/routers/workspaces/utils/setup.test.ts
  • apps/desktop/src/lib/trpc/routers/config/config.ts
  • apps/desktop/src/lib/trpc/routers/index.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/components/SetupConfigModal/SetupConfigModal.tsx
  • apps/desktop/src/renderer/screens/main/components/StartView/index.tsx
  • apps/desktop/src/renderer/components/OpenInButton/OpenInButton.tsx
  • apps/desktop/src/renderer/screens/main/components/WorkspaceView/WorkspaceHeader/WorkspaceHeader.tsx
  • apps/desktop/src/renderer/screens/main/components/TopBar/WorkspaceTabs/WorkspaceDropdown.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/components/SetupConfigModal/SetupConfigModal.tsx
  • apps/desktop/src/renderer/screens/main/components/StartView/index.tsx
  • apps/desktop/src/renderer/screens/main/index.tsx
  • apps/desktop/src/renderer/components/OpenInButton/OpenInButton.tsx
  • apps/desktop/src/renderer/screens/main/components/WorkspaceView/WorkspaceHeader/WorkspaceHeader.tsx
  • apps/desktop/src/renderer/screens/main/components/TopBar/WorkspaceTabs/WorkspaceDropdown.tsx
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
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
🧠 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-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
📚 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/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 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/index.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} : Please use alias as defined in `tsconfig.json` when possible

Applied to files:

  • apps/desktop/src/renderer/components/OpenInButton/OpenInButton.tsx
🧬 Code graph analysis (8)
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/components/SetupConfigModal/SetupConfigModal.tsx (5)
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)
packages/ui/src/components/dialog.tsx (5)
  • Dialog (132-132)
  • DialogContent (134-134)
  • DialogHeader (137-137)
  • DialogTitle (140-140)
  • DialogDescription (135-135)
apps/desktop/src/renderer/components/OpenInButton/OpenInButton.tsx (1)
  • OpenInButton (50-149)
packages/ui/src/components/button.tsx (1)
  • Button (61-61)
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/renderer/screens/main/components/StartView/index.tsx (2)
apps/desktop/src/renderer/stores/config-modal.ts (1)
  • useOpenConfigModal (34-35)
packages/ui/src/components/sonner.tsx (1)
  • toast (30-30)
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/screens/main/index.tsx (2)
apps/desktop/src/renderer/components/SetupConfigModal/SetupConfigModal.tsx (1)
  • SetupConfigModal (24-90)
apps/desktop/src/renderer/components/SetupConfigModal/index.ts (1)
  • SetupConfigModal (1-1)
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/renderer/screens/main/components/TopBar/WorkspaceTabs/WorkspaceDropdown.tsx (2)
apps/desktop/src/renderer/stores/config-modal.ts (1)
  • useOpenConfigModal (34-35)
packages/ui/src/components/sonner.tsx (1)
  • toast (30-30)
⏰ 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 (30)
.env.example (1)

3-3: LGTM!

The WEBSITE_URL environment variable is appropriately added for local development and aligns with the new documentation page feature.

.gitignore (1)

58-58: LGTM!

The gitignore exception correctly updates to track config.json instead of setup.json, aligning with the naming migration throughout the PR.

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

9-9: LGTM!

The optional configToastDismissed field is well-named and appropriately typed for tracking per-project toast dismissal state.

README.md (1)

53-53: LGTM!

The documentation correctly updates to reference .superset/config.json and fixes the path format, aligning with the naming migration throughout the PR.

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

121-121: LGTM!

Returning projectId in the workspace creation response enables the caller to associate the workspace with its project, which is necessary for the per-project toast notification feature.

apps/desktop/src/shared/constants.ts (1)

26-27: LGTM!

The WEBSITE_URL constant with environment override follows the existing pattern in this file and provides appropriate defaults for production and development.

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

1-21: LGTM!

The imports and example constants are well-structured. The JSON examples provide clear, practical guidance for users configuring their setup and teardown scripts.

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

6-6: LGTM!

The import follows the established alias pattern for the renderer directory as per coding guidelines.


157-157: LGTM!

The SetupConfigModal is correctly mounted at the top level of the MainScreen component, allowing it to overlay the entire application when opened. The modal manages its own state via Zustand, which is the preferred state management approach per coding guidelines.

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

22-59: Tests correctly target .superset/config.json and remain well‑isolated

The updated tests consistently use .superset/config.json and still cover the key paths (missing file, valid config, invalid JSON, invalid setup type) with one assertion per test and proper setup/teardown of the temp directory.

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

1-2: Barrel export matches component structure guidelines

Re-exporting OpenInButton and its props from the index keeps consumers clean and follows the one‑component‑per‑folder + barrel pattern.

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

1-1: SetupConfigModal barrel export looks good

The index re-export keeps the component tree organized and makes imports consistent with other components.

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

3-26: Config router wiring is consistent with existing router composition

Adding config: createConfigRouter() alongside the other domain routers cleanly exposes the new config procedures on AppRouter. Ensure any generated TRPC client types are refreshed so trpc.config.* is available in the renderer.

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

83-90: New projects.get query is straightforward and consistent

The get procedure’s schema and implementation are simple and match existing router style, returning Project | null without side effects. This should integrate cleanly with the rest of the TRPC API surface.

apps/desktop/src/renderer/screens/main/components/StartView/index.tsx (2)

1-1: LGTM on imports and hook setup.

The new imports for toast, useOpenConfigModal, and the dismissConfigToast mutation are correctly set up and follow the established patterns in the codebase.

Also applies to: 9-9, 59-60


89-94: Consistent onSuccess callback usage.

The showConfigToastIfNeeded callback is correctly wired to both workspace creation flows, ensuring users see the configuration prompt regardless of how they open a project.

Also applies to: 108-108

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

1-2: LGTM!

Clean barrel export following tRPC router conventions.

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

1-1: Good refactor to reusable component.

Delegating to OpenInButton reduces code duplication and centralizes the "open in app" logic. The component correctly passes the derived label and enables keyboard shortcuts.

Also applies to: 14-18

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

19-22: Static template shown regardless of existing config.

The CONFIG_TEMPLATE constant is always displayed, even if a config.json file already exists with different content. If this is intentional (showing the expected format), consider adding a note in the UI. Otherwise, you may want to fetch and display the actual file content when it exists.


45-89: LGTM on modal structure.

The Dialog implementation correctly uses the UI primitives, handles close via onOpenChange, and provides a clean UX with the config path display and "Learn more" external link.

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

1-27: LGTM!

Clean Zustand store implementation with devtools middleware. The state management follows the codebase patterns and avoids unnecessary effects. Based on learnings, this correctly uses Zustand for state management.


29-37: Well-structured convenience hooks.

The individual selector hooks provide efficient subscriptions to specific state slices, preventing unnecessary re-renders when unrelated state changes.

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

50-84: Component logic is well-structured.

The tRPC integration, state management, and action guards are correctly implemented. The handlers properly check for path existence before executing mutations, and the invalidation pattern ensures the UI stays in sync.


85-149: UI rendering is clean and accessible.

The button group structure, dropdown menu implementation, and conditional rendering logic are well-organized. Proper use of disabled states and ARIA-compatible components from @superset/ui.


10-10: Move ExternalApp type to shared location.

The renderer process is importing a type from main/lib/db/schemas, which violates the separation between main and renderer processes. Even though it's just a type import, this creates coupling to main-process code.

Consider moving the ExternalApp type to a shared location (e.g., src/lib/types/external.ts or similar) that both main and renderer can import from. This maintains proper process boundaries in the Electron architecture.

As per coding guidelines, renderer code should remain browser-environment compatible and not depend on main process modules.

⛔ Skipped due to learnings
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
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/renderer/**/*.{ts,tsx} : Never import Node.js modules (fs, path, os, net, etc.) in renderer process code - browser environment only
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/main/**/*.{ts,tsx} : Node.js modules (fs, path, os, net, etc.) can be used in main process code only
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,js,jsx} : For Electron interprocess communication, ALWAYS use tRPC as defined in `src/lib/trpc`
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/main/lib/*-ipcs.ts : IPC handlers must accept a single object parameter, not positional parameters, to match type-safe renderer calls
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/db/src/**/*.ts : Define all database schema in `packages/db/src/` using Drizzle ORM
apps/desktop/src/lib/trpc/routers/config/config.ts (5)

1-10: File system utilities are correctly scoped.

The Node.js imports (node:fs, node:path) are appropriate here since tRPC routers run in the main process. The configExists helper is a straightforward existence check.


12-16: Config template is clear and functional.

The template provides a valid starting structure for the configuration file with empty arrays for setup and teardown commands.


40-55: Toast visibility logic is sound.

The procedure correctly guards against missing projects, respects the dismissal flag, and accurately determines toast visibility based on config file existence. The early returns make the logic easy to follow.


57-68: Dismissal mutation is implemented correctly.

The procedure properly updates the database to mark the toast as dismissed, uses async/await appropriately, and returns a success indicator.


70-80: Query with side effects—verify this is intentional.

The getConfigFilePath query calls ensureConfigExists, which creates directories and files as a side effect. tRPC queries are typically read-only operations, while mutations handle state changes.

If this auto-creation behavior is intentional (e.g., to ensure config always exists when accessed), consider:

  1. Documenting this behavior in a comment
  2. Alternatively, splitting into a separate mutation like ensureAndGetConfigFilePath to make the side effect explicit

Example documentation:

// Get the config file path (creates it if it doesn't exist)
// Note: This query has side effects—it will create .superset/config.json
// if it doesn't already exist. This ensures the path is always valid.
getConfigFilePath: publicProcedure

Verify this design aligns with your team's tRPC patterns for side-effecting operations.

Comment on lines +22 to +36
function ensureConfigExists(mainRepoPath: string): string {
const configPath = getConfigPath(mainRepoPath);
const supersetDir = join(mainRepoPath, ".superset");

if (!existsSync(configPath)) {
// Create .superset directory if it doesn't exist
if (!existsSync(supersetDir)) {
mkdirSync(supersetDir, { recursive: true });
}
// Create config.json with template
writeFileSync(configPath, CONFIG_TEMPLATE, "utf-8");
}

return configPath;
}
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟠 Major

Add error handling for file system operations.

The ensureConfigExists function performs file system operations (mkdirSync, writeFileSync) without error handling. Operations can fail due to permissions, disk space, or other I/O issues, potentially causing unhandled exceptions.

Consider wrapping in try-catch to provide better error feedback:

function ensureConfigExists(mainRepoPath: string): string {
	const configPath = getConfigPath(mainRepoPath);
	const supersetDir = join(mainRepoPath, ".superset");

	try {
		if (!existsSync(configPath)) {
			if (!existsSync(supersetDir)) {
				mkdirSync(supersetDir, { recursive: true });
			}
			writeFileSync(configPath, CONFIG_TEMPLATE, "utf-8");
		}
		return configPath;
	} catch (error) {
		throw new Error(`Failed to create config file: ${error instanceof Error ? error.message : 'Unknown error'}`);
	}
}

This ensures failures are caught and reported with context rather than causing silent crashes.

🤖 Prompt for AI Agents
In apps/desktop/src/lib/trpc/routers/config/config.ts around lines 22 to 36, the
ensureConfigExists function performs filesystem operations (mkdirSync,
writeFileSync) without error handling; wrap the block that checks/creates the
.superset directory and writes config.json in a try-catch, on error throw or
rethrow a new Error with contextual message including the original error message
(safely checking error instanceof Error), so callers receive a clear, readable
failure reason instead of an unhandled exception.

Comment on lines +66 to +82
const showConfigToastIfNeeded = (data: {
initialCommands: string[] | null;
projectId: string;
}) => {
if (!data.initialCommands || data.initialCommands.length === 0) {
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 });
},
});
}
};
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟠 Major

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
# Search for shouldShowConfigToast usage
rg "shouldShowConfigToast" --type ts --type tsx -A 3 -B 3

Repository: superset-sh/superset

Length of output: 91


🏁 Script executed:

#!/bin/bash
# Search for config-related TRPC routes to understand the API
fd "config" --type f | grep -E "(trpc|router)" | head -20

Repository: superset-sh/superset

Length of output: 114


🏁 Script executed:

#!/bin/bash
# Check the StartView file to see current imports and usage
cat -n apps/desktop/src/renderer/screens/main/components/StartView/index.tsx | head -100

Repository: superset-sh/superset

Length of output: 4331


🏁 Script executed:

#!/bin/bash
# Search for dismissConfigToast to understand how dismissal is implemented
rg "dismissConfigToast" --type ts --type tsx -B 5 -A 5

Repository: superset-sh/superset

Length of output: 91


🏁 Script executed:

#!/bin/bash
# Read the config TRPC router to see all available queries and mutations
cat apps/desktop/src/lib/trpc/routers/config/config.ts

Repository: superset-sh/superset

Length of output: 2424


🏁 Script executed:

#!/bin/bash
# Search for shouldShowConfigToast with correct file types
rg "shouldShowConfigToast" -t ts

Repository: superset-sh/superset

Length of output: 155


🏁 Script executed:

#!/bin/bash
# Search for dismissal-related code in config
rg "dismissConfig" -t ts -A 5 -B 5

Repository: superset-sh/superset

Length of output: 6087


🏁 Script executed:

#!/bin/bash
# Find all config-related files
fd "config" --type f -E node_modules | grep -v ".git"

Repository: superset-sh/superset

Length of output: 853


Add shouldShowConfigToast query check before displaying the toast.

The showConfigToastIfNeeded function shows the toast whenever initialCommands is empty, but doesn't check if the user previously dismissed it for this project. While dismissConfigToast.mutate() persists the dismissal server-side via project.configToastDismissed, the client-side check is missing. The shouldShowConfigToast query is available in the TRPC config router and already handles this dismissal check—use it before showing the toast to prevent repeated prompts after dismissal.

Comment on lines 25 to 27
const openConfigModal = useOpenConfigModal();
const dismissConfigToast = trpc.config.dismissConfigToast.useMutation();

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟡 Minor

🧩 Analysis chain

🏁 Script executed:

fd WorkspaceDropdown.tsx

Repository: superset-sh/superset

Length of output: 156


🏁 Script executed:

cat -n apps/desktop/src/renderer/screens/main/components/TopBar/WorkspaceTabs/WorkspaceDropdown.tsx

Repository: superset-sh/superset

Length of output: 4760


🏁 Script executed:

rg "shouldShowConfigToast" --type ts --type tsx

Repository: superset-sh/superset

Length of output: 91


🏁 Script executed:

rg "dismissConfigToast" --type ts --type tsx -A 3 -B 3

Repository: superset-sh/superset

Length of output: 91


🏁 Script executed:

fd "config" apps/desktop/src --type d | head -20

Repository: superset-sh/superset

Length of output: 160


🏁 Script executed:

rg "shouldShowConfigToast" -t ts

Repository: superset-sh/superset

Length of output: 155


🏁 Script executed:

rg "dismissConfigToast" -t ts -A 3 -B 3

Repository: superset-sh/superset

Length of output: 3977


🏁 Script executed:

cat -n apps/desktop/src/lib/trpc/routers/config/index.ts

Repository: superset-sh/superset

Length of output: 170


🏁 Script executed:

cat -n apps/desktop/src/lib/trpc/routers/config/config.ts

Repository: superset-sh/superset

Length of output: 3005


🏁 Script executed:

sed -n '1,150p' apps/desktop/src/renderer/screens/main/components/StartView/index.tsx | grep -A 30 "dismissConfigToast"

Repository: superset-sh/superset

Length of output: 1448


Call trpc.config.shouldShowConfigToast before showing the config toast

The toast is shown whenever there are no initialCommands, but the dismissal state is never checked before display. The dismissConfigToast mutation persists dismissal to the database (setting configToastDismissed flag), but shouldShowConfigToast is never queried to gate the toast. This means the toast will reappear on every workspace creation without initialCommands, even after the user has dismissed it for that project.

Add a check:

const shouldShow = await trpc.config.shouldShowConfigToast.useQuery({ projectId });
if (shouldShow.data) {
  // show toast
}
🤖 Prompt for AI Agents
In
apps/desktop/src/renderer/screens/main/components/TopBar/WorkspaceTabs/WorkspaceDropdown.tsx
around lines 25 to 27, the config toast is shown without checking persisted
dismissal state; add a top-level TRPC query using
trpc.config.shouldShowConfigToast.useQuery({ projectId }) (not an imperative
mutation) and use its returned data to gate showing the toast: only show the
toast when there are no initialCommands AND shouldShowConfigToast.data is
truthy; ensure the hook is called unconditionally at component top-level and
handle loading/undefined safely before deciding to show the toast.

Comment on lines +163 to +165
Add <code className="text-amber-400">.superset/</code> to your{" "}
<code className="text-amber-400">.gitignore</code> if you
don&apos;t want to share configs
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟡 Minor

Clarify the gitignore advice to align with tracked config.

The tip suggests adding .superset/ to .gitignore, but this PR specifically tracks .superset/config.json in version control. Consider revising this tip to clarify that users can ignore the directory while still tracking specific files, or remove this tip to avoid confusion with the project's established pattern.

Apply this diff to clarify the guidance:

 							<li>
-								Add <code className="text-amber-400">.superset/</code> to your{" "}
-								<code className="text-amber-400">.gitignore</code> if you
-								don&apos;t want to share configs
+								The config file can be committed to share workspace setup with your team,
+								or kept local if you prefer different setups per developer
 							</li>
-							<li>Or commit it to share workspace setup with your team</li>

Committable suggestion skipped: line range outside the PR's diff.

🤖 Prompt for AI Agents
In apps/website/src/app/scripts/page.tsx around lines 163 to 165, the current
tip tells users to add ".superset/" to .gitignore which conflicts with this repo
tracking ".superset/config.json"; update the copy to clarify that you can ignore
the .superset/ directory while still tracking specific files (e.g., keep
.superset/config.json in source control) or remove the tip entirely to avoid
confusion; adjust the sentence to explicitly mention preserving
.superset/config.json if the ignore rule is recommended.

- 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 <noreply@anthropic.com>
@saddlepaddle saddlepaddle merged commit 762b7fe into main Dec 1, 2025
7 checks passed
Kitenite added a commit that referenced this pull request Dec 2, 2025
- 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 <noreply@anthropic.com>
@Kitenite Kitenite deleted the jade-ocean-28 branch December 2, 2025 02:26
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant