📌 Feature Overview & Motivation
HalpTask features a dedicated Focus Mode (🎯 FOCUS) that highlights the active priority task and displays a top Focus Banner. The natural next step for deep-work power users is an Integrated Pomodoro Timer & Work Time Tracker.
This feature allows users to execute timed focus sprints (e.g. 25m work / 5m break) directly inside the terminal without switching to external timer tools, while automatically tracking time spent per task.
🎯 User Stories & Key Scenarios
- Integrated Pomodoro Countdown:
- When in Focus Mode (
fo / tf), pressing <space> p s (or <space> t p) starts an interactive 25-minute Pomodoro timer.
- The top Focus Banner dynamically updates with real-time countdown progress, sprint count, and session phase:
┌─ 🎯 ACTIVE FOCUS ────────────────────────────────────────────────────────┐
│ Task: Refactor storage proto serialization (#dev) │
│ Timer: 🍅 19:42 / 25:00 [Sprint 2/4] • Total Logged: 1h 15m │
└──────────────────────────────────────────────────────────────────────────┘
- Work / Break State Machine:
- Cycles through:
Work (25m) ➜ Short Break (5m) ➜ Work (25m) ... ➜ Long Break (15m) after 4 sprints.
- Customizable durations via
config.yaml or Config Dashboard modal (<space> c c).
- Session Completion Alerts:
- Plays terminal bell (
\a) and optionally triggers OS desktop notification when a sprint/break ends.
- Task Time Tracking & Persistence:
- Total active time spent is accumulated and saved in task metadata (
TimeSpentSeconds).
- Display total time logged badge (e.g.
⏱️ 45m) on the task.
🏗️ Architectural Touchpoints
1. Protobuf Schema & Data Model
proto/v1/storage.proto:
Add to ItemProto:
int64 time_spent_seconds = 17; // Accumulated active focus time in seconds
model/item.go:
- Add
TimeSpentSeconds int64 to Item.
- Add methods:
(i *Item) AddTimeSpent(seconds int64)
(i *Item) FormattedTimeSpent() string (e.g. "1h 25m", "45m")
- Update
Item.Clone() to preserve TimeSpentSeconds.
2. Pomodoro Engine & Timer Subscription (ui/pomodoro.go)
- Create
type PomodoroState struct:
Phase: PomodoroWork, PomodoroShortBreak, PomodoroLongBreak, PomodoroIdle, PomodoroPaused
RemainingSeconds int
TotalSeconds int
CompletedSprints int
TargetItemID string
- Bubble Tea timer integration:
- Return
tea.Tick(time.Second, func(t time.Time) tea.Msg { return pomodoroTickMsg{Time: t} }) when timer is active.
- In
Update(msg tea.Msg) in ui/app.go, handle pomodoroTickMsg, decrement RemainingSeconds, increment TimeSpentSeconds on the active focused item, and transition phases when reaching 0.
3. UI & Top Focus Banner Updates
ui/treeview.go & ui/app.go:
- Update Focus Banner renderer to display the live Pomodoro timer pill and sprint badges.
- Display subtle
⏱️ [45m] badge in the tree view for items with logged time.
ui/keys.go:
- Add Pomodoro leader keybindings:
<space> p s: Start / Pause Pomodoro timer
<space> p r: Reset Pomodoro timer
<space> p n: Skip to next Pomodoro phase (Work/Break)
<space> p c: Clear timer & unassign
- Register in WhichKey menu under
<space> p (Pomodoro).
4. Configuration Options (config/config.go)
- Add fields to
Config struct:
pomodoro_work_mins: 25
pomodoro_short_break_mins: 5
pomodoro_long_break_mins: 15
pomodoro_sound: true
- Expose toggles in interactive Config Dashboard (
<space> c c).
📋 Step-by-Step Implementation Plan
✅ Acceptance Criteria
- Starting Pomodoro via
<space> p s initiates a 1-second interval ticker that renders smoothly in the Top Focus Banner.
- Completed work seconds accurately accumulate into
item.TimeSpentSeconds and persist across file save/reload.
- Keybinding prefix tests pass without collisions in
ui/keys_test.go.
- Tests pass across all packages with zero race conditions (
go test -race ./...).
📌 Feature Overview & Motivation
HalpTask features a dedicated Focus Mode (
🎯 FOCUS) that highlights the active priority task and displays a top Focus Banner. The natural next step for deep-work power users is an Integrated Pomodoro Timer & Work Time Tracker.This feature allows users to execute timed focus sprints (e.g. 25m work / 5m break) directly inside the terminal without switching to external timer tools, while automatically tracking time spent per task.
🎯 User Stories & Key Scenarios
fo/tf), pressing<space> p s(or<space> t p) starts an interactive 25-minute Pomodoro timer.Work (25m)➜Short Break (5m)➜Work (25m)... ➜Long Break (15m)after 4 sprints.config.yamlor Config Dashboard modal (<space> c c).\a) and optionally triggers OS desktop notification when a sprint/break ends.TimeSpentSeconds).⏱️ 45m) on the task.🏗️ Architectural Touchpoints
1. Protobuf Schema & Data Model
proto/v1/storage.proto:Add to
ItemProto:int64 time_spent_seconds = 17; // Accumulated active focus time in secondsmodel/item.go:TimeSpentSeconds int64toItem.(i *Item) AddTimeSpent(seconds int64)(i *Item) FormattedTimeSpent() string(e.g."1h 25m","45m")Item.Clone()to preserveTimeSpentSeconds.2. Pomodoro Engine & Timer Subscription (
ui/pomodoro.go)type PomodoroState struct:Phase:PomodoroWork,PomodoroShortBreak,PomodoroLongBreak,PomodoroIdle,PomodoroPausedRemainingSeconds intTotalSeconds intCompletedSprints intTargetItemID stringtea.Tick(time.Second, func(t time.Time) tea.Msg { return pomodoroTickMsg{Time: t} })when timer is active.Update(msg tea.Msg)inui/app.go, handlepomodoroTickMsg, decrementRemainingSeconds, incrementTimeSpentSecondson the active focused item, and transition phases when reaching 0.3. UI & Top Focus Banner Updates
ui/treeview.go&ui/app.go:⏱️ [45m]badge in the tree view for items with logged time.ui/keys.go:<space> p s: Start / Pause Pomodoro timer<space> p r: Reset Pomodoro timer<space> p n: Skip to next Pomodoro phase (Work/Break)<space> p c: Clear timer & unassign<space> p(Pomodoro).4. Configuration Options (
config/config.go)Configstruct:<space> c c).📋 Step-by-Step Implementation Plan
time_spent_seconds(tag 17) toproto/v1/storage.protoandstorage.pb.go.model/item.gostruct, methods, and cloning logic.ui/pomodoro.gostate machine andtea.Tickmessage handler.ui/treeview.go.<space> pkeybindings inui/keys.goand WhichKey menu.config/config.goandui/configmodal.go.ui/pomodoro_test.goandmodel/item_test.go.README.md,wiki/Power-User-Guide.md, andwiki/Keybindings-Reference.md.✅ Acceptance Criteria
<space> p sinitiates a 1-second interval ticker that renders smoothly in the Top Focus Banner.item.TimeSpentSecondsand persist across file save/reload.ui/keys_test.go.go test -race ./...).