# kb_bootpack_inline_json_patch_v1.1.ps1 # Objet : Injecter/rafraîchir la section [BUG_KB_JSON] dans bootpack.txt à partir de bootpack_paste.txt (Source=paste) # ou bug_kb\BUG_KB.json.txt (Source=kb), en PS 5.1 strict (UTF-8 BOM, pas de tokens PS7, pas de here-strings). # Ne JAMAIS modifier la section [BUG_KB_JSON_POINTER]. # Sécurité : Lecture/écriture locale sur le SoT ; ce script ne fait AUCUNE écriture réseau hors fichier cible. # Encodage : Ce fichier doit être enregistré en UTF-8 avec BOM. param( [string]$Root="\\DS-918\chatgpt\ChatGPT-Gouvernance-Projets\_registry", [ValidateSet("paste","kb")][string]$Source="paste", [switch]$Preview, [switch]$Execute, [switch]$Utf8Console ) if($Utf8Console){ try{ [Console]::OutputEncoding = New-Object System.Text.UTF8Encoding }catch{} } if($Preview -and $Execute){ Write-Host "[NOK] -Preview et -Execute sont exclusifs."; exit 1 } if(-not $Preview -and -not $Execute){ $Preview = $true } function Read-AllTextUtf8([string]$p){ try { return [IO.File]::ReadAllText($p,[Text.UTF8Encoding]::new($false)) } catch { if(Test-Path -LiteralPath $p){ return Get-Content -LiteralPath $p -Raw } else { return "" } } } function Write-Utf8NoBom([string]$p,[string]$t){ $enc = New-Object System.Text.UTF8Encoding($false) [IO.File]::WriteAllText($p,$t,$enc) } function Ensure-Parent([string]$p){ $parent = [IO.Path]::GetDirectoryName($p) if(-not [string]::IsNullOrWhiteSpace($parent)){ [void][IO.Directory]::CreateDirectory($parent) } } function Trim-FooterJson([string]$raw){ if([string]::IsNullOrWhiteSpace($raw)){ return "" } $start = $raw.IndexOf("{") $end = $raw.LastIndexOf("}") if($start -ge 0 -and $end -ge $start){ return $raw.Substring($start, $end-$start+1) } return $raw } function Parse-EntriesCount([string]$jsonText){ try{ $obj = $jsonText | ConvertFrom-Json -ErrorAction Stop if($null -eq $obj.entries){ return -1 } if($obj.entries -is [System.Array]){ return $obj.entries.Count } else { return -1 } }catch{ return -1 } } function NowIso(){ (Get-Date).ToString("yyyyMMdd_HHmmss") } $boot = Join-Path $Root "bootpack\bootpack.txt" $paste= Join-Path $Root "bootpack\bootpack_paste.txt" $kb = Join-Path $Root "bug_kb\BUG_KB.json.txt" if(-not (Test-Path -LiteralPath $boot)){ Write-Host ("[NOK] bootpack.txt introuvable : {0}" -f $boot); exit 2 } $srcFile = $paste if($Source -eq "kb"){ $srcFile = $kb } if(-not (Test-Path -LiteralPath $srcFile)){ Write-Host ("[NOK] Source introuvable : {0}" -f $srcFile); exit 3 } $rawBoot = Read-AllTextUtf8 $boot $rawJson = Read-AllTextUtf8 $srcFile $rawJson = Trim-FooterJson $rawJson $entriesCount = Parse-EntriesCount $rawJson if($entriesCount -lt 0){ Write-Host "[NOK] JSON KB invalide (entries non-tableau)."; exit 4 } # Localiser la section [BUG_KB_JSON] avec fence ``` $lines = $rawBoot -split "`r?`n" $startIdx = -1; $fenceStart = -1; $fenceEnd = -1 for($i=0;$i -lt $lines.Length;$i++){ $line = $lines[$i] if($line -like "[BUG_KB_JSON]*"){ $startIdx = $i; break } } if($startIdx -ge 0){ # Chercher le premier fence ``` après start for($j=$startIdx+1;$j -lt $lines.Length;$j++){ if($lines[$j].Trim().StartsWith("```")){ $fenceStart = $j; break } } if($fenceStart -ge 0){ for($k=$fenceStart+1;$k -lt $lines.Length;$k++){ if($lines[$k].Trim().StartsWith("```")){ $fenceEnd = $k; break } } } } # Construire le bloc JSON compact try{ $obj = $rawJson | ConvertFrom-Json -ErrorAction Stop $jsonCompact = ($obj | ConvertTo-Json -Depth 50 -Compress) }catch{ Write-Host "[NOK] Impossible de parser/compacter le JSON de KB."; exit 5 } $newLines = @() if($startIdx -ge 0 -and $fenceStart -ge 0 -and $fenceEnd -ge 0){ # Remplacer uniquement la zone JSON entre fences for($i=0;$i -lt $lines.Length;$i++){ if($i -le $fenceStart){ $newLines += $lines[$i] } elseif($i -gt $fenceStart -and $i -lt $fenceEnd){ # skip ancien JSON continue } else { if($i -eq $fenceEnd){ $newLines += $jsonCompact } $newLines += $lines[$i] } } } else { # Ajouter une section [BUG_KB_JSON] standardisée en fin de fichier $newLines = @() $newLines += $lines $newLines += "" $newLines += "[BUG_KB_JSON]" $newLines += "```json" $newLines += $jsonCompact $newLines += "```" } $outText = ($newLines -join "`r`n") Write-Host ("[PLAN] entries={0} ; Source={1}" -f $entriesCount, $Source) if($Preview){ Write-Host "[INFO] Preview : aucune écriture." exit 0 } if($Execute){ $ts = NowIso $bak = $boot + "." + $ts + ".bak" Copy-Item -LiteralPath $boot -Destination $bak -Force Write-Utf8NoBom -p $boot -t $outText Write-Host "[OK] Section [BUG_KB_JSON] mise à jour." exit 0 }