Dotfiles project-time-tracker
install
source · Clone the upstream repo
git clone https://github.com/KIM-KYOUNG-OH/dotfiles
Claude Code · Install into ~/.claude/skills/
T=$(mktemp -d) && git clone --depth=1 https://github.com/KIM-KYOUNG-OH/dotfiles "$T" && mkdir -p ~/.claude/skills && cp -r "$T/.claude/skills/project-time-tracker" ~/.claude/skills/kim-kyoung-oh-dotfiles-project-time-tracker && rm -rf "$T"
manifest:
.claude/skills/project-time-tracker/SKILL.mdsource content
Project Time Tracker Skill
개요
Claude Code 세션 로그의 타임스탬프를 분석하여 프로젝트별 작업 시간을 집계하고, 일별/주별/월별 리포트를 생성하는 skill.
사용 방식
/project-time-tracker # 이번 주 시간 리포트 /project-time-tracker daily # 오늘 시간 리포트 /project-time-tracker weekly # 이번 주 시간 리포트 (기본값) /project-time-tracker monthly # 이번 달 시간 리포트 /project-time-tracker 2026-01-15 # 특정 날짜 시간 리포트
경로 정보
| 항목 | 경로 |
|---|---|
| 세션 로그 | |
| 출력 | |
데이터 구조
세션 로그 위치
~/.claude/projects/ ├── -Users-msbaek-project-a/ │ ├── abc123.jsonl │ └── def456.jsonl ├── -Users-msbaek-project-b/ │ └── ghi789.jsonl └── ...
JSONL 타임스탬프 추출
세션 시간 계산:
- 시작 시간: 첫 번째 레코드의
필드timestamp - 종료 시간: 마지막 레코드의
필드timestamp - 세션 시간: 종료 - 시작
# 세션 시작/종료 시간 추출 jq -s '[.[0].timestamp, .[-1].timestamp] | {start: .[0], end: .[1], duration_min: ((.[1] | fromdateiso8601) - (.[0] | fromdateiso8601)) / 60}' \ session.jsonl
실행 절차
Step 1: 분석 기간 결정
# 모드에 따른 기간 설정 MODE="${1:-weekly}" case "$MODE" in daily|today) START_DATE=$(date +%Y-%m-%d) END_DATE=$(date -v+1d +%Y-%m-%d) PERIOD_NAME="일일" ;; weekly) START_DATE=$(date -v-$(($(date +%u) - 1))d +%Y-%m-%d) # 이번 주 월요일 END_DATE=$(date -v+1d +%Y-%m-%d) PERIOD_NAME="주간" ;; monthly) START_DATE=$(date +%Y-%m-01) # 이번 달 1일 END_DATE=$(date -v+1d +%Y-%m-%d) PERIOD_NAME="월간" ;; *) # 특정 날짜 START_DATE="$MODE" END_DATE=$(date -j -f "%Y-%m-%d" -v+1d "$MODE" +%Y-%m-%d) PERIOD_NAME="일일" ;; esac echo "분석 기간: $START_DATE ~ $END_DATE ($PERIOD_NAME)"
Step 2: 해당 기간 세션 로그 수집
# 기간 내 수정된 세션 로그 찾기 find ~/.claude/projects -name "*.jsonl" \ -newermt "$START_DATE 00:00:00" \ ! -newermt "$END_DATE 00:00:00" 2>/dev/null
Step 3: 프로젝트별 시간 집계
# 프로젝트 경로 디코딩 함수 decode_project_path() { echo "$1" | sed 's/-/\//g' | sed 's/^\/Users\/msbaek\///' } # 각 세션 시간 계산 및 프로젝트별 집계 for session in $(find ~/.claude/projects -name "*.jsonl" -newermt "$START_DATE"); do PROJECT_DIR=$(dirname "$session" | xargs basename) PROJECT_NAME=$(decode_project_path "$PROJECT_DIR") # 세션 시간 계산 (분 단위) DURATION=$(jq -s ' if length > 1 then (((.[-1].timestamp | fromdateiso8601) - (.[0].timestamp | fromdateiso8601)) / 60) | floor else 0 end ' "$session" 2>/dev/null || echo "0") echo "$PROJECT_NAME: ${DURATION}분" done | sort | uniq -c | sort -rn
Step 4: 일별 분포 계산 (주간/월간 리포트용)
# 각 세션의 날짜별 시간 분포 for session in $(find ~/.claude/projects -name "*.jsonl" -newermt "$START_DATE"); do # 세션 시작 날짜 추출 SESSION_DATE=$(jq -r '.[0].timestamp[:10]' "$session" 2>/dev/null) # ... 집계 done
Step 5: 리포트 생성
일일 리포트
--- created: {DATE} type: time-tracking period: daily date: {TARGET_DATE} tags: - analytics/time - analytics/daily --- # 시간 추적 - {TARGET_DATE} ## 오늘 작업 시간 | 프로젝트 | 세션 수 | 작업 시간 | |---------|--------|----------| | project-a | 3 | 2h 30m | | project-b | 2 | 1h 15m | | **합계** | **5** | **3h 45m** | ## 세션 상세 | 시작 | 종료 | 프로젝트 | 시간 | |-----|-----|---------|-----| | 09:30 | 11:00 | project-a | 1h 30m | | 14:00 | 15:00 | project-b | 1h 00m | | ... | ... | ... | ... |
주간 리포트
--- created: {DATE} type: time-tracking period: weekly week: {WEEK_NUM} tags: - analytics/time - analytics/weekly --- # 주간 시간 추적 - {WEEK_NUM} > 분석 기간: {START_DATE} (월) ~ {END_DATE} (금) ## 프로젝트별 총 시간 | 프로젝트 | 세션 수 | 총 시간 | 비율 | |---------|--------|--------|-----| | project-a | 12 | 8h 30m | 45% | | project-b | 8 | 5h 20m | 28% | | project-c | 5 | 3h 10m | 17% | | 기타 | 3 | 1h 50m | 10% | | **합계** | **28** | **18h 50m** | **100%** | ## 일별 시간 분포 | 프로젝트 | 월 | 화 | 수 | 목 | 금 | 합계 | |---------|-----|-----|-----|-----|-----|------| | project-a | 2h | 1h30m | 2h | 1h30m | 1h30m | 8h30m | | project-b | 1h | 1h | 1h30m | 1h | 50m | 5h20m | | ... | ... | ... | ... | ... | ... | ... | ## 일별 총 작업 시간 | 요일 | 세션 수 | 총 시간 | |-----|--------|--------| | 월 | 5 | 3h 30m | | 화 | 6 | 4h 00m | | 수 | 7 | 4h 15m | | 목 | 5 | 3h 45m | | 금 | 5 | 3h 20m |
월간 리포트
--- created: {DATE} type: time-tracking period: monthly month: {MONTH} tags: - analytics/time - analytics/monthly --- # 월간 시간 추적 - {MONTH} ## 프로젝트별 총 시간 | 프로젝트 | 세션 수 | 총 시간 | 비율 | |---------|--------|--------|-----| | ... | ... | ... | ... | ## 주간별 분포 | 프로젝트 | W01 | W02 | W03 | W04 | 합계 | |---------|-----|-----|-----|-----|------| | project-a | 8h | 10h | 7h | 9h | 34h | | ... | ... | ... | ... | ... | ... | ## 일별 추이 (그래프용 데이터) | 날짜 | 시간(분) | |-----|---------| | 01 | 180 | | 02 | 210 | | ... | ... |
시간 계산 규칙
세션 시간 산정
- 기본 방식: 첫 레코드 ~ 마지막 레코드 시간 차이
- 공백 처리: 10분 이상 공백은 미활동으로 간주하여 제외 (선택적)
- 최소 단위: 5분 이하 세션은 5분으로 올림
시간 형식
| 분 | 표시 형식 |
|---|---|
| 30 | 30m |
| 60 | 1h |
| 90 | 1h 30m |
| 150 | 2h 30m |
# 분 → 시간:분 변환 format_duration() { local mins=$1 local hours=$((mins / 60)) local remaining=$((mins % 60)) if [ $hours -gt 0 ]; then echo "${hours}h ${remaining}m" else echo "${remaining}m" fi }
에러 처리
- 세션 없음: "해당 기간에 Claude Code 세션 없음" 반환
- 타임스탬프 없음: 해당 세션 건너뛰기
- 파싱 오류: 세션 건너뛰고 계속 진행
관련 Skill
: 주간 종합 분석 (시간 외 다른 지표 포함)weekly-claude-analytics
: 일일 작업 로그daily-work-logger
: 도구 사용 패턴 분석usage-pattern-analyzer