feat: add main features

Agents for developpement added + frontend add + backend added. Git viewer created + agent and template creator + layout and project creator
This commit is contained in:
2026-06-06 01:27:01 +02:00
parent 55b3bee2c8
commit 307ae71857
273 changed files with 48740 additions and 0 deletions

View File

@ -0,0 +1,54 @@
# L0 — Socle domaine & ports
**Binôme :** `dev-core-domain` / `test-core-domain`
**Crate :** `crates/domain` (pur, zéro I/O)
**Dépendances amont :** aucune (fondation du projet).
**Statut :** en cours.
## Objectif
Poser le **cœur hexagonal** : toutes les entités, value objects, invariants, **ports (traits)**, domain events et la **logique de layout pure**. Aucun adapter, aucune I/O.
## Périmètre (DEV)
### Entities & Value Objects (cf. ARCHITECTURE §3)
- IDs typés (`ProjectId`, `AgentId`, `TemplateId`, `ProfileId`, `SessionId`, `WindowId`, `TabId`, `NodeId`).
- `Project`, `ProjectPath`, `Agent`, `AgentOrigin`, `AgentTemplate`, `TemplateVersion`, `AgentProfile`, `ContextInjection`.
- `TerminalSession`, `SessionKind`, `PtySize`, `RemoteRef`/`SshAuth`, `GitRepository`, `AgentManifest`/`ManifestEntry`, `Workspace`/`Window`/`Tab`.
- `MarkdownDoc` (VO contenu .md).
- Tous les **invariants** documentés en §3 doivent être appliqués (constructeurs validants / `try_new`).
### Logique de layout pure (cf. ARCHITECTURE §7)
- `LayoutNode` (`Leaf`/`Split`/`Grid`), `SplitContainer`, `WeightedChild`, `GridContainer`, `GridCell`.
- Opérations **pures** : `split`, `merge`, `resize`, `move``LayoutTree -> Result<LayoutTree, LayoutError>`.
- Validation des invariants (poids > 0, pas de chevauchement de spans, surface couverte, 1 session par leaf max).
### Ports (traits) — définitions seulement, pas d'impl
`AgentRuntime`, `PtyPort`, `RemoteHost`, `ProcessSpawner`, `FileSystem`, `TemplateStore`, `ProjectStore`, `AgentContextStore`, `GitRepository`, `EventBus`, `Clock`, `IdGenerator` (signatures conceptuelles en ARCHITECTURE §4).
### Domain events & erreurs
- `DomainEvent` (enum complet de §3.2).
- Types d'erreur par domaine (`LayoutError`, et erreurs de port définies ici si partagées).
### serde
- Autorisé **uniquement** pour les types persistés (manifeste, layout, profils) — dérive `Serialize`/`Deserialize`. Aucune autre dépendance I/O.
## Périmètre (TEST)
- Invariants d'entités : rejets attendus (chemin relatif, `synchronized` sans template, port SSH hors plage, etc.).
- **Layout** (cœur du lot) : `split`/`merge`/`resize`/`move` — cas nominaux + cas d'erreur (chevauchement, poids ≤ 0, span hors grille, session dupliquée).
- Déterminisme via `FixedClock`/`SeqIdGenerator`.
- `ContextInjection` : validation des 4 variantes (target relatif, var env valide, flag non vide).
- Sérialisation round-trip JSON des types persistés.
## Definition of Done
- `cargo test -p domain` vert.
- `crates/domain/Cargo.toml` ne dépend d'aucun crate I/O (vérifié).
- Tous les ports compilent et sont documentés.
- Logique de layout couverte (cas limites inclus).
## Notes / points d'attention
- Choisir `async_trait` vs `-> impl Future` pour les ports I/O (à figer ici, impacte tous les lots).
- Garder les traits **fins** (Interface Segregation) : ne pas fusionner FS/PTY/Process.

View File

@ -0,0 +1,44 @@
# L1 — Composition root & IPC
**Binôme :** `dev-ipc-bridge` / `test-ipc-bridge`
**Zones :** `crates/app-tauri`, `frontend/ports`, `frontend/adapters`
**Dépendances amont :** L0 (ports figés).
**Statut :** suivant (enchaîné après L0).
## Objectif
Mettre en place le **squelette Tauri qui tourne** : composition root (DI), pont IPC bidirectionnel, et la couche ports/adapters du frontend (avec mocks) — pour que le front soit développable **sans backend** dès les lots suivants.
## Périmètre (DEV)
### Backend `app-tauri` (driving adapter + composition root)
- **Composition root** : instancier les adapters concrets (au départ : `LocalFileSystem`, `TokioBroadcastEventBus`, `SystemClock`, `UuidGenerator`) et les injecter dans les use cases via `tauri::State` (`Arc<dyn Port>`).
- Registre des `#[tauri::command]` (squelette, mapping DTO ↔ use case) et `ErrorDTO`.
- **`TauriEventRelay`** : souscrit l'`EventBus` domaine → relaie en events/Channels Tauri.
- **Bridge PTY ↔ Tauri Channel** (`tauri::ipc::Channel`) : infrastructure générique de flux d'octets par session (sera consommée par L3).
- App Tauri v2 minimale qui démarre (fenêtre vide).
### Frontend (hexagonal côté UI)
- `frontend/ports` : gateways TS (`AgentGateway`, `TerminalGateway`, `ProjectGateway`, `LayoutGateway`, `GitGateway`, `RemoteGateway`).
- `frontend/adapters` : impl via `@tauri-apps/api` (`invoke`/`listen`/`Channel`).
- `frontend/adapters/mock` : impl mock de chaque gateway.
- `frontend/app` : bootstrap React + Vite, provider de DI des adapters (réel vs mock).
## Périmètre (TEST)
- Backend : mapping commands ↔ use cases (un use case in-memory simple validant le wiring).
- Relais `EventBus` → events Tauri (un `DomainEvent` publié arrive bien côté relais).
- Front : chaque gateway mock satisfait l'interface du port (typecheck + tests Vitest).
- Provider de DI : bascule réel/mock fonctionnelle.
## Definition of Done
- L'app Tauri démarre (fenêtre vide) sur Linux.
- `cargo test -p app-tauri` et `vitest` verts.
- Front compile et tourne en mode **mock** sans backend.
- Aucun `invoke()` direct dans les composants (uniquement via gateways).
## Points d'attention / spikes
- Forme du bridge PTY↔Channel (backpressure) — préparé ici, stressé en L3.
- Convention de (dé)sérialisation DTO Rust ↔ TS (serde camelCase ?). À figer ici.

