Initial commit

This commit is contained in:
2026-05-17 17:24:03 +08:00
commit 9204ae36fd
6 changed files with 802 additions and 0 deletions

View File

@@ -0,0 +1,117 @@
param(
[string]$Root = (Get-Location).Path,
[switch]$Json
)
$ErrorActionPreference = "Stop"
if (-not (Test-Path -LiteralPath $Root)) {
throw "Root path does not exist: $Root"
}
$rootPath = (Resolve-Path -LiteralPath $Root).Path
$excludedDirs = @(".git", "node_modules", "vendor", "dist", "build", "target", ".next", ".idea", ".vscode")
function Get-RelativePath {
param([string]$Path)
$fullPath = (Resolve-Path -LiteralPath $Path).Path
if ($fullPath.StartsWith($rootPath, [System.StringComparison]::OrdinalIgnoreCase)) {
return ($fullPath.Substring($rootPath.Length).TrimStart([char[]]"\/") -replace "\\", "/")
}
return ($fullPath -replace "\\", "/")
}
function Test-IsExcluded {
param([string]$Path)
$relativePath = Get-RelativePath -Path $Path
$parts = $relativePath -split "/"
foreach ($part in $parts) {
if ($excludedDirs -contains $part) {
return $true
}
}
return $false
}
$files = @(Get-ChildItem -Path $rootPath -Recurse -File -Force | Where-Object { -not (Test-IsExcluded -Path $_.FullName) })
$directories = @(Get-ChildItem -Path $rootPath -Recurse -Directory -Force | Where-Object { -not (Test-IsExcluded -Path $_.FullName) })
$signals = New-Object System.Collections.Generic.List[object]
function Add-Signal {
param(
[string]$Name,
[string]$Confidence,
[string]$Reason,
[string[]]$Evidence
)
$existing = @($signals | Where-Object { $_.name -eq $Name })
if ($existing.Count -gt 0) {
return
}
[void]$signals.Add([pscustomobject]@{
name = $Name
confidence = $Confidence
reason = $Reason
evidence = @($Evidence)
})
}
$sqlFiles = @($files | Where-Object { $_.Extension -match "^\.(sql|dbml)$" })
$ormFiles = @($files | Where-Object { $_.Name -match "(?i)(schema\.prisma|sequelize|typeorm|entity|model|migration)" })
$dbDirs = @($directories | Where-Object { $_.Name -match "(?i)^(db|database|migrations|migration|models|entities|dao|mapper|repository|doc-sql)$" })
$databaseConfig = @($files | Where-Object { $_.Name -match "(?i)(database|datasource|jdbc|gorm|mybatis|hibernate|prisma|knex|typeorm)" })
if ($sqlFiles.Count -gt 0 -or $ormFiles.Count -gt 0 -or $dbDirs.Count -gt 0 -or $databaseConfig.Count -gt 0) {
$evidence = @($sqlFiles + $ormFiles + $databaseConfig | Select-Object -First 8 | ForEach-Object { Get-RelativePath -Path $_.FullName })
$evidence += @($dbDirs | Select-Object -First 5 | ForEach-Object { Get-RelativePath -Path $_.FullName })
Add-Signal -Name "project-has-database" -Confidence "high" -Reason "Database files, ORM files, database directories, or database configs were found." -Evidence $evidence
}
$tableDesignDocs = @($files | Where-Object { (Get-RelativePath -Path $_.FullName) -match "(?i)(doc-sql|table|schema|database|data-model)" })
if ($tableDesignDocs.Count -gt 0) {
Add-Signal -Name "designing-tables" -Confidence "medium" -Reason "Database or table-design documentation paths were found." -Evidence @($tableDesignDocs | Select-Object -First 8 | ForEach-Object { Get-RelativePath -Path $_.FullName })
}
$syncFiles = @($files | Where-Object { $_.Name -match "(?i)(sync|import|export|reconcile|recovery|recover|external|serial|code|number)" })
if ($syncFiles.Count -gt 0) {
Add-Signal -Name "data-may-sync-or-recover" -Confidence "medium" -Reason "Sync, import/export, recovery, external-code, or number-related names were found." -Evidence @($syncFiles | Select-Object -First 8 | ForEach-Object { Get-RelativePath -Path $_.FullName })
}
$apiFiles = @($files | Where-Object { $_.Name -match "(?i)(openapi|swagger|controller|router|route|api)" })
if ($apiFiles.Count -gt 0) {
Add-Signal -Name "has-api-contract" -Confidence "medium" -Reason "API contract, router, route, or controller files were found." -Evidence @($apiFiles | Select-Object -First 8 | ForEach-Object { Get-RelativePath -Path $_.FullName })
}
$frontendFiles = @($files | Where-Object { $_.Extension -match "^\.(tsx|jsx|vue|svelte)$" -or $_.Name -match "(?i)(component|page|view|route|menu|form)" })
if ($frontendFiles.Count -gt 0) {
Add-Signal -Name "has-frontend-ui" -Confidence "medium" -Reason "Frontend page, component, route, menu, or form files were found." -Evidence @($frontendFiles | Select-Object -First 8 | ForEach-Object { Get-RelativePath -Path $_.FullName })
}
$result = [pscustomobject]@{
root = $rootPath
signals = @($signals.ToArray())
}
if ($Json) {
ConvertTo-Json -InputObject $result -Depth 8
return
}
if ($signals.Count -eq 0) {
Write-Host "No project signals detected."
return
}
foreach ($signal in $signals) {
Write-Host "$($signal.name) [$($signal.confidence)] - $($signal.reason)"
foreach ($item in @($signal.evidence)) {
Write-Host " - $item"
}
}