Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
180 changes: 128 additions & 52 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -30,35 +30,49 @@ This will:
## CLI Usage

```bash
# Database status and stats
session-analytics-cli status

# Ingest/refresh log data
session-analytics-cli ingest --days 7

# Tool frequency (which tools you use most)
session-analytics-cli frequency --days 30

# Bash command breakdown
session-analytics-cli commands
session-analytics-cli commands --prefix git # Just git commands

# Session info and token totals
session-analytics-cli sessions

# Token usage analysis
session-analytics-cli tokens --by day
session-analytics-cli tokens --by session
session-analytics-cli tokens --by model

# Common tool sequences (workflow patterns)
session-analytics-cli sequences --min-count 5 --length 3

# Permission gaps (commands that need settings.json)
session-analytics-cli permissions --threshold 10

# Full insights for /improve-workflow
session-analytics-cli insights --refresh
# Status & Ingestion
session-analytics-cli status # Database stats
session-analytics-cli ingest --days 7 # Refresh data from logs

# Core Analytics
session-analytics-cli frequency # Tool usage (--no-expand to hide breakdowns)
session-analytics-cli commands # Bash command breakdown (--prefix git)
session-analytics-cli sessions # Session metadata and tokens
session-analytics-cli tokens --by day # Token usage (day/session/model)

# Workflow Analysis
session-analytics-cli sequences # Tool chains (--expand for command-level)
session-analytics-cli permissions # Commands needing settings.json
session-analytics-cli insights # Pre-computed patterns for /improve-workflow

# File & Project Activity
session-analytics-cli file-activity # File reads/edits/writes
session-analytics-cli languages # Language distribution
session-analytics-cli projects # Activity by project
session-analytics-cli mcp-usage # MCP server/tool usage

# Session Analysis
session-analytics-cli signals # Raw session metrics for LLM interpretation
session-analytics-cli classify # Categorize sessions (debug/dev/research)
session-analytics-cli failures # Error patterns and rework detection
session-analytics-cli trends # Compare usage across time periods
session-analytics-cli handoff # Context summary for session handoff

# User Messages
session-analytics-cli journey # User messages across sessions
session-analytics-cli search <query> # Full-text search on messages

# Session Relationships
session-analytics-cli parallel # Find simultaneously active sessions
session-analytics-cli related <id> # Find sessions with similar patterns

# Git Integration
session-analytics-cli git-ingest # Import git commit history
session-analytics-cli git-correlate # Link commits to sessions
session-analytics-cli session-commits # Show commits per session

# Pattern Inspection
session-analytics-cli sample-sequences # Sample instances of a pattern with context
```

All commands support:
Expand All @@ -70,62 +84,124 @@ All commands support:

When running as an MCP server, these tools are available:

### Status & Ingestion

| Tool | Description |
|------|-------------|
| `get_status` | Database stats and last ingestion time |
| `ingest_logs` | Refresh data from JSONL files |
| `query_tool_frequency` | Tool usage counts |
| `query_timeline` | Events in time window with filtering |
| `query_commands` | Bash command breakdown |
| `query_sessions` | Session metadata and totals |
| `query_tokens` | Token usage by day/session/model |
| `query_sequences` | Common tool patterns (n-grams) |
| `query_permission_gaps` | Commands needing settings.json |

### Core Analytics

| Tool | Description |
|------|-------------|
| `get_tool_frequency` | Tool usage counts with optional breakdown |
| `get_session_events` | Events in time window with filtering |
| `get_command_frequency` | Bash command breakdown |
| `list_sessions` | Session metadata and totals |
| `get_token_usage` | Token usage by day/session/model |

### Workflow Analysis

| Tool | Description |
|------|-------------|
| `get_tool_sequences` | Common tool patterns (n-grams) |
| `sample_sequences` | Sample instances of a pattern with context |
| `get_permission_gaps` | Commands needing settings.json |
| `get_insights` | Pre-computed patterns for /improve-workflow |

### Example: query_tool_frequency
### File & Project Activity

