Ticket #3 vert (995/995 suite complète, tsc propre) : les dropdowns de la
vue Tickets ne sont plus rognées en bas de fenêtre.
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Remplace les <select> natifs de la vue Tickets (statut, priorité, tri,
lien, agent assigné/assistant, sprint) par TicketViewportSelect, qui
repositionne intelligemment son overlay selon l'espace disponible dans
la fenêtre au lieu de toujours ouvrir vers le bas.
QA vert : 80/80 (frontend/src/features/tickets), tsc --noEmit propre.
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Ajoute created_by sur IssueIndexEntry/TicketSummaryDto + filtre createdBy
(#5), et les use cases BulkUpdateIssueStatus/Priority + BulkDeleteIssues
avec les DTO/outils MCP idea_ticket_bulk_* associés (#6).
NON VERT : BulkDeleteIssues::execute référence BatchIssueResult::deleted(),
constructeur pas encore ajouté à BatchIssueResult (seuls ok/err existent) ->
`cargo check` échoue (E0599 dans application::issues::mod). Reste à
DevBackend avant toute QA/merge.
Branché sur feature/sdk-integration (dépend du commit #2 dans
orchestrator/mcp/server.rs et tools.rs) ; à rebaser sur develop une fois
feature/sdk-integration mergé.
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Wrapper MCP backend pur : dispatche N requêtes idea_ask_agent en parallèle
et retourne un résultat par requête, dans l'ordre, en rejetant les cibles
dupliquées avant dispatch. Aucun changement de domaine/application — pose
la primitive nécessaire au SDK (chantier feature/sdk-integration).
QA vert (ticket #2).
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Feature terminée et verte (Architect/DevBackend/DevFrontend/QA au vert) :
durcissement de la reprise headless inter-projets et persistance des
profils Opencode.
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Ticket #91 — libellé explicite « Appel X -> Y terminé/en échec/annulé »
pour les notifications de fin de background task issues d'un rendez-vous
inter-agent. Frontend pur, tests annoncés verts.
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Le toast de fin de tâche de fond liée à un rendez-vous inter-agent passe
de « Main -> DevBackend completed » à « Appel Main -> DevBackend terminé »
(idem en échec / annulé), pour nommer explicitement l'appel plutôt qu'un
état brut. Fallback générique conservé quand requester/target sont absents.
Validations obtenues avant commit : tests frontend annoncés verts pour #91.
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Câble un canal attachable au flux de sortie d'une tâche de fond (runner
infrastructure + commande app-tauri + port/adaptateurs frontend) et le
panneau ProjectWorkStatePanel s'y abonne pour un rendu live au lieu d'un
état figé au dernier snapshot.
Validations obtenues avant commit :
- cargo test -p infrastructure --test background_task_runner : vert
- cargo check -p backend -p app-tauri : vert
- npx vitest run src/features/workstate/workstate.test.tsx : vert
- npm run typecheck : vert
- verdict QA #58 : vert
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Un tour OpenCode sans texte mais terminé proprement (step_finish, ex.
tool-call-only) échouait en Decode alors qu'aucune erreur réelle ne
s'était produite : parse_jsonl_turn émet désormais un Final vide dans
ce cas au lieu d'un hard-fail, réservé aux flux vraiment vides,
ignorés ou seulement démarrés.
send() inversait aussi l'ordre de décision : un statut de sortie non
nul faisait échouer la délégation même quand stdout contenait un
événement terminal structuré exploitable (Final/Error). Le parse est
maintenant tenté avant l'évaluation du statut, et un événement
terminal structuré prévaut sur un exit code non nul.
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Résout le conflit d'imports/helpers de tests dans
crates/application/tests/model_server.rs par union des deux côtés
(imports application/domain + helpers aid/nid/sess).
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Implémentation du garde ModelServerProjectUseGuard pour séparer
les retours des agents entre projets concurrents.
- Garde RAII par LocalModelServerId partagé entre projets
- Refus inter-projets concurrent via model_server_in_use
- Partage intra-projet conservé avec refcount
- Libération automatique à la fermeture/erreur de session
Tests de validation: rejet projet distinct, compteur refs, libération retrait
Ajout du catalogue enrichi pour les modèles Codex et Claude avec:
- Compatibilité estimée avec la version CLI locale détectée
- Source d'origine (catalogue/Provider) pour chaque entrée
- Support du catalogue Provider API externe
- Matrice de compatibilité embarquée dans l'application
Frontend:
- UI de configuration des modèles avec affichage des états de compatibilité
- Suggestions dynamiques avec badges de compatibilité
- Messages d'aide contextuels (compatible/unknown/likelyTooRecent)
- Alertes non-bloquantes pour les modèles trop récents
- Gestion des échecs de catalogue avec saisie manuelle conservée
Backend:
- Ports CliVersionReader, ProviderModelCatalogue, CompatibilityMatrixSource
- Implémentations: ProcessCliVersionReader, HttpProviderModelCatalogue, EmbeddedCompatibilityMatrix
- Enrichissement des DTOs avec compatibility, cli_version, warnings
- Tests unitaires complets pour le resolver de catalogue
CloneOpenCodeProfileFromSeed::execute rejetait auparavant tout profil persisté squattant l'UUID déterministe du seed canonique opencode-llamacpp avec « internal error: canonical OpenCode seed is not an OpenCode profile ».
Root cause: un profil persisté converti en backend cloud GLM5.2 (ticket #92, opencodeProvider) conserve l'UUID du seed ; le find le matchait et le garde-fou seed.opencode.is_none() — non mis à jour pour le backend cloud — déclenchait une erreur Internal bloquante.
Correctif:
- Le find exige désormais un seed OpenCode valide (structured_adapter OpenCode + au moins un backend opencode local OU opencode_provider cloud), et retombe sur le seed catalogue sinon au lieu d'errer sur un état de store inattendu.
- L'override opencode local remet opencode_provider = None pour honorer l'invariant #97 opencode_backend_is_consistent (miroir de AgentProfile::with_opencode).
- 2 tests de régression (fallback catalogue, seed cloud accepté) + 1 test de symétrie save ajoutés.
Vérification: cargo test -p application --test profile_usecases -> 25 passed.
Les builders `with_opencode` / `with_opencode_provider` s'évacuent
réciproquement (dernier appel gagnant) pour honorer l'invariant
`opencode_backend_is_consistent`. Le use case SaveOpenCodeProviderProfile
route désormais via le builder au lieu de muter le champ directement — c'est
ce qui dupliquait `opencode` + `opencodeProvider` et forçait un repli sur
llamacpp même quand l'utilisateur choisissait un provider cloud.
Défense en profondeur côté store :
- `read_doc` répare les profils corrompus sur disque (drop du stale `opencode`)
- `save` refuse de persister un profil violant l'invariant via le nouveau
variant `StoreError::Invalid` (mappé vers `AppError::Invalid`)
Tests verts : builders last-wins (domain), save rejets + read repair
(infra, profile_store 10/10).
Refs #97