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