From d3d07e84c9dcbfc6ca476f0ecee7ebf0e2201ada Mon Sep 17 00:00:00 2001 From: Aleksander Grygier Date: Tue, 25 Aug 2026 12:10:25 +0200 Subject: [PATCH 1/2] chore: Spacing between sibling elements in html markup --- tools/ui/eslint.config.js | 110 +++++++++++++++++- ...hatAttachmentsPreviewCurrentItemPdf.svelte | 8 ++ .../ChatFormActionAddReasoningSubmenu.svelte | 1 + .../ChatFormActionSubmit.svelte | 1 + .../ContextGaugeDetailRow.svelte | 1 + .../ContextGaugeDetails.svelte | 2 + .../ContextGaugeLoadModel.svelte | 2 + .../ContextGaugePopup.svelte | 3 + .../ChatFormCurrentWorkingDirectory.svelte | 1 + ...ChatFormCurrentWorkingDirectoryChip.svelte | 1 + ...mCurrentWorkingDirectoryResultsList.svelte | 1 + .../ChatFormPicker/ChatFormPickerList.svelte | 2 + .../ChatFormPickerListItemSkeleton.svelte | 1 + .../ChatFormPickerCommand.svelte | 2 + .../ChatFormPickerMention.svelte | 4 + .../ChatMessage/ChatMessageCwdChange.svelte | 3 + .../ChatMessageToolCallBlockDefault.svelte | 7 ++ .../ChatMessageToolCallBlockEditFile.svelte | 9 ++ ...essageToolCallBlockExecShellCommand.svelte | 8 ++ ...tMessageToolCallBlockFileGlobSearch.svelte | 6 + ...ChatMessageToolCallBlockGetDatetime.svelte | 4 + .../ChatMessageToolCallBlockGetInfo.svelte | 5 + .../ChatMessageToolCallBlockGrepSearch.svelte | 10 ++ .../ChatMessageToolCallBlockReadFile.svelte | 2 + .../ChatMessageToolCallBlockReadMedia.svelte | 2 + ...atMessageToolCallBlockRunJavascript.svelte | 6 + ...atMessageToolCallBlockSearchResults.svelte | 8 ++ .../ChatMessageToolCallBlockWriteFile.svelte | 5 + .../ChatMessageUserPending.svelte | 2 + .../ChatMessageActionCard.svelte | 2 + ...tMessageActionCardPermissionRequest.svelte | 1 + .../ChatMessageActionIcons.svelte | 1 + .../ChatMessageStatisticsBadge.svelte | 1 + .../ChatScreenStreamResumeStatus.svelte | 1 + .../app/chat/ChatTabs/ChatTabs.svelte | 1 + .../MarkdownContent/MarkdownContent.svelte | 5 + .../app/content/MermaidPreviewControls.svelte | 4 + .../app/dialogs/DialogConfirmation.svelte | 1 + .../app/dialogs/DialogMcpServerAddNew.svelte | 1 + .../app/dialogs/DialogModelInformation.svelte | 2 + .../dialogs/DialogModelNotAvailable.svelte | 2 + .../app/mcp/McpActiveServersAvatars.svelte | 1 + .../mcp/McpServerCard/McpServerCard.svelte | 5 + .../app/mcp/McpServerCardSkeleton.svelte | 8 ++ .../app/models/ModelsSelectorList.svelte | 4 + .../app/models/ModelsSelectorSheet.svelte | 2 + .../app/navigation/DropdownMenuActions.svelte | 2 + .../app/server/ServerErrorSplash.svelte | 6 + .../settings/SettingsChat/SettingsChat.svelte | 1 + .../SettingsChat/SettingsChatFields.svelte | 8 ++ .../SettingsChat/SettingsChatToolsTab.svelte | 3 + .../SettingsChatDesktopSidebar.svelte | 2 + .../settings/SettingsChatMobileHeader.svelte | 2 + .../app/settings/SettingsFooter.svelte | 3 + .../src/lib/components/pwa/PwaMetaTags.svelte | 3 + .../alert-dialog/alert-dialog-content.svelte | 1 + .../ui/dialog/dialog-content.svelte | 3 + .../dropdown-menu-checkbox-item.svelte | 1 + .../dropdown-menu-radio-item.svelte | 1 + .../dropdown-menu-sub-trigger.svelte | 1 + .../scroll-area/scroll-area-scrollbar.svelte | 1 + .../ui/scroll-area/scroll-area.svelte | 3 + .../ui/select/select-content.svelte | 2 + .../components/ui/select/select-item.svelte | 1 + .../ui/select/select-trigger.svelte | 1 + .../components/ui/sheet/sheet-content.svelte | 3 + .../ui/tooltip/tooltip-content.svelte | 1 + tools/ui/src/routes/+error.svelte | 3 + .../stories/ModelsSelector.stories.svelte | 9 ++ .../a11y/ActionIcon.a11y.stories.svelte | 1 + .../a11y/ScrollCarousel.a11y.stories.svelte | 4 + 71 files changed, 324 insertions(+), 1 deletion(-) diff --git a/tools/ui/eslint.config.js b/tools/ui/eslint.config.js index 6ad065f5a0f8..9eba3435d262 100644 --- a/tools/ui/eslint.config.js +++ b/tools/ui/eslint.config.js @@ -12,6 +12,107 @@ import { fileURLToPath } from 'node:url'; import ts from 'typescript-eslint'; const gitignorePath = fileURLToPath(new URL('./.gitignore', import.meta.url)); +// Require a blank line between sibling element-like nodes in a Svelte template +// (elements, components, and the {#if} / {#each} / {#await} / {#snippet} / +// {@render} blocks) that sit on separate lines at the same nesting level. +// Whitespace between siblings is a whitespace-only SvelteText node; when it +// holds a single newline (no blank line) the fix adds one, keeping the +// indentation of the second sibling. Real text content (e.g. `foo\n\nbar`) +// is left alone. +const ELEMENT_LIKE_TYPES = new Set([ + 'SvelteAwaitBlock', + 'SvelteComponent', + 'SvelteEachBlock', + 'SvelteElement', + 'SvelteIfBlock', + 'SvelteKeyBlock', + 'SvelteRenderTag', + 'SvelteSelf', + 'SvelteSnippetBlock' +]); +const paddingLineBetweenElements = { + create(context) { + // Check one list of template children. Each children array holds the + // element-like nodes plus the whitespace/comment text between them. + function checkChildren(children) { + if (!Array.isArray(children)) return; + + let lastElement = null; + let lastWhitespace = null; + + for (const child of children) { + if (child.type === 'SvelteText' && /^\s*$/.test(child.value)) { + lastWhitespace = child; + + continue; + } + + if (!ELEMENT_LIKE_TYPES.has(child.type)) continue; + + if ( + lastElement && + lastWhitespace && + child.loc.start.line - lastElement.loc.end.line === 1 + ) { + const textNode = lastWhitespace; + + context.report({ + fix(fixer) { + // Add a second newline so the two siblings are separated by a + // blank line, keeping the trailing indentation. + return fixer.replaceText(textNode, textNode.value.replace(/\n/, '\n\n')); + }, + message: 'Expected a blank line between sibling elements.', + node: child + }); + } + + lastElement = child; + lastWhitespace = null; + } + } + + return { + SvelteAwaitBlock(node) { + checkChildren(node.children); + checkChildren(node.then?.children); + checkChildren(node.else?.children); + }, + SvelteComponent(node) { + checkChildren(node.children); + }, + SvelteEachBlock(node) { + checkChildren(node.children); + checkChildren(node.else?.children); + }, + SvelteElement(node) { + checkChildren(node.children); + }, + SvelteFragment(node) { + checkChildren(node.children); + }, + SvelteIfBlock(node) { + checkChildren(node.children); + checkChildren(node.else?.children); + }, + SvelteKeyBlock(node) { + checkChildren(node.children); + }, + SvelteProgram(node) { + checkChildren(node.children); + }, + SvelteSnippetBlock(node) { + checkChildren(node.children); + } + }; + }, + meta: { + docs: { description: 'Require a blank line between sibling elements in a Svelte template.' }, + fixable: 'whitespace', + schema: [], + type: 'layout' + } +}; // Require a blank line between consecutive class accessors (get/set). The core // `padding-line-between-statements` rule only handles statements, not class // members, so this is enforced with a small custom rule. @@ -66,7 +167,12 @@ export default ts.config( { languageOptions: { globals: { ...globals.browser, ...globals.node } }, plugins: { - local: { rules: { 'blank-line-between-accessors': blankLineBetweenAccessors } }, + local: { + rules: { + 'blank-line-between-accessors': blankLineBetweenAccessors, + 'padding-line-between-elements': paddingLineBetweenElements + } + }, perfectionist, 'simple-import-sort': simpleImportSort }, @@ -82,6 +188,8 @@ export default ts.config( 'eol-last': 'error', // Enforce a blank line between consecutive get/set accessors 'local/blank-line-between-accessors': 'error', + // Require a blank line between sibling elements in a Svelte template + 'local/padding-line-between-elements': 'error', // typescript-eslint strongly recommend that you do not use the no-undef lint rule on TypeScript projects. // see: https://typescript-eslint.io/troubleshooting/faqs/eslint/#i-get-errors-from-the-no-undef-rule-about-global-variables-not-being-defined-even-though-there-are-no-typescript-errors 'no-undef': 'off', diff --git a/tools/ui/src/lib/components/app/chat/ChatAttachments/ChatAttachmentsPreview/ChatAttachmentsPreviewCurrentItem/ChatAttachmentsPreviewCurrentItemPdf.svelte b/tools/ui/src/lib/components/app/chat/ChatAttachments/ChatAttachmentsPreview/ChatAttachmentsPreviewCurrentItem/ChatAttachmentsPreviewCurrentItemPdf.svelte index 4be156edbaea..3eeb59d0e860 100644 --- a/tools/ui/src/lib/components/app/chat/ChatAttachments/ChatAttachmentsPreview/ChatAttachmentsPreviewCurrentItem/ChatAttachmentsPreviewCurrentItemPdf.svelte +++ b/tools/ui/src/lib/components/app/chat/ChatAttachments/ChatAttachmentsPreview/ChatAttachmentsPreviewCurrentItem/ChatAttachmentsPreviewCurrentItemPdf.svelte @@ -116,7 +116,9 @@ {#if !hasVisionModality && activeModelId && currentItem} + Preview only + The selected model does not support vision. Only the extracted @@ -140,6 +142,7 @@
+

