Commit Graph
27 Commits
Author SHA1 Message Date
Bohdan Triapitsyn 4901cf60b8 fix(projects): deterministic project identity + safe per-project persistence
Derive project.id from project.path (path_<base64url(path)>), shared helper on
both server (lib/projects/project-id.js) and client (lib/projectId.ts). Replace
random UUIDs so icons, notes, todos, actions, setup-worktree, plans and
scheduledTasks share one id across restarts and reinstalls.

Fix read-then-overwrite clobber in project-config.js: scheduled-task writes now
merge with the existing project json instead of replacing it, preserving
client-written fields that live in the same file.

On settings load migrate legacy UUID ids to canonical path ids, moving config
json, storage dir contents and icon files, and remap activeProjectId. Scan for
orphan non-path_* project configs and merge them into the canonical project
when a \$ROOT_PROJECT_PATH/<file> reference resolves on disk, logging any that
can't be matched.

Client openchamberConfig.writeOpenChamberConfig re-asserts server-owned keys
(version, scheduledTasks) on write to defeat the symmetric race. Stores and
persistence derive ids from path consistently.
2026-04-18 13:46:38 +03:00
jwcrystal f5535dcaf1 fix: recover from sleep/wake disconnection with connection state tracking and immediate health check (#940)
When the computer sleeps and wakes, the SSE/WS event stream drops
silently. Messages appeared sent (optimistic insert) but never reached
the OpenCode server, and the user had no indication the system was
disconnected.

Three fixes:

1. Connection state tracking: add onDisconnect callback to the event
   pipeline. Stream failures set isConnected=false in useConfigStore;
   successful reconnect sets isConnected=true.

2. Send guard: optimisticSend, respondToPermission, and
   respondToQuestion now check isConnected before making API calls,
   throwing a clear error that surfaces as a toast to the user.
   The /compact command also checks connection with error feedback.

3. Faster server recovery: add triggerHealthCheck() to the server
   lifecycle and wire it into the WS event stream runtime. When the
   upstream OpenCode connection fails, the server immediately checks
   health and restarts if needed, instead of waiting up to 15s for
   the periodic health check.
2026-04-17 18:48:39 +03:00
Bohdan Triapitsyn c494d9f8b9 feat: add desktop LAN access setting 2026-04-17 18:05:53 +03:00
YifanandBohdan Triapitsyn bee9d19f3a feat(web): add WebSocket transport for message event streaming with SSE fallback (#764)
* feat: add websocket message stream transport

* fix: avoid false missing session directories in sidebar

* fix: re-probe project root session directories

* refactor: use button group for message stream transport

* fix: resolve chat input hook dependency warning

---------

Co-authored-by: Bohdan Triapitsyn <artmore@protonmail.com>
2026-04-17 11:07:26 +03:00
Bohdan Triapitsyn 4f228f768d feat: add scheduled tasks with locale-aware scheduling and safer desktop quit flow (#920)
* feat: keep desktop app running in background when closing last window

Closing last window hides it instead of quitting — sidecar keeps running
Cmd+Q now shows confirmation dialog warning about stopping background processes
Clicking dock icon reopens hidden window or creates a new one

* docs: add scheduled tasks impl plan

* feat: add scheduled tasks runtime, api, and ui

* feat: conditionally confirm desktop quit on risks

* chore: remove scheduled tasks plan doc

* feat: add scheduled tasks runtime and management UI

Add server-side scheduled task runtime with project-backed config persistence
Add task scheduling UI and API integration for creating and editing schedules
Add tests for runtime scheduling behavior and project config validation

* feat: add locale display preferences for scheduled tasks

Add Appearance settings for time format and week start with settings.json persistence
Apply preferences in scheduled task editor for time display and weekday ordering
Rename Thinking level control and disable it when model variants are unavailable

* feat: improve scheduled tasks editor and sidebar action order

Reorder session sidebar header actions to separate creation and management tools
Polish scheduled tasks dialog layout and controls for clearer editing flow

* feat: polish scheduled task editor usability

Improve scheduled task dialog layout for clearer scheduling controls
Refine time and weekday inputs for more intuitive task configuration
Update editor labels and control states for better model variant guidance

* feat: add prompt autocomplete and command-aware scheduled runs

Add @ and / autocomplete support to task, multi-run, and agent manager prompt fields
Fix agent mention selection so subagents can be inserted from @ suggestions
Run scheduled prompts as commands when they match slash commands, with message fallback
2026-04-16 15:55:08 +03:00
Bohdan Triapitsyn fbb9330b1c fix: reduce Windows console popups in web backend
Prefer graceful process termination before taskkill fallback
Force ConPTY for Windows terminal sessions to avoid console flashes
Keep git and server process operations running without visible command windows
2026-04-14 23:41:53 +03:00
马曜峥行 43a4c0c874 add tree view (#906) 2026-04-14 20:08:59 +03:00
Dave OteroandBohdan Triapitsyn 75a10ea66c Add passkey login for protected UI (#845)
* feat(auth): add passkey login for protected UI

* fix: polish passkey setup and correct WebAuthn user IDs

* feat: improve passkey login management

* build: align passkey deps with upstream main

* refactor: move ui auth out of opencode module

---------

Co-authored-by: Bohdan Triapitsyn <artmore@protonmail.com>
2026-04-11 22:36:02 +03:00
Dr. ZedandBohdan Triapitsyn 636dcd5314 fix: improve Windows managed OpenCode shutdown and launch behavior (#844)
* fix: windows shutdown and restart orphaned cleanup

* fix: launch managed OpenCode directly on Windows
Unwrap OpenCode wrappers to launch directly on Windows, improving shutdown reliability and avoid orphans.

* fix: restore desktopNotifyEnabled in health snapshot

---------

Signed-off-by: Dr. Zed <142888684+DocterZed@users.noreply.github.com>
Co-authored-by: Bohdan Triapitsyn <artmore@protonmail.com>
2026-04-11 22:29:09 +03:00
Bohdan Triapitsyn 5f0d1623ae feat: expand magic prompts coverage and split generation prompts (#835)
- Add configurable visible/instructions prompt families for commit/PR generation, PR checks/comments flows, and git conflict resolution helpers.
- Refactor prompt sending to explicit visible + synthetic parts instead of newline-based splitting, with legacy override migration for old keys.
- Polish Magic Prompts settings UX with grouped sidebar entries, tooltip-based descriptions, AI icon, and validation that visible prompts cannot be empty across web and VS Code runtimes.
2026-04-07 22:51:14 +03:00
Bohdan Triapitsyn e9c7c9a436 fix: improve web self-update package manager detection
- Detect update package manager from install ownership across npm, pnpm, yarn, and bun
- Fix web self-update restart command so the server comes back cleanly after install
- Add clearer update logs with package manager choice, commands, and restart context
2026-04-07 13:02:30 +03:00
Bohdan Triapitsyn db19f83f46 fix: restore remote OpenCode providers and startup errors
- Fix OpenChamber proxying to the correct OpenCode host for remote VPS setups
- Show a clear empty-state error when OpenCode is not reachable
- Harden session event routing for early or mismatched directory events
2026-04-07 01:17:12 +03:00
Bohdan Triapitsyn 9254ec0783 fix desktop notifications and chat scroll stability 2026-04-06 17:36:08 +03:00
Bohdan Triapitsyn 4663abd6f3 refactor: isolate chat hot paths and lazy server watchers
Split static history from live tail, stabilize chat data identities, and reduce scroll-shell churn so old viewport content stops waking on stream deltas. Also defer watcher startup and health polling so idle runtime work better matches actual usage.
2026-04-05 15:36:11 +03:00
Bohdan Triapitsyn d9fdd39f99 fix: restore proxied chat event streaming
- Add dedicated SSE passthrough for proxied chat events
- Keep generic API proxy behavior for non-stream requests
- Add regression coverage for nginx-safe SSE headers
2026-04-01 17:01:35 +03:00
shekohex 7b0e279a30 fix(server): strip hop-by-hop proxy response headers (#813)
* fix(server): strip hop-by-hop proxy response headers

* chore(ui): remove unused markdown runtime destructures
2026-04-01 16:19:20 +03:00
JovinesandJovines ed9d31c681 fix(server): force identity encoding for OpenCode proxy requests (#808)
Co-authored-by: Jovines <jovines@qq.com>
2026-04-01 09:24:46 +03:00
Bohdan TriapitsynandIuliia Ivashko c9e31a0e6c perf: harden sync architecture and modularize runtimes (#803)
* fix: added desktop app background throttling

* perf: add streaming debug metrics panel

- Show streaming performance metrics in the debug panel
- Auto-enable stream profiling while the panel is open
- Add JSON export for sharing UI and VS Code metrics

* perf: batch streaming updates more aggressively

- Buffer message deltas and metadata updates to cut render churn
- Skip no-op part updates before they touch the message store
- Fix the desktop debug panel shortcut binding

* perf: split streaming event handling and coalesce deltas

- Move streaming content events onto a dedicated fast path
- Defer non-critical stream side effects off the hot path
- Merge repeated message delta events before they reach the UI

* perf: isolate streaming rows from chat rerenders

- Memoize chat rows against render-relevant message changes only
- Read live assistant text directly from store to narrow streaming updates
- Split the active streaming entry from the stable message list path

* perf: streamline chat streaming and SSE proxying

- Reduce chat rerenders around the active streaming path
- Simplify server SSE forwarding to avoid duplicate proxy work

* fix: preserve the first streaming text chunk

- Show the initial text chunk immediately before batched deltas arrive
- Bypass batching for the first text or reasoning part update
- Keep later streaming updates buffered for performance

* perf: align streaming/render hot paths with opencode parity

* perf: harden turn/cache stability and stale delta suppression

* fix: stabilize chat rendering and disable timeline interactions

- Disabled timeline dialog access from shortcuts, commands, and chat input
- Reduced chat render churn by simplifying message list and turn staging behavior
- Improved session-switch stability to prevent update-depth crashes

* perf: track static message rerenders during streaming

* perf: reduce sorted-mode activity rerender fanout

* perf: reduce chat rerender fanout and add active-turn metrics

- Reduced sorted-mode rerender coupling by tightening turn context propagation
- Added a metric for static rerenders outside the active turn during streaming
- Exposed new chat render counters in the debug panel for parity tracking

* fix: keep sorted activity mounted while stream grows

* fix: stabilize session and history scroll rendering

* refactor: decouple server routes from index

* refactor: extract fs module from server index

* refactor: move opencode route ownership into module

* refactor: extract notification route registration

* refactor: extract opencode and notification runtimes from index

* refactor: extract settings runtime and complete server modularization pass

* refactor: modularize server config, skills, icons, and tunnel routes

* refactor: extract server modules from monolithic index.js

Split proxy, routes, runtime helpers, and notification emitter
into dedicated modules under packages/web/server/lib/.

* refactor: replace session/message stores with SSE-driven sync layer

Delete ~9200 lines of old architecture (useEventStream, messageStore,
sessionStore, useSessionStore, questionStore, useTodoStore, client SSE).

New sync layer: event pipeline with coalescing + 16ms flush, pure event
reducer, per-directory child stores with LRU eviction, cursor pagination,
optimistic updates, deferred timeline staging, text throttle.

Migrate all UI consumers to sync hooks (useSessionMessages,
useSessionMessageRecords, useSessionStatus, useSessionPermissions, etc).

Strip session-ui-store to UI-only state, delegate SDK ops to
session-actions with abort-if-busy, optimistic store updates, and
response merging for revert/fork/archive/delete.

Add notification-store for SSE-driven session attention tracking,
cross-directory GlobalSessionStatusStore for sidebar indicators,
client-side diff snapshot sanitization to prevent memory bloat,
and revert message filtering via useVisibleSessionMessages.

* feat: notification store, session actions, activity detection

Add notification-store.ts for SSE-driven attention tracking.
Add sanitize.ts to strip diff snapshot memory bloat.
Add session-actions.ts with optimistic revert/fork/archive/delete.
Improve useSessionActivity with incomplete-message fallback.
Delete useServerSessionStatus polling hook.

* fix: add directory param to all SDK calls, fix command/shell/abort routing

All SDK calls in session-actions.ts now pass directory parameter —
required by OpenCode server to scope session operations. Without it,
abort, commands, revert, fork, and other operations returned 500.

Add routeMessage() in session-ui-store for shell mode (session.shell),
slash commands (session.command), and normal prompts. Command lookup
checks both sync child store and useCommandsStore. Handle /compact
locally via session.summarize().

Implement getContextUsage() to restore header context usage display —
reads token counts from last assistant message in sync store.

* refactor: replace custom API proxy with http-proxy-middleware

Remove ~280 lines of custom proxy code: forwardSseRequest,
forwardGenericApiRequest, collectRequestBodyBuffer, header
manipulation, hop-by-hop filtering, SSE block buffering.

Replace with single createProxyMiddleware() call that handles
SSE streaming, large bodies, and timeouts out of the box.
Dynamic router for OpenCode port changes after restarts.
Auth headers injected via proxyReq hook.

Keep: readiness gate, Windows session merge, API prefix detection.

* perf: targeted event draft cloning to fix streaming render cascade

Event handler was eagerly cloning all state slices on every event,
breaking Zustand selector referential equality. During streaming
(~60 events/sec), this caused every subscriber to re-render regardless
of which slice actually changed.

Now only clones fields the specific event type mutates. Also extracts
StatusRowContainer to isolate high-frequency useAssistantStatus
subscription, removes dead messageStreamStatesMap subscription from
ChatContainer, and narrows useAssistantStatus to only track last
assistant message parts.

MessageList renders: 1972 → 296 per streaming session (-85%).

* fix: null safety for sync state slices

Add defensive ?? {} guards on permission, question, session_status,
and message record access. Prevents crashes when child store state
is partially initialized during bootstrap.

* perf: dedup inflight SDK calls, extract concurrency util, delay PR tracking

Extract mapWithConcurrency to shared lib/concurrency.ts. Add in-flight
dedup for loadProviders/loadAgents to prevent concurrent duplicate SDK
calls. Delay initial PR background tracking by 5s to reduce startup
CPU burst.

* fix: header session lookup across all child stores

Session title and context panel click failed when session belonged to
a different directory than the current child store. Fall back to
getAllSyncSessions() to search all initialized stores.

* chore: bump @opencode-ai/sdk to 1.3.5

* docs: add sync event handling guide

* Optimize session prefetch and improve delete/archive UX

- Add settlement delay to session prefetch to avoid race conditions on
  rapid session switches
- Reduce git diff prefetch and session cache limits for better performance
- Implement optimistic UI updates for session delete/archive operations
  with proper rollback on failure
- Wire session prefetch hook into SessionSidebar with sync integration

* Add file content cache and sync optimizations

- Wrap FilesAPI with in-memory LRU cache for file content with dual
  constraints (entry count and byte size)
- Optimize chat timeline scroll restoration using useLayoutEffect
- Preserve React references in message and part arrays to prevent
  unnecessary re-renders when prepending history
- Add session prefetch TTL cache to prevent redundant fetches
- Integrate session prefetch cache clearing with eviction flow

* Improve session sidebar error handling and add diff prefetch filtering

Load active and archived sessions independently using Promise.allSettled
to prevent one failure from blocking the other. Add retry logic to session
API calls and skip large files during diff prefetch to improve performance.

* Replace sendMessage with optimisticSend wrapper

Introduces optimistic UI updates for normal chat messages to provide
instant feedback. Messages appear immediately in the UI while the API
call executes in the background, with automatic rollback on errors.

* perf: split stores, proper optimistic send, fix revert/directory bugs

- split session-ui-store into voice/input/selection/viewport stores
  to reduce subscriber re-evaluation during streaming
- wire optimisticSend through useSync shadow Map infrastructure
  matching OpenCode's pattern (no heuristic part detection)
- port OpenCode Identifier.ascending ID format for correct sorting
- pass messageID to promptAsync to prevent duplicate messages
- fix worktree directory not propagating to session actions
  (dynamic dir() via opencodeClient.getDirectory)
- fix setCurrentSession accepting directoryHint for new sessions
- fix revert not hiding messages (session limit was 5, bumped to match loaded count)
- fix revert optimistic message removal from store
- fix load-more flicker (useLayoutEffect scroll compensation)
- add prefetch TTL cache, file content LRU cache
- add session prefetch for adjacent sessions
- add instant archive/delete (optimistic before SDK call)
- migrate legacy window.__zustand_session_store__ to session-ui-store
- add retry + independent error handling for archived sessions
- add AGENTS.md performance rules

* perf: startup optimization — dedup, caching, light git status, diff rendering gates

- defer diff prefetch to git tab open, reduce concurrency 4→2, skip >500 changed lines
- cap project git checks concurrency (2), directory status probe (3)
- dedup provider/agent loading, github auth, worktree list (in-flight + TTL caches)
- delay PR tracking 5s, cache 403 search failures per-repo
- coalesce settings PUT (200ms debounce), cache settings GET (2s TTL)
- cache canonical directory resolution (60s TTL)
- persist missing directory status to localStorage (10min TTL)
- light/heavy git status: polling skips numstat+line counting+rev-list
- large diff rendering gate (>500 lines → "render anyway" button)
- tokenization degradation for >500KB files in Pierre
- parallelize main.tsx pre-render awaits
- batch sidebar file tree expanded paths restoration (3 at a time)
- remove bare useConfigStore() subscription in AgentsPage
- sync worktree sandboxes to OpenCode SQLite DB
- fix RightSidebarTabs ternary → explicit tab matching
- defensive guards on sync state (session_status, permission, question, message)

* fix: add defensive guards on remaining sync state field accesses

guard session_status, permission, message, todo, part, config with ?? {}
in useDirectorySync selectors, session-cache, and bootstrap

* fix: add missing directory dep to useCallback in use-sync.ts

* fix: preserve diffStats when light-mode polling overwrites status

* perf: optimize startup git status polling and diff rendering

Preserves diff stats when lightweight polling updates repository status
Reduces startup overhead with smarter git polling and store updates
Adds detailed optimization and migration docs for next performance steps

* fix: keep chat diff stats stable during git status updates

Prevents lightweight git polling from dropping diff statistics
Keeps MessageList diff indicators consistent while status refreshes
Improves reliability of git-aware chat rendering

* fix: user animation replay, queued message variant, startup provider loading

- consume animation ID after first play to prevent re-animation
  on neighbor assistant message completion
- capture send config (model/agent/variant) at queue time matching
  OpenCode's FollowupDraft pattern instead of re-resolving at send time
- replace one-shot startup recovery effect with polling interval
  that retries every 2s until providers and agents load
- fix optimistic bridge to avoid re-render loop (stable ref wrappers)

* chore: update tauri to 2.10.3 and all plugins to latest

- tauri 2.9.4 → 2.10.3
- tauri-build 2.5.3 → 2.5.6
- tauri-plugin-dialog 2.4.2 → 2.6.0
- tauri-plugin-log 2.7.1 → 2.8.0
- tauri-plugin-shell 2.3.3 → 2.3.5
- tauri-plugin-updater 2 (floating) → 2.10.0 (pinned)
- @tauri-apps/api ^2.9.0 → ^2.10.1
- wry 0.53.5 → 0.54.4 (transitive)

* refactor: decouple web server index orchestration runtimes

* fix: align VS Code runtime behavior with web and reduce draft view CPU load

- Queue VS Code bridge and SSE startup requests until API readiness to avoid false bootstrap failures
- Make agent manager actions directory-aware and remove real worktrees with safer partial-failure handling
- Replace heavy logo animation path with a lightweight pulse to cut draft-session CPU usage

* fix: restore auto-selected file sending in chat input

- Send server-selected files as proper file URLs in the message payload
- Include server-backed attachments in submit flow instead of dropping them
- Restore queued-message attachments through the refactored input store

* fix: restore session model selection consistently on session switch

- Restore agent, model, and variant from the latest loaded user message for each session
- Wait for session messages before applying restored selections to avoid stale or missing state
- Remove legacy session-choice inference paths that caused overlap and instability

* fix: restore permission replies and auto-accept across sessions

- Scope permission and question replies to the target session directory so answers take effect reliably
- Make permission auto-accept immediately handle pending requests and react to new permission prompts
- Keep parent-session handling working for child-session requests through the shared response path

* feat: add reusable fuzzy branch fuzzy-search helper and dialog integration (#798)

* feat: add reusable fuzzy branch search for worktrees

* chore: drop planning docs from feature branch

* feat: make worktree branch refresh manual

* feat: add configurable session retention action

* refactor: centralize global session state in ui store

* fix: cancel debounced permission push after reply

* docs: clarify global and directory session store architecture

* docs: refine agent development rules and session activity guidance

- Clarify agent code of conduct and durable development patterns
- Add explicit shared-store rerender and live-state guidance
- Narrow session activity fallback to avoid stale working state

* chore: updated .gitignore

---------

Co-authored-by: Iuliia Ivashko <yulia.ivashko@gmail.com>
2026-03-31 18:47:00 +03:00
Iuliia Ivashko b3905e7e93 fix: recognize host.docker.internal as localhost in Docker deployments (#744)
* fix: recognize host.docker.internal as localhost in Docker deployments

* chore: remove tunnel-auth test file
2026-03-23 01:12:29 +02:00
Bohdan Triapitsyn 7356090e3d fix: improve cross-runtime session UX and platform config handling (#725)
* fix: make textarea focus highlight render inside

Apply inset focus ring to shared textarea component
Prevent focus border from appearing clipped near container edges

* fix: build desktop sidecar with target-matched architecture

Map Tauri target triples to Bun compile targets
Pass explicit Bun compile target for sidecar builds
Prevent x86_64 releases from shipping arm64 sidecar binaries

* fix: allow Windows git custom binary paths

Enable safe use of resolved custom git executable paths
Prevent git status failures when path contains restricted characters
Keep default behavior unchanged for plain git invocations

* fix: allow toggling diff line wrap on mobile

Stops forcing wrapped lines in mobile diff view
Line-wrap button now reflects and applies user preference

* fix: align VS Code managed server env with shell settings

Import login-shell environment variables before starting managed OpenCode
Apply Windows and Unix shell snapshot resolution for parity
Improve proxy-dependent provider connectivity in VS Code extension

* fix: respect user scope when adding MCP servers

Prevent user-scope MCP entries from being written to project config
Keep project writes only for explicit project scope

* fix: show linked GitHub issues and PRs as user message attachments

Preserve synthetic issue/PR context parts during message filtering.
Convert synthetic GitHub context JSON into attachment-style user parts.
Open issue/PR attachment links via shared external URL helper.

* fix: restore and polish project notes in sessions sidebar

Restored the Notes button in the left sessions sidebar header
Improved notes panel layout with wider dialog, larger notes area, and project name in the header
Refined todo rows with inline expand/collapse text and stable action/checkbox alignment

* fix: hide sidebar footer actions in VS Code runtime

Remove Settings, About, and Shortcuts buttons from the sessions sidebar footer in VS Code
Keep update button behavior unchanged across runtimes

* fix: normalize Windows paths for VS Code session loading

Canonicalize drive-letter casing in session path normalization
Align VS Code workspace path persistence with the same Windows path format
Normalize client directory context before API calls to keep session filtering consistent

* fix: open linked GitHub attachments with shared URL helper

Use runtime-aware external URL opening for issue/PR attachment links.
Keep GitHub attachment labels readable without altering normal file name rendering.

* fix: keep user MCP config writes out of project files

Respect user scope when selecting config write target
Prevent MCP user entries from being written to project opencode.json

* fix: prevent project menu from overlapping new session button

Align project menu positioning for non-git and git project rows
Avoid kebab-menu and plus-button overlap in sessions sidebar
2026-03-20 18:58:13 +02:00
Iuliia Ivashko d4269a1cc8 fix: harden terminal auth, skill file access, and sensitive request logging (#575)
* fix: enforce terminal websocket authentication on upgrade

* fix: block path traversal in skill supporting file APIs

* fix: redact voice token request logs

* fix: block skill file path traversal
2026-03-02 18:25:55 +02:00
Bohdan Triapitsyn 56d2f8390e fix: prevent tunnel lock for non-tunnel web sessions 2026-02-28 04:48:35 +02:00
Iuliia IvashkoandBrian-Hwang d5d0d35083 feat: redesign remote tunnel settings and named tunnel workflow (#546)
* feat: add Cloudflare Tunnel settings for desktop app

Add a 'Remote Tunnel' section in Settings (desktop-only) that lets users
start/stop a Cloudflare quick tunnel on demand, with auto-generated
password protection and a QR code for easy mobile access.

- Server: 4 new API endpoints (check/status/start/stop) reusing the
  existing cloudflare-tunnel module
- UI: TunnelSettings component with full state machine
  (checking → idle/not-available → starting → active → stopping)
- QR code rendered via the qrcode package for in-app display
- Hidden from VS Code extension (desktop/web only)

* fix: use ?token= instead of ?p= in tunnel password URLs

REST API endpoints were building passwordUrl with ?p=<token> but
SessionAuthGate reads the ?token= query param, causing QR code
auto-login to fail — the password was never extracted from the URL.

Standardize all three tunnel URL construction sites to use ?token=
so scanning the QR code correctly pre-fills and submits the password.

* feat: secure remote tunnel access with one-time connect links

* feat: redesign remote tunnel settings and access flow

* fix: cleaned up unused desktop close code path

* feat: overhaul named tunnel setup and persistence flow

* chore: align codemirror language dependency resolution

---------

Co-authored-by: Brian-Hwang <brian.hwang@cornelisnetworks.com>
2026-02-28 04:21:46 +02:00
JovinesandJovines 7a151290be refactor(auth): migrate session storage to JWT with persistent secret (#508)
- Replace in-memory session Map with stateless JWT tokens
- Add jose library for JWT signing and verification
- Implement persistent JWT secret storage in ~/.config/openchamber
- Support OPENCODE_JWT_SECRET environment variable override
- Update SessionAuthGate and useServerSessionStatus hooks
- Remove session cleanup timer (JWTs are stateless)

Co-authored-by: Jovines <jovines@qq.com>
2026-02-25 19:40:28 +02:00
Nguyễn Ngô ThượngandBohdan Triapitsyn b2101acfbf feat(settings): group agents and skills sidebar by subfolder (#464)
* feat(settings): group agents and skills by subfolder in sidebar

- Server: fix getUserAgentPath() to walk subfolders so grouped agent
  layouts (e.g. agents/business/ceo.md) are correctly resolved
- Store: add 'group' field to AgentWithExtras and DiscoveredSkill,
  parsed from file path at load time
- UI: add collapsible SidebarGroup component with localStorage-persisted
  expand/collapse state
- AgentsSidebar: render custom agents grouped by subfolder name
- SkillsSidebar: render project/user skills grouped by domain folder
- Ungrouped items (flat root) fall through and render normally

* fix(settings): normalize group paths and add agent lookup caching parity

---------

Co-authored-by: Bohdan Triapitsyn <artmore@protonmail.com>
2026-02-23 12:28:24 +02:00
Nguyễn Ngô ThượngandBohdan Triapitsyn d0e4dc2704 feat(mcp): add MCP Config Manager UI (#473)
* feat(session-folders): drag-to-folder DnD, sort by activity, and UX improvements

- Add DraggableSessionRow wrapping each session row so the whole row is
  draggable; stopPropagation prevents outer group-reorder DnD from firing
- Add DroppableFolderWrapper + SessionFolderDndScope (inner DndContext
  scoped per group) with closestCenter collision detection
- DragOverlay matches exact width/height of dragged row so cursor stays
  aligned
- Folder header highlights (ring + primary colour) when a session hovers
  over it during drag
- + button on folder header opens a dropdown: 'New session' / 'New folder'
- + button on each folder row creates a session scoped to that folder
- Empty folders are no longer auto-deleted (removed .filter(sessionIds.length>0)
  from addSessionToFolder / removeSessionFromFolder / cleanupSessions)
- Sessions inside a folder are sorted by most-recent activity (same
  compareSessionsByPinnedAndTime logic used everywhere else)
- Sort comparator now takes sessionAttentionStates so lastUserMessageAt /
  lastStatusChangeAt is used when newer than session.time.updated; all
  sort call-sites and their useMemo/useCallback deps updated accordingly
- Remove foldersMap from cleanup effect deps to prevent cascade re-renders
  when folders change; read current value via getState() instead

* fix(session-folders): new session is placed into the correct folder

sendMessage() was calling useSessionManagementStore.createSession()
directly, bypassing the targetFolderId logic in useSessionStore.createSession.

Fix: read targetFolderId from draft at the top of the draft branch in
sendMessage, then call addSessionToFolder immediately after the session
is created and before the draft is closed. Also propagate targetFolderId
through openNewSessionDraft options and NewSessionDraftState type.

* feat(session-folders): add sub-folder support (one level deep)

- SessionFolder gains optional parentId field for hierarchy
- createFolder accepts parentId to create sub-folders
- deleteFolder cascades to remove all child sub-folders
- SessionFolderItem renders sub-folders before sessions in body;
  new sub-folder button (RiFolderAddLine) visible at depth 0 only
- renderOneFolderItem in SessionSidebar builds the tree recursively;
  sub-folders are indented via depth prop (ml-3 on root's children)
- Persist/hydrate parentId correctly from localStorage

* feat(session): add delete confirm dialogs and improve subtitle UX

- Add confirmation dialogs before deleting sessions or folders
- Show relative time (e.g., '2h ago', '35min ago') for recent sessions
- Replace +/- diff numbers with file change count (e.g., '3 files changed')
- New folders use default name without forcing rename
- Cleaner, less cluttered session list UI

* fix(session-folders): skip folder cleanup while sessions are loading

Prevents race condition on reload where cleanupSessions() runs before
the server returns the full session list, causing folder-session
assignments to be incorrectly wiped from localStorage.

* feat(mcp): add MCP Config Manager UI

- Backend: CRUD lib (mcp.js) + 5 REST routes (GET/POST/PATCH/DELETE /api/config/mcp/:name)
- Frontend: Zustand store (useMcpConfigStore), McpSidebar with status dots, McpPage with redesigned UX
  - Textarea command editor: paste full shell commands, auto-split into args, one-arg-per-line view
  - Compact env editor: wide value column, show/hide toggle, paste .env format support
  - Header card: name, type badge, enabled toggle, connect/disconnect button
- Navigation: 'mcp' added to sidebar sections in SettingsView
- TypeScript: all packages pass type-check clean

* fix(mcp): remove constant truthiness lint error in McpPage

Replace '(isNewServer || true) &&' with unconditional render — type
selector should always be visible so the user can switch between
stdio and remote without recreating the server.

* fix: add MCP server management to VS Code backend

- Implement CRUD operations for MCP servers via bridge API
- Support local and remote MCP server configurations with validation
- Add VS Code webview endpoints for MCP server management

* feat: add project-level MCP server configuration

---------

Co-authored-by: Bohdan Triapitsyn <artmore@protonmail.com>
2026-02-22 23:22:33 +02:00
Nelson Pires 073f44de2a refactor(server): split opencode config/auth/ui-auth into domain modules (#454)
* docs(agents): map opencode module documentation

* docs(opencode): document split module responsibilities

* refactor(opencode): centralize shared config and file helpers

* refactor(opencode): move auth storage helpers into domain module

* refactor(opencode): move UI auth implementation into domain module

* refactor(opencode): isolate agent scope and CRUD logic

* refactor(opencode): isolate command scope and CRUD logic

* refactor(opencode): isolate provider config helpers

* refactor(opencode): isolate skill discovery and CRUD logic

* refactor(opencode): define single public module entrypoint

* refactor(opencode): remove legacy opencode-config module

* refactor(opencode): remove obsolete opencode-config typings

* refactor(opencode): remove legacy opencode-auth module

* refactor(opencode): remove legacy ui-auth shim

* refactor(server): import opencode APIs from new module paths

* refactor(tts): consume auth helpers from opencode domain module

* refactor(quota): point claude provider auth import to opencode domain

* refactor(quota): point codex provider auth import to opencode domain

* refactor(quota): point copilot provider auth import to opencode domain

* refactor(quota): point google auth import to opencode domain

* refactor(quota): point kimi provider auth import to opencode domain

* refactor(quota): point nanogpt provider auth import to opencode domain

* refactor(quota): point openai provider auth import to opencode domain

* refactor(quota): point openrouter provider auth import to opencode domain

* refactor(quota): point zai provider auth import to opencode domain

* fix(opencode): restore provider source and disconnect semantics
2026-02-20 15:57:44 +02:00