feat(desktop): add teardown script support for workspace deletion#178
feat(desktop): add teardown script support for workspace deletion#178saddlepaddle merged 3 commits intomainfrom
Conversation
|
The latest updates on your projects. Learn more about Vercel for GitHub.
|
|
Warning Rate limit exceeded@saddlepaddle has exceeded the limit for the number of commits or files that can be reviewed per hour. Please wait 8 minutes and 46 seconds before requesting another review. ⌛ How to resolve this issue?After the wait time has elapsed, a review can be triggered using the We recommend that you space out your commits to avoid hitting the rate limit. 🚦 How do rate limits work?CodeRabbit enforces hourly rate limits for each developer per organization. Our paid plans have higher rate limits than the trial, open-source and free plans. In all cases, we re-allow further reviews after a brief timeout. Please see our FAQ for further information. 📒 Files selected for processing (9)
WalkthroughThis PR introduces workspace teardown functionality, enabling automatic cleanup when a workspace is deleted. It adds a new teardown configuration to setup.json, creates a teardown utility that executes shell commands from the setup configuration, integrates teardown into the workspace deletion flow, updates the type system to include teardown commands, and provides a bash script to delete Neon branches. Changes
Sequence Diagram(s)sequenceDiagram
actor User
participant UI as DeleteWorkspaceDialog
participant Router as Workspaces Router
participant Utils as Teardown Utility
participant Shell as Shell / neonctl
User->>UI: Click delete workspace
UI->>Router: call delete(workspaceName)
Router->>Utils: runTeardown(mainRepoPath, worktreePath, workspaceName)
Utils->>Utils: loadSetupConfig(.superset/setup.json)
alt Teardown commands defined
Utils->>Shell: execSync(teardown commands, env vars)
alt Success
Shell-->>Utils: exit 0
Utils-->>Router: {success: true}
else Error
Shell-->>Utils: error
Utils-->>Router: {success: false, error: msg}
end
else No teardown commands
Utils-->>Router: {success: true}
end
Router->>Router: Remove worktree
alt Teardown had error
Router-->>UI: {success: true, teardownError: msg}
UI->>UI: Display warning toast
else Teardown succeeded
Router-->>UI: {success: true}
end
UI->>User: Workspace deleted (with optional teardown warning)
Estimated code review effort🎯 3 (Moderate) | ⏱️ ~20 minutes Areas requiring extra attention:
Possibly related PRs
Poem
Pre-merge checks and finishing touches❌ Failed checks (1 warning)
✅ Passed checks (2 passed)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
There was a problem hiding this comment.
Actionable comments posted: 0
🧹 Nitpick comments (4)
apps/desktop/src/renderer/screens/main/components/TopBar/WorkspaceTabs/DeleteWorkspaceDialog.tsx (1)
11-11: Teardown warning toast wiring looks correct; consider also checkingsuccessUsing the TRPC result’s
teardownErrorto trigger atoast.warningis a good way to surface non-fatal teardown failures to the user. Import and usage oftoastare consistent with the rest of the file.One thing to consider (can be a follow-up): the delete mutation can return
{ success: false, error }without throwing; in that case this handler will still close the dialog as if deletion succeeded. You might want to gateonOpenChange(false)and the teardown warning behindresult.successand optionally surface an error toast if it’sfalse.Also applies to: 41-46
apps/desktop/src/lib/trpc/routers/workspaces/workspaces.ts (1)
15-15: Delete mutation teardown integration is correct; consider slightly richer error handlingThe wiring here looks solid:
- You guard teardown behind
worktree && projectand a positiveworktreeExistscheck, so you avoid chdir failures for missing worktrees.runTeardownerrors are captured intoteardownErrorand do not block removal or DB cleanup, which matches the requirement “warn but still delete”.- You still short‑circuit on
removeWorktreefailures and avoid DB inconsistency.A couple of optional improvements:
- If
worktreeExiststhrows (e.g., git misconfigured), the whole mutation will reject. If you want failure behavior to mirrorcanDelete, you could wrapworktreeExistsin a try/catch here and return a structured{ success: false, error }instead of throwing.- Depending on how you conceptualize teardown, you might want teardown to run even when the git worktree is gone (e.g., to clean remote resources keyed only by workspace name). Right now, missing git worktree skips teardown entirely.
These are non-blocking and can be addressed later if they become an issue.
Also applies to: 299-336, 368-369
superset-teardown.sh (1)
1-26: Teardown failure signaling vs. UI behavior may not match expectationsThe script is generally robust (dependency check, safe quoting, non-fatal branch‑missing case), but there’s a subtle interaction with how
runTeardowninterprets success:
- Because the
neonctl branches deletecall is insideif ...; then ... else ... fiwithset -e, most failures (branch missing, auth error, etc.) will just take theelsebranch and still exit with status 0.runTeardownonly treats non‑zero exit codes as failures, so these conditions won’t populateteardownErrorand no warning toast will be shown, even though you print a warning line in the script.- Since
execSyncis invoked withstdio: "pipe", that warning line also isn’t visible to the user by default.If you want conditions like “branch not found” or other Neon errors to trigger the teardown‑warning toast, you could either:
- Make those cases exit non‑zero (e.g.,
echo "..."; exit 1), or- Keep exit 0 but have
runTeardowncapture and plumb the script’s stdout/stderr up intoteardownError.Otherwise, this behavior is fine as long as “already deleted / not found” is considered a clean teardown.
apps/desktop/src/lib/trpc/routers/workspaces/utils/teardown.ts (1)
1-74: Teardown runner is solid and defensive; consider reuse and async executionThis implementation looks correct and reasonably hardened:
loadSetupConfiggracefully handles missing/invalid JSON and enforces thatteardownis an array before use.runTeardownno‑ops when no teardown is configured, injects useful env vars, and returns a clear{ success, error? }result.- Errors from the child process are logged and mapped into a string, which is appropriate for surfacing via the UI.
A few non‑blocking refinements you might consider:
- There’s now a second
loadSetupConfigalongside./utils/setup. If that other helper also reads.superset/setup.json, it may be worth consolidating to a single shared loader (with teardown validation moved there) to avoid drift.execSyncwith a 60s timeout will block the Electron main process while teardown runs. If teardown scripts might be slow, wrappingexec/spawnin a Promise and awaiting it would keep the event loop responsive while still enforcing the timeout.- If you care about stricter validation, you could assert that every
teardownentry is a string (not just that it’s an array) beforejoin(" && ").Overall, the current design is acceptable; these are incremental improvements.
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (6)
.superset/setup.json(1 hunks)apps/desktop/src/lib/trpc/routers/workspaces/utils/teardown.ts(1 hunks)apps/desktop/src/lib/trpc/routers/workspaces/workspaces.ts(3 hunks)apps/desktop/src/renderer/screens/main/components/TopBar/WorkspaceTabs/DeleteWorkspaceDialog.tsx(2 hunks)apps/desktop/src/shared/types.ts(1 hunks)superset-teardown.sh(1 hunks)
🧰 Additional context used
📓 Path-based instructions (7)
apps/desktop/**/*.{ts,tsx,js,jsx}
📄 CodeRabbit inference engine (apps/desktop/AGENTS.md)
For Electron interprocess communication, ALWAYS use tRPC as defined in
src/lib/trpc
Files:
apps/desktop/src/shared/types.tsapps/desktop/src/lib/trpc/routers/workspaces/workspaces.tsapps/desktop/src/lib/trpc/routers/workspaces/utils/teardown.tsapps/desktop/src/renderer/screens/main/components/TopBar/WorkspaceTabs/DeleteWorkspaceDialog.tsx
apps/desktop/**/*.{ts,tsx}
📄 CodeRabbit inference engine (apps/desktop/AGENTS.md)
apps/desktop/**/*.{ts,tsx}: Please use alias as defined intsconfig.jsonwhen possible
Prefer zustand for state management if it makes sense. Do not use effect unless absolutely necessary
Files:
apps/desktop/src/shared/types.tsapps/desktop/src/lib/trpc/routers/workspaces/workspaces.tsapps/desktop/src/lib/trpc/routers/workspaces/utils/teardown.tsapps/desktop/src/renderer/screens/main/components/TopBar/WorkspaceTabs/DeleteWorkspaceDialog.tsx
**/*.{ts,tsx}
📄 CodeRabbit inference engine (AGENTS.md)
**/*.{ts,tsx}: Avoid usinganytype - use explicit types instead for type safety
Use camelCase for variable and function names following existing codebase patterns
Keep diffs minimal with targeted edits only - avoid unnecessary changes when making modifications
Follow existing patterns and match the codebase style when writing new code
Files:
apps/desktop/src/shared/types.tsapps/desktop/src/lib/trpc/routers/workspaces/workspaces.tsapps/desktop/src/lib/trpc/routers/workspaces/utils/teardown.tsapps/desktop/src/renderer/screens/main/components/TopBar/WorkspaceTabs/DeleteWorkspaceDialog.tsx
apps/desktop/src/lib/**/*.ts
📄 CodeRabbit inference engine (AGENTS.md)
Never import Node.js modules in shared code like
src/lib/electron-router-dom.ts- this code runs in both main and renderer processes
Files:
apps/desktop/src/lib/trpc/routers/workspaces/workspaces.tsapps/desktop/src/lib/trpc/routers/workspaces/utils/teardown.ts
**/components/**/*.tsx
📄 CodeRabbit inference engine (AGENTS.md)
**/components/**/*.tsx: Create one folder per component with structure:ComponentName/ComponentName.tsx+index.tsfor barrel export
Co-locate tests next to the component file they test (e.g.,ComponentName.test.tsx)
Co-locate dependencies (utils, hooks, constants, config, stories) next to the file using them
Use nestedcomponents/subdirectory within a parent component only if a sub-component is used 2+ times within that parent; otherwise keep it in the parent'scomponents/folder
One component per file - avoid multi-component files
Files:
apps/desktop/src/renderer/screens/main/components/TopBar/WorkspaceTabs/DeleteWorkspaceDialog.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/screens/main/components/TopBar/WorkspaceTabs/DeleteWorkspaceDialog.tsx
apps/desktop/src/renderer/**/*.tsx
📄 CodeRabbit inference engine (AGENTS.md)
Call IPC methods using
window.ipcRenderer.invoke()with object parameters - TypeScript will infer the exact response type automatically
Files:
apps/desktop/src/renderer/screens/main/components/TopBar/WorkspaceTabs/DeleteWorkspaceDialog.tsx
🧠 Learnings (3)
📚 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/lib/trpc/routers/workspaces/utils/teardown.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 independent
Applied to files:
apps/desktop/src/lib/trpc/routers/workspaces/utils/teardown.ts
📚 Learning: 2025-11-28T01:03:47.951Z
Learnt from: CR
Repo: superset-sh/superset PR: 0
File: AGENTS.md:0-0
Timestamp: 2025-11-28T01:03:47.951Z
Learning: Applies to **/*.{ts,tsx} : Keep diffs minimal with targeted edits only - avoid unnecessary changes when making modifications
Applied to files:
apps/desktop/src/renderer/screens/main/components/TopBar/WorkspaceTabs/DeleteWorkspaceDialog.tsx
🧬 Code graph analysis (3)
apps/desktop/src/lib/trpc/routers/workspaces/workspaces.ts (2)
apps/desktop/src/lib/trpc/routers/workspaces/utils/git.ts (1)
worktreeExists(99-116)apps/desktop/src/lib/trpc/routers/workspaces/utils/teardown.ts (1)
runTeardown(37-74)
superset-teardown.sh (1)
apps/cli/src/lib/storage/lowdb-adapter.ts (1)
set(162-172)
apps/desktop/src/renderer/screens/main/components/TopBar/WorkspaceTabs/DeleteWorkspaceDialog.tsx (1)
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). (2)
- GitHub Check: Build - macOS (arm64)
- GitHub Check: Build
🔇 Additional comments (2)
apps/desktop/src/shared/types.ts (1)
129-133: SetupConfig.teardown shape is consistent and backward compatibleAdding
teardown?: string[]mirrorscommands?: string[]and matches usage inteardown.tsand.superset/setup.json. No issues from a typing or compatibility standpoint..superset/setup.json (1)
2-3: Config shape matches SetupConfig and teardown runner expectations
commandsandteardownare bothstring[], which aligns withSetupConfigand howrunTeardownbuilds the command (join(" && ")). Ensure./superset-setup.shand./superset-teardown.share committed as executable so they can be run without extra setup.
- Add teardown commands to SetupConfig type - Create teardown.ts utility to run teardown scripts synchronously - Modify delete mutation to run teardown before worktree removal - Show toast warning if teardown fails (deletion still proceeds) - Add superset-teardown.sh to delete Neon branch on workspace deletion 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com>
Rename `commands` to `setup` for clarity and consistency with `teardown`. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com>
76585de to
f2fe1ed
Compare
🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com>
Summary
.superset/setup.jsonunder theteardownkeysuperset-teardown.shwhich deletes the associated Neon branchChanges
teardownfield toSetupConfigtypeteardown.tsutility to run teardown scripts synchronously (60s timeout)deletemutation to run teardown before worktree removalDeleteWorkspaceDialogTest plan
Notes
Users need to update their local
.superset/setup.jsonto include:{ "commands": ["./superset-setup.sh"], "teardown": ["./superset-teardown.sh"] }🤖 Generated with Claude Code
Summary by CodeRabbit
✏️ Tip: You can customize this high-level summary in your review settings.