Commit Graph
1052 Commits
Author SHA1 Message Date
82b36e5080 fix: align session status parsing and vscode reconnect reconcile (#1125)
* fix: align session status parsing and vscode reconnect reconcile

* fix vscode session status fallback and reconcile cleanup safety

---------

Co-authored-by: vhqtvn <8930337+vhqtvn@users.noreply.github.com>
Co-authored-by: Bohdan Triapitsyn <artmore@protonmail.com>
2026-05-06 19:45:31 +03:00
3a98987f71 Add quick archive action to session rows (#1124)
* feat: add quick archive action to session rows

* refine quick archive row spacing and handler consistency

---------

Co-authored-by: Zoubair Benryane <zoubair@Zoubairs-MacBook-Air.local>
Co-authored-by: Bohdan Triapitsyn <artmore@protonmail.com>
2026-05-06 19:42:19 +03:00
7eff2f725f feat: add Polish localization (#1123)
* Add Polish (pl) localization

* translations

* fix: add missing Polish translations

* copy en keys to pl

* fix: complete Polish settings translations

* fix: localize PWA install prompt

* fix pwa install prompt lifecycle and complete Polish locale keys

* polish polish locale wording for natural phrasing

---------

Co-authored-by: levy52 <levy52@vp.pl>
Co-authored-by: Bohdan Triapitsyn <artmore@protonmail.com>
2026-05-06 19:38:58 +03:00
Junlang Huang ce4c5ae99f fix: redirect focus to hidden input after blurring Ghostty elements (#1122)
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.
2026-05-06 19:30:43 +03:00
Bohdan Triapitsyn c9289eb24f feat: add stash access in clean git state
Show a Stashes button when the working tree is clean
Keep stash management available even without visible file changes
2026-05-06 15:13:38 +03:00
Bohdan Triapitsyn dbc06dd6fa perf: reduce duplicate app initialization and heavy view imports
Deduplicates concurrent app initialization in the config store
Lazy-loads VS Code-only app surfaces
Avoids broad view barrel imports for better chunk isolation
2026-05-06 02:43:13 +03:00
Bohdan Triapitsyn 170d334921 feat: add manual save mode to file editor
Added a persistent autosave toggle for file editing
Manual save mode applies across current and future opened files
Updated localized toolbar labels
2026-05-06 02:27:07 +03:00
Bohdan Triapitsyn b18886598c fix: validate configured OpenCode binary (#1120)
* Validate configured OpenCode binary

* fix: keep WSL OpenCode startup failures retryable

Avoids misclassifying transient WSL resolution failures as invalid binary config
Adds regression coverage for WSL strict-mode handling
Cleans up temporary test directories
Fix for #1119 issue
2026-05-06 02:06:16 +03:00
Bohdan Triapitsyn a02f0cd7c7 fix: improve git operation progress banner
Replace placeholder conflict text with localized copy
Split in-progress operation details and actions into clearer rows
Keep merge and rebase status messages consistent
2026-05-06 01:58:36 +03:00
Bohdan Triapitsyn 6a749ed259 fix: suppress expected missing directory logs
Stops noisy stack traces for missing directory probes
Preserves existing 404 behavior for absent directories
2026-05-06 01:51:14 +03:00
Bohdan Triapitsyn 105443aac2 style: refine git header tab sizing
Compact the Git tab row beside sync
Tune tab height for a cleaner header
2026-05-06 01:46:33 +03:00
Bohdan Triapitsyn a6582bbcff fix: expand git history dialog height
Give the history dialog more vertical space
Let the commit list fill the dialog height
2026-05-06 01:34:58 +03:00
Bohdan Triapitsyn 9af3b49e7b fix: remove duplicate clean-state sync action
Keep sync available only in the Git header
Simplify the clean working tree empty state
2026-05-06 01:31:23 +03:00
Bohdan Triapitsyn 0546de31f6 refactor: streamline git sidebar header
Move action tabs into the Git header with sync beside them
Merge worktree actions into the Update tab
Place stash access next to changed files
2026-05-06 01:29:01 +03:00
Bohdan Triapitsyn 6b25fd7d20 fix: show pull request unavailable state
Replace the empty PR tab with a clear unavailable message
Explain when pull request actions are available
2026-05-06 00:55:56 +03:00
Bohdan Triapitsyn 89f0e0a0e6 fix: show sync loading during commit sync
Keep the header sync button busy while commit & sync finishes
Avoid showing pending push counts during the sync step
2026-05-06 00:49:32 +03:00
Bohdan Triapitsyn cce782a62b fix: simplify existing pull request header
Reflow PR status and checks into a cleaner two-row header
Remove the remote selector from existing PRs
Keep remote context as read-only tracking info
2026-05-06 00:46:40 +03:00
Bohdan Triapitsyn 32929d592e fix: make branch updates use latest remote refs
Fetch remote targets before merge or rebase
Prefer remote branch targets over stale local branches
Fix Update copy and branch search input
2026-05-06 00:32:55 +03:00
Bohdan Triapitsyn 8540f51395 fix: make commit sync use safe sync flow
Rename commit push action to Commit & sync
Use fetch and rebase before pushing committed changes
Keep sync result toasts consistent
2026-05-06 00:12:39 +03:00
Bohdan Triapitsyn 16c349417f style: simplify git header controls
Show sync counters only when needed
Use an icon-only identity selector
2026-05-05 23:57:42 +03:00
Bohdan Triapitsyn 7b66bca2c5 fix: clarify sync button and result toasts
Show sync label when no remote changes are known
Report pulled file counts in sync success toasts
Count pulled files correctly in VS Code sync
2026-05-05 23:53:21 +03:00
Bohdan Triapitsyn 93267927ff feat: add git stash management
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
2026-05-05 23:39:20 +03:00
Bohdan Triapitsyn c80c2b62a8 feat: add one-click git sync button
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
2026-05-05 20:45:31 +03:00
Bohdan Triapitsyn ddfd2db0b8 fix: keep button text unselectable outside markdown
Restore non-selectable text for app buttons
Keep markdown file links selectable
2026-05-05 20:45:31 +03:00
2b0e1ef42e fix(sync): preserve pending questions across session switch and directory eviction (closes #918) (#1103)
* 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>
2026-05-05 19:39:35 +03:00
Bohdan Triapitsyn a49e2ce1ae perf: optimize markdown file link detection
Only mark existing files as openable links
Avoid file-link behavior while messages stream
Limit file existence checks to 4 concurrent requests
2026-05-05 19:21:44 +03:00
Bohdan Triapitsyn fd6635a963 fix: prevent generate button flicker during git refresh
Keep Generate enabled during changed-file refreshes
Preserve existing blockers for generation and commits
2026-05-05 19:00:35 +03:00
Bohdan Triapitsyn 6dd322ddbe fix: reduce local server status overhead 2026-05-05 18:47:00 +03:00
962ee41bba fix(ui): add opt-in mobile keyboard resize mode and stabilize touch terminal input (#1107)
* fix(ui): add opt-in mobile keyboard resize mode

* fix(ui): stabilize touch terminal input and tab layout

* fix(ui): narrow touch terminal handling to mobile and tablet

* fix(ui): refine touch terminal input handling

* fix(ui): re-key terminal viewport on session id

* fix(ui): avoid touch-laptop terminal overlay regression

* fix(ui): hide ghostty system caret surfaces

* fix(settings): normalize mobile keyboard mode sanitization

* fix(ui): honor terminal quick keys toggle on mobile

* fix(ui): gate mobile keyboard resize mode on iOS

---------

Co-authored-by: vhqtvn <8930337+vhqtvn@users.noreply.github.com>
Co-authored-by: Bohdan Triapitsyn <artmore@protonmail.com>
2026-05-05 12:26:34 +03:00
jwcrystalandBohdan Triapitsyn 63b4a5b996 feat(ui): enable TimelineDialog with full-text search across all message roles in one session (#1104)
* feat: register open_timeline_dialog shortcut (mod+t)

* feat: enhance TimelineDialog with full-text search across all roles

* feat: add open_timeline_dialog shortcut labels to all locales

* feat: wire TimelineDialog into ChatContainer

* fix: add setTimelineDialogOpen to hook dependency array

* fix: tighten timeline dialog interactions

---------

Co-authored-by: Bohdan Triapitsyn <artmore@protonmail.com>
2026-05-05 11:21:06 +03:00
Bohdan Triapitsyn 495b9d56d2 release v1.10.0 2026-05-05 01:39:33 +03:00
Bohdan Triapitsyn eadff4e338 fix: resolve message action lint warning
Added the missing hook dependency for message action rendering
Lint and type-check now pass cleanly
2026-05-05 01:26:37 +03:00
David SazandBohdan Triapitsyn 5475ef2db3 Feat/add ide opened file to chat context (#1106)
* 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>
2026-05-05 01:24:03 +03:00
Bohdan Triapitsyn 7fc22bc69b feat: auto-detect OpenCode CLI on onboarding screen
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
2026-05-05 00:41:30 +03:00
Bohdan Triapitsyn 581f7c34dc fix: align iPad PWA window controls spacing
Adds tablet standalone PWA detection
Aligns header and sidebar action padding
Extends safe-area handling for tablet PWAs
2026-05-04 00:04:29 +03:00
Bohdan Triapitsyn fc2f4746e5 fix: avoid iPad PWA traffic light overlap
Adds tablet standalone PWA detection
Reuses macOS traffic-light header spacing
Protects session sidebar and multirun headers
2026-05-03 21:39:30 +03:00
Bohdan Triapitsyn 9964dcdb99 fix(cli): tolerate legacy daemon flag (#1097) 2026-05-03 21:38:45 +03:00
Bohdan Triapitsyn 6595322f1a fix: show tablet actions without hover
Makes hover-only controls visible on tablets
Preserves existing mobile and desktop layouts
Covers chat, session sidebar, file, tab, and picker actions
2026-05-03 17:19:55 +03:00
Bohdan Triapitsyn 43f98e0344 feat(ui): add recent section toggle 2026-05-03 16:32:14 +03:00
Bohdan Triapitsyn 5614012acb fix(ui): keep streaming deltas through pipeline 2026-05-03 13:42:50 +03:00
Bohdan Triapitsyn f810a3316c fix(ui): prevent streaming text flicker and first-chunk loss 2026-05-03 02:32:05 +03:00
Bohdan Triapitsyn 4ad5d2f4b7 fix(ui): tolerate invalid message parts 2026-05-01 15:08:44 +03:00
Shyamalan KannanandBohdan Triapitsyn a9ee499ae4 fix: add concurrency controls for multiple sessions using the same provider (#1069)
* 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>
2026-05-01 14:57:31 +03:00
pasta-paulandBohdan Triapitsyn f9094bc3cc fix(ui): prevent queued message truncation from stale React closure (#1087)
* 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>
2026-05-01 14:26:14 +03:00
Bohdan Triapitsyn a077735bcf fix: keep chat pinned during delayed rendering
Keeps long historical sessions scrolled to the bottom after load
Preserves bottom follow while assistant responses grow
2026-05-01 14:13:18 +03:00
Bohdan Triapitsyn d820e25ea1 fix: keep generated prompts scrolled into view
Force chat to bottom on normal sends
Scroll generated commit prompts into view
Preserve saved scroll restore for passive navigation
2026-05-01 13:48:07 +03:00
pasta-paulandBohdan Triapitsyn 1991736ebf fix(server): prevent streaming hang during long agent sessions (#1088)
* fix(server): increase WS buffer/replay limits and add backpressure warning

During long-running agent sessions (e.g. ultrawork loops with many tool
calls), the browser WebSocket client can briefly fall behind the server.
When the outbound buffer exceeds the limit, the server force-disconnects
with close code 1013, and the small replay buffer (512 events) is
insufficient to recover all missed events — leaving the UI permanently
stalled.

Changes:
- Raise MESSAGE_STREAM_WS_MAX_BUFFERED_BYTES from 4 MB to 16 MB to
  tolerate larger bursts without disconnecting
- Add MESSAGE_STREAM_WS_BACKPRESSURE_WARN_BYTES (12 MB) threshold that
  sends a one-shot "backpressure" frame to the client before the hard
  disconnect, giving it a chance to shed low-priority updates
- Raise MESSAGE_STREAM_GLOBAL_REPLAY_LIMIT from 512 to 2048 so more
  events survive brief reconnection gaps
- Add tests for the backpressure warning behavior (emit, dedup, reset)

* fix(ui): batch event flushes under backpressure

---------
Co-authored-by: Bohdan Triapitsyn <artmore@protonmail.com>
2026-05-01 13:25:19 +03:00
jwcrystalandBohdan Triapitsyn 03c9065c90 fix: preserve per-session scroll position on session switch (#1083)
* fix: restore scroll position when switching chat sessions

When switching between chat sessions, scroll position now restores to
where the user left off instead of always jumping to the bottom.

- Save pixel-level scrollPosition (scrollTop/scrollHeight/clientHeight)
  in viewport store on every scroll event
- Add restoreSavedScrollPosition to timeline controller for ratio-based
  restoration (handles content size changes between visits)
- Suppress intermediate scroll events during session transition with an
  explicit flag, cleared deterministically after restore completes
- Cancel in-flight animations/follow-loops on session switch
- Preserve scrollPosition when session-ui-store rebuilds SessionMemoryState

* fix: keep streaming sessions pinned on restore

---------

Co-authored-by: Bohdan Triapitsyn <artmore@protonmail.com>
2026-05-01 12:39:04 +03:00
Islam NoflandBohdan Triapitsyn a23f5e7545 fix: cross-verify update API claims against npm registry (#1082)
* fix: cross-verify update API claims against npm registry

* Update packages/web/server/lib/package-manager.js

Signed-off-by: Islam Nofl <islamnofl.official@gmail.com>

* fix: show live server version in AboutDialog instead of stale build-time constant

* fix: add comment to empty catch block to satisfy lint no-empty rule

* fix: preserve live about dialog version in electron

* fix: scope update checks by runtime

---------

Signed-off-by: Islam Nofl <islamnofl.official@gmail.com>
Co-authored-by: Bohdan Triapitsyn <artmore@protonmail.com>
2026-05-01 12:23:58 +03:00
Bohdan Triapitsyn c924e85a29 feat(settings): add response style presets 2026-05-01 01:27:31 +03:00