ci: format

This commit is contained in:
Dax Raad
2025-09-09 23:43:37 -04:00
parent 58fe884327
commit 38e8c42cf0
68 changed files with 921 additions and 1018 deletions

View File

@@ -2,7 +2,7 @@ name: discord
on: on:
release: release:
types: [published] # fires only when a release is published types: [published] # fires only when a release is published
jobs: jobs:
notify: notify:

View File

@@ -24,4 +24,4 @@ jobs:
env: env:
OPENCODE_API_KEY: ${{ secrets.OPENCODE_API_KEY }} OPENCODE_API_KEY: ${{ secrets.OPENCODE_API_KEY }}
with: with:
model: opencode/sonic model: opencode/sonic

View File

@@ -1,15 +1,15 @@
import { MetaProvider, Title, Meta } from "@solidjs/meta"; import { MetaProvider, Title, Meta } from "@solidjs/meta"
import { Router } from "@solidjs/router"; import { Router } from "@solidjs/router"
import { FileRoutes } from "@solidjs/start/router"; import { FileRoutes } from "@solidjs/start/router"
import { ErrorBoundary, Suspense } from "solid-js"; import { ErrorBoundary, Suspense } from "solid-js"
import "@ibm/plex/css/ibm-plex.css"; import "@ibm/plex/css/ibm-plex.css"
import "./app.css"; import "./app.css"
export default function App() { export default function App() {
return ( return (
<Router <Router
explicitLinks={true} explicitLinks={true}
root={props => ( root={(props) => (
<MetaProvider> <MetaProvider>
<Title>opencode</Title> <Title>opencode</Title>
<Meta name="description" content="opencode - The AI coding agent built for the terminal." /> <Meta name="description" content="opencode - The AI coding agent built for the terminal." />
@@ -19,5 +19,5 @@ export default function App() {
> >
<FileRoutes /> <FileRoutes />
</Router> </Router>
); )
} }

View File

@@ -6,34 +6,66 @@ export function IconLogo(props: JSX.SvgSVGAttributes<SVGSVGElement>) {
<path d="M264.5 0H288.5V8.5H272.5V16.5H288.5V25H272.5V33H288.5V41.5H264.5V0Z" fill="currentColor" /> <path d="M264.5 0H288.5V8.5H272.5V16.5H288.5V25H272.5V33H288.5V41.5H264.5V0Z" fill="currentColor" />
<path d="M248.5 0H224.5V41.5H248.5V33H232.5V8.5H248.5V0Z" fill="currentColor" /> <path d="M248.5 0H224.5V41.5H248.5V33H232.5V8.5H248.5V0Z" fill="currentColor" />
<path d="M256.5 8.5H248.5V33H256.5V8.5Z" fill="currentColor" /> <path d="M256.5 8.5H248.5V33H256.5V8.5Z" fill="currentColor" />
<path fill-rule="evenodd" clip-rule="evenodd" d="M184.5 0H216.5V41.5H184.5V0ZM208.5 8.5H192.5V33H208.5V8.5Z" fill="currentColor" /> <path
fill-rule="evenodd"
clip-rule="evenodd"
d="M184.5 0H216.5V41.5H184.5V0ZM208.5 8.5H192.5V33H208.5V8.5Z"
fill="currentColor"
/>
<path d="M144.5 8.5H136.5V41.5H144.5V8.5Z" fill="currentColor" /> <path d="M144.5 8.5H136.5V41.5H144.5V8.5Z" fill="currentColor" />
<path d="M136.5 0H112.5V41.5H120.5V8.5H136.5V0Z" fill="currentColor" /> <path d="M136.5 0H112.5V41.5H120.5V8.5H136.5V0Z" fill="currentColor" />
<path d="M80.5 0H104.5V8.5H88.5V16.5H104.5V25H88.5V33H104.5V41.5H80.5V0Z" fill="currentColor" /> <path d="M80.5 0H104.5V8.5H88.5V16.5H104.5V25H88.5V33H104.5V41.5H80.5V0Z" fill="currentColor" />
<path fill-rule="evenodd" clip-rule="evenodd" d="M40.5 0H72.5V41.5H48.5V49.5H40.5V0ZM64.5 8.5H48.5V33H64.5V8.5Z" fill="currentColor" /> <path
<path fill-rule="evenodd" clip-rule="evenodd" d="M0.5 0H32.5V41.5955H0.5V0ZM24.5 8.5H8.5V33H24.5V8.5Z" fill="currentColor" /> fill-rule="evenodd"
clip-rule="evenodd"
d="M40.5 0H72.5V41.5H48.5V49.5H40.5V0ZM64.5 8.5H48.5V33H64.5V8.5Z"
fill="currentColor"
/>
<path
fill-rule="evenodd"
clip-rule="evenodd"
d="M0.5 0H32.5V41.5955H0.5V0ZM24.5 8.5H8.5V33H24.5V8.5Z"
fill="currentColor"
/>
<path d="M152.5 0H176.5V8.5H160.5V33H176.5V41.5H152.5V0Z" fill="currentColor" /> <path d="M152.5 0H176.5V8.5H160.5V33H176.5V41.5H152.5V0Z" fill="currentColor" />
</svg> </svg>
); )
} }
export function IconCopy(props: JSX.SvgSVGAttributes<SVGSVGElement>) { export function IconCopy(props: JSX.SvgSVGAttributes<SVGSVGElement>) {
return ( return (
<svg <svg {...props} viewBox="0 0 512 512">
{...props} <rect
viewBox="0 0 512 512" > width="336"
<rect width="336" height="336" x="128" y="128" fill="none" stroke="currentColor" stroke-linejoin="round" stroke-width="32" rx="57" ry="57"></rect> height="336"
<path fill="none" stroke="currentColor" stroke-linecap="round" stroke-linejoin="round" stroke-width="32" d="m383.5 128l.5-24a56.16 56.16 0 0 0-56-56H112a64.19 64.19 0 0 0-64 64v216a56.16 56.16 0 0 0 56 56h24"></path> x="128"
y="128"
fill="none"
stroke="currentColor"
stroke-linejoin="round"
stroke-width="32"
rx="57"
ry="57"
></rect>
<path
fill="none"
stroke="currentColor"
stroke-linecap="round"
stroke-linejoin="round"
stroke-width="32"
d="m383.5 128l.5-24a56.16 56.16 0 0 0-56-56H112a64.19 64.19 0 0 0-64 64v216a56.16 56.16 0 0 0 56 56h24"
></path>
</svg> </svg>
) )
} }
export function IconCheck(props: JSX.SvgSVGAttributes<SVGSVGElement>) { export function IconCheck(props: JSX.SvgSVGAttributes<SVGSVGElement>) {
return ( return (
<svg <svg {...props} viewBox="0 0 24 24">
{...props} <path
viewBox="0 0 24 24" > fill="currentColor"
<path fill="currentColor" d="M9 16.17L5.53 12.7a.996.996 0 1 0-1.41 1.41l4.18 4.18c.39.39 1.02.39 1.41 0L20.29 7.71a.996.996 0 1 0-1.41-1.41z"></path> d="M9 16.17L5.53 12.7a.996.996 0 1 0-1.41 1.41l4.18 4.18c.39.39 1.02.39 1.41 0L20.29 7.71a.996.996 0 1 0-1.41-1.41z"
></path>
</svg> </svg>
) )
} }

View File

@@ -1,4 +1,4 @@
// @refresh reload // @refresh reload
import { mount, StartClient } from "@solidjs/start/client"; import { mount, StartClient } from "@solidjs/start/client"
mount(() => <StartClient />, document.getElementById("app")!); mount(() => <StartClient />, document.getElementById("app")!)

View File

@@ -1,26 +1,28 @@
// @refresh reload // @refresh reload
import { createHandler, StartServer } from "@solidjs/start/server" import { createHandler, StartServer } from "@solidjs/start/server"
export default createHandler(
export default createHandler(() => ( () => (
<StartServer <StartServer
document={({ assets, children, scripts }) => ( document={({ assets, children, scripts }) => (
<html lang="en"> <html lang="en">
<head> <head>
<meta charset="utf-8" /> <meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1" /> <meta name="viewport" content="width=device-width, initial-scale=1" />
<link rel="icon" href="/favicon.svg" /> <link rel="icon" href="/favicon.svg" />
<meta property="og:image" content="/social-share.png" /> <meta property="og:image" content="/social-share.png" />
<meta property="twitter:image" content="/social-share.png" /> <meta property="twitter:image" content="/social-share.png" />
{assets} {assets}
</head> </head>
<body> <body>
<div id="app">{children}</div> <div id="app">{children}</div>
{scripts} {scripts}
</body> </body>
</html> </html>
)} )}
/> />
), { ),
mode: "async", {
}) mode: "async",
},
)

View File

@@ -64,9 +64,7 @@ export default function Home() {
<section data-component="cta"> <section data-component="cta">
<div data-slot="left"> <div data-slot="left">
<a href="/docs"> <a href="/docs">Get Started</a>
Get Started
</a>
</div> </div>
<div data-slot="right"> <div data-slot="right">
<button data-copy data-slot="command"> <button data-copy data-slot="command">
@@ -90,7 +88,8 @@ export default function Home() {
<strong>LSP enabled</strong> Automatically loads the right LSPs for the LLM <strong>LSP enabled</strong> Automatically loads the right LSPs for the LLM
</li> </li>
<li> <li>
<strong>opencode zen</strong> A <a href="/docs/zen">curated list of models</a> provided by opencode <label>New</label> <strong>opencode zen</strong> A <a href="/docs/zen">curated list of models</a> provided by opencode{" "}
<label>New</label>
</li> </li>
<li> <li>
<strong>Multi-session</strong> Start multiple agents in parallel on the same project <strong>Multi-session</strong> Start multiple agents in parallel on the same project

View File

@@ -2,7 +2,17 @@ import "./workspace.css"
import { useAuthSession } from "~/context/auth.session" import { useAuthSession } from "~/context/auth.session"
import { IconLogo } from "../component/icon" import { IconLogo } from "../component/icon"
import { withActor } from "~/context/auth.withActor" import { withActor } from "~/context/auth.withActor"
import { query, action, redirect, createAsync, RouteSectionProps, Navigate, useNavigate, useParams, A } from "@solidjs/router" import {
query,
action,
redirect,
createAsync,
RouteSectionProps,
Navigate,
useNavigate,
useParams,
A,
} from "@solidjs/router"
import { User } from "@opencode/cloud-core/user.js" import { User } from "@opencode/cloud-core/user.js"
import { Actor } from "@opencode/cloud-core/actor.js" import { Actor } from "@opencode/cloud-core/actor.js"
import { getRequestEvent } from "solid-js/web" import { getRequestEvent } from "solid-js/web"

View File

@@ -1,15 +1,7 @@
import "./[id].css" import "./[id].css"
import { Billing } from "@opencode/cloud-core/billing.js" import { Billing } from "@opencode/cloud-core/billing.js"
import { Key } from "@opencode/cloud-core/key.js" import { Key } from "@opencode/cloud-core/key.js"
import { import { json, query, action, useParams, useAction, createAsync, useSubmission } from "@solidjs/router"
json,
query,
action,
useParams,
useAction,
createAsync,
useSubmission,
} from "@solidjs/router"
import { createMemo, createSignal, For, Show } from "solid-js" import { createMemo, createSignal, For, Show } from "solid-js"
import { withActor } from "~/context/auth.withActor" import { withActor } from "~/context/auth.withActor"
import { IconCopy, IconCheck } from "~/component/icon" import { IconCopy, IconCheck } from "~/component/icon"
@@ -432,50 +424,57 @@ function PaymentsSection() {
const payments = createAsync(() => getPaymentsInfo(params.id)) const payments = createAsync(() => getPaymentsInfo(params.id))
// const payments = () => dummyPayments // const payments = () => dummyPayments
return payments() && payments()!.length > 0 && ( return (
<section data-component="payments-section"> payments() &&
<div data-slot="section-title"> payments()!.length > 0 && (
<h2>Payments History</h2> <section data-component="payments-section">
<p>Recent payment transactions.</p> <div data-slot="section-title">
</div> <h2>Payments History</h2>
<div data-slot="payments-table"> <p>Recent payment transactions.</p>
<table data-slot="payments-table-element"> </div>
<thead> <div data-slot="payments-table">
<tr> <table data-slot="payments-table-element">
<th>Date</th> <thead>
<th>Payment ID</th> <tr>
<th>Amount</th> <th>Date</th>
</tr> <th>Payment ID</th>
</thead> <th>Amount</th>
<tbody> </tr>
<For each={payments()!}> </thead>
{(payment) => { <tbody>
const date = new Date(payment.timeCreated) <For each={payments()!}>
return ( {(payment) => {
<tr> const date = new Date(payment.timeCreated)
<td data-slot="payment-date" title={formatDateUTC(date)}> return (
{formatDateForTable(date)} <tr>
</td> <td data-slot="payment-date" title={formatDateUTC(date)}>
<td data-slot="payment-id">{payment.id}</td> {formatDateForTable(date)}
<td data-slot="payment-amount">${((payment.amount ?? 0) / 100000000).toFixed(2)}</td> </td>
</tr> <td data-slot="payment-id">{payment.id}</td>
) <td data-slot="payment-amount">${((payment.amount ?? 0) / 100000000).toFixed(2)}</td>
}} </tr>
</For> )
</tbody> }}
</table> </For>
</div> </tbody>
</section> </table>
</div>
</section>
)
) )
} }
export default function() { export default function () {
return ( return (
<div data-page="workspace-[id]"> <div data-page="workspace-[id]">
<section data-component="title-section"> <section data-component="title-section">
<h1>Zen</h1> <h1>Zen</h1>
<p> <p>
Curated list of models provided by opencode. <a target="_blank" href="/docs/zen">Learn more</a>. Curated list of models provided by opencode.{" "}
<a target="_blank" href="/docs/zen">
Learn more
</a>
.
</p> </p>
</section> </section>

View File

@@ -14,6 +14,7 @@ body {
--font-size-8xl: 6rem; --font-size-8xl: 6rem;
--font-size-9xl: 8rem; --font-size-9xl: 8rem;
--font-mono: "IBM Plex Mono", ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, "Liberation Mono", "Courier New", monospace; --font-mono:
"IBM Plex Mono", ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, "Liberation Mono", "Courier New", monospace;
--font-sans: var(--font-mono); --font-sans: var(--font-mono);
} }

View File

@@ -6,4 +6,4 @@
/// <reference path="../../sst-env.d.ts" /> /// <reference path="../../sst-env.d.ts" />
import "sst" import "sst"
export {} export {}

View File

@@ -12,14 +12,10 @@
"allowJs": true, "allowJs": true,
"strict": true, "strict": true,
"noEmit": true, "noEmit": true,
"types": [ "types": ["vinxi/types/client"],
"vinxi/types/client"
],
"isolatedModules": true, "isolatedModules": true,
"paths": { "paths": {
"~/*": [ "~/*": ["./src/*"]
"./src/*"
]
} }
} }
} }

View File

@@ -48,9 +48,7 @@
"indexes": { "indexes": {
"email": { "email": {
"name": "email", "name": "email",
"columns": [ "columns": ["email"],
"email"
],
"isUnique": true "isUnique": true
} }
}, },
@@ -140,10 +138,7 @@
"compositePrimaryKeys": { "compositePrimaryKeys": {
"billing_workspace_id_id_pk": { "billing_workspace_id_id_pk": {
"name": "billing_workspace_id_id_pk", "name": "billing_workspace_id_id_pk",
"columns": [ "columns": ["workspace_id", "id"]
"workspace_id",
"id"
]
} }
}, },
"uniqueConstraints": {}, "uniqueConstraints": {},
@@ -216,10 +211,7 @@
"compositePrimaryKeys": { "compositePrimaryKeys": {
"payment_workspace_id_id_pk": { "payment_workspace_id_id_pk": {
"name": "payment_workspace_id_id_pk", "name": "payment_workspace_id_id_pk",
"columns": [ "columns": ["workspace_id", "id"]
"workspace_id",
"id"
]
} }
}, },
"uniqueConstraints": {}, "uniqueConstraints": {},
@@ -320,10 +312,7 @@
"compositePrimaryKeys": { "compositePrimaryKeys": {
"usage_workspace_id_id_pk": { "usage_workspace_id_id_pk": {
"name": "usage_workspace_id_id_pk", "name": "usage_workspace_id_id_pk",
"columns": [ "columns": ["workspace_id", "id"]
"workspace_id",
"id"
]
} }
}, },
"uniqueConstraints": {}, "uniqueConstraints": {},
@@ -401,9 +390,7 @@
"indexes": { "indexes": {
"global_key": { "global_key": {
"name": "global_key", "name": "global_key",
"columns": [ "columns": ["key"],
"key"
],
"isUnique": true "isUnique": true
} }
}, },
@@ -411,10 +398,7 @@
"compositePrimaryKeys": { "compositePrimaryKeys": {
"key_workspace_id_id_pk": { "key_workspace_id_id_pk": {
"name": "key_workspace_id_id_pk", "name": "key_workspace_id_id_pk",
"columns": [ "columns": ["workspace_id", "id"]
"workspace_id",
"id"
]
} }
}, },
"uniqueConstraints": {}, "uniqueConstraints": {},
@@ -492,10 +476,7 @@
"indexes": { "indexes": {
"user_email": { "user_email": {
"name": "user_email", "name": "user_email",
"columns": [ "columns": ["workspace_id", "email"],
"workspace_id",
"email"
],
"isUnique": true "isUnique": true
} }
}, },
@@ -503,10 +484,7 @@
"compositePrimaryKeys": { "compositePrimaryKeys": {
"user_workspace_id_id_pk": { "user_workspace_id_id_pk": {
"name": "user_workspace_id_id_pk", "name": "user_workspace_id_id_pk",
"columns": [ "columns": ["workspace_id", "id"]
"workspace_id",
"id"
]
} }
}, },
"uniqueConstraints": {}, "uniqueConstraints": {},
@@ -563,9 +541,7 @@
"indexes": { "indexes": {
"slug": { "slug": {
"name": "slug", "name": "slug",
"columns": [ "columns": ["slug"],
"slug"
],
"isUnique": true "isUnique": true
} }
}, },
@@ -573,9 +549,7 @@
"compositePrimaryKeys": { "compositePrimaryKeys": {
"workspace_id": { "workspace_id": {
"name": "workspace_id", "name": "workspace_id",
"columns": [ "columns": ["id"]
"id"
]
} }
}, },
"uniqueConstraints": {}, "uniqueConstraints": {},
@@ -592,4 +566,4 @@
"tables": {}, "tables": {},
"indexes": {} "indexes": {}
} }
} }

