- Highlight the vertical rail on conversations open in tabs with a darker primary tint and bleed 1px at both ends to stay continuous across cards
- Add emphasized state to SidebarStatusIcon mirroring the rail, deepening color when the conversation is open in a tab
- Redesign done icon as outlined circle + check, unify all status icons to sidebar-primary with consistent 0.75rem size and sidebar-tinted backdrop so they mask the rail
- Drop the expanded-state background and border on folder headers; keep the unified hover background
- Swap the arrow to a ChevronRight/ChevronDown toggle and remove the rotation animation to avoid subpixel rendering drift
- Size the arrow icon at 11px so its vertical center lands on an integer pixel
- Round the sticky overlay's top offset so it stays pixel-aligned with the virtual list items
Call plugin:event|listen/unlisten directly and guard the client-side listener
registry cleanup, so unsubscribe always reaches the backend even when the
registration eval has not yet populated window.__TAURI_EVENT_LISTENERS__.
Prevents the intermittent `listeners[eventId].handlerId` TypeError and the
resulting leaked listener.
- Sidebar: replace the "no conversations" placeholder with Open Folder, Clone Repository, and Project Boot buttons when the workspace has no open folders.
- Title bar: disable the terminal and auxiliary-panel toggle buttons while no folder is active.
- Aux panel: show a shared localized "no folder open" prompt in the file tree, git changes, and git log tabs when no folder is active.
- Add auxPanel.noFolderTitle / noFolderHint translations across all ten supported locales.
- 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.