feat(cli): menu contextuel d'autocomplétion des slash-commands dans le composer — #163 (QA verte)

À la saisie d'un « / » en début de draft (sans espace), ouverture d'un menu
contextuel listant les commandes matchant le préfixe, via le contrat unifié
listSlashCommands — aucune liste codée en dur côté UI. Rafinement incrémental
des suggestions à la frappe, navigation clavier + sélection, exécution par
executeSlashCommand.

- adapters/agent: listSlashCommands(prefix?) + executeSlashCommand (invoke Tauri).
- domain + ports: types SlashCommand / ExecuteSlashCommandResult.
- mock: données de test.
- CustomAgentChatView: détection de préfixe (/ sans espace), fetch avec séquence
  anti-retard, gestion ouverture/active index, navigation clavier, fermeture
  quand le préfixe cesse d'être éligible.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
2026-08-06 15:02:40 +02:00
parent b51011d206
commit 853d8229f2
7 changed files with 467 additions and 0 deletions

View File

@ -19,8 +19,10 @@ import type {
AgentContextDocument,
EffortSelection,
GatewayError,
ExecuteSlashCommandResult,
ReplyChunk,
ResumableAgent,
SlashCommand,
TerminalSession,
} from "@/domain";
import type {
@ -274,6 +276,26 @@ export class TauriAgentGateway implements AgentGateway {
});
}
async listSlashCommands(prefix?: string): Promise<SlashCommand[]> {
const request = prefix === undefined ? {} : { prefix };
const res = await invoke<{ commands: SlashCommand[] }>("list_slash_commands", {
request,
});
return res.commands;
}
async executeSlashCommand(
name: string,
options: { sessionId?: string | null } = {},
): Promise<ExecuteSlashCommandResult> {
return invoke<ExecuteSlashCommandResult>("execute_slash_command", {
request: {
name,
sessionId: options.sessionId ?? null,
},
});
}
async closeAgentChat(sessionId: string): Promise<void> {
await invoke("close_agent_session", { sessionId });
}