claude-work-timer
v0.1.0
Published
Track actual working hours from Claude Code session logs with idle detection
Maintainers
Readme
claude-work-timer (ctt)
Track actual working hours from Claude Code session logs — not just tokens or costs, but real time spent coding.
The Problem
Claude Code tracks tokens and costs, but not your time. Session spans don't reflect actual work — you step away for lunch, get distracted, or context-switch between projects. A 4-hour session span might only contain 45 minutes of real work.
The Solution
ctt analyzes Claude Code's local session logs, detects idle gaps, and calculates net active working time per session, project, and day.
Claude Code Working Hours — 2026-02-24
Project │ Sessions │ Active │ Span │ Idle
─────────────────────┼──────────┼─────────┼─────────┼───────
gmat-simulator-1 │ 3 │ 2h 15m │ 3h 42m │ 1h 27m
GMAT-skills │ 1 │ 45m │ 1h 10m │ 25m
─────────────────────┼──────────┼─────────┼─────────┼───────
Total │ 4 │ 3h 00m │ 4h 52m │ 1h 52m
(idle threshold: 5 min)Install
npm install -g claude-work-timerOr run directly without installing:
npx claude-work-timer dailyFor local development:
git clone https://github.com/danyuchn/claude-work-timer.git
cd claude-work-timer
npm install
npm run build
npm link # Makes "ctt" available globally from this local copyUsage
ctt # Quick overview: today + this week
ctt daily # Today's working hours by project
ctt daily --since 2026-02-01 # Date range
ctt weekly # This week, day by day
ctt project # All projects, all time
ctt project my-project # Single project breakdown
ctt session # Recent sessions list
ctt session abc12345 # Single session detail
# Options
--json # JSON output (pipe-friendly)
--idle-threshold <min> # Override idle threshold (default: 5)
--since <YYYY-MM-DD> # Filter start date
--until <YYYY-MM-DD> # Filter end date
# Config
ctt config set idle-threshold 10 # Change default idle threshold
ctt config get # Show all configHow It Works
Data Source
ctt reads Claude Code's local session logs at ~/.claude/projects/. Each session is a JSONL file with timestamped messages. No data leaves your machine.
Idle Detection Algorithm
- Parse all
userandassistantmessages from a session - Deduplicate streaming assistant updates (keep last per
parentUuid) - Sort events chronologically
- Walk adjacent pairs — if the gap exceeds the idle threshold (default: 5 min), split into a new work segment
- Add a tail buffer (default: 30s) after the last event in each segment
- Sum segment durations = active working time
Timeline: |---work---| (8 min idle) |---work---| (2 min gap) |---work---|
Segments: [segment 1 ] [ segment 2 + tail ]Key Metrics
| Metric | Description | |--------|-------------| | Active | Net working time (sum of work segments) | | Span | Wall-clock time from first to last event | | Idle | Span minus Active (time you were away) |
Configuration
Config file: ~/.claude-time-tracker/config.json
| Key | Default | Description |
|-----|---------|-------------|
| idle-threshold | 5 | Minutes of inactivity before a gap is considered idle |
| tail-buffer | 30 | Seconds added after the last event in each segment |
| claude-dir | ~/.claude | Path to Claude Code data directory |
vs Other Tools
| Tool | Tracks | Idle Detection | |------|--------|----------------| | ccusage | Tokens, costs, models | No | | ccstat | Session timeline visualization | No | | WakaTime | General coding time | Yes (different scope) | | ctt | Net working hours per project | Yes (core feature) |
Development
git clone https://github.com/danyuchn/claude-work-timer.git
cd claude-work-timer
npm install
npm run build
npm test
# Test locally
node bin/ctt.js dailyLicense
MIT
