Skip to content

Commit 3666845

Browse files
committed
Merge branch 'opencode-mirror' into fork/local
2 parents 2c1254d + c769380 commit 3666845

227 files changed

Lines changed: 11259 additions & 1287 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/TEAM_MEMBERS

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
adamdotdevin
2+
arvsrn
23
Brendonovich
34
fwang
45
Hona
@@ -7,11 +8,14 @@ jayair
78
jlongster
89
kitlangton
910
kommander
11+
ludvigrask
1012
MrMushrooooom
1113
nexxeln
1214
R44VC0RP
1315
rekram1-node
1416
thdxr
1517
simonklee
18+
Slickstef11
19+
usrnk1
1620
vimtor
1721
starptech

bun.lock

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

infra/stats.ts

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -185,7 +185,9 @@ export const statSync = new sst.aws.Service("StatsSyncService", {
185185
cluster: lakeCluster,
186186
architecture: "arm64",
187187
cpu: "0.25 vCPU",
188-
memory: "0.5 GB",
188+
// 0.5 GB caused an OOM crash loop: every restart immediately re-ran the 4 Athena
189+
// stats queries (~$5/pass) every ~5 minutes instead of hourly.
190+
memory: "2 GB",
189191
image: {
190192
context: ".",
191193
dockerfile: "packages/stats/server/Dockerfile",

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-KTyd2ISQ4n1E3tm1LMEHtz+rKRZga+SONn5J6H0pheQ=",
4-
"aarch64-linux": "sha256-ZIeaaqRr4JorEmmwFYuitxfYEAtrP8C6IlD+pmFRko0=",
5-
"aarch64-darwin": "sha256-Po8FISoBzUMwJSn6nw243/hLT/gAQCrm5HbwXe2uA0g=",
6-
"x86_64-darwin": "sha256-5TZzrCnvg1z00YP6O9U0SXjL04r+VmF7LVrqQ9BbSn4="
3+
"x86_64-linux": "sha256-JTtn+wXTXg+yklvIMDLcGFaYhTU6ZrCgKT9JTNEQ3gA=",
4+
"aarch64-linux": "sha256-gXU6zyhvAZrZirkL/PlHdkHtEof/7PVSPCaE34Jnd4U=",
5+
"aarch64-darwin": "sha256-Q0oTG3uzOlD/X2kJingLle529lKFoTpyCW2rHXOZ6iE=",
6+
"x86_64-darwin": "sha256-LINvKHxPibTlJeNzfACQx0x+Yj5oROT6Du3I5AtqqXk="
77
}
88
}

package.json

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@
1919
"prepare": "husky",
2020
"random": "echo 'Random script'",
2121
"sso": "aws sso login --sso-session=opencode --no-browser",
22+
"translate:app": "bun run script/translate-app.ts",
2223
"test": "echo 'do not run tests from root' && exit 1"
2324
},
2425
"workspaces": {
@@ -46,6 +47,7 @@
4647
"@shikijs/stream": "4.2.0",
4748
"ulid": "3.0.1",
4849
"@kobalte/core": "0.13.11",
50+
"@corvu/drawer": "0.2.4",
4951
"@types/luxon": "3.7.1",
5052
"@types/node": "24.12.2",
5153
"@types/semver": "7.7.1",
@@ -146,7 +148,7 @@
146148
"@silvia-odwyer/photon-node@0.3.4": "patches/@silvia-odwyer%2Fphoton-node@0.3.4.patch",
147149
"@standard-community/standard-openapi@0.2.9": "patches/@standard-community%2Fstandard-openapi@0.2.9.patch",
148150
"solid-js@1.9.10": "patches/solid-js@1.9.10.patch",
149-
"@ai-sdk/xai@3.0.82": "patches/@ai-sdk%2Fxai@3.0.82.patch",
151+
"@ai-sdk/xai@3.0.102": "patches/@ai-sdk%2Fxai@3.0.102.patch",
150152
"gcp-metadata@8.1.2": "patches/gcp-metadata@8.1.2.patch",
151153
"pacote@21.5.0": "patches/pacote@21.5.0.patch",
152154
"@ai-sdk/google@3.0.73": "patches/@ai-sdk%2Fgoogle@3.0.73.patch",
Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
import { expect, test } from "@playwright/test"
2+
import { base64Encode } from "@opencode-ai/core/util/encode"
3+
import { mockOpenCodeServer } from "../utils/mock-server"
4+
5+
const draftID = "draft_legacy_new_session"
6+
const directory = "C:/OpenCode/LegacyNewSession"
7+
const server = `http://${process.env.PLAYWRIGHT_SERVER_HOST ?? "127.0.0.1"}:${process.env.PLAYWRIGHT_SERVER_PORT ?? "4096"}`
8+
9+
test("redirects a draft to the legacy new-session route", async ({ page }) => {
10+
await mockOpenCodeServer(page, {
11+
directory,
12+
project: {
13+
id: "proj_legacy_new_session",
14+
worktree: directory,
15+
vcs: "git",
16+
name: "legacy-new-session",
17+
time: { created: 1700000000000, updated: 1700000000000 },
18+
sandboxes: [],
19+
},
20+
provider: { all: [], connected: [], default: {} },
21+
sessions: [],
22+
pageMessages: () => ({ items: [] }),
23+
})
24+
await page.addInitScript(
25+
({ directory, draftID, server }) => {
26+
localStorage.setItem("settings.v3", JSON.stringify({ general: { newLayoutDesigns: false } }))
27+
localStorage.setItem(
28+
"opencode.window.browser.dat:tabs",
29+
JSON.stringify([{ type: "draft", draftID, server, directory }]),
30+
)
31+
},
32+
{ directory, draftID, server },
33+
)
34+
35+
await page.goto(`/new-session?draftId=${draftID}`)
36+
37+
await expect(page).toHaveURL(`/${base64Encode(directory)}/session`)
38+
await expect(page.locator("header[data-tauri-drag-region]")).toBeVisible()
39+
await expect(page.locator('[data-component="prompt-input"]')).toBeVisible()
40+
})
Lines changed: 155 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,155 @@
1+
import { base64Encode } from "@opencode-ai/core/util/encode"
2+
import { expect, test } from "@playwright/test"
3+
import { mockOpenCodeServer } from "../utils/mock-server"
4+
import { expectSessionTitle } from "../utils/waits"
5+
6+
const directory = "C:/OpenCode/ReviewOpenFile"
7+
const projectID = "proj_review_open_file"
8+
const sessionID = "ses_review_open_file"
9+
const title = "Review open file"
10+
const server = `http://${process.env.PLAYWRIGHT_SERVER_HOST ?? "127.0.0.1"}:${process.env.PLAYWRIGHT_SERVER_PORT ?? "4096"}`
11+
12+
test.use({ viewport: { width: 1440, height: 900 } })
13+
14+
test("opens and searches project files inline", async ({ page }) => {
15+
const searches: { query: string; dirs?: string; limit?: number }[] = []
16+
await mockOpenCodeServer(page, {
17+
directory,
18+
project: {
19+
id: projectID,
20+
worktree: directory,
21+
vcs: "git",
22+
name: "open-file-project",
23+
time: { created: 1700000000000, updated: 1700000000000 },
24+
sandboxes: [],
25+
},
26+
provider: {
27+
all: [
28+
{
29+
id: "opencode",
30+
name: "OpenCode",
31+
models: { test: { id: "test", name: "Test", limit: { context: 200_000 } } },
32+
},
33+
],
34+
connected: ["opencode"],
35+
default: { providerID: "opencode", modelID: "test" },
36+
},
37+
sessions: [
38+
{
39+
id: sessionID,
40+
slug: sessionID,
41+
projectID,
42+
directory,
43+
title,
44+
version: "dev",
45+
time: { created: 1700000000000, updated: 1700000000000 },
46+
},
47+
],
48+
vcsDiff: [fileDiff("src/changed.ts")],
49+
fileList: (path) => {
50+
if (path) return []
51+
return [
52+
fileNode("README.md"),
53+
{ name: "src", path: "src", absolute: `${directory}/src`, type: "directory", ignored: false },
54+
]
55+
},
56+
fileContent: (path) => ({ type: "text", content: `contents:${path}` }),
57+
findFiles: (input) => {
58+
searches.push(input)
59+
return input.query === "nested" ? ["src/nested.ts"] : []
60+
},
61+
pageMessages: () => ({ items: [] }),
62+
})
63+
await page.addInitScript(
64+
({ directory, server, sessionID }) => {
65+
localStorage.setItem("settings.v3", JSON.stringify({ general: { newLayoutDesigns: true } }))
66+
localStorage.setItem(
67+
"opencode.global.dat:server",
68+
JSON.stringify({
69+
projects: { local: [{ worktree: directory, expanded: true }] },
70+
lastProject: { local: directory },
71+
}),
72+
)
73+
localStorage.setItem(
74+
"opencode.global.dat:layout",
75+
JSON.stringify({ review: { diffStyle: "split", panelOpened: true } }),
76+
)
77+
localStorage.setItem(
78+
"opencode.global.dat:review-panel-v2",
79+
JSON.stringify({ sidebarOpened: false, sidebarWidth: 240, expandMode: "collapse" }),
80+
)
81+
localStorage.setItem(
82+
"opencode.window.browser.dat:tabs",
83+
JSON.stringify([{ type: "session", server, sessionId: sessionID }]),
84+
)
85+
},
86+
{ directory, server, sessionID },
87+
)
88+
89+
await page.goto(`/server/${base64Encode(server)}/session/${sessionID}`)
90+
await expectSessionTitle(page, title)
91+
92+
const panel = page.locator("#review-panel")
93+
const sidebar = panel.locator('[data-slot="session-review-v2-sidebar"]')
94+
const contextButton = page.getByRole("button", { name: "View context usage" })
95+
await contextButton.click()
96+
await expect(panel.getByRole("tab", { name: "Context" })).toHaveAttribute("data-selected", "")
97+
await panel.getByRole("button", { name: "Open file" }).click()
98+
await expect(panel.getByRole("tab", { name: "Open file" })).toHaveAttribute("data-selected", "")
99+
await expect(sidebar).toBeVisible()
100+
await contextButton.click()
101+
await expect(panel.getByRole("tab", { name: "Context" })).toHaveAttribute("data-selected", "")
102+
await expect(sidebar).toHaveCount(0)
103+
await panel.getByRole("button", { name: "Open file" }).click()
104+
const filter = panel.getByRole("combobox", { name: "Filter files" })
105+
await expect(filter).toBeFocused()
106+
await expect(panel.getByRole("tab", { name: "Open file" })).toHaveAttribute("data-selected", "")
107+
await expect(panel.getByText("open-file-project", { exact: true })).toBeVisible()
108+
109+
await panel.getByRole("button", { name: "README.md" }).click()
110+
await expect(panel.getByRole("tab", { name: "README.md" })).toHaveAttribute("data-selected", "")
111+
await expect(panel.getByText("contents:README.md", { exact: true })).toBeVisible()
112+
await expect(sidebar).toHaveCount(0)
113+
114+
await panel.getByRole("button", { name: "Open file" }).click()
115+
await expect(panel.getByRole("tab", { name: "README.md" })).toHaveCount(0)
116+
await expect(sidebar).toBeVisible()
117+
await filter.fill("nested")
118+
const result = panel.getByRole("option", { name: /nested\.ts/ })
119+
await expect(result).toBeVisible()
120+
const resultID = await result.getAttribute("id")
121+
expect(resultID).toBeTruthy()
122+
await expect(filter).toHaveAttribute("aria-activedescendant", resultID!)
123+
await filter.press("Enter")
124+
await expect(panel.getByRole("tab", { name: "nested.ts" })).toHaveAttribute("data-selected", "")
125+
await expect(panel.getByText("contents:src/nested.ts", { exact: true })).toBeVisible()
126+
expect(searches).toContainEqual({ query: "nested", dirs: "false", limit: 200 })
127+
128+
await panel.getByRole("button", { name: "Open file" }).click()
129+
await expect(panel.getByRole("tab", { name: "nested.ts" })).toHaveCount(1)
130+
await expect(panel.getByRole("tab", { name: "Open file" })).toHaveAttribute("data-selected", "")
131+
await page.keyboard.press("Control+w")
132+
await expect(panel.getByRole("tab", { name: "Open file" })).toHaveCount(0)
133+
await expect(panel.getByRole("tab", { name: "nested.ts" })).toHaveAttribute("data-selected", "")
134+
})
135+
136+
function fileNode(path: string) {
137+
return {
138+
name: path,
139+
path,
140+
absolute: `${directory}/${path}`,
141+
type: "file",
142+
ignored: false,
143+
}
144+
}
145+
146+
function fileDiff(file: string) {
147+
return {
148+
file,
149+
before: "before\n",
150+
after: "after\n",
151+
additions: 1,
152+
deletions: 1,
153+
status: "modified",
154+
}
155+
}

0 commit comments

Comments
 (0)