mirror of
https://github.com/stablyai/orca.git
synced 2026-10-20 00:03:45 +00:00
Fix setup prompt CI regressions
This commit is contained in:
@@ -21,12 +21,11 @@ import { openSetupScriptSettings } from './open-setup-script-settings'
|
||||
import { trackSetupScriptPromptExposure } from './setup-script-prompt-exposure-telemetry'
|
||||
import {
|
||||
findSetupScriptPromptRepo,
|
||||
getRenderedSetupScriptPromptState,
|
||||
markSetupScriptPromptSaved,
|
||||
type LastVisibleSetupScriptPrompt,
|
||||
type SetupScriptPromptState
|
||||
} from './setup-script-prompt-render-state'
|
||||
import { useSetupScriptPromptRevalidation } from './useSetupScriptPromptRevalidation'
|
||||
import { useRenderedSetupScriptPromptState } from './useRenderedSetupScriptPromptState'
|
||||
import { translate } from '@/i18n/i18n'
|
||||
import { getRepoHostIdentity } from '@/store/slices/repo-host-identity'
|
||||
import { getRepoExecutionHostId } from '../../../../shared/execution-host'
|
||||
@@ -60,7 +59,6 @@ function SetupScriptPromptCard(): React.JSX.Element | null {
|
||||
const isDismissed = activeRepoHostIdentity
|
||||
? isSetupScriptPromptDismissed(activeRepoHostIdentity, dismissedRepoIds)
|
||||
: false
|
||||
const lastVisiblePromptRef = useRef<LastVisibleSetupScriptPrompt | null>(null)
|
||||
|
||||
useEffect(() => {
|
||||
if (!sidebarOpen || !activeRepo || !isGitRepoKind(activeRepo) || isDismissed) {
|
||||
@@ -348,31 +346,25 @@ function SetupScriptPromptCard(): React.JSX.Element | null {
|
||||
})
|
||||
}, [activeRepo, detectedSetupDraft, promptState, saveSetupCandidate])
|
||||
|
||||
if (
|
||||
const promptTargetHidden =
|
||||
!sidebarOpen ||
|
||||
!activeRepo ||
|
||||
!activeRepoHostIdentity ||
|
||||
!isGitRepoKind(activeRepo) ||
|
||||
isDismissed
|
||||
) {
|
||||
lastVisiblePromptRef.current = null
|
||||
return null
|
||||
}
|
||||
|
||||
const renderedPromptState = getRenderedSetupScriptPromptState({
|
||||
const renderedPromptState = useRenderedSetupScriptPromptState({
|
||||
promptState,
|
||||
activeRepoId: activeRepo.id,
|
||||
activeRepoId: activeRepo?.id ?? null,
|
||||
activeRepoHostIdentity,
|
||||
lastVisiblePrompt: lastVisiblePromptRef.current
|
||||
promptTargetHidden
|
||||
})
|
||||
|
||||
if (
|
||||
promptTargetHidden ||
|
||||
!activeRepo ||
|
||||
!renderedPromptState ||
|
||||
(renderedPromptState.status === 'ok' && renderedPromptState.hasEffectiveSetup)
|
||||
) {
|
||||
if (renderedPromptState?.status === 'ok' && renderedPromptState.hasEffectiveSetup) {
|
||||
lastVisiblePromptRef.current = null
|
||||
}
|
||||
return null
|
||||
}
|
||||
|
||||
@@ -380,18 +372,9 @@ function SetupScriptPromptCard(): React.JSX.Element | null {
|
||||
// retry-able card entirely — the global scope-mismatch banner explains it and
|
||||
// a retry would just re-fire repo.hooksCheck on every repo focus.
|
||||
if (renderedPromptState.status === 'forbidden') {
|
||||
lastVisiblePromptRef.current = null
|
||||
return null
|
||||
}
|
||||
|
||||
if (
|
||||
renderedPromptState.status === 'ok' &&
|
||||
!renderedPromptState.hasEffectiveSetup &&
|
||||
renderedPromptState.repoHostIdentity === activeRepoHostIdentity
|
||||
) {
|
||||
lastVisiblePromptRef.current = { state: renderedPromptState }
|
||||
}
|
||||
|
||||
const isInspectionError = renderedPromptState.status === 'error'
|
||||
const candidate = renderedPromptState.status === 'ok' ? renderedPromptState.candidate : null
|
||||
const isPackageManagerSuggestion = candidate?.provider === 'package-manager'
|
||||
|
||||
@@ -0,0 +1,48 @@
|
||||
// @vitest-environment happy-dom
|
||||
|
||||
import { renderHook } from '@testing-library/react'
|
||||
import { describe, expect, it } from 'vitest'
|
||||
import { getRepoHostIdentityForParts } from '@/store/slices/repo-host-identity'
|
||||
import type { SetupScriptPromptState } from './setup-script-prompt-render-state'
|
||||
import { useRenderedSetupScriptPromptState } from './useRenderedSetupScriptPromptState'
|
||||
|
||||
function prompt(repoId: string, hostId: string): SetupScriptPromptState {
|
||||
return {
|
||||
status: 'ok',
|
||||
repoId,
|
||||
repoHostIdentity: getRepoHostIdentityForParts(repoId, hostId),
|
||||
hasEffectiveSetup: false,
|
||||
hasSharedHooks: false,
|
||||
candidate: null
|
||||
}
|
||||
}
|
||||
|
||||
describe('useRenderedSetupScriptPromptState', () => {
|
||||
it('preserves a committed same-host prompt without leaking it to another host', () => {
|
||||
const local = prompt('repo-1', 'local')
|
||||
const { result, rerender } = renderHook(
|
||||
({ hostIdentity, promptState }) =>
|
||||
useRenderedSetupScriptPromptState({
|
||||
promptState,
|
||||
activeRepoId: 'repo-1',
|
||||
activeRepoHostIdentity: hostIdentity,
|
||||
promptTargetHidden: false
|
||||
}),
|
||||
{
|
||||
initialProps: {
|
||||
hostIdentity: local.repoHostIdentity,
|
||||
promptState: local as SetupScriptPromptState | null
|
||||
}
|
||||
}
|
||||
)
|
||||
|
||||
rerender({ hostIdentity: local.repoHostIdentity, promptState: null })
|
||||
expect(result.current).toBe(local)
|
||||
|
||||
rerender({
|
||||
hostIdentity: getRepoHostIdentityForParts('repo-1', 'ssh:windows'),
|
||||
promptState: null
|
||||
})
|
||||
expect(result.current).toBeNull()
|
||||
})
|
||||
})
|
||||
@@ -0,0 +1,45 @@
|
||||
import { useEffect, useRef } from 'react'
|
||||
import {
|
||||
getRenderedSetupScriptPromptState,
|
||||
type LastVisibleSetupScriptPrompt,
|
||||
type SetupScriptPromptState
|
||||
} from './setup-script-prompt-render-state'
|
||||
|
||||
export function useRenderedSetupScriptPromptState(input: {
|
||||
promptState: SetupScriptPromptState | null
|
||||
activeRepoId: string | null
|
||||
activeRepoHostIdentity: string | null
|
||||
promptTargetHidden: boolean
|
||||
}): SetupScriptPromptState | null {
|
||||
const { activeRepoHostIdentity, activeRepoId, promptState, promptTargetHidden } = input
|
||||
const lastVisiblePromptRef = useRef<LastVisibleSetupScriptPrompt | null>(null)
|
||||
const renderedPromptState =
|
||||
!promptTargetHidden && activeRepoId && activeRepoHostIdentity
|
||||
? getRenderedSetupScriptPromptState({
|
||||
promptState,
|
||||
activeRepoId,
|
||||
activeRepoHostIdentity,
|
||||
lastVisiblePrompt: lastVisiblePromptRef.current
|
||||
})
|
||||
: null
|
||||
|
||||
useEffect(() => {
|
||||
if (
|
||||
renderedPromptState?.status === 'ok' &&
|
||||
!renderedPromptState.hasEffectiveSetup &&
|
||||
renderedPromptState.repoHostIdentity === activeRepoHostIdentity
|
||||
) {
|
||||
lastVisiblePromptRef.current = { state: renderedPromptState }
|
||||
return
|
||||
}
|
||||
if (
|
||||
promptTargetHidden ||
|
||||
renderedPromptState?.status === 'forbidden' ||
|
||||
(renderedPromptState?.status === 'ok' && renderedPromptState.hasEffectiveSetup)
|
||||
) {
|
||||
lastVisiblePromptRef.current = null
|
||||
}
|
||||
}, [activeRepoHostIdentity, promptTargetHidden, renderedPromptState])
|
||||
|
||||
return renderedPromptState
|
||||
}
|
||||
@@ -141,6 +141,7 @@ describe('repo slice runtime routing', () => {
|
||||
|
||||
expect(store.getState().repos[0]?.displayName).toBe('SSH Renamed')
|
||||
expect(reposUpdate).toHaveBeenCalledWith({
|
||||
hostId: 'ssh:ssh-1',
|
||||
repoId: sshRepo.id,
|
||||
updates: { displayName: 'SSH Renamed' }
|
||||
})
|
||||
|
||||
Reference in New Issue
Block a user