Commit Graph

104 Commits

Author SHA1 Message Date
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
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
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
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
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
dce61ae1aa feat(sdk,plugins): API publique d'accès fichiers/workspace + analyse structure (#124,#129) 2026-08-02 13:34:54 +02:00
033e9a86d5 feat(sdk,plugins): ajoute capability tooling et services runtime publics (workspace/terminal/tasks)
- capability manifeste tooling supportée backend + transport runtime catalog
- ctx.services publique côté SDK/runtime, gated par tooling
- surface honnête: workspace, terminal, et tasks en observation/contrôle uniquement
- docs/exemple/tests mis à jour
- QA PASS sur feature/sdk-plugin-tooling-build-debug-surface
2026-08-02 00:31:15 +02:00
92b17e9a69 feat(skills): capacités agent découvrables via idea_list_agents
Ajoute SkillKind (Workflow/Reference) sur Skill, extrait le use case
ResolveAgentCapabilities à partir des SkillRef assignés, et enrichit
idea_list_agents d'un champ additif capabilities (name, description,
kind) — remplace l'exposition de SkillRef opaques par un inventaire de
capacités interrogeable, source commune avec le bloc « Skills
disponibles » injecté au lancement (#119).

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-08-01 00:26:56 +02:00
32c257d2e1 Merge branch 'feature/117-opencode-headless-recovery' into develop 2026-07-31 15:05:14 +02:00
10c0bef5e5 ticket117: synchronie métier idea_ask_agent + corrélation task ↔ rendezvous 2026-07-31 15:04:54 +02:00
fbe3c51fd4 ticket115: snapshot runtime skills assignés + durcissement idea_skill_read 2026-07-31 13:56:18 +02:00
d0b65a92bd fix(#108): restreint Code Mode Codex au namespace MCP IdeA et documente les tools au démarrage
Codex Code Mode pouvait appeler n'importe quel outil MCP directement,
contournant la médiation d'approbation. On force
[features.code_mode].direct_only_tool_namespaces = ["mcp__idea"] sur
chaque surface qui écrit le config.toml Codex (permission projector,
lifecycle, migration run-dir, assistant de ticket), et on ajoute
initialize.instructions côté serveur MCP pour orienter Codex vers le
bon outil idea_* dès la connexion, sans dépendre de la recherche
sémantique différée.

QA : domain 283/0, application 126/0 + agent_lifecycle 73/0 +
change_agent_profile 19/0 + ticket_assistant 5/0, infrastructure 339/0
dont mcp_server 37/0, backend 68/0 (7 ignored). Les échecs web-server
observés sur cargo test --workspace (Too many open files, cookies)
sont une contamination de ressources inter-tests ; les deux tests
concernés repassent isolément.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-29 22:51:38 +02:00
af6b76935c fix(#108): expose les tools MCP autorisées dès le démarrage de session Codex 2026-07-29 18:19:38 +02:00
21a84ab8f2 feat(mcp): synchronise les permissions MCP avec les tools réellement exposés
Les permissions déclarées ne reflétaient pas toujours les tools
effectivement exposés aux agents (contexte requester/projet lié après
coup). Ajoute ToolInvoker::tools_for_bound_context/tools_for_context
pour exposer la liste effective au moment de l'injection dans une
requête OpenAI-compatible, et propage le calcul dans la policy MCP,
le serveur, la factory de session et l'adapter openai_compat.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-07-29 15:57:45 +02:00
8158057b1d feat(tickets): ajoute les pièces jointes sur tickets (#108)
Stockage flat côté ticket + métadonnées d'attachments, lecture exposée côté
backend/MCP, et UI minimale de liste/ajout dans TicketDetail. Traverse le
domaine (Issue, ports), l'application (usecases + assistant de ticket), les
adaptateurs infra/MCP (issues store, orchestrateur), les DTO backend/web-
server/app-tauri, et le frontend (domain/ports/adapters/hooks/UI).

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-29 11:08:45 +02:00
6da52c6a02 wip(tickets): backend createdBy (#5) + bulk status/priority/delete (#6)
Ajoute created_by sur IssueIndexEntry/TicketSummaryDto + filtre createdBy
(#5), et les use cases BulkUpdateIssueStatus/Priority + BulkDeleteIssues
avec les DTO/outils MCP idea_ticket_bulk_* associés (#6).

NON VERT : BulkDeleteIssues::execute référence BatchIssueResult::deleted(),
constructeur pas encore ajouté à BatchIssueResult (seuls ok/err existent) ->
`cargo check` échoue (E0599 dans application::issues::mod). Reste à
DevBackend avant toute QA/merge.

Branché sur feature/sdk-integration (dépend du commit #2 dans
orchestrator/mcp/server.rs et tools.rs) ; à rebaser sur develop une fois
feature/sdk-integration mergé.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-07-28 18:28:39 +02:00
e74a9703f9 feat: livrable ticket #96 — effective permissions pour assistants de ticket 2026-07-27 13:37:08 +02:00
038e90ecec feat: livrable ticket #91 — notification fin BackgroundTask enrichie
- Backend: enrichissement HeadlessRendezvous avec requester/target/conversationId
- Frontend: toast 'Requester -> Target completed/...' explicite
- Clic ouvrant viewer de conversation pour visualiser l'échange
2026-07-27 09:05:34 +02:00
02603441c1 fix: livrable tickets #70 #100 #102 — UX surface scoping
- #70: implémentation suppression modèles locaux téléchargés
- #100: correction scroll OpenCode
- #102: correction fit TUI après switch/layout
- memory note scoping UX
2026-07-26 19:42:06 +02:00
ca70ec75f4 feat: catalogue dynamique modèles Codex/Claude avec compatibilité CLI locale
Ajout du catalogue enrichi pour les modèles Codex et Claude avec:
- Compatibilité estimée avec la version CLI locale détectée
- Source d'origine (catalogue/Provider) pour chaque entrée
- Support du catalogue Provider API externe
- Matrice de compatibilité embarquée dans l'application

Frontend:
- UI de configuration des modèles avec affichage des états de compatibilité
- Suggestions dynamiques avec badges de compatibilité
- Messages d'aide contextuels (compatible/unknown/likelyTooRecent)
- Alertes non-bloquantes pour les modèles trop récents
- Gestion des échecs de catalogue avec saisie manuelle conservée

Backend:
- Ports CliVersionReader, ProviderModelCatalogue, CompatibilityMatrixSource
- Implémentations: ProcessCliVersionReader, HttpProviderModelCatalogue, EmbeddedCompatibilityMatrix
- Enrichissement des DTOs avec compatibility, cli_version, warnings
- Tests unitaires complets pour le resolver de catalogue
2026-07-26 16:09:10 +02:00
0821739924 feat: finalise ticket99 - implémentation agent model configuration v2
- agent/lifecycle.rs: lifecycle management per profile
- agent/provider_catalogue.rs: provider registration with model support
- agent/usecases.rs: usecases for profile-based agent invocation
- agent/mod.rs: expose agent capabilities via AgentManager
- backend/dto.rs: AgentModelConfig, AgentProviderConfig DTOs
- domain/profile.rs: extend Profile avec agent capabilities
- domain/permission.rs: permission checks pour agent access
- infrastructure/assistant/mod.rs: agent integration
- infrastructure/permission/{claude,codex}.rs: permission handlers
- web-server/lib.rs: agent endpoints
- commands.rs: agent commands
- frontend/adapters/{http,profile,mock,domain}.ts: adapters
- frontend/first-run/FirstRunWizard.{test.tsx,tsx}: first-run flow
2026-07-26 13:38:18 +02:00
dae07d35bb feat: implémentation et QA ticket99 - agent model configuration v2
- backend A-C: VO Codex/Claude, renderers/projecteurs modèle, SecretRef/env, catalogues/use cases/Tauri commands
- frontend D: profils Codex/Claude provider->model->secret, validations, conservation SecretRef
- fix: app-tauri embedded_server isolant IDEA_WEB_ROOT

QA: backend 57/57 tests, frontend 74/74 tests OK
2026-07-26 11:56:25 +02:00
13fb538880 fix(permissions): validate network access flow 2026-07-26 10:52:46 +02:00
3047dc9195 feat(permissions): expose network permission state (#103) 2026-07-25 23:06:50 +02:00
6e98fd89f7 fix(runtime): isolate agent state by project (#101) 2026-07-25 22:14:02 +02:00
0f0a76d806 fix(backend): exclusion mutuelle des backends OpenCode (llamacpp vs cloud) (#97)
Les builders `with_opencode` / `with_opencode_provider` s'évacuent
réciproquement (dernier appel gagnant) pour honorer l'invariant
`opencode_backend_is_consistent`. Le use case SaveOpenCodeProviderProfile
route désormais via le builder au lieu de muter le champ directement — c'est
ce qui dupliquait `opencode` + `opencodeProvider` et forçait un repli sur
llamacpp même quand l'utilisateur choisissait un provider cloud.

Défense en profondeur côté store :
- `read_doc` répare les profils corrompus sur disque (drop du stale `opencode`)
- `save` refuse de persister un profil violant l'invariant via le nouveau
  variant `StoreError::Invalid` (mappé vers `AppError::Invalid`)

Tests verts : builders last-wins (domain), save rejets + read repair
(infra, profile_store 10/10).

Refs #97
2026-07-24 19:52:34 +02:00
56631bd3c8 fix(backend): projeter les EffectivePermissions dans le bloc permission d'opencode.json
Les 4 générateurs opencode.json/opencode_provider.json codaient en dur
{"bash":"ask","edit":"ask"}, ignorant les permissions configurées côté
IdeA pour l'agent. Claude et Codex appliquaient déjà PermissionProjector,
seul OpenCode passait à côté.

Ajoute domain::opencode_permission_block(eff: Option<&EffectivePermissions>)
qui mappe bash ← posture bash effective, edit ← posture Write effective
(Read/Delete non exprimables dans le schéma OpenCode, déjà enforcées par
le sandbox Landlock). eff == None omet la clé permission entièrement,
préservant le prompting natif OpenCode — même invariant que Claude/Codex.

Câble eff jusqu'aux 4 sites d'appel (lifecycle.rs + assistant/mod.rs,
variantes llamacpp et provider cloud). Le chemin ticket-assistant
(assistant/mod.rs) n'a pas de PermissionStore par agent pour l'instant,
donc eff y reste None (comportement inchangé, pas de régression).

Réf ticket #94.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-23 18:14:20 +02:00
e943a0efed feat(backend): catalogue de providers OpenCode dynamique + provider personnalisé (#92)
Le catalogue de providers OpenCode lit désormais le cache local
~/.cache/opencode/models.json pour refléter les providers réellement
disponibles, avec repli garanti sur le catalogue statique en cas
d'absence ou d'erreur de lecture du cache. Ajout d'un champ additif
`custom` sur OpenCodeProviderConfig pour permettre à l'utilisateur de
déclarer un provider hors catalogue (id + clé API en saisie libre).

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-23 12:43:59 +02:00
23a3c2788f feat(backend): support des providers OpenCode cloud (#92)
Ajoute le catalogue statique de providers OpenCode (lot B3), le stockage
sécurisé des secrets (SecretStore + adapter infrastructure), et les
use cases SaveOpenCodeProviderProfile/DeleteProfile câblés en composition
root. Couvre le fix B1 et les tests de régression demandés par QA.

cargo build --workspace propre, cargo test --workspace -- --test-threads=1
intégralement vert.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-23 08:03:03 +02:00
bb35641715 feat(backend): système de plugins — domaine, application, infrastructure (#43)
Lots B1-B4 : modèle de domaine des plugins (manifeste, capacités menus/layouts/MCP),
port et registre applicatif, chargement/validation en infrastructure, exposition DTO
et commandes Tauri. Tests cargo verts.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-07-22 07:37:03 +02:00
5175589aa5 feat(backend): domaine + catalogue et store durable des permissions tools MCP (#82 lot B1)
Introduit le domaine mcp_tool_permissions (règles de permission par tool
MCP) et étend le port de store correspondant. Le catalogue read/write des
tools MCP (orchestrator/mcp/tools.rs) s'appuie désormais sur ces règles, et
un store durable (mcp_tool_permission.rs) persiste les permissions au-delà
d'une session.

Lot B1 du ticket #82 : pose le socle domaine/store, l'enforcement suit en
B2 sur la même branche.

QA vert.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-07-18 22:45:32 +02:00
b4a34b40e5 fix(backend): identité requester explicite + policy des tools OpenAI-compatible (#62)
AgentSessionFactory::start propage désormais l'identité du requester aux
sessions structurées ; OpenTicketAssistant et LaunchAgent la portent
correctement de bout en bout. ToolPolicyRegistry est branché sur
AppOpenAiToolInvoker pour combler le trou de parité : TicketToolProvider
n'appliquait pas la policy des tools sur le chemin OpenAI-compatible,
contrairement au chemin structuré natif.

QA vert (échecs de bind loopback écartés comme non-régression préexistante,
tracés en #80).

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-07-18 22:35:17 +02:00
8fe93d1652 feat(backend): appareils appairés persistants, révocables et code éphémère (#77 B1-B4)
L'appairage ne survivait pas au redémarrage et son code, permanent, était
imprimé sur la sortie standard. Un appareil appairé devient une entité
persistante, nommée et révocable, derrière un code désormais éphémère.

- B1 : port DeviceSessionStore et adapter FsDeviceSessionStore, entités de
  domaine (PairedDevice, DeviceId, SessionTokenHash, DeviceName). Les tokens
  sont hachés en SHA-256 et comparés en temps constant (subtle) : le store
  ne peut pas rejouer une session qu'il a servie. Cookie Max-Age 400 j à
  renouvellement glissant, lastSeenAtMs throttlé.
- B2 : code éphémère en mémoire, TTL 10 min et usage unique, toute
  génération invalidant la précédente. POST /api/pairing-code authentifiée,
  flag --new-code. Le code est retiré du boot et l'eprintln! qui l'imprimait
  est supprimé.
- B3 : endpoints devices (list/rename/revoke/revoke-all/logout), event
  DeviceRevoked et ActiveConnectionRegistry par device_id, fermant sans
  délai les WebSockets d'un appareil révoqué.
- B4 : port PairAttemptLimiter et adapter mémoire, rate-limit par origine et
  global sur horloge injectée, donc testable sans attente réelle.

La normalisation du code passe côté serveur : elle absorbe la dette #76, que
la seule normalisation frontend de #75 ne faisait que masquer.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-17 13:26:56 +02:00
ebad5ff9f2 Merge feature/ticket60-ticket-assistant-no-reply into develop (#60)
Rendre visible l'échec « aucune réponse » de l'assistant de ticket :
stream sans Final ou Final vide → ReplyChunk::Error terminal visible,
plus jamais de tour muet. Backend + frontend, tests verts.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-15 08:48:04 +02:00
f7cae4c0a8 fix(model-server): deadline de warmup configurable pour le cold-start llama.cpp (#55)
Corrige la régression high « Error on loading local model » : le premier chargement
du serveur modèle local (cold-start llama.cpp) dépassait la fenêtre de readiness et
échouait. Le warmup dispose désormais d'un deadline par défaut de 600 s, surchargable
par config optionnelle `warmup_deadline_secs` (validée dans [30, 1800]).

- domain: champ `warmup_deadline_secs: Option<u64>` + validation de borne
- application: policy de readiness effective (défaut 600 s, override par config)
- app-tauri: DTO `warmupDeadlineSecs`
- infrastructure: application de la deadline effective au warmup

Verdict QA (vert) : domain 252, application 81 + 22 model_server, app-tauri
dto_model_servers 6, infrastructure model_server 2, build OK. Contrat readiness
couvert sur ports mockés.
Caveat : le cold-start end-to-end réel (llama-server) sort du sandbox de test ->
vérification manuelle utilisateur restante, non couverte par les tests unitaires.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-15 08:41:44 +02:00
2f7f111545 fix(ticket-assistant): rendre visible l'échec « aucune réponse » de l'assistant de ticket (#60)
Introduit un variant terminal `ReplyEvent::Error { message }` (domain/ports)
propagé jusqu'au chat : l'adapter OpenAI-compat récupère `reasoning_content`
quand `content` est vide, et un `Final` vide est converti en `Error` visible
plutôt qu'un tour silencieux qui pend. Le front (`ReplyChunk` + useTicketAssistant)
rend ce message d'erreur dans la cellule.

- domain: variant `ReplyEvent::Error`, bras non terminal (readiness, structured drain)
- infra/session: parse `reasoning_content` (delta/completion), fallback visible
- app-tauri: mapping ReplyEvent::Error -> ReplyChunk::Error, Final vide -> Error
- frontend: ReplyChunk `error`, rendu dans useTicketAssistant (+ test .test.tsx)

NB: commit sur la feature branch, PAS un merge. #60 reste inProgress.
Les 10 tests `cargo test -p infrastructure --lib session` échouent SOUS SANDBOX
uniquement (bind loopback 127.0.0.1:0 interdit -> Os PermissionDenied), pas une
régression : revérification hors-sandbox requise avant tout merge vers develop.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-15 08:32:59 +02:00
62b71776f5 fix(background-task): découpler la détection de fin de tâche du drain output PTY (#2)
Le runner de tâches de fond détectait la fin d'un process via l'EOF du drain de
sortie PTY, couplant le cycle de vie du process au flux d'output. Un output
encore ouvert (ou drainé ailleurs) pouvait masquer ou retarder la détection de
fin.

Ajoute wait/try_wait au port figé PtyPort :
- wait : bloquant, rend un ExitStatus idempotent ;
- try_wait : non bloquant, rend Option<ExitStatus> ;
- exit status mémorisé pour garder wait/try_wait/kill cohérents.
Implémentation dans PortablePtyAdapter (état d'exit mémorisé). Le
CommandBackgroundRunner détecte désormais la fin via pty.wait (select sur
cancel/deadline) au lieu de l'EOF du drain. Tous les fakes PtyPort du workspace
sont complétés en conséquence.

Le tee live UI reste hors périmètre (traité en #58). Aucun breaking IPC/front.

Tests : infrastructure/tests/background_task_runner.rs (nouveau) + pty_adapter.rs
verts, non-régression application/app-tauri OK (hors échecs réseau du sandbox).

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-14 23:42:40 +02:00
2183dfd291 feat(model-server): progression fine du téléchargement du modèle llamacpp (#54)
Stretch B2/F2 de #54, par-dessus le MVP déjà mergé (B1/F1).

Backend : le port de téléchargement HF publie une progression débouncée
(bytes reçus / total, pourcentage) via le stream de statut du serveur
modèle, avec gestion du total inconnu (pas de faux %), du cache hit,
de l'annulation et du timeout.

Frontend : l'overlay plein-cellule de préparation du serveur affiche la
progression réelle (barre, %, octets, source) en mappant le fil de
statut, avec la règle « pas de faux % » quand le total est inconnu.

Tests : application + infrastructure (téléchargement débouncé, cancel,
timeout, cache hit, total inconnu) et vitest (overlay + formatage pur).

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-14 10:37:14 +02:00
fe7ed0aa20 feat(model-server): afficher le téléchargement du modèle llamacpp au démarrage (#54)
Ajoute un handle du téléchargement des modèles lors du démarrage de
llamacpp : le domaine et l'application émettent la progression de
téléchargement du modèle, relayée en événement côté app-tauri, et l'UI
l'affiche via un badge de lancement et un overlay de cellule pendant que
le serveur de modèle démarre.

Backend (B1) : progression de téléchargement dans domain/application,
relais d'événement app-tauri, couverture de tests.
Frontend (F1) : modelServerLaunch, badge et overlay LayoutGrid, tests.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-13 23:14:05 +02:00
6387fac34f fix(windows): restauration panel-only des fenêtres détachées suivant le projet en focus (#47)
Partie backend. Les fenêtres/panneaux détachés étaient restaurés avec un
project_id figé au moment du détachement, si bien qu'ils restaient collés à
un projet mort ou incohérent après redémarrage. Ils sont désormais restaurés
en mode panel-only, sans project_id figé, et suivent le projet en focus de la
fenêtre principale via un event focused-project exposé par la couche fenêtre.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-13 12:37:25 +02:00
8570adb8e0 fix(ticket-assistant): édition de ticket via les tools MCP idea_ticket_* (#27)
L'assistant IA d'édition de ticket éditait les fichiers du ticket en direct,
hors de tout contrôle. Il passe désormais par les tools MCP idea_ticket_* :
préparation d'un environnement structuré dédié et policy d'enforcement scopée
au ticket courant, de sorte que l'assistant ne peut agir que sur son ticket
via la surface MCP plutôt que sur le système de fichiers.

Couvert par de nouveaux tests QA (mcp_server, assistant_context_store).

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-13 09:10:23 +02:00
2eb51d3335 feat(windows): persistance et restauration des fenêtres au redémarrage (#40)
Persiste l'état des fenêtres (layout/position) et le restaure au
relancement de l'application. Découpage hexagonal :
- domaine : modèle et port d'état des fenêtres (layout, ports)
- application : use cases de persistance/restauration
- infrastructure : store window_state (adapter de persistance)
- présentation : câblage app-tauri (state, commands, lib)
Couvert par des tests ciblés domaine/application/infrastructure.

Depend de #39 (fermeture des fenêtres auxiliaires).

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-13 08:00:20 +02:00
38aecf2cac feat(model-server): source Hugging Face (-hf) + options structurées llama.cpp + migration store V2
Backend du support natif d'une source modèle Hugging Face en alternative au
chemin .gguf local pour le serveur llama.cpp intégré, et refonte des options.

- domaine : ModelSource {LocalPath|HuggingFace} + HfModelRef,
  LlamaCppOptions {host,gpu_layers,context_size,jinja}, invariant auto_start
  exigeant une source, validate_free_args (rejet des flags réservés).
- infra : build_argv partagé avec build_spawn_spec, émission -hf vs --model,
  ordre argv figé ; migration model-servers.json V1 -> V2.
- app-tauri : DTO V2 (modelSource, compat modelPath, conflit = INVALID),
  commande preview_model_server_command.

QA : cargo test ciblés verts (domain 7, application 8, infra model_server 4,
app-tauri dto 5). Échecs des suites complètes infra/app-tauri environnementaux
(sandbox bind/socket), hors périmètre.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-12 14:31:54 +02:00
b82ac76f8b feat(model-server): backend modèles locaux — serveur llama.cpp intégré (#35) et profils OpenCode locaux multiples (#36)
Sprint « Modeles locaux », couche backend (domain/application/infra/app-tauri).

#35 — Serveur de modèle local intégré (llama.cpp) :
- domain: model_server.rs (agrégat + statut), ports ModelServerProbe /
  ManagedProcess / ModelServerRuntime / ModelServerRegistry, événements
  model_server_status_changed et agent_launch_failed.
- application: use case EnsureLocalModelServer branché sur LaunchAgent.
- infrastructure: adapters HttpOpenAiCompatibleProbe, LlamaCppRuntime,
  LocalManagedProcess, FsModelServerRegistry.
- app-tauri: DTO plat LocalModelServerConfigDto, commandes
  list/save/delete_model_server avec garde model_server_in_use, wiring.

#36 — Profils OpenCode locaux multiples :
- domain: VO LocalModelServerId, OpenCodeConfig.local_model_server_id.
- application: use case CloneOpenCodeProfileFromSeed.
- app-tauri: commande clone_opencode_profile_from_seed, DTO/wiring.

Tests verts (exécution réelle) : domain+application OK, app-tauri
dto_model_servers 3/3 et dto_profiles 10/10, infra model_server 2/2,
application model_server+profile_usecases 19/19, cargo build workspace Finished.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-11 15:50:08 +02:00
4e70631c40 feat(opencode): remplace le provider Ollama par llama.cpp
Le tool-calling local ne fonctionnait jamais via Ollama. Refonte du
support local d'OpenCode autour de llama.cpp: profil, catalogue,
matérialisation de la config OpenCode et surface first-run alignés sur
llama-server (backend + frontend).

QA vert (commandes réelles): domain 244, application 81+64, infra 263
(10 échecs = bind-port sandbox identiques sur develop, non-régression),
frontend 574, tsc propre. Réserve E2E live non bloquante faute de
llama-server joignable.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-11 00:41:19 +02:00
eaba05d27d feat(opencode): remplace le profil Ollama HTTP par OpenCode
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-09 15:48:07 +02:00
3abf2fce98 fix(runtime): detection non bloquante, bornée dans le temps, HTTP pour les profils locaux (#28)
Le first-run wizard restait figé : `CliAgentRuntime::detect` construisait un
runtime tokio courant-thread via `futures_block_on` pour piloter un
`ProcessSpawner` async. Appelé depuis le runtime async de Tauri, ce
`block_on` imbriqué panique ; la commande IPC ne répond alors jamais, la
promesse `detectProfiles` reste pendante et `busy` ne redescend plus.

Ce commit s'attaque à la cause côté backend :

- `AgentRuntime::detect` devient `async fn` (`#[async_trait]`) : le port cesse
  de mentir sur sa nature. Il pilote un spawner async, il est async. Le
  `futures_block_on` disparaît, et avec lui le runtime imbriqué.
- La sonde CLI est bornée par `tokio::time::timeout(DETECTION_TIMEOUT)` :
  un binaire qui ne rend jamais la main dégrade la détection en `Err`, il
  ne gèle plus l'appelant.
- Les profils `StructuredAdapter::OpenAiCompatible` n'ont pas de CLI à
  spawner : les sonder revenait à tester un binaire inexistant. Ils sont
  désormais sondés par un GET HTTP sur l'endpoint `/models` dérivé de
  `chat_http.endpoint`, borné par le même timeout.

`DetectProfiles` séquence les `await` sur les candidats. Les fakes
`AgentRuntime` des crates application/infrastructure/app-tauri suivent la
nouvelle signature.

Tests: cargo test -p domain (241), -p application (81), -p infrastructure
(269), -p app-tauri (63+15) — verts. `rg futures_block_on crates` sans match.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-08 08:11:14 +02:00
aab4bcafb6 feat(session): adapter HTTP OpenAI-compatible pour profils locaux/LAN (#14)
Ajoute un adapter de session HTTP OpenAI-compatible, purement additif,
permettant d'intégrer des modèles locaux/LAN comme profils IdeA canoniques
avec parité tool-calling/MCP.

- domain: extension du profil et des ports pour l'adapter OpenAI-compatible
- infrastructure: adapter openai_compat + routage factory
- app-tauri: mapping des outils OpenAI (openai_tools) + wiring state/lib
- application: catalogue d'agents + tests de use-cases profils

Validé QA (backend GO): round-trip byte-identique Claude/Codex, mapping
erreurs, dégradation tools, conversation_id None, conformance un seul Final,
routage factory. Suites vertes domain 467 / application 530 /
infrastructure 523 / app-tauri 247, 0 échec.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-07 22:09:16 +02:00
961a2cadc4 fix(assistant): retire le plan sandbox project_read_only de l'assistant de ticket (#25)
La surface « assistant de ticket » imposait un SessionPlan Landlock
restrictif (project_read_only) qui gouvernait la classe exec de la
sandbox OS et empêchait le spawn de la CLI (EACCES / os error 13).

factory.start reçoit désormais SessionPlan::None + sandbox absent :
l'assistant n'impose plus ce plan OS-sandbox. La classe exec n'est
plus verrouillée, le spawn de la CLI aboutit.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-07 17:28:30 +02:00
feeca3462c feat(tickets): filtres multi-critères par cases à cocher (backend + frontend)
Passe les filtres de la liste des tickets en sélection multiple (#12).

Backend Rust :
- IssueListFilter : statuses/priorities en Vec, filter_matches en OR intra-champ
  et AND inter-champs
- TicketListRequestDto en tableaux + from_request (parse/déduplication)
- MCP idea_ticket_list aligné sur le nouveau contrat

Frontend :
- TicketListQuery.statuses/priorities
- UI de cases à cocher, toggle/clear des filtres

Tests verts : issue_store (7), app-tauri --lib (59), mcp_server (24),
issue_usecases (6), sprint_usecases (6), frontend vitest (505), npm run build (exit 0).

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-06 06:41:01 +02:00