Skip to content

sync: upstream 195f59264 (between v1.14.50 and v1.14.51)#70

Merged
Alezander9 merged 379 commits into
mainfrom
sync/upstream-195f59264
May 16, 2026
Merged

sync: upstream 195f59264 (between v1.14.50 and v1.14.51)#70
Alezander9 merged 379 commits into
mainfrom
sync/upstream-195f59264

Conversation

@Alezander9
Copy link
Copy Markdown
Member

@Alezander9 Alezander9 commented May 16, 2026

Summary

Brings anomalyco/opencode from ce66b191d (v1.14.48, our previous anchor) to 195f59264 (refactor(server): simplify listener lifecycle, between v1.14.50 and v1.14.51). 379 upstream commits.

Did NOT target v1.14.51. Upstream's chore: generate commit e62ebd8fe (the parent of 4e7a60dac/v1.14.51) regenerated packages/sdk/openapi.json + the v2 SDK in a way that drops EventMessageUpdated/EventMessagePartUpdated from the SDK's Event union — while cli/cmd/run.ts, acp/agent.ts, cli/cmd/run/{demo,session-data,stream.transport}.ts, etc. still string-compare against those types. A pristine checkout of 4e7a60dac produces 207 typecheck errors. The parent commit 195f59264 is the last clean point that still includes the upstream image-fix PR #26805 we wanted, so I anchored there. Recommend retrying once upstream re-aligns its event consumers with the new SyncEvent shape.

Why this sync now

User pointed at our PRs #64 (fix/strict-temperature-required-models) and #69 (fix/photon-load-and-typed-omitted-message) and asked whether upstream had fixed those independently and if so to adopt upstream and drop our exceptions.

Conflicts resolved

