Commit Graph
761 Commits
Author SHA1 Message Date
Bohdan Triapitsyn 2e49e44205 feat(ui): let users hide context rail surfaces
A trailing configure button on the rail — outside the sortable list and the
digit shortcuts — opens a dialog that toggles each surface. The choice is
stored as the hidden set so newly added surfaces appear for everyone, and
the rail and the mod+alt+digit switcher share the same visibility filter, so
badges and shortcuts always agree. Hidden surfaces keep their data and stay
reachable from the command palette.
2026-08-26 16:18:15 +03:00
Bohdan Triapitsyn f2ec9b1003 feat(ui): add session history navigation, permission keys, and review shortcuts
mod+alt+arrows step through this window's session-open history (or between
neighbouring tabs when session tabs are on), mod+k r renames the current
session inline, and mod+k a toggles permission auto-accept. Pending
permission cards respond to alt+enter / alt+shift+enter / alt+backspace with
the keys printed on the buttons. The commit message box commits on
mod+enter, alt+arrows step the diff review between changed files, and the
command palette gains search-only commands for rare actions so the initial
list stays short.
2026-08-26 15:46:44 +03:00
Bohdan Triapitsyn 7977842e1e feat(ui): redesign the default shortcut layout around a mod+k leader
Single chords stay for everyday actions; open/go actions move to two-step
mod+k sequences; held mod+digit switches header session tabs and held
mod+alt+digit switches context panel surfaces. Rare actions leave the
shortcut schema for the command palette, every remaining action ships with
a default binding, and stored overrides from the old layout reset once.
Key matching now follows the physical key on non-Latin layouts and for
Option-modified digits on macOS, including in the recording dialog.
2026-08-26 14:52:31 +03:00
Bohdan Triapitsyn e904abb794 fix(ui): drop the dead switch_tab actions that collided with surface switching 2026-08-26 11:17:33 +03:00
Bohdan Triapitsyn 94f6b5fd38 feat(ui): migrate all shortcut surfaces to the centralized registry 2026-08-26 10:59:04 +03:00
Bohdan Triapitsyn f1c3870909 feat(ui): land the centralized shortcuts core from #2532 with review fixes
The schema/config/bindings/registry/dispatcher module, useKeybind hooks,
recording dialog, reworked shortcuts settings page, help dialog, and the
localized action labels — re-based onto current main rather than merged
(the branch predates 440+ commits including the session-tabs shortcuts).

Review fixes applied on top of the original:
- close_session_tab (alt+w) joins the schema with labels in every locale;
  it shipped on main after the PR's base and would otherwise silently die.
- switch_context_surface's special-case in conflict resolution is now a
  declared prefixStyle config property instead of a magic id string.
- Duplicate handler registration warns in dev builds.
- The risky-browser-shortcut warning inspects every chord and covers
  mod+q/d/h/j/o/u plus mod+shift+w/q.
- The dispatcher remembers which target armed a two-chord prefix so the
  window-level completion handler can distinguish a deliberate sequence
  from typing in an editable field (guard lands with the dispatch hook).
- Schema tests: unique normalized default bindings enforced, and the
  flat-file-era override format proven to keep resolving.
2026-08-26 10:47:44 +03:00
Bohdan Triapitsyn 79b726451d Merge main and keep the read timeout armed without AbortSignal.any
When the caller passes its own AbortSignal and AbortSignal.any is
unavailable, the timeout was silently dropped — disabling the fix on
exactly the bootstrap reads it targets, since those carry a cancellation
signal. Compose the two signals manually through an AbortController in
that case; listeners detach when the request settles.
2026-08-26 02:23:21 +03:00
Bohdan Triapitsyn 90b6776e5b Merge branch 'main' into pr2969-integration 2026-08-26 02:22:29 +03:00
Bohdan Triapitsyn 448ecc12b8 fix(ui): close review findings from the switch-and-scroll integration
- Markdown DOM cache: key includes a content-length fingerprint so an
  edited or reverted part re-materializing under the same id cannot
  restore stale DOM, memoization uses scalar identities instead of the
  part object (store reducers recreate part objects on unrelated updates,
  which re-ran the async render pipeline for identical content), and a
  probe with a mismatched locale/directory no longer destroys the entry
  it failed to claim.
