mirror of
https://github.com/anomalyco/opencode.git
synced 2026-08-04 01:06:16 -04:00
Compare commits
8 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 3b29b7e3af | |||
| 7fe993879f | |||
| def14d96ef | |||
| b0b1149233 | |||
| 7becbbf711 | |||
| 87481f2bb6 | |||
| 9535a8f929 | |||
| e917c12c80 |
@@ -252,33 +252,6 @@ These are not strictly enforced, they are just general guidelines:
|
||||
|
||||
For net-new functionality, start with a design conversation. Open an issue describing the problem, your proposed approach (optional), and why it belongs in OpenCode. The core team will help decide whether it should move forward; please wait for that approval instead of opening a feature PR directly.
|
||||
|
||||
## Trust & Vouch System
|
||||
|
||||
This project uses [vouch](https://github.com/mitchellh/vouch) to manage contributor trust. The vouch list is maintained in [`.github/VOUCHED.td`](.github/VOUCHED.td).
|
||||
|
||||
### How it works
|
||||
|
||||
- **Vouched users** are explicitly trusted contributors.
|
||||
- **Denounced users** are explicitly blocked. Issues and pull requests from denounced users are automatically closed. If you have been denounced, you can request to be unvouched by reaching out to a maintainer on [Discord](https://opencode.ai/discord)
|
||||
- **Everyone else** can participate normally — you don't need to be vouched to open issues or PRs.
|
||||
|
||||
### For maintainers
|
||||
|
||||
Collaborators with write access can manage the vouch list by commenting on any issue:
|
||||
|
||||
- `vouch` — vouch for the issue author
|
||||
- `vouch @username` — vouch for a specific user
|
||||
- `denounce` — denounce the issue author
|
||||
- `denounce @username` — denounce a specific user
|
||||
- `denounce @username <reason>` — denounce with a reason
|
||||
- `unvouch` / `unvouch @username` — remove someone from the list
|
||||
|
||||
Changes are committed automatically to `.github/VOUCHED.td`.
|
||||
|
||||
### Denouncement policy
|
||||
|
||||
Denouncement is reserved for users who repeatedly submit low-quality AI-generated contributions, spam, or otherwise act in bad faith. It is not used for disagreements or honest mistakes.
|
||||
|
||||
## Issue Requirements
|
||||
|
||||
All issues **must** use one of our issue templates:
|
||||
|
||||
@@ -29,7 +29,7 @@
|
||||
},
|
||||
"packages/app": {
|
||||
"name": "@opencode-ai/app",
|
||||
"version": "1.18.11",
|
||||
"version": "1.18.12",
|
||||
"dependencies": {
|
||||
"@corvu/drawer": "catalog:",
|
||||
"@dnd-kit/abstract": "0.5.0",
|
||||
@@ -96,7 +96,7 @@
|
||||
},
|
||||
"packages/cli": {
|
||||
"name": "@opencode-ai/cli",
|
||||
"version": "1.18.11",
|
||||
"version": "1.18.12",
|
||||
"bin": {
|
||||
"lildax": "./bin/lildax.cjs",
|
||||
},
|
||||
@@ -144,7 +144,7 @@
|
||||
},
|
||||
"packages/codemode": {
|
||||
"name": "@opencode-ai/codemode",
|
||||
"version": "1.18.11",
|
||||
"version": "1.18.12",
|
||||
"dependencies": {
|
||||
"acorn": "8.15.0",
|
||||
"effect": "catalog:",
|
||||
@@ -158,7 +158,7 @@
|
||||
},
|
||||
"packages/console/app": {
|
||||
"name": "@opencode-ai/console-app",
|
||||
"version": "1.18.11",
|
||||
"version": "1.18.12",
|
||||
"dependencies": {
|
||||
"@cloudflare/vite-plugin": "1.15.2",
|
||||
"@ibm/plex": "6.4.1",
|
||||
@@ -194,7 +194,7 @@
|
||||
},
|
||||
"packages/console/core": {
|
||||
"name": "@opencode-ai/console-core",
|
||||
"version": "1.18.11",
|
||||
"version": "1.18.12",
|
||||
"dependencies": {
|
||||
"@aws-sdk/client-sts": "3.782.0",
|
||||
"@jsx-email/render": "1.1.1",
|
||||
@@ -221,7 +221,7 @@
|
||||
},
|
||||
"packages/console/function": {
|
||||
"name": "@opencode-ai/console-function",
|
||||
"version": "1.18.11",
|
||||
"version": "1.18.12",
|
||||
"dependencies": {
|
||||
"@ai-sdk/anthropic": "3.0.82",
|
||||
"@ai-sdk/openai": "3.0.48",
|
||||
@@ -243,7 +243,7 @@
|
||||
},
|
||||
"packages/console/mail": {
|
||||
"name": "@opencode-ai/console-mail",
|
||||
"version": "1.18.11",
|
||||
"version": "1.18.12",
|
||||
"dependencies": {
|
||||
"@jsx-email/all": "2.2.3",
|
||||
"@jsx-email/cli": "1.4.3",
|
||||
@@ -267,7 +267,7 @@
|
||||
},
|
||||
"packages/console/support": {
|
||||
"name": "@opencode-ai/console-support",
|
||||
"version": "1.18.11",
|
||||
"version": "1.18.12",
|
||||
"dependencies": {
|
||||
"@cloudflare/vite-plugin": "1.15.2",
|
||||
"@opencode-ai/console-core": "workspace:*",
|
||||
@@ -287,7 +287,7 @@
|
||||
},
|
||||
"packages/core": {
|
||||
"name": "@opencode-ai/core",
|
||||
"version": "1.18.11",
|
||||
"version": "1.18.12",
|
||||
"bin": {
|
||||
"opencode": "./bin/opencode",
|
||||
},
|
||||
@@ -381,7 +381,7 @@
|
||||
},
|
||||
"packages/desktop": {
|
||||
"name": "@opencode-ai/desktop",
|
||||
"version": "1.18.11",
|
||||
"version": "1.18.12",
|
||||
"dependencies": {
|
||||
"@zip.js/zip.js": "2.7.62",
|
||||
"drizzle-orm": "catalog:",
|
||||
@@ -435,7 +435,7 @@
|
||||
},
|
||||
"packages/effect-drizzle-sqlite": {
|
||||
"name": "@opencode-ai/effect-drizzle-sqlite",
|
||||
"version": "1.18.11",
|
||||
"version": "1.18.12",
|
||||
"dependencies": {
|
||||
"drizzle-orm": "catalog:",
|
||||
"effect": "catalog:",
|
||||
@@ -449,7 +449,7 @@
|
||||
},
|
||||
"packages/effect-sqlite-node": {
|
||||
"name": "@opencode-ai/effect-sqlite-node",
|
||||
"version": "1.18.11",
|
||||
"version": "1.18.12",
|
||||
"dependencies": {
|
||||
"effect": "catalog:",
|
||||
},
|
||||
@@ -461,7 +461,7 @@
|
||||
},
|
||||
"packages/enterprise": {
|
||||
"name": "@opencode-ai/enterprise",
|
||||
"version": "1.18.11",
|
||||
"version": "1.18.12",
|
||||
"dependencies": {
|
||||
"@hono/standard-validator": "catalog:",
|
||||
"@opencode-ai/core": "workspace:*",
|
||||
@@ -493,7 +493,7 @@
|
||||
},
|
||||
"packages/function": {
|
||||
"name": "@opencode-ai/function",
|
||||
"version": "1.18.11",
|
||||
"version": "1.18.12",
|
||||
"dependencies": {
|
||||
"@octokit/auth-app": "8.0.1",
|
||||
"@octokit/rest": "catalog:",
|
||||
@@ -509,7 +509,7 @@
|
||||
},
|
||||
"packages/http-recorder": {
|
||||
"name": "@opencode-ai/http-recorder",
|
||||
"version": "1.18.11",
|
||||
"version": "1.18.12",
|
||||
"dependencies": {
|
||||
"@effect/platform-node": "4.0.0-beta.83",
|
||||
"@effect/platform-node-shared": "4.0.0-beta.83",
|
||||
@@ -540,7 +540,7 @@
|
||||
},
|
||||
"packages/llm": {
|
||||
"name": "@opencode-ai/llm",
|
||||
"version": "1.18.11",
|
||||
"version": "1.18.12",
|
||||
"dependencies": {
|
||||
"@opencode-ai/schema": "workspace:*",
|
||||
"@smithy/eventstream-codec": "4.2.14",
|
||||
@@ -559,7 +559,7 @@
|
||||
},
|
||||
"packages/opencode": {
|
||||
"name": "opencode",
|
||||
"version": "1.18.11",
|
||||
"version": "1.18.12",
|
||||
"bin": {
|
||||
"opencode": "./bin/opencode",
|
||||
},
|
||||
@@ -690,7 +690,7 @@
|
||||
},
|
||||
"packages/plugin": {
|
||||
"name": "@opencode-ai/plugin",
|
||||
"version": "1.18.11",
|
||||
"version": "1.18.12",
|
||||
"dependencies": {
|
||||
"@ai-sdk/provider": "3.0.8",
|
||||
"@opencode-ai/sdk": "workspace:*",
|
||||
@@ -766,7 +766,7 @@
|
||||
},
|
||||
"packages/sdk/js": {
|
||||
"name": "@opencode-ai/sdk",
|
||||
"version": "1.18.11",
|
||||
"version": "1.18.12",
|
||||
"dependencies": {
|
||||
"cross-spawn": "catalog:",
|
||||
},
|
||||
@@ -781,7 +781,7 @@
|
||||
},
|
||||
"packages/server": {
|
||||
"name": "@opencode-ai/server",
|
||||
"version": "1.18.11",
|
||||
"version": "1.18.12",
|
||||
"dependencies": {
|
||||
"@opencode-ai/core": "workspace:*",
|
||||
"@opencode-ai/protocol": "workspace:*",
|
||||
@@ -796,7 +796,7 @@
|
||||
},
|
||||
"packages/session-ui": {
|
||||
"name": "@opencode-ai/session-ui",
|
||||
"version": "1.18.11",
|
||||
"version": "1.18.12",
|
||||
"dependencies": {
|
||||
"@kobalte/core": "catalog:",
|
||||
"@opencode-ai/client": "file:../app/vendor/opencode-ai-client-1.17.13-v2.tgz",
|
||||
@@ -840,7 +840,7 @@
|
||||
},
|
||||
"packages/slack": {
|
||||
"name": "@opencode-ai/slack",
|
||||
"version": "1.18.11",
|
||||
"version": "1.18.12",
|
||||
"dependencies": {
|
||||
"@opencode-ai/sdk": "workspace:*",
|
||||
"@slack/bolt": "^3.17.1",
|
||||
@@ -853,7 +853,7 @@
|
||||
},
|
||||
"packages/stats/app": {
|
||||
"name": "@opencode-ai/stats-app",
|
||||
"version": "1.18.11",
|
||||
"version": "1.18.12",
|
||||
"dependencies": {
|
||||
"@ibm/plex": "6.4.1",
|
||||
"@kobalte/core": "catalog:",
|
||||
@@ -887,7 +887,7 @@
|
||||
},
|
||||
"packages/stats/core": {
|
||||
"name": "@opencode-ai/stats-core",
|
||||
"version": "1.18.11",
|
||||
"version": "1.18.12",
|
||||
"dependencies": {
|
||||
"@aws-sdk/client-athena": "3.933.0",
|
||||
"@planetscale/database": "1.19.0",
|
||||
@@ -906,7 +906,7 @@
|
||||
},
|
||||
"packages/stats/server": {
|
||||
"name": "@opencode-ai/stats-server",
|
||||
"version": "1.18.11",
|
||||
"version": "1.18.12",
|
||||
"dependencies": {
|
||||
"@aws-sdk/client-firehose": "3.933.0",
|
||||
"@effect/platform-node": "catalog:",
|
||||
@@ -948,7 +948,7 @@
|
||||
},
|
||||
"packages/tui": {
|
||||
"name": "@opencode-ai/tui",
|
||||
"version": "1.18.11",
|
||||
"version": "1.18.12",
|
||||
"dependencies": {
|
||||
"@opencode-ai/core": "workspace:*",
|
||||
"@opencode-ai/plugin": "workspace:*",
|
||||
@@ -975,7 +975,7 @@
|
||||
},
|
||||
"packages/ui": {
|
||||
"name": "@opencode-ai/ui",
|
||||
"version": "1.18.11",
|
||||
"version": "1.18.12",
|
||||
"dependencies": {
|
||||
"@kobalte/core": "catalog:",
|
||||
"@pierre/diffs": "catalog:",
|
||||
@@ -1027,7 +1027,7 @@
|
||||
},
|
||||
"packages/web": {
|
||||
"name": "@opencode-ai/web",
|
||||
"version": "1.18.11",
|
||||
"version": "1.18.12",
|
||||
"dependencies": {
|
||||
"@astrojs/cloudflare": "12.6.3",
|
||||
"@astrojs/markdown-remark": "6.3.1",
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@opencode-ai/app",
|
||||
"version": "1.18.11",
|
||||
"version": "1.18.12",
|
||||
"description": "",
|
||||
"type": "module",
|
||||
"exports": {
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
{
|
||||
"$schema": "https://json.schemastore.org/package.json",
|
||||
"name": "@opencode-ai/cli",
|
||||
"version": "1.18.11",
|
||||
"version": "1.18.12",
|
||||
"type": "module",
|
||||
"license": "MIT",
|
||||
"bin": {
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
{
|
||||
"$schema": "https://json.schemastore.org/package.json",
|
||||
"name": "@opencode-ai/codemode",
|
||||
"version": "1.18.11",
|
||||
"version": "1.18.12",
|
||||
"description": "Effect-native confined code execution over schema-described tools",
|
||||
"private": true,
|
||||
"type": "module",
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@opencode-ai/console-app",
|
||||
"version": "1.18.11",
|
||||
"version": "1.18.12",
|
||||
"type": "module",
|
||||
"license": "MIT",
|
||||
"scripts": {
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
{
|
||||
"$schema": "https://json.schemastore.org/package.json",
|
||||
"name": "@opencode-ai/console-core",
|
||||
"version": "1.18.11",
|
||||
"version": "1.18.12",
|
||||
"private": true,
|
||||
"type": "module",
|
||||
"license": "MIT",
|
||||
|
||||
@@ -59,7 +59,30 @@ export namespace Referral {
|
||||
const accountID = Actor.account()
|
||||
const code = await ensureCode(workspaceID)
|
||||
const rows = await Database.use(async (tx) => {
|
||||
const [invites, inviteeReferral] = await Promise.all([
|
||||
const [rewards, invites, inviteeReferral, inviteeRewards] = await Promise.all([
|
||||
tx
|
||||
.select({
|
||||
referralID: ReferralRewardTable.referralID,
|
||||
workspaceID: ReferralRewardTable.workspaceID,
|
||||
referralWorkspaceID: ReferralTable.workspaceID,
|
||||
inviteeEmail: AuthTable.subject,
|
||||
amount: ReferralRewardTable.amount,
|
||||
timeCreated: ReferralRewardTable.timeCreated,
|
||||
timeApplied: ReferralRewardTable.timeApplied,
|
||||
})
|
||||
.from(ReferralRewardTable)
|
||||
.innerJoin(ReferralTable, eq(ReferralTable.id, ReferralRewardTable.referralID))
|
||||
.innerJoin(
|
||||
AuthTable,
|
||||
and(eq(AuthTable.accountID, ReferralTable.inviteeAccountID), eq(AuthTable.provider, "email")),
|
||||
)
|
||||
.where(
|
||||
and(
|
||||
eq(ReferralRewardTable.workspaceID, workspaceID),
|
||||
isNull(ReferralRewardTable.timeDeleted),
|
||||
isNull(ReferralTable.timeDeleted),
|
||||
),
|
||||
),
|
||||
tx
|
||||
.select({ id: ReferralTable.id, inviteeEmail: AuthTable.subject, timeCreated: ReferralTable.timeCreated })
|
||||
.from(ReferralTable)
|
||||
@@ -83,20 +106,19 @@ export namespace Referral {
|
||||
.where(and(eq(ReferralTable.inviteeAccountID, accountID), isNull(ReferralTable.timeDeleted)))
|
||||
.orderBy(asc(UserTable.timeCreated))
|
||||
.then((rows) => rows.find((row) => row.inviterEmail) ?? rows[0]),
|
||||
tx
|
||||
.select({ referralID: ReferralRewardTable.referralID })
|
||||
.from(ReferralRewardTable)
|
||||
.innerJoin(ReferralTable, eq(ReferralTable.id, ReferralRewardTable.referralID))
|
||||
.where(
|
||||
and(
|
||||
eq(ReferralTable.inviteeAccountID, accountID),
|
||||
isNull(ReferralRewardTable.timeDeleted),
|
||||
isNull(ReferralTable.timeDeleted),
|
||||
),
|
||||
),
|
||||
])
|
||||
|
||||
// Hide reward history until the referral_id index can be deployed and this lookup restored.
|
||||
const rewards: {
|
||||
referralID: string
|
||||
workspaceID: string
|
||||
referralWorkspaceID: string
|
||||
inviteeEmail: string
|
||||
amount: number
|
||||
timeCreated: Date
|
||||
timeApplied: Date | null
|
||||
}[] = []
|
||||
// Hide pending invitee rewards until the referral_id index can be deployed and this lookup restored.
|
||||
const inviteeRewards = inviteeReferral ? [{ referralID: inviteeReferral.id }] : []
|
||||
return { inviteeReferral, inviteeRewards, invites, rewards }
|
||||
})
|
||||
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@opencode-ai/console-function",
|
||||
"version": "1.18.11",
|
||||
"version": "1.18.12",
|
||||
"$schema": "https://json.schemastore.org/package.json",
|
||||
"private": true,
|
||||
"type": "module",
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@opencode-ai/console-mail",
|
||||
"version": "1.18.11",
|
||||
"version": "1.18.12",
|
||||
"dependencies": {
|
||||
"@jsx-email/all": "2.2.3",
|
||||
"@jsx-email/cli": "1.4.3",
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@opencode-ai/console-support",
|
||||
"version": "1.18.11",
|
||||
"version": "1.18.12",
|
||||
"type": "module",
|
||||
"license": "MIT",
|
||||
"scripts": {
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"$schema": "https://json.schemastore.org/package.json",
|
||||
"version": "1.18.11",
|
||||
"version": "1.18.12",
|
||||
"name": "@opencode-ai/core",
|
||||
"type": "module",
|
||||
"license": "MIT",
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
{
|
||||
"name": "@opencode-ai/desktop",
|
||||
"private": true,
|
||||
"version": "1.18.11",
|
||||
"version": "1.18.12",
|
||||
"type": "module",
|
||||
"license": "MIT",
|
||||
"homepage": "https://opencode.ai",
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"$schema": "https://json.schemastore.org/package.json",
|
||||
"version": "1.18.11",
|
||||
"version": "1.18.12",
|
||||
"name": "@opencode-ai/effect-drizzle-sqlite",
|
||||
"type": "module",
|
||||
"license": "MIT",
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"$schema": "https://json.schemastore.org/package.json",
|
||||
"version": "1.18.11",
|
||||
"version": "1.18.12",
|
||||
"name": "@opencode-ai/effect-sqlite-node",
|
||||
"type": "module",
|
||||
"license": "MIT",
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@opencode-ai/enterprise",
|
||||
"version": "1.18.11",
|
||||
"version": "1.18.12",
|
||||
"private": true,
|
||||
"type": "module",
|
||||
"license": "MIT",
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@opencode-ai/function",
|
||||
"version": "1.18.11",
|
||||
"version": "1.18.12",
|
||||
"$schema": "https://json.schemastore.org/package.json",
|
||||
"private": true,
|
||||
"type": "module",
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"$schema": "https://json.schemastore.org/package.json",
|
||||
"version": "1.18.11",
|
||||
"version": "1.18.12",
|
||||
"name": "@opencode-ai/http-recorder",
|
||||
"description": "Record and replay Effect HTTP client traffic with deterministic cassettes",
|
||||
"type": "module",
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"$schema": "https://json.schemastore.org/package.json",
|
||||
"version": "1.18.11",
|
||||
"version": "1.18.12",
|
||||
"name": "@opencode-ai/llm",
|
||||
"type": "module",
|
||||
"license": "MIT",
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"$schema": "https://json.schemastore.org/package.json",
|
||||
"version": "1.18.11",
|
||||
"version": "1.18.12",
|
||||
"name": "opencode",
|
||||
"type": "module",
|
||||
"license": "MIT",
|
||||
|
||||
@@ -551,6 +551,32 @@ export async function XaiAuthPlugin(input: PluginInput, options: XaiAuthPluginOp
|
||||
{
|
||||
label: "xAI Grok OAuth (SuperGrok Subscription)",
|
||||
type: "oauth",
|
||||
authorize: async () => {
|
||||
const device = await requestDeviceCode(options)
|
||||
const browserUrl = device.verification_uri_complete ?? device.verification_uri
|
||||
return {
|
||||
url: browserUrl,
|
||||
instructions: `Open ${device.verification_uri} on any device and enter code: ${device.user_code}`,
|
||||
method: "auto" as const,
|
||||
callback: async () => {
|
||||
try {
|
||||
const tokens = await pollDeviceCodeToken(device, options)
|
||||
return {
|
||||
type: "success" as const,
|
||||
refresh: tokens.refresh_token,
|
||||
access: tokens.access_token,
|
||||
expires: Date.now() + (tokens.expires_in ?? 3600) * 1000,
|
||||
}
|
||||
} catch (err) {
|
||||
return { type: "failed" as const }
|
||||
}
|
||||
},
|
||||
}
|
||||
},
|
||||
},
|
||||
{
|
||||
label: "xAI Grok OAuth (Local Callback)",
|
||||
type: "oauth",
|
||||
authorize: async () => {
|
||||
await startOAuthServer()
|
||||
const pkce = await generatePKCE()
|
||||
@@ -582,40 +608,6 @@ export async function XaiAuthPlugin(input: PluginInput, options: XaiAuthPluginOp
|
||||
}
|
||||
},
|
||||
},
|
||||
{
|
||||
// RFC 8628 device-code flow. The CLI prints a verification URL
|
||||
// and a short user_code that the user enters in a browser on
|
||||
// any device. No loopback callback server runs on the CLI host,
|
||||
// so this works on VPS / SSH / Docker / CI / WSL / any
|
||||
// environment where 127.0.0.1:56121 isn't reachable from the
|
||||
// user's browser. Defends the only attack surface (the polling
|
||||
// loop) with the standard authorization_pending / slow_down
|
||||
// backoff and a hard deadline from xAI's `expires_in`.
|
||||
label: "xAI Grok OAuth (Headless / Remote / VPS)",
|
||||
type: "oauth",
|
||||
authorize: async () => {
|
||||
const device = await requestDeviceCode(options)
|
||||
const browserUrl = device.verification_uri_complete ?? device.verification_uri
|
||||
return {
|
||||
url: browserUrl,
|
||||
instructions: `Open ${device.verification_uri} on any device and enter code: ${device.user_code}`,
|
||||
method: "auto" as const,
|
||||
callback: async () => {
|
||||
try {
|
||||
const tokens = await pollDeviceCodeToken(device, options)
|
||||
return {
|
||||
type: "success" as const,
|
||||
refresh: tokens.refresh_token,
|
||||
access: tokens.access_token,
|
||||
expires: Date.now() + (tokens.expires_in ?? 3600) * 1000,
|
||||
}
|
||||
} catch (err) {
|
||||
return { type: "failed" as const }
|
||||
}
|
||||
},
|
||||
}
|
||||
},
|
||||
},
|
||||
{
|
||||
label: "Manually enter API Key",
|
||||
type: "api",
|
||||
|
||||
@@ -1270,6 +1270,17 @@ export function options(input: {
|
||||
result["gateway"] = { caching: "auto" }
|
||||
}
|
||||
|
||||
// Any gpt version above 5.4 in combination with azure does not support reasoningEffort
|
||||
// so we should return early here.
|
||||
const [, gptMajorVersion, gptMinorVersion] = input.model.api.id.match(/gpt-(\d+)\.(\d+)/) ?? []
|
||||
const isGpt55OrNewer = Number(gptMajorVersion) > 5 || (Number(gptMajorVersion) === 5 && Number(gptMinorVersion) >= 5)
|
||||
if (input.model.api.npm === "@ai-sdk/azure" && input.providerOptions?.useCompletionUrls) {
|
||||
if (!isGpt55OrNewer) {
|
||||
result["reasoningEffort"] = "medium"
|
||||
}
|
||||
return result
|
||||
}
|
||||
|
||||
if (input.model.api.id.includes("gpt-5") && !input.model.api.id.includes("gpt-5-chat")) {
|
||||
if (!input.model.api.id.includes("gpt-5-pro")) {
|
||||
result["reasoningEffort"] = "medium"
|
||||
|
||||
@@ -93,7 +93,6 @@ export const prepare = Effect.fn("LLMRequestPrep.prepare")(function* (input: Pre
|
||||
input.model.api.npm === "@ai-sdk/azure" &&
|
||||
(input.provider.options.useCompletionUrls || input.model.options.useCompletionUrls || options.useCompletionUrls)
|
||||
) {
|
||||
delete options.reasoningEffort
|
||||
delete options.reasoningSummary
|
||||
delete options.include
|
||||
}
|
||||
|
||||
@@ -111,7 +111,7 @@ describe("plugin.xai", () => {
|
||||
).toEqual({})
|
||||
expect(hooks.auth!.methods.map((m) => [m.type, m.label])).toEqual([
|
||||
["oauth", "xAI Grok OAuth (SuperGrok Subscription)"],
|
||||
["oauth", "xAI Grok OAuth (Headless / Remote / VPS)"],
|
||||
["oauth", "xAI Grok OAuth (Local Callback)"],
|
||||
["api", "Manually enter API Key"],
|
||||
])
|
||||
})
|
||||
@@ -424,11 +424,11 @@ describe("plugin.xai", () => {
|
||||
return new Response("unexpected request", { status: 500 })
|
||||
})
|
||||
const hooks = await XaiAuthPlugin({} as any, serverOptions(server))
|
||||
const headless = hooks.auth!.methods.find(
|
||||
const oauth = hooks.auth!.methods.find(
|
||||
(m): m is Extract<typeof m, { type: "oauth" }> =>
|
||||
m.type === "oauth" && m.label === "xAI Grok OAuth (Headless / Remote / VPS)",
|
||||
m.type === "oauth" && m.label === "xAI Grok OAuth (SuperGrok Subscription)",
|
||||
)!
|
||||
const result = await headless.authorize!()
|
||||
const result = await oauth.authorize!()
|
||||
|
||||
expect(result.method).toBe("auto")
|
||||
expect(result.url).toBe("https://x.ai/device?user_code=ABCD-1234")
|
||||
@@ -448,11 +448,11 @@ describe("plugin.xai", () => {
|
||||
}
|
||||
return new Response("unexpected request", { status: 500 })
|
||||
})
|
||||
const headless = (await XaiAuthPlugin({} as any, serverOptions(server))).auth!.methods.find(
|
||||
const oauth = (await XaiAuthPlugin({} as any, serverOptions(server))).auth!.methods.find(
|
||||
(m): m is Extract<typeof m, { type: "oauth" }> =>
|
||||
m.type === "oauth" && m.label === "xAI Grok OAuth (Headless / Remote / VPS)",
|
||||
m.type === "oauth" && m.label === "xAI Grok OAuth (SuperGrok Subscription)",
|
||||
)!
|
||||
expect((await headless.authorize!()).url).toBe("https://x.ai/device")
|
||||
expect((await oauth.authorize!()).url).toBe("https://x.ai/device")
|
||||
})
|
||||
|
||||
test("requestDeviceCode posts form body, validates fields, and surfaces endpoint errors", async () => {
|
||||
@@ -610,11 +610,11 @@ describe("plugin.xai", () => {
|
||||
}
|
||||
return Response.json({ error: "access_denied" }, { status: 400 })
|
||||
})
|
||||
const headless = (await XaiAuthPlugin({} as any, serverOptions(server))).auth!.methods.find(
|
||||
const oauth = (await XaiAuthPlugin({} as any, serverOptions(server))).auth!.methods.find(
|
||||
(m): m is Extract<typeof m, { type: "oauth" }> =>
|
||||
m.type === "oauth" && m.label === "xAI Grok OAuth (Headless / Remote / VPS)",
|
||||
m.type === "oauth" && m.label === "xAI Grok OAuth (SuperGrok Subscription)",
|
||||
)!
|
||||
expect(await ((await headless.authorize!()) as any).callback()).toEqual({ type: "failed" })
|
||||
expect(await ((await oauth.authorize!()) as any).callback()).toEqual({ type: "failed" })
|
||||
})
|
||||
})
|
||||
})
|
||||
|
||||
@@ -252,7 +252,7 @@ describe("ProviderTransform.options - setCacheKey", () => {
|
||||
expect(result.promptCacheKey).toBeUndefined()
|
||||
})
|
||||
|
||||
test("should keep the Azure cache key for gpt-5.5 Responses defaults", () => {
|
||||
test("should keep the Azure cache key for gpt-5.5 early return", () => {
|
||||
const result = ProviderTransform.options({
|
||||
model: {
|
||||
...mockModel,
|
||||
@@ -525,7 +525,7 @@ describe("ProviderTransform.options - gpt-5 textVerbosity", () => {
|
||||
expect(result.include).toBeUndefined()
|
||||
})
|
||||
|
||||
test("azure chat completions omit unsupported reasoning options after variants merge", async () => {
|
||||
test("azure chat completions omit Responses-only reasoning options after variants merge", async () => {
|
||||
const model = {
|
||||
...createGpt5Model("gpt-5.4"),
|
||||
id: "azure/gpt-5.4",
|
||||
@@ -580,7 +580,7 @@ describe("ProviderTransform.options - gpt-5 textVerbosity", () => {
|
||||
isWorkflow: false,
|
||||
}),
|
||||
)
|
||||
expect(result.params.options.reasoningEffort).toBeUndefined()
|
||||
expect(result.params.options.reasoningEffort).toBe("high")
|
||||
expect(result.params.options.reasoningSummary).toBeUndefined()
|
||||
expect(result.params.options.include).toBeUndefined()
|
||||
expect(result.tools.lookup.strict).toBe(false)
|
||||
@@ -681,15 +681,34 @@ describe("ProviderTransform.options - gpt-5 reasoningEffort", () => {
|
||||
expect(result.reasoningEffort).toBeUndefined()
|
||||
})
|
||||
|
||||
test("gpt-5.5 should set Responses reasoning options", () => {
|
||||
test("gpt-5.5 should NOT set reasoningEffort for the completions API", () => {
|
||||
const result = ProviderTransform.options({
|
||||
model: createModel("gpt-5.5"),
|
||||
sessionID,
|
||||
providerOptions: { useCompletionUrls: true },
|
||||
})
|
||||
|
||||
expect(result.reasoningEffort).toBeUndefined()
|
||||
})
|
||||
|
||||
test("gpt-5.6 should NOT set reasoningEffort for the completions API", () => {
|
||||
const result = ProviderTransform.options({
|
||||
model: createModel("gpt-5.6"),
|
||||
sessionID,
|
||||
providerOptions: { useCompletionUrls: true },
|
||||
})
|
||||
|
||||
expect(result.reasoningEffort).toBeUndefined()
|
||||
})
|
||||
|
||||
test("gpt-5.6 should set reasoningEffort for the responses API", () => {
|
||||
const result = ProviderTransform.options({
|
||||
model: createModel("gpt-5.6"),
|
||||
sessionID,
|
||||
providerOptions: {},
|
||||
})
|
||||
|
||||
expect(result.reasoningEffort).toBe("medium")
|
||||
expect(result.reasoningSummary).toBe("auto")
|
||||
})
|
||||
})
|
||||
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
{
|
||||
"$schema": "https://json.schemastore.org/package.json",
|
||||
"name": "@opencode-ai/plugin",
|
||||
"version": "1.18.11",
|
||||
"version": "1.18.12",
|
||||
"type": "module",
|
||||
"license": "MIT",
|
||||
"scripts": {
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
{
|
||||
"$schema": "https://json.schemastore.org/package.json",
|
||||
"name": "@opencode-ai/sdk",
|
||||
"version": "1.18.11",
|
||||
"version": "1.18.12",
|
||||
"type": "module",
|
||||
"license": "MIT",
|
||||
"scripts": {
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
{
|
||||
"$schema": "https://json.schemastore.org/package.json",
|
||||
"name": "@opencode-ai/server",
|
||||
"version": "1.18.11",
|
||||
"version": "1.18.12",
|
||||
"private": true,
|
||||
"type": "module",
|
||||
"license": "MIT",
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@opencode-ai/session-ui",
|
||||
"version": "1.18.11",
|
||||
"version": "1.18.12",
|
||||
"private": true,
|
||||
"type": "module",
|
||||
"license": "MIT",
|
||||
|
||||
@@ -255,8 +255,16 @@ function useFileViewer(config: ViewerConfig) {
|
||||
if (!dragMoved) {
|
||||
pendingSelectionEnd = false
|
||||
const selected = config.buildClickSelection()
|
||||
if (selected) config.setSelectedLines(selected)
|
||||
config.onLineSelectionEnd(lastSelection)
|
||||
const next =
|
||||
selected &&
|
||||
lastSelection?.start === selected.start &&
|
||||
lastSelection.end === selected.end &&
|
||||
lastSelection.side === selected.side &&
|
||||
(lastSelection.endSide ?? lastSelection.side) === (selected.endSide ?? selected.side)
|
||||
? null
|
||||
: selected
|
||||
if (next !== undefined) config.setSelectedLines(next)
|
||||
config.onLineSelectionEnd(next === undefined ? lastSelection : next)
|
||||
dragStart = undefined
|
||||
dragEnd = undefined
|
||||
dragMoved = false
|
||||
@@ -291,10 +299,29 @@ function useFileViewer(config: ViewerConfig) {
|
||||
createEffect(() => {
|
||||
rendered()
|
||||
const ranges = config.commentedLines()
|
||||
requestAnimationFrame(() => {
|
||||
const root = getRoot()
|
||||
if (!root) return
|
||||
const root = getRoot()
|
||||
if (!root) return
|
||||
if (ranges.length === 0) {
|
||||
config.markCommented(root, ranges)
|
||||
return
|
||||
}
|
||||
|
||||
let frame: number | undefined
|
||||
const mark = () => {
|
||||
if (frame !== undefined) cancelAnimationFrame(frame)
|
||||
frame = requestAnimationFrame(() => {
|
||||
frame = undefined
|
||||
config.markCommented(root, ranges)
|
||||
})
|
||||
}
|
||||
const observer = new MutationObserver(mark)
|
||||
|
||||
observer.observe(root, { childList: true, subtree: true })
|
||||
mark()
|
||||
|
||||
onCleanup(() => {
|
||||
observer.disconnect()
|
||||
if (frame !== undefined) cancelAnimationFrame(frame)
|
||||
})
|
||||
})
|
||||
|
||||
|
||||
@@ -26,30 +26,19 @@ const unsafeCSS = `
|
||||
color-mix(in lab, var(--diffs-bg) 33.333%, var(--diffs-deletion-base)),
|
||||
color-mix(in lab, var(--diffs-bg) 60%, var(--diffs-deletion-base))
|
||||
);
|
||||
--diffs-bg-deletion-number-override: var(--diffs-bg-deletion-override);
|
||||
--diffs-bg-addition-override: light-dark(
|
||||
color-mix(in lab, var(--diffs-bg) 33.333%, var(--diffs-addition-base)),
|
||||
color-mix(in lab, var(--diffs-bg) 60%, var(--diffs-addition-base))
|
||||
);
|
||||
--diffs-selection-base: var(--surface-warning-strong);
|
||||
--diffs-selection-border: var(--border-warning-base);
|
||||
--diffs-selection-number-fg: #1c1917;
|
||||
--diffs-bg-addition-number-override: var(--diffs-bg-addition-override);
|
||||
--diffs-selection-base: var(--v2-background-bg-accent);
|
||||
--diffs-selection-number-fg: var(--v2-text-text-accent);
|
||||
--diffs-comment-bg: rgb(from var(--v2-background-bg-accent) r g b / 0.06);
|
||||
/* Use explicit alpha instead of color-mix(..., transparent) to avoid Safari's non-premultiplied interpolation bugs. */
|
||||
--diffs-bg-selection: var(--diffs-bg-selection-override, rgb(from var(--surface-warning-base) r g b / 0.65));
|
||||
--diffs-bg-selection-number: var(
|
||||
--diffs-bg-selection-number-override,
|
||||
rgb(from var(--surface-warning-base) r g b / 0.85)
|
||||
);
|
||||
--diffs-bg-selection-text: rgb(from var(--surface-warning-strong) r g b / 0.2);
|
||||
}
|
||||
|
||||
:host([data-color-scheme='dark']) [data-diff],
|
||||
:host([data-color-scheme='dark']) [data-file] {
|
||||
--diffs-selection-number-fg: #fdfbfb;
|
||||
--diffs-bg-selection: var(--diffs-bg-selection-override, rgb(from var(--solaris-dark-6) r g b / 0.65));
|
||||
--diffs-bg-selection-number: var(
|
||||
--diffs-bg-selection-number-override,
|
||||
rgb(from var(--solaris-dark-6) r g b / 0.85)
|
||||
);
|
||||
--diffs-bg-selection: var(--diffs-bg-selection-override, rgb(from var(--diffs-selection-base) r g b / 0.2));
|
||||
--diffs-bg-selection-number: var(--diffs-bg-selection-number-override, var(--diffs-bg-selection));
|
||||
--diffs-bg-selection-text: rgb(from var(--diffs-selection-base) r g b / 0.2);
|
||||
}
|
||||
|
||||
[data-diff] ::selection,
|
||||
@@ -57,6 +46,34 @@ const unsafeCSS = `
|
||||
background-color: var(--diffs-bg-selection-text);
|
||||
}
|
||||
|
||||
[data-indicators='bars'] [data-column-number][data-line-type='change-addition']::before,
|
||||
[data-indicators='bars'] [data-column-number][data-line-type='change-deletion']::before {
|
||||
width: 2px;
|
||||
}
|
||||
|
||||
[data-indicators='bars'] [data-column-number][data-line-type='change-deletion']::before {
|
||||
background-image: none;
|
||||
background-color: var(--diffs-deletion-base);
|
||||
}
|
||||
|
||||
[data-background] [data-column-number] {
|
||||
--mix-light: 88%;
|
||||
--mix-dark: 80%;
|
||||
}
|
||||
|
||||
[data-diff-type='split'] [data-additions],
|
||||
[data-diff-type='split'] [data-additions] [data-gutter],
|
||||
[data-diff-type='split'] [data-deletions],
|
||||
[data-diff-type='split'] [data-deletions] [data-content] {
|
||||
border-left: 0;
|
||||
border-right: 0;
|
||||
}
|
||||
|
||||
[data-content-buffer] {
|
||||
background-image: none;
|
||||
background-color: var(--diffs-bg-context-gutter);
|
||||
}
|
||||
|
||||
::highlight(opencode-find) {
|
||||
background-color: rgb(from var(--surface-warning-base) r g b / 0.35);
|
||||
}
|
||||
@@ -83,22 +100,24 @@ const unsafeCSS = `
|
||||
color: var(--diffs-selection-number-fg);
|
||||
}
|
||||
|
||||
[data-diff] [data-line-annotation][data-comment-selected]:not([data-selected-line]) [data-annotation-content] {
|
||||
box-shadow: inset 0 0 0 9999px var(--diffs-bg-selection);
|
||||
}
|
||||
|
||||
[data-file] [data-line-annotation][data-comment-selected]:not([data-selected-line]) [data-annotation-content] {
|
||||
box-shadow: inset 0 0 0 9999px var(--diffs-bg-selection);
|
||||
[data-diff] [data-line-annotation],
|
||||
[data-diff] [data-gutter-buffer='annotation'],
|
||||
[data-file] [data-line-annotation],
|
||||
[data-file] [data-gutter-buffer='annotation'] {
|
||||
--diffs-annotation-bg: var(--diffs-comment-bg);
|
||||
--diffs-computed-decoration-bg: var(--diffs-comment-bg);
|
||||
--diffs-computed-diff-line-bg: var(--diffs-comment-bg);
|
||||
--diffs-computed-selected-line-bg: var(--diffs-comment-bg);
|
||||
--diffs-line-bg: var(--diffs-comment-bg);
|
||||
background-color: var(--diffs-comment-bg);
|
||||
}
|
||||
|
||||
[data-diff] [data-line][data-selected-line] {
|
||||
background-color: var(--diffs-bg-selection);
|
||||
box-shadow: inset 2px 0 0 var(--diffs-selection-border);
|
||||
}
|
||||
|
||||
[data-file] [data-line][data-selected-line] {
|
||||
background-color: var(--diffs-bg-selection);
|
||||
box-shadow: inset 2px 0 0 var(--diffs-selection-border);
|
||||
}
|
||||
|
||||
[data-diff] [data-column-number][data-selected-line] {
|
||||
@@ -118,6 +137,19 @@ const unsafeCSS = `
|
||||
color: var(--diffs-selection-number-fg);
|
||||
}
|
||||
|
||||
@media (pointer: fine) {
|
||||
[data-gutter-utility-slot] {
|
||||
opacity: 0;
|
||||
pointer-events: none;
|
||||
}
|
||||
|
||||
[data-column-number][data-hovered] [data-gutter-utility-slot],
|
||||
[data-gutter-utility-slot]:focus-within {
|
||||
opacity: 1;
|
||||
pointer-events: auto;
|
||||
}
|
||||
}
|
||||
|
||||
/* The deletion word-diff emphasis is stronger than additions; soften it while selected so the selection highlight reads consistently. */
|
||||
[data-diff] [data-line][data-line-type='change-deletion'][data-selected-line] {
|
||||
--diffs-bg-deletion-emphasis: light-dark(
|
||||
@@ -133,7 +165,6 @@ const unsafeCSS = `
|
||||
height: 24px;
|
||||
}
|
||||
[data-column-number] {
|
||||
background-color: var(--diffs-bg);
|
||||
cursor: default !important;
|
||||
}
|
||||
|
||||
@@ -182,5 +213,6 @@ export const styleVariables = {
|
||||
"--diffs-font-features": "var(--font-family-mono--font-feature-settings)",
|
||||
"--diffs-header-font-family": "var(--font-family-sans)",
|
||||
"--diffs-gap-block": 0,
|
||||
"--diffs-min-number-column-width": "4ch",
|
||||
"--diffs-gap-style": 0,
|
||||
"--diffs-min-number-column-width": "3ch",
|
||||
}
|
||||
|
||||
@@ -151,7 +151,10 @@ export function createLineCommentControllerV2<T extends LineCommentShape>(props:
|
||||
}
|
||||
: undefined
|
||||
},
|
||||
onMouseEnter: () => note.hoverComment(comment.selection),
|
||||
onMouseEnter: () => {
|
||||
if (note.commenting()) return
|
||||
note.hoverComment(comment.selection)
|
||||
},
|
||||
onClick: () => {
|
||||
if (note.isEditing(comment.id)) return
|
||||
note.toggleComment(comment.id, comment.selection)
|
||||
@@ -164,10 +167,14 @@ export function createLineCommentControllerV2<T extends LineCommentShape>(props:
|
||||
},
|
||||
selection: formatSelectedLineLabel(range, i18n.t),
|
||||
onInput: note.setDraft,
|
||||
onCancel: note.cancelDraft,
|
||||
onCancel: () => {
|
||||
note.cancelDraft()
|
||||
note.select(null)
|
||||
},
|
||||
onSubmit: (comment) => {
|
||||
props.onSubmit({ comment, selection: cloneSelectedLineRange(range) })
|
||||
note.cancelDraft()
|
||||
note.select(null)
|
||||
},
|
||||
cancelLabel: i18n.t("ui.lineComment.cancel"),
|
||||
submitLabel: i18n.t("ui.lineComment.submit"),
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@opencode-ai/slack",
|
||||
"version": "1.18.11",
|
||||
"version": "1.18.12",
|
||||
"type": "module",
|
||||
"license": "MIT",
|
||||
"scripts": {
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
{
|
||||
"$schema": "https://json.schemastore.org/package.json",
|
||||
"name": "@opencode-ai/stats-app",
|
||||
"version": "1.18.11",
|
||||
"version": "1.18.12",
|
||||
"private": true,
|
||||
"type": "module",
|
||||
"license": "MIT",
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
{
|
||||
"$schema": "https://json.schemastore.org/package.json",
|
||||
"name": "@opencode-ai/stats-core",
|
||||
"version": "1.18.11",
|
||||
"version": "1.18.12",
|
||||
"private": true,
|
||||
"type": "module",
|
||||
"license": "MIT",
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
{
|
||||
"$schema": "https://json.schemastore.org/package.json",
|
||||
"name": "@opencode-ai/stats-server",
|
||||
"version": "1.18.11",
|
||||
"version": "1.18.12",
|
||||
"private": true,
|
||||
"type": "module",
|
||||
"license": "MIT",
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
{
|
||||
"$schema": "https://json.schemastore.org/package.json",
|
||||
"name": "@opencode-ai/tui",
|
||||
"version": "1.18.11",
|
||||
"version": "1.18.12",
|
||||
"private": true,
|
||||
"type": "module",
|
||||
"license": "MIT",
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@opencode-ai/ui",
|
||||
"version": "1.18.11",
|
||||
"version": "1.18.12",
|
||||
"type": "module",
|
||||
"license": "MIT",
|
||||
"repository": {
|
||||
|
||||
@@ -1,8 +1,3 @@
|
||||
<svg width="24" height="24" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<path d="M3.10913 12.07C3.65512 12.07 5.76627 11.5988 6.85825 10.98C7.95023 10.3612 7.95023 10.3612 10.207 8.75965C13.0642 6.73196 15.0845 7.41088 18.3968 7.41088" fill="currentColor"/>
|
||||
<path d="M3.10913 12.07C3.65512 12.07 5.76627 11.5988 6.85825 10.98C7.95023 10.3612 7.95023 10.3612 10.207 8.75965C13.0642 6.73196 15.0845 7.41088 18.3968 7.41088" stroke="currentColor" stroke-width="3.27593"/>
|
||||
<path d="M21.6 7.43108L16.0037 10.6622V4.20001L21.6 7.43108Z" fill="currentColor" stroke="currentColor" stroke-width="0.0363992"/>
|
||||
<path d="M3 12.072C3.54599 12.072 5.65714 12.5432 6.74912 13.162C7.8411 13.7808 7.8411 13.7808 10.0978 15.3823C12.9551 17.41 14.9753 16.7311 18.2877 16.7311" fill="currentColor"/>
|
||||
<path d="M3 12.072C3.54599 12.072 5.65714 12.5432 6.74912 13.162C7.8411 13.7808 7.8411 13.7808 10.0978 15.3823C12.9551 17.41 14.9753 16.7311 18.2877 16.7311" stroke="currentColor" stroke-width="3.27593"/>
|
||||
<path d="M21.4909 16.7109L15.8945 13.4798V19.942L21.4909 16.7109Z" fill="currentColor" stroke="currentColor" stroke-width="0.0363992"/>
|
||||
<path d="M728.039 234C819.325 234 893.323 308.62 893.323 400.668C893.323 492.716 819.325 567.336 728.039 567.336L891.984 732.656C912.81 753.655 898.061 789.56 868.613 789.56H397.472C245.333 789.56 122 665.193 122 511.78C122 358.367 245.333 234 397.472 234H728.039ZM397.472 345.112C306.189 345.112 232.189 419.732 232.189 511.78C232.189 603.828 306.189 678.448 397.472 678.448C488.756 678.448 562.756 603.828 562.756 511.78C562.756 419.732 488.756 345.112 397.472 345.112Z" fill="currentColor" transform="scale(0.0234375)"/>
|
||||
</svg>
|
||||
|
||||
|
Before Width: | Height: | Size: 1.1 KiB After Width: | Height: | Size: 627 B |
@@ -366,34 +366,9 @@
|
||||
</symbol>
|
||||
<symbol viewBox="0 0 24 24" fill="none" id="openrouter">
|
||||
<path
|
||||
d="M3.10913 12.07C3.65512 12.07 5.76627 11.5988 6.85825 10.98C7.95023 10.3612 7.95023 10.3612 10.207 8.75965C13.0642 6.73196 15.0845 7.41088 18.3968 7.41088"
|
||||
d="M728.039 234C819.325 234 893.323 308.62 893.323 400.668C893.323 492.716 819.325 567.336 728.039 567.336L891.984 732.656C912.81 753.655 898.061 789.56 868.613 789.56H397.472C245.333 789.56 122 665.193 122 511.78C122 358.367 245.333 234 397.472 234H728.039ZM397.472 345.112C306.189 345.112 232.189 419.732 232.189 511.78C232.189 603.828 306.189 678.448 397.472 678.448C488.756 678.448 562.756 603.828 562.756 511.78C562.756 419.732 488.756 345.112 397.472 345.112Z"
|
||||
fill="currentColor"
|
||||
></path>
|
||||
<path
|
||||
d="M3.10913 12.07C3.65512 12.07 5.76627 11.5988 6.85825 10.98C7.95023 10.3612 7.95023 10.3612 10.207 8.75965C13.0642 6.73196 15.0845 7.41088 18.3968 7.41088"
|
||||
stroke="currentColor"
|
||||
stroke-width="3.27593"
|
||||
></path>
|
||||
<path
|
||||
d="M21.6 7.43108L16.0037 10.6622V4.20001L21.6 7.43108Z"
|
||||
fill="currentColor"
|
||||
stroke="currentColor"
|
||||
stroke-width="0.0363992"
|
||||
></path>
|
||||
<path
|
||||
d="M3 12.072C3.54599 12.072 5.65714 12.5432 6.74912 13.162C7.8411 13.7808 7.8411 13.7808 10.0978 15.3823C12.9551 17.41 14.9753 16.7311 18.2877 16.7311"
|
||||
fill="currentColor"
|
||||
></path>
|
||||
<path
|
||||
d="M3 12.072C3.54599 12.072 5.65714 12.5432 6.74912 13.162C7.8411 13.7808 7.8411 13.7808 10.0978 15.3823C12.9551 17.41 14.9753 16.7311 18.2877 16.7311"
|
||||
stroke="currentColor"
|
||||
stroke-width="3.27593"
|
||||
></path>
|
||||
<path
|
||||
d="M21.4909 16.7109L15.8945 13.4798V19.942L21.4909 16.7109Z"
|
||||
fill="currentColor"
|
||||
stroke="currentColor"
|
||||
stroke-width="0.0363992"
|
||||
transform="scale(0.0234375)"
|
||||
></path>
|
||||
</symbol>
|
||||
<symbol viewBox="0 0 24 24" fill="none" id="opencode">
|
||||
|
||||
|
Before Width: | Height: | Size: 276 KiB After Width: | Height: | Size: 275 KiB |
@@ -41,7 +41,8 @@
|
||||
"syntax-type": "var(--v2-purple-800)",
|
||||
"syntax-constant": "#007b80",
|
||||
"syntax-critical": "var(--v2-red-800)",
|
||||
"syntax-diff-delete": "#ff8c00",
|
||||
"syntax-diff-add": "var(--v2-state-fg-success)",
|
||||
"syntax-diff-delete": "var(--v2-state-fg-danger)",
|
||||
"syntax-diff-unknown": "#a753ae",
|
||||
"surface-critical-base": "#FFF2F0"
|
||||
},
|
||||
@@ -275,7 +276,8 @@
|
||||
"syntax-type": "var(--v2-purple-400)",
|
||||
"syntax-constant": "#93e9f6",
|
||||
"syntax-critical": "var(--v2-red-400)",
|
||||
"syntax-diff-delete": "#fab283",
|
||||
"syntax-diff-add": "var(--v2-state-fg-success)",
|
||||
"syntax-diff-delete": "var(--v2-state-fg-danger)",
|
||||
"syntax-diff-unknown": "#edb2f1",
|
||||
"surface-critical-base": "#1F0603"
|
||||
},
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
"name": "@opencode-ai/web",
|
||||
"type": "module",
|
||||
"license": "MIT",
|
||||
"version": "1.18.11",
|
||||
"version": "1.18.12",
|
||||
"scripts": {
|
||||
"dev": "astro dev",
|
||||
"dev:remote": "VITE_API_URL=https://api.opencode.ai astro dev",
|
||||
|
||||
@@ -2244,9 +2244,9 @@ Some useful routing options:
|
||||
|
||||
### xAI
|
||||
|
||||
Three ways to authenticate: a SuperGrok subscription via browser OAuth, the same SuperGrok subscription via a headless device-code flow (for VPS / SSH / Docker), or a pay-as-you-go API key from the xAI console.
|
||||
Three ways to authenticate: a SuperGrok subscription via device-code OAuth, the same SuperGrok subscription via a local callback, or a pay-as-you-go API key from the xAI console.
|
||||
|
||||
#### Option A — SuperGrok OAuth (browser login)
|
||||
#### Option A — SuperGrok OAuth
|
||||
|
||||
1. Run the `/connect` command and search for **xAI**.
|
||||
|
||||
@@ -2254,9 +2254,11 @@ Three ways to authenticate: a SuperGrok subscription via browser OAuth, the same
|
||||
/connect
|
||||
```
|
||||
|
||||
2. Select **xAI Grok OAuth (SuperGrok Subscription)**. OpenCode opens xAI's consent screen in your browser and waits for the callback on `http://127.0.0.1:56121/callback`.
|
||||
2. Select **xAI Grok OAuth (SuperGrok Subscription)**. OpenCode prints a verification URL and a short user code.
|
||||
|
||||
3. Run the `/models` command to select a Grok model.
|
||||
3. Open the URL, enter the code, and approve the consent screen. OpenCode polls xAI's token endpoint and stores the resulting OAuth tokens once you approve.
|
||||
|
||||
4. Run the `/models` command to select a Grok model.
|
||||
|
||||
```txt
|
||||
/models
|
||||
@@ -2264,23 +2266,17 @@ Three ways to authenticate: a SuperGrok subscription via browser OAuth, the same
|
||||
|
||||
OpenCode refreshes the OAuth access token automatically. Any Grok or X Premium plan that includes Grok API access works; you do not need a separate `XAI_API_KEY`.
|
||||
|
||||
#### Option B — SuperGrok device-code (headless / remote server / VPS)
|
||||
#### Option B — SuperGrok local callback
|
||||
|
||||
Use this when OpenCode is running somewhere a browser can't reach the loopback redirect: a VPS, a remote dev box over SSH, inside Docker, in CI, etc. No callback port is opened on the host running OpenCode — instead xAI hands the CLI a short code that you type into a browser on any other device (laptop, phone, …).
|
||||
Use this only if you prefer a local browser callback and the browser can reach OpenCode on the same machine.
|
||||
|
||||
1. Run the `/connect` command on the remote host and search for **xAI**.
|
||||
1. Run the `/connect` command and search for **xAI**.
|
||||
|
||||
```txt
|
||||
/connect
|
||||
```
|
||||
|
||||
2. Select **xAI Grok OAuth (Headless / Remote / VPS)**. OpenCode prints a verification URL and a short user code.
|
||||
|
||||
```txt
|
||||
Open https://x.ai/device on any device and enter code: ABCD-1234
|
||||
```
|
||||
|
||||
3. Open the URL on a device that has a browser (your laptop or phone), enter the code, and approve the consent screen. OpenCode polls xAI's token endpoint and stores the resulting OAuth tokens once you approve. Token refresh works the same as Option A.
|
||||
2. Select **xAI Grok OAuth (Local Callback)**. OpenCode opens xAI's consent screen and waits for the callback on `http://127.0.0.1:56121/callback`. Token refresh works the same as Option A.
|
||||
|
||||
#### Option C — API key
|
||||
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
"name": "opencode",
|
||||
"displayName": "opencode",
|
||||
"description": "opencode for VS Code",
|
||||
"version": "1.18.11",
|
||||
"version": "1.18.12",
|
||||
"publisher": "sst-dev",
|
||||
"repository": {
|
||||
"type": "git",
|
||||
|
||||
Reference in New Issue
Block a user