cargo auto-rewrote the tiletopia entry from 0.0.1 to 0.1.0 during the M5 release build; manually updating Cargo.toml in M5 didn't touch the lockfile. Committing so the release tag points at a clean tree. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com> |
||
|---|---|---|
| scripts | ||
| src | ||
| src-tauri | ||
| .gitignore | ||
| CLAUDE.md | ||
| index.html | ||
| memory.md | ||
| package.json | ||
| pnpm-lock.yaml | ||
| pnpm-workspace.yaml | ||
| README.md | ||
| svelte.config.js | ||
| tsconfig.json | ||
| tsconfig.node.json | ||
| vite.config.ts | ||
tiletopia
A Windows desktop app for running and arranging many WSL terminals at once. Built primarily for managing multiple claude sessions across projects in parallel; works for any multi-shell workflow.
- Tiling layout — recursive splits, draggable dividers, preset layouts (single / 2-col / 3-col / 2-row / 2×2)
- Per-pane distro + cwd + label, persisted across restarts
- Broadcast input to a group of panes
- Idle detection toasts when a pane goes quiet
- Ctrl+K palette to fuzzy-jump between panes
Install
- Download the latest
tiletopia_<version>_x64-setup.exefrom the releases page. - Run it. Windows SmartScreen will warn "unrecognized publisher" — it's not code-signed. More info → Run anyway.
- Launch tiletopia from the Start menu. A window opens with one terminal pane bound to your default WSL distro.
Requirements
- Windows 10/11 with WebView2 Runtime (preinstalled on Windows 11; downloadable on Windows 10).
- At least one WSL distro registered (
wsl -l -vlists them).
Using it
- Split panes —
⇥in the pane toolbar splits right,⇣splits down. New pane inherits the parent's distro + cwd. - Close pane —
×. The sibling expands to fill. - Rename pane — click the label in the toolbar, type, Enter.
- Change distro — click the small
Ubuntu ▾chip; pick a distro from the popover. The pane respawns (old shell is killed). - Broadcast — toggle
📡on two or more panes (orange border). Typing in any of them mirrors to all. - Preset layouts — titlebar buttons:
1/2H/3H/2V/2×2. - Active pane — click any pane → blue border + keyboard focus.
- Jump to pane —
Ctrl+Kopens a fuzzy picker over label / distro / cwd. ↑/↓ to navigate, Enter to focus, Esc to close. - Idle toasts — top-right notification appears when a pane goes quiet for 5s. Useful for "I started a long task; tell me when it's done."
Layout + per-pane settings auto-save to %APPDATA%\com.megaproxy.tiletopia\workspace.json (debounced 500 ms).
Develop
Develop the Rust + frontend code in WSL; build and run on the Windows host (Tauri targets Windows, Rust toolchain is Windows-side).
Source location matters. The project must live on a Windows-native drive (D:\dev\tiletopia\). Don't run pnpm against the \\wsl.localhost\... UNC path — pnpm 11.x crashes inside isDriveExFat (the actual error gets swallowed by the crashing error-hint formatter). The WSL-side symlink at ~/claude/projects/tiletopia is for editing, not building.
Prereqs (Windows host)
- Windows 10/11 + WebView2 Runtime
- MSVC toolchain (VS Build Tools, "C++ build tools" workload)
- Rust on the Windows host
- Node 20+ and pnpm (
corepack use pnpm@11.2.2)
Build + iterate
cd D:\dev\tiletopia
pnpm install
pnpm tauri dev # iterate — auto-reloads frontend on save, recompiles Rust on src-tauri changes
pnpm tauri build # NSIS installer at src-tauri\target\release\bundle\nsis\
Test (WSL)
pnpm test # vitest, ~43 cases on the layout tree
pnpm test:watch # rerun on file change
pnpm check # svelte-check
The test suite covers the pure tree helpers in src/lib/layout/tree.ts. UI behavior, broadcast routing, and Tauri integration are still manually tested.
Release
- Bump version in
package.json,src-tauri/Cargo.toml,src-tauri/tauri.conf.json. Commit + push. - On Windows:
pnpm tauri build(producessrc-tauri\target\release\bundle\nsis\tiletopia_<ver>_x64-setup.exe). - From WSL:
scripts/release.sh v0.1.0— sanity-checks, tagsv0.1.0, pushes the tag, and uploads the installer to Forgejo as a release viatea.
Regenerate the icon
python3 scripts/make-icon.py
pnpm tauri icon src-tauri/icons/source.png
# Tauri's icon command writes iOS + Android + UWP outputs too; rm them.
rm -rf src-tauri/icons/{ios,android,Square*.png,StoreLogo.png,64x64.png,icon.png}
See src-tauri/icons/README.md for details.
Architecture (quick tour)
- Backend —
src-tauri/src/pty.rs:PtyManagerholdingMutex<HashMap<PaneId, PaneHandle>>ofportable-ptychildren. Each spawned pane gets a background reader thread that emitspane://{id}/dataevents to the frontend (base64 chunks). Counterparts:write_to_pane/resize_pane/kill_pane. Workspace persistence viasave_workspace/load_workspacewriting toapp.path().app_config_dir()with atomic tmp+rename. - Layout —
src/lib/layout/tree.ts: binary tree of splits.HSplit | VSplitinternal nodes with a ratio,Leafat the bottom. Same model as i3 / tmux / Zellij — adaptive resize falls out of mutating one parent ratio. Pure helpers (splitLeaf,closeLeaf,changeDistro, etc.) live intree.ts; the rendering chain (Pane.svelte→SplitNode.svelte/LeafPane.svelte) is thin. - Orchestration — broadcast routing, idle detection, palette, active-pane focus all live in
App.svelteand are bundled into aPaneOpsinterface (src/lib/layout/ops.ts) drilled through the Pane chain. - Stack precedent — mirrors
~/claude/projects/claude-usage-widget/: same Tauri 2 + Svelte 5 + Vite + pnpm + NSIS Forgejo-release toolchain.
License
Personal project; no formal license yet.