Skip to content

Commit 4a8f40f

Browse files
authored
Merge branch 'dev' into fix/billing-refund-amount
2 parents 9f00c8f + 86907e2 commit 4a8f40f

433 files changed

Lines changed: 21565 additions & 11593 deletions

File tree

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

.github/workflows/deploy.yml

Lines changed: 0 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -21,15 +21,6 @@ jobs:
2121
with:
2222
node-version: "24"
2323

24-
# Workaround for Pulumi version conflict:
25-
# GitHub runners have Pulumi 3.212.0+ pre-installed, which removed the -root flag
26-
# from pulumi-language-nodejs (see https://github.com/pulumi/pulumi/pull/21065).
27-
# SST 3.17.x uses Pulumi SDK 3.210.0 which still passes -root, causing a conflict.
28-
# Removing the system language plugin forces SST to use its bundled compatible version.
29-
# TODO: Remove when sst supports Pulumi >3.210.0
30-
- name: Fix Pulumi version conflict
31-
run: sudo rm -f /usr/local/bin/pulumi-language-nodejs
32-
3324
- run: bun sst deploy --stage=${{ github.ref_name }}
3425
env:
3526
CLOUDFLARE_API_TOKEN: ${{ secrets.CLOUDFLARE_API_TOKEN }}

AGENTS.md

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,14 @@
44
- Local `main` ref may not exist; use `dev` or `origin/dev` for diffs.
55
- Prefer automation: execute requested actions without confirmation unless blocked by missing info or safety/irreversibility.
66

7+
## Commits and PR Titles
8+
9+
Use conventional commit-style messages and PR titles: `type(scope): summary`.
10+
11+
Valid types are `feat`, `fix`, `docs`, `chore`, `refactor`, and `test`. Scopes are optional; use the affected package or area when helpful, e.g. `core`, `opencode`, `tui`, `app`, `desktop`, `sdk`, or `plugin`.
12+
13+
Examples: `fix(tui): simplify thinking toggle styling`, `docs: update contributing guide`, `chore(sdk): regenerate types`.
14+
715
## Style Guide
816

917
### General Principles

bun.lock

Lines changed: 166 additions & 155 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

