Skip to content

Commit fe67e60

Browse files
Merge branch 'dev' into fix-post-install-instruction-ask-user
2 parents 97f5c1d + 6bee6ee commit fe67e60

435 files changed

Lines changed: 27287 additions & 9936 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.

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: 66 additions & 43 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

infra/monitoring.ts

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ 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

67
const webhookRecipient = new honeycomb.WebhookRecipient("DiscordAlerts", {
78
name: $app.stage === "production" ? "Discord Alerts" : `Discord Alerts (${$app.stage})`,
@@ -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
}
@@ -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
@@ -159,6 +160,7 @@ const modelLowTpsQuery = (product: "go" | "zen") => {
159160
new honeycomb.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,
@@ -178,6 +180,7 @@ new honeycomb.Trigger("IncreasedModelHttpErrorsGo", {
178180
new honeycomb.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,
@@ -197,6 +200,7 @@ new honeycomb.Trigger("IncreasedModelHttpErrorsZen", {
197200
new honeycomb.Trigger("LowModelTpsGo", {
198201
name: "Low Model TPS [Go]",
199202
description,
203+
disabled: alertsDisabled,
200204
queryJson: modelLowTpsQuery("go"),
201205
alertType: "on_change",
202206
frequency: 600,
@@ -216,6 +220,7 @@ new honeycomb.Trigger("LowModelTpsGo", {
216220
new honeycomb.Trigger("LowModelTpsZen", {
217221
name: "Low Model TPS [Zen]",
218222
description,
223+
disabled: alertsDisabled,
219224
queryJson: modelLowTpsQuery("zen"),
220225
alertType: "on_change",
221226
frequency: 600,
@@ -235,6 +240,7 @@ new honeycomb.Trigger("LowModelTpsZen", {
235240
new honeycomb.Trigger("IncreasedProviderHttpErrors", {
236241
name: "Increased Provider HTTP Errors",
237242
description,
243+
disabled: alertsDisabled,
238244
queryJson: providerHttpErrorsQuery(),
239245
alertType: "on_change",
240246
frequency: 300,
@@ -254,6 +260,7 @@ new honeycomb.Trigger("IncreasedProviderHttpErrors", {
254260
new honeycomb.Trigger("IncreasedFreeTierRequests", {
255261
name: "Increased Free Tier Requests",
256262
description,
263+
disabled: alertsDisabled,
257264
queryJson: honeycomb.getQuerySpecificationOutput({
258265
calculations: [{ op: "COUNT" }],
259266
filters: [

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-hIarzU3QNIvkwpfnearfsGaBMCSdovkOWAuvX+EBQI8=",
4+
"aarch64-linux": "sha256-qu+86RNsBZhqzE3CEyg4XHD/3Czc/BqHhY3O1vyogtY=",
5+
"aarch64-darwin": "sha256-7sXZdPh/R4fQBBMq36YdpQE6G2ELMZd08BqMhHbhwv4=",
6+
"x86_64-darwin": "sha256-g5QWpX33R143sNR1G9m7UsSA3jygFyJjT7Kjyjo6sCc="
77
}
88
}

package.json

Lines changed: 11 additions & 9 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",
@@ -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.6",
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
}

packages/app/src/components/dialog-edit-project.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ import { type LocalProject, getAvatarColors } from "@/context/layout"
1212
import { getFilename } from "@opencode-ai/core/util/path"
1313
import { Avatar } from "@opencode-ai/ui/avatar"
1414
import { useLanguage } from "@/context/language"
15-
import { getProjectAvatarSource } from "@/pages/layout/sidebar-items"
15+
import { getProjectAvatarSource } from "@/pages/layout/helpers"
1616

1717
const AVATAR_COLOR_KEYS = ["pink", "mint", "orange", "purple", "cyan", "lime"] as const
1818

0 commit comments

Comments
 (0)