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>
This commit is contained in:
2026-08-03 11:06:23 +02:00
parent 22c6bd803d
commit 171c6c923c
59 changed files with 3654 additions and 291 deletions

View File

@ -12,6 +12,7 @@ import { useCallback, useEffect, useState } from "react";
import type {
Agent,
AgentProfile,
EffortSelection,
GatewayError,
ModelServerStatus,
TerminalSession,
@ -124,6 +125,11 @@ export interface AgentsViewModel {
rows: number,
cols: number,
) => Promise<TerminalSession | undefined>;
/** Sets or clears a per-agent effort override. */
updateAgentEffort: (
agentId: string,
effort: EffortSelection | null,
) => Promise<void>;
/** Deletes an agent; deselects if it was selected. */
deleteAgent: (agentId: string) => Promise<void>;
/**
@ -427,6 +433,26 @@ export function useAgents(projectId: string): AgentsViewModel {
[agent, projectId, refreshLiveAgents],
);
const updateAgentEffort = useCallback(
async (agentId: string, effort: EffortSelection | null): Promise<void> => {
setBusy(true);
setError(null);
try {
const updated = await agent.updateAgentEffort(projectId, agentId, effort);
setAgents((prev) =>
prev.map((candidate) =>
candidate.id === updated.id ? updated : candidate,
),
);
} catch (e) {
setError(describe(e));
} finally {
setBusy(false);
}
},
[agent, projectId],
);
const deleteAgent = useCallback(
async (agentId: string) => {
setBusy(true);
@ -544,6 +570,7 @@ export function useAgents(projectId: string): AgentsViewModel {
selectAgent,
saveContext,
changeAgentProfile,
updateAgentEffort,
deleteAgent,
launchAgent,
stopAgent,