Generated: 2025-11-22T22:40:00+09:00 Based on: Phase 1 plan + Phase 2 documentation Project: Pomodoro Timer - Simple productivity tool
これは完全な新規実装プロジェクトです。現在、ドキュメントファイル(README.md, DESIGN.md, pyproject.toml, .gitignore)のみが存在し、コードファイルは一切存在しません。
Phase 2で作成したDESIGN.mdの仕様に基づき、すべてのコードファイルとディレクトリ構造を一から構築します。
実装スコープ:
- Core modules: 6ファイル(models, storage, timer, stats, notifications, + init.py)
- UI layer: 5ファイル(app, components × 2, + init.py × 2)
- Tests: 5ファイル(unit tests × 4 + init.py)
- Configuration: 1ファイル(data/.gitkeep)
- Total: 17ファイル + 4ディレクトリ
まず、以下のディレクトリ構造を作成します:
pomodoro-timer/
├── pomodoro/ # Core business logic
│ └── __init__.py
├── ui/ # Streamlit UI
│ ├── components/
│ │ └── __init__.py
│ └── __init__.py
├── tests/ # Test suite
│ └── __init__.py
└── data/ # Session storage (gitignored)
└── .gitkeep
Current State: 存在しない
Required Changes: パッケージ初期化ファイルを作成
Implementation:
"""Pomodoro Timer - Core business logic package.
This package contains the core functionality for the Pomodoro Timer application:
- Data models (models.py)
- Timer logic (timer.py)
- Storage persistence (storage.py)
- Statistics calculation (stats.py)
- OS notifications (notifications.py)
"""
__version__ = "0.1.0"Dependencies: なし Agent Suggestion: modular-builder Tests: なし(パッケージマーカーのみ)
Current State: 存在しない
Required Changes: データモデルを定義(DESIGN.md lines 131-164参照)
Specific Implementation:
"""Data models for Pomodoro Timer.
Defines the core data structures used throughout the application.
"""
from dataclasses import dataclass
from datetime import datetime
@dataclass
class Session:
"""Represents a completed Pomodoro session.
Attributes:
id: Unique session identifier (UUID string)
type: Session type - "work", "short_break", or "long_break"
start_time: When the session started
end_time: When the session completed
completed: Whether session was completed (vs interrupted)
duration_seconds: Actual duration in seconds
"""
id: str
type: str # "work", "short_break", "long_break"
start_time: datetime
end_time: datetime
completed: bool
duration_seconds: int
@dataclass
class TimerConfig:
"""Configuration for timer durations and behavior.
Default values follow classic Pomodoro Technique:
- 25 minute work sessions
- 5 minute short breaks
- 15 minute long breaks every 4 pomodoros
"""
work_duration: int = 1500 # 25 minutes
short_break: int = 300 # 5 minutes
long_break: int = 900 # 15 minutes
pomodoros_until_long_break: int = 4
sound_enabled: bool = True
notification_enabled: bool = TrueDependencies: 標準ライブラリのみ
Agent Suggestion: modular-builder
Tests: tests/test_models.py
Current State: 存在しない
Required Changes: JSONファイル永続化を実装(DESIGN.md lines 166-206参照)
Specific Implementation:
save_session(session: Session) -> None: アトミックライトパターンで保存load_sessions(start_date, end_date) -> list[Session]: 日付範囲でフィルタリングget_sessions_today() -> list[Session]: 今日のセッションを取得- 内部ヘルパー:
_load_all_sessions(),_deserialize_session()
Key Patterns:
-
Atomic Write:
temp_path = DATA_PATH.with_suffix('.json.tmp') with open(temp_path, 'w') as f: json.dump(data, f, indent=2) temp_path.rename(DATA_PATH) # Atomic on POSIX
-
Incremental Save: セッション完了ごとに即座に保存
-
Date Filtering:
datetime.date()で日付比較
Dependencies: models.py, 標準ライブラリ(json, pathlib, datetime)
Agent Suggestion: modular-builder
Tests: tests/test_storage.py
Current State: 存在しない
Required Changes: タイマーコアロジックを実装(DESIGN.md lines 208-250参照)
Specific Implementation:
Classes:
TimerState(Enum): IDLE, WORKING, SHORT_BREAK, LONG_BREAK, PAUSEDPomodoroTimer: メインタイマークラス
Methods:
start() -> None: タイマー開始(IDLE → WORKING)pause() -> int: 一時停止、残り秒数を返すresume() -> None: 再開(PAUSED → WORKING)stop() -> None: 停止してリセット(Any → IDLE)get_state() -> TimerState: 現在の状態を取得get_remaining() -> int: 残り秒数を取得is_complete() -> bool: セッション完了判定
Key Implementation Details:
-
Drift-Free Timer:
end_time = time.time() + duration_seconds while time.time() < end_time: remaining = int(end_time - time.time()) # Update display time.sleep(0.1) # Check frequently
-
State Machine: 明示的な状態遷移ログ
-
Auto-Save: セッション完了時に
storage.save_session()呼び出し -
Pomodoro Counting: 作業セッション完了数をカウント、4回目で長休憩
Dependencies: models.py, storage.py, notifications.py
Agent Suggestion: modular-builder
Tests: tests/test_timer.py
Current State: 存在しない
Required Changes: 統計計算を実装(DESIGN.md lines 252-284参照)
Specific Implementation:
Functions:
calculate_today_stats() -> dict: 今日の集中時間と完了ポモドーロ数calculate_streak() -> int: 連続日数計算calculate_weekly_overview() -> dict[str, int]: 過去7日間の日別ポモドーロ数
Algorithm Notes:
-
Today Stats:
storage.get_sessions_today()でセッション取得type == "work"のみカウントduration_secondsを合計して分に変換
-
Streak Calculation:
- 各日付の作業セッション数を集計
- 今日から遡って連続日数をカウント
- 0ポモドーロの日でストリーク終了
-
Weekly Overview:
- 過去7日間のセッションを読み込み
- 日付別にグループ化
- 作業セッション数をカウント
Dependencies: models.py, storage.py
Agent Suggestion: modular-builder
Tests: tests/test_stats.py
Current State: 存在しない
Required Changes: OS通知システムを実装(DESIGN.md lines 286-324参照)
Specific Implementation:
Functions:
notify_session_complete(session_type: str) -> Nonenotify_break_complete() -> None
Key Details:
from plyer import notification
def notify_session_complete(session_type: str) -> None:
"""セッション完了通知を表示。
Args:
session_type: "work", "short_break", "long_break"
"""
if session_type == "work":
title = "ポモドーロ完了!"
message = "よくできました!5分休憩しましょう。"
elif session_type == "short_break":
title = "休憩完了!"
message = "さあ、次のポモドーロを始めましょう。"
else: # long_break
title = "長休憩完了!"
message = "リフレッシュできましたか?作業を再開しましょう。"
notification.notify(
title=title,
message=message,
app_name="Pomodoro Timer",
timeout=10
)Dependencies: plyer
Agent Suggestion: modular-builder
Tests: 手動テスト(OS通知が実際に表示されるか)
Current State: 存在しない
Required Changes: UIパッケージ初期化
Implementation:
"""Pomodoro Timer - User Interface package.
Streamlit-based UI for the Pomodoro Timer application.
"""Dependencies: なし Agent Suggestion: modular-builder Tests: なし
Current State: 存在しない
Required Changes: メインStreamlitアプリケーションを実装(DESIGN.md lines 326-355参照)
Specific Implementation:
Structure:
import streamlit as st
from pomodoro.timer import PomodoroTimer, TimerState
from pomodoro import stats
from ui.components import timer_display, stats_display
def main():
"""メインアプリケーション。"""
st.set_page_config(page_title="Pomodoro Timer", layout="wide")
# セッション状態の初期化
initialize_session_state()
# タイマー表示
timer_display.render()
# コントロールボタン
render_controls()
# 統計表示
stats_display.render()
# 設定パネル(サイドバー)
render_settings()
def initialize_session_state():
"""Streamlitセッション状態を初期化。"""
if 'timer' not in st.session_state:
st.session_state.timer = PomodoroTimer()
# その他の状態変数...
def render_controls():
"""タイマーコントロールボタンを表示。"""
col1, col2, col3 = st.columns(3)
with col1:
if st.button("Start", key="start_btn"):
st.session_state.timer.start()
# ...
def render_settings():
"""設定パネルをサイドバーに表示。"""
with st.sidebar:
st.header("設定")
# TimerConfigの編集UI
# ...
if __name__ == "__main__":
main()Key Features:
- セッション状態によるタイマー永続化
- 0.1秒ごとの自動リフレッシュ(
st.rerun()) - キーボードショートカット(Space, Esc, B, S)
- 設定の編集と保存
Dependencies: すべてのビジネスロジックモジュール、Streamlit Agent Suggestion: modular-builder Tests: 手動テスト(UIの動作確認)
Current State: 存在しない
Required Changes: コンポーネントパッケージ初期化
Implementation:
"""UI components for Pomodoro Timer."""Dependencies: なし Agent Suggestion: modular-builder Tests: なし
Current State: 存在しない
Required Changes: タイマー表示コンポーネントを実装
Specific Implementation:
"""Timer display component."""
import streamlit as st
from pomodoro.timer import TimerState
def render():
"""タイマー表示をレンダリング。
大きく読みやすいフォントで残り時間を表示。
- 7:1コントラスト比(アクセシビリティ)
- MM:SS形式
- 状態に応じた色分け(作業=青、休憩=緑)
"""
timer = st.session_state.timer
remaining = timer.get_remaining()
state = timer.get_state()
# MM:SS形式に変換
minutes = remaining // 60
seconds = remaining % 60
time_str = f"{minutes:02d}:{seconds:02d}"
# 状態に応じた色とメッセージ
if state == TimerState.WORKING:
st.markdown(f"<h1 style='color: #1E3A8A;'>{time_str}</h1>", unsafe_allow_html=True)
st.write("作業中...")
elif state == TimerState.SHORT_BREAK:
st.markdown(f"<h1 style='color: #166534;'>{time_str}</h1>", unsafe_allow_html=True)
st.write("短い休憩")
# ...Dependencies: Streamlit, pomodoro.timer
Agent Suggestion: modular-builder
Tests: 手動テスト(表示の確認)
Current State: 存在しない
Required Changes: 統計表示コンポーネントを実装
Specific Implementation:
"""Statistics display component."""
import streamlit as st
from pomodoro import stats
def render():
"""統計をレンダリング。
表示内容:
- 今日の集中時間(分)
- 完了ポモドーロ数
- 連続日数
- 週間概要(バーチャート)
"""
st.header("統計")
# 今日の統計
today = stats.calculate_today_stats()
col1, col2 = st.columns(2)
with col1:
st.metric("今日の集中時間", f"{today['focus_time']}分")
with col2:
st.metric("完了ポモドーロ", today['completed_pomodoros'])
# 連続日数
streak = stats.calculate_streak()
st.metric("連続日数", f"{streak}日")
# 週間概要
weekly = stats.calculate_weekly_overview()
st.bar_chart(weekly)Dependencies: Streamlit, pomodoro.stats
Agent Suggestion: modular-builder
Tests: 手動テスト(統計の正確性)
Current State: 存在しない
Required Changes: テストパッケージ初期化
Implementation:
"""Test suite for Pomodoro Timer."""Dependencies: なし Agent Suggestion: modular-builder Tests: なし
Current State: 存在しない
Required Changes: データモデルのユニットテスト
Specific Tests:
"""Unit tests for data models."""
from datetime import datetime
from pomodoro.models import Session, TimerConfig
def test_session_creation():
"""Sessionデータクラスが正しく作成されるか。"""
session = Session(
id="test-123",
type="work",
start_time=datetime.now(),
end_time=datetime.now(),
completed=True,
duration_seconds=1500
)
assert session.id == "test-123"
assert session.type == "work"
assert session.completed is True
def test_timer_config_defaults():
"""TimerConfigのデフォルト値が正しいか。"""
config = TimerConfig()
assert config.work_duration == 1500
assert config.short_break == 300
assert config.long_break == 900
assert config.pomodoros_until_long_break == 4
def test_session_serialization():
"""Sessionをdictにシリアライズできるか。"""
# dataclasses.asdict()を使用
# ...Dependencies: pomodoro.models, pytest
Agent Suggestion: test-coverage
Tests: 自己テスト
Current State: 存在しない
Required Changes: ストレージ永続化のユニットテスト
Specific Tests:
"""Unit tests for storage persistence."""
import pytest
from datetime import datetime, date
from pathlib import Path
from pomodoro.models import Session
from pomodoro import storage
@pytest.fixture
def temp_data_file(tmp_path):
"""一時的なデータファイルを作成。"""
data_file = tmp_path / "sessions.json"
# storage.DATA_PATHを一時的に置き換え
# ...
return data_file
def test_save_and_load_session(temp_data_file):
"""セッションを保存して読み込めるか。"""
session = Session(
id="test-1",
type="work",
start_time=datetime.now(),
end_time=datetime.now(),
completed=True,
duration_seconds=1500
)
storage.save_session(session)
sessions = storage.load_sessions()
assert len(sessions) == 1
assert sessions[0].id == "test-1"
def test_date_filtering(temp_data_file):
"""日付フィルタリングが正しく動作するか。"""
# 異なる日付のセッションを作成
# load_sessions(start_date, end_date)で取得
# フィルタリング結果を検証
# ...
def test_atomic_write(temp_data_file):
"""アトミックライトが正しく動作するか。"""
# 保存中にクラッシュしても既存データが破損しないことを確認
# ...Dependencies: pomodoro.models, pomodoro.storage, pytest
Agent Suggestion: test-coverage
Tests: 自己テスト
Current State: 存在しない
Required Changes: タイマーロジックのユニットテスト
Specific Tests:
"""Unit tests for timer logic."""
import pytest
from unittest.mock import Mock, patch
from pomodoro.timer import PomodoroTimer, TimerState
def test_initial_state():
"""初期状態がIDLEであるか。"""
timer = PomodoroTimer()
assert timer.get_state() == TimerState.IDLE
def test_start_timer():
"""タイマーを開始できるか。"""
timer = PomodoroTimer()
timer.start()
assert timer.get_state() == TimerState.WORKING
def test_pause_resume():
"""一時停止と再開が正しく動作するか。"""
timer = PomodoroTimer()
timer.start()
remaining = timer.pause()
assert timer.get_state() == TimerState.PAUSED
assert remaining > 0
timer.resume()
assert timer.get_state() == TimerState.WORKING
def test_state_transitions():
"""状態遷移が正しく動作するか。"""
# IDLE → WORKING → SHORT_BREAK → WORKING → ...
# 4回目のWORKING完了後に LONG_BREAK
# ...
@patch('pomodoro.storage.save_session')
def test_session_auto_save(mock_save):
"""セッション完了時に自動保存されるか。"""
# タイマー完了をシミュレート
# mock_save が呼ばれたことを確認
# ...Dependencies: pomodoro.timer, pomodoro.models, pytest
Agent Suggestion: test-coverage
Tests: 自己テスト
Current State: 存在しない
Required Changes: 統計計算のユニットテスト
Specific Tests:
"""Unit tests for statistics calculation."""
import pytest
from datetime import datetime, timedelta, date
from pomodoro.models import Session
from pomodoro import stats, storage
@pytest.fixture
def sample_sessions():
"""テスト用のサンプルセッションを作成。"""
sessions = []
# 今日の作業セッション3つ
for i in range(3):
sessions.append(Session(
id=f"today-{i}",
type="work",
start_time=datetime.now() - timedelta(hours=i),
end_time=datetime.now() - timedelta(hours=i) + timedelta(minutes=25),
completed=True,
duration_seconds=1500
))
return sessions
def test_today_stats(sample_sessions):
"""今日の統計が正しく計算されるか。"""
# sample_sessionsを一時的に保存
# stats.calculate_today_stats()を呼び出し
# focus_time = 75分(25×3)
# completed_pomodoros = 3
# ...
def test_streak_calculation():
"""連続日数が正しく計算されるか。"""
# 過去5日間、毎日1ポモドーロのセッションを作成
# calculate_streak()が5を返すことを確認
# ...
def test_weekly_overview():
"""週間概要が正しく計算されるか。"""
# 過去7日間のセッションを作成
# calculate_weekly_overview()の結果を検証
# 日付キーとポモドーロ数のマッピング
# ...Dependencies: pomodoro.models, pomodoro.stats, pomodoro.storage, pytest
Agent Suggestion: test-coverage
Tests: 自己テスト
Current State: 存在しない
Required Changes: データディレクトリを保持するための空ファイル
Implementation: 空ファイル
Purpose: data/ ディレクトリをGitで追跡するが、sessions.jsonは除外(.gitignoreに記載)
Dependencies: なし Agent Suggestion: modular-builder Tests: なし
実装を論理的で独立してテスト可能なチャンクに分割します。
Files:
pomodoro/__init__.pypomodoro/models.pytests/__init__.pytests/test_models.py
Description: 基本的なデータモデルを定義し、テストを作成
Why First: 他のすべてのモジュールがこれらのデータ構造に依存
Test Strategy:
pytest tests/test_models.py -v- データクラスの作成、デフォルト値、シリアライゼーション
Dependencies: なし
Commit Point: すべてのユニットテストがパスした後
Files:
pomodoro/storage.pytests/test_storage.pydata/.gitkeep
Description: JSONファイル永続化を実装
Why Second: タイマーとstatsがストレージに依存
Test Strategy:
pytest tests/test_storage.py -v- 保存/読み込み、日付フィルタリング、アトミックライト
Dependencies: Chunk 1(models)
Commit Point: すべてのストレージテストがパスした後
Files:
pomodoro/notifications.py
Description: OS通知システムを実装
Why Third: タイマーが通知に依存するが、他のモジュールには依存しない
Test Strategy: 手動テスト(OS通知が実際に表示されるか)
Dependencies: なし(plyerライブラリのみ)
Commit Point: 手動テストで通知が確認された後
Files:
pomodoro/timer.pytests/test_timer.py
Description: タイマー状態マシンとカウントダウンロジックを実装
Why Fourth: storage と notifications が完成している必要がある
Test Strategy:
pytest tests/test_timer.py -v- 状態遷移、pause/resume、セッション完了、自動保存
Dependencies: Chunk 1(models)、Chunk 2(storage)、Chunk 3(notifications)
Commit Point: すべてのタイマーテストがパスした後
Files:
pomodoro/stats.pytests/test_stats.py
Description: セッションデータから統計を計算
Why Fifth: storage が完成している必要があるが、UI には依存しない
Test Strategy:
pytest tests/test_stats.py -v- 今日の統計、連続日数、週間概要
Dependencies: Chunk 1(models)、Chunk 2(storage)
Commit Point: すべての統計テストがパスした後
Files:
ui/__init__.pyui/components/__init__.pyui/components/timer_display.pyui/components/stats_display.py
Description: Streamlit UIコンポーネントを実装
Why Sixth: すべてのビジネスロジックが完成している必要がある
Test Strategy: 手動テスト(UIの表示確認)
Dependencies: すべての前チャンク(models, timer, stats)
Commit Point: UIコンポーネントが正しく表示された後
Files:
ui/app.py
Description: メインStreamlitアプリケーションを実装
Why Last: すべてのコンポーネントを統合
Test Strategy: 手動エンドツーエンドテスト
- タイマーの開始/停止
- セッション完了時の通知
- 統計の表示
- 設定の編集
Dependencies: すべての前チャンク
Commit Point: エンドツーエンドテストが成功した後
modular-builder - すべてのモジュール実装:
Task modular-builder: "Implement pomodoro/models.py according to
code_plan.md and DESIGN.md specification"
test-coverage - テスト計画とレビュー:
Task test-coverage: "Review test coverage for pomodoro package
and suggest additional test cases"
bug-hunter - 問題発生時:
Task bug-hunter: "Debug issue with timer drift after 25 minutes"
このプロジェクトは完全に順次的に実装します:
Chunk 1 → Chunk 2 → Chunk 3 → Chunk 4 → Chunk 5 → Chunk 6 → Chunk 7
Rationale: 各チャンクが前のチャンクに依存しているため
Parallel Implementation: なし(依存関係が強い)
test_session_creation()- Sessionデータクラスの作成test_timer_config_defaults()- デフォルト値の検証test_session_serialization()- dict変換
test_save_and_load_session()- 保存/読み込みtest_date_filtering()- 日付範囲フィルタリングtest_atomic_write()- アトミックライトパターンtest_get_sessions_today()- 今日のセッション取得
test_initial_state()- 初期状態IDLEtest_start_timer()- タイマー開始test_pause_resume()- 一時停止と再開test_state_transitions()- 完全な状態遷移サイクルtest_session_auto_save()- セッション完了時の自動保存test_pomodoro_counting()- 4回目で長休憩
test_today_stats()- 今日の集中時間と完了数test_streak_calculation()- 連続日数計算test_weekly_overview()- 週間概要test_empty_sessions()- セッションなしの場合
timer + storage:
- セッション完了時の自動保存
- 保存されたセッションの読み込み
timer + notifications:
- セッション完了時の通知トリガー
stats + storage:
- 保存されたセッションからの統計計算
User Testing Plan:
# アプリケーション起動
uv run streamlit run ui/app.py
# テストシナリオ1: 基本的なタイマー動作
1. "Start"ボタンをクリック
2. タイマーが25:00からカウントダウン開始
3. "Pause"で一時停止
4. "Resume"で再開
5. "Stop"でリセット
# テストシナリオ2: セッション完了
1. タイマー開始
2. 25分待つ(または duration を短縮してテスト)
3. OS通知が表示されることを確認
4. 自動的に休憩に移行することを確認
# テストシナリオ3: 統計表示
1. 複数のポモドーロを完了
2. 統計ビューを開く
3. 今日の集中時間が正しく表示されるか
4. 完了ポモドーロ数が正しいか
# テストシナリオ4: キーボードショートカット
1. Spaceキーでタイマー開始/停止
2. Escキーでリセット
3. Bキーで手動休憩開始
4. Sキーで統計表示切り替えExpected Behavior:
- タイマーがドリフトなく正確にカウント
- 通知がセッション完了時に表示
- 統計が正しく計算され表示
- キーボードショートカットが機能
適用箇所:
- JSONストレージ(データベース不要)
- Streamlit UI(フロントエンドフレームワーク不要)
- 基本統計のみ(高度な分析なし)
- シンプルな状態マシン(複雑なライブラリなし)
実装しないもの:
- ✗ クラウド同期
- ✗ タスク管理統合
- ✗ カスタムアニメーション
- ✗ 高度なレポート
- ✗ チーム機能
各モジュールで:
- 最小限の抽象化
- 明確な責任
- 直接的なAPI
Bricks(自己完結モジュール):
models.py- データ定義のみ、依存なしstorage.py- ファイルI/O、modelsのみ依存notifications.py- OS統合、依存なしtimer.py- タイマーロジック、明確な依存stats.py- 計算ロジック、明確な依存app.py- UI統合、すべてに依存
Studs(接続ポイント):
Session,TimerConfig- データインターフェースsave_session(),load_sessions()- 永続化インターフェースstart(),pause(),stop()- タイマー制御インターフェースcalculate_*()- 統計インターフェースnotify_*()- 通知インターフェース
再生成可能性: 各モジュールは以下から完全に再構築可能:
code_plan.mdの仕様DESIGN.mdの詳細設計- テストスイート
実装すること:
- ✓ 完全に動作するコード
- ✓ 即座に実行可能
- ✓ すべてのテストがパス
- ✓ 実際のファイルI/O(モック最小限)
実装しないこと:
- ✗ TODOコメント
- ✗
NotImplementedError - ✗ プレースホルダーテキスト
- ✗ 将来の機能のスタブ
アクセシビリティ:
- タイマーテキスト: 7:1コントラスト比
- ボタン: 44×44px最小サイズ
- キーボードナビゲーション: 完全サポート
- スクリーンリーダー: 意味のあるHTML
ユーザビリティ:
- 明確な状態表示
- 予測可能な動作
- 役立つエラーメッセージ
- 設定可能な通知
詳細なコミット計画:
git add pomodoro/__init__.py pomodoro/models.py tests/__init__.py tests/test_models.py
git commit -m "feat(models): Add core data models
- Add Session dataclass for completed pomodoros
- Add TimerConfig with classic Pomodoro defaults
- Add comprehensive unit tests
Tests:
- test_session_creation
- test_timer_config_defaults
- test_session_serialization
🤖 Generated with [Amplifier](https://github.com/microsoft/amplifier)
Co-Authored-By: Amplifier <240397093+microsoft-amplifier@users.noreply.github.com>"git add pomodoro/storage.py tests/test_storage.py data/.gitkeep
git commit -m "feat(storage): Implement JSON file persistence
- Add atomic write pattern (temp file + rename)
- Add save_session() with incremental processing
- Add load_sessions() with date filtering
- Add get_sessions_today() convenience function
Tests:
- test_save_and_load_session
- test_date_filtering
- test_atomic_write
🤖 Generated with [Amplifier](https://github.com/microsoft/amplifier)
Co-Authored-By: Amplifier <240397093+microsoft-amplifier@users.noreply.github.com>"git add pomodoro/notifications.py
git commit -m "feat(notifications): Add OS-native desktop notifications
- Add notify_session_complete() for work/break completion
- Add notify_break_complete() for break completion
- Use plyer for cross-platform support
Manual testing confirms notifications work on current platform.
🤖 Generated with [Amplifier](https://github.com/microsoft/amplifier)
Co-Authored-By: Amplifier <240397093+microsoft-amplifier@users.noreply.github.com>"git add pomodoro/timer.py tests/test_timer.py
git commit -m "feat(timer): Implement Pomodoro timer core logic
- Add TimerState enum (IDLE, WORKING, SHORT_BREAK, LONG_BREAK, PAUSED)
- Add PomodoroTimer class with drift-free countdown
- Add state machine with explicit transitions
- Add auto-save on session completion
- Add pomodoro counting (long break every 4)
Tests:
- test_initial_state
- test_start_timer
- test_pause_resume
- test_state_transitions
- test_session_auto_save
🤖 Generated with [Amplifier](https://github.com/microsoft/amplifier)
Co-Authored-By: Amplifier <240397093+microsoft-amplifier@users.noreply.github.com>"git add pomodoro/stats.py tests/test_stats.py
git commit -m "feat(stats): Add statistics calculation
- Add calculate_today_stats() for focus time and pomodoro count
- Add calculate_streak() for consecutive days
- Add calculate_weekly_overview() for last 7 days
Tests:
- test_today_stats
- test_streak_calculation
- test_weekly_overview
- test_empty_sessions
🤖 Generated with [Amplifier](https://github.com/microsoft/amplifier)
Co-Authored-By: Amplifier <240397093+microsoft-amplifier@users.noreply.github.com>"git add ui/__init__.py ui/components/__init__.py ui/components/timer_display.py ui/components/stats_display.py
git commit -m "feat(ui): Add Streamlit UI components
- Add timer_display.py for countdown visualization
- Add stats_display.py for statistics dashboard
- 7:1 contrast ratio for accessibility
- Color-coded state indication
Manual testing confirms correct display.
🤖 Generated with [Amplifier](https://github.com/microsoft/amplifier)
Co-Authored-By: Amplifier <240397093+microsoft-amplifier@users.noreply.github.com>"git add ui/app.py
git commit -m "feat(ui): Add main Streamlit application
- Add session state management
- Add timer controls (start, pause, stop)
- Add keyboard shortcuts (Space, Esc, B, S)
- Add settings panel in sidebar
- Add 0.1s auto-refresh for smooth countdown
End-to-end testing confirms all features working.
🤖 Generated with [Amplifier](https://github.com/microsoft/amplifier)
Co-Authored-By: Amplifier <240397093+microsoft-amplifier@users.noreply.github.com>"Risk 1: Timer Drift
- Problem:
sleep()accumulation could cause drift - Mitigation: Target end time approach (lines 476-482 in DESIGN.md)
- Test: Manual test with 25-minute session
Risk 2: UI Thread Blocking
- Problem: Countdown loop might block Streamlit UI
- Mitigation: 0.1s sleep +
st.rerun()for responsive updates - Test: Check UI responsiveness during countdown
Risk 3: Data Corruption on Crash
- Problem: Partial writes could corrupt sessions.json
- Mitigation: Atomic write pattern (temp file + rename)
- Test: Simulate crash during save
plyer (notifications):
- Version: >=2.1.0
- Constraint: クロスプラットフォーム動作
- Fallback: 通知失敗時は静かにログ
streamlit:
- Version: >=1.30.0
- Constraint: セッション状態API
- Risk: Streamlit更新によるAPI変更
なし - 新規プロジェクトのため既存APIなし
コードが準備完了の条件:
- すべてのドキュメント化された動作が実装されている
- すべてのテストがパス(
uv run pytest) - コード品質チェックがパス(
make check) - ユーザーテストが正常に動作(タイマー、通知、統計)
- 既存機能の退行なし(新規プロジェクトなのでN/A)
- コードが哲学原則に従っている
- Phase 4実装準備完了
✅ Code plan complete and detailed
➡️ Get user approval
このコード計画を確認してください。すべてのファイル、実装の詳細、テスト戦略、コミット計画が含まれています。
➡️ When approved, run: /ddd:4-code
Phase 4では、この計画に基づいて実際のコード実装を行います。各チャンクを順次実装し、テストし、コミットします。
Created: 2025-11-22T22:40:00+09:00
Based on: plan.md (Phase 1), DESIGN.md (Phase 2)
Status: Ready for User Approval
Next Phase: /ddd:4-code
Estimated Implementation Time: 1-2 hours