package tools import ( "context" "encoding/json" "fmt" "gitea.d-ma.be/mathias/gitea-mcp/internal/allowlist" "gitea.d-ma.be/mathias/gitea-mcp/internal/gitea" "gitea.d-ma.be/mathias/gitea-mcp/internal/registry" ) type RepoUpdate struct { c *gitea.Client a *allowlist.Allowlist } func NewRepoUpdate(c *gitea.Client, a *allowlist.Allowlist) *RepoUpdate { return &RepoUpdate{c: c, a: a} } func (t *RepoUpdate) Descriptor() registry.ToolDescriptor { return registry.ToolDescriptor{ Name: "repo_update", Description: "Update repository metadata via PATCH (archived, description, private, website, template). " + "Only fields explicitly set in the call are patched. " + "WARNING: private=false exposes the repo publicly — verify intent before calling.", InputSchema: json.RawMessage(`{ "type":"object", "properties":{ "owner":{"type":"string"}, "name":{"type":"string"}, "archived":{"type":"boolean","description":"Mark repo as archived (read-only). Reversible."}, "description":{"type":"string"}, "private":{"type":"boolean","description":"Toggle visibility. false makes the repo public."}, "website":{"type":"string","description":"Homepage URL"}, "template":{"type":"boolean","description":"Toggle template-repo flag"} }, "required":["owner","name"] }`), } } type repoUpdateArgs struct { Owner string `json:"owner"` Name string `json:"name"` Archived *bool `json:"archived,omitempty"` Description *string `json:"description,omitempty"` Private *bool `json:"private,omitempty"` Website *string `json:"website,omitempty"` Template *bool `json:"template,omitempty"` } func (t *RepoUpdate) Call(ctx context.Context, raw json.RawMessage) (json.RawMessage, error) { var args repoUpdateArgs if err := parseArgs(raw, &args); err != nil { return nil, err } if err := t.a.Check(args.Owner); err != nil { return nil, err } if args.Name == "" { return nil, fmt.Errorf("name required: %w", gitea.ErrValidation) } if args.Archived == nil && args.Description == nil && args.Private == nil && args.Website == nil && args.Template == nil { return nil, fmt.Errorf("at least one updatable field must be set: %w", gitea.ErrValidation) } updated, err := t.c.EditRepo(ctx, args.Owner, args.Name, gitea.EditRepoArgs{ Archived: args.Archived, Description: args.Description, Private: args.Private, Website: args.Website, Template: args.Template, }) if err != nil { return nil, fmt.Errorf("edit repo: %w", err) } return textOK(updated) }