Commit Graph

290 Commits

Author SHA1 Message Date
b6238f002e fix(opencode): le Final textuel exploitable survit au changement de messageID du tour — sélection du message courant par priorité (texte non vide > erreur tardive > step/tool) élimine les NoReply sporadiques sur rendez-vous structurés — #254 (QA verte) 2026-08-24 12:21:02 +02:00
69129a95ad fix(templates): mcpToolPermissions persisté via create/update_template — désérialisation par alias préférés (mcpToolPermissions > defaultMcpToolPermissions > defaultMcpToolPolicy) sur les DTO Create/UpdateTemplateRequestDto — #244 (QA verte) 2026-08-24 11:46:14 +02:00
cd70a3c61b test(opencode): fiabilisation de la suite en parallèle — écriture atomique des fixtures, gates par fichier au lieu de sleep, runtime dédié par test, timeout 5s — #253 (QA verte) 2026-08-24 08:19:41 +02:00
d553d137ea fix(custom-cli): progression et messages d'outils restaurés au second tour — le projecteur ne retient plus les events de progress après le premier message, seuls Text/Error restent bufferisés — #252 (QA verte) 2026-08-24 08:04:49 +02:00
f1d85dfc5a fix(custom-cli): busy/progress/tools/chatbox bloqués après le premier appel — #245 (QA verte)
Backend : StructuredHumanTurnGuard pour partager la comptabilité busy/FIFO entre chat direct humain (agent_send, web chat.send) et asks inter-agents structurés, avec liveness mark_alive et retrait idempotent du tour. Web-server : tap d'événements sur chat.send pour le scrollback temps réel. Frontend : scoping des clés de progression par tour pour éviter la déduplication/ghosting des progress et outils entre appels.
2026-08-23 13:34:56 +02:00
0a7d7f844e fix(templates): open_project ne rétro-synchronise plus les permissions agents vers les templates — #244 (QA verte)
Suppression du backfill agent→template au open_project (cause racine de la non-persistance des permissions MCP/system des templates) et couverture de régression : create/read/update des default permissions + test dédié open_project sans backfill.
2026-08-23 13:03:07 +02:00
d6c80be56d feat(templates): nom d'agent par défaut + permissions système et MCP outils sur AgentTemplate — #242
AgentTemplate étendu (defaultAgentName, systemPermissions, mcpToolPermissions),
CreateTemplate/UpdateTemplate/CreateAgentFromTemplate projetés vers l'agent créé,
DTO/MCP tools et persistance store complétés. Correctif modèle par défaut:
UpdateTemplate ne persistait pas defaultProfileId (profil stale à la création
d'agent). Backfill best-effort des templates existants depuis les agents du
projet au open_project, overrides explicites uniquement.
2026-08-23 10:59:55 +02:00
1962408eda fix(session): un item.completed tardif n'efface plus le final agent_message Codex — #240
event_supersedes_pending_final ne fait plus annuler le final en attente par
tout événement autre que Heartbeat/RateLimited/turn-progress: seuls un progress
non-turn Started/Delta, un ToolActivity ou un Error annulent. Le buffering
agent_message survive ainsi jusqu'au flush a turn.completed (regréssion
codex_agent_message_survives_late_completed_item_as_final).
2026-08-22 17:27:13 +02:00
ade1908c76 fix(session): final de secours fabriqué depuis les deltas quand Claude ferme sans ligne result — #239
append_text_fallback_final accumule les TextDelta et produit un Final uniqne
en fin de flux si aucun Final/Error/RateLimited n'a été émis et que le texte
est non vide. Un long message utilisateur sur un autre projet (GameTime) ne
conclut plus a tort « La réponse du modèle n'a pas pu être finalisée. ».
Le test qui pinnait l'absence de Final devient la régression #239.
2026-08-22 16:38:47 +02:00
5449526157 fix(orchestrator): le lancement d'une cible structurée froide lie la session au fil A-B résolu par ask_agent — #238
ensure_structured_session reçoit désormais le conversation_id déjà résolu et le
transmet au plan de spawn au lieu de retomber sur le fallback User-B. WorkState
et la session lancée pointent ainsi sur le même fil. Test de régression
ask_cold_structured_agent_requester_launches_on_resolved_pair_thread.
2026-08-22 11:30:35 +02:00
f8cf86c6f5 fix(infra): temp IdeA géré alloué avant le convention file, exposé via IDEA_MANAGED_TMP et instruction explicite privilégiant le temp géré à /tmp — #200 2026-08-22 09:50:00 +02:00
3f3eb5938a fix(chat): capture du final et cause réelle des fins de tour « Le modèle n'a renvoyé aucune réponse. » — #231 2026-08-21 20:45:50 +02:00
3db23321a7 fix(web): gère les frames chat.attach/chat.send/chat.detach du structured chat — #231 2026-08-20 15:48:38 +02:00
023d483ba2 fix(web): émet chat.attached pour les sessions agents structurées au lieu de UNSUPPORTED — #229 2026-08-20 15:10:41 +02:00
e2d423f986 fix(agents): ne relaye plus le plan de sandbox OS aux providers structurés — #227
Les grants Landlock RO/RW empêchaient la custom CLI de démarrer côté web
téléphone avant d'atteindre le project root. Les providers structurés/headless
gèrent leur propre sandbox compatible CLI.
2026-08-20 14:07:07 +02:00
9a3ca51f6b fix(web): démarre le serveur MCP custom CLI via idea-serve au lieu de node — #224 2026-08-20 12:49:00 +02:00
bfa4d322e8 fix(git): peel les tags annotés vers leur commit cible dans log_graph — #218 2026-08-15 20:01:23 +02:00
b3fe1d57d1 fix(web): accepte GET /api/project-files* sans Origin (allow_missing ciblé) — #214 2026-08-15 17:49:22 +02:00
86f6c7ebf8 fix(web): route la famille layout dans /api/invoke + fallback UX restauration — #212
Le web-server ne routait pas load_layout (UNKNOWN_COMMAND a l'ouverture
d'un projet web PC). Alignement de l'adapter web sur les contrats Tauri:
load_layout, mutate_layout, list_layouts, create_layout, rename_layout,
delete_layout, set_active_layout. useLayout ne propage plus l'erreur
brute: message utilisateur + fallback singleLeafTree.
2026-08-15 11:40:00 +02:00
79fc3d184d feat(web): panneau Fichiers — navigation projet + téléchargements fichier/dossier ZIP — #211 2026-08-15 10:38:53 +02:00
b5653b24b5 feat(infra): temp IdeA généralisé à tous les agents + purge du store managed-tmp au shutdown d'IdeA — #200 (QA verte) 2026-08-15 00:14:25 +02:00
1157de1dda feat(infra): temp IdeA launch-scoped alloué par lancement d'agent, injecté via TMPDIR/TMP/TEMP, writable_roots + release au stop, fail-closed — #200 (QA verte) 2026-08-14 23:55:54 +02:00
a60fb3ed92 fix(sandbox): writable roots Codex dérivées des permissions effectives du menu agent — #197 (QA verte) 2026-08-14 15:05:15 +02:00
d0521db6b6 merge(infra): tests d'intégration managed temp handlers/routage — #191 (QA verte) 2026-08-13 14:23:17 +02:00
cc5a324bf8 test(infra): intégration handlers Tauri managed_temp_* + routage idea_managed_temp_* — #191 2026-08-13 14:23:03 +02:00
4e9b205b40 feat(infra): injection sandbox des handles managed temp résolus dans les sessions agents — #190 2026-08-13 14:08:36 +02:00
fdca55ecd4 feat(infra): tmp partagé inter-projets géré par IdeA (handles opaques, leases, GC, projection sandbox) — #189 (QA verte)
- Domaine: port ManagedTempStore + modèle (handle opaque, kind Directory/File, état Active/Released, allocation/lease, expiry).
- Application: use cases Allocate/Resolve/Release/GcManagedTemp, horodatés via Clock.
- Infrastructure: impl FS FsManagedTempStore sous app_data_dir/managed-tmp (root global inter-projets, métadonnées par handle, GC des leases expirés/libérés).
- Exposition MCP contrôlée (ManagedTempToolProvider, catalogue) + câblage sandbox: les agents résolvent un handle au lieu d'inventer un path libre.
- Tests: application/infrastructure managed_temp.
2026-08-13 13:34:33 +02:00
4f38e1c506 feat(cli): références d'attachments [file n]/[image n] dans le transcript + zone chat redimensionnable — #188 (QA verte)
- Attachments: projection canonique ChatPromptAttachmentDto (référence [file n]/[image n] par compteur de type, ordre d'import) insérée dans le prompt modèle et transportée par ReplyChunk::UserPrompt (attachmentRefs) ; rendu compact côté CustomAgentChatView.
- Resize: la zone chat (LeafView/LayoutGrid) est redimensionnable, taille actuelle conservée par défaut, préférence locale persistée.
- Tests: commands (projection des refs), dto_chat, chat_bridge, CustomAgentChatView, LayoutGrid.chat.
2026-08-13 13:01:03 +02:00
a3ee2814d6 fix(cli): progress agent_message émis en live + anti-doublon running/done par progressId — #187 (QA verte)
- Codex: les items agent_message sont désormais tapés en live comme progress (Message/Delta) dès item.completed, au lieu d'être bufferisés dans pending_final jusqu'à l'événement tool/MCP suivant.
- Corrélation stable progressId (codex:item:<id>) ajoutée sur ReplyProgress, propagée jusqu'au DTO (ReplyProgressDto.progressId) et au frontend ; le ProgressSettler et la vue procèdent par upsert running -> done au lieu d'empiler des lignes dupliquées.
- Tests: chat_bridge (settler par progressId), dto_chat, session codex, CustomAgentChatView (upsert par progressId).
2026-08-13 12:45:32 +02:00
e2fc85b434 fix(sandbox): accès Git minimal pour Codex — writable roots restreints au .git résolu, sans blanket grant project (#195, QA verte)
Codex ne pouvait pas accéder aux métadonnées Git sous sandbox workspace-write.
À l'inverse, la factory relayait jusqu'ici le project_root entier en --add-dir,
soit un grant large non défendable.

Change pour n'accorder en écriture (Codex --add-dir ET SandboxPlan OS) que le
.git réellement résolu :
- resolve_git_dir gère .git/ directory ET fichier worktree 'gitdir: <path>'
  (absolu ou relatif au parent du marker), puis canonicalize.
- enrich_sandbox_plan_with_codex_git_roots ajoute/déduplique les roots en RW
  sur le SandboxPlan existant (préserve l'autorité EffectivePermissions).
- factory: défaut writable_roots = Vec::new() en l'absence de policy explicite.

Invariants conservés :
- project_root n'est jamais injecté comme writable root.
- aucun élargissement au parent commun (canonicalize + BTreeSet).
- permissions MCP/globales inchangées (seul le plan runtime est enrichi).

Tests (crates/application) :
- standard .git/ dir -> root unique.
- projet non-Git -> aucun root.
- worktree (.git file gitdir:) -> résolution + canonicalization.
- symlink -> dédup, pas de grant parent.
- factory: défaut sans policy n'émet plus --add-dir project_root.

Réserve QA: launch_conventionfile_injects_assigned_skills_in_order
(agent_lifecycle) arbitré hors-scope/non bloquant pour #195.
2026-08-12 16:41:25 +02:00
803e9de093 fix(runtime): cancel en cascade des tasks filles — stop agent / cancel parent (#200, QA verte)
Cancel transitif, idempotent et ownership-aware sur le graphe parent→enfants des background tasks:

- domain/background_task + ports: modèle parent/enfant (parent_task_id, rejet du self-parent), index children_by_parent, traversal des descendants en largeur.

- application/background + infrastructure/store: cascade cancel (annule les descendants running/open, laisse les terminaux), idempotente face aux double-cancel et ordres de terminaison non déterministes; respect de l'ownership (parent_task_link).

- orchestrator/service: stop agent → cascade cancel des tasks lancées par cet agent (relatesTo #196); cancel task parent → cascade de ses sous-tasks (dependsOn #199). Refactor unifiant le chemin de cancel, sans sémantique #196/#199 regreffée (tests hérités verts).

- frontend: projection parentTaskId (workstate normalization/domain/services).

Tests QA verts: domain background_task, application background_task_cancel (cascades_background_task_subtree, cascades_to_running_child, cascades_to_open_descendants_and_leaves_terminal_child, parent_task_link_roundtrips_and_rejects_self_parent), orchestrator_service, workstate_actions, workstate.test.tsx.
2026-08-12 16:02:17 +02:00
46103397de fix(runtime): cancel de background task immédiat et fiable depuis le workstate (#199, QA verte)
Transforme l'annulation d'une background task en contrat immédiat, observable et non-best-effort:

- domain/background_task: états Cancelling/Cancelled/CancelFailed et transitions idempotentes; un kill PTY qui échoue est surfacé en CancelFailed plutôt qu'en succès silencieux.

- infrastructure/runner + store: cancel effectif de la task ciblée, reconcile marque Cancelling même sans live handle, et départage CancelFailed des tâches pending au boot.

- application/background + workstate + orchestrator/wake: chemin de cancel initié depuis le workstate, projection synchronisée de l'état (pas d'attente d'un cycle ambigu).

- frontend: projection workstate de l'état cancelled/cancelling/cancelFailed (cancellingRow/cancelFailedRow/cancelButtons), normalization et services.

Tests QA verts: background_task_cancel, background_task_runner cancel_wins_even_if_output_is_still_available, background_task_store reconcile_marks_cancelling_without_live_handle_cancel_failed_and_pending, workstate.test.tsx.
2026-08-12 15:18:38 +02:00
bad7b4c2f3 fix(runtime): stop/restart d'agent visible robuste — kill réel, état stopped, relance froide (#196, QA verte)
Solidifie le cycle stop/restart d'un agent visible en cellule:

- terminal/registry: kill effectif de la TUI native et de la CLI custom, arrêt idempotent du live runtime (PTY + structuré), distinction nette « agent stoppé » vs « pas de session ».

- workstate + lifecycle: projection d'un état runtime explicite « stopped » (AgentRuntimeState: running/stopping/stopped/failedStart), réconcilié avec le live state; traitement des courses « agent not found ».

- relance froide via freshStart: repart de zéro sans réattacher une session morte et recharge la configuration courante de l'agent (y compris changement de modèle).

- contrat projeté côté adapters frontend (ports/domain/normalization/mock) pour la consommation UI future (#197/#198), sans surface UI ici.

Tests QA verts: workstate_actions, orchestrator_service stop_agent, agent_lifecycle (reopen/fresh_start), workstate stopped runtime state, vitest adapter stop_live_agent.
2026-08-12 14:56:02 +02:00
646b9d9284 fix(orchestrator): la délégation simple vers UX renvoie son Final structuré (#207, QA verte)
Une demande idea_ask_agent vers UX échouait avec « finished without a structured Final response » alors qu'Architect répondait. Deux causes corrigées:

- session/process: un tour CLI terminé en code non nul SANS stdout (ex. erreur 401/auth) renvoyait une sortie vide au lieu du stderr réel; l'orchestrateur concluait alors à un « no Final ». On remonte désormais le stderr effectif (drain sync + async + helper process_exit_message + test dédié).

- orchestrator/service: la branche « ask waiting on background » masquait le premier Final structuré; la réponse synchrone redevient le premier Final (suppression de active_rendezvous_has_background_tasks / mark_rendezvous_task_waiting).

Nettoyage runtime corollaire (#204): arrêt du live runtime stale (PTY + structuré) d'un agent recréé afin que la délégation route vers l'agent courant (LiveSessions, stop_live_agent_runtime_in_project, wiring backend via DeleteAgent::with_runtime_cleanup, lifecycle, workstate cascade).
2026-08-12 14:09:06 +02:00
ddecf9e0c5 fix(chat): reprise robuste au retour d'un layout non conversationnel (composer verrouillé selon l'état réel, replay complet du scrollback, plus de fausse terminaison 'no reply') (#190) 2026-08-11 19:50:35 +02:00
17b98e3d03 fix(tui): la bascule TUI native <-> CLI custom ne déclenche plus de faux conflit de visibilité (#189) 2026-08-11 19:27:15 +02:00
ee0ffd4e2d fix(chat): réattache persistante CLI custom et rendu tools/MCP/progress enrichi (#188)
Corrige la perte de session à la navigation: le démontage du CustomAgentChatView
appelait close_agent_session (destructeur) au lieu de simplement détacher le
transport. Désormais:

- nouvelle commande Tauri detach_agent_chat (+ ChatBridge::detach) qui libère le
  canal sans tuer la session ni le scrollback retenu; distinct de
  close_agent_session qui reste le close destructeur explicite;
- le frontend appelle detachAgentChat à l'unmount puis restore sa vue depuis un
  cache de session (turns + chunkCount) à la réattache;
- message « Reprise effectuée: N événements rattrapés… » quand la réattache
  rejoue plus de chunks que le cache local n'en avait conservé.

Enrichit le rendu tools/MCP/progress:

- ProgressSettler (chat bridge) émet un progress completed synthétique quand un
  spinner reste ouvert (nouvelle entité progress, chunk text/final/error): fini
  les spinners fantômes;
- les adapters claude/codex/opencode/openai_compat extraient un aperçu du
  payload (arguments/input/command/message/params) attaché au progress;
- bounded_reply_progress_preview (domain) garde les 4 premières lignes non
  vides, normalisation CR/LF;
- previewText (frontend) multiligne whitespace-pre-wrap, source/nativeEvent
  affichés sous le titre; suppression du flag settled et du Spinner inline
  devenus redondants (l'état est porté par le stage + le settler).

Tests: detach_agent_chat gateway (Tauri + mock), ProgressSettler, bornage
reply_progress, item_preview/tool_preview par adapter, réattache avec cache et
notice de rattrapage.
2026-08-11 18:49:12 +02:00
22ce2f62fd fix(chat): le bouton Stop de la CLI custom arrête l'agent en cascade (#187)
Le Stop du CustomAgentChatView n'annulait que le tour courant sans libérer la
session ni toucher aux tâches enfants ou appels MCP en cours. Il appelle
désormais stop_live_agent sur l'agent vivant, qui:

- ajoute le port StopAgentExecutionCascade (best-effort, idempotent), implémenté
  par OrchestratorService pour annuler les idea_run_in_background rattachés au
  rendez-vous actif (via BackgroundTaskRunner.cancel);
- cascade l'arrêt aux wait-dépendances (stop_turn_watch + preempt) pour
  interrompre les appels MCP et les attentes inter-agents;
- libère et supprime la session structurée.

UI: nouvel état "Arrêt en cours..." (bouton disabled + loading) pendant l'arrêt,
libération du sessionId, label expliquant la cascade demandée. La Tauri command
cancel_agent_chat est alignée sur stop_live_agent + stop_turn_watch agent et
dépendances.

Tests: SpyBackgroundRunner (cascade n'annule que les tâches rattachées),
workstate_actions cascade best-effort, CustomAgentChatView stop+cascade feedback
et fallback NOT_FOUND.
2026-08-11 18:14:47 +02:00
d9f949c0f2 fix(chat): restaure le collage des images dans le composer custom CLI (#184)
Le collage d'une image (ex. capture d'écran) échouait en environnement desktop : le presse-papier image n'est souvent pas exposé comme un File synchrone dans clipboardData.files, mais uniquement via l'Async Clipboard API. On ajoute donc un repli sur navigator.clipboard.read() (MIME image/*) quand l'événement de collage ne fournit aucun fichier. Le preventDefault() n'est émis que lorsqu'on a effectivement lu des fichiers issus de l'événement, afin de ne pas bloquer le collage texte quand le repli async ne remonte rien.

- refactor clipboardFiles(event) -> dataTransferFiles(DataTransfer) réutilisable
- dedupeKey robuste pour les images sans nom (mime + taille + contenu base64)
- ReplyChunk::UserPrompt porte désormais les labels d'attachments (DTO + accounting reply_chunk_bytes, skip_serializing_if Vec::is_empty)
- tests ciblés frontend (+219) et backend (chat_bridge/dto/attachments) verts

QA : tests ciblés verts. Réserve : environnement headless, pas de validation manuelle desktop — validation AppImage à confirmer en suivi.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-08-11 16:49:28 +02:00
94b4ce7e5f feat(chat): persistance bornee du brouillon custom chat par projet/layout (#182) 2026-08-11 16:24:20 +02:00
419987d890 feat(chat): colle les fichiers du presse-papiers via Ctrl+V dans le composer (#181) 2026-08-11 15:57:30 +02:00
5609c6a7a8 fix(slash-commands): route /clean et /help en commandes natives IdeA avant dispatch plugin (#183) 2026-08-11 15:46:59 +02:00
d6306bb513 fix(codex): intention pré-MCP reclassée en Announcement + doublon ToolActivity supprimé (#157 #171)
Un agent_message d'intention arrivant avant un tool (ex idea_ask_agent) n'est plus avalé comme faux candidat Final: tamponné puis reclassé en Announcement dès qu'un événement le détrône (helper event_supersedes_pending_final), sur le tap live comme sur le flux autoritatif. Les items reasoning/command n'émettent plus de ToolActivity de compatibilité en doublon du Progress canonique Completed -> supprime les doubles cartes tool/MCP à la source. Tests mod.rs alignés + nouveau cas agent_message_before_tool_becomes_announcement_before_tool_progress.
2026-08-10 18:37:17 +02:00
c5a38df2af fix(codex): activité tool/MCP émise en live pendant le tour (#58 #93 #171)
L'adaptateur Codex n'émettait Progress/ToolActivity qu'à item.completed. On capte désormais conversation.item.added / item.started / response.output_item.added (stage Started), item.updated (Delta) et conversation.item.done / response.output_item.done (Completed), en préservant le nom réel de l'outil (name / function.name / function_call.name).

Les outils idea_* sont taggés ReplyProgressSource::IdeaLocal / Kind::Mcp pour les distinguer du tooling provider. Corrige #93 (l'activité MCP idea_ask_agent devient visible avant le Final, nom non corrompu) et #171 (pipeline progress -> UI temps réel) ; base du rendu live #58.

Tests : 3 unitaires (started live, tag IdeaLocal/Mcp, done avec nom) + assertion d'intégration (MCP started tapé avant le Final). QA : verte (live).
2026-08-10 16:46:17 +02:00
836137a36d fix(opencode): streaming progress + bulle MCP pour la CLI custom (#157)
Override send_with_tap: progress/text/tool désormais projetés en live via LiveTurnProjector (au lieu d'un batch en EOF), en suivant le pattern de codex.rs.

Tagging des tool_use idea_* en Progress Mcp/IdeaLocal/Completed (tool_progress) pour faire apparaître la bulle MCP IdeA locale au moment de l'invocation.

Protection anti-replay de session continuée: hold_until_new_message + buffer pending n'émet que le message courant, jamais l'historique rejoué.

send() batch inchangé: stream_events ne filtre le Final que lorsqu'un tap est présent.
2026-08-09 23:06:41 +02:00
292a81ee60 fix(backend): disponibilité session user + hand-off CLI↔TUI sans collision — #169 #170 2026-08-06 20:00:36 +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
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
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
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