Converting PDF to images...

@@ -147,20 +150,25 @@
+

Failed to load PDF images

+

{pdfImagesError}

{:else if pdfImages.length > 0} {#each pdfImages as image, index (image)}

Page {index + 1}

+ PDF Page {index + 1} +
{/each} {:else}
+

No PDF pages available

diff --git a/tools/ui/src/lib/components/app/chat/ChatForm/ChatFormActions/ChatFormActionAdd/ChatFormActionAddReasoningSubmenu.svelte b/tools/ui/src/lib/components/app/chat/ChatForm/ChatFormActions/ChatFormActionAdd/ChatFormActionAddReasoningSubmenu.svelte index a3a0b3a20fc5..1b6fc4b02096 100644 --- a/tools/ui/src/lib/components/app/chat/ChatForm/ChatFormActions/ChatFormActionAdd/ChatFormActionAddReasoningSubmenu.svelte +++ b/tools/ui/src/lib/components/app/chat/ChatForm/ChatFormActions/ChatFormActionAdd/ChatFormActionAddReasoningSubmenu.svelte @@ -64,6 +64,7 @@ +

Maximum reasoning effort with extended context usage

diff --git a/tools/ui/src/lib/components/app/chat/ChatForm/ChatFormActions/ChatFormActionSubmit.svelte b/tools/ui/src/lib/components/app/chat/ChatForm/ChatFormActions/ChatFormActionSubmit.svelte index eff0364fa065..1018cad54dc1 100644 --- a/tools/ui/src/lib/components/app/chat/ChatForm/ChatFormActions/ChatFormActionSubmit.svelte +++ b/tools/ui/src/lib/components/app/chat/ChatForm/ChatFormActions/ChatFormActionSubmit.svelte @@ -27,6 +27,7 @@ {...props} > Send + {/snippet} diff --git a/tools/ui/src/lib/components/app/chat/ChatForm/ChatFormContextGauge/ContextGaugeDetailRow.svelte b/tools/ui/src/lib/components/app/chat/ChatForm/ChatFormContextGauge/ContextGaugeDetailRow.svelte index 271997b39355..572d4a42dd44 100644 --- a/tools/ui/src/lib/components/app/chat/ChatForm/ChatFormContextGauge/ContextGaugeDetailRow.svelte +++ b/tools/ui/src/lib/components/app/chat/ChatForm/ChatFormContextGauge/ContextGaugeDetailRow.svelte @@ -11,6 +11,7 @@
{label} + {value}
diff --git a/tools/ui/src/lib/components/app/chat/ChatForm/ChatFormContextGauge/ContextGaugeDetails.svelte b/tools/ui/src/lib/components/app/chat/ChatForm/ChatFormContextGauge/ContextGaugeDetails.svelte index 1153c70fdd85..c6170880f4ca 100644 --- a/tools/ui/src/lib/components/app/chat/ChatForm/ChatFormContextGauge/ContextGaugeDetails.svelte +++ b/tools/ui/src/lib/components/app/chat/ChatForm/ChatFormContextGauge/ContextGaugeDetails.svelte @@ -63,6 +63,7 @@ : undefined} /> {/if} + {#if cumulativeOutput > 0}
KV cache total + {kvTotal.toLocaleString()} tok
diff --git a/tools/ui/src/lib/components/app/chat/ChatForm/ChatFormContextGauge/ContextGaugeLoadModel.svelte b/tools/ui/src/lib/components/app/chat/ChatForm/ChatFormContextGauge/ContextGaugeLoadModel.svelte index 022e626ae9d0..3a03bad86082 100644 --- a/tools/ui/src/lib/components/app/chat/ChatForm/ChatFormContextGauge/ContextGaugeLoadModel.svelte +++ b/tools/ui/src/lib/components/app/chat/ChatForm/ChatFormContextGauge/ContextGaugeLoadModel.svelte @@ -14,11 +14,13 @@ {#if modelId !== null && !isLoading}
Available context size is only visible once the model is loaded. +
{:else if isLoading}
+ Loading model...
{/if} diff --git a/tools/ui/src/lib/components/app/chat/ChatForm/ChatFormContextGauge/ContextGaugePopup.svelte b/tools/ui/src/lib/components/app/chat/ChatForm/ChatFormContextGauge/ContextGaugePopup.svelte index 5d80ecc11b93..b1665a366e73 100644 --- a/tools/ui/src/lib/components/app/chat/ChatForm/ChatFormContextGauge/ContextGaugePopup.svelte +++ b/tools/ui/src/lib/components/app/chat/ChatForm/ChatFormContextGauge/ContextGaugePopup.svelte @@ -64,7 +64,9 @@
Context + · + {formatParameters(gauge.contextUsed)} / {gauge.contextTotal !== null ? formatParameters(gauge.contextTotal) : '-'} @@ -91,6 +93,7 @@ {gauge.contextPercent}% used + {formatParameters(gauge.contextAvailable ?? 0)} remaining diff --git a/tools/ui/src/lib/components/app/chat/ChatForm/ChatFormCurrentWorkingDirectory/ChatFormCurrentWorkingDirectory.svelte b/tools/ui/src/lib/components/app/chat/ChatForm/ChatFormCurrentWorkingDirectory/ChatFormCurrentWorkingDirectory.svelte index 99b7763e3504..ea6b5e664d56 100644 --- a/tools/ui/src/lib/components/app/chat/ChatForm/ChatFormCurrentWorkingDirectory/ChatFormCurrentWorkingDirectory.svelte +++ b/tools/ui/src/lib/components/app/chat/ChatForm/ChatFormCurrentWorkingDirectory/ChatFormCurrentWorkingDirectory.svelte @@ -391,6 +391,7 @@ onclick={browseNative} > + Browse {/if} diff --git a/tools/ui/src/lib/components/app/chat/ChatForm/ChatFormCurrentWorkingDirectory/ChatFormCurrentWorkingDirectoryChip.svelte b/tools/ui/src/lib/components/app/chat/ChatForm/ChatFormCurrentWorkingDirectory/ChatFormCurrentWorkingDirectoryChip.svelte index 23661d223d53..70101ec49b25 100644 --- a/tools/ui/src/lib/components/app/chat/ChatForm/ChatFormCurrentWorkingDirectory/ChatFormCurrentWorkingDirectoryChip.svelte +++ b/tools/ui/src/lib/components/app/chat/ChatForm/ChatFormCurrentWorkingDirectory/ChatFormCurrentWorkingDirectoryChip.svelte @@ -42,6 +42,7 @@ {displayLabel} {/snippet} +

{displayLabelTitle}

diff --git a/tools/ui/src/lib/components/app/chat/ChatForm/ChatFormCurrentWorkingDirectory/ChatFormCurrentWorkingDirectoryResultsList.svelte b/tools/ui/src/lib/components/app/chat/ChatForm/ChatFormCurrentWorkingDirectory/ChatFormCurrentWorkingDirectoryResultsList.svelte index e8087d967ef1..fa2ec79b5a2c 100644 --- a/tools/ui/src/lib/components/app/chat/ChatForm/ChatFormCurrentWorkingDirectory/ChatFormCurrentWorkingDirectoryResultsList.svelte +++ b/tools/ui/src/lib/components/app/chat/ChatForm/ChatFormCurrentWorkingDirectory/ChatFormCurrentWorkingDirectoryResultsList.svelte @@ -56,6 +56,7 @@ onmouseenter={() => onHover?.(index)} > + {#each highlightMatch(path, rawQuery.trim()) as seg, segIndex (segIndex)} {#if seg.match} diff --git a/tools/ui/src/lib/components/app/chat/ChatForm/ChatFormPickers/ChatFormPicker/ChatFormPickerList.svelte b/tools/ui/src/lib/components/app/chat/ChatForm/ChatFormPickers/ChatFormPicker/ChatFormPickerList.svelte index 160c14ce8e8a..57df2d680b26 100644 --- a/tools/ui/src/lib/components/app/chat/ChatForm/ChatFormPickers/ChatFormPicker/ChatFormPickerList.svelte +++ b/tools/ui/src/lib/components/app/chat/ChatForm/ChatFormPickers/ChatFormPicker/ChatFormPickerList.svelte @@ -85,8 +85,10 @@ {#each { length: skeletonCount } as _, rowIndex (rowIndex)}
+
+
diff --git a/tools/ui/src/lib/components/app/chat/ChatForm/ChatFormPickers/ChatFormPicker/ChatFormPickerListItemSkeleton.svelte b/tools/ui/src/lib/components/app/chat/ChatForm/ChatFormPickers/ChatFormPicker/ChatFormPickerListItemSkeleton.svelte index cbf7b972e5f5..36910eda42cc 100644 --- a/tools/ui/src/lib/components/app/chat/ChatForm/ChatFormPickers/ChatFormPicker/ChatFormPickerListItemSkeleton.svelte +++ b/tools/ui/src/lib/components/app/chat/ChatForm/ChatFormPickers/ChatFormPicker/ChatFormPickerListItemSkeleton.svelte @@ -12,6 +12,7 @@
+
diff --git a/tools/ui/src/lib/components/app/chat/ChatForm/ChatFormPickers/ChatFormPickerCommand.svelte b/tools/ui/src/lib/components/app/chat/ChatForm/ChatFormPickers/ChatFormPickerCommand.svelte index df654b25bb45..6be129b4372f 100644 --- a/tools/ui/src/lib/components/app/chat/ChatForm/ChatFormPickers/ChatFormPickerCommand.svelte +++ b/tools/ui/src/lib/components/app/chat/ChatForm/ChatFormPickers/ChatFormPickerCommand.svelte @@ -130,8 +130,10 @@ }} > +
/{command.name} + {command.description} diff --git a/tools/ui/src/lib/components/app/chat/ChatForm/ChatFormPickers/ChatFormPickerMention.svelte b/tools/ui/src/lib/components/app/chat/ChatForm/ChatFormPickers/ChatFormPickerMention.svelte index 2cc3bd8b6f7a..6c6e6cd81ee8 100644 --- a/tools/ui/src/lib/components/app/chat/ChatForm/ChatFormPickers/ChatFormPickerMention.svelte +++ b/tools/ui/src/lib/components/app/chat/ChatForm/ChatFormPickers/ChatFormPickerMention.svelte @@ -245,6 +245,7 @@ : 'text-muted-foreground' ]} /> +
{#if showTooltip} @@ -254,6 +255,7 @@ {entry.name} {/snippet} +

{entry.path}

@@ -261,12 +263,14 @@ {:else} {entry.name} {/if} + {entry.type}
+ diff --git a/tools/ui/src/lib/components/app/chat/ChatMessages/ChatMessage/ChatMessageCwdChange.svelte b/tools/ui/src/lib/components/app/chat/ChatMessages/ChatMessage/ChatMessageCwdChange.svelte index 3869e19a0df4..6d8d045dceb2 100644 --- a/tools/ui/src/lib/components/app/chat/ChatMessages/ChatMessage/ChatMessageCwdChange.svelte +++ b/tools/ui/src/lib/components/app/chat/ChatMessages/ChatMessage/ChatMessageCwdChange.svelte @@ -19,10 +19,13 @@
{#if info.path === null} + Working directory cleared {:else} + Set working directory to  + {info.display} diff --git a/tools/ui/src/lib/components/app/chat/ChatMessages/ChatMessage/ChatMessageToolCall/ChatMessageToolCallBlockDefault.svelte b/tools/ui/src/lib/components/app/chat/ChatMessages/ChatMessage/ChatMessageToolCall/ChatMessageToolCallBlockDefault.svelte index 3ca64a7823ca..99e2dba36619 100644 --- a/tools/ui/src/lib/components/app/chat/ChatMessages/ChatMessage/ChatMessageToolCall/ChatMessageToolCallBlockDefault.svelte +++ b/tools/ui/src/lib/components/app/chat/ChatMessages/ChatMessage/ChatMessageToolCall/ChatMessageToolCallBlockDefault.svelte @@ -39,10 +39,12 @@ {#if ctx.isStreamingCall}
Input + {#if ctx.isStreaming} {/if}
+ {#if section.toolArgs} Input
+ {/if} +
Output + {#if ctx.isPending} {/if}
+ {#if ctx.isPending}
Waiting for result... @@ -103,6 +109,7 @@
{line.text}
+ {#if line.media} {#if line.media.type === AttachmentType.AUDIO} {@const audioMimeType = line.media.mimeType ?? MimeTypeAudio.MP3_MPEG} diff --git a/tools/ui/src/lib/components/app/chat/ChatMessages/ChatMessage/ChatMessageToolCall/ChatMessageToolCallBlockEditFile.svelte b/tools/ui/src/lib/components/app/chat/ChatMessages/ChatMessage/ChatMessageToolCall/ChatMessageToolCallBlockEditFile.svelte index 6545cc39f7a9..70dd9bb110a4 100644 --- a/tools/ui/src/lib/components/app/chat/ChatMessages/ChatMessage/ChatMessageToolCall/ChatMessageToolCallBlockEditFile.svelte +++ b/tools/ui/src/lib/components/app/chat/ChatMessages/ChatMessage/ChatMessageToolCall/ChatMessageToolCallBlockEditFile.svelte @@ -26,9 +26,11 @@ {#snippet titleSnippet()} Edit file + {abbreviateHome(editFileMeta?.filePath ?? '', home)} + {#if editFileMeta?.errorMessage} (failed) {/if} @@ -40,6 +42,7 @@ class="flex items-start gap-2 rounded bg-red-500/10 p-2 text-xs text-red-600 italic dark:text-red-400" > + {meta.errorMessage}
{:else if meta && meta.edits.length > 0} @@ -48,13 +51,17 @@
Edit {ei + 1} of {meta.edits.length}
+
{#each diffLines as line, li (li)}
{line.oldLine ?? ''} + {prefixFor(line.kind)} + {line.newLine ?? ''} + {line.text || ' '}
{/each} @@ -62,9 +69,11 @@
{/each} +
{#if meta.resultMessage} {meta.resultMessage}{meta.editsApplied != null ? RESULT_STAT_SEPARATOR : ''}{/if} + {#if meta.editsApplied != null} {meta.editsApplied} {meta.editsApplied === 1 ? 'edit' : 'edits'} applied diff --git a/tools/ui/src/lib/components/app/chat/ChatMessages/ChatMessage/ChatMessageToolCall/ChatMessageToolCallBlockExecShellCommand.svelte b/tools/ui/src/lib/components/app/chat/ChatMessages/ChatMessage/ChatMessageToolCall/ChatMessageToolCallBlockExecShellCommand.svelte index d7103bf97f27..1fb4369834c0 100644 --- a/tools/ui/src/lib/components/app/chat/ChatMessages/ChatMessage/ChatMessageToolCall/ChatMessageToolCallBlockExecShellCommand.svelte +++ b/tools/ui/src/lib/components/app/chat/ChatMessages/ChatMessage/ChatMessageToolCall/ChatMessageToolCallBlockExecShellCommand.svelte @@ -176,6 +176,7 @@ {#snippet execShellTitle()} {#if cwd} {wdDisplay} + $ {/if} @@ -209,6 +210,7 @@ {:else if execShellError}
+ {execShellError}
{:else if section.toolResult} @@ -220,6 +222,7 @@ > {#each outputLines as line, i (i)}
{line.text}
+ {#if line.media?.type === AttachmentType.IMAGE} {#if execShellExitStatus.timedOut} + timed out + · + exit {execShellExitStatus.code} {:else if execShellExitStatus.code === 0} + exit 0 {:else} + exit {execShellExitStatus.code} {/if}
diff --git a/tools/ui/src/lib/components/app/chat/ChatMessages/ChatMessage/ChatMessageToolCall/ChatMessageToolCallBlockFileGlobSearch.svelte b/tools/ui/src/lib/components/app/chat/ChatMessages/ChatMessage/ChatMessageToolCall/ChatMessageToolCallBlockFileGlobSearch.svelte index 7a9fbe97b6ed..305d70e629ce 100644 --- a/tools/ui/src/lib/components/app/chat/ChatMessages/ChatMessage/ChatMessageToolCall/ChatMessageToolCallBlockFileGlobSearch.svelte +++ b/tools/ui/src/lib/components/app/chat/ChatMessages/ChatMessage/ChatMessageToolCall/ChatMessageToolCallBlockFileGlobSearch.svelte @@ -25,10 +25,13 @@ {fileGlobMeta.include === '**' ? 'List files' : 'Search files'}  + {#if fileGlobMeta.include !== '**'} {fileGlobMeta.include} {/if} +  in  + {abbreviateHome(fileGlobMeta.path, home)} @@ -45,6 +48,7 @@ class="flex items-start gap-2 rounded bg-red-500/10 p-2 text-xs text-red-600 italic dark:text-red-400" > + {meta.errorMessage}
{:else if meta && meta.matches.length > 0} @@ -53,11 +57,13 @@
{match}
{/each}
+
Total matches: {meta.totalMatches ?? meta.matches.length}
{:else}
No matches
+
Total matches: {meta?.totalMatches ?? 0}
diff --git a/tools/ui/src/lib/components/app/chat/ChatMessages/ChatMessage/ChatMessageToolCall/ChatMessageToolCallBlockGetDatetime.svelte b/tools/ui/src/lib/components/app/chat/ChatMessages/ChatMessage/ChatMessageToolCall/ChatMessageToolCallBlockGetDatetime.svelte index 44b3ec645159..60ab14160f19 100644 --- a/tools/ui/src/lib/components/app/chat/ChatMessages/ChatMessage/ChatMessageToolCall/ChatMessageToolCallBlockGetDatetime.svelte +++ b/tools/ui/src/lib/components/app/chat/ChatMessages/ChatMessage/ChatMessageToolCall/ChatMessageToolCallBlockGetDatetime.svelte @@ -44,15 +44,19 @@
+ {#if showSpinner} Current time + {:else if dateMeta.errorMessage} Current time  + - {dateMeta.errorMessage} {:else if dateMeta.dateString} Current time is  + {dateMeta.dateString} {:else} Current time diff --git a/tools/ui/src/lib/components/app/chat/ChatMessages/ChatMessage/ChatMessageToolCall/ChatMessageToolCallBlockGetInfo.svelte b/tools/ui/src/lib/components/app/chat/ChatMessages/ChatMessage/ChatMessageToolCall/ChatMessageToolCallBlockGetInfo.svelte index 6b39e7d92f73..bd46b76dc96a 100644 --- a/tools/ui/src/lib/components/app/chat/ChatMessages/ChatMessage/ChatMessageToolCall/ChatMessageToolCallBlockGetInfo.svelte +++ b/tools/ui/src/lib/components/app/chat/ChatMessages/ChatMessage/ChatMessageToolCall/ChatMessageToolCallBlockGetInfo.svelte @@ -52,18 +52,23 @@
+ {#if showSpinner} Runtime info + {:else if infoMeta.errorMessage} Runtime info  + - {infoMeta.errorMessage} {:else if infoMeta.os || infoMeta.cwd} Runtime info  + {#if infoMeta.os} {infoMeta.os} {/if} + {#if infoMeta.cwd} {cwdDisplay} {/if} diff --git a/tools/ui/src/lib/components/app/chat/ChatMessages/ChatMessage/ChatMessageToolCall/ChatMessageToolCallBlockGrepSearch.svelte b/tools/ui/src/lib/components/app/chat/ChatMessages/ChatMessage/ChatMessageToolCall/ChatMessageToolCallBlockGrepSearch.svelte index a56a8da9d6e4..22778f009569 100644 --- a/tools/ui/src/lib/components/app/chat/ChatMessages/ChatMessage/ChatMessageToolCall/ChatMessageToolCallBlockGrepSearch.svelte +++ b/tools/ui/src/lib/components/app/chat/ChatMessages/ChatMessage/ChatMessageToolCall/ChatMessageToolCallBlockGrepSearch.svelte @@ -23,8 +23,11 @@ {#snippet titleSnippet()} {#if grepMeta} Search for  + {grepMeta.pattern} +  in  + {abbreviateHome(grepMeta.path, home)} {/if} {/snippet} @@ -39,6 +42,7 @@ class="flex items-start gap-2 rounded bg-red-500/10 p-2 text-xs text-red-600 italic dark:text-red-400" > + {meta.errorMessage}
{:else if meta && meta.matches.length > 0} @@ -46,22 +50,28 @@ {#each meta.matches as match, mi (mi)}
{match.file} + {#if meta.showLineNumbers && match.line != null} :{match.line} {/if} + : + {match.content}
{/each}
+
Total matches: {meta.totalMatches ?? meta.matches.length} + {#if meta.showLineNumbers}  (with line numbers) {/if}
{:else}
No matches
+
Total matches: {meta?.totalMatches ?? 0}
diff --git a/tools/ui/src/lib/components/app/chat/ChatMessages/ChatMessage/ChatMessageToolCall/ChatMessageToolCallBlockReadFile.svelte b/tools/ui/src/lib/components/app/chat/ChatMessages/ChatMessage/ChatMessageToolCall/ChatMessageToolCallBlockReadFile.svelte index ad29e31d8fa1..3f6ac52f1200 100644 --- a/tools/ui/src/lib/components/app/chat/ChatMessages/ChatMessage/ChatMessageToolCall/ChatMessageToolCallBlockReadFile.svelte +++ b/tools/ui/src/lib/components/app/chat/ChatMessages/ChatMessage/ChatMessageToolCall/ChatMessageToolCallBlockReadFile.svelte @@ -20,7 +20,9 @@ {#snippet titleSnippet()} Read file + {readFileMeta?.fileName} + {#if readFileMeta?.lineRange}  (lines {readFileMeta.lineRange.start}-{readFileMeta.lineRange.end}) {#snippet titleSnippet()} Read media + {readMediaMeta?.fileName} {/snippet} @@ -81,6 +82,7 @@ {#if readMediaMeta?.sizeBytes} Size: {readMediaMeta.sizeBytes} bytes {/if} + {#if readMediaMeta?.mimeType} MIME: {readMediaMeta.mimeType} {/if} diff --git a/tools/ui/src/lib/components/app/chat/ChatMessages/ChatMessage/ChatMessageToolCall/ChatMessageToolCallBlockRunJavascript.svelte b/tools/ui/src/lib/components/app/chat/ChatMessages/ChatMessage/ChatMessageToolCall/ChatMessageToolCallBlockRunJavascript.svelte index 5c60457dbef6..f35689191c9b 100644 --- a/tools/ui/src/lib/components/app/chat/ChatMessages/ChatMessage/ChatMessageToolCall/ChatMessageToolCallBlockRunJavascript.svelte +++ b/tools/ui/src/lib/components/app/chat/ChatMessages/ChatMessage/ChatMessageToolCall/ChatMessageToolCallBlockRunJavascript.svelte @@ -30,8 +30,10 @@ class="flex items-start gap-2 rounded bg-red-500/10 p-2 text-xs text-red-600 italic dark:text-red-400" > + {meta.errorMessage}
+
+
+ Console + {#if meta.timeoutMs != null} · timeout {meta.timeoutMs} ms {/if}
+ {#if section.toolResult}
{/if} + {result.title} + {#if showHoverCard} {@const publishDate = formatPublishDate(result.published)} {@const host = hostFor(safeUrl)} @@ -122,19 +124,23 @@ class="line-clamp-3 text-sm font-medium leading-snug hover:underline" >{result.title} + {#if publishDate || result.author}
{#if publishDate} {publishDate} {/if} + {#if publishDate && result.author} · {/if} + {#if result.author} {result.author} {/if}
{/if} + {#if result.highlights}

{/if} + {#if host}

{host}
{/if} @@ -162,6 +169,7 @@ {:else if showSpinner}
+ Searching...
{:else} diff --git a/tools/ui/src/lib/components/app/chat/ChatMessages/ChatMessage/ChatMessageToolCall/ChatMessageToolCallBlockWriteFile.svelte b/tools/ui/src/lib/components/app/chat/ChatMessages/ChatMessage/ChatMessageToolCall/ChatMessageToolCallBlockWriteFile.svelte index 2551fb0b21c0..ffd0de63b55d 100644 --- a/tools/ui/src/lib/components/app/chat/ChatMessages/ChatMessage/ChatMessageToolCall/ChatMessageToolCallBlockWriteFile.svelte +++ b/tools/ui/src/lib/components/app/chat/ChatMessages/ChatMessage/ChatMessageToolCall/ChatMessageToolCallBlockWriteFile.svelte @@ -24,9 +24,11 @@ {#snippet titleSnippet()} Write file + {abbreviateHome(writeFileMeta?.filePath ?? '', home)} + {#if writeFileMeta?.errorMessage} (failed) {/if} @@ -38,6 +40,7 @@ class="flex items-start gap-2 rounded bg-red-500/10 p-2 text-xs text-red-600 italic dark:text-red-400" > + {meta.errorMessage}
{:else if meta} @@ -47,9 +50,11 @@ maxHeight={MAX_HEIGHT_CODE_BLOCK} streaming={ctx.isCodeStreaming} /> +
{#if meta.resultMessage} {meta.resultMessage}{meta.bytesWritten != null ? RESULT_STAT_SEPARATOR : ''}{/if} + {#if meta.bytesWritten != null} {meta.bytesWritten} bytes diff --git a/tools/ui/src/lib/components/app/chat/ChatMessages/ChatMessage/ChatMessageUser/ChatMessageUserPending.svelte b/tools/ui/src/lib/components/app/chat/ChatMessages/ChatMessage/ChatMessageUser/ChatMessageUserPending.svelte index a072f2e84dd2..d03a9adbfb36 100644 --- a/tools/ui/src/lib/components/app/chat/ChatMessages/ChatMessage/ChatMessageUser/ChatMessageUserPending.svelte +++ b/tools/ui/src/lib/components/app/chat/ChatMessages/ChatMessage/ChatMessageUser/ChatMessageUserPending.svelte @@ -51,7 +51,9 @@ class="pointer-events-auto inset-0 flex items-center gap-1 opacity-0 transition-all duration-150 group-hover:opacity-100" > + +
diff --git a/tools/ui/src/lib/components/app/chat/ChatMessages/ChatMessageActions/ChatMessageActionCard/ChatMessageActionCard.svelte b/tools/ui/src/lib/components/app/chat/ChatMessages/ChatMessageActions/ChatMessageActionCard/ChatMessageActionCard.svelte index 0ee66829abae..e7e168233645 100644 --- a/tools/ui/src/lib/components/app/chat/ChatMessages/ChatMessageActions/ChatMessageActionCard/ChatMessageActionCard.svelte +++ b/tools/ui/src/lib/components/app/chat/ChatMessages/ChatMessageActions/ChatMessageActionCard/ChatMessageActionCard.svelte @@ -14,10 +14,12 @@
+ {@render message()}
+
{@render actions()}
diff --git a/tools/ui/src/lib/components/app/chat/ChatMessages/ChatMessageActions/ChatMessageActionCard/ChatMessageActionCardPermissionRequest.svelte b/tools/ui/src/lib/components/app/chat/ChatMessages/ChatMessageActions/ChatMessageActionCard/ChatMessageActionCardPermissionRequest.svelte index e8af9446400b..24d71bf71b95 100644 --- a/tools/ui/src/lib/components/app/chat/ChatMessages/ChatMessageActions/ChatMessageActionCard/ChatMessageActionCardPermissionRequest.svelte +++ b/tools/ui/src/lib/components/app/chat/ChatMessages/ChatMessageActions/ChatMessageActionCard/ChatMessageActionCardPermissionRequest.svelte @@ -54,6 +54,7 @@ Always allow
{toolName}
tool + {#if serverLabel} onDecision(ToolPermissionDecision.ALWAYS_SERVER)}> Always allow all tools from {serverLabel} diff --git a/tools/ui/src/lib/components/app/chat/ChatMessages/ChatMessageActions/ChatMessageActionIcons/ChatMessageActionIcons.svelte b/tools/ui/src/lib/components/app/chat/ChatMessages/ChatMessageActions/ChatMessageActionIcons/ChatMessageActionIcons.svelte index 895f391255bb..add615e9dc9e 100644 --- a/tools/ui/src/lib/components/app/chat/ChatMessages/ChatMessageActions/ChatMessageActionIcons/ChatMessageActionIcons.svelte +++ b/tools/ui/src/lib/components/app/chat/ChatMessages/ChatMessageActions/ChatMessageActionIcons/ChatMessageActionIcons.svelte @@ -100,6 +100,7 @@ {#if showRawOutputSwitch}
Show raw output + onRawOutputToggle?.(checked)} diff --git a/tools/ui/src/lib/components/app/chat/ChatMessages/ChatMessageStatistics/ChatMessageStatisticsBadge.svelte b/tools/ui/src/lib/components/app/chat/ChatMessages/ChatMessageStatistics/ChatMessageStatisticsBadge.svelte index 0aa4cda877cf..3bde97581583 100644 --- a/tools/ui/src/lib/components/app/chat/ChatMessages/ChatMessageStatistics/ChatMessageStatisticsBadge.svelte +++ b/tools/ui/src/lib/components/app/chat/ChatMessages/ChatMessageStatistics/ChatMessageStatisticsBadge.svelte @@ -32,6 +32,7 @@ {/snippet} +

{tooltipLabel}

diff --git a/tools/ui/src/lib/components/app/chat/ChatScreen/ChatScreenStreamResumeStatus.svelte b/tools/ui/src/lib/components/app/chat/ChatScreen/ChatScreenStreamResumeStatus.svelte index a8e0dcc196d5..bb6f78f83bf8 100644 --- a/tools/ui/src/lib/components/app/chat/ChatScreen/ChatScreenStreamResumeStatus.svelte +++ b/tools/ui/src/lib/components/app/chat/ChatScreen/ChatScreenStreamResumeStatus.svelte @@ -13,6 +13,7 @@ aria-live="polite" > + Reconnecting to the stream...
{/if} diff --git a/tools/ui/src/lib/components/app/chat/ChatTabs/ChatTabs.svelte b/tools/ui/src/lib/components/app/chat/ChatTabs/ChatTabs.svelte index 763241c56dda..b2cd93f96b38 100644 --- a/tools/ui/src/lib/components/app/chat/ChatTabs/ChatTabs.svelte +++ b/tools/ui/src/lib/components/app/chat/ChatTabs/ChatTabs.svelte @@ -115,6 +115,7 @@ ? 'opacity-100' : 'opacity-0'}" >
+
mermaid +
+
Generating diagram...
@@ -909,6 +911,7 @@
svg +
+ {#if liveSvgHtml}
@@ -933,6 +937,7 @@
{incompleteCodeBlock.language || 'text'} + + {Math.round(scale * 100)}% + +
+
diff --git a/tools/ui/src/lib/components/app/dialogs/DialogModelInformation.svelte b/tools/ui/src/lib/components/app/dialogs/DialogModelInformation.svelte index fb749887024b..1054423dc8ae 100644 --- a/tools/ui/src/lib/components/app/dialogs/DialogModelInformation.svelte +++ b/tools/ui/src/lib/components/app/dialogs/DialogModelInformation.svelte @@ -123,6 +123,7 @@ + @@ -213,6 +214,7 @@ {#if modelMeta?.vocab_type} Vocabulary Type + {modelMeta.vocab_type} {/if} diff --git a/tools/ui/src/lib/components/app/dialogs/DialogModelNotAvailable.svelte b/tools/ui/src/lib/components/app/dialogs/DialogModelNotAvailable.svelte index 1f0ac2fca478..8b3e42a4ee75 100644 --- a/tools/ui/src/lib/components/app/dialogs/DialogModelNotAvailable.svelte +++ b/tools/ui/src/lib/components/app/dialogs/DialogModelNotAvailable.svelte @@ -53,6 +53,7 @@ {#if availableModels.length > 0}

Select an available model:

+
{#each availableModels as model (model)}
+

{favicon.name}

diff --git a/tools/ui/src/lib/components/app/mcp/McpServerCard/McpServerCard.svelte b/tools/ui/src/lib/components/app/mcp/McpServerCard/McpServerCard.svelte index 0ba56caf28bd..beee8b04b0c4 100644 --- a/tools/ui/src/lib/components/app/mcp/McpServerCard/McpServerCard.svelte +++ b/tools/ui/src/lib/components/app/mcp/McpServerCard/McpServerCard.svelte @@ -145,11 +145,15 @@
+
+
+ +
@@ -157,6 +161,7 @@
+
diff --git a/tools/ui/src/lib/components/app/mcp/McpServerCardSkeleton.svelte b/tools/ui/src/lib/components/app/mcp/McpServerCardSkeleton.svelte index 39a1372806a5..52776ff6067f 100644 --- a/tools/ui/src/lib/components/app/mcp/McpServerCardSkeleton.svelte +++ b/tools/ui/src/lib/components/app/mcp/McpServerCardSkeleton.svelte @@ -7,20 +7,26 @@
+ +
+
+ +
+
@@ -28,7 +34,9 @@
+ +
diff --git a/tools/ui/src/lib/components/app/models/ModelsSelectorList.svelte b/tools/ui/src/lib/components/app/models/ModelsSelectorList.svelte index 38f4db8a727e..e59744bf5ebe 100644 --- a/tools/ui/src/lib/components/app/models/ModelsSelectorList.svelte +++ b/tools/ui/src/lib/components/app/models/ModelsSelectorList.svelte @@ -47,6 +47,7 @@ {#if groups.loaded.length > 0}

Loaded models

+ {#each groups.loaded as item (`loaded-${item.option.id}`)} {@render render(item, false)} {/each} @@ -54,6 +55,7 @@ {#if groups.favorites.length > 0}

Favorite models

+ {#each groups.favorites as item (`fav-${item.option.id}`)} {@render render(item, true)} {/each} @@ -61,10 +63,12 @@ {#if groups.available.length > 0}

Available models

+ {#each groups.available as group (group.orgName)} {#if group.orgName}

{group.orgName}

{/if} + {#each group.items as item (item.option.id)} {@render render(item, true)} {/each} diff --git a/tools/ui/src/lib/components/app/models/ModelsSelectorSheet.svelte b/tools/ui/src/lib/components/app/models/ModelsSelectorSheet.svelte index 0d10dd106ccc..e1e6ee620f45 100644 --- a/tools/ui/src/lib/components/app/models/ModelsSelectorSheet.svelte +++ b/tools/ui/src/lib/components/app/models/ModelsSelectorSheet.svelte @@ -149,8 +149,10 @@ {selectedOption?.name || currentModel} + (not available) +
{/if} diff --git a/tools/ui/src/lib/components/app/navigation/DropdownMenuActions.svelte b/tools/ui/src/lib/components/app/navigation/DropdownMenuActions.svelte index 1bf41b69a7c3..7f614d5b67c9 100644 --- a/tools/ui/src/lib/components/app/navigation/DropdownMenuActions.svelte +++ b/tools/ui/src/lib/components/app/navigation/DropdownMenuActions.svelte @@ -44,12 +44,14 @@ onclick={(e) => e.stopPropagation()} > {@render iconComponent(triggerIcon, 'h-3 w-3')} + {#if triggerTooltip} {triggerTooltip} {/if} {/snippet} + {#if triggerTooltip}

{triggerTooltip}

diff --git a/tools/ui/src/lib/components/app/server/ServerErrorSplash.svelte b/tools/ui/src/lib/components/app/server/ServerErrorSplash.svelte index fbdbf19f29f6..d721557194e2 100644 --- a/tools/ui/src/lib/components/app/server/ServerErrorSplash.svelte +++ b/tools/ui/src/lib/components/app/server/ServerErrorSplash.svelte @@ -170,6 +170,7 @@ : ''}" disabled={apiKeyState === 'validating'} /> + {#if apiKeyState === 'validating'}
@@ -190,17 +191,20 @@
{/if}
+ {#if apiKeyError}

{apiKeyError}

{/if} + {#if apiKeyState === 'success'}

✓ API key validated successfully! Connecting...

{/if}
+
+
  • Check that the server is accessible at the correct URL
  • diff --git a/tools/ui/src/lib/components/app/settings/SettingsChat/SettingsChat.svelte b/tools/ui/src/lib/components/app/settings/SettingsChat/SettingsChat.svelte index 97ff30ba7a47..a6bcb3b7b34c 100644 --- a/tools/ui/src/lib/components/app/settings/SettingsChat/SettingsChat.svelte +++ b/tools/ui/src/lib/components/app/settings/SettingsChat/SettingsChat.svelte @@ -145,6 +145,7 @@
    +

    {currentSection.title}

    diff --git a/tools/ui/src/lib/components/app/settings/SettingsChat/SettingsChatFields.svelte b/tools/ui/src/lib/components/app/settings/SettingsChat/SettingsChatFields.svelte index d5d93e11d746..9888c3cf8cbb 100644 --- a/tools/ui/src/lib/components/app/settings/SettingsChat/SettingsChatFields.svelte +++ b/tools/ui/src/lib/components/app/settings/SettingsChat/SettingsChatFields.svelte @@ -73,6 +73,7 @@ {/if} + {#if isCustomRealTime} {/if} @@ -97,6 +98,7 @@ : (field.placeholder ?? '')} class="w-full {isCustomRealTime ? 'pr-8' : ''}" /> + {#if isCustomRealTime}
    + {#if field.help || SETTING_CONFIG_INFO[field.key]}

    {@html field.help || SETTING_CONFIG_INFO[field.key]} @@ -179,6 +182,7 @@ {/if} + {#if isCustomRealTime} {/if} @@ -206,6 +210,7 @@ {selectedOption?.label || `Select ${field.label.toLowerCase()}`}

+ {#if isCustomRealTime}
+ {#if field.options} {#each field.options as option (option.value)} @@ -237,6 +243,7 @@ {/if} + {#if field.help || SETTING_CONFIG_INFO[field.key]}

{field.help || SETTING_CONFIG_INFO[field.key]} @@ -269,6 +276,7 @@ {@const itemId = `${field.key}-${opt.value}`}

+
+
+ {}} onKeyDown={() => {}} /> + {}} onKeyDown={() => {}} /> + {}} onKeyDown={() => {}} /> +
+ {}} />
diff --git a/tools/ui/tests/stories/a11y/ScrollCarousel.a11y.stories.svelte b/tools/ui/tests/stories/a11y/ScrollCarousel.a11y.stories.svelte index b9bf5afbc640..72e13766e5d3 100644 --- a/tools/ui/tests/stories/a11y/ScrollCarousel.a11y.stories.svelte +++ b/tools/ui/tests/stories/a11y/ScrollCarousel.a11y.stories.svelte @@ -34,10 +34,13 @@ >
+
+
+
@@ -61,6 +64,7 @@ >
+ {#each [...Array(20).keys()] as i (i)}
{i}
From 722847b12d9c056af7452a19af4a705f2f8e7aec Mon Sep 17 00:00:00 2001 From: Aleksander Grygier Date: Tue, 25 Aug 2026 13:21:54 +0200 Subject: [PATCH 2/2] chore: Formatting and linting rules --- tools/ui/eslint.config.js | 44 +++++- .../components/app/actions/ActionIcon.svelte | 10 +- .../actions/ActionIconCopyToClipboard.svelte | 4 +- .../ChatAttachmentsList.svelte | 4 +- .../ChatAttachmentsListItem.svelte | 30 ++-- .../ChatAttachmentsListItemMcpPrompt.svelte | 2 +- ...hatAttachmentsListItemThumbnailFile.svelte | 2 +- ...atAttachmentsListItemThumbnailImage.svelte | 2 +- .../ChatAttachmentsPreview.svelte | 20 +-- .../ChatAttachmentsPreviewCurrentItem.svelte | 4 +- ...tAttachmentsPreviewCurrentItemAudio.svelte | 2 +- ...tAttachmentsPreviewCurrentItemImage.svelte | 2 +- ...hatAttachmentsPreviewCurrentItemPdf.svelte | 14 +- ...tAttachmentsPreviewCurrentItemVideo.svelte | 2 +- .../ChatAttachmentsPreviewNavButtons.svelte | 12 +- ...hatAttachmentsPreviewThumbnailStrip.svelte | 4 +- .../app/chat/ChatForm/ChatForm.svelte | 56 ++++---- .../ChatFormActionAddButton.svelte | 2 +- .../ChatFormActionAddMcpServersSubmenu.svelte | 10 +- .../ChatFormActionAddSheet.svelte | 36 ++--- .../ChatFormActionAddToolsSubmenu.svelte | 10 +- .../ChatFormActionModels.svelte | 4 +- .../ChatFormActionSubmit.svelte | 4 +- .../ChatFormActions/ChatFormActions.svelte | 18 +-- .../ChatFormContextGauge.svelte | 8 +- .../ContextGaugeDetails.svelte | 4 +- .../ContextGaugeDial.svelte | 8 +- .../ContextGaugeLoadModel.svelte | 2 +- .../ContextGaugePopup.svelte | 18 +-- .../ChatFormCurrentWorkingDirectory.svelte | 40 +++--- ...ChatFormCurrentWorkingDirectoryChip.svelte | 10 +- ...mCurrentWorkingDirectoryResultsList.svelte | 4 +- .../ChatFormInput/ChatFormInput.svelte | 4 +- .../ChatFormInput/ChatFormInputBasic.svelte | 4 +- .../ChatFormInputFileInputInvisible.svelte | 4 +- .../ChatFormInput/ChatFormInputRich.svelte | 18 +-- .../ChatForm/ChatFormMcpResourcesList.svelte | 2 +- .../ChatFormPickerItemHeader.svelte | 2 +- .../ChatFormPicker/ChatFormPickerList.svelte | 8 +- .../ChatFormPickerListItem.svelte | 4 +- .../ChatFormPickerPopover.svelte | 10 +- .../ChatFormPickerCommand.svelte | 14 +- .../ChatFormPickerMcpPrompts.svelte | 34 ++--- .../ChatFormPromptPickerArgumentForm.svelte | 16 +-- .../ChatFormPromptPickerArgumentInput.svelte | 18 +-- .../ChatFormPickerMention.svelte | 30 ++-- .../ChatFormPickers/ChatFormPickers.svelte | 14 +- .../ChatMessage/ChatMessage.svelte | 8 +- .../ChatMessageAssistant.svelte | 26 ++-- .../ChatMessageAssistantProcessingInfo.svelte | 2 +- .../ChatMessageAssistantStatistics.svelte | 24 ++-- .../ChatMessageMcpPrompt.svelte | 2 +- .../ChatMessageMcpPromptContent.svelte | 2 +- .../ChatMessage/ChatMessageSynthetic.svelte | 2 +- .../ChatMessageSystem.svelte | 8 +- .../ChatMessageToolCallBlock.svelte | 30 ++-- .../ChatMessageToolCallBlockDefault.svelte | 8 +- .../ChatMessageToolCallBlockEditFile.svelte | 4 +- ...essageToolCallBlockExecShellCommand.svelte | 14 +- ...tMessageToolCallBlockFileGlobSearch.svelte | 2 +- .../ChatMessageToolCallBlockGrepSearch.svelte | 2 +- .../ChatMessageToolCallBlockReadFile.svelte | 2 +- .../ChatMessageToolCallBlockReadMedia.svelte | 6 +- ...atMessageToolCallBlockRunJavascript.svelte | 2 +- ...atMessageToolCallBlockSearchResults.svelte | 19 ++- .../ChatMessageToolCallBlockWriteFile.svelte | 2 +- .../ChatMessageToolCall/ToolCallBlock.svelte | 8 +- .../ChatMessageUser/ChatMessageUser.svelte | 8 +- .../ChatMessageUserBubble.svelte | 2 +- .../ChatMessageUserPending.svelte | 10 +- ...hatMessageActionCardContinueRequest.svelte | 6 +- ...tMessageActionCardPermissionRequest.svelte | 8 +- .../ChatMessageActionIcons.svelte | 44 +++--- ...MessageActionIconsBranchingControls.svelte | 12 +- .../ChatMessageAgenticContent.svelte | 32 ++--- .../ChatMessages/ChatMessageEditForm.svelte | 34 ++--- .../ChatMessageReasoningBlock.svelte | 12 +- .../ChatMessageStatistics.svelte | 28 ++-- .../app/chat/ChatMessages/ChatMessages.svelte | 14 +- .../app/chat/ChatScreen/ChatScreen.svelte | 16 +-- .../ChatScreenActionScrollDown.svelte | 8 +- .../ChatScreenDialogsAndAlerts.svelte | 12 +- .../app/chat/ChatScreen/ChatScreenForm.svelte | 8 +- .../ChatScreen/ChatScreenServerError.svelte | 4 +- .../ChatScreenStreamResumeStatus.svelte | 2 +- .../app/chat/ChatTabs/ChatTabs.svelte | 8 +- .../app/chat/ChatTabs/ChatTabsItem.svelte | 12 +- .../ChatTabs/ChatTabsNewChatButton.svelte | 2 +- .../content/CollapsibleContentBlock.svelte | 6 +- .../content/CollapsibleTerminalBlock.svelte | 6 +- .../MarkdownContent/MarkdownContent.svelte | 16 +-- .../app/content/MermaidPreview.svelte | 14 +- .../app/content/MermaidPreviewControls.svelte | 8 +- .../app/content/SyntaxHighlightedCode.svelte | 2 +- .../DialogChatAttachmentsPreview.svelte | 8 +- .../app/dialogs/DialogChatError.svelte | 2 +- .../app/dialogs/DialogCodePreview.svelte | 8 +- .../app/dialogs/DialogConfirmation.svelte | 4 +- .../dialogs/DialogConversationRename.svelte | 12 +- .../DialogConversationSelection.svelte | 2 +- .../app/dialogs/DialogEmptyFileAlert.svelte | 2 +- .../app/dialogs/DialogExportSettings.svelte | 8 +- .../app/dialogs/DialogFileUploadError.svelte | 2 +- .../dialogs/DialogMcpResourcePreview.svelte | 16 +-- .../dialogs/DialogMcpResourcesBrowser.svelte | 24 ++-- .../app/dialogs/DialogMcpServerAddNew.svelte | 28 ++-- .../app/dialogs/DialogModelInformation.svelte | 10 +- .../dialogs/DialogModelNotAvailable.svelte | 4 +- .../app/forms/InputWithSuggestions.svelte | 18 +-- .../components/app/forms/KeyValuePairs.svelte | 24 ++-- .../components/app/forms/SearchInput.svelte | 10 +- .../app/mcp/McpActiveServersAvatars.svelte | 2 +- .../app/mcp/McpCapabilitiesBadges.svelte | 12 +- .../src/lib/components/app/mcp/McpLogo.svelte | 34 ++--- .../app/mcp/McpResourcePreview.svelte | 14 +- .../app/mcp/McpResourceTemplateForm.svelte | 20 +-- .../McpResourcesBrowser.svelte | 16 +-- .../McpResourcesBrowserHeader.svelte | 8 +- .../McpResourcesBrowserServerItem.svelte | 6 +- .../mcp/McpServerCard/McpServerCard.svelte | 18 +-- .../McpServerCard/McpServerCardActions.svelte | 16 +-- .../McpServerCard/McpServerCardCompact.svelte | 4 +- .../McpServerCardEditForm.svelte | 16 +-- .../McpServerCard/McpServerCardHeader.svelte | 4 +- .../components/app/mcp/McpServerForm.svelte | 44 +++--- .../app/mcp/McpServerIdentity.svelte | 14 +- .../app/misc/CodeBlockActions.svelte | 8 +- .../app/misc/ConversationSelection.svelte | 8 +- .../components/app/misc/ScrollCarousel.svelte | 8 +- .../components/app/models/ModelBadge.svelte | 2 +- .../app/models/ModelsSelectorDropdown.svelte | 50 +++---- .../app/models/ModelsSelectorList.svelte | 12 +- .../app/models/ModelsSelectorOption.svelte | 58 ++++---- .../app/models/ModelsSelectorSheet.svelte | 34 ++--- .../app/navigation/DropdownMenuActions.svelte | 4 +- .../navigation/DropdownMenuSearchable.svelte | 2 +- .../SidebarNavigation.svelte | 90 ++++++------ .../SidebarNavigationActions.svelte | 14 +- .../SidebarNavigationConversationItem.svelte | 24 ++-- .../SidebarNavigationConversationList.svelte | 60 ++++---- .../SidebarNavigationSearch.svelte | 2 +- .../SidebarNavigationSearchResults.svelte | 12 +- .../SidebarNavigationSelectionBar.svelte | 62 ++++----- .../app/server/ServerErrorSplash.svelte | 36 ++--- .../app/server/ServerLoadingSplash.svelte | 2 +- .../components/app/server/ServerStatus.svelte | 6 +- .../settings/SettingsChat/SettingsChat.svelte | 14 +- .../SettingsChat/SettingsChatFields.svelte | 50 +++---- .../SettingsChatImportExportTab.svelte | 44 +++--- ...ettingsChatParameterSourceIndicator.svelte | 2 +- .../SettingsChat/SettingsChatToolsTab.svelte | 14 +- .../settings/SettingsChatMobileHeader.svelte | 2 +- .../app/settings/SettingsFooter.svelte | 2 +- .../app/settings/SettingsMcpServers.svelte | 10 +- .../src/lib/components/pwa/PwaMetaTags.svelte | 10 +- .../lib/components/pwa/PwaRefreshAlert.svelte | 2 +- .../alert-dialog/alert-dialog-action.svelte | 2 +- .../alert-dialog/alert-dialog-cancel.svelte | 2 +- .../alert-dialog/alert-dialog-content.svelte | 2 +- .../alert-dialog-description.svelte | 2 +- .../alert-dialog/alert-dialog-footer.svelte | 2 +- .../alert-dialog/alert-dialog-header.svelte | 2 +- .../alert-dialog/alert-dialog-overlay.svelte | 2 +- .../ui/alert-dialog/alert-dialog-title.svelte | 2 +- .../ui/alert/alert-description.svelte | 2 +- .../components/ui/alert/alert-title.svelte | 2 +- .../src/lib/components/ui/alert/alert.svelte | 2 +- .../src/lib/components/ui/badge/badge.svelte | 2 +- .../lib/components/ui/button/button.svelte | 8 +- .../lib/components/ui/card/card-action.svelte | 2 +- .../components/ui/card/card-content.svelte | 2 +- .../ui/card/card-description.svelte | 2 +- .../lib/components/ui/card/card-footer.svelte | 2 +- .../lib/components/ui/card/card-header.svelte | 2 +- .../lib/components/ui/card/card-title.svelte | 2 +- .../ui/src/lib/components/ui/card/card.svelte | 2 +- .../components/ui/checkbox/checkbox.svelte | 8 +- .../ui/collapsible/collapsible.svelte | 2 +- .../ui/dialog/dialog-content.svelte | 2 +- .../ui/dialog/dialog-description.svelte | 2 +- .../components/ui/dialog/dialog-footer.svelte | 2 +- .../components/ui/dialog/dialog-header.svelte | 2 +- .../ui/dialog/dialog-overlay.svelte | 2 +- .../components/ui/dialog/dialog-title.svelte | 2 +- .../dropdown-menu-checkbox-item.svelte | 4 +- .../dropdown-menu-content.svelte | 4 +- .../dropdown-menu-group-heading.svelte | 4 +- .../dropdown-menu/dropdown-menu-item.svelte | 6 +- .../dropdown-menu/dropdown-menu-label.svelte | 4 +- .../dropdown-menu-radio-item.svelte | 2 +- .../dropdown-menu-separator.svelte | 2 +- .../dropdown-menu-shortcut.svelte | 2 +- .../dropdown-menu-sub-content.svelte | 2 +- .../dropdown-menu-sub-trigger.svelte | 4 +- .../components/ui/empty/empty-content.svelte | 2 +- .../ui/empty/empty-description.svelte | 2 +- .../components/ui/empty/empty-header.svelte | 2 +- .../components/ui/empty/empty-media.svelte | 2 +- .../components/ui/empty/empty-title.svelte | 2 +- .../src/lib/components/ui/empty/empty.svelte | 2 +- .../ui/hover-card/hover-card-content.svelte | 4 +- .../src/lib/components/ui/input/input.svelte | 10 +- .../src/lib/components/ui/label/label.svelte | 2 +- .../ui/popover/popover-content.svelte | 8 +- .../ui/popover/popover-trigger.svelte | 2 +- .../ui/radio-group/radio-group-item.svelte | 4 +- .../ui/radio-group/radio-group.svelte | 2 +- .../scroll-area/scroll-area-scrollbar.svelte | 6 +- .../ui/scroll-area/scroll-area.svelte | 8 +- .../ui/select/select-content.svelte | 4 +- .../ui/select/select-group-heading.svelte | 2 +- .../components/ui/select/select-item.svelte | 4 +- .../components/ui/select/select-label.svelte | 2 +- .../select/select-scroll-down-button.svelte | 2 +- .../ui/select/select-scroll-up-button.svelte | 2 +- .../ui/select/select-separator.svelte | 2 +- .../ui/select/select-trigger.svelte | 4 +- .../components/ui/separator/separator.svelte | 2 +- .../components/ui/sheet/sheet-content.svelte | 2 +- .../ui/sheet/sheet-description.svelte | 2 +- .../components/ui/sheet/sheet-footer.svelte | 2 +- .../components/ui/sheet/sheet-header.svelte | 2 +- .../components/ui/sheet/sheet-overlay.svelte | 2 +- .../components/ui/sheet/sheet-title.svelte | 2 +- .../components/ui/skeleton/skeleton.svelte | 2 +- .../lib/components/ui/switch/switch.svelte | 6 +- .../lib/components/ui/table/table-body.svelte | 2 +- .../components/ui/table/table-caption.svelte | 2 +- .../lib/components/ui/table/table-cell.svelte | 2 +- .../components/ui/table/table-footer.svelte | 2 +- .../lib/components/ui/table/table-head.svelte | 2 +- .../components/ui/table/table-header.svelte | 2 +- .../lib/components/ui/table/table-row.svelte | 2 +- .../src/lib/components/ui/table/table.svelte | 4 +- .../components/ui/textarea/textarea.svelte | 4 +- .../ui/tooltip/tooltip-content.svelte | 4 +- .../ui/tooltip/tooltip-trigger.svelte | 2 +- tools/ui/src/routes/(chat)/+page.svelte | 2 +- .../src/routes/(chat)/chat/[id]/+page.svelte | 2 +- tools/ui/src/routes/+error.svelte | 4 +- tools/ui/src/routes/+layout.svelte | 6 +- tools/ui/src/routes/search/+page.svelte | 12 +- tools/ui/src/routes/settings/+layout.svelte | 2 +- .../components/AgenticPerfWrapper.svelte | 4 +- .../components/McpServerFormWrapper.svelte | 8 +- .../components/PickerListScrollHarness.svelte | 8 +- .../tests/stories/ChatMessage.stories.svelte | 16 +-- .../stories/ChatScreenForm.stories.svelte | 8 +- .../stories/MarkdownContent.stories.svelte | 18 +-- .../stories/ModelsSelector.stories.svelte | 128 +++++++++--------- .../stories/PwaRefreshAlert.stories.svelte | 8 +- .../stories/SidebarNavigation.stories.svelte | 2 +- .../a11y/ActionIcon.a11y.stories.svelte | 4 +- .../ChatMessageStatistics.a11y.stories.svelte | 4 +- .../a11y/ChatScreenForm.a11y.stories.svelte | 6 +- .../a11y/ScrollCarousel.a11y.stories.svelte | 2 +- ...gationConversationItem.a11y.stories.svelte | 4 +- 257 files changed, 1327 insertions(+), 1288 deletions(-) diff --git a/tools/ui/eslint.config.js b/tools/ui/eslint.config.js index 9eba3435d262..9eab1734c3d9 100644 --- a/tools/ui/eslint.config.js +++ b/tools/ui/eslint.config.js @@ -264,9 +264,49 @@ export default ts.config( // grouping); Prettier normalizes comma spacing afterwards. 'simple-import-sort/imports': ['error', { groups: [['.*']] }], 'svelte/no-at-html-tags': 'off', - // This app uses hash-based routing (#/) where resolve() from $app/paths does not apply - 'svelte/no-navigation-without-resolve': 'off' + 'svelte/no-navigation-without-resolve': 'off', + + // Sort HTML attributes alphabetically in the markup. The Svelte directives + // (bind:/use:/animate:/style:/in:/out:/transition:/class:) sort first, + // alphabetically among themselves, then all remaining attributes sort + // alphabetically. The rule keeps spread attributes in place and does not cross + // them. `this` stays first on because Prettier forces it there + // - reordering it alphabetically would fight the formatter. + 'svelte/sort-attributes': [ + 'error', + { + order: [ + 'this', + { + match: [ + '/^bind:/u', + '/^use:/u', + '/^animate:/u', + '/^style:/u', + '/^in:/u', + '/^out:/u', + '/^transition:/u', + '/^class:/u' + ], + sort: 'alphabetical' + }, + { + match: [ + '!/^bind:/u', + '!/^use:/u', + '!/^animate:/u', + '!/^style:/u', + '!/^in:/u', + '!/^out:/u', + '!/^transition:/u', + '!/^class:/u' + ], + sort: 'alphabetical' + } + ] + } + ] } }, { diff --git a/tools/ui/src/lib/components/app/actions/ActionIcon.svelte b/tools/ui/src/lib/components/app/actions/ActionIcon.svelte index e29b5ad67dca..0ed22d932cc0 100644 --- a/tools/ui/src/lib/components/app/actions/ActionIcon.svelte +++ b/tools/ui/src/lib/components/app/actions/ActionIcon.svelte @@ -41,17 +41,17 @@ {#snippet button(props = {})}
diff --git a/tools/ui/src/lib/components/app/chat/ChatAttachments/ChatAttachmentsList/ChatAttachmentsListItem/ChatAttachmentsListItemThumbnailFile.svelte b/tools/ui/src/lib/components/app/chat/ChatAttachments/ChatAttachmentsList/ChatAttachmentsListItem/ChatAttachmentsListItemThumbnailFile.svelte index abdba0e2e043..409a3a0f4a35 100644 --- a/tools/ui/src/lib/components/app/chat/ChatAttachments/ChatAttachmentsList/ChatAttachmentsListItem/ChatAttachmentsListItemThumbnailFile.svelte +++ b/tools/ui/src/lib/components/app/chat/ChatAttachments/ChatAttachmentsList/ChatAttachmentsListItem/ChatAttachmentsListItemThumbnailFile.svelte @@ -101,7 +101,7 @@
- onRemove?.(id)} /> + onRemove?.(id)} stopPropagationOnClick tooltip="Remove" />
{/snippet} diff --git a/tools/ui/src/lib/components/app/chat/ChatAttachments/ChatAttachmentsList/ChatAttachmentsListItem/ChatAttachmentsListItemThumbnailImage.svelte b/tools/ui/src/lib/components/app/chat/ChatAttachments/ChatAttachmentsList/ChatAttachmentsListItem/ChatAttachmentsListItemThumbnailImage.svelte index a71e23a836be..34db43339232 100644 --- a/tools/ui/src/lib/components/app/chat/ChatAttachments/ChatAttachmentsList/ChatAttachmentsListItem/ChatAttachmentsListItemThumbnailImage.svelte +++ b/tools/ui/src/lib/components/app/chat/ChatAttachments/ChatAttachmentsList/ChatAttachmentsListItem/ChatAttachmentsListItemThumbnailImage.svelte @@ -30,7 +30,7 @@ {#snippet image()} - {name} + {name} {/snippet}
- 1} /> + 1} />
{#if currentItem} {/if} - +
diff --git a/tools/ui/src/lib/components/app/chat/ChatAttachments/ChatAttachmentsPreview/ChatAttachmentsPreviewCurrentItem/ChatAttachmentsPreviewCurrentItem.svelte b/tools/ui/src/lib/components/app/chat/ChatAttachments/ChatAttachmentsPreview/ChatAttachmentsPreviewCurrentItem/ChatAttachmentsPreviewCurrentItem.svelte index c0d7cbd30de1..eabfe2f1aeeb 100644 --- a/tools/ui/src/lib/components/app/chat/ChatAttachments/ChatAttachmentsPreview/ChatAttachmentsPreviewCurrentItem/ChatAttachmentsPreviewCurrentItem.svelte +++ b/tools/ui/src/lib/components/app/chat/ChatAttachments/ChatAttachmentsPreview/ChatAttachmentsPreviewCurrentItem/ChatAttachmentsPreviewCurrentItem.svelte @@ -53,18 +53,18 @@ {#key currentItem.id} {#if isPdf} {:else if isImage} {:else if isText && displayTextContent} {:else if isAudio} - + {:else if isVideo} {:else if isUnavailable} diff --git a/tools/ui/src/lib/components/app/chat/ChatAttachments/ChatAttachmentsPreview/ChatAttachmentsPreviewCurrentItem/ChatAttachmentsPreviewCurrentItemAudio.svelte b/tools/ui/src/lib/components/app/chat/ChatAttachments/ChatAttachmentsPreview/ChatAttachmentsPreviewCurrentItem/ChatAttachmentsPreviewCurrentItemAudio.svelte index ace69b818114..90392c9570fd 100644 --- a/tools/ui/src/lib/components/app/chat/ChatAttachments/ChatAttachmentsPreview/ChatAttachmentsPreviewCurrentItem/ChatAttachmentsPreviewCurrentItemAudio.svelte +++ b/tools/ui/src/lib/components/app/chat/ChatAttachments/ChatAttachmentsPreview/ChatAttachmentsPreviewCurrentItem/ChatAttachmentsPreviewCurrentItemAudio.svelte @@ -14,7 +14,7 @@ {#if audioSrc} -