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:
@ -203,6 +203,56 @@ describe("TauriAgentGateway invoke payloads", () => {
|
||||
});
|
||||
});
|
||||
|
||||
it("listSlashCommands forwards the unified slash-command filter request and unwraps commands", async () => {
|
||||
invoke.mockResolvedValueOnce({
|
||||
commands: [
|
||||
{
|
||||
name: "/clean",
|
||||
shortDescription: "Clean current conversation",
|
||||
requiresConfirmation: false,
|
||||
availability: { status: "available" },
|
||||
source: "native",
|
||||
native: "clean",
|
||||
},
|
||||
],
|
||||
});
|
||||
|
||||
const out = await new TauriAgentGateway().listSlashCommands("/c");
|
||||
|
||||
expect(invoke).toHaveBeenCalledWith("list_slash_commands", {
|
||||
request: { prefix: "/c" },
|
||||
});
|
||||
expect(out).toHaveLength(1);
|
||||
expect(out[0].name).toBe("/clean");
|
||||
});
|
||||
|
||||
it("executeSlashCommand wraps the selected command and current session id", async () => {
|
||||
invoke.mockResolvedValueOnce({
|
||||
command: {
|
||||
name: "/clean",
|
||||
shortDescription: "Clean current conversation",
|
||||
requiresConfirmation: false,
|
||||
availability: { status: "available" },
|
||||
source: "native",
|
||||
native: "clean",
|
||||
},
|
||||
effect: {
|
||||
kind: "cleanConversation",
|
||||
sessionId: "chat-session-1",
|
||||
clearedChunks: 2,
|
||||
},
|
||||
});
|
||||
|
||||
const out = await new TauriAgentGateway().executeSlashCommand("/clean", {
|
||||
sessionId: "chat-session-1",
|
||||
});
|
||||
|
||||
expect(invoke).toHaveBeenCalledWith("execute_slash_command", {
|
||||
request: { name: "/clean", sessionId: "chat-session-1" },
|
||||
});
|
||||
expect(out.effect.kind).toBe("cleanConversation");
|
||||
});
|
||||
|
||||
it("launchAgentChat returns a handle only when launch_agent confirms cellKind chat", async () => {
|
||||
invoke.mockResolvedValueOnce({
|
||||
sessionId: "chat-session-1",
|
||||
|
||||
Reference in New Issue
Block a user