Capitalise les notes durables produites pendant le sprint UI rework et les tickets livrés depuis. Commit séparé du code : `.ideai/memory/` est le store durable versionné, il ne doit jamais être mélangé aux commits de feature. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2.1 KiB
name, description, metadata
| name | description | metadata | ||
|---|---|---|---|---|
| ticket28-f1-frontend-delivered | Lot F1 du ticket |
|
Lot F1 (frontend) du bug #28 implémenté sur feature/ticket28-firstrun-detect-hang (non committé, Git s'en charge).
Invariant posé : dans frontend/src/features/first-run/useFirstRun.ts, le retour de busy à false ne dépend d'aucun appel à detectProfiles. busy n'entoure plus que firstRunState() (reload) et configureProfiles() (finish). Toute future régression qui remet un await profile.detectProfiles(...) sur un chemin gouvernant busy re-gèle le wizard.
Mécanisme : runDetection(candidates, { preselect, reportError }) factorise auto-détection et bouton manuel. Le flag detecting est relâché par un setTimeout(DETECT_TIMEOUT_MS = 3_000), jamais par la promesse — car le finally d'un await sur une promesse jamais settled (panic Rust ⇒ pas de réponse IPC) n'est jamais atteint. Un compteur detectRun invalide les rounds périmés (re-clic, unmount).
Piège UI à retenir : <Button loading> implique disabled dans le design system (shared/ui/Button.tsx:46). Donc detecting ne peut pas être surfacé via loading sur les boutons Save/Detect sans réintroduire le grisage — il est rendu comme un role="status" « Detecting… » séparé.
Point de vérité QA : FirstRunWizard.test.tsx, describe « detection that never answers (ticket #28) », gateway HangingDetectGateway dont detectProfiles renvoie new Promise(() => {}). Vérifié à teeth : en réintroduisant setBusy(true); await runDetection(...) dans reload, 2 des 3 tests échouent avec exactement le symptôme du ticket.
Vert : npx vitest run 59 fichiers / 569 tests, npx tsc --noEmit exit 0. Pas de lint dans ce projet (aucun eslint config ni script). F1 débloque l'UI mais B1 (DevBackend, AgentRuntime::detect sync→async) reste requis pour que la détection remonte réellement un résultat.