From 47e7dcbf33b825570a629760523eac7a374c06a7 Mon Sep 17 00:00:00 2001 From: Matthew Taylor Date: Wed, 14 Jan 2026 14:22:47 -0800 Subject: [PATCH] Add IDE selector for file links in HTML reports - Add IDE selector UI with buttons for VS Code, Cursor, Augment, and File - Position selector just above Findings section for clear context - Store user preference in localStorage for persistence across reports - Generate links with data-file and data-line attributes for dynamic switching - Support IDE URL protocols: vscode://file, cursor://file, augment://file Closes #65 Co-Authored-By: Claude Opus 4.5 --- dist/bin/json-to-html.py | 6 +- dist/bin/templates/report-template.html | 113 ++++++++++++++++++++++++ 2 files changed, 116 insertions(+), 3 deletions(-) diff --git a/dist/bin/json-to-html.py b/dist/bin/json-to-html.py index fc0e8be..2f25407 100755 --- a/dist/bin/json-to-html.py +++ b/dist/bin/json-to-html.py @@ -170,13 +170,13 @@ def main(): # Create clickable links for scanned paths abs_path = os.path.abspath(paths) if not os.path.isabs(paths) else paths - paths_link = f'{paths}' + paths_link = f'{paths}' # Create clickable link for JSON log file json_log_link = "" if os.path.isfile(input_json): abs_json_path = os.path.abspath(input_json) - log_link = f'{input_json}' + log_link = f'{input_json}' json_log_link = f'
JSON Log: {log_link}
' # Determine status @@ -217,7 +217,7 @@ def main(): {impact.upper()}
- +
{code_escaped}
''' diff --git a/dist/bin/templates/report-template.html b/dist/bin/templates/report-template.html index da42c06..dc8c797 100644 --- a/dist/bin/templates/report-template.html +++ b/dist/bin/templates/report-template.html @@ -273,6 +273,57 @@ border-bottom: 1px solid #dee2e6; } + /* IDE Selector Styles */ + .ide-selector { + display: flex; + align-items: center; + gap: 8px; + margin-bottom: 20px; + flex-wrap: wrap; + } + + .ide-selector-label { + font-size: 0.9em; + color: #495057; + font-weight: 500; + } + + .ide-buttons { + display: flex; + gap: 8px; + flex-wrap: wrap; + } + + .ide-btn { + padding: 4px 12px; + border: 1px solid #dee2e6; + border-radius: 4px; + background: white; + color: #495057; + font-size: 0.8em; + font-weight: 500; + cursor: pointer; + transition: all 0.2s ease; + display: flex; + align-items: center; + gap: 4px; + } + + .ide-btn:hover { + border-color: #667eea; + background: #f0f4ff; + } + + .ide-btn.active { + border-color: #667eea; + background: #667eea; + color: white; + } + + .ide-btn .ide-icon { + font-size: 1.1em; + } + .search-input-wrapper { position: relative; width: 100%; @@ -564,6 +615,16 @@

🤖 Phase 2 (TL;DR) - AI Triage Summary

📋 Findings ({{FINDINGS_COUNT}})

+ +
+ Open in: +
+ + + + +
+
{{FINDINGS_HTML}}
@@ -630,8 +691,60 @@

✓ Checks Summary

}); } + // IDE Protocol Configuration + const ideProtocols = { + vscode: { prefix: 'vscode://file', format: (file, line) => line ? `vscode://file${file}:${line}` : `vscode://file${file}` }, + cursor: { prefix: 'cursor://file', format: (file, line) => line ? `cursor://file${file}:${line}` : `cursor://file${file}` }, + augment: { prefix: 'augment://file', format: (file, line) => line ? `augment://file${file}:${line}` : `augment://file${file}` }, + file: { prefix: 'file://', format: (file, line) => `file://${file}` } + }; + + // IDE Selector functionality + function initIdeSelector() { + const ideButtons = document.querySelectorAll('.ide-btn'); + const ideLinks = document.querySelectorAll('.ide-link'); + + // Load saved preference or default to 'file' + const savedIde = localStorage.getItem('wp-code-check-ide') || 'file'; + + // Set initial active state and update links + updateIdeSelection(savedIde, ideButtons, ideLinks); + + // Add click handlers to IDE buttons + ideButtons.forEach(btn => { + btn.addEventListener('click', function() { + const ide = this.dataset.ide; + localStorage.setItem('wp-code-check-ide', ide); + updateIdeSelection(ide, ideButtons, ideLinks); + }); + }); + } + + function updateIdeSelection(ide, buttons, links) { + // Update button states + buttons.forEach(btn => { + if (btn.dataset.ide === ide) { + btn.classList.add('active'); + } else { + btn.classList.remove('active'); + } + }); + + // Update all links + const protocol = ideProtocols[ide] || ideProtocols.file; + links.forEach(link => { + const file = link.dataset.file; + const line = link.dataset.line; + if (file) { + link.href = protocol.format(file, line); + } + }); + } + // Convert UTC timestamp to local time document.addEventListener('DOMContentLoaded', function() { + // Initialize IDE selector + initIdeSelector(); // Get the UTC timestamp from the page const utcTimestamp = '{{TIMESTAMP}}';