diff --git a/Makefile b/Makefile index 2257767..f4739fe 100644 --- a/Makefile +++ b/Makefile @@ -32,13 +32,18 @@ venv: dev: venv .venv/bin/pip install -e ".[dev]" -# Full installation: venv + deps + LaunchAgent + CLI + MCP +# Full installation: venv + deps + service + CLI + MCP install: venv @echo "Installing dependencies..." .venv/bin/pip install -e . @echo "" - @echo "Installing LaunchAgent..." - ./scripts/install-launchagent.sh + @if [ "$$(uname)" = "Darwin" ]; then \ + echo "Installing LaunchAgent (macOS)..."; \ + ./scripts/install-launchagent.sh; \ + else \ + echo "Installing systemd service (Linux)..."; \ + ./scripts/install-systemd.sh; \ + fi @echo "" @echo "Adding to Claude Code..." @CLAUDE_CMD=$$(command -v claude || echo "$$HOME/.local/bin/claude"); \ @@ -56,35 +61,51 @@ install: venv @echo "Make sure ~/.local/bin is in your PATH:" @echo ' export PATH="$$HOME/.local/bin:$$PATH"' -# Restart the LaunchAgent (pick up code changes) +# Restart the service (pick up code changes) restart: - @PLIST="$$HOME/Library/LaunchAgents/com.evansenter.claude-session-analytics.plist"; \ - if [ -f "$$PLIST" ]; then \ + @if [ "$$(uname)" = "Darwin" ]; then \ + PLIST="$$HOME/Library/LaunchAgents/com.evansenter.claude-session-analytics.plist"; \ + if [ -f "$$PLIST" ]; then \ + echo "Restarting session-analytics..."; \ + launchctl unload "$$PLIST" 2>/dev/null || true; \ + launchctl load "$$PLIST"; \ + sleep 1; \ + if launchctl list | grep -q "com.evansenter.claude-session-analytics"; then \ + echo "Service restarted successfully"; \ + else \ + echo "Error: Service failed to start. Check ~/.claude/session-analytics.err"; \ + exit 1; \ + fi; \ + else \ + echo "LaunchAgent not installed. Run: make install"; \ + exit 1; \ + fi; \ + else \ echo "Restarting session-analytics..."; \ - launchctl unload "$$PLIST" 2>/dev/null || true; \ - launchctl load "$$PLIST"; \ + systemctl --user restart claude-session-analytics; \ sleep 1; \ - if launchctl list | grep -q "com.evansenter.claude-session-analytics"; then \ + if systemctl --user is-active claude-session-analytics &>/dev/null; then \ echo "Service restarted successfully"; \ else \ echo "Error: Service failed to start. Check ~/.claude/session-analytics.err"; \ exit 1; \ fi; \ - else \ - echo "LaunchAgent not installed. Run: make install"; \ - exit 1; \ fi -# Reinstall: pip install + restart LaunchAgent (picks up code changes) +# Reinstall: pip install + restart service (picks up code changes) reinstall: venv @echo "Reinstalling package..." .venv/bin/pip install -e . @$(MAKE) restart -# Uninstall: LaunchAgent + CLI + MCP config +# Uninstall: service + CLI + MCP config uninstall: @echo "Uninstalling..." - ./scripts/uninstall-launchagent.sh + @if [ "$$(uname)" = "Darwin" ]; then \ + ./scripts/uninstall-launchagent.sh; \ + else \ + ./scripts/uninstall-systemd.sh; \ + fi @echo "" @echo "Removing from Claude Code..." @CLAUDE_CMD=$$(command -v claude || echo "$$HOME/.local/bin/claude"); \ diff --git a/scripts/claude-session-analytics.service b/scripts/claude-session-analytics.service new file mode 100644 index 0000000..429dcf0 --- /dev/null +++ b/scripts/claude-session-analytics.service @@ -0,0 +1,16 @@ +[Unit] +Description=Claude Session Analytics - MCP server for session log analysis +After=network.target + +[Service] +Type=simple +WorkingDirectory=__PROJECT_DIR__ +Environment=PYTHONPATH=__PROJECT_DIR__/src +ExecStart=__VENV_PYTHON__ -m session_analytics.server +Restart=always +RestartSec=5 +StandardOutput=append:__HOME__/.claude/session-analytics.log +StandardError=append:__HOME__/.claude/session-analytics.err + +[Install] +WantedBy=default.target diff --git a/scripts/install-systemd.sh b/scripts/install-systemd.sh new file mode 100755 index 0000000..8578205 --- /dev/null +++ b/scripts/install-systemd.sh @@ -0,0 +1,63 @@ +#!/bin/bash +# Install the session analytics server as a Linux systemd user service (auto-starts on login) + +set -e + +SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" +PROJECT_DIR="$(dirname "$SCRIPT_DIR")" +VENV_PYTHON="$PROJECT_DIR/.venv/bin/python" +SERVICE_TEMPLATE="$SCRIPT_DIR/claude-session-analytics.service" +SERVICE_DIR="$HOME/.config/systemd/user" +SERVICE_DEST="$SERVICE_DIR/claude-session-analytics.service" +SERVICE_NAME="claude-session-analytics" + +# Check venv exists +if [[ ! -f "$VENV_PYTHON" ]]; then + echo "Error: Virtual environment not found at $PROJECT_DIR/.venv" + echo "Run: python3 -m venv .venv && source .venv/bin/activate && pip install -e ." + exit 1 +fi + +# Create directories if needed +mkdir -p "$SERVICE_DIR" +mkdir -p "$HOME/.claude/contrib/analytics" + +# Stop existing service if running +if systemctl --user is-active "$SERVICE_NAME" &>/dev/null; then + echo "Stopping existing service..." + systemctl --user stop "$SERVICE_NAME" +fi + +# Generate service file with correct paths +echo "Installing systemd service..." +sed -e "s|__VENV_PYTHON__|$VENV_PYTHON|g" \ + -e "s|__PROJECT_DIR__|$PROJECT_DIR|g" \ + -e "s|__HOME__|$HOME|g" \ + "$SERVICE_TEMPLATE" > "$SERVICE_DEST" + +# Reload systemd and start service +systemctl --user daemon-reload +echo "Starting service..." +systemctl --user enable --now "$SERVICE_NAME" + +# Verify it's running +sleep 1 +if systemctl --user is-active "$SERVICE_NAME" &>/dev/null; then + echo "" + echo "Session analytics installed and running!" + echo " Logs: ~/.claude/session-analytics.log" + echo " Errors: ~/.claude/session-analytics.err" + echo " Status: systemctl --user status $SERVICE_NAME" + echo "" + + # Also install CLI for use in hooks/scripts + echo "Installing CLI..." + "$SCRIPT_DIR/install-cli.sh" + echo "" + echo "To uninstall: $SCRIPT_DIR/uninstall-systemd.sh" +else + echo "Error: Service failed to start. Check logs:" + echo " journalctl --user -u $SERVICE_NAME" + echo " ~/.claude/session-analytics.err" + exit 1 +fi diff --git a/scripts/uninstall-systemd.sh b/scripts/uninstall-systemd.sh new file mode 100755 index 0000000..9985d79 --- /dev/null +++ b/scripts/uninstall-systemd.sh @@ -0,0 +1,33 @@ +#!/bin/bash +# Uninstall the session analytics systemd user service (preserves database) + +set -e + +SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" +SERVICE_DEST="$HOME/.config/systemd/user/claude-session-analytics.service" +SERVICE_NAME="claude-session-analytics" + +# Stop and disable service if running +if systemctl --user is-active "$SERVICE_NAME" &>/dev/null; then + echo "Stopping service..." + systemctl --user stop "$SERVICE_NAME" +fi + +if systemctl --user is-enabled "$SERVICE_NAME" &>/dev/null; then + echo "Disabling service..." + systemctl --user disable "$SERVICE_NAME" +fi + +# Remove service file +if [[ -f "$SERVICE_DEST" ]]; then + echo "Removing service file..." + rm "$SERVICE_DEST" + systemctl --user daemon-reload +fi + +# Uninstall CLI +"$SCRIPT_DIR/uninstall-cli.sh" + +echo "" +echo "Session analytics uninstalled." +echo "Note: Database preserved at ~/.claude/contrib/analytics/data.db"