38
agents-dev/L10-windows.md Normal file
View File

@ -0,0 +1,38 @@
# L10 — Fenêtres & multi-window
**Binôme :** `dev-windows` / `test-windows`
**Zones :** `application`, `app-tauri`, `frontend/app`
**Dépendances amont :** L0, L1, L2, L4.
## Objectif
Gestion des fenêtres et onglets : un onglet par projet ; **drag d'un onglet hors de la fenêtre → nouvelle fenêtre OS** portant ce projet.
## Périmètre (DEV)
- Entités `Workspace`/`Window`/`Tab` + persistance (`workspace.json`, machine-local).
- Use case `MoveTabToNewWindow` (réaffectation `WindowId`, l'onglet est déplacé, pas dupliqué).
- `app-tauri` : création de `WebviewWindow`, transfert d'état, fermeture de l'onglet source.
- Front : barre d'onglets, drag & drop, restauration de session.
## Périmètre (TEST)
- `MoveTabToNewWindow` : invariants (un projet dans un seul onglet à la fois ; fenêtre ≥ 1 onglet ou fermée).
- Persistance workspace round-trip.
- Front : interactions onglets (mock).
## Definition of Done
- `cargo test` + `vitest` verts ; détacher un onglet en nouvelle fenêtre fonctionne (dev manuel).
## Avancement
### ✅ Backend (vert)
- **Domaine** : opération **pure** `Workspace::move_tab_to_new_window(tab, new_window)` (`layout.rs`) — l'onglet est *déplacé* (jamais dupliqué) ; fenêtre source vidée → supprimée ; onglet actif déplacé → repli sur un onglet restant. Variante d'erreur `LayoutError::TabNotFound`. 4 tests domaine.
- **Application** (`application/window/`) : `MoveTabToNewWindow` (charge le workspace, mint `WindowId`, applique l'op pure, persiste via `ProjectStore`). 2 tests (store mock). La persistance round-trip du workspace est déjà couverte par `FsProjectStore` (L2).
- `cargo test --workspace` : **323 verts, 0 régression** ; clippy clean.
### ✅ IPC `app-tauri` (vert)
- Composition root : use case `MoveTabToNewWindow` injecté. Commande `move_tab_to_new_window(tabId)` : applique la topologie (persistée) **et ouvre une vraie `WebviewWindow`** (primitive de détach résolue). DTO `MoveTabResultDto` + `parse_tab_id`. Test `tests/dto_window.rs` (2). Workspace **325 verts, 0 régression**, clippy clean.
### ⏳ Reste (fait pendant la refonte disposition L11)
- **Front multi-fenêtres** : adopter le modèle `Workspace`/`Window`/`Tab` persistant (aujourd'hui les onglets vivent en state React transitoire), barre d'onglets, **DnD detach** + handoff d'état vers la nouvelle fenêtre. Couplé à la refonte de disposition IDE (L11), donc traité là-bas pour éviter de construire une barre d'onglets jetable.
## Spike (cf. ARCHITECTURE §13)
- DnD inter-fenêtres Tauri (le DnD HTML ne traverse pas les fenêtres OS) → protocole « detach » via store + event.

View File

@ -0,0 +1,45 @@
# L11 — Packaging & livraison
**Binôme :** `dev-packaging` / `test-packaging`
**Zones :** `app-tauri` (bundle), CI
**Dépendances amont :** transverse (mûrit avec les autres lots) ; finalisé en fin de cycle.
## Objectif
Livrer IdeA : **`setup.exe` (NSIS) Windows** et **AppImage Linux multi-distro**. macOS plus tard.
## Périmètre (DEV)
- Config bundle Tauri v2 : NSIS (Windows), AppImage (Linux).
- Vendoring statique des deps natives (git2/openssl → préférer `rustls` pour russh ; features git2) pour la portabilité AppImage.
- Pipeline CI : build Linux + Windows, artefacts publiés.
## Périmètre (TEST)
- Le bundle se construit sur Linux et Windows (CI verte).
- L'AppImage **démarre sur ≥3 distros** (Ubuntu, Fedora, Arch) — smoke test.
- L'installeur Windows installe/lance/désinstalle proprement.
## Definition of Done
- CI produit un `setup.exe` et un AppImage fonctionnels ; smoke tests multi-distro verts.
## Spike (cf. ARCHITECTURE §13)
- AppImage multi-distro : glibc/openssl/libgit2 liés dynamiquement = risque ; valider le vendoring statique tôt (coordonné avec L8/L9).
## Notes de build vérifiées (2026-06-04, premier build sur Arch)
- **CLI** : `@tauri-apps/cli` v2 installé en devDependency frontend ; binaire à `frontend/node_modules/.bin/tauri`.
- **Hooks `tauri.conf.json`** : Tauri exécute `beforeBuildCommand`/`beforeDevCommand` avec cwd = `IdeA/crates/`. Les chemins npm doivent donc être `--prefix ../frontend` (et NON `../../frontend` ni `frontend`).
- **Arch Linux — `linuxdeploy` strip échoue** : le `strip` embarqué dans `linuxdeploy-x86_64.AppImage` ne comprend pas la section ELF `.relr.dyn` des libs Arch modernes (`libzstd.so.1`, `libyuv.so`…) → erreur `unknown type [0x13] section .relr.dyn`. **Parade** : exporter **`NO_STRIP=true`** avant `tauri build`. À intégrer dans la CI/scripts de build Linux.
- Build de référence OK : `cd crates/app-tauri && NO_STRIP=true tauri build --bundles appimage``target/release/bundle/appimage/IdeA_0.1.0_amd64.AppImage` (~101 Mo).
- Le 1er échec `failed to run linuxdeploy` masquait le vrai message (strip) ; `--verbose` est nécessaire pour le voir.
- **Écran blanc au lancement (Linux/WebKitGTK)** : le renderer DMABUF de WebKitGTK rend une fenêtre blanche sur beaucoup de configs Linux récentes (Mesa/Nvidia, fréquent sur Arch). **Fix baké dans `crates/app-tauri/src/main.rs`** : on positionne `WEBKIT_DISABLE_DMABUF_RENDERER=1` au début de `main()` (cfg `target_os = "linux"`, seulement si non déjà défini) avant l'init du webview. Plus besoin de variable d'env côté utilisateur. Vérifié visuellement OK sur Arch (UI projets + health-check rendus).
## Avancement (2026-06-05)
### ✅ Fait
- **Icônes** générées (`tauri icon``crates/app-tauri/icons/`, monogramme « IA » sombre/accent) — manquaient, requises par le bundle.
- **AppImage Linux reconstruite** : `target/release/bundle/appimage/IdeA_0.1.0_amd64.AppImage` (~103 Mo), validée (ELF AppImage-runtime, libfuse2 présent, se lance directement). `git2` lié à la **libgit2 système** via `.cargo/config.toml` (`LIBGIT2_SYS_USE_PKG_CONFIG=1`).
- **`beforeBuildCommand`/`beforeDevCommand`** confirmés à `--prefix ../frontend` (cwd des hooks = `IdeA/crates/`).
- **Refonte disposition IDE** (passe UI/altitude) ✅ : `ProjectsView` réécrit en disposition d'IDE — **barre d'onglets projets** en haut, **sidebar** (onglets Projects/Agents/Templates/Git, un panneau à la fois) + **zone principale** = `LayoutGrid` (grille de terminaux) qui remplit la hauteur. App shell en `h-full`. Composants `ProjectLauncher`/`ProjectTabs`/`Workspace` extraits. Hooks de test préservés ; front **158 tests verts**, `tsc` clean. (Note : `beforeBuildCommand` retiré de `tauri.conf.json` — chemins de hook ambigus selon le cwd d'invocation ; on **build le front manuellement** (`npm --prefix frontend run build`) avant `tauri build` lancé **depuis la racine du repo**. C'est le recette déterministe vérifiée.)
### ⏳ Reste
- **Vendoring statique** pour AppImage portable multi-distro : passer git2 en `vendored-libgit2` (nécessite **cmake**, absent de la machine actuelle) + `rustls` pour russh (L9). Aujourd'hui l'AppImage lie la libgit2 **système** → portable seulement vers des distros fournissant libgit2 ≥ 1.9.
- **Windows `setup.exe` (NSIS)** : non constructible ici (Linux) → CI Windows.
- **CI** Linux+Windows (avec `NO_STRIP=true` côté Linux) + smoke tests ≥3 distros.

22
agents-dev/L2-projects.md Normal file
View File

@ -0,0 +1,22 @@
# L2 — Projets & stockage
**Binôme :** `dev-projects` / `test-projects`
**Zones :** `application/project`, `infrastructure/{fs,store}`, `frontend/features/projects`
**Dépendances amont :** L0, L1.
## Objectif
Gérer le cycle de vie des projets (création par project root, ouverture, fermeture) et le stockage de base.
## Périmètre (DEV)
- Use cases : `CreateProject` (init `.ideai/` + `project.json` + registre), `OpenProject`, `CloseProject`/`CloseTab`.
- Adapters : `LocalFileSystem` (tokio::fs), `FsProjectStore` (registre projets + workspace en JSON dans données app).
- UI : sélection du project root, liste des projets, ouverture en onglet.
## Périmètre (TEST)
- Use cases avec `FileSystem`/`ProjectStore` mockés : création initialise bien `.ideai/`, invariants projet respectés (root absolu, unicité `(remote, root)`).
- Intégration ciblée : `LocalFileSystem` sur tmpdir, `FsProjectStore` round-trip.
- Front : feature projects avec gateway mock (RTL).
## Definition of Done
- `cargo test -p application -p infrastructure` (filtré projet) + `vitest` verts.
- Créer/ouvrir/fermer un projet de bout en bout (avec adapters réels en dev manuel).

View File

@ -0,0 +1,25 @@
# L3 — Terminaux & PTY (local)
**Binôme :** `dev-terminals` / `test-terminals`
**Zones :** `infrastructure/pty`, `application/terminal`, `frontend/features/terminals`
**Dépendances amont :** L0, L1.
## Objectif
Terminaux fonctionnels en local : ouverture PTY, I/O, resize, fermeture, rendu xterm.js, flux via Tauri Channel.
## Périmètre (DEV)
- Adapter `PortablePtyAdapter` (portable-pty) implémentant `PtyPort`.
- Use cases : `OpenTerminal`, `WriteToTerminal`, `ResizeTerminal`, `CloseTerminal`.
- Front : wrapper xterm.js, abonnement au flux d'octets (Channel), envoi des frappes/resize.
## Périmètre (TEST)
- Use cases avec `PtyPort` mocké (spawn/write/resize/kill appelés correctement).
- Intégration : `PortablePtyAdapter` lance `echo`/`printf` et reçoit la sortie attendue.
- Front : wrapper xterm avec gateway mock (frappe → write, octets reçus → rendu).
## Definition of Done
- `cargo test` (pty/terminal) + `vitest` verts ; un terminal réel utilisable en dev manuel sur Linux.
## Spikes (cf. ARCHITECTURE §13)
- ConPTY Windows (resize/signaux/exit codes).
- Backpressure/coalescing du flux haute fréquence via Channel.

21
agents-dev/L4-layout.md Normal file
View File

@ -0,0 +1,21 @@
# L4 — Layout tableur
**Binôme :** `dev-layout` / `test-layout`
**Zones :** `domain/layout` (déjà amorcé en L0), `application/layout`, `frontend/features/layout`
**Dépendances amont :** L0, L1, L3 (cellules ↔ terminaux).
## Objectif
Grille redimensionnable type tableur : N colonnes par ligne / M lignes par colonne indépendantes, **fusion de cellules**, persistance.
## Périmètre (DEV)
- Compléter la logique de layout pure du domaine (si reliquats post-L0).
- Use case `MutateLayout` (split/merge/resize/move) + persistance `.ideai/layout.json`.
- UI : grille redimensionnable (drag des séparateurs), création/suppression de cellules, fusion, mapping cellule → terminal.
## Périmètre (TEST)
- Domaine : opérations pures exhaustives (déjà couvertes L0, étendre cas combinés).
- Application : `MutateLayout` persiste et publie `LayoutChanged`.
- Front : logique de calcul des tailles de cellules (Vitest, pure) ; interactions de split/merge (RTL + mock).
## Definition of Done
- `cargo test` (layout) + `vitest` verts ; manipulation visuelle de la grille fonctionnelle.

View File

@ -0,0 +1,22 @@
# L5 — Profils IA & runtime
**Binôme :** `dev-ai-runtime` / `test-ai-runtime`
**Zones :** `infrastructure/runtime`, `application/agent`, `frontend/features/first-run`
**Dépendances amont :** L0, L1, L2.
## Objectif
Moteur IA flexible : profils déclaratifs, détection, first-run wizard. Cœur du « 100% IA, piloté par données ».
## Périmètre (DEV)
- Adapter `CliAgentRuntime` (un seul, piloté par `AgentProfile`) : `detect`, `prepare_invocation` (construit `SpawnSpec` + plan d'injection selon `ContextInjection`).
- Use cases : `DetectProfiles`, `ConfigureProfiles`.
- Stockage `profiles.json` (store global IDE).
- Front : **first-run wizard** demandant quels profils configurer ; commandes pré-remplies (Claude/Codex/Gemini/Aider) **éditables** ; ajout de **profil custom**.
## Périmètre (TEST)
- `CliAgentRuntime` : pour chaque stratégie d'injection (conventionFile/flag/stdin/env), le `SpawnSpec` produit est correct.
- `DetectProfiles` avec `ProcessSpawner` mocké (présent/absent).
- Front : wizard avec gateway mock (sélection, édition, ajout custom).
## Definition of Done
- `cargo test` (runtime/agent) + `vitest` verts ; wizard fonctionnel en dev manuel.

52
agents-dev/L6-agents.md Normal file
View File

@ -0,0 +1,52 @@
# L6 — Agents & contextes
**Binôme :** `dev-agents` / `test-agents`
**Zones :** `application/agent`, `infrastructure/store`, `frontend/features/agents`
**Dépendances amont :** L0, L1, L2, L3, L5.
## Objectif
Agents de projet : contextes `.md` dans `.ideai/`, manifeste, et **lancement d'un agent** (injection contexte + spawn CLI dans une cellule terminal).
## Périmètre (DEV)
- Adapter `IdeaiContextStore` (compose `FileSystem`) : lecture/écriture `.md` + `agents.json`.
- Use cases : `CreateAgentFromScratch`, `LaunchAgent` (résout profil+contexte, injecte, ouvre cellule PTY au bon `cwd`, spawn CLI), CRUD agents.
- Front : panneau agents (créer, éditer le `.md`, activer → terminal).
## Périmètre (TEST)
- `IdeaiContextStore` : round-trip `.md` + manifeste (intégration tmpdir + mock FS pour les use cases).
- `LaunchAgent` : ordre des appels (prepare_invocation → injection → pty.spawn) avec `cwd` correct.
- Front : feature agents avec gateway mock.
## Definition of Done
- `cargo test` (agent/store) + `vitest` verts ; activer un agent ouvre un terminal avec la CLI lancée (dev manuel).
## Spike
- Injection `conventionFile` : symlink vs copie ; conflits si `CLAUDE.md` existe ; symlinks Windows.
## Avancement
### ✅ Backend (vert)
- **Domaine** : `ManifestEntry` réconcilié avec le schéma documenté `agents.json` (ARCHITECTURE §9.1) — porte désormais `name` + `profile_id` ; helpers `from_agent`/`to_agent` (le manifeste est la forme persistée d'un `Agent`). Tests domaine maj, verts.
- **Infra** : `IdeaiContextStore` (`infrastructure/store/context.rs`) implémente `AgentContextStore` en composant `FileSystem` ; écrit `.ideai/agents.json` + `.ideai/agents/*.md`, location-neutre (réutilisable local/SSH/WSL). Test d'intégration tmpdir (5 tests).
- **Application** (`application/agent/lifecycle.rs`) : `CreateAgentFromScratch`, `ListAgents`, `ReadAgentContext`, `UpdateAgentContext`, `DeleteAgent`, et `LaunchAgent` (résout profil+contexte → `prepare_invocation` → injection → `pty.spawn` au bon `cwd` → event `AgentLaunched`). 9 tests use cases (ordre d'appel vérifié via trace partagée).
- **Spike `conventionFile`** tranché pour L6 : **copie** du `.md` vers le fichier conventionnel (ex. `CLAUDE.md`), écrasement si présent — choix portable (symlinks Windows = privilèges, sémantique SFTP/WSL divergente). Stratégie `Env` → chemin absolu du `.md` ; `Stdin` → contenu piped après spawn.
### ✅ Front (vert)
- **Port** `AgentGateway` étendu (list/create/read/update/delete/launch) + type `Agent` dans `domain` ; **mock** stateful `MockAgentGateway` ; **adapter** Tauri `TauriAgentGateway` (`src/adapters/agent.ts`, commandes `*_agent` — câblage backend à venir).
- **Feature** `frontend/features/agents` : hook `useAgents(projectId)` + `AgentsPanel` (liste, création nom+profil, éditeur de contexte `.md`, Launch/Delete), bâti sur le **design system** (LD) et intégré dans l'onglet projet actif.
- **Tests** : 13 nouveaux (RTL + mock) ; suite front **116 verts**, `tsc` clean. Garde-fou « no direct invoke » respecté.
### ✅ IPC `app-tauri` (vert)
- **Composition root** (`state.rs`) : `IdeaiContextStore` construit ; 6 use cases agents instanciés en réutilisant les ports existants ; `LaunchAgent` partage le **même** `pty_port` + `terminal_sessions` que les terminaux (indispensable au `PtyBridge`) ; handle `project_store` ajouté pour résoudre le `Project` depuis un `projectId`.
- **Commands** (`commands.rs`) : `create_agent`, `list_agents`, `read_agent_context`, `update_agent_context`, `delete_agent`, `launch_agent`. `launch_agent` imite `open_terminal` (Channel + `PtyBridge` + thread de pompe). Enregistrées dans `lib.rs`.
- **DTOs** (`dto.rs`) : `AgentDto`/`AgentListDto` (transparent, camelCase), request DTOs, `parse_agent_id`, `From<LaunchAgentOutput> for TerminalSessionDto`.
- **Tests** : `tests/dto_agents.rs` (10) ; `cargo test -p app-tauri` 44 verts ; `cargo test --workspace` **256 verts, 0 régression** ; clippy clean.
### ✅ Terminal d'agent (front, vert) — L6 clos
- `AgentGateway.launchAgent(projectId, agentId, options, onData)` renvoie désormais un `TerminalHandle` (signature calquée sur `openTerminal`) ; adapter Tauri = `Channel<number[]>` + `invoke("launch_agent", …)` + write/resize/close via les commandes terminal (clé `sessionId`) ; mock = greeting + echo.
- `TerminalView` généralisé avec une prop `open?` optionnelle (par défaut = gateway terminal) → réutilisé tel quel pour le terminal d'agent (xterm/fit/resize/cleanup partagés).
- `AgentsPanel` : bouton **Launch** monte un `TerminalView` (conteneur sombre `h-96`) branché sur la session d'agent ; bouton **Stop** le démonte (cleanup `close()`).
- **Tests** front : 120 verts (`tsc` clean), garde-fou « no direct invoke » respecté. Backend/IPC : 256 verts.
### ⏳ Hors périmètre L6 (à reprendre plus tard)
- Affiner la stratégie `Env` (support adapter de premier ordre).

View File

@ -0,0 +1,42 @@
# L7 — Templates & synchronisation
**Binôme :** `dev-templates` / `test-templates`
**Zones :** `application/template`, `infrastructure/store`, `frontend/features/templates`
**Dépendances amont :** L0, L1, L5, L6.
## Objectif
Templates d'agents (store global IDE), versioning, création d'agent depuis template, **détection de drift** et **synchronisation template → agents**.
## Périmètre (DEV)
- Adapter `FsTemplateStore` (md + `index.json`) avec versioning monotone + `content_hash`.
- Use cases : `CreateTemplate`, `UpdateTemplate` (bump version), `CreateAgentFromTemplate`, `DetectAgentDrift`, `SyncAgentWithTemplate` (remplacement du `.md` si `synchronized`).
- Front : gestion des templates, badge « MAJ disponible », action de sync.
## Périmètre (TEST)
- `UpdateTemplate` incrémente la version ; `DetectAgentDrift` détecte `version > synced_template_version`.
- `SyncAgentWithTemplate` : applique aux `synchronized==true`, ignore `false` et `scratch` ; met à jour `synced_template_version`.
- Front : badge drift + flux de sync avec gateway mock.
## Definition of Done
- `cargo test` (template/store) + `vitest` verts ; cycle MAJ template → propagation aux agents synchronisés (dev manuel).
## Avancement
### ✅ Backend (vert)
- **Infra** : `FsTemplateStore` (`infrastructure/store/template.rs`) — store global `<app>/templates/{index.json, md/<id>.md}`, versioning persisté, `contentHash` (digest stable, sans dépendance) pour détection d'édition hors-app. 6 tests d'intégration (tmpdir).
- **Application** (`application/template/usecases.rs`) : `CreateTemplate`, `UpdateTemplate` (bump version + event `TemplateUpdated`), `ListTemplates`, `DeleteTemplate`, `CreateAgentFromTemplate` (origine `FromTemplate` + seed du `.md`, réutilise le helper de nommage L6), `DetectAgentDrift` (ne flague que les `synchronized` en retard ; ignore non-sync/scratch/à-jour/template supprimé ; émet `AgentDriftDetected`), `SyncAgentWithTemplate` (remplace le `.md`, avance `synced_template_version`, émet `AgentSynced` ; laisse intacts non-sync/scratch). 8 tests use cases.
- `cargo test --workspace` : **270 verts, 0 régression** ; clippy clean.
### ✅ IPC `app-tauri` (vert)
- Composition root : `FsTemplateStore` construit, 7 use cases injectés (réutilise `contexts_port`/`ids`/`events_port`).
- 7 commands : `create_template`, `update_template`, `list_templates`, `delete_template`, `create_agent_from_template`, `detect_agent_drift`, `sync_agent_with_template` (shells fins, `resolve_project` réutilisé). DTOs camelCase (`TemplateDto` transparent, `AgentDriftDto`, `SyncResultDto`, `parse_template_id`).
- Tests `tests/dto_templates.rs` (18) ; `cargo test -p app-tauri` 62 verts ; workspace **288 verts, 0 régression** ; clippy clean.
### ✅ Front (vert)
- Port `TemplateGateway` (7 méthodes) + types `Template`/`AgentDrift` ; adapter Tauri `TauriTemplateGateway` ; `MockTemplateGateway` stateful **partageant le registre d'agents** du `MockAgentGateway` (helpers internes `_insertAgent`/`_updateAgent`/`_rawAgents`) pour faire vivre le drift offline.
- Feature `features/templates` : `useTemplates` (CRUD), `useDrift(projectId)` (détection + sync), `TemplatesPanel` (liste nom+version, création, édition, suppression, « Create agent from template »), monté dans l'onglet projet.
- `AgentsPanel` : **badge « update available »** + bouton **Sync** par agent en drift.
- Tests : 20 ajoutés ; suite front **140 verts** ; `tsc` clean ; garde-fou « no direct invoke » respecté.
### ⏳ Hors périmètre L7
- Intégration front du terminal d'agent depuis un agent créé via template (réutilise le fil L6).

42
agents-dev/L8-git.md Normal file
View File

@ -0,0 +1,42 @@
# L8 — Git
**Binôme :** `dev-git` / `test-git`
**Zones :** `infrastructure/git`, `application/git`, `frontend/features/git`
**Dépendances amont :** L0, L1, L2.
## Objectif
Support Git intégré (local) via libgit2.
## Périmètre (DEV)
- Adapter `Git2Repository` (git2) : `status`, `stage`/`unstage`, `commit`, `branches`, `checkout`, `current_branch`, `diff`, `log`, `pull`, `push`, `clone`, `init`.
- Use cases Git (`GitStatus`, `GitCommit`, `GitCheckout`, `GitPush`, …).
- Front : panneau Git (changements, staging, commit, branches).
## Périmètre (TEST)
- Use cases avec `GitRepository` mocké.
- Intégration : `Git2Repository` sur repo temporaire (init → commit → branch → status).
- Front : feature git avec gateway mock.
## Definition of Done
- `cargo test` (git) + `vitest` verts ; opérations git de base utilisables (dev manuel).
## Spike
- Vendoring statique git2/openssl pour l'AppImage (coordonné avec L11).
## Avancement
### ✅ Backend (vert)
- **Dépendance** : `git2` 0.20 (`default-features = false`, pas d'openssl) liée à la **libgit2 système** via `.cargo/config.toml` (`LIBGIT2_SYS_USE_PKG_CONFIG=1`) — évite cmake/vendoring ; le vendoring statique AppImage reste pour L11.
- **Infra** : `Git2Repository` (`infrastructure/git/mod.rs`) implémente `GitPort``init`, `status`, `stage`, `unstage`, `commit` (signature de repli `IdeA <idea@localhost>` si pas de config user), `branches`, `current_branch`, `checkout`, `log`. `pull`/`push` renvoient une erreur explicite (réseau/credentials → L9). Appels libgit2 synchrones sans `await` ⇒ futures `Send`. 3 tests d'intégration (vrai repo temporaire).
- **Application** (`application/git/`) : `GitStatus`, `GitStage`, `GitUnstage`, `GitCommit` (valide message non vide + event `GitStateChanged`), `GitBranches` (liste + courante), `GitCheckout` (+ event), `GitLog`, `GitInit` (+ event). 7 tests use cases (mock `GitPort`).
- `cargo test --workspace` : **298 verts, 0 régression** ; clippy clean.
### ✅ IPC `app-tauri` (vert)
- Composition root : `Git2Repository` construit, 8 use cases injectés. 8 commands (`git_status`, `git_stage`, `git_unstage`, `git_commit`, `git_branches`, `git_checkout`, `git_log`, `git_init`), résolution `projectId → root` via `resolve_project`. DTOs `GitFileStatusDto`/`GitCommitDto`/`GitBranchesDto` + request DTOs camelCase. Tests `tests/dto_git.rs` (12). `cargo test -p app-tauri` 74 verts ; workspace **310 verts, 0 régression** ; clippy clean.
### ✅ Front (vert)
- Port `GitGateway` complet (8 méthodes) + types `GitFileStatus`/`GitCommit`/`GitBranches` ; adapter `TauriGitGateway` ; `MockGitGateway` stateful (état par projet, seedé) pour le mode offline.
- Feature `features/git` : `useGit(projectId)` + `GitPanel` (sections Staged/Unstaged + stage/unstage, message + commit, branches + checkout, log récent), monté dans l'onglet projet. 17 tests ; suite front **157 verts** ; `tsc` clean ; garde-fou « no invoke » OK.
### ⏳ Hors périmètre L8
- `pull`/`push`/`clone` (réseau + credentials) → L9 (`RemoteGitRepository` + callbacks) ; vendoring statique git2 pour l'AppImage → L11.

40
agents-dev/L9-remote.md Normal file
View File

@ -0,0 +1,40 @@
# L9 — Remote (SSH + WSL)
**Binôme :** `dev-remote` / `test-remote`
**Zones :** `infrastructure/remote`, `application/remote`, `frontend/features/remote`
**Dépendances amont :** L0, L1, L2, L3, L8.
## Objectif
Développement distant : projet sur autre machine via **SSH**, ou sur une **WSL** depuis Windows. Transparence local/distant via la stratégie `RemoteHost`.
## Périmètre (DEV)
- `RemoteHost` : `LocalHost`, `SshHost` (russh/ssh2), `WslHost` (`wsl.exe`) — fabriquent FS/PTY/Spawner adaptés.
- Adapters distants : `SshFileSystem` (SFTP), `SshPtyAdapter`, `SshProcessSpawner` ; `WslFileSystem`, `WslPtyAdapter`, `WslProcessSpawner`.
- `RemoteGitRepository` (git CLI via `ProcessSpawner`) en fallback distant.
- Use case `ConnectRemote` (valide l'accès au root). Front : UI de connexion SSH/WSL.
## Périmètre (TEST)
- Substituabilité (Liskov) : un use case marche identiquement quel que soit le `RemoteHost` (tests avec hosts mockés).
- Intégration SSH/WSL : tests `#[ignore]` gated derrière feature/env (CI conditionnelle).
- Front : feature remote avec gateway mock.
## Definition of Done
- `cargo test` (remote, hors `#[ignore]`) + `vitest` verts ; connexion SSH et WSL démontrée en dev manuel.
## Avancement
### ✅ Socle (vert)
- **Domaine** : `RemoteRef` (Local/Ssh/Wsl) + port `RemoteHost` (fabrique FS/PTY/Spawner) déjà en place (L0).
- **Infra** (`infrastructure/remote/mod.rs`) : `LocalHost` (fabrique les adapters locaux ; `connect` = no-op) + sélecteur `remote_host(&RemoteRef)` (Local → `LocalHost` ; SSH/WSL → `RemoteError::Connection` explicite « not yet supported »). 4 tests d'intégration.
- **Application** (`application/remote/`) : `ConnectRemote` (établit l'hôte, valide que le root existe via le FS de l'hôte, émet `RemoteConnected`). 3 tests **Liskov** (comportement identique Local/Ssh/Wsl avec hôte mocké ; échec connexion → REMOTE ; root absent → NOT_FOUND).
- `cargo test --workspace` : **317 verts, 0 régression** ; clippy clean.
### ⏳ Reste à faire (gated / non vérifiable dans cet environnement)
- Adapters distants **SSH** (`SshHost`/`SshFileSystem` SFTP/`SshPtyAdapter`/`SshProcessSpawner` via russh ou ssh2 — décision auth à figer, cf. spikes) et **WSL** (`WslHost` + adapters préfixant `wsl.exe`), avec tests d'intégration `#[ignore]` derrière feature/env.
- `RemoteGitRepository` (git CLI distant via `ProcessSpawner`) + `pull`/`push` (reportés depuis L8).
- IPC `app-tauri` `connect_remote` + front feature remote (UI connexion SSH/WSL).
## Spikes (cf. ARCHITECTURE §13)
- Auth SSH (clé/agent/mot de passe/known_hosts) ; choix russh(rustls) vs ssh2(OpenSSL) — impacte l'AppImage.
- Conversion de chemins WSL `/mnt/...``\\wsl$\...` ; perf I/O cross-boundary.
- Git sur FS distant (perf, parsing CLI).

View File

@ -0,0 +1,39 @@
# LD — Design System (UI kit maison)
**Binôme :** `dev-ui` / `test-ui`
**Zones :** `frontend/src/shared` (UI kit), `frontend` (config Tailwind), `frontend/src/app` (app shell)
**Dépendances amont :** L1 (frontend ports/adapters/DI en place).
**Position :** inséré **après L6** (décision produit : voir CONTEXT, lot transverse), consommé ensuite au fil de l'eau par chaque feature.
## Objectif
Doter IdeA d'un **design system maison** cohérent et d'un **thème sombre** par défaut (c'est un IDE), pour que chaque feature cesse de bricoler des styles inline et consomme des composants réutilisables.
## Stack (validée)
- **Tailwind v4** + `@tailwindcss/vite` (CSS-first, `@theme`), composants **maison** dans `shared/ui` (pas de lib de composants tierce).
- Tokens de design (couleurs/typo/espacements/rayons) en variables de thème ; helper `cn()` pour composer les classes.
## Périmètre (DEV)
- Config Tailwind (plugin Vite, feuille de thème globale, tokens, dark par défaut).
- `shared/ui` : composants de base — `Button`, `IconButton`, `Input`, `Panel`/`Card`, `Tabs`, `Toolbar`, `Spinner`, `Field`. Helper `cn`.
- **App shell** sombre dans `app/` (remplace les styles inline du smoke-test).
## Périmètre (TEST)
- `cn()` (unitaire).
- Rendu + variantes/états des composants (`Button` variants/disabled, `Input` label/aria, `Tabs` sélection) via RTL/vitest, **sans backend**.
## Definition of Done
- `vitest` vert ; `tsc --noEmit` vert ; le domaine/les ports UI restent inchangés (pur skin).
- Aucune feature ne régresse ; l'app monte avec le thème sombre.
## Hors périmètre
- Re-styling exhaustif de toutes les features (fait au fil de l'eau quand on touche chacune).
## Avancement — ✅ vert
- **Config** : `tailwindcss@4` + `@tailwindcss/vite` ajoutés ; plugin câblé dans `vite.config.ts` ; feuille de thème globale `src/shared/styles/theme.css` (tokens sémantiques sous `@theme`, thème **sombre** par défaut, focus ring), importée une fois dans `app/main.tsx`.
- **UI kit** `src/shared/ui` : `Button` (variants primary/secondary/ghost/danger, sizes, loading), `IconButton`, `Input`, `Field` (label/hint/error + aria), `Panel`, `Tabs` (sélection + close), `Toolbar`, `Spinner`. Helper `cn()`. Baril `@/shared`.
- **App shell** sombre (`app/App.tsx`) : header avec statut backend, plus de styles inline.
- **Consommation** : `features/projects/ProjectsView` migré sur le kit (premier consommateur), hooks d'accessibilité préservés (tests L2 toujours verts).
- **Tests** : `cn` + composants (`Button`/`Input`/`Field`/`Tabs`) via RTL — assertions sur rôles/aria, pas sur les classes Tailwind (le design peut évoluer sans casser la suite).
**Vérifs** : `tsc --noEmit` vert · `vitest` **103 tests verts** (14 fichiers) · `vite build` OK (Tailwind compile, CSS 22.8 kB).

69
agents-dev/README.md Normal file
View File

@ -0,0 +1,69 @@
# Agents de développement IdeA — Protocole commun
> Ces agents servent à **développer l'IDE IdeA lui-même**. Ils ne sont pas la feature produit « agents IA » de l'application.
> Référence produit/archi : [`../CONTEXT.md`](../CONTEXT.md) · [`../ARCHITECTURE.md`](../ARCHITECTURE.md).
## Composition de l'équipe
Chaque **lot livrable** (L0…L11) est confié à un **binôme** :
- un **agent de développement** (écrit le code),
- un **agent de test** appairé (écrit et exécute les tests unitaires).
Un fichier `Lx-*.md` par binôme décrit son périmètre, ses ports/adapters, ses dépendances et sa *definition of done*.
| Lot | Fichier | Statut |
|---|---|---|
| L0 | [L0-core-domain.md](L0-core-domain.md) | ✅ **vert** (84 tests) |
| L1 | [L1-ipc-bridge.md](L1-ipc-bridge.md) | ✅ **vert** (46 tests) |
| L2 | [L2-projects.md](L2-projects.md) | ✅ **vert** (26 tests) |
| L3 | [L3-terminals.md](L3-terminals.md) | ✅ **vert** (61 tests) |
| L4 | [L4-layout.md](L4-layout.md) | ✅ **vert** (52 tests) |
| L5 | [L5-ai-runtime.md](L5-ai-runtime.md) | ✅ **vert** (69 tests) |
| L6 | [L6-agents.md](L6-agents.md) | ✅ **vert** (domaine+app+infra+IPC+front · activer un agent ouvre son terminal) |
| LD | [LD-design-system.md](LD-design-system.md) | ✅ **vert** (Tailwind v4 + UI kit maison, thème sombre) |
| L7 | [L7-templates.md](L7-templates.md) | ✅ **vert** (backend + IPC + front · drift & sync) |
| L8 | [L8-git.md](L8-git.md) | ✅ **vert** (backend + IPC + front · git local libgit2) |
| L9 | [L9-remote.md](L9-remote.md) | 🟡 **socle vert** (LocalHost + ConnectRemote, Liskov) · SSH/WSL gated à venir |
| L10 | [L10-windows.md](L10-windows.md) | 🟡 **backend + IPC verts** (move-tab + `WebviewWindow`) · détach UI fait avec la refonte L11 |
| L11 | [L11-packaging.md](L11-packaging.md) | 🟡 AppImage Linux **OK** · refonte disposition IDE en cours · Windows/CI à venir |
## Cycle dev ↔ test (obligatoire, cf. CONTEXT §3)
```
1. Archi valide le découpage et les contrats (ports/interfaces) du lot.
2. Agent DEV écrit le code de la feature.
3. Agent TEST écrit les tests unitaires + les exécute.
4a. Vert → feature validée, lot suivant.
4b. Rouge → rapport d'erreurs structuré → retour DEV → correction → retour étape 3.
```
**Règle d'or** : aucune feature n'est « terminée » tant que ses tests ne passent pas. Les résultats sont relayés fidèlement (sortie réelle des tests).
## Definition of Done (commune à tous les lots)
- [ ] Code conforme à l'architecture hexagonale et SOLID (cf. ARCHITECTURE §1).
- [ ] Le `domain` reste pur (aucune dépendance I/O qui y entre).
- [ ] Les use cases ne parlent qu'aux **ports**, jamais aux adapters concrets.
- [ ] Tests unitaires écrits et **verts** : `cargo test -p <crate>` (Rust) et/ou `vitest` (front).
- [ ] Domaine/application testés **sans I/O** (ports mockés : `mockall` ou fakes).
- [ ] Pas de `new ConcreteAdapter` ailleurs que dans la composition root (`app-tauri`).
- [ ] Pas de régression sur les lots déjà verts.
- [ ] Code lisible, cohérent avec le style existant.
## Format du rapport d'erreurs (TEST → DEV)
```
LOT: Lx
TEST EN ÉCHEC: <nom du test>
ATTENDU: <…>
OBTENU: <…>
SORTIE: <extrait pertinent de cargo test / vitest>
HYPOTHÈSE: <cause probable, si identifiable>
```
## Conventions techniques
- Rust : workspace multi-crate (`crates/domain`, `application`, `infrastructure`, `app-tauri`).
- Erreurs typées par port/use case ; `async` via `async_trait` côté ports I/O.
- Déterminisme des tests via ports `Clock`/`IdGenerator` (impl `Fixed`/`Seq` en test).
- Front : `domain`/`ports` purs (Vitest), `features` testés avec gateways **mock** (RTL).