[CmdletBinding()] param() $ErrorActionPreference = "Stop" $Root = (Resolve-Path (Join-Path $PSScriptRoot "..\..")).Path $excludedDirs = @( "\.git\", "\target\", "\workspace\", "\diagnostics\", "\dist\", "\.jackailocal\", "\.jackailocal-builder\", "\.claude\", "\.venv\", "\.jackaiagent\", "\__pycache__\", "\cache\", "\logs\" ) $files = Get-ChildItem $Root -Recurse -File -ErrorAction SilentlyContinue | Where-Object { $full = $_.FullName if ($full -like "*\manifest\sha256-manifest.json") { return $false } if ($full -like "*\config\update-private-key.xml") { return $false } if ($full -like "*\Generate-UpdateKeys.ps1" -or $full -like "*\Sign-Manifest.ps1") { return $false } foreach ($dir in $excludedDirs) { if ($full.Contains($dir)) { return $false } } return $true } $list = foreach ($f in $files) { if (!(Test-Path -LiteralPath $f.FullName -PathType Leaf)) { continue } $rel = $f.FullName.Substring($Root.Length).TrimStart("\", "/") [pscustomobject]@{ path=$rel.Replace('\','/'); sha256=(Get-FileHash -Algorithm SHA256 -LiteralPath $f.FullName).Hash.ToLowerInvariant(); size=$f.Length } } $json = @{ product="JackAILocal"; generated_at=(Get-Date).ToString("o"); files=$list } | ConvertTo-Json -Depth 20 [System.IO.File]::WriteAllText((Join-Path $Root "manifest\sha256-manifest.json"), $json, [System.Text.UTF8Encoding]::new($false))