Limits reconnect and repair message fetches to recent messages
Reduces repeated bandwidth for large tool outputs
Keeps normal session loading unchanged
On Android tablets in Desktop site mode, the handleDocumentFocusIn handler
intercepted Ghostty's internal element focus and blurred them, but never
redirected focus to the hidden input overlay. This left the terminal with
no focused element - the IME keyboard would appear but keystrokes went
nowhere. Now focusHiddenInput() is called after the blur to ensure the
terminal always has a focused input surface.
Deduplicates concurrent app initialization in the config store
Lazy-loads VS Code-only app surfaces
Avoids broad view barrel imports for better chunk isolation
Replace placeholder conflict text with localized copy
Split in-progress operation details and actions into clearer rows
Keep merge and rebase status messages consistent
Add a Stashes dialog with create, apply, pop, and drop actions
Include untracked files automatically when stashing
Show file counts for current changes and stash entries
Combine fetch, pull with rebase, and push into one sync action
Keep remote dropdown focused on safe fetch actions
Block sync when uncommitted changes would conflict with rebase
* fix(sync): preserve pending questions across session switch and directory eviction
Closes#918, completes the gap left by #909.
The 'agent question disappears after switching session / coming back
later' bug had two root causes that #909 only partially addressed:
1. Directory-eviction TTL (20 min) silently dropped child stores that
held pending questions/permissions. The discard wasn't gated on
in-flight blocking-request state, so any 'question.asked' event
that arrived during the eviction-then-rehydrate window was routed
to a non-existent store and silently lost.
2. PR #909 re-fetches listPendingQuestions/Permissions only on SSE
reconnect. Switching sessions within the same socket — including
navigating back to a directory whose child store was rebuilt after
eviction — left the UI relying on store state that may have missed
events that fired while a different session was active.
Three edits, in src/sync:
- eviction.ts / types.ts / child-store.ts: add hasPendingBlockingRequests
to EvictPlan + DisposeCheck and never evict a directory whose store
carries a non-empty state.question or state.permission record.
- sync-context.tsx: extract resyncBlockingRequestsForDirectory from the
reconnect path and call it on currentSessionId changes (debounced
250ms), reusing PR #909's signature-based merge so concurrent SSE
updates aren't clobbered.
- __tests__/eviction.test.ts, __tests__/session-switch-resync.test.ts:
new unit coverage for the eviction guard and resync semantics
(deduped fetch per switch, in-flight SSE preservation, stale entry
cleanup, unknown-session filtering).
* fix(sync): refresh store before blocking request resync
---------
Co-authored-by: Alexander Busse <alex@ableph.net>
Co-authored-by: Bohdan Triapitsyn <artmore@protonmail.com>
* feat(chat): add active editor file context and related functionality
* feat(chat): improve active editor file context handling and update translations
* feat(i18n): standardize quotation marks in file attachment messages
* update Korean translation for image removal action in file attachment
* feat(chat): refine active editor file handling and optimize broadcast logic
* fix(chat): stabilize VS Code editor context chips
---------
Signed-off-by: David Saz <david.saz.g@gmail.com>
Co-authored-by: Bohdan Triapitsyn <artmore@protonmail.com>
Polls every 2.5s and transitions automatically once the CLI is reachable
Advanced settings and troubleshooting moved into collapsible accordions
New i18n keys added for status indicator and section titles across 6 locales
* fix: add concurrency controls for multiple sessions using the same provider
Adds OS-inspired scheduling primitives (from HiveMind/AIMD research) to prevent
concurrent sessions from the same provider from experiencing slowdowns, random
stops, and cascading failures.
Server-side:
- Health check skips OpenCode restart when sessions are actively busy — a busy
server under concurrent load can fail the health check timeout without being
dead. Staleness guard forces restart if unhealthy+busy persists >2 minutes.
- Upstream SSE stall timeout scaled from 20s to 60s to avoid unnecessary
reconnections when multiple sessions are waiting for LLM responses.
Client-side (HiveMind primitives, arXiv:2604.17111):
- Transparent retry with exponential backoff (1s→2s→4s, max 32s) for
429/502/503/504 errors — the #1 most effective primitive from the paper.
- Circuit breaker: opens after 3 consecutive retryable errors, cooldown
doubles each trip (30s→60s→120s, capped 128s), matching TCP AIMD.
- Per-provider session tracking with TTL eviction (1h idle sweep).
- Fetch-level retry gated on AbortError/TypeError only (not DNS failures).
Refs github-code-review skill findings (all 8 issues resolved).
* fix: use definite assignment assertion for response variable
Fixes TS2454: Variable 'response' is used before being assigned
in strict mode. The for-loop body always assigns it on every path
that reaches the post-loop code, but TS can't prove that.
* fix: add cleanupSession to error paths and remove unreachable code
P1 fixes (Greptile review):
- cleanupSession called on fetch error throw path
- cleanupSession called on non-retryable HTTP error throw path
- Removed unreachable post-loop code (loop always terminates via return or throw)
Adds explicit post-loop throw to satisfy TypeScript strict return check.
* fix: address Greptile review feedback on concurrent session controls
Removes client-side session tracking that leaked on normal completion paths.
The session tracking was redundant — the server-side health check already reads from
sessionRuntime.getSessionActivitySnapshot() for busy-session detection.
Changes:
- Remove activeSessions Set and all session-tracking functions from provider-tracker
- Remove trackSessionStarted/cleanupSession calls from client.ts
- Remove unreachable (response as Response) block after retry loop
- Make upstreamStallTimeoutMs conditional: 60s when >1 sessions, 20s otherwise
Refs #1069
* fix: enforce dynamic concurrency safeguards
---------
Co-authored-by: Bohdan Triapitsyn <artmore@protonmail.com>
* fix(ui): read textarea DOM value in queue handler to prevent truncation
When the user types quickly and clicks the Queue button, React may not
have committed the latest `message` state yet, causing handleQueueMessage
to capture a stale closure (often just the first character typed).
Read textareaRef.current.value directly from the DOM instead, which
always reflects the current input regardless of React's render cycle.
Fall back to the React state when the ref is unavailable.
Also recompute hasContent from the DOM value to ensure the guard check
is consistent with the actual message being queued.
* fix(ui): use current input value when sending
---------
Co-authored-by: Bohdan Triapitsyn <artmore@protonmail.com>