#!/usr/bin/env python3 # -*- coding: utf-8 -*- """ Full reconstruction of admin.html from JSONL transcript. Handles: Write, cat>>, node script files, node -e inline, Edit ops. """ import json import re import sys JSONL_PATH = r'C:/Users/Administrator/.claude/projects/h--lab-safety-monitor-exam-main-2026/369b78fb-8697-4ea6-b83e-eeb87cee0bba.jsonl' OUTPUT_PATH = r'H:/lab-safety-monitor/exam_main_2026/admin.html' # ────────────────────────────────────────────── # 1. Parse JSONL: collect tool_uses + tool_results # ────────────────────────────────────────────── tool_results = {} # tool_use_id -> {is_error, content} all_tool_uses = [] # list of (lineno, ts, name, input, tool_use_id) with open(JSONL_PATH, 'r', encoding='utf-8') as f: for lineno, raw in enumerate(f, 1): raw = raw.strip() if not raw: continue try: obj = json.loads(raw) except Exception: continue ts = obj.get('timestamp', '') msg = obj.get('message', {}) if not isinstance(msg, dict): continue content = msg.get('content', []) if not isinstance(content, list): continue for item in content: if not isinstance(item, dict): continue itype = item.get('type', '') if itype == 'tool_use': all_tool_uses.append((lineno, ts, item.get('name', ''), item.get('input', {}), item.get('id', ''))) elif itype == 'tool_result': tid = item.get('tool_use_id', '') is_err = item.get('is_error', False) tc = item.get('content', '') if isinstance(tc, list): tc = ' '.join(x.get('text', '') if isinstance(x, dict) else str(x) for x in tc) else: tc = str(tc) if '' in tc: is_err = True tool_results[tid] = {'is_error': is_err, 'content': tc} def succeeded(tid): r = tool_results.get(tid, None) if r is None: return True # assume OK if no result found return not r['is_error'] # ────────────────────────────────────────────── # 2. Build virtual filesystem for helper scripts # ────────────────────────────────────────────── vfs = {} # normalized path -> content (for helper .js files) def norm(path): return path.replace('\\', '/').lower().replace('./', 'h:/lab-safety-monitor/exam_main_2026/') def norm_js(path): """Normalize helper script paths.""" p = path.replace('\\', '/') if p.startswith('./'): p = 'h:/lab-safety-monitor/exam_main_2026/' + p[2:] return p.lower() # ────────────────────────────────────────────── # 3. Process node scripts: extract JS and simulate # - append_admin.js: reads admin.html, inserts chunk before # - finalize_admin.js: same pattern # - fix_admin.js: runs string replacements on admin.html # ────────────────────────────────────────────── def extract_backtick_chunk(js_content): """Extract the template literal content from `const chunk = \`...\`;`""" # Find `const chunk = ` followed by backtick m = re.search(r'const chunk = `(.*?)`\s*;', js_content, re.DOTALL) if m: return m.group(1) return None def simulate_append_js(admin_html, js_content): """Simulate append_admin.js / finalize_admin.js which insert chunk before .""" chunk = extract_backtick_chunk(js_content) if chunk is None: print(" WARNING: Could not extract chunk from JS") return admin_html # The scripts do: html.replace('', chunk + '\n') # or insert before if '' in admin_html: result = admin_html.replace('', chunk + '\n', 1) else: result = admin_html + chunk return result def simulate_fix_admin_js(admin_html, js_content): """ fix_admin.js does complex string replacements. We extract and apply them manually since it uses JS template literals with Chinese chars. """ # The fix_admin.js: # 1. Removes a duplicate page-training-plan block (the fake 'active' one with workbench breadcrumb) # 2. Adds 'active' class to the real page-training-plan # 3. Fixes breadcrumbs # 4. Removes view-tabs and student view panel # Step 1: find and remove the duplicate/malformed page-training-plan active block # The pattern: finds first occurrence of PAGE: 培训计划 comment + active div, up to the second occurrence # We look for the block between two PAGE: 培训计划 markers # Find all occurrences of marker # Find first occurrence: '
' active_plan_marker = '
' active_idx = admin_html.find(active_plan_marker) if active_idx != -1: # Find the PAGE comment before this active div comment_before = admin_html.rfind('