+
+
+
ID
+
Template
+ {@render sortableHeader('CPU', 'vcpus')}
+ {@render sortableHeader('Memory', 'memory_mb')}
+ {@render sortableHeader('Idle Timeout', 'timeout_sec')}
+ {@render sortableHeader('Started', 'started_at')}
+ {@render sortableHeader('Status', 'status')}
+
+
+ {#if loading && capsules.length === 0}
+
+
+
+ Loading capsules...
+
+
+ {:else if filteredCapsules.length === 0}
+
+
+
+ No capsules yet
+
+
+ Each capsule is an isolated VM. Launch one to get started.
+
+
+
+ {:else}
+ {#each filteredCapsules as capsule, i (capsule.id)}
+ {@const stripeColor = capsule.status === 'running' ? 'bg-[var(--color-accent)]' : capsule.status === 'paused' ? 'bg-[var(--color-amber)]' : 'bg-[var(--color-text-muted)]'}
+
+
+
+
+
+
+ {#if capsule.status === 'running'}
+
+
+
+
+ {:else if capsule.status === 'paused'}
+
+ {:else}
+
+ {/if}
+ {#if searchQuery && capsule.id.toLowerCase().includes(searchQuery.toLowerCase())}
+ {@const matchIdx = capsule.id.toLowerCase().indexOf(searchQuery.toLowerCase())}
+ {capsule.id.slice(0, matchIdx)}{capsule.id.slice(matchIdx, matchIdx + searchQuery.length)}{capsule.id.slice(matchIdx + searchQuery.length)}
+ {:else}
+ {capsule.id}
+ {/if}
+
+
+
+
+ {capsule.template}
+
+
+
+
+ {capsule.vcpus}
+
+
+
+
+ {capsule.memory_mb}MB
+
+
+
+
+ {capsule.timeout_sec ? `${capsule.timeout_sec}s` : '—'}
+
+
+
+
+ {formatTime(capsule.started_at)}
+ {#if capsule.last_active_at}
+ {timeAgo(capsule.last_active_at)}
+ {/if}
+
+
+
+
+
+ {/each}
+ {/if}
+