- Sidebar bootstrap: the layout-level sync owner only knows known
  directories, so expanded projects bootstrapped serialized at background
  priority. The visible collection now publishes a second, expansion-
  aware demand owner, restoring concurrent hydration for expanded
  projects and worktree groups.
- Settings: local changes still sitting in the debounce buffer are not
  yet tracked as mutations, so a settings GET racing the debounce window
  briefly reverted them; reconciled results now reapply the pending
  buffer.
2026-08-26 01:03:47 +03:00
Bohdan Triapitsyn ac880e8e62 Merge main (anchored-turn chat scrolling) into perf/switch-and-scroll
Main replaced the chat timeline scroll engine while this branch was in
flight, which obsoletes two of its subareas and reshapes a third:

- Chat timeline: main's LegendList-based MessageList/ChatContainer win;
  the activation-overscan staircase targeted the removed tanstack path
  (LegendList provides adaptive rendering natively) and is dropped along
  with its test.
- Scroll shadows: main's hook-based masks stay (the virtualized list owns
  its scroll element — there is no wrapper to hand the styling to); the
  viewport-wrapper ScrollShadow rewrite, its index.css replacement, its
  test, and the call-site viewportClassName adaptations are reverted to
  main. The chat OverlayScrollbar keeps this branch's disableHorizontal.
- OverlayScrollbar: the direct-DOM rewrite lands, but binding now follows
  the live container node instead of binding once per ref object — the
  chat scroller remounts on every session switch, and a bind-once
  contract left the scrollbar attached to a dead element.
- Markdown renderer: the detached-DOM cache and warm-block fast path
  merge with main's block-commit reveal (enter cascade), streaming code
  highlighting, and gutter reservation; the per-block reconcile keeps
  both the decoration-refresh path and the reveal cascade.
2026-08-26 00:59:45 +03:00
c_w_xiaohei f329a22cf3 test(ui): align selection with context shell 2026-08-26 02:31:35 +08:00
c_w_xiaohei df924aa532 fix(ui): bound settings mutation history
Skip mutation history when no settings operation is in flight and merge updates that share the same operation visibility window. This keeps stale-response reconciliation unchanged while preventing history from growing with repeated debounced updates.

Add a repeated-update regression covering an older pending load and latest-value reconciliation.

Tests: bun test src/lib/persistence.test.ts
2026-08-26 00:42:37 +08:00
c_w_xiaohei 4454bf7e14 refactor(ui): encapsulate settings mutation tracking
Keep settings mutation revisions and in-flight operations behind a private tracker so stale GET and PUT responses cannot overwrite newer local settings.

Remove redundant runtime identity and numeric operation IDs. Use operation object identity while preserving runtime reset and mutation retention behavior.

Tests: bun test src/lib/persistence.test.ts
2026-08-26 00:42:36 +08:00
c_w_xiaohei 532bdab5e8 fix(ui): preserve upstream behavior after performance rebase 2026-08-26 00:42:36 +08:00
Bohdan Triapitsyn dac31ee026 feat(settings): add streaming auto-follow toggle
New Streaming section on the Chat settings page with a checkbox that
controls whether the viewport follows new content while a response
streams. Default stays on. With it off, the anchored user message still
parks at the top on send, but no glide or end-follow correction runs and
the list's maintain-scroll-at-end stays disabled; the scroll-to-bottom
pill and session open keep scrolling explicitly.

