chore: establish local platform baseline

This commit is contained in:
Codex Local
2026-08-26 06:41:54 +08:00
commit 29bdf4900f
575 changed files with 95644 additions and 0 deletions
+121
View File
@@ -0,0 +1,121 @@
param(
[Parameter(Mandatory = $true)]
[string]$Source,
[string]$Output = (Join-Path $PSScriptRoot '..\artifacts\requirements-source-inventory.md')
)
$ErrorActionPreference = 'Stop'
Add-Type -AssemblyName System.IO.Compression.FileSystem
$sourcePath = (Resolve-Path -LiteralPath $Source).Path
$outputPath = [System.IO.Path]::GetFullPath($Output)
$outputDirectory = Split-Path -Parent $outputPath
if (-not (Test-Path -LiteralPath $outputDirectory)) {
New-Item -ItemType Directory -Path $outputDirectory | Out-Null
}
$stylesByID = @{}
$archive = [System.IO.Compression.ZipFile]::OpenRead($sourcePath)
try {
$entry = $archive.GetEntry('word/document.xml')
if ($null -eq $entry) {
throw 'DOCX中缺少word/document.xml'
}
$stream = $entry.Open()
try {
$reader = [System.IO.StreamReader]::new($stream, [System.Text.Encoding]::UTF8, $true)
try {
[xml]$document = $reader.ReadToEnd()
}
finally {
$reader.Dispose()
}
}
finally {
$stream.Dispose()
}
$stylesEntry = $archive.GetEntry('word/styles.xml')
if ($null -ne $stylesEntry) {
$stylesStream = $stylesEntry.Open()
try {
$stylesReader = [System.IO.StreamReader]::new($stylesStream, [System.Text.Encoding]::UTF8, $true)
try {
[xml]$stylesDocument = $stylesReader.ReadToEnd()
}
finally {
$stylesReader.Dispose()
}
}
finally {
$stylesStream.Dispose()
}
$stylesNamespace = [System.Xml.XmlNamespaceManager]::new($stylesDocument.NameTable)
$stylesNamespace.AddNamespace('w', 'http://schemas.openxmlformats.org/wordprocessingml/2006/main')
foreach ($styleNode in $stylesDocument.SelectNodes('/w:styles/w:style', $stylesNamespace)) {
$idAttribute = $styleNode.Attributes.GetNamedItem('styleId', 'http://schemas.openxmlformats.org/wordprocessingml/2006/main')
$nameNode = $styleNode.SelectSingleNode('./w:name', $stylesNamespace)
if ($null -eq $idAttribute -or $null -eq $nameNode) {
continue
}
$nameAttribute = $nameNode.Attributes.GetNamedItem('val', 'http://schemas.openxmlformats.org/wordprocessingml/2006/main')
if ($null -ne $nameAttribute) {
$stylesByID[$idAttribute.Value] = $nameAttribute.Value
}
}
}
}
finally {
$archive.Dispose()
}
$namespace = [System.Xml.XmlNamespaceManager]::new($document.NameTable)
$namespace.AddNamespace('w', 'http://schemas.openxmlformats.org/wordprocessingml/2006/main')
$paragraphs = $document.SelectNodes('/w:document/w:body/w:p', $namespace)
if ($paragraphs.Count -eq 0) {
throw 'DOCX正文没有可追踪段落'
}
$hash = (Get-FileHash -LiteralPath $sourcePath -Algorithm SHA256).Hash.ToLowerInvariant()
$lines = [System.Collections.Generic.List[string]]::new()
$lines.Add('# 原始需求来源段落清单')
$lines.Add('')
$lines.Add('> 此文件由`scripts/extract-requirements.ps1`从原始DOCX机械提取,用于稳定引用来源,不替代原需求文档。`Pxxxx`是`word/document.xml`正文段落的零基顺序号;空段落保留编号但不输出正文。')
$lines.Add('')
$lines.Add("- 来源文件:$([System.IO.Path]::GetFileName($sourcePath))")
$lines.Add(('- SHA-256:`{0}`' -f $hash))
$lines.Add("- 正文段落总数:$($paragraphs.Count)")
$lines.Add('')
$lines.Add('## 非空段落')
$lines.Add('')
$nonEmpty = 0
for ($index = 0; $index -lt $paragraphs.Count; $index++) {
$paragraph = $paragraphs[$index]
$textParts = $paragraph.SelectNodes('.//w:t', $namespace) | ForEach-Object { $_.InnerText }
$text = (($textParts -join '') -replace '[\r\n\t]+', ' ' -replace '\s{2,}', ' ').Trim()
if ([string]::IsNullOrWhiteSpace($text)) {
continue
}
$nonEmpty++
$styleNode = $paragraph.SelectSingleNode('./w:pPr/w:pStyle', $namespace)
$style = 'Normal'
if ($null -ne $styleNode) {
$styleAttribute = $styleNode.Attributes.GetNamedItem('val', 'http://schemas.openxmlformats.org/wordprocessingml/2006/main')
if ($null -ne $styleAttribute -and -not [string]::IsNullOrWhiteSpace($styleAttribute.Value)) {
$style = $styleAttribute.Value
if ($stylesByID.ContainsKey($style)) {
$style = $stylesByID[$style]
}
}
}
$safeText = $text.Replace('\', '\\').Replace('`', '\`')
$lines.Add(('- `P{0}` [{1}] {2}' -f $index.ToString('0000'), $style, $safeText))
}
$lines.Insert(7, "- 非空段落数:$nonEmpty")
[System.IO.File]::WriteAllLines($outputPath, $lines, [System.Text.UTF8Encoding]::new($false))
Write-Output "已提取 $nonEmpty/$($paragraphs.Count) 个段落:$outputPath"