Slice 9: git_checkout and create_branch (menu + MCP)

git boundary Checkout/CreateBranch; service GitCheckout/GitCreateBranch (activity detail names the branch; gitAction takes an ok-detail). HTTP /api/repo/git ops checkout + create-branch (branch field). MCP tools git_checkout and create_branch. <repo-menu> gains Switch branch… and New branch… (prompt for name). Service test covers create+switch and existing-branch failure. Checkout is not destructive - git refuses if it would overwrite changes.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
2026-09-20 17:27:58 -04:00
parent e59d5bbd29
commit e1999bcf21
10 changed files with 136 additions and 14 deletions
+34
View File
@@ -92,6 +92,18 @@ type gitActionOutput struct {
Output string `json:"output" jsonschema:"the git command output (may be empty)"`
}
// gitCheckoutInput selects a branch to switch to.
type gitCheckoutInput struct {
Path string `json:"path" jsonschema:"absolute path of the repository, from list_repos"`
Branch string `json:"branch" jsonschema:"the existing branch to switch to"`
}
// createBranchInput names a new branch to create.
type createBranchInput struct {
Path string `json:"path" jsonschema:"absolute path of the repository, from list_repos"`
Name string `json:"name" jsonschema:"the new branch name to create and switch to"`
}
// NewServer builds the MCP server and registers the (currently read-only) tools.
func NewServer(svc *service.Service, version string) *mcpsdk.Server {
s := mcpsdk.NewServer(&mcpsdk.Implementation{
@@ -253,6 +265,28 @@ func NewServer(svc *service.Service, version string) *mcpsdk.Server {
return nil, gitActionOutput{Output: out}, nil
})
mcpsdk.AddTool(s, &mcpsdk.Tool{
Name: "git_checkout",
Description: "Switch a repository to an existing branch. Git refuses if uncommitted changes would be overwritten (the error is returned). Path is from list_repos.",
}, func(ctx context.Context, _ *mcpsdk.CallToolRequest, in gitCheckoutInput) (*mcpsdk.CallToolResult, gitActionOutput, error) {
out, err := svc.GitCheckout(ctx, activity.ActorClaude, in.Path, in.Branch)
if err != nil {
return nil, gitActionOutput{}, err
}
return nil, gitActionOutput{Output: out}, nil
})
mcpsdk.AddTool(s, &mcpsdk.Tool{
Name: "create_branch",
Description: "Create a new branch from the current HEAD and switch to it (git checkout -b). Fails if the branch already exists. Path is from list_repos.",
}, func(ctx context.Context, _ *mcpsdk.CallToolRequest, in createBranchInput) (*mcpsdk.CallToolResult, gitActionOutput, error) {
out, err := svc.GitCreateBranch(ctx, activity.ActorClaude, in.Path, in.Name)
if err != nil {
return nil, gitActionOutput{}, err
}
return nil, gitActionOutput{Output: out}, nil
})
return s
}