100 Commits

Author SHA1 Message Date
a3d94d4d5e fix(layout): barre supérieure CLI custom cliquable — stacking context du corps de leaf
Le corps d'une leaf (layout-leaf-body) crée désormais son propre stacking context (z-index 0). Les vues CLI custom peuvent comporter des enfants à haut z local (toolbar z-20) qui restaient au-dessus des contrôles de cellule (CELL_Z 5) et captaient les clics ; ils restent désormais sous les contrôles. Test de layering dédié ajouté dans LayoutGrid.cellControlsLayering.test.tsx.
2026-08-06 21:57:48 +02:00
bbcb303061 merge(cli): lot CLI/TUI 2026-08-06 — #168 #169 #170 (QA verte) + #155 (contrat vert, e2e AppImage fichier non-image en attente) 2026-08-06 20:00:51 +02:00
b5b360c266 chore(tickets): QA verte lot CLI/TUI #168/#169/#170 + #155 (contrat vert, e2e AppImage fichier non-image en attente) 2026-08-06 20:00:36 +02:00
8e97da57c9 fix(cli): bouton Send↔Stop #168 + collage clipboard fichier générique #155 2026-08-06 20:00:36 +02:00
292a81ee60 fix(backend): disponibilité session user + hand-off CLI↔TUI sans collision — #169 #170 2026-08-06 20:00:36 +02:00
c50b6c5388 chore(tickets): sync miroir — lot CLI/TUI #155/#168/#169/#170 (+ clôture #151/#167)
(cherry picked from commit d7c4505bacdb9bc03145f12267ae281ad6a35739)
2026-08-06 19:40:46 +02:00
31976d6ed8 fix(cli): collage presse-papiers image/fichier via clipboardData.files — #155 (partiel : logique+tests verts, e2e AppImage clipboard en attente)
(cherry picked from commit 2f39a5ce17b9895e683c0d48f0d9e034e701ed19)
2026-08-06 19:40:46 +02:00
d1e6ae1a22 chore(memory): màj note topologie cycle #151/#167/#155 (issue finale) 2026-08-06 19:16:30 +02:00
0390d18214 chore(tickets): clôture #151 #167 (QA verte) — sync miroir; #155 reste ouvert (e2e AppImage en attente) 2026-08-06 19:14:12 +02:00
9f05ad6aa6 merge(cli): intègre #151 #167 (QA verte) — z-order Cancel + projection live événements avant Final 2026-08-06 19:10:02 +02:00
b45deabe6d fix(cli): z-order Cancel #151 + projection live événements avant Final #167 (+ alignement fixture plugin #165/#166) — QA verte 2026-08-06 19:09:07 +02:00
3d4ea6859e chore(tickets): rouverture #151 #155 + création #167 — sync miroir tickets 2026-08-06 18:50:52 +02:00
e148d3cc5e chore(tickets): clôture #165 #166 + épic #161 — sync miroir tickets
#165 (seam plugin slash-commands) et #166 (dispatch e2e du callback plugin)
fermés après merge de feature/165-plugin-slash-commands dans develop.
L'épic #161 (commandes slash custom CLI) est entièrement terminé : tous ses
sous-tickets (#162 fondation, #163 autocomplete, #164 /profile, #165 seam
plugin) plus le dispatch e2e (#166) sont intégrés.
Sync du miroir local + counter (#166 créé).

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-08-06 15:47:46 +02:00
f6d2a37a97 merge(plugins): intègre feature/165 — seam #165 + dispatch e2e #166 (QA verte)
Clôture l'épic slash-commands #161 : avec le seam plugin (#165) et le dispatch
end-to-end du callback (#166), tous les sous-tickets natifs + plugin sont livrés.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-08-06 15:47:19 +02:00
b0be5f04e4 feat(cli): dispatch du callback plugin slash-command vers le runtime registry — #166 (QA verte)
Boucle le gap end-to-end de #165 : à l'exécution d'une commande slash plugin
depuis le composer custom, l'UI traite l'effet pluginCallback et le dispatche
au PluginRuntimeRegistry pour que la callback du plugin s'exécute réellement.

- runtime/registry: runCommandStrict (échec explicite si handler absent) +
  propagation de la valeur de retour ; élargit les types de retour (unknown).
- runtime/loader: chargement de contributes.slashCommands au registre +
  propagation du retour du handler.
- features/plugins/usePluginMenus: runCommand retourne unknown.
- features/agents/CustomAgentChatView: handler de l'effet pluginCallback ->
  pluginRuntime.registry.runCommandStrict, avec retour utilisateur en cas
  d'échec (commande indisponible / callback absente).

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-08-06 15:47:04 +02:00
fbaca9d5cc feat(plugins): seam slash-commands contribuées par plugin via callback — #165 (QA verte)
Permet à un plugin de contribuer des commandes slash adossées à une callback,
transitant par le registry/contrat unifié (#162) :

- sdk/IdeaSDK: manifeste contributes.slashCommands (déclaratif) — pointer bumpé.
- domain: source Plugin étendue + effet PluginCallback (la commande ne
  s'exécute pas directement : elle renvoie une référence à la callback du plugin).
- application: registration des commandes plugin dans le registry + exécution
  renvoyant l'effet PluginCallback ; métadonnées UI suffisantes pour l'autocomplete.
- backend + app-tauri: DTO + commandes Tauri listant/invoquant les commandes plugin.
- frontend (contrat): types adapters/domain/ports/mock pour pluginCallback et
  l'invocation avec arguments.

L'exécution effective de la callback côté runtime UI est livrée par #166.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-08-06 15:46:52 +02:00
ff7696b724 chore(tickets): clôture #164 (QA verte) — sync miroir tickets
#164 (/profile + reset de session confirmé) fermé après merge de
feature/164-profile-command dans develop. Sync du miroir local.
Reste #165 (seam plugins) pour clore l'épic #161.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-08-06 15:12:24 +02:00
4ebf125ec6 merge(cli): intègre feature/164-profile-command — /profile + reset confirmé #164 (QA verte)
Commande /profile first-class avec reset de session explicite et confirmé,
séparée de la palette slash générique. Dernier sous-ticket de l'épic #161
avant #165 (seam plugins).

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-08-06 15:12:07 +02:00
2cd8df4a4e feat(cli): commande /profile + sélection de profil avec reset de session confirmé — #164 (QA verte)
Ajoute /profile comme commande slash first-class dont la sémantique de reset
de session reste explicite et testable, séparée de la palette générique :

- domain + application: /profile est enregistrée et renvoie un effet
  SlashCommandEffect::ProfileSwitch { session_id }. La commande ne reset pas
  directement : elle délègue l'effet au frontend pour imposer une confirmation.
- frontend (CustomAgentChatView): à l'exécution de /profile, ouverture d'un
  popup de sélection de profil informant que la validation reset la session,
  avec confirmation explicite (confirmedReset) requise avant changeAgentProfile.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-08-06 15:12:00 +02:00
a6ba3ff6e1 chore(tickets): clôture #163 (QA verte) — sync miroir tickets
#163 (UX autocomplete slash-commands) fermé après merge de
feature/163-slash-command-autocomplete dans develop. Sync du miroir local.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-08-06 15:03:04 +02:00
c42ba63c28 merge(cli): intègre feature/163-slash-command-autocomplete — menu slash-commands #163 (QA verte)
UX d'autocomplétion slash dans le composer custom, consommant le contrat
unifié de #162 (aucune liste codée en dur). Débloque #164 (/profile).

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-08-06 15:02:49 +02:00
853d8229f2 feat(cli): menu contextuel d'autocomplétion des slash-commands dans le composer — #163 (QA verte)
À la saisie d'un « / » en début de draft (sans espace), ouverture d'un menu
contextuel listant les commandes matchant le préfixe, via le contrat unifié
listSlashCommands — aucune liste codée en dur côté UI. Rafinement incrémental
des suggestions à la frappe, navigation clavier + sélection, exécution par
executeSlashCommand.

- adapters/agent: listSlashCommands(prefix?) + executeSlashCommand (invoke Tauri).
- domain + ports: types SlashCommand / ExecuteSlashCommandResult.
- mock: données de test.
- CustomAgentChatView: détection de préfixe (/ sans espace), fetch avec séquence
  anti-retard, gestion ouverture/active index, navigation clavier, fermeture
  quand le préfixe cesse d'être éligible.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-08-06 15:02:40 +02:00
b51011d206 chore(tickets): clôture #162 (QA verte) — sync miroir tickets
#162 (fondation slash-commands) fermé après merge de
feature/162-slash-commands-foundation dans develop. Sync du miroir local.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-08-06 14:53:04 +02:00
6c558cc0af merge(slash): intègre feature/162-slash-commands-foundation — fondation commandes slash #162 (QA verte)
Contrat unifié slash-command (domain + application registry + wiring
backend/app-tauri) avec /help et /clean natifs. Débloque #163, #164, #165.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-08-06 14:52:44 +02:00
6997138a71 feat(slash): fondation du système de commandes slash pour la CLI custom — #162 (QA verte)
Introduit le contrat unifié des commandes slash consommable par le frontend,
indépendant de la source (native, puis plugin plus tard) :

- domain: modèle pur SlashCommand / SlashCommandSource / SlashCommandAvailability,
  métadonnées UI (nom, description, disponibilité, confirmation requise) et
  validation des noms/préfixes.
- application: registry + list/filter par préfixe + plan d'exécution natif ;
  commandes natives /help et /clean (/clean = nettoyage de la vue de session
  courante ; pas de /reset distinct tant qu'aucune utilité produit ne le justifie).
- backend + app-tauri: exposition du contrat via DTO/transport + tests DTO.

Source neutre : les commandes contribuées par plugins (#165) transiteront par
le même registry sans changer le contrat frontend.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-08-06 14:52:36 +02:00
4e57161e1d chore(tickets): clôture #151 #157 (QA verte) — sync miroir tickets
#151 (z-order bouton Cancel) et #157 (arrêt spinner Progress) fermés
après merge du Cluster A (fix/batch-151-157-cli-ui) dans develop.
Sync du miroir local .ideai/tickets.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-08-06 14:30:13 +02:00
102c003405 merge(ui): intègre fix/batch-151-157-cli-ui — fixes #151 #157 (Cluster A, QA verte)
#151: z-order du bouton Cancel en état busy (LayoutGrid).
#157: arrêt du spinner Progress à l'état terminal (CustomAgentChatView).

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-08-06 14:29:49 +02:00
57ced6801b fix(cli): arrêt du spinner Progress à l'état terminal — #157 (QA verte)
Ajoute completeRunningProgress() qui passe les stages started/delta à
completed lors des événements final/error. La ligne Progress conserve son
contenu statique utile mais n'affiche plus l'animation de chargement une
fois le tour terminé.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-08-06 14:29:39 +02:00
a9346476ee fix(layout): bouton Cancel en z-order propre pendant un tour agent — #151 (QA verte)
Extrait le bouton Cancel du banner inline et le rend en position absolue
(top:24, right:20) avec zIndex CELL_Z.turnActions. Le banner de statut est
décalé (right:76 en état busy) et rétrogradé en CELL_Z.banner, afin que
Cancel reste au premier plan et cliquable sans recouvrement en état busy.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-08-06 14:29:31 +02:00
0f60f625a1 chore(tickets): réouverture #151 #157 + création epic slash-commands #161–#165
Réouvre #151 (résidu z-order bouton Cancel en état busy) et #157 (suivi UX :
arrêt du spinner à l'état terminal) en statut open avec assignations.
Crée l'epic slash-commands custom CLI : #161 (ombrelle suivi produit),
#162 (fondation registry + /help + /clean), #163 (UX autocomplete / menu),
#164 (/profile + reset session confirmé), #165 (commands contribées plugins).
nextNumber 161 → 166.

Bookkeeping tickets seul (l'état runtime .ideai hors-lot reste en working
tree, non committé).

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-08-06 14:19:04 +02:00
380fefd37b chore(tickets): clôture #151 #156 #157 #160 — sync tickets/mémoire (QA verte) 2026-08-06 13:14:01 +02:00
03303aa276 fix(ui): toolbar CLI sans overlap + retrait du bouton History — #151 #160 (QA verte) 2026-08-06 13:13:30 +02:00
309c10e5e9 feat(cli): surface progression intermédiaire, activité MCP, flux agent↔agent — #157 (QA verte) 2026-08-06 13:13:24 +02:00
918116664c feat(backend): modèle unifié streaming/progress/events provider-agnostic + pont app-tauri — foundation #156 (QA verte) 2026-08-06 13:13:17 +02:00
40fa551f32 merge(chat): intègre feature/155-clipboard-paste-image — paste image clipboard dans le composer (#155, QA verte) 2026-08-06 11:01:50 +02:00
790c4755be feat(chat): #155 paste image depuis presse-papier dans le composer custom (QA verte)
- frontend: onPaste sur CustomAgentChatView, détection MIME image, chip/preview d'attachment, envoi via le contrat #154 (adapters/agent, ports)

- backend: import d'image par bytes dans le store attachments (commands, chat_attachments app+infra, dto, ports) + tests
2026-08-06 11:01:50 +02:00
88dfbfe471 merge(attachments): intègre feature/154-attachments-pipeline — fondation pipeline durable d'attachments agent/chat (#154, QA verte) 2026-08-06 10:44:15 +02:00
1c80d08f92 feat(attachments): fondation pipeline durable d'attachments agent/chat + sandbox-safe (#154, QA verte)
Socle #154 : entité attachment, store, contrat DTO et routage session. Modules : domain/chat_attachment, application/chat_attachments, infrastructure/chat_attachments, app-tauri (commands/lib), backend dto.
2026-08-06 10:44:15 +02:00
560b5ae7d1 merge(ui): intègre fix/batch-151-158-159-ui — fixes #151 #158 #159 (Lot A, QA verte) 2026-08-06 10:23:23 +02:00
c5d6c3b98e fix(ui): Lot A #151 #158 #159 (QA verte)
- #151: chevauchement des boutons dans la barre supérieure pendant une conversation agent

- #158: popup de reprise de conversation intempestive (ajout cellule / changement layout / projet)

- #159: pastille d'activité de projet
2026-08-06 10:23:23 +02:00
fb19ee48dc chore(tickets): met à jour le timestamp index.json 2026-08-05 23:44:51 +02:00
ee35c15958 chore(tickets): journalise le correctif routing chat vs PTY #149
- Met à jour le carnet avec la preuve runtime returned cellKind=pty; expected chat
- Documente les hypothèses invalidées et la nouvelle cible de correction
- Met à jour issue.md avec le titre et le diagnostic consolidés
- Incrémente le compteur et ajoute les tickets 150-158 à l'index

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-08-05 23:40:03 +02:00
937ea07df1 feat(chat): valide le routing cellKind=chat côté frontend et corrige UX
- Ajoute cellKind dans AgentChatHandle et vérifie que launchAgentChat reçoit cellKind:chat
- Rejette avec erreur STRUCTURED_ROUTED_TO_PTY si le backend route vers PTY
- Ajoute cellKind:chat dans MockAgentGateway.launchAgentChat
- Corrige l'overflow du layout CustomAgentChatView (bounded shell avec scroll + composer fixe)
- Dédouble les prompts utilisateur quand le stream les echo
- Ajoute les tests launchAgentChat returns handle only when confirms chat et launchAgentChat rejects PTY-routed launch
- Ajoute les tests does not duplicate user prompt when echoed et keeps chat shell bounded

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-08-05 23:39:50 +02:00
c43f29b2f2 feat(chat): propage l'intention chat → require_structured dans le pipeline de lancement
- Ajoute le champ cell_kind dans LaunchAgentRequestDto pour distinguer les demandes chat (custom CLI) des lancements PTY historiques
- Convertit cellKind:Chat en require_structured:true dans commands.rs et web-server/src/lib.rs
- Implémente la logique de routing structuré dans LaunchAgent::execute :
  - valide que require_structured implique un profil avec structured_adapter
  - remplace une session PTY existante quand require_structured est vrai
  - route vers structured seulement quand wants_structured est vrai
- Met à jour tous les appels historiques avec require_structured:false pour préserver le contrat PTY
- Ajoute les tests unitaires human_launcher_with_chat_intent_routes_structured_profile_to_chat_session et chat_intent_replaces_existing_pty_instead_of_returning_pty_session
- Wire les ports structured dans BackendCore pour le launcher humain

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-08-05 23:39:35 +02:00
7071c53bb2 fix(chat): handle raw structured session NOT_FOUND errors from Tauri
Elargit isNotFound() pour reconnaitre aussi la forme brute
'not found: structured session <uuid>' que Tauri peut retourner,
en plus de la forme typée {code: 'NOT_FOUND'}.

Ajoute deux tests couvrant:
- fallback sur reattach avec erreur brute
- retry prompt sur send avec erreur brute

QA: tests passés sur cette correction.
2026-08-05 16:00:37 +02:00
62ac05a080 chore(tickets): journalise le correctif session echo #149
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-08-05 15:30:08 +02:00
ce9ba0dc3d fix(chat): ignore self-emitted custom session echoes
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-08-05 15:29:03 +02:00
525ea94b09 chore(tickets): journalise le recadrage #149
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-08-05 15:23:45 +02:00
029ed97bff chore(chat): instrumentation session CustomAgentChatView pour diagnostic #149
Ajoute des points de traçage ciblés sur le cycle de vie de session
CustomAgentChatView/LayoutGrid pour isoler la cause du fallback
silencieux CLI custom avant tentative de fix.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-08-05 15:23:45 +02:00
4d8b69afca chore(tickets): recadre #149 — instrumentation ciblée CustomAgentChatView/session au lieu d'une 4e variation LayoutGrid
Consigne Architecte: le fallback custom→TUI persiste après 3 correctifs sur
LayoutGrid.tsx. Nouvelle piste non explorée: boucle d'effet sessionId dans
CustomAgentChatView.tsx (openOrAttach déclenché par son propre callback
onSessionId). Carnet mis à jour avec l'historique complet des tentatives et
la règle de traçabilité demandée par l'utilisateur.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-08-05 14:50:33 +02:00
66b9c34bc3 merge(chat): intègre feature/ticket149-reopen-frontend-refetch — stabilise CLI custom vs refetch stale (#149, QA verte)
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-08-05 14:25:03 +02:00
e9e4623ecf fix(chat): stabilise le mode CLI custom contre le refetch stale agents/profiles (#149)
Le fallback custom→TUI se redéclenchait après le premier chargement dès que
refreshProfiles() renvoyait un instant un profil pinné sans structuredAdapter
(refetch en vol), coupant la CLI custom ~0.5s après son ouverture. Introduit
un binding "trusted" (agent+profil validés) qui reste valide tant qu'aucun
changement légitime de profil n'est observé via agentProfileChanged, et ne
retombe en TUI que sur perte réelle du CLI custom.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-08-05 14:24:55 +02:00
0e2fc83689 chore(tickets): réouvre #149 — le fallback silencieux CLI custom persiste après retest
Retest utilisateur du 2026-08-05: la CLI custom s'ouvre ~0.5s puis retombe
sur Plain/TUI malgré le fix précédent. Statut repassé à open pour relancer
le cycle de diagnostic/correction.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-08-05 14:17:00 +02:00
3ae616bad9 merge(chat): intègre feature/ticket149-cache-stale-agents-profiles — fix cache stale agents/profiles (#149, QA verte)
QA verte : LayoutGrid.chat.test.tsx (7 tests), src/features/layout (16 fichiers, 130 tests).

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-08-05 14:06:27 +02:00
61055779c4 fix(chat): retarde le fallback custom→TUI tant que le catalogue agents/profiles est stale (#149)
Cause racine restante après le fix de la course au premier chargement : le
garde-fou de LayoutGrid retombait sur `tui` dès que agents/profiles semblaient
indisponibles, y compris quand le cache était simplement stale (refresh en
cours), écrasant silencieusement la préférence custom. Le fallback n'agit
désormais qu'une fois le catalogue confirmé à jour.

QA verte : LayoutGrid.chat.test.tsx (7 tests), src/features/layout (16
fichiers, 130 tests), cas ciblé "stale catalog refresh".

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-08-05 14:06:18 +02:00
fa518415c6 merge(chat): intègre feature/ticket149-custom-cli-silent-fallback — fix fallback silencieux CLI custom → Plain (#149, QA verte)
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-08-05 13:48:35 +02:00
0103a8acf6 chore(tickets): clôture #149 — QA verte sur feature/ticket149-custom-cli-silent-fallback
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-08-05 13:48:30 +02:00
dedc3b5134 test(chat): couvre le fallback TUI si le catalogue invalide le profil pinné (#149)
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-08-05 13:48:27 +02:00
51bda20455 fix(chat): preserve custom CLI preference during catalog load (#149)
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-08-05 13:45:41 +02:00
9d18d01380 chore(tickets): ouvre le ticket #149 (fallback silencieux CLI custom → Plain)
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-08-05 13:41:30 +02:00
ecad746c66 chore(tickets): synchronise les statuts tickets et l'état plugin android
Rattrapage de l'état runtime .ideai/ (tickets #119-#139/#147 clôturés,
compteur→149, ticket #148 clos et QA verte, métadonnées plugin android) —
séparé du code de feature avant d'ouvrir le travail sur le nouveau bug
de lancement CLI custom.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-08-05 13:40:44 +02:00
00a2eaaa16 merge(chat): intègre fix/ticket148-structured-session-not-found — relance propre sur reattach mort (#148, QA verte)
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-08-05 13:17:39 +02:00
e80f7631ff fix(chat): relance propre au lieu de re-tenter l'attach sur une session structurée morte (#148)
Sur reattach NOT_FOUND, le composant retentait implicitement l'attach sur le
même sessionId mort au lieu de nettoyer l'état avant de relancer, ce qui
produisait l'erreur "not found: structured session …" côté utilisateur.
recoverStructuredSession() nettoie désormais sessionId/conversationId avant
de relancer et retente une seule fois le reattach sur NOT_FOUND post-launch.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-08-05 13:17:31 +02:00
fab172094a merge(chat): intègre fix/ticket147-structured-session-reattach-fallback — fallback fresh launch sur reattach mort (#147, QA verte)
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-08-05 12:11:46 +02:00
b37542107a fix(chat): fallback vers un nouveau lancement quand la session structurée reattach est morte (#147)
reattachAgentChat pouvait échouer avec NOT_FOUND (session structurée fermée
ou jamais vivante) et laisser fuiter l'erreur brute jusqu'à l'utilisateur
("not found: structured session ... not found") au lieu de relancer une
session fraîche. Le fallback ne s'applique qu'au code NOT_FOUND ; toute
autre erreur de reattach continue de remonter telle quelle.

QA vert 2026-08-05 : npx vitest run CustomAgentChatView.test.tsx,
npx vitest run agents.test.tsx CustomAgentChatView.test.tsx, npm run typecheck.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-08-05 12:11:38 +02:00
c0764d6a0c merge(orchestrator): intègre feature/ticket147-custom-chat-cli — CLI custom de chat agent (#147, QA verte)
Livraison complète : toggle TUI/CLI custom par cellule, socle backend
AgentSession/ChatBridge, et correctif du bouton Cancel (interruption du
tour courant au lieu de fermer la session). QA a validé en vert après
le correctif frontend ciblé.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-08-05 12:00:05 +02:00
dcba76b871 feat(chat): livre la CLI custom de chat agent (#147) et corrige Cancel
Implémente la vue chat structurée par cellule agent (toggle TUI/CLI custom,
préférence persistée `preferred_view`, reattach live, composer + pièces
jointes) avec le socle backend AgentSession/ChatBridge (UserPrompt,
cancel_current_turn, routage interrupt_agent, commande cancel_agent_chat).

Corrige le bug bloquant relevé par QA : le bouton Cancel de
CustomAgentChatView interrompait tout le tour via closeAgentChat au lieu
de n'annuler que le tour courant via cancelAgentChat, ce qui tuait la
session contrairement au contrat produit validé.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-08-05 11:59:39 +02:00
efbd56a149 chore(tickets): sync carnets/issues #102/#141-#147 + agent glmopencode
Rebase de l'état ticket (réouverture #102, clôtures #141-146, ouverture
#147) et ajout du contexte agent glmopencode avant démarrage du cycle #147.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-08-04 23:57:30 +02:00
1c53ee09ef merge(orchestrator): intègre feature/fix-ask-agents-background-task-store — fix background task store (idea_ask_agents, tests verts)
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-08-04 12:26:38 +02:00
c1267bf880 fix(infrastructure): corrige le background task store utilisé par idea_ask_agents
Le store de tâches d'arrière-plan produisait un état incohérent lors de la
délégation multi-agent via idea_ask_agents. Tests ciblés ajoutés/étendus,
suite verte.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-08-04 12:26:33 +02:00
d997aba288 merge(orchestrator): intègre feature/glm-opencode-delegation-fix — fix délégation GLM/OpenCode (QA verte)
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-08-04 09:50:06 +02:00
b88d500d89 fix(orchestrator): corrige la delegation inter-agent GLM/OpenCode sans reponse Final
La detection d'absence de reponse structuree finale (structured_no_reply_error)
ne couvrait pas AgentSessionError::Decode ni le message "aucun final textuel
exploitable" emis par l'adaptateur OpenCode, ce qui laissait idea_ask_agent
planter silencieusement sur les profils GLM/OpenCode au lieu de retomber sur
le chemin de secours prevu.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-08-04 09:50:02 +02:00
11c405efea merge(window): intègre feature/plugin-hosted-windows — fenêtres plugin-hébergées #142-146 (vert QA)
Backend (window usecases + commande Tauri), frontend (host de fenêtre +
services.windows.open), runtime SDK (react/react-dom résolus vers l'host) et
documentation SDK restructurée. QA verte (cargo + vitest + typecheck + build
+ sdk check) ; réserve non bloquante : pas d'e2e natif clic sous-menu ->
fenêtre OS.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-08-04 00:40:16 +02:00
5a64e7fd5b chore(sdk): pointe le submodule sur develop (post-merge feature/plugin-hosted-windows)
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-08-04 00:40:16 +02:00
13bad558ba chore(tickets): synchronise carnets/statuts #142-146 (QA verte) + bump IdeaSDK
QA verte sur feature/plugin-hosted-windows : cargo (domain/application/
infrastructure/app-tauri), frontend (vitest/typecheck/build), sdk npm check.
Réserve non bloquante : pas d'e2e natif complet clic sous-menu -> fenêtre OS.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-08-04 00:39:57 +02:00
d8df466fba feat(frontend): host les fenêtres plugin et l'API publique windows.open
Ajoute la vue window host qui charge le layout plugin dans une fenêtre OS
détachée, expose react/react-dom/jsx-runtime hébergés sous
frontend/public/plugin-host pour que le runtime SDK y résolve React, et
câble services.windows.open() côté runtime plugin (loader/services/registry).

npm test -- --run src/adapters/window.test.ts src/app/ViewWindow.test.tsx
  src/plugins/runtime/loader.test.ts src/plugins/runtime/services.test.ts : 39/39
npm run typecheck : OK
npm run build : OK

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-08-04 00:39:50 +02:00
551eb09ad2 feat(window): support des fenêtres plugin-hébergées (backend)
Étend le port/usecases window et layout.customPluginLayout pour ouvrir et
piloter des fenêtres OS hébergeant un layout plugin, en réutilisant
contributes.layouts plutôt qu'un système de fenêtres parallèle. Câble la
commande Tauri et l'état app-tauri correspondants.

Cargo test -p domain --test window : 5/5
Cargo test -p application --test window_usecases : 7/7
Cargo test -p infrastructure --test window_state_store : 1/1
Cargo test -p app-tauri view_window_tests : 8/8

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-08-04 00:39:42 +02:00
3ea1d58b38 chore(ideai): sync tickets #142-146 (SDK plugin windows) + contexte git + bump IdeaSDK
Enregistre le cadrage du programme fenêtres plugin-hébergées (#142 backend,
#143 frontend host + windows.open, #144 runtime React partagé, #145 docs SDK,
#146 QA) et met à jour le contexte de l'agent Git avec le modèle de branches
git-flow simplifié.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-08-04 00:10:00 +02:00
78dc888bd9 merge(layout): intègre ticket141-plugin-layout-create-support — création de layouts plugins (vert QA) 2026-08-03 18:34:24 +02:00
45617992ef feat(layout): supporte la création de layouts plugins (customPluginLayout)
Étend le flux de création de layout backend (DTO, usecases, store) et le
frontend (sélecteur, adaptateurs, LayoutTabs/LayoutGrid) pour permettre
d'ouvrir un layout déclaré par un plugin installé (ex. Android Health),
sans passer par le message bloquant "extension backend pas encore livrée".

Ticket #141 — QA vert.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-08-03 18:34:21 +02:00
168f93df78 merge(context): intègre fix-context-read-canonical-path — idea_context_read pointe .ideai/CONTEXT.md (vert QA) 2026-08-03 14:58:30 +02:00
70712a35f8 fix(context): route idea_context_read vers .ideai/CONTEXT.md au lieu de CLAUDE.md
La lecture du contexte projet global via MCP (idea_context_read sans target)
lisait <root>/CLAUDE.md au lieu de la source de vérité canonique
<root>/.ideai/CONTEXT.md, désynchronisant la lecture MCP de
crates/application/src/project/context.rs. ReadContext, UpdateProjectContext
et ProposeContext partagent désormais project_context_path/project_context_dir,
avec création du dossier .ideai/ à l'écriture et lecture tolérante à l'absence
du fichier (FsError::NotFound -> contenu vide).

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-08-03 14:58:22 +02:00
3fa9691cd6 merge(batch): intègre plugin-activation-scope-loading — chargement du scope d'activation des plugins (vert QA) 2026-08-03 14:44:23 +02:00
6a86b3ad80 chore(ideai): sync tickets #43/#140 + skills index + agent context
Ticket #43 carnet reflects activationScope in the plugin manifest
example; ticket #140 closed; skills index/content refreshed.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-08-03 14:44:12 +02:00
e2da2d911e feat(plugins): load activation scope from plugin manifest
Plugins can now declare activationScope ("app" | "project") in their
manifest; loader/runtime honor it to defer activation of project-scoped
plugins until a project is focused instead of activating everything at
app bootstrap. Bumps sdk/IdeaSDK to the commit that adds the field.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-08-03 14:44:08 +02:00
863d9b7277 fix(agents): unwrap read_agent_context DTO content (#140)
Le contexte projet d'un agent s'affichait "[object Object]" et se
vidait à la réouverture du panneau : read_agent_context renvoie déjà
{content} côté backend, mais les gateways front traitaient la réponse
comme une string brute. Les deux gateways (Tauri + HTTP) unwrap
maintenant .content ; type AgentContextDocument ajouté au domaine.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-08-03 14:35:36 +02:00
cf61060ffb chore(tickets): sync statuts/carnets #113/#119/#120/#122/#131/#132 + bump IdeaSDK ESM (#134/#139)
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-08-03 12:44:20 +02:00
59d81851e9 chore(tickets): synchronise index/carnets tickets #131-#139 + note mémoire assets/persistance plugins
État runtime .ideai séparé du code (index, counter, carnets, note mémoire
plugin-asset-serving-and-owned-storage-contracts). Purge des tickets obsolètes
51/63/66.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-08-03 11:06:30 +02:00
171c6c923c feat(wave): #119/#122/#131/#132 verts + sprint plugins ESM/persistance #135/#136/#139
État d'intégration confiné à la branche batch. Les tickets #119 (skills →
capacités agent découvrables), #122 (override permissions par défaut), #131
(effort par agent/presets) et #132 (outil MCP d'édition du contexte projet)
sont verts en périmètre. Le sprint plugins multi-fichiers ESM / persistance
plugin-owned (#135/#136/#139) est co-implémenté dans les MÊMES fichiers de
câblage (frontend/src/ports/index.ts, backend/src/lib.rs, domain/ports.rs,
backend/dto.rs), inséparable sans staging interactif (indisponible ici).

Commit unique volontaire : préserve l'état vert QA sans découpe hunk risquée.
NON mergé vers develop tant que #137 (QA e2e plugins) n'est pas vert.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-08-03 11:06:23 +02:00
7497fe19aa merge: intègre #113 — champ args llamacpp ne capture plus les frappes (vert QA)
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-08-03 10:51:55 +02:00
0a52005afb fix(model-servers): empêche la capture des touches dans le champ args du serveur llamacpp (#113)
Les espaces et autres frappes étaient interceptés par un handler parent ;
stopPropagation sur le onKeyDown de l'input args laisse la saisie intacte.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-08-03 10:51:47 +02:00
22c6bd803d merge(batch): intègre #134 — service confiné multi-fichiers ESM (vert QA)
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-08-03 00:02:11 +02:00
71d08795d9 feat(plugins): sert tout fichier confiné du package installé (multi-fichiers ESM) (#134)
Implémente §22.1 : asset_allowed autorise tout chemin relatif dès lors que
les gardes déjà en place sont satisfaites (entrée registre active,
content_hash du package, confinement canonicalize en aval), au lieu de
restreindre au triplet main/icon/assets. Débloque les imports ESM
multi-fichiers (./constants.js, ./core/x.js) sans affaiblir le modèle de
menace fixé à l'install (#135).

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-08-02 23:47:41 +02:00
2f1d99c5e1 merge(batch): intègre #138 — §22.2 persistance plugin-owned hors projet
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-08-02 22:52:18 +02:00
a5e56885d9 docs(architecture): §22.2 — persistance plugin-owned hors projet & purge à la désinstallation (#138)
Cadrage architecture du ticket #138 : séparation project-owned/plugin-owned,
API canonique ctx.storage seule, stockage sous app_data/plugins/data/<id>/
(frère de installed/), purge intégrale à l'uninstall. Débloque #139.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-08-02 22:52:13 +02:00
1b9915c229 merge(batch): intègre #133 — §22.1 contrat de service des assets multi-fichiers ESM
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-08-02 22:52:00 +02:00
fa474ae97f docs(architecture): §22.1 — contrat de service des assets idea-plugin:// multi-fichiers ESM (#133)
Cadrage architecture du ticket #133 : asset_allowed autorise tout chemin
relatif confiné dès lors que registre actif + content_hash + confinement
canonicalize sont satisfaits, sans gater fichier par fichier. Débloque
#134/#135.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-08-02 22:51:53 +02:00
7c2bd227d2 fix: Codex PTY launch forwards profile model as argv override
- injecte model et model_reasoning_effort du profil via -c dans argv
- remplace le modèle TUI stale en config.toml
- aligne PTY/interactif sur le comportement déjà garanti par CodexExecSession
- test unitaire codex_pty_launch_forwards_profile_model_as_config_override
2026-08-02 18:02:00 +02:00
dcc7a6f216 fix: project model and reasoning_effort into Codex CLI args, stop rewriting .codex/config.toml
- Add model_reasoning_effort field to AgentProfile (domain layer)
- Remove model parameter from codex_config_toml, stop rewriting model in TOML
- Pass model and model_reasoning_effort via Codex CLI -c overrides on every exec
- Update CodexExecSession with new_with_policy_and_overrides factory
- Cover new conversation and resume flows with tests
2026-08-02 17:19:26 +02:00
b730e356aa refactor(sdk): remplace dépôt imbriqué par git submodule
- Convertit sdk/IdeaSDK en git submodule pointant vers IdeaSDK dédié
- Nettoie les artefacts du dépôt git imbriqué (.git.disabled-empty-nested-repo)
- Le SDK TypeScript plugin est maintenant dans son propre repo

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-08-02 16:33:50 +02:00
321 changed files with 19900 additions and 4307 deletions

4
.gitignore vendored
View File

@ -73,3 +73,7 @@ Thumbs.db
.ideai/agents.json
.ideai/background-tasks/
.ideai/mcp-tool-permissions.json
# QA isolated cargo home/target (never commit)
.qa-cargo-home/
.qa-cargo-target/

3
.gitmodules vendored Normal file
View File

@ -0,0 +1,3 @@
[submodule "sdk/IdeaSDK"]
path = sdk/IdeaSDK
url = https://gitea.anthonybouteiller.ovh/blomios/IdeaSDK.git

View File

@ -1,16 +1,15 @@
# Git — Agent de gestion du dépôt git local
> Tu es l'**agent Git** d'IdeA. Ta responsabilité est la **gestion du dépôt
> git local** : commits de l'application, création et bascule de
> branches, merges, rebases. Tu es le **seul**
> à décider de la topologie des branches et à manipuler l'historique. Main te
> sollicite ; tu décides et tu exécutes.
> Tu es l'**agent Git** d'IdeA. Ton unique responsabilité est la **gestion du dépôt
> git local** : commits de l'application, création et bascule de branches, merges et
> rebases. Tu es le **seul** à décider de la topologie des branches et à manipuler
> l'historique local. Main te sollicite ; tu décides et tu exécutes.
---
## 1. Ton rôle (et ses limites)
Tu t'occupes **du repo git local** :
Tu t'occupes **du local du repo git**, rien d'autre :
- **Commits** : tu transformes le travail réalisé par les agents de dev en commits
propres, atomiques, au bon endroit (bonne branche), avec des messages cohérents.
@ -20,16 +19,14 @@ Tu t'occupes **du repo git local** :
- Tu **décides** : quand Main t'annonce une nouvelle feature (après cadrage Architect),
c'est **toi** qui tranches s'il faut une nouvelle branche, un checkout/switch, ou rien.
Après chaque implémentation, Main revient vers toi pour que tu décides si un **merge**
doit avoir lieu, ou non.
doit avoir lieu quelque part, ou non.
**Hors périmètre / garde-fous :**
**Hors périmètre :**
- Tu **n'écris pas de code de feature** (c'est DevBackend/DevFrontend).
- Tu ne fais **aucune action sortante** (`push`, publication, création de PR distante)
sans validation explicite de Main / de l'utilisateur. Ton terrain est **local**.
- Tu ne prends pas de décision produit/archi : si un choix dépend de l'architecture,
tu remontes à Main.
- **Aucune action sortante** : tu ne **pousses pas** vers un remote (pas de `git push`),
tu ne crées pas de PR distante, tu ne publies pas de tags. La synchronisation avec un
remote n'est pas dans ton périmètre. Tu restes **strictement local**.
- **Jamais** de réécriture destructive de l'historique sans validation explicite de Main.
---
@ -37,7 +34,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.
@ -55,6 +52,7 @@ feature/* ← une branche PAR nouvelle feature. C'est là que le dev se fait.
> Si le dépôt ne possède pas encore `main`/`develop`, c'est à toi de les établir
> proprement (création de `develop` depuis `main`) lors de ta première sollicitation.
> A chaque feature ou fix demandé, vérifier qu'il n'y a pas une branche non mergée dans develop qui peut être intéressante de laquelle repartir ou a merge sur la nouvelle branche créée depuis develop.
---
@ -62,7 +60,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,24 +105,21 @@ tu le dis.
---
## 5. Sous-repos Git imbriqués
## 5. Délégation & collaboration
- 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.
- Tu réponds à Main via le protocole d'orchestration IdeA (`idea_reply`). Quand Main te
délègue une tâche (message `[IdeA · tâche de … · ticket …]`), tu traites puis tu
appelles **impérativement** `idea_reply(result=…)`.
- Tu rends compte clairement : branche courante, ce que tu as committé (hash + message
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.
---
## 6. Délégation & collaboration
## 6. Les répos
- 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
de ticket et tu n'appelles pas d'outil de remise de résultat.
- Tu rends compte clairement : branche courante, ce que tu as committé (hash + message
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.
- Tu as au total deux repo à gérer. Le premier qui est le superrepo, à la racine du projet.
- Le second est un subrepo présent dans le dossier <root project>/sdk/IdeaSDK qui est le SDK de création de plugin de IdeA.
- Tu dois gérer ces deux repo.

View File

103
.ideai/agents/test-2.md Normal file
View File

@ -0,0 +1,103 @@
# Main — Agent orchestrateur
> Tu es **Main**, l'agent chef d'orchestre du projet. Ton rôle est de **piloter les
> agents spécialisés**, pas d'écrire le code applicatif toi-même. Tu découpes, tu
> délègues, tu relaies les résultats, tu arbitres le produit et tu garantis le cycle.
---
## 1. Règle centrale : tu ne codes pas
Tu **n'implémentes pas les features** et tu ne corriges pas toi-même le code de production.
Tu peux lire le projet, analyser, découper le travail, mettre à jour les contextes et
mémoires, lancer des commandes de vérification et relayer les résultats. Pour toute
feature ou correction applicative, tu passes par les agents spécialisés :
- **UX** pour la conception des surfaces, parcours et libellés.
- **Architect** pour l'architecture, les ports, contrats, DTO, frontières et impacts.
- **Git** pour la branche, les commits et les merges locaux.
- **DevBackend** pour le code côté serveur/domaine/données.
- **DevFrontend** pour le code d'interface.
- **QA** pour écrire et exécuter les tests, et produire les rapports d'échec.
**Exception limitée** : tu peux modifier toi-même les fichiers de contexte, de mémoire,
la documentation de pilotage et la configuration d'orchestration quand la demande porte
précisément là-dessus.
---
## 2. Délégation
Pour déléguer, utilise uniquement les outils d'orchestration natifs de l'IDE
(lister les agents, confier une tâche, lancer ou rattacher un agent). N'utilise jamais
les subagents natifs du fournisseur IA pour ce projet.
Quand tu es sollicité via une conversation inter-agent headless, traite la demande et
termine ton tour avec ta réponse normale : la réponse finale est capturée
automatiquement et transmise au demandeur. N'invente pas de protocole de ticket et
n'appelle pas d'outil de remise de résultat.
---
## 3. Cycle obligatoire de développement
Pour chaque feature ou correction applicative :
```text
1. UX conçoit la surface, dès qu'il y a de l'UI.
2. Architect cadre ou valide l'architecture et les contrats.
3. Git décide de la branche de travail locale.
4. DevBackend et/ou DevFrontend implémente selon le périmètre.
5. QA écrit et exécute les tests pertinents.
6. Si tests KO : tu relaies le rapport réel au dev concerné, puis retour QA.
7. Si tests OK : tu demandes à Git de committer et de décider du merge local éventuel.
```
**Aucune feature n'est terminée sans sortie de test verte réelle.** Si un test échoue,
relaie la commande, la sortie et le diagnostic **sans enjoliver**.
**Quand solliciter UX — la règle.** Dès qu'une demande touche ce que l'utilisateur voit,
lit ou manipule : nouvelle surface, écran, menu, libellé, message d'erreur, parcours,
responsive. Ne dessine pas l'UI à sa place pour « gagner du temps » et ne la laisse pas
tomber par défaut dans les mains d'un dev. UX passe **avant** Architect quand la forme
conditionne les contrats, et **avec** lui quand une contrainte technique borne la
conception. UX ne bloque pas les lots sans surface utilisateur.
---
## 4. Répartition des responsabilités
Tu arbitres les décisions produit et de pilotage, mais **tu ne remplaces jamais un agent
spécialisé dans son domaine** :
- **UX** est propriétaire de la forme : surfaces, navigation, libellés, hiérarchie de
l'information, formulation des erreurs, parcours.
- **Architect** est propriétaire des frontières techniques : architecture, ports/adapters,
contrats, DTO, modules, invariants, cartographie. Si un choix touche ces frontières,
demande-lui d'abord.
- **DevBackend** et **DevFrontend** implémentent dans le respect de ces contrats.
- **QA** ne valide que sur preuve par commande réelle.
- **Git** est propriétaire de la topologie locale du dépôt. **Ne demande pas à
l'utilisateur s'il faut brancher, committer ou merger** : sollicite Git, qui tranche.
Aucune action sortante (push, publication, PR distante) sans validation explicite
de l'utilisateur.
---
## 5. Décisions et garde-fous
Tu peux agir de façon autonome dans le project root pour lire, organiser, lancer les
commandes de dev/test et mettre à jour les contextes. Les actions **destructrices,
hors-projet ou sortantes** restent interdites sans validation explicite.
Si la demande de l'utilisateur contredit le cycle, rappelle brièvement la règle et
applique le cycle.
Si le contexte d'un agent manque une consigne qui relève de son rôle, **mets à jour ce
contexte** au lieu de gonfler le tien. Ton contexte reste celui du pilotage ; les détails
d'architecture, de conception et de test appartiennent aux agents propriétaires.
Si une réflexion est récurrente et aboutit toujours à la même solution, créés en un skill réutilisable
Mets a jours le status des tickets que tu traites in progress, closed, QA

116
.ideai/agents/test.md Normal file
View File

@ -0,0 +1,116 @@
# Git — Agent de gestion du dépôt git local
> Tu es l'**agent Git** d'IdeA. Ton unique responsabilité est la **gestion du dépôt
> git local** : commits de l'application, création et bascule de branches, merges et
> rebases. Tu es le **seul** à décider de la topologie des branches et à manipuler
> l'historique local. Main te sollicite ; tu décides et tu exécutes.
---
## 1. Ton rôle (et ses limites)
Tu t'occupes **du local du repo git**, rien d'autre :
- **Commits** : tu transformes le travail réalisé par les agents de dev en commits
propres, atomiques, au bon endroit (bonne branche), avec des messages cohérents.
- **Branches** : tu **crées, checkout, switch** les branches selon ce qui est en cours.
- **Intégration** : tu **merges** et **rebases** les branches entre elles selon le
modèle ci-dessous.
- Tu **décides** : quand Main t'annonce une nouvelle feature (après cadrage Architect),
c'est **toi** qui tranches s'il faut une nouvelle branche, un checkout/switch, ou rien.
Après chaque implémentation, Main revient vers toi pour que tu décides si un **merge**
doit avoir lieu quelque part, ou non.
**Hors périmètre :**
- Tu **n'écris pas de code de feature** (c'est DevBackend/DevFrontend).
- Tu ne fais **aucune action sortante** (`push`, publication, création de PR distante)
sans validation explicite de Main / de l'utilisateur. Ton terrain est **local**.
- Tu ne prends pas de décision produit/archi : si un choix dépend de l'architecture,
tu remontes à Main.
---
## 2. Modèle de branches (git-flow simplifié)
Le dépôt s'articule autour de trois niveaux :
```
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.
feature/* ← une branche PAR nouvelle feature. C'est là que le dev se fait.
```
- **`main`** : reçoit uniquement des releases (merge depuis `develop` quand on décide
de livrer). Jamais de dev direct.
- **`develop`** : base d'intégration. Toute feature terminée (tests verts) y est mergée.
C'est le point de départ de chaque nouvelle branche de feature.
- **`feature/<nom-court>`** : une branche par feature, créée **depuis `develop`**. Nom
dérivé du sujet de la feature (ex. `feature/sandbox-allow-fallback`,
`feature/sidebar-tabs-responsive`).
> Si le dépôt ne possède pas encore `main`/`develop`, c'est à toi de les établir
> proprement (création de `develop` depuis `main`) lors de ta première sollicitation.
---
## 3. Le cycle, vu de Git
Tu interviens à **deux moments** du cycle de dev (cf. CLAUDE.md §3), encadré par Main :
```
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
- reprise/extension d'un travail en cours → rester / switch sur la branche existante
- simple correctif sur une feature vivante → rester sur sa branche
→ tu annonces à Main sur quelle branche le dev va se faire.
2. Dev (DevBackend/DevFrontend) + Test (QA) implémentent sur cette branche.
3. Implémentation terminée → Main revient vers TOI :
→ committer le travail (commits atomiques, message clair) sur la branche de feature.
→ décider d'un éventuel merge :
- feature TERMINÉE et VERTE → merge feature/X → develop
(rebase préalable sur develop si l'historique a divergé, pour rester linéaire),
puis suppression de la branche de feature si plus utile.
- feature pas finie / tests KO → on NE merge PAS, on reste sur feature/X.
- décision de release → merge develop → main (sur validation explicite).
```
**Règle d'or partagée** : aucune feature n'est mergée dans `develop` tant que ses
**tests ne passent pas**. Si on te demande de merger une feature rouge, tu refuses et
tu le dis.
---
## 4. Conventions
- **Messages de commit** : en **français**, style Conventional Commits cohérent avec
l'historique : `feat(scope): …`, `fix(scope): …`, `chore(scope): …`, `docs(scope): …`,
`refactor(scope): …`. Corps multi-ligne expliquant le **pourquoi** quand utile.
- **Atomicité** : un commit = une intention cohérente. Tu sépares le code de feature de
l'état runtime (`.ideai/` conversations, layouts, manifestes) et des docs.
- **Co-author** : termine les messages de commit par
`Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>` (convention de l'environnement).
- **Branches** : `feature/<kebab-case>`, dérivé du sujet. Pas d'espaces, pas de majuscules.
- **Historique linéaire** privilégié sur les features : **rebase** avant merge quand la
base a avancé ; merge `--no-ff` vers `develop`/`main` pour garder la trace de
l'intégration de la feature.
- **Pas d'interactif** : pas de `rebase -i` / `add -i` (non supportés dans l'environnement).
- **Jamais** d'action destructive hors-projet ni de réécriture d'historique déjà poussé
sans validation explicite.
---
## 5. Délégation & collaboration
- Tu réponds à Main via le protocole d'orchestration IdeA (`idea_reply`). Quand Main te
délègue une tâche (message `[IdeA · tâche de … · ticket …]`), tu traites puis tu
appelles **impérativement** `idea_reply(result=…)`.
- Tu rends compte clairement : branche courante, ce que tu as committé (hash + message
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.

View File

@ -0,0 +1,30 @@
{
"lastContext": {
"lastCommandId": "idea-android.adbDevices",
"lastDiagnosticSeverity": "warning",
"probableAppModule": null,
"projectId": "97b49ac2-8376-4aa3-8ea9-bf3ac81d0023",
"projectRoot": "/home/anthony/Documents/Projects/IdeA",
"updatedAt": "2026-08-06T09:47:45.004Z"
},
"ownerAgentId": null,
"ownerAgentMapping": {},
"refresh": {
"onActivate": true,
"watchWorkspace": true
},
"schemaVersion": 1,
"selection": {
"activeModulePath": "android/app",
"debugApkPathByModule": {},
"selectedDeviceSerial": null
},
"toolchain": {
"adbPath": null,
"androidSdkPath": null,
"emulatorPath": null
},
"ui": {
"showDebugActions": true
}
}

View File

@ -77,3 +77,6 @@
- [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
- [plugin-asset-serving-and-owned-storage-contracts](plugin-asset-serving-and-owned-storage-contracts.md) — memory note plugin-asset-serving-and-owned-storage-contracts
- [ticket156-reply-progress-foundation](ticket156-reply-progress-foundation.md) — memory note ticket156-reply-progress-foundation
- [cycle-151-167-155-git-topology](cycle-151-167-155-git-topology.md) — memory note cycle-151-167-155-git-topology

View File

@ -0,0 +1,33 @@
---
name: cycle-151-167-155-git-topology
description: memory note cycle-151-167-155-git-topology
metadata:
type: project
---
# Cycle correctif #151 #167 #155 — topologie Git (RÉSOLU)
Cycle groupé custom CLI. Décision Git rendue/exécutée le 2026-08-06.
## Issue finale
- **#151 (z-order Cancel) : CLOSED** — mergé dans develop, QA verte.
- **#167 (ordre événements avant Final) : CLOSED** — mergé dans develop, QA verte (backend `codex_send_with_tap...ok` + frontend 38/38 confirmés sur develop).
- **#155 (clipboard paste) : OUVERT** — partiel. Logique+tests verts, mais e2e presse-papiers natif Tauri/AppImage non validable dans l'env. Code NON mergé dans develop.
## Commits
- `3d4ea685` chore(tickets): rouverture #151 #155 + création #167 (sur develop, début cycle)
- `b45deabe` **C1** fix(cli): z-order Cancel #151 + projection live événements #167 (+ résidu fixture #165/#166) — QA verte → **mergé**
- `388de4b8` **C2** fix(cli): collage presse-papiers clipboardData.files #155 (partiel) → **non mergé**
- `9f05ad6a` merge(cli): intègre #151 #167 (QA verte) — --no-ff sur develop
- `0390d182` chore(tickets): clôture #151 #167 — sync miroir
## Branches
- `develop` : intègre #151 #167 (pas #155). En avance sur origin/develop, **pas de push**.
- `fix/cycle-151-167-155-custom-cli` : ramenée à C1 (b45deabe), mergée dans develop.
- `wip/155-clipboard-paste-e2e` : préserve C1+C2 (388de4b8) → porte le code #155 pour le cycle de clôture e2e AppImage.
## Point de clôture #155
Valider le collage presse-papiers image/fichier sur l'AppImage réelle. Reprendre depuis `wip/155-clipboard-paste-e2e`.
## Notes
- `reset --hard` a révoqué hors-cycle les modifs miroir disque non committées (carnets QA, `.ideai/idea-android-plugin.json`) ; le store IdeA reste source de vérité, miroirs resyncés à la clôture. La modif 1-ligne `idea-android-plugin.json` (propriétaire inconnu) a été perdue du working tree — à refaire si besoin.
- Le toolchain Rust du shell n'a pas de default ; backend confirmé via cargo nightly sous `.ideai/run/<agent>/.opencode/.rustup`.

View File

@ -0,0 +1,19 @@
---
name: plugin-asset-serving-and-owned-storage-contracts
description: memory note plugin-asset-serving-and-owned-storage-contracts
metadata:
type: project
---
# Contrats plugins #133/#138 : service d'assets multi-fichiers + persistance plugin-owned hors projet
Décisions figées dans `ARCHITECTURE.md` §22 (2026-08-02).
## #133 — service des assets `idea-plugin://`
`asset_allowed` (`crates/app-tauri/src/plugins.rs:504-536`) doit servir tout chemin relatif confiné dès lors que les gardes déjà présentes tiennent : registre actif (`lifecycle_state.is_runtime_active()`) + `content_hash` du package matché + confinement canonicalize (déjà en place lignes 467-483). Fin de l'allowlist `declared_main || declared_icon || starts_with("assets/")` qui cassait tout import ESM relatif secondaire (`./constants.js`, `./core/x.js`) → "Importing a module script failed.". Pas de résolution `node_modules`/bare specifiers — hors scope, figé. Débloque #134 (implémentation) et #135 (audit confinement install + désinstallation 100%).
## #138 — persistance plugin-owned
`ctx.storage` (déjà typé dans `sdk/IdeaSDK/src/runtime.ts`, jamais câblé côté `frontend/src/plugins/runtime/loader.ts` ni implémenté côté Rust — vérifié : zéro port/commande/répertoire) devient l'API canonique unique pour l'état interne du plugin (prefs/cache/index). Nouveau répertoire `app_data/plugins/data/<pluginId>/`, frère de `plugins/installed/<pluginId>/` (jamais dedans, pour survivre aux réinstalls et donner une racine univoque à purger). `plugin_uninstall` doit purger les deux répertoires. `ctx.services.config`/`workspace` restent réservés au project-owned (fichiers réels du projet, jamais l'état interne du plugin). L'exemple `hello-plugin` doit migrer ses compteurs internes de `.ideai/hello-plugin.json` vers `ctx.storage`. Débloque #139.
Détail complet et rationale : `ARCHITECTURE.md` §22. Tickets liés : #133/#134/#135 (assets), #138/#139 (storage). Les deux tickets #133/#138 sont passés en `QA` avec carnet détaillé.

View File

@ -0,0 +1,20 @@
---
name: ticket156-reply-progress-foundation
description: memory note ticket156-reply-progress-foundation
metadata:
type: project
---
# Ticket #156 — foundation canonique ReplyProgress
Type: reference
Phase 2 du cycle CLI custom a pose le contrat backend canonique des evenements intermediaires avant `Final`.
Decisions livrees :
- Domaine : `ReplyProgress` + `ReplyProgressSource` (`ProviderNative` vs `IdeaLocal`) + `ReplyProgressKind` (`Turn`, `Message`, `Tool`, `Mcp`, `Other`) + `ReplyProgressStage` (`Started`, `Delta`, `Completed`, `Info`) dans `domain::ports`.
- `ReplyEvent::Progress { progress }` est explicitement non terminal ; `ReadinessPolicy` et les drains applicatifs continuent de donner autorite uniquement a `ReplyEvent::Final` pour la fin de tour. `RateLimited` reste orthogonal/non terminal.
- DTO transport : `ReplyChunk::Progress { progress }` avec shape JSON camelCase, additive par rapport aux anciens chunks.
- `agent_send` utilise maintenant `AgentSession::send_with_tap` pour projeter best-effort les progress pendant que `send` tourne ; le `ReplyStream` retourne par l'adapter reste le chemin autoritaire draine jusqu'au `Final`.
- Mapping adapters : Claude/Codex/OpenCode emettent des progress `ProviderNative` pour les evenements natifs observables (turn/system/step/tool item). OpenAI-compatible emet des progress `IdeaLocal`/`Mcp` autour des appels d'outils orchestries par IdeA.
Garde-fous : ne pas promettre le streaming du raisonnement interne ; ne jamais parser les metadonnees provider comme autorite metier ; #157 doit consommer `ReplyChunk::Progress` cote UI pour affichage distinct et degrade proprement si absent.

View File

@ -5,13 +5,8 @@
"id": "a72dac60-641c-4417-b0d7-94b8539f817a",
"name": "build-appimage",
"description": null,
"contentHash": "77cb33b978b242f6"
},
{
"id": "86ea97df-1533-47e5-8809-dc2b02242567",
"name": "mcp-rendezvous-functional-test",
"description": null,
"contentHash": "9fc8260f64c3b9d5"
"kind": "workflow",
"contentHash": "56dd74230ccf517d"
}
]
}
}

View File

@ -0,0 +1 @@
Skill de test

View File

@ -1,6 +1,6 @@
# Build de l'AppImage IdeA (Linux)
Commande **validée bout-en-bout** (2026-06-17, build exit 0, artefact 106M produit) pour reconstruire l'AppImage Linux d'IdeA. À utiliser à chaque fois qu'un correctif backend/front doit être rendu actif dans l'app (rappel : **le binaire qui tourne = l'AppImage installée, pas les sources** — un correctif n'est actif qu'après rebuild + remplacement + relance d'IdeA).
Commande **validée bout-en-bout** (mise à jour 2026-08-03) pour reconstruire l'AppImage Linux d'IdeA. À utiliser à chaque fois qu'un correctif backend/front doit être rendu actif dans l'app (rappel : **le binaire qui tourne = l'AppImage installée, pas les sources** — un correctif n'est actif qu'après rebuild + remplacement + relance d'IdeA).
## Procédure (2 étapes, depuis le project root `/home/anthony/Documents/Projects/IdeA`)
@ -12,16 +12,18 @@ npm --prefix frontend run build
### 2. Bundle Tauri AppImage (depuis `crates/app-tauri/`)
```bash
cd crates/app-tauri
APPIMAGE_EXTRACT_AND_RUN=1 NO_STRIP=1 ../../frontend/node_modules/.bin/tauri build --bundles appimage
mkdir -p /tmp/idea-cargo-home
CARGO_HOME=/tmp/idea-cargo-home APPIMAGE_EXTRACT_AND_RUN=1 NO_STRIP=1 ../../frontend/node_modules/.bin/tauri build --bundles appimage
```
## Pourquoi ces options (ne pas les retirer)
- `--bundles appimage` : **exclut NSIS** (installeur Windows) — sinutile et cassant sur Linux.
- `APPIMAGE_EXTRACT_AND_RUN=1 NO_STRIP=1` : **workaround FUSE obligatoire**. Sans ça, l'étape finale `linuxdeploy` (elle-même une AppImage montée via FUSE) échoue avec `failed to run linuxdeploy`. Le compile Rust réussit avant ce point ; seul le bundling casse (l'`AppDir` est généré mais pas le `.AppImage`).
- `CARGO_HOME=/tmp/idea-cargo-home` : **workaround sandbox/permissions** pour les environnements où `/home/<user>/.cargo` est monté en lecture seule. Sans ça, `tauri build` peut échouer pendant le téléchargement/unpack Cargo avec `Read-only file system (os error 30)`.
## Artefact produit
```
target/release/bundle/appimage/IdeA_0.1.0_amd64.AppImage
target/release/bundle/appimage/IdeA_0.3.0_amd64.AppImage
```
(Le build est long : compile Rust release ~1 min + bundling. Lancer en arrière-plan.)
@ -29,4 +31,4 @@ target/release/bundle/appimage/IdeA_0.1.0_amd64.AppImage
Pour rendre le correctif actif, il faut **remplacer l'AppImage installée** `/home/anthony/Documents/IdeA_0.1.0_amd64.AppImage` par l'artefact, puis **relancer IdeA**. ⚠️ Relancer IdeA **tue l'orchestrateur en cours** (le serveur qui héberge la session active et les ponts MCP) : à faire par l'utilisateur quand il est prêt, pas en pleine session multi-agents. Garder un backup de l'ancienne AppImage avant remplacement (cf. convention `.old-<raison>`).
## Piège env (si on lance un binaire ensuite)
La session shell hérite des variables de l'AppImage montée (`APPDIR`, `LD_LIBRARY_PATH`, `PYTHONHOME``/tmp/.mount_IdeA_*`). Pour lancer un binaire app-tauri compilé sans crash WebKit, partir d'un env propre (`env -i PATH=/usr/bin:/bin HOME=$HOME XDG_RUNTIME_DIR=/run/user/1000 …`) et préférer `jq` à `python3`.
La session shell hérite des variables de l'AppImage montée (`APPDIR`, `LD_LIBRARY_PATH`, `PYTHONHOME``/tmp/.mount_IdeA_*`). Pour lancer un binaire app-tauri compilé sans crash WebKit, partir d'un env propre (`env -i PATH=/usr/bin:/bin HOME=$HOME XDG_RUNTIME_DIR=/run/user/1000 …`) et préférer `jq` à `python3`.

View File

@ -1,6 +1,38 @@
---
issueRef: "#102"
version: 4
updatedBy: {"kind":"user"}
updatedAt: 1784993980505
version: 11
updatedBy: {"kind":"agent","agent_id":"a6c6ea12-bfc6-4bdc-8031-324102dfa34d"}
updatedAt: 1785878554632
---
## 2026-08-04 — Réouverture
- Repro utilisateur confirmée: en changeant de projet, si une cellule contient un terminal d'agent IA et que du contenu est arrivé pendant que le projet n'était pas affiché, le terminal revient partiellement/blanc/tronqué.
- Symptôme visuel observé: le contenu complet réapparaît immédiatement après un resize de la cellule ou de la fenêtre.
- Portée repro indiquée historiquement: switch de projet, switch de layout, ajout/suppression/redécoupage de cellules; le cas prioritaire confirmé aujourd'hui est le retour sur projet.
- Hypothèse de travail à valider: problème de refresh/fit/reflow frontend du terminal lors de la ré-attache ou ré-activation de la vue, pas un manque de données côté agent.
- Action en cours: recadrage Architect, décision de branche Git, implémentation dev ciblée, puis validation QA sur reproduction réelle.
## 2026-08-04 — Cadrage Architecture (analyse statique, avant implémentation)
- Frontière validée: frontend pur, ciblée sur `frontend/src/features/terminals/TerminalView.tsx`.
- Le backend/PTY n'est pas suspecté à ce stade: le tail de scrollback est bien restitué au reattach; le défaut semble être de rendu/reflow au retour sur la vue.
- Point d'attention principal: `term.write(scrollback)` pourrait arriver avant le premier `fit()` réellement utile, ce qui laisserait xterm wrapper le contenu sur une géométrie transitoire et n'obtiendrait un repaint correct qu'au resize manuel ultérieur.
- Les correctifs précédents ont déjà renforcé la boucle de fit; le trou probable est l'absence de test sur le rendu/repaint effectif et sur l'ordre `reattach/write` vs `first useful fit`.
- Stratégie recommandée: corriger dans `TerminalView` l'ordre de réécriture du scrollback et/ou forcer un repaint plein-buffer après le premier fit utile, puis valider par test ciblé et repro réelle.
## 2026-08-04 — Implémentation DevFrontend
- Correctif appliqué dans `frontend/src/features/terminals/TerminalView.tsx`.
- Changement clé: en cas de `reattach`, le scrollback et les chunks live reçus pendant la fenêtre de réattache ne sont plus écrits immédiatement dans xterm; ils sont tamponnés jusqu'au premier `fit` utile, puis rejoués dans l'ordre `scrollback` puis `live output`.
- Objectif: éviter un rendu initial du buffer sur une géométrie transitoire et supprimer la dépendance à un resize manuel ultérieur pour déclencher l'affichage correct.
- Test ajouté/ajusté dans `frontend/src/features/terminals/TerminalView.test.tsx` pour verrouiller qu'aucun `term.write` ne précède le premier `fit` utile et que l'ordre de replay est conservé.
## 2026-08-04 — Verdict QA
- Validation automatisée verte:
- `cd frontend && npx vitest run src/features/terminals/TerminalView.test.tsx` -> 22 tests passés.
- `cd frontend && npx vitest run src/features/terminals/TerminalView.scrollback.test.tsx src/features/terminals/TerminalView.portal.test.tsx` -> 5 tests passés.
- `cd frontend && npx vitest run src/features/terminals` -> 39 tests passés.
- `cd frontend && npx vitest run` -> 115 fichiers, 1083 tests passés.
- Verdict QA: `vert avec réserve de preuve manuelle`.
- Réserve restante: absence de repro visuelle réelle rejouée dans l'application avec un vrai xterm, une session vivante, puis un reattach après switch projet/layout. Le ticket reste donc ouvert tant que cette validation de terrain n'est pas obtenue.

View File

@ -2,15 +2,16 @@
id: "e91fd358-da94-4382-aa70-6a3fe5a63840"
number: 102
title: "[Bug] Devoir resize les cellule pour afficher la TUI d'un agent"
status: "closed"
status: "inProgress"
priority: "medium"
sprint: "e28a4d53-8bd2-446a-b0ac-2a017373b8b2"
links: []
agentRefs: [{"agentId":"a6ced819-b893-4213-b003-9e9dc79b9641","role":"assigned"}]
attachments: []
createdBy: {"kind":"user"}
updatedBy: {"kind":"agent","agent_id":"a6ced819-b893-4213-b003-9e9dc79b9641"}
updatedBy: {"kind":"agent","agent_id":"a6c6ea12-bfc6-4bdc-8031-324102dfa34d"}
createdAt: 1784993319700
updatedAt: 1785083912470
version: 5
updatedAt: 1785878554632
version: 11
---
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

View File

@ -1,6 +1,6 @@
---
issueRef: "#113"
version: 4
updatedBy: {"kind":"user"}
updatedAt: 1785395935541
version: 5
updatedBy: {"kind":"agent","agent_id":"a6c6ea12-bfc6-4bdc-8031-324102dfa34d"}
updatedAt: 1785748044140
---

View File

@ -2,16 +2,16 @@
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"
status: "closed"
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"}
updatedBy: {"kind":"agent","agent_id":"a6c6ea12-bfc6-4bdc-8031-324102dfa34d"}
createdAt: 1785395710201
updatedAt: 1785395935541
version: 4
updatedAt: 1785748044140
version: 5
---
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

View File

@ -1,6 +1,6 @@
---
issueRef: "#119"
version: 2
updatedBy: {"kind":"agent","agent_id":"a6ced819-b893-4213-b003-9e9dc79b9641"}
updatedAt: 1785536553069
version: 4
updatedBy: {"kind":"user"}
updatedAt: 1785881187569
---

View File

@ -2,17 +2,17 @@
id: "b76431d7-f3a3-438f-ae3f-5648f5eda8ce"
number: 119
title: "Refondre le système de skills IdeA en capacités agent découvrables"
status: "inProgress"
status: "closed"
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"}
updatedBy: {"kind":"user"}
createdAt: 1785534242629
updatedAt: 1785536553069
version: 2
updatedAt: 1785881187569
version: 4
---
## Constat

View File

@ -1,8 +1,8 @@
---
issueRef: "#120"
version: 9
updatedBy: {"kind":"agent","agent_id":"a6ced819-b893-4213-b003-9e9dc79b9641"}
updatedAt: 1785600025153
version: 11
updatedBy: {"kind":"user"}
updatedAt: 1785881187579
---
---
issueRef: "#120"

View File

@ -2,17 +2,17 @@
id: "f4218553-680a-4fbb-9514-a96eab79b8d8"
number: 120
title: "Réinvestiguer linstallation de hello-plugin: écran noir / perte daffichage IdeA"
status: "inProgress"
status: "closed"
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"}
updatedBy: {"kind":"user"}
createdAt: 1785534496259
updatedAt: 1785600025153
version: 9
updatedAt: 1785881187579
version: 11
---
## Constat utilisateur

View File

@ -1,6 +1,6 @@
---
issueRef: "#122"
version: 3
updatedBy: {"kind":"user"}
updatedAt: 1785592528432
version: 4
updatedBy: {"kind":"agent","agent_id":"a6c6ea12-bfc6-4bdc-8031-324102dfa34d"}
updatedAt: 1785748044193
---

View File

@ -2,16 +2,16 @@
id: "fa083793-48ae-417a-ab16-3813e22df2e3"
number: 122
title: "[Bug] Override des permissions defaut qui ne marche pas"
status: "open"
status: "closed"
priority: "medium"
sprint: null
links: []
agentRefs: [{"agentId":"a6ced819-b893-4213-b003-9e9dc79b9641","role":"assigned"}]
attachments: []
createdBy: {"kind":"user"}
updatedBy: {"kind":"user"}
updatedBy: {"kind":"agent","agent_id":"a6c6ea12-bfc6-4bdc-8031-324102dfa34d"}
createdAt: 1785592422173
updatedAt: 1785592528432
version: 3
updatedAt: 1785748044193
version: 4
---
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

View File

@ -1,8 +1,8 @@
---
issueRef: "#123"
version: 4
updatedBy: {"kind":"agent","agent_id":"a6ced819-b893-4213-b003-9e9dc79b9641"}
updatedAt: 1785670261241
version: 5
updatedBy: {"kind":"user"}
updatedAt: 1785881187586
---
## Contexte
Le besoin initial vient dun futur plugin orienté développement Android, mais le périmètre validé pour ce chantier est strictement **SDK générique**. Lobjectif nest pas dajouter des API Android-first, mais de combler les trous du SDK public qui empêchent aujourdhui tout plugin de développement un peu sérieux.

View File

@ -2,16 +2,16 @@
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"
status: "closed"
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"}
updatedBy: {"kind":"user"}
createdAt: 1785662012603
updatedAt: 1785670261241
version: 4
updatedAt: 1785881187586
version: 5
---
Ticket parapluie pour structurer lextension du SDK public des plugins IdeA afin de supporter des plugins de développement avancés sans introduire dAPI métier spécifiques à une stack donnée. Le besoin initial vient du cas Android, mais le périmètre doit rester strictement transversal.

View File

@ -1,8 +1,8 @@
---
issueRef: "#124"
version: 4
updatedBy: {"kind":"agent","agent_id":"a6ced819-b893-4213-b003-9e9dc79b9641"}
updatedAt: 1785666067073
version: 5
updatedBy: {"kind":"user"}
updatedAt: 1785881187593
---
## Problème
`WorkspaceService` public expose aujourdhui 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 dun projet.

View File

@ -2,16 +2,16 @@
id: "639787e1-83b5-49b7-a89f-3a6985129163"
number: 124
title: "SDK plugins: exposer une API publique daccès fichiers/workspace"
status: "qa"
status: "closed"
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"}
updatedBy: {"kind":"user"}
createdAt: 1785662026640
updatedAt: 1785666067073
version: 4
updatedAt: 1785881187593
version: 5
---
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.

View File

@ -1,8 +1,8 @@
---
issueRef: "#125"
version: 4
updatedBy: {"kind":"agent","agent_id":"a6ced819-b893-4213-b003-9e9dc79b9641"}
updatedAt: 1785667057177
version: 5
updatedBy: {"kind":"user"}
updatedAt: 1785881187607
---
## Problème
Le SDK public permet seulement :

View File

@ -2,16 +2,16 @@
id: "78bb45fb-6320-4d75-8db2-1e2a9591219f"
number: 125
title: "SDK plugins: exposer une API publique de lancement de commandes et tâches"
status: "qa"
status: "closed"
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"}
updatedBy: {"kind":"user"}
createdAt: 1785662026655
updatedAt: 1785667057177
version: 4
updatedAt: 1785881187607
version: 5
---
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 lobservation des tâches existantes et du simple PTY interactif.

View File

@ -1,8 +1,8 @@
---
issueRef: "#126"
version: 7
updatedBy: {"kind":"agent","agent_id":"a6ced819-b893-4213-b003-9e9dc79b9641"}
updatedAt: 1785668062783
version: 8
updatedBy: {"kind":"user"}
updatedAt: 1785881187599
---
## 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 lenvironnement est valide. Le SDK public nexpose pas aujourdhui cette capacité comme primitive générique.

View File

@ -2,16 +2,16 @@
id: "51d4f4b0-4482-4400-a0d5-9f88471581f0"
number: 126
title: "SDK plugins: exposer une API publique de découverte/validation doutillage externe"
status: "qa"
status: "closed"
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"}
updatedBy: {"kind":"user"}
createdAt: 1785662026684
updatedAt: 1785668062783
version: 7
updatedAt: 1785881187599
version: 8
---
Ajouter au SDK plugin une API publique pour détecter, valider et décrire des toolchains externes (exécutables, versions, variables denvironnement, prérequis) sans spécialiser le SDK pour une stack donnée.

View File

@ -1,8 +1,8 @@
---
issueRef: "#127"
version: 4
updatedBy: {"kind":"agent","agent_id":"a6ced819-b893-4213-b003-9e9dc79b9641"}
updatedAt: 1785669121141
version: 5
updatedBy: {"kind":"user"}
updatedAt: 1785881187615
---
## 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. Cest coûteux, fragile et peu réactif.

View File

@ -2,16 +2,16 @@
id: "9b238559-9982-4a69-8795-99da8a46be1e"
number: 127
title: "SDK plugins: exposer une API publique dévénements et de watch"
status: "qa"
status: "closed"
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"}
updatedBy: {"kind":"user"}
createdAt: 1785662026701
updatedAt: 1785669121141
version: 4
updatedAt: 1785881187615
version: 5
---
Ajouter au SDK plugin une API publique dabonnement 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.

View File

@ -1,8 +1,8 @@
---
issueRef: "#128"
version: 4
updatedBy: {"kind":"agent","agent_id":"a6ced819-b893-4213-b003-9e9dc79b9641"}
updatedAt: 1785670260985
version: 5
updatedBy: {"kind":"user"}
updatedAt: 1785881187622
---
## Problème
Le manifeste expose déjà des contributions `layouts`, mais la runtime publique ne formalise pas proprement lenregistrement et le cycle de vie de ces layouts. Lexemple SDK actuel contourne la surface avec des casts ad hoc.

View File

@ -2,16 +2,16 @@
id: "053f079d-1dfd-48bb-85a2-2dfa8d237999"
number: 128
title: "SDK plugins: typer et stabiliser la runtime UI/layout publique"
status: "qa"
status: "closed"
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"}
updatedBy: {"kind":"user"}
createdAt: 1785662026717
updatedAt: 1785670260985
version: 4
updatedAt: 1785881187622
version: 5
---
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.

View File

@ -1,8 +1,8 @@
---
issueRef: "#129"
version: 5
updatedBy: {"kind":"agent","agent_id":"a6ced819-b893-4213-b003-9e9dc79b9641"}
updatedAt: 1785666067171
version: 6
updatedBy: {"kind":"user"}
updatedAt: 1785881187631
---
## Problème
Chaque plugin de développement devrait aujourdhui rescanner lui-même le workspace pour reconstruire une vision de la structure projet. Cela duplique les heuristiques et rend lécosystème fragile.

View File

@ -2,16 +2,16 @@
id: "550fe7ca-8a25-4529-be2e-2fd79c7ddde4"
number: 129
title: "SDK plugins: exposer une API publique danalyse/requête de structure projet"
status: "qa"
status: "closed"
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"}
updatedBy: {"kind":"user"}
createdAt: 1785662026738
updatedAt: 1785666067171
version: 5
updatedAt: 1785881187631
version: 6
---
Ajouter au SDK plugin une API publique pour interroger la structure dun projet (fichiers, modules, graphes simples, conventions détectées) sans obliger chaque plugin à rescanner le workspace depuis zéro.

View File

@ -1,8 +1,8 @@
---
issueRef: "#130"
version: 5
updatedBy: {"kind":"agent","agent_id":"a6ced819-b893-4213-b003-9e9dc79b9641"}
updatedAt: 1785669830933
version: 6
updatedBy: {"kind":"user"}
updatedAt: 1785881187639
---
## 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 dincohérence.

View File

@ -2,16 +2,16 @@
id: "07a76880-f176-4fc8-b1d3-732a88a8c837"
number: 130
title: "SDK plugins: exposer une API publique de documents de configuration structurés"
status: "qa"
status: "closed"
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"}
updatedBy: {"kind":"user"}
createdAt: 1785662026750
updatedAt: 1785669830933
version: 5
updatedAt: 1785881187639
version: 6
---
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.

View File

@ -0,0 +1,6 @@
---
issueRef: "#131"
version: 2
updatedBy: {"kind":"agent","agent_id":"a6c6ea12-bfc6-4bdc-8031-324102dfa34d"}
updatedAt: 1785748044208
---

View File

@ -0,0 +1,39 @@
---
id: "4092a7bf-5abb-4056-9e6d-226c392b2279"
number: 131
title: "Configurer l'effort par agent avec presets adaptatifs selon le profil AI"
status: "closed"
priority: "medium"
sprint: null
links: []
agentRefs: []
attachments: []
createdBy: {"kind":"agent","agent_id":"a6ced819-b893-4213-b003-9e9dc79b9641"}
updatedBy: {"kind":"agent","agent_id":"a6c6ea12-bfc6-4bdc-8031-324102dfa34d"}
createdAt: 1785687359220
updatedAt: 1785748044208
version: 2
---
Objectif: permettre de choisir l'effort de chaque agent, idéalement via une droplist qui s'adapte au profil AI sélectionné (ex: Codex, Claude Code, OpenCode), tout en conservant un fallback sûr.
Cadrage validé en pré-analyse:
- Faisabilité: oui.
- Recommandation produit/contrat: approche hybride contrôlée.
- UI recommandée: droplist dépendante du profil AI + option "Personnalisé" ouvrant un champ texte/valeur libre si nécessaire.
Attendus de conception:
- Le profil AI déclare ses options natives d'effort/presets quand elles existent.
- La UI affiche ces options dans une droplist ordonnée du plus léger au plus profond.
- Si le provider n'expose pas d'options propres, fallback vers des presets génériques (ex: Rapide / Standard / Approfondi) clairement marqués comme options par défaut.
- Une option "Personnalisé" reste disponible pour couvrir les providers ou cas non modélisables proprement.
Attendus de contrat:
- Ajouter sur le profil AI un mécanisme déclaratif d'options d'effort (ex: effort_options avec label + valeur interne + éventuels hints).
- Le DTO d'agent doit persister soit un preset choisi, soit une valeur brute personnalisée.
- Prévoir la rétrocompatibilité avec les profils/configs existants, notamment les champs Codex déjà proches de cette notion.
Risques à traiter:
- Mapping imparfait entre presets UI et paramètres natifs des providers.
- Cohérence des libellés entre providers.
- Découverte UX de l'option "Personnalisé".
- Rétrocompatibilité/persistance sur les profils existants.

View File

@ -0,0 +1,6 @@
---
issueRef: "#132"
version: 2
updatedBy: {"kind":"agent","agent_id":"a6c6ea12-bfc6-4bdc-8031-324102dfa34d"}
updatedAt: 1785748044221
---

View File

@ -0,0 +1,41 @@
---
id: "37c98a91-ee51-42b3-b804-8c0732784e11"
number: 132
title: "Ajouter un outil MCP IdeA pour éditer le contexte projet global"
status: "closed"
priority: "medium"
sprint: null
links: []
agentRefs: []
attachments: []
createdBy: {"kind":"agent","agent_id":"a6ced819-b893-4213-b003-9e9dc79b9641"}
updatedBy: {"kind":"agent","agent_id":"a6c6ea12-bfc6-4bdc-8031-324102dfa34d"}
createdAt: 1785687502830
updatedAt: 1785748044221
version: 2
---
Objectif: permettre à un agent autorisé d'éditer le contexte projet global via un outil MCP IdeA dédié, au lieu de passer uniquement par une proposition enregistrée.
Constat actuel:
- Le contexte projet global est lisible via `idea_context_read`.
- Son évolution passe aujourd'hui par `idea_context_propose` sans `target`, ce qui enregistre une proposition pour validation mais n'applique pas directement la modification.
- Pour certains workflows d'orchestration, il manque une capacité native explicite d'édition contrôlée du contexte projet global.
Attendu produit/technique:
- Introduire un outil MCP IdeA dédié pour mettre à jour le contexte projet global.
- Définir clairement qui peut l'utiliser (ex: Main uniquement, ou liste d'agents autorisés).
- Préserver les garde-fous de concurrence et de traçabilité déjà attendus sur les contextes.
- Clarifier la relation entre ce nouvel outil et `idea_context_propose` (complément, remplacement partiel, ou voie restreinte selon les droits).
Points à cadrer:
- Modèle d'autorisation: quels agents peuvent écrire le contexte global.
- Concurrence/versioning: écrasement simple vs contrôle optimiste.
- Auditabilité: auteur, date, historique/provenance des changements.
- UX/runtime: comportement si un agent non autorisé tente l'opération.
- Compatibilité avec la règle actuelle de single-writer réservée à l'orchestrateur.
Critères de sortie:
- Contrat MCP défini.
- Règles d'autorisation explicites.
- Comportement d'erreur et de concurrence défini.
- Décision documentée sur la coexistence avec `idea_context_propose`.

View File

@ -0,0 +1,24 @@
---
issueRef: "#133"
version: 5
updatedBy: {"kind":"user"}
updatedAt: 1785881187645
---
## Décision d'architecture (2026-08-02)
Documentée dans `ARCHITECTURE.md` §22.1 (nouvelle section "Plugins — service des assets multi-fichiers & persistance plugin-owned").
**Contrat tranché :** `asset_allowed` (`crates/app-tauri/src/plugins.rs:504-536`) doit servir tout chemin relatif confiné dès lors que les trois gardes déjà présentes sont satisfaites — entrée registre trouvée + `lifecycle_state.is_runtime_active()` + `entry.content_hash == hash` de l'URL (intégrité du package entier) — sans plus restreindre au triplet `declared_main || declared_icon || starts_with("assets/")`. Le confinement canonicalize aval (lignes 467-483, `target.starts_with(&root)`) reste inchangé et continue de protéger contre l'évasion de racine. `validator.validate(manifest)` reste appelé comme garde d'intégrité globale du manifeste, mais cesse de gater le service fichier par fichier.
**Rationale sécurité :** aucune perte de garantie — le modèle de menace est fixé par `content_hash` à l'installation (audité en #135), donc restreindre les fichiers *siblings* d'un package déjà intégralement vérifié n'arrête aucune attaque supplémentaire, ça casse juste des graphes de modules ESM légitimes.
**Limite figée :** pas de résolution `node_modules`/bare specifiers — hors scope, aucun résolveur de module à construire. Un plugin avec dépendances tierces les bundle ou vendore en relatif, à son choix.
**Contrat de confinement/désinstallation formalisé :** racine servie = exclusivement `app_data/plugins/installed/<pluginId>/` ; jamais d'écriture/exposition hors project root ou `.ideai/` de l'utilisateur ; désinstallation = suppression complète + entrée registre, zéro résidu (périmètre détaillé pour #135).
## Débloque
- **#134** : remplacer la dernière ligne de `asset_allowed``Ok(declared_main || declared_icon || rel.as_str().starts_with("assets/"))` — par une autorisation basée uniquement sur les gardes déjà calculées plus haut dans la fonction. Tests de non-régression path-traversal et hash/lifecycle invalides déjà spécifiés dans #134, contrat inchangé.
- **#135** : périmètre d'audit = confinement à l'install (`RelativePath::new` déjà rejette `..`/absolu côté domaine — vérifier qu'il est bien appliqué à l'INSTALL, pas seulement au SERVE) + désinstallation 100%.
Aucun changement de code applicatif dans ce ticket (portée strictement architecture, conforme à l'objectif du ticket). Fichier touché : `ARCHITECTURE.md` (§22.1 ajouté).

View File

@ -0,0 +1,31 @@
---
id: "f5296d8b-6bef-45c4-ac8a-cf6e0f90ae9c"
number: 133
title: "Plugins: contrat de service des assets idea-plugin:// (multi-fichiers ESM) & confinement"
status: "closed"
priority: "high"
sprint: null
links: []
agentRefs: [{"agentId":"b4730d7f-c54d-4736-8a04-c6203aa2fd49","role":"assigned"}]
attachments: []
createdBy: {"kind":"agent","agent_id":"b4730d7f-c54d-4736-8a04-c6203aa2fd49"}
updatedBy: {"kind":"user"}
createdAt: 1785702640094
updatedAt: 1785881187645
version: 5
---
Bug diagnostiqué : `crates/app-tauri/src/plugins.rs:504-536` (`asset_allowed`) n'autorise que `main`/`icon` déclarés au manifeste, ou un chemin préfixé `assets/`. Tout import ESM relatif secondaire (`./constants.js`, `./core/x.js`) depuis le `main` est donc rejeté 403 → "Importing a module script failed." côté navigateur. Le SDK (sdk/IdeaSDK/README.md) documente `main: dist/index.js` comme point d'entrée sans jamais imposer un bundle mono-fichier, ce qui sous-entend un support multi-fichiers jamais réellement vérifié (l'exemple hello-plugin est mono-fichier).
Objectif de ce ticket : trancher le contrat d'architecture, PAS l'implémenter.
À décider et documenter :
1. Élargir la politique de service à : tout chemin relatif confiné du package installé, dès lors que `entry.content_hash == hash` (intégrité du package entier déjà vérifiée) ET `entry.lifecycle_state.is_runtime_active()` ET confinement canonicalize (`target.starts_with(root)`, déjà en place lignes 467-483). Ces trois garanties suffisent déjà sans dépendre d'une déclaration par-fichier dans le manifeste.
2. Figer la limite explicite : imports ESM relatifs uniquement, pas de résolution `node_modules`/bare specifiers (hors scope, pas de résolveur de modules à construire) — un plugin qui a des dépendances tierces doit les vendorer en relatif ou les bundler lui-même, à son choix, jamais une obligation d'IdeA.
3. Formaliser le contrat de confinement + désinstallation propre : aucune écriture ne doit jamais sortir de `app_data/plugins/installed/<id>` (pas de pollution project root ni `.ideai/`), et la désinstallation doit être 100% (dossier + entrée registry, zéro résidu), à la manière VSCode.
Livrable : note d'architecture (+ mise à jour de la doc plugin existante si présente) qui fait foi pour les tickets d'implémentation liés (DevBackend, SDK/doc, QA).
Critères d'acceptation :
- Le contrat écrit référence explicitement le code actuel (plugins.rs:504-536) et explique pourquoi hash+lifecycle+confinement remplacent l'allowlist par fichier sans régression de sécurité.
- La limite bare-specifiers/node_modules est tranchée noir sur blanc (in ou out, et pourquoi).
- Le contrat de confinement/désinstallation est écrit explicitement (racine autorisée, ce qui est interdit, ce que "propre" veut dire).

View File

@ -0,0 +1,6 @@
---
issueRef: "#134"
version: 4
updatedBy: {"kind":"user"}
updatedAt: 1785881187652
---

View File

@ -0,0 +1,33 @@
---
id: "e98c3f80-9fd6-444a-be80-ad695809c71c"
number: 134
title: "Plugins: servir tout fichier confiné du package installé (fix racine multi-fichiers ESM)"
status: "closed"
priority: "critical"
sprint: null
links: [{"target":"#133","kind":"dependsOn"}]
agentRefs: [{"agentId":"fe887179-933f-47d4-960f-c3b06827f86c","role":"assigned"}]
attachments: []
createdBy: {"kind":"agent","agent_id":"b4730d7f-c54d-4736-8a04-c6203aa2fd49"}
updatedBy: {"kind":"user"}
createdAt: 1785702651199
updatedAt: 1785881187652
version: 4
---
Implémente le contrat décidé en #133.
Modifier `asset_allowed` / `plugin_asset_response_with_stores` dans `crates/app-tauri/src/plugins.rs:504-536` : remplacer la condition `declared_main || declared_icon || rel.as_str().starts_with("assets/")` par une autorisation basée sur les garanties déjà vérifiées avant cette ligne (hash de contenu du package `entry.content_hash.as_str() == hash`, `entry.lifecycle_state.is_runtime_active()`) et sur le confinement canonicalize déjà en place lignes 467-483 (`target.starts_with(&root)`).
Ne pas retirer `validator.validate(&manifest_bytes.bytes, &package)` : cette vérification reste une garde d'intégrité globale du manifeste, mais ne doit plus servir à restreindre le service fichier par fichier.
Respecter strictement la limite figée en #133 (imports relatifs uniquement, pas de résolveur node_modules/bare specifiers — hors scope).
Tests à ajouter dans `crates/app-tauri/src/plugins.rs` (module de tests existant en bas de fichier) :
- requête d'un fichier non déclaré dans le manifeste (ex: `dist/core/helper.js`) → 200 OK si hash+lifecycle valides.
- path traversal (`../`) → toujours 403 (non-régression, déjà couvert mais à revérifier après le changement).
- hash de contenu différent ou plugin non `runtime_active` → toujours 403 (non-régression).
Critères d'acceptation :
- `cargo test -p app-tauri` vert, nouveaux cas inclus.
- Un plugin composé de `dist/index.js` + `dist/constants.js` (import relatif) se charge sans 403 via le protocole `idea-plugin://`.
- Aucune régression sur les tests de confinement/path-traversal existants.

View File

@ -0,0 +1,26 @@
---
issueRef: "#135"
version: 5
updatedBy: {"kind":"user"}
updatedAt: 1785881187659
---
## Audit QA
- `install_from_directory` : audit confirme qu'avant correctif le store ne rejetait pas explicitement les symlinks source ; il les ignorait. Le correctif fait maintenant échouer l'installation sur toute entrée symlink ou unsupported dans l'arbre source.
- `install_from_archive` : audit confirme un trou réel de confinement avant correctif. L'extraction reposait entièrement sur `unzip` sans validation applicative des entrées. Le correctif remplace cette extraction par une lecture Rust confinée qui rejette les entrées `../`/absolues via `enclosed_name()` et refuse explicitement les symlinks d'archive.
- Confinement d'écriture : après correctif, aucune écriture d'install ne sort de `app_data/plugins/_staging/...` puis `app_data/plugins/installed/<id>` ; le test `../../../../outside.txt` prouve l'absence d'écriture hors racine.
- `hash_dir` / collecte fichiers : durci pour échouer si un package contient encore un symlink ou une entrée non supportée, au lieu de l'ignorer.
- `plugin_uninstall` / `remove_package` : audit confirmé par test multifichier. La désinstallation supprime le dossier entier, retire l'entrée registry et laisse le runtime catalog vide.
## Tests ajoutés/ajustés
- `plugin::tests::install_from_directory_rejects_source_symlink`
- `plugin::tests::install_from_archive_rejects_parent_traversal_without_writing_outside_stage`
- `plugin::tests::install_from_archive_rejects_symlink_entries`
- `plugin_install_load::uninstall_multifile_plugin_removes_package_registry_and_runtime_residue`
- Stabilisation des tests SDK `hello-plugin` : fixture matérialisée avec `dist/index.js` dans un temp dir pour supprimer une dépendance implicite à un build préalable.
## Verdict
- Correctif confinement install/uninstall validé.
- `cargo test -p infrastructure -p application -p app-tauri` vert avec `CARGO_HOME=/tmp/idea-cargo-home` dans cet environnement.

View File

@ -0,0 +1,31 @@
---
id: "13442dae-7860-45e3-9287-31b9bde19170"
number: 135
title: "Plugins: audit confinement install & désinstallation 100% propre"
status: "closed"
priority: "high"
sprint: null
links: [{"target":"#133","kind":"dependsOn"}]
agentRefs: [{"agentId":"ab328d90-c307-4771-a3b6-6c56089c8506","role":"assigned"}]
attachments: []
createdBy: {"kind":"agent","agent_id":"b4730d7f-c54d-4736-8a04-c6203aa2fd49"}
updatedBy: {"kind":"user"}
createdAt: 1785702662938
updatedAt: 1785881187659
version: 5
---
Applique le contrat de confinement/désinstallation décidé en #133.
Auditer `plugin_install_from_archive` / `plugin_install_from_directory` (`crates/app-tauri/src/plugins.rs:67-142`) et le store d'infrastructure (`crates/infrastructure/src/plugin/mod.rs`) pour confirmer qu'aucune écriture ne peut jamais sortir de `app_data/plugins/installed/<id>` :
- Un plugin dont le manifeste ou l'archive contient un chemin `../` ou un symlink pointant hors de sa racine doit échouer à l'install (vérifier que `RelativePath::new` — qui rejette déjà `..` et les chemins absolus, cf. `crates/domain/src/plugin.rs` — est bien appliqué à l'INSTALL, pas seulement au SERVE ajouté en #134).
- Aucune écriture ne doit jamais toucher le project root ni `.ideai/` du projet ouvert : le plugin est un citoyen de `app_data`, jamais du repo utilisateur.
Vérifier que `plugin_uninstall` (`crates/app-tauri/src/plugins.rs:142`) supprime bien 100% : dossier entier + entrée registry, zéro résidu. Étendre si besoin les tests existants (`uninstall_removes_registry_package_and_stops_mcp`, `uninstall_then_reinstall_leaves_runtime_catalog_active_without_residue` dans `crates/application/src/plugin/mod.rs`) pour couvrir explicitement le cas d'un plugin multi-fichiers (plusieurs fichiers sous `dist/`).
Si un chemin d'attaque (symlink sortant, `../` dans une archive zip malveillante) n'est pas déjà bloqué à l'install, ouvrir un correctif dans ce même ticket (pas de nouveau ticket) : c'est un renforcement du même contrat, pas une nouvelle feature.
Critères d'acceptation :
- Rapport d'audit écrit (dans le carnet du ticket) listant les points vérifiés et leur statut.
- Test explicite : tentative d'installer un plugin avec chemin `../` ou symlink sortant → échec propre, aucun fichier écrit hors racine.
- Test explicite : désinstallation d'un plugin multi-fichiers → dossier disparu, entrée registry disparue, aucun résidu.
- `cargo test -p app-tauri -p infrastructure -p application` vert.

View File

@ -0,0 +1,6 @@
---
issueRef: "#136"
version: 4
updatedBy: {"kind":"user"}
updatedAt: 1785881187667
---

View File

@ -0,0 +1,27 @@
---
id: "214e7c14-fab8-45ed-bb71-5f309a8479a6"
number: 136
title: "SDK plugins: aligner doc/exemple sur le support multi-fichiers ESM"
status: "closed"
priority: "high"
sprint: null
links: [{"target":"#134","kind":"dependsOn"}]
agentRefs: [{"agentId":"8f7da528-58df-4315-97e9-0562230ecc19","role":"assigned"}]
attachments: []
createdBy: {"kind":"agent","agent_id":"b4730d7f-c54d-4736-8a04-c6203aa2fd49"}
updatedBy: {"kind":"user"}
createdAt: 1785702672090
updatedAt: 1785881187667
version: 4
---
Une fois #134 livré, aligner le SDK et sa documentation pour que le support multi-fichiers soit explicite et testé, pas seulement sous-entendu.
Étendre `sdk/IdeaSDK/examples/hello-plugin` (ou ajouter un nouvel exemple dédié, ex: `hello-plugin-multi`) avec un vrai split en plusieurs fichiers ESM compilés séparément — `src/index.ts` qui importe `./constants.ts` et `./core/...` — sans bundler forcé (juste `tsc`, comme l'exemple actuel). Ce sera la preuve vivante et le test de non-régression du contrat de #133/#134.
Mettre à jour `sdk/IdeaSDK/README.md` (autour de la ligne 50 où `main` est décrit comme "compiled ESM entrypoint") :
- Clarifier explicitement que `main` est le point d'entrée, mais que des imports relatifs vers d'autres fichiers du même package sont servis nativement par le protocole `idea-plugin://` (plus besoin de tout bundler en un seul fichier).
- Documenter la limite figée en #133 : imports relatifs uniquement ; les dépendances tierces (npm) doivent être bundlées ou vendorées en relatif par le plugin, IdeA ne résout pas `node_modules`.
Critères d'acceptation :
- L'exemple multi-fichiers build (`npm run build` ou équivalent existant) et se charge dans IdeA sans erreur `Importing a module script failed.` (vérification manuelle ou via #136).
- Le README ne laisse plus entendre un support non vérifié ; la limite bare-specifiers est écrite noir sur blanc.

View File

@ -1,6 +1,6 @@
---
issueRef: "#66"
issueRef: "#137"
version: 2
updatedBy: {"kind":"user"}
updatedAt: 1784193460805
updatedAt: 1785881139749
---

View File

@ -0,0 +1,27 @@
---
id: "2ef9b71a-9869-4476-88b6-65aaefc993e1"
number: 137
title: "QA: validation end-to-end plugin multi-fichiers ESM (chargement + désinstallation propre)"
status: "closed"
priority: "critical"
sprint: null
links: [{"target":"#134","kind":"dependsOn"},{"target":"#136","kind":"dependsOn"}]
agentRefs: [{"agentId":"ab328d90-c307-4771-a3b6-6c56089c8506","role":"assigned"}]
attachments: []
createdBy: {"kind":"agent","agent_id":"b4730d7f-c54d-4736-8a04-c6203aa2fd49"}
updatedBy: {"kind":"user"}
createdAt: 1785702681696
updatedAt: 1785881139749
version: 2
---
Validation réelle, sortie observée — pas seulement des tests unitaires — du fix multi-fichiers (#134) et de l'exemple SDK (#136).
À exécuter dans une build réelle (AppImage ou dev Tauri) :
1. Installer le plugin multi-fichiers issu de #136 (fichiers ESM non bundlés, imports relatifs). Confirmer l'absence de l'erreur navigateur "Importing a module script failed." et l'activation correcte (`activate(ctx)` appelé, contributions menus/layouts visibles et fonctionnelles selon ce que déclare l'exemple).
2. Vérifier l'isolement : le plugin ne dépose rien dans le project root ni dans `.ideai/` du projet ouvert (contrat de #133/#135).
3. Désinstaller depuis l'UI (Panneau Plugins) : vérifier disque (aucun résidu sous `app_data/plugins/installed/<id>`), registre (entrée disparue), et absence de toute trace côté projet.
4. Réinstaller le même plugin après désinstallation : doit repartir propre, sans conflit résiduel.
Critères d'acceptation :
- Rapport QA avec preuve d'exécution réelle (logs/captures), verdict vert ou liste d'écarts bloquants.
- Si régression détectée sur #134/#135/#136, retour précis (repro + fichier/ligne suspecté) au dev concerné avant clôture.

View File

@ -0,0 +1,30 @@
---
issueRef: "#138"
version: 5
updatedBy: {"kind":"user"}
updatedAt: 1785881187672
---
## Décision d'architecture (2026-08-02)
Documentée dans `ARCHITECTURE.md` §22.2 (même nouvelle section que #133).
**Constat vérifié dans le code :** `sdk/IdeaSDK/src/runtime.ts` déclare déjà `ActivateContext.storage?: PluginStorage` (`get/set/delete`, clé-valeur JSON-serializable), et l'exemple `hello-plugin` s'en sert (`ctx.storage?.get<string>("helloPlugin.ownerAgentId")`). Mais ce champ n'est **jamais peuplé** : `frontend/src/plugins/runtime/loader.ts` (~lignes 249-256) ne câble que `logger`, `subscriptions`, `services``ctx.storage` vaut toujours `undefined` en exécution. Côté Rust : zéro port, zéro commande, zéro répertoire pour cette primitive (recherché, rien trouvé). Faute d'API réelle, l'exemple détourne `ctx.services.workspace`/`ctx.services.config` pour écrire son état interne sous `.ideai/hello-plugin.txt` et `.ideai/hello-plugin.json`.
**Décision — séparation noir sur blanc :**
- **Project-owned** : fichiers du workspace que le plugin modifie *volontairement* pour l'utilisateur/le projet → reste `ctx.services.workspace.*`/`ctx.services.config.*`, sandbox projet existant inchangé.
- **Plugin-owned** : préférences/cache/sélection/index/config interne → ne vit **jamais** dans le project root ni sous `.ideai/`. Nouveau répertoire **frère** de `plugins/installed/<id>/` : `app_data/plugins/data/<pluginId>/`. Séparé de `installed/` pour que les mises à jour de package ne touchent jamais aux données utilisateur, et pour donner à la désinstallation une deuxième racine univoque à purger.
**API canonique tranchée : `ctx.storage` seul, pas de second API document.** `ctx.storage.set(key, value)` avec des valeurs JSON couvre déjà le besoin de document structuré — une deuxième API "document plugin-scopé" ferait doublon. `ctx.services.config` reste réservé au project-owned.
**Cycle de vie figé :**
- `ctx.storage.get/set/delete` → commandes Tauri (ex. `plugin_storage_get/set/delete`) → store scopé par `pluginId` sous `plugins/data/<pluginId>/` (format interne — JSON unique ou par clé — laissé à #139, seule la frontière de répertoire est un contrat figé).
- `plugin_uninstall` (`crates/app-tauri/src/plugins.rs:142`) doit purger `plugins/data/<id>/` en plus de `plugins/installed/<id>` + registre (déjà couvert par #135). Les fichiers project-owned écrits par le plugin dans le workspace ne sont **jamais** touchés par l'uninstall.
## Débloque #139
1. Implémenter `ctx.storage` de bout en bout : port domaine + adapter infra scopés à `plugins/data/<pluginId>/`, commandes Tauri, câblage réel dans `loader.ts` (absent aujourd'hui), confinement en esprit identique à #133/#135.
2. Réaligner `hello-plugin` : migrer les compteurs internes (`launches`, `enabled`, `ownerAgentId`) vers `ctx.storage`. Garder au plus un exemple clairement étiqueté "fichier projet réel" via `workspace`/`config`, pas comme pattern par défaut.
3. `sdk/IdeaSDK/README.md` section "Structured Config Documents" à corriger : ne plus donner `.ideai/hello-plugin.json` comme exemple d'état interne, remplacer par un exemple `ctx.storage`, documenter la séparation project-owned/plugin-owned.
4. Preuve requise : test de purge (installer → écrire via `ctx.storage` → désinstaller → `plugins/data/<id>/` disparu) + absence de tout chemin `.ideai/...` dans les exemples SDK par défaut.
Aucun changement de code applicatif dans ce ticket (portée strictement architecture/API, conforme à l'objectif du ticket). Fichier touché : `ARCHITECTURE.md` (§22.2 ajouté).

View File

@ -0,0 +1,33 @@
---
id: "e33fd0ea-e7c6-40dc-a244-f158e44ac4a7"
number: 138
title: "SDK plugins: contrat de persistance plugin-owned hors projet et effacement total à la désinstallation"
status: "closed"
priority: "critical"
sprint: null
links: []
agentRefs: [{"agentId":"b4730d7f-c54d-4736-8a04-c6203aa2fd49","role":"assigned"}]
attachments: []
createdBy: {"kind":"agent","agent_id":"a6c6ea12-bfc6-4bdc-8031-324102dfa34d"}
updatedBy: {"kind":"user"}
createdAt: 1785702748769
updatedAt: 1785881187672
version: 5
---
Le lot #133/#135 traite déjà le confinement du package installé et labsence décritures parasites au runtime, mais il reste un trou produit/API majeur : le SDK public et son exemple `sdk/IdeaSDK/examples/hello-plugin` montrent encore des écritures plugin sous `.ideai/hello-plugin.txt` et `.ideai/hello-plugin.json`, alors que lobjectif utilisateur est un modèle type VSCode où létat propre au plugin ne pollue jamais le projet et disparaît entièrement à la désinstallation.
Objectif de ce ticket : trancher le contrat darchitecture/API, PAS limplémenter.
À décider et documenter :
1. Séparer noir sur blanc les deux familles de données plugin :
- données métier du PROJET que le plugin modifie volontairement dans le workspace utilisateur (autorisées, explicites, relèvent de `workspace.*` / éventuellement `config` quand on touche un vrai fichier du projet) ;
- données PROPRES AU PLUGIN (prefs, cache, dernière sélection, index interne, état UI durable, config interne) qui doivent vivre hors project root, dans un store plugin-scopé sous app data, jamais sous `.ideai/` ni ailleurs dans le repo utilisateur.
2. Dire si `ctx.storage` clé/valeur suffit comme primitive canonique pour cet état plugin-owned, ou sil faut une API publique supplémentaire de document structuré plugin-scopé (ex: JSON app-data du plugin) pour éviter de pousser les auteurs à détourner `ctx.services.config` vers `.ideai/*.json`.
3. Figer le contrat de désinstallation : la suppression du plugin doit aussi supprimer 100% de son état plugin-owned hors projet (storage, éventuels docs/config plugin-scopés, caches internes), sans toucher aux fichiers métier du projet que lutilisateur a explicitement demandé au plugin de modifier.
4. Imposer lalignement doc/exemples SDK : ne plus montrer `.ideai/...` comme emplacement par défaut pour létat interne dun plugin.
Critères dacceptation :
- Une note darchitecture/API explicite distingue « project-owned » vs « plugin-owned ».
- La source de vérité et le cycle de vie du stockage plugin-owned sont écrits noir sur blanc (création, lecture, suppression à luninstall).
- Le ticket précise si une nouvelle API SDK est nécessaire ou si `ctx.storage` devient la voie canonique, et pourquoi.
- Le contrat est compatible avec lexigence utilisateur : plugin désinstallé => plus aucun état propre au plugin, ni dans le projet, ni dans lapp data plugin.

View File

@ -0,0 +1,6 @@
---
issueRef: "#139"
version: 4
updatedBy: {"kind":"user"}
updatedAt: 1785881187678
---

View File

@ -0,0 +1,17 @@
---
id: "a5bac900-806d-4e13-866f-7ebae686a43d"
number: 139
title: "SDK plugins: aligner lAPI publique et les exemples sur une persistance plugin-owned hors projet"
status: "closed"
priority: "critical"
sprint: null
links: [{"target":"#138","kind":"dependsOn"}]
agentRefs: [{"agentId":"fe887179-933f-47d4-960f-c3b06827f86c","role":"assigned"},{"agentId":"8f7da528-58df-4315-97e9-0562230ecc19","role":"assigned"}]
attachments: []
createdBy: {"kind":"agent","agent_id":"a6c6ea12-bfc6-4bdc-8031-324102dfa34d"}
updatedBy: {"kind":"user"}
createdAt: 1785702774592
updatedAt: 1785881187678
version: 4
---
Implémenter le contrat décidé en #138. Ce ticket ne doit démarrer quaprès arbitrage architecture, car la forme exacte de lAPI publique peut varier (`ctx.storage` canonique seul, ou nouvelle API publique de document structuré plugin-scopé hors projet).\n\nPérimètre attendu après #138 :\n1. Faire de la voie canonique plugin-owned celle décidée en #138, et retirer lincitation actuelle à écrire létat interne du plugin dans le workspace utilisateur / `.ideai/`.\n2. Mettre à jour `sdk/IdeaSDK/README.md` et `sdk/IdeaSDK/examples/hello-plugin` pour que lexemple de référence nécrive plus `.ideai/hello-plugin.txt` ni `.ideai/hello-plugin.json` comme état interne par défaut.\n3. Si #138 décide quune nouvelle API SDK publique est nécessaire (par ex. document structuré plugin-scopé hors projet), lexposer de bout en bout : types SDK, façade runtime publique, adaptateurs hôte nécessaires, et documentation dusage.\n4. Garantir que la désinstallation du plugin purge aussi létat plugin-owned correspondant, conformément au contrat #138, sans supprimer les fichiers métier du projet que le plugin aurait modifiés explicitement.\n\nCritères dacceptation :\n- Le README SDK sépare explicitement données project-owned vs plugin-owned.\n- Lexemple de référence nemploie plus `.ideai/...` pour stocker son état interne.\n- Si une nouvelle API publique a été décidée en #138, elle est documentée, typée et couverte par des tests.\n- La purge de létat plugin-owned à la désinstallation est prouvée par tests ciblés sur le chemin réellement choisi par #138.\n- Aucun message public du SDK ne laisse entendre que `.ideai/` est le lieu normal de persistance interne dun plugin.

View File

@ -0,0 +1,6 @@
---
issueRef: "#140"
version: 4
updatedBy: {"kind":"agent","agent_id":"a6c6ea12-bfc6-4bdc-8031-324102dfa34d"}
updatedAt: 1785760572251
---

View File

@ -0,0 +1,17 @@
---
id: "353aa2ae-cf98-4a63-b4fb-a15fdb801a0a"
number: 140
title: "[Bug] je ne peux pas editer le context projet d'un agent a la main"
status: "closed"
priority: "medium"
sprint: null
links: []
agentRefs: [{"agentId":"a6c6ea12-bfc6-4bdc-8031-324102dfa34d","role":"assigned"}]
attachments: []
createdBy: {"kind":"user"}
updatedBy: {"kind":"agent","agent_id":"a6c6ea12-bfc6-4bdc-8031-324102dfa34d"}
createdAt: 1785759952774
updatedAt: 1785760572251
version: 4
---
Quand je suis dans le panneau des agents, que je selectionne un agent, le context projet de l'agent s'affiche mal (il n'affiche que [object Object]) et si je l'edit, que je save, et que je le réouvre il estd e nouveau vide

View File

@ -0,0 +1,6 @@
---
issueRef: "#141"
version: 2
updatedBy: {"kind":"user"}
updatedAt: 1785838243826
---

View File

@ -0,0 +1,38 @@
---
id: "5ed1fc9b-1eef-4236-be89-e5d351ece549"
number: 141
title: "Supporter louverture des layouts plugins comme Android Health"
status: "closed"
priority: "high"
sprint: null
links: []
agentRefs: []
attachments: []
createdBy: {"kind":"agent","agent_id":"a6c6ea12-bfc6-4bdc-8031-324102dfa34d"}
updatedBy: {"kind":"user"}
createdAt: 1785766766212
updatedAt: 1785838243826
version: 2
---
Le plugin Android `dev.idea.android-plugin` déclare un layout `idea-android.health` et lenregistre correctement à lactivation, mais louverture depuis lUI échoue avec le message : « la création de layouts plugins nécessite une extension backend pas encore livrée ».
Constat confirmé :
- Ce nest pas un bug du plugin Android sur la déclaration/enregistrement du layout.
- Ce nest pas un problème du SDK sur le contrat de layout.
- Le blocage est côté IdeA host : le frontend expose bien les contributions de layout plugin, mais la création effective dune cellule/layout plugin depuis le sélecteur nest pas supportée de bout en bout.
Preuves repo :
- `frontend/src/features/layout/LayoutTabs.tsx` affiche explicitement ce message et mentionne labsence de lextension backend `create_layout` pour les plugin layouts.
- `frontend/src/features/plugins/PluginLayoutSelectorSection.tsx` documente aussi que la partie frontend est prête mais que le flux réel dépend dune extension backend non livrée.
- Le rendu dun `customPluginLayout` déjà présent semble supporté (`PluginLayoutCellView`, `CustomPluginLayoutCell`) ; le manque porte sur la création de cette cellule depuis lUI.
Attendu :
- Permettre à lutilisateur de créer/ouvrir un layout plugin déclaré dans un plugin installé et chargé, notamment `Android Health` du plugin Android.
- Étendre le flux de création de layout côté backend + DTO/layout kind si nécessaire pour supporter `customPluginLayout`/`pluginId`/`layoutType`/`state`.
- Retirer le message bloquant une fois le support livré.
Critères dacceptation :
1. Depuis le sélecteur de layouts, choisir `Android Health` crée une cellule/layout plugin valide dans larbre de layout.
2. Le layout `idea-android.health` du plugin `dev.idea.android-plugin` se rend correctement via le runtime plugin chargé.
3. Létat opaque du layout peut être persistant comme prévu par le contrat `customPluginLayout`.
4. Aucun message « extension backend pas encore livrée » napparaît plus pour les plugin layouts supportés.

View File

@ -0,0 +1,6 @@
---
issueRef: "#142"
version: 4
updatedBy: {"kind":"agent","agent_id":"a6c6ea12-bfc6-4bdc-8031-324102dfa34d"}
updatedAt: 1785796835464
---

View File

@ -0,0 +1,17 @@
---
id: "73c2a22d-86bb-4bf5-912b-7766a528d5e7"
number: 142
title: "Plugin SDK: backend support for plugin-hosted windows"
status: "closed"
priority: "high"
sprint: null
links: []
agentRefs: [{"agentId":"fe887179-933f-47d4-960f-c3b06827f86c","role":"assigned"}]
attachments: []
createdBy: {"kind":"agent","agent_id":"a6c6ea12-bfc6-4bdc-8031-324102dfa34d"}
updatedBy: {"kind":"agent","agent_id":"a6c6ea12-bfc6-4bdc-8031-324102dfa34d"}
createdAt: 1785794926619
updatedAt: 1785796835464
version: 4
---
Implement the backend/domain/application changes needed so plugin commands can open a new OS window that hosts a plugin-contributed layout, reusing the existing window pipeline and anti-duplication rules instead of inventing a parallel window system. Scope: extend the accepted view/window surface contract for plugin layout ids, preserve native panel behavior, and keep the window lifecycle compatible with the existing layout/window stores and commands.

View File

@ -0,0 +1,6 @@
---
issueRef: "#143"
version: 4
updatedBy: {"kind":"agent","agent_id":"a6c6ea12-bfc6-4bdc-8031-324102dfa34d"}
updatedAt: 1785796835483
---

View File

@ -0,0 +1,17 @@
---
id: "9e684778-62df-491f-b824-d74960bd6b9d"
number: 143
title: "Plugin SDK: frontend host for plugin windows and window-open API"
status: "closed"
priority: "high"
sprint: null
links: []
agentRefs: [{"agentId":"8f7da528-58df-4315-97e9-0562230ecc19","role":"assigned"}]
attachments: []
createdBy: {"kind":"agent","agent_id":"a6c6ea12-bfc6-4bdc-8031-324102dfa34d"}
updatedBy: {"kind":"agent","agent_id":"a6c6ea12-bfc6-4bdc-8031-324102dfa34d"}
createdAt: 1785794926635
updatedAt: 1785796835483
version: 4
---
Implement the frontend runtime and SDK service surface so a plugin menu command can open a new window rendering one of its declared layout contributions. Scope: route plugin window surfaces through the existing view-window host, reuse plugin layout rendering/fallback behavior, and expose a public `services.windows.open(...)` API validated against declared layout ids.

View File

@ -0,0 +1,6 @@
---
issueRef: "#144"
version: 4
updatedBy: {"kind":"agent","agent_id":"a6c6ea12-bfc6-4bdc-8031-324102dfa34d"}
updatedAt: 1785796835501
---

View File

@ -0,0 +1,17 @@
---
id: "7ed6eb7f-713e-41c6-a0b4-9783acf68268"
number: 144
title: "Plugin SDK: shared React runtime for plugin layouts"
status: "closed"
priority: "high"
sprint: null
links: []
agentRefs: [{"agentId":"8f7da528-58df-4315-97e9-0562230ecc19","role":"assigned"}]
attachments: []
createdBy: {"kind":"agent","agent_id":"a6c6ea12-bfc6-4bdc-8031-324102dfa34d"}
updatedBy: {"kind":"agent","agent_id":"a6c6ea12-bfc6-4bdc-8031-324102dfa34d"}
createdAt: 1785794926654
updatedAt: 1785796835501
version: 4
---
Upgrade the plugin SDK/runtime so plugin-contributed layouts can be authored as real React components with JSX and hooks. Scope: resolve `react`/`react-dom` imports to the host instance, update SDK public types/tsconfig/package metadata accordingly, and refresh the hello-plugin example to demonstrate the supported React authoring model.

View File

@ -0,0 +1,6 @@
---
issueRef: "#145"
version: 4
updatedBy: {"kind":"agent","agent_id":"a6c6ea12-bfc6-4bdc-8031-324102dfa34d"}
updatedAt: 1785796835521
---

View File

@ -0,0 +1,17 @@
---
id: "00df9acb-29ec-498b-b0dd-56af00b3d630"
number: 145
title: "Plugin SDK: expand and restructure SDK documentation"
status: "closed"
priority: "high"
sprint: null
links: []
agentRefs: [{"agentId":"8f7da528-58df-4315-97e9-0562230ecc19","role":"assigned"}]
attachments: []
createdBy: {"kind":"agent","agent_id":"a6c6ea12-bfc6-4bdc-8031-324102dfa34d"}
updatedBy: {"kind":"agent","agent_id":"a6c6ea12-bfc6-4bdc-8031-324102dfa34d"}
createdAt: 1785794926667
updatedAt: 1785796835521
version: 4
---
Produce a much more complete SDK documentation set under `sdk/IdeaSDK/docs/` with explicit file names and focused topics. Scope: turn the root README into a concise entrypoint/summary, add dedicated docs for manifest, activation/context, menus, layouts with React, windows, services, packaging/distribution, and keep the content aligned with the real runtime contracts and example plugin.

View File

@ -0,0 +1,6 @@
---
issueRef: "#146"
version: 3
updatedBy: {"kind":"agent","agent_id":"a6c6ea12-bfc6-4bdc-8031-324102dfa34d"}
updatedAt: 1785796835539
---

View File

@ -0,0 +1,17 @@
---
id: "1b3f9aa1-c16a-4fb7-aab0-a3c5b56b200b"
number: 146
title: "QA: validate plugin window opening, React layouts, and SDK docs/examples"
status: "closed"
priority: "high"
sprint: null
links: []
agentRefs: [{"agentId":"ab328d90-c307-4771-a3b6-6c56089c8506","role":"assigned"}]
attachments: []
createdBy: {"kind":"agent","agent_id":"a6c6ea12-bfc6-4bdc-8031-324102dfa34d"}
updatedBy: {"kind":"agent","agent_id":"a6c6ea12-bfc6-4bdc-8031-324102dfa34d"}
createdAt: 1785794926679
updatedAt: 1785796835539
version: 3
---
Validate the plugin SDK feature set end to end after implementation. Scope: real test evidence that a plugin submenu click can open a new window, the opened window renders a React-based plugin layout correctly, layout state still round-trips, existing plugin layout cells still work, and the refreshed SDK docs/example match the shipped behavior.

Binary file not shown.

After

Width:  |  Height:  |  Size: 19 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 135 KiB

View File

@ -0,0 +1,94 @@
---
issueRef: "#147"
version: 8
updatedBy: {"kind":"agent","agent_id":"a6c6ea12-bfc6-4bdc-8031-324102dfa34d"}
updatedAt: 1785924224928
---
## Cadrage consolidé
### Intention produit
Créer une CLI custom alternative à la TUI native actuelle pour les cellules agent. Cette vue doit communiquer avec l'agent en headless et afficher une retranscription conversationnelle vivante de ce que fait l'agent, sans limiter ce qui fait la spécificité d'IdeA.
Références visuelles jointes : `task_completed.jpg`, `Cline.png`.
### Décisions validées avec l'utilisateur
- Tous les agents IdeA sont dans le périmètre, car le mode headless est considéré comme un socle du produit.
- Le choix `TUI native` / `CLI custom` est `par cellule`, uniquement quand la cellule est sur un agent. En mode `Plain`, le terminal reste inchangé.
- La TUI native reste le mode par défaut pour le moment.
- Le switch de mode est autorisé en cours de session, mais avec warning explicite et arrêt de la session courante pour éviter toute confusion utilisateur.
- Même logique quand on repasse de `CLI custom` à `TUI native`.
- Le bouton `cancel` doit se comporter comme une interruption du tour courant (analogue à `Esc` dans Claude/Codex), sans tuer la session elle-même.
- La vue custom est une retranscription live pendant la durée de vie de la session, comme la TUI actuelle ; ce n'est pas un transcript persistant indépendant.
- Si la session est toujours vivante quand on rouvre la cellule, on doit revoir l'historique live associé ; si la session est morte, non.
- On veut afficher un maximum de ce qui est exposé proprement par le headless : messages intermédiaires, progression, appels d'outils, édition de fichiers, final, etc. La règle est d'utiliser au maximum les features fournies par le headless, sans bricolage fragile.
- Si certains rendus avancés (ex. code avec syntax highlighting, détails riches de tool calls, etc.) ne peuvent pas être faits de manière propre et solide, ils ne doivent pas être forcés.
### Arbitrage prioritaire
Ordre de priorité explicitement demandé par l'utilisateur :
1. Robustesse
2. User experience
3. Beauté de la CLI
### Position de cadrage
Ce ticket ne doit pas être traité comme un simple ticket UI : il implique un vrai contrat runtime/headless pour piloter et afficher une session agent structurée. Le rendu en bulles est secondaire par rapport à la solidité des événements exposés et de la bascule de mode.
### Hypothèses de travail à privilégier
- S'appuyer sur le mode headless des agents et normaliser uniquement les événements réellement fiables.
- Prévoir une dégradation contrôlée quand un agent expose moins de richesse événementielle qu'un autre.
- Pour les fichiers joints, privilégier une solution robuste de staging temporaire par session si nécessaire, plutôt qu'un mécanisme dépendant du provider.
- Garder la CLI custom comme vue de session vivante, pas comme nouvelle source de vérité persistante.
### Questions résiduelles à arbitrer techniquement pendant le cycle
- Contrat précis des événements normalisés côté IdeA (`message`, `tool_call`, `tool_result`, `file_edit`, `status`, `final`, etc.).
- Comportement exact du staging temporaire des fichiers joints : durée de vie, nettoyage, taille max, comportement si le fichier source change.
- UX précise du warning de bascule de mode et du redémarrage de session.
- Stratégie de dégradation contrôlée selon la richesse réellement exposée par chaque agent headless.
## Exécution du cycle au 4 août 2026
### Architect
- Architect a revu le code réel et a conclu qu'il existe déjà un socle backend de chat structuré (`AgentSession`, `ChatBridge`, `ReplyChunk`, `reattach_agent_chat`) ; le ticket est donc une réintégration de la vue chat avec quelques compléments ciblés, pas une reconstruction complète.
- Contrats proposés : `preferred_view` persistant par cellule, `cancel_current_turn()` côté `AgentSession`, `ReplyChunk::UserPrompt`, toggle par cellule agent, vue live seulement, pas de transcript persistant secondaire.
### Git
- Branche de travail locale décidée par Git : `feature/ticket147-custom-chat-cli`.
- Base choisie : `develop`.
- Commit de bookkeeping déjà posé par Git : `efbd56a1 chore(tickets): sync carnets/issues #102/#141-#147 + agent glmopencode`.
### DevBackend — état réel livré
- Livré :
- `LeafCell.preferred_view` avec migration douce (`Tui` par défaut).
- mutation layout pour persister cette préférence.
- `ReplyChunk::UserPrompt` + ajout du prompt user dans le scrollback live.
- `AgentSession::cancel_current_turn()` avec défaut no-op.
- implémentation concrète best-effort du cancel pour `OpenCodeSession`.
- routage `interrupt_agent` selon `preferred_view`.
- commande Tauri `cancel_agent_chat(session_id)`.
- Limites explicitement laissées :
- pas de staging backend structuré des pièces jointes ; le frontend injecte actuellement le chemin dans le prompt.
- cancel concret non généralisé à tous les adapters.
- pas de nouvelle persistance de transcript hors session vivante.
- Tests annoncés verts par DevBackend : `cargo test -p domain`, tests `application` ciblés layout, tests `infrastructure opencode`, tests `app-tauri` ciblés `dto_chat` / `chat_bridge`, `cargo fmt`.
### DevFrontend — état réel livré
- Livré :
- toggle `TUI native` / `CLI custom` par cellule agent seulement, selon compatibilité structured/headless.
- modale de confirmation de switch avec arrêt + relance et wording dynamique.
- vue `CustomAgentChatView` live en bulles user/agent, rendu défensif, mise en avant du `Final` via `Task Complete`.
- composer texte + pièce jointe via `pickFile()` + bouton `Cancel`.
- reattach live de session structurée si elle est encore vivante.
- câblage TS des méthodes `launchAgentChat`, `reattachAgentChat`, `sendAgentChat`, `closeAgentChat` côté ports/adapters/mock.
- Limites explicitement laissées :
- pas de payload structuré pour les attachments ; chemin injecté dans le prompt.
- rendu limité aux chunks réellement exposés (`textDelta`, `toolActivity`, `final`, `error`, `userPrompt`).
### QA — verdict actuel
- Verdict QA au 4 août 2026 : **ROUGE** pour le MVP réellement livré.
- Finding bloquant principal : dans `CustomAgentChatView`, le bouton `Cancel` ferme la session structurée via `closeAgentChat` au lieu d'interrompre seulement le tour courant. Cela viole explicitement le contrat produit validé avec l'utilisateur.
- Finding secondaire : absence de test de non-régression couvrant ce comportement `Cancel`.
- Côté frontend, `npx vitest run` a été exécuté par QA et est vert (`115` fichiers / `1083` tests).
- Côté Rust, QA n'a pas obtenu de preuve globale exploitable dans le sandbox à cause de contraintes d'environnement (`Read-only file system`, verrous `cargo`, saturation temporaire `/tmp`).
### État d'avancement
- Le cycle a été lancé et exécuté jusqu'à QA.
- Le ticket n'est pas encore validé parce qu'il reste un correctif frontend ciblé à livrer sur `Cancel`, suivi d'une revalidation QA.

View File

@ -0,0 +1,23 @@
---
id: "64a8f704-df3e-40f4-9148-d39ae4f86af1"
number: 147
title: "[UI] créer une CLI custom alternative"
status: "closed"
priority: "medium"
sprint: null
links: []
agentRefs: []
attachments: [{"id":"06f4e827-d693-4190-9c53-186585602006","filename":"task_completed.jpg","path":"attachments/06f4e827-d693-4190-9c53-186585602006-task_completed.jpg","mime":"image/jpeg","sizeBytes":19288,"addedBy":{"kind":"user"},"addedAt":1785878707537,"summarizedInCarnet":false,"summarizedBy":null,"summarizedAt":null},{"id":"93c049aa-c5d5-44d5-a7d7-35ef929efd19","filename":"Cline.png","path":"attachments/93c049aa-c5d5-44d5-a7d7-35ef929efd19-Cline.png","mime":"image/png","sizeBytes":137940,"addedBy":{"kind":"user"},"addedAt":1785878711232,"summarizedInCarnet":false,"summarizedBy":null,"summarizedAt":null}]
createdBy: {"kind":"user"}
updatedBy: {"kind":"agent","agent_id":"a6c6ea12-bfc6-4bdc-8031-324102dfa34d"}
createdAt: 1785877963139
updatedAt: 1785924224928
version: 8
---
J'aimerais une CLI alternative pour mes agents. Cette CLI doit contenir bine entendu la barre de chat, ainsi que pour le reste de l'écran les bulle de conversation de l'agent et dde l'utilisateur. Cette CLI doit etre de la meme forme que ce qu'on peut voir dans les CLI des agents IA dans les IDE de code. Je veux voir s'afficher les reflexions de l'IA etc. La CLI communiquera en headless avec l'agent.
Cette CLI est alternative, il faudra simplement proposé un bouton en haut à côté du choix de l'agent pour proposer d'utiliser la CLI custom ou la CLI (fin la TUI de l'agent, celle qu'on utilise actuellement). Pour le moment, par défaut on utilisera la TUI comme actuellement.
Pour c equie st un peu du design, j'aimerais que les bulles de conversation de l'utilisateur soient allignée à gauche et que celle de l'agent soient alignées à droite. La couleur de sbulles de l'agents devront etre légèrement différente de celle de l'utilisateur. On devra pouvoir du coup envoyer un message ainsi que joindre un fichier. Une fois envoyé, on devra avoir un bouton pour cancel l'agent, encore une fois comme dans les CLI multi agent qu'on trouve ailleurs.
Je dirais que notre référence serait Cline, j'aime beaucoup le fait que le final soit mis en avent avec le Task Complete. Je mets des exemple dans les fichiers joint a ce ticket. Ce ne sont que des exemples, il faut que la CLI custom propose un maximum de ce qui fait d'IdeA une experience unique, il faut donc que la CLI ne limite pas IdeA

View File

@ -0,0 +1,6 @@
---
issueRef: "#148"
version: 3
updatedBy: {"kind":"agent","agent_id":"a6c6ea12-bfc6-4bdc-8031-324102dfa34d"}
updatedAt: 1785928836678
---

View File

@ -0,0 +1,17 @@
---
id: "1ec75572-ecfa-47f9-a051-2eeb434c65a7"
number: 148
title: "CLI custom: structured session introuvable au lancement"
status: "closed"
priority: "high"
sprint: null
links: []
agentRefs: [{"agentId":"8f7da528-58df-4315-97e9-0562230ecc19","role":"assigned"}]
attachments: []
createdBy: {"kind":"agent","agent_id":"a6c6ea12-bfc6-4bdc-8031-324102dfa34d"}
updatedBy: {"kind":"agent","agent_id":"a6c6ea12-bfc6-4bdc-8031-324102dfa34d"}
createdAt: 1785927987793
updatedAt: 1785928836678
version: 3
---
Bug report utilisateur du 2026-08-05: lors du lancement de la CLI custom, l'app échoue avec `not found: structured session 86248c8d-9c67-4512-872b-87b0213a625e`. Diagnostic Architecture: trou de contrat frontend dans `CustomAgentChatView` — seul `reattach_agent_chat` au mount gère `NOT_FOUND`; `send()` et `cancel()` propagent encore l'erreur brute, et le reattach post-launch avale toute erreur. Objectif: centraliser la récupération de session structurée, relancer proprement sur `NOT_FOUND`, couvrir par tests réels, puis rebuild l'AppImage Linux.

View File

@ -0,0 +1,125 @@
---
issueRef: "#149"
version: 25
updatedBy: {"kind":"user"}
updatedAt: 1785964173499
---
# Historique des tentatives
## 2026-08-05 — Implementation frontend bornee `cellKind` + validation QA verte
- **Pourquoi cette tentative change d'hypothese**: on ne repart pas sur `LayoutGrid` ni sur un nouveau patch `NOT_FOUND`. La tentative cible explicitement le desalignement possible entre la reponse reelle de `launch_agent` et ce que le frontend croit lancer en session structuree.
- **Manip/code reel cote DevFrontend**:
1. `frontend/src/adapters/agent.ts` relaie maintenant `cellKind` dans `LaunchAgentResponse` et refuse explicitement toute reponse `cellKind !== "chat"` dans `launchAgentChat()`.
2. En cas de routage non-chat, le frontend loggue `[ticket149] launchAgentChat:routed-to-non-chat` avec requete/reponse completes et leve `STRUCTURED_ROUTED_TO_PTY` **avant** de publier un faux `sessionId` structure.
3. `frontend/src/ports/index.ts` borne `AgentChatHandle` avec `cellKind: "chat"`.
4. `frontend/src/adapters/mock/index.ts` est aligne avec `cellKind: "chat"`.
5. Tests ajoutes/etendus:
- `frontend/src/adapters/agent.test.ts`: cas `cellKind: "chat"` accepte + cas `cellKind: "pty"` refuse.
- `frontend/src/features/agents/CustomAgentChatView.test.tsx`: non-regression garantissant qu'un lancement route vers PTY ne publie pas de `sessionId` et n'appelle pas `reattachAgentChat`.
- **Commandes executees par DevFrontend et resultat exact**:
1. `cd frontend && npx vitest run src/adapters/agent.test.ts src/features/agents/CustomAgentChatView.test.tsx` -> succes ; `2 passed`, `23 passed`.
2. `cd frontend && npx vitest run` -> succes ; `116 passed`, `1102 passed`.
3. `cd frontend && npm run build` -> succes ; `tsc --noEmit && vite build` OK.
4. tentative de commit locale -> echec sandbox: `fatal: Unable to create '/home/anthony/Documents/Projects/IdeA/.git/index.lock': Read-only file system` ; aucun commit cree dans ce tour.
- **Validation QA reelle sur commande**:
1. `cd frontend && npx vitest run src/adapters/agent.test.ts src/features/agents/CustomAgentChatView.test.tsx` -> succes ; `Test Files 2 passed`, `Tests 23 passed`.
2. `cd frontend && npm test` -> succes ; `Test Files 116 passed`, `Tests 1102 passed`.
- **Verdict QA**: lot frontend **vert** sur la branche `feature/ticket149-customchat-session-instrumentation`.
- **Resultat exact de cette tentative**:
- le frontend ne peut plus accepter silencieusement une reponse `launch_agent` routee en PTY comme si c'etait une vraie session chat structuree ;
- si le runtime route en `pty`, l'erreur devient explicite et exploitable, sans publication de faux `sessionId` ni boucle de `reattach` impossible.
- **Risque residuel maintenu explicitement**:
- ce verdict reste un verdict frontend/tests ; il manque encore la preuve runtime Tauri/AppImage du comportement reel sur un clic utilisateur, en particulier pour confirmer si le backend renvoie effectivement `cellKind: "pty"` dans le cas qui t'affecte.
- **Etape suivante**:
- faire retester la CLI custom sur le runtime reel contenant ce diff ; selon le message exact observe, trancher entre:
1. `STRUCTURED_ROUTED_TO_PTY` -> anomalie de routage/runtime a creuser ;
2. aucune erreur mais retombee -> bug frontend post-DTO restant ;
3. autre erreur -> nouveau symptome a classifier avec les logs `[ticket149]`.
## 2026-08-05 — Reprise Main: recadrage borne pour casser la boucle
- **Retour utilisateur de cette reprise**: la CLI custom ne se relance toujours pas, et le probleme est confirme comme etant **anterieur** a la tentative de fix sur `not found: structured session ...`.
- **Commandes / manipulations reelles executees**:
1. `git -C /home/anthony/Documents/Projects/IdeA status --short --branch` -> succes ; branche `feature/ticket149-customchat-session-instrumentation`, changements uniquement `.ideai/*` + changement non lie `.ideai/idea-android-plugin.json`.
2. `git -C /home/anthony/Documents/Projects/IdeA log --oneline --decorate -n 15` -> succes ; HEAD `7071c53b`, avec historique des fixes `ce9ba0dc` et des commits d'instrumentation/journalisation.
3. Delegation `Architect` -> succes ; recadrage: ne plus traiter `LayoutGrid` ni le simple `NOT_FOUND` comme racine sans preuve runtime nouvelle.
4. Delegation `DevFrontend` -> succes ; nouvelle piste concrete: l'adapter frontend ignore `cellKind` dans la reponse de `launch_agent`, alors que le backend peut router effectivement en `pty`.
5. Delegation `DevBackend` -> succes ; confirmation que `reattach_agent_chat` n'est pas une cause racine et qu'un `NOT_FOUND` est coherent si aucune session structuree stable n'a existe.
6. Delegation `Git` -> l'agent n'a pas rendu de reponse exploitable ; la decision court terme reste celle deja consignée: conserver la branche actuelle et interdire tout merge direct vers `develop`.
- **Decision de pilotage issue de cette reprise**:
- Le message `not found: structured session ...` est desormais a classer comme **symptome secondaire**.
- La prochaine preuve utile n'est pas un nouveau patch speculatif, mais la **reponse brute** de `launch_agent` au moment du clic CLI custom: `sessionId`, `cellKind`, `assignedConversationId`, `engineSessionId`.
- **Nouvelle hypothese de travail prioritaire**:
- Si `launch_agent` repond `cellKind: "pty"`, le frontend croit a tort avoir ouvert une session structuree et entre ensuite dans une boucle de reattach impossible.
- Si aucun `launch_agent` n'est appele, le bug est frontend **pre-launch**.
- Si `cellKind: "chat"` revient bien et que la vue retombe quand meme, le bug est frontend **post-DTO**.
- **Interdictions explicites pour eviter de reboucler**:
- ne pas refaire une nouvelle variation de `shouldFallbackCustomCliMode` / `LayoutGrid.tsx` ;
- ne pas ajouter encore du handling `NOT_FOUND` dans `CustomAgentChatView.tsx` ;
- ne pas reconsiderer l'echo `sessionId` comme cause racine ;
- ne pas pointer `reattach_agent_chat` tant qu'on n'a pas prouve qu'une vraie session `chat` a existe juste avant.
- **Etape suivante imposee**:
- demander a `DevFrontend` un patch borne d'instrumentation/guard sur `LaunchAgentResponse.cellKind` pour distinguer explicitement `chat` vs `pty` au moment du lancement custom, puis faire valider ce comportement par `QA` sur un repro reel.
## 2026-08-05 — Décision Git court terme
### État Git actuel
- **Branche active** : `feature/ticket149-customchat-session-instrumentation`
- **HEAD courant** : `7071c53b` (fix frontend NOT_FOUND)
- **Worktree** : modifications uniquement `.ideai/*` (métadonnées), aucun code source
### Décision Git EXPLOITABLE
1. **Branche à conserver** : `feature/ticket149-customchat-session-instrumentation` (contient `ce9ba0dc` et `7071c53b` qui ne sont PAS dans `develop`)
2. **Statut worktree** : RISQUE MINIMAL - modifications uniquement `.ideai/*`, pas de conflit prévisible
3. **Politique commit/merge** : INTERDICTION de merge direct vers `develop`. STRATÉGIE : cherry-pick sélectif des fixes fonctionnels (`ce9ba0dc` et/ou `7071c53b`) seulement quand validé, jamais les commits d'instrumentation
4. **Règle anti-boucle** : NE PAS retoucher LayoutGrid.tsx fallback pour une 4e fois sans trace runtime nouvelle. 3 tentatives sans effet valide, et TOUJOURS vérifier que le binaire testé contient bien les commits source (date AppImage vs date commit)
## 2026-08-05 — NOUVEAU RECADRAGE APRES RETOUR UTILISATEUR CRITIQUE
- **Retour utilisateur**: "je ne peux de nouveau plus lancer la cli custom" ET "on tourne en rond, c'etait deja le souci avant qu'on essaie de regler le message not found: structured session ..."
- **Consequence decisive**: le message `NOT_FOUND` N'EST PAS le bug source. Le bug original est revenu: la CLI custom s'ouvre 1/2 seconde puis retombe vers Plain/TUI **avant meme qu'une session structurée soit créée**.
- **Racine architecturale identifiée**: le symptôme `NOT_FOUND` n'était qu'un symptôme secondaire d'une tentative de reattach sur une session qui n'a jamais réussi à se stabiliser. Le vrai problème est dans le **pipeline de création/initialisation de session** entre l'action utilisateur et la stabilisation effective.
### Hypothèses INVALIDÉES (ne plus jamais retenter):
- ✗ Fallback premature dans `LayoutGrid.tsx` pendant chargement catalogue (3 tentatives sans effet)
- ✗ Echo `sessionId` auto-émis dans `CustomAgentChatView` (fixé mais n'a pas résolu le symptôme)
- ✗ Absorption de la forme brute `NOT_FOUND` (symptôme secondaire, pas la racine)
-`reattach_agent_chat` backend (idempotent par design, jamais démontré fautif)
### Périmètre DEVFRONTEND (nouvelle hypothèse):
- Investiger le pipeline complet d'initialisation custom — depuis l'action utilisateur jusqu'à la stabilisation de la session — en identifiant où la transition custom→Plain se produit AVANT même l'appel `launch_agent`.
- Vérifier particulièrement si un effet React ou une validation dans `CustomAgentChatView` ou `LayoutGrid` interrompt l'ouverture AVANT la création de session.
### Périmètre DEVBACKEND (nouvelle hypothèse):
- Vérifier la logique d'initialisation de session structurée côté Rust — en particulier si `launch_agent` peut échouer silencieusement ou retourner un état non valide qui déclenche un fallback frontend.
### Règle stricte pour les prochaines entrées de carnet:
1. Toujours vérifier si le symptôme observé se produit **avant** ou **après** la création de session structurée
2. Si avant: se concentrer sur le pipeline d'initialisation, pas sur la gestion des erreurs de session
3. Si après: alors seulement considérer la gestion `NOT_FOUND` / reattach
4. Documenter explicitement le point chronologique exact du fail dans chaque tentative
## 2026-08-05 — Nouvelle preuve runtime: `returned cellKind=pty; expected chat`
- **Retour utilisateur exact**: `custom CLI launch for agent a6c6ea12-bfc6-4bdc-8031-324102dfa34d in project 97b49ac2-8376-4aa3-8ea9-bf3ac81d0023 returned cellKind=pty; expected chat. sessionId=28b18fd2-e70c-4509-a633-e57e568234d9; nodeId=3e5d083c-4d04-41d6-a4e9-2970fc5b1fd6`.
- **Ce que cette preuve tranche**:
- le frontend a bien envoye une intention `chat` et a correctement refuse une reponse backend routee en `pty` ;
- le symptome n'est donc plus un fallback UI silencieux ni un `NOT_FOUND` tardif ;
- la prochaine cible de correction est le **routage backend/launcher humain** ou le **contrat de profil structured**, pas `LayoutGrid.tsx` ni un nouveau handling frontend du `NOT_FOUND`.
- **Retour Architecture**:
- cause probable: profil de l'agent sans `structured_adapter` effectif **ou** routage backend qui ne transforme pas l'intention `cellKind:"chat"` en exigence structured ;
- `cellKind` cote DTO est derive de la presence d'une session structured, donc `pty` prouve l'absence de session structured reelle au runtime.
- **Retour DevFrontend**:
- le frontend fait maintenant ce qu'on attend face a `pty` ;
- le message observe vient explicitement du garde `launchAgentChat()` et constitue une preuve que le runtime a renvoye `cellKind: "pty"` a une demande `chat`.
- **Retour DevBackend**:
- points de verite signales: `crates/application/src/agent/lifecycle.rs` pour le routage `LaunchAgent::execute`, `crates/backend/src/dto.rs` pour la derivation de `cellKind`, `crates/app-tauri/src/commands.rs` pour la conversion de la requete Tauri ;
- cause probable la plus plausible: le launch humain ne propage pas toujours correctement l'intention `chat` jusqu'au routage structured, ce qui laisse un fallback PTY possible.
- **Hypotheses INVALIDÉES supplementaires**:
- ✗ refaire un patch `CustomAgentChatView` pour tolérer `pty` ; ce serait masquer un contrat casse ;
- ✗ revenir encore sur les effets de chargement catalogue / `LayoutGrid.tsx` ; la preuve runtime est plus forte ;
- ✗ traiter `sessionId=28b18fd2-e70c-4509-a633-e57e568234d9` comme une vraie session structured ; le backend a explicitement renvoye `cellKind=pty`.
- **Règles anti-boucle a respecter desormais**:
1. Toute nouvelle tentative doit noter si le correctif vise **profil/config**, **routing backend**, ou **frontend** ; ne plus melanger ces pistes dans une meme iteration.
2. Aucun nouveau patch frontend de fallback/reattach tant qu'on n'a pas prouve que le backend renvoie bien `cellKind:"chat"`.
3. Toute validation doit citer la commande exacte et le type de preuve: test unitaire, test integration, ou repro runtime AppImage/Tauri.
4. Si un message futur mentionne encore `returned cellKind=pty; expected chat`, classer immediatement l'echec comme **routage/backend ou contrat profil**, pas comme regression `NOT_FOUND`.
- **Prochaine etape imposee**:
- faire valider par QA les tests backend/frontend lies a cette propagation `chat -> structured`, puis demander a Git de cadrer le commit local du correctif backend si la worktree contient bien le diff correspondant.

View File

@ -0,0 +1,29 @@
---
id: "1bd74960-361f-4083-acff-4c0b55cd920f"
number: 149
title: "CLI custom: une demande chat est routee en PTY au lieu d'une session structured"
status: "closed"
priority: "high"
sprint: null
links: [{"target":"#148","kind":"relatesTo"},{"target":"#147","kind":"relatesTo"}]
agentRefs: [{"agentId":"fe887179-933f-47d4-960f-c3b06827f86c","role":"assigned"},{"agentId":"8f7da528-58df-4315-97e9-0562230ecc19","role":"assigned"}]
attachments: []
createdBy: {"kind":"agent","agent_id":"a6c6ea12-bfc6-4bdc-8031-324102dfa34d"}
updatedBy: {"kind":"user"}
createdAt: 1785930073255
updatedAt: 1785964173499
version: 25
---
Bug report utilisateur confirme le mercredi 5 aout 2026: la CLI custom de l'agent Main peut de nouveau etre lancee, mais l'ouverture echoue avec le message runtime exact `custom CLI launch for agent a6c6ea12-bfc6-4bdc-8031-324102dfa34d in project 97b49ac2-8376-4aa3-8ea9-bf3ac81d0023 returned cellKind=pty; expected chat. sessionId=28b18fd2-e70c-4509-a633-e57e568234d9; nodeId=3e5d083c-4d04-41d6-a4e9-2970fc5b1fd6`.
Le ticket a ete initialement ouvert sur une hypothese frontend de fallback silencieux vers Plain/TUI pendant le chargement du catalogue agent/profil. Cette hypothese n'est plus la piste principale. La preuve runtime ci-dessus tranche que le frontend demande bien une cellule `chat`, mais que le runtime/backend renvoie effectivement `cellKind=pty`; le garde frontend rejette alors correctement la reponse au lieu de publier un faux `sessionId` structured.
Diagnostic courant consolide le mercredi 5 aout 2026:
- le message `not found: structured session ...` doit etre traite comme symptome secondaire historique, pas comme cause racine actuelle ;
- la prochaine cible de correction est le routage backend/human launcher et/ou la propagation du contrat `cellKind: chat -> require_structured`, pas un nouveau fallback `LayoutGrid.tsx` ;
- DevBackend a localise les points de verite dans `crates/app-tauri/src/commands.rs`, `crates/application/src/agent/lifecycle.rs`, `crates/backend/src/lib.rs` et `crates/backend/src/dto.rs` ;
- QA a valide sur l'arbre courant, le mercredi 5 aout 2026, les tests cibles backend/frontend couvrant cette propagation.
Objectif du ticket: garantir qu'un lancement custom CLI demande en `chat` ouvre une vraie session structured quand le profil le permet, et n'aboutit jamais a un retour `pty` silencieux ou a une boucle de reattach secondaire.
Voir le carnet pour l'historique detaille, les hypotheses invalidees et les regles anti-boucle.

View File

@ -0,0 +1,6 @@
---
issueRef: "#150"
version: 2
updatedBy: {"kind":"user"}
updatedAt: 1785964248745
---

View File

@ -0,0 +1,17 @@
---
id: "ebb59f0b-fb54-40f9-a4bc-d873f9716255"
number: 150
title: "CLI UI: messages utilisateur affichés en double dans la conversation agent"
status: "closed"
priority: "high"
sprint: null
links: []
agentRefs: []
attachments: []
createdBy: {"kind":"agent","agent_id":"a6c6ea12-bfc6-4bdc-8031-324102dfa34d"}
updatedBy: {"kind":"user"}
createdAt: 1785945386638
updatedAt: 1785964248745
version: 2
---
Depuis la CLI intégrée IdeA, les messages utilisateur apparaissent deux fois dans la conversation avec un agent. La capture fournie montre deux occurrences successives de "Qui es tu ?" dans la colonne de conversation. Attendu: un seul rendu par message utilisateur envoyé. Surface concernée: frontend UI conversation CLI.

View File

@ -0,0 +1,11 @@
---
issueRef: "#151"
version: 12
updatedBy: {"kind":"agent","agent_id":"a6c6ea12-bfc6-4bdc-8031-324102dfa34d"}
updatedAt: 1786036825333
---
## 2026-08-06 — Reopened from user validation on AppImage
- User retested the custom CLI on the current AppImage build.
- Regression still visible: the red `Cancel` button remains visually underneath adjacent toolbar controls while the conversation is busy.
- Scope for this new cycle: identify whether the issue is pure z-index/stacking, container overflow/clipping, or layout ordering in the custom CLI toolbar; fix without regressing idle-state controls.
- Main reopened the ticket and assigned it to DevFrontend for a full Architect -> Git -> DevFrontend -> QA -> Git cycle.

View File

@ -0,0 +1,17 @@
---
id: "c9aaa2e5-b17c-42ec-aa4c-2802a2863a1d"
number: 151
title: "CLI UI: chevauchement des boutons dans la barre supérieure pendant une conversation agent"
status: "closed"
priority: "medium"
sprint: null
links: []
agentRefs: [{"agentId":"8f7da528-58df-4315-97e9-0562230ecc19","role":"assigned"}]
attachments: []
createdBy: {"kind":"agent","agent_id":"a6c6ea12-bfc6-4bdc-8031-324102dfa34d"}
updatedBy: {"kind":"agent","agent_id":"a6c6ea12-bfc6-4bdc-8031-324102dfa34d"}
createdAt: 1785945386695
updatedAt: 1786036825333
version: 12
---
Régression toujours présente sur la custom CLI: pendant une conversation agent active, le bouton rouge Cancel en haut à droite de la cellule reste sous/derrière les autres contrôles de la toolbar au lieu de passer au premier plan et de rester cliquable. Attendu: hiérarchie visuelle stable et z-order correct en état busy, sans recouvrement du bouton Cancel.

View File

@ -0,0 +1,6 @@
---
issueRef: "#152"
version: 3
updatedBy: {"kind":"user"}
updatedAt: 1786010223872
---

View File

@ -0,0 +1,17 @@
---
id: "3a501b32-7b71-43c5-838c-bfc7e772e860"
number: 152
title: "CLI UI: mauvaise mise à léchelle sur conversation longue, barre de chat hors écran"
status: "closed"
priority: "high"
sprint: null
links: []
agentRefs: []
attachments: []
createdBy: {"kind":"agent","agent_id":"a6c6ea12-bfc6-4bdc-8031-324102dfa34d"}
updatedBy: {"kind":"user"}
createdAt: 1785945386711
updatedAt: 1786010223872
version: 3
---
Quand la conversation CLI devient longue, le layout/scaling se dégrade et la barre de saisie sort de l'écran par le bas. Attendu: zone de messages scrollable, footer/input toujours visible dans le viewport de la cellule. Surface concernée: frontend UI layout CLI conversation.

View File

@ -0,0 +1,87 @@
---
issueRef: "#154"
version: 3
updatedBy: {"kind":"agent","agent_id":"a6c6ea12-bfc6-4bdc-8031-324102dfa34d"}
updatedAt: 1786007117802
---
## Objective
Build a first-class attachment pipeline for agent-facing chat flows so files provided by the user are persisted, referenced, and made readable by agents without relying on prompt-text hacks.
## Why this exists
Current custom agent chat can only append a picked local path into the prompt text. That is not a robust attachment model and it does not guarantee that the target agent sandbox can read the file. Clipboard-paste support should not be built on top of this weak contract.
## Product target
Match as closely as reasonable the ergonomics of Codex / Claude Code style attachments while staying aligned with IdeA architecture:
- attachments are first-class entities, not just a string in the prompt;
- files are persisted in a stable host-controlled location;
- agents receive attachment context through an explicit contract;
- sandbox readability is guaranteed by construction for attached files;
- the model can support images first, then general files, without redesign.
## Non-goals
- No one-off frontend-only workaround that stores a browser blob URL or injects base64 into the prompt.
- No attachment flow that depends on the source file remaining at an arbitrary user path outside IdeA-managed storage.
- No design that works only for one provider/profile while breaking the abstraction for others.
## Expected architecture
A solid outcome should include the following, subject to Architect arbitration:
1. A durable attachment store owned by IdeA for agent/chat inputs.
2. A stable attachment identity and metadata contract (id, filename, mime, size, source kind, storage path, createdAt).
3. A transport contract from frontend to backend that sends structured attachment intent rather than only prompt text.
4. A backend/application path that materializes attachments into the attachment store and exposes them to the launched agent session.
5. A sandbox policy/story that makes attached files readable by the target agent without broadening access to arbitrary user filesystem paths.
## Storage / sandbox direction
Preferred direction:
- store agent-chat attachments under a project-owned IdeA path, for example `.ideai/attachments/agent-chat/...` or equivalent durable app-owned location that is intentionally mounted/readable for agent runs;
- if temporary staging is needed, staging must still end in a durable managed location before send;
- the chosen location must be easy to add to sandbox readable roots with minimal blast radius.
Important constraint:
- attached files should be readable even when the original source came from clipboard paste or from a user path outside the project root.
## UX contract this foundation should unlock
- picker-selected files become first-class attachments;
- clipboard-pasted images can use the exact same downstream attachment pipeline;
- future drag-and-drop can reuse the same contract;
- chat UI can display attachment chips/previews based on metadata instead of raw path strings.
## Suggested work split
### Architecture
- define ownership and location of the attachment store;
- decide whether the store is project-local vs app-data with projection into sandbox roots;
- define DTO/port contract for structured chat attachments;
- define lifecycle rules (persist until manually removed? per conversation? per turn?).
### Backend / app-tauri / application
- add write path for attachment creation/import;
- add any read-model or DTO needed by the custom chat flow;
- ensure structured launch / send path can pass attachment references to the session layer;
- ensure sandbox roots include the managed attachment location with least privilege.
### Frontend
- stop treating chat attachments as prompt suffix text;
- represent selected attachments as typed UI state;
- render chips/previews from metadata;
- call the new attachment APIs.
### QA
- verify picked file outside project root becomes readable by the agent through managed import;
- verify attachment survives send and session restart expectations defined by architecture;
- verify sandbox does not gain broad arbitrary read access.
## Acceptance criteria
- There is a first-class attachment contract for custom/structured agent chat.
- A user-selected file is imported into IdeA-managed storage before send.
- The target agent can read the attachment from within its sandbox without extra manual permission tweaking.
- The prompt path no longer relies on a brittle plain-text `[Fichier joint: ...]` suffix as the only attachment mechanism.
- The contract is reusable by clipboard image paste and future drag/drop.
## Risks to watch
- sandbox over-broadening to all of `$HOME` or arbitrary original source paths;
- provider-specific coupling that leaks one CLI's attachment semantics into the generic product contract;
- retention bloat if attachments are never garbage-collected;
- hidden duplication / large binary churn if images are copied repeatedly without lifecycle policy.
## Deliverable quality bar
This ticket is explicitly meant to prevent bricolage. If a proposed implementation cannot explain how attachment persistence, identity, routing, and sandbox readability work end-to-end, it is not sufficient.

View File

@ -0,0 +1,17 @@
---
id: "551a6639-315d-4ff3-8a01-7ecc077b0e30"
number: 154
title: "Foundation: durable agent/chat attachments pipeline with sandbox-safe file access"
status: "closed"
priority: "high"
sprint: null
links: []
agentRefs: []
attachments: []
createdBy: {"kind":"agent","agent_id":"a6c6ea12-bfc6-4bdc-8031-324102dfa34d"}
updatedBy: {"kind":"agent","agent_id":"a6c6ea12-bfc6-4bdc-8031-324102dfa34d"}
createdAt: 1785964740314
updatedAt: 1786007117802
version: 3
---
Build a first-class attachment pipeline for agent/custom-chat flows so user-supplied files are persisted, referenced, and readable by agents without prompt-string bricolage. Scope includes durable storage location, DTO/contracts, routing through structured chat flows, and sandbox/readability guarantees for attached files.

View File

@ -0,0 +1,26 @@
---
issueRef: "#155"
version: 12
updatedBy: {"kind":"agent","agent_id":"a6c6ea12-bfc6-4bdc-8031-324102dfa34d"}
updatedAt: 1786039145667
---
## 2026-08-06 — Reopened from user validation on AppImage
- User reports that clipboard paste in the custom CLI chat still does not work in practice.
- Suspected historical scope was around #154/#155; this cycle treats #155 as the user-visible clipboard UX bug and keeps the #154 attachment foundation dependency in view.
- Scope for this cycle: verify whether the regression is frontend paste interception, attachment import, backend routing, or AppImage/runtime mismatch; restore end-to-end paste of clipboard image/file into the custom chat composer.
- Main reopened the ticket and assigned frontend/backend ownership before architecture arbitration.
## 2026-08-06 — DevFrontend
- Frontend complété sur `fix/cli-tui-batch-2026-08-06`: le collage clipboard accepte maintenant les fichiers génériques en plus des images.
- Les fichiers venant de `clipboardData.items/files` sont convertis en attachment `contentBase64` avec `filename` / `mime` / `sourceKind=clipboard` ; les images conservent une preview, les autres fichiers partent comme attachments sans preview.
- Tests frontend verts : `cd frontend && npx vitest run src/features/agents/CustomAgentChatView.test.tsx src/features/layout/LayoutGrid.chat.test.tsx src/features/layout/singletonAgent.test.tsx` -> 46 passed ; `cd frontend && npm run typecheck` -> exit 0 ; `cd frontend && npx vitest run` -> 117 files, 1130 tests passed.
## 2026-08-06 — DevBackend
- Vérification backend effectuée. Aucun changement backend requis pour le scope image/fichier depuis clipboard : le pipeline existe déjà côté DTO/Tauri/application/infrastructure.
- `ChatAttachmentInputDto` accepte `path` ou `contentBase64`; `import_chat_attachments` et `agent_send` routent vers `ImportChatAttachments`; le store FS persiste chemins locaux et bytes clipboard dans `.ideai/attachments/agent-chat/<session>/`.
- Tests backend verts : `cargo test -p application --test chat_attachments -- --nocapture` -> 3 passed ; `CARGO_HOME=/tmp/idea-cargo-home cargo test -p infrastructure --test chat_attachments -- --nocapture` -> 4 passed.
## 2026-08-06 — QA
- QA a rejoué les validations frontend/backend ciblées avec succès.
- Verdict: VERT AVEC RÉSERVE. Le contrat frontend/application/infrastructure du collage image/fichier est vert, mais cette session ne fournit pas de preuve runtime/AppImage réelle d'un collage OS de fichier non-image.
- Décision QA explicite: si le ticket exige une preuve runtime/AppImage du collage clipboard fichier, il doit rester ouvert jusqu'à validation E2E sur l'AppImage.

View File

@ -0,0 +1,17 @@
---
id: "620bc08f-835c-483c-a9f1-59690ebf8ab5"
number: 155
title: "Custom chat: paste image/fichier depuis le clipboard dans le composer"
status: "qa"
priority: "medium"
sprint: null
links: [{"target":"#154","kind":"dependsOn"}]
agentRefs: [{"agentId":"8f7da528-58df-4315-97e9-0562230ecc19","role":"assigned"},{"agentId":"fe887179-933f-47d4-960f-c3b06827f86c","role":"assigned"}]
attachments: []
createdBy: {"kind":"agent","agent_id":"a6c6ea12-bfc6-4bdc-8031-324102dfa34d"}
updatedBy: {"kind":"agent","agent_id":"a6c6ea12-bfc6-4bdc-8031-324102dfa34d"}
createdAt: 1785964740363
updatedAt: 1786039145667
version: 12
---
Demande utilisateur requalifiée le 2026-08-06: la custom CLI ne permet toujours pas de coller un fichier dans la barre de chat, comme dans une TUI native Claude Code ou Codex. Le scope ne doit pas rester limité au seul collage d'image: il faut couvrir au minimum les fichiers/images exposés par le clipboard et les convertir en attachments utilisables dans le composer custom, via le pipeline d'attachments existant.

View File

@ -0,0 +1,50 @@
---
issueRef: "#156"
version: 7
updatedBy: {"kind":"agent","agent_id":"1ff94b51-3e17-4a39-8543-7715d1ff0f80"}
updatedAt: 1786014830849
---
# Objectif
Fournir une fondation canonique permettant d'exposer **tous les progress/events non terminaux réellement mis à disposition** par les profils IA, avant `Final`, sans coupler le produit au format d'un provider particulier.
# Pourquoi
Le comportement observé sur la CLI custom montre que certains profils, notamment Codex, donnent aujourd'hui une impression de silence jusqu'au `Final`, puis affichent certains appels/outils après coup. Même si une partie du "thinking" interne reste potentiellement indisponible, IdeA doit au moins projeter de manière cohérente tout ce qui est effectivement observable.
# Portée attendue
- Définir une taxonomie canonique d'événements intermédiaires utilisable par le chat agent et l'inter-agent.
- Couvrir un maximum de profils IA : Codex, Claude, profils structured/OpenAI-like, et futurs profils.
- Prévoir une dégradation propre quand un profil n'expose que `turn.started`/`Final`, ou seulement quelques items/outils.
- Séparer clairement :
- événements natifs du provider (text deltas, item started/completed, progress, etc.)
- observabilité locale IdeA (ex. calls MCP/tooling orchestrés par IdeA)
- Préserver la robustesse : aucun affichage temps réel ne doit devenir autorité de fin de tour.
# Contraintes / garde-fous
- Ne jamais promettre le streaming du raisonnement interne si le provider ne l'expose pas explicitement.
- Les événements intermédiaires sont "best effort" ; `Final` reste l'unique sortie terminale métier.
- Le contrat doit être provider-agnostic côté domaine/application ; les adapters font le mapping.
- Les appels MCP/outils orchestrés par IdeA doivent être projetables même si le provider reste silencieux.
# Livrables attendus
- Contrat d'événements canonique + mapping par famille de profils.
- Stratégie de transport/projection live jusqu'au frontend.
- Inventaire des événements accessibles par profil et des trous assumés.
- Tests de non-régression sur l'absence de blocage/buffering terminal.
# Questions à arbitrer
- Quels événements deviennent de première classe dans le contrat canonique ?
- Quelle granularité conserver pour les tool/MCP calls (start/end seulement, ou payload résumé) ?
- Quelle source de vérité pour les événements locaux IdeA vs les événements natifs provider ?
- Quelle stratégie de batching/throttling pour éviter le bruit tout en gardant du temps réel utile ?
# Définition de done
- IdeA sait exposer, au fil de l'eau, le maximum d'événements disponibles sans attendre systématiquement `Final`.
- L'absence d'événements d'un provider est traitée comme une limite du provider, pas comme un bug UI.
- Le comportement est documenté profil par profil.

View File

@ -0,0 +1,17 @@
---
id: "8ba27857-773a-4303-a7b5-ae7d688b3442"
number: 156
title: "Foundation: unified streaming progress/event model across AI profiles"
status: "closed"
priority: "high"
sprint: null
links: []
agentRefs: [{"agentId":"fe887179-933f-47d4-960f-c3b06827f86c","role":"assigned"}]
attachments: []
createdBy: {"kind":"agent","agent_id":"a6c6ea12-bfc6-4bdc-8031-324102dfa34d"}
updatedBy: {"kind":"agent","agent_id":"1ff94b51-3e17-4a39-8543-7715d1ff0f80"}
createdAt: 1785965383888
updatedAt: 1786014830849
version: 7
---
Define and implement a provider-agnostic progress/event pipeline so IdeA can expose as much non-terminal activity as each AI profile makes available before Final. Scope includes a canonical event taxonomy for chat/delegation flows, mapping from profile-specific adapters (Codex, Claude, OpenAI-style structured, and future profiles), and transport/projection rules that preserve robustness when some profiles expose little or no intermediate output.

View File

@ -0,0 +1,71 @@
---
issueRef: "#157"
version: 12
updatedBy: {"kind":"agent","agent_id":"1ff94b51-3e17-4a39-8543-7715d1ff0f80"}
updatedAt: 1786019394609
---
# Objectif
Améliorer la CLI custom / chat agent pour afficher **un maximum de progress intermédiaires réellement disponibles** au lieu d'un silence jusqu'au `Final`, avec une UX différenciée pour :
- les messages/progress agent généraux
- les appels MCP / outils
- les délégations inter-agent
# Dépendance
- Dépend explicitement de #156, qui doit fournir le contrat d'événements canonique multi-profils.
# Attentes produit
- Afficher les événements intermédiaires au fil de l'eau quand ils existent.
- Montrer clairement quel agent parle à quel agent.
- Afficher un extrait court de la demande déléguée.
- Rendre les appels MCP/outils visuellement distincts du reste du flux.
- Fonctionner avec un maximum de profils IA, avec dégradation élégante quand un profil n'expose pas grand-chose.
# Périmètre UI/UX attendu
## Types visuels
- `AgentMessage` : message/progress principal d'un agent.
- `Delegation` : carte dédiée `Agent A -> Agent B` avec extrait court de la demande.
- `ToolCall` : carte secondaire/indentée pour les appels d'outil.
- `MCPEvent` : variante spécifique pour les appels MCP/méthodes MCP, distincte visuellement.
## États
- `started`
- `running`
- `done`
- `error`
## Hiérarchie visuelle
- Les délégations et appels MCP ne doivent pas se confondre avec un simple texte agent.
- Les appels MCP/outils doivent être lisibles mais plus discrets que le message principal.
- Prévoir la lecture d'une conversation longue sans transformer l'écran en log brut.
# Recommandations UX initiales (retour UX intégré)
- `Delegation` : carte avec flèche `From -> To`, extrait de demande tronqué (~80 chars), accès au détail sur expansion/hover.
- `ToolCall` : carte indentée avec badge outil, état spinner/check/error, args résumés/tronqués.
- `MCPEvent` : bordure latérale/coloration dédiée par serveur ou type de méthode.
- Timeline verticale légère pour relier visuellement les sous-événements au message/agent source.
- Les événements très courts doivent être lissés/batchés pour éviter le clignotement.
# Anti-bruit / garde-fous
- Ne pas afficher comme texte brut tous les micro-événements sans hiérarchie.
- Seuil temporel ou batching pour les événements trop fugitifs.
- Possibilité de collapse/groupement pour tool calls répétitifs.
- Limitation du nombre d'événements visibles avant expansion.
- Si un profil n'expose aucun delta ni événement intermédiaire, afficher au minimum l'état occupé/vivant sans simuler un faux stream.
# Critères d'acceptation
- Sur les profils riches, l'utilisateur voit les progress/events apparaître avant le `Final`.
- Sur les profils pauvres, l'UI reste honnête et utile (busy/progression minimale) sans faux "thinking".
- Les appels MCP apparaissent au fil de l'eau, pas seulement après le `Final`, si l'information est disponible côté IdeA.
- Les délégations inter-agent sont lisibles : on comprend qui parle à qui et à propos de quoi.
- La vue reste stable et lisible sur conversation longue.

View File

@ -0,0 +1,17 @@
---
id: "d49aaae5-0d03-43fe-a51c-2ab5e921045c"
number: 157
title: "CLI custom: surface all available agent progress, MCP activity, and inter-agent delegation flow"
status: "closed"
priority: "high"
sprint: null
links: [{"target":"#156","kind":"dependsOn"}]
agentRefs: [{"agentId":"8f7da528-58df-4315-97e9-0562230ecc19","role":"assigned"}]
attachments: []
createdBy: {"kind":"agent","agent_id":"a6c6ea12-bfc6-4bdc-8031-324102dfa34d"}
updatedBy: {"kind":"agent","agent_id":"1ff94b51-3e17-4a39-8543-7715d1ff0f80"}
createdAt: 1785965383914
updatedAt: 1786019394609
version: 12
---
Suivi UX sur la custom CLI après livraison du flux Progress/MCP/inter-agent: l'affichage des messages de Progress est jugé correct, mais l'animation du rond/spinner affichée à côté du libellé Progress doit disparaître une fois l'événement terminé. Attendu: à la transition vers l'état terminal (done), la ligne Progress conserve éventuellement son contenu statique utile, mais n'affiche plus d'animation de chargement.

View File

@ -0,0 +1,6 @@
---
issueRef: "#158"
version: 4
updatedBy: {"kind":"agent","agent_id":"a6c6ea12-bfc6-4bdc-8031-324102dfa34d"}
updatedAt: 1786007117845
---

View File

@ -0,0 +1,17 @@
---
id: "67825d87-57d0-47c3-a44f-2916a342c542"
number: 158
title: "[Bug] popup reprise de conversation intempestive"
status: "closed"
priority: "medium"
sprint: null
links: []
agentRefs: [{"agentId":"a6c6ea12-bfc6-4bdc-8031-324102dfa34d","role":"assigned"}]
attachments: []
createdBy: {"kind":"user"}
updatedBy: {"kind":"agent","agent_id":"a6c6ea12-bfc6-4bdc-8031-324102dfa34d"}
createdAt: 1785965398697
updatedAt: 1786007117845
version: 4
---
J'ai la popup "Reprise de conversation" qui s'affiche de façon intempestive. Quand j'ajoute une cellule a mon layout, quand je change de layout, quand je change de projet etc. Elle n'a pas a as'afficher, la conversation doit continuer la ou on l'a laissé sans etre perturbée si une tache avant était en cours

View File

@ -0,0 +1,6 @@
---
issueRef: "#159"
version: 4
updatedBy: {"kind":"agent","agent_id":"a6c6ea12-bfc6-4bdc-8031-324102dfa34d"}
updatedAt: 1786007117864
---

View File

@ -0,0 +1,19 @@
---
id: "dfcbcdbf-2b1d-433a-a168-601c234cefaf"
number: 159
title: "[UI] Pastille d'activité de projet"
status: "closed"
priority: "medium"
sprint: null
links: []
agentRefs: []
attachments: []
createdBy: {"kind":"user"}
updatedBy: {"kind":"agent","agent_id":"a6c6ea12-bfc6-4bdc-8031-324102dfa34d"}
createdAt: 1785965966515
updatedAt: 1786007117864
version: 4
---
J'iamerais ajouter des pastiles d'activités qui se base sur les CLI custom. Quand je bosse sur plusieurs projets a la fois, j'aiemrais pouvoir voir quand un projet a fini de livré une demande. Pour faire simple je veux trois pastilles. Quand aucune custom cli du projet n'a de conversation en cours, je veux une pastille grise a gauche du nom du projet. Quand au moins une custom cli possède uine conversation mais ne travail pas, je veux une pastille fixe verte. Quand au moins une custom cli a une conversation et qu'elle travaille, je veux une pastille orange qui clignote.
Une cli custom qui travail est une cli custom a qui on a demandé une tache, et qui est en train de la faire (est en reflexion, ecrit du code, est en train d'utiliser un tool mcp, est en attente d'un tool mcp, par exemple en aillant délégué a un agent etc)

View File

@ -0,0 +1,6 @@
---
issueRef: "#160"
version: 3
updatedBy: {"kind":"agent","agent_id":"1ff94b51-3e17-4a39-8543-7715d1ff0f80"}
updatedAt: 1786014830849
---

View File

@ -0,0 +1,17 @@
---
id: "6d8084ea-6b8d-482e-9d6b-0d9bf5edec2b"
number: 160
title: "CLI UI: remove History button from custom chat toolbar"
status: "closed"
priority: "medium"
sprint: null
links: []
agentRefs: [{"agentId":"8f7da528-58df-4315-97e9-0562230ecc19","role":"assigned"}]
attachments: []
createdBy: {"kind":"agent","agent_id":"a6c6ea12-bfc6-4bdc-8031-324102dfa34d"}
updatedBy: {"kind":"agent","agent_id":"1ff94b51-3e17-4a39-8543-7715d1ff0f80"}
createdAt: 1786010666209
updatedAt: 1786014830849
version: 3
---
Remove the History button from the custom CLI/chat toolbar. User feedback is that it is not useful in this surface and it currently adds clutter around busy-state actions like Cancel. Scope: frontend toolbar only; no conversation persistence redesign.

Some files were not shown because too many files have changed in this diff Show More