feat: add issue_edit tool (#34)
Adds issue_edit, mapping to Gitea's PATCH /repos/{owner}/{repo}/issues/{index},
so an existing issue's title and/or body can be edited through the MCP surface.
Previously the only post-create mutation was issue_comment, which buries
backlinks in the thread instead of the canonical body.
Partial patch via pointer fields (omitempty): omitted fields are left
untouched, an explicit empty string clears a field. Body is sent verbatim —
no identity footer — so repeated edits are idempotent, matching the acceptance
criteria. Registered alongside the other issue tools for tool_search discovery.
Closes #34
This commit is contained in:
+41
-10
@@ -9,16 +9,16 @@ import (
|
||||
)
|
||||
|
||||
type Issue struct {
|
||||
Number int `json:"number"`
|
||||
Title string `json:"title"`
|
||||
Body string `json:"body"`
|
||||
HTMLURL string `json:"html_url"`
|
||||
State string `json:"state"`
|
||||
CreatedAt string `json:"created_at"`
|
||||
UpdatedAt string `json:"updated_at"`
|
||||
Labels []Label `json:"labels"`
|
||||
Assignees []User `json:"assignees"`
|
||||
Comments int `json:"comments"`
|
||||
Number int `json:"number"`
|
||||
Title string `json:"title"`
|
||||
Body string `json:"body"`
|
||||
HTMLURL string `json:"html_url"`
|
||||
State string `json:"state"`
|
||||
CreatedAt string `json:"created_at"`
|
||||
UpdatedAt string `json:"updated_at"`
|
||||
Labels []Label `json:"labels"`
|
||||
Assignees []User `json:"assignees"`
|
||||
Comments int `json:"comments"`
|
||||
}
|
||||
|
||||
type Label struct {
|
||||
@@ -140,6 +140,37 @@ func (c *Client) SetIssueState(ctx context.Context, owner, repo string, number i
|
||||
return &iss, nil
|
||||
}
|
||||
|
||||
// EditIssueArgs uses pointers so omitempty distinguishes "not set" (nil,
|
||||
// left untouched) from an explicit empty string (clears the field). Maps to
|
||||
// Gitea's PATCH /repos/{owner}/{repo}/issues/{index}.
|
||||
type EditIssueArgs struct {
|
||||
Title *string `json:"title,omitempty"`
|
||||
Body *string `json:"body,omitempty"`
|
||||
}
|
||||
|
||||
// EditIssue patches an issue's title and/or body. Only fields set in args are
|
||||
// sent, so omitted fields are left as-is server-side. Body is sent verbatim —
|
||||
// no identity footer — so repeated edits are idempotent.
|
||||
func (c *Client) EditIssue(ctx context.Context, owner, repo string, number int, args EditIssueArgs) (*Issue, error) {
|
||||
p := fmt.Sprintf("/api/v1/repos/%s/%s/issues/%d", owner, repo, number)
|
||||
payload, err := json.Marshal(args)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
body, status, err := c.PatchJSON(ctx, p, payload)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if err := MapStatus(status, body); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
var iss Issue
|
||||
if err := json.Unmarshal(body, &iss); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return &iss, nil
|
||||
}
|
||||
|
||||
type IssueComment struct {
|
||||
ID int64 `json:"id"`
|
||||
Body string `json:"body"`
|
||||
|
||||
Reference in New Issue
Block a user