A mob programming timer — manages participant rotation, turn countdowns, and scheduled breaks for a dev session.
Before anything, make sure you have:
curl -fsSL https://bun.sh/install | bashxcode-select --installVerify your setup:
rustc --version # 1.77+
bun --version # 1.0+
# 1. Install frontend dependencies
bun install
# 2. The Rust dependencies are fetched automatically on first build/run
# but you can pre-fetch them with:
cd src-tauri && cargo fetch
# Full app (Rust backend + Svelte frontend, with hot reload)
bun run tauri dev
# Frontend only (no Rust, useful for UI work)
bun run dev
First run will be slow (~2–3 min) while Rust compiles all dependencies. Subsequent runs are fast.
bun run tauri build
Output is in src-tauri/target/release/bundle/ — platform-specific installer (.dmg on macOS, .msi on Windows).
Here's how the app works end to end once running:
init() from state.svelte.tsinit() fetches the current SessionState from Rust and subscribes to two events: session_tick and session_completeSessionStaterunning: trueremaining_phase_secs, and emits a session_tick event with the full updated statesession_tick and updates $state — the UI re-renders automaticallyremaining_phase_secs hits 0, Rust advances current_index to the next participant (wraps around)elapsed_session_secs reaches next_break_at_secs, Rust switches phase from turn to breaknext_break_at_secs is pushed forwardelapsed_session_secs >= session_duration_secs, Rust emits session_complete and stops the tickersrc/
lib/
types.ts # TypeScript mirrors of all Rust structs
ipc.ts # All invoke() calls — the only file that talks to Rust
state.svelte.ts # App-wide $state, event listeners, action functions
routes/
+page.svelte # Main view
+layout.ts # SPA config (ssr: false)
src-tauri/
src/
types.rs # Rust structs (Participant, Settings, SessionState)
session.rs # Timer logic — tick, rotation, break injection
commands.rs # Tauri IPC commands + background ticker
lib.rs # App entry — wires state, registers commands
bun run check # TypeScript + Svelte type check
cd src-tauri && cargo clippy # Rust linter
cd src-tauri && cargo test # Rust unit tests
All three must be clean before committing.