Creating a worktree wrote the new directory straight into OpenCode's own
project storage: the web server updated `storage/project/<id>.json` and ran an
`UPDATE project SET sandboxes` against `opencode.db` through better-sqlite3,
and the VS Code extension wrote the same JSON.
Both wrote behind the back of a running OpenCode process. OpenCode registers a
sandbox through `project.addSandbox`, which emits a project-updated event; a
direct row write emits nothing, so a worktree created while OpenCode was
running stayed unknown to it until a restart. The SQLite write also opened a
database file owned by another live process. The VS Code write was inert on top
of that: OpenCode v2 reads sandboxes from the database, not from that JSON.
Registration is not ours to perform. OpenCode records a worktree as a sandbox
itself when an instance boots for that directory, and filters entries whose
directory no longer exists when reading them back, so removal needs no
counterpart either. The only consumer on our side, the project seed in
sync/bootstrap.ts, already falls back to `project.current()` when the seed is
absent; the worktree list itself comes from git, not from sandboxes.
Reported symptom this targets: a worktree created after `openchamber restart`
never answers prompts, and restarting OpenChamber makes it work. Not reproduced
locally, so this is not confirmed as the cause.
Expose authoritative renamable on skill list responses using the same
managed-root policy as renameSkill, drop the divergent UI path heuristic,
and remove an unused rejection-test fixture.
Co-authored-by: Serhii Dziupin <makeittech@users.noreply.github.com>
Restrict in-place skill rename to managed skill directories, require
frontmatter name to match before moving, roll back/reject with tests,
hide rename in the UI for unmanaged paths, and drop unused toast keys.
Co-authored-by: Serhii Dziupin <makeittech@users.noreply.github.com>
Derive the effective OpenCode config layer (custom > project > user) from
provider sources and send it on PUT /api/provider so project/custom edits
update that layer instead of creating a global user override. Resolve
OPENCODE_CONFIG at call time and add UI/web/VS Code coverage for scoped
upserts.
Co-authored-by: Serhii Dziupin <makeittech@users.noreply.github.com>
Rename skills by moving the skill directory and updating frontmatter
name instead of recreate-with-stub-description, which wiped the body
and supporting files.
Co-authored-by: Serhii Dziupin <makeittech@users.noreply.github.com>
A diff is ordered by file path, which is almost never the order in which a
change makes sense. This adds a Walkthrough surface that reorders it: the model
groups related hunks into stops, explains what each group changes about
behavior, and orders the stops so each builds on the last. It explains and
orders; judging code stays with the existing Review action.
Reviews uncommitted work (all, staged, unstaged), a branch against its base, or
a pull request. Generation is always user-initiated — nothing runs on a timer,
on a file change, or as a side effect of opening a panel.
Invariants worth preserving:
- Hunk identity is derived on the server and only there. Ids are content
hashes, so an anchor that no longer resolves is proof the code it described
changed, and staleness needs no heuristics. The client matches ids to ids and
never recomputes them; two implementations would have to agree forever.
- The digest is never truncated. A diff that does not fit the model's context
is refused with an actionable reason, because a walkthrough written against
half a diff reads as confident and is wrong.
- Nothing disappears. Lockfiles and other generated output are excluded from
the model's input by name — never by size — and everything no stop covers is
listed at the end, so "have I seen all of it" stays answerable.
- Cost is explicit. Results are content-addressed, so returning the working
tree to an earlier state costs nothing; generation outlives its request, so a
refresh detaches the client rather than discarding paid-for work, and only an
explicit cancel stops it.
Supporting changes to shared modules:
- git: expose the existing getRangeDiff as GET /api/git
listUntrackedPaths and getUntrackedDiffs. The latter resolve the repository
once for a batch instead of per file, taking a panel
~340ms on an 80-file working tree.
- small-model: structured output across four wire forma
and abort signal, and an onOverflow policy so an oversized prompt fails
loudly instead of being silently clipped. A provider
remembered so the prompt-side fallback goes first next time.
- models.dev metadata: surface structured_output as tri
false blocks a model, a missing field does not, because the catalog omits it
for roughly half of all models.
Desktop and tablet only: VS Code serves Git through its
these routes, and the mobile shell does not consume the surface registry.
Docs: packages/docs walkthrough page in English and all eight locales.
Require an API key or {env:VAR} on client and server, add edit/prefill for
existing custom providers, save auth before config, and surface incomplete
auth plus disconnect after partial failures. Add VS Code parity tests and
drop the unused allProvidersConnected locale key.
Co-authored-by: Serhii Dziupin <makeittech@users.noreply.github.com>
Allow Settings → Providers to define custom providers (id, name, base URL,
API key, models, headers) without code changes. Persist config via OpenCode
layers, store keys through auth.set, and keep web/VS Code parity.
Co-authored-by: Serhii Dziupin <makeittech@users.noreply.github.com>
* feat: add Windows ARM64 support with x64-baseline CLI workaround
Windows ARM64 native opencode.exe fails with a Bun FFI/TinyCC dlopen
error (anomalyco/opencode#19130). As a temporary workaround:
- Bundle x64-baseline OpenCode CLI on ARM64 instead of native ARM64
(prepare-opencode-cli.mjs, env-runtime.js)
- Disable OpenCode self-upgrade on ARM64 in server, VS Code, and UI
(upgrade-capability.js, opencode-upgrade-runtime.ts, useUIStore.ts,
OpenCodeCliSettings.tsx, search.ts, SettingsView.tsx, platform.ts)
- Add ARM64 Windows cross-compile builds to release and smoke workflows
(release.yml, release-desktop-smoke.yml)
- Refactor Windows latest.yml to use combine-electron-manifests pattern
matching macOS, since two arches now produce per-arch manifests
The CI ARM64 build itself is permanent; only the x64-baseline CLI
bundling and upgrade disablement are temporary and should be reverted
when the upstream issue is resolved.
* fix(desktop): select Windows updater by architecture
---------
Co-authored-by: Bohdan Triapitsyn <artmore@protonmail.com>
The VS Code bridge re-mapped the already-mapped platform value from the
webview, collapsing every install to platform "web"; it also sent the
installId even when usage reporting was disabled. The remote-instance
update poll in the header and the post-update wait poll now send
reportUsage=false so status checks no longer count as activity.
Added new CLI and managed-instance session capabilities
Documented chat, settings, shortcut, and mobile fixes
Noted small model, desktop, and iOS updates
Users can now attach Microsoft Office documents (.docx, .pptx, and .xlsx) and OpenDocument files (.odt, .odp, and .ods) from the shared web, desktop, mobile, and VS Code chat surfaces.
Document text is extracted locally and sent as a text/plain file part with the original filename, keeping the visible user message clean. Supported embedded PNG, JPEG, GIF, and WebP images are sent as separate image parts, with matching [filename] citations preserved near their source paragraph, slide object, spreadsheet cell anchor, or OpenDocument position. Presentation notes, spreadsheet values, headers, and footers are included where available.
Document expansion is metadata-validated and bounded against oversized entries, excessive uncompressed data, unsafe paths, invalid image signatures, attachment-name races, and dangling citations after truncation. Generated document parts are published to the composer atomically.
Add fflate for worker-backed ZIP extraction and narrowly allow blob workers in the VS Code webview CSP without permitting blob scripts. Include focused fixtures for every supported format, extraction limits, positional citations, collision recovery, atomic attachment state, and CSP behavior.
Attachment pickers now share an allowlist for supported file types
Local attachments are normalized to consistent MIME types before upload
VS Code file picker now respects extension filters and larger files are allowed
Improve OpenChamber responsiveness under large session workloads while fixing
cache, synchronization, and persistence correctness across runtimes, projects,
directories, and worktrees.
- prioritize selected and visible sessions during bootstrap and defer
non-critical enrichment work
- reduce redundant message loading, event processing, store publication, and
hidden sidebar work
- prevent stale session and message requests from overwriting newer
authoritative state
- preserve existing data when authoritative fetches fail instead of treating
failures as successful empty responses
- scope session materialization, messages, drafts, queues, todos, pins,
permissions, folders, tabs, Git state, and pull request data by runtime and
directory identity
- harden runtime switching, reconnect, cleanup, mutation reconciliation, and
persisted-state ordering
- preserve live subagent Task linkage when metadata arrives after an older
message request or while streaming parts are suspended
- coalesce overlapping tail refreshes without losing newer refresh demand
- improve cold-session loading by moving deferrable work out of the critical
bootstrap path
- isolate URL authentication, mobile credentials, native secrets, and other
runtime-owned state across endpoint changes
- bound long-lived caches and remove avoidable allocations from event and
rendering hot paths
- limit virtualization to archive collections where it improves rendering
without disrupting active sidebar layout
- stabilize session folders, pin ordering, expanded state, and persisted
sidebar behavior
- open skill files through the same secure editor and outside-workspace grant
flow used by file navigation, including worktree sessions
- expand regression coverage for stale completions, runtime collisions,
reconnect behavior, persistence races, authoritative empty results, and
subagent refresh ordering
- document the updated synchronization, cache ownership, performance, and
runtime-isolation invariants
Add a root-session action that creates a generated worktree from the session directory's current branch, transfers uncommitted changes, and moves the parent session plus its descendants through OpenCode's control-plane API.
Reuse existing project/worktree topology and quick-create behavior, keep the UI non-blocking, reconcile live and global session state across directories, and roll back partial moves and failed worktree creation safely.
Split worktree bootstrap readiness into directory-created, git-ready, and setup-ready phases across web and VS Code. Session moves wait for Git readiness while existing setup-aware flows continue waiting for full setup completion, and worktree removal is serialized with active bootstrap tasks.
Expose the move only for idle root sessions, show localized progress and explanatory tooltips in the sidebar, and keep pending/ready worktree metadata synchronized with authoritative session attachments to avoid stale setup indicators.
Add coverage for control-plane payloads, session-state migration, bootstrap phase ordering and compatibility, removal races, progress metadata, and fast-ready attachment races.
Retries transient index.lock conflicts during worktree population
Removes unchanged stale locks automatically and continues bootstrap
Adds coverage for stale lock recovery
Updates the SDK dependency across web, UI, and VS Code packages.
Refreshes the lockfile and package versions to match the release.
Adds unreleased changelog notes for the current set of user-facing changes.
Replace the legacy terminal flow with a shared authenticated WebSocket
runtime used across web, desktop, relay, and mobile surfaces.
- introduce the v3 terminal protocol with scoped attachments, snapshots,
ordered output, bounded replay history, reconnects, and explicit lifecycle
- harden PTY creation, restart, resize, close, force-kill, idle cleanup,
shell selection, login mode, environment sanitization, and appearance sync
- add runtime-aware terminal APIs with relay authentication and Electron parity
- add a fullscreen mobile terminal workspace with touch scrolling,
long-press selection, safe-area controls, quick keys, and Ctrl/Alt input
- add terminal selection attachments, preview detection, project actions,
shell settings, and localized UI
- harden Ghostty rendering, resize recovery, Unicode handling, block
characters, line height, and stale-row behavior
- remove the obsolete terminal SSE path and update reverse-proxy guidance
- expand terminal runtime, transport, input, selection, and store coverage
- avoid duplicate web builds when preparing mobile assets in root CI builds
Add a VS Code-specific foreground permission responder while preserving the server-owned implementation for web, desktop, and mobile runtimes.
Persist the authoritative VS Code policy in extension global state and expose matching GET/PUT bridge routes. Broadcast policy updates to the sidebar, session editor panels, and agent manager so every active webview observes the same explicit per-session policy.
Resolve missing child-session lineage through OpenCode, honor nearest explicit ancestor overrides, deduplicate concurrent requests, retry transient replies, and reconcile pending permissions after enablement, bootstrap, and reconnect. Treat resolved requests as handled and route notification suppression through the same responder outcome.
Keep post-toggle reconciliation failures non-fatal after policy persistence and fail closed when lineage or replies cannot be confirmed. Document that auto-accept intentionally cannot run while every OpenChamber webview is closed or suspended.