import { describe, expect, it } from "vitest";import { Schema } from "effect"; import { GitCreateWorktreeInput, GitPreparePullRequestThreadInput, GitRunStackedActionInput, GitResolvePullRequestResult,} from "./git"; const decodeCreateWorktreeInput = Schema.decodeUnknownSync(GitCreateWorktreeInput);const decodePreparePullRequestThreadInput = Schema.decodeUnknownSync( GitPreparePullRequestThreadInput,);const decodeRunStackedActionInput = Schema.decodeUnknownSync(GitRunStackedActionInput);const decodeResolvePullRequestResult = Schema.decodeUnknownSync(GitResolvePullRequestResult); describe("GitCreateWorktreeInput", () => { it("accepts omitted newBranch for existing-branch worktrees", () => { const parsed = decodeCreateWorktreeInput({ cwd: "/repo", branch: "feature/existing", path: "/tmp/worktree", }); expect(parsed.newBranch).toBeUndefined(); expect(parsed.branch).toBe("feature/existing"); });}); describe("GitPreparePullRequestThreadInput", () => { it("accepts pull request references and mode", () => { const parsed = decodePreparePullRequestThreadInput({ cwd: "/repo", reference: "#42", mode: "worktree", }); expect(parsed.reference).toBe("#42"); expect(parsed.mode).toBe("worktree"); });}); describe("GitResolvePullRequestResult", () => { it("decodes resolved pull request metadata", () => { const parsed = decodeResolvePullRequestResult({ pullRequest: { number: 42, title: "PR threads", url: "https://github.com/pingdotgg/codething-mvp/pull/42", baseBranch: "main", headBranch: "feature/pr-threads", state: "open", }, }); expect(parsed.pullRequest.number).toBe(42); expect(parsed.pullRequest.headBranch).toBe("feature/pr-threads"); });}); describe("GitRunStackedActionInput", () => { it("requires a client-provided actionId for progress correlation", () => { const parsed = decodeRunStackedActionInput({ actionId: "action-1", cwd: "/repo", action: "commit", modelSelection: { provider: "codex", model: "gpt-5.4-mini", }, }); expect(parsed.actionId).toBe("action-1"); expect(parsed.action).toBe("commit"); }); it("accepts git text generation as a modelSelection", () => { const parsed = decodeRunStackedActionInput({ actionId: "action-1", cwd: "/repo", action: "commit_push_pr", modelSelection: { provider: "claudeAgent", model: "claude-haiku-4-5", }, }); expect(parsed.modelSelection?.provider).toBe("claudeAgent"); expect(parsed.modelSelection?.model).toBe("claude-haiku-4-5"); });});
import { describe, expect, it } from "vitest";
import { Schema } from "effect";
import {
GitCreateWorktreeInput,
GitPreparePullRequestThreadInput,
GitRunStackedActionInput,
GitResolvePullRequestResult,
} from "./git";
const decodeCreateWorktreeInput = Schema.decodeUnknownSync(GitCreateWorktreeInput);
const decodePreparePullRequestThreadInput = Schema.decodeUnknownSync(
GitPreparePullRequestThreadInput,
);
const decodeRunStackedActionInput = Schema.decodeUnknownSync(GitRunStackedActionInput);
const decodeResolvePullRequestResult = Schema.decodeUnknownSync(GitResolvePullRequestResult);
describe("GitCreateWorktreeInput", () => {
it("accepts omitted newBranch for existing-branch worktrees", () => {
const parsed = decodeCreateWorktreeInput({
cwd: "/repo",
branch: "feature/existing",
path: "/tmp/worktree",
});
expect(parsed.newBranch).toBeUndefined();
expect(parsed.branch).toBe("feature/existing");
});
});
describe("GitPreparePullRequestThreadInput", () => {
it("accepts pull request references and mode", () => {
const parsed = decodePreparePullRequestThreadInput({
cwd: "/repo",
reference: "#42",
mode: "worktree",
});
expect(parsed.reference).toBe("#42");
expect(parsed.mode).toBe("worktree");
});
});
describe("GitResolvePullRequestResult", () => {
it("decodes resolved pull request metadata", () => {
const parsed = decodeResolvePullRequestResult({
pullRequest: {
number: 42,
title: "PR threads",
url: "https://github.com/pingdotgg/codething-mvp/pull/42",
baseBranch: "main",
headBranch: "feature/pr-threads",
state: "open",
},
});
expect(parsed.pullRequest.number).toBe(42);
expect(parsed.pullRequest.headBranch).toBe("feature/pr-threads");
});
});
describe("GitRunStackedActionInput", () => {
it("requires a client-provided actionId for progress correlation", () => {
const parsed = decodeRunStackedActionInput({
actionId: "action-1",
cwd: "/repo",
action: "commit",
modelSelection: {
provider: "codex",
model: "gpt-5.4-mini",
},
});
expect(parsed.actionId).toBe("action-1");
expect(parsed.action).toBe("commit");
});
it("accepts git text generation as a modelSelection", () => {
const parsed = decodeRunStackedActionInput({
actionId: "action-1",
cwd: "/repo",
action: "commit_push_pr",
modelSelection: {
provider: "claudeAgent",
model: "claude-haiku-4-5",
},
});
expect(parsed.modelSelection?.provider).toBe("claudeAgent");
expect(parsed.modelSelection?.model).toBe("claude-haiku-4-5");
});
});