@@ -304,7 +304,11 @@ def find_all_sessions(folder, include_agents=False):
304304
305305
306306def generate_batch_html (
307- source_folder , output_dir , include_agents = False , progress_callback = None
307+ source_folder ,
308+ output_dir ,
309+ include_agents = False ,
310+ progress_callback = None ,
311+ paginate = False ,
308312):
309313 """Generate HTML archive for all sessions in a Claude projects folder.
310314
@@ -319,6 +323,7 @@ def generate_batch_html(
319323 include_agents: Whether to include agent-* session files
320324 progress_callback: Optional callback(project_name, session_name, current, total)
321325 called after each session is processed
326+ paginate: Whether to generate paginated output
322327
323328 Returns statistics dict with total_projects, total_sessions, failed_sessions, output_dir.
324329 """
@@ -347,7 +352,7 @@ def generate_batch_html(
347352
348353 # Generate transcript HTML with error handling
349354 try :
350- generate_html (session ["path" ], session_dir )
355+ generate_html (session ["path" ], session_dir , paginate = paginate )
351356 successful_sessions += 1
352357 except Exception as e :
353358 failed_sessions .append (
@@ -1153,7 +1158,7 @@ def generate_index_pagination_html(total_pages):
11531158 return _macros .index_pagination (total_pages )
11541159
11551160
1156- def generate_html (json_path , output_dir , github_repo = None ):
1161+ def generate_html (json_path , output_dir , github_repo = None , paginate = False ):
11571162 output_dir = Path (output_dir )
11581163 output_dir .mkdir (exist_ok = True )
11591164
@@ -1212,6 +1217,58 @@ def generate_html(json_path, output_dir, github_repo=None):
12121217 total_convs = len (conversations )
12131218 total_pages = (total_convs + PROMPTS_PER_PAGE - 1 ) // PROMPTS_PER_PAGE
12141219
1220+ if not paginate :
1221+ messages_html = []
1222+ for conv in conversations :
1223+ is_first = True
1224+ for log_type , message_json , timestamp in conv ["messages" ]:
1225+ msg_html = render_message (log_type , message_json , timestamp )
1226+ if msg_html :
1227+ if is_first and conv .get ("is_continuation" ):
1228+ msg_html = f'<details class="continuation"><summary>Session continuation summary</summary>{ msg_html } </details>'
1229+ messages_html .append (msg_html )
1230+ is_first = False
1231+ page_template = get_template ("page.html" )
1232+ page_content = page_template .render (
1233+ css = CSS ,
1234+ js = JS ,
1235+ page_num = 1 ,
1236+ total_pages = 1 ,
1237+ pagination_html = "" ,
1238+ messages_html = "" .join (messages_html ),
1239+ paginate = False ,
1240+ )
1241+ index_path = output_dir / "index.html"
1242+ index_path .write_text (page_content , encoding = "utf-8" )
1243+ print (f"Generated { index_path .resolve ()} ({ total_convs } prompts)" )
1244+ return
1245+
1246+ if not paginate :
1247+ messages_html = []
1248+ for conv in conversations :
1249+ is_first = True
1250+ for log_type , message_json , timestamp in conv ["messages" ]:
1251+ msg_html = render_message (log_type , message_json , timestamp )
1252+ if msg_html :
1253+ if is_first and conv .get ("is_continuation" ):
1254+ msg_html = f'<details class="continuation"><summary>Session continuation summary</summary>{ msg_html } </details>'
1255+ messages_html .append (msg_html )
1256+ is_first = False
1257+ page_template = get_template ("page.html" )
1258+ page_content = page_template .render (
1259+ css = CSS ,
1260+ js = JS ,
1261+ page_num = 1 ,
1262+ total_pages = 1 ,
1263+ pagination_html = "" ,
1264+ messages_html = "" .join (messages_html ),
1265+ paginate = False ,
1266+ )
1267+ index_path = output_dir / "index.html"
1268+ index_path .write_text (page_content , encoding = "utf-8" )
1269+ print (f"Generated { index_path .resolve ()} ({ total_convs } prompts)" )
1270+ return
1271+
12151272 for page_num in range (1 , total_pages + 1 ):
12161273 start_idx = (page_num - 1 ) * PROMPTS_PER_PAGE
12171274 end_idx = min (start_idx + PROMPTS_PER_PAGE , total_convs )
@@ -1236,6 +1293,7 @@ def generate_html(json_path, output_dir, github_repo=None):
12361293 total_pages = total_pages ,
12371294 pagination_html = pagination_html ,
12381295 messages_html = "" .join (messages_html ),
1296+ paginate = True ,
12391297 )
12401298 (output_dir / f"page-{ page_num :03d} .html" ).write_text (
12411299 page_content , encoding = "utf-8"
@@ -1369,12 +1427,26 @@ def cli():
13691427 is_flag = True ,
13701428 help = "Open the generated index.html in your default browser (default if no -o specified)." ,
13711429)
1430+ @click .option (
1431+ "--paginate" ,
1432+ is_flag = True ,
1433+ help = "Enable pagination (default: single page)." ,
1434+ )
13721435@click .option (
13731436 "--limit" ,
13741437 default = 10 ,
13751438 help = "Maximum number of sessions to show (default: 10)" ,
13761439)
1377- def local_cmd (output , output_auto , repo , gist , include_json , open_browser , limit ):
1440+ def local_cmd (
1441+ output ,
1442+ output_auto ,
1443+ repo ,
1444+ gist ,
1445+ include_json ,
1446+ open_browser ,
1447+ paginate ,
1448+ limit ,
1449+ ):
13781450 """Select and convert a local Claude Code session to HTML."""
13791451 projects_folder = Path .home () / ".claude" / "projects"
13801452
@@ -1425,7 +1497,7 @@ def local_cmd(output, output_auto, repo, gist, include_json, open_browser, limit
14251497 output = Path (tempfile .gettempdir ()) / f"claude-session-{ session_file .stem } "
14261498
14271499 output = Path (output )
1428- generate_html (session_file , output , github_repo = repo )
1500+ generate_html (session_file , output , github_repo = repo , paginate = paginate )
14291501
14301502 # Show output directory
14311503 click .echo (f"Output: { output .resolve ()} " )
@@ -1487,7 +1559,14 @@ def local_cmd(output, output_auto, repo, gist, include_json, open_browser, limit
14871559 is_flag = True ,
14881560 help = "Open the generated index.html in your default browser (default if no -o specified)." ,
14891561)
1490- def json_cmd (json_file , output , output_auto , repo , gist , include_json , open_browser ):
1562+ @click .option (
1563+ "--paginate" ,
1564+ is_flag = True ,
1565+ help = "Enable pagination (default: single page)." ,
1566+ )
1567+ def json_cmd (
1568+ json_file , output , output_auto , repo , gist , include_json , open_browser , paginate
1569+ ):
14911570 """Convert a Claude Code session JSON/JSONL file to HTML."""
14921571 # Determine output directory and whether to open browser
14931572 # If no -o specified, use temp dir and open browser by default
@@ -1500,7 +1579,7 @@ def json_cmd(json_file, output, output_auto, repo, gist, include_json, open_brow
15001579 output = Path (tempfile .gettempdir ()) / f"claude-session-{ Path (json_file ).stem } "
15011580
15021581 output = Path (output )
1503- generate_html (json_file , output , github_repo = repo )
1582+ generate_html (json_file , output , github_repo = repo , paginate = paginate )
15041583
15051584 # Show output directory
15061585 click .echo (f"Output: { output .resolve ()} " )
@@ -1574,7 +1653,9 @@ def format_session_for_display(session_data):
15741653 return f"{ session_id } { created_at [:19 ] if created_at else 'N/A' :19} { title } "
15751654
15761655
1577- def generate_html_from_session_data (session_data , output_dir , github_repo = None ):
1656+ def generate_html_from_session_data (
1657+ session_data , output_dir , github_repo = None , paginate = False
1658+ ):
15781659 """Generate HTML from session data dict (instead of file path)."""
15791660 output_dir = Path (output_dir )
15801661 output_dir .mkdir (exist_ok = True , parents = True )
@@ -1627,6 +1708,32 @@ def generate_html_from_session_data(session_data, output_dir, github_repo=None):
16271708 total_convs = len (conversations )
16281709 total_pages = (total_convs + PROMPTS_PER_PAGE - 1 ) // PROMPTS_PER_PAGE
16291710
1711+ if not paginate :
1712+ messages_html = []
1713+ for conv in conversations :
1714+ is_first = True
1715+ for log_type , message_json , timestamp in conv ["messages" ]:
1716+ msg_html = render_message (log_type , message_json , timestamp )
1717+ if msg_html :
1718+ if is_first and conv .get ("is_continuation" ):
1719+ msg_html = f'<details class="continuation"><summary>Session continuation summary</summary>{ msg_html } </details>'
1720+ messages_html .append (msg_html )
1721+ is_first = False
1722+ page_template = get_template ("page.html" )
1723+ page_content = page_template .render (
1724+ css = CSS ,
1725+ js = JS ,
1726+ page_num = 1 ,
1727+ total_pages = 1 ,
1728+ pagination_html = "" ,
1729+ messages_html = "" .join (messages_html ),
1730+ paginate = False ,
1731+ )
1732+ index_path = output_dir / "index.html"
1733+ index_path .write_text (page_content , encoding = "utf-8" )
1734+ print (f"Generated { index_path .resolve ()} ({ total_convs } prompts)" )
1735+ return
1736+
16301737 for page_num in range (1 , total_pages + 1 ):
16311738 start_idx = (page_num - 1 ) * PROMPTS_PER_PAGE
16321739 end_idx = min (start_idx + PROMPTS_PER_PAGE , total_convs )
@@ -1651,6 +1758,7 @@ def generate_html_from_session_data(session_data, output_dir, github_repo=None):
16511758 total_pages = total_pages ,
16521759 pagination_html = pagination_html ,
16531760 messages_html = "" .join (messages_html ),
1761+ paginate = True ,
16541762 )
16551763 (output_dir / f"page-{ page_num :03d} .html" ).write_text (
16561764 page_content , encoding = "utf-8"
@@ -1782,6 +1890,11 @@ def generate_html_from_session_data(session_data, output_dir, github_repo=None):
17821890 is_flag = True ,
17831891 help = "Open the generated index.html in your default browser (default if no -o specified)." ,
17841892)
1893+ @click .option (
1894+ "--paginate" ,
1895+ is_flag = True ,
1896+ help = "Enable pagination (default: single page)." ,
1897+ )
17851898def web_cmd (
17861899 session_id ,
17871900 output ,
@@ -1792,6 +1905,7 @@ def web_cmd(
17921905 gist ,
17931906 include_json ,
17941907 open_browser ,
1908+ paginate ,
17951909):
17961910 """Select and convert a web session from the Claude API to HTML.
17971911
@@ -1863,7 +1977,9 @@ def web_cmd(
18631977
18641978 output = Path (output )
18651979 click .echo (f"Generating HTML in { output } /..." )
1866- generate_html_from_session_data (session_data , output , github_repo = repo )
1980+ generate_html_from_session_data (
1981+ session_data , output , github_repo = repo , paginate = paginate
1982+ )
18671983
18681984 # Show output directory
18691985 click .echo (f"Output: { output .resolve ()} " )
@@ -1921,13 +2037,18 @@ def web_cmd(
19212037 is_flag = True ,
19222038 help = "Open the generated archive in your default browser." ,
19232039)
2040+ @click .option (
2041+ "--paginate" ,
2042+ is_flag = True ,
2043+ help = "Enable pagination (default: single page)." ,
2044+ )
19242045@click .option (
19252046 "-q" ,
19262047 "--quiet" ,
19272048 is_flag = True ,
19282049 help = "Suppress all output except errors." ,
19292050)
1930- def all_cmd (source , output , include_agents , dry_run , open_browser , quiet ):
2051+ def all_cmd (source , output , include_agents , dry_run , open_browser , paginate , quiet ):
19312052 """Convert all local Claude Code sessions to a browsable HTML archive.
19322053
19332054 Creates a directory structure with:
@@ -1993,6 +2114,7 @@ def on_progress(project_name, session_name, current, total):
19932114 output ,
19942115 include_agents = include_agents ,
19952116 progress_callback = on_progress ,
2117+ paginate = paginate ,
19962118 )
19972119
19982120 # Report any failures
0 commit comments