3.8 KiB
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 :namenon vide,content_mdnon vide. EventSkillAssigned. - Port
SkillStore: CRUD skills globaux (<app_data>/IdeA/skills/) + skills projet (.ideai/skills/<name>.md), résolution selonscope(composeFileSystem/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)
Skillrejettename/content_mdvides.SkillStore: CRUD round-trip en tmpdir pour les deux scopes ; un skillProjectn'apparaît pas dans le scopeGlobalet inversement.AssignSkillToAgent/UnassignSkillFromAgent: mutent l'AgentManifest, émettentSkillAssigned, idempotents (pas de doublon).- Injection : le convention file généré contient bien le
content_mddes 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) +vitestverts ; 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_mdnon vides),with_contentre-valide l'invariant. SkillRef { skill_id, scope }: référence d'assignation portée par l'agent ;From<&Skill>.SkillIdajouté (ids.rs), eventSkillAssigned { agent_id, skill_id, assigned }(events.rs), DTO + arm de mapping côtéapp-tauri(events.rs).Agentétendu : champskills: Vec<SkillRef>(serdedefault), méthodesassign_skill(idempotent),unassign_skill,with_skills(dédup).ManifestEntry: champskills(serdedefault+skip_serializing_if→ rétrocompat des manifests pré-L12) ;from_agent/to_agentpré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 domainvert ;cargo test --workspacevert (0 régression) ; clippy clean.
⏳ Reste à faire
- Port
SkillStore(domain/ports.rs) + adapterFsSkillStore(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+ frontfeatures/skills.