DeskPet
A desktop companion app — a transparent, always-on-top cat lives at the edge of your screen and gently reminds you to drink water and stretch.
A little cat sits at the edge of your screen: transparent, always on top, draggable. It rests, walks, gets picked up, talks to you, occasionally heads out — and at the right moments, gently reminds you to drink some water or stand up and stretch. The product is deliberately subtractive: no feeding, no leveling, no affection meters, no AI chat — companionship should be low-noise, and restraint is itself a product decision.

Two pets ship built-in — Jiaojiao and Dimo — and custom pet packs are supported: drop spritesheets and a manifest into a folder and you have a new pet, with versioned manifests (v1/v2) and forward-compatible unknown fields. Settings persist locally and restore on launch. It stays polite as a resident app: a tiny transparent window, preloaded spritesheets, low-frequency polling, and every timer and animation paused while hidden or away.
Technical highlights
~4,400 lines of source, split between Rust and TypeScript by responsibility rather than by technology.
Three-layer boundaries
One iron rule throughout: Rust owns system and file concerns only (transparent always-on-top window, tray, settings I/O, pet-pack scanning); every visual state and animation behavior stays in TypeScript.
Testable behavior layer
The state machine is a pure reducer; scheduling, sprite parsing and edge bouncing are pure functions; anything touching the window goes through dependency injection — 132 tests run entirely without a real Tauri window.
Drag race-condition controller
Dragging must query the native window position asynchronously while pointer events arrive synchronously. A generation counter + pendingStart buffer + move coalescing resolves the race; a 6px threshold splits click from drag.
Defensive self-healing
Corrupted settings are clamped and repaired on both the Rust and TS sides; pack manifests canonicalize every file path to block ../ traversal; invalid packs are quarantined and reported instead of crashing the app.
No feeding, no leveling, no AI chat — restraint is itself a product decision.