View File

@@ -48,9 +48,7 @@
"indexes": { "indexes": {
"email": { "email": {
"name": "email", "name": "email",
"columns": [ "columns": ["email"],
"email"
],
"isUnique": true "isUnique": true
} }
}, },
@@ -140,10 +138,7 @@
"compositePrimaryKeys": { "compositePrimaryKeys": {
"billing_workspace_id_id_pk": { "billing_workspace_id_id_pk": {
"name": "billing_workspace_id_id_pk", "name": "billing_workspace_id_id_pk",
"columns": [ "columns": ["workspace_id", "id"]
"workspace_id",
"id"
]
} }
}, },
"uniqueConstraints": {}, "uniqueConstraints": {},
@@ -216,10 +211,7 @@
"compositePrimaryKeys": { "compositePrimaryKeys": {
"payment_workspace_id_id_pk": { "payment_workspace_id_id_pk": {
"name": "payment_workspace_id_id_pk", "name": "payment_workspace_id_id_pk",
"columns": [ "columns": ["workspace_id", "id"]
"workspace_id",
"id"
]
} }
}, },
"uniqueConstraints": {}, "uniqueConstraints": {},
@@ -320,10 +312,7 @@
"compositePrimaryKeys": { "compositePrimaryKeys": {
"usage_workspace_id_id_pk": { "usage_workspace_id_id_pk": {
"name": "usage_workspace_id_id_pk", "name": "usage_workspace_id_id_pk",
"columns": [ "columns": ["workspace_id", "id"]
"workspace_id",
"id"
]
} }
}, },
"uniqueConstraints": {}, "uniqueConstraints": {},
@@ -401,9 +390,7 @@
"indexes": { "indexes": {
"global_key": { "global_key": {
"name": "global_key", "name": "global_key",
"columns": [ "columns": ["key"],
"key"
],
"isUnique": true "isUnique": true
} }
}, },
@@ -411,10 +398,7 @@
"compositePrimaryKeys": { "compositePrimaryKeys": {
"key_workspace_id_id_pk": { "key_workspace_id_id_pk": {
"name": "key_workspace_id_id_pk", "name": "key_workspace_id_id_pk",
"columns": [ "columns": ["workspace_id", "id"]
"workspace_id",
"id"
]
} }
}, },
"uniqueConstraints": {}, "uniqueConstraints": {},
@@ -492,10 +476,7 @@
"indexes": { "indexes": {
"user_email": { "user_email": {
"name": "user_email", "name": "user_email",
"columns": [ "columns": ["workspace_id", "email"],
"workspace_id",
"email"
],
"isUnique": true "isUnique": true
} }
}, },
@@ -503,10 +484,7 @@
"compositePrimaryKeys": { "compositePrimaryKeys": {
"user_workspace_id_id_pk": { "user_workspace_id_id_pk": {
"name": "user_workspace_id_id_pk", "name": "user_workspace_id_id_pk",
"columns": [ "columns": ["workspace_id", "id"]
"workspace_id",
"id"
]
} }
}, },
"uniqueConstraints": {}, "uniqueConstraints": {},
@@ -563,9 +541,7 @@
"indexes": { "indexes": {
"slug": { "slug": {
"name": "slug", "name": "slug",
"columns": [ "columns": ["slug"],
"slug"
],
"isUnique": true "isUnique": true
} }
}, },
@@ -573,9 +549,7 @@
"compositePrimaryKeys": { "compositePrimaryKeys": {
"workspace_id": { "workspace_id": {
"name": "workspace_id", "name": "workspace_id",
"columns": [ "columns": ["id"]
"id"
]
} }
}, },
"uniqueConstraints": {}, "uniqueConstraints": {},
@@ -592,4 +566,4 @@
"tables": {}, "tables": {},
"indexes": {} "indexes": {}
} }
} }

View File

@@ -17,4 +17,4 @@
"breakpoints": true "breakpoints": true
} }
] ]
} }

View File

