Skip to content

worktree#140

Closed
Kitenite wants to merge 10 commits intomainfrom
worktree
Closed

worktree#140
Kitenite wants to merge 10 commits intomainfrom
worktree

Conversation

@Kitenite
Copy link
Copy Markdown
Collaborator

@Kitenite Kitenite commented Nov 24, 2025

  • working setup worktree using script

Summary by CodeRabbit

Release Notes

  • New Features

    • Added workspace setup workflow: automatically loads setup configuration, copies files matching patterns, and executes setup commands during workspace creation.
    • Added Setup tab view with interactive terminal for running workspace initialization commands and displaying file copy results.
    • Enhanced Terminal component with session-ready callbacks for programmatic terminal control.
  • Tests

    • Added comprehensive test coverage for setup configuration loading and file copying utilities.
  • Chores

    • Import reorganization and code formatting improvements across components.

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

@coderabbitai
Copy link
Copy Markdown
Contributor

coderabbitai Bot commented Nov 24, 2025

Walkthrough

This PR introduces a workspace setup workflow that loads setup configuration from a setup.json file, copies specified files to new workspaces, and executes setup commands in a dedicated Setup Tab within the workspace's terminal interface. The feature integrates with the workspace creation flow, tab system, TRPC router, and terminal components.

Changes

