diff --git a/.github/HOOKS.md b/.github/HOOKS.md index ce1e4757..c5db72ce 100644 --- a/.github/HOOKS.md +++ b/.github/HOOKS.md @@ -4,6 +4,17 @@ Il repository ha un pre-commit hook che verifica la qualità del codice prima di ogni commit. +## Post-Commit Hook: Auto-Implement Design Changes + +Quando committi modifiche a `ui-design.pen`, il post-commit hook: +1. Analizza automaticamente le modifiche (colori, typography, spacing, layout) +2. Spawna Claude Code in background per implementare le modifiche +3. Ti notifica quando l'implementazione è completa + +--- + +## Pre-Commit Hook Details + ### Cosa Fa 1. **Analizza file staged** — controlla solo TypeScript/Rust modificati @@ -102,3 +113,145 @@ Possibili miglioramenti: - [ ] Fail automatico se code health < soglia - [ ] Cache dei risultati per evitare re-analisi - [ ] Hook pre-push più pesante per analisi completa + +--- + +## Post-Commit Hook: Auto-Implement Design Changes + +### Cosa Fa + +Quando committi modifiche a `ui-design.pen`, il hook: + +1. **Analizza il diff** — usa `scripts/design-diff-analyzer.js` +2. **Identifica modifiche significative:** + - 🎨 Colori (fill, backgroundColor) + - 📝 Typography (fontSize, fontFamily) + - 📏 Spacing (padding, margin, gap) + - 🔲 Layout (nuovi componenti, riorganizzazioni) +3. **Spawna Claude Code** — in background via `openclaw sessions spawn` +4. **Auto-notifica** — quando l'implementazione è completa + +### Cosa Implementa + +| Tipo Modifica | Azione | +|--------------|--------| +| Colori | Aggiorna `src/theme.json` o CSS variables | +| Typography | Aggiorna `src/theme.json` typography | +| Spacing | Aggiorna `src/theme.json` spacing | +| Layout | Modifica/crea componenti React | +| Testi mockup | Nessuna azione (solo design) | + +### Esempio Output + +``` +🎨 Design file changed - analyzing... + +📋 Implementation tasks: + +1. [HIGH] Update color palette + - fill: $--muted-foreground → #666666 + - backgroundColor: #FFFFFF → #F5F5F5 + +Update src/theme.json or CSS variables to match the design. + +2. [MEDIUM] Update typography + - fontSize: 14px → 16px + +Update src/theme.json typography settings. + +🚀 Spawning Claude Code to implement changes... + +✅ Claude Code spawned - you'll be notified when implementation is complete +``` + +### Workflow Completo + +``` +You Post-Commit Hook Claude Code Brian (AI) + │ │ │ │ + ├─ Modify ui-design.pen │ │ │ + ├─ git add ui-design.pen │ │ │ + ├─ git commit │ │ │ + │ │ │ │ + │ ├─ Analyze diff │ │ + │ ├─ Generate tasks │ │ + │ ├─ Spawn Claude Code ────────> │ + │ │ │ │ + │ │ ├─ Implement changes │ + │ │ ├─ Test visually │ + │ │ ├─ Run tests │ + │ │ ├─ Commit │ + │ │ ├─ openclaw system event ────> + │ │ │ │ + │ │ │ ├─ Notify Telegram + │ <─────────────────────────────────────────────────────────────────────────────┘ + │ "✅ Design changes implemented and tested" +``` + +### Design Diff Analyzer + +Lo script `scripts/design-diff-analyzer.js` rileva: + +- **Color changes** — `"fill": "#OLD" → "#NEW"` +- **Font changes** — `"fontSize": 14 → 16` +- **Spacing** — `"padding": 8 → 12` +- **Content** — testi mockup (no implementation) + +Uso: +```bash +# Analizza ultimo commit +node scripts/design-diff-analyzer.js + +# Output JSON per automation +node scripts/design-diff-analyzer.js --json +``` + +### Disabilitare Temporaneamente + +Se vuoi committare il design senza auto-implementazione: + +```bash +# Disabilita hook +mv .git/hooks/post-commit .git/hooks/post-commit.disabled + +# Commit +git commit -m "design: update mockup" + +# Riabilita hook +mv .git/hooks/post-commit.disabled .git/hooks/post-commit +``` + +### Monitorare Claude Code + +Mentre Claude Code lavora in background: + +```bash +# Lista sub-agent attivi +openclaw sessions list --kinds isolated + +# Vedi log di un sub-agent +openclaw sessions history --session-key + +# Ferma sub-agent (se necessario) +openclaw subagents kill --target design-auto-implement +``` + +### Troubleshooting + +**Hook non parte:** +- Verifica che `ui-design.pen` sia effettivamente cambiato: `git diff HEAD~1 ui-design.pen` +- Verifica che lo script analyzer esista: `ls -la scripts/design-diff-analyzer.js` + +**Nessuna notifica:** +- Claude Code potrebbe essere ancora in esecuzione — controlla `openclaw sessions list` +- Verifica che il prompt includa `openclaw system event` al termine + +**Modifiche non implementate:** +- Controlla i log di Claude Code: `openclaw sessions history --session-key ` +- Il sub-agent viene auto-eliminato dopo completion (cleanup=delete) + +### Limitazioni + +- **Modifiche complesse** — layout completamente nuovi potrebbero richiedere intervento manuale +- **Timeout** — 10 minuti max (configurabile in hook) +- **Solo modifiche recenti** — analizza solo HEAD vs HEAD~1 diff --git a/.github/hooks/install-hooks.sh b/.github/hooks/install-hooks.sh index 1832b148..5c12ccd7 100755 --- a/.github/hooks/install-hooks.sh +++ b/.github/hooks/install-hooks.sh @@ -9,11 +9,17 @@ echo "Installing git hooks..." # Copy pre-commit hook cp "$SCRIPT_DIR/pre-commit" "$HOOKS_DIR/pre-commit" chmod +x "$HOOKS_DIR/pre-commit" - echo "✅ Installed pre-commit hook" + +# Copy post-commit hook +cp "$SCRIPT_DIR/post-commit" "$HOOKS_DIR/post-commit" +chmod +x "$HOOKS_DIR/post-commit" +echo "✅ Installed post-commit hook" + echo "" echo "Hooks installed:" echo " - pre-commit: CodeScene code health check" +echo " - post-commit: Auto-implement design changes via Claude Code" echo "" -echo "To bypass a hook, use: git commit --no-verify" +echo "To bypass pre-commit, use: git commit --no-verify" echo "Or include [skip codescene] in your commit message" diff --git a/.github/hooks/post-commit b/.github/hooks/post-commit new file mode 100644 index 00000000..fb6cfb68 --- /dev/null +++ b/.github/hooks/post-commit @@ -0,0 +1,72 @@ +#!/bin/bash +# Post-commit hook: Auto-implement design changes via Claude Code +# Copy to .git/hooks/post-commit and make executable + +set -e + +# Check if ui-design.pen was modified in this commit +if ! git diff --name-only HEAD~1 HEAD | grep -q "ui-design.pen"; then + exit 0 +fi + +echo "" +echo "🎨 Design file changed - analyzing..." + +# Run analyzer +ANALYZER_OUTPUT=$(node scripts/design-diff-analyzer.js --json 2>&1) + +if [ $? -eq 0 ]; then + echo "✅ No implementation tasks needed (content-only changes)" + exit 0 +fi + +# Extract tasks from JSON +TASKS_JSON=$(echo "$ANALYZER_OUTPUT" | sed -n '/---JSON---/,$ p' | tail -n +2) + +if [ -z "$TASKS_JSON" ]; then + echo "✅ No significant design changes" + exit 0 +fi + +echo "$ANALYZER_OUTPUT" | sed '/---JSON---/,$ d' + +# Generate Claude Code prompt +PROMPT=$(cat < 0) { + const colorList = changes.colors.map(c => + ` - ${c.type}: ${c.from} → ${c.to}` + ).join('\n'); + + tasks.push({ + priority: 'high', + description: 'Update color palette', + details: `Color changes detected:\n${colorList}\n\nUpdate src/theme.json or CSS variables to match the design.` + }); + } + + // Typography changes → update theme.json + if (changes.typography.length > 0) { + const typoList = changes.typography.map(t => + ` - ${t.type}: ${t.from}px → ${t.to}px` + ).join('\n'); + + tasks.push({ + priority: 'medium', + description: 'Update typography', + details: `Typography changes detected:\n${typoList}\n\nUpdate src/theme.json typography settings.` + }); + } + + // Spacing changes → update theme.json + if (changes.spacing.length > 0) { + const spacingList = changes.spacing.map(s => + ` - ${s.type}: ${s.from}px → ${s.to}px` + ).join('\n'); + + tasks.push({ + priority: 'medium', + description: 'Update spacing', + details: `Spacing changes detected:\n${spacingList}\n\nUpdate src/theme.json spacing values.` + }); + } + + return tasks; +} + +function formatOutput(tasks, changes) { + if (tasks.length === 0 && changes.content.length === 0) { + return null; + } + + let output = '🎨 Design changes detected:\n\n'; + + if (tasks.length > 0) { + output += '📋 Implementation tasks:\n\n'; + tasks.forEach((task, i) => { + output += `${i + 1}. [${task.priority.toUpperCase()}] ${task.description}\n`; + output += `${task.details}\n\n`; + }); + } + + if (changes.content.length > 0) { + output += '📝 Content changes (mockup text only, no code changes needed):\n'; + changes.content.forEach(c => { + output += ` - "${c.from}" → "${c.to}"\n`; + }); + output += '\n'; + } + + return { output, tasks }; +} + +function main() { + const diff = getDiff(); + + if (!diff) { + console.log('No design changes detected'); + process.exit(0); + } + + const changes = analyzeDiff(diff); + const tasks = generateTasks(changes); + const result = formatOutput(tasks, changes); + + if (!result) { + console.log('No significant design changes detected'); + process.exit(0); + } + + console.log(result.output); + + // Output JSON for automation + if (process.argv.includes('--json')) { + console.log('\n---JSON---'); + console.log(JSON.stringify({ tasks, changes }, null, 2)); + } + + process.exit(tasks.length > 0 ? 1 : 0); // Exit 1 if there are tasks to implement +} + +main();