cursor Init 完善多人协同changelog,以及godot相关基础skill和代码规范
This commit is contained in:
@@ -1,35 +1,111 @@
|
||||
# run-hook.ps1 — 通用 hook dispatcher
|
||||
# 从 .cursor/local-env.json 读取 shell 类型,决定执行 .ps1 还是 .sh 脚本
|
||||
# 用法:powershell -ExecutionPolicy Bypass -File .cursor/hooks/run-hook.ps1 <hook-name>
|
||||
# 示例:run-hook.ps1 session-init → 执行 session-init.ps1 或 session-init.sh
|
||||
|
||||
# Hook dispatcher: select the PowerShell or Bash implementation from local-env.json.
|
||||
param([string]$HookName)
|
||||
|
||||
$localEnvPath = ".cursor\local-env.json"
|
||||
$shell = "powershell"
|
||||
$utf8 = New-Object System.Text.UTF8Encoding($false)
|
||||
[Console]::InputEncoding = $utf8
|
||||
[Console]::OutputEncoding = $utf8
|
||||
|
||||
if (Test-Path $localEnvPath) {
|
||||
try {
|
||||
$config = Get-Content $localEnvPath -Raw | ConvertFrom-Json
|
||||
if ($config.shell) { $shell = $config.shell }
|
||||
} catch {}
|
||||
function Write-EmptyHookResult {
|
||||
[Console]::Out.WriteLine('{}')
|
||||
}
|
||||
|
||||
$hookDir = ".cursor\hooks"
|
||||
$input = [Console]::In.ReadToEnd()
|
||||
$inputPayload = [Console]::In.ReadToEnd()
|
||||
|
||||
if ($shell -eq "powershell") {
|
||||
$scriptPath = Join-Path $hookDir "$HookName.ps1"
|
||||
if (Test-Path $scriptPath) {
|
||||
$input | powershell -ExecutionPolicy Bypass -File $scriptPath
|
||||
} else {
|
||||
Write-Output '{}'
|
||||
try {
|
||||
if ([string]::IsNullOrWhiteSpace($HookName) -or $HookName -notmatch '^[A-Za-z0-9][A-Za-z0-9._-]*$') {
|
||||
throw "Invalid hook name."
|
||||
}
|
||||
} else {
|
||||
$scriptPath = Join-Path $hookDir "$HookName.sh"
|
||||
if (Test-Path $scriptPath) {
|
||||
$input | bash $scriptPath
|
||||
} else {
|
||||
Write-Output '{}'
|
||||
|
||||
$cursorDir = Split-Path -Parent $PSScriptRoot
|
||||
$repoRoot = Split-Path -Parent $cursorDir
|
||||
$localEnvPath = Join-Path $cursorDir 'local-env.json'
|
||||
$shell = 'powershell'
|
||||
|
||||
if (Test-Path -LiteralPath $localEnvPath -PathType Leaf) {
|
||||
try {
|
||||
$config = Get-Content -LiteralPath $localEnvPath -Raw -Encoding UTF8 | ConvertFrom-Json
|
||||
if ($config.shell -is [string] -and -not [string]::IsNullOrWhiteSpace($config.shell)) {
|
||||
$shell = $config.shell.Trim().ToLowerInvariant()
|
||||
}
|
||||
} catch {
|
||||
[Console]::Error.WriteLine("[run-hook] Ignoring invalid local-env.json: {0}", $_.Exception.Message)
|
||||
}
|
||||
}
|
||||
|
||||
$processInfo = New-Object System.Diagnostics.ProcessStartInfo
|
||||
$processInfo.UseShellExecute = $false
|
||||
$processInfo.CreateNoWindow = $true
|
||||
$processInfo.RedirectStandardInput = $true
|
||||
$processInfo.RedirectStandardOutput = $true
|
||||
$processInfo.RedirectStandardError = $true
|
||||
$processInfo.WorkingDirectory = $repoRoot
|
||||
|
||||
if ($processInfo.PSObject.Properties.Name -contains 'StandardInputEncoding') {
|
||||
$processInfo.StandardInputEncoding = $utf8
|
||||
$processInfo.StandardOutputEncoding = $utf8
|
||||
$processInfo.StandardErrorEncoding = $utf8
|
||||
}
|
||||
|
||||
switch ($shell) {
|
||||
{ $_ -in @('powershell', 'powershell.exe', 'pwsh', 'pwsh.exe') } {
|
||||
$scriptPath = Join-Path $PSScriptRoot "$HookName.ps1"
|
||||
if (-not (Test-Path -LiteralPath $scriptPath -PathType Leaf)) {
|
||||
throw "PowerShell hook not found: $HookName"
|
||||
}
|
||||
$processInfo.FileName = if ($shell -in @('pwsh', 'pwsh.exe')) { 'pwsh' } else { 'powershell' }
|
||||
$processInfo.Arguments = "-NoLogo -NoProfile -NonInteractive -ExecutionPolicy Bypass -File `"$scriptPath`""
|
||||
break
|
||||
}
|
||||
{ $_ -in @('bash', 'bash.exe', 'zsh', 'sh') } {
|
||||
$scriptPath = (Join-Path $PSScriptRoot "$HookName.sh") -replace '\\', '/'
|
||||
if (-not (Test-Path -LiteralPath $scriptPath -PathType Leaf)) {
|
||||
throw "Shell hook not found: $HookName"
|
||||
}
|
||||
$processInfo.FileName = 'bash'
|
||||
$processInfo.Arguments = "`"$scriptPath`""
|
||||
break
|
||||
}
|
||||
default {
|
||||
throw "Unsupported shell '$shell'."
|
||||
}
|
||||
}
|
||||
|
||||
$process = New-Object System.Diagnostics.Process
|
||||
$process.StartInfo = $processInfo
|
||||
if (-not $process.Start()) {
|
||||
throw "Unable to start hook process."
|
||||
}
|
||||
|
||||
$stdoutTask = $process.StandardOutput.ReadToEndAsync()
|
||||
$stderrTask = $process.StandardError.ReadToEndAsync()
|
||||
$process.StandardInput.Write($inputPayload)
|
||||
$process.StandardInput.Close()
|
||||
$process.WaitForExit()
|
||||
|
||||
$stdout = $stdoutTask.Result
|
||||
$stderr = $stderrTask.Result
|
||||
if (-not [string]::IsNullOrWhiteSpace($stderr)) {
|
||||
[Console]::Error.WriteLine($stderr.TrimEnd())
|
||||
}
|
||||
if ($process.ExitCode -ne 0) {
|
||||
throw "Hook exited with code $($process.ExitCode)."
|
||||
}
|
||||
|
||||
$trimmed = $stdout.Trim()
|
||||
if ([string]::IsNullOrWhiteSpace($trimmed) -or -not $trimmed.StartsWith('{')) {
|
||||
throw "Hook returned an empty or non-object response."
|
||||
}
|
||||
|
||||
$result = $trimmed | ConvertFrom-Json
|
||||
$normalized = $result | ConvertTo-Json -Compress -Depth 20
|
||||
if ([string]::IsNullOrWhiteSpace($normalized) -or -not $normalized.StartsWith('{')) {
|
||||
throw "Hook response is not a JSON object."
|
||||
}
|
||||
|
||||
[Console]::Out.WriteLine($normalized)
|
||||
} catch {
|
||||
[Console]::Error.WriteLine("[run-hook] {0}", $_.Exception.Message)
|
||||
Write-EmptyHookResult
|
||||
}
|
||||
|
||||
exit 0
|
||||
|
||||
Reference in New Issue
Block a user