Cohort / File(s) Summary
Setup utilities & tests
apps/desktop/src/lib/trpc/routers/workspaces/utils/setup.ts, setup.test.ts
New utilities for loading .superset/setup.json config and copying glob-matched files to worktree paths. Test coverage for config validation, file copying, error handling, and directory creation.
Workspace creation flow
apps/desktop/src/lib/trpc/routers/workspaces/workspaces.ts
Enhanced workspace create mutation to load setup config, copy files, and return composite object with workspace, setupConfig, setupCopyResults, and worktreePath.
Tab types & store
apps/desktop/src/renderer/stores/tabs/types.ts, store.ts, helpers/tab-crud.ts
Added SetupTab type to TabType enum. New SetupTab interface with setupCommands, setupCwd, setupPending, and setupCopyResults. Introduced addSetupTab action and handleAddSetupTab helper.
Setup tab UI components
apps/desktop/src/renderer/screens/main/components/WorkspaceView/ContentView/TabsContent/SetupTabView/SetupTabView.tsx, SetupTerminal.tsx, index.ts
New SetupTabView component wrapping SetupTerminal. SetupTerminal renders xterm instance, displays setup status, executes setup commands via TRPC, streams output, and handles resizing.
Terminal component enhancements
apps/desktop/src/renderer/screens/main/components/WorkspaceView/ContentView/TabsContent/Terminal/Terminal.tsx, types.ts
Added optional title and onSessionReady props to Terminal. New TerminalSession type. Session readiness callback invoked once with xterm instance and write function.
Tab content routing
apps/desktop/src/renderer/screens/main/components/WorkspaceView/ContentView/TabsContent/index.tsx
Added render branch for TabType.Setup to render SetupTabView alongside existing SingleTabView and GroupTabView.
React Query integration
apps/desktop/src/renderer/react-query/workspaces/useCreateWorkspace.ts
Modified useCreateWorkspace onSuccess to call addSetupTab when setupConfig contains commands.
UI component fixes
apps/desktop/src/renderer/screens/main/components/WorkspaceView/ContentView/TabsContent/GroupTabView/GroupTabPane.tsx, TopBar/WorkspaceTabs/WorkspaceDropdown.tsx
Added Button and HiMiniXMark imports for close toolbar button. Import reordering.
Terminal manager tests
apps/desktop/src/main/lib/terminal-manager.test.ts
Added tabTitle and workspaceName fields to createOrAttach calls across test cases.
Website component cleanup
apps/website/src/app/components/{DownloadButton,Header,JoinWaitlistButton,SocialLinks,VideoSection}/*
Removed component re-exports from barrel index files; reorganized Header imports.
Import reorganizations
apps/desktop/src/{lib/trpc/routers/notifications.ts,main/lib/{agent-setup.ts,terminal-history.test.ts,terminal-manager.ts},main/windows/main.ts}
Consolidated and reordered imports across multiple files. Changed @ts-ignore to @ts-expect-error in terminal-history.test.ts.
Minor updates
apps/desktop/src/renderer/globals.css, apps/desktop/src/shared/ipc-channels/external.ts, apps/desktop/test-setup.ts, .superset/setup.json, packages/ui/src/components/alert-dialog.tsx
CSS color token normalization, ExternalChannels interface-to-type conversion, BrowserWindow mock refactor, setup.json command update, alert-dialog formatting.

Sequence Diagram(s)

sequenceDiagram
    actor User
    participant CreateWorkspace as Workspace<br/>Creation Mutation
    participant SetupUtils as Setup<br/>Utilities
    participant FileSystem as File<br/>System
    participant FS as File<br/>Copy
    participant React as React Query<br/>Hook
    participant Store as Tabs<br/>Store
    participant UI as Setup<br/>Tab UI

    User->>CreateWorkspace: Create workspace
    CreateWorkspace->>SetupUtils: loadSetupConfig()
    SetupUtils->>FileSystem: Read .superset/setup.json
    FileSystem-->>SetupUtils: Config (or null)
    
    alt Config exists with patterns
        CreateWorkspace->>SetupUtils: copySetupFiles(patterns)
        SetupUtils->>FS: Glob match files
        FS->>FileSystem: Copy matched files
        FileSystem-->>FS: Success/errors
        FS-->>SetupUtils: { copied, errors }
    end
    
    CreateWorkspace-->>React: Return<br/>(workspace, setupConfig,<br/>setupCopyResults)
    React->>Store: addSetupTab(setupCommands,<br/>setupCwd, copyResults)
    Store-->>UI: Create SetupTab
    UI->>UI: Launch SetupTerminal
Loading

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~25 minutes

  • Areas requiring extra attention:
    • SetupTerminal component: Verify xterm lifecycle, TRPC session creation/streaming integration, resize handling, and proper cleanup on unmount.
    • Store integration: Ensure handleAddSetupTab correctly manages tab history and activeTabIds when inserting setup tab.
    • Workspace mutation return type change: Confirm all consumers of workspace creation handle the new composite return object (workspace, setupConfig, setupCopyResults, worktreePath).
    • Terminal component session callback: Verify onSessionReady is called exactly once and that the TerminalSession object provides expected functionality.
    • File copying logic: Review glob pattern matching, dotfile inclusion, and error aggregation in copySetupFiles.

Possibly related PRs

  • Create a worktree for each opened branch #113: Both modify workspace creation flow in workspaces.ts; #113 adds git worktree creation and data model changes that complement this PR's setup config/file copying logic.
  • node pty processes #117: Both enhance terminal/session APIs (Terminal component props and createOrAttach signature changes) and introduce terminal-manager/terminal router flows for setup integration.
  • new desktop #101: Overlapping setup feature implementation—both introduce setup config reading (loadSetupConfig/readSetupConfig) and file copying (copySetupFiles/copyFiles) utilities with similar semantics.

Poem

🐰 Hop hop, a setup flow takes shape,
With tabs and terminals, files escape,
Config reads true, commands run free,
From copy to stream, a workspace symphony!
Setup pending? No worry, dear—
Our xterm's here! 🎉

Pre-merge checks and finishing touches

❌ Failed checks (2 warnings, 1 inconclusive)
Check name Status Explanation Resolution
Description check ⚠️ Warning The description is incomplete; it only contains a single bullet point and lacks most required template sections including Related Issues, Type of Change, Testing, and Additional Notes. Complete the PR description by filling in all template sections: add related issue links, select the type of change (appears to be a New feature), describe testing performed, and provide additional context about the setup worktree implementation.
Docstring Coverage ⚠️ Warning Docstring coverage is 18.18% which is insufficient. The required threshold is 80.00%. You can run @coderabbitai generate docstrings to improve docstring coverage.
Title check ❓ Inconclusive The title 'worktree' is vague and does not clearly summarize the main changes; it lacks specificity about what setup functionality is being added. Use a more descriptive title that explains the primary change, such as 'Add setup worktree utilities for workspace creation' or 'Implement setup configuration and file copying for workspaces'.
✨ 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 worktree

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: 2

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

14-26: Consider validating array element types.

The validation checks if copy and commands are arrays, but doesn't verify that each element is a string. Invalid element types could cause runtime errors in copySetupFiles or when executing commands.

Apply this diff to add element validation:

 	if (parsed.copy && !Array.isArray(parsed.copy)) {
 		throw new Error("'copy' field must be an array of strings");
 	}
+	if (parsed.copy && !parsed.copy.every((item) => typeof item === "string")) {
+		throw new Error("'copy' field must contain only strings");
+	}

 	if (parsed.commands && !Array.isArray(parsed.commands)) {
 		throw new Error("'commands' field must be an array of strings");
 	}
+	if (parsed.commands && !parsed.commands.every((item) => typeof item === "string")) {
+		throw new Error("'commands' field must contain only strings");
+	}
apps/desktop/src/lib/trpc/routers/workspaces/utils/setup.test.ts (1)

50-58: Consider adding test coverage for commands field validation.

The test suite validates that copy must be an array, but there's no corresponding test for the commands field validation (which has identical logic at lines 22-24 in setup.ts).

Add a test case:

test("validates commands field must be an array", () => {
	writeFileSync(
		join(MAIN_REPO, ".superset", "setup.json"),
		JSON.stringify({ commands: "not-an-array" }),
	);

	const config = loadSetupConfig(MAIN_REPO);
	expect(config).toBeNull();
});
apps/desktop/src/lib/trpc/routers/workspaces/workspaces.ts (1)

109-114: Consider documenting the return type transformation.

The function returns setupConfig: setupConfig?.commands || null, extracting only the commands array from the full config. This transformation means the UI only receives commands, not the copy patterns. While this appears intentional (copy happens server-side), documenting this choice would help future maintainers.

Add a comment:

+	// Return only commands (copy patterns already processed)
 	return {
 		workspace,
 		setupConfig: setupConfig?.commands || null,
 		setupCopyResults,
 		worktreePath,
 	};
📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 0507561 and 45a9a13.

📒 Files selected for processing (8)
  • apps/desktop/src/lib/trpc/routers/workspaces/utils/setup.test.ts (1 hunks)
  • apps/desktop/src/lib/trpc/routers/workspaces/utils/setup.ts (1 hunks)
  • apps/desktop/src/lib/trpc/routers/workspaces/workspaces.ts (3 hunks)
  • apps/desktop/src/renderer/react-query/workspaces/useCreateWorkspace.ts (1 hunks)
  • apps/desktop/src/renderer/screens/main/components/WorkspaceView/ContentView/TabsContent/Terminal/Terminal.tsx (3 hunks)
  • apps/desktop/src/renderer/stores/tabs/helpers/tab-crud.ts (1 hunks)
  • apps/desktop/src/renderer/stores/tabs/store.ts (2 hunks)
  • apps/desktop/src/renderer/stores/tabs/types.ts (2 hunks)
🧰 Additional context used
🧬 Code graph analysis (5)
apps/desktop/src/renderer/screens/main/components/WorkspaceView/ContentView/TabsContent/Terminal/Terminal.tsx (1)
apps/desktop/src/renderer/stores/tabs/store.ts (1)
  • useTabsStore (36-167)
apps/desktop/src/renderer/react-query/workspaces/useCreateWorkspace.ts (1)
apps/desktop/src/renderer/stores/tabs/store.ts (1)
  • useTabsStore (36-167)
apps/desktop/src/lib/trpc/routers/workspaces/utils/setup.test.ts (1)
apps/desktop/src/lib/trpc/routers/workspaces/utils/setup.ts (2)
  • loadSetupConfig (7-33)
  • copySetupFiles (35-79)
apps/desktop/src/lib/trpc/routers/workspaces/utils/setup.ts (1)
apps/desktop/src/shared/types.ts (1)
  • SetupConfig (130-133)
apps/desktop/src/lib/trpc/routers/workspaces/workspaces.ts (1)
apps/desktop/src/lib/trpc/routers/workspaces/utils/setup.ts (2)
  • loadSetupConfig (7-33)
  • copySetupFiles (35-79)
⏰ 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 (11)
apps/desktop/src/lib/trpc/routers/workspaces/utils/setup.ts (2)

45-50: Verify symbolic link handling is intentional.

The followSymbolicLinks: false option prevents following symlinks. If users have symlinked configuration files (e.g., shared .env files), they won't be copied. Ensure this behavior aligns with the intended use case.


35-79: LGTM! Comprehensive error handling.

The function properly handles errors at multiple levels (glob, file copy) and aggregates them for the caller. The use of recursive: true for directory creation is appropriate.

apps/desktop/src/renderer/stores/tabs/store.ts (1)

48-63: LGTM! Consistent with existing patterns.

The addSetupTab action follows the established pattern of delegating to a helper function and properly forwards all parameters through the Zustand state setter.

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

75-124: LGTM! Comprehensive file copy testing.

The test suite covers key scenarios: empty patterns, glob matching, nested directories, error cases, and multiple file matching. The cleanup logic properly removes test directories.

apps/desktop/src/renderer/screens/main/components/WorkspaceView/ContentView/TabsContent/Terminal/Terminal.tsx (2)

176-214: Setup execution flow looks solid.

The guard ensures setup runs exactly once per terminal attachment, copy results are displayed before command execution, and the tab state is updated to reflect completion. The implementation properly integrates with the existing terminal flow.


204-206: The review comment's concern is incorrect and based on a misunderstanding of shell behavior.

When commands separated by newlines are written to a shell's stdin (via a PTY), the shell processes them sequentially by default. Each command waits for the previous one to complete before starting—this is standard POSIX shell behavior. The backend writes directly to the PTY using node-pty without buffering or batching, so commands are delivered correctly to the shell.

The code at lines 205-206 properly executes setup commands sequentially as written. Using && between commands would add error handling (stopping if a command fails), but it's not necessary for sequential execution.

Likely an incorrect or invalid review comment.

apps/desktop/src/renderer/stores/tabs/helpers/tab-crud.ts (1)

98-132: LGTM! Consistent implementation.

The handleAddSetupTab function properly mirrors the handleAddTab pattern, correctly manages tab history, and sets all setup-related properties. The implementation is clean and maintains consistency with existing tab operations.

apps/desktop/src/renderer/stores/tabs/types.ts (2)

15-18: LGTM! Well-defined setup properties.

The setup-related properties are appropriately typed and optional, allowing tabs to exist with or without setup metadata. The structure clearly captures all necessary setup information.


40-45: LGTM! Clear method signature.

The addSetupTab signature is well-defined with explicit types for all parameters, making the optional setupCopyResults parameter clear and type-safe.

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

84-107: Solid error handling for setup file copying.

The implementation properly treats file copy errors as non-fatal, allowing workspace creation to succeed even if some files fail to copy. The error messages are informative and include context.


176-176: Good defensive programming.

The optional chaining prevents runtime errors if groupsMap.get() returns undefined, which shouldn't happen based on the logic but adds safety.

const pendingEventsRef = useRef<TerminalStreamEvent[]>([]);
const [subscriptionEnabled, setSubscriptionEnabled] = useState(false);
const setActiveTab = useSetActiveTab();
const setupExecutedRef = useRef(false);
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

Setup execution guard is component-scoped, not tab-scoped.

The setupExecutedRef persists across the component lifecycle. If the component renders for a different tabId (e.g., switching tabs and back), the ref won't reset, potentially preventing setup from running for a different setup tab. Consider making the ref tab-specific:

-const setupExecutedRef = useRef(false);
+const setupExecutedRef = useRef<Record<string, boolean>>({});

Then update the guard condition at line 180:

-	!setupExecutedRef.current
+	!setupExecutedRef.current[tabId]

And set it at line 182:

-setupExecutedRef.current = true;
+setupExecutedRef.current[tabId] = true;

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

🤖 Prompt for AI Agents
In
apps/desktop/src/renderer/screens/main/components/WorkspaceView/ContentView/TabsContent/Terminal/Terminal.tsx
around line 25 (and update usages at ~180 and ~182), the setupExecutedRef is
currently component-scoped and prevents setup from running when switching to a
different tabId; change it to be tab-scoped by replacing the single boolean ref
with a keyed store (e.g., useRef<Record<string, boolean>>({}) or useRef(new
Map<string, boolean>())), update the guard at line ~180 to check the entry for
the current tabId (e.g., !setupExecutedRef.current[tabId] or
!setupExecutedRef.current.get(tabId)), and set the tab-specific flag at line
~182 after running setup (e.g., setupExecutedRef.current[tabId] = true or
setupExecutedRef.current.set(tabId, true)).

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: 3

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
apps/desktop/src/renderer/screens/main/components/WorkspaceView/ContentView/TabsContent/GroupTabView/GroupTabPane.tsx (1)

55-65: Remove leading space in className.

The Button implementation is correct, but the className on line 61 has an unnecessary leading space.

Apply this diff:

-					className=" hover:text-white/80"
+					className="hover:text-white/80"
♻️ Duplicate comments (1)
apps/desktop/src/renderer/screens/main/components/WorkspaceView/ContentView/TabsContent/Terminal/Terminal.tsx (1)

14-21: onSessionReady guard is component‑scoped; may skip callbacks for other tabIds.

sessionReadyCalledRef is a single boolean shared across all uses of this Terminal instance. If the same component instance is ever reused with a different tabId (e.g., React keeps the component and just changes props), the effect will re‑run for the new tab, but onSessionReady will not fire because sessionReadyCalledRef.current is already true. That can prevent setup logic (or any other caller of onSessionReady) from running for subsequent tabs.

Consider making the guard tab‑scoped instead of component‑scoped, e.g.:

-const sessionReadyCalledRef = useRef(false);
+const sessionReadyCalledRef = useRef<Record<string, boolean>>({});

...

-					if (onSessionReady && !sessionReadyCalledRef.current) {
-						sessionReadyCalledRef.current = true;
+					if (onSessionReady && !sessionReadyCalledRef.current[tabId]) {
+						sessionReadyCalledRef.current[tabId] = true;
 						onSessionReady({
 							xterm,
 							write: (data: string) => writeRef.current({ tabId, data }),
 						});
 					}

This preserves the “once per tab” behavior while still allowing Terminal to be reused safely across different tabId values.

Also applies to: 28-29, 168-217

🧹 Nitpick comments (2)
apps/desktop/src/renderer/screens/main/components/WorkspaceView/ContentView/TabsContent/SetupTabView.tsx (1)

1-49: SetupTabView wiring matches other tab views; consider trimming unused pieces.

The split/remove wiring and use of TabContentContextMenu plus SetupTerminal look consistent with the existing tab patterns. Right now isDropZone and handleFocus are unused in this component; if there’s no near‑term plan to use them (e.g., for styling or manual focus), you could drop them to keep the surface minimal.

apps/desktop/src/renderer/screens/main/components/WorkspaceView/ContentView/TabsContent/Terminal/useTerminalSetup.ts (1)

10-15: Consider exporting UseTerminalSetupParams for consistency.

While this interface is currently only used internally, exporting it would improve type consistency and enable potential future consumers to type-check their parameters before passing them to the hook.

-interface UseTerminalSetupParams {
+export interface UseTerminalSetupParams {
 	tabId: string;
 	setupPending?: boolean;
 	setupCommands?: string[];
 	setupCopyResults?: SetupCopyResults;
 }
📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 45a9a13 and e2a02fd.

📒 Files selected for processing (27)
  • apps/desktop/src/lib/trpc/routers/notifications.ts (1 hunks)
  • apps/desktop/src/main/lib/agent-setup.ts (1 hunks)
  • apps/desktop/src/main/lib/terminal-history.test.ts (2 hunks)
  • apps/desktop/src/main/lib/terminal-manager.ts (1 hunks)
  • apps/desktop/src/main/windows/main.ts (1 hunks)
  • apps/desktop/src/renderer/globals.css (2 hunks)
  • apps/desktop/src/renderer/screens/main/components/TopBar/WorkspaceTabs/WorkspaceDropdown.tsx (1 hunks)
  • apps/desktop/src/renderer/screens/main/components/WorkspaceView/ContentView/TabsContent/GroupTabView/GroupTabPane.tsx (1 hunks)
  • apps/desktop/src/renderer/screens/main/components/WorkspaceView/ContentView/TabsContent/SetupTabView.tsx (1 hunks)
  • apps/desktop/src/renderer/screens/main/components/WorkspaceView/ContentView/TabsContent/Terminal/SetupTerminal.tsx (1 hunks)
  • apps/desktop/src/renderer/screens/main/components/WorkspaceView/ContentView/TabsContent/Terminal/Terminal.tsx (3 hunks)
  • apps/desktop/src/renderer/screens/main/components/WorkspaceView/ContentView/TabsContent/Terminal/index.ts (1 hunks)
  • apps/desktop/src/renderer/screens/main/components/WorkspaceView/ContentView/TabsContent/Terminal/types.ts (1 hunks)
  • apps/desktop/src/renderer/screens/main/components/WorkspaceView/ContentView/TabsContent/Terminal/useTerminalSetup.ts (1 hunks)
  • apps/desktop/src/renderer/screens/main/components/WorkspaceView/ContentView/TabsContent/index.tsx (2 hunks)
  • apps/desktop/src/renderer/stores/tabs/helpers/tab-crud.ts (1 hunks)
  • apps/desktop/src/renderer/stores/tabs/types.ts (3 hunks)
  • apps/desktop/src/shared/ipc-channels/external.ts (1 hunks)
  • apps/desktop/test-setup.ts (1 hunks)
  • apps/website/src/app/components/DownloadButton/index.ts (0 hunks)
  • apps/website/src/app/components/Header/Header.tsx (1 hunks)
  • apps/website/src/app/components/JoinWaitlistButton/index.ts (0 hunks)
  • apps/website/src/app/components/SocialLinks/SocialLinks.tsx (0 hunks)
  • apps/website/src/app/components/SocialLinks/index.ts (0 hunks)
  • apps/website/src/app/components/VideoSection/VideoSection.tsx (0 hunks)
  • apps/website/src/app/components/VideoSection/index.ts (0 hunks)
  • packages/ui/src/components/alert-dialog.tsx (1 hunks)
💤 Files with no reviewable changes (6)
  • apps/website/src/app/components/VideoSection/VideoSection.tsx
  • apps/website/src/app/components/DownloadButton/index.ts
  • apps/website/src/app/components/SocialLinks/SocialLinks.tsx
  • apps/website/src/app/components/VideoSection/index.ts
  • apps/website/src/app/components/JoinWaitlistButton/index.ts
  • apps/website/src/app/components/SocialLinks/index.ts
✅ Files skipped from review due to trivial changes (2)
  • packages/ui/src/components/alert-dialog.tsx
  • apps/desktop/src/renderer/screens/main/components/TopBar/WorkspaceTabs/WorkspaceDropdown.tsx
🧰 Additional context used
📓 Path-based instructions (9)
**/*.{ts,tsx,js,jsx,json}