Persisted through desktop settings like the other chat toggles (auto-save
diff, authoritative apply, sanitize), registered in settings search, and
localized in every locale.
2026-08-25 14:53:43 +03:00
Bohdan Triapitsyn b6e14cbf21 refactor(settings): always-docked editor toolbar; reorder Navigation
The 'Always show editor toolbar' preference is gone — the docked
toolbar under the file tabs is now the only mode, and the floating
hover toolbar branch in the files editor (with its open-state and
outside-click machinery) is deleted. The stored preference is dropped
by a store migration and removed from desktop settings persistence,
settings search and every locale.

Navigation section order now reads: file editor keymap, auto-save,
terminal shell + login shell, Terminal Quick Keys, and the Session
tabs group last.
2026-08-25 00:32:09 +03:00
Bohdan Triapitsyn ce90e7e24f feat(settings): Session tabs toggle in General → Navigation
A new Session tabs group (web/desktop only) turns the header session
tabs off; disabled, the header renders the exact pre-tabs view — plain
session title with meta row and the always-visible session menu (the
same block VS Code uses). The Alt+W close-tab shortcut no-ops while
tabs are off. Registered in settings search with a matching anchor;
labels translated in all locales.
2026-08-25 00:05:45 +03:00
Bohdan Triapitsyn 2c1d8d592e feat(header): Alt+W closes the active session tab, customizable in Settings
The close-with-neighbour-activation logic moved into a shared helper
(the strip and the shortcut use the same path). Alt+W is the default
because the browser owns Cmd/Ctrl+W on web; desktop users can rebind it
— the action is registered as customizable, so it appears in the
Settings shortcuts section and the shortcuts help automatically. VS
Code is excluded (it has no session tabs).
2026-08-24 20:57:01 +03:00
Bohdan Triapitsyn dcacf4b3fc perf(header): cap session tabs at 20; tooltip data loads on hover only
Auto-add means the strip only grows, so past 20 tabs the oldest one
leaves the working set (the newly opened tab is always the survivor).
The branch/worktree/PR/project subscriptions that feed the hover
tooltip moved into the tooltip body component, which mounts only while
the tooltip is open — a resting tab now subscribes only to its status
dot's session status and unread count.
2026-08-24 20:47:51 +03:00
Bohdan Triapitsyn a53c78b54a fix: adjust light theme selection color 2026-08-24 20:37:25 +03:00
Bohdan Triapitsyn a3813f57e9 feat(header): session tabs — a horizontal working set of open sessions
Web/desktop header replaces the single session title with a strip of
soft pill tabs, one per session the user has opened (sidebar, palette
or deep link — opening anywhere adds a tab once). The active tab is the
familiar title block — rename, meta row and the full session menu —
inside a gently selected pill; a brand-new draft shows as a transient
pill until its session exists. Inactive tabs show the title with a
hover-revealed "..." menu (close tab, close other tabs, copy id) that
nudges the text like sidebar rows, and close by middle-click too.

Tabs drag to reorder, scroll behind the right-side header buttons with
soft fade edges, respect the reserved window-controls inset, and
persist across reloads. Closing the active tab activates its neighbour
(or opens a new draft when it was the last). Tab ids whose session is
not in the loaded list stay stored but hidden, so a partial session
list never destroys the working set. VS Code keeps the plain title;
mobile is untouched.
2026-08-24 17:07:09 +03:00
Bohdan Triapitsyn c82f188fc8 refactor(surface): remove the main-area surface concept entirely
activeSurface was permanently 'chat' after the legacy mobile layout
removal, so the whole concept is gone: the store field, surfaceGuard,
setActiveSurface/setSurfaceGuard, the per-runtime surface memory in
prepare/restoreForRuntimeSwitch, and WorkspaceSurface itself. All ~30
setActiveSurface('chat') call sites were no-ops and are deleted;
always-true 'is the chat active' checks in keyboard shortcuts, Header
and ChatContainer are unconditional now. FilesView's dirty-file guard
kept its file-switch and close protection but drops the surface-switch
branch nothing could trigger. TerminalView visibility comes only from
its callers. The router keeps parsing legacy ?tab= links (they open the
matching context-panel surface) via its own RouteTab type and no longer
serializes a tab or diff file into URLs — desktop URLs never carried
them anyway.
2026-08-24 16:36:41 +03:00
Bohdan Triapitsyn 4da7604d7d refactor(surface): drop the deprecated main-tab aliases and dead diagram surface
MainTab/activeMainTab/setActiveMainTab/setMainTabGuard were deprecated
mirrors of the surface names — every call site now uses
activeSurface/setActiveSurface/setSurfaceGuard directly and the aliases
are gone, including the persisted mirror field.

