Skip to content

Commit efc1ee3

Browse files
Merge branch 'main' into patch-1
2 parents c7a5123 + 543a1fa commit efc1ee3

File tree

5 files changed

+305
-31
lines changed

5 files changed

+305
-31
lines changed

pkg/github/issues.go

Lines changed: 6 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -376,12 +376,9 @@ func GetIssue(ctx context.Context, client *github.Client, deps ToolDependencies,
376376
}
377377
}
378378

379-
r, err := json.Marshal(issue)
380-
if err != nil {
381-
return nil, fmt.Errorf("failed to marshal issue: %w", err)
382-
}
379+
minimalIssue := convertToMinimalIssue(issue)
383380

384-
return utils.NewToolResultText(string(r)), nil
381+
return MarshalledTextResult(minimalIssue), nil
385382
}
386383

387384
func GetIssueComments(ctx context.Context, client *github.Client, deps ToolDependencies, owner string, repo string, issueNumber int, pagination PaginationParams) (*mcp.CallToolResult, error) {
@@ -436,12 +433,12 @@ func GetIssueComments(ctx context.Context, client *github.Client, deps ToolDepen
436433
comments = filteredComments
437434
}
438435

439-
r, err := json.Marshal(comments)
440-
if err != nil {
441-
return nil, fmt.Errorf("failed to marshal response: %w", err)
436+
minimalComments := make([]MinimalIssueComment, 0, len(comments))
437+
for _, comment := range comments {
438+
minimalComments = append(minimalComments, convertToMinimalIssueComment(comment))
442439
}
443440

444-
return utils.NewToolResultText(string(r)), nil
441+
return MarshalledTextResult(minimalComments), nil
445442
}
446443

447444
func GetSubIssues(ctx context.Context, client *github.Client, deps ToolDependencies, owner string, repo string, issueNumber int, pagination PaginationParams) (*mcp.CallToolResult, error) {

pkg/github/issues_test.go

Lines changed: 11 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -345,15 +345,15 @@ func Test_GetIssue(t *testing.T) {
345345

346346
textContent := getTextResult(t, result)
347347

348-
var returnedIssue github.Issue
348+
var returnedIssue MinimalIssue
349349
err = json.Unmarshal([]byte(textContent.Text), &returnedIssue)
350350
require.NoError(t, err)
351-
assert.Equal(t, *tc.expectedIssue.Number, *returnedIssue.Number)
352-
assert.Equal(t, *tc.expectedIssue.Title, *returnedIssue.Title)
353-
assert.Equal(t, *tc.expectedIssue.Body, *returnedIssue.Body)
354-
assert.Equal(t, *tc.expectedIssue.State, *returnedIssue.State)
355-
assert.Equal(t, *tc.expectedIssue.HTMLURL, *returnedIssue.HTMLURL)
356-
assert.Equal(t, *tc.expectedIssue.User.Login, *returnedIssue.User.Login)
351+
assert.Equal(t, tc.expectedIssue.GetNumber(), returnedIssue.Number)
352+
assert.Equal(t, tc.expectedIssue.GetTitle(), returnedIssue.Title)
353+
assert.Equal(t, tc.expectedIssue.GetBody(), returnedIssue.Body)
354+
assert.Equal(t, tc.expectedIssue.GetState(), returnedIssue.State)
355+
assert.Equal(t, tc.expectedIssue.GetHTMLURL(), returnedIssue.HTMLURL)
356+
assert.Equal(t, tc.expectedIssue.GetUser().GetLogin(), returnedIssue.User.Login)
357357
})
358358
}
359359
}
@@ -2020,16 +2020,16 @@ func Test_GetIssueComments(t *testing.T) {
20202020
textContent := getTextResult(t, result)
20212021

20222022
// Unmarshal and verify the result
2023-
var returnedComments []*github.IssueComment
2023+
var returnedComments []MinimalIssueComment
20242024
err = json.Unmarshal([]byte(textContent.Text), &returnedComments)
20252025
require.NoError(t, err)
20262026
assert.Equal(t, len(tc.expectedComments), len(returnedComments))
20272027
for i := range tc.expectedComments {
20282028
require.NotNil(t, tc.expectedComments[i].User)
20292029
require.NotNil(t, returnedComments[i].User)
2030-
assert.Equal(t, tc.expectedComments[i].GetID(), returnedComments[i].GetID())
2031-
assert.Equal(t, tc.expectedComments[i].GetBody(), returnedComments[i].GetBody())
2032-
assert.Equal(t, tc.expectedComments[i].GetUser().GetLogin(), returnedComments[i].GetUser().GetLogin())
2030+
assert.Equal(t, tc.expectedComments[i].GetID(), returnedComments[i].ID)
2031+
assert.Equal(t, tc.expectedComments[i].GetBody(), returnedComments[i].Body)
2032+
assert.Equal(t, tc.expectedComments[i].GetUser().GetLogin(), returnedComments[i].User.Login)
20332033
}
20342034
})
20352035
}

