#!/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) " 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