Initial scaffold from M1 spike (tiletopia)

Tauri 2 + Svelte 5 + xterm.js + portable-pty. Single full-window
WSL terminal pane with clickable distro picker. M1 verified manually
on Windows: window opens, xterm.js renders, claude TUI works,
resize reflows cleanly.

Graduated from ~/claude/ideas/wsl-mux/ per the approved plan at
~/.claude/plans/imperative-coalescing-feigenbaum.md. See memory.md
for decisions, open TODOs, and the M2-M5 roadmap.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
megaproxy 2026-05-22 12:31:29 +01:00
commit b352f8f049
36 changed files with 11534 additions and 0 deletions

112
src/App.svelte Normal file
View file

@ -0,0 +1,112 @@
<script lang="ts">
import { onMount } from "svelte";
import XtermPane from "./components/XtermPane.svelte";
import { listDistros } from "./ipc";
let distros = $state<string[]>([]);
let selected = $state<string | undefined>(undefined);
let status = $state("starting…");
let statusOk = $state(true);
let loadError = $state<string | null>(null);
function isInteractiveDistro(name: string): boolean {
return !name.toLowerCase().startsWith("docker-desktop");
}
onMount(async () => {
try {
const d = await listDistros();
console.log("listDistros() returned:", d);
distros = d;
// Pick fresh every mount (HMR can preserve $state across reloads).
selected = d.find(isInteractiveDistro) ?? d[0] ?? undefined;
console.log("default selected:", selected);
} catch (e) {
console.warn("list_distros failed:", e);
loadError = String(e);
}
});
function pick(d: string) {
console.log("user picked distro:", d);
selected = d;
}
</script>
<div class="app">
<header class="titlebar">
<span class="label">tiletopia</span>
<span class="distros">
{#if distros.length === 0}
<span class="muted">no distros enumerated</span>
{:else}
{#each distros as d}
<button
class="distro-btn"
class:active={d === selected}
onclick={() => pick(d)}
>
{d}
</button>
{/each}
{/if}
</span>
<span class="status {statusOk ? 'ok' : 'err'}">{status}</span>
</header>
<div class="pane-wrap">
{#if loadError}
<pre class="err-pre">listDistros failed: {loadError}</pre>
{:else if selected !== undefined || distros.length === 0}
{#key selected}
<XtermPane
distro={selected}
onStatus={(msg, ok) => {
status = msg;
statusOk = ok;
}}
/>
{/key}
{/if}
</div>
</div>
<style>
.distros {
display: flex;
gap: 4px;
align-items: center;
}
.distro-btn {
font: inherit;
font-family: "Cascadia Mono", "JetBrains Mono", "Consolas", monospace;
font-size: 11px;
background: #222;
color: #aaa;
border: 1px solid #333;
border-radius: 3px;
padding: 2px 8px;
cursor: pointer;
}
.distro-btn:hover {
background: #2a2a2a;
color: #ddd;
}
.distro-btn.active {
background: #1a3a5c;
color: #cce6ff;
border-color: #2a5a8c;
}
.muted {
color: #666;
font-style: italic;
}
.err-pre {
color: #d66;
padding: 12px;
margin: 0;
white-space: pre-wrap;
}
</style>