@@ -1452,8 +1452,47 @@ def local_cmd(output, output_auto, repo, gist, include_json, open_browser, limit
14521452 webbrowser .open (index_url )
14531453
14541454
1455+ def is_url (path ):
1456+ """Check if a path is a URL (starts with http:// or https://)."""
1457+ return path .startswith ("http://" ) or path .startswith ("https://" )
1458+
1459+
1460+ def fetch_url_to_tempfile (url ):
1461+ """Fetch a URL and save to a temporary file.
1462+
1463+ Returns the Path to the temporary file.
1464+ Raises click.ClickException on network errors.
1465+ """
1466+ try :
1467+ response = httpx .get (url , timeout = 60.0 , follow_redirects = True )
1468+ response .raise_for_status ()
1469+ except httpx .RequestError as e :
1470+ raise click .ClickException (f"Failed to fetch URL: { e } " )
1471+ except httpx .HTTPStatusError as e :
1472+ raise click .ClickException (
1473+ f"Failed to fetch URL: { e .response .status_code } { e .response .reason_phrase } "
1474+ )
1475+
1476+ # Determine file extension from URL
1477+ url_path = url .split ("?" )[0 ] # Remove query params
1478+ if url_path .endswith (".jsonl" ):
1479+ suffix = ".jsonl"
1480+ elif url_path .endswith (".json" ):
1481+ suffix = ".json"
1482+ else :
1483+ suffix = ".jsonl" # Default to JSONL
1484+
1485+ # Extract a name from the URL for the temp file
1486+ url_name = Path (url_path ).stem or "session"
1487+
1488+ temp_dir = Path (tempfile .gettempdir ())
1489+ temp_file = temp_dir / f"claude-url-{ url_name } { suffix } "
1490+ temp_file .write_text (response .text , encoding = "utf-8" )
1491+ return temp_file
1492+
1493+
14551494@cli .command ("json" )
1456- @click .argument ("json_file" , type = click .Path (exists = True ))
1495+ @click .argument ("json_file" , type = click .Path ())
14571496@click .option (
14581497 "-o" ,
14591498 "--output" ,
@@ -1488,29 +1527,45 @@ def local_cmd(output, output_auto, repo, gist, include_json, open_browser, limit
14881527 help = "Open the generated index.html in your default browser (default if no -o specified)." ,
14891528)
14901529def json_cmd (json_file , output , output_auto , repo , gist , include_json , open_browser ):
1491- """Convert a Claude Code session JSON/JSONL file to HTML."""
1530+ """Convert a Claude Code session JSON/JSONL file or URL to HTML."""
1531+ # Handle URL input
1532+ if is_url (json_file ):
1533+ click .echo (f"Fetching { json_file } ..." )
1534+ temp_file = fetch_url_to_tempfile (json_file )
1535+ json_file_path = temp_file
1536+ # Use URL path for naming
1537+ url_name = Path (json_file .split ("?" )[0 ]).stem or "session"
1538+ else :
1539+ # Validate that local file exists
1540+ json_file_path = Path (json_file )
1541+ if not json_file_path .exists ():
1542+ raise click .ClickException (f"File not found: { json_file } " )
1543+ url_name = None
1544+
14921545 # Determine output directory and whether to open browser
14931546 # If no -o specified, use temp dir and open browser by default
14941547 auto_open = output is None and not gist and not output_auto
14951548 if output_auto :
14961549 # Use -o as parent dir (or current dir), with auto-named subdirectory
14971550 parent_dir = Path (output ) if output else Path ("." )
1498- output = parent_dir / Path ( json_file ) .stem
1551+ output = parent_dir / ( url_name or json_file_path .stem )
14991552 elif output is None :
1500- output = Path (tempfile .gettempdir ()) / f"claude-session-{ Path (json_file ).stem } "
1553+ output = (
1554+ Path (tempfile .gettempdir ())
1555+ / f"claude-session-{ url_name or json_file_path .stem } "
1556+ )
15011557
15021558 output = Path (output )
1503- generate_html (json_file , output , github_repo = repo )
1559+ generate_html (json_file_path , output , github_repo = repo )
15041560
15051561 # Show output directory
15061562 click .echo (f"Output: { output .resolve ()} " )
15071563
15081564 # Copy JSON file to output directory if requested
15091565 if include_json :
15101566 output .mkdir (exist_ok = True )
1511- json_source = Path (json_file )
1512- json_dest = output / json_source .name
1513- shutil .copy (json_file , json_dest )
1567+ json_dest = output / json_file_path .name
1568+ shutil .copy (json_file_path , json_dest )
15141569 json_size_kb = json_dest .stat ().st_size / 1024
15151570 click .echo (f"JSON: { json_dest } ({ json_size_kb :.1f} KB)" )
15161571
0 commit comments