Skip to content

Commit 7e65272

Browse files
NicholasDominicirekram1-nodeopencode-agent[bot]jlongsterfwang
authored
Pr 41 (#42)
* fix: bump openrouter ai sdk pkg to fix openrouter issues (anomalyco#21242) * chore: update nix node_modules hashes * chore: remove ai-sdk/provider-utils patch and update pkg (anomalyco#21245) * chore: update nix node_modules hashes * chore: bump anthropic ai sdk pkg, delete patch (anomalyco#21247) * refactor(core): add full http proxy and change workspace adaptor interface (anomalyco#21239) * go: add mimo * feat: add --dangerously-skip-permissions flag to opencode run (anomalyco#21266) * chore: update nix node_modules hashes * feat(opencode): Add PDF attachment Drag and Drop (anomalyco#16926) Co-authored-by: Aiden Cline <[email protected]> Co-authored-by: Aiden Cline <[email protected]> * feat(app): show full names on composer attachment chips (anomalyco#21306) * style(app): redesign jump-to-bottom button per figma spec (anomalyco#21313) * Move auto-accept permissions to settings (anomalyco#21308) * go: support coupon * fix(opencode): keep user message variants scoped to model (anomalyco#21332) * chore: generate * chore: update web stats * feat(app): better subagent experience (anomalyco#20708) * refactor(core): support multiple event streams in worker and remove workspaces from plugin api (anomalyco#21348) * fix(tui): use sentence case for theme mode command palette items (anomalyco#21192) Co-authored-by: Aiden Cline <[email protected]> * fix: ensure the alibaba provider errors are retried (anomalyco#21355) * fix(opencode): improve console login transport errors (anomalyco#21350) * chore: generate * feat(tui): allow variant_list keybind for the "Switch model variant" command (anomalyco#21185) Co-authored-by: Aiden Cline <[email protected]> * test: disable GPG signing in test fixtures (anomalyco#20386) * fix(opencode): clear webfetch timeouts on failed fetches (anomalyco#21378) * feat(opencode): add OTLP observability support (anomalyco#21387) * zen: glm5.1 doc * zen: glm5.1 doc * go: glm5.1 * core: refactor tool system to remove agent context from initialization (anomalyco#21052) * refactor(snapshot): store unified patches in file diffs (anomalyco#21244) Co-authored-by: Adam <[email protected]> * chore: generate * release: v1.4.0 * chore: update nix node_modules hashes * fix(tui): simplify console org display (anomalyco#21339) Co-authored-by: opencode-agent[bot] <opencode-agent[bot]@users.noreply.github.com> * ui: fix sticky session diffs header (anomalyco#21486) * test: update webfetch test (anomalyco#21398) Co-authored-by: opencode-agent[bot] <opencode-agent[bot]@users.noreply.github.com> * fix: ensure that /providers list and shell endpoints are correctly typed in sdk and openapi schema (anomalyco#21543) * fix(app): patch tool diff rendering * fix(app): diff list normalization * fix: dont show invalid variants for BP (anomalyco#21555) * tweak: separate ModelsDev.Model and Config model schemas (anomalyco#21561) * refactor(effect): build task tool from agent services (anomalyco#21017) * fix(app): skip url password setting for same-origin server and web app (anomalyco#19923) * fix: propagate abort signal to inline read tool (anomalyco#21584) * refactor(effect): inline session processor interrupt cleanup (anomalyco#21593) * feat(llm): integrate GitLab DWS tool approval with permission system (anomalyco#19955) Co-authored-by: Aiden Cline <[email protected]> * chore: update nix node_modules hashes * fix(lsp): remove CMakeLists.txt and Makefile from clangd root markers (anomalyco#21466) * Remove CLI from electron app (anomalyco#17803) Co-authored-by: LukeParkerDev <[email protected]> * chore: generate * chore: update nix node_modules hashes * feat: add opencode go upsell modal when limits are hit (anomalyco#21583) Co-authored-by: Frank <[email protected]> * release: v1.4.1 * app: remove min loading duration (anomalyco#21655) * fix: preserve interrupted bash output in tool results (anomalyco#21598) * fix: preserve text part timing in session processor (anomalyco#21691) * refactor(effect): drop shell abort signals from runner (anomalyco#21599) * refactor: fix tool call state handling and clean up imports (anomalyco#21709) * release: v1.4.2 * feat(mcp): add OAuth redirect URI configuration for MCP servers (anomalyco#21385) Co-authored-by: Aiden Cline <[email protected]> * chore: generate * fix(tui): restore hidden session scrollbar default (anomalyco#20947) * feat: add support for fast modes for claude and gpt models (that support it) (anomalyco#21706) * opencode: lazy-load top-level CLI commands The CLI imports every top-level command before argument parsing has decided which handler will run. This makes simple invocations pay for the full command graph up front and slows down the default startup path. Parse the root argv first and load only the command module that matches the selected top-level command. Keep falling back to the default TUI path for non-command positionals, and preserve root help, version and completion handling * delete unused withALS method (anomalyco#21723) * Revert "opencode: lazy-load top-level CLI commands" (anomalyco#21726) * fix(effect): suspend agent default layer construction (anomalyco#21732) --------- Co-authored-by: Aiden Cline <[email protected]> Co-authored-by: opencode-agent[bot] <opencode-agent[bot]@users.noreply.github.com> Co-authored-by: James Long <[email protected]> Co-authored-by: Frank <[email protected]> Co-authored-by: gitpush-gitpaid <[email protected]> Co-authored-by: Aiden Cline <[email protected]> Co-authored-by: Shoubhit Dash <[email protected]> Co-authored-by: Dax <[email protected]> Co-authored-by: Adam <[email protected]> Co-authored-by: Ariane Emory <[email protected]> Co-authored-by: Kit Langton <[email protected]> Co-authored-by: Kyle Altendorf <[email protected]> Co-authored-by: opencode <[email protected]> Co-authored-by: Brendan Allan <[email protected]> Co-authored-by: OpeOginni <[email protected]> Co-authored-by: Vladimir Glafirov <[email protected]> Co-authored-by: Cho HyeonJong <[email protected]> Co-authored-by: LukeParkerDev <[email protected]> Co-authored-by: Aleksandr Lossenko <[email protected]> Co-authored-by: Simon Klee <[email protected]>
1 parent c22eead commit 7e65272

294 files changed

Lines changed: 67062 additions & 3836 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.

bun.lock

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

infra/console.ts

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -109,6 +109,12 @@ const zenLiteCouponFirstMonth50 = new stripe.Coupon("ZenLiteCouponFirstMonth50",
109109
appliesToProducts: [zenLiteProduct.id],
110110
duration: "once",
111111
})
112+
const zenLiteCouponFirstMonth100 = new stripe.Coupon("ZenLiteCouponFirstMonth100", {
113+
name: "First month 100% off",
114+
percentOff: 100,
115+
appliesToProducts: [zenLiteProduct.id],
116+
duration: "once",
117+
})
112118
const zenLitePrice = new stripe.Price("ZenLitePrice", {
113119
product: zenLiteProduct.id,
114120
currency: "usd",
@@ -124,6 +130,7 @@ const ZEN_LITE_PRICE = new sst.Linkable("ZEN_LITE_PRICE", {
124130
price: zenLitePrice.id,
125131
priceInr: 92900,
126132
firstMonth50Coupon: zenLiteCouponFirstMonth50.id,
133+
firstMonth100Coupon: zenLiteCouponFirstMonth100.id,
127134
},
128135
})
129136

@@ -229,6 +236,7 @@ new sst.cloudflare.x.SolidStart("Console", {
229236
SALESFORCE_INSTANCE_URL,
230237
ZEN_BLACK_PRICE,
231238
ZEN_LITE_PRICE,
239+
new sst.Secret("ZEN_LITE_COUPON_FIRST_MONTH_100_INVITEES"),
232240
new sst.Secret("ZEN_LIMITS"),
233241
new sst.Secret("ZEN_SESSION_SECRET"),
234242
...ZEN_MODELS,

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-weR6jLBRU54GpE7MCQODzOZH3vER2xOqLb4+Dh0ipYY=",
4-
"aarch64-linux": "sha256-NIcstlZn/w8gfrTSqcsEG7HoIjW73a+KKvyNrly8DZg=",
5-
"aarch64-darwin": "sha256-sAOgteyMcWVvJQE+TudCr2seJghwiTismGq9A1OmzZc=",
6-
"x86_64-darwin": "sha256-i7fmGHqKPuQLFT23B5LP78nRkUeIspykQfzvCvBY5EM="
3+
"x86_64-linux": "sha256-285KZ7rZLRoc6XqCZRHc25NE+mmpGh/BVeMpv8aPQtQ=",
4+
"aarch64-linux": "sha256-qIwmY4TP4CI7R7G6A5OMYRrorVNXjkg25tTtVpIHm2o=",
5+
"aarch64-darwin": "sha256-RwvnZQhdYZ0u7h7evyfxuPLHHX9eO/jXTAxIFc8B+IE=",
6+
"x86_64-darwin": "sha256-vVj40al+TEeMpbe5XG2GmJEpN+eQAvtr9W0T98l5PBE="
77
}
88
}

package.json

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -48,7 +48,7 @@
4848
"drizzle-kit": "1.0.0-beta.19-d95b7a4",
4949
"drizzle-orm": "1.0.0-beta.19-d95b7a4",
5050
"effect": "4.0.0-beta.43",
51-
"ai": "6.0.138",
51+
"ai": "6.0.149",
5252
"cross-spawn": "7.0.6",
5353
"hono": "4.10.7",
5454
"hono-openapi": "1.1.2",
@@ -71,7 +71,8 @@
7171
"@solidjs/router": "0.15.4",
7272
"@solidjs/start": "https://pkg.pr.new/@solidjs/start@dfb2020",
7373
"solid-js": "1.9.10",
74-
"vite-plugin-solid": "2.11.10"
74+
"vite-plugin-solid": "2.11.10",
75+
"@lydell/node-pty": "1.2.0-beta.10"
7576
}
7677
},
7778
"devDependencies": {
@@ -91,6 +92,7 @@
9192
"@opencode-ai/plugin": "workspace:*",
9293
"@opencode-ai/script": "workspace:*",
9394
"@opencode-ai/sdk": "workspace:*",
95+
"heap-snapshot-toolkit": "1.1.3",
9496
"typescript": "catalog:"
9597
},
9698
"repository": {
@@ -118,8 +120,6 @@
118120
},
119121
"patchedDependencies": {
120122
"@standard-community/[email protected]": "patches/@standard-community%[email protected]",
121-
122-
"@ai-sdk/[email protected]": "patches/@ai-sdk%[email protected]",
123-
"@ai-sdk/[email protected]": "patches/@ai-sdk%[email protected]"
123+
124124
}
125125
}

