Loading source
Pulling the file list, source metadata, and syntax-aware rendering for this listing.
Source from repo
Reviews, improves, and writes SwiftUI code following state management, view composition, performance, and iOS 26+ Liquid Glass best practices.
Files
Skill
Size
Entrypoint
Format
Open file
Syntax-highlighted preview of this file as included in the skill package.
scripts/instruments_parser/summary.py
1"""Markdown summary renderer for the combined trace analysis."""2from __future__ import annotations345def render(result: dict) -> str:6lines: list[str] = []7trace = result.get("trace", "?")8header = result.get("xctrace_version") or ""9template = result.get("template") or ""10duration_s = result.get("duration_s")11lines.append(f"# Instruments Trace Analysis")12meta = [p for p in [f"Trace: `{trace}`", header, template] if p]13lines.append(" • ".join(meta))14if duration_s is not None:15lines.append(f"Recording duration: {duration_s:.2f}s")16lines.append("")1718lanes_by_name = {lane["lane"]: lane for lane in result.get("lanes", [])}1920_render_time_profiler(lines, lanes_by_name.get("time-profiler"))21_render_hangs(lines, lanes_by_name.get("hangs"))22_render_hitches(lines, lanes_by_name.get("hitches"))23_render_swiftui(lines, lanes_by_name.get("swiftui"))24_render_causes(lines, lanes_by_name.get("swiftui-causes"))25_render_correlations(lines, result.get("correlations", []))2627return "\n".join(lines).rstrip() + "\n"282930def _skipped_block(title: str, lane: dict | None) -> list[str]:31if lane is None:32return [f"## {title} — skipped (lane module not run)", ""]33notes = lane.get("notes") or []34note_text = f" — {notes[0]}" if notes else ""35return [f"## {title} — skipped{note_text}", ""]363738def _render_time_profiler(lines: list[str], lane: dict | None) -> None:39if not lane or not lane.get("available"):40lines.extend(_skipped_block("Time Profiler", lane))41return42m = lane["metrics"]43lines.append(44f"## Time Profiler — {m['total_samples']:,} samples, "45f"{m['total_weight_ms']:.0f}ms CPU time"46)47if m.get("processes"):48lines.append(f"Processes: {', '.join(m['processes'])}")49lines.append("")50if lane["top_offenders"]:51lines.append("Top offenders:")52for i, o in enumerate(lane["top_offenders"], 1):53lines.append(54f"{i}. `{_truncate(o['symbol'], 90)}` — "55f"{o['percent']:.1f}% ({o['weight_ms']:.0f}ms, "56f"{o['samples']} samples, {_short_thread(o['thread'])})"57)58for note in lane.get("notes") or []:59lines.append(f"> {note}")60lines.append("")616263def _render_hangs(lines: list[str], lane: dict | None) -> None:64if not lane or not lane.get("available"):65lines.extend(_skipped_block("Hangs", lane))66return67m = lane["metrics"]68buckets = m["severity_buckets"]69lines.append(70f"## Hangs — {m['count']} hangs, {m['total_duration_ms']:.0f}ms total, "71f"worst {m['worst_duration_ms']:.0f}ms"72)73lines.append(74f"Severity: <250ms={buckets['lt_250ms']}, "75f"250ms–1s={buckets['250ms_1s']}, >1s={buckets['gt_1s']}"76)77lines.append("")78for i, h in enumerate(lane["top_offenders"], 1):79lines.append(80f"{i}. {h['duration_ms']:.0f}ms {h['hang_type']} at "81f"{h['start_ms']:.2f}ms on {_short_thread(h['thread'])}"82)83lines.append("")848586def _render_hitches(lines: list[str], lane: dict | None) -> None:87if not lane or not lane.get("available"):88lines.extend(_skipped_block("Animation Hitches", lane))89return90m = lane["metrics"]91lines.append(92f"## Animation Hitches — {m['count']} hitches, "93f"{m['total_hitch_ms']:.0f}ms total, worst {m['worst_hitch_ms']:.0f}ms"94)95if m.get("per_process"):96pp = ", ".join(f"{k}={v}" for k, v in m["per_process"].items())97lines.append(f"By process: {pp}")98lines.append("")99if m.get("narrative_breakdown"):100nb = ", ".join(f"{k}={v}" for k, v in m["narrative_breakdown"].items() if k)101if nb:102lines.append(f"Apple attribution: {nb}")103if m.get("system_hitches") is not None:104lines.append(105f"System vs app: system={m['system_hitches']}, app={m['app_hitches']}"106)107lines.append("")108for i, h in enumerate(lane["top_offenders"], 1):109narrative = f" — {h['narrative']}" if h.get("narrative") else ""110src = " [system]" if h.get("is_system") else ""111proc = f" ({h['process']})" if h.get("process") else ""112lines.append(113f"{i}. {h['hitch_duration_ms']:.0f}ms at {h['start_ms']:.2f}ms"114f"{proc}{src}{narrative}"115)116lines.append("")117118119def _render_swiftui(lines: list[str], lane: dict | None) -> None:120if not lane or not lane.get("available"):121lines.extend(_skipped_block("SwiftUI", lane))122return123m = lane["metrics"]124lines.append(125f"## SwiftUI — {m['total_events']:,} updates across "126f"{m['unique_views']} views, {m['total_duration_ms']:.0f}ms total"127)128if m.get("severity_breakdown"):129sb = ", ".join(f"{k}={v}" for k, v in m["severity_breakdown"].items())130lines.append(f"Severity: {sb}")131if m.get("update_type_breakdown"):132ub = ", ".join(f"{k}={v}" for k, v in m["update_type_breakdown"].items())133lines.append(f"Update types: {ub}")134lines.append("")135if lane["top_offenders"]:136lines.append("Heaviest views (by total body time):")137for i, v in enumerate(lane["top_offenders"], 1):138lines.append(139f"{i}. `{_truncate(v['view'], 80)}` — {v['total_ms']:.0f}ms total, "140f"{v['count']} updates (avg {v['avg_ms']:.2f}ms)"141)142if lane.get("high_severity_events"):143lines.append("")144lines.append("High-severity updates:")145for i, e in enumerate(lane["high_severity_events"][:5], 1):146cat = f" [{e['category']}]" if e.get("category") else ""147lines.append(148f"{i}. `{_truncate(e['view'], 60)}` — "149f"{e['severity']} ({e['duration_ms']:.2f}ms at {e['start_ms']:.2f}ms){cat}"150)151lines.append("")152153154def _render_causes(lines: list[str], lane: dict | None) -> None:155if not lane or not lane.get("available"):156lines.extend(_skipped_block("SwiftUI Cause Graph", lane))157return158m = lane["metrics"]159lines.append(160f"## SwiftUI Cause Graph — {m['total_edges']:,} edges, "161f"{m['unique_sources']} sources → {m['unique_destinations']} destinations"162)163lines.append("")164if lane.get("top_sources"):165lines.append("Top sources (who's driving the most updates):")166for i, s in enumerate(lane["top_sources"][:5], 1):167lines.append(f"{i}. `{_truncate(s['source'], 80)}` — {s['edges']:,} edges")168for d in s["top_destinations"][:3]:169lines.append(170f" → `{_truncate(d['destination'], 70)}` {d['edges']:,}"171)172if lane.get("top_destinations"):173lines.append("")174lines.append("Top destinations (who's being invalidated most):")175for i, d in enumerate(lane["top_destinations"][:5], 1):176lines.append(f"{i}. `{_truncate(d['destination'], 80)}` — {d['edges']:,} edges")177for s in d["top_sources"][:3]:178lines.append(179f" ← `{_truncate(s['source'], 70)}` {s['edges']:,}"180)181lines.append("")182183184def _render_correlations(lines: list[str], correlations: list[dict]) -> None:185if not correlations:186return187lines.append("## Correlations")188lines.append("")189for c in correlations:190t = c["trigger"]191head = (192f"- **{t['lane']}** at {t['start_ms']:.2f}ms "193f"({t['duration_ms']:.0f}ms)"194)195if t.get("hang_type"):196head += f" — {t['hang_type']}"197lines.append(head)198199tp = c.get("time_profiler_main_thread")200if tp is not None:201cov = tp["main_running_coverage_pct"]202lines.append(203f" - Main thread: {tp['samples_on_main']} running samples "204f"({cov:.0f}% coverage — "205f"{'blocked' if cov < 25 else 'mostly running'})"206)207for s in tp["hot_symbols"][:3]:208lines.append(209f" · `{_truncate(s['symbol'], 80)}` "210f"{s['percent_of_main']:.0f}% ({s['samples']} samples)"211)212if not tp["hot_symbols"]:213lines.append(" · no main-thread samples in window")214215sui = c.get("swiftui_overlapping_updates")216if sui:217for s in sui[:3]:218lines.append(219f" - SwiftUI: `{s['view']}` {s['duration_ms']:.2f}ms "220f"(at {s['start_ms']:.2f}ms)"221)222lines.append("")223224225def _short_thread(name: str) -> str:226if not name:227return ""228if name.startswith("Main Thread") or name == "main":229return "main"230# "NowPlaying Gigs (0x251990d) (NowPlaying Gigs, pid: 28401)" -> "tid 0x251990d"231tid_start = name.find("(0x")232if tid_start != -1:233start = tid_start + 1234end = name.find(")", start)235if end != -1:236return f"tid {name[start:end]}"237return name[:40]238239240def _truncate(s: str, n: int) -> str:241if len(s) <= n:242return s243return s[: n - 1] + "…"244