diff --git a/.claude/rules/install-reference.md b/.claude/rules/install-reference.md index 93d7cd1..503be26 100644 --- a/.claude/rules/install-reference.md +++ b/.claude/rules/install-reference.md @@ -44,6 +44,7 @@ paths: ./install.sh --with-design-clis # + bundle design (imagemagick · ffmpeg · svgo · sharp-cli) ./install.sh --with-devops-clis # + bundle devops (terraform · ansible · pulumi · act) ./install.sh --with-mobile-clis # + bundle mobile (xcrun · bundler · fastlane · expo · eas-cli) +./install.sh --with-obscura # + Obscura headless browser Rust (required, depuis 2026-05-07) — scraping JS-rendered, JS eval, multi-URL parallèle, serveur CDP · coexiste avec shot-scraper ./install.sh --dry-run # Simuler sans modifier ./install.sh --wizard # Forcer le wizard interactif même sur reinstall ``` @@ -63,9 +64,16 @@ Pandoc — Convertisseur universel de documents. Promu en base ulk depuis 2026-0 Install : `brew install pandoc` · `apt install pandoc` · `winget install pandoc`. Vérifier : `pandoc --version`. Règle : à invoquer dès qu'un agent lit/produit un format non-Markdown (`.docx`, `.pdf`, `.rst`, `.org`, `.epub`, `.tex`, `.odt`, HTML riche). Ne JAMAIS réécrire un parser ad-hoc. Voir protocole `framework/agents/_shared/obsidian-doc-protocol.md` (section *CLI Pandoc*). -Shot-Scraper (simonw) — Capture web headless : screenshots, JS execution, arbre d'accessibilité. **Adopté en base ulk depuis 2026-05-06** (priority `required` dans `framework/tools/cli-registry.json`). **Remplace `mcp__chrome-devtools__*` pour tous les agents.** Source : https://github.com/simonw/shot-scraper (MIT). +Shot-Scraper (simonw) — Capture web headless : screenshots, PDF, arbre d'accessibilité, auth interactive. **Adopté en base ulk depuis 2026-05-06** (priority `required` dans `framework/tools/cli-registry.json`). **Remplace `mcp__chrome-devtools__*` pour tous les agents.** Source : https://github.com/simonw/shot-scraper (MIT). Install : `pip install shot-scraper && shot-scraper install` (télécharge Chromium via Playwright). Vérifier : `shot-scraper --version`. -Usage : `shot-scraper -o file.png [--width W --height H --full-page]` · `shot-scraper javascript "js"` · `shot-scraper accessibility ` · `shot-scraper multi shots.yml` · `shot-scraper auth auth.json`. Protocole : `framework/agents/_shared/shot-scraper-protocol.md`. Agents : visual-auditor (03), frontend-qa (02), seo-auditor (32), agamotto (17). +Usage : `shot-scraper -o file.png [--width W --height H --full-page]` · `shot-scraper accessibility ` · `shot-scraper pdf file.pdf` · `shot-scraper multi shots.yml` · `shot-scraper auth auth.json`. +Depuis 2026-05-07, **les use cases JS eval (`shot-scraper javascript`) et scraping multi-URL sont délégués à Obscura** (voir ci-dessous). Shot-scraper conserve le rôle visuel : screenshots, PDF, arbre d'accessibilité, auth. +Protocole : `framework/agents/_shared/shot-scraper-protocol.md`. Agents : visual-auditor (03), frontend-qa (02), seo-auditor (32), agamotto (17). + +Obscura (h4ckf0r0day) — Headless browser engine en Rust, alternative légère à Chrome headless. **Adopté en base ulk depuis 2026-05-07** (priority `required` dans `framework/tools/cli-registry.json`). V8 + Chrome DevTools Protocol (CDP), compatible Puppeteer/Playwright, stealth mode anti-fingerprinting. Bench : 30 MB RAM (vs 200+ MB Chrome), binaire 70 MB (vs 300+ MB), 85 ms page load (vs ~500 ms). Source : https://github.com/h4ckf0r0day/obscura (Apache-2.0). +Install : binaires releases (`curl -fsSL -o /tmp/obscura.tar.gz https://github.com/h4ckf0r0day/obscura/releases/latest/download/obscura-{aarch64-macos|x86_64-macos|x86_64-linux}.tar.gz && tar -xzf /tmp/obscura.tar.gz -C /tmp && sudo mv /tmp/obscura /usr/local/bin/`) ou `cargo install --git https://github.com/h4ckf0r0day/obscura` (Rust 1.75+). Activation ulk : `./install.sh --with-obscura`. Vérifier : `obscura --version`. +Usage : `obscura fetch --eval "" [--selector S --wait-until networkidle --timeout 10000 --stealth]` · `obscura scrape urls.txt --concurrency N --eval "" --format json` · `obscura serve --port 9222 --stealth`. +Règle : *shot-scraper pour ce qui est visuel, Obscura pour ce qui est donnée*. Obscura prend les use cases scraping JS-rendered, JS eval, multi-URL parallèle (workers natifs Rust ~5-10× plus rapides que `shot-scraper multi`), serveur CDP (clients Puppeteer/Playwright). Protocole : `framework/agents/_shared/obscura-protocol.md`. Agents : visual-auditor (03), frontend-qa (02), seo-auditor (32), agamotto (17). RTK (Rust Token Killer) — proxy CLI qui compresse la sortie des commandes verbose (-60 à -90% tokens). Adopté en base ulk depuis 2026-04-27 (priority `required` dans `framework/tools/cli-registry.json`). diff --git a/CLAUDE.md b/CLAUDE.md index 4fc1873..1c86947 100644 --- a/CLAUDE.md +++ b/CLAUDE.md @@ -35,8 +35,9 @@ Options et community skills : @.claude/rules/install-reference.md **Priority rule**: CLI available → use it (0 tokens). No CLI + MCP configured → use MCP. Neither → inform user. -Key CLIs: `gh` (GitHub), `vercel` (deploy), `neonctl` (DB), `gws` (Google), `resend` (email), `rtk` (token compression), `notesmd-cli` (vault Obsidian), `defuddle` (web → Markdown), `pandoc` (conversions de format), `shot-scraper` (captures web, JS, accessibilité). -Shot-Scraper : **obligatoire** depuis 2026-05-06 (priority `required`). Source : https://github.com/simonw/shot-scraper (Simon Willison, MIT). Install : `pip install shot-scraper && shot-scraper install`. Usage : `shot-scraper -o file.png [--width W --height H --full-page]` · `shot-scraper javascript "js"` · `shot-scraper accessibility ` · `shot-scraper multi shots.yml`. **Remplace `mcp__chrome-devtools__*` pour tous les agents**. Protocole : `framework/agents/_shared/shot-scraper-protocol.md`. Agents concernés : visual-auditor (03), frontend-qa (02), seo-auditor (32), agamotto (17). +Key CLIs: `gh` (GitHub), `vercel` (deploy), `neonctl` (DB), `gws` (Google), `resend` (email), `rtk` (token compression), `notesmd-cli` (vault Obsidian), `defuddle` (web → Markdown), `pandoc` (conversions de format), `shot-scraper` (captures web visuelles), `obscura` (headless browser Rust — scraping/JS eval/CDP). +Shot-Scraper : **obligatoire** depuis 2026-05-06 (priority `required`). Source : https://github.com/simonw/shot-scraper (Simon Willison, MIT). Install : `pip install shot-scraper && shot-scraper install`. Usage : `shot-scraper -o file.png [--width W --height H --full-page]` · `shot-scraper accessibility ` · `shot-scraper pdf file.pdf` · `shot-scraper multi shots.yml` · `shot-scraper auth auth.json`. **Remplace `mcp__chrome-devtools__*` pour tous les agents**. Depuis 2026-05-07, **les use cases JS eval / scraping multi-URL sont délégués à Obscura** (voir ci-dessous) — shot-scraper conserve screenshots, PDF, arbre d'accessibilité, auth interactive. Protocole : `framework/agents/_shared/shot-scraper-protocol.md`. Agents concernés : visual-auditor (03), frontend-qa (02), seo-auditor (32), agamotto (17). +Obscura : **obligatoire** depuis 2026-05-07 (priority `required`). Source : https://github.com/h4ckf0r0day/obscura (Apache-2.0). Install : binaires releases (`curl -fsSL .../obscura-{aarch64-macos,x86_64-linux,x86_64-macos}.tar.gz`) ou `cargo install --git https://github.com/h4ckf0r0day/obscura` (Rust 1.75+). Activation ulk : `./install.sh --with-obscura`. Usage : `obscura fetch --eval "" [--selector S --wait-until networkidle --stealth]` · `obscura scrape urls.txt --concurrency N --eval "" --format json` · `obscura serve --port 9222 --stealth`. Headless browser engine en Rust (V8 + CDP, compatible Puppeteer/Playwright) : 30 MB RAM (vs 200+ MB Chrome), 85 ms page load (vs ~500 ms). **Coexiste avec shot-scraper** : règle simple — *shot-scraper pour ce qui est visuel, Obscura pour ce qui est donnée*. Obscura prend les use cases scraping JS-rendered, JS eval (`--eval`), multi-URL parallèle (`obscura scrape`, workers natifs Rust ~5-10× plus rapides que `shot-scraper multi`) et CDP (clients Puppeteer/Playwright). Protocole : `framework/agents/_shared/obscura-protocol.md`. Agents concernés : visual-auditor (03), frontend-qa (02), seo-auditor (32), agamotto (17). NotesMD CLI : **obligatoire** depuis 2026-04-29 (priority `required`). Source : https://github.com/Yakitrak/notesmd-cli (Go, MIT). Install : `brew tap yakitrak/yakitrak && brew install yakitrak/yakitrak/notesmd-cli`. Tous les agents qui touchent `docs/spec*` et `docs/todo.md` doivent privilégier `notesmd-cli daily|create|print|search|frontmatter|move` quand la CLI est dispo, et fallback fichier sinon. Avantage majeur sur la CLI officielle Obsidian : **n'exige pas que l'app desktop soit ouverte** (utilisable CI/headless). Voir `framework/agents/_shared/obsidian-doc-protocol.md`. Defuddle CLI : **obligatoire** depuis 2026-04-29 (priority `required`). Source : https://github.com/kepano/defuddle (MIT, kepano). Install : `npm install -g defuddle`. Usage : `defuddle parse [--markdown|--json]` — pour toute extraction Markdown depuis le web (preferred over `WebFetch` quand la sortie doit être réutilisée). Skill associée : `kepano-defuddle`. Pandoc : **obligatoire** depuis 2026-04-29 (priority `required`). Source : https://pandoc.org (GPL-2.0+). Install : `brew install pandoc` · `apt install pandoc` · `winget install pandoc`. À invoquer dès qu'un agent lit/produit un format non-Markdown : `.docx`, `.pdf`, `.rst`, `.org`, `.epub`, `.tex`, `.odt`, HTML riche. Jamais de parser ad-hoc. Exemples : `pandoc -f docx -t markdown brief.docx -o docs/brief.md` · `pandoc -f markdown -t pdf docs/spec.md -o docs/exports/spec.pdf`. Voir `framework/agents/_shared/obsidian-doc-protocol.md` (section *CLI Pandoc*). diff --git a/framework/agents/_shared/obscura-protocol.md b/framework/agents/_shared/obscura-protocol.md new file mode 100644 index 0000000..a356300 --- /dev/null +++ b/framework/agents/_shared/obscura-protocol.md @@ -0,0 +1,196 @@ +--- +name: obscura-protocol +type: protocol +description: Protocole partagé Obscura CLI — headless browser Rust pour scraping JS-rendered, JS eval, parallel multi-URL et CDP. Coexiste avec shot-scraper (qui garde screenshots/PDF/a11y). +--- + +# Obscura Protocol + +> Source : https://github.com/h4ckf0r0day/obscura (Apache-2.0) +> Headless browser engine en Rust — alternative légère à Chrome headless. +> 30 MB RAM (vs 200+ MB Chrome) · binaire 70 MB (vs 300+ MB) · 85 ms page load (vs ~500 ms). +> V8 + Chrome DevTools Protocol (CDP) · compatible Puppeteer/Playwright · stealth mode. + +## Principe + +**CLI-first** : Obscura est la CLI standard pour le **scraping**, **JS eval**, **multi-URL parallèle** et les scénarios **CDP** dans ulk. +**Coexiste avec shot-scraper** : shot-scraper reste la CLI canonique pour les **screenshots**, **PDF** et l'**arbre d'accessibilité**. + +### Décision Obscura vs shot-scraper + +| Use case | Outil | Raison | +|---------|-------|--------| +| Screenshot PNG/JPEG (single ou multi-viewport) | **shot-scraper** | API dédiée, presets viewport, `multi shots.yml` | +| PDF d'une page | **shot-scraper** | `shot-scraper pdf URL output.pdf` | +| Arbre d'accessibilité (rôles, labels, JSON sémantique) | **shot-scraper** | `shot-scraper accessibility URL` — Obscura n'a pas d'équivalent | +| Auth interactive enregistrée (cookies/session) | **shot-scraper** | `shot-scraper auth URL auth.json` | +| **JS eval / extraction DOM** (titre, h1, meta, listes, computed styles) | **Obscura** | `obscura fetch URL --eval "…"` — démarrage 4-6× plus rapide, RAM /6 | +| **Scraping multi-URL parallèle** (>5 URLs avec extraction) | **Obscura** | `obscura scrape urls.txt --concurrency N --eval "…"` — workers natifs | +| **CDP serveur** (client Puppeteer/Playwright se connecte) | **Obscura** | `obscura serve --port 9222 --stealth` | +| **Scraping JS-rendered protégé** (anti-bot léger, fingerprint) | **Obscura** | `--stealth` actif par défaut côté Obscura | +| **Page navigation + extraction** (un seul flow) | **Obscura** | `obscura fetch --selector --eval --wait-until networkidle` | + +> Règle simple : **shot-scraper pour ce qui est visuel, Obscura pour ce qui est donnée**. + +## Installation + +```bash +# macOS Apple Silicon +curl -fsSL -o /tmp/obscura.tar.gz \ + https://github.com/h4ckf0r0day/obscura/releases/latest/download/obscura-aarch64-macos.tar.gz +tar -xzf /tmp/obscura.tar.gz -C /tmp && sudo mv /tmp/obscura /usr/local/bin/ + +# Linux x86_64 +curl -fsSL -o /tmp/obscura.tar.gz \ + https://github.com/h4ckf0r0day/obscura/releases/latest/download/obscura-x86_64-linux.tar.gz +tar -xzf /tmp/obscura.tar.gz -C /tmp && sudo mv /tmp/obscura /usr/local/bin/ + +# Source (Rust 1.75+) +cargo install --git https://github.com/h4ckf0r0day/obscura + +# Vérifier +obscura --version +``` + +Activation ulk : `./install.sh --with-obscura` (ou installé automatiquement en base — voir `priority: required`). + +## Commandes Clés + +### `obscura fetch` — page unique + +```bash +# Page brute (HTML après rendu JS) +obscura fetch https://example.com + +# Extraction JS (résultat sur stdout) +obscura fetch https://example.com --eval "document.title" + +# Extraction structurée (JSON multi-champs) +obscura fetch https://example.com --eval "JSON.stringify({ + title: document.title, + h1: [...document.querySelectorAll('h1')].map(h => h.textContent.trim()), + description: document.querySelector('meta[name=description]')?.content, + canonical: document.querySelector('link[rel=canonical]')?.href, + wordCount: document.body.innerText.split(/\s+/).filter(Boolean).length +})" + +# Dump du DOM rendu d'un sélecteur (article, .content, etc.) +obscura fetch https://example.com --selector ".article" --dump + +# Attendre networkidle puis extraire +obscura fetch https://example.com --wait-until networkidle --timeout 10000 \ + --eval "document.querySelectorAll('a').length" + +# Stealth (anti-fingerprinting) +obscura fetch https://example.com --stealth --eval "navigator.webdriver" +``` + +### `obscura scrape` — multi-URL parallèle + +```bash +# urls.txt = une URL par ligne +obscura scrape urls.txt \ + --concurrency 8 \ + --eval "JSON.stringify({ url: location.href, title: document.title, h1: document.querySelector('h1')?.textContent })" \ + --format json > results.json + +# CSV pour ingestion tableur +obscura scrape urls.txt --concurrency 4 --eval "document.title" --format csv > titles.csv +``` + +> Avantage net sur `shot-scraper multi` : workers Rust natifs (`obscura-worker`), pas de fork Python par URL → débit 5-10× supérieur sur des batches > 20 URLs. + +### `obscura serve` — serveur CDP + +```bash +# Démarrer le serveur CDP (port 9222 par défaut) +obscura serve --port 9222 --stealth --workers 4 + +# Avec proxy upstream +obscura serve --port 9222 --proxy http://127.0.0.1:8080 +``` + +Un client Puppeteer/Playwright peut alors se connecter via CDP : +```javascript +const browser = await puppeteer.connect({ browserURL: 'http://localhost:9222' }); +``` + +--- + +## Patterns ulk fréquents + +### Audit SEO (titres, descriptions, canonicals) +```bash +obscura fetch "$URL" --eval "JSON.stringify({ + title: document.title, + description: document.querySelector('meta[name=description]')?.content, + canonical: document.querySelector('link[rel=canonical]')?.href, + ogTitle: document.querySelector('meta[property=\"og:title\"]')?.content, + ogImage: document.querySelector('meta[property=\"og:image\"]')?.content, + jsonLd: [...document.querySelectorAll('script[type=\"application/ld+json\"]')].map(s => s.textContent) +})" > "docs/audits/seo-$DATE.json" +``` + +### Audit images sans alt +```bash +obscura fetch "$URL" --eval "JSON.stringify( + [...document.querySelectorAll('img')] + .filter(i => !i.alt || i.alt.trim() === '') + .map(i => ({ src: i.src, parent: i.parentElement?.tagName })) +)" +``` + +### Liens cassés (extraction + check externe) +```bash +obscura fetch "$URL" --eval "JSON.stringify( + [...document.querySelectorAll('a[href]')].map(a => a.href) +)" | jq -r '.[]' | sort -u | xargs -P 8 -I {} curl -sI -o /dev/null -w "%{http_code} {}\n" {} +``` + +### Crawl + extraction (visual-auditor URL list) +```bash +# 1. Extraire les URLs internes depuis sitemap +obscura fetch "$BASE/sitemap.xml" --eval "[...document.querySelectorAll('loc')].map(l => l.textContent).join('\n')" > urls.txt + +# 2. Scraper en parallèle +obscura scrape urls.txt --concurrency 8 \ + --eval "JSON.stringify({ url: location.href, title: document.title })" \ + --format json > pages.json +``` + +--- + +## Limitations + +- **Screenshots** : Obscura sait rendre la page (V8) mais shot-scraper reste la voie canonique pour les fichiers PNG/PDF (workflow + presets viewport éprouvés). +- **Arbre d'accessibilité** : pas d'équivalent à `shot-scraper accessibility` — utiliser shot-scraper. +- **Console / Network monitoring** : pas de capture native. Utiliser `obscura serve` + client CDP pour un contrôle fin, ou Lighthouse pour les Core Web Vitals. +- **Auth interactive** : pas d'équivalent direct à `shot-scraper auth`. Workaround : démarrer `obscura serve --stealth` et piloter via Puppeteer/Playwright. + +--- + +## Règle agents ulk + +Tout agent qui faisait `shot-scraper javascript URL "…"`, `shot-scraper multi shots.yml` (sans screenshots) ou avait besoin d'un serveur CDP **doit** : + +1. Garder `Bash` dans `tools:` +2. Ajouter `extends: _shared/obscura-protocol.md` (en plus de `shot-scraper-protocol.md` si screenshots conservés) +3. Remplacer : + - `shot-scraper javascript URL "JS"` → `obscura fetch URL --eval "JS"` + - `shot-scraper multi shots.yml` (sans screenshots) → `obscura scrape urls.txt --eval "JS"` +4. **Conserver** `shot-scraper` pour : screenshots, PDF, accessibility tree, auth. + +Agents directement concernés : **visual-auditor (03)**, **frontend-qa (02)**, **seo-auditor (32)**, **agamotto (17)**. + +## Fallback si Obscura absent + +Si `obscura` n'est pas dans le `PATH`, l'agent doit tomber sur shot-scraper avec un avertissement explicite : + +```bash +if command -v obscura >/dev/null 2>&1; then + obscura fetch "$URL" --eval "$JS" +else + echo "⚠️ obscura absent — fallback shot-scraper (4-6× plus lent sur multi-URL)" >&2 + shot-scraper javascript "$URL" "$JS" +fi +``` diff --git a/framework/agents/audit/32-seo-auditor.md b/framework/agents/audit/32-seo-auditor.md index 0cdfd73..475f1eb 100644 --- a/framework/agents/audit/32-seo-auditor.md +++ b/framework/agents/audit/32-seo-auditor.md @@ -12,6 +12,7 @@ extends: - _shared/auditor-base.md - _shared/checklists/seo-report-template.md - _shared/shot-scraper-protocol.md + - _shared/obscura-protocol.md --- # Agent SEO & GEO Auditor @@ -250,10 +251,10 @@ find . -path "*/locales/*" -o -path "*/i18n/*" -o -path "*/translations/*" 2>/de ### 3.1 - ANALYSE DU CONTENU -Si URL de production disponible, utiliser shot-scraper javascript : +Si URL de production disponible, utiliser **Obscura** (extraction donnée — démarrage 4-6× plus rapide que shot-scraper, idéal pour multi-URL via `obscura scrape`) : ```bash -shot-scraper javascript "$URL" "JSON.stringify( +obscura fetch "$URL" --eval "JSON.stringify( (function() { const h1 = document.querySelectorAll('h1'); const title = document.title; diff --git a/framework/agents/docs/17-agamotto.md b/framework/agents/docs/17-agamotto.md index bcb7639..eb6eae3 100644 --- a/framework/agents/docs/17-agamotto.md +++ b/framework/agents/docs/17-agamotto.md @@ -15,6 +15,7 @@ extends: - _shared/design-source-protocol.md - _shared/update-protocol.md - _shared/shot-scraper-protocol.md + - _shared/obscura-protocol.md context_budget: 14000 loads_files: docs/design.md, docs/design-wireframe/_index.md loads_skills: figma-use, figma-implement-design @@ -161,14 +162,14 @@ Demarrage de l'analyse... → Capture visuelle globale ``` -#### Penpot (via shot-scraper) +#### Penpot (capture via shot-scraper, extraction via Obscura) ```bash -# 1. Capture generale du fichier Penpot +# 1. Capture generale du fichier Penpot (visuel → shot-scraper) shot-scraper "$PENPOT_URL" -o penpot-capture.png --width 1920 --height 1080 -# 2. Extraire les donnees via l'API Penpot -shot-scraper javascript "$PENPOT_URL" "JSON.stringify( +# 2. Extraire les donnees via l'API Penpot (JS eval → Obscura, ~5× plus rapide) +obscura fetch "$PENPOT_URL" --eval "JSON.stringify( window.app?.main?.store?.state ?? 'Penpot state non accessible' )" ``` diff --git a/framework/agents/frontend/02-frontend-qa.md b/framework/agents/frontend/02-frontend-qa.md index 3b9031e..5df2b0f 100644 --- a/framework/agents/frontend/02-frontend-qa.md +++ b/framework/agents/frontend/02-frontend-qa.md @@ -16,6 +16,7 @@ extends: - _shared/stack-detection.md - _shared/auditor-base.md - _shared/shot-scraper-protocol.md + - _shared/obscura-protocol.md --- # Frontend QA Agent @@ -223,8 +224,8 @@ DATE=$(date +%Y%m%d) # 1. Screenshot desktop full page shot-scraper "$URL" -o "docs/audits/assets/desktop-$DATE.png" --width 1440 --height 900 --full-page -# 2. Analyser structure DOM (headings, CTAs, forms) -shot-scraper javascript "$URL" "JSON.stringify({ +# 2. Analyser structure DOM (headings, CTAs, forms) — via Obscura (JS eval, ~5× plus rapide que shot-scraper) +obscura fetch "$URL" --eval "JSON.stringify({ h1: [...document.querySelectorAll('h1')].map(h => h.textContent.trim()), ctas: [...document.querySelectorAll('a[href], button')].map(b => b.textContent.trim()).filter(t => t).slice(0, 20), forms: document.querySelectorAll('form').length, @@ -444,4 +445,4 @@ npx vite-bundle-visualizer - Focus on **actionable** recommendations - Group related issues for easier remediation - Consider framework-specific best practices -- Landing mode requires shot-scraper (`pip install shot-scraper && shot-scraper install`) for screenshots and DOM analysis +- Landing mode requires shot-scraper (`pip install shot-scraper && shot-scraper install`) for screenshots, et obscura (`./install.sh --with-obscura`) pour l'analyse DOM/JS eval (depuis 2026-05-07). Voir `_shared/obscura-protocol.md` pour la matrice de décision. diff --git a/framework/agents/frontend/03-visual-auditor.md b/framework/agents/frontend/03-visual-auditor.md index 74aadb5..cca507e 100644 --- a/framework/agents/frontend/03-visual-auditor.md +++ b/framework/agents/frontend/03-visual-auditor.md @@ -1,7 +1,7 @@ --- name: visual-auditor type: custom-command -description: Audit visuel complet via shot-scraper CLI - screenshots multi-viewport comparatifs, analyse DOM/CSS, arbre d'accessibilité, performance visuelle (LCP/CLS/FCP). Supporte URL unique, liste URLs, ou projet local. +description: Audit visuel complet via shot-scraper (screenshots, PDF, a11y) + Obscura (JS eval, scraping multi-URL, CDP) - screenshots multi-viewport comparatifs, analyse DOM/CSS, arbre d'accessibilité, performance visuelle (LCP/CLS/FCP). Supporte URL unique, liste URLs, ou projet local. tools: Task, Read, Write, Bash, Glob, AskUserQuestionTool model: sonnet phase: verify @@ -12,6 +12,7 @@ extends: - _shared/auditor-base.md - _shared/design-source-protocol.md - _shared/shot-scraper-protocol.md + - _shared/obscura-protocol.md context_budget: 10000 loads_files: docs/design.md, docs/design-wireframe/_index.md mcp_cap_strategy: summarize @@ -20,11 +21,15 @@ mcp_cap_threshold: 4000 # Visual Auditor - Agent d'Audit Visuel -> "Une image vaut mille lignes de code" - Audit visuel complet via shot-scraper CLI. +> "Une image vaut mille lignes de code" - Audit visuel via shot-scraper (rendu visuel) + Obscura (extraction donnée). -> **Références** : `_shared/base-rules.md` · `_shared/auditor-base.md` · `_shared/shot-scraper-protocol.md` +> **Références** : `_shared/base-rules.md` · `_shared/auditor-base.md` · `_shared/shot-scraper-protocol.md` · `_shared/obscura-protocol.md` -Vous etes Visual Auditor, un agent specialise dans l'audit visuel de sites web et applications. Vous utilisez shot-scraper CLI pour capturer, analyser et comparer l'etat visuel des pages. +Vous etes Visual Auditor, un agent specialise dans l'audit visuel de sites web et applications. Vous utilisez **deux CLIs complémentaires** : +- **shot-scraper** pour les captures (screenshots PNG/PDF, arbre d'accessibilité, auth interactive) +- **Obscura** pour l'extraction de données (JS eval, scraping multi-URL parallèle, CDP) + +Règle simple : *shot-scraper pour ce qui est visuel, Obscura pour ce qui est donnée*. Voir `_shared/obscura-protocol.md` pour la matrice de décision complète. ## Mission @@ -41,7 +46,7 @@ Realiser un audit visuel complet comprenant : ## Prerequis -shot-scraper doit etre installe : +**shot-scraper** (captures visuelles, a11y) : ```bash pip install shot-scraper @@ -49,6 +54,19 @@ shot-scraper install # telecharge le navigateur Playwright shot-scraper --version # verifier ``` +**Obscura** (JS eval, scraping multi-URL, CDP) — adopté en base ulk depuis 2026-05-07 : + +```bash +# Activation ulk (recommandé) +./install.sh --with-obscura + +# Ou installation manuelle (binaire releases) +curl -fsSL -o /tmp/obscura.tar.gz \ + https://github.com/h4ckf0r0day/obscura/releases/latest/download/obscura-x86_64-linux.tar.gz +tar -xzf /tmp/obscura.tar.gz -C /tmp && sudo mv /tmp/obscura /usr/local/bin/ +obscura --version # verifier +``` + --- ## Phase 0 : Detection du Mode @@ -226,10 +244,10 @@ print('TBT:', audits['total-blocking-time']['displayValue']) " ``` -Ou via shot-scraper javascript (performance timing basique) : +Ou via Obscura (performance timing basique, démarrage 4-6× plus rapide que shot-scraper) : ```bash -shot-scraper javascript "$URL" "JSON.stringify( +obscura fetch "$URL" --eval "JSON.stringify( performance.getEntriesByType('navigation').map(e => ({ domInteractive: Math.round(e.domInteractive), loadEventEnd: Math.round(e.loadEventEnd), @@ -255,7 +273,7 @@ shot-scraper javascript "$URL" "JSON.stringify( ```bash # Erreurs post-chargement -shot-scraper javascript "$URL" "JSON.stringify( +obscura fetch "$URL" --eval "JSON.stringify( (function() { const errors = []; window.onerror = (msg, src, line) => errors.push({type: 'error', msg, src, line}); @@ -269,14 +287,14 @@ shot-scraper javascript "$URL" "JSON.stringify( ```bash # Images cassees -shot-scraper javascript "$URL" "JSON.stringify( +obscura fetch "$URL" --eval "JSON.stringify( [...document.querySelectorAll('img')] .filter(i => !i.complete || i.naturalWidth === 0) .map(i => ({src: i.src, alt: i.alt})) )" # Toutes les ressources liees -shot-scraper javascript "$URL" "JSON.stringify( +obscura fetch "$URL" --eval "JSON.stringify( [...document.querySelectorAll('img, link[rel=stylesheet], script[src]')] .map(el => el.src || el.href) .filter(Boolean) @@ -289,11 +307,11 @@ shot-scraper javascript "$URL" "JSON.stringify( ## Phase 5 : Analyse DOM/CSS -### 5.1 - Verifications automatiques via shot-scraper javascript +### 5.1 - Verifications automatiques via Obscura (`obscura fetch --eval`) ```bash # Verifier coherence espacements -shot-scraper javascript "$URL" "JSON.stringify( +obscura fetch "$URL" --eval "JSON.stringify( (function() { const margins = [...document.querySelectorAll('*')] .map(el => getComputedStyle(el).marginBottom) @@ -306,7 +324,7 @@ shot-scraper javascript "$URL" "JSON.stringify( )" # Verifier z-index excessifs -shot-scraper javascript "$URL" "JSON.stringify( +obscura fetch "$URL" --eval "JSON.stringify( [...document.querySelectorAll('*')] .map(el => ({tag: el.tagName + (el.className ? '.' + el.className.split(' ')[0] : ''), z: getComputedStyle(el).zIndex})) .filter(o => o.z !== 'auto' && parseInt(o.z) > 1000) @@ -314,12 +332,12 @@ shot-scraper javascript "$URL" "JSON.stringify( )" # Verifier fonts -shot-scraper javascript "$URL" "JSON.stringify( +obscura fetch "$URL" --eval "JSON.stringify( [...new Set([...document.querySelectorAll('*')].map(el => getComputedStyle(el).fontFamily))].slice(0, 15) )" # Verifier couleurs -shot-scraper javascript "$URL" "JSON.stringify( +obscura fetch "$URL" --eval "JSON.stringify( [...new Set([...document.querySelectorAll('*')].map(el => getComputedStyle(el).color))].slice(0, 20) )" ``` @@ -531,7 +549,8 @@ https://example.com/ https://example.com/about https://example.com/contact -→ Audit de chaque URL via shot-scraper multi +→ Captures (screenshots, a11y) via shot-scraper multi +→ Extraction JS / scraping parallèle via obscura scrape (~5-10× plus rapide sur batches > 20 URLs) → Rapport consolide ``` @@ -602,7 +621,7 @@ Prompt: "Audit visuel complementaire. Focus: mobile responsive, performance visu ### shot-scraper non disponible ``` -❌ shot-scraper non installe +❌ shot-scraper non installe (requis pour screenshots, PDF, accessibility) Verifiez que : 1. Python est installe (python3 --version) @@ -613,6 +632,24 @@ Commande de diagnostic : shot-scraper --version ``` +### obscura non disponible + +``` +❌ obscura non installe (requis pour JS eval, scraping multi-URL, CDP) + +Activation ulk : ./install.sh --with-obscura +Manuel : curl -fsSL -o /tmp/obscura.tar.gz \ + https://github.com/h4ckf0r0day/obscura/releases/latest/download/obscura-x86_64-linux.tar.gz \ + && tar -xzf /tmp/obscura.tar.gz -C /tmp \ + && sudo mv /tmp/obscura /usr/local/bin/ + +Fallback : si Obscura absent, tomber sur shot-scraper javascript +(4-6× plus lent sur multi-URL — voir _shared/obscura-protocol.md). + +Commande de diagnostic : +obscura --version +``` + ### Timeout de page ``` @@ -696,7 +733,8 @@ Si une carte wireframe (`docs/design-wireframe//CARD.md`) correspond a la 3. **TOUJOURS** generer un rapport meme si erreurs partielles 4. **JAMAIS** ecraser baseline sans confirmation explicite 5. **JAMAIS** ignorer les erreurs JS detectees -6. **JAMAIS** continuer si shot-scraper non installe (verifier avec `shot-scraper --version`) +6. **JAMAIS** continuer si shot-scraper non installe (verifier avec `shot-scraper --version`) — requis pour screenshots/PDF/a11y +7. **Avertir mais continuer** si obscura absent — tomber sur shot-scraper javascript (4-6× plus lent, voir `_shared/obscura-protocol.md`) 7. **TOUJOURS** rebouclier les findings dans `docs/design.md` (si present) — section `## Audit findings` + `## Changelog`. Voir `_shared/design-source-protocol.md`. --- diff --git a/framework/agents/registry.json b/framework/agents/registry.json index 9acafc1..a1ac3e1 100644 --- a/framework/agents/registry.json +++ b/framework/agents/registry.json @@ -2159,7 +2159,7 @@ "category": "frontend", "model": "sonnet", "phase": "verify", - "description": "Audit visuel complet via shot-scraper CLI - screenshots multi-viewport comparatifs, analyse DOM/CSS, arbre d'accessibilité, performance visuelle (LCP/CLS/FCP). Supporte URL unique, liste URLs, ou projet local.", + "description": "Audit visuel complet via shot-scraper (screenshots, PDF, a11y) + Obscura (JS eval, scraping multi-URL, CDP) - screenshots multi-viewport comparatifs, analyse DOM/CSS, arbre d'accessibilité, performance visuelle (LCP/CLS/FCP). Supporte URL unique, liste URLs, ou projet local.", "tools": [ "Task", "Read", diff --git a/framework/agents/registry.md b/framework/agents/registry.md index baa0113..9b52af1 100644 --- a/framework/agents/registry.md +++ b/framework/agents/registry.md @@ -142,7 +142,7 @@ Prompt: "Read [agent.file] then follow its instructions. | `/ulk:frontend:shadcn-migrator` | sonnet | 🔍review | Audit et plan de migration shadcn/ui. Analyse le code source (composants, pag... | | `/ulk:stark` | **opus**·xhigh | 💡define | Stark — Designer en chef. Transforme un brief de marque, une URL, des screens... | | `/ulk:frontend:svg-analyzer` | sonnet | 🔨build | Analyse exhaustive d'un projet React/Next.js - identifie pages, layouts et co... | -| `/ulk:frontend:visual-auditor` | sonnet | ✅verify | Audit visuel complet via shot-scraper CLI - screenshots multi-viewport compar... | +| `/ulk:frontend:visual-auditor` | sonnet | ✅verify | Audit visuel complet via shot-scraper (screenshots, PDF, a11y) + Obscura (JS ... | ## VPS (vps/) diff --git a/framework/cli/internal/installer/catalog.go b/framework/cli/internal/installer/catalog.go index 591da6d..a758ae7 100644 --- a/framework/cli/internal/installer/catalog.go +++ b/framework/cli/internal/installer/catalog.go @@ -154,6 +154,12 @@ var All = []Installable{ runCmd: []string{"sh", "-c", "pip3 install shot-scraper && shot-scraper install"}, message: "pip3 requis : brew install python3 (macOS) · apt install python3-pip (Linux)", }, + &ExternalModule{ + base: base{key: "obscura", flag: "--with-obscura", label: "obscura", description: "headless browser Rust — scraping JS, multi-URL parallèle, CDP (required, coexiste avec shot-scraper)", category: "tools"}, + dep: "curl", + runCmd: []string{"sh", "-c", "OS=$(uname -s); ARCH=$(uname -m); case \"$OS-$ARCH\" in Darwin-arm64) ASSET=obscura-aarch64-macos.tar.gz ;; Darwin-x86_64) ASSET=obscura-x86_64-macos.tar.gz ;; Linux-x86_64) ASSET=obscura-x86_64-linux.tar.gz ;; *) echo \"obscura: plateforme non supportée ($OS-$ARCH) — fallback cargo\" >&2; cargo install --git https://github.com/h4ckf0r0day/obscura && exit 0 ;; esac; curl -fsSL -o /tmp/obscura.tar.gz \"https://github.com/h4ckf0r0day/obscura/releases/latest/download/$ASSET\" && tar -xzf /tmp/obscura.tar.gz -C /tmp && sudo mv /tmp/obscura /usr/local/bin/ && rm -f /tmp/obscura.tar.gz && obscura --version"}, + message: "curl requis (préinstallé sur macOS/Linux). Fallback : cargo install --git https://github.com/h4ckf0r0day/obscura (Rust 1.75+).", + }, &NoopModule{ base: base{key: "faru", flag: "--with-faru", label: "faru", description: "kanban git-natif agent-first — crée docs/backlog/ (installe faru manuellement : npm install -g faru)", category: "tools"}, }, diff --git a/framework/commands/agents/agamotto.md b/framework/commands/agents/agamotto.md index bcb7639..eb6eae3 100644 --- a/framework/commands/agents/agamotto.md +++ b/framework/commands/agents/agamotto.md @@ -15,6 +15,7 @@ extends: - _shared/design-source-protocol.md - _shared/update-protocol.md - _shared/shot-scraper-protocol.md + - _shared/obscura-protocol.md context_budget: 14000 loads_files: docs/design.md, docs/design-wireframe/_index.md loads_skills: figma-use, figma-implement-design @@ -161,14 +162,14 @@ Demarrage de l'analyse... → Capture visuelle globale ``` -#### Penpot (via shot-scraper) +#### Penpot (capture via shot-scraper, extraction via Obscura) ```bash -# 1. Capture generale du fichier Penpot +# 1. Capture generale du fichier Penpot (visuel → shot-scraper) shot-scraper "$PENPOT_URL" -o penpot-capture.png --width 1920 --height 1080 -# 2. Extraire les donnees via l'API Penpot -shot-scraper javascript "$PENPOT_URL" "JSON.stringify( +# 2. Extraire les donnees via l'API Penpot (JS eval → Obscura, ~5× plus rapide) +obscura fetch "$PENPOT_URL" --eval "JSON.stringify( window.app?.main?.store?.state ?? 'Penpot state non accessible' )" ``` diff --git a/framework/commands/agents/seo-auditor.md b/framework/commands/agents/seo-auditor.md index 0cdfd73..475f1eb 100644 --- a/framework/commands/agents/seo-auditor.md +++ b/framework/commands/agents/seo-auditor.md @@ -12,6 +12,7 @@ extends: - _shared/auditor-base.md - _shared/checklists/seo-report-template.md - _shared/shot-scraper-protocol.md + - _shared/obscura-protocol.md --- # Agent SEO & GEO Auditor @@ -250,10 +251,10 @@ find . -path "*/locales/*" -o -path "*/i18n/*" -o -path "*/translations/*" 2>/de ### 3.1 - ANALYSE DU CONTENU -Si URL de production disponible, utiliser shot-scraper javascript : +Si URL de production disponible, utiliser **Obscura** (extraction donnée — démarrage 4-6× plus rapide que shot-scraper, idéal pour multi-URL via `obscura scrape`) : ```bash -shot-scraper javascript "$URL" "JSON.stringify( +obscura fetch "$URL" --eval "JSON.stringify( (function() { const h1 = document.querySelectorAll('h1'); const title = document.title; diff --git a/framework/commands/frontend/frontend-qa.md b/framework/commands/frontend/frontend-qa.md index 3b9031e..5df2b0f 100644 --- a/framework/commands/frontend/frontend-qa.md +++ b/framework/commands/frontend/frontend-qa.md @@ -16,6 +16,7 @@ extends: - _shared/stack-detection.md - _shared/auditor-base.md - _shared/shot-scraper-protocol.md + - _shared/obscura-protocol.md --- # Frontend QA Agent @@ -223,8 +224,8 @@ DATE=$(date +%Y%m%d) # 1. Screenshot desktop full page shot-scraper "$URL" -o "docs/audits/assets/desktop-$DATE.png" --width 1440 --height 900 --full-page -# 2. Analyser structure DOM (headings, CTAs, forms) -shot-scraper javascript "$URL" "JSON.stringify({ +# 2. Analyser structure DOM (headings, CTAs, forms) — via Obscura (JS eval, ~5× plus rapide que shot-scraper) +obscura fetch "$URL" --eval "JSON.stringify({ h1: [...document.querySelectorAll('h1')].map(h => h.textContent.trim()), ctas: [...document.querySelectorAll('a[href], button')].map(b => b.textContent.trim()).filter(t => t).slice(0, 20), forms: document.querySelectorAll('form').length, @@ -444,4 +445,4 @@ npx vite-bundle-visualizer - Focus on **actionable** recommendations - Group related issues for easier remediation - Consider framework-specific best practices -- Landing mode requires shot-scraper (`pip install shot-scraper && shot-scraper install`) for screenshots and DOM analysis +- Landing mode requires shot-scraper (`pip install shot-scraper && shot-scraper install`) for screenshots, et obscura (`./install.sh --with-obscura`) pour l'analyse DOM/JS eval (depuis 2026-05-07). Voir `_shared/obscura-protocol.md` pour la matrice de décision. diff --git a/framework/commands/frontend/visual-auditor.md b/framework/commands/frontend/visual-auditor.md index 74aadb5..cca507e 100644 --- a/framework/commands/frontend/visual-auditor.md +++ b/framework/commands/frontend/visual-auditor.md @@ -1,7 +1,7 @@ --- name: visual-auditor type: custom-command -description: Audit visuel complet via shot-scraper CLI - screenshots multi-viewport comparatifs, analyse DOM/CSS, arbre d'accessibilité, performance visuelle (LCP/CLS/FCP). Supporte URL unique, liste URLs, ou projet local. +description: Audit visuel complet via shot-scraper (screenshots, PDF, a11y) + Obscura (JS eval, scraping multi-URL, CDP) - screenshots multi-viewport comparatifs, analyse DOM/CSS, arbre d'accessibilité, performance visuelle (LCP/CLS/FCP). Supporte URL unique, liste URLs, ou projet local. tools: Task, Read, Write, Bash, Glob, AskUserQuestionTool model: sonnet phase: verify @@ -12,6 +12,7 @@ extends: - _shared/auditor-base.md - _shared/design-source-protocol.md - _shared/shot-scraper-protocol.md + - _shared/obscura-protocol.md context_budget: 10000 loads_files: docs/design.md, docs/design-wireframe/_index.md mcp_cap_strategy: summarize @@ -20,11 +21,15 @@ mcp_cap_threshold: 4000 # Visual Auditor - Agent d'Audit Visuel -> "Une image vaut mille lignes de code" - Audit visuel complet via shot-scraper CLI. +> "Une image vaut mille lignes de code" - Audit visuel via shot-scraper (rendu visuel) + Obscura (extraction donnée). -> **Références** : `_shared/base-rules.md` · `_shared/auditor-base.md` · `_shared/shot-scraper-protocol.md` +> **Références** : `_shared/base-rules.md` · `_shared/auditor-base.md` · `_shared/shot-scraper-protocol.md` · `_shared/obscura-protocol.md` -Vous etes Visual Auditor, un agent specialise dans l'audit visuel de sites web et applications. Vous utilisez shot-scraper CLI pour capturer, analyser et comparer l'etat visuel des pages. +Vous etes Visual Auditor, un agent specialise dans l'audit visuel de sites web et applications. Vous utilisez **deux CLIs complémentaires** : +- **shot-scraper** pour les captures (screenshots PNG/PDF, arbre d'accessibilité, auth interactive) +- **Obscura** pour l'extraction de données (JS eval, scraping multi-URL parallèle, CDP) + +Règle simple : *shot-scraper pour ce qui est visuel, Obscura pour ce qui est donnée*. Voir `_shared/obscura-protocol.md` pour la matrice de décision complète. ## Mission @@ -41,7 +46,7 @@ Realiser un audit visuel complet comprenant : ## Prerequis -shot-scraper doit etre installe : +**shot-scraper** (captures visuelles, a11y) : ```bash pip install shot-scraper @@ -49,6 +54,19 @@ shot-scraper install # telecharge le navigateur Playwright shot-scraper --version # verifier ``` +**Obscura** (JS eval, scraping multi-URL, CDP) — adopté en base ulk depuis 2026-05-07 : + +```bash +# Activation ulk (recommandé) +./install.sh --with-obscura + +# Ou installation manuelle (binaire releases) +curl -fsSL -o /tmp/obscura.tar.gz \ + https://github.com/h4ckf0r0day/obscura/releases/latest/download/obscura-x86_64-linux.tar.gz +tar -xzf /tmp/obscura.tar.gz -C /tmp && sudo mv /tmp/obscura /usr/local/bin/ +obscura --version # verifier +``` + --- ## Phase 0 : Detection du Mode @@ -226,10 +244,10 @@ print('TBT:', audits['total-blocking-time']['displayValue']) " ``` -Ou via shot-scraper javascript (performance timing basique) : +Ou via Obscura (performance timing basique, démarrage 4-6× plus rapide que shot-scraper) : ```bash -shot-scraper javascript "$URL" "JSON.stringify( +obscura fetch "$URL" --eval "JSON.stringify( performance.getEntriesByType('navigation').map(e => ({ domInteractive: Math.round(e.domInteractive), loadEventEnd: Math.round(e.loadEventEnd), @@ -255,7 +273,7 @@ shot-scraper javascript "$URL" "JSON.stringify( ```bash # Erreurs post-chargement -shot-scraper javascript "$URL" "JSON.stringify( +obscura fetch "$URL" --eval "JSON.stringify( (function() { const errors = []; window.onerror = (msg, src, line) => errors.push({type: 'error', msg, src, line}); @@ -269,14 +287,14 @@ shot-scraper javascript "$URL" "JSON.stringify( ```bash # Images cassees -shot-scraper javascript "$URL" "JSON.stringify( +obscura fetch "$URL" --eval "JSON.stringify( [...document.querySelectorAll('img')] .filter(i => !i.complete || i.naturalWidth === 0) .map(i => ({src: i.src, alt: i.alt})) )" # Toutes les ressources liees -shot-scraper javascript "$URL" "JSON.stringify( +obscura fetch "$URL" --eval "JSON.stringify( [...document.querySelectorAll('img, link[rel=stylesheet], script[src]')] .map(el => el.src || el.href) .filter(Boolean) @@ -289,11 +307,11 @@ shot-scraper javascript "$URL" "JSON.stringify( ## Phase 5 : Analyse DOM/CSS -### 5.1 - Verifications automatiques via shot-scraper javascript +### 5.1 - Verifications automatiques via Obscura (`obscura fetch --eval`) ```bash # Verifier coherence espacements -shot-scraper javascript "$URL" "JSON.stringify( +obscura fetch "$URL" --eval "JSON.stringify( (function() { const margins = [...document.querySelectorAll('*')] .map(el => getComputedStyle(el).marginBottom) @@ -306,7 +324,7 @@ shot-scraper javascript "$URL" "JSON.stringify( )" # Verifier z-index excessifs -shot-scraper javascript "$URL" "JSON.stringify( +obscura fetch "$URL" --eval "JSON.stringify( [...document.querySelectorAll('*')] .map(el => ({tag: el.tagName + (el.className ? '.' + el.className.split(' ')[0] : ''), z: getComputedStyle(el).zIndex})) .filter(o => o.z !== 'auto' && parseInt(o.z) > 1000) @@ -314,12 +332,12 @@ shot-scraper javascript "$URL" "JSON.stringify( )" # Verifier fonts -shot-scraper javascript "$URL" "JSON.stringify( +obscura fetch "$URL" --eval "JSON.stringify( [...new Set([...document.querySelectorAll('*')].map(el => getComputedStyle(el).fontFamily))].slice(0, 15) )" # Verifier couleurs -shot-scraper javascript "$URL" "JSON.stringify( +obscura fetch "$URL" --eval "JSON.stringify( [...new Set([...document.querySelectorAll('*')].map(el => getComputedStyle(el).color))].slice(0, 20) )" ``` @@ -531,7 +549,8 @@ https://example.com/ https://example.com/about https://example.com/contact -→ Audit de chaque URL via shot-scraper multi +→ Captures (screenshots, a11y) via shot-scraper multi +→ Extraction JS / scraping parallèle via obscura scrape (~5-10× plus rapide sur batches > 20 URLs) → Rapport consolide ``` @@ -602,7 +621,7 @@ Prompt: "Audit visuel complementaire. Focus: mobile responsive, performance visu ### shot-scraper non disponible ``` -❌ shot-scraper non installe +❌ shot-scraper non installe (requis pour screenshots, PDF, accessibility) Verifiez que : 1. Python est installe (python3 --version) @@ -613,6 +632,24 @@ Commande de diagnostic : shot-scraper --version ``` +### obscura non disponible + +``` +❌ obscura non installe (requis pour JS eval, scraping multi-URL, CDP) + +Activation ulk : ./install.sh --with-obscura +Manuel : curl -fsSL -o /tmp/obscura.tar.gz \ + https://github.com/h4ckf0r0day/obscura/releases/latest/download/obscura-x86_64-linux.tar.gz \ + && tar -xzf /tmp/obscura.tar.gz -C /tmp \ + && sudo mv /tmp/obscura /usr/local/bin/ + +Fallback : si Obscura absent, tomber sur shot-scraper javascript +(4-6× plus lent sur multi-URL — voir _shared/obscura-protocol.md). + +Commande de diagnostic : +obscura --version +``` + ### Timeout de page ``` @@ -696,7 +733,8 @@ Si une carte wireframe (`docs/design-wireframe//CARD.md`) correspond a la 3. **TOUJOURS** generer un rapport meme si erreurs partielles 4. **JAMAIS** ecraser baseline sans confirmation explicite 5. **JAMAIS** ignorer les erreurs JS detectees -6. **JAMAIS** continuer si shot-scraper non installe (verifier avec `shot-scraper --version`) +6. **JAMAIS** continuer si shot-scraper non installe (verifier avec `shot-scraper --version`) — requis pour screenshots/PDF/a11y +7. **Avertir mais continuer** si obscura absent — tomber sur shot-scraper javascript (4-6× plus lent, voir `_shared/obscura-protocol.md`) 7. **TOUJOURS** rebouclier les findings dans `docs/design.md` (si present) — section `## Audit findings` + `## Changelog`. Voir `_shared/design-source-protocol.md`. --- diff --git a/framework/tests/agents/agathe.golden.md b/framework/tests/agents/agathe.golden.md index 5bd4029..dd3996a 100644 --- a/framework/tests/agents/agathe.golden.md +++ b/framework/tests/agents/agathe.golden.md @@ -5,7 +5,7 @@ description: Régression structurelle de la DA garante du design system ulk expect_name: agathe expect_type: custom-command -expect_model: sonnet +expect_model: opus required_sections: - "Personnalité" diff --git a/framework/tests/agents/alex.golden.md b/framework/tests/agents/alex.golden.md index bc79ca0..08e3056 100644 --- a/framework/tests/agents/alex.golden.md +++ b/framework/tests/agents/alex.golden.md @@ -5,7 +5,7 @@ description: Régression structurelle du conseiller-auditeur musitech ulk expect_name: alex expect_type: custom-command -expect_model: opus +expect_model: sonnet required_sections: - "Personnalité" diff --git a/framework/tests/agents/benjamin.golden.md b/framework/tests/agents/benjamin.golden.md index 28a76cf..e12a2a1 100644 --- a/framework/tests/agents/benjamin.golden.md +++ b/framework/tests/agents/benjamin.golden.md @@ -5,7 +5,7 @@ description: Régression structurelle de l'agent devil's advocate expect_name: benjamin expect_type: custom-command -expect_model: sonnet +expect_model: opus required_sections: - "Personnalité" diff --git a/framework/tests/agents/frontend-orchestrateur.golden.md b/framework/tests/agents/frontend-orchestrateur.golden.md index e8d6323..d9d82d5 100644 --- a/framework/tests/agents/frontend-orchestrateur.golden.md +++ b/framework/tests/agents/frontend-orchestrateur.golden.md @@ -5,7 +5,7 @@ description: Régression structurelle de frontend-orchestrateur expect_name: frontend-orchestrateur expect_type: custom-command -expect_model: sonnet +expect_model: opus required_sections: - "Bundle Frontend (mode=bundle)" diff --git a/framework/tests/agents/gandalf.golden.md b/framework/tests/agents/gandalf.golden.md index fefafa3..bcad481 100644 --- a/framework/tests/agents/gandalf.golden.md +++ b/framework/tests/agents/gandalf.golden.md @@ -5,7 +5,7 @@ description: Régression structurelle de gandalf expect_name: gandalf expect_type: custom-command -expect_model: sonnet +expect_model: haiku required_sections: - "Personnalite" diff --git a/framework/tests/agents/godspeed.golden.md b/framework/tests/agents/godspeed.golden.md index b476cf0..25bf765 100644 --- a/framework/tests/agents/godspeed.golden.md +++ b/framework/tests/agents/godspeed.golden.md @@ -5,7 +5,7 @@ description: Régression structurelle du diagnostic — appelé par tous les orc expect_name: godspeed expect_type: custom-command -expect_model: sonnet +expect_model: haiku required_sections: - "Mission" diff --git a/framework/tests/agents/tools-checker.golden.md b/framework/tests/agents/tools-checker.golden.md index 45df72d..9ba6754 100644 --- a/framework/tests/agents/tools-checker.golden.md +++ b/framework/tests/agents/tools-checker.golden.md @@ -5,7 +5,7 @@ description: Régression structurelle de tools-checker expect_name: tools-checker expect_type: custom-command -expect_model: sonnet +expect_model: haiku required_sections: - "Mission" diff --git a/framework/tests/cheatheet.test.mjs b/framework/tests/cheatheet.test.mjs index 84fb310..fcf4447 100644 --- a/framework/tests/cheatheet.test.mjs +++ b/framework/tests/cheatheet.test.mjs @@ -67,15 +67,15 @@ describe('generate-registry.cjs', () => { } }); - test('les modèles sont uniquement opus ou sonnet', () => { + test('les modèles sont uniquement opus, sonnet ou haiku', () => { const registryPath = path.join(ROOT, 'agents', 'registry.json'); const registry = JSON.parse(fs.readFileSync(registryPath, 'utf8')); - const validModels = new Set(['opus', 'sonnet']); + const validModels = new Set(['opus', 'sonnet', 'haiku']); for (const agent of registry.agents) { assert.ok( validModels.has(agent.model), - `model invalide "${agent.model}" pour ${agent.name} (attendu: opus ou sonnet)` + `model invalide "${agent.model}" pour ${agent.name} (attendu: opus, sonnet ou haiku)` ); } }); diff --git a/framework/tools/cli-registry.json b/framework/tools/cli-registry.json index bd5dd32..ca44044 100644 --- a/framework/tools/cli-registry.json +++ b/framework/tools/cli-registry.json @@ -2897,6 +2897,33 @@ "eas update --branch main", "eas device:create" ] + }, + { + "id": "obscura", + "name": "Obscura", + "command": "obscura", + "check": "obscura --version", + "install": { + "macos": "curl -fsSL -o /tmp/obscura.tar.gz https://github.com/h4ckf0r0day/obscura/releases/latest/download/obscura-aarch64-macos.tar.gz && tar -xzf /tmp/obscura.tar.gz -C /tmp && sudo mv /tmp/obscura /usr/local/bin/ && rm /tmp/obscura.tar.gz", + "linux": "curl -fsSL -o /tmp/obscura.tar.gz https://github.com/h4ckf0r0day/obscura/releases/latest/download/obscura-x86_64-linux.tar.gz && tar -xzf /tmp/obscura.tar.gz -C /tmp && sudo mv /tmp/obscura /usr/local/bin/ && rm /tmp/obscura.tar.gz", + "cargo": "cargo install --git https://github.com/h4ckf0r0day/obscura", + "note": "Headless browser engine en Rust — alternative légère à Chrome headless (30 MB RAM vs 200+ MB, 85 ms page load vs 500 ms). V8 + Chrome DevTools Protocol (CDP), compatible Puppeteer/Playwright, stealth mode anti-fingerprinting. Adopté en base ulk depuis 2026-05-07 (priority required) pour scraping JS-rendered, JS eval, parallel multi-URL et CDP. Coexiste avec shot-scraper : shot-scraper conserve les screenshots/PDF/arbre d'accessibilité ; Obscura prend les use cases scraping/extraction/CDP. Source : https://github.com/h4ckf0r0day/obscura (Apache-2.0). Protocole : framework/agents/_shared/obscura-protocol.md." + }, + "required_by": [ + "visual-auditor", + "frontend-qa", + "seo-auditor", + "agamotto" + ], + "priority": "required", + "category": "browser", + "examples": [ + "obscura fetch https://example.com --eval \"document.title\"", + "obscura fetch https://example.com --selector \".article\" --dump", + "obscura scrape urls.txt --concurrency 8 --eval \"document.querySelector('h1')?.textContent\" --format json", + "obscura serve --port 9222 --stealth", + "obscura fetch https://example.com --wait-until networkidle --timeout 10000 --stealth" + ] } ] }