Commit graph

132 commits

Author SHA1 Message Date
Pascal André
9dd4b3f059
feat(remote-control): add Remote Control over OpenTunnel alongside direct access (#668)
Adds Remote Control alongside direct/LAN access. A phone or another computer pairs with CodeNomad and continues its sessions from anywhere, without an inbound port. The transport is OpenTunnel, the blind TLS relay used by OpenCode: TLS ends inside the CodeNomad backend, and nothing has to be deployed.

- packages/remote-tunnel wraps @opentunnel/client. The server build bundles it with its own Effect 4.0.x, so the published server has no runtime dependency on a private workspace package. CodeNomad claims its own route on the device's shared identity and never deletes it.
- A remote-only loopback ingress marks its sockets as remote, so local privileges come from isLocalRequest(), never the peer address. The gate runs before CORS, auth and routing:
  - exact tunnel Host, and the public Origin on mutations;
  - stripped forwarding headers;
  - origin-form targets only, judged as routed (decoded, cut at ';');
  - host-only paths denied;
  - a paired device required, except for the public UI bundle.
- Host-owned pairing: a single-use five-minute code, hashed device credentials with 30-day idle expiry, and a __Host- cookie. Revocation or eviction closes live streams. A revoked device is asked to pair again, keeping drafts.
- The Cloudflare Worker/Durable Object relay, the custom E2EE protocol and the browser transport shims are removed. Electron and Tauri keep the backend alive after the last window only while Remote Control is enabled.

Validation:
- the real createHttpServer is exercised through the ingress, plus raw-socket canonicalization tests and device registry tests;
- recovery unit and browser tests;
- an opt-in end-to-end run through the hosted relay;
- a packaged smoke import of the bundled runtime;
- five gatekeeper rounds to zero findings, and green CI on all desktop targets.
2026-10-09 12:43:25 +02:00
Pascal André
288bc7c343
fix(browser): preserve per-session previews and Back history (#884)
## Summary

- Give each conversation its own browser preview, keyed by project
folder and session ID, rather than reusing the project's URL across
conversations.
- Preserve the actual native guest when returning to chat, selecting
another session, showing Info or hiding the project. Page state and
native Back history survive these transitions.
- Keep guest DOM order stable. Only explicitly opened browser shells
remain mounted; inactive transcripts and composers still unmount and the
existing transcript-memory budget remains independent.
- Both the conversation toolbar toggle and the preview's X return to
chat while keeping the browser, document state and native history
intact. The X is not a destructive browser close.
- Adopt an old project-wide saved URL once for the first restoring
conversation.
- Persist a bounded URL history and cursor per session. After restart,
browsers are restored only on explicit opening: load the current URL,
never replay intermediate visits or eagerly create saved guests.
- Add Back/Forward traversal using owned native CDP history IDs for live
entries. When an entry no longer exists natively, load only that
selected saved URL. Persist neither native pageState, POST bodies nor
form/DOM/JavaScript state; existing cookies/site storage remain native.

## Why

The preview was conditionally mounted inside the active
session/transcript view. Going back to chat or changing sessions
destroyed its webview; reopening recreated only the last URL, losing the
native history. The preview store was also keyed by project folder
despite the native guest being session-bound.

This fixes the lifetime and ownership at their existing shared UI
boundaries. Electron unregisters hidden guests from automation without
destroying them; Tauri hides and reuses its existing child. Native
controllers, authentication and browser storage partitions are reused.

## Validation

- UI, Electron and server typechecks passed.
- Full-shell browser/history suite: **9/9 passed**. Real Electron guests
and the production controller cover guest/form retention,
X/chat/session/project/Info transitions, renderer restart, lazy restore,
no intermediate replay, Back/Forward and hidden navigation. Also covers
interrupted native/iframe traversal, inactive transcript/composer
disposal, project/session separation, Tauri hide/reuse and one-time
legacy migration.
- Tauri native suite: **197/197 passed** (serial rerun after an
unrelated Windows service-fixture failure under parallel load).
- Focused Electron browser controller/preload: **23/23 passed**,
including hidden owned-history access without automation visibility and
foreign-owner/unsafe-entry refusal.
- Existing BrowserFrame native/renderer regressions: **19/19 passed**.
- Focused existing header/session/preview-close regressions: **3/3
passed**.
- Preview persistence/native adapter unit cases and the
browser-conditioned transcript-budget regression passed.
- `git diff --check` passed.

The broad local Electron suite hits unrelated, unchanged Windows
process-identity/service-start fixtures; focused browser/native checks
pass. The broad header run exceeded the local command timeout; relevant
cases were rerun separately. Tauri browser interaction is exercised
through the real Solid shell with mocked native IPC and Rust controller
regressions, not a packaged WebView2 smoke.

History is capped at 32 URLs per session within the existing 4 KB
aggregate layout-value budget; trim history before evicting saved
previews. Application/project closure ends the live document: restored
history preserves URLs/cursor, not unsent forms or scroll.

## Autonomous gatekeeper loop

Independent pass 1 found hidden Tauri navigation loss and explicit Go
superseding a pending Back corrupting an entry. Pass 2 found hidden
Electron navigation loss before restart and stale iframe Back callbacks
after Go/Refresh. All four findings were fixed with regression tests;
the final independent pass reports **zero actionable findings**. The
final review will be published separately on the exact pushed head
before the requested admin merge.

Prior-head CI also exposed three failing clipboard-diff tests. An
independent diagnostic reproduced them unchanged on exact `dev` baseline
`027f5094`: the fixture omitted the session context required since #848.
The fixture-only correction seeds/passes its session and all three cases
pass. Production permission/approval behavior is untouched.

## Size notes

Existing large files touched:
`packages/ui/src/components/instance/instance-shell2.tsx` (~1334 lines),
`packages/ui/src/components/browser-frame.tsx` (~1005),
`packages/ui/src/components/session/session-view.tsx` (~723),
`packages/tauri-app/src-tauri/src/main.rs` (~2712), and
`packages/tauri-app/src-tauri/src/browser_controller.rs` (~1674).
2026-10-09 00:30:01 +02:00
Pascal André
027f50947c
refactor: retire obsolete docs, dead APIs and speculative loaders (#880)
## Scope
Implement the two repository-wide Ponytail audit lists, deduplicating
overlapping recommendations. Based on current `dev@aa2776ef`, on
`refactor/ponytail-cleanup`; no direct dev changes. Initial delta:
**3,548 net lines removed**, two direct dependencies removed (and their
unused transitive lockfile entries).

## Changes and preserved behavior
- Delete superseded MVP/UI/tool-rendering/summary docs; compact the
index and canonical architecture references and remove
per-review/temp-path bookkeeping from runtime-transition history.
Preserve security/ownership rules, technical minimum rationale,
compatibility provenance and reproduction commands.
- Remove confirmed-unused UI surfaces, Electron JSON storage IPC,
obsolete release fetch/shell runners and dead
bridge/storage/command/keyboard utilities. Keep existing native
environment discovery and shared-service lifecycle untouched.
- Replace the empty first-party plugin loading layer with direct
built-in right-panel construction. External sandboxed extensions,
consent, assets authority, activation, ordering and visibility remain
intact.
- Retire the unused incremental-part message mutation engine and
exclusively owned pending-part buffers/budgets/types. The active native
reducer still publishes bounded authoritative snapshots. Preserve
optimistic send identity, pending sends, permissions, usage,
pruning/revert, memory accounting and scroll restoration. Rewrite old
tests using snapshots rather than removing relevant behavioral
assertions.
- Share speech streaming/base64 helpers, retaining playback lifecycle
and cancellation in each caller; deterministic transport regression
covers ordering, start-once, completion and failures.
- Replace three Material icons with existing Lucide icons; remove
`@suid/icons-material` and unused `ts-node` without upgrading other
dependencies.
- Drop the redundant Favorites implementation-shape test; behavioral
store/browser regressions stay. Repair two inherited tests to current
palette and lazy copy contracts, preserving image/privacy assertions.

## Validation
Server/UI/Electron typechecks, UI production build, targeted
core-panel/Favorites/audio/image/palette checks pass. Full local suites
and focused browser/native Electron regressions are in progress. The
broad server run found one existing deadline-sensitive pending-broker
test; its entire 20-test file passes in isolation. Independent
gatekeeper review is required on this exact committed head, findings
will be corrected and re-reviewed to zero before the explicitly
authorized admin merge. No user credentials/shared daemon/database were
used for testing.

## Size notes
Touched existing large files:
`packages/ui/src/stores/message-v2/instance-store.ts` ~1,450 lines,
`packages/ui/src/stores/message-v2/instance-store.test.ts` ~516 lines,
`packages/ui/src/stores/conversation-speech.ts` ~432 lines. No size-only
refactor; source/test coverage reduction is tied to proven-unused paths.
Native application is not replaced/restarted by these isolated checks.
2026-10-08 01:03:40 +02:00
Pascal André
5d1c10e86f
docs: prune obsolete specifications and development readouts
Remove superseded MVP/UI/tool-rendering specifications, duplicate implementation and index summaries, completed attachment planning, incident readouts and redundant CI/pruning/native-backport reports at the user's explicit request. Trim the worktree validation diary while retaining placement, ownership and native-instruction contracts.

Preserve public extension contracts, attribution/licenses, private RPC safety, runtime capability policy and vendor patch provenance/removal criteria. Redirect native-backport instructions to the existing vendor README and remove dangling deployment links and a stale architecture dependency snapshot.

Validation: Markdown-only diff, whitespace checks and repository-wide checks for removed-file references. No runtime source, tests, build dependencies, installed application or shared OpenCode service is changed.
2026-10-08 00:42:53 +02:00
Pascal André
fd725bfe7b
docs: remove unsolicited F6 development readout
Remove the committed diagnostic/validation report and its AGENTS.md entry at the user's request. Keep the F6 mitigation and all runnable regression checks unchanged; investigation notes remain local rather than creating unsolicited development documents.

Verified this change touches documentation only, passes diff checks and leaves no references to the removed file.
2026-10-08 00:36:11 +02:00
Pascal André
260249cfee
fix(tauri): prevent WebView2 F6 browser-process crash (#881)
Closes #875.

## Captured cause
A trusted, foreground-checked F6 reproduced the black interface on
installed Tauri 0.20.1-dev-20261007-c995044b / WebView2 154.0.4258.62.
The native host remained responsive, but the WebView2 process tree
exited. An offline Crashpad dump with matching Microsoft symbols
identifies a browser-process null dereference in
`MultiContentsView::GetActiveContentsContainerView`, reached through
`chrome::FocusNextPane` and native pane-focus rotation. This is not a
hard refresh or the earlier Tao input deadlock. The dump remains local
because it can contain secrets.

## Mitigation
- Disable F6 browser actions only, through
`ICoreWebView2AcceleratorKeyPressedEventArgs2`, on each created local,
preferences, remote and preview webview.
- Preserve DOM delivery, including configured F6 shortcuts; retain all
unrelated browser accelerators. Older runtimes without the per-key
interface swallow only F6. No version gate or global accelerator
disabling.
- No callback locks, IPC, message pumping, app/controller capture or
additional preview capabilities. Electron and other platforms remain
unchanged.

## Validation
- 196/196 Windows Rust host tests, serial mode.
- Real isolated Tauri/WebView2 154.0.4258.62 tests in frameless and
decorated windows: F6, Shift+F6 and Ctrl+F6 browser policy disabled
while DOM delivery remains; F8 policy/delivery untouched; continuing
JavaScript heartbeat; no ProcessFailed.
- Positive native runs now verify the effective isolated profile and
final post-input heartbeat advancement under deliberately conflicting
inherited overrides; both framed/frameless runs pass. The negative
stopped-heartbeat check correctly rejects otherwise successful keyboard
checks.
- Frameless post-input capture visually inspected. No installed
application or shared OpenCode daemon replaced or restarted.
- Windows release build passes (`cargo build --release --bin
codenomad-tauri`); packaged-resource smoke checks pass. Existing
dead-code warnings remain.

The minimal baseline does not reproduce the captured installed-app
crash. Native fixtures validate the prevention mechanism and keyboard
preservation, not a full application A/B reproduction. No fixed
installed-app, Electron, Linux or macOS runtime qualification is
claimed. See `dev-docs/TAURI_WINDOWS_F6_CRASH.md`.
2026-10-08 00:26:00 +02:00
Pascal André
dc7d3fae2c
test(tauri): fence F6 fixture profiles and post-input liveness
Address both gatekeeper findings: sanitize inherited WebView2 overrides before creating threads, force the fresh owned user-data folder and controlled browser arguments, and verify the environment's actual user-data directory. Every runner launch injects conflicting temporary overrides and checks that their folder stays unused.

Require heartbeat advancement during the final two post-input intervals, after F8 confirms the last input arrived. Add a negative native check that deliberately stops only those heartbeats and verifies the fixture rejects it even though all key-policy/delivery checks pass and ProcessFailed is absent. Positive framed/frameless and negative checks pass on WebView2 154.0.4258.62.
2026-10-08 00:24:06 +02:00
Pascal André
2da2dadb25
fix(tauri): block WebView2's crashing F6 browser focus action
An offline, symbolicated dump identifies the captured Windows F6 failure as a WebView2 browser-process null dereference in MultiContentsView reached through FocusNextPane. Prevent only that native browser action on every created local, preferences, remote and preview webview.

Use the per-key WebView2 accelerator policy to preserve DOM delivery and configured UI shortcuts. Hosts without that interface swallow only F6 as a safe fallback; other accelerators, capabilities and platforms stay unchanged. Handlers capture no application/controller state and do no locking, IPC or message pumping.

Add a fresh-profile, static-loopback native fixture and ownership-fenced PowerShell runner for F6, Shift+F6, Ctrl+F6 and an untouched F8 control. Native decorated/frameless checks and 196 serial Rust host tests pass. Document the captured stack and the limitation that the minimal baseline does not reproduce the full installed-app crash; no fixed installed-app retest is claimed.
2026-10-08 00:17:30 +02:00
Pascal André
aa2776efa7
feat(extensions): add bounded current-session assets for API 2 panels (#874)
Add the shared, explicit API 2 session.assets.read capability required by the independently distributed MCP Assets addon. Keep API 1 context-only, preserve one general activation checkbox, and require consent tied to the exact installed package digest.

Use the bundled native history integration for bounded metadata pages and exact embedded tool-result bytes, with session/Location ownership and final consent revalidation. Fence native/backend disconnects, generation changes and stale responses; refresh after failed tool results and direct pruning. Admit bounded source dimensions before host bitmap decoding and preserve thumbnail aspect ratio. Include the new native modules in the packed plugin as well as the shipped bundle.

Two autonomous gatekeeper rounds ended with zero P0–P3 findings on 9da8513326583c7e2b56c5f86554817d478d0cbf; the initial three P2s have regression coverage. Local validation passed 16 browser, 14 server/image, seven package/presence and three bundled-installation checks, both shared typechecks, and the outside-checkout native fixture with official OpenCode 2.0.24. CI native plugin tests passed on Windows/Linux/macOS, as did runtime-contract and compatibility jobs.

Admin merge is explicitly requested by the maintainer. Global CI is not green: its three permission-fallback-diff Copy patch timeouts also occurred in the parent PR #872 (run 37632060353), and Windows reported two unchanged cross-host election-test failures. Preserve these failures as follow-up diagnostics rather than claiming full CI success or modifying unrelated paths in this PR. No protection settings are changed.
2026-10-07 22:54:06 +02:00
Pascal André
f610f2faf5
fix(extensions): simplify management inside customization (#872)
I put Extensions below a separator in the customization popup, collapsed
by default. I combine installed addons and the catalogue in one compact
searchable list and remove the separate modes and floating window.

I make the existing addon checkbox the only profile-wide activation
control. Disabled installed addons stay listed; reset never grants
consent. Explicit trust, digest-bound replacement/removal, offline ZIP
installation and sandbox protections remain intact.

I pass the UI typecheck, 9 server tests and 14 real-component
extension/Status browser tests, including narrow translated/RTL layouts
and real ZIP gestures. I inspect the interactive preview validated by
the user. Windows Tauri release qualification and the final independent
gatekeeper review are in progress; I do not replace the installed app or
stop the shared daemon.
2026-10-07 15:59:10 +02:00
Pascal André
88ac70062c
fix(chat): keep request icons and show complete red badges (#871)
## Requested change
Restore the normal question/permission icon for requests from unrelated
conversations. Show the complete shared red status badge, including its
localized text, separately at the trailing end of the collapsed bar.
Clicking the badge expands the selected request.

## Layout
Retain leading disclosure chevrons and source titles. Crowded mobile
headers wrap trailing controls instead of squeezing away the
conversation name. Reuse existing badge geometry, colors and
translations.

## Validation
- Initial dock/mobile run: 36 passes, one cold fixture navigation
timeout.
- All six final targeted checks pass, including the previously timed-out
recovery case; fixture initial navigation now has the same 60-second
budget as the real-shell fixture. Assertions preserved.
- Final UI TypeScript, production UI build and diff checks pass.
- Desktop/mobile compact question and permission captures inspected.
- Independent gatekeeper reviewed final diff/captures: ZERO FINDINGS.
Review will be published before the requested admin merge without
waiting for CI.

Installation is separate; no running application or native daemon was
restarted.
2026-10-07 14:22:55 +02:00
Pascal André
ce589dc7d7
fix(extensions): keep management compact with general activation (#869)
I restore right-panel customization to one compact Extensions action and move catalogue, ZIP installation, activation and trust/removal confirmations into a separate non-modal utility window. Lists stay single-line, metadata is available on hover and keyboard focus, toolbar actions remain reachable at narrow translated widths, and disposal fences late results.\n\nI remove speculative per-folder activation from the UI, client contract and backend. Each installed addon has one general activation control per CodeNomad profile. Existing packages and general grants survive; legacy folder-only consent is never broadened, and obsolete grants are removed only during an explicit successful mutation. Trust, digest-bound replacement/removal and owned-instance executable-panel reads remain enforced.\n\nI publish independent gatekeeper iterations until zero findings on the exact final head. Both typechecks, nine server tests and thirteen real-component extension/Status tests pass, including migration and French/Hebrew/Japanese/Spanish narrow layouts. Windows Tauri/WebView2 command denial passes. I use the requested admin override with the documented CI caveat: four unrelated browser failures also occurred in the final pre-correction run. The installed desktop and shared OpenCode daemon are unchanged.
2026-10-07 13:41:25 +02:00
Pascal André
c995044b64
feat(extensions): install independently distributed right-panel addons (#862)
## What changes

I add independently distributed right-panel UI extensions and an
official online catalogue in Customize right panel. Users browse/search
available addons, choose one and confirm installation directly from its
exact GitHub Release, without a manual ZIP download, rebuilding
CodeNomad or restarting OpenCode. Manual ZIP installation remains
available.

I publish the curated index, contribution rules and Session info demo at
https://github.com/NeuralNomadsAI/CodeNomad-Extensions. That repository
can host several official addons; the index can also reference
author-owned repositories. Separate means independent of the main
application repository, not a mandatory repository per addon.

I show the manifest and exact archive SHA-256 before trust confirmation.
Installation starts disabled; users enable it for all projects in the
server profile or for the exact opened folder. Replacement requires the
previous digest and revokes every activation grant. Removal is explicit.
Packages and grants stay outside project/OpenCode storage.

I keep author code out of the main renderer. API 1 exposes only session
ID, locale and appearance through a per-mount MessageChannel. It does
not expose filesystem, transcript, images, credentials, native commands
or the OpenCode proxy. Frames are sandboxed without same-origin access
and receive a restrictive CSP; obsolete responses and ports are fenced
on project/session changes, disconnects, revocation and replacement.

I document the package, permissions, API compatibility, scope,
release/checksum and maintainer rules in `dev-docs/PANEL_EXTENSIONS.md`,
with a standalone starter in `examples/panel-extension/`. GitHub's
source ZIP is not an installable package. There is no arbitrary URL
installer or automatic update.

I load catalogue metadata only during discovery. Inspection and
installation each revalidate a fresh index, exact ZIP digest and full
manifest; unsupported APIs/permissions cannot install. Downloads are
bounded, deadline-limited, credential-free HTTPS requests to GitHub's
exact release hosts, with constrained redirects. A withdrawn or changed
selection cannot become a different trusted package. Offline catalogue
failures leave installed addons and ZIP installation available.

## Scope and limits

I keep #801's assets gallery for a separate follow-up. It needs a
bounded, authorized image/history capability rather than access to
internal stores. This PR only establishes external distribution and a
minimal context API.

Windows Tauri may inject native bridge objects into subframes: object
presence is not a grant. My isolated WebView2 fixture proves parent
command execution while direct/raw child calls do not reach it, and
verifies context delivery plus DOM/network restrictions. A trusted
hostile extension can still stall its renderer or attempt
self-navigation; this is not process isolation or a universal offline
guarantee. The installer warns users to trust the author.

I have not run a native Electron/macOS/Linux qualification or changed
the shared daemon. The runtime implementation is shared between desktop
hosts; native GUI validation here is Tauri only.

## Validation

- UI and server typechecks.
- 14 focused server/registry/manifest tests.
- Real right-panel browser tests for ZIP consent, activation scopes,
replacement, revocation, context changes, stale reads and frame
isolation.
- Five catalogue/server checks and seven right-panel browser scenarios
cover metadata-only browse/search, online consent, withdrawal,
incompatibility, offline ZIP fallback, hashes/manifests, redirect
restrictions and size budgets.
- Live public GitHub index and Release download matched SHA-256
`cf80226a40dd077a6a8cc2a4b65bbb46bf33619d62007982bd7dcea34ae4545f`;
installation and activation used a disposable isolated store.
- `node scripts/test-panel-extension-native.mjs` on Windows, using the
application's locked Tauri dependencies and an isolated browser profile:
parent native call allowed; child native calls, parent DOM and network
APIs blocked; session context delivered.
- UI build, Windows Tauri release build (`--no-bundle`) and
packaged-resource smoke passed. Full browser suite results are recorded
in the follow-up validation comment.

Existing oversized files touched only for integration:
`packages/server/src/api-types.ts` (~735 lines),
`packages/server/src/index.ts` (~713),
`packages/server/src/server/http-server.ts` (~2,438).
2026-10-06 23:58:18 +02:00
Pascal André
00029c8b04
fix(pending): stop cold-worktree recovery fallback; qualify OpenCode 2.0.24 (#865)
## Summary

- Qualify and pin the generated client/plugin at OpenCode **2.0.24**,
recommended independently of the unchanged **2.0.7** technical minimum.
- **On every runtime version**, automatic Form/permission recovery uses
only the authenticated loaded-only broker. Missing capacity stops
recovery non-authoritatively; it never falls back to ordinary lists
across historical/inactive worktrees.
- Retain known requests and editor drafts through unavailable/partial
recovery and rehydration, and show a localized recovery-incomplete
status even when no request is known. Only explicit settlement
reconciliation may use ordinary lists at the attempted request's
authorized location. Keep mutation fences and settlement tombstones.
- **Remove the private reader's runtime and Effect version allowlist.**
An untested/custom/prerelease/missing version label no longer disables
recovery. Registration checks the real native RPC capability; each read
validates graph, existing-only lease, queue, codec and identity
contracts. These checks fail safely without mass-loading fallback.
Tested versions remain evidence, not grounds for blocking other
versions.

## Contract audit

The authenticated isolated 2.0.24 daemon exposes 117 native OpenAPI
paths vs 116 on 2.0.22. The new `/api/vcs/init` is not exposed by
CodeNomad. Of 167 structural schema changes, most add declared
`LocationNotFoundError` failures to location-sensitive routes; other
changes add optional `ServerInfo.capabilities.persistentPty`,
WorktreeError's literal `_tag` and the VCS-init error. Published
declaration changes: 11/30 client files (+service-probe), 3/60 plugin,
8/36 protocol and 3/102 schema files (three retired IDE/question
declarations removed). No removed declaration is imported by CodeNomad;
no consumed dependency establishes a higher minimum.

The upstream source audit leaves LocationServiceMap, Form, Permission
and RPC contracts unchanged; the Location-services wrapper changes only
its TypeScript error parameter. Effect remains rc.112. The published
native implementation chunks are hash-checked against separate receipts
before each isolated fixture run.

Native SDK service contender/probe/PTY handoff internals change, but
CodeNomad retains its selected-CLI lifecycle adapter and bounded
authenticated registration fallback rather than using
`Service.ensure/stop`. **No shared daemon restart, storage mutation or
OpenCode PR is part of this change.**

The source audit also covers compaction-agent model/budget selection,
ChatGPT's temporary remote-model synchronization removal, local-provider
discovery/cache sharing, text-capable default selection, bounded MCP
connection/catalog retries and OAuth callback timing, Windows
instruction ancestry, skill frontmatter, subagent text boundaries and
PTY runtime storage/availability. These remain native-owned; no
CodeNomad adapter change is justified by the consumed contracts.
`dev-docs/OPENCODE_V2_COMPATIBILITY.md` records the consequences and
limits: synthetic account tests are not real OAuth/provider
certification, compaction isolation does not exhaust alternate
summarizer configurations, and no desktop terminal-survival test across
service restart is claimed.

## Native loaded-only evidence

### Follow-up: unjustified version lock removed

At the user's explicit direction, remove both
`PENDING_SNAPSHOT_NATIVE_VERSIONS` and the Effect-version equality
check, as well as all version checks in registration and reader
execution. The reader no longer accepts or consults an executing-version
argument. Regression coverage registers across 2.0.7–2.0.24,
newer/custom/prerelease/missing labels and a context whose `app` getter
throws if accessed. Actual malformed/missing contracts, unsafe data,
eviction/disposal races and timeouts remain non-authoritative. The rule
against blocking untested versions is recorded in `AGENTS.md`.

The source comparison across published tags 2.0.7–2.0.24 finds an
unchanged LocationServiceMap and existing-only lookup, RPC contracts and
queue-list interfaces. Changes in older releases affect Form
cancellation feedback/state and permission rejection feedback, not queue
listing. All these tags use Effect rc.112. This is source evidence, not
a claim that all eighteen releases have passed native fixtures.

After gate removal, **29/29 reader/broker/admission tests pass**, as do
server typecheck and pruning build. Fresh published native fixtures on
**2.0.23 and 2.0.24 pass**, recovering permissions/global Forms with 100
cold candidates (three actual Git worktrees), four native boots
before/after and zero cold constructions. The fresh bounded
**full-server run on the follow-up passes: 888 passed, 0 failed, 6
skipped (894 tests, 76 suites)**. Receipts: `no-gate-server.log`,
`no-gate-native-23/receipt.json`, `no-gate-native-24/receipt.json`,
`matrix-source-inventory.json`, `server-all-no-gate-final.log`.

The follow-up also records the distinction between pinned build
dependencies and an independently updated external service in
`AGENTS.md`; no README changes. Independent read-only gatekeeper review
of the **full diff**
`1abeba78043fc6ec1fac4eb57eb6c82a541cf66e..e159068bc0a37a668814c1c5a031115dea38ed28`:
**APPROVE, 0 findings**, 59 independent targeted tests passed plus an
isolated reactive check. The review is published separately on this PR;
it is an agent review, not human approval or deployment acceptance. At
the pre-merge CI inspection, runtime contracts (minimum/latest),
OpenCode compatibility (Linux/Windows/macOS) and native pruning
(Linux/macOS) passed; general tests, native pruning on Windows and Tauri
tests were still in progress. Earlier cancelled/skipped runs are not
passes. The user explicitly requested an admin merge after zero
gatekeeper findings; no all-green CI claim is made.

The committed Bun fixture now uses the same managed `.ts` plugin
discovery shape as production, not configured-package directory
resolution. It uses an authenticated unmodified published HTTP router
in-process, with an in-memory database, private discovery paths, no
listener/service discovery and no external provider.

| Published runtime | Preloaded Locations | Locations after recovery |
Native boot logs before/after | Cold candidates | Cold constructed |
|---|---:|---:|---:|---:|---:|
| 2.0.22 | 4 | 4 | 4 / 4 | 100 (three actual Git worktrees) | 0 |
| 2.0.24 | 4 | 4 | 4 / 4 | 100 (three actual Git worktrees) | 0 |

Both runs recover three permissions, six Forms including three global
Forms. They exercise absent/present backend presence, two backends
retaining registration, expiry, return and final disposal, coexistence
with the existing Promise pruning RPC, authenticated 401 rejection,
schema limits and non-authoritative failures. The boot-log assertion
also detects briefly constructed Locations even if they later disappear
from the map.

Short-fixture RSS: 2.0.24 460,599,296 → 461,824,000 bytes; 2.0.22
463,929,344 → 461,701,120 bytes. These are receipts, **not a memory
profile or comparable deployment soak**, and do not attribute the
reported 10 GiB to this fallback.

## Validation

Environment: Windows, Node **25.2.1**, Bun **1.3.14**. All native checks
use owned processes, synthetic providers/configuration/data and explicit
isolated CLI paths; never the shared daemon or user database.

- `bun scripts/test-pending-snapshot-native.mjs <qualified-packages>
<fresh-output>`: passes separately on published 2.0.22 and 2.0.24.
- 2.0.24 native automation, pruning parent runner,
Location/worktree/proxy/event relay, environment, fork, aside, degraded
Git, prompt skills, provider usage/accounts, permission receipts and
blank-session cleanup: **12 suites pass**.
- Minimum 2.0.7 with the same 2.0.24 client/plugin dependencies: **nine
isolated suites pass** (automation, pruning,
Location/worktree/proxy/relay, environment, fork, aside, degraded Git,
prompt skills and blank-session cleanup). Operation-specific
usage/account/receipt checks do not establish a new global minimum.
- `test-compaction-isolation-native.mjs <2.0.24-cli> --context-mib 2`:
passes with native compaction and outline enabled; the second session
completes before releasing the first session's provider gate.
- Focused UI pending recovery, compaction, Forms and permission
lifecycle: **37/37 pass**. Coverage includes 100 cold worktrees on
unsupported capability, reconnection, request retention, per-kind
mutation fences, settlement reconciliation, late supported/unsupported
responses and compaction admission.
- Final browser dock/selection/mobile regressions: **44/44 pass**. The
incomplete status appears with no known request at 393 px, has no
horizontal overflow, preserves a typed answer on repeated unavailable
recovery and disappears only after full recovery. Real-shell provenance,
recursive interruptions, Android keyboards and per-conversation drafts
remain covered.
- Server/UI typechecks and shared server/UI/plugin builds: pass.
- Final full server unit run after dependency reinstall, `node --import
tsx --test --test-concurrency=2 'packages/server/src/**/*.test.ts'`:
**888 pass, 0 fail, 6 skipped** (894 tests, 76 suites). An earlier
unbounded parallel run exceeded the existing 30-second pending-broker
deadline; the bounded rerun passes without changing that deadline.
- Broad UI unit tests: **1189 pass, 2 fail**. Both failures are
reproduced from unmodified base `1abeba78` sources in an extracted tree:
`classic-dark-surfaces.test.ts` expects a removed accent-hover override;
`tool-content.test.ts` expects copy text where the renderer returns
none. These paths use OpenCode types only, no runtime client import.
This suite is **not green**; unrelated UI corrections are intentionally
not included.
- `git diff --check`: pass. Lockfile retains unrelated package
versions/integrities; npm peer metadata recalculation remains.
- Lockfile reproducibility: `npm ci --ignore-scripts --no-audit
--no-fund` passes after browser fixtures release the Windows esbuild
executable. An earlier attempt during those fixtures encountered
`EPERM`; a simultaneously launched server rerun was invalidated by
dependency removal and is not counted as product evidence.

Detailed local receipts/logs are retained under
`C:\Users\Admin\AppData\Local\Temp\opencode\q224`:
`pending-native-final/receipt.json`, `pending-native-22/receipt.json`,
`schema-audit.log`, `*-declarations.diff`,
`server-all-bounded-final.log`, `ui-pending-final.log`,
`ui-all-final.log`, `ui-unrelated-baseline.log`,
`browser-interruption-final.log`, native-suite logs and
`compaction-2mib-final.log`.

## Deployment acceptance and limits

Not deployed to the active user service. After authorized deployment,
compare passive-recovery Location boot/eviction counts and process
RSS/private memory over a comparable observation window, separating
explicit user actions. Accumulated pre-fix Locations are not
automatically evicted. Only an explicitly confirmed shared-service
restart may release them. The separate Usage-flicker work is not a
substitute for this fix.

Unknown requests cannot be exhaustively recovered on a daemon without
the capability; known requests and live events remain usable. Existing
bootstrap warming, bounded coverage, compaction admission and ownership
constraints remain documented in
`dev-docs/OPENCODE_V2_COMPATIBILITY.md`.

File-size signal: `packages/ui/src/stores/instances.ts` remains
approximately 2,300 lines; no threshold-only refactor is included.
2026-10-06 23:06:50 +02:00
Pascal André
68e4d2a401
chore: remove historical reports and generated artifacts (#857)
## Summary

Cleanup following an inventory of 146 merged PRs from August 29 through
October 6, 2026, with targeted inspection of oversized diffs, generated
files, historical reports and current references.

- Remove the palette gallery, 21 PR screenshots, ten historical
reports/plans, the historical tail of the compatibility register, and
the unused February SDK tarball/metadata under `temp/`.
- Stop tracking five generated Tauri schemas; ignore their output
directory and root `temp/`. Keep capability/permission sources, build
logic and the vendored native fixes intact.
- Remove exactly 16 unused Plugins translation keys in each of ten
locales. Preserve the dynamically selected Global/Project labels and all
active labels.
- Repair links, index descriptions and the palette-test comment.
Preserve current runtime qualification/ownership contracts, palette
attribution and all executable regression tests.

58 files changed: **7 insertions, 11,723 deletions** (net **-11,716
lines**), including 22 binary removals. No new repository files or
committed audit artifacts.

## Validation

- UI typecheck: passed.
- Production UI build through Tauri `dev:prep`: passed.
- Palette quality: 40/40 passed.
- Real-component browser Plugins regressions: 8/8 passed.
- Clean Windows Tauri build with all five checked-in schemas absent:
188/188 tests passed, including actual generated ACL authority checks.
- Warm build, delete generated schemas again, incremental rebuild:
passed; generated JSON exists and remains ignored.
- Exact baseline comparison: only the intended 16 translation entries
removed per locale; retained compatibility body unchanged.
- Retained tracked text: no references to deleted reports or removed
translation keys. Synthetic Git-history fixture paths remain synthetic
and do not read the deleted gallery.
- Permission sources and runtime/build code unchanged; no added files;
staged whitespace check passed.

Validation was local on Windows, not a claim of completed Linux/macOS
CI. Existing locale `settings.ts` files remain approximately 677-691
lines; this cleanup removes entries without unrelated restructuring.
2026-10-06 02:25:35 +02:00
Pascal André
39cad79241
chore(search): remove generated artifacts and committed documentation (#856)
Removes the four benchmark JSON exports, two screenshots, evaluation
Markdown and AGENTS note introduced by #854: 31,419 text lines deleted.
Runtime code and runnable tests are retained. Measurement summaries stay
in #854's discussion. Validation: deletion-only diff, git diff --check,
and no remaining references to the removed paths.
2026-10-06 01:20:14 +02:00
Pascal André
3e7679341c
perf(search): paint transcript matches with owned CSS highlights (#854)
Replace transcript search DOM rewrites with document-scoped CSS Highlight registrations owned by each mounted message. Preserve selection, repaint committed asynchronous content, reveal active occurrences through nested scrollers and retain an overlap-safe Unicode mark fallback. Review findings were corrected and the integrated search/system regressions and typecheck pass. Production fixtures pass on Chromium, Electron and WebKit. Record reproducible raw measurements: reduced synchronous work, alongside Electron's worse paint-opportunity tail and three unrelated permission tests reproduced on the original base. Administrator merge explicitly requested by the maintainer.
2026-10-06 01:12:30 +02:00
Pascal André
3b21c84566
fix(ui): yield and batch transcript rotation replay
Replay queued native events in bounded cooperative chunks so a delayed SDK window rotation cannot monopolize the renderer thread with repeated full-page hydration. Skip unchanged queued-ingress projection and publish one ordered dispatcher snapshot per chunk, preserving the existing pre-reduction compaction buffer.

Keep event-specific callbacks as ordering barriers, including inbox cancellation and revert, and revalidate transcript identity and generations after publications and macrotask yields. Disposal, reconnect, overflow recovery and later rotations cannot publish stale continuations. The shared UI path applies to both desktop hosts without host-specific changes.

Add real SDK/dispatcher regressions for queued hydration, unfinished replay at a timer boundary, FIFO arrivals, callback isolation boundaries and reset/overflow fencing. Update existing rotation tests to await final state. Targeted regressions and UI typechecking pass; the two full-suite failures also reproduce on the unchanged base. A Tauri guest reproduces the prior conditional stall; this does not claim attribution or resolution of every symptom in issue #851.
2026-10-06 01:00:45 +02:00
Pascal André
6f6edbbcb9
perf(ui): skip redundant outline and superseded Markdown work (#852)
## Summary

I reduced two independently demonstrated sources of redundant work in
the UI shared by Electron and Tauri:

- I reuse the timeline projection when the outline snapshot, resident
marker identities and translated labels have not changed, preserving
reactive locale updates and structural marker changes.
- I discard superseded or disposed Markdown invocations before parsing
and before publishing results, including same-key language retries and
cache hits.

Related to #851, **not a confirmed fix for its Linux Electron freeze**.
I have not reproduced the reporter's environment, and this PR
intentionally does not close the issue. Native events, transcript
authority and OpenCode service lifecycle are unchanged.

## Evidence and validation

- Real native-dispatcher/SessionView fixture with 10k outline entries:
64 sub-bucket deltas trigger **64 full-history projections before / zero
after**; changed text buckets, locale and final text still update.
- Real Markdown/parser instrumentation: cold burst **33 parses before /
one after**, warm burst **32 before / one after**. Disposal, same-key
retries, cached results, theme/highlight, wrap and full-source copy are
covered.
- 100 browser regressions passed (70 renderer/parser/outline + 6
full-source-copy + 24 history-navigation/reasoning), plus 3 outline unit
tests; UI typecheck passed.
- Independent gatekeeper: **zero actionable findings**, with 60 browser
and 6 unit tests passed independently.
- Windows Tauri `build --no-bundle`, packaged-resource smoke and
isolated launch/capture/close passed. I did not replace the installed
app or restart OpenCode. No Electron desktop build/test was run;
Chromium fixture tests do not establish Linux Electron host behavior.
- The initial concurrent history/reasoning regression run hit a shared
Vite cache `EPERM` on Windows and timed out; all 24 affected checks
passed when rerun sequentially.

The broad synthetic stream profile still shows pauses and does **not**
demonstrate an overall responsiveness win. I recorded the measured work
reductions and remaining limits in
`dev-docs/STREAMING_RESPONSIVENESS.md`, with reproducible profiling
scripts.
2026-10-05 22:32:03 +02:00
Pascal André
449b2a46f7
feat(chat): make cross-conversation requests explicit and expandable (#848)
## Approved UX
The user found cross-conversation authorization useful after trying it,
but could not clearly identify the source. They explicitly approved
revising #847: keep in-place replies with compact external previews and
prominent persistent provenance.

## Behavior
- External conversations and sessionless project requests start compact;
deliberate expansion opens their form without changing conversations.
- Source name becomes the primary heading. Subagents show their parent
context; View conversation explicitly navigates to the source.
- One bounded external preview remains discoverable alongside a local
request. Arrival does not replace the current draft; settlement leaves
foreign fallbacks compact.
- The red badge expands the selected request in place, including from
the project Info view. Native reply identity, hidden drafts and
short-keyboard footer access remain preserved.
- Labels translated in all ten locales.

## Validation
- 71 affected browser checks pass; six targeted Info-badge checks pass
after reproducing/fixing the Info entry regression.
- UI TypeScript, production UI build and diff checks pass.
- Desktop/Android-touch compact, expanded, alongside-local and
short-keyboard captures inspected.
- Independent gatekeeper will be published and corrected until zero
findings; user requested admin merge without waiting for CI.

## Scope and maintenance
This implements the revised interaction preference, not a claimed fix
for the separate Android reconnect disappearance. Installation remains
separate. Existing oversized component touched:
packages/ui/src/components/instance/instance-shell2.tsx (~1335 lines).
2026-10-04 23:14:51 +02:00
Pascal André
74e6a02f54
fix(chat): keep interruption forms within the conversation and subagents (#847)
## User-requested behavior
The user reported that seeing a question from an unrelated conversation
was problematic and explicitly selected **conversation and subagents**.
This change scopes the visible dock to the open conversation and
recursive descendants, excluding parents, siblings and unrelated roots.

## Implementation
- Shared hierarchy scope for dock and project badge; visible
counts/navigation/composer compaction use only that scope.
- Keep off-scope editors mounted, hidden and inert so answer and
permission drafts survive navigation; remember selection per
conversation.
- Explicit project-badge navigation opens the actual owner. Sessionless
global Forms use the no-session surface and remain reachable through the
badge.
- No unrelated fallback for stale focus intents; preserve native reply
identity.

## Validation
- 37 interruption dock/selection/mobile browser tests pass.
- Real-shell badge regression passes; 2 additional desktop/mobile
permission draft and owner-identity checks pass.
- UI TypeScript, production UI build and diff check pass.
- Independent gatekeeper in progress; full CI will be awaited before
merge.

## Scope
This implements the user's explicit conversation-scope preference. It
does not claim to resolve the separately observed Android form
disappearance after reconnect. No installed application was
rebuilt/replaced.

## Maintenance
Existing oversized component touched:
packages/ui/src/components/instance/instance-shell2.tsx (~1344 lines).
2026-10-04 21:44:05 +02:00
Pascal André
5c523e3f1c
fix(chat): preserve answer focus during session activation (#846)
## Summary
Follow up the three full-CI failures reported after #845. A delayed
session-activation callback could steal focus from an answer field and
insert the answer into the composer. Recheck input/dock/modal ownership
at execution and fence deactivation, disposal and superseded callbacks.

## Baseline evidence
The focus race reproduces at baseline 04654996 and #845 head;
deterministic new coverage fails against the old focus implementation.
The other two failures also reproduce on both snapshots: the transcript
fixture returned an empty body for permission-receipts, rendering error
panels that changed row geometry. Fulfill that route with valid empty
receipts; no assertion changes, added waits or forced clicks.

## Validation
- 7 deterministic activation/selection tests pass; competing inputs,
modal/dock ownership, stale callbacks, normal activation and phone
behavior covered.
- 46 transcript tests pass.
- Header/mobile/dock: 57/58 initially; one cold fixture navigation
timeout passed its isolated rerun.
- UI TypeScript and production UI build pass.
- Independent gatekeeper and full CI required before the requested admin
merge.

## Maintenance
Existing oversized file:
packages/ui/src/components/session/session-view.tsx (~720 lines).
2026-10-04 19:34:18 +02:00
Pascal André
69d33b4a8d
fix(opencode): keep service restart available in troubleshooting (#844)
## Summary

I added a permanent **Restart OpenCode service** control under
**Settings → OpenCode → Troubleshooting**, shared with startup recovery.
It confirms interruption of active work across connected clients and
does not delete session history. The existing post-update shortcut
remains available.

I enabled authenticated same-version restarts through the existing
host/WSL lifecycle while retaining downgrade/unknown-version fences,
mutation serialization and no automatic retry. Configuration reload
remains a separate action that does not replace the daemon process. This
is a troubleshooting tool, not a fix for the memory behavior reported in
#833.

## Validation

- Final commit `84b4c743e447a7bb68b81e2a276389f94d4dcbaf`: 23
service/reconnect tests and 29 real Solid/Chromium setup tests passed.
- UI and server typechecks passed; production UI build passed.
- Browser captures inspected, including French settings at 390px.
- Native desktop packaging/live installed-application validation was not
performed; no shared daemon was restarted.

The ten touched `packages/ui/src/lib/i18n/messages/*/settings.ts`
translation files remain approximately 692–706 lines. No unrelated
refactor.

Independent gatekeeper reviews are published below: pass 1 identified
one P2 (superseded confirmation could lock the runtime controls); I
fixed it and added a browser regression. Pass 2 reviewed the complete
final diff and returned **zero actionable findings**.
2026-10-04 18:41:34 +02:00
Pascal André
182bea93f7
fix(chat): keep question and permission panels usable on mobile (#845)
## Summary
Follow-up to #836 and #838. An expanded interruption now takes priority
over an enlarged composer without changing its saved height or draft.
Collapse/settlement restores normal sizing. Keep the dock non-shrinking
and bound the stack to Android visualViewport changes so response fields
and actions remain reachable.

## Reproduction and scope
Real InstanceShell at 851x393 with maximum composer height reduced the
dock to 54px and its body to 11px, clipping the response and submit
controls. The regression uses native Form events, mobile web/remote
runtime and coarse-pointer Chromium emulation.
The user's separate screenshot showed pre-836 navigation buttons: the
installed bundle still contains those old labels. Merged PRs had not
replaced that installed build. This follow-up fixes the independently
reproduced current-code height issue; it does not claim deployment to
the user's phone.

## Validation
- 7 mobile shell tests: portrait, short viewport, landscape, immersive,
saved maximum size, keyboard resize/pan, long Forms, background/global
requests and permission actions.
- 44 header/composer/interruption browser regressions and 1 isolated
Electron zoom test pass.
- UI TypeScript, production UI build and diff check pass; rendered
captures inspected.

## Gatekeeper
Independent review will be published and corrected in a loop until zero
findings before the requested admin merge.

## Maintenance
Existing large components touched:
packages/ui/src/components/instance/instance-shell2.tsx (~1327 lines),
prompt-input.tsx (~1081), session/session-view.tsx (~711).
2026-10-04 18:19:17 +02:00
Pascal André
8ce70ec414
fix(performance): recover pending requests without warming historical Locations (#840)
Recover pending Forms and Permissions through a fixed presence-owned RPC in
the existing bundled plugin, without warming historical native Locations.
Validate established execution-host origin, complete coverage, directory/Git
ownership, WSL aliases and every placement before admitting capability.
Keep generic RPC forwarding closed and preserve non-authoritative failures.

Observe native compaction before event ownership routing and defer expensive
legacy discovery before inventory reads and at forwarding. Preserve concurrent
holds, bounded missed-end probes, exact settlement reconciliation grants,
per-kind mutation fences, global/idle Forms and settled-request tombstones.
Never replay ambiguous mutations. Share presence observations, not registrations
or execution authority.

Integrate current dev receipt and event-ownership changes. Reassert the native
connection after permission receipt preparation and before granting settlement
reconciliation or dispatching mutations. Reject overflowing raw JSON numbers,
including unknown metadata, without altering native numeric codec strings.
Use eight-directory UI batches with the unchanged request deadline and URL
budget rather than weakening ownership checks or extending timeouts.

Add scoped broker, reader, presence, proxy, compaction and UI lifecycle
regressions plus an opt-in isolated native reader fixture. Independent
Gatekeeper reviews are published on the PR; R1's numeric overflow finding is
fixed and rechecked on the final head before merge.

The private reader is qualified for native 2.0.22 / Effect rc.112 only. The
global minimum and already-recommended 2.0.22 remain unchanged. Unsupported
runtimes retain guarded legacy recovery. This mitigates CodeNomad's load
amplification, not the upstream Bus issue or previously retained Locations;
installed-application freeze resolution, deployment and daemon restart are
not claimed. Preserve bootstrap-warming and bounded-scan limitations.
2026-10-03 12:18:33 +02:00
Pascal André
a076d01e79
fix(history): fill search pages and remove redundant counting (#839)
## Summary
- Continue sparse history scans until a bounded result page is filled,
publishing matches progressively across sessions.
- Remove the automatic count traversal. Show page-local results and
messages scanned directly from search responses, with no scan when
opening an empty search.
- Project text-only content in SQLite, reduce bounded RPC round trips,
and share identical location checks only inside a request.

## Validation
- UI/server typechecks and targeted server/store tests passed.
- Chromium regression covers progressive results, pagination, workspace
scope, technical toggle, empty results and absence of statistics
requests.
- Isolated native OpenCode 2.0.22 fixture passed, including all 242
workspace matches across two sessions and pruning/ownership regressions.
- Synthetic benchmark: text search materializes 9.6 KB instead of 145
MB; CPU gain is modest because SQLite still parses stored JSON. See
dev-docs/SESSION_HISTORY_QUERIES.md.

## Review
Independent gatekeeper review and post-rebase validation in progress;
findings will be addressed before administrator merge.
2026-10-03 11:36:04 +02:00
Pascal André
961f2792b6
feat(chat): preserve permission decisions and richer question receipts (#838)
## Summary
- Persist all permission decisions: allowed once, always allowed and
rejected, with request context and known reasons. Distinguish CodeNomad,
automatic Yolo and native settlements.
- Keep receipts visible alongside transcript messages even with hidden
tools; provide paginated source-less session receipts. Ownership-checked
bounded reads, atomic profile storage, deletion cleanup and stale-read
fencing.
- Enrich completed native question receipts with selected-option
descriptions, verbatim custom answers and a disclosure for other
choices. Translate labels in all ten locales.

## Validation
- Locked dependencies installed; server and UI TypeScript checks pass;
production UI build passes.
- 126 targeted server regressions during implementation, then 26
receipt/replier/service checks against the pinned client passed.
- 20 receipt/dock browser tests and 21 history navigation tests pass; 5
question decoding/copy tests pass.
- Rendered captures inspected at 393/1100px in light/dark, including
long text and pagination.

## Persistence boundaries
Native permission events are ephemeral: past lost decisions cannot be
reconstructed. Receipts are CodeNomad annotations outside native
search/copy/export. Storage namespaces follow execution host, native
root and authenticated channel; credential rotation starts a new
namespace. Bounded text excludes metadata/diffs.

## Review
Autonomous independent gatekeeper review will be published and repeated
until zero findings before the user-requested admin merge.

## Maintenance
Existing oversized files touched: server/http-server.ts (~2415),
server/api-types.ts (~717), server/index.ts (~707),
ui/message-section.tsx (~1566), ui/lib/api-client.ts (~650).
2026-10-03 07:06:03 +02:00
Pascal André
c05f7956d6
fix(events): prevent relay timeout on worktree discovery waits (#837)
## Summary

Follow-up to merged #835: fix the demonstrated dependency behind real
`Instance event relay routing timed out` disconnects, not duplicate
connection notifications.

Existing diagnostics captured relay ownership blocked in `getWorktrees
-> WorktreeInventory -> POST /api/worktree/refresh`, including a refresh
pending beyond 150 seconds and a separate ~220-second completed call.
That exceeds the unchanged 60-second relay job deadline, so the shared
relay reconnects and Usage correctly clears for all projects.

Event authorization now uses a separate **registered-only** native
worktree inventory and never starts or joins native strategy discovery.
Native project/checkout checks, physical Git membership, clone
exclusion, configured roots, nested-folder and WSL projection remain in
the shared catalogue implementation. Native/local invalidation and
workspace disposal fence both inventories and their distinct
directory-cache namespaces. Ordinary request authorization and explicit
worktree discovery retain refresh and read-your-writes behavior.
Full-location checks receive the connection attempt's abort signal.

No timeout increase, swallowed reconnect, stale authorization fallback
or quota-specific workaround. FIFO lanes, ownership retries,
generation/workspace fences and retained-work budgets are unchanged.

## Validation

- Baseline-red production-manager + relay reproduction: hold discovery
unresolved and require the linked-worktree event to route before
releasing it.
- All **248 workspace tests pass**, including event order/reconnect,
ownership, no-Git, WSL, configured Git roots and inventory invalidation.
- Server TypeScript check passes.
- Isolated OpenCode **2.0.22** location/worktree/event fixture passes,
including real pre-refresh native registration and ordered real session
events during a held fixture-manager discovery request.
- Isolated no-Git native prompt/recovery fixture passes.
- `git diff --check` passes.

## Scope / limitations

The native refresh's internal delay is not claimed fixed; the relay no
longer depends on that unnecessary discovery operation. Actual transport
failures and other stuck native reads still trigger bounded
reconnect/reconciliation. Compaction and window-resize jank are not
established causes or fixed by this PR.

The installed application, shared daemon, user settings and independent
#824 worktree are untouched. This conversation remains attached to
`D:\CodeNomad`.

Existing oversized source touched:
`packages/server/src/workspaces/manager.ts`, approximately 1,260 lines.
No unrelated size-only refactor.

Independent Gatekeeper review will be published against the exact PR
head, with findings resolved and fresh passes until zero findings before
the requested administrator merge.
2026-10-03 04:04:03 +02:00
Pascal André
7cf9b014cd
fix(chat): simplify and polish question and permission requests (#836)
## Summary
- Keep pending questions in the composer-adjacent dock and native
answers in the transcript after completion; remove redundant navigation
links.
- Separate collapse from bounded request navigation and hide navigation
for one request. Preserve the selected draft across incoming permissions
and session changes.
- Add accented window chrome, fixed action footers, readable dark
receipts and visible scrolling. Preserve permission diff-review gates
and disable form editing during submission.

## Validation
- UI TypeScript and production build passed.
- 16 Form/settlement/diff-review unit-store tests passed.
- 10 dock browser tests, 1 cross-session selection test, 5
permission/Form browser regressions, 21 history-navigation tests and 1
session-search regression passed.
- Rendered captures inspected at 393 and 1100 CSS pixels in light/dark;
mobile permission actions validated.

## Review
Independent UX and interaction reviews informed the implementation.
Autonomous final gatekeeper review in progress before requested admin
merge.

## Maintenance note
Existing large components touched: message-block.tsx (~1965 lines),
message-section.tsx (~1561), tool-call.tsx (~991).
2026-10-03 01:07:50 +02:00
Pascal André
4122438890
fix(usage): preserve quotas on duplicate connection notifications (#835)
## Summary

- Ignore repeated browser transport statuses and identical
instance/status/native-generation snapshots instead of clearing
validated provider quotas and restarting reads.
- Keep genuine reconnects, changed native generations (including a
missed disconnect), account/configuration changes, native
`server.connected`, source changes and failed-read revocation unchanged.
- Add real Solid/browser dispatcher regressions covering quota DOM
stability, in-flight refreshes, compaction independence and
stale-response fencing.

## Scope and evidence

The regression test fails before the fix: 40 duplicate connected
notifications produce 40 additional quota reads and replace the quota
display with Loading. After the fix, the same bar DOM and request cycle
remain intact. Quotas still use the native credential API and provider
HTTP endpoint; no log-based or host-credential fallback is added.

This fixes a demonstrated flicker trigger, not every live disappearance.
Initial passive captures did not reproduce a disconnect. A later capture
did confirm a real relay failure: `Instance event relay routing timed
out` at native generation 52, followed by connecting/connected at
generation 53, affecting both opened projects. This PR deliberately
continues to revoke quotas on that real boundary; it does **not** fix
the relay timeout itself. The installed desktop application and shared
daemon are unchanged.

## Validation

- 17 UI state/component/browser tests passed.
- 12 native usage/route tests passed.
- UI typecheck and production build passed.
- Before-fix regression failure confirmed; rendered fixture capture
inspected.

Independent Gatekeeper review will be published against the exact PR
head before administrator merge.
2026-10-03 00:57:04 +02:00
Pascal André
394482f97f
feat(accounts): native account controls and opt-in Codex quota selection (#793)
Expose the approved active-account dropdown with persistent credential-keyed drafts and always-visible add/rename/remove actions. Enrich only native fallback labels with a sanitized Codex login while keeping all credential values server-side. Persist opt-in automatic selection for supported OpenAI OAuth accounts and admit one fresh-quota-verified native activation before the next prompt/custom command, with local manual/policy fences, ownership and deletion admission, no model changes, and no prompt or mutation replay. Preserve dev's Missions revert and document service-wide selection and external-client compare-and-set limitations. Validated both package typechecks, the UI build, 812 server tests, 865 CI-selected UI unit tests, isolated native 2.0.22 synthetic-account/YAML fixtures, and focused Chromium/native bridge regressions. Final admin merge explicitly requested by the user; platform/runtime/native checks are green while the general tests job is still in progress.
2026-10-02 17:36:23 +02:00
Pascal André
c954841f09
revert(missions): undo PR #673 without dropping later dev changes
Revert merge c118478805 relative to its first parent after the user confirmed the merge was requested in the wrong conversation. Remove the published Missions plugin, control routes, UI, playbooks and packaging references; do not rewrite dev history or touch durable-refactor work in the separate missions-v2 checkout.

Preserve subsequent PRs #792, #829 and #830. Remove only #829's now-invalid Mission reader import, dismissal hook and dedicated reader scenario, retaining the native questions/permissions dock, file-preview navigation and its other tests. Keep the 2.0.22 package pin and parent-session creation fence.

Validation: revert applied without conflicts; all 139 original merge paths reversed; later-only paths retained except the three minimal interruption-dock integration adaptations. Server and UI TypeScript checks and 18 automation/plugin lifecycle/desktop resource tests pass using existing local dependencies. Staged diff checks are clean. Full hosted CI, browser suites and native 2.0.22 qualification were not rerun for this immediate user-authorized admin revert.
2026-10-02 16:18:06 +02:00
Pascal André
a9e624baf5
fix(opencode): qualify 2.0.22 and fence parent session creation (#830)
## Summary

Qualify **OpenCode 2.0.22**, align server/UI client and plugin pins, and
recommend this release. Keep the demonstrated **2.0.7** global minimum
and **2.0.20** Codex Usage feature-local requirement.

Block the new native `parentID` create variant in the workspace proxy:
upstream ignores the supplied location and inherits the parent's
directory. Require inspectable JSON objects to close opaque-body
bypasses. Root creation and the existing authorized fork route remain
available.

Started at `dev@0983db3c` (#828 Windows test harness), then integrated
`dev@97c361c3` (#789 Code Mode presentation). Conversation remains
attached to `D:\CodeNomad`; all work and tests use explicit separate
paths and synthetic data.

## Upstream audit: 2.0.21 → 2.0.22

- Authenticated native OpenAPI retains **116 paths**, with **11 schema
differences**: session creation gains optional `parentID`,
parent-not-found response/description; provider settings gain optional
`headerTimeout` and `chunkTimeout=false`; configured model capability
overrides become partial. No new proxy route or consumed mandatory API.
- Published declarations: **4/30 client, 2/60 plugin, 3/36 protocol,
4/102 schema** files change. Plugin session domains expose `remove` and
`compact`; CodeNomad does not add calls to them. Identifier namespace
export is additive.
- An isolated native fixture proves parent creation inherits the parent
location despite a different supplied directory. Mock and
production-proxy fixtures reject owned/foreign parents; malformed values
and opaque content types are covered before any native request. Owned
root creation stays available.
- Runtime changes include HTTP header/chunk/whole-response timeout
handling and bounded timeout retries, provider cache/error/tool-history
fixes, model capability defaults, and legacy MCP shutdown cleanup.
- Lock changes are limited to six `@opencode` packages and two workspace
entries. Integrity/dependency metadata matches independently installed
published packages; clean `npm ci --ignore-scripts` passes. Optional
OpenTUI peers are not installed by CodeNomad.

## Isolated local qualification

**Windows / Node 24.20.0**, isolated profiles, databases, services and
synthetic providers/credentials. No shared-daemon or personal-history
mutations.

- Previous **2.0.21 dependencies + runtime 2.0.22**: native
pruning/history/proxy acceptance passes.
- New **2.0.22 dependencies + runtimes 2.0.7 and 2.0.22**: seven suites
pass (automation, pruning/history/navigation, per-send environment,
inclusive forks, idle/busy side questions, blank-session cleanup,
Git-degraded recovery), plus explicit native proxy suites.
- Native/UI pruning acceptance passes through the committed parent
runner, with completion and actual child exit verified. This uses #828's
early dependency-import workaround, not the old late-import order. No
claim that underlying Windows heap corruption is repaired.
- Current compaction-isolation acceptance passes: session B progresses
while session A's provider response is held; bounded outline reads
retain daemon heartbeats. Fixture runtime selection is extended to
include 2.0.22; its assertions are unchanged. This supplemental fixture
was not qualified on 2.0.7 (explicit runtime selector rejects it).
- Native Codex Usage passes on 2.0.22 with synthetic OAuth/key
credentials and mocked quota HTTP; not a live-account/WSL test.
- Native migrations **2.0.3 → 2.0.22** and **beta-19271 → 2.0.22**
preserve full history/forks/inbox/provider selection.
- Packed standalone pruning plugin installed outside the repository
passes native acceptance.
- Native npm upgrade **2.0.15 → 2.0.22** passes; authenticated daemon
remains **2.0.15 / PID 43876** before and after.
- Full server run: **794 passed / 6 skipped / 0 failed**. Final guard
revision separately passes **68 focused server tests** and native proxy
suites on minimum/current. Aggregate runs use `--test-force-exit`.
- Targeted client/store/reducer/usage UI: **63/63** with
`--conditions=browser`, `--test-force-exit`, bounded timeout. Initial
broad UI run used the wrong Node conditions and hung at
`prioritized-read.test.ts`; only its owned processes were stopped. That
incomplete run is **not green**. The same prioritized-read tests pass
under the browser condition used by CI. No production fix is inferred
from this launch correction.
- **41 browser scenarios** pass: setup/install, auth recovery, tool
images, rendered Codex Usage and compaction responsiveness. Browser
tests do not use forced exit.
- Server/UI/Electron typechecks and production server/UI/plugin builds
pass. Revalidation after #789 integration and independent gatekeeper are
reported separately below.

Local results do not certify all real providers, Linux/macOS/WSL, or
installed Electron/Tauri hosts. Historical Windows import and Git
cleanup failures remain limitations, not repaired by this upgrade.
Remote CI is not continuously monitored and no global CI-green claim is
made.

Size note: existing `packages/server/src/server/http-server.ts` is
~2,359 lines;
`packages/server/src/server/__tests__/instance-proxy.test.ts` is ~1,139
lines. Changes are narrowly scoped; no unrelated size-driven refactor.

## Independent gatekeeper

Review launched on exact head `0a7615476034eabbff54967aacc8a93ab0e6ab12`
against `dev@97c361c33f6fa7de30be5dde31c0e26e12bab574`; verdict will be
published before any admin merge. Findings will be corrected and
reviewed again until zero actionable findings.
2026-10-02 15:47:14 +02:00
Pascal André
a80b364292
feat(chat): dock native questions and permissions above the composer (#829)
## Summary
- Answer native Forms and permissions in a persistent composer-adjacent
dock with queue navigation and source-session labels.
- Target requests from badges and inline tools; reveal off-window source
messages through bounded history navigation, closing file previews and
exposing hidden source tools.
- Render durable native question answers in the transcript and preserve
partial request/composer drafts.
- Replace the former permission modal and retain native global Form
routing and full permission-diff review.

## Gatekeeper
- Pass 1: two actionable P2 findings.
- Corrected both in fb7ed772 with regression tests reproducing failures
before the fixes.
- Independent pass 2 at fb7ed772: zero actionable findings.

## Validation
- UI TypeScript and production build passed after rebase.
- 30 focused browser and 17 native-store/unit regressions passed after
rebase.
- All six interruption-dock tests and TypeScript passed after
corrections.
- Independent final review: nine browser tests, 20 unit/store tests and
TypeScript passed.
- Final GitHub CI in progress.

See dev-docs/NATIVE_INTERRUPTION_UX.md for ownership and validation
details.
2026-10-02 14:49:52 +02:00
Pascal André
ee77c1e491
feat(settings): scoped web search configuration (4/8) (#792)
## Behavior
Global/Project websearch choice, inherited/default, disabled and
automatic/provider selection. Display effective native configuration.
Optional global API keys use native integration/credential endpoints;
environment credentials remain read-only. Scoped failures reconcile
without mutation replay, and late results are fenced.

## Contract adjustment
OpenChamber's /api/config/websearch is its backend route. OpenCode
2.0.18 has no equivalent native config write API. Reuse CodeNomad's
authorized plugin-control configuration targets, JSONC conflict-safe
edits, WSL filesystem adapter and connection/deletion fences. Preserve
unrelated fields and comments; use native watching, never implicit
location.reload.

## Validation
Server/UI typechecks pass. 51 focused server/config regression tests
pass; four real-WSL cases skipped. Real Chromium fixture passes scoped
writes, failure reconciliation, API-key clearing and late mutation
fencing; narrow capture inspected. Isolated native fixtures pass on
2.0.7 and 2.0.18 (global watching, project document persistence/reset,
foreign-directory rejection). Project discovery is disabled in native
fixtures to exclude user ancestor config; deterministic server tests
cover precedence. No shared daemon or personal data used.

## Stack/review
Depends on #791, zero findings at ea3b4ef6. Independent gatekeeper
pending; fix/re-review until zero. User requires all PRs remain
unmerged.

Size notes: existing http-server.ts (~2300), api-types.ts (~1200),
plugin-controls.ts (~810), api-client.ts (~1000) and locale settings
files exceed guidance; focused changes only.


## User-feedback correction
Clarify which search provider agents use, automatic saves, the default
across projects and the current-project override. Move API keys into a
separate collapsed section explaining that credentials are shared
service-wide and saving a key does not change the selected provider.
Environment credentials are explicitly read-only. Updated in all ten
locales; narrow Chromium lifecycle/failure test and UI typecheck pass.
Alpha in fixture captures is synthetic test data.
2026-10-02 14:49:18 +02:00
Pascal André
c118478805
feat(missions): add native dynamic session workflows (#673)
## Summary

- add a durable, project-local Missions control plane on top of native
OpenCode V2 root sessions
- expose live Mission Control navigation, task state, actor state,
reports, and evidence in the right panel
- provide bounded Pocock bug-fixing and Wayfinder exploration playbooks
without introducing a generic workflow DSL
- keep Developer Mode automation separate from mission orchestration

## Architecture

Missions uses native OpenCode V2 primitives rather than a parallel
runtime:

- root sessions are mission actors
- `queue` and `steer` are the durable actor inbox
- session metadata carries mission, task, role, and coordinator
correlation
- plugin hooks inject role context
- project-local plugin storage persists an append-only mission journal
and materialized map
- topology mutations are coordinator-only and remain scoped to one
project

The agent surface is deliberately limited to `mission.inspect`,
`mission.delegate`, and `mission.report`. The CodeNomad broker exposes
only the typed `codenomad.missions.snapshot` RPC; change events are
invalidations that trigger authoritative reconciliation.

## User-visible behavior

Mission Control shows the active mission's status, frontier, tasks, root
actors, correlated reports, and expandable evidence. It updates live,
survives reconnects, preserves the last durable map through transient
failures, and can navigate to an actor session without becoming a second
workflow executor.

All new UI strings are available in the existing 10 locales. The panel
uses the shared token, utility, and square-corner window conventions.

## Playbooks and safety bounds

- Pocock remains evidence-driven and dynamically sequences
implementation, independent reviews, resolution, and fresh validation.
- Wayfinder preserves destination, map, frontier, claims, and fog-of-war
while allowing bounded parallel research.
- Admission and resume paths are idempotent.
- Limits: 8 actors, 96 tasks, 2,000 events, and 20 missions per project.
- A green completion requires every task to be completed.

## Validation

- [x] Rebased directly on `dev` after #647
- [x] OpenCode plugin contract typecheck
- [x] Server typecheck
- [x] UI typecheck
- [x] Mission server tests: 18 passing
- [x] Mission UI/i18n tests: 4 passing
- [x] Full server, UI, Electron, and Tauri suites/builds completed
during implementation
- [x] Private runtime spike verified activation, typed RPC, restart
persistence, root-session delegation, queue/resume, correlation,
idempotence, invalidations, broker allowlisting, and checkout/worktree
storage sharing
- [x] Pocock and Wayfinder runtime demonstrations completed
- [x] Windows Tauri Mission Control validated live from active mission
through completed status, including actor navigation and expandable
evidence

## Known runtime note

A daemon that was already running before the project-local plugin
existed may fail to hot-add that plugin on Windows. Fresh daemon
activation is verified and works correctly; CodeNomad does not restart
or take ownership of a foreign/shared daemon.
## Tester feedback phase

This PR intentionally remains in draft while the session mesh receives
broader real-world use. Please exercise:

- custom missions with both idle and busy actor sessions
- Pocock implementation, independent review, resolution, and fresh
validation loops
- Wayfinder exploration with parallel frontier tasks and unresolved fog
- restart/reconnect recovery before and after delegation and reporting
- actor navigation and evidence expansion from Mission Control
- project, checkout, and worktree boundaries, including expected
authorization failures

Useful reports include the desktop host, workflow/template, exact point
of friction, expected versus observed behavior, and whether the durable
map recovered after reopening. Do not include secrets or private prompt
contents.

The unrelated automation-registry CI fix is tracked separately in #675
and is not part of this branch. After that fix lands on `dev`, this
branch can be rebased and its validation rerun before any decision to
mark it ready.
2026-10-02 14:37:45 +02:00
Pascal André
1999600424
feat(composer): native skill attachments (3/8) (#791)
## Behavior
Attach/remove skills in the composer using the current session
directory's native catalog. IDs are sent through prompt.skills; OpenCode
expands the instructions. Historical and optimistic messages show skill
labels. Queued edits restore removable skill attachments without
resurrecting removals.

## Lifecycle
Visible demand only, skill/config native updates, reconnect refresh,
coalesced trailing reads and view/session response fencing. Ten locales.
Native startup registers plugins progressively, covered by fixture and
catalog updates.

## Validation
UI typecheck passed; 53 session-action regressions passed; three focused
skill tests passed; Chromium
selection/deduplication/location/stale/coalesced/inactive scenario
passed and narrow capture inspected. Isolated native fixture passed on
2.0.7 and 2.0.18 (synthetic provider, private home/database/process; no
shared daemon). No runtime-minimum change.

## Stack and gatekeeper
Depends on #790, whose independent gatekeeper has zero findings.
Independent review of this PR pending; corrections/re-reviews continue
until zero. User requested no merges.

Size notes: prompt-input.tsx (~1120), session-actions.ts (~1000),
session-view.tsx (~720), session-actions.test.ts (~1040), and locale
messaging files exceed guidance; focused additions only.
2026-10-02 13:23:42 +02:00
Pascal André
92bc8c4185
feat(websearch): native results and provider consent (2/8) (#790)
## Behavior
Dedicated websearch source cards with safe links, publication metadata,
literal snippets and raw-output fallback. Recognized native provider
consent receives a localized heading and stacked options through the
existing Form validation/reply path. Ten locales.

## Stack
Depends on #789 (zero-finding gatekeeper at aaee7d5a). This PR contains
only step 2. All eight PRs are to remain unmerged at the user's request.

## Contracts and validation
Tagged native 2.0.7 and 2.0.18 tool/plugin/websearch.ts contracts
verified. No new API or minimum-version dependency. UI typecheck passed;
five focused parser, shape and browser tests passed, including hidden
Forms regression. Narrow rendered capture inspected. Raw results retain
copy/search via shared renderer. Existing tool-call.css exceeds
source-size guidance; change is one import.

Independent gatekeeper review pending; findings will be corrected and
re-reviewed until zero. Do not merge.
2026-10-02 13:17:22 +02:00
Pascal André
97c361c33f
feat(transcript): native Code Mode presentation (1/8) (#789)
## Increment over existing execute display
Execute already renders as a tool card through the generic renderer.
This PR adds a specialized presentation of its script and native
nested-call metadata (names, inputs, statuses), plus truncation
information. It reuses the existing aggregate output and image surfaces.
It does not introduce Code Mode execution or mission orchestration
(#673).

## Purpose
First PR in the V2 product integration series. Present execute scripts,
nested tool calls and progress, failure and native truncation
information. Preserve shared native output/image rendering and copying.

## Contract and implementation
Verified upstream Code Mode contracts at tags 2.0.7 and 2.0.18: code
input, metadata.toolCalls (tool/status/input), metadata.error. No API
calls or runtime minimum changes. Small dedicated parser and renderer,
scoped CSS, nine locales. Subsequent PRs will stack on this branch.

## Local validation
- UI typecheck passed.
- Four isolated Chromium scenarios passed: native events, history
reload, nested errors, images, collapse and narrow layout.
- Rendered capture inspected at 380px.
- git diff --check passed.

## Gatekeeper
Independent review pending; findings will be fixed and re-reviewed until
zero. User requested all PRs remain unmerged. Do not merge.

Size note: existing tool-call.css is above the source warning threshold;
changed only by adding the scoped import.
2026-10-02 13:08:14 +02:00
Pascal André
0983db3c30
fix(ci): stabilize Windows native tests and artifact comments (#828)
Stabilize the Windows pruning/UI CI harness by loading its unchanged UI dependencies before the long native/SQLite preamble. The late-import baseline reproduced locally under CI's Node 24.20.0 with native status 0xC0000374. This is a qualified import-order workaround, not attribution or repair of the underlying heap corruption; no assertions, dependencies, test skips or retries change.

Retain actual child exit status/signal, stdout/stderr, durable stages and synthetic fixture logs through a parent runner. Require explicit completion as well as exit zero, and upload parent/fixture diagnostics on failure. Preserve the original UI scenario exception if diagnostic capture fails.

Trigger artifact announcements from validation completion rather than bounded polling. Failed validation stays red in its own workflow. Run only trusted default-branch helper code, verify the originating workflow and current authorized PR head, use GitHub commit association when needed and update only bot-owned marker comments. Artifact names remain escaped display text, never executed contents.

Fifteen focused tests pass under Node 24.20.0. Two coordinator-run and one independent full Windows native/UI scenarios complete naturally with all original assertions, restart persistence and presence cleanup. YAML and diff checks pass. The published independent gatekeeper review of this exact head has zero findings.

Admin merge is explicitly requested without waiting for CI. GitHub workflow_run delivery needs post-merge confirmation; no universal CI reliability, underlying heap repair, Linux/macOS native rerun, installed app replacement or shared daemon restart is claimed.
2026-10-02 11:24:27 +02:00
Pascal André
bbbc5e3ff9
merge(dev): resolve mission integration conflicts
Integrate current dev while preserving the mission routes, durable execution controls and specialist cleanup. Retain native usage route dependencies and align local plugin dependencies and architecture guidance with OpenCode 2.0.21.

Combine the workspace file reader with the mission reader in the central session surface. Explicit reader selection dismisses the competing preview without losing stored editor drafts or the composer. Extend the real-session browser regression to cover switching between both readers.

Validate server and UI typechecks and all ten mission browser/i18n tests. Preserve the upstream Tao patch unchanged, including its original whitespace and provenance.
2026-10-01 18:49:47 +02:00
Pascal André
366830f6b4
fix(usage): preserve quotas during provider catalogue refreshes (#823)
Complete the earlier Usage flicker fix after reproducing eleven Loading flashes in twenty seconds in the installed Tauri app. Same-location provider catalogue events now revalidate quotas in place, unrelated native locations do not trigger reads, and window-label keys preserve quota rows during value changes.

Share one current-generation in-flight read and coalesce trailing refresh demand. Credential, integration, configuration, reconnect and source changes still clear old quotas immediately, fence late responses and discard obsolete trailing work. Failures revoke quotas rather than retain possibly different account data. Hidden panels remain inactive; no global browser quota cache, native API fallback or shared OpenCode lifecycle change is introduced.

Add controller and real Solid browser regressions for event bursts, location isolation, stable DOM, account changes during passive reads, removed windows and failures, and document the refresh policy. New burst/boundary tests fail before the fix; fourteen targeted tests, UI typecheck and production build pass. An independent published gatekeeper review of this exact head found zero findings and independently repeated these validations.

Admin merge without waiting for CI was explicitly requested. The installed application has not been replaced, and rebuilt installed Tauri or live account-switch validation is not claimed.
2026-10-01 17:01:03 +02:00
Pascal André
46a4ea0a85
fix(tauri): prevent macOS startup window event feedback (#821)
Backport the exact read-only macOS maximize getter from Tao #1182 into the existing 0.34.6 vendor override, preserving the Windows input backport. The original borderless getter changed AppKit style masks and generated geometry events whose persistence capture called the getter again, starving startup independently of OpenCode readiness. Window chrome, persistence policy and shared OpenCode lifecycle remain unchanged.

Add a bounded native AppKit regression with isolated original-crate negative-control artifacts, repeated warm-cache runs, getter-phase capture evidence, maximize/restore and fixed-size/decorated cases. Reject unrelated watchdog timeouts and validate runner results with platform-independent tests. Run the native regression in macOS ARM64 CI.

Validation includes the macOS Intel VM reproduction and rebuilt Tauri startup, second-window quit/relaunch with isolated OpenCode 2.0.21, 181 macOS and 188 Windows Tauri tests, Windows input negative controls, 44 targeted Electron regressions, successful ARM64 CI tests and a published ARM64 test artifact. Both independent gatekeeper findings were fixed and re-reviewed to zero findings. All test jobs passed; remaining platform builds were still running at the explicitly requested admin merge.

Fixes #819.
2026-10-01 14:58:32 +02:00
Pascal André
c2d9c663f5
feat(missions): add durable execution controls and specialist cleanup
Flatten Mission Control into compact top-level rows with two-line objectives, semantic state colors, direct readers and coordinator navigation. Put Work first, collapse secondary sections by default, and retain per-window reader and disclosure state.

Create UI missions in a prepared state and use one Play button for start/resume alongside Pause and terminal Stop. Persist explicit control intents and per-target receipts, serialize them with mission admissions, and use the authenticated desktop bridge for native root-session interruption and environment-fenced resumption. Park report notifications while paused, cancel mission-owned queued inputs on Stop, and prevent stale retries from reopening terminal missions. Native descendant suspension remains outside these root-actor controls.

Add opt-in deletion of mission-created specialist conversations. Persist cleanup targets and receipts, reserve journal capacity, and validate ownership through a narrow cleanup authority RPC before native HTTP removal. Preserve coordinators, reused/shared/moved sessions and roots with children; partial failures keep stable explicit retry identities.

Validate with 88 focused server tests, 10 browser/i18n tests, server and UI typechecks, the full build and an isolated OpenCode 2.0.21 fixture covering Play/Pause/Resume/terminal Stop, cleanup and transcript preservation. Inspect rendered controls and document the lifecycle, cleanup and styling conventions.
2026-10-01 14:02:32 +02:00
Pascal André
fb2ae42aeb
fix(layout): make desktop minimums zoom-aware and compact headers at 420px (#817)
## Summary
Follow-up to #813.

- Scale main local/remote Electron and Tauri content minimums with
application zoom: 390 × 600 CSS px, rounded up in native logical units
and capped to the monitor work area.
- Restore local window dimensions against their saved zoom; keep native
frame offsets and monitor DPI separate.
- Reserve 390 CSS px for conversations before side panels overlay.
- Force conversation-header actions into overflow below 420 CSS px,
matching timeline hiding, while preserving measured expansion and
filter/focus behavior.
- Leave Preferences, native preview guests, existing profiles and the
shared OpenCode daemon untouched.

## Validation
- 32 targeted browser tests, including real isolated Electron
framed/frameless zoom at 80/100/125/150%, menu/keyboard input and reload
persistence.
- 220 Electron native tests passed; 4 platform skips.
- 182 Windows Tauri tests passed.
- UI/Electron typechecks and UI/server/Electron builds passed.
- Rendered native captures inspected.

## Review and delivery
Independent Gatekeeper review reports will be published as GitHub
reviews. Findings will be corrected and re-reviewed until zero findings
before the requested administrator squash merge.
2026-10-01 12:44:01 +02:00
Pascal André
ad056ff5b7
fix(usage): prevent quota panel flicker and explain older service limitations (#818)
Keep the Usage panel mounted when streaming session metadata replaces the active session object. Deduplicate equal request identities without suppressing revalidation of actual instance, session, native directory, provider or model changes. This removes the repeated loading/unavailable flashes and quota reads while retaining native account, reconnect and late-response fences.

Expose only a sanitized feature-local reason for a missing native credential-list endpoint and translate the actionable service-version message in all locales. The global OpenCode minimum stays at 2.0.7; Codex Usage alone requires 2.0.20. Authentication/other errors remain generic, no legacy credentials are substituted, and service restart remains explicit.

Validation includes generated-client and HTTP route status regressions, real Solid panel lifecycles for available/unavailable usage, session identity transitions, 760 passing server tests with six platform skips, neighboring UI and desktop-resource checks, server/UI typechecks and build, and an isolated native OpenCode 2.0.20 fixture using synthetic credentials and mocked quota HTTP.

An independent published gatekeeper review of the exact head found zero actionable findings. The reviewer independently passed 71 targeted tests, exercised extra scope/lifecycle browser probes and checked all ten locales. No native desktop or live account/quota validation is claimed.
2026-10-01 12:03:56 +02:00
Pascal André
ee5f7382d7
feat(files): unify Workspace, Changes and Commits with central previews (#797)
## Summary

Unify the right-panel Git and file surfaces as **Files**, with a compact
**Workspace / Changes / Commits** switch and a shared central preview
above the
conversation composer.

- Workspace: lazy, keyboard-accessible directory tree; read-only source,
  Markdown and image previews; bounded binary-file fallback.
- Changes: indexed/working-tree files and central diffs, with existing
Git
  mutations kept in a collapsed actions section.
- Commits: paginated history of the browsed worktree, commit
details/files and
first-parent diffs, including root commits, renames, deletions and
gitlinks.
- Preserve drafts and mode navigation; fence late responses across
session and
worktree changes. Migrate previous tab customization and retain
diff/wrap
preferences. Bundle Monaco tokenizers locally for offline highlighting.
- Worktree browsing does not move a conversation or check out a branch.

## Implementation

The common Solid UI is used by Electron and Tauri. New file previews
reuse the
directory ownership boundary and bounded filesystem reader. Historical
reads use
worker Git commands with full-hash validation, authoritative file
membership,
bounded command output/time and snapshot-based paging. The old sidebar
editor
and split viewer are retired. See `dev-docs/FILES_PANEL.md`.

## Validation

Before rebasing onto current dev:
- Server, UI and Electron typechecks passed.
- Server/UI and Electron builds passed.
- 20 focused unit/route tests passed, including real isolated root and
linked
  repositories, preview bounds and directory ownership.
- 12 distinct browser scenarios passed: 5 Files flows (including real
SessionView/composer, Markdown/images/source and RTL keyboard
navigation) and
  7 existing Git lifecycle regressions.

Post-rebase validation, independent gatekeeper reviews and the Windows
Tauri
test build will be recorded below as they complete. This PR is intended
for
interactive validation before merge.
2026-10-01 11:10:50 +02:00
Pascal André
43e3ba72bc
chore(opencode): qualify and recommend stable 2.0.21
Align server/UI client and bundled-plugin pins with OpenCode 2.0.21 while keeping the demonstrated 2.0.7 application minimum and the separate 2.0.20 Codex Usage requirement. The native contract changes only by optional form-cancellation text, so existing callers need no production adapter or proxy expansion.

Extend recommendation/status coverage and update maintained architecture and compatibility references. Scope the lockfile to published OpenCode packages, including optional OpenTUI peer metadata, without refreshing unrelated dependencies.

Qualify minimum/current native suites, generated cancellation with and without a message, selected native Codex credentials, ordinary pruning/UI acceptance, standalone plugin, historical migrations and isolated upgrade retaining daemon version/PID. Typechecks, builds, 71 UI tests and 32 browser cases pass. Preserve the full server suite cleanup EPERM and its successful focused rerun as separate evidence rather than claiming a fix.
2026-10-01 01:43:49 +02:00
Pascal André
0822c794ff
fix(mobile): responsive conversation controls and proportional prompt sizing (#813)
## Summary
- Improve mobile conversation controls for #800: one-row truncated
composer controls, compact touch actions, header overflow for transcript
filters and session-change header measurement rebinding.
- Hide the timeline below 420px and reduce the worktree selector to its
accessible arrow below 460px of conversation width; preserve
preferences.
- Make the prompt itself follow visible conversation height with a saved
manual proportion, 8% minimum / 60% maximum and a 44px floor. Keep
drafts and migrate legacy pixel preferences.
- Preserve the original six preview templates and add owned native
Android/Chromium touch emulation to mobile templates in Electron and
Windows Tauri. Allow main windows to shrink to 390px.

## Validation
- UI typecheck and build passed.
- Focused browser regressions cover narrow mouse/touch layouts,
thresholds, filters, draft preservation, pointer/keyboard resizing,
proportional window resizing and visual-keyboard changes.
- Native Electron emulation and controller/window tests and Tauri
controller/restoration tests exercised during implementation; final
verification and independent Gatekeeper review will be posted below.

## Scope and limitations
- Emulation is Android/Chromium, not a claim of Gecko/Waterfox or Safari
parity; iframe fallback changes only dimensions. Physical software
keyboard behavior is represented with deterministic visualViewport
fixtures.
- No shared daemon restart, profile reset or unrelated main-checkout
changes.
- Existing large files touched: `prompt-input.tsx` (~1068 lines),
`instance-shell2.tsx` (~1325), `session-view.tsx` (~697),
`browser-frame.tsx` (~877).

Refs #800.
2026-10-01 01:04:25 +02:00
Pascal André
db1f552afd
fix(usage): use selected native V2 Codex credentials (#811)
## Summary

I replaced Codex Usage's legacy auth-file reads with the connected
OpenCode V2 daemon's selected ChatGPT OAuth credential. This addresses
the stale-file mismatch described in #808 without guessing WSL
credential paths or substituting another account.

- Resolve the provider integration in the owned session's native
location; use only its selected active credential and native accountID.
- Keep credentials server-only, OAuth refresh native-owned, and
credential export/generic RPC blocked through the browser proxy.
- Fence warm and pending quota results on account changes, reconnects
and session movement; scope the visible panel to its instance/session.
- Bound quota HTTP, reject redirects and sanitize errors. No SQLite
access or legacy/Codex CLI fallback.

The credential-list API requires OpenCode 2.0.20 for this feature only.
Older runtimes, expired native tokens and non-ChatGPT connections fail
closed; the global application minimum is unchanged. Other providers'
credential integrations are outside this focused fix.

## Validation

- Server/UI typechecks; 85 server tests; five UI unit tests; three
rendered browser scenarios; UI build and diff checks passed.
- A fresh native 2.0.20 Windows daemon with synthetic credentials
exercises the production adapter: selected OAuth/accountID, key-account
switch invalidating a warm snapshot, and recovery despite stale
auth.json. Quota HTTP is mocked; no shared daemon or real credentials
are used.
- This fixes the confirmed integration mismatch, but I have not
reproduced the author's real WSL/live account failure.

Closes #808.

Maintenance: existing `packages/server/src/server/http-server.ts`
(~2,317 lines) and `packages/ui/src/lib/api-client.ts` (~613 lines)
exceed the source-size guideline; their wiring changes remain small.
2026-09-30 17:29:13 +02:00