feat & fix : intégration IA éditeur + onglet admin IA + corrections CSP (v1.6.24-25)

- #96 : boutons IA sidebar éditeur (analyse critique / réécriture) via Anthropic API
- #97 : onglet admin /admin/ia — provider anthropic/claude_code, modèle, procédure CLI
- #95 : extraction scripts inline vers fichiers JS (comments.js, post_confirm.js, admin.js)

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
2026-05-16 12:18:38 +02:00
parent fabe5a9f53
commit 298f18dabe
16 changed files with 527 additions and 32 deletions
+125
View File
@@ -73,6 +73,10 @@ function adminStatusBadge(array $a, int $now): string
<a class="nav-link <?= $tab === 'flux' ? 'active' : '' ?>"
href="/admin/flux">Flux</a>
</li>
<li class="nav-item">
<a class="nav-link <?= $tab === 'ia' ? 'active' : '' ?>"
href="/admin/ia">IA</a>
</li>
<li class="nav-item">
<a class="nav-link <?= $tab === 'stats' ? 'active' : '' ?>"
href="/admin/stats">Statistiques</a>
@@ -1486,6 +1490,127 @@ foreach (COLOR_PALETTE_16 as $_i => $_rgb):
<?php endif; ?>
<?php if ($tab === 'ia' && isAdmin()): ?>
<?php
$_aiNotice = $adminData['ai_notice'] ?? '';
$_aiProvider = $adminData['ai_provider'] ?? 'anthropic';
$_aiModel = $adminData['ai_model'] ?? '';
$_anthropicOk = $adminData['anthropic_key_set'] ?? false;
$_cliOk = $adminData['claude_cli_found'] ?? false;
?>
<?php if ($_aiNotice === 'saved'): ?>
<div class="alert alert-success py-2 small">Configuration IA enregistrée.</div>
<?php elseif ($_aiNotice === 'error'): ?>
<div class="alert alert-danger py-2 small">Erreur lors de l'enregistrement.</div>
<?php endif; ?>
<h5 class="mb-3">Intelligence artificielle</h5>
<!-- Section 1 — Statut -->
<div class="card mb-4">
<div class="card-header fw-semibold small">Statut</div>
<div class="card-body p-0">
<table class="table table-sm mb-0">
<tbody>
<tr>
<th class="ps-3" scope="row">Clé Anthropic (<code>ANTHROPIC_API_KEY</code>)</th>
<td><?= $_anthropicOk ? '<span class="text-success">✓ Configurée</span>' : '<span class="text-danger">✗ Absente</span>' ?></td>
</tr>
<tr>
<th class="ps-3" scope="row">Claude Code CLI (<code>/usr/local/bin/claude</code>)</th>
<td><?= $_cliOk ? '<span class="text-success">✓ Trouvé</span>' : '<span class="text-danger">✗ Introuvable</span>' ?></td>
</tr>
<tr>
<th class="ps-3" scope="row">Provider actif</th>
<td><code><?= htmlspecialchars($_aiProvider) ?></code></td>
</tr>
<tr>
<th class="ps-3" scope="row">Modèle actif</th>
<td><code><?= htmlspecialchars($_aiModel ?: 'claude-haiku-4-5-20251001 (défaut)') ?></code></td>
</tr>
</tbody>
</table>
</div>
</div>
<!-- Section 2 — Configuration -->
<div class="card mb-4">
<div class="card-header fw-semibold small">Configuration</div>
<div class="card-body">
<form method="POST" action="/?action=admin_save_ai_config">
<div class="mb-3">
<label class="form-label fw-semibold small">Provider</label>
<div class="d-flex gap-3">
<div class="form-check">
<input class="form-check-input" type="radio" name="ai_provider" id="ai_provider_anthropic"
value="anthropic" <?= $_aiProvider === 'anthropic' ? 'checked' : '' ?>>
<label class="form-check-label" for="ai_provider_anthropic">Anthropic (API)</label>
</div>
<div class="form-check">
<input class="form-check-input" type="radio" name="ai_provider" id="ai_provider_claude_code"
value="claude_code" <?= $_aiProvider === 'claude_code' ? 'checked' : '' ?>>
<label class="form-check-label" for="ai_provider_claude_code">Claude Code CLI</label>
</div>
</div>
</div>
<div class="mb-3">
<label for="ai_model" class="form-label fw-semibold small">Modèle Anthropic</label>
<input type="text" class="form-control form-control-sm font-monospace" id="ai_model" name="ai_model"
value="<?= htmlspecialchars($_aiModel) ?>"
placeholder="claude-haiku-4-5-20251001">
<div class="form-text">Laisser vide pour utiliser le défaut (<code>claude-haiku-4-5-20251001</code>). Ignoré si le provider est Claude Code CLI.</div>
</div>
<button type="submit" class="btn btn-primary btn-sm">Enregistrer</button>
</form>
</div>
</div>
<!-- Section 3 — Clé Anthropic -->
<div class="card mb-4">
<div class="card-header fw-semibold small">Clé API Anthropic</div>
<div class="card-body">
<div class="alert alert-warning py-2 small mb-0">
<strong>La clé API Anthropic ne peut pas être saisie ici.</strong><br>
Elle doit être définie dans le fichier <code>.env</code> du serveur :
<pre class="mt-2 mb-0 small"><code>ANTHROPIC_API_KEY=sk-ant-...</code></pre>
<div class="mt-2">Statut actuel : <?= $_anthropicOk ? '<span class="text-success">✓ Configurée</span>' : '<span class="text-danger">✗ Absente</span>' ?></div>
</div>
</div>
</div>
<!-- Section 4 — Procédure Claude Code CLI -->
<div class="card mb-4">
<div class="card-header fw-semibold small">Procédure d'installation de Claude Code CLI</div>
<div class="card-body">
<?php if ($_cliOk): ?>
<div class="alert alert-success py-2 small mb-3">✓ <code>/usr/local/bin/claude</code> détecté.</div>
<?php else: ?>
<div class="alert alert-secondary py-2 small mb-3">✗ <code>/usr/local/bin/claude</code> introuvable — suivez les étapes ci-dessous.</div>
<?php endif; ?>
<p class="small text-muted">À exécuter en SSH sur le serveur (en root ou via sudo) :</p>
<pre class="bg-dark text-light p-3 rounded small"><code># 1. Installer Claude Code CLI (en root)
sudo npm install -g @anthropic-ai/claude-code
# Vérifier l'installation
/usr/local/bin/claude --version
# 2. Créer le répertoire HOME de www-data pour Claude
sudo mkdir -p /var/lib/claude-www
sudo chown www-data:www-data /var/lib/claude-www
# 3. Authentifier Claude en tant que www-data
sudo -u www-data HOME=/var/lib/claude-www /usr/local/bin/claude auth login
# → Suivre les instructions (OAuth navigateur ou clé API)
# 4. Vérifier que ça fonctionne
sudo -u www-data HOME=/var/lib/claude-www /usr/local/bin/claude --print "Réponds juste OK"</code></pre>
</div>
</div>
<?php endif; ?>
<?php if ($tab === 'stats' && isAdmin()): ?>
<?php include __DIR__ . '/admin_stats.php'; ?>