Repository navigation
feat(desktop): add background preset launch mode - #5988
MikeMcQuaid wants to merge 1 commit into
Conversation
|
Ready to review this PR? Stage has broken it down into 7 individual chapters for you: Chapters generated by Stage for commit ce13806 on Jul 27, 2026 1:41pm UTC. |
📝 WalkthroughWalkthroughThe PR adds background terminal preset support with editor, launch, and lifecycle handling. It also adds macOS command app-bundle icon lookup, exposes it through tRPC, and uses the result as a preset icon fallback. ChangesPreset execution and command app icons
Estimated code review effort: 4 (Complex) | ~45 minutes Possibly related PRs
🚥 Pre-merge checks | ✅ 4 | ❌ 1❌ Failed checks (1 warning)
✅ Passed checks (4 passed)
✨ Finishing Touches🧪 Generate unit tests (beta)
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: 2
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Inline comments:
In `@apps/desktop/src/renderer/lib/preset-icon-key.ts`:
- Around line 98-105: Update resolvePresetCommandExecutable and its command-name
extraction so path-based commands return undefined, while bare executable
commands preserve their original parsed casing. Do not reuse getExecutableName,
since it lowercases values and strips paths; ensure singleValue still returns
undefined when commands resolve to conflicting executables.
In `@packages/local-db/src/schema/zod.ts`:
- Line 83: Keep background v2-only: in packages/local-db/src/schema/zod.ts lines
83 and 93-94, separate v2 modes from EXECUTION_MODES and normalize background to
new-tab for v1. In
apps/desktop/src/renderer/routes/_authenticated/settings/terminal/components/TerminalSettings/components/PresetsSection/PresetsSection.tsx
lines 14 and 384-387, use v1-compatible normalization and ensure the dialog
receives only a mode supported by its options. Update
apps/desktop/src/lib/trpc/routers/settings/preset-execution-mode.test.ts lines
49, 58, and 134 to remove background from v1 fixtures, expect fallback to
new-tab, and no longer treat background as normalized.
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: defaults
Review profile: CHILL
Plan: Pro Plus
Run ID: deae4399-523b-430a-a269-6bcec20fd93b
📒 Files selected for processing (22)
apps/desktop/src/lib/trpc/routers/external/app-icon.tsapps/desktop/src/lib/trpc/routers/external/index.tsapps/desktop/src/lib/trpc/routers/settings/preset-execution-mode.test.tsapps/desktop/src/renderer/hooks/useCommandAppIcons/index.tsapps/desktop/src/renderer/hooks/useCommandAppIcons/useCommandAppIcons.tsapps/desktop/src/renderer/lib/preset-icon-key.tsapps/desktop/src/renderer/routes/_authenticated/_dashboard/v2-workspace/$workspaceId/components/V2PresetsBar/V2PresetsBar.tsxapps/desktop/src/renderer/routes/_authenticated/_dashboard/v2-workspace/$workspaceId/components/V2PresetsBar/components/V2PresetBarItem/V2PresetBarItem.tsxapps/desktop/src/renderer/routes/_authenticated/_dashboard/v2-workspace/$workspaceId/hooks/useV2PresetExecution/useV2PresetExecution.tsapps/desktop/src/renderer/routes/_authenticated/_dashboard/v2-workspace/$workspaceId/hooks/useWorkspacePaneOpeners/useWorkspacePaneOpeners.tsapps/desktop/src/renderer/routes/_authenticated/providers/CollectionsProvider/dashboardSidebarLocal/schema.tsapps/desktop/src/renderer/routes/_authenticated/settings/terminal/components/TerminalSettings/components/PresetRow/PresetRow.tsxapps/desktop/src/renderer/routes/_authenticated/settings/terminal/components/TerminalSettings/components/PresetRow/PresetRow.utils.test.tsapps/desktop/src/renderer/routes/_authenticated/settings/terminal/components/TerminalSettings/components/PresetRow/PresetRow.utils.tsapps/desktop/src/renderer/routes/_authenticated/settings/terminal/components/TerminalSettings/components/PresetsSection/PresetsSection.tsxapps/desktop/src/renderer/routes/_authenticated/settings/terminal/components/TerminalSettings/components/PresetsSection/components/PresetEditorDialog/PresetEditorDialog.tsxapps/desktop/src/renderer/routes/_authenticated/settings/terminal/components/TerminalSettings/components/PresetsSection/components/PresetsTable/PresetsTable.tsxapps/desktop/src/renderer/routes/_authenticated/settings/terminal/components/TerminalSettings/components/V2PresetsSection/V2PresetsSection.tsxapps/desktop/src/renderer/stores/tabs/preset-launch.test.tsapps/desktop/src/renderer/stores/tabs/preset-launch.tsapps/desktop/test-setup.tspackages/local-db/src/schema/zod.ts
ce13806 to
625cbd8
Compare
There was a problem hiding this comment.
Actionable comments posted: 2
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/routes/_authenticated/settings/terminal/components/TerminalSettings/components/V2PresetsSection/V2PresetsSection.tsx (1)
295-314: 🗄️ Data Integrity & Integration | 🟠 Major | ⚡ Quick winDo not update ambiguous legacy preset snapshots.
Line 304 treats
updated.presetIdas a linked agent identity. The migration at Lines 267-285 correctly skips this case when multiple agent configs share thatpresetId. Saving either matching agent can overwrite the same legacy row's fallback command. A later launch without loaded agent config can run the wrong command.Only sync an exact
agentIdmatch, or apply the same unique-match check before updating a legacy row.Proposed fix
+ const matchingLegacyAgents = agents.filter( + (agent) => agent.presetId === updated.presetId, + ); for (const preset of serverPresetsRef.current) { const row = preset as V2TerminalPresetRow; - if (row.agentId !== updated.id && row.agentId !== updated.presetId) { + const isUniqueLegacyLink = + row.agentId === updated.presetId && + matchingLegacyAgents.length === 1; + if (row.agentId !== updated.id && !isUniqueLegacyLink) { continue; }🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@apps/desktop/src/renderer/routes/_authenticated/settings/terminal/components/TerminalSettings/components/V2PresetsSection/V2PresetsSection.tsx` around lines 295 - 314, Update syncLinkedPresetSnapshots so legacy preset rows are not synchronized through ambiguous presetId matches: only use an exact row.agentId-to-updated.id match, or first verify that the presetId identifies a unique agent configuration using the same check as the migration logic. Preserve synchronization for unambiguous linked presets and avoid overwriting shared legacy rows.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Inline comments:
In `@apps/desktop/src/lib/trpc/routers/external/app-icon.ts`:
- Around line 55-58: Update the getFileIcon call in the app icon retrieval flow
to use the macOS-supported normal size or omit the size option, while preserving
the existing empty-icon null handling and data URL return behavior.
- Around line 22-29: Update resolveExecutablePath to pass a finite timeout
option to execFileAsync when invoking /usr/bin/which, preventing the lookup from
hanging indefinitely. Preserve the existing error handling and null fallback for
timeout or other lookup failures.
---
Outside diff comments:
In
`@apps/desktop/src/renderer/routes/_authenticated/settings/terminal/components/TerminalSettings/components/V2PresetsSection/V2PresetsSection.tsx`:
- Around line 295-314: Update syncLinkedPresetSnapshots so legacy preset rows
are not synchronized through ambiguous presetId matches: only use an exact
row.agentId-to-updated.id match, or first verify that the presetId identifies a
unique agent configuration using the same check as the migration logic. Preserve
synchronization for unambiguous linked presets and avoid overwriting shared
legacy rows.
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: defaults
Review profile: CHILL
Plan: Pro Plus
Run ID: 001ba7aa-d247-4abc-9558-701db5ff7562
📒 Files selected for processing (23)
apps/desktop/src/lib/trpc/routers/external/app-icon.tsapps/desktop/src/lib/trpc/routers/external/index.tsapps/desktop/src/lib/trpc/routers/settings/preset-execution-mode.test.tsapps/desktop/src/renderer/hooks/useCommandAppIcons/index.tsapps/desktop/src/renderer/hooks/useCommandAppIcons/useCommandAppIcons.tsapps/desktop/src/renderer/lib/preset-icon-key.test.tsapps/desktop/src/renderer/lib/preset-icon-key.tsapps/desktop/src/renderer/routes/_authenticated/_dashboard/v2-workspace/$workspaceId/components/V2PresetsBar/V2PresetsBar.tsxapps/desktop/src/renderer/routes/_authenticated/_dashboard/v2-workspace/$workspaceId/components/V2PresetsBar/components/V2PresetBarItem/V2PresetBarItem.tsxapps/desktop/src/renderer/routes/_authenticated/_dashboard/v2-workspace/$workspaceId/hooks/useV2PresetExecution/useV2PresetExecution.tsapps/desktop/src/renderer/routes/_authenticated/_dashboard/v2-workspace/$workspaceId/hooks/useWorkspacePaneOpeners/useWorkspacePaneOpeners.tsapps/desktop/src/renderer/routes/_authenticated/providers/CollectionsProvider/dashboardSidebarLocal/schema.tsapps/desktop/src/renderer/routes/_authenticated/settings/terminal/components/TerminalSettings/components/PresetRow/PresetRow.tsxapps/desktop/src/renderer/routes/_authenticated/settings/terminal/components/TerminalSettings/components/PresetRow/PresetRow.utils.test.tsapps/desktop/src/renderer/routes/_authenticated/settings/terminal/components/TerminalSettings/components/PresetRow/PresetRow.utils.tsapps/desktop/src/renderer/routes/_authenticated/settings/terminal/components/TerminalSettings/components/PresetsSection/PresetsSection.tsxapps/desktop/src/renderer/routes/_authenticated/settings/terminal/components/TerminalSettings/components/PresetsSection/components/PresetEditorDialog/PresetEditorDialog.tsxapps/desktop/src/renderer/routes/_authenticated/settings/terminal/components/TerminalSettings/components/PresetsSection/components/PresetsTable/PresetsTable.tsxapps/desktop/src/renderer/routes/_authenticated/settings/terminal/components/TerminalSettings/components/V2PresetsSection/V2PresetsSection.tsxapps/desktop/src/renderer/stores/tabs/preset-launch.test.tsapps/desktop/src/renderer/stores/tabs/preset-launch.tsapps/desktop/test-setup.tspackages/local-db/src/schema/zod.ts
🚧 Files skipped from review as they are similar to previous changes (11)
- apps/desktop/src/renderer/routes/_authenticated/settings/terminal/components/TerminalSettings/components/PresetsSection/components/PresetsTable/PresetsTable.tsx
- apps/desktop/src/lib/trpc/routers/settings/preset-execution-mode.test.ts
- apps/desktop/src/renderer/routes/_authenticated/settings/terminal/components/TerminalSettings/components/PresetRow/PresetRow.utils.test.ts
- apps/desktop/src/renderer/routes/_authenticated/providers/CollectionsProvider/dashboardSidebarLocal/schema.ts
- apps/desktop/src/renderer/stores/tabs/preset-launch.ts
- apps/desktop/src/lib/trpc/routers/external/index.ts
- apps/desktop/src/renderer/hooks/useCommandAppIcons/index.ts
- apps/desktop/src/renderer/routes/_authenticated/_dashboard/v2-workspace/$workspaceId/components/V2PresetsBar/components/V2PresetBarItem/V2PresetBarItem.tsx
- apps/desktop/src/renderer/routes/_authenticated/_dashboard/v2-workspace/$workspaceId/components/V2PresetsBar/V2PresetsBar.tsx
- apps/desktop/src/renderer/hooks/useCommandAppIcons/useCommandAppIcons.ts
- apps/desktop/src/renderer/routes/_authenticated/_dashboard/v2-workspace/$workspaceId/hooks/useV2PresetExecution/useV2PresetExecution.ts
- Presets that launch GUI tools (e.g. `fork .`, `zed .`) stole focus and needed a manual `; exit` to close their terminal. - New v2-only `background` execution mode runs preset commands in a pane-less session behind the background-terminals button; an appended `; exit` closes it when the run finishes and a non-zero exit surfaces as a failure toast via `terminal:lifecycle`. - Preset bar and settings rows fall back to the macOS app-bundle icon for GUI-tool commands instead of the generic terminal glyph.
625cbd8 to
5a65e25
Compare
|
Note GitHub couldn't provide a complete incremental comparison for this pull request, so CodeRabbit is performing a full review instead. This review may take a little longer. |
What & why
Presets that launch GUI tools (e.g.
fork .,zed .) opened a foregroundterminal tab that stole focus from the CLI you were working in, needed a
manual
; exitto close themselves and showed the generic terminal glyphin the presets bar instead of the app's icon.
For v2 workspaces this PR adds:
backgroundexecution mode: commands run in a pane-lesshost-service session with
; exitappended, so nothing opens in theforeground, focus stays put and the terminal exits and closes itself
when the run finishes. While running, the session sits behind the
existing background-terminals button (adopt or kill from there) and is
marked so session auto-adoption leaves it alone. The preset editor
offers the mode as a "Background" segment (single command) or "In the
background" select entry (grouped commands); the v1 editor does not
offer it and v1 degrades legacy data to the default new-tab behaviour.
useV2PresetExecutionlistens toterminal:lifecycleand toasts the preset name and exit code when a background run exits
non-zero. Kills arrive as signal exits or dispose broadcasts with code
0, so they stay silent.
external.getCommandAppIconsprocedure resolves the preset's executable via login-shell
which,follows symlinks to the containing
.appbundle and returnsapp.getFileIconas a cached data URI. The presets bar, its managedropdown and the settings rows fall back to it, so
fork .showsFork's icon and
zed .shows Zed's. Agent icons (Claude, Codex) keepprecedence and non-app commands keep the terminal glyph.
How I tested it
bun testinapps/desktop: 2296 pass; the 3 failures(
shell-wrappers, shell-envgit.test.ts) also fail on the basecommit in this sandbox. New unit cases cover
normalizeExecutionMode,getPresetLaunchPlan,buildBackgroundTerminalCommand,getPresetModeLabelandgetLaunchModeValue.bun run typecheck --filter=@superset/desktop --filter=@superset/local-dband
bun run lintpass.quick visual check that Fork/Zed presets pick up their bundle icons and
that the background-terminals button shows the session while running
and clears once it exits.
Checklist
type(scope): subject)bun run lintandbun run typecheckpass (CI fails on lint warnings too)Summary by cubic
Adds a v2-only “background” launch mode for presets so GUI-tool commands run without opening a tab or stealing focus, and adds macOS app‑bundle icons for GUI‑tool presets like
fork .andzed .. Background sessions auto‑close and show a failure toast on non‑zero exit.New Features
terminal:lifecycleexits; non‑zero exits from background runs toast the preset name and code; signal kills stay silent.external.getCommandAppIconsresolves.appbundle icons viawhich+ Electronapp.getFileIcon, caching data URIs. The presets bar (items and manage menu) and settings rows fall back to these when no agent icon matches; non‑app, path‑based, or conflicting commands keep the terminal glyph.Bug Fixes
Written for commit 5a65e25. Summary will update on new commits.
Summary by CodeRabbit
New Features
Bug Fixes