feat(aircoding): AirCoding V2 baseline — deterministic multi-agent architecture

Forked from OpenCode v1.17.4 with multi-agent system:
- 5 agents: aircoding, scheduler, worker, architect, reviewer
- Deterministic DAG scheduling engine (coordinator_tick)
- Tool whitelists as hard enforcement
- AirCoding validation plugin
- System prompt injection for routing
- V1 requirements: C4 docs, ADR, AGENTS.md, debug-log.md
- Design documents in docs/
This commit is contained in:
airlongdian
2026-06-13 21:41:54 +08:00
commit af3016fe27
5757 changed files with 1170017 additions and 0 deletions

17
packages/stats/app/.gitignore vendored Normal file
View File

@@ -0,0 +1,17 @@
dist
.wrangler
.output
.vercel
.netlify
app.config.timestamp_*.js
# Environment
.env
.env*.local
# dependencies
/node_modules
# System Files
.DS_Store
Thumbs.db

View File

@@ -0,0 +1,5 @@
export default {
server: {
preset: "cloudflare-module",
},
}

View File

@@ -0,0 +1,46 @@
{
"$schema": "https://json.schemastore.org/package.json",
"name": "@opencode-ai/stats-app",
"version": "1.17.4",
"private": true,
"type": "module",
"license": "MIT",
"scripts": {
"typecheck": "tsgo --noEmit",
"dev": "vite dev --host 0.0.0.0",
"build": "vite build",
"start": "vite start"
},
"dependencies": {
"@ibm/plex": "6.4.1",
"@opencode-ai/stats-core": "workspace:*",
"@opencode-ai/ui": "workspace:*",
"@solidjs/meta": "catalog:",
"@solidjs/router": "catalog:",
"@solidjs/start": "catalog:",
"d3-geo": "3.1.1",
"d3-scale": "4.0.2",
"effect": "catalog:",
"i18n-iso-countries": "7.14.0",
"nitro": "3.0.1-alpha.1",
"solid-js": "catalog:",
"sst": "catalog:",
"topojson-client": "3.1.0",
"vite": "catalog:",
"world-atlas": "2.0.2"
},
"devDependencies": {
"@cloudflare/workers-types": "catalog:",
"@types/bun": "catalog:",
"@types/d3-geo": "3.1.0",
"@types/d3-scale": "4.0.9",
"@types/geojson": "7946.0.16",
"@types/topojson-client": "3.1.5",
"@types/topojson-specification": "1.0.5",
"@typescript/native-preview": "catalog:",
"typescript": "catalog:"
},
"engines": {
"node": ">=22"
}
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 163 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 116 KiB

View File

@@ -0,0 +1,123 @@
:root {
color-scheme: light dark;
--stats-bg: #f8f5ee;
--stats-ink: #16110d;
--stats-muted: #6d6257;
--stats-line: #ded5c9;
--stats-panel: #fffaf1;
--stats-accent: #2357ff;
}
@media (prefers-color-scheme: dark) {
:root {
--stats-bg: #11100e;
--stats-ink: #f7efe4;
--stats-muted: #b8aa99;
--stats-line: #322d27;
--stats-panel: #1a1714;
--stats-accent: #86a2ff;
}
}
html {
line-height: 1;
background: var(--stats-bg);
}
body {
margin: 0;
min-width: 320px;
background:
radial-gradient(circle at top left, color-mix(in srgb, var(--stats-accent) 16%, transparent), transparent 32rem),
var(--stats-bg);
color: var(--stats-ink);
font-family: ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, "Liberation Mono", "Courier New", monospace;
-webkit-font-smoothing: antialiased;
}
a {
color: inherit;
}
.shell {
box-sizing: border-box;
min-height: 100vh;
padding: 2rem clamp(1rem, 4vw, 4rem);
}
.panel {
display: grid;
gap: clamp(2rem, 8vw, 5rem);
box-sizing: border-box;
width: min(100%, 72rem);
margin: 0 auto;
padding: clamp(1.25rem, 4vw, 3rem);
border: 1px solid var(--stats-line);
border-radius: 1.5rem;
background: color-mix(in srgb, var(--stats-panel) 88%, transparent);
}
.eyebrow {
margin: 0 0 1rem;
color: var(--stats-muted);
font-size: 0.75rem;
letter-spacing: 0.14em;
text-transform: uppercase;
}
h1 {
max-width: 11ch;
margin: 0;
font-size: clamp(3rem, 14vw, 9rem);
line-height: 0.85;
letter-spacing: -0.08em;
}
.summary {
max-width: 42rem;
margin: 1.5rem 0 0;
color: var(--stats-muted);
font-size: clamp(1rem, 2vw, 1.25rem);
line-height: 1.6;
}
.grid {
display: grid;
grid-template-columns: repeat(3, minmax(0, 1fr));
gap: 1px;
overflow: hidden;
border: 1px solid var(--stats-line);
border-radius: 1rem;
background: var(--stats-line);
}
.metric {
padding: 1rem;
background: var(--stats-panel);
}
.metric b {
display: block;
margin-bottom: 0.5rem;
font-size: clamp(1.5rem, 4vw, 3rem);
letter-spacing: -0.05em;
}
.metric span {
color: var(--stats-muted);
font-size: 0.8125rem;
}
.link {
display: inline-flex;
width: fit-content;
margin-top: 1.5rem;
color: var(--stats-accent);
text-decoration: none;
}
@media (max-width: 720px) {
.grid {
grid-template-columns: 1fr;
}
}

View File

@@ -0,0 +1,31 @@
import { MetaProvider, Meta, Title } from "@solidjs/meta"
import { Router } from "@solidjs/router"
import { FileRoutes } from "@solidjs/start/router"
import { Suspense } from "solid-js"
import "./app.css"
function AppMeta() {
return (
<>
<Title>OpenCode Data</Title>
<Meta name="description" content="OpenCode usage data, market share, token cost, and session cost." />
</>
)
}
export default function App() {
return (
<Router
base={import.meta.env.BASE_URL.replace(/\/$/, "")}
explicitLinks={true}
root={(props) => (
<MetaProvider>
<AppMeta />
<Suspense>{props.children}</Suspense>
</MetaProvider>
)}
>
<FileRoutes />
</Router>
)
}

View File

@@ -0,0 +1,18 @@
<svg width="234" height="42" viewBox="0 0 234 42" fill="none" xmlns="http://www.w3.org/2000/svg">
<path d="M18 30H6V18H18V30Z" fill="#4B4646"/>
<path d="M18 12H6V30H18V12ZM24 36H0V6H24V36Z" fill="#B7B1B1"/>
<path d="M48 30H36V18H48V30Z" fill="#4B4646"/>
<path d="M36 30H48V12H36V30ZM54 36H36V42H30V6H54V36Z" fill="#B7B1B1"/>
<path d="M84 24V30H66V24H84Z" fill="#4B4646"/>
<path d="M84 24H66V30H84V36H60V6H84V24ZM66 18H78V12H66V18Z" fill="#B7B1B1"/>
<path d="M108 36H96V18H108V36Z" fill="#4B4646"/>
<path d="M108 12H96V36H90V6H108V12ZM114 36H108V12H114V36Z" fill="#B7B1B1"/>
<path d="M144 30H126V18H144V30Z" fill="#4B4646"/>
<path d="M144 12H126V30H144V36H120V6H144V12Z" fill="#F1ECEC"/>
<path d="M168 30H156V18H168V30Z" fill="#4B4646"/>
<path d="M168 12H156V30H168V12ZM174 36H150V6H174V36Z" fill="#F1ECEC"/>
<path d="M198 30H186V18H198V30Z" fill="#4B4646"/>
<path d="M198 12H186V30H198V12ZM204 36H180V6H198V0H204V36Z" fill="#F1ECEC"/>
<path d="M234 24V30H216V24H234Z" fill="#4B4646"/>
<path d="M216 12V18H228V12H216ZM234 24H216V30H234V36H210V6H234V24Z" fill="#F1ECEC"/>
</svg>

After

Width:  |  Height:  |  Size: 1.1 KiB

View File

@@ -0,0 +1,18 @@
<svg width="234" height="42" viewBox="0 0 234 42" fill="none" xmlns="http://www.w3.org/2000/svg">
<path d="M18 30H6V18H18V30Z" fill="#CFCECD"/>
<path d="M18 12H6V30H18V12ZM24 36H0V6H24V36Z" fill="#656363"/>
<path d="M48 30H36V18H48V30Z" fill="#CFCECD"/>
<path d="M36 30H48V12H36V30ZM54 36H36V42H30V6H54V36Z" fill="#656363"/>
<path d="M84 24V30H66V24H84Z" fill="#CFCECD"/>
<path d="M84 24H66V30H84V36H60V6H84V24ZM66 18H78V12H66V18Z" fill="#656363"/>
<path d="M108 36H96V18H108V36Z" fill="#CFCECD"/>
<path d="M108 12H96V36H90V6H108V12ZM114 36H108V12H114V36Z" fill="#656363"/>
<path d="M144 30H126V18H144V30Z" fill="#CFCECD"/>
<path d="M144 12H126V30H144V36H120V6H144V12Z" fill="#211E1E"/>
<path d="M168 30H156V18H168V30Z" fill="#CFCECD"/>
<path d="M168 12H156V30H168V12ZM174 36H150V6H174V36Z" fill="#211E1E"/>
<path d="M198 30H186V18H198V30Z" fill="#CFCECD"/>
<path d="M198 12H186V30H198V12ZM204 36H180V6H198V0H204V36Z" fill="#211E1E"/>
<path d="M234 24V30H216V24H234Z" fill="#CFCECD"/>
<path d="M216 12V18H228V12H216ZM234 24H216V30H234V36H210V6H234V24Z" fill="#211E1E"/>
</svg>

After

Width:  |  Height:  |  Size: 1.1 KiB

View File

@@ -0,0 +1,7 @@
// @refresh reload
import { mount, StartClient } from "@solidjs/start/client"
const root = document.getElementById("app")
if (!root) throw new Error("Root element #app not found")
mount(() => <StartClient />, root)

View File

@@ -0,0 +1,37 @@
// @refresh reload
import { createHandler, StartServer } from "@solidjs/start/server"
const statsThemePreloadScript = `;(function () {
var preference = "system"
try {
var stored = localStorage.getItem("opencode:stats-theme")
if (stored === "dark" || stored === "light" || stored === "system") preference = stored
} catch (_) {}
document.documentElement.dataset.statsTheme = preference
if (preference === "system") document.documentElement.style.removeProperty("color-scheme")
else document.documentElement.style.setProperty("color-scheme", preference)
})()`
export default createHandler(
() => (
<StartServer
document={({ assets, children, scripts }) => (
<html lang="en">
<head>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1" />
<script id="stats-theme-preload-script">{statsThemePreloadScript}</script>
{assets}
</head>
<body>
<div id="app">{children}</div>
{scripts}
</body>
</html>
)}
/>
),
{
mode: "async",
},
)

1
packages/stats/app/src/global.d.ts vendored Normal file
View File

@@ -0,0 +1 @@
/// <reference types="@solidjs/start/env" />

10
packages/stats/app/src/resource.d.ts vendored Normal file
View File

@@ -0,0 +1,10 @@
import "sst/resource"
declare module "sst/resource" {
export interface Resource {
EMAILOCTOPUS_API_KEY: {
type: "sst.sst.Secret"
value: string
}
}
}

View File

@@ -0,0 +1,836 @@
import "../index.css"
import { Link, Meta, Title } from "@solidjs/meta"
import { ProviderIcon } from "@opencode-ai/ui/provider-icon"
import { geoEquirectangular, geoPath } from "d3-geo"
import { scaleSqrt } from "d3-scale"
import countryCodesSource from "i18n-iso-countries/codes.json?raw"
import { feature, mesh } from "topojson-client"
import countriesTopologySource from "world-atlas/countries-110m.json?raw"
import {
getStatsModelData,
type CountryEntry,
type ModelPeerEntry,
type ModelUsagePoint,
type StatsModelData,
type UsageRange,
} from "@opencode-ai/stats-core/domain/home"
import { runtime } from "@opencode-ai/stats-core/runtime"
import { createAsync, query, useParams } from "@solidjs/router"
import { createMemo, createSignal, For, onMount, Show, type JSX } from "solid-js"
import { getRequestEvent } from "solid-js/web"
import type { FeatureCollection, GeometryObject, GeoJsonProperties } from "geojson"
import type { GeometryCollection, Topology } from "topojson-specification"
import { findModelCatalogEntry, formatCatalogLabName, getModelCatalog, type ModelCatalogEntry } from "../model-catalog"
import {
applyThemePreference,
Footer,
getGitHubStars,
Header,
isThemePreference,
themeStorageKey,
type HeaderLink,
type ThemePreference,
} from "../stats-shell"
const statsCanonicalBaseUrl = "https://opencode.ai/data/"
const statsUnfurlPath = "banner.png"
const statsUnfurlAlt = "OpenCode Data wordmark on a dark patterned background"
const statsUnfurlUrl = new URL(statsUnfurlPath, statsCanonicalBaseUrl).toString()
const modelHeaderLinks: readonly HeaderLink[] = [
{ href: "#overview", label: "Overview" },
{ href: "#usage", label: "Usage" },
{ href: "#efficiency", label: "Efficiency" },
{ href: "#geo-breakdown", label: "Geo Breakdown" },
{ href: "#peers", label: "Peers" },
]
const modelFooterLinks: readonly HeaderLink[] = [
{ href: import.meta.env.BASE_URL, label: "Data Home" },
{ href: `${import.meta.env.BASE_URL}#top-models`, label: "Top Models" },
{ href: `${import.meta.env.BASE_URL}#leaderboard`, label: "Leaderboard" },
{ href: `${import.meta.env.BASE_URL}#session-cost`, label: "Session Cost" },
{ href: `${import.meta.env.BASE_URL}#token-cost`, label: "Token Cost" },
{ href: `${import.meta.env.BASE_URL}#market-share`, label: "Market Share" },
{ href: `${import.meta.env.BASE_URL}#geo-breakdown`, label: "Geo Breakdown" },
]
const geoMapWidth = 960
const geoMapHeight = 430
const countryDisplayNames = new Intl.DisplayNames(["en"], { type: "region" })
type IsoCountryCode = readonly [string, string, string]
type WorldCountryProperties = GeoJsonProperties & { name?: string }
type WorldTopology = Topology<{ countries: GeometryCollection<WorldCountryProperties> }>
const countryNumericIds = new Map(
(JSON.parse(countryCodesSource) as IsoCountryCode[]).map((country) => [country[0], country[2]] as const),
)
const worldTopology = JSON.parse(countriesTopologySource) as WorldTopology
const worldCountryGeometries: GeometryCollection<WorldCountryProperties> = {
...worldTopology.objects.countries,
geometries: worldTopology.objects.countries.geometries.filter((country) => String(country.id ?? "") !== "010"),
}
const worldCountries = feature<WorldCountryProperties>(worldTopology, worldCountryGeometries) as FeatureCollection<
GeometryObject,
WorldCountryProperties
>
const worldProjection = geoEquirectangular().fitExtent(
[
[10, 12],
[geoMapWidth - 10, geoMapHeight - 12],
],
worldCountries,
)
const worldPath = geoPath(worldProjection)
const worldCountryPaths = worldCountries.features.map((country) => ({
id: String(country.id ?? "").padStart(3, "0"),
path: worldPath(country) ?? "",
}))
const worldBorderPath = worldPath(mesh(worldTopology, worldCountryGeometries, (a, b) => a !== b)) ?? ""
const getModelData = query(async (lab: string, model: string) => {
"use server"
return runtime.runPromise(getStatsModelData(model, lab))
}, "getStatsModelData")
export default function StatsModel() {
const event = getRequestEvent()
event?.response.headers.set("Cache-Control", "public, max-age=60, s-maxage=300, stale-while-revalidate=86400")
const params = useParams()
const labParam = createMemo(() => params.lab ?? "")
const modelParam = createMemo(() => params.model ?? "")
const catalog = createAsync(() => getModelCatalog())
const catalogEntry = createMemo(() => {
const data = catalog()
if (!data) return undefined
return findModelCatalogEntry(data, modelParam(), labParam()) ?? null
})
const stats = createAsync(() => {
const entry = catalogEntry()
if (catalog() === undefined || entry === undefined) return Promise.resolve(undefined)
if (!entry && (!labParam() || !modelParam())) return Promise.resolve(null)
return getModelData(labParam(), entry?.slug ?? modelParam())
})
const githubStars = createAsync(() => getGitHubStars())
const [themePreference, setThemePreference] = createSignal<ThemePreference>("system")
const modelName = createMemo(() => catalogEntry()?.name ?? stats()?.model ?? modelParam() ?? "Model")
const labName = createMemo(() => formatCatalogLabName(catalogEntry()?.lab ?? stats()?.provider ?? labParam()))
const modelTitle = createMemo(() => `${modelName()} Data`)
const modelDescription = createMemo(() =>
stats()
? `${modelName()} usage, rank, token mix, cost, geo breakdown, and peer data across OpenCode.`
: `${modelName()} model facts, limits, and OpenCode usage availability.`,
)
const modelUrl = createMemo(() =>
new URL(
catalogEntry()?.id ?? [labParam(), stats()?.slug ?? modelParam()].filter((part) => part.length > 0).join("/"),
statsCanonicalBaseUrl,
).toString(),
)
const updateThemePreference = (preference: ThemePreference) => {
applyThemePreference(preference)
setThemePreference(preference)
if (typeof window === "undefined") return
window.localStorage.setItem(themeStorageKey, preference)
}
onMount(() => {
if (typeof window === "undefined") return
const preference = window.localStorage.getItem(themeStorageKey)
const nextPreference = isThemePreference(preference) ? preference : "system"
applyThemePreference(nextPreference)
setThemePreference(nextPreference)
})
return (
<main data-page="stats" data-theme={themePreference()}>
<Title>{modelTitle()}</Title>
<Meta name="description" content={modelDescription()} />
<Link rel="canonical" href={modelUrl()} />
<Meta property="og:type" content="website" />
<Meta property="og:site_name" content="OpenCode" />
<Meta property="og:title" content={modelTitle()} />
<Meta property="og:description" content={modelDescription()} />
<Meta property="og:url" content={modelUrl()} />
<Meta property="og:image" content={statsUnfurlUrl} />
<Meta property="og:image:type" content="image/png" />
<Meta property="og:image:width" content="1200" />
<Meta property="og:image:height" content="630" />
<Meta property="og:image:alt" content={statsUnfurlAlt} />
<Meta name="twitter:card" content="summary_large_image" />
<Meta name="twitter:title" content={modelTitle()} />
<Meta name="twitter:description" content={modelDescription()} />
<Meta name="twitter:image" content={statsUnfurlUrl} />
<Meta name="twitter:image:alt" content={statsUnfurlAlt} />
<Header githubStars={githubStars() ?? "150K"} links={modelHeaderLinks} brandHref={import.meta.env.BASE_URL} />
<div data-component="container">
<div data-component="content">
<Show when={catalogEntry() || stats() !== undefined} fallback={<ModelLoading />}>
<Show when={catalogEntry() || stats()} fallback={<ModelNotFound lab={labParam()} model={modelParam()} />}>
<>
<ModelHero data={stats() ?? null} catalog={catalogEntry() ?? null} labName={labName()} />
<ModelOverview data={stats() ?? null} />
<ModelUsageSection data={stats()?.usage ?? []} />
<ModelEfficiencySection data={stats() ?? null} />
<ModelGeoBreakdownSection data={stats()?.country ?? emptyCountryRecord()} />
<ModelPeersSection data={stats() ?? null} />
</>
</Show>
</Show>
</div>
<Footer
themePreference={themePreference()}
onThemePreferenceChange={updateThemePreference}
links={modelFooterLinks}
/>
</div>
</main>
)
}
function ModelLoading() {
return (
<>
<section id="overview" data-section="model-hero">
<div data-slot="model-hero-grid">
<div data-slot="model-hero-copy">
<a data-slot="model-back-link" href={import.meta.env.BASE_URL}>
Data
</a>
<h1>Model Data</h1>
<p>Reading model aggregates from model_stat.</p>
</div>
</div>
</section>
<section data-section="model-panel">
<ModelEmptyState title="Loading model data" description="Reading the model profile." />
</section>
</>
)
}
function ModelNotFound(props: { lab: string; model: string }) {
return (
<>
<section id="overview" data-section="model-hero">
<div data-slot="model-hero-grid">
<div data-slot="model-hero-copy">
<a data-slot="model-back-link" href={import.meta.env.BASE_URL}>
Data
</a>
<h1>{props.model || "Model"}</h1>
<p>No model facts or model_stat rows matched {props.lab ? `${props.lab}/${props.model}` : props.model}.</p>
</div>
</div>
</section>
<section data-section="model-panel">
<ModelEmptyState title="No model data" description="Try opening a model from the leaderboard." />
</section>
</>
)
}
function ModelHero(props: { data: StatsModelData | null; catalog: ModelCatalogEntry | null; labName: string }) {
const labId = () => props.catalog?.lab ?? props.data?.provider ?? props.labName
const modelId = () => props.catalog?.id ?? props.data?.model ?? "Model"
const weights = () => props.catalog?.weights[0]
return (
<section id="overview" data-section="model-hero">
<a data-slot="model-back-link" href={import.meta.env.BASE_URL}>
Data
</a>
<div data-slot="model-hero-grid">
<div data-slot="model-hero-copy">
<div data-slot="model-hero-tags">
<a data-slot="hero-meta" href={`${import.meta.env.BASE_URL}${providerSlug(labId())}`}>
<ProviderIcon aria-hidden="true" id={getProviderIconId(labId())} />
<span>{props.labName}</span>
</a>
<span data-slot="model-id-tag">{modelId()}</span>
</div>
<h1>{props.catalog?.name ?? props.data?.model ?? "Model"}</h1>
<Show
when={props.data}
fallback={
<p>Model facts from the shared model index. OpenCode usage appears once this model has activity.</p>
}
>
{(data) => (
<p>
Ranked #{data().rank} across recent OpenCode token usage with {formatPercent(data().tokenShare)} of
observed volume.
</p>
)}
</Show>
<Show when={props.catalog?.openWeights && weights()}>
{(weight) => (
<a data-slot="model-weight-link" href={weight().url} target="_blank" rel="noopener noreferrer">
Model weights: {weight().label}
</a>
)}
</Show>
</div>
<Show when={props.data} fallback={<ModelCatalogCallout catalog={props.catalog} />}>
{(data) => (
<div data-component="model-rank-panel">
<span>Current Rank</span>
<strong>#{data().rank}</strong>
<p>{formatRankMoveLabel(data().previousRank, data().rank)}</p>
</div>
)}
</Show>
</div>
<div data-slot="model-hero-pattern" aria-hidden="true" />
<Show when={props.catalog}>{(catalog) => <ModelCatalogPanel data={catalog()} />}</Show>
</section>
)
}
function ModelCatalogCallout(props: { catalog: ModelCatalogEntry | null }) {
return (
<div data-component="model-rank-panel">
<span>Model Profile</span>
<strong>{props.catalog?.releaseDate ? formatCatalogDate(props.catalog.releaseDate) : "Listed"}</strong>
<p>No OpenCode usage in the current data window.</p>
</div>
)
}
function ModelCatalogPanel(props: { data: ModelCatalogEntry }) {
return (
<aside data-component="model-catalog" aria-label="Model facts">
<div data-slot="model-catalog-grid">
<CatalogDatum label="Context" value={formatCatalogLimit(props.data.limit?.context)} />
<CatalogDatum label="Output" value={formatCatalogLimit(props.data.limit?.output)} />
<CatalogDatum label="Knowledge" value={formatCatalogDate(props.data.knowledge)} />
<CatalogDatum label="Release" value={formatCatalogDate(props.data.releaseDate)} />
<CatalogDatum label="Inputs" value={formatCatalogModalities(props.data.modalities.input)} />
</div>
</aside>
)
}
function CatalogDatum(props: { label: string; value: string }) {
return (
<article data-component="model-catalog-datum">
<span>{props.label}</span>
<strong>{props.value}</strong>
</article>
)
}
function ModelOverview(props: { data: StatsModelData | null }) {
return (
<section data-section="model-panel">
<SectionTitle title="Overview" description="Recent tokens, sessions, and market position." />
<Show
when={props.data}
fallback={<ModelEmptyState title="No usage summary" description="This model has no OpenCode usage rows yet." />}
>
{(data) => (
<div data-component="model-metric-grid">
<MetricCard label="Tokens" value={formatTokens(data().totals.tokens)} detail="last two months" />
<MetricCard label="Sessions" value={formatInteger(data().totals.sessions)} detail="completed sessions" />
<MetricCard
label="Token Share"
value={formatPercent(data().tokenShare)}
detail={`${data().totalModels} models`}
/>
<MetricCard
label="Momentum"
value={formatChange(data().tokenChange)}
detail="vs previous window"
state={data().tokenChange < 0 ? "negative" : "positive"}
/>
</div>
)}
</Show>
</section>
)
}
function ModelUsageSection(props: { data: ModelUsagePoint[] }) {
const [activeIndex, setActiveIndex] = createSignal<number>()
const max = createMemo(() => Math.max(0, ...props.data.map((item) => item.tokens)) || 1)
const activePoint = createMemo(() => {
const index = activeIndex()
if (index === undefined) return undefined
return props.data[index]
})
return (
<section id="usage" data-section="model-panel">
<SectionTitle title="Usage" description="Daily token volume over the recent two-month window." />
<Show
when={props.data.some((item) => item.tokens > 0)}
fallback={<ModelEmptyState title="No usage" description="No usage landed in the current window." />}
>
<div
data-component="model-usage-chart"
data-dense-labels={isModelUsageDense(props.data.length) ? "true" : undefined}
role="img"
aria-label="Daily token usage chart"
style={{ "--model-usage-count": props.data.length } as JSX.CSSProperties}
onPointerLeave={(event) => {
if (event.pointerType === "touch") return
setActiveIndex(undefined)
}}
>
<div data-slot="model-usage-axis" aria-hidden="true">
<For each={props.data}>
{(point, index) => (
<div
data-active={activeIndex() === index() ? "true" : undefined}
data-label-hidden={isModelUsageLabelHidden(index(), props.data.length) ? "true" : undefined}
>
<span data-slot="model-usage-label">
<span data-slot="model-usage-total">{formatTokens(point.tokens)}</span>
<span data-slot="model-usage-date">{point.date}</span>
</span>
</div>
)}
</For>
</div>
<div data-slot="model-usage-bars">
<For each={props.data}>
{(point, index) => (
<div
data-slot="model-usage-column"
role="button"
tabIndex={0}
aria-label={`${point.date} ${formatTokens(point.tokens)} tokens`}
data-active={activeIndex() === index() ? "true" : undefined}
data-muted={activeIndex() !== undefined && activeIndex() !== index() ? "true" : undefined}
onPointerDown={(event) => {
if (event.pointerType !== "touch") return
setActiveIndex(index())
}}
onPointerEnter={() => setActiveIndex(index())}
onPointerMove={(event) => {
if (event.pointerType === "touch") return
setActiveIndex(index())
}}
onClick={() => setActiveIndex(index())}
onFocus={() => setActiveIndex(index())}
onBlur={() => setActiveIndex(undefined)}
onKeyDown={(event) => {
if (event.key !== "Enter" && event.key !== " ") return
event.preventDefault()
setActiveIndex(index())
}}
>
<div
data-slot="model-usage-bar"
style={{ "--model-usage-fill": `${modelUsageHeight(point.tokens, max())}%` } as JSX.CSSProperties}
/>
<Show when={activeIndex() === index() && activePoint()}>
{(active) => (
<div
data-component="chart-tooltip"
data-placement={index() > props.data.length * 0.62 ? "left" : "right"}
>
<strong>{active().date}</strong>
<span>{formatTokens(active().tokens)} tokens</span>
<div data-slot="tooltip-divider" />
<p>
<span data-slot="tooltip-label">
<i /> Daily tokens
</span>
<b>{formatTokens(active().tokens)}</b>
</p>
</div>
)}
</Show>
</div>
)}
</For>
</div>
</div>
</Show>
</section>
)
}
function ModelEfficiencySection(props: { data: StatsModelData | null }) {
return (
<section id="efficiency" data-section="model-panel">
<SectionTitle title="Efficiency" description="Cost, cache behavior, and average session shape." />
<Show
when={props.data}
fallback={
<ModelEmptyState title="No efficiency data" description="Efficiency data appears after usage lands." />
}
>
{(data) => (
<div data-component="model-metric-grid" data-variant="dense">
<MetricCard label="Cost" value={formatMoney(data().totals.cost)} detail="total spend" />
<MetricCard label="Cost / 1M" value={formatMoney(data().totals.costPerMillion)} detail="all tokens" />
<MetricCard
label="Cost / Session"
value={formatSessionCost(data().totals.costPerSession)}
detail="average"
/>
<MetricCard
label="Tokens / Session"
value={formatTokens(data().totals.tokensPerSession)}
detail="average"
/>
<MetricCard label="Cache Ratio" value={formatPercent(data().totals.cacheRatio)} detail="input tokens" />
</div>
)}
</Show>
</section>
)
}
function ModelGeoBreakdownSection(props: { data: Record<UsageRange, CountryEntry[]> }) {
const [activeCountry, setActiveCountry] = createSignal<string>()
const data = createMemo(() => props.data["2M"])
const countryById = createMemo(
() =>
new Map(
data().flatMap((country) => {
const id = countryNumericId(country.country)
return id ? [[id, country] as const] : []
}),
),
)
const maxTokens = createMemo(() => Math.max(0, ...data().map((country) => country.tokens)) || 1)
const topCountries = createMemo(() => data().slice(0, 15))
const active = createMemo(() => data().find((country) => country.country === activeCountry()) ?? data()[0])
return (
<section
id="geo-breakdown"
data-section="geo-breakdown"
onPointerLeave={(event) => {
if (event.pointerType === "touch") return
setActiveCountry(undefined)
}}
>
<SectionTitle title="Geo Breakdown" description="Model tokens used by country." />
<Show
when={data().length > 0}
fallback={<ModelEmptyState title="No geo data" description="No geo_stat rows matched this model." />}
>
<div data-component="geo-breakdown">
<div data-slot="geo-map-panel">
<GeoWorldMap
countryById={countryById()}
activeCountry={activeCountry()}
maxTokens={maxTokens()}
onActiveCountryChange={setActiveCountry}
/>
<Show when={active()}>
{(country) => (
<div data-slot="geo-active-country">
<span>#{String(country().rank).padStart(2, "0")}</span>
<strong>{formatCountryName(country().country)}</strong>
<p>
<b>{formatGeoTokens(country().tokens)}</b>
<em>{formatGeoShare(country().share)}</em>
</p>
</div>
)}
</Show>
</div>
<GeoCountryList
data={topCountries()}
activeCountry={activeCountry()}
maxTokens={maxTokens()}
onActiveCountryChange={setActiveCountry}
/>
</div>
</Show>
</section>
)
}
function GeoWorldMap(props: {
countryById: Map<string, CountryEntry>
activeCountry: string | undefined
maxTokens: number
onActiveCountryChange: (country: string | undefined) => void
}) {
const opacityScale = createMemo(() => scaleSqrt().domain([0, props.maxTokens]).range([0.26, 0.96]).clamp(true))
const countryOpacity = (country: CountryEntry | undefined) => {
if (!country) return 0
const opacity = opacityScale()(country.tokens)
if (!props.activeCountry || props.activeCountry === country.country) return opacity
return Math.max(0.18, opacity * 0.36)
}
return (
<svg
data-component="geo-world-map"
viewBox={`0 0 ${geoMapWidth} ${geoMapHeight}`}
role="img"
aria-label="World map of model token usage by country"
>
<title>Geo Breakdown map</title>
<g data-slot="geo-countries">
<For each={worldCountryPaths}>
{(country) => {
const entry = () => props.countryById.get(country.id)
return (
<path
d={country.path}
data-has-data={entry() ? "true" : undefined}
data-active={entry()?.country === props.activeCountry ? "true" : undefined}
style={{ "--geo-country-opacity": String(countryOpacity(entry())) } as JSX.CSSProperties}
aria-hidden="true"
onPointerEnter={() => {
const item = entry()
if (!item) return
props.onActiveCountryChange(item.country)
}}
onClick={() => {
const item = entry()
if (!item) return
props.onActiveCountryChange(item.country)
}}
/>
)
}}
</For>
</g>
<path data-slot="geo-borders" d={worldBorderPath} aria-hidden="true" />
</svg>
)
}
function GeoCountryList(props: {
data: CountryEntry[]
activeCountry: string | undefined
maxTokens: number
onActiveCountryChange: (country: string | undefined) => void
}) {
const opacityScale = createMemo(() => scaleSqrt().domain([0, props.maxTokens]).range([0.26, 0.96]).clamp(true))
return (
<ol data-component="geo-country-list">
<For each={props.data}>
{(country) => (
<li>
<button
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)} ${formatGeoTokens(country.tokens)} ${formatGeoShare(
country.share,
)}`}
onClick={() => props.onActiveCountryChange(country.country)}
onPointerEnter={() => props.onActiveCountryChange(country.country)}
onFocus={() => props.onActiveCountryChange(country.country)}
>
<span>{String(country.rank).padStart(2, "0")}</span>
<i />
<strong>{formatCountryName(country.country)}</strong>
<em>{formatGeoTokens(country.tokens)}</em>
<b>{formatGeoShare(country.share)}</b>
</button>
</li>
)}
</For>
</ol>
)
}
function ModelPeersSection(props: { data: StatsModelData | null }) {
return (
<section id="peers" data-section="model-panel">
<SectionTitle title="Peers" description="Nearby models by recent token volume." />
<Show
when={props.data?.peers.length}
fallback={<ModelEmptyState title="No peers" description="Peer rankings appear after usage lands." />}
>
<ol data-component="model-peer-list">
<For each={props.data?.peers ?? []}>
{(peer) => <PeerRow peer={peer} active={peer.model === props.data?.model} />}
</For>
</ol>
</Show>
</section>
)
}
function MetricCard(props: { label: string; value: string; detail: string; state?: "positive" | "negative" }) {
return (
<article data-component="model-metric" data-state={props.state}>
<span>{props.label}</span>
<strong>{props.value}</strong>
<p>{props.detail}</p>
</article>
)
}
function PeerRow(props: { peer: ModelPeerEntry; active: boolean }) {
return (
<li>
<a
href={`${import.meta.env.BASE_URL}${providerSlug(props.peer.provider)}/${props.peer.slug}`}
data-active={props.active ? "true" : undefined}
>
<span>{String(props.peer.rank).padStart(2, "0")}</span>
<ProviderIcon aria-hidden="true" id={getProviderIconId(props.peer.author)} />
<strong>{props.peer.model}</strong>
<em>{props.peer.author}</em>
<b>{formatTokens(props.peer.tokens)}</b>
</a>
</li>
)
}
function SectionTitle(props: { title: string; description: string }) {
return (
<p data-slot="section-title">
<strong>{props.title}.</strong> <span>{props.description}</span>
</p>
)
}
function ModelEmptyState(props: { title: string; description: string; compact?: boolean }) {
return (
<div data-component="empty-state" data-compact={props.compact ? "true" : undefined}>
<strong>{props.title}</strong>
<p>{props.description}</p>
</div>
)
}
function getProviderIconId(author: string) {
if (author === "MiniMax") return "minimax"
if (author === "Moonshot") return "moonshotai"
if (author === "Zhipu") return "zhipuai"
return author.toLowerCase().replace(/[^a-z0-9]+/g, "")
}
function emptyCountryRecord(): Record<UsageRange, CountryEntry[]> {
return {
"1D": [],
"1W": [],
"2W": [],
"1M": [],
"2M": [],
"3M": [],
YTD: [],
ALL: [],
}
}
function countryNumericId(country: string) {
return countryNumericIds.get(country.toUpperCase())?.padStart(3, "0")
}
function formatCountryName(country: string) {
const code = country.toUpperCase()
if (code === "ZZ") return "Unknown"
if (!countryNumericId(code)) return code
return countryDisplayNames.of(code) ?? code
}
function formatGeoTokens(value: number) {
return formatTokens(value * 1_000_000_000_000)
}
function formatGeoShare(value: number) {
return `${value.toFixed(value > 0 && value < 1 ? 1 : 0)}%`
}
function modelUsageHeight(tokens: number, max: number) {
if (tokens <= 0) return 0
return Math.max(2, Math.min(100, (tokens / max) * 100))
}
function isModelUsageDense(count: number) {
return count > 20
}
function isModelUsageLabelHidden(index: number, count: number) {
if (count <= 16) return false
const interval = Math.ceil(count / 8)
return index !== count - 1 && index % interval !== 0
}
function formatRankMove(previousRank: number, rank: number) {
const change = previousRank - rank
if (change > 0) return `+${change}`
if (change < 0) return `${change}`
return "Even"
}
function formatRankMoveLabel(previousRank: number | null, rank: number) {
return previousRank === null ? "New in window" : `${formatRankMove(previousRank, rank)} vs previous window`
}
function formatTokens(value: number) {
if (value >= 1_000_000_000_000)
return `${trimNumber(value / 1_000_000_000_000, value >= 10_000_000_000_000 ? 0 : 1)}T`
if (value >= 1_000_000_000) return `${trimNumber(value / 1_000_000_000, value >= 10_000_000_000 ? 0 : 1)}B`
if (value >= 1_000_000) return `${trimNumber(value / 1_000_000, value >= 10_000_000 ? 0 : 1)}M`
if (value >= 1_000) return `${trimNumber(value / 1_000, value >= 10_000 ? 0 : 1)}K`
return String(Math.round(value))
}
function formatInteger(value: number) {
return new Intl.NumberFormat("en").format(value)
}
function formatPercent(value: number) {
return `${value.toFixed(value > 0 && value < 10 ? 1 : 0)}%`
}
function formatMoney(value: number) {
if (value >= 1_000_000) return `$${trimNumber(value / 1_000_000, value >= 10_000_000 ? 0 : 1)}M`
if (value >= 1_000) return `$${trimNumber(value / 1_000, value >= 10_000 ? 0 : 1)}K`
return `$${value.toFixed(value >= 10 ? 0 : 2)}`
}
function formatSessionCost(value: number) {
return `$${value.toFixed(value > 0 && value < 0.01 ? 4 : 2)}`
}
function formatChange(value: number) {
if (value > 0) return `+${value}%`
return `${value}%`
}
function formatCatalogLimit(value: number | undefined) {
return value === undefined ? "Unknown" : formatTokens(value)
}
function formatCatalogModalities(value: string[]) {
if (value.length === 0) return "Unknown"
return value.map(formatCatalogModality).join(", ")
}
function formatCatalogModality(value: string) {
if (value === "pdf") return "PDF"
return value.charAt(0).toUpperCase() + value.slice(1)
}
function formatCatalogDate(value: string | undefined) {
if (!value) return "Unknown"
const match = /^(\d{4})(?:-(\d{2}))?(?:-(\d{2}))?$/.exec(value)
if (!match) return value
const year = Number(match[1])
const month = match[2] ? Number(match[2]) - 1 : 0
const day = match[3] ? Number(match[3]) : 1
return new Intl.DateTimeFormat("en", {
month: match[2] ? "short" : undefined,
day: match[3] ? "numeric" : undefined,
year: "numeric",
timeZone: "UTC",
}).format(new Date(Date.UTC(year, month, day)))
}
function trimNumber(value: number, digits: number) {
return Number(value.toFixed(digits)).toLocaleString("en")
}
function providerSlug(provider: string) {
return provider
.trim()
.toLowerCase()
.replace(/[^a-z0-9]+/g, "-")
.replace(/^-+|-+$/g, "")
.replace(/-{2,}/g, "-")
}

View File

@@ -0,0 +1,432 @@
import "../index.css"
import { Link, Meta, Title } from "@solidjs/meta"
import {
getStatsLabData,
type LabUsageModelEntry,
type ModelUsagePoint,
type StatsLabData,
} from "@opencode-ai/stats-core/domain/home"
import { runtime } from "@opencode-ai/stats-core/runtime"
import { createAsync, query, useParams } from "@solidjs/router"
import { createMemo, createSignal, For, onMount, Show, type JSX } from "solid-js"
import { getRequestEvent } from "solid-js/web"
import {
findModelCatalogLab,
formatCatalogLabName,
getModelCatalog,
type ModelCatalogEntry,
type ModelCatalogLab,
} from "../model-catalog"
import {
applyThemePreference,
Footer,
getGitHubStars,
Header,
isThemePreference,
themeStorageKey,
type HeaderLink,
type ThemePreference,
} from "../stats-shell"
const statsCanonicalBaseUrl = "https://opencode.ai/data/"
const statsUnfurlPath = "banner.png"
const statsUnfurlAlt = "OpenCode Data wordmark on a dark patterned background"
const statsUnfurlUrl = new URL(statsUnfurlPath, statsCanonicalBaseUrl).toString()
const labHeaderLinks: readonly HeaderLink[] = [
{ href: "#overview", label: "Overview" },
{ href: "#usage", label: "Usage" },
{ href: "#models", label: "Models" },
]
const labFooterLinks: readonly HeaderLink[] = [
{ href: import.meta.env.BASE_URL, label: "Data Home" },
{ href: `${import.meta.env.BASE_URL}#top-models`, label: "Top Models" },
{ href: `${import.meta.env.BASE_URL}#market-share`, label: "Market Share" },
{ href: `${import.meta.env.BASE_URL}#geo-breakdown`, label: "Geo Breakdown" },
]
const getLabData = query(async (lab: string) => {
"use server"
return runtime.runPromise(getStatsLabData(lab))
}, "getStatsLabData")
export default function StatsLab() {
const event = getRequestEvent()
event?.response.headers.set("Cache-Control", "public, max-age=60, s-maxage=300, stale-while-revalidate=86400")
const params = useParams()
const labParam = createMemo(() => params.lab ?? "")
const catalog = createAsync(() => getModelCatalog())
const lab = createMemo(() => {
const data = catalog()
if (!data) return undefined
return findModelCatalogLab(data, labParam()) ?? null
})
const stats = createAsync(() => {
const entry = lab()
if (catalog() === undefined || entry === undefined) return Promise.resolve(undefined)
if (!entry) return Promise.resolve(null)
return getLabData(entry.id)
})
const githubStars = createAsync(() => getGitHubStars())
const [themePreference, setThemePreference] = createSignal<ThemePreference>("system")
const labName = createMemo(() => lab()?.name ?? formatCatalogLabName(labParam()))
const labTitle = createMemo(() => `${labName()} Models`)
const labDescription = createMemo(
() =>
`Explore ${labName()} models used in OpenCode, with recent token usage, context windows, release dates, and model-specific data.`,
)
const labUrl = createMemo(() => new URL(lab()?.id ?? labParam(), statsCanonicalBaseUrl).toString())
const updateThemePreference = (preference: ThemePreference) => {
applyThemePreference(preference)
setThemePreference(preference)
if (typeof window === "undefined") return
window.localStorage.setItem(themeStorageKey, preference)
}
onMount(() => {
if (typeof window === "undefined") return
const preference = window.localStorage.getItem(themeStorageKey)
const nextPreference = isThemePreference(preference) ? preference : "system"
applyThemePreference(nextPreference)
setThemePreference(nextPreference)
})
return (
<main data-page="stats" data-theme={themePreference()}>
<Title>{labTitle()}</Title>
<Meta name="description" content={labDescription()} />
<Link rel="canonical" href={labUrl()} />
<Meta property="og:type" content="website" />
<Meta property="og:site_name" content="OpenCode" />
<Meta property="og:title" content={labTitle()} />
<Meta property="og:description" content={labDescription()} />
<Meta property="og:url" content={labUrl()} />
<Meta property="og:image" content={statsUnfurlUrl} />
<Meta property="og:image:type" content="image/png" />
<Meta property="og:image:width" content="1200" />
<Meta property="og:image:height" content="630" />
<Meta property="og:image:alt" content={statsUnfurlAlt} />
<Meta name="twitter:card" content="summary_large_image" />
<Meta name="twitter:title" content={labTitle()} />
<Meta name="twitter:description" content={labDescription()} />
<Meta name="twitter:image" content={statsUnfurlUrl} />
<Meta name="twitter:image:alt" content={statsUnfurlAlt} />
<Header githubStars={githubStars() ?? "150K"} links={labHeaderLinks} brandHref={import.meta.env.BASE_URL} />
<div data-component="container">
<div data-component="content">
<Show when={catalog() !== undefined} fallback={<LabLoading />}>
<Show when={lab()} fallback={<LabNotFound lab={labParam()} />}>
{(data) => (
<>
<LabHero lab={data()} stats={stats() ?? null} />
<LabUsageSection lab={data()} data={stats() ?? null} />
<LabModelsSection lab={data()} usage={stats()?.models ?? []} />
</>
)}
</Show>
</Show>
</div>
<Footer
themePreference={themePreference()}
onThemePreferenceChange={updateThemePreference}
links={labFooterLinks}
/>
</div>
</main>
)
}
function LabLoading() {
return (
<section id="overview" data-section="lab-hero">
<div data-slot="model-hero-grid">
<div data-slot="model-hero-copy">
<a data-slot="model-back-link" href={import.meta.env.BASE_URL}>
Data
</a>
<h1>Model Lab</h1>
<p>Reading model availability and recent OpenCode usage.</p>
</div>
</div>
</section>
)
}
function LabNotFound(props: { lab: string }) {
return (
<section id="overview" data-section="lab-hero">
<div data-slot="model-hero-grid">
<div data-slot="model-hero-copy">
<a data-slot="model-back-link" href={import.meta.env.BASE_URL}>
Data
</a>
<h1>{formatCatalogLabName(props.lab)}</h1>
<p>No models matched this lab.</p>
</div>
</div>
</section>
)
}
function LabHero(props: { lab: ModelCatalogLab; stats: StatsLabData | null }) {
const latest = createMemo(
() =>
props.lab.models
.map((model) => model.releaseDate)
.filter((value): value is string => value !== undefined)
.toSorted((a, b) => new Date(b).getTime() - new Date(a).getTime())[0],
)
const featuredModels = createMemo(() => props.lab.models.slice(0, 3).map((model) => model.name))
return (
<section id="overview" data-section="lab-hero">
<a data-slot="model-back-link" href={import.meta.env.BASE_URL}>
Data
</a>
<div data-slot="model-hero-grid">
<div data-slot="model-hero-copy">
<h1>{props.lab.name}</h1>
<div data-slot="model-hero-pattern" aria-hidden="true" />
<p>
Explore {props.lab.models.length} {props.lab.name} models used in OpenCode
<Show when={featuredModels().length > 0}> including {formatList(featuredModels())}</Show>. Compare recent
token usage, context windows, release dates, and model-specific data.
</p>
</div>
<div data-component="model-rank-panel">
<span>Tokens Processed</span>
<strong>{props.stats ? formatTokens(props.stats.totals.tokens) : "Pending"}</strong>
<p>
{props.stats
? `${formatPercent(props.stats.tokenShare)} of recent OpenCode usage`
: latest()
? `Latest release ${formatCatalogDate(latest())}`
: "Usage appears after model activity lands"}
</p>
</div>
</div>
</section>
)
}
function LabUsageSection(props: { lab: ModelCatalogLab; data: StatsLabData | null }) {
const [activeIndex, setActiveIndex] = createSignal<number>()
const usage = createMemo(() => props.data?.usage ?? [])
const max = createMemo(() => Math.max(0, ...usage().map((item) => item.tokens)) || 1)
const activePoint = createMemo(() => {
const index = activeIndex()
if (index === undefined) return undefined
return usage()[index]
})
return (
<section id="usage" data-section="model-panel">
<p data-slot="section-title">
<strong>{props.lab.name} token usage.</strong>{" "}
<span>Daily OpenCode token volume over the last two months.</span>
</p>
<Show
when={usage().some((item) => item.tokens > 0)}
fallback={
<LabEmptyState
title="No usage yet"
description="Recent token usage appears here once this lab has activity."
/>
}
>
<div
data-component="model-usage-chart"
data-dense-labels={isLabUsageDense(usage().length) ? "true" : undefined}
role="img"
aria-label={`${props.lab.name} daily token usage chart`}
style={{ "--model-usage-count": usage().length } as JSX.CSSProperties}
onPointerLeave={(event) => {
if (event.pointerType === "touch") return
setActiveIndex(undefined)
}}
>
<div data-slot="model-usage-axis" aria-hidden="true">
<For each={usage()}>
{(point, index) => (
<div
data-active={activeIndex() === index() ? "true" : undefined}
data-label-hidden={isLabUsageLabelHidden(index(), usage().length) ? "true" : undefined}
>
<span data-slot="model-usage-label">
<span data-slot="model-usage-total">{formatTokens(point.tokens)}</span>
<span data-slot="model-usage-date">{point.date}</span>
</span>
</div>
)}
</For>
</div>
<div data-slot="model-usage-bars">
<For each={usage()}>
{(point, index) => (
<div
data-slot="model-usage-column"
role="button"
tabIndex={0}
aria-label={`${point.date} ${formatTokens(point.tokens)} tokens`}
data-active={activeIndex() === index() ? "true" : undefined}
data-muted={activeIndex() !== undefined && activeIndex() !== index() ? "true" : undefined}
onPointerDown={(event) => {
if (event.pointerType !== "touch") return
setActiveIndex(index())
}}
onPointerEnter={() => setActiveIndex(index())}
onPointerMove={(event) => {
if (event.pointerType === "touch") return
setActiveIndex(index())
}}
onClick={() => setActiveIndex(index())}
onFocus={() => setActiveIndex(index())}
onBlur={() => setActiveIndex(undefined)}
onKeyDown={(event) => {
if (event.key !== "Enter" && event.key !== " ") return
event.preventDefault()
setActiveIndex(index())
}}
>
<div
data-slot="model-usage-bar"
style={{ "--model-usage-fill": `${usageHeight(point.tokens, max())}%` } as JSX.CSSProperties}
/>
<Show when={activeIndex() === index() && activePoint()}>
{(active) => (
<div
data-component="chart-tooltip"
data-placement={index() > usage().length * 0.62 ? "left" : "right"}
>
<strong>{active().date}</strong>
<span>{formatTokens(active().tokens)} tokens</span>
<div data-slot="tooltip-divider" />
<p>
<span data-slot="tooltip-label">
<i /> Daily tokens
</span>
<b>{formatTokens(active().tokens)}</b>
</p>
</div>
)}
</Show>
</div>
)}
</For>
</div>
</div>
</Show>
</section>
)
}
function LabModelsSection(props: { lab: ModelCatalogLab; usage: LabUsageModelEntry[] }) {
const usageBySlug = createMemo(() => new Map(props.usage.map((item) => [item.slug, item])))
return (
<section id="models" data-section="model-panel">
<p data-slot="section-title">
<strong>{props.lab.name} models.</strong> <span>Recent usage and limits.</span>
</p>
<div data-component="lab-model-grid">
<For each={props.lab.models}>
{(model) => <LabModelCard model={model} usage={usageBySlug().get(model.slug)} />}
</For>
</div>
</section>
)
}
function LabModelCard(props: { model: ModelCatalogEntry; usage: LabUsageModelEntry | undefined }) {
return (
<a data-component="lab-model-card" href={`${import.meta.env.BASE_URL}${props.model.id}`}>
<strong>{props.model.name}</strong>
<div data-slot="lab-model-card-meta">
<p>
<b>Usage</b>
<em>{props.usage ? formatTokens(props.usage.tokens) : "—"}</em>
</p>
<p>
<b>Share</b>
<em>{props.usage ? formatPercent(props.usage.share) : "—"}</em>
</p>
<p>
<b>Context</b>
<em>{formatCatalogLimit(props.model.limit?.context)}</em>
</p>
<p>
<b>Output</b>
<em>{formatCatalogLimit(props.model.limit?.output)}</em>
</p>
<p>
<b>Release</b>
<em>{formatCatalogDate(props.model.releaseDate)}</em>
</p>
</div>
</a>
)
}
function LabEmptyState(props: { title: string; description: string }) {
return (
<div data-component="empty-state" data-compact="true">
<strong>{props.title}</strong>
<p>{props.description}</p>
</div>
)
}
function formatCatalogLimit(value: number | undefined) {
return value === undefined ? "Unknown" : formatTokens(value)
}
function formatCatalogDate(value: string | undefined) {
if (!value) return "Unknown"
const match = /^(\d{4})(?:-(\d{2}))?(?:-(\d{2}))?$/.exec(value)
if (!match) return value
const year = Number(match[1])
const month = match[2] ? Number(match[2]) - 1 : 0
const day = match[3] ? Number(match[3]) : 1
return new Intl.DateTimeFormat("en", {
month: match[2] ? "short" : undefined,
day: match[3] ? "numeric" : undefined,
year: "numeric",
timeZone: "UTC",
}).format(new Date(Date.UTC(year, month, day)))
}
function formatList(values: string[]) {
if (values.length <= 1) return values[0] ?? ""
if (values.length === 2) return `${values[0]} and ${values[1]}`
return `${values.slice(0, -1).join(", ")}, and ${values[values.length - 1]}`
}
function formatPercent(value: number) {
return `${trimNumber(value, value >= 10 ? 1 : 2)}%`
}
function formatTokens(value: number) {
if (value >= 1_000_000_000_000)
return `${trimNumber(value / 1_000_000_000_000, value >= 10_000_000_000_000 ? 0 : 1)}T`
if (value >= 1_000_000_000) return `${trimNumber(value / 1_000_000_000, value >= 10_000_000_000 ? 0 : 1)}B`
if (value >= 1_000_000) return `${trimNumber(value / 1_000_000, value >= 10_000_000 ? 0 : 1)}M`
if (value >= 1_000) return `${trimNumber(value / 1_000, value >= 10_000 ? 0 : 1)}K`
return String(Math.round(value))
}
function trimNumber(value: number, digits: number) {
return Number(value.toFixed(digits)).toLocaleString("en")
}
function usageHeight(value: number, max: number) {
if (value <= 0 || max <= 0) return 0
return Math.max(4, (value / max) * 100)
}
function isLabUsageDense(count: number) {
return count > 20
}
function isLabUsageLabelHidden(index: number, count: number) {
if (count <= 14) return false
const cadence = count > 45 ? 7 : count > 28 ? 4 : 2
return index % cadence !== 0 && index !== count - 1
}

View File

@@ -0,0 +1,19 @@
import { AppConfig } from "@opencode-ai/stats-core/config"
import { runtime } from "@opencode-ai/stats-core/runtime"
import { Effect } from "effect"
export async function GET() {
return Response.json(
await runtime.runPromise(
Effect.gen(function* () {
const config = yield* AppConfig
return {
ok: true,
app: "stats",
stage: config.stage,
publicUrl: config.publicUrl,
}
}),
),
)
}

View File

@@ -0,0 +1,29 @@
import { Resource } from "sst/resource"
const listId = "8b9bb82c-9d5f-11f0-975f-0df6fd1e4945"
export async function POST(event: { request: Request }) {
const contentType = event.request.headers.get("content-type") ?? ""
if (!contentType.includes("multipart/form-data") && !contentType.includes("application/x-www-form-urlencoded")) {
return Response.json({ error: "Email address is required" }, { status: 400 })
}
const form = await event.request.formData()
const emailAddress = form.get("email")
if (typeof emailAddress !== "string" || emailAddress.trim().length === 0) {
return Response.json({ error: "Email address is required" }, { status: 400 })
}
const response = await fetch(`https://api.emailoctopus.com/lists/${listId}/contacts`, {
method: "PUT",
headers: {
Authorization: `Bearer ${Resource.EMAILOCTOPUS_API_KEY.value}`,
"Content-Type": "application/json",
},
body: JSON.stringify({
email_address: emailAddress.trim(),
}),
})
if (!response.ok) return Response.json({ error: "Failed to subscribe" }, { status: 502 })
return Response.json({ success: true })
}

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,224 @@
import { query } from "@solidjs/router"
export const modelCatalogSourceUrl = "https://models.dev/models.json"
export type ModelCatalogEntry = {
id: string
lab: string
slug: string
name: string
family?: string
knowledge?: string
releaseDate?: string
lastUpdated?: string
limit?: { context?: number; output?: number }
modalities: { input: string[]; output: string[] }
openWeights: boolean
reasoning: boolean
toolCall: boolean
attachment: boolean
temperature: boolean
weights: { label: string; url: string }[]
benchmarks: ModelCatalogBenchmark[]
}
export type ModelCatalogBenchmark = {
name: string
score: number
metric?: string
harness?: string
variant?: string
dataset?: string
version?: string
source?: string
}
export type ModelCatalogLab = {
id: string
name: string
models: ModelCatalogEntry[]
}
export type ModelCatalog = {
models: ModelCatalogEntry[]
labs: ModelCatalogLab[]
}
export const getModelCatalog = query(async () => {
"use server"
const payload = await fetch(modelCatalogSourceUrl)
.then((response): Promise<unknown> => (response.ok ? (response.json() as Promise<unknown>) : Promise.resolve()))
.catch(() => undefined)
return buildModelCatalog(payload)
}, "getModelCatalog")
export function findModelCatalogEntry(catalog: ModelCatalog, model: string, lab?: string) {
const normalizedId = lab ? `${catalogSlug(lab)}/${catalogSlug(model)}` : model.trim().toLowerCase()
const leaf = catalogSlug(model)
return (
catalog.models.find((entry) => entry.id.toLowerCase() === normalizedId) ??
catalog.models.find((entry) => (lab ? entry.lab === catalogSlug(lab) : true) && entry.slug === leaf) ??
catalog.models.find((entry) => entry.slug === leaf)
)
}
export function findModelCatalogLab(catalog: ModelCatalog, lab: string) {
const id = catalogSlug(lab)
return catalog.labs.find((entry) => entry.id === id)
}
export function formatCatalogLabName(lab: string) {
const known: Record<string, string> = {
alibaba: "Alibaba",
anthropic: "Anthropic",
cohere: "Cohere",
deepseek: "DeepSeek",
google: "Google",
meta: "Meta",
minimax: "MiniMax",
mistral: "Mistral",
moonshotai: "Moonshot",
openai: "OpenAI",
perplexity: "Perplexity",
stepfun: "StepFun",
tencent: "Tencent",
xai: "xAI",
xiaomi: "Xiaomi",
zai: "Z.ai",
zhipuai: "Zhipu",
}
return known[catalogSlug(lab)] ?? lab.replace(/[-_]/g, " ").replace(/\b\w/g, (letter) => letter.toUpperCase())
}
export function catalogSlug(value: string) {
return value
.trim()
.toLowerCase()
.replace(/[^a-z0-9]+/g, "-")
.replace(/^-+|-+$/g, "")
.replace(/-{2,}/g, "-")
}
function buildModelCatalog(payload: unknown): ModelCatalog {
const models = (Array.isArray(payload) ? payload : isRecord(payload) ? Object.values(payload) : [])
.flatMap(readModelCatalogEntry)
.toSorted((a, b) => a.lab.localeCompare(b.lab) || displayDateTime(b.releaseDate) - displayDateTime(a.releaseDate))
return {
models,
labs: Object.values(
models.reduce<Record<string, ModelCatalogLab>>((result, model) => {
result[model.lab] = {
id: model.lab,
name: formatCatalogLabName(model.lab),
models: [...(result[model.lab]?.models ?? []), model],
}
return result
}, {}),
).toSorted((a, b) => a.name.localeCompare(b.name)),
}
}
function readModelCatalogEntry(value: unknown): ModelCatalogEntry[] {
if (!isRecord(value)) return []
const id = stringValue(value.id)
const name = stringValue(value.name)
const lab = id?.split("/")[0]
const slug = id?.split("/").slice(1).join("/")
if (!id || !name || !lab || !slug) return []
return [
{
id,
lab: catalogSlug(lab),
slug: catalogSlug(slug),
name,
family: stringValue(value.family),
knowledge: stringValue(value.knowledge),
releaseDate: stringValue(value.release_date),
lastUpdated: stringValue(value.last_updated),
limit: readCatalogLimit(value.limit),
modalities: readCatalogModalities(value.modalities),
openWeights: booleanValue(value.open_weights),
reasoning: booleanValue(value.reasoning),
toolCall: booleanValue(value.tool_call),
attachment: booleanValue(value.attachment),
temperature: booleanValue(value.temperature),
weights: readCatalogWeights(value.weights),
benchmarks: readCatalogBenchmarks(value.benchmarks),
},
]
}
function readCatalogLimit(value: unknown) {
if (!isRecord(value)) return undefined
return {
context: numberValue(value.context),
output: numberValue(value.output),
}
}
function readCatalogModalities(value: unknown) {
if (!isRecord(value)) return { input: [], output: [] }
return {
input: stringArrayValue(value.input),
output: stringArrayValue(value.output),
}
}
function readCatalogWeights(value: unknown) {
if (!Array.isArray(value)) return []
return value.flatMap((item) => {
if (!isRecord(item)) return []
const label = stringValue(item.label)
const url = stringValue(item.url)
return label && url ? [{ label, url }] : []
})
}
function readCatalogBenchmarks(value: unknown) {
if (!Array.isArray(value)) return []
return value.flatMap((item) => {
if (!isRecord(item)) return []
const name = stringValue(item.name)
const score = numberValue(item.score)
return name && score !== undefined
? [
{
name,
score,
metric: stringValue(item.metric),
harness: stringValue(item.harness),
variant: stringValue(item.variant),
dataset: stringValue(item.dataset),
version: stringValue(item.version),
source: stringValue(item.source),
},
]
: []
})
}
function displayDateTime(value: string | undefined) {
return value ? new Date(value).getTime() || 0 : 0
}
function isRecord(value: unknown): value is Record<string, unknown> {
return typeof value === "object" && value !== null && !Array.isArray(value)
}
function stringValue(value: unknown) {
return typeof value === "string" && value.trim() ? value : undefined
}
function numberValue(value: unknown) {
return typeof value === "number" && Number.isFinite(value) ? value : undefined
}
function booleanValue(value: unknown) {
return value === true
}
function stringArrayValue(value: unknown) {
return Array.isArray(value)
? value.filter((item): item is string => typeof item === "string" && item.trim() !== "")
: []
}

View File

@@ -0,0 +1,476 @@
import opencodeWordmarkDark from "../asset/logo-ornate-dark.svg"
import { query } from "@solidjs/router"
import { createEffect, createMemo, createSignal, For, onCleanup, onMount, Show } from "solid-js"
export type HeaderLink = { href: string; label: string }
export const headerLinks = [
{ href: "#top-models", label: "Top Models" },
{ href: "#leaderboard", label: "Leaderboard" },
{ href: "#session-cost", label: "Session Cost" },
{ href: "#token-cost", label: "Token Cost" },
{ href: "#cache-ratio", label: "Cache Ratio" },
{ href: "#market-share", label: "Market Share" },
{ href: "#geo-breakdown", label: "Geo Breakdown" },
] as const
export const githubLink = {
href: "https://github.com/anomalyco/opencode",
apiHref: "https://api.github.com/repos/anomalyco/opencode",
label: "GitHub",
fallbackStars: "150K",
ariaLabel: "Star OpenCode on GitHub",
}
export const themePreferences = ["dark", "light", "system"] as const
export const themeStorageKey = "opencode:stats-theme"
export type ThemePreference = (typeof themePreferences)[number]
const compactNumberFormatter = new Intl.NumberFormat("en", {
notation: "compact",
maximumFractionDigits: 1,
})
const themePreferenceLabels = {
dark: "Dark",
light: "Light",
system: "System",
} as const
export const getGitHubStars = query(async () => {
"use server"
return fetch(githubLink.apiHref, {
headers: {
Accept: "application/vnd.github+json",
"X-GitHub-Api-Version": "2022-11-28",
},
})
.then((response) => (response.ok ? response.json() : undefined))
.then((body: unknown) =>
body && typeof body === "object" && "stargazers_count" in body && typeof body.stargazers_count === "number"
? compactNumberFormatter.format(body.stargazers_count)
: githubLink.fallbackStars,
)
.catch(() => githubLink.fallbackStars)
}, "getGitHubStars")
export function isThemePreference(value: string | null): value is ThemePreference {
return value === "dark" || value === "light" || value === "system"
}
export function applyThemePreference(preference: ThemePreference) {
if (typeof document === "undefined") return
document.documentElement.dataset.statsTheme = preference
if (preference === "system") {
document.documentElement.style.removeProperty("color-scheme")
return
}
document.documentElement.style.setProperty("color-scheme", preference)
}
export function Header(props: { githubStars: string; links?: readonly HeaderLink[]; brandHref?: string }) {
const [menuOpen, setMenuOpen] = createSignal(false)
const [menuViewport, setMenuViewport] = createSignal(false)
const links = createMemo(() => props.links ?? headerLinks)
createEffect(() => {
if (typeof window === "undefined") return
const media = window.matchMedia("(max-width: 74.999rem)")
const update = () => setMenuViewport(media.matches)
update()
media.addEventListener("change", update)
onCleanup(() => media.removeEventListener("change", update))
})
createEffect(() => {
if (!menuOpen()) return
if (!menuViewport()) return
if (typeof document === "undefined") return
const page = document.querySelector<HTMLElement>('[data-page="stats"]')
const scrollbarWidth = window.innerWidth - document.documentElement.clientWidth
const htmlOverflow = document.documentElement.style.overflow
const pagePaddingRight = page?.style.paddingRight
const bodyOverflow = document.body.style.overflow
document.documentElement.style.overflow = "hidden"
if (scrollbarWidth > 0 && page) page.style.paddingRight = `${scrollbarWidth}px`
document.body.style.overflow = "hidden"
onCleanup(() => {
document.documentElement.style.overflow = htmlOverflow
if (page && pagePaddingRight !== undefined) page.style.paddingRight = pagePaddingRight
document.body.style.overflow = bodyOverflow
})
})
return (
<header data-component="top" data-menu-open={menuOpen() ? "true" : undefined}>
<div data-slot="header-bar">
<a data-slot="brand" href={props.brandHref ?? import.meta.env.BASE_URL} aria-label="Data home">
<DataWordmark />
</a>
<nav data-component="section-nav" aria-label="Data sections">
<ul>
<For each={links()}>
{(link) => (
<li>
<a href={link.href}>{link.label}</a>
</li>
)}
</For>
</ul>
</nav>
<div data-slot="header-actions">
<a
data-slot="header-button"
data-variant="neutral"
href={githubLink.href}
target="_blank"
rel="noreferrer"
aria-label={`${githubLink.ariaLabel} (${props.githubStars} stars)`}
>
<strong>{githubLink.label}</strong>
<span>[{props.githubStars}]</span>
</a>
<a data-slot="header-button" data-variant="contrast" href="https://opencode.ai/">
<strong>Try OpenCode</strong>
</a>
<button
data-slot="menu-button"
type="button"
aria-controls="stats-mobile-nav"
aria-expanded={menuOpen() ? "true" : "false"}
aria-label={menuOpen() ? "Close navigation" : "Open navigation"}
onClick={() => setMenuOpen((value) => !value)}
>
<svg width="16" height="16" viewBox="0 0 16 16" fill="none" aria-hidden="true">
<Show when={menuOpen()} fallback={<path d="M2 4.72H14M2 8.5H14M2 12.28H14" stroke="currentColor" />}>
<path d="M4.44 4.44L11.56 11.56M11.56 4.44L4.44 11.56" stroke="currentColor" />
</Show>
</svg>
</button>
</div>
</div>
<nav id="stats-mobile-nav" data-slot="mobile-menu" aria-label="Data sections" hidden={!menuOpen()}>
<a
data-slot="mobile-menu-item"
data-variant="github"
href={githubLink.href}
target="_blank"
rel="noreferrer"
aria-label={`${githubLink.ariaLabel} (${props.githubStars} stars)`}
>
<strong>{githubLink.label}</strong>
<span>[{props.githubStars}]</span>
</a>
<For each={links()}>
{(link) => (
<a data-slot="mobile-menu-item" href={link.href} onClick={() => setMenuOpen(false)}>
{link.label}
</a>
)}
</For>
</nav>
</header>
)
}
function DataWordmark() {
return (
<svg data-slot="stats-wordmark" width="66" height="20" viewBox="0 0 66 20" fill="none" aria-hidden="true">
<path opacity="0.2" d="M12 16H4V8H12V16Z" fill="currentColor" />
<path d="M12 4H4V16H12V4ZM16 20H0V0H16V20Z" fill="currentColor" />
<path
d="M63.3543 16L62.5119 12.8711H58.6437L57.8013 16H55.7383L59.2454 4H61.9618L65.4689 16H63.3543ZM61.0678 7.851L60.6896 5.94269H60.4489L60.0707 7.851L59.1595 11.1347H61.9962L61.0678 7.851Z"
fill="currentColor"
/>
<path d="M52.5951 5.87392V16H50.4461V5.87392H47.4375V4H55.6209V5.87392H52.5951Z" fill="currentColor" />
<path
d="M45.2059 16L44.3635 12.8711H40.4953L39.6529 16H37.5898L41.097 4H43.8133L47.3205 16H45.2059ZM42.9194 7.851L42.5411 5.94269H42.3004L41.9222 7.851L41.011 11.1347H43.8477L42.9194 7.851Z"
fill="currentColor"
/>
<path
d="M28 4H32.0917C32.8138 4 33.4556 4.11461 34.0172 4.34384C34.5903 4.5616 35.0716 4.9169 35.4613 5.40974C35.8625 5.89112 36.1662 6.51003 36.3725 7.26648C36.5788 8.02292 36.6819 8.9341 36.6819 10C36.6819 11.0659 36.5788 11.9771 36.3725 12.7335C36.1662 13.49 35.8625 14.1146 35.4613 14.6075C35.0716 15.0888 34.5903 15.4441 34.0172 15.6734C33.4556 15.8911 32.8138 16 32.0917 16H28V4ZM32.0917 14.1261C32.8252 14.1261 33.3926 13.9026 33.7937 13.4556C34.1948 12.9971 34.3954 12.3152 34.3954 11.4097V8.59026C34.3954 7.68481 34.1948 7.0086 33.7937 6.5616C33.3926 6.10315 32.8252 5.87392 32.0917 5.87392H30.149V14.1261H32.0917Z"
fill="currentColor"
/>
</svg>
)
}
function OpenCodeMark() {
return (
<svg data-slot="opencode-mark" width="40" height="40" viewBox="0 0 40 40" fill="none" aria-hidden="true">
<path d="M40 40H0V0H40V40Z" fill="var(--stats-logo-bg)" />
<path d="M26 29H14V17H26V29Z" fill="var(--stats-logo-fill)" />
<path d="M26 11H14V29H26V11ZM32 35H8V5H32V35Z" fill="var(--stats-logo-stroke)" />
</svg>
)
}
export function Footer(props: {
themePreference: ThemePreference
onThemePreferenceChange: (preference: ThemePreference) => void
links?: readonly HeaderLink[]
}) {
const [subscribeOpen, setSubscribeOpen] = createSignal(false)
const modelStats = props.links ?? [
{ href: "#top-models", label: "Top Models" },
{ href: "#leaderboard", label: "Leaderboard" },
{ href: "#session-cost", label: "Session Cost" },
{ href: "#token-cost", label: "Token Cost" },
{ href: "#cache-ratio", label: "Cache Ratio" },
{ href: "#market-share", label: "Market Share" },
{ href: "#geo-breakdown", label: "Geo Breakdown" },
]
const legal = [
{ href: "https://opencode.ai/legal/terms-of-service", label: "Terms of service" },
{ href: "https://opencode.ai/legal/privacy-policy", label: "Privacy policy" },
]
const connect = [
{ href: "mailto:hello@opencode.ai", label: "Contact us" },
{ href: "https://opencode.ai/discord", label: "Community" },
{ href: "https://x.com/opencode", label: "X" },
githubLink,
{ href: "https://www.youtube.com/@anomaly-co", label: "YouTube" },
]
return (
<footer data-component="footer">
<SectionBridge label="GEO BREAKDOWN" href="#geo-breakdown" />
<div data-slot="footer-grid">
<a data-slot="footer-mark" href="https://opencode.ai" aria-label="OpenCode home">
<OpenCodeMark />
</a>
<FooterColumn title="Model Data" links={modelStats} />
<FooterColumn title="Legal" links={legal} />
<FooterColumn title="Connect" links={connect} />
<div data-slot="footer-column">
<h2>Newsletter</h2>
<p>Be the first to know about new releases.</p>
<button data-slot="subscribe-button" type="button" onClick={() => setSubscribeOpen(true)}>
Subscribe
</button>
</div>
</div>
<div data-slot="footer-pattern" aria-hidden="true" />
<div data-slot="footer-bottom">
<div>
<span>© 2026 Anomaly Innovations Inc.</span>
<span data-slot="status">All systems Operational</span>
</div>
<div data-slot="theme-toggle" role="group" aria-label="Theme">
<For each={themePreferences}>
{(preference) => (
<button
data-slot="theme-option"
type="button"
aria-label={themePreferenceLabels[preference]}
aria-pressed={props.themePreference === preference ? "true" : "false"}
title={themePreferenceLabels[preference]}
onClick={() => props.onThemePreferenceChange(preference)}
>
<ThemePreferenceIcon preference={preference} />
</button>
)}
</For>
</div>
</div>
<Show when={subscribeOpen()}>
<SubscribeModal onClose={() => setSubscribeOpen(false)} />
</Show>
</footer>
)
}
function SectionBridge(props: { label: string; href: string }) {
return (
<a data-component="section-bridge" href={props.href}>
<span>LEAN MORE</span>
<i />
<strong>{props.label}</strong>
<b></b>
</a>
)
}
function ThemePreferenceIcon(props: { preference: ThemePreference }) {
return (
<svg data-slot="theme-icon" width="16" height="16" viewBox="0 0 16 16" fill="none" aria-hidden="true">
<Show
when={props.preference === "dark"}
fallback={
<Show
when={props.preference === "light"}
fallback={
<>
<rect x="1.5552" y="2.4448" width="12.8896" height="8.8888" fill="currentColor" opacity="0.3" />
<svg
x="1.0552"
y="1.9446"
width="13.8889"
height="12.5325"
viewBox="0 0 13.8889 12.5325"
preserveAspectRatio="none"
overflow="visible"
>
<path
d="M4.05559 12.0555C4.72936 11.8431 5.72492 11.6111 6.94448 11.6111M6.94448 11.6111C7.65114 11.6111 8.66981 11.6893 9.83336 12.0555M6.94448 11.6111L6.94448 9.38888M13.3889 0.5H0.500102C0.500102 0.5 0.500017 1.29594 0.500017 2.27778V7.61112C0.500017 8.59298 0.500007 9.38889 0.500007 9.38889H13.3889C13.3889 9.38889 13.3889 8.59298 13.3889 7.61112V2.27778C13.3889 1.29594 13.3889 0.5 13.3889 0.5Z"
stroke="currentColor"
/>
</svg>
</>
}
>
<svg
x="0.6102"
y="0.6102"
width="14.7778"
height="14.7778"
viewBox="0 0 14.7778 14.7778"
preserveAspectRatio="none"
overflow="visible"
>
<path
d="M7.38889 0.5V1.38889M12.26 2.51782L11.6315 3.14627M14.2778 7.38892H13.3889M12.26 12.26L11.6315 11.6316M7.38889 14.2778V13.3889M2.51778 12.26L3.14622 11.6316M0.5 7.38892H1.38889M2.51778 2.51782L3.14622 3.14627M7.38888 11.1666C9.47528 11.1666 11.1667 9.47526 11.1667 7.38886C11.1667 5.30245 9.47528 3.61108 7.38888 3.61108C5.30247 3.61108 3.6111 5.30245 3.6111 7.38886C3.6111 9.47526 5.30247 11.1666 7.38888 11.1666Z"
stroke="currentColor"
stroke-linecap="square"
/>
</svg>
</Show>
}
>
<svg
x="2.0549"
y="1.742"
width="12.3867"
height="12.3971"
viewBox="0 0 12.3867 12.3971"
preserveAspectRatio="none"
overflow="visible"
>
<path
d="M9.05556 8.39711C6.37067 8.39711 4.19444 6.22089 4.19444 3.536C4.19444 2.48445 4.53122 1.51456 5.09822 0.71889C2.48178 1.20733 0.5 3.49944 0.5 6.25822C0.5 9.37244 3.02467 11.8971 6.13889 11.8971C8.76156 11.8971 10.9596 10.1036 11.5903 7.67844C10.8514 8.13189 9.98578 8.39711 9.05556 8.39711Z"
stroke="currentColor"
stroke-linecap="round"
/>
</svg>
</Show>
</svg>
)
}
function SubscribeModal(props: { onClose: () => void }) {
const [status, setStatus] = createSignal<"idle" | "pending" | "success" | "error">("idle")
const [message, setMessage] = createSignal("")
let input: HTMLInputElement | undefined
onMount(() => {
if (typeof document === "undefined") return
const activeElement = document.activeElement instanceof HTMLElement ? document.activeElement : undefined
const htmlOverflow = document.documentElement.style.overflow
const bodyOverflow = document.body.style.overflow
document.documentElement.style.overflow = "hidden"
document.body.style.overflow = "hidden"
const focusTimeout = window.setTimeout(() => input?.focus(), 0)
const onKeyDown = (event: KeyboardEvent) => {
if (event.key === "Escape") props.onClose()
}
document.addEventListener("keydown", onKeyDown)
onCleanup(() => {
window.clearTimeout(focusTimeout)
document.documentElement.style.overflow = htmlOverflow
document.body.style.overflow = bodyOverflow
document.removeEventListener("keydown", onKeyDown)
activeElement?.focus()
})
})
return (
<div data-component="subscribe-modal" role="dialog" aria-modal="true" aria-labelledby="subscribe-title">
<div data-slot="modal-scrim" aria-hidden="true" onClick={props.onClose} />
<div data-slot="modal-panel">
<div data-slot="modal-brand">
<img data-slot="modal-logo" src={opencodeWordmarkDark} alt="OpenCode" />
<button data-slot="modal-close" type="button" aria-label="Close newsletter signup" onClick={props.onClose}>
<svg width="16" height="16" viewBox="0 0 16 16" fill="none" aria-hidden="true">
<path d="M4.44 4.44L11.56 11.56M11.56 4.44L4.44 11.56" stroke="currentColor" />
</svg>
</button>
</div>
<div data-slot="modal-body">
<div data-slot="modal-intro">
<h2 id="subscribe-title">OpenCode Newsletter</h2>
<p>
Be the first to know
<br />
about new releases.
</p>
</div>
<form
data-slot="subscribe-form"
method="post"
onSubmit={(event) => {
event.preventDefault()
const form = event.currentTarget
setStatus("pending")
setMessage("")
fetch(`${import.meta.env.BASE_URL}api/newsletter`, {
method: "POST",
body: new FormData(form),
}).then(
async (response) => {
if (response.ok) {
form.reset()
setStatus("success")
return
}
setMessage(await newsletterErrorMessage(response))
setStatus("error")
},
() => {
setMessage("Failed to subscribe")
setStatus("error")
},
)
}}
>
<input ref={input} type="email" name="email" placeholder="Email address" required />
<button type="submit" disabled={status() === "pending"}>
<span>{status() === "pending" ? "Subscribing..." : "Subscribe"}</span>
</button>
</form>
<div data-slot="subscribe-feedback" aria-live="polite">
<Show when={status() === "success"}>
<p data-state="success">You're subscribed.</p>
</Show>
<Show when={status() === "error"}>
<p data-state="error">{message()}</p>
</Show>
</div>
</div>
</div>
</div>
)
}
function newsletterErrorMessage(response: Response) {
return response.json().then(
(body: unknown) =>
body && typeof body === "object" && "error" in body && typeof body.error === "string"
? body.error
: "Failed to subscribe",
() => "Failed to subscribe",
)
}
function FooterColumn(props: { title: string; links: readonly { href: string; label: string }[] }) {
return (
<div data-slot="footer-column">
<h2>{props.title}</h2>
<nav aria-label={props.title}>
<For each={props.links}>
{(link) => (
<a href={link.href} target={link.href.startsWith("http") ? "_blank" : undefined} rel="noreferrer">
{link.label}
</a>
)}
</For>
</nav>
</div>
)
}

View File

@@ -0,0 +1 @@
export { GET } from "../../api/health"

View File

@@ -0,0 +1 @@
export { POST } from "../../api/newsletter"

10
packages/stats/app/sst-env.d.ts vendored Normal file
View File

@@ -0,0 +1,10 @@
/* This file is auto-generated by SST. Do not edit. */
/* tslint:disable */
/* eslint-disable */
/* deno-fmt-ignore-file */
/* biome-ignore-all lint: auto-generated */
/// <reference path="../../../sst-env.d.ts" />
import "sst"
export {}

View File

@@ -0,0 +1,22 @@
{
"$schema": "https://json.schemastore.org/tsconfig",
"compilerOptions": {
"target": "ESNext",
"module": "ESNext",
"skipLibCheck": true,
"moduleResolution": "bundler",
"allowSyntheticDefaultImports": true,
"esModuleInterop": true,
"jsx": "preserve",
"jsxImportSource": "solid-js",
"allowJs": true,
"strict": true,
"noEmit": true,
"types": ["vite/client", "bun"],
"isolatedModules": true,
"paths": {
"~/*": ["./src/*"]
}
},
"include": ["*.ts", "src", "../core/src/resource.d.ts"]
}

View File

@@ -0,0 +1,23 @@
import { solidStart } from "@solidjs/start/config"
import { nitro } from "nitro/vite"
import { defineConfig, type PluginOption } from "vite"
export default defineConfig({
base: "/data/",
plugins: [
solidStart() as PluginOption,
nitro({
compatibilityDate: "2024-09-19",
preset: "cloudflare-module",
cloudflare: {
nodeCompat: true,
},
}),
],
server: {
allowedHosts: true,
},
build: {
minify: false,
},
})