1import { Type } from "@sinclair/typebox";
2import type { AgentTool } from "@mariozechner/pi-agent-core";
3import simpleGit from "simple-git";
4import { ToolInputError } from "../../../util/errors.js";
5
6// Trust boundary: refs and paths are passed directly to simple-git, which is
7// scoped to the workspace. The user chose to clone this repo, so its contents
8// are trusted. See AGENTS.md § Workspace Sandboxing.
9
10const CheckoutSchema = Type.Object({
11 ref: Type.String({ description: "Ref to checkout" }),
12});
13
14export const createGitCheckoutTool = (workspacePath: string): AgentTool => ({
15 name: "git_checkout",
16 label: "Git Checkout",
17 description: "Checkout a branch, tag, or commit.",
18 parameters: CheckoutSchema as any,
19 execute: async (_toolCallId: string, params: any) => {
20 if (!String(params.ref ?? "").trim()) {
21 throw new ToolInputError("ref must be a non-empty string");
22 }
23 const git = simpleGit(workspacePath);
24 await git.checkout(params.ref);
25
26 return {
27 content: [{ type: "text", text: `Checked out ${params.ref}` }],
28 details: { ref: params.ref },
29 };
30 },
31});