@@ -1,9 +1,6 @@
import { z } from "zod" import { z } from "zod"
export function fn<T extends z.ZodType, Result>( export function fn<T extends z.ZodType, Result>(schema: T, cb: (input: z.output<T>) => Result) {
schema: T,
cb: (input: z.output<T>) => Result,
) {
const result = (input: z.input<T>) => { const result = (input: z.input<T>) => {
const parsed = schema.parse(input) const parsed = schema.parse(input)
return cb(parsed) return cb(parsed)

View File

@@ -6,4 +6,4 @@
/// <reference path="../../sst-env.d.ts" /> /// <reference path="../../sst-env.d.ts" />
import "sst" import "sst"
export {} export {}

View File

@@ -6,87 +6,87 @@
import "sst" import "sst"
declare module "sst" { declare module "sst" {
export interface Resource { export interface Resource {
"ANTHROPIC_API_KEY": { ANTHROPIC_API_KEY: {
"type": "sst.sst.Secret" type: "sst.sst.Secret"
"value": string value: string
} }
"AUTH_API_URL": { AUTH_API_URL: {
"type": "sst.sst.Linkable" type: "sst.sst.Linkable"
"value": string value: string
} }
"BASETEN_API_KEY": { BASETEN_API_KEY: {
"type": "sst.sst.Secret" type: "sst.sst.Secret"
"value": string value: string
} }
"Console": { Console: {
"type": "sst.cloudflare.SolidStart" type: "sst.cloudflare.SolidStart"
"url": string url: string
} }
"Database": { Database: {
"database": string database: string
"host": string host: string
"password": string password: string
"port": number port: number
"type": "sst.sst.Linkable" type: "sst.sst.Linkable"
"username": string username: string
} }
"GITHUB_APP_ID": { GITHUB_APP_ID: {
"type": "sst.sst.Secret" type: "sst.sst.Secret"
"value": string value: string
} }
"GITHUB_APP_PRIVATE_KEY": { GITHUB_APP_PRIVATE_KEY: {
"type": "sst.sst.Secret" type: "sst.sst.Secret"
"value": string value: string
} }
"GITHUB_CLIENT_ID_CONSOLE": { GITHUB_CLIENT_ID_CONSOLE: {
"type": "sst.sst.Secret" type: "sst.sst.Secret"
"value": string value: string
} }
"GITHUB_CLIENT_SECRET_CONSOLE": { GITHUB_CLIENT_SECRET_CONSOLE: {
"type": "sst.sst.Secret" type: "sst.sst.Secret"
"value": string value: string
} }
"GOOGLE_CLIENT_ID": { GOOGLE_CLIENT_ID: {
"type": "sst.sst.Secret" type: "sst.sst.Secret"
"value": string value: string
} }
"HONEYCOMB_API_KEY": { HONEYCOMB_API_KEY: {
"type": "sst.sst.Secret" type: "sst.sst.Secret"
"value": string value: string
} }
"OPENAI_API_KEY": { OPENAI_API_KEY: {
"type": "sst.sst.Secret" type: "sst.sst.Secret"
"value": string value: string
} }
"STRIPE_SECRET_KEY": { STRIPE_SECRET_KEY: {
"type": "sst.sst.Secret" type: "sst.sst.Secret"
"value": string value: string
} }
"STRIPE_WEBHOOK_SECRET": { STRIPE_WEBHOOK_SECRET: {
"type": "sst.sst.Linkable" type: "sst.sst.Linkable"
"value": string value: string
} }
"Web": { Web: {
"type": "sst.cloudflare.Astro" type: "sst.cloudflare.Astro"
"url": string url: string
} }
"XAI_API_KEY": { XAI_API_KEY: {
"type": "sst.sst.Secret" type: "sst.sst.Secret"
"value": string value: string
} }
} }
} }
// cloudflare // cloudflare
import * as cloudflare from "@cloudflare/workers-types"; import * as cloudflare from "@cloudflare/workers-types"
declare module "sst" { declare module "sst" {
export interface Resource { export interface Resource {
"Api": cloudflare.Service Api: cloudflare.Service
"AuthApi": cloudflare.Service AuthApi: cloudflare.Service
"AuthStorage": cloudflare.KVNamespace AuthStorage: cloudflare.KVNamespace
"Bucket": cloudflare.R2Bucket Bucket: cloudflare.R2Bucket
"LogProcessor": cloudflare.Service LogProcessor: cloudflare.Service
} }
} }
import "sst" import "sst"
export {} export {}

View File

@@ -6,87 +6,87 @@
import "sst" import "sst"
declare module "sst" { declare module "sst" {
export interface Resource { export interface Resource {
"ANTHROPIC_API_KEY": { ANTHROPIC_API_KEY: {
"type": "sst.sst.Secret" type: "sst.sst.Secret"
"value": string value: string
} }
"AUTH_API_URL": { AUTH_API_URL: {
"type": "sst.sst.Linkable" type: "sst.sst.Linkable"
"value": string value: string
} }
"BASETEN_API_KEY": { BASETEN_API_KEY: {
"type": "sst.sst.Secret" type: "sst.sst.Secret"
"value": string value: string
} }
"Console": { Console: {
"type": "sst.cloudflare.SolidStart" type: "sst.cloudflare.SolidStart"
"url": string url: string
} }
"Database": { Database: {
"database": string database: string
"host": string host: string
"password": string password: string
"port": number port: number
"type": "sst.sst.Linkable" type: "sst.sst.Linkable"
"username": string username: string
} }
"GITHUB_APP_ID": { GITHUB_APP_ID: {
"type": "sst.sst.Secret" type: "sst.sst.Secret"
"value": string value: string
} }
"GITHUB_APP_PRIVATE_KEY": { GITHUB_APP_PRIVATE_KEY: {
"type": "sst.sst.Secret" type: "sst.sst.Secret"
"value": string value: string
} }
"GITHUB_CLIENT_ID_CONSOLE": { GITHUB_CLIENT_ID_CONSOLE: {
"type": "sst.sst.Secret" type: "sst.sst.Secret"
"value": string value: string
} }
"GITHUB_CLIENT_SECRET_CONSOLE": { GITHUB_CLIENT_SECRET_CONSOLE: {
"type": "sst.sst.Secret" type: "sst.sst.Secret"
"value": string value: string
} }
"GOOGLE_CLIENT_ID": { GOOGLE_CLIENT_ID: {
"type": "sst.sst.Secret" type: "sst.sst.Secret"
"value": string value: string
} }
"HONEYCOMB_API_KEY": { HONEYCOMB_API_KEY: {
"type": "sst.sst.Secret" type: "sst.sst.Secret"
"value": string value: string
} }
"OPENAI_API_KEY": { OPENAI_API_KEY: {
"type": "sst.sst.Secret" type: "sst.sst.Secret"
"value": string value: string
} }
"STRIPE_SECRET_KEY": { STRIPE_SECRET_KEY: {
"type": "sst.sst.Secret" type: "sst.sst.Secret"
"value": string value: string
} }
"STRIPE_WEBHOOK_SECRET": { STRIPE_WEBHOOK_SECRET: {
"type": "sst.sst.Linkable" type: "sst.sst.Linkable"
"value": string value: string
} }
"Web": { Web: {
"type": "sst.cloudflare.Astro" type: "sst.cloudflare.Astro"
"url": string url: string
} }
"XAI_API_KEY": { XAI_API_KEY: {
"type": "sst.sst.Secret" type: "sst.sst.Secret"
"value": string value: string
} }
} }
} }
// cloudflare // cloudflare
import * as cloudflare from "@cloudflare/workers-types"; import * as cloudflare from "@cloudflare/workers-types"
declare module "sst" { declare module "sst" {
export interface Resource { export interface Resource {
"Api": cloudflare.Service Api: cloudflare.Service
"AuthApi": cloudflare.Service AuthApi: cloudflare.Service
"AuthStorage": cloudflare.KVNamespace AuthStorage: cloudflare.KVNamespace
"Bucket": cloudflare.R2Bucket Bucket: cloudflare.R2Bucket
"LogProcessor": cloudflare.Service LogProcessor: cloudflare.Service
} }
} }
import "sst" import "sst"
export {} export {}

View File

@@ -4,9 +4,6 @@
"compilerOptions": { "compilerOptions": {
"module": "ESNext", "module": "ESNext",
"moduleResolution": "bundler", "moduleResolution": "bundler",
"types": [ "types": ["@cloudflare/workers-types", "node"]
"@cloudflare/workers-types",
"node"
]
} }
} }

View File

@@ -6,4 +6,4 @@
/// <reference path="../../sst-env.d.ts" /> /// <reference path="../../sst-env.d.ts" />
import "sst" import "sst"
export {} export {}

2
github/sst-env.d.ts vendored
View File

@@ -6,4 +6,4 @@
/// <reference path="../sst-env.d.ts" /> /// <reference path="../sst-env.d.ts" />
import "sst" import "sst"
export {} export {}

View File

@@ -6,6 +6,7 @@
"packageManager": "bun@1.2.19", "packageManager": "bun@1.2.19",
"scripts": { "scripts": {
"dev": "bun run --conditions=development packages/opencode/src/index.ts", "dev": "bun run --conditions=development packages/opencode/src/index.ts",
"format": "bun run prettier --ignore-unknown --write $(git ls-files)",
"typecheck": "bun run --filter='*' typecheck", "typecheck": "bun run --filter='*' typecheck",
"generate": "(cd packages/sdk && ./js/script/generate.ts) && (cd packages/sdk/stainless && ./generate.ts)", "generate": "(cd packages/sdk && ./js/script/generate.ts) && (cd packages/sdk/stainless && ./generate.ts)",
"postinstall": "./script/hooks" "postinstall": "./script/hooks"

View File

@@ -6,87 +6,87 @@
import "sst" import "sst"
declare module "sst" { declare module "sst" {
export interface Resource { export interface Resource {
"ANTHROPIC_API_KEY": { ANTHROPIC_API_KEY: {
"type": "sst.sst.Secret" type: "sst.sst.Secret"
"value": string value: string
} }
"AUTH_API_URL": { AUTH_API_URL: {
"type": "sst.sst.Linkable" type: "sst.sst.Linkable"
"value": string value: string
} }
"BASETEN_API_KEY": { BASETEN_API_KEY: {
"type": "sst.sst.Secret" type: "sst.sst.Secret"
"value": string value: string
} }
"Console": { Console: {
"type": "sst.cloudflare.SolidStart" type: "sst.cloudflare.SolidStart"
"url": string url: string
} }
"Database": { Database: {
"database": string database: string
"host": string host: string
"password": string password: string
"port": number port: number
"type": "sst.sst.Linkable" type: "sst.sst.Linkable"
"username": string username: string
} }
"GITHUB_APP_ID": { GITHUB_APP_ID: {
"type": "sst.sst.Secret" type: "sst.sst.Secret"
"value": string value: string
} }
"GITHUB_APP_PRIVATE_KEY": { GITHUB_APP_PRIVATE_KEY: {
"type": "sst.sst.Secret" type: "sst.sst.Secret"
"value": string value: string
} }
"GITHUB_CLIENT_ID_CONSOLE": { GITHUB_CLIENT_ID_CONSOLE: {
"type": "sst.sst.Secret" type: "sst.sst.Secret"
"value": string value: string
} }
"GITHUB_CLIENT_SECRET_CONSOLE": { GITHUB_CLIENT_SECRET_CONSOLE: {
"type": "sst.sst.Secret" type: "sst.sst.Secret"
"value": string value: string
} }
"GOOGLE_CLIENT_ID": { GOOGLE_CLIENT_ID: {
"type": "sst.sst.Secret" type: "sst.sst.Secret"
"value": string value: string
} }
"HONEYCOMB_API_KEY": { HONEYCOMB_API_KEY: {
"type": "sst.sst.Secret" type: "sst.sst.Secret"
"value": string value: string
} }
"OPENAI_API_KEY": { OPENAI_API_KEY: {
"type": "sst.sst.Secret" type: "sst.sst.Secret"
"value": string value: string
} }
"STRIPE_SECRET_KEY": { STRIPE_SECRET_KEY: {
"type": "sst.sst.Secret" type: "sst.sst.Secret"
"value": string value: string
} }
"STRIPE_WEBHOOK_SECRET": { STRIPE_WEBHOOK_SECRET: {
"type": "sst.sst.Linkable" type: "sst.sst.Linkable"
"value": string value: string
} }
"Web": { Web: {
"type": "sst.cloudflare.Astro" type: "sst.cloudflare.Astro"
"url": string url: string
} }
"XAI_API_KEY": { XAI_API_KEY: {
"type": "sst.sst.Secret" type: "sst.sst.Secret"
"value": string value: string
} }
} }
} }
// cloudflare // cloudflare
import * as cloudflare from "@cloudflare/workers-types"; import * as cloudflare from "@cloudflare/workers-types"
declare module "sst" { declare module "sst" {
export interface Resource { export interface Resource {
"Api": cloudflare.Service Api: cloudflare.Service
"AuthApi": cloudflare.Service AuthApi: cloudflare.Service
"AuthStorage": cloudflare.KVNamespace AuthStorage: cloudflare.KVNamespace
"Bucket": cloudflare.R2Bucket Bucket: cloudflare.R2Bucket
"LogProcessor": cloudflare.Service LogProcessor: cloudflare.Service
} }
} }
import "sst" import "sst"
export {} export {}

View File

@@ -46,10 +46,7 @@ export namespace Fzf {
log.info("found", { filepath }) log.info("found", { filepath })
return { filepath } return { filepath }
} }
filepath = path.join( filepath = path.join(Global.Path.bin, "fzf" + (process.platform === "win32" ? ".exe" : ""))
Global.Path.bin,
"fzf" + (process.platform === "win32" ? ".exe" : ""),
)
const file = Bun.file(filepath) const file = Bun.file(filepath)
if (!(await file.exists())) { if (!(await file.exists())) {
@@ -57,18 +54,15 @@ export namespace Fzf {
const arch = archMap[process.arch as keyof typeof archMap] ?? "amd64" const arch = archMap[process.arch as keyof typeof archMap] ?? "amd64"
const config = PLATFORM[process.platform as keyof typeof PLATFORM] const config = PLATFORM[process.platform as keyof typeof PLATFORM]
if (!config) if (!config) throw new UnsupportedPlatformError({ platform: process.platform })
throw new UnsupportedPlatformError({ platform: process.platform })
const version = VERSION const version = VERSION
const platformName = const platformName = process.platform === "win32" ? "windows" : process.platform
process.platform === "win32" ? "windows" : process.platform
const filename = `fzf-${version}-${platformName}_${arch}.${config.extension}` const filename = `fzf-${version}-${platformName}_${arch}.${config.extension}`
const url = `https://github.com/junegunn/fzf/releases/download/v${version}/${filename}` const url = `https://github.com/junegunn/fzf/releases/download/v${version}/${filename}`
const response = await fetch(url) const response = await fetch(url)
if (!response.ok) if (!response.ok) throw new DownloadFailedError({ url, status: response.status })
throw new DownloadFailedError({ url, status: response.status })
const buffer = await response.arrayBuffer() const buffer = await response.arrayBuffer()
const archivePath = path.join(Global.Path.bin, filename) const archivePath = path.join(Global.Path.bin, filename)
@@ -87,13 +81,13 @@ export namespace Fzf {
}) })
} }
if (config.extension === "zip") { if (config.extension === "zip") {
const zipFileReader = new ZipReader(new BlobReader(new Blob([await Bun.file(archivePath).arrayBuffer()]))); const zipFileReader = new ZipReader(new BlobReader(new Blob([await Bun.file(archivePath).arrayBuffer()])))
const entries = await zipFileReader.getEntries(); const entries = await zipFileReader.getEntries()
let fzfEntry: any; let fzfEntry: any
for (const entry of entries) { for (const entry of entries) {
if (entry.filename === "fzf.exe") { if (entry.filename === "fzf.exe") {
fzfEntry = entry; fzfEntry = entry
break; break
} }
} }
@@ -101,18 +95,18 @@ export namespace Fzf {
throw new ExtractionFailedError({ throw new ExtractionFailedError({
filepath: archivePath, filepath: archivePath,
stderr: "fzf.exe not found in zip archive", stderr: "fzf.exe not found in zip archive",
}); })
} }
const fzfBlob = await fzfEntry.getData(new BlobWriter()); const fzfBlob = await fzfEntry.getData(new BlobWriter())
if (!fzfBlob) { if (!fzfBlob) {
throw new ExtractionFailedError({ throw new ExtractionFailedError({
filepath: archivePath, filepath: archivePath,
stderr: "Failed to extract fzf.exe from zip archive", stderr: "Failed to extract fzf.exe from zip archive",
}); })
} }
await Bun.write(filepath, await fzfBlob.arrayBuffer()); await Bun.write(filepath, await fzfBlob.arrayBuffer())
await zipFileReader.close(); await zipFileReader.close()
} }
await fs.unlink(archivePath) await fs.unlink(archivePath)
if (process.platform !== "win32") await fs.chmod(filepath, 0o755) if (process.platform !== "win32") await fs.chmod(filepath, 0o755)
@@ -127,4 +121,4 @@ export namespace Fzf {
const { filepath } = await state() const { filepath } = await state()
return filepath return filepath
} }
} }

View File

