Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2,129 changes: 1,347 additions & 782 deletions bun.lock

Large diffs are not rendered by default.

1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@
"dev:stats": "bun sst shell --stage=production -- bun run --cwd packages/stats/app dev",
"dev:www": "bun run --cwd packages/www dev",
"dev:storybook": "bun --cwd packages/storybook storybook",
"bench:devex": "bun run --cwd packages/app test:bench:devex",
"lint": "oxlint",
"lint:effect-patterns": "ast-grep scan -c script/ast-grep/sgconfig.yml packages/util/src packages/core/src packages/server/src packages/protocol/src packages/cli/src",
"test:lint-rules": "ast-grep test -c script/ast-grep/sgconfig.yml",
Expand Down
22 changes: 22 additions & 0 deletions packages/app/e2e/performance/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,12 +2,34 @@

The app's high-volume performance diagnostics live under `packages/app/e2e/performance` and are excluded from normal local and CI Playwright discovery. The benchmark config builds the app and serves the production bundle before running scenarios serially.

The `devex` category is the explicit exception to the production-build rule. It measures development commands from submission through a user-visible ready state and has its own Playwright configuration.

Run the suite explicitly from `packages/app`:

```sh
bun run test:bench
```

Run the desktop development startup benchmark from the repository root:

```sh
bun run bench:devex
```

It runs five serial samples of the exact `bun dev:desktop` command. Each sample uses a fresh desktop profile, database, service configuration, service registration, and service process; the desktop selects an isolated ephemeral loopback endpoint. It removes desktop build output and the desktop Vite cache before every run; dependencies, Bun's package cache, and Electron remain installed. The harness stops only that sample's service; it does not stop or change the elected global OpenCode service. The measured endpoint is a visible Home page whose empty-state controls pass Playwright actionability checks. The command's Electron installation check remains inside the measured interval.

Set `DESKTOP_STARTUP_RUNS` only for focused diagnostics:

```sh
DESKTOP_STARTUP_RUNS=1 bun run bench:devex
```

Set `OPENCODE_PERFORMANCE_TRACE_DIR` to capture the renderer's CDP trace from attachment through actionable Home:

```sh
DESKTOP_STARTUP_RUNS=1 OPENCODE_PERFORMANCE_TRACE_DIR=/tmp/opencode-desktop-traces bun run bench:devex
```

PowerShell:

```powershell
Expand Down
4 changes: 2 additions & 2 deletions packages/app/e2e/performance/chrome-trace.ts
Original file line number Diff line number Diff line change
Expand Up @@ -18,9 +18,9 @@ const categories = [
"disabled-by-default-v8.cpu_profiler",
]

export async function startChromeTrace(page: Page, name: string) {
export async function startChromeTrace(page: Page, name: string): Promise<undefined | (() => Promise<string>)> {
const directory = process.env.OPENCODE_PERFORMANCE_TRACE_DIR
if (!directory) return
if (!directory) return undefined

const selectors = process.env.OPENCODE_PERFORMANCE_SELECTOR_TRACE === "1"
const file = await prepareChromeTrace(directory, name, selectors)
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
import { benchmark } from "../benchmark"
import {
desktopBenchmarkContext,
runDesktopStartup,
summarizeDesktopStartup,
type DesktopStartupSample,
} from "./desktop-startup"

benchmark.describe("devex: desktop startup", () => {
benchmark("opens a cold desktop on Home", async ({ report }, testInfo) => {
benchmark.setTimeout(15 * 60_000)
const runs = Number(process.env.DESKTOP_STARTUP_RUNS ?? 5)
if (!Number.isSafeInteger(runs) || runs < 1) throw new Error("DESKTOP_STARTUP_RUNS must be a positive integer")

const samples: DesktopStartupSample[] = []
const context = await desktopBenchmarkContext(runs)
for (let run = 1; run <= runs; run++) {
const sample = await runDesktopStartup(run, testInfo).catch((error) => {
report(samples.length ? { samples, summary: summarizeDesktopStartup(samples) } : { samples }, context)
throw error
})
samples.push(sample)
}
report({ samples, summary: summarizeDesktopStartup(samples) }, context)
})
})
Loading
Loading