mirror of
https://github.com/aljazceru/opencode.git
synced 2026-01-07 01:44:56 +01:00
Merge branch 'dev' of https://github.com/sst/opencode into dev
This commit is contained in:
42
bun.lock
42
bun.lock
@@ -39,7 +39,7 @@
|
|||||||
},
|
},
|
||||||
"packages/console/core": {
|
"packages/console/core": {
|
||||||
"name": "@opencode-ai/console-core",
|
"name": "@opencode-ai/console-core",
|
||||||
"version": "1.0.20",
|
"version": "1.0.23",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@aws-sdk/client-sts": "3.782.0",
|
"@aws-sdk/client-sts": "3.782.0",
|
||||||
"@jsx-email/render": "1.1.1",
|
"@jsx-email/render": "1.1.1",
|
||||||
@@ -66,7 +66,7 @@
|
|||||||
},
|
},
|
||||||
"packages/console/function": {
|
"packages/console/function": {
|
||||||
"name": "@opencode-ai/console-function",
|
"name": "@opencode-ai/console-function",
|
||||||
"version": "1.0.20",
|
"version": "1.0.23",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@ai-sdk/anthropic": "2.0.0",
|
"@ai-sdk/anthropic": "2.0.0",
|
||||||
"@ai-sdk/openai": "2.0.2",
|
"@ai-sdk/openai": "2.0.2",
|
||||||
@@ -90,7 +90,7 @@
|
|||||||
},
|
},
|
||||||
"packages/console/mail": {
|
"packages/console/mail": {
|
||||||
"name": "@opencode-ai/console-mail",
|
"name": "@opencode-ai/console-mail",
|
||||||
"version": "1.0.20",
|
"version": "1.0.23",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@jsx-email/all": "2.2.3",
|
"@jsx-email/all": "2.2.3",
|
||||||
"@jsx-email/cli": "1.4.3",
|
"@jsx-email/cli": "1.4.3",
|
||||||
@@ -111,7 +111,7 @@
|
|||||||
},
|
},
|
||||||
"packages/desktop": {
|
"packages/desktop": {
|
||||||
"name": "@opencode-ai/desktop",
|
"name": "@opencode-ai/desktop",
|
||||||
"version": "1.0.20",
|
"version": "1.0.23",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@kobalte/core": "catalog:",
|
"@kobalte/core": "catalog:",
|
||||||
"@opencode-ai/sdk": "workspace:*",
|
"@opencode-ai/sdk": "workspace:*",
|
||||||
@@ -150,7 +150,7 @@
|
|||||||
},
|
},
|
||||||
"packages/function": {
|
"packages/function": {
|
||||||
"name": "@opencode-ai/function",
|
"name": "@opencode-ai/function",
|
||||||
"version": "1.0.20",
|
"version": "1.0.23",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@octokit/auth-app": "8.0.1",
|
"@octokit/auth-app": "8.0.1",
|
||||||
"@octokit/rest": "22.0.0",
|
"@octokit/rest": "22.0.0",
|
||||||
@@ -166,7 +166,7 @@
|
|||||||
},
|
},
|
||||||
"packages/opencode": {
|
"packages/opencode": {
|
||||||
"name": "opencode",
|
"name": "opencode",
|
||||||
"version": "1.0.20",
|
"version": "1.0.23",
|
||||||
"bin": {
|
"bin": {
|
||||||
"opencode": "./bin/opencode",
|
"opencode": "./bin/opencode",
|
||||||
},
|
},
|
||||||
@@ -184,8 +184,8 @@
|
|||||||
"@opencode-ai/plugin": "workspace:*",
|
"@opencode-ai/plugin": "workspace:*",
|
||||||
"@opencode-ai/script": "workspace:*",
|
"@opencode-ai/script": "workspace:*",
|
||||||
"@opencode-ai/sdk": "workspace:*",
|
"@opencode-ai/sdk": "workspace:*",
|
||||||
"@opentui/core": "0.1.34",
|
"@opentui/core": "0.1.33",
|
||||||
"@opentui/solid": "0.1.34",
|
"@opentui/solid": "0.1.33",
|
||||||
"@parcel/watcher": "2.5.1",
|
"@parcel/watcher": "2.5.1",
|
||||||
"@pierre/precision-diffs": "catalog:",
|
"@pierre/precision-diffs": "catalog:",
|
||||||
"@solid-primitives/event-bus": "1.1.2",
|
"@solid-primitives/event-bus": "1.1.2",
|
||||||
@@ -243,7 +243,7 @@
|
|||||||
},
|
},
|
||||||
"packages/plugin": {
|
"packages/plugin": {
|
||||||
"name": "@opencode-ai/plugin",
|
"name": "@opencode-ai/plugin",
|
||||||
"version": "1.0.20",
|
"version": "1.0.23",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@opencode-ai/sdk": "workspace:*",
|
"@opencode-ai/sdk": "workspace:*",
|
||||||
"zod": "catalog:",
|
"zod": "catalog:",
|
||||||
@@ -263,7 +263,7 @@
|
|||||||
},
|
},
|
||||||
"packages/sdk/js": {
|
"packages/sdk/js": {
|
||||||
"name": "@opencode-ai/sdk",
|
"name": "@opencode-ai/sdk",
|
||||||
"version": "1.0.20",
|
"version": "1.0.23",
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@hey-api/openapi-ts": "0.81.0",
|
"@hey-api/openapi-ts": "0.81.0",
|
||||||
"@tsconfig/node22": "catalog:",
|
"@tsconfig/node22": "catalog:",
|
||||||
@@ -274,7 +274,7 @@
|
|||||||
},
|
},
|
||||||
"packages/slack": {
|
"packages/slack": {
|
||||||
"name": "@opencode-ai/slack",
|
"name": "@opencode-ai/slack",
|
||||||
"version": "1.0.20",
|
"version": "1.0.23",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@opencode-ai/sdk": "workspace:*",
|
"@opencode-ai/sdk": "workspace:*",
|
||||||
"@slack/bolt": "^3.17.1",
|
"@slack/bolt": "^3.17.1",
|
||||||
@@ -287,7 +287,7 @@
|
|||||||
},
|
},
|
||||||
"packages/ui": {
|
"packages/ui": {
|
||||||
"name": "@opencode-ai/ui",
|
"name": "@opencode-ai/ui",
|
||||||
"version": "1.0.20",
|
"version": "1.0.23",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@kobalte/core": "catalog:",
|
"@kobalte/core": "catalog:",
|
||||||
"@opencode-ai/sdk": "workspace:*",
|
"@opencode-ai/sdk": "workspace:*",
|
||||||
@@ -317,7 +317,7 @@
|
|||||||
},
|
},
|
||||||
"packages/web": {
|
"packages/web": {
|
||||||
"name": "@opencode-ai/web",
|
"name": "@opencode-ai/web",
|
||||||
"version": "1.0.20",
|
"version": "1.0.23",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@astrojs/cloudflare": "12.6.3",
|
"@astrojs/cloudflare": "12.6.3",
|
||||||
"@astrojs/markdown-remark": "6.3.1",
|
"@astrojs/markdown-remark": "6.3.1",
|
||||||
@@ -961,21 +961,21 @@
|
|||||||
|
|
||||||
"@opentelemetry/api": ["@opentelemetry/api@1.9.0", "", {}, "sha512-3giAOQvZiH5F9bMlMiv8+GSPMeqg0dbaeo58/0SlA9sxSqZhnUtxzX9/2FzyhS9sWQf5S0GJE0AKBrFqjpeYcg=="],
|
"@opentelemetry/api": ["@opentelemetry/api@1.9.0", "", {}, "sha512-3giAOQvZiH5F9bMlMiv8+GSPMeqg0dbaeo58/0SlA9sxSqZhnUtxzX9/2FzyhS9sWQf5S0GJE0AKBrFqjpeYcg=="],
|
||||||
|
|
||||||
"@opentui/core": ["@opentui/core@0.1.34", "", { "dependencies": { "bun-ffi-structs": "^0.1.0", "jimp": "1.6.0", "yoga-layout": "3.2.1" }, "optionalDependencies": { "@dimforge/rapier2d-simd-compat": "^0.17.3", "@opentui/core-darwin-arm64": "0.1.34", "@opentui/core-darwin-x64": "0.1.34", "@opentui/core-linux-arm64": "0.1.34", "@opentui/core-linux-x64": "0.1.34", "@opentui/core-win32-arm64": "0.1.34", "@opentui/core-win32-x64": "0.1.34", "bun-webgpu": "0.1.3", "planck": "^1.4.2", "three": "0.177.0" }, "peerDependencies": { "web-tree-sitter": "0.25.10" } }, "sha512-rsqEbHXIFL6JEZs/2dCHn7efnJaGByqpI3mMtt+cJvyt7ZiGU9y+JwryFb9rE8KZMtwsUWN1ECz58ufy6iJvzA=="],
|
"@opentui/core": ["@opentui/core@0.1.33", "", { "dependencies": { "bun-ffi-structs": "^0.1.0", "jimp": "1.6.0", "yoga-layout": "3.2.1" }, "optionalDependencies": { "@dimforge/rapier2d-simd-compat": "^0.17.3", "@opentui/core-darwin-arm64": "0.1.33", "@opentui/core-darwin-x64": "0.1.33", "@opentui/core-linux-arm64": "0.1.33", "@opentui/core-linux-x64": "0.1.33", "@opentui/core-win32-arm64": "0.1.33", "@opentui/core-win32-x64": "0.1.33", "bun-webgpu": "0.1.3", "planck": "^1.4.2", "three": "0.177.0" }, "peerDependencies": { "web-tree-sitter": "0.25.10" } }, "sha512-vwHdrPIqnsY6YnG2JTNhenHSsx+HUPYrQTBZdmEfCj9ROGVzKgUKbSDH1xGK2OtSNRb2KVBg4XaMpq0bie6afQ=="],
|
||||||
|
|
||||||
"@opentui/core-darwin-arm64": ["@opentui/core-darwin-arm64@0.1.34", "", { "os": "darwin", "cpu": "arm64" }, "sha512-P/Pw66vJ1W5pIVg7D5bUlMPBTarXh0S/conHRaeybBZoO+8G04A6x9ufeaD/L4HCE0iR0huSoHGDB1VxZUL2Zg=="],
|
"@opentui/core-darwin-arm64": ["@opentui/core-darwin-arm64@0.1.33", "", { "os": "darwin", "cpu": "arm64" }, "sha512-JBvzcP2V7fT9KxFAMenHRd/t72qPP5IL5kzge2uok1T7t2nw3Wa+CWI5s6FYP42p2b1W9qZkv5Fno5gA7OAYuQ=="],
|
||||||
|
|
||||||
"@opentui/core-darwin-x64": ["@opentui/core-darwin-x64@0.1.34", "", { "os": "darwin", "cpu": "x64" }, "sha512-JKfDC2qI1AmY4u504FKfrSdP0qOJIn+rI7kj0C0ydpvj1Wd2c6ImOsbnny70372Uq/m3EXxPE3Hq/66DL4P94A=="],
|
"@opentui/core-darwin-x64": ["@opentui/core-darwin-x64@0.1.33", "", { "os": "darwin", "cpu": "x64" }, "sha512-x7DY6VCkAky10z/2o4UkkuNW/nIvoX7uAh3dJOHWZCLbiKywSFvFk3QZVVcH5BMk4tOOophYTzika4s4HpaeMg=="],
|
||||||
|
|
||||||
"@opentui/core-linux-arm64": ["@opentui/core-linux-arm64@0.1.34", "", { "os": "linux", "cpu": "arm64" }, "sha512-E1xAuz0xx7lmh7tZmexP/4Aceyzmpuo4c9UoNd844Aweu/AlmjsmaOMOBLA77I94RSbEuGKJt9WAPyiSZbgwVw=="],
|
"@opentui/core-linux-arm64": ["@opentui/core-linux-arm64@0.1.33", "", { "os": "linux", "cpu": "arm64" }, "sha512-bBc1EdkVxsLBtqGjXM2BYpBJLa57ogcrSADSZbc5cQkPu0muSGzUwBbVnVZJUjWEfk6n5jcd4dDmLezVoQga0A=="],
|
||||||
|
|
||||||
"@opentui/core-linux-x64": ["@opentui/core-linux-x64@0.1.34", "", { "os": "linux", "cpu": "x64" }, "sha512-VZxgdOUR8h2l3LUPex0A02pLsw9+P4RouL7sJ2Ul/sXvvi/b2ptzJvGQluynV6yHa2etYklZWDyWyMJmF8OKzw=="],
|
"@opentui/core-linux-x64": ["@opentui/core-linux-x64@0.1.33", "", { "os": "linux", "cpu": "x64" }, "sha512-3oVL5mrLlKLUc1lc4v7xS3BJ9N7PnnimbGwAvlnVpfaAygotAs1XkPcjsUe6ItMnSJyi0FWiDHUE2+GiDtM5Nw=="],
|
||||||
|
|
||||||
"@opentui/core-win32-arm64": ["@opentui/core-win32-arm64@0.1.34", "", { "os": "win32", "cpu": "arm64" }, "sha512-4HXGcYdAHodhm0VnL3nn9uYFvmUhKHiN2vSMDy5KO2NZ49O1IXcS001g/TKryv0hcK1kIUBkq+RH/0vrieCAJw=="],
|
"@opentui/core-win32-arm64": ["@opentui/core-win32-arm64@0.1.33", "", { "os": "win32", "cpu": "arm64" }, "sha512-Q68v7wssE+r0OG1KIGfi7m3fnu8KOK4ZNg9ML6EwE47VF9/bqgUe+6fPiXh5mmHzTwof7nAOdXCf052av5/upQ=="],
|
||||||
|
|
||||||
"@opentui/core-win32-x64": ["@opentui/core-win32-x64@0.1.34", "", { "os": "win32", "cpu": "x64" }, "sha512-ptuIL6QO7LVFGI6ouZ01fw+AQfjJC+DURjsqiQhoaS/iunFefZY0q83V7ZWgv0nYlhRm+E2yWjRNNzCySJlTaQ=="],
|
"@opentui/core-win32-x64": ["@opentui/core-win32-x64@0.1.33", "", { "os": "win32", "cpu": "x64" }, "sha512-PvuchmUnbMCUXXMzfle/WTzhNGIdJ6RGCCoclx3YVUyNUVuUicPf42OEV+td2m81/Hr3CgcLn98HYX1TLIzPrw=="],
|
||||||
|
|
||||||
"@opentui/solid": ["@opentui/solid@0.1.34", "", { "dependencies": { "@babel/core": "7.28.0", "@babel/preset-typescript": "7.27.1", "@opentui/core": "0.1.34", "babel-plugin-module-resolver": "5.0.2", "babel-preset-solid": "1.9.9", "s-js": "^0.4.9" }, "peerDependencies": { "solid-js": "1.9.9" } }, "sha512-GPT+EeC6vcDnb4aUJ2K4t01GlbNoMZUfMTiIif55JSjXTKURzdDLL4mOhxar1+iJqwubYHEu/nC1GkTiGWIJoQ=="],
|
"@opentui/solid": ["@opentui/solid@0.1.33", "", { "dependencies": { "@babel/core": "7.28.0", "@babel/preset-typescript": "7.27.1", "@opentui/core": "0.1.33", "babel-plugin-module-resolver": "5.0.2", "babel-preset-solid": "1.9.9", "s-js": "^0.4.9" }, "peerDependencies": { "solid-js": "1.9.9" } }, "sha512-bWSALdGJ2j51zwZ2gK1ZIBxFgauHq+V1ejEnyd4XamYMdWfpAKU+AUWDVLbpx1T9XG1oAnycJZfYX7BsZdVOOg=="],
|
||||||
|
|
||||||
"@oslojs/asn1": ["@oslojs/asn1@1.0.0", "", { "dependencies": { "@oslojs/binary": "1.0.0" } }, "sha512-zw/wn0sj0j0QKbIXfIlnEcTviaCzYOY3V5rAyjR6YtOByFtJiT574+8p9Wlach0lZH9fddD4yb9laEAIl4vXQA=="],
|
"@oslojs/asn1": ["@oslojs/asn1@1.0.0", "", { "dependencies": { "@oslojs/binary": "1.0.0" } }, "sha512-zw/wn0sj0j0QKbIXfIlnEcTviaCzYOY3V5rAyjR6YtOByFtJiT574+8p9Wlach0lZH9fddD4yb9laEAIl4vXQA=="],
|
||||||
|
|
||||||
|
|||||||
@@ -7,7 +7,7 @@
|
|||||||
"dev:remote": "VITE_AUTH_URL=https://auth.dev.opencode.ai bun sst shell --stage=dev bun dev",
|
"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",
|
"build": "vinxi build && ../../opencode/script/schema.ts ./.output/public/config.json",
|
||||||
"start": "vinxi start",
|
"start": "vinxi start",
|
||||||
"version": "1.0.20"
|
"version": "1.0.23"
|
||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@ibm/plex": "6.4.1",
|
"@ibm/plex": "6.4.1",
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
{
|
{
|
||||||
"$schema": "https://json.schemastore.org/package.json",
|
"$schema": "https://json.schemastore.org/package.json",
|
||||||
"name": "@opencode-ai/console-core",
|
"name": "@opencode-ai/console-core",
|
||||||
"version": "1.0.20",
|
"version": "1.0.23",
|
||||||
"private": true,
|
"private": true,
|
||||||
"type": "module",
|
"type": "module",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "@opencode-ai/console-function",
|
"name": "@opencode-ai/console-function",
|
||||||
"version": "1.0.20",
|
"version": "1.0.23",
|
||||||
"$schema": "https://json.schemastore.org/package.json",
|
"$schema": "https://json.schemastore.org/package.json",
|
||||||
"private": true,
|
"private": true,
|
||||||
"type": "module",
|
"type": "module",
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "@opencode-ai/console-mail",
|
"name": "@opencode-ai/console-mail",
|
||||||
"version": "1.0.20",
|
"version": "1.0.23",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@jsx-email/all": "2.2.3",
|
"@jsx-email/all": "2.2.3",
|
||||||
"@jsx-email/cli": "1.4.3",
|
"@jsx-email/cli": "1.4.3",
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "@opencode-ai/desktop",
|
"name": "@opencode-ai/desktop",
|
||||||
"version": "1.0.20",
|
"version": "1.0.23",
|
||||||
"description": "",
|
"description": "",
|
||||||
"type": "module",
|
"type": "module",
|
||||||
"scripts": {
|
"scripts": {
|
||||||
|
|||||||
@@ -12,7 +12,9 @@ import Home from "@/pages"
|
|||||||
const host = import.meta.env.VITE_OPENCODE_SERVER_HOST ?? "127.0.0.1"
|
const host = import.meta.env.VITE_OPENCODE_SERVER_HOST ?? "127.0.0.1"
|
||||||
const port = import.meta.env.VITE_OPENCODE_SERVER_PORT ?? "4096"
|
const port = import.meta.env.VITE_OPENCODE_SERVER_PORT ?? "4096"
|
||||||
|
|
||||||
const url = new URLSearchParams(document.location.search).get("url") || `http://${host}:${port}`
|
const url =
|
||||||
|
new URLSearchParams(document.location.search).get("url") ||
|
||||||
|
(location.hostname.includes("opencode.ai") ? `http://${host}:${port}` : "/")
|
||||||
|
|
||||||
const root = document.getElementById("root")
|
const root = document.getElementById("root")
|
||||||
if (import.meta.env.DEV && !(root instanceof HTMLElement)) {
|
if (import.meta.env.DEV && !(root instanceof HTMLElement)) {
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "@opencode-ai/function",
|
"name": "@opencode-ai/function",
|
||||||
"version": "1.0.20",
|
"version": "1.0.23",
|
||||||
"$schema": "https://json.schemastore.org/package.json",
|
"$schema": "https://json.schemastore.org/package.json",
|
||||||
"private": true,
|
"private": true,
|
||||||
"type": "module",
|
"type": "module",
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"$schema": "https://json.schemastore.org/package.json",
|
"$schema": "https://json.schemastore.org/package.json",
|
||||||
"version": "1.0.20",
|
"version": "1.0.23",
|
||||||
"name": "opencode",
|
"name": "opencode",
|
||||||
"type": "module",
|
"type": "module",
|
||||||
"private": true,
|
"private": true,
|
||||||
@@ -54,8 +54,8 @@
|
|||||||
"@opencode-ai/plugin": "workspace:*",
|
"@opencode-ai/plugin": "workspace:*",
|
||||||
"@opencode-ai/script": "workspace:*",
|
"@opencode-ai/script": "workspace:*",
|
||||||
"@opencode-ai/sdk": "workspace:*",
|
"@opencode-ai/sdk": "workspace:*",
|
||||||
"@opentui/core": "0.1.34",
|
"@opentui/core": "0.1.33",
|
||||||
"@opentui/solid": "0.1.34",
|
"@opentui/solid": "0.1.33",
|
||||||
"@parcel/watcher": "2.5.1",
|
"@parcel/watcher": "2.5.1",
|
||||||
"@solid-primitives/event-bus": "1.1.2",
|
"@solid-primitives/event-bus": "1.1.2",
|
||||||
"@pierre/precision-diffs": "catalog:",
|
"@pierre/precision-diffs": "catalog:",
|
||||||
|
|||||||
@@ -10,6 +10,7 @@ export namespace Auth {
|
|||||||
refresh: z.string(),
|
refresh: z.string(),
|
||||||
access: z.string(),
|
access: z.string(),
|
||||||
expires: z.number(),
|
expires: z.number(),
|
||||||
|
enterpriseUrl: z.string().optional(),
|
||||||
})
|
})
|
||||||
.meta({ ref: "OAuth" })
|
.meta({ ref: "OAuth" })
|
||||||
|
|
||||||
|
|||||||
@@ -102,178 +102,223 @@ export const AuthLoginCommand = cmd({
|
|||||||
prompts.outro("Done")
|
prompts.outro("Done")
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
await ModelsDev.refresh().catch(() => {})
|
await ModelsDev.refresh().catch(() => {})
|
||||||
const providers = await ModelsDev.get()
|
const providers = await ModelsDev.get()
|
||||||
const priority: Record<string, number> = {
|
const priority: Record<string, number> = {
|
||||||
opencode: 0,
|
opencode: 0,
|
||||||
anthropic: 1,
|
anthropic: 1,
|
||||||
"github-copilot": 2,
|
"github-copilot": 2,
|
||||||
openai: 3,
|
openai: 3,
|
||||||
google: 4,
|
google: 4,
|
||||||
openrouter: 5,
|
openrouter: 5,
|
||||||
vercel: 6,
|
vercel: 6,
|
||||||
}
|
}
|
||||||
let provider = await prompts.autocomplete({
|
let provider = await prompts.autocomplete({
|
||||||
message: "Select provider",
|
message: "Select provider",
|
||||||
maxItems: 8,
|
maxItems: 8,
|
||||||
options: [
|
options: [
|
||||||
...pipe(
|
...pipe(
|
||||||
providers,
|
providers,
|
||||||
values(),
|
values(),
|
||||||
sortBy(
|
sortBy(
|
||||||
(x) => priority[x.id] ?? 99,
|
(x) => priority[x.id] ?? 99,
|
||||||
(x) => x.name ?? x.id,
|
(x) => x.name ?? x.id,
|
||||||
),
|
|
||||||
map((x) => ({
|
|
||||||
label: x.name,
|
|
||||||
value: x.id,
|
|
||||||
hint: priority[x.id] <= 1 ? "recommended" : undefined,
|
|
||||||
})),
|
|
||||||
),
|
),
|
||||||
{
|
map((x) => ({
|
||||||
value: "other",
|
label: x.name,
|
||||||
label: "Other",
|
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))
|
const plugin = await Plugin.list().then((x) => x.find((x) => x.auth?.provider === provider))
|
||||||
if (plugin && plugin.auth) {
|
if (plugin && plugin.auth) {
|
||||||
let index = 0
|
let index = 0
|
||||||
if (plugin.auth.methods.length > 1) {
|
if (plugin.auth.methods.length > 1) {
|
||||||
const method = await prompts.select({
|
const method = await prompts.select({
|
||||||
message: "Login method",
|
message: "Login method",
|
||||||
options: [
|
options: [
|
||||||
...plugin.auth.methods.map((x, index) => ({
|
...plugin.auth.methods.map((x, index) => ({
|
||||||
label: x.label,
|
label: x.label,
|
||||||
value: index.toString(),
|
value: index.toString(),
|
||||||
})),
|
})),
|
||||||
],
|
],
|
||||||
})
|
})
|
||||||
if (prompts.isCancel(method)) throw new UI.CancelledError()
|
if (prompts.isCancel(method)) throw new UI.CancelledError()
|
||||||
index = parseInt(method)
|
index = parseInt(method)
|
||||||
}
|
}
|
||||||
const method = plugin.auth.methods[index]
|
const method = plugin.auth.methods[index]
|
||||||
if (method.type === "oauth") {
|
|
||||||
await new Promise((resolve) => setTimeout(resolve, 10))
|
|
||||||
const authorize = await method.authorize()
|
|
||||||
|
|
||||||
if (authorize.url) {
|
// Handle prompts for all auth types
|
||||||
prompts.log.info("Go to: " + authorize.url)
|
await new Promise((resolve) => setTimeout(resolve, 10))
|
||||||
|
const inputs: Record<string, string> = {}
|
||||||
|
if (method.prompts) {
|
||||||
|
for (const prompt of method.prompts) {
|
||||||
|
if (prompt.condition && !prompt.condition(inputs)) {
|
||||||
|
continue
|
||||||
}
|
}
|
||||||
|
if (prompt.type === "select") {
|
||||||
if (authorize.method === "auto") {
|
const value = await prompts.select({
|
||||||
if (authorize.instructions) {
|
message: prompt.message,
|
||||||
prompts.log.info(authorize.instructions)
|
options: prompt.options,
|
||||||
}
|
|
||||||
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") {
|
|
||||||
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 (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()
|
if (prompts.isCancel(value)) throw new UI.CancelledError()
|
||||||
const result = await authorize.callback(code)
|
inputs[prompt.key] = value
|
||||||
if (result.type === "failed") {
|
} else {
|
||||||
prompts.log.error("Failed to authorize")
|
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 (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 ("key" in result) {
|
||||||
if ("refresh" in result) {
|
await Auth.set(saveProvider, {
|
||||||
await Auth.set(provider, {
|
type: "api",
|
||||||
type: "oauth",
|
key: result.key,
|
||||||
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")
|
|
||||||
}
|
}
|
||||||
|
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 (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 ("key" in result) {
|
||||||
|
await Auth.set(saveProvider, {
|
||||||
|
type: "api",
|
||||||
|
key: result.key,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
prompts.log.success("Login successful")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
prompts.outro("Done")
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
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")
|
prompts.outro("Done")
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (provider === "other") {
|
if (provider === "other") {
|
||||||
provider = await prompts.text({
|
provider = await prompts.text({
|
||||||
message: "Enter provider id",
|
message: "Enter provider id",
|
||||||
validate: (x) => (x && x.match(/^[0-9a-z-]+$/) ? undefined : "a-z, 0-9 and hyphens only"),
|
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")
|
|
||||||
}
|
|
||||||
|
|
||||||
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 (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")
|
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")
|
||||||
},
|
},
|
||||||
})
|
})
|
||||||
},
|
},
|
||||||
|
|||||||
@@ -358,6 +358,7 @@ function App() {
|
|||||||
|
|
||||||
event.on(SessionApi.Event.Deleted.type, (evt) => {
|
event.on(SessionApi.Event.Deleted.type, (evt) => {
|
||||||
if (route.data.type === "session" && route.data.sessionID === evt.properties.info.id) {
|
if (route.data.type === "session" && route.data.sessionID === evt.properties.info.id) {
|
||||||
|
dialog.clear()
|
||||||
route.navigate({ type: "home" })
|
route.navigate({ type: "home" })
|
||||||
toast.show({
|
toast.show({
|
||||||
variant: "info",
|
variant: "info",
|
||||||
|
|||||||
@@ -22,15 +22,16 @@ export type CommandOption = DialogSelectOption & {
|
|||||||
|
|
||||||
function init() {
|
function init() {
|
||||||
const [registrations, setRegistrations] = createSignal<Accessor<CommandOption[]>[]>([])
|
const [registrations, setRegistrations] = createSignal<Accessor<CommandOption[]>[]>([])
|
||||||
|
const [suspendCount, setSuspendCount] = createSignal(0)
|
||||||
const dialog = useDialog()
|
const dialog = useDialog()
|
||||||
const keybind = useKeybind()
|
const keybind = useKeybind()
|
||||||
const options = createMemo(() => {
|
const options = createMemo(() => {
|
||||||
return registrations().flatMap((x) => x())
|
return registrations().flatMap((x) => x())
|
||||||
})
|
})
|
||||||
|
const suspended = () => suspendCount() > 0
|
||||||
|
|
||||||
let keybinds = true
|
|
||||||
useKeyboard((evt) => {
|
useKeyboard((evt) => {
|
||||||
if (!keybinds) return
|
if (suspended()) return
|
||||||
for (const option of options()) {
|
for (const option of options()) {
|
||||||
if (option.keybind && keybind.match(option.keybind, evt)) {
|
if (option.keybind && keybind.match(option.keybind, evt)) {
|
||||||
evt.preventDefault()
|
evt.preventDefault()
|
||||||
@@ -50,8 +51,9 @@ function init() {
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
keybinds(enabled: boolean) {
|
keybinds(enabled: boolean) {
|
||||||
keybinds = enabled
|
setSuspendCount((count) => count + (enabled ? -1 : 1))
|
||||||
},
|
},
|
||||||
|
suspended,
|
||||||
show() {
|
show() {
|
||||||
dialog.replace(() => <DialogCommand options={options()} />)
|
dialog.replace(() => <DialogCommand options={options()} />)
|
||||||
},
|
},
|
||||||
@@ -83,7 +85,10 @@ export function CommandProvider(props: ParentProps) {
|
|||||||
const keybind = useKeybind()
|
const keybind = useKeybind()
|
||||||
|
|
||||||
useKeyboard((evt) => {
|
useKeyboard((evt) => {
|
||||||
if (keybind.match("command_list", evt) && dialog.stack.length === 0) {
|
if (value.suspended()) return
|
||||||
|
if (dialog.stack.length > 0) return
|
||||||
|
if (evt.defaultPrevented) return
|
||||||
|
if (keybind.match("command_list", evt)) {
|
||||||
evt.preventDefault()
|
evt.preventDefault()
|
||||||
dialog.replace(() => <DialogCommand options={value.options} />)
|
dialog.replace(() => <DialogCommand options={value.options} />)
|
||||||
return
|
return
|
||||||
|
|||||||
@@ -72,7 +72,7 @@ export function DialogSessionList() {
|
|||||||
},
|
},
|
||||||
})
|
})
|
||||||
setToDelete(undefined)
|
setToDelete(undefined)
|
||||||
dialog.clear()
|
// dialog.clear()
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
setToDelete(option.value)
|
setToDelete(option.value)
|
||||||
|
|||||||
@@ -54,6 +54,12 @@ export function Autocomplete(props: {
|
|||||||
|
|
||||||
const val = props.input().getTextRange(store.index + 1, props.input().cursorOffset + 1)
|
const val = props.input().getTextRange(store.index + 1, props.input().cursorOffset + 1)
|
||||||
|
|
||||||
|
// If the filter contains a space, hide the autocomplete
|
||||||
|
if (val.includes(" ")) {
|
||||||
|
hide()
|
||||||
|
return undefined
|
||||||
|
}
|
||||||
|
|
||||||
return val
|
return val
|
||||||
})
|
})
|
||||||
|
|
||||||
@@ -373,15 +379,45 @@ export function Autocomplete(props: {
|
|||||||
return store.visible
|
return store.visible
|
||||||
},
|
},
|
||||||
onInput() {
|
onInput() {
|
||||||
if (store.visible && props.input().cursorOffset <= store.index) hide()
|
if (store.visible) {
|
||||||
|
if (props.input().cursorOffset <= store.index) {
|
||||||
|
hide()
|
||||||
|
return
|
||||||
|
}
|
||||||
|
// Check if a space was typed after the trigger character
|
||||||
|
const currentText = props.input().getTextRange(store.index + 1, props.input().cursorOffset + 1)
|
||||||
|
if (currentText.includes(" ")) {
|
||||||
|
hide()
|
||||||
|
}
|
||||||
|
}
|
||||||
},
|
},
|
||||||
onKeyDown(e: KeyEvent) {
|
onKeyDown(e: KeyEvent) {
|
||||||
if (store.visible) {
|
if (store.visible) {
|
||||||
if (e.name === "up") move(-1)
|
const name = e.name?.toLowerCase()
|
||||||
if (e.name === "down") move(1)
|
const ctrlOnly = e.ctrl && !e.meta && !e.shift
|
||||||
if (e.name === "escape") hide()
|
const isNavUp = name === "up" || (ctrlOnly && name === "p")
|
||||||
if (e.name === "return" || e.name === "tab") select()
|
const isNavDown = name === "down" || (ctrlOnly && name === "n")
|
||||||
if (["up", "down", "return", "tab", "escape"].includes(e.name)) e.preventDefault()
|
|
||||||
|
if (isNavUp) {
|
||||||
|
move(-1)
|
||||||
|
e.preventDefault()
|
||||||
|
return
|
||||||
|
}
|
||||||
|
if (isNavDown) {
|
||||||
|
move(1)
|
||||||
|
e.preventDefault()
|
||||||
|
return
|
||||||
|
}
|
||||||
|
if (name === "escape") {
|
||||||
|
hide()
|
||||||
|
e.preventDefault()
|
||||||
|
return
|
||||||
|
}
|
||||||
|
if (name === "return" || name === "tab") {
|
||||||
|
select()
|
||||||
|
e.preventDefault()
|
||||||
|
return
|
||||||
|
}
|
||||||
}
|
}
|
||||||
if (!store.visible) {
|
if (!store.visible) {
|
||||||
if (e.name === "@") {
|
if (e.name === "@") {
|
||||||
|
|||||||
@@ -115,15 +115,11 @@ export function Prompt(props: PromptProps) {
|
|||||||
{
|
{
|
||||||
title: "Clear prompt",
|
title: "Clear prompt",
|
||||||
value: "prompt.clear",
|
value: "prompt.clear",
|
||||||
disabled: true,
|
|
||||||
category: "Prompt",
|
category: "Prompt",
|
||||||
|
disabled: true,
|
||||||
onSelect: (dialog) => {
|
onSelect: (dialog) => {
|
||||||
input.extmarks.clear()
|
input.extmarks.clear()
|
||||||
setStore("prompt", {
|
input.clear()
|
||||||
input: "",
|
|
||||||
parts: [],
|
|
||||||
})
|
|
||||||
setStore("extmarkToPartIndex", new Map())
|
|
||||||
dialog.clear()
|
dialog.clear()
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
@@ -156,16 +152,27 @@ export function Prompt(props: PromptProps) {
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
title: "Interrupt session",
|
||||||
|
value: "session.interrupt",
|
||||||
|
keybind: "session_interrupt",
|
||||||
|
category: "Session",
|
||||||
|
disabled: true,
|
||||||
|
onSelect: (dialog) => {
|
||||||
|
if (!props.sessionID) return
|
||||||
|
sdk.client.session.abort({
|
||||||
|
path: {
|
||||||
|
id: props.sessionID,
|
||||||
|
},
|
||||||
|
})
|
||||||
|
dialog.clear()
|
||||||
|
},
|
||||||
|
},
|
||||||
]
|
]
|
||||||
})
|
})
|
||||||
|
|
||||||
sdk.event.on(TuiEvent.PromptAppend.type, (evt) => {
|
sdk.event.on(TuiEvent.PromptAppend.type, (evt) => {
|
||||||
setStore(
|
input.insertText(evt.properties.text)
|
||||||
"prompt",
|
|
||||||
produce((draft) => {
|
|
||||||
draft.input += evt.properties.text
|
|
||||||
}),
|
|
||||||
)
|
|
||||||
})
|
})
|
||||||
|
|
||||||
createEffect(() => {
|
createEffect(() => {
|
||||||
|
|||||||
@@ -26,12 +26,15 @@ export const WebCommand = cmd({
|
|||||||
port,
|
port,
|
||||||
hostname,
|
hostname,
|
||||||
})
|
})
|
||||||
const url = `https://desktop.dev.opencode.ai?url=${server.url}`
|
|
||||||
UI.empty()
|
UI.empty()
|
||||||
UI.println(UI.logo(" "))
|
UI.println(UI.logo(" "))
|
||||||
UI.empty()
|
UI.empty()
|
||||||
UI.println(UI.Style.TEXT_INFO_BOLD + " Web interface: ", UI.Style.TEXT_NORMAL, url)
|
UI.println(
|
||||||
open(url).catch(() => {})
|
UI.Style.TEXT_INFO_BOLD + " Web interface: ",
|
||||||
|
UI.Style.TEXT_NORMAL,
|
||||||
|
server.url.toString(),
|
||||||
|
)
|
||||||
|
open(server.url.toString()).catch(() => {})
|
||||||
await new Promise(() => {})
|
await new Promise(() => {})
|
||||||
await server.stop()
|
await server.stop()
|
||||||
},
|
},
|
||||||
|
|||||||
@@ -574,6 +574,7 @@ export namespace Config {
|
|||||||
.object({
|
.object({
|
||||||
apiKey: z.string().optional(),
|
apiKey: z.string().optional(),
|
||||||
baseURL: z.string().optional(),
|
baseURL: z.string().optional(),
|
||||||
|
enterpriseUrl: z.string().optional().describe("GitHub Enterprise URL for copilot authentication"),
|
||||||
timeout: z
|
timeout: z
|
||||||
.union([
|
.union([
|
||||||
z
|
z
|
||||||
|
|||||||
@@ -28,7 +28,7 @@ export namespace Plugin {
|
|||||||
}
|
}
|
||||||
const plugins = [...(config.plugin ?? [])]
|
const plugins = [...(config.plugin ?? [])]
|
||||||
if (!Flag.OPENCODE_DISABLE_DEFAULT_PLUGINS) {
|
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")
|
plugins.push("opencode-anthropic-auth@0.0.2")
|
||||||
}
|
}
|
||||||
for (let plugin of plugins) {
|
for (let plugin of plugins) {
|
||||||
|
|||||||
@@ -283,6 +283,18 @@ export namespace Provider {
|
|||||||
|
|
||||||
const configProviders = Object.entries(config.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) {
|
for (const [providerID, provider] of configProviders) {
|
||||||
const existing = database[providerID]
|
const existing = database[providerID]
|
||||||
const parsed: ModelsDev.Provider = {
|
const parsed: ModelsDev.Provider = {
|
||||||
@@ -378,14 +390,44 @@ export namespace Provider {
|
|||||||
if (!plugin.auth) continue
|
if (!plugin.auth) continue
|
||||||
const providerID = plugin.auth.provider
|
const providerID = plugin.auth.provider
|
||||||
if (disabled.has(providerID)) continue
|
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)
|
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
|
if (!plugin.auth.loader) continue
|
||||||
const options = await plugin.auth.loader(
|
|
||||||
() => Auth.get(providerID) as any,
|
// Load for the main provider if auth exists
|
||||||
database[plugin.auth.provider],
|
if (auth) {
|
||||||
)
|
const options = await plugin.auth.loader(
|
||||||
mergeProvider(plugin.auth.provider, options ?? {}, "custom")
|
() => 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
|
// load config
|
||||||
@@ -458,7 +500,8 @@ export namespace Provider {
|
|||||||
: installedPath
|
: installedPath
|
||||||
const mod = await import(modPath)
|
const mod = await import(modPath)
|
||||||
if (options["timeout"] !== undefined && options["timeout"] !== null) {
|
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) => {
|
options["fetch"] = async (input: any, init?: BunFetchRequestInit) => {
|
||||||
const { signal, ...rest } = init ?? {}
|
const { signal, ...rest } = init ?? {}
|
||||||
|
|
||||||
@@ -468,7 +511,8 @@ export namespace Provider {
|
|||||||
|
|
||||||
const combined = signals.length > 1 ? AbortSignal.any(signals) : signals[0]
|
const combined = signals.length > 1 ? AbortSignal.any(signals) : signals[0]
|
||||||
|
|
||||||
return fetch(input, {
|
const fetchFn = customFetch ?? fetch
|
||||||
|
return fetchFn(input, {
|
||||||
...rest,
|
...rest,
|
||||||
signal: combined,
|
signal: combined,
|
||||||
// @ts-ignore see here: https://github.com/oven-sh/bun/issues/16682
|
// @ts-ignore see here: https://github.com/oven-sh/bun/issues/16682
|
||||||
|
|||||||
@@ -10,6 +10,7 @@ import {
|
|||||||
import { Hono } from "hono"
|
import { Hono } from "hono"
|
||||||
import { cors } from "hono/cors"
|
import { cors } from "hono/cors"
|
||||||
import { stream, streamSSE } from "hono/streaming"
|
import { stream, streamSSE } from "hono/streaming"
|
||||||
|
import { proxy } from "hono/proxy"
|
||||||
import { Session } from "../session"
|
import { Session } from "../session"
|
||||||
import z from "zod"
|
import z from "zod"
|
||||||
import { Provider } from "../provider/provider"
|
import { Provider } from "../provider/provider"
|
||||||
@@ -757,6 +758,34 @@ export namespace Server {
|
|||||||
return c.json(messages)
|
return c.json(messages)
|
||||||
},
|
},
|
||||||
)
|
)
|
||||||
|
.get(
|
||||||
|
"/session/:id/diff",
|
||||||
|
describeRoute({
|
||||||
|
description: "Get the diff for this session",
|
||||||
|
operationId: "session.diff",
|
||||||
|
responses: {
|
||||||
|
200: {
|
||||||
|
description: "List of diffs",
|
||||||
|
content: {
|
||||||
|
"application/json": {
|
||||||
|
schema: resolver(Snapshot.FileDiff.array()),
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
...errors(400, 404),
|
||||||
|
},
|
||||||
|
}),
|
||||||
|
validator(
|
||||||
|
"param",
|
||||||
|
z.object({
|
||||||
|
id: z.string().meta({ description: "Session ID" }),
|
||||||
|
}),
|
||||||
|
),
|
||||||
|
async (c) => {
|
||||||
|
const diff = await Session.diff(c.req.valid("param").id)
|
||||||
|
return c.json(diff)
|
||||||
|
},
|
||||||
|
)
|
||||||
.get(
|
.get(
|
||||||
"/session/:id/message/:messageID",
|
"/session/:id/message/:messageID",
|
||||||
describeRoute({
|
describeRoute({
|
||||||
@@ -1696,7 +1725,15 @@ export namespace Server {
|
|||||||
})
|
})
|
||||||
})
|
})
|
||||||
},
|
},
|
||||||
),
|
)
|
||||||
|
.all("/*", async (c) => {
|
||||||
|
return proxy(`https://desktop.dev.opencode.ai${c.req.path}`, {
|
||||||
|
...c.req,
|
||||||
|
headers: {
|
||||||
|
host: "desktop.dev.opencode.ai",
|
||||||
|
},
|
||||||
|
})
|
||||||
|
}),
|
||||||
)
|
)
|
||||||
|
|
||||||
export async function openapi() {
|
export async function openapi() {
|
||||||
|
|||||||
@@ -15,8 +15,8 @@ import { MessageV2 } from "./message-v2"
|
|||||||
import { Instance } from "../project/instance"
|
import { Instance } from "../project/instance"
|
||||||
import { SessionPrompt } from "./prompt"
|
import { SessionPrompt } from "./prompt"
|
||||||
import { fn } from "@/util/fn"
|
import { fn } from "@/util/fn"
|
||||||
import { Snapshot } from "@/snapshot"
|
|
||||||
import { Command } from "../command"
|
import { Command } from "../command"
|
||||||
|
import { Snapshot } from "@/snapshot"
|
||||||
|
|
||||||
export namespace Session {
|
export namespace Session {
|
||||||
const log = Log.create({ service: "session" })
|
const log = Log.create({ service: "session" })
|
||||||
@@ -42,7 +42,9 @@ export namespace Session {
|
|||||||
parentID: Identifier.schema("session").optional(),
|
parentID: Identifier.schema("session").optional(),
|
||||||
summary: z
|
summary: z
|
||||||
.object({
|
.object({
|
||||||
diffs: Snapshot.FileDiff.array(),
|
additions: z.number(),
|
||||||
|
deletions: z.number(),
|
||||||
|
diffs: Snapshot.FileDiff.array().optional(),
|
||||||
})
|
})
|
||||||
.optional(),
|
.optional(),
|
||||||
share: z
|
share: z
|
||||||
@@ -258,6 +260,11 @@ export namespace Session {
|
|||||||
return result
|
return result
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export const diff = fn(Identifier.schema("session"), async (sessionID) => {
|
||||||
|
const diffs = await Storage.read<Snapshot.FileDiff[]>(["session_diff", sessionID])
|
||||||
|
return diffs ?? []
|
||||||
|
})
|
||||||
|
|
||||||
export const messages = fn(Identifier.schema("session"), async (sessionID) => {
|
export const messages = fn(Identifier.schema("session"), async (sessionID) => {
|
||||||
const result = [] as MessageV2.WithParts[]
|
const result = [] as MessageV2.WithParts[]
|
||||||
for (const p of await Storage.list(["message", sessionID])) {
|
for (const p of await Storage.list(["message", sessionID])) {
|
||||||
|
|||||||
@@ -11,6 +11,7 @@ import { SystemPrompt } from "./system"
|
|||||||
import { Log } from "@/util/log"
|
import { Log } from "@/util/log"
|
||||||
import path from "path"
|
import path from "path"
|
||||||
import { Instance } from "@/project/instance"
|
import { Instance } from "@/project/instance"
|
||||||
|
import { Storage } from "@/storage/storage"
|
||||||
|
|
||||||
export namespace SessionSummary {
|
export namespace SessionSummary {
|
||||||
const log = Log.create({ service: "session.summary" })
|
const log = Log.create({ service: "session.summary" })
|
||||||
@@ -44,9 +45,11 @@ export namespace SessionSummary {
|
|||||||
)
|
)
|
||||||
await Session.update(input.sessionID, (draft) => {
|
await Session.update(input.sessionID, (draft) => {
|
||||||
draft.summary = {
|
draft.summary = {
|
||||||
diffs,
|
additions: diffs.reduce((sum, x) => sum + x.additions, 0),
|
||||||
|
deletions: diffs.reduce((sum, x) => sum + x.deletions, 0),
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
await Storage.write(["session_diff", input.sessionID], diffs)
|
||||||
}
|
}
|
||||||
|
|
||||||
async function summarizeMessage(input: { messageID: string; messages: MessageV2.WithParts[] }) {
|
async function summarizeMessage(input: { messageID: string; messages: MessageV2.WithParts[] }) {
|
||||||
|
|||||||
@@ -85,7 +85,9 @@ export namespace Storage {
|
|||||||
const session = await Bun.file(sessionFile).json()
|
const session = await Bun.file(sessionFile).json()
|
||||||
await Bun.write(dest, JSON.stringify(session))
|
await Bun.write(dest, JSON.stringify(session))
|
||||||
log.info(`migrating messages for session ${session.id}`)
|
log.info(`migrating messages for session ${session.id}`)
|
||||||
for await (const msgFile of new Bun.Glob(`storage/session/message/${session.id}/*.json`).scan({
|
for await (const msgFile of new Bun.Glob(
|
||||||
|
`storage/session/message/${session.id}/*.json`,
|
||||||
|
).scan({
|
||||||
cwd: fullProjectDir,
|
cwd: fullProjectDir,
|
||||||
absolute: true,
|
absolute: true,
|
||||||
})) {
|
})) {
|
||||||
@@ -98,12 +100,12 @@ export namespace Storage {
|
|||||||
await Bun.write(dest, JSON.stringify(message))
|
await Bun.write(dest, JSON.stringify(message))
|
||||||
|
|
||||||
log.info(`migrating parts for message ${message.id}`)
|
log.info(`migrating parts for message ${message.id}`)
|
||||||
for await (const partFile of new Bun.Glob(`storage/session/part/${session.id}/${message.id}/*.json`).scan(
|
for await (const partFile of new Bun.Glob(
|
||||||
{
|
`storage/session/part/${session.id}/${message.id}/*.json`,
|
||||||
cwd: fullProjectDir,
|
).scan({
|
||||||
absolute: true,
|
cwd: fullProjectDir,
|
||||||
},
|
absolute: true,
|
||||||
)) {
|
})) {
|
||||||
const dest = path.join(dir, "part", message.id, path.basename(partFile))
|
const dest = path.join(dir, "part", message.id, path.basename(partFile))
|
||||||
const part = await Bun.file(partFile).json()
|
const part = await Bun.file(partFile).json()
|
||||||
log.info("copying", {
|
log.info("copying", {
|
||||||
@@ -117,6 +119,29 @@ export namespace Storage {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
async (dir) => {
|
||||||
|
for await (const item of new Bun.Glob("session/*/*.json").scan({
|
||||||
|
cwd: dir,
|
||||||
|
absolute: true,
|
||||||
|
})) {
|
||||||
|
const session = await Bun.file(item).json()
|
||||||
|
if (!session.projectID) continue
|
||||||
|
if (!session.summary?.diffs) continue
|
||||||
|
const { diffs } = session.summary
|
||||||
|
await Bun.file(path.join(dir, "session_diff", session.id + ".json")).write(
|
||||||
|
JSON.stringify(diffs),
|
||||||
|
)
|
||||||
|
await Bun.file(path.join(dir, "session", session.projectID, session.id + ".json")).write(
|
||||||
|
JSON.stringify({
|
||||||
|
...session,
|
||||||
|
summary: {
|
||||||
|
additions: diffs.reduce((sum: any, x: any) => sum + x.additions, 0),
|
||||||
|
deletions: diffs.reduce((sum: any, x: any) => sum + x.deletions, 0),
|
||||||
|
},
|
||||||
|
}),
|
||||||
|
)
|
||||||
|
}
|
||||||
|
},
|
||||||
]
|
]
|
||||||
|
|
||||||
const state = lazy(async () => {
|
const state = lazy(async () => {
|
||||||
@@ -128,9 +153,7 @@ export namespace Storage {
|
|||||||
for (let index = migration; index < MIGRATIONS.length; index++) {
|
for (let index = migration; index < MIGRATIONS.length; index++) {
|
||||||
log.info("running migration", { index })
|
log.info("running migration", { index })
|
||||||
const migration = MIGRATIONS[index]
|
const migration = MIGRATIONS[index]
|
||||||
await migration(dir).catch((e) => {
|
await migration(dir).catch(() => log.error("failed to run migration", { index }))
|
||||||
log.error("failed to run migration", { error: e, index })
|
|
||||||
})
|
|
||||||
await Bun.write(path.join(dir, "migration"), (index + 1).toString())
|
await Bun.write(path.join(dir, "migration"), (index + 1).toString())
|
||||||
}
|
}
|
||||||
return {
|
return {
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
{
|
{
|
||||||
"$schema": "https://json.schemastore.org/package.json",
|
"$schema": "https://json.schemastore.org/package.json",
|
||||||
"name": "@opencode-ai/plugin",
|
"name": "@opencode-ai/plugin",
|
||||||
"version": "1.0.20",
|
"version": "1.0.23",
|
||||||
"type": "module",
|
"type": "module",
|
||||||
"scripts": {
|
"scripts": {
|
||||||
"typecheck": "tsgo --noEmit",
|
"typecheck": "tsgo --noEmit",
|
||||||
|
|||||||
@@ -39,13 +39,35 @@ export interface Hooks {
|
|||||||
| {
|
| {
|
||||||
type: "oauth"
|
type: "oauth"
|
||||||
label: string
|
label: string
|
||||||
authorize(): Promise<
|
prompts?: Array<
|
||||||
|
| {
|
||||||
|
type: "text"
|
||||||
|
key: string
|
||||||
|
message: string
|
||||||
|
placeholder?: string
|
||||||
|
validate?: (value: string) => string | undefined
|
||||||
|
condition?: (inputs: Record<string, string>) => boolean
|
||||||
|
}
|
||||||
|
| {
|
||||||
|
type: "select"
|
||||||
|
key: string
|
||||||
|
message: string
|
||||||
|
options: Array<{
|
||||||
|
label: string
|
||||||
|
value: string
|
||||||
|
hint?: string
|
||||||
|
}>
|
||||||
|
condition?: (inputs: Record<string, string>) => boolean
|
||||||
|
}
|
||||||
|
>
|
||||||
|
authorize(inputs?: Record<string, string>): Promise<
|
||||||
{ url: string; instructions: string } & (
|
{ url: string; instructions: string } & (
|
||||||
| {
|
| {
|
||||||
method: "auto"
|
method: "auto"
|
||||||
callback(): Promise<
|
callback(): Promise<
|
||||||
| ({
|
| ({
|
||||||
type: "success"
|
type: "success"
|
||||||
|
provider?: string
|
||||||
} & (
|
} & (
|
||||||
| {
|
| {
|
||||||
refresh: string
|
refresh: string
|
||||||
@@ -64,6 +86,7 @@ export interface Hooks {
|
|||||||
callback(code: string): Promise<
|
callback(code: string): Promise<
|
||||||
| ({
|
| ({
|
||||||
type: "success"
|
type: "success"
|
||||||
|
provider?: string
|
||||||
} & (
|
} & (
|
||||||
| {
|
| {
|
||||||
refresh: 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<string, string>) => boolean
|
||||||
|
}
|
||||||
|
| {
|
||||||
|
type: "select"
|
||||||
|
key: string
|
||||||
|
message: string
|
||||||
|
options: Array<{
|
||||||
|
label: string
|
||||||
|
value: string
|
||||||
|
hint?: string
|
||||||
|
}>
|
||||||
|
condition?: (inputs: Record<string, string>) => boolean
|
||||||
|
}
|
||||||
|
>
|
||||||
|
authorize?(inputs?: Record<string, string>): Promise<
|
||||||
|
| {
|
||||||
|
type: "success"
|
||||||
|
key: string
|
||||||
|
provider?: string
|
||||||
|
}
|
||||||
|
| {
|
||||||
|
type: "failed"
|
||||||
|
}
|
||||||
|
>
|
||||||
|
}
|
||||||
)[]
|
)[]
|
||||||
}
|
}
|
||||||
/**
|
/**
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
{
|
{
|
||||||
"$schema": "https://json.schemastore.org/package.json",
|
"$schema": "https://json.schemastore.org/package.json",
|
||||||
"name": "@opencode-ai/sdk",
|
"name": "@opencode-ai/sdk",
|
||||||
"version": "1.0.20",
|
"version": "1.0.23",
|
||||||
"type": "module",
|
"type": "module",
|
||||||
"scripts": {
|
"scripts": {
|
||||||
"typecheck": "tsgo --noEmit",
|
"typecheck": "tsgo --noEmit",
|
||||||
|
|||||||
@@ -55,6 +55,7 @@ import type {
|
|||||||
SessionShareErrors,
|
SessionShareErrors,
|
||||||
SessionDiffData,
|
SessionDiffData,
|
||||||
SessionDiffResponses,
|
SessionDiffResponses,
|
||||||
|
SessionDiffErrors,
|
||||||
SessionSummarizeData,
|
SessionSummarizeData,
|
||||||
SessionSummarizeResponses,
|
SessionSummarizeResponses,
|
||||||
SessionSummarizeErrors,
|
SessionSummarizeErrors,
|
||||||
@@ -475,12 +476,16 @@ class Session extends _HeyApiClient {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get the diff that resulted from this user message
|
* Get the diff for this session
|
||||||
*/
|
*/
|
||||||
public diff<ThrowOnError extends boolean = false>(
|
public diff<ThrowOnError extends boolean = false>(
|
||||||
options: Options<SessionDiffData, ThrowOnError>,
|
options: Options<SessionDiffData, ThrowOnError>,
|
||||||
) {
|
) {
|
||||||
return (options.client ?? this._client).get<SessionDiffResponses, unknown, ThrowOnError>({
|
return (options.client ?? this._client).get<
|
||||||
|
SessionDiffResponses,
|
||||||
|
SessionDiffErrors,
|
||||||
|
ThrowOnError
|
||||||
|
>({
|
||||||
url: "/session/{id}/diff",
|
url: "/session/{id}/diff",
|
||||||
...options,
|
...options,
|
||||||
})
|
})
|
||||||
|
|||||||
@@ -163,7 +163,7 @@ export type KeybindsConfig = {
|
|||||||
*/
|
*/
|
||||||
history_previous?: string
|
history_previous?: string
|
||||||
/**
|
/**
|
||||||
* Previous history item
|
* Next history item
|
||||||
*/
|
*/
|
||||||
history_next?: string
|
history_next?: string
|
||||||
/**
|
/**
|
||||||
@@ -405,6 +405,10 @@ export type Config = {
|
|||||||
options?: {
|
options?: {
|
||||||
apiKey?: string
|
apiKey?: string
|
||||||
baseURL?: 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.
|
* Timeout in milliseconds for requests to this provider. Default is 300000 (5 minutes). Set to false to disable timeout.
|
||||||
*/
|
*/
|
||||||
@@ -527,7 +531,9 @@ export type Session = {
|
|||||||
directory: string
|
directory: string
|
||||||
parentID?: string
|
parentID?: string
|
||||||
summary?: {
|
summary?: {
|
||||||
diffs: Array<FileDiff>
|
additions: number
|
||||||
|
deletions: number
|
||||||
|
diffs?: Array<FileDiff>
|
||||||
}
|
}
|
||||||
share?: {
|
share?: {
|
||||||
url: string
|
url: string
|
||||||
@@ -1133,6 +1139,7 @@ export type OAuth = {
|
|||||||
refresh: string
|
refresh: string
|
||||||
access: string
|
access: string
|
||||||
expires: number
|
expires: number
|
||||||
|
enterpriseUrl?: string
|
||||||
}
|
}
|
||||||
|
|
||||||
export type ApiAuth = {
|
export type ApiAuth = {
|
||||||
@@ -1882,6 +1889,9 @@ export type SessionShareResponse = SessionShareResponses[keyof SessionShareRespo
|
|||||||
export type SessionDiffData = {
|
export type SessionDiffData = {
|
||||||
body?: never
|
body?: never
|
||||||
path: {
|
path: {
|
||||||
|
/**
|
||||||
|
* Session ID
|
||||||
|
*/
|
||||||
id: string
|
id: string
|
||||||
}
|
}
|
||||||
query?: {
|
query?: {
|
||||||
@@ -1891,9 +1901,22 @@ export type SessionDiffData = {
|
|||||||
url: "/session/{id}/diff"
|
url: "/session/{id}/diff"
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export type SessionDiffErrors = {
|
||||||
|
/**
|
||||||
|
* Bad request
|
||||||
|
*/
|
||||||
|
400: BadRequestError
|
||||||
|
/**
|
||||||
|
* Not found
|
||||||
|
*/
|
||||||
|
404: NotFoundError
|
||||||
|
}
|
||||||
|
|
||||||
|
export type SessionDiffError = SessionDiffErrors[keyof SessionDiffErrors]
|
||||||
|
|
||||||
export type SessionDiffResponses = {
|
export type SessionDiffResponses = {
|
||||||
/**
|
/**
|
||||||
* Successfully retrieved diff
|
* List of diffs
|
||||||
*/
|
*/
|
||||||
200: Array<FileDiff>
|
200: Array<FileDiff>
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "@opencode-ai/slack",
|
"name": "@opencode-ai/slack",
|
||||||
"version": "1.0.20",
|
"version": "1.0.23",
|
||||||
"type": "module",
|
"type": "module",
|
||||||
"scripts": {
|
"scripts": {
|
||||||
"dev": "bun run src/index.ts",
|
"dev": "bun run src/index.ts",
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "@opencode-ai/ui",
|
"name": "@opencode-ai/ui",
|
||||||
"version": "1.0.20",
|
"version": "1.0.23",
|
||||||
"type": "module",
|
"type": "module",
|
||||||
"exports": {
|
"exports": {
|
||||||
".": "./src/components/index.ts",
|
".": "./src/components/index.ts",
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
{
|
{
|
||||||
"name": "@opencode-ai/web",
|
"name": "@opencode-ai/web",
|
||||||
"type": "module",
|
"type": "module",
|
||||||
"version": "1.0.20",
|
"version": "1.0.23",
|
||||||
"scripts": {
|
"scripts": {
|
||||||
"dev": "astro dev",
|
"dev": "astro dev",
|
||||||
"dev:remote": "VITE_API_URL=https://api.opencode.ai astro dev",
|
"dev:remote": "VITE_API_URL=https://api.opencode.ai astro dev",
|
||||||
|
|||||||
@@ -2,7 +2,7 @@
|
|||||||
"name": "opencode",
|
"name": "opencode",
|
||||||
"displayName": "opencode",
|
"displayName": "opencode",
|
||||||
"description": "opencode for VS Code",
|
"description": "opencode for VS Code",
|
||||||
"version": "1.0.20",
|
"version": "1.0.23",
|
||||||
"publisher": "sst-dev",
|
"publisher": "sst-dev",
|
||||||
"repository": {
|
"repository": {
|
||||||
"type": "git",
|
"type": "git",
|
||||||
|
|||||||
Reference in New Issue
Block a user