Skip to content

feat(settings): make automatic terminal creation optional - #22504

Closed
trentshapiro wants to merge 7 commits into
stablyai:mainfrom
trentshapiro:feat/optional-auto-terminal-creation
Closed

trentshapiro wants to merge 7 commits into
stablyai:mainfrom
trentshapiro:feat/optional-auto-terminal-creation

Conversation

@trentshapiro

@trentshapiro trentshapiro commented Sep 23, 2026 •

Copy link
Copy Markdown

ELI5

Orca can now leave an empty workspace empty. A new setting controls whether selecting, creating, or importing an empty workspace opens a terminal automatically. When automatic creation is disabled, the workspace shows explicit actions for opening a terminal, Markdown note, or browser.

What Changed

  • Added Open a Terminal When Selecting a Workspace under General workspace settings. Existing behavior remains enabled by default.
  • Applied the preference when selecting a workspace, creating a project, importing a folder, and bootstrapping remote runtime workspaces.
  • Added an empty workspace surface with Terminal, Markdown, and Browser actions and their configured shortcuts.
  • Preserved terminals required by explicit startup, setup, issue command, agent, and nonempty default-tab launches.
  • Added behavior coverage for local activation, project onboarding, folder workspaces, SSH and remote activation, and web-runtime bootstrap.

Why

Workspace navigation should be able to remain passive. Users who intentionally keep a workspace empty should not have a terminal or process created merely because they selected, created, or imported it. A default-on preference preserves current behavior while allowing explicit control.

This implementation builds on the approach explored in #9960. It also incorporates the automated review feedback from that PR by using intent-named localization IDs and reusing the parent workspace model commands in the empty state.

Linked Issue

Fixes #11108

Visual Proof

Before, selecting an empty workspace with automatic creation enabled opens Terminal 1.

image

After, selecting an empty workspace with automatic creation disabled leaves it empty and presents explicit actions.

image

Testing

  • I manually tested these changes locally
  • Automated tests added and updated
  • Manually verified on macOS that selecting an empty workspace does not create a terminal when disabled.
  • Manually verified Create Project and Import Folder respect the preference.
  • Verified the default-on behavior still creates the initial terminal.
  • Verified the empty-state Terminal, Markdown, and Browser actions.
  • pnpm typecheck passes.
  • 139 focused tests across 12 files pass.
  • pnpm run check:code-quality:changed passes with zero findings.
  • pnpm run build:desktop passes.
  • Localization catalog, extraction, runtime catalog, and coverage checks pass.
  • pnpm lint was run and reaches unrelated existing import-cycle findings in unchanged mobile files.
  • pnpm test was run and reaches unrelated local environment and integration failures, including unavailable Playwright browser binaries and real CLI timeouts. The finalized feature-focused suite passes.
  • pnpm build completes desktop and web output, then the native macOS helper build fails locally when Xcode reports Unknown error parsing property list.
  • Linux, Windows, and SSH were not manually exercised. Platform-neutral logic and automated remote-runtime coverage were reviewed.

AI Disclosure

OpenAI Codex was used to inspect the stalled implementation, implement and test the feature, review the branch, incorporate prior automated feedback, and prepare this PR.

Review

  • Cross-platform compatibility was reviewed. The setting, state checks, and UI use existing platform-neutral abstractions with no new path or shortcut assumptions.
  • Local, SSH, and remote-runtime compatibility was reviewed. Remote initial-terminal bootstrap now observes the same preference, while explicit remote launch work remains preserved.
  • Supported agents and integrations were reviewed. The change is provider-neutral and keeps explicit agent startup, setup, issue command, and default-tab behavior intact.
  • Performance risk is low. The implementation adds boolean checks to existing activation paths and introduces no polling, network calls, or persistent background work.
  • UI quality was reviewed against existing settings and empty-state patterns. Existing design tokens, button primitives, shortcut rendering, and localization conventions are reused.
  • Basic security risk was reviewed. The change adds no permissions, credential access, shell interpolation, IPC surface, or external input handling.
  • The branch was reviewed against origin/main. No remaining feature-blocking issues were found.

Agent skill upstream boundary

  • Not applicable, or this change follows docs/reference/agent-skill-sharing-upstream-boundary.md and copies or mechanically translates no upstream skill-installer source, tests, fixtures, registry entries, path tables, comments, or documentation.

Notes

  • Prior implementation and discussion #9960
  • Original request #11108
  • X handle N/A

