The command fragment named the full command line, so a session spawned with `claude --dangerously-skip-permissions` spent the whole line on a flag. Cards now name the program only — its icon in the web client, its bare name in the TUI — and keep the full command line in the tooltip. Adds `maestro_protocol::display::command_program`, the Rust counterpart of the web's `splitCommand`.
59 lines
2.1 KiB
TypeScript
59 lines
2.1 KiB
TypeScript
import { describe, expect, it } from "vitest";
|
|
import { splitCommand, toolIconSvg } from "./toolIcon.js";
|
|
|
|
describe("tool icons on the command fragment (docs/SIDEBAR.md)", () => {
|
|
it("recognises the agents and shells sessions are spawned with", () => {
|
|
const cases: Array<[string, string]> = [
|
|
["claude", "claude"],
|
|
["codex", "codex"],
|
|
["opencode", "opencode"],
|
|
["gemini", "gemini"],
|
|
["aider", "aider"],
|
|
["cursor-agent", "cursor"],
|
|
["pi", "pi"],
|
|
["zsh", "shell"],
|
|
["bash", "shell"],
|
|
["fish", "shell"],
|
|
];
|
|
for (const [command, tool] of cases) {
|
|
expect(splitCommand(command).tool, command).toBe(tool);
|
|
}
|
|
});
|
|
|
|
it("drops everything after the program", () => {
|
|
expect(splitCommand("claude --dangerously-skip-permissions")).toEqual({
|
|
tool: "claude",
|
|
program: "claude",
|
|
});
|
|
expect(splitCommand(" zsh -l ")).toEqual({ tool: "shell", program: "zsh" });
|
|
});
|
|
|
|
it("looks through paths, env assignments and wrappers", () => {
|
|
expect(splitCommand("/usr/local/bin/claude").tool).toBe("claude");
|
|
expect(splitCommand("FOO=1 BAR=2 claude").tool).toBe("claude");
|
|
expect(splitCommand("npx opencode").tool).toBe("opencode");
|
|
expect(splitCommand("pnpm dlx opencode run").tool).toBe("opencode");
|
|
expect(splitCommand("pnpm dlx opencode run").program).toBe("opencode");
|
|
});
|
|
|
|
it("leaves an unrecognised program as its bare name, mark-less", () => {
|
|
expect(splitCommand("hx src/main.rs")).toEqual({
|
|
tool: null,
|
|
program: "hx",
|
|
});
|
|
// A wrapper with nothing after it is not a tool either.
|
|
expect(splitCommand("sudo").tool).toBeNull();
|
|
expect(splitCommand("").tool).toBeNull();
|
|
});
|
|
|
|
it("gives every recognised tool a labelled mark", () => {
|
|
for (const tool of ["claude", "codex", "opencode", "gemini", "aider", "cursor", "pi", "shell"]) {
|
|
const svg = toolIconSvg(tool);
|
|
expect(svg, tool).toContain("<svg");
|
|
expect(svg, tool).toContain(`data-tool="${tool}"`);
|
|
expect(svg, tool).toContain("aria-label=");
|
|
}
|
|
expect(toolIconSvg("nonesuch")).toBeNull();
|
|
});
|
|
});
|