Skip to content

chore(sync): merge upstream v2 through v2.0.25 - #443

Merged
shuv1337 merged 107 commits into
integration-v2from
cursor/sync-upstream-v225-9a24
Oct 8, 2026
Merged

shuv1337 merged 107 commits into
integration-v2from
cursor/sync-upstream-v225-9a24

Conversation

@shuv1337

@shuv1337 shuv1337 commented Oct 8, 2026 •

Copy link
Copy Markdown
Owner

Issue for this PR

N/A. Upstream sync.

Type of change

  • Bug fix
  • New feature
  • Refactor / code improvement
  • Documentation

Upstream sync of anomalyco/opencode branch v2 into integration-v2.

What does this PR do?

Merges anomalyco/opencode branch v2 through the v2.0.25 tip into the Shuvcode fork and keeps fork identity.

  • Fork base: integration-v2 at 66f52fe5926d (PR chore(sync): merge upstream v2 through v2.0.24 #436, the v2.0.24 sync merge).
  • Previous sync stopped at bd55d4895f (sync release versions for v2.0.24 [skip ci]).
  • Merged upstream sha: 0621ea9d9fe0916b1f4fca5941d5d1932641537f (chore: update nix node_modules hashes). That was upstream/v2 HEAD at merge time.
  • Merge commit: cfb02b22954ebf7e3ccae6c567a9e3e01678d599 (66f52fe5926d + 0621ea9d9f). Regular merge. No squash, no rebase.
  • Follow-ups on this branch: 2c886758ba (narrow external credentials in fork auth paths), 741e82685e (test expectations), and the review fixes through 119a26e147. Branch HEAD is 119a26e14779f4fdac0e0f38b9503d878b3f582f.
  • CLI stays package/bin shuvcode at 2.0.25-shuv.1.
  • GitHub Actions workflows are unchanged versus integration-v2. CI stays on the self-hosted runner.

Tag relationship (same shape as v2.0.24):

Upstream range bd55d4895f..0621ea9d9f: 99 commits, 731 files, +21898 / −4010.

That range starts with the three commits #436 stopped before (9daf46b327 anomalyco#52859, cb11287ae6 anomalyco#51783, b78d10cd71 anomalyco#53471) and continues through v2.0.25. Highlights from the subjects:

Conflicts (10) and resolutions:

  • bun.lock: took the fork lock, then regenerated with bun install. Frozen install: Checked 2511 installs across 2945 packages (no changes). Workspace entry is shuvcode@2.0.25-shuv.1. Fork plugins stay (@shuvcode/antigravity-plugin, @shuvcode/claude-plugin, @shuvcode/gpt-live-plugin, @shuvcode/quota-plugin).
  • bunfig.toml: union of minimumReleaseAgeExcludes. Kept @agentclientprotocol/sdk and added upstream @kitlangton/solid-motion, @opentunnel/client, @opentunnel/protocol. minimumReleaseAge stays 259200.
  • packages/cli/package.json: name and bin stay shuvcode (./bin/shuvcode.mjs). Version is 2.0.25-shuv.1.
  • packages/cli/script/postinstall.mjs: stays deleted (fork identity commit removed the curl/npm postinstall). Upstream's stale-binary check (fix(cli): reject stale platform binaries during install anomalyco/opencode#53845) is in packages/cli/script/launcher.mjs. A version mismatch throws STALE_PLATFORM_BINARY and the launcher exits 1.
  • packages/cli/src/commands/commands.ts: uninstall description is Uninstall Shuvcode, keeping session data, configuration, and state. ACP keeps connectionFlags: "unsupported" and gains upstream --login.
  • packages/cli/src/commands/handlers/uninstall.ts: removes the cache only, with Shuvcode wording. Curl installer shell-profile cleanup was left out.
  • packages/client/src/promise/generated/types.ts: regenerated with bun run generate in packages/client. experimental.jev remains. Policy actions are provider.use | tool.use | integration.use. integration.connect has key and external.
  • packages/core/src/database/migration.gen.ts: regenerated with bun script/migration.ts from packages/core. The generator reported no schema change and rewrote the registry. Timestamp order is fork 20261005094821_subagent-operation then upstream 20261007190000_azure_cli_external_credential (data-only UPDATE).
  • packages/core/src/integration.ts: refresh still takes refreshLocks.withLock, and shuvcodeAuthImport === "access-only" still refuses a near-expiry imported token. Only oauth credentials refresh; key and external return the stored value.
  • packages/script/src/index.ts: channel resolution stays the fork resolveChannel (detached HEAD, jj, GITHUB_*). Fork version helpers below that block were already unconflicted.

Also regenerated, rather than hand-merged: packages/protocol/openapi.json and the services/www copies (openapi.json, public/openapi.json). Regeneration added /api/integration/{integrationID}/connect/external, which upstream's committed OpenAPI had not recorded yet. public/cli.json was unchanged.

Judgment calls:

  • Merged v2 tip 0621ea9d9f, not tag b44eea9e20. The tag is a sibling release commit. Includes fix(tui): open clicked transcript links, including wrapped rows anomalyco/opencode#53903 and chore: upgrade opentui v0.5.17 anomalyco/opencode#53904. Same shape as chore(sync): merge upstream v2 through v2.0.24 #436.
  • Version counter restarts at 2.0.25-shuv.1 because the upstream base moved.
  • Stale-binary check lives in the fork launcher and fails closed. postinstall.mjs stays deleted. No curl installer and no opencode.ai update path.
  • Uninstall keeps data, config, and state and removes cache. Wording is Shuvcode.
  • OAuth refresh keeps the fork lock and access-only import refusal, and adopts upstream's oauth-only refresh so external credentials are not refreshed as oauth.
  • External credentials are rejected by the fork auth importer, ignored by Claude subscription detection, and ignored by quota key matching.
  • ACP keeps connectionFlags: "unsupported", gains --login, and calls fork login.default with target, method, and answer only. Per-command server / standalone are global flags on this fork (fix(cli): accept --server and --standalone as global flags #428).
  • Migrations stay in timestamp order: fork subagent operation, then upstream Azure external credential. No new schema migration.
  • OpenAPI regeneration is larger than the conflict because upstream's committed document lagged the schema. Paths and schemas from both parents were kept, jev remains, and the external connect route was added.
  • Compiled-binary Scalar notice says Shuvcode. Console and www docs that already say OpenCode were left; those trees are outside fork publish.
  • GitHub Actions runners were not modified.

Unmerged fork branches:

How did you verify your code works?

Local only. This PR was not merged and auto-merge is off. Bun 1.4.2. Node 22.22.2 for bun run check (oxlint's TypeScript plugins do not load on the image's Node 22.14).

  • bun install --frozen-lockfile: Checked 2511 installs across 2945 packages (no changes).
  • bun run check on push: oxlint Found 1519 warnings and 0 errors. Turbo typecheck 41 successful, 41 total.

Package tests with bun test from each package directory:

  • packages/client: 233 pass, 0 fail, after expecting integration.connect keys ["key", "external"].
  • packages/cli: the first full run was 340 pass, 7 skip, 40 fail. 39 failures are Cannot find module 'react/jsx-dev-runtime' when a test spawns the CLI with cwd outside the package directory. The same failure reproduces on integration-v2 in this VM (bun packages/cli/src/index.ts --help from /tmp exits 1; from packages/cli it exits 0). OpenTUI JSX depends on packages/cli/bunfig.toml preload, which Bun applies when cwd is the package. The remaining failure was packages/cli/test/acp/session.test.ts expecting Run `opencode auth login` ; the implementation says shuvcode. The expectation was updated and that file passes (5 tests). packages/cli/test/launcher.test.ts covers the stale platform package and passes.
  • packages/core: 6368 pass, 365 skip, 2 fail, 1 error under parallel load with the other suites. test/preload.test.ts (OPENCODE_TEST_HOME undefined) fails the same way on integration-v2 with raw bun test. The RepositoryCache refresh case timed out at 15s under that load and passed in isolation (280ms).
  • packages/tui: 1529 pass, 2 skip, 2 fail. dialog-shell-output.test.tsx shell-output cases at 40 and 100 columns time out at 5000ms. The same timeouts reproduce on integration-v2 in this VM.

Review follow-up

  • 56f082dfd3 points remote access at ShuvTunnel. @opentunnel/client@0.2.0 is wire-compatible (same tunnel HTTP paths and bridge frames) and matches this repo's Effect. @shuvtunnel/* is unpublished and built against an older Effect, so it is not a dependency. Bun patches set the subprotocol to shuvtunnel, the default API to https://shuv.zip, and the profile directory to shuvtunnel. SHUVTUNNEL_API and SHUVTUNNEL_PROFILE override those. The client bridge is wss://<api>/api/tunnel/:id/connect. Routes are shuvcode for channel latest and shuvcode-<channel> otherwise.
  • 921ba6d4d3 renames pairing and remote-access command hints to shuvcode in the CLI, the embedded web UI, and the desktop pairing page.
  • b76fda012d changes the ACP auth method name to Login with Shuvcode. The method id stays opencode-login.
  • 1e15f94d59 reports MCP clientInfo.name as Global.app (shuvcode).
  • 119a26e147 ports fix(script): normalize local build channels anomalyco/opencode#53461 into fork resolveChannel so a slashed branch is a valid preview version. Explicit OPENCODE_CHANNEL and detached-HEAD failure stay.

services/www still documents the upstream opencode CLI. That site is outside fork publish. shuv.zip returned HTTP 200. Follow-up bun run check: typecheck 41/41. Remote-tunnel, ACP session, channel, and pairing-link tests passed.

Screenshots / recordings

N/A. No fork UI layout change.

Checklist

  • I have tested my changes locally
  • I have not included unrelated changes in this PR
Open in Web Open in Cursor 

opencode-agent Bot and others added 30 commits October 6, 2026 13:07
…#52859)

Co-authored-by: iamdavidhill <1879069+iamdavidhill@users.noreply.github.com>
Co-authored-by: LukeParkerDev <10430890+Hona@users.noreply.github.com>
Co-authored-by: Brendonovich <14191578+Brendonovich@users.noreply.github.com>
Co-authored-by: rekram1-node <rekram1-node@users.noreply.github.com>
Co-authored-by: Eric Curtin <eric.curtin@docker.com>
Co-authored-by: OpenCode (GPT-5.6-Sol) <noreply@opencode.ai>
…2327)

Co-authored-by: Aiden Cline <aidenpcline@gmail.com>
)