Checklist

  • This PR is small and focused
  • I explained what changed and why
  • Before and after screenshots attached
  • Self-reviewed for correctness, security, and performance
  • Cross-platform, SSH and remote, and path and shortcut impact considered
  • pnpm lint, pnpm typecheck, pnpm test, and pnpm build all pass locally. Local failures are documented above and CI will cover the full matrix.

@coderabbitai

coderabbitai Bot commented Sep 23, 2026 •

Copy link
Copy Markdown
Contributor

Review in Change Stack →

Navigate logical layers of code changes, visualize relationships, and explore their blast radius.

Note

Reviews paused

It looks like this branch is under active development. To avoid overwhelming you with review comments due to an influx of new commits, CodeRabbit has automatically paused this review. You can configure this behavior by changing the reviews.auto_review.auto_pause_after_reviewed_commits setting.

Use the following commands to manage reviews:

  • @coderabbitai resume to resume automatic reviews.
  • @coderabbitai review to trigger a single review.

Use the checkboxes below for quick actions:

  • ▶️ Resume reviews
  • 🔍 Trigger review

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Repository UI

Review profile: CHILL

Plan: Advanced

Run ID: 8c4e3cf3-a79c-4560-8be9-e59769bae29b

📥 Commits

Reviewing files that changed from the base of the PR and between f22910e and 9314f5c.

📒 Files selected for processing (5)
  • src/renderer/src/lib/web-runtime-worktree-terminal-after-wake.ts
  • src/renderer/src/lib/worktree-activation-empty-remote.test.ts
  • src/renderer/src/lib/worktree-activation.ts
  • src/renderer/src/lib/worktree-creation-flow-execute.ts
  • src/renderer/src/lib/worktree-creation-flow-stranded-surface.test.ts

Included review availability: Your plan provides up to 10 included reviews per hour; 9 remain after this review.


📝 Walkthrough

Walkthrough

The change adds a default-enabled setting that controls automatic terminal creation when selecting a workspace. Terminal seeding and web-runtime bootstrap paths read the setting, while explicit startup work remains handled separately. When automatic creation is disabled and a tab group has no active content, the panel can display terminal, markdown, and policy-controlled browser actions. Floating-terminal actions now use a shared action component.

Priority: ➖ Normal

Severity of issue fixed: Medium

Merge Risk: 🟡 Moderate · up to 9314f

With automatic terminal creation disabled, launches configured with default tabs can open a generic terminal without the requested tabs. This core workflow should be corrected before merging.

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 68.00% which is insufficient. The required threshold is 80.00%. Docstring coverage is scoped to functions touched by this diff. Analyzed 25 functions across 31 files. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Title check ✅ Passed The title clearly and concisely describes the main change: making automatic terminal creation optional through settings.
Description check ✅ Passed The description covers the required sections, linked issue, user-facing behavior, visual proof, testing, AI disclosure, compatibility review, and checklist. It also documents known local failures, alt…
Linked Issues check ✅ Passed Issue #11108 requires a way to select an empty existing workspace without automatic terminal creation. The PR adds the autoCreateTerminalOnWorkspaceActivation setting, defaults it to enabled, and ap…
Out of Scope Changes check ✅ Passed The settings UI, activation gates, remote bootstrap changes, empty-state actions, translation updates, and tests directly implement or support issue #11108. The shared empty-state action component and…
  • Fix all pre-merge checks with AI

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.

@coderabbitai coderabbitai Bot left a comment

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.

Actionable comments posted: 1

🧹 Nitpick comments (1)
src/renderer/src/components/settings/GeneralWorkspaceSettingsSection.tsx (1)

106-106: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick win

Use intent-named IDs for the new localization strings.

The new setting and search strings use newly minted hash IDs. The repository policy does not grandfather these IDs. Rename the setting title, description, search title, description, and keyword IDs in an adjacent dedicated localization change, with matching English catalog entries.


ℹ️ Review info
⚙️ Run configuration

Configuration used: Repository UI

Review profile: CHILL

Plan: Advanced

Run ID: a2093a8a-8909-4159-b34d-a291d488424d

📥 Commits

Reviewing files that changed from the base of the PR and between dac82f6 and 97ca889.

