Commit graph

1027 commits

Author SHA1 Message Date
Pascal André
00fcee388f
fix(ui): truncate shell output at safe boundaries
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.
2026-08-21 18:56:56 +02:00
Pascal André
8ac7453440
fix(server): fence worktrees by physical identity
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.
2026-08-21 18:56:56 +02:00
Pascal André
12563d250c
fix(ui): preserve shell output truncation boundaries
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.
2026-08-21 18:04:08 +02:00
Pascal André
d9b0755081
fix(tauri): bound CLI restart shutdown authority
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.
2026-08-21 18:04:07 +02:00
Pascal André
97ebfe5973
fix(electron): recover CLI after failed state release
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.
2026-08-21 18:04:07 +02:00
Pascal André
006522f00c
fix(server): fence deletion through upstream completion
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.
2026-08-21 18:04:07 +02:00
Pascal André
b78697fc99
fix(server): drain session mutations before worktree deletion
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.
2026-08-21 17:24:30 +02:00
Pascal André
7a8d06d32b
fix(tauri): serialize CLI restart with shutdown
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.
2026-08-21 17:24:29 +02:00
Pascal André
4c702cdf36
fix(ui): bound retained shell output
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.
2026-08-21 17:21:12 +02:00
Pascal André
082ba90b42
fix(server): fence worktree deletion against session admission
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.
2026-08-21 17:18:50 +02:00
Pascal André
be6cf9fc79
fix(electron): retain state ownership after failed drain
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.
2026-08-21 17:15:15 +02:00
Pascal André
3445de6b20
fix(ui): restore shell status and reasoning details
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.
2026-08-21 16:11:14 +02:00
Pascal André
7df0974f64
fix(desktop): serialize V2 navigation and process shutdown
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.
2026-08-21 16:08:29 +02:00
Pascal André
08dd380e58
fix(v2): preserve shared service and worktree authority
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.
2026-08-21 16:07:37 +02:00
Pascal André
c51e40eac7
fix(server): harden shared location ownership cleanup
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.
2026-08-21 16:05:53 +02:00
Pascal André
2714fab237
fix(electron): block close when renderer state cannot persist
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.
2026-08-21 16:05:18 +02:00
Pascal André
8f5aad82cb
fix(electron): make failed client-state release retryable
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.
2026-08-21 16:03:07 +02:00
Pascal André
2f087705d4
fix(ui): restore V2 sessions without blocking first paint
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.
2026-08-21 16:00:43 +02:00
Pascal André
2a29836f36
test(server): avoid ES2022 array access
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.
2026-08-21 10:11:42 +02:00
Pascal André
290ad3d586
fix(v2): harden state authority across reconnects
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.
2026-08-21 02:07:48 +02:00
Pascal André
6ef68ed69e
refactor(v2): remove verified dead migration code
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.
2026-08-21 00:28:55 +02:00
Pascal André
34179162df
fix(v2): close current desktop parity gaps
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.
2026-08-21 00:28:09 +02:00
Pascal André
a3f7e3be27
refactor(electron): remove obsolete single-window lifecycle
Delete the unused ClientStateLifecycle implementation and its isolated tests now that every production window routes through MultiwindowLifecycle. Remove the deleted test file from the native test command without changing multi-window close, persistence, or shutdown behavior.

Validated with all 158 Electron native tests and the Electron TypeScript typecheck.
2026-08-20 22:59:36 +02:00
Pascal André
8fe238f52f
refactor(workspaces): inline canonical path resolution
Remove the one-caller workspace identity module now that logical workspace deduplication no longer exists. Keep realpath canonicalization directly at the launch boundary and cover it through duplicate alias creation behavior.

This removes another 22 net lines and one source file. Focused manager tests and the server typecheck pass.
2026-08-20 22:16:50 +02:00
Pascal André
161aebb50e
fix(workspaces): restore duplicate folder tabs
Create a fresh logical workspace for each normal folder launch so repeated opens produce separate tabs again. The explicit Open action still selects an existing instance without creating one.

