ui: CWD for agent (#26518)

* server : extend file_glob_search for UI pickers

* ui : add per-conversation working directory with picker

* ui : add path navigation and search scope to cwd picker

Treat path-like queries (starting with / or ~) as directory navigation
instead of glob-matching the whole query: search the parent for the last
segment, and descend into an exactly-typed directory by listing its
children. Show the effective search scope in the footer and auto-search
on open so the current directory and its siblings appear immediately.

Assisted-by: Claude

* db : persist per-call tool cwd on tool result messages

* ui : abbreviate tool paths under home with a tilde

* ui : show the per-call cwd on exec shell rows

* ui : clarify the synthetic cwd message for the model

* ui : reuse the trailing cwd row on a repeated pick

* ui : don't jump when a cwd row is injected mid-chat

* chore: Formatting

* refactor: Cleanup comments

* ui : unify working directory naming and add a synthetic-message flag

* ui : render synthetic cwd rows without a scroll jump

* ui : decouple the working directory picker into utils and sub-components

* ui : add get_info tool call block

* chore: Formatting

* refactor: Cleanup

* refactor: Cleanup

* refactor: Cleanup

* fix: UI

* server : harden file_glob_search listing (kind enum, timeout, symlink guard, absolute base)

* ui : use persisted isSynthetic flag for cwd rows, drop legacy formats

* ui : cache picker search, fail visibly on native resolve

* ui : escape glob metacharacters in picker search glob

* ui : simplify auto-scroll pin

* chore: Format

* fix: Use `SvelteMap`

* refactor: Post-review fixes

* ui: accept Windows roots in the working directory picker

recognize a drive root (C:) and a UNC share (//host/share) as path
navigation, alongside the POSIX root and ~, so a query like D:\repos
lists that directory instead of glob-matching it under the home dir

split below the root, so a bare drive resolves to its root rather than
to a drive-relative prefix

rewrite backslashes into forward slashes only when the query carries a
Windows root, since a backslash is a legal POSIX filename character

paths keep travelling with forward slashes, which is what the server
returns and what Windows accepts

---------

Co-authored-by: Pascal <admin@serveurperso.com>
This commit is contained in:
Aleksander Grygier
2026-08-04 19:05:48 +02:00
committed by GitHub
co-authored by Pascal
parent 0713275082
commit 2f56fc3431
41 changed files with 1946 additions and 95 deletions
@@ -272,6 +272,16 @@ export { default as ChatFormMcpResourcesList } from './ChatForm/ChatFormMcpResou
*/
export { default as ChatFormTextarea } from './ChatForm/ChatFormTextarea.svelte';
/**
* Working directory selector for agent mode. Renders a chip below the chat
* form; clicking it opens a popover with a directory picker backed by the
* server's `file_glob_search` built-in tool (POST /tools). The picked
* directory is exposed via `bind:directory`; changing it records a
* synthetic "Set working directory to ..." user message into chat history
* and is enforced on tool calls via the `x-tool-cwd` request header.
*/
export { default as ChatFormWorkingDirectory } from './ChatForm/ChatFormWorkingDirectory.svelte';
/**
* **ChatFormPickerMcpPrompts** - MCP prompt selection interface
*
@@ -557,6 +567,22 @@ export { default as ChatMessageStatisticsBadge } from './ChatMessages/ChatMessag
*/
export { default as ChatMessageMcpPrompt } from './ChatMessages/ChatMessage/ChatMessageMcpPrompt/ChatMessageMcpPrompt.svelte';
/**
* Synthetic working-directory-change message. Rendered in place of a user
* bubble when the message content parses as a cwd message (see
* parseCwdMessage); shows the new cwd with the same folder-row treatment
* the tool-call UI used.
*/
export { default as ChatMessageCwdChange } from './ChatMessages/ChatMessage/ChatMessageCwdChange.svelte';
/**
* Generic wrapper for UI-generated (synthetic) messages. Routes the
* working-directory change to ChatMessageCwdChange and renders a muted
* fallback for any other synthetic text, so no synthetic message ever
* surfaces as a user bubble.
*/
export { default as ChatMessageSynthetic } from './ChatMessages/ChatMessage/ChatMessageSynthetic.svelte';
/**
* Formatted content display for MCP prompt messages. Renders the full prompt
* content with arguments in a readable format. Used within ChatMessageMcpPrompt