import { writeFileSync } from "node:fs"; import { join } from "node:path"; import { type } from "arktype"; import { log } from "../utils/cli.ts"; import { formatFilesWithLineNumbers, type DiffFile } from "./checkout.ts"; import type { ToolContext } from "./server.ts"; import { execute, tool } from "./shared.ts"; interface GiteaCommit { sha?: string; html_url?: string; parents?: Array<{ sha?: string }>; commit?: { message?: string; author?: { name?: string; date?: string }; committer?: { name?: string; date?: string } }; author?: { login?: string }; committer?: { login?: string }; stats?: { additions?: number; deletions?: number; total?: number }; files?: Array<{ filename?: string; status?: string; patch?: string }>; } export const CommitInfo = type({ sha: type.string.describe("the commit SHA to fetch") }); export function CommitInfoTool(ctx: ToolContext) { return tool({ name: "get_commit_info", description: "Retrieve commit metadata and diff via Gitea API. Returns diffPath pointing to formatted diff file.", parameters: CommitInfo, execute: execute(async ({ sha }) => { const r = await ctx.gitea.request( "GET /repos/{owner}/{repo}/git/commits/{sha}", { owner: ctx.repo.owner, repo: ctx.repo.name, sha } ); const data = r.data as GiteaCommit; const files: DiffFile[] = (data.files ?? []).map((f) => ({ filename: f.filename, patch: f.patch })); const formatResult = formatFilesWithLineNumbers(files); const tempDir = process.env.SHOCKBOT_TEMP_DIR; if (!tempDir) throw new Error("SHOCKBOT_TEMP_DIR not set"); const diffFile = join(tempDir, `commit-${sha.slice(0, 7)}.diff`); writeFileSync(diffFile, formatResult.content); log.debug(`wrote commit diff to ${diffFile}`); return { sha: data.sha, message: data.commit?.message, author: data.author?.login ?? data.commit?.author?.name ?? null, committer: data.committer?.login ?? data.commit?.committer?.name ?? null, date: data.commit?.author?.date ?? data.commit?.committer?.date ?? "", url: data.html_url, parents: (data.parents ?? []).map((p) => p.sha), stats: data.stats ?? { additions: 0, deletions: 0, total: 0 }, fileCount: files.length, diffFile, }; }), }); }