diff --git a/internal/tools/alias_test.go b/internal/tools/alias_test.go index 76719e3..97cb9e5 100644 --- a/internal/tools/alias_test.go +++ b/internal/tools/alias_test.go @@ -14,20 +14,20 @@ import ( "github.com/stretchr/testify/require" ) -// #36: every caller (claude.ai connector, gitea's own convention) sends the -// repo identifier as `repo` and issue/PR index as `index`, but the tools -// declare them as `name` and `number`. Unmatched fields zero-valued the path -// segment and produced gitea's misleading /api/swagger 404. parseArgs now -// aliases repo->name and index->number so the idiomatic call works. +// #38: `repo` (and `number`) are the canonical, idiomatic gitea/GitHub arg names +// that identifier tools advertise. `name` is kept as a back-compat alias via the +// bidirectional shim, so old `name` callers still work. `index`->`number` stays. +// An explicit canonical (`repo`) always wins over its alias (`name`). func TestRepoAndIndexAliasesResolve(t *testing.T) { tests := []struct { name string args string wantPath string }{ - {"repo+index aliases", `{"owner":"mathias","repo":"infra","index":7}`, "/api/v1/repos/mathias/infra/issues/7"}, - {"canonical name+number", `{"owner":"mathias","name":"infra","number":7}`, "/api/v1/repos/mathias/infra/issues/7"}, - {"explicit name wins over repo", `{"owner":"mathias","name":"infra","repo":"ignored","number":7}`, "/api/v1/repos/mathias/infra/issues/7"}, + {"canonical repo+number", `{"owner":"mathias","repo":"infra","number":7}`, "/api/v1/repos/mathias/infra/issues/7"}, + {"repo+index alias", `{"owner":"mathias","repo":"infra","index":7}`, "/api/v1/repos/mathias/infra/issues/7"}, + {"legacy name alias", `{"owner":"mathias","name":"infra","number":7}`, "/api/v1/repos/mathias/infra/issues/7"}, + {"explicit repo wins over name", `{"owner":"mathias","name":"ignored","repo":"infra","number":7}`, "/api/v1/repos/mathias/infra/issues/7"}, } for _, tc := range tests { t.Run(tc.name, func(t *testing.T) { @@ -47,3 +47,28 @@ func TestRepoAndIndexAliasesResolve(t *testing.T) { }) } } + +// #38: identifier tools must ADVERTISE `repo` (not `name`) in their schema, so +// the contract a client reads matches what every caller sends. The two create +// tools keep `name` because there it means "name of the new repo", not an +// existing-repo identifier. +func TestRepoIsCanonicalInAdvertisedSchema(t *testing.T) { + c := gitea.NewClient("http://unused", "") + a := allowlist.New([]string{"mathias"}) + + identifier := map[string]json.RawMessage{ + "repo_get": tools.NewRepoGet(c, a).Descriptor().InputSchema, + "issue_get": tools.NewIssueGet(c, a).Descriptor().InputSchema, + "pr_merge": tools.NewPRMerge(c, a).Descriptor().InputSchema, + "repo_delete": tools.NewRepoDelete(c, a).Descriptor().InputSchema, + "file_read": tools.NewFileRead(c, a).Descriptor().InputSchema, + } + for name, sch := range identifier { + s := string(sch) + assert.Contains(t, s, `"repo":`, name+" must advertise repo") + assert.NotContains(t, s, `"name":`, name+" must not advertise name") + } + + // create tools keep `name` (new resource name, not an existing-repo id) + assert.Contains(t, string(tools.NewRepoCreate(c, a).Descriptor().InputSchema), `"name":`) +} diff --git a/internal/tools/branch_delete.go b/internal/tools/branch_delete.go index 8938602..162c947 100644 --- a/internal/tools/branch_delete.go +++ b/internal/tools/branch_delete.go @@ -27,17 +27,17 @@ func (t *BranchDelete) Descriptor() registry.ToolDescriptor { "type":"object", "properties":{ "owner":{"type":"string"}, - "name":{"type":"string"}, + "repo":{"type":"string"}, "branch":{"type":"string"} }, - "required":["owner","name","branch"] + "required":["owner","repo","branch"] }`), } } type branchDeleteArgs struct { Owner string `json:"owner"` - Name string `json:"name"` + Repo string `json:"repo"` Branch string `json:"branch"` } @@ -53,7 +53,7 @@ func (t *BranchDelete) Call(ctx context.Context, raw json.RawMessage) (json.RawM return nil, fmt.Errorf("branch is required: %w", gitea.ErrValidation) } - if err := t.c.DeleteBranch(ctx, args.Owner, args.Name, args.Branch); err != nil { + if err := t.c.DeleteBranch(ctx, args.Owner, args.Repo, args.Branch); err != nil { return nil, err } diff --git a/internal/tools/branch_list.go b/internal/tools/branch_list.go index f991d75..874b520 100644 --- a/internal/tools/branch_list.go +++ b/internal/tools/branch_list.go @@ -26,18 +26,18 @@ func (t *BranchList) Descriptor() registry.ToolDescriptor { "type":"object", "properties":{ "owner":{"type":"string"}, - "name":{"type":"string"}, + "repo":{"type":"string"}, "page":{"type":"integer","minimum":1}, "limit":{"type":"integer","minimum":1,"maximum":50} }, - "required":["owner","name"] + "required":["owner","repo"] }`), } } type branchListArgs struct { Owner string `json:"owner"` - Name string `json:"name"` + Repo string `json:"repo"` Page int `json:"page"` Limit int `json:"limit"` } @@ -51,7 +51,7 @@ func (t *BranchList) Call(ctx context.Context, raw json.RawMessage) (json.RawMes return nil, err } - branches, err := t.c.ListBranches(ctx, args.Owner, args.Name, args.Page, capLimit(args.Limit, 30)) + branches, err := t.c.ListBranches(ctx, args.Owner, args.Repo, args.Page, capLimit(args.Limit, 30)) if err != nil { return nil, err } diff --git a/internal/tools/branch_protection_get.go b/internal/tools/branch_protection_get.go index 821357c..7ce9b81 100644 --- a/internal/tools/branch_protection_get.go +++ b/internal/tools/branch_protection_get.go @@ -26,17 +26,17 @@ func (t *BranchProtectionGet) Descriptor() registry.ToolDescriptor { "type":"object", "properties":{ "owner":{"type":"string"}, - "name":{"type":"string"}, + "repo":{"type":"string"}, "branch":{"type":"string"} }, - "required":["owner","name","branch"] + "required":["owner","repo","branch"] }`), } } type branchProtectionGetArgs struct { Owner string `json:"owner"` - Name string `json:"name"` + Repo string `json:"repo"` Branch string `json:"branch"` } @@ -49,7 +49,7 @@ func (t *BranchProtectionGet) Call(ctx context.Context, raw json.RawMessage) (js return nil, err } - bp, err := t.c.GetBranchProtection(ctx, args.Owner, args.Name, args.Branch) + bp, err := t.c.GetBranchProtection(ctx, args.Owner, args.Repo, args.Branch) if err != nil { return nil, err } diff --git a/internal/tools/dir_list.go b/internal/tools/dir_list.go index 14ac572..b0df36d 100644 --- a/internal/tools/dir_list.go +++ b/internal/tools/dir_list.go @@ -26,18 +26,18 @@ func (t *DirList) Descriptor() registry.ToolDescriptor { "type":"object", "properties":{ "owner":{"type":"string"}, - "name":{"type":"string"}, + "repo":{"type":"string"}, "path":{"type":"string"}, "ref":{"type":"string"} }, - "required":["owner","name"] + "required":["owner","repo"] }`), } } type dirListArgs struct { Owner string `json:"owner"` - Name string `json:"name"` + Repo string `json:"repo"` Path string `json:"path"` Ref string `json:"ref"` } @@ -51,7 +51,7 @@ func (t *DirList) Call(ctx context.Context, raw json.RawMessage) (json.RawMessag return nil, err } - entries, err := t.c.ListContents(ctx, args.Owner, args.Name, args.Path, args.Ref) + entries, err := t.c.ListContents(ctx, args.Owner, args.Repo, args.Path, args.Ref) if err != nil { return nil, err } diff --git a/internal/tools/file_delete.go b/internal/tools/file_delete.go index a06e6cb..b7c53a2 100644 --- a/internal/tools/file_delete.go +++ b/internal/tools/file_delete.go @@ -27,20 +27,20 @@ func (t *FileDelete) Descriptor() registry.ToolDescriptor { "type":"object", "properties":{ "owner":{"type":"string"}, - "name":{"type":"string"}, + "repo":{"type":"string"}, "path":{"type":"string"}, "branch":{"type":"string"}, "message":{"type":"string"}, "sha":{"type":"string"} }, - "required":["owner","name","path","branch","message","sha"] + "required":["owner","repo","path","branch","message","sha"] }`), } } type fileDeleteArgs struct { Owner string `json:"owner"` - Name string `json:"name"` + Repo string `json:"repo"` Path string `json:"path"` Branch string `json:"branch"` Message string `json:"message"` @@ -62,7 +62,7 @@ func (t *FileDelete) Call(ctx context.Context, raw json.RawMessage) (json.RawMes return nil, fmt.Errorf("message is required: %w", gitea.ErrValidation) } - result, err := t.c.DeleteFile(ctx, args.Owner, args.Name, args.Path, gitea.DeleteFileArgs{ + result, err := t.c.DeleteFile(ctx, args.Owner, args.Repo, args.Path, gitea.DeleteFileArgs{ Branch: args.Branch, Message: args.Message, Sha: args.Sha, diff --git a/internal/tools/file_read.go b/internal/tools/file_read.go index 1cef6f3..6eedad9 100644 --- a/internal/tools/file_read.go +++ b/internal/tools/file_read.go @@ -30,18 +30,18 @@ func (t *FileRead) Descriptor() registry.ToolDescriptor { "type":"object", "properties":{ "owner":{"type":"string"}, - "name":{"type":"string"}, + "repo":{"type":"string"}, "path":{"type":"string"}, "ref":{"type":"string"} }, - "required":["owner","name","path"] + "required":["owner","repo","path"] }`), } } type fileReadArgs struct { Owner string `json:"owner"` - Name string `json:"name"` + Repo string `json:"repo"` Path string `json:"path"` Ref string `json:"ref"` } @@ -58,13 +58,13 @@ func (t *FileRead) Call(ctx context.Context, raw json.RawMessage) (json.RawMessa ref := args.Ref if ref == "" { var err error - ref, err = t.c.DefaultBranch(ctx, args.Owner, args.Name) + ref, err = t.c.DefaultBranch(ctx, args.Owner, args.Repo) if err != nil { return nil, err } } - fc, err := t.c.GetFileContents(ctx, args.Owner, args.Name, args.Path, ref) + fc, err := t.c.GetFileContents(ctx, args.Owner, args.Repo, args.Path, ref) if err != nil { return nil, err } diff --git a/internal/tools/file_write_branch.go b/internal/tools/file_write_branch.go index eaf6113..8362d49 100644 --- a/internal/tools/file_write_branch.go +++ b/internal/tools/file_write_branch.go @@ -28,7 +28,7 @@ func (t *FileWriteBranch) Descriptor() registry.ToolDescriptor { "type":"object", "properties":{ "owner":{"type":"string"}, - "name":{"type":"string"}, + "repo":{"type":"string"}, "path":{"type":"string"}, "content":{"type":"string"}, "branch":{"type":"string"}, @@ -36,14 +36,14 @@ func (t *FileWriteBranch) Descriptor() registry.ToolDescriptor { "message":{"type":"string"}, "sha":{"type":"string"} }, - "required":["owner","name","path","content","branch","message"] + "required":["owner","repo","path","content","branch","message"] }`), } } type fileWriteBranchArgs struct { Owner string `json:"owner"` - Name string `json:"name"` + Repo string `json:"repo"` Path string `json:"path"` Content string `json:"content"` Branch string `json:"branch"` @@ -68,7 +68,7 @@ func (t *FileWriteBranch) Call(ctx context.Context, raw json.RawMessage) (json.R } // Resolve base default if branch needs to be created - exists, err := t.c.BranchExists(ctx, args.Owner, args.Name, args.Branch) + exists, err := t.c.BranchExists(ctx, args.Owner, args.Repo, args.Branch) if err != nil { return nil, err } @@ -76,18 +76,18 @@ func (t *FileWriteBranch) Call(ctx context.Context, raw json.RawMessage) (json.R base := args.Base if base == "" { var err error - base, err = t.c.DefaultBranch(ctx, args.Owner, args.Name) + base, err = t.c.DefaultBranch(ctx, args.Owner, args.Repo) if err != nil { return nil, err } } - if err := t.c.CreateBranch(ctx, args.Owner, args.Name, args.Branch, base); err != nil { + if err := t.c.CreateBranch(ctx, args.Owner, args.Repo, args.Branch, base); err != nil { return nil, err } } encoded := base64.StdEncoding.EncodeToString([]byte(args.Content)) - result, err := t.c.UpsertFile(ctx, args.Owner, args.Name, args.Path, gitea.UpsertFileArgs{ + result, err := t.c.UpsertFile(ctx, args.Owner, args.Repo, args.Path, gitea.UpsertFileArgs{ Branch: args.Branch, Content: encoded, Message: args.Message, diff --git a/internal/tools/issue_close.go b/internal/tools/issue_close.go index eb7532d..661ebfa 100644 --- a/internal/tools/issue_close.go +++ b/internal/tools/issue_close.go @@ -26,17 +26,17 @@ func (t *IssueClose) Descriptor() registry.ToolDescriptor { "type":"object", "properties":{ "owner":{"type":"string"}, - "name":{"type":"string"}, + "repo":{"type":"string"}, "number":{"type":"integer","minimum":1} }, - "required":["owner","name","number"] + "required":["owner","repo","number"] }`), } } type issueCloseArgs struct { Owner string `json:"owner"` - Name string `json:"name"` + Repo string `json:"repo"` Number int `json:"number"` } @@ -48,7 +48,7 @@ func (t *IssueClose) Call(ctx context.Context, raw json.RawMessage) (json.RawMes if err := t.a.Check(args.Owner); err != nil { return nil, err } - iss, err := t.c.SetIssueState(ctx, args.Owner, args.Name, args.Number, "closed") + iss, err := t.c.SetIssueState(ctx, args.Owner, args.Repo, args.Number, "closed") if err != nil { return nil, err } diff --git a/internal/tools/issue_comment.go b/internal/tools/issue_comment.go index 0b641e2..21d452a 100644 --- a/internal/tools/issue_comment.go +++ b/internal/tools/issue_comment.go @@ -29,18 +29,18 @@ func (t *IssueComment) Descriptor() registry.ToolDescriptor { "type":"object", "properties":{ "owner":{"type":"string"}, - "name":{"type":"string"}, + "repo":{"type":"string"}, "number":{"type":"integer","minimum":1}, "body":{"type":"string"} }, - "required":["owner","name","number","body"] + "required":["owner","repo","number","body"] }`), } } type issueCommentArgs struct { Owner string `json:"owner"` - Name string `json:"name"` + Repo string `json:"repo"` Number int `json:"number"` Body string `json:"body"` } @@ -61,7 +61,7 @@ func (t *IssueComment) Call(ctx context.Context, raw json.RawMessage) (json.RawM } body := identity.ApplyFooter(args.Body, auth.Caller(ctx)) - c, err := t.c.CreateIssueComment(ctx, args.Owner, args.Name, args.Number, body) + c, err := t.c.CreateIssueComment(ctx, args.Owner, args.Repo, args.Number, body) if err != nil { return nil, err } diff --git a/internal/tools/issue_create.go b/internal/tools/issue_create.go index a58b0d3..37cda25 100644 --- a/internal/tools/issue_create.go +++ b/internal/tools/issue_create.go @@ -29,21 +29,21 @@ func (t *IssueCreate) Descriptor() registry.ToolDescriptor { "type":"object", "properties":{ "owner":{"type":"string"}, - "name":{"type":"string"}, + "repo":{"type":"string"}, "title":{"type":"string"}, "body":{"type":"string"}, "labels":{"type":"array","items":{"type":"integer"}}, "assignees":{"type":"array","items":{"type":"string"}}, "milestone":{"type":"integer"} }, - "required":["owner","name","title"] + "required":["owner","repo","title"] }`), } } type issueCreateArgs struct { Owner string `json:"owner"` - Name string `json:"name"` + Repo string `json:"repo"` Title string `json:"title"` Body string `json:"body"` Labels []int64 `json:"labels"` @@ -64,7 +64,7 @@ func (t *IssueCreate) Call(ctx context.Context, raw json.RawMessage) (json.RawMe } body := identity.ApplyFooter(args.Body, auth.Caller(ctx)) - iss, err := t.c.CreateIssue(ctx, args.Owner, args.Name, gitea.CreateIssueArgs{ + iss, err := t.c.CreateIssue(ctx, args.Owner, args.Repo, gitea.CreateIssueArgs{ Title: args.Title, Body: body, Labels: args.Labels, diff --git a/internal/tools/issue_edit.go b/internal/tools/issue_edit.go index 6d9c3a7..dd6e49b 100644 --- a/internal/tools/issue_edit.go +++ b/internal/tools/issue_edit.go @@ -30,19 +30,19 @@ func (t *IssueEdit) Descriptor() registry.ToolDescriptor { "type":"object", "properties":{ "owner":{"type":"string"}, - "name":{"type":"string"}, + "repo":{"type":"string"}, "number":{"type":"integer","minimum":1}, "title":{"type":"string","description":"New title. Omit to leave unchanged."}, "body":{"type":"string","description":"New body, full replacement. Omit to leave unchanged."} }, - "required":["owner","name","number"] + "required":["owner","repo","number"] }`), } } type issueEditArgs struct { Owner string `json:"owner"` - Name string `json:"name"` + Repo string `json:"repo"` Number int `json:"number"` Title *string `json:"title,omitempty"` Body *string `json:"body,omitempty"` @@ -63,7 +63,7 @@ func (t *IssueEdit) Call(ctx context.Context, raw json.RawMessage) (json.RawMess return nil, fmt.Errorf("at least one of title or body must be set: %w", gitea.ErrValidation) } - iss, err := t.c.EditIssue(ctx, args.Owner, args.Name, args.Number, gitea.EditIssueArgs{ + iss, err := t.c.EditIssue(ctx, args.Owner, args.Repo, args.Number, gitea.EditIssueArgs{ Title: args.Title, Body: args.Body, }) diff --git a/internal/tools/issue_get.go b/internal/tools/issue_get.go index 1ee716d..0013c08 100644 --- a/internal/tools/issue_get.go +++ b/internal/tools/issue_get.go @@ -24,17 +24,17 @@ func (t *IssueGet) Descriptor() registry.ToolDescriptor { "type":"object", "properties":{ "owner":{"type":"string"}, - "name":{"type":"string"}, + "repo":{"type":"string"}, "number":{"type":"integer","minimum":1} }, - "required":["owner","name","number"] + "required":["owner","repo","number"] }`), } } type issueGetArgs struct { Owner string `json:"owner"` - Name string `json:"name"` + Repo string `json:"repo"` Number int `json:"number"` } @@ -46,7 +46,7 @@ func (t *IssueGet) Call(ctx context.Context, raw json.RawMessage) (json.RawMessa if err := t.a.Check(args.Owner); err != nil { return nil, err } - iss, err := t.c.GetIssue(ctx, args.Owner, args.Name, args.Number) + iss, err := t.c.GetIssue(ctx, args.Owner, args.Repo, args.Number) if err != nil { return nil, err } diff --git a/internal/tools/issue_list.go b/internal/tools/issue_list.go index 0889cc1..aab71b7 100644 --- a/internal/tools/issue_list.go +++ b/internal/tools/issue_list.go @@ -26,21 +26,21 @@ func (t *IssueList) Descriptor() registry.ToolDescriptor { "type":"object", "properties":{ "owner":{"type":"string"}, - "name":{"type":"string"}, + "repo":{"type":"string"}, "state":{"type":"string","enum":["open","closed","all"]}, "labels":{"type":"string"}, "since":{"type":"string"}, "page":{"type":"integer","minimum":1}, "limit":{"type":"integer","minimum":1,"maximum":50} }, - "required":["owner","name"] + "required":["owner","repo"] }`), } } type issueListArgs struct { Owner string `json:"owner"` - Name string `json:"name"` + Repo string `json:"repo"` State string `json:"state"` Labels string `json:"labels"` Since string `json:"since"` @@ -63,7 +63,7 @@ func (t *IssueList) Call(ctx context.Context, raw json.RawMessage) (json.RawMess if args.Page < 1 { args.Page = 1 } - issues, err := t.c.ListIssues(ctx, args.Owner, args.Name, gitea.ListIssuesArgs{ + issues, err := t.c.ListIssues(ctx, args.Owner, args.Repo, gitea.ListIssuesArgs{ State: args.State, Labels: args.Labels, Since: args.Since, diff --git a/internal/tools/issue_list_comments.go b/internal/tools/issue_list_comments.go index c2d2888..4a0b579 100644 --- a/internal/tools/issue_list_comments.go +++ b/internal/tools/issue_list_comments.go @@ -26,17 +26,17 @@ func (t *IssueListComments) Descriptor() registry.ToolDescriptor { "type":"object", "properties":{ "owner":{"type":"string"}, - "name":{"type":"string"}, + "repo":{"type":"string"}, "number":{"type":"integer","minimum":1} }, - "required":["owner","name","number"] + "required":["owner","repo","number"] }`), } } type issueListCommentsArgs struct { Owner string `json:"owner"` - Name string `json:"name"` + Repo string `json:"repo"` Number int `json:"number"` } @@ -48,7 +48,7 @@ func (t *IssueListComments) Call(ctx context.Context, raw json.RawMessage) (json if err := t.a.Check(args.Owner); err != nil { return nil, err } - comments, err := t.c.ListIssueComments(ctx, args.Owner, args.Name, args.Number) + comments, err := t.c.ListIssueComments(ctx, args.Owner, args.Repo, args.Number) if err != nil { return nil, err } diff --git a/internal/tools/issue_reopen.go b/internal/tools/issue_reopen.go index c3a9f53..6bfe038 100644 --- a/internal/tools/issue_reopen.go +++ b/internal/tools/issue_reopen.go @@ -26,17 +26,17 @@ func (t *IssueReopen) Descriptor() registry.ToolDescriptor { "type":"object", "properties":{ "owner":{"type":"string"}, - "name":{"type":"string"}, + "repo":{"type":"string"}, "number":{"type":"integer","minimum":1} }, - "required":["owner","name","number"] + "required":["owner","repo","number"] }`), } } type issueReopenArgs struct { Owner string `json:"owner"` - Name string `json:"name"` + Repo string `json:"repo"` Number int `json:"number"` } @@ -48,7 +48,7 @@ func (t *IssueReopen) Call(ctx context.Context, raw json.RawMessage) (json.RawMe if err := t.a.Check(args.Owner); err != nil { return nil, err } - iss, err := t.c.SetIssueState(ctx, args.Owner, args.Name, args.Number, "open") + iss, err := t.c.SetIssueState(ctx, args.Owner, args.Repo, args.Number, "open") if err != nil { return nil, err } diff --git a/internal/tools/pr_comment.go b/internal/tools/pr_comment.go index 32c1c52..9f6e974 100644 --- a/internal/tools/pr_comment.go +++ b/internal/tools/pr_comment.go @@ -29,18 +29,18 @@ func (t *PRComment) Descriptor() registry.ToolDescriptor { "type":"object", "properties":{ "owner":{"type":"string"}, - "name":{"type":"string"}, + "repo":{"type":"string"}, "number":{"type":"integer","minimum":1}, "body":{"type":"string"} }, - "required":["owner","name","number","body"] + "required":["owner","repo","number","body"] }`), } } type prCommentArgs struct { Owner string `json:"owner"` - Name string `json:"name"` + Repo string `json:"repo"` Number int `json:"number"` Body string `json:"body"` } @@ -61,7 +61,7 @@ func (t *PRComment) Call(ctx context.Context, raw json.RawMessage) (json.RawMess } body := identity.ApplyFooter(args.Body, auth.Caller(ctx)) - c, err := t.c.CreateIssueComment(ctx, args.Owner, args.Name, args.Number, body) + c, err := t.c.CreateIssueComment(ctx, args.Owner, args.Repo, args.Number, body) if err != nil { return nil, err } diff --git a/internal/tools/pr_create.go b/internal/tools/pr_create.go index c5ccfc5..a7334ea 100644 --- a/internal/tools/pr_create.go +++ b/internal/tools/pr_create.go @@ -29,21 +29,21 @@ func (t *PRCreate) Descriptor() registry.ToolDescriptor { "type":"object", "properties":{ "owner":{"type":"string"}, - "name":{"type":"string"}, + "repo":{"type":"string"}, "title":{"type":"string"}, "body":{"type":"string"}, "head":{"type":"string"}, "base":{"type":"string"}, "draft":{"type":"boolean"} }, - "required":["owner","name","title","head","base"] + "required":["owner","repo","title","head","base"] }`), } } type prCreateArgs struct { Owner string `json:"owner"` - Name string `json:"name"` + Repo string `json:"repo"` Title string `json:"title"` Body string `json:"body"` Head string `json:"head"` @@ -68,7 +68,7 @@ func (t *PRCreate) Call(ctx context.Context, raw json.RawMessage) (json.RawMessa body := identity.ApplyFooter(args.Body, auth.Caller(ctx)) - pr, err := t.c.CreatePullRequest(ctx, args.Owner, args.Name, gitea.CreatePullRequestArgs{ + pr, err := t.c.CreatePullRequest(ctx, args.Owner, args.Repo, gitea.CreatePullRequestArgs{ Title: args.Title, Body: body, Head: args.Head, diff --git a/internal/tools/pr_files_diff.go b/internal/tools/pr_files_diff.go index 12f131a..fb7f3a9 100644 --- a/internal/tools/pr_files_diff.go +++ b/internal/tools/pr_files_diff.go @@ -35,17 +35,17 @@ func (t *PRFilesDiff) Descriptor() registry.ToolDescriptor { "type":"object", "properties":{ "owner":{"type":"string"}, - "name":{"type":"string"}, + "repo":{"type":"string"}, "number":{"type":"integer","minimum":1} }, - "required":["owner","name","number"] + "required":["owner","repo","number"] }`), } } type prFilesDiffArgs struct { Owner string `json:"owner"` - Name string `json:"name"` + Repo string `json:"repo"` Number int `json:"number"` } @@ -70,12 +70,12 @@ func (t *PRFilesDiff) Call(ctx context.Context, raw json.RawMessage) (json.RawMe return nil, fmt.Errorf("number must be >= 1: %w", gitea.ErrValidation) } - files, err := t.c.GetPullRequestFiles(ctx, args.Owner, args.Name, args.Number) + files, err := t.c.GetPullRequestFiles(ctx, args.Owner, args.Repo, args.Number) if err != nil { return nil, err } - rawDiff, err := t.c.GetPullRequestDiff(ctx, args.Owner, args.Name, args.Number) + rawDiff, err := t.c.GetPullRequestDiff(ctx, args.Owner, args.Repo, args.Number) if err != nil { return nil, err } diff --git a/internal/tools/pr_get.go b/internal/tools/pr_get.go index 87334c0..3188fbd 100644 --- a/internal/tools/pr_get.go +++ b/internal/tools/pr_get.go @@ -25,17 +25,17 @@ func (t *PRGet) Descriptor() registry.ToolDescriptor { "type":"object", "properties":{ "owner":{"type":"string"}, - "name":{"type":"string"}, + "repo":{"type":"string"}, "number":{"type":"integer","minimum":1} }, - "required":["owner","name","number"] + "required":["owner","repo","number"] }`), } } type prGetArgs struct { Owner string `json:"owner"` - Name string `json:"name"` + Repo string `json:"repo"` Number int `json:"number"` } @@ -51,7 +51,7 @@ func (t *PRGet) Call(ctx context.Context, raw json.RawMessage) (json.RawMessage, return nil, fmt.Errorf("number must be >= 1: %w", gitea.ErrValidation) } - pr, err := t.c.GetPullRequest(ctx, args.Owner, args.Name, args.Number) + pr, err := t.c.GetPullRequest(ctx, args.Owner, args.Repo, args.Number) if err != nil { return nil, err } diff --git a/internal/tools/pr_list.go b/internal/tools/pr_list.go index b2ecb0d..f881a08 100644 --- a/internal/tools/pr_list.go +++ b/internal/tools/pr_list.go @@ -26,20 +26,20 @@ func (t *PRList) Descriptor() registry.ToolDescriptor { "type":"object", "properties":{ "owner":{"type":"string"}, - "name":{"type":"string"}, + "repo":{"type":"string"}, "state":{"type":"string","enum":["open","closed","all"]}, "head":{"type":"string"}, "page":{"type":"integer","minimum":1}, "limit":{"type":"integer","minimum":1,"maximum":50} }, - "required":["owner","name"] + "required":["owner","repo"] }`), } } type prListArgs struct { Owner string `json:"owner"` - Name string `json:"name"` + Repo string `json:"repo"` State string `json:"state"` Head string `json:"head"` Page int `json:"page"` @@ -59,7 +59,7 @@ func (t *PRList) Call(ctx context.Context, raw json.RawMessage) (json.RawMessage state = "open" } - prs, err := t.c.ListPullRequests(ctx, args.Owner, args.Name, state, args.Head, args.Page, capLimit(args.Limit, 30)) + prs, err := t.c.ListPullRequests(ctx, args.Owner, args.Repo, state, args.Head, args.Page, capLimit(args.Limit, 30)) if err != nil { return nil, err } diff --git a/internal/tools/pr_merge.go b/internal/tools/pr_merge.go index 6e6da4a..f6b0e0d 100644 --- a/internal/tools/pr_merge.go +++ b/internal/tools/pr_merge.go @@ -27,20 +27,20 @@ func (t *PRMerge) Descriptor() registry.ToolDescriptor { "type":"object", "properties":{ "owner":{"type":"string"}, - "name":{"type":"string"}, + "repo":{"type":"string"}, "index":{"type":"integer","minimum":1}, "style":{"type":"string","enum":["merge","squash","rebase"]}, "merge_message_title":{"type":"string"}, "merge_message_field":{"type":"string"} }, - "required":["owner","name","index"] + "required":["owner","repo","index"] }`), } } type prMergeArgs struct { Owner string `json:"owner"` - Name string `json:"name"` + Repo string `json:"repo"` Index int `json:"index"` Style string `json:"style"` Title string `json:"merge_message_title"` @@ -64,7 +64,7 @@ func (t *PRMerge) Call(ctx context.Context, raw json.RawMessage) (json.RawMessag style = "merge" } - if err := t.c.MergePullRequest(ctx, args.Owner, args.Name, args.Index, gitea.MergePRArgs{ + if err := t.c.MergePullRequest(ctx, args.Owner, args.Repo, args.Index, gitea.MergePRArgs{ Do: style, Title: args.Title, Body: args.Body, diff --git a/internal/tools/release_create.go b/internal/tools/release_create.go index 9a21247..cae04cb 100644 --- a/internal/tools/release_create.go +++ b/internal/tools/release_create.go @@ -26,7 +26,7 @@ func (t *ReleaseCreate) Descriptor() registry.ToolDescriptor { "type":"object", "properties":{ "owner":{"type":"string"}, - "name":{"type":"string"}, + "repo":{"type":"string"}, "tag_name":{"type":"string","description":"Tag to create or use, e.g. 'v1.0.0'."}, "release_name":{"type":"string","description":"Display name for the release."}, "body":{"type":"string","description":"Release notes / changelog."}, @@ -34,14 +34,14 @@ func (t *ReleaseCreate) Descriptor() registry.ToolDescriptor { "prerelease":{"type":"boolean"}, "target":{"type":"string","description":"Branch or commit SHA to tag. Defaults to repo default branch."} }, - "required":["owner","name","tag_name"] + "required":["owner","repo","tag_name"] }`), } } type releaseCreateArgs struct { Owner string `json:"owner"` - Name string `json:"name"` + Repo string `json:"repo"` TagName string `json:"tag_name"` ReleaseName string `json:"release_name"` Body string `json:"body"` @@ -58,7 +58,7 @@ func (t *ReleaseCreate) Call(ctx context.Context, raw json.RawMessage) (json.Raw if err := t.a.Check(args.Owner); err != nil { return nil, err } - rel, err := t.c.CreateRelease(ctx, args.Owner, args.Name, gitea.CreateReleaseArgs{ + rel, err := t.c.CreateRelease(ctx, args.Owner, args.Repo, gitea.CreateReleaseArgs{ TagName: args.TagName, Name: args.ReleaseName, Body: args.Body, diff --git a/internal/tools/repo_delete.go b/internal/tools/repo_delete.go index 0546773..3ea637e 100644 --- a/internal/tools/repo_delete.go +++ b/internal/tools/repo_delete.go @@ -27,17 +27,17 @@ func (t *RepoDelete) Descriptor() registry.ToolDescriptor { "type":"object", "properties":{ "owner":{"type":"string"}, - "name":{"type":"string"}, + "repo":{"type":"string"}, "confirm":{"type":"string","description":"Must equal the repo name exactly to proceed."} }, - "required":["owner","name","confirm"] + "required":["owner","repo","confirm"] }`), } } type repoDeleteArgs struct { Owner string `json:"owner"` - Name string `json:"name"` + Repo string `json:"repo"` Confirm string `json:"confirm"` } @@ -49,11 +49,11 @@ func (t *RepoDelete) Call(ctx context.Context, raw json.RawMessage) (json.RawMes if err := t.a.Check(args.Owner); err != nil { return nil, err } - if args.Confirm != args.Name { - return nil, fmt.Errorf("repo_delete requires confirm=%q to match the repo name — got %q", args.Name, args.Confirm) + if args.Confirm != args.Repo { + return nil, fmt.Errorf("repo_delete requires confirm=%q to match the repo name — got %q", args.Repo, args.Confirm) } - if err := t.c.DeleteRepo(ctx, args.Owner, args.Name); err != nil { + if err := t.c.DeleteRepo(ctx, args.Owner, args.Repo); err != nil { return nil, err } - return textOK(map[string]string{"status": "deleted", "repo": args.Owner + "/" + args.Name}) + return textOK(map[string]string{"status": "deleted", "repo": args.Owner + "/" + args.Repo}) } diff --git a/internal/tools/repo_get.go b/internal/tools/repo_get.go index b7fb650..ef1a4fa 100644 --- a/internal/tools/repo_get.go +++ b/internal/tools/repo_get.go @@ -22,15 +22,15 @@ func (t *RepoGet) Descriptor() registry.ToolDescriptor { Description: "Get a repo's metadata.", InputSchema: json.RawMessage(`{ "type":"object", - "properties":{"owner":{"type":"string"},"name":{"type":"string"}}, - "required":["owner","name"] + "properties":{"owner":{"type":"string"},"repo":{"type":"string"}}, + "required":["owner","repo"] }`), } } type repoGetArgs struct { Owner string `json:"owner"` - Name string `json:"name"` + Repo string `json:"repo"` } func (t *RepoGet) Call(ctx context.Context, raw json.RawMessage) (json.RawMessage, error) { @@ -41,7 +41,7 @@ func (t *RepoGet) Call(ctx context.Context, raw json.RawMessage) (json.RawMessag if err := t.a.Check(args.Owner); err != nil { return nil, err } - r, err := t.c.GetRepo(ctx, args.Owner, args.Name) + r, err := t.c.GetRepo(ctx, args.Owner, args.Repo) if err != nil { return nil, err } diff --git a/internal/tools/repo_mirror_push.go b/internal/tools/repo_mirror_push.go index 783c863..8309508 100644 --- a/internal/tools/repo_mirror_push.go +++ b/internal/tools/repo_mirror_push.go @@ -27,7 +27,7 @@ func (t *RepoMirrorPush) Descriptor() registry.ToolDescriptor { "type":"object", "properties":{ "owner":{"type":"string"}, - "name":{"type":"string"}, + "repo":{"type":"string"}, "action":{"type":"string","enum":["add","list","delete"]}, "remote_address":{"type":"string","description":"Mirror target URL (required for add)."}, "remote_username":{"type":"string"}, @@ -36,14 +36,14 @@ func (t *RepoMirrorPush) Descriptor() registry.ToolDescriptor { "sync_on_commit":{"type":"boolean"}, "mirror_name":{"type":"string","description":"Remote name to delete (required for delete)."} }, - "required":["owner","name","action"] + "required":["owner","repo","action"] }`), } } type repoMirrorPushArgs struct { Owner string `json:"owner"` - Name string `json:"name"` + Repo string `json:"repo"` Action string `json:"action"` RemoteAddress string `json:"remote_address"` RemoteUsername string `json:"remote_username"` @@ -82,7 +82,7 @@ func (t *RepoMirrorPush) Call(ctx context.Context, raw json.RawMessage) (json.Ra } switch args.Action { case "add": - m, err := t.c.AddPushMirror(ctx, args.Owner, args.Name, gitea.AddPushMirrorArgs{ + m, err := t.c.AddPushMirror(ctx, args.Owner, args.Repo, gitea.AddPushMirrorArgs{ RemoteAddress: args.RemoteAddress, RemoteUsername: args.RemoteUsername, RemotePassword: args.RemotePassword, @@ -94,7 +94,7 @@ func (t *RepoMirrorPush) Call(ctx context.Context, raw json.RawMessage) (json.Ra } return textOK(toSafeMirror(m)) case "list": - mirrors, err := t.c.ListPushMirrors(ctx, args.Owner, args.Name) + mirrors, err := t.c.ListPushMirrors(ctx, args.Owner, args.Repo) if err != nil { return nil, err } @@ -107,7 +107,7 @@ func (t *RepoMirrorPush) Call(ctx context.Context, raw json.RawMessage) (json.Ra if args.MirrorName == "" { return nil, fmt.Errorf("mirror_name is required for action=delete") } - if err := t.c.DeletePushMirror(ctx, args.Owner, args.Name, args.MirrorName); err != nil { + if err := t.c.DeletePushMirror(ctx, args.Owner, args.Repo, args.MirrorName); err != nil { return nil, err } return textOK(map[string]string{"status": "deleted", "mirror_name": args.MirrorName}) diff --git a/internal/tools/repo_status.go b/internal/tools/repo_status.go index ac2e939..f9f6313 100644 --- a/internal/tools/repo_status.go +++ b/internal/tools/repo_status.go @@ -26,17 +26,17 @@ func (t *RepoStatus) Descriptor() registry.ToolDescriptor { "type":"object", "properties":{ "owner":{"type":"string"}, - "name":{"type":"string"}, + "repo":{"type":"string"}, "branch":{"type":"string"} }, - "required":["owner","name"] + "required":["owner","repo"] }`), } } type repoStatusArgs struct { Owner string `json:"owner"` - Name string `json:"name"` + Repo string `json:"repo"` Branch string `json:"branch"` } @@ -52,23 +52,23 @@ func (t *RepoStatus) Call(ctx context.Context, raw json.RawMessage) (json.RawMes branch := args.Branch if branch == "" { var err error - branch, err = t.c.DefaultBranch(ctx, args.Owner, args.Name) + branch, err = t.c.DefaultBranch(ctx, args.Owner, args.Repo) if err != nil { return nil, err } } - branches, err := t.c.ListBranches(ctx, args.Owner, args.Name, 1, 50) + branches, err := t.c.ListBranches(ctx, args.Owner, args.Repo, 1, 50) if err != nil { return nil, err } - prs, err := t.c.ListPullRequests(ctx, args.Owner, args.Name, "open", "", 1, 50) + prs, err := t.c.ListPullRequests(ctx, args.Owner, args.Repo, "open", "", 1, 50) if err != nil { return nil, err } - bp, err := t.c.GetBranchProtection(ctx, args.Owner, args.Name, branch) + bp, err := t.c.GetBranchProtection(ctx, args.Owner, args.Repo, branch) if err != nil { return nil, err } diff --git a/internal/tools/repo_topics_update.go b/internal/tools/repo_topics_update.go index 7a330e9..657fb84 100644 --- a/internal/tools/repo_topics_update.go +++ b/internal/tools/repo_topics_update.go @@ -26,17 +26,17 @@ func (t *RepoTopicsUpdate) Descriptor() registry.ToolDescriptor { "type":"object", "properties":{ "owner":{"type":"string"}, - "name":{"type":"string"}, + "repo":{"type":"string"}, "topics":{"type":"array","items":{"type":"string"},"description":"Full replacement list. Send [] to clear all topics."} }, - "required":["owner","name","topics"] + "required":["owner","repo","topics"] }`), } } type repoTopicsUpdateArgs struct { Owner string `json:"owner"` - Name string `json:"name"` + Repo string `json:"repo"` Topics []string `json:"topics"` } @@ -48,7 +48,7 @@ func (t *RepoTopicsUpdate) Call(ctx context.Context, raw json.RawMessage) (json. if err := t.a.Check(args.Owner); err != nil { return nil, err } - if err := t.c.UpdateTopics(ctx, args.Owner, args.Name, args.Topics); err != nil { + if err := t.c.UpdateTopics(ctx, args.Owner, args.Repo, args.Topics); err != nil { return nil, err } return textOK(map[string]any{"status": "updated", "topics": args.Topics}) diff --git a/internal/tools/repo_tree.go b/internal/tools/repo_tree.go index 97ecdb0..acc963d 100644 --- a/internal/tools/repo_tree.go +++ b/internal/tools/repo_tree.go @@ -26,17 +26,17 @@ func (t *RepoTree) Descriptor() registry.ToolDescriptor { "type":"object", "properties":{ "owner":{"type":"string"}, - "name":{"type":"string"}, + "repo":{"type":"string"}, "ref":{"type":"string","description":"Branch, tag, or commit SHA."} }, - "required":["owner","name","ref"] + "required":["owner","repo","ref"] }`), } } type repoTreeArgs struct { Owner string `json:"owner"` - Name string `json:"name"` + Repo string `json:"repo"` Ref string `json:"ref"` } @@ -48,7 +48,7 @@ func (t *RepoTree) Call(ctx context.Context, raw json.RawMessage) (json.RawMessa if err := t.a.Check(args.Owner); err != nil { return nil, err } - tree, err := t.c.GetTree(ctx, args.Owner, args.Name, args.Ref, true) + tree, err := t.c.GetTree(ctx, args.Owner, args.Repo, args.Ref, true) if err != nil { return nil, err } diff --git a/internal/tools/repo_update.go b/internal/tools/repo_update.go index 5201070..60ed9ea 100644 --- a/internal/tools/repo_update.go +++ b/internal/tools/repo_update.go @@ -29,7 +29,7 @@ func (t *RepoUpdate) Descriptor() registry.ToolDescriptor { "type":"object", "properties":{ "owner":{"type":"string"}, - "name":{"type":"string"}, + "repo":{"type":"string"}, "description":{"type":"string"}, "private":{"type":"boolean","description":"Toggle visibility. false makes the repo public."}, "website":{"type":"string","description":"Homepage URL"}, @@ -38,14 +38,14 @@ func (t *RepoUpdate) Descriptor() registry.ToolDescriptor { "template":{"type":"boolean","description":"Toggle template-repo flag"}, "confirm":{"type":"string","description":"Required when setting private=false. Must equal the repo name."} }, - "required":["owner","name"] + "required":["owner","repo"] }`), } } type repoUpdateArgs struct { Owner string `json:"owner"` - Name string `json:"name"` + Repo string `json:"repo"` Description *string `json:"description,omitempty"` Private *bool `json:"private,omitempty"` Website *string `json:"website,omitempty"` @@ -66,8 +66,8 @@ func (t *RepoUpdate) Call(ctx context.Context, raw json.RawMessage) (json.RawMes // Making a repo public is a significant action — require explicit confirmation. if args.Private != nil && !*args.Private { - if args.Confirm != args.Name { - return nil, fmt.Errorf("setting private=false makes the repo public: set confirm=%q to proceed", args.Name) + if args.Confirm != args.Repo { + return nil, fmt.Errorf("setting private=false makes the repo public: set confirm=%q to proceed", args.Repo) } } @@ -76,7 +76,7 @@ func (t *RepoUpdate) Call(ctx context.Context, raw json.RawMessage) (json.RawMes return nil, fmt.Errorf("at least one updatable field must be set: %w", gitea.ErrValidation) } - r, err := t.c.UpdateRepo(ctx, args.Owner, args.Name, gitea.UpdateRepoArgs{ + r, err := t.c.UpdateRepo(ctx, args.Owner, args.Repo, gitea.UpdateRepoArgs{ Description: args.Description, Private: args.Private, Website: args.Website, diff --git a/internal/tools/tag_create.go b/internal/tools/tag_create.go index 7b6b435..fa7e6ad 100644 --- a/internal/tools/tag_create.go +++ b/internal/tools/tag_create.go @@ -27,19 +27,19 @@ func (t *TagCreate) Descriptor() registry.ToolDescriptor { "type":"object", "properties":{ "owner":{"type":"string"}, - "name":{"type":"string"}, + "repo":{"type":"string"}, "tag":{"type":"string"}, "target":{"type":"string"}, "message":{"type":"string"} }, - "required":["owner","name","tag","target"] + "required":["owner","repo","tag","target"] }`), } } type tagCreateArgs struct { Owner string `json:"owner"` - Name string `json:"name"` + Repo string `json:"repo"` Tag string `json:"tag"` Target string `json:"target"` Message string `json:"message"` @@ -60,7 +60,7 @@ func (t *TagCreate) Call(ctx context.Context, raw json.RawMessage) (json.RawMess return nil, fmt.Errorf("target is required: %w", gitea.ErrValidation) } - tag, err := t.c.CreateTag(ctx, args.Owner, args.Name, gitea.CreateTagArgs{ + tag, err := t.c.CreateTag(ctx, args.Owner, args.Repo, gitea.CreateTagArgs{ TagName: args.Tag, Target: args.Target, Message: args.Message, diff --git a/internal/tools/tool.go b/internal/tools/tool.go index 28132cc..ec4c287 100644 --- a/internal/tools/tool.go +++ b/internal/tools/tool.go @@ -21,19 +21,21 @@ func parseArgs(raw json.RawMessage, dst any) error { return json.Unmarshal(normalizeAliases(raw), dst) } -// normalizeAliases maps the near-universal gitea/GitHub argument names onto the -// idiosyncratic ones these tools declare: `repo` -> `name`, `index` -> `number`. -// Every MCP caller (the claude.ai connector, LLMs primed on gitea's own API) -// reaches for `repo`/`index`; without this the unmatched fields zero-valued the -// upstream path segment and produced gitea's misleading /api/swagger 404 (#36). -// The alias key is left intact so a tool whose real field IS `index` -// (e.g. pr_merge) is unaffected. +// normalizeAliases reconciles the two spellings of the repo identifier so a tool +// works whichever the caller sends. `repo` is the canonical, idiomatic name that +// identifier tools now advertise (#38); `name` is kept as a back-compat alias. +// The mapping is bidirectional: `name`->`repo` fills the new canonical for old +// callers, and `repo`->`name` still fills the two create tools (repo_create, +// create_project_from_template) whose `name` legitimately means "name of the new +// repo". `index`->`number` is kept for the issue tools whose canonical is +// `number`. An explicit canonical value always wins over its alias. func normalizeAliases(raw json.RawMessage) json.RawMessage { var m map[string]json.RawMessage if err := json.Unmarshal(raw, &m); err != nil { return raw // not a JSON object — leave untouched } changed := aliasInto(m, "name", "repo") + changed = aliasInto(m, "repo", "name") || changed changed = aliasInto(m, "number", "index") || changed if !changed { return raw diff --git a/internal/tools/workflow_run_list.go b/internal/tools/workflow_run_list.go index f6b486d..bed7420 100644 --- a/internal/tools/workflow_run_list.go +++ b/internal/tools/workflow_run_list.go @@ -26,7 +26,7 @@ func (t *WorkflowRunList) Descriptor() registry.ToolDescriptor { "type":"object", "properties":{ "owner":{"type":"string"}, - "name":{"type":"string"}, + "repo":{"type":"string"}, "branch":{"type":"string"}, "head_sha":{"type":"string"}, "status":{"type":"string","enum":["queued","in_progress","completed","all"]}, @@ -35,14 +35,14 @@ func (t *WorkflowRunList) Descriptor() registry.ToolDescriptor { "page":{"type":"integer","minimum":1}, "limit":{"type":"integer","minimum":1,"maximum":50} }, - "required":["owner","name"] + "required":["owner","repo"] }`), } } type workflowRunListArgs struct { Owner string `json:"owner"` - Name string `json:"name"` + Repo string `json:"repo"` Branch string `json:"branch"` HeadSHA string `json:"head_sha"` Status string `json:"status"` @@ -64,7 +64,7 @@ func (t *WorkflowRunList) Call(ctx context.Context, raw json.RawMessage) (json.R if args.Page < 1 { args.Page = 1 } - resp, err := t.c.ListWorkflowRuns(ctx, args.Owner, args.Name, gitea.ListWorkflowRunsArgs{ + resp, err := t.c.ListWorkflowRuns(ctx, args.Owner, args.Repo, gitea.ListWorkflowRunsArgs{ Branch: args.Branch, HeadSHA: args.HeadSHA, Status: args.Status, diff --git a/internal/tools/workflow_run_status.go b/internal/tools/workflow_run_status.go index 45ce198..4530c30 100644 --- a/internal/tools/workflow_run_status.go +++ b/internal/tools/workflow_run_status.go @@ -28,17 +28,17 @@ func (t *WorkflowRunStatus) Descriptor() registry.ToolDescriptor { "type":"object", "properties":{ "owner":{"type":"string"}, - "name":{"type":"string"}, + "repo":{"type":"string"}, "run_id":{"type":"integer","minimum":1} }, - "required":["owner","name","run_id"] + "required":["owner","repo","run_id"] }`), } } type workflowRunStatusArgs struct { Owner string `json:"owner"` - Name string `json:"name"` + Repo string `json:"repo"` RunID int64 `json:"run_id"` } @@ -54,7 +54,7 @@ func (t *WorkflowRunStatus) Call(ctx context.Context, raw json.RawMessage) (json return nil, fmt.Errorf("run_id must be >= 1: %w", gitea.ErrValidation) } - run, err := t.c.GetWorkflowRun(ctx, args.Owner, args.Name, args.RunID) + run, err := t.c.GetWorkflowRun(ctx, args.Owner, args.Repo, args.RunID) if err != nil { return nil, err } diff --git a/internal/tools/workflow_run_trigger.go b/internal/tools/workflow_run_trigger.go index 8a8dcdb..357d2fd 100644 --- a/internal/tools/workflow_run_trigger.go +++ b/internal/tools/workflow_run_trigger.go @@ -39,19 +39,19 @@ func (t *WorkflowRunTrigger) Descriptor() registry.ToolDescriptor { "type":"object", "properties":{ "owner":{"type":"string"}, - "name":{"type":"string"}, + "repo":{"type":"string"}, "workflow":{"type":"string"}, "ref":{"type":"string"}, "inputs":{"type":"object"} }, - "required":["owner","name","workflow"] + "required":["owner","repo","workflow"] }`), } } type workflowRunTriggerArgs struct { Owner string `json:"owner"` - Name string `json:"name"` + Repo string `json:"repo"` Workflow string `json:"workflow"` Ref string `json:"ref"` Inputs map[string]any `json:"inputs"` @@ -72,7 +72,7 @@ func (t *WorkflowRunTrigger) Call(ctx context.Context, raw json.RawMessage) (jso ref := args.Ref if ref == "" { var err error - ref, err = t.c.DefaultBranch(ctx, args.Owner, args.Name) + ref, err = t.c.DefaultBranch(ctx, args.Owner, args.Repo) if err != nil { return nil, err } @@ -80,9 +80,9 @@ func (t *WorkflowRunTrigger) Call(ctx context.Context, raw json.RawMessage) (jso // Snapshot the newest existing workflow_dispatch run BEFORE dispatching, so we // can tell our fresh run apart from a prior one (Gitea's 204 carries no run ID). - baseline := t.newestDispatchRunID(ctx, args.Owner, args.Name, args.Workflow, ref) + baseline := t.newestDispatchRunID(ctx, args.Owner, args.Repo, args.Workflow, ref) - if err := t.c.DispatchWorkflow(ctx, args.Owner, args.Name, args.Workflow, gitea.DispatchWorkflowArgs{ + if err := t.c.DispatchWorkflow(ctx, args.Owner, args.Repo, args.Workflow, gitea.DispatchWorkflowArgs{ Ref: ref, Inputs: args.Inputs, }); err != nil { @@ -101,7 +101,7 @@ func (t *WorkflowRunTrigger) Call(ctx context.Context, raw json.RawMessage) (jso case <-time.After(dispatchResolvePoll): } } - if r := t.newestDispatchRun(ctx, args.Owner, args.Name, args.Workflow, ref); r != nil && r.ID > baseline { + if r := t.newestDispatchRun(ctx, args.Owner, args.Repo, args.Workflow, ref); r != nil && r.ID > baseline { run = r break } @@ -119,7 +119,7 @@ func (t *WorkflowRunTrigger) Call(ctx context.Context, raw json.RawMessage) (jso htmlURL := run.HTMLURL if htmlURL == "" { - htmlURL = fmt.Sprintf("%s/%s/%s/actions/runs/%d", t.baseURL, args.Owner, args.Name, run.ID) + htmlURL = fmt.Sprintf("%s/%s/%s/actions/runs/%d", t.baseURL, args.Owner, args.Repo, run.ID) } return textOK(map[string]any{ "dispatched": true,