init commit

This commit is contained in:
2026-01-18 22:07:48 -05:00
parent 9c019e3d41
commit 56dde9cf91
43 changed files with 2925 additions and 0 deletions
+116
View File
@@ -0,0 +1,116 @@
<script lang="ts">
import { page } from '$app/stores';
import { goto } from '$app/navigation';
import { onMount, onDestroy } from 'svelte';
import { activeSession } from '$lib/stores/sessions';
import MessageList from '$lib/components/MessageList.svelte';
import InputBar from '$lib/components/InputBar.svelte';
$: sessionId = $page.params.id;
onMount(() => {
if (sessionId) {
activeSession.load(sessionId);
}
});
onDestroy(() => {
activeSession.clear();
});
function handleSend(event: CustomEvent<string>) {
activeSession.sendMessage(event.detail);
}
function goBack() {
goto('/');
}
$: session = $activeSession.session;
$: externalId = session?.['external-id'] || session?.externalId || '';
$: workingDir = session?.['working-dir'] || session?.workingDir || '';
$: shortId = externalId.slice(0, 8);
$: projectName = workingDir.split('/').pop() || '';
const statusColors: Record<string, string> = {
idle: 'bg-zinc-600',
running: 'bg-green-500 animate-pulse',
completed: 'bg-blue-500'
};
</script>
<svelte:head>
<title>{session?.title || `Session ${shortId}`} - Spiceflow</title>
</svelte:head>
<!-- Header -->
<header class="flex-shrink-0 border-b border-zinc-800 px-4 py-3">
<div class="flex items-center gap-3">
<button
on:click={goBack}
class="p-1 -ml-1 hover:bg-zinc-700 rounded transition-colors"
aria-label="Go back"
>
<svg class="h-6 w-6" fill="none" viewBox="0 0 24 24" stroke="currentColor">
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M15 19l-7-7 7-7" />
</svg>
</button>
{#if $activeSession.loading}
<div class="flex-1">
<div class="h-5 w-32 bg-zinc-700 rounded animate-pulse"></div>
<div class="h-4 w-24 bg-zinc-800 rounded animate-pulse mt-1"></div>
</div>
{:else if session}
<div class="flex-1 min-w-0">
<div class="flex items-center gap-2">
<span class="w-2 h-2 rounded-full {statusColors[session.status] || statusColors.idle}"></span>
<h1 class="font-semibold truncate">
{session.title || `Session ${shortId}`}
</h1>
</div>
{#if projectName}
<p class="text-xs text-zinc-500 truncate">{projectName}</p>
{/if}
</div>
<span
class="text-xs font-medium uppercase {session.provider === 'claude'
? 'text-spice-400'
: 'text-emerald-400'}"
>
{session.provider}
</span>
{/if}
</div>
</header>
<!-- Content -->
{#if $activeSession.error}
<div class="flex-1 flex items-center justify-center p-4">
<div class="text-center">
<div class="text-red-400 mb-4">{$activeSession.error}</div>
<button on:click={goBack} class="btn btn-secondary">Go Back</button>
</div>
</div>
{:else if $activeSession.loading}
<div class="flex-1 flex items-center justify-center">
<svg class="animate-spin h-8 w-8 text-spice-500" fill="none" viewBox="0 0 24 24">
<circle class="opacity-25" cx="12" cy="12" r="10" stroke="currentColor" stroke-width="4"
></circle>
<path
class="opacity-75"
fill="currentColor"
d="M4 12a8 8 0 018-8V0C5.373 0 0 5.373 0 12h4z"
></path>
</svg>
</div>
{:else}
<MessageList messages={$activeSession.messages} streamingContent={$activeSession.streamingContent} />
<InputBar
on:send={handleSend}
disabled={session?.status === 'running' && $activeSession.streamingContent !== ''}
placeholder={session?.status === 'running' ? 'Waiting for response...' : 'Type a message...'}
/>
{/if}