diff --git a/CLAUDE.md b/CLAUDE.md index 45df765..ad76338 100644 --- a/CLAUDE.md +++ b/CLAUDE.md @@ -2,6 +2,8 @@ Queryable analytics for Claude Code session logs, exposed as an MCP server and CLI. +**Related**: [claude-event-bus](https://github.com/evansenter/claude-event-bus) shares design patterns with this project. + ## Project Overview This MCP server replaces the bash script `~/.claude/contrib/parse-session-logs.sh` with a persistent, queryable analytics layer. It parses JSONL session logs from `~/.claude/projects/` and provides: @@ -91,7 +93,14 @@ The install is editable (`pip install -e .`), so Python code changes are picked - **Formatter Registry**: CLI uses `@_register_formatter(predicate)` decorator pattern - **Schema Migrations**: Use `@migration(version, name)` decorator in storage.py for DB changes - **Module Imports**: server.py uses `from session_analytics import queries, patterns, ingest` -- **CLI/MCP Parity**: Always expose new query functions on both CLI and MCP. Add MCP tool in `server.py`, CLI command in `cli.py`, document in both `guide.md` and this file +- **CLI/MCP Parity**: Always expose new query functions on both CLI and MCP + +**When modifying the API**: Update all discovery surfaces together: +1. **CLI command** - in `cli.py` (visible via `session-analytics-cli --help`) +2. **MCP tool** - in `server.py` (visible to CC via tool inspection) +3. **Usage guide** - `guide.md` (served as `session-analytics://guide` resource) +4. **CLAUDE.md** - This file, for codebase context +5. **~/.claude/contrib/README.md** - User's local contrib directory (lists MCP server data locations) ## MCP API Naming Conventions @@ -296,6 +305,10 @@ session-analytics-cli ingest --days 1 --json 2>/dev/null || true **Patterns table**: Pre-computed patterns for fast querying **Ingested files table**: Tracks file mtime/size for incremental updates +## Related + +- [claude-event-bus](https://github.com/evansenter/claude-event-bus) - Cross-session communication for Claude Code + ## Reference Full implementation plan: `~/.claude/plans/precious-crunching-crescent.md` diff --git a/README.md b/README.md index 35a53c8..5959934 100644 --- a/README.md +++ b/README.md @@ -2,6 +2,8 @@ MCP server and CLI for queryable analytics on Claude Code session logs. +**Related**: [claude-event-bus](https://github.com/evansenter/claude-event-bus) shares design patterns with this project. + ## What It Does Parses your Claude Code session logs (`~/.claude/projects/**/*.jsonl`) and provides: @@ -259,6 +261,10 @@ Key patterns used in the codebase: See `CLAUDE.md` for more details on contributing. +## Related + +- [claude-event-bus](https://github.com/evansenter/claude-event-bus) - Cross-session communication for Claude Code + ## Uninstall ```bash diff --git a/scripts/install-cli.sh b/scripts/install-cli.sh new file mode 100755 index 0000000..016911b --- /dev/null +++ b/scripts/install-cli.sh @@ -0,0 +1,52 @@ +#!/bin/bash +# Install session-analytics-cli to ~/.local/bin as a symlink + +set -e + +SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" +PROJECT_DIR="$(dirname "$SCRIPT_DIR")" +VENV_CLI="$PROJECT_DIR/.venv/bin/session-analytics-cli" +INSTALL_DIR="$HOME/.local/bin" +CLI_PATH="$INSTALL_DIR/session-analytics-cli" + +# Check venv CLI exists +if [[ ! -f "$VENV_CLI" ]]; then + echo "Error: CLI not found at $VENV_CLI" + echo "Run: make dev (or pip install -e .)" + exit 1 +fi + +# Create install directory +mkdir -p "$INSTALL_DIR" + +# Remove existing file/symlink if present +if [[ -e "$CLI_PATH" || -L "$CLI_PATH" ]]; then + # Skip if already correctly symlinked + if [[ -L "$CLI_PATH" && "$(readlink "$CLI_PATH")" == "$VENV_CLI" ]]; then + echo "session-analytics-cli already symlinked correctly" + exit 0 + fi + rm -f "$CLI_PATH" +fi + +# Create symlink +ln -s "$VENV_CLI" "$CLI_PATH" +echo "Installed session-analytics-cli to $CLI_PATH (symlink)" + +# Check if ~/.local/bin is in PATH +if [[ ":$PATH:" != *":$INSTALL_DIR:"* ]]; then + echo "" + echo "Warning: $INSTALL_DIR is not in your PATH" + echo "Add this to your shell profile (.bashrc, .zshrc, etc.):" + echo "" + echo " export PATH=\"\$HOME/.local/bin:\$PATH\"" + echo "" +fi + +# Test it works +if "$CLI_PATH" --help > /dev/null 2>&1; then + echo "Verified: session-analytics-cli is working" +else + echo "Warning: session-analytics-cli installed but test failed" + exit 1 +fi diff --git a/scripts/install-launchagent.sh b/scripts/install-launchagent.sh index 40c9398..4a40f8f 100755 --- a/scripts/install-launchagent.sh +++ b/scripts/install-launchagent.sh @@ -46,6 +46,11 @@ if launchctl list | grep -q "$LABEL"; then echo " Logs: ~/.claude/session-analytics.log" echo " Errors: ~/.claude/session-analytics.err" echo "" + + # Also install CLI for use in hooks/scripts + echo "Installing CLI..." + "$SCRIPT_DIR/install-cli.sh" + echo "" echo "To uninstall: $SCRIPT_DIR/uninstall-launchagent.sh" osascript -e 'display notification "LaunchAgent installed and running" with title "Session Analytics"' 2>/dev/null else diff --git a/scripts/uninstall-cli.sh b/scripts/uninstall-cli.sh new file mode 100755 index 0000000..9373764 --- /dev/null +++ b/scripts/uninstall-cli.sh @@ -0,0 +1,14 @@ +#!/bin/bash +# Uninstall session-analytics-cli from ~/.local/bin + +set -e + +CLI_PATH="$HOME/.local/bin/session-analytics-cli" + +if [[ ! -e "$CLI_PATH" && ! -L "$CLI_PATH" ]]; then + echo "session-analytics-cli not installed." + exit 0 +fi + +rm -f "$CLI_PATH" +echo "Removed session-analytics-cli from ~/.local/bin" diff --git a/scripts/uninstall-launchagent.sh b/scripts/uninstall-launchagent.sh index 9e556ed..e9693db 100755 --- a/scripts/uninstall-launchagent.sh +++ b/scripts/uninstall-launchagent.sh @@ -19,6 +19,10 @@ rm -f "$PLIST_DEST" echo "Session analytics LaunchAgent uninstalled." +# Also uninstall CLI +SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" +"$SCRIPT_DIR/uninstall-cli.sh" + echo "" -echo "Note: Logs remain at ~/.claude/session-analytics.log" +echo "Note: Data remains at ~/.claude/contrib/analytics/" osascript -e 'display notification "LaunchAgent uninstalled" with title "Session Analytics"' 2>/dev/null