Compare commits
84 Commits
78f7c8fe2d
...
6959fbbe9a
| Author | SHA1 | Date | |
|---|---|---|---|
| 6959fbbe9a | |||
| a051b5299a | |||
| 8c4f1ea2e3 | |||
| e3e887d6a4 | |||
| dce61ae1aa | |||
| 80c9e0a236 | |||
| 033e9a86d5 | |||
| efaeb31a38 | |||
| a88307c5ff | |||
| 5baf5821d4 | |||
| 0061685b08 | |||
| fd2ab4a0d7 | |||
| fbe69de0c2 | |||
| 95066d4110 | |||
| add61f176d | |||
| 5a30ec8b9c | |||
| 8031d86deb | |||
| 3fc15fd706 | |||
| c19fb6bf8c | |||
| 961bf4623f | |||
| 07df50f9de | |||
| 0eea4421f9 | |||
| e741f76cab | |||
| e21db9bf40 | |||
| 92b17e9a69 | |||
| dbaf6fe2f4 | |||
| 46086af026 | |||
| 50b71f4ece | |||
| ac659c42f2 | |||
| 5efb026a80 | |||
| 32c257d2e1 | |||
| 10c0bef5e5 | |||
| f6685aa745 | |||
| d4e61a86f0 | |||
| e042ced724 | |||
| fbe3c51fd4 | |||
| fe5fe7cb70 | |||
| f81b385616 | |||
| 5be5c5975e | |||
| 9b1ced50be | |||
| fda4126a5f | |||
| 6165eaf8d9 | |||
| c100a0317c | |||
| aa850374ce | |||
| eec3e0a5bc | |||
| d0b65a92bd | |||
| af6b76935c | |||
| 2c3a46e690 | |||
| 3f27eb878b | |||
| f5007fcb11 | |||
| 6bd5e64dd1 | |||
| 21a84ab8f2 | |||
| 5955ea37a2 | |||
| 30c8009a96 | |||
| 712b19ed10 | |||
| 73a676a002 | |||
| 4280c70514 | |||
| 25e1231a9e | |||
| b55d12d035 | |||
| 66f0dca916 | |||
| 8158057b1d | |||
| 2692b9cc03 | |||
| 9d6d0fbdf1 | |||
| d965970696 | |||
| 6270f98e54 | |||
| c1ff98086c | |||
| f0ba559885 | |||
| b4f4c8eb71 | |||
| ec305657ad | |||
| 6fa41013ed | |||
| bd4f76ae74 | |||
| 73c6081ab8 | |||
| e1b1c1e103 | |||
| f0a63de042 | |||
| 9b150983bb | |||
| f4ae5df17c | |||
| bcd489aac8 | |||
| 5d6a295715 | |||
| 50219df4e5 | |||
| 05402c7544 | |||
| 6da52c6a02 | |||
| 1ef1fd9e40 | |||
| 454f8ad57d | |||
| 045e0984cc |
4
.gitignore
vendored
4
.gitignore
vendored
@ -48,7 +48,6 @@ frontend/coverage/
|
||||
# Ticket store IdeA: l'utilisateur veut conserver l'état local des tickets en
|
||||
# dehors des branches Git. À ignorer, sinon les changements de branche peuvent
|
||||
# écraser/supprimer cet état local.
|
||||
.ideai/tickets/
|
||||
# Volatile agent live-state snapshot ("who is doing what right now", lot LS2):
|
||||
# rebuilt at runtime, keyed last-writer-wins — not versioned (unlike .ideai/memory/).
|
||||
.ideai/live-state.json
|
||||
@ -73,7 +72,4 @@ Thumbs.db
|
||||
.ideai/conversations/
|
||||
.ideai/agents.json
|
||||
.ideai/background-tasks/
|
||||
|
||||
# IdeA local runtime state kept outside Git
|
||||
.ideai/tickets/
|
||||
.ideai/mcp-tool-permissions.json
|
||||
|
||||
@ -37,7 +37,7 @@ Tu t'occupes **du repo git local** :
|
||||
|
||||
Le dépôt s'articule autour de trois niveaux :
|
||||
|
||||
```
|
||||
```text
|
||||
main ← branche de RELEASE. Stable, livrable. On n'y commite jamais en direct.
|
||||
│
|
||||
develop ← branche d'INTÉGRATION. On y merge chaque feature une fois TERMINÉE et VERTE.
|
||||
@ -62,7 +62,7 @@ feature/* ← une branche PAR nouvelle feature. C'est là que le dev se fait.
|
||||
|
||||
Tu interviens à **deux moments** du cycle de dev (cf. CLAUDE.md §3), encadré par Main :
|
||||
|
||||
```
|
||||
```text
|
||||
1. Main : « nouvelle feature X » (architecture cadrée par Architect)
|
||||
→ TOI : décider de la branche.
|
||||
- nouvelle feature indépendante → créer feature/X depuis develop, switch dessus
|
||||
@ -107,7 +107,18 @@ tu le dis.
|
||||
|
||||
---
|
||||
|
||||
## 5. Délégation & collaboration
|
||||
## 5. Sous-repos Git imbriqués
|
||||
|
||||
- Un dossier du projet pouvant contenir son propre `.git` fait **pleinement partie de ton périmètre** de gestion du dépôt local.
|
||||
- Tu **ne redemandes pas à l'utilisateur** quoi faire pour un sous-repo/sous-module/sous-dépôt : tu examines l'état réel et tu **tranches**.
|
||||
- Si un sous-repo est un **vrai sous-module voulu**, tu le traites comme tel (gitlink, état détaché, commit du pointeur dans le repo parent si pertinent).
|
||||
- Si un sous-repo est un **dépôt imbriqué accidentel ou non initialisé** qui bloque l'intégration locale, tu prends la décision locale appropriée pour permettre le commit correct du lot dans le repo principal, puis tu la rapportes clairement à Main.
|
||||
- Si le lot porte sur des fichiers d'un sous-repo imbriqué, tu dois décider comment les versionner proprement au lieu de déclarer un blocage par défaut.
|
||||
- Tu ne considères pas la simple présence d'un `.git` imbriqué comme un motif suffisant pour t'arrêter ou renvoyer la décision à l'utilisateur.
|
||||
|
||||
---
|
||||
|
||||
## 6. Délégation & collaboration
|
||||
|
||||
- Quand Main te délègue une tâche via IdeA, tu la traites puis tu termines ton tour avec
|
||||
ta réponse normale. IdeA capture automatiquement ta réponse finale ; tu ne gères pas
|
||||
@ -116,4 +127,4 @@ tu le dis.
|
||||
court), ce que tu as mergé/rebasé, et **ta décision** (pourquoi cette
|
||||
branche, pourquoi ce merge ou ce non-merge).
|
||||
- En cas de conflit de merge/rebase, tu le signales à Main avec le détail ; tu ne forces
|
||||
pas une résolution hasardeuse.
|
||||
pas une résolution hasardeuse.
|
||||
@ -109,3 +109,16 @@ Si la demande utilisateur contredit le cycle, rappelle brièvement la règle et
|
||||
---
|
||||
|
||||
*Dernière mise à jour : 2026-06-20*
|
||||
|
||||
---
|
||||
|
||||
## Découverte exhaustive des outils MCP IdeA
|
||||
|
||||
Codex charge les outils MCP de façon différée : une recherche sémantique peut ne retourner qu'un sous-ensemble des outils IdeA disponibles. Avant toute opération d'orchestration, de tickets, de mémoire, de contexte, de skills, de templates, de sprint, de workstate ou de tâche en arrière-plan :
|
||||
|
||||
1. Inspecte le registre complet des outils disponibles et filtre le préfixe `mcp__idea__`.
|
||||
2. Choisis l'outil natif IdeA le plus spécifique dans cet inventaire exhaustif.
|
||||
3. N'utilise pas l'absence d'un outil dans les résultats partiels de recherche comme preuve de son indisponibilité.
|
||||
4. Appelle les outils différés par leur nom exact via le registre lorsqu'ils ne sont pas exposés directement.
|
||||
|
||||
Cette vérification de découverte est obligatoire au début de chaque workflow IdeA, afin que les outils natifs soient utilisés spontanément et pas seulement lorsqu'un utilisateur en rappelle le nom.
|
||||
@ -10,7 +10,7 @@
|
||||
|
||||
## 1. Ta mission (le cycle, §3 de la méthode)
|
||||
|
||||
```
|
||||
```text
|
||||
DevBackend/DevFrontend écrit le code
|
||||
→ TOI : tu écris les tests unitaires + tu les exécutes
|
||||
→ vert : feature validée
|
||||
@ -28,6 +28,7 @@ tu le signales tel quel.
|
||||
- `crates/application` : use cases avec **fakes** des ports (jamais d'adapter concret).
|
||||
- `crates/infrastructure` : adapters concrets (peuvent toucher FS temporaire), tests d'intégration ciblés.
|
||||
- `crates/app-tauri` : DTO (round-trip serde), wiring.
|
||||
- `crates/web-server` : handlers / Web API / mapping requête-réponse / erreurs.
|
||||
- Commandes : `cargo test -p <crate>` ciblé, `cargo test --workspace` global.
|
||||
|
||||
**Frontend (TS/React)** :
|
||||
@ -42,6 +43,7 @@ tu le signales tel quel.
|
||||
- **Round-trip de sérialisation** (DTO ↔ domaine, fichiers `.ideai/*.json`).
|
||||
- **Régressions** : avant de valider un lot, relance la suite complète des crates touchées.
|
||||
- **Pas de faux vert** : un test tautologique ou qui ne s'exécute pas n'est pas un test.
|
||||
- **Tests fonctionnels Web API** : dès qu'une feature passe par `web-server` ou une surface serveur/HTTP/JSON-RPC analogue, tu dois chercher une preuve fonctionnelle réelle sur les requêtes/réponses du serveur, pas seulement des tests de store/use case. Si le câblage serveur existe, ton objectif par défaut est d'avoir au moins un test qui exerce la requête publique correspondante et qui aurait échoué si le handler/DTO/route était cassé.
|
||||
|
||||
## 4. Format du rapport d'erreurs
|
||||
|
||||
@ -75,4 +77,4 @@ Trois chantiers (cadence **A+B ensemble, puis C**). Points de vigilance test :
|
||||
fichier quand un profil ne supporte pas MCP, la non-régression du protocole `.ideai/requests`.
|
||||
|
||||
Tu interviens **après** le cadrage d'`Architect`, en binôme avec le dev du lot concerné, jusqu'au
|
||||
vert.
|
||||
vert.
|
||||
@ -21,7 +21,6 @@
|
||||
"idea_context_propose",
|
||||
"idea_memory_write",
|
||||
"idea_workstate_set",
|
||||
"idea_create_skill",
|
||||
"idea_ticket_create",
|
||||
"idea_ticket_update",
|
||||
"idea_ticket_update_status",
|
||||
@ -31,82 +30,12 @@
|
||||
"idea_ticket_unlink",
|
||||
"idea_template_create",
|
||||
"idea_template_update",
|
||||
"idea_template_delete"
|
||||
"idea_template_delete",
|
||||
"idea_create_skill",
|
||||
"idea_ask_agents"
|
||||
]
|
||||
},
|
||||
"agents": [
|
||||
{
|
||||
"agentId": "a6ced819-b893-4213-b003-9e9dc79b9641",
|
||||
"policy": {
|
||||
"allowedTools": [
|
||||
"idea_list_agents",
|
||||
"idea_context_read",
|
||||
"idea_memory_read",
|
||||
"idea_skill_read",
|
||||
"idea_workstate_read",
|
||||
"idea_ticket_read",
|
||||
"idea_ticket_list",
|
||||
"idea_ticket_read_carnet",
|
||||
"idea_sprint_list",
|
||||
"idea_template_list",
|
||||
"idea_template_read",
|
||||
"idea_ask_agent",
|
||||
"idea_launch_agent",
|
||||
"idea_stop_agent",
|
||||
"idea_update_context",
|
||||
"idea_context_propose",
|
||||
"idea_memory_write",
|
||||
"idea_workstate_set",
|
||||
"idea_create_skill",
|
||||
"idea_ticket_create",
|
||||
"idea_ticket_update",
|
||||
"idea_ticket_update_status",
|
||||
"idea_ticket_update_priority",
|
||||
"idea_ticket_update_carnet",
|
||||
"idea_ticket_link",
|
||||
"idea_ticket_unlink",
|
||||
"idea_template_create",
|
||||
"idea_template_update",
|
||||
"idea_template_delete"
|
||||
]
|
||||
}
|
||||
},
|
||||
{
|
||||
"agentId": "dce19c75-9669-4e45-b8de-9950025157da",
|
||||
"policy": {
|
||||
"allowedTools": [
|
||||
"idea_list_agents",
|
||||
"idea_context_read",
|
||||
"idea_memory_read",
|
||||
"idea_skill_read",
|
||||
"idea_workstate_read",
|
||||
"idea_ticket_read",
|
||||
"idea_ticket_list",
|
||||
"idea_ticket_read_carnet",
|
||||
"idea_sprint_list",
|
||||
"idea_template_list",
|
||||
"idea_template_read",
|
||||
"idea_ask_agent",
|
||||
"idea_launch_agent",
|
||||
"idea_stop_agent",
|
||||
"idea_update_context",
|
||||
"idea_context_propose",
|
||||
"idea_memory_write",
|
||||
"idea_workstate_set",
|
||||
"idea_create_skill",
|
||||
"idea_ticket_create",
|
||||
"idea_ticket_update",
|
||||
"idea_ticket_update_status",
|
||||
"idea_ticket_update_priority",
|
||||
"idea_ticket_update_carnet",
|
||||
"idea_ticket_link",
|
||||
"idea_ticket_unlink",
|
||||
"idea_template_create",
|
||||
"idea_template_update",
|
||||
"idea_template_delete"
|
||||
]
|
||||
}
|
||||
},
|
||||
{
|
||||
"agentId": "73c853d1-c0fd-463b-ad17-1d24fefa371f",
|
||||
"policy": {
|
||||
@ -358,6 +287,81 @@
|
||||
"idea_template_delete"
|
||||
]
|
||||
}
|
||||
},
|
||||
{
|
||||
"agentId": "dce19c75-9669-4e45-b8de-9950025157da",
|
||||
"policy": {
|
||||
"allowedTools": [
|
||||
"idea_list_agents",
|
||||
"idea_context_read",
|
||||
"idea_memory_read",
|
||||
"idea_skill_read",
|
||||
"idea_workstate_read",
|
||||
"idea_ticket_read",
|
||||
"idea_ticket_list",
|
||||
"idea_ticket_read_carnet",
|
||||
"idea_sprint_list",
|
||||
"idea_template_list",
|
||||
"idea_template_read",
|
||||
"idea_ask_agent",
|
||||
"idea_launch_agent",
|
||||
"idea_stop_agent",
|
||||
"idea_update_context",
|
||||
"idea_context_propose",
|
||||
"idea_memory_write",
|
||||
"idea_workstate_set",
|
||||
"idea_create_skill",
|
||||
"idea_ticket_create",
|
||||
"idea_ticket_update",
|
||||
"idea_ticket_update_status",
|
||||
"idea_ticket_update_priority",
|
||||
"idea_ticket_update_carnet",
|
||||
"idea_ticket_link",
|
||||
"idea_ticket_unlink",
|
||||
"idea_template_create",
|
||||
"idea_template_update",
|
||||
"idea_template_delete",
|
||||
"idea_run_in_background"
|
||||
]
|
||||
}
|
||||
},
|
||||
{
|
||||
"agentId": "a6ced819-b893-4213-b003-9e9dc79b9641",
|
||||
"policy": {
|
||||
"allowedTools": [
|
||||
"idea_list_agents",
|
||||
"idea_context_read",
|
||||
"idea_memory_read",
|
||||
"idea_skill_read",
|
||||
"idea_workstate_read",
|
||||
"idea_ticket_read",
|
||||
"idea_ticket_list",
|
||||
"idea_ticket_read_carnet",
|
||||
"idea_sprint_list",
|
||||
"idea_template_list",
|
||||
"idea_template_read",
|
||||
"idea_ask_agent",
|
||||
"idea_launch_agent",
|
||||
"idea_stop_agent",
|
||||
"idea_update_context",
|
||||
"idea_context_propose",
|
||||
"idea_memory_write",
|
||||
"idea_workstate_set",
|
||||
"idea_create_skill",
|
||||
"idea_ticket_create",
|
||||
"idea_ticket_update",
|
||||
"idea_ticket_update_status",
|
||||
"idea_ticket_update_priority",
|
||||
"idea_ticket_update_carnet",
|
||||
"idea_ticket_link",
|
||||
"idea_ticket_unlink",
|
||||
"idea_template_create",
|
||||
"idea_template_update",
|
||||
"idea_template_delete",
|
||||
"idea_run_in_background",
|
||||
"idea_ask_agents"
|
||||
]
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
|
||||
@ -73,3 +73,7 @@
|
||||
- [multi-profile-codex-claude-model-catalogue-scoping](multi-profile-codex-claude-model-catalogue-scoping.md) — memory note multi-profile-codex-claude-model-catalogue-scoping
|
||||
- [model-catalogue-compat-cadrage](model-catalogue-compat-cadrage.md) — Frontières hexagonales, ports, DTO, fallback et matrice de compatibilité versionnée pour l'évolution du catalogue de modèles des profils structurés Codex/Claude.
|
||||
- [tickets-70-100-102-ux-surface-scoping](tickets-70-100-102-ux-surface-scoping.md) — memory note tickets-70-100-102-ux-surface-scoping
|
||||
- [ux-ai-profiles-opencode-persistence-list-coherence](ux-ai-profiles-opencode-persistence-list-coherence.md) — memory note ux-ai-profiles-opencode-persistence-list-coherence
|
||||
- [ticket113-controlled-args-field-rootcause](ticket113-controlled-args-field-rootcause.md) — memory note ticket113-controlled-args-field-rootcause
|
||||
- [ticket120-hello-plugin-recurrence-investigation-angle](ticket120-hello-plugin-recurrence-investigation-angle.md) — memory note ticket120-hello-plugin-recurrence-investigation-angle
|
||||
- [ticket120-hello-plugin-blackscreen-recurrence](ticket120-hello-plugin-blackscreen-recurrence.md) — memory note ticket120-hello-plugin-blackscreen-recurrence
|
||||
|
||||
20
.ideai/memory/ticket113-controlled-args-field-rootcause.md
Normal file
20
.ideai/memory/ticket113-controlled-args-field-rootcause.md
Normal file
@ -0,0 +1,20 @@
|
||||
---
|
||||
name: ticket113-controlled-args-field-rootcause
|
||||
description: memory note ticket113-controlled-args-field-rootcause
|
||||
metadata:
|
||||
type: project
|
||||
---
|
||||
---
|
||||
name: ticket113-controlled-args-field-rootcause
|
||||
description: Cause racine identifiée du bug ticket #113 (espaces impossibles dans le champ Arguments supplémentaires llamacpp) et niveau de fix attendu.
|
||||
metadata:
|
||||
type: project
|
||||
---
|
||||
|
||||
Root cause confirmée dans le code (2026-07-31) : `frontend/src/features/model-servers/ModelServersPanel.tsx:645-647` affiche `value={draft.args.join(" ")}` et parse via `parseArgs` (`modelServer.ts:133`, `split(/\s+/).filter(non-vide)`) à chaque `onChange`. Le state du champ est un `string[]` reconstruit en texte à chaque frappe, donc tout espace en fin de saisie ou espace double est immédiatement absorbé avant le prochain re-render : l'utilisateur ne peut jamais laisser un espace « en attente ».
|
||||
|
||||
Le même pattern existe à l'identique dans `frontend/src/features/first-run/FirstRunWizard.tsx:264` (même `parseArgs` importé depuis `first-run/profile.ts`) — probablement le même bug latent, non signalé par l'utilisateur mais à couvrir dans le même correctif.
|
||||
|
||||
**Why:** classique piège de champ contrôlé dont le state est un type dérivé (array) plutôt que la chaîne brute tapée — le round-trip parse→join efface la saisie en cours.
|
||||
|
||||
**How to apply:** le fix attendu est purement frontend/local : garder une valeur de saisie brute en state local (string) pendant la frappe, ne convertir vers `args: string[]` qu'à la sortie du champ (blur/submit), sans reconstruire `value` depuis `args.join(" ")` à chaque `onChange`. Aucun changement domaine/backend/DTO nécessaire — `args: string[]` reste le contrat de sortie inchangé.
|
||||
@ -0,0 +1,26 @@
|
||||
---
|
||||
name: ticket120-hello-plugin-blackscreen-recurrence
|
||||
description: memory note ticket120-hello-plugin-blackscreen-recurrence
|
||||
metadata:
|
||||
type: project
|
||||
---
|
||||
# Récidive écran noir hello-plugin malgré 3 fixes mergés
|
||||
|
||||
Le bug "écran noir à l'installation de hello-plugin" (#120, encore open) a déjà survécu à 3 correctifs mergés dans develop — traiter le prochain lot comme recherche de root cause, pas comme patch symptomatique de plus.
|
||||
|
||||
## Constat
|
||||
|
||||
Le ticket #120 ("Réinvestiguer l'installation de hello-plugin: écran noir / perte d'affichage IdeA") est toujours **`open`** au 2026-08-01, alors que **trois** correctifs distincts ont déjà été mergés dans `develop` sur le même symptôme :
|
||||
|
||||
1. `fix/ticket116-plugin-install-black-screen` → mergé `f6685aa` (ticket #116, closed) — "isoler crash plugin hello-plugin + erreur explicite UI"
|
||||
2. `feature/hello-plugin-manifest-fix-and-fixture-tests` → mergé `6270f98` — "aligne le manifeste hello-plugin sur le schéma backend + fixture de test"
|
||||
3. `feature/ticket120-hello-plugin-blackscreen-reinvestigation` → mergé `e741f76` (aujourd'hui) — "isolation plugin invalide + réconciliation MCP durcie + loader export default/cleanup"
|
||||
|
||||
Et le bug revient une 4e fois, ce qui a motivé la relance de #120 le 2026-08-01 sur la branche `feature/ticket120-hello-plugin-blackscreen-crash-diagnostics`.
|
||||
|
||||
**Why** : chaque fix précédent a visiblement traité un symptôme observable (crash isolation, manifeste, réconciliation MCP, loader export) sans que la cause racine soit couverte — sinon le bug ne reviendrait pas. Fermer #120 à chaque merge sans validation e2e réelle post-merge semble être le trou du cycle.
|
||||
|
||||
**How to apply** :
|
||||
- Avant tout nouveau fix sur ce symptôme, lire l'historique des 3 tentatives ci-dessus pour ne pas répéter une piste déjà explorée et retombée.
|
||||
- Ne pas fermer #120 au merge — seulement après validation réelle de l'installation du plugin de bout en bout (voir [[git-owns-commit-merge-decisions]] pour la règle générale de non-merge sans tests verts, qui s'applique ici avec une vigilance renforcée).
|
||||
- La dette de diagnostic crash/logs est traitée dans le même lot que ce 4e essai (branche `feature/ticket120-hello-plugin-blackscreen-crash-diagnostics`), précisément pour éviter un 5e patch aveugle.
|
||||
@ -0,0 +1,18 @@
|
||||
---
|
||||
name: ticket120-hello-plugin-recurrence-investigation-angle
|
||||
description: memory note ticket120-hello-plugin-recurrence-investigation-angle
|
||||
metadata:
|
||||
type: project
|
||||
---
|
||||
---
|
||||
name: ticket120-hello-plugin-recurrence-investigation-angle
|
||||
description: Angle d'investigation pour le ticket #120 (récidive du black screen hello-plugin après 3 vagues de correctifs sur #116 et antérieurs) — la cause probable est en amont de la couche déjà blindée.
|
||||
metadata:
|
||||
type: project
|
||||
---
|
||||
|
||||
Historique des correctifs déjà appliqués au symptôme « installer hello-plugin fait perdre l'affichage IdeA » : `fe5fe7c` (crash asset protocol Tauri), `aa85037`/`c100a03` (isolation des contributions plugin en erreur + durcissement `menus.ts`), `d4e61a8`/`f6685aa` (ticket #116, fermé). Constat utilisateur live au 2026-07-31 (ticket #120) : le black screen est **toujours observé** malgré ces trois vagues.
|
||||
|
||||
**Why:** trois correctifs successifs ciblant tous la couche « rendu des contributions plugin déjà chargées » sans faire disparaître le symptôme est un signal fort que la cause racine réelle est ailleurs — probablement en amont (flux d'installation backend : validation manifeste, copie assets, écriture manifeste projet — un panic/erreur non catché ici peut tuer le process Tauri entier, ce qu'aucune isolation frontend ne peut rattraper) ou dans le remount/reload post-install côté frontend, pas dans le rendu des contributions lui-même qui a déjà été isolé trois fois.
|
||||
|
||||
**How to apply:** pour #120, prioriser l'audit du chemin d'installation backend et de la frontière install→reload frontend AVANT de retoucher l'isolation des contributions (déjà traitée). Reproduire dans l'AppImage réellement rebuild (pas `pnpm dev`), pas seulement en dev — voir [[mcp-bridge-and-delegation-runtime-notes]] sur le piège du binaire qui tourne. Ne pas re-fermer le ticket sans preuve live post-fix dans le binaire réel, comme #116 l'a probablement fait à tort.
|
||||
@ -0,0 +1,41 @@
|
||||
---
|
||||
name: ux-ai-profiles-opencode-persistence-list-coherence
|
||||
description: memory note ux-ai-profiles-opencode-persistence-list-coherence
|
||||
metadata:
|
||||
type: project
|
||||
---
|
||||
---
|
||||
title: UX — Cohérence profils IA/OpenCode entre éditeur et picker agents
|
||||
type: decision
|
||||
description: Décisions de surface pour corriger la création de profils OpenCode, la persistance visible après sauvegarde et la cohérence entre Settings > Profils IA et les sélecteurs d'agents.
|
||||
---
|
||||
|
||||
# UX — Profils IA/OpenCode : création, persistance, liste unique
|
||||
|
||||
## Décision centrale
|
||||
La liste visible dans `Settings > Profils IA` et les pickers de profils des agents doit représenter la même collection persistée de profils IA. Les profils de référence ne sont qu'une source d'ajout, pas une deuxième vérité visible.
|
||||
|
||||
## Comportement attendu
|
||||
- Le bouton de création OpenCode s'appelle `Créer un profil OpenCode` dans la surface française.
|
||||
- Cliquer sur ce bouton ajoute immédiatement une ligne de profil en brouillon, sélectionnée, éditable et clairement marquée non enregistrée tant que la sauvegarde n'a pas réussi.
|
||||
- Chaque nouveau profil OpenCode doit avoir une identité distincte et un nom humain distinct par défaut, par exemple `OpenCode local 2`; l'utilisateur peut renommer avant sauvegarde.
|
||||
- `Dupliquer` conserve la configuration du profil source mais crée une nouvelle identité et un nom suffixé, par exemple `(copie)`.
|
||||
- `Enregistrer` persiste tous les profils sélectionnés/édités, puis recharge la liste depuis la source persistée. La liste affichée après succès doit être le résultat relu, pas seulement l'état local optimiste.
|
||||
- Après sauvegarde réussie, le profil créé reste visible dans l'éditeur sans réouverture manuelle et apparaît dans le picker de création d'agent et dans le picker de changement de profil d'un agent existant.
|
||||
- Les profils OpenCode ne doivent jamais être fusionnés/dédupliqués par commande, modèle, endpoint ou adapter. La déduplication visible se fait uniquement par `id`.
|
||||
- En mode édition, les profils déjà configurés apparaissent en premier, pré-sélectionnés, avec leur configuration réelle intacte. Les profils de référence non configurés peuvent suivre comme suggestions non sélectionnées.
|
||||
- Si un profil référencé par un agent n'existe plus dans la liste persistée, le picker de l'agent conserve l'id courant comme option orpheline lisible, sans le mélanger aux profils disponibles.
|
||||
|
||||
## États et feedback
|
||||
- Pendant la création/clonage : bouton désactivé ou loading local, sans bloquer la détection CLI.
|
||||
- Ligne brouillon : indicateur discret `Non enregistré` ou état visuel équivalent.
|
||||
- Sauvegarde réussie : statut court `Profils enregistrés` puis disparition automatique.
|
||||
- Échec sauvegarde : message d'erreur persistant, la ligne brouillon reste éditable et n'est pas perdue.
|
||||
- Picker agents vide : ne pas encourager la saisie libre d'id comme chemin normal. Afficher plutôt un état vide actionnable vers `Profils IA`.
|
||||
|
||||
## Critères d'acceptation visuels
|
||||
- Créer un profil OpenCode, sauvegarder, rester sur Settings : le profil est toujours visible après le retour succès.
|
||||
- Sans fermer Settings, ouvrir/créer un agent : le même profil est disponible dans le picker.
|
||||
- Deux profils OpenCode avec même endpoint/modèle mais ids distincts restent deux lignes et deux options distinctes.
|
||||
- Renommer un profil puis sauvegarder met à jour le libellé dans l'éditeur et dans les pickers agents.
|
||||
- Aucun écran ne montre simultanément une liste issue seulement des références et une liste issue des profils persistés comme si elles étaient équivalentes.
|
||||
29
.ideai/tickets/1/carnet.md
Normal file
29
.ideai/tickets/1/carnet.md
Normal file
@ -0,0 +1,29 @@
|
||||
---
|
||||
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.
|
||||
24
.ideai/tickets/1/issue.md
Normal file
24
.ideai/tickets/1/issue.md
Normal file
@ -0,0 +1,24 @@
|
||||
---
|
||||
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).
|
||||
6
.ideai/tickets/10/carnet.md
Normal file
6
.ideai/tickets/10/carnet.md
Normal file
@ -0,0 +1,6 @@
|
||||
---
|
||||
issueRef: "#10"
|
||||
version: 5
|
||||
updatedBy: {"kind":"agent","agent_id":"a6ced819-b893-4213-b003-9e9dc79b9641"}
|
||||
updatedAt: 1783241883970
|
||||
---
|
||||
15
.ideai/tickets/10/issue.md
Normal file
15
.ideai/tickets/10/issue.md
Normal file
@ -0,0 +1,15 @@
|
||||
---
|
||||
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)
|
||||
6
.ideai/tickets/100/carnet.md
Normal file
6
.ideai/tickets/100/carnet.md
Normal file
@ -0,0 +1,6 @@
|
||||
---
|
||||
issueRef: "#100"
|
||||
version: 3
|
||||
updatedBy: {"kind":"user"}
|
||||
updatedAt: 1784993984569
|
||||
---
|
||||
16
.ideai/tickets/100/issue.md
Normal file
16
.ideai/tickets/100/issue.md
Normal file
@ -0,0 +1,16 @@
|
||||
---
|
||||
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.
|
||||
96
.ideai/tickets/101/carnet.md
Normal file
96
.ideai/tickets/101/carnet.md
Normal file
@ -0,0 +1,96 @@
|
||||
---
|
||||
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).
|
||||
16
.ideai/tickets/101/issue.md
Normal file
16
.ideai/tickets/101/issue.md
Normal file
@ -0,0 +1,16 @@
|
||||
---
|
||||
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)
|
||||
6
.ideai/tickets/102/carnet.md
Normal file
6
.ideai/tickets/102/carnet.md
Normal file
@ -0,0 +1,6 @@
|
||||
---
|
||||
issueRef: "#102"
|
||||
version: 4
|
||||
updatedBy: {"kind":"user"}
|
||||
updatedAt: 1784993980505
|
||||
---
|
||||
16
.ideai/tickets/102/issue.md
Normal file
16
.ideai/tickets/102/issue.md
Normal file
@ -0,0 +1,16 @@
|
||||
---
|
||||
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
|
||||
99
.ideai/tickets/103/carnet.md
Normal file
99
.ideai/tickets/103/carnet.md
Normal file
@ -0,0 +1,99 @@
|
||||
---
|
||||
issueRef: "#103"
|
||||
version: 5
|
||||
updatedBy: {"kind":"user"}
|
||||
updatedAt: 1785271085635
|
||||
---
|
||||
# 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.
|
||||
39
.ideai/tickets/103/issue.md
Normal file
39
.ideai/tickets/103/issue.md
Normal file
@ -0,0 +1,39 @@
|
||||
---
|
||||
id: "3d9021da-26c3-439d-9463-8d206bd06f1b"
|
||||
number: 103
|
||||
title: "Exposer et piloter la permission réseau des agents/commandes dans IdeA"
|
||||
status: "closed"
|
||||
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":"user"}
|
||||
createdAt: 1785011668081
|
||||
updatedAt: 1785271085635
|
||||
version: 5
|
||||
---
|
||||
## 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.
|
||||
6
.ideai/tickets/107/carnet.md
Normal file
6
.ideai/tickets/107/carnet.md
Normal file
@ -0,0 +1,6 @@
|
||||
---
|
||||
issueRef: "#107"
|
||||
version: 4
|
||||
updatedBy: {"kind":"user"}
|
||||
updatedAt: 1785271098557
|
||||
---
|
||||
17
.ideai/tickets/107/issue.md
Normal file
17
.ideai/tickets/107/issue.md
Normal file
@ -0,0 +1,17 @@
|
||||
---
|
||||
id: "6a79006b-0201-4176-ae54-39a05cc3baa6"
|
||||
number: 107
|
||||
title: "[Bug] croisement entre les projet des retours des agents"
|
||||
status: "closed"
|
||||
priority: "critical"
|
||||
sprint: null
|
||||
links: []
|
||||
agentRefs: [{"agentId":"a6ced819-b893-4213-b003-9e9dc79b9641","role":"assigned"}]
|
||||
createdBy: {"kind":"user"}
|
||||
updatedBy: {"kind":"user"}
|
||||
createdAt: 1785136727824
|
||||
updatedAt: 1785271098557
|
||||
version: 4
|
||||
---
|
||||
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.
|
||||
6
.ideai/tickets/108/carnet.md
Normal file
6
.ideai/tickets/108/carnet.md
Normal file
@ -0,0 +1,6 @@
|
||||
---
|
||||
issueRef: "#108"
|
||||
version: 3
|
||||
updatedBy: {"kind":"user"}
|
||||
updatedAt: 1785328001206
|
||||
---
|
||||
17
.ideai/tickets/108/issue.md
Normal file
17
.ideai/tickets/108/issue.md
Normal file
@ -0,0 +1,17 @@
|
||||
---
|
||||
id: "d5953745-406f-406f-9008-916de0527cbf"
|
||||
number: 108
|
||||
title: "Ajouter la possibilité de joindre des fichiers aux tickets"
|
||||
status: "closed"
|
||||
priority: "medium"
|
||||
sprint: null
|
||||
links: []
|
||||
agentRefs: []
|
||||
attachments: []
|
||||
createdBy: {"kind":"user"}
|
||||
updatedBy: {"kind":"user"}
|
||||
createdAt: 1785311525586
|
||||
updatedAt: 1785328001206
|
||||
version: 3
|
||||
---
|
||||
J'aimerais pouvoir ajouter des fichiers (photo, texte, xml etc...) lisible par les agents AI a mes tickets. Dans le cas ou un fichier a déjà été traité par un agent, il faudrait que le fichier soit résumé dans le carnet et flag par les agents de façon a ce que si plusieurs agents lisent le même tickets, ils ne grillent pas tous leurs tokens a lire le fichier
|
||||
6
.ideai/tickets/109/carnet.md
Normal file
6
.ideai/tickets/109/carnet.md
Normal file
@ -0,0 +1,6 @@
|
||||
---
|
||||
issueRef: "#109"
|
||||
version: 4
|
||||
updatedBy: {"kind":"user"}
|
||||
updatedAt: 1785328001167
|
||||
---
|
||||
17
.ideai/tickets/109/issue.md
Normal file
17
.ideai/tickets/109/issue.md
Normal file
@ -0,0 +1,17 @@
|
||||
---
|
||||
id: "1c6440f1-806f-41e4-92c9-6cef30d3023e"
|
||||
number: 109
|
||||
title: "Ajouter le nom du créateur de ticket"
|
||||
status: "closed"
|
||||
priority: "medium"
|
||||
sprint: null
|
||||
links: []
|
||||
agentRefs: []
|
||||
attachments: []
|
||||
createdBy: {"kind":"user"}
|
||||
updatedBy: {"kind":"user"}
|
||||
createdAt: 1785311822279
|
||||
updatedAt: 1785328001167
|
||||
version: 4
|
||||
---
|
||||
J'aiemrais que le nom de celui qui a créé le ticket soit ajouté au ticket (nom de l'agent agent ou utilisateur). et qu'un filtre soit ajouté dans la liste des tickets
|
||||
6
.ideai/tickets/11/carnet.md
Normal file
6
.ideai/tickets/11/carnet.md
Normal file
@ -0,0 +1,6 @@
|
||||
---
|
||||
issueRef: "#11"
|
||||
version: 6
|
||||
updatedBy: {"kind":"agent","agent_id":"a6ced819-b893-4213-b003-9e9dc79b9641"}
|
||||
updatedAt: 1783278726067
|
||||
---
|
||||
15
.ideai/tickets/11/issue.md
Normal file
15
.ideai/tickets/11/issue.md
Normal file
@ -0,0 +1,15 @@
|
||||
---
|
||||
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
|
||||
6
.ideai/tickets/112/carnet.md
Normal file
6
.ideai/tickets/112/carnet.md
Normal file
@ -0,0 +1,6 @@
|
||||
---
|
||||
issueRef: "#112"
|
||||
version: 4
|
||||
updatedBy: {"kind":"user"}
|
||||
updatedAt: 1785341341049
|
||||
---
|
||||
17
.ideai/tickets/112/issue.md
Normal file
17
.ideai/tickets/112/issue.md
Normal file
@ -0,0 +1,17 @@
|
||||
---
|
||||
id: "ff8e11d1-98f8-4c6c-b5d0-a8a087c1dbbc"
|
||||
number: 112
|
||||
title: "Pouvoir ajouter plusieurs tickets a la fois a un sprint"
|
||||
status: "closed"
|
||||
priority: "medium"
|
||||
sprint: null
|
||||
links: []
|
||||
agentRefs: [{"agentId":"a6ced819-b893-4213-b003-9e9dc79b9641","role":"assigned"}]
|
||||
attachments: []
|
||||
createdBy: {"kind":"user"}
|
||||
updatedBy: {"kind":"user"}
|
||||
createdAt: 1785332192429
|
||||
updatedAt: 1785341341049
|
||||
version: 4
|
||||
---
|
||||
Je veux qu'on ajoute la possibilité de set le sprint des tickets selectionnés grace a la selection multiple de ticket dans la liste des tickets.
|
||||
6
.ideai/tickets/113/carnet.md
Normal file
6
.ideai/tickets/113/carnet.md
Normal file
@ -0,0 +1,6 @@
|
||||
---
|
||||
issueRef: "#113"
|
||||
version: 4
|
||||
updatedBy: {"kind":"user"}
|
||||
updatedAt: 1785395935541
|
||||
---
|
||||
17
.ideai/tickets/113/issue.md
Normal file
17
.ideai/tickets/113/issue.md
Normal file
@ -0,0 +1,17 @@
|
||||
---
|
||||
id: "1c128e50-96bd-4689-a080-f6b5e0c5a6b6"
|
||||
number: 113
|
||||
title: "[Bug] Les espaces ne epuvent pas etre entrés dans les args du serveur llamacpp"
|
||||
status: "open"
|
||||
priority: "medium"
|
||||
sprint: "e28a4d53-8bd2-446a-b0ac-2a017373b8b2"
|
||||
links: []
|
||||
agentRefs: [{"agentId":"a6ced819-b893-4213-b003-9e9dc79b9641","role":"assigned"}]
|
||||
attachments: []
|
||||
createdBy: {"kind":"user"}
|
||||
updatedBy: {"kind":"user"}
|
||||
createdAt: 1785395710201
|
||||
updatedAt: 1785395935541
|
||||
version: 4
|
||||
---
|
||||
Dnas les option de reglage llama.cpp de l'edition des serveurs locaux de modele llm, je ne peux pas entrer d'espaces dans le champs de texte Arguments supplémentaires. Il faut faire en sorte que ça soit possible
|
||||
6
.ideai/tickets/114/carnet.md
Normal file
6
.ideai/tickets/114/carnet.md
Normal file
@ -0,0 +1,6 @@
|
||||
---
|
||||
issueRef: "#114"
|
||||
version: 5
|
||||
updatedBy: {"kind":"user"}
|
||||
updatedAt: 1785509526119
|
||||
---
|
||||
17
.ideai/tickets/114/issue.md
Normal file
17
.ideai/tickets/114/issue.md
Normal file
@ -0,0 +1,17 @@
|
||||
---
|
||||
id: "a7602792-21c6-40f3-852a-5200d604db9d"
|
||||
number: 114
|
||||
title: "[UI] un iformiser les droplist"
|
||||
status: "closed"
|
||||
priority: "medium"
|
||||
sprint: "5afd6780-0f76-40d7-a10f-32ee52469d74"
|
||||
links: []
|
||||
agentRefs: [{"agentId":"a6ced819-b893-4213-b003-9e9dc79b9641","role":"assigned"}]
|
||||
attachments: []
|
||||
createdBy: {"kind":"user"}
|
||||
updatedBy: {"kind":"user"}
|
||||
createdAt: 1785395791597
|
||||
updatedAt: 1785509526119
|
||||
version: 5
|
||||
---
|
||||
Dans les différentes fenetres j'aimerais qu'on uniformise les droplist. C'est a dire que par exemple dans la fenetre de création de ticket, on a une droplist noire pour la selection d'un agent à lier, j'aimerais que ça soit la même droplist pour la selection du modele dans la fenetre des agents, dans la selection du template a la création d'un agent etc. Que toutes ces petites droplist dynamiques soient comme celle de selection de l'agent dans la fenetre de creation de tickets
|
||||
6
.ideai/tickets/115/carnet.md
Normal file
6
.ideai/tickets/115/carnet.md
Normal file
@ -0,0 +1,6 @@
|
||||
---
|
||||
issueRef: "#115"
|
||||
version: 3
|
||||
updatedBy: {"kind":"agent","agent_id":"cd0b4cf1-1bef-4fae-ade5-f0a6b49bbaf5"}
|
||||
updatedAt: 1785499018589
|
||||
---
|
||||
44
.ideai/tickets/115/issue.md
Normal file
44
.ideai/tickets/115/issue.md
Normal file
@ -0,0 +1,44 @@
|
||||
---
|
||||
id: "e5db2ff6-64c6-4aaa-a070-67f6904bd7eb"
|
||||
number: 115
|
||||
title: "Rendre visibles les skills IdeA assignés dans le contexte effectif de chaque agent"
|
||||
status: "closed"
|
||||
priority: "high"
|
||||
sprint: null
|
||||
links: []
|
||||
agentRefs: []
|
||||
attachments: []
|
||||
createdBy: {"kind":"agent","agent_id":"a6ced819-b893-4213-b003-9e9dc79b9641"}
|
||||
updatedBy: {"kind":"agent","agent_id":"cd0b4cf1-1bef-4fae-ade5-f0a6b49bbaf5"}
|
||||
createdAt: 1785497413891
|
||||
updatedAt: 1785499018589
|
||||
version: 3
|
||||
---
|
||||
Constat: les agents n'utilisent pas les skills IdeA parce qu'ils n'ont pas connaissance, au runtime, de la liste des skills qu'IdeA leur met à disposition.
|
||||
|
||||
Objectif:
|
||||
Faire en sorte que, quel que soit l'agent/profil, la liste des skills IdeA assignés soit correctement visible et exploitable par le modèle.
|
||||
|
||||
Attendu produit/architecture:
|
||||
- La liste des skills assignés doit être traitée comme un artefact d'orchestration/capability snapshot, pas comme du texte documentaire passif.
|
||||
- Source de vérité unique côté orchestrateur: catalogue réel des skills + règles d'assignation par agent.
|
||||
- Injection systématique de cette liste dans le contexte effectif/prompt livré au modèle:
|
||||
- au lancement
|
||||
- à la reprise
|
||||
- au handoff/changement de profil
|
||||
- idéalement à chaque reconstruction de contexte/tour
|
||||
- Format injecté court, stable, structuré et provider-agnostic, avec version de snapshot/catalogue.
|
||||
- Règles injectées explicitement: utiliser un skill listé quand la demande y correspond, lire son détail via idea_skill_read(name=...).
|
||||
- Fallback runtime si la liste change: soit mécanisme de refresh orchestrateur, soit endpoint/outillage canonique de relecture de la liste assignée.
|
||||
|
||||
Invariants à garantir:
|
||||
- ne jamais annoncer un skill non réellement accessible
|
||||
- ne jamais omettre un skill réellement assigné
|
||||
- aucun agent ne commence un tour sans snapshot de skills cohérent avec l'état orchestrateur
|
||||
- comportement homogène quel que soit le provider/profil
|
||||
- snapshot versionné et traçable
|
||||
|
||||
Critères de validation:
|
||||
- pour un agent ayant des skills assignés, la liste apparaît bien dans le contexte effectif vu par le modèle
|
||||
- l'agent peut citer/consommer un skill assigné sans connaissance préalable externe
|
||||
- un changement d'assignation est reflété sans dérive durable entre orchestrateur et agent
|
||||
6
.ideai/tickets/116/carnet.md
Normal file
6
.ideai/tickets/116/carnet.md
Normal file
@ -0,0 +1,6 @@
|
||||
---
|
||||
issueRef: "#116"
|
||||
version: 2
|
||||
updatedBy: {"kind":"agent","agent_id":"cd0b4cf1-1bef-4fae-ade5-f0a6b49bbaf5"}
|
||||
updatedAt: 1785500328024
|
||||
---
|
||||
39
.ideai/tickets/116/issue.md
Normal file
39
.ideai/tickets/116/issue.md
Normal file
@ -0,0 +1,39 @@
|
||||
---
|
||||
id: "0a38f0bc-e4c0-4e31-b682-738367463989"
|
||||
number: 116
|
||||
title: "Installer hello-plugin provoque un écran noir / crash apparent d'IdeA"
|
||||
status: "closed"
|
||||
priority: "critical"
|
||||
sprint: null
|
||||
links: []
|
||||
agentRefs: []
|
||||
attachments: []
|
||||
createdBy: {"kind":"agent","agent_id":"a6ced819-b893-4213-b003-9e9dc79b9641"}
|
||||
updatedBy: {"kind":"agent","agent_id":"cd0b4cf1-1bef-4fae-ade5-f0a6b49bbaf5"}
|
||||
createdAt: 1785499247761
|
||||
updatedAt: 1785500328024
|
||||
version: 2
|
||||
---
|
||||
Constat utilisateur au 2026-07-31 : lors de l'installation du plugin de démonstration `hello-plugin`, IdeA affiche encore un écran noir, ce qui laisse supposer un crash du runtime/fenêtre.
|
||||
|
||||
Contexte utile déjà observé :
|
||||
- des correctifs précédents existent autour de `hello-plugin` et du runtime plugin, notamment :
|
||||
- `fe5fe7c` : `fix(hello-plugin): prévient le crash de l'asset protocol dans le runtime Tauri`
|
||||
- `aa85037` / `c100a03` : isolation des contributions plugin en erreur + durcissement menus
|
||||
- `2c3a46e` / `6270f98` : corrections manifeste/contexte hello-plugin
|
||||
- malgré cela, l'installation du plugin déclenche encore un écran noir côté utilisateur.
|
||||
|
||||
Objectif :
|
||||
Identifier la cause racine exacte du black screen au moment de l'installation/chargement de `hello-plugin`, corriger le défaut, et garantir qu'un plugin défectueux ou mal chargé ne puisse plus faire tomber la fenêtre principale d'IdeA.
|
||||
|
||||
Attendu :
|
||||
- reproduire le problème sur le flux réel d'installation du plugin
|
||||
- localiser la couche fautive (installation, validation, asset protocol, chargement frontend, runtime contributions, rendu UI, Tauri)
|
||||
- corriger la cause racine
|
||||
- ajouter des tests de non-régression sur le chemin réel concerné
|
||||
- si un plugin reste invalide/non chargeable, l'UI doit rester vivante avec un état d'erreur explicite, pas un écran noir
|
||||
|
||||
Critères de validation :
|
||||
- installation réelle de `hello-plugin` sans écran noir ni crash apparent
|
||||
- IdeA reste interactive même si le plugin échoue à se charger
|
||||
- tests pertinents verts avec preuve réelle
|
||||
6
.ideai/tickets/117/carnet.md
Normal file
6
.ideai/tickets/117/carnet.md
Normal file
@ -0,0 +1,6 @@
|
||||
---
|
||||
issueRef: "#117"
|
||||
version: 7
|
||||
updatedBy: {"kind":"agent","agent_id":"cd0b4cf1-1bef-4fae-ade5-f0a6b49bbaf5"}
|
||||
updatedAt: 1785503128343
|
||||
---
|
||||
51
.ideai/tickets/117/issue.md
Normal file
51
.ideai/tickets/117/issue.md
Normal file
@ -0,0 +1,51 @@
|
||||
---
|
||||
id: "66e80f94-780b-4856-806d-ba4b96673630"
|
||||
number: 117
|
||||
title: "Garantir la synchronie métier de idea_ask_agent malgré les background tasks"
|
||||
status: "closed"
|
||||
priority: "high"
|
||||
sprint: null
|
||||
links: []
|
||||
agentRefs: [{"agentId":"a6ced819-b893-4213-b003-9e9dc79b9641","role":"assigned"}]
|
||||
attachments: []
|
||||
createdBy: {"kind":"user"}
|
||||
updatedBy: {"kind":"agent","agent_id":"cd0b4cf1-1bef-4fae-ade5-f0a6b49bbaf5"}
|
||||
createdAt: 1785500280516
|
||||
updatedAt: 1785503128343
|
||||
version: 7
|
||||
---
|
||||
Constat : quand un agent `A` délègue une demande à un agent `B` via `idea_ask_agent`, `B` peut lancer une background task puis terminer son tour avant que cette tâche ne finisse. Dans ce cas, `A` peut recevoir une pseudo-réponse terminale trop tôt, alors que le travail réel n'est pas terminé.
|
||||
|
||||
Décision produit validée : `idea_ask_agent` doit rester synchrone d'un point de vue métier.
|
||||
|
||||
Cela implique :
|
||||
- `A` ne doit jamais recevoir comme réponse métier finale un simple "task lancée" si le résultat utile dépend encore d'une background task.
|
||||
- si `B` a besoin d'une background task pour produire sa réponse, la délégation `A -> B` reste ouverte.
|
||||
- la background task est une étape interne du traitement de `B`, pas une réponse à `A`.
|
||||
- à la fin de la task, IdeA réveille `B`, puis `B` rend la vraie réponse finale.
|
||||
- `A` reste en attente du rendez-vous logique, même si techniquement le tour initial de `B` s'est terminé.
|
||||
|
||||
Objectif :
|
||||
Faire en sorte qu'une background task lancée pendant un `idea_ask_agent` soit corrélée au rendez-vous inter-agent en cours, et que ce rendez-vous reste ouvert jusqu'à la réponse finale métier de `B`.
|
||||
|
||||
Invariants à garantir :
|
||||
- `idea_ask_agent` ne se termine jamais par "task lancée" si le résultat utile dépend encore d'une background task.
|
||||
- toute background task lancée pendant une délégation porte la corrélation du rendez-vous source.
|
||||
- la complétion de task réveille `B`, pas `A` directement.
|
||||
- `B` transforme ensuite le résultat en vraie réponse finale à `A`.
|
||||
- la réponse capturée pour `A` n'est émise qu'après clôture logique du travail.
|
||||
- reboot, cancel, timeout et échec de task ne doivent pas casser cette corrélation.
|
||||
|
||||
Découpage attendu :
|
||||
1. Étendre le modèle de corrélation pour rattacher une background task à un rendez-vous délégué.
|
||||
2. Introduire un état explicite de rendez-vous du type `WaitingOnBackgroundTask` ou équivalent.
|
||||
3. Empêcher la clôture terminale d'un `idea_ask_agent` tant qu'une task corrélée est encore ouverte.
|
||||
4. À la complétion, réveiller `B`, injecter le résultat dans son inbox, puis laisser `B` répondre à `A`.
|
||||
5. Ajouter les tests de reprise après reboot, timeout, cancel et double complétion.
|
||||
|
||||
Critères de validation :
|
||||
- `A` délègue à `B`, `B` lance une task longue, `A` n'obtient pas de faux terminal.
|
||||
- à la fin de la task, `B` est réveillé et répond finalement à `A`.
|
||||
- après redémarrage, la réponse finale revient encore à `A`.
|
||||
- échec ou annulation de task produisent une réponse terminale cohérente côté `A`.
|
||||
- aucune complétion ne reste orpheline hors du rendez-vous initial.
|
||||
6
.ideai/tickets/119/carnet.md
Normal file
6
.ideai/tickets/119/carnet.md
Normal file
@ -0,0 +1,6 @@
|
||||
---
|
||||
issueRef: "#119"
|
||||
version: 2
|
||||
updatedBy: {"kind":"agent","agent_id":"a6ced819-b893-4213-b003-9e9dc79b9641"}
|
||||
updatedAt: 1785536553069
|
||||
---
|
||||
134
.ideai/tickets/119/issue.md
Normal file
134
.ideai/tickets/119/issue.md
Normal file
@ -0,0 +1,134 @@
|
||||
---
|
||||
id: "b76431d7-f3a3-438f-ae3f-5648f5eda8ce"
|
||||
number: 119
|
||||
title: "Refondre le système de skills IdeA en capacités agent découvrables"
|
||||
status: "inProgress"
|
||||
priority: "high"
|
||||
sprint: null
|
||||
links: []
|
||||
agentRefs: []
|
||||
attachments: []
|
||||
createdBy: {"kind":"agent","agent_id":"a6ced819-b893-4213-b003-9e9dc79b9641"}
|
||||
updatedBy: {"kind":"agent","agent_id":"a6ced819-b893-4213-b003-9e9dc79b9641"}
|
||||
createdAt: 1785534242629
|
||||
updatedAt: 1785536553069
|
||||
version: 2
|
||||
---
|
||||
## Constat
|
||||
|
||||
Le système actuel de skills IdeA est techniquement fonctionnel, mais conceptuellement centré sur l'injection de contenu plutôt que sur l'exposition de capacités agent.
|
||||
|
||||
État actuel confirmé dans le code :
|
||||
- `Skill` + `SkillRef` avec deux scopes `global` / `project`.
|
||||
- assignation des skills sur les agents via le manifeste.
|
||||
- résolution au lancement, puis composition du contexte effectif.
|
||||
- en mode MCP : bloc `# Skills disponibles` + lazy-load via `idea_skill_read(name)`.
|
||||
- en mode non-MCP : dump complet du corps des skills dans le contexte.
|
||||
- `idea_list_agents` retourne la forme `Agent` du manifeste, donc seulement des `SkillRef` bruts (`skillId` + `scope`), pas un inventaire de capacités utile à un agent ou à Main.
|
||||
|
||||
Le défaut de fond est que le catalogue de skills n'existe pas comme objet métier interrogeable. Il n'existe qu'au moment du rendu markdown dans `compose_convention_file`. Le système se comporte donc comme un mécanisme d'injection de documentation, puis simule partiellement une surface de capacités en mode MCP.
|
||||
|
||||
## Problèmes à résoudre
|
||||
|
||||
1. Les skills assignés ne sont pas modélisés comme un inventaire de capacités agent de premier ordre.
|
||||
2. `idea_list_agents` ne permet pas de savoir ce que les autres agents savent faire, seulement quels `SkillRef` opaques leur sont assignés.
|
||||
3. L'asymétrie MCP / non-MCP est un patch : mode MCP = affordances bornées, mode non-MCP = dump lourd.
|
||||
4. Le système ne distingue pas explicitement un skill procédural (`workflow`) d'un skill de référence (`reference`).
|
||||
5. Le modèle actuel n'est pas pleinement aligné avec la frontière produit déjà actée : surface AGENT bornée/distillée/pointeur ; surface HUMAINE riche.
|
||||
|
||||
## Cible produit / architecture
|
||||
|
||||
Faire évoluer les skills IdeA d'un modèle "contenu injecté" vers un modèle "capacités agent assignées et découvrables".
|
||||
|
||||
### Décisions cibles
|
||||
|
||||
- Garder :
|
||||
- l'entité `Skill`.
|
||||
- les scopes `global` / `project`.
|
||||
- `SkillRef` dans le manifeste agent.
|
||||
- `idea_skill_read(name)` comme primitive de lazy-load autorisée uniquement sur les skills assignés au requester.
|
||||
|
||||
- Ajouter :
|
||||
- une nature explicite de skill, par exemple `SkillKind` avec au minimum :
|
||||
- `Workflow` : procédure exécutable à la demande.
|
||||
- `Reference` : savoir consultable, plus proche d'un contexte sélectif.
|
||||
|
||||
- Extraire un use case applicatif réutilisable, type :
|
||||
- `ResolveAgentCapabilities(agent) -> [{ name, description, kind }]`
|
||||
|
||||
Ce use case devient la source de vérité commune pour :
|
||||
- le bloc `# Skills disponibles` injecté dans le contexte agent.
|
||||
- l'exposition des capacités d'un agent dans les surfaces de découverte.
|
||||
|
||||
### Arbitrages
|
||||
|
||||
- Ne pas créer de `idea_list_skills` global.
|
||||
- Les skills ne sont pas des tools MCP uniformes de session.
|
||||
- Ce sont des capacités portées par un agent.
|
||||
- La bonne surface de découverte inter-agent est donc `idea_list_agents` enrichi, pas un catalogue global détaché des porteurs.
|
||||
|
||||
- Enrichir `idea_list_agents` avec un champ additif du type :
|
||||
- `capabilities: [{ name, description, kind }]`
|
||||
|
||||
- Supprimer à terme le dump complet des corps de skills en mode non-MCP.
|
||||
- Le remplacer par une surface bornée et homogène avec le mode MCP : catalogue compact + lecture à la demande via la surface adaptée au runtime.
|
||||
|
||||
- Distinguer la politique d'injection selon le type :
|
||||
- `Workflow` : jamais injecté en corps complet par défaut.
|
||||
- `Reference` : peut éventuellement être injecté de façon compacte selon des règles bornées (optionnel, à arbitrer plus tard).
|
||||
|
||||
## Frontières avec les autres surfaces IdeA
|
||||
|
||||
- Tools MCP :
|
||||
- les skills ne deviennent pas des tools MCP.
|
||||
- `idea_skill_read` reste un pont vers les skills, pas une matérialisation des skills comme tools.
|
||||
|
||||
- Contexte projet :
|
||||
- le contexte reste global au projet et commun.
|
||||
- un skill reste assignable sélectivement agent par agent.
|
||||
|
||||
- Mémoire durable :
|
||||
- la mémoire reste un savoir stabilisé écrit dynamiquement.
|
||||
- un skill reste une capacité/version de workflow éditée explicitement.
|
||||
|
||||
- Live-state :
|
||||
- aucun recouvrement fonctionnel ; pas de mélange.
|
||||
|
||||
- Templates :
|
||||
- à envisager plus tard : un template pourrait référencer des skills à assigner par défaut.
|
||||
- en revanche, un template ne doit pas dupliquer le corps des skills.
|
||||
|
||||
- Plugins :
|
||||
- hors périmètre ; ne pas confondre extension IDE humaine et capacité agent.
|
||||
|
||||
## Plan de migration incrémental
|
||||
|
||||
1. **Domaine**
|
||||
- ajouter `SkillKind` sur `Skill` avec rétrocompatibilité (`default`).
|
||||
|
||||
2. **Application**
|
||||
- extraire un use case dédié de résolution des capacités agent à partir des `SkillRef` assignés.
|
||||
|
||||
3. **Surfaces agent / orchestration**
|
||||
- faire reposer `# Skills disponibles` sur ce use case au lieu de recalculer localement pendant le rendu markdown.
|
||||
|
||||
4. **Découverte inter-agent**
|
||||
- enrichir `idea_list_agents` avec les capacités résolues de chaque agent, en gardant les `skills` bruts si nécessaire pour compatibilité.
|
||||
|
||||
5. **Unification MCP / non-MCP**
|
||||
- supprimer le dump intégral non-MCP et le remplacer par une surface bornée cohérente avec le modèle capability-first.
|
||||
|
||||
6. **Optionnel ensuite**
|
||||
- politique fine d'injection compacte pour certains skills `Reference` courts.
|
||||
|
||||
## Critères de succès
|
||||
|
||||
- Un agent neuf connaît immédiatement ses skills assignés sous forme d'affordances bornées, sans dépendre d'un dump lourd.
|
||||
- Un agent ou Main peut découvrir les capacités utiles d'un autre agent sans manipuler des `SkillRef` opaques.
|
||||
- Le système reste cohérent avec la séparation IdeA : surface agent bornée, surface humaine riche.
|
||||
- Le modèle fonctionne proprement en MCP et hors MCP, sans dégradation conceptuelle majeure.
|
||||
- `idea_skill_read` reste la primitive de lecture détaillée et d'autorisation.
|
||||
|
||||
## Notes
|
||||
|
||||
Ce ticket est un ticket de refonte/cadrage cible. Il ne demande pas de refaire le stockage ni de supprimer `idea_skill_read`. La refonte porte sur le modèle de capacité agent, la composition de contexte et les surfaces de découverte.
|
||||
6
.ideai/tickets/12/carnet.md
Normal file
6
.ideai/tickets/12/carnet.md
Normal file
@ -0,0 +1,6 @@
|
||||
---
|
||||
issueRef: "#12"
|
||||
version: 5
|
||||
updatedBy: {"kind":"agent","agent_id":"a6ced819-b893-4213-b003-9e9dc79b9641"}
|
||||
updatedAt: 1783312900907
|
||||
---
|
||||
15
.ideai/tickets/12/issue.md
Normal file
15
.ideai/tickets/12/issue.md
Normal file
@ -0,0 +1,15 @@
|
||||
---
|
||||
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
|
||||
264
.ideai/tickets/120/carnet.md
Normal file
264
.ideai/tickets/120/carnet.md
Normal file
@ -0,0 +1,264 @@
|
||||
---
|
||||
issueRef: "#120"
|
||||
version: 9
|
||||
updatedBy: {"kind":"agent","agent_id":"a6ced819-b893-4213-b003-9e9dc79b9641"}
|
||||
updatedAt: 1785600025153
|
||||
---
|
||||
---
|
||||
issueRef: "#120"
|
||||
version: 8
|
||||
updatedBy: {"kind":"agent","agent_id":"a6ced819-b893-4213-b003-9e9dc79b9641"}
|
||||
updatedAt: 1785595113109
|
||||
---
|
||||
# Carnet de suivi — hello-plugin
|
||||
|
||||
## Etat courant
|
||||
|
||||
- Ticket canonique: `#120`
|
||||
- Ticket parent historique: `#43`
|
||||
- Date de rechute confirmee: 2026-08-01
|
||||
- Statut: investigation relancee sur rechute reelle post-rebuild SDK
|
||||
- Severite: critique (l'UI d'IdeA tombe sur une erreur d'affichage lors de l'installation/chargement de `hello-plugin`)
|
||||
|
||||
## Constat central au 2026-08-01
|
||||
|
||||
Le probleme persiste meme apres reconstruction de `hello-plugin` comme plugin d'exemple 100% SDK.
|
||||
|
||||
Implication forte:
|
||||
- la cause racine est probablement dans le systeme plugin / runtime frontend / chargement UI / integration layout-menu, et non dans l'ancien exemple `hello-plugin` uniquement.
|
||||
|
||||
## Trace utilisateur fournie le 2026-08-01
|
||||
|
||||
Message visible:
|
||||
- `IdeA a rencontre une erreur d'affichage.`
|
||||
- `L'application reste ouverte. Rechargez la fenetre apres avoir copie le diagnostic si le probleme doit etre investigue.`
|
||||
|
||||
Stack affichee (trace la plus recente):
|
||||
|
||||
```text
|
||||
ST@tauri://localhost/assets/index-DxqF_K_z.js:88:33125
|
||||
wT@tauri://localhost/assets/index-DxqF_K_z.js:88:32065
|
||||
om@tauri://localhost/assets/index-DxqF_K_z.js:38:17019
|
||||
oh@tauri://localhost/assets/index-DxqF_K_z.js:40:3141
|
||||
Fb@tauri://localhost/assets/index-DxqF_K_z.js:40:39779
|
||||
SC@tauri://localhost/assets/index-DxqF_K_z.js:40:39707
|
||||
ic@tauri://localhost/assets/index-DxqF_K_z.js:40:39559
|
||||
yh@tauri://localhost/assets/index-DxqF_K_z.js:40:35923
|
||||
Bb@tauri://localhost/assets/index-DxqF_K_z.js:40:34872
|
||||
E@tauri://localhost/assets/index-DxqF_K_z.js:25:1541
|
||||
L@tauri://localhost/assets/index-DxqF_K_z.js:25:1903
|
||||
|
||||
wT@tauri://localhost/assets/index-DxqF_K_z.js:88:28284
|
||||
div
|
||||
div
|
||||
div
|
||||
MD@tauri://localhost/assets/index-DxqF_K_z.js:94:63541
|
||||
main
|
||||
div
|
||||
div
|
||||
G4@tauri://localhost/assets/index-DxqF_K_z.js:129:18726
|
||||
div
|
||||
div
|
||||
yT@tauri://localhost/assets/index-DxqF_K_z.js:88:24863
|
||||
BP@tauri://localhost/assets/index-DxqF_K_z.js:88:1862
|
||||
ez@tauri://localhost/assets/index-DxqF_K_z.js:129:31967
|
||||
mP@tauri://localhost/assets/index-DxqF_K_z.js:82:27658
|
||||
Iz@tauri://localhost/assets/index-DxqF_K_z.js:129:83720
|
||||
```
|
||||
|
||||
## Faits etablis avant cette rechute
|
||||
|
||||
- Un rebuild SDK de `hello-plugin` a ete realise pour produire un plugin d'exemple minimal mais fonctionnel.
|
||||
- Des verifications de build, packaging et tests locaux ont ete annoncees vertes par DevFrontend.
|
||||
- QA avait pu valider partiellement:
|
||||
- l'artefact SDK se reconstruit
|
||||
- le plugin s'installe cote runtime/backend
|
||||
- IdeA charge reellement le bundle plugin via `idea-plugin://.../dist/index.js`
|
||||
- QA n'avait pas pu valider de bout en bout la surface UI visible (menu `Hello Plugin`, entree `hello-plugin`, rendu `hello-world`) faute d'une session UI observable sans ambiguite.
|
||||
|
||||
## Reinterpretation apres rechute utilisateur
|
||||
|
||||
- L'absence de validation UI de bout en bout n'etait pas un detail: la rechute utilisateur montre que le crash survient bien dans le flux reel d'affichage, malgre un plugin reconstruit proprement.
|
||||
- Le signal pointe desormais plus fortement vers un probleme dans la consommation frontend des contributions plugin que vers le contenu fonctionnel du plugin lui-meme.
|
||||
|
||||
## Cadrage UX du 2026-08-01
|
||||
|
||||
- Une contribution plugin invalide ou qui plante ne doit jamais faire tomber l'app entiere.
|
||||
- Le fallback attendu est local a la surface plugin en faute:
|
||||
- menu plugin en erreur -> menus natifs seuls
|
||||
- layout plugin en erreur -> fallback local de layout indisponible
|
||||
- `INTERFACE INTERROMPUE` doit rester reserve aux crashs shell irrecoverables.
|
||||
- A terme, l'etat d'erreur plugin devrait rester visible dans la gestion des plugins plutot qu'etre seulement silencieux.
|
||||
|
||||
## Requalification Architect du 2026-08-01
|
||||
|
||||
- Fait cle: le meme hash de crash apparait avec deux plugins differents:
|
||||
- ancien hello-plugin minimal (menu + item, sans layout utile)
|
||||
- nouveau hello-plugin reconstruit via SDK (menu + item + layout)
|
||||
- Denominateur commun probable: la contribution de menu, pas le layout.
|
||||
- Zone la plus suspecte identifiee: `ProjectsView.tsx` sur l'injection de `pluginMenus` dans `<MenuBar>`.
|
||||
- Point precis: le rendu des menus plugin est consomme dans l'app-shell sans isolation locale equivalente a celle deja ajoutee pour `PluginLayoutCellView`.
|
||||
- Hypothese prioritaire: une entree de menu plugin ou son rendu dans `MenuBar` leve une erreur qui remonte jusqu'a `RootErrorBoundary`, produisant `INTERFACE INTERROMPUE`.
|
||||
- Strate touchee: frontend prioritaire, pas de nouveau chantier backend requis pour cette cause racine.
|
||||
|
||||
## Verification DevFrontend du 2026-08-01
|
||||
|
||||
- Branche verifiee: `feature/ticket120-plugin-menu-crash-isolation`
|
||||
- HEAD verifie: `5a30ec8`
|
||||
- Verdict DevFrontend: le correctif existant couvre deja la rechute prioritaire sur le chemin `ProjectsView -> usePluginMenus -> MenuBar`.
|
||||
- Aucun complement de code ajoute a ce stade.
|
||||
- Verifications executees:
|
||||
- `cd frontend && npx vitest run src/features/plugins/usePluginMenus.test.tsx src/plugins/runtime/loader.test.ts src/features/plugins/menus.test.ts` : OK (22 tests)
|
||||
- `cd frontend && npx vitest run` : OK (114 fichiers, 1046 tests)
|
||||
|
||||
## Correctif systeme plugin/UI deja porte par la branche
|
||||
|
||||
### Cause probable retenue
|
||||
Deux plugins differents declenchent le meme crash minifie apres installation. Le denominateur commun le plus probable est le chemin `ProjectsView -> usePluginMenus -> MenuBar`.
|
||||
|
||||
### Correctif applique
|
||||
- `usePluginMenus` isole defensivement la resolution/conversion des contributions plugin.
|
||||
- Si la resolution de menus ou d'items plugin throw, le hook renvoie `[]` pour la surface plugin concernee au lieu de propager l'erreur.
|
||||
- `ProjectsView` separe les menus natifs des menus enrichis par plugin.
|
||||
- `ProjectsView` rend `MenuBar` derriere une error boundary locale: si le rendu enrichi plante, fallback immediat sur les menus natifs seuls.
|
||||
- Logs ajoutes:
|
||||
- `[plugins] menu contribution rejected` avec le contexte utile quand disponible
|
||||
- `[plugins] menu render failed; using native menus only`
|
||||
|
||||
### Fichiers touches
|
||||
- `frontend/src/features/plugins/usePluginMenus.ts`
|
||||
- `frontend/src/features/plugins/usePluginMenus.test.tsx`
|
||||
- `frontend/src/features/projects/ProjectsView.tsx`
|
||||
|
||||
## Validation QA du 2026-08-01
|
||||
|
||||
- Branche validee: `feature/ticket120-plugin-menu-crash-isolation`
|
||||
- HEAD valide: `5a30ec8b9c4758602cc96e72ffd69e415422cd85`
|
||||
- Verdict QA courant: bug `INTERFACE INTERROMPUE` non reproduit par les validations reelles executees ici.
|
||||
|
||||
### Commandes executees
|
||||
- `git -C /home/anthony/Documents/Projects/IdeA rev-parse HEAD`
|
||||
- `npm --prefix /home/anthony/Documents/Projects/IdeA/sdk/IdeaSDK run package:hello-plugin`
|
||||
- `cd /home/anthony/Documents/Projects/IdeA/frontend && npx vitest run src/features/plugins/menus.test.ts src/features/plugins/usePluginMenus.test.tsx src/features/plugins/plugins.test.tsx src/plugins/runtime/loader.test.ts`
|
||||
- `cargo test -p infrastructure --test plugin_install_load -- --nocapture`
|
||||
- `cargo test -p infrastructure extracts_archive_without_path_escape -- --nocapture`
|
||||
- `cd /home/anthony/Documents/Projects/IdeA/frontend && npm run test:bundle-transport`
|
||||
- `cd /home/anthony/Documents/Projects/IdeA/crates/app-tauri && NO_STRIP=true ../../frontend/node_modules/.bin/tauri build --bundles appimage`
|
||||
|
||||
### Resultats utiles
|
||||
- archive SDK regeneree: `sdk/IdeaSDK/examples/hello-plugin/build/hello-plugin-0.1.0.zip`
|
||||
- tests frontend cibles: OK (4 fichiers, 29 tests)
|
||||
- tests backend d'installation/chargement plugin: OK (3 tests)
|
||||
- AppImage rebuild: `target/release/bundle/appimage/IdeA_0.3.0_amd64.AppImage`
|
||||
|
||||
### Limite de preuve restante
|
||||
- Pas de harness e2e UI automatise ici pour cliquer le parcours Tauri/AppImage "Installer depuis une archive..." de bout en bout.
|
||||
- La validation est donc reelle sur archive SDK, backend d'installation, non-regression frontend, et artefact packagé reconstruit, mais pas sur un clic UI automatise observable.
|
||||
|
||||
## Requalification Architect du 2026-08-01 (rechute post-rebuild)
|
||||
|
||||
### Fait determinant trouve par inspection directe des artefacts
|
||||
|
||||
Deux binaires AppImage distincts coexistent sur la machine, avec un ecart temporel et de contenu net:
|
||||
|
||||
| Fichier | mtime | sha256 (8 premiers car.) |
|
||||
|---|---|---|
|
||||
| `/home/anthony/Documents/IdeA_0.3.0_amd64.AppImage` (celui qu'IdeA fait tourner — cf. memoire `mcp-bridge-and-delegation-runtime-notes`) | 2026-07-24 15:09 | `61d499f2` |
|
||||
| `target/release/bundle/appimage/IdeA_0.3.0_amd64.AppImage` (rebuild QA du jour) | 2026-08-01 16:37 | `9ad50c21` |
|
||||
|
||||
Le commit du correctif (`5a30ec8`, isolation `usePluginMenus`/`ProjectsView`) date du **2026-08-01 16:23:56**, soit **apres** le mtime du binaire `~/Documents`. Le binaire que l'utilisateur execute au quotidien (`~/Documents/IdeA_0.3.0_amd64.AppImage`) est donc anterieur de plusieurs jours au correctif et ne peut structurellement pas le contenir.
|
||||
|
||||
### Requalification de cause racine
|
||||
|
||||
- La rechute rapportee le 2026-08-01 par l'utilisateur est tres vraisemblablement un **artefact de deploiement**, pas une regression de code: le rebuild QA a produit un binaire correct dans `target/release/bundle/appimage/`, mais ce binaire n'a jamais remplace celui reellement lance par l'utilisateur (`~/Documents/IdeA_0.3.0_amd64.AppImage`).
|
||||
- C'est exactement le piege deja documente en memoire projet (`mcp-bridge-and-delegation-runtime-notes`, section « Le binaire qui tourne = AppImage installee, pas les sources ») applique cette fois au correctif plugin plutot qu'au pont MCP.
|
||||
- Le carnet QA ci-dessus ne mentionne a aucun moment le remplacement du binaire `~/Documents` ni le redemarrage d'IdeA sur ce binaire remplace — seule la production de l'artefact dans `target/release/bundle/` est tracee.
|
||||
|
||||
### Borne de correction attendue
|
||||
|
||||
- **Aucun nouveau code frontend ou backend n'est requis a ce stade.** Le correctif `5a30ec8` (isolation menus plugin) est deja en place et deja valide par tests reels (114 fichiers / 1046 tests vitest, tests backend d'installation/chargement).
|
||||
- Action requise: deploiement, pas developpement — remplacer `~/Documents/IdeA_0.3.0_amd64.AppImage` par `target/release/bundle/appimage/IdeA_0.3.0_amd64.AppImage` (backup de l'ancien conseille, cf. convention memoire `*.old-<raison>fix`), relancer IdeA depuis ce binaire, puis reproduire exactement le parcours Parametres > Plugins > Installer depuis une archive > hello-plugin.
|
||||
- Si la rechute persiste APRES ce remplacement effectif et un redemarrage complet d'IdeA, alors l'hypothese frontend doit etre rouverte avec un perimetre elargi au-dela de `ProjectsView -> usePluginMenus -> MenuBar`, en verifiant en priorite (deja inspectes le 2026-08-01, RAS a la lecture statique mais non exerces en e2e reel):
|
||||
- `frontend/src/features/plugins/PluginsPanel.tsx` (flux `startInstallFromArchive` / `reviewArchive` / dialog de confirmation) — surface active au moment precis du clic « Installer »
|
||||
- `frontend/src/features/plugins/PluginConfirmDialog.tsx`
|
||||
- `frontend/src/features/plugins/PluginLayoutCellView.tsx` (isolation deja posee en amont de ce ticket, a re-verifier qu'elle couvre bien le layout du hello-plugin reconstruit)
|
||||
- la place de `RootErrorBoundary` par rapport a ces surfaces, pour confirmer qu'aucun chemin ne la contourne
|
||||
|
||||
### Prochaine etape (remplace la precedente)
|
||||
|
||||
- Ne pas rouvrir de chantier de code avant d'avoir confirme que l'utilisateur reproduit sur le binaire effectivement a jour.
|
||||
- Remplacement de binaire + retest = action Git/deploiement, a executer avant toute nouvelle investigation frontend.
|
||||
|
||||
## Requalification Architect du 2026-08-01 (nouveau symptome CORS apres installation)
|
||||
|
||||
### Nouveau fait utilisateur
|
||||
|
||||
Le symptome visible n'est plus seulement un ecran noir: dans la vue Plugins, IdeA affiche apres installation de `hello-plugin` un bandeau explicite:
|
||||
- `Certains plugins installes n'ont pas pu etre charges.`
|
||||
- `com.example.hello-plugin : Cross-origin script load denied by Cross-Origin Resource Sharing policy.`
|
||||
|
||||
Cette observation invalide la piste `LayoutTabs -> PluginLayoutSelectorSection` comme cause racine de ce symptome precis. Le durcissement frontend precedent reste utile: il a empeche le black screen et laisse remonter l'erreur exploitable.
|
||||
|
||||
### Cause racine retenue
|
||||
|
||||
- Le protocole custom `idea-plugin://` repondait sans headers CORS dans `crates/app-tauri/src/plugins.rs` (`plugin_asset_response`).
|
||||
- Le frontend charge le bundle plugin via `import()` dynamique depuis `frontend/src/plugins/runtime/loader.ts`; ce chargement est un fetch CORS.
|
||||
- L'origine du document (`tauri://localhost` / `http://tauri.localhost` en prod, `http://localhost:5173` en dev) est distincte de `idea-plugin://...`.
|
||||
- Faute de `Access-Control-Allow-Origin`, WebKitGTK bloque le module avec exactement le message observe.
|
||||
|
||||
### Couche proprietaire et perimetre de correction
|
||||
|
||||
- Couche proprietaire: backend/infrastructure `app-tauri`, pas frontend produit, pas packaging plugin.
|
||||
- Correctif attendu:
|
||||
- ajouter `Access-Control-Allow-Origin` sur les reponses du protocole plugin
|
||||
- ajouter `Access-Control-Allow-Methods: GET`
|
||||
- conserver intact le confinement `asset_allowed`
|
||||
- ajouter un test backend verrouillant ces headers sur `plugin_asset_response`
|
||||
|
||||
## Livraison DevBackend du 2026-08-01
|
||||
|
||||
- Branche de travail dediee: `feature/ticket120-plugin-asset-cors-headers`
|
||||
- Correctif implemente dans `crates/app-tauri/src/plugins.rs`
|
||||
- Headers ajoutes sur les reponses du protocole `idea-plugin://`:
|
||||
- `Access-Control-Allow-Origin: *`
|
||||
- `Access-Control-Allow-Methods: GET`
|
||||
- Factorisation via un builder de reponse commun aux chemins succes/erreur du protocole
|
||||
- Test ajoute: `plugin_asset_response_includes_cors_headers_for_dynamic_import`
|
||||
|
||||
### Commandes executees par DevBackend
|
||||
- `cargo fmt -p app-tauri` : OK
|
||||
- `cargo test -p app-tauri plugin_asset_response_includes_cors_headers_for_dynamic_import` : OK
|
||||
- `cargo test -p app-tauri plugins::tests` : OK
|
||||
- `cargo test -p app-tauri` : OK (242 passed, 0 failed, 5 ignored)
|
||||
|
||||
## Validation QA du 2026-08-01 (fix CORS)
|
||||
|
||||
### Verdict
|
||||
- PASS avec reserve explicite.
|
||||
|
||||
### Validation reelle obtenue
|
||||
- `cargo test -p app-tauri plugin_asset_response_includes_cors_headers_for_dynamic_import -- --nocapture` : OK
|
||||
- `cargo test -p app-tauri` : OK
|
||||
- `cargo test -p infrastructure --test plugin_install_load installs_sdk_hello_plugin_and_loads_runtime_catalog -- --nocapture` : OK
|
||||
- `cargo test -p infrastructure --test plugin_install_load installs_reference_fixture_and_loads_runtime_catalog -- --nocapture` : OK
|
||||
- `npm --prefix /home/anthony/Documents/Projects/IdeA/sdk/IdeaSDK run package:hello-plugin` : OK
|
||||
- `cd /home/anthony/Documents/Projects/IdeA/frontend && npx vitest run src/plugins/runtime/loader.test.ts src/features/plugins/plugins.test.tsx src/features/plugins/menus.test.ts` : OK (27 tests)
|
||||
|
||||
### Reserve QA restante
|
||||
- Pas de preuve visuelle AppImage/UI de bout en bout dans cet environnement.
|
||||
- Tentative de build AppImage realisee, mais l'artefact final n'etait pas disponible ensuite dans `target/release/bundle/appimage/`.
|
||||
- Tentative d'execution d'une AppImage existante bloquee par l'environnement (`No suitable fusermount binary found on the $PATH`).
|
||||
- Risque residuel exact: le fix est prouve au niveau handler backend, catalogue runtime et chargeur frontend, mais pas sur l'enchainement visuel complet `archive installee -> redemarrage UI reel -> absence du bandeau CORS`.
|
||||
|
||||
## Decision Git du 2026-08-01
|
||||
|
||||
- Commit local realise sur la branche dediee: `fbe69de`
|
||||
- Merge local `--no-ff` dans `develop`: `fd2ab4a`
|
||||
- Motivation: QA a rendu un verdict PASS; la reserve porte sur une limite d'environnement de preuve AppImage/FUSE, pas sur un test rouge.
|
||||
- La branche `feature/ticket120-plugin-asset-cors-headers` a ete supprimee apres merge.
|
||||
|
||||
## Etat reel a la fin de cette relance
|
||||
|
||||
- Le correctif CORS est livre dans `develop`.
|
||||
- Le ticket **reste a considerer ouvert fonctionnellement** tant qu'une validation visuelle reelle sur AppImage/redemarrage n'a pas confirme la disparition du bandeau `Cross-origin script load denied by Cross-Origin Resource Sharing policy` et l'activation effective des contributions `hello-plugin`.
|
||||
- Prochaine preuve attendue hors environnement QA courant: lancer le binaire AppImage reellement utilise par l'utilisateur, installer l'archive `hello-plugin`, redemarrer IdeA, verifier visuellement l'absence du bandeau CORS et la presence des contributions plugin actives.
|
||||
34
.ideai/tickets/120/issue.md
Normal file
34
.ideai/tickets/120/issue.md
Normal file
@ -0,0 +1,34 @@
|
||||
---
|
||||
id: "f4218553-680a-4fbb-9514-a96eab79b8d8"
|
||||
number: 120
|
||||
title: "Réinvestiguer l’installation de hello-plugin: écran noir / perte d’affichage IdeA"
|
||||
status: "inProgress"
|
||||
priority: "critical"
|
||||
sprint: null
|
||||
links: [{"target":"#116","kind":"relatesTo"},{"target":"#43","kind":"relatesTo"}]
|
||||
agentRefs: []
|
||||
attachments: []
|
||||
createdBy: {"kind":"agent","agent_id":"a6ced819-b893-4213-b003-9e9dc79b9641"}
|
||||
updatedBy: {"kind":"agent","agent_id":"a6ced819-b893-4213-b003-9e9dc79b9641"}
|
||||
createdAt: 1785534496259
|
||||
updatedAt: 1785600025153
|
||||
version: 9
|
||||
---
|
||||
## Constat utilisateur
|
||||
|
||||
Au 2026-07-31, l’installation de `hello-plugin` fait encore perdre tout l’affichage d’IdeA (écran noir / UI vide), malgré un précédent correctif supposé sur `#116`.
|
||||
|
||||
## Objectif
|
||||
|
||||
Reprendre le sujet proprement avec un ticket neuf de réinvestigation et de durcissement:
|
||||
- recréer un plugin de test minimal `hello-plugin` depuis zéro pour repartir d’un cas maîtrisé ;
|
||||
- renforcer les tests e2e autour du cycle d’installation plugin ;
|
||||
- identifier précisément la cause réelle de la perte d’affichage ;
|
||||
- corriger le ou les défauts (backend, frontend, runtime, permissions, flux d’installation, etc.) ;
|
||||
- valider la non-régression sur le cas `hello-plugin`.
|
||||
|
||||
## Notes de cadrage
|
||||
|
||||
- Le ticket n’assume pas que la cause soit dans le plugin lui-même ; la reconstruction du plugin sert de témoin minimal reproductible.
|
||||
- Le ticket doit s’appuyer sur le précédent `#116` mais repart d’un constat live utilisateur indiquant que le système plugin reste non fiable.
|
||||
- La sortie attendue inclut des tests e2e réellement exécutés et un rebuild AppImage pour validation dans le binaire utilisé par IdeA.
|
||||
6
.ideai/tickets/121/carnet.md
Normal file
6
.ideai/tickets/121/carnet.md
Normal file
@ -0,0 +1,6 @@
|
||||
---
|
||||
issueRef: "#121"
|
||||
version: 2
|
||||
updatedBy: {"kind":"agent","agent_id":"dce19c75-9669-4e45-b8de-9950025157da"}
|
||||
updatedAt: 1785534534027
|
||||
---
|
||||
16
.ideai/tickets/121/issue.md
Normal file
16
.ideai/tickets/121/issue.md
Normal file
@ -0,0 +1,16 @@
|
||||
---
|
||||
id: "07d83a8e-63cd-4f72-b056-aaf792d517fb"
|
||||
number: 121
|
||||
title: "__probe__"
|
||||
status: "closed"
|
||||
priority: "medium"
|
||||
sprint: null
|
||||
links: []
|
||||
agentRefs: []
|
||||
attachments: []
|
||||
createdBy: {"kind":"agent","agent_id":"dce19c75-9669-4e45-b8de-9950025157da"}
|
||||
updatedBy: {"kind":"agent","agent_id":"dce19c75-9669-4e45-b8de-9950025157da"}
|
||||
createdAt: 1785534526705
|
||||
updatedAt: 1785534534027
|
||||
version: 2
|
||||
---
|
||||
6
.ideai/tickets/122/carnet.md
Normal file
6
.ideai/tickets/122/carnet.md
Normal file
@ -0,0 +1,6 @@
|
||||
---
|
||||
issueRef: "#122"
|
||||
version: 3
|
||||
updatedBy: {"kind":"user"}
|
||||
updatedAt: 1785592528432
|
||||
---
|
||||
17
.ideai/tickets/122/issue.md
Normal file
17
.ideai/tickets/122/issue.md
Normal file
@ -0,0 +1,17 @@
|
||||
---
|
||||
id: "fa083793-48ae-417a-ab16-3813e22df2e3"
|
||||
number: 122
|
||||
title: "[Bug] Override des permissions defaut qui ne marche pas"
|
||||
status: "open"
|
||||
priority: "medium"
|
||||
sprint: null
|
||||
links: []
|
||||
agentRefs: [{"agentId":"a6ced819-b893-4213-b003-9e9dc79b9641","role":"assigned"}]
|
||||
attachments: []
|
||||
createdBy: {"kind":"user"}
|
||||
updatedBy: {"kind":"user"}
|
||||
createdAt: 1785592422173
|
||||
updatedAt: 1785592528432
|
||||
version: 3
|
||||
---
|
||||
J'ai l'impression que l'override des permissions systeme ne fonctionne pas. J'avais les permissions par defaut qui ne donnait pas les droits bash, et meme après avoir override ce parametre sur un de mes agents, il n'avait aps acces aux tools bash. Il y a eu acces une fois qu'avais mis le droit dans la config defaut
|
||||
39
.ideai/tickets/123/carnet.md
Normal file
39
.ideai/tickets/123/carnet.md
Normal file
@ -0,0 +1,39 @@
|
||||
---
|
||||
issueRef: "#123"
|
||||
version: 4
|
||||
updatedBy: {"kind":"agent","agent_id":"a6ced819-b893-4213-b003-9e9dc79b9641"}
|
||||
updatedAt: 1785670261241
|
||||
---
|
||||
## Contexte
|
||||
Le besoin initial vient d’un futur plugin orienté développement Android, mais le périmètre validé pour ce chantier est strictement **SDK générique**. L’objectif n’est pas d’ajouter des API Android-first, mais de combler les trous du SDK public qui empêchent aujourd’hui tout plugin de développement un peu sérieux.
|
||||
|
||||
## Ce qui existe déjà
|
||||
- Manifest public `idea-plugin.json`
|
||||
- Runtime `activate(ctx)`
|
||||
- `commands`, `storage`, `logger`
|
||||
- `services.workspace`, `services.tasks`, `services.terminal`
|
||||
- Contributions `menus`, `menuItems`, `layouts`, `mcpServers`
|
||||
|
||||
## Problème
|
||||
Le SDK public actuel est volontairement minimal. Il permet des plugins simples, mais pas un plugin d’outillage qui doit agir sur un workspace, lancer des outils externes, réagir aux événements du host, afficher une UI riche, ou analyser la structure d’un projet.
|
||||
|
||||
## Décision de cadrage
|
||||
Découper le besoin en tickets transverses, indépendants autant que possible.
|
||||
|
||||
Ordre de priorité retenu :
|
||||
1. `#124` API fichiers/workspace
|
||||
2. `#125` API lancement de commandes et tâches
|
||||
3. `#126` API découverte/validation d’outillage externe
|
||||
4. `#127` API d’événements et de watch
|
||||
5. `#128` runtime UI/layout publique
|
||||
6. `#129` API d’analyse/requête de structure projet
|
||||
7. `#130` API de documents de configuration structurés
|
||||
|
||||
## Garde-fous
|
||||
- Pas d’API spécifique Android dans ce lot.
|
||||
- Préserver une frontière SDK public vs runtime interne.
|
||||
- Favoriser des primitives génériques réutilisables pour Android, iOS, Node, Python, Docker, etc.
|
||||
- Éviter de forcer les plugins à dépendre de casts ad hoc ou d’objets runtime internes.
|
||||
|
||||
## Définition de done du parapluie
|
||||
Le parapluie est clôturable quand les tickets enfants retenus pour le MVP sont livrés ou explicitement re-scopeés avec arbitrage.
|
||||
17
.ideai/tickets/123/issue.md
Normal file
17
.ideai/tickets/123/issue.md
Normal file
@ -0,0 +1,17 @@
|
||||
---
|
||||
id: "0013caf7-bbc9-439f-82b2-9d23ed9e901a"
|
||||
number: 123
|
||||
title: "SDK plugins: combler les capacités globales manquantes pour les plugins de développement outillés"
|
||||
status: "qa"
|
||||
priority: "high"
|
||||
sprint: null
|
||||
links: []
|
||||
agentRefs: []
|
||||
attachments: []
|
||||
createdBy: {"kind":"agent","agent_id":"a6ced819-b893-4213-b003-9e9dc79b9641"}
|
||||
updatedBy: {"kind":"agent","agent_id":"a6ced819-b893-4213-b003-9e9dc79b9641"}
|
||||
createdAt: 1785662012603
|
||||
updatedAt: 1785670261241
|
||||
version: 4
|
||||
---
|
||||
Ticket parapluie pour structurer l’extension du SDK public des plugins IdeA afin de supporter des plugins de développement avancés sans introduire d’API métier spécifiques à une stack donnée. Le besoin initial vient du cas Android, mais le périmètre doit rester strictement transversal.
|
||||
39
.ideai/tickets/124/carnet.md
Normal file
39
.ideai/tickets/124/carnet.md
Normal file
@ -0,0 +1,39 @@
|
||||
---
|
||||
issueRef: "#124"
|
||||
version: 4
|
||||
updatedBy: {"kind":"agent","agent_id":"a6ced819-b893-4213-b003-9e9dc79b9641"}
|
||||
updatedAt: 1785666067073
|
||||
---
|
||||
## Problème
|
||||
`WorkspaceService` public expose aujourd’hui seulement le projet courant, son root, et la lecture/écriture du contexte Markdown IdeA. Cela ne suffit pas pour un plugin de développement qui doit lire, écrire, lister ou surveiller les fichiers d’un projet.
|
||||
|
||||
## Pourquoi c’est global
|
||||
Ce besoin n’a rien de spécifique à Android. Tout plugin de dev outillé doit pouvoir manipuler le workspace : configs, manifests, scripts, sources, fichiers générés, assets, etc.
|
||||
|
||||
## Ce que ce ticket doit produire
|
||||
Une API publique de workspace/fichiers permettant au minimum :
|
||||
- lecture de fichier texte/binaire
|
||||
- écriture atomique ou contrôlée
|
||||
- listing de répertoires
|
||||
- existence/stat basiques
|
||||
- résolution sûre de chemins dans le project root
|
||||
- capacité de watch ou point d’extension compatible avec `#127`
|
||||
|
||||
## Contraintes d’architecture
|
||||
- API strictement publique côté SDK TypeScript.
|
||||
- Aucun accès direct aux objets runtime internes.
|
||||
- Respect du sandboxing et du project root.
|
||||
- Contrat clair sur les erreurs, encodages, chemins hors-root et fichiers absents.
|
||||
|
||||
## Non-objectifs
|
||||
- Pas de parser Gradle/XML/JSON dans ce ticket.
|
||||
- Pas d’analyse sémantique du projet.
|
||||
- Pas de conventions Android codées en dur.
|
||||
|
||||
## Dépendances
|
||||
- Bloque `#126`, `#129`, `#130`.
|
||||
|
||||
## Critères d’acceptation
|
||||
- Un plugin peut lire/écrire/lister dans le workspace sans cast interne.
|
||||
- Le contrat gère explicitement les chemins invalides/hors-root.
|
||||
- La documentation SDK montre un exemple simple de manipulation de fichiers.
|
||||
17
.ideai/tickets/124/issue.md
Normal file
17
.ideai/tickets/124/issue.md
Normal file
@ -0,0 +1,17 @@
|
||||
---
|
||||
id: "639787e1-83b5-49b7-a89f-3a6985129163"
|
||||
number: 124
|
||||
title: "SDK plugins: exposer une API publique d’accès fichiers/workspace"
|
||||
status: "qa"
|
||||
priority: "critical"
|
||||
sprint: null
|
||||
links: [{"target":"#123","kind":"blocks"}]
|
||||
agentRefs: []
|
||||
attachments: []
|
||||
createdBy: {"kind":"agent","agent_id":"a6ced819-b893-4213-b003-9e9dc79b9641"}
|
||||
updatedBy: {"kind":"agent","agent_id":"a6ced819-b893-4213-b003-9e9dc79b9641"}
|
||||
createdAt: 1785662026640
|
||||
updatedAt: 1785666067073
|
||||
version: 4
|
||||
---
|
||||
Ajouter au SDK plugin une API publique de lecture/écriture/listing/watch dans le workspace projet, distincte du simple accès au contexte Markdown IdeA.
|
||||
40
.ideai/tickets/125/carnet.md
Normal file
40
.ideai/tickets/125/carnet.md
Normal file
@ -0,0 +1,40 @@
|
||||
---
|
||||
issueRef: "#125"
|
||||
version: 4
|
||||
updatedBy: {"kind":"agent","agent_id":"a6ced819-b893-4213-b003-9e9dc79b9641"}
|
||||
updatedAt: 1785667057177
|
||||
---
|
||||
## Problème
|
||||
Le SDK public permet seulement :
|
||||
- d’observer/contrôler des background tasks existantes
|
||||
- d’ouvrir un PTY interactif
|
||||
|
||||
Il manque une API publique pour **démarrer** une commande/outillage externe de façon intégrée à IdeA.
|
||||
|
||||
## Pourquoi c’est global
|
||||
Le besoin est transversal à tous les plugins de développement : build, test, lint, génération, outils CLI, pipelines locaux, simulateurs, wrappers maison.
|
||||
|
||||
## Ce que ce ticket doit produire
|
||||
Une API publique de lancement de commandes/tâches permettant au minimum :
|
||||
- exécuter une commande avec `cwd`, args, env
|
||||
- choisir un mode tracked/background task plutôt qu’un PTY brut
|
||||
- suivre statut, exit code, stdout/stderr
|
||||
- annuler / éventuellement relancer
|
||||
- corréler le run avec le modèle Work d’IdeA
|
||||
|
||||
## Contraintes d’architecture
|
||||
- Ne pas confondre terminal interactif et task runner.
|
||||
- Contrat stable sur environnement, cwd, timeouts éventuels, sortie et erreurs.
|
||||
- Le plugin ne doit pas avoir à bricoler une session PTY pour lancer un build.
|
||||
|
||||
## Non-objectifs
|
||||
- Pas de sémantique Android/Gradle/adb.
|
||||
- Pas d’orchestration multi-étapes spécifique à une stack.
|
||||
|
||||
## Dépendances
|
||||
- Bloque `#126`.
|
||||
|
||||
## Critères d’acceptation
|
||||
- Un plugin peut lancer une commande externe sans passer par un cast interne ni un PTY interactif.
|
||||
- L’exécution remonte un état observable et un résultat terminal clair.
|
||||
- Le contrat est documenté côté SDK avec exemple de commande simple.
|
||||
17
.ideai/tickets/125/issue.md
Normal file
17
.ideai/tickets/125/issue.md
Normal file
@ -0,0 +1,17 @@
|
||||
---
|
||||
id: "78bb45fb-6320-4d75-8db2-1e2a9591219f"
|
||||
number: 125
|
||||
title: "SDK plugins: exposer une API publique de lancement de commandes et tâches"
|
||||
status: "qa"
|
||||
priority: "critical"
|
||||
sprint: null
|
||||
links: [{"target":"#123","kind":"blocks"}]
|
||||
agentRefs: []
|
||||
attachments: []
|
||||
createdBy: {"kind":"agent","agent_id":"a6ced819-b893-4213-b003-9e9dc79b9641"}
|
||||
updatedBy: {"kind":"agent","agent_id":"a6ced819-b893-4213-b003-9e9dc79b9641"}
|
||||
createdAt: 1785662026655
|
||||
updatedAt: 1785667057177
|
||||
version: 4
|
||||
---
|
||||
Ajouter au SDK plugin une API publique pour lancer des commandes/outils externes et suivre leur exécution comme tâches IdeA, au-delà de l’observation des tâches existantes et du simple PTY interactif.
|
||||
36
.ideai/tickets/126/carnet.md
Normal file
36
.ideai/tickets/126/carnet.md
Normal file
@ -0,0 +1,36 @@
|
||||
---
|
||||
issueRef: "#126"
|
||||
version: 7
|
||||
updatedBy: {"kind":"agent","agent_id":"a6ced819-b893-4213-b003-9e9dc79b9641"}
|
||||
updatedAt: 1785668062783
|
||||
---
|
||||
## Problème
|
||||
Un plugin de dev a souvent besoin de savoir si un outillage externe existe, où il se trouve, quelle version est installée, et si l’environnement est valide. Le SDK public n’expose pas aujourd’hui cette capacité comme primitive générique.
|
||||
|
||||
## Pourquoi c’est global
|
||||
Ce besoin vaut pour Android SDK, Java, Node, Python, Docker, Go, Rust toolchain, etc. Le ticket doit fournir une abstraction générique de découverte/validation d’outillage, pas une API dédiée Android.
|
||||
|
||||
## Ce que ce ticket doit produire
|
||||
Une API publique permettant idéalement :
|
||||
- résolution d’un exécutable ou d’une toolchain par nom/id
|
||||
- lecture de version
|
||||
- inspection de variables d’environnement pertinentes
|
||||
- validation de prérequis déclaratifs
|
||||
- restitution d’un diagnostic structuré exploitable par une UI plugin
|
||||
|
||||
## Contraintes d’architecture
|
||||
- La source de vérité peut s’appuyer sur fichiers, env et exécution d’outils, mais l’API exposée doit rester stable et agnostique.
|
||||
- Ne pas figer de modèle métier Android.
|
||||
|
||||
## Dépendances
|
||||
- Dépend de `#124` pour l’accès workspace/config.
|
||||
- Dépend de `#125` pour l’exécution contrôlée des commandes de détection.
|
||||
|
||||
## Non-objectifs
|
||||
- Pas de gestion d’émulateur/device manager.
|
||||
- Pas d’installation automatique d’une toolchain dans ce ticket.
|
||||
|
||||
## Critères d’acceptation
|
||||
- Un plugin peut diagnostiquer la présence/absence d’un outillage externe de façon structurée.
|
||||
- Le diagnostic est assez générique pour servir plusieurs stacks.
|
||||
- La doc SDK montre un cas simple de détection d’exécutable/version.
|
||||
17
.ideai/tickets/126/issue.md
Normal file
17
.ideai/tickets/126/issue.md
Normal file
@ -0,0 +1,17 @@
|
||||
---
|
||||
id: "51d4f4b0-4482-4400-a0d5-9f88471581f0"
|
||||
number: 126
|
||||
title: "SDK plugins: exposer une API publique de découverte/validation d’outillage externe"
|
||||
status: "qa"
|
||||
priority: "high"
|
||||
sprint: null
|
||||
links: [{"target":"#123","kind":"blocks"},{"target":"#124","kind":"dependsOn"},{"target":"#125","kind":"dependsOn"}]
|
||||
agentRefs: []
|
||||
attachments: []
|
||||
createdBy: {"kind":"agent","agent_id":"a6ced819-b893-4213-b003-9e9dc79b9641"}
|
||||
updatedBy: {"kind":"agent","agent_id":"a6ced819-b893-4213-b003-9e9dc79b9641"}
|
||||
createdAt: 1785662026684
|
||||
updatedAt: 1785668062783
|
||||
version: 7
|
||||
---
|
||||
Ajouter au SDK plugin une API publique pour détecter, valider et décrire des toolchains externes (exécutables, versions, variables d’environnement, prérequis) sans spécialiser le SDK pour une stack donnée.
|
||||
35
.ideai/tickets/127/carnet.md
Normal file
35
.ideai/tickets/127/carnet.md
Normal file
@ -0,0 +1,35 @@
|
||||
---
|
||||
issueRef: "#127"
|
||||
version: 4
|
||||
updatedBy: {"kind":"agent","agent_id":"a6ced819-b893-4213-b003-9e9dc79b9641"}
|
||||
updatedAt: 1785669121141
|
||||
---
|
||||
## Problème
|
||||
Sans bus d’événements ou API de watch publique, un plugin doit poller l’état du host ou du workspace pour se tenir à jour. C’est coûteux, fragile et peu réactif.
|
||||
|
||||
## Pourquoi c’est global
|
||||
Tout plugin de dev outillé peut avoir besoin de réagir à :
|
||||
- changement de fichier
|
||||
- fin/échec d’une tâche
|
||||
- changement de projet courant
|
||||
- autres événements système ou host pertinents
|
||||
|
||||
## Ce que ce ticket doit produire
|
||||
Une API publique d’abonnement permettant au minimum :
|
||||
- souscription/désinscription propre
|
||||
- typage minimal des événements publics
|
||||
- événements documentés et versionnables
|
||||
- stratégie claire sur rétention/perte d’événements
|
||||
|
||||
## Contraintes d’architecture
|
||||
- Exposer uniquement des événements publics stables.
|
||||
- Ne pas refléter brut de décoffrage les événements internes du host.
|
||||
- Bien définir les garanties: best effort vs livraison fiable.
|
||||
|
||||
## Non-objectifs
|
||||
- Pas de protocole temps réel cross-process complexe si non nécessaire.
|
||||
- Pas d’événements spécifiques Android.
|
||||
|
||||
## Critères d’acceptation
|
||||
- Un plugin peut se mettre à jour sur changements du workspace/host sans polling permanent.
|
||||
- L’API de subscription est proprement disposable et documentée.
|
||||
17
.ideai/tickets/127/issue.md
Normal file
17
.ideai/tickets/127/issue.md
Normal file
@ -0,0 +1,17 @@
|
||||
---
|
||||
id: "9b238559-9982-4a69-8795-99da8a46be1e"
|
||||
number: 127
|
||||
title: "SDK plugins: exposer une API publique d’événements et de watch"
|
||||
status: "qa"
|
||||
priority: "high"
|
||||
sprint: null
|
||||
links: [{"target":"#123","kind":"blocks"}]
|
||||
agentRefs: []
|
||||
attachments: []
|
||||
createdBy: {"kind":"agent","agent_id":"a6ced819-b893-4213-b003-9e9dc79b9641"}
|
||||
updatedBy: {"kind":"agent","agent_id":"a6ced819-b893-4213-b003-9e9dc79b9641"}
|
||||
createdAt: 1785662026701
|
||||
updatedAt: 1785669121141
|
||||
version: 4
|
||||
---
|
||||
Ajouter au SDK plugin une API publique d’abonnement aux événements utiles du host et du projet: changements de fichiers, évolution des tâches, focus projet et autres signaux nécessaires pour éviter le polling côté plugin.
|
||||
31
.ideai/tickets/128/carnet.md
Normal file
31
.ideai/tickets/128/carnet.md
Normal file
@ -0,0 +1,31 @@
|
||||
---
|
||||
issueRef: "#128"
|
||||
version: 4
|
||||
updatedBy: {"kind":"agent","agent_id":"a6ced819-b893-4213-b003-9e9dc79b9641"}
|
||||
updatedAt: 1785670260985
|
||||
---
|
||||
## Problème
|
||||
Le manifeste expose déjà des contributions `layouts`, mais la runtime publique ne formalise pas proprement l’enregistrement et le cycle de vie de ces layouts. L’exemple SDK actuel contourne la surface avec des casts ad hoc.
|
||||
|
||||
## Pourquoi c’est global
|
||||
Ce n’est pas spécifique à Android: tout plugin de dev peut vouloir afficher un panneau d’état, un tableau, un viewer de logs, une vue de diagnostic, etc.
|
||||
|
||||
## Ce que ce ticket doit produire
|
||||
Une runtime UI/layout publique stable permettant au minimum :
|
||||
- enregistrement typé d’un layout
|
||||
- props publiques documentées
|
||||
- cycle de vie clair
|
||||
- persistance/lecture de state si le host la supporte
|
||||
- retrait propre via disposable
|
||||
|
||||
## Contraintes d’architecture
|
||||
- Pas de dépendance à des détails runtime privés.
|
||||
- Contrat explicite sur le rendu et la sérialisation du state plugin.
|
||||
|
||||
## Non-objectifs
|
||||
- Pas d’imposer un design system plugin complet.
|
||||
- Pas d’API spécifique aux vues Android.
|
||||
|
||||
## Critères d’acceptation
|
||||
- L’exemple SDK n’a plus besoin de cast ad hoc pour enregistrer un layout.
|
||||
- La surface publique suffit pour un panneau plugin de dev non trivial.
|
||||
17
.ideai/tickets/128/issue.md
Normal file
17
.ideai/tickets/128/issue.md
Normal file
@ -0,0 +1,17 @@
|
||||
---
|
||||
id: "053f079d-1dfd-48bb-85a2-2dfa8d237999"
|
||||
number: 128
|
||||
title: "SDK plugins: typer et stabiliser la runtime UI/layout publique"
|
||||
status: "qa"
|
||||
priority: "medium"
|
||||
sprint: null
|
||||
links: [{"target":"#123","kind":"blocks"}]
|
||||
agentRefs: []
|
||||
attachments: []
|
||||
createdBy: {"kind":"agent","agent_id":"a6ced819-b893-4213-b003-9e9dc79b9641"}
|
||||
updatedBy: {"kind":"agent","agent_id":"a6ced819-b893-4213-b003-9e9dc79b9641"}
|
||||
createdAt: 1785662026717
|
||||
updatedAt: 1785670260985
|
||||
version: 4
|
||||
---
|
||||
Formaliser la surface runtime publique pour les contributions UI/layout des plugins afin d’éviter les casts ad hoc et de permettre des panneaux/plugins de dev riches sur base stable.
|
||||
30
.ideai/tickets/129/carnet.md
Normal file
30
.ideai/tickets/129/carnet.md
Normal file
@ -0,0 +1,30 @@
|
||||
---
|
||||
issueRef: "#129"
|
||||
version: 5
|
||||
updatedBy: {"kind":"agent","agent_id":"a6ced819-b893-4213-b003-9e9dc79b9641"}
|
||||
updatedAt: 1785666067171
|
||||
---
|
||||
## Problème
|
||||
Chaque plugin de développement devrait aujourd’hui rescanner lui-même le workspace pour reconstruire une vision de la structure projet. Cela duplique les heuristiques et rend l’écosystème fragile.
|
||||
|
||||
## Pourquoi c’est global
|
||||
Android n’est qu’un cas parmi d’autres. Les plugins pour monorepos JS, workspaces Rust, Python multi-env, etc. ont tous besoin d’une lecture structurée minimale du projet.
|
||||
|
||||
## Ce que ce ticket doit produire
|
||||
Une API publique d’analyse/requête permettant idéalement :
|
||||
- liste de fichiers ou sous-ensembles pertinents
|
||||
- conventions détectées
|
||||
- modules/units logiques quand connus
|
||||
- graphes simples ou métadonnées projet de base
|
||||
- résultats structurés et bornés, pas un AST universel magique
|
||||
|
||||
## Dépendances
|
||||
- Dépend de `#124` car l’analyse repose au minimum sur l’accès contrôlé au workspace.
|
||||
|
||||
## Non-objectifs
|
||||
- Pas d’indexation sémantique profonde de tous les langages.
|
||||
- Pas de modèle Android-only (Gradle modules, variants, etc.) dans l’API publique de base.
|
||||
|
||||
## Critères d’acceptation
|
||||
- Un plugin peut interroger la structure du projet sans rescanner tout le disque lui-même.
|
||||
- Le contrat reste utile à plusieurs stacks et ne fuit pas des abstractions internes.
|
||||
17
.ideai/tickets/129/issue.md
Normal file
17
.ideai/tickets/129/issue.md
Normal file
@ -0,0 +1,17 @@
|
||||
---
|
||||
id: "550fe7ca-8a25-4529-be2e-2fd79c7ddde4"
|
||||
number: 129
|
||||
title: "SDK plugins: exposer une API publique d’analyse/requête de structure projet"
|
||||
status: "qa"
|
||||
priority: "medium"
|
||||
sprint: null
|
||||
links: [{"target":"#123","kind":"blocks"},{"target":"#124","kind":"dependsOn"}]
|
||||
agentRefs: []
|
||||
attachments: []
|
||||
createdBy: {"kind":"agent","agent_id":"a6ced819-b893-4213-b003-9e9dc79b9641"}
|
||||
updatedBy: {"kind":"agent","agent_id":"a6ced819-b893-4213-b003-9e9dc79b9641"}
|
||||
createdAt: 1785662026738
|
||||
updatedAt: 1785666067171
|
||||
version: 5
|
||||
---
|
||||
Ajouter au SDK plugin une API publique pour interroger la structure d’un projet (fichiers, modules, graphes simples, conventions détectées) sans obliger chaque plugin à rescanner le workspace depuis zéro.
|
||||
54
.ideai/tickets/13/carnet.md
Normal file
54
.ideai/tickets/13/carnet.md
Normal file
@ -0,0 +1,54 @@
|
||||
---
|
||||
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).
|
||||
16
.ideai/tickets/13/issue.md
Normal file
16
.ideai/tickets/13/issue.md
Normal file
@ -0,0 +1,16 @@
|
||||
---
|
||||
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.
|
||||
31
.ideai/tickets/130/carnet.md
Normal file
31
.ideai/tickets/130/carnet.md
Normal file
@ -0,0 +1,31 @@
|
||||
---
|
||||
issueRef: "#130"
|
||||
version: 5
|
||||
updatedBy: {"kind":"agent","agent_id":"a6ced819-b893-4213-b003-9e9dc79b9641"}
|
||||
updatedAt: 1785669830933
|
||||
---
|
||||
## Problème
|
||||
Un plugin de développement doit souvent lire ou modifier des documents structurés. Sans primitive publique, chaque plugin doit réimplémenter parsing, validation et patching, avec un risque élevé de corruption ou d’incohérence.
|
||||
|
||||
## Pourquoi c’est global
|
||||
Le besoin concerne JSON, YAML, TOML, XML, propriétés, DSL de config, et potentiellement d’autres formats. Android n’est qu’un consommateur parmi d’autres.
|
||||
|
||||
## Ce que ce ticket doit produire
|
||||
Une API publique de documents/config structurés permettant idéalement :
|
||||
- lecture d’un document typé ou semi-structuré
|
||||
- édition contrôlée/patch ciblé
|
||||
- sérialisation stable
|
||||
- erreurs structurées
|
||||
- capacité d’évolution format par format
|
||||
|
||||
## Dépendances
|
||||
- Dépend de `#124` car il faut d’abord un accès fichier/workspace public.
|
||||
|
||||
## Garde-fous
|
||||
- Commencer petit si nécessaire; ne pas promettre tous les formats d’un coup.
|
||||
- Préférer une abstraction extensible plutôt qu’un parser universel monolithique.
|
||||
- Ne pas embarquer des helpers Android-only.
|
||||
|
||||
## Critères d’acceptation
|
||||
- Le SDK expose une primitive réutilisable pour lire et mettre à jour un document de config sans bricolage spécifique par plugin.
|
||||
- Le contrat précise clairement quels formats sont supportés dans le premier lot.
|
||||
17
.ideai/tickets/130/issue.md
Normal file
17
.ideai/tickets/130/issue.md
Normal file
@ -0,0 +1,17 @@
|
||||
---
|
||||
id: "07a76880-f176-4fc8-b1d3-732a88a8c837"
|
||||
number: 130
|
||||
title: "SDK plugins: exposer une API publique de documents de configuration structurés"
|
||||
status: "qa"
|
||||
priority: "medium"
|
||||
sprint: null
|
||||
links: [{"target":"#123","kind":"blocks"},{"target":"#124","kind":"dependsOn"}]
|
||||
agentRefs: []
|
||||
attachments: []
|
||||
createdBy: {"kind":"agent","agent_id":"a6ced819-b893-4213-b003-9e9dc79b9641"}
|
||||
updatedBy: {"kind":"agent","agent_id":"a6ced819-b893-4213-b003-9e9dc79b9641"}
|
||||
createdAt: 1785662026750
|
||||
updatedAt: 1785669830933
|
||||
version: 5
|
||||
---
|
||||
Ajouter au SDK plugin une API publique pour lire/mettre à jour des documents de configuration structurés via un modèle générique plutôt que forcer chaque plugin à réimplémenter son parsing/patching.
|
||||
20
.ideai/tickets/14/carnet.md
Normal file
20
.ideai/tickets/14/carnet.md
Normal file
@ -0,0 +1,20 @@
|
||||
---
|
||||
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.
|
||||
75
.ideai/tickets/14/issue.md
Normal file
75
.ideai/tickets/14/issue.md
Normal file
@ -0,0 +1,75 @@
|
||||
---
|
||||
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.
|
||||
15
.ideai/tickets/15/carnet.md
Normal file
15
.ideai/tickets/15/carnet.md
Normal file
@ -0,0 +1,15 @@
|
||||
---
|
||||
issueRef: "#15"
|
||||
version: 6
|
||||
updatedBy: {"kind":"user"}
|
||||
updatedAt: 1785271075239
|
||||
---
|
||||
## 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.
|
||||
28
.ideai/tickets/15/issue.md
Normal file
28
.ideai/tickets/15/issue.md
Normal file
@ -0,0 +1,28 @@
|
||||
---
|
||||
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: "closed"
|
||||
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":"user"}
|
||||
createdAt: 1783208599385
|
||||
updatedAt: 1785271075239
|
||||
version: 6
|
||||
---
|
||||
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.
|
||||
6
.ideai/tickets/16/carnet.md
Normal file
6
.ideai/tickets/16/carnet.md
Normal file
@ -0,0 +1,6 @@
|
||||
---
|
||||
issueRef: "#16"
|
||||
version: 7
|
||||
updatedBy: {"kind":"user"}
|
||||
updatedAt: 1783405334263
|
||||
---
|
||||
17
.ideai/tickets/16/issue.md
Normal file
17
.ideai/tickets/16/issue.md
Normal file
@ -0,0 +1,17 @@
|
||||
---
|
||||
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.
|
||||
6
.ideai/tickets/17/carnet.md
Normal file
6
.ideai/tickets/17/carnet.md
Normal file
@ -0,0 +1,6 @@
|
||||
---
|
||||
issueRef: "#17"
|
||||
version: 10
|
||||
updatedBy: {"kind":"user"}
|
||||
updatedAt: 1783405334977
|
||||
---
|
||||
16
.ideai/tickets/17/issue.md
Normal file
16
.ideai/tickets/17/issue.md
Normal file
@ -0,0 +1,16 @@
|
||||
---
|
||||
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.
|
||||
6
.ideai/tickets/18/carnet.md
Normal file
6
.ideai/tickets/18/carnet.md
Normal file
@ -0,0 +1,6 @@
|
||||
---
|
||||
issueRef: "#18"
|
||||
version: 9
|
||||
updatedBy: {"kind":"user"}
|
||||
updatedAt: 1783405335941
|
||||
---
|
||||
16
.ideai/tickets/18/issue.md
Normal file
16
.ideai/tickets/18/issue.md
Normal file
@ -0,0 +1,16 @@
|
||||
---
|
||||
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.
|
||||
6
.ideai/tickets/19/carnet.md
Normal file
6
.ideai/tickets/19/carnet.md
Normal file
@ -0,0 +1,6 @@
|
||||
---
|
||||
issueRef: "#19"
|
||||
version: 8
|
||||
updatedBy: {"kind":"user"}
|
||||
updatedAt: 1783405337651
|
||||
---
|
||||
16
.ideai/tickets/19/issue.md
Normal file
16
.ideai/tickets/19/issue.md
Normal file
@ -0,0 +1,16 @@
|
||||
---
|
||||
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
|
||||
6
.ideai/tickets/2/carnet.md
Normal file
6
.ideai/tickets/2/carnet.md
Normal file
@ -0,0 +1,6 @@
|
||||
---
|
||||
issueRef: "#2"
|
||||
version: 6
|
||||
updatedBy: {"kind":"agent","agent_id":"a6ced819-b893-4213-b003-9e9dc79b9641"}
|
||||
updatedAt: 1784065385002
|
||||
---
|
||||
39
.ideai/tickets/2/issue.md
Normal file
39
.ideai/tickets/2/issue.md
Normal file
@ -0,0 +1,39 @@
|
||||
---
|
||||
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.
|
||||
6
.ideai/tickets/20/carnet.md
Normal file
6
.ideai/tickets/20/carnet.md
Normal file
@ -0,0 +1,6 @@
|
||||
---
|
||||
issueRef: "#20"
|
||||
version: 5
|
||||
updatedBy: {"kind":"agent","agent_id":"a6ced819-b893-4213-b003-9e9dc79b9641"}
|
||||
updatedAt: 1784049665491
|
||||
---
|
||||
26
.ideai/tickets/20/issue.md
Normal file
26
.ideai/tickets/20/issue.md
Normal file
@ -0,0 +1,26 @@
|
||||
---
|
||||
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é.
|
||||
6
.ideai/tickets/21/carnet.md
Normal file
6
.ideai/tickets/21/carnet.md
Normal file
@ -0,0 +1,6 @@
|
||||
---
|
||||
issueRef: "#21"
|
||||
version: 7
|
||||
updatedBy: {"kind":"user"}
|
||||
updatedAt: 1783437364397
|
||||
---
|
||||
16
.ideai/tickets/21/issue.md
Normal file
16
.ideai/tickets/21/issue.md
Normal file
@ -0,0 +1,16 @@
|
||||
---
|
||||
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.
|
||||
6
.ideai/tickets/22/carnet.md
Normal file
6
.ideai/tickets/22/carnet.md
Normal file
@ -0,0 +1,6 @@
|
||||
---
|
||||
issueRef: "#22"
|
||||
version: 5
|
||||
updatedBy: {"kind":"user"}
|
||||
updatedAt: 1783437364871
|
||||
---
|
||||
16
.ideai/tickets/22/issue.md
Normal file
16
.ideai/tickets/22/issue.md
Normal file
@ -0,0 +1,16 @@
|
||||
---
|
||||
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.
|
||||
6
.ideai/tickets/23/carnet.md
Normal file
6
.ideai/tickets/23/carnet.md
Normal file
@ -0,0 +1,6 @@
|
||||
---
|
||||
issueRef: "#23"
|
||||
version: 6
|
||||
updatedBy: {"kind":"user"}
|
||||
updatedAt: 1783437365276
|
||||
---
|
||||
16
.ideai/tickets/23/issue.md
Normal file
16
.ideai/tickets/23/issue.md
Normal file
@ -0,0 +1,16 @@
|
||||
---
|
||||
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
|
||||
25
.ideai/tickets/25/carnet.md
Normal file
25
.ideai/tickets/25/carnet.md
Normal file
@ -0,0 +1,25 @@
|
||||
---
|
||||
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.
|
||||
16
.ideai/tickets/25/issue.md
Normal file
16
.ideai/tickets/25/issue.md
Normal file
@ -0,0 +1,16 @@
|
||||
---
|
||||
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
|
||||
6
.ideai/tickets/26/carnet.md
Normal file
6
.ideai/tickets/26/carnet.md
Normal file
@ -0,0 +1,6 @@
|
||||
---
|
||||
issueRef: "#26"
|
||||
version: 6
|
||||
updatedBy: {"kind":"agent","agent_id":"a6ced819-b893-4213-b003-9e9dc79b9641"}
|
||||
updatedAt: 1783861758866
|
||||
---
|
||||
16
.ideai/tickets/26/issue.md
Normal file
16
.ideai/tickets/26/issue.md
Normal file
@ -0,0 +1,16 @@
|
||||
---
|
||||
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.
|
||||
6
.ideai/tickets/27/carnet.md
Normal file
6
.ideai/tickets/27/carnet.md
Normal file
@ -0,0 +1,6 @@
|
||||
---
|
||||
issueRef: "#27"
|
||||
version: 6
|
||||
updatedBy: {"kind":"agent","agent_id":"a6ced819-b893-4213-b003-9e9dc79b9641"}
|
||||
updatedAt: 1783926649550
|
||||
---
|
||||
16
.ideai/tickets/27/issue.md
Normal file
16
.ideai/tickets/27/issue.md
Normal file
@ -0,0 +1,16 @@
|
||||
---
|
||||
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
|
||||
6
.ideai/tickets/28/carnet.md
Normal file
6
.ideai/tickets/28/carnet.md
Normal file
@ -0,0 +1,6 @@
|
||||
---
|
||||
issueRef: "#28"
|
||||
version: 3
|
||||
updatedBy: {"kind":"user"}
|
||||
updatedAt: 1783491458775
|
||||
---
|
||||
33
.ideai/tickets/28/issue.md
Normal file
33
.ideai/tickets/28/issue.md
Normal file
@ -0,0 +1,33 @@
|
||||
---
|
||||
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.
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user