This file provides guidance to AI assistants when working with the Pomodoro Timer project.
Pomodoro Timer is a productivity application implementing the Pomodoro Technique:
- 25-minute work sessions (Pomodoros)
- 5-minute short breaks
- 15-minute long breaks (after 4 Pomodoros)
- Session tracking and statistics
- Visual timer with notifications
Vision: Help users improve focus and productivity through structured time management, with a clean, distraction-free interface.
Learning Goals (This is an Amplifier tutorial project):
- Experience the complete DDD workflow (
/ddd:1-planthrough/ddd:5-finish) - Understand modular design principles
- Practice AI-assisted design iteration (
/designer) - Build a complete, working application in 1-2 hours
This project inherits core principles from the parent Amplifier project. Always reference:
../AGENTS.md- Core development guidelines../DISCOVERIES.md- Known issues and solutions../ai_context/IMPLEMENTATION_PHILOSOPHY.md- Ruthless simplicity principles../ai_context/MODULAR_DESIGN_PHILOSOPHY.md- Bricks and studs approach
Key inherited principles:
- Ruthless simplicity over complexity
- Modular "bricks and studs" design
- Zero-BS principle (no stubs, placeholders, or TODOs)
- Purpose-driven execution
- Design for humans (accessibility, usability)
- Language: Python 3.11+
- Data Storage: JSON files (simple, human-readable)
- Time Management: Python's
timeanddatetimemodules - Notifications: OS-level notifications (cross-platform)
Option 1: Streamlit (Recommended for quick start)
- Pros: Fast development, Python-only, built-in reactivity
- Cons: Less control over animations, refresh-based updates
Option 2: HTML/CSS/JavaScript
- Pros: Rich animations, precise timer display, better UX control
- Cons: Requires JavaScript knowledge, more setup
pomodoro-timer/
├── AGENTS.md # This file
├── README.md # User-facing documentation
├── DESIGN.md # Design decisions and rationale
├── pomodoro/ # Main package
│ ├── __init__.py
│ ├── models.py # Timer, Session, Statistics models
│ ├── timer.py # Timer logic and state management
│ ├── storage.py # JSON persistence
│ ├── notifications.py # OS notification system
│ └── stats.py # Statistics calculation
├── ui/ # User interface
│ ├── app.py # Main application entry point
│ └── components/ # Reusable UI components
├── data/ # Session data storage (gitignored)
│ └── sessions.json
└── tests/ # Test suite
├── test_timer.py
├── test_storage.py
└── test_stats.py
Core Principle: Timer state must be simple and predictable.
States:
IDLE- No active timerWORKING- 25-minute work sessionSHORT_BREAK- 5-minute breakLONG_BREAK- 15-minute breakPAUSED- Timer paused (preserve remaining time)
Critical Requirements:
- State transitions must be explicit and logged
- Remaining time must persist across pauses
- Completed sessions must be immediately saved (incremental processing pattern)
- No silent failures - log all state changes
Anti-pattern:
# DON'T: Complex state with nested conditions
if timer.is_running and not timer.is_paused and timer.mode == "work":
...Good pattern:
# DO: Clear state enum with explicit transitions
class TimerState(Enum):
IDLE = "idle"
WORKING = "working"
SHORT_BREAK = "short_break"
LONG_BREAK = "long_break"
PAUSED = "paused"
def transition_to(new_state: TimerState, reason: str):
logger.info(f"Timer: {self.state} → {new_state} ({reason})")
self.state = new_stateIncremental Processing Pattern (inherited from parent):
- Save after every session completion - Don't batch writes
- Fixed filename:
sessions.json(overwrite, don't timestamp) - Enable interruption: Users can stop app anytime without data loss
- Atomic writes: Write to temp file, then rename (prevents corruption)
Example:
def save_session(session: Session):
"""Save completed session immediately."""
sessions = load_all_sessions()
sessions.append(session)
# Atomic write (inherited pattern)
temp_path = DATA_PATH.with_suffix('.json.tmp')
with open(temp_path, 'w') as f:
json.dump(sessions, f, indent=2)
temp_path.rename(DATA_PATH) # Atomic on POSIX systemsPrinciple: Notifications should be helpful, not annoying.
Requirements:
- Sound should be optional (configurable)
- Visual notification even if sound is off
- Clear message: "Pomodoro complete! Time for a 5-minute break."
- Notification should persist until acknowledged
- Respect OS notification settings
User Control:
- Allow disabling sound
- Allow disabling notifications entirely
- Provide visual-only mode (for quiet environments)
Principle: Show meaningful data, not vanity metrics.
Focus on:
- Today's focus time: Total minutes in work sessions
- Completed Pomodoros: Count of 25-minute sessions finished
- Streak: Consecutive days with at least 1 Pomodoro
- Weekly overview: Visual chart of daily Pomodoros
Avoid:
- Complex aggregations (percentiles, moving averages)
- Gamification that encourages overwork
- Comparing users (this is personal productivity)
Visual Hierarchy:
- Timer display - Large, immediately visible (most important)
- Current state - "Working" or "Break" (context)
- Progress indicator - Circular or linear progress bar
- Action button - Start/Pause/Stop (single clear action)
- Today's stats - Small, non-distracting summary
- Settings - Accessible but not prominent
Motion Design:
- Smooth countdown animation (no jumpy updates)
- Progress bar should feel continuous (60fps if possible)
- State transitions should be visually clear (color changes, icons)
- Avoid distracting animations during work sessions
Accessibility:
- High contrast timer text (minimum 7:1 ratio)
- Large touch targets for mobile (44×44px minimum)
- Keyboard shortcuts (Space = Start/Pause, Esc = Stop)
- Screen reader support for timer state
- Respect
prefers-reduced-motion(disable animations)
Key Decisions to Make:
- Frontend choice: Streamlit vs HTML/CSS/JS
- Consider: Development speed, UX requirements, animation needs
- Timer precision: Second-level vs minute-level display
- Notification approach: OS-native vs in-app
- Data schema: Session model structure
- Statistics scope: Which metrics to include
Expected Output:
- Technology stack decision with rationale
- Data model design (Timer, Session, Statistics)
- Module breakdown (timer, storage, notifications, stats, ui)
- User flow diagram (start → work → break → repeat)
Critical Documents:
- README.md:
- Installation instructions
- Usage guide
- Configuration options
- DESIGN.md:
- Architecture decisions
- State machine diagram
- Data flow
- Module responsibilities
- Module specifications:
- Each module's purpose, inputs, outputs, dependencies
- Public API (the "studs" that other modules connect to)
Implementation Order (suggested):
- Models (
models.py) - Data structures first - Storage (
storage.py) - Persistence layer - Timer (
timer.py) - Core business logic - Statistics (
stats.py) - Calculations based on sessions - Notifications (
notifications.py) - External integration - UI (
ui/app.py) - Presentation layer
Rationale: Build from data → logic → presentation (inside-out approach)
Module-by-Module Generation:
- Generate complete modules, not fragments
- Include tests alongside implementation
- Follow "Zero-BS Principle" - no TODOs or placeholders
- Each module should be immediately runnable/testable
Validation After Each Module:
- Run tests to verify correctness
- Check imports and dependencies
- Ensure type hints are complete
- Verify against module specification from Phase 2
Focus Areas:
- Timer Visual Design:
- Font size and readability
- Progress indicator style (circular vs linear)
- Color scheme (work vs break states)
- Layout Optimization:
- White space and hierarchy
- Mobile responsiveness
- Button placement and sizing
- Accessibility Review:
- Color contrast validation
- Keyboard navigation
- Screen reader compatibility
- Micro-interactions:
- Button hover states
- Timer completion animations
- Notification styling
Design Principles to Apply:
- Purpose Drives Execution: Every design choice serves user focus
- Craft Embeds Care: Attention to typography, spacing, timing
- Constraints Enable Creativity: Work within platform limitations
- Design for Humans: Accessibility is non-negotiable
Final Checklist:
- All modules implemented and tested
- README.md complete with examples
- DESIGN.md reflects final architecture
- No temporary files or debug code
- Data directory properly .gitignored
- Cross-platform compatibility verified (Windows, macOS, Linux)
- Accessibility validated
- Performance acceptable (timer updates smoothly)
- Timer logic: State transitions, time calculations
- Storage: Load/save operations, error handling
- Statistics: Calculation correctness, edge cases
- Timer + Storage: Session persistence
- Timer + Notifications: Trigger on completion
- Stats + Storage: Calculate from saved sessions
- Timer accuracy: Does 25 minutes actually take 25 minutes?
- Notification delivery: Do OS notifications appear?
- UI responsiveness: Does the interface feel smooth?
- Cross-platform: Test on different operating systems
- Critical paths: 100% (timer logic, data persistence)
- Overall: 80%+ (use pytest-cov to measure)
Problem: Using sleep() accumulates drift over long periods.
Solution: Calculate target end time at start, check against it each iteration.
# DON'T: Accumulates drift
for _ in range(1500): # 25 minutes = 1500 seconds
time.sleep(1)
update_display()
# DO: Check against target time
end_time = time.time() + 1500
while time.time() < end_time:
remaining = int(end_time - time.time())
update_display(remaining)
time.sleep(0.1) # Check frequentlyProblem: Timer logic blocks the UI thread. Solution: Use threading or async for timer countdown.
# Streamlit: Use session state + auto-refresh
# HTML/JS: Use JavaScript intervals + AJAX/WebSockets for state syncProblem: Saving sessions only at app exit loses data. Solution: Save immediately after each session completes (incremental processing).
Problem: Complex aggregations slow down the app. Solution: Calculate only what's displayed, cache if necessary.
Default Configuration (config.json or hardcoded):
{
"work_duration": 1500, // 25 minutes in seconds
"short_break": 300, // 5 minutes
"long_break": 900, // 15 minutes
"pomodoros_until_long_break": 4,
"sound_enabled": true,
"notification_enabled": true,
"auto_start_break": false // Automatically start break after work session
}Customization:
- Allow users to adjust durations (but warn if deviating from classic 25/5/15)
- Provide presets: "Classic", "Short" (15/3/10), "Long" (50/10/30)
- Save user preferences in
user_config.json(separate from default)
- Minimum contrast ratio: 7:1 for timer text (large, critical)
- Color independence: Don't rely on color alone (use icons + text)
- Font size: Timer should be at least 48px (readable from distance)
- Touch targets: Minimum 44×44px (mobile friendly)
- Keyboard shortcuts:
Space: Start/Pause timerEscape: Stop and reset timerB: Start break manuallyS: Open statistics view
- Visual alternatives: Always show visual notification alongside sound
- Configurable sound: Allow disabling or choosing notification sound
- Clear state: Always show current state ("Working", "Break", "Paused")
- Simple controls: One primary action button (context-sensitive)
- Predictable behavior: Timer always counts down, no surprises
Follow parent project conventions with project-specific tags:
feat(timer): Implement Pomodoro countdown logic
fix(storage): Prevent data loss on app crash
docs(readme): Add installation instructions for Windows
style(ui): Improve timer display contrast ratio
test(stats): Add tests for weekly statistics calculation
Always append:
🤖 Generated with [Amplifier](https://github.com/microsoft/amplifier)
Co-Authored-By: Amplifier <240397093+microsoft-amplifier@users.noreply.github.com>
- Timer update frequency: 10 Hz (0.1s intervals) for smooth visual updates
- UI responsiveness: Button clicks register within 100ms
- Session save time: < 50ms (even with 1000+ sessions)
- Statistics calculation: < 200ms for 30 days of data
- App startup time: < 1 second
If performance degrades:
- Profile with
cProfileorpy-spy - Check for blocking I/O operations
- Consider caching statistics calculations
- Optimize data structures (e.g., index sessions by date)
- All data stays local: No external servers or cloud sync
- No telemetry: App doesn't phone home
- Clear data ownership: User owns their session data
- sessions.json: Read/write by user only (chmod 600)
- config.json: Read-only after initial setup (chmod 444)
- Configuration values: Validate duration ranges (1-180 minutes)
- File paths: Sanitize to prevent directory traversal
- JSON parsing: Handle malformed data gracefully
Once the core is complete, users might explore:
- Cloud sync: Multi-device session sync via Firebase/Supabase
- Integrations: Export to Notion, Todoist, Google Calendar
- Advanced statistics: Productivity trends, focus patterns
- Theming: Dark mode, custom color schemes
- Social features: Share daily Pomodoro count with accountability partners
Important: These are FUTURE ideas. Don't implement them unless explicitly requested. Focus on nailing the core experience first.
By completing this project, users will:
- ✅ Experience the full DDD workflow
- ✅ Understand state machine design
- ✅ Practice data persistence patterns
- ✅ Apply UI/UX design principles
- ✅ Implement accessible interfaces
- ✅ Test time-based logic
- ✅ Build a complete, usable application
Most importantly: Users will see how Amplifier's philosophy (simplicity, modularity, purpose-driven design) creates better software faster.
- Check parent project:
../AGENTS.mdfor general guidelines../DISCOVERIES.mdfor known issues
- Consult design resources:
../ai_context/IMPLEMENTATION_PHILOSOPHY.md../ai_context/MODULAR_DESIGN_PHILOSOPHY.md
- Ask for clarification: If requirements are unclear, ask before implementing
- Ruthless simplicity: Don't over-engineer
- Purpose-driven: Every feature serves user focus
- Accessible: Design for all users, not ideal ones
- Testable: Write tests as you build
- Documented: Explain decisions, not just code
This is a learning project. The journey matters as much as the destination.