param( [string]$AuditDate = '2026-07-28' ) $ErrorActionPreference = 'Stop' Add-Type -AssemblyName System.Drawing $repoRoot = (Resolve-Path (Join-Path $PSScriptRoot '..\..')).Path $auditRoot = Join-Path $repoRoot "docs\audits\$AuditDate\openclaw-core-integration" $screenshotRoot = Join-Path $auditRoot 'screenshots' function New-LabelledComparison { param( [Parameter(Mandatory)][string]$LeftPath, [Parameter(Mandatory)][string]$LeftLabel, [Parameter(Mandatory)][string]$RightPath, [Parameter(Mandatory)][string]$RightLabel, [Parameter(Mandatory)][string]$OutputPath ) $left = [System.Drawing.Image]::FromFile($LeftPath) $right = [System.Drawing.Image]::FromFile($RightPath) $canvas = New-Object System.Drawing.Bitmap 1440, 490 $graphics = [System.Drawing.Graphics]::FromImage($canvas) $font = New-Object System.Drawing.Font 'Segoe UI', 13, ([System.Drawing.FontStyle]::Bold) $labelBrush = New-Object System.Drawing.SolidBrush ([System.Drawing.Color]::FromArgb(232, 234, 240)) $backgroundBrush = New-Object System.Drawing.SolidBrush ([System.Drawing.Color]::FromArgb(8, 7, 24)) try { $graphics.FillRectangle($backgroundBrush, 0, 0, $canvas.Width, $canvas.Height) $graphics.DrawString($LeftLabel, $font, $labelBrush, 12, 10) $graphics.DrawString($RightLabel, $font, $labelBrush, 732, 10) $graphics.DrawImage($left, 0, 40, 720, 450) $graphics.DrawImage($right, 720, 40, 720, 450) $canvas.Save($OutputPath, [System.Drawing.Imaging.ImageFormat]::Png) } finally { $backgroundBrush.Dispose() $labelBrush.Dispose() $font.Dispose() $graphics.Dispose() $canvas.Dispose() $right.Dispose() $left.Dispose() } } function New-ContactSheet { param( [Parameter(Mandatory)][array]$Items, [Parameter(Mandatory)][int]$Columns, [Parameter(Mandatory)][int]$CellWidth, [Parameter(Mandatory)][int]$CellHeight, [Parameter(Mandatory)][string]$OutputPath ) $labelHeight = 28 $rows = [Math]::Ceiling($Items.Count / $Columns) $canvas = New-Object System.Drawing.Bitmap ($Columns * $CellWidth), ($rows * ($CellHeight + $labelHeight)) $graphics = [System.Drawing.Graphics]::FromImage($canvas) $font = New-Object System.Drawing.Font 'Segoe UI', 10, ([System.Drawing.FontStyle]::Bold) $labelBrush = New-Object System.Drawing.SolidBrush ([System.Drawing.Color]::FromArgb(224, 226, 238)) $backgroundBrush = New-Object System.Drawing.SolidBrush ([System.Drawing.Color]::FromArgb(8, 7, 24)) try { $graphics.FillRectangle($backgroundBrush, 0, 0, $canvas.Width, $canvas.Height) for ($index = 0; $index -lt $Items.Count; $index++) { $item = $Items[$index] $column = $index % $Columns $row = [Math]::Floor($index / $Columns) $x = $column * $CellWidth $y = $row * ($CellHeight + $labelHeight) $image = [System.Drawing.Image]::FromFile($item.Path) try { $graphics.DrawString($item.Label, $font, $labelBrush, $x + 8, $y + 6) $graphics.DrawImage($image, $x, $y + $labelHeight, $CellWidth, $CellHeight) } finally { $image.Dispose() } } $canvas.Save($OutputPath, [System.Drawing.Imaging.ImageFormat]::Png) } finally { $backgroundBrush.Dispose() $labelBrush.Dispose() $font.Dispose() $graphics.Dispose() $canvas.Dispose() } } New-LabelledComparison ` -LeftPath (Join-Path $repoRoot 'docs\audits\2026-07-26\screenshots\00-dashboard-reference-1440.png') ` -LeftLabel 'Reference - 1440 px' ` -RightPath (Join-Path $screenshotRoot '02-dashboard-1440.png') ` -RightLabel 'Current build - 1440 px' ` -OutputPath (Join-Path $auditRoot 'dashboard-reference-vs-current.png') New-LabelledComparison ` -LeftPath (Join-Path $repoRoot 'docs\audits\2026-07-28\sites-mission-control\02-run-control.png') ` -LeftLabel 'Reference mockup' ` -RightPath (Join-Path $screenshotRoot '03-run-control-1440.png') ` -RightLabel 'Current functional build' ` -OutputPath (Join-Path $auditRoot 'run-control-mock-vs-current.png') $coreItems = @( @{ Label = 'Dashboard'; Path = Join-Path $screenshotRoot '02-dashboard-1440.png' }, @{ Label = 'Run Control'; Path = Join-Path $screenshotRoot '03-run-control-1440.png' }, @{ Label = 'Agents'; Path = Join-Path $screenshotRoot '04-agents-1440.png' }, @{ Label = 'Agent detail'; Path = Join-Path $screenshotRoot '05-agent-detail-1440.png' }, @{ Label = 'Projects'; Path = Join-Path $screenshotRoot '06-projects-1440.png' }, @{ Label = 'Project detail'; Path = Join-Path $screenshotRoot '07-project-detail-1440.png' }, @{ Label = 'Task Board'; Path = Join-Path $screenshotRoot '08-task-board-1440.png' }, @{ Label = 'Task detail'; Path = Join-Path $screenshotRoot '09-task-detail-1440.png' }, @{ Label = 'Memory'; Path = Join-Path $screenshotRoot '10-memory-1440.png' }, @{ Label = 'Docs'; Path = Join-Path $screenshotRoot '11-docs-1440.png' }, @{ Label = 'Models'; Path = Join-Path $screenshotRoot '12-models-1440.png' }, @{ Label = 'Activity'; Path = Join-Path $screenshotRoot '13-activity-1440.png' }, @{ Label = 'Calendar'; Path = Join-Path $screenshotRoot '14-calendar-1440.png' }, @{ Label = 'Security'; Path = Join-Path $screenshotRoot '15-security-1440.png' }, @{ Label = 'Incidents'; Path = Join-Path $screenshotRoot '16-incidents-1440.png' }, @{ Label = 'Notifications'; Path = Join-Path $screenshotRoot '17-notifications-1440.png' }, @{ Label = 'Settings'; Path = Join-Path $screenshotRoot '18-settings-1440.png' } ) New-ContactSheet ` -Items $coreItems ` -Columns 4 ` -CellWidth 360 ` -CellHeight 225 ` -OutputPath (Join-Path $auditRoot 'core-pages-contact-sheet.png') $responsiveItems = @( @{ Label = 'Run Control - 375 px'; Path = Join-Path $screenshotRoot '19-run-control-375.png' }, @{ Label = 'Run Control - 768 px'; Path = Join-Path $screenshotRoot '23-run-control-768.png' }, @{ Label = 'Run Control - 1024 px'; Path = Join-Path $screenshotRoot '24-run-control-1024.png' }, @{ Label = 'Run Control - 1920 px'; Path = Join-Path $screenshotRoot '25-run-control-1920.png' } ) New-ContactSheet ` -Items $responsiveItems ` -Columns 2 ` -CellWidth 720 ` -CellHeight 450 ` -OutputPath (Join-Path $auditRoot 'run-control-responsive-contact-sheet.png')