@github-tools/sdk 1.2.0 → 1.4.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.mjs CHANGED
@@ -1,767 +1,21 @@
1
- import { Octokit } from "octokit";
2
- import { ToolLoopAgent, tool } from "ai";
3
- import { z } from "zod";
1
+ import { A as addPullRequestComment, B as createRepository, C as addLabels, D as listIssues, E as getIssue, F as listPullRequestReviews, G as createOctokit, H as getFileContent, I as listPullRequests, L as mergePullRequest, M as createPullRequestReview, N as getPullRequest, O as listLabels, P as listPullRequestFiles, R as createBranch, S as addIssueComment, T as createIssue, U as getRepository, V as forkRepository, W as listBranches, _ as getBlame, a as listWorkflowJobs, b as searchCode, c as rerunWorkflowRun, d as createGistComment, f as deleteGist, g as updateGist, h as listGists, i as getWorkflowRun, j as createPullRequest, k as removeLabel, l as triggerWorkflow, m as listGistComments, o as listWorkflowRuns, p as getGist, r as cancelWorkflowRun, s as listWorkflows, t as createGithubAgent, u as createGist, v as getCommit, w as closeIssue, x as searchRepositories, y as listCommits, z as createOrUpdateFile } from "./agents-D9aKsd_7.mjs";
4
2
 
