Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions .changeset/add-pr-review-and-label-tools.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"@github-tools/sdk": minor
---

Add PR review tools (`listPullRequestFiles`, `listPullRequestReviews`, `createPullRequestReview`) and label tools (`listLabels`, `addLabels`, `removeLabel`).
6 changes: 6 additions & 0 deletions apps/chat/shared/utils/tools/github.ts
Original file line number Diff line number Diff line change
Expand Up @@ -23,11 +23,17 @@ export const GITHUB_TOOL_META: Record<GithubToolName, GithubToolMeta> = {
createPullRequest: { title: 'Create Pull Request', label: 'Pull request created', labelActive: 'Creating pull request', icon: 'i-lucide-git-pull-request-arrow' },
mergePullRequest: { title: 'Merge Pull Request', label: 'Pull request merged', labelActive: 'Merging pull request', icon: 'i-lucide-git-merge' },
addPullRequestComment: { title: 'Comment on PR', label: 'Comment posted', labelActive: 'Posting PR comment', icon: 'i-lucide-message-square-plus' },
listPullRequestFiles: { title: 'List PR Files', label: 'Files listed', labelActive: 'Listing PR files', icon: 'i-lucide-file-diff' },
listPullRequestReviews: { title: 'List PR Reviews', label: 'Reviews listed', labelActive: 'Listing PR reviews', icon: 'i-lucide-message-circle' },
createPullRequestReview: { title: 'Submit PR Review', label: 'Review submitted', labelActive: 'Submitting PR review', icon: 'i-lucide-shield-check' },
listIssues: { title: 'List Issues', label: 'Issues listed', labelActive: 'Listing issues', icon: 'i-lucide-circle-dot' },
getIssue: { title: 'Get Issue', label: 'Issue fetched', labelActive: 'Fetching issue', icon: 'i-lucide-circle-dot' },
createIssue: { title: 'Create Issue', label: 'Issue created', labelActive: 'Creating issue', icon: 'i-lucide-circle-plus' },
addIssueComment: { title: 'Comment on Issue', label: 'Comment posted', labelActive: 'Posting issue comment', icon: 'i-lucide-message-square-plus' },
closeIssue: { title: 'Close Issue', label: 'Issue closed', labelActive: 'Closing issue', icon: 'i-lucide-circle-check' },
listLabels: { title: 'List Labels', label: 'Labels listed', labelActive: 'Listing labels', icon: 'i-lucide-tags' },
addLabels: { title: 'Add Labels', label: 'Labels added', labelActive: 'Adding labels', icon: 'i-lucide-tag' },
removeLabel: { title: 'Remove Label', label: 'Label removed', labelActive: 'Removing label', icon: 'i-lucide-x' },
searchCode: { title: 'Search Code', label: 'Code searched', labelActive: 'Searching code', icon: 'i-lucide-search-code' },
searchRepositories: { title: 'Search Repositories', label: 'Repositories searched', labelActive: 'Searching repositories', icon: 'i-lucide-search' },
listCommits: { title: 'List Commits', label: 'Commits listed', labelActive: 'Listing commits', icon: 'i-lucide-git-commit-horizontal' },
Expand Down
2 changes: 1 addition & 1 deletion apps/docs/app/pages/index.vue
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ useSeoMeta({
const layers = [
{
title: 'Tools',
description: '35 AI-callable GitHub operations — repositories, branches, pull requests, issues, commits, search, gists, and workflows.',
description: '42 AI-callable GitHub operations — repositories, branches, pull requests, issues, commits, search, gists, and workflows.',
to: '/api/tools-catalog',
icon: 'i-custom:sdk',
},
Expand Down
4 changes: 2 additions & 2 deletions apps/docs/content/docs/1.getting-started/1.introduction.md
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ Pass them to `generateText`, `streamText`, or any agent loop — the model decid

## Explore the tools

The SDK ships **36 tools** covering repositories, branches, pull requests, issues, commits, code search, gists, and workflows. Each tool wraps a GitHub API operation (mostly REST; line-level blame uses the GraphQL `Commit.blame` field) and is fully typed with [Zod](https://zod.dev) schemas.
The SDK ships **42 tools** covering repositories, branches, pull requests, issues, commits, code search, gists, and workflows. Each tool wraps a GitHub API operation (mostly REST; line-level blame uses the GraphQL `Commit.blame` field) and is fully typed with [Zod](https://zod.dev) schemas.

Browse the full list in the [Tools Catalog](/api/tools-catalog).

Expand Down Expand Up @@ -79,7 +79,7 @@ Install the **`github-tools-agents`** skill with `npx skills add https://github-
title: Tools
to: /api/tools-catalog
---
36 individual GitHub operations you wire into any AI SDK call — each callable as a durable workflow step.
42 individual GitHub operations you wire into any AI SDK call — each callable as a durable workflow step.
:::

:::card
Expand Down
2 changes: 1 addition & 1 deletion apps/docs/content/docs/2.guide/1.quick-start.md
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,7 @@ const { text } = await generateText({
console.log(text)
```

The SDK reads `GITHUB_TOKEN` from your environment automatically. This gives the model access to all 36 tools — see the [Tools Catalog](/api/tools-catalog) for what each one does.
The SDK reads `GITHUB_TOKEN` from your environment automatically. This gives the model access to all 42 tools — see the [Tools Catalog](/api/tools-catalog) for what each one does.

## Narrow tools with a preset

Expand Down
3 changes: 3 additions & 0 deletions apps/docs/content/docs/2.guide/3.approval-control.md
Original file line number Diff line number Diff line change
Expand Up @@ -82,7 +82,10 @@ const tools = createGithubTools({
| `createPullRequest` | Medium | Optional in trusted CI |
| `createBranch` | Low | Usually skip |
| `addPullRequestComment` | Low | Usually skip |
| `createPullRequestReview` | Medium | Require in production repos |
| `addIssueComment` | Low | Usually skip |
| `addLabels` | Low | Usually skip |
| `removeLabel` | Low | Usually skip |
| `deleteGist` | High | Always require approval |
| `createGist` | Medium | Optional in trusted CI |
| `updateGist` | Medium | Require in production |
Expand Down
6 changes: 6 additions & 0 deletions apps/docs/content/docs/3.api/1.tools-catalog.md
Original file line number Diff line number Diff line change
Expand Up @@ -54,9 +54,12 @@ Available in `code-review` and `maintainer` presets:
|---|---|---|
| `listPullRequests` | list pull requests filtered by state | — |
| `getPullRequest` | read PR details including diff stats | — |
| `listPullRequestFiles` | list files changed in a PR with diff status and patches | — |
| `listPullRequestReviews` | list reviews on a PR (approvals, change requests, comments) | — |
| `createPullRequest` | open a new pull request | Yes |
| `mergePullRequest` | merge a pull request | Yes |
| `addPullRequestComment` | post a review comment | Yes |
| `createPullRequestReview` | submit a formal review (approve, request changes, or comment) with inline comments | Yes |

## Issue tools

Expand All @@ -69,6 +72,9 @@ Available in `issue-triage` and `maintainer` presets:
| `createIssue` | create a new issue | Yes |
| `addIssueComment` | post a comment on an issue | Yes |
| `closeIssue` | close an issue thread | Yes |
| `listLabels` | list labels available in a repository | — |
| `addLabels` | add labels to an issue or pull request | Yes |
| `removeLabel` | remove a label from an issue or pull request | Yes |

## Gist tools

Expand Down
24 changes: 15 additions & 9 deletions packages/github-tools/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@

GitHub tools for the [AI SDK](https://ai-sdk.dev) — wrap GitHub's REST API as ready-to-use tools for any agent or `generateText` / `streamText` call.

36 tools covering repositories, branches, pull requests, issues, commits, search, gists, and workflows. Write operations support granular approval control out of the box.
42 tools covering repositories, branches, pull requests, issues, commits, search, gists, and workflows. Write operations support granular approval control out of the box.

## Installation

Expand Down Expand Up @@ -62,11 +62,11 @@ createGithubTools({ token, preset: ['code-review', 'issue-triage'] })

| Preset | Tools included |
|---|---|
| `code-review` | `getPullRequest`, `listPullRequests`, `getFileContent`, `listCommits`, `getCommit`, `getBlame`, `getRepository`, `listBranches`, `searchCode`, `addPullRequestComment` |
| `issue-triage` | `listIssues`, `getIssue`, `createIssue`, `addIssueComment`, `closeIssue`, `getRepository`, `searchRepositories`, `searchCode` |
| `code-review` | `getPullRequest`, `listPullRequests`, `listPullRequestFiles`, `listPullRequestReviews`, `getFileContent`, `listCommits`, `getCommit`, `getBlame`, `getRepository`, `listBranches`, `searchCode`, `addPullRequestComment`, `createPullRequestReview` |
| `issue-triage` | `listIssues`, `getIssue`, `createIssue`, `addIssueComment`, `closeIssue`, `listLabels`, `addLabels`, `removeLabel`, `getRepository`, `searchRepositories`, `searchCode` |
| `repo-explorer` | All read-only tools including gists and workflows (no write operations) |
| `ci-ops` | `listWorkflows`, `listWorkflowRuns`, `getWorkflowRun`, `listWorkflowJobs`, `triggerWorkflow`, `cancelWorkflowRun`, `rerunWorkflowRun`, `getRepository`, `listBranches`, `listCommits`, `getCommit` |
| `maintainer` | All 36 tools |
| `maintainer` | All 42 tools |

Omit `preset` to get all tools (same as `maintainer`).

Expand Down Expand Up @@ -113,7 +113,7 @@ createGithubTools({
})
```

Write tools: `createOrUpdateFile`, `createPullRequest`, `mergePullRequest`, `addPullRequestComment`, `createIssue`, `addIssueComment`, `closeIssue`, `createGist`, `updateGist`, `deleteGist`, `createGistComment`, `triggerWorkflow`, `cancelWorkflowRun`, `rerunWorkflowRun`.
Write tools: `createOrUpdateFile`, `createPullRequest`, `mergePullRequest`, `addPullRequestComment`, `createPullRequestReview`, `createIssue`, `addIssueComment`, `closeIssue`, `addLabels`, `removeLabel`, `createGist`, `updateGist`, `deleteGist`, `createGistComment`, `triggerWorkflow`, `cancelWorkflowRun`, `rerunWorkflowRun`.

All other tools are read-only and never require approval.

Expand Down Expand Up @@ -181,9 +181,12 @@ All presets work with `createDurableGithubAgent`.
|---|---|
| `listPullRequests` | List PRs filtered by state |
| `getPullRequest` | Get a PR's full details (diff stats, body, merge status) |
| `listPullRequestFiles` | List files changed in a PR with diff status and patches |
| `listPullRequestReviews` | List reviews on a PR (approvals, change requests, comments) |
| `createPullRequest` | Open a new PR |
| `mergePullRequest` | Merge a PR (merge, squash, or rebase) |
| `addPullRequestComment` | Post a comment on a PR |
| `createPullRequestReview` | Submit a formal review (approve, request changes, or comment) with inline comments |

### Issues

Expand All @@ -194,6 +197,9 @@ All presets work with `createDurableGithubAgent`.
| `createIssue` | Open a new issue |
| `addIssueComment` | Post a comment on an issue |
| `closeIssue` | Close an issue (completed or not planned) |
| `listLabels` | List labels available in a repository |
| `addLabels` | Add labels to an issue or pull request |
| `removeLabel` | Remove a label from an issue or pull request |

### Gists

Expand Down Expand Up @@ -247,10 +253,10 @@ Create one at **GitHub → Settings → Developer settings → Personal access t
| **Metadata** | Read-only | Always required (auto-included) |
| **Contents** | Read-only | `getRepository`, `listBranches`, `getFileContent`, `listCommits`, `getCommit`, `getBlame` |
| **Contents** | Read and write | `createOrUpdateFile` |
| **Pull requests** | Read-only | `listPullRequests`, `getPullRequest` |
| **Pull requests** | Read and write | `createPullRequest`, `mergePullRequest`, `addPullRequestComment` |
| **Issues** | Read-only | `listIssues`, `getIssue` |
| **Issues** | Read and write | `createIssue`, `addIssueComment`, `closeIssue` |
| **Pull requests** | Read-only | `listPullRequests`, `getPullRequest`, `listPullRequestFiles`, `listPullRequestReviews` |
| **Pull requests** | Read and write | `createPullRequest`, `mergePullRequest`, `addPullRequestComment`, `createPullRequestReview` |
| **Issues** | Read-only | `listIssues`, `getIssue`, `listLabels` |
| **Issues** | Read and write | `createIssue`, `addIssueComment`, `closeIssue`, `addLabels`, `removeLabel` |

| **Gists** | Read-only | `listGists`, `getGist`, `listGistComments` |
| **Gists** | Read and write | `createGist`, `updateGist`, `deleteGist`, `createGistComment` |
Expand Down
3 changes: 3 additions & 0 deletions packages/github-tools/src/agents.ts
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,8 @@ When reviewing a PR:
- Check for bugs, logic errors, and edge cases
- Suggest improvements when you spot issues
- Be constructive — explain why something is a problem and how to fix it
- Use listPullRequestFiles to see exactly which files changed before diving into details
- Use createPullRequestReview to submit a formal review with inline comments on specific lines
- Post your review as PR comments when asked

${SHARED_RULES}`,
Expand All @@ -29,6 +31,7 @@ When triaging issues:
- Identify duplicates when possible
- Help categorize and prioritize issues
- Respond to users with clear, helpful information
- Use listLabels to see available labels, then addLabels and removeLabel to categorize issues
- Create new issues when asked, with clear titles and descriptions

${SHARED_RULES}`,
Expand Down
28 changes: 20 additions & 8 deletions packages/github-tools/src/index.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { getRepository, listBranches, getFileContent, createBranch, forkRepository, createRepository, createOrUpdateFile } from './tools/repository'
import { listPullRequests, getPullRequest, createPullRequest, mergePullRequest, addPullRequestComment } from './tools/pull-requests'
import { listIssues, getIssue, createIssue, addIssueComment, closeIssue } from './tools/issues'
import { listPullRequests, getPullRequest, createPullRequest, mergePullRequest, addPullRequestComment, listPullRequestFiles, listPullRequestReviews, createPullRequestReview } from './tools/pull-requests'
import { listIssues, getIssue, createIssue, addIssueComment, closeIssue, listLabels, addLabels, removeLabel } from './tools/issues'
import { searchCode, searchRepositories } from './tools/search'
import { listCommits, getCommit, getBlame } from './tools/commits'
import { listGists, getGist, listGistComments, createGist, updateGist, deleteGist, createGistComment } from './tools/gists'
Expand All @@ -14,9 +14,12 @@ export type GithubWriteToolName =
| 'createPullRequest'
| 'mergePullRequest'
| 'addPullRequestComment'
| 'createPullRequestReview'
| 'createIssue'
| 'addIssueComment'
| 'closeIssue'
| 'addLabels'
| 'removeLabel'
| 'createGist'
| 'updateGist'
| 'deleteGist'
Expand Down Expand Up @@ -56,12 +59,13 @@ export type GithubToolPreset = 'code-review' | 'issue-triage' | 'repo-explorer'

const PRESET_TOOLS: Record<GithubToolPreset, string[]> = {
'code-review': [
'getPullRequest', 'listPullRequests', 'getFileContent', 'listCommits', 'getCommit', 'getBlame',
'getPullRequest', 'listPullRequests', 'listPullRequestFiles', 'listPullRequestReviews', 'getFileContent', 'listCommits', 'getCommit', 'getBlame',
'getRepository', 'listBranches', 'searchCode',
'addPullRequestComment'
'addPullRequestComment', 'createPullRequestReview'
],
'issue-triage': [
'listIssues', 'getIssue', 'createIssue', 'addIssueComment', 'closeIssue',
'listLabels', 'addLabels', 'removeLabel',
'getRepository', 'searchRepositories', 'searchCode'
],
'ci-ops': [
Expand All @@ -72,17 +76,19 @@ const PRESET_TOOLS: Record<GithubToolPreset, string[]> = {
],
'repo-explorer': [
'getRepository', 'listBranches', 'getFileContent',
'listPullRequests', 'getPullRequest',
'listPullRequests', 'getPullRequest', 'listPullRequestFiles', 'listPullRequestReviews',
'listIssues', 'getIssue',
'listLabels',
'listCommits', 'getCommit', 'getBlame',
'searchCode', 'searchRepositories',
'listGists', 'getGist', 'listGistComments',
'listWorkflows', 'listWorkflowRuns', 'getWorkflowRun', 'listWorkflowJobs'
],
'maintainer': [
'getRepository', 'listBranches', 'getFileContent', 'createBranch', 'forkRepository', 'createRepository', 'createOrUpdateFile',
'listPullRequests', 'getPullRequest', 'createPullRequest', 'mergePullRequest', 'addPullRequestComment',
'listPullRequests', 'getPullRequest', 'listPullRequestFiles', 'listPullRequestReviews', 'createPullRequest', 'mergePullRequest', 'addPullRequestComment', 'createPullRequestReview',
'listIssues', 'getIssue', 'createIssue', 'addIssueComment', 'closeIssue',
'listLabels', 'addLabels', 'removeLabel',
'listCommits', 'getCommit', 'getBlame',
'searchCode', 'searchRepositories',
'listGists', 'getGist', 'listGistComments', 'createGist', 'updateGist', 'deleteGist', 'createGistComment',
Expand Down Expand Up @@ -186,9 +192,15 @@ export function createGithubTools({ token, requireApproval = true, preset }: Git
createPullRequest: createPullRequest(resolvedToken, approval('createPullRequest')),
mergePullRequest: mergePullRequest(resolvedToken, approval('mergePullRequest')),
addPullRequestComment: addPullRequestComment(resolvedToken, approval('addPullRequestComment')),
listPullRequestFiles: listPullRequestFiles(resolvedToken),
listPullRequestReviews: listPullRequestReviews(resolvedToken),
createPullRequestReview: createPullRequestReview(resolvedToken, approval('createPullRequestReview')),
createIssue: createIssue(resolvedToken, approval('createIssue')),
addIssueComment: addIssueComment(resolvedToken, approval('addIssueComment')),
closeIssue: closeIssue(resolvedToken, approval('closeIssue')),
listLabels: listLabels(resolvedToken),
addLabels: addLabels(resolvedToken, approval('addLabels')),
removeLabel: removeLabel(resolvedToken, approval('removeLabel')),
listGists: listGists(resolvedToken),
getGist: getGist(resolvedToken),
listGistComments: listGistComments(resolvedToken),
Expand Down Expand Up @@ -217,8 +229,8 @@ export type GithubTools = ReturnType<typeof createGithubTools>
// Re-export individual tool factories for cherry-picking
export { createOctokit } from './client'
export { getRepository, listBranches, getFileContent, createBranch, forkRepository, createRepository, createOrUpdateFile } from './tools/repository'
export { listPullRequests, getPullRequest, createPullRequest, mergePullRequest, addPullRequestComment } from './tools/pull-requests'
export { listIssues, getIssue, createIssue, addIssueComment, closeIssue } from './tools/issues'
export { listPullRequests, getPullRequest, createPullRequest, mergePullRequest, addPullRequestComment, listPullRequestFiles, listPullRequestReviews, createPullRequestReview } from './tools/pull-requests'
export { listIssues, getIssue, createIssue, addIssueComment, closeIssue, listLabels, addLabels, removeLabel } from './tools/issues'
export { searchCode, searchRepositories } from './tools/search'
export { listCommits, getCommit, getBlame } from './tools/commits'
export { listGists, getGist, listGistComments, createGist, updateGist, deleteGist, createGistComment } from './tools/gists'
Expand Down
Loading
Loading