From 93ae23dacc75063a2ae1d5423f0cc6222fcf5013 Mon Sep 17 00:00:00 2001 From: Tom Date: Fri, 6 Mar 2026 13:17:25 +0100 Subject: [PATCH] fix: prevent header corruption when sexpdata compacts schematic to single line MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit create_component_instance used line-based insertion which placed new symbols BEFORE (kicad_sch ...) header when the file was written as a single line by sexpdata.dumps(). Switch to rfind()-based string insertion which is format-independent. Also remove StreamHandler(sys.stdout) from logging — Python logs now go only to file (~/.kicad-mcp/logs/kicad_interface.log) to avoid polluting MCP stderr with INFO/DEBUG entries shown as [error]. --- python/commands/dynamic_symbol_loader.py | 26 +++++++----------------- python/kicad_interface.py | 2 +- 2 files changed, 8 insertions(+), 20 deletions(-) diff --git a/python/commands/dynamic_symbol_loader.py b/python/commands/dynamic_symbol_loader.py index cc22ebd..a2736d1 100644 --- a/python/commands/dynamic_symbol_loader.py +++ b/python/commands/dynamic_symbol_loader.py @@ -450,29 +450,17 @@ class DynamicSymbolLoader: with open(schematic_path, "r", encoding="utf-8") as f: content = f.read() - # Insert before (sheet_instances or at end before final ) - lines = content.split("\n") - insert_pos = None - - for i, line in enumerate(lines): - if "(sheet_instances" in line: - insert_pos = i - break - - if insert_pos is None: - # Insert before the last closing parenthesis - for i in range(len(lines) - 1, -1, -1): - if lines[i].strip() == ")": - insert_pos = i - break - - if insert_pos is None: + # Insert before (sheet_instances using direct string search. + # This works for both pretty-printed and sexpdata-compacted single-line files. + insert_marker = "(sheet_instances" + insert_at = content.rfind(insert_marker) + if insert_at == -1: raise ValueError("Could not find insertion point in schematic") - lines.insert(insert_pos, instance_block) + content = content[:insert_at] + instance_block + "\n " + content[insert_at:] with open(schematic_path, "w", encoding="utf-8") as f: - f.write("\n".join(lines)) + f.write(content) logger.info( f"Added component instance {reference} ({full_lib_id}) at ({x}, {y})" diff --git a/python/kicad_interface.py b/python/kicad_interface.py index cf9496f..7ae71c2 100644 --- a/python/kicad_interface.py +++ b/python/kicad_interface.py @@ -26,7 +26,7 @@ log_file = os.path.join(log_dir, "kicad_interface.log") logging.basicConfig( level=logging.DEBUG, format="%(asctime)s [%(levelname)s] %(message)s", - handlers=[logging.FileHandler(log_file), logging.StreamHandler(sys.stdout)], + handlers=[logging.FileHandler(log_file)], ) logger = logging.getLogger("kicad_interface")