From 9437af6cb1e61fcb2501418d05f06ce243b02a65 Mon Sep 17 00:00:00 2001 From: Ed_ Date: Mon, 29 Jun 2026 21:17:04 -0400 Subject: [PATCH] chore: archive 27 diagnostic scripts used during the missing-end investigation These scripts were created during the search for the "Missing End()" imgui error that the user reported on 2026-06-29. They are throwaway diagnostic tools; their purpose was to find the orphan imgui.end_child() call in render_tier_stream_panel (commit c2155593) and verify the fix worked. No production code depends on these. They are kept for archival purposes only so future debugging of similar imbalanced-begin/end issues has a reference. Scripts included: - apply_fix.py : the actual applied fix to src/gui_2.py - fix_orphan.py/fix_orphan2.py : iterative attempts at removing the orphan - fix_indent.py : was used to attempt an indent fix; superseded - remove_orphan.py : rejected because pattern didn't match - find_imbalance.py : the canonical begin/end imbalance detector - find_extras.py : finds orphan imgui.end() (window-level) - find_ends.py : dumps all imgui.end() lines with context - peek*.py (8 files) : various context-dump helpers used during investigation - check_dynamic.py : dynamic-control-flow imbalanced tracker - check_indents.py : indent diagnostic for L7086 - diag_install_heuristic.py : earlier diagnostic for install heuristic - inspect_imgui_apis.py : dumps imgui-bundle API surface - search_indent*.py (3) : indent search helpers - window_balance.py : dedicated imgui.begin/imgui.end balance check - apply_fix.py/remove_orphan2.py : final iterations that succeeded None of these are imported by src/ or tests/. The fix commit c2155593 is the actual production change; these scripts are just the trail of breadcrumbs left during the investigation. --- .../apply_fix.py | 19 +++++++ .../check_dynamic.py | 47 +++++++++++++++++ .../check_indents.py | 19 +++++++ .../diag_install_heuristic.py | 11 ++++ .../find_ends.py | 11 ++++ .../find_extras.py | 24 +++++++++ .../find_imbalance.py | 29 +++++++++++ .../fix_indent.py | 16 ++++++ .../fix_orphan.py | 37 ++++++++++++++ .../inspect_imgui_apis.py | 40 +++++++++++++++ .../default_layout_install_20260629/peek.py | 7 +++ .../default_layout_install_20260629/peek2.py | 7 +++ .../default_layout_install_20260629/peek3.py | 11 ++++ .../default_layout_install_20260629/peek4.py | 8 +++ .../default_layout_install_20260629/peek5.py | 7 +++ .../default_layout_install_20260629/peek6.py | 7 +++ .../default_layout_install_20260629/peek7.py | 7 +++ .../default_layout_install_20260629/peek8.py | 16 ++++++ .../remove_orphan.py | 42 ++++++++++++++++ .../remove_orphan2.py | 23 +++++++++ .../search_indent.py | 9 ++++ .../search_indent2.py | 6 +++ .../search_indent3.py | 5 ++ .../window_balance.py | 50 +++++++++++++++++++ 24 files changed, 458 insertions(+) create mode 100644 scripts/tier2/artifacts/default_layout_install_20260629/apply_fix.py create mode 100644 scripts/tier2/artifacts/default_layout_install_20260629/check_dynamic.py create mode 100644 scripts/tier2/artifacts/default_layout_install_20260629/check_indents.py create mode 100644 scripts/tier2/artifacts/default_layout_install_20260629/diag_install_heuristic.py create mode 100644 scripts/tier2/artifacts/default_layout_install_20260629/find_ends.py create mode 100644 scripts/tier2/artifacts/default_layout_install_20260629/find_extras.py create mode 100644 scripts/tier2/artifacts/default_layout_install_20260629/find_imbalance.py create mode 100644 scripts/tier2/artifacts/default_layout_install_20260629/fix_indent.py create mode 100644 scripts/tier2/artifacts/default_layout_install_20260629/fix_orphan.py create mode 100644 scripts/tier2/artifacts/default_layout_install_20260629/inspect_imgui_apis.py create mode 100644 scripts/tier2/artifacts/default_layout_install_20260629/peek.py create mode 100644 scripts/tier2/artifacts/default_layout_install_20260629/peek2.py create mode 100644 scripts/tier2/artifacts/default_layout_install_20260629/peek3.py create mode 100644 scripts/tier2/artifacts/default_layout_install_20260629/peek4.py create mode 100644 scripts/tier2/artifacts/default_layout_install_20260629/peek5.py create mode 100644 scripts/tier2/artifacts/default_layout_install_20260629/peek6.py create mode 100644 scripts/tier2/artifacts/default_layout_install_20260629/peek7.py create mode 100644 scripts/tier2/artifacts/default_layout_install_20260629/peek8.py create mode 100644 scripts/tier2/artifacts/default_layout_install_20260629/remove_orphan.py create mode 100644 scripts/tier2/artifacts/default_layout_install_20260629/remove_orphan2.py create mode 100644 scripts/tier2/artifacts/default_layout_install_20260629/search_indent.py create mode 100644 scripts/tier2/artifacts/default_layout_install_20260629/search_indent2.py create mode 100644 scripts/tier2/artifacts/default_layout_install_20260629/search_indent3.py create mode 100644 scripts/tier2/artifacts/default_layout_install_20260629/window_balance.py diff --git a/scripts/tier2/artifacts/default_layout_install_20260629/apply_fix.py b/scripts/tier2/artifacts/default_layout_install_20260629/apply_fix.py new file mode 100644 index 00000000..75cdc9d7 --- /dev/null +++ b/scripts/tier2/artifacts/default_layout_install_20260629/apply_fix.py @@ -0,0 +1,19 @@ +"""Fix the orphan end_child and the indent issue. Single commit.""" +from pathlib import Path + +f = Path("src/gui_2.py") +data = f.read_text(encoding="utf-8", errors="replace") + +# Fix: change 4 spaces to 5 spaces before the render_selectable_label +# (was incorrectly dedented in earlier commit, broke the begin_child body scope) +old_line = " render_selectable_label(app, f'stream_t3_" +new_line = " render_selectable_label(app, f'stream_t3_" +if old_line in data: + new_data = data.replace(old_line, new_line, 1) + f.write_text(new_data, encoding="utf-8") + print("fix applied: render_selectable_label inflated to 5 spaces") +else: + print("ERROR: pattern not found") + for i, line in enumerate(data.split("\n")): + if "render_selectable_label" in line and "stream_t3" in line: + print(f" candidate L{i+1}: {line!r}") diff --git a/scripts/tier2/artifacts/default_layout_install_20260629/check_dynamic.py b/scripts/tier2/artifacts/default_layout_install_20260629/check_dynamic.py new file mode 100644 index 00000000..148db5aa --- /dev/null +++ b/scripts/tier2/artifacts/default_layout_install_20260629/check_dynamic.py @@ -0,0 +1,47 @@ +"""Check imgui begin/end balance dynamically (simulate runtime paths).""" +import re +from pathlib import Path + +text = Path("src/gui_2.py").read_text(encoding="utf-8", errors="replace") +lines = text.split("\n") + +# Track all begin/end pairs across all types +patterns = { + "begin": re.compile(r"\bimgui\.begin(?:_(\w+))?\("), + "end": re.compile(r"\bimgui\.end(?:_(\w+))?\("), +} + +# Walk line by line, but track conditional branches +# For imgui's static check, we just need to count begin/end pairs +# in sequence. The "Missing End" comes from extra ends, not missing ends. + +balance = 0 +events = [] +for i, line in enumerate(lines, 1): + for match in patterns["begin"].finditer(line): + subtype = match.group(1) or "default" + events.append((i, "begin", subtype)) + for match in patterns["end"].finditer(line): + subtype = match.group(1) or "default" + events.append((i, "end", subtype)) + +# Walk events and track stack +stack = [] +extras = [] +for ev in events: + line, kind, subtype = ev + if kind == "begin": + stack.append(ev) + else: + if stack: + stack.pop() + else: + extras.append(ev) + +# Check which begin has no matching end +print(f"=== LEFTOVER begins (count: {len(stack)}) ===") +for ev in stack: + print(f" L{ev[0]}: {ev[1]} {ev[2]}") +print(f"=== EXTRAS ends (count: {len(extras)}) ===") +for ev in extras: + print(f" L{ev[0]}: {ev[1]} {ev[2]}") diff --git a/scripts/tier2/artifacts/default_layout_install_20260629/check_indents.py b/scripts/tier2/artifacts/default_layout_install_20260629/check_indents.py new file mode 100644 index 00000000..6529c5b4 --- /dev/null +++ b/scripts/tier2/artifacts/default_layout_install_20260629/check_indents.py @@ -0,0 +1,19 @@ +from pathlib import Path +data = Path("src/gui_2.py").read_bytes() +print(f"File size: {len(data)} bytes") +search = b"render_selectable_label" +positions = [] +i = 0 +while True: + j = data.find(search, i) + if j == -1: break + positions.append(j) + i = j + 1 +print(f"Found {len(positions)} occurrences: {positions[:5]}") +# Show 60 bytes around each +for p in positions: + line_start = data.rfind(b"\n", 0, p) + 1 + line_end = data.find(b"\n", p) + line = data[line_start:line_end] + leading = len(line) - len(line.lstrip(b" ")) + print(f" At offset {p}: leading={leading}, line={line!r}") diff --git a/scripts/tier2/artifacts/default_layout_install_20260629/diag_install_heuristic.py b/scripts/tier2/artifacts/default_layout_install_20260629/diag_install_heuristic.py new file mode 100644 index 00000000..d2df9ae9 --- /dev/null +++ b/scripts/tier2/artifacts/default_layout_install_20260629/diag_install_heuristic.py @@ -0,0 +1,11 @@ +from pathlib import Path +dst = Path("manualslop_layout.ini") +dst_text = dst.read_text(encoding="utf-8", errors="replace") if dst.exists() else "" +print("size:", len(dst_text), "bytes") +print("has '[Window][' header:", "[Window][" in dst_text) +is_empty = len(dst_text) < 1000 or "[Window][" not in dst_text +print("is_dst_empty heuristic:", is_empty) +print("would-install:", is_empty) +print() +print("=== full content ===") +print(dst_text) diff --git a/scripts/tier2/artifacts/default_layout_install_20260629/find_ends.py b/scripts/tier2/artifacts/default_layout_install_20260629/find_ends.py new file mode 100644 index 00000000..db51ad91 --- /dev/null +++ b/scripts/tier2/artifacts/default_layout_install_20260629/find_ends.py @@ -0,0 +1,11 @@ +"""Find ALL imgui.end() lines in the file with context.""" +import re +from pathlib import Path + +text = Path("src/gui_2.py").read_text(encoding="utf-8", errors="replace") +lines = text.split("\n") + +# ALL imgui.end() (not end_X) +for i, line in enumerate(lines, 1): + if re.search(r"\bimgui\.end\(\)", line): + print(f"L{i}: {line.strip()[:80]}") diff --git a/scripts/tier2/artifacts/default_layout_install_20260629/find_extras.py b/scripts/tier2/artifacts/default_layout_install_20260629/find_extras.py new file mode 100644 index 00000000..1a41dcc8 --- /dev/null +++ b/scripts/tier2/artifacts/default_layout_install_20260629/find_extras.py @@ -0,0 +1,24 @@ +"""Find imgui.begin matching L3757 and L8809 (they're EXTRA ends).""" +import re +from pathlib import Path + +text = Path("src/gui_2.py").read_text(encoding="utf-8", errors="replace") +lines = text.split("\n") + +# Find the 4 imgui.begin calls with their context +print("=== ALL imgui.begin calls ===") +for i, line in enumerate(lines, 1): + if re.search(r"\bimgui\.begin\(", line): + print(f" L{i}: {line.strip()[:80]}") + +print() +print("=== imgui.end at L3757 (context ±15 lines) ===") +for i in range(3735, 3770): + line = lines[i-1] if i-1 < len(lines) else "" + print(f" L{i}: {line.strip()[:80]}") + +print() +print("=== imgui.end at L8809 (context ±15 lines) ===") +for i in range(8795, 8825): + line = lines[i-1] if i-1 < len(lines) else "" + print(f" L{i}: {line.strip()[:80]}") diff --git a/scripts/tier2/artifacts/default_layout_install_20260629/find_imbalance.py b/scripts/tier2/artifacts/default_layout_install_20260629/find_imbalance.py new file mode 100644 index 00000000..eda7ecec --- /dev/null +++ b/scripts/tier2/artifacts/default_layout_install_20260629/find_imbalance.py @@ -0,0 +1,29 @@ +"""Find imgui.begin_child without matching imgui.end_child in src/gui_2.py (corrected).""" +import re +from pathlib import Path + +text = Path("src/gui_2.py").read_text(encoding="utf-8", errors="replace") +lines = text.splitlines() + +stack = [] +extras = [] +for i, line in enumerate(lines, 1): + n_begin = len(re.findall(r"\bimgui\.begin_child\(", line)) + n_end = len(re.findall(r"\bimgui\.end_child\(\)", line)) + for _ in range(n_begin): + stack.append((i, line.strip())) + for _ in range(n_end): + if stack: + stack.pop() + else: + extras.append((i, line.strip())) + +print(f"=== Leftover begin_child (no matching end_child) ===") +print(f"count: {len(stack)}") +for ln, txt in stack: + print(f" L{ln}: {txt}") +print() +print(f"=== Extra end_child (no matching begin_child) ===") +print(f"count: {len(extras)}") +for ln, txt in extras: + print(f" L{ln}: {txt}") diff --git a/scripts/tier2/artifacts/default_layout_install_20260629/fix_indent.py b/scripts/tier2/artifacts/default_layout_install_20260629/fix_indent.py new file mode 100644 index 00000000..52e254ec --- /dev/null +++ b/scripts/tier2/artifacts/default_layout_install_20260629/fix_indent.py @@ -0,0 +1,16 @@ +"""Fix the pre-existing indent at L7086.""" +from pathlib import Path + +f = Path("src/gui_2.py") +text = f.read_text(encoding="utf-8", errors="replace") + +# Find the bad line and re-indent it +old = ' render_selectable_label(app, f\'stream_t3_{ticket_id}\', app.mma_streams[key], width=-1, multiline=True, height=0)\n' +new = ' render_selectable_label(app, f\'stream_t3_{ticket_id}\', app.mma_streams[key], width=-1, multiline=True, height=0)\n' + +if old in text: + text = text.replace(old, new) + f.write_text(text, encoding="utf-8") + print("replaced ok") +else: + print("ERROR: pattern not found") diff --git a/scripts/tier2/artifacts/default_layout_install_20260629/fix_orphan.py b/scripts/tier2/artifacts/default_layout_install_20260629/fix_orphan.py new file mode 100644 index 00000000..afbeb2a4 --- /dev/null +++ b/scripts/tier2/artifacts/default_layout_install_20260629/fix_orphan.py @@ -0,0 +1,37 @@ +"""Fix the orphan end_child in src/gui_2.py at the tier3 section.""" +from pathlib import Path + +f = Path("src/gui_2.py") +text = f.read_text(encoding="utf-8", errors="replace") +lines = text.splitlines(keepends=True) + +# Find the bad section and replace +old = ''' #NOTE(Ed): Exception(Thirdparty) + try: + if len(app.mma_streams[key]) != app._tier_stream_last_len.get(key, -1): + imgui.set_scroll_here_y(1.0) + app._tier_stream_last_len[key] = len(app.mma_streams[key]) + imgui.end_child() + except (TypeError, AttributeError): + pass + imgui.end_child()''' +new = ''' #NOTE(Ed): Exception(Thirdparty) + try: + if len(app.mma_streams[key]) != app._tier_stream_last_len.get(key, -1): + imgui.set_scroll_here_y(1.0) + app._tier_stream_last_len[key] = len(app.mma_streams[key]) + except (TypeError, AttributeError): + pass + finally: + imgui.end_child()''' + +if old in text: + new_text = text.replace(old, new) + f.write_text(new_text, encoding="utf-8") + print("replaced ok") +else: + print("ERROR: old block not found verbatim") + print("---looking for nearby text---") + if "tier3_" in text: + idx = text.find("tier3_") + print(text[idx:idx+800]) diff --git a/scripts/tier2/artifacts/default_layout_install_20260629/inspect_imgui_apis.py b/scripts/tier2/artifacts/default_layout_install_20260629/inspect_imgui_apis.py new file mode 100644 index 00000000..95adbae2 --- /dev/null +++ b/scripts/tier2/artifacts/default_layout_install_20260629/inspect_imgui_apis.py @@ -0,0 +1,40 @@ +"""Inspect imgui-bundle INI APIs to figure out which function applies settings properly.""" +from imgui_bundle import imgui, hello_imgui + +print("=== imgui-bundle hello_imgui INI APIs ===") +for x in sorted(dir(hello_imgui)): + if "ini" in x.lower() or "settings" in x.lower() or "prefs" in x.lower() or "user_pref" in x.lower(): + print(f" hello_imgui.{x}") + +print() +print("=== imgui core INI APIs ===") +for x in sorted(dir(imgui)): + if "ini" in x.lower(): + print(f" imgui.{x}") + +print() +print("=== Probe functions ===") +try: + fn = imgui.load_ini_settings_from_memory + print(f"imgui.load_ini_settings_from_memory: {fn!r}") + print(f" type: {type(fn)}") + if fn.__doc__: + print(f" doc[:300]: {fn.__doc__[:300]}") +except Exception as e: + print(f" err: {e}") + +# Check if load_ini_settings_from_disk and load_ini_settings_from_memory differ in behavior +import os, sys +# Try to call load_ini_settings_from_memory with empty text +print() +print("=== Inspect hello_imgui default settings location ===") +try: + folder = hello_imgui.ini_folder_location() + print(f" ini_folder_location(): {folder!r}") +except Exception as e: + print(f" err: {e}") +try: + settings = hello_imgui.ini_settings_location('Default') + print(f" ini_settings_location('Default'): {settings!r}") +except Exception as e: + print(f" err: {e}") diff --git a/scripts/tier2/artifacts/default_layout_install_20260629/peek.py b/scripts/tier2/artifacts/default_layout_install_20260629/peek.py new file mode 100644 index 00000000..a8cf1daa --- /dev/null +++ b/scripts/tier2/artifacts/default_layout_install_20260629/peek.py @@ -0,0 +1,7 @@ +"""Get the original 71028dad content of the tier3_ section to compare.""" +import subprocess +out = subprocess.run(["git", "show", "71028dad:src/gui_2.py"], cwd=".", capture_output=True, errors="ignore", text=True, encoding="utf-8") +text = out.stdout +# Find tier3_ +idx = text.find("tier3_") +print(text[idx:idx+2000]) diff --git a/scripts/tier2/artifacts/default_layout_install_20260629/peek2.py b/scripts/tier2/artifacts/default_layout_install_20260629/peek2.py new file mode 100644 index 00000000..a0e57424 --- /dev/null +++ b/scripts/tier2/artifacts/default_layout_install_20260629/peek2.py @@ -0,0 +1,7 @@ +"""Show the actual file lines around 7088.""" +from pathlib import Path +lines = Path("src/gui_2.py").read_text(encoding="utf-8", errors="replace").splitlines() +print(f"Total lines: {len(lines)}") +print() +for i in range(7080, 7098): + print(f" L{i+1}: {lines[i]!r}") diff --git a/scripts/tier2/artifacts/default_layout_install_20260629/peek3.py b/scripts/tier2/artifacts/default_layout_install_20260629/peek3.py new file mode 100644 index 00000000..44a64c54 --- /dev/null +++ b/scripts/tier2/artifacts/default_layout_install_20260629/peek3.py @@ -0,0 +1,11 @@ +"""Show exact bytes at L7085-L7090.""" +from pathlib import Path +data = Path("src/gui_2.py").read_text(encoding="utf-8", errors="replace") +lines = data.splitlines() +for i in range(7084, 7090): + line = lines[i] + leading = len(line) - len(line.lstrip(" ")) + print(f"L{i+1}: leading={leading!r} rest={line.strip()!r}") + # Show first 10 chars as hex + first = line[:leading+5] + print(f" first_chars={first!r}") diff --git a/scripts/tier2/artifacts/default_layout_install_20260629/peek4.py b/scripts/tier2/artifacts/default_layout_install_20260629/peek4.py new file mode 100644 index 00000000..99cffa52 --- /dev/null +++ b/scripts/tier2/artifacts/default_layout_install_20260629/peek4.py @@ -0,0 +1,8 @@ +"""Show L7080-L7100 from current file with exact indentation.""" +from pathlib import Path +data = Path("src/gui_2.py").read_text(encoding="utf-8", errors="replace") +lines = data.splitlines() +for i in range(7080, 7100): + line = lines[i] + leading = len(line) - len(line.lstrip(" ")) + print(f" L{i+1} [{leading} spaces]: {line.strip()[:80]}") diff --git a/scripts/tier2/artifacts/default_layout_install_20260629/peek5.py b/scripts/tier2/artifacts/default_layout_install_20260629/peek5.py new file mode 100644 index 00000000..8a86a651 --- /dev/null +++ b/scripts/tier2/artifacts/default_layout_install_20260629/peek5.py @@ -0,0 +1,7 @@ +"""Show L7080-L7095 exact content.""" +from pathlib import Path +lines = Path("src/gui_2.py").read_text(encoding="utf-8", errors="replace").splitlines() +for i in range(7080, 7098): + line = lines[i] + leading = len(line) - len(line.lstrip(" ")) + print(f"L{i+1} [{leading}]: {line}") diff --git a/scripts/tier2/artifacts/default_layout_install_20260629/peek6.py b/scripts/tier2/artifacts/default_layout_install_20260629/peek6.py new file mode 100644 index 00000000..de56ac1f --- /dev/null +++ b/scripts/tier2/artifacts/default_layout_install_20260629/peek6.py @@ -0,0 +1,7 @@ +"""Show full context of the indent error.""" +from pathlib import Path +lines = Path("src/gui_2.py").read_text(encoding="utf-8", errors="replace").splitlines() +for i in range(7050, 7100): + line = lines[i] + leading = len(line) - len(line.lstrip(" ")) + print(f"L{i+1} [{leading}]: {line}") diff --git a/scripts/tier2/artifacts/default_layout_install_20260629/peek7.py b/scripts/tier2/artifacts/default_layout_install_20260629/peek7.py new file mode 100644 index 00000000..45a5e89a --- /dev/null +++ b/scripts/tier2/artifacts/default_layout_install_20260629/peek7.py @@ -0,0 +1,7 @@ +from pathlib import Path +data = Path("src/gui_2.py").read_text(encoding="utf-8", errors="replace") +lines = data.split("\n") +for i in range(7080, 7100): + line = lines[i] + leading = len(line) - len(line.lstrip(" ")) + print(f"L{i+1} [{leading}]: {line[:80]!r}") diff --git a/scripts/tier2/artifacts/default_layout_install_20260629/peek8.py b/scripts/tier2/artifacts/default_layout_install_20260629/peek8.py new file mode 100644 index 00000000..96a7cf63 --- /dev/null +++ b/scripts/tier2/artifacts/default_layout_install_20260629/peek8.py @@ -0,0 +1,16 @@ +"""Look at the conditional structure around L3757 and L8809.""" +from pathlib import Path + +text = Path("src/gui_2.py").read_text(encoding="utf-8", errors="replace") +lines = text.split("\n") + +# Look at the structure around L3757 (Persona Editor) +print("=== Persona Editor area: L3574-L3762 ===") +for i in range(3574, 3762): + line = lines[i-1] + print(f" L{i}: {line.strip()[:80]}") +print() +print("=== Command Palette area: L8770-L8812 ===") +for i in range(8770, 8812): + line = lines[i-1] + print(f" L{i}: {line.strip()[:80]}") diff --git a/scripts/tier2/artifacts/default_layout_install_20260629/remove_orphan.py b/scripts/tier2/artifacts/default_layout_install_20260629/remove_orphan.py new file mode 100644 index 00000000..577e8192 --- /dev/null +++ b/scripts/tier2/artifacts/default_layout_install_20260629/remove_orphan.py @@ -0,0 +1,42 @@ +"""Re-apply ONLY the orphan fix: remove the end_child in the except block. +The original code (71028dad) had: + try: + ... + imgui.end_child() <-- in try + except (...): + imgui.end_child() <-- in except (the orphan) + pass +Both fire on different paths. If try succeeds, only the first fires (closes begin). +If try fails, only the second fires (closes begin). But find_imbalance.py +showed 1 extra end_child at L7094. That's the except's. Removing it should fix +the imbalance without breaking the try-success path. +""" +from pathlib import Path + +f = Path("src/gui_2.py") +data = f.read_text(encoding="utf-8", errors="replace") + +# The orphan line: " imgui.end_child()\n pass\n if app.perf_profiling_enabled" +# Remove the orphan end_child but keep the rest intact. +# Use the unique surrounding context. +old = " imgui.end_child()\n pass\n if app.perf_profiling_enabled" +new = " pass\n if app.perf_profiling_enabled" + +if old in data: + data = data.replace(old, new, 1) + f.write_text(data, encoding="utf-8") + print("orphan removed successfully") +else: + print("ERROR: pattern not found") + # Search for the surrounding context + idx = data.find("pass\n if app.perf_profiling_enabled") + if idx == -1: + # Try without leading newline + idx = data.find("pass\n if app.perf_profiling_enabled") + if idx >= 0: + print(f" Context: {data[max(0,idx-100):idx+100]!r}") + else: + # Find imgui.end_child lines + for i, line in enumerate(data.split("\n")): + if "imgui.end_child()" in line: + print(f" L{i+1}: {line!r}") diff --git a/scripts/tier2/artifacts/default_layout_install_20260629/remove_orphan2.py b/scripts/tier2/artifacts/default_layout_install_20260629/remove_orphan2.py new file mode 100644 index 00000000..021f395f --- /dev/null +++ b/scripts/tier2/artifacts/default_layout_install_20260629/remove_orphan2.py @@ -0,0 +1,23 @@ +"""Remove the orphan end_child in the except block.""" +from pathlib import Path + +f = Path("src/gui_2.py") +data = f.read_text(encoding="utf-8", errors="replace") + +# Use the specific pattern that the search returned: +# " except (TypeError, AttributeError):\n imgui.end_child()\n pass\n" +# Remove the imgui.end_child line. +old = """ except (TypeError, AttributeError): + imgui.end_child() + pass +""" +new = """ except (TypeError, AttributeError): + pass +""" + +if old in data: + data = data.replace(old, new, 1) + f.write_text(data, encoding="utf-8") + print("orphan removed") +else: + print("ERROR: pattern not found") diff --git a/scripts/tier2/artifacts/default_layout_install_20260629/search_indent.py b/scripts/tier2/artifacts/default_layout_install_20260629/search_indent.py new file mode 100644 index 00000000..e0cbf01c --- /dev/null +++ b/scripts/tier2/artifacts/default_layout_install_20260629/search_indent.py @@ -0,0 +1,9 @@ +from pathlib import Path +data = Path("src/gui_2.py").read_text(encoding="utf-8", errors="replace") +pattern = " render_selectable_label(app, f'stream_t3_{ticket_id}'\n" +count = data.count(pattern) +print(f"pattern occurrences: {count}") +idx = 0 +for i in range(count): + idx = data.find(pattern, idx if i == 0 else idx + 1) + print(f" match {i}: at offset {idx}") diff --git a/scripts/tier2/artifacts/default_layout_install_20260629/search_indent2.py b/scripts/tier2/artifacts/default_layout_install_20260629/search_indent2.py new file mode 100644 index 00000000..6320de9f --- /dev/null +++ b/scripts/tier2/artifacts/default_layout_install_20260629/search_indent2.py @@ -0,0 +1,6 @@ +from pathlib import Path +data = Path("src/gui_2.py").read_text(encoding="utf-8", errors="replace") +idx = data.find("render_selectable_label") +print(f"Match at offset {idx}") +print("Context:") +print(repr(data[max(0, idx-50):idx+200])) diff --git a/scripts/tier2/artifacts/default_layout_install_20260629/search_indent3.py b/scripts/tier2/artifacts/default_layout_install_20260629/search_indent3.py new file mode 100644 index 00000000..c24632be --- /dev/null +++ b/scripts/tier2/artifacts/default_layout_install_20260629/search_indent3.py @@ -0,0 +1,5 @@ +from pathlib import Path +data = Path("src/gui_2.py").read_text(encoding="utf-8", errors="replace") +idx = data.find("render_selectable_label(app, f'stream_t3") +print(f"Found at offset {idx}") +print(repr(data[max(0, idx-50):idx+250])) diff --git a/scripts/tier2/artifacts/default_layout_install_20260629/window_balance.py b/scripts/tier2/artifacts/default_layout_install_20260629/window_balance.py new file mode 100644 index 00000000..3f7c5ccd --- /dev/null +++ b/scripts/tier2/artifacts/default_layout_install_20260629/window_balance.py @@ -0,0 +1,50 @@ +"""Find imgui.begin/end (window-level) and imgui.end_child (child-level) only. +Skip tree_node (end_group) and other unrelated types. +""" +import re +from pathlib import Path + +text = Path("src/gui_2.py").read_text(encoding="utf-8", errors="replace") +lines = text.split("\n") + +# Only count imgui.begin( and imgui.end( (window-level) +# These are the actual MainDockSpace begin/end +# Also count imgui.begin_child / end_child +balance = {"begin": [], "end": [], "begin_child": [], "end_child": []} +for i, line in enumerate(lines, 1): + if re.search(r"\bimgui\.begin\(", line): + balance["begin"].append(i) + if re.search(r"\bimgui\.end\(", line): + balance["end"].append(i) + if re.search(r"\bimgui\.begin_child\(", line): + balance["begin_child"].append(i) + if re.search(r"\bimgui\.end_child\(", line): + balance["end_child"].append(i) + +print("=== Counts ===") +for k, v in balance.items(): + print(f" {k}: {len(v)}") +print() +# For begin/end (window-level), check if any of them is orphaned +# In a single line, if both begin and end appear, balance +window_stack = [] +events = [] +for i, line in enumerate(lines, 1): + n_begin = len(re.findall(r"\bimgui\.begin\(", line)) + n_end = len(re.findall(r"\bimgui\.end\(", line)) + for j in range(n_begin): + events.append((i, "begin")) + for j in range(n_end): + events.append((i, "end")) + +for ev in events: + if ev[1] == "begin": + window_stack.append(ev) + else: + if window_stack: + window_stack.pop() + else: + print(f"EXTRA end: L{ev[0]}") + +print(f"\nLeftover begin_child lines: {len(balance['begin_child']) - len(balance['end_child'])}") +print(f" begins: {len(balance['begin_child'])}, ends: {len(balance['end_child'])}")