pomodoro-dashboard
Browser-only Pomodoro timer SPA with task tracking, focus stats, and a 12-week activity heatmap. All data stored in localStorage. No backend required.
Best use case
pomodoro-dashboard is best used when you need a repeatable AI agent workflow instead of a one-off prompt.
Browser-only Pomodoro timer SPA with task tracking, focus stats, and a 12-week activity heatmap. All data stored in localStorage. No backend required.
Teams using pomodoro-dashboard should expect a more consistent output, faster repeated execution, less prompt rewriting.
When to use this skill
- You want a reusable workflow that can be run more than once with consistent structure.
When not to use this skill
- You only need a quick one-off answer and do not need a reusable workflow.
- You cannot install or maintain the underlying files, dependencies, or repository context.
Installation
Claude Code / Cursor / Codex
Manual Installation
- Download SKILL.md from GitHub
- Place it in
.claude/skills/pomodoro-dashboard/SKILL.mdinside your project - Restart your AI agent — it will auto-discover the skill
How pomodoro-dashboard Compares
| Feature / Agent | pomodoro-dashboard | Standard Approach |
|---|---|---|
| Platform Support | Not specified | Limited / Varies |
| Context Awareness | High | Baseline |
| Installation Complexity | Unknown | N/A |
Frequently Asked Questions
What does this skill do?
Browser-only Pomodoro timer SPA with task tracking, focus stats, and a 12-week activity heatmap. All data stored in localStorage. No backend required.
Where can I find the source code?
You can find the source code on GitHub using the link provided at the top of the page.
SKILL.md Source
# pomodoro-dashboard Skill
## When to use
Use this skill when you need to:
- Start or configure a Pomodoro timer session
- Manage tasks linked to focus sessions
- View focus stats, streaks, and heatmap data
- Understand the localStorage data schema
- Customize timer durations or sounds
## Prerequisites
No server required. Open `dist/index.html` or run:
```
pnpm dev
```
Then open http://localhost:5173 in your browser.
Or build and serve statically:
```
pnpm build
npx serve dist
```
## Quick start
1. Open the app in a browser
2. Add a task on the Tasks page
3. Click "Set active" on the task
4. Press Start on the Dashboard (or press Space)
5. Work until the alarm sounds
6. Take your break
7. Repeat
## Timer controls
| Action | Button | Keyboard |
|---|---|---|
| Start / Pause | Start / Pause button | Space |
| Reset to full duration | Reset button | R |
| Skip to next phase | Skip button | S |
## Phase sequence
```
Focus (25 min)
-> Short Break (5 min)
Focus
-> Short Break
Focus
-> Short Break
Focus (4th)
-> Long Break (15 min)
Focus (cycle repeats)
```
After the long break, `pomodoroCount` resets to 0.
## localStorage schema
All keys prefixed `pomo_`. Data is plain JSON.
### pomo_settings
```json
{
"pomodoroDuration": 25,
"shortBreakDuration": 5,
"longBreakDuration": 15,
"longBreakInterval": 4,
"autoStartBreaks": true,
"autoStartPomodoros": false,
"tickSound": false,
"alarmSound": true,
"alarmVolume": 0.7,
"desktopNotifications": true,
"theme": "system"
}
```
### pomo_tasks (array)
```json
[
{
"id": "uuid",
"title": "Write project proposal",
"estimatedPomodoros": 4,
"completedPomodoros": 2,
"done": false,
"createdAt": "2026-03-20T09:00:00.000Z",
"completedAt": null
}
]
```
### pomo_sessions (array)
```json
[
{
"id": "uuid",
"type": "pomodoro",
"taskId": "uuid-of-task-or-null",
"startedAt": "2026-03-20T13:00:00.000Z",
"completedAt": "2026-03-20T13:25:00.000Z",
"durationMinutes": 25,
"interrupted": false
}
]
```
### pomo_state (current timer)
```json
{
"phase": "pomodoro",
"endTime": 1742475900000,
"remainingMs": 873000,
"paused": false,
"pomodoroCount": 2,
"activeTaskId": "uuid-or-null"
}
```
## Reading stats from console
```javascript
// Total sessions
JSON.parse(localStorage.getItem('pomo_sessions') || '[]').length
// Today's pomodoros
JSON.parse(localStorage.getItem('pomo_sessions') || '[]')
.filter(s => s.type === 'pomodoro' && s.completedAt?.startsWith('2026-03-20'))
.length
// All tasks
JSON.parse(localStorage.getItem('pomo_tasks') || '[]')
```
## Exporting data
Sessions and tasks can be exported by copying localStorage values:
```javascript
// In browser console:
const data = {
sessions: JSON.parse(localStorage.getItem('pomo_sessions') || '[]'),
tasks: JSON.parse(localStorage.getItem('pomo_tasks') || '[]'),
settings: JSON.parse(localStorage.getItem('pomo_settings') || '{}'),
};
console.log(JSON.stringify(data, null, 2));
```
## Importing data
```javascript
// Restore sessions from backup JSON string
localStorage.setItem('pomo_sessions', JSON.stringify(sessions));
localStorage.setItem('pomo_tasks', JSON.stringify(tasks));
// Reload the page
location.reload();
```
## Resetting data
```javascript
// Clear all pomodoro data
Object.keys(localStorage)
.filter(k => k.startsWith('pomo_'))
.forEach(k => localStorage.removeItem(k));
location.reload();
```
## Behavior notes
- The timer uses `Date.now()` snapshots, not cumulative interval ticks. It survives tab backgrounding and device sleep without drift.
- Audio requires a user gesture to initialize (browser policy). The AudioContext is resumed on the first click anywhere.
- Desktop notification permission is requested only when the user enables the setting, never on page load.
- Sessions are never deleted. The history grows indefinitely and forms the basis for the heatmap.
- Closing the tab while the timer is running: on next load, `pomo_state` is restored and the timer resumes from the correct remaining time.
## Troubleshooting
**Timer shows wrong remaining time after reload**
- Check `pomo_state` in localStorage. If `endTime` is in the past and `paused` is false, the session should be marked as interrupted on next load.
**No sound on timer completion**
- Click anywhere on the page first to resume the AudioContext
- Check that "Alarm sound" is enabled in Settings
- Check browser permissions for audio
**Notifications not appearing**
- Check that "Desktop notifications" is enabled in Settings
- Check browser notification permissions for the site
- Ensure the tab is not in focus (browsers often suppress notifications when the tab is active)Related Skills
vitals-dashboard
Track blood pressure, heart rate, weight, blood glucose, and temperature over time with target range bands, trend analysis, alerts for out-of-range readings, correlation analysis, and CSV/PDF export. Use when a user needs to log vital sign readings, review trends, acknowledge alerts, or produce a health summary report.
home-sensor-dashboard
No description provided.
time-series-dashboard
Manage dashboards, metrics, alert rules, and query time-series data in the time-series-dashboard application. Use this skill for all operations against the running server.
weather-station-dashboard
Query live and historical weather sensor data, manage stations and alert thresholds, and retrieve daily summaries. Use when asked to check current temperature, view recent readings for a station, find the highest temperature recorded this week, dismiss an active alert, list which stations are online, or retrieve today's daily summary. Triggers include "current temperature", "sensor readings", "station status", "alert history", "daily summary", "wind speed", "humidity", "rainfall total", or any query about live or historical weather data.
Skill: Uptime Monitoring
## Overview
Skill: Status Page
## Overview
Skill: unit-conversion
## Overview
Skill: recipe-scaler
## Overview
reading-list
Operate the reading-list API to save, manage, tag, search, and export articles.
email-digest
Configure, test, and troubleshoot the reading-list daily email digest delivered via nodemailer.
websocket-realtime
Use the WebSocket connection in poll-builder to receive live vote updates. Use when you need to stream real-time poll results, monitor a poll for new votes, or build a live dashboard. Triggers include "live results", "real-time updates", "stream votes", "watch poll", or "WebSocket".
poll-builder
Self-hosted poll creation tool with real-time results. Use when you need to create a poll, check vote counts, close a poll, export results, or get the shareable link for a poll. Triggers include "create poll", "vote", "poll results", "survey", "collect votes", "share poll", or any task involving polling or voting.