Keep the shared OpenCode location alive until its final logical workspace closes. Remove canonical deduplication, multi-owner launch bookkeeping, inode identity state, and the tests that only supported that behavior.

Validated with the full server suite, restore ownership tests, server typecheck, and focused concurrent launch and location eviction coverage.
2026-08-20 22:15:27 +02:00
Pascal André
52a9589f60
fix(ui): keep session hydration state accurate
Show the initial loading state while the native session cursor is still unresolved, including the metadata hydration window before the list request starts.

Remove the misleading load-more label from the pagination sentinel because the shared fetch flag tracks initial and refresh requests rather than cursor requests. Native cursor handling remains authoritative, including terminal empty pages.

Validated with UI typecheck, focused pagination and request-authority tests, and the production UI build.
2026-08-20 21:49:37 +02:00
Pascal André
db0464f702
fix(v2): stabilize catalog and transcript loading
Coalesce concurrent provider and agent catalog requests per OpenCode location while preserving one trailing refresh after reconnect, authentication, or catalog invalidation. Fence stale responses with monotonic request generations and cancel removed-instance flights so reused workspace IDs cannot install obsolete providers, agents, models, or commands.

Load only the selected session transcript instead of eagerly requesting every descendant. Keep thread cost and token totals complete from native session aggregates, including newly paginated descendants, while retaining cursor-based transcript history loading.

Strip upstream WWW-Authenticate and Proxy-Authenticate challenges alongside response cookies so OpenCode authentication cannot trigger the browser's native Basic Auth dialog. Coverage exercises coalescing, invalidation, location switches, instance-ID reuse, lazy transcripts, native totals, and real 401 proxy responses.
2026-08-20 20:18:39 +02:00
Pascal André
2c9ced635e
fix(v2): harden reconnect and desktop state recovery
Preserve the OpenCode data controller across reconnects, require the native server.connected handshake, restore native cursor pagination for sessions and messages, and route global Forms through their validated worktree locations.

Make partitioned client state tolerate corrupt inactive leaves and store unsent attachment payloads as bounded content-addressed chunks without silently rewriting drafts. Align Electron and Tauri commit limits and shutdown-generation fencing.

Tighten SSE CORS, proxy ownership checks, remote-window navigation, process exit classification, and pre-navigation renderer flushing. Ordinary backend shutdown now detaches local workspaces without evicting shared OpenCode locations.

Coverage includes server proxy/event/lifecycle tests, UI pagination and restoration tests, Electron native lifecycle/security tests, and the full Tauri Rust suite.
2026-08-20 17:28:52 +02:00
Pascal André
ec543e3df8
test(server): support configured TypeScript target
Replace Array.prototype.at() in the new OpenCode service tests with equivalent indexed access so the Tauri prebuild compiles under the server workspace's existing TypeScript library target on macOS ARM64.

Validated with the full server production build and the focused host/WSL service test suite (14 passing).
2026-08-20 08:54:28 +02:00
Pascal André
b5f3fc6e82
feat(v2): unify global service and desktop windows
Use the official host and WSL OpenCode service lifecycle instead of private daemon ownership. Workspace deletion now evicts only the selected location while shared sessions, agents, messages, and executions remain available to other windows.

Add profile-scoped singleton multi-window support for Electron and Tauri, isolate local window UI state in a durable partition graph, and preserve migration, fencing, bounded persistence, and cross-host ownership semantics. New Window and New Instance are exposed together in the native Window menu.

Harden renderer authority, remote profiles, SSE identity, idle attention, git-status concurrency, SideCar sandboxing, shutdown, generated Tauri ACLs, documentation, and CI coverage.

Validated with server, UI, Electron, and Tauri test matrices; TypeScript checks; cargo fmt; production Electron/server/Tauri builds; diff checks; and a packaged Windows smoke covering singleton focus, --new-window, one shared backend, menu placement, and slot hash verification.
2026-08-20 08:41:27 +02:00
Pascal André
5484f9c990
fix(v2): use native shells for background processes
Migrate the Status panel from interactive PTYs to the location-scoped shell API, refresh shell state after lifecycle events and reconnects, and route locationless shell events by their owned working directory.