packages/app/e2e/actions.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -320,6 +320,7 @@ export async function createTestProject(input?: { serverUrl?: string }) {
320320
execSync("git init", { cwd: root, stdio: "ignore" })
321321
await fs.writeFile(path.join(root, ".git", "opencode"), id)
322322
execSync("git config core.fsmonitor false", { cwd: root, stdio: "ignore" })
323+
execSync("git config commit.gpgsign false", { cwd: root, stdio: "ignore" })
323324
execSync("git add -A", { cwd: root, stdio: "ignore" })
324325
execSync('git -c user.name="e2e" -c user.email="[email protected]" commit -m "init" --allow-empty', {
325326
cwd: root,

packages/app/e2e/prompt/prompt-shell.spec.ts

Lines changed: 9 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
import type { ToolPart } from "@opencode-ai/sdk/v2/client"
22
import { test, expect } from "../fixtures"
3-
import { withSession } from "../actions"
3+
import { closeDialog, openSettings, withSession } from "../actions"
44
import { promptModelSelector, promptSelector, promptVariantSelector } from "../selectors"
55

66
const isBash = (part: unknown): part is ToolPart => {
@@ -19,12 +19,15 @@ test("shell mode runs a command in the project directory", async ({ page, projec
1919
await withSession(project.sdk, `e2e shell ${Date.now()}`, async (session) => {
2020
project.trackSession(session.id)
2121
await project.gotoSession(session.id)
22-
const button = page.locator('[data-action="prompt-permissions"]').first()
23-
await expect(button).toBeVisible()
24-
if ((await button.getAttribute("aria-pressed")) !== "true") {
25-
await button.click()
26-
await expect(button).toHaveAttribute("aria-pressed", "true")
22+
const dialog = await openSettings(page)
23+
const toggle = dialog.locator('[data-action="settings-auto-accept-permissions"]').first()
24+
const input = toggle.locator('[data-slot="switch-input"]').first()
25+
await expect(toggle).toBeVisible()
26+
if ((await input.getAttribute("aria-checked")) !== "true") {
27+
await toggle.locator('[data-slot="switch-control"]').click()
28+
await expect(input).toHaveAttribute("aria-checked", "true")
2729
}
30+
await closeDialog(page, dialog)
2831
await project.shell(cmd)
2932

3033
await expect

packages/app/e2e/session/session-child-navigation.spec.ts

Lines changed: 23 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,6 @@
11
import { seedSessionTask, withSession } from "../actions"
22
import { test, expect } from "../fixtures"
33
import { inputMatch } from "../prompt/mock"
4-
import { promptSelector } from "../selectors"
54

65
test("task tool child-session link does not trigger stale show errors", async ({ page, llm, project }) => {
76
test.setTimeout(120_000)
@@ -30,15 +29,33 @@ test("task tool child-session link does not trigger stale show errors", async ({
3029

3130
await project.gotoSession(session.id)
3231

33-
const link = page
34-
.locator("a.subagent-link")
32+
const header = page.locator("[data-session-title]")
33+
await expect(header.getByRole("button", { name: "More options" })).toBeVisible({ timeout: 30_000 })
34+
35+
const card = page
36+
.locator('[data-component="task-tool-card"]')
3537
.filter({ hasText: /open child session/i })
3638
.first()
37-
await expect(link).toBeVisible({ timeout: 30_000 })
38-
await link.click()
39+
await expect(card).toBeVisible({ timeout: 30_000 })
40+
await card.click()
3941

4042
await expect(page).toHaveURL(new RegExp(`/session/${child.sessionID}(?:[/?#]|$)`), { timeout: 30_000 })
41-
await expect(page.locator(promptSelector)).toBeVisible({ timeout: 30_000 })
43+
await expect(header.locator('[data-slot="session-title-parent"]')).toHaveText(session.title)
44+
await expect(header.locator('[data-slot="session-title-child"]')).toHaveText(taskInput.description)
45+
await expect(header.locator('[data-slot="session-title-separator"]')).toHaveText("/")
46+
await expect
47+
.poll(
48+
() =>
49+
header.locator('[data-slot="session-title-separator"]').evaluate((el) => ({
50+
left: getComputedStyle(el).paddingLeft,
51+
right: getComputedStyle(el).paddingRight,
52+
})),
53+
{ timeout: 30_000 },
54+
)
55+
.toEqual({ left: "8px", right: "8px" })
56+
await expect(header.getByRole("button", { name: "More options" })).toHaveCount(0)
57+
await expect(page.getByText("Subagent sessions cannot be prompted.")).toBeVisible({ timeout: 30_000 })
58+
await expect(page.getByRole("button", { name: "Back to main session." })).toBeVisible({ timeout: 30_000 })
4259
await expect.poll(() => errs, { timeout: 5_000 }).toEqual([])
4360
})
4461
} finally {

packages/app/e2e/session/session-composer-dock.spec.ts

Lines changed: 10 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ import {
55
type ComposerProbeState,
66
type ComposerWindow,
77
} from "../../src/testing/session-composer"
8-
import { cleanupSession, clearSessionDockSeed, seedSessionQuestion } from "../actions"
8+
import { cleanupSession, clearSessionDockSeed, closeDialog, openSettings, seedSessionQuestion } from "../actions"
99
import {
1010
permissionDockSelector,
1111
promptSelector,
@@ -65,12 +65,14 @@ async function clearPermissionDock(page: any, label: RegExp) {
6565
}
6666

6767
async function setAutoAccept(page: any, enabled: boolean) {
68-
const button = page.locator('[data-action="prompt-permissions"]').first()
69-
await expect(button).toBeVisible()
70-
const pressed = (await button.getAttribute("aria-pressed")) === "true"
71-
if (pressed === enabled) return
72-
await button.click()
73-
await expect(button).toHaveAttribute("aria-pressed", enabled ? "true" : "false")
68+
const dialog = await openSettings(page)
69+
const toggle = dialog.locator('[data-action="settings-auto-accept-permissions"]').first()
70+
const input = toggle.locator('[data-slot="switch-input"]').first()
71+
await expect(toggle).toBeVisible()
72+
const checked = (await input.getAttribute("aria-checked")) === "true"
73+
if (checked !== enabled) await toggle.locator('[data-slot="switch-control"]').click()
74+
await expect(input).toHaveAttribute("aria-checked", enabled ? "true" : "false")
75+
await closeDialog(page, dialog)
7476
}
7577

7678
async function expectQuestionBlocked(page: any) {
@@ -277,6 +279,7 @@ test("default dock shows prompt input", async ({ page, project }) => {
277279

278280
await expect(page.locator(sessionComposerDockSelector)).toBeVisible()
279281
await expect(page.locator(promptSelector)).toBeVisible()
282+
await expect(page.locator('[data-action="prompt-permissions"]')).toHaveCount(0)
280283
await expect(page.locator(questionDockSelector)).toHaveCount(0)
281284
await expect(page.locator(permissionDockSelector)).toHaveCount(0)
282285

@@ -290,10 +293,6 @@ test("default dock shows prompt input", async ({ page, project }) => {
290293
test("auto-accept toggle works before first submit", async ({ page, project }) => {
291294
await project.open()
292295

293-
const button = page.locator('[data-action="prompt-permissions"]').first()
294-
await expect(button).toBeVisible()
295-
await expect(button).toHaveAttribute("aria-pressed", "false")
296-
297296
await setAutoAccept(page, true)
298297
await setAutoAccept(page, false)
299298
})

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.3.17",
3+
"version": "1.4.2",
44
"description": "",
55
"type": "module",
66
"exports": {

packages/app/src/app.tsx

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -182,7 +182,6 @@ function ConnectionGate(props: ParentProps<{ disableHealthCheck?: boolean }>) {
182182
if (checkMode() === "background" || type === "http") return false
183183
}
184184
}).pipe(
185-
effectMinDuration(checkMode() === "blocking" ? "1.2 seconds" : 0),
186185
Effect.timeoutOrElse({ duration: "10 seconds", orElse: () => Effect.succeed(false) }),
187186
Effect.ensuring(Effect.sync(() => setCheckMode("background"))),
188187
Effect.runPromise,

0 commit comments

Comments
 (0)