fix(first-run): découple busy de la détection des CLI (#28)
Même backend réparé, le wizard restait à la merci d'une détection qui ne répond pas : `reload()` et `detect()` awaitaient `detectProfiles` sous le même drapeau `busy` qui grise « Save and continue » et « Detect installed CLIs ». Une promesse IPC jamais résolue laissait donc les deux boutons grisés à vie — sans issue pour l'utilisateur. La détection redevient ce qu'elle est : une étape best-effort, jamais bloquante. - `busy` ne garde plus que ce dont le wizard ne peut pas se passer (`firstRunState`) ou qui mute l'état (`configureProfiles`). Il ne dépend plus jamais de `detectProfiles`. L'invariant est documenté en tête de module. - Un drapeau `detecting` distinct suit la sonde et n'inhibe aucune action. Il est relâché par un timer (`DETECT_TIMEOUT_MS`), jamais par la seule promesse : celle-ci peut rester pendante indéfiniment. - Un identifiant de tour monotone (`detectRun`) invalide les tours périmés et ceux qui survivent au démontage, évitant un `setState` hors montage. - `reload()` rend les lignes immédiatement puis lance la détection en tâche détachée. Si elle échoue, les lignes restent cochables à la main ; seul le bouton explicite remonte l'erreur. Tests: vitest 59 fichiers / 569 tests verts, tsc --noEmit exit 0. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
@ -78,6 +78,8 @@ export function FirstRunWizard({
|
||||
)}
|
||||
|
||||
<Toolbar>
|
||||
{/* `detecting` deliberately does NOT disable this button (ticket #28):
|
||||
detection is best-effort and may never answer. */}
|
||||
<Button
|
||||
onClick={() => void vm.detect()}
|
||||
disabled={vm.busy}
|
||||
@ -85,6 +87,11 @@ export function FirstRunWizard({
|
||||
>
|
||||
Detect installed CLIs
|
||||
</Button>
|
||||
{vm.detecting && (
|
||||
<span role="status" className="text-xs text-muted">
|
||||
Detecting…
|
||||
</span>
|
||||
)}
|
||||
</Toolbar>
|
||||
|
||||
<ul className="flex list-none flex-col gap-3 p-0">
|
||||
|
||||
Reference in New Issue
Block a user