Allowlist shell routes explicitly and verify ShellInfo.cwd before every ID-scoped request, including trailing-slash aliases, while preserving native output cursor parameters. Keep PTYs separate for interactive terminal use.

Load project metadata before the first session inventory, preserve native projected message order, invalidate inactive transcripts instead of reloading every transcript after reconnect, and keep native shutdown terminal without latching ordinary navigation flushes.

Update V2 documentation and CI test paths. Validated with UI and server typechecks, 15 focused UI tests, 35 focused server tests, and git diff --check.
2026-08-19 16:11:47 +02:00
Pascal André
109a8ee37a
fix(ui): reconcile prompt admission identity
Use the inbox identifier returned by OpenCode as the authoritative message identity instead of assuming every compatible CLI preserves the client-provided optimistic ID. This prevents the optimistic and admitted prompts from remaining as duplicate bubbles when their IDs differ.

Delete the replaced store record through a Solid produce update so the old key is actually removed. Covered by the optimistic send lifecycle suite and validated with the UI typecheck.
2026-08-19 15:24:24 +02:00
Pascal André
e1987b9cdd
fix(v2): decouple runtime CLI version
Stop comparing the selected OpenCode CLI version with the generated client package and stop constraining shared-service discovery to that exact string. Runtime releases can now update independently while existing health, location, API decoding, and launch-signature checks continue to fail closed on actual incompatibility.

Update migration and architecture guidance so the strict gate is not reintroduced. Validated server typecheck, 32 focused manager/service/identity tests with one platform skip, Tauri release build, NSIS installer hash, and diff cleanliness.
2026-08-19 09:33:16 +02:00
Pascal André
a2d5df96f5
fix(forms): allow required custom select values
Disable native select required validation once a non-option custom value is present, so required long-option forms can submit through the existing schema validation.

Validated with UI typecheck, focused form protocol tests, and git diff --check.
2026-08-19 09:05:15 +02:00
Pascal André
affdb96f14
fix(v2): keep forms and worktree deletion fail-safe
Render the floating Form fallback whenever its inline tool target is unresolved, and allow required custom select answers to pass native validity checks. This prevents native Forms from leaving sessions permanently blocked.

Recheck affected session activity before each evacuation move and immediately before Git removal so execution starting after preflight aborts and rolls the transaction back. Validated with root typechecks, focused Form and projection tests, evacuation tests, and server typecheck.
2026-08-19 06:26:54 +02:00
Pascal André
3b5f443073
style(ui): remove trailing whitespace
Keep the V2 migration diff clean so git diff --check succeeds as claimed by the gatekeeper validation.
2026-08-19 06:22:40 +02:00
Pascal André
af22f58ca6
fix(ui): replace optimistic prompt after native projection
Confirm same-ID user messages when createData exposes their native projected parts. This removes the client-only optimistic parts before applying the server representation, preventing every submitted prompt from rendering twice inside one message.

Add a regression that starts with an optimistic text part, applies the native inbox event, and asserts only the projected prompt remains. Validated with UI typecheck and 17 focused projection, send lifecycle, and request authority tests.
2026-08-19 06:13:01 +02:00
Pascal André
ef70a8b799
fix(v2): harden reconciliation and worktree rollback
Scope global Form actions to the logical workspace location without hydrating a synthetic global session. Keep successfully loaded message sessions eligible for later reconnect retries and traverse project descendants independently of parent worktree subpaths.

Treat native session moves as asynchronous operations, block active worktree sessions, verify complete project inventory before Git removal, and roll all accepted moves back if verification or Git deletion fails.

