Skip to content

sync: upstream v1.14.39 (773078e81 on dev)#37

Merged
Alezander9 merged 179 commits intomainfrom
sync/upstream-v1.14.39
May 6, 2026
Merged

sync: upstream v1.14.39 (773078e81 on dev)#37
Alezander9 merged 179 commits intomainfrom
sync/upstream-v1.14.39

Conversation

@Alezander9
Copy link
Copy Markdown
Member

Summary

Brings anomalyco/opencode up to v1.14.39 (773078e81 on dev). 178 upstream commits since 21f8027ef.

Conflicts resolved

File Resolution
.github/workflows/publish.yml Re-deleted per PR #14
bun.lock git checkout --theirs, regenerated via bun install
README.md Kept our concise version; dropped upstream's reintroduced OpenCode FAQ/Discord block
packages/opencode/package.json Kept name @browser-use/browsercode-core, took upstream version 1.14.39
packages/opencode/src/cli/cmd/agent.ts Adopted upstream's Effect-ification + dedented form (Instance.worktreectx.worktree, AppRuntime.runPromise(Agent.Service.use(...))Effect.runPromise(agentSvc.generate(...))); flipped post-merge .opencode.bcode (one site)
packages/opencode/src/cli/cmd/{run,serve,web}.ts Adopted upstream's Effect.fn("Cli.<name>")(function* (args) {...}) handler shape + instance: false/directory: fields; kept our bcode brand strings in describe:
packages/opencode/src/cli/cmd/tui/routes/session/index.tsx Took upstream's ShellTool + ShellID imports (PR #20039 renamed tool/bash.{ts,txt}tool/shell.{ts,txt}); kept our BrowserExecuteTool import. Auto-merge handled the <Match>/<Shell> rewrite

Verification

  • bun install: clean
  • bun run typecheck: 5/5 passed in 13.8s

Yellow-zone audit

Upstream touched 9 Yellow-zone files in this window:

  • packages/core/src/global.tsapp = "bcode" preserved
  • packages/opencode/script/build.tsbcode-<target> asset naming preserved
  • packages/opencode/src/cli/cmd/tui/app.tsxBrowserCode title + BC | <session> prefix preserved
  • packages/opencode/src/cli/cmd/tui/routes/session/index.tsxBrowserExecute renderer preserved
  • packages/opencode/src/config/config.tsbcode.json/bcode.jsonc/.bcode/, bcode.sh schema URLs preserved
  • packages/opencode/src/plugin/index.ts — internal-plugins list intact (LaminarPlugin not yet on main, no regression)
  • packages/opencode/src/provider/provider.ts — attribution headers https://bcode.sh/, X-Title: bcode, X-Source: bcode preserved
  • packages/opencode/src/session/session.ts.bcode/plans rename preserved
  • packages/opencode/src/storage/db.tsbcode.db filename preserved

All customizations verified post-merge.

Notable upstream changes pulled in

  • PR #20039bash tool renamed to shell with shell-aware prompts (bash, pwsh+powershell, cmd). New sub-package tool/shell/{id,prompt}.ts. Match predicate moves from string literal "bash" to ShellID.ToolID.
  • CLI Effect-ificationcli/cmd/{run,serve,web,agent}.ts switch from async (args) => {...} to Effect.fn(...) handlers; framework-managed instance/directory loading via new instance: and directory: fields.
  • PR #25822 — Desktop consolidation (desktop-electrondesktop). Not a package we ship.
  • PR #25768 — Session warping in @opencode-ai/core.
  • 178 commits total — see git log 21f8027ef..773078e81 --oneline for the full list.

Workflow re-deletions

All 30 inherited workflows re-deleted per opencode-sync.md step 3a. Final state: release.yml + typecheck.yml.

simonklee and others added 30 commits May 1, 2026 11:33
…prompts