Co-authored-by: Brendonovich <14191578+Brendonovich@users.noreply.github.com>
Co-authored-by: Brendonovich <14191578+Brendonovich@users.noreply.github.com>
Co-authored-by: Brendonovich <14191578+Brendonovich@users.noreply.github.com>
)

Co-authored-by: Brendonovich <14191578+Brendonovich@users.noreply.github.com>
Co-authored-by: rekram1-node <63023139+rekram1-node@users.noreply.github.com>
…odel compatibility (anomalyco#52172)

Co-authored-by: argszero <argszero@users.noreply.github.com>
Co-authored-by: Aiden Cline <aidenpcline@gmail.com>
thdxr and others added 17 commits October 7, 2026 23:05
…malyco#53761)

Co-authored-by: Brendonovich <14191578+Brendonovich@users.noreply.github.com>
…o#53667)

Fixes anomalyco#53666

Co-authored-by: Ayush Thakur <51413362+Ayushlm10@users.noreply.github.com>
…es (anomalyco#53860)

Co-authored-by: Brendonovich <14191578+Brendonovich@users.noreply.github.com>
…malyco#53880)

Co-authored-by: Brendonovich <14191578+Brendonovich@users.noreply.github.com>
Merge anomalyco/opencode v2 tip 0621ea9.
Tag v2.0.25 (b44eea9) is a sibling
release commit, not an ancestor of v2.
Upstream external credentials widened Credential.Value. Keep Claude
subscription detection, quota key reads, and auth import on oauth and
key values, and call auth login from acp --login without the removed
per-command server flags.
The regenerated client exposes integration.connect.external. ACP terminal
auth keeps the fork's shuvcode auth login command in its description.

shuv1337 commented Oct 8, 2026

Copy link
Copy Markdown
Owner Author

🔍 Automated Cursor review is underway. Please hold off on merging until the review comment lands here (usually 10–20 minutes).

@socket-security

socket-security Bot commented Oct 8, 2026 •

Copy link
Copy Markdown

@shuv1337

shuv1337 commented Oct 8, 2026

Copy link
Copy Markdown
Owner Author

Review complete:

Medium

  1. OpenTunnel remote access still identifies as OpenCode, and the recovery commands name a binary this fork does not install. packages/cli/src/services/remote-tunnel.ts:11-13 claims route opencode for channel latest and opencode-<channel> otherwise. The comment at :8-10 says OpenTunnel keeps one tunnel per device, shared by every SDK app, and each app claims its own routes. A release build’s channel is latest, so Shuvcode and upstream OpenCode attach the same route; the last process to connect owns https://opencode.<device-host>. Recovery text in the same feature was only partly rebranded: packages/cli/src/commands/handlers/pair.ts:17 and :61 say shuvcode, but :91 still says run `opencode pair --remote` . packages/cli/src/services/remote-tunnel.ts:45 says run `opencode service set remote true` . The embedded web UI (shipped in the CLI) adds the same instructions: packages/app/src/runtime/i18n/en.ts:348, :351, :362, :366, and the hardcoded command at packages/app/src/servers/connect/screen.tsx:249.

Low

  1. ACP terminal auth still displays “Login with opencode”. packages/cli/src/acp/service.ts:110 (id is opencode-login, declared at :48). The description and the legacy terminal-auth command were changed to shuvcode, and 741e82685e locks the display name in packages/cli/test/acp/session.test.ts. Clients that render authMethods[].name will show OpenCode.

  2. MCP handshake no longer uses the app name. packages/server/src/routes.ts:136 hardcodes clientInfo.name to "opencode". On integration-v2 this was options.app?.name ?? "opencode", so Shuvcode reported shuvcode. It merged cleanly from fix(server): always report opencode as mcp client name anomalyco/opencode#53471. Worth confirming the upstream client name is intentional; it changes every MCP connection.

  3. Upstream channel sanitization (fix(script): normalize local build channels anomalyco/opencode#53461) was not folded into fork resolveChannel. The conflict kept packages/script/src/version.ts:23 (if (branch) return branch) and the same for GITHUB_HEAD_REF at :25. fix(script): normalize local build channels anomalyco/opencode#53461 replaced characters outside [A-Za-z0-9._-] and prefixed a leading non-alphanumeric. Preview versions are built as `0.0.0-${CHANNEL}-...` (packages/script/src/index.ts:51), so a branch such as cursor/sync-upstream-v225-9a24 puts a slash in the version. Publish CI sets OPENCODE_CHANNEL, so release builds are unaffected. Detached-HEAD fail-closed behavior is preserved.

Checked, not a product defect

The claimed pre-existing failures match the tree:

  • packages/core/test/preload.test.ts is unchanged. OPENCODE_TEST_HOME is set by packages/core/script/test.ts, not by packages/core/test/preload.ts. Raw bun test fails that assertion on integration-v2 as well. bun run test from packages/core is the entrypoint that sets the home.
  • packages/tui/test/component/dialog-shell-output.test.tsx is unchanged versus integration-v2. Catalog @opentui/* did move from 0.5.14 to 0.5.17, so a base checkout that still uses this branch’s node_modules does not separate an OpenTUI hang from a slow VM.
  • The CLI react/jsx-dev-runtime failures follow packages/cli/bunfig.toml (preload = ["@opentui/solid/preload"]), which Bun applies when cwd is the package. That file is unchanged, and launching packages/cli/src/index.ts from another directory fails the same way on the base.

Conflict resolutions I checked and did not find a defect in: bun.lock still has the four @shuvcode/* plugins and shuvcode@2.0.25-shuv.1; bunfig.toml unions the release-age excludes; packages/cli/package.json name and bin stay shuvcode; the stale-binary check in launcher.mjs fails closed and postinstall.mjs stays deleted; uninstall drops curl shell-profile cleanup and keeps data, config, and state; generated client types keep experimental.jev and add integration.connect.external; migrations stay id-ordered (20261005094821_subagent-operation, then the Azure data-only UPDATE); integration.ts keeps the refresh lock and access-only import refusal and refreshes only oauth. Follow-ups 2c886758ba and 741e82685e narrow external credentials in the importer, Claude subscription detection, and quota key matching, and acp --login calls login.default without the removed per-command server flags.

Release builds claim the shuvcode route on https://shuv.zip instead of OpenCode's shared opencode route. The OpenTunnel SDK stays, patched onto the shuvtunnel subprotocol, API, and profile directory.
Pairing recovery text in the CLI, embedded web UI, and desktop pairing page names the shuvcode binary.
The auth method clients display now says Login with Shuvcode. The method id stays opencode-login.
The handshake uses the existing app name instead of the hardcoded opencode client name from the upstream sync.
Branch names with a slash become valid preview version identifiers, matching upstream anomalyco#53461, while explicit channels and detached-HEAD failure stay as they are.
@shuv1337

shuv1337 commented Oct 8, 2026

Copy link
Copy Markdown
Owner Author

Follow-up on the review. Five commits on this branch, no rebase:

  • 56f082dfd3 OpenTunnel → ShuvTunnel. @opentunnel/client@0.2.0 is wire-compatible with shuv1337/shuvtunnel (same /api/tunnel paths and bridge frames; Effect 4.0.0-rc.112 matches this repo, while @shuvtunnel/client is on Effect beta and is not published). Two bun patches retarget it: subprotocol shuvtunnel, default API https://shuv.zip, profile directory shuvtunnel. The bridge URL is wss://<api>/api/tunnel/:id/connect (the TCP relay stays wss://shuv.zip/api/relay on the server). SHUVTUNNEL_API and SHUVTUNNEL_PROFILE override the API and profile. Routes are shuvcode on the latest channel and shuvcode-<channel> otherwise, so a release build no longer claims OpenCode's opencode route. shuv.zip returned HTTP 200.
  • 921ba6d4d3 Pairing hints. CLI recovery (shuvcode pair --remote, shuvcode service set remote true), the embedded web UI (English and the existing locale strings that named the command), the desktop pairing listen command (shuvcode service set hostname 0.0.0.0), and the app README now name shuvcode.
  • b76fda012d ACP auth name. Display name is Login with Shuvcode. Method id stays opencode-login. Session test updated.
  • 1e15f94d59 MCP client name. packages/server/src/routes.ts reports Global.app (shuvcode) instead of the hardcoded opencode from fix(server): always report opencode as mcp client name anomalyco/opencode#53471.
  • 119a26e147 Preview channels. Fork resolveChannel now applies fix(script): normalize local build channels anomalyco/opencode#53461: characters outside [A-Za-z0-9._-] become -, and a leading non-alphanumeric is prefixed with branch-. Explicit OPENCODE_CHANNEL and detached-HEAD failure are unchanged. cursor/sync-upstream-v225-9a24 becomes a valid 0.0.0-cursor-sync-upstream-v225-9a24-<build>.

services/www docs still describe the upstream opencode CLI. That site is outside fork publish. No packages were published and no secrets were added. bun run check on push: typecheck 41/41. Affected tests: remote-tunnel, ACP session, script channel, and pairing link all passed.

@shuv1337

shuv1337 commented Oct 8, 2026

Copy link
Copy Markdown
Owner Author

🔍 Automated Cursor re-review of the fix commits (56f082d..119a26e) is underway. Please hold off on merging until the "Review complete:" comment lands here.

@cursor

cursor Bot commented Oct 8, 2026

Copy link
Copy Markdown

Review complete: No High or Medium findings. Remote access on this head talks to ShuvTunnel, not OpenCode's shared tunnel.

The patched @opentunnel/client@0.2.0 matches the current shuvtunnel server on the wire. The bridge control schema, HTTP paths (POST /api/tunnel, certificate, connect), bearer auth, and profile files (tunnel.json, token, private-key.pem, certificate.pem, chain.pem) are the same. The patches only change the default API to https://shuv.zip, the profile directory to $XDG_DATA_HOME/shuvtunnel, and the WebSocket subprotocol to shuvtunnel. There is no fallback read of ~/.local/share/opentunnel. I created a tunnel on https://shuv.zip and got a *.shuv.zip hostname, the bridge opened with subprotocol shuvtunnel, and opentunnel was rejected. The tunnel was deleted afterward. packages/cli/src/services/remote-tunnel.ts passes https://shuv.zip unless SHUVTUNNEL_API is set, so a missing client-default patch still does not call opentunnel.xyz. Both patches are in root patchedDependencies and bun.lock. Publish installs with bun install --frozen-lockfile and then compiles a binary that bundles the client (external is only node-gyp). The published npm package does not depend on @opentunnel/client. services/www is outside the fork publish set in packages/cli/script/publish-ownership.ts.

Route shuvcode on latest, and shuvcode-<channel> otherwise, does not collide with OpenCode's opencode route. The tested channels are valid DNS labels. ACP shows "Login with Shuvcode" and keeps method id opencode-login. That assertion fails on 741e826. The server MCP handshake uses Global.app, which is "shuvcode". resolveChannel applies the same sanitizer as upstream anomalyco#53461 to inferred branch names, including slash branches, and leaves an explicit OPENCODE_CHANNEL alone, so release CI is unchanged. The slash-branch test fails on 741e826. bun typecheck passed in packages/script, packages/util, packages/server, and packages/cli. The remote-tunnel and ACP session tests pass on this head.

Low: Several locales still tell the user to scan an OpenCode pairing command, because the rename only replaced the literal opencode pair token. English still says OpenCode in the same errors at packages/app/src/runtime/i18n/en.ts:360 and packages/app/src/runtime/i18n/en.ts:366. Locales that translated the command were missed: packages/app/src/runtime/i18n/bn.ts:798, dv.ts:817, hi.ts:798, ko.ts:806, lo.ts:791, ms.ts:796, my.ts:811, ne.ts:798, pa.ts:804, pl.ts:821, ru.ts:877, ur.ts:805, and vi.ts:802.

Low: shuvcode pair --remote help still names the wrong service at packages/cli/src/commands/commands.ts:513 ("Pair through the OpenTunnel remote address").

Low: The server handshake is fixed, but other MCP client identities are still hardcoded opencode. The connect default is packages/core/src/mcp/client.ts:152. OAuth registration uses client_name: "opencode" and client_uri: "https://opencode.ai" at packages/core/src/mcp/oauth.ts:183, and the unauthenticated initialize probe uses clientInfo: { name: "opencode" } at packages/core/src/mcp/oauth.ts:415. The editor socket does the same at packages/tui/src/context/editor.ts:228.

@shuv1337
shuv1337 merged commit cc86ee7 into integration-v2 Oct 8, 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.