diff --git a/bun.lock b/bun.lock index eb51eb0420..07fe4a33e8 100644 --- a/bun.lock +++ b/bun.lock @@ -278,7 +278,7 @@ "@ai-sdk/vercel": "1.0.31", "@ai-sdk/xai": "2.0.51", "@clack/prompts": "1.0.0-alpha.1", - "@gitlab/gitlab-ai-provider": "3.1.0", + "@gitlab/gitlab-ai-provider": "3.1.1", "@hono/standard-validator": "0.1.5", "@hono/zod-validator": "catalog:", "@modelcontextprotocol/sdk": "1.25.2", @@ -913,7 +913,7 @@ "@fontsource/inter": ["@fontsource/inter@5.2.8", "", {}, "sha512-P6r5WnJoKiNVV+zvW2xM13gNdFhAEpQ9dQJHt3naLvfg+LkF2ldgSLiF4T41lf1SQCM9QmkqPTn4TH568IRagg=="], - "@gitlab/gitlab-ai-provider": ["@gitlab/gitlab-ai-provider@3.1.0", "", { "dependencies": { "@anthropic-ai/sdk": "^0.71.0", "@anycable/core": "^0.9.2", "graphql-request": "^6.1.0", "isomorphic-ws": "^5.0.0", "socket.io-client": "^4.8.1", "vscode-jsonrpc": "^8.2.1", "zod": "^3.25.76" }, "peerDependencies": { "@ai-sdk/provider": ">=2.0.0", "@ai-sdk/provider-utils": ">=3.0.0" } }, "sha512-S0MVXsogrwbOboA/8L0CY5sBXg2HrrO8gdeUeHd9yLZDPsggFD0FzcSuzO5vBO6geUOpruRa8Hqrbb6WWu7Frw=="], + "@gitlab/gitlab-ai-provider": ["@gitlab/gitlab-ai-provider@3.1.1", "", { "dependencies": { "@anthropic-ai/sdk": "^0.71.0", "@anycable/core": "^0.9.2", "graphql-request": "^6.1.0", "isomorphic-ws": "^5.0.0", "socket.io-client": "^4.8.1", "vscode-jsonrpc": "^8.2.1", "zod": "^3.25.76" }, "peerDependencies": { "@ai-sdk/provider": ">=2.0.0", "@ai-sdk/provider-utils": ">=3.0.0" } }, "sha512-7AtFrCflq2NzC99bj7YaqbQDCZyaScM1+L4ujllV5syiRTFE239Uhnd/yEkPXa7sUAnNRfN3CWusCkQ2zK/q9g=="], "@graphql-typed-document-node/core": ["@graphql-typed-document-node/core@3.2.0", "", { "peerDependencies": { "graphql": "^0.8.0 || ^0.9.0 || ^0.10.0 || ^0.11.0 || ^0.12.0 || ^0.13.0 || ^14.0.0 || ^15.0.0 || ^16.0.0 || ^17.0.0" } }, "sha512-mB9oAsNCm9aM3/SOv4YtBMqZbYj10R7dkq8byBqxGY/ncFwhf2oQzMV+LCRlWoDSEBJ3COiR1yeDvMtsoOsuFQ=="], diff --git a/nix/hashes.json b/nix/hashes.json index df6cd8069f..f24bf1136e 100644 --- a/nix/hashes.json +++ b/nix/hashes.json @@ -1,6 +1,6 @@ { "nodeModules": { - "x86_64-linux": "sha256-wENwhwRVfgoVyA9YNGcG+fAfu46JxK4xvNgiPbRt//s=", - "aarch64-darwin": "sha256-vm1DYl1erlbaqz5NHHlnZEMuFmidr/UkS84nIqLJ96Q=" + "x86_64-linux": "sha256-1l4twtOi/7YYy1KFJME1XazAgTETAfbxB3EOv2qQeVs=", + "aarch64-darwin": "sha256-jdZI3BA/v35er4xgWkI2rHo54D1TDNVhMX83b5BcIvk=" } } diff --git a/packages/opencode/package.json b/packages/opencode/package.json index 9019635b10..8b6ccf84b5 100644 --- a/packages/opencode/package.json +++ b/packages/opencode/package.json @@ -70,7 +70,7 @@ "@ai-sdk/vercel": "1.0.31", "@ai-sdk/xai": "2.0.51", "@clack/prompts": "1.0.0-alpha.1", - "@gitlab/gitlab-ai-provider": "3.1.0", + "@gitlab/gitlab-ai-provider": "3.1.1", "@hono/standard-validator": "0.1.5", "@hono/zod-validator": "catalog:", "@modelcontextprotocol/sdk": "1.25.2", diff --git a/packages/opencode/src/cli/cmd/upgrade.ts b/packages/opencode/src/cli/cmd/upgrade.ts index 65f3bab4d4..4438fa3b84 100644 --- a/packages/opencode/src/cli/cmd/upgrade.ts +++ b/packages/opencode/src/cli/cmd/upgrade.ts @@ -16,7 +16,7 @@ export const UpgradeCommand = { alias: "m", describe: "installation method to use", type: "string", - choices: ["curl", "npm", "pnpm", "bun", "brew"], + choices: ["curl", "npm", "pnpm", "bun", "brew", "choco", "scoop"], }) }, handler: async (args: { target?: string; method?: string }) => { @@ -56,8 +56,14 @@ export const UpgradeCommand = { const err = await Installation.upgrade(method, target).catch((err) => err) if (err) { spinner.stop("Upgrade failed", 1) - if (err instanceof Installation.UpgradeFailedError) prompts.log.error(err.data.stderr) - else if (err instanceof Error) prompts.log.error(err.message) + if (err instanceof Installation.UpgradeFailedError) { + // necessary because choco only allows install/upgrade in elevated terminals + if (method === "choco" && err.data.stderr.includes("not running from an elevated command shell")) { + prompts.log.error("Please run the terminal as Administrator and try again") + } else { + prompts.log.error(err.data.stderr) + } + } else if (err instanceof Error) prompts.log.error(err.message) prompts.outro("Done") return } diff --git a/packages/opencode/src/installation/index.ts b/packages/opencode/src/installation/index.ts index 9e6dd2b9e9..dea312adb0 100644 --- a/packages/opencode/src/installation/index.ts +++ b/packages/opencode/src/installation/index.ts @@ -83,6 +83,14 @@ export namespace Installation { name: "brew" as const, command: () => $`brew list --formula opencode`.throws(false).quiet().text(), }, + { + name: "scoop" as const, + command: () => $`scoop list opencode`.throws(false).quiet().text(), + }, + { + name: "choco" as const, + command: () => $`choco list --limit-output opencode`.throws(false).quiet().text(), + }, ] checks.sort((a, b) => { @@ -95,7 +103,9 @@ export namespace Installation { for (const check of checks) { const output = await check.command() - if (output.includes(check.name === "brew" ? "opencode" : "opencode-ai")) { + const installedName = + check.name === "brew" || check.name === "choco" || check.name === "scoop" ? "opencode" : "opencode-ai" + if (output.includes(installedName)) { return check.name } } @@ -144,20 +154,28 @@ export namespace Installation { }) break } + case "choco": + cmd = $`echo Y | choco upgrade opencode --version=${target}` + break + case "scoop": + cmd = $`scoop install extras/opencode@${target}` + break default: throw new Error(`Unknown method: ${method}`) } const result = await cmd.quiet().throws(false) + if (result.exitCode !== 0) { + const stderr = method === "choco" ? "not running from an elevated command shell" : result.stderr.toString("utf8") + throw new UpgradeFailedError({ + stderr: stderr, + }) + } log.info("upgraded", { method, target, stdout: result.stdout.toString(), stderr: result.stderr.toString(), }) - if (result.exitCode !== 0) - throw new UpgradeFailedError({ - stderr: result.stderr.toString("utf8"), - }) await $`${process.execPath} --version`.nothrow().quiet().text() } @@ -195,6 +213,29 @@ export namespace Installation { .then((data: any) => data.version) } + if (detectedMethod === "choco") { + return fetch( + "https://community.chocolatey.org/api/v2/Packages?$filter=Id%20eq%20%27opencode%27%20and%20IsLatestVersion&$select=Version", + { headers: { Accept: "application/json;odata=verbose" } }, + ) + .then((res) => { + if (!res.ok) throw new Error(res.statusText) + return res.json() + }) + .then((data: any) => data.d.results[0].Version) + } + + if (detectedMethod === "scoop") { + return fetch("https://raw.githubusercontent.com/ScoopInstaller/Extras/master/bucket/opencode.json", { + headers: { Accept: "application/json" }, + }) + .then((res) => { + if (!res.ok) throw new Error(res.statusText) + return res.json() + }) + .then((data: any) => data.version) + } + return fetch("https://api.github.com/repos/anomalyco/opencode/releases/latest") .then((res) => { if (!res.ok) throw new Error(res.statusText) diff --git a/packages/opencode/src/provider/provider.ts b/packages/opencode/src/provider/provider.ts index d87e0db2e6..5374d76ee2 100644 --- a/packages/opencode/src/provider/provider.ts +++ b/packages/opencode/src/provider/provider.ts @@ -416,10 +416,8 @@ export namespace Provider { ...(providerConfig?.options?.featureFlags || {}), }, }, - async getModel(sdk: ReturnType, modelID: string, options?: { anthropicModel?: string }) { - const anthropicModel = options?.anthropicModel + async getModel(sdk: ReturnType, modelID: string) { return sdk.agenticChat(modelID, { - anthropicModel, featureFlags: { duo_agent_platform_agentic_chat: true, duo_agent_platform: true, diff --git a/packages/web/src/assets/lander/screenshot-splash.png b/packages/web/src/assets/lander/screenshot-splash.png index e900673ef5..c5e6547daa 100644 Binary files a/packages/web/src/assets/lander/screenshot-splash.png and b/packages/web/src/assets/lander/screenshot-splash.png differ diff --git a/packages/web/src/assets/lander/screenshot.png b/packages/web/src/assets/lander/screenshot.png index feb6175851..b9d8bf4df1 100644 Binary files a/packages/web/src/assets/lander/screenshot.png and b/packages/web/src/assets/lander/screenshot.png differ