📄 CodeRabbit inference engine (AGENTS.md)

Apply Biome formatting, linting, and import organization at the root level for all code files

Files:

  • apps/desktop/src/renderer/stores/tabs/helpers/tab-crud.ts
  • apps/desktop/src/lib/trpc/routers/notifications.ts
  • apps/desktop/src/renderer/screens/main/components/WorkspaceView/ContentView/TabsContent/Terminal/useTerminalSetup.ts
  • apps/desktop/src/renderer/screens/main/components/WorkspaceView/ContentView/TabsContent/SetupTabView.tsx
  • apps/desktop/src/main/windows/main.ts
  • apps/desktop/src/renderer/stores/tabs/types.ts
  • apps/desktop/src/shared/ipc-channels/external.ts
  • apps/desktop/src/renderer/screens/main/components/WorkspaceView/ContentView/TabsContent/Terminal/index.ts
  • apps/desktop/src/renderer/screens/main/components/WorkspaceView/ContentView/TabsContent/index.tsx
  • apps/desktop/src/main/lib/agent-setup.ts
  • apps/desktop/src/main/lib/terminal-history.test.ts
  • apps/desktop/src/renderer/screens/main/components/WorkspaceView/ContentView/TabsContent/GroupTabView/GroupTabPane.tsx
  • apps/desktop/src/main/lib/terminal-manager.ts
  • apps/desktop/test-setup.ts
  • apps/desktop/src/renderer/screens/main/components/WorkspaceView/ContentView/TabsContent/Terminal/SetupTerminal.tsx
  • apps/website/src/app/components/Header/Header.tsx
  • apps/desktop/src/renderer/screens/main/components/WorkspaceView/ContentView/TabsContent/Terminal/Terminal.tsx
  • apps/desktop/src/renderer/screens/main/components/WorkspaceView/ContentView/TabsContent/Terminal/types.ts
**/*.{ts,tsx}

📄 CodeRabbit inference engine (AGENTS.md)

**/*.{ts,tsx}: Avoid using any type; use type-safe approaches instead, unless necessary
Ensure TypeScript type checking passes across all packages using bun run typecheck

Files:

  • apps/desktop/src/renderer/stores/tabs/helpers/tab-crud.ts
  • apps/desktop/src/lib/trpc/routers/notifications.ts
  • apps/desktop/src/renderer/screens/main/components/WorkspaceView/ContentView/TabsContent/Terminal/useTerminalSetup.ts
  • apps/desktop/src/renderer/screens/main/components/WorkspaceView/ContentView/TabsContent/SetupTabView.tsx
  • apps/desktop/src/main/windows/main.ts
  • apps/desktop/src/renderer/stores/tabs/types.ts
  • apps/desktop/src/shared/ipc-channels/external.ts
  • apps/desktop/src/renderer/screens/main/components/WorkspaceView/ContentView/TabsContent/Terminal/index.ts
  • apps/desktop/src/renderer/screens/main/components/WorkspaceView/ContentView/TabsContent/index.tsx
  • apps/desktop/src/main/lib/agent-setup.ts
  • apps/desktop/src/main/lib/terminal-history.test.ts
  • apps/desktop/src/renderer/screens/main/components/WorkspaceView/ContentView/TabsContent/GroupTabView/GroupTabPane.tsx
  • apps/desktop/src/main/lib/terminal-manager.ts
  • apps/desktop/test-setup.ts
  • apps/desktop/src/renderer/screens/main/components/WorkspaceView/ContentView/TabsContent/Terminal/SetupTerminal.tsx
  • apps/website/src/app/components/Header/Header.tsx
  • apps/desktop/src/renderer/screens/main/components/WorkspaceView/ContentView/TabsContent/Terminal/Terminal.tsx
  • apps/desktop/src/renderer/screens/main/components/WorkspaceView/ContentView/TabsContent/Terminal/types.ts
apps/**/*.{tsx,ts}

📄 CodeRabbit inference engine (AGENTS.md)

apps/**/*.{tsx,ts}: Structure React applications with one folder per component following the pattern: ComponentName/ComponentName.tsx with index.ts barrel export
Co-locate component dependencies (hooks, utils, constants, tests, stories) next to the file using them

