Skip to content

Commit 7323e1a

Browse files
authored
Merge branch 'dev' into console-email-change-self-service
2 parents 636c9b3 + 86907e2 commit 7323e1a

580 files changed

Lines changed: 41996 additions & 14112 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 }}

.opencode/tool/github-triage.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,8 +4,8 @@ import { tool } from "@opencode-ai/plugin"
44
const TEAM = {
55
tui: ["kommander", "simonklee"],
66
desktop_web: ["Hona", "Brendonovich"],
7-
core: ["jlongster", "rekram1-node", "nexxeln", "kitlangton"],
8-
inference: ["fwang", "MrMushrooooom"],
7+
core: ["jlongster", "rekram1-node", "nexxeln", "kitlangton", "starptech"],
8+
inference: ["fwang", "MrMushrooooom", "starptech"],
99
windows: ["Hona"],
1010
} as const
1111

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: 20 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -2,8 +2,9 @@ import { SECRET } from "./secret"
22
import { domain } from "./stage"
33

44
const description = "Managed by SST (Don't edit in Honeycomb UI)"
5+
const alertsDisabled = $app.stage !== "production"
56

6-
const webhookRecipient = new honeycomb.WebhookRecipient("DiscordAlerts", {
7+
const webhookRecipient = new honeycombio.WebhookRecipient("DiscordAlerts", {
78
name: $app.stage === "production" ? "Discord Alerts" : `Discord Alerts (${$app.stage})`,
89
url: `https://${domain}/honeycomb/webhook`,
910
secret: SECRET.HoneycombWebhookSecret.result,
@@ -66,7 +67,7 @@ IF(
6667
)`,
6768
})
6869

69-
return honeycomb.getQuerySpecificationOutput({
70+
return honeycombio.getQuerySpecificationOutput({
7071
breakdowns: ["model"],
7172
calculatedFields: [failedHttpStatus],
7273
calculations: [
@@ -79,7 +80,7 @@ IF(
7980
filters,
8081
},
8182
],
82-
formulas: [{ name: "ERROR", expression: "IF(GTE($TOTAL, 200), DIV($FAILED, $TOTAL), 0)" }],
83+
formulas: [{ name: "ERROR", expression: "IF(GTE($TOTAL, 150), DIV($FAILED, $TOTAL), 0)" }],
8384
timeRange: 900,
8485
}).json
8586
}
@@ -98,7 +99,7 @@ const providerHttpErrorsQuery = () => {
9899
expression: `IF(GT($llm.error.code, "400"), 1, 0)`,
99100
})
100101

101-
return honeycomb.getQuerySpecificationOutput({
102+
return honeycombio.getQuerySpecificationOutput({
102103
breakdowns: ["provider"],
103104
calculatedFields: [successHttpStatus, failedProviderHttpStatus],
104105
calculations: [
@@ -122,7 +123,7 @@ const providerHttpErrorsQuery = () => {
122123
},
123124
],
124125
formulas: [
125-
{ name: "ERROR", expression: "IF(GTE(SUM($SUCCESS, $FAILED), 200), DIV($FAILED, SUM($SUCCESS, $FAILED)), 0)" },
126+
{ name: "ERROR", expression: "IF(GTE(SUM($SUCCESS, $FAILED), 150), DIV($FAILED, SUM($SUCCESS, $FAILED)), 0)" },
126127
],
127128
timeRange: 900,
128129
}).json
@@ -139,7 +140,7 @@ const modelLowTpsQuery = (product: "go" | "zen") => {
139140
{ column: "tps.output", op: "exists" },
140141
]
141142

142-
return honeycomb.getQuerySpecificationOutput({
143+
return honeycombio.getQuerySpecificationOutput({
143144
breakdowns: ["model"],
144145
calculations: [
145146
{ op: "COUNT", name: "TOTAL", filterCombination: "AND", filters },
@@ -156,9 +157,10 @@ const modelLowTpsQuery = (product: "go" | "zen") => {
156157
}).json
157158
}
158159

159-
new honeycomb.Trigger("IncreasedModelHttpErrorsGo", {
160+
new honeycombio.Trigger("IncreasedModelHttpErrorsGo", {
160161
name: "Increased Model HTTP Errors [Go]",
161162
description,
163+
disabled: alertsDisabled,
162164
queryJson: modelHttpErrorsQuery("go"),
163165
alertType: "on_change",
164166
frequency: 300,
@@ -175,9 +177,10 @@ new honeycomb.Trigger("IncreasedModelHttpErrorsGo", {
175177
],
176178
})
177179

178-
new honeycomb.Trigger("IncreasedModelHttpErrorsZen", {
180+
new honeycombio.Trigger("IncreasedModelHttpErrorsZen", {
179181
name: "Increased Model HTTP Errors [Zen]",
180182
description,
183+
disabled: alertsDisabled,
181184
queryJson: modelHttpErrorsQuery("zen"),
182185
alertType: "on_change",
183186
frequency: 300,
@@ -194,9 +197,10 @@ new honeycomb.Trigger("IncreasedModelHttpErrorsZen", {
194197
],
195198
})
196199

197-
new honeycomb.Trigger("LowModelTpsGo", {
200+
new honeycombio.Trigger("LowModelTpsGo", {
198201
name: "Low Model TPS [Go]",
199202
description,
203+
disabled: alertsDisabled,
200204
queryJson: modelLowTpsQuery("go"),
201205
alertType: "on_change",
202206
frequency: 600,
@@ -213,9 +217,10 @@ new honeycomb.Trigger("LowModelTpsGo", {
213217
],
214218
})
215219

216-
new honeycomb.Trigger("LowModelTpsZen", {
220+
new honeycombio.Trigger("LowModelTpsZen", {
217221
name: "Low Model TPS [Zen]",
218222
description,
223+
disabled: alertsDisabled,
219224
queryJson: modelLowTpsQuery("zen"),
220225
alertType: "on_change",
221226
frequency: 600,
@@ -232,9 +237,10 @@ new honeycomb.Trigger("LowModelTpsZen", {
232237
],
233238
})
234239

235-
new honeycomb.Trigger("IncreasedProviderHttpErrors", {
240+
new honeycombio.Trigger("IncreasedProviderHttpErrors", {
236241
name: "Increased Provider HTTP Errors",
237242
description,
243+
disabled: alertsDisabled,
238244
queryJson: providerHttpErrorsQuery(),
239245
alertType: "on_change",
240246
frequency: 300,
@@ -251,10 +257,11 @@ new honeycomb.Trigger("IncreasedProviderHttpErrors", {
251257
],
252258
})
253259

254-
new honeycomb.Trigger("IncreasedFreeTierRequests", {
260+
new honeycombio.Trigger("IncreasedFreeTierRequests", {
255261
name: "Increased Free Tier Requests",
256262
description,
257-
queryJson: honeycomb.getQuerySpecificationOutput({
263+
disabled: alertsDisabled,
264+
queryJson: honeycombio.getQuerySpecificationOutput({
258265
calculations: [{ op: "COUNT" }],
259266
filters: [
260267
{ 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: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,11 @@
11
{
22
"name": "@opencode-ai/app",
3-
"version": "1.15.5",
3+
"version": "1.15.7",
44
"description": "",
55
"type": "module",
66
"exports": {
77
".": "./src/index.ts",
8+
"./desktop-menu": "./src/desktop-menu.ts",
89
"./vite": "./vite.js",
910
"./index.css": "./src/index.css"
1011
},

0 commit comments

Comments
 (0)