Technology Stack
- Tauri 2: Desktop application framework with IPC bridge
- Rust (edition 2024): Systems programming language
- SQLite (rusqlite): Embedded database for course metadata and progress
- portable-pty: Cross-platform PTY (pseudoterminal) for terminal emulation
- reqwest: Async HTTP client for course downloads
- notify: File system watcher for hot reload
- serde/serde_json: Serialization and deserialization
- tokio: Async runtime (used by dependencies)
Project Structure
Core Modules
Application Initialization
File:src/lib.rs
The run() function initializes the app:
Initialize database
~/.handhold/handhold.db with schema for courses, progress, and settings.TTS (Text-to-Speech)
Location:src/tts/
Integrates Kokoro TTS engine as a sidecar binary.
Architecture
- Frontend calls
synthesize(text, options) - Backend spawns
kokobinary as child process - Sends text to stdin as JSON
- Receives WAV audio on stdout
- Parses WAV to compute word boundaries
- Returns audio (base64) + word timings to frontend
Key Functions
synthesize command (src/tts/commands.rs)
src/tts/timing.rs)
Divides audio duration evenly across words (simple heuristic). Future enhancement: Use phoneme-level timing from TTS engine.
Kokoro Binary Management (src/tts/synth.rs)
Spawns koko process:
Course Management
Location:src/course/
Handles course discovery, import, metadata, and progress tracking.
Database Schema
Courses Table:Import Flow
Command:course_import
Detect source type
If URL is a Git repository, clone to
~/.handhold/courses/<course-id>.If local path, copy to same location.Progress Tracking
Commands:step_complete(course_id, step_id)- Mark step as completestep_progress(course_id, step_id)- Query completion statusslide_position_save(course_id, step_id, position)- Save playback positionslide_position_load(course_id, step_id)- Load playback position
Container Orchestration
File:src/container.rs
Manages Docker/Podman containers for lab services.
Runtime Detection
Command:detect_container_runtime
Checks for podman or docker in PATH:
Docker Compose Integration
Command:compose_up
Runs docker-compose up -d (or podman-compose):
compose_down
Stops and removes containers:
container_logs
Streams logs from a container:
PTY (Terminal Emulation)
File:src/pty.rs
Provides terminal emulation using portable-pty.
Architecture
- Frontend calls
pty_spawn(shell, cwd, env)→ Returns PTY ID - Backend spawns shell process attached to PTY
- Frontend sends input via
pty_write(id, data) - Backend writes to PTY stdin
- Backend reads PTY output and sends to frontend via events
Key Functions
pty_spawn command
pty_write command
pty_resize command
LSP (Language Server Protocol)
File:src/lsp.rs
Bridges Monaco Editor to language servers (e.g., TypeScript, Rust Analyzer).
Architecture
- Frontend calls
lsp_spawn(language, root_path)→ Returns LSP ID - Backend spawns language server process
- Frontend sends LSP requests via
lsp_send(id, message) - Backend forwards to LSP stdin
- Backend reads LSP stdout and emits to frontend
Key Functions
lsp_spawn command
typescript→typescript-language-serverrust→rust-analyzerpython→pyright
lsp_send command
File System Operations
File:src/fs.rs
Provides file system access for labs.
Key Commands
Git Operations
File:src/git.rs
Provides Git integration for labs.
Key Commands
git_line_diff command
Compares working directory to last commit:
git_status_files command
Lists modified files:
Database
File:src/db.rs
Initializes SQLite and provides connection pool.
Initialization
State Management
Database is managed via Tauri state:Preview Compilation
File:src/preview.rs
Compiles JSX to JavaScript using the Oxc (Oxidation Compiler) toolchain.
Command: compile_jsx
Command Execution
File:src/runner.rs
Runs shell commands and captures output.
Command: run_command
File Watching
File:src/watcher.rs
Watches directories for file changes using notify.
Commands:
IPC Communication
All backend functions are exposed as Tauri commands using the#[tauri::command] macro.
Frontend invokes via @tauri-apps/api:
Error Handling
Commands returnResult<T, String>:
Ok(value)→ Frontend receives valueErr(message)→ Frontend receives error message
Performance Considerations
- Async operations: Long-running tasks (e.g., course download) should use async/await to avoid blocking
- Batch operations: Minimize IPC calls by batching when possible
- Caching: Frontend caches TTS audio, course metadata, etc., to reduce backend calls
Security
- Path validation: All file operations validate paths to prevent directory traversal
- Command injection: Shell commands are carefully constructed to avoid injection
- CSP: Content Security Policy is disabled for preview iframes (configurable)
Next Steps
Frontend
Explore the React frontend
Parser
Understand the markdown parser
Presentation Engine
Learn how playback works
Architecture
High-level system overview