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"); }); });