The 'diagram' surface had no way to open it (navigateToDiagram had no
callers except a .drawio attachment click that navigated to a surface
nothing rendered); the surface, DiagramView, and its store plumbing are
removed, and a .drawio attachment now opens in the file panel.

?tab= deep links map to the matching context-panel surface instead of
setting a main-area surface nothing renders, and a persisted non-chat
surface can no longer rehydrate into a blank main area.
2026-08-24 16:21:05 +03:00
Bohdan Triapitsyn 841eca5720 feat(surface): switch app shells when the viewport crosses the phone threshold
The mobile-vs-desktop surface is stamped once at boot, so a browser
window narrowed past the phone threshold kept the desktop shell (and
its legacy squeezed layout) until a manual reload. A viewport watcher
now reloads into the other shell once the resize settles — the same
mechanism the old Settings toggle used. Fixed shells (Capacitor,
desktop, VS Code) and ?surface= overrides never switch.

With the new mobile app reachable this way, the old/new mobile layout
preference is gone: phones always get the mobile app.
2026-08-24 16:08:04 +03:00
Bohdan Triapitsyn b8716fe808 refactor(search): unify dropdown filtering on the shared ranked matcher
Branch, project, agent, model, provider, stash, SSH-host, skill-catalog
and archive filters each had their own toLowerCase().includes (or no
ordering at all); the git branch and gitmoji pickers also let cmdk
re-filter and reorder on top of the manual filter, silently dropping
rows. All of them now go through rankByQuery/matchesRankQuery: results
are relevance-ordered, multi-word queries match in any order, matching
ignores punctuation, and cmdk filtering is disabled where the ranked
list is already final. rankBranchesForQuery keeps relevance order
instead of re-sorting matches alphabetically; the model picker now also
matches model ids.
2026-08-24 15:00:52 +03:00
Bohdan Triapitsyn 081056e6e5 feat(search): canonical rankByQuery matcher for searchable dropdowns
One matcher for every dropdown filter: multi-token queries match in any
order, matching is punctuation-insensitive, single-token queries
tolerate typos, and results come back relevance-ordered (prefix, then
word-boundary, then substring, original order on ties). matchesRankQuery
is the boolean companion for lists that keep their own grouping.
2026-08-24 14:54:14 +03:00
Bohdan Triapitsyn 2f27f0ec4b fix(terminal): reconcile tabs with server sessions and keep shown terminals alive
The tab list lived only in per-tab sessionStorage, so a new browser
tab, another device, or cleared storage showed an empty terminal
sidebar while PTYs kept running server-side, and orphans leaked until
the idle sweep. Add GET /api/terminal/sessions and adopt unknown
server sessions into the local tab projection (additive only; a failed
listing changes nothing).

