This commit is contained in:
Timothy Jaeryang Baek 2026-11-02 10:14:44 +09:00
parent 151f7a84d1
commit 27963030ec
18 changed files with 51 additions and 34 deletions

View file

@ -407,7 +407,7 @@
>{/if}
</div>
{#if error}
<p role="alert" class="px-2 py-1 text-xs text-red-500">{error}</p>
<p role="alert" class="px-2 py-1 text-xs text-gray-500 dark:text-gray-400">{error}</p>
{:else if connectionStatus}
<p role="status" class="px-2 py-1 text-xs text-gray-500 dark:text-gray-400">
{$i18n.t(connectionStatus)}

View file

@ -593,7 +593,7 @@
>{/if}
{#if additions || deletions}<span class="flex gap-1 shrink-0"
><span class="text-green-600 dark:text-green-400">+{additions}</span><span
class="text-red-500 dark:text-red-400">-{deletions}</span
class="text-gray-500 dark:text-gray-400">-{deletions}</span
></span
>{/if}
</button>
@ -621,7 +621,7 @@
on:click={toggle}><Icon name={expanded ? 'chevron-down' : 'chevron-up'} size={14} /></button
>
</div>
{#if error}<div role="alert" class="px-3 py-2 text-xs text-red-500 break-words">
{#if error}<div role="alert" class="px-3 py-2 text-xs text-gray-500 dark:text-gray-400 break-words">
{error}
</div>{/if}
{#if expanded}
@ -811,7 +811,7 @@
aria-label={`${$i18n.t('View changes')} ${file.path}`}
on:click={() => selectFile(file, file.staged)}
><span class="text-green-600 dark:text-green-400">+{file.additions}</span
><span class="text-red-500 dark:text-red-400">-{file.deletions}</span
><span class="text-gray-500 dark:text-gray-400">-{file.deletions}</span
></button
>{/if}
<Dropdown side="top" align="end" closeOnSelect>
@ -967,7 +967,7 @@
>
{#if diff && !loadingDiff}<span class="flex shrink-0 items-center gap-1"
><span class="text-green-600 dark:text-green-400">+{diffStats.additions}</span
><span class="text-red-500 dark:text-red-400">-{diffStats.deletions}</span
><span class="text-gray-500 dark:text-gray-400">-{diffStats.deletions}</span
></span
>{/if}
</div>

View file

@ -135,13 +135,13 @@
}
.removed {
background-color: var(--color-red-100);
color: var(--color-red-900);
color: var(--color-gray-600);
}
.added .prefix {
color: var(--color-green-600);
}
.removed .prefix {
color: var(--color-red-500);
color: var(--color-gray-500);
}
.git-diff:not(.split) .added {
box-shadow: inset 0.1875rem 0 0 #22c55e;
@ -196,12 +196,12 @@
}
:global(.dark) .removed {
background-color: #ef444426;
color: var(--color-red-300);
color: var(--color-gray-400);
}
:global(.dark) .added .prefix {
color: var(--color-green-400);
}
:global(.dark) .removed .prefix {
color: var(--color-red-400);
color: var(--color-gray-400);
}
</style>

View file

@ -203,7 +203,7 @@
</div>
{#if error && !selected && !creating && !editing}<p
role="alert"
class="px-2 py-1 text-red-500 break-words"
class="px-2 py-1 text-gray-500 dark:text-gray-400 break-words"
>
{error}
</p>{/if}
@ -281,7 +281,7 @@
</div></Dropdown
>{/if}
</div>
{#if error}<p role="alert" class="px-3 py-1 text-red-500 break-words">{error}</p>{/if}
{#if error}<p role="alert" class="px-3 py-1 text-gray-500 dark:text-gray-400 break-words">{error}</p>{/if}
{#if creating || editing}
<form
class="min-h-0 overflow-y-auto px-3 py-2 space-y-2"
@ -404,7 +404,7 @@
}}>{$i18n.t(method[0].toUpperCase() + method.slice(1))}</button
>{/each}
<button
class="pr-action text-red-500"
class="pr-action text-gray-500 dark:text-gray-400"
disabled={busy}
on:click={() => confirm('close')}>{$i18n.t('Close')}</button
>

View file

@ -47,9 +47,11 @@
}
while (branch.at(-1)?.role === 'assistant' && !branch.at(-1)?.done) branch.pop();
return structuredClone(
branch.map(({ role, content, output, files }) => ({
branch.map(({ id, role, content, output, files, contextSummary }) => ({
id,
role,
files,
contextSummary,
...(output?.length && role === 'assistant' ? { output } : { content: content ?? '' })
}))
);
@ -113,6 +115,13 @@
const receive = (event: any, callback?: (value: any) => void) => {
if (!id || event.chat_id !== id) return;
const { type, data } = event.data ?? {};
if (type === 'context_compaction') {
const checkpoint = [...context, ...messages].find(
(message) => message.id === data.checkpoint_message_id
);
if (checkpoint && data.context_summary) checkpoint.contextSummary = data.context_summary;
return;
}
if (type === 'request:interaction:done') {
interactions = interactions.filter((item) => item.id !== data.interaction_id);
return;
@ -240,12 +249,19 @@
if (messages.length) messages.at(-1).childrenIds.push(userMessage.id);
const conversation = [...context, ...messages, userMessage].map((message) => {
if (message.role === 'assistant' && message.output?.length)
return { role: message.role, output: message.output };
return {
id: message.id,
role: message.role,
output: message.output,
contextSummary: message.contextSummary
};
const images = (message.files ?? []).filter(
(file: any) => file.type === 'image' || isRasterImageContentType(file.content_type)
);
return {
id: message.id,
role: message.role,
contextSummary: message.contextSummary,
content: images.length
? [
{ type: 'text', text: message.content ?? '' },
@ -274,6 +290,7 @@
chat_id: id,
session_id: $socket.id,
id: answer.id,
user_message: userMessage,
params: { ...params, tool_approval_mode: toolApprovalMode },
files: requestFiles,
tool_ids: selectedToolIds.filter((id) => !id.startsWith('direct_server:')),
@ -421,7 +438,7 @@
{/if}
</div>
<div class="shrink-0 pb-2 z-10">
{#if error}<p role="alert" class="px-4 py-2 text-xs text-red-500">{error}</p>{/if}
{#if error}<p role="alert" class="px-4 py-2 text-xs text-gray-500 dark:text-gray-400">{error}</p>{/if}
{#if sideChatAllowed}
<MessageInput
bind:this={input}

View file

@ -226,7 +226,7 @@
>
{/each}{/if}
</div>
{#if error}<p role="alert" class="py-2 text-xs text-red-500">{error}</p>{/if}
{#if error}<p role="alert" class="py-2 text-xs text-gray-500 dark:text-gray-400">{error}</p>{/if}
<div class="flex items-center gap-2 pt-2">
<span class="min-w-0 flex-1 truncate text-xs text-gray-400" title={fullPath}>{fullPath}</span>
<button

View file

@ -58,7 +58,7 @@
<Tooltip content={$i18n.t('Delete')}>
<button
class="flex h-5 w-5 items-center justify-center rounded transition-colors duration-100 text-gray-400 dark:text-gray-500 hover:text-red-500 disabled:opacity-30 disabled:hover:text-gray-400"
class="flex h-5 w-5 items-center justify-center rounded transition-colors duration-100 text-gray-400 dark:text-gray-500 hover:text-gray-600 dark:hover:text-gray-300 disabled:opacity-30 disabled:hover:text-gray-400"
on:click={onDelete}
disabled={!canDelete}
aria-label={$i18n.t('Delete')}

View file

@ -318,7 +318,7 @@
selectedExcelSheet={sheet}
onSheetChange={setSheet}
/>
{:else if previewError}<p class="p-4 text-sm text-red-500">{$i18n.t('Preview failed')}</p>{/if}
{:else if previewError}<p class="p-4 text-sm text-gray-500 dark:text-gray-400">{$i18n.t('Preview failed')}</p>{/if}
{#if unplaced.length || commentState === 'error' || commentState === 'partial'}
<button
type="button"

View file

@ -237,7 +237,7 @@
>+{result.additions}</span
>
<span
class="text-red-500 dark:text-red-400"
class="text-gray-500 dark:text-gray-400"
aria-label={$i18n.t('{{count}} removed lines', { count: result.deletions })}
>−{result.deletions}</span
>
@ -395,7 +395,7 @@
}
.removed {
background-color: var(--color-red-100);
color: var(--color-red-900);
color: var(--color-gray-600);
background-image: repeating-linear-gradient(
-45deg,
#ef4444 0,
@ -411,7 +411,7 @@
color: var(--color-green-600);
}
.removed .marker {
color: var(--color-red-500);
color: var(--color-gray-500);
}
.added .changed {
background: rgb(22 163 74 / 0.38);
@ -428,13 +428,13 @@
}
:global(.dark) .removed {
background-color: color-mix(in oklab, var(--color-red-500) 15%, transparent);
color: var(--color-red-300);
color: var(--color-gray-400);
}
:global(.dark) .added .marker {
color: var(--color-green-400);
}
:global(.dark) .removed .marker {
color: var(--color-red-400);
color: var(--color-gray-400);
}
:global(.dark) .number {
color: var(--color-gray-600);

View file

@ -167,7 +167,7 @@
<Spinner className="size-4" />{$i18n.t('Loading...')}
</div>
{:else if error}
<p class="px-5 py-2 break-words text-red-600" role="alert">{error}</p>
<p class="px-5 py-2 break-words text-gray-500 dark:text-gray-400" role="alert">{error}</p>
<button
type="button"
class="mx-5 mt-2 self-start rounded-lg bg-gray-100 dark:bg-gray-850 px-2.5 h-7"

View file

@ -66,7 +66,7 @@
aria-label={$i18n.t('File changes')}
aria-busy={loading}
>
{#if error}<div role="alert" class="p-3 text-xs text-red-500">
{#if error}<div role="alert" class="p-3 text-xs text-gray-500 dark:text-gray-400">
{error}<button
class="ml-2 underline"
on:click={() =>

View file

@ -155,7 +155,7 @@
>
{:else}
<span class="text-green-600 dark:text-green-400">+{gitFile.additions ?? 0}</span>
<span class="text-red-500 dark:text-red-400">-{gitFile.deletions ?? 0}</span>
<span class="text-gray-500 dark:text-gray-400">-{gitFile.deletions ?? 0}</span>
{/if}
</span>
{/if}

View file

@ -356,7 +356,7 @@
: undefined}
/>
{:catch}
<div class="p-4 text-sm text-red-500">{$i18n.t('Preview failed')}</div>
<div class="p-4 text-sm text-gray-500 dark:text-gray-400">{$i18n.t('Preview failed')}</div>
{/await}
{/key}
{:else if fileSqliteData !== null}
@ -516,7 +516,7 @@
</div>
{:else if isJson && !showRaw && jsonError}
<div class="p-3 text-xs">
<div class="text-red-500 mb-2">
<div class="text-gray-500 dark:text-gray-400 mb-2">
{$i18n.t('JSON parse error: {{error}}', { error: jsonError })}
</div>
<pre

View file

@ -269,7 +269,7 @@
{#if kernelError}
<div
class="px-2 py-1 text-[0.65rem] text-red-600 dark:text-red-400 bg-red-50 dark:bg-red-950/30 whitespace-pre-wrap font-mono"
class="px-2 py-1 text-[0.65rem] text-gray-500 dark:text-gray-400 bg-red-50 dark:bg-red-950/30 whitespace-pre-wrap font-mono"
>
{kernelError}
</div>

View file

@ -129,7 +129,7 @@
{#if loading}
<div class="flex items-center justify-center h-full"><Spinner className="size-4" /></div>
{:else if error}
<div class="p-3 text-xs text-red-500">{error}</div>
<div class="p-3 text-xs text-gray-500 dark:text-gray-400">{error}</div>
{:else}
<!-- Table tabs + query toggle -->
<div
@ -181,7 +181,7 @@
class="flex items-center justify-between px-2 py-1 bg-gray-50 dark:bg-gray-900 border-b border-gray-100 dark:border-gray-800"
>
{#if queryError}
<span class="text-[0.65rem] text-red-500 dark:text-red-400 truncate mr-2"
<span class="text-[0.65rem] text-gray-500 dark:text-gray-400 truncate mr-2"
>{queryError}</span
>
{:else}

View file

@ -447,7 +447,7 @@
</div>
{:else if error}
<div class="flex items-center justify-center flex-1 p-6">
<div class="text-xs text-red-500">{error}</div>
<div class="text-xs text-gray-500 dark:text-gray-400">{error}</div>
</div>
{:else if entries.length === 0 && !creatingFolder && !creatingFile}
<div class="flex flex-col items-center justify-center flex-1 p-6 text-center gap-2">

View file

@ -171,7 +171,7 @@
/>
</div>
</div>
{#if error}<p role="alert" class="py-1 text-xs text-red-500">{error}</p>{/if}
{#if error}<p role="alert" class="py-1 text-xs text-gray-500 dark:text-gray-400">{error}</p>{/if}
<div class="absolute {embedded ? 'bottom-0 end-0' : 'bottom-2 end-2.5'} flex items-center">
<div class="flex items-center gap-2">
<button

View file

@ -262,7 +262,7 @@
>
{#if loading}<div class="flex justify-center py-5"><Spinner className="size-5" /></div>{/if}
{#if error}<div class="px-4 py-2">
<p role="alert" class="text-xs text-red-500">{error}</p>
<p role="alert" class="text-xs text-gray-500 dark:text-gray-400">{error}</p>
<button
type="button"
class="mt-1 text-xs text-gray-500 hover:text-gray-700 dark:hover:text-gray-300"