infra/console.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -278,6 +278,7 @@ new sst.cloudflare.x.SolidStart("Console", {
278278
//VITE_API_URL: gateway.url.apply((url) => url!),
279279
VITE_AUTH_URL: auth.url.apply((url) => url!),
280280
VITE_STRIPE_PUBLISHABLE_KEY: STRIPE_PUBLISHABLE_KEY.value,
281+
PLACEHOLDER: "keepalive",
281282
},
282283
transform: {
283284
server: {

infra/monitoring.ts

Lines changed: 11 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ import { domain } from "./stage"
44
const description = "Managed by SST (Don't edit in Honeycomb UI)"
55
const alertsDisabled = $app.stage !== "production"
66

7-
const webhookRecipient = new honeycomb.WebhookRecipient("DiscordAlerts", {
7+
const webhookRecipient = new honeycombio.WebhookRecipient("DiscordAlerts", {
88
name: $app.stage === "production" ? "Discord Alerts" : `Discord Alerts (${$app.stage})`,
99
url: `https://${domain}/honeycomb/webhook`,
1010
secret: SECRET.HoneycombWebhookSecret.result,
@@ -67,7 +67,7 @@ IF(
6767
)`,
6868
})
6969

70-
return honeycomb.getQuerySpecificationOutput({
70+
return honeycombio.getQuerySpecificationOutput({
7171
breakdowns: ["model"],
7272
calculatedFields: [failedHttpStatus],
7373
calculations: [
@@ -99,7 +99,7 @@ const providerHttpErrorsQuery = () => {
9999
expression: `IF(GT($llm.error.code, "400"), 1, 0)`,
100100
})
101101

102-
return honeycomb.getQuerySpecificationOutput({
102+
return honeycombio.getQuerySpecificationOutput({
103103
breakdowns: ["provider"],
104104
calculatedFields: [successHttpStatus, failedProviderHttpStatus],
105105
calculations: [
@@ -140,7 +140,7 @@ const modelLowTpsQuery = (product: "go" | "zen") => {
140140
{ column: "tps.output", op: "exists" },
141141
]
142142

143-
return honeycomb.getQuerySpecificationOutput({
143+
return honeycombio.getQuerySpecificationOutput({
144144
breakdowns: ["model"],
145145
calculations: [
146146
{ op: "COUNT", name: "TOTAL", filterCombination: "AND", filters },
@@ -157,7 +157,7 @@ const modelLowTpsQuery = (product: "go" | "zen") => {
157157
}).json
158158
}
159159

160-
new honeycomb.Trigger("IncreasedModelHttpErrorsGo", {
160+
new honeycombio.Trigger("IncreasedModelHttpErrorsGo", {
161161
name: "Increased Model HTTP Errors [Go]",
162162
description,
163163
disabled: alertsDisabled,
@@ -177,7 +177,7 @@ new honeycomb.Trigger("IncreasedModelHttpErrorsGo", {
177177
],
178178
})
179179

180-
new honeycomb.Trigger("IncreasedModelHttpErrorsZen", {
180+
new honeycombio.Trigger("IncreasedModelHttpErrorsZen", {
181181
name: "Increased Model HTTP Errors [Zen]",
182182
description,
183183
disabled: alertsDisabled,
@@ -197,7 +197,7 @@ new honeycomb.Trigger("IncreasedModelHttpErrorsZen", {
197197
],
198198
})
199199

200-
new honeycomb.Trigger("LowModelTpsGo", {
200+
new honeycombio.Trigger("LowModelTpsGo", {
201201
name: "Low Model TPS [Go]",
202202
description,
203203
disabled: alertsDisabled,
@@ -217,7 +217,7 @@ new honeycomb.Trigger("LowModelTpsGo", {
217217
],
218218
})
219219

220-
new honeycomb.Trigger("LowModelTpsZen", {
220+
new honeycombio.Trigger("LowModelTpsZen", {
221221
name: "Low Model TPS [Zen]",
222222
description,
223223
disabled: alertsDisabled,
@@ -237,7 +237,7 @@ new honeycomb.Trigger("LowModelTpsZen", {
237237
],
238238
})
239239

240-
new honeycomb.Trigger("IncreasedProviderHttpErrors", {
240+
new honeycombio.Trigger("IncreasedProviderHttpErrors", {
241241
name: "Increased Provider HTTP Errors",
242242
description,
243243
disabled: alertsDisabled,
@@ -257,11 +257,11 @@ new honeycomb.Trigger("IncreasedProviderHttpErrors", {
257257
],
258258
})
259259

260-
new honeycomb.Trigger("IncreasedFreeTierRequests", {
260+
new honeycombio.Trigger("IncreasedFreeTierRequests", {
261261
name: "Increased Free Tier Requests",
262262
description,
263263
disabled: alertsDisabled,
264-
queryJson: honeycomb.getQuerySpecificationOutput({
264+
queryJson: honeycombio.getQuerySpecificationOutput({
265265
calculations: [{ op: "COUNT" }],
266266
filters: [
267267
{ column: "event_type", op: "=", value: "completions" },

nix/hashes.json

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,8 @@
11
{
22
"nodeModules": {
3-
"x86_64-linux": "sha256-FI1mX42vJuYdUDdWevlfHz+OcYkDn/I/HUbHE/jdQvs=",
4-
"aarch64-linux": "sha256-3CQzzKnh/4Zf5vyn56yR5P3ULsW7K7Fr8/RQpekEJDk=",
5-
"aarch64-darwin": "sha256-XPDVHMxlPpXlf43BRqNnwF809unk6iE8tvd0o92d0/w=",
6-
"x86_64-darwin": "sha256-dFXTi13RSgL62lMsep1EoE/KSEPF7Oh31PVdxW1tkzg="
3+
"x86_64-linux": "sha256-1RiaZQHzIhdtcOJUMsLagpP+nBBL/Qu6zQgrAXMHDCI=",
4+
"aarch64-linux": "sha256-5QZhtkWuNpY/qUxlKRHcGbILOAVnuyzu+h8VDIuMQcU=",
5+
"aarch64-darwin": "sha256-9w3QA22XNc1itGLyhikYU90xGH/iLUUM+SSGXla7lhw=",
6+
"x86_64-darwin": "sha256-cSYiyhhSqIYiTeK1uWHDkHbYstQYD5jEB7JaYjWjgi4="
77
}
88
}

package.json

Lines changed: 12 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -28,16 +28,17 @@
2828
"packages/slack"
2929
],
3030
"catalog": {
31-
"@effect/opentelemetry": "4.0.0-beta.65",
32-
"@effect/platform-node": "4.0.0-beta.65",
31+
"@effect/opentelemetry": "4.0.0-beta.66",
32+
"@effect/platform-node": "4.0.0-beta.66",
33+
"@effect/sql-sqlite-bun": "4.0.0-beta.66",
3334
"@npmcli/arborist": "9.4.0",
3435
"@types/bun": "1.3.13",
3536
"@types/cross-spawn": "6.0.6",
3637
"@octokit/rest": "22.0.0",
3738
"@hono/zod-validator": "0.4.2",
38-
"@opentui/core": "0.2.14",
39-
"@opentui/keymap": "0.2.14",
40-
"@opentui/solid": "0.2.14",
39+
"@opentui/core": "0.2.15",
40+
"@opentui/keymap": "0.2.15",
41+
"@opentui/solid": "0.2.15",
4142
"ulid": "3.0.1",
4243
"@kobalte/core": "0.13.11",
4344
"@types/luxon": "3.7.1",
@@ -53,9 +54,9 @@
5354
"@tailwindcss/vite": "4.1.11",
5455
"diff": "8.0.2",
5556
"dompurify": "3.3.1",
56-
"drizzle-kit": "1.0.0-beta.19-d95b7a4",
57-
"drizzle-orm": "1.0.0-beta.19-d95b7a4",
58-
"effect": "4.0.0-beta.65",
57+
"drizzle-kit": "1.0.0-rc.2",
58+
"drizzle-orm": "1.0.0-rc.2",
59+
"effect": "4.0.0-beta.66",
5960
"ai": "6.0.168",
6061
"cross-spawn": "7.0.6",
6162
"hono": "4.10.7",
@@ -97,7 +98,7 @@
9798
"oxlint-tsgolint": "0.21.0",
9899
"prettier": "3.6.2",
99100
"semver": "^7.6.0",
100-
"sst": "3.18.10",
101+
"sst": "4.13.1",
101102
"turbo": "2.8.13"
102103
},
103104
"dependencies": {
@@ -138,6 +139,7 @@
138139
"@npmcli/agent@4.0.0": "patches/@npmcli%2Fagent@4.0.0.patch",
139140
"@silvia-odwyer/photon-node@0.3.4": "patches/@silvia-odwyer%2Fphoton-node@0.3.4.patch",
140141
"@standard-community/standard-openapi@0.2.9": "patches/@standard-community%2Fstandard-openapi@0.2.9.patch",
141-
"solid-js@1.9.10": "patches/solid-js@1.9.10.patch"
142+
"solid-js@1.9.10": "patches/solid-js@1.9.10.patch",
143+
"@ai-sdk/xai@3.0.82": "patches/@ai-sdk%2Fxai@3.0.82.patch"
142144
}
143145
}

packages/app/e2e/smoke/session-timeline.spec.ts

Lines changed: 33 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
import { expect, test, type Page } from "@playwright/test"
2+
import { base64Encode } from "@opencode-ai/core/util/encode"
23
import { fixture, pageMessages } from "./session-timeline.fixture"
34
import { trackPageErrors, expectNoSmokeErrors } from "../utils/errors"
45
import { mockOpenCodeServer } from "../utils/mock-server"
@@ -37,20 +38,20 @@ test.describe("smoke: session timeline", () => {
3738
project: fixture.project,
3839
pageMessages,
3940
})
40-
await configureSmokePage(page)
41+
await configureSmokePage(page, fixture.directory)
4142

42-
await openProject(page, "SmokeProject")
43-
await navigateToSession(page, fixture.sourceID, fixture.expected.sourceTitle)
44-
await expectSessionReady(page, "smoke-project")
45-
await navigateToSession(page, fixture.targetID, fixture.expected.targetTitle)
43+
await selectHomeProject(page, fixture.project.name)
44+
await navigateToSession(page, fixture.directory, fixture.sourceID, fixture.expected.sourceTitle)
45+
await expectSessionReady(page)
46+
await navigateToSession(page, fixture.directory, fixture.targetID, fixture.expected.targetTitle)
4647
const expectedPartIDs = fixture.expected.targetPartIDs
4748
const expectedMessageIDs = fixture.expected.targetMessageIDs
4849
await expectSessionTimelineReady(page, expectedPartIDs, expectedMessageIDs, errors)
4950
await expectCanScrollToStart(page, expectedPartIDs, expectedMessageIDs, errors)
5051
})
5152
})
5253

53-
async function configureSmokePage(page: Page) {
54+
async function configureSmokePage(page: Page, directory: string) {
5455
await page.addInitScript(() => {
5556
localStorage.setItem(
5657
"settings.v3",
@@ -63,7 +64,23 @@ async function configureSmokePage(page: Page) {
6364
},
6465
}),
6566
)
67+
})
6668

69+
await page.addInitScript((directory) => {
70+
localStorage.setItem(
71+
"opencode.global.dat:server",
72+
JSON.stringify({
73+
projects: {
74+
local: [{ worktree: directory, expanded: true }],
75+
},
76+
lastProject: {
77+
local: directory,
78+
},
79+
}),
80+
)
81+
}, directory)
82+
83+
await page.addInitScript(() => {
6784
const smoke = window as SmokeWindow
6885
smoke.__timelineSmokeErrorToasts = []
6986
smoke.__timelineSmokeForbiddenText = []
@@ -392,21 +409,20 @@ function expectCompleteScroll(
392409
expect(expectedPartIDs.length).toBe(331)
393410
}
394411

395-
async function openProject(page: Page, projectName: string) {
412+
async function selectHomeProject(page: Page, projectName: string) {
396413
await page.goto("/")
397-
await page.getByRole("button", { name: new RegExp(projectName, "i") }).click()
414+
await page
415+
.locator('[data-component="home-project-row"]')
416+
.filter({ hasText: new RegExp(projectName, "i") })
417+
.click()
418+
await expect(page).toHaveURL(/\/$/)
398419
}
399420

400-
async function navigateToSession(page: Page, sessionId: string, expectedTitle: string) {
401-
// Use evaluate to click to avoid strict visibility/animation issues during rapid e2e navigation
402-
await page
403-
.locator(`a[href*="${sessionId}"]`)
404-
.first()
405-
.evaluate((el) => (el as HTMLElement).click())
421+
async function navigateToSession(page: Page, directory: string, sessionId: string, expectedTitle: string) {
422+
await page.goto(`/${base64Encode(directory)}/session/${sessionId}`)
406423
await expect(page.getByRole("heading", { name: expectedTitle })).toBeVisible()
407424
}
408425

409-
async function expectSessionReady(page: Page, projectName: string) {
410-
await expect(page.getByText(projectName).first()).toBeVisible()
411-
await expect(page.getByText("Ask anything...")).toBeVisible()
426+
async function expectSessionReady(page: Page) {
427+
await expect(page.getByRole("textbox", { name: /Ask anything/i })).toBeVisible()
412428
}

packages/app/package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "@opencode-ai/app",
3-
"version": "1.15.5",
3+
"version": "1.15.7",
44
"description": "",
55
"type": "module",
66
"exports": {

packages/app/src/app.tsx

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -78,6 +78,7 @@ declare global {
7878
}
7979
api?: {
8080
setTitlebar?: (theme: { mode: "light" | "dark" }) => Promise<void>
81+
exportDebugLogs?: () => Promise<string>
8182
}
8283
}
8384
}

0 commit comments

Comments
 (0)