The idle sweep also reaped terminals in background tabs because only
the active tab holds a WebSocket attachment. Add POST
/api/terminal/touch and have open clients periodically refresh
activity for every session their tabs reference.
2026-08-24 14:30:00 +03:00
Bohdan Triapitsyn 0918bee566 fix(chat): rank @ mention files and directories together by match quality
Directories and files were rendered as fixed category blocks, so an
exact file match sat below unrelated directories. Merge both result
sets and rank them with the shared fuzzy scorer against the full
relative path. Multi-word queries now match tokens in any order
(longest token queries the server, the rest filter client-side), and
path truncation keeps the parent segments next to the file name so
index.md-heavy trees stay distinguishable.
2026-08-24 14:30:00 +03:00
Bohdan Triapitsyn eb03ffaa80 feat(files): comment on selection in read-only markdown previews
Selecting text in a rendered markdown preview shows a Comment pill;
attaching stores a file-quote context draft carrying the file path, the
selected fragment (not whole lines), the user's comment, and a
best-effort source line range resolved by anchoring the fragment's
first and last lines in the raw content — a partially located fragment
gets no range rather than a misleading one. The fragment stays
highlighted while the comment input is open, using the selection
overlay rects shared with chat quote comments, and the preview's
native selection color now matches chat messages. file-quote flows
through the same context contract: composer chip previews, the message
context card, and the metadata round-trip.
2026-08-24 01:21:35 +03:00
Bohdan Triapitsyn 538b532fb1 feat(composer): context chip previews with inline comment editing
Hovering (or tapping) a context chip opens a stacked preview of its
pending items above the composer: numbered entries with a muted header
band, the captured selection, and the user's comment, which can be
edited in place (save/cancel) or removed before sending. The chips
component now subscribes to the draft store itself; the per-kind count
plumbing in ChatInput is gone.
2026-08-24 00:16:26 +03:00
Bohdan Triapitsyn 1ae3aeff5f feat(chat): structured context attachments with metadata round-trip
Every user-attached context item (diff/file/plan comments, terminal
selections, browser annotations, PR comments and failed checks, linked
issues/PRs, and new chat-quote comments from the selection menu) is now
sent as its own synthetic text part carrying an openchamberContext
metadata payload. The model-facing text keeps the previous wording; the
timeline reads the metadata back and renders each item as a context card
instead of raw prompt text. Legacy messages still render via the old
text sniffing.