📒 Files selected for processing (29)
  • src/renderer/src/components/WorkspaceEmptyStateAction.tsx
  • src/renderer/src/components/floating-terminal/FloatingTerminalEmptyState.tsx
  • src/renderer/src/components/floating-terminal/FloatingTerminalPanel.empty-state.test.tsx
  • src/renderer/src/components/settings/GeneralWorkspaceSettingsSection.test.tsx
  • src/renderer/src/components/settings/GeneralWorkspaceSettingsSection.tsx
  • src/renderer/src/components/settings/general-search.ts
  • src/renderer/src/components/tab-group/TabGroupEmptyState.tsx
  • src/renderer/src/components/tab-group/TabGroupPanel.tsx
  • src/renderer/src/components/terminal/initial-terminal-structured-launch.test.tsx
  • src/renderer/src/components/terminal/initial-terminal-wiring.test.ts
  • src/renderer/src/components/terminal/initial-terminal.test.ts
  • src/renderer/src/components/terminal/initial-terminal.ts
  • src/renderer/src/components/use-terminal-watcher-effects.ts
  • src/renderer/src/i18n/locales/en.json
  • src/renderer/src/lib/can-inspect-agent-activation-inventory.ts
  • src/renderer/src/lib/web-runtime-worktree-terminal-after-wake.ts
  • src/renderer/src/lib/worktree-activation-created-agent.test.ts
  • src/renderer/src/lib/worktree-activation-default-tabs.test.ts
  • src/renderer/src/lib/worktree-activation-emptied-workspace-reseed.test.ts
  • src/renderer/src/lib/worktree-activation-empty-remote.test.ts
  • src/renderer/src/lib/worktree-activation-store-contract.ts
  • src/renderer/src/lib/worktree-activation.ts
  • src/renderer/src/lib/worktree-creation-flow-execute.ts
  • src/renderer/src/lib/worktree-initial-terminal-seeding.ts
  • src/renderer/src/runtime/web-session-tabs-sync-terminal-bootstrap.test.ts
  • src/renderer/src/runtime/web-session-tabs-sync/active-session-subscription.ts
  • src/renderer/src/runtime/web-session-tabs-sync/tracking-decisions.ts
  • src/shared/default-global-settings.ts
  • src/shared/global-settings-types.ts

Included review availability: Your plan provides up to 10 included reviews per hour; 9 remain after this review.

@pullfrog pullfrog Bot left a comment

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.

Important

Turning off Open a Terminal When Selecting a Workspace silently drops configured default tabs — and, on the web-runtime path, non-agent startup work — in the backgrounded and activation-recovery create paths. The primary activation path preserves them, so the same workspace behaves differently depending on whether the create was backgrounded.

Reviewed changes

  • New setting — autoCreateTerminalOnWorkspaceActivation (default on) added to GlobalSettings, buildDefaultSettings, the General workspace pane, and the general search catalog.
  • Activation gate — shouldAutoCreateInitialTerminal gains a third automaticCreationEnabled argument, threaded through local/folder/SSH activation, the seeding helper, web-runtime after-wake, worktree creation, and the web-session bootstrap.
  • Empty-workspace surface — new WorkspaceEmptyStateAction + TabGroupEmptyState, rendered by TabGroupPanel only when the setting is off; FloatingTerminalEmptyState is refactored onto the shared action.
  • Empty defaultTabs no longer counts as activation work — hasActivationWork now uses opts?.defaultTabs?.tabs.length.
  • Extraction — canInspectAgentActivationInventory moved to its own module; behavior tests added for local, folder, SSH/remote, web-runtime, and the settings toggle.

ℹ️ Nitpicks

  • TabGroupEmptyState always renders the New Browser action, while FloatingTerminalEmptyState gates it behind showNewBrowser. On workspaces where managed browser creation is disabled (e.g. some SSH/remote hosts), clicking it throws and surfaces an error toast; consider computing availability via getClientCreationActionPolicy and hiding the action.

Pullfrog  | Fix all ➔ | Fix 👍s ➔ | View workflow run | Using DeepSeek Flash (free via Pullfrog for OSS) | 𝕏

@pullfrog pullfrog Bot left a comment

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.

✅ No new issues found.

Reviewed changes

Fixes the prior review's default-tab/web-runtime findings, gates the empty-state Browser action, and renames the new localization IDs. New commits since the last pullfrog review (97ca8897df):

  • Default tabs preserved when the setting is off — ensureWorktreeHasInitialTerminal now counts a non-empty defaultTabs payload as explicit launch work, so applyDefaultTerminalTabs still runs with automaticCreationEnabled: false.
  • Web-runtime non-agent startup preserved — ensureWebRuntimeWorktreeTerminalAfterWake skips the passive-seed gate when an explicit startup is supplied.
  • Browser action gated in the empty state — TabGroupEmptyState gains a showNewBrowser prop, computed in TabGroupPanel from getClientCreationActionPolicy, matching FloatingTerminalEmptyState.
  • Intent-named localization IDs — the setting/search strings were renamed off hashed IDs, and JSDoc was added to the touched exports.
  • Tests — coverage added for preserved default tabs, preserved remote startup, the disabled-setting empty workspace, and the Browser action gating.

