mirror of
https://github.com/stablyai/orca.git
synced 2026-10-31 00:57:45 +00:00
* fix(worktrees): decide setup before git worktree add on the host's create, so an undecided ask repo leaves nothing behind The host's create (agent.launch, worktree.create, the phone and the CLI) only checked the setup policy after adding the worktree. An ask repo with no setup decision then threw with the worktree already on disk and no worktrees-changed event. It now refuses before the add, as the desktop create does, and a setup hook the new branch adds (one nobody decided on) is skipped with a warning instead of failing a create that already exists. * fix(worktrees): read the host create's setup decision in one place, after recording its host The pre-add refusal now runs after the create records its execution host, so a refused create's failure telemetry still says where it ran; it still runs before any git work. Both setup checks read the decision from one helper so they cannot disagree, and the post-add skip logs once. The refusal test now also proves no base resolution, fetch or branch naming ran and that the hooks came from the main checkout. * test(worktrees): cover a setup hook only the new branch adds through the managed create An ask repo with no decision, whose setup hook exists only in the new worktree's orca.yaml, now creates, refreshes the worktree list, reports setup as skipped and returns the warning. * fix(cli): name the --setup flag when a worktree create needs a setup decision The host refuses an undecided create in an ask repo with "Setup decision required for this repository", which desktop and phone answer in their own UI. The CLI now adds the next step: pass --setup run or --setup skip.
61 lines
1.9 KiB
TypeScript
61 lines
1.9 KiB
TypeScript
import { beforeEach, describe, expect, it, vi } from 'vitest'
|
|
import type { Repo } from '../../shared/repo-types'
|
|
import { getDefaultRepoHookSettings } from '../../shared/constants'
|
|
|
|
const mocks = vi.hoisted(() => ({
|
|
effectiveHooks: vi.fn(),
|
|
runHook: vi.fn()
|
|
}))
|
|
|
|
vi.mock('../hooks', () => ({
|
|
getEffectiveHooks: mocks.effectiveHooks,
|
|
loadHooks: () => null,
|
|
runHook: mocks.runHook
|
|
}))
|
|
|
|
import { prepareRuntimeLocalWorktreeSetup } from './runtime-local-worktree-setup'
|
|
|
|
const askRepo: Repo = {
|
|
id: 'repo-1',
|
|
path: '/repo',
|
|
displayName: 'Repo',
|
|
badgeColor: '#000000',
|
|
addedAt: 0,
|
|
hookSettings: { ...getDefaultRepoHookSettings(), setupRunPolicy: 'ask' }
|
|
}
|
|
|
|
function prepare(request: { setupDecision?: 'run' | 'skip' | 'inherit' } = {}) {
|
|
return prepareRuntimeLocalWorktreeSetup({
|
|
request: { repoSelector: 'repo-1', name: 'app', ...request },
|
|
repo: askRepo,
|
|
worktreePath: '/worktrees/app',
|
|
// oxlint-disable-next-line typescript/consistent-type-assertions -- SAFETY: settings are read only by the setup runner, which this in-process path never builds.
|
|
settings: {} as never,
|
|
runtimeTarget: undefined,
|
|
shouldUseSetupRunner: false
|
|
})
|
|
}
|
|
|
|
describe('runtime create setup for a hook the new branch added', () => {
|
|
beforeEach(() => {
|
|
vi.resetAllMocks()
|
|
mocks.runHook.mockResolvedValue({ success: true, output: '' })
|
|
mocks.effectiveHooks.mockReturnValue({ scripts: { setup: 'pnpm install' } })
|
|
})
|
|
|
|
it('skips setup with a warning instead of failing a create that already added the worktree', async () => {
|
|
const result = await prepare()
|
|
|
|
expect(result.shouldRunSetup).toBe(false)
|
|
expect(result.warning).toContain('pass --setup run to run it')
|
|
expect(mocks.runHook).not.toHaveBeenCalled()
|
|
})
|
|
|
|
it('still runs setup when the caller decided to', async () => {
|
|
const result = await prepare({ setupDecision: 'run' })
|
|
|
|
expect(result.shouldRunSetup).toBe(true)
|
|
expect(mocks.runHook).toHaveBeenCalledOnce()
|
|
})
|
|
})
|