feat: add CLI Apps settings MVP
This commit is contained in:
@@ -2,7 +2,42 @@ import { act, fireEvent, render, screen, waitFor } from "@testing-library/react"
|
||||
import { describe, expect, it, vi } from "vitest";
|
||||
|
||||
import { MessageBubble } from "@/components/MessageBubble";
|
||||
import type { UIMessage } from "@/lib/types";
|
||||
import type { CliAppInfo, UIMessage } from "@/lib/types";
|
||||
|
||||
const CLI_APPS: CliAppInfo[] = [
|
||||
{
|
||||
name: "zoom",
|
||||
display_name: "Zoom",
|
||||
category: "productivity",
|
||||
description: "Meetings",
|
||||
requires: "",
|
||||
source: "harness",
|
||||
entry_point: "cli-anything-zoom",
|
||||
install_supported: true,
|
||||
installed: true,
|
||||
available: true,
|
||||
status: "installed",
|
||||
logo_url: "https://example.invalid/zoom.svg",
|
||||
brand_color: "#0B5CFF",
|
||||
skill_installed: true,
|
||||
},
|
||||
{
|
||||
name: "krita",
|
||||
display_name: "Krita",
|
||||
category: "image",
|
||||
description: "Painting",
|
||||
requires: "",
|
||||
source: "harness",
|
||||
entry_point: "cli-anything-krita",
|
||||
install_supported: true,
|
||||
installed: false,
|
||||
available: false,
|
||||
status: "not_installed",
|
||||
logo_url: null,
|
||||
brand_color: "#3BABFF",
|
||||
skill_installed: false,
|
||||
},
|
||||
];
|
||||
|
||||
describe("MessageBubble", () => {
|
||||
it("renders user messages as right-aligned pills", () => {
|
||||
@@ -22,6 +57,53 @@ describe("MessageBubble", () => {
|
||||
expect(screen.queryByRole("button", { name: "Copy reply" })).not.toBeInTheDocument();
|
||||
});
|
||||
|
||||
it("renders installed CLI app mentions inside sent user messages", () => {
|
||||
const message: UIMessage = {
|
||||
id: "u-cli",
|
||||
role: "user",
|
||||
content: "Hi nano, please use @zoom to book a meeting, not @krita",
|
||||
createdAt: Date.now(),
|
||||
};
|
||||
|
||||
render(<MessageBubble message={message} cliApps={CLI_APPS} />);
|
||||
|
||||
const token = screen.getByTestId("message-cli-mention-zoom");
|
||||
expect(token).toHaveTextContent("@zoom");
|
||||
expect(token.className).not.toContain("rounded");
|
||||
expect(token.className).not.toContain("px-");
|
||||
expect(token.getAttribute("style")).toContain("color: #0B5CFF");
|
||||
expect(token.getAttribute("style")).toContain("text-shadow");
|
||||
expect(screen.getByTestId("message-cli-mention-logo-zoom")).toBeInTheDocument();
|
||||
expect(screen.queryByTestId("message-cli-mention-krita")).not.toBeInTheDocument();
|
||||
expect(screen.getByText(/not @krita/)).toBeInTheDocument();
|
||||
});
|
||||
|
||||
it("renders structured CLI app attachments even without the installed catalog", () => {
|
||||
const message: UIMessage = {
|
||||
id: "u-cli-attached",
|
||||
role: "user",
|
||||
content: "Please use @drawio for the diagram",
|
||||
createdAt: Date.now(),
|
||||
cliApps: [{
|
||||
name: "drawio",
|
||||
display_name: "Draw.io",
|
||||
category: "diagram",
|
||||
entry_point: "cli-anything-drawio",
|
||||
logo_url: "https://example.invalid/drawio.svg",
|
||||
brand_color: "#F08705",
|
||||
}],
|
||||
};
|
||||
|
||||
render(<MessageBubble message={message} cliApps={[]} />);
|
||||
|
||||
const token = screen.getByTestId("message-cli-mention-drawio");
|
||||
expect(token).toHaveTextContent("@drawio");
|
||||
expect(token.className).not.toContain("rounded");
|
||||
expect(token.className).not.toContain("px-");
|
||||
expect(token.getAttribute("style")).toContain("color: #F08705");
|
||||
expect(screen.getByTestId("message-cli-mention-logo-drawio")).toBeInTheDocument();
|
||||
});
|
||||
|
||||
it("copies completed assistant replies from the action row", async () => {
|
||||
const writeText = vi.fn().mockResolvedValue(undefined);
|
||||
Object.defineProperty(navigator, "clipboard", {
|
||||
|
||||
Reference in New Issue
Block a user