Pullfrog  | View workflow run | Using DeepSeek Flash (free via Pullfrog for OSS) | 𝕏

@trentshapiro

Copy link
Copy Markdown
Author

@coderabbitai review

@coderabbitai coderabbitai Bot left a comment

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.

Actionable comments posted: 2


ℹ️ Review info
⚙️ Run configuration

Configuration used: Repository UI

Review profile: CHILL

Plan: Advanced

Run ID: c6c929dd-d6a4-4201-a3a5-e01cde99f49d

📥 Commits

Reviewing files that changed from the base of the PR and between 97ca889 and a71d53d.

📒 Files selected for processing (19)
  • src/renderer/src/components/WorkspaceEmptyStateAction.tsx
  • src/renderer/src/components/floating-terminal/FloatingTerminalEmptyState.tsx
  • src/renderer/src/components/settings/GeneralWorkspaceSettingsSection.tsx
  • src/renderer/src/components/settings/general-search.ts
  • src/renderer/src/components/tab-group/TabGroupEmptyState.test.tsx
  • src/renderer/src/components/tab-group/TabGroupEmptyState.tsx
  • src/renderer/src/components/tab-group/TabGroupPanel.tsx
  • src/renderer/src/components/terminal/initial-terminal.ts
  • src/renderer/src/components/use-terminal-watcher-effects.ts
  • src/renderer/src/i18n/locales/en.json
  • src/renderer/src/lib/can-inspect-agent-activation-inventory.ts
  • src/renderer/src/lib/web-runtime-worktree-terminal-after-wake.ts
  • src/renderer/src/lib/worktree-activation-default-tabs.test.ts
  • src/renderer/src/lib/worktree-activation-empty-remote.test.ts
  • src/renderer/src/lib/worktree-activation.ts
  • src/renderer/src/lib/worktree-creation-flow-execute.ts
  • src/renderer/src/lib/worktree-initial-terminal-seeding.ts
  • src/renderer/src/runtime/web-session-tabs-sync/tracking-decisions.ts
  • src/shared/default-global-settings.ts
🚧 Files skipped from review as they are similar to previous changes (10)
  • src/renderer/src/components/terminal/initial-terminal.ts
  • src/renderer/src/runtime/web-session-tabs-sync/tracking-decisions.ts
  • src/renderer/src/components/use-terminal-watcher-effects.ts
  • src/shared/default-global-settings.ts
  • src/renderer/src/lib/can-inspect-agent-activation-inventory.ts
  • src/renderer/src/i18n/locales/en.json
  • src/renderer/src/components/WorkspaceEmptyStateAction.tsx
  • src/renderer/src/lib/worktree-creation-flow-execute.ts
  • src/renderer/src/components/floating-terminal/FloatingTerminalEmptyState.tsx
  • src/renderer/src/lib/worktree-activation.ts

Included review availability: Your plan provides up to 10 included reviews per hour; 8 remain after this review.

@coderabbitai

coderabbitai Bot commented Sep 23, 2026 •

Copy link
Copy Markdown
Contributor
⚠️ Action not completed

Already reviewed the last commit. Use @coderabbitai full review to rerun a review of the entire changeset.

Note: CodeRabbit is an incremental review system and does not re-review already reviewed commits. This command is applicable only when automatic reviews are paused.

@pullfrog pullfrog Bot left a comment

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.

✅ No new issues found.

Reviewed changes

Follow-up fix for duplicate activation terminals. New commits since the last pullfrog review (a71d53d13b):

  • Applied default tabs no longer count as explicit launch work — ensureWorktreeHasInitialTerminal computes hasPendingDefaultTabs (a non-empty defaultTabs payload with no persisted applied marker) and uses it for both hasExplicitLaunchWork and the callerProvidesSurface early return, so re-activating an already-seeded workspace can no longer fall through to a bare fallback terminal when automatic creation is off.
  • Web-runtime wake duplicate guards restored for non-agent startup — ensureWebRuntimeWorktreeTerminalAfterWake's live-PTY / mirrored-host-tabs / last-known-count guards run again when opts.startup is set; only the empty-workspace auto-create gate stays skipped for startup.
  • Tests — applied default tabs with the setting off create nothing; non-agent startup does not repeat when a terminal is already live.

