feat(webui): highlight slash commands and app mentions (#4933)

This commit is contained in:
chengyongru
2026-07-15 00:34:22 +08:00
committed by GitHub
parent 2116e32013
commit 37165b0db0
15 changed files with 459 additions and 88 deletions
+63
View File
@@ -1587,4 +1587,67 @@ describe("ThreadShell", () => {
expect(screen.getByRole("listbox", { name: "Apps" })).toBeInTheDocument();
expect(screen.getByRole("option", { name: /@gimp/i })).toBeInTheDocument();
});
it("keeps installed app mentions available during transient catalog refresh failures", async () => {
const client = makeClient();
const payload: CliAppsPayload = {
apps: [{
name: "obsidian-agent-cli",
display_name: "Obsidian",
category: "productivity",
description: "Obsidian automation",
requires: "",
source: "harness",
entry_point: "cli-anything-obsidian",
install_supported: true,
installed: true,
available: true,
status: "installed",
logo_url: null,
brand_color: "#7C3AED",
skill_installed: true,
}],
installed_count: 1,
catalog_updated_at: "2026-07-14",
};
vi.mocked(fetch).mockImplementation(async (input) => {
if (String(input).includes("/api/settings/cli-apps?installed_only=1")) {
throw new Error("temporary catalog failure");
}
return {
ok: false,
status: 404,
json: async () => ({}),
} as Response;
});
render(wrap(
client,
<ThreadShell
session={session("chat-cli-refresh")}
title="Chat chat-cli-refresh"
onToggleSidebar={() => {}}
onGoHome={() => {}}
onNewChat={() => {}}
/>,
));
const input = await screen.findByLabelText("Message input");
await act(async () => {
window.dispatchEvent(new CustomEvent(CLI_APPS_CHANGED_EVENT, { detail: payload }));
});
const mention = "@obsidian-agent-cli";
fireEvent.change(input, { target: { value: mention, selectionStart: mention.length } });
expect(screen.getByRole("option", { name: /@obsidian-agent-cli/i })).toBeInTheDocument();
await act(async () => {
window.dispatchEvent(new Event("focus"));
await Promise.resolve();
});
expect(screen.getByRole("option", { name: /@obsidian-agent-cli/i })).toBeInTheDocument();
expect(screen.getByTestId("composer-cli-mention-obsidian-agent-cli")).toHaveTextContent(
"@obsidian-agent-cli",
);
});
});