@@ -3,18 +3,16 @@ import { Log } from "../util/log"
export namespace FileTime { export namespace FileTime {
const log = Log.create({ service: "file.time" }) const log = Log.create({ service: "file.time" })
export const state = Instance.state( export const state = Instance.state(() => {
() => { const read: {
const read: { [sessionID: string]: {
[sessionID: string]: { [path: string]: Date | undefined
[path: string]: Date | undefined
}
} = {}
return {
read,
} }
}, } = {}
) return {
read,
}
})
export function read(sessionID: string, file: string) { export function read(sessionID: string, file: string) {
log.info("read", { sessionID, file }) log.info("read", { sessionID, file })

View File

@@ -25,8 +25,8 @@ export namespace Plugin {
worktree: Instance.worktree, worktree: Instance.worktree,
directory: Instance.directory, directory: Instance.directory,
$: Bun.$, $: Bun.$,
Tool: await import("../tool/tool").then(m => m.Tool), Tool: await import("../tool/tool").then((m) => m.Tool),
z: await import("zod").then(m => m.z), z: await import("zod").then((m) => m.z),
} }
const plugins = [...(config.plugin ?? [])] const plugins = [...(config.plugin ?? [])]
if (!Flag.OPENCODE_DISABLE_DEFAULT_PLUGINS) { if (!Flag.OPENCODE_DISABLE_DEFAULT_PLUGINS) {
@@ -79,10 +79,13 @@ export namespace Plugin {
for (const hook of hooks) { for (const hook of hooks) {
await hook.config?.(config) await hook.config?.(config)
// Let plugins register tools at startup // Let plugins register tools at startup
await hook["tool.register"]?.({}, { await hook["tool.register"]?.(
registerHTTP: ToolRegistry.registerHTTP, {},
register: ToolRegistry.register {
}) registerHTTP: ToolRegistry.registerHTTP,
register: ToolRegistry.register,
},
)
} }
Bus.subscribeAll(async (input) => { Bus.subscribeAll(async (input) => {
const hooks = await state().then((x) => x.hooks) const hooks = await state().then((x) => x.hooks)

View File

@@ -623,5 +623,7 @@ export function replace(content: string, oldString: string, newString: string, r
if (notFound) { if (notFound) {
throw new Error("oldString not found in content") throw new Error("oldString not found in content")
} }
throw new Error("oldString found multiple times and requires more code context to uniquely identify the intended match") throw new Error(
"oldString found multiple times and requires more code context to uniquely identify the intended match",
)
} }

View File

@@ -71,9 +71,7 @@ export namespace ToolRegistry {
break break
case "array": case "array":
if (!val.items) throw new Error(`array spec for ${key} requires 'items'`) if (!val.items) throw new Error(`array spec for ${key} requires 'items'`)
base = z.array( base = z.array(val.items === "string" ? z.string() : val.items === "number" ? z.number() : z.boolean())
val.items === "string" ? z.string() : val.items === "number" ? z.number() : z.boolean(),
)
break break
default: default:
base = z.any() base = z.any()

View File

@@ -11,14 +11,12 @@ const TodoInfo = z.object({
}) })
type TodoInfo = z.infer<typeof TodoInfo> type TodoInfo = z.infer<typeof TodoInfo>
const state = Instance.state( const state = Instance.state(() => {
() => { const todos: {
const todos: { [sessionId: string]: TodoInfo[]
[sessionId: string]: TodoInfo[] } = {}
} = {} return todos
return todos })
},
)
export const TodoWriteTool = Tool.define("todowrite", { export const TodoWriteTool = Tool.define("todowrite", {
description: DESCRIPTION_WRITE, description: DESCRIPTION_WRITE,

View File

@@ -6,4 +6,4 @@
/// <reference path="../../sst-env.d.ts" /> /// <reference path="../../sst-env.d.ts" />
import "sst" import "sst"
export {} export {}

View File

@@ -7,7 +7,7 @@ describe("BunProc registry configuration", () => {
// Read the bun/index.ts file // Read the bun/index.ts file
const bunIndexPath = path.join(__dirname, "../src/bun/index.ts") const bunIndexPath = path.join(__dirname, "../src/bun/index.ts")
const content = await fs.readFile(bunIndexPath, "utf-8") const content = await fs.readFile(bunIndexPath, "utf-8")
// Verify that no hardcoded registry is present // Verify that no hardcoded registry is present
expect(content).not.toContain("--registry=") expect(content).not.toContain("--registry=")
expect(content).not.toContain("hasNpmRcConfig") expect(content).not.toContain("hasNpmRcConfig")
@@ -18,7 +18,7 @@ describe("BunProc registry configuration", () => {
// Read the bun/index.ts file // Read the bun/index.ts file
const bunIndexPath = path.join(__dirname, "../src/bun/index.ts") const bunIndexPath = path.join(__dirname, "../src/bun/index.ts")
const content = await fs.readFile(bunIndexPath, "utf-8") const content = await fs.readFile(bunIndexPath, "utf-8")
// Verify that it uses Bun's default resolution // Verify that it uses Bun's default resolution
expect(content).toContain("Bun's default registry resolution") expect(content).toContain("Bun's default registry resolution")
expect(content).toContain("Bun will use them automatically") expect(content).toContain("Bun will use them automatically")
@@ -29,22 +29,22 @@ describe("BunProc registry configuration", () => {
// Read the bun/index.ts file // Read the bun/index.ts file
const bunIndexPath = path.join(__dirname, "../src/bun/index.ts") const bunIndexPath = path.join(__dirname, "../src/bun/index.ts")
const content = await fs.readFile(bunIndexPath, "utf-8") const content = await fs.readFile(bunIndexPath, "utf-8")
// Extract the install function // Extract the install function
const installFunctionMatch = content.match(/export async function install[\s\S]*?^ }/m) const installFunctionMatch = content.match(/export async function install[\s\S]*?^ }/m)
expect(installFunctionMatch).toBeTruthy() expect(installFunctionMatch).toBeTruthy()
if (installFunctionMatch) { if (installFunctionMatch) {
const installFunction = installFunctionMatch[0] const installFunction = installFunctionMatch[0]
// Verify expected arguments are present // Verify expected arguments are present
expect(installFunction).toContain('"add"') expect(installFunction).toContain('"add"')
expect(installFunction).toContain('"--force"') expect(installFunction).toContain('"--force"')
expect(installFunction).toContain('"--exact"') expect(installFunction).toContain('"--exact"')
expect(installFunction).toContain('"--cwd"') expect(installFunction).toContain('"--cwd"')
expect(installFunction).toContain('Global.Path.cache') expect(installFunction).toContain("Global.Path.cache")
expect(installFunction).toContain('pkg + "@" + version') expect(installFunction).toContain('pkg + "@" + version')
// Verify no registry argument is added // Verify no registry argument is added
expect(installFunction).not.toContain('"--registry"') expect(installFunction).not.toContain('"--registry"')
expect(installFunction).not.toContain('args.push("--registry') expect(installFunction).not.toContain('args.push("--registry')

View File

@@ -2,13 +2,7 @@
"$schema": "https://json.schemastore.org/tsconfig", "$schema": "https://json.schemastore.org/tsconfig",
"extends": "@tsconfig/bun/tsconfig.json", "extends": "@tsconfig/bun/tsconfig.json",
"compilerOptions": { "compilerOptions": {
"lib": [ "lib": ["ESNext", "DOM", "DOM.Iterable"],
"ESNext", "customConditions": ["development"]
"DOM",
"DOM.Iterable"
],
"customConditions": [
"development"
]
} }
} }

View File

@@ -19,10 +19,7 @@ export type PluginInput = {
worktree: string worktree: string
$: BunShell $: BunShell
Tool: { Tool: {
define( define(id: string, init: any | (() => Promise<any>)): any
id: string,
init: any | (() => Promise<any>)
): any
} }
z: any // Zod instance for creating schemas z: any // Zod instance for creating schemas
} }
@@ -133,7 +130,7 @@ export interface Hooks {
input: {}, input: {},
output: { output: {
registerHTTP: (tool: HttpToolRegistration) => void | Promise<void> registerHTTP: (tool: HttpToolRegistration) => void | Promise<void>
register: (tool: any) => void | Promise<void> // Tool.Info type from opencode register: (tool: any) => void | Promise<void> // Tool.Info type from opencode
}, },
) => Promise<void> ) => Promise<void>
} }

View File

@@ -6,4 +6,4 @@
/// <reference path="../../sst-env.d.ts" /> /// <reference path="../../sst-env.d.ts" />
import "sst" import "sst"
export {} export {}

View File

@@ -6,16 +6,8 @@
"module": "preserve", "module": "preserve",
"declaration": true, "declaration": true,
"moduleResolution": "bundler", "moduleResolution": "bundler",
"lib": [ "lib": ["es2022", "dom", "dom.iterable"],
"es2022", "customConditions": ["development"]
"dom",
"dom.iterable"
],
"customConditions": [
"development"
]
}, },
"include": [ "include": ["src"]
"src"
]
} }

View File

@@ -2,15 +2,15 @@ name: CI
on: on:
push: push:
branches-ignore: branches-ignore:
- 'generated' - "generated"
- 'codegen/**' - "codegen/**"
- 'integrated/**' - "integrated/**"
- 'stl-preview-head/**' - "stl-preview-head/**"
- 'stl-preview-base/**' - "stl-preview-base/**"
pull_request: pull_request:
branches-ignore: branches-ignore:
- 'stl-preview-head/**' - "stl-preview-head/**"
- 'stl-preview-base/**' - "stl-preview-base/**"
jobs: jobs:
lint: lint:

View File

@@ -1,3 +1,3 @@
{ {
".": "0.8.0" ".": "0.8.0"
} }

View File

@@ -6,7 +6,7 @@ Full Changelog: [v0.7.0...v0.8.0](https://github.com/sst/opencode-sdk-go/compare
### Features ### Features
* **api:** api update ([ae87a71](https://github.com/sst/opencode-sdk-go/commit/ae87a71949994590ace8285a39f0991ef34b664d)) - **api:** api update ([ae87a71](https://github.com/sst/opencode-sdk-go/commit/ae87a71949994590ace8285a39f0991ef34b664d))
## 0.7.0 (2025-09-01) ## 0.7.0 (2025-09-01)
@@ -14,7 +14,7 @@ Full Changelog: [v0.6.0...v0.7.0](https://github.com/sst/opencode-sdk-go/compare
### Features ### Features
* **api:** api update ([64bb1b1](https://github.com/sst/opencode-sdk-go/commit/64bb1b1ee0cbe153abc6fb7bd9703b47911724d4)) - **api:** api update ([64bb1b1](https://github.com/sst/opencode-sdk-go/commit/64bb1b1ee0cbe153abc6fb7bd9703b47911724d4))
## 0.6.0 (2025-09-01) ## 0.6.0 (2025-09-01)
@@ -22,7 +22,7 @@ Full Changelog: [v0.5.0...v0.6.0](https://github.com/sst/opencode-sdk-go/compare
### Features ### Features
* **api:** api update ([928e384](https://github.com/sst/opencode-sdk-go/commit/928e3843355f96899f046f002b84372281dad0c8)) - **api:** api update ([928e384](https://github.com/sst/opencode-sdk-go/commit/928e3843355f96899f046f002b84372281dad0c8))
## 0.5.0 (2025-08-31) ## 0.5.0 (2025-08-31)
@@ -30,7 +30,7 @@ Full Changelog: [v0.4.0...v0.5.0](https://github.com/sst/opencode-sdk-go/compare
### Features ### Features
* **api:** api update ([44b281d](https://github.com/sst/opencode-sdk-go/commit/44b281d0bb39c5022a984ac9d0fca1529ccc0604)) - **api:** api update ([44b281d](https://github.com/sst/opencode-sdk-go/commit/44b281d0bb39c5022a984ac9d0fca1529ccc0604))
## 0.4.0 (2025-08-31) ## 0.4.0 (2025-08-31)
@@ -38,7 +38,7 @@ Full Changelog: [v0.3.0...v0.4.0](https://github.com/sst/opencode-sdk-go/compare
### Features ### Features
* **api:** api update ([fa9d6ec](https://github.com/sst/opencode-sdk-go/commit/fa9d6ec6472e62f4f6605d0a71a7aa8bf8a24559)) - **api:** api update ([fa9d6ec](https://github.com/sst/opencode-sdk-go/commit/fa9d6ec6472e62f4f6605d0a71a7aa8bf8a24559))
## 0.3.0 (2025-08-31) ## 0.3.0 (2025-08-31)
@@ -46,7 +46,7 @@ Full Changelog: [v0.2.0...v0.3.0](https://github.com/sst/opencode-sdk-go/compare
### Features ### Features
* **api:** api update ([aae1c06](https://github.com/sst/opencode-sdk-go/commit/aae1c06bb5a93a1cd9c589846a84b3f16246f5da)) - **api:** api update ([aae1c06](https://github.com/sst/opencode-sdk-go/commit/aae1c06bb5a93a1cd9c589846a84b3f16246f5da))
## 0.2.0 (2025-08-31) ## 0.2.0 (2025-08-31)
@@ -54,7 +54,7 @@ Full Changelog: [v0.1.0...v0.2.0](https://github.com/sst/opencode-sdk-go/compare
### Features ### Features
* **api:** api update ([1472790](https://github.com/sst/opencode-sdk-go/commit/1472790542515f47bd46e2a9e28d8afea024cf9c)) - **api:** api update ([1472790](https://github.com/sst/opencode-sdk-go/commit/1472790542515f47bd46e2a9e28d8afea024cf9c))
## 0.1.0 (2025-08-31) ## 0.1.0 (2025-08-31)
@@ -62,61 +62,59 @@ Full Changelog: [v0.0.1...v0.1.0](https://github.com/sst/opencode-sdk-go/compare
### Features ### Features
* **api:** api update ([3f03ddd](https://github.com/sst/opencode-sdk-go/commit/3f03dddd5ec0de98f99ce48679077dcae9ceffd6)) - **api:** api update ([3f03ddd](https://github.com/sst/opencode-sdk-go/commit/3f03dddd5ec0de98f99ce48679077dcae9ceffd6))
* **api:** api update ([e9f79c4](https://github.com/sst/opencode-sdk-go/commit/e9f79c4792b21ef64ab0431ffd76f5a71e04d182)) - **api:** api update ([e9f79c4](https://github.com/sst/opencode-sdk-go/commit/e9f79c4792b21ef64ab0431ffd76f5a71e04d182))
* **api:** api update ([139a686](https://github.com/sst/opencode-sdk-go/commit/139a6862d2f0ab0c8ea791663d736868be3e96e6)) - **api:** api update ([139a686](https://github.com/sst/opencode-sdk-go/commit/139a6862d2f0ab0c8ea791663d736868be3e96e6))
* **api:** api update ([2ed0800](https://github.com/sst/opencode-sdk-go/commit/2ed0800b2c5b99877e9f7fde669a6c005fad6b77)) - **api:** api update ([2ed0800](https://github.com/sst/opencode-sdk-go/commit/2ed0800b2c5b99877e9f7fde669a6c005fad6b77))
* **api:** api update ([88a87a4](https://github.com/sst/opencode-sdk-go/commit/88a87a458f56ce0c18b502c73da933f614f56e8b)) - **api:** api update ([88a87a4](https://github.com/sst/opencode-sdk-go/commit/88a87a458f56ce0c18b502c73da933f614f56e8b))
* **api:** api update ([0e5d65b](https://github.com/sst/opencode-sdk-go/commit/0e5d65b571e7b30dc6347e6730098878ebba3a42)) - **api:** api update ([0e5d65b](https://github.com/sst/opencode-sdk-go/commit/0e5d65b571e7b30dc6347e6730098878ebba3a42))
* **api:** api update ([ba381f1](https://github.com/sst/opencode-sdk-go/commit/ba381f1e07aad24e9824df7d53befae2a644f69f)) - **api:** api update ([ba381f1](https://github.com/sst/opencode-sdk-go/commit/ba381f1e07aad24e9824df7d53befae2a644f69f))
* **api:** api update ([3f429f5](https://github.com/sst/opencode-sdk-go/commit/3f429f5b4be5607433ef5fdc0d5bf67fe590d039)) - **api:** api update ([3f429f5](https://github.com/sst/opencode-sdk-go/commit/3f429f5b4be5607433ef5fdc0d5bf67fe590d039))
* **api:** api update ([9f34787](https://github.com/sst/opencode-sdk-go/commit/9f347876b35b7f898060c1a5f71c322e95978e3e)) - **api:** api update ([9f34787](https://github.com/sst/opencode-sdk-go/commit/9f347876b35b7f898060c1a5f71c322e95978e3e))
* **api:** api update ([379c8e0](https://github.com/sst/opencode-sdk-go/commit/379c8e00197e13aebaf2f2d61277b125f1f90011)) - **api:** api update ([379c8e0](https://github.com/sst/opencode-sdk-go/commit/379c8e00197e13aebaf2f2d61277b125f1f90011))
* **api:** api update ([550511c](https://github.com/sst/opencode-sdk-go/commit/550511c4c5b5055ac8ff22b7b11731331bd9d088)) - **api:** api update ([550511c](https://github.com/sst/opencode-sdk-go/commit/550511c4c5b5055ac8ff22b7b11731331bd9d088))
* **api:** api update ([547f0c2](https://github.com/sst/opencode-sdk-go/commit/547f0c262f2df1ce83eaa7267d68be64bb29b841)) - **api:** api update ([547f0c2](https://github.com/sst/opencode-sdk-go/commit/547f0c262f2df1ce83eaa7267d68be64bb29b841))
* **api:** api update ([b7b0720](https://github.com/sst/opencode-sdk-go/commit/b7b07204bff314da24b1819c128835a43ef64065)) - **api:** api update ([b7b0720](https://github.com/sst/opencode-sdk-go/commit/b7b07204bff314da24b1819c128835a43ef64065))
* **api:** api update ([7250ffc](https://github.com/sst/opencode-sdk-go/commit/7250ffcba262b916c958ddecc2a42927982db39f)) - **api:** api update ([7250ffc](https://github.com/sst/opencode-sdk-go/commit/7250ffcba262b916c958ddecc2a42927982db39f))
* **api:** api update ([17fbab7](https://github.com/sst/opencode-sdk-go/commit/17fbab73111a3eae488737c69b12370bc69c65f7)) - **api:** api update ([17fbab7](https://github.com/sst/opencode-sdk-go/commit/17fbab73111a3eae488737c69b12370bc69c65f7))
* **api:** api update ([1270b5c](https://github.com/sst/opencode-sdk-go/commit/1270b5cd81e6ac769dcd92ade6d877891bf51bd5)) - **api:** api update ([1270b5c](https://github.com/sst/opencode-sdk-go/commit/1270b5cd81e6ac769dcd92ade6d877891bf51bd5))
* **api:** api update ([a238d4a](https://github.com/sst/opencode-sdk-go/commit/a238d4abd6ed7d15f3547d27a4b6ecf4aec8431e)) - **api:** api update ([a238d4a](https://github.com/sst/opencode-sdk-go/commit/a238d4abd6ed7d15f3547d27a4b6ecf4aec8431e))
* **api:** api update ([7475655](https://github.com/sst/opencode-sdk-go/commit/7475655aca577fe4f807c2f02f92171f6a358e9c)) - **api:** api update ([7475655](https://github.com/sst/opencode-sdk-go/commit/7475655aca577fe4f807c2f02f92171f6a358e9c))
* **api:** api update ([429d258](https://github.com/sst/opencode-sdk-go/commit/429d258bb56e9cdeb1528be3944bf5537ac26a96)) - **api:** api update ([429d258](https://github.com/sst/opencode-sdk-go/commit/429d258bb56e9cdeb1528be3944bf5537ac26a96))
* **api:** api update ([f250915](https://github.com/sst/opencode-sdk-go/commit/f2509157eaf1b453e741ee9482127cad2e3ace25)) - **api:** api update ([f250915](https://github.com/sst/opencode-sdk-go/commit/f2509157eaf1b453e741ee9482127cad2e3ace25))
* **api:** api update ([5efc987](https://github.com/sst/opencode-sdk-go/commit/5efc987353801d1e772c20edf162b1c75da32743)) - **api:** api update ([5efc987](https://github.com/sst/opencode-sdk-go/commit/5efc987353801d1e772c20edf162b1c75da32743))
* **api:** api update ([98a8350](https://github.com/sst/opencode-sdk-go/commit/98a83504f7cfc361e83314c3e79a4e9ff53f0560)) - **api:** api update ([98a8350](https://github.com/sst/opencode-sdk-go/commit/98a83504f7cfc361e83314c3e79a4e9ff53f0560))
* **api:** api update ([6da8bf8](https://github.com/sst/opencode-sdk-go/commit/6da8bf8bfe91d45991fb580753d77c5534fc0b1b)) - **api:** api update ([6da8bf8](https://github.com/sst/opencode-sdk-go/commit/6da8bf8bfe91d45991fb580753d77c5534fc0b1b))
* **api:** api update ([f8c7148](https://github.com/sst/opencode-sdk-go/commit/f8c7148ae56143823186e2675a78e82676154956)) - **api:** api update ([f8c7148](https://github.com/sst/opencode-sdk-go/commit/f8c7148ae56143823186e2675a78e82676154956))
* **api:** manual updates ([7cf038f](https://github.com/sst/opencode-sdk-go/commit/7cf038ffae5da1b77e1cef11b5fa166a53b467f2)) - **api:** manual updates ([7cf038f](https://github.com/sst/opencode-sdk-go/commit/7cf038ffae5da1b77e1cef11b5fa166a53b467f2))
* **api:** update via SDK Studio ([068a0eb](https://github.com/sst/opencode-sdk-go/commit/068a0eb025010da0c8d86fa1bb496a39dbedcef9)) - **api:** update via SDK Studio ([068a0eb](https://github.com/sst/opencode-sdk-go/commit/068a0eb025010da0c8d86fa1bb496a39dbedcef9))
* **api:** update via SDK Studio ([ca651ed](https://github.com/sst/opencode-sdk-go/commit/ca651edaf71d1f3678f929287474f5bc4f1aad10)) - **api:** update via SDK Studio ([ca651ed](https://github.com/sst/opencode-sdk-go/commit/ca651edaf71d1f3678f929287474f5bc4f1aad10))
* **api:** update via SDK Studio ([13550a5](https://github.com/sst/opencode-sdk-go/commit/13550a5c65d77325e945ed99fe0799cd1107b775)) - **api:** update via SDK Studio ([13550a5](https://github.com/sst/opencode-sdk-go/commit/13550a5c65d77325e945ed99fe0799cd1107b775))
* **api:** update via SDK Studio ([7b73730](https://github.com/sst/opencode-sdk-go/commit/7b73730c7fa62ba966dda3541c3e97b49be8d2bf)) - **api:** update via SDK Studio ([7b73730](https://github.com/sst/opencode-sdk-go/commit/7b73730c7fa62ba966dda3541c3e97b49be8d2bf))
* **api:** update via SDK Studio ([9e39a59](https://github.com/sst/opencode-sdk-go/commit/9e39a59b3d5d1bd5e64633732521fb28362cc70e)) - **api:** update via SDK Studio ([9e39a59](https://github.com/sst/opencode-sdk-go/commit/9e39a59b3d5d1bd5e64633732521fb28362cc70e))
* **api:** update via SDK Studio ([9609d1b](https://github.com/sst/opencode-sdk-go/commit/9609d1b1db7806d00cb846c9914cb4935cdedf52)) - **api:** update via SDK Studio ([9609d1b](https://github.com/sst/opencode-sdk-go/commit/9609d1b1db7806d00cb846c9914cb4935cdedf52))
* **api:** update via SDK Studio ([51315fa](https://github.com/sst/opencode-sdk-go/commit/51315fa2eae424743ea79701e67d44447c44144d)) - **api:** update via SDK Studio ([51315fa](https://github.com/sst/opencode-sdk-go/commit/51315fa2eae424743ea79701e67d44447c44144d))
* **api:** update via SDK Studio ([af07955](https://github.com/sst/opencode-sdk-go/commit/af0795543240aefaf04fc7663a348825541c79ed)) - **api:** update via SDK Studio ([af07955](https://github.com/sst/opencode-sdk-go/commit/af0795543240aefaf04fc7663a348825541c79ed))
* **api:** update via SDK Studio ([5e3468a](https://github.com/sst/opencode-sdk-go/commit/5e3468a0aaa5ed3b13e019c3a24e0ba9147d1675)) - **api:** update via SDK Studio ([5e3468a](https://github.com/sst/opencode-sdk-go/commit/5e3468a0aaa5ed3b13e019c3a24e0ba9147d1675))
* **api:** update via SDK Studio ([0a73e04](https://github.com/sst/opencode-sdk-go/commit/0a73e04c23c90b2061611edaa8fd6282dc0ce397)) - **api:** update via SDK Studio ([0a73e04](https://github.com/sst/opencode-sdk-go/commit/0a73e04c23c90b2061611edaa8fd6282dc0ce397))
* **api:** update via SDK Studio ([9b7883a](https://github.com/sst/opencode-sdk-go/commit/9b7883a144eeac526d9d04538e0876a9d18bb844)) - **api:** update via SDK Studio ([9b7883a](https://github.com/sst/opencode-sdk-go/commit/9b7883a144eeac526d9d04538e0876a9d18bb844))
* **client:** expand max streaming buffer size ([76303e5](https://github.com/sst/opencode-sdk-go/commit/76303e51067e78e732af26ced9d83b8bad7655c3)) - **client:** expand max streaming buffer size ([76303e5](https://github.com/sst/opencode-sdk-go/commit/76303e51067e78e732af26ced9d83b8bad7655c3))
* **client:** support optional json html escaping ([449748f](https://github.com/sst/opencode-sdk-go/commit/449748f35a1d8cb6f91dc36d25bf9489f4f371bd)) - **client:** support optional json html escaping ([449748f](https://github.com/sst/opencode-sdk-go/commit/449748f35a1d8cb6f91dc36d25bf9489f4f371bd))
### Bug Fixes ### Bug Fixes
* **client:** process custom base url ahead of time ([9b360d6](https://github.com/sst/opencode-sdk-go/commit/9b360d642cf6f302104308af5622e17099899e5f)) - **client:** process custom base url ahead of time ([9b360d6](https://github.com/sst/opencode-sdk-go/commit/9b360d642cf6f302104308af5622e17099899e5f))
* **client:** resolve lint errors in streaming tests ([4d36cb0](https://github.com/sst/opencode-sdk-go/commit/4d36cb09fc9d436734d5dab1c499acaa88568ff7)) - **client:** resolve lint errors in streaming tests ([4d36cb0](https://github.com/sst/opencode-sdk-go/commit/4d36cb09fc9d436734d5dab1c499acaa88568ff7))
* close body before retrying ([4da3f7f](https://github.com/sst/opencode-sdk-go/commit/4da3f7f372bad222a189ba3eabcfde3373166ae5)) - close body before retrying ([4da3f7f](https://github.com/sst/opencode-sdk-go/commit/4da3f7f372bad222a189ba3eabcfde3373166ae5))
* don't try to deserialize as json when ResponseBodyInto is []byte ([595291f](https://github.com/sst/opencode-sdk-go/commit/595291f6dba6af472f160b9f8e3d145002f43a4a)) - don't try to deserialize as json when ResponseBodyInto is []byte ([595291f](https://github.com/sst/opencode-sdk-go/commit/595291f6dba6af472f160b9f8e3d145002f43a4a))
### Chores ### Chores
* **ci:** only run for pushes and fork pull requests ([bea59b8](https://github.com/sst/opencode-sdk-go/commit/bea59b886800ef555f89c47a9256d6392ed2e53d)) - **ci:** only run for pushes and fork pull requests ([bea59b8](https://github.com/sst/opencode-sdk-go/commit/bea59b886800ef555f89c47a9256d6392ed2e53d))
* **internal:** codegen related update ([6a22ce6](https://github.com/sst/opencode-sdk-go/commit/6a22ce6df155f5003e80b8a75686a9e513a5568a)) - **internal:** codegen related update ([6a22ce6](https://github.com/sst/opencode-sdk-go/commit/6a22ce6df155f5003e80b8a75686a9e513a5568a))
* **internal:** fix lint script for tests ([391c482](https://github.com/sst/opencode-sdk-go/commit/391c482148ed0a77c4ad52807abeb2d540b56797)) - **internal:** fix lint script for tests ([391c482](https://github.com/sst/opencode-sdk-go/commit/391c482148ed0a77c4ad52807abeb2d540b56797))
* **internal:** update comment in script ([b7f1c3e](https://github.com/sst/opencode-sdk-go/commit/b7f1c3e16935c71e243004b8f321d661cd8e9474)) - **internal:** update comment in script ([b7f1c3e](https://github.com/sst/opencode-sdk-go/commit/b7f1c3e16935c71e243004b8f321d661cd8e9474))
* lint tests ([616796b](https://github.com/sst/opencode-sdk-go/commit/616796b761704bde6be5c6c2428f28c79c7f05ff)) - lint tests ([616796b](https://github.com/sst/opencode-sdk-go/commit/616796b761704bde6be5c6c2428f28c79c7f05ff))
* lint tests in subpackages ([50c82ff](https://github.com/sst/opencode-sdk-go/commit/50c82ff0757c973834b68adc22566b70f767b611)) - lint tests in subpackages ([50c82ff](https://github.com/sst/opencode-sdk-go/commit/50c82ff0757c973834b68adc22566b70f767b611))
* sync repo ([2f34d5d](https://github.com/sst/opencode-sdk-go/commit/2f34d5d53e56e9cdc3df99be7ee7efc83dd977a3)) - sync repo ([2f34d5d](https://github.com/sst/opencode-sdk-go/commit/2f34d5d53e56e9cdc3df99be7ee7efc83dd977a3))
* update @stainless-api/prism-cli to v5.15.0 ([2f24852](https://github.com/sst/opencode-sdk-go/commit/2f2485216d4f4891d1fbfbc23ff8410c2f35152a)) - update @stainless-api/prism-cli to v5.15.0 ([2f24852](https://github.com/sst/opencode-sdk-go/commit/2f2485216d4f4891d1fbfbc23ff8410c2f35152a))

View File

@@ -60,8 +60,5 @@
} }
], ],
"release-type": "go", "release-type": "go",
"extra-files": [ "extra-files": ["internal/version.go", "README.md"]
"internal/version.go", }
"README.md"
]
}

View File

@@ -14,7 +14,7 @@ await createClient({
input: "./openapi.json", input: "./openapi.json",
output: { output: {
path: "./src/gen", path: "./src/gen",
tsConfigPath: path.join(dir, 'tsconfig.json') tsConfigPath: path.join(dir, "tsconfig.json"),
}, },
plugins: [ plugins: [
{ {

View File

@@ -105,7 +105,7 @@ export function createOpencodeTui(options?: TuiOptions) {
const proc = spawn(`opencode`, args, { const proc = spawn(`opencode`, args, {
signal: options?.signal, signal: options?.signal,
stdio: 'inherit', stdio: "inherit",
env: { env: {
...process.env, ...process.env,
OPENCODE_CONFIG_CONTENT: JSON.stringify(options?.config ?? {}), OPENCODE_CONFIG_CONTENT: JSON.stringify(options?.config ?? {}),

View File

@@ -6,4 +6,4 @@
/// <reference path="../../../sst-env.d.ts" /> /// <reference path="../../../sst-env.d.ts" />
import "sst" import "sst"
export {} export {}

View File

@@ -6,16 +6,8 @@
"module": "nodenext", "module": "nodenext",
"declaration": true, "declaration": true,
"moduleResolution": "nodenext", "moduleResolution": "nodenext",
"lib": [ "lib": ["es2022", "dom", "dom.iterable"],
"es2022", "customConditions": ["development"]
"dom",
"dom.iterable"
],
"customConditions": [
"development"
]
}, },
"include": [ "include": ["src"]
"src"
]
} }

View File

@@ -1,219 +1,218 @@
{ {
"$schema": "https://opencode.ai/theme.json", "$schema": "https://opencode.ai/theme.json",
"defs": { "defs": {
"vesperBg": "#101010", "vesperBg": "#101010",
"vesperFg": "#FFF", "vesperFg": "#FFF",
"vesperComment": "#8b8b8b94", "vesperComment": "#8b8b8b94",
"vesperKeyword": "#A0A0A0", "vesperKeyword": "#A0A0A0",
"vesperFunction": "#FFC799", "vesperFunction": "#FFC799",
"vesperString": "#99FFE4", "vesperString": "#99FFE4",
"vesperNumber": "#FFC799", "vesperNumber": "#FFC799",
"vesperError": "#FF8080", "vesperError": "#FF8080",
"vesperWarning": "#FFC799", "vesperWarning": "#FFC799",
"vesperSuccess": "#99FFE4", "vesperSuccess": "#99FFE4",
"vesperMuted": "#A0A0A0" "vesperMuted": "#A0A0A0"
},
"theme": {
"primary": {
"dark": "#FFC799",
"light": "#FFC799"
}, },
"theme": { "secondary": {
"primary": { "dark": "#99FFE4",
"dark": "#FFC799", "light": "#99FFE4"
"light": "#FFC799" },
}, "accent": {
"secondary": { "dark": "#FFC799",
"dark": "#99FFE4", "light": "#FFC799"
"light": "#99FFE4" },
}, "error": {
"accent": { "dark": "vesperError",
"dark": "#FFC799", "light": "vesperError"
"light": "#FFC799" },
}, "warning": {
"error": { "dark": "vesperWarning",
"dark": "vesperError", "light": "vesperWarning"
"light": "vesperError" },
}, "success": {
"warning": { "dark": "vesperSuccess",
"dark": "vesperWarning", "light": "vesperSuccess"
"light": "vesperWarning" },
}, "info": {
"success": { "dark": "#FFC799",
"dark": "vesperSuccess", "light": "#FFC799"
"light": "vesperSuccess" },
}, "text": {
"info": { "dark": "vesperFg",
"dark": "#FFC799", "light": "vesperBg"
"light": "#FFC799" },
}, "textMuted": {
"text": { "dark": "vesperMuted",
"dark": "vesperFg", "light": "vesperMuted"
"light": "vesperBg" },
}, "background": {
"textMuted": { "dark": "vesperBg",
"dark": "vesperMuted", "light": "#FFF"
"light": "vesperMuted" },
}, "backgroundPanel": {
"background": { "dark": "vesperBg",
"dark": "vesperBg", "light": "#F0F0F0"
"light": "#FFF" },
}, "backgroundElement": {
"backgroundPanel": { "dark": "vesperBg",
"dark": "vesperBg", "light": "#E0E0E0"
"light": "#F0F0F0" },
}, "border": {
"backgroundElement": { "dark": "#282828",
"dark": "vesperBg", "light": "#D0D0D0"
"light": "#E0E0E0" },
}, "borderActive": {
"border": { "dark": "#FFC799",
"dark": "#282828", "light": "#FFC799"
"light": "#D0D0D0" },
}, "borderSubtle": {
"borderActive": { "dark": "#1C1C1C",
"dark": "#FFC799", "light": "#E8E8E8"
"light": "#FFC799" },
}, "diffAdded": {
"borderSubtle": { "dark": "vesperSuccess",
"dark": "#1C1C1C", "light": "vesperSuccess"
"light": "#E8E8E8" },
}, "diffRemoved": {
"diffAdded": { "dark": "vesperError",
"dark": "vesperSuccess", "light": "vesperError"
"light": "vesperSuccess" },
}, "diffContext": {
"diffRemoved": { "dark": "vesperMuted",
"dark": "vesperError", "light": "vesperMuted"
"light": "vesperError" },
}, "diffHunkHeader": {
"diffContext": { "dark": "vesperMuted",
"dark": "vesperMuted", "light": "vesperMuted"
"light": "vesperMuted" },
}, "diffHighlightAdded": {
"diffHunkHeader": { "dark": "vesperSuccess",
"dark": "vesperMuted", "light": "vesperSuccess"
"light": "vesperMuted" },
}, "diffHighlightRemoved": {
"diffHighlightAdded": { "dark": "vesperError",
"dark": "vesperSuccess", "light": "vesperError"
"light": "vesperSuccess" },
}, "diffAddedBg": {
"diffHighlightRemoved": { "dark": "#0d2818",
"dark": "vesperError", "light": "#e8f5e8"
"light": "vesperError" },
}, "diffRemovedBg": {
"diffAddedBg": { "dark": "#281a1a",
"dark": "#0d2818", "light": "#f5e8e8"
"light": "#e8f5e8" },
}, "diffContextBg": {
"diffRemovedBg": { "dark": "vesperBg",
"dark": "#281a1a", "light": "#F8F8F8"
"light": "#f5e8e8" },
}, "diffLineNumber": {
"diffContextBg": { "dark": "#505050",
"dark": "vesperBg", "light": "#808080"
"light": "#F8F8F8" },
}, "diffAddedLineNumberBg": {
"diffLineNumber": { "dark": "#0d2818",
"dark": "#505050", "light": "#e8f5e8"
"light": "#808080" },
}, "diffRemovedLineNumberBg": {
"diffAddedLineNumberBg": { "dark": "#281a1a",
"dark": "#0d2818", "light": "#f5e8e8"
"light": "#e8f5e8" },
}, "markdownText": {
"diffRemovedLineNumberBg": { "dark": "vesperFg",
"dark": "#281a1a", "light": "vesperBg"
"light": "#f5e8e8" },
}, "markdownHeading": {
"markdownText": { "dark": "#FFC799",
"dark": "vesperFg", "light": "#FFC799"
"light": "vesperBg" },
}, "markdownLink": {
"markdownHeading": { "dark": "#FFC799",
"dark": "#FFC799", "light": "#FFC799"
"light": "#FFC799" },
}, "markdownLinkText": {
"markdownLink": { "dark": "vesperMuted",
"dark": "#FFC799", "light": "vesperMuted"
"light": "#FFC799" },
}, "markdownCode": {
"markdownLinkText": { "dark": "vesperMuted",
"dark": "vesperMuted", "light": "vesperMuted"
"light": "vesperMuted" },
}, "markdownBlockQuote": {
"markdownCode": { "dark": "vesperFg",
"dark": "vesperMuted", "light": "vesperBg"
"light": "vesperMuted" },
}, "markdownEmph": {
"markdownBlockQuote": { "dark": "vesperFg",
"dark": "vesperFg", "light": "vesperBg"
"light": "vesperBg" },
}, "markdownStrong": {
"markdownEmph": { "dark": "vesperFg",
"dark": "vesperFg", "light": "vesperBg"
"light": "vesperBg" },
}, "markdownHorizontalRule": {
"markdownStrong": { "dark": "#65737E",
"dark": "vesperFg", "light": "#65737E"
"light": "vesperBg" },
}, "markdownListItem": {
"markdownHorizontalRule": { "dark": "vesperFg",
"dark": "#65737E", "light": "vesperBg"
"light": "#65737E" },
}, "markdownListEnumeration": {
"markdownListItem": { "dark": "vesperFg",
"dark": "vesperFg", "light": "vesperBg"
"light": "vesperBg" },
}, "markdownImage": {
"markdownListEnumeration": { "dark": "#FFC799",
"dark": "vesperFg", "light": "#FFC799"
"light": "vesperBg" },
}, "markdownImageText": {
"markdownImage": { "dark": "vesperMuted",
"dark": "#FFC799", "light": "vesperMuted"
"light": "#FFC799" },
}, "markdownCodeBlock": {
"markdownImageText": { "dark": "vesperFg",
"dark": "vesperMuted", "light": "vesperBg"
"light": "vesperMuted" },
}, "syntaxComment": {
"markdownCodeBlock": { "dark": "vesperComment",
"dark": "vesperFg", "light": "vesperComment"
"light": "vesperBg" },
}, "syntaxKeyword": {
"syntaxComment": { "dark": "vesperKeyword",
"dark": "vesperComment", "light": "vesperKeyword"
"light": "vesperComment" },
}, "syntaxFunction": {
"syntaxKeyword": { "dark": "vesperFunction",
"dark": "vesperKeyword", "light": "vesperFunction"
"light": "vesperKeyword" },
}, "syntaxVariable": {
"syntaxFunction": { "dark": "vesperFg",
"dark": "vesperFunction", "light": "vesperBg"
"light": "vesperFunction" },
}, "syntaxString": {
"syntaxVariable": { "dark": "vesperString",
"dark": "vesperFg", "light": "vesperString"
"light": "vesperBg" },
}, "syntaxNumber": {
"syntaxString": { "dark": "vesperNumber",
"dark": "vesperString", "light": "vesperNumber"
"light": "vesperString" },
}, "syntaxType": {
"syntaxNumber": { "dark": "vesperFunction",
"dark": "vesperNumber", "light": "vesperFunction"
"light": "vesperNumber" },
}, "syntaxOperator": {
"syntaxType": { "dark": "vesperKeyword",
"dark": "vesperFunction", "light": "vesperKeyword"
"light": "vesperFunction" },
}, "syntaxPunctuation": {
"syntaxOperator": { "dark": "vesperFg",
"dark": "vesperKeyword", "light": "vesperBg"
"light": "vesperKeyword"
},
"syntaxPunctuation": {
"dark": "vesperFg",
"light": "vesperBg"
}
} }
} }
}

View File

@@ -1,12 +1,8 @@
const stage = process.env.SST_STAGE || "dev" const stage = process.env.SST_STAGE || "dev"
export default { export default {
url: stage === "production" url: stage === "production" ? "https://opencode.ai" : `https://${stage}.opencode.ai`,
? "https://opencode.ai" console: stage === "production" ? "https://opencode.ai/auth" : `https://${stage}.opencode.ai/auth`,
: `https://${stage}.opencode.ai`,
console: stage === "production"
? "https://opencode.ai/auth"
: `https://${stage}.opencode.ai/auth`,
email: "contact@anoma.ly", email: "contact@anoma.ly",
socialCard: "https://social-cards.sst.dev", socialCard: "https://social-cards.sst.dev",
github: "https://github.com/sst/opencode", github: "https://github.com/sst/opencode",

View File

@@ -37,11 +37,7 @@ function getStatusText(status: [Status, string?]): string {
} }
} }
export default function Share(props: { export default function Share(props: { id: string; api: string; info: Session.Info }) {
id: string
api: string
info: Session.Info
}) {
let lastScrollY = 0 let lastScrollY = 0
let hasScrolledToAnchor = false let hasScrolledToAnchor = false
let scrollTimeout: number | undefined let scrollTimeout: number | undefined
@@ -67,7 +63,8 @@ export default function Share(props: {
created: props.info.time.created, created: props.info.time.created,
updated: props.info.time.updated, updated: props.info.time.updated,
}, },
}, messages: {} },
messages: {},
}) })
const messages = createMemo(() => Object.values(store.messages).toSorted((a, b) => a.id?.localeCompare(b.id))) const messages = createMemo(() => Object.values(store.messages).toSorted((a, b) => a.id?.localeCompare(b.id)))
const [connectionStatus, setConnectionStatus] = createSignal<[Status, string?]>(["disconnected", "Disconnected"]) const [connectionStatus, setConnectionStatus] = createSignal<[Status, string?]>(["disconnected", "Disconnected"])
@@ -413,7 +410,11 @@ export default function Share(props: {
</li> </li>
<li> <li>
<span data-element-label>Output Tokens</span> <span data-element-label>Output Tokens</span>
{data().tokens.output ? <span>{data().tokens.output}</span> : <span data-placeholder>&mdash;</span>} {data().tokens.output ? (
<span>{data().tokens.output}</span>
) : (
<span data-placeholder>&mdash;</span>
)}
</li> </li>
<li> <li>
<span data-element-label>Reasoning Tokens</span> <span data-element-label>Reasoning Tokens</span>

View File

@@ -90,7 +90,6 @@
} }
[data-component="mobile"] { [data-component="mobile"] {
& > [data-component="diff-block"]:first-child > div { & > [data-component="diff-block"]:first-child > div {
padding-top: 0.25rem; padding-top: 0.25rem;
} }

View File

@@ -61,5 +61,4 @@
padding: 2px 0; padding: 2px 0;
font-size: 0.75rem; font-size: 0.75rem;
} }
} }

View File

@@ -10,19 +10,12 @@ export function ContentError(props: Props) {
const overflow = createOverflow() const overflow = createOverflow()
return ( return (
<div <div class={style.root} data-expanded={expanded() || props.expand === true ? true : undefined}>
class={style.root}
data-expanded={expanded() || props.expand === true ? true : undefined}
>
<div data-section="content" ref={overflow.ref}> <div data-section="content" ref={overflow.ref}>
{props.children} {props.children}
</div> </div>
{((!props.expand && overflow.status) || expanded()) && ( {((!props.expand && overflow.status) || expanded()) && (
<button <button type="button" data-element-button-text onClick={() => setExpanded((e) => !e)}>
type="button"
data-element-button-text
onClick={() => setExpanded((e) => !e)}
>
{expanded() ? "Show less" : "Show more"} {expanded() ? "Show less" : "Show more"}
</button> </button>
)} )}

View File

@@ -11,8 +11,7 @@ export function CopyButton(props: CopyButtonProps) {
function handleCopyClick() { function handleCopyClick() {
if (props.text) { if (props.text) {
navigator.clipboard.writeText(props.text) navigator.clipboard.writeText(props.text).catch((err) => console.error("Copy failed", err))
.catch((err) => console.error("Copy failed", err))
setCopied(true) setCopied(true)
setTimeout(() => setCopied(false), 2000) setTimeout(() => setCopied(false), 2000)
@@ -21,15 +20,8 @@ export function CopyButton(props: CopyButtonProps) {
return ( return (
<div data-component="copy-button" class={styles.root}> <div data-component="copy-button" class={styles.root}>
<button <button type="button" onClick={handleCopyClick} data-copied={copied() ? true : undefined}>
type="button" {copied() ? <IconCheckCircle width={16} height={16} /> : <IconClipboard width={16} height={16} />}
onClick={handleCopyClick}
data-copied={copied() ? true : undefined}
>
{copied()
? <IconCheckCircle width={16} height={16} />
: <IconClipboard width={16} height={16} />
}
</button> </button>
</div> </div>
) )

View File

@@ -168,32 +168,25 @@ export function Part(props: PartProps) {
</Show> </Show>
</div> </div>
)} )}
{ {props.message.role === "user" && props.part.type === "file" && (
props.message.role === "user" && props.part.type === "file" && ( <div data-component="attachment">
<div data-component="attachment"> <div data-slot="copy">Attachment</div>
<div data-slot="copy">Attachment</div> <div data-slot="filename">{props.part.filename}</div>
<div data-slot="filename">{props.part.filename}</div> </div>
</div> )}
) {props.part.type === "step-start" && props.message.role === "assistant" && (
} <div data-component="step-start">
{ <div data-slot="provider">{props.message.providerID}</div>
props.part.type === "step-start" && props.message.role === "assistant" && ( <div data-slot="model">{props.message.modelID}</div>
<div data-component="step-start"> </div>
<div data-slot="provider">{props.message.providerID}</div> )}
<div data-slot="model">{props.message.modelID}</div> {props.part.type === "tool" && props.part.state.status === "error" && (
</div> <div data-component="tool" data-tool="error">
) <ContentError>{formatErrorString(props.part.state.error)}</ContentError>
} <Spacer />
{ </div>
props.part.type === "tool" && props.part.state.status === "error" && ( )}
<div data-component="tool" data-tool="error"> {props.part.type === "tool" &&
<ContentError>{formatErrorString(props.part.state.error)}</ContentError>
<Spacer />
</div>
)
}
{
props.part.type === "tool" &&
props.part.state.status === "completed" && props.part.state.status === "completed" &&
props.message.role === "assistant" && ( props.message.role === "assistant" && (
<> <>
@@ -295,10 +288,9 @@ export function Part(props: PartProps) {
.toMillis()} .toMillis()}
/> />
</> </>
) )}
} </div>
</div > </div>
</div >
) )
} }

View File

@@ -17,8 +17,6 @@ But it also accepts commands as documented on this page. This allows you to inte
opencode run "Explain how closures work in JavaScript" opencode run "Explain how closures work in JavaScript"
``` ```
--- ---
## Commands ## Commands

View File

@@ -62,7 +62,7 @@ Use the `command` option in your opencode [config](/docs/config):
"description": "Run tests with coverage", "description": "Run tests with coverage",
"agent": "build", "agent": "build",
"model": "anthropic/claude-3-5-sonnet-20241022" "model": "anthropic/claude-3-5-sonnet-20241022"
}, }
} }
} }
``` ```

View File

@@ -164,13 +164,13 @@ You can configure custom commands for repetitive tasks through the `command` opt
"template": "Run the full test suite with coverage report and show any failures.\nFocus on the failing tests and suggest fixes.", "template": "Run the full test suite with coverage report and show any failures.\nFocus on the failing tests and suggest fixes.",
"description": "Run tests with coverage", "description": "Run tests with coverage",
"agent": "build", "agent": "build",
"model": "anthropic/claude-3-5-sonnet-20241022" "model": "anthropic/claude-3-5-sonnet-20241022",
}, },
"component": { "component": {
"template": "Create a new React component named $ARGUMENTS with TypeScript support.\nInclude proper typing and basic structure.", "template": "Create a new React component named $ARGUMENTS with TypeScript support.\nInclude proper typing and basic structure.",
"description": "Create a new component" "description": "Create a new component",
} },
} },
} }
``` ```

View File

@@ -11,19 +11,19 @@ opencode automatically formats files after they are written or edited using lang
opencode comes with several built-in formatters for popular languages and frameworks. Below is a list of the formatters, supported file extensions, and commands or config options it needs. opencode comes with several built-in formatters for popular languages and frameworks. Below is a list of the formatters, supported file extensions, and commands or config options it needs.
| Formatter | Extensions | Requirements | | Formatter | Extensions | Requirements |
| -------------- | -------------------------------------------------------------------------------------------------------- | ------------------------------------- | | -------------- | -------------------------------------------------------------------------------------------------------- | --------------------------------------- |
| gofmt | .go | `gofmt` command available | | gofmt | .go | `gofmt` command available |
| mix | .ex, .exs, .eex, .heex, .leex, .neex, .sface | `mix` command available | | mix | .ex, .exs, .eex, .heex, .leex, .neex, .sface | `mix` command available |
| prettier | .js, .jsx, .ts, .tsx, .html, .css, .md, .json, .yaml, and [more](https://prettier.io/docs/en/index.html) | `prettier` dependency in `package.json` | | prettier | .js, .jsx, .ts, .tsx, .html, .css, .md, .json, .yaml, and [more](https://prettier.io/docs/en/index.html) | `prettier` dependency in `package.json` |
| biome | .js, .jsx, .ts, .tsx, .html, .css, .md, .json, .yaml, and [more](https://biomejs.dev/) | `biome.json(c)` config file | | biome | .js, .jsx, .ts, .tsx, .html, .css, .md, .json, .yaml, and [more](https://biomejs.dev/) | `biome.json(c)` config file |
| zig | .zig, .zon | `zig` command available | | zig | .zig, .zon | `zig` command available |
| clang-format | .c, .cpp, .h, .hpp, .ino, and [more](https://clang.llvm.org/docs/ClangFormat.html) | `.clang-format` config file | | clang-format | .c, .cpp, .h, .hpp, .ino, and [more](https://clang.llvm.org/docs/ClangFormat.html) | `.clang-format` config file |
| ktlint | .kt, .kts | `ktlint` command available | | ktlint | .kt, .kts | `ktlint` command available |
| ruff | .py, .pyi | `ruff` command available with config | | ruff | .py, .pyi | `ruff` command available with config |
| rubocop | .rb, .rake, .gemspec, .ru | `rubocop` command available | | rubocop | .rb, .rake, .gemspec, .ru | `rubocop` command available |
| standardrb | .rb, .rake, .gemspec, .ru | `standardrb` command available | | standardrb | .rb, .rake, .gemspec, .ru | `standardrb` command available |
| htmlbeautifier | .erb, .html.erb | `htmlbeautifier` command available | | htmlbeautifier | .erb, .html.erb | `htmlbeautifier` command available |
So if your project has `prettier` in your `package.json`, opencode will automatically use it. So if your project has `prettier` in your `package.json`, opencode will automatically use it.
@@ -48,7 +48,7 @@ You can customize formatters through the `formatter` section in your opencode co
```json title="opencode.json" ```json title="opencode.json"
{ {
"$schema": "https://opencode.ai/config.json", "$schema": "https://opencode.ai/config.json",
"formatter": { } "formatter": {}
} }
``` ```
@@ -56,7 +56,7 @@ Each formatter configuration supports the following:
| Property | Type | Description | | Property | Type | Description |
| ------------- | -------- | ------------------------------------------------------- | | ------------- | -------- | ------------------------------------------------------- |
| `disabled` | boolean | Set this to `true` to disable the formatter | | `disabled` | boolean | Set this to `true` to disable the formatter |
| `command` | string[] | The command to run for formatting | | `command` | string[] | The command to run for formatting |
| `environment` | object | Environment variables to set when running the formatter | | `environment` | object | Environment variables to set when running the formatter |
| `extensions` | string[] | File extensions this formatter should handle | | `extensions` | string[] | File extensions this formatter should handle |

View File

@@ -33,7 +33,7 @@ Check out the [**GitLab docs**](https://docs.gitlab.com/user/duo_agent_platform/
6. Create a flow config file, here's an example: 6. Create a flow config file, here's an example:
<details> <details>
<summary>Flow configuration</summary> <summary>Flow configuration</summary>
```yaml ```yaml
image: node:22-slim image: node:22-slim
@@ -67,17 +67,17 @@ Check out the [**GitLab docs**](https://docs.gitlab.com/user/duo_agent_platform/
- | - |
opencode run " opencode run "
You are an AI assistant helping with GitLab operations. You are an AI assistant helping with GitLab operations.
Context: $AI_FLOW_CONTEXT Context: $AI_FLOW_CONTEXT
Task: $AI_FLOW_INPUT Task: $AI_FLOW_INPUT
Event: $AI_FLOW_EVENT Event: $AI_FLOW_EVENT
Please execute the requested task using the available GitLab tools. Please execute the requested task using the available GitLab tools.
Be thorough in your analysis and provide clear explanations. Be thorough in your analysis and provide clear explanations.
<important> <important>
Please use the glab CLI to access data from GitLab. The glab CLI has already been authenticated. You can run the corresponding commands. Please use the glab CLI to access data from GitLab. The glab CLI has already been authenticated. You can run the corresponding commands.
If you are asked to summarise an MR or issue or asked to provide more information then please post back a note to the MR/Issue so that the user can see it. If you are asked to summarise an MR or issue or asked to provide more information then please post back a note to the MR/Issue so that the user can see it.
You don't need to commit or push up changes, those will be done automatically based on the file changes you make. You don't need to commit or push up changes, those will be done automatically based on the file changes you make.
</important> </important>

View File

@@ -41,26 +41,10 @@ You can also install it with the following:
- **Using Node.js** - **Using Node.js**
<Tabs> <Tabs>
<TabItem label="npm"> <TabItem label="npm">```bash npm install -g opencode-ai ```</TabItem>
```bash <TabItem label="Bun">```bash bun install -g opencode-ai ```</TabItem>
npm install -g opencode-ai <TabItem label="pnpm">```bash pnpm install -g opencode-ai ```</TabItem>
``` <TabItem label="Yarn">```bash yarn global add opencode-ai ```</TabItem>
</TabItem>
<TabItem label="Bun">
```bash
bun install -g opencode-ai
```
</TabItem>
<TabItem label="pnpm">
```bash
pnpm install -g opencode-ai
```
</TabItem>
<TabItem label="Yarn">
```bash
yarn global add opencode-ai
```
</TabItem>
</Tabs> </Tabs>
- **Using Homebrew on macOS and Linux** - **Using Homebrew on macOS and Linux**

View File

@@ -79,9 +79,9 @@ The opencode server exposes the following APIs.
### Config ### Config
| Method | Path | Description | Response | | Method | Path | Description | Response |
| ------ | ------------------- | --------------------------------- | ----------------------------------------------------------------------------------------------------- | | ------ | ------------------- | --------------------------------- | ---------------------------------------------------------------------------------------- |
| `GET` | `/config` | Get config info | <a href={typesUrl}><code>Config</code></a> | | `GET` | `/config` | Get config info | <a href={typesUrl}><code>Config</code></a> |
| `GET` | `/config/providers` | List providers and default models | `{ providers: `<a href={typesUrl}>Provider[]</a>`, default: { [key: string]: string } }` | | `GET` | `/config/providers` | List providers and default models | `{ providers: `<a href={typesUrl}>Provider[]</a>`, default: { [key: string]: string } }` |
--- ---
@@ -101,8 +101,8 @@ The opencode server exposes the following APIs.
| `POST` | `/session/:id/share` | Share session | Returns <a href={typesUrl}><code>Session</code></a> | | `POST` | `/session/:id/share` | Share session | Returns <a href={typesUrl}><code>Session</code></a> |
| `DELETE` | `/session/:id/share` | Unshare session | Returns <a href={typesUrl}><code>Session</code></a> | | `DELETE` | `/session/:id/share` | Unshare session | Returns <a href={typesUrl}><code>Session</code></a> |
| `POST` | `/session/:id/summarize` | Summarize session | | | `POST` | `/session/:id/summarize` | Summarize session | |
| `GET` | `/session/:id/message` | List messages in a session | Returns `{ info: `<a href={typesUrl}>Message</a>`, parts: `<a href={typesUrl}>Part[]</a>`}[]` | | `GET` | `/session/:id/message` | List messages in a session | Returns `{ info: `<a href={typesUrl}>Message</a>`, parts: `<a href={typesUrl}>Part[]</a>`}[]` |
| `GET` | `/session/:id/message/:messageID` | Get message details | Returns `{ info: `<a href={typesUrl}>Message</a>`, parts: `<a href={typesUrl}>Part[]</a>`}` | | `GET` | `/session/:id/message/:messageID` | Get message details | Returns `{ info: `<a href={typesUrl}>Message</a>`, parts: `<a href={typesUrl}>Part[]</a>`}` |
| `POST` | `/session/:id/message` | Send chat message | body matches [`ChatInput`](https://github.com/sst/opencode/blob/main/packages/opencode/src/session/index.ts#L358), returns <a href={typesUrl}><code>Message</code></a> | | `POST` | `/session/:id/message` | Send chat message | body matches [`ChatInput`](https://github.com/sst/opencode/blob/main/packages/opencode/src/session/index.ts#L358), returns <a href={typesUrl}><code>Message</code></a> |
| `POST` | `/session/:id/shell` | Run a shell command | body matches [`CommandInput`](https://github.com/sst/opencode/blob/main/packages/opencode/src/session/index.ts#L1007), returns <a href={typesUrl}><code>Message</code></a> | | `POST` | `/session/:id/shell` | Run a shell command | body matches [`CommandInput`](https://github.com/sst/opencode/blob/main/packages/opencode/src/session/index.ts#L1007), returns <a href={typesUrl}><code>Message</code></a> |
| `POST` | `/session/:id/revert` | Revert a message | body: `{ messageID }` | | `POST` | `/session/:id/revert` | Revert a message | body: `{ messageID }` |
@@ -175,6 +175,6 @@ The opencode server exposes the following APIs.
### Docs ### Docs
| Method | Path | Description | Response | | Method | Path | Description | Response |
| ------ | ------ | -------------------------------------- | ------------------------------------------ | | ------ | ------ | ------------------------- | --------------------------- |
| `GET` | `/doc` | OpenAPI 3.1 specification | HTML page with OpenAPI spec | | `GET` | `/doc` | OpenAPI 3.1 specification | HTML page with OpenAPI spec |

View File

@@ -272,6 +272,7 @@ Both the `/editor` and `/export` commands use the editor specified in your `EDIT
To make it permanent, add this to your shell profile; To make it permanent, add this to your shell profile;
`~/.bashrc`, `~/.zshrc`, etc. `~/.bashrc`, `~/.zshrc`, etc.
</TabItem> </TabItem>
<TabItem label="Windows (CMD)"> <TabItem label="Windows (CMD)">
@@ -284,6 +285,7 @@ Both the `/editor` and `/export` commands use the editor specified in your `EDIT
To make it permanent, use **System Properties** > **Environment To make it permanent, use **System Properties** > **Environment
Variables**. Variables**.
</TabItem> </TabItem>
<TabItem label="Windows (PowerShell)"> <TabItem label="Windows (PowerShell)">
@@ -295,6 +297,7 @@ Both the `/editor` and `/export` commands use the editor specified in your `EDIT
``` ```
To make it permanent, add this to your PowerShell profile. To make it permanent, add this to your PowerShell profile.
</TabItem> </TabItem>
</Tabs> </Tabs>

View File

@@ -73,11 +73,11 @@ We created opencode zen to:
Below are the models that we currently support and their prices **per 1M Below are the models that we currently support and their prices **per 1M
tokens**. tokens**.
| Model | Input | Output | | Model | Input | Output |
| ----- | ----- | ------ | | ---------------- | ----- | ------ |
| Qwen3 Coder 480B | $0.38 | $0.50 | | Qwen3 Coder 480B | $0.38 | $0.50 |
| Grok Code Fast 1 | Free | Free | | Grok Code Fast 1 | Free | Free |
| Sonnet 4 | Soon | Soon | | Sonnet 4 | Soon | Soon |
:::note :::note
We add a small markup to cover our costs. We add a small markup to cover our costs.
@@ -86,7 +86,7 @@ We add a small markup to cover our costs.
A couple of notes: A couple of notes:
- These are the raw prices based on the provider we are using internally. We - These are the raw prices based on the provider we are using internally. We
charge a small markup on top of this to cover our processing fees. charge a small markup on top of this to cover our processing fees.
- Grok Code Fast 1 is currently free on opencode till Sep 10th. The xAI team is - Grok Code Fast 1 is currently free on opencode till Sep 10th. The xAI team is
using this time to collect feedback and improve Grok Code. using this time to collect feedback and improve Grok Code.

View File

@@ -6,4 +6,4 @@
/// <reference path="../../sst-env.d.ts" /> /// <reference path="../../sst-env.d.ts" />
import "sst" import "sst"
export {} export {}

View File

@@ -1,5 +1,5 @@
import { defineConfig } from '@vscode/test-cli'; import { defineConfig } from "@vscode/test-cli"
export default defineConfig({ export default defineConfig({
files: 'out/test/**/*.test.js', files: "out/test/**/*.test.js",
}); })

View File

@@ -1,56 +1,54 @@
const esbuild = require("esbuild"); const esbuild = require("esbuild")
const production = process.argv.includes('--production'); const production = process.argv.includes("--production")
const watch = process.argv.includes('--watch'); const watch = process.argv.includes("--watch")
/** /**
* @type {import('esbuild').Plugin} * @type {import('esbuild').Plugin}
*/ */
const esbuildProblemMatcherPlugin = { const esbuildProblemMatcherPlugin = {
name: 'esbuild-problem-matcher', name: "esbuild-problem-matcher",
setup(build) { setup(build) {
build.onStart(() => { build.onStart(() => {
console.log('[watch] build started'); console.log("[watch] build started")
}); })
build.onEnd((result) => { build.onEnd((result) => {
result.errors.forEach(({ text, location }) => { result.errors.forEach(({ text, location }) => {
console.error(`✘ [ERROR] ${text}`); console.error(`✘ [ERROR] ${text}`)
console.error(` ${location.file}:${location.line}:${location.column}:`); console.error(` ${location.file}:${location.line}:${location.column}:`)
}); })
console.log('[watch] build finished'); console.log("[watch] build finished")
}); })
}, },
};
async function main() {
const ctx = await esbuild.context({
entryPoints: [
'src/extension.ts'
],
bundle: true,
format: 'cjs',
minify: production,
sourcemap: !production,
sourcesContent: false,
platform: 'node',
outfile: 'dist/extension.js',
external: ['vscode'],
logLevel: 'silent',
plugins: [
/* add to the end of plugins array */
esbuildProblemMatcherPlugin,
],
});
if (watch) {
await ctx.watch();
} else {
await ctx.rebuild();
await ctx.dispose();
}
} }
main().catch(e => { async function main() {
console.error(e); const ctx = await esbuild.context({
process.exit(1); entryPoints: ["src/extension.ts"],
}); bundle: true,
format: "cjs",
minify: production,
sourcemap: !production,
sourcesContent: false,
platform: "node",
outfile: "dist/extension.js",
external: ["vscode"],
logLevel: "silent",
plugins: [
/* add to the end of plugins array */
esbuildProblemMatcherPlugin,
],
})
if (watch) {
await ctx.watch()
} else {
await ctx.rebuild()
await ctx.dispose()
}
}
main().catch((e) => {
console.error(e)
process.exit(1)
})

View File

@@ -1,28 +1,34 @@
import typescriptEslint from "@typescript-eslint/eslint-plugin"; import typescriptEslint from "@typescript-eslint/eslint-plugin"
import tsParser from "@typescript-eslint/parser"; import tsParser from "@typescript-eslint/parser"
export default [{ export default [
{
files: ["**/*.ts"], files: ["**/*.ts"],
}, { },
{
plugins: { plugins: {
"@typescript-eslint": typescriptEslint, "@typescript-eslint": typescriptEslint,
}, },
languageOptions: { languageOptions: {
parser: tsParser, parser: tsParser,
ecmaVersion: 2022, ecmaVersion: 2022,
sourceType: "module", sourceType: "module",
}, },
rules: { rules: {
"@typescript-eslint/naming-convention": ["warn", { "@typescript-eslint/naming-convention": [
selector: "import", "warn",
format: ["camelCase", "PascalCase"], {
}], selector: "import",
format: ["camelCase", "PascalCase"],
},
],
curly: "warn", curly: "warn",
eqeqeq: "warn", eqeqeq: "warn",
"no-throw-literal": "warn", "no-throw-literal": "warn",
semi: "warn", semi: "warn",
}, },
}]; },
]

View File

@@ -6,4 +6,4 @@
/// <reference path="../../sst-env.d.ts" /> /// <reference path="../../sst-env.d.ts" />
import "sst" import "sst"
export {} export {}

132
sst-env.d.ts vendored
View File

@@ -5,95 +5,95 @@
declare module "sst" { declare module "sst" {
export interface Resource { export interface Resource {
"ANTHROPIC_API_KEY": { ANTHROPIC_API_KEY: {
"type": "sst.sst.Secret" type: "sst.sst.Secret"
"value": string value: string
} }
"AUTH_API_URL": { AUTH_API_URL: {
"type": "sst.sst.Linkable" type: "sst.sst.Linkable"
"value": string value: string
} }
"Api": { Api: {
"type": "sst.cloudflare.Worker" type: "sst.cloudflare.Worker"
"url": string url: string
} }
"AuthApi": { AuthApi: {
"type": "sst.cloudflare.Worker" type: "sst.cloudflare.Worker"
"url": string url: string
} }
"AuthStorage": { AuthStorage: {
"type": "sst.cloudflare.Kv" type: "sst.cloudflare.Kv"
} }
"BASETEN_API_KEY": { BASETEN_API_KEY: {
"type": "sst.sst.Secret" type: "sst.sst.Secret"
"value": string value: string
} }
"Bucket": { Bucket: {
"name": string name: string
"type": "sst.cloudflare.Bucket" type: "sst.cloudflare.Bucket"
} }
"Console": { Console: {
"type": "sst.cloudflare.SolidStart" type: "sst.cloudflare.SolidStart"
"url": string url: string
} }
"Database": { Database: {
"database": string database: string
"host": string host: string
"password": string password: string
"port": number port: number
"type": "sst.sst.Linkable" type: "sst.sst.Linkable"
"username": string username: string
} }
"GITHUB_APP_ID": { GITHUB_APP_ID: {
"type": "sst.sst.Secret" type: "sst.sst.Secret"
"value": string value: string
} }
"GITHUB_APP_PRIVATE_KEY": { GITHUB_APP_PRIVATE_KEY: {
"type": "sst.sst.Secret" type: "sst.sst.Secret"
"value": string value: string
} }
"GITHUB_CLIENT_ID_CONSOLE": { GITHUB_CLIENT_ID_CONSOLE: {
"type": "sst.sst.Secret" type: "sst.sst.Secret"
"value": string value: string
} }
"GITHUB_CLIENT_SECRET_CONSOLE": { GITHUB_CLIENT_SECRET_CONSOLE: {
"type": "sst.sst.Secret" type: "sst.sst.Secret"
"value": string value: string
} }
"GOOGLE_CLIENT_ID": { GOOGLE_CLIENT_ID: {
"type": "sst.sst.Secret" type: "sst.sst.Secret"
"value": string value: string
} }
"HONEYCOMB_API_KEY": { HONEYCOMB_API_KEY: {
"type": "sst.sst.Secret" type: "sst.sst.Secret"
"value": string value: string
} }
"LogProcessor": { LogProcessor: {
"type": "sst.cloudflare.Worker" type: "sst.cloudflare.Worker"
} }
"OPENAI_API_KEY": { OPENAI_API_KEY: {
"type": "sst.sst.Secret" type: "sst.sst.Secret"
"value": string value: string
} }
"STRIPE_SECRET_KEY": { STRIPE_SECRET_KEY: {
"type": "sst.sst.Secret" type: "sst.sst.Secret"
"value": string value: string
} }
"STRIPE_WEBHOOK_SECRET": { STRIPE_WEBHOOK_SECRET: {
"type": "sst.sst.Linkable" type: "sst.sst.Linkable"
"value": string value: string
} }
"Web": { Web: {
"type": "sst.cloudflare.Astro" type: "sst.cloudflare.Astro"
"url": string url: string
} }
"XAI_API_KEY": { XAI_API_KEY: {
"type": "sst.sst.Secret" type: "sst.sst.Secret"
"value": string value: string
} }
} }
} }
/// <reference path="sst-env.d.ts" /> /// <reference path="sst-env.d.ts" />
import "sst" import "sst"
export {} export {}

View File

@@ -2,8 +2,6 @@
"$schema": "https://json.schemastore.org/tsconfig", "$schema": "https://json.schemastore.org/tsconfig",
"extends": "@tsconfig/bun/tsconfig.json", "extends": "@tsconfig/bun/tsconfig.json",
"compilerOptions": { "compilerOptions": {
"customConditions": [ "customConditions": ["development"]
"development"
],
} }
} }