Files:

  • apps/desktop/src/renderer/stores/tabs/helpers/tab-crud.ts
  • apps/desktop/src/lib/trpc/routers/notifications.ts
  • apps/desktop/src/renderer/screens/main/components/WorkspaceView/ContentView/TabsContent/Terminal/useTerminalSetup.ts
  • apps/desktop/src/renderer/screens/main/components/WorkspaceView/ContentView/TabsContent/SetupTabView.tsx
  • apps/desktop/src/main/windows/main.ts
  • apps/desktop/src/renderer/stores/tabs/types.ts
  • apps/desktop/src/shared/ipc-channels/external.ts
  • apps/desktop/src/renderer/screens/main/components/WorkspaceView/ContentView/TabsContent/Terminal/index.ts
  • apps/desktop/src/renderer/screens/main/components/WorkspaceView/ContentView/TabsContent/index.tsx
  • apps/desktop/src/main/lib/agent-setup.ts
  • apps/desktop/src/main/lib/terminal-history.test.ts
  • apps/desktop/src/renderer/screens/main/components/WorkspaceView/ContentView/TabsContent/GroupTabView/GroupTabPane.tsx
  • apps/desktop/src/main/lib/terminal-manager.ts
  • apps/desktop/test-setup.ts
  • apps/desktop/src/renderer/screens/main/components/WorkspaceView/ContentView/TabsContent/Terminal/SetupTerminal.tsx
  • apps/website/src/app/components/Header/Header.tsx
  • apps/desktop/src/renderer/screens/main/components/WorkspaceView/ContentView/TabsContent/Terminal/Terminal.tsx
  • apps/desktop/src/renderer/screens/main/components/WorkspaceView/ContentView/TabsContent/Terminal/types.ts
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/stores/tabs/helpers/tab-crud.ts
  • apps/desktop/src/lib/trpc/routers/notifications.ts
  • apps/desktop/src/renderer/screens/main/components/WorkspaceView/ContentView/TabsContent/Terminal/useTerminalSetup.ts
  • apps/desktop/src/renderer/screens/main/components/WorkspaceView/ContentView/TabsContent/SetupTabView.tsx
  • apps/desktop/src/main/windows/main.ts
  • apps/desktop/src/renderer/stores/tabs/types.ts
  • apps/desktop/src/shared/ipc-channels/external.ts
  • apps/desktop/src/renderer/screens/main/components/WorkspaceView/ContentView/TabsContent/Terminal/index.ts
  • apps/desktop/src/renderer/screens/main/components/WorkspaceView/ContentView/TabsContent/index.tsx
  • apps/desktop/src/main/lib/agent-setup.ts
  • apps/desktop/src/main/lib/terminal-history.test.ts
  • apps/desktop/src/renderer/screens/main/components/WorkspaceView/ContentView/TabsContent/GroupTabView/GroupTabPane.tsx
  • apps/desktop/src/main/lib/terminal-manager.ts
  • apps/desktop/test-setup.ts
  • apps/desktop/src/renderer/screens/main/components/WorkspaceView/ContentView/TabsContent/Terminal/SetupTerminal.tsx
  • apps/desktop/src/renderer/screens/main/components/WorkspaceView/ContentView/TabsContent/Terminal/Terminal.tsx
  • apps/desktop/src/renderer/screens/main/components/WorkspaceView/ContentView/TabsContent/Terminal/types.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/stores/tabs/helpers/tab-crud.ts
  • apps/desktop/src/lib/trpc/routers/notifications.ts
  • apps/desktop/src/renderer/screens/main/components/WorkspaceView/ContentView/TabsContent/Terminal/useTerminalSetup.ts
  • apps/desktop/src/renderer/screens/main/components/WorkspaceView/ContentView/TabsContent/SetupTabView.tsx
  • apps/desktop/src/main/windows/main.ts
  • apps/desktop/src/renderer/stores/tabs/types.ts
  • apps/desktop/src/shared/ipc-channels/external.ts
  • apps/desktop/src/renderer/screens/main/components/WorkspaceView/ContentView/TabsContent/Terminal/index.ts
  • apps/desktop/src/renderer/screens/main/components/WorkspaceView/ContentView/TabsContent/index.tsx
  • apps/desktop/src/main/lib/agent-setup.ts
  • apps/desktop/src/main/lib/terminal-history.test.ts
  • apps/desktop/src/renderer/screens/main/components/WorkspaceView/ContentView/TabsContent/GroupTabView/GroupTabPane.tsx
  • apps/desktop/src/main/lib/terminal-manager.ts
  • apps/desktop/test-setup.ts
  • apps/desktop/src/renderer/screens/main/components/WorkspaceView/ContentView/TabsContent/Terminal/SetupTerminal.tsx
  • apps/desktop/src/renderer/screens/main/components/WorkspaceView/ContentView/TabsContent/Terminal/Terminal.tsx
  • apps/desktop/src/renderer/screens/main/components/WorkspaceView/ContentView/TabsContent/Terminal/types.ts
apps/**/*.tsx

📄 CodeRabbit inference engine (AGENTS.md)

Use one component per file; do not create multi-component files

Files:

  • apps/desktop/src/renderer/screens/main/components/WorkspaceView/ContentView/TabsContent/SetupTabView.tsx
  • apps/desktop/src/renderer/screens/main/components/WorkspaceView/ContentView/TabsContent/index.tsx
  • apps/desktop/src/renderer/screens/main/components/WorkspaceView/ContentView/TabsContent/GroupTabView/GroupTabPane.tsx
  • apps/desktop/src/renderer/screens/main/components/WorkspaceView/ContentView/TabsContent/Terminal/SetupTerminal.tsx
  • apps/website/src/app/components/Header/Header.tsx
  • apps/desktop/src/renderer/screens/main/components/WorkspaceView/ContentView/TabsContent/Terminal/Terminal.tsx
apps/desktop/src/renderer/**/*.tsx

📄 CodeRabbit inference engine (AGENTS.md)

Define keyboard shortcuts using the centralized system in apps/desktop/src/renderer/lib/shortcuts.ts with Arc Browser-inspired shortcut definitions

Files:

  • apps/desktop/src/renderer/screens/main/components/WorkspaceView/ContentView/TabsContent/SetupTabView.tsx
  • apps/desktop/src/renderer/screens/main/components/WorkspaceView/ContentView/TabsContent/index.tsx
  • apps/desktop/src/renderer/screens/main/components/WorkspaceView/ContentView/TabsContent/GroupTabView/GroupTabPane.tsx
  • apps/desktop/src/renderer/screens/main/components/WorkspaceView/ContentView/TabsContent/Terminal/SetupTerminal.tsx
  • apps/desktop/src/renderer/screens/main/components/WorkspaceView/ContentView/TabsContent/Terminal/Terminal.tsx
apps/**/*.test.{ts,tsx}

📄 CodeRabbit inference engine (AGENTS.md)

Co-locate tests with their corresponding components (e.g., Component.test.tsx next to Component.tsx)

Files:

  • apps/desktop/src/main/lib/terminal-history.test.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/main/lib/terminal-history.test.ts
🧠 Learnings (15)
📚 Learning: 2025-11-24T21:32:46.559Z
Learnt from: CR
Repo: superset-sh/superset PR: 0
File: AGENTS.md:0-0
Timestamp: 2025-11-24T21:32:46.559Z
Learning: Applies to apps/desktop/src/lib/electron-router-dom.ts : Do not import Node.js modules in apps/desktop/src/lib/electron-router-dom.ts as it is shared between main and renderer processes

Applied to files:

  • apps/desktop/src/lib/trpc/routers/notifications.ts
  • apps/desktop/src/main/lib/agent-setup.ts
  • apps/desktop/src/main/lib/terminal-manager.ts
📚 Learning: 2025-11-24T21:32:46.559Z
Learnt from: CR
Repo: superset-sh/superset PR: 0
File: AGENTS.md:0-0
Timestamp: 2025-11-24T21:32:46.559Z
Learning: Applies to apps/desktop/src/main/lib/*-ipcs.ts : Implement Electron IPC handlers in dedicated files under apps/desktop/src/main/lib/ (e.g., workspace-ipcs.ts, terminal-ipcs.ts)

Applied to files:

  • apps/desktop/src/renderer/screens/main/components/WorkspaceView/ContentView/TabsContent/Terminal/useTerminalSetup.ts
  • apps/desktop/src/renderer/screens/main/components/WorkspaceView/ContentView/TabsContent/SetupTabView.tsx
  • apps/desktop/src/main/windows/main.ts
  • apps/desktop/src/shared/ipc-channels/external.ts
  • apps/desktop/src/renderer/screens/main/components/WorkspaceView/ContentView/TabsContent/Terminal/index.ts
  • apps/desktop/src/main/lib/agent-setup.ts
  • apps/desktop/src/main/lib/terminal-history.test.ts
  • apps/desktop/src/main/lib/terminal-manager.ts
  • apps/desktop/src/renderer/screens/main/components/WorkspaceView/ContentView/TabsContent/Terminal/SetupTerminal.tsx
  • apps/desktop/src/renderer/screens/main/components/WorkspaceView/ContentView/TabsContent/Terminal/Terminal.tsx
  • apps/desktop/src/renderer/screens/main/components/WorkspaceView/ContentView/TabsContent/Terminal/types.ts
📚 Learning: 2025-11-24T21:33:13.244Z
Learnt from: CR
Repo: superset-sh/superset PR: 0
File: apps/desktop/AGENTS.md:0-0
Timestamp: 2025-11-24T21:33:13.244Z
Learning: Applies to apps/desktop/**/*.{ts,tsx} : Please use alias as defined in `tsconfig.json` when possible

