diff --git a/src/renderer/src/components/WorkspaceEmptyAgentList.tsx b/src/renderer/src/components/WorkspaceEmptyAgentList.tsx
deleted file mode 100644
index 61acbaadbd2..00000000000
--- a/src/renderer/src/components/WorkspaceEmptyAgentList.tsx
+++ /dev/null
@@ -1,121 +0,0 @@
-import { AgentIcon, getAgentLabel } from '@/lib/agent-catalog'
-import { AgentTerminalLaunchButton } from './agent/AgentTerminalLaunchButton'
-import { useAgentDetectionTargetForWorktree } from '@/hooks/useAgentDetectionTarget'
-import { focusTerminalTabSurface } from '@/lib/focus-terminal-tab-surface'
-import { useAppStore } from '@/store'
-import { translate } from '@/i18n/i18n'
-import { requestNativeChatComposerFocus } from './native-chat/use-native-chat-composer-reveal-focus'
-import { useTabAgentMenuLaunch } from './tab-bar/QuickLaunchButton'
-import { useNewTabAgentMenuRows } from './tab-bar/use-new-tab-agent-menu-rows'
-import {
- chatUnavailableLabel,
- rowId,
- rowLabel,
- rowTitle
-} from './tab-bar/tab-agent-row-presentation'
-import { Button } from './ui/button'
-
-export function WorkspaceEmptyAgentList({
- worktreeId,
- groupId
-}: {
- worktreeId: string
- groupId: string
-}): React.JSX.Element {
- const target = useAgentDetectionTargetForWorktree(worktreeId)
- const model = useNewTabAgentMenuRows(worktreeId, true, target)
- const launch = useTabAgentMenuLaunch({
- worktreeId,
- groupId,
- onFocusTerminal: focusTerminalTabSurface,
- onFocusChat: requestNativeChatComposerFocus
- })
- const openSettingsPage = useAppStore((state) => state.openSettingsPage)
- const openSettingsTarget = useAppStore((state) => state.openSettingsTarget)
- const primaryRow =
- model.state === 'settled'
- ? model.rows.find((row) => row.kind !== 'chat-unavailable')
- : undefined
-
- return (
-
-
- {translate('components.WorkspaceEmptyState.startAgent', 'Start an agent')}
-
- {model.state === 'loading' ? (
-
- {translate('auto.components.tab.bar.QuickLaunchButton.agentsLoading', 'Loading agents')}
-
- ) : model.rows.length === 0 ? (
-
- {model.detection.needsServerUpdate
- ? translate(
- 'auto.components.tab.bar.QuickLaunchButton.needsServerUpdate',
- 'Update Orca on this server to list this workspace’s agents'
- )
- : model.detection.detectionFailed
- ? translate(
- 'auto.components.tab.bar.QuickLaunchButton.hostUnreachable',
- 'Can’t reach this workspace’s host to list its agents'
- )
- : model.detection.detectedIds?.length
- ? translate(
- 'auto.components.tab.bar.QuickLaunchButton.8dea9b5cdf',
- 'No enabled agents'
- )
- : translate(
- 'auto.components.tab.bar.QuickLaunchButton.e518f544b1',
- 'No agents detected'
- )}
-
- ) : (
-
- {model.rows.map((row) => (
-
-
-
- {row.kind === 'chat' ? (
-
launch({ ...row, kind: 'cli' })}
- />
- ) : null}
-
- {row.kind === 'chat-unavailable' ? (
-
- {chatUnavailableLabel(row.reason)}
-
- ) : null}
-
- ))}
-
- )}
-
-
- )
-}
diff --git a/src/renderer/src/components/WorkspaceEmptyState.tsx b/src/renderer/src/components/WorkspaceEmptyState.tsx
deleted file mode 100644
index 053ad0a2ecf..00000000000
--- a/src/renderer/src/components/WorkspaceEmptyState.tsx
+++ /dev/null
@@ -1,88 +0,0 @@
-import { FileText, Globe, Terminal } from 'lucide-react'
-import { useAppStore } from '@/store'
-import { translate } from '@/i18n/i18n'
-import { getWorkspaceClientCreationActionPolicy } from '@/lib/client-creation-action-policy'
-import { showClientCreationActionError } from '@/lib/client-creation-action-error'
-import { openDocumentInFloatingWorkspace } from '@/lib/open-document-in-floating-workspace'
-import { FLOATING_TERMINAL_WORKTREE_ID } from '../../../shared/constants'
-import { WorkspaceEmptyAgentList } from './WorkspaceEmptyAgentList'
-import { Button } from './ui/button'
-
-export function WorkspaceEmptyState({
- worktreeId,
- groupId
-}: {
- worktreeId: string
- groupId: string
-}): React.JSX.Element {
- const newTerminal = useAppStore((state) => state.openNewTerminalTabInActiveWorkspace)
- const newBrowser = useAppStore((state) => state.openNewBrowserTabInActiveWorkspace)
- const openModal = useAppStore((state) => state.openModal)
- const focusGroup = useAppStore((state) => state.focusGroup)
- const browserEnabled = useAppStore(
- (state) =>
- getWorkspaceClientCreationActionPolicy(state, worktreeId)['managed-browser'].state ===
- 'enabled'
- )
- const openFile = async (): Promise => {
- focusGroup(worktreeId, groupId)
- if (worktreeId === FLOATING_TERMINAL_WORKTREE_ID) {
- const document = await window.api.app.pickFloatingMarkdownDocument()
- if (document) {
- openDocumentInFloatingWorkspace(useAppStore.getState().openFile, document, {
- targetGroupId: groupId
- })
- }
- return
- }
- openModal('quick-open')
- }
-
- return (
-
-
-
- {translate('components.WorkspaceEmptyState.title', 'What would you like to do?')}
-
-
- {translate(
- 'components.WorkspaceEmptyState.description',
- 'No tabs are open here. Start an agent or open a tool to get going.'
- )}
-
-
-
-
- {browserEnabled ? (
-
- ) : null}
-
-
-
-
- )
-}
diff --git a/src/renderer/src/components/tab-bar/QuickLaunchButton.launch-status.test.tsx b/src/renderer/src/components/tab-bar/QuickLaunchButton.launch-status.test.tsx
index c775a5766d2..9352e9b27c6 100644
--- a/src/renderer/src/components/tab-bar/QuickLaunchButton.launch-status.test.tsx
+++ b/src/renderer/src/components/tab-bar/QuickLaunchButton.launch-status.test.tsx
@@ -33,7 +33,6 @@ vi.mock('@/store', async () => {
return { useAppStore }
})
vi.mock('@/lib/agent-catalog', () => ({
- getAgentLabel: (agent: string) => (agent === 'codex' ? 'Codex' : 'Claude'),
getAgentCatalog: () => [
{ id: 'claude', label: 'Claude' },
{ id: 'codex', label: 'Codex' }
@@ -68,7 +67,6 @@ vi.mock('@/lib/launch-agent-in-new-tab', () => ({ launchAgentInNewTab: launchMoc
type DivProps = { disabled?: boolean; title?: string; onSelect?: () => void }
import { QuickLaunchAgentMenuItems, ProjectedAgentMenuItems } from './QuickLaunchButton'
-import { WorkspaceEmptyAgentList } from '../WorkspaceEmptyAgentList'
import { useTabBarCreateMenuController } from './use-tab-bar-create-menu-controller'
import * as menuRows from './use-new-tab-agent-menu-rows'
import {
@@ -78,43 +76,6 @@ import {
const WORKTREE_ID = 'worktree-1'
-it('offers separate chat and CLI launches on the empty workspace with the same owning host', () => {
- const model = vi.spyOn(menuRows, 'useNewTabAgentMenuRows').mockReturnValueOnce({
- state: 'settled',
- rows: [{ kind: 'chat', agent: 'codex', executionHostId: 'runtime:server' }],
- detection: {
- detectedIds: ['codex'],
- detectionFailed: false,
- needsServerUpdate: false,
- isLoading: false,
- isRefreshing: false,
- refresh: async () => ['codex']
- }
- })
- launchMock.mockReset().mockReturnValue({ surface: { kind: 'host-published' } })
- const view = render()
- model.mockRestore()
-
- fireEvent.click(view.getByRole('button', { name: 'Launch Codex in a new terminal' }))
- fireEvent.click(view.getByRole('button', { name: 'Start a chat with Codex' }))
-
- expect(launchMock.mock.calls.map(([args]) => args)).toEqual([
- expect.objectContaining({
- requestedSurface: 'terminal',
- selectedExecutionHostId: 'runtime:server',
- worktreeId: WORKTREE_ID,
- groupId: 'group-1'
- }),
- expect.objectContaining({
- requestedSurface: 'chat',
- selectedExecutionHostId: 'runtime:server',
- worktreeId: WORKTREE_ID,
- groupId: 'group-1'
- })
- ])
- view.unmount()
-})
-
it('gives static/search no agent actions while loading, retaining settings and generic terminal', () => {
const model = vi
.spyOn(menuRows, 'useNewTabAgentMenuRows')
diff --git a/src/renderer/src/components/tab-group/TabGroupPanel.tsx b/src/renderer/src/components/tab-group/TabGroupPanel.tsx
index 1de05feda10..6e623c14482 100644
--- a/src/renderer/src/components/tab-group/TabGroupPanel.tsx
+++ b/src/renderer/src/components/tab-group/TabGroupPanel.tsx
@@ -3,7 +3,6 @@ import { lazyWithRetry as lazy } from '@/lib/lazy-with-retry'
import { useDroppable } from '@dnd-kit/core'
import { useAppStore } from '../../store'
import TabBar from '../tab-bar/TabBar'
-import { WorkspaceEmptyState } from '../WorkspaceEmptyState'
import { TabBarQuickCommandsButton } from '../tab-bar/TabBarQuickCommandsButton'
import { TabGroupPaneActionsMenu } from './TabGroupPaneActionsMenu'
@@ -330,12 +329,6 @@ export default function TabGroupPanel({
className="relative flex-1 min-h-0 overflow-hidden"
style={bodyAnchorStyle}
>
- {isVisible &&
- !activeTab &&
- model.groupTabs.length === 0 &&
- clientHostedRows.length === 0 ? (
-
- ) : null}
{/* Why: empty anchor so the agent-sessions tour reads as a terminal-area tip, not toolbar chrome. */}
{isFocused ? (
{
expect(store.getState().tabsByWorktree['wt-1'] ?? []).toEqual([])
})
- it('creates a terminal in the invoking group’s workspace when another workspace is selected', async () => {
- const store = createTestStore()
- seedActiveWorkspace(store)
- store.setState({ activeWorktreeId: 'another-workspace' })
-
- await store.getState().openNewTerminalTabInActiveWorkspace('group-1')
-
- expect(createWebRuntimeSessionTerminalMock).toHaveBeenCalledWith({
- worktreeId: 'wt-1',
- environmentId: 'runtime-1',
- targetGroupId: 'group-1',
- activate: true
- })
- expect(store.getState().tabsByWorktree['another-workspace'] ?? []).toEqual([])
- })
-
- it('creates a floating terminal locally while a paired workspace is selected', async () => {
- const store = createTestStore()
- seedActiveWorkspace(store)
- store.setState({
- groupsByWorktree: {
- ...store.getState().groupsByWorktree,
- [FLOATING_TERMINAL_WORKTREE_ID]: [
- {
- id: 'floating-group',
- worktreeId: FLOATING_TERMINAL_WORKTREE_ID,
- activeTabId: null,
- tabOrder: []
- }
- ]
- }
- })
-
- await store.getState().openNewTerminalTabInActiveWorkspace('floating-group')
-
- expect(createWebRuntimeSessionTerminalMock).not.toHaveBeenCalled()
- expect(store.getState().tabsByWorktree['wt-1'] ?? []).toEqual([])
- const tabs = store.getState().tabsByWorktree[FLOATING_TERMINAL_WORKTREE_ID] ?? []
- expect(tabs).toHaveLength(1)
- expect(store.getState().unifiedTabsByWorktree[FLOATING_TERMINAL_WORKTREE_ID]).toEqual([
- expect.objectContaining({ entityId: tabs[0].id, groupId: 'floating-group' })
- ])
- })
-
it('does not create a local folder terminal while paired ownership is unresolved', async () => {
const folderId = 'folder-1'
const workspaceKey = folderWorkspaceKey(folderId)
diff --git a/src/renderer/src/store/terminals/terminal-active-workspace-creation.ts b/src/renderer/src/store/terminals/terminal-active-workspace-creation.ts
index ffce04170b0..c1636f3cd70 100644
--- a/src/renderer/src/store/terminals/terminal-active-workspace-creation.ts
+++ b/src/renderer/src/store/terminals/terminal-active-workspace-creation.ts
@@ -4,7 +4,6 @@ import { focusTerminalTabSurface } from '@/lib/focus-terminal-tab-surface'
import { runtimeEnvironmentIdOrLocalUnlessTwin } from '@/lib/worktree-runtime-owner'
import { resolveWorktreeOperationRouteResult } from '@/lib/worktree-operation-route'
import { isWebClientLocation } from '@/lib/web-client-location'
-import { findGroupAndWorktree } from '../slices/tab-group-state'
import type { TerminalSlice, TerminalStoreGet, TerminalStoreSet } from './terminal-state'
export function createActiveWorkspaceTerminalActions(
@@ -14,8 +13,7 @@ export function createActiveWorkspaceTerminalActions(
return {
openNewTerminalTabInActiveWorkspace: async (groupId) => {
const state = get()
- const worktreeId =
- findGroupAndWorktree(state.groupsByWorktree, groupId)?.worktreeId ?? state.activeWorktreeId
+ const worktreeId = state.activeWorktreeId
if (!worktreeId) {
return
}