5
- //#region src/client.ts
6
- function createOctokit(token) {
7
- return new Octokit({ auth: token });
8
- }
9
-
10
- //#endregion
11
- //#region src/tools/repository.ts
12
- const getRepository = (octokit) => tool({
13
- description: "Get information about a GitHub repository including description, stars, forks, language, and default branch",
14
- inputSchema: z.object({
15
- owner: z.string().describe("Repository owner (user or organization)"),
16
- repo: z.string().describe("Repository name")
17
- }),
18
- execute: async ({ owner, repo }) => {
19
- const { data } = await octokit.rest.repos.get({
20
- owner,
21
- repo
22
- });
23
- return {
24
- name: data.name,
25
- fullName: data.full_name,
26
- description: data.description,
27
- url: data.html_url,
28
- defaultBranch: data.default_branch,
29
- stars: data.stargazers_count,
30
- forks: data.forks_count,
31
- openIssues: data.open_issues_count,
32
- language: data.language,
33
- private: data.private,
34
- createdAt: data.created_at,
35
- updatedAt: data.updated_at
36
- };
37
- }
38
- });
39
- const listBranches = (octokit) => tool({
40
- description: "List branches in a GitHub repository",
41
- inputSchema: z.object({
42
- owner: z.string().describe("Repository owner"),
43
- repo: z.string().describe("Repository name"),
44
- perPage: z.number().optional().default(30).describe("Number of branches to return (max 100)")
45
- }),
46
- execute: async ({ owner, repo, perPage }) => {
47
- const { data } = await octokit.rest.repos.listBranches({
48
- owner,
49
- repo,
50
- per_page: perPage
51
- });
52
- return data.map((branch) => ({
53
- name: branch.name,
54
- sha: branch.commit.sha,
55
- protected: branch.protected
56
- }));
57
- }
58
- });
59
- const getFileContent = (octokit) => tool({
60
- description: "Get the content of a file from a GitHub repository",
61
- inputSchema: z.object({
62
- owner: z.string().describe("Repository owner"),
63
- repo: z.string().describe("Repository name"),
64
- path: z.string().describe("Path to the file in the repository"),
65
- ref: z.string().optional().describe("Branch, tag, or commit SHA (defaults to the default branch)")
66
- }),
67
- execute: async ({ owner, repo, path, ref }) => {
68
- const { data } = await octokit.rest.repos.getContent({
69
- owner,
70
- repo,
71
- path,
72
- ref
73
- });
74
- if (Array.isArray(data)) return {
75
- type: "directory",
76
- entries: data.map((e) => ({
77
- name: e.name,
78
- type: e.type,
79
- path: e.path
80
- }))
81
- };
82
- if (data.type !== "file") return {
83
- type: data.type,
84
- path: data.path
85
- };
86
- const content = Buffer.from(data.content, "base64").toString("utf-8");
87
- return {
88
- type: "file",
89
- path: data.path,
90
- sha: data.sha,
91
- size: data.size,
92
- content
93
- };
94
- }
95
- });
96
- const createBranch = (octokit, { needsApproval = true } = {}) => tool({
97
- description: "Create a new branch in a GitHub repository from an existing branch or commit SHA",
98
- needsApproval,
99
- inputSchema: z.object({
100
- owner: z.string().describe("Repository owner"),
101
- repo: z.string().describe("Repository name"),
102
- branch: z.string().describe("Name for the new branch"),
103
- from: z.string().optional().describe("Source branch name or commit SHA to branch from (defaults to the default branch)")
104
- }),
105
- execute: async ({ owner, repo, branch, from }) => {
106
- let sha = from;
107
- if (!sha || !sha.match(/^[0-9a-f]{40}$/i)) {
108
- const { data: ref } = await octokit.rest.git.getRef({
109
- owner,
110
- repo,
111
- ref: `heads/${from || (await octokit.rest.repos.get({
112
- owner,
113
- repo
114
- })).data.default_branch}`
115
- });
116
- sha = ref.object.sha;
117
- }
118
- const { data } = await octokit.rest.git.createRef({
119
- owner,
120
- repo,
121
- ref: `refs/heads/${branch}`,
122
- sha
123
- });
124
- return {
125
- ref: data.ref,
126
- sha: data.object.sha,
127
- url: data.url
128
- };
129
- }
130
- });
131
- const forkRepository = (octokit, { needsApproval = true } = {}) => tool({
132
- description: "Fork a GitHub repository to the authenticated user account or a specified organization",
133
- needsApproval,
134
- inputSchema: z.object({
135
- owner: z.string().describe("Repository owner to fork from"),
136
- repo: z.string().describe("Repository name to fork"),
137
- organization: z.string().optional().describe("Organization to fork into (omit to fork to your personal account)"),
138
- name: z.string().optional().describe("Name for the forked repository (defaults to the original name)")
139
- }),
140
- execute: async ({ owner, repo, organization, name }) => {
141
- const { data } = await octokit.rest.repos.createFork({
142
- owner,
143
- repo,
144
- organization,
145
- name
146
- });
147
- return {
148
- name: data.name,
149
- fullName: data.full_name,
150
- url: data.html_url,
151
- cloneUrl: data.clone_url,
152
- sshUrl: data.ssh_url,
153
- defaultBranch: data.default_branch,
154
- private: data.private,
155
- parent: data.parent ? {
156
- fullName: data.parent.full_name,
157
- url: data.parent.html_url
158
- } : null
159
- };
160
- }
161
- });
162
- const createRepository = (octokit, { needsApproval = true } = {}) => tool({
163
- description: "Create a new GitHub repository for the authenticated user or a specified organization",
164
- needsApproval,
165
- inputSchema: z.object({
166
- name: z.string().describe("Repository name"),
167
- description: z.string().optional().describe("A short description of the repository"),
168
- isPrivate: z.boolean().optional().default(false).describe("Whether the repository is private"),
169
- autoInit: z.boolean().optional().default(false).describe("Create an initial commit with a README"),
170
- gitignoreTemplate: z.string().optional().describe("Gitignore template to use (e.g. \"Node\", \"Python\")"),
171
- licenseTemplate: z.string().optional().describe("License keyword (e.g. \"mit\", \"apache-2.0\")"),
172
- org: z.string().optional().describe("Organization to create the repository in (omit for personal repo)")
173
- }),
174
- execute: async ({ name, description, isPrivate, autoInit, gitignoreTemplate, licenseTemplate, org }) => {
175
- const params = {
176
- name,
177
- description,
178
- private: isPrivate,
179
- auto_init: autoInit,
180
- gitignore_template: gitignoreTemplate,
181
- license_template: licenseTemplate
182
- };
183
- const { data } = org ? await octokit.rest.repos.createInOrg({
184
- org,
185
- ...params
186
- }) : await octokit.rest.repos.createForAuthenticatedUser(params);
187
- return {
188
- name: data.name,
189
- fullName: data.full_name,
190
- description: data.description,
191
- url: data.html_url,
192
- cloneUrl: data.clone_url,
193
- sshUrl: data.ssh_url,
194
- defaultBranch: data.default_branch,
195
- private: data.private,
196
- createdAt: data.created_at
197
- };
198
- }
199
- });
200
- const createOrUpdateFile = (octokit, { needsApproval = true } = {}) => tool({
201
- description: "Create or update a file in a GitHub repository. Provide the SHA when updating an existing file.",
202
- needsApproval,
203
- inputSchema: z.object({
204
- owner: z.string().describe("Repository owner"),
205
- repo: z.string().describe("Repository name"),
206
- path: z.string().describe("Path to the file in the repository"),
207
- message: z.string().describe("Commit message"),
208
- content: z.string().describe("File content (plain text, will be base64-encoded automatically)"),
209
- branch: z.string().optional().describe("Branch to commit to (defaults to the default branch)"),
210
- sha: z.string().optional().describe("SHA of the file being replaced (required when updating an existing file)")
211
- }),
212
- execute: async ({ owner, repo, path, message, content, branch, sha }) => {
213
- const encoded = Buffer.from(content).toString("base64");
214
- const { data } = await octokit.rest.repos.createOrUpdateFileContents({
215
- owner,
216
- repo,
217
- path,
218
- message,
219
- content: encoded,
220
- branch,
221
- sha
222
- });
223
- return {
224
- path: data.content?.path,
225
- sha: data.content?.sha,
226
- commitSha: data.commit.sha,
227
- commitUrl: data.commit.html_url
228
- };
229
- }
230
- });
231
-
232
- //#endregion
233
- //#region src/tools/pull-requests.ts
234
- const listPullRequests = (octokit) => tool({
235
- description: "List pull requests for a GitHub repository",
236
- inputSchema: z.object({
237
- owner: z.string().describe("Repository owner"),
238
- repo: z.string().describe("Repository name"),
239
- state: z.enum([
240
- "open",
241
- "closed",
242
- "all"
243
- ]).optional().default("open").describe("Filter by state"),
244
- perPage: z.number().optional().default(30).describe("Number of results to return (max 100)")
245
- }),
246
- execute: async ({ owner, repo, state, perPage }) => {
247
- const { data } = await octokit.rest.pulls.list({
248
- owner,
249
- repo,
250
- state,
251
- per_page: perPage
252
- });
253
- return data.map((pr) => ({
254
- number: pr.number,
255
- title: pr.title,
256
- state: pr.state,
257
- url: pr.html_url,
258
- author: pr.user?.login,
259
- branch: pr.head.ref,
260
- base: pr.base.ref,
261
- draft: pr.draft,
262
- createdAt: pr.created_at,
263
- updatedAt: pr.updated_at
264
- }));
265
- }
266
- });
267
- const getPullRequest = (octokit) => tool({
268
- description: "Get detailed information about a specific pull request",
269
- inputSchema: z.object({
270
- owner: z.string().describe("Repository owner"),
271
- repo: z.string().describe("Repository name"),
272
- pullNumber: z.number().describe("Pull request number")
273
- }),
274
- execute: async ({ owner, repo, pullNumber }) => {
275
- const { data } = await octokit.rest.pulls.get({
276
- owner,
277
- repo,
278
- pull_number: pullNumber
279
- });
280
- return {
281
- number: data.number,
282
- title: data.title,
283
- body: data.body,
284
- state: data.state,
285
- url: data.html_url,
286
- author: data.user?.login,
287
- branch: data.head.ref,
288
- base: data.base.ref,
289
- draft: data.draft,
290
- merged: data.merged,
291
- mergeable: data.mergeable,
292
- additions: data.additions,
293
- deletions: data.deletions,
294
- changedFiles: data.changed_files,
295
- createdAt: data.created_at,
296
- updatedAt: data.updated_at,
297
- mergedAt: data.merged_at
298
- };
299
- }
300
- });
301
- const createPullRequest = (octokit, { needsApproval = true } = {}) => tool({
302
- description: "Create a new pull request in a GitHub repository",
303
- needsApproval,
304
- inputSchema: z.object({
305
- owner: z.string().describe("Repository owner"),
306
- repo: z.string().describe("Repository name"),
307
- title: z.string().describe("Pull request title"),
308
- body: z.string().optional().describe("Pull request description (supports Markdown)"),
309
- head: z.string().describe("Branch containing the changes (format: branch or username:branch)"),
310
- base: z.string().describe("Branch to merge into"),
311
- draft: z.boolean().optional().default(false).describe("Create as draft pull request")
312
- }),
313
- execute: async ({ owner, repo, title, body, head, base, draft }) => {
314
- const { data } = await octokit.rest.pulls.create({
315
- owner,
316
- repo,
317
- title,
318
- body,
319
- head,
320
- base,
321
- draft
322
- });
323
- return {
324
- number: data.number,
325
- title: data.title,
326
- url: data.html_url,
327
- state: data.state,
328
- draft: data.draft,
329
- branch: data.head.ref,
330
- base: data.base.ref
331
- };
332
- }
333
- });
334
- const mergePullRequest = (octokit, { needsApproval = true } = {}) => tool({
335
- description: "Merge a pull request",
336
- needsApproval,
337
- inputSchema: z.object({
338
- owner: z.string().describe("Repository owner"),
339
- repo: z.string().describe("Repository name"),
340
- pullNumber: z.number().describe("Pull request number"),
341
- commitTitle: z.string().optional().describe("Title for the automatic merge commit"),
342
- commitMessage: z.string().optional().describe("Extra detail to append to automatic commit message"),
343
- mergeMethod: z.enum([
344
- "merge",
345
- "squash",
346
- "rebase"
347
- ]).optional().default("merge").describe("Merge strategy")
348
- }),
349
- execute: async ({ owner, repo, pullNumber, commitTitle, commitMessage, mergeMethod }) => {
350
- const { data } = await octokit.rest.pulls.merge({
351
- owner,
352
- repo,
353
- pull_number: pullNumber,
354
- commit_title: commitTitle,
355
- commit_message: commitMessage,
356
- merge_method: mergeMethod
357
- });
358
- return {
359
- merged: data.merged,
360
- message: data.message,
361
- sha: data.sha
362
- };
363
- }
364
- });
365
- const addPullRequestComment = (octokit, { needsApproval = true } = {}) => tool({
366
- description: "Add a comment to a pull request",
367
- needsApproval,
368
- inputSchema: z.object({
369
- owner: z.string().describe("Repository owner"),
370
- repo: z.string().describe("Repository name"),
371
- pullNumber: z.number().describe("Pull request number"),
372
- body: z.string().describe("Comment text (supports Markdown)")
373
- }),
374
- execute: async ({ owner, repo, pullNumber, body }) => {
375
- const { data } = await octokit.rest.issues.createComment({
376
- owner,
377
- repo,
378
- issue_number: pullNumber,
379
- body
380
- });
381
- return {
382
- id: data.id,
383
- url: data.html_url,
384
- body: data.body,
385
- author: data.user?.login,
386
- createdAt: data.created_at
387
- };
388
- }
389
- });
390
-
391
- //#endregion
392
- //#region src/tools/issues.ts
393
- const listIssues = (octokit) => tool({
394
- description: "List issues for a GitHub repository (excludes pull requests)",
395
- inputSchema: z.object({
396
- owner: z.string().describe("Repository owner"),
397
- repo: z.string().describe("Repository name"),
398
- state: z.enum([
399
- "open",
400
- "closed",
401
- "all"
402
- ]).optional().default("open").describe("Filter by state"),
403
- labels: z.string().optional().describe("Comma-separated list of label names to filter by"),
404
- perPage: z.number().optional().default(30).describe("Number of results to return (max 100)")
405
- }),
406
- execute: async ({ owner, repo, state, labels, perPage }) => {
407
- const { data } = await octokit.rest.issues.listForRepo({
408
- owner,
409
- repo,
410
- state,
411
- labels,
412
- per_page: perPage
413
- });
414
- return data.filter((issue) => !issue.pull_request).map((issue) => ({
415
- number: issue.number,
416
- title: issue.title,
417
- state: issue.state,
418
- url: issue.html_url,
419
- author: issue.user?.login,
420
- labels: issue.labels.map((l) => typeof l === "string" ? l : l.name),
421
- createdAt: issue.created_at,
422
- updatedAt: issue.updated_at
423
- }));
424
- }
425
- });
426
- const getIssue = (octokit) => tool({
427
- description: "Get detailed information about a specific issue",
428
- inputSchema: z.object({
429
- owner: z.string().describe("Repository owner"),
430
- repo: z.string().describe("Repository name"),
431
- issueNumber: z.number().describe("Issue number")
432
- }),
433
- execute: async ({ owner, repo, issueNumber }) => {
434
- const { data } = await octokit.rest.issues.get({
435
- owner,
436
- repo,
437
- issue_number: issueNumber
438
- });
439
- return {
440
- number: data.number,
441
- title: data.title,
442
- body: data.body,
443
- state: data.state,
444
- url: data.html_url,
445
- author: data.user?.login,
446
- assignees: data.assignees?.map((a) => a.login),
447
- labels: data.labels.map((l) => typeof l === "string" ? l : l.name),
448
- comments: data.comments,
449
- createdAt: data.created_at,
450
- updatedAt: data.updated_at,
451
- closedAt: data.closed_at
452
- };
453
- }
454
- });
455
- const createIssue = (octokit, { needsApproval = true } = {}) => tool({
456
- description: "Create a new issue in a GitHub repository",
457
- needsApproval,
458
- inputSchema: z.object({
459
- owner: z.string().describe("Repository owner"),
460
- repo: z.string().describe("Repository name"),
461
- title: z.string().describe("Issue title"),
462
- body: z.string().optional().describe("Issue description (supports Markdown)"),
463
- labels: z.array(z.string()).optional().describe("Labels to apply to the issue"),
464
- assignees: z.array(z.string()).optional().describe("GitHub usernames to assign to the issue")
465
- }),
466
- execute: async ({ owner, repo, title, body, labels, assignees }) => {
467
- const { data } = await octokit.rest.issues.create({
468
- owner,
469
- repo,
470
- title,
471
- body,
472
- labels,
473
- assignees
474
- });
475
- return {
476
- number: data.number,
477
- title: data.title,
478
- url: data.html_url,
479
- state: data.state,
480
- labels: data.labels.map((l) => typeof l === "string" ? l : l.name)
481
- };
482
- }
483
- });
484
- const addIssueComment = (octokit, { needsApproval = true } = {}) => tool({
485
- description: "Add a comment to a GitHub issue",
486
- needsApproval,
487
- inputSchema: z.object({
488
- owner: z.string().describe("Repository owner"),
489
- repo: z.string().describe("Repository name"),
490
- issueNumber: z.number().describe("Issue number"),
491
- body: z.string().describe("Comment text (supports Markdown)")
492
- }),
493
- execute: async ({ owner, repo, issueNumber, body }) => {
494
- const { data } = await octokit.rest.issues.createComment({
495
- owner,
496
- repo,
497
- issue_number: issueNumber,
498
- body
499
- });
500
- return {
501
- id: data.id,
502
- url: data.html_url,
503
- body: data.body,
504
- author: data.user?.login,
505
- createdAt: data.created_at
506
- };
507
- }
508
- });
509
- const closeIssue = (octokit, { needsApproval = true } = {}) => tool({
510
- description: "Close an open GitHub issue",
511
- needsApproval,
512
- inputSchema: z.object({
513
- owner: z.string().describe("Repository owner"),
514
- repo: z.string().describe("Repository name"),
515
- issueNumber: z.number().describe("Issue number to close"),
516
- stateReason: z.enum(["completed", "not_planned"]).optional().default("completed").describe("Reason for closing")
517
- }),
518
- execute: async ({ owner, repo, issueNumber, stateReason }) => {
519
- const { data } = await octokit.rest.issues.update({
520
- owner,
521
- repo,
522
- issue_number: issueNumber,
523
- state: "closed",
524
- state_reason: stateReason
525
- });
526
- return {
527
- number: data.number,
528
- title: data.title,
529
- state: data.state,
530
- url: data.html_url,
531
- closedAt: data.closed_at
532
- };
533
- }
534
- });
535
-
536
- //#endregion
537
- //#region src/tools/search.ts
538
- const searchCode = (octokit) => tool({
539
- description: "Search for code in GitHub repositories. Use qualifiers like \"repo:owner/name\" to scope the search.",
540
- inputSchema: z.object({
541
- query: z.string().describe("Search query. Supports GitHub search qualifiers, e.g. \"useState repo:facebook/react\""),
542
- perPage: z.number().optional().default(10).describe("Number of results to return (max 30)")
543
- }),
544
- execute: async ({ query, perPage }) => {
545
- const { data } = await octokit.rest.search.code({
546
- q: query,
547
- per_page: perPage
548
- });
549
- return {
550
- totalCount: data.total_count,
551
- items: data.items.map((item) => ({
552
- name: item.name,
553
- path: item.path,
554
- url: item.html_url,
555
- repository: item.repository.full_name,
556
- sha: item.sha
557
- }))
558
- };
559
- }
560
- });
561
- const searchRepositories = (octokit) => tool({
562
- description: "Search for GitHub repositories by keyword, topic, language, or other qualifiers",
563
- inputSchema: z.object({
564
- query: z.string().describe("Search query. Supports GitHub search qualifiers, e.g. \"nuxt language:typescript stars:>1000\""),
565
- perPage: z.number().optional().default(10).describe("Number of results to return (max 30)"),
566
- sort: z.enum([
567
- "stars",
568
- "forks",
569
- "help-wanted-issues",
570
- "updated"
571
- ]).optional().describe("Sort field"),
572
- order: z.enum(["asc", "desc"]).optional().default("desc").describe("Sort order")
573
- }),
574
- execute: async ({ query, perPage, sort, order }) => {
575
- const { data } = await octokit.rest.search.repos({
576
- q: query,
577
- per_page: perPage,
578
- sort,
579
- order
580
- });
581
- return {
582
- totalCount: data.total_count,
583
- items: data.items.map((repo) => ({
584
- name: repo.name,
585
- fullName: repo.full_name,
586
- description: repo.description,
587
- url: repo.html_url,
588
- stars: repo.stargazers_count,
589
- forks: repo.forks_count,
590
- language: repo.language,
591
- topics: repo.topics
592
- }))
593
- };
594
- }
595
- });
596
-
597
- //#endregion
598
- //#region src/tools/commits.ts
599
- const listCommits = (octokit) => tool({
600
- description: "List commits for a GitHub repository. Filter by file path to see who changed a specific file and when (git blame alternative). Filter by author, branch, or date range.",
601
- inputSchema: z.object({
602
- owner: z.string().describe("Repository owner"),
603
- repo: z.string().describe("Repository name"),
604
- path: z.string().optional().describe("Only commits containing this file path"),
605
- sha: z.string().optional().describe("Branch name or commit SHA to start listing from"),
606
- author: z.string().optional().describe("GitHub username or email to filter commits by"),
607
- since: z.string().optional().describe("Only commits after this date (ISO 8601 format)"),
608
- until: z.string().optional().describe("Only commits before this date (ISO 8601 format)"),
609
- perPage: z.number().optional().default(30).describe("Number of results to return (max 100)")
610
- }),
611
- execute: async ({ owner, repo, path, sha, author, since, until, perPage }) => {
612
- const { data } = await octokit.rest.repos.listCommits({
613
- owner,
614
- repo,
615
- path,
616
- sha,
617
- author,
618
- since,
619
- until,
620
- per_page: perPage
621
- });
622
- return data.map((commit) => ({
623
- sha: commit.sha,
624
- message: commit.commit.message,
625
- author: commit.commit.author?.name,
626
- authorLogin: commit.author?.login,
627
- date: commit.commit.author?.date,
628
- url: commit.html_url
629
- }));
630
- }
631
- });
632
- const getCommit = (octokit) => tool({
633
- description: "Get detailed information about a specific commit, including the list of files changed with additions and deletions",
634
- inputSchema: z.object({
635
- owner: z.string().describe("Repository owner"),
636
- repo: z.string().describe("Repository name"),
637
- ref: z.string().describe("Commit SHA, branch name, or tag")
638
- }),
639
- execute: async ({ owner, repo, ref }) => {
640
- const { data } = await octokit.rest.repos.getCommit({
641
- owner,
642
- repo,
643
- ref
644
- });
645
- return {
646
- sha: data.sha,
647
- message: data.commit.message,
648
- author: data.commit.author?.name,
649
- authorLogin: data.author?.login,
650
- date: data.commit.author?.date,
651
- url: data.html_url,
652
- stats: data.stats ? {
653
- additions: data.stats.additions,
654
- deletions: data.stats.deletions,
655
- total: data.stats.total
656
- } : null,
657
- files: data.files?.map((file) => ({
658
- filename: file.filename,
659
- status: file.status,
660
- additions: file.additions,
661
- deletions: file.deletions,
662
- patch: file.patch
663
- }))
664
- };
665
- }
666
- });
667
-
668
- //#endregion
669
- //#region src/agents.ts
670
- const SHARED_RULES = `When a tool execution is denied by the user, do not retry it. Briefly acknowledge the decision and move on.`;
671
- const DEFAULT_INSTRUCTIONS = `You are a helpful GitHub assistant. You can read and explore repositories, issues, pull requests, commits, and code. You can also create issues, pull requests, comments, and update files when asked.
672
-
673
- ${SHARED_RULES}`;
674
- const PRESET_INSTRUCTIONS = {
675
- "code-review": `You are a code review assistant. Your job is to review pull requests thoroughly and provide constructive feedback.
676
-
677
- When reviewing a PR:
678
- - Read the PR description and changed files carefully
679
- - Check for bugs, logic errors, and edge cases
680
- - Suggest improvements when you spot issues
681
- - Be constructive — explain why something is a problem and how to fix it
682
- - Post your review as PR comments when asked
683
-
684
- ${SHARED_RULES}`,
685
- "issue-triage": `You are an issue triage assistant. Your job is to help manage and organize GitHub issues.
686
-
687
- When triaging issues:
688
- - Read issue descriptions carefully to understand the problem
689
- - Identify duplicates when possible
690
- - Help categorize and prioritize issues
691
- - Respond to users with clear, helpful information
692
- - Create new issues when asked, with clear titles and descriptions
693
-
694
- ${SHARED_RULES}`,
695
- "repo-explorer": `You are a repository explorer. Your job is to help users understand codebases and find information across GitHub repositories.
696
-
697
- When exploring repos:
698
- - Answer questions about code structure and organization
699
- - Summarize recent activity (commits, PRs, issues)
700
- - Find specific files, functions, or patterns in code
701
- - Explain how different parts of the codebase work together
702
- - You have read-only access — you cannot make changes
703
-
704
- ${SHARED_RULES}`,
705
- "maintainer": `You are a repository maintainer assistant. You have full access to manage repositories, issues, and pull requests.
706
-
707
- When maintaining repos:
708
- - Be careful with write operations — review before acting
709
- - Create well-structured issues and PRs with clear descriptions
710
- - Use merge strategies appropriate for the repository
711
- - Keep commit messages clean and descriptive
712
- - When closing issues, provide a clear reason
713
-
714
- ${SHARED_RULES}`
715
- };
716
- /**
717
- * Create a pre-configured GitHub agent powered by the AI SDK's `ToolLoopAgent`.
718
- *
719
- * Returns a `ToolLoopAgent` instance with `.generate()` and `.stream()` methods.
720
- *
721
- * @example
722
- * ```ts
723
- * import { createGithubAgent } from '@github-tools/sdk'
724
- *
725
- * const agent = createGithubAgent({
726
- * model: 'anthropic/claude-sonnet-4.6',
727
- * token: process.env.GITHUB_TOKEN!,
728
- * preset: 'code-review',
729
- * })
730
- *
731
- * const result = await agent.generate({ prompt: 'Review PR #42 on vercel/ai' })
732
- * ```
733
- */
734
- function createGithubAgent({ token, preset, requireApproval, instructions, additionalInstructions, ...agentOptions }) {
735
- const tools = createGithubTools({
736
- token,
737
- requireApproval,
738
- preset
739
- });
740
- const defaultPrompt = preset && !Array.isArray(preset) ? PRESET_INSTRUCTIONS[preset] : DEFAULT_INSTRUCTIONS;
741
- let resolvedInstructions;
742
- if (instructions) resolvedInstructions = instructions;
743
- else if (additionalInstructions) resolvedInstructions = `${defaultPrompt}\n\n${additionalInstructions}`;
744
- else resolvedInstructions = defaultPrompt;
745
- return new ToolLoopAgent({
746
- ...agentOptions,
747
- tools,
748
- instructions: resolvedInstructions
749
- });
750
- }
751
-
752
- //#endregion
753
3
  //#region src/index.ts
