Track development time and update Excel timesheets AND markdown work logs. Use this skill when the user wants to record development work sessions, log hours worked, update their development time tracking spreadsheet, or create/update a work log file. Triggers on phrases like "log my time", "record development hours", "track my work time", "update time tracking", "log session", "update worklog", "add to work log", or when the user mentions they finished working and wants to record it. This skill calculates session duration and appends entries to both an Excel timesheet AND a markdown WORKLOG.md file.
Track development sessions and update both Excel timesheets and markdown work logs with session details.
Invoke this skill when:
Determine from the conversation:
Calculate time elapsed from session start to now:
Use the current date (system provides this).
Default location pattern: {project}/docs/development_time.xlsx
Use the xlsx skill patterns with openpyxl:
from openpyxl import load_workbook
from datetime import datetime
wb = load_workbook(excel_path)
sheet = wb.active # or wb['Time Tracking']
# Find next empty row (after header + existing data)
next_row = sheet.max_row + 1
# Get day name from date
day_name = date_obj.strftime('%A')
# Insert new row
sheet.insert_rows(next_row)
# Populate columns
sheet[f'A{next_row}'] = date_obj # Date
sheet[f'B{next_row}'] = day_name # Day
sheet[f'C{next_row}'] = hours # Hours
sheet[f'D{next_row}'] = focus # Focus
sheet[f'E{next_row}'] = deliverables # Key Deliverables
sheet[f'F{next_row}'] = notes # Notes
# Move TOTAL row down (it should stay at bottom)
# The TOTAL formula should auto-adjust or needs update
wb.save(excel_path)
Location: {project}/docs/WORKLOG.md
The WORKLOG.md uses a weekly table format with the following structure:
To add a new session entry:
from datetime import datetime, timedelta
import os
import re
worklog_path = os.path.join(project_path, 'docs', 'WORKLOG.md')
# Get session details
date_str = date_obj.strftime('%Y-%m-%d') # YYYY-MM-DD
time_str = datetime.now().strftime('%H:%M') # Current time as end time
start_time_str = session_start_time.strftime('%H:%M') if session_start_time else (datetime.now() - timedelta(hours=hours)).strftime('%H:%M')
# Format hours for table (e.g., "1.5h", "2h")
hours_formatted = f"{hours}h" if hours == int(hours) else f"{hours}h"
# Get commits from deliverables (extract commit hashes if present)
commits = extract_commits(deliverables) # e.g., "9bbbd55, 3e756e9" or "-"
# Activity description (use focus + shortened deliverables)
activity = f"{focus}: {deliverables.split(';')[0]}" if len(deliverables) > 50 else f"{focus}: {deliverables}"
# Build table row
new_row = f"| {start_time_str} | {time_str} | {hours_formatted} | {activity} | {commits} |"
# Determine week range
date_obj = datetime.strptime(date_str, '%Y-%m-%d')
week_start = date_obj - timedelta(days=date_obj.weekday()) # Monday
week_end = week_start + timedelta(days=6) # Sunday
week_range = f"{week_start.strftime('%Y-%m-%d')} a {week_end.strftime('%Y-%m-%d')}"
day_name_es = {
'Monday': 'Lunes', 'Tuesday': 'Martes', 'Wednesday': 'Miércoles',
'Thursday': 'Jueves', 'Friday': 'Viernes', 'Saturday': 'Sábado', 'Sunday': 'Domingo'
}[date_obj.strftime('%A')]
# Read existing file or create new
if not os.path.exists(worklog_path):
# Create new file with first week table
content = generate_new_worklog(week_range, date_str, day_name_es, new_row, hours)
with open(worklog_path, 'w') as f:
f.write(content)