Add a "View in web" link to the run summary, and make the logo clickable

This commit is contained in:
Jonathan Singer
2026-07-20 10:04:40 -04:00
parent 8bbcafcf1a
commit 11c7eef082
5 changed files with 127 additions and 69 deletions
+57 -8
View File
@@ -7,6 +7,7 @@ import argparse
import asyncio
import shutil
import sys
import time
from datetime import UTC, datetime
from pathlib import Path
@@ -720,7 +721,9 @@ def _load_resume_state(args: argparse.Namespace, parser: argparse.ArgumentParser
args.scan_mode = persisted_scan_mode
def display_completion_message(args: argparse.Namespace, results_path: Path) -> None:
def display_completion_message(
args: argparse.Namespace, results_path: Path, web_url: str | None = None
) -> None:
console = Console()
report_state = get_global_report_state()
@@ -759,12 +762,28 @@ def display_completion_message(args: argparse.Namespace, results_path: Path) ->
results_text.append(str(results_path), style="#60a5fa")
panel_parts.extend(["\n", results_text])
view_text = Text()
view_text.append("\n")
view_text.append("View", style="dim")
view_text.append(" ")
view_text.append(f"strix view {args.run_name}", style="#22c55e")
panel_parts.extend(["\n", view_text])
if web_url:
web_text = Text()
web_text.append("\n")
web_text.append("View in web", style="dim")
web_text.append(" ")
# OSC-8 hyperlink: clickable in modern terminals, falls back to the URL.
web_text.append(web_url, style=f"#60a5fa link {web_url}")
panel_parts.extend(["\n", web_text])
reopen_text = Text()
reopen_text.append("\n")
reopen_text.append("Reopen", style="dim")
reopen_text.append(" ")
reopen_text.append(f"strix view {args.run_name}", style="#22c55e")
panel_parts.extend(["\n", reopen_text])
else:
view_text = Text()
view_text.append("\n")
view_text.append("View", style="dim")
view_text.append(" ")
view_text.append(f"strix view {args.run_name}", style="#22c55e")
panel_parts.extend(["\n", view_text])
if not scan_completed:
resume_text = Text()
@@ -955,7 +974,37 @@ def main() -> None:
scarf.end(report_state, exit_reason=exit_reason)
results_path = run_dir_for(args.run_name)
display_completion_message(args, results_path)
# For an interactive run, host the local viewer so the completion panel can
# show a clickable "View in web" link. Skipped in non-interactive/CI runs
# (no TTY to serve and it would block the process).
viewer_httpd = None
web_url = None
if not args.non_interactive and sys.stdout.isatty():
from strix.viewer.server import bundle_is_built, serve
if bundle_is_built():
try:
viewer_httpd, web_url = serve(results_path, open_browser=False)
posthog.viewer_opened(source="post_scan", live=False)
except Exception:
logger.debug("could not start local viewer", exc_info=True)
viewer_httpd, web_url = None, None
display_completion_message(args, results_path, web_url=web_url)
if viewer_httpd is not None:
console = Console()
console.print("[dim]Hosting the local viewer. Press Ctrl-C to stop.[/]")
console.print()
try:
while True:
time.sleep(1)
except KeyboardInterrupt:
console.print("\n[dim]Viewer stopped.[/]")
finally:
viewer_httpd.shutdown()
viewer_httpd.server_close()
if args.non_interactive:
report_state = get_global_report_state()
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
+2 -2
View File
@@ -6,8 +6,8 @@
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<meta name="color-scheme" content="dark" />
<title>Strix Results</title>
<script type="module" crossorigin src="./assets/index-CCvWcFs6.js"></script>
<link rel="stylesheet" crossorigin href="./assets/index-D743S243.css">
<script type="module" crossorigin src="./assets/index-HNJsx9zD.js"></script>
<link rel="stylesheet" crossorigin href="./assets/index-F6wiPyoI.css">
</head>
<body>
<div id="root"></div>
+11 -2
View File
@@ -113,8 +113,17 @@ export default function App() {
{/* Top bar */}
<div className="border-b border-[#222]">
<div className="max-w-[88rem] mx-auto px-6 py-4 flex items-center gap-1.5">
<img src="./logo.png" alt="Strix Logo" className="w-10 h-8 object-cover opacity-90" />
<div className="text-base text-white font-medium tracking-tight">Strix</div>
<a
href="https://app.strix.ai"
target="_blank"
rel="noopener noreferrer"
onClick={() => trackCta("logo")}
className="flex items-center gap-1.5 opacity-90 transition-opacity hover:opacity-100"
title="Open Strix Cloud"
>
<img src="./logo.png" alt="Strix" className="w-10 h-8 object-cover" />
<div className="text-base text-white font-medium tracking-tight">Strix</div>
</a>
<span className="ml-3 text-xs text-[#666]">Local results</span>
{run && <LiveIndicator finished={run.finished} />}
</div>