def normalize_notebook()

in src/graph_notebook/notebooks/install.py [0:0]


def normalize_notebook(file_path: str):
    """
    Process and normalize Jupyter notebooks by:
    1. Removing cell IDs from all cells (these are auto-generated and can cause merge conflicts)
    2. Setting execution_count to None for code cells that don't have it defined
    3. Validating notebook format before and after modifications
    4. Saving changes back to the original file
    
    Args:
        file_path (str): Path to the .ipynb file to normalize
    
    Note: Only processes files with .ipynb extension. Skips malformed notebooks.
    """
    try:
        if not file_path.endswith('.ipynb'):
            return

        with open(file_path, 'r', encoding='utf-8') as f:
            try:
                notebook = nbformat.read(f, as_version=4)
            except Exception as e:
                print(f"Notebook does not appear to be JSON: {str(e)}")
                return

        # Validate notebook structure
        if not hasattr(notebook, 'cells') or not isinstance(notebook.cells, list):
            print(f"Skipping malformed notebook: {file_path}")
            return

        # Process cells
        for cell in notebook.cells:
            if 'id' in cell:
                del cell['id']

            if cell.cell_type == 'code' and ('execution_count' not in cell or cell.execution_count is None):
                cell['execution_count'] = None

        # Validate again
        try:
            nbformat.validate(notebook)
        except Exception as e:
            print(f"Validation error for {file_path}: {str(e)}")
            return

        # Save back to file
        with open(file_path, 'w', encoding='utf-8') as f:
            nbformat.write(notebook, f)

    except Exception as e:
        print(f"Error normalizing notebook {file_path}: {str(e)}")