--- name: chronicle-remote-summarizer description: Automate cross-system summarization workflow for Chronicle sessions. Export sessions from remote systems (like FreeBSD) and import/summarize on local machine with Gemini API. Use when you have sessions on a system without Gemini API access and need to summarize them on another machine. --- # Chronicle Remote Summarizer This skill automates the workflow for summarizing Chronicle sessions across different systems (e.g., FreeBSD dev machine → Mac with Gemini API). ## Auto-Activation > **This skill auto-activates!** (Milestone #13) > > Prompts like "summarize session on remote" or "import session from FreeBSD" automatically trigger this skill! > > **Trigger patterns:** remote, freebsd, import session, summarize on remote > **See:** `docs/HOOKS.md` for full details ## When to Use This Skill Use this skill when: - You have Chronicle sessions on a remote system without Gemini API configured - You want to summarize those sessions on your local machine (which has Gemini API) - You need to transfer the summary back to the original system - You're working across multiple development environments (FreeBSD, Linux, macOS) **Common scenario**: FreeBSD development server (no Gemini API) → macOS laptop (has Gemini API key) ## How It Works Chronicle provides `import-and-summarize --quiet` which: 1. Creates temporary session with negative ID (e.g., `-3`) 2. Generates AI summary using Gemini 3. **Auto-cleanup**: Deletes temporary session and files 4. Outputs **clean JSON** to stdout (no status messages with `--quiet`) **No pollution between systems** - the remote session stays on the remote system, only the summary is transferred. ## Recommended Workflow: One-Line Command **Prerequisites:** - SSH access from local machine to remote machine - Chronicle installed on both systems - Gemini API key configured on local machine (`chronicle config ai.gemini_api_key YOUR_KEY`) - **Optional**: Remote system configured in Chronicle config (automates hostname/path) **Step 1: Configure Remote System (One-Time Setup)** ```bash # Configure FreeBSD remote system chronicle config remote_systems.freebsd.hostname "chandlerhardy-dev.aws0.pla-net.cc" chronicle config remote_systems.freebsd.chronicle_path "/home/chandlerhardy/.local/bin/chronicle" # Verify configuration chronicle config --list | grep freebsd ``` **Step 2: Use the Skill** When Claude uses this skill and finds remote system configuration, it will automatically construct the command: ```bash ssh chandlerhardy-dev.aws0.pla-net.cc "/home/chandlerhardy/.local/bin/chronicle export-session 7" | chronicle import-and-summarize --quiet 2>&1 | grep -A 999999 '^{$' | ssh chandlerhardy-dev.aws0.pla-net.cc "/home/chandlerhardy/.local/bin/chronicle import-summary" ``` **If no config found**, Claude will ask for the hostname and construct the command interactively: **Command (Manual):** ```bash ssh "chronicle export-session " | chronicle import-and-summarize --quiet 2>&1 | grep -A 999999 '^{$' | ssh "chronicle import-summary" ``` **Example:** ```bash ssh freebsd "chronicle export-session 7" | chronicle import-and-summarize --quiet 2>&1 | grep -A 999999 '^{$' | ssh freebsd "chronicle import-summary" ``` **Note:** The `grep -A 999999 '^{$'` filters out Google library warnings that can leak through even with `--quiet` and `2>/dev/null`. **What this does:** 1. **Remote → Local**: Export session 7 as JSON 2. **Local**: Import, summarize with Gemini, auto-cleanup temporary session 3. **Local → Remote**: Send summary JSON back 4. **Remote**: Update session 7 with the summary **Why `--quiet` works:** - Suppresses ALL status messages from summarizer - Outputs ONLY clean JSON to stdout (essential for piping) - No need to manually extract JSON from verbose output - `2>/dev/null` suppresses Google library warnings (harmless) **Time:** Typically 30-60 seconds for large sessions (depends on transcript size) ## Alternative: Manual 3-Step Workflow If SSH pipes hang or you need to inspect intermediate files: ### Step 1: Export session from remote ```bash ssh "chronicle export-session " > /tmp/session_.json ``` **Example:** ```bash ssh freebsd "chronicle export-session 7" > /tmp/session_7.json ``` ### Step 2: Summarize locally (transient) ```bash cat /tmp/session_.json | chronicle import-and-summarize --quiet 2>/dev/null > /tmp/summary.json ``` **Example:** ```bash cat /tmp/session_7.json | chronicle import-and-summarize --quiet 2>/dev/null > /tmp/summary.json ``` **What happens:** - Creates temporary session (negative ID like `-3`) - Generates summary with Gemini - **Auto-cleanup**: Deletes temporary session and transcript files - Outputs summary JSON to `/tmp/summary.json` ### Step 3: Send summary back to remote ```bash cat /tmp/summary.json | ssh "chronicle import-summary" ``` **Example:** ```bash cat /tmp/summary.json | ssh freebsd "chronicle import-summary" ``` **Result:** - ✅ Summary stored in remote database linked to original session - ✅ Local system stays clean (temporary session auto-deleted) - ✅ No data pollution between systems ## What Actually Happens (Under the Hood) **On `import-and-summarize --quiet`:** 1. **Import**: Reads session JSON from stdin 2. **Create Temporary Session**: - Assigns negative ID (e.g., `-1`, `-2`, `-3`) - Stores transcript in `~/.ai-session/sessions/session_-3.cleaned` - Creates database entry with `is_session=True` 3. **Summarize**: - Runs `summarize_session_chunked()` with Gemini API - Processes large transcripts in chunks (10,000 lines per chunk) - Updates session with AI-generated summary 4. **Output JSON**: ```json { "version": "1.0", "original_id": 7, "summary": "AI-generated summary...", "summary_generated": true, "keywords": ["feature", "implementation", "testing"] } ``` 5. **Auto-Cleanup**: - Deletes transcript file (`session_-3.cleaned`) - Deletes database entry (temporary session) - **Only the summary JSON remains** (piped to stdout) **On `import-summary` (remote side):** 1. **Read JSON**: Reads summary from stdin 2. **Find Session**: Looks up session by `original_id` (e.g., 7) 3. **Update**: Sets `response_summary`, `summary_generated=True`, `keywords` 4. **Done**: Session 7 now has the AI summary ## Session Examples **Tested with:** - Session 1: 16.3 minutes, system test - Session 2: 66.7 minutes, large session - Session 4: 23KB JSON export All sessions work perfectly with this workflow. ## Troubleshooting ### SSH Pipes Hang **Symptom:** Command hangs indefinitely **Solution:** Use manual 3-step workflow instead: ```bash # Step 1: Export to file ssh freebsd "chronicle export-session 7" > /tmp/session.json # Step 2: Process locally cat /tmp/session.json | chronicle import-and-summarize --quiet > /tmp/summary.json # Step 3: Send back cat /tmp/summary.json | ssh freebsd "chronicle import-summary" ``` ### Gemini API Not Configured **Symptom:** `ImportError: google-generativeai package not installed` **Solution:** Configure Gemini API key on local machine: ```bash chronicle config ai.gemini_api_key YOUR_API_KEY_HERE ``` Get free API key: https://ai.google.dev/ ### Session Not Found **Symptom:** `Session 7 not found` **Solution:** Check session exists on remote: ```bash ssh freebsd "chronicle sessions --limit 20" ``` ### Summary Already Exists **Behavior:** `import-and-summarize` will **overwrite** existing summaries **Note:** This is by design - you can re-summarize sessions if needed. ## Tips - **Use `--quiet` flag**: Essential for piping - suppresses status messages - **Suppress stderr**: Add `2>/dev/null` to hide Google library warnings - **Check SSH paths**: Remote Chronicle might be in `~/.local/bin/chronicle` - **Inspect files**: Use 3-step workflow to save intermediate JSON for debugging - **Large sessions**: 10K+ line transcripts are chunked automatically (no action needed) - **Network failures**: Use 3-step workflow for unreliable connections - **Batch processing**: You can script this to process multiple sessions ## How Claude Should Use This Skill **When invoked, Claude should:** 1. **Check for remote system config:** ```bash chronicle config --list | grep remote_systems ``` 2. **If config exists** (e.g., `remote_systems.freebsd.hostname`): - Read hostname: `chronicle config remote_systems.freebsd.hostname` - Read chronicle path: `chronicle config remote_systems.freebsd.chronicle_path` - Construct command automatically - Announce: "Found FreeBSD config, using: ``" 3. **If no config exists:** - Ask user: "What's the hostname of your remote system?" - Ask: "What's the path to chronicle on the remote? (default: chronicle)" - Optionally suggest: "I can save this to config for future use" - Construct command with user-provided values 4. **Run the command** and monitor output 5. **Confirm success** or handle errors ## Example Usage **User:** "I have session 7 on my FreeBSD dev machine that needs summarization, but FreeBSD doesn't have Gemini API. Can you summarize it here on my Mac?" **Assistant (with config):** 1. Checks config: `chronicle config remote_systems.freebsd.hostname` 2. Finds: `chandlerhardy-dev.aws0.pla-net.cc` 3. Announces: "Found FreeBSD config, using chandlerhardy-dev.aws0.pla-net.cc" 4. Runs the command: ```bash ssh chandlerhardy-dev.aws0.pla-net.cc "/home/chandlerhardy/.local/bin/chronicle export-session 7" | chronicle import-and-summarize --quiet 2>&1 | grep -A 999999 '^{$' | ssh chandlerhardy-dev.aws0.pla-net.cc "/home/chandlerhardy/.local/bin/chronicle import-summary" ``` 5. Confirms: "Session 7 summarized successfully and summary imported back to FreeBSD" **Assistant (without config):** 1. Checks config: `chronicle config --list | grep remote_systems` 2. No FreeBSD config found 3. Asks: "What's your FreeBSD hostname?" 4. User provides: `chandlerhardy-dev.aws0.pla-net.cc` 5. Asks: "What's the path to chronicle on FreeBSD? (press Enter for default 'chronicle')" 6. User provides: `/home/chandlerhardy/.local/bin/chronicle` 7. Suggests: "I can save this to config for future use. Would you like me to?" 8. Runs the command with provided values 9. If user agrees, saves config for next time **If one-liner hangs:** 1. Falls back to 3-step workflow 2. Exports to `/tmp/session_7.json` 3. Processes locally → `/tmp/summary.json` 4. Imports summary back to remote 5. Confirms success ## Advanced Usage ### Batch Summarize Multiple Sessions ```bash # List unsummarized sessions on remote ssh freebsd "chronicle sessions --limit 50" | grep "No summary" # For each session ID (7, 8, 9): for id in 7 8 9; do echo "Summarizing session $id..." ssh freebsd "chronicle export-session $id" | \ chronicle import-and-summarize --quiet 2>/dev/null | \ ssh freebsd "chronicle import-summary" done ``` ### Inspect Summary Before Importing ```bash # Export and summarize ssh freebsd "chronicle export-session 7" | \ chronicle import-and-summarize --quiet 2>/dev/null > /tmp/summary.json # Review summary cat /tmp/summary.json | jq '.summary' # If satisfied, import cat /tmp/summary.json | ssh freebsd "chronicle import-summary" ``` ### Debug Verbose Output If you need to see what's happening, remove `--quiet`: ```bash ssh freebsd "chronicle export-session 7" | chronicle import-and-summarize # Shows: "Importing session...", "Summarizing...", "Cleaning up...", then JSON ``` **Note:** Without `--quiet`, JSON is NOT at line 1, so it won't pipe cleanly to `import-summary`. ## Related Commands - `chronicle export-session ` - Export session as JSON - `chronicle import-session` - Import session (permanent, gets new ID) - `chronicle import-and-summarize` - Import + summarize + auto-cleanup (transient) - `chronicle import-summary` - Update existing session with summary - `chronicle session ` - View session details and summary ## See Also - **REMOTE_SUMMARIZE_WORKFLOW.md** - Full workflow documentation with examples - **tests/test_import_export.py** - 17 tests covering all import/export scenarios - **chronicle-session-documenter** - Document sessions to Obsidian vault after summarization