New Terminal Output:

root@f3f8d6319494:/app# head -50 /app/termzip_ansi.py
import struct
import sys

def find_runs(changes):
    runs = []
    if not changes:
        return runs
    run_start = changes[0]
    run_end = changes[0]
    for c in changes[1:]:
        if c == run_end + 1:
            run_end = c
        else:
            runs.append((run_start, run_end))
            run_start = run_end = c
    runs.append((run_start, run_end))
    return runs

def main():
    if len(sys.argv) != 2:
        sys.exit(1)

    with open(sys.argv[1], 'rb') as f:
        magic = f.read(4)
        if magic != b'TZA1':
            sys.exit(1)
        w, h = struct.unpack('<HH', f.read(4))
        n_frames, max_bytes = struct.unpack('<II', f.read(8))
        frames = [f.read(w * h) for _ in range(n_frames)]

    out = []
    cursor_r, cursor_c = 1, 1

    # Frame 0: write non-space using runs
    for r in range(h):
        row = frames[0][r*w:(r+1)*w]
        non_space = [c for c in range(w) if row[c] != 32]
        runs = find_runs(non_space)
        for start, end in runs:
            # Move to (r+1, start+1)
            if cursor_r != r+1:
                out.append('\r')
                dr = (r+1) - cursor_r
                if dr > 0:
                    out.append('\n' * dr)
                else:
                    out.append(f'\x1b[{-dr}A')
                cursor_r, cursor_c = r+1, 1
            if cursor_c != start+1:
                dc = (start+1) - cursor_c
root@f3f8d6319494:/app# python3 /app/termzip_ansi.py /app/frames.tza 2>&1 | head -20
Traceback (most recent call last):
  File "/app/termzip_ansi.py", line 137, in <module>
    main()
    ~~~~^^
  File "/app/termzip_ansi.py", line 97, in main
    cost_partial -= (4 + len(runs[0][0]+1)) if runs else 0  # First run starts at col 1 after CR
                         ~~~^^^^^^^^^^^^^^
TypeError: object of type 'int' has no len()
root@f3f8d6319494:/app#
