use crate::git_caveats::GitCaveats;
pub trait GitTool: Send + Sync {
fn dispatch(
&self,
op: &str,
args: &serde_json::Value,
caveats: &GitCaveats,
) -> Result<String, String>;
}
pub fn git_tool_definition() -> serde_json::Value {
serde_json::json!({
"type": "function",
"function": {
"name": "git",
"description": "Run a git operation through the embedded engine \
(NOT run_command). Local-only: read status/log/diff, \
stage with add, commit, amend the last commit, create \
a branch (branch), switch to / create-and-switch a \
branch (checkout), delete a branch (branch-delete), \
and rebase (structured plan: reword/squash/drop). \
Writes (add/commit/amend/branch/checkout/branch-delete/ \
rebase) require the session to permit them; there are \
no network ops (pull/fetch/push are unavailable).",
"parameters": {
"type": "object",
"properties": {
"op": {
"type": "string",
"enum": ["status", "log", "diff", "add", "commit", "amend", "branch", "rebase", "checkout", "branch-delete"],
"description": "The git operation to run."
},
"onto": {
"type": "string",
"description": "For op=rebase: the base commit/ref to replay the plan onto."
},
"plan": {
"type": "array",
"description": "For op=rebase: ordered steps, oldest first. Each: \
{commit, action: pick|reword|squash|fixup|drop, message?}. \
reword/squash use message; squash folds into the previous \
commit keeping both messages; fixup folds discarding it; \
drop removes the commit. Aborts (no change) on any conflict.",
"items": {
"type": "object",
"properties": {
"commit": { "type": "string" },
"action": {
"type": "string",
"enum": ["pick", "reword", "squash", "fixup", "drop"]
},
"message": { "type": "string" }
},
"required": ["commit", "action"]
}
},
"paths": {
"type": "array",
"items": { "type": "string" },
"description": "For op=add: the paths to stage."
},
"message": {
"type": "string",
"description": "For op=commit: the commit message. For \
op=amend: the reworded message (omit to \
keep the existing one)."
},
"name": {
"type": "string",
"description": "The branch name — for op=branch (create), \
op=checkout (switch to / create), and \
op=branch-delete."
},
"create": {
"type": "boolean",
"description": "For op=checkout: create the branch at HEAD \
when it does not exist (default true, i.e. \
`checkout -b`). Set false to switch to an \
existing branch only."
},
"spec": {
"type": "string",
"enum": ["worktree", "staged"],
"description": "For op=diff: worktree (unstaged, default) or staged."
},
"limit": {
"type": "integer",
"description": "For op=log: max commits (default 20)."
}
},
"required": ["op"]
}
}
})
}