feat(opencode): migrate CodeNomad to native V2 - #647
Conversation
Replace the V1 SDK, custom plugin, and per-workspace runtimes with the pinned OpenCode V2 client and one shared service. Model workspaces through native locations and route sessions, messages, events, files, VCS, permissions, questions, providers, commands, and MCP directly through V2 APIs. Remove the legacy plugin and background-process layers, use native Shell and PTY support, preserve server-side Git mutations where V2 lacks parity, and update the UI, packaging, CI, architecture documentation, and translations for the new model. Add focused coverage for shared-service ownership, Windows and WSL startup, proxy boundaries, worktree event routing, native event normalization, provider authentication, voice instructions, and location-scoped requests. Server and UI typechecks pass; remaining security review items and the real opencode2 smoke test are documented in MIGRATION_V2.md and will be completed before the draft PR is marked ready.
Remove the duplicate Tauri native event transport and use the server EventSource stream consistently across web, Electron, and Tauri clients. Align the generated client and required opencode2 CLI on next-17353. Restrict workspace proxying to the required V2 API surface, enforce session and directory ownership, validate local file URIs, strip routing headers, and tighten provider, Yolo, worktree, and session event state handling. Protect the shared service lifecycle with private registration state, process-identity leases, safe ownership transfer, bounded shutdown, Windows executable resolution, and WSL namespace-aware PID verification. Unknown wrappers now fail closed rather than leaving an unowned service. Validated with server and UI typechecks, 433 UI tests, focused server lifecycle and proxy suites, 67 Rust tests, server and UI builds, and a real next-17353 service lifecycle smoke test.
Treat the persisted V1 default command 'opencode' as 'opencode2' so restored and newly selected workspaces use the required V2 service instead of waiting for the obsolete binary to time out. Keep the folder selection view mounted while startup restore is active and feed it the existing loading state, preventing the renderer from appearing blank while saved workspaces are recreated. Cover the legacy binary setting and restore loading gate with regression tests. Server/UI typechecks, targeted restore tests, the UI production build, and a real lifecycle smoke from an 'opencode' configuration pass.
Load sessions from each logical root and worktree using the native V2 directory filter, preserve locally known sessions when a combined response may be incomplete, and resolve locationless events through their session IDs. This restores worktree sessions, prompt activity, and deletion updates without reintroducing the removed transport. Require the bundled OpenCode prerelease for shared-service discovery and surface structured prompt errors. Move Electron and Tauri restore state and election files under the V2 namespace, copying V1 state once without mutating or deleting the legacy files. Cover multi-directory loading, locationless event routing, version-constrained discovery, and cross-host state isolation. Validated UI, server, Electron, and Tauri tests and built the Tauri release executable and NSIS installer.
Restore reliable V2 catalogs, agent identifiers, cursor pagination, prompts, variants, attachments, forms, native event reconciliation, Yolo persistence, and location-aware PTY controls. Prevent completed control records from appearing as streaming placeholders and keep live output refreshing during sustained token streams. Harden the shared service and workspace proxy with explicit OPENCODE_DB isolation, launch-signature validation, traversal protection, WSL namespace translation, ownership-scoped routes, bounded SSE backpressure, reconnect recovery, and safe process-proof transfer and shutdown semantics. Align provider, VCS, LSP, update, documentation, and CI behavior with the experimental next-17353 contract. Validation includes server/UI/Electron typechecks, 252 workflow UI tests, focused server suites, production UI/server builds, 68 Tauri tests, and a real V2 workspace/session/prompt smoke.
Merge upstream dev into the OpenCode V2 foundation while preserving native V2 session, provider, proxy, PTY, and explicit database behavior. Resolve desktop workspace-open and provider visibility conflicts across Electron and Tauri, bound local API requests, refresh standalone dependency locks, and keep grouped integration preferences keyed by native provider IDs. Validated with desktop typechecks, 267 UI tests, 308 server tests, 122 Electron tests, 74 Tauri tests, packaged builds, and an exact OpenCode 0.0.0-next-17353 Tauri smoke covering prompt, reload, agent fallback, and PTY lifecycle.
|
Updated validation after commits 9a53e2f, e996196, and 04cb287. The V2 runtime now uses @opencode-ai/client, protocol, and schema 0.0.0-next-17444, accepts the discovered current opencode2 CLI instead of enforcing an exact runtime version, and uses ~/.local/share/opencode2/opencode.db. Targeted manager/service tests, server/UI typechecks, packaged resources, and the Tauri 0.19.0 release build passed. Real desktop smoke reused three existing sessions from the copied V2 database and received V2_EXISTING_SESSION_ONE_OK, V2_EXISTING_SESSION_TWO_OK, and V2_EXISTING_SESSION_THREE_OK. Windows V1 and V2 now use distinct WebView2 profiles; with both applications running, the final V2 build opened D:\CodeNomad and D:\openchamber sequentially without dialogs, toasts, CDP exceptions, or server errors. Nine native shutdown tests also passed. The PR remains open until V2 is out of beta. |
Force the V2 service to use the opencode2 database under the current user's data directory so parallel V1 launches cannot redirect it through shared environment settings. Keep the bare opencode and opencode2 commands out of custom binary history while preserving real executable paths, and document the parallel desktop smoke procedure. Existing history entries are intentionally left untouched for manual cleanup. The server manager test and typecheck passed, and the Tauri package built successfully before the final UI-only simplification. No additional compilation was run per request.
Update the experimental OpenCode client, protocol, and schema dependencies to the latest reviewed next release while removing the exact CLI version gate from shared-service discovery. This lets CodeNomad use current opencode2 releases instead of timing out solely because the runtime advanced. Refresh migration, contributor, architecture, and skill guidance to require release-note, documentation, declaration, and proxy-parity review on each upgrade. The isolated opencode2 database behavior is documented consistently. Validated with server and UI typechecks, 36 passing targeted service/workspace tests, a release Tauri build, and a packaged desktop smoke. The smoke opened D:\CodeNomad, reused three existing sessions, and received three distinct exact prompt responses from opencode2 next-17444.
Give the V2 desktop runtime its own WebView2 user-data folder so it cannot reuse V1 service workers, browser caches, or locked profile state. Preserve an explicitly supplied WEBVIEW2_USER_DATA_FOLDER for debugging and custom launches. Defer installation of the Windows session-end subclass until the main thread can provide a native window handle, preventing startup from aborting during slower WebView creation. Validated with nine shutdown tests, a release build, simultaneous V1/V2 WebView processes using distinct data folders, and sequential CodeNomad/openchamber workspace launches without UI or runtime exceptions.
Keep established conversations mounted while V2 performs authoritative message refreshes. Background loads no longer insert the initial loader or clear timeline segments, preventing the measured prompt displacement and timeline flicker during native streaming. Restore saved sessions directly before the expensive all-worktree session scan, while preserving every referenced draft, attachment, scroll, expansion, idle, and generation record. Make workspace readiness follow newer reconnect loads without leaking waits after cancellation, and exclude synthetic views from native session hydration. Harden question interruption races by rebinding requests when authoritative tool parts arrive late or replace optimistic parts, and clear inline question state immediately after reply or rejection. Isolate PTY loading reads from Solid effects to prevent recursive reload storms. Add focused regressions to the PR workflow. Validated with 223 standard UI tests, 58 browser-condition tests, full TypeScript checks, 307 server tests, 74 Rust tests, 28 Windows spawn tests, a production Tauri build, and real cold-start state restoration.
Apply OpenCode V2 text and reasoning delta events directly to the normalized message store so assistant responses appear as they are generated instead of waiting for periodic HTTP snapshots. Deduplicate replayed events, preserve ordinal part ordering, reconcile stale or superseded snapshots, settle terminal messages, retry failed terminal refreshes, and clear streaming state when sessions or workspaces are removed. This keeps snapshot refreshes as authoritative recovery without erasing visible streamed content or recreating removed stores. Add focused streaming regression coverage and extend native event tests for immediate text, reasoning, periodic refresh behavior, replay handling, deletion cleanup, and terminal reconciliation. Validated with 223 standard UI tests, 64 browser/integration tests, full workspace typechecks, a production Tauri build, and a live CDP smoke covering progressive rendering and reload restoration.
Align the V2 delta reducer with the live OpenCode contract, where many unique events append to the same message, content type, and ordinal. Keep one provisional part per source part instead of treating ordinals as fragment sequence numbers. Render the first fragment immediately, then coalesce subsequent store and Markdown updates to one 16 ms window. Flush pending content before terminal reconciliation, preserve authoritative snapshot IDs and error states, cancel timers on session or workspace cleanup, and retain bounded replay protection. Validated against a live 1,485-event response that streamed 100 lines and 6,387 characters continuously to completion. Added repeated-ordinal, timer, snapshot, tool-boundary, cleanup, terminal, and error regressions; all 223 standard UI tests, 72 browser/integration tests, and workspace typechecks pass.
Keep follow ownership tied to explicit user intent so Virtua measurement corrections cannot silently escape an actively followed response. Large key jumps now land immediately, while explicit timeline and top navigation cancel submit pinning without confusing programmatic movement for user scrolling. Rebuild timeline segments from cached V2 structural signatures instead of part-count and same-length replacement heuristics. This handles provisional-to-authoritative part replacement, type and renderability changes, terminal status updates, locale changes, duplicate part IDs, and the V2 time.completed contract without rebuilding streamed text on every token. Add follow-state, timeline projection, and duplicate-part regression coverage to the PR workflow. Validated with 264 standard UI tests, 72 browser/integration tests, full UI and Electron typechecks, production UI build, and live Tauri WebView navigation/follow scenarios.
Preserve the last authoritative non-empty tab snapshot through native shutdown, make shutdown capture terminal, and restore the exact saved active tab. Seed scroll snapshots before session selection and wait for usable Virtua measurements so project, tab, session, and anchor position survive A/B restarts. Render native runtime forms inline only when their active-session tool target is resolved, retain the floating fallback for unresolved requests, share form schema visibility and URL validation with provider auth, and remove the unused session form-list proxy route and obsolete V1 request wrapper. Return the native V2 session.active map without a legacy data envelope, avoid full-history refreshes for deltas already applied locally, and bound timeline projection refreshes during streaming. Coverage includes UI restoration, form targeting, proxy contracts, native streaming, and CI test registration. Validated with root typecheck, 529 UI tests, 305 passing server tests with 3 skips, 74 Tauri tests, 122 Electron native tests, production A/B builds, a no-seed native handoff, and runtime verification of the active-session proxy shape.
Attempt configured WSL host-to-service translation before treating POSIX paths as already service-native. This preserves real Windows behavior while allowing Linux CI to exercise Windows workspace ownership with temporary git worktrees. Remove the environment-dependent assertion that a bare opencode2 command resolves to a packaged executable. Deterministic shim coverage remains in buildServiceLaunchSpec and the Windows PATH/PATHEXT tests. Validated with full typecheck, 27 spawn tests, 9 workspace manager tests, and the complete server suite with 304 passing tests and 3 skips.
Stop deleting OPENCODE_DB from legacy CodeNomad environment preferences during settings layout migration. Environment variables now migrate uniformly without a database-specific exception. The OpenCode V2 service destination remains unchanged and continues to use ~/.local/share/opencode2/opencode.db through the launch-time service environment override. Validated with the settings migration test, root typecheck, the complete server suite, and git diff --check.
When a native V2 form resolves to a tool call, render it as the sole interactive surface and suppress the legacy QuestionToolBlock for that call. Legacy questions remain available when no native form is pending, while unresolved and cross-session forms continue to use the existing floating fallback. Improve the native form hierarchy with token-based panel and field surfaces, explicit required and focus states, consistent checkbox controls, square action buttons, and responsive stacked actions on narrow screens. Validated with UI typecheck, 530 UI tests, a production desktop build, git diff checks, and desktop/mobile inspection in the deployed WebView.
Render native V2 string option lists with up to four answers as visible radio cards, including each option description, so question-style forms retain the scannable V1 interaction. Lists with five or more answers continue to use a compact select control. Apply the same selected-card treatment to multiselect answers, preserve custom-value entry, validate required inline strings, and keep grouped controls accessibly labelled. Option styling lives in a focused component stylesheet and uses existing square-corner design tokens. Validated with UI typecheck, 531 UI tests, a production desktop build, git diff checks, and visual inspection in the deployed WebView.
Electron and Tauri can each publish a legacy running marker immediately before publishing their shared cross-host participant. On a simultaneous Windows startup, both hosts could observe that transient gap and yield ownership, leaving no primary. When legacy detection initially blocks a primary candidate, wait for one bounded 50ms participant grace period and reconcile once before yielding. Apply the same protocol on both Node and Rust hosts; genuine legacy clients still block ownership after the grace period. Validated with root typecheck, 50 repeated cross-host election runs, 122 Electron native tests, 74 Tauri tests, and git diff checks.
A session can mount from startup discovery before native workspace restoration seeds its saved scroll snapshot. The message stream previously marked that no-snapshot pass complete and ignored the authoritative seed when it arrived, leaving Virtua at the top despite a valid anchor. Track no-snapshot completion as provisional and permit exactly one later restore when the reactive seed appears. Normal completed restores remain terminal, and session changes reset the provisional authority. Validated with UI typecheck, 48 targeted restoration tests, 532 complete UI tests, and git diff checks.
The Tauri client-state tests exercise process-global file locks and invoke PowerShell/CIM for process identity. Running them concurrently on the shared Windows runner can starve those probes, causing both cross-host election and bounded registration timing assertions to fail together despite passing independently. Run the 74-test Windows Tauri suite with one test thread. Linux coverage remains parallel, and product-side participant reconciliation remains covered by repeated cross-host tests. Validated with the exact serial Windows cargo command: 74 passed, 0 failed.
The Tauri macOS ARM prebuild combines DOM and Node timer declarations, so injected and global setTimeout implementations can return either a numeric browser handle or a Node Timeout. The previous inferred alias accepted only the Node variant and failed server compilation on that matrix leg. Represent the manager timer handle as the actual portable union and avoid Array.prototype.at in a server test because the server TypeScript target predates ES2022. Validated with the complete server build, 304 passing server tests with 3 platform skips, 11 targeted workspace tests, and git diff checks.
|
PR builds are available as GitHub Actions artifacts: https://github.com/NeuralNomadsAI/CodeNomad/actions/runs/32124483864 Artifacts expire in 7 days.
|
Real question-backed V2 forms set custom=true. The long-option branch therefore bypassed the intended select and rendered a text input with a datalist, so the tested 4/5 threshold did not hold for actual native requests. Render every long option list as a select regardless of custom-value support, and preserve free-form answers in a separate custom input. Short lists remain visible cards. Validated against a live four-option V2 form, targeted form tests, the UI typecheck, 532 UI tests, and git diff checks.
OpenCode SDK location responses expose workspaceID, while generated request inputs require workspace. Passing a response LocationRef directly was structurally accepted by TypeScript but caused the generated client to omit the workspace selector from catalog requests. Centralize the output-to-request conversion and apply it to agent, provider, model, default-model, and command catalog calls. Internal session state continues using the SDK response shape. Validated with 21 targeted request-authority tests, the UI typecheck, 533 UI tests, and git diff checks.
Volatile V2 events previously refreshed every catalog, metadata, and filesystem domain. Even an agent or command update therefore caused unrelated API requests and cache invalidation, with a trailing full rerun when events overlapped. Map each native event to the state domains it can affect and merge pending domains in one coordinator. Reconnects retain a complete refresh, while agent, command, integration, metadata, filesystem, and VCS events now update only their relevant stores. Validated with 21 targeted invalidation and request-authority tests, the UI typecheck, 535 UI tests, and git diff checks.
The instance bridge duplicated every OpenCode event payload into a synthetic properties field because server-side auto-accept still consumed the V1-style envelope. This expanded the SSE contract and left UI deletion handling with legacy fallbacks. Move auto-accept and session deletion to native event.data, publish OpenCode events unchanged, type the shared stream as OpenCodeEvent, and guard PTY consumers before narrowing their event union. Internal CodeNomad worktree events remain separate. Validated with server and UI typechecks, 51 targeted server tests, 21 targeted UI tests, 304 passing server tests with 3 platform skips, 535 UI tests, and git diff checks.
Rewrite the migration guide around the architecture now present on DEV-v2. Inventory the removed V1 plugin, runtime, background-process, Question, delta, and native Tauri event layers; describe their native V2 replacements and the shared-service ownership model. Document duplicate-folder instances, per-window tabs, native cursor authority, reconnect reconciliation, worktree evacuation, proxy security, multi-window persistence, restore fencing, UI performance work, current automated validation, and the remaining interactive smoke gate. Remove stale claims about private OpenCode storage, daemon shutdown, canonical workspace deduplication, projection resets, and pending CI. Validated with stale-claim searches and git diff --check.
|
PR builds are available as GitHub Actions artifacts: https://github.com/NeuralNomadsAI/CodeNomad/actions/runs/32417144366 Artifacts expire in 7 days.
|
1 similar comment
|
PR builds are available as GitHub Actions artifacts: https://github.com/NeuralNomadsAI/CodeNomad/actions/runs/32417144366 Artifacts expire in 7 days.
|
Load continuation message pages with the native cursor alone, hide deprecated models, and tolerate failed plugin records that do not carry an ID. Match official Desktop URL handling by limiting native external openers to web and mail schemes. Connect wildcard-bound shared services through loopback while preserving strict authentication and non-loopback rejection. Remove the inactive unrestricted Tauri asset scope and add focused regression coverage for cursor requests, model/plugin projection, URL schemes, and wildcard service discovery. Validated with focused UI/server tests, all 158 Electron native tests, all 104 Tauri tests, package typechecks, the UI production build, Rust formatting, and diff checks.
Delete unused client-connection notifications, spawn classifications, WSL metadata, workspace creation fields, one-element event sets, and renderer helpers left behind by the V2 restructuring. Remove obsolete Shell rename translations and test-only fixtures or captures that had no production caller. Preserve shared-daemon ownership, WSL launch behavior, restore state, pagination, and multi-window lifecycle semantics. The cleanup removes 257 lines while adding 23 lines of direct replacements. Focused server and UI suites, all native host suites, typechecks, the UI build, and independent diff review passed.
Document the reviewed CodeNomad and OpenCode Desktop V2 baselines, incremental methodology, existing parity, and every defect closed by the accompanying implementation changes. Separate remaining work into active-location correctness, undo/redo, release signing, coordinated runtime upgrade, and optional PTY, export, reference, and MCP-resource features. Record rejected false positives and the validated Ponytail reduction. Link the comparison from the migration guide and documentation index so future V2 upgrades can resume from an explicit commit baseline instead of repeating the full audit.
Preserve native V2 session and message cursor semantics while keeping restored history, concurrent roots, drafts, and interruption state authoritative across reconnects and client replacement. Historical scroll restoration and conversation search now load older pages safely with bounded, retryable progress, and partition commits reject snapshots above the native 256 MiB budget. Serialize workspace location eviction against creation, release failed initial daemon identities, and translate WSL certificate paths under one deadline. Electron and Tauri now retain window persistence through failed shutdown or close operations, fence navigation generations, bound CLI cleanup, and keep remote-window origin and TLS authority isolated across concurrent reuse. Refresh the architecture guide for the current Forms-based V2 client and strict Electron/Tauri parity. Coverage includes 277 server tests, 333 UI tests, 163 Electron tests, 117 Tauri tests, all TypeScript typechecks, Rust formatting, and complete Windows Electron ZIP and Tauri NSIS builds.
Use indexed access in the host OpenCode service fixture so the server test sources compile under the repository's current TypeScript library target during Tauri packaging. Validated with the focused host service tests, server typecheck, and git diff checks.
|
PR builds are available as GitHub Actions artifacts: https://github.com/NeuralNomadsAI/CodeNomad/actions/runs/32462058484 Artifacts expire in 7 days.
|
Publish native root session pages before descendant inventory enrichment, preserve native cursor authority across refresh and history pagination, and reconcile complete message snapshots without racing newer runtime state. Hydrate restored session branches concurrently by ancestry level and gate initial session/message work only on project identity rather than supplemental MCP and plugin metadata. This keeps saved selections and transcripts responsive across multiple restored workspaces while retaining authoritative cleanup. Validated with 43 targeted UI tests covering session request authority, message pagination, metadata replacement, and message-store restoration, plus the UI TypeScript check.
Treat a repeated drain as complete once the first drain's finally block has already released primary ownership. The first drain for secondary clients still runs so process registration markers are not leaked. This lets a user retry application shutdown after a queued persistence failure instead of reusing the permanently rejected release promise on every subsequent attempt. Validated with all 33 Electron client-state tests, including a new failed-write and repeated-drain regression case.
Propagate renderer client-state flush failures through interactive local close and normal application shutdown. A failed close now retains the persisted window record, while a failed quit restores hidden windows instead of destroying the renderer's only dirty snapshot. Windows OS session-end remains the explicit bounded fail-open path so logout and machine shutdown cannot be vetoed indefinitely. Validated with 15 lifecycle and renderer-flush tests, including oversized-snapshot failure simulations for local close and global quit.
Serialize validation and eviction authority for duplicate workspaces, keep timed-out cleanup attached to the old owner, and remove failed unpublished launch records even when their best-effort OpenCode location eviction also fails. This prevents invisible failed records from suppressing later final eviction while preserving shared-daemon ownership and avoiding per-workspace service shutdown. Validated with all 27 workspace manager lifecycle tests, including concurrent deletion, timeout, shutdown, header failure, and replacement-owner scenarios.
Keep one pinned OpenCode V2 background service, validate every proxied workspace location and cursor, and route host and WSL service discovery through bounded authenticated lifecycle adapters. Evacuate every paginated worktree session before Git deletion, roll moves back when removal fails, and reconcile UI worktree state only after the server confirms deletion. Native session and shell ownership remains scoped without creating or stopping a daemon per workspace. Validated with the complete server suite (284 passed, 2 skipped), server typecheck, and the UI worktree deletion authority test.
Fence renderer access across queued reloads and cross-origin navigation, preserve remote-window authority through overlapping loads, and route shutdown through serialized lifecycle ownership before rotating client-state tokens. Keep the Tauri CLI control channel attached on Windows, enforce identity-aware bounded process-tree cleanup, and expose only the native permissions required by local windows. Validated with 170 Electron native tests, Electron typecheck, and all 121 Tauri Rust tests.
Expose native OpenCode shell output from the Status panel, keep shell records visible when removal fails, and render distinct process cards with explicit output and removal actions. Cover terminal timeout and killed states in every supported locale. Parse canonical reasoning headings separately from their detail so the heading is not duplicated in expanded output, and disable expansion when no detail exists. Validated with all 518 UI tests and the UI TypeScript check.
Keep client-state ownership and reopen persistence when a shutdown drain rejects. A later renderer flush can now persist dirty state before a successful retry releases process and cross-host ownership. This prevents a failed late write from turning every subsequent normal quit into a non-primary no-op followed by forced state loss. Validated with 46 Electron client-state and lifecycle tests plus the Electron TypeScript check.
Serialize deletion attempts per worktree and mark both host and service directories blocked from enqueue through completion. Workspace proxy mutations targeting a blocked directory now fail before reaching OpenCode. This prevents concurrent deletes from rolling sessions back into an already removed worktree and closes CodeNomad's session create or move window between final inventory and Git removal. Validated with 29 worktree evacuation, route, and instance-proxy tests plus the server TypeScript check.
Keep only the newest four MiB in the shell output dialog and skip ANSI reparsing when a poll returns no new bytes. The native output file remains unchanged and the existing truncation notice is shown when the display cap is reached. This prevents long-running verbose shells from growing renderer memory without bound or repeatedly reparsing unchanged output. Validated with the shell store test and UI TypeScript check.
Run the complete CLI stop/start restart while holding the shutdown coordinator authority. Shutdown now waits for an admitted restart, while restart requests arriving after shutdown begins fail without spawning another process. This prevents final cleanup from racing a restart that could recreate the embedded server immediately before application exit. Validated with cargo fmt and all 121 Tauri tests on Windows.
Track admitted workspace mutations by normalized directory and hold deletion until their proxy responses finish. Once deletion is queued, later mutations targeting either the host or service worktree path are rejected atomically. This closes the remaining window where a create or move admitted just before the deletion fence could complete after final session inventory. Validated with 30 worktree evacuation, route, and proxy tests plus the server TypeScript check.
|
PR builds are available as GitHub Actions artifacts: https://github.com/NeuralNomadsAI/CodeNomad/actions/runs/32497436700 Artifacts expire in 7 days.
|
Release admitted worktree mutations only when reply-from receives the upstream response or error, so downstream disconnects cannot let deletion overtake an OpenCode mutation. Deletion waits fail closed after a bounded timeout. Canonicalize workspace directories through the resolved Git worktree and use that identity while inventorying sessions, preventing dot, duplicate-separator, symlink, and junction aliases from bypassing the fence. Validated with 61 manager, proxy, route, and evacuation tests including delayed upstream, alias, rollback, and timeout cases, plus the server TypeScript check.
Reopen the serialized CLI lifecycle and restart the embedded server when client-state ownership release fails after shutdown. Restored windows remain functional while the next quit retries the dirty state drain. Validated with 73 client-state, lifecycle, and process-stop tests plus the Electron TypeScript check.
Keep restart serialized with shutdown while limiting the CLI stop phase to two seconds. A slow restart now fails without respawning and leaves the Windows session-end path time to flush renderer and native state. Validated with cargo fmt and all 121 Tauri tests on Windows.
Advance the retained output boundary past split UTF-16 surrogates and partial ANSI CSI sequences. Truncated shell output no longer begins with malformed Unicode or a literal escape fragment. Validated with four shell-store tests and the UI TypeScript check.
|
PR builds are available as GitHub Actions artifacts: https://github.com/NeuralNomadsAI/CodeNomad/actions/runs/32501000153 Artifacts expire in 7 days.
|
Track admitted proxy mutations through upstream response completion and key deletion fencing by the canonical physical worktree root. Nested paths, duplicate logical workspaces, symlink and junction aliases, WSL paths, and stale missing descendants now converge on the same identity while unresolved reparse points fail closed. Evacuate every session belonging to that identity before removal, refresh stale worktree caches, and bound mutation draining so deletion cannot hang indefinitely or overtake active upstream work. Document OpenCode's confirmed one-process architecture. Validated with all 299 server tests (297 passed, 2 skipped), focused Windows junction and WSL probes, server typecheck, and diff check.
Keep the four MiB display cap without retaining split UTF-16 surrogates or partial ANSI CSI, OSC, DCS, APC, and PM control strings. Handle ESC-backslash terminators and CAN/SUB cancellation so visible output is preserved. Validated with four shell-store tests, including Unicode and ANSI boundary probes, plus the UI typecheck.
|
PR builds are available as GitHub Actions artifacts: https://github.com/NeuralNomadsAI/CodeNomad/actions/runs/32505585098 Artifacts expire in 7 days.
|
OpenCode V2 Migration and Desktop Restructuring
Summary
This branch replaces CodeNomad's OpenCode V1 SDK, custom plugin, and per-workspace runtime architecture with the experimental native OpenCode V2 client and one shared OpenCode service. It intentionally ships no V1 runtime fallback.
The scope now goes well beyond the original SDK migration: native location ownership, Forms and Shell resources, project-wide cursor pagination, streaming reconciliation, virtualized histories, duplicate-folder instances, multi-window Electron/Tauri behavior, and content-addressed desktop restore are all included.
Full architecture and review notes:
MIGRATION_V2.mdLegacy Architecture Removed
packages/opencode-pluginpackage, packaging/setup hooks, desktop resources, environment plumbing, plugin POST/SSE routes, event bridge, and voice synchronization channel..codenomad/worktreeMap.jsonand the UI-side OpenCode workspace/worktree-client matching layer.shell.*resources replace it.EventSource.@opencode-ai/sdkfrom server/UI and remove the V1 compatibility path.Native V2 Contract
@opencode-ai/client@0.0.0-beta-17595; manage theopencode2CLI independently and accept compatible versions after authenticated health/API validation.SessionInfo.locationas the authority for workspaces, sessions, files, events, Git worktrees, Shells, and PTYs.@opencode-ai/client/solidcreateDatafor live reduction while retaining REST history and optimistic prompt admission.session.shell; expose backgroundshell.*resources separately from interactivepty.*terminals.Shared Service and Workspace Model
service status,service start, andservice get passwordcommands; accept only bounded authenticated loopback health endpoints.Sessions, Events, and Performance
Worktrees, Requests, and Security
Desktop and Restore Architecture
--new-windowis supplied.Validation
8fe238f5: repository tests, Windows Tauri tests, Electron builds on Linux/macOS/Windows, and supported Tauri builds on Linux/macOS/Windows; Linux ARM64 Tauri was intentionally skipped.git diff --checkpasses.The remaining release gate is one final interactive real-service smoke covering folder/session opening, prompt/response, reload/restore, background Shell proxy lifecycle, and V1/V2 client-state coexistence.
Notes