chore(gitignore): stop tracking local IdeA tickets state
This commit is contained in:
4
.gitignore
vendored
4
.gitignore
vendored
@ -66,3 +66,7 @@ Thumbs.db
|
||||
.ideai/conversations/
|
||||
.ideai/agents.json
|
||||
.ideai/background-tasks/
|
||||
|
||||
# IdeA local runtime state kept outside Git
|
||||
.ideai/tickets/
|
||||
.ideai/mcp-tool-permissions.json
|
||||
|
||||
@ -1,29 +0,0 @@
|
||||
---
|
||||
issueRef: "#1"
|
||||
version: 11
|
||||
updatedBy: {"kind":"user"}
|
||||
updatedAt: 1783175265022
|
||||
---
|
||||
- Cadrage: background-tasks-first-class-design. Arbitrage 5 écarts: b8-arbitration-outcomes.
|
||||
- FAIT B8 runner PTY + boucle sink fermée + refactor point-2. QA vert. Commit backend 8cac147.
|
||||
- FAIT UI cancel/retry câblés (cancel_background_task/retry_background_task). Commit frontend c179f93.
|
||||
- FAIT déclencheur in-app: surface MCP idea_run_in_background (BE-1+BE-2), commit f08dae6. Ferme l'écart de périmètre « aucun producteur ».
|
||||
- Dette tracée: #2 (PtyPort::wait + tee live), #3 (persistance sûre invocation/retry-after-reboot + énumération store), #5 (contrat DTO work-state).
|
||||
|
||||
## MAJ 2026-07-04 — part autonome de #1 clôturée (Main)
|
||||
- AppImage rebuild frais confirmé (build 2026-07-03 23:56 > dernier source 23:53), inclut T1+T3, NO_STRIP=true.
|
||||
- VALIDATION AUTOMATISÉE VERTE : cargo build --workspace OK ; cargo test -p application / -p app-tauri / -p infrastructure = 0 failed ; frontend npm run build OK + vitest 459/460. L'unique rouge = flake de timing src/features/permissions/permissions.test.tsx (passe en isolation 2/2, non touché par #1, pas une régression).
|
||||
- COMMITS Git sur feature/background-tasks-first-class : eb9cc16 (code T1+T3, 21 fichiers) + ebd992e (19 notes mémoire + MEMORY.md). AUCUN merge vers develop. Runtime .ideai/{background-tasks,proposals,tickets}/ volontairement non commités.
|
||||
|
||||
## ⚠️ MAJ 2026-07-04 — IMPACT TOPOLOGIE (constat Git, cadrage #4)
|
||||
- `feature/background-tasks-first-class` (#1) est DÉRIVÉE du `develop` ANORMAL/rembobiné (merge-base #1↔main = 1fc7869, pré-canonique ; a9653bc tip develop est ancêtre de #1). Donc #1 = baseline PRÉ-CANONIQUE (spawn_turn=0, run_turn batch, pas d'AgentTurnEvent).
|
||||
- La vraie ligne d'intégration est `main` (canonique, release ~01/07), PAS le develop rembobiné (18 commits en retard sur main). ⇒ la cible de merge « → develop » prévue au point 3 ci-dessous est INVALIDÉE.
|
||||
- #1 modifie massivement les fichiers divergés côté canonique : orchestrator/service.rs +425, domain/events.rs +184, lifecycle.rs +83, session/codex.rs. ⇒ portage sur canonique = CONFLITS NON TRIVIAUX attendus, pas un simple changement de cible.
|
||||
- PLAN Git (Phase C, à faire quand on reprendra #1) : branche fraîche `feature/background-tasks-first-class-canonical` depuis main + cherry-pick séquentiel des 17 commits (ancienne branche gardée comme filet), conflits sémantiques service/events escaladés à DevBackend/Architect, puis QA avant tout merge.
|
||||
- Décision de reconstruction de `develop` sur `main` : DESTRUCTIVE (rewrite branche partagée) → en attente validation utilisateur.
|
||||
|
||||
## RESTE — DÉPENDANT UTILISATEUR (Main ne peut pas seul)
|
||||
1. Re-QA LIVE T3 : relancer l'AppImage fraîche puis vérifier onglet Work → Cancel/Retry (T3-a..f du cadrage workstate-background-tasks-projection-fix). QA non pilotable depuis sandbox → besoin app lancée.
|
||||
2. T2 — reconcile après reboot (fin AVANT wake), protocole MANUEL, coordination reboot utilisateur.
|
||||
3. [CIBLE À REVOIR] merge de #1 : ne plus viser le develop rembobiné. Porter #1 sur canonique (Phase C ci-dessus) PUIS merger vers develop-reconstruit/main. Dépend de la décision de reconstruction de develop.
|
||||
Main travaille sur #4 (annonces inter-agent) en attendant la dispo utilisateur pour 1-2-3.
|
||||
@ -1,24 +0,0 @@
|
||||
---
|
||||
id: "ec19c041-7a44-456d-994d-f0dcb7c52f39"
|
||||
number: 1
|
||||
title: "Tâches de fond — finaliser B8 (runner PTY) et clôturer le chantier"
|
||||
status: "closed"
|
||||
priority: "medium"
|
||||
links: []
|
||||
agentRefs: [{"agentId":"a6ced819-b893-4213-b003-9e9dc79b9641","role":"assigned"}]
|
||||
createdBy: {"kind":"user"}
|
||||
updatedBy: {"kind":"user"}
|
||||
createdAt: 1783026129089
|
||||
updatedAt: 1783175265022
|
||||
version: 11
|
||||
---
|
||||
Description :
|
||||
|
||||
Le chantier « tâches de fond de 1re classe » est livré et QA-vert jusqu'à B7 inclus (mailbox bornée, rendez-vous inter-agent comme tâche durable, reconcile au boot, réveil du propriétaire, UI F1–F4). Commité sur feature/background-tasks-first-class (e05edc6 backend, 5d88c95 frontend), non mergé. Reste à fermer les points suivants avant de considérer le chantier terminé.
|
||||
|
||||
Reste à faire :
|
||||
|
||||
- [ ] B8 — runner de commandes couplé PTY : créer un BackgroundTask{kind: Command} au spawn d'une commande longue (côté pty.rs / LocalProcessSpawner) et pousser exit/stdout/stderr dans le completion sink. C'est ce qui active le flux run_in_background complet : une commande qui finit après la fin du tour de l'agent réveille automatiquement son propriétaire avec le résultat. Aujourd'hui le sink est prêt mais aucun runner concret ne s'y abonne.
|
||||
- [ ] UI cancel / retry des tâches de fond : les boutons existent mais sont désactivés faute de commande Tauri. Exposer cancel/retry (dépend de B8) et brancher l'UI.
|
||||
- [ ] Validation live end-to-end de la feature dans l'app réelle : lancer un build/commande longue en run_in_background, laisser le tour se terminer, vérifier que le propriétaire est bien re-réveillé avec le résultat (et idem après redémarrage d'IdeA entre la fin et le wake — le reconcile doit retrouver la complétion).
|
||||
- [ ] Merge feature/background-tasks-first-class → develop (sur validation) : résorbe aussi les 4 tests de protocole MCP périmés qui sont encore rouges sur develop (le fix d'alignement vit sur cette branche).
|
||||
@ -1,6 +0,0 @@
|
||||
---
|
||||
issueRef: "#10"
|
||||
version: 5
|
||||
updatedBy: {"kind":"agent","agent_id":"a6ced819-b893-4213-b003-9e9dc79b9641"}
|
||||
updatedAt: 1783241883970
|
||||
---
|
||||
@ -1,15 +0,0 @@
|
||||
---
|
||||
id: "37bfbb89-a8a5-475f-91bf-ecfd60ee4203"
|
||||
number: 10
|
||||
title: "Ticket par sprint"
|
||||
status: "closed"
|
||||
priority: "medium"
|
||||
links: []
|
||||
agentRefs: [{"agentId":"a6ced819-b893-4213-b003-9e9dc79b9641","role":"assigned"}]
|
||||
createdBy: {"kind":"user"}
|
||||
updatedBy: {"kind":"agent","agent_id":"a6ced819-b893-4213-b003-9e9dc79b9641"}
|
||||
createdAt: 1783183841014
|
||||
updatedAt: 1783241883970
|
||||
version: 5
|
||||
---
|
||||
J'aimerais pouvoir regrouper mes tickets en sprints. C'est a dire en catégories qui auraient elles meme un ordre d'execution (sprint 1, sprint 2 etc)
|
||||
@ -1,6 +0,0 @@
|
||||
---
|
||||
issueRef: "#100"
|
||||
version: 3
|
||||
updatedBy: {"kind":"user"}
|
||||
updatedAt: 1784993984569
|
||||
---
|
||||
@ -1,16 +0,0 @@
|
||||
---
|
||||
id: "4709958c-5082-44fd-a1fd-d6bad85f9361"
|
||||
number: 100
|
||||
title: "[Bug] Problème sur le scroll des agents OpenCode"
|
||||
status: "closed"
|
||||
priority: "high"
|
||||
sprint: "e28a4d53-8bd2-446a-b0ac-2a017373b8b2"
|
||||
links: []
|
||||
agentRefs: []
|
||||
createdBy: {"kind":"user"}
|
||||
updatedBy: {"kind":"agent","agent_id":"a6ced819-b893-4213-b003-9e9dc79b9641"}
|
||||
createdAt: 1784992615586
|
||||
updatedAt: 1785083912470
|
||||
version: 4
|
||||
---
|
||||
Quand un agent est un agent opencode, je ne peux aps scroll très haut dans sa cellule.
|
||||
@ -1,96 +0,0 @@
|
||||
---
|
||||
issueRef: "#101"
|
||||
version: 7
|
||||
updatedBy: {"kind":"agent","agent_id":"a6ced819-b893-4213-b003-9e9dc79b9641"}
|
||||
updatedAt: 1785011116365
|
||||
---
|
||||
# Carnet #101 — défaut d'isolation multi-projet (cause racine figée)
|
||||
|
||||
> Diagnostic Architect (2026-07-25). Source de vérité du fix. Mémoire durable :
|
||||
> `ticket101-cross-talk-multi-project-rootcause`.
|
||||
|
||||
## Cause racine
|
||||
Stores disque IdeA **correctement scoppés par projet** (mémoire, contexte, handoff, live-state lus
|
||||
depuis `input.project.root` ; agents persistés dans `.ideai/agents.json` par root projet, **sans
|
||||
re-mint des UUID à l'ouverture**). Mais plusieurs **registres mémoire runtime restent globaux,
|
||||
indexés par `AgentId` seul** → deux projets ouverts (surtout si l'un est une copie) peuvent porter
|
||||
les **mêmes `AgentId`** et le runtime les confond.
|
||||
|
||||
### 2 manifestations, même défaut
|
||||
- **A — contamination du contexte d'inférence** : conversation/session d'un projet réutilisée pour
|
||||
l'autre → contexte injecté à l'agent contaminé (preuve : pseudo-branche `wear-os-watch-sync`
|
||||
créée par l'agent Git avec un nom de l'autre projet).
|
||||
- **B — notification de tâche backend perdue / agent s'arrête** (sujet original) : complétion
|
||||
livrable/bloquée/réveillant la mauvaise session.
|
||||
|
||||
## Points précis (registres par `AgentId` seul à requalifier)
|
||||
- ConversationRegistry global + `ConversationId` dérivé des UUID agents seuls :
|
||||
`crates/domain/src/conversation.rs:71`, `crates/infrastructure/src/conversation/mod.rs:41`,
|
||||
orchestrateur `crates/application/src/orchestrator/service.rs:2192` (et `:2293`, `:2368`).
|
||||
- Sessions PTY/structured par `agent_id` seul :
|
||||
`crates/application/src/terminal/registry.rs:182,437`.
|
||||
- Verrous ask / busy-state / liveness / délégations différées :
|
||||
`crates/application/src/orchestrator/service.rs:418`,
|
||||
`crates/infrastructure/src/input/mod.rs:47`.
|
||||
- Inbox/mailbox par `AgentId` seul : `crates/domain/src/inbox.rs:68,156`,
|
||||
`crates/infrastructure/src/input/mod.rs:1052`, `crates/infrastructure/src/mailbox/mod.rs:44`.
|
||||
- Wake par `AgentId` seul : `crates/application/src/orchestrator/wake.rs:87`,
|
||||
provider `crates/backend/src/lib.rs:687`.
|
||||
|
||||
### Pour B — distinction runtime vs modèle
|
||||
La chaîne sink→`project_id`→wake est **correcte** jusqu'au bridge
|
||||
(`crates/infrastructure/src/background_task/sink.rs:23,142` ; `crates/backend/src/lib.rs:2228`
|
||||
recharge le projet par `project_id` puis `wake_agent`). Le défaut réapparaît juste après
|
||||
(inbox/mailbox/busy/session par AgentId seul). **Runtime IdeA suspecté en premier.** GLM 5.2 n'est
|
||||
l'hypothèse principale que si les logs prouvent enqueue+wake+`BackgroundTaskCompletionDelivered`
|
||||
sur le bon projet sans reprise. Traces : `lib.rs:2238`, `wake.rs:93`.
|
||||
|
||||
## Décision utilisateur
|
||||
**Lancer le fix structurel maintenant (lots 1-2).** La collision d'UUID et les logs B se
|
||||
vérifieront en parallèle.
|
||||
|
||||
## Périmètre DevBackend (lots 1-2 de ce fix)
|
||||
- **Lot 1** : introduire une clé runtime scellée `RuntimeAgentKey { project_id, agent_id }` ;
|
||||
interdire toute map app-wide indexée par `AgentId` seul.
|
||||
- **Lot 2** : propager la clé dans `AgentInbox`, `InputMediator`, `AgentMailbox`,
|
||||
busy/liveness/deferred, wake, session lookup, ask-locks. **Correctif structurel commun à A et B.**
|
||||
|
||||
Lots suivants (3-6, hors premier passage) : qualifier ConversationId/registry par projet (lot 3) ;
|
||||
requalifier `TerminalSessions`/`StructuredSessions` par `(project_id, agent_id)` +
|
||||
`AppWakeSessionProvider` refuse l'autre projet (lot 4) ; audit `session_limit`/tables reprise (lot 5) ;
|
||||
télémétrie `project_id` sur logs diag wake/routage (lot 6).
|
||||
|
||||
## Invariants
|
||||
- Sources de contexte sur disque restent root-scopées (ne pas régresser).
|
||||
- Templates/profils globaux restent globaux produit (pas de vecteur de session/conversation partagée).
|
||||
- Un projet non-actif doit continuer à recevoir ses wakes et complétions.
|
||||
- Pas de régression OpenCode/Codex/Claude (correctif transverse runtime, pas moteur-spécifique).
|
||||
- Aucun nouveau DTO frontend pour la correction minimale.
|
||||
|
||||
## QA — critère de vérité
|
||||
Test d'intégration **non-cross-talk** : 2 projets ouverts avec **volontairement les mêmes `AgentId`** :
|
||||
- délégation projet A ne réutilise jamais session/conversation vivante de projet B ;
|
||||
- complétion `(projet A, agent X)` n'entre ni dans l'inbox ni dans la session de `(projet B, agent X)` ;
|
||||
- wake d'un projet non-actif fonctionne ;
|
||||
- collision d'ids qui échouait avant → verte sur PTY, structured et background wake.
|
||||
|
||||
## Clôture 2026-07-25
|
||||
- Correctif livré sur `feature/ticket101-multi-project-isolation` puis mergé localement dans `develop`.
|
||||
- Commit feature : `6e98fd8 fix(runtime): isolate agent state by project (#101)`.
|
||||
- Merge local : `merge: integrate ticket 101 multi-project isolation`.
|
||||
- QA ciblée verte :
|
||||
- `cargo test -p application --test agent_wake --test orchestrator_service --test structured_registry_d1 --test structured_launch_d3 --test session_limit_service --test session_limit_t4 --test workstate --test workstate_actions`
|
||||
- `cargo test -p infrastructure --test agent_inbox --test mcp_server`
|
||||
- `cargo test -p app-tauri --test session_limit_wiring`
|
||||
- `cargo test -p application`
|
||||
- `cargo test -p app-tauri --tests`
|
||||
- Réserve connue : `cargo test -p infrastructure` complet reste rouge dans le sandbox QA sur tests `openai_compat` à cause du bind local interdit (`Operation not permitted`), sans signal de régression #101.
|
||||
|
||||
## Hors périmètre
|
||||
- #91 (popup de notification) : purement front, indépendant.
|
||||
- Remint systématique des AgentId à l'ouverture : non retenu (la clé runtime rend la collision
|
||||
inoffensive même sans remint).
|
||||
|
||||
## Lié
|
||||
- #91 (relatesTo). Mémoires : `background-tasks-first-class-design`, `b8-command-runner-pty-framing`,
|
||||
`mcp-bridge-and-delegation-runtime-notes` (règle rebuild AppImage).
|
||||
@ -1,16 +0,0 @@
|
||||
---
|
||||
id: "05f9f05b-97d4-4ae2-9fd9-220dd71f7231"
|
||||
number: 101
|
||||
title: "[Bug] Soucis de retour de notification sur les taches backend"
|
||||
status: "closed"
|
||||
priority: "critical"
|
||||
sprint: "e28a4d53-8bd2-446a-b0ac-2a017373b8b2"
|
||||
links: []
|
||||
agentRefs: [{"agentId":"a6ced819-b893-4213-b003-9e9dc79b9641","role":"assigned"}]
|
||||
createdBy: {"kind":"user"}
|
||||
updatedBy: {"kind":"agent","agent_id":"a6ced819-b893-4213-b003-9e9dc79b9641"}
|
||||
createdAt: 1784993230013
|
||||
updatedAt: 1785011116365
|
||||
version: 7
|
||||
---
|
||||
Lorsque un agent Opencode lance une tache backend, il s'arrete de travailler et je ne suis pas sur q'uil y ai un jour un retour de notification. Je ne sais aps si le soucis provient de OpenCode ou s'il provient du model (GLM 5.2 ici)
|
||||
@ -1,6 +0,0 @@
|
||||
---
|
||||
issueRef: "#102"
|
||||
version: 4
|
||||
updatedBy: {"kind":"user"}
|
||||
updatedAt: 1784993980505
|
||||
---
|
||||
@ -1,16 +0,0 @@
|
||||
---
|
||||
id: "e91fd358-da94-4382-aa70-6a3fe5a63840"
|
||||
number: 102
|
||||
title: "[Bug] Devoir resize les cellule pour afficher la TUI d'un agent"
|
||||
status: "closed"
|
||||
priority: "medium"
|
||||
sprint: "e28a4d53-8bd2-446a-b0ac-2a017373b8b2"
|
||||
links: []
|
||||
agentRefs: [{"agentId":"a6ced819-b893-4213-b003-9e9dc79b9641","role":"assigned"}]
|
||||
createdBy: {"kind":"user"}
|
||||
updatedBy: {"kind":"agent","agent_id":"a6ced819-b893-4213-b003-9e9dc79b9641"}
|
||||
createdAt: 1784993319700
|
||||
updatedAt: 1785083912470
|
||||
version: 5
|
||||
---
|
||||
J'ai toujours un soucis qui fait que quand je switch de projet IdeA ou de layout ou que j'ajoute des cellules ou autres, je suis obligé de resize un coup la cellule pour que son constenu s'affiche correctement
|
||||
@ -1,99 +0,0 @@
|
||||
---
|
||||
issueRef: "#103"
|
||||
version: 4
|
||||
updatedBy: {"kind":"agent","agent_id":"a6ced819-b893-4213-b003-9e9dc79b9641"}
|
||||
updatedAt: 1785013507979
|
||||
---
|
||||
# Carnet #103 — permission réseau exposée dans IdeA
|
||||
|
||||
## Problème
|
||||
Certaines commandes lancées par les agents s'exécutent dans un environnement où le réseau est restreint, sans visibilité ni action claire dans IdeA. Exemple live : rebuild AppImage OK jusqu'au bundling, puis `appimagetool` échoue à télécharger le runtime GitHub car la session agent est `network restricted` + `approval policy: never`.
|
||||
|
||||
## Décision UX
|
||||
Mémoire : `ticket103-network-permission-ux-surface`.
|
||||
|
||||
- Surface principale : `Permissions > Système`.
|
||||
- Miroirs de lecture : badge compact dans `Agents`, bannière/erreur contextualisée dans `Terminal`.
|
||||
- États visibles : `Réseau autorisé`, `Réseau interdit`, `Demande d'autorisation`, `Verrouillé par le runtime`.
|
||||
- Distinction obligatoire : politique voulue, état effectif, verrou runtime.
|
||||
- Si le runtime externe ne permet pas l'élévation dans la session active : contrôle read-only + explication explicite.
|
||||
|
||||
## Cadrage architecture
|
||||
Ne pas étendre le modèle existant `ProjectPermissions` fichier/bash : le réseau n'est ni une capability filesystem ni une règle Landlock. Ajouter un modèle/read-model séparé de permissions système.
|
||||
|
||||
### Domaine / DTO V1
|
||||
- `NetworkPolicy = "allow" | "deny" | "ask"`.
|
||||
- `SystemPermissionSet { network?: NetworkPolicy }`.
|
||||
- `ProjectSystemPermissions { version, projectDefault?: SystemPermissionSet, agents?: [{ agentId, permissions: SystemPermissionSet }] }`.
|
||||
- `ResolvedAgentSystemPermissions` :
|
||||
- `wanted: NetworkPolicy | null`
|
||||
- `effective: NetworkPolicy`
|
||||
- `runtimeLock: { state: "none" | "locked", source?: string, reason?: string }`
|
||||
- `control: { mode: "editable" | "readOnly", reason?: string }`
|
||||
|
||||
### Ports / use cases
|
||||
- `SystemPermissionStore`.
|
||||
- `GetProjectSystemPermissions`.
|
||||
- `UpdateProjectSystemPermissions`.
|
||||
- `UpdateAgentSystemPermissions`.
|
||||
- `ResolveAgentSystemPermissions`.
|
||||
- `RuntimePermissionProbe` : expose ce que le runtime hôte/fournisseur autorise réellement et s'il verrouille le réseau.
|
||||
|
||||
### API/commands attendus
|
||||
- `get_project_system_permissions(projectId) -> ProjectSystemPermissionsDto`
|
||||
- `update_project_system_permissions({ projectId, permissions }) -> ProjectSystemPermissionsDto`
|
||||
- `update_agent_system_permissions({ projectId, agentId, permissions }) -> ProjectSystemPermissionsDto`
|
||||
- `resolve_agent_system_permissions({ projectId, agentId }) -> ResolvedAgentSystemPermissionsDto`
|
||||
|
||||
### Limite produit V1
|
||||
Implémentable maintenant : persister la politique voulue, afficher `wanted/effective/runtimeLock`, rendre le contrôle read-only si runtime verrouillé/non inspectable, badges agents, bannière terminal.
|
||||
|
||||
Non promis en V1 : changer effectivement la permission réseau d'une session fournisseur déjà lancée ou élever un runtime externe `network restricted` / `approval never`. IdeA doit l'expliquer plutôt que simuler une élévation.
|
||||
|
||||
## Découpage
|
||||
### DevBackend
|
||||
1. Ajouter domaine `system permissions` séparé de LP1 permissions fichier/bash.
|
||||
2. Ajouter store + use cases + DTO + commands Tauri/HTTP.
|
||||
3. Ajouter `RuntimePermissionProbe` read-only au composition root.
|
||||
4. Ajouter read-model `resolve_agent_system_permissions`.
|
||||
5. Optionnel si simple : mapper des échecs réseau vers un code stable `NETWORK_LOCKED` ou `NETWORK_UNAVAILABLE`.
|
||||
|
||||
### DevFrontend
|
||||
1. Étendre types domaine, ports, adapters Tauri/HTTP/mock.
|
||||
2. Ajouter la sous-section `Réseau` dans `Permissions > Système`.
|
||||
3. Ajouter badge compact dans `Agents`.
|
||||
4. Ajouter bannière/erreur terminal contextualisée pour état verrouillé/échec réseau.
|
||||
|
||||
### QA
|
||||
- Projet sans config : état cohérent, pas de faux `allow`.
|
||||
- Save project default puis override agent : relecture identique.
|
||||
- Resolve distingue `wanted`, `effective`, `runtimeLock`.
|
||||
- Probe `locked` : contrôle read-only + message visible.
|
||||
- Non-régression `Permissions > Système` existant fichier/bash.
|
||||
- Aucun moteur ne reçoit de faux flag réseau au spawn.
|
||||
- Badge agents et bannière terminal reflètent l'état effectif.
|
||||
|
||||
## Validation 2026-07-25
|
||||
QA verte sur le périmètre #103.
|
||||
|
||||
Commandes exécutées par QA :
|
||||
- `cargo test -p domain system_permissions`
|
||||
- `cargo test -p application --test system_permission_usecases`
|
||||
- `cargo test -p infrastructure --test system_permission_store`
|
||||
- `cargo test -p app-tauri --test dto_system_permissions`
|
||||
- `cargo test -p web-server allowlisted`
|
||||
- `npm run typecheck`
|
||||
- `npx vitest run src/features/permissions/permissions.test.tsx src/features/agents/agents.test.tsx src/features/terminals/TerminalView.test.tsx`
|
||||
- `npx vitest run src/features/permissions/permissions.test.tsx`
|
||||
|
||||
Résultats : backend ciblé vert, frontend typecheck vert, tests frontend ciblés 49 passed.
|
||||
|
||||
## État Git
|
||||
Implémentation validée dans le working tree courant, mais commit/merge non réalisé par Main :
|
||||
- l'agent Git headless renvoie un pseudo-appel outil au lieu d'agir ;
|
||||
- Main ne peut pas écrire `.git/index.lock` depuis cette session (`Read-only file system`).
|
||||
|
||||
Le commit local reste à faire manuellement ou via un agent Git fonctionnel.
|
||||
|
||||
## Critère de clôture
|
||||
Tests pertinents verts, commit/merge local par Git, puis rebuild AppImage.
|
||||
@ -1,39 +0,0 @@
|
||||
---
|
||||
id: "3d9021da-26c3-439d-9463-8d206bd06f1b"
|
||||
number: 103
|
||||
title: "Exposer et piloter la permission réseau des agents/commandes dans IdeA"
|
||||
status: "qa"
|
||||
priority: "high"
|
||||
sprint: null
|
||||
links: []
|
||||
agentRefs: [{"agentId":"a6ced819-b893-4213-b003-9e9dc79b9641","role":"assigned"}]
|
||||
createdBy: {"kind":"agent","agent_id":"a6ced819-b893-4213-b003-9e9dc79b9641"}
|
||||
updatedBy: {"kind":"agent","agent_id":"a6ced819-b893-4213-b003-9e9dc79b9641"}
|
||||
createdAt: 1785011668081
|
||||
updatedAt: 1785013507979
|
||||
version: 4
|
||||
---
|
||||
## Problème
|
||||
|
||||
Aujourd'hui certaines commandes lancées par les agents s'exécutent dans un environnement où le réseau est restreint, sans que l'utilisateur puisse le voir ni l'autoriser depuis IdeA. Exemple réel : rebuild AppImage OK jusqu'au bundling, puis `appimagetool` échoue à télécharger le runtime AppImage depuis GitHub (`Failed to download runtime: server returned status code 0`) parce que la session agent a `network restricted` et `approval policy: never`.
|
||||
|
||||
## Besoin utilisateur
|
||||
|
||||
Depuis IdeA, l'utilisateur doit pouvoir comprendre et piloter cette permission réseau :
|
||||
- voir qu'un agent/profil/session est en mode réseau interdit ou autorisé ;
|
||||
- configurer la politique réseau attendue pour les agents/commandes ;
|
||||
- éviter les échecs opaques de commandes qui ont légitimement besoin d'Internet (build, install, téléchargement runtime, docs, dépendances) ;
|
||||
- conserver un comportement sûr par défaut et explicite.
|
||||
|
||||
## Attendu produit
|
||||
|
||||
Définir puis implémenter une surface IdeA pour exposer cette permission. La solution doit respecter le modèle de permissions/sandbox existant et clarifier la limite éventuelle : si le sandbox fournisseur impose `network restricted` sans possibilité d'élévation runtime, IdeA doit l'expliquer plutôt que faire croire que le réseau est activable.
|
||||
|
||||
## Critères d'acceptation
|
||||
|
||||
- Une surface UI ou configuration explicite permet de voir la politique réseau applicable aux agents/commandes.
|
||||
- L'utilisateur dispose d'une action ou d'un réglage clair quand IdeA peut piloter cette permission.
|
||||
- Si la permission est imposée par le runtime externe et non modifiable, l'UI l'indique clairement.
|
||||
- Les agents/commandes ne gagnent pas l'accès réseau silencieusement.
|
||||
- Tests pertinents verts.
|
||||
- AppImage reconstruite après livraison.
|
||||
@ -1,6 +0,0 @@
|
||||
---
|
||||
issueRef: "#107"
|
||||
version: 3
|
||||
updatedBy: {"kind":"user"}
|
||||
updatedAt: 1785136945441
|
||||
---
|
||||
@ -1,17 +0,0 @@
|
||||
---
|
||||
id: "6a79006b-0201-4176-ae54-39a05cc3baa6"
|
||||
number: 107
|
||||
title: "[Bug] croisement entre les projet des retours des agents"
|
||||
status: "open"
|
||||
priority: "critical"
|
||||
sprint: null
|
||||
links: []
|
||||
agentRefs: [{"agentId":"a6ced819-b893-4213-b003-9e9dc79b9641","role":"assigned"}]
|
||||
createdBy: {"kind":"user"}
|
||||
updatedBy: {"kind":"user"}
|
||||
createdAt: 1785136727824
|
||||
updatedAt: 1785136945441
|
||||
version: 3
|
||||
---
|
||||
Il y a un soucis très important que j'ai constatés. J'ai actuellement 2 projets ouverts: IdeA et GameTime. Les deux projets travaillaient en même temps et j'ai vu GameTime qui semblait récupérer une requete du projet IdeA. Pour plus de précision, sur mes deux projets, j'ai un agent Git qui utilise OpenCode et un modelle local llamacpp, et j'ia eu l'impression qu'ils ont tous les deux appelé leur agent Git mais GameTime à recus la réponse de IdeA car la réponse parlait d'une branche du projet IdeA.
|
||||
Je ne suis pas totalement sur de ce que j'avance, la seule chose dont je suis sur, c'est que GameTime s'est vu adressé une réponse qui était déstinée au projet IdeA.
|
||||
@ -1,6 +0,0 @@
|
||||
---
|
||||
issueRef: "#11"
|
||||
version: 6
|
||||
updatedBy: {"kind":"agent","agent_id":"a6ced819-b893-4213-b003-9e9dc79b9641"}
|
||||
updatedAt: 1783278726067
|
||||
---
|
||||
@ -1,15 +0,0 @@
|
||||
---
|
||||
id: "dad53cb9-a818-4475-be12-fd3ba6c59638"
|
||||
number: 11
|
||||
title: "Interface de création de sprint"
|
||||
status: "closed"
|
||||
priority: "medium"
|
||||
links: [{"target":"#10","kind":"dependsOn"}]
|
||||
agentRefs: [{"agentId":"a6ced819-b893-4213-b003-9e9dc79b9641","role":"assigned"}]
|
||||
createdBy: {"kind":"user"}
|
||||
updatedBy: {"kind":"agent","agent_id":"a6ced819-b893-4213-b003-9e9dc79b9641"}
|
||||
createdAt: 1783183911244
|
||||
updatedAt: 1783278726067
|
||||
version: 6
|
||||
---
|
||||
Pour créer des sprints, j'aimerais une inteface de création dans laquelle je pourrais facilement ajouter/enlever des tickets de mes différents sprint
|
||||
@ -1,6 +0,0 @@
|
||||
---
|
||||
issueRef: "#12"
|
||||
version: 5
|
||||
updatedBy: {"kind":"agent","agent_id":"a6ced819-b893-4213-b003-9e9dc79b9641"}
|
||||
updatedAt: 1783312900907
|
||||
---
|
||||
@ -1,15 +0,0 @@
|
||||
---
|
||||
id: "fb8a73f9-c871-4513-aa09-b35fbbef637a"
|
||||
number: 12
|
||||
title: "Checkbox pour les filters des tickets"
|
||||
status: "closed"
|
||||
priority: "low"
|
||||
links: []
|
||||
agentRefs: [{"agentId":"a6ced819-b893-4213-b003-9e9dc79b9641","role":"assigned"}]
|
||||
createdBy: {"kind":"user"}
|
||||
updatedBy: {"kind":"agent","agent_id":"a6ced819-b893-4213-b003-9e9dc79b9641"}
|
||||
createdAt: 1783184054842
|
||||
updatedAt: 1783312900907
|
||||
version: 5
|
||||
---
|
||||
Pour les filtres des tickets, j'aimerais qu'on ai une checkbox plutot que la selection d'un seul filtre, de façon a pouvoir faire des combinaisons de plusieurs priorité et de plusieurs status par exemple
|
||||
@ -1,54 +0,0 @@
|
||||
---
|
||||
issueRef: "#13"
|
||||
version: 19
|
||||
updatedBy: {"kind":"agent","agent_id":"a6ced819-b893-4213-b003-9e9dc79b9641"}
|
||||
updatedAt: 1784193634690
|
||||
---
|
||||
|
||||
# Ticket #13 — Server/client mode (carnet de chantier)
|
||||
|
||||
Ticket gated : review agent-utilisateur faite 2026-07-15. Base develop. Aucune action sortante.
|
||||
|
||||
## Arbitrages produit validés (utilisateur)
|
||||
- Remote perso, 1 SEUL user. Pas de multi-tenant. CLI natif via WS PTY, xterm.js inchangé, PTY serveur. SSH écarté.
|
||||
- Desktop Tauri ET client/serveur sur cœur backend commun. Exposition Internet ⇒ TLS/reverse proxy obligatoire.
|
||||
- Packaging `idea --serve`, artefact unique. Auth pairing code + cookie session, jamais dans l'URL.
|
||||
- Multi-fenêtres OS HORS V1 web. B6→B8 + servir dist, validation live groupée à la fin.
|
||||
|
||||
## Contrat de transport figé (Architect)
|
||||
- `POST /api/invoke {command,args}` (allowlist read-only). Cookie session `HttpOnly,Secure,SameSite=Strict` au pairing (`POST /api/pair`). `POST /api/logout` = révocation (B8). Cookie invalide→401 ; mauvais code→403 ; Origin refusée→403.
|
||||
- Frames WS JSON base64, ack unifié `terminal.attached`, output APRÈS l'ack. structured→UNSUPPORTED.
|
||||
- Flags : `--listen`, `--public-origin`, `--allow-remote`, `--trust-reverse-proxy`, `--app-data-dir`, `--web-root` (B8).
|
||||
|
||||
## Plan de lots — TOUS LES LOTS DEV LIVRÉS ✅
|
||||
B0→B8 + F1→F6 livrés/verts/committés. + correctifs live écarts 1/2. Reste : finir la validation live groupée (utilisateur) puis merge develop + clôture.
|
||||
|
||||
## Livrés VERT
|
||||
- develop (e457152) : B0 5505acc · B1 955db79 · B2 c8fef2a · F1 e0cdb4a · B3 4ed0b16 · B4 fa353f6 · F2 e500e31.
|
||||
- feature/ticket13-pty-websocket : B5 917be99 · F3 7487902 · B6 6391d1c · F4 5254f16 · B7 1bc5217 · F5 dd1d083 · B8 d538808 · F6 6117177 · **fix live écarts 1+2 c9ce3d7**.
|
||||
- B8 : sert dist/ same-origin, serve_static durci, `/api/logout`, logs sécurité, doc remote. 57/57.
|
||||
- F6 : logout, 401→pairing, bannière reconnexion, serveur indispo. build+vitest 758/758.
|
||||
|
||||
## ⚙️ Validation live 1er passage (utilisateur) — 3 écarts remontés
|
||||
1. **Erreur `__TAURI_INTERNALS__ undefined` + projets vides** = MA commande de test était incomplète (build sans `VITE_TRANSPORT=http` → build desktop dans le navigateur ; et `--app-data-dir` non pointé sur le dossier desktop). PAS un bug de code.
|
||||
2. **Défaut app-data-dir désaligné** (RÉSOLU c9ce3d7) : `default_app_data_dir()` retournait `~/.local/share/IdeA` alors que le desktop = identifier tauri `app.idea.ide` (`~/.local/share/app.idea.ide`). Corrigé : précédence `--app-data-dir` > `IDEA_APP_DATA_DIR` > `$XDG_DATA_HOME/app.idea.ide` > `$HOME/.local/share/app.idea.ide` + log démarrage `idea --serve: app data dir = <path>`. Doc corrigée (npm + VITE_TRANSPORT=http + avertissement double-writer). Garde-fou lock inter-process app-data-dir = ticket court à créer AVANT d'ouvrir des écritures web.
|
||||
3. **Bouton Browse (créer/ajouter projet) inopérant en web** = `pickFolder()`→`UNSUPPORTED_ON_WEB` (dialogue natif OS absent du navigateur). PAS régression : report documenté F1. Sélection d'un projet EXISTANT couverte par list_projects/open_project (OK une fois écart 2 corrigé). Créer un NOUVEAU projet en web = nouveau lot (folder browser serveur sandboxé + create_project write) → **ticket #64 créé** (dependsOn #13), cadré par Architect, hors #13.
|
||||
|
||||
## ⚠️ RESTE : re-passage validation live (utilisateur, HORS SANDBOX)
|
||||
Commande corrigée :
|
||||
1. `cd frontend && VITE_TRANSPORT=http npx vite build` (npm, jamais pnpm — voir mémoire `frontend-uses-npm-not-pnpm`).
|
||||
2. Fermer l'app desktop, puis `cargo run --release -p app-tauri -- --serve --web-root frontend/dist --app-data-dir ~/.local/share/app.idea.ide` (pairing code + app data dir sur stderr).
|
||||
3. Navigateur `http://127.0.0.1:17373` → écran pairing → code.
|
||||
4. Vérifier : liste projets (existants visibles), ouvrir projet, terminal CLI (frappe→serveur, reload→réattache/scrollback), cellule agent, surfaces live (workstate/background Cancel-Retry/inbox), reconnexion, logout→pairing.
|
||||
|
||||
## Réserves / écarts V1 (acceptés)
|
||||
- Replay V1 = repaint scrollback complet. Multi-onglets « dernier gagne » silencieux. F4 write-portal NON câblé web. Browse créer-projet web → #64. Lock double-writer app-data-dir → ticket court à créer.
|
||||
|
||||
## Branches
|
||||
`feature/ticket13-pty-websocket` (courante). À merger dans develop après validation live OK.
|
||||
|
||||
## Prochaine étape
|
||||
Re-passage validation live (commande corrigée ci-dessus). Si OK → Git merge dans develop → clôture #13. #64 (Browse web) à planifier après. Aucune action sortante sans validation utilisateur.
|
||||
|
||||
## Dette hors chantier
|
||||
Warnings clippy pré-existants crates/domain (fileguard/profile/sprint).
|
||||
@ -1,16 +0,0 @@
|
||||
---
|
||||
id: "036783fa-9856-4643-8c28-653b93ac36e1"
|
||||
number: 13
|
||||
title: "Server/client mode"
|
||||
status: "closed"
|
||||
priority: "low"
|
||||
sprint: "028179b1-eaf4-41e9-9c1f-7c37125117e6"
|
||||
links: []
|
||||
agentRefs: [{"agentId":"a6ced819-b893-4213-b003-9e9dc79b9641","role":"assigned"}]
|
||||
createdBy: {"kind":"user"}
|
||||
updatedBy: {"kind":"agent","agent_id":"a6ced819-b893-4213-b003-9e9dc79b9641"}
|
||||
createdAt: 1783184188272
|
||||
updatedAt: 1784193634690
|
||||
version: 19
|
||||
---
|
||||
J'aimerais pouvoir utiliser IdeA sous forme de client/server. C'est a dire que IdeA aurait son backend sur une machine et son interface qui serait un frontend web. Les agents etc seraient tous côté server. C'est a dire que la cli de Claude serait celle côté serveur, l'interface client ne serait que l'affichage frontend, une UI. Je pense que tout est faisable, il faudrait cependant parler du côté CLI. Est ce qu'il serait possible de garde rle CLI natif comme il est actuellement, de l'afficher côté client tout en gardant l'installation claude code, codex etc côté serveur ? Peut etre qu'en ssh ça passerait ? Ce ticket ne pourra pas être fait en autonomie par un agent sans une review agent-utilisateur avant.
|
||||
@ -1,20 +0,0 @@
|
||||
---
|
||||
issueRef: "#14"
|
||||
version: 8
|
||||
updatedBy: {"kind":"user"}
|
||||
updatedAt: 1784449099987
|
||||
---
|
||||
## Production #14 — livrée dans develop (validation e2e live restante)
|
||||
|
||||
Périmètre figé avec l'utilisateur : adapter HTTP OpenAI-compatible **purement additif** (zéro régression Claude/Codex), parité **tool-calling + MCP** complète, canal HTTP natif robuste.
|
||||
|
||||
### Cycle
|
||||
- Cadrage Architect : slug mémoire `ticket14-local-lan-openai-adapter-scoping` (asymétrie CLI-vs-serveur HTTP, port ToolInvoker in-process, reprise sans id provider).
|
||||
- Backend (DevBackend) : variante `StructuredAdapter::OpenAiCompatible`, VO `HttpChatConfig`, `openai_compat.rs`, port `ToolInvoker` déléguant à la même OrchestratorService que le MCP. GO QA (domain 467 / application 530 / infrastructure 523 / app-tauri 247, 0 échec). Défaut réel corrigé : timeout post-contact mappé Io.
|
||||
- Frontend (DevFrontend) : types DTO miroir, wizard/settings (endpoint/model/apiKeyEnv=nom de var/timeouts, validation miroir backend), profil de référence Ollama éditable, erreur endpoint rendue via bannière role="alert". GO QA (tsc 0 + vitest 59 fichiers / 566 tests, 0 échec). Défaut réel corrigé : erreur endpoint invisible dans le DOM.
|
||||
|
||||
### Git
|
||||
- Backend `aab4bca`, frontend `d89380c`, merge `--no-ff` `3c6cd04` → develop. Branche feature supprimée. **Local uniquement, rien poussé.**
|
||||
|
||||
### Reste à faire (hors code)
|
||||
- Validation e2e **live contre un vrai endpoint Ollama/LAN** : lancement cellule, conversation headless, reprise, délégation inter-agents, vivacité/timeout, endpoint indisponible/modèle absent (critère d'acceptation n°7). Non exercée en tests automatisés — c'est la raison du statut QA plutôt que closed.
|
||||
@ -1,75 +0,0 @@
|
||||
---
|
||||
id: "0c1f1991-b6db-47b7-bbef-2478bc7874ab"
|
||||
number: 14
|
||||
title: "Integration de profils IA locaux/LAN comme profils IdeA canoniques"
|
||||
status: "closed"
|
||||
priority: "medium"
|
||||
sprint: null
|
||||
links: []
|
||||
agentRefs: [{"agentId":"a6ced819-b893-4213-b003-9e9dc79b9641","role":"assigned"}]
|
||||
createdBy: {"kind":"user"}
|
||||
updatedBy: {"kind":"user"}
|
||||
createdAt: 1783184495846
|
||||
updatedAt: 1784449099987
|
||||
version: 8
|
||||
---
|
||||
Objectif : permettre à IdeA d'utiliser des modèles hébergés localement ou sur le réseau local, par exemple Qwen via Ollama ou un runtime Docker exposant une API, avec le même niveau d'intégration produit que les profils Claude Code et OpenAI Codex CLI.
|
||||
|
||||
La finalité n'est pas un simple profil custom lancé dans un terminal brut. Ces profils doivent devenir de vrais profils IA IdeA : sélectionnables, lançables depuis les cellules, pilotés par la conversation headless canonique, compatibles avec les mécanismes de conversation/reprise, et utilisables par l'orchestration de la même manière que Claude/Codex.
|
||||
|
||||
## Cible produit
|
||||
|
||||
Ajouter une famille de profil structuré pour serveurs de modèles locaux ou LAN, idéalement basée sur une API HTTP compatible OpenAI/Ollama :
|
||||
|
||||
- endpoint configurable (`localhost`, machine LAN, container Docker, etc.) ;
|
||||
- modèle configurable (`qwen...`, autre modèle local) ;
|
||||
- authentification optionnelle via nom de variable d'environnement, jamais clé en clair ;
|
||||
- profil visible et sélectionnable dans IdeA comme Claude/Codex ;
|
||||
- cellule IdeA utilisable de façon canonique : conversation headless, historique, reprise, délégation, affichage des réponses et état de vivacité.
|
||||
|
||||
## Contraintes importantes
|
||||
|
||||
- Ne pas considérer le mode PTY/TUI comme suffisant pour ce ticket.
|
||||
- Éviter une dépendance obligatoire à `ollama`, `docker` ou une commande shell quand une API HTTP suffit.
|
||||
- Étudier explicitement les impacts commandes/headless :
|
||||
- adapter HTTP natif ;
|
||||
- wrapper CLI éventuel ;
|
||||
- Docker/LAN ;
|
||||
- sandbox et permissions ;
|
||||
- absence ou présence de tool-calling/MCP côté modèle local.
|
||||
- Le résultat doit s'intégrer dans le modèle existant `StructuredAdapter` / `AgentSessionFactory`, pas contourner le runtime IA d'IdeA.
|
||||
|
||||
## Travail attendu
|
||||
|
||||
1. Ajouter un adapter structuré pour modèle local/LAN, par exemple `StructuredAdapter::OpenAiCompatible` ou `LocalChat`.
|
||||
2. Étendre le modèle de profil pour porter la configuration nécessaire : endpoint, model, apiKeyEnv optionnel, timeouts/liveness si nécessaire.
|
||||
3. Implémenter une session headless `AgentSession` :
|
||||
- `send(prompt)` ;
|
||||
- émission de `ReplyEvent` ;
|
||||
- gestion propre des erreurs réseau/modèle ;
|
||||
- conversation id ou stratégie de reprise compatible avec le modèle IdeA.
|
||||
4. Brancher l'adapter dans `StructuredSessionFactory`.
|
||||
5. Rendre ces profils sélectionnables dans le wizard/settings au même titre que Claude/Codex.
|
||||
6. Ajouter un profil de référence local, par exemple “Ollama / OpenAI-compatible local model”, éditable.
|
||||
7. Vérifier l'intégration avec :
|
||||
- lancement depuis une cellule ;
|
||||
- conversation headless ;
|
||||
- reprise ;
|
||||
- changement de profil ;
|
||||
- délégation inter-agents quand applicable ;
|
||||
- état de vivacité/timeout ;
|
||||
- erreurs endpoint indisponible/modèle absent.
|
||||
|
||||
## Critères d'acceptation
|
||||
|
||||
- Je peux configurer un profil Qwen hébergé via Ollama ou endpoint LAN.
|
||||
- Je peux créer/lancer un agent IdeA avec ce profil comme avec Claude/Codex.
|
||||
- La cellule utilise le chemin headless structuré, pas un terminal brut PTY.
|
||||
- Les conversations apparaissent et se comportent comme les conversations Claude/Codex.
|
||||
- La reprise ne mélange pas l'id logique IdeA avec un éventuel id provider.
|
||||
- Un endpoint indisponible produit une erreur propre dans l'UI, sans bloquer IdeA.
|
||||
- Les dépendances à `ollama`, Docker ou une CLI externe sont documentées et non imposées si le mode HTTP suffit.
|
||||
- Tests backend couvrant factory, session adapter, erreurs HTTP et sérialisation du profil.
|
||||
- Tests frontend couvrant configuration/sélection du nouveau profil.
|
||||
|
||||
Review agent-user requise avant démarrage d'implémentation pour figer le périmètre exact : HTTP natif uniquement, support d'un wrapper CLI, et niveau attendu de tool-calling/MCP pour les modèles locaux.
|
||||
@ -1,15 +0,0 @@
|
||||
---
|
||||
issueRef: "#15"
|
||||
version: 5
|
||||
updatedBy: {"kind":"agent","agent_id":"a6ced819-b893-4213-b003-9e9dc79b9641"}
|
||||
updatedAt: 1784093861343
|
||||
---
|
||||
## Cadrage Architect — DIFFÉRÉ (2026-07-13)
|
||||
|
||||
#15 (cas DÉLÉGUÉ : A→B via idea_ask_agent, B limité → parquer le waiter de A et re-livrer au reset) est **distinct de #30** (cas direct) et **différé hors sprint**.
|
||||
|
||||
**Motif (Architect)** : le faire maintenant en in-memory serait une rustine fragile — réintroduit un blocage long côté A et ne tient pas les scénarios reboot/crash/redémarrage IdeA déjà identifiés.
|
||||
|
||||
**Prérequis bloquant** : un modèle fiable de *délégation durable runtime-agent identity* (stockage waiter, corrélation requester/target/request, re-livraison idempotente, reprise après reset, comportement si A meurt / B redémarre / IdeA redémarre, expiration/annulation). → design `durable-delegation-runtime-agent-identity-design`.
|
||||
|
||||
**Statut** : reste ouvert, priorité low/stretch conservée. Dépendance baseline #7 maintenue + à rattacher au redesign délégation durable. Ne pas mélanger avec #30.
|
||||
@ -1,28 +0,0 @@
|
||||
---
|
||||
id: "5de121f3-1cd1-4a73-bcab-b0a43a7c257f"
|
||||
number: 15
|
||||
title: "[Bloqué par #7 — design durable] Limites de session — re-livraison auto parquée au reset (stretch B5)"
|
||||
status: "open"
|
||||
priority: "low"
|
||||
sprint: "e28a4d53-8bd2-446a-b0ac-2a017373b8b2"
|
||||
links: [{"target":"#7","kind":"dependsOn"}]
|
||||
agentRefs: []
|
||||
createdBy: {"kind":"agent","agent_id":"a6ced819-b893-4213-b003-9e9dc79b9641"}
|
||||
updatedBy: {"kind":"agent","agent_id":"a6ced819-b893-4213-b003-9e9dc79b9641"}
|
||||
createdAt: 1783208599385
|
||||
updatedAt: 1784093861343
|
||||
version: 5
|
||||
---
|
||||
Extrait du cadrage Architect du ticket #7 (baseline livrée : propagation inter-agent B1→B3 + F1/F2). Stretch non retenu dans #7.
|
||||
|
||||
⛔ STATUT (2026-07-15) : BLOQUÉ / PARQUÉ. Dépend de #7 qui est encore en QA (non stabilisé). Architect (triage sprint « Gestion des bugs ») : « le waiter A→B n'est pas parqué/re-livré, l'ask retourne encore une erreur Process ; à traiter APRÈS stabilisation QA de #7/LS7 ». De plus c'est un item de « délégation durable » (in-memory fragile aux redémarrages) qui relève d'un design dédié, pas d'une rustine. Non lançable tant que #7 n'est pas vert et que le design durable-delegation n'est pas cadré. Sorti de la production active du sprint.
|
||||
|
||||
--- Cadrage conservé ---
|
||||
|
||||
Objectif : quand A délègue à B via idea_ask_agent et que B atteint sa limite, au lieu de demander à A de ré-interroger après le reset, PARQUER le waiter de A par (requester,target) ; au execute_resume de B (reprise auto au reset), RE-LIVRER la tâche d'origine et router la complétion vers le waiter de A s'il est encore vivant (sinon drop, contrainte in-memory).
|
||||
|
||||
État actuel (triage) : le rendez-vous délégué détecte RateLimited et arme une reprise de la cible (crates/application/src/orchestrator/service.rs:1854), execute_resume relance l'agent (crates/application/src/agent/session_limit.rs:226) ; mais le waiter A→B n'est pas parqué/re-livré.
|
||||
|
||||
Coût/risque (Architect) : rapproche du modèle « délégation durable » tout en restant in-memory → fragile aux redémarrages/interruptions de A, ré-introduit un blocage long côté A. À rattacher au design durable-delegation-runtime-agent-identity-design plutôt que traité en rustine in-memory.
|
||||
|
||||
Dépend de : #7 (baseline inter-agent B1→B3). Voir mémoire ticket7-session-limit-interagent-cadrage.
|
||||
@ -1,6 +0,0 @@
|
||||
---
|
||||
issueRef: "#16"
|
||||
version: 7
|
||||
updatedBy: {"kind":"user"}
|
||||
updatedAt: 1783405334263
|
||||
---
|
||||
@ -1,17 +0,0 @@
|
||||
---
|
||||
id: "0a3585f0-9774-4109-a4e3-746dc5b2a4b2"
|
||||
number: 16
|
||||
title: "[UI] réorganisation des menus"
|
||||
status: "closed"
|
||||
priority: "medium"
|
||||
sprint: null
|
||||
links: []
|
||||
agentRefs: [{"agentId":"a6ced819-b893-4213-b003-9e9dc79b9641","role":"assigned"}]
|
||||
createdBy: {"kind":"user"}
|
||||
updatedBy: {"kind":"user"}
|
||||
createdAt: 1783329576091
|
||||
updatedAt: 1783405334263
|
||||
version: 7
|
||||
---
|
||||
J'aimerais réorganiser les mesnus de façon à être un peu plus proche de l'interface d'un IDE plus classique. J'aiemrais plutot avoir des menu déroulant en haut de la fenetre que d'avoir cette barre latérale
|
||||
Les menus déroulant pourraient afficher des fenetres flottantes, ce qui laisserait plus de place pour l'affichage.
|
||||
@ -1,6 +0,0 @@
|
||||
---
|
||||
issueRef: "#17"
|
||||
version: 10
|
||||
updatedBy: {"kind":"user"}
|
||||
updatedAt: 1783405334977
|
||||
---
|
||||
@ -1,16 +0,0 @@
|
||||
---
|
||||
id: "66aaef66-c70a-4153-81e9-a8f323686092"
|
||||
number: 17
|
||||
title: "[UI] fenetre de gestion de tickets"
|
||||
status: "closed"
|
||||
priority: "medium"
|
||||
sprint: null
|
||||
links: [{"target":"#16","kind":"dependsOn"},{"target":"#18","kind":"dependsOn"}]
|
||||
agentRefs: []
|
||||
createdBy: {"kind":"user"}
|
||||
updatedBy: {"kind":"user"}
|
||||
createdAt: 1783329807682
|
||||
updatedAt: 1783405334977
|
||||
version: 10
|
||||
---
|
||||
J'aimerais une fenetre dédiée à la gestion des tickets. Autant pour le listing que pour la création/edition des tickets. Dans un même temps, j'aimerais qu'on améliore la gestion des tickets lié lorsque l'on édite les tickets en utilisant la popup du ticket #18. J'aiemrais aussi que l'agent permettant l'écriture des tickets soit proposé de façon plus évidante. Je pense qu'un bouton en bas à droite de la fenetre d'édition ouverte serait bien.
|
||||
@ -1,6 +0,0 @@
|
||||
---
|
||||
issueRef: "#18"
|
||||
version: 9
|
||||
updatedBy: {"kind":"user"}
|
||||
updatedAt: 1783405335941
|
||||
---
|
||||
@ -1,16 +0,0 @@
|
||||
---
|
||||
id: "5c17d6d3-c537-45b1-a17e-9c4edee963d1"
|
||||
number: 18
|
||||
title: "[UI] Créer une popup de selection de ticket"
|
||||
status: "closed"
|
||||
priority: "medium"
|
||||
sprint: null
|
||||
links: []
|
||||
agentRefs: [{"agentId":"a6ced819-b893-4213-b003-9e9dc79b9641","role":"assigned"}]
|
||||
createdBy: {"kind":"user"}
|
||||
updatedBy: {"kind":"user"}
|
||||
createdAt: 1783330038271
|
||||
updatedAt: 1783405335941
|
||||
version: 9
|
||||
---
|
||||
Pour différentes feature comme la création de sprint ou même le link d'un ticket à d'autres, il est necessaire de selectionner un ticket. Pour ça j'aimerais un popup qui puisse être utilisée dans ces différentes features pour la selection d'un ticket. Il faudrait une barre de recherche ainsi que la possibilité d'appliquer des filtres sur l'avancée ainsi que la priorité des tickets, comme pour le listing principal des tickets.
|
||||
@ -1,6 +0,0 @@
|
||||
---
|
||||
issueRef: "#19"
|
||||
version: 8
|
||||
updatedBy: {"kind":"user"}
|
||||
updatedAt: 1783405337651
|
||||
---
|
||||
@ -1,16 +0,0 @@
|
||||
---
|
||||
id: "b1c84dd2-cef7-4e48-a501-1a30eedb02f2"
|
||||
number: 19
|
||||
title: "[UI] implémentation de la popup de selection de ticket dans la création d'un sprint"
|
||||
status: "closed"
|
||||
priority: "low"
|
||||
sprint: null
|
||||
links: [{"target":"#18","kind":"dependsOn"}]
|
||||
agentRefs: [{"agentId":"a6ced819-b893-4213-b003-9e9dc79b9641","role":"assigned"}]
|
||||
createdBy: {"kind":"user"}
|
||||
updatedBy: {"kind":"user"}
|
||||
createdAt: 1783330352910
|
||||
updatedAt: 1783405337651
|
||||
version: 8
|
||||
---
|
||||
Lors de l'edition d'un sprint, j'aimerais que pour selectionner un ticket, ça soit la popup de selection de ticket qui soit utilisée
|
||||
@ -1,6 +0,0 @@
|
||||
---
|
||||
issueRef: "#2"
|
||||
version: 6
|
||||
updatedBy: {"kind":"agent","agent_id":"a6ced819-b893-4213-b003-9e9dc79b9641"}
|
||||
updatedAt: 1784065385002
|
||||
---
|
||||
@ -1,39 +0,0 @@
|
||||
---
|
||||
id: "0a492d45-e195-4df7-a2ad-65649372abf0"
|
||||
number: 2
|
||||
title: "Tâches de fond — dette A : découpler fin de process et flux output PTY (PtyPort::wait/try_wait)"
|
||||
status: "closed"
|
||||
priority: "low"
|
||||
sprint: "e28a4d53-8bd2-446a-b0ac-2a017373b8b2"
|
||||
links: []
|
||||
agentRefs: [{"agentId":"a6ced819-b893-4213-b003-9e9dc79b9641","role":"assigned"}]
|
||||
createdBy: {"kind":"agent","agent_id":"a6ced819-b893-4213-b003-9e9dc79b9641"}
|
||||
updatedBy: {"kind":"agent","agent_id":"a6ced819-b893-4213-b003-9e9dc79b9641"}
|
||||
createdAt: 1783082860742
|
||||
updatedAt: 1784065385002
|
||||
version: 6
|
||||
---
|
||||
Ticket #2 — Tâches de fond : découpler fin de process et flux output PTY.
|
||||
|
||||
REQUALIFIÉ (2026-07-14) : le hub broadcast PTY existe désormais (crates/infrastructure/src/pty/mod.rs), donc l'ancienne contrainte « pas de broadcast multi-consommateur » est OBSOLÈTE. Le volet « tee live UI » est sorti en sous-ticket B/F séparé (voir lien blocks). La dette restante ici est purement backend.
|
||||
|
||||
Constat : `CommandBackgroundRunner` détecte encore la fin d'une tâche en drainant `PtyPort::subscribe_output` jusqu'à EOF (crates/infrastructure/src/background_task/runner.rs:187), ce qui couple la lifecycle du process à la consommation de sortie et empêche un tee sans casser la détection.
|
||||
|
||||
Attendu :
|
||||
- Ajouter au port figé `PtyPort` (crates/domain/src/ports.rs:952) deux opérations explicites :
|
||||
- `async fn wait(&self, handle: &PtyHandle) -> Result<ExitStatus, PtyError>` (attend la fin naturelle + status ; documenter l'idempotence : premier wait consomme, suivants retournent le status mémorisé).
|
||||
- `fn try_wait(&self, handle: &PtyHandle) -> Result<Option<ExitStatus>, PtyError>` (non bloquant : Ok(None) si vivant, Ok(Some(status)) si terminé).
|
||||
- `kill` reste « forcer l'arrêt puis retourner status » ; si déjà terminé, retourne le status mémorisé. NotFound si handle inconnu/purgé. L'exit status est mémorisé dans le registre live tant que la session existe (cohérence wait/try_wait/kill).
|
||||
- Implémenter dans `PortablePtyAdapter` (état d'exit partagé, attendre le child sans dépendre du reader EOF, éviter double wait/kill) et dans tous les fakes de test.
|
||||
- Migrer le runner : remplacer l'attente EOF (runner.rs:187) par une attente sur `pty.wait(&handle)`, concurrencée avec cancel/deadline. La sortie de completion reste prise depuis le scrollback borné ; le runner n'a plus besoin de subscribe_output pour savoir si le process est fini.
|
||||
|
||||
Impact contractuel : port figé modifié → changement source-breaking intra-workspace (tous les adapters/fakes ajoutent wait/try_wait), mais PAS de breaking IPC/front, pas de migration de données.
|
||||
|
||||
Lots : B1 wait/try_wait au port + fakes ; B2 impl PortablePtyAdapter ; B3 migrer CommandBackgroundRunner vers wait ; B4 tests. Taille M.
|
||||
|
||||
QA (point de vérité) :
|
||||
- Fake PtyPort dont l'output n'est jamais drainé (ou consommé par 2 subscribers) mais `wait` résout → le runner complète quand même.
|
||||
- Fake avec subscriber UI actif + runner → completion via `wait`, pas via EOF.
|
||||
- Deadline : si `wait` ne résout pas avant deadline → runner retourne Expired et tue/cleanup correctement.
|
||||
- Cancel : cancel gagne même si l'output continue.
|
||||
- Portable PTY réel : commande courte (`echo hi`) → completion exit 0 sans dépendre d'un drain output.
|
||||
@ -1,6 +0,0 @@
|
||||
---
|
||||
issueRef: "#20"
|
||||
version: 5
|
||||
updatedBy: {"kind":"agent","agent_id":"a6ced819-b893-4213-b003-9e9dc79b9641"}
|
||||
updatedAt: 1784049665491
|
||||
---
|
||||
@ -1,26 +0,0 @@
|
||||
---
|
||||
id: "1be19ee5-fd03-42ea-8df6-da18704807a9"
|
||||
number: 20
|
||||
title: "[Backend] Dette ticket_list — matching #ref dans text + curseur opaque/stable"
|
||||
status: "closed"
|
||||
priority: "low"
|
||||
sprint: "e28a4d53-8bd2-446a-b0ac-2a017373b8b2"
|
||||
links: [{"target":"#18","kind":"relatesTo"}]
|
||||
agentRefs: []
|
||||
createdBy: {"kind":"agent","agent_id":"a6ced819-b893-4213-b003-9e9dc79b9641"}
|
||||
updatedBy: {"kind":"agent","agent_id":"a6ced819-b893-4213-b003-9e9dc79b9641"}
|
||||
createdAt: 1783331172226
|
||||
updatedAt: 1784049665491
|
||||
version: 5
|
||||
---
|
||||
Dette backend identifiée pendant le cadrage du sprint UI rework (gate G4), non bloquante pour la popup #18 qui démarre sur le contrat actuel.
|
||||
|
||||
Deux écarts sur la commande `ticket_list` (handler `crates/app-tauri/src/tickets.rs:681`, filtre store `crates/infrastructure/src/issues.rs`) :
|
||||
|
||||
1. Recherche `text` : appliquée serveur sur titre (issues.rs:322) + description/carnet (issues.rs:326/465) mais PAS sur le `#ref`/numéro de ticket. Étendre le matching `text` à `issue_ref` pour permettre la recherche par numéro dans la popup de sélection.
|
||||
|
||||
2. `cursor` : actuellement un offset numérique parsé en usize avec fallback silencieux à 0 si invalide (tickets.rs:1231), non opaque et non stable face à des mutations entre pages. Contractualiser un curseur opaque + stable (ordre déterministe préservé).
|
||||
|
||||
Garde G3-bis déjà en place côté frontend : `TicketPicker`/`useTicketSearch` traitent `cursor` comme un token opaque (jamais construit/incrémenté côté client), donc la migration vers un curseur opaque backend n'exigera AUCUN changement frontend — cette dette est non-breaking.
|
||||
|
||||
statuses[]/priorities[] sont conformes (OR intra-facette, AND inter-facette, testés) — rien à faire de ce côté.
|
||||
@ -1,6 +0,0 @@
|
||||
---
|
||||
issueRef: "#21"
|
||||
version: 7
|
||||
updatedBy: {"kind":"user"}
|
||||
updatedAt: 1783437364397
|
||||
---
|
||||
@ -1,16 +0,0 @@
|
||||
---
|
||||
id: "4ffe9f90-2264-4861-b7da-f5535b0a622f"
|
||||
number: 21
|
||||
title: "[UI] pouvoir trier les ticket par..."
|
||||
status: "closed"
|
||||
priority: "low"
|
||||
sprint: null
|
||||
links: [{"target":"#16","kind":"dependsOn"},{"target":"#18","kind":"dependsOn"}]
|
||||
agentRefs: []
|
||||
createdBy: {"kind":"user"}
|
||||
updatedBy: {"kind":"user"}
|
||||
createdAt: 1783331825658
|
||||
updatedAt: 1783437364397
|
||||
version: 7
|
||||
---
|
||||
J'aiemrais qu'on ajoute une option "trier par..." dans la popup de selection des tickets et dans la liste principale des tickets. On pourrait trier par numéro de ticket, priorité, status, ou titre du ticket. Avec chaque fois croissant/decroissant.
|
||||
@ -1,6 +0,0 @@
|
||||
---
|
||||
issueRef: "#22"
|
||||
version: 5
|
||||
updatedBy: {"kind":"user"}
|
||||
updatedAt: 1783437364871
|
||||
---
|
||||
@ -1,16 +0,0 @@
|
||||
---
|
||||
id: "2b90fd78-8fce-449d-ab61-e5aee5ede08c"
|
||||
number: 22
|
||||
title: "[UI] Anchor de views"
|
||||
status: "closed"
|
||||
priority: "medium"
|
||||
sprint: null
|
||||
links: []
|
||||
agentRefs: []
|
||||
createdBy: {"kind":"user"}
|
||||
updatedBy: {"kind":"user"}
|
||||
createdAt: 1783405028818
|
||||
updatedAt: 1783437364871
|
||||
version: 5
|
||||
---
|
||||
J'aimerais qu'à la manière d'un IDE classique, il soit possible d'ancrer des views sur le côté droite ou gauche et de proposer un format vertical. 9a peut être utilise par exemple pour git, les work, les agents, les skills etc. J'ai en tête les IDE comme Visual COde ou la suite Jetbrains par exemple.
|
||||
@ -1,6 +0,0 @@
|
||||
---
|
||||
issueRef: "#23"
|
||||
version: 6
|
||||
updatedBy: {"kind":"user"}
|
||||
updatedAt: 1783437365276
|
||||
---
|
||||
@ -1,16 +0,0 @@
|
||||
---
|
||||
id: "ed815933-ed48-466d-b265-3724f3ea943b"
|
||||
number: 23
|
||||
title: "[UI] rendre les fenêtres View séparée de IdeA"
|
||||
status: "closed"
|
||||
priority: "medium"
|
||||
sprint: null
|
||||
links: []
|
||||
agentRefs: []
|
||||
createdBy: {"kind":"user"}
|
||||
updatedBy: {"kind":"user"}
|
||||
createdAt: 1783405188644
|
||||
updatedAt: 1783437365276
|
||||
version: 6
|
||||
---
|
||||
J'aimerais que les fenêtre qu'on affiche via le menu View soient des fenêtre à part entières, qu'on puisse les déplacer sur les différents écrans, les mettre fullscreen etc, que ça soit des enetres "systeme" normales
|
||||
@ -1,25 +0,0 @@
|
||||
---
|
||||
issueRef: "#25"
|
||||
version: 11
|
||||
updatedBy: {"kind":"user"}
|
||||
updatedAt: 1783491435654
|
||||
---
|
||||
## Root cause
|
||||
`OpenTicketAssistant::execute` fabriquait un plan OS-sandbox bespoke via `SandboxPlan::project_read_only` (grant RO sur project_root, posture Deny). Sous Landlock, un grant RO fait *handle* la classe read/exec (`AccessFs::from_read(V1)` inclut Execute). Le binaire CLI (codex/claude) vit hors du project root ⇒ `execve` refusé ⇒ EACCES (os error 13) au spawn sandboxé. Indépendant de la CLI. Les agents workspace n'ont pas le bug (plan no-op sous posture Allow).
|
||||
|
||||
## Correctif (backend-pur, zéro port/DTO)
|
||||
Décision Main : option fallback `None`. La surface assistant de ticket passe désormais `None` en 5e arg de `factory.start` (aligné sur les agents workspace). Garde-fous restants : policy MCP `idea_ticket_read/update*` + advisory LP3. Helper `ticket_assistant_sandbox` et preset `SandboxPlan::project_read_only` supprimés (plus aucun appelant).
|
||||
|
||||
Fichiers : crates/application/src/ticket_assistant.rs (+tests), crates/domain/src/sandbox.rs.
|
||||
|
||||
## Validation
|
||||
- `cargo test --workspace` VERT (app-tauri 63, application 80, infrastructure 254, domain OK).
|
||||
- Test ciblé : `factory.start` reçoit `SessionPlan::None` + `sandbox.is_none()`.
|
||||
- Tests Landlock infra verts sur la machine.
|
||||
- RÉSERVE : repro live Codex+Claude non exécutée — nécessite rebuild + swap de l'AppImage active + relance IdeA (interrompt la session).
|
||||
|
||||
## Git
|
||||
Commit `961a2ca` → merge `--no-ff` `cb20fab` dans develop. Local only, pas de push.
|
||||
|
||||
## Reste à faire
|
||||
Repro live après rebuild AppImage pour clôture définitive. Dette différée : write-fence OS uniforme sur toutes les surfaces (cf. cadrage Architect) si l'on veut une clôture write-OS.
|
||||
@ -1,16 +0,0 @@
|
||||
---
|
||||
id: "6123b180-b36b-4807-ba31-46d60d3ef022"
|
||||
number: 25
|
||||
title: "[Bug] Codex/Claude erreur lors de l'utilisation dans l'edition d'un ticket"
|
||||
status: "closed"
|
||||
priority: "medium"
|
||||
sprint: null
|
||||
links: []
|
||||
agentRefs: [{"agentId":"a6ced819-b893-4213-b003-9e9dc79b9641","role":"assigned"}]
|
||||
createdBy: {"kind":"user"}
|
||||
updatedBy: {"kind":"user"}
|
||||
createdAt: 1783406391625
|
||||
updatedAt: 1783491435654
|
||||
version: 11
|
||||
---
|
||||
J'ai voulu créer un ticket via Codex dasn l'interface d'edition d'un ticket, mais j'ai eu cette erreur: process error: agent session start failed: codex: Permission non accordée (os error 13). J'aéi séléctionné que je voulais utiliser codex et l'erreur est apparue quand j'ai essayé de lui donné mon premier message. Je me rend compte que j'ai la même erreur avec Claude
|
||||
@ -1,6 +0,0 @@
|
||||
---
|
||||
issueRef: "#26"
|
||||
version: 6
|
||||
updatedBy: {"kind":"agent","agent_id":"a6ced819-b893-4213-b003-9e9dc79b9641"}
|
||||
updatedAt: 1783861758866
|
||||
---
|
||||
@ -1,16 +0,0 @@
|
||||
---
|
||||
id: "2201b898-9c45-4057-9014-5284897507ad"
|
||||
number: 26
|
||||
title: "[UI] refonte totale de la gestion des menus via agent UX"
|
||||
status: "closed"
|
||||
priority: "medium"
|
||||
sprint: "5afd6780-0f76-40d7-a10f-32ee52469d74"
|
||||
links: []
|
||||
agentRefs: []
|
||||
createdBy: {"kind":"user"}
|
||||
updatedBy: {"kind":"agent","agent_id":"a6ced819-b893-4213-b003-9e9dc79b9641"}
|
||||
createdAt: 1783437525356
|
||||
updatedAt: 1783861758866
|
||||
version: 6
|
||||
---
|
||||
J'aimerais une refonte totale de l'UX et de l'UI d'IdeA pour tout ce qui touche aux menus. Je n'aime pas la disposition actuelle. Il est important de garder l'aspect fenêtre flottantes, le fait de pouvoir anchor les fenêtres sur le côté d'IdeA, mais je n'aime pas le fait qu'il y ai deux listes déroulantes View et Window. Onne comprends pas vraiemnt la différence. De plus, l'affichage de l'onglet du projet avec le nom "Projet : IdeA" sur lequel cliquer pour changer de projet je n'aime pas. Je pense peut être plutot ajouter un + à côté de l'onglet du projet pour pouvoir ouvrir plusieurs projet en parallèle ? (A l''approbation de UX). Par contre je ne veux pas qu'on touche aux cellules des agents, elles sont très bien comme ça, on se contente des menus et des fenêtres.
|
||||
@ -1,6 +0,0 @@
|
||||
---
|
||||
issueRef: "#27"
|
||||
version: 6
|
||||
updatedBy: {"kind":"agent","agent_id":"a6ced819-b893-4213-b003-9e9dc79b9641"}
|
||||
updatedAt: 1783926649550
|
||||
---
|
||||
@ -1,16 +0,0 @@
|
||||
---
|
||||
id: "d7459ae0-31ae-49b2-bd93-2419397b0343"
|
||||
number: 27
|
||||
title: "[Bug] L'outil assistance IA n'a pas les commandes MCP"
|
||||
status: "closed"
|
||||
priority: "high"
|
||||
sprint: "e28a4d53-8bd2-446a-b0ac-2a017373b8b2"
|
||||
links: []
|
||||
agentRefs: [{"agentId":"a6ced819-b893-4213-b003-9e9dc79b9641","role":"assigned"}]
|
||||
createdBy: {"kind":"user"}
|
||||
updatedBy: {"kind":"agent","agent_id":"a6ced819-b893-4213-b003-9e9dc79b9641"}
|
||||
createdAt: 1783439818722
|
||||
updatedAt: 1783926649550
|
||||
version: 6
|
||||
---
|
||||
Il semblerait que l'outil assistance IA des tickets n'ait pas connaissance des tools MCP pour l'edition des tickets. J'ai essayé de demandé à l'assistant de modifié le ticket pour que ça aille dans le sens de la conversation que j'ai eu avec lui et il m'a dabord donné un .md. Quand je lui ai demandé de modifier lui même le ticket, il est allé dans le fichier directement pour apporter des modifications au lieu d'utiliser le tool MCP d'IdeA
|
||||
@ -1,6 +0,0 @@
|
||||
---
|
||||
issueRef: "#28"
|
||||
version: 3
|
||||
updatedBy: {"kind":"user"}
|
||||
updatedAt: 1783491458775
|
||||
---
|
||||
@ -1,33 +0,0 @@
|
||||
---
|
||||
id: "9d8ec8cf-312a-4f90-8199-e37b183ba11e"
|
||||
number: 28
|
||||
title: "First-run wizard : bouton « Save and continue » figé (busy bloqué par l'auto-détection)"
|
||||
status: "closed"
|
||||
priority: "high"
|
||||
sprint: null
|
||||
links: []
|
||||
agentRefs: []
|
||||
createdBy: {"kind":"agent","agent_id":"a6ced819-b893-4213-b003-9e9dc79b9641"}
|
||||
updatedBy: {"kind":"user"}
|
||||
createdAt: 1783458330440
|
||||
updatedAt: 1783491458775
|
||||
version: 3
|
||||
---
|
||||
## Symptôme (confirmé live, build 0.3.0 @2026-07-07 22:46, = develop 3c6cd04)
|
||||
Au premier lancement, le wizard affiche les profils de référence (Claude/Codex/Ollama), l'utilisateur remplit le profil Ollama et coche la case, mais **« Save and continue » ET « Detect installed CLIs » restent grisés** → impossible de finir le first-run. Confirmé par l'utilisateur : les deux boutons sont grisés.
|
||||
|
||||
## Diagnostic (source + JS embarqué vérifiés)
|
||||
- Le JS embarqué contient exactement `disabled: n.busy` sur le bouton (`FirstRunWizard.tsx:103`) — **aucune** condition de validation. Donc bouton grisé ⇔ `busy` reste `true`.
|
||||
- `useFirstRun.reload()` : `setBusy(true)` → affiche les lignes (d'où formulaire visible/éditable) → `await detectProfiles(refs)` (auto-détection à l'ouverture) → `finally { setBusy(false) }`. Le `finally` ne s'exécute que **si la détection se termine**. Si la promesse `detectProfiles` ne se résout jamais, `busy` reste figé → les deux boutons restent grisés.
|
||||
|
||||
## Causes racines suspectées (2 défauts #14 qui se combinent)
|
||||
1. **Profil Ollama sans commande de détection** : `detect: None` → `detection_spec` retombe sur `"{command} --version"` = `openai-compatible --version` (`runtime/mod.rs:64`), binaire inexistant → ligne « ✗ not found », et surtout probe inutile.
|
||||
2. **`block_on` sur runtime tokio imbriqué** dans le chemin de détection : `DetectProfiles::execute` (`usecases.rs:79`) appelle `runtime.detect()` synchrone → `futures_block_on` construit un runtime current-thread et `block_on` (`runtime/mod.rs:231`) **à l'intérieur** de la commande async Tauri `detect_profiles` (`commands.rs:752`). Pattern qui peut paniquer (« Cannot start a runtime from within a runtime ») / rester pendu → la promesse ne se résout jamais. Se déclenche probablement sur une machine **sans Claude/Codex installés**.
|
||||
|
||||
## Attendu du fix
|
||||
- `busy` doit **toujours** revenir à `false` même si la détection panique/pend (le `finally` ne doit pas dépendre du résultat de la détection ; détection best-effort, non bloquante, éventuellement bornée par timeout).
|
||||
- Donner une commande/stratégie de détection correcte au profil OpenAI-compatible (ou ne pas le sonder comme un CLI — c'est un endpoint HTTP, pas un binaire).
|
||||
- Corriger le `block_on` imbriqué dans le runtime de détection (ne pas bloquer dans un contexte async Tauri).
|
||||
|
||||
## Validation QA
|
||||
Reproduire sur une machine **sans** Claude/Codex installés + Ollama lancé ; vérifier que le wizard reste utilisable (boutons cliquables) et que le profil Ollama se persiste et démarre.
|
||||
@ -1,6 +0,0 @@
|
||||
---
|
||||
issueRef: "#29"
|
||||
version: 5
|
||||
updatedBy: {"kind":"agent","agent_id":"a6ced819-b893-4213-b003-9e9dc79b9641"}
|
||||
updatedAt: 1783921595742
|
||||
---
|
||||
@ -1,16 +0,0 @@
|
||||
---
|
||||
id: "51f19ca1-6b67-491b-b750-735c48a89d4b"
|
||||
number: 29
|
||||
title: "[UI] Garder les filtres des tickets entre deux redemarrage"
|
||||
status: "closed"
|
||||
priority: "low"
|
||||
sprint: "5afd6780-0f76-40d7-a10f-32ee52469d74"
|
||||
links: []
|
||||
agentRefs: []
|
||||
createdBy: {"kind":"user"}
|
||||
updatedBy: {"kind":"agent","agent_id":"a6ced819-b893-4213-b003-9e9dc79b9641"}
|
||||
createdAt: 1783491008871
|
||||
updatedAt: 1783921595742
|
||||
version: 5
|
||||
---
|
||||
J'aimerais garder les filtres des tickets en mémoire entre deux redemarrage ou ouverture de la fenetre ou d ela popup de choix de tickets.
|
||||
@ -1,6 +0,0 @@
|
||||
---
|
||||
issueRef: "#3"
|
||||
version: 7
|
||||
updatedBy: {"kind":"user"}
|
||||
updatedAt: 1784377533777
|
||||
---
|
||||
@ -1,28 +0,0 @@
|
||||
---
|
||||
id: "fedd343e-f9c1-467b-bab4-455f51907de7"
|
||||
number: 3
|
||||
title: "[Différé — design à mûrir] Tâches de fond — dette B : retry durable après reboot"
|
||||
status: "closed"
|
||||
priority: "low"
|
||||
sprint: "e28a4d53-8bd2-446a-b0ac-2a017373b8b2"
|
||||
links: []
|
||||
agentRefs: [{"agentId":"a6ced819-b893-4213-b003-9e9dc79b9641","role":"assigned"}]
|
||||
createdBy: {"kind":"agent","agent_id":"a6ced819-b893-4213-b003-9e9dc79b9641"}
|
||||
updatedBy: {"kind":"user"}
|
||||
createdAt: 1783082860758
|
||||
updatedAt: 1784377533777
|
||||
version: 7
|
||||
---
|
||||
Ticket #3 — Tâches de fond : retry après redémarrage sans fuite de secrets dans le projet.
|
||||
|
||||
⛔ DÉCISION UTILISATEUR (2026-07-15) : DIFFÉRÉ. On ne persiste PAS de secrets en clair machine-local pour l'instant. À reprendre plus tard avec un vrai design sécurisé (keyring OS multiplateforme — Secret Service / Keychain / Credential Manager — ou modèle d'invocation déclaratif avec secret-refs re-résolus au retry depuis profil/env). Le retry-after-reboot reste indisponible en attendant. Ticket sorti de la production active du sprint « Gestion des bugs ».
|
||||
|
||||
--- Cadrage conservé pour la reprise ---
|
||||
|
||||
REQUALIFIÉ (2026-07-14) :
|
||||
- Volet « énumération terminale/projet du BackgroundTaskStore » : RÉSOLU par l'implémentation actuelle (store durable par projet sous <root>/.ideai/background-tasks, listes open par agent + completions non livrées, routage par projet). RETIRÉ du périmètre.
|
||||
- Reste uniquement le retry après redémarrage. L'invocation d'origine (SpawnSpec) est conservée dans un registre in-memory session-scoped (BackgroundCommandArchive, crates/application/src/background/mod.rs:203) volontairement non persistée dans .ideai car elle peut contenir des secrets. Après reboot, une tâche persistée ne peut donc pas être relancée.
|
||||
|
||||
Option A (écartée pour l'instant par décision utilisateur) : store machine-local hors projet (app-data OS/Tauri), SpawnSpec complet par (project_id, task_id), permissions 0700/0600 best-effort, JSON projet sans secret, retry échouant explicitement si invocation absente. Simple (M) mais persiste des secrets en clair local → refusée à ce stade.
|
||||
|
||||
Piste retenue pour la reprise : keyring OS multiplateforme OU secret-refs déclaratifs (chantier plus large que « low », à cadrer comme design dédié le moment venu).
|
||||
@ -1,25 +0,0 @@
|
||||
---
|
||||
issueRef: "#30"
|
||||
version: 8
|
||||
updatedBy: {"kind":"agent","agent_id":"a6ced819-b893-4213-b003-9e9dc79b9641"}
|
||||
updatedAt: 1783941648176
|
||||
---
|
||||
## Cadrage Architect (2026-07-13) — cas DIRECT, actionnable
|
||||
|
||||
Débloqué : #27 fermé. #30 ≠ #15 (#15 = cas délégué, différé).
|
||||
|
||||
**Périmètre** : le chemin direct de session agent (agent directement adressé, ex. Main) ne remonte pas la limite vers `SessionLimitService`. Fix = accrocher le détecteur sur le chemin direct, avant résolution finale du tour.
|
||||
|
||||
**Frontière hexagonale** : infra détecte (adapter provider/profil déclaratif extrait la limite du flux structuré/regex → `ReplyEvent::RateLimited { resets_at_ms? }`) ; application arme la reprise (`SessionLimitService::on_rate_limited(agent_id,node_id,conversation_id,resets_at_ms)`) ; app-tauri relaie ; React affiche/annule. Aucune logique provider dans domaine/application.
|
||||
|
||||
**Contrat d'événements** :
|
||||
- `DomainEvent::AgentRateLimited { agent_id, resets_at_ms }`
|
||||
- `DomainEvent::AgentResumeScheduled { agent_id, fire_at_ms }` si reprise armée
|
||||
- reprise auto au reset, annulable via `cancel_resume` (contrat existant conservé)
|
||||
- si heure de reset non récupérable : fallback niveau humain déjà cadré (état suspect + saisie d'heure, pas de silence)
|
||||
|
||||
**Point clé** : identité runtime — résoudre l'agent courant + `node_id` vivant + `conversation_id` via le registre/session meta existant (pas de convention UI). Sans `conversation_id`, ne PAS prétendre la reprise armée.
|
||||
|
||||
**Découpage** : B1 tap `ReplyEvent::RateLimited → on_rate_limited` dans le runner direct ; B2 résolution identité/session (agent_id/node_id/conversation_id) pour l'agent adressé ; B3 tests application/app-tauri (flux direct rate-limit avec resets_at_ms → AgentRateLimited puis AgentResumeScheduled) ; F1 régression badge existant (pas de nouveau contrat) ; F2 QA réelle (limite provoquée/mockée sur Main → heure affichée, annulation, reprise planifiée).
|
||||
|
||||
**Sous-lot adjacent** (ferme #7/F2, mémoire `ticket7-f2-delegated-limit-no-agentratelimited`) : la branche rendez-vous délégué publie seulement `DelegationRateLimited` et doit aussi armer `on_rate_limited(target,…)`. Traité dans la même branche mais en commit séparé.
|
||||
@ -1,16 +0,0 @@
|
||||
---
|
||||
id: "f2c4ed9c-ba54-42c1-90aa-0345d4ff4c6b"
|
||||
number: 30
|
||||
title: "[Bug] Le handle de limite session n'est pas fonctionnel quand c'est Main qui limite session"
|
||||
status: "closed"
|
||||
priority: "medium"
|
||||
sprint: "d8f3f37b-87ca-4509-9116-45a99bc711df"
|
||||
links: [{"target":"#27","kind":"blockedBy"}]
|
||||
agentRefs: []
|
||||
createdBy: {"kind":"user"}
|
||||
updatedBy: {"kind":"agent","agent_id":"a6ced819-b893-4213-b003-9e9dc79b9641"}
|
||||
createdAt: 1783491181648
|
||||
updatedAt: 1783941648176
|
||||
version: 8
|
||||
---
|
||||
Lorsque l'agent qui atteint sa limite est celui à qui ont parle, la limite de session n'est pas récupérée par IdeA et n'est pas gérée
|
||||
@ -1,6 +0,0 @@
|
||||
---
|
||||
issueRef: "#31"
|
||||
version: 4
|
||||
updatedBy: {"kind":"agent","agent_id":"a6ced819-b893-4213-b003-9e9dc79b9641"}
|
||||
updatedAt: 1784064442657
|
||||
---
|
||||
@ -1,31 +0,0 @@
|
||||
---
|
||||
id: "83d320f1-766b-4744-b518-8e39a2518e9c"
|
||||
number: 31
|
||||
title: "Détection de profils séquentielle : N × 800 ms au pire, résultat potentiellement partiel"
|
||||
status: "closed"
|
||||
priority: "low"
|
||||
sprint: "e28a4d53-8bd2-446a-b0ac-2a017373b8b2"
|
||||
links: [{"target":"#28","kind":"relatesTo"}]
|
||||
agentRefs: []
|
||||
createdBy: {"kind":"agent","agent_id":"a6ced819-b893-4213-b003-9e9dc79b9641"}
|
||||
updatedBy: {"kind":"agent","agent_id":"a6ced819-b893-4213-b003-9e9dc79b9641"}
|
||||
createdAt: 1783491197541
|
||||
updatedAt: 1784064442657
|
||||
version: 4
|
||||
---
|
||||
## Origine
|
||||
Relevé par Git en revue du diff du ticket #28 (merge 710fa8f), hors périmètre du fix.
|
||||
|
||||
## Constat
|
||||
Depuis #28, `DetectProfiles::execute` séquence les `await` candidat par candidat, chaque sonde bornée par `tokio::time::timeout(800ms)`. N profils indisponibles coûtent donc **N × 800 ms** au pire.
|
||||
|
||||
Côté frontend, `DETECT_TIMEOUT_MS = 3 s` relâche le flag `detecting`. À partir de ~4 candidats muets, le tour de détection dépasse ce délai : l'indicateur « Detecting… » disparaît avant que les résultats n'arrivent.
|
||||
|
||||
## Impact
|
||||
Cosmétique. L'UI **ne gèle plus** (c'est bien l'objet de #28, corrigé) ; le risque résiduel est un affichage de disponibilité qui arrive après la retombée de l'indicateur.
|
||||
|
||||
## Piste de fix
|
||||
Paralléliser les sondes avec `futures::future::join_all` dans `DetectProfiles::execute` (`crates/application/src/agent/usecases.rs`) : le coût au pire retombe à ~800 ms quel que soit N, largement sous le timeout UI.
|
||||
|
||||
## Validation
|
||||
Test `#[tokio::test(flavor = "multi_thread")]` sur `DetectProfiles::execute` avec N candidats muets, asserting que la durée totale reste bornée par ~1 × timeout et non N ×.
|
||||
@ -1,6 +0,0 @@
|
||||
---
|
||||
issueRef: "#32"
|
||||
version: 6
|
||||
updatedBy: {"kind":"agent","agent_id":"a6ced819-b893-4213-b003-9e9dc79b9641"}
|
||||
updatedAt: 1783723378815
|
||||
---
|
||||
@ -1,23 +0,0 @@
|
||||
---
|
||||
id: "9291e7ad-a300-4f15-83b1-93f56f6e1b79"
|
||||
number: 32
|
||||
title: "[Bug] Erreur CLI Ollama profile"
|
||||
status: "closed"
|
||||
priority: "medium"
|
||||
sprint: null
|
||||
links: [{"target":"#14","kind":"relatesTo"}]
|
||||
agentRefs: [{"agentId":"a6ced819-b893-4213-b003-9e9dc79b9641","role":"assigned"}]
|
||||
createdBy: {"kind":"user"}
|
||||
updatedBy: {"kind":"agent","agent_id":"a6ced819-b893-4213-b003-9e9dc79b9641"}
|
||||
createdAt: 1783491571863
|
||||
updatedAt: 1783723378815
|
||||
version: 6
|
||||
---
|
||||
J'ai créé un profile IA Ollama et j'ai ajouté un agent avec ce profile (agent TestOllama), mais quand
|
||||
j'essaie d'afficher sa cli j'ai un bandeau rouge qui dit "Échec du lancement de l'agent : process error: pty spawn
|
||||
failed: Unable to spawn openai-compatible because:
|
||||
No viable candidates found in PATH "/tmp/.mount_IdeA_0mlgJnH/usr/bin/:/tmp/.mount_IdeA_0mlgJnH/usr/sbin/:/tmp/.mount_
|
||||
IdeA_0mlgJnH/usr/games/:/tmp/.mount_IdeA_0mlgJnH/bin/:/tmp/.mount_IdeA_0mlgJnH/sbin/:/home/anthony/.local/bin:/run/us
|
||||
er/1000/fnm_multishells/4610_1783490075749/bin:/home/anthony/.local/share/fnm:/home/anthony/go/bin:/home/anthony/.car
|
||||
go/bin:/usr/local/bin:/usr/bin:/bin:/usr/local/sbin:/usr/lib/jvm/default/bin:/usr/bin/site_perl:/usr/bin/vendor_perl:
|
||||
/usr/bin/core_perl:/home/anthony/.local/share/JetBrains/Toolbox/scripts"
|
||||
@ -1,6 +0,0 @@
|
||||
---
|
||||
issueRef: "#33"
|
||||
version: 4
|
||||
updatedBy: {"kind":"agent","agent_id":"a6ced819-b893-4213-b003-9e9dc79b9641"}
|
||||
updatedAt: 1784048928225
|
||||
---
|
||||
@ -1,39 +0,0 @@
|
||||
---
|
||||
id: "c3e1fbcc-cedc-48a5-a00e-b22ea8dc90de"
|
||||
number: 33
|
||||
title: "[Dette] Fallthrough silencieux du routage structuré (lifecycle.rs:1705)"
|
||||
status: "closed"
|
||||
priority: "high"
|
||||
sprint: "e28a4d53-8bd2-446a-b0ac-2a017373b8b2"
|
||||
links: [{"target":"#32","kind":"relatesTo"},{"target":"#14","kind":"relatesTo"}]
|
||||
agentRefs: []
|
||||
createdBy: {"kind":"agent","agent_id":"a6ced819-b893-4213-b003-9e9dc79b9641"}
|
||||
updatedBy: {"kind":"agent","agent_id":"a6ced819-b893-4213-b003-9e9dc79b9641"}
|
||||
createdAt: 1783492190391
|
||||
updatedAt: 1784048928225
|
||||
version: 4
|
||||
---
|
||||
Cause racine structurelle identifiée par Architect lors du cadrage de #32.
|
||||
|
||||
`LaunchAgent::execute` (crates/application/src/agent/lifecycle.rs:1705) route vers la session structurée avec :
|
||||
|
||||
```rust
|
||||
if let (Some(factory), Some(structured), true) = (
|
||||
self.session_factory.as_ref(), self.structured.as_ref(),
|
||||
profile.structured_adapter.is_some(),
|
||||
)
|
||||
```
|
||||
|
||||
Ce `if let` **confond deux situations distinctes** :
|
||||
- « profil structuré, mais factory non câblée » (cas de l'UI : `state.rs:1466` construit le `LaunchAgent` sans `.with_structured(...)`) ;
|
||||
- « profil non structuré » (vrai profil PTY historique).
|
||||
|
||||
Dans les deux cas on tombe silencieusement, sans erreur ni branche explicite, sur `lifecycle.rs:1746` `self.pty.spawn(spec)`.
|
||||
|
||||
C'est ce fallthrough qui a produit le bug #32 : un profil `openAiCompatible` (aucun binaire) atteignait `CommandBuilder::new("openai-compatible")`. Claude et Codex tombent dans le **même** fallthrough ; ça ne passe inaperçu que parce qu'un binaire `claude`/`codex` existe dans le PATH.
|
||||
|
||||
Le fix de #32 neutralise le cas transport-backed, mais **le piège reste armé** pour le prochain adapter.
|
||||
|
||||
**Attendu** : remplacer le `if let` par un `match` explicite qui distingue les deux cas, et décider du comportement quand un profil structuré rencontre une factory non câblée (erreur explicite plutôt que dégradation muette vers le PTY).
|
||||
|
||||
Hors périmètre de #32 (déposé comme bug). Cadrage Architect requis avant implémentation.
|
||||
@ -1,6 +0,0 @@
|
||||
---
|
||||
issueRef: "#34"
|
||||
version: 4
|
||||
updatedBy: {"kind":"agent","agent_id":"a6ced819-b893-4213-b003-9e9dc79b9641"}
|
||||
updatedAt: 1784050010085
|
||||
---
|
||||
@ -1,29 +0,0 @@
|
||||
---
|
||||
id: "8dca00bf-ec0f-4da1-a231-46b27c711b78"
|
||||
number: 34
|
||||
title: "[Risque] ChatBridge.scrollback non borné (croissance mémoire)"
|
||||
status: "closed"
|
||||
priority: "medium"
|
||||
sprint: "e28a4d53-8bd2-446a-b0ac-2a017373b8b2"
|
||||
links: [{"target":"#32","kind":"relatesTo"}]
|
||||
agentRefs: []
|
||||
createdBy: {"kind":"agent","agent_id":"a6ced819-b893-4213-b003-9e9dc79b9641"}
|
||||
updatedBy: {"kind":"agent","agent_id":"a6ced819-b893-4213-b003-9e9dc79b9641"}
|
||||
createdAt: 1783492562056
|
||||
updatedAt: 1784050010085
|
||||
version: 4
|
||||
---
|
||||
Identifié par Architect lors du cadrage de #32 (variante B).
|
||||
|
||||
`ChatBridge` retient le scrollback d'une session chat pour le rejouer au remount (`reattach_agent_chat`). L'enregistrement se fait par un `push` nu, **sans aucun cap** :
|
||||
|
||||
- `app-tauri/src/chat.rs:161` — `push` sans borne.
|
||||
- `app-tauri/src/chat.rs:47` — la doc prétend « Bounded only by the conversation length (a turn count) », ce qui est un euphémisme : chaque `TextDelta` (quelques octets) est retenu à vie.
|
||||
|
||||
**Dormant jusqu'ici** : aucune session structurée vivante ne passait par ce chemin. **Devient actif avec #32 variante B** (cellule chat pour les adapters transport-backed) : une conversation Ollama longue fait croître le `Vec` sans borne.
|
||||
|
||||
Distinct de la rétention/rotation du transcript disque (mémoire `conversation-log-ls6-rotation-and-paginated-read`), qui porte sur `log.jsonl`, pas sur ce buffer mémoire.
|
||||
|
||||
**Attendu** : borner le scrollback (cap en nombre d'événements ou en octets, avec troncature par la tête), corriger la doc `chat.rs:47`, et décider si le remount doit signaler une troncature à l'UI.
|
||||
|
||||
Hors périmètre #32. Cadrage Architect requis.
|
||||
@ -1,6 +0,0 @@
|
||||
---
|
||||
issueRef: "#35"
|
||||
version: 6
|
||||
updatedBy: {"kind":"agent","agent_id":"a6ced819-b893-4213-b003-9e9dc79b9641"}
|
||||
updatedAt: 1783777898736
|
||||
---
|
||||
@ -1,16 +0,0 @@
|
||||
---
|
||||
id: "77ef65a5-bbb8-44d2-a610-27bf15c54a0a"
|
||||
number: 35
|
||||
title: "Avoir llamacpp intégré"
|
||||
status: "closed"
|
||||
priority: "high"
|
||||
sprint: "883534aa-7fc1-4d83-a9c0-17cac4a4eea5"
|
||||
links: []
|
||||
agentRefs: [{"agentId":"a6ced819-b893-4213-b003-9e9dc79b9641","role":"assigned"}]
|
||||
createdBy: {"kind":"user"}
|
||||
updatedBy: {"kind":"agent","agent_id":"a6ced819-b893-4213-b003-9e9dc79b9641"}
|
||||
createdAt: 1783756863540
|
||||
updatedAt: 1783777898736
|
||||
version: 6
|
||||
---
|
||||
Nous avons llamacpp qui marche super avec OpencCode à présent. J'aimerais maintenant que llamacpp soit lancé automatiquement via IdeA avec le bon modele à la bonne url et bon port si celui-ci n'est pas encore lancé
|
||||
@ -1,6 +0,0 @@
|
||||
---
|
||||
issueRef: "#36"
|
||||
version: 6
|
||||
updatedBy: {"kind":"agent","agent_id":"a6ced819-b893-4213-b003-9e9dc79b9641"}
|
||||
updatedAt: 1783777899737
|
||||
---
|
||||
@ -1,16 +0,0 @@
|
||||
---
|
||||
id: "3bb071b9-08eb-4e1b-b4b4-dccee8114a7e"
|
||||
number: 36
|
||||
title: "[UI] Pouvoir déclarer plusieurs profils AI de modeles locaux"
|
||||
status: "closed"
|
||||
priority: "medium"
|
||||
sprint: "883534aa-7fc1-4d83-a9c0-17cac4a4eea5"
|
||||
links: []
|
||||
agentRefs: [{"agentId":"a6ced819-b893-4213-b003-9e9dc79b9641","role":"assigned"}]
|
||||
createdBy: {"kind":"user"}
|
||||
updatedBy: {"kind":"agent","agent_id":"a6ced819-b893-4213-b003-9e9dc79b9641"}
|
||||
createdAt: 1783757232381
|
||||
updatedAt: 1783777899737
|
||||
version: 6
|
||||
---
|
||||
Actuellement chaque type de profils ne peux déclarer qu'un seul profile AI. J'aimerais que le profile OpenCode puisse permetre d'en décalrer plusieurs différents.
|
||||
@ -1,6 +0,0 @@
|
||||
---
|
||||
issueRef: "#37"
|
||||
version: 7
|
||||
updatedBy: {"kind":"agent","agent_id":"a6ced819-b893-4213-b003-9e9dc79b9641"}
|
||||
updatedAt: 1783878976369
|
||||
---
|
||||
@ -1,16 +0,0 @@
|
||||
---
|
||||
id: "a2b6212a-8725-4ace-b8a4-c3a41e2c2988"
|
||||
number: 37
|
||||
title: "[UI] garder les tickets dans les sprints, mais ajouter l'affichage du status et la possibiliter de filtrer les tickets"
|
||||
status: "closed"
|
||||
priority: "low"
|
||||
sprint: "5afd6780-0f76-40d7-a10f-32ee52469d74"
|
||||
links: []
|
||||
agentRefs: [{"agentId":"a6ced819-b893-4213-b003-9e9dc79b9641","role":"assigned"}]
|
||||
createdBy: {"kind":"user"}
|
||||
updatedBy: {"kind":"agent","agent_id":"a6ced819-b893-4213-b003-9e9dc79b9641"}
|
||||
createdAt: 1783757421147
|
||||
updatedAt: 1783878976369
|
||||
version: 7
|
||||
---
|
||||
Actuelleemnt dans les sprints les tickets sont retirés une fois fait. J'aimerais que les tickets restent dans le sprints mais qu'on ajoute l'affichage du status de chaque ticket. J'aimerais aussi qu'on ai la possibilité de trier les tickets via leur status, leur priorité etc comme sur la liste des tickets
|
||||
@ -1,6 +0,0 @@
|
||||
---
|
||||
issueRef: "#38"
|
||||
version: 7
|
||||
updatedBy: {"kind":"agent","agent_id":"a6ced819-b893-4213-b003-9e9dc79b9641"}
|
||||
updatedAt: 1783879443381
|
||||
---
|
||||
@ -1,16 +0,0 @@
|
||||
---
|
||||
id: "7e89bfc9-dc56-4656-a154-690f02e69756"
|
||||
number: 38
|
||||
title: "[UI] Pouvoir ajouter un ticket à un sprint pendant sa création"
|
||||
status: "closed"
|
||||
priority: "low"
|
||||
sprint: "5afd6780-0f76-40d7-a10f-32ee52469d74"
|
||||
links: []
|
||||
agentRefs: []
|
||||
createdBy: {"kind":"user"}
|
||||
updatedBy: {"kind":"agent","agent_id":"a6ced819-b893-4213-b003-9e9dc79b9641"}
|
||||
createdAt: 1783757548614
|
||||
updatedAt: 1783879443381
|
||||
version: 7
|
||||
---
|
||||
J'aimerais que dans la création de ticket on puisse lui attribuer un sprint via une popup comme celle du choix de tickets
|
||||
@ -1,6 +0,0 @@
|
||||
---
|
||||
issueRef: "#39"
|
||||
version: 5
|
||||
updatedBy: {"kind":"agent","agent_id":"a6ced819-b893-4213-b003-9e9dc79b9641"}
|
||||
updatedAt: 1783921595316
|
||||
---
|
||||
@ -1,16 +0,0 @@
|
||||
---
|
||||
id: "02ff2d0c-4312-47c3-b84c-834029723fc4"
|
||||
number: 39
|
||||
title: "[UI] Fermer toutes les fernetres lors de la fermeture de la fenetre principale principale"
|
||||
status: "closed"
|
||||
priority: "low"
|
||||
sprint: "5afd6780-0f76-40d7-a10f-32ee52469d74"
|
||||
links: []
|
||||
agentRefs: []
|
||||
createdBy: {"kind":"user"}
|
||||
updatedBy: {"kind":"agent","agent_id":"a6ced819-b893-4213-b003-9e9dc79b9641"}
|
||||
createdAt: 1783757707896
|
||||
updatedAt: 1783921595316
|
||||
version: 5
|
||||
---
|
||||
Quand on ferme la fenetre principale d'IdeA, j'aimerais que toutes les fenêtres IdeA se ferment aussi.
|
||||
@ -1,28 +0,0 @@
|
||||
---
|
||||
issueRef: "#4"
|
||||
version: 9
|
||||
updatedBy: {"kind":"user"}
|
||||
updatedAt: 1783437430509
|
||||
---
|
||||
## 🔄 REDÉMARRAGE DE ZÉRO (2026-07-04) — décision utilisateur
|
||||
|
||||
TOUT le travail #4 précédent (sur base canonique/main) est ABANDONNÉ comme ligne de livraison. Raison : l'utilisateur a réaligné main = develop = feature/background-tasks-first-class (ebd992e, base PRÉ-canonique de #1). Le moteur de conversation « canonique » (spawn_turn/AgentTurnEvent/agentBusyChanged) sur lequel reposait l'ancien #4 n'est PLUS sur main/develop. On refait #4 de zéro sur la base develop.
|
||||
|
||||
BRANCHE DE TRAVAIL : `feature/agent-live-announcements` (créée depuis develop ebd992e).
|
||||
|
||||
BRANCHES SUPPRIMÉES (obsolètes) : feature/announcements-canonical, feature/inter-agent-announcements.
|
||||
FILETS DE RÉCUPÉRATION (si on veut repiquer du code) :
|
||||
- backup/announcements-work-20260704 (691b2ce) = ancien #4 complet (backend B0-B3 + frontend F1/F2/F3 recâblé busy + tests).
|
||||
- backup/inter-agent-announcements-71d307d (71d307d) = backend annonces d'origine.
|
||||
- backup/main-canonical-20260704 (3cff2b1) = moteur canonique + releases.
|
||||
|
||||
OBJECTIF PRODUIT (inchangé, reconfirmé utilisateur) : affichage live sur la cellule d'un agent de ce qu'il raconte quand un AUTRE agent le sollicite via idea_ask_agent. Overlay sur la cellule CIBLE (« un agent est en train de lui parler » + annonces défilantes), monté quand la cible est busy, retiré à l'idle. Preview côté DEMANDEUR près de la liste d'agents, filtré par ticket + requester==self.
|
||||
|
||||
⚠️ ATTENTION base develop : moteur « batch » (run_turn), PAS le canonique. À cadrer par Architect : quels signaux live develop émet-il déjà (annonces intermédiaires ? busy/idle par agent ? l'ancien #4 utilisait agentBusyChanged + read-model agents[].busy — existent-ils sur develop ?), et que faut-il (ré)implémenter côté backend pour que les annonces soient LIVE (pas flushées en fin de tour). Réutiliser les composants frontend depuis backup/announcements-work-20260704 si le contrat de signaux le permet.
|
||||
|
||||
## RESTE À FAIRE (cycle complet sur base develop)
|
||||
1. [EN COURS] Architect : cadrage from-scratch sur base develop (signaux live disponibles + à créer, contrat Announcement/Final, plan B/F, réutilisabilité du code sauvegardé).
|
||||
2. Git : branche de travail = feature/agent-live-announcements (FAIT).
|
||||
3. DevBackend : mécanisme annonces/Final + signaux live sur moteur develop.
|
||||
4. DevFrontend : F1 store + F2 preview demandeur + F3 overlay cible.
|
||||
5. QA : reproduire le déclenchement inter-agent + constater overlay/preview live + fermeture à l'idle.
|
||||
@ -1,35 +0,0 @@
|
||||
---
|
||||
id: "547f6a47-9c86-4c16-9018-f050af75a6aa"
|
||||
number: 4
|
||||
title: "Annonces inter-agent (UI live) — reprise et finalisation : overlay cellule cible + preview demandeur (F1-F3)"
|
||||
status: "closed"
|
||||
priority: "medium"
|
||||
sprint: null
|
||||
links: []
|
||||
agentRefs: [{"agentId":"a6ced819-b893-4213-b003-9e9dc79b9641","role":"assigned"}]
|
||||
createdBy: {"kind":"agent","agent_id":"a6ced819-b893-4213-b003-9e9dc79b9641"}
|
||||
updatedBy: {"kind":"user"}
|
||||
createdAt: 1783083604350
|
||||
updatedAt: 1783437430509
|
||||
version: 9
|
||||
---
|
||||
Objectif produit (demande utilisateur, design figé le 2026-07-02) :
|
||||
Quand un agent en contacte un autre via idea_ask_agent, l'agent CONTACTÉ doit afficher, par-dessus sa cellule, un overlay « un agent est en train de lui parler » avec ses réflexions/annonces en cours qui défilent ; l'agent DEMANDEUR affiche un petit preview des annonces près de la drop-list d'agents, filtré par ticket. L'overlay est piloté par le live-state (monté sur Working, retiré au Final/idle, persiste tant qu'≥1 ticket actif sur la cible). Design et cadrage complets en mémoire projet : inter-agent-announcements-feature-and-codex-final-bug (+ inter-agent-live-context-shared-per-agent).
|
||||
|
||||
ÉTAT ACTUEL (vérifié 2026-07-03) :
|
||||
- Backend B0-B3 DÉJÀ implémenté sur la branche feature/inter-agent-announcements, commit 71d307d :
|
||||
- ReplyEvent::Announcement (non terminal) vs Final (terminal, résout le ticket).
|
||||
- DomainEvent::AgentAnnouncement{project_id, requester, target, ticket_id, text, at_ms}.
|
||||
- Relay Tauri (crates/app-tauri/src/events.rs), DTO.
|
||||
- Fix du Final Codex : dernier agent_message avant turn.completed = Final (avant : le préambule était renvoyé au demandeur au lieu de la conclusion). 18 fichiers backend + tests.
|
||||
- FRONTEND F1/F2/F3 : JAMAIS écrit. Aucune référence « announcement » sous frontend/src. C'est la pièce visuelle centrale de la demande (preview demandeur + overlay cible) — absente.
|
||||
- La branche feature/inter-agent-announcements est 15 commits EN RETARD sur develop, jamais mergée. Une seconde branche feature/inter-agent-announcements-v2 ne contient PAS le code d'annonces (repartie sur d'autres fixes codex/orchestrator).
|
||||
|
||||
RESTE À FAIRE :
|
||||
1. Architect : cadrer la REPRISE — décider du rebase de 71d307d sur develop actuel, arbitrer les conflits avec le nouveau modèle de conversation (le fix Final Codex et le modèle de fil ont évolué depuis ; cf. inter-agent-live-context-shared-per-agent : log canonique PAR AGENT + vues par paire). Confirmer que le contrat Announcement/Final tient encore.
|
||||
2. Git : décider de la topologie (rebase vs re-cherry-pick du backend sur une branche fraîche depuis develop).
|
||||
3. DevBackend : réintégrer/adapter B0-B3 sur develop actuel si des conflits d'API le nécessitent.
|
||||
4. DevFrontend : écrire F1 (store/gateway annonces, index par ticket/target, borné ~20-50), F2 (preview cellule demandeur près de la drop-list, filtré par ticket_id), F3 (overlay cellule cible : texte haut + annonces défilantes au centre, monté sur live-state Working, retiré au Final/idle).
|
||||
5. QA e2e : reproduire le bug initial (Main→Architect→QA avec préambule+outil+conclusion, vérifier que le demandeur ne reçoit QUE la conclusion), puis constater le preview demandeur + l'overlay cible pendant le travail, et la fermeture au Final.
|
||||
|
||||
Chantier DISTINCT du ticket #1 (tâches de fond). Non prioritaire tant que #1 n'est pas mergé, sauf décision contraire.
|
||||
@ -1,6 +0,0 @@
|
||||
---
|
||||
issueRef: "#40"
|
||||
version: 6
|
||||
updatedBy: {"kind":"agent","agent_id":"a6ced819-b893-4213-b003-9e9dc79b9641"}
|
||||
updatedAt: 1783922451268
|
||||
---
|
||||
@ -1,16 +0,0 @@
|
||||
---
|
||||
id: "6b04c8d1-177c-422a-9955-7fee2e8afdeb"
|
||||
number: 40
|
||||
title: "[UI] réouvrir les fenetres au lancement d'IdeA"
|
||||
status: "closed"
|
||||
priority: "low"
|
||||
sprint: "5afd6780-0f76-40d7-a10f-32ee52469d74"
|
||||
links: [{"target":"#39","kind":"dependsOn"}]
|
||||
agentRefs: [{"agentId":"a6ced819-b893-4213-b003-9e9dc79b9641","role":"assigned"}]
|
||||
createdBy: {"kind":"user"}
|
||||
updatedBy: {"kind":"agent","agent_id":"a6ced819-b893-4213-b003-9e9dc79b9641"}
|
||||
createdAt: 1783757766786
|
||||
updatedAt: 1783922451268
|
||||
version: 6
|
||||
---
|
||||
Au lancement d'IdeA, j'aimerais que les fenêtres fermées lors de la précédentes fermeture de la fenêtre principale d'IdeA soient automatiqument réouvertes dans le même status, position, écran que quand elles ont été fermée
|
||||
@ -1,6 +0,0 @@
|
||||
---
|
||||
issueRef: "#41"
|
||||
version: 6
|
||||
updatedBy: {"kind":"agent","agent_id":"a6ced819-b893-4213-b003-9e9dc79b9641"}
|
||||
updatedAt: 1783878363957
|
||||
---
|
||||
@ -1,16 +0,0 @@
|
||||
---
|
||||
id: "7d026901-333a-46a6-87f6-7384bf742310"
|
||||
number: 41
|
||||
title: "[UI] Selection multiple lors de la selection de tickets pour les sprints"
|
||||
status: "closed"
|
||||
priority: "low"
|
||||
sprint: "5afd6780-0f76-40d7-a10f-32ee52469d74"
|
||||
links: []
|
||||
agentRefs: [{"agentId":"a6ced819-b893-4213-b003-9e9dc79b9641","role":"assigned"}]
|
||||
createdBy: {"kind":"user"}
|
||||
updatedBy: {"kind":"agent","agent_id":"a6ced819-b893-4213-b003-9e9dc79b9641"}
|
||||
createdAt: 1783757895085
|
||||
updatedAt: 1783878363957
|
||||
version: 6
|
||||
---
|
||||
Lorsque je selectionne les tickets pour mes sprints, j'iamerais que la selection me permette d'en choisir plusieurs à la fois pour ne pas avoir à réouvrir chaque fois la fenetre.
|
||||
@ -1,6 +0,0 @@
|
||||
---
|
||||
issueRef: "#42"
|
||||
version: 2
|
||||
updatedBy: {"kind":"agent","agent_id":"a6ced819-b893-4213-b003-9e9dc79b9641"}
|
||||
updatedAt: 1783877612067
|
||||
---
|
||||
@ -1,16 +0,0 @@
|
||||
---
|
||||
id: "239aff64-a131-47eb-9a95-cc56c8c369c6"
|
||||
number: 42
|
||||
title: "[UI] Clarifier les contrôles d'en-tête de panneau (DockControls) — icônes libellées + tooltips alignés sur le menu Panneaux"
|
||||
status: "closed"
|
||||
priority: "low"
|
||||
sprint: null
|
||||
links: [{"target":"#26","kind":"relatesTo"}]
|
||||
agentRefs: []
|
||||
createdBy: {"kind":"agent","agent_id":"a6ced819-b893-4213-b003-9e9dc79b9641"}
|
||||
updatedBy: {"kind":"agent","agent_id":"a6ced819-b893-4213-b003-9e9dc79b9641"}
|
||||
createdAt: 1783862180616
|
||||
updatedAt: 1783877612067
|
||||
version: 2
|
||||
---
|
||||
Refinement UX suite à #26. Remplacer les glyphes peu explicites des en-têtes de panneaux docké/flottant (◧ ◨ ⧉ ⤢ ✕) par des boutons-icônes libellés + tooltips (title natif), alignés strictement sur les libellés du menu Panneaux. Spec UX figé : IconButton existant (@/shared, pas de lib externe, pas de Tooltip custom), ordre [⇤ Ancré à gauche][⇥ Ancré à droite][□ Flottant][↗ Fenêtre détachée][× Fermé] ; title + aria-label "<action> — <titre panneau>" ; placement courant = actif (aria-pressed=true, bg-raised text-content, ring-1 ring-border-strong) et NON désactivé ; "Fenêtre détachée" masqué pour projects et désactivé sans projet actif ; conteneur flex shrink-0 items-center gap-1. Périmètre strict : DockControls dans ProjectsView.tsx uniquement, aucun changement LayoutGrid/LeafView/cellules agents/write-portal/F3/DockRegion/FloatingWindow/ViewWindow.
|
||||
@ -1,349 +0,0 @@
|
||||
---
|
||||
issueRef: "#43"
|
||||
version: 6
|
||||
updatedBy: {"kind":"agent","agent_id":"a6ced819-b893-4213-b003-9e9dc79b9641"}
|
||||
updatedAt: 1784707900405
|
||||
---
|
||||
# Ticket #43 — Cadrage consolidé v2 du système de plugins
|
||||
|
||||
> Mise à jour Architect du 2026-07-21 après retour QA F4. Ce carnet v2 annule les ambiguïtés du cadrage initial, en particulier sur le schéma de layout custom plugin.
|
||||
|
||||
## 0. Décisions discovery conservées
|
||||
|
||||
- Plugins **full-trust** v1 : pas de sandbox UI.
|
||||
- Bundle **JS/ESM pré-compilé**, importé dynamiquement ; IdeA ne compile pas de TS/TSX.
|
||||
- Installation **globale** dans le dossier données utilisateur de l'application, pas dans les projets.
|
||||
- Distribution v1 locale : dossier ou archive locale ; packaging compatible archive partageable future type `.vsix`.
|
||||
- Contributions v1 : menus top-level, items de menus existants, layouts custom React arbitraires, serveurs MCP externes.
|
||||
- MCP plugin = process serveur MCP externe déclaré par manifeste et supervisé via le pont MCP existant.
|
||||
- Propreté retrait : après uninstall + redémarrage, aucune contribution, aucun process, aucune entrée fantôme, aucun état plugin-specific.
|
||||
|
||||
## 1. Store global et cycle de vie
|
||||
|
||||
Store global :
|
||||
|
||||
```text
|
||||
{app_data_dir}/plugins/
|
||||
registry.json
|
||||
installed/
|
||||
<pluginId>/
|
||||
idea-plugin.json
|
||||
dist/index.js
|
||||
assets/...
|
||||
servers/...
|
||||
```
|
||||
|
||||
États v1 persistés :
|
||||
|
||||
```text
|
||||
enabled
|
||||
disabled
|
||||
pending-enable
|
||||
pending-disable
|
||||
pending-uninstall
|
||||
invalid
|
||||
```
|
||||
|
||||
Règles :
|
||||
|
||||
- Installer depuis archive ou dossier local copie toujours un snapshot dans `installed/<pluginId>/`.
|
||||
- `registry.json` porte seulement l'état global nécessaire ; une désinstallation réussie supprime l'entrée registry.
|
||||
- Disable/uninstall en session masque les contributions UI et arrête MCP immédiatement si possible, mais le code ESM déjà importé n'est purgé strictement qu'au redémarrage.
|
||||
- Au boot, le frontend reconstruit une registry plugin vide puis charge uniquement les plugins `enabled` et non `pending-uninstall`.
|
||||
|
||||
## 2. Manifeste v1
|
||||
|
||||
Fichier obligatoire : `idea-plugin.json`.
|
||||
|
||||
```json
|
||||
{
|
||||
"ideaPluginManifestVersion": 1,
|
||||
"id": "dev.acme.gitgraph",
|
||||
"displayName": "Git Graph",
|
||||
"publisher": "Acme DevTools",
|
||||
"version": "1.2.3",
|
||||
"engines": { "idea": ">=0.1.0 <1.0.0" },
|
||||
"main": "dist/index.js",
|
||||
"icon": "assets/icon.svg",
|
||||
"trustLevel": "full",
|
||||
"capabilities": ["ui", "mcp"],
|
||||
"contributes": {
|
||||
"menus": [],
|
||||
"menuItems": [],
|
||||
"layouts": [],
|
||||
"mcpServers": []
|
||||
},
|
||||
"archive": {
|
||||
"files": ["idea-plugin.json", "dist/**", "assets/**", "servers/**"]
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
Validation :
|
||||
|
||||
- `trustLevel` vaut uniquement `full` en v1.
|
||||
- `main`, `icon`, assets et commandes MCP relatives ne doivent contenir ni chemin absolu ni `..`.
|
||||
- `id` stable, unique, reverse-DNS recommandé.
|
||||
- `version` SemVer.
|
||||
- `engines.idea` incompatible => plugin `invalid`, jamais chargé.
|
||||
|
||||
## 3. Contrat définitif des layouts custom plugin
|
||||
|
||||
### 3.1 Décision ferme
|
||||
|
||||
`CustomPluginLayout` est une **vraie variante top-level de `LayoutNode`**, pas un champ optionnel de `LeafCell`.
|
||||
|
||||
Motif : un layout plugin occupe une zone de l'arbre au même niveau conceptuel qu'une leaf terminal, un split ou une grid. Le mettre dans `LeafCell` mélangerait deux responsabilités incompatibles : terminal/session/agent d'un côté, composant React arbitraire et état opaque plugin de l'autre.
|
||||
|
||||
### 3.2 Schéma JSON canonique
|
||||
|
||||
Le layout tree garde le format serde existant `#[serde(tag = "type", content = "node")]`.
|
||||
|
||||
Union canonique :
|
||||
|
||||
```ts
|
||||
export type LayoutNode =
|
||||
| { type: "leaf"; node: LeafCell }
|
||||
| { type: "split"; node: SplitContainer }
|
||||
| { type: "grid"; node: GridContainer }
|
||||
| { type: "customPluginLayout"; node: CustomPluginLayoutCell };
|
||||
```
|
||||
|
||||
Payload canonique :
|
||||
|
||||
```ts
|
||||
export interface CustomPluginLayoutCell {
|
||||
id: string;
|
||||
pluginId: string;
|
||||
layoutType: string;
|
||||
state: unknown;
|
||||
}
|
||||
```
|
||||
|
||||
Exemple complet :
|
||||
|
||||
```json
|
||||
{
|
||||
"root": {
|
||||
"type": "customPluginLayout",
|
||||
"node": {
|
||||
"id": "018f0c5a-2b4b-70d4-a7c2-300000000001",
|
||||
"pluginId": "dev.acme.gitgraph",
|
||||
"layoutType": "dev.acme.gitgraph.layout",
|
||||
"state": {
|
||||
"branchFilter": "main"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
Dans un split :
|
||||
|
||||
```json
|
||||
{
|
||||
"type": "split",
|
||||
"node": {
|
||||
"id": "split-1",
|
||||
"direction": "row",
|
||||
"children": [
|
||||
{
|
||||
"weight": 1,
|
||||
"node": {
|
||||
"type": "leaf",
|
||||
"node": { "id": "terminal-1" }
|
||||
}
|
||||
},
|
||||
{
|
||||
"weight": 1,
|
||||
"node": {
|
||||
"type": "customPluginLayout",
|
||||
"node": {
|
||||
"id": "plugin-cell-1",
|
||||
"pluginId": "dev.acme.gitgraph",
|
||||
"layoutType": "dev.acme.gitgraph.layout",
|
||||
"state": {}
|
||||
}
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
Dans une grid, `GridCell.node` peut pareillement être `{ type: "customPluginLayout", node: ... }`.
|
||||
|
||||
### 3.3 Ce qui est explicitement interdit
|
||||
|
||||
Cette forme n'est **pas** contractuelle et ne doit plus être produite ni consommée comme modèle canonique :
|
||||
|
||||
```json
|
||||
{
|
||||
"type": "leaf",
|
||||
"node": {
|
||||
"id": "leaf-1",
|
||||
"pluginLayout": {
|
||||
"pluginId": "dev.acme.gitgraph",
|
||||
"layoutType": "dev.acme.gitgraph.layout",
|
||||
"state": {}
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
`LeafCell.pluginLayout` est une divergence frontend issue de l'ambiguïté initiale. Elle doit être supprimée du modèle domaine TS ou limitée à une migration locale temporaire de tests/mocks ; elle ne fait pas partie de l'IPC ni de la persistance.
|
||||
|
||||
### 3.4 Disponibilité et fallback
|
||||
|
||||
La disponibilité n'est pas stockée dans le layout. Elle est dérivée côté UI à partir du plugin registry/runtime catalog :
|
||||
|
||||
```ts
|
||||
export type PluginLayoutAvailability =
|
||||
| "available"
|
||||
| "plugin-disabled"
|
||||
| "plugin-missing"
|
||||
| "incompatible";
|
||||
```
|
||||
|
||||
Rendu :
|
||||
|
||||
- `available` : rendre le composant React enregistré pour `layoutType`.
|
||||
- `plugin-disabled`, `plugin-missing`, `incompatible` : rendre le fallback non destructif `Layout indisponible`.
|
||||
- Le fallback ne transforme pas automatiquement le nœud et ne supprime jamais `state`.
|
||||
|
||||
### 3.5 Ajustements requis
|
||||
|
||||
Verdict convergence F4 : **frontend à ajuster, backend à conserver**.
|
||||
|
||||
Backend :
|
||||
|
||||
- L'implémentation actuelle `LayoutNode::CustomPluginLayout(CustomPluginLayoutCell)` sérialisée `type: "customPluginLayout"` est le contrat canonique.
|
||||
- À vérifier seulement : roundtrip serde et DTO Tauri exposent bien `pluginId`, `layoutType`, `state` en camelCase.
|
||||
|
||||
Frontend :
|
||||
|
||||
- Ajouter la variante `{ type: "customPluginLayout"; node: CustomPluginLayoutCell }` à `LayoutNode`.
|
||||
- Retirer `pluginLayout?: CustomPluginLayoutCell` de `LeafCell` comme contrat domaine.
|
||||
- Adapter `LayoutGrid`/renderer récursif pour router `type === "customPluginLayout"` vers `PluginLayoutCellView`.
|
||||
- Adapter `layoutAvailability`, fallback et tests pour recevoir le payload depuis `node.node` de la variante top-level.
|
||||
- Ajouter un test de parsing/rendu avec un layout JSON produit par Rust contenant `type: "customPluginLayout"`.
|
||||
|
||||
## 4. Contribution points menus et `when`
|
||||
|
||||
Menus v1 :
|
||||
|
||||
```ts
|
||||
type MenuTargetId = "panels" | "settings" | `plugin:${string}`;
|
||||
```
|
||||
|
||||
Items v1 :
|
||||
|
||||
```ts
|
||||
interface PluginMenuItemContribution {
|
||||
id: string;
|
||||
targetMenuId: MenuTargetId;
|
||||
label: string;
|
||||
command: string;
|
||||
order?: number;
|
||||
icon?: string;
|
||||
when?: string;
|
||||
}
|
||||
```
|
||||
|
||||
`when` v1 utilise le mini-langage booléen `&&`, `||`, `!`, parenthèses.
|
||||
|
||||
Variables :
|
||||
|
||||
```ts
|
||||
type WhenVariable =
|
||||
| "projectOpen"
|
||||
| "gitRepository"
|
||||
| "agentSelected"
|
||||
| "terminalFocused"
|
||||
| "layoutCellFocused";
|
||||
```
|
||||
|
||||
Arbitrage QA sur les variables actuellement figées à `false` :
|
||||
|
||||
- `projectOpen` : obligatoire v1, doit refléter l'état réel.
|
||||
- `gitRepository` : **bloquant avant clôture #43/F3**. Le manifeste exemple et le cas GitGraph dépendent de `projectOpen && gitRepository`; le laisser à `false` rend des contributions valides inatteignables.
|
||||
- `agentSelected`, `terminalFocused`, `layoutCellFocused` : dette acceptable v1 si elles restent explicitement documentées comme **best-effort non câblé** et donc `false` jusqu'à un lot focus/selection dédié. Ce n'est pas bloquant pour F4 ni pour la clean-removal QA, sauf si un plugin de validation les utilise dans son manifeste.
|
||||
|
||||
Ajustement recommandé : DevFrontend câble au minimum `gitRepository` depuis l'état projet/git déjà disponible, ou retire temporairement `gitRepository` des manifests/tests de validation. La préférence architecture est de le câbler, car il est déjà annoncé comme variable v1.
|
||||
|
||||
## 5. Contribution MCP et `${appDataDir}`
|
||||
|
||||
Manifest MCP :
|
||||
|
||||
```ts
|
||||
interface PluginMcpServerContribution {
|
||||
id: string;
|
||||
displayName: string;
|
||||
command: string;
|
||||
args?: string[];
|
||||
env?: Record<string, string>;
|
||||
cwd?: "${pluginRoot}" | "${appDataDir}" | string;
|
||||
transport: "stdio";
|
||||
autoStart?: boolean;
|
||||
}
|
||||
```
|
||||
|
||||
Variables de substitution contractuelles dans `command`, `args`, `env` et `cwd` :
|
||||
|
||||
- `${pluginRoot}` : obligatoire v1.
|
||||
- `${appDataDir}` : **obligatoire v1 si la spec continue de l'accepter**.
|
||||
- `${projectRoot}` : interdit v1.
|
||||
|
||||
Arbitrage QA sur `${appDataDir}` non implémenté :
|
||||
|
||||
- Pas bloquant pour F4 layout.
|
||||
- **Bloquant pour clôture B4/#43** si le manifeste continue de documenter `${appDataDir}` comme disponible. Un contrat annoncé mais non substitué crée des specs MCP fausses.
|
||||
- Deux sorties acceptables, par ordre de préférence :
|
||||
1. DevBackend implémente la substitution `${appDataDir}` dans les specs MCP plugin et ajoute tests args/env/cwd.
|
||||
2. Si le coût est refusé pour v1, retirer `${appDataDir}` du contrat manifeste et du validator, puis documenter explicitement `${pluginRoot}` comme seule variable v1.
|
||||
|
||||
Décision architecture par défaut : garder `${appDataDir}` et le faire implémenter par DevBackend, car le store global est déjà résolu côté backend et le coût est borné.
|
||||
|
||||
## 6. Lots et responsabilités actualisés
|
||||
|
||||
### F4 — convergence layout custom plugin
|
||||
|
||||
Owner : DevFrontend.
|
||||
|
||||
Livrables :
|
||||
|
||||
- Union TS `LayoutNode` alignée sur Rust avec `customPluginLayout` top-level.
|
||||
- Renderer/fallback branchés sur cette variante.
|
||||
- Suppression du contrat `LeafCell.pluginLayout`.
|
||||
- Test frontend à partir d'un JSON Rust réel.
|
||||
|
||||
Backend F4 : pas de refonte attendue ; seulement vérifier/maintenir les tests serde existants.
|
||||
|
||||
### F3 — `when.gitRepository`
|
||||
|
||||
Owner : DevFrontend.
|
||||
|
||||
Livrable : `gitRepository` ne doit plus être figé à `false` pour un projet Git réel avant clôture #43/F3.
|
||||
|
||||
### B4 — `${appDataDir}` MCP
|
||||
|
||||
Owner : DevBackend.
|
||||
|
||||
Livrable : substitution `${appDataDir}` dans `command`, `args`, `env`, `cwd` des specs MCP plugin, ou retrait explicite du contrat si arbitré à la baisse. Par défaut : implémenter.
|
||||
|
||||
### QA — non-régression à ajouter
|
||||
|
||||
- Layout JSON backend `customPluginLayout` top-level rendu côté frontend.
|
||||
- Fallback atteint si plugin missing/disabled avec nœud top-level.
|
||||
- Aucun fallback basé sur `leaf.node.pluginLayout` ne compte comme validation du contrat.
|
||||
- MCP spec avec `${pluginRoot}` et `${appDataDir}`.
|
||||
- Menu item `when: "projectOpen && gitRepository"` actif dans un projet Git.
|
||||
|
||||
## 7. Non-objectifs maintenus v1
|
||||
|
||||
- Pas de sandbox UI.
|
||||
- Pas de hot-unload mémoire garanti dans la même session.
|
||||
- Pas de marketplace distant.
|
||||
- Pas de compilation TS/TSX.
|
||||
- Pas de `${projectRoot}` pour serveurs MCP plugin globaux.
|
||||
- Pas de garantie v1 sur `agentSelected`, `terminalFocused`, `layoutCellFocused` tant qu'un lot focus/selection n'a pas été cadré.
|
||||
@ -1,16 +0,0 @@
|
||||
---
|
||||
id: "63e80352-8ce1-4116-9ec3-b4cb3fc5c077"
|
||||
number: 43
|
||||
title: "Systeme de plugins"
|
||||
status: "closed"
|
||||
priority: "medium"
|
||||
sprint: null
|
||||
links: []
|
||||
agentRefs: []
|
||||
createdBy: {"kind":"user"}
|
||||
updatedBy: {"kind":"agent","agent_id":"a6ced819-b893-4213-b003-9e9dc79b9641"}
|
||||
createdAt: 1783879315858
|
||||
updatedAt: 1784707900405
|
||||
version: 6
|
||||
---
|
||||
Système de plugins/extensions pour IdeA (à la VSCode/Visual Studio) : permettre d'ajouter des menus (dropdown façon Panneaux/Paramètres), des items dans des menus existants, des types de layout custom (à la GitGraph), et des tools MCP.
|
||||
@ -1,25 +0,0 @@
|
||||
---
|
||||
issueRef: "#44"
|
||||
version: 8
|
||||
updatedBy: {"kind":"agent","agent_id":"a6ced819-b893-4213-b003-9e9dc79b9641"}
|
||||
updatedAt: 1783976073932
|
||||
---
|
||||
## Résolution (2026-07-13)
|
||||
|
||||
Le first-run wizard tourne désormais en deux **modes explicites** passés en argument (jamais inférés de `isFirstRun`) :
|
||||
- `firstRun` : catalogue de référence seul, tout désélectionné, availability inconnue (détection auto pré-coche les CLI installés).
|
||||
- `edit` (rouvert via *Settings ▸ Configure profiles*, `forceOpen`) : les profils déjà configurés reviennent **pré-sélectionnés avec leur vraie config**, en tête ; les profils de référence dont l'`id` est déjà configuré sont **dédupliqués par `profile.id` uniquement** (plusieurs OpenCode locaux partagent command/adapter mais diffèrent par endpoint/model). La détection auto ne touche PAS la sélection initiale (`preselect:false`).
|
||||
|
||||
Logique pure isolée dans `wizardEntries.ts` (`buildWizardEntries`) pour tester les invariants unitairement.
|
||||
|
||||
### Fichiers
|
||||
- `frontend/src/features/first-run/wizardEntries.ts` (+ `.test.ts`) — nouveaux
|
||||
- `useFirstRun.ts` — `mode` param, charge `listProfiles()` en edit via `Promise.all`
|
||||
- `FirstRunWizard.tsx` — `mode = forceOpen ? "edit" : "firstRun"`
|
||||
- `FirstRunWizard.test.tsx` — étendu
|
||||
|
||||
### QA — vert
|
||||
`npx vitest run wizardEntries.test.ts FirstRunWizard.test.tsx` → 37 passed ; `npx tsc --noEmit` → exit 0.
|
||||
|
||||
### Git
|
||||
Commit `8cdc44d` sur `feature/ticket44-firstrun-keep-profile-info` (base develop), mergé `--no-ff` vers `develop` (`c67ec4f`). Aucune action sortante.
|
||||
@ -1,16 +0,0 @@
|
||||
---
|
||||
id: "d7c17017-f6fb-4e55-8119-8fbc42641f48"
|
||||
number: 44
|
||||
title: "Garder les infos du profils courant sur l'affichage d'edition des profiles"
|
||||
status: "closed"
|
||||
priority: "medium"
|
||||
sprint: "5afd6780-0f76-40d7-a10f-32ee52469d74"
|
||||
links: []
|
||||
agentRefs: [{"agentId":"a6ced819-b893-4213-b003-9e9dc79b9641","role":"assigned"}]
|
||||
createdBy: {"kind":"user"}
|
||||
updatedBy: {"kind":"agent","agent_id":"a6ced819-b893-4213-b003-9e9dc79b9641"}
|
||||
createdAt: 1783879634794
|
||||
updatedAt: 1783976073932
|
||||
version: 8
|
||||
---
|
||||
Si je vais dans l'edition des profiles, le pré-remplissage des profiles ne correspond pas aux profiles existants. C'est a dire que par exemple pour le profiles OpenCode, j'aimerais que si j'en ai déjà un de créé, celui (ou ceux d'affichés) correspondent à celui ou ceux qui existent déjà.
|
||||
@ -1,6 +0,0 @@
|
||||
---
|
||||
issueRef: "#45"
|
||||
version: 6
|
||||
updatedBy: {"kind":"agent","agent_id":"a6ced819-b893-4213-b003-9e9dc79b9641"}
|
||||
updatedAt: 1783925599109
|
||||
---
|
||||
@ -1,16 +0,0 @@
|
||||
---
|
||||
id: "b4e30445-b972-400a-879f-193c9c7aa10e"
|
||||
number: 45
|
||||
title: "[Bug] Erreur OpenCode au lancement IdeA"
|
||||
status: "closed"
|
||||
priority: "medium"
|
||||
sprint: "e28a4d53-8bd2-446a-b0ac-2a017373b8b2"
|
||||
links: []
|
||||
agentRefs: [{"agentId":"a6ced819-b893-4213-b003-9e9dc79b9641","role":"assigned"}]
|
||||
createdBy: {"kind":"user"}
|
||||
updatedBy: {"kind":"agent","agent_id":"a6ced819-b893-4213-b003-9e9dc79b9641"}
|
||||
createdAt: 1783920311014
|
||||
updatedAt: 1783925599109
|
||||
version: 6
|
||||
---
|
||||
Quand je lance IdeA avec un layout qui contient opencode, j'ai un beandeau d'erreur dans la cellule opencode qui dit : Échec du lancement de l'agent : model server error (port_occupied): port occupied: 8080. Par contre si je relance une cellule une fois IdeA lancé, ça fonctionne et la cellule s'affiche correctement.
|
||||
@ -1,6 +0,0 @@
|
||||
---
|
||||
issueRef: "#46"
|
||||
version: 6
|
||||
updatedBy: {"kind":"agent","agent_id":"a6ced819-b893-4213-b003-9e9dc79b9641"}
|
||||
updatedAt: 1783939380889
|
||||
---
|
||||
@ -1,16 +0,0 @@
|
||||
---
|
||||
id: "1fe837f0-bc97-4b8e-945e-940fdd3c0249"
|
||||
number: 46
|
||||
title: "[Bug] Plus de boutons pour ajouter un projet en onglet"
|
||||
status: "closed"
|
||||
priority: "low"
|
||||
sprint: "e28a4d53-8bd2-446a-b0ac-2a017373b8b2"
|
||||
links: []
|
||||
agentRefs: [{"agentId":"a6ced819-b893-4213-b003-9e9dc79b9641","role":"assigned"}]
|
||||
createdBy: {"kind":"user"}
|
||||
updatedBy: {"kind":"agent","agent_id":"a6ced819-b893-4213-b003-9e9dc79b9641"}
|
||||
createdAt: 1783923416403
|
||||
updatedAt: 1783939380889
|
||||
version: 6
|
||||
---
|
||||
Il manque un bouton + dans la barre des onglets des projets pour pouvoir ajouter un projet en onglet
|
||||
@ -1,6 +0,0 @@
|
||||
---
|
||||
issueRef: "#47"
|
||||
version: 6
|
||||
updatedBy: {"kind":"agent","agent_id":"a6ced819-b893-4213-b003-9e9dc79b9641"}
|
||||
updatedAt: 1783939089770
|
||||
---
|
||||
@ -1,16 +0,0 @@
|
||||
---
|
||||
id: "0591d2d3-b03e-41bc-8c6b-349fc4ddf1a5"
|
||||
number: 47
|
||||
title: "[Bug] Réouverture de fenêtres non lié au projet"
|
||||
status: "closed"
|
||||
priority: "medium"
|
||||
sprint: "e28a4d53-8bd2-446a-b0ac-2a017373b8b2"
|
||||
links: []
|
||||
agentRefs: [{"agentId":"a6ced819-b893-4213-b003-9e9dc79b9641","role":"assigned"}]
|
||||
createdBy: {"kind":"user"}
|
||||
updatedBy: {"kind":"agent","agent_id":"a6ced819-b893-4213-b003-9e9dc79b9641"}
|
||||
createdAt: 1783923465694
|
||||
updatedAt: 1783939089770
|
||||
version: 6
|
||||
---
|
||||
Si je suis sur un projet A, et que j'ouvre par exemple le panneau des agents. Si je ferme IdeA et que je réouvre IdeA, comme convenui j'ai ma fenêtre des agents qui s'affiche. Mais il m'affiche directement les agents de mon projet A, alors que je n'ai encore ouvert aucun projet. J'aimerais alors qu'il ne m'affiche rien avec juste un message qui me demande d'ouvrir un projet pour qu'il puisse afficher ce qu'il faut dedans et que ça soit toujours lié au projet en focus
|
||||
@ -1,6 +0,0 @@
|
||||
---
|
||||
issueRef: "#48"
|
||||
version: 6
|
||||
updatedBy: {"kind":"agent","agent_id":"a6ced819-b893-4213-b003-9e9dc79b9641"}
|
||||
updatedAt: 1783924961311
|
||||
---
|
||||
@ -1,16 +0,0 @@
|
||||
---
|
||||
id: "0e449e11-2af9-47ca-83da-03568d9af100"
|
||||
number: 48
|
||||
title: "[Bug] Bandeau d'affichage d'erreur au dessus des boutons de gestion de cellule"
|
||||
status: "closed"
|
||||
priority: "medium"
|
||||
sprint: "e28a4d53-8bd2-446a-b0ac-2a017373b8b2"
|
||||
links: []
|
||||
agentRefs: [{"agentId":"a6ced819-b893-4213-b003-9e9dc79b9641","role":"assigned"}]
|
||||
createdBy: {"kind":"user"}
|
||||
updatedBy: {"kind":"agent","agent_id":"a6ced819-b893-4213-b003-9e9dc79b9641"}
|
||||
createdAt: 1783923674564
|
||||
updatedAt: 1783924961311
|
||||
version: 6
|
||||
---
|
||||
Les bandeaux d'affichage d'erreur de cellule passent par dessus les boutons de changement d'agent, de split de cellule ou de fermeture de cellule ce qui rend la gestion de la cellule impossible s'il y a une erreur. Il faudrait que les boutons soient par dessus le bandeau d'erreur pour être accessibles
|
||||
@ -1,20 +0,0 @@
|
||||
---
|
||||
issueRef: "#49"
|
||||
version: 5
|
||||
updatedBy: {"kind":"agent","agent_id":"a6ced819-b893-4213-b003-9e9dc79b9641"}
|
||||
updatedAt: 1783940643502
|
||||
---
|
||||
## Nettoyage mémoire — fait (Main, 2026-07-13)
|
||||
|
||||
Store passé de ~83 notes à **52 notes**, index `MEMORY.md` remis en parité stricte (52 entrées = 52 fichiers, 0 lien cassé, 0 orphelin).
|
||||
|
||||
**Supprimé (31, récupérable via git)** — notes transitoires / supersédées :
|
||||
- 20 `checkpoint-*` (snapshots de work-state de sprints livrés).
|
||||
- Campagne de tests MCP/backstop clôturée (programme live-state fermé, cf. `live-state-persistence-program-closed-ls8`) : `mcp-functional-test-plan-2026-06-24`, `mcp-functional-tests-t1-t9-green-live-2026-06-24`, `mcp-t7-backstop-...`, `mcp-t10a-...`, `mcp-t10b-...`, `mcp-e2e-findings-...`, `backstop-no-reply-live-test-failed-...`, `backstop-fires-on-intra-task-turn-rootcause`, `reconcile-live-state-implemented-feature-branch`, `resume-after-appimage-rebuild-mcp-e2e`.
|
||||
- `f35-launch-status-done-config-crud-blocked` (supersédé par `f35-config-crud-delivered`).
|
||||
|
||||
**Conservé** : toutes les notes de design/contrat/référence durables + gotchas (build, focus-trap, sandbox, ports/contrats).
|
||||
|
||||
**Restauré à l'index** (fichiers présents mais index dérivé/désync) : `develop-realigned-to-cli-ui-baseline-2026-07-02`, `feature-agent-skill-awareness-design`, `inter-agent-announcements-feature-and-codex-final-bug`, `inter-agent-live-context-shared-per-agent`, `ticket4-announcements-frontend-f1f2f3`.
|
||||
|
||||
Commit du diff `.ideai/memory/` à confier à l'agent Git.
|
||||
@ -1,16 +0,0 @@
|
||||
---
|
||||
id: "a6552142-1c48-49b0-85a7-56b6ebaaacff"
|
||||
number: 49
|
||||
title: "[Misc] clean les memory qui ne sont plus valable ou qui n'ont plus de raisons d'être"
|
||||
status: "closed"
|
||||
priority: "medium"
|
||||
sprint: null
|
||||
links: []
|
||||
agentRefs: [{"agentId":"a6ced819-b893-4213-b003-9e9dc79b9641","role":"assigned"}]
|
||||
createdBy: {"kind":"user"}
|
||||
updatedBy: {"kind":"agent","agent_id":"a6ced819-b893-4213-b003-9e9dc79b9641"}
|
||||
createdAt: 1783935372750
|
||||
updatedAt: 1783940643502
|
||||
version: 5
|
||||
---
|
||||
Il y a beaucoup de memories dans la liste Memory. J'iamerais qu'un nettoyage soit fait au cas ou certaines ne soient plus d'actualité.
|
||||
@ -1,6 +0,0 @@
|
||||
---
|
||||
issueRef: "#5"
|
||||
version: 4
|
||||
updatedBy: {"kind":"agent","agent_id":"a6ced819-b893-4213-b003-9e9dc79b9641"}
|
||||
updatedAt: 1783328740886
|
||||
---
|
||||
@ -1,22 +0,0 @@
|
||||
---
|
||||
id: "bd0f52c4-480f-4cf8-9c4c-05d05fb9e102"
|
||||
number: 5
|
||||
title: "Tâches de fond — dette de contrat DTO work-state : summary non affiché + owner/project inutiles + tri"
|
||||
status: "closed"
|
||||
priority: "low"
|
||||
links: [{"target":"#1","kind":"relatesTo"}]
|
||||
agentRefs: [{"agentId":"a6ced819-b893-4213-b003-9e9dc79b9641","role":"assigned"}]
|
||||
createdBy: {"kind":"agent","agent_id":"a6ced819-b893-4213-b003-9e9dc79b9641"}
|
||||
updatedBy: {"kind":"agent","agent_id":"a6ced819-b893-4213-b003-9e9dc79b9641"}
|
||||
createdAt: 1783115680555
|
||||
updatedAt: 1783328740886
|
||||
version: 4
|
||||
---
|
||||
Dette de contrat mineure détectée lors du fix T3 du ticket #1 (projection background_tasks dans le read-model work-state, branche feature/background-tasks-first-class). Non bloquant : Cancel/Retry fonctionnent en live.
|
||||
|
||||
Points à traiter :
|
||||
|
||||
- [ ] `summary` : le DTO backend `AgentBackgroundTaskStateDto` émet un `summary` (résumé/erreur/raison du résultat terminal) que le type frontend `BackgroundCompletion` ne porte pas → info perdue, non affichée dans le panneau. Décider si on l'affiche (utile pour comprendre un échec/annulation d'un coup d'œil) et brancher.
|
||||
- [ ] `ownerAgentId`/`projectId` absents du payload par-agent : inoffensif (les tâches sont imbriquées sous leur agent, fallback ownerAgentId = agentId), mais le chemin de merge top-level dans `normalizeProjectWorkState` reste du code défensif inutilisé pour ce contrat. À nettoyer ou documenter comme volontaire.
|
||||
|
||||
Contexte : mémoire projet `workstate-background-tasks-projection-fix` (décision d'archi) et `tickets-t3-frontend-validation-verdict` (verdict FE + écarts). Le point tri sur finishedAtMs a déjà été corrigé (bascule sur updatedAtMs) et n'est PAS dans cette dette.
|
||||
@ -1,6 +0,0 @@
|
||||
---
|
||||
issueRef: "#50"
|
||||
version: 7
|
||||
updatedBy: {"kind":"agent","agent_id":"a6ced819-b893-4213-b003-9e9dc79b9641"}
|
||||
updatedAt: 1783959345112
|
||||
---
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user