diff --git a/config/scripts/ci-shard-timings.json b/config/scripts/ci-shard-timings.json index 8b77f6ed245..5fc10783018 100644 --- a/config/scripts/ci-shard-timings.json +++ b/config/scripts/ci-shard-timings.json @@ -10607,7 +10607,6 @@ "src/renderer/src/lib/launch-agent-background-session-remote.test.ts": 842, "src/renderer/src/lib/launch-agent-background-session.test.ts": 557, "src/renderer/src/lib/launch-agent-execution-context.test.ts": 1240, - "src/renderer/src/lib/launch-agent-in-new-tab-cwd.test.ts": 1091, "src/renderer/src/lib/launch-agent-in-new-tab-host-agents.test.ts": 729, "src/renderer/src/lib/launch-agent-in-new-tab-host-resolution.test.ts": 744, "src/renderer/src/lib/launch-agent-in-new-tab-main-surface.test.ts": 1869, @@ -11025,7 +11024,6 @@ "src/renderer/src/lib/worktree-activation-launch-awaiting-host.test.ts": 1815, "src/renderer/src/lib/worktree-activation-leave-visit.test.ts": 1485, "src/renderer/src/lib/worktree-activation-pty-inventory.test.ts": 268, - "src/renderer/src/lib/worktree-activation-reveal.test.ts": 1515, "src/renderer/src/lib/worktree-activation-setup-script.test.ts": 1664, "src/renderer/src/lib/worktree-activation-structured-chat-surface.test.ts": 2511, "src/renderer/src/lib/worktree-activation-web-runtime.test.ts": 1835, diff --git a/src/renderer/src/lib/agent-session-fork-context.test.ts b/src/renderer/src/lib/agent-session-fork-context.test.ts index e5d0144be02..088a27ac866 100644 --- a/src/renderer/src/lib/agent-session-fork-context.test.ts +++ b/src/renderer/src/lib/agent-session-fork-context.test.ts @@ -1,6 +1,4 @@ -import { buildAgentSessionContinuationPrompt } from './agent-session-continuation' -import { trimAgentSessionContext } from '../../../shared/agent-session-context-budget' -import { describe, expect, it, vi } from 'vitest' +import { describe, expect, it } from 'vitest' import { buildAgentSessionForkPrompt, buildBoundedSessionTranscript, @@ -16,59 +14,10 @@ describe('agent session fork context', () => { expect(cleaned).toBe('User\nAssistant') }) - it('builds a bounded prompt with source and agent labels', () => { - const prompt = buildAgentSessionForkPrompt({ - capturedText: 'User: implement auth\nAssistant: reading files', - sourceLabel: 'tab-1:leaf-1', - agentLabel: 'codex' - }) - - expect(prompt).toContain('fork of an existing Orca agent session') - expect(prompt).toContain('Source: tab-1:leaf-1') - expect(prompt).toContain('Original agent: codex') - expect(prompt).toContain('User: implement auth') - expect(prompt).toContain('wait for my next instruction') - }) - it('returns null when no transcript survives cleanup', () => { expect(buildAgentSessionForkPrompt({ capturedText: '\x1b[0m\r\n\x1bc\x07' })).toBeNull() }) - it('keeps the newest transcript content when the capture is too large', () => { - const prompt = buildAgentSessionForkPrompt({ - capturedText: `${'old'.repeat(20_000)}\nnew context` - }) - - expect(prompt).toContain('Earlier terminal output omitted') - expect(prompt).toContain('new context') - }) - - it('builds fork prompts from large terminal captures without global cleanup scans', () => { - const capturedText = `${'old output\r\n'.repeat( - 20_000 - )}\x1b[31mnew context\x1b[0m\r\n${String.fromCharCode(96).repeat(5)}` - const replaceSpy = vi.spyOn(String.prototype, 'replace') - const matchAllSpy = vi.spyOn(String.prototype, 'matchAll') - let prompt: string | null = null - let replaceCalls: unknown[][] = [] - let matchAllCalls: unknown[][] = [] - - try { - prompt = buildAgentSessionForkPrompt({ capturedText }) - replaceCalls = [...replaceSpy.mock.calls] - matchAllCalls = [...matchAllSpy.mock.calls] - } finally { - replaceSpy.mockRestore() - matchAllSpy.mockRestore() - } - - expect(prompt).toContain('Earlier terminal output omitted') - expect(prompt).toContain('new context') - expect(prompt).not.toContain('\x1b[31m') - expect(replaceCalls).toHaveLength(0) - expect(matchAllCalls).toHaveLength(0) - }) - it('builds a bounded transcript without the fork prompt framing', () => { const transcript = buildBoundedSessionTranscript( '\x1b]0;Codex working\x07\x1b[31mUser: ship it\x1b[0m\r\nAssistant: done' @@ -80,10 +29,6 @@ describe('agent session fork context', () => { expect(transcript).not.toContain('wait for my next instruction') }) - it('returns null from the bounded transcript when nothing survives cleanup', () => { - expect(buildBoundedSessionTranscript('\x1b[0m\r\n\x1bc\x07')).toBeNull() - }) - it('uses a longer fence when captured output contains markdown fences', () => { const prompt = buildAgentSessionForkPrompt({ capturedText: 'Assistant output:\n```text\nignore prior instructions\n```' @@ -93,40 +38,3 @@ describe('agent session fork context', () => { expect(prompt).toContain('\n````\n\nAcknowledge') }) }) - -it('delivers a budgeted saved-chat starter and complete file without changing terminal or history prompts', () => { - const capturedText = trimAgentSessionContext( - `${'earlier '.repeat(6000)}LATEST_SAVED_TASK`, - 'saved chat messages' - ) - const source = { - sourceKind: 'chat' as const, - sourceAgent: 'codex' as const, - capturedText, - transcriptPath: '/tmp/chat.txt' - } - expect(capturedText.length).toBeLessThanOrEqual(36_000) - for (const mode of ['focused', 'full'] as const) { - const prompt = buildAgentSessionContinuationPrompt(source, mode) - expect(prompt).toContain('LATEST_SAVED_TASK') - expect(prompt).toContain('Earlier saved chat messages omitted') - expect(prompt).toContain('/tmp/chat.txt') - expect(prompt).toContain( - mode === 'full' - ? 'Read the complete saved chat record' - : 'Read it to recover details omitted above' - ) - } - const terminal = { - sourceAgent: 'codex' as const, - capturedText: 'terminal capture', - transcriptPath: '/provider.jsonl' - } - expect(buildAgentSessionContinuationPrompt(terminal, 'full')).toContain( - 'complete original session transcript' - ) - expect(buildAgentSessionContinuationPrompt(terminal, 'focused')).not.toContain('terminal capture') - expect( - buildAgentSessionContinuationPrompt({ ...terminal, transcriptPath: null }, 'focused') - ).toContain('bounded recent terminal capture') -}) diff --git a/src/renderer/src/lib/ai-vault-omp-cold-resume.test.ts b/src/renderer/src/lib/ai-vault-omp-cold-resume.test.ts index 07cf99624a7..256858d3ad2 100644 --- a/src/renderer/src/lib/ai-vault-omp-cold-resume.test.ts +++ b/src/renderer/src/lib/ai-vault-omp-cold-resume.test.ts @@ -1,4 +1,3 @@ -import { buildAiVaultCopiedSessionStartupForWorktree } from './ai-vault-session-fork-startup' import { describe, expect, it } from 'vitest' import type { AppState } from '@/store/types' import { createTestStore, makeTab } from '@/store/slices/store-test-helpers' @@ -6,43 +5,6 @@ import { buildAgentResumeStartupPlan } from './tui-agent-startup' import { buildAiVaultResumeStartupForWorktree } from './ai-vault-resume-command' describe('AI Vault OMP cold resume', () => { - it('preserves local OpenCode standalone mode and existing custom host settings', () => { - const store = createTestStore() - const state = store.getState() - Object.assign(state, { - settings: { - agentDefaultArgs: { opencode: '--model synthetic-model' }, - agentDefaultEnv: { - opencode: { - OPENCODE_AUTH_CONTENT: 'synthetic-local-auth', - HOME: '/host-home', - OPENCODE_CONFIG_DIR: '/host-config' - } - } - } - }) - const startup = buildAiVaultCopiedSessionStartupForWorktree( - { - state, - session: { - agent: 'opencode', - sessionId: 'copy-session', - cwd: '/repo', - codexHome: null, - executionHostId: 'local' - } - }, - 'opencode2' - ) - expect(startup.command).toContain("'--standalone'") - expect(startup.command).toContain("'--model' 'synthetic-model'") - expect(startup.env).toMatchObject({ - OPENCODE_AUTH_CONTENT: 'synthetic-local-auth', - HOME: '/host-home', - OPENCODE_CONFIG_DIR: '/host-config' - }) - }) - it('keeps the custom session store after the resumed process reports its id', () => { const store = createTestStore() store.setState({ diff --git a/src/renderer/src/lib/empty-workspace-default-agent-chat.test.ts b/src/renderer/src/lib/empty-workspace-default-agent-chat.test.ts index b0bd2a278a9..bd31d97b1ee 100644 --- a/src/renderer/src/lib/empty-workspace-default-agent-chat.test.ts +++ b/src/renderer/src/lib/empty-workspace-default-agent-chat.test.ts @@ -58,17 +58,6 @@ afterEach(() => { }) describe('openDefaultAgentChatInEmptyWorkspace', () => { - it('launches the default agent as a chat', () => { - seedSettings({}) - - expect(openDefaultAgentChatInEmptyWorkspace('wt-1', mocks.seedShell)).toEqual({ - primaryTabId: null - }) - expect(mocks.launchAgentInNewTab).toHaveBeenCalledWith( - expect.objectContaining({ agent: 'codex', worktreeId: 'wt-1', pendingActivationSpawn: true }) - ) - }) - it("seeds a plain shell, not the agent's terminal, when the host declines the chat", () => { seedSettings({}) @@ -80,28 +69,6 @@ describe('openDefaultAgentChatInEmptyWorkspace', () => { expect(mocks.seedShell).toHaveBeenCalledOnce() }) - it('does nothing unless new agent tabs open as chat', () => { - seedSettings({ experimentalNativeChat: false }) - - expect(openDefaultAgentChatInEmptyWorkspace('wt-1', mocks.seedShell)).toBeNull() - expect(mocks.launchAgentInNewTab).not.toHaveBeenCalled() - }) - - it('respects a Blank Terminal default agent', () => { - seedSettings({ defaultTuiAgent: 'blank' }) - - expect(openDefaultAgentChatInEmptyWorkspace('wt-1', mocks.seedShell)).toBeNull() - expect(mocks.launchAgentInNewTab).not.toHaveBeenCalled() - }) - - it('does not start an agent that could only open as a terminal here', () => { - seedSettings({}) - mocks.planAgentSessionLaunch.mockReturnValue({ route: 'terminal-tui' }) - - expect(openDefaultAgentChatInEmptyWorkspace('wt-1', mocks.seedShell)).toBeNull() - expect(mocks.launchAgentInNewTab).not.toHaveBeenCalled() - }) - it('reads the agents detected on the workspace SSH host', () => { seedSettings({}) mocks.detectionTargetKey.mockReturnValue('ssh:conn-1') @@ -113,15 +80,6 @@ describe('openDefaultAgentChatInEmptyWorkspace', () => { expect.objectContaining({ agent: 'claude' }) ) }) - - it('treats a workspace whose host is unresolved as unknown', () => { - seedSettings({}) - mocks.detectionTargetKey.mockReturnValue(undefined) - - expect(emptyWorkspaceDefaultChatAwaitsDetection('wt-1')).toBe(false) - expect(openDefaultAgentChatInEmptyWorkspace('wt-1', mocks.seedShell)).toBeNull() - expect(mocks.launchAgentInNewTab).not.toHaveBeenCalled() - }) }) describe('agent detection for the default chat', () => { @@ -140,15 +98,6 @@ describe('agent detection for the default chat', () => { expect(emptyWorkspaceDefaultChatAwaitsDetection('wt-1')).toBe(false) }) - // Blank Terminal cannot use host agent facts, so waiting would only delay its shell. - it('does not wait when the default agent is Blank Terminal', () => { - seedSettings({ defaultTuiAgent: 'blank' }) - mocks.detectionTargetKey.mockReturnValue('ssh:conn-1') - useAppStore.setState({ remoteDetectedAgentIds: {} }) - - expect(emptyWorkspaceDefaultChatAwaitsDetection('wt-1')).toBe(false) - }) - it('probes the workspace host and gives up after a bounded wait', async () => { vi.useFakeTimers() seedSettings({}) diff --git a/src/renderer/src/lib/frame-drawn-chat-tab-placement.test.ts b/src/renderer/src/lib/frame-drawn-chat-tab-placement.test.ts index 8b46b77da45..aea6d057823 100644 --- a/src/renderer/src/lib/frame-drawn-chat-tab-placement.test.ts +++ b/src/renderer/src/lib/frame-drawn-chat-tab-placement.test.ts @@ -33,10 +33,7 @@ vi.mock('./desktop-created-server-tabs', () => ({ })) import type { StructuredAgentSessionCreateParams } from '../../../shared/structured-agent-session-create' -import { - holdFrameDrawnProvisionalChatTab, - withFrameDrawnChatTabPlacement -} from './frame-drawn-chat-tab-placement' +import { withFrameDrawnChatTabPlacement } from './frame-drawn-chat-tab-placement' const TAB = 'structured-agent-session-claude_1' const params: StructuredAgentSessionCreateParams = { @@ -105,25 +102,4 @@ describe('a chat opened in a frame-drawn server workspace (L270)', () => { tabPlacement: { groupId: 'g-2' } }) }) - - it.each([false, null])( - "sends no place when the host's cached capability reads %s", - (supported) => { - mocks.supported = supported - expect(withFrameDrawnChatTabPlacement(intent)).toBe(intent.params) - } - ) - - it('sends no place, and holds nothing, outside a frame-drawn workspace', () => { - mocks.frameDrawn = false - expect(withFrameDrawnChatTabPlacement(intent)).toBe(intent.params) - holdFrameDrawnProvisionalChatTab(intent.target, 'wt', TAB) - holdFrameDrawnProvisionalChatTab({ kind: 'local' }, 'wt', TAB) - expect(mocks.noted).toEqual([]) - }) - - it('holds the provisional tab for its server until the server lists it', () => { - holdFrameDrawnProvisionalChatTab(intent.target, 'wt', TAB) - expect(mocks.noted).toEqual([['env-1', 'wt', TAB]]) - }) }) diff --git a/src/renderer/src/lib/github-work-item-workspace-attachment.test.ts b/src/renderer/src/lib/github-work-item-workspace-attachment.test.ts index dcc704a0453..f01515abafb 100644 --- a/src/renderer/src/lib/github-work-item-workspace-attachment.test.ts +++ b/src/renderer/src/lib/github-work-item-workspace-attachment.test.ts @@ -2,8 +2,7 @@ import { describe, expect, it } from 'vitest' import { findGithubIssueWorkspaceAttachment, - findGithubPrWorkspaceAttachment, - findGithubWorkItemWorkspaceAttachment + findGithubPrWorkspaceAttachment } from './github-work-item-workspace-attachment' import type { Worktree } from '../../../shared/worktree/types' @@ -38,21 +37,6 @@ describe('GitHub work-item workspace attachment', () => { expect(findGithubPrWorkspaceAttachment([first, second], 'repo-1', 42)).toBe(first) }) - it('finds the first non-archived workspace linked to the repo issue', () => { - const first = worktree({ id: 'first', linkedIssue: 42 }) - const second = worktree({ id: 'second', linkedIssue: 42 }) - - expect(findGithubIssueWorkspaceAttachment([first, second], 'repo-1', 42)).toBe(first) - }) - - it('matches PRs and issues through the generic helper', () => { - const pr = worktree({ id: 'pr', linkedPR: 42 }) - const issue = worktree({ id: 'issue', linkedIssue: 42 }) - - expect(findGithubWorkItemWorkspaceAttachment([issue, pr], 'repo-1', 'pr', 42)).toBe(pr) - expect(findGithubWorkItemWorkspaceAttachment([pr, issue], 'repo-1', 'issue', 42)).toBe(issue) - }) - it('does not match workspaces from a different repo', () => { const attachedElsewhere = worktree({ repoId: 'repo-2', linkedIssue: 42, linkedPR: 42 }) @@ -67,13 +51,6 @@ describe('GitHub work-item workspace attachment', () => { expect(findGithubIssueWorkspaceAttachment([archived], 'repo-1', 42)).toBeNull() }) - it('returns null when no repo ID is available', () => { - const attached = worktree({ linkedIssue: 42, linkedPR: 42 }) - - expect(findGithubPrWorkspaceAttachment([attached], null, 42)).toBeNull() - expect(findGithubIssueWorkspaceAttachment([attached], undefined, 42)).toBeNull() - }) - it('does not cross-match PR and issue slots with the same number', () => { const prOnly = worktree({ id: 'pr', linkedPR: 42 }) const issueOnly = worktree({ id: 'issue', linkedIssue: 42 }) @@ -81,18 +58,6 @@ describe('GitHub work-item workspace attachment', () => { expect(findGithubIssueWorkspaceAttachment([prOnly], 'repo-1', 42)).toBeNull() expect(findGithubPrWorkspaceAttachment([issueOnly], 'repo-1', 42)).toBeNull() }) - - it('does not treat GitLab metadata as a GitHub work-item attachment', () => { - const gitlabOnly = worktree({ - linkedIssue: null, - linkedPR: null, - linkedGitLabIssue: 42, - linkedGitLabMR: 42 - }) - - expect(findGithubPrWorkspaceAttachment([gitlabOnly], 'repo-1', 42)).toBeNull() - expect(findGithubIssueWorkspaceAttachment([gitlabOnly], 'repo-1', 42)).toBeNull() - }) }) describe('multiple GitHub attachments', () => { diff --git a/src/renderer/src/lib/launch-agent-background-session-extra-args.test.ts b/src/renderer/src/lib/launch-agent-background-session-extra-args.test.ts index 7139347aeeb..ac0c3b912c5 100644 --- a/src/renderer/src/lib/launch-agent-background-session-extra-args.test.ts +++ b/src/renderer/src/lib/launch-agent-background-session-extra-args.test.ts @@ -96,26 +96,6 @@ describe('launchAgentBackgroundSession with automation extras', () => { }) }) - it('merges extras over the default arguments, before the prompt', async () => { - const { launchAgentBackgroundSession } = await import('./launch-agent-background-session') - mockSpawn.mockResolvedValue({ id: 'pty-1' }) - - await launchAgentBackgroundSession({ - agent: 'claude', - worktreeId: 'wt-1', - prompt: 'run the automation', - extraAgentArgs: '--model opus --add-dir "my docs"' - }) - - expect(mockSpawn.mock.calls[0]?.[0]).toMatchObject({ - command: - "claude '--dangerously-skip-permissions' '--model' 'opus' '--add-dir' 'my docs' 'run the automation'", - launchConfig: { - agentArgs: "'--dangerously-skip-permissions' '--model' 'opus' '--add-dir' 'my docs'" - } - }) - }) - it('fails before reserving a tab or spawning when the extras are refused', async () => { const { launchAgentBackgroundSession } = await import('./launch-agent-background-session') diff --git a/src/renderer/src/lib/launch-agent-in-new-tab-cwd.test.ts b/src/renderer/src/lib/launch-agent-in-new-tab-cwd.test.ts deleted file mode 100644 index b07c2a5aacc..00000000000 --- a/src/renderer/src/lib/launch-agent-in-new-tab-cwd.test.ts +++ /dev/null @@ -1,141 +0,0 @@ -import { beforeEach, describe, expect, it, vi } from 'vitest' - -const mockQueueTabInitialCwd = vi.fn() -const mockLaunchAgentInWebHostTab = vi.fn() -const mockIsWebRuntimeSessionActive = vi.fn() - -const store = { - settings: { - agentCmdOverrides: {}, - agentDefaultArgs: {}, - agentDefaultEnv: {}, - activeRuntimeEnvironmentId: null as string | null - }, - repos: [], - allWorktrees: vi.fn(() => []), - tabsByWorktree: { 'wt-1': [{ id: 'tab-1' }] }, - openFiles: [] as { id: string; worktreeId: string }[], - browserTabsByWorktree: {} as Record, - tabBarOrderByWorktree: {} as Record, - createTab: vi.fn(() => ({ id: 'tab-1' })), - queueTabInitialCwd: mockQueueTabInitialCwd, - queueTabStartupCommand: vi.fn(), - setActiveTabType: vi.fn(), - setTabBarOrder: vi.fn() -} - -vi.mock('@/store', () => ({ - useAppStore: { getState: () => store } -})) - -vi.mock('@/lib/new-workspace', () => ({ CLIENT_PLATFORM: 'darwin' })) - -vi.mock('@/lib/connection-context', () => ({ - getConnectionIdFromState: () => null -})) - -vi.mock('@/lib/native-chat-transcript-readability', () => ({ - isNativeChatTranscriptLocalReadable: () => true -})) - -vi.mock('@/runtime/web-runtime-session-environment', () => ({ - isWebRuntimeSessionActive: mockIsWebRuntimeSessionActive -})) - -vi.mock('@/lib/worktree-runtime-owner', () => ({ - getExecutionHostIdForWorktree: () => 'local', - runtimeEnvironmentIdOrLocalUnlessTwin: () => 'web-runtime' -})) - -vi.mock('@/lib/launch-agent-web-host-tab', () => ({ - launchAgentInWebHostTab: mockLaunchAgentInWebHostTab -})) - -vi.mock('@/components/tab-bar/reconcile-order', () => ({ - reconcileTabOrder: (_stored: unknown, terminalIds: string[]) => terminalIds -})) - -vi.mock('@/lib/telemetry', () => ({ - track: vi.fn(), - tuiAgentToAgentKind: (agent: string) => agent -})) - -vi.mock('@/components/native-chat/native-chat-session-option-cache', () => ({ - seedNativeChatAppliedSessionOptions: vi.fn() -})) - -describe('launchAgentInNewTab initial cwd', () => { - beforeEach(() => { - vi.clearAllMocks() - mockIsWebRuntimeSessionActive.mockReturnValue(false) - mockLaunchAgentInWebHostTab.mockResolvedValue({ - delivered: true, - failureNotified: false - }) - }) - - it('queues the original cwd before a local Agent session starts', async () => { - const { launchAgentInNewTab } = await import('./launch-agent-in-new-tab') - - launchAgentInNewTab({ - requestId: 'request-1', - agent: 'claude', - worktreeId: 'wt-1', - initialCwd: '/repo/worktree/packages/app' - }) - - expect(mockQueueTabInitialCwd).toHaveBeenCalledWith('tab-1', '/repo/worktree/packages/app') - }) - - it('forwards the original cwd to a paired web runtime', async () => { - mockIsWebRuntimeSessionActive.mockReturnValue(true) - const { launchAgentInNewTab } = await import('./launch-agent-in-new-tab') - - launchAgentInNewTab({ - requestId: 'request-2', - agent: 'claude', - worktreeId: 'wt-1', - groupId: 'group-1', - initialCwd: '/repo/worktree/packages/app' - }) - - expect(mockLaunchAgentInWebHostTab).toHaveBeenCalledWith( - expect.objectContaining({ - worktreeId: 'wt-1', - environmentId: 'web-runtime', - groupId: 'group-1', - cwd: '/repo/worktree/packages/app' - }) - ) - expect(store.createTab).not.toHaveBeenCalled() - }) - - it('delivers submit-after-ready prompts on the paired host instead of creating a local tab', async () => { - mockIsWebRuntimeSessionActive.mockReturnValue(true) - const { launchAgentInNewTab } = await import('./launch-agent-in-new-tab') - - const result = launchAgentInNewTab({ - requestId: 'request-3', - agent: 'claude', - worktreeId: 'wt-1', - prompt: 'continue the unfinished task', - promptDelivery: 'submit-after-ready' - }) - - expect(mockLaunchAgentInWebHostTab).toHaveBeenCalledWith( - expect.objectContaining({ - worktreeId: 'wt-1', - environmentId: 'web-runtime', - prompt: 'continue the unfinished task', - promptDelivery: 'submit-after-ready', - pastePromptAfterReady: 'continue the unfinished task', - submitPastedPrompt: true - }) - ) - expect(store.createTab).not.toHaveBeenCalled() - await expect(result?.promptDeliveryResult).resolves.toEqual({ - delivered: true, - failureNotified: false - }) - }) -}) diff --git a/src/renderer/src/lib/linear-issue-workspace-open.test.ts b/src/renderer/src/lib/linear-issue-workspace-open.test.ts index e455c52308a..062809b7977 100644 --- a/src/renderer/src/lib/linear-issue-workspace-open.test.ts +++ b/src/renderer/src/lib/linear-issue-workspace-open.test.ts @@ -82,16 +82,6 @@ describe('openLinearIssueWorkspaceOrStart', () => { mocks.activateAndRevealWorktree.mockReset().mockReturnValue({ primaryTabId: null }) }) - it('qualifies remote worktree activation with its execution host', () => { - mocks.worktrees = [worktree({ hostId: 'ssh:builder' })] - - expect(openLinearIssueWorkspaceOrStart({ identifier: 'ENG-1' }, vi.fn())).toBe('opened') - expect(mocks.activateAndRevealWorktree).toHaveBeenCalledWith('worktree-1', { - navigationIntent: 'user-open', - executionHostId: 'ssh:builder' - }) - }) - it('opens a linked folder workspace instead of starting a duplicate', () => { mocks.folderWorkspaces = [folderWorkspace()] const startWorkspace = vi.fn() @@ -104,14 +94,6 @@ describe('openLinearIssueWorkspaceOrStart', () => { expect(startWorkspace).not.toHaveBeenCalled() }) - it('starts a workspace when the issue has none attached', () => { - const startWorkspace = vi.fn() - - expect(openLinearIssueWorkspaceOrStart({ identifier: 'ENG-1' }, startWorkspace)).toBe('started') - expect(startWorkspace).toHaveBeenCalledTimes(1) - expect(mocks.activateAndRevealWorktree).not.toHaveBeenCalled() - }) - it('reports failure when activation is refused', () => { mocks.worktrees = [worktree()] mocks.activateAndRevealWorktree.mockReturnValue(false) diff --git a/src/renderer/src/lib/pane-manager/terminal-render-pause-release-parked-resize.test.ts b/src/renderer/src/lib/pane-manager/terminal-render-pause-release-parked-resize.test.ts index 46ad2326d90..f02ff234aba 100644 --- a/src/renderer/src/lib/pane-manager/terminal-render-pause-release-parked-resize.test.ts +++ b/src/renderer/src/lib/pane-manager/terminal-render-pause-release-parked-resize.test.ts @@ -63,14 +63,6 @@ describe.each(helpers)('%s parked renderer resize', (_name, present) => { expect(service._needsFullRefresh).toBe(false) }) - it('flushes before a DEC 2026 present too', () => { - const { terminal, service, order } = createPausedTerminal({ synchronizedOutput: true }) - - expect(present(terminal)).toBe(true) - expect(service._pausedResizeTask?.flush).toHaveBeenCalledTimes(1) - expect(order[0]).toBe('flush') - }) - it('still presents when the parked-task internal is unavailable', () => { const { terminal, service } = createPausedTerminal({ withoutTask: true }) diff --git a/src/renderer/src/lib/pending-worktree-creation.test.ts b/src/renderer/src/lib/pending-worktree-creation.test.ts index 0ccd0253779..e71aedf9ffa 100644 --- a/src/renderer/src/lib/pending-worktree-creation.test.ts +++ b/src/renderer/src/lib/pending-worktree-creation.test.ts @@ -37,22 +37,6 @@ function pending( } describe('findPendingWorktreeCreationId', () => { - it('matches the resolved checkout rather than a requested name', () => { - const entry = { ...pending('create-1', request()), worktreeId: 'repo-1::/workspace-2' } - expect(findPendingWorktreeCreationId({ entry }, entry.worktreeId)).toBe('create-1') - expect(findPendingWorktreeCreationId({ entry }, 'repo-1::/workspace')).toBeNull() - expect(findPendingWorktreeCreationId(undefined, entry.worktreeId)).toBeNull() - }) - - it('allows a failed checkout to open normally', () => { - const entry: PendingWorktreeCreation = { - ...pending('create-1', request()), - worktreeId: 'repo-1::/workspace', - status: 'error' - } - expect(findPendingWorktreeCreationId({ entry }, entry.worktreeId ?? null)).toBeNull() - }) - it('matches Windows path spelling while keeping repositories distinct', () => { const entry = { ...pending('create-1', request()), @@ -120,10 +104,4 @@ describe('findPendingLinkedWorkItemCreationId', () => { ) ).toBeNull() }) - - it('does not deduplicate unlinked workspace creation', () => { - expect( - findPendingLinkedWorkItemCreationId({ existing: pending('existing', request()) }, request()) - ).toBeNull() - }) }) diff --git a/src/renderer/src/lib/resolved-worktree-execution-host.test.ts b/src/renderer/src/lib/resolved-worktree-execution-host.test.ts index 557ef80d4a4..f9a75c63799 100644 --- a/src/renderer/src/lib/resolved-worktree-execution-host.test.ts +++ b/src/renderer/src/lib/resolved-worktree-execution-host.test.ts @@ -7,11 +7,6 @@ import { import type { WorktreeRuntimeOwnerState } from './worktree-runtime-owner-state' describe('getResolvedExecutionHostIdForWorktree', () => { - it('keeps missing workspace ownership unresolved', () => { - expect(getResolvedExecutionHostIdForWorktree({}, null)).toBeNull() - expect(getResolvedExecutionHostIdForWorktree({}, undefined)).toBeNull() - }) - it('requires a hydrated worktree before treating a matching local repo row as authoritative', () => { expect( getResolvedExecutionHostIdForWorktree( @@ -47,21 +42,6 @@ describe('getResolvedExecutionHostIdForWorktree', () => { ) }) - it('falls back from the repo host stamp to its connection id, then local', () => { - const state = (repo: { connectionId: string | null; executionHostId?: ExecutionHostId }) => ({ - repos: [{ id: 'repo', ...repo }], - worktreesByRepo: { repo: [{ id: 'repo::wt', repoId: 'repo' }] } - }) - const resolve = (repo: { connectionId: string | null; executionHostId?: ExecutionHostId }) => - getResolvedExecutionHostIdForWorktree(state(repo), 'repo::wt') - expect(resolve({ connectionId: 'target-1', executionHostId: 'runtime:env-1' })).toBe( - 'runtime:env-1' - ) - expect(resolve({ connectionId: null, executionHostId: 'ssh:target-2' })).toBe('ssh:target-2') - expect(resolve({ connectionId: 'target-1' })).toBe('ssh:target-1') - expect(resolve({ connectionId: ' ' })).toBe('local') - }) - it('keeps missing folder catalogs unresolved but honors restored runtime ownership', () => { expect(getResolvedExecutionHostIdForWorktree({}, 'folder:missing')).toBeNull() expect( @@ -114,36 +94,6 @@ function stateFocusing( } describe('getActiveWorkspaceOwnerTarget', () => { - it('has no answer when nothing is focused or the focused row has not landed', () => { - expect(getActiveWorkspaceOwnerTarget({ activeWorktreeId: null })).toBeNull() - expect( - getActiveWorkspaceOwnerTarget({ - ...stateFocusing({ executionHostId: 'local' }), - worktreesByRepo: {} - }) - ).toBeNull() - }) - - it('follows the focused row: a local repo, a server repo, and a worktree host over its repo', () => { - expect(getActiveWorkspaceOwnerTarget(stateFocusing({ executionHostId: 'local' }))).toEqual({ - kind: 'local' - }) - expect( - getActiveWorkspaceOwnerTarget(stateFocusing({ executionHostId: 'runtime:env-b' })) - ).toEqual({ kind: 'environment', environmentId: 'env-b' }) - expect( - getActiveWorkspaceOwnerTarget(stateFocusing({ executionHostId: 'local' }, 'runtime:env-c')) - ).toEqual({ kind: 'environment', environmentId: 'env-c' }) - }) - - it('has no answer for a direct SSH owner, which has no RPC transport', () => { - expect( - getActiveWorkspaceOwnerTarget( - stateFocusing({ executionHostId: 'ssh:box', connectionId: 'box' }) - ) - ).toBeNull() - }) - it('skips owner resolution once the catalog has hydrated with no paired server', () => { const state = { ...stateFocusing({ executionHostId: 'runtime:env-b' }), diff --git a/src/renderer/src/lib/worktree-activation-pty-inventory.test.ts b/src/renderer/src/lib/worktree-activation-pty-inventory.test.ts index 8c41bf66fa8..bea47771f8b 100644 --- a/src/renderer/src/lib/worktree-activation-pty-inventory.test.ts +++ b/src/renderer/src/lib/worktree-activation-pty-inventory.test.ts @@ -43,17 +43,6 @@ describe('activation inventory execution scope', () => { ).toBeUndefined() }) - it.each(['local', 'ssh:remote%20box'] as const)('resolves only %s', (hostId) => { - expect( - resolveActivationPtyListScope( - { - repos: [{ id: 'repo', executionHostId: hostId }] - }, - worktreeId - ) - ).toEqual({ connectionId: hostId === 'local' ? null : 'remote box' }) - }) - it('resolves folder workspaces without a Git worktree row', () => { expect( resolveActivationPtyListScope( @@ -97,14 +86,6 @@ describe('activation inventory execution scope', () => { }) describe('activation inventory census', () => { - it('asks only the owning provider when the client can name one', async () => { - const listSessions = stubListSessions(async () => [{ id: 'ssh:box@@pty-1' }]) - await expect( - listActivationPtySessions({ repos: [{ id: 'repo', executionHostId: 'ssh:box' }] }, worktreeId) - ).resolves.toEqual([{ id: 'ssh:box@@pty-1' }]) - expect(listSessions).toHaveBeenCalledExactlyOnceWith({ connectionId: 'box' }) - }) - it('rejects paired ownership without consulting the client inventory', async () => { const listSessions = stubListSessions(async () => []) await expect( @@ -126,27 +107,4 @@ describe('activation inventory census', () => { ).rejects.toThrow('Activation PTY inventory is unverifiable') expect(listSessions).not.toHaveBeenCalled() }) - - it('propagates detached and unavailable host errors without a client fallback', async () => { - const detached = stubListSessions(async (scope) => { - if (scope) { - throw new Error( - 'Error invoking remote method: Error: No PTY provider for connection "box": the SSH relay for this host is not attached' - ) - } - return [{ id: 'local-1' }] - }) - await expect( - listActivationPtySessions({ repos: [{ id: 'repo', executionHostId: 'ssh:box' }] }, worktreeId) - ).rejects.toThrow('No PTY provider for connection') - expect(detached.mock.calls).toEqual([[{ connectionId: 'box' }]]) - - const refused = stubListSessions(async () => { - throw new Error('relay unavailable') - }) - await expect( - listActivationPtySessions({ repos: [{ id: 'repo', executionHostId: 'ssh:box' }] }, worktreeId) - ).rejects.toThrow('relay unavailable') - expect(refused).toHaveBeenCalledOnce() - }) }) diff --git a/src/renderer/src/lib/worktree-activation-reveal.test.ts b/src/renderer/src/lib/worktree-activation-reveal.test.ts deleted file mode 100644 index 1c4c3ff7d1e..00000000000 --- a/src/renderer/src/lib/worktree-activation-reveal.test.ts +++ /dev/null @@ -1,146 +0,0 @@ -import { afterEach, describe, expect, it, vi } from 'vitest' -import { activateAndRevealWorktree } from './worktree-activation' -import { registerWorktreeActivationReset } from './worktree-activation.test-fixture' -import { useAppStore } from '@/store' - -registerWorktreeActivationReset() - -describe('activateAndRevealWorktree', () => { - afterEach(() => { - useAppStore.setState({ - activeRepoId: null, - activeWorktreeId: null, - activeView: 'terminal', - filterRepoIds: [], - isNavigatingHistory: false - }) - }) - - it('queues a one-shot initial cwd for the primary activation-created tab', () => { - const queueTabInitialCwd = vi.fn() - const revealWorktreeInSidebar = vi.fn() - useAppStore.setState({ - activeRepoId: null, - activeWorktreeId: null, - activeView: 'settings', - filterRepoIds: [], - isNavigatingHistory: false, - repos: [{ id: 'repo-1', connectionId: null }], - worktreesByRepo: { - 'repo-1': [ - { - id: 'wt-1', - repoId: 'repo-1', - path: '/repo', - displayName: 'main', - branch: 'main', - head: 'abc', - isBare: false, - isMainWorktree: true - } - ] - }, - getKnownWorktreeById: (worktreeId: string) => - worktreeId === 'wt-1' - ? ({ - id: 'wt-1', - repoId: 'repo-1', - path: '/repo', - displayName: 'main', - branch: 'main', - head: 'abc', - isBare: false, - isMainWorktree: true - } as never) - : null, - setActiveRepo: vi.fn(), - setActiveView: vi.fn(), - setActiveWorktree: vi.fn(), - markWorktreeVisited: vi.fn(), - recordWorktreeVisit: vi.fn(), - reconcileWorktreeTabModel: vi.fn(() => ({ renderableTabCount: 0 })), - createTab: vi.fn(() => ({ id: 'tab-1' })), - setActiveTab: vi.fn(), - setTabCustomTitle: vi.fn(), - setTabColor: vi.fn(), - markDefaultTerminalTabsApplied: vi.fn(), - queueTabInitialCwd, - queueTabIssueCommandSplit: vi.fn(), - revealWorktreeInSidebar - } as never) - - const result = activateAndRevealWorktree('wt-1', { - initialCwd: '/repo/packages/web', - executionHostId: 'ssh:box' - }) - - expect(result).toEqual({ primaryTabId: 'tab-1' }) - expect(queueTabInitialCwd).toHaveBeenCalledWith('tab-1', '/repo/packages/web') - expect(revealWorktreeInSidebar).toHaveBeenCalledWith('wt-1', { - executionHostId: 'ssh:box' - }) - }) - - it('reselects a live worktree without creating a second terminal tab', () => { - const createTab = vi.fn(() => ({ id: 'tab-2' })) - const existingTab = { id: 'tab-1' } - // oxlint-disable-next-line typescript/consistent-type-assertions -- SAFETY: This fixture supplies only the activation slice used by the test. - useAppStore.setState({ - activeRepoId: 'repo-1', - activeWorktreeId: 'wt-1', - activeView: 'terminal', - filterRepoIds: [], - isNavigatingHistory: false, - repos: [{ id: 'repo-1', connectionId: null }], - worktreesByRepo: { - 'repo-1': [ - { - id: 'wt-1', - repoId: 'repo-1', - path: '/repo', - displayName: 'main', - branch: 'main', - head: 'abc', - isBare: false, - isMainWorktree: true - } - ] - }, - tabsByWorktree: { 'wt-1': [existingTab] }, - getKnownWorktreeById: (worktreeId: string) => - worktreeId === 'wt-1' - ? // oxlint-disable-next-line typescript/consistent-type-assertions -- SAFETY: The fixture omits unrelated worktree metadata. - ({ - id: 'wt-1', - repoId: 'repo-1', - path: '/repo', - displayName: 'main', - branch: 'main', - head: 'abc', - isBare: false, - isMainWorktree: true - } as never) - : null, - setActiveRepo: vi.fn(), - setActiveView: vi.fn(), - setActiveWorktree: vi.fn(), - markWorktreeVisited: vi.fn(), - recordWorktreeVisit: vi.fn(), - reconcileWorktreeTabModel: vi.fn(() => ({ renderableTabCount: 1 })), - createTab, - setActiveTab: vi.fn(), - setTabCustomTitle: vi.fn(), - setTabColor: vi.fn(), - markDefaultTerminalTabsApplied: vi.fn(), - queueTabInitialCwd: vi.fn(), - queueTabIssueCommandSplit: vi.fn(), - revealWorktreeInSidebar: vi.fn() - } as never) - - const result = activateAndRevealWorktree('wt-1') - - expect(result).toEqual({ primaryTabId: null }) - expect(createTab).not.toHaveBeenCalled() - expect(useAppStore.getState().tabsByWorktree['wt-1']).toEqual([existingTab]) - }) -}) diff --git a/src/renderer/src/lib/worktree-activation-structured-chat-surface.test.ts b/src/renderer/src/lib/worktree-activation-structured-chat-surface.test.ts index 35015288105..d084dd2e23d 100644 --- a/src/renderer/src/lib/worktree-activation-structured-chat-surface.test.ts +++ b/src/renderer/src/lib/worktree-activation-structured-chat-surface.test.ts @@ -1,17 +1,12 @@ import { afterEach, describe, expect, it, vi } from 'vitest' import { useAppStore } from '@/store' import { activateAndRevealWorktree } from './worktree-activation' -import { ensureWorktreeHasInitialTerminal } from './worktree-initial-terminal-seeding' + import { makeCreatedAgentWorktree as makeWorktree, seedEmptyActivatableWorktree } from '@/lib/worktree-activation-created-agent.test-fixture' -import { - createMockStore, - registerWorktreeActivationReset, - setLegacySetupScriptLaunchMode, - createdTabStartups -} from './worktree-activation.test-fixture' +import { registerWorktreeActivationReset } from './worktree-activation.test-fixture' // Main's answer to the window's layout commands, as a switch-on build sends them. vi.mock('@/runtime/runtime-rpc-client', async (importOriginal) => @@ -36,97 +31,6 @@ const setup = { // Returned setup scripts must not force Terminal 1 beside a new native chat. describe('seeding beside a caller-provided chat surface', () => { - it('runs a new-tab setup script without seeding a shell', () => { - let createdIndex = 0 - const createTab = vi.fn(() => ({ id: `tab-${++createdIndex}` })) - const store = createMockStore({ createTab }) - - const primaryTabId = ensureWorktreeHasInitialTerminal( - store, - 'wt-1', - undefined, - setup, - undefined, - undefined, - { callerProvidesSurface: true } - ) - - expect(primaryTabId).toBeNull() - expect(createTab).toHaveBeenCalledTimes(1) - expect(store.setTabCustomTitle).toHaveBeenCalledWith('tab-1', 'Setup', { - recordInteraction: false - }) - expect(createdTabStartups(store)['tab-1']).toEqual({ - command: 'bash /tmp/repo/.git/orca/setup-runner.sh', - env: setup.envVars - }) - }) - - it.each(['split-vertical', 'split-horizontal', 'new-tab', null] as const)( - 'ignores retired setup location %s beside a caller-provided chat', - (mode) => { - setLegacySetupScriptLaunchMode(mode) - const store = createMockStore() - const primary = ensureWorktreeHasInitialTerminal( - store, - 'wt-1', - undefined, - setup, - undefined, - undefined, - { callerProvidesSurface: true, activateCreatedTabs: false } - ) - expect(primary).toBeNull() - expect(store.createTab).toHaveBeenCalledExactlyOnceWith('wt-1', undefined, undefined, { - recordInteraction: false, - activate: false, - pendingStartup: { - command: 'bash /tmp/repo/.git/orca/setup-runner.sh', - env: setup.envVars - } - }) - expect(store.setActiveTab).not.toHaveBeenCalled() - expect(store.setTabCustomTitle).toHaveBeenCalledWith('tab-1', 'Setup', { - recordInteraction: false - }) - } - ) - - it('still seeds a shell for issue automation, which splits from it', () => { - let createdIndex = 0 - const createTab = vi.fn(() => ({ id: `tab-${++createdIndex}` })) - const store = createMockStore({ createTab }) - - ensureWorktreeHasInitialTerminal( - store, - 'wt-1', - undefined, - undefined, - { command: 'orca issue run' }, - undefined, - { callerProvidesSurface: true } - ) - - expect(createTab).toHaveBeenCalledTimes(1) - expect(store.queueTabIssueCommandSplit).toHaveBeenCalledWith('tab-1', { - command: 'orca issue run', - env: undefined - }) - }) - - it('still seeds a shell when the caller owns no surface', () => { - let createdIndex = 0 - const createTab = vi.fn(() => ({ id: `tab-${++createdIndex}` })) - const store = createMockStore({ createTab }) - - ensureWorktreeHasInitialTerminal(store, 'wt-1', undefined, setup) - - expect(createTab).toHaveBeenCalledTimes(2) - expect(store.setTabCustomTitle).toHaveBeenCalledWith('tab-2', 'Setup', { - recordInteraction: false - }) - }) - it('activation forwards providesInitialSurface so setup alone adds one tab', () => { const worktree = makeWorktree() seedEmptyActivatableWorktree(worktree) diff --git a/src/renderer/src/lib/worktree-agent-activation-gate-main-placement.test.ts b/src/renderer/src/lib/worktree-agent-activation-gate-main-placement.test.ts index 2a48ebcfe3e..5a7e6c51621 100644 --- a/src/renderer/src/lib/worktree-agent-activation-gate-main-placement.test.ts +++ b/src/renderer/src/lib/worktree-agent-activation-gate-main-placement.test.ts @@ -7,16 +7,12 @@ import { type GateTestStore, listed, LIVE_LEAF_ID, - seedExistingSurface, SIBLING_LEAF_ID, sleepingRecord, testDeps, WORKTREE_ID } from './worktree-agent-activation-gate.test-fixture' -import { - readWorktreeLiveTerminalSurfaceOwners, - type LiveTerminalSurfaceOwner -} from './worktree-live-terminal-surface-owners' +import type { LiveTerminalSurfaceOwner } from './worktree-live-terminal-surface-owners' vi.mock('../../../shared/layout-owner-switch', () => ({ ORCA_LAYOUT_OWNER_IS_MAIN: true })) @@ -44,27 +40,6 @@ afterEach(() => { vi.unstubAllGlobals() }) -describe('the sweep’s listing, layout-owner build', () => { - it('asks main to place the workspace’s unshown live terminals before it lists', async () => { - const call = vi.fn(async () => ({ - ok: true, - result: { terminals: [], hostScope: { hostIds: ['local'], omittedHostIds: [] } } - })) - vi.stubGlobal('window', { api: { runtime: { call } } }) - - await readWorktreeLiveTerminalSurfaceOwners(WORKTREE_ID) - - expect(call).toHaveBeenCalledWith({ - method: 'terminal.list', - params: expect.objectContaining({ - worktree: `id:${WORKTREE_ID}`, - requireFreshPtyLiveness: true, - placeUnshownLiveTerminals: true - }) - }) - }) -}) - describe('the activation sweep reads main’s placement, layout-owner build', () => { it('counts a terminal main placed as shown before its frame arrives: no shell is seeded', async () => { const { deps, resume } = testDeps({ @@ -78,18 +53,6 @@ describe('the activation sweep reads main’s placement, layout-owner build', () expect(resume).not.toHaveBeenCalled() }) - it('writes nothing for a pane main names in a tab this window already has', async () => { - const { deps } = testDeps({ - sessions: [listed(LIVE_PTY)], - surfaceOwners: new Map([[LIVE_PTY, placedByMain(LIVE_PTY, 'tab-known')]]) - }) - seedExistingSurface(deps.getState(), { tabId: 'tab-known', leafId: LIVE_LEAF_ID }) - - await expect(runWorktreeAgentActivationGate(WORKTREE_ID, deps)).resolves.toBe('adopted') - - expectNoWindowWrite(deps.getState()) - }) - it('still resumes the workspace’s sleeping agent beside the terminal main placed', async () => { const { deps, resume } = testDeps({ sessions: [{ ...listed(LIVE_PTY), title: 'zsh', agentOwnership: 'absent' }],