mirror of
https://github.com/badlogic/pi-mono.git
synced 2026-08-20 22:23:59 +00:00
132 lines
3.9 KiB
TypeScript
132 lines
3.9 KiB
TypeScript
import { describe, expect, test, vi } from "vitest";
|
|
import { cli } from "../src/cli/experimental/cli.ts";
|
|
|
|
const UNSUPPORTED_SERVER_OPTIONS = "The experimental server command does not support existing CLI options yet";
|
|
const UNSUPPORTED_CLIENT_OPTIONS = "The experimental client command does not support existing CLI options yet";
|
|
|
|
describe("experimental CLI command composition", () => {
|
|
test("composes pi command options with the existing parser", () => {
|
|
const result = cli.parse([
|
|
"--listen",
|
|
"unix:///tmp/pi.sock",
|
|
"--auth-token",
|
|
"secret",
|
|
"--provider",
|
|
"anthropic",
|
|
"--model",
|
|
"claude-sonnet",
|
|
"--thinking",
|
|
"high",
|
|
"inspect",
|
|
]);
|
|
|
|
expect(result).toMatchObject({
|
|
ok: true,
|
|
command: {
|
|
command: "pi",
|
|
listen: [{ transport: "unix", path: "/tmp/pi.sock" }],
|
|
auth: { type: "token", token: "secret" },
|
|
options: {
|
|
provider: "anthropic",
|
|
model: "claude-sonnet",
|
|
thinking: "high",
|
|
messages: ["inspect"],
|
|
},
|
|
},
|
|
});
|
|
});
|
|
|
|
test.each(["--help", "--version"] as const)("keeps Pi %s handling in existing CLI options", (option) => {
|
|
expect(cli.parse([option])).toMatchObject({
|
|
ok: true,
|
|
command: { command: "pi", options: { [option === "--help" ? "help" : "version"]: true } },
|
|
});
|
|
});
|
|
|
|
test.each([
|
|
["server", "--help", UNSUPPORTED_SERVER_OPTIONS],
|
|
["server", "--version", UNSUPPORTED_SERVER_OPTIONS],
|
|
["client", "--help", UNSUPPORTED_CLIENT_OPTIONS],
|
|
["client", "--version", UNSUPPORTED_CLIENT_OPTIONS],
|
|
] as const)("rejects deferred %s %s handling", (command, option, error) => {
|
|
expect(cli.parse([command, option])).toEqual({ ok: false, errors: [error] });
|
|
});
|
|
|
|
test("accepts provider and model options for the server command", () => {
|
|
expect(cli.parse(["server", "--provider", "anthropic", "--model", "claude-sonnet-4-5"])).toEqual({
|
|
ok: true,
|
|
command: {
|
|
command: "server",
|
|
provider: "anthropic",
|
|
model: "claude-sonnet-4-5",
|
|
},
|
|
});
|
|
});
|
|
|
|
test("rejects existing options that the client command does not support yet", () => {
|
|
expect(cli.parse(["client", "--tui-mode", "fullscreen", "@prompt.md"])).toEqual({
|
|
ok: false,
|
|
errors: [UNSUPPORTED_CLIENT_OPTIONS],
|
|
});
|
|
});
|
|
|
|
test("reports existing parser errors before capability errors", () => {
|
|
expect(cli.parse(["client", "--tui-mode", "wrong", "--model", "claude-sonnet"])).toEqual({
|
|
ok: false,
|
|
errors: ['Invalid TUI mode "wrong". Valid values: regular, fullscreen', UNSUPPORTED_CLIENT_OPTIONS],
|
|
});
|
|
});
|
|
|
|
test("parses an empty server command", () => {
|
|
expect(cli.parse(["server"])).toEqual({
|
|
ok: true,
|
|
command: { command: "server" },
|
|
});
|
|
});
|
|
|
|
test("passes server options to the command action", async () => {
|
|
const runServer = vi.fn(() => undefined);
|
|
const result = await cli.execute(
|
|
[
|
|
"server",
|
|
"--server-id",
|
|
"00000000-0000-4000-8000-000000000001",
|
|
"--session-dir",
|
|
"./sessions",
|
|
"--provider",
|
|
"anthropic",
|
|
"--model",
|
|
"claude-sonnet-4-5",
|
|
],
|
|
{
|
|
runPi: vi.fn(() => undefined),
|
|
runServer,
|
|
runClient: vi.fn(() => undefined),
|
|
},
|
|
);
|
|
|
|
const command = {
|
|
command: "server" as const,
|
|
serverId: "00000000-0000-4000-8000-000000000001",
|
|
sessionDir: "./sessions",
|
|
provider: "anthropic",
|
|
model: "claude-sonnet-4-5",
|
|
};
|
|
expect(result).toEqual({ ok: true, command });
|
|
expect(runServer).toHaveBeenCalledWith(command);
|
|
});
|
|
|
|
test.each(["pi", "server", "client"] as const)("executes the parsed %s command", async (name) => {
|
|
const context = {
|
|
runPi: vi.fn(() => undefined),
|
|
runServer: vi.fn(() => undefined),
|
|
runClient: vi.fn(() => undefined),
|
|
};
|
|
const result = await cli.execute(name === "pi" ? [] : [name], context);
|
|
|
|
expect(result).toMatchObject({ ok: true, command: { command: name } });
|
|
expect(context.runPi).toHaveBeenCalledTimes(name === "pi" ? 1 : 0);
|
|
expect(context.runServer).toHaveBeenCalledTimes(name === "server" ? 1 : 0);
|
|
expect(context.runClient).toHaveBeenCalledTimes(name === "client" ? 1 : 0);
|
|
});
|
|
});
|