Agents can now create temporary files in the global tmp directory without
triggering external_directory permission prompts. This enables agents to
freely use temporary storage for intermediate files during builds and
other operations.
…ovider (#21114)

Co-authored-by: Aiden Cline <aidenpcline@gmail.com>
opencode-agent Bot and others added 28 commits May 5, 2026 00:35
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.

6 issues found across 853 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="packages/desktop/scripts/copy-bundles.ts">

<violation number="1" location="packages/desktop/scripts/copy-bundles.ts:12">
P1: The copy command recursively includes the destination directory (`dist/bundles`) in its own source glob, which can make the script fail with a self-copy error.</violation>
</file>

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

<violation number="1" location="packages/console/app/src/routes/zen/util/provider/openai.ts:21">
P2: OpenAI request body no longer includes `safety_identifier`, so workspace identity is dropped for safety attribution.</violation>
</file>

<file name="packages/app/src/pages/session/terminal-panel.tsx">

<violation number="1" location="packages/app/src/pages/session/terminal-panel.tsx:152">
P1: Recovery can get permanently disabled after one failed clone attempt because the `recovered` flag is never cleared on clone failure.</violation>
</file>

<file name="packages/opencode/migration/20260427172553_slow_nightmare/migration.sql">

<violation number="1" location="packages/opencode/migration/20260427172553_slow_nightmare/migration.sql:17">
P1: This migration drops `session_entry` without copying existing rows into `session_message`, causing data loss for all existing session messages.</violation>
</file>

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

<violation number="1" location="packages/console/app/src/routes/zen/util/handler.ts:160">
P1: Missing null guard before recursive call — `typeof null === "object"` is true in JS, so a `null` value in `payloadModifier` will crash with `TypeError: Cannot convert undefined or null to object` when `Object.entries(null)` is called.</violation>

<violation number="2" location="packages/console/app/src/routes/zen/util/handler.ts:926">
P2: `cacheWrite1hCost` is missing from the new microcents metrics. The deprecated metrics track both `cache_write_5m` and `cache_write_1h` separately, but the new `"cost.cache_write.microcents"` only reports the 5m cost. If `cacheWrite1hCost` is nonzero while `cacheWrite5mCost` is zero/undefined, this metric will show `undefined` instead of the actual cache write cost.</violation>
</file>

Note: This PR contains a large number of files. cubic only reviews up to 75 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.
Fix all with cubic.


await $`mkdir -p ${BUNDLES_OUT_DIR}`
await $`cp -r ${BUNDLE_DIR}/*/OpenCode* ${BUNDLES_OUT_DIR}`
await $`cp -r ${BUNDLE_DIR}/* ${BUNDLES_OUT_DIR}`
Copy link
Copy Markdown

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

Choose a reason for hiding this comment

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

P1: The copy command recursively includes the destination directory (dist/bundles) in its own source glob, which can make the script fail with a self-copy error.

Prompt for AI agents
Check if this issue is valid — if so, understand the root cause and fix it. At packages/desktop/scripts/copy-bundles.ts, line 12:

<comment>The copy command recursively includes the destination directory (`dist/bundles`) in its own source glob, which can make the script fail with a self-copy error.</comment>

<file context>
@@ -5,8 +5,8 @@ import { RUST_TARGET } from "./utils"
 
 await $`mkdir -p ${BUNDLES_OUT_DIR}`
-await $`cp -r ${BUNDLE_DIR}/*/OpenCode* ${BUNDLES_OUT_DIR}`
+await $`cp -r ${BUNDLE_DIR}/* ${BUNDLES_OUT_DIR}`
</file context>
Fix with Cubic

const recoverTerminal = (key: string, id: string, clone: (id: string) => Promise<void>) => {
if (store.recovered[key]) return
setStore("recovered", key, true)
void clone(id)
Copy link
Copy Markdown

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

Choose a reason for hiding this comment

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

P1: Recovery can get permanently disabled after one failed clone attempt because the recovered flag is never cleared on clone failure.

Prompt for AI agents
Check if this issue is valid — if so, understand the root cause and fix it. At packages/app/src/pages/session/terminal-panel.tsx, line 152:

<comment>Recovery can get permanently disabled after one failed clone attempt because the `recovered` flag is never cleared on clone failure.</comment>

<file context>
@@ -145,6 +146,21 @@ export function TerminalPanel() {
+  const recoverTerminal = (key: string, id: string, clone: (id: string) => Promise<void>) => {
+    if (store.recovered[key]) return
+    setStore("recovered", key, true)
+    void clone(id)
+  }
+
</file context>
Suggested change
void clone(id)
void clone(id).finally(() => setStore("recovered", key, false))
Fix with Cubic

CREATE INDEX `session_message_session_idx` ON `session_message` (`session_id`);--> statement-breakpoint
CREATE INDEX `session_message_session_type_idx` ON `session_message` (`session_id`,`type`);--> statement-breakpoint
CREATE INDEX `session_message_time_created_idx` ON `session_message` (`time_created`);--> statement-breakpoint
DROP TABLE `session_entry`;
Copy link
Copy Markdown

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

Choose a reason for hiding this comment

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

P1: This migration drops session_entry without copying existing rows into session_message, causing data loss for all existing session messages.

Prompt for AI agents
Check if this issue is valid — if so, understand the root cause and fix it. At packages/opencode/migration/20260427172553_slow_nightmare/migration.sql, line 17:

<comment>This migration drops `session_entry` without copying existing rows into `session_message`, causing data loss for all existing session messages.</comment>

<file context>
@@ -0,0 +1,17 @@
+CREATE INDEX `session_message_session_idx` ON `session_message` (`session_id`);--> statement-breakpoint
+CREATE INDEX `session_message_session_type_idx` ON `session_message` (`session_id`,`type`);--> statement-breakpoint
+CREATE INDEX `session_message_time_created_idx` ON `session_message` (`time_created`);--> statement-breakpoint
+DROP TABLE `session_entry`;
\ No newline at end of file
</file context>
Fix with Cubic

Object.fromEntries(
Object.entries(obj).flatMap(([k, v]) => {
if (Array.isArray(v)) return [[k, v]]
if (typeof v === "object") return [[k, replacer(v)]]
Copy link
Copy Markdown

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

Choose a reason for hiding this comment

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

P1: Missing null guard before recursive call — typeof null === "object" is true in JS, so a null value in payloadModifier will crash with TypeError: Cannot convert undefined or null to object when Object.entries(null) is called.

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/handler.ts, line 160:

<comment>Missing null guard before recursive call — `typeof null === "object"` is true in JS, so a `null` value in `payloadModifier` will crash with `TypeError: Cannot convert undefined or null to object` when `Object.entries(null)` is called.</comment>

<file context>
@@ -141,20 +141,36 @@ export async function handler(
+              Object.fromEntries(
+                Object.entries(obj).flatMap(([k, v]) => {
+                  if (Array.isArray(v)) return [[k, v]]
+                  if (typeof v === "object") return [[k, replacer(v)]]
+                  if (typeof v === "string") {
+                    if (v === "$ip") return [[k, ip]]
</file context>
Suggested change
if (typeof v === "object") return [[k, replacer(v)]]
if (v != null && typeof v === "object") return [[k, replacer(v)]]
Fix with Cubic

...body,
...(workspaceID ? { safety_identifier: workspaceID } : {}),
}),
modifyBody: (body: Record<string, any>) => body,
Copy link
Copy Markdown

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

Choose a reason for hiding this comment

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

P2: OpenAI request body no longer includes safety_identifier, so workspace identity is dropped for safety attribution.

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/provider/openai.ts, line 21:

<comment>OpenAI request body no longer includes `safety_identifier`, so workspace identity is dropped for safety attribution.</comment>

<file context>
@@ -18,10 +18,7 @@ export const openaiHelper: ProviderHelper = ({ workspaceID }) => ({
-    ...body,
-    ...(workspaceID ? { safety_identifier: workspaceID } : {}),
-  }),
+  modifyBody: (body: Record<string, any>) => body,
   createBinaryStreamDecoder: () => undefined,
   streamSeparator: "\n\n",
</file context>
Suggested change
modifyBody: (body: Record<string, any>) => body,
modifyBody: (body: Record<string, any>) => ({
...body,
...(workspaceID ? { safety_identifier: workspaceID } : {}),
}),
Fix with Cubic

"cost.output.microcents": centsToMicroCents(outputCost),
"cost.reasoning.microcents": reasoningCost ? centsToMicroCents(reasoningCost) : undefined,
"cost.cache_read.microcents": cacheReadCost ? centsToMicroCents(cacheReadCost) : undefined,
"cost.cache_write.microcents": cacheWrite5mCost ? centsToMicroCents(cacheWrite5mCost) : undefined,
Copy link
Copy Markdown

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

Choose a reason for hiding this comment

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

P2: cacheWrite1hCost is missing from the new microcents metrics. The deprecated metrics track both cache_write_5m and cache_write_1h separately, but the new "cost.cache_write.microcents" only reports the 5m cost. If cacheWrite1hCost is nonzero while cacheWrite5mCost is zero/undefined, this metric will show undefined instead of the actual cache write cost.

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/handler.ts, line 926:

<comment>`cacheWrite1hCost` is missing from the new microcents metrics. The deprecated metrics track both `cache_write_5m` and `cache_write_1h` separately, but the new `"cost.cache_write.microcents"` only reports the 5m cost. If `cacheWrite1hCost` is nonzero while `cacheWrite5mCost` is zero/undefined, this metric will show `undefined` instead of the actual cache write cost.</comment>

<file context>
@@ -904,6 +919,13 @@ export async function handler(
+      "cost.output.microcents": centsToMicroCents(outputCost),
+      "cost.reasoning.microcents": reasoningCost ? centsToMicroCents(reasoningCost) : undefined,
+      "cost.cache_read.microcents": cacheReadCost ? centsToMicroCents(cacheReadCost) : undefined,
+      "cost.cache_write.microcents": cacheWrite5mCost ? centsToMicroCents(cacheWrite5mCost) : undefined,
+      "cost.total.microcents": centsToMicroCents(totalCostInCent),
+      // deprecated - remove after May 20, 2026
</file context>
Suggested change
"cost.cache_write.microcents": cacheWrite5mCost ? centsToMicroCents(cacheWrite5mCost) : undefined,
"cost.cache_write_5m.microcents": cacheWrite5mCost ? centsToMicroCents(cacheWrite5mCost) : undefined,
"cost.cache_write_1h.microcents": cacheWrite1hCost ? centsToMicroCents(cacheWrite1hCost) : undefined,
Fix with Cubic

@Alezander9 Alezander9 merged commit 2ac59c8 into main May 6, 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.