metallkart-erp/scripts/dev-task.ps1
2026-04-08 15:48:24 +03:00

152 lines
5.8 KiB
PowerShell

#!/usr/bin/env pwsh
# dev-task.ps1 — Execute une spec via Claude Code CLI (equivalent dev_task.sh VPS)
# Usage: .\dev-task.ps1 specs\ma-spec.md
# Usage: .\dev-task.ps1 specs\ma-spec.md -NoCommit -NoPush
#
# Flow: lit spec → claude -p → commit → push github + VPS → sync MEMORY.md → notif TG
param(
[Parameter(Mandatory=$true, Position=0)]
[string]$SpecFile,
[switch]$NoCommit,
[switch]$NoPush,
[switch]$NoNotify,
[string]$AllowedTools = "Bash(*),Read,Write,Edit,Glob,Grep"
)
$ErrorActionPreference = "Continue"
$REPO = "C:\Projects\metallkart-erp"
$VPS = "root@76.13.55.81"
$SCRIPTS = "$REPO\scripts"
$LOGS = "$REPO\logs"
# --- Resolve spec file ---
if (-not [System.IO.Path]::IsPathRooted($SpecFile)) {
$SpecFile = Join-Path $REPO $SpecFile
}
if (-not (Test-Path $SpecFile)) {
Write-Host "ERREUR: fichier spec introuvable: $SpecFile" -ForegroundColor Red
exit 1
}
$specName = [System.IO.Path]::GetFileNameWithoutExtension($SpecFile)
$logFile = Join-Path $LOGS "$specName-$(Get-Date -Format 'yyyyMMdd-HHmmss').log"
$startTime = Get-Date
Write-Host "========================================" -ForegroundColor Cyan
Write-Host " dev-task.ps1 — $specName" -ForegroundColor Cyan
Write-Host " $(Get-Date -Format 'yyyy-MM-dd HH:mm:ss')" -ForegroundColor DarkGray
Write-Host "========================================" -ForegroundColor Cyan
# --- Notify start ---
if (-not $NoNotify) {
& "$SCRIPTS\notify-telegram.ps1" "DEBUT [$specName] task sur PC local"
}
# --- Run Claude Code CLI ---
Write-Host "`n[1/4] Claude Code CLI..." -ForegroundColor Yellow
$prompt = "Lis le fichier $SpecFile et execute TOUTES les instructions. Quand termine, supprime le fichier spec. Resume ce que tu as fait en 3 lignes max."
$wrapperPath = "$env:TEMP\dev-task-$specName.ps1"
$outputPath = "$env:TEMP\dev-task-output-$specName.txt"
$exitCodePath = "$env:TEMP\dev-task-exit-$specName.txt"
$wrapperLines = @(
"Set-Location '$REPO'"
"try {"
" `$out = claude -p '$($prompt -replace "'","''")' --allowedTools '$AllowedTools' 2>&1 | Out-String"
" `$out | Out-File -FilePath '$outputPath' -Encoding utf8"
" `$LASTEXITCODE | Out-File -FilePath '$exitCodePath' -Encoding utf8"
"} catch {"
" `$_.Exception.Message | Out-File -FilePath '$outputPath' -Encoding utf8"
" '1' | Out-File -FilePath '$exitCodePath' -Encoding utf8"
"}"
)
[System.IO.File]::WriteAllLines($wrapperPath, $wrapperLines, [System.Text.Encoding]::UTF8)
Start-Process powershell.exe -ArgumentList "-NoProfile","-ExecutionPolicy","Bypass","-File",$wrapperPath -Wait -NoNewWindow
$output = ""
$exitCode = 0
if (Test-Path $outputPath) { $output = Get-Content $outputPath -Raw -ErrorAction SilentlyContinue }
if (Test-Path $exitCodePath) {
$codeStr = (Get-Content $exitCodePath -Raw -ErrorAction SilentlyContinue)
if ($codeStr) { $codeStr = $codeStr.Trim(); if ($codeStr -match '^\d+$') { $exitCode = [int]$codeStr } }
}
$elapsed = [math]::Round(((Get-Date) - $startTime).TotalSeconds, 1)
# Save log
$logContent = "=== dev-task $specName ===`nStart: $($startTime.ToString('o'))`nElapsed: ${elapsed}s`nExit: $exitCode`n`n$output"
[System.IO.File]::WriteAllText($logFile, $logContent, [System.Text.Encoding]::UTF8)
if ($exitCode -ne 0) {
Write-Host " ERREUR (exit $exitCode) en ${elapsed}s" -ForegroundColor Red
Write-Host " Log: $logFile" -ForegroundColor DarkGray
if (-not $NoNotify) {
$errSnippet = if ($output.Length -gt 200) { $output.Substring($output.Length - 200) } else { $output }
& "$SCRIPTS\notify-telegram.ps1" -Status "ERREUR" -TaskId $specName -Elapsed $elapsed -Details $errSnippet
}
# Cleanup
Remove-Item $wrapperPath,$outputPath,$exitCodePath -Force -ErrorAction SilentlyContinue
exit 1
}
Write-Host " OK en ${elapsed}s" -ForegroundColor Green
# --- Git commit ---
if (-not $NoCommit) {
Write-Host "`n[2/4] Git commit..." -ForegroundColor Yellow
Set-Location $REPO
$changes = git status --porcelain 2>&1
if ($changes) {
git add -A
git commit -m "spec: $specName`n`nCo-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>"
Write-Host " Committed" -ForegroundColor Green
} else {
$unpushed = git log "origin/master..HEAD" --oneline 2>&1
if ($unpushed) {
Write-Host " Deja commite, commits non pushes detectes" -ForegroundColor DarkYellow
} else {
Write-Host " Rien a commiter" -ForegroundColor DarkGray
}
}
} else {
Write-Host "`n[2/4] Git commit SKIP (--NoCommit)" -ForegroundColor DarkGray
}
# --- Git push ---
if (-not $NoPush -and -not $NoCommit) {
Write-Host "`n[3/4] Git push..." -ForegroundColor Yellow
$unpushed = git log "origin/master..HEAD" --oneline 2>&1
if ($unpushed) {
git push origin master 2>&1
if ($LASTEXITCODE -eq 0) {
Write-Host " Pushed to origin" -ForegroundColor Green
} else {
Write-Host " Push failed" -ForegroundColor Red
}
} else {
Write-Host " Rien a pusher" -ForegroundColor DarkGray
}
# Sync to VPS
scp "$REPO\MEMORY.md" "${VPS}:/opt/erp/metallkart-erp/MEMORY.md" 2>$null
Write-Host " MEMORY.md synced to VPS" -ForegroundColor Magenta
} else {
Write-Host "`n[3/4] Git push SKIP" -ForegroundColor DarkGray
}
# --- Notify end ---
Write-Host "`n[4/4] Notification..." -ForegroundColor Yellow
if (-not $NoNotify) {
& "$SCRIPTS\notify-telegram.ps1" -Status "OK" -TaskId $specName -Elapsed $elapsed
}
# Cleanup temp
Remove-Item $wrapperPath,$outputPath,$exitCodePath -Force -ErrorAction SilentlyContinue
Write-Host "`n========================================" -ForegroundColor Green
Write-Host " TERMINE: $specName (${elapsed}s)" -ForegroundColor Green
Write-Host " Log: $logFile" -ForegroundColor DarkGray
Write-Host "========================================" -ForegroundColor Green