Applied to files:

  • apps/desktop/src/renderer/screens/main/components/WorkspaceView/ContentView/TabsContent/Terminal/useTerminalSetup.ts
  • apps/desktop/src/shared/ipc-channels/external.ts
  • apps/desktop/src/renderer/screens/main/components/WorkspaceView/ContentView/TabsContent/Terminal/index.ts
  • apps/desktop/src/main/lib/agent-setup.ts
📚 Learning: 2025-11-24T21:32:46.559Z
Learnt from: CR
Repo: superset-sh/superset PR: 0
File: AGENTS.md:0-0
Timestamp: 2025-11-24T21:32:46.559Z
Learning: Applies to apps/desktop/src/shared/ipc-channels.ts : Define all Electron IPC channel types in apps/desktop/src/shared/ipc-channels.ts before implementing handlers

Applied to files:

  • apps/desktop/src/main/windows/main.ts
  • apps/desktop/src/shared/ipc-channels/external.ts
📚 Learning: 2025-11-24T21:32:46.559Z
Learnt from: CR
Repo: superset-sh/superset PR: 0
File: AGENTS.md:0-0
Timestamp: 2025-11-24T21:32:46.559Z
Learning: Applies to apps/desktop/src/main/lib/*-ipcs.ts : In Electron IPC handlers, accept object parameters instead of positional parameters to maintain type safety

Applied to files:

  • apps/desktop/src/shared/ipc-channels/external.ts
📚 Learning: 2025-11-24T21:33:13.244Z
Learnt from: CR
Repo: superset-sh/superset PR: 0
File: apps/desktop/AGENTS.md:0-0
Timestamp: 2025-11-24T21:33:13.244Z
Learning: Applies to apps/desktop/**/*.{ts,tsx,js,jsx} : For Electron interprocess communication, ALWAYS use tRPC as defined in `src/lib/trpc`

Applied to files:

  • apps/desktop/src/shared/ipc-channels/external.ts
📚 Learning: 2025-11-24T21:32:46.559Z
Learnt from: CR
Repo: superset-sh/superset PR: 0
File: AGENTS.md:0-0
Timestamp: 2025-11-24T21:32:46.559Z
Learning: Applies to @(apps/desktop/src/renderer|apps/desktop/src/shared)/**/*.{ts,tsx} : Never import Node.js modules in Electron renderer process or shared code; use IPC for communication between main and renderer processes

Applied to files:

  • apps/desktop/src/shared/ipc-channels/external.ts
  • apps/desktop/src/main/lib/agent-setup.ts
  • apps/desktop/src/main/lib/terminal-manager.ts
📚 Learning: 2025-11-24T21:32:46.559Z
Learnt from: CR
Repo: superset-sh/superset PR: 0
File: AGENTS.md:0-0
Timestamp: 2025-11-24T21:32:46.559Z
Learning: Applies to apps/desktop/src/main/index.ts : Load environment variables from monorepo root .env file in apps/desktop/src/main/index.ts before any imports with override: true

Applied to files:

  • apps/desktop/src/main/lib/agent-setup.ts
📚 Learning: 2025-11-24T21:32:46.559Z
Learnt from: CR
Repo: superset-sh/superset PR: 0
File: AGENTS.md:0-0
Timestamp: 2025-11-24T21:32:46.559Z
Learning: Applies to apps/**/*.test.{ts,tsx} : Co-locate tests with their corresponding components (e.g., Component.test.tsx next to Component.tsx)

Applied to files:

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

Applied to files:

  • apps/desktop/src/main/lib/terminal-history.test.ts
📚 Learning: 2025-11-24T21:32:46.559Z
Learnt from: CR
Repo: superset-sh/superset PR: 0
File: AGENTS.md:0-0
Timestamp: 2025-11-24T21:32:46.559Z
Learning: Applies to apps/**/*.{tsx,ts} : Co-locate component dependencies (hooks, utils, constants, tests, stories) next to the file using them

Applied to files:

  • apps/desktop/src/main/lib/terminal-history.test.ts
  • apps/website/src/app/components/Header/Header.tsx
📚 Learning: 2025-11-24T21:33:13.244Z
Learnt from: CR
Repo: superset-sh/superset PR: 0
File: apps/desktop/AGENTS.md:0-0
Timestamp: 2025-11-24T21:33:13.244Z
Learning: Applies to apps/desktop/**/*.test.{ts,tsx,js,jsx} : Tests should be repeatable

Applied to files:

  • apps/desktop/src/main/lib/terminal-history.test.ts
  • apps/desktop/test-setup.ts
📚 Learning: 2025-11-24T21:32:46.559Z
Learnt from: CR
Repo: superset-sh/superset PR: 0
File: AGENTS.md:0-0
Timestamp: 2025-11-24T21:32:46.559Z
Learning: Applies to packages/ui/**/*.{tsx,ts} : Use TailwindCSS v4 and shadcn/ui for UI component styling and design

Applied to files:

  • apps/desktop/src/renderer/screens/main/components/WorkspaceView/ContentView/TabsContent/GroupTabView/GroupTabPane.tsx
📚 Learning: 2025-11-24T21:33:13.244Z
Learnt from: CR
Repo: superset-sh/superset PR: 0
File: apps/desktop/AGENTS.md:0-0
Timestamp: 2025-11-24T21:33:13.244Z
Learning: Applies to apps/desktop/**/*.test.{ts,tsx,js,jsx} : Tests should be independent

Applied to files:

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

Applied to files:

  • apps/desktop/test-setup.ts
🧬 Code graph analysis (6)
apps/desktop/src/renderer/stores/tabs/helpers/tab-crud.ts (2)
apps/desktop/src/renderer/stores/tabs/types.ts (1)
  • TabsState (37-41)
apps/desktop/src/shared/types.ts (1)
  • TabType (23-30)
apps/desktop/src/renderer/screens/main/components/WorkspaceView/ContentView/TabsContent/Terminal/useTerminalSetup.ts (2)
apps/desktop/src/renderer/screens/main/components/WorkspaceView/ContentView/TabsContent/Terminal/types.ts (1)
  • TerminalSession (3-6)
apps/desktop/src/renderer/stores/tabs/store.ts (1)
  • useTabsStore (36-167)
apps/desktop/src/renderer/screens/main/components/WorkspaceView/ContentView/TabsContent/SetupTabView.tsx (4)
apps/desktop/src/renderer/stores/tabs/types.ts (1)
  • SetupTab (27-33)
apps/desktop/src/renderer/stores/tabs/hooks.ts (4)
  • useSplitTabHorizontal (21-22)
  • useSplitTabVertical (19-20)
  • useRemoveTab (8-8)
  • useSetActiveTab (10-11)
apps/desktop/src/renderer/screens/main/components/WorkspaceView/ContentView/TabsContent/TabContentContextMenu.tsx (1)
  • TabContentContextMenu (17-40)
apps/desktop/src/renderer/screens/main/components/WorkspaceView/ContentView/TabsContent/Terminal/SetupTerminal.tsx (1)
  • SetupTerminal (15-44)
apps/desktop/src/renderer/stores/tabs/types.ts (1)
apps/desktop/src/shared/types.ts (1)
  • TabType (23-30)
apps/desktop/src/renderer/screens/main/components/WorkspaceView/ContentView/TabsContent/index.tsx (3)
apps/desktop/src/shared/types.ts (1)
  • TabType (23-30)
apps/desktop/src/renderer/screens/main/components/WorkspaceView/ContentView/TabsContent/SetupTabView.tsx (1)
  • SetupTabView (16-49)
apps/desktop/src/renderer/screens/main/components/WorkspaceView/ContentView/TabsContent/DropOverlay.tsx (1)
  • DropOverlay (5-13)
apps/desktop/src/renderer/screens/main/components/WorkspaceView/ContentView/TabsContent/Terminal/Terminal.tsx (3)
apps/desktop/src/renderer/screens/main/components/WorkspaceView/ContentView/TabsContent/Terminal/index.ts (1)
  • Terminal (2-2)
apps/desktop/src/renderer/screens/main/components/WorkspaceView/ContentView/TabsContent/Terminal/types.ts (2)
  • TerminalProps (8-13)
  • TerminalStreamEvent (15-17)
apps/desktop/src/renderer/stores/tabs/hooks.ts (1)
  • useSetActiveTab (10-11)
⏰ 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 (20)
apps/desktop/src/main/lib/terminal-manager.ts (1)

5-5: Import reordering is safe and consistent

Reordering getSupersetPath after NOTIFICATIONS_PORT does not affect runtime behavior and keeps imports organized; no further changes needed here.

apps/desktop/src/renderer/globals.css (2)

26-26: CSS variable normalization; no functional impact.

The change from oklch(0.20 ...) to oklch(0.2 ...) is a numeric normalization—both render identically. This is fine.


64-64: Verify: CSS change appears tangential to PR objectives.

The AI summary states the dark theme value "remains unchanged," but line 64 is marked as modified. Additionally, this CSS color token adjustment appears unrelated to the PR's workspace setup flow (setup config loading, file copying, terminal integration). Please clarify whether this change is intentional and its connection to the PR objectives.

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

2-5: LGTM!

This is a trivial import reordering change, likely from Biome's import organization. The file correctly uses tRPC for Electron IPC as per the coding guidelines, and the subscription pattern with proper cleanup is well-implemented.

apps/website/src/app/components/Header/Header.tsx (1)

7-9: LGTM! Import reordering aligns with PR-wide adjustments.