File Resolution
packages/opencode/package.json Kept @browser-use/browsercode-core, bumped version string to 1.14.51
bun.lock --theirs, regenerated via bun install
30 .github/workflows/*.yml Re-deleted per PR #14
src/agent/agent.ts Kept Skills + Flag imports + Scout referencePrompt/referenceDescription block. Added missing Reference import (auto-merge dropped it).
src/cli/cmd/tui/feature-plugins/home/tips-view.tsx Kept brand strings (bcode.json, ~/.config/bcode, .bcode/commands/agents/tools/plugins/themes, BrowserCode). Adopted upstream's dynamic-shortcut refactors + formatter/lsp tip rewordings. Dropped the new docker/zen marketing tips.
src/image/image.ts Adopted upstream verbatim (PR #26805).
src/index.ts Combined trace + isRecord imports.
src/installation/index.ts Kept our curl-only Method surface but rebuilt on upstream's new appProcess.run shape + userAgent(client) factory. Added back Flag import for the UA default.
src/plugin/index.ts Combined Laminar + DigitalOcean plugins in INTERNAL_PLUGINS.
src/provider/provider.ts Kept bcode.sh / bcode headers for nvidia. Dropped upstream's new X-BILLING-INVOKE-ORIGIN: OpenCode (would phone home wrong brand).
src/server/shared/ui.ts Adopted upstream's embeddedUI(disableEmbeddedWebUi) signature. Kept F7 phone-home removal (dropped requestBody/proxyResponseHeaders/upstreamURL).
src/session/processor.ts Kept our typed-message UX. Renamed ImagePhotonUnavailableError case to ImageResizerUnavailableError.
src/storage/db.ts Adopted upstream's flags: ChannelDbFlags signature. Kept bcode.db / bcode-<channel>.db filenames.
src/tool/registry.ts Adopted upstream's SessionStatus + BackgroundJob + RuntimeFlags additions. Split FetchUse.layer into its own .pipe() call (Effect caps .pipe() at 20 args; pre-piped with FetchHttpClient.layer so its HttpClient dep doesn't escape).
src/tool/webfetch.ts Combined FetchUse + Config + Parser imports.
test/storage/db.test.ts Adopted upstream's new it.effect + RuntimeFlags.layer shape. Kept bcode.db filenames.
test/tool/registry.test.ts Adopted upstream's factory shape. Same FetchUse pipe-split as the source.
test/tool/webfetch.test.ts Adopted upstream's Effect.acquireUseRelease test shape. Promoted top it = testEffect(...) to include FetchUse + Config layers.

Brand sweep

packages/core/src/models.ts is a NEW file from upstream that includes USER_AGENT = \"opencode/...\". Rebranded to browsercode/... in the F7-style sweep so it doesn't ship as a regression of that work.

Verification

  • bun install: clean, regenerated lockfile.
  • bun run typecheck: 7/7 packages passed in ~10s (one-time cold run).
  • Pristine 195f592 standalone also typechecks clean (sanity check that we hit the right anchor and aren't compounding upstream's regression).

Yellow-zone audit

12 files touched upstream + at our zone: customizations preserved across the board (banner/title BC, bcode.sh HTTP-Referer/X-Title/X-Source across 8 providers, Cerebras X-Cerebras-3rd-Party-Integration: bcode, .bcode/plans, .bcode/agent-workspace, Skills import, BrowserExecute renderer, bcode.db filenames, bcode.sh/install curl bootstrap, Method surface stays curl-only, userAgent(client) returns browsercode/...).

EXCEPTIONS.md follow-up

Not in this PR (lives outside this repo in the maintainer's agent memory). To be updated to:


Summary by cubic

Sync with upstream to a clean pre-v1.14.51 point to pull in image handling and core/server updates, and add console-side TPS limiting + sticky provider persistence. Kept our typed image error UX and temperature fix; skipped v1.14.51 due to an upstream SDK event regression.

  • New Features

    • Console
      • Per-model TPS limiter and DB-backed sticky provider tracking; new Cloudflare Worker Stat for TPS history.
      • Honeycomb webhook handles low TPS alerts.
    • App
      • Project quick-switch hotkeys (mod+1mod+9); improved “session working” state; review panel unmounts when closed.
      • Todo dock collapse state is remembered per session.
      • Palette/keybinds hide hidden commands; dialog excludes hidden options.
      • MCP shows “needs client registration” and click-to-auth; toggle/connect flow hardened; popover prioritizes MCP issues.
      • Clearer server errors by unwrapping SDK-wrapped causes.
    • Core
      • New aisdk bridge (adds SSE timeout guard) and catalog module for providers/models.
      • Auth storage migrated to v2 with on-write migration from legacy file.
      • Removed effect-zod; moved/renamed GitHub Copilot helpers.
  • Dependencies

    • Updated to effect/@effect/* 4.0.0-beta.65 and @opentui/{core,keymap,solid} 0.2.10.
    • Package versions bumped to 1.14.50 where applicable; bun.lock and Nix hashes refreshed.
    • CI hardening: pin actions/checkout, actions/create-github-app-token, and oven-sh/setup-bun; split cache restore/save; bunfig.toml adds minimumReleaseAge.

Written for commit 22e180b. Summary will update on new commits. Review in cubic

kitlangton and others added 30 commits May 12, 2026 19:41
Co-authored-by: Andrew Suffield <asuffield@cloudflare.com>
Co-authored-by: Aiden Cline <aidenpcline@gmail.com>
kitlangton and others added 28 commits May 14, 2026 13:56
Pulls anomalyco/opencode from ce66b19 (v1.14.48) to 195f592. 379 upstream
commits. Targeted 195f592 explicitly because v1.14.51 itself ships with a
broken openapi.json regen that drops EventMessageUpdated/EventMessagePartUpdated
from the v2 SDK while consumers still string-compare against them (207 typecheck
errors on a pristine v1.14.51). 195f592 is the last commit before that regen
and is the latest point that includes the image-fix PR #26805 we wanted.

Notable:
- Adopts upstream's image fix (PR #26805) — replaces our PR #69 photon loader.
  Cleaner shape (top-level import-with-attributes + path resolution instead of
  new Function/createRequire eval). Renames PhotonUnavailableError to
  ResizerUnavailableError.
- Keeps our PR #69 typed omitted-image-message UX in processor.ts (upstream
  did not adopt that part). Updated the case label to the renamed error tag.
- Keeps our PR #64 temperature operand swap — upstream did not include it.
- Absorbs the runtime-flags refactor wave (channelDb / autoShare /
  embeddedWebUi / icon / oxfmt / bash-timeout / experimental models / output-
  token-max / llm client / event system migrated to RuntimeFlags).
- Absorbs new core packages from upstream (auth/catalog/instance/model/
  plugin/provider/etc.), AppFileSystem and AppProcess migrations,
  BackgroundJob service, task_status tool, DigitalOcean auth plugin.
- Rebrands USER_AGENT in the new packages/core/src/models.ts (opencode/... ->
  browsercode/...).

Conflicts: 17 source-side + bun.lock + 30 workflow re-deletes. See UPSTREAM.md
row for the full per-file resolution log.
Copy link
Copy Markdown

@cubic-dev-ai cubic-dev-ai Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

7 issues found across 774 files

Prompt for AI agents (unresolved issues)

Check if these issues are valid — if so, understand the root cause of each and fix them. If appropriate, use sub-agents to investigate and fix each issue separately.


<file name=".opencode/opencode.jsonc">

<violation number="1" location=".opencode/opencode.jsonc:4">
P2: This removes the migration-path edit approval guard; with default-permissive permissions, edits in `packages/opencode/migration/*` will no longer require confirmation.</violation>
</file>

<file name="packages/app/src/context/command.tsx">

<violation number="1" location="packages/app/src/context/command.tsx:285">
P2: Persist the `hidden` flag when building `command.catalog`; otherwise hidden commands can reappear from catalog metadata in settings.</violation>
</file>

<file name="packages/core/src/auth.ts">

<violation number="1" location="packages/core/src/auth.ts:136">
P1: Migrating `auth.json` before reading `auth-v2.json` can overwrite newer v2 auth data with stale legacy content when both files exist.</violation>
</file>

<file name="packages/core/src/plugin/provider/azure.ts">

<violation number="1" location="packages/core/src/plugin/provider/azure.ts:28">
P2: Treat `resourceName` as missing when it is an empty/whitespace string; the current truthiness check allows invalid values to bypass Azure configuration validation.</violation>
</file>

<file name="packages/console/app/src/routes/zen/util/modelTpsLimiter.ts">

<violation number="1" location="packages/console/app/src/routes/zen/util/modelTpsLimiter.ts:74">
P2: Guard against non-positive elapsed time before computing TPS to avoid `Infinity`/invalid TPS values.</violation>
</file>

<file name="packages/app/src/components/settings-keybinds.tsx">

<violation number="1" location="packages/app/src/components/settings-keybinds.tsx:126">
P2: Skipping hidden commands here removes them from keybind conflict detection, so users can assign shortcuts that collide with active hidden keybinds.</violation>
</file>

<file name="packages/core/src/plugin/auth.ts">

<violation number="1" location="packages/core/src/plugin/auth.ts:19">
P2: `Object.assign` after setting `apiKey` may overwrite it if `metadata` contains an `apiKey` field. Swap the order so the explicit key wins, or destructure `apiKey` out of metadata before assigning.</violation>
</file>

Tip: instead of fixing issues one by one fix them all with cubic
Note: This PR contains a large number of files. cubic only reviews up to 100 files per PR, so some files may not have been reviewed. cubic prioritizes the most important files to review.
On a pro plan you can use ultrareview for larger PRs.
Re-trigger cubic

Comment thread packages/core/src/auth.ts

const raw = yield* fsys.readJson(file).pipe(Effect.orElseSucceed(() => null))
const legacy = yield* fsys.readJson(legacyFile).pipe(Effect.orElseSucceed(() => null))
if (legacy && typeof legacy === "object") return yield* writeMigrated(legacy as Record<string, unknown>)
Copy link
Copy Markdown

@cubic-dev-ai cubic-dev-ai Bot May 16, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P1: Migrating auth.json before reading auth-v2.json can overwrite newer v2 auth data with stale legacy content when both files exist.

Prompt for AI agents
Check if this issue is valid — if so, understand the root cause and fix it. At packages/core/src/auth.ts, line 136:

<comment>Migrating `auth.json` before reading `auth-v2.json` can overwrite newer v2 auth data with stale legacy content when both files exist.</comment>

<file context>
@@ -106,25 +106,43 @@ export const layer = Layer.effect(
 
-      const raw = yield* fsys.readJson(file).pipe(Effect.orElseSucceed(() => null))
+      const legacy = yield* fsys.readJson(legacyFile).pipe(Effect.orElseSucceed(() => null))
+      if (legacy && typeof legacy === "object") return yield* writeMigrated(legacy as Record<string, unknown>)
 
-      if (!raw || typeof raw !== "object") return { version: 2, accounts: {}, active: {} }
</file context>
Fix with Cubic

Comment thread .opencode/opencode.jsonc
"packages/opencode/migration/*": "ask",
},
},
"permission": {},
Copy link
Copy Markdown

@cubic-dev-ai cubic-dev-ai Bot May 16, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2: This removes the migration-path edit approval guard; with default-permissive permissions, edits in packages/opencode/migration/* will no longer require confirmation.

Prompt for AI agents
Check if this issue is valid — if so, understand the root cause and fix it. At .opencode/opencode.jsonc, line 4:

<comment>This removes the migration-path edit approval guard; with default-permissive permissions, edits in `packages/opencode/migration/*` will no longer require confirmation.</comment>

<file context>
@@ -1,11 +1,7 @@
-      "packages/opencode/migration/*": "ask",
-    },
-  },
+  "permission": {},
   "mcp": {},
   "tools": {
</file context>
Suggested change
"permission": {},
"permission": {
"edit": {
"packages/opencode/migration/*": "ask",
},
},
Fix with Cubic

Comment on lines +285 to +291
acc[id] = {
title: opt.title,
description: opt.description,
category: opt.category,
keybind: opt.keybind,
slash: opt.slash,
}
Copy link
Copy Markdown

@cubic-dev-ai cubic-dev-ai Bot May 16, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2: Persist the hidden flag when building command.catalog; otherwise hidden commands can reappear from catalog metadata in settings.

Prompt for AI agents
Check if this issue is valid — if so, understand the root cause and fix it. At packages/app/src/context/command.tsx, line 285:

<comment>Persist the `hidden` flag when building `command.catalog`; otherwise hidden commands can reappear from catalog metadata in settings.</comment>

<file context>
@@ -279,13 +281,14 @@ export const { use: useCommand, provider: CommandProvider } = createSimpleContex
-            slash: opt.slash,
-          }
+          if (opt.title)
+            acc[id] = {
+              title: opt.title,
+              description: opt.description,
</file context>
Suggested change
acc[id] = {
title: opt.title,
description: opt.description,
category: opt.category,
keybind: opt.keybind,
slash: opt.slash,
}
acc[id] = {
title: opt.title,
description: opt.description,
category: opt.category,
keybind: opt.keybind,
slash: opt.slash,
hidden: opt.hidden,
}
Fix with Cubic

if (evt.package !== "@ai-sdk/azure") return
if (evt.model.providerID === ProviderV2.ID.azure) {
if (
!evt.options.resourceName &&
Copy link
Copy Markdown

@cubic-dev-ai cubic-dev-ai Bot May 16, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2: Treat resourceName as missing when it is an empty/whitespace string; the current truthiness check allows invalid values to bypass Azure configuration validation.

Prompt for AI agents
Check if this issue is valid — if so, understand the root cause and fix it. At packages/core/src/plugin/provider/azure.ts, line 28:

<comment>Treat `resourceName` as missing when it is an empty/whitespace string; the current truthiness check allows invalid values to bypass Azure configuration validation.</comment>

<file context>
@@ -0,0 +1,64 @@
+        if (evt.package !== "@ai-sdk/azure") return
+        if (evt.model.providerID === ProviderV2.ID.azure) {
+          if (
+            !evt.options.resourceName &&
+            !evt.options.baseURL &&
+            (evt.model.endpoint.type !== "aisdk" || !evt.model.endpoint.url)
</file context>
Fix with Cubic

const tokens = usageInfo.outputTokens
if (tokens <= 10) return

const tps = (tokens / (tsLastByte - tsFirstByte)) * 1000
Copy link
Copy Markdown

@cubic-dev-ai cubic-dev-ai Bot May 16, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2: Guard against non-positive elapsed time before computing TPS to avoid Infinity/invalid TPS values.

Prompt for AI agents
Check if this issue is valid — if so, understand the root cause and fix it. At packages/console/app/src/routes/zen/util/modelTpsLimiter.ts, line 74:

<comment>Guard against non-positive elapsed time before computing TPS to avoid `Infinity`/invalid TPS values.</comment>

<file context>
@@ -0,0 +1,95 @@
+      const tokens = usageInfo.outputTokens
+      if (tokens <= 10) return
+
+      const tps = (tokens / (tsLastByte - tsFirstByte)) * 1000
+      const qualify = tps >= tpsGoal ? 1 : 0
+      const unqualify = tps < tpsGoal ? 1 : 0
</file context>
Fix with Cubic


for (const opt of command.catalog) {
if (opt.id.startsWith("suggested.")) continue
if (opt.hidden) continue
Copy link
Copy Markdown

@cubic-dev-ai cubic-dev-ai Bot May 16, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2: Skipping hidden commands here removes them from keybind conflict detection, so users can assign shortcuts that collide with active hidden keybinds.

Prompt for AI agents
Check if this issue is valid — if so, understand the root cause and fix it. At packages/app/src/components/settings-keybinds.tsx, line 126:

<comment>Skipping hidden commands here removes them from keybind conflict detection, so users can assign shortcuts that collide with active hidden keybinds.</comment>

<file context>
@@ -123,11 +123,13 @@ function listFor(command: CommandContext, map: KeybindMap, palette: string) {
 
   for (const opt of command.catalog) {
     if (opt.id.startsWith("suggested.")) continue
+    if (opt.hidden) continue
     out.set(opt.id, { title: opt.title, group: groupFor(opt.id) })
   }
</file context>
Fix with Cubic

}
if (account.credential.type === "api") {
evt.provider.options.aisdk.provider.apiKey = account.credential.key
Object.assign(evt.provider.options.aisdk.provider, account.credential.metadata ?? {})
Copy link
Copy Markdown

@cubic-dev-ai cubic-dev-ai Bot May 16, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2: Object.assign after setting apiKey may overwrite it if metadata contains an apiKey field. Swap the order so the explicit key wins, or destructure apiKey out of metadata before assigning.

Prompt for AI agents
Check if this issue is valid — if so, understand the root cause and fix it. At packages/core/src/plugin/auth.ts, line 19:

<comment>`Object.assign` after setting `apiKey` may overwrite it if `metadata` contains an `apiKey` field. Swap the order so the explicit key wins, or destructure `apiKey` out of metadata before assigning.</comment>

<file context>
@@ -0,0 +1,27 @@
+        }
+        if (account.credential.type === "api") {
+          evt.provider.options.aisdk.provider.apiKey = account.credential.key
+          Object.assign(evt.provider.options.aisdk.provider, account.credential.metadata ?? {})
+        }
+        if (account.credential.type === "oauth") {
</file context>
Fix with Cubic

@Alezander9 Alezander9 merged commit 92d8bdb into main May 16, 2026
3 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.