| name | sync-report |
| description | Generate diagnostic HTML reports from utility-bill-manager sync logs. Analyzes logs for errors, identifies root causes, and creates a visual report in a temp directory. Use when debugging failed syncs, understanding why 0 bills were downloaded, or reviewing navigator behavior. |
| tools | Bash, Read, Write, Grep |
Sync Report Generator
Generate visual HTML diagnostic reports from utility-bill-manager sync logs. Reports are created in a temp directory (not in the repo) and automatically opened in the browser.
Usage
Invoke this skill with:
- A log file path:
/sync-report /path/to/sync.log
- Or paste the log content directly after invoking
What It Analyzes
Error Categories
| Category | Patterns | Severity |
|---|
| VectorDB | sqlite-vec search failed, SqliteError | High |
| LLM Failures | LLM failed, No high-confidence memory match | Medium |
| Selector Issues | not found on page, Invalid selector, SyntaxError | High |
| Element Issues | detached from DOM, Element detached | Medium |
| PDF Download | Could not extract PDF, blob extraction failed | High |
| Navigation | FAILED:, action_failed | Medium |
| Timeout | exceeded timeout, timed out | Medium |
Metrics Extracted
- Total navigation steps
- Successful vs failed actions
- Bills found (from HTML extraction)
- Bills downloaded (actual PDFs)
- LLM call count and failure rate
- VectorDB query errors
- Popup tracking stats
Workflow
Step 1: Locate the Log
If user provides a file path, read it. Otherwise, check recent logs:
ls -lt ~/Library/Logs/utility-bill-manager/*.log 2>/dev/null | head -5
ls -lt /tmp/utility-bill-manager*.log 2>/dev/null | head -5
Step 2: Extract Key Events
Parse the log for important events:
grep -c "ERROR\|FAILED\|failed" "$LOG_FILE"
grep "VectorDB.*failed\|SqliteError" "$LOG_FILE"
grep "not found on page\|SyntaxError" "$LOG_FILE"
grep "LLM failed\|LLM.*trying" "$LOG_FILE"
grep "bills downloaded\|PDF.*captured\|PDF.*extracted" "$LOG_FILE"
grep "HTML-EXTRACT" "$LOG_FILE"
Step 3: Generate the HTML Report
Create the report in the scratchpad directory (session-specific temp):
SCRATCHPAD="${CLAUDE_SCRATCHPAD:-/tmp/claude-sync-reports}"
mkdir -p "$SCRATCHPAD"
REPORT_FILE="$SCRATCHPAD/sync-report-$(date +%Y%m%d-%H%M%S).html"
Step 4: Report Structure
The HTML report should include:
-
Summary Card
- Sync result (success/failure)
- Bills found vs downloaded
- Total steps / errors
- Duration
-
Failure Cascade Flow
- Visual diagram showing how errors propagated
- Arrow-connected boxes for each stage
-
Root Causes
- Card for each identified issue
- Status badge (fixed/unfixed/mitigated)
- Code snippets from log
- Impact description
-
Event Timeline
- Chronological list of important events
- Color-coded by severity
- Timestamps and log excerpts
-
Recommendations
- Actionable next steps
- Priority levels
Step 5: Open the Report
open "$REPORT_FILE"
xdg-open "$REPORT_FILE" 2>/dev/null || echo "Report saved to: $REPORT_FILE"
HTML Template
Use this template structure for the report:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Sync Diagnostic Report</title>
<style>
:root {
--bg: #0f1419;
--card-bg: #1a1f2e;
--accent: #3b82f6;
--success: #10b981;
--warning: #f59e0b;
--error: #ef4444;
--text: #e5e7eb;
--text-muted: #9ca3af;
--border: #374151;
}
body {
font-family: 'SF Mono', 'Fira Code', monospace;
background: var(--bg);
color: var(--text);
padding: 2rem;
line-height: 1.6;
}
.container { max-width: 1200px; margin: 0 auto; }
.card {
: (--card-bg);
: ;
: ;
: ;
: solid (--border);
}
{
: inline-block;
: ;
: ;
: ;
: ;
}
{ : (, , , ); : (--error); }
{ : (, , , ); : (--success); }
{ : (, , , ); : (--warning); }
{ : (--accent); }
{ : solid (--border); : ; }
pre {
: ;
: ;
: ;
: auto;
: ;
}
{
: relative;
: ;
}
{
: ;
: absolute;
: ;
: ;
: ;
: ;
: (--border);
}
{
: relative;
: ;
}
{
: ;
: absolute;
: -;
: ;
: ;
: ;
: ;
: (--border);
}
{ : (--error); }
{ : (--success); }
{
: flex;
: wrap;
: ;
: center;
}
{
: (--card-bg);
: ;
: ;
: ;
: solid (--border);
}
{ : (--error); : (--error); }
{ : (--success); : (--success); }
{ : (--text-muted); }
Sync Diagnostic Report
Generated: [TIMESTAMP] | Profile: [PROFILE]
Result: [RESULT]
Steps: [STEPS] | Errors: [ERRORS] | Bills: [DOWNLOADED]/[FOUND]
Failure Cascade
[FLOW_STEPS]
Issues Identified
[ISSUE_CARDS]
Event Timeline
[TIMELINE_ITEMS]
Recommendations
[RECOMMENDATIONS]
Issue Detection Patterns
VectorDB Error
Pattern: "sqlite-vec search failed" OR "SqliteError"
Root Cause: LIMIT and k=? conflict in query
Impact: Navigation memory disabled, forces LLM fallback
Invalid CSS Selector
Pattern: "SyntaxError" + "querySelectorAll" + ":has-text"
Root Cause: Playwright selector used with native DOM API
Impact: Retry logic fails completely
Blob Extraction Failure
Pattern: "Could not extract PDF content from blob"
Root Cause: Cross-origin restriction on blob URL
Impact: PDF viewer opens but content not captured
Element Detachment
Pattern: "detached from DOM" OR "Element detached"
Root Cause: SPA navigation changes DOM during click
Impact: Click succeeds but follow-up actions fail
LLM Exhaustion
Pattern: "LLM failed Xx" followed by "hardcoded fallback"
Root Cause: Vision model couldn't identify correct element
Impact: Falls back to potentially stale selectors
Example Output
After running, report the location:
Sync diagnostic report generated:
/tmp/claude-sync-reports/sync-report-20260204-063126.html
Opening in browser...
Related Files
/Users/mcai/src/util/utility-bill-manager/electron/main/services/intelligent-navigator.ts - Main navigation
/Users/mcai/src/util/utility-bill-manager/electron/main/services/vector-db.ts - Navigation memory
/Users/mcai/src/util/utility-bill-manager/electron/main/services/browser-agent.ts - PDF handling