diff --git a/.changeset/yellow-poets-hide.md b/.changeset/yellow-poets-hide.md new file mode 100644 index 0000000..9a0e04e --- /dev/null +++ b/.changeset/yellow-poets-hide.md @@ -0,0 +1,5 @@ +--- +"@github-tools/sdk": minor +--- + +auto-detech github token from process.env diff --git a/apps/docs/content/docs/1.getting-started/1.introduction.md b/apps/docs/content/docs/1.getting-started/1.introduction.md index 2e8511e..61f97e6 100644 --- a/apps/docs/content/docs/1.getting-started/1.introduction.md +++ b/apps/docs/content/docs/1.getting-started/1.introduction.md @@ -47,7 +47,6 @@ import { createGithubAgent } from '@github-tools/sdk' const reviewer = createGithubAgent({ model: 'anthropic/claude-sonnet-4-6', - token: process.env.GITHUB_TOKEN!, preset: 'code-review', system: 'You review PRs for security issues. Cite file paths and line numbers.', }) diff --git a/apps/docs/content/docs/1.getting-started/2.installation.md b/apps/docs/content/docs/1.getting-started/2.installation.md index 543055f..d5114f8 100644 --- a/apps/docs/content/docs/1.getting-started/2.installation.md +++ b/apps/docs/content/docs/1.getting-started/2.installation.md @@ -53,12 +53,18 @@ bun add ai zod ## Set your GitHub token -Create a `.env` file at the root of your project: +The SDK reads `GITHUB_TOKEN` from your environment automatically. Create a `.env` file at the root of your project: ```bash [.env] GITHUB_TOKEN=github_pat_xxxxxxxxxxxx ``` +You can also pass the token explicitly if you prefer: + +```ts [explicit-token.ts] +createGithubTools({ token: 'github_pat_xxxxxxxxxxxx' }) +``` + ::warning Never commit tokens. Use `.env` locally and secret managers (Vercel, GitHub Actions secrets) in CI/production. :: @@ -79,10 +85,7 @@ Run a minimal script to confirm the SDK initializes and a read tool resolves: ```ts [verify.ts] import { createGithubTools } from '@github-tools/sdk' -const tools = createGithubTools({ - token: process.env.GITHUB_TOKEN!, - preset: 'repo-explorer', -}) +const tools = createGithubTools({ preset: 'repo-explorer' }) console.log('Tools loaded:', Object.keys(tools).join(', ')) ``` diff --git a/apps/docs/content/docs/2.guide/1.quick-start.md b/apps/docs/content/docs/2.guide/1.quick-start.md index db4fabf..5a2b009 100644 --- a/apps/docs/content/docs/2.guide/1.quick-start.md +++ b/apps/docs/content/docs/2.guide/1.quick-start.md @@ -45,14 +45,14 @@ import { openai } from '@ai-sdk/openai' const { text } = await generateText({ model: openai('gpt-4o'), - tools: createGithubTools({ token: process.env.GITHUB_TOKEN! }), + tools: createGithubTools(), prompt: 'List open pull requests on vercel/ai and summarize each one.', }) console.log(text) ``` -This gives the model access to all 18 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 18 tools — see the [Tools Catalog](/api/tools-catalog) for what each one does. ## Narrow tools with a preset @@ -65,10 +65,7 @@ import { anthropic } from '@ai-sdk/anthropic' const result = streamText({ model: anthropic('claude-sonnet-4-6'), - tools: createGithubTools({ - token: process.env.GITHUB_TOKEN!, - preset: 'code-review', - }), + tools: createGithubTools({ preset: 'code-review' }), prompt: 'Review the latest PR on HugoRCD/github-tools for security issues.', }) @@ -88,7 +85,6 @@ import { createGithubAgent } from '@github-tools/sdk' const triager = createGithubAgent({ model: 'anthropic/claude-sonnet-4-6', - token: process.env.GITHUB_TOKEN!, preset: 'issue-triage', system: 'You classify issues as bug, feature, or question. Always post a comment with the classification.', }) diff --git a/apps/docs/content/docs/2.guide/2.presets.md b/apps/docs/content/docs/2.guide/2.presets.md index 0349741..9a92c1b 100644 --- a/apps/docs/content/docs/2.guide/2.presets.md +++ b/apps/docs/content/docs/2.guide/2.presets.md @@ -25,7 +25,6 @@ Use a preset to restrict the tools to a specific capability domain. For example, import { createGithubTools } from '@github-tools/sdk' const tools = createGithubTools({ - token: process.env.GITHUB_TOKEN!, preset: 'code-review', }) ``` @@ -38,7 +37,6 @@ When a workflow spans multiple domains, pass an array. This agent can both revie import { createGithubTools } from '@github-tools/sdk' const tools = createGithubTools({ - token: process.env.GITHUB_TOKEN!, preset: ['code-review', 'issue-triage'], }) ``` diff --git a/apps/docs/content/docs/2.guide/3.approval-control.md b/apps/docs/content/docs/2.guide/3.approval-control.md index bf635c7..518cdc1 100644 --- a/apps/docs/content/docs/2.guide/3.approval-control.md +++ b/apps/docs/content/docs/2.guide/3.approval-control.md @@ -25,8 +25,8 @@ By default, every write operation requires explicit approval. You don't need to import { createGithubTools } from '@github-tools/sdk' const tools = createGithubTools({ - token: process.env.GITHUB_TOKEN!, -}) + }) + ``` ## Disable approval in trusted environments @@ -37,7 +37,6 @@ In CI pipelines or automated workflows where human review happens elsewhere (e.g import { createGithubTools } from '@github-tools/sdk' const tools = createGithubTools({ - token: process.env.GITHUB_TOKEN!, requireApproval: false, }) ``` @@ -50,7 +49,6 @@ For nuanced policies, enable approval selectively. This example approves destruc import { createGithubTools } from '@github-tools/sdk' const tools = createGithubTools({ - token: process.env.GITHUB_TOKEN!, requireApproval: { mergePullRequest: true, createOrUpdateFile: true, diff --git a/apps/docs/content/docs/2.guide/6.examples.md b/apps/docs/content/docs/2.guide/6.examples.md index 75a52b5..ede8b42 100644 --- a/apps/docs/content/docs/2.guide/6.examples.md +++ b/apps/docs/content/docs/2.guide/6.examples.md @@ -27,7 +27,6 @@ import { openai } from '@ai-sdk/openai' const { text } = await generateText({ model: openai('gpt-4o'), tools: createGithubTools({ - token: process.env.GITHUB_TOKEN!, preset: 'code-review', }), prompt: 'List all open pull requests on HugoRCD/github-tools and write a one-line summary for each.', @@ -48,7 +47,6 @@ import { anthropic } from '@ai-sdk/anthropic' const { text } = await generateText({ model: anthropic('claude-sonnet-4-6'), tools: createGithubTools({ - token: process.env.GITHUB_TOKEN!, preset: 'issue-triage', requireApproval: { addIssueComment: false, @@ -73,7 +71,6 @@ import { createGithubAgent } from '@github-tools/sdk' const reviewer = createGithubAgent({ model: 'anthropic/claude-sonnet-4-6', - token: process.env.GITHUB_TOKEN!, preset: 'code-review', system: ` You review pull requests for code quality and security issues. @@ -95,7 +92,6 @@ import { openai } from '@ai-sdk/openai' const result = streamText({ model: openai('gpt-4o'), tools: createGithubTools({ - token: process.env.GITHUB_TOKEN!, preset: 'repo-explorer', }), prompt: 'Find all TypeScript files that export a function named "create" in HugoRCD/github-tools and explain what each one does.', @@ -118,7 +114,6 @@ import { anthropic } from '@ai-sdk/anthropic' const { text } = await generateText({ model: anthropic('claude-sonnet-4-6'), tools: createGithubTools({ - token: process.env.GITHUB_TOKEN!, preset: 'maintainer', requireApproval: true, }), diff --git a/apps/docs/content/docs/3.api/2.reference.md b/apps/docs/content/docs/3.api/2.reference.md index 35ee4c3..b36c56a 100644 --- a/apps/docs/content/docs/3.api/2.reference.md +++ b/apps/docs/content/docs/3.api/2.reference.md @@ -15,13 +15,13 @@ links: variant: subtle --- -## `createGithubTools(options)` +## `createGithubTools(options?)` -Returns a record of AI SDK tools you can pass to `generateText` or `streamText`: +Returns a record of AI SDK tools you can pass to `generateText` or `streamText`. All options are optional — the SDK reads `GITHUB_TOKEN` from your environment by default: ```ts [types.ts] type GithubToolsOptions = { - token: string + token?: string requireApproval?: boolean | Partial> preset?: GithubToolPreset | GithubToolPreset[] } @@ -33,13 +33,21 @@ type GithubToolPreset = | 'maintainer' ``` -Minimal usage with a single preset: +Minimal usage — reads `GITHUB_TOKEN` automatically: -```ts [usage.ts] +```ts [minimal.ts] +import { createGithubTools } from '@github-tools/sdk' + +const tools = createGithubTools() +``` + +With a preset and explicit token: + +```ts [with-options.ts] import { createGithubTools } from '@github-tools/sdk' const tools = createGithubTools({ - token: process.env.GITHUB_TOKEN!, + token: 'github_pat_xxxxxxxxxxxx', preset: 'repo-explorer', }) ``` @@ -48,12 +56,12 @@ See [Scope with presets](/guide/presets) for preset details and [Control write s ## `createGithubAgent(options)` -Returns a `ToolLoopAgent` with GitHub tools and system instructions pre-configured: +Returns a `ToolLoopAgent` with GitHub tools and system instructions pre-configured. The token is also auto-detected from `GITHUB_TOKEN`: ```ts [types.ts] type GithubAgentOptions = { model: string - token: string + token?: string preset?: GithubToolPreset | GithubToolPreset[] requireApproval?: boolean | Partial> system?: string @@ -71,20 +79,19 @@ import { createGithubAgent } from '@github-tools/sdk' const agent = createGithubAgent({ model: 'anthropic/claude-sonnet-4-6', - token: process.env.GITHUB_TOKEN!, preset: 'code-review', system: 'You review PRs for security issues. Cite file paths and line numbers.', }) ``` -## `createOctokit(token)` +## `createOctokit(token?)` Returns a configured [`@octokit/rest`](https://github.com/octokit/rest.js) instance. Use this when you need lower-level GitHub API access or want to build custom tool factories: ```ts [custom-tool.ts] import { createOctokit } from '@github-tools/sdk' -const octokit = createOctokit(process.env.GITHUB_TOKEN!) +const octokit = createOctokit() const { data } = await octokit.repos.get({ owner: 'HugoRCD', repo: 'github-tools' }) ``` diff --git a/packages/github-tools/src/agents.ts b/packages/github-tools/src/agents.ts index 5903776..afe98df 100644 --- a/packages/github-tools/src/agents.ts +++ b/packages/github-tools/src/agents.ts @@ -59,7 +59,11 @@ type AgentOptions = Omit = { } export type GithubToolsOptions = { - token: string + /** + * GitHub personal access token. + * Falls back to `process.env.GITHUB_TOKEN` when omitted. + */ + token?: string requireApproval?: ApprovalConfig /** * Restrict the returned tools to a predefined preset. @@ -132,8 +136,12 @@ function resolvePresetTools(preset: GithubToolPreset | GithubToolPreset[]): Set< * }) * ``` */ -export function createGithubTools({ token, requireApproval = true, preset }: GithubToolsOptions) { - const octokit = createOctokit(token) +export function createGithubTools({ token, requireApproval = true, preset }: GithubToolsOptions = {}) { + const resolvedToken = token || process.env.GITHUB_TOKEN + if (!resolvedToken) { + throw new Error('GitHub token is required. Pass it as `token` or set the GITHUB_TOKEN environment variable.') + } + const octokit = createOctokit(resolvedToken) const approval = (name: GithubWriteToolName) => ({ needsApproval: resolveApproval(name, requireApproval) }) const allowed = preset ? resolvePresetTools(preset) : null