show.ts

 1import { Type } from "@sinclair/typebox";
 2import type { AgentTool } from "@mariozechner/pi-agent-core";
 3import simpleGit from "simple-git";
 4import { ToolInputError } from "../../../util/errors.js";
 5import { formatSize, truncateHead } from "../../../util/truncate.js";
 6
 7// Trust boundary: refs and paths are passed directly to simple-git, which is
 8// scoped to the workspace. The user chose to clone this repo, so its contents
 9// are trusted. See AGENTS.md § Workspace Sandboxing.
10
11const ShowSchema = Type.Object({
12  ref: Type.String({ description: "Commit hash or ref" }),
13});
14
15export const createGitShowTool = (workspacePath: string): AgentTool => ({
16  name: "git_show",
17  label: "Git Show",
18  description: "Show commit message and diff for a given ref.",
19  parameters: ShowSchema as any,
20  execute: async (_toolCallId: string, params: any) => {
21    if (!String(params.ref ?? "").trim()) {
22      throw new ToolInputError("ref must be a non-empty string");
23    }
24    const git = simpleGit(workspacePath);
25    const raw = await git.show([params.ref]);
26    const truncation = truncateHead(raw);
27
28    let text = truncation.content;
29    if (truncation.truncated) {
30      text += `\n\n[truncated: showing ${truncation.outputLines} of ${truncation.totalLines} lines (${formatSize(truncation.outputBytes)} of ${formatSize(truncation.totalBytes)})]`;
31    }
32
33    return {
34      content: [{ type: "text", text }],
35      details: { ref: params.ref, ...(truncation.truncated ? { truncation } : {}) },
36    };
37  },
38});