Reorganizare documentație și adăugare scripturi
- README.md nou cu documentație completă: concept, workflow-uri, configurare SSH prin Proxmox, Tailscale, troubleshooting - CLAUDE.md simplificat - doar reguli pentru mod non-interactiv - Șters SETUP-COMPLETE.md (conținut mutat în README) - claudep.sh - script pentru task-uri în background cu logging - work.sh - actualizat - .gitignore - adăugat node_modules, Python, IDE, build outputs 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
50
.gitignore
vendored
50
.gitignore
vendored
@@ -1,7 +1,57 @@
|
|||||||
# Exclude project directories
|
# Exclude project directories
|
||||||
romfastsql/
|
romfastsql/
|
||||||
test/
|
test/
|
||||||
|
|
||||||
|
# Claude Code
|
||||||
.claude-logs/
|
.claude-logs/
|
||||||
|
.claude-work/
|
||||||
|
.claude/
|
||||||
|
|
||||||
|
# Node.js
|
||||||
|
node_modules/
|
||||||
|
package-lock.json
|
||||||
|
npm-debug.log*
|
||||||
|
yarn-debug.log*
|
||||||
|
yarn-error.log*
|
||||||
|
.npm/
|
||||||
|
.yarn/
|
||||||
|
|
||||||
|
# Python
|
||||||
|
__pycache__/
|
||||||
|
*.py[cod]
|
||||||
|
*$py.class
|
||||||
|
.Python
|
||||||
|
*.egg-info/
|
||||||
|
.eggs/
|
||||||
|
*.egg
|
||||||
|
.venv/
|
||||||
|
venv/
|
||||||
|
ENV/
|
||||||
|
.env
|
||||||
|
|
||||||
|
# IDE & Editors
|
||||||
|
.idea/
|
||||||
|
.vscode/
|
||||||
|
*.swp
|
||||||
|
*.swo
|
||||||
|
*~
|
||||||
|
.DS_Store
|
||||||
|
|
||||||
|
# Build outputs
|
||||||
|
dist/
|
||||||
|
build/
|
||||||
|
*.o
|
||||||
|
*.so
|
||||||
|
|
||||||
|
# Logs
|
||||||
|
*.log
|
||||||
|
logs/
|
||||||
|
|
||||||
|
# Temporary files
|
||||||
|
*.tmp
|
||||||
|
*.temp
|
||||||
|
.cache/
|
||||||
|
tmp/
|
||||||
|
|
||||||
# Exclude any other project directories that might be added
|
# Exclude any other project directories that might be added
|
||||||
# Keep only workspace-level files (.sh, .md)
|
# Keep only workspace-level files (.sh, .md)
|
||||||
|
|||||||
54
CLAUDE.md
54
CLAUDE.md
@@ -1,43 +1,31 @@
|
|||||||
# Claude Agent Workspace
|
# Instrucțiuni Claude Code
|
||||||
|
|
||||||
## Informații Agent
|
## Reguli pentru Mod Non-Interactiv (claudep.sh / claude -p)
|
||||||
- **Hostname:** claude-agent
|
|
||||||
- **IP:** 10.0.20.171
|
|
||||||
- **User:** claude
|
|
||||||
- **Git remote:** gitea.romfast.ro
|
|
||||||
|
|
||||||
## Comenzi Utile
|
Când ești lansat în mod non-interactiv (pipe mode cu `claude -p`):
|
||||||
|
|
||||||
### Pornire sesiune agent
|
1. **Director de lucru separat**: Creează un director temporar pentru fișierele de lucru:
|
||||||
```bash
|
```
|
||||||
~/start-agent.sh
|
/workspace/.claude-work/<timestamp>_<task-name>/
|
||||||
```
|
```
|
||||||
|
Exemplu: `/workspace/.claude-work/20240115_143022_api-research/`
|
||||||
|
|
||||||
### Verificare tmux sessions
|
2. **NU crea fișiere direct în /workspace**: Orice fișier temporar, note, output sau rezultate trebuie să fie în directorul de lucru separat.
|
||||||
```bash
|
|
||||||
tmux ls
|
|
||||||
```
|
|
||||||
|
|
||||||
### Pornire Claude Code în proiect
|
3. **Structura recomandată**:
|
||||||
```bash
|
```
|
||||||
cd /workspace/<project>
|
/workspace/.claude-work/<task>/
|
||||||
claude
|
├── output/ # Rezultate finale
|
||||||
```
|
├── temp/ # Fișiere temporare
|
||||||
|
└── notes.md # Note și concluzii
|
||||||
|
```
|
||||||
|
|
||||||
## Workflow Recomandat
|
4. **La final**: Dacă sunt fișiere finale relevante pentru utilizator, menționează locația lor în output.
|
||||||
|
|
||||||
1. Conectează-te via SSH: `ssh claude@10.0.20.171`
|
5. **Excepție**: Modificările la fișiere existente din proiecte (cod, configurații) se fac normal, în locația lor originală.
|
||||||
2. Pornește sesiunea tmux: `~/start-agent.sh`
|
|
||||||
3. Navighează în proiect: `cd /workspace/<project>`
|
|
||||||
4. Pornește Claude: `claude`
|
|
||||||
|
|
||||||
## Git - Gitea
|
## Note Generale
|
||||||
Repository-urile se clonează cu:
|
|
||||||
```bash
|
|
||||||
git clone git@gitea.romfast.ro:romfast/<repo>.git
|
|
||||||
```
|
|
||||||
|
|
||||||
## Note
|
|
||||||
- Această mașină este configurată pentru dezvoltare cu Claude Code
|
|
||||||
- Toate proiectele ar trebui să fie în /workspace
|
- Toate proiectele ar trebui să fie în /workspace
|
||||||
- tmux prefix este Ctrl+A (nu Ctrl+B)
|
- Git remote: gitea.romfast.ro
|
||||||
|
- Vezi README.md pentru detalii despre sistem și comenzi
|
||||||
|
|||||||
367
README.md
Normal file
367
README.md
Normal file
@@ -0,0 +1,367 @@
|
|||||||
|
# Claude Agent - Cloud Development Environment
|
||||||
|
|
||||||
|
Container LXC configurat pentru **rularea Claude Code în cloud cu sesiuni permanente tmux**.
|
||||||
|
|
||||||
|
## Concept
|
||||||
|
|
||||||
|
Acest sistem permite:
|
||||||
|
1. **Lansezi o sarcină pentru Claude** (interactiv sau cu `claudep.sh`)
|
||||||
|
2. **Claude lucrează în tmux** - sesiunea persistă chiar dacă te deconectezi
|
||||||
|
3. **Te reconectezi oricând** - de pe laptop, telefon, alt calculator
|
||||||
|
4. **Vezi ce a făcut Claude** - revizuiești codul, testezi, dai feedback
|
||||||
|
5. **Push în Gitea** - când ești mulțumit cu rezultatul
|
||||||
|
|
||||||
|
Poți lansa un task dimineața, Claude lucrează toată ziua, iar seara te conectezi de pe alt calculator să vezi progresul.
|
||||||
|
|
||||||
|
## Informații Sistem
|
||||||
|
|
||||||
|
| Parametru | Valoare |
|
||||||
|
|-----------|---------|
|
||||||
|
| VMID | 171 |
|
||||||
|
| Hostname | claude-agent |
|
||||||
|
| IP LAN | 10.0.20.171 |
|
||||||
|
| IP Tailscale | claude-agent (sau 100.95.55.51) |
|
||||||
|
| Gateway | 10.0.20.1 |
|
||||||
|
| Host Proxmox | pveelite (10.0.20.202) |
|
||||||
|
| User | claude |
|
||||||
|
| Storage | local-zfs (32GB) |
|
||||||
|
| RAM | 4GB |
|
||||||
|
| CPU | 2 cores |
|
||||||
|
|
||||||
|
**Data setup:** 2025-12-31
|
||||||
|
|
||||||
|
## 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 |
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Conectare SSH
|
||||||
|
|
||||||
|
Poți te conecta în două moduri:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# Din rețeaua locală
|
||||||
|
ssh claude@10.0.20.171
|
||||||
|
|
||||||
|
# Prin Tailscale (de oriunde)
|
||||||
|
ssh claude@claude-agent
|
||||||
|
```
|
||||||
|
|
||||||
|
**Notă:** Nu există parolă setată pentru userul `claude`. Accesul se face doar cu SSH key.
|
||||||
|
Vezi secțiunea "Configurare Acces SSH" pentru instalarea cheii.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Workflow Principal
|
||||||
|
|
||||||
|
### Varianta 1: Sesiune Interactivă
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# 1. Conectare SSH (LAN sau Tailscale)
|
||||||
|
ssh claude@10.0.20.171 # sau
|
||||||
|
ssh claude@claude-agent # prin Tailscale
|
||||||
|
|
||||||
|
# 2. Pornire/reatașare sesiune tmux (automat)
|
||||||
|
~/start-agent.sh
|
||||||
|
|
||||||
|
# 3. Navighează în proiect și pornește Claude
|
||||||
|
cd /workspace/<project>
|
||||||
|
claude
|
||||||
|
|
||||||
|
# 4. Lucrezi cu Claude interactiv...
|
||||||
|
|
||||||
|
# 5. Când vrei să pleci - detașare din tmux (sesiunea rămâne activă)
|
||||||
|
Ctrl+A, d
|
||||||
|
|
||||||
|
# 6. Mai târziu - reconectare la sesiune (start-agent.sh reatașează automat)
|
||||||
|
ssh claude@claude-agent
|
||||||
|
~/start-agent.sh
|
||||||
|
```
|
||||||
|
|
||||||
|
### Varianta 2: Task în Background
|
||||||
|
|
||||||
|
Două scripturi disponibile:
|
||||||
|
|
||||||
|
**`work.sh`** - Te întreabă interactiv ce proiect și ce task:
|
||||||
|
```bash
|
||||||
|
ssh claude@claude-agent
|
||||||
|
/workspace/work.sh
|
||||||
|
# Răspunzi la întrebări despre proiect și task
|
||||||
|
```
|
||||||
|
|
||||||
|
**`claudep.sh`** - Rulează în directorul curent, creează fișiere independent:
|
||||||
|
```bash
|
||||||
|
ssh claude@claude-agent
|
||||||
|
cd /workspace/<project> # Navighează în proiect
|
||||||
|
/workspace/claudep.sh "Implementează autentificare JWT"
|
||||||
|
|
||||||
|
# SAU din /workspace (fișierele se creează în .claude-work/)
|
||||||
|
cd /workspace
|
||||||
|
/workspace/claudep.sh "Cercetează cele mai bune practici pentru API design"
|
||||||
|
```
|
||||||
|
|
||||||
|
**Monitorizare și rezultate:**
|
||||||
|
```bash
|
||||||
|
# Urmărește progresul în timp real
|
||||||
|
tail -f /workspace/.claude-logs/claude_*_progress.log
|
||||||
|
|
||||||
|
# Vezi rezultatele finale
|
||||||
|
cat /workspace/.claude-logs/claude_*_progress.log
|
||||||
|
```
|
||||||
|
|
||||||
|
### Varianta 3: VS Code Remote
|
||||||
|
|
||||||
|
Cea mai convenabilă metodă pentru lucru prelungit - editezi cod, vezi terminal, totul într-un singur loc.
|
||||||
|
|
||||||
|
1. **Configurează accesul SSH** (vezi secțiunea de mai jos)
|
||||||
|
2. **Instalează extensia** "Remote - SSH" în VS Code
|
||||||
|
3. **Conectare:** `Ctrl+Shift+P` → `Remote-SSH: Connect to Host...` → `claude-agent`
|
||||||
|
4. **Deschide terminal** în VS Code (`Ctrl+``)
|
||||||
|
5. **Atașează la sesiunea Claude:** `~/start-agent.sh`
|
||||||
|
6. **Lucrezi** - editezi fișiere în VS Code, interacționezi cu Claude în terminal
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Configurare Acces SSH (Prima dată)
|
||||||
|
|
||||||
|
**Problema:** Nu există parolă setată pentru userul `claude` în LXC. Accesul se face prin SSH key.
|
||||||
|
|
||||||
|
### Pas 1: Generează SSH key pe calculatorul tău (dacă nu ai)
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# Pe calculatorul tău (Windows PowerShell, Mac/Linux Terminal)
|
||||||
|
ssh-keygen -t ed25519 -C "your-email@example.com"
|
||||||
|
|
||||||
|
# Afișează cheia publică
|
||||||
|
cat ~/.ssh/id_ed25519.pub
|
||||||
|
# SAU pe Windows:
|
||||||
|
type %USERPROFILE%\.ssh\id_ed25519.pub
|
||||||
|
```
|
||||||
|
|
||||||
|
Copiază cheia publică (linia care începe cu `ssh-ed25519 ...`).
|
||||||
|
|
||||||
|
### Pas 2: Adaugă cheia în LXC prin Proxmox
|
||||||
|
|
||||||
|
Conectează-te la host-ul Proxmox și adaugă cheia în container:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# 1. SSH pe Proxmox host
|
||||||
|
ssh root@10.0.20.202 # pveelite
|
||||||
|
|
||||||
|
# 2. Intră în containerul LXC (VMID 171)
|
||||||
|
pct enter 171
|
||||||
|
|
||||||
|
# 3. Adaugă cheia publică SSH
|
||||||
|
echo "ssh-ed25519 AAAA...cheia_ta_aici... your-email@example.com" >> /home/claude/.ssh/authorized_keys
|
||||||
|
|
||||||
|
# 4. Verifică permisiunile (ar trebui să fie deja corecte)
|
||||||
|
chown claude:claude /home/claude/.ssh/authorized_keys
|
||||||
|
chmod 600 /home/claude/.ssh/authorized_keys
|
||||||
|
|
||||||
|
# 5. Ieși din container
|
||||||
|
exit
|
||||||
|
|
||||||
|
# 6. Ieși din Proxmox
|
||||||
|
exit
|
||||||
|
```
|
||||||
|
|
||||||
|
**Alternativ** (fără a intra în container):
|
||||||
|
```bash
|
||||||
|
# De pe Proxmox host, într-o singură comandă:
|
||||||
|
ssh root@10.0.20.202
|
||||||
|
|
||||||
|
pct exec 171 -- bash -c 'echo "ssh-ed25519 AAAA...cheia_ta... email" >> /home/claude/.ssh/authorized_keys'
|
||||||
|
```
|
||||||
|
|
||||||
|
### Pas 3: Configurează SSH pe calculatorul tău
|
||||||
|
|
||||||
|
Adaugă în `~/.ssh/config` (sau `%USERPROFILE%\.ssh\config` pe Windows):
|
||||||
|
|
||||||
|
```
|
||||||
|
# Acces prin Tailscale (recomandat - funcționează de oriunde)
|
||||||
|
Host claude-agent
|
||||||
|
HostName claude-agent
|
||||||
|
User claude
|
||||||
|
IdentityFile ~/.ssh/id_ed25519
|
||||||
|
ForwardAgent yes
|
||||||
|
|
||||||
|
# Acces prin LAN (doar din rețeaua locală)
|
||||||
|
Host claude-agent-lan
|
||||||
|
HostName 10.0.20.171
|
||||||
|
User claude
|
||||||
|
IdentityFile ~/.ssh/id_ed25519
|
||||||
|
ForwardAgent yes
|
||||||
|
```
|
||||||
|
|
||||||
|
### Pas 4: Testează conexiunea
|
||||||
|
|
||||||
|
```bash
|
||||||
|
ssh claude@claude-agent
|
||||||
|
# Ar trebui să te conectezi fără parolă
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Comenzi Utile
|
||||||
|
|
||||||
|
### tmux (Sesiuni Permanente)
|
||||||
|
```bash
|
||||||
|
~/start-agent.sh # Pornește SAU reatașează sesiune "agent" (automat)
|
||||||
|
tmux ls # Lista sesiuni active
|
||||||
|
tmux new -s <nume> # Sesiune nouă cu alt nume
|
||||||
|
Ctrl+A, d # Detașare (sesiunea continuă în background)
|
||||||
|
Ctrl+A, c # Fereastră nouă în sesiune
|
||||||
|
Ctrl+A, n # Fereastră următoare
|
||||||
|
Ctrl+A, p # Fereastră anterioară
|
||||||
|
Ctrl+A, [ # Mod scroll (q pentru ieșire)
|
||||||
|
```
|
||||||
|
|
||||||
|
**Notă:** Prefix-ul tmux este `Ctrl+A` (nu `Ctrl+B` ca default).
|
||||||
|
|
||||||
|
### Claude Code
|
||||||
|
```bash
|
||||||
|
claude # Pornire interactivă
|
||||||
|
claude -p "prompt" # Mod non-interactiv (pipe mode)
|
||||||
|
```
|
||||||
|
|
||||||
|
### Git - Gitea
|
||||||
|
```bash
|
||||||
|
git clone git@gitea.romfast.ro:romfast/<repo>.git
|
||||||
|
git push origin main
|
||||||
|
ssh -T git@gitea.romfast.ro # Test conexiune SSH
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## SSH Key pentru Gitea
|
||||||
|
|
||||||
|
Această cheie este deja generată pe server. Trebuie adăugată în Gitea:
|
||||||
|
|
||||||
|
1. Mergi la https://gitea.romfast.ro
|
||||||
|
2. Settings → SSH/GPG Keys → Add Key
|
||||||
|
3. Paste:
|
||||||
|
```
|
||||||
|
ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIKrxEqh5L1SRrZ4f6j04mLaNdr6LJf+xb9EKBvwegeXS claude-agent@romfast.ro
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Structura Directoare
|
||||||
|
|
||||||
|
```
|
||||||
|
/home/claude/
|
||||||
|
├── .ssh/
|
||||||
|
│ ├── authorized_keys # Chei SSH pentru acces (adaugă cheia ta aici)
|
||||||
|
│ ├── 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 (prefix Ctrl+A)
|
||||||
|
└── start-agent.sh # Script helper - pornește/reatașează tmux
|
||||||
|
|
||||||
|
/workspace/ # Director pentru proiecte
|
||||||
|
├── CLAUDE.md # Instrucțiuni pentru Claude Code
|
||||||
|
├── README.md # Acest fișier
|
||||||
|
├── claudep.sh # Task în background (directorul curent)
|
||||||
|
├── work.sh # Task interactiv (întreabă proiectul)
|
||||||
|
├── .claude-work/ # Fișiere temporare create de claude -p
|
||||||
|
├── .claude-logs/ # Log-uri pentru task-uri în background
|
||||||
|
└── <project>/ # Proiectele tale (clone din Gitea)
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Scripturi Disponibile
|
||||||
|
|
||||||
|
| Script | Descriere |
|
||||||
|
|--------|-----------|
|
||||||
|
| `~/start-agent.sh` | Pornește sesiune tmux "agent" sau reatașează dacă există |
|
||||||
|
| `/workspace/work.sh` | Lansează task - te întreabă interactiv proiectul și descrierea |
|
||||||
|
| `/workspace/claudep.sh` | Lansează task în directorul curent, cu logging |
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Troubleshooting
|
||||||
|
|
||||||
|
### Nu mă pot conecta SSH (Permission denied)
|
||||||
|
```bash
|
||||||
|
# Verifică dacă ai cheia SSH instalată
|
||||||
|
ssh -v claude@claude-agent
|
||||||
|
|
||||||
|
# Dacă nu ai acces, trebuie să adaugi cheia prin Proxmox:
|
||||||
|
ssh root@10.0.20.202
|
||||||
|
pct enter 171
|
||||||
|
# ... vezi secțiunea "Configurare Acces SSH"
|
||||||
|
```
|
||||||
|
|
||||||
|
### Claude Code nu pornește
|
||||||
|
```bash
|
||||||
|
source ~/.nvm/nvm.sh # Încarcă Node.js
|
||||||
|
which claude # Verifică dacă e în PATH
|
||||||
|
claude --version # Test
|
||||||
|
```
|
||||||
|
|
||||||
|
### tmux - sesiunea nu există
|
||||||
|
```bash
|
||||||
|
tmux ls # Vezi ce sesiuni există
|
||||||
|
~/start-agent.sh # Creează/reatașează sesiune "agent"
|
||||||
|
```
|
||||||
|
|
||||||
|
### Git clone eșuează
|
||||||
|
```bash
|
||||||
|
ssh -T git@gitea.romfast.ro # Test conexiune
|
||||||
|
# Dacă eșuează: verifică că ai adăugat SSH key în Gitea (vezi secțiunea dedicată)
|
||||||
|
```
|
||||||
|
|
||||||
|
### Claude pare blocat / nu răspunde
|
||||||
|
```bash
|
||||||
|
# În tmux, verifică dacă Claude așteaptă input
|
||||||
|
# Dacă da, răspunde sau Ctrl+C pentru a opri
|
||||||
|
|
||||||
|
# Pentru task-uri în background, verifică log-ul:
|
||||||
|
tail -f /workspace/.claude-logs/claude_*_progress.log
|
||||||
|
```
|
||||||
|
|
||||||
|
### Tailscale nu rezolvă hostname-ul
|
||||||
|
```bash
|
||||||
|
# Folosește IP-ul Tailscale direct
|
||||||
|
tailscale ip claude-agent # Pe alt device din Tailscale
|
||||||
|
ssh claude@<ip-rezultat>
|
||||||
|
|
||||||
|
# Sau folosește IP-ul LAN dacă ești în rețeaua locală
|
||||||
|
ssh claude@10.0.20.171
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Quick Reference
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# Conectare și pornire sesiune (Tailscale)
|
||||||
|
ssh claude@claude-agent && ~/start-agent.sh
|
||||||
|
|
||||||
|
# Conectare și pornire sesiune (LAN)
|
||||||
|
ssh claude@10.0.20.171 && ~/start-agent.sh
|
||||||
|
|
||||||
|
# Lansare task interactiv (te întreabă proiectul)
|
||||||
|
ssh claude@claude-agent -t "/workspace/work.sh"
|
||||||
|
|
||||||
|
# Lansare task în background pentru un proiect
|
||||||
|
ssh claude@claude-agent -t "cd /workspace/<project> && /workspace/claudep.sh 'descriere task'"
|
||||||
|
|
||||||
|
# Verificare log-uri
|
||||||
|
ssh claude@claude-agent "tail -50 /workspace/.claude-logs/claude_*_progress.log"
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
*Setup realizat cu Claude Code*
|
||||||
@@ -1,146 +0,0 @@
|
|||||||
# 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/<project>
|
|
||||||
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*
|
|
||||||
255
claudep.sh
Executable file
255
claudep.sh
Executable file
@@ -0,0 +1,255 @@
|
|||||||
|
#!/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 "$*"
|
||||||
500
work.sh
500
work.sh
@@ -102,8 +102,8 @@ select_work_mode() {
|
|||||||
echo -e " ${BOLD}1)${NC} ${GREEN}Feature nou${NC} ${CYAN}(worktree separat)${NC}"
|
echo -e " ${BOLD}1)${NC} ${GREEN}Feature nou${NC} ${CYAN}(worktree separat)${NC}"
|
||||||
echo -e " └─ Creează branch + worktree izolat pentru dezvoltare"
|
echo -e " └─ Creează branch + worktree izolat pentru dezvoltare"
|
||||||
echo ""
|
echo ""
|
||||||
echo -e " ${BOLD}2)${NC} ${YELLOW}Task temporar${NC} ${CYAN}(fără worktree)${NC}"
|
echo -e " ${BOLD}2)${NC} ${YELLOW}Task temporar${NC} ${CYAN}(background, fără worktree)${NC}"
|
||||||
echo -e " └─ Documente, analiză, rezultate temporare"
|
echo -e " └─ Rulează în background, revine la meniu"
|
||||||
echo ""
|
echo ""
|
||||||
echo -e " ${BOLD}3)${NC} ${BLUE}Mod interactiv${NC} ${CYAN}(claude normal)${NC}"
|
echo -e " ${BOLD}3)${NC} ${BLUE}Mod interactiv${NC} ${CYAN}(claude normal)${NC}"
|
||||||
echo -e " └─ Pornește Claude interactiv pe branch-ul curent"
|
echo -e " └─ Pornește Claude interactiv pe branch-ul curent"
|
||||||
@@ -111,14 +111,27 @@ select_work_mode() {
|
|||||||
echo -e " ${BOLD}4)${NC} ${MAGENTA}Gestionare worktrees${NC}"
|
echo -e " ${BOLD}4)${NC} ${MAGENTA}Gestionare worktrees${NC}"
|
||||||
echo -e " └─ Vezi, șterge worktrees existente"
|
echo -e " └─ Vezi, șterge worktrees existente"
|
||||||
echo ""
|
echo ""
|
||||||
|
echo -e " ${BOLD}5)${NC} ${CYAN}Vezi task-uri active${NC}"
|
||||||
|
echo -e " └─ Log-uri recente și procese Claude active"
|
||||||
|
echo ""
|
||||||
|
echo -e " ${BOLD}b)${NC} Înapoi la selectare proiect"
|
||||||
|
echo -e " ${BOLD}q)${NC} ${RED}Ieșire${NC}"
|
||||||
|
echo ""
|
||||||
|
|
||||||
read -p "Alege mod [1-4]: " mode_choice
|
read -p "Alege mod [1-5/b/q]: " mode_choice
|
||||||
|
|
||||||
case $mode_choice in
|
case $mode_choice in
|
||||||
1) WORK_MODE="feature" ;;
|
1) WORK_MODE="feature" ;;
|
||||||
2) WORK_MODE="temp" ;;
|
2) WORK_MODE="temp" ;;
|
||||||
3) WORK_MODE="interactive" ;;
|
3) WORK_MODE="interactive" ;;
|
||||||
4) WORK_MODE="manage" ;;
|
4) WORK_MODE="manage" ;;
|
||||||
|
5) WORK_MODE="status" ;;
|
||||||
|
b|B) WORK_MODE="back" ;;
|
||||||
|
q|Q)
|
||||||
|
echo ""
|
||||||
|
print_info "La revedere!"
|
||||||
|
exit 0
|
||||||
|
;;
|
||||||
*)
|
*)
|
||||||
print_error "Opțiune invalidă"
|
print_error "Opțiune invalidă"
|
||||||
exit 1
|
exit 1
|
||||||
@@ -221,7 +234,170 @@ create_worktree() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
# ============================================================================
|
# ============================================================================
|
||||||
# Rulează Claude cu monitorizare progres
|
# Rulează Claude în background cu log procesat
|
||||||
|
# ============================================================================
|
||||||
|
|
||||||
|
run_claude_background() {
|
||||||
|
local work_dir="$1"
|
||||||
|
local prompt="$2"
|
||||||
|
local log_file="$3"
|
||||||
|
|
||||||
|
# Log procesat (mesaje utile, nu JSON brut)
|
||||||
|
local processed_log="${log_file%.log}_progress.log"
|
||||||
|
# Fișier PID pentru tracking
|
||||||
|
local pid_file="${log_file%.log}.pid"
|
||||||
|
|
||||||
|
mkdir -p "$LOG_DIR"
|
||||||
|
|
||||||
|
print_section "Lansare Claude în background"
|
||||||
|
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} # Urmărește progresul"
|
||||||
|
echo -e " ${BOLD}ps aux | grep $bg_pid${NC} # Verifică dacă rulează"
|
||||||
|
echo ""
|
||||||
|
print_success "Revenire la meniu..."
|
||||||
|
sleep 2
|
||||||
|
}
|
||||||
|
|
||||||
|
# ============================================================================
|
||||||
|
# Rulează Claude cu monitorizare progres (pentru mod feature - sincron)
|
||||||
# ============================================================================
|
# ============================================================================
|
||||||
|
|
||||||
run_claude_with_progress() {
|
run_claude_with_progress() {
|
||||||
@@ -229,11 +405,14 @@ run_claude_with_progress() {
|
|||||||
local prompt="$2"
|
local prompt="$2"
|
||||||
local log_file="$3"
|
local log_file="$3"
|
||||||
|
|
||||||
|
# Log procesat (mesaje utile, nu JSON brut)
|
||||||
|
local processed_log="${log_file%.log}_progress.log"
|
||||||
|
|
||||||
cd "$work_dir"
|
cd "$work_dir"
|
||||||
|
|
||||||
print_section "Lansare Claude"
|
print_section "Lansare Claude"
|
||||||
echo -e "${CYAN}Director:${NC} $work_dir"
|
echo -e "${CYAN}Director:${NC} $work_dir"
|
||||||
echo -e "${CYAN}Log:${NC} $log_file"
|
echo -e "${CYAN}Log progres:${NC} $processed_log"
|
||||||
echo -e "${CYAN}Prompt:${NC} $prompt"
|
echo -e "${CYAN}Prompt:${NC} $prompt"
|
||||||
echo ""
|
echo ""
|
||||||
|
|
||||||
@@ -248,54 +427,114 @@ run_claude_with_progress() {
|
|||||||
echo -e "${BOLD}${BLUE}╚════════════════════════════════════════════════════════════════╝${NC}"
|
echo -e "${BOLD}${BLUE}╚════════════════════════════════════════════════════════════════╝${NC}"
|
||||||
echo ""
|
echo ""
|
||||||
|
|
||||||
|
# Inițializează log-ul procesat
|
||||||
|
{
|
||||||
|
echo "═══════════════════════════════════════════════════════════════"
|
||||||
|
echo " Claude Code - Task"
|
||||||
|
echo "═══════════════════════════════════════════════════════════════"
|
||||||
|
echo "Start: $(date '+%Y-%m-%d %H:%M:%S')"
|
||||||
|
echo "Director: $work_dir"
|
||||||
|
echo "Prompt: $prompt"
|
||||||
|
echo "═══════════════════════════════════════════════════════════════"
|
||||||
|
echo ""
|
||||||
|
} > "$processed_log"
|
||||||
|
|
||||||
# Salvează prompt-ul într-un fișier temporar pentru a evita probleme cu escape
|
# Salvează prompt-ul într-un fișier temporar pentru a evita probleme cu escape
|
||||||
local prompt_file=$(mktemp)
|
local prompt_file=$(mktemp)
|
||||||
echo "$prompt" > "$prompt_file"
|
echo "$prompt" > "$prompt_file"
|
||||||
|
|
||||||
# Rulează Claude cu stream-json și procesează output-ul în timp real
|
# 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")" \
|
claude -p "$(cat "$prompt_file")" \
|
||||||
--output-format stream-json \
|
--output-format stream-json \
|
||||||
--verbose \
|
--verbose \
|
||||||
--allowedTools "Bash,Read,Edit,Write,Grep,Glob,LSP" \
|
--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 20 2>&1 | tee "$log_file" | while IFS= read -r line; do
|
--max-turns 50 2>&1 | while IFS= read -r line; do
|
||||||
|
|
||||||
# Parsează JSON și extrage informații relevante
|
# Parsează JSON și extrage informații relevante
|
||||||
if echo "$line" | jq -e . >/dev/null 2>&1; then
|
if echo "$line" | jq -e . >/dev/null 2>&1; then
|
||||||
# Extrage tipul mesajului
|
|
||||||
msg_type=$(echo "$line" | jq -r '.type // empty' 2>/dev/null)
|
msg_type=$(echo "$line" | jq -r '.type // empty' 2>/dev/null)
|
||||||
|
timestamp=$(date '+%H:%M:%S')
|
||||||
|
|
||||||
case "$msg_type" in
|
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"
|
||||||
|
echo -e "${GREEN}▶${NC} Sesiune Claude pornită"
|
||||||
|
fi
|
||||||
|
;;
|
||||||
"assistant")
|
"assistant")
|
||||||
# Mesaj de la Claude - extrage text
|
# Verifică pentru tool_use - extrage detalii complete
|
||||||
content=$(echo "$line" | jq -r '
|
tool_info=$(echo "$line" | jq -r '
|
||||||
.message.content[]? |
|
.message.content[]? | select(.type == "tool_use") |
|
||||||
select(.type == "text") |
|
{name: .name, input: .input} |
|
||||||
.text // empty
|
if .name == "WebFetch" then "WebFetch: \(.input.url // "?") | \(.input.prompt // "" | .[0:50])"
|
||||||
' 2>/dev/null | head -c 150)
|
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"
|
||||||
|
echo -e "${YELLOW}⚙${NC} $tool_info"
|
||||||
|
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
|
if [ -n "$content" ]; then
|
||||||
|
echo "[$timestamp] 💬 $content" >> "$processed_log"
|
||||||
echo -e "${GREEN}◉${NC} $content"
|
echo -e "${GREEN}◉${NC} $content"
|
||||||
fi
|
fi
|
||||||
;;
|
;;
|
||||||
"user")
|
"user")
|
||||||
# Tool result
|
# Tool result - extrage detalii despre eroare
|
||||||
echo -e "${CYAN} ↪${NC} Tool result received"
|
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"
|
||||||
|
if [[ "$tool_result" == *"EROARE"* ]]; then
|
||||||
|
echo -e "${RED} $tool_result${NC}"
|
||||||
|
else
|
||||||
|
echo -e "${CYAN} $tool_result${NC}"
|
||||||
|
fi
|
||||||
|
else
|
||||||
|
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"
|
||||||
|
echo -e "${RED} ✗ EROARE: $err_content${NC}"
|
||||||
|
else
|
||||||
|
echo "[$timestamp] ✓ OK" >> "$processed_log"
|
||||||
|
echo -e "${CYAN} ✓ OK${NC}"
|
||||||
|
fi
|
||||||
|
fi
|
||||||
;;
|
;;
|
||||||
"result")
|
"result")
|
||||||
# Rezultat final
|
result_text=$(echo "$line" | jq -r '.result // empty' 2>/dev/null | head -c 500)
|
||||||
result_text=$(echo "$line" | jq -r '.result // empty' 2>/dev/null | head -c 200)
|
echo "" >> "$processed_log"
|
||||||
|
echo "[$timestamp] ════════════════════════════════════════════" >> "$processed_log"
|
||||||
|
echo "[$timestamp] ✅ TASK FINALIZAT" >> "$processed_log"
|
||||||
|
echo "[$timestamp] ════════════════════════════════════════════" >> "$processed_log"
|
||||||
|
echo "Rezultat:" >> "$processed_log"
|
||||||
|
echo "$result_text" >> "$processed_log"
|
||||||
|
|
||||||
echo ""
|
echo ""
|
||||||
echo -e "${GREEN}✓ REZULTAT:${NC}"
|
echo -e "${GREEN}✓ TASK FINALIZAT${NC}"
|
||||||
echo -e "$result_text"
|
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
|
esac
|
||||||
fi
|
fi
|
||||||
done
|
done
|
||||||
@@ -306,6 +545,16 @@ run_claude_with_progress() {
|
|||||||
|
|
||||||
rm -f "$prompt_file"
|
rm -f "$prompt_file"
|
||||||
|
|
||||||
|
# Finalizează log-ul procesat
|
||||||
|
{
|
||||||
|
echo ""
|
||||||
|
echo "═══════════════════════════════════════════════════════════════"
|
||||||
|
echo "End: $(date '+%Y-%m-%d %H:%M:%S')"
|
||||||
|
echo "Durată: ${duration}s"
|
||||||
|
echo "Exit code: $exit_code"
|
||||||
|
echo "═══════════════════════════════════════════════════════════════"
|
||||||
|
} >> "$processed_log"
|
||||||
|
|
||||||
echo ""
|
echo ""
|
||||||
echo -e "${BOLD}${BLUE}════════════════════════════════════════════════════════════════${NC}"
|
echo -e "${BOLD}${BLUE}════════════════════════════════════════════════════════════════${NC}"
|
||||||
|
|
||||||
@@ -315,52 +564,156 @@ run_claude_with_progress() {
|
|||||||
print_error "Claude a terminat cu eroare (cod: $exit_code) în ${duration}s"
|
print_error "Claude a terminat cu eroare (cod: $exit_code) în ${duration}s"
|
||||||
fi
|
fi
|
||||||
|
|
||||||
echo -e "${CYAN}Log salvat:${NC} $log_file"
|
echo -e "${CYAN}Log progres:${NC} $processed_log"
|
||||||
echo -e "${BOLD}${BLUE}════════════════════════════════════════════════════════════════${NC}"
|
echo -e "${BOLD}${BLUE}════════════════════════════════════════════════════════════════${NC}"
|
||||||
|
|
||||||
return $exit_code
|
return $exit_code
|
||||||
}
|
}
|
||||||
|
|
||||||
|
# ============================================================================
|
||||||
|
# Vezi task-uri active și log-uri recente
|
||||||
|
# ============================================================================
|
||||||
|
|
||||||
|
show_task_status() {
|
||||||
|
print_section "Task-uri active și log-uri recente"
|
||||||
|
|
||||||
|
# Afișează procese Claude active (bazat pe fișiere PID)
|
||||||
|
echo -e "${CYAN}Task-uri background active:${NC}"
|
||||||
|
local active_count=0
|
||||||
|
shopt -s nullglob
|
||||||
|
for pid_file in "$LOG_DIR"/*.pid; do
|
||||||
|
[ -f "$pid_file" ] || continue
|
||||||
|
local pid=$(cat "$pid_file" 2>/dev/null)
|
||||||
|
if [ -n "$pid" ] && kill -0 "$pid" 2>/dev/null; then
|
||||||
|
local log_name=$(basename "${pid_file%.pid}_progress.log")
|
||||||
|
echo -e " ${GREEN}●${NC} PID: $pid → $log_name"
|
||||||
|
((active_count++))
|
||||||
|
else
|
||||||
|
# PID invalid sau proces terminat - șterge fișierul
|
||||||
|
rm -f "$pid_file" 2>/dev/null
|
||||||
|
fi
|
||||||
|
done
|
||||||
|
if [ $active_count -eq 0 ]; then
|
||||||
|
echo -e " ${YELLOW}○${NC} Niciun task activ"
|
||||||
|
fi
|
||||||
|
echo ""
|
||||||
|
|
||||||
|
# Afișează log-uri de progres recente
|
||||||
|
echo -e "${CYAN}Log-uri recente (ultimele 5):${NC}"
|
||||||
|
local logs=$(ls -t "$LOG_DIR"/*_progress.log 2>/dev/null | head -5)
|
||||||
|
if [ -n "$logs" ]; then
|
||||||
|
local i=1
|
||||||
|
for log in $logs; do
|
||||||
|
local log_basename=$(basename "$log")
|
||||||
|
local pid_file="${log%_progress.log}.pid"
|
||||||
|
|
||||||
|
# Verifică status
|
||||||
|
if [ -f "$pid_file" ]; then
|
||||||
|
local pid=$(cat "$pid_file" 2>/dev/null)
|
||||||
|
if kill -0 "$pid" 2>/dev/null; then
|
||||||
|
status="${BLUE}◐ În curs (PID: $pid)${NC}"
|
||||||
|
else
|
||||||
|
status="${RED}✗ Întrerupt${NC}"
|
||||||
|
rm -f "$pid_file" 2>/dev/null
|
||||||
|
fi
|
||||||
|
elif grep -q "TASK FINALIZAT" "$log" 2>/dev/null; then
|
||||||
|
status="${GREEN}✓ Finalizat${NC}"
|
||||||
|
elif grep -q "Exit code:" "$log" 2>/dev/null; then
|
||||||
|
exit_code=$(grep "Exit code:" "$log" | tail -1 | awk '{print $NF}')
|
||||||
|
if [ "$exit_code" = "0" ]; then
|
||||||
|
status="${GREEN}✓ Terminat OK${NC}"
|
||||||
|
else
|
||||||
|
status="${RED}✗ Terminat cu eroare ($exit_code)${NC}"
|
||||||
|
fi
|
||||||
|
else
|
||||||
|
status="${RED}✗ Întrerupt/Incomplet${NC}"
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Afișează ultima activitate
|
||||||
|
local last_activity=$(grep "^\[" "$log" 2>/dev/null | tail -1 | head -c 100)
|
||||||
|
|
||||||
|
echo -e " ${BOLD}$i)${NC} $log_basename"
|
||||||
|
echo -e " Status: $status"
|
||||||
|
echo -e " Ultima: ${CYAN}${last_activity:-N/A}${NC}"
|
||||||
|
echo -e " Path: $log"
|
||||||
|
echo ""
|
||||||
|
((i++))
|
||||||
|
done
|
||||||
|
echo -e "${YELLOW}Comenzi utile:${NC}"
|
||||||
|
echo -e " tail -f <path> # Urmărește live"
|
||||||
|
echo -e " less <path> # Citește complet"
|
||||||
|
else
|
||||||
|
echo -e " ${YELLOW}○${NC} Nu există log-uri"
|
||||||
|
fi
|
||||||
|
echo ""
|
||||||
|
echo -e " ${BOLD}b)${NC} Înapoi la meniu"
|
||||||
|
echo -e " ${BOLD}q)${NC} ${RED}Ieșire${NC}"
|
||||||
|
echo ""
|
||||||
|
|
||||||
|
read -p "Alege [b/q]: " status_choice
|
||||||
|
case $status_choice in
|
||||||
|
q|Q)
|
||||||
|
echo ""
|
||||||
|
print_info "La revedere!"
|
||||||
|
exit 0
|
||||||
|
;;
|
||||||
|
*)
|
||||||
|
# Orice altceva (inclusiv b sau Enter) - înapoi la meniu
|
||||||
|
;;
|
||||||
|
esac
|
||||||
|
}
|
||||||
|
|
||||||
# ============================================================================
|
# ============================================================================
|
||||||
# Gestionare worktrees
|
# Gestionare worktrees
|
||||||
# ============================================================================
|
# ============================================================================
|
||||||
|
|
||||||
manage_worktrees() {
|
manage_worktrees() {
|
||||||
print_section "Worktrees existente pentru $PROJECT_NAME"
|
while true; do
|
||||||
|
print_section "Worktrees existente pentru $PROJECT_NAME"
|
||||||
|
|
||||||
cd "$PROJECT_DIR"
|
cd "$PROJECT_DIR"
|
||||||
|
|
||||||
echo -e "${CYAN}Worktrees:${NC}"
|
echo -e "${CYAN}Worktrees:${NC}"
|
||||||
git worktree list
|
git worktree list
|
||||||
echo ""
|
echo ""
|
||||||
|
|
||||||
echo -e " ${BOLD}1)${NC} Șterge un worktree"
|
echo -e " ${BOLD}1)${NC} Șterge un worktree"
|
||||||
echo -e " ${BOLD}2)${NC} Navighează la un worktree"
|
echo -e " ${BOLD}2)${NC} Navighează la un worktree"
|
||||||
echo -e " ${BOLD}3)${NC} Înapoi"
|
echo -e " ${BOLD}b)${NC} Înapoi la meniu"
|
||||||
echo ""
|
echo -e " ${BOLD}q)${NC} ${RED}Ieșire${NC}"
|
||||||
|
echo ""
|
||||||
|
|
||||||
read -p "Alege [1-3]: " manage_choice
|
read -p "Alege [1-2/b/q]: " manage_choice
|
||||||
|
|
||||||
case $manage_choice in
|
case $manage_choice in
|
||||||
1)
|
1)
|
||||||
read -p "Path worktree de șters: " wt_path
|
read -p "Path worktree de șters: " wt_path
|
||||||
if [ -n "$wt_path" ]; then
|
if [ -n "$wt_path" ]; then
|
||||||
git worktree remove "$wt_path" --force
|
git worktree remove "$wt_path" --force
|
||||||
print_success "Worktree șters"
|
print_success "Worktree șters"
|
||||||
fi
|
fi
|
||||||
;;
|
;;
|
||||||
2)
|
2)
|
||||||
read -p "Path worktree: " wt_path
|
read -p "Path worktree: " wt_path
|
||||||
if [ -d "$wt_path" ]; then
|
if [ -d "$wt_path" ]; then
|
||||||
cd "$wt_path"
|
cd "$wt_path"
|
||||||
print_success "Navigat la $wt_path"
|
print_success "Navigat la $wt_path"
|
||||||
exec bash
|
exec bash
|
||||||
fi
|
fi
|
||||||
;;
|
;;
|
||||||
3)
|
b|B)
|
||||||
return
|
exec "$0"
|
||||||
;;
|
;;
|
||||||
esac
|
q|Q)
|
||||||
|
echo ""
|
||||||
|
print_info "La revedere!"
|
||||||
|
exit 0
|
||||||
|
;;
|
||||||
|
*)
|
||||||
|
print_error "Opțiune invalidă"
|
||||||
|
;;
|
||||||
|
esac
|
||||||
|
done
|
||||||
}
|
}
|
||||||
|
|
||||||
# ============================================================================
|
# ============================================================================
|
||||||
@@ -373,8 +726,17 @@ main() {
|
|||||||
# 1. Selectare proiect
|
# 1. Selectare proiect
|
||||||
select_project
|
select_project
|
||||||
|
|
||||||
# 2. Selectare mod de lucru
|
# 2. Selectare mod de lucru (cu loop pentru navigare)
|
||||||
select_work_mode
|
while true; do
|
||||||
|
select_work_mode
|
||||||
|
|
||||||
|
# Dacă vrea înapoi, repornește scriptul
|
||||||
|
if [ "$WORK_MODE" = "back" ]; then
|
||||||
|
exec "$0"
|
||||||
|
fi
|
||||||
|
|
||||||
|
break
|
||||||
|
done
|
||||||
|
|
||||||
case $WORK_MODE in
|
case $WORK_MODE in
|
||||||
"feature")
|
"feature")
|
||||||
@@ -409,7 +771,7 @@ main() {
|
|||||||
;;
|
;;
|
||||||
|
|
||||||
"temp")
|
"temp")
|
||||||
# Mod temporar fără worktree
|
# Mod temporar fără worktree - rulează în background
|
||||||
get_task_description
|
get_task_description
|
||||||
|
|
||||||
# Folosește directorul proiectului direct
|
# Folosește directorul proiectului direct
|
||||||
@@ -418,8 +780,11 @@ main() {
|
|||||||
# Generează log file
|
# Generează log file
|
||||||
LOG_FILE="$LOG_DIR/${PROJECT_NAME}_temp_$(date +%Y%m%d_%H%M%S).log"
|
LOG_FILE="$LOG_DIR/${PROJECT_NAME}_temp_$(date +%Y%m%d_%H%M%S).log"
|
||||||
|
|
||||||
# Rulează Claude
|
# Rulează Claude în background și revine la meniu
|
||||||
run_claude_with_progress "$WORKING_DIR" "$TASK_DESCRIPTION" "$LOG_FILE"
|
run_claude_background "$WORKING_DIR" "$TASK_DESCRIPTION" "$LOG_FILE"
|
||||||
|
|
||||||
|
# Revine la meniu
|
||||||
|
exec "$0"
|
||||||
;;
|
;;
|
||||||
|
|
||||||
"interactive")
|
"interactive")
|
||||||
@@ -433,6 +798,13 @@ main() {
|
|||||||
# Gestionare worktrees
|
# Gestionare worktrees
|
||||||
manage_worktrees
|
manage_worktrees
|
||||||
;;
|
;;
|
||||||
|
|
||||||
|
"status")
|
||||||
|
# Vezi task-uri active
|
||||||
|
show_task_status
|
||||||
|
# Revine la meniu
|
||||||
|
exec "$0"
|
||||||
|
;;
|
||||||
esac
|
esac
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user