The selection menu gains a Comment option with an inline multiline
input, the quoted fragment stays highlighted while commenting, and on
mobile the input overlays the composer pill by rendering inside the
composer form. Add to chat is renamed Add to input; the menu is
restyled and the mobile Copy tile removed. Terminal drafts move their
terminal id out of the language field (persisted-draft migration v3),
and the dead preview-console source is deleted.
2026-08-23 23:40:32 +03:00
ChangeHowandBohdan Triapitsyn 3a78d86248 fix(ui): open app deep links from chat after confirmation (#2932)
* fix(ui): open app deep links from chat after confirmation

DOMPurify's default URI policy stripped href from anchors with custom
application schemes (obsidian://, vscode://, ...), so every app link
rendered in chat was dead across web, desktop, VS Code, and mobile.

- Classify safe app-link schemes in lib/url.ts (browser-handled,
  scriptable, webview-internal, network, and self-deep-link schemes
  stay excluded) and let openExternalUrl accept them
- Keep app-link hrefs through the markdown sanitize hook
- Intercept app-link clicks in the markdown renderer and route them
  through a confirmation dialog (Trust and open / Open once, dismiss
  to cancel) mounted in the desktop/web app root and the mobile shell
- Persist per-device trusted schemes in a zustand store; trusted
  schemes open without asking again

* feat(settings): manage trusted app link schemes in General

Add an App links section to Settings > General listing the application
schemes trusted on this device with a delete action; removing a scheme
restores the confirmation dialog for it. Register the section in
settings search.

* fix(ui): enforce app link confirmation

* fix(ui): handle app links by runtime

* fix(vscode): keep app links unsupported

* fix(settings): clarify trusted app links

---------

Co-authored-by: Bohdan Triapitsyn <artmore@protonmail.com>
2026-08-23 01:53:21 +03:00
Jay GuptaandBohdan Triapitsyn 46426e8495 feat(chat): /btw — side questions in a temporary forked session (#2796)
* feat(chat): /btw command — side questions in a temporary forked session

/btw <question> forks the current session (full context inheritance) and
opens a compact peek panel docked above the composer. The composer itself
becomes the btw input while the panel is open: sends route to the fork,
the placeholder and a mode chip reflect the target, and the stop button
aborts the fork's turn. Closing the panel (or the chip's ✕) destroys the
fork, leaving the main conversation untouched.

The panel shows only the fork's own tail (messages at/after the fork
creation time) and live permission/question cards scoped to the fork.

- chat/btw/BtwPanel: peek sheet (desktop + mobile), fork-tail view,
  auto-close on disappearance, Esc to close
- lib/btw: startBtwSession (fork + rename + routed send), closeBtwPanel
  (close = destroy), filterBtwTailMessages
- ChatInput: btw-mode send routing via SendMessageOptions.sessionId,
  btw-aware activity (stop/abort), placeholder + mode chip
- useSessionActivity: exported for per-session activity reads
- i18n: btw keys across all 11 locales

* fix(chat): keep btw sends isolated

* refactor(chat): rework /btw into a metadata-scoped peek panel

- Link the active btw fork through the parent session's metadata
  (openchamber.btwSessionID) so the panel exists only in the session that
  invoked /btw, follows parent navigation, and survives reloads; the fork
  carries a kind:'btw' marker with its originalSessionID.
- Replace the wall-clock history boundary with the id of the newest cloned
  message (server-generated ascending ids), stored in fork metadata.
- Derive panel identity in useBtwPanelState; useBtwStore shrinks to
  transient per-parent UI state (collapsed/creating/destroying).
- Panel UX: dropdown-style glass surface, chat ScrollShadow, single
  title+chevron collapse toggle, muted header controls, promote action
  (keep as a full session and navigate to it), Esc collapses instead of
  destroying, reserved Working indicator row, streaming auto-follow via
  ResizeObserver keyed on content readiness.
- Add a 'peek' chat surface mode that suppresses per-message controls and
  turn footers inside the panel; user bubbles keep a small gap below.
- Hide btw forks from the sidebar, session switcher, and command palette
  until promoted; mark the fork before inserting it into local stores.
- Delete/archive lifecycle: removing the fork unlinks the parent; removing
  the parent also removes its temporary fork.
- patchSessionMetadata now mirrors updated sessions into live stores.
- Localize new strings across all 12 dictionaries; add unit tests for
  metadata helpers, the btw flow, and the UI store.

* fix(chat): clamp the btw panel below the app header when the keyboard is open

Reuse useMobileAutocompleteMaxHeight (the composer autocomplete precedent)
on the panel's scroll body, reserving the panel header and bottom spacer
height, so the sheet adapts to the visual viewport instead of riding under
the app header on mobile.

* fix(lint): drop unused destructured bindings in sessionBtwMetadata

CI eslint has no underscore ignore pattern; strip metadata keys with typed
copies and delete instead of discard-destructuring.

---------

Co-authored-by: Bohdan Triapitsyn <artmore@protonmail.com>
2026-08-23 00:40:06 +03:00
Bohdan Triapitsyn 2740c7b3a2 feat(projects): pin a thinking level next to a project's model
A project could pin the model new chats start on, but not the level to
run it at: the default cascade dropped any variant as soon as a project
model won, and only ever considered the global one — which belongs to
the global model.

Projects now carry `defaultVariant` alongside `defaultModel`, stored and
sanitized only next to that model, and the cascade passes it through.
Both controls sit in one "Defaults for new chats" group laid out like the
Sessions defaults, and the level appears only for models that offer them.
2026-08-22 20:31:31 +03:00
Pascal André c452a8092c fix(files): refresh expired outside-workspace grants (#3078)
* fix(files): refresh expired outside file grants

* fix(files): scope outside grants to local runtime
2026-08-22 20:26:20 +03:00
Bohdan Triapitsyn f7a0d1f0f6 feat(ssh): rework remote instance setup and fix remote installs
Adding an SSH connection now starts from the hosts in the SSH config
instead of a blank command field, ports and install options sit behind
Advanced settings, and each connection reports one of three states with
the failure text and an action that resolves it.

Remote installs no longer touch the root-owned global npm prefix: npm is
pinned to a prefix under $HOME and bun is resolved at its known location,
because an SSH login shell exposes neither on PATH. The opencode CLI is
resolved the same way and handed to the remote server through
OPENCODE_BINARY, and the server is started and stopped through the
resolved binary rather than PATH — the HTTP shutdown route sits behind UI
authentication and never stopped anything.

A managed remote server can also be published to the remote machine's own
network. That requires a UI password, enforced in the form and again in
the SSH manager.
2026-08-22 16:45:56 +03:00
Bohdan Triapitsyn 735a9463ca fix(chats): use a dedicated empty message
Show a localized Chats-specific empty state instead of reusing the project workspace session message.
2026-08-22 11:41:59 +03:00
Bohdan Triapitsyn 4021dd4e26 fix(git): separate generated PR prompt blocks
The additional context and pull request template blocks ran into the file
list without a blank line, and the template's markdown headings blended into
the surrounding instructions. Each block now starts on its own, and template
content is fenced with explicit markers labelled as structure to reuse rather
than instructions to follow.

Claude-Session: https://claude.ai/code/session_01NzK8hD1hFHHHwv2FgZJwC2
2026-08-22 02:04:06 +03:00
Bohdan Triapitsyn 514d2e82da feat(git): follow repository style when generating commit and PR text
Commit generation now samples the last 10 commit subjects and instructs the
model to match their language, prefix convention, and length, falling back to
Conventional Commits only when the history shows no consistent style.

PR generation probes the conventional pull request template locations and
reuses the repository's own sections and checklists as the body structure when
one is found.

Claude-Session: https://claude.ai/code/session_01NzK8hD1hFHHHwv2FgZJwC2
2026-08-22 01:52:19 +03:00
Bohdan Triapitsyn 23928d342c feat(dictation): transcribe after recording instead of live
Parakeet is an offline model trained on whole utterances, so re-decoding
the growing buffer to animate a live transcript cost O(n^2) work for a
result the final decode replaced. Sessions now decode once per committed
segment, and the composer shows a scrolling waveform of the mic level
instead of running text.

Long dictations split at a pause once past 60s (hard cap 90s) instead of
on a blind 15s timer, so cuts no longer land mid-word. Committed segments
decode while the user is still speaking: a 185s dictation returns 4.1s
after stop instead of 11.0s, with identical text (816 vs 817 words).

Also fixes two ways the stream manager could silently drop transcribed
audio. It now counts the commits it issued instead of trusting the
session's echoed events, so a commit still in flight when the client
finishes can no longer be left out of the final text. And segment
byte/peak accounting is reset where the commit is issued rather than when
the event arrives, which could mistake the tail of a dictation for
silence and clear it.
2026-08-22 01:10:19 +03:00
Bohdan Triapitsyn 0d50253efa refactor(integrations): retire unavailable options
Remove retired Command Code, Discord, and Telegram integration entries, search targets, and documentation. Keep Command Code provider usage and logo support available through normalized provider ID aliases.
2026-08-22 01:10:19 +03:00
Bohdan Triapitsyn 0b01f5ae2d feat(diff): add branch scope to context panel diff view
Show every change on the current branch relative to its base in the
Changed/Staged/Last turn dropdown. The base comes from the branch's
reflog record or an explicit per-branch user choice (persisted), never
a main/master guess; when git has no record the user picks a base once
from a searchable branch list.

- server: GET /api/git/branch-base (reflog-derived base),
  GET /api/git/range-files (name-status -z with rename/copy
  destination paths and -C copy detection)
- shared UI: optional getBranchBase/getGitRangeFiles runtime APIs
  with boundary parsing; persisted per-branch overrides keyed by
  runtime+directory+branch
- DiffView: branch scope with confirmed-unavailability coercion of
  persisted tabs (detached HEAD, default-branch checkout, metadata
  settled without a default), range-invalidated diff cache guarded
  against stale completions, bounded branch-metadata retry, read-only
  diff actions in branch scope; hidden in VS Code
- helper module branchDiffScope.ts with tests for coercion,
  availability, race conditions, and retry exhaustion
2026-08-22 01:10:19 +03:00
Bohdan Triapitsyn f29844b2f1 feat(settings): mark integrations as experimental 2026-08-22 01:10:19 +03:00
Bohdan Triapitsyn 70a7a77ded refactor(ui): name workspace surfaces 2026-08-22 01:10:19 +03:00
Bohdan Triapitsyn b1030d3cb7 fix(chats): align folders and session actions
Render managed Chats through the shared folder-aware session group and keep folder ownership at the Chats root, including new drafts and older per-directory scopes.

Hide worktree actions for Chats, make worktree shortcuts inert on Chat drafts, and let new-session shortcuts inherit an active session directory while explicit Chats controls still create managed Chat drafts.
2026-08-21 16:29:26 +03:00
Bohdan Triapitsyn b879cf323f feat(sidebar): add single-project display mode 2026-08-21 16:25:51 +03:00
Bohdan Triapitsyn 9e87d7fdb9 feat(chats): add managed projectless chat sessions
Create projectless chat sessions under a managed, date-scoped Chats directory and clean abandoned or deleted session folders.

Add Chats to sidebar state, startup cache, shared context, and Electron Mini Chat while keeping VS Code project-only. Resolve managed chat directories to one server-side memory owner and document the runtime contracts.
2026-08-21 12:12:40 +03:00
Bohdan Triapitsyn 3613127e2d fix(quota): support z.ai credit limits 2026-08-20 19:09:13 +03:00
Bohdan Triapitsyn 647a949369 feat(providers): support custom API protocols 2026-08-20 18:39:13 +03:00
Bohdan Triapitsyn 1ed3f1f575 feat(skills): curated GitHub catalog redesign (#3016)
* feat(skills): remove ClawHub catalog integration

Drop the ClawHub registry as a skills catalog source across web server,
shared UI, VS Code, docs, and locales. The catalog now serves git-based
sources only: the curated Anthropic repo and user-defined repositories.
Also removes the now-unused adm-zip dependency.

* feat(skills): redesign catalog around curated GitHub repositories

Replace the single-source dropdown with a card grid of curated GitHub
repositories (Anthropic, OpenAI, Cursor pstack/skills, Matt Pocock) plus
user-defined sources. Source cards show skill counts, GitHub stars, and
last-updated time; a global search covers all loaded sources.

Server: curated sources gain GitHub repo metadata (stars, pushed_at)
fetched best-effort with a 3-hour in-memory and on-disk cache; scans
run through a concurrency-limited, deduplicated cache with 3-hour TTL
persisted across restarts. Refresh still bypasses the cache.

Shared UI: source cards, global search with clear button, per-skill
GitHub links, install/installed states. VS Code curated list updated
to match. All new copy translated across 12 locales.

* fix(skills): address catalog review findings

- GitHub metadata fetch timeout drops to 1.5s (under the catalog
  client's 3s deadline) and failed lookups cache briefly (5 min) so
  repeated catalog loads do not re-hit a failing API.
- Disk cache files are written with owner-only permissions (0o600);
  rename preserves the mode.
- loadSource deduplicates concurrent in-flight requests per source and
  the shared isLoadingSource flag now clears only when the last active
  source load finishes.
2026-08-20 01:40:10 +03:00