Files
IdeA/agents-dev/L12-skills.md

3.8 KiB

L12 — Skills

Binôme : dev-skills / test-skills Zones : domain/skill, application/skill, infrastructure/store, frontend/features/skills Dépendances amont : L0, L1, L5, L6 (convention file généré à l'activation), L7 (store global réutilisé).

Objectif

Modéliser les Skills : workflows réutilisables (équivalent universel des slash-commands, sans dépendance à la syntaxe /command d'un modèle). Stockage global IDE + projet, assignation agent↔skills, injection des skills assignés dans le convention file généré à l'activation de l'agent. Cf. ARCHITECTURE §14.2.

Périmètre (DEV)

  • Domaine : entité Skill { id, name, content_md: MarkdownDoc, scope: SkillScope(Global|Project) }. Invariants : name non vide, content_md non vide. Event SkillAssigned.
  • Port SkillStore : CRUD skills globaux (<app_data>/IdeA/skills/) + skills projet (.ideai/skills/<name>.md), résolution selon scope (compose FileSystem/store global comme L7).
  • AgentManifest : étendre pour porter la liste skills: Vec<SkillRef> assignés à chaque agent (0..N).
  • Use cases (application/skill) : CreateSkill, UpdateSkill, DeleteSkill, ListSkills(scope), AssignSkillToAgent, UnassignSkillFromAgent.
  • Injection : à l'activation (fil L6), composer le convention file en concaténant persona agent + chemin project root + skills assignés (lus via SkillStore). Pas de mécanisme CLI propriétaire.
  • Front : onglet/section Skills (liste globale + projet, CRUD, éditeur md), assignation skills↔agent dans AgentsPanel.

Périmètre (TEST)

  • Skill rejette name/content_md vides.
  • SkillStore : CRUD round-trip en tmpdir pour les deux scopes ; un skill Project n'apparaît pas dans le scope Global et inversement.
  • AssignSkillToAgent / UnassignSkillFromAgent : mutent l'AgentManifest, émettent SkillAssigned, idempotents (pas de doublon).
  • Injection : le convention file généré contient bien le content_md des skills assignés et rien des skills non assignés ; ordre déterministe.
  • Front : CRUD skills + assignation via gateway mock (RTL) ; garde-fou « no direct invoke ».

Definition of Done

  • cargo test (skill/store/app) + vitest verts ; cycle manuel : créer un skill, l'assigner à un agent, l'activer → le skill apparaît dans le convention file de .ideai/run/<agent-id>/.
  • DoD commune (cf. README) respectée ; zéro régression.

Avancement

Domaine (vert)

  • Entité Skill (domain/skill.rs) : id: SkillId, name, content_md: MarkdownDoc, scope: SkillScope(Global|Project). Constructeur validant (name + content_md non vides), with_content re-valide l'invariant.
  • SkillRef { skill_id, scope } : référence d'assignation portée par l'agent ; From<&Skill>.
  • SkillId ajouté (ids.rs), event SkillAssigned { agent_id, skill_id, assigned } (events.rs), DTO + arm de mapping côté app-tauri (events.rs).
  • Agent étendu : champ skills: Vec<SkillRef> (serde default), méthodes assign_skill (idempotent), unassign_skill, with_skills (dédup). ManifestEntry : champ skills (serde default + skip_serializing_if → rétrocompat des manifests pré-L12) ; from_agent/to_agent préservent les skills.
  • Tests : 8 invariants (entities.rs) + 3 serde dont rétrocompat d'un manifest legacy sans clé skills (serde_roundtrip.rs). cargo test -p domain vert ; cargo test --workspace vert (0 régression) ; clippy clean.

Reste à faire

  • Port SkillStore (domain/ports.rs) + adapter FsSkillStore (infrastructure/store).
  • Use cases application/skill : CRUD + AssignSkillToAgent/UnassignSkillFromAgent.
  • Injection des skills assignés dans le convention file à l'activation (fil L6).
  • IPC app-tauri + front features/skills.