Skip to content

[Feature] Sync upstream opencode v1.4.6 → v1.4.11 (graft + multi-PR) #27

@Astro-Han

Description

@Astro-Han

What task are you trying to do?

Keep PawWork's vendored copy of packages/opencode and shared infrastructure in lockstep with upstream anomalyco/opencode so we do not accumulate architectural drift. The foundation strategy is now stable: opencode remains the foundation until PawWork crosses 10K users. We do not have the team to fork the foundation; staying current is non-negotiable infrastructure work.

This issue tracks the first full sync cycle from our fork point (v1.4.6 area) to upstream v1.4.11, which contains 309 commits including namespace unwrap, zod -> Effect Schema migration, HttpApi route changes, and workspace control-plane refactors.

What do you do today?

We previously used a pinned vendor fork plus selective cherry-picks. That worked for one cycle but is no longer enough. Skipping the architectural migrations now would make every future cherry-pick pay import-path, schema-shape, and route-contract translation cost.

A second structural problem is history shape. Our initial commit bde4c3927 initial: based on OpenCode (MIT License) is an orphan snapshot import, not a normal fork. A naive merge against upstream creates hundreds of false add/add conflicts.

What would a good result look like?

After this issue closes:

  • packages/opencode and shared infrastructure reflect upstream v1.4.11 semantics
  • UI rewrite carve-out paths stay on HEAD and are still owned by #26
  • PawWork history keeps only PawWork-authored commits, not upstream contributor history
  • Future syncs can reuse the same graft + squash workflow with smaller marginal cost
  • Phase 1 macOS GUI flows still work end to end

The workflow itself lives in docs/upstream-sync.md. This issue tracks live status and lane ownership, not the whole protocol.

Live status

# Branch Status
1 sync/setup done locally
2 sync/opencode-tool merged as #31
3 sync/opencode-provider-plugin merged as #33
4 sync/opencode-provider-runtime-bridge merged as #34
5 sync/opencode-runtime-core merged as #36
6 sync/opencode-cli-core merged as #46
7 sync/opencode-tui-compat last; scope decided from live bun run typecheck output after PR 8 merges
8 sync/opencode-session next main lane
9a sync/opencode-foundation-tail merged as #48
9b sync/nonui-primitives merged as #49
9c sync/desktop-app merged as #47

Execution plan

  1. PR 8 sync/opencode-session is now the next main lane. It starts after PR 6 and PR 9a and does not depend on packages/app, packages/ui, or packages/desktop-electron.
  2. PR 7 sync/opencode-tui-compat stays last. Decide exact scope from live typecheck after PR 8. Do not assume a cheap path-only tsconfig exclude is a safe fallback.
  3. Any remaining branch should refresh from dev before final push. If bun.lock moved, regenerate it with bun install; do not hand-merge lockfile diffs.

Lane ownership after PR 5

  • PR 6 sync/opencode-cli-core: packages/opencode/src/cli/** excluding src/cli/cmd/tui/**, plus packages/opencode/test/cli/run.test.ts
  • PR 9a sync/opencode-foundation-tail: remaining opencode-internal non-session foundation, specifically src/{provider,plugin,control-plane,file,mcp,project}/**, src/index.ts, and matching tests under test/{provider,plugin,file,mcp,project}/**
  • PR 9b sync/nonui-primitives: packages/ui/**, packages/util/**, packages/plugin/**, packages/function/**, packages/sdk/**
  • PR 9c sync/desktop-app: packages/app/package.json, packages/app/src/{context,types}/**, packages/desktop-electron/**

The current live dev..v1.4.11 diff makes PR 6, PR 9a, PR 9b, and PR 9c file-disjoint. That disjointness is the reason this plan is faster. If a later refresh shows overlap, re-cut before editing instead of relying on spillover.

Which audience does this matter to most?

Both. The upstream fixes in v1.4.7 to v1.4.11 affect user-visible behavior, and the architectural sync is what keeps the foundation maintainable.

Acceptance criteria

After all remaining sync PRs merge:

  • bun install clean
  • bun run build for packages/opencode succeeds
  • bun run typecheck passes across shipped packages
  • Electron app boots and first-message -> AI response works
  • Existing tests do not regress, or removed tests are intentionally removed and documented
  • git replace -l returns empty after final cleanup
  • No upstream contributor appears in git log dev for the sync window
  • UI rewrite carve-out is respected: no sync-attributable changes under packages/app/src/{components,pages,styles,theme,i18n}

Out of scope

  • TUI / ghostty / Windows-specific UX as product surface
  • UI rewrite itself, which belongs to #26
  • Workspace remote / control-plane activation beyond the inert foundation needed for sync
  • Telemetry activation; upstream OTel code may land inert, but product analytics decisions stay separate

Extra context

  • Workflow doc: docs/upstream-sync.md
  • Cross-link: #26
  • docs/TODO.md upstream sync entry

Metadata

Metadata

Assignees

No one assigned

    Labels

    P1High priorityenhancementNew feature or requestupstreamTracked upstream or vendor behavior

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions