Some checks failed
Build AppImage / build (push) Has been cancelled
Phase 8 (VS-Code-Look Chatbereich): - Linksbuendige Messages mit Avatar-Spalte, Hover-Actions - Inline Tool-Karten (Read/Edit/Bash/Generic) in Assistant-Messages - Edit-Karten zeigen Diff direkt mit Accept/Reject - Tool-Calls werden via events.ts an letzte Assistant-Message gebunden - Smart-Sticky-Scroll (Auto-Scroll stoppt wenn User selbst scrollt) - OOM-Bug durch MutationObserver mit subtree:true behoben Phase 9 (Komplettes UI-Redesign): - Design-System in app.css: 4 Graustufen, 1 Akzent (#007acc), 4 Status-Farben, 5 Schriftgroessen (11/12/13/14/16), 4-Punkt-Spacing, 2 Radius-Werte - vscode.css als Aliase auf das neue System - UI-Library src/lib/ui/: Button, Card, Icon, Badge, StatusDot, Tooltip, Drawer, Tabs - Lucide-svelte fuer SVG-Icons (ersetzt Emojis im Chrome) - StatusBar (22px) ersetzt ueberfuellten Footer mit 6+ Stats - Titlebar entruempelt: ✱-Logo + Stop + Schulungsmodus + Version - 2-spaltiges Layout (Sidebar 240px + Hauptbereich) statt 4-Pane-Zerstueckelung - ToolDrawer: 13 Panels in 4 Gruppen (Aktivitaet/Speicher/Werkzeuge/Einstellungen), jede Gruppe mit internen Tabs, Esc schliesst - Cmd+K global oeffnet QuickActions als zentrale Navigation - StatusDot-Komponente ersetzt Emoji-Status (🟢🟡⚪🔴) in AgentView - Hardgecodete Farben (#ef4444, #22c55e, #eab308 ...) in 9 Komponenten durch CSS-Variablen ersetzt Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
129 lines
3.3 KiB
Svelte
129 lines
3.3 KiB
Svelte
<script lang="ts">
|
|
// Spezialisierung Read/Glob/NotebookRead
|
|
// Zeigt Inhalt als Code-Block mit Zeilennummern, kollabsbar, Copy-Button.
|
|
|
|
import ToolCallCard from './ToolCallCard.svelte';
|
|
import type { InlineToolCall } from '$lib/stores';
|
|
|
|
interface Props {
|
|
call: InlineToolCall;
|
|
}
|
|
let { call }: Props = $props();
|
|
|
|
const filePath = $derived((call.input.file_path || call.input.path || '') as string);
|
|
const offset = $derived((call.input.offset as number | undefined) ?? 1);
|
|
|
|
// Result kann sehr lang sein — nur erste 40 Zeilen rendern, Rest als "+N weitere"
|
|
const MAX_LINES = 40;
|
|
const allLines = $derived((call.result || '').split('\n'));
|
|
const visibleLines = $derived(allLines.slice(0, MAX_LINES));
|
|
const hiddenCount = $derived(Math.max(0, allLines.length - MAX_LINES));
|
|
|
|
let copied = $state(false);
|
|
async function copyResult() {
|
|
try {
|
|
await navigator.clipboard.writeText(call.result || '');
|
|
copied = true;
|
|
setTimeout(() => (copied = false), 1500);
|
|
} catch {
|
|
/* ignore */
|
|
}
|
|
}
|
|
</script>
|
|
|
|
<ToolCallCard {call}>
|
|
{#snippet children()}
|
|
{#if call.status === 'running'}
|
|
<div class="placeholder">… Datei wird gelesen …</div>
|
|
{:else if call.status === 'error'}
|
|
<div class="error-msg">{call.result || 'Fehler beim Lesen'}</div>
|
|
{:else if call.result}
|
|
<div class="actions">
|
|
<button class="action-btn" onclick={copyResult}>
|
|
{copied ? '✓ Kopiert' : '📋 Kopieren'}
|
|
</button>
|
|
</div>
|
|
<pre class="code-block"><code>{#each visibleLines as line, i}<span class="line"><span class="lineno">{offset + i}</span><span class="lineof">│</span><span class="lineco">{line}</span>
|
|
</span>{/each}</code></pre>
|
|
{#if hiddenCount > 0}
|
|
<div class="more-hint">… +{hiddenCount} weitere Zeilen</div>
|
|
{/if}
|
|
{:else}
|
|
<div class="placeholder">{filePath}</div>
|
|
{/if}
|
|
{/snippet}
|
|
</ToolCallCard>
|
|
|
|
<style>
|
|
.actions {
|
|
display: flex;
|
|
justify-content: flex-end;
|
|
gap: 6px;
|
|
margin-bottom: 4px;
|
|
}
|
|
.action-btn {
|
|
font-size: 11px;
|
|
padding: 2px 8px;
|
|
color: var(--vscode-descriptionForeground);
|
|
border-radius: 2px;
|
|
background: transparent;
|
|
}
|
|
.action-btn:hover {
|
|
color: var(--vscode-editor-foreground);
|
|
background: var(--vscode-list-hoverBackground);
|
|
}
|
|
|
|
.code-block {
|
|
font-family: var(--font-mono);
|
|
font-size: 11.5px;
|
|
line-height: 1.55;
|
|
background: var(--vscode-terminal-background);
|
|
color: var(--vscode-editor-foreground);
|
|
border: 1px solid var(--vscode-input-border);
|
|
border-radius: 3px;
|
|
overflow-x: auto;
|
|
max-height: 360px;
|
|
overflow-y: auto;
|
|
padding: 6px 0;
|
|
}
|
|
.code-block code { background: none; padding: 0; }
|
|
|
|
.line {
|
|
display: grid;
|
|
grid-template-columns: 44px 12px 1fr;
|
|
column-gap: 0;
|
|
}
|
|
.lineno {
|
|
color: var(--vscode-editorLineNumber-foreground);
|
|
text-align: right;
|
|
padding-right: 8px;
|
|
user-select: none;
|
|
}
|
|
.lineof {
|
|
color: var(--vscode-editorLineNumber-foreground);
|
|
opacity: 0.5;
|
|
user-select: none;
|
|
}
|
|
.lineco {
|
|
white-space: pre;
|
|
padding-left: 6px;
|
|
}
|
|
|
|
.placeholder {
|
|
color: var(--vscode-descriptionForeground);
|
|
font-size: 11.5px;
|
|
font-family: var(--font-mono);
|
|
}
|
|
.error-msg {
|
|
color: var(--vscode-errorForeground);
|
|
font-family: var(--font-mono);
|
|
font-size: 11.5px;
|
|
white-space: pre-wrap;
|
|
}
|
|
.more-hint {
|
|
margin-top: 4px;
|
|
color: var(--vscode-descriptionForeground);
|
|
font-size: 11px;
|
|
font-style: italic;
|
|
}
|
|
</style>
|