feat(workspace): composer like Claude Desktop, image thumbnails, tool icons in the picker

This commit is contained in:
2026-10-02 16:13:27 +07:00
parent 4802684d2f
commit f35bf2043f
15 changed files with 414 additions and 185 deletions
@@ -19,6 +19,8 @@ vi.mock("../../conversation/ConversationView", () => ({
),
}));
vi.mock("../../run/RunSetup", () => ({
promptWithImages: (text: string, images: { path: string }[]) =>
[text.trim(), ...images.map((i) => i.path)].filter(Boolean).join(" "),
PromptEditor: ({
value,
onChange,
@@ -19,6 +19,8 @@ import type { Lane, Session } from "../../../lib/types";
import type { LaneSourcesView, RunHandle } from "../../../lib/api";
vi.mock("../../run/RunSetup", () => ({
promptWithImages: (text: string, images: { path: string }[]) =>
[text.trim(), ...images.map((i) => i.path)].filter(Boolean).join(" "),
PromptEditor: ({
value,
onChange,
@@ -211,9 +213,11 @@ describe("WorkspaceHome", () => {
it("lays its fields out in order: AI, AI Router, Model, Permission mode, Thinking effort", async () => {
renderHome();
await screen.findByTestId("workspace-recent-s-live");
const card = screen.getByTestId("workspace-home-start").closest(".card") as HTMLElement;
const labels = [...card.querySelectorAll("span.uppercase")].map((x) => x.textContent);
expect(labels).toEqual(["AI", "AI Router", "Model", "Permission mode", "Thinking effort"]);
const box = screen.getByTestId("workspace-home-composer");
const labels = [
...box.querySelectorAll("button[aria-haspopup='listbox'], input[aria-label='model']"),
].map((x) => x.getAttribute("aria-label"));
expect(labels).toEqual(["AI", "AI Router", "model", "Permission mode", "Thinking effort"]);
});
it("starts the session on the AI tool picked for it, with that tool's own fields", async () => {