The import reorganization is consistent with the broader changes in this PR where certain components are no longer exported from index barrels. The direct imports are appropriate, and all imported components are correctly used in the JSX.

apps/desktop/src/renderer/screens/main/components/WorkspaceView/ContentView/TabsContent/GroupTabView/GroupTabPane.tsx (2)

1-2: LGTM!

The imports are correct and properly used in the component. Button from the UI library and the close icon are appropriate for the close button functionality.


46-49: LGTM!

The close handler correctly prevents event propagation and invokes the removal callback. The implementation is clean and type-safe.

apps/desktop/test-setup.ts (1)

51-57: LGTM! Consistent mock pattern.

The BrowserWindow mock now uses the same mock(() => ({ ... })) pattern as other mocks in this file (e.g., getPath, getName, showOpenDialog), which improves consistency and correctly represents BrowserWindow as a callable constructor that returns a mock window object.

apps/desktop/src/main/lib/agent-setup.ts (1)

1-1: LGTM! Import consolidation improves code organization.

Moving execSync to the top-level imports and removing the duplicate is a good refactoring that follows best practices.

apps/desktop/src/main/windows/main.ts (1)

8-13: Import reordering is safe and keeps types/runtime values clearly separated

The reordered imports (placing type AgentCompleteEvent and NOTIFICATIONS_PORT together) are behaviorally neutral and improve readability without affecting runtime behavior. Keeping AgentCompleteEvent as a type‑only import is also in line with TypeScript best practices.

apps/desktop/src/shared/ipc-channels/external.ts (1)

7-7: Type alias change is safe; no augmentation of ExternalChannels detected

The change from interface ExternalChannels {} to type ExternalChannels = {} is non-breaking. Verification confirms ExternalChannels is only referenced in apps/desktop/src/shared/ipc-channels/index.ts where it is extended by the IpcChannels interface. Type aliases can be used with extends, so the interface composition continues to work. No declaration merging or augmentation patterns exist in the codebase.

The empty type aligns with the file's purpose: backwards compatibility for the IPC channels type system while external operations now use tRPC (as documented in the file header).

apps/desktop/src/main/lib/terminal-history.test.ts (2)

4-11: LGTM! Import reordering aligns with formatting standards.

The reordering of HistoryReader and HistoryWriter imports is a formatting improvement that aligns with Biome's import organization rules specified in the coding guidelines.


382-383: LGTM! Improved type error handling.

The change from @ts-ignore to @ts-expect-error is a best practice improvement. @ts-expect-error is superior because it expects a type error to exist and will warn if the suppression becomes unnecessary, making the code more maintainable.

apps/desktop/src/renderer/screens/main/components/WorkspaceView/ContentView/TabsContent/index.tsx (1)

7-55: Setup tab branch integrates cleanly into existing tab rendering.

The new TabType.Setup branch reuses the single‑tab split behavior and overlay semantics without affecting group handling; the control flow and JSX structure look consistent with the prior logic.

apps/desktop/src/renderer/screens/main/components/WorkspaceView/ContentView/TabsContent/Terminal/index.ts (1)

1-2: Barrel export for SetupTerminal is appropriate.

Re‑exporting SetupTerminal next to Terminal makes the terminal module’s public API clearer and simplifies imports for callers.

apps/desktop/src/renderer/stores/tabs/types.ts (1)

3-50: Setup tab typing fits cleanly into the existing tabs model.

Extending TabType with Setup, adding SetupTab, and updating Tab/TabsStore preserves the discriminated union pattern and keeps store APIs explicit for setup‑specific tabs.

apps/desktop/src/renderer/screens/main/components/WorkspaceView/ContentView/TabsContent/Terminal/types.ts (1)

1-13: Terminal session typing aligns with component usage.

TerminalSession and the extended TerminalProps cleanly describe what Terminal exposes via onSessionReady, and match the object structure built in Terminal.tsx.

apps/desktop/src/renderer/stores/tabs/helpers/tab-crud.ts (1)

98-136: handleAddSetupTab mirrors existing tab‑creation semantics correctly.

The helper constructs a Setup tab with the expected fields, updates the active tab for the workspace, and maintains the history stack in line with handleAddTab, so it slots neatly into the existing tabs store behavior.

apps/desktop/src/renderer/screens/main/components/WorkspaceView/ContentView/TabsContent/Terminal/useTerminalSetup.ts (2)

1-3: LGTM!

The imports follow the project's alias patterns and properly reference the local types file.


21-70: Well-designed hook structure.

The hook correctly uses useRef to track execution state without triggering re-renders, avoids unnecessary useEffect calls, and provides a clean API. The guard conditions properly prevent duplicate execution via both the local ref and the store's setupPending flag.

Comment on lines +5 to +8
interface SetupCopyResults {
copied: string[];
errors: string[];
}
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.

🛠️ Refactor suggestion | 🟠 Major

Move SetupCopyResults to the shared types file.

According to the AI summary, SetupCopyResults is produced by setup utilities and consumed by multiple components. This type should be defined in types.ts (in the same directory) alongside TerminalSession for better organization and to avoid duplication.

Move the type definition to types.ts:

export interface SetupCopyResults {
	copied: string[];
	errors: string[];
}

Then update the import in this file:

 import { useRef } from "react";
 import { useTabsStore } from "renderer/stores";
-import type { TerminalSession } from "./types";
+import type { SetupCopyResults, TerminalSession } from "./types";
🤖 Prompt for AI Agents
In
apps/desktop/src/renderer/screens/main/components/WorkspaceView/ContentView/TabsContent/Terminal/useTerminalSetup.ts
around lines 5-8, the local SetupCopyResults interface should be moved to the
shared types file (types.ts) next to TerminalSession; create/export
SetupCopyResults there with the shape { copied: string[]; errors: string[] },
remove the local definition from this file, and add an import for
SetupCopyResults from the types.ts file.

Comment on lines +29 to +67
const executeSetup = (session: TerminalSession) => {
// Only execute setup once and only if setup is pending
if (!setupPending || !setupCommands || setupExecutedRef.current) {
return;
}

setupExecutedRef.current = true;

// Print copy results if available
if (setupCopyResults) {
const { copied, errors } = setupCopyResults;
if (copied.length > 0) {
session.xterm.writeln(
`\r\n\x1b[32m✓ Copied ${copied.length} file(s):\x1b[0m`,
);
for (const file of copied) {
session.xterm.writeln(` - ${file}`);
}
}
if (errors.length > 0) {
session.xterm.writeln(`\r\n\x1b[33m⚠ Copy warnings:\x1b[0m`);
for (const error of errors) {
session.xterm.writeln(` ${error}`);
}
}
session.xterm.writeln("\r\n");
}

// Send all commands sequentially
const commands = `${setupCommands.join("\n")}\n`;
session.write(commands);

// Mark setup as no longer pending
useTabsStore.setState((state) => ({
tabs: state.tabs.map((t) =>
t.id === tabId ? { ...t, setupPending: false } : t,
),
}));
};
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 around session operations.

The executeSetup function writes to the terminal session without error handling. If session.write() or session.xterm.writeln() throw an exception:

  1. setupExecutedRef.current will be set to true (line 35 executes before the error)
  2. The store update at lines 62-66 won't execute
  3. The tab's setupPending remains true, but setupExecutedRef prevents retry
  4. Setup commands never execute, leaving the terminal in an inconsistent state

Wrap session operations in try-catch:

 const executeSetup = (session: TerminalSession) => {
 	// Only execute setup once and only if setup is pending
 	if (!setupPending || !setupCommands || setupExecutedRef.current) {
 		return;
 	}

-	setupExecutedRef.current = true;
-
-	// Print copy results if available
-	if (setupCopyResults) {
-		const { copied, errors } = setupCopyResults;
-		if (copied.length > 0) {
-			session.xterm.writeln(
-				`\r\n\x1b[32m✓ Copied ${copied.length} file(s):\x1b[0m`,
-			);
-			for (const file of copied) {
-				session.xterm.writeln(`  - ${file}`);
-			}
-		}
-		if (errors.length > 0) {
-			session.xterm.writeln(`\r\n\x1b[33m⚠ Copy warnings:\x1b[0m`);
-			for (const error of errors) {
-				session.xterm.writeln(`  ${error}`);
-			}
-		}
-		session.xterm.writeln("\r\n");
-	}
-
-	// Send all commands sequentially
-	const commands = `${setupCommands.join("\n")}\n`;
-	session.write(commands);
-
-	// Mark setup as no longer pending
-	useTabsStore.setState((state) => ({
-		tabs: state.tabs.map((t) =>
-			t.id === tabId ? { ...t, setupPending: false } : t,
-		),
-	}));
+	try {
+		setupExecutedRef.current = true;
+
+		// Print copy results if available
+		if (setupCopyResults) {
+			const { copied, errors } = setupCopyResults;
+			if (copied.length > 0) {
+				session.xterm.writeln(
+					`\r\n\x1b[32m✓ Copied ${copied.length} file(s):\x1b[0m`,
+				);
+				for (const file of copied) {
+					session.xterm.writeln(`  - ${file}`);
+				}
+			}
+			if (errors.length > 0) {
+				session.xterm.writeln(`\r\n\x1b[33m⚠ Copy warnings:\x1b[0m`);
+				for (const error of errors) {
+					session.xterm.writeln(`  ${error}`);
+				}
+			}
+			session.xterm.writeln("\r\n");
+		}
+
+		// Send all commands sequentially
+		const commands = `${setupCommands.join("\n")}\n`;
+		session.write(commands);
+
+		// Mark setup as no longer pending
+		useTabsStore.setState((state) => ({
+			tabs: state.tabs.map((t) =>
+				t.id === tabId ? { ...t, setupPending: false } : t,
+			),
+		}));
+	} catch (error) {
+		console.error("Failed to execute terminal setup:", error);
+		setupExecutedRef.current = false; // Allow retry
+		// Optionally: display error to user via terminal or notification
+	}
 };
