Commit Graph
875 Commits
Author SHA1 Message Date
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
Bohdan Triapitsyn 6d21cdc69e fix: keep active sessions visible in Recent sidebar 2026-04-14 23:41:34 +03:00
jwcrystalandBohdan Triapitsyn 9b169aaacf feat: deliver polished desktop first-launch experience with smart recovery (#850)
* feat: implement desktop boot outcome architecture

- Add structured DesktopBootOutcome with target/status fields
- Implement boot outcome computation and validation
- Add desktop hosts configuration management (Tauri + TypeScript)
- Add desktop hosts probing with timeout and retry logic
- Support local/remote host classification and health checks

This provides the foundational infrastructure for desktop onboarding
flow to determine whether to show local setup, remote connection,
or recovery screens based on OpenCode availability and remote host
reachability.

* feat: add desktop onboarding UI components

Add comprehensive onboarding flow for desktop app:

- ChooserScreen: First-launch local/remote selection
- LocalSetupScreen: CLI installation guidance and manual detection
- RecoveryScreen: Recovery mode with routing to local/remote
- RemoteConnectionForm: Remote host connection with validation
- DesktopConnectionRecovery: Recovery variants and routing logic
- ConnectionSettingsPage: Manage remote connections

Components handle:
- Local vs remote choice persistence
- Recovery scenarios (unreachable, wrong-service, missing)
- Manual CLI detection (replaced auto-polling)
- Back navigation and state preservation

* feat: integrate desktop onboarding with app shell

- Update App.tsx to handle onboarding routing and recovery
- Add onboarding mode switching (first-launch/local-setup/recovery)
- Integrate desktop hosts in SettingsView
- Update DesktopHostSwitcher with recovery routing
- Add desktop shell utilities for onboarding detection
- Update web manifest for desktop app metadata

Completes the desktop onboarding feature integration,
allowing users to choose local or remote OpenCode on
first launch and recover from connection failures.

* fix: hide back button in remote connection form for first-launch chooser

In first-launch chooser mode, the back button is redundant since users
can simply click the "Local Install" tab. The back button is still shown
in recovery mode where there's no tab interface.

Changes:
- Add showBackButton prop to RemoteConnectionForm (default: true)
- Set showBackButton={false} in ChooserScreen remote tab
- Keep showBackButton={true} in RecoveryScreen for navigation

* refactor: remove Connection Settings page and simplify recovery UI

Remove the Connection Settings page as it was redundant:
- Local server is single-instance (no need to "choose")
- Remote servers are one-time setup (first-launch chooser)
- SSH Instances remain for multi-instance management

Changes:
- Remove ConnectionSettingsPage component and directory
- Remove 'connection' from Settings metadata
- Remove "Open Settings" button from recovery screens
- Remove desktopBootBypassToSettings state and logic
- Update recovery config to use 'local' icon instead of 'settings'
- Update tests to reflect removed showOpenSettings field

This simplifies the UX by focusing on:
- First-launch chooser for initial local/remote decision
- Remote Instances (SSH) for managing multiple remote machines
- No persistent "server management" needed for typical desktop usage

* fix: remove unused enableCliPolling prop and clean up TypeScript errors

Remove the obsolete enableCliPolling prop that was used for auto-
polling CLI detection. We replaced this with manual "Check and Continue"
button in a previous commit, so this prop is no longer needed.

Changes:
- Remove enableCliPolling from OnboardingScreen props and usage
- Remove enableCliPolling from App.tsx calls
- Remove unused 'connection' case from getSettingsNavIcon()
- Remove unused RiGlobalLine import

This resolves all TypeScript compilation errors reported by Copilot.

* fix: remove unused onChooseLocal prop and CLI_MISSING_ERROR_REGEX

These were left over from the refactoring:
- onChooseLocal in RecoveryScreen was defined but never used
- CLI_MISSING_ERROR_REGEX in App.tsx was leftover from removed enableCliPolling code

* fix: remove unused variables and fix React Hook dependency warnings

Remove unused memoized components and variables that were causing
lint errors in packages/ui:

- MainLayout.tsx: Remove unused MemoHeader, MemoChatView, MemoPlanView,
  MemoGitView, MemoDiffView, MemoTerminalView, MemoFilesView,
  MemoRightSidebarTabs, DesktopLeftSidebar, and DesktopRightPanel
- useGitHubPrStatusStore.ts: Remove unused prVisualPriority function
- useChatScrollManager.ts: Add missing markProgrammaticScroll dependency
  to React.useEffect hook

These fixes resolve the CI lint failures in PR 850.

* chore: remove local claude settings from repo

* refactor(desktop): drop vibrancy code from onboarding PR

---------

Co-authored-by: Bohdan Triapitsyn <artmore@protonmail.com>
2026-04-14 20:32:59 +03:00
jwcrystalandBohdan Triapitsyn bb1d522838 fix(task): prevent subagent silent failures in session resolution and polling lifecycle (#903)
* fix(task): prevent subagent silent failures in session resolution and polling lifecycle

Two failure points fixed:

1. Fallback session resolution window too narrow (3s):
   - resolveFallbackTaskSessionId now accepts hasRetried boolean
   - First attempt uses 3s window (avoids binding wrong sessions)
   - Subsequent attempts widen to 8s (handles late-appearing child sessions)
   - Uses useState + useEffect instead of side effects in Zustand selector

2. Polling stops before child results are captured:
   - When child session goes idle before parent sees it active, polling
     would stop without fetching results
   - Added final-fetch-before-stop: a one-shot delayed fetch that runs
     after the settle grace period, ensuring child results are captured
   - Uses taskFinalFetchDoneRef to guarantee exactly one final fetch
   - Preserves existing happy path (active child → normal settle timer)

* fix(task): serialize final fetch after polling stops

Move the subagent final-fetch into a dedicated effect that runs only after
polling has stopped, avoiding races between polling writes and final-fetch
writes to the child sync store.

Also retry safely on final-fetch failure by reopening polling instead of
marking the final fetch as done before the request succeeds.

* feat(task): distinguish child session errors from normal idle

When a subagent terminates with an error, abort, timeout, or failure,
the parent session could not tell it apart from a normal completion.

Changes:
- event-reducer.ts: session.error now stores { type: 'error' } instead of
  { type: 'idle' }, so consumers can distinguish failed from completed sessions
- useSessionActivity.ts: add 'error' phase to SessionActivityPhase and
  isError flag to SessionActivityResult; error phase is non-active (like idle)
  but distinguishable via isError
- ToolPart.tsx: pass childSessionError to TaskToolSummary and show
  'Subagent session ended with an error.' instead of the generic
  'No subagent session id on task metadata.' when the child errored

Other consumers of session_status that only check 'busy'/'idle' are
unaffected — 'error' falls through to existing idle-like behavior.

* Revert "feat(task): distinguish child session errors from normal idle"

This reverts commit b3cc749bde16ed8fc55e4f304dcc455484335fba.

* fix(task): delay fallback retry window widening

---------

Co-authored-by: Bohdan Triapitsyn <artmore@protonmail.com>
2026-04-14 20:17:52 +03:00
马曜峥行 43a4c0c874 add tree view (#906) 2026-04-14 20:08:59 +03:00
jwcrystalandBohdan Triapitsyn 1656c3bb93 perf(sync): optimize multi-session event pipeline with per-directory queues and delta coalescing (#908)
* fix: hide archived section and empty folders when no sessions remain

- Only push archived group in useSessionGrouping when there are archived
  sessions, preventing an empty archived section from rendering
- Hide empty folders in archived bucket via shouldKeepFolder check in
  SessionGroupSection (folders with no sessions and no content in
  children are filtered out)
- Always filter folders through shouldKeepFolder, not just during search

* perf: memoize archived folder filtering

* perf(sync): per-directory event queues to eliminate cross-session HoL blocking

The SSE event pipeline previously used a single global queue and a single
flush timer shared across all directories. Under concurrent multi-session
workloads, a busy directory's delta storm would block other directories'
status and state events from reaching the UI until the next flush tick,
producing the "multi-session latency" symptom users report.

Split the queue into one DirectoryQueue per directory, each with its own
coalesce map, stale-delta set, and flush timer. Directories flush
independently so a busy directory can no longer starve a quiet one. Coalesce
keys are now scoped to a single directory's queue, so the directory prefix
is removed from the key strings.

Cross-directory behavior only; same-directory multi-session behavior is
unchanged (React 18 auto-batching still collapses a single directory's
flush into one render).

* perf(sync): coalesce consecutive message.part.delta events per flush window

Within a 16ms flush window, consecutive delta events for the same
(messageID, partID, field) tuple are string-concatenated into a single
accumulated delta rather than being queued individually.

This directly addresses same-project multi-session workloads — most
notably parent sessions with subagent tasks (child sessions share the
same directory queue). Both parties stream deltas concurrently, which
previously multiplied raw event count proportionally to the number of
active sessions. Coalescing can reduce queue depth by 10-100x during
active streaming.

Safety: verified against event-reducer.ts — the delta handler is a pure
string append (existingValue + props.delta) with no per-event side
effects (no time.updated, no notifications, no diff calculations). The
merged result is semantically identical to applying each delta separately.

The staleDeltas skip mechanism is unaffected: accumulated delta payloads
retain their type and identifiers, so message.part.updated supersession
still works correctly.

* test(sync): cover per-directory queues and delta coalescing

Extend event-pipeline.test.js with behavioural coverage for both
optimizations landed in 98d013a and 258acf0:

P1 (per-directory queues)
- Delivers events from two directories without loss
- Keeps distinct sessionIDs in the same directory as independent coalesce
  slots (session.status is not overwritten across sessions)
- Collapses repeated session.status for the same session down to latest

Option C (delta coalescing)
- Accumulates consecutive deltas for the same (messageID, partID, field)
  into a single dispatched event with concatenated content
- Does not merge deltas across different fields on the same part
- Does not merge deltas across different parts on the same message
- Does not merge deltas across different directories (per-dir queues)
- Skips accumulated deltas when message.part.updated is coalesced onto
  an earlier update, proving staleDeltas still works with C
- Leaves non-delta coalescing (session.status replace semantics) intact

All 13 tests pass under bun:test.

Also adds event-pipeline.bench.js, a runnable synthetic benchmark that
reports delta reduction and byte integrity across 8 workload scenarios
from "single session, 500 tokens" up to "10 projects × 5 sessions ×
1000 tokens". Run with:

  bun packages/ui/src/sync/__tests__/event-pipeline.bench.js

Current numbers on this machine: 99.5% - 99.9% delta event reduction
with full byte-level integrity (concatenated delta bytes always equal
the input total).

* fix(sync): remove staleDeltas — it silently drops delta events

---------

Co-authored-by: Bohdan Triapitsyn <artmore@protonmail.com>
2026-04-14 20:08:40 +03:00
jwcrystalandBohdan Triapitsyn 5584537da5 fix: question tool content disappears after refresh (#879) (#909)
* fix: show question content in ToolPart instead of 'Awaiting response...' after refresh

Previously, when the question tool was pending/running or completed
without parseable output, the ToolPart fell through to a generic
'Awaiting response...' message. After a page refresh or app restart,
this made questions appear empty even though the tool state still
contained the question input data.

Now the ToolPart reads question text, headers, and options from the
tool state's input field, ensuring question content persists across
refreshes regardless of QuestionCard store availability.

Fixes #879

* fix: restore QuestionCard after refresh and pause working status during active questions

Two fixes for question tool UX:

1. ChatContainer: sessionIsWorking now returns false when there are
   active questions (same as it already did for permissions). This
   prevents the status row from showing 'Asking question...' and
   instead shows the QuestionCard.

2. sync-context: resyncDirectoryAfterReconnect now re-fetches
   pending questions via listPendingQuestions(). Previously only
   sessions and messages were re-fetched on SSE reconnect, so
   questions asked during disconnection were lost, causing
   QuestionCard to disappear after page refresh.

Refs #879

* fix: hide assistant working status while questions are pending

The assistant status hook only special-cased pending permissions, so
question tools still surfaced 'Asking question...' after refresh even
when the UI was already waiting on a QuestionCard response.

Treat pending questions like other blocking requests by clearing the
working indicator until the user answers.

Refs #879

* fix: merge question/permission stores instead of full replace on bootstrap and reconnect

The root cause of QuestionCard disappearing after refresh was a race
condition between SSE events and HTTP bootstrap. Bootstrap and reconnect
both did full replacement of state.question, wiping SSE-delivered data
that arrived between the HTTP call initiation and response arrival.

Changes:
- bootstrap.ts: question and permission stores now use merge semantics.
  Only sessions present in the API response are overwritten. Sessions
  absent from the response are left untouched (they may hold SSE data).
- sync-context.tsx: reconnect question resync uses the same merge pattern.
  No longer clears question entries for sessions not in the API response.
- bootstrap.ts: sdk.question.list() now passes directory parameter to
  scope the query correctly.

This ensures SSE-delivered question data survives the bootstrap window,
while still allowing the API response to be authoritative for sessions
it covers.

Refs #879

* fix: prune stale pending requests after reconnect

---------

Co-authored-by: Bohdan Triapitsyn <artmore@protonmail.com>
2026-04-14 20:02:07 +03:00
Bohdan Triapitsyn 01ca471776 fix: render JSON code block quotes correctly 2026-04-14 19:40:36 +03:00
Bohdan Triapitsyn 16270e4b03 fix: restore desktop window dragging on remote instances
- Fixes header drag behavior in Desktop when connected to remote hosts
- Routes all window-drag entry points through a shared safe desktop helper
- Keeps local desktop drag behavior unchanged while avoiding remote IPC failures
2026-04-14 19:33:09 +03:00
Bohdan Triapitsyn c7f1501ad2 fix: harden custom TTS URL handling and availability checks
Validate and normalize custom TTS server URLs before proxying requests.
Gate server TTS availability by provider mode to avoid OpenAI/custom misrouting.
Keep browser and message TTS hooks aligned with the new provider-specific checks.
2026-04-12 10:38:16 +03:00
Alexander BusseandAlexander Busse 055b6f6af0 feat(tts): add OpenAI-compatible custom server TTS provider with configurable model, pitch, and volume (#859)
Co-authored-by: Alexander Busse <alex@ableph.net>
2026-04-12 10:33:15 +03:00
Bohdan Triapitsyn 8a836d4aed test: remove UI verification file for tool preview checks 2026-04-12 00:41:25 +03:00
Bohdan Triapitsyn 844052e599 fix: restore desktop startup and align tool previews with SDK updates
Add reflect-metadata bootstrap so desktop sidecar no longer crashes on startup.
Update SDK v1.4 compatibility for model variant and diff payload handling.
Unify write/edit/apply patch expanded previews and hide write success output noise.
2026-04-12 00:40:49 +03:00
Gyumin Lee e6ac6badde fix: restore variant restoration for OpenCode 1.4.0 (#871)
OpenCode 1.4.0 moved `UserMessage.variant` from the top-level to
`UserMessage.model.variant`. OpenChamber still read the legacy location,
so variant selection silently stopped being restored on sessions served
by OpenCode 1.4.0+.

Read `model.variant` first and fall back to the legacy top-level field
so both pre-1.4 and 1.4+ OpenCode servers keep working.
2026-04-11 23:50:13 +03:00
jwcrystal 291d00de8b fix: remove shell-specific \&\& operators for non-POSIX shell compat (#870) (#888)
Replace shell `\&\&` and `||` operators in execCommand calls with
TypeScript control flow. This fixes re-integrate commits failing when
the user's default shell is Nushell, which does not support `\&\&`.

Changes:
- createTempWorktree: split `mkdir \&\& mktemp` into two calls
- ensureLocalBranch: use isOk() instead of `echo ok || echo missing`
- isCherryPickInProgress: use isOk() instead of `echo yes || echo no`

Closes #870
2026-04-11 23:43:57 +03:00
jwcrystal 6425161bef fix(sidebar): auto-expand parent node when navigating to subagent session (#893)
When a user navigates to a subagent (child) session, the parent session
node in the left sidebar was not automatically expanded, making the
child session invisible in the tree. This change adds a useEffect that
detects when the current session has a parentID and automatically adds
that parentID to expandedParents, ensuring the subagent session is
visible in the sidebar hierarchy.
2026-04-11 23:42:02 +03:00
jwcrystal 964c209ff6 fix(sync): remove stale-delta skip and add parts-gap recovery (#889)
The pipeline's stale-delta mechanism incorrectly marked all
message.part.delta events as stale when a message.part.updated
coalesced, regardless of queue position. This caused valid streaming
deltas to be silently dropped, resulting in blank or incomplete
assistant messages.

Additionally, when part events were dropped by the reducer (missing
parts array or partID not found), there was no recovery path — the
state stayed permanently out of sync until the next SSE reconnect
or manual refresh.

Also discovered: message.updated that successfully writes an assistant
message but has empty parts would render a blank bubble, with no
repair triggered since repair only ran on reducer return false.

Changes:
- Remove staleDeltas Set and deltaKey from event-pipeline.ts
- Coalesce still replaces same-key events, but deltas are never skipped
- Add enqueuePartsRepair + repairSessionParts to sync-context.tsx
  (5s cooldown, deduped, async SDK re-fetch)
- Trigger repair on reducer return false for part events
- Trigger repair on message.updated return true with empty parts
- Add sync debug.ts with gated diagnostic logging
- Add pipeline coalescing tests
2026-04-11 23:40:47 +03:00
Aaron Hogue 1c7a0b8ddd Add Kiro as an 'Open in' app option (#882)
- Add Kiro to OPEN_IN_APPS list with id 'kiro' and appName 'Kiro'
- This enables users to open files and projects directly in Kiro IDE
  via the Open in menu, similar to VS Code, Cursor, and Windsurf
2026-04-11 23:29:53 +03:00
jwcrystal 700138c9b5 fix(git): restore changes panel visibility and sidebar sync (#886)
* fix: restore git changes panel visibility and sidebar sync

Two independent fixes:

1. ChangesSection virtualizer returned empty rows due to useMemo caching
   getVirtualItems() with a stale stable reference. First render produced
   an empty array, and useMemo never recomputed because rowVirtualizer
   reference never changed. Removed the useMemo to call getVirtualItems()
   directly on every render. Also added a ResizeObserver to force
   remeasurement on visibility transitions (defensive).

2. RightSidebarTabs now keeps git status fresh while the sidebar is open
   via useRightSidebarGitSync hook (10s polling with ensureStatus).
   Replaces the GitPollingProvider removed in commit d9821716.

* fix(virtualizer): prevent React error #185 from render-phase getVirtualItems

Restoring useMemo for virtualRows with totalSize as an invalidation
dependency. Calling getVirtualItems() directly during render triggers
the virtualizer's maybeNotify() → onChange() → useReducer dispatch,
causing React error #185 (https://react.dev/errors/185 — cannot
update a component while rendering a different component).

The original useMemo([rowVirtualizer, shouldVirtualize]) was removed
because rowVirtualizer is a stable useState ref that never changes,
leaving the memo permanently stale after the first empty render.
Adding totalSize (from getTotalSize()) as a dependency solves this:
it changes whenever the virtualizer recalculates after measure/scroll,
ensuring getVirtualItems() returns fresh rows while staying wrapped
in useMemo.
2026-04-11 23:29:35 +03:00
jwcrystal b91a72c74b fix(chat): replace hover bridge with padding to unblock desktop interactions (#885)
* fix(chat): replace hover bridge with padding to unblock desktop interactions

PR #826 removed pointer-events-none from the hover bridge div to fix
short user message revert button hover, but the transparent 44px
full-width bridge blocked all interactions (clicks, text selection)
with messages below it on Tauri desktop where the rendering difference
made the overlay consume pointer events across the entire message area.

Replacing the bridge div approach with pb-12 padding on the message
bubble container (max-w-[85%]) when sticky inline hover is active.
This extends the hover hit area downward within the bubble's own
padding, maintaining continuous hover path from bubble to action
buttons without any overlay that could block sibling elements.

The padding approach works because:
- The 48px bottom padding extends max-w-[85%]'s hover area to cover
  the gap between bubble bottom and the absolute-positioned buttons
- Hovering the padding counts as hovering group/user-shell (parent)
- No absolute-positioned invisible layer means nothing blocks the
  next message's interactive content

* fix(chat): reduce hover padding from pb-12 to pb-5 for tighter spacing
2026-04-11 23:27:47 +03:00
jwcrystal 5ea2fed0d3 fix: hide empty archived section and folders (#872)
* fix: hide archived section and empty folders when no sessions remain

- Only push archived group in useSessionGrouping when there are archived
  sessions, preventing an empty archived section from rendering
- Hide empty folders in archived bucket via shouldKeepFolder check in
  SessionGroupSection (folders with no sessions and no content in
  children are filtered out)
- Always filter folders through shouldKeepFolder, not just during search

* perf: memoize archived folder filtering
2026-04-11 23:25:33 +03:00
Bohdan Triapitsyn 36b2bcf4f9 fix(stt): validate custom base url 2026-04-11 22:51:37 +03:00
Alexander BusseandAlexander Busse 3746d99a85 feat(stt): add server-side STT provider via OpenAI-compatible Whisper endpoint (#860)
Co-authored-by: Alexander Busse <alex@ableph.net>
2026-04-11 22:47:33 +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
Paul Mourer 37cf7d9c79 Adds 1w, 30d session token expirations (#853) 2026-04-11 22:33:38 +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
Xiangfang Chen a3d73a8b67 feat(quota): add Zhipu AI Coding Plan usage tracking (#756)
- Add zhipuai-coding-plan provider for quota monitoring
- Support TOKENS_LIMIT (5-hour window) and TIME_LIMIT (MCP tools monthly)
- Update UI provider list and TypeScript types
- Register provider in server quota registry
2026-04-11 22:15:19 +03:00
Bohdan Triapitsyn bdcff3a5b7 docs: add vacation notice to README 2026-04-08 11:36:08 +03:00
jwcrystal 4fd1d68eb9 fix(chat): allow revert button hover on short user messages (#826) 2026-04-08 10:44:17 +03:00
Bohdan Triapitsyn ec1e309c40 release v1.9.4 2026-04-07 23:10:08 +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 2e5b02e753 test: cover external OpenCode proxy routing
- Expose external OpenCode base URL to proxy runtime
- Add regression coverage for provider requests through external OpenCode hosts
2026-04-07 22:48:17 +03:00
Bohdan Triapitsyn 46d166e205 fix: drop stale chat memo boundaries
Remove remaining chat row and body memo comparators that were still keeping finished background session responses blank or stale in the UI.
2026-04-07 21:48:56 +03:00
Bohdan Triapitsyn 952132a08d fix: remove desktop translucency to reduce macOS compositing cost 2026-04-07 21:46:38 +03:00
Bohdan Triapitsyn 605e4bf42c fix: stop stale chat renders after session switches
Roll back aggressive chat reuse paths that froze message parts, tool state, and completed assistant bodies when sessions were inactive or backgrounded.
2026-04-07 20:33:55 +03:00
Gyumin Lee c16d767dff fix: add defensive checks for missing model cost and capabilities fields (#855)
OpenCode v1.3.13 may omit cost and capabilities from provider model
config responses. The deriveModelMetadata function accessed these
fields without optional chaining, causing a TypeError that crashes
the chat interface.
2026-04-07 15:47:53 +03:00
jwcrystalandBohdan Triapitsyn 4cb918f6cb fix: implement loading timeout, SSE reconnect, and message retry (#857)
* fix: implement loading timeout, SSE reconnect, and message retry

- Loading timeout: 30s timeout with retry/cancel buttons to prevent infinite loading
- SSE reconnect: Auto-reconnect up to 3 times with exponential backoff (1s, 2s, 4s)
- Message retry: Ensure critical messages reach webview with 5s timeout and 3 retries

This fix prevents the chat from getting stuck in a permanent loading state
and improves reliability of SSE connections and webview communication.

Fixes #851

* fix: harden vscode bridge retry flow

---------

Co-authored-by: Bohdan Triapitsyn <artmore@protonmail.com>
2026-04-07 15:46:06 +03:00
Bohdan Triapitsyn 1fed81439c ci: mention Discord update role in release posts 2026-04-07 14:11:03 +03:00
nzlov 2af782b4da Update minimax-cn-coding-plan.js (#864)
* Update minimax-cn-coding-plan.js

Signed-off-by: nzlov <wfhtqp@gmail.com>

* Update minimax-cn-coding-plan.js

Signed-off-by: nzlov <wfhtqp@gmail.com>

---------

Signed-off-by: nzlov <wfhtqp@gmail.com>
2026-04-07 14:05:22 +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 16a4157440 perf: pause background polling and animations when tab is hidden
- Background polling pauses when tab is not visible
- Timer-based animations replaced with efficient frame-based updates
- Reduced CPU usage when OpenChamber is in background
2026-04-06 21:05:02 +03:00
Bohdan Triapitsyn 2f1377ec01 fix: prevent duplicate desktop notifications 2026-04-06 20:55:32 +03:00
Bohdan Triapitsyn 8de1884f5c refactor: remove plan polling, add message-driven detection via usePlanDetection hook 2026-04-06 20:44:13 +03:00
Bohdan Triapitsyn a516650f96 fix: stabilize chat auto-scroll and bottom resume
- Unify send and session resumes around the latest chat tail
- Keep smooth follow active during assistant message growth
Remove staged chat rendering from the main scroll path
2026-04-06 20:18:20 +03:00
Bohdan Triapitsyn f884919165 fix: keep notification summaries in plain text
- Force notification summaries to avoid markdown formatting
- Normalize generated notification text before system display
- Cover plain-text notification formatting with tests
2026-04-06 17:40:20 +03:00
Bohdan Triapitsyn 9254ec0783 fix desktop notifications and chat scroll stability 2026-04-06 17:36:08 +03:00
Bohdan Triapitsyn e42471ee7b chore: update workspace dependencies and chat behavior
- Adjust package metadata and lockfiles across the workspace
- Refine chat sidebar and auto-scroll behavior in the UI
- Update PWA install handling alongside runtime package changes
2026-04-06 13:04:36 +03:00
Bohdan Triapitsyn 4db1e6baad perf: reduce active-turn chat rerenders during streaming
- Keep older assistant messages in the active turn stable while new content streams
- Prevent existing tool rows from rerendering when new tool activity is appended
- Tighten message and tool memo comparisons to isolate render work to changed rows
2026-04-06 00:43:19 +03:00
Bohdan Triapitsyn 4a3b7ec5c9 fix: restore smooth chat auto-scroll and live compaction updates
- Keep assistant auto-scroll smooth during active responses without periodic snaps
- Restore live `/compact` rendering and streamed compaction summaries without refresh
- Preserve global event handling while routing session and message updates efficiently
2026-04-05 23:01:12 +03:00