refactor(provider-opencode): move OpenCode into its own provider package#17345

merged3
main
t3/provider-opencode
opened22d agobyJJulius Marminge
View on GitHubTwo-way sync enabledPR last imported 10d ago

OpenCode (1.x and 2.x) was the next provider still living inside apps/server. This moves it into @t3tools/provider-opencode, using the same layout as Pi and Muse.

Package

  • ./settings: OpenCodeSettings, moved out of contracts.
  • ./client: label, settings form, and a plain-data glyph. Web and mobile now draw the package icon, so the hand-drawn OpenCodeIcon and the mobile branch are gone. The collapsed composer's monochrome icon now clears any package icon's per-path detail fill (data-icon-detail), not just OpenCode's own data-opencode-hole.
  • ./server: OpenCodeDriver, OpenCodeAdapterV2Driver, and the OpenCodeRuntime/OpenCodeServerLedger layers the server provides once.
  • ./testing: the 2.x client, server, adapter, and text generation that the server's replay testkits drive.

Boundaries

  • The adapters, driver, and text generation reach the server only through ProviderHost (cwd and attachment paths) instead of ServerConfig and attachmentStore. The server ledger takes its stateDir as layer input.
  • Shared helpers move with it: writeFileStringAtomically goes to @t3tools/shared/atomicWrite; native protocol log summaries and subagent projection helpers go to provider-core.
  • Service keys follow the package path.
  • Replay testkits, the replay-backed adapter and title tests, and the event-recording test stay in the server, because they need the orchestrator harness and the shared fixtures. Everything else (driver, status, runtime parsers, ledger, owner, version probe, 1.x adapter and text generation, 2.x client and server) runs in the package with layerTestProviderHost.

Verification

  • Typecheck: provider-opencode, provider-core, provider-testing, shared, contracts, server, web, mobile, desktop, client-runtime.
  • Tests: the package's tests, the OpenCode 2 adapter, orchestrator replay and title-generation tests, provider registry tests, the subagent projection, atomic write, and web/mobile provider icon tests.
  • vp lint, knip:check workspaces.

Stack: #17330 → #17331 → #17345 → #17349 → #17354 → #17357.

Done by Claude Opus 5.5 in Claude Code.

🤖 Generated with Claude Code


Devin Review

Checks

24 successful · 10 skipped
All checks passed
b64bda7
Synced from GitHub

Thread transfer impact

✅ Thread transfer remains within every enforced ceiling.

ProviderMetricMain baselineThis PRImpactPR ceiling
CodexTotal thread wire5.0 KiB5.0 KiB0 B (0.0%)6.8 KiB✅
CodexThread snapshot wire3.8 KiB3.8 KiB0 B (0.0%)4.9 KiB✅
CodexLive turn WebSocket wire1.2 KiB1.2 KiB0 B (0.0%)2.0 KiB✅
CodexLive turn WebSocket decoded20.9 KiB20.9 KiB0 B (0.0%)29.3 KiB✅
CodexLive turn messages220 (0.0%)8✅
ClaudeTotal thread wire5.0 KiB5.0 KiB−24 B (−0.5%)6.8 KiB✅
ClaudeThread snapshot wire3.8 KiB3.8 KiB0 B (0.0%)4.9 KiB✅
ClaudeLive turn WebSocket wire1.2 KiB1.2 KiB−24 B (−2.0%)2.0 KiB✅
ClaudeLive turn WebSocket decoded21.2 KiB21.2 KiB−41 B (−0.2%)29.3 KiB✅
ClaudeLive turn messages21−1 (−50.0%)8✅

Baseline: 2c7a446 · PR result: b64bda7 · Source CI: success

Scenario and decoded snapshot size

10 historical turns, 5 command tools per turn, 878.9 KiB retained MCP result per historical turn, and a 1.05 MiB retained result in the measured turn.

  • Codex decoded thread snapshot: 108.5 KiB
  • Claude decoded thread snapshot: 108.8 KiB

Updated in place by a trusted workflow. PR artifacts are strictly validated and never executed.