| Tool | Description |
|------|-------------|
| `get_file_activity` | File reads/edits/writes breakdown |
| `get_languages` | Language distribution from file extensions |
| `get_projects` | Activity breakdown by project |
| `get_mcp_usage` | MCP server and tool usage |

### Session Analysis

| Tool | Description |
|------|-------------|
| `get_session_signals` | Raw session metrics for LLM interpretation |
| `classify_sessions` | Categorize sessions (debugging, dev, research) |
| `analyze_failures` | Error patterns and rework detection |
| `analyze_trends` | Compare usage across time periods |
| `get_handoff_context` | Context summary for session handoff |

### User Messages

| Tool | Description |
|------|-------------|
| `get_session_messages` | User messages across sessions |
| `search_messages` | Full-text search on user messages (FTS5) |

### Session Relationships

| Tool | Description |
|------|-------------|
| `detect_parallel_sessions` | Find simultaneously active sessions |
| `find_related_sessions` | Find sessions with similar patterns |

### Git Integration

| Tool | Description |
|------|-------------|
| `ingest_git_history` | Import git commit history |
| `correlate_git_with_sessions` | Link commits to sessions by timing |
| `get_session_commits` | Get commits associated with a session |

### Example: get_tool_frequency

```json
{
"days": 7,
"total_tool_calls": 1523,
"tools": [
{"tool": "Read", "count": 423},
{"tool": "Bash", "count": 312},
{"tool": "Bash", "count": 312, "breakdown": [{"name": "git", "count": 145}, {"name": "make", "count": 89}]},
{"tool": "Edit", "count": 289},
{"tool": "Grep", "count": 156}
]
}
```

### Example: query_permission_gaps
### Example: get_permission_gaps

```json
{
"gaps": [
{
"command": "npm",
"count": 47,
"suggestion": "Bash(npm:*)"
},
{
"command": "docker",
"count": 23,
"suggestion": "Bash(docker:*)"
}
{"command": "npm", "count": 47, "suggestion": "Bash(npm:*)"},
{"command": "docker", "count": 23, "suggestion": "Bash(docker:*)"}
]
}
```

### Example: query_sequences
### Example: get_tool_sequences

```json
{
"sequences": [
{"pattern": "Read → Edit", "count": 156},
{"pattern": "Grep → Read", "count": 89},
{"pattern": "Edit → Bash", "count": 67},
{"pattern": "Read → Edit → Bash", "count": 45}
{"pattern": "Edit → Bash", "count": 67}
]
}
```

### Example: get_session_signals

```json
{
"sessions": [
{
"session_id": "abc123",
"event_count": 45,
"error_rate": 0.04,
"commit_count": 2,
"has_rework": false,
"has_pr_activity": true
}
]
}
```
Expand Down
4 changes: 4 additions & 0 deletions src/session_analytics/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
__version__ = "0.1.0" # Fallback for development

# Re-export public API
from session_analytics.queries import build_where_clause, get_cutoff
from session_analytics.storage import (
Event,
GitCommit,
Expand All @@ -27,4 +28,7 @@
"Pattern",
"IngestionState",
"GitCommit",
# Query helpers
"build_where_clause",
"get_cutoff",
]
56 changes: 19 additions & 37 deletions src/session_analytics/cli.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,39 +5,24 @@
import sqlite3

from session_analytics.ingest import (
correlate_git_with_sessions as do_correlate_git,
)
from session_analytics.ingest import (
ingest_git_history as do_ingest_git,
)
from session_analytics.ingest import (
correlate_git_with_sessions,
ingest_git_history,
ingest_logs,
)
from session_analytics.patterns import (
analyze_failures as do_analyze_failures,
)
from session_analytics.patterns import (
analyze_trends as do_analyze_trends,
)
from session_analytics.patterns import (
analyze_failures,
analyze_trends,
compute_permission_gaps,
compute_sequence_patterns,
)
from session_analytics.patterns import (
get_insights as do_get_insights,
)
from session_analytics.patterns import (
get_session_signals as do_get_signals,
)
from session_analytics.patterns import (
sample_sequences as do_sample_sequences,
)
from session_analytics.queries import (
classify_sessions as do_classify_sessions,
get_insights,
get_session_signals,
sample_sequences,
)
from session_analytics.queries import (
classify_sessions,
detect_parallel_sessions,
find_related_sessions,
get_handoff_context,
get_user_journey,
query_commands,
query_file_activity,
Expand All @@ -48,9 +33,6 @@
query_tokens,
query_tool_frequency,
)
from session_analytics.queries import (
get_handoff_context as do_get_handoff_context,
)
from session_analytics.storage import SQLiteStorage