pkg/github/minimal_types.go

Lines changed: 280 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,8 @@
11
package github
22

33
import (
4+
"time"
5+
46
"github.com/google/go-github/v82/github"
57
)
68

@@ -134,8 +136,286 @@ type MinimalProject struct {
134136
OwnerType string `json:"owner_type,omitempty"`
135137
}
136138

139+
// MinimalReactions is the trimmed output type for reaction summaries, dropping the API URL.
140+
type MinimalReactions struct {
141+
TotalCount int `json:"total_count"`
142+
PlusOne int `json:"+1"`
143+
MinusOne int `json:"-1"`
144+
Laugh int `json:"laugh"`
145+
Confused int `json:"confused"`
146+
Heart int `json:"heart"`
147+
Hooray int `json:"hooray"`
148+
Rocket int `json:"rocket"`
149+
Eyes int `json:"eyes"`
150+
}
151+
152+
// MinimalIssue is the trimmed output type for issue objects to reduce verbosity.
153+
type MinimalIssue struct {
154+
Number int `json:"number"`
155+
Title string `json:"title"`
156+
Body string `json:"body,omitempty"`
157+
State string `json:"state"`
158+
StateReason string `json:"state_reason,omitempty"`
159+
Draft bool `json:"draft,omitempty"`
160+
Locked bool `json:"locked,omitempty"`
161+
HTMLURL string `json:"html_url"`
162+
User *MinimalUser `json:"user,omitempty"`
163+
AuthorAssociation string `json:"author_association,omitempty"`
164+
Labels []string `json:"labels,omitempty"`
165+
Assignees []string `json:"assignees,omitempty"`
166+
Milestone string `json:"milestone,omitempty"`
167+
Comments int `json:"comments,omitempty"`
168+
Reactions *MinimalReactions `json:"reactions,omitempty"`
169+
CreatedAt string `json:"created_at,omitempty"`
170+
UpdatedAt string `json:"updated_at,omitempty"`
171+
ClosedAt string `json:"closed_at,omitempty"`
172+
ClosedBy string `json:"closed_by,omitempty"`
173+
IssueType string `json:"issue_type,omitempty"`
174+
}
175+
176+
// MinimalIssueComment is the trimmed output type for issue comment objects to reduce verbosity.
177+
type MinimalIssueComment struct {
178+
ID int64 `json:"id"`
179+
Body string `json:"body,omitempty"`
180+
HTMLURL string `json:"html_url"`
181+
User *MinimalUser `json:"user,omitempty"`
182+
AuthorAssociation string `json:"author_association,omitempty"`
183+
Reactions *MinimalReactions `json:"reactions,omitempty"`
184+
CreatedAt string `json:"created_at,omitempty"`
185+
UpdatedAt string `json:"updated_at,omitempty"`
186+
}
187+
188+
// MinimalPullRequest is the trimmed output type for pull request objects to reduce verbosity.
189+
type MinimalPullRequest struct {
190+
Number int `json:"number"`
191+
Title string `json:"title"`
192+
Body string `json:"body,omitempty"`
193+
State string `json:"state"`
194+
Draft bool `json:"draft"`
195+
Merged bool `json:"merged"`
196+
MergeableState string `json:"mergeable_state,omitempty"`
197+
HTMLURL string `json:"html_url"`
198+
User *MinimalUser `json:"user,omitempty"`
199+
Labels []string `json:"labels,omitempty"`
200+
Assignees []string `json:"assignees,omitempty"`
201+
RequestedReviewers []string `json:"requested_reviewers,omitempty"`
202+
MergedBy string `json:"merged_by,omitempty"`
203+
Head *MinimalPRBranch `json:"head,omitempty"`
204+
Base *MinimalPRBranch `json:"base,omitempty"`
205+
Additions int `json:"additions,omitempty"`
206+
Deletions int `json:"deletions,omitempty"`
207+
ChangedFiles int `json:"changed_files,omitempty"`
208+
Commits int `json:"commits,omitempty"`
209+
Comments int `json:"comments,omitempty"`
210+
CreatedAt string `json:"created_at,omitempty"`
211+
UpdatedAt string `json:"updated_at,omitempty"`
212+
ClosedAt string `json:"closed_at,omitempty"`
213+
MergedAt string `json:"merged_at,omitempty"`
214+
Milestone string `json:"milestone,omitempty"`
215+
}
216+
217+
// MinimalPRBranch is the trimmed output type for pull request branch references.
218+
type MinimalPRBranch struct {
219+
Ref string `json:"ref"`
220+
SHA string `json:"sha"`
221+
Repo *MinimalPRBranchRepo `json:"repo,omitempty"`
222+
}
223+
224+
// MinimalPRBranchRepo is the trimmed repo info nested inside a PR branch.
225+
type MinimalPRBranchRepo struct {
226+
FullName string `json:"full_name"`
227+
Description string `json:"description,omitempty"`
228+
}
229+
137230
// Helper functions
138231

