mirror of
https://github.com/stablyai/orca.git
synced 2026-11-03 02:27:43 +00:00
* wip(layout): applyDefaultTabs command in the layout model (dark) * wip(layout): applyDefaultTabs takes the window's proposed ids; main refuses a taken one * wip(layout): main closes or keeps an exited split pane by the window's rule (dark) * wip(layout): a create or split sent again after its close is refused (dark) * wip: typed test doubles * wip(layout): main writes a worktree's default tabs in one command and starts them, window or none (dark; twin e) * wip(layout): main writes a worktree's default tabs in one command and starts them, window or none (dark; twin e) * wip(layout): main provisions setup and default tabs even when the agent fails to start; no window takes over (dark) * wip(layout): pane start status in frames; a failed start keeps its pane; a terminal close stands after a failed write (dark) * wip: lint fixes (max-lines, test throws) * test(layout): a terminal close stands after a real failed profile write; switch off still refuses * fix(layout): checked types in the close-failure rule and its tests * fix(layout): a failed start keeps its pane whatever failed; default tabs start once; a tab's last pane keeps its card (dark) * test(layout): the agent's kept pane counts as the workspace's terminal; main starts it whatever failed * fix(layout): the switch-off create path gains no await * fix(layout): a failed start never writes back a pane the user closed (dark) * fix(layout): a failed start's pane goes through main's create rules, so a closed tab stays closed (dark) * test(layout): D1a's switch-on close tests assert the intent main receives (both builds) * test(layout): the close fixture answers main's command without naming the method * fix(layout): a re-created pane binds as designed; the id-only ratchet reads a shared import (dark) * fix(layout): a pane's start status may sit on a pane still bound to its old terminal (dark) * fix(layout): a pane's start status ends when its pane binds again by any path (dark) * test(layout): same-id restore ends a status; a replayed split brings back a closed pane by design * fix(terminal): keep shipped exit and default-tab behaviour with the layout switch on An exited pane closes through the legacy retirement unless the keep rule holds; the default tab's title and color still reach the window and the phone's live tabs. * fix(terminal): one id guard for every pane write; keep panes on an unvouched -1 Main's taken and closed-id guard now runs where every pane write goes, so a runtime create replayed after its tab closed is refused before it spawns. An exit code nothing vouches for keeps the pane, as the window does; a kept pane sends the phone no retirement. Converts the switch-on tests that asserted the deleted window hand-off and title bridge. * fix(terminal): keep the closed-tab guard on every pane write, held-id checks on client commands A paired host starts each pane of a client's tab as a create under the tab's id, so a held tab id is refused only for a client's own layout command. * fix(terminal): a provider-reported -1 keeps the pane, as the window does Only a requested stop or a host-confirmed death closes a pane on a negative exit code. Pins that the closed-tab guard never fires in the shipped build. * chore(terminal): satisfy the exhaustive-switch and test typing checks * test(terminal): give the replay test's live process a cwd --------- Co-authored-by: E2E Test <e2e@test.local>
58 lines
2.1 KiB
TypeScript
58 lines
2.1 KiB
TypeScript
import { describe, expect, it, vi } from 'vitest'
|
|
import type { Repo } from '../../shared/repo-types'
|
|
import { createRuntimeFolderWorktree } from './runtime-folder-worktree-create'
|
|
import type { HostWorktreeTarget } from '../../shared/worktree/host-qualified-identity'
|
|
|
|
vi.mock('../../shared/layout-owner-switch', () => ({ ORCA_LAYOUT_OWNER_IS_MAIN: true }))
|
|
|
|
type CreateArgs = Parameters<typeof createRuntimeFolderWorktree>[0]
|
|
|
|
const repo: Repo = {
|
|
id: 'repo-1',
|
|
path: '/folder',
|
|
displayName: 'folder',
|
|
badgeColor: 'blue',
|
|
addedAt: 1
|
|
}
|
|
|
|
function createDeps() {
|
|
const createTerminal = vi
|
|
.fn<CreateArgs['deps']['createTerminal']>()
|
|
.mockResolvedValue({ handle: 'term-1', worktreeId: 'folder-1', title: null })
|
|
const store = {
|
|
getSettings: () => ({ workspaceDir: '/ws', nestWorkspaces: false }),
|
|
setWorktreeMeta: (_target: HostWorktreeTarget, meta: Record<string, unknown>) => meta,
|
|
getProjectHostSetups: () => []
|
|
}
|
|
const deps: CreateArgs['deps'] = {
|
|
// oxlint-disable-next-line typescript/consistent-type-assertions -- SAFETY: the create reads only these three store methods; any other would throw on call rather than read a wrong value.
|
|
store: store as unknown as CreateArgs['deps']['store'],
|
|
ptySpawnAvailable: true,
|
|
createTerminal,
|
|
pasteDraft: vi.fn(),
|
|
sendFollowup: vi.fn(),
|
|
invalidateResolvedWorktrees: vi.fn(),
|
|
notifyWorktreesChanged: vi.fn(),
|
|
emitCreated: vi.fn(),
|
|
activate: vi.fn()
|
|
}
|
|
return { createTerminal, deps }
|
|
}
|
|
|
|
describe('layout-owner build: a folder create whose agent failed to start', () => {
|
|
it('hands the window no start to retry', async () => {
|
|
const { createTerminal, deps } = createDeps()
|
|
createTerminal.mockRejectedValueOnce(new Error('pty unavailable'))
|
|
const warn = vi.spyOn(console, 'warn').mockImplementation(() => {})
|
|
await createRuntimeFolderWorktree({
|
|
request: { repoSelector: `id:${repo.id}`, name: 'task', activate: true },
|
|
repo,
|
|
createdWithAgent: 'codex',
|
|
startup: { command: 'codex' },
|
|
deps
|
|
})
|
|
expect(deps.activate).toHaveBeenCalledWith(repo.id, expect.any(String), undefined, undefined)
|
|
warn.mockRestore()
|
|
})
|
|
})
|