The prior review's open thread (worktree-creation-flow-execute.ts) is resolved and its concern remains addressed by this refinement.

Pullfrog  | View workflow run | Using DeepSeek Flash (free via Pullfrog for OSS) | 𝕏

@pullfrog pullfrog Bot left a comment

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.

Important

The flag simplification in f22910ee68 drops explicit non-startup launch work (setup, issueCommand, non-empty defaultTabs) on the web-runtime after-wake path when the setting is off — the host terminal is never requested, so the queued commands have no tab to attach to. Existing tests do not cover this arm.

Reviewed changes — incremental review of f22910ee68 ("refactor: simplify initial terminal activation") since the prior pullfrog review at 20ac964a75:

  • Setting read at the leaf — ensureWorktreeHasInitialTerminal and ensureWebRuntimeWorktreeTerminalAfterWake now read settings.autoCreateTerminalOnWorkspaceActivation directly instead of accepting the caller-threaded automaticCreationEnabled option; InitialTerminalOptions and the store contract drop the field.
  • Activation derivation removed — activateAndRevealWorktree no longer computes hasActivationWork || setting !== false; the agent-activation gate reads the setting inline (equivalent, since those gates are already guarded by !hasActivationWork / !opts.startup).
  • Inventory helper inlined — can-inspect-agent-activation-inventory.ts was deleted and canInspectAgentActivationInventory moved back into worktree-activation.ts.
  • Test rewrites — worktree-activation-empty-remote.test.ts rebuilt on a seedRemoteWorktreeTestState helper; TabGroupEmptyState.test.tsx moved to React Testing Library; JSDoc reworded across the touched modules.

The single existing review thread (worktree-creation-flow-execute.ts) is already resolved, and the new commits do not reopen it.

Pullfrog  | Fix all ➔ | Fix 👍s ➔ | View workflow run | Using DeepSeek Flash (free via Pullfrog for OSS) | 𝕏

@pullfrog pullfrog Bot left a comment

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.

✅ No new issues found.

Reviewed changes — incremental review of 9314f5c9b9 ("fix: preserve explicit web-runtime launch work") since the prior pullfrog review at f22910ee68:

  • Explicit-work bypass restored on the web-runtime after-wake path — ensureWebRuntimeWorktreeTerminalAfterWake gains hasExplicitLaunchWork; when set, it skips the passive empty-workspace gate so the host terminal is requested even with the setting off.
  • Callers forward the signal — activateAndRevealWorktree passes hasActivationWork, and executeWorktreeCreation computes hasExplicitTerminalWork once and passes it to both the activation-recovery and backgrounded after-wake sites.
  • defaultTabs truthiness tightened — the creation-flow flag now counts result.defaultTabs?.tabs.length, matching the seeding helper's pending-tab semantics.
  • Tests — after-wake coverage for the explicit-work bypass with the setting off, plus an assertion that a setup create forwards hasExplicitLaunchWork: true.

The prior review's regression (explicit non-startup work stranded on a live web runtime with the setting off) is resolved and its thread is closed. The remaining live-host limitation — defaultTabs are not materialized on a live host authority regardless of the setting — is pre-existing from 20ac964a75 and outside this delta.

Pullfrog  | View workflow run | Using DeepSeek Flash (free via Pullfrog for OSS) | 𝕏

@AmethystLiang

Copy link
Copy Markdown
Contributor

Thank you so much, @trentshapiro, for the thoughtful implementation, tests, and before/after evidence here, and for crediting @yiuf63’s earlier work in #9960. We referred to your PR while comparing the community approaches with the empty-pane launch UI that has now landed in #32182.

I have explicitly credited you and linked this PR in #32182. The empty-state action surface is now available there, including file, terminal, browser, and host-aware agent launches. Your automatic-terminal preference and its activation/creation/import/bootstrap coverage go beyond what #32182 landed; that remaining request is still tracked in #11108.

We really appreciate the care you put into this and the concrete coverage you provided. Thank you again for helping move this workflow forward.

@trentshapiro

Copy link
Copy Markdown
Author

Closing as superseded.

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.

[Feature]: Allow selecting an empty workspace without creating a terminal

2 participants