- Replace the branch badge with a compact count badge; recolor the
folder name and badge to sidebar-primary on a tinted row background
when expanded
- Lighten the selected conversation item background so the expanded
folder row stays the strongest signal
- Add a "+" button on each folder header that reuses a single new-
conversation tab across folders, disconnecting the old ACP session
so the connection lifecycle reconnects against the target folder's
working directory
Folder/branch pickers now render at the top of the input's rounded box
instead of a separate strip above it. Restyled as xs outlined buttons
matching the config selectors, always rendering the folder picker
chevron (dimmed when not editable). Removed the right-side commit/push
git action buttons and their unused imports. Scoped the bar to its
owning tab via a tabId prop so tile mode shows each tab's own folder
and disabled state independent of which tab is globally active.
- Align conversation guide line and status icon to the folder chevron center (left: 0.875rem)
- Use fixed 1px guide line with darker shade (sidebar-primary/15) for better visibility
- Add bottom border to sidebar title and a top gap above the folder list
- Tighten list horizontal padding to px-2 with matching pt-2 for consistency
- Fill the done status icon frame directly to avoid sub-pixel off-centering
Replace flat/grouped view toggle with a show-completed filter dropdown,
add expand/collapse-all control, extract status icon component, and
simplify the sidebar header.
Both the inline autocomplete (triggered by `/` in the textarea) and the
dropdown popup (triggered by the slash-command button) now show a search
field at the top. Matching uses substring on name and description, and
ranks name matches above description/id-only matches.
When a deep directory was renamed or deleted externally and both the
directory itself and a parent directory were cached, only the self entry
was cleared — leaving the parent's children list holding a ghost reference
to the old child. Walk up to the nearest cached ancestor in addition to
the direct hit so both stale entries are dropped together.
Also gate the follow-up getFileTree refetch on the directory still being
expanded. Collapsed branches only need their cache cleared; they will
re-hydrate naturally on the next expansion, which avoids unnecessary IPC
traffic during FS event bursts.
Deep directories (beyond the workspace snapshot's depth limit) relied on
a lazy-loaded override cache that was never invalidated, so agent-created
files, in-app deletes / renames / rollbacks, and external changes inside
expanded deep folders stayed invisible until the folder was reopened.
Propagate watcher `changed_paths` through the delta envelope and fire a
Meta event whenever FS activity doesn't alter the tree/git snapshots, so
the frontend can surgically invalidate affected cache entries and
re-fetch. Manual refresh (Reload from disk) clears the cache and
re-hydrates still-expanded deep dirs through the same path. Replayed
deltas after reconnect are forwarded to the same listeners.
Also split the combined workspace-state effect into tree / git / status
slices so unrelated state transitions (e.g. the 'resyncing' flip during
a refresh) no longer rebuild the entire node tree and cause a flash.
Replace the legacy folder + welcome routes with a unified /workspace route
that hosts all folders, conversations, tabs, and terminals in one window.
- Persist opened tabs to the database (opened_tabs entity + migration)
so tab layout survives restarts and deep-link bootstrap restores state
- Replace FolderContext shim with AppWorkspaceProvider, ActiveFolderProvider,
and TabProvider; expose both opened (folders) and full DB (allFolders)
listings via list_all_folder_details
- Return conversations across all non-deleted folders from list_all when
no folder filter is given, so the sidebar can show every folder's history
- Add ConversationContextBar above the chat input with folder picker
(auto-opens unopened folders on select), branch picker, and commit /
push / merge / stash entries to restore BranchDropdown functionality
- Rework sidebar with stats header, search, flat / folder-grouped view
modes (localStorage-persisted), reveal-in-sidebar event subscriber,
and per-folder context menu (focus, close tabs, remove from workspace);
indent conversations under folder headers in grouped mode
- Gate terminal creation on active folder and show folder context
- Remove deprecated BranchDropdown, FolderNameDropdown, welcome route,
and per-folder window commands
- Localize all new strings across 10 locales
Intercept keyboard events via xterm's custom key handler and emit
readline/zle escape sequences so bindings work regardless of terminfo:
- Alt/Option + Left/Right: word-wise cursor move
- Alt/Option + Backspace: delete previous word
- macOS Cmd + Left/Right: jump to line start/end
- macOS Cmd + Backspace: clear to line start
Uses `e.code` to stay correct on dead-key layouts, skips IME
composition, and excludes AltGr (ctrl+alt) on Windows/Linux.
Extend the existing appearance zoom setting so it also scales xterm.js
terminals and Monaco editors (diff viewer, three-pane merge editor, file
workspace editor), which previously rendered at a hard-coded 13px
regardless of zoom.
- Terminals read zoom at init and update term.options.fontSize live on
zoom change, refitting after a double rAF so xterm's renderer has
recomputed cell metrics. Font size is rounded to an integer to avoid
subpixel blur in the canvas renderer.
- Monaco editors derive fontSize from zoomLevel; three-pane merge
editor memoizes its options object to avoid redundant updateOptions
calls on unrelated re-renders.
The settings shell wrapped children in an outer section with p-3/p-4 padding.
With OverlayScrollbars replacing native scroll, the overlay scrollbar sat at
the viewport's right edge and covered the right border of inner cards.
Drop the outer padding (and the now-redundant overflow-auto) from the shell
and apply p-3 md:p-4 inside each settings page instead, so the scrollbar
aligns with the column edge while inner sections stay within the padded area.
Child processes now have LANG/LC_ALL pinned to C.UTF-8 on every
platform, so git stderr is always English when it leaks past the
typed not_a_git_repository preflight. The 8 non-English regex
fallbacks were dead code; keep only the English pattern as a
belt-and-suspenders fallback for un-preflighted commands.
Previously LANG/LC_ALL were only set on Windows, so git stderr was
localized on macOS/Linux and substring checks for English messages
(e.g. 'unknown revision or path not in the working tree') silently
failed — empty-repo/missing-branch cases surfaced as red error
banners in the Git log panel instead of rendering as empty lists.
Reintroduce a local not-a-git-repo fallback state in the git log panel so non-repo errors still render the dedicated empty state when workspace state streaming is degraded.
Improve git repository preflight classification by distinguishing missing paths, permission issues, and non-directory targets before checking .git presence.
Add not_a_git_repository to the frontend AppErrorCode union for explicit typed handling.
Consolidate `.git` presence detection into a shared `git_repo` module used by both the workspace state watcher and the command preflight helper, replacing duplicated local definitions.
Introduce `AppErrorCode::NotAGitRepository` (HTTP 422) and preflight eleven frontend-callable git commands (log, status, list-branches, diff, diff-with-branch, show-diff, show-file, push-info, list-remotes, list-all-branches, commit-branches) so non-git folders short-circuit with a structured error instead of leaking locale-dependent git stderr.
Frontend `isNotAGitRepoError` checks the error code first and falls back to a multi-language regex list centralized in `src/i18n/git-error-patterns.ts`, covering the nine languages git actually translates into.
Wire the git log panel to `workspaceState.isGitRepo` rather than a local cached flag, so running `git init` or deleting `.git` externally propagates through the watcher and refreshes the panel automatically.
- Replace hardcoded "Claude Code" in agent_responding with each session's actual AgentType label; store agent_type on ActiveSession and populate it in both task-start and resume paths
- Remove silent ClaudeCode fallback in resolve_agent_type; /task now prompts the user to pick an agent when none is selected and the folder has no default
- Move session command strings out of session_commands.rs into i18n.rs with full 10-language coverage (en/zh-CN/zh-TW/ja/ko/es/de/fr/pt/ar)
- Fix French accent and wrap Latin agent name with Arabic bidi isolates (FSI/PDI) for consistent rendering across Telegram/Lark/WeiXin clients
- Release the bridge lock before the get_lang DB lookup in the content_delta flush path to avoid cross-session contention
- Log unknown agent_type fallback in conversation_service::parse_agent_type for observability
Reconcile the cached is_git_repo flag against the filesystem on every watch flush so `git init` or deletion of .git is reflected immediately: sync the stored flag, drop stale git_snapshot data when the repo goes away, emit a meta delta when presence flips without any data change, and mark the event as requires_resync so the frontend re-fetches the snapshot to pick up the new flag.
Replace the title-bar branch polling interval with a self-adjusting setTimeout chain that backs off to 60s when get_git_branch returns null or throws and drops back to 10s once a branch is detected, so branches created externally recover within one slow tick without hammering the backend on non-git folders.
Gate git refresh on .git presence so file churn in non-git workspaces no longer produces endless resync_hint events, and silently log tree/git refresh errors during watch flushing instead of flagging requires_resync, which turned transient failures into self-reinforcing loops.
Degrade gracefully when the filesystem watcher fails to attach (e.g. permission denied, inotify quota): keep the initial snapshot, surface a degraded flag, and expose a store-level restart that the banner uses to retry attachment after the root cause is fixed.
Propagate is_git_repo through the snapshot so the git log and changes tabs render a dedicated "Not a Git repository" empty state instead of raw git stderr with a useless retry button.
Stop polling get_git_branch from the title bar once it returns null and re-arm on visibility change.
Add translations for the new banner, empty-state, and retry keys across all ten locales.
- Persist user-supplied access token and last-used port in app_metadata, falling back to defaults when unset
- Atomically guard concurrent starts via compare_exchange with RAII rollback of the running flag
- Wrap token and port persistence in a single SeaORM transaction to prevent partial writes
- Classify bind errors (port in use, permission denied, address unavailable, invalid address) into stable i18n keys
- Localize start-failure messages across all 10 supported languages