mirror of
https://github.com/stablyai/orca.git
synced 2026-10-25 16:03:53 +00:00
fix(native-chat): restore runtime refusals behind the win32 gate
506d375de3 replaced the project-runtime checks with a bare platform test,
so a WSL or repair-required runtime resolution would no longer refuse
structured chat off-win32. Keep the unconditional win32 refusal and
re-run the runtime resolution after it, so the gate does not depend on
the resolver's own platform guard. Tests inject WSL and repair-required
resolutions on darwin/linux and fail against the regressed gate.
This commit is contained in:
@@ -1,5 +1,7 @@
|
||||
import { beforeEach, describe, expect, it, vi } from 'vitest'
|
||||
import type { AppState } from '@/store/types'
|
||||
import type * as localPreflightContext from '@/lib/local-preflight-context'
|
||||
import type { ProjectExecutionRuntimeResolution } from '../../../shared/project-execution-runtime'
|
||||
import { canUseStructuredNativeChat } from './structured-native-chat-availability'
|
||||
|
||||
const { mockGetRendererAppPlatform } = vi.hoisted(() => ({
|
||||
@@ -10,6 +12,43 @@ vi.mock('@/lib/renderer-app-platform', () => ({
|
||||
getRendererAppPlatform: mockGetRendererAppPlatform
|
||||
}))
|
||||
|
||||
type GetLocalProjectExecutionRuntimeContext =
|
||||
typeof localPreflightContext.getLocalProjectExecutionRuntimeContext
|
||||
|
||||
const projectRuntimeMock = vi.hoisted(() => ({
|
||||
fn: vi.fn<GetLocalProjectExecutionRuntimeContext>(),
|
||||
actual: undefined as GetLocalProjectExecutionRuntimeContext | undefined
|
||||
}))
|
||||
|
||||
vi.mock('@/lib/local-preflight-context', async (importOriginal) => {
|
||||
const actual = await importOriginal<typeof localPreflightContext>()
|
||||
projectRuntimeMock.actual = actual.getLocalProjectExecutionRuntimeContext
|
||||
return { ...actual, getLocalProjectExecutionRuntimeContext: projectRuntimeMock.fn }
|
||||
})
|
||||
|
||||
const wslRuntimeResolution: ProjectExecutionRuntimeResolution = {
|
||||
status: 'resolved',
|
||||
runtime: {
|
||||
kind: 'wsl',
|
||||
hostPlatform: 'wsl',
|
||||
projectId: 'repo-1',
|
||||
distro: 'Ubuntu',
|
||||
reason: 'project-override',
|
||||
cacheKey: 'repo-1|wsl|Ubuntu'
|
||||
}
|
||||
}
|
||||
|
||||
const repairRequiredResolution: ProjectExecutionRuntimeResolution = {
|
||||
status: 'repair-required',
|
||||
repair: {
|
||||
projectId: 'repo-1',
|
||||
preferredRuntime: { kind: 'wsl', distro: null },
|
||||
reason: 'wsl-distro-required',
|
||||
source: 'project-override',
|
||||
cacheKey: 'repo-1|wsl|repair'
|
||||
}
|
||||
}
|
||||
|
||||
function stateFor(input: {
|
||||
connectionId?: string | null
|
||||
windowsRuntime?: 'windows-host' | 'wsl'
|
||||
@@ -46,6 +85,13 @@ function stateFor(input: {
|
||||
describe('canUseStructuredNativeChat', () => {
|
||||
beforeEach(() => {
|
||||
mockGetRendererAppPlatform.mockReturnValue('darwin')
|
||||
projectRuntimeMock.fn.mockReset()
|
||||
projectRuntimeMock.fn.mockImplementation((...args) => {
|
||||
if (!projectRuntimeMock.actual) {
|
||||
throw new Error('real getLocalProjectExecutionRuntimeContext was never captured')
|
||||
}
|
||||
return projectRuntimeMock.actual(...args)
|
||||
})
|
||||
})
|
||||
|
||||
it('allows the structured stack on a local worktree', () => {
|
||||
@@ -101,4 +147,27 @@ describe('canUseStructuredNativeChat', () => {
|
||||
} as unknown as AppState
|
||||
expect(canUseStructuredNativeChat(state, 'folder:folder-1')).toBe(true)
|
||||
})
|
||||
|
||||
it.each(['darwin', 'linux'] as const)('allows a supported local worktree on %s', (platform) => {
|
||||
mockGetRendererAppPlatform.mockReturnValue(platform)
|
||||
expect(canUseStructuredNativeChat(stateFor({}), 'wt-1')).toBe(true)
|
||||
})
|
||||
|
||||
it.each(['darwin', 'linux'] as const)(
|
||||
'refuses a WSL project runtime even when the renderer reports %s',
|
||||
(platform) => {
|
||||
mockGetRendererAppPlatform.mockReturnValue(platform)
|
||||
projectRuntimeMock.fn.mockReturnValue(wslRuntimeResolution)
|
||||
expect(canUseStructuredNativeChat(stateFor({}), 'wt-1')).toBe(false)
|
||||
}
|
||||
)
|
||||
|
||||
it.each(['darwin', 'linux'] as const)(
|
||||
'refuses a repair-required runtime even when the renderer reports %s',
|
||||
(platform) => {
|
||||
mockGetRendererAppPlatform.mockReturnValue(platform)
|
||||
projectRuntimeMock.fn.mockReturnValue(repairRequiredResolution)
|
||||
expect(canUseStructuredNativeChat(stateFor({}), 'wt-1')).toBe(false)
|
||||
}
|
||||
)
|
||||
})
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
import type { AppState } from '@/store/types'
|
||||
import { getLocalProjectExecutionRuntimeContext } from '@/lib/local-preflight-context'
|
||||
import { getExecutionHostIdForWorktree } from '@/lib/worktree-runtime-owner'
|
||||
import { getRendererAppPlatform } from '@/lib/renderer-app-platform'
|
||||
|
||||
@@ -13,5 +14,11 @@ export function canUseStructuredNativeChat(state: AppState, worktreeId: string):
|
||||
// the host advertises that proof, refuse every local Windows execution path —
|
||||
// windows-host, WSL, and keys that resolve no project runtime (folder
|
||||
// workspaces, floating terminal) — so create cannot fail after the click.
|
||||
return getRendererAppPlatform() !== 'win32'
|
||||
if (getRendererAppPlatform() === 'win32') {
|
||||
return false
|
||||
}
|
||||
// Refuse WSL and repair-required runtimes even if resolution ever runs
|
||||
// off-win32; the gate must not depend on the resolver's platform guard.
|
||||
const projectRuntime = getLocalProjectExecutionRuntimeContext(state, worktreeId)
|
||||
return !(projectRuntime?.status === 'repair-required' || projectRuntime?.runtime.kind === 'wsl')
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user