Validated with server and UI typechecks, 255 passing server tests plus 3 platform skips, 31 affected UI tests, and git diff --check.
2026-08-19 02:38:57 +02:00
Pascal André
249a96e7c0
fix(v2): close native integration review gaps
Merge live createData projections into REST history and reset their event cache for every internal stream generation. Load sessions by validated project scope across all descendant depths and apply native active state to later root pages.

Pin the updater and standalone server lockfile to the startup-compatible client version. Decode and authorize native session cursors, permit global Form actions, and prevent the WSL stop path from invoking the client's host PID fallback.

Make worktree deletion server-authoritative by inventorying the complete native project, moving affected session families with verification and rollback, and failing direct delete calls closed when evacuation cannot complete.

Validated with server and UI typechecks, 254 server tests plus 3 platform skips, 247 UI CI-partition tests, 122 Electron native tests, server/UI/Electron production builds, standalone server lockfile installation, Tauri cargo check --locked, and git diff --check.
2026-08-19 02:32:59 +02:00
Pascal André
4359b4bfe9
fix(v2): align with current OpenCode client contract
Pin the server and UI client to the installed beta runtime and reject mismatched CLI versions before shared-service startup. Delegate proven shared-service shutdown to Service.stop while retaining CodeNomad lease, peer, registration, endpoint, and process-identity checks.

Adopt native Forms and the client/solid data reducer for live messages, tools, permissions, and input forms. Propagate internal stream generations into authoritative reconnect reconciliation and replace directory-wide session scans with native project cursor pagination.

Fail worktree deletion when session evacuation fails and deduplicate canonical workspace folders instead of exposing non-isolated duplicate instances. Update migration notes and CI coverage for the reviewed contract.

Validated with server/UI/Electron typechecks, 244 UI partition tests, 122 Electron native tests, 248 server tests plus 3 platform skips (the sole Windows cleanup race passed in isolation), UI/server/Electron builds, Tauri cargo check --locked, and git diff --check.
2026-08-19 01:50:39 +02:00
Pascal André
4c65e60fa9
test(v2): remove redundant migration coverage
Reduce the V2 test matrix to CodeNomad-owned behavior instead of repeating generated OpenCode request shapes, mock choreography, equivalent endpoint permutations, and source-level helper wiring.

Retain representative happy paths and the boundaries that protect workspace ownership, traversal and credentials, PID and WSL lifecycle proof, shutdown timeouts, permission isolation, restore handoff, deletion authority, streaming reconciliation, and persisted client state.

This removes 2,818 net test and CI lines. The full server suite passes with 249 tests and 3 platform skips; the PR UI matrices pass with 204 standard and 53 browser-conditioned tests, both server and UI typechecks pass, and git diff checks are clean.
2026-08-18 23:49:35 +02:00
Pascal André
775c6c6ca1
refactor(v2): remove dead migration scaffolding
Delete the obsolete pre-MVP roadmap and task references now that Git preserves that development history, while retaining current V2 operational and architecture guidance.

Remove behavior-neutral server and UI plumbing that has no remaining caller: unused workspace options and cached endpoint state, redundant auto-accept metadata, an unused PTY get adapter, and a one-use message-loading helper. Keep lifecycle proof, restore gates, timeline projection, and targeted invalidation because they still enforce runtime behavior.

Validated with server and UI typechecks, the full server suite (308 passed, 3 skipped), focused UI matrices, browser-conditioned UI tests, production server/UI build, diff checks, caller searches, and an independent regression review.
2026-08-18 23:21:43 +02:00
Pascal André
a820f80be3
fix(ui): keep native forms visually stable
Keep tool-targeted V2 forms inline from the moment their metadata arrives instead of briefly opening the permission-center fallback while message state catches up.

Render the pending form directly in place of the tool-call chrome so users see one stable response surface without a stray disclosure chevron. Global and inactive-session forms retain the floating fallback.

Validated with the UI typecheck, the 83-test restore/form integration matrix, a production Tauri build, and git diff checks.
2026-08-18 21:42:07 +02:00
Pascal André
68abdc6d2b
fix(i18n): describe active plugin state
Update the empty plugin-status copy in every supported locale now that the panel reports runtime-active plugin IDs rather than configured package entries.

