Compare commits

..
1 Commits
Author SHA1 Message Date
opencode 65cf14df16 release: v1.18.14 2026-08-05 20:58:38 +00:00
11 changed files with 51 additions and 56 deletions
-1
View File
@@ -322,7 +322,6 @@ jobs:
working-directory: packages/desktop
env:
NODE_OPTIONS: --max-old-space-size=4096
OPENCODE_VERSION: ${{ needs.version.outputs.version }}
OPENCODE_CHANNEL: ${{ (github.ref_name == 'beta' && 'beta') || 'prod' }}
SENTRY_AUTH_TOKEN: ${{ secrets.SENTRY_AUTH_TOKEN }}
SENTRY_ORG: ${{ vars.SENTRY_ORG }}
+4 -4
View File
@@ -1,8 +1,8 @@
{
"nodeModules": {
"x86_64-linux": "sha256-uduwrM143NDSc+tXsi4lVVfoMll2a3BDHRUjuO7GB68=",
"aarch64-linux": "sha256-6DUda78XdXY6DP86lIUkweSjys3iG4Y4mo1PiaNuXbg=",
"aarch64-darwin": "sha256-AkJwfLULLZVwwz+XU1QcFUZoIS7oVPCn+n/MXEaxrqE=",
"x86_64-darwin": "sha256-hAxKGdiITTxQ2uujQt6prNjo3NxGAMMeo+9HlMWK6GU="
"x86_64-linux": "sha256-GRjnvvyj37H36RqiCB7dz5ALAEwvw16izwuk1wsHEpU=",
"aarch64-linux": "sha256-0OIn1o6dpqIQ5XgIMzpenMCMqsYzraaYVJk+te5eINU=",
"aarch64-darwin": "sha256-sQSQcuox78d8wT1lsKYHqVBl11NusiszQ+gu2XYXZi8=",
"x86_64-darwin": "sha256-SINkhMRd4oM1zABSs1Uf3OAzxJ1lgcycl1U4fmi+baY="
}
}
-1
View File
@@ -21,7 +21,6 @@ await Bun.build({
external: ["jsonc-parser", "@lydell/node-pty"],
define: {
OPENCODE_MODELS_DEV: generated.modelsData,
OPENCODE_VERSION: `'${Script.version}'`,
OPENCODE_CHANNEL: `'${Script.channel}'`,
},
files: {
+1 -1
View File
@@ -9,7 +9,7 @@ let embeddedUIPromise: Promise<Record<string, string> | null> | undefined
export const UI_UPSTREAM = new URL("https://app.opencode.ai")
export const csp = (hash = "") =>
`default-src 'self'; script-src 'self' 'wasm-unsafe-eval'${hash ? ` 'sha256-${hash}'` : ""}; style-src 'self' 'unsafe-inline'; img-src 'self' data: https: blob:; font-src 'self' data:; media-src 'self' data:; connect-src * data: blob:`
`default-src 'self'; script-src 'self' 'wasm-unsafe-eval'${hash ? ` 'sha256-${hash}'` : ""}; style-src 'self' 'unsafe-inline'; img-src 'self' data: https:; font-src 'self' data:; media-src 'self' data:; connect-src * data:`
export const DEFAULT_CSP = csp()
export function themePreloadHash(body: string) {
@@ -326,7 +326,7 @@ describe("HttpApi UI fallback", () => {
}),
)
it.live("allows embedded UI terminal wasm, blob attachments, and theme preload CSP", () =>
it.live("allows embedded UI terminal wasm and theme preload CSP", () =>
Effect.gen(function* () {
const script = 'document.documentElement.dataset.theme = "dark"'
@@ -351,8 +351,7 @@ describe("HttpApi UI fallback", () => {
const csp = response.headers.get("content-security-policy") ?? ""
expect(csp).toContain("script-src 'self' 'wasm-unsafe-eval'")
expect(csp).toContain(`'sha256-${createHash("sha256").update(script).digest("base64")}'`)
expect(csp).toContain("img-src 'self' data: https: blob:")
expect(csp).toContain("connect-src * data: blob:")
expect(csp).toContain("connect-src * data:")
}),
)
@@ -610,7 +610,9 @@ it.live("session.processor effect tests retry OpenAI-compatible midstream server
Effect.gen(function* () {
const { processors, session, provider } = yield* boot()
yield* llm.push(raw({ chunks: [{ error: { type: "server_error", code: "server_error", message: "xxx" } }] }))
yield* llm.push(
raw({ chunks: [{ error: { type: "server_error", code: "server_error", message: "xxx" } }] }),
)
yield* llm.text("after")
const chat = yield* session.create({})
+1 -10
View File
@@ -1,10 +1,7 @@
// @refresh reload
import type { Asset, PageEvent } from "@solidjs/start"
import { createHandler, StartServer } from "@solidjs/start/server"
import ibmPlexMonoMediumLatin1 from "@ibm/plex/IBM-Plex-Mono/fonts/split/woff2/IBMPlexMono-Medium-Latin1.woff2?url"
import { getRequestEvent } from "solid-js/web"
import { dir, localeFromRequest, tag } from "./lib/language"
import statsStylesheetUrl from "./routes/index.css?url"
const statsThemePreloadScript = `;(function () {
var preference = "system"
@@ -21,12 +18,8 @@ export default createHandler(
() => (
<StartServer
document={({ assets, children, scripts }) => {
const event = getRequestEvent() as PageEvent | undefined
const event = getRequestEvent()
const locale = event ? localeFromRequest(event.request) : "en"
const stylesheet = (event?.assets as Asset[] | undefined)?.find(
(asset): asset is Extract<Asset, { tag: "link" }> => asset.tag === "link" && asset.attrs.rel === "stylesheet",
)
const stylesheetHref = import.meta.env.DEV ? statsStylesheetUrl : stylesheet?.attrs.href
return (
<html lang={tag(locale)} dir={dir(locale)} data-locale={locale}>
@@ -34,8 +27,6 @@ export default createHandler(
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1" />
<script id="stats-theme-preload-script">{statsThemePreloadScript}</script>
<link rel="preload" href={ibmPlexMonoMediumLatin1} as="font" type="font/woff2" crossorigin="anonymous" />
{stylesheetHref ? <link rel="stylesheet" href={stylesheetHref} /> : null}
{assets}
</head>
<body>
@@ -83,7 +83,11 @@ export function ComparisonCardsSection(props: {
function FeaturedComparisonCard(props: { pair: ComparisonPair }) {
return (
<a data-component="compare-home-card" href={canonicalComparisonHref(props.pair.first, props.pair.second)}>
<a
data-component="compare-home-card"
href={canonicalComparisonHref(props.pair.first, props.pair.second)}
aria-label={`${props.pair.detail}: ${props.pair.first.name} vs ${props.pair.second.name}`}
>
<span data-slot="compare-home-card-head">
<span>
<strong>{props.pair.detail}</strong>
+11 -25
View File
@@ -55,7 +55,7 @@ body {
--color-background-strong: #161616;
--color-background-strong-hover: #242424;
--color-text: #5c5c5c;
--color-text-weak: #707070;
--color-text-weak: #808080;
--color-text-strong: #161616;
--color-text-inverted: #ffffff;
--color-border-weak: #0000001a;
@@ -66,10 +66,10 @@ body {
--stats-line-strong: #00000033;
--stats-text: #161616;
--stats-muted: #5c5c5c;
--stats-faint: #707070;
--stats-faint: #808080;
--stats-theme-icon-active: #3a3a3a;
--stats-accent: #3b5cf6;
--stats-accent-text: #3b5cf6;
--stats-accent-text: #6c7dff;
--stats-bar-idle: #d4d4d4;
--stats-dot: #d4d4d4;
--stats-hero-muted: #5c5c5c;
@@ -92,18 +92,6 @@ body {
display: none !important;
}
[data-page="stats"] [data-slot="visually-hidden"] {
position: absolute;
width: 1px;
height: 1px;
padding: 0;
margin: -1px;
overflow: hidden;
clip: rect(0 0 0 0);
white-space: nowrap;
border: 0;
}
[data-page="stats"][data-layout="compare-detail"] {
/* The table contains its own wide rows; keep the page itself out of the horizontal scroll chain. */
overflow-x: visible;
@@ -7091,7 +7079,7 @@ body {
--color-background-strong: #ffffff;
--color-background-strong-hover: #eeeeee;
--color-text: #d4d4d4;
--color-text-weak: #a3a3a3;
--color-text-weak: #808080;
--color-text-strong: #ffffff;
--color-text-inverted: #161616;
--color-border-weak: #ffffff1a;
@@ -7102,12 +7090,11 @@ body {
--stats-line-strong: #ffffff33;
--stats-text: #ffffff;
--stats-muted: #d4d4d4;
--stats-faint: #a3a3a3;
--stats-accent-text: #8190ff;
--stats-faint: #808080;
--stats-theme-icon-active: #fafafa;
--stats-bar-idle: #303030;
--stats-dot: #303030;
--stats-hero-muted: #a3a3a3;
--stats-hero-muted: #808080;
--stats-hero-pattern: #303030;
--stats-logo-bg: #f1ecec;
--stats-logo-fill: #b7b1b1;
@@ -7267,7 +7254,7 @@ body {
--color-background-strong: #ffffff;
--color-background-strong-hover: #eeeeee;
--color-text: #d4d4d4;
--color-text-weak: #a3a3a3;
--color-text-weak: #808080;
--color-text-strong: #ffffff;
--color-text-inverted: #161616;
--color-border-weak: #ffffff1a;
@@ -7278,12 +7265,11 @@ body {
--stats-line-strong: #ffffff33;
--stats-text: #ffffff;
--stats-muted: #d4d4d4;
--stats-faint: #a3a3a3;
--stats-accent-text: #8190ff;
--stats-faint: #808080;
--stats-theme-icon-active: #fafafa;
--stats-bar-idle: #303030;
--stats-dot: #303030;
--stats-hero-muted: #a3a3a3;
--stats-hero-muted: #808080;
--stats-hero-pattern: #303030;
--stats-logo-bg: #f1ecec;
--stats-logo-fill: #b7b1b1;
@@ -8407,7 +8393,7 @@ body {
}
[data-page="stats"] [data-component="top-models-chart"][data-dense-labels="true"] {
--top-models-mobile-bar-width: 18px;
--top-models-mobile-bar-width: 12px;
}
[data-page="stats"] [data-component="top-models-chart"][data-dense-labels="true"] [data-slot="top-models-axis"],
@@ -8416,7 +8402,7 @@ body {
}
[data-page="stats"] [data-component="market-share"][data-dense-labels="true"] {
--market-mobile-bar-width: 18px;
--market-mobile-bar-width: 12px;
}
[data-page="stats"] [data-component="market-share"][data-dense-labels="true"] [data-slot="market-labels"],
+23 -7
View File
@@ -1,7 +1,11 @@
import { Meta, Title } from "@solidjs/meta"
import { Link, Meta, Title } from "@solidjs/meta"
import { ProviderIcon } from "@opencode-ai/ui/provider-icon"
import { scaleSqrt } from "d3-scale"
import countryCodesSource from "i18n-iso-countries/codes.json?raw"
import ibmPlexMonoRegularLatin1 from "@ibm/plex/IBM-Plex-Mono/fonts/split/woff2/IBMPlexMono-Regular-Latin1.woff2?url"
import ibmPlexMonoMediumLatin1 from "@ibm/plex/IBM-Plex-Mono/fonts/split/woff2/IBMPlexMono-Medium-Latin1.woff2?url"
import ibmPlexMonoSemiBoldLatin1 from "@ibm/plex/IBM-Plex-Mono/fonts/split/woff2/IBMPlexMono-SemiBold-Latin1.woff2?url"
import ibmPlexMonoBoldLatin1 from "@ibm/plex/IBM-Plex-Mono/fonts/split/woff2/IBMPlexMono-Bold-Latin1.woff2?url"
import {
getStatsHomeData,
type CacheRatioEntry,
@@ -138,6 +142,10 @@ export default function StatsHome() {
<Meta name="twitter:description" content={i18n.t("app.description")} />
<Meta name="twitter:image" content={statsUnfurlUrl} />
<Meta name="twitter:image:alt" content={i18n.t("app.unfurlAlt")} />
<Link rel="preload" href={ibmPlexMonoRegularLatin1} as="font" type="font/woff2" crossorigin="anonymous" />
<Link rel="preload" href={ibmPlexMonoMediumLatin1} as="font" type="font/woff2" crossorigin="anonymous" />
<Link rel="preload" href={ibmPlexMonoSemiBoldLatin1} as="font" type="font/woff2" crossorigin="anonymous" />
<Link rel="preload" href={ibmPlexMonoBoldLatin1} as="font" type="font/woff2" crossorigin="anonymous" />
<Header githubStars={githubStars() ?? githubLink.fallbackStars} />
<div data-component="container">
<div data-component="content">
@@ -219,8 +227,7 @@ function Hero(props: { updatedAt: string | null }) {
return (
<section data-section="hero">
<p data-slot="hero-meta" role="status" aria-atomic="true">
<span data-slot="visually-hidden">{currentUpdatedLabel()}</span>
<p data-slot="hero-meta" aria-live="polite" aria-atomic="true" aria-label={currentUpdatedLabel()}>
<svg aria-hidden="true" width="16" height="16" viewBox="0 0 16 16">
<path
fill-rule="evenodd"
@@ -689,7 +696,7 @@ function isDenseColumnRange(range: UsageRange) {
function scrollDenseChartToEnd(element: HTMLDivElement | undefined, range: UsageRange, count: number) {
if (!element || count <= 0 || !isDenseColumnRange(range) || typeof window === "undefined") return
window.requestAnimationFrame(() => {
element.scrollLeft = Number.MAX_SAFE_INTEGER
element.scrollLeft = element.scrollWidth - element.clientWidth
})
}
@@ -728,11 +735,12 @@ function Leaderboard(props: {
activeModel: string | undefined
onActiveModelChange: (model: string | undefined) => void
}) {
const i18n = useI18n()
const featured = createMemo(() => props.data.slice(0, 3))
const compact = createMemo(() => props.data.slice(3))
return (
<div id="leaderboard" data-component="leaderboard">
<div id="leaderboard" data-component="leaderboard" role="list" aria-label={i18n.t("chart.leaderboardAria")}>
<div data-slot="leaderboard-featured">
<For each={featured()}>
{(entry) => (
@@ -758,7 +766,7 @@ function Leaderboard(props: {
)}
</For>
</div>
<div data-slot="leaderboard-mobile">
<div data-slot="leaderboard-mobile" aria-label={i18n.t("chart.scrollableLeaderboardAria")}>
<For each={props.data}>
{(entry) => (
<LeaderboardCard
@@ -790,6 +798,9 @@ function LeaderboardCard(props: {
href={language.route(
`${import.meta.env.BASE_URL}${modelSlug(props.entry.provider)}/${modelSlug(props.entry.model)}`,
)}
role="listitem"
tabIndex={0}
aria-label={`${String(props.entry.rank).padStart(2, "0")} ${props.entry.model} ${i18n.t("chart.byAuthor", { author: props.entry.author })}`}
onPointerEnter={() => props.onActiveModelChange(props.entry.model)}
onPointerLeave={(event) => {
if (event.pointerType === "touch") return
@@ -945,7 +956,6 @@ function MarketShare(props: {
{(day, index) => (
<button
type="button"
aria-label={`${day.date} ${formatTrillions(day.total)}`}
data-active={props.inspecting && props.activeIndex === index() ? "true" : undefined}
data-label-hidden={isColumnLabelHidden(index(), props.data.length) ? "true" : undefined}
data-mobile-hidden={isMarketMobileLabelHidden(index(), props.data.length) ? "true" : undefined}
@@ -1021,11 +1031,14 @@ function MarketShareList(props: {
activeAuthor: string | undefined
onActiveAuthorChange: (author: string) => void
}) {
const i18n = useI18n()
const language = useLanguage()
return (
<ol data-component="market-share-list">
<For each={props.data}>
{(item, index) => {
const label = () =>
`${item.author} ${formatTrillions(item.tokens)} ${item.share.toFixed(1)} ${i18n.t("chart.percent")}`
const content = () => (
<>
<span>{String(index() + 1).padStart(2, "0")}</span>
@@ -1047,6 +1060,7 @@ function MarketShareList(props: {
fallback={
<button
type="button"
aria-label={label()}
onClick={() => props.onActiveAuthorChange(item.author)}
onFocus={() => props.onActiveAuthorChange(item.author)}
>
@@ -1057,6 +1071,7 @@ function MarketShareList(props: {
{(href) => (
<a
href={href()}
aria-label={label()}
onClick={() => props.onActiveAuthorChange(item.author)}
onFocus={() => props.onActiveAuthorChange(item.author)}
>
@@ -1244,6 +1259,7 @@ function GeoCountryList(props: {
type="button"
data-active={props.activeCountry === country.country ? "true" : undefined}
style={{ "--geo-row-opacity": String(opacityScale()(country.tokens)) } as JSX.CSSProperties}
aria-label={`${formatCountryName(country.country, language.tag(language.locale()), i18n.t("home.unknown"))} ${formatGeoTokens(country.tokens)} ${formatGeoShare(country.share)}`}
onClick={() => props.onActiveCountryChange(country.country)}
onPointerEnter={() => props.onActiveCountryChange(country.country)}
onFocus={() => props.onActiveCountryChange(country.country)}
+1 -2
View File
@@ -18,7 +18,6 @@ export default defineConfig({
allowedHosts: true,
},
build: {
minify: "esbuild",
cssMinify: true,
minify: false,
},
})