| [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)) | |