The UI typecheck and diff check pass.
2026-08-18 21:19:38 +02:00
Pascal André
e4a2bde33b
fix(server): expose active V2 plugin metadata
Allow the read-only OpenCode /api/plugin endpoint through the workspace proxy so the status panel can distinguish active plugins from configured but unloaded packages.

Keep the route inside the explicit proxy allowlist and cover it with the instance proxy suite. The focused 25-test proxy suite, server typecheck, and diff check pass.
2026-08-18 21:12:49 +02:00
Pascal André
97d4645388
fix(ui): stabilize V2 runtime status panels
Keep provider usage visible across status-panel remounts and reuse fresh results for the normal polling interval so message refreshes cannot collapse the panel into a loading state.

Treat compaction as the boundary for the visible agent plan, source plugin status from active V2 plugin IDs instead of configured package entries, and reserve the background-shell panel for native PTYs.

Propagate session interruption to active descendants and replace the placeholder busy check with the real working/compacting status. Focused tests cover active plugin filtering, compacted plans, and descendant interruption; the complete UI test matrix, UI typecheck, and production build pass.
2026-08-18 21:03:56 +02:00
Pascal André
c4bc08ee03
fix(settings): restore OpenCode V2 updates
The V2 migration first disabled and then removed the OpenCode update action because the native runtime no longer exposes V1's global upgrade endpoint. The remaining version card also queried the legacy opencode-ai package instead of the V2 beta channel.

Restore the settings action using the official @opencode-ai/cli beta installation flow for npm, pnpm, bun, and yarn. Restrict automatic updates to the managed opencode2 command, preserve custom binaries, compare monotonically numbered beta builds numerically, and verify the configured binary after installation before reporting success.

Validated against the live beta registry, 11 focused update tests, 307 server tests with 3 skipped, 544 UI tests, server and UI typechecks, the production UI build, and diff checks.
2026-08-18 18:20:10 +02:00
Pascal André
ae6a2a8b2e
fix(ui): preserve streaming follow invariants
Rapid V2 deltas continuously extended the programmatic-scroll window. Virtua measurement corrections during that window could leave the controller logically following while the viewport remained above the bottom.

Enforce the bottom invariant whenever follow mode has no fresh user escape or active restoration. Classify page navigation from non-editing controls and primary selection drags as user ownership, cancel pending submit pinning for every recognized user scroll, and allow explicit downward intent to rejoin during a programmatic window.

Validated with 39 focused follow tests, 56 combined streaming/send/projection tests, the UI typecheck, 544 UI tests, and diff checks.
2026-08-18 16:55:52 +02:00
Pascal André
d2783ee8c4
fix(ui): render prompts before native admission
Optimistic user text was inserted synchronously but marked synthetic, causing timeline projection and message rendering to hide it until delayed REST or SSE reconciliation replaced the part. Large histories and active streaming made that delay especially visible.

Keep optimistic user text renderable while retaining reconciliation authority through the existing optimistic part ID registry. Also tolerate provisional text and reasoning parts without a text property when computing timeline signatures.

Validated with 12 focused projection and send-lifecycle tests, including a deferred native request proving pre-network visibility, plus the UI typecheck and diff checks.
2026-08-18 16:52:04 +02:00
Pascal André
0cac5ca2f7
fix(ui): release follow on middle-button scroll
Middle-button autoscroll starts from message descendants, but the virtual list only recorded pointer intent when the scroll container itself was the event target. The resulting scroll events had no user intent and were immediately pinned back to the bottom.

Treat a non-interactive middle-button pointer press anywhere inside the list as explicit user scroll ownership. This exits follow mode and cancels active bottom pinning without preventing the browser's native middle-button behavior.

Validated with 36 focused follow-controller tests, the UI typecheck, 539 UI tests, and git diff checks.
2026-08-18 16:26:35 +02:00