diff --git a/config/flaky-test-pattern-baseline.txt b/config/flaky-test-pattern-baseline.txt
index c4c935d5ea1..db99e6e09b4 100644
--- a/config/flaky-test-pattern-baseline.txt
+++ b/config/flaky-test-pattern-baseline.txt
@@ -755,7 +755,6 @@
3 test-no-wall-clock:src/main/wsl/orcad/wsl-orcad-real-distro-lane.test.ts
3 test-no-wall-clock:src/renderer/src/components/activity/activity-auto-mark-read-loop.react185.test.tsx
2 test-no-wall-clock:src/renderer/src/components/artifacts/ArtifactCollection.test.tsx
-1 test-no-wall-clock:src/renderer/src/components/automations/use-automation-list-search.test.tsx
1 test-no-wall-clock:src/renderer/src/components/browser-pane/assemble-chrome/browser-workspace-pane.adoption-chrome.test.tsx
2 test-no-wall-clock:src/renderer/src/components/dashboard/useLiveDashboardSnapshot.test.ts
1 test-no-wall-clock:src/renderer/src/components/native-chat/NativeChatMessageList.opening-send.test.tsx
diff --git a/config/reliability-gates.jsonc b/config/reliability-gates.jsonc
index b2a32f817e7..74e924e64a8 100644
--- a/config/reliability-gates.jsonc
+++ b/config/reliability-gates.jsonc
@@ -2784,10 +2784,8 @@
{
"file": "src/shared/ephemeral-vm-runtime-store-rollback.test.ts",
"assertions": [
- "ordinary runtime bytes remain unchanged and create no feature sidecar",
"malformed, future, oversized, and unknown feature data is preserved without poisoning v1 records",
- "current-main poisoned bytes migrate to a rollback-readable projection",
- "unchanged compatibility metadata is not rewritten during lifecycle updates"
+ "current-main poisoned bytes migrate to a rollback-readable projection"
]
},
{
diff --git a/config/scripts/ci/sharding/ci-shard-timings.json b/config/scripts/ci/sharding/ci-shard-timings.json
index ec696f5c9f2..e8602250f7d 100644
--- a/config/scripts/ci/sharding/ci-shard-timings.json
+++ b/config/scripts/ci/sharding/ci-shard-timings.json
@@ -914,7 +914,6 @@
"src/main/automations/automation-wsl-move-refusal.test.ts": 2285,
"src/main/automations/automation-zero-grace-tick-latency.test.ts": 2108,
"src/main/automations/dispatch-refusal-wsl-move.test.ts": 577,
- "src/main/automations/dispatch-tokens.test.ts": 120,
"src/main/automations/external-automation-manager-cache.test.ts": 70,
"src/main/automations/external-automation-owner-guard.test.ts": 332,
"src/main/automations/external-automation-probe-scheduler.test.ts": 97,
@@ -5631,17 +5630,14 @@
"src/renderer/src/components/automations/use-automation-list-search.test.tsx": 679,
"src/renderer/src/components/automations/use-automation-runs-dashboard-payload.test.tsx": 6692,
"src/renderer/src/components/automations/use-automation-runs-dashboard.test.tsx": 854,
- "src/renderer/src/components/automations/use-external-automation-scope-retention.test.tsx": 232,
"src/renderer/src/components/automations/use-selected-automation-run-history.test.tsx": 2104,
"src/renderer/src/components/browser-favicon.test.tsx": 333,
"src/renderer/src/components/browser-pane/ClientHostedBrowserPagePane.dead-guest.test.tsx": 6219,
"src/renderer/src/components/browser-pane/ClientHostedBrowserPagePane.drag-focus.test.tsx": 5826,
"src/renderer/src/components/browser-pane/ClientHostedBrowserPagePane.failure-remount.test.tsx": 3085,
"src/renderer/src/components/browser-pane/ClientHostedBrowserPagePane.markup.test.tsx": 4575,
- "src/renderer/src/components/browser-pane/ClientHostedBrowserPagePane.popup-notices.test.tsx": 6196,
"src/renderer/src/components/browser-pane/ClientHostedBrowserPagePane.test.tsx": 6541,
"src/renderer/src/components/browser-pane/ReopenBrowserPageOnServerButton.test.tsx": 497,
- "src/renderer/src/components/browser-pane/annotate/GrabConfirmationSheet.test.ts": 261,
"src/renderer/src/components/browser-pane/annotate/MarkupOverlay.test.tsx": 1124,
"src/renderer/src/components/browser-pane/annotate/browser-annotation-output.test.ts": 74,
"src/renderer/src/components/browser-pane/annotate/browser-grab-toast-owner-cleanup.test.tsx": 1007,
@@ -8689,34 +8685,23 @@
"src/shared/ephemeral-vm-recipes.test.ts": 160,
"src/shared/ephemeral-vm-runtime-store-rollback.test.ts": 321,
"src/shared/ephemeral-vm-runtime-store.test.ts": 195,
- "src/shared/errno-code.test.ts": 50,
- "src/shared/event-loop-yield.test.ts": 72,
"src/shared/execution-host-registry-shared-control-connect.test.ts": 160,
"src/shared/execution-host-registry.test.ts": 169,
"src/shared/execution-host.test.ts": 56,
- "src/shared/export-let-function-initializer-ban.test.ts": 2489,
"src/shared/external-automation-jobs-file.test.ts": 72,
"src/shared/external-worktree-inbox.test.ts": 69,
"src/shared/feature-education-telemetry.test.ts": 36,
- "src/shared/feature-interactions.test.ts": 47,
"src/shared/feature-tips.test.ts": 54,
- "src/shared/feature-wall-tour-depth.test.ts": 45,
- "src/shared/feedback-image-limits.test.ts": 43,
"src/shared/file-explorer-display-root.test.ts": 47,
"src/shared/file-inventory-budget.test.ts": 44,
"src/shared/file-links/file-link-location.test.ts": 40,
- "src/shared/file-name-sort.test.ts": 47,
- "src/shared/file-preview-kind.test.ts": 46,
"src/shared/file-write-disk-precondition.test.ts": 56,
- "src/shared/filesystem-watch-batch-window.test.ts": 48,
"src/shared/filesystem-watch-event-buffer.test.ts": 42,
- "src/shared/fish-binary-requirement.test.ts": 51,
"src/shared/folder-workspaces/folder-workspace-execution-host.test.ts": 84,
"src/shared/folder-workspaces/folder-workspace-worktree.test.ts": 104,
"src/shared/folder-workspaces/folder-workspaces.test.ts": 131,
"src/shared/foreground-process-selection.test.ts": 100,
"src/shared/foreground-wrapper-agent.test.ts": 82,
- "src/shared/generated-code-path.test.ts": 46,
"src/shared/git/compatibility/git-binary-compatibility.test.ts": 377,
"src/shared/git/diff/git-blob-absence.test.ts": 54,
"src/shared/git/branches/git-branch-cleanup-real-git.test.ts": 883,
diff --git a/src/main/ai-vault/session-scanner-scope.test.ts b/src/main/ai-vault/session-scanner-scope.test.ts
index 1e9a41ee265..39f4b2faa17 100644
--- a/src/main/ai-vault/session-scanner-scope.test.ts
+++ b/src/main/ai-vault/session-scanner-scope.test.ts
@@ -109,27 +109,6 @@ describe('scanAiVaultSessions scope inclusion', () => {
expect(ids(withScope)).toContain('old-in-scope-subdir')
})
- it('does not duplicate sessions already in the capped result', async () => {
- const root = await mkdtemp(join(tmpdir(), 'orca-ai-vault-scope-'))
- tempRoots.push(root)
- const claudeRoot = join(root, 'claude-projects')
-
- await writeClaudeSession({
- claudeRoot,
- dirName: '-repo-app',
- sessionId: 'recent-in-scope',
- cwd: '/repo/app',
- iso: '2026-06-24T00:00:00.000Z'
- })
-
- const result = await scanAiVaultSessions(
- scopedScanOptions(claudeRoot, { limit: 50, scopePaths: ['/repo/app'] })
- )
-
- const matches = result.sessions.filter((session) => session.sessionId === 'recent-in-scope')
- expect(matches).toHaveLength(1)
- })
-
it('does not assign a native transcript to a WSL distro from cwd alone', async () => {
const root = await mkdtemp(join(tmpdir(), 'orca-ai-vault-scope-'))
tempRoots.push(root)
diff --git a/src/main/ai-vault/session-scanner-timeline.test.ts b/src/main/ai-vault/session-scanner-timeline.test.ts
index cd488347a7f..e20c5ed55ae 100644
--- a/src/main/ai-vault/session-scanner-timeline.test.ts
+++ b/src/main/ai-vault/session-scanner-timeline.test.ts
@@ -1,10 +1,5 @@
-import { describe, expect, it, vi } from 'vitest'
-import {
- cloneSessionAccumulator,
- createAccumulator,
- finalizeSession,
- updateTimeline
-} from './session-scanner-accumulator'
+import { describe, expect, it } from 'vitest'
+import { createAccumulator, finalizeSession, updateTimeline } from './session-scanner-accumulator'
function accumulator() {
return createAccumulator({
@@ -44,53 +39,4 @@ describe('session timeline bounds', () => {
expect(state.createdAt).toBe(new Date(base - 1).toISOString())
expect(state.latestTimestampMs).toBe(base + 0.1)
})
-
- it('preserves pre-epoch and extended-year ISO timestamps', () => {
- const state = accumulator()
- updateTimeline(state, '+010000-01-01T00:00:00.000Z')
- updateTimeline(state, '-000001-01-01T00:00:00.000Z')
- updateTimeline(state, '1969-12-31T23:59:59.999Z')
- expect(state.createdAt).toBe('-000001-01-01T00:00:00.000Z')
- expect(state.updatedAt).toBe('+010000-01-01T00:00:00.000Z')
- })
-
- it('ignores invalid timestamps and retains the existing out-of-range error', () => {
- const state = accumulator()
- for (const timestamp of [null, undefined, '', 'bad-date', 0, -1, Number.NaN, Infinity]) {
- updateTimeline(state, timestamp)
- }
- expect(state.createdAt).toBeNull()
- expect(state.updatedAt).toBeNull()
- expect(() => updateTimeline(state, 8_640_000_000_000_001)).toThrow(RangeError)
- expect(state.createdAt).toBeNull()
- expect(state.updatedAt).toBeNull()
- })
-
- it('keeps cloned parse-state bounds independent', () => {
- const state = accumulator()
- updateTimeline(state, '2026-01-02T00:00:00Z')
- const clone = cloneSessionAccumulator(state)
- updateTimeline(clone, '2026-01-01T00:00:00Z')
- updateTimeline(clone, '2026-01-03T00:00:00Z')
- expect(state.createdAt).toBe('2026-01-02T00:00:00.000Z')
- expect(state.updatedAt).toBe('2026-01-02T00:00:00.000Z')
- expect(clone.createdAt).toBe('2026-01-01T00:00:00.000Z')
- expect(clone.updatedAt).toBe('2026-01-03T00:00:00.000Z')
- })
-
- it('does not reparse accumulated bounds for every numeric record', () => {
- const state = accumulator()
- const spy = vi.spyOn(Date, 'parse')
- let parseCalls: number
- try {
- for (let index = 0; index < 1000; index += 1) {
- updateTimeline(state, 1_700_000_000_000 + index)
- }
- parseCalls = spy.mock.calls.length
- } finally {
- spy.mockRestore()
- }
- expect(state.latestTimestampMs).toBe(1_700_000_000_999)
- expect(parseCalls).toBe(0)
- })
})
diff --git a/src/main/ai-vault/session-scanner-values.test.ts b/src/main/ai-vault/session-scanner-values.test.ts
index 243232118bd..7090c7e1ce5 100644
--- a/src/main/ai-vault/session-scanner-values.test.ts
+++ b/src/main/ai-vault/session-scanner-values.test.ts
@@ -1,11 +1,9 @@
import { homedir } from 'node:os'
import { join } from 'node:path'
-import { describe, expect, it, vi } from 'vitest'
+import { describe, expect, it } from 'vitest'
import {
extractFullFirstUserPromptText,
extractPreviewContentText,
- normalizeAgentSessionsDir,
- normalizeFullFirstUserPromptText,
normalizePrimeAgentSessionsDir,
primeAgentSessionsDirFromEnv,
normalizePreviewText,
@@ -41,47 +39,12 @@ describe('AI Vault session scanner text values', () => {
expect(extractPreviewContentText([{ type: 'text', text: line }], 'user')).toBe(line)
})
- it('folds large preview text directly without full-string replacement', () => {
- const replaceSpy = vi.spyOn(String.prototype, 'replace')
- const hiddenContext = `${'SECRET\n'.repeat(10_000)}`
- const result = normalizePreviewText(`${hiddenContext}\nVisible preview ${'copy '.repeat(120)}`)
- const replaceCalls = replaceSpy.mock.calls.length
-
- expect(replaceCalls).toBe(0)
- expect(result?.startsWith('Visible preview copy copy')).toBe(true)
- expect(result).not.toContain('SECRET')
- expect(result?.endsWith('...')).toBe(true)
- })
-
- it('stops reading preview array items after the bounded display text is settled', () => {
- const unreadItem = {}
- Object.defineProperty(unreadItem, 'text', {
- get() {
- throw new Error('later preview items should not be read')
- }
- })
-
- const result = extractPreviewContentText([
- { type: 'text', text: 'Visible preview '.repeat(30) },
- unreadItem
- ])
- const normalizedPreview = Array.from({ length: 30 }, () => 'Visible preview').join(' ')
-
- expect(result).toBe(`${normalizedPreview.slice(0, 217)}...`)
- })
-
it('keeps truncation from splitting surrogate pairs', () => {
const result = normalizePreviewText(`${'a'.repeat(216)}😀tail`)
expect(result).toBe(`${'a'.repeat(216)}...`)
})
- it('preserves full first-prompt text including newlines for copy', () => {
- const body = `First prompt line one\n\nline two ${'word '.repeat(100)}`
- expect(normalizeFullFirstUserPromptText(body)).toBe(body.trim())
- expect(extractFullFirstUserPromptText([{ type: 'text', text: body }])).toBe(body.trim())
- })
-
it('reads Codex input_text blocks and ignores tool blocks', () => {
const body = `Review the PR\n\n${'detail '.repeat(50).trimEnd()}`
expect(extractFullFirstUserPromptText([{ type: 'input_text', text: body }])).toBe(body)
@@ -93,41 +56,6 @@ describe('AI Vault session scanner text values', () => {
).toBe('Please continue the editor refactor')
})
- it('expands Pi and OMP agent homes to their session directories', () => {
- expect(normalizeAgentSessionsDir('/agents/.pi', '.pi')).toBe('/agents/.pi/agent/sessions')
- expect(normalizeAgentSessionsDir('/agents/.pi/agent', '.pi')).toBe('/agents/.pi/agent/sessions')
- expect(normalizeAgentSessionsDir('/agents/.pi/agent/sessions', '.pi')).toBe(
- '/agents/.pi/agent/sessions'
- )
-
- expect(normalizeAgentSessionsDir('/agents/.omp', '.omp')).toBe('/agents/.omp/agent/sessions')
- expect(normalizeAgentSessionsDir('/agents/.omp/agent', '.omp')).toBe(
- '/agents/.omp/agent/sessions'
- )
- expect(normalizeAgentSessionsDir('/agents/.omp/agent/sessions', '.omp')).toBe(
- '/agents/.omp/agent/sessions'
- )
- })
-
- it('maps any Prime Agent agent dir to its sessions child', () => {
- expect(normalizePrimeAgentSessionsDir('/tmp/prime-agent')).toBe('/tmp/prime-agent/sessions')
- expect(normalizePrimeAgentSessionsDir('/tmp/prime-agent///')).toBe('/tmp/prime-agent/sessions')
- expect(normalizePrimeAgentSessionsDir('/agents/.prime')).toBe('/agents/.prime/sessions')
- expect(normalizePrimeAgentSessionsDir('/agents/.prime/agent')).toBe(
- '/agents/.prime/agent/sessions'
- )
- })
-
- it('still appends sessions when the agent dir is itself named sessions', () => {
- expect(normalizePrimeAgentSessionsDir('/data/sessions')).toBe('/data/sessions/sessions')
- })
-
- it('expands a leading tilde in the agent dir', () => {
- expect(normalizePrimeAgentSessionsDir('~/work/prime')).toBe(
- join(homedir(), 'work', 'prime', 'sessions')
- )
- })
-
// Drive-relative paths are invalid on POSIX too; native Windows semantics need a Windows runner.
it('falls back to the default root for every non-absolute agent dir', () => {
const fallback = join(homedir(), '.prime', 'agent', 'sessions')
@@ -151,16 +79,6 @@ describe('AI Vault session scanner text values', () => {
describe('primeAgentSessionsDirFromEnv', () => {
const defaultDir = join(homedir(), '.prime', 'agent', 'sessions')
- it('defaults to the home agent dir when nothing is configured', () => {
- expect(primeAgentSessionsDirFromEnv({})).toBe(defaultDir)
- })
-
- it('appends sessions to a configured agent dir', () => {
- expect(primeAgentSessionsDirFromEnv({ PRIME_AGENT_CODING_AGENT_DIR: '/opt/prime' })).toBe(
- '/opt/prime/sessions'
- )
- })
-
it('prefers the sessions-root overrides verbatim over the agent dir', () => {
expect(
primeAgentSessionsDirFromEnv({
diff --git a/src/main/ai-vault/shell-command-words.test.ts b/src/main/ai-vault/shell-command-words.test.ts
index 97920230c9d..0c1229828f3 100644
--- a/src/main/ai-vault/shell-command-words.test.ts
+++ b/src/main/ai-vault/shell-command-words.test.ts
@@ -39,13 +39,6 @@ describe('shellCommands', () => {
['b', 'x', 'y']
])
})
-
- it('stays linear on long and unbalanced texts', () => {
- const size = 2 * 1024 * 1024
- expect(commands('a'.repeat(size))[0]![0]).toHaveLength(size)
- expect(commands(`"${' \\"'.repeat(size / 3)}`)).toHaveLength(1)
- expect(commands(`'${" '".repeat(size / 2)}`)).toHaveLength(1)
- })
})
describe('commandProgramIndex', () => {
diff --git a/src/main/amp/hook-service.test.ts b/src/main/amp/hook-service.test.ts
index b7ed91ddab5..3949890224e 100644
--- a/src/main/amp/hook-service.test.ts
+++ b/src/main/amp/hook-service.test.ts
@@ -64,46 +64,4 @@ describe('AmpHookService', () => {
expect(skipped.state).toBe('partial')
expect(existsSync(pluginPath)).toBe(true)
})
-
- it('reports partial for stale managed plugin content missing required handlers', () => {
- const pluginPath = _internals.getPluginPath()
- mkdirSync(dirname(pluginPath), { recursive: true })
- writeFileSync(pluginPath, `// ${_internals.AMP_PLUGIN_MARKER}\n`, 'utf-8')
-
- const status = new AmpHookService().getStatus()
-
- expect(status).toMatchObject({
- agent: 'amp',
- state: 'partial',
- managedHooksPresent: true
- })
- expect(status.detail).toContain('missing required handlers')
- })
-
- it('reports partial when a stale managed plugin is missing the session reset handler', () => {
- const pluginPath = _internals.getPluginPath()
- mkdirSync(dirname(pluginPath), { recursive: true })
- writeFileSync(
- pluginPath,
- [
- `// ${_internals.AMP_PLUGIN_MARKER}`,
- "amp.on('agent.start', () => {})",
- "amp.on('tool.call', () => {})",
- "amp.on('tool.result', () => {})",
- "amp.on('agent.end', () => {})",
- '/hook/amp',
- ''
- ].join('\n'),
- 'utf-8'
- )
-
- const status = new AmpHookService().getStatus()
-
- expect(status).toMatchObject({
- agent: 'amp',
- state: 'partial',
- managedHooksPresent: true
- })
- expect(status.detail).toContain('missing required handlers')
- })
})
diff --git a/src/main/antigravity/hook-service.test.ts b/src/main/antigravity/hook-service.test.ts
index 5cd628bb03b..20ae7b9d529 100644
--- a/src/main/antigravity/hook-service.test.ts
+++ b/src/main/antigravity/hook-service.test.ts
@@ -1,6 +1,6 @@
import { afterEach, beforeEach, describe, expect, it, vi } from 'vitest'
import { spawnSync } from 'node:child_process'
-import { mkdirSync, mkdtempSync, readFileSync, existsSync, rmSync, writeFileSync } from 'node:fs'
+import { mkdirSync, mkdtempSync, readFileSync, rmSync, writeFileSync } from 'node:fs'
import { tmpdir } from 'node:os'
import { dirname, join } from 'node:path'
@@ -26,7 +26,6 @@ const ANTIGRAVITY_POST_TOOL_USE_COMMAND =
const ANTIGRAVITY_PRE_TOOL_USE_COMMAND =
process.platform === 'win32' ? 'antigravity-pre-tool-use.cmd' : 'antigravity-hook.sh'
const PRE_TOOL_USE_DECISION = '{"decision":"ask"}'
-const POLICY_OVERRIDING_DECISIONS = ['allow', 'deny', 'force_ask', 'deny_unless_prior_grant']
function withPlatform(platform: NodeJS.Platform, run: () => T): T {
const originalPlatform = Object.getOwnPropertyDescriptor(process, 'platform')
@@ -124,97 +123,6 @@ describe('AntigravityHookService', () => {
}
)
- it('installs Windows event wrappers without nested cmd quoting and replaces stale PreToolUse hooks', () => {
- withPlatform('win32', () => {
- const configPath = join(homeDir, '.gemini', 'config', 'hooks.json')
- const staleScriptPath = join(
- homeDir,
- '.orca',
- 'agent-hooks',
- 'antigravity-hook.cmd'
- ).replaceAll('/', '\\')
- mkdirSync(dirname(configPath), { recursive: true })
- writeFileSync(
- configPath,
- `${JSON.stringify(
- {
- 'orca-status': {
- PreToolUse: [
- {
- matcher: '*',
- hooks: [
- {
- type: 'command',
- command: `cmd /d /s /c "set "ORCA_ANTIGRAVITY_EVENT=PreToolUse" && call "${staleScriptPath}""`
- }
- ]
- }
- ]
- }
- },
- null,
- 2
- )}\n`
- )
-
- const service = new AntigravityHookService()
- const staleStatus = service.getStatus()
- expect(staleStatus.state).toBe('partial')
- expect(staleStatus.managedHooksPresent).toBe(true)
-
- const status = service.install()
-
- expect(status.state).toBe('installed')
-
- const config = JSON.parse(readFileSync(configPath, 'utf8')) as {
- 'orca-status': Record<
- string,
- { matcher?: string; command?: string; hooks?: { command: string }[] }[]
- >
- }
- expect(config['orca-status'].PreToolUse).toHaveLength(1)
-
- const expectedWrappers = {
- PreInvocation: 'antigravity-pre-invocation.cmd',
- PostInvocation: 'antigravity-post-invocation.cmd',
- Stop: 'antigravity-stop.cmd',
- PreToolUse: 'antigravity-pre-tool-use.cmd',
- PostToolUse: 'antigravity-post-tool-use.cmd'
- }
- for (const [eventName, wrapperFileName] of Object.entries(expectedWrappers)) {
- const definition = config['orca-status'][eventName][0]
- const command = ['PreToolUse', 'PostToolUse'].includes(eventName)
- ? definition.hooks?.[0]?.command
- : definition.command
- expect(createManagedCommandMatcher(wrapperFileName)(command)).toBe(true)
- expect(command).not.toContain('cmd /d /s /c')
- expect(command).not.toContain('ORCA_ANTIGRAVITY_EVENT')
-
- const wrapper = readFileSync(join(homeDir, '.orca', 'agent-hooks', wrapperFileName), 'utf8')
- expect(wrapper).toContain(`set "ORCA_ANTIGRAVITY_EVENT=${eventName}"`)
- expect(wrapper).toContain('call "%ORCA_ANTIGRAVITY_CORE%"')
- if (eventName === 'PreToolUse') {
- expect(wrapper).toContain(`echo ${PRE_TOOL_USE_DECISION}`)
- }
- for (const decision of POLICY_OVERRIDING_DECISIONS) {
- expect(wrapper).not.toContain(`{"decision":"${decision}"}`)
- }
- }
-
- const script = readFileSync(
- join(homeDir, '.orca', 'agent-hooks', 'antigravity-hook.cmd'),
- 'utf8'
- )
- expect(script).toContain('antigravity-hook-post.cjs')
- expect(script).not.toContain('powershell.exe')
- expect(script).toContain('ELECTRON_RUN_AS_NODE=1')
- expect(
- readFileSync(join(homeDir, '.orca', 'agent-hooks', 'antigravity-hook-post.cjs'), 'utf8')
- ).toContain('/hook/antigravity')
- expect(script).toContain('setlocal DisableDelayedExpansion')
- })
- })
-
it('preserves the installed core and config when publishing the Windows reader fails', () => {
withPlatform('win32', () => {
const service = new AntigravityHookService()
@@ -234,28 +142,6 @@ describe('AntigravityHookService', () => {
})
})
- it('restores the owned Windows reader and resolves the current runtime on refresh', async () => {
- vi.spyOn(process, 'platform', 'get').mockReturnValue('win32')
- try {
- const service = new AntigravityHookService()
- let runtimePath = 'C:\\Orca1\\Orca.exe'
- service.setWindowsRuntimePathProvider(() => runtimePath)
- const readerPath = join(homeDir, '.orca', 'agent-hooks', 'antigravity-hook-post.cjs')
- await service.refreshManagedScripts()
- expect(existsSync(readerPath)).toBe(false)
- expect(service.install().state).toBe('installed')
- rmSync(readerPath)
- runtimePath = 'C:\\Orca2\\Orca.exe'
- await service.refreshManagedScripts()
- expect(readFileSync(readerPath, 'utf8')).toContain("require('node:string_decoder')")
- expect(
- readFileSync(join(homeDir, '.orca', 'agent-hooks', 'antigravity-hook.cmd'), 'utf8')
- ).toContain('ORCA_AGENT_HOOK_NODE=C:\\Orca2\\Orca.exe')
- } finally {
- vi.restoreAllMocks()
- }
- })
-
it('preserves user-authored hook bundles and entries in Orca bundle', () => {
const configPath = join(homeDir, '.gemini', 'config', 'hooks.json')
mkdirSync(dirname(configPath), { recursive: true })
diff --git a/src/main/artifacts/artifact-cloud-recovery.test.ts b/src/main/artifacts/artifact-cloud-recovery.test.ts
index 8008826464f..5c5a8890df0 100644
--- a/src/main/artifacts/artifact-cloud-recovery.test.ts
+++ b/src/main/artifacts/artifact-cloud-recovery.test.ts
@@ -74,23 +74,6 @@ describe('ArtifactCloudService committed response loss recovery', () => {
expect(server.artifactContent('artifact-1')).toBe(writeRequest.content)
})
- it('updates a recovered share when its content changed after response loss', async () => {
- const userDataPath = await createUserDataPath()
- const server = new ArtifactFaultServer()
- server.loseNextCreateResponse = true
- vi.stubGlobal('fetch', server.fetch)
-
- await expect(service(userDataPath).share(writeRequest)).rejects.toThrow('response lost')
- await expect(
- service(userDataPath).share({ ...writeRequest, content: 'Changed share
' })
- ).resolves.toMatchObject({
- status: 'ok',
- value: { artifact: { slug: 'artifact-1' } }
- })
- expect(server.createMutations).toBe(1)
- expect(server.artifactContent('artifact-1')).toBe('Changed share
')
- })
-
it('retains recovery until a changed-content update succeeds', async () => {
const userDataPath = await createUserDataPath()
const server = new ArtifactFaultServer()
diff --git a/src/main/artifacts/artifact-cloud-service.test.ts b/src/main/artifacts/artifact-cloud-service.test.ts
index f33405d72bd..05b9922687f 100644
--- a/src/main/artifacts/artifact-cloud-service.test.ts
+++ b/src/main/artifacts/artifact-cloud-service.test.ts
@@ -105,90 +105,6 @@ afterEach(async () => {
})
describe('ArtifactCloudService record authorization', () => {
- it('passes an opaque cursor and returns the complete list page', async () => {
- const { service } = await setup()
- const fetchMock = vi.fn().mockResolvedValue(
- new Response(JSON.stringify({ artifacts: [], nextCursor: 'next-page' }), {
- status: 200,
- headers: { 'content-type': 'application/json' }
- })
- )
- vi.stubGlobal('fetch', fetchMock)
-
- await expect(
- service.list({ apiUrl, authToken: 'token-a', cursor: 'opaque/+=' })
- ).resolves.toEqual({
- status: 'ok',
- value: { artifacts: [], nextCursor: 'next-page' }
- })
- expect(fetchMock).toHaveBeenCalledWith(
- `${apiUrl}/v1/artifacts?cursor=opaque%2F%2B%3D`,
- expect.any(Object)
- )
- })
-
- it('uses a distinct idempotency key for each logical share', async () => {
- const { service } = await setup()
- const fetchMock = vi
- .fn()
- .mockResolvedValueOnce(createResponse('artifact-a'))
- .mockResolvedValueOnce(createResponse('artifact-b'))
- vi.stubGlobal('fetch', fetchMock)
-
- await service.share(writeRequest)
- await service.share({ ...writeRequest, sourceKey: '/repo/other.html' })
-
- const firstKey = requestHeader(fetchMock, 0, 'idempotency-key')
- const secondKey = requestHeader(fetchMock, 1, 'idempotency-key')
- expect(firstKey).toMatch(/^[0-9a-f-]{36}$/)
- expect(secondKey).toMatch(/^[0-9a-f-]{36}$/)
- expect(firstKey).not.toBe(secondKey)
- })
-
- it('creates once and updates on repeated publish', async () => {
- const { service } = await setup()
- const fetchMock = vi
- .fn()
- .mockResolvedValueOnce(createResponse())
- .mockResolvedValueOnce(createResponse())
- vi.stubGlobal('fetch', fetchMock)
-
- await expect(service.publish(writeRequest)).resolves.toMatchObject({
- status: 'ok',
- value: { change: 'created', item: { shareUrl: 'https://share.onorca.dev/a/artifact-a' } }
- })
- await expect(service.publish(writeRequest)).resolves.toMatchObject({
- status: 'ok',
- value: { change: 'updated', item: { shareUrl: 'https://share.onorca.dev/a/artifact-a' } }
- })
-
- expect(fetchMock.mock.calls[0]?.[1]).toMatchObject({ method: 'POST' })
- expect(fetchMock.mock.calls[1]?.[0]).toBe(`${apiUrl}/v1/artifacts/artifact-a`)
- expect(fetchMock.mock.calls[1]?.[1]).toMatchObject({ method: 'PUT' })
- })
-
- it('resolves a persisted public link only for its source and cloud scope', async () => {
- const { service } = await setup()
- const fetchMock = vi.fn().mockResolvedValueOnce(createResponse())
- vi.stubGlobal('fetch', fetchMock)
-
- await service.publish(writeRequest)
-
- await expect(
- service.getPublishedLink({ sourceKey: writeRequest.sourceKey, apiUrl, authToken: 'token-a' })
- ).resolves.toEqual({
- status: 'ok',
- value: { shareUrl: 'https://share.onorca.dev/a/artifact-a' }
- })
- await expect(
- service.getPublishedLink({ sourceKey: '/repo/other.html', apiUrl, authToken: 'token-a' })
- ).resolves.toEqual({ status: 'ok', value: null })
- await expect(
- service.getPublishedLink({ sourceKey: writeRequest.sourceKey, apiUrl, authToken: 'token-b' })
- ).resolves.toEqual({ status: 'ok', value: null })
- expect(fetchMock).toHaveBeenCalledOnce()
- })
-
it('serializes concurrent publishes for the same source', async () => {
const { service } = await setup()
let resolveCreate: ((response: Response) => void) | undefined
@@ -434,20 +350,6 @@ describe('ArtifactCloudService record authorization', () => {
expect(fetchMock).toHaveBeenCalledOnce()
})
- it('cleans all matching source mappings after delete by slug', async () => {
- const { service } = await setup()
- const fetchMock = vi
- .fn()
- .mockResolvedValueOnce(createResponse())
- .mockResolvedValueOnce(new Response(null, { status: 204 }))
- vi.stubGlobal('fetch', fetchMock)
- await service.share(writeRequest)
- await service.delete('artifact-a', { apiUrl, authToken: 'token-a' })
-
- await expect(service.update(writeRequest)).rejects.toThrow(/has not been shared/)
- expect(fetchMock).toHaveBeenCalledTimes(2)
- })
-
it('keeps update and unshare working after an update extends expiration', async () => {
vi.useFakeTimers({ toFake: ['Date'] })
vi.setSystemTime('2026-08-07T00:00:00.000Z')
diff --git a/src/main/artifacts/artifact-create-intent-store.test.ts b/src/main/artifacts/artifact-create-intent-store.test.ts
index 0376d11821b..cc0fa083633 100644
--- a/src/main/artifacts/artifact-create-intent-store.test.ts
+++ b/src/main/artifacts/artifact-create-intent-store.test.ts
@@ -15,15 +15,6 @@ import {
getOrCreateArtifactCreateIntent,
removeArtifactCreateIntent
} from './artifact-create-intent-store'
-import { runProcess, runProcessSync } from '@orca/process-host'
-import {
- resetWindowsSecurityLoadForTests,
- setWindowsSecurityForTests
-} from '../../shared/windows-security-addon'
-import {
- createFakeWindowsSecurity,
- FAKE_USER_SID
-} from '../../shared/windows-security-addon.test-fixture'
import type { ArtifactShareScope } from './artifact-share-record-store'
vi.mock('@orca/process-host', () => ({
@@ -179,53 +170,6 @@ describe('artifact create intent store', () => {
expect((await readdir(directory)).some((name) => name.endsWith('.tmp'))).toBe(false)
})
- it('writes each Windows intent born restricted and relocks the directory once, off the write', async () => {
- const originalPlatform = Object.getOwnPropertyDescriptor(process, 'platform')
- Object.defineProperty(process, 'platform', { configurable: true, value: 'win32' })
- const fake = createFakeWindowsSecurity()
- setWindowsSecurityForTests(fake)
- try {
- const userDataPath = await createUserDataPath()
- const directory = join(userDataPath, 'profiles', 'local-profile', 'artifact-create-intents')
- for (const [sourceKey, key] of [
- ['/repo/report.html', 'key-a'],
- ['/repo/other.html', 'key-b']
- ]) {
- getOrCreateArtifactCreateIntent('local-profile', userDataPath, sourceKey, scope, key, body)
- }
- await new Promise((resolve) => setTimeout(resolve, 0))
-
- const creates = fake.callsFor('create')
- expect(creates).toHaveLength(2)
- for (const create of creates) {
- expect(create.path.startsWith(directory)).toBe(true)
- expect(create.path.endsWith('.tmp')).toBe(true)
- expect(create).toMatchObject({
- sddl: `D:P(A;;FA;;;S-1-5-18)(A;;FA;;;S-1-5-32-544)(A;;FA;;;${FAKE_USER_SID})`
- })
- }
- expect(fake.callsFor('setAsync')).toMatchObject([
- {
- op: 'setAsync',
- path: directory,
- sddl: `D:P(A;OICI;FA;;;S-1-5-18)(A;OICI;FA;;;S-1-5-32-544)(A;OICI;FA;;;${FAKE_USER_SID})`
- }
- ])
- expect(fake.callsFor('set')).toEqual([])
- expect(
- getArtifactCreateIntent('local-profile', userDataPath, '/repo/other.html', scope)
- ).toMatchObject({ idempotencyKey: 'key-b' })
- expect((await readdir(directory)).filter((name) => name.endsWith('.tmp'))).toEqual([])
- expect(runProcess).not.toHaveBeenCalled()
- expect(runProcessSync).not.toHaveBeenCalled()
- } finally {
- if (originalPlatform) {
- Object.defineProperty(process, 'platform', originalPlatform)
- }
- resetWindowsSecurityLoadForTests()
- }
- })
-
it('refuses to overwrite an unreadable matching intent', async () => {
const userDataPath = await createUserDataPath()
const directory = join(userDataPath, 'profiles', 'local-profile', 'artifact-create-intents')
diff --git a/src/main/artifacts/artifact-share-record-store.test.ts b/src/main/artifacts/artifact-share-record-store.test.ts
index 6c1f08ab696..4068e447d26 100644
--- a/src/main/artifacts/artifact-share-record-store.test.ts
+++ b/src/main/artifacts/artifact-share-record-store.test.ts
@@ -134,37 +134,6 @@ describe('artifact share record store', () => {
expect(persisted.shares).toEqual({})
})
- it('caps records deterministically at ten thousand', async () => {
- const path = await userDataPath()
- clearArtifactShareRecords('local-profile', path)
- const recordsPath = join(path, 'profiles', 'local-profile', 'artifact-shares.json')
- const shares = Object.fromEntries(
- Array.from({ length: 10_001 }, (_, index) => [
- `/repo/report-${String(index).padStart(5, '0')}.html`,
- {
- ...scopeA,
- slug: `artifact-${index}`,
- editToken: `secret-${index}`,
- shareUrl: `https://share.onorca.dev/a/artifact-${index}`,
- expiresAt: '2099-01-01T00:00:00.000Z',
- savedAt: index
- }
- ])
- )
- await writeFile(recordsPath, JSON.stringify({ version: 2, lifecycleGeneration: 0, shares }))
-
- expect(
- getArtifactShareRecord('local-profile', path, '/repo/report-10000.html', scopeA)?.editToken
- ).toBe('secret-10000')
- expect(
- getArtifactShareRecord('local-profile', path, '/repo/report-00000.html', scopeA)
- ).toBeNull()
- const persisted = JSON.parse(await readFile(recordsPath, 'utf8')) as {
- shares: Record
- }
- expect(Object.keys(persisted.shares)).toHaveLength(10_000)
- })
-
it('keeps usable legacy version-two records without timestamps', async () => {
const path = await userDataPath()
clearArtifactShareRecords('local-profile', path)
diff --git a/src/main/automations/automation-run-terminal-surface.test.ts b/src/main/automations/automation-run-terminal-surface.test.ts
index a3d68be55fd..eceecf0cb51 100644
--- a/src/main/automations/automation-run-terminal-surface.test.ts
+++ b/src/main/automations/automation-run-terminal-surface.test.ts
@@ -47,21 +47,6 @@ const retainedRun = {
} as unknown as AutomationRun
describe('resolving an automation run terminal across startup states', () => {
- it('cannot answer for any pane while no graph has published', () => {
- const runtime = new OrcaRuntimeService(makeStore() as never)
- const observer = createRuntimeAutomationRunTerminalObserver(runtime)
-
- expect(observer.resolveRunTerminal(retainedRun)).toBeNull()
- })
-
- it('still cannot answer once an explicitly empty headless graph publishes', () => {
- const runtime = new OrcaRuntimeService(makeStore() as never)
- runtime.syncWindowGraph(HEADLESS_RUNTIME_WINDOW_ID, { tabs: [], leaves: [] })
- const observer = createRuntimeAutomationRunTerminalObserver(runtime)
-
- expect(observer.resolveRunTerminal(retainedRun)).toBeNull()
- })
-
it('answers from an adopted PTY bound to the pane, with no leaves at all', () => {
const runtime = new OrcaRuntimeService(makeStore() as never)
runtime.syncWindowGraph(HEADLESS_RUNTIME_WINDOW_ID, { tabs: [], leaves: [] })
diff --git a/src/main/automations/automation-ssh-readoption-migration.test.ts b/src/main/automations/automation-ssh-readoption-migration.test.ts
index 27bef43d3a8..aab37d2f244 100644
--- a/src/main/automations/automation-ssh-readoption-migration.test.ts
+++ b/src/main/automations/automation-ssh-readoption-migration.test.ts
@@ -104,13 +104,6 @@ describe('migrateAutomationsForSshReadoption', () => {
expect(automation.executionTargetGeneration).toBeUndefined()
})
- it('leaves automations on other targets alone', () => {
- const other = makeAutomation({ id: 'auto-2', executionTargetId: 'ssh-other' })
- expect(migrate([other], 9)).toBe(false)
- expect(other.executionTargetId).toBe('ssh-other')
- expect(other.executionTargetGeneration).toBe(3)
- })
-
it('re-points run history so workspace navigation survives re-adoption', () => {
const run = {
id: 'run-1',
@@ -123,20 +116,6 @@ describe('migrateAutomationsForSshReadoption', () => {
})
describe('migrateAutomationHostFilterSshTargetId', () => {
- it('follows the re-adopted id', () => {
- const ui = uiWithFilter(
- hostStableKey({ authority: { kind: 'desktop' }, selector: { kind: 'ssh', targetId: OLD_ID } })
- )
- expect(migrateAutomationHostFilterSshTargetId(ui, OLD_ID, NEW_ID)).toBe(true)
- expect(ui.automationHostFilter).toEqual({
- kind: 'host',
- hostKey: hostStableKey({
- authority: { kind: 'desktop' },
- selector: { kind: 'ssh', targetId: NEW_ID }
- })
- })
- })
-
it('never rewrites a runtime authority filter that reuses the same target id', () => {
const hostKey = hostStableKey({
authority: { kind: 'runtime', environmentId: 'env-1' },
@@ -146,22 +125,4 @@ describe('migrateAutomationHostFilterSshTargetId', () => {
expect(migrateAutomationHostFilterSshTargetId(ui, OLD_ID, NEW_ID)).toBe(false)
expect(ui.automationHostFilter).toEqual({ kind: 'host', hostKey })
})
-
- it('ignores All hosts, other hosts, and unparseable persisted values', () => {
- const all = { automationHostFilter: { kind: 'all' } } as PersistedUIState
- expect(migrateAutomationHostFilterSshTargetId(all, OLD_ID, NEW_ID)).toBe(false)
- const selfKey = hostStableKey({
- authority: { kind: 'desktop' },
- selector: { kind: 'self' }
- })
- expect(migrateAutomationHostFilterSshTargetId(uiWithFilter(selfKey), OLD_ID, NEW_ID)).toBe(
- false
- )
- expect(migrateAutomationHostFilterSshTargetId(uiWithFilter('garbage'), OLD_ID, NEW_ID)).toBe(
- false
- )
- expect(migrateAutomationHostFilterSshTargetId({} as PersistedUIState, OLD_ID, NEW_ID)).toBe(
- false
- )
- })
})
diff --git a/src/main/automations/dispatch-tokens.test.ts b/src/main/automations/dispatch-tokens.test.ts
deleted file mode 100644
index 03225a0d6f9..00000000000
--- a/src/main/automations/dispatch-tokens.test.ts
+++ /dev/null
@@ -1,37 +0,0 @@
-import { describe, expect, it, vi } from 'vitest'
-import {
- beginAutomationDispatchTokenUse,
- createAutomationDispatchToken,
- getAutomationDispatchTokenCountForTests,
- MAX_AUTOMATION_DISPATCH_TOKENS
-} from './dispatch-tokens'
-
-describe('automation dispatch tokens', () => {
- it('bounds distinct token churn', () => {
- vi.useFakeTimers({ toFake: ['Date'] })
- vi.setSystemTime(1_700_000_000_000)
- try {
- const tokens = Array.from({ length: MAX_AUTOMATION_DISPATCH_TOKENS + 4 }, (_, index) => {
- const automationId = `automation-${index}`
- const runId = `run-${index}`
- return {
- automationId,
- runId,
- token: createAutomationDispatchToken(automationId, runId)
- }
- })
-
- expect(getAutomationDispatchTokenCountForTests()).toBe(MAX_AUTOMATION_DISPATCH_TOKENS)
- for (const token of tokens.slice(0, 4)) {
- expect(beginAutomationDispatchTokenUse({ ...token, reservationId: 'request-1' })).toBe(
- false
- )
- }
- for (const token of tokens.slice(4)) {
- expect(beginAutomationDispatchTokenUse({ ...token, reservationId: 'request-1' })).toBe(true)
- }
- } finally {
- vi.useRealTimers()
- }
- })
-})
diff --git a/src/main/automations/external-automation-manager-cache.test.ts b/src/main/automations/external-automation-manager-cache.test.ts
index a86a4ebb0b0..32e428e10d2 100644
--- a/src/main/automations/external-automation-manager-cache.test.ts
+++ b/src/main/automations/external-automation-manager-cache.test.ts
@@ -1,8 +1,7 @@
-import { describe, expect, it, vi } from 'vitest'
+import { describe, expect, it } from 'vitest'
import {
ExternalAutomationManagerCache,
- describeExternalManagerFailure,
- MAX_EXTERNAL_AUTOMATION_MANAGER_CACHE_ENTRIES
+ describeExternalManagerFailure
} from './external-automation-manager-cache'
import { ExternalAutomationProbeCancelledError } from './external-automation-probe-scheduler'
import type { ExternalAutomationManager } from '../../shared/automations-types'
@@ -25,16 +24,6 @@ const selfOwner = 'owner:desktop:self'
const sshOwner = 'owner:desktop:ssh:target-a:3'
describe('ExternalAutomationManagerCache', () => {
- it('bounds distinct scope churn', () => {
- const cache = new ExternalAutomationManagerCache()
-
- for (let index = 0; index < MAX_EXTERNAL_AUTOMATION_MANAGER_CACHE_ENTRIES + 4; index += 1) {
- cache.write({ ownerKey: `owner-${index}`, provider: 'openclaw' }, null)
- }
-
- expect(cache.size).toBe(MAX_EXTERNAL_AUTOMATION_MANAGER_CACHE_ENTRIES)
- })
-
it('keeps each owner’s manager and failure separate', () => {
const cache = new ExternalAutomationManagerCache()
const failedOwner = 'owner:desktop:ssh:target-b:1'
@@ -75,31 +64,6 @@ describe('ExternalAutomationManagerCache', () => {
expect(cache.read({ ownerKey: selfOwner, provider: 'openclaw' })).toBeNull()
})
- it('prunes expired entries when the cache is accessed', () => {
- let now = 1_000
- const cache = new ExternalAutomationManagerCache({ ttlMs: 100, now: () => now })
- for (let index = 0; index < 10; index += 1) {
- cache.write({ ownerKey: `owner-${index}`, provider: 'openclaw' }, manager(String(index)))
- }
- now += 101
-
- expect(cache.read({ ownerKey: 'unrelated', provider: 'openclaw' })).toBeNull()
- expect(cache.size).toBe(0)
- })
-
- it('serves a fresh entry without reloading, and reloads on refresh', async () => {
- const cache = new ExternalAutomationManagerCache()
- const load = vi.fn(() => Promise.resolve(manager('openclaw:local')))
- const key = { ownerKey: selfOwner, provider: 'openclaw' }
-
- await cache.resolve(key, load)
- await cache.resolve(key, load)
- expect(load).toHaveBeenCalledTimes(1)
-
- await cache.resolve(key, load, { refresh: true })
- expect(load).toHaveBeenCalledTimes(2)
- })
-
it('records a load failure as error state rather than throwing', async () => {
const cache = new ExternalAutomationManagerCache()
diff --git a/src/renderer/src/components/automations/external-automation-scope-gating.test.ts b/src/renderer/src/components/automations/external-automation-scope-gating.test.ts
index 0f755933487..49e2620f825 100644
--- a/src/renderer/src/components/automations/external-automation-scope-gating.test.ts
+++ b/src/renderer/src/components/automations/external-automation-scope-gating.test.ts
@@ -39,15 +39,6 @@ const runtimeEntry = entry({
})
describe('external automation scope gating', () => {
- it('lists managers only for a desktop host with a captured owner', () => {
- const gate = resolveExternalAutomationScopeGate(entry())
- expect(gate.status).toBe('listed')
- expect(gate.probeOwner).toEqual({
- authority: { kind: 'desktop' },
- selector: { kind: 'self' }
- })
- })
-
it('never presents a runtime-owned host as clean', () => {
const gate = resolveExternalAutomationScopeGate(runtimeEntry)
expect(gate.status).toBe('not-listed')
@@ -99,17 +90,6 @@ describe('engine scope errors', () => {
).toBe(EXTERNAL_AUTOMATION_SCOPE_CODES.targetHidden)
})
- it('preserves the hidden-target scope code', () => {
- const gate = externalAutomationScopeGateFromError(
- new ExternalAutomationScopeError(EXTERNAL_AUTOMATION_SCOPE_CODES.targetHidden)
- )
- expect(gate).toEqual({
- status: 'not-listed',
- probeOwner: null,
- code: EXTERNAL_AUTOMATION_SCOPE_CODES.targetHidden
- })
- })
-
it('leaves unrelated failures alone so they are not relabelled as scope limits', () => {
expect(externalAutomationScopeGateFromError(new Error('socket hang up'))).toBeNull()
expect(parseExternalAutomationScopeCode(null)).toBeNull()
diff --git a/src/renderer/src/components/automations/external-automation-scope-keys.test.ts b/src/renderer/src/components/automations/external-automation-scope-keys.test.ts
index f34f9198aaf..ac11d0bbb25 100644
--- a/src/renderer/src/components/automations/external-automation-scope-keys.test.ts
+++ b/src/renderer/src/components/automations/external-automation-scope-keys.test.ts
@@ -36,16 +36,6 @@ describe('external automation scope keys', () => {
)
})
- it('keeps key kinds in separate namespaces', () => {
- const kinds = new Set([
- externalAutomationScopeKey(local),
- externalAutomationManagerKey(local, 'x'),
- externalAutomationJobKey(local, 'x'),
- externalAutomationActionKey(local, 'x', 'run')
- ])
- expect(kinds.size).toBe(4)
- })
-
it('escapes components so a hostile ID cannot forge another key', () => {
const forged = externalAutomationJobKey(local, 'job|extra')
expect(forged).not.toBe(externalAutomationActionKey(local, 'job', 'run'))
@@ -55,10 +45,4 @@ describe('external automation scope keys', () => {
)
expect(forged.split('|')).toHaveLength(4)
})
-
- it('distinguishes actions on the same job', () => {
- expect(externalAutomationActionKey(local, 'job-1', 'run')).not.toBe(
- externalAutomationActionKey(local, 'job-1', 'delete')
- )
- })
})
diff --git a/src/renderer/src/components/automations/use-automation-list-search.test.tsx b/src/renderer/src/components/automations/use-automation-list-search.test.tsx
index 40bf294a66a..08bc7892067 100644
--- a/src/renderer/src/components/automations/use-automation-list-search.test.tsx
+++ b/src/renderer/src/components/automations/use-automation-list-search.test.tsx
@@ -6,8 +6,7 @@ import { afterEach, beforeEach, describe, expect, it, vi } from 'vitest'
import type { Repo } from '../../../../shared/repo-types'
import { makeAutomation, makeAutomationListRow, REPO_ID } from './automations-page-fixtures'
import type { AutomationListRow } from './automation-list-row-identity'
-import { resolveAutomationListEmptyState } from './automation-list-empty-state'
-import type { AutomationHostFilterResolution } from './automation-host-filter-resolution'
+
import * as searchRows from './automation-list-search-rows'
import { useAutomationListSearch } from './use-automation-list-search'
@@ -54,18 +53,6 @@ function render(query: string, rows: readonly AutomationListRow[]): void {
})
}
-function makeRows(count: number): AutomationListRow[] {
- return Array.from({ length: count }, (_, index) =>
- makeAutomationListRow({
- automation: makeAutomation({
- id: `a-${index}`,
- name: `Automation ${index}`,
- prompt: `sweep repo ${index}`
- })
- })
- )
-}
-
beforeEach(() => {
container = document.createElement('div')
document.body.appendChild(container)
@@ -80,62 +67,6 @@ afterEach(() => {
latest = null
})
-describe('useAutomationListSearch index shape', () => {
- it('reuses search indexes across query changes and equivalent row arrays', () => {
- render('', makeRows(20))
- const buildsAfterMount = buildRowsSpy.mock.calls.length
-
- // Fresh arrays per keystroke: a refresh tick mid-typing must not re-index.
- for (const query of ['s', 'sw', 'swe', 'swee', 'sweep']) {
- render(query, makeRows(20))
- }
-
- expect(buildRowsSpy.mock.calls.length).toBe(buildsAfterMount)
- expect(latest?.filteredRows).toHaveLength(20)
- })
-
- it('reuses the index when a refresh tick replaces rows with equal search content', () => {
- render('', makeRows(5))
- const buildsAfterMount = buildRowsSpy.mock.calls.length
-
- // New objects, new array, same searchable content — a nextRunAt-style tick.
- render(
- '',
- makeRows(5).map((row) => ({
- ...row,
- automation: { ...row.automation, nextRunAt: Date.now() }
- }))
- )
-
- expect(buildRowsSpy.mock.calls.length).toBe(buildsAfterMount)
- })
-
- it('rebuilds once when searchable content actually changes', () => {
- const automations = makeRows(5)
- render('', automations)
- const buildsAfterMount = buildRowsSpy.mock.calls.length
-
- const renamed = automations.map((row, index) =>
- index === 0 ? { ...row, automation: { ...row.automation, name: 'Renamed sweep' } } : row
- )
- render('', renamed)
-
- expect(buildRowsSpy.mock.calls.length).toBe(buildsAfterMount + 1)
- })
-
- it('matches in a single pass over prebuilt indexes per settled query', () => {
- const automations = makeRows(10)
- render('', automations)
- matchRowsSpy.mockClear()
-
- render('sweep repo 3', automations)
-
- // Two row sets (local + external), matched once each for the settled query.
- expect(matchRowsSpy.mock.calls.length).toBeLessThanOrEqual(2)
- expect(latest?.filteredRows.map((row) => row.automation.id)).toEqual(['a-3'])
- })
-})
-
describe('useAutomationListSearch cross-host identity', () => {
it('keeps both hosts’ copies of one automation ID through a matching query', () => {
// Bare-ID reconstruction would duplicate one authority’s row and drop its colliding counterpart.
@@ -157,38 +88,3 @@ describe('useAutomationListSearch cross-host identity', () => {
])
})
})
-
-describe('useAutomationListSearch counts', () => {
- it('reports rows before and after search for the empty-state view', () => {
- const automations = makeRows(4)
- render('', automations)
- expect(latest?.searchCounts).toEqual({
- hostRowCount: 4,
- visibleRowCount: 4,
- searchActive: false
- })
-
- render('no-such-automation', automations)
- expect(latest?.searchCounts).toEqual({
- hostRowCount: 4,
- visibleRowCount: 0,
- searchActive: true
- })
- })
-
- it('feeds the no-match empty state instead of letting it recompute counts', () => {
- const resolution: AutomationHostFilterResolution = {
- effective: { kind: 'all' },
- entry: null,
- status: 'all',
- announceFallback: false
- }
- render('no-such-automation', makeRows(3))
- const counts = latest?.searchCounts
- if (!counts) {
- throw new Error('hook produced no counts')
- }
-
- expect(resolveAutomationListEmptyState({ resolution, ...counts }).kind).toBe('search-no-match')
- })
-})
diff --git a/src/renderer/src/components/automations/use-automation-runs-dashboard.test.tsx b/src/renderer/src/components/automations/use-automation-runs-dashboard.test.tsx
index 519904a1e90..d7f4e95e4e1 100644
--- a/src/renderer/src/components/automations/use-automation-runs-dashboard.test.tsx
+++ b/src/renderer/src/components/automations/use-automation-runs-dashboard.test.tsx
@@ -74,16 +74,6 @@ afterEach(() => {
})
describe('useAutomationRunsDashboard', () => {
- it('appends the next page when load more fires', async () => {
- await render(true)
- expect(latest?.entries.map((entry) => entry.run.id)).toEqual(['run-2'])
-
- await act(async () => latest?.loadMore())
-
- expect(latest?.entries.map((entry) => entry.run.id)).toEqual(['run-2', 'run-1'])
- expect(historySpy.mock.calls.at(-1)?.[2].cursor).toBe('2:run-2')
- })
-
it('keeps the cursor when a load more fails so the page stays retryable', async () => {
await render(true)
historySpy.mockImplementationOnce(async () => ({
@@ -101,18 +91,6 @@ describe('useAutomationRunsDashboard', () => {
expect(latest?.entries.map((entry) => entry.run.id)).toEqual(['run-2', 'run-1'])
})
- it('refetches the head when the view is re-entered after a load more', async () => {
- await render(true)
- await act(async () => latest?.loadMore())
- await render(false)
- historySpy.mockClear()
-
- await render(true)
-
- expect(historySpy.mock.calls.at(-1)?.[2].cursor).toBeUndefined()
- expect(latest?.entries.map((entry) => entry.run.id)).toEqual(['run-2'])
- })
-
it('reloads from the head when the authority is re-paired', async () => {
const paired = (pairingRevision: number): AutomationAuthorityRef => ({
kind: 'runtime',
diff --git a/src/renderer/src/components/automations/use-external-automation-scope-retention.test.tsx b/src/renderer/src/components/automations/use-external-automation-scope-retention.test.tsx
deleted file mode 100644
index 10f6265e05a..00000000000
--- a/src/renderer/src/components/automations/use-external-automation-scope-retention.test.tsx
+++ /dev/null
@@ -1,140 +0,0 @@
-// @vitest-environment happy-dom
-
-import { act } from 'react'
-import { createRoot, type Root } from 'react-dom/client'
-import { afterEach, beforeEach, describe, expect, it, vi } from 'vitest'
-import type { AutomationOwnerRef } from '../../../../shared/automation-owner-ref'
-import type { AutomationHostCatalogEntry } from './automation-host-catalog-types'
-import { useExternalAutomationScopeRetention } from './use-external-automation-scope-retention'
-
-const retainExternalScopes =
- vi.fn<(request: { owners: readonly AutomationOwnerRef[] }) => Promise>()
-
-let container: HTMLDivElement
-let root: Root
-
-function entry(overrides: Partial = {}): AutomationHostCatalogEntry {
- return {
- stableRef: { authority: { kind: 'desktop' }, selector: { kind: 'self' } },
- owner: { authority: { kind: 'desktop' }, selector: { kind: 'self' } },
- stableKey: 'host:desktop:self',
- label: 'This computer',
- authorityLabel: 'This computer',
- kind: 'self',
- catalogState: 'authoritative',
- authorityHealth: 'fresh',
- executionHealth: 'connected',
- querySupport: 'scoped',
- ...overrides
- }
-}
-
-function sshEntry(targetId: string, targetGeneration = 3): AutomationHostCatalogEntry {
- return entry({
- stableRef: { authority: { kind: 'desktop' }, selector: { kind: 'ssh', targetId } },
- owner: {
- authority: { kind: 'desktop' },
- selector: { kind: 'ssh', targetId, targetGeneration }
- },
- stableKey: `host:desktop:ssh:${targetId}`,
- label: targetId,
- kind: 'ssh'
- })
-}
-
-const runtimeEntry = entry({
- stableRef: { authority: { kind: 'runtime', environmentId: 'env-1' }, selector: { kind: 'self' } },
- owner: {
- authority: { kind: 'runtime', environmentId: 'env-1', pairingRevision: 1 },
- selector: { kind: 'self' }
- },
- stableKey: 'host:runtime:env-1:self',
- label: 'Build box'
-})
-
-function Harness({ entries }: { entries: readonly AutomationHostCatalogEntry[] }): null {
- useExternalAutomationScopeRetention(entries)
- return null
-}
-
-function render(entries: readonly AutomationHostCatalogEntry[]): void {
- act(() => {
- root.render()
- })
-}
-
-function retainedOwners(callIndex: number): readonly AutomationOwnerRef[] {
- return retainExternalScopes.mock.calls[callIndex]?.[0].owners ?? []
-}
-
-beforeEach(() => {
- container = document.createElement('div')
- document.body.appendChild(container)
- root = createRoot(container)
- retainExternalScopes.mockReset()
- retainExternalScopes.mockResolvedValue(undefined)
- Object.assign(window, { api: { automations: { retainExternalScopes } } })
-})
-
-afterEach(() => {
- container.remove()
-})
-
-describe('useExternalAutomationScopeRetention', () => {
- it('retains only the hosts whose managers are actually listed', () => {
- render([entry(), runtimeEntry, sshEntry('t1')])
-
- expect(retainExternalScopes).toHaveBeenCalledTimes(1)
- expect(retainedOwners(0)).toEqual([
- { authority: { kind: 'desktop' }, selector: { kind: 'self' } },
- {
- authority: { kind: 'desktop' },
- selector: { kind: 'ssh', targetId: 't1', targetGeneration: 3 }
- }
- ])
- act(() => root.unmount())
- })
-
- it('does not re-retain the same scope set when it re-renders', () => {
- render([entry(), sshEntry('t1')])
- render([entry(), sshEntry('t1')])
-
- expect(retainExternalScopes).toHaveBeenCalledTimes(1)
- act(() => root.unmount())
- })
-
- it('drops a host as soon as the filter moves off it', () => {
- render([entry(), sshEntry('t1')])
- render([sshEntry('t1')])
-
- expect(retainExternalScopes).toHaveBeenCalledTimes(2)
- expect(retainedOwners(1)).toEqual([
- {
- authority: { kind: 'desktop' },
- selector: { kind: 'ssh', targetId: 't1', targetGeneration: 3 }
- }
- ])
- act(() => root.unmount())
- })
-
- it('re-retains when a host is re-added under a new incarnation', () => {
- render([sshEntry('t1', 3)])
- render([sshEntry('t1', 4)])
-
- expect(retainExternalScopes).toHaveBeenCalledTimes(2)
- expect(retainedOwners(1)).toEqual([
- {
- authority: { kind: 'desktop' },
- selector: { kind: 'ssh', targetId: 't1', targetGeneration: 4 }
- }
- ])
- act(() => root.unmount())
- })
-
- it('retains nothing once the page unmounts', () => {
- render([entry()])
- act(() => root.unmount())
-
- expect(retainedOwners(retainExternalScopes.mock.calls.length - 1)).toEqual([])
- })
-})
diff --git a/src/renderer/src/components/browser-favicon.test.tsx b/src/renderer/src/components/browser-favicon.test.tsx
index 991f71807d7..fd47287073a 100644
--- a/src/renderer/src/components/browser-favicon.test.tsx
+++ b/src/renderer/src/components/browser-favicon.test.tsx
@@ -27,24 +27,6 @@ it('retries a failed icon after a same-origin reload completes', () => {
expect(view.container.querySelector('img')).not.toBeNull()
})
-it('shows a loading spinner throughout a reload', () => {
- const view = render(icon())
- view.rerender(icon(true))
- expect(view.container.querySelector('img')).toBeNull()
- expect(view.container.firstElementChild?.getAttribute('class')).toContain(
- 'motion-safe:animate-spin'
- )
- view.rerender(icon(false))
- expect(view.container.querySelector('img')?.getAttribute('src')).toBe(faviconUrl)
-})
-
-it('shows the favicon when initial loading finishes', () => {
- const view = render(icon(true))
- expect(view.container.querySelector('img')).toBeNull()
- view.rerender(icon(false))
- expect(view.container.querySelector('img')).not.toBeNull()
-})
-
it('still resets failures when the favicon URL changes or clears', () => {
const view = render(icon())
fireEvent.error(view.container.querySelector('img')!)
diff --git a/src/renderer/src/components/browser-pane/ClientHostedBrowserPagePane.dead-guest.test.tsx b/src/renderer/src/components/browser-pane/ClientHostedBrowserPagePane.dead-guest.test.tsx
index 794085b891f..30b1f23b1c6 100644
--- a/src/renderer/src/components/browser-pane/ClientHostedBrowserPagePane.dead-guest.test.tsx
+++ b/src/renderer/src/components/browser-pane/ClientHostedBrowserPagePane.dead-guest.test.tsx
@@ -154,17 +154,6 @@ describe('client-hosted browser pane over a dead guest', () => {
})
})
- it('stops the spinner it inherited from a page that died mid-load', () => {
- webview.getURL.mockImplementation(() => {
- throw invalidGuestInstanceId()
- })
- const onUpdatePageState = vi.fn()
-
- render(paneElement(true, { browserTab: page({ loading: true }), onUpdatePageState }))
-
- expect(onUpdatePageState).toHaveBeenCalledWith('page-a', { loading: false })
- })
-
it('flips to the unavailable notice when the guest renderer goes away after attach', () => {
const onUpdatePageState = vi.fn()
render(paneElement(true, { browserTab: page({ loading: true }), onUpdatePageState }))
@@ -208,22 +197,6 @@ describe('client-hosted browser pane over a dead guest', () => {
expect(webview.reload).not.toHaveBeenCalled()
})
- it('does not freeze silently when a navigation event finds the guest gone', () => {
- const onUpdatePageState = vi.fn()
- render(paneElement(true, { onUpdatePageState }))
- onUpdatePageState.mockClear()
- webview.getURL.mockImplementation(() => {
- throw invalidGuestInstanceId()
- })
-
- act(() => {
- webview.dispatchEvent(new Event('did-navigate'))
- })
-
- expect(screen.getByText('Client-hosted browser unavailable')).toBeTruthy()
- expect(onUpdatePageState).toHaveBeenCalledWith('page-a', { loading: false })
- })
-
it('stops the spinner when the guest dies as a load starts', () => {
const onUpdatePageState = vi.fn()
render(paneElement(true, { onUpdatePageState }))
@@ -253,52 +226,6 @@ describe('client-hosted browser pane over a dead guest', () => {
expect(screen.getByText('Client-hosted browser unavailable')).toBeTruthy()
})
- it('uses one guarded title read when the next read would find the guest gone', () => {
- const onUpdatePageState = vi.fn()
- render(paneElement(true, { onUpdatePageState }))
- onUpdatePageState.mockClear()
- const readTitle = vi.fn(() => {
- webview.getTitle = vi.fn(() => {
- throw invalidGuestInstanceId()
- })
- return 'Last live title'
- })
- webview.getTitle = readTitle
-
- expect(() => act(() => webview.dispatchEvent(new Event('did-navigate')))).not.toThrow()
- expect(readTitle).toHaveBeenCalledTimes(1)
- expect(webview.getTitle).not.toHaveBeenCalled()
- expect(onUpdatePageState).toHaveBeenCalledWith(
- 'page-a',
- expect.objectContaining({ title: 'Last live title' })
- )
- })
-
- it('shows unavailability when a load-failure fallback finds the guest gone', () => {
- const onUpdatePageState = vi.fn()
- render(paneElement(true, { onUpdatePageState }))
- webview.getURL.mockImplementation(() => {
- throw invalidGuestInstanceId()
- })
-
- act(() => webview.dispatchEvent(new Event('did-fail-load')))
-
- expect(screen.getByText('Client-hosted browser unavailable')).toBeTruthy()
- expect(onUpdatePageState.mock.calls.at(-1)).toEqual(['page-a', { loading: false }])
- })
-
- it('removes loss listeners when the initial guest read fails', () => {
- const removeListener = vi.spyOn(webview, 'removeEventListener')
- webview.getURL.mockImplementation(() => {
- throw invalidGuestInstanceId()
- })
-
- render(paneElement(true))
-
- expect(removeListener).toHaveBeenCalledWith('destroyed', expect.any(Function))
- expect(removeListener).toHaveBeenCalledWith('render-process-gone', expect.any(Function))
- })
-
it('stops listening for guest loss once the pane lets go of the tag', () => {
const onUpdatePageState = vi.fn()
const view = render(paneElement(true, { onUpdatePageState }))
diff --git a/src/renderer/src/components/browser-pane/ClientHostedBrowserPagePane.drag-focus.test.tsx b/src/renderer/src/components/browser-pane/ClientHostedBrowserPagePane.drag-focus.test.tsx
index bca8ea4e25c..723dd7471e9 100644
--- a/src/renderer/src/components/browser-pane/ClientHostedBrowserPagePane.drag-focus.test.tsx
+++ b/src/renderer/src/components/browser-pane/ClientHostedBrowserPagePane.drag-focus.test.tsx
@@ -121,15 +121,6 @@ describe.each([
cleanup()
})
- it('focuses the guest when the tab activates outside a drag', () => {
- const { focus } = createGuest()
- const view = render(paneElement(false))
-
- view.rerender(paneElement(true))
-
- expect(focus).toHaveBeenCalledTimes(1)
- })
-
// Guest focus blurs the embedder, triggering the drag’s missed-end fallback and aborting its own preview activation.
it('leaves the guest unfocused while a drag holds guests click-through', () => {
const { focus } = createGuest()
diff --git a/src/renderer/src/components/browser-pane/ClientHostedBrowserPagePane.markup.test.tsx b/src/renderer/src/components/browser-pane/ClientHostedBrowserPagePane.markup.test.tsx
index d639ab4b8d9..743e80e9d59 100644
--- a/src/renderer/src/components/browser-pane/ClientHostedBrowserPagePane.markup.test.tsx
+++ b/src/renderer/src/components/browser-pane/ClientHostedBrowserPagePane.markup.test.tsx
@@ -185,25 +185,6 @@ describe('client-hosted screenshot markup', () => {
expect(overlay()).toBeNull()
})
- it.each(['pending', 'unavailable', 'inactive', 'failed'])(
- 'disables Draw for a %s pane',
- (state) => {
- const pane = renderPane(
- {
- ...(state === 'pending' ? { placement: null } : {}),
- ...(state === 'inactive' ? { isActive: false } : {})
- },
- state !== 'unavailable'
- )
- if (state === 'failed') {
- fireEvent(pane.webview, new Event('destroyed'))
- }
- expect(drawButton().disabled).toBe(true)
- fireEvent.click(drawButton())
- expect(mocks.capture).not.toHaveBeenCalled()
- }
- )
-
it.each(['cancel', 'deactivate', 'replace', 'loss', 'unmount'])(
'invalidates an in-flight capture on %s',
async (action) => {
diff --git a/src/renderer/src/components/browser-pane/ClientHostedBrowserPagePane.popup-notices.test.tsx b/src/renderer/src/components/browser-pane/ClientHostedBrowserPagePane.popup-notices.test.tsx
deleted file mode 100644
index 79ecdda5799..00000000000
--- a/src/renderer/src/components/browser-pane/ClientHostedBrowserPagePane.popup-notices.test.tsx
+++ /dev/null
@@ -1,109 +0,0 @@
-// @vitest-environment happy-dom
-import { act, cleanup, render } from '@testing-library/react'
-import { afterEach, beforeEach, describe, expect, it, vi } from 'vitest'
-
-const toastMocks = vi.hoisted(() => ({
- loading: vi.fn(),
- success: vi.fn(),
- error: vi.fn(),
- message: vi.fn()
-}))
-
-vi.mock('sonner', () => ({ toast: toastMocks }))
-
-import { TooltipProvider } from '@/components/ui/tooltip'
-import { installClientHostedPaneApi, paneChannel } from './client-hosted-browser-pane-test-rig'
-import { ClientHostedBrowserPagePane } from './ClientHostedBrowserPagePane'
-
-type PopupEvent = {
- browserPageId: string
- origin: string
- action: 'opened-in-orca' | 'opened-external' | 'blocked'
-}
-
-let popups = paneChannel()
-
-beforeEach(() => {
- popups = paneChannel()
- installClientHostedPaneApi({ browser: { onPopup: popups.subscribe } })
-})
-
-afterEach(() => {
- cleanup()
- vi.clearAllMocks()
-})
-
-function renderPane(): void {
- render(
-
-
-
- )
-}
-
-function emitPopup(overrides: Partial = {}): void {
- const event: PopupEvent = {
- browserPageId: 'page-a',
- origin: 'https://accounts.example.com',
- action: 'blocked',
- ...overrides
- }
- act(() => popups.emit(event))
-}
-
-describe('ClientHostedBrowserPagePane popup notices', () => {
- it('names the origin whose popup was refused', () => {
- renderPane()
-
- emitPopup()
-
- expect(toastMocks.message).toHaveBeenCalledWith(
- 'https://accounts.example.com tried to open a popup Orca does not support here.',
- { id: 'browser-popup:page-a:blocked:https://accounts.example.com' }
- )
- })
-
- it('silences in-Orca opens but reports external opens', () => {
- renderPane()
-
- emitPopup({ action: 'opened-in-orca' })
- expect(toastMocks.message).not.toHaveBeenCalled()
- emitPopup({ action: 'opened-external' })
- expect(toastMocks.message).toHaveBeenCalledExactlyOnceWith(
- 'https://accounts.example.com opened a new window in your default browser.',
- { id: 'browser-popup:page-a:opened-external:https://accounts.example.com' }
- )
- })
-
- it('ignores popups belonging to another page', () => {
- renderPane()
-
- emitPopup({ browserPageId: 'page-b' })
-
- expect(toastMocks.message).not.toHaveBeenCalled()
- })
-})
diff --git a/src/renderer/src/components/browser-pane/ClientHostedBrowserPagePane.test.tsx b/src/renderer/src/components/browser-pane/ClientHostedBrowserPagePane.test.tsx
index 19a355f5a94..c123add3e30 100644
--- a/src/renderer/src/components/browser-pane/ClientHostedBrowserPagePane.test.tsx
+++ b/src/renderer/src/components/browser-pane/ClientHostedBrowserPagePane.test.tsx
@@ -67,93 +67,6 @@ describe('ClientHostedBrowserPagePane', () => {
})
afterEach(() => cleanup())
- it('attaches the exact retained guest once and keeps focus changes local', () => {
- const { webview, focus } = createWebview()
- const detach = vi.fn()
- mocks.attach.mockReturnValue(retainedAttachment(webview, detach))
- const onUpdatePageState = vi.fn()
- const onSetUrl = vi.fn()
- const view = render(
-
- )
-
- expect(mocks.attach).toHaveBeenCalledTimes(1)
- expect(mocks.attach).toHaveBeenCalledWith(
- { browserPageId: 'page-a', pageHostGeneration: 7 },
- expect.any(HTMLElement)
- )
- view.rerender(
-
- )
-
- expect(mocks.attach).toHaveBeenCalledTimes(1)
- expect(focus).toHaveBeenCalledTimes(1)
- view.unmount()
- expect(detach).toHaveBeenCalledTimes(1)
- })
-
- it('updates local chrome from the retained guest navigation', () => {
- const { webview, setUrl, setTitle } = createWebview()
- mocks.attach.mockReturnValue(retainedAttachment(webview))
- const onUpdatePageState = vi.fn()
- const onSetUrl = vi.fn()
- render(
-
- )
- onUpdatePageState.mockClear()
- onSetUrl.mockClear()
- setUrl('https://remote.internal/path')
- setTitle('Remote page')
-
- act(() => webview.dispatchEvent(new Event('did-navigate')))
-
- expect(onSetUrl).toHaveBeenCalledWith('page-a', 'https://remote.internal/path', {
- preserveLoadError: true
- })
- expect(onUpdatePageState).toHaveBeenCalledWith(
- 'page-a',
- expect.objectContaining({
- title: 'Remote page',
- loading: false,
- canGoBack: true,
- canGoForward: false
- })
- )
- expect((screen.getByLabelText('Address') as HTMLInputElement).value).toBe(
- 'https://remote.internal/path'
- )
- })
-
it('searches non-URL address input like the local pane instead of forcing a host', () => {
const { webview } = createWebview()
mocks.attach.mockReturnValue(retainedAttachment(webview))
@@ -285,38 +198,6 @@ describe('ClientHostedBrowserPagePane', () => {
expect(document.querySelector('webview')).toBeNull()
})
- it('escapes an unrenderable page to a NEW server-placed page at its last committed URL', async () => {
- mocks.attach.mockReturnValue(null)
- mocks.createBrowserTab.mockClear()
-
- render(
-
- )
-
- expect(screen.getByText(/Signed-in and other transient page state may differ/)).not.toBeNull()
- await act(async () => {
- screen.getByRole('button', { name: 'Reopen on server' }).click()
- })
-
- expect(mocks.createBrowserTab).toHaveBeenCalledWith({
- worktreeId: 'worktree-a',
- environmentId: 'environment-a',
- url: 'https://remote.internal/path',
- placementPreference: 'server',
- focusOnCreate: true
- })
- })
-
it('requests the one-time intro tour on the first active client-hosted page', async () => {
vi.useFakeTimers()
const { useAppStore } = await import('@/store')
@@ -406,45 +287,6 @@ describe('ClientHostedBrowserPagePane', () => {
vi.useRealTimers()
}
})
-
- it('publishes full guest metadata through the exact runtime placement', async () => {
- const { webview, setUrl, setTitle } = createWebview()
- mocks.attach.mockReturnValue(retainedAttachment(webview))
- render(
-
- )
- setUrl('https://remote.internal/path')
- setTitle('Remote page')
-
- act(() => webview.dispatchEvent(new Event('did-navigate')))
-
- await vi.waitFor(() => expect(mocks.publishMetadata).toHaveBeenCalledTimes(2))
- expect(mocks.publishMetadata).toHaveBeenLastCalledWith({
- environmentId: 'environment-a',
- params: {
- browserHostClientId: 'host-a',
- browserHostGeneration: 3,
- browserPageId: 'page-a',
- pageHostGeneration: 7,
- revision: 2,
- url: 'https://remote.internal/path',
- title: 'Remote page',
- loading: false,
- canGoBack: true,
- canGoForward: false
- }
- })
- })
})
describe('ClientHostedBrowserPagePane address bar parity', () => {
@@ -510,32 +352,6 @@ describe('ClientHostedBrowserPagePane address bar parity', () => {
expect(focus).not.toHaveBeenCalled()
})
- it('still hands focus to the guest when the tab opens on a real page', () => {
- const { webview, focus, setUrl } = createWebview()
- // Why: the attach is mocked, so place the guest where the real attach would put it.
- document.body.appendChild(webview)
- setUrl('https://remote.internal/path')
- mocks.attach.mockReturnValue(retainedAttachment(webview))
-
- render(
-
- )
- act(() => flushFrames())
-
- expect(focus).toHaveBeenCalledTimes(1)
- expect(document.activeElement).not.toBe(screen.getByLabelText('Address'))
- })
-
it('gives the guest focus back after the palette hands the address bar a turn', () => {
const { webview, focus, setUrl } = createWebview()
// Why: the attach is mocked, so place the guest where the real attach would put it.
@@ -605,34 +421,6 @@ describe('ClientHostedBrowserPagePane address bar parity', () => {
expect(blur).toHaveBeenCalled()
expect(document.activeElement).toBe(screen.getByLabelText('Address'))
})
-
- it('files guest navigations into the URL history the address bar suggests from', () => {
- const { webview, setUrl, setTitle } = createWebview()
- mocks.attach.mockReturnValue(retainedAttachment(webview))
- render(
-
- )
- // Why: the initial sync sees about:blank, which never belongs in history.
- expect(useAppStore.getState().browserUrlHistory).toHaveLength(0)
-
- setUrl('https://remote.internal/docs')
- setTitle('Remote docs')
- act(() => webview.dispatchEvent(new Event('did-navigate')))
-
- expect(useAppStore.getState().browserUrlHistory).toEqual([
- expect.objectContaining({ url: 'https://remote.internal/docs', title: 'Remote docs' })
- ])
- })
})
function page(): BrowserPage {
diff --git a/src/renderer/src/components/browser-pane/ReopenBrowserPageOnServerButton.test.tsx b/src/renderer/src/components/browser-pane/ReopenBrowserPageOnServerButton.test.tsx
index ca1264d7da8..7d802303a96 100644
--- a/src/renderer/src/components/browser-pane/ReopenBrowserPageOnServerButton.test.tsx
+++ b/src/renderer/src/components/browser-pane/ReopenBrowserPageOnServerButton.test.tsx
@@ -1,6 +1,6 @@
// @vitest-environment happy-dom
import '@testing-library/jest-dom/vitest'
-import { act, cleanup, fireEvent, render, screen } from '@testing-library/react'
+import { cleanup, fireEvent, render, screen } from '@testing-library/react'
import { afterEach, describe, expect, it, vi } from 'vitest'
const reopenMocks = vi.hoisted(() => ({ reopenBrowserPageOnServer: vi.fn() }))
@@ -29,68 +29,7 @@ function renderButton(): HTMLElement {
return screen.getByRole('button')
}
-// Test DOM does not resolve Tailwind invisible; inspect both class and accessibility state.
-function shown(text: string): boolean {
- const label = screen.getByText(text)
- return !label.className.includes('invisible') && label.getAttribute('aria-hidden') === 'false'
-}
-
describe('ReopenBrowserPageOnServerButton', () => {
- it('swaps in a spinner label once the remote round-trip outlasts the defer window', async () => {
- vi.useFakeTimers()
- let settle = (): void => {}
- reopenMocks.reopenBrowserPageOnServer.mockImplementation(
- () =>
- new Promise((resolve) => {
- settle = () => resolve(true)
- })
- )
- const button = renderButton()
-
- fireEvent.click(button)
-
- expect(button).toBeDisabled()
- expect(button).toHaveAttribute('aria-busy', 'true')
- expect(shown('Reopening…')).toBe(false)
-
- await act(async () => {
- await vi.advanceTimersByTimeAsync(200)
- })
-
- expect(shown('Reopening…')).toBe(true)
- expect(shown('Reopen on server')).toBe(false)
-
- await act(async () => {
- settle()
- await Promise.resolve()
- })
-
- expect(button).not.toBeDisabled()
- expect(button).toHaveAttribute('aria-busy', 'false')
- expect(shown('Reopen on server')).toBe(true)
- expect(shown('Reopening…')).toBe(false)
- })
-
- it('never flashes the spinner for a round-trip that settles quickly', async () => {
- vi.useFakeTimers()
- reopenMocks.reopenBrowserPageOnServer.mockResolvedValue(true)
- const button = renderButton()
-
- await act(async () => {
- fireEvent.click(button)
- await vi.advanceTimersByTimeAsync(0)
- })
-
- expect(shown('Reopening…')).toBe(false)
-
- await act(async () => {
- await vi.advanceTimersByTimeAsync(1_000)
- })
-
- expect(shown('Reopening…')).toBe(false)
- expect(button).not.toBeDisabled()
- })
-
it('rejects a second click while the first is still running', () => {
reopenMocks.reopenBrowserPageOnServer.mockImplementation(() => new Promise(() => {}))
const button = renderButton()
diff --git a/src/renderer/src/components/browser-pane/annotate/GrabConfirmationSheet.test.ts b/src/renderer/src/components/browser-pane/annotate/GrabConfirmationSheet.test.ts
deleted file mode 100644
index 7877d9d803b..00000000000
--- a/src/renderer/src/components/browser-pane/annotate/GrabConfirmationSheet.test.ts
+++ /dev/null
@@ -1,105 +0,0 @@
-import { describe, expect, it } from 'vitest'
-import { formatGrabPayloadAsText } from './GrabConfirmationSheet'
-import type { BrowserGrabPayload } from '../../../../../shared/browser-grab-types'
-
-function makeTestPayload(overrides?: Partial): BrowserGrabPayload {
- return {
- page: {
- sanitizedUrl: 'https://example.com/pricing',
- title: 'Pricing - Example',
- viewportWidth: 1280,
- viewportHeight: 720,
- scrollX: 0,
- scrollY: 0,
- devicePixelRatio: 2,
- capturedAt: '2026-04-10T00:00:00.000Z'
- },
- target: {
- tagName: 'button',
- selector: 'main section:nth-of-type(2) button.primary',
- textSnippet: 'Start free trial',
- htmlSnippet: '',
- attributes: { class: 'primary', type: 'button' },
- accessibility: {
- role: 'button',
- accessibleName: 'Start free trial',
- ariaLabel: null,
- ariaLabelledBy: null
- },
- rectViewport: { x: 400, y: 300, width: 148, height: 44 },
- rectPage: { x: 400, y: 300, width: 148, height: 44 },
- computedStyles: {
- display: 'inline-flex',
- position: 'relative',
- width: '148px',
- height: '44px',
- margin: '0px',
- padding: '12px 24px',
- color: 'rgb(255, 255, 255)',
- backgroundColor: 'rgb(99, 102, 241)',
- border: '0px none',
- borderRadius: '8px',
- fontFamily: 'Inter, sans-serif',
- fontSize: '16px',
- fontWeight: '600',
- lineHeight: '20px',
- textAlign: 'center',
- zIndex: 'auto'
- }
- },
- nearbyText: ['Pro', '$29/month', 'Unlimited projects'],
- ancestorPath: ['section', 'main', 'body'],
- screenshot: null,
- ...overrides
- }
-}
-
-describe('formatGrabPayloadAsText', () => {
- it('formats a complete payload with all sections', () => {
- const text = formatGrabPayloadAsText(makeTestPayload())
-
- expect(text).toContain('Attached browser context from https://example.com/pricing')
- expect(text).toContain('Selected element:')
- expect(text).toContain('button')
- expect(text).toContain('Accessible name: "Start free trial"')
- expect(text).toContain('Selector: main section:nth-of-type(2) button.primary')
- expect(text).toContain('148x44')
- expect(text).toContain('Nearby context:')
- expect(text).toContain('- Pro')
- expect(text).toContain('- $29/month')
- expect(text).toContain('HTML:')
- expect(text).toContain('')
- })
-
- it('omits nearby context section when empty', () => {
- const text = formatGrabPayloadAsText(makeTestPayload({ nearbyText: [] }))
- expect(text).not.toContain('Nearby context:')
- })
-
- it('omits text content section when empty', () => {
- const payload = makeTestPayload()
- payload.target.textSnippet = ''
- const text = formatGrabPayloadAsText(payload)
- expect(text).not.toContain('Text content:')
- })
-
- it('includes computed styles that differ from defaults', () => {
- const text = formatGrabPayloadAsText(makeTestPayload())
- expect(text).toContain('Computed styles:')
- expect(text).toContain('display: inline-flex')
- expect(text).toContain('position: relative')
- expect(text).toContain('font-size: 16px')
- })
-
- it('includes ancestor path', () => {
- const text = formatGrabPayloadAsText(makeTestPayload())
- expect(text).toContain('Ancestor path: section > main > body')
- })
-
- it('handles payload with no accessible name', () => {
- const payload = makeTestPayload()
- payload.target.accessibility.accessibleName = null
- const text = formatGrabPayloadAsText(payload)
- expect(text).not.toContain('Accessible name:')
- })
-})
diff --git a/src/renderer/src/components/browser-pane/annotate/MarkupOverlay.test.tsx b/src/renderer/src/components/browser-pane/annotate/MarkupOverlay.test.tsx
index 23055c77086..25b4c29d9a1 100644
--- a/src/renderer/src/components/browser-pane/annotate/MarkupOverlay.test.tsx
+++ b/src/renderer/src/components/browser-pane/annotate/MarkupOverlay.test.tsx
@@ -41,14 +41,6 @@ function stroke(
}
describe('MarkupOverlay canvas pointer wiring', () => {
- it('commits a stroke on release', () => {
- const { canvas, undoButton } = renderOverlay()
-
- stroke(canvas, 'pointerUp')
-
- expect(undoButton).toHaveProperty('disabled', false)
- })
-
it('commits a stroke whose release never arrived once the canvas loses the pointer', () => {
const { canvas, undoButton, redoButton } = renderOverlay()
@@ -60,12 +52,4 @@ describe('MarkupOverlay canvas pointer wiring', () => {
// Only a committed stroke leaves something to redo; a still-held one is just dropped.
expect(redoButton).toHaveProperty('disabled', false)
})
-
- it('discards a stroke whose pointer was cancelled', () => {
- const { canvas, undoButton } = renderOverlay()
-
- stroke(canvas, 'pointerCancel')
-
- expect(undoButton).toHaveProperty('disabled', true)
- })
})
diff --git a/src/renderer/src/components/browser-pane/annotate/browser-grab-toast-owner-cleanup.test.tsx b/src/renderer/src/components/browser-pane/annotate/browser-grab-toast-owner-cleanup.test.tsx
index f8921f4f91d..d1e2c5a6cd6 100644
--- a/src/renderer/src/components/browser-pane/annotate/browser-grab-toast-owner-cleanup.test.tsx
+++ b/src/renderer/src/components/browser-pane/annotate/browser-grab-toast-owner-cleanup.test.tsx
@@ -159,40 +159,6 @@ const screenshot = {
height: 40
} as const
describe('browser grab toast owner', () => {
- it.each(['miss', 'reject'] as const)(
- 'releases sixty-four closed shortcut %s owners',
- async (outcome) => {
- const requests = Array.from({ length: 64 }, () => deferred())
- let index = 0
- extract.mockImplementation(() => requests[index++].promise)
- const bounds: ReturnType['bounds'][] = []
- for (let owner = 0; owner < 64; owner++) {
- const mounted = mount({ id: `page${owner}` })
- bounds.push(mounted.bounds)
- act(() => mounted.view.result.current.handleGrabActionShortcut('c'))
- mounted.view.unmount()
- }
- expect(extract.mock.calls).toEqual(
- Array.from({ length: 64 }, (_, owner) => [{ browserPageId: `page${owner}` }])
- )
- expect(vi.getTimerCount()).toBe(0)
- await act(async () => {
- for (const request of requests) {
- if (outcome === 'miss') {
- request.complete({ ok: false, reason: 'not-ready' })
- } else {
- request.fail(new Error('Guest destroyed'))
- }
- }
- await Promise.resolve()
- })
- expect(writes).not.toHaveBeenCalled()
- expect(imageWrites).not.toHaveBeenCalled()
- expect(state.recordFeatureInteraction).not.toHaveBeenCalled()
- expect(bounds.reduce((total, bound) => total + (bound?.mock.calls.length ?? 0), 0)).toBe(0)
- expect(vi.getTimerCount()).toBe(0)
- }
- )
it.each(['c', 's'] as const)(
'finishes late requested %s delivery without closed presentation',
async (key) => {
@@ -221,38 +187,6 @@ describe('browser grab toast owner', () => {
expect(vi.getTimerCount()).toBe(0)
}
)
- it.each(['c', 's'] as const)(
- 'preserves complete live %s toast and exact two-second lifetime',
- async (key) => {
- const payload = makePayload()
- extract.mockResolvedValue({ ok: true, payload })
- capture.mockResolvedValue({ ok: true, screenshot })
- const { view, bounds, grab } = mount({ strict: true })
- await act(async () => {
- view.result.current.handleGrabActionShortcut(key)
- await Promise.resolve()
- })
- expect(writes.mock.calls).toEqual(key === 'c' ? [[formatGrabPayloadAsText(payload)]] : [])
- expect(imageWrites.mock.calls).toEqual(key === 's' ? [[screenshot.dataUrl]] : [])
- expect(state.recordFeatureInteraction.mock.calls).toEqual([['browser-grab']])
- expect(view.result.current.grabToast).toEqual({
- message: key === 'c' ? 'Copied' : 'Screenshotted',
- type: 'success',
- x: 50,
- y: 0,
- below: false,
- payload
- })
- expect(bounds).toHaveBeenCalledTimes(1)
- expect(vi.getTimerCount()).toBe(1)
- act(() => vi.advanceTimersByTime(1999))
- expect(view.result.current.grabToast?.type).toBe('success')
- act(() => vi.advanceTimersByTime(1))
- expect(view.result.current.grabToast).toBeNull()
- expect(grab.rearm).not.toHaveBeenCalled()
- expect(vi.getTimerCount()).toBe(0)
- }
- )
it.each(['miss', 'reject', 'screenshot-reject'] as const)(
'preserves live %s feedback and cleanup',
async (outcome) => {
diff --git a/src/renderer/src/components/browser-pane/annotate/markup-drawing-model.test.ts b/src/renderer/src/components/browser-pane/annotate/markup-drawing-model.test.ts
index fe6e21b4722..94844bd25a2 100644
--- a/src/renderer/src/components/browser-pane/annotate/markup-drawing-model.test.ts
+++ b/src/renderer/src/components/browser-pane/annotate/markup-drawing-model.test.ts
@@ -1,21 +1,13 @@
import { describe, expect, it } from 'vitest'
import {
- arrowHeadGeometry,
canRedo,
- canUndo,
- clearShapes,
commitShape,
createMarkupDocument,
- isEmptyDocument,
- normalizeRect,
redoShape,
- scaleShape,
setShapes,
undoShape,
- type ArrowShape,
type MarkupShape,
- type PenShape,
- type TextShape
+ type PenShape
} from './markup-drawing-model'
function pen(id: string): PenShape {
@@ -23,23 +15,6 @@ function pen(id: string): PenShape {
}
describe('markup document undo/redo', () => {
- it('starts empty', () => {
- const doc = createMarkupDocument()
- expect(doc.shapes).toHaveLength(0)
- expect(isEmptyDocument(doc)).toBe(true)
- expect(canUndo(doc)).toBe(false)
- expect(canRedo(doc)).toBe(false)
- })
-
- it('commits shapes in order and enables undo', () => {
- let doc = createMarkupDocument()
- doc = commitShape(doc, pen('a'))
- doc = commitShape(doc, pen('b'))
- expect(doc.shapes.map((s) => s.id)).toEqual(['a', 'b'])
- expect(canUndo(doc)).toBe(true)
- expect(canRedo(doc)).toBe(false)
- })
-
it('undoes and redoes in order', () => {
let doc = createMarkupDocument()
doc = commitShape(doc, pen('a'))
@@ -62,21 +37,6 @@ describe('markup document undo/redo', () => {
expect(canRedo(doc)).toBe(false)
})
- it('undo/redo on empty document are no-ops returning the same reference', () => {
- const doc = createMarkupDocument()
- expect(undoShape(doc)).toBe(doc)
- expect(redoShape(doc)).toBe(doc)
- })
-
- it('clears shapes, and is a no-op (same reference) when already empty', () => {
- const empty = createMarkupDocument()
- expect(clearShapes(empty)).toBe(empty)
- let doc = commitShape(empty, pen('a'))
- doc = clearShapes(doc)
- expect(doc.shapes).toHaveLength(0)
- expect(canRedo(doc)).toBe(false)
- })
-
it('undoes an edit (not just an add) via whole-list snapshots', () => {
let doc = commitShape(createMarkupDocument(), pen('a'))
doc = setShapes(doc, [])
@@ -86,79 +46,5 @@ describe('markup document undo/redo', () => {
})
})
-describe('markup geometry', () => {
- it('normalizes rectangles from any drag direction', () => {
- expect(normalizeRect({ x: 10, y: 20 }, { x: 4, y: 50 })).toEqual({
- x: 4,
- y: 20,
- width: 6,
- height: 30
- })
- })
-
- it('scales pen points and width', () => {
- const shape: PenShape = {
- id: 'a',
- kind: 'pen',
- color: '#fff',
- width: 4,
- points: [
- { x: 2, y: 3 },
- { x: 4, y: 5 }
- ]
- }
- const scaled = scaleShape(shape, 2) as PenShape
- expect(scaled.width).toBe(8)
- expect(scaled.points).toEqual([
- { x: 4, y: 6 },
- { x: 8, y: 10 }
- ])
- })
-
- it('scales arrow endpoints and text position + font size', () => {
- const arrow: ArrowShape = {
- id: 'a',
- kind: 'arrow',
- color: '#fff',
- width: 3,
- from: { x: 1, y: 1 },
- to: { x: 3, y: 5 }
- }
- const scaledArrow = scaleShape(arrow, 3) as ArrowShape
- expect(scaledArrow.from).toEqual({ x: 3, y: 3 })
- expect(scaledArrow.to).toEqual({ x: 9, y: 15 })
- expect(scaledArrow.width).toBe(9)
-
- const text: TextShape = {
- id: 't',
- kind: 'text',
- color: '#fff',
- at: { x: 10, y: 20 },
- text: 'fix',
- fontSize: 18
- }
- const scaledText = scaleShape(text, 2) as TextShape
- expect(scaledText.at).toEqual({ x: 20, y: 40 })
- expect(scaledText.fontSize).toBe(36)
- })
-
- it('returns null arrowhead for a zero-length segment', () => {
- expect(arrowHeadGeometry({ x: 5, y: 5 }, { x: 5, y: 5 }, 4)).toBeNull()
- })
-
- it('produces a symmetric arrowhead pointing at the tip', () => {
- const head = arrowHeadGeometry({ x: 0, y: 0 }, { x: 10, y: 0 }, 4)
- expect(head).not.toBeNull()
- if (!head) {
- return
- }
- expect(head.tip).toEqual({ x: 10, y: 0 })
- // Wings sit behind the tip (smaller x) and mirror across the horizontal axis.
- expect(head.left.x).toBeLessThan(10)
- expect(head.right.x).toBeLessThan(10)
- expect(head.left.y).toBeCloseTo(-head.right.y, 6)
- })
-})
-
const _exhaustive: MarkupShape['kind'][] = ['pen', 'highlight', 'arrow', 'rect', 'ellipse', 'text']
void _exhaustive
diff --git a/src/renderer/src/components/browser-pane/annotate/markup-gesture.test.ts b/src/renderer/src/components/browser-pane/annotate/markup-gesture.test.ts
index a2cdfeac2f1..12532004935 100644
--- a/src/renderer/src/components/browser-pane/annotate/markup-gesture.test.ts
+++ b/src/renderer/src/components/browser-pane/annotate/markup-gesture.test.ts
@@ -6,8 +6,7 @@ import {
redoShape,
undoShape,
type MarkupPoint,
- type PenShape,
- type TextShape
+ type PenShape
} from './markup-drawing-model'
import {
applyDocumentCommand,
@@ -80,14 +79,6 @@ describe('erase gesture', () => {
expect(undoShape(after.doc).shapes.map((shape) => shape.id)).toEqual(['older', 'newer'])
})
- it('keeps a click a click when a tap jitters by a fraction of a pixel', () => {
- const pressed = erase(editorWith(line('older', 0), line('newer', 0)), [{ x: 50, y: 0 }])
- const jittered = moveGesture(pressed, 1, { x: 50.6, y: 0.4 }, noText)
-
- expect(jittered).toBe(pressed)
- expect(ids(endGesture(jittered, 1))).toEqual(['older'])
- })
-
it('keeps a click a click when the pointer wanders inside the slop and back', () => {
const before = editorWith(line('older', 0), line('newer', 0), line('near', 12))
// `near` is out of reach of the press point but within reach 3.5px below it.
@@ -101,15 +92,6 @@ describe('erase gesture', () => {
expect(ids(endGesture(wandered, 1))).toEqual(['older', 'near'])
})
- it('becomes a drag once the pointer leaves the slop', () => {
- const dragged = erase(editorWith(line('older', 0), line('newer', 0)), [
- { x: 50, y: 0 },
- { x: 54, y: 0 }
- ])
-
- expect(erasedIds(dragged)).toEqual(new Set(['older', 'newer']))
- })
-
it('erases every mark under the press point once the click becomes a drag', () => {
const before = editorWith(line('older', 0), line('newer', 0), line('away', 200))
// The drag leaves the marks behind straight away, so only the press point touched them.
@@ -162,35 +144,6 @@ describe('erase gesture', () => {
expect(ids(after)).toEqual(['a'])
})
- it('keeps the same erased set while a drag hits nothing new', () => {
- const begun = beginEraseGesture(editorWith(line('a', 0)), 1, { x: 50, y: 0 }, noText)
- const moved = moveGesture(begun, 1, { x: 50, y: 300 }, noText)
-
- expect(erasedIds(begun)).toEqual(new Set(['a']))
- expect(erasedIds(moved)).toBe(erasedIds(begun))
- })
-
- it('erases a text label the drag passes through', () => {
- const label: TextShape = {
- id: 'label',
- kind: 'text',
- color: '#111827',
- at: { x: 200, y: 200 },
- text: 'note',
- fontSize: 18
- }
- const inkBox = () => ({ x: 200, y: 200, width: 60, height: 20 })
- const before: MarkupEditorState = {
- doc: commitShape(createMarkupDocument(), label),
- gesture: null
- }
- const begun = beginEraseGesture(before, 1, { x: 100, y: 210 }, inkBox)
- const after = endGesture(moveGesture(begun, 1, { x: 230, y: 210 }, inkBox), 1)
-
- expect(erasedIds(begun)).toEqual(new Set())
- expect(ids(after)).toEqual([])
- })
-
it('ignores a second pointer while a gesture is in flight', () => {
const first = erase(editorWith(line('a', 0), line('b', 100)), [{ x: 50, y: 0 }], 1)
@@ -231,30 +184,6 @@ describe('erase gesture', () => {
})
describe('draw gesture', () => {
- it('keeps every point of a freehand stroke', () => {
- const begun = beginDrawGesture(editorWith(), 1, {
- id: 'pen',
- kind: 'highlight',
- color: '#eab308',
- width: 4,
- points: [{ x: 0, y: 0 }]
- })
- const moved = [
- { x: 10, y: 5 },
- { x: 20, y: 0 }
- ].reduce((state, point) => moveGesture(state, 1, point, noText), begun)
-
- expect(endGesture(moved, 1).doc.shapes).toMatchObject([
- {
- points: [
- { x: 0, y: 0 },
- { x: 10, y: 5 },
- { x: 20, y: 0 }
- ]
- }
- ])
- })
-
it('commits a stroke whose release was lost and starts afresh on the next press', () => {
const stale = moveGesture(
beginDrawGesture(editorWith(), 1, line('old', 0)),
@@ -321,16 +250,6 @@ describe('draw gesture', () => {
}
)
- it('lets an eraser click take a mark where a shape was pressed without dragging', () => {
- const at = { x: 50, y: 0 }
- const clicked = endGesture(
- beginDrawGesture(editorWith(line('a', 0)), 1, pressedShape('rect', at)),
- 1
- )
-
- expect(ids(endGesture(erase(clicked, [at]), 1))).toEqual([])
- })
-
it('still saves a pen tap, which leaves a visible dot', () => {
const tapped = endGesture(
beginDrawGesture(editorWith(), 1, { ...line('dot', 0), points: [{ x: 50, y: 0 }] }),
diff --git a/src/renderer/src/components/browser-pane/annotate/markup-screenshot-compose.test.ts b/src/renderer/src/components/browser-pane/annotate/markup-screenshot-compose.test.ts
index 0f4c5869bbf..246b28d9274 100644
--- a/src/renderer/src/components/browser-pane/annotate/markup-screenshot-compose.test.ts
+++ b/src/renderer/src/components/browser-pane/annotate/markup-screenshot-compose.test.ts
@@ -1,31 +1,7 @@
import { describe, expect, it } from 'vitest'
-import {
- clampMarkupScale,
- dataUrlByteLength,
- effectiveMarkupScale,
- markupCanvasSize
-} from './markup-screenshot-compose'
-
-describe('clampMarkupScale', () => {
- it('keeps sane scales and clamps to [1, 4]', () => {
- expect(clampMarkupScale(2)).toBe(2)
- expect(clampMarkupScale(0.5)).toBe(1)
- expect(clampMarkupScale(10)).toBe(4)
- })
-
- it('guards against non-finite / non-positive values', () => {
- expect(clampMarkupScale(0)).toBe(1)
- expect(clampMarkupScale(-3)).toBe(1)
- expect(clampMarkupScale(Number.NaN)).toBe(1)
- })
-})
+import { markupCanvasSize } from './markup-screenshot-compose'
describe('markupCanvasSize', () => {
- it('sizes the output to the content box times the (clamped) scale', () => {
- expect(markupCanvasSize(800, 600, 2)).toEqual({ width: 1600, height: 1200 })
- expect(markupCanvasSize(800, 600, 0.5)).toEqual({ width: 800, height: 600 })
- })
-
it('keeps the composite within the pixel budget (never over)', () => {
// A large HiDPI pane: 4000×3000 CSS × dpr 2 = 48M px > the ~33.55M (32×1024×1024) ceiling.
const maxPixels = 32 * 1024 * 1024
@@ -34,30 +10,3 @@ describe('markupCanvasSize', () => {
expect(size.width / size.height).toBeCloseTo(4000 / 3000, 3)
})
})
-
-describe('effectiveMarkupScale', () => {
- it('returns the clamped scale when the composite fits the pixel budget', () => {
- expect(effectiveMarkupScale(800, 600, 2, 32 * 1024 * 1024)).toBe(2)
- })
-
- it('reduces the scale so area stays within the pixel budget', () => {
- const scale = effectiveMarkupScale(4000, 3000, 2, 32 * 1024 * 1024)
- expect(scale).toBeLessThan(2)
- expect(4000 * scale * (3000 * scale)).toBeLessThanOrEqual(32 * 1024 * 1024 + 1)
- })
-
- it('defaults to the clamped scale with no pixel budget', () => {
- expect(effectiveMarkupScale(3840, 2160, 2)).toBe(2)
- })
-})
-
-describe('dataUrlByteLength', () => {
- it('decodes the base64 payload size', () => {
- expect(dataUrlByteLength('data:image/png;base64,aGk=')).toBe(2)
- expect(dataUrlByteLength('data:image/png;base64,bWFu')).toBe(3)
- })
-
- it('returns 0 for a malformed data url', () => {
- expect(dataUrlByteLength('not-a-data-url')).toBe(0)
- })
-})
diff --git a/src/renderer/src/components/browser-pane/annotate/markup-shape-hit-test.test.ts b/src/renderer/src/components/browser-pane/annotate/markup-shape-hit-test.test.ts
index e6eedb0f4c5..9ee654adee6 100644
--- a/src/renderer/src/components/browser-pane/annotate/markup-shape-hit-test.test.ts
+++ b/src/renderer/src/components/browser-pane/annotate/markup-shape-hit-test.test.ts
@@ -1,5 +1,5 @@
import { describe, expect, it } from 'vitest'
-import { arrowHeadGeometry, type MarkupPoint, type MarkupShape } from './markup-drawing-model'
+import type { MarkupPoint, MarkupShape } from './markup-drawing-model'
import { shapesTouchedBySweep, topmostShapeAt } from './markup-shape-hit-test'
// Pinned here on purpose: how close the pointer must come is part of the behaviour.
@@ -71,21 +71,6 @@ describe('shapesTouchedBySweep', () => {
expect(touches({ ...base, kind: 'pen', width: 4, points }, edge)).toBe(false)
})
- it('hits an arrow on its head wings as well as its shaft', () => {
- const from = { x: 0, y: 0 }
- const to = { x: 200, y: 0 }
- const arrow: MarkupShape = { ...base, kind: 'arrow', width: 8, from, to }
- const head = arrowHeadGeometry(from, to, 8)
- expect(head).not.toBeNull()
- // The wing tips sit well off the shaft, so only the head geometry can match them.
- for (const wing of head ? [head.left, head.right] : []) {
- expect(Math.abs(wing.y)).toBeGreaterThan(4 + ERASER_RADIUS)
- expect(touches(arrow, wing)).toBe(true)
- }
- expect(touches(arrow, { x: 100, y: 4 + ERASER_RADIUS })).toBe(true)
- expect(touches(arrow, { x: 100, y: 4 + ERASER_RADIUS + 1 })).toBe(false)
- })
-
it('hits a rectangle on its border but not in its hollow interior', () => {
const rect: MarkupShape = {
...base,
diff --git a/src/shared/ephemeral-vm-runtime-store-rollback.test.ts b/src/shared/ephemeral-vm-runtime-store-rollback.test.ts
index ce36709999e..d2bd379205c 100644
--- a/src/shared/ephemeral-vm-runtime-store-rollback.test.ts
+++ b/src/shared/ephemeral-vm-runtime-store-rollback.test.ts
@@ -1,19 +1,9 @@
-import {
- existsSync,
- mkdtempSync,
- readFileSync,
- rmSync,
- statSync,
- truncateSync,
- utimesSync,
- writeFileSync
-} from 'node:fs'
+import { mkdtempSync, readFileSync, rmSync, truncateSync, writeFileSync } from 'node:fs'
import { tmpdir } from 'node:os'
import { join } from 'node:path'
import { afterEach, describe, expect, it } from 'vitest'
import {
getEphemeralVmRuntimeFeatureStorePath,
- restoreRuntimeFeatureList,
MAX_EPHEMERAL_VM_RUNTIME_FEATURE_STORE_FILE_BYTES
} from './ephemeral-vm-runtime-feature-store'
import {
@@ -121,60 +111,6 @@ describe('ephemeral VM runtime store rollback projection', () => {
expect(listEphemeralVmRuntimes(userDataPath)).toEqual([provisioned, ordinary])
})
- it('keeps ordinary v1 bytes and sidecar behavior unchanged', () => {
- const userDataPath = makeUserDataPath()
- const runtime = runtimeRecord()
- const expected = JSON.stringify(
- EphemeralVmRuntimeStoreSchema.parse({ version: 1, runtimes: [runtime] })
- )
-
- upsertEphemeralVmRuntime(userDataPath, runtime)
-
- expect(readFileSync(getEphemeralVmRuntimeStorePath(userDataPath), 'utf8')).toBe(expected)
- expect(existsSync(getEphemeralVmRuntimeFeatureStorePath(userDataPath))).toBe(false)
- })
-
- it('projects an explicit ordinary checkout mode without changing its current meaning', () => {
- const userDataPath = makeUserDataPath()
- const runtime = runtimeRecord({
- recipe: { ...runtimeRecord().recipe!, checkoutMode: 'orca-worktree' }
- })
-
- upsertEphemeralVmRuntime(userDataPath, runtime)
-
- const persisted = JSON.parse(readFileSync(getEphemeralVmRuntimeStorePath(userDataPath), 'utf8'))
- expect(RollbackEphemeralVmRuntimeStoreSchema.safeParse(persisted).success).toBe(true)
- expect(listEphemeralVmRuntimes(userDataPath)).toEqual([runtime])
- })
-
- it('does not rewrite unchanged features when runtime order differs from feature order', () => {
- const userDataPath = makeUserDataPath()
- const older = {
- ...provisionedRootRecord(),
- id: 'a-runtime',
- recipeId: 'a-recipe',
- createdAt: 1_000
- }
- const newer = {
- ...provisionedRootRecord(),
- id: 'z-runtime',
- recipeId: 'z-recipe',
- createdAt: 2_000
- }
- upsertEphemeralVmRuntime(userDataPath, older)
- upsertEphemeralVmRuntime(userDataPath, newer)
- const featurePath = getEphemeralVmRuntimeFeatureStorePath(userDataPath)
- const oldTimestamp = new Date('2020-01-01T00:00:00.000Z')
- utimesSync(featurePath, oldTimestamp, oldTimestamp)
- const beforeBytes = readFileSync(featurePath, 'utf8')
- const beforeMtime = statSync(featurePath).mtimeMs
-
- updateEphemeralVmRuntimeStatus(userDataPath, newer.id, { status: 'suspended' })
-
- expect(readFileSync(featurePath, 'utf8')).toBe(beforeBytes)
- expect(statSync(featurePath).mtimeMs).toBe(beforeMtime)
- })
-
it('migrates current-main poisoned bytes when they are first read', () => {
const userDataPath = makeUserDataPath()
const poisoned = {
@@ -287,30 +223,3 @@ describe('ephemeral VM runtime store rollback projection', () => {
])
})
})
-
-describe('runtime feature restoration scaling', () => {
- it('indexes feature identities once and preserves unmatched runtime references', () => {
- let reads = 0
- const runtimes = Array.from({ length: 1000 }, (_, i) => runtimeRecord({ id: `runtime-${i}` }))
- const features = runtimes.map((runtime) => ({
- get id() {
- reads++
- return runtime.id
- },
- recipeId: runtime.recipeId,
- createdAt: runtime.createdAt,
- recipeCheckoutMode: 'provisioned-root' as const
- }))
- const restored = restoreRuntimeFeatureList(runtimes, features)
- expect(reads).toBe(1000)
- expect(restored.map((runtime) => runtime.id)).toEqual(runtimes.map((runtime) => runtime.id))
- expect(restored.every((runtime) => runtime.recipe?.checkoutMode === 'provisioned-root')).toBe(
- true
- )
- expect(restoreRuntimeFeatureList([runtimes[0]], [])[0]).toBe(runtimes[0])
- const first = { ...features[0], recipeCheckoutMode: 'orca-worktree' as const }
- expect(
- restoreRuntimeFeatureList([runtimes[0]], [first, features[0]])[0].recipe?.checkoutMode
- ).toBe('orca-worktree')
- })
-})
diff --git a/src/shared/errno-code.test.ts b/src/shared/errno-code.test.ts
deleted file mode 100644
index 236673a3f39..00000000000
--- a/src/shared/errno-code.test.ts
+++ /dev/null
@@ -1,13 +0,0 @@
-import { describe, expect, it } from 'vitest'
-import { errnoCodeOrUnknown } from './errno-code'
-
-describe('errnoCodeOrUnknown', () => {
- it.each([
- ['a plain error', new Error('boom')],
- ['a non-errno code', Object.assign(new Error('x'), { code: 'ERR_INVALID_ARG_TYPE' })],
- ['a numeric code', Object.assign(new Error('x'), { code: 11 })],
- ['a non-error throw', 'EAGAIN']
- ])('reports unknown for %s', (_label, error) => {
- expect(errnoCodeOrUnknown(error)).toBe('unknown')
- })
-})
diff --git a/src/shared/event-loop-yield.test.ts b/src/shared/event-loop-yield.test.ts
deleted file mode 100644
index 0bbba1b36fd..00000000000
--- a/src/shared/event-loop-yield.test.ts
+++ /dev/null
@@ -1,54 +0,0 @@
-import { afterEach, describe, expect, it, vi } from 'vitest'
-import { getPendingRendererYieldCountForTesting, yieldToEventLoop } from './event-loop-yield'
-
-afterEach(() => {
- vi.unstubAllEnvs()
- vi.unstubAllGlobals()
-})
-
-describe('yieldToEventLoop', () => {
- it('uses setImmediate in Node runtimes', async () => {
- const scheduleImmediate = vi.fn((callback: () => void) => queueMicrotask(callback))
- vi.stubEnv('VITEST', 'false')
- vi.stubGlobal('window', undefined)
- vi.stubGlobal('setImmediate', scheduleImmediate)
-
- await yieldToEventLoop()
-
- expect(scheduleImmediate).toHaveBeenCalledOnce()
- })
-
- it('releases callbacks during sustained concurrent renderer yields', async () => {
- const postMessage = vi.fn()
- let peakPendingAfterResolution = 0
- vi.stubEnv('VITEST', 'false')
- vi.stubGlobal('window', {})
- vi.stubGlobal(
- 'MessageChannel',
- class {
- port1: { onmessage: ((event: MessageEvent) => void) | null } = { onmessage: null }
- port2 = {
- postMessage: (data: unknown): void => {
- postMessage(data)
- setTimeout(() => this.port1.onmessage?.({ data } as MessageEvent), 0)
- }
- }
- }
- )
-
- const runProducer = async (): Promise => {
- for (let index = 0; index < 20; index += 1) {
- await yieldToEventLoop()
- peakPendingAfterResolution = Math.max(
- peakPendingAfterResolution,
- getPendingRendererYieldCountForTesting()
- )
- }
- }
- await Promise.all([runProducer(), runProducer()])
-
- expect(postMessage).toHaveBeenCalledTimes(40)
- expect(peakPendingAfterResolution).toBeLessThanOrEqual(1)
- expect(getPendingRendererYieldCountForTesting()).toBe(0)
- })
-})
diff --git a/src/shared/execution-host-registry.test.ts b/src/shared/execution-host-registry.test.ts
index 0bb5798c1b7..8243011b749 100644
--- a/src/shared/execution-host-registry.test.ts
+++ b/src/shared/execution-host-registry.test.ts
@@ -1,62 +1,8 @@
import { describe, expect, it } from 'vitest'
-import { getExecutionHostLabel } from './execution-host'
-import { MIN_COMPATIBLE_RUNTIME_SERVER_VERSION, RUNTIME_PROTOCOL_VERSION } from './protocol-version'
+
import { buildExecutionHostRegistry } from './execution-host-registry'
-const LOCAL_HOST_LABEL = getExecutionHostLabel('local')
-
describe('execution host registry', () => {
- it('returns only the local host for local-only state', () => {
- expect(
- buildExecutionHostRegistry({
- repos: [{ connectionId: null }],
- settings: { activeRuntimeEnvironmentId: null }
- })
- ).toEqual([
- {
- id: 'local',
- kind: 'local',
- label: LOCAL_HOST_LABEL,
- detail: 'This computer',
- health: 'local'
- }
- ])
- })
-
- it('includes saved and repo-derived SSH hosts with connection health', () => {
- const hosts = buildExecutionHostRegistry({
- repos: [{ connectionId: 'repo-ssh' }],
- settings: { activeRuntimeEnvironmentId: null },
- sshTargetLabels: new Map([['saved-ssh', 'Saved SSH']]),
- sshConnectionStates: new Map([
- [
- 'repo-ssh',
- {
- targetId: 'repo-ssh',
- status: 'connected',
- error: null,
- reconnectAttempt: 0
- }
- ],
- [
- 'saved-ssh',
- {
- targetId: 'saved-ssh',
- status: 'auth-failed',
- error: 'Permission denied',
- reconnectAttempt: 1
- }
- ]
- ])
- })
-
- expect(hosts).toMatchObject([
- { id: 'local', health: 'local' },
- { id: 'ssh:saved-ssh', label: 'Saved SSH', health: 'error', connectionStatus: 'auth-failed' },
- { id: 'ssh:repo-ssh', label: 'repo-ssh', health: 'available', connectionStatus: 'connected' }
- ])
- })
-
it('excludes repository references from configured-only registries', () => {
const hosts = buildExecutionHostRegistry({
repos: [
@@ -76,31 +22,6 @@ describe('execution host registry', () => {
])
})
- it('keeps repository references in the default reference-inclusive registry', () => {
- const hosts = buildExecutionHostRegistry({
- repos: [
- { connectionId: 'removed-ssh' },
- { connectionId: null, executionHostId: 'runtime:removed-runtime' }
- ],
- settings: { activeRuntimeEnvironmentId: null }
- })
-
- expect(hosts.map((host) => host.id)).toEqual([
- 'local',
- 'runtime:removed-runtime',
- 'ssh:removed-ssh'
- ])
- })
-
- it('hides machine-provider SSH targets the same way', () => {
- const hosts = buildExecutionHostRegistry({
- repos: [{ connectionId: 'machine-0123', executionHostId: 'ssh:machine-0123' }],
- settings: { activeRuntimeEnvironmentId: null },
- sshTargetLabels: new Map([['machine-0123', 'omarchy-dev']])
- })
- expect(hosts.some((h) => h.id.includes('machine-0123'))).toBe(false)
- })
-
it('hides runtime-owned (ephemeral VM) SSH targets from repo-derived hosts', () => {
const hosts = buildExecutionHostRegistry({
// A VM-backed repo carries the hidden runtime-owned target on both fields.
@@ -135,296 +56,4 @@ describe('execution host registry', () => {
expect(hosts.map((h) => h.id)).toEqual(['local', 'runtime:env-1'])
})
-
- it('adds saved runtime environments and preserves compatibility state per host', () => {
- const hosts = buildExecutionHostRegistry({
- repos: [],
- settings: { activeRuntimeEnvironmentId: 'old-server' },
- runtimeEnvironments: [{ id: 'builder', name: 'Linux Builder' }],
- runtimeStatusByEnvironmentId: new Map([
- [
- 'builder',
- {
- checkedAt: 0,
- appVersion: '1.8.0',
- status: {
- runtimeId: 'runtime-builder',
- rendererGraphEpoch: 1,
- graphStatus: 'ready',
- authoritativeWindowId: 1,
- liveTabCount: 0,
- liveLeafCount: 0,
- runtimeProtocolVersion: RUNTIME_PROTOCOL_VERSION,
- minCompatibleRuntimeClientVersion: 1,
- capabilities: ['terminal.binary-stream.v1'],
- hostPlatform: 'linux'
- }
- }
- ],
- [
- 'old-server',
- {
- checkedAt: 0,
- appVersion: '1.6.0',
- status: {
- runtimeId: 'runtime-old',
- rendererGraphEpoch: 1,
- graphStatus: 'ready',
- authoritativeWindowId: 1,
- liveTabCount: 0,
- liveLeafCount: 0,
- runtimeProtocolVersion: MIN_COMPATIBLE_RUNTIME_SERVER_VERSION - 1,
- minCompatibleRuntimeClientVersion: 1,
- capabilities: []
- }
- }
- ]
- ])
- })
-
- expect(hosts).toMatchObject([
- { id: 'local', health: 'local' },
- {
- id: 'runtime:builder',
- label: 'Linux Builder',
- health: 'available',
- appVersion: '1.8.0',
- protocolVersion: RUNTIME_PROTOCOL_VERSION,
- capabilities: ['terminal.binary-stream.v1'],
- platform: 'linux',
- compatibility: { kind: 'ok' }
- },
- {
- id: 'runtime:old-server',
- label: 'old-server',
- health: 'blocked',
- appVersion: '1.6.0',
- compatibility: { kind: 'blocked', reason: 'server-too-old' }
- }
- ])
- })
-
- it('uses shared-control diagnostics to show reconnecting runtime host health', () => {
- const hosts = buildExecutionHostRegistry({
- repos: [],
- settings: { activeRuntimeEnvironmentId: null },
- runtimeEnvironments: [{ id: 'dev-box', name: 'Dev Box' }],
- runtimeStatusByEnvironmentId: new Map([
- [
- 'dev-box',
- {
- checkedAt: 0,
- status: {
- runtimeId: 'runtime-dev',
- rendererGraphEpoch: 1,
- graphStatus: 'ready',
- authoritativeWindowId: 1,
- liveTabCount: 0,
- liveLeafCount: 0,
- remoteControl: {
- state: 'reconnecting',
- pendingRequestCount: 0,
- subscriptionCount: 2,
- reconnectAttempt: 1,
- lastConnectedAt: 123,
- lastClose: { code: 1006, reason: '' },
- lastError: 'Remote Orca runtime closed the connection.'
- }
- }
- }
- ]
- ])
- })
-
- expect(hosts).toMatchObject([
- { id: 'local', health: 'local' },
- {
- id: 'runtime:dev-box',
- label: 'Dev Box',
- health: 'connecting',
- remoteControlState: { state: 'reconnecting', subscriptionCount: 2 }
- }
- ])
- })
-
- it('treats ready shared-control diagnostics without a status payload as available', () => {
- const hosts = buildExecutionHostRegistry({
- repos: [],
- settings: { activeRuntimeEnvironmentId: null },
- runtimeEnvironments: [{ id: 'dev-box', name: 'Dev Box' }],
- runtimeStatusByEnvironmentId: new Map([
- [
- 'dev-box',
- {
- checkedAt: 0,
- status: null,
- remoteControl: {
- state: 'ready',
- pendingRequestCount: 0,
- subscriptionCount: 1,
- reconnectAttempt: 0,
- lastConnectedAt: 123,
- lastClose: null,
- lastError: null
- }
- }
- ]
- ])
- })
-
- expect(hosts).toMatchObject([
- { id: 'local', health: 'local' },
- {
- id: 'runtime:dev-box',
- label: 'Dev Box',
- health: 'available',
- remoteControlState: { state: 'ready' }
- }
- ])
- })
-
- it('preserves runtime environment source on runtime hosts', () => {
- const hosts = buildExecutionHostRegistry({
- repos: [],
- settings: { activeRuntimeEnvironmentId: null },
- runtimeEnvironments: [{ id: 'vm-runtime', name: 'VM Runtime', source: 'ephemeral-vm' }],
- runtimeStatusByEnvironmentId: new Map([
- [
- 'vm-runtime',
- {
- checkedAt: 0,
- status: {
- runtimeId: 'runtime-vm',
- rendererGraphEpoch: 1,
- graphStatus: 'ready',
- authoritativeWindowId: 1,
- liveTabCount: 0,
- liveLeafCount: 0,
- runtimeProtocolVersion: RUNTIME_PROTOCOL_VERSION,
- minCompatibleRuntimeClientVersion: 1,
- capabilities: ['project-host-setup.v1']
- }
- }
- ]
- ])
- })
-
- expect(hosts).toContainEqual(
- expect.objectContaining({
- id: 'runtime:vm-runtime',
- kind: 'runtime',
- source: 'ephemeral-vm'
- })
- )
- })
-
- it('applies per-host display-label overrides to derived labels', () => {
- const hosts = buildExecutionHostRegistry({
- repos: [{ connectionId: 'repo-ssh' }],
- settings: { activeRuntimeEnvironmentId: null },
- sshTargetLabels: new Map([['repo-ssh', 'Derived SSH']]),
- hostLabelOverrides: new Map([
- ['ssh:repo-ssh', 'Renamed Box'],
- ['local', 'My Laptop']
- ])
- })
-
- expect(hosts).toMatchObject([
- { id: 'local', label: 'My Laptop' },
- { id: 'ssh:repo-ssh', label: 'Renamed Box' }
- ])
- })
-
- it('keeps derived labels for hosts without an override', () => {
- const hosts = buildExecutionHostRegistry({
- repos: [{ connectionId: 'repo-ssh' }],
- settings: { activeRuntimeEnvironmentId: null },
- sshTargetLabels: new Map([['repo-ssh', 'Derived SSH']]),
- hostLabelOverrides: new Map([['ssh:other', 'Unrelated']])
- })
-
- expect(hosts).toMatchObject([
- { id: 'local', label: LOCAL_HOST_LABEL },
- { id: 'ssh:repo-ssh', label: 'Derived SSH' }
- ])
- })
-
- it('keeps runtime hosts checking before their first status result', () => {
- const hosts = buildExecutionHostRegistry({
- repos: [{ connectionId: null, executionHostId: 'runtime:env-2' }],
- settings: { activeRuntimeEnvironmentId: null }
- })
-
- expect(hosts).toMatchObject([
- { id: 'local', health: 'local' },
- { id: 'runtime:env-2', kind: 'runtime', label: 'env-2', health: 'connecting' }
- ])
- })
-
- it('includes runtime hosts from hydrated status even when they are not focused', () => {
- const hosts = buildExecutionHostRegistry({
- repos: [],
- settings: { activeRuntimeEnvironmentId: null },
- runtimeStatusByEnvironmentId: new Map([
- [
- 'gpu',
- {
- checkedAt: 0,
- appVersion: '1.8.0',
- status: {
- runtimeId: 'runtime-gpu',
- rendererGraphEpoch: 1,
- graphStatus: 'ready',
- authoritativeWindowId: 1,
- liveTabCount: 0,
- liveLeafCount: 0,
- runtimeProtocolVersion: RUNTIME_PROTOCOL_VERSION,
- minCompatibleRuntimeClientVersion: 1,
- capabilities: ['project-host-setup.v1'],
- hostPlatform: 'linux'
- }
- }
- ]
- ])
- })
-
- expect(hosts).toMatchObject([
- { id: 'local', health: 'local' },
- {
- id: 'runtime:gpu',
- kind: 'runtime',
- label: 'gpu',
- health: 'available',
- capabilities: ['project-host-setup.v1'],
- platform: 'linux'
- }
- ])
- })
-})
-
-it('keeps an initial unknown-transport verification connecting', () => {
- const hosts = buildExecutionHostRegistry({
- repos: [],
- settings: null,
- runtimeEnvironments: [{ id: 'host', name: 'Host' }],
- runtimeStatusByEnvironmentId: new Map([
- [
- 'host',
- {
- checkedAt: 0,
- status: null,
- snapshot: {
- environmentId: 'host',
- pairingRevision: 1,
- sequence: 1,
- checkedAt: 0,
- status: null,
- verification: 'checking',
- transport: 'unknown'
- }
- }
- ]
- ])
- })
- expect(hosts.find((host) => host.id === 'runtime:host')?.health).toBe('connecting')
})
diff --git a/src/shared/execution-host.test.ts b/src/shared/execution-host.test.ts
index 1c10fa57e2c..6d661518823 100644
--- a/src/shared/execution-host.test.ts
+++ b/src/shared/execution-host.test.ts
@@ -2,25 +2,15 @@ import { afterEach, describe, expect, it, vi } from 'vitest'
import {
ALL_EXECUTION_HOSTS_SCOPE,
LOCAL_EXECUTION_HOST_ID,
- getConnectionExecutionHostId,
- getExecutionHostLabel,
- getLocalExecutionHostLabel,
getRepoDialableSshTargetId,
getRepoExecutionHostId,
getRepoSshConnectionId,
- getSettingsFocusedExecutionHostId,
getWorktreeExecutionHostId,
- isOwnedSshTargetId,
isRepoOnCatalogHost,
- isRuntimeOwnedSshTargetId,
isUnresolvedOwnerHostId,
- normalizeExecutionHostOrder,
- normalizeExecutionHostScope,
- normalizeVisibleExecutionHostIds,
parseExecutionHostId,
parseRoutableExecutionHostId,
requestedExecutionHostScope,
- toRuntimeExecutionHostId,
toSshExecutionHostId,
UNRESOLVED_OWNER_HOST_ID
} from './execution-host'
@@ -31,49 +21,6 @@ describe('execution host identity', () => {
vi.unstubAllGlobals()
})
- it('normalizes local, SSH, and runtime host ids', () => {
- expect(parseExecutionHostId('local')).toEqual({ kind: 'local', id: 'local' })
- expect(parseExecutionHostId(toSshExecutionHostId('win vm'))).toEqual({
- kind: 'ssh',
- id: 'ssh:win%20vm',
- targetId: 'win vm'
- })
- expect(parseExecutionHostId(toRuntimeExecutionHostId('prod/server'))).toEqual({
- kind: 'runtime',
- id: 'runtime:prod%2Fserver',
- environmentId: 'prod/server'
- })
- })
-
- it('labels the local host by platform and by navigator detection', () => {
- expect(getLocalExecutionHostLabel('darwin')).toBe('Local Mac')
- expect(getLocalExecutionHostLabel('win32')).toBe('Local Windows')
- expect(getLocalExecutionHostLabel('linux')).toBe('Local Linux')
- expect(getLocalExecutionHostLabel('freebsd')).toBe('This computer')
-
- // Exercise navigator detection used by the live host selector.
- vi.stubGlobal('navigator', { userAgent: 'Mozilla/5.0 (Windows NT 10.0; Win64; x64)' })
- expect(getLocalExecutionHostLabel()).toBe('Local Windows')
-
- vi.stubGlobal('navigator', { userAgent: 'Mozilla/5.0 (X11; Linux x86_64)' })
- expect(getLocalExecutionHostLabel()).toBe('Local Linux')
-
- vi.stubGlobal('navigator', { userAgent: 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7)' })
- expect(getLocalExecutionHostLabel()).toBe('Local Mac')
-
- // Compare to the explicit platform fallback so this remains deterministic across CI hosts.
- vi.stubGlobal('navigator', { userAgent: 'totally-unknown-agent' })
- expect(getLocalExecutionHostLabel()).toBe(getLocalExecutionHostLabel(process.platform))
- })
-
- it('falls back invalid scopes to all hosts', () => {
- expect(normalizeExecutionHostScope(null)).toBe(ALL_EXECUTION_HOSTS_SCOPE)
- expect(normalizeExecutionHostScope('')).toBe(ALL_EXECUTION_HOSTS_SCOPE)
- expect(normalizeExecutionHostScope('bogus')).toBe(ALL_EXECUTION_HOSTS_SCOPE)
- expect(normalizeExecutionHostScope('ssh:')).toBe(ALL_EXECUTION_HOSTS_SCOPE)
- expect(normalizeExecutionHostScope('all')).toBe(ALL_EXECUTION_HOSTS_SCOPE)
- })
-
it('defaults an omitted scope request to this host, not a fan-out', () => {
expect(requestedExecutionHostScope(undefined)).toBe(LOCAL_EXECUTION_HOST_ID)
expect(requestedExecutionHostScope(null)).toBe(LOCAL_EXECUTION_HOST_ID)
@@ -84,34 +31,6 @@ describe('execution host identity', () => {
expect(requestedExecutionHostScope('ssh:dev%20box')).toBe('ssh:dev%20box')
})
- it('normalizes visible host id arrays', () => {
- expect(normalizeVisibleExecutionHostIds(null)).toBeNull()
- expect(normalizeVisibleExecutionHostIds([])).toBeNull()
- expect(normalizeVisibleExecutionHostIds(['local', 'bogus', 'ssh:win%20vm', 'local'])).toEqual([
- 'local',
- 'ssh:win%20vm'
- ])
- })
-
- it('normalizes host order arrays', () => {
- expect(normalizeExecutionHostOrder(null)).toEqual([])
- expect(normalizeExecutionHostOrder([])).toEqual([])
- expect(normalizeExecutionHostOrder(['ssh:win%20vm', 'bogus', 'local', 'ssh:win%20vm'])).toEqual(
- ['ssh:win%20vm', 'local']
- )
- })
-
- it('maps a legacy connection id to its host without trimming it', () => {
- expect(getConnectionExecutionHostId(null)).toBe('local')
- expect(getConnectionExecutionHostId('')).toBe('local')
- expect(getConnectionExecutionHostId('a b')).toBe('ssh:a%20b')
- })
-
- it('derives repo ownership from SSH connection ids', () => {
- expect(getRepoExecutionHostId({ connectionId: null })).toBe(LOCAL_EXECUTION_HOST_ID)
- expect(getRepoExecutionHostId({ connectionId: 'ssh-target-1' })).toBe('ssh:ssh-target-1')
- })
-
it('prefers explicit worktree ownership before repo and focused-host fallbacks', () => {
expect(
getWorktreeExecutionHostId(
@@ -157,13 +76,6 @@ describe('execution host identity', () => {
'ssh:runtime-ssh-vm-1'
)
})
-
- it('derives focused host compatibility from active runtime settings', () => {
- expect(getSettingsFocusedExecutionHostId(null)).toBe(LOCAL_EXECUTION_HOST_ID)
- expect(getSettingsFocusedExecutionHostId({ activeRuntimeEnvironmentId: 'runtime-1' })).toBe(
- 'runtime:runtime-1'
- )
- })
})
describe('execution host id delimiter invariant', () => {
@@ -177,17 +89,6 @@ describe('execution host id delimiter invariant', () => {
targetId: 'a|b'
})
})
-
- // An invalid id denotes one unknown host; All hosts would misrepresent its routing scope.
- it('labels an id that names no host as one unknown host, not as every host', () => {
- for (const id of ['ssh:', 'ssh:a|b', 'ssh:%zz', 'runtime:', 'quantum:box'] as const) {
- expect(getExecutionHostLabel(id as never)).toBe('Unknown host')
- }
- expect(getExecutionHostLabel(null)).toBe('Unknown host')
- expect(getExecutionHostLabel(ALL_EXECUTION_HOSTS_SCOPE)).toBe('All hosts')
- expect(getExecutionHostLabel('ssh:box')).toBe('box')
- expect(getExecutionHostLabel('runtime:env-1')).toBe('env-1')
- })
})
describe('unresolved-owner sentinel', () => {
@@ -213,14 +114,3 @@ describe('isRepoOnCatalogHost', () => {
expect(isRepoOnCatalogHost({ executionHostId: 'future:host' })).toBe(false)
})
})
-
-describe('owned SSH target ids', () => {
- it('hides recipe-VM and machine targets but keeps the recipe-VM meaning narrow', () => {
- expect(isOwnedSshTargetId('runtime-ssh-vm-1')).toBe(true)
- expect(isOwnedSshTargetId('machine-0123456789abcdef0123')).toBe(true)
- expect(isOwnedSshTargetId('ssh-1792393612859-abc123')).toBe(false)
- expect(isOwnedSshTargetId(null)).toBe(false)
- // Only recipe VMs carry "replaced every provision" semantics.
- expect(isRuntimeOwnedSshTargetId('machine-0123456789abcdef0123')).toBe(false)
- })
-})
diff --git a/src/shared/export-let-function-initializer-ban.test.ts b/src/shared/export-let-function-initializer-ban.test.ts
deleted file mode 100644
index f8e02de41ea..00000000000
--- a/src/shared/export-let-function-initializer-ban.test.ts
+++ /dev/null
@@ -1,184 +0,0 @@
-import { mkdtempSync, rmSync, writeFileSync } from 'node:fs'
-import { tmpdir } from 'node:os'
-import { join, resolve } from 'node:path'
-import { beforeAll, describe, expect, it } from 'vitest'
-import type { parseAst as ParseAstFn } from 'vite' with { 'resolution-mode': 'import' }
-import { scanSourceTree } from './source-scan/source-tree-scan'
-
-// Dynamic import: vite is ESM-only and this file typechecks under tsconfig.tc.cli.json's node16/CJS.
-let parseAst: typeof ParseAstFn
-
-beforeAll(async () => {
- ;({ parseAst } = await import('vite'))
-})
-
-/** Rolldown folds function-initialized export let bindings into callers, ignoring setter reassignments in built apps.
- * Use local null-initialized impl slots behind exported wrappers (src/main/ipc/pty/delivery/debug.ts); null-initialized exports remain allowed.
- * Use the bundler’s own Oxc parser to detect this hazard. */
-
-type AstNode = {
- type: string
- start?: number
- expression?: AstNode
- expressions?: AstNode[]
- declaration?: AstNode
- kind?: string
- declarations?: {
- id?: { name?: string }
- init?: AstNode | null
- start?: number
- }[]
- specifiers?: { local?: { name?: string } }[]
-}
-
-/** Casts, parens, `!`, and comma sequences around the function don't change what rolldown folds. */
-function unwrapInitializer(node: AstNode): AstNode {
- let current = node
- for (;;) {
- if (
- current.expression &&
- [
- 'ParenthesizedExpression',
- 'TSAsExpression',
- 'TSSatisfiesExpression',
- 'TSTypeAssertion',
- 'TSNonNullExpression'
- ].includes(current.type)
- ) {
- current = current.expression
- continue
- }
- const sequenceTail =
- current.type === 'SequenceExpression' ? current.expressions?.at(-1) : undefined
- if (sequenceTail) {
- current = sequenceTail
- continue
- }
- return current
- }
-}
-
-export type FunctionInitializedExportLet = { name: string; line: number }
-
-export function findFunctionInitializedExportLets(
- fileName: string,
- sourceText: string
-): FunctionInitializedExportLet[] {
- // Cheap prefilter: full parses only for files that could contain the pattern.
- if (!/\bexport\b/.test(sourceText) || !/\blet\b/.test(sourceText)) {
- return []
- }
- const lineOf = (offset: number): number => sourceText.slice(0, offset).split('\n').length
- const program = parseAst(sourceText, {
- lang: fileName.endsWith('.tsx') ? 'tsx' : 'ts'
- }) as unknown as { body: AstNode[] }
- const functionLets: (FunctionInitializedExportLet & { exported: boolean })[] = []
- const exportedNames = new Set()
- const collectLets = (declaration: AstNode | undefined, exported: boolean): void => {
- if (declaration?.type !== 'VariableDeclaration' || declaration.kind !== 'let') {
- return
- }
- for (const declarator of declaration.declarations ?? []) {
- const initializer = declarator.init && unwrapInitializer(declarator.init)
- if (
- initializer &&
- ['ArrowFunctionExpression', 'FunctionExpression'].includes(initializer.type)
- ) {
- functionLets.push({
- name: declarator.id?.name ?? '',
- line: lineOf(declarator.start ?? 0),
- exported
- })
- }
- }
- }
- for (const statement of program.body) {
- if (statement.type === 'ExportNamedDeclaration') {
- collectLets(statement.declaration, true)
- // `let fn = () => {}; export { fn }` is the same live binding — same hazard.
- for (const specifier of statement.specifiers ?? []) {
- if (specifier.local?.name) {
- exportedNames.add(specifier.local.name)
- }
- }
- continue
- }
- collectLets(statement, false)
- }
- return functionLets
- .filter((candidate) => candidate.exported || exportedNames.has(candidate.name))
- .map(({ name, line }) => ({ name, line }))
-}
-
-describe('function-initialized export let ban', () => {
- it('flags the shapes rolldown miscompiles', () => {
- const flagged = [
- 'export let f = () => {}',
- 'export let f = function () {}',
- 'export let f = async () => {}',
- 'export let f = (() => {}) as () => void',
- 'export let f = (() => {})!',
- 'export let f = (0, () => {})',
- 'export let f: (id: string) => void = (_id) => {}',
- 'let f = () => {}\nexport { f }',
- 'let f = () => {}\nexport { f as g }'
- ]
- for (const source of flagged) {
- expect(findFunctionInitializedExportLets('a.ts', source), source).toHaveLength(1)
- }
- })
-
- it('reports the declaration line', () => {
- const source = 'const a = 1\n\nexport let f = () => {}'
- expect(findFunctionInitializedExportLets('a.ts', source)).toEqual([{ name: 'f', line: 3 }])
- })
-
- it('allows the safe shapes', () => {
- const allowed = [
- 'export let f: (() => void) | null = null',
- 'export const f = () => {}',
- 'let f = () => {}',
- 'let f: (() => void) | null = null\nexport { f }',
- 'export let n = 0',
- 'export let f'
- ]
- for (const source of allowed) {
- expect(findFunctionInitializedExportLets('a.ts', source), source).toEqual([])
- }
- })
-
- const repoRoot = resolve(__dirname, '..', '..')
- // Tests deliberately exercise banned shapes and are not Rolldown-bundled; scanSourceTree excludes them.
- const files = scanSourceTree(join(repoRoot, 'src'))
-
- it('scans shipped sources and excludes hazardous test fixtures', () => {
- expect(
- files.some(({ relativePath }) => relativePath === 'main/ipc/pty/delivery/debug.ts')
- ).toBe(true)
- const root = mkdtempSync(join(tmpdir(), 'orca-export-let-'))
- try {
- writeFileSync(join(root, 'bridge.ts'), 'export let bridge = () => {}')
- writeFileSync(join(root, 'bridge.test.ts'), 'export let fixture = () => {}')
-
- const offenders = scanSourceTree(root).flatMap(({ relativePath, source }) =>
- findFunctionInitializedExportLets(relativePath, source)
- )
-
- expect(offenders).toEqual([{ name: 'bridge', line: 1 }])
- } finally {
- rmSync(root, { recursive: true, force: true })
- }
- })
-
- it('has no function-initialized export let in shipped code', () => {
- const offenders = files.flatMap(({ relativePath, source }) =>
- findFunctionInitializedExportLets(relativePath, source).map(
- (offender) => `src/${relativePath}:${offender.line} (${offender.name})`
- )
- )
- expect(
- offenders,
- 'Rolldown miscompiles `export let fn = ` bridges: the initializer is folded into call sites and the setter reassignment is dropped in the built app. Use a module-local null-initialized impl var behind an exported wrapper function instead — see src/main/ipc/pty/delivery/debug.ts.'
- ).toEqual([])
- })
-})
diff --git a/src/shared/external-automation-jobs-file.test.ts b/src/shared/external-automation-jobs-file.test.ts
index 3c9ed7fbd75..a38e64d5a09 100644
--- a/src/shared/external-automation-jobs-file.test.ts
+++ b/src/shared/external-automation-jobs-file.test.ts
@@ -21,20 +21,6 @@ async function tempFile(name: string): Promise {
}
describe('readExternalAutomationJobsFile', () => {
- it('preserves supported jobs shapes below the limits', async () => {
- const wrappedPath = await tempFile('wrapped.json')
- const rootPath = await tempFile('root.json')
- await writeFile(wrappedPath, JSON.stringify({ jobs: [{ id: 'one' }] }))
- await writeFile(rootPath, JSON.stringify([{ id: 'two' }]))
-
- await expect(
- readExternalAutomationJobsFile(wrappedPath, { allowRootArray: false })
- ).resolves.toEqual([{ id: 'one' }])
- await expect(
- readExternalAutomationJobsFile(rootPath, { allowRootArray: true })
- ).resolves.toEqual([{ id: 'two' }])
- })
-
it('rejects oversized sparse files with the explicit memory-limit error', async () => {
const path = await tempFile('oversized.json')
await writeFile(path, '')
diff --git a/src/shared/external-worktree-inbox.test.ts b/src/shared/external-worktree-inbox.test.ts
index dad9f6870de..66bb7675a3f 100644
--- a/src/shared/external-worktree-inbox.test.ts
+++ b/src/shared/external-worktree-inbox.test.ts
@@ -1,22 +1,13 @@
import { describe, expect, it } from 'vitest'
-import type { GlobalSettings } from './global-settings-types'
import type { Repo } from './repo-types'
-import type { DetectedWorktree, DetectedWorktreeListResult, Worktree } from './worktree/types'
+import type { DetectedWorktree, DetectedWorktreeListResult } from './worktree/types'
import {
getHiddenExternalWorktrees,
getHiddenImportableExternalWorktrees,
- getNewExternalWorktreeInboxWorktrees,
- getVisibleExternalWorktrees,
- getVisibleNonOrcaWorktrees,
- mergeExternalWorktreeInboxPaths,
- shouldOfferNewExternalWorktreeInbox
+ getNewExternalWorktreeInboxWorktrees
} from './external-worktree-inbox'
-import {
- buildKnownOrcaWorkspaceLayouts,
- EXTERNAL_WORKTREE_VISIBILITY_ROLLOUT_AT,
- toDetectedWorktree
-} from './worktree/ownership'
+import { EXTERNAL_WORKTREE_VISIBILITY_ROLLOUT_AT } from './worktree/ownership'
const repo: Repo = {
id: 'repo-1',
@@ -63,118 +54,7 @@ function detectedResult(worktrees: DetectedWorktree[]): DetectedWorktreeListResu
}
}
-function makeSettings(): GlobalSettings {
- return {
- workspaceDir: '/orca/workspaces',
- nestWorkspaces: true,
- workspaceDirHistory: [],
- refreshLocalBaseRefOnWorktreeCreate: false,
- localBaseRefSuggestionDismissed: false,
- branchPrefix: 'none',
- branchPrefixCustom: '',
- theme: 'system',
- appFontFamily: 'Geist',
- editorAutoSave: false,
- editorAutoSaveDelayMs: 1000,
- editorMinimapEnabled: false,
- markdownReviewToolsEnabled: true,
- terminalFontSize: 14,
- terminalFontFamily: 'monospace',
- terminalFontWeight: 400,
- terminalLineHeight: 1.2
- } as unknown as GlobalSettings
-}
-
-function makeGitWorktree(overrides: Partial = {}): Worktree {
- return {
- id: `repo-1::${overrides.path ?? '/repo'}`,
- repoId: repo.id,
- path: '/repo',
- displayName: 'repo',
- branch: 'refs/heads/main',
- head: 'abc123',
- isBare: false,
- isMainWorktree: true,
- comment: '',
- linkedIssue: null,
- linkedPR: null,
- linkedLinearIssue: null,
- linkedGitLabMR: null,
- linkedGitLabIssue: null,
- isArchived: false,
- isUnread: false,
- isPinned: false,
- sortOrder: 0,
- lastActivityAt: 0,
- workspaceStatus: 'todo',
- ...overrides
- }
-}
-
describe('external worktree inbox', () => {
- it('merges inbox paths without duplicates when paths match after normalization', () => {
- expect(mergeExternalWorktreeInboxPaths(['/repo/one/'], ['/repo/one', '/repo/two'])).toEqual([
- '/repo/one/',
- '/repo/two'
- ])
- })
-
- it('offers the inbox only after the initial prompt is dismissed and discovery is not suppressed', () => {
- expect(shouldOfferNewExternalWorktreeInbox(repo)).toBe(true)
- expect(
- shouldOfferNewExternalWorktreeInbox({
- ...repo,
- externalWorktreeVisibilityPromptDismissedAt: undefined
- })
- ).toBe(false)
- expect(
- shouldOfferNewExternalWorktreeInbox({
- ...repo,
- externalWorktreeDiscoverySuppressedAt: 1
- })
- ).toBe(false)
- expect(
- shouldOfferNewExternalWorktreeInbox({
- ...repo,
- externalWorktreeVisibility: 'show'
- })
- ).toBe(false)
- })
-
- it('returns only hidden external worktrees outside the inbox baseline', () => {
- const hidden = detectedWorktree({ id: 'hidden', path: '/scratch/new-one' })
- const baselined = detectedWorktree({ id: 'baselined', path: '/scratch/old-one' })
- const detected = detectedResult([
- hidden,
- baselined,
- detectedWorktree({ id: 'visible', visible: true }),
- detectedWorktree({ id: 'orca-managed', ownership: 'orca-managed' })
- ])
-
- expect(getHiddenExternalWorktrees(detected)).toEqual([hidden, baselined])
- expect(
- getNewExternalWorktreeInboxWorktrees(detected, {
- ...repo,
- externalWorktreeInboxBaselinePaths: ['/scratch/old-one']
- })
- ).toEqual([hidden])
- })
-
- it('excludes explicitly visible agent scratch from visibility-control counts', () => {
- const visible = detectedWorktree({ id: 'visible', visible: true })
- const scratch = detectedWorktree({
- id: 'agent-scratch',
- ownership: 'agent-scratch',
- visible: true
- })
-
- expect(getVisibleExternalWorktrees(detectedResult([visible, scratch]))).toEqual([visible])
- expect(getVisibleNonOrcaWorktrees(detectedResult([visible, scratch]))).toEqual([
- visible,
- scratch
- ])
- })
-
it('lists hidden agent scratch among importable worktrees so recovery stays reachable', () => {
// Scratch cannot be revealed by the visibility toggle (#9388); per-path import preserves recovery (#10324).
const hiddenScratch = detectedWorktree({
@@ -205,25 +85,6 @@ describe('external worktree inbox', () => {
expect(getHiddenImportableExternalWorktrees(undefined)).toEqual([])
})
- it('offers metadata-free nested Orca workspace worktrees through the inbox', () => {
- const settings = makeSettings()
- const manual = toDetectedWorktree({
- repo,
- settings,
- worktree: makeGitWorktree({
- path: '/orca/workspaces/orca/manual-from-git',
- displayName: 'manual-from-git',
- branch: 'refs/heads/manual-from-git',
- isMainWorktree: false
- }),
- knownOrcaLayouts: buildKnownOrcaWorkspaceLayouts(settings, repo)
- })
-
- expect(manual.ownership).toBe('external')
- expect(manual.visible).toBe(false)
- expect(getNewExternalWorktreeInboxWorktrees(detectedResult([manual]), repo)).toEqual([manual])
- })
-
it('suppresses non-authoritative detected results', () => {
expect(
getNewExternalWorktreeInboxWorktrees(detectedResult([detectedWorktree()]), {
diff --git a/src/shared/feature-interactions.test.ts b/src/shared/feature-interactions.test.ts
deleted file mode 100644
index bc3be043c09..00000000000
--- a/src/shared/feature-interactions.test.ts
+++ /dev/null
@@ -1,69 +0,0 @@
-import { describe, expect, it } from 'vitest'
-import {
- getFeatureInteractionUsageBucket,
- hasFeatureInteraction,
- normalizeFeatureInteractionTelemetryBuckets,
- normalizeFeatureInteractions
-} from './feature-interactions'
-
-describe('feature interactions', () => {
- it('normalizes persisted records by removing unknown ids and malformed values', () => {
- expect(
- normalizeFeatureInteractions({
- tasks: { firstInteractedAt: 100 },
- browser: { firstInteractedAt: Number.NaN },
- automations: { firstInteractedAt: 200, interactionCount: 3 },
- 'browser-grab': { firstInteractedAt: 250, interactionCount: 0 },
- unknown: { firstInteractedAt: 200 },
- 'voice-dictation': { firstInteractedAt: 300 }
- })
- ).toEqual({
- tasks: { firstInteractedAt: 100, interactionCount: 1 },
- automations: { firstInteractedAt: 200, interactionCount: 3 },
- 'browser-grab': { firstInteractedAt: 250, interactionCount: 1 },
- 'voice-dictation': { firstInteractedAt: 300, interactionCount: 1 }
- })
- })
-
- it('treats only valid known records as interacted', () => {
- expect(
- hasFeatureInteraction({ tasks: { firstInteractedAt: 100, interactionCount: 1 } }, 'tasks')
- ).toBe(true)
- expect(
- hasFeatureInteraction({ tasks: { firstInteractedAt: 100, interactionCount: 1 } }, 'browser')
- ).toBe(false)
- expect(
- hasFeatureInteraction(
- { tasks: { firstInteractedAt: Number.POSITIVE_INFINITY, interactionCount: 1 } },
- 'tasks'
- )
- ).toBe(false)
- })
-
- it('maps interaction counts to the exact top-coded telemetry buckets', () => {
- expect(getFeatureInteractionUsageBucket(0)).toBeNull()
- expect(getFeatureInteractionUsageBucket(1)).toBe('count_1')
- expect(getFeatureInteractionUsageBucket(2)).toBe('count_2')
- expect(getFeatureInteractionUsageBucket(3)).toBe('count_3_4')
- expect(getFeatureInteractionUsageBucket(4)).toBe('count_3_4')
- expect(getFeatureInteractionUsageBucket(5)).toBe('count_5_9')
- expect(getFeatureInteractionUsageBucket(999)).toBe('count_500_999')
- expect(getFeatureInteractionUsageBucket(1000)).toBe('count_1000_plus')
- expect(getFeatureInteractionUsageBucket(1001)).toBe('count_1000_plus')
- })
-
- it('normalizes persisted telemetry bucket markers by removing unknown ids and buckets', () => {
- expect(
- normalizeFeatureInteractionTelemetryBuckets({
- tasks: 'count_1',
- browser: 'count_1000_plus',
- automations: 'count_4',
- unknown: 'count_1',
- 'voice-dictation': null
- })
- ).toEqual({
- tasks: 'count_1',
- browser: 'count_1000_plus'
- })
- })
-})
diff --git a/src/shared/feature-wall-tour-depth.test.ts b/src/shared/feature-wall-tour-depth.test.ts
deleted file mode 100644
index d8a4229ba30..00000000000
--- a/src/shared/feature-wall-tour-depth.test.ts
+++ /dev/null
@@ -1,68 +0,0 @@
-import { describe, expect, it } from 'vitest'
-import type { AgentsStepId } from './agents-orchestration-steps'
-import type { FeatureWallWorkflowId } from './feature-wall-workflows'
-import type { ReviewStepId } from './review-steps'
-import type { WorkbenchStepId } from './workbench-steps'
-import {
- buildFeatureWallTourDepthSummary,
- getFeatureWallTourDepthStep
-} from './feature-wall-tour-depth'
-
-describe('feature wall tour depth summary', () => {
- it('maps workflow and nested steps to canonical depth values', () => {
- expect(getFeatureWallTourDepthStep({ workflowId: 'workspaces' })).toBe('workspaces')
- expect(
- getFeatureWallTourDepthStep({
- workflowId: 'agents-orchestration',
- agentStepId: 'usage'
- })
- ).toBe('agents_usage')
- expect(
- getFeatureWallTourDepthStep({ workflowId: 'workbench', workbenchStepId: 'browser' })
- ).toBe('workbench_browser')
- expect(getFeatureWallTourDepthStep({ workflowId: 'review', reviewStepId: 'ship' })).toBe(
- 'review_ship'
- )
- })
-
- it('builds session-local counts and furthest step from visited sets', () => {
- expect(
- buildFeatureWallTourDepthSummary({
- visitedWorkflows: new Set(['workspaces', 'workbench']),
- visitedAgentSteps: new Set(),
- visitedWorkbenchSteps: new Set(['terminal', 'editor']),
- visitedReviewSteps: new Set(),
- workflowDone: {
- workspaces: true,
- tasks: false,
- 'agents-orchestration': false,
- workbench: false,
- review: false
- },
- agentStepDone: {
- statuses: false,
- usage: false,
- orchestration: false
- },
- workbenchStepDone: {
- terminal: true,
- editor: true,
- browser: false
- },
- reviewStepDone: {
- notes: false,
- 'pr-view': false,
- ship: false
- },
- lastGroupId: 'workbench'
- })
- ).toEqual({
- furthest_step: 'workbench_editor',
- last_group_id: 'workbench',
- visited_workflow_count: 2,
- visited_substep_count: 2,
- completed_workflow_count: 1,
- completed_substep_count: 2
- })
- })
-})
diff --git a/src/shared/feedback-image-limits.test.ts b/src/shared/feedback-image-limits.test.ts
deleted file mode 100644
index 6f222e69dc3..00000000000
--- a/src/shared/feedback-image-limits.test.ts
+++ /dev/null
@@ -1,15 +0,0 @@
-import { describe, expect, it } from 'vitest'
-import { MAX_FEEDBACK_IMAGE_BYTES, MAX_FEEDBACK_IMAGE_TOTAL_BYTES } from './feedback-image-limits'
-
-// Vercel rejects feedback bodies above 4.5 MB with 413 FUNCTION_PAYLOAD_TOO_LARGE (#22466); keep the budget below it.
-const VERCEL_FUNCTION_PAYLOAD_LIMIT_BYTES = 4_500_000
-
-describe('feedback image limits', () => {
- it('keeps the whole attachment budget under the endpoint host request-body limit', () => {
- expect(MAX_FEEDBACK_IMAGE_TOTAL_BYTES).toBeLessThan(VERCEL_FUNCTION_PAYLOAD_LIMIT_BYTES)
- })
-
- it('cannot let one image exceed the whole budget', () => {
- expect(MAX_FEEDBACK_IMAGE_BYTES).toBeLessThanOrEqual(MAX_FEEDBACK_IMAGE_TOTAL_BYTES)
- })
-})
diff --git a/src/shared/file-explorer-display-root.test.ts b/src/shared/file-explorer-display-root.test.ts
index fe57dcb7a50..0a4aa375880 100644
--- a/src/shared/file-explorer-display-root.test.ts
+++ b/src/shared/file-explorer-display-root.test.ts
@@ -1,29 +1,7 @@
import { describe, expect, it } from 'vitest'
-import {
- FILE_EXPLORER_FULL_ROOT,
- migrateExplorerDisplayRoots,
- normalizeExplorerDisplayRootByWorktree
-} from './file-explorer-display-root'
+import { normalizeExplorerDisplayRootByWorktree } from './file-explorer-display-root'
describe('explorer root persistence', () => {
- it('preserves existing sparse worktrees without overriding explicit choices', () => {
- expect(
- migrateExplorerDisplayRoots({ chosen: 'packages/app' }, false, {
- old: { sparseDirectories: ['src'] },
- chosen: { sparseDirectories: ['packages/app'] },
- normal: {}
- })
- ).toEqual({ old: FILE_EXPLORER_FULL_ROOT, chosen: 'packages/app' })
- })
- it('does not seed newly created worktrees on subsequent loads', () => {
- const migrated = migrateExplorerDisplayRoots({}, false, { old: { sparseDirectories: ['src'] } })
- expect(
- migrateExplorerDisplayRoots(migrated, true, {
- old: { sparseDirectories: ['src'] },
- newlyCreated: { sparseDirectories: ['app'] }
- })
- ).toEqual({ old: FILE_EXPLORER_FULL_ROOT })
- })
it('rejects malformed records and unsafe keys', () => {
expect(normalizeExplorerDisplayRootByWorktree(['src'])).toEqual({})
expect(
diff --git a/src/shared/file-name-sort.test.ts b/src/shared/file-name-sort.test.ts
deleted file mode 100644
index ab778c34138..00000000000
--- a/src/shared/file-name-sort.test.ts
+++ /dev/null
@@ -1,61 +0,0 @@
-import { describe, expect, it } from 'vitest'
-import { compareFileNames, sortDirEntries } from './file-name-sort'
-
-describe('compareFileNames', () => {
- it('sorts numeric name segments naturally instead of lexicographically', () => {
- const names = [
- '1 - item.txt',
- '100 - item.txt',
- '2 - item.txt',
- '200 - item.txt',
- '409 - item.txt',
- '41 - item.txt',
- '410 - item.txt',
- '9 - item.txt',
- '99 - item.txt'
- ]
- expect([...names].sort(compareFileNames)).toEqual([
- '1 - item.txt',
- '2 - item.txt',
- '9 - item.txt',
- '41 - item.txt',
- '99 - item.txt',
- '100 - item.txt',
- '200 - item.txt',
- '409 - item.txt',
- '410 - item.txt'
- ])
- })
-
- it('sorts embedded numbers naturally within alphabetical order', () => {
- expect(['b1.md', 'a10.md', 'a2.md', 'a1.md'].sort(compareFileNames)).toEqual([
- 'a1.md',
- 'a2.md',
- 'a10.md',
- 'b1.md'
- ])
- })
-
- it('breaks numeric-collation ties deterministically instead of readdir order', () => {
- expect(['2.txt', '02.txt'].sort(compareFileNames)).toEqual(['02.txt', '2.txt'])
- expect(['02.txt', '2.txt'].sort(compareFileNames)).toEqual(['02.txt', '2.txt'])
- expect(compareFileNames('a.txt', 'a.txt')).toBe(0)
- })
-})
-
-describe('sortDirEntries', () => {
- it('keeps directories first, each group in natural order', () => {
- const entries = [
- { name: '10 - notes', isDirectory: false },
- { name: '2 - src', isDirectory: true },
- { name: '9 - docs.txt', isDirectory: false },
- { name: '10 - assets', isDirectory: true }
- ]
- expect(sortDirEntries(entries).map((e) => e.name)).toEqual([
- '2 - src',
- '10 - assets',
- '9 - docs.txt',
- '10 - notes'
- ])
- })
-})
diff --git a/src/shared/file-preview-kind.test.ts b/src/shared/file-preview-kind.test.ts
deleted file mode 100644
index 2471573e0e8..00000000000
--- a/src/shared/file-preview-kind.test.ts
+++ /dev/null
@@ -1,16 +0,0 @@
-import { describe, expect, it } from 'vitest'
-import { filePreviewForPath } from './file-preview-kind'
-
-describe('filePreviewForPath', () => {
- it.each([
- ['a/b.MP4', { kind: 'video', mimeType: 'video/mp4' }],
- ['a\\b.opus', { kind: 'audio', mimeType: 'audio/ogg' }],
- ['x.avif', { kind: 'image', mimeType: 'image/avif' }],
- ['doc.PDF', { kind: 'pdf', mimeType: 'application/pdf' }],
- ['dir/.mp4', null],
- ['lib.so', null],
- ['notes.txt', null]
- ])('%s', (path, expected) => {
- expect(filePreviewForPath(path)).toEqual(expected)
- })
-})
diff --git a/src/shared/file-write-disk-precondition.test.ts b/src/shared/file-write-disk-precondition.test.ts
index 317a4c8e90d..e7a9ef50b9a 100644
--- a/src/shared/file-write-disk-precondition.test.ts
+++ b/src/shared/file-write-disk-precondition.test.ts
@@ -1,9 +1,5 @@
import { describe, expect, it } from 'vitest'
-import {
- diskBaselineSignatureLength,
- getDiskBaselineSignature,
- utf8ByteSizeCanDecodeToLength
-} from './disk-baseline-signature'
+import { getDiskBaselineSignature } from './disk-baseline-signature'
import {
compareDiskWritePrecondition,
diskConflictFromReadFailure,
@@ -42,16 +38,6 @@ describe('disk write precondition', () => {
expect(compareDiskWritePrecondition(precondition, current, decoded)).toBeNull()
})
- it('reports an external rewrite as changed before checking for U+FFFD', () => {
- expect(
- compareDiskWritePrecondition(
- { expectedSignature: getDiskBaselineSignature('original'), requireLosslessUtf8: true },
- 'rewritten �',
- 'mine'
- )
- ).toBe('changed')
- })
-
it('treats anything but an explicit refusal from a host as a completed write', () => {
expect(parseFileWriteResult({ ok: false, diskConflict: 'not-utf8' })).toEqual({
ok: false,
@@ -74,16 +60,6 @@ describe('disk write precondition', () => {
expect(parseFileWriteResult({ ok: false })).toEqual({ ok: false, diskConflict: 'changed' })
})
- it('bounds the UTF-8 size a baseline can decode from', () => {
- const content = 'a€𝄞'
- const length = diskBaselineSignatureLength(getDiskBaselineSignature(content))
- expect(length).toBe(content.length)
- expect(utf8ByteSizeCanDecodeToLength(Buffer.byteLength(content), length ?? -1)).toBe(true)
- expect(utf8ByteSizeCanDecodeToLength(content.length - 1, content.length)).toBe(false)
- expect(utf8ByteSizeCanDecodeToLength(content.length * 3 + 1, content.length)).toBe(false)
- expect(diskBaselineSignatureLength('not-a-signature')).toBeNull()
- })
-
it.each([
[
'an ENOENT code with plain wording',
@@ -95,17 +71,6 @@ describe('disk write precondition', () => {
expect(diskConflictFromReadFailure(precondition, error)).toBe('missing')
})
- it.each([
- [
- 'the desktop IPC wrapping',
- "Error invoking remote method 'fs:readFile': Error: ENOENT: no such file or directory, open '/repo/a.ts'"
- ],
- ['the runtime wording', "ENOENT: no such file or directory, stat '/repo/a.ts'"]
- ])('reads a not-found from %s', (_label, message) => {
- const precondition = { expectedSignature: getDiskBaselineSignature('base') }
- expect(diskConflictFromReadFailure(precondition, new Error(message))).toBe('missing')
- })
-
it.each([
"EACCES: permission denied, open '/repo/ENOENT.md'",
"EACCES: permission denied, open '/repo/ENOENT/notes.md'",
diff --git a/src/shared/filesystem-watch-batch-window.test.ts b/src/shared/filesystem-watch-batch-window.test.ts
deleted file mode 100644
index 05710c0a5b8..00000000000
--- a/src/shared/filesystem-watch-batch-window.test.ts
+++ /dev/null
@@ -1,34 +0,0 @@
-import { describe, expect, it } from 'vitest'
-import {
- WATCH_BATCH_INTERVAL_MS,
- WATCH_BATCH_LEADING_MS,
- watchBatchFlushDelayMs
-} from './filesystem-watch-batch-window'
-
-describe('watchBatchFlushDelayMs', () => {
- it('uses the leading delay before the first flush', () => {
- expect(watchBatchFlushDelayMs(1_000_000, 0)).toBe(WATCH_BATCH_LEADING_MS)
- })
-
- it('uses the leading delay once a full interval has passed', () => {
- expect(watchBatchFlushDelayMs(1_000 + WATCH_BATCH_INTERVAL_MS, 1_000)).toBe(
- WATCH_BATCH_LEADING_MS
- )
- })
-
- it('waits out the rest of the interval after a recent flush', () => {
- expect(watchBatchFlushDelayMs(1_010, 1_000)).toBe(WATCH_BATCH_INTERVAL_MS - 10)
- })
-
- it('never returns less than the leading delay', () => {
- expect(watchBatchFlushDelayMs(1_090, 1_000)).toBe(WATCH_BATCH_LEADING_MS)
- })
-
- it('never waits longer than one interval when the clock moves backwards', () => {
- expect(watchBatchFlushDelayMs(1_000, 3_600_000)).toBe(WATCH_BATCH_INTERVAL_MS)
- })
-
- it('honours custom windows', () => {
- expect(watchBatchFlushDelayMs(1_000, 950, 5, 200)).toBe(150)
- })
-})
diff --git a/src/shared/filesystem-watch-event-buffer.test.ts b/src/shared/filesystem-watch-event-buffer.test.ts
index cba80ad750d..f0a58d95575 100644
--- a/src/shared/filesystem-watch-event-buffer.test.ts
+++ b/src/shared/filesystem-watch-event-buffer.test.ts
@@ -3,24 +3,6 @@ import type { FsChangeEvent } from './filesystem-entry-types'
import { FileWatchEventBuffer } from './filesystem-watch-event-buffer'
describe('FileWatchEventBuffer', () => {
- it('preserves precise event order and releases a consumed batch', () => {
- const buffer = new FileWatchEventBuffer()
- const events: FsChangeEvent[] = [
- { kind: 'delete', absolutePath: '/repo/old/file.ts' },
- { kind: 'create', absolutePath: '/repo/new/file.ts' },
- {
- kind: 'rename',
- absolutePath: '/repo/new',
- oldAbsolutePath: '/repo/old'
- }
- ]
- buffer.push(events.slice(0, 1))
- buffer.push(events.slice(1))
- expect(buffer.take()).toEqual(events)
- expect(buffer.size).toBe(0)
- expect(buffer.take()).toEqual([])
- })
-
it('retains an explicit overflow until consumed without retaining later paths', () => {
const buffer = new FileWatchEventBuffer()
const overflow: FsChangeEvent = { kind: 'overflow', absolutePath: '/repo' }
diff --git a/src/shared/fish-binary-requirement.test.ts b/src/shared/fish-binary-requirement.test.ts
deleted file mode 100644
index e4d57bbf9e4..00000000000
--- a/src/shared/fish-binary-requirement.test.ts
+++ /dev/null
@@ -1,54 +0,0 @@
-import { describe, expect, it } from 'vitest'
-import {
- fishRequirementViolation,
- REQUIRE_FISH_ENV_VAR,
- resolveFishBinary,
- type FishBinaryLookup
-} from './fish-binary-requirement'
-
-const FOUND: FishBinaryLookup = { available: true, path: '/usr/bin/fish', majorVersion: 4 }
-const MISSING: FishBinaryLookup = {
- available: false,
- path: null,
- majorVersion: 0,
- reason: 'no fish binary on PATH'
-}
-
-describe('fishRequirementViolation', () => {
- it('lets a missing fish skip when the requirement is not set', () => {
- expect(fishRequirementViolation(MISSING, {})).toBeNull()
- expect(fishRequirementViolation(MISSING, { [REQUIRE_FISH_ENV_VAR]: '0' })).toBeNull()
- })
-
- // The #9993 guard is CI's only end-to-end coverage; a skip there is a silent gap.
- it('reports a violation naming the reason when CI requires fish and it is absent', () => {
- const violation = fishRequirementViolation(MISSING, { [REQUIRE_FISH_ENV_VAR]: '1' })
- expect(violation).toContain(REQUIRE_FISH_ENV_VAR)
- expect(violation).toContain('no fish binary on PATH')
- })
-
- it('reports no violation when fish is present, requirement set or not', () => {
- expect(fishRequirementViolation(FOUND, { [REQUIRE_FISH_ENV_VAR]: '1' })).toBeNull()
- expect(fishRequirementViolation(FOUND, {})).toBeNull()
- })
-})
-
-describe('resolveFishBinary', () => {
- it('treats an installed fish below the floor as unavailable, with the version in the reason', () => {
- const lookup = resolveFishBinary(Number.MAX_SAFE_INTEGER)
- if (lookup.available) {
- throw new Error('no fish can satisfy an unreachable version floor')
- }
- // Only when a fish is actually installed does the reason describe a version.
- if (lookup.majorVersion > 0) {
- expect(lookup.reason).toContain(`fish ${Number.MAX_SAFE_INTEGER}+ required`)
- }
- })
-
- it('never reports a path on Windows', () => {
- if (process.platform !== 'win32') {
- return
- }
- expect(resolveFishBinary().path).toBeNull()
- })
-})
diff --git a/src/shared/foreground-process-selection.test.ts b/src/shared/foreground-process-selection.test.ts
index d034f1ccff2..7f6d0861fb8 100644
--- a/src/shared/foreground-process-selection.test.ts
+++ b/src/shared/foreground-process-selection.test.ts
@@ -39,37 +39,6 @@ describe('selectForegroundProcessCandidate', () => {
expect(selectForegroundProcessCandidate(candidates)).toBeNull()
})
-
- it.each([
- { helperStat: 'S+', selectedPid: 102 },
- { helperStat: 'S', selectedPid: 101 }
- ])('prefers foreground processes, then depth ($helperStat)', ({ helperStat, selectedPid }) => {
- const candidates = [
- { pid: 101, ppid: 100, depth: 1, stat: 'S+', command: 'node /opt/bin/codex' },
- { pid: 102, ppid: 101, depth: 2, stat: helperStat, command: '/opt/vendor/bin/codex' }
- ]
-
- expect(selectForegroundProcessCandidate(candidates)).toMatchObject({
- candidate: { pid: selectedPid },
- recognized: { agent: 'codex' }
- })
- })
-})
-
-it('memoizes shared ancestry while validating a long agent/helper lineage', () => {
- let reads = 0
- const candidates = Array.from({ length: 1000 }, (_, index) => ({
- pid: index + 1,
- get ppid() {
- reads += 1
- return index
- },
- depth: index,
- stat: 'S+',
- command: index % 2 === 0 ? 'omp' : 'codex'
- }))
- expect(selectForegroundProcessCandidate(candidates)?.candidate.pid).toBe(1)
- expect(reads).toBeLessThanOrEqual(1000)
})
it('terminates on a ppid cycle that never reaches the outer agent', () => {
diff --git a/src/shared/foreground-wrapper-agent.test.ts b/src/shared/foreground-wrapper-agent.test.ts
index 3d63958c2f4..267ec75bf5c 100644
--- a/src/shared/foreground-wrapper-agent.test.ts
+++ b/src/shared/foreground-wrapper-agent.test.ts
@@ -5,46 +5,8 @@ import {
} from './foreground-wrapper-agent'
describe('resolveOuterWrapperForegroundProcess', () => {
- const omp = { agent: 'omp' as const, processName: 'omp' }
const pi = { agent: 'pi' as const, processName: 'pi' }
- it('collapses a wrapped pi read onto the shallower omp wrapper', () => {
- expect(
- resolveOuterWrapperForegroundProcess(pi, { pid: 102, ppid: 101, command: 'pi' }, [
- { pid: 102, ppid: 101, command: 'pi' },
- { pid: 101, ppid: 100, command: 'omp' }
- ])
- ).toBe('omp')
- })
-
- it('keeps bare pi when no same-group wrapper is present', () => {
- const barePi = { pid: 101, ppid: 100, command: 'pi' }
- expect(resolveOuterWrapperForegroundProcess(pi, barePi, [barePi])).toBe('pi')
- })
-
- it('keeps Codex identity beneath a shell parent', () => {
- const codex = { agent: 'codex' as const, processName: 'codex' }
- expect(
- resolveOuterWrapperForegroundProcess(
- codex,
- { pid: 102, ppid: 101, command: 'node /usr/bin/codex' },
- [
- { pid: 102, ppid: 101, command: 'node /usr/bin/codex' },
- { pid: 101, ppid: 100, command: 'bash -l' }
- ]
- )
- ).toBe('codex')
- })
-
- it('does not promote a deeper pi over an already-outer omp winner', () => {
- expect(
- resolveOuterWrapperForegroundProcess(omp, { pid: 101, ppid: 100, command: 'omp' }, [
- { pid: 101, ppid: 100, command: 'omp' },
- { pid: 102, ppid: 101, command: 'pi' }
- ])
- ).toBe('omp')
- })
-
it('does not treat an unrelated shallower omp sibling as the pi wrapper', () => {
expect(
resolveOuterWrapperForegroundProcess(pi, { pid: 103, ppid: 102, command: 'pi' }, [
@@ -64,12 +26,4 @@ describe('resolveOuterWrapperForegroundProcess', () => {
])
).toEqual({ processName: 'omp', processId: 101 })
})
-
- it('keeps the winner pid when nothing collapses', () => {
- const barePi = { pid: 101, ppid: 100, command: 'pi' }
- expect(resolveOuterWrapperForegroundIdentity(pi, barePi, [barePi])).toEqual({
- processName: 'pi',
- processId: 101
- })
- })
})
diff --git a/src/shared/generated-code-path.test.ts b/src/shared/generated-code-path.test.ts
deleted file mode 100644
index 6af7617cf40..00000000000
--- a/src/shared/generated-code-path.test.ts
+++ /dev/null
@@ -1,72 +0,0 @@
-import { describe, expect, it } from 'vitest'
-import { isGeneratedCodePath } from './generated-code-path'
-
-describe('isGeneratedCodePath', () => {
- it('recognizes dependency lockfiles across ecosystems', () => {
- for (const filePath of [
- 'package-lock.json',
- 'pnpm-lock.yaml',
- 'yarn.lock',
- 'bun.lockb',
- 'Cargo.lock',
- 'poetry.lock',
- 'uv.lock',
- 'Gemfile.lock',
- 'composer.lock',
- 'go.sum',
- 'flake.lock',
- 'mobile/pubspec.lock',
- 'services/api/Pipfile.lock'
- ]) {
- expect(isGeneratedCodePath(filePath), filePath).toBe(true)
- }
- })
-
- it('recognizes tool-stamped filename suffixes', () => {
- for (const filePath of [
- 'api/service.pb.go',
- // grpc-gateway / protoc-gen-validate stack extra segments onto `.pb.`
- 'api/service.pb.gw.go',
- 'api/service.pb.validate.go',
- 'api/service_pb2.py',
- 'api/service_pb2_grpc.py',
- 'src/schema.gen.ts',
- 'internal/bindings_generated.go',
- 'src/Api.generated.ts',
- 'Forms/Main.Designer.cs',
- 'lib/model.g.dart',
- 'lib/model.freezed.dart',
- 'public/app.min.js',
- 'public/app.js.map',
- 'src/components/__snapshots__/Chip.tsx.snap'
- ]) {
- expect(isGeneratedCodePath(filePath), filePath).toBe(true)
- }
- })
-
- it('recognizes generated directories on either separator', () => {
- expect(isGeneratedCodePath('dist/renderer/index.js')).toBe(true)
- expect(isGeneratedCodePath('src/__generated__/schema.ts')).toBe(true)
- expect(isGeneratedCodePath('vendor/github.com/pkg/errors/errors.go')).toBe(true)
- expect(isGeneratedCodePath('src\\__pycache__\\mod.pyc')).toBe(true)
- })
-
- it('leaves hand-written paths alone, including the ambiguous directory names', () => {
- for (const filePath of [
- 'src/shared/git-branch-line-total.ts',
- // Excluded on purpose: all common as authored source directories.
- 'build/scripts/release.ts',
- 'target/tracker.rs',
- 'src/out/renderer.ts',
- 'cmd/bin/main.go',
- // Substrings, not whole segments or suffixes.
- 'src/distributed/queue.ts',
- 'src/vendors/stripe.ts',
- 'src/generator/emit.ts',
- 'docs/generated-code-policy.md',
- 'src/shared/generated-code-path.ts'
- ]) {
- expect(isGeneratedCodePath(filePath), filePath).toBe(false)
- }
- })
-})
diff --git a/src/shared/github/account-binding.test.ts b/src/shared/github/account-binding.test.ts
index bacb1efc4b5..7d68b80fa83 100644
--- a/src/shared/github/account-binding.test.ts
+++ b/src/shared/github/account-binding.test.ts
@@ -1,37 +1,5 @@
import { describe, expect, it } from 'vitest'
-import {
- ghAccountBindingsEqual,
- ghTokenEnvVarForHost,
- normalizeGhAccountBinding
-} from './account-binding'
-
-describe('normalizeGhAccountBinding', () => {
- it('trims, lowercases host, and preserves user case', () => {
- expect(normalizeGhAccountBinding({ host: ' GitHub.COM ', user: ' Alice ' })).toEqual({
- host: 'github.com',
- user: 'Alice'
- })
- })
-
- it('rejects malformed shapes', () => {
- expect(normalizeGhAccountBinding(null)).toBeNull()
- expect(normalizeGhAccountBinding({ host: '', user: 'a' })).toBeNull()
- expect(normalizeGhAccountBinding({ host: 'github.com', user: '' })).toBeNull()
- expect(normalizeGhAccountBinding({ host: 'bad host', user: 'a' })).toBeNull()
- expect(normalizeGhAccountBinding({ host: 'github.com', user: 'has space' })).toBeNull()
- })
-
- it('accepts GHES/LDAP logins with underscores and dots', () => {
- expect(normalizeGhAccountBinding({ host: 'github.acme.com', user: 'svc_build' })).toEqual({
- host: 'github.acme.com',
- user: 'svc_build'
- })
- expect(normalizeGhAccountBinding({ host: 'github.acme.com', user: 'first.last' })).toEqual({
- host: 'github.acme.com',
- user: 'first.last'
- })
- })
-})
+import { ghTokenEnvVarForHost } from './account-binding'
describe('ghTokenEnvVarForHost', () => {
it('selects GH_TOKEN for github.com, github.localhost, and *.ghe.com', () => {
@@ -45,20 +13,3 @@ describe('ghTokenEnvVarForHost', () => {
expect(ghTokenEnvVarForHost('ghe.internal')).toBe('GH_ENTERPRISE_TOKEN')
})
})
-
-describe('ghAccountBindingsEqual', () => {
- it('compares equal pairs and preserves user case sensitivity', () => {
- expect(
- ghAccountBindingsEqual(
- { host: 'github.com', user: 'Alice' },
- { host: 'github.com', user: 'Alice' }
- )
- ).toBe(true)
- expect(
- ghAccountBindingsEqual(
- { host: 'github.com', user: 'Alice' },
- { host: 'github.com', user: 'alice' }
- )
- ).toBe(false)
- })
-})