From 6b9a3adf85fe4db6ced250e109aa74ff0636117d Mon Sep 17 00:00:00 2001 From: megaproxy Date: Fri, 22 May 2026 13:50:02 +0100 Subject: [PATCH] Slim README for public visibility Repo is now public; the previous README leaked author-only context (local ~/claude/projects path, scripts/release.sh + tea workflow, icon-regen steps) that's irrelevant to anyone landing fresh. Now: Install / Using it / Stack / Build from source / Tests / Architecture / License-note. The release + icon-regen flows live in memory.md for the maintainer. Co-Authored-By: Claude Opus 4.7 (1M context) --- README.md | 75 +++++++++++++++++++++---------------------------------- 1 file changed, 28 insertions(+), 47 deletions(-) diff --git a/README.md b/README.md index ba434df..c91c02c 100644 --- a/README.md +++ b/README.md @@ -5,7 +5,7 @@ A Windows desktop app for running and arranging many WSL terminals at once. Buil - 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 +- Idle-detection toasts when a pane goes quiet - Ctrl+K palette to fuzzy-jump between panes ## Install @@ -16,79 +16,60 @@ A Windows desktop app for running and arranging many WSL terminals at once. Buil ### Requirements -- **Windows 10/11** with [WebView2 Runtime](https://developer.microsoft.com/microsoft-edge/webview2/) (preinstalled on Windows 11; downloadable on Windows 10). -- At least one WSL distro registered (`wsl -l -v` lists them). +- **Windows 10/11** with [WebView2 Runtime](https://developer.microsoft.com/microsoft-edge/webview2/) (preinstalled on Win11). +- At least one WSL distro registered (`wsl -l -v`). ## Using it -- **Split panes** — `⇥` in the pane toolbar splits right, `⇣` splits down. New pane inherits the parent's distro + cwd. +- **Split panes** — `⇥` in the pane toolbar splits right, `⇣` splits down. The 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. +- **Rename pane** — click the label in the toolbar, type, Enter (Esc to cancel). - **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`. +- **Preset layouts** — titlebar buttons: `1` / `2H` / `3H` / `2V` / `2×2`. Confirms before replacing a multi-pane layout. - **Active pane** — click any pane → blue border + keyboard focus. - **Jump to pane** — `Ctrl+K` opens 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." +- **Idle toasts** — top-right notification when a pane goes quiet for 5 s. 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 +## Stack -Develop the Rust + frontend code in WSL; **build and run on the Windows host** (Tauri targets Windows, Rust toolchain is Windows-side). +- **Tauri 2** (Rust backend, WebView2 frontend) — small bundle, native NSIS installer. +- **Svelte 5** + TypeScript + Vite + pnpm. +- **xterm.js** + `@xterm/addon-fit` for terminal rendering. +- **`portable-pty`** (Rust) spawning `wsl.exe -d ` PTYs. -**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. +## Build from source -### Prereqs (Windows host) - -- Windows 10/11 + WebView2 Runtime -- [MSVC toolchain](https://v2.tauri.app/start/prerequisites/#windows) (VS Build Tools, "C++ build tools" workload) -- [Rust](https://rustup.rs/) on the Windows host -- Node 20+ and pnpm (`corepack use pnpm@11.2.2`) - -### Build + iterate +This targets Windows; the Rust toolchain runs on the Windows host. Prereqs per [Tauri docs](https://v2.tauri.app/start/prerequisites/#windows): MSVC ("C++ build tools" workload), Rust, Node 20+, pnpm (`corepack use pnpm@latest`), at least one WSL distro. ```powershell -cd D:\dev\tiletopia +git clone https://git.rdx4.com/megaproxy/tiletopia.git +cd tiletopia pnpm install -pnpm tauri dev # iterate — auto-reloads frontend on save, recompiles Rust on src-tauri changes +pnpm tauri dev # iterate pnpm tauri build # NSIS installer at src-tauri\target\release\bundle\nsis\ ``` -### Test (WSL) +**Keep the source on a Windows-native drive** (e.g. `C:\` or `D:\`). Running pnpm against a `\\wsl.localhost\...` UNC path crashes pnpm 11.x inside `isDriveExFat` (with a misleading error from the crashing hint formatter). + +### Run the tests ```sh -pnpm test # vitest, ~43 cases on the layout tree -pnpm test:watch # rerun on file change +pnpm test # vitest, 43 cases on the layout tree +pnpm test:watch 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. +The test suite covers the pure helpers in `src/lib/layout/tree.ts`. UI behavior, broadcast routing, and Tauri integration are manually tested. -### Release +## Architecture -1. Bump version in `package.json`, `src-tauri/Cargo.toml`, `src-tauri/tauri.conf.json`. Commit + push. -2. On Windows: `pnpm tauri build` (produces `src-tauri\target\release\bundle\nsis\tiletopia__x64-setup.exe`). -3. From WSL: `scripts/release.sh v0.1.0` — sanity-checks, tags `v0.1.0`, pushes the tag, and uploads the installer to Forgejo as a release via `tea`. - -### Regenerate the icon - -```sh -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`: `PtyManager` holding `Mutex>` of `portable-pty` children. Each spawned pane gets a background reader thread that emits `pane://{id}/data` events to the frontend (base64 chunks). Counterparts: `write_to_pane` / `resize_pane` / `kill_pane`. Workspace persistence via `save_workspace` / `load_workspace` writing to `app.path().app_config_dir()` with atomic tmp+rename. -- **Layout** — `src/lib/layout/tree.ts`: binary tree of splits. `HSplit | VSplit` internal nodes with a ratio, `Leaf` at the bottom. Same model as i3 / tmux / Zellij — adaptive resize falls out of mutating one parent ratio. Pure helpers (`splitLeaf`, `closeLeaf`, `changeDistro`, etc.) live in `tree.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.svelte` and are bundled into a `PaneOps` interface (`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. +- **Backend** (`src-tauri/src/pty.rs`): `PtyManager` holding `Mutex>` of `portable-pty` children. Each spawned pane gets a background reader thread that emits `pane://{id}/data` events (base64 byte chunks). Counterparts: `write_to_pane` / `resize_pane` / `kill_pane`. Workspace persistence via `save_workspace` / `load_workspace` writes to `app.path().app_config_dir()` with atomic tmp + rename. +- **Layout** (`src/lib/layout/tree.ts`): binary tree of splits. `HSplit | VSplit` internal nodes with a ratio, `Leaf` at the bottom — same model as i3 / tmux / Zellij. Adaptive resize falls out of mutating one parent ratio. Pure helpers (`splitLeaf`, `closeLeaf`, `changeDistro`, etc.) live in `tree.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.svelte` and reach the panes via a `PaneOps` bundle (`src/lib/layout/ops.ts`) drilled through the Pane chain. ## License -Personal project; no formal license yet. +No formal license yet. Public for inspection and personal use; if you want to redistribute, open an issue and ask.