packages/provider-opencode/src/server/adapter.tsline 444Outdated · 07e04c1Open thread
……@@ -440,7 +441,7 @@ export interface OpenCodeAdapterV2Options {
441442 readonly runtime: OpenCodeRuntime.OpenCodeRuntimeShape;
442443 readonly idAllocator: IdAllocator.IdAllocatorV2Shape;
443- readonly serverConfig: ServerConfig.ServerConfig["Service"];
444+ readonly host: ProviderHostShape;
MmacroscopeappBoton line 44422d ago

ProviderHost is an Effect service, but the refactored adapter now accepts its service shape as a factory argument and production construction passes the acquired instance through. Could you make the factory acquire ProviderHost from the Effect environment instead, and expose that requirement in its type? Tests can still provide a test layer. This avoids introducing another explicitly injected service dependency at the new package boundary.

Posted via Macroscope — Effect Service Conventions

Keeping this as is. makeOpenCodeAdapterV2 was already a plain factory taking acquired services (runtime, idAllocator, and serverConfig: ServerConfig["Service"] on main); this PR only swaps serverConfig for host. The Effect-environment requirement is exposed where it belongs: OpenCodeAdapterV2Driver.create yields ProviderHost and lists it in OpenCodeAdapterV2DriverEnv. The same shape is already on main for Pi and Muse (host: ProviderHostShape), and the plain factory lets the replay testkit and unit tests build an adapter without a layer.

Correction to my reply above: this does go against our Effect service guidelines (dependencies come from the environment, not as parameters to make). It's deferred on purpose, not dismissed. The provider-packages stack keeps the existing argument-passing shape so the layers can merge quickly, and one follow-up after the stack lands will make every adapter factory yield* ProviderHost (and its other services) and rename ProviderHostShape to ProviderHost["Service"].

Synced from GitHub

Approvability

Verdict: Approved at 99208f0

Macroscope's review found this PR approvable — This is a behavior-preserving refactor that moves the existing OpenCode implementation, settings, tests, and icon into a dedicated provider package. Runtime wiring preserves the prior paths, attachment handling, ledger lifecycle, defaults, and UI glyph while updating imports and package boundaries.

No code changes detected at b64bda7. Prior analysis still applies.

You can add or adjust custom eligibility rules. Learn more.

Synced from GitHub

Review in Change Stack →

Note

Reviews paused

It looks like this branch is under active development. To avoid overwhelming you with review comments due to an influx of new commits, CodeRabbit has automatically paused this review. You can configure this behavior by changing the reviews.auto_review.auto_pause_after_reviewed_commits setting.

Use the following commands to manage reviews:

  • @coderabbitai resume to resume automatic reviews.
  • @coderabbitai review to trigger a single review.

Use the checkboxes below for quick actions:

  • ▶️ Resume reviews
  • 🔍 Trigger review

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration
  • Configuration used: Path: .coderabbit.config.ts
  • Review profile: CHILL
  • Plan: Team
  • Run ID: 1d0386d9-4987-4933-be1c-1b7d5ad73fd5
📥 Commits

Reviewing files that changed from the base of the PR and between 7b0dda5c177cb50bc8ef7f53b33b14bf316290a2 and 99208f01cad5579e634d875093ba5476febd687d.

📒 Files selected for processing (9)
  • packages/provider-opencode/src/server/OpenCodeRuntime.cliParsers.test.ts
  • packages/provider-opencode/src/server/OpenCodeRuntime.permissions.test.ts
  • packages/provider-opencode/src/server/adapter.test.ts
  • packages/provider-opencode/src/server/adapter.ts
  • packages/provider-opencode/src/server/driver.ts
  • packages/provider-opencode/src/server/textGeneration.ts
  • packages/provider-opencode/src/server/v2/OpenCode2Server.ts
  • packages/provider-opencode/src/server/v2/adapter.ts
  • packages/provider-opencode/src/server/v2/textGeneration.ts
🚧 Files skipped from review as they are similar to previous changes (2)
  • packages/provider-opencode/src/server/adapter.test.ts
  • packages/provider-opencode/src/server/adapter.ts

Limit details: You’ve used all 10 included reviews currently available.


📝 Walkthrough

Walkthrough

The OpenCode implementation and settings now live in @t3tools/provider-opencode, which mobile, web, and server consume through package exports. Its server adapters use ProviderHost for working-directory and attachment resolution. Shared utilities and server consumers use workspace package exports.

Changes

OpenCode provider package

Layer / File(s)Summary
Package contracts and provider registration
packages/provider-opencode/*, packages/contracts/src/settings.ts, apps/mobile/*, apps/web/*, apps/server/package.json, package.json, docs/internals/*, scripts/release-smoke.ts
Adds the OpenCode package manifest, settings schema, client, and exports. Mobile and web register the client and update icon rendering. The OpenCode settings schema is removed from contracts. Workspace manifests, docs, and release-smoke inputs are updated.
OpenCode server implementation and ProviderHost integration
packages/provider-opencode/src/server/*
Moves server dependencies to package-local settings and modules. Drivers and adapters use ProviderHost for working directories and attachment resolution. The ledger layer accepts an explicit stateDir. Related tests use provider-host test layers.
Shared exports and consumer imports
packages/shared/*, packages/provider-core/*, apps/server/src/cli/*, apps/server/src/device/*, apps/server/src/keybindings.ts, apps/server/src/provider/*, apps/server/src/orchestration-v2/*, apps/server/src/server*, apps/server/src/telemetry/*, apps/server/src/usage/*, apps/server/src/mcp/*
Exports atomic writing, native protocol logging, and subagent projection from shared packages. Server consumers import these modules through package exports.
Server wiring and provider-package consumers
apps/server/src/server.ts, apps/server/src/provider/*, apps/server/src/orchestration-v2/*, apps/server/src/textGeneration/*
Server runtime and registries use OpenCode package exports. Orchestration and provider tests use package imports. OpenCode replay testkits use provider-host test layers.

Priority: ⬇️ Low

Estimated code review effort: 4 (Complex) | ~45 minutes

Change: Refactor

Merge Risk: ⚪ Minimal · up to 99208

OpenCode continues to receive its configured working directory and attachment resolver. No concrete user-facing or operational issue remains that warrants delaying merge.

🚥 Pre-merge checks | ✅ 4
✅ Passed checks (4 passed)
Check nameStatusExplanation
Title checkPassedThe title clearly and concisely describes the primary change: moving OpenCode into its own provider package.
Description checkPassedThe description explains the refactor scope, package boundaries, architectural changes, and verification performed. It is mostly complete, although it does not explicitly include a separate Problem se…
Linked Issues checkPassedCheck skipped because no linked issues were found for this pull request.
Out of Scope Changes checkPassedCheck skipped because no linked issues were found for this pull request.
✨ Finishing Touches 💡 1
🛠️ Fix failing CI checks 💡
  • Commit to this branch
  • Create a new PR
📝 Generate docstrings
  • Commit to this branch
  • Create a new PR
🧪 Generate unit tests (beta)
  • Commit to this branch
  • Create a new PR
  • Autopilot · Keep fixing CodeRabbit findings and required CI, and resolving merge conflicts

Comment @coderabbitai help to get the list of available commands.

Added 3 commits

  • refactor(provider-opencode): import OpenCode services as namespaces06fd4da
  • refactor(provider-opencode): move OpenCode into its own provider package1124f58
  • refactor(provider-opencode): namespace-import service modules everywhereb64bda7