From 193b94c94f522cf265176aa59eef4328155e6af7 Mon Sep 17 00:00:00 2001 From: Claude Agent Date: Thu, 1 Jan 2026 19:11:44 +0000 Subject: [PATCH] Initial commit - workspace setup scripts MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Add Claude Agent workspace configuration and utility scripts: - CLAUDE.md: Agent documentation and instructions - SETUP-COMPLETE.md: Setup completion notes - start-agent.sh: Script to start tmux session - new-task.sh: Script for new task workflow - finish-task.sh: Script to finish tasks - work.sh: Main work script 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 --- .gitignore | 7 + CLAUDE.md | 43 +++++ SETUP-COMPLETE.md | 146 +++++++++++++++ finish-task.sh | 31 ++++ new-task.sh | 26 +++ start-agent.sh | 17 ++ work.sh | 440 ++++++++++++++++++++++++++++++++++++++++++++++ 7 files changed, 710 insertions(+) create mode 100644 .gitignore create mode 100644 CLAUDE.md create mode 100644 SETUP-COMPLETE.md create mode 100755 finish-task.sh create mode 100755 new-task.sh create mode 100755 start-agent.sh create mode 100755 work.sh diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..3ed69f7 --- /dev/null +++ b/.gitignore @@ -0,0 +1,7 @@ +# Exclude project directories +romfastsql/ +test/ +.claude-logs/ + +# Exclude any other project directories that might be added +# Keep only workspace-level files (.sh, .md) diff --git a/CLAUDE.md b/CLAUDE.md new file mode 100644 index 0000000..7b35695 --- /dev/null +++ b/CLAUDE.md @@ -0,0 +1,43 @@ +# Claude Agent Workspace + +## Informații Agent +- **Hostname:** claude-agent +- **IP:** 10.0.20.171 +- **User:** claude +- **Git remote:** gitea.romfast.ro + +## Comenzi Utile + +### Pornire sesiune agent +```bash +~/start-agent.sh +``` + +### Verificare tmux sessions +```bash +tmux ls +``` + +### Pornire Claude Code în proiect +```bash +cd /workspace/ +claude +``` + +## Workflow Recomandat + +1. Conectează-te via SSH: `ssh claude@10.0.20.171` +2. Pornește sesiunea tmux: `~/start-agent.sh` +3. Navighează în proiect: `cd /workspace/` +4. Pornește Claude: `claude` + +## Git - Gitea +Repository-urile se clonează cu: +```bash +git clone git@gitea.romfast.ro:romfast/.git +``` + +## Note +- Această mașină este configurată pentru dezvoltare cu Claude Code +- Toate proiectele ar trebui să fie în /workspace +- tmux prefix este Ctrl+A (nu Ctrl+B) diff --git a/SETUP-COMPLETE.md b/SETUP-COMPLETE.md new file mode 100644 index 0000000..3eebe6f --- /dev/null +++ b/SETUP-COMPLETE.md @@ -0,0 +1,146 @@ +# LXC Claude Agent - Setup Complete ✓ + +**Data setup:** 2025-12-31 +**Status:** Functional + +## Informații LXC + +| Parametru | Valoare | +|-----------|---------| +| VMID | 171 | +| Hostname | claude-agent | +| IP | 10.0.20.171 | +| Gateway | 10.0.20.1 | +| Host Proxmox | pveelite (10.0.20.202) | +| User | claude | +| Storage | local-zfs (32GB) | +| RAM | 4GB | +| CPU | 2 cores | + +## Componente Instalate + +| Component | Versiune | +|-----------|----------| +| Ubuntu | 24.04 LTS | +| Node.js | v20.19.6 (via nvm) | +| Claude Code | 2.0.76 | +| tmux | 3.4 | +| Git | 2.43.0 | + +## Comenzi Utile + +### Conectare SSH +```bash +ssh claude@10.0.20.171 +``` + +### Pornire sesiune tmux agent +```bash +~/start-agent.sh +``` + +### Pornire Claude Code +```bash +source ~/.nvm/nvm.sh +cd /workspace/ +claude +``` + +### Atașare la sesiune tmux existentă +```bash +tmux attach -t agent +``` + +### Detașare din tmux +``` +Ctrl+A, d +``` + +## VS Code Remote SSH Config + +Adaugă în `~/.ssh/config`: +``` +Host claude-agent + HostName 10.0.20.171 + User claude + IdentityFile ~/.ssh/id_rsa + ForwardAgent yes +``` + +Apoi în VS Code: `Remote-SSH: Connect to Host...` → `claude-agent` + +## SSH Key pentru Gitea + +**Adaugă acest key în Gitea → Settings → SSH/GPG Keys → Add Key:** + +``` +ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIKrxEqh5L1SRrZ4f6j04mLaNdr6LJf+xb9EKBvwegeXS claude-agent@romfast.ro +``` + +## Next Steps (Manual) + +1. **Adaugă SSH key în Gitea:** + - Mergi la https://gitea.romfast.ro + - Settings → SSH/GPG Keys → Add Key + - Paste-uiește cheia de mai sus + +2. **Prima autentificare Claude Code:** + ```bash + ssh claude@10.0.20.171 + source ~/.nvm/nvm.sh + claude + ``` + - Va cere să te autentifici cu contul Anthropic + - Urmează instrucțiunile din terminal + +3. **Test clonare repository:** + ```bash + cd /workspace + git clone git@gitea.romfast.ro:romfast/romfastsql.git + ``` + +4. **Configurare VS Code Remote (opțional):** + - Instalează extensia "Remote - SSH" în VS Code + - Adaugă configurația SSH de mai sus + - Conectează-te la claude-agent + +## Structura Directoare + +``` +/home/claude/ +├── .ssh/ +│ ├── authorized_keys # Key pentru acces SSH +│ ├── gitea_ed25519 # Key privat pentru Gitea +│ ├── gitea_ed25519.pub # Key public pentru Gitea +│ └── config # SSH config pentru Gitea +├── .nvm/ # Node Version Manager +├── .claude/ +│ └── settings.json # Claude Code permissions +├── .tmux.conf # Configurare tmux +└── start-agent.sh # Script helper tmux + +/workspace/ # Director pentru proiecte +├── CLAUDE.md # Template info agent +└── SETUP-COMPLETE.md # Acest fișier +``` + +## Troubleshooting + +### Claude Code nu pornește +```bash +source ~/.nvm/nvm.sh +which claude +``` + +### tmux nu găsește sesiunea +```bash +tmux ls +tmux new -s agent +``` + +### Git clone eșuează +- Verifică dacă ai adăugat SSH key-ul în Gitea +- Testează cu: `ssh -T git@gitea.romfast.ro` + +--- +*Setup realizat automat cu Claude Code* diff --git a/finish-task.sh b/finish-task.sh new file mode 100755 index 0000000..382e567 --- /dev/null +++ b/finish-task.sh @@ -0,0 +1,31 @@ +#!/bin/bash +# Script pentru a finaliza un task (commit + push) + +PROJECT_DIR="/workspace/romfastsql" +cd "$PROJECT_DIR" || exit 1 + +BRANCH=$(git branch --show-current) + +if [ "$BRANCH" = "main" ]; then + echo "❌ Ești pe main! Nu face commit direct pe main." + exit 1 +fi + +echo "📋 Status curent:" +git status --short + +echo "" +read -p "Mesaj commit: " COMMIT_MSG + +if [ -z "$COMMIT_MSG" ]; then + echo "❌ Trebuie să dai un mesaj pentru commit" + exit 1 +fi + +git add . +git commit -m "$COMMIT_MSG" +git push -u origin "$BRANCH" + +echo "" +echo "✅ Done! Branch-ul $BRANCH a fost push-uit." +echo "🔗 Creează Pull Request în Gitea: https://gitea.romfast.ro/romfast/romfastsql/compare/main...$BRANCH" diff --git a/new-task.sh b/new-task.sh new file mode 100755 index 0000000..0106f8f --- /dev/null +++ b/new-task.sh @@ -0,0 +1,26 @@ +#!/bin/bash +# Script pentru a începe un task nou cu branch + +if [ -z "$1" ]; then + echo "Utilizare: ~/new-task.sh " + echo "Exemplu: ~/new-task.sh fix/rezolva-bug" + exit 1 +fi + +BRANCH_NAME="$1" +PROJECT_DIR="/workspace/romfastsql" + +cd "$PROJECT_DIR" || exit 1 + +# Actualizează main +echo "📥 Actualizez main..." +git checkout main +git pull origin main + +# Creează branch nou +echo "🌿 Creez branch: $BRANCH_NAME" +git checkout -b "$BRANCH_NAME" + +echo "✅ Gata! Ești pe branch-ul: $BRANCH_NAME" +echo "" +echo "Pornește Claude cu: source ~/.nvm/nvm.sh && claude" diff --git a/start-agent.sh b/start-agent.sh new file mode 100755 index 0000000..4854253 --- /dev/null +++ b/start-agent.sh @@ -0,0 +1,17 @@ +#!/bin/bash +# Start or attach to Claude agent tmux session + +SESSION_NAME="agent" + +# Load nvm +export NVM_DIR="$HOME/.nvm" +[ -s "$NVM_DIR/nvm.sh" ] && \. "$NVM_DIR/nvm.sh" + +# Check if session exists +if tmux has-session -t $SESSION_NAME 2>/dev/null; then + echo "Attaching to existing session: $SESSION_NAME" + tmux attach-session -t $SESSION_NAME +else + echo "Creating new session: $SESSION_NAME" + tmux new-session -s $SESSION_NAME -c /workspace +fi diff --git a/work.sh b/work.sh new file mode 100755 index 0000000..673fbe1 --- /dev/null +++ b/work.sh @@ -0,0 +1,440 @@ +#!/bin/bash +# ============================================================================ +# Claude Workflow Script - Lansare Claude automat cu monitorizare progres +# ============================================================================ +# Funcționalități: +# - Selectare proiect din workspace +# - Mod feature (worktree) vs. mod temporar (fără worktree) +# - Lansare Claude cu -p (non-interactiv) și stream-json pentru progres +# - Monitorizare în timp real a progresului +# ============================================================================ + +set -e + +WORKSPACE="/workspace" +WORKTREES_BASE="/workspace/.worktrees" +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_section() { + echo -e "\n${BOLD}${MAGENTA}▸ $1${NC}\n" +} + +print_success() { + echo -e "${GREEN}✓ $1${NC}" +} + +print_error() { + echo -e "${RED}✗ $1${NC}" +} + +print_info() { + echo -e "${YELLOW}ℹ $1${NC}" +} + +# ============================================================================ +# Selectare Proiect +# ============================================================================ + +select_project() { + print_section "Proiecte disponibile" + + projects=() + i=1 + for dir in "$WORKSPACE"/*/; do + if [ -d "$dir/.git" ]; then + name=$(basename "$dir") + projects+=("$dir") + branch=$(cd "$dir" && git branch --show-current 2>/dev/null || echo "n/a") + echo -e " ${BOLD}$i)${NC} $name ${CYAN}[$branch]${NC}" + ((i++)) + fi + done + + if [ ${#projects[@]} -eq 0 ]; then + print_error "Nu am găsit proiecte Git în $WORKSPACE" + exit 1 + fi + + echo "" + read -p "Alege proiect [1-$((i-1))]: " proj_choice + + if [ -z "$proj_choice" ] || [ "$proj_choice" -lt 1 ] || [ "$proj_choice" -gt ${#projects[@]} ]; then + print_error "Selecție invalidă" + exit 1 + fi + + PROJECT_DIR="${projects[$((proj_choice-1))]}" + PROJECT_NAME=$(basename "$PROJECT_DIR") + + print_success "Proiect selectat: $PROJECT_NAME" +} + +# ============================================================================ +# Selectare Mod de Lucru +# ============================================================================ + +select_work_mode() { + print_section "Mod de lucru" + + echo -e " ${BOLD}1)${NC} ${GREEN}Feature nou${NC} ${CYAN}(worktree separat)${NC}" + echo -e " └─ Creează branch + worktree izolat pentru dezvoltare" + echo "" + echo -e " ${BOLD}2)${NC} ${YELLOW}Task temporar${NC} ${CYAN}(fără worktree)${NC}" + echo -e " └─ Documente, analiză, rezultate temporare" + echo "" + echo -e " ${BOLD}3)${NC} ${BLUE}Mod interactiv${NC} ${CYAN}(claude normal)${NC}" + echo -e " └─ Pornește Claude interactiv pe branch-ul curent" + echo "" + echo -e " ${BOLD}4)${NC} ${MAGENTA}Gestionare worktrees${NC}" + echo -e " └─ Vezi, șterge worktrees existente" + echo "" + + read -p "Alege mod [1-4]: " mode_choice + + case $mode_choice in + 1) WORK_MODE="feature" ;; + 2) WORK_MODE="temp" ;; + 3) WORK_MODE="interactive" ;; + 4) WORK_MODE="manage" ;; + *) + print_error "Opțiune invalidă" + exit 1 + ;; + esac +} + +# ============================================================================ +# Selectare tip feature (pentru modul feature) +# ============================================================================ + +select_feature_type() { + print_section "Tip feature" + + echo -e " ${BOLD}1)${NC} feature/ - Funcționalitate nouă" + echo -e " ${BOLD}2)${NC} fix/ - Bug fix" + echo -e " ${BOLD}3)${NC} refactor/ - Refactorizare cod" + echo -e " ${BOLD}4)${NC} docs/ - Documentație" + echo -e " ${BOLD}5)${NC} test/ - Teste" + echo -e " ${BOLD}6)${NC} chore/ - Mentenanță" + echo -e " ${BOLD}7)${NC} [custom] - Prefix personalizat" + echo "" + + read -p "Alege tip [1-7]: " type_choice + + case $type_choice in + 1) BRANCH_PREFIX="feature" ;; + 2) BRANCH_PREFIX="fix" ;; + 3) BRANCH_PREFIX="refactor" ;; + 4) BRANCH_PREFIX="docs" ;; + 5) BRANCH_PREFIX="test" ;; + 6) BRANCH_PREFIX="chore" ;; + 7) + read -p "Prefix custom: " BRANCH_PREFIX + ;; + *) BRANCH_PREFIX="feature" ;; + esac +} + +# ============================================================================ +# Obține descrierea task-ului +# ============================================================================ + +get_task_description() { + print_section "Descriere task" + + echo -e "${CYAN}Descrie ce vrei să facă Claude:${NC}" + echo "" + read -p "> " TASK_DESCRIPTION + + if [ -z "$TASK_DESCRIPTION" ]; 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_DESCRIPTION="$TASK_DESCRIPTION. $extra" + fi +} + +# ============================================================================ +# Creează worktree pentru feature +# ============================================================================ + +create_worktree() { + local branch_name="$1" + local worktree_path="$WORKTREES_BASE/$PROJECT_NAME/$branch_name" + + mkdir -p "$WORKTREES_BASE/$PROJECT_NAME" + + cd "$PROJECT_DIR" + + # Actualizează main/master + DEFAULT_BRANCH=$(git symbolic-ref refs/remotes/origin/HEAD 2>/dev/null | sed 's@^refs/remotes/origin/@@' || echo "main") + + print_info "Actualizez $DEFAULT_BRANCH..." + git fetch origin "$DEFAULT_BRANCH" 2>/dev/null || true + + # Creează worktree + print_info "Creez worktree: $worktree_path" + + if [ -d "$worktree_path" ]; then + print_error "Worktree există deja: $worktree_path" + read -p "Șterge și recreează? [y/N]: " confirm + if [ "$confirm" = "y" ] || [ "$confirm" = "Y" ]; then + git worktree remove "$worktree_path" --force 2>/dev/null || rm -rf "$worktree_path" + git branch -D "$branch_name" 2>/dev/null || true + else + exit 1 + fi + fi + + git worktree add -b "$branch_name" "$worktree_path" "origin/$DEFAULT_BRANCH" + + WORKING_DIR="$worktree_path" + print_success "Worktree creat: $worktree_path" +} + +# ============================================================================ +# Rulează Claude cu monitorizare progres +# ============================================================================ + +run_claude_with_progress() { + local work_dir="$1" + local prompt="$2" + local log_file="$3" + + cd "$work_dir" + + print_section "Lansare Claude" + echo -e "${CYAN}Director:${NC} $work_dir" + echo -e "${CYAN}Log:${NC} $log_file" + echo -e "${CYAN}Prompt:${NC} $prompt" + echo "" + + # Pregătește log directory + mkdir -p "$LOG_DIR" + + local start_time=$(date +%s) + + # Header pentru progress + echo -e "${BOLD}${BLUE}╔════════════════════════════════════════════════════════════════╗${NC}" + echo -e "${BOLD}${BLUE}║${NC} ${CYAN}Claude Code - Execuție în curs${NC} ${BOLD}${BLUE}║${NC}" + echo -e "${BOLD}${BLUE}╚════════════════════════════════════════════════════════════════╝${NC}" + echo "" + + # Salvează prompt-ul într-un fișier temporar pentru a evita probleme cu escape + local prompt_file=$(mktemp) + echo "$prompt" > "$prompt_file" + + # Rulează Claude cu stream-json și procesează output-ul în timp real + # --allowedTools pre-aprobă tool-urile necesare pentru execuție automată + # --max-turns limitează iterațiile pentru siguranță + claude -p "$(cat "$prompt_file")" \ + --output-format stream-json \ + --verbose \ + --allowedTools "Bash,Read,Edit,Write,Grep,Glob,LSP" \ + --max-turns 20 2>&1 | tee "$log_file" | while IFS= read -r line; do + + # Parsează JSON și extrage informații relevante + if echo "$line" | jq -e . >/dev/null 2>&1; then + # Extrage tipul mesajului + msg_type=$(echo "$line" | jq -r '.type // empty' 2>/dev/null) + + case "$msg_type" in + "assistant") + # Mesaj de la Claude - extrage text + content=$(echo "$line" | jq -r ' + .message.content[]? | + select(.type == "text") | + .text // empty + ' 2>/dev/null | head -c 150) + if [ -n "$content" ]; then + echo -e "${GREEN}◉${NC} $content" + fi + ;; + "user") + # Tool result + echo -e "${CYAN} ↪${NC} Tool result received" + ;; + "result") + # Rezultat final + result_text=$(echo "$line" | jq -r '.result // empty' 2>/dev/null | head -c 200) + echo "" + echo -e "${GREEN}✓ REZULTAT:${NC}" + echo -e "$result_text" + ;; + *) + # Verifică pentru tool_use în content + tool_name=$(echo "$line" | jq -r '.message.content[]? | select(.type == "tool_use") | .name // empty' 2>/dev/null | head -1) + if [ -n "$tool_name" ]; then + echo -e "${YELLOW}⚙${NC} Tool: ${BOLD}$tool_name${NC}" + fi + ;; + esac + fi + done + + local exit_code=${PIPESTATUS[0]} + local end_time=$(date +%s) + local duration=$((end_time - start_time)) + + rm -f "$prompt_file" + + echo "" + echo -e "${BOLD}${BLUE}════════════════════════════════════════════════════════════════${NC}" + + if [ $exit_code -eq 0 ]; then + print_success "Claude a terminat în ${duration}s" + else + print_error "Claude a terminat cu eroare (cod: $exit_code) în ${duration}s" + fi + + echo -e "${CYAN}Log salvat:${NC} $log_file" + echo -e "${BOLD}${BLUE}════════════════════════════════════════════════════════════════${NC}" + + return $exit_code +} + +# ============================================================================ +# Gestionare worktrees +# ============================================================================ + +manage_worktrees() { + print_section "Worktrees existente pentru $PROJECT_NAME" + + cd "$PROJECT_DIR" + + echo -e "${CYAN}Worktrees:${NC}" + git worktree list + echo "" + + echo -e " ${BOLD}1)${NC} Șterge un worktree" + echo -e " ${BOLD}2)${NC} Navighează la un worktree" + echo -e " ${BOLD}3)${NC} Înapoi" + echo "" + + read -p "Alege [1-3]: " manage_choice + + case $manage_choice in + 1) + read -p "Path worktree de șters: " wt_path + if [ -n "$wt_path" ]; then + git worktree remove "$wt_path" --force + print_success "Worktree șters" + fi + ;; + 2) + read -p "Path worktree: " wt_path + if [ -d "$wt_path" ]; then + cd "$wt_path" + print_success "Navigat la $wt_path" + exec bash + fi + ;; + 3) + return + ;; + esac +} + +# ============================================================================ +# Main +# ============================================================================ + +main() { + print_header "Claude Workflow Manager" + + # 1. Selectare proiect + select_project + + # 2. Selectare mod de lucru + select_work_mode + + case $WORK_MODE in + "feature") + # Mod feature cu worktree + select_feature_type + + echo "" + read -p "Nume scurt feature (ex: add-login, fix-auth): " feature_name + + if [ -z "$feature_name" ]; then + print_error "Trebuie să dai un nume pentru feature" + exit 1 + fi + + BRANCH_NAME="${BRANCH_PREFIX}/${feature_name}" + + get_task_description + + # Creează worktree + create_worktree "$BRANCH_NAME" + + # Generează log file + LOG_FILE="$LOG_DIR/${PROJECT_NAME}_${feature_name}_$(date +%Y%m%d_%H%M%S).log" + + # Rulează Claude + run_claude_with_progress "$WORKING_DIR" "$TASK_DESCRIPTION" "$LOG_FILE" + + echo "" + echo -e "${CYAN}Pentru a continua manual:${NC}" + echo -e " cd $WORKING_DIR" + echo -e " claude" + ;; + + "temp") + # Mod temporar fără worktree + get_task_description + + # Folosește directorul proiectului direct + WORKING_DIR="$PROJECT_DIR" + + # Generează log file + LOG_FILE="$LOG_DIR/${PROJECT_NAME}_temp_$(date +%Y%m%d_%H%M%S).log" + + # Rulează Claude + run_claude_with_progress "$WORKING_DIR" "$TASK_DESCRIPTION" "$LOG_FILE" + ;; + + "interactive") + # Mod interactiv normal + cd "$PROJECT_DIR" + print_info "Pornesc Claude interactiv în $PROJECT_NAME..." + exec claude + ;; + + "manage") + # Gestionare worktrees + manage_worktrees + ;; + esac +} + +# Rulează main +main "$@"