📝 Committable suggestion

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

Suggested change
const executeSetup = (session: TerminalSession) => {
// Only execute setup once and only if setup is pending
if (!setupPending || !setupCommands || setupExecutedRef.current) {
return;
}
setupExecutedRef.current = true;
// Print copy results if available
if (setupCopyResults) {
const { copied, errors } = setupCopyResults;
if (copied.length > 0) {
session.xterm.writeln(
`\r\n\x1b[32m✓ Copied ${copied.length} file(s):\x1b[0m`,
);
for (const file of copied) {
session.xterm.writeln(` - ${file}`);
}
}
if (errors.length > 0) {
session.xterm.writeln(`\r\n\x1b[33m⚠ Copy warnings:\x1b[0m`);
for (const error of errors) {
session.xterm.writeln(` ${error}`);
}
}
session.xterm.writeln("\r\n");
}
// Send all commands sequentially
const commands = `${setupCommands.join("\n")}\n`;
session.write(commands);
// Mark setup as no longer pending
useTabsStore.setState((state) => ({
tabs: state.tabs.map((t) =>
t.id === tabId ? { ...t, setupPending: false } : t,
),
}));
};
const executeSetup = (session: TerminalSession) => {
// Only execute setup once and only if setup is pending
if (!setupPending || !setupCommands || setupExecutedRef.current) {
return;
}
try {
setupExecutedRef.current = true;
// Print copy results if available
if (setupCopyResults) {
const { copied, errors } = setupCopyResults;
if (copied.length > 0) {
session.xterm.writeln(
`\r\n\x1b[32m✓ Copied ${copied.length} file(s):\x1b[0m`,
);
for (const file of copied) {
session.xterm.writeln(` - ${file}`);
}
}
if (errors.length > 0) {
session.xterm.writeln(`\r\n\x1b[33m⚠ Copy warnings:\x1b[0m`);
for (const error of errors) {
session.xterm.writeln(` ${error}`);
}
}
session.xterm.writeln("\r\n");
}
// Send all commands sequentially
const commands = `${setupCommands.join("\n")}\n`;
session.write(commands);
// Mark setup as no longer pending
useTabsStore.setState((state) => ({
tabs: state.tabs.map((t) =>
t.id === tabId ? { ...t, setupPending: false } : t,
),
}));
} catch (error) {
console.error("Failed to execute terminal setup:", error);
setupExecutedRef.current = false; // Allow retry
// Optionally: display error to user via terminal or notification
}
};
🤖 Prompt for AI Agents
In
apps/desktop/src/renderer/screens/main/components/WorkspaceView/ContentView/TabsContent/Terminal/useTerminalSetup.ts
around lines 29-67, wrap all interactions with session.xterm.writeln and
session.write in a try-catch so exceptions from terminal ops don't leave state
inconsistent; move setting setupExecutedRef.current = true until after the
terminal writes succeed, in the catch reset/setupExecutedRef.current = false and
log or surface the error, and ensure the useTabsStore update that clears
setupPending only runs after successful execution (i.e., inside the try after
writes) so failed writes allow retry.

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: 2

🧹 Nitpick comments (4)
apps/desktop/src/main/lib/terminal-manager.test.ts (1)

79-87: New tab/workspace metadata arguments are wired correctly into tests

Passing tabTitle and workspaceName through these createOrAttach call sites keeps the tests aligned with the updated TerminalManager API without changing existing behavior they assert on (spawn options, reuse semantics, resize, write). This looks correct and keeps the fixtures straightforward with stable literal values.

If TerminalManager is now expected to persist or expose these labels (e.g., via getSession metadata or events), consider adding one focused test that asserts on that new behavior so the contract around these fields is locked in; otherwise, this change is sufficient for the current test intentions.

Also applies to: 104-110, 115-120, 130-137, 139-146, 154-159, 181-186

apps/desktop/src/renderer/screens/main/components/WorkspaceView/ContentView/TabsContent/SetupTabView/SetupTabView.tsx (1)

10-15: Unused isDropZone prop.

The isDropZone prop is declared in the interface but never destructured or used in the component. Either remove it from the interface or implement the intended drop zone behavior.

 interface SetupTabViewProps {
 	tab: SetupTab;
-	isDropZone: boolean;
 }

