#!/bin/bash # ============================================================================ # claudep.sh - Claude Prompt (Non-Interactive Background Execution) # ============================================================================ # Utilizare: # claudep.sh "promptul tău aici" # claudep.sh # fără argument, te întreabă pentru prompt # ============================================================================ set -e WORKSPACE="/workspace" LOG_DIR="/workspace/.claude-logs" # Inițializare NVM pentru Node [ -f ~/.nvm/nvm.sh ] && source ~/.nvm/nvm.sh # Culori pentru output RED='\033[0;31m' GREEN='\033[0;32m' YELLOW='\033[1;33m' BLUE='\033[0;34m' CYAN='\033[0;36m' MAGENTA='\033[0;35m' NC='\033[0m' # No Color BOLD='\033[1m' # ============================================================================ # Funcții utilitare # ============================================================================ print_header() { echo -e "\n${BOLD}${BLUE}═══════════════════════════════════════════════════════════════${NC}" echo -e "${BOLD}${CYAN} $1${NC}" echo -e "${BOLD}${BLUE}═══════════════════════════════════════════════════════════════${NC}\n" } print_success() { echo -e "${GREEN}✓ $1${NC}" } print_error() { echo -e "${RED}✗ $1${NC}" } print_info() { echo -e "${YELLOW}ℹ $1${NC}" } # ============================================================================ # Obține promptul # ============================================================================ get_prompt() { if [ -n "$1" ]; then TASK_PROMPT="$1" else echo -e "${CYAN}Descrie ce vrei să facă Claude:${NC}" echo "" read -p "> " TASK_PROMPT if [ -z "$TASK_PROMPT" ]; then print_error "Trebuie să dai o descriere" exit 1 fi # Întreabă dacă vrea să adauge mai multe detalii echo "" read -p "Detalii adiționale (sau Enter pentru a continua): " extra if [ -n "$extra" ]; then TASK_PROMPT="$TASK_PROMPT. $extra" fi fi } # ============================================================================ # Rulează Claude în background cu log procesat # ============================================================================ run_claude_background() { local work_dir="$1" local prompt="$2" # Generează nume pentru log bazat pe timestamp local timestamp=$(date +%Y%m%d_%H%M%S) local log_file="$LOG_DIR/claude_${timestamp}.log" local processed_log="$LOG_DIR/claude_${timestamp}_progress.log" local pid_file="$LOG_DIR/claude_${timestamp}.pid" mkdir -p "$LOG_DIR" echo -e "${CYAN}Director:${NC} $work_dir" echo -e "${CYAN}Prompt:${NC} $prompt" echo "" # Salvează prompt-ul într-un fișier temporar local prompt_file=$(mktemp) echo "$prompt" > "$prompt_file" # Inițializează log-ul procesat { echo "═══════════════════════════════════════════════════════════════" echo " Claude Code - Task Background" echo "═══════════════════════════════════════════════════════════════" echo "Start: $(date '+%Y-%m-%d %H:%M:%S')" echo "Director: $work_dir" echo "Prompt: $prompt" echo "PID File: $pid_file" echo "═══════════════════════════════════════════════════════════════" echo "" } > "$processed_log" # Rulează Claude în background cu procesare a log-ului ( # Salvează PID-ul subshell-ului echo "$$" > "$pid_file" cd "$work_dir" local start_time=$(date +%s) claude -p "$(cat "$prompt_file")" \ --output-format stream-json \ --verbose \ --allowedTools "Bash(git:*),Bash(npm:*),Bash(node:*),Bash(python3:*),Bash(pip3:*),Bash(pip:*),Bash(ls:*),Bash(cat:*),Bash(mkdir:*),Bash(rm:*),Bash(cp:*),Bash(mv:*),Bash(chmod:*),Bash(touch:*),Bash(find:*),Bash(grep:*),Bash(head:*),Bash(tail:*),Bash(wc:*),Bash(which:*),Bash(stat:*),Bash(file:*),Bash(pgrep:*),Bash(kill:*),Read,Write,Edit,Glob,Grep,WebSearch,WebFetch,Task,Skill,TodoWrite,LSP" \ --max-turns 50 2>&1 | while IFS= read -r line; do # Parsează JSON și extrage informații relevante if echo "$line" | jq -e . >/dev/null 2>&1; then msg_type=$(echo "$line" | jq -r '.type // empty' 2>/dev/null) timestamp=$(date '+%H:%M:%S') case "$msg_type" in "system") subtype=$(echo "$line" | jq -r '.subtype // empty' 2>/dev/null) if [ "$subtype" = "init" ]; then echo "[$timestamp] ▶ Sesiune Claude pornită" >> "$processed_log" fi ;; "assistant") # Verifică pentru tool_use - extrage detalii complete tool_info=$(echo "$line" | jq -r ' .message.content[]? | select(.type == "tool_use") | {name: .name, input: .input} | if .name == "WebFetch" then "WebFetch: \(.input.url // "?") | \(.input.prompt // "" | .[0:50])" elif .name == "WebSearch" then "WebSearch: \(.input.query // "?")" elif .name == "Bash" then "Bash: \(.input.command // "" | .[0:100])" elif .name == "Read" then "Read: \(.input.file_path // "?")" elif .name == "Write" then "Write: \(.input.file_path // "?")" elif .name == "Edit" then "Edit: \(.input.file_path // "?")" elif .name == "Grep" then "Grep: \(.input.pattern // "?") in \(.input.path // ".")" elif .name == "Glob" then "Glob: \(.input.pattern // "?")" elif .name == "Task" then "Task: \(.input.description // "?") [\(.input.subagent_type // "?")]" elif .name == "Skill" then "Skill: \(.input.skill // "?")" else "\(.name): \(.input | tostring | .[0:80])" end ' 2>/dev/null | head -1) if [ -n "$tool_info" ]; then echo "[$timestamp] ⚙ $tool_info" >> "$processed_log" fi # Text output content=$(echo "$line" | jq -r '.message.content[]? | select(.type == "text") | .text // empty' 2>/dev/null | head -c 300) if [ -n "$content" ]; then echo "[$timestamp] 💬 $content" >> "$processed_log" fi ;; "user") # Tool result - extrage detalii despre eroare sau rezumat tool_result=$(echo "$line" | jq -r ' .message.content[]? | select(.type == "tool_result") | if .is_error == true then "✗ EROARE: \(.content // "" | .[0:150])" else "✓ OK" end ' 2>/dev/null | head -1) if [ -n "$tool_result" ]; then echo "[$timestamp] $tool_result" >> "$processed_log" else # Fallback pentru alte formate de rezultat is_error=$(echo "$line" | jq -r '.message.content[]?.is_error // false' 2>/dev/null | head -1) if [ "$is_error" = "true" ]; then err_content=$(echo "$line" | jq -r '.message.content[]?.content // "" | .[0:150]' 2>/dev/null | head -1) echo "[$timestamp] ✗ EROARE: $err_content" >> "$processed_log" else echo "[$timestamp] ✓ OK" >> "$processed_log" fi fi ;; "result") result_text=$(echo "$line" | jq -r '.result // empty' 2>/dev/null | head -c 500) echo "" >> "$processed_log" echo "[$timestamp] ════════════════════════════════════════════" >> "$processed_log" echo "[$timestamp] ✅ TASK FINALIZAT" >> "$processed_log" echo "[$timestamp] ════════════════════════════════════════════" >> "$processed_log" echo "" >> "$processed_log" echo "Rezultat:" >> "$processed_log" echo "$result_text" >> "$processed_log" ;; esac fi done local exit_code=${PIPESTATUS[0]} local end_time=$(date +%s) local duration=$((end_time - start_time)) echo "" >> "$processed_log" echo "═══════════════════════════════════════════════════════════════" >> "$processed_log" echo "End: $(date '+%Y-%m-%d %H:%M:%S')" >> "$processed_log" echo "Durată: ${duration}s" >> "$processed_log" echo "Exit code: $exit_code" >> "$processed_log" echo "═══════════════════════════════════════════════════════════════" >> "$processed_log" rm -f "$prompt_file" rm -f "$pid_file" ) & local bg_pid=$! # Salvează și PID-ul procesului părinte pentru referință echo "$bg_pid" > "$pid_file" echo -e "${BOLD}${BLUE}╔════════════════════════════════════════════════════════════════╗${NC}" echo -e "${BOLD}${BLUE}║${NC} ${GREEN}Claude rulează în background${NC} ${BOLD}${BLUE}║${NC}" echo -e "${BOLD}${BLUE}╚════════════════════════════════════════════════════════════════╝${NC}" echo "" echo -e "${CYAN}PID:${NC} $bg_pid" echo -e "${CYAN}Log progres:${NC} $processed_log" echo "" echo -e "${YELLOW}Comenzi utile:${NC}" echo -e " ${BOLD}tail -f $processed_log${NC}" echo "" } # ============================================================================ # Main # ============================================================================ main() { print_header "Claude Prompt (Background)" # Detectează directorul curent ca working directory WORK_DIR=$(pwd) # Obține promptul din argument sau interactiv get_prompt "$1" # Rulează Claude în background run_claude_background "$WORK_DIR" "$TASK_PROMPT" print_success "Task lansat! Folosește tail -f pentru a urmări progresul." } # Rulează main cu toate argumentele main "$*"