# Formatter registry: list of (predicate, formatter) tuples
Expand Down Expand Up @@ -440,7 +422,7 @@ def _format_handoff_context(data: dict) -> list[str]:
@_register_formatter(
lambda d: "sessions_analyzed" in d
and "sessions" in d
and "error_count" in d.get("sessions", [{}])[0]
and (len(d.get("sessions", [])) == 0 or "error_count" in d.get("sessions", [{}])[0])
)
def _format_signals(data: dict) -> list[str]:
"""Format raw session signals for display."""
Expand Down Expand Up @@ -651,7 +633,7 @@ def cmd_mcp_usage(args):
def cmd_insights(args):
"""Show insights for /improve-workflow."""
storage = SQLiteStorage()
result = do_get_insights(
result = get_insights(
storage,
refresh=args.refresh,
days=args.days,
Expand All @@ -663,7 +645,7 @@ def cmd_insights(args):
def cmd_sample_sequences(args):
"""Show sampled sequence instances."""
storage = SQLiteStorage()
result = do_sample_sequences(
result = sample_sequences(
storage,
pattern=args.pattern,
count=args.limit,
Expand Down Expand Up @@ -747,7 +729,7 @@ def cmd_related(args):
def cmd_failures(args):
"""Show failure analysis."""
storage = SQLiteStorage()
result = do_analyze_failures(
result = analyze_failures(
storage,
days=args.days,
rework_window_minutes=args.rework_window,
Expand All @@ -758,7 +740,7 @@ def cmd_failures(args):
def cmd_classify(args):
"""Show session classifications."""
storage = SQLiteStorage()
result = do_classify_sessions(
result = classify_sessions(
storage,
days=args.days,
project=args.project,
Expand All @@ -770,7 +752,7 @@ def cmd_handoff(args):
"""Show handoff context for a session."""
storage = SQLiteStorage()
hours = int(args.days * 24)
result = do_get_handoff_context(
result = get_handoff_context(
storage,
session_id=args.session_id,
hours=hours,
Expand All @@ -782,7 +764,7 @@ def cmd_handoff(args):
def cmd_trends(args):
"""Show trend analysis."""
storage = SQLiteStorage()
result = do_analyze_trends(
result = analyze_trends(
storage,
days=args.days,
compare_to=args.compare_to,
Expand All @@ -793,7 +775,7 @@ def cmd_trends(args):
def cmd_git_ingest(args):
"""Ingest git history."""
storage = SQLiteStorage()
result = do_ingest_git(
result = ingest_git_history(
storage,
repo_path=args.repo_path,
days=args.days,
Expand All @@ -805,7 +787,7 @@ def cmd_git_ingest(args):
def cmd_git_correlate(args):
"""Correlate git commits with sessions."""
storage = SQLiteStorage()
result = do_correlate_git(
result = correlate_git_with_sessions(
storage,
days=args.days,
)
Expand All @@ -815,7 +797,7 @@ def cmd_git_correlate(args):
def cmd_signals(args):
"""Show raw session signals for LLM interpretation (RFC #26, revised per RFC #17)."""
storage = SQLiteStorage()
result = do_get_signals(
result = get_session_signals(
storage,
days=args.days,
min_count=args.min_count,
Expand Down
2 changes: 2 additions & 0 deletions src/session_analytics/guide.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
# Session Analytics Usage Guide

> **Tip:** Read this guide via the MCP resource `session-analytics://guide` for usage patterns and best practices.

## What is this?

Session Analytics provides queryable analytics on Claude Code session logs. It parses
Expand Down
Loading