754
4
  const PRESET_TOOLS = {
755
5
  "code-review": [
756
6
  "getPullRequest",
757
7
  "listPullRequests",
8
+ "listPullRequestFiles",
9
+ "listPullRequestReviews",
758
10
  "getFileContent",
759
11
  "listCommits",
760
12
  "getCommit",
13
+ "getBlame",
761
14
  "getRepository",
762
15
  "listBranches",
763
16
  "searchCode",
764
- "addPullRequestComment"
17
+ "addPullRequestComment",
18
+ "createPullRequestReview"
765
19
  ],
766
20
  "issue-triage": [
767
21
  "listIssues",
@@ -769,22 +23,49 @@ const PRESET_TOOLS = {
769
23
  "createIssue",
770
24
  "addIssueComment",
771
25
  "closeIssue",
26
+ "listLabels",
27
+ "addLabels",
28
+ "removeLabel",
772
29
  "getRepository",
773
30
  "searchRepositories",
774
31
  "searchCode"
775
32
  ],
33
+ "ci-ops": [
34
+ "getRepository",
35
+ "listBranches",
36
+ "listCommits",
37
+ "getCommit",
38
+ "listWorkflows",
39
+ "listWorkflowRuns",
40
+ "getWorkflowRun",
41
+ "listWorkflowJobs",
42
+ "triggerWorkflow",
43
+ "cancelWorkflowRun",
44
+ "rerunWorkflowRun"
45
+ ],
776
46
  "repo-explorer": [
777
47
  "getRepository",
778
48
  "listBranches",
779
49
  "getFileContent",
780
50
  "listPullRequests",
781
51
  "getPullRequest",
52
+ "listPullRequestFiles",
53
+ "listPullRequestReviews",
782
54
  "listIssues",
783
55
  "getIssue",
56
+ "listLabels",
784
57
  "listCommits",
785
58
  "getCommit",
59
+ "getBlame",
786
60
  "searchCode",
787
- "searchRepositories"
61
+ "searchRepositories",
62
+ "listGists",
63
+ "getGist",
64
+ "listGistComments",
65
+ "listWorkflows",
66
+ "listWorkflowRuns",
67
+ "getWorkflowRun",
68
+ "listWorkflowJobs"
788
69
  ],
789
70
  "maintainer": [
790
71
  "getRepository",
@@ -796,18 +77,39 @@ const PRESET_TOOLS = {
796
77
  "createOrUpdateFile",
797
78
  "listPullRequests",
798
79
  "getPullRequest",
80
+ "listPullRequestFiles",
81
+ "listPullRequestReviews",
799
82
  "createPullRequest",
800
83
  "mergePullRequest",
801
84
  "addPullRequestComment",
85
+ "createPullRequestReview",
802
86
  "listIssues",
803
87
  "getIssue",
804
88
  "createIssue",
805
89
  "addIssueComment",
806
90
  "closeIssue",
91
+ "listLabels",
92
+ "addLabels",
93
+ "removeLabel",
807
94
  "listCommits",
808
95
  "getCommit",
96
+ "getBlame",
809
97
  "searchCode",
810
- "searchRepositories"
98
+ "searchRepositories",
99
+ "listGists",
100
+ "getGist",
101
+ "listGistComments",
102
+ "createGist",
103
+ "updateGist",
104
+ "deleteGist",
105
+ "createGistComment",
106
+ "listWorkflows",
107
+ "listWorkflowRuns",
108
+ "getWorkflowRun",
109
+ "listWorkflowJobs",
110
+ "triggerWorkflow",
111
+ "cancelWorkflowRun",
112
+ "rerunWorkflowRun"
811
113
  ]
812
114
  };
813
115
  function resolveApproval(toolName, config) {
@@ -851,39 +153,68 @@ function resolvePresetTools(preset) {
851
153
  * })
852
154
  * ```
853
155
  */
854
- function createGithubTools({ token, requireApproval = true, preset } = {}) {
156
+ function createGithubTools({ token, requireApproval = true, preset, overrides } = {}) {
855
157
  const resolvedToken = token || process.env.GITHUB_TOKEN;
856
158
  if (!resolvedToken) throw new Error("GitHub token is required. Pass it as `token` or set the GITHUB_TOKEN environment variable.");
857
- const octokit = createOctokit(resolvedToken);
858
159
  const approval = (name) => ({ needsApproval: resolveApproval(name, requireApproval) });
859
160
  const allowed = preset ? resolvePresetTools(preset) : null;
860
161
  const allTools = {
861
- getRepository: getRepository(octokit),
862
- listBranches: listBranches(octokit),
863
- getFileContent: getFileContent(octokit),
864
- listPullRequests: listPullRequests(octokit),
865
- getPullRequest: getPullRequest(octokit),
866
- listIssues: listIssues(octokit),
867
- getIssue: getIssue(octokit),
868
- searchCode: searchCode(octokit),
869
- searchRepositories: searchRepositories(octokit),
870
- listCommits: listCommits(octokit),
871
- getCommit: getCommit(octokit),
872
- createBranch: createBranch(octokit, approval("createBranch")),
873
- forkRepository: forkRepository(octokit, approval("forkRepository")),
874
- createRepository: createRepository(octokit, approval("createRepository")),
875
- createOrUpdateFile: createOrUpdateFile(octokit, approval("createOrUpdateFile")),
876
- createPullRequest: createPullRequest(octokit, approval("createPullRequest")),
877
- mergePullRequest: mergePullRequest(octokit, approval("mergePullRequest")),
878
- addPullRequestComment: addPullRequestComment(octokit, approval("addPullRequestComment")),
879
- createIssue: createIssue(octokit, approval("createIssue")),
880
- addIssueComment: addIssueComment(octokit, approval("addIssueComment")),
881
- closeIssue: closeIssue(octokit, approval("closeIssue"))
162
+ getRepository: getRepository(resolvedToken),
163
+ listBranches: listBranches(resolvedToken),
164
+ getFileContent: getFileContent(resolvedToken),
165
+ listPullRequests: listPullRequests(resolvedToken),
166
+ getPullRequest: getPullRequest(resolvedToken),
167
+ listIssues: listIssues(resolvedToken),
168
+ getIssue: getIssue(resolvedToken),
169
+ searchCode: searchCode(resolvedToken),
170
+ searchRepositories: searchRepositories(resolvedToken),
171
+ listCommits: listCommits(resolvedToken),
172
+ getCommit: getCommit(resolvedToken),
173
+ getBlame: getBlame(resolvedToken),
174
+ createBranch: createBranch(resolvedToken, approval("createBranch")),
175
+ forkRepository: forkRepository(resolvedToken, approval("forkRepository")),
176
+ createRepository: createRepository(resolvedToken, approval("createRepository")),
177
+ createOrUpdateFile: createOrUpdateFile(resolvedToken, approval("createOrUpdateFile")),
178
+ createPullRequest: createPullRequest(resolvedToken, approval("createPullRequest")),
179
+ mergePullRequest: mergePullRequest(resolvedToken, approval("mergePullRequest")),
180
+ addPullRequestComment: addPullRequestComment(resolvedToken, approval("addPullRequestComment")),
181
+ listPullRequestFiles: listPullRequestFiles(resolvedToken),
182
+ listPullRequestReviews: listPullRequestReviews(resolvedToken),
183
+ createPullRequestReview: createPullRequestReview(resolvedToken, approval("createPullRequestReview")),
184
+ createIssue: createIssue(resolvedToken, approval("createIssue")),
185
+ addIssueComment: addIssueComment(resolvedToken, approval("addIssueComment")),
186
+ closeIssue: closeIssue(resolvedToken, approval("closeIssue")),
187
+ listLabels: listLabels(resolvedToken),
188
+ addLabels: addLabels(resolvedToken, approval("addLabels")),
189
+ removeLabel: removeLabel(resolvedToken, approval("removeLabel")),
190
+ listGists: listGists(resolvedToken),
191
+ getGist: getGist(resolvedToken),
192
+ listGistComments: listGistComments(resolvedToken),
193
+ createGist: createGist(resolvedToken, approval("createGist")),
194
+ updateGist: updateGist(resolvedToken, approval("updateGist")),
195
+ deleteGist: deleteGist(resolvedToken, approval("deleteGist")),
196
+ createGistComment: createGistComment(resolvedToken, approval("createGistComment")),
197
+ listWorkflows: listWorkflows(resolvedToken),
198
+ listWorkflowRuns: listWorkflowRuns(resolvedToken),
199
+ getWorkflowRun: getWorkflowRun(resolvedToken),
200
+ listWorkflowJobs: listWorkflowJobs(resolvedToken),
201
+ triggerWorkflow: triggerWorkflow(resolvedToken, approval("triggerWorkflow")),
202
+ cancelWorkflowRun: cancelWorkflowRun(resolvedToken, approval("cancelWorkflowRun")),
203
+ rerunWorkflowRun: rerunWorkflowRun(resolvedToken, approval("rerunWorkflowRun"))
882
204
  };
205
+ if (overrides) {
206
+ for (const [name, toolOverrides] of Object.entries(overrides)) if (name in allTools && toolOverrides) {
207
+ const key = name;
208
+ Object.assign(allTools, { [key]: {
209
+ ...allTools[key],
210
+ ...toolOverrides
211
+ } });
212
+ }
213
+ }
883
214
  if (!allowed) return allTools;
884
215
  return Object.fromEntries(Object.entries(allTools).filter(([name]) => allowed.has(name)));
885
216
  }
886
217
 
887
218
  //#endregion
888
- export { addIssueComment, addPullRequestComment, closeIssue, createBranch, createGithubAgent, createGithubTools, createIssue, createOctokit, createOrUpdateFile, createPullRequest, createRepository, forkRepository, getCommit, getFileContent, getIssue, getPullRequest, getRepository, listBranches, listCommits, listIssues, listPullRequests, mergePullRequest, searchCode, searchRepositories };
219
+ export { addIssueComment, addLabels, addPullRequestComment, cancelWorkflowRun, closeIssue, createBranch, createGist, createGistComment, createGithubAgent, createGithubTools, createIssue, createOctokit, createOrUpdateFile, createPullRequest, createPullRequestReview, createRepository, deleteGist, forkRepository, getBlame, getCommit, getFileContent, getGist, getIssue, getPullRequest, getRepository, getWorkflowRun, listBranches, listCommits, listGistComments, listGists, listIssues, listLabels, listPullRequestFiles, listPullRequestReviews, listPullRequests, listWorkflowJobs, listWorkflowRuns, listWorkflows, mergePullRequest, removeLabel, rerunWorkflowRun, searchCode, searchRepositories, triggerWorkflow, updateGist };
889
220
  //# sourceMappingURL=index.mjs.map