Preserve native V2 session and message cursor semantics while keeping restored history, concurrent roots, drafts, and interruption state authoritative across reconnects and client replacement. Historical scroll restoration and conversation search now load older pages safely with bounded, retryable progress, and partition commits reject snapshots above the native 256 MiB budget.
Serialize workspace location eviction against creation, release failed initial daemon identities, and translate WSL certificate paths under one deadline. Electron and Tauri now retain window persistence through failed shutdown or close operations, fence navigation generations, bound CLI cleanup, and keep remote-window origin and TLS authority isolated across concurrent reuse.
Refresh the architecture guide for the current Forms-based V2 client and strict Electron/Tauri parity. Coverage includes 277 server tests, 333 UI tests, 163 Electron tests, 117 Tauri tests, all TypeScript typechecks, Rust formatting, and complete Windows Electron ZIP and Tauri NSIS builds.
Use the official host and WSL OpenCode service lifecycle instead of private daemon ownership. Workspace deletion now evicts only the selected location while shared sessions, agents, messages, and executions remain available to other windows.
Add profile-scoped singleton multi-window support for Electron and Tauri, isolate local window UI state in a durable partition graph, and preserve migration, fencing, bounded persistence, and cross-host ownership semantics. New Window and New Instance are exposed together in the native Window menu.
Harden renderer authority, remote profiles, SSE identity, idle attention, git-status concurrency, SideCar sandboxing, shutdown, generated Tauri ACLs, documentation, and CI coverage.
Validated with server, UI, Electron, and Tauri test matrices; TypeScript checks; cargo fmt; production Electron/server/Tauri builds; diff checks; and a packaged Windows smoke covering singleton focus, --new-window, one shared backend, menu placement, and slot hash verification.
Migrate the Status panel from interactive PTYs to the location-scoped shell API, refresh shell state after lifecycle events and reconnects, and route locationless shell events by their owned working directory.
Allowlist shell routes explicitly and verify ShellInfo.cwd before every ID-scoped request, including trailing-slash aliases, while preserving native output cursor parameters. Keep PTYs separate for interactive terminal use.
Load project metadata before the first session inventory, preserve native projected message order, invalidate inactive transcripts instead of reloading every transcript after reconnect, and keep native shutdown terminal without latching ordinary navigation flushes.
Update V2 documentation and CI test paths. Validated with UI and server typechecks, 15 focused UI tests, 35 focused server tests, and git diff --check.
Stop comparing the selected OpenCode CLI version with the generated client package and stop constraining shared-service discovery to that exact string. Runtime releases can now update independently while existing health, location, API decoding, and launch-signature checks continue to fail closed on actual incompatibility.
Update migration and architecture guidance so the strict gate is not reintroduced. Validated server typecheck, 32 focused manager/service/identity tests with one platform skip, Tauri release build, NSIS installer hash, and diff cleanliness.
Merge live createData projections into REST history and reset their event cache for every internal stream generation. Load sessions by validated project scope across all descendant depths and apply native active state to later root pages.
Pin the updater and standalone server lockfile to the startup-compatible client version. Decode and authorize native session cursors, permit global Form actions, and prevent the WSL stop path from invoking the client's host PID fallback.
Make worktree deletion server-authoritative by inventorying the complete native project, moving affected session families with verification and rollback, and failing direct delete calls closed when evacuation cannot complete.
Validated with server and UI typechecks, 254 server tests plus 3 platform skips, 247 UI CI-partition tests, 122 Electron native tests, server/UI/Electron production builds, standalone server lockfile installation, Tauri cargo check --locked, and git diff --check.
Pin the server and UI client to the installed beta runtime and reject mismatched CLI versions before shared-service startup. Delegate proven shared-service shutdown to Service.stop while retaining CodeNomad lease, peer, registration, endpoint, and process-identity checks.
Adopt native Forms and the client/solid data reducer for live messages, tools, permissions, and input forms. Propagate internal stream generations into authoritative reconnect reconciliation and replace directory-wide session scans with native project cursor pagination.
Fail worktree deletion when session evacuation fails and deduplicate canonical workspace folders instead of exposing non-isolated duplicate instances. Update migration notes and CI coverage for the reviewed contract.
Validated with server/UI/Electron typechecks, 244 UI partition tests, 122 Electron native tests, 248 server tests plus 3 platform skips (the sole Windows cleanup race passed in isolation), UI/server/Electron builds, Tauri cargo check --locked, and git diff --check.
Update the experimental OpenCode client, protocol, and schema dependencies to the latest reviewed next release while removing the exact CLI version gate from shared-service discovery. This lets CodeNomad use current opencode2 releases instead of timing out solely because the runtime advanced.
Refresh migration, contributor, architecture, and skill guidance to require release-note, documentation, declaration, and proxy-parity review on each upgrade. The isolated opencode2 database behavior is documented consistently.
Validated with server and UI typechecks, 36 passing targeted service/workspace tests, a release Tauri build, and a packaged desktop smoke. The smoke opened D:\CodeNomad, reused three existing sessions, and received three distinct exact prompt responses from opencode2 next-17444.
Merge upstream dev into the OpenCode V2 foundation while preserving native V2 session, provider, proxy, PTY, and explicit database behavior.
Resolve desktop workspace-open and provider visibility conflicts across Electron and Tauri, bound local API requests, refresh standalone dependency locks, and keep grouped integration preferences keyed by native provider IDs.
Validated with desktop typechecks, 267 UI tests, 308 server tests, 122 Electron tests, 74 Tauri tests, packaged builds, and an exact OpenCode 0.0.0-next-17353 Tauri smoke covering prompt, reload, agent fallback, and PTY lifecycle.
Restore reliable V2 catalogs, agent identifiers, cursor pagination, prompts, variants, attachments, forms, native event reconciliation, Yolo persistence, and location-aware PTY controls. Prevent completed control records from appearing as streaming placeholders and keep live output refreshing during sustained token streams.
Harden the shared service and workspace proxy with explicit OPENCODE_DB isolation, launch-signature validation, traversal protection, WSL namespace translation, ownership-scoped routes, bounded SSE backpressure, reconnect recovery, and safe process-proof transfer and shutdown semantics.
Align provider, VCS, LSP, update, documentation, and CI behavior with the experimental next-17353 contract. Validation includes server/UI/Electron typechecks, 252 workflow UI tests, focused server suites, production UI/server builds, 68 Tauri tests, and a real V2 workspace/session/prompt smoke.
Remove the duplicate Tauri native event transport and use the server EventSource stream consistently across web, Electron, and Tauri clients. Align the generated client and required opencode2 CLI on next-17353.
Restrict workspace proxying to the required V2 API surface, enforce session and directory ownership, validate local file URIs, strip routing headers, and tighten provider, Yolo, worktree, and session event state handling.
Protect the shared service lifecycle with private registration state, process-identity leases, safe ownership transfer, bounded shutdown, Windows executable resolution, and WSL namespace-aware PID verification. Unknown wrappers now fail closed rather than leaving an unowned service.
Validated with server and UI typechecks, 433 UI tests, focused server lifecycle and proxy suites, 67 Rust tests, server and UI builds, and a real next-17353 service lifecycle smoke test.
Replace the V1 SDK, custom plugin, and per-workspace runtimes with the pinned OpenCode V2 client and one shared service. Model workspaces through native locations and route sessions, messages, events, files, VCS, permissions, questions, providers, commands, and MCP directly through V2 APIs.
Remove the legacy plugin and background-process layers, use native Shell and PTY support, preserve server-side Git mutations where V2 lacks parity, and update the UI, packaging, CI, architecture documentation, and translations for the new model.
Add focused coverage for shared-service ownership, Windows and WSL startup, proxy boundaries, worktree event routing, native event normalization, provider authentication, voice instructions, and location-scoped requests. Server and UI typechecks pass; remaining security review items and the real opencode2 smoke test are documented in MIGRATION_V2.md and will be completed before the draft PR is marked ready.
## Summary
Yolo (permission auto-accept) currently lives entirely in the UI. Each
browser keeps its own toggle in `localStorage` and auto-replies to
permission requests over a 4-hop path (`OpenCode → server SSE → UI →
server proxy → OpenCode`). The server — which already sits on the event
stream that carries every `permission.asked` — does none of the work.
This PR makes the **server authoritative**: it owns the toggle state,
resolves family-root inheritance, and performs the auto-reply in-process
via loopback using the same `"once"` semantics the UI used to send. The
UI becomes a pure view: it toggles via REST and mirrors state from a
`yolo.stateChanged` SSE event.
## Why
- **Correctness**: the server already consumes the instance SSE stream
(`InstanceEventBridge`); auto-accepting there is the natural choke point
instead of bouncing to the UI and back.
- **Multi-client**: previously each browser had independent
`localStorage` state and never synced. Toggles now broadcast to all
connected clients in real time.
- **Headless**: Yolo keeps auto-accepting even when no UI is connected
(useful for long autonomous runs).
- **Latency**: drops from 4 hops to a single in-process loopback call.
## What changed
**Server (new, authoritative)**
- `permissions/auto-accept-store.ts` — in-memory state keyed by family
root. Faithful port of `resolvePermissionAutoAcceptFamilyRoot`:
fork/`revert` sessions root at themselves; enabling any member enables
the whole family.
- `permissions/auto-accept-manager.ts` — subscribes to `instance.event`,
builds the session tree from `session.created/updated/deleted`
(`properties.info`), intercepts `permission.v2.asked` /
`permission.asked`, dedupes in-flight replies, emits `yolo.stateChanged`
/ `yolo.autoAccepted`, clears per-instance state on
`workspace.stopped/error`.
- `permissions/opencode-replier.ts` — default replier calling OpenCode
directly (`getInstancePort` + auth header), mirroring
`background-processes/manager.ts`.
- `server/routes/yolo.ts` — `GET/POST
/workspaces/:id/yolo/sessions/:sid[/toggle]`, following existing route
conventions.
- `api-types.ts` / `events/bus.ts` — `YoloStateResponse` + the two new
event types registered in `onEvent` so they flow over `/api/events`.
**UI (pure view)**
- `permission-auto-accept.ts` — removed `localStorage`, persistence, and
drain logic; now a runtime (non-persisted) projection.
`resolvePermissionAutoAcceptFamilyRoot` is **retained as a display aid**
so the badge still lights up for child/sub-sessions of an enabled family
(preserving the inheritance UX).
- `instances.ts` — toggle calls REST (optimistic, reconciled on success,
reverted on failure); subscribes to `yolo.stateChanged`;
`ensureYoloStateSynced` backfills the active session's state on first
connect (deduped per session, reset on SSE reconnect so it re-syncs
after a server restart).
- `session-events.ts` — removed the three
`drainAutoAcceptPermissionsForInstance` hooks (the server drains now).
- `api-client.ts` — `getYoloState` / `toggleYolo`.
## Behavior parity
| Aspect | Before | After |
|---|---|---|
| Reply semantics | `"once"` | `"once"` (unchanged) |
| Inheritance | whole family (root + non-fork descendants) | **same** |
| Fork isolation | `revert` session is its own root | **same** |
| Persistence | UI `localStorage` | none (intentional, see Notes) |
| Multi-client sync | ❌ independent per browser | ✅ real-time via SSE |
| Works with UI closed | ❌ | ✅ |
| Auto-reply path | 4 hops | 1 in-process hop |
## Testing
32 unit tests added (`node:test`), all passing. Server + UI typecheck
clean.
- **Store (16)**: inheritance (parent/child/sibling), fork isolation,
cyclic parent chains, late parent discovery, `revert` re-rooting,
per-instance independence, tree maintenance.
- **Manager (13)**: real `properties.info` event shapes, v2 vs legacy
reply, in-flight dedup + retry-after-resolve, `yolo.stateChanged`
emission, `session.deleted` keeps toggle, `workspace.stopped` clears
state, `stop()` unsubscribes.
- **UI (3)**: retained `resolvePermissionAutoAcceptFamilyRoot`
display-projection tests.
## Notes for reviewers
- **No persistence is intentional** for this milestone — server restart
resets all Yolo state (matches the agreed scope). The UI mirror
self-heals via SSE reconnect + `ensureYoloStateSynced`. Persistence can
be layered on later (e.g. into `~/.config/codenomad/config.json`)
without touching the manager.
- **Family-root resolution lives in two places on purpose**: the server
resolves it to decide whether to auto-reply; the UI resolves the same
pure function to render the badge instantly (synchronous memo). Both are
faithful ports; no network round-trip is added for display.
- **`properties.info` nesting**: OpenCode wraps session records under
`properties.info` for `session.*` events (permission events are flat).
The manager handles both and the tests use the real nested shape to
guard against regressions.
- `getYoloState` / `yolo.autoAccepted` are wired but `yolo.autoAccepted`
is not yet consumed by the UI — it's available on the wire for future
observability (e.g. an audit log / toast).
## Risk / rollback
The change is additive on the server and the UI gracefully degrades to
the SSE mirror. If the server lacks the new routes (mixed-version), the
UI's optimistic toggle still flips locally and `toggleYolo` failures are
logged + reverted, so no hard breakage.
---------
Co-authored-by: Pascal André <pascalandr@gmail.com>
## Summary
This PR removes tracked NomadWorks/OpenCode/task-tracking artifacts that
were accidentally committed to the repository and now interfere with
local NomadWorks usage for other contributors.
NomadWorks generates local workflow state such as `tasks/`, SCR
registries, and codemaps as needed. Keeping those generated artifacts
tracked in the shared repository creates stale state, false active
tasks, and confusing/broken NomadWorks behavior for other users who
initialize or run the workflow locally.
## Problematic commits / artifacts
The cleanup addresses artifacts introduced by the following
Shantur-authored commits:
- `e708c565ef`
- `docs(wake-lock): record wake-lock change workflow`
- Introduced NomadWorks wake-lock SCR/task artifacts:
- `docs/scrs/SCR-2026-04-21-001-wake-lock-system-sleep-only.md`
- `tasks/current.md`
-
`tasks/discussions/DISCUSSION-001-wake-lock-behavior-change-for-macos-sleep-vs-screen-lock.md`
- `tasks/todo/055-wake-lock-investigation.md`
- `tasks/todo/056-wake-lock-behavior-change.md`
- `tasks/todo/057-implement-system-sleep-only-wake-lock.md`
- `a337c19b63`
- `Init nomadworks`
- Introduced tracked NomadWorks/OpenCode initialization artifacts:
- `.nomadworks/**`
- root `codemap.yml`
- `docs/scrs/current.md`
- `docs/scrs/done.md`
- `tasks/done.md`
- `.opencode/opencode.jsonc`
- `.opencode/package-lock.json`
- The removed `.opencode/opencode.jsonc` only contained the OpenCode
schema plus a commented NomadWorks plugin entry:
- `"$schema": "https://opencode.ai/config.json"`
- `// "@neuralnomads/nomadworks@0.1.0-rc.10"`
- The removed `.opencode/package-lock.json` was an orphan lockfile with
no tracked `.opencode/package.json`. It pinned old OpenCode
plugin/runtime packages, notably:
- `@opencode-ai/plugin@1.14.24`
- `@opencode-ai/sdk@1.14.24`
- Those pinned OpenCode versions are stale for the current
CodeNomad/OpenCode integration, so keeping this lockfile is misleading
and can imply an unsupported local plugin setup.
- `b06b8104a5`
- `Add task specifications for Phase 5 advanced input features`
- Introduced tracked task-planning artifacts including:
- `tasks/todo/015-keyboard-shortcuts.md`
- `tasks/todo/020-command-palette.md`
- `tasks/todo/021-file-attachments.md`
- `tasks/todo/022-long-paste-handling.md`
- `tasks/todo/023-symbol-attachments.md`
- `tasks/todo/024-agent-attachments.md`
- `tasks/todo/025-image-clipboard-support.md`
- `0a3ac6cbf2`
- `docs: add theme overhaul task series`
- Introduced tracked task-planning artifacts `tasks/todo/041-*` through
`tasks/todo/045-*`.
- `cb56eed4f9`
- `docs: add tailwind refactor follow-up tasks`
- Introduced tracked task-planning artifacts `tasks/todo/046-*` through
`tasks/todo/048-*`.
- `7267baf23d`
- `docs: queue remaining style cleanup tasks`
- Introduced tracked task-planning artifacts `tasks/todo/049-*` through
`tasks/todo/054-*`.
Some older mixed product commits also added `tasks/done/*` or
`PROGRESS.md` while introducing real product code. Those commits should
not be fully reverted because that would remove product functionality,
so this PR removes the stale tracking files directly in a final cleanup
commit.
## Changes
- Reverts the previous partial NomadWorks cleanup so the full original
faulty state can be reverted cleanly.
- Fully reverts the original `Init nomadworks` commit.
- Fully reverts the wake-lock NomadWorks workflow artifact commit.
- Removes remaining stale historical progress/task-tracking files that
are not used by CodeNomad runtime, builds, or GitHub workflows.
- Removes stale `.opencode` root config/lock artifacts introduced by the
NomadWorks initialization because the config only references a commented
NomadWorks plugin and the lockfile pins unsupported old OpenCode
packages without a matching package manifest.
## Validation
- `git status --short` is clean.
- `git diff --check upstream/dev..HEAD` passes with no output.
- Final diff only removes tracked NomadWorks/OpenCode/task/progress
artifacts; no runtime source files are changed.