232+
func convertToMinimalIssue(issue *github.Issue) MinimalIssue {
233+
m := MinimalIssue{
234+
Number: issue.GetNumber(),
235+
Title: issue.GetTitle(),
236+
Body: issue.GetBody(),
237+
State: issue.GetState(),
238+
StateReason: issue.GetStateReason(),
239+
Draft: issue.GetDraft(),
240+
Locked: issue.GetLocked(),
241+
HTMLURL: issue.GetHTMLURL(),
242+
User: convertToMinimalUser(issue.GetUser()),
243+
AuthorAssociation: issue.GetAuthorAssociation(),
244+
Comments: issue.GetComments(),
245+
}
246+
247+
if issue.CreatedAt != nil {
248+
m.CreatedAt = issue.CreatedAt.Format(time.RFC3339)
249+
}
250+
if issue.UpdatedAt != nil {
251+
m.UpdatedAt = issue.UpdatedAt.Format(time.RFC3339)
252+
}
253+
if issue.ClosedAt != nil {
254+
m.ClosedAt = issue.ClosedAt.Format(time.RFC3339)
255+
}
256+
257+
for _, label := range issue.Labels {
258+
if label != nil {
259+
m.Labels = append(m.Labels, label.GetName())
260+
}
261+
}
262+
263+
for _, assignee := range issue.Assignees {
264+
if assignee != nil {
265+
m.Assignees = append(m.Assignees, assignee.GetLogin())
266+
}
267+
}
268+
269+
if closedBy := issue.GetClosedBy(); closedBy != nil {
270+
m.ClosedBy = closedBy.GetLogin()
271+
}
272+
273+
if milestone := issue.GetMilestone(); milestone != nil {
274+
m.Milestone = milestone.GetTitle()
275+
}
276+
277+
if issueType := issue.GetType(); issueType != nil {
278+
m.IssueType = issueType.GetName()
279+
}
280+
281+
if r := issue.Reactions; r != nil {
282+
m.Reactions = &MinimalReactions{
283+
TotalCount: r.GetTotalCount(),
284+
PlusOne: r.GetPlusOne(),
285+
MinusOne: r.GetMinusOne(),
286+
Laugh: r.GetLaugh(),
287+
Confused: r.GetConfused(),
288+
Heart: r.GetHeart(),
289+
Hooray: r.GetHooray(),
290+
Rocket: r.GetRocket(),
291+
Eyes: r.GetEyes(),
292+
}
293+
}
294+
295+
return m
296+
}
297+
298+
func convertToMinimalIssueComment(comment *github.IssueComment) MinimalIssueComment {
299+
m := MinimalIssueComment{
300+
ID: comment.GetID(),
301+
Body: comment.GetBody(),
302+
HTMLURL: comment.GetHTMLURL(),
303+
User: convertToMinimalUser(comment.GetUser()),
304+
AuthorAssociation: comment.GetAuthorAssociation(),
305+
}
306+
307+
if comment.CreatedAt != nil {
308+
m.CreatedAt = comment.CreatedAt.Format(time.RFC3339)
309+
}
310+
if comment.UpdatedAt != nil {
311+
m.UpdatedAt = comment.UpdatedAt.Format(time.RFC3339)
312+
}
313+
314+
if r := comment.Reactions; r != nil {
315+
m.Reactions = &MinimalReactions{
316+
TotalCount: r.GetTotalCount(),
317+
PlusOne: r.GetPlusOne(),
318+
MinusOne: r.GetMinusOne(),
319+
Laugh: r.GetLaugh(),
320+
Confused: r.GetConfused(),
321+
Heart: r.GetHeart(),
322+
Hooray: r.GetHooray(),
323+
Rocket: r.GetRocket(),
324+
Eyes: r.GetEyes(),
325+
}
326+
}
327+
328+
return m
329+
}
330+
331+
func convertToMinimalPullRequest(pr *github.PullRequest) MinimalPullRequest {
332+
m := MinimalPullRequest{
333+
Number: pr.GetNumber(),
334+
Title: pr.GetTitle(),
335+
Body: pr.GetBody(),
336+
State: pr.GetState(),
337+
Draft: pr.GetDraft(),
338+
Merged: pr.GetMerged(),
339+
MergeableState: pr.GetMergeableState(),
340+
HTMLURL: pr.GetHTMLURL(),
341+
User: convertToMinimalUser(pr.GetUser()),
342+
Additions: pr.GetAdditions(),
343+
Deletions: pr.GetDeletions(),
344+
ChangedFiles: pr.GetChangedFiles(),
345+
Commits: pr.GetCommits(),
346+
Comments: pr.GetComments(),
347+
}
348+
349+
if pr.CreatedAt != nil {
350+
m.CreatedAt = pr.CreatedAt.Format(time.RFC3339)
351+
}
352+
if pr.UpdatedAt != nil {
353+
m.UpdatedAt = pr.UpdatedAt.Format(time.RFC3339)
354+
}
355+
if pr.ClosedAt != nil {
356+
m.ClosedAt = pr.ClosedAt.Format(time.RFC3339)
357+
}
358+
if pr.MergedAt != nil {
359+
m.MergedAt = pr.MergedAt.Format(time.RFC3339)
360+
}
361+
362+
for _, label := range pr.Labels {
363+
if label != nil {
364+
m.Labels = append(m.Labels, label.GetName())
365+
}
366+
}
367+
368+
for _, assignee := range pr.Assignees {
369+
if assignee != nil {
370+
m.Assignees = append(m.Assignees, assignee.GetLogin())
371+
}
372+
}
373+
374+
for _, reviewer := range pr.RequestedReviewers {
375+
if reviewer != nil {
376+
m.RequestedReviewers = append(m.RequestedReviewers, reviewer.GetLogin())
377+
}
378+
}
379+
380+
if mergedBy := pr.GetMergedBy(); mergedBy != nil {
381+
m.MergedBy = mergedBy.GetLogin()
382+
}
383+
384+
if head := pr.Head; head != nil {
385+
m.Head = convertToMinimalPRBranch(head)
386+
}
387+
388+
if base := pr.Base; base != nil {
389+
m.Base = convertToMinimalPRBranch(base)
390+
}
391+
392+
if milestone := pr.GetMilestone(); milestone != nil {
393+
m.Milestone = milestone.GetTitle()
394+
}
395+
396+
return m
397+
}
398+
399+
func convertToMinimalPRBranch(branch *github.PullRequestBranch) *MinimalPRBranch {
400+
if branch == nil {
401+
return nil
402+
}
403+
404+
b := &MinimalPRBranch{
405+
Ref: branch.GetRef(),
406+
SHA: branch.GetSHA(),
407+
}
408+
409+
if repo := branch.GetRepo(); repo != nil {
410+
b.Repo = &MinimalPRBranchRepo{
411+
FullName: repo.GetFullName(),
412+
Description: repo.GetDescription(),
413+
}
414+
}
415+
416+
return b
417+
}
418+
139419
func convertToMinimalProject(fullProject *github.ProjectV2) *MinimalProject {
140420
if fullProject == nil {
141421
return nil

pkg/github/pullrequests.go

Lines changed: 2 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -186,12 +186,9 @@ func GetPullRequest(ctx context.Context, client *github.Client, deps ToolDepende
186186
}
187187
}
188188

189-
r, err := json.Marshal(pr)
190-
if err != nil {
191-
return nil, fmt.Errorf("failed to marshal response: %w", err)
192-
}
189+
minimalPR := convertToMinimalPullRequest(pr)
193190

194-
return utils.NewToolResultText(string(r)), nil
191+
return MarshalledTextResult(minimalPR), nil
195192
}
196193

197194
func GetPullRequestDiff(ctx context.Context, client *github.Client, owner, repo string, pullNumber int) (*mcp.CallToolResult, error) {

0 commit comments

Comments
 (0)