/**
* Tool: git_status
* Check git repository status, branch, and changed files
*/
import { ToolHandler } from "../types/index.js";
import { execSync } from "child_process";
import path from "path";
import os from "os";
export const gitStatusTool: ToolHandler = async (args) => {
try {
// Get the repository path from args or use current directory
const repoPath = (args.path as string) || process.cwd();
// Validate it's a git repo
try {
execSync("git rev-parse --git-dir", {
cwd: repoPath,
stdio: "pipe",
});
} catch {
return {
error: "Not a git repository",
path: repoPath,
tip: "Make sure the path points to a valid git repository",
};
}
// Get current branch
const branch = execSync("git rev-parse --abbrev-ref HEAD", {
cwd: repoPath,
encoding: "utf-8",
}).trim();
// Get status
const status = execSync("git status --porcelain", {
cwd: repoPath,
encoding: "utf-8",
});
// Get commit info
const latestCommit = execSync(
'git log -1 --pretty=format:"%h - %s (%an, %ar)"',
{
cwd: repoPath,
encoding: "utf-8",
}
);
// Count changes
const lines = status.split("\n").filter((line) => line.trim());
const staged = lines.filter((line) => line.startsWith("M ") || line.startsWith("A ") || line.startsWith("D ") || line.startsWith("R ")).length;
const unstaged = lines.filter((line) => line.startsWith(" M") || line.startsWith(" D")).length;
const untracked = lines.filter((line) => line.startsWith("??")).length;
// Get remote info
let remoteBranch = "N/A";
try {
remoteBranch = execSync("git rev-parse --abbrev-ref --symbolic-full-name @{u}", {
cwd: repoPath,
encoding: "utf-8",
stdio: ["pipe", "pipe", "pipe"],
}).trim();
} catch {
remoteBranch = "No upstream branch";
}
return {
repository: repoPath,
branch,
remoteBranch,
status: {
staged,
unstaged,
untracked,
total: lines.length,
},
latestCommit,
isClean: lines.length === 0,
changedFiles: status.length > 0 ? status.split("\n").filter((l) => l) : [],
};
} catch (error) {
const errorMsg = error instanceof Error ? error.message : String(error);
return {
error: "Failed to get git status",
details: errorMsg,
};
}
};
export const gitStatusToolDefinition = {
name: "git_status",
description:
"Check the status of a git repository, including current branch, changed files, and commit history",
inputSchema: {
type: "object" as const,
properties: {
path: {
type: "string" as const,
description:
"Optional path to the git repository (defaults to current directory)",
},
},
},
};