-export function SetupTabView({ tab }: SetupTabViewProps) {
+export function SetupTabView({ tab }: SetupTabViewProps) {
apps/desktop/src/renderer/screens/main/components/WorkspaceView/ContentView/TabsContent/SetupTabView/SetupTerminal.tsx (2)

10-13: Consider reusing the existing type from SetupTab.

This interface duplicates setupCopyResults type already defined in SetupTab (see apps/desktop/src/renderer/stores/tabs/types.ts). Consider importing or deriving from that type to maintain a single source of truth.

+import type { SetupTab } from "renderer/stores";
+
-interface SetupCopyResults {
-	copied: string[];
-	errors: string[];
-}
+type SetupCopyResults = NonNullable<SetupTab["setupCopyResults"]>;

143-153: Remove mutation objects from the dependency array.

Including createMutation, writeMutation, resizeMutation, and detachMutation in the dependency array is non-standard. While tRPC mutation objects are referentially stable, the ESLint exhaustive-deps rule may have flagged them. The setupExecutedRef guard prevents re-execution anyway, so consider moving mutation calls outside the effect or using refs to avoid linter warnings while keeping intent clear.

📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between e2a02fd and 06a481d.

📒 Files selected for processing (8)
  • .superset/setup.json (1 hunks)
  • apps/desktop/src/lib/trpc/routers/workspaces/utils/setup.ts (1 hunks)
  • apps/desktop/src/main/lib/terminal-manager.test.ts (6 hunks)
  • apps/desktop/src/main/windows/main.ts (1 hunks)
  • apps/desktop/src/renderer/react-query/workspaces/useCreateWorkspace.ts (1 hunks)
  • apps/desktop/src/renderer/screens/main/components/WorkspaceView/ContentView/TabsContent/SetupTabView/SetupTabView.tsx (1 hunks)
  • apps/desktop/src/renderer/screens/main/components/WorkspaceView/ContentView/TabsContent/SetupTabView/SetupTerminal.tsx (1 hunks)
  • apps/desktop/src/renderer/screens/main/components/WorkspaceView/ContentView/TabsContent/SetupTabView/index.ts (1 hunks)
✅ Files skipped from review due to trivial changes (1)
  • apps/desktop/src/renderer/screens/main/components/WorkspaceView/ContentView/TabsContent/SetupTabView/index.ts
🚧 Files skipped from review as they are similar to previous changes (3)
  • apps/desktop/src/main/windows/main.ts
  • apps/desktop/src/renderer/react-query/workspaces/useCreateWorkspace.ts
  • apps/desktop/src/lib/trpc/routers/workspaces/utils/setup.ts
🧰 Additional context used
📓 Path-based instructions (9)
**/*.{ts,tsx,js,jsx,json}

📄 CodeRabbit inference engine (AGENTS.md)

Apply Biome formatting, linting, and import organization at the root level for all code files

Files:

  • apps/desktop/src/renderer/screens/main/components/WorkspaceView/ContentView/TabsContent/SetupTabView/SetupTabView.tsx
  • apps/desktop/src/renderer/screens/main/components/WorkspaceView/ContentView/TabsContent/SetupTabView/SetupTerminal.tsx
  • apps/desktop/src/main/lib/terminal-manager.test.ts
**/*.{ts,tsx}

📄 CodeRabbit inference engine (AGENTS.md)

**/*.{ts,tsx}: Avoid using any type; use type-safe approaches instead, unless necessary
Ensure TypeScript type checking passes across all packages using bun run typecheck

Files:

  • apps/desktop/src/renderer/screens/main/components/WorkspaceView/ContentView/TabsContent/SetupTabView/SetupTabView.tsx
  • apps/desktop/src/renderer/screens/main/components/WorkspaceView/ContentView/TabsContent/SetupTabView/SetupTerminal.tsx
  • apps/desktop/src/main/lib/terminal-manager.test.ts
apps/**/*.{tsx,ts}

📄 CodeRabbit inference engine (AGENTS.md)

apps/**/*.{tsx,ts}: Structure React applications with one folder per component following the pattern: ComponentName/ComponentName.tsx with index.ts barrel export
Co-locate component dependencies (hooks, utils, constants, tests, stories) next to the file using them

Files:

  • apps/desktop/src/renderer/screens/main/components/WorkspaceView/ContentView/TabsContent/SetupTabView/SetupTabView.tsx
  • apps/desktop/src/renderer/screens/main/components/WorkspaceView/ContentView/TabsContent/SetupTabView/SetupTerminal.tsx
  • apps/desktop/src/main/lib/terminal-manager.test.ts
apps/**/*.tsx

📄 CodeRabbit inference engine (AGENTS.md)

Use one component per file; do not create multi-component files

Files:

  • apps/desktop/src/renderer/screens/main/components/WorkspaceView/ContentView/TabsContent/SetupTabView/SetupTabView.tsx
  • apps/desktop/src/renderer/screens/main/components/WorkspaceView/ContentView/TabsContent/SetupTabView/SetupTerminal.tsx
apps/desktop/src/renderer/**/*.tsx

📄 CodeRabbit inference engine (AGENTS.md)

Define keyboard shortcuts using the centralized system in apps/desktop/src/renderer/lib/shortcuts.ts with Arc Browser-inspired shortcut definitions

Files:

  • apps/desktop/src/renderer/screens/main/components/WorkspaceView/ContentView/TabsContent/SetupTabView/SetupTabView.tsx
  • apps/desktop/src/renderer/screens/main/components/WorkspaceView/ContentView/TabsContent/SetupTabView/SetupTerminal.tsx
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/WorkspaceView/ContentView/TabsContent/SetupTabView/SetupTabView.tsx
  • apps/desktop/src/renderer/screens/main/components/WorkspaceView/ContentView/TabsContent/SetupTabView/SetupTerminal.tsx
  • apps/desktop/src/main/lib/terminal-manager.test.ts
apps/desktop/**/*.{ts,tsx}

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

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

Files:

  • apps/desktop/src/renderer/screens/main/components/WorkspaceView/ContentView/TabsContent/SetupTabView/SetupTabView.tsx
  • apps/desktop/src/renderer/screens/main/components/WorkspaceView/ContentView/TabsContent/SetupTabView/SetupTerminal.tsx
  • apps/desktop/src/main/lib/terminal-manager.test.ts
apps/**/*.test.{ts,tsx}

📄 CodeRabbit inference engine (AGENTS.md)

Co-locate tests with their corresponding components (e.g., Component.test.tsx next to Component.tsx)

Files:

  • apps/desktop/src/main/lib/terminal-manager.test.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/main/lib/terminal-manager.test.ts
🧠 Learnings (2)
📚 Learning: 2025-11-24T21:32:46.559Z
Learnt from: CR
Repo: superset-sh/superset PR: 0
File: AGENTS.md:0-0
Timestamp: 2025-11-24T21:32:46.559Z
Learning: Applies to apps/desktop/src/main/lib/*-ipcs.ts : Implement Electron IPC handlers in dedicated files under apps/desktop/src/main/lib/ (e.g., workspace-ipcs.ts, terminal-ipcs.ts)

Applied to files:

  • apps/desktop/src/renderer/screens/main/components/WorkspaceView/ContentView/TabsContent/SetupTabView/SetupTabView.tsx
  • apps/desktop/src/renderer/screens/main/components/WorkspaceView/ContentView/TabsContent/SetupTabView/SetupTerminal.tsx
  • apps/desktop/src/main/lib/terminal-manager.test.ts
📚 Learning: 2025-11-24T21:32:46.559Z
Learnt from: CR
Repo: superset-sh/superset PR: 0
File: AGENTS.md:0-0
Timestamp: 2025-11-24T21:32:46.559Z
Learning: Applies to apps/**/*.{tsx,ts} : Structure React applications with one folder per component following the pattern: ComponentName/ComponentName.tsx with index.ts barrel export

Applied to files:

  • apps/desktop/src/renderer/screens/main/components/WorkspaceView/ContentView/TabsContent/SetupTabView/SetupTabView.tsx
🧬 Code graph analysis (2)
apps/desktop/src/renderer/screens/main/components/WorkspaceView/ContentView/TabsContent/SetupTabView/SetupTabView.tsx (4)
apps/desktop/src/renderer/stores/tabs/types.ts (1)
  • SetupTab (27-33)
apps/desktop/src/renderer/stores/tabs/hooks.ts (3)
  • useSplitTabHorizontal (21-22)
  • useSplitTabVertical (19-20)
  • useRemoveTab (8-8)
apps/desktop/src/renderer/screens/main/components/WorkspaceView/ContentView/TabsContent/TabContentContextMenu.tsx (1)
  • TabContentContextMenu (17-40)
apps/desktop/src/renderer/screens/main/components/WorkspaceView/ContentView/TabsContent/SetupTabView/SetupTerminal.tsx (1)
  • SetupTerminal (26-160)
apps/desktop/src/renderer/screens/main/components/WorkspaceView/ContentView/TabsContent/SetupTabView/SetupTerminal.tsx (2)
apps/desktop/src/renderer/screens/main/components/WorkspaceView/ContentView/TabsContent/Terminal/helpers.ts (2)
  • createTerminalInstance (11-70)
  • setupResizeHandlers (92-116)
apps/desktop/src/renderer/screens/main/components/WorkspaceView/ContentView/TabsContent/Terminal/types.ts (1)
  • TerminalStreamEvent (15-17)
🔇 Additional comments (3)
apps/desktop/src/renderer/screens/main/components/WorkspaceView/ContentView/TabsContent/SetupTabView/SetupTabView.tsx (1)

16-48: LGTM!

The hooks usage, event handlers, and JSX structure are clean. The component correctly wires up split/close actions and passes the required props to SetupTerminal.

apps/desktop/src/renderer/screens/main/components/WorkspaceView/ContentView/TabsContent/SetupTabView/SetupTerminal.tsx (2)

136-142: Cleanup mutation may fire after unmount.

Calling detachMutation.mutate() in the cleanup function works but the mutation callback closures may reference stale state. This is generally fine for fire-and-forget detach operations, but be aware that any onSuccess/onError handlers would run after the component unmounts.


26-57: LGTM!

The terminal initialization, stream handling, status message rendering, and JSX structure are well-implemented. The component correctly manages the xterm lifecycle and integrates cleanly with tRPC subscriptions.

Also applies to: 155-159

Comment thread .superset/setup.json
Comment on lines 5 to 7
"commands": [
"bun i"
"echo 'Hello world'"
]
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 | 🔴 Critical

Revert placeholder command — dependency installation is missing.

Line 6 replaces the meaningful "bun i" (dependency installation) command with "echo 'Hello world'" (a trivial placeholder). This breaks the workspace setup flow and prevents dependencies from being installed in new workspaces.

Revert to the original install command:

 	"commands": [
-		"echo 'Hello world'"
+		"bun i"
 	]

If this change was intentional and the setup flow no longer requires dependency installation, please clarify the updated setup strategy and ensure all downstream setup utilities (file copying, terminal execution) account for this change.

📝 Committable suggestion

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

Suggested change
"commands": [
"bun i"
"echo 'Hello world'"
]
"commands": [
"bun i"
]
🤖 Prompt for AI Agents
In .superset/setup.json around lines 5 to 7, the commands array was changed to a
placeholder ("echo 'Hello world'") which removes the dependency installation
step; restore the original dependency install command (e.g., "bun i") in place
of the echo so the workspace setup installs required packages, or if the change
was intentional, update the setup.json to document the new flow and adjust any
downstream setup utilities to handle the absence of an install step.

Comment on lines +99 to +124
if (setupCommands && setupCommands.length > 0) {
xterm.writeln("\x1b[36mRunning setup commands...\x1b[0m\r\n");
}

// Create terminal session and run commands
createMutation.mutate(
{
tabId,
workspaceId,
tabTitle: "Setup",
cols: xterm.cols,
rows: xterm.rows,
cwd: setupCwd,
},
{
onSuccess: () => {
setSubscriptionEnabled(true);

// Send commands once
if (setupCommands && setupCommands.length > 0) {
const combinedCommands = `${setupCommands.join(" && ")} && exit\n`;
writeMutation.mutate({ tabId, data: combinedCommands });
}
},
},
);
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

Handle the case when setupCommands is empty or undefined.

When setupCommands is empty/undefined, a terminal session is created but no commands are sent and no exit is issued. The user sees "Setting up worktree..." but the terminal just hangs without completing. Consider either auto-exiting when there are no commands, or showing a completion message directly.

 				onSuccess: () => {
 					setSubscriptionEnabled(true);

 					// Send commands once
 					if (setupCommands && setupCommands.length > 0) {
 						const combinedCommands = `${setupCommands.join(" && ")} && exit\n`;
 						writeMutation.mutate({ tabId, data: combinedCommands });
+					} else {
+						// No commands to run, exit immediately
+						writeMutation.mutate({ tabId, data: "exit\n" });
 					}
 				},
🤖 Prompt for AI Agents
In
apps/desktop/src/renderer/screens/main/components/WorkspaceView/ContentView/TabsContent/SetupTabView/SetupTerminal.tsx
around lines 99–124, handle the case where setupCommands is empty/undefined by
sending an explicit completion or exit to the terminal after the session is
created: inside the createMutation.onSuccess block, if setupCommands is falsy or
has length 0, call the writeMutation to send either a completion message (e.g.
"Setup complete\n") followed by an exit ("\nexit\n" or "exit\n") or just send
"exit\n" so the terminal session closes; keep the existing behavior for when
setupCommands exist (combine commands + " && exit\n") and ensure
setSubscriptionEnabled(true) is still called before writing.

@Kitenite Kitenite closed this Nov 26, 2025
@Kitenite Kitenite deleted the worktree branch November 29, 2025 06:29
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