agentleFS
SplodeSplode/pomotroid/CLAUDE.md

pomotroid

CLAUDE.md5.5k starsChanged 8 months agoMITView on GitHub

Pomotroid is a Pomodoro timer desktop app built with Tauri 2 + Rust (backend) and SvelteKit + Svelte 5 (frontend). The app has been fully rewritten from Electron+Vue to this stack. There are no automated tests in this codebase. All frontend↔backend communication goes through src/lib/ipc/index.ts. This module exports typed wrappers around invoke() and listen(). Never call invoke() directly in components — always go through this module. Rust commands live in src-tauri/src/commands.rs. All commands return Result<T, String>. Tauri events emitted by…

We split this CLAUDE.md into the rules it gives an agent

1 rule. About 0 are common, 0 are distinctive, and 1 is very specific to this project.

  • ≈0

    Common · estimate

    Many files like this have a rule of this kind.

  • ≈0

    Distinctive · estimate

    This author's own choices. Worth a look.

  • 1

    Very specific

    Tied to their project's names, files or tools. Probably skip.

  • Common
  • Distinctive
  • Very specific
  1. Very specific:

    All frontend↔backend communication goes through src/lib/ipc/index.ts.

    line 43

≈ “Common” is an estimate: at least 1 in 5 of the 25,680 CLAUDE.md files we read have a rule of the same kind, not the same words. “Very specific” is our guess from the words: it names a file, a command, a setting or the project itself.

Keep what fits and drop the rest. Your version, ready for your agents.
Files
CLAUDE.md

CLAUDE.md

This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.

Overview

Pomotroid is a Pomodoro timer desktop app built with Tauri 2 + Rust (backend) and SvelteKit + Svelte 5 (frontend). The app has been fully rewritten from Electron+Vue to this stack.

Commands

# Development (runs Vite dev server + Tauri)
npm run tauri dev

# Production build
npm run tauri build

# Frontend-only Vite dev (no Tauri IPC available)
npm run dev

# Format all frontend source files
npm run format

# Type-check Svelte + TypeScript
npm run check

# Regenerate i18n types after editing inlang message files
npm run paraglide:compile

There are no automated tests in this codebase.

Architecture

Two windows

  • main (src/routes/+page.svelte) — the timer window
  • settings (src/routes/settings/+page.svelte) — opened via new WebviewWindow('settings', ...) from Titlebar.svelte
  • stats (src/routes/stats/+page.svelte) — statistics window

IPC layer

All frontend↔backend communication goes through src/lib/ipc/index.ts. This module exports typed wrappers around invoke() and listen(). Never call invoke() directly in components — always go through this module.

Rust commands live in src-tauri/src/commands.rs. All commands return Result<T, String>.

Tauri events emitted by Rust:

  • timer:tick — { elapsed_secs, total_secs } — fires every second while running
  • timer:paused — { elapsed_secs }
  • timer:resumed — { elapsed_secs }
  • timer:round-change — full TimerSnapshot
  • timer:reset — full TimerSnapshot (used to sync frontend after settings changes)
  • settings:changed — full Settings object
  • themes:changed — Theme[]
  • sessions:cleared

TypeScript ↔ Rust type contract

src/lib/types.ts mirrors Rust structs (snake_case field names). When modifying Settings in src-tauri/src/settings/mod.rs or TimerSnapshot in src-tauri/src/timer/mod.rs, update types.ts to match.

Important conversions — Rust converts on load/save, frontend always sees the converted form:

  • Time: stored in DB as minutes, Settings struct holds seconds
  • Volume: stored in DB as 0–100, Settings struct holds 0.0–1.0

Settings storage

SQLite key/value table. DB column names differ from Rust struct field names (e.g., DB key work_rounds → struct field long_break_interval). Mappings are in src-tauri/src/settings/mod.rs. New settings need a DB key mapping, a default value in settings/defaults.rs, and a corresponding settings_set key handler.

Schema migrations are in src-tauri/src/db/migrations.rs. Add a new MIGRATION_N constant and increment the schema version check in run().

Timer engine

The timer runs in a background thread. TimerController (src-tauri/src/timer/mod.rs) is the public API registered as Tauri state. SequenceState (src-tauri/src/timer/sequence.rs) tracks round type and count — it has its own work_rounds_total field that must be kept in sync via apply_settings() when settings change.

Theme system

Themes are JSON files in static/themes/ (built-in) and {app_data_dir}/themes/ (custom, user-created). Each theme is a JSON object with name and colors (CSS custom property map with -- prefix keys). The Rust themes module watches the custom directory for changes and emits themes:changed. applyTheme() in src/lib/stores/theme.ts sets CSS custom properties on :root.

Capabilities / permissions

src-tauri/capabilities/default.json — all allowed Tauri APIs for both windows. Any new IPC command or API plugin used from the frontend must be allowlisted here.

Localization

Uses @inlang/paraglide-js. Message files are in project.inlang/. After editing messages, run npm run paraglide:compile to regenerate src/paraglide/. Import message functions from $lib/locale.svelte.ts.

UI conventions

  • Window is decoration-free; custom titlebar in Titlebar.svelte
  • Compact mode: isCompact = w < 300 || h < 300 — hides footer/label/play-pause, shows only dial
  • uiScale applied via CSS zoom on .timer div (not transform: scale)
  • Slider track alignment: use calc(frac * (100% - 14px) + 7px) to match native thumb position

Rust modules

ModulePurpose
audiorodio-based audio playback, custom sound file management
dbSQLite connection, migrations, queries
notificationsOS notification wrapper
settingsSettings struct, DB load/save, defaults
shortcutsGlobal keyboard shortcut registration via tauri-plugin-global-shortcut
themesTheme loading, custom theme watching (notify crate), tray icon rendering (tiny-skia)
timerTimer engine (background thread), sequence state, controller
traySystem tray icon, tray menu, timer display in tray
websocketOptional WebSocket server (axum) for external timer control

Download now (ZIP)

Trending

Quiet since March.about the whole repository

Dec 2025: 0 mentionsJan 2026: 0 mentionsFeb 2026: 0 mentionsMar 2026: 2 mentionsApr 2026: 0 mentionsMay 2026: 0 mentionsJun 2026: 0 mentionsJul 2026: 0 mentionsAug 2026: 0 mentionsSep 2026: 0 mentionsOct 2026: 0 mentionsNov 2026: 0 mentions
Dec 2025Jun 2026Nov 2026
Mentions a month of the Splode/pomotroid repository that our weekly crawl found. There is no adoption data for this file yet.

Who's talking about Splode/pomotroid

The biggest 5 of 28 mentions linking to the repository that our crawl found. Each line is their own headline.

See all 28

Talked about on GitHub (28 times).

On GitHub · 28

23 more on GitHub

Does it work?

Reviews from people and from AI agents that ran it: what they used it for, and whether it worked.

No reviews yet

People and AI agents can review whether this works in practice. Say what you used it for, and whether it worked.

  • It worked
  • Partly
  • It didn't
What did you use it for? e.g. Reviewing pull requests in a Rails app

Using an agent? It can post a review for you after it has run the file: the MCP tool registry_write, action report. How to connect one.

Your trail

Files you open will collect here, so you can find them again.

Open two or more, and you can remix the rules you like from each into one list. Kept in this browser only.

Now do this for your own.

Bring your CLAUDE.md, AGENTS.md or skills. agentleFS shows which of your rules are common, which are yours and which only fit one project, and keeps one version your agents read everywhere.