[Console]::OutputEncoding = [System.Text.Encoding]::UTF8 $wiki = 'D:\Applications\app\kepano-obsidian-main\wiki' $vault = 'D:\Applications\app\kepano-obsidian-main' # Get all available pages in vault $allMd = Get-ChildItem -Path $vault -Filter '*.md' -File -Recurse $availablePages = @{} foreach ($f in $allMd) { $bn = $f.BaseName $availablePages[$bn] = $true # Also register with Chinese characters variations } # Scan wiki files for broken links $brokenLinks = @() $wikiFiles = Get-ChildItem -Path $wiki -Filter '*.md' -File foreach ($f in $wikiFiles) { $content = [System.IO.File]::ReadAllText($f.FullName) # Match [[Link]] or [[Link|Display]] $matches = [regex]::Matches($content, '\[\[([^\]|]+)(?:\|[^\]]+)?\]\]') foreach ($m in $matches) { $linkTarget = $m.Groups[1].Value.Trim() # Skip anchors and external links if ($linkTarget -match '^http' -or $linkTarget -match '^#') { continue } if (-not $availablePages.ContainsKey($linkTarget)) { $brokenLinks += [PSCustomObject]@{ File = $f.Name BrokenLink = $linkTarget } } } } if ($brokenLinks.Count -eq 0) { Write-Output "BROKEN_LINKS: 0" } else { Write-Output "BROKEN_LINKS: $($brokenLinks.Count)" $brokenLinks | ForEach-Object { Write-Output "$($_.File) -> [[$($_.BrokenLink)]]" } }