from __future__ import annotations # ── Dark G100 design tokens ────────────────────────────────────────────────── _BG = "#161616" _L1 = "#262626" # layer 01 — panels _L2 = "#393939" # layer 02 — rows / hover _L3 = "#525252" # layer 03 — borders _T1 = "#f4f4f4" # text primary _T2 = "#c6c6c6" # text secondary _T3 = "#8d8d8d" # text helper / labels _T4 = "#6f6f6f" # text disabled / placeholder _BLUE = "#4589ff" # interactive (blue-40) _BLUE_DIM = "#001d6c" # blue tint bg (blue-90) _BLUE_LNK = "#78a9ff" # link / code (blue-30) # status — dark _ERR_BG = "#2d0709"; _ERR_BD = "#ff8389"; _ERR_FG = "#ff8389" _WARN_BG = "#302200"; _WARN_BD = "#f1c21b"; _WARN_FG = "#f1c21b" _OK_BG = "#071908"; _OK_BD = "#42be65"; _OK_FG = "#42be65" _INFO_BG = _BLUE_DIM; _INFO_BD = _BLUE; _INFO_FG = _BLUE _FONT = "'IBM Plex Sans', system-ui, -apple-system, sans-serif" _MONO = "'IBM Plex Mono', 'SFMono-Regular', Consolas, monospace" # ── SVG icons ──────────────────────────────────────────────────────────────── _SVG_ERROR = ( "" "" ) _SVG_WARNING = ( "" "" ) _SVG_CHECK = ( "" "" ) _SVG_INFO = ( "" "" ) _NOTIFICATION: dict[str, dict] = { "approved": {"border": _OK_BD, "bg": _OK_BG, "color": _OK_FG, "icon": _SVG_CHECK, "label": "APPROVED"}, "needs_human_review": {"border": _WARN_BD, "bg": _WARN_BG, "color": _WARN_FG, "icon": _SVG_WARNING, "label": "NEEDS HUMAN REVIEW"}, "rejected": {"border": _ERR_BD, "bg": _ERR_BG, "color": _ERR_FG, "icon": _SVG_ERROR, "label": "REJECTED"}, "refused": {"border": _ERR_BD, "bg": _ERR_BG, "color": _ERR_FG, "icon": _SVG_ERROR, "label": "REFUSED"}, } _DEFAULT_NOTIFICATION = {"border": _L3, "bg": _L1, "color": _T3, "icon": _SVG_INFO, "label": "UNKNOWN"} def _notification_html(action: str, reason: str) -> str: cfg = _NOTIFICATION.get(action, _DEFAULT_NOTIFICATION) return ( f"
" f"{cfg['icon']}" f"
" f"

{cfg['label']}

" f"

{reason}

" f"
" ) def _severity_pill(sev: str) -> str: dark_colors = { "CRITICAL": (_ERR_FG, _ERR_BG), "HIGH": ("#ffb3b8", "#3b0d0e"), "MEDIUM": (_WARN_FG, _WARN_BG), "LOW": (_BLUE_LNK, "#001141"), } fg, bg = dark_colors.get(sev, (_T3, _L2)) return ( f"{sev}" ) def render_findings_html(rule_ids: list[str], summary: dict) -> str: failed = summary.get("failed", len(rule_ids)) crit = int(summary.get("CRITICAL", 0)) high = int(summary.get("HIGH", 0)) med = int(summary.get("MEDIUM", 0)) rows = "".join( f"{rid}" for rid in rule_ids ) table = ( f"" f"{rows}
" f"Rule ID
" ) if rule_ids else f"

No findings

" pills = " ".join(filter(None, [ (_severity_pill("CRITICAL") + f" {crit}") if crit else "", (_severity_pill("HIGH") + f" {high}") if high else "", (_severity_pill("MEDIUM") + f" {med}") if med else "", ])) return ( f"
" f"
" f"{failed}" f"failed checks" f"
" f"
{pills}
" f"{table}
" ) def _details_html( parse_ok: bool, changed_ratio: float, resolved: list[str], unresolved: list[str], explanation: str, risk_notes: list[str], ) -> str: def _row(label: str, value: str) -> str: return ( f"" f"{label}" f"{value}" f"" ) def _pill_list(items: list[str], ok: bool) -> str: if not items: return f"" fg = _OK_FG if ok else _ERR_FG bg = _OK_BG if ok else _ERR_BG pills = "".join( f"{r}" for r in items ) return f"
{pills}
" risks_html = "" if risk_notes: items = "".join(f"
  • {n}
  • " for n in risk_notes) risks_html = ( f"
    " f"

    Risk Notes

    " f"" f"
    " ) expl_html = "" if explanation: expl_html = ( f"
    " f"

    Explanation

    " f"

    {explanation}

    " f"
    " ) table = ( f"" f"{_row('Parse OK', 'Yes' if parse_ok else 'No')}" f"{_row('Changed lines', f'{changed_ratio:.0%}')}" f"{_row('Resolved', _pill_list(resolved, ok=True))}" f"{_row('Unresolved', _pill_list(unresolved, ok=False))}" f"
    " ) return ( f"
    " f"{table}{expl_html}{risks_html}" f"
    " ) def render_result(data: dict) -> tuple[str, str, str, str, str, str]: decision = data.get("decision") or {} action = decision.get("action", "unknown") reason = decision.get("reason", "") original = data.get("original_file", "") patch_obj = decision.get("patch") or {} fixed = patch_obj.get("fixed_file") or data.get("fixed_file", "") pre_rules: list[str] = data.get("pre_rule_ids") or [] post_rules: list[str] = data.get("post_rule_ids") or [] pre_summary: dict = data.get("pre_summary") or {} post_summary:dict = data.get("post_summary") or {} validation = decision.get("validation") or data.get("validation") or {} resolved: list[str] = validation.get("targeted_resolved") or [] unresolved: list[str] = validation.get("targeted_unresolved") or [] parse_ok: bool = validation.get("parse_ok", False) changed_ratio: float = validation.get("changed_lines_ratio", 0.0) explanation = patch_obj.get("explanation") or reason risk_notes: list[str] = patch_obj.get("risk_notes") or [] return ( original, fixed, _notification_html(action, reason), render_findings_html(pre_rules, pre_summary), render_findings_html(post_rules, post_summary), _details_html(parse_ok, changed_ratio, resolved, unresolved, explanation, risk_notes), ) def error_html(label: str, exc: Exception) -> str: return _notification_html("rejected", f"{label}: {exc}")