Files
claude-code/skills/usage/SKILL.md
OpenCode Test 4ca3365d55 Implement /usage command for session tracking (fc-005)
Components:
- commands/usage.md: Slash command with aliases (stats)
- skills/usage/SKILL.md: Query logic and report generation
- state/usage/config.json: Log level and preferences

Features:
- Parse history/index.json for session metadata
- Estimate duration from consecutive session starts
- Group by date, show summary stats
- Configurable log levels (minimal/standard/detailed)
- Extensible for future session content parsing

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2025-12-31 23:21:00 -08:00

4.2 KiB

name, description, allowed-tools
name description allowed-tools
usage Track and report model usage across sessions
Bash
Read

Usage Tracking Skill

Query session history and report usage statistics.

Data Sources

Source Status Data Available
history/index.json Available Session IDs, start times
history/*.jsonl Future Session content, commands, tokens
usage/config.json Available Log level, preferences

Command Routing

Command Action
/usage Show last 7 days summary
/usage today Today's sessions
/usage week Last 7 days
/usage month Last 30 days
/usage all All time stats
/usage --by agent Group by agent
/usage --by skill Group by skill
/usage --by model Group by model tier
/usage --set-level <level> Set log level
/usage --show-config Show current config

Log Levels

Level Data Captured
minimal Session ID, time, model
standard + agents, skills, tokens (default)
detailed + commands, delegations, errors

Implementation

Query Sessions

import json
from datetime import datetime, timedelta
from pathlib import Path
from zoneinfo import ZoneInfo

LOCAL_TZ = ZoneInfo('America/Los_Angeles')
HISTORY_DIR = Path.home() / ".claude/state/personal-assistant/history"
CONFIG_PATH = Path.home() / ".claude/state/usage/config.json"

def load_sessions():
    index_path = HISTORY_DIR / "index.json"
    if not index_path.exists():
        return []
    with open(index_path) as f:
        data = json.load(f)
    return data.get("sessions", [])

def filter_sessions(sessions, range_type="week"):
    now = datetime.now(LOCAL_TZ)
    if range_type == "today":
        cutoff = now.replace(hour=0, minute=0, second=0, microsecond=0)
    elif range_type == "week":
        cutoff = now - timedelta(days=7)
    elif range_type == "month":
        cutoff = now - timedelta(days=30)
    else:  # all
        return sessions

    filtered = []
    for s in sessions:
        started = datetime.fromisoformat(s["started"])
        if started >= cutoff:
            filtered.append(s)
    return filtered

def estimate_duration(sessions):
    """Estimate session duration from consecutive start times."""
    if not sessions:
        return []

    sorted_sessions = sorted(sessions, key=lambda s: s["started"])
    for i, session in enumerate(sorted_sessions):
        if i + 1 < len(sorted_sessions):
            start = datetime.fromisoformat(session["started"])
            next_start = datetime.fromisoformat(sorted_sessions[i + 1]["started"])
            duration = (next_start - start).total_seconds() / 60
            # Cap at 2 hours (likely session gap)
            session["duration_mins"] = min(duration, 120)
        else:
            # Current/last session: estimate 30 mins
            session["duration_mins"] = 30
    return sorted_sessions

Generate Report

def generate_report(sessions, range_type="week"):
    total_mins = sum(s.get("duration_mins", 0) for s in sessions)
    hours = int(total_mins // 60)
    mins = int(total_mins % 60)

    report = f"""
📊 Usage Summary — {range_type.title()}

Sessions: {len(sessions)}
Total time: {hours}h {mins}m
Model: opus (primary)
"""
    return report

Output Format

📊 Usage Summary — Last 7 Days

Sessions: 12
Total time: 8h 32m
Model: opus (primary)

┌─────────────┬──────────┬────────┐
│ Agent       │ Sessions │ Time   │
├─────────────┼──────────┼────────┤
│ PA          │ 12       │ 8h 32m │
└─────────────┴──────────┴────────┘

Note: Detailed metrics available when session
content logging is enabled.

Future Enhancements

When history/*.jsonl files are available:

  • Parse actual commands used
  • Detect skill invocations
  • Count delegations (sonnet/haiku)
  • Estimate token usage
  • Track errors

Policy

  • Read-only operations
  • No external API calls
  • Local data only