Deletes the vanilla shell and mounts App.tsx on #root. main.ts and the 23 views it drove are gone; App.tsx composes the ported components — sidebar, multi-view, command bar, spawn modal, help and restart overlays, daemon link, drawer — around the catalog and layout stores. The pure parts of four deleted modules moved next to the components that still use them: the spawn-form model and spawnSimilar into components/spawn, the transcript's markdown/format helpers and the diff into components/structured, the help overlay's grouping into components/dialogs. Document-level event names now live in uiEvents.ts. Deduplicated two pairs the migration left side by side: the sidebar uses dialogs/KillDialog and common/ContextMenu. It also listens for the command bar's kill/rename events, which nothing had picked up since catalog.ts went away. styles.css stays as the token and base layer, with `#app` renamed to `#root` and the pane-body rules re-keyed off the classes the React panes actually carry. Closes #253
122 lines
3.5 KiB
TypeScript
122 lines
3.5 KiB
TypeScript
import { describe, expect, it } from "vitest";
|
|
|
|
import { buildSpawnRequest, type SpawnFormValues } from "./model.js";
|
|
|
|
const base: SpawnFormValues = {
|
|
command: "claude",
|
|
cwd: "/home/user/project",
|
|
name: "amber-fox",
|
|
structuredView: false,
|
|
autoApprove: false,
|
|
worktreeEnabled: false,
|
|
worktreeBranch: "",
|
|
worktreeBranchMode: "new",
|
|
worktreeBranchEdited: false,
|
|
};
|
|
|
|
describe("buildSpawnRequest", () => {
|
|
it("builds a plain request with the picked cwd and command", () => {
|
|
const res = buildSpawnRequest(base, null);
|
|
expect(res).toEqual({
|
|
req: { cwd: "/home/user/project", command: "claude", metadata: { name: "amber-fox" } },
|
|
});
|
|
});
|
|
|
|
it("omits metadata.name when the name is blank", () => {
|
|
const res = buildSpawnRequest({ ...base, name: " " }, null);
|
|
expect(res).toEqual({ req: { cwd: base.cwd, command: base.command, metadata: {} } });
|
|
});
|
|
|
|
it.each(["claude", "FOO=1 /usr/local/bin/codex", "env -i codex"])(
|
|
"requests structured view for resolved %s commands",
|
|
(command) => {
|
|
expect(buildSpawnRequest({ ...base, command, structuredView: true }, null)).toEqual({
|
|
req: {
|
|
cwd: base.cwd,
|
|
command,
|
|
metadata: { name: "amber-fox" },
|
|
view: "Structured",
|
|
},
|
|
});
|
|
},
|
|
);
|
|
|
|
it("does not request structured view for unsupported commands", () => {
|
|
expect(
|
|
buildSpawnRequest({ ...base, command: "opencode", structuredView: true }, null),
|
|
).toEqual({
|
|
req: { cwd: base.cwd, command: "opencode", metadata: { name: "amber-fox" } },
|
|
});
|
|
});
|
|
|
|
it("attaches a trimmed branch when worktree is enabled, and always cleans up", () => {
|
|
const res = buildSpawnRequest(
|
|
{ ...base, worktreeEnabled: true, worktreeBranch: " feat/foo " },
|
|
"/home/user/project",
|
|
);
|
|
expect(res).toEqual({
|
|
req: {
|
|
cwd: base.cwd,
|
|
command: base.command,
|
|
metadata: { name: "amber-fox" },
|
|
worktree: {
|
|
base_repo: "/home/user/project",
|
|
branch: "feat/foo",
|
|
create_branch: true,
|
|
},
|
|
},
|
|
});
|
|
});
|
|
|
|
it("checks out an existing branch when the mode is existing (#61)", () => {
|
|
const res = buildSpawnRequest(
|
|
{
|
|
...base,
|
|
worktreeEnabled: true,
|
|
worktreeBranch: "spawn-v2",
|
|
worktreeBranchMode: "existing",
|
|
},
|
|
"/home/user/project",
|
|
);
|
|
expect(res).toEqual({
|
|
req: {
|
|
cwd: base.cwd,
|
|
command: base.command,
|
|
metadata: { name: "amber-fox" },
|
|
worktree: {
|
|
base_repo: "/home/user/project",
|
|
branch: "spawn-v2",
|
|
create_branch: false,
|
|
},
|
|
},
|
|
});
|
|
});
|
|
|
|
it("rejects an existing-mode worktree with no branch picked", () => {
|
|
expect(
|
|
buildSpawnRequest(
|
|
{ ...base, worktreeEnabled: true, worktreeBranch: "", worktreeBranchMode: "existing" },
|
|
"/repo",
|
|
),
|
|
).toHaveProperty("error");
|
|
});
|
|
|
|
it("rejects a missing working directory", () => {
|
|
expect(buildSpawnRequest({ ...base, cwd: "" }, null)).toHaveProperty("error");
|
|
});
|
|
|
|
it("rejects a missing command", () => {
|
|
expect(buildSpawnRequest({ ...base, command: "" }, null)).toHaveProperty("error");
|
|
});
|
|
|
|
it("rejects a worktree without an inferred base repo", () => {
|
|
expect(buildSpawnRequest({ ...base, worktreeEnabled: true, worktreeBranch: "b" }, null))
|
|
.toHaveProperty("error");
|
|
});
|
|
|
|
it("rejects a worktree without a branch name", () => {
|
|
expect(buildSpawnRequest({ ...base, worktreeEnabled: true, worktreeBranch: " " }, "/repo"))
|
|
.toHaveProperty("error");
|
|
});
|
|
});
|