From f9af9fc22184c5e4a62a18a2df6746d6a1945264 Mon Sep 17 00:00:00 2001 From: opencode Date: Tue, 4 Nov 2025 17:47:34 +0000 Subject: release: v1.0.21 --- packages/plugin/package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'packages/plugin') diff --git a/packages/plugin/package.json b/packages/plugin/package.json index 897931489..14aa24058 100644 --- a/packages/plugin/package.json +++ b/packages/plugin/package.json @@ -1,7 +1,7 @@ { "$schema": "https://json.schemastore.org/package.json", "name": "@opencode-ai/plugin", - "version": "1.0.20", + "version": "1.0.21", "type": "module", "scripts": { "typecheck": "tsgo --noEmit", -- cgit v1.2.3 From 434c0ff0d7f7e6f453d3c51560d16bc91e473ca8 Mon Sep 17 00:00:00 2001 From: opencode Date: Tue, 4 Nov 2025 18:41:38 +0000 Subject: release: v1.0.22 --- bun.lock | 22 +++++++++++----------- packages/console/app/package.json | 2 +- packages/console/core/package.json | 2 +- packages/console/function/package.json | 2 +- packages/console/mail/package.json | 2 +- packages/desktop/package.json | 2 +- packages/function/package.json | 2 +- packages/opencode/package.json | 2 +- packages/plugin/package.json | 2 +- packages/sdk/js/package.json | 2 +- packages/slack/package.json | 2 +- packages/ui/package.json | 2 +- packages/web/package.json | 2 +- sdks/vscode/package.json | 2 +- 14 files changed, 24 insertions(+), 24 deletions(-) (limited to 'packages/plugin') diff --git a/bun.lock b/bun.lock index 34a21d6a2..92b77a60a 100644 --- a/bun.lock +++ b/bun.lock @@ -39,7 +39,7 @@ }, "packages/console/core": { "name": "@opencode-ai/console-core", - "version": "1.0.21", + "version": "1.0.22", "dependencies": { "@aws-sdk/client-sts": "3.782.0", "@jsx-email/render": "1.1.1", @@ -66,7 +66,7 @@ }, "packages/console/function": { "name": "@opencode-ai/console-function", - "version": "1.0.21", + "version": "1.0.22", "dependencies": { "@ai-sdk/anthropic": "2.0.0", "@ai-sdk/openai": "2.0.2", @@ -90,7 +90,7 @@ }, "packages/console/mail": { "name": "@opencode-ai/console-mail", - "version": "1.0.21", + "version": "1.0.22", "dependencies": { "@jsx-email/all": "2.2.3", "@jsx-email/cli": "1.4.3", @@ -111,7 +111,7 @@ }, "packages/desktop": { "name": "@opencode-ai/desktop", - "version": "1.0.21", + "version": "1.0.22", "dependencies": { "@kobalte/core": "catalog:", "@opencode-ai/sdk": "workspace:*", @@ -150,7 +150,7 @@ }, "packages/function": { "name": "@opencode-ai/function", - "version": "1.0.21", + "version": "1.0.22", "dependencies": { "@octokit/auth-app": "8.0.1", "@octokit/rest": "22.0.0", @@ -166,7 +166,7 @@ }, "packages/opencode": { "name": "opencode", - "version": "1.0.21", + "version": "1.0.22", "bin": { "opencode": "./bin/opencode", }, @@ -243,7 +243,7 @@ }, "packages/plugin": { "name": "@opencode-ai/plugin", - "version": "1.0.21", + "version": "1.0.22", "dependencies": { "@opencode-ai/sdk": "workspace:*", "zod": "catalog:", @@ -263,7 +263,7 @@ }, "packages/sdk/js": { "name": "@opencode-ai/sdk", - "version": "1.0.21", + "version": "1.0.22", "devDependencies": { "@hey-api/openapi-ts": "0.81.0", "@tsconfig/node22": "catalog:", @@ -274,7 +274,7 @@ }, "packages/slack": { "name": "@opencode-ai/slack", - "version": "1.0.21", + "version": "1.0.22", "dependencies": { "@opencode-ai/sdk": "workspace:*", "@slack/bolt": "^3.17.1", @@ -287,7 +287,7 @@ }, "packages/ui": { "name": "@opencode-ai/ui", - "version": "1.0.21", + "version": "1.0.22", "dependencies": { "@kobalte/core": "catalog:", "@opencode-ai/sdk": "workspace:*", @@ -317,7 +317,7 @@ }, "packages/web": { "name": "@opencode-ai/web", - "version": "1.0.21", + "version": "1.0.22", "dependencies": { "@astrojs/cloudflare": "12.6.3", "@astrojs/markdown-remark": "6.3.1", diff --git a/packages/console/app/package.json b/packages/console/app/package.json index cb14e6481..75af91691 100644 --- a/packages/console/app/package.json +++ b/packages/console/app/package.json @@ -7,7 +7,7 @@ "dev:remote": "VITE_AUTH_URL=https://auth.dev.opencode.ai bun sst shell --stage=dev bun dev", "build": "vinxi build && ../../opencode/script/schema.ts ./.output/public/config.json", "start": "vinxi start", - "version": "1.0.21" + "version": "1.0.22" }, "dependencies": { "@ibm/plex": "6.4.1", diff --git a/packages/console/core/package.json b/packages/console/core/package.json index 477a55491..b5dad7341 100644 --- a/packages/console/core/package.json +++ b/packages/console/core/package.json @@ -1,7 +1,7 @@ { "$schema": "https://json.schemastore.org/package.json", "name": "@opencode-ai/console-core", - "version": "1.0.21", + "version": "1.0.22", "private": true, "type": "module", "dependencies": { diff --git a/packages/console/function/package.json b/packages/console/function/package.json index 9cae8d9fe..f71330676 100644 --- a/packages/console/function/package.json +++ b/packages/console/function/package.json @@ -1,6 +1,6 @@ { "name": "@opencode-ai/console-function", - "version": "1.0.21", + "version": "1.0.22", "$schema": "https://json.schemastore.org/package.json", "private": true, "type": "module", diff --git a/packages/console/mail/package.json b/packages/console/mail/package.json index 2e1943c2a..3e84e2ca8 100644 --- a/packages/console/mail/package.json +++ b/packages/console/mail/package.json @@ -1,6 +1,6 @@ { "name": "@opencode-ai/console-mail", - "version": "1.0.21", + "version": "1.0.22", "dependencies": { "@jsx-email/all": "2.2.3", "@jsx-email/cli": "1.4.3", diff --git a/packages/desktop/package.json b/packages/desktop/package.json index 23f2a7349..2c6897232 100644 --- a/packages/desktop/package.json +++ b/packages/desktop/package.json @@ -1,6 +1,6 @@ { "name": "@opencode-ai/desktop", - "version": "1.0.21", + "version": "1.0.22", "description": "", "type": "module", "scripts": { diff --git a/packages/function/package.json b/packages/function/package.json index 7129dbab0..bb223e3eb 100644 --- a/packages/function/package.json +++ b/packages/function/package.json @@ -1,6 +1,6 @@ { "name": "@opencode-ai/function", - "version": "1.0.21", + "version": "1.0.22", "$schema": "https://json.schemastore.org/package.json", "private": true, "type": "module", diff --git a/packages/opencode/package.json b/packages/opencode/package.json index 2e97b6dea..b050e7ab9 100644 --- a/packages/opencode/package.json +++ b/packages/opencode/package.json @@ -1,6 +1,6 @@ { "$schema": "https://json.schemastore.org/package.json", - "version": "1.0.21", + "version": "1.0.22", "name": "opencode", "type": "module", "private": true, diff --git a/packages/plugin/package.json b/packages/plugin/package.json index 14aa24058..85fee69b6 100644 --- a/packages/plugin/package.json +++ b/packages/plugin/package.json @@ -1,7 +1,7 @@ { "$schema": "https://json.schemastore.org/package.json", "name": "@opencode-ai/plugin", - "version": "1.0.21", + "version": "1.0.22", "type": "module", "scripts": { "typecheck": "tsgo --noEmit", diff --git a/packages/sdk/js/package.json b/packages/sdk/js/package.json index b0dc34c1c..1931dff22 100644 --- a/packages/sdk/js/package.json +++ b/packages/sdk/js/package.json @@ -1,7 +1,7 @@ { "$schema": "https://json.schemastore.org/package.json", "name": "@opencode-ai/sdk", - "version": "1.0.21", + "version": "1.0.22", "type": "module", "scripts": { "typecheck": "tsgo --noEmit", diff --git a/packages/slack/package.json b/packages/slack/package.json index 76f3dea82..a38cdd106 100644 --- a/packages/slack/package.json +++ b/packages/slack/package.json @@ -1,6 +1,6 @@ { "name": "@opencode-ai/slack", - "version": "1.0.21", + "version": "1.0.22", "type": "module", "scripts": { "dev": "bun run src/index.ts", diff --git a/packages/ui/package.json b/packages/ui/package.json index 7cfd1e78a..38b28deb5 100644 --- a/packages/ui/package.json +++ b/packages/ui/package.json @@ -1,6 +1,6 @@ { "name": "@opencode-ai/ui", - "version": "1.0.21", + "version": "1.0.22", "type": "module", "exports": { ".": "./src/components/index.ts", diff --git a/packages/web/package.json b/packages/web/package.json index fe654df91..39335a007 100644 --- a/packages/web/package.json +++ b/packages/web/package.json @@ -1,7 +1,7 @@ { "name": "@opencode-ai/web", "type": "module", - "version": "1.0.21", + "version": "1.0.22", "scripts": { "dev": "astro dev", "dev:remote": "VITE_API_URL=https://api.opencode.ai astro dev", diff --git a/sdks/vscode/package.json b/sdks/vscode/package.json index 7557f4c0a..7d29958fa 100644 --- a/sdks/vscode/package.json +++ b/sdks/vscode/package.json @@ -2,7 +2,7 @@ "name": "opencode", "displayName": "opencode", "description": "opencode for VS Code", - "version": "1.0.21", + "version": "1.0.22", "publisher": "sst-dev", "repository": { "type": "git", -- cgit v1.2.3 From ba8bc1b8b488e10eec8c0b915a753f4810164343 Mon Sep 17 00:00:00 2001 From: opencode Date: Tue, 4 Nov 2025 19:38:18 +0000 Subject: release: v1.0.23 --- bun.lock | 22 +++++++++++----------- packages/console/app/package.json | 2 +- packages/console/core/package.json | 2 +- packages/console/function/package.json | 2 +- packages/console/mail/package.json | 2 +- packages/desktop/package.json | 2 +- packages/function/package.json | 2 +- packages/opencode/package.json | 2 +- packages/plugin/package.json | 2 +- packages/sdk/js/package.json | 2 +- packages/slack/package.json | 2 +- packages/ui/package.json | 2 +- packages/web/package.json | 2 +- sdks/vscode/package.json | 2 +- 14 files changed, 24 insertions(+), 24 deletions(-) (limited to 'packages/plugin') diff --git a/bun.lock b/bun.lock index 92b77a60a..e18ad9507 100644 --- a/bun.lock +++ b/bun.lock @@ -39,7 +39,7 @@ }, "packages/console/core": { "name": "@opencode-ai/console-core", - "version": "1.0.22", + "version": "1.0.23", "dependencies": { "@aws-sdk/client-sts": "3.782.0", "@jsx-email/render": "1.1.1", @@ -66,7 +66,7 @@ }, "packages/console/function": { "name": "@opencode-ai/console-function", - "version": "1.0.22", + "version": "1.0.23", "dependencies": { "@ai-sdk/anthropic": "2.0.0", "@ai-sdk/openai": "2.0.2", @@ -90,7 +90,7 @@ }, "packages/console/mail": { "name": "@opencode-ai/console-mail", - "version": "1.0.22", + "version": "1.0.23", "dependencies": { "@jsx-email/all": "2.2.3", "@jsx-email/cli": "1.4.3", @@ -111,7 +111,7 @@ }, "packages/desktop": { "name": "@opencode-ai/desktop", - "version": "1.0.22", + "version": "1.0.23", "dependencies": { "@kobalte/core": "catalog:", "@opencode-ai/sdk": "workspace:*", @@ -150,7 +150,7 @@ }, "packages/function": { "name": "@opencode-ai/function", - "version": "1.0.22", + "version": "1.0.23", "dependencies": { "@octokit/auth-app": "8.0.1", "@octokit/rest": "22.0.0", @@ -166,7 +166,7 @@ }, "packages/opencode": { "name": "opencode", - "version": "1.0.22", + "version": "1.0.23", "bin": { "opencode": "./bin/opencode", }, @@ -243,7 +243,7 @@ }, "packages/plugin": { "name": "@opencode-ai/plugin", - "version": "1.0.22", + "version": "1.0.23", "dependencies": { "@opencode-ai/sdk": "workspace:*", "zod": "catalog:", @@ -263,7 +263,7 @@ }, "packages/sdk/js": { "name": "@opencode-ai/sdk", - "version": "1.0.22", + "version": "1.0.23", "devDependencies": { "@hey-api/openapi-ts": "0.81.0", "@tsconfig/node22": "catalog:", @@ -274,7 +274,7 @@ }, "packages/slack": { "name": "@opencode-ai/slack", - "version": "1.0.22", + "version": "1.0.23", "dependencies": { "@opencode-ai/sdk": "workspace:*", "@slack/bolt": "^3.17.1", @@ -287,7 +287,7 @@ }, "packages/ui": { "name": "@opencode-ai/ui", - "version": "1.0.22", + "version": "1.0.23", "dependencies": { "@kobalte/core": "catalog:", "@opencode-ai/sdk": "workspace:*", @@ -317,7 +317,7 @@ }, "packages/web": { "name": "@opencode-ai/web", - "version": "1.0.22", + "version": "1.0.23", "dependencies": { "@astrojs/cloudflare": "12.6.3", "@astrojs/markdown-remark": "6.3.1", diff --git a/packages/console/app/package.json b/packages/console/app/package.json index 75af91691..7e06d8248 100644 --- a/packages/console/app/package.json +++ b/packages/console/app/package.json @@ -7,7 +7,7 @@ "dev:remote": "VITE_AUTH_URL=https://auth.dev.opencode.ai bun sst shell --stage=dev bun dev", "build": "vinxi build && ../../opencode/script/schema.ts ./.output/public/config.json", "start": "vinxi start", - "version": "1.0.22" + "version": "1.0.23" }, "dependencies": { "@ibm/plex": "6.4.1", diff --git a/packages/console/core/package.json b/packages/console/core/package.json index b5dad7341..c1ab23476 100644 --- a/packages/console/core/package.json +++ b/packages/console/core/package.json @@ -1,7 +1,7 @@ { "$schema": "https://json.schemastore.org/package.json", "name": "@opencode-ai/console-core", - "version": "1.0.22", + "version": "1.0.23", "private": true, "type": "module", "dependencies": { diff --git a/packages/console/function/package.json b/packages/console/function/package.json index f71330676..0c6e02886 100644 --- a/packages/console/function/package.json +++ b/packages/console/function/package.json @@ -1,6 +1,6 @@ { "name": "@opencode-ai/console-function", - "version": "1.0.22", + "version": "1.0.23", "$schema": "https://json.schemastore.org/package.json", "private": true, "type": "module", diff --git a/packages/console/mail/package.json b/packages/console/mail/package.json index 3e84e2ca8..30e772b6b 100644 --- a/packages/console/mail/package.json +++ b/packages/console/mail/package.json @@ -1,6 +1,6 @@ { "name": "@opencode-ai/console-mail", - "version": "1.0.22", + "version": "1.0.23", "dependencies": { "@jsx-email/all": "2.2.3", "@jsx-email/cli": "1.4.3", diff --git a/packages/desktop/package.json b/packages/desktop/package.json index 2c6897232..341884453 100644 --- a/packages/desktop/package.json +++ b/packages/desktop/package.json @@ -1,6 +1,6 @@ { "name": "@opencode-ai/desktop", - "version": "1.0.22", + "version": "1.0.23", "description": "", "type": "module", "scripts": { diff --git a/packages/function/package.json b/packages/function/package.json index bb223e3eb..eeb842ca3 100644 --- a/packages/function/package.json +++ b/packages/function/package.json @@ -1,6 +1,6 @@ { "name": "@opencode-ai/function", - "version": "1.0.22", + "version": "1.0.23", "$schema": "https://json.schemastore.org/package.json", "private": true, "type": "module", diff --git a/packages/opencode/package.json b/packages/opencode/package.json index b050e7ab9..3e4f5c02c 100644 --- a/packages/opencode/package.json +++ b/packages/opencode/package.json @@ -1,6 +1,6 @@ { "$schema": "https://json.schemastore.org/package.json", - "version": "1.0.22", + "version": "1.0.23", "name": "opencode", "type": "module", "private": true, diff --git a/packages/plugin/package.json b/packages/plugin/package.json index 85fee69b6..0ad4afe63 100644 --- a/packages/plugin/package.json +++ b/packages/plugin/package.json @@ -1,7 +1,7 @@ { "$schema": "https://json.schemastore.org/package.json", "name": "@opencode-ai/plugin", - "version": "1.0.22", + "version": "1.0.23", "type": "module", "scripts": { "typecheck": "tsgo --noEmit", diff --git a/packages/sdk/js/package.json b/packages/sdk/js/package.json index 1931dff22..d4de9ca17 100644 --- a/packages/sdk/js/package.json +++ b/packages/sdk/js/package.json @@ -1,7 +1,7 @@ { "$schema": "https://json.schemastore.org/package.json", "name": "@opencode-ai/sdk", - "version": "1.0.22", + "version": "1.0.23", "type": "module", "scripts": { "typecheck": "tsgo --noEmit", diff --git a/packages/slack/package.json b/packages/slack/package.json index a38cdd106..f9392ef37 100644 --- a/packages/slack/package.json +++ b/packages/slack/package.json @@ -1,6 +1,6 @@ { "name": "@opencode-ai/slack", - "version": "1.0.22", + "version": "1.0.23", "type": "module", "scripts": { "dev": "bun run src/index.ts", diff --git a/packages/ui/package.json b/packages/ui/package.json index 38b28deb5..585a249b0 100644 --- a/packages/ui/package.json +++ b/packages/ui/package.json @@ -1,6 +1,6 @@ { "name": "@opencode-ai/ui", - "version": "1.0.22", + "version": "1.0.23", "type": "module", "exports": { ".": "./src/components/index.ts", diff --git a/packages/web/package.json b/packages/web/package.json index 39335a007..2de696b3e 100644 --- a/packages/web/package.json +++ b/packages/web/package.json @@ -1,7 +1,7 @@ { "name": "@opencode-ai/web", "type": "module", - "version": "1.0.22", + "version": "1.0.23", "scripts": { "dev": "astro dev", "dev:remote": "VITE_API_URL=https://api.opencode.ai astro dev", diff --git a/sdks/vscode/package.json b/sdks/vscode/package.json index 7d29958fa..6a8ed497a 100644 --- a/sdks/vscode/package.json +++ b/sdks/vscode/package.json @@ -2,7 +2,7 @@ "name": "opencode", "displayName": "opencode", "description": "opencode for VS Code", - "version": "1.0.22", + "version": "1.0.23", "publisher": "sst-dev", "repository": { "type": "git", -- cgit v1.2.3 From fe94bb8e50ed9625e553cc7bd79d3a02889c2979 Mon Sep 17 00:00:00 2001 From: Ola <74724224+OlaHulleberg@users.noreply.github.com> Date: Tue, 4 Nov 2025 22:36:12 +0100 Subject: feat(provider): add GitHub Enterprise support for Copilot (#2522) Co-authored-by: Jon-Mikkel Korsvik <48263282+jkorsvik@users.noreply.github.com> Co-authored-by: GitHub Action Co-authored-by: Aiden Cline --- packages/opencode/src/auth/index.ts | 1 + packages/opencode/src/cli/cmd/auth.ts | 341 ++++++++++++++++------------- packages/opencode/src/config/config.ts | 1 + packages/opencode/src/plugin/index.ts | 2 +- packages/opencode/src/provider/provider.ts | 60 ++++- packages/plugin/src/index.ts | 61 +++++- packages/sdk/js/src/gen/types.gen.ts | 5 + 7 files changed, 312 insertions(+), 159 deletions(-) (limited to 'packages/plugin') diff --git a/packages/opencode/src/auth/index.ts b/packages/opencode/src/auth/index.ts index 6d90c9325..883b9acc6 100644 --- a/packages/opencode/src/auth/index.ts +++ b/packages/opencode/src/auth/index.ts @@ -10,6 +10,7 @@ export namespace Auth { refresh: z.string(), access: z.string(), expires: z.number(), + enterpriseUrl: z.string().optional(), }) .meta({ ref: "OAuth" }) diff --git a/packages/opencode/src/cli/cmd/auth.ts b/packages/opencode/src/cli/cmd/auth.ts index 763d82b3f..aa833e977 100644 --- a/packages/opencode/src/cli/cmd/auth.ts +++ b/packages/opencode/src/cli/cmd/auth.ts @@ -102,178 +102,223 @@ export const AuthLoginCommand = cmd({ prompts.outro("Done") return } - await ModelsDev.refresh().catch(() => {}) - const providers = await ModelsDev.get() - const priority: Record = { - opencode: 0, - anthropic: 1, - "github-copilot": 2, - openai: 3, - google: 4, - openrouter: 5, - vercel: 6, - } - let provider = await prompts.autocomplete({ - message: "Select provider", - maxItems: 8, - options: [ - ...pipe( - providers, - values(), - sortBy( - (x) => priority[x.id] ?? 99, - (x) => x.name ?? x.id, - ), - map((x) => ({ - label: x.name, - value: x.id, - hint: priority[x.id] <= 1 ? "recommended" : undefined, - })), + await ModelsDev.refresh().catch(() => {}) + const providers = await ModelsDev.get() + const priority: Record = { + opencode: 0, + anthropic: 1, + "github-copilot": 2, + openai: 3, + google: 4, + openrouter: 5, + vercel: 6, + } + let provider = await prompts.autocomplete({ + message: "Select provider", + maxItems: 8, + options: [ + ...pipe( + providers, + values(), + sortBy( + (x) => priority[x.id] ?? 99, + (x) => x.name ?? x.id, ), - { - value: "other", - label: "Other", - }, - ], - }) + map((x) => ({ + label: x.name, + value: x.id, + hint: priority[x.id] <= 1 ? "recommended" : undefined, + })), + ), + { + value: "other", + label: "Other", + }, + ], + }) - if (prompts.isCancel(provider)) throw new UI.CancelledError() + if (prompts.isCancel(provider)) throw new UI.CancelledError() - const plugin = await Plugin.list().then((x) => x.find((x) => x.auth?.provider === provider)) - if (plugin && plugin.auth) { - let index = 0 - if (plugin.auth.methods.length > 1) { - const method = await prompts.select({ - message: "Login method", - options: [ - ...plugin.auth.methods.map((x, index) => ({ - label: x.label, - value: index.toString(), - })), - ], - }) - if (prompts.isCancel(method)) throw new UI.CancelledError() - index = parseInt(method) - } - const method = plugin.auth.methods[index] - if (method.type === "oauth") { - await new Promise((resolve) => setTimeout(resolve, 10)) - const authorize = await method.authorize() + const plugin = await Plugin.list().then((x) => x.find((x) => x.auth?.provider === provider)) + if (plugin && plugin.auth) { + let index = 0 + if (plugin.auth.methods.length > 1) { + const method = await prompts.select({ + message: "Login method", + options: [ + ...plugin.auth.methods.map((x, index) => ({ + label: x.label, + value: index.toString(), + })), + ], + }) + if (prompts.isCancel(method)) throw new UI.CancelledError() + index = parseInt(method) + } + const method = plugin.auth.methods[index] - if (authorize.url) { - prompts.log.info("Go to: " + authorize.url) + // Handle prompts for all auth types + await new Promise((resolve) => setTimeout(resolve, 10)) + const inputs: Record = {} + if (method.prompts) { + for (const prompt of method.prompts) { + if (prompt.condition && !prompt.condition(inputs)) { + continue } + if (prompt.type === "select") { + const value = await prompts.select({ + message: prompt.message, + options: prompt.options, + }) + if (prompts.isCancel(value)) throw new UI.CancelledError() + inputs[prompt.key] = value + } else { + const value = await prompts.text({ + message: prompt.message, + placeholder: prompt.placeholder, + validate: prompt.validate ? (v) => prompt.validate!(v ?? "") : undefined, + }) + if (prompts.isCancel(value)) throw new UI.CancelledError() + inputs[prompt.key] = value + } + } + } - if (authorize.method === "auto") { - if (authorize.instructions) { - prompts.log.info(authorize.instructions) - } - const spinner = prompts.spinner() - spinner.start("Waiting for authorization...") - const result = await authorize.callback() - if (result.type === "failed") { - spinner.stop("Failed to authorize", 1) + if (method.type === "oauth") { + const authorize = await method.authorize(inputs) + + if (authorize.url) { + prompts.log.info("Go to: " + authorize.url) + } + + if (authorize.method === "auto") { + if (authorize.instructions) { + prompts.log.info(authorize.instructions) + } + const spinner = prompts.spinner() + spinner.start("Waiting for authorization...") + const result = await authorize.callback() + if (result.type === "failed") { + spinner.stop("Failed to authorize", 1) + } + if (result.type === "success") { + const saveProvider = result.provider ?? provider + if ("refresh" in result) { + const { type: _, provider: __, refresh, access, expires, ...extraFields } = result + await Auth.set(saveProvider, { + type: "oauth", + refresh, + access, + expires, + ...extraFields, + }) } - if (result.type === "success") { - if ("refresh" in result) { - await Auth.set(provider, { - type: "oauth", - refresh: result.refresh, - access: result.access, - expires: result.expires, - }) - } - if ("key" in result) { - await Auth.set(provider, { - type: "api", - key: result.key, - }) - } - spinner.stop("Login successful") + if ("key" in result) { + await Auth.set(saveProvider, { + type: "api", + key: result.key, + }) } + spinner.stop("Login successful") } + } - if (authorize.method === "code") { - const code = await prompts.text({ - message: "Paste the authorization code here: ", - validate: (x) => (x && x.length > 0 ? undefined : "Required"), - }) - if (prompts.isCancel(code)) throw new UI.CancelledError() - const result = await authorize.callback(code) - if (result.type === "failed") { - prompts.log.error("Failed to authorize") + if (authorize.method === "code") { + const code = await prompts.text({ + message: "Paste the authorization code here: ", + validate: (x) => (x && x.length > 0 ? undefined : "Required"), + }) + if (prompts.isCancel(code)) throw new UI.CancelledError() + const result = await authorize.callback(code) + if (result.type === "failed") { + prompts.log.error("Failed to authorize") + } + if (result.type === "success") { + const saveProvider = result.provider ?? provider + if ("refresh" in result) { + const { type: _, provider: __, refresh, access, expires, ...extraFields } = result + await Auth.set(saveProvider, { + type: "oauth", + refresh, + access, + expires, + ...extraFields, + }) } - if (result.type === "success") { - if ("refresh" in result) { - await Auth.set(provider, { - type: "oauth", - refresh: result.refresh, - access: result.access, - expires: result.expires, - }) - } - if ("key" in result) { - await Auth.set(provider, { - type: "api", - key: result.key, - }) - } - prompts.log.success("Login successful") + if ("key" in result) { + await Auth.set(saveProvider, { + type: "api", + key: result.key, + }) } + prompts.log.success("Login successful") } - prompts.outro("Done") - return } - } - if (provider === "other") { - provider = await prompts.text({ - message: "Enter provider id", - validate: (x) => (x && x.match(/^[0-9a-z-]+$/) ? undefined : "a-z, 0-9 and hyphens only"), - }) - if (prompts.isCancel(provider)) throw new UI.CancelledError() - provider = provider.replace(/^@ai-sdk\//, "") - if (prompts.isCancel(provider)) throw new UI.CancelledError() - prompts.log.warn( - `This only stores a credential for ${provider} - you will need configure it in opencode.json, check the docs for examples.`, - ) - } - - if (provider === "amazon-bedrock") { - prompts.log.info( - "Amazon bedrock can be configured with standard AWS environment variables like AWS_BEARER_TOKEN_BEDROCK, AWS_PROFILE or AWS_ACCESS_KEY_ID", - ) - prompts.outro("Done") - return - } - - if (provider === "google-vertex") { - prompts.log.info( - "Google Cloud Vertex AI uses Application Default Credentials. Set GOOGLE_APPLICATION_CREDENTIALS or run 'gcloud auth application-default login'. Optionally set GOOGLE_CLOUD_PROJECT and GOOGLE_CLOUD_LOCATION (or VERTEX_LOCATION)", - ) prompts.outro("Done") return } - if (provider === "opencode") { - prompts.log.info("Create an api key at https://opencode.ai/auth") - } - - if (provider === "vercel") { - prompts.log.info("You can create an api key at https://vercel.link/ai-gateway-token") + if (method.type === "api") { + if (method.authorize) { + const result = await method.authorize(inputs) + if (result.type === "failed") { + prompts.log.error("Failed to authorize") + } + if (result.type === "success") { + const saveProvider = result.provider ?? provider + await Auth.set(saveProvider, { + type: "api", + key: result.key, + }) + prompts.log.success("Login successful") + } + prompts.outro("Done") + return + } } + } - const key = await prompts.password({ - message: "Enter your API key", - validate: (x) => (x && x.length > 0 ? undefined : "Required"), - }) - if (prompts.isCancel(key)) throw new UI.CancelledError() - await Auth.set(provider, { - type: "api", - key, + if (provider === "other") { + provider = await prompts.text({ + message: "Enter provider id", + validate: (x) => (x && x.match(/^[0-9a-z-]+$/) ? undefined : "a-z, 0-9 and hyphens only"), }) + if (prompts.isCancel(provider)) throw new UI.CancelledError() + provider = provider.replace(/^@ai-sdk\//, "") + if (prompts.isCancel(provider)) throw new UI.CancelledError() + prompts.log.warn( + `This only stores a credential for ${provider} - you will need configure it in opencode.json, check the docs for examples.`, + ) + } + if (provider === "amazon-bedrock") { + prompts.log.info( + "Amazon bedrock can be configured with standard AWS environment variables like AWS_BEARER_TOKEN_BEDROCK, AWS_PROFILE or AWS_ACCESS_KEY_ID", + ) prompts.outro("Done") + return + } + + if (provider === "opencode") { + prompts.log.info("Create an api key at https://opencode.ai/auth") + } + + if (provider === "vercel") { + prompts.log.info("You can create an api key at https://vercel.link/ai-gateway-token") + } + + const key = await prompts.password({ + message: "Enter your API key", + validate: (x) => (x && x.length > 0 ? undefined : "Required"), + }) + if (prompts.isCancel(key)) throw new UI.CancelledError() + await Auth.set(provider, { + type: "api", + key, + }) + + prompts.outro("Done") }, }) }, diff --git a/packages/opencode/src/config/config.ts b/packages/opencode/src/config/config.ts index 63a956fb3..efd31ccba 100644 --- a/packages/opencode/src/config/config.ts +++ b/packages/opencode/src/config/config.ts @@ -574,6 +574,7 @@ export namespace Config { .object({ apiKey: z.string().optional(), baseURL: z.string().optional(), + enterpriseUrl: z.string().optional().describe("GitHub Enterprise URL for copilot authentication"), timeout: z .union([ z diff --git a/packages/opencode/src/plugin/index.ts b/packages/opencode/src/plugin/index.ts index 1d433628d..a3d8d6c0e 100644 --- a/packages/opencode/src/plugin/index.ts +++ b/packages/opencode/src/plugin/index.ts @@ -28,7 +28,7 @@ export namespace Plugin { } const plugins = [...(config.plugin ?? [])] if (!Flag.OPENCODE_DISABLE_DEFAULT_PLUGINS) { - plugins.push("opencode-copilot-auth@0.0.3") + plugins.push("opencode-copilot-auth@0.0.4") plugins.push("opencode-anthropic-auth@0.0.2") } for (let plugin of plugins) { diff --git a/packages/opencode/src/provider/provider.ts b/packages/opencode/src/provider/provider.ts index 730ba3963..3be091df8 100644 --- a/packages/opencode/src/provider/provider.ts +++ b/packages/opencode/src/provider/provider.ts @@ -283,6 +283,18 @@ export namespace Provider { const configProviders = Object.entries(config.provider ?? {}) + // Add GitHub Copilot Enterprise provider that inherits from GitHub Copilot + if (database["github-copilot"]) { + const githubCopilot = database["github-copilot"] + database["github-copilot-enterprise"] = { + ...githubCopilot, + id: "github-copilot-enterprise", + name: "GitHub Copilot Enterprise", + // Enterprise uses a different API endpoint - will be set dynamically based on auth + api: undefined, + } + } + for (const [providerID, provider] of configProviders) { const existing = database[providerID] const parsed: ModelsDev.Provider = { @@ -378,14 +390,44 @@ export namespace Provider { if (!plugin.auth) continue const providerID = plugin.auth.provider if (disabled.has(providerID)) continue + + // For github-copilot plugin, check if auth exists for either github-copilot or github-copilot-enterprise + let hasAuth = false const auth = await Auth.get(providerID) - if (!auth) continue + if (auth) hasAuth = true + + // Special handling for github-copilot: also check for enterprise auth + if (providerID === "github-copilot" && !hasAuth) { + const enterpriseAuth = await Auth.get("github-copilot-enterprise") + if (enterpriseAuth) hasAuth = true + } + + if (!hasAuth) continue if (!plugin.auth.loader) continue - const options = await plugin.auth.loader( - () => Auth.get(providerID) as any, - database[plugin.auth.provider], - ) - mergeProvider(plugin.auth.provider, options ?? {}, "custom") + + // Load for the main provider if auth exists + if (auth) { + const options = await plugin.auth.loader( + () => Auth.get(providerID) as any, + database[plugin.auth.provider], + ) + mergeProvider(plugin.auth.provider, options ?? {}, "custom") + } + + // If this is github-copilot plugin, also register for github-copilot-enterprise if auth exists + if (providerID === "github-copilot") { + const enterpriseProviderID = "github-copilot-enterprise" + if (!disabled.has(enterpriseProviderID)) { + const enterpriseAuth = await Auth.get(enterpriseProviderID) + if (enterpriseAuth) { + const enterpriseOptions = await plugin.auth.loader( + () => Auth.get(enterpriseProviderID) as any, + database[enterpriseProviderID], + ) + mergeProvider(enterpriseProviderID, enterpriseOptions ?? {}, "custom") + } + } + } } // load config @@ -458,7 +500,8 @@ export namespace Provider { : installedPath const mod = await import(modPath) if (options["timeout"] !== undefined && options["timeout"] !== null) { - // Only override fetch if user explicitly sets timeout + // Preserve custom fetch if it exists, wrap it with timeout logic + const customFetch = options["fetch"] options["fetch"] = async (input: any, init?: BunFetchRequestInit) => { const { signal, ...rest } = init ?? {} @@ -468,7 +511,8 @@ export namespace Provider { const combined = signals.length > 1 ? AbortSignal.any(signals) : signals[0] - return fetch(input, { + const fetchFn = customFetch ?? fetch + return fetchFn(input, { ...rest, signal: combined, // @ts-ignore see here: https://github.com/oven-sh/bun/issues/16682 diff --git a/packages/plugin/src/index.ts b/packages/plugin/src/index.ts index 9c2647c60..f103749bd 100644 --- a/packages/plugin/src/index.ts +++ b/packages/plugin/src/index.ts @@ -39,13 +39,35 @@ export interface Hooks { | { type: "oauth" label: string - authorize(): Promise< + prompts?: Array< + | { + type: "text" + key: string + message: string + placeholder?: string + validate?: (value: string) => string | undefined + condition?: (inputs: Record) => boolean + } + | { + type: "select" + key: string + message: string + options: Array<{ + label: string + value: string + hint?: string + }> + condition?: (inputs: Record) => boolean + } + > + authorize(inputs?: Record): Promise< { url: string; instructions: string } & ( | { method: "auto" callback(): Promise< | ({ type: "success" + provider?: string } & ( | { refresh: string @@ -64,6 +86,7 @@ export interface Hooks { callback(code: string): Promise< | ({ type: "success" + provider?: string } & ( | { refresh: string @@ -80,7 +103,41 @@ export interface Hooks { ) > } - | { type: "api"; label: string } + | { + type: "api" + label: string + prompts?: Array< + | { + type: "text" + key: string + message: string + placeholder?: string + validate?: (value: string) => string | undefined + condition?: (inputs: Record) => boolean + } + | { + type: "select" + key: string + message: string + options: Array<{ + label: string + value: string + hint?: string + }> + condition?: (inputs: Record) => boolean + } + > + authorize?(inputs?: Record): Promise< + | { + type: "success" + key: string + provider?: string + } + | { + type: "failed" + } + > + } )[] } /** diff --git a/packages/sdk/js/src/gen/types.gen.ts b/packages/sdk/js/src/gen/types.gen.ts index d4b763324..0c0135b4f 100644 --- a/packages/sdk/js/src/gen/types.gen.ts +++ b/packages/sdk/js/src/gen/types.gen.ts @@ -405,6 +405,10 @@ export type Config = { options?: { apiKey?: string baseURL?: string + /** + * GitHub Enterprise URL for copilot authentication + */ + enterpriseUrl?: string /** * Timeout in milliseconds for requests to this provider. Default is 300000 (5 minutes). Set to false to disable timeout. */ @@ -1135,6 +1139,7 @@ export type OAuth = { refresh: string access: string expires: number + enterpriseUrl?: string } export type ApiAuth = { -- cgit v1.2.3