diff --git a/services/wolf.sh b/services/wolf.sh index c22d2dc..ca2d2b9 100644 --- a/services/wolf.sh +++ b/services/wolf.sh @@ -1421,14 +1421,27 @@ def update_field(lines, wolf_name, field, new_value): # any orphaned remnants left by a previously corrupted single-line rewrite. for i, line in enumerate(lines): if f"name = '{wolf_name}'" in line: - for j in range(max(0, i-25), min(len(lines), i+25)): + # Bound the search to just THIS app's own [[profiles.apps]] block — + # a blind +/-25-line window used to reach into a neighboring app's + # block once blocks got short enough (e.g. after collapsing a + # mounts array down to one line), splicing that block's own + # mounts/env field or table header instead. Confirmed live: this + # corrupted config.toml into invalid TOML ("cannot redefine + # existing table 'profiles.apps.runner'") and crash-looped Wolf. + block_start = i + while block_start > 0 and lines[block_start].strip() != '[[profiles.apps]]': + block_start -= 1 + block_end = i + 1 + while block_end < len(lines) and lines[block_end].strip() not in ('[[profiles.apps]]', '[[profiles]]'): + block_end += 1 + for j in range(block_start, block_end): if lines[j].lstrip().startswith(field + ' ='): indent = lines[j][:len(lines[j]) - len(lines[j].lstrip())] k = j - while k < len(lines) and ']' not in lines[k]: + while k < block_end and ']' not in lines[k]: k += 1 m = k + 1 - while m < len(lines): + while m < block_end: s = lines[m].lstrip() if s.startswith("'") or s.startswith(']'): m += 1 @@ -2706,14 +2719,27 @@ def update_field(lines, wolf_name, field, new_value): # any orphaned remnants left by a previously corrupted single-line rewrite. for i, line in enumerate(lines): if f"name = '{wolf_name}'" in line: - for j in range(max(0, i-25), min(len(lines), i+25)): + # Bound the search to just THIS app's own [[profiles.apps]] block — + # a blind +/-25-line window used to reach into a neighboring app's + # block once blocks got short enough (e.g. after collapsing a + # mounts array down to one line), splicing that block's own + # mounts/env field or table header instead. Confirmed live: this + # corrupted config.toml into invalid TOML ("cannot redefine + # existing table 'profiles.apps.runner'") and crash-looped Wolf. + block_start = i + while block_start > 0 and lines[block_start].strip() != '[[profiles.apps]]': + block_start -= 1 + block_end = i + 1 + while block_end < len(lines) and lines[block_end].strip() not in ('[[profiles.apps]]', '[[profiles]]'): + block_end += 1 + for j in range(block_start, block_end): if lines[j].lstrip().startswith(field + ' ='): indent = lines[j][:len(lines[j]) - len(lines[j].lstrip())] k = j - while k < len(lines) and ']' not in lines[k]: + while k < block_end and ']' not in lines[k]: k += 1 m = k + 1 - while m < len(lines): + while m < block_end: s = lines[m].lstrip() if s.startswith("'") or s.startswith(']'): m += 1