claude-desktop/src/lib/components/ToolCardBash.svelte
Eddy ad9833fcb8
Some checks failed
Build AppImage / build (push) Has been cancelled
feat: Phase 8+9 — Inline Tool-Karten + komplettes UI-Redesign auf Cursor/Zed-Niveau [appimage]
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>
2026-04-27 14:27:09 +02:00

133 lines
3.2 KiB
Svelte

<script lang="ts">
// Spezialisierung Bash / BashOutput
// Zeigt Kommando als Zeile + Terminal-Output (monospace, gescrollt).
import ToolCallCard from './ToolCallCard.svelte';
import type { InlineToolCall } from '$lib/stores';
interface Props {
call: InlineToolCall;
}
let { call }: Props = $props();
const command = $derived((call.input.command as string) || '');
const description = $derived((call.input.description as string) || '');
let copied = $state(false);
async function copyOutput() {
try {
await navigator.clipboard.writeText(call.result || '');
copied = true;
setTimeout(() => (copied = false), 1500);
} catch { /* ignore */ }
}
// Output kuerzen (Terminal kann beliebig lang werden)
const MAX_LINES = 50;
const allLines = $derived((call.result || '').split('\n'));
const visibleLines = $derived(allLines.slice(-MAX_LINES));
const hiddenCount = $derived(Math.max(0, allLines.length - MAX_LINES));
</script>
<ToolCallCard {call}>
{#snippet children()}
{#if command}
<div class="cmd-line">
<span class="prompt">$</span>
<span class="cmd">{command}</span>
</div>
{/if}
{#if description && description !== command}
<div class="desc">{description}</div>
{/if}
{#if call.status === 'running'}
<div class="placeholder">… Befehl laeuft …</div>
{:else if call.result}
<div class="actions">
<button class="action-btn" onclick={copyOutput}>
{copied ? '✓ Kopiert' : '📋 Output kopieren'}
</button>
</div>
{#if hiddenCount > 0}
<div class="more-hint">… +{hiddenCount} fruehere Zeilen ausgeblendet</div>
{/if}
<pre class="terminal" class:err={call.status === 'error'}><code>{visibleLines.join('\n')}</code></pre>
{/if}
{/snippet}
</ToolCallCard>
<style>
.cmd-line {
font-family: var(--font-mono);
font-size: 12px;
color: var(--vscode-editor-foreground);
display: flex;
gap: 8px;
margin-bottom: 4px;
word-break: break-all;
}
.prompt {
color: var(--vscode-successForeground);
user-select: none;
}
.cmd { white-space: pre-wrap; }
.desc {
font-size: 11px;
color: var(--vscode-descriptionForeground);
margin-bottom: 6px;
}
.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);
}
.terminal {
font-family: var(--font-mono);
font-size: 11.5px;
line-height: 1.55;
background: var(--vscode-terminal-background);
color: var(--vscode-terminal-foreground);
border: 1px solid var(--vscode-input-border);
border-radius: 3px;
padding: 8px 10px;
max-height: 300px;
overflow: auto;
white-space: pre;
}
.terminal.err {
border-color: var(--vscode-errorForeground);
}
.terminal code {
background: none;
padding: 0;
}
.placeholder {
color: var(--vscode-descriptionForeground);
font-size: 11.5px;
font-family: var(--font-mono);
}
.more-hint {
font-size: 11px;
color: var(--vscode-descriptionForeground);
font-style: italic;
margin-bottom: 4px;
}
</style>