Enregistre l'état du registre de tickets : #74 et #68 passent en closed après la validation live de l'intégration web, #75 (ce fix) entre en QA et #76 ouvre la dette de casse du code d'appairage côté serveur. État runtime uniquement : aucun code de feature n'est touché. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
@ -8177,10 +8177,88 @@
|
||||
"ticket_id": "8bf414e0-60f1-4fb8-87ff-76d618150fb0",
|
||||
"conversation_id": "6bc594e8-a37c-0dbd-1de6-6e3b73002cb4"
|
||||
},
|
||||
"state": "running",
|
||||
"state": "completed",
|
||||
"wakePolicy": "recordOnly",
|
||||
"createdAtMs": 1784277230713,
|
||||
"updatedAtMs": 1784277230713,
|
||||
"updatedAtMs": 1784277293596,
|
||||
"deadlineMs": null,
|
||||
"result": {
|
||||
"outcome": "success",
|
||||
"finished_at_ms": 1784277293596,
|
||||
"exit_code": null,
|
||||
"summary": "Headless rendezvous completed with Final",
|
||||
"stdout_tail": "**#74 est intégré dans `develop`. Working tree propre, rien en attente, aucun push effectué.**\n\n## Ce que j'ai commité\n\nUn seul commit restait à faire : `4de25d2 — chore(ideai): état runtime du ticket #74 (passage en QA)`. Il porte les 4 fichiers non commités (issue, carnet, index des tickets, accusés de complétion des rendez-vous headless). C'est de l'état runtime pur, donc isolé du code de feature selon ma convention. J'ai vérifié avec `--untracked-files=all` qu'aucun artefact de build ne traînait (`dist/`, `dist-web/`, `target/`, AppImage) — rien.\n\n## Ce que j'ai mergé\n\n`aec4293` — merge `--no-ff` de `feature/ticket74-web-transport-bundle` vers `develop`. Aucun conflit, `develop` n'avait pas bougé depuis la création de la branche (0 commit de retard), donc pas de rebase préalable nécessaire.\n\n**Un point mérite ton attention** : ce merge intègre **deux tickets**, pas un. La branche #74 était empilée sur `feature/ticket68-appimage-web-assets` et contenait `166adc3` (#68, packaging des assets web en ressource Tauri), qui n'était pas encore dans `develop`. C'était voulu et je l'assume : le packaging #68 servait précisément le bundle cassé que #74 corrige, il ne pouvait pas être déclaré vert tout seul. Les deux ferment ensemble. Si tu considérais #68 comme ayant sa propre porte QA à franchir séparément, dis-le moi — mais techniquement, le séparer était impossible sans conflit frontal sur les mêmes lignes de `tauri.conf.json`.\n\nJ'ai aussi supprimé `feature/ticket68-appimage-web-assets` : elle était un ancêtre strict de la branche #74, sans aucun commit propre. La garder n'apportait rien.\n\n## État final\n\n`develop` est sur `aec4293`, en avance de **34 commits sur `origin/develop`**, arbre propre. Les deux branches de feature (`ticket74-web-transport-bundle`, `ticket68-appimage-web-assets`) sont supprimées, leur travail vivant dans `develop`.\n\n## Ce qui reste en suspens\n\nLe **statut des tickets #68 et #74 est resté à `qa`** dans les métadonnées. Le code est mergé et validé live, mais la clôture formelle d'un ticket n'est pas ma décision — c'est Main qui arbitre. À faire passer en `done` de son côté.\n\nCôté remote, **les 34 commits d'avance sur `origin/develop` ne sont pas poussés**, conformément à mon périmètre strictement local. Un `git push origin develop` les publierait ; dis-moi si tu le veux et je m'en occupe. Enfin, `develop → main` (release) n'a pas été touché, ça reste une décision explicite de ta part.",
|
||||
"stderr_tail": null
|
||||
},
|
||||
"completionDelivered": false
|
||||
},
|
||||
{
|
||||
"id": "078855de-999f-40a8-97fc-0b5c1be2fe5c",
|
||||
"projectId": "97b49ac2-8376-4aa3-8ea9-bf3ac81d0023",
|
||||
"ownerAgentId": "c3e0d9d8-df36-4b00-b271-62d8aa78892c",
|
||||
"kind": {
|
||||
"kind": "headlessRendezvous",
|
||||
"requester_agent_id": "a6ced819-b893-4213-b003-9e9dc79b9641",
|
||||
"target_agent_id": "c3e0d9d8-df36-4b00-b271-62d8aa78892c",
|
||||
"ticket_id": "1a3657bd-1067-4a0c-96ab-28bb326a3e6c",
|
||||
"conversation_id": "652e01c1-67a5-0913-0272-fc456de31f6d"
|
||||
},
|
||||
"state": "completed",
|
||||
"wakePolicy": "recordOnly",
|
||||
"createdAtMs": 1784277366856,
|
||||
"updatedAtMs": 1784277379813,
|
||||
"deadlineMs": null,
|
||||
"result": {
|
||||
"outcome": "success",
|
||||
"finished_at_ms": 1784277379813,
|
||||
"exit_code": null,
|
||||
"summary": "Headless rendezvous completed with Final",
|
||||
"stdout_tail": "Décision UX pour Ticket #75 :\n\n1. `inputMode`\nUtiliser `inputMode=\"text\"`.\n\nRaison : le code contient chiffres + lettres `A-F`; un pavé numérique rend la saisie partiellement impossible. Ne pas utiliser `numeric`, `decimal` ni `tel`.\n\n2. Placeholder / aide visuelle\nRemplacer le placeholder actuel par un exemple fidèle :\n\n`AB12-CD34`\n\nAjouter ou conserver une aide courte sous le champ si l’écran en a déjà une :\n\n`8 caractères : chiffres et lettres A-F`\n\nÉviter le mot “hexadécimal”. Il est exact techniquement, mais inutile côté utilisateur.\n\n3. Casse\nL’UI doit normaliser la saisie en majuscules avant affichage et avant envoi.\n\nComportement attendu :\n- si l’utilisateur tape `ab12cd34`, le champ affiche `AB12-CD34` ou `AB12CD34` selon le formatage existant retenu ;\n- la valeur envoyée au serveur est toujours `AB12CD34`, sans tiret ni espace ;\n- ne pas imposer à l’utilisateur de changer manuellement de casse.\n\nPérimètre frontend pur suffisant : normalisation côté UI avant submit. \nÀ noter comme robustesse future, mais hors périmètre demandé : le backend devrait idéalement comparer en normalisant aussi, car la tolérance ne doit pas dépendre uniquement du client.\n\n4. `autoCapitalize` / `autoComplete`\nMettre :\n\n- `autoCapitalize=\"characters\"`\n- `autoCorrect=\"off\"`\n- `autoComplete=\"one-time-code\"`\n- `spellCheck={false}` si le composant le permet\n\nCritères d’acceptation visuels/fonctionnels :\n- sur mobile, le clavier permet lettres et chiffres sans bascule manuelle obligatoire ;\n- le placeholder ne suggère plus un code numérique ;\n- une saisie minuscule aboutit à un code accepté par le serveur via normalisation frontend ;\n- l’aide reste courte, non technique, et ne prend pas plus d’une ligne sur mobile.",
|
||||
"stderr_tail": null
|
||||
},
|
||||
"completionDelivered": false
|
||||
},
|
||||
{
|
||||
"id": "fecf3304-b299-45f0-9ec6-0dff06d4a990",
|
||||
"projectId": "97b49ac2-8376-4aa3-8ea9-bf3ac81d0023",
|
||||
"ownerAgentId": "af7f86da-76bc-48e1-9900-71f45a624800",
|
||||
"kind": {
|
||||
"kind": "headlessRendezvous",
|
||||
"requester_agent_id": "a6ced819-b893-4213-b003-9e9dc79b9641",
|
||||
"target_agent_id": "af7f86da-76bc-48e1-9900-71f45a624800",
|
||||
"ticket_id": "e315464e-656f-4484-b444-18245987e85f",
|
||||
"conversation_id": "09b15ec3-ce2f-0af2-2903-ef699df9de41"
|
||||
},
|
||||
"state": "completed",
|
||||
"wakePolicy": "recordOnly",
|
||||
"createdAtMs": 1784277402194,
|
||||
"updatedAtMs": 1784277521434,
|
||||
"deadlineMs": null,
|
||||
"result": {
|
||||
"outcome": "success",
|
||||
"finished_at_ms": 1784277521434,
|
||||
"exit_code": null,
|
||||
"summary": "Headless rendezvous completed with Final",
|
||||
"stdout_tail": "Ticket #75 est corrigé et vert. Le champ demande maintenant le clavier texte et la valeur envoyée au serveur est normalisée en majuscules.\n\n## Ce que j'ai changé\n\n**`frontend/src/features/web/PairingScreen.tsx`** — les 5 points de la spec, tels quels :\n\n- `inputMode=\"numeric\"` → `inputMode=\"text\"`, et `autoCapitalize=\"off\"` → `\"characters\"`. Les autres attributs (`autoCorrect=\"off\"`, `autoComplete=\"one-time-code\"`, `spellCheck={false}`) sont conservés. J'ai remplacé le commentaire `#69` qui justifiait le pavé numérique par un commentaire `#75` expliquant pourquoi le clavier texte est requis.\n- Placeholder `p. ex. 4821-93` → `p. ex. AB12CD34`, sans séparateur comme tu l'as tranché.\n- L'aide passe par le `hint` de `Field`, qui la rend dans le `<p id={...}-msg>` déjà câblé à `aria-describedby` — donc pas de `<p>` libre, et le lien accessibilité est automatique. Texte : « 8 caractères : chiffres et lettres A-F ».\n- Une fonction `normalize()` locale remplace le `trim()` : elle enlève tous les espaces (pas seulement en bord) et met en majuscules. C'est elle qui alimente `session.pair()`.\n- Le `disabled` du bouton submit passe de `code.trim().length === 0` à `normalize(code).length === 0`, donc une saisie de seuls espaces reste refusée, cohérente avec ce qui serait envoyé.\n\nPas de masque de saisie ni de formatage à la frappe, et l'écran ne parle toujours qu'à la `WebSession` injectée — aucun import `@tauri-apps` ajouté, le garde-fou `no-direct-invoke` n'est pas touché.\n\n**`frontend/src/features/web/PairingScreen.test.tsx`** (nouveau) — j'ai préféré un fichier dédié plutôt que d'alourdir `WebApp.test.tsx`, qui teste le routage et non le champ. Quatre tests, avec un `vi.spyOn(session, \"pair\")` sur une vraie `WebSession` à fetch injecté : le `inputMode` est bien `text`, le placeholder et l'aide sont fidèles, ` ab12cd34 ` part en `AB12CD34`, et le submit reste désactivé sur une saisie vide ou blanche.\n\n## Sortie de test réelle\n\n`cd frontend && npx vitest run` (suite complète) :\n\n```\n Test Files 88 passed (88)\n Tests 801 passed (801)\n Duration 16.78s\n```\n\n`npx tsc --noEmit` sort en 0. Les tests existants de `WebApp.test.tsx` passent sans modification : leur code `4821-93` traverse `normalize()` inchangé.\n\n## Dette à ouvrir, hors périmètre\n\nLa comparaison serveur (`crates/web-server/src/lib.rs:1612`) reste stricte sur la casse. Le fix d'aujourd'hui rend l'écran web tolérant, mais la tolérance vit côté client : tout autre client de l'API (curl, un futur client mobile natif, un test manuel) échouera encore sur `3f7a9c21`. Le backend devrait normaliser en majuscules à la comparaison, ce qui rendrait la normalisation UI redondante mais inoffensive. À toi de décider si ça mérite un ticket.",
|
||||
"stderr_tail": null
|
||||
},
|
||||
"completionDelivered": false
|
||||
},
|
||||
{
|
||||
"id": "cef21a7e-3eab-4bc5-a4d8-46af0cab4496",
|
||||
"projectId": "97b49ac2-8376-4aa3-8ea9-bf3ac81d0023",
|
||||
"ownerAgentId": "cd0b4cf1-1bef-4fae-ade5-f0a6b49bbaf5",
|
||||
"kind": {
|
||||
"kind": "headlessRendezvous",
|
||||
"requester_agent_id": "a6ced819-b893-4213-b003-9e9dc79b9641",
|
||||
"target_agent_id": "cd0b4cf1-1bef-4fae-ade5-f0a6b49bbaf5",
|
||||
"ticket_id": "690948d6-4063-4d28-ba3c-a6b6545f03c0",
|
||||
"conversation_id": "6bc594e8-a37c-0dbd-1de6-6e3b73002cb4"
|
||||
},
|
||||
"state": "running",
|
||||
"wakePolicy": "recordOnly",
|
||||
"createdAtMs": 1784277549807,
|
||||
"updatedAtMs": 1784277549807,
|
||||
"deadlineMs": null,
|
||||
"result": null,
|
||||
"completionDelivered": false
|
||||
|
||||
Reference in New Issue
Block a user