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
26 changes: 26 additions & 0 deletions CLAUDE.md
Original file line number Diff line number Diff line change
Expand Up @@ -77,3 +77,29 @@ make reinstall # pip install -e . + restart (for pyproject.toml)
5. Documentation in `guide.md`
6. Self-play test: can you reach actionable info using only MCP?
7. Run `make check`

### MCP Tool Docstrings

Keep docstrings minimal - `guide.md` is the **canonical reference** and should contain verbose explanations, usage examples, and tips. Docstrings add token overhead on every session, so they should only provide quick context.

**Include:**
- First-line description (what it does)
- Brief `Args:` section (name + type + purpose)
- Behavioral notes (defaults, special cases)

**Omit:**
- `Returns:` sections (structure is self-documenting in JSON)
- Usage examples (use guide.md)
- Tips/references to other docs

Example:
```python
def get_tool_frequency(...):
"""Get tool usage frequency counts.

Args:
days: Days to analyze (default: 7)
project: Optional project path filter (LIKE match)
expand: Include Bash→command, Skill→name, Task→subagent breakdown
"""
```
47 changes: 20 additions & 27 deletions src/session_analytics/cli.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,9 @@
ingest_git_history_all_projects,
ingest_logs,
)

# Note: correlate_git_with_sessions and ingest_git_history_all_projects are kept
# for CLI backward compatibility, though MCP now consolidates them into ingest_git_history
from session_analytics.patterns import (
analyze_failures,
analyze_trends,
Expand Down Expand Up @@ -1138,14 +1141,20 @@ def cmd_trends(args):


def cmd_git_ingest(args):
"""Ingest git history."""
"""Ingest git history and correlate with sessions."""
storage = SQLiteStorage()
result = ingest_git_history(
storage,
repo_path=args.repo_path,
days=args.days,
project_path=args.project,
)
if getattr(args, "all_projects", False):
result = ingest_git_history_all_projects(storage, days=args.days)
else:
result = ingest_git_history(
storage,
repo_path=args.repo_path,
days=args.days,
project_path=args.project,
)
# Auto-correlate commits with sessions (matches MCP behavior)
correlation = correlate_git_with_sessions(storage, days=args.days)
result["correlation"] = correlation
print(format_output(result, args.json))


Expand Down Expand Up @@ -1357,9 +1366,6 @@ def cmd_benchmark(args):
from session_analytics.patterns import (
sample_sequences as patterns_sample_sequences,
)
from session_analytics.queries import (
analyze_pre_compaction_patterns as queries_analyze_pre_compaction_patterns,
)
from session_analytics.queries import (
classify_sessions as queries_classify_sessions,
)
Expand All @@ -1384,21 +1390,12 @@ def cmd_benchmark(args):
from session_analytics.queries import (
query_agent_activity as queries_query_agent_activity,
)
from session_analytics.queries import (
query_bus_events as queries_query_bus_events,
)
from session_analytics.queries import (
query_commands as queries_query_commands,
)
from session_analytics.queries import (
query_error_details as queries_query_error_details,
)
from session_analytics.queries import (
query_file_activity as queries_query_file_activity,
)
from session_analytics.queries import (
query_languages as queries_query_languages,
)
from session_analytics.queries import (
query_mcp_usage as queries_query_mcp_usage,
)
Expand All @@ -1424,11 +1421,12 @@ def cmd_benchmark(args):
# Define all MCP tools with their default parameters
# These call the underlying query functions directly (not the MCP wrappers)
# Skip mutating tools (ingest_*) and tools requiring specific IDs
# Note: Removed tools not in MCP (get_command_frequency, get_languages, get_bus_events,
# analyze_pre_compaction_patterns) - CLI still has them for backward compat
tool_functions = {
"get_status": lambda: storage.get_db_stats(),
"get_tool_frequency": lambda: queries_query_tool_frequency(storage, days=7),
"get_session_events": lambda: queries_query_timeline(storage, limit=10),
"get_command_frequency": lambda: queries_query_commands(storage, days=7),
"list_sessions": lambda: queries_query_sessions(storage, days=7),
"get_token_usage": lambda: queries_query_tokens(storage, days=7),
"get_tool_sequences": lambda: patterns_compute_sequence_patterns(storage, days=7),
Expand Down Expand Up @@ -1456,11 +1454,9 @@ def cmd_benchmark(args):
"get_session_signals": lambda: patterns_get_session_signals(storage, days=7),
"get_session_commits": lambda: storage.get_session_commits(None),
"get_file_activity": lambda: queries_query_file_activity(storage, days=7),
"get_languages": lambda: queries_query_languages(storage, days=7),
"get_projects": lambda: queries_query_projects(storage, days=7),
"get_mcp_usage": lambda: queries_query_mcp_usage(storage, days=7),
"get_agent_activity": lambda: queries_query_agent_activity(storage, days=7),
"get_bus_events": lambda: queries_query_bus_events(storage, days=7, limit=10),
# Issue #69: Compaction and efficiency tools
"get_compaction_events": lambda: queries_get_compaction_events(storage, days=7),
"get_compaction_events_agg": lambda: queries_get_compaction_events(
Expand All @@ -1470,10 +1466,6 @@ def cmd_benchmark(args):
storage, days=7, min_size_kb=10, limit=10
),
"get_session_efficiency": lambda: queries_get_session_efficiency(storage, days=7),
# Issue #81: Pre-compaction pattern analysis
"analyze_pre_compaction_patterns": lambda: queries_analyze_pre_compaction_patterns(
storage, days=7
),
}

# Skipped tools (require specific data or modify DB):
Expand Down Expand Up @@ -1702,10 +1694,11 @@ def main():
sub.set_defaults(func=cmd_trends)

# git-ingest
sub = subparsers.add_parser("git-ingest", help="Ingest git commit history")
sub = subparsers.add_parser("git-ingest", help="Ingest git commit history and correlate")
sub.add_argument("--repo-path", help="Path to git repository (default: current dir)")
sub.add_argument("--days", type=int, default=7, help="Days of history (default: 7)")
sub.add_argument("--project", help="Project path to associate commits with")
sub.add_argument("--all-projects", action="store_true", help="Ingest from all known projects")
sub.set_defaults(func=cmd_git_ingest)

# git-correlate
Expand Down
41 changes: 8 additions & 33 deletions src/session_analytics/guide.md
Original file line number Diff line number Diff line change
Expand Up @@ -22,13 +22,11 @@ identify permission gaps.

| Tool | Purpose |
|------|---------|
| `get_tool_frequency(days?, project?)` | Tool usage counts (Read, Edit, Bash, etc.) |
| `get_command_frequency(days?, prefix?, project?)` | Bash command breakdown |
| `get_tool_frequency(days?, project?, expand?)` | Tool usage counts with Bash/Skill/Task breakdown |
| `list_sessions(days?, project?)` | Session metadata and token totals |
| `get_token_usage(days?, by?, project?)` | Token usage by day, session, or model |
| `get_session_events(days?, tool?, session_id?)` | Recent events with filtering |
| `get_file_activity(days?, project?, limit?, collapse_worktrees?)` | File reads/edits/writes breakdown |
| `get_languages(days?, project?)` | Language distribution from file extensions |
| `get_projects(days?)` | Activity across all projects |
| `get_mcp_usage(days?, project?)` | MCP server and tool usage |

Expand Down Expand Up @@ -116,9 +114,7 @@ Returns both core metrics (`events`, `sessions`, `errors`, `tokens`) and `effici

| Tool | Purpose |
|------|---------|
| `ingest_git_history(days?, repo_path?)` | Parse and store git commits from current repo |
| `ingest_git_history_all_projects(days?)` | Parse commits from all known projects |
| `correlate_git_with_sessions(days?)` | Link commits to sessions by timing |
| `ingest_git_history(days?, all_projects?)` | Ingest commits and auto-correlate with sessions |
| `get_session_commits(session_id?)` | Get commits associated with a session |

### Session Signals
Expand All @@ -139,8 +135,6 @@ Returns both core metrics (`events`, `sessions`, `errors`, `tokens`) and `effici
| Tool | Purpose |
|------|---------|
| `get_compaction_events(days?, session_id?, limit?, aggregate?)` | List compaction events (context resets) |
| `get_pre_compaction_events(session_id, compaction_timestamp, limit?)` | Events before a compaction for analysis |
| `analyze_pre_compaction_patterns(days?, events_before?, limit?)` | Aggregated patterns before compactions (RFC #81) |
| `get_large_tool_results(days?, min_size_kb?, limit?)` | Find tool results consuming context space |
| `get_session_efficiency(days?, project?, limit?)` | Session efficiency metrics and burn rate |

Expand All @@ -151,21 +145,6 @@ Returns both core metrics (`events`, `sessions`, `errors`, `tokens`) and `effici
- **Read/Edit ratio**: High ratio suggests inefficient exploration (should use Task/Explore)
- **Files read multiple times**: Redundant reads indicate opportunity to cache context

### Event-Bus Integration

| Tool | Purpose |
|------|---------|
| `ingest_bus_events(days?)` | Import events from event-bus for cross-session insights |
| `get_bus_events(days?, event_type?, session_id?, repo?, limit?)` | Query event-bus events (gotchas, patterns, help) |

Cross-session events include:
- `gotcha_discovered` - Non-obvious issues found during work
- `pattern_found` - Useful patterns identified
- `help_needed` / `help_response` - Cross-session coordination
- `task_completed` / `task_started` - Work progress tracking

These appear in `get_insights()` under `cross_session_activity` when available.

## Quick Start

### 1. Check status
Expand Down Expand Up @@ -200,7 +179,6 @@ use the APIs however best fits your needs.
β”œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€
β”‚ get_status() β†’ Is data fresh? How many events? β”‚
β”‚ get_tool_frequency() β†’ What tools are used most? β”‚
β”‚ get_command_frequency()β†’ What commands are common? β”‚
β”œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€
β”‚ DISCOVER PATTERNS β”‚
β”œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€
Expand Down Expand Up @@ -241,10 +219,8 @@ analyze_trends() β†’ "Usage is increasing/decreasing"
```
get_compaction_events() β†’ "When did context resets happen?"
get_compaction_events(aggregate=True) β†’ "Which sessions had most compactions?"
analyze_pre_compaction_patterns() β†’ "What patterns precede compactions?" (RFC #81)
get_session_efficiency() β†’ "Which sessions burn context fastest?"
get_large_tool_results() β†’ "What operations consume the most space?"
get_pre_compaction_events() β†’ "What led up to a specific reset?"
```

## Reference
Expand Down Expand Up @@ -280,18 +256,17 @@ Add suggestions to `permissions.allow` in your settings.

### Git Integration

Git correlation requires two steps:
Git ingestion automatically correlates commits with sessions:

```
# Option 1: Ingest from all known projects (recommended)
ingest_git_history_all_projects(days=30)
# Ingest from all known projects (recommended)
ingest_git_history(all_projects=True, days=30)

# Option 2: Ingest from current repo only
# Or from current repo only
ingest_git_history(days=30)

# Then correlate and query
correlate_git_with_sessions() # Link to sessions by timing
get_session_commits(session_id="abc") # View results
# Query results
get_session_commits(session_id="abc")
```

## Tips
Expand Down
Loading