diff --git a/.claude/rules/agents-authoring.md b/.claude/rules/agents-authoring.md index 7f50362..a8bc1b8 100644 --- a/.claude/rules/agents-authoring.md +++ b/.claude/rules/agents-authoring.md @@ -70,7 +70,8 @@ extends: | `agent-teams.md` | Orchestrateurs supportant Agent Teams | | `memory-protocol.md` | Agents avec mémoire persistante | | `simplify-principles.md` | Agents avec mode simplification | -| `obsidian-doc-protocol.md` | Agents qui touchent `docs/spec*`, `docs/todo.md`, `docs/_memory/**` (Shuri 01, Task Runner 04, Bruce 25, 2b3 08, Lovecraft 47, Godspeed 00, …) — format Obsidian + CLIs `notesmd-cli` / `defuddle` / `pandoc` | +| `obsidian-doc-protocol.md` | Agents qui touchent `docs/spec*`, `docs/todo.md`, `docs/_memory/**` (Shuri 01, Task Runner 04, Bruce 25, 2b3 08, Lovecraft 47, Godspeed 00, …) — format Obsidian + CLIs `notesmd-cli` / `curl.md` / `defuddle` / `pandoc` | +| `curl-md-protocol.md` | Agents qui consultent / extraient une URL (Strange 16, Shuri 01, Mathieu 61, Tony 50, Stark 58, Agathe 60, Jean-Claude 63, SEO-auditor 32, …) — `curl.md` est le premier réflexe ; remplace `WebFetch` et `defuddle parse ` | | `faru-protocol.md` | Agents qui gèrent specs/tasks en mode faru (Shuri 01, Task Runner 04, 2b3 08) — détection `DOC_MODE`, branches `docs/backlog/` vs `docs/todo.md` | ## Phase (champ obligatoire) @@ -154,8 +155,9 @@ Ne jamais hardcoder de version de modèle — utiliser uniquement les alias `opu - `update-protocol.md` — mises à jour incrémentales (jamais de réécriture complète) - `context-protocol.md` — passage de contexte inter-agents (économise 3-10K tokens) - `agent-teams.md` — coordination parallèle -- `cli-tools-protocol.md` — priorité CLI > MCP (mentionne notesmd-cli, defuddle, pandoc) -- `obsidian-doc-protocol.md` — **format canonique** spec/todo/mémoire (Obsidian) + CLIs requises (notesmd-cli, defuddle, pandoc) +- `cli-tools-protocol.md` — priorité CLI > MCP (mentionne notesmd-cli, curl.md, defuddle, pandoc) +- `curl-md-protocol.md` — **URL → Markdown** : `curl.md` premier réflexe (depuis 2026-05-07), remplace `WebFetch` et `defuddle parse ` +- `obsidian-doc-protocol.md` — **format canonique** spec/todo/mémoire (Obsidian) + CLIs (notesmd-cli, curl.md, defuddle, pandoc) ## Format todo.md (Obsidian Kanban plugin) @@ -191,6 +193,6 @@ Efforts : XS (<30min), S (1-2h), M (2-4h), L (4-8h), XL (1-2j), XXL (3-5j). - Lecture/écriture du board → `notesmd-cli` (Yakitrak — pas besoin d'Obsidian app) - `notesmd-cli print name="docs/todo"` · `notesmd-cli search-content query="P0"` - Manipulation atomique : `notesmd-cli frontmatter set …` · `notesmd-cli move from=… to=…` -- Recherche web → spec/note → `defuddle parse --markdown | notesmd-cli create name=… content=-` +- Recherche web → spec/note → `curl.md | notesmd-cli create name=… content=-` (fallback : `defuddle parse --markdown` si curl.md HS) - Conversion `.docx`/`.pdf`/`.rst` → Markdown → `pandoc` (jamais de parser ad-hoc) - Spec agrégée → `docs/spec.base` (Obsidian Base, skill `kepano-obsidian-bases`) diff --git a/.claude/rules/install-reference.md b/.claude/rules/install-reference.md index 8960cee..c0a7b04 100644 --- a/.claude/rules/install-reference.md +++ b/.claude/rules/install-reference.md @@ -46,6 +46,7 @@ paths: ./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 --with-curl-md # + curl.md CLI (required, depuis 2026-05-07, activé par défaut) — URL → Markdown pour agents (wevm, MIT) · remplace WebFetch + defuddle parse · service public gratuit, pas d'API key ./install.sh --dry-run # Simuler sans modifier ./install.sh --wizard # Forcer le wizard interactif même sur reinstall ``` @@ -57,9 +58,14 @@ Install : `brew tap yakitrak/yakitrak && brew install yakitrak/yakitrak/notesmd- Vérifier : `notesmd-cli --version`. Setup vault : `notesmd-cli add-vault path="$(pwd)"`. Usage : `notesmd-cli daily|create|print|search|search-content|frontmatter|move|list|list-vaults|set-default-vault …`. Voir protocole `framework/agents/_shared/obsidian-doc-protocol.md`. -Defuddle (kepano) — Extracteur HTML → Markdown propre. Adopté en base ulk depuis 2026-04-29 (priority `required` dans `framework/tools/cli-registry.json`). Source : https://github.com/kepano/defuddle (MIT). Note : le package `defuddle-cli` historique est fusionné dans `defuddle`. +Defuddle (kepano) — Extracteur HTML → Markdown propre. **Fallback** depuis 2026-05-07 (priority `recommended`, anciennement `required` 2026-04-29). Source : https://github.com/kepano/defuddle (MIT). Note : le package `defuddle-cli` historique est fusionné dans `defuddle`. Install : `npm install -g defuddle` (ou `npx defuddle …` pour usage ponctuel). Vérifier : `defuddle --version`. -Usage : `defuddle parse [--markdown|--json] [--property X]`. Skill associée : `~/.claude/skills/kepano-defuddle/`. +Usage : `defuddle parse [--markdown|--json] [--property X]`. **Rôle révisé** depuis 2026-05-07 : **fallback** lorsque `curl.md` est down ou pour les **fichiers HTML locaux** uniquement. Le premier réflexe URL→Markdown est désormais `curl.md`. Skill associée : `~/.claude/skills/kepano-defuddle/`. + +curl.md (wevm) — URL → Markdown optimisé pour agents. **Adopté en base ulk depuis 2026-05-07** (priority `required` dans `framework/tools/cli-registry.json`, activé par défaut). Source : https://github.com/wevm/curl.md (MIT). Service public gratuit (rate limit généreux, pas d'API key obligatoire — login optionnel pour des quotas plus élevés). +Install : `curl -fsSL https://curl.md/install.sh | bash` (ou `npm install -g curl.md` · `bun add -g curl.md`). Vérifier : `curl.md --version`. **Sans install** : `curl https://curl.md/` (1-shot, idéal en CI / hooks). +Usage : `curl.md ` (CLI, stdout Markdown) · `curl https://curl.md/` (sans CLI) · préfixage navigateur `https://curl.md/`. +**Premier réflexe** dès qu'un agent consulte/cite/extrait/indexe une URL — **remplace `WebFetch` et `defuddle parse ` partout**. Coexiste avec `shot-scraper` (visuel) et `obscura` (scraping JS-rendered/CDP). Fallback ordonné : `curl.md` → `defuddle` (HTML local ou curl.md down) → `WebFetch` (dernier recours, qualité moindre). ⚠️ Ne **jamais** y passer une URL avec un secret en query string ni une page d'admin/intranet : utiliser `defuddle` local. Plugin Claude officiel : https://curl.md/docs/plugins/claude (non bundlé — la CLI suffit). Protocole : `framework/agents/_shared/curl-md-protocol.md`. Pandoc — Convertisseur universel de documents. Promu en base ulk depuis 2026-04-29 (priority `required` dans `framework/tools/cli-registry.json`). Source : https://pandoc.org (GPL-2.0+). Install : `brew install pandoc` · `apt install pandoc` · `winget install pandoc`. Vérifier : `pandoc --version`. diff --git a/CLAUDE.md b/CLAUDE.md index a315728..9c82744 100644 --- a/CLAUDE.md +++ b/CLAUDE.md @@ -35,11 +35,12 @@ 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 visuelles), `obscura` (headless browser Rust — scraping/JS eval/CDP). +Key CLIs: `gh` (GitHub), `vercel` (deploy), `neonctl` (DB), `gws` (Google), `resend` (email), `rtk` (token compression), `notesmd-cli` (vault Obsidian), `curl.md` (URL → Markdown, premier réflexe consultation web), `defuddle` (HTML local / fallback URL), `pandoc` (conversions de format), `shot-scraper` (captures web visuelles), `obscura` (headless browser Rust — scraping/JS eval/CDP). +curl.md : **obligatoire** depuis 2026-05-07 (priority `required`). Source : https://github.com/wevm/curl.md (MIT, wevm). Service public gratuit (rate limit généreux, pas d'API key obligatoire). Install : `curl -fsSL https://curl.md/install.sh | bash` (ou `npm install -g curl.md` · `bun add -g curl.md`). Usage : `curl.md ` (CLI) · `curl https://curl.md/` (1-shot sans install) · préfixe `https://curl.md/` dans le navigateur. **Premier réflexe** dès qu'un agent consulte/cite/extrait/indexe une URL — **remplace `WebFetch` et `defuddle parse ` partout**. Coexiste avec shot-scraper (visuel : screenshots/PDF/a11y/auth) et Obscura (scraping JS-rendered, JS eval, multi-URL parallèle, CDP). Règle simple : *curl.md pour le texte, shot-scraper pour le visuel, Obscura pour la donnée*. Fallback ordonné : curl.md → defuddle (HTML local ou curl.md down) → WebFetch (dernier recours, qualité moindre). ⚠️ Ne **jamais** passer à curl.md une URL contenant un secret en query string ou une page d'admin/intranet — utiliser `defuddle` local. Plugin Claude officiel disponible (https://curl.md/docs/plugins/claude) mais **non bundlé** (CLI suffit). Protocole : `framework/agents/_shared/curl-md-protocol.md`. Activation ulk : `./install.sh --with-curl-md` (activé par défaut). 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`. +Defuddle CLI : **fallback** depuis 2026-05-07 (priority `recommended`, anciennement `required` 2026-04-29). Source : https://github.com/kepano/defuddle (MIT, kepano). Install : `npm install -g defuddle`. Usage : `defuddle parse [--markdown|--json]`. **Rôle révisé** : utiliser **curl.md en premier** pour les URLs ; defuddle est conservé pour les **fichiers HTML locaux** (`page.html`) et comme **fallback** quand curl.md est down ou que l'URL ne peut pas transiter par un service tiers (intranet, secrets en query string). 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*). Token compression: `rtk` (rtk-ai/rtk, MIT) — adopté en base ulk depuis 2026-04-27. Pour les commandes verbose (`git status/log/diff`, `gh pr list/view`, `npm test`, `pytest`, `cargo test`, `terraform plan`, logs CI…), préférer `rtk proxy ` — gain -60 à -90% tokens. Hook PreToolUse `rtk-compress.sh` actif en base avec whitelist : suggère `rtk proxy` quand approprié. Install : `brew install rtk` · `curl -fsSL https://raw.githubusercontent.com/rtk-ai/rtk/refs/heads/master/install.sh | sh`. Stats : `rtk gain`. LLM-local: `apfel` **(optionnel, macOS 26+ Apple Silicon)** + `ollama qwen3.6:35b-a3b-mlx-bf16` **(optionnel, multiplateforme, Apple Silicon MLX)** — délèguent les micro-tâches (classification, TODO/secrets, commit message, extraction tags) à un LLM local gratuit. apfel = fichiers courts (<4K tokens), ollama = diffs longs (128K ctx). Install : `brew install Arthur-Ficial/tap/apfel` · `brew install ollama && ollama pull qwen3.6:35b-a3b-mlx-bf16`. Protocole unifié : `framework/agents/_shared/local-llm-protocol.md` · helpers : `framework/tools/llm-local.sh` (`llm_detect`, `llm_commit_message`, `llm_classify_ci_error`, `llm_extract_spec_meta`, …). Utilisé par godspeed (00), 2b3 (08), task-runner (04), ci-guard (54), shuri (01) ; fallback Claude si aucun. Gain mesuré : ~355-795 output tokens/session + latence (apfel ~1s vs Claude 2-5s par micro-tâche). Sprint : `docs/09-research/llm-local-sprint.md`. diff --git a/framework/agents/CLAUDE.md b/framework/agents/CLAUDE.md index e8ea8a5..244ff08 100644 --- a/framework/agents/CLAUDE.md +++ b/framework/agents/CLAUDE.md @@ -46,7 +46,8 @@ Full spec: `.claude/rules/agents-authoring.md` | `plugins-protocol.md` | Official plugins delegation | | `discovery-protocol.md` | Extended frontmatter spec | | `phase-grid.md` | 6-phase grid + agent mapping | -| `cli-tools-protocol.md` | CLI > MCP priority — mentions `notesmd-cli`, `defuddle`, `pandoc` (required) | +| `cli-tools-protocol.md` | CLI > MCP priority — mentions `notesmd-cli`, `curl.md`, `defuddle`, `pandoc` (required/recommended) | +| `curl-md-protocol.md` | **URL → Markdown** : `curl.md` premier réflexe pour consultation/extraction web (depuis 2026-05-07). Remplace `WebFetch` et `defuddle parse ` | | `obsidian-doc-protocol.md` | **Canonical format** for `docs/spec*`, `docs/todo.md`, `docs/_memory/` (Obsidian) + required CLIs | | `faru-protocol.md` | Faru mode (git-native kanban): DOC_MODE detection, `docs/backlog/` card format, coexistence rule — Shuri 01, Task Runner 04, 2b3 08 | | `design-source-protocol.md` | **Design source of truth** : `docs/design.md` (racine) + `docs/design-wireframe//CARD.md` (cartes faru-style). Garante : Agathe (60). Hérité par Agathe, Stark, Agamotto, Brique, Visual-Auditor. | @@ -75,7 +76,8 @@ Policy (ULK-072): an agent must not stay in `specials/` for more than 2 versions - **notion CLI** (prioritaire): `brew install notion-cli` + `notion auth` — brigitte, bifrost — voir `_shared/notion-protocol.md` - **mcp__notion__***: Notion API (fallback si CLI absent ou non-auth) - **notesmd-cli** (required, gestion vault Obsidian sans app desktop): `brew tap yakitrak/yakitrak && brew install yakitrak/yakitrak/notesmd-cli` — privilégier pour `docs/spec*`, `docs/todo.md`, `docs/_memory/**` — voir `_shared/obsidian-doc-protocol.md` -- **defuddle** (required, web → Markdown propre): `npm install -g defuddle` — privilégier sur `WebFetch` quand la sortie est réutilisée +- **curl.md** (required, URL → Markdown pour agents — premier réflexe consultation web depuis 2026-05-07): `curl -fsSL https://curl.md/install.sh | bash` (ou `npm install -g curl.md`) — **remplace `WebFetch` et `defuddle parse `**. Usage : `curl.md ` ou `curl https://curl.md/`. Voir `_shared/curl-md-protocol.md`. +- **defuddle** (recommended, fallback URL→Markdown si curl.md down + fichiers HTML locaux): `npm install -g defuddle` - **pandoc** (required, conversions multi-format): `brew install pandoc` — à invoquer dès qu'un format non-Markdown est en jeu (`.docx`, `.pdf`, `.rst`, `.org`, `.epub`, `.tex`, `.odt`) ## Model Distribution diff --git a/framework/agents/_shared/base-rules.md b/framework/agents/_shared/base-rules.md index 3418660..1b6a4df 100644 --- a/framework/agents/_shared/base-rules.md +++ b/framework/agents/_shared/base-rules.md @@ -67,6 +67,24 @@ Tous les agents et skills doivent appliquer ces 4 règles : --- +## Consultation web — premier réflexe `curl.md` + +> Détails complets : `_shared/curl-md-protocol.md` (depuis 2026-05-07). + +Pour **toute** consultation, citation, extraction ou indexation du contenu textuel d'une URL, l'agent passe par **`curl.md`** (wevm/curl.md, MIT, gratuit) : + +```bash +curl.md https://example.com/article # CLI installée +curl https://curl.md/https://example.com/article # 1-shot sans install (CI/hooks) +``` + +**Remplace** : `WebFetch` et `defuddle parse `. +**Coexiste avec** : `shot-scraper` (visuel), `obscura` (JS-rendered, scraping multi-URL, CDP). +**Fallback ordonné** : `curl.md` → `defuddle` (HTML local ou curl.md down) → `WebFetch` (qualité moindre). +**⚠️ Sécurité** : ne **jamais** passer à curl.md une URL avec un secret en query string ou une page d'admin/intranet (le service est distant) — utiliser `defuddle` local. + +--- + ## Conventions de nommage des fichiers | Type | Pattern | Emplacement | diff --git a/framework/agents/_shared/cli-tools-protocol.md b/framework/agents/_shared/cli-tools-protocol.md index 6cb490a..8edea48 100644 --- a/framework/agents/_shared/cli-tools-protocol.md +++ b/framework/agents/_shared/cli-tools-protocol.md @@ -34,10 +34,11 @@ Avant d'utiliser un outil, vérifier sa disponibilité : ## Gestion documentaire (Obsidian-canonical, depuis 2026-04-29) -Trois CLIs **`required`** (registre `framework/tools/cli-registry.json`) couvrent toute la chaîne docs/spec/todo/recherche-web. Voir `_shared/obsidian-doc-protocol.md` pour le détail. +Quatre CLIs **`required`** (registre `framework/tools/cli-registry.json`) couvrent toute la chaîne docs/spec/todo/recherche-web. Voir `_shared/obsidian-doc-protocol.md` et `_shared/curl-md-protocol.md` pour le détail. - **`notesmd-cli`** (Yakitrak, Go) — vault Obsidian sans nécessiter l'app desktop ouverte (utilisable en CI/headless). À utiliser pour toute interaction avec `docs/spec*.md`, `docs/spec.base`, `docs/todo.md`, `docs/_memory/**`. Install : `brew tap yakitrak/yakitrak && brew install yakitrak/yakitrak/notesmd-cli`. Préféré à la CLI officielle Obsidian (qui exige Obsidian.app actif). -- **`defuddle`** (kepano) — extraction HTML → Markdown propre. **À privilégier sur `WebFetch`** dès que la sortie est réutilisée (note, spec, citation). Install : `npm install -g defuddle`. +- **`curl.md`** (wevm) — **URL → Markdown pour agents, premier réflexe consultation/extraction web** (depuis 2026-05-07). **Remplace `WebFetch` et `defuddle parse `**. Service public gratuit (rate limit généreux, pas d'API key). Install : `curl -fsSL https://curl.md/install.sh | bash` (ou usage 1-shot : `curl https://curl.md/`). +- **`defuddle`** (kepano) — **fallback** quand curl.md est down + extraction depuis fichier HTML local. Rôle révisé 2026-05-07. Install : `npm install -g defuddle`. - **`pandoc`** — conversion universelle de documents. **À 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**. Install : `brew install pandoc` · `apt install pandoc` · `winget install pandoc`. Règle d'enchaînement type : @@ -46,8 +47,11 @@ Règle d'enchaînement type : # Brief Word client → spec Obsidian pandoc -f docx -t markdown brief.docx | notesmd-cli create name="docs/spec/from-brief" content=- -# Article web → note de recherche Obsidian -defuddle parse https://example.com/article --markdown | notesmd-cli create name="docs/research/source" content=- +# Article web → note de recherche Obsidian (curl.md = premier réflexe) +curl.md https://example.com/article | notesmd-cli create name="docs/research/source" content=- + +# Fichier HTML local → Markdown (cas où curl.md ne s'applique pas) +defuddle parse page.html --markdown | notesmd-cli create name="docs/research/local" content=- ``` ## LLM local diff --git a/framework/agents/_shared/curl-md-protocol.md b/framework/agents/_shared/curl-md-protocol.md new file mode 100644 index 0000000..1772338 --- /dev/null +++ b/framework/agents/_shared/curl-md-protocol.md @@ -0,0 +1,179 @@ +--- +name: curl-md-protocol +type: protocol +description: Protocole partagé curl.md — URL → Markdown optimisé pour agents. Premier réflexe pour toute consultation / extraction d'une page web. Remplace WebFetch et defuddle (qui devient fallback). +--- + +# curl.md Protocol + +> Source : https://github.com/wevm/curl.md (MIT, wevm) +> Service public gratuit — `https://curl.md/` renvoie la page transformée en Markdown propre, optimisé pour LLMs (token-savings 50-90 % vs HTML brut). +> Adopté en base ulk depuis 2026-05-07 (priority `required` dans `framework/tools/cli-registry.json`). + +## Principe + +**curl.md est le premier réflexe** dès qu'un agent doit consulter, citer, extraire ou indexer le contenu textuel d'une URL. Il **remplace** : + +| Outil historique | Nouveau réflexe | +|------------------|-----------------| +| `WebFetch` (URL → HTML rendu côté Claude) | `curl https://curl.md/` | +| `defuddle parse ` (extraction Markdown distante) | `curl.md ` | +| `curl \| html2text` (parser ad-hoc) | `curl.md ` | + +**Coexiste avec** : + +- **`shot-scraper`** — visuel (screenshots, PDF, arbre d'accessibilité, auth interactive). curl.md ne capture pas d'image. +- **`obscura`** — JS-rendered scraping, JS eval (`--eval`), multi-URL parallèle, serveur CDP. curl.md exécute le JS côté serveur curl.md mais n'expose pas d'API d'évaluation arbitraire. +- **`defuddle`** — fallback URL→Markdown si curl.md est down + extraction depuis fichier HTML local. + +> Règle simple : *curl.md pour consulter / extraire le texte d'une URL ; shot-scraper pour le visuel ; obscura pour le scraping de données structurées.* + +## Installation + +```bash +# Recommandé (script officiel) +curl -fsSL https://curl.md/install.sh | bash + +# Alternatives +npm install -g curl.md +bun add -g curl.md + +# Vérifier +curl.md --version +``` + +Activation ulk : `./install.sh --with-curl-md` (activé par défaut depuis 2026-05-07). + +> **Pas d'install obligatoire** : curl.md est aussi utilisable sans CLI via `curl https://curl.md/` — pratique en CI / hooks Git / cloud routines. + +## Usages + +### CLI installée + +```bash +# 1-shot : URL → Markdown sur stdout +curl.md https://example.com/article + +# Vers un fichier +curl.md https://example.com/article > /tmp/article.md + +# Pipe vers notesmd-cli (chaînage doc canonique) +curl.md https://example.com/article | \ + notesmd-cli create name="docs/research/example-article" content=- +``` + +### Sans install (fallback / CI) + +```bash +# Préfixage curl.md/ +curl https://curl.md/https://example.com/article + +# Stdout direct vers fichier +curl -fsSL https://curl.md/https://example.com/article > /tmp/article.md +``` + +### Browser + +Préfixer une URL dans la barre d'adresse : +``` +https://curl.md/https://news.ycombinator.com +``` +→ rend la page en Markdown affiché tel quel par le navigateur. + +## Patterns ulk fréquents + +### Spec / brief depuis un article public +```bash +URL="https://example.com/blog/post" +curl.md "$URL" | notesmd-cli create name="docs/research/$(basename $URL)" content=- +``` + +### Recherche cumulative (plusieurs sources → 1 note) +```bash +{ + echo "# Sources collectées — $(date +%F)" + for u in $(cat sources.txt); do + echo "## $u" + curl.md "$u" + echo + done +} > docs/research/cumul-$(date +%F).md +``` + +### Audit SEO rapide (titres + sections d'une URL) +```bash +curl.md "https://example.com" | grep -E '^#{1,3} ' +``` + +### Brief reverse depuis un site de référence (Strange / Mathieu) +```bash +curl.md "https://competitor.example.com/pricing" > docs/audits/competitor-pricing.md +``` + +## Authentification & quotas + +- **Gratuit, pas d'API key obligatoire** au lancement (rate limit généreux). +- Connexion sur https://curl.md/login → quotas plus élevés. +- Crédits prépayés disponibles pour skip rate-limit (workflow CI lourd). + +> Aucune variable d'environnement n'est requise. Si l'usage devient massif, configurer un token via le mécanisme de la CLI (cf. `curl.md --help`) — protocole à mettre à jour le jour où on l'active. + +## Plugin Claude officiel + +curl.md publie un plugin Claude Code : https://curl.md/docs/plugins/claude. + +```bash +# Installer le plugin (marketplace Claude Code) +/plugin marketplace add wevm/curl.md +``` + +> Le plugin n'est **pas** bundlé par défaut dans ulk — la CLI suffit pour 100 % des cas d'usage agents. Le plugin expose des MCP tools dédiés ; à activer projet par projet si on veut court-circuiter le shell. + +## Règle agents ulk + +Tout agent qui faisait **`WebFetch ""`** ou **`defuddle parse --markdown`** **doit** : + +1. Garder `Bash` dans `tools:` +2. Ajouter `extends: _shared/curl-md-protocol.md` +3. Remplacer : + - `WebFetch ` → `curl.md ` (ou `curl https://curl.md/` si CLI absente) + - `defuddle parse --markdown` → `curl.md ` +4. **Conserver** `defuddle` uniquement pour les **fichiers HTML locaux** (`defuddle parse page.html`) ou en fallback si curl.md est indisponible. +5. **Conserver** `shot-scraper` pour le visuel (screenshots, PDF, a11y, auth). +6. **Conserver** `obscura` pour le scraping JS-rendered, le JS eval, le multi-URL parallèle et le CDP. + +Agents directement concernés (consultation / extraction web) : **strange (16)**, **shuri (01)**, **mathieu (61)**, **tony (50)**, **stark (58)**, **agathe (60)**, **jean-claude (63)**, **seo-auditor (32)**, **frontend-qa (02)**, **agamotto (17)**, **2b3 (08)** quand il documente un brief externe, **bruce (25)** lors d'un cadrage initial sur URL publique. + +## Fallback si curl.md est down / réseau bloqué + +Si `curl.md` retourne une erreur (5xx, timeout, host non joignable), basculer **dans cet ordre** : + +```bash +fetch_md() { + local url="$1" + if curl -fsSL --max-time 10 "https://curl.md/$url" 2>/dev/null; then + return 0 + fi + echo "⚠️ curl.md indisponible — fallback defuddle" >&2 + if command -v defuddle >/dev/null 2>&1; then + defuddle parse "$url" --markdown && return 0 + fi + echo "⚠️ defuddle absent — dernier fallback : WebFetch (qualité moindre)" >&2 + return 1 # l'agent utilise WebFetch via son tool +} +``` + +Le fallback n'est **jamais silencieux** : l'agent loggue `⚠️ curl.md down — fallback X` dans son rapport pour traçabilité. + +## Limitations connues + +- **Pas de JS arbitraire** — pour exécuter du JS dans la page, utiliser `obscura fetch --eval ""`. +- **Pas de screenshots / PDF** — utiliser `shot-scraper`. +- **Pas d'auth** — pour les pages derrière login, utiliser `shot-scraper auth` (cookies Playwright) puis curl avec ces cookies, ou un MCP authentifié. +- **Service distant** — la requête transite par les serveurs curl.md ; ne **jamais** y passer une URL contenant un secret en query string. Pour les sites internes / privés, `defuddle` reste obligatoire. + +## Sécurité / privacy + +- ✅ Sites publics, articles, docs OSS, blog posts → curl.md OK. +- ❌ URLs contenant des tokens (`?key=…&signature=…`), pages d'admin, intranet → **ne pas** passer par curl.md. Utiliser `defuddle` local. +- Ne jamais loguer le résultat de curl.md dans un rapport public si l'URL d'origine est privée — privilégier le résumé. diff --git a/framework/agents/_shared/design-source-protocol.md b/framework/agents/_shared/design-source-protocol.md index 6dbfd18..36d12ad 100644 --- a/framework/agents/_shared/design-source-protocol.md +++ b/framework/agents/_shared/design-source-protocol.md @@ -255,7 +255,7 @@ mcp_cap_threshold: 4000 - `notesmd-cli print name="docs/design"` · `notesmd-cli search-content query="--accent"` - Création carte : `notesmd-cli create name="docs/design-wireframe/component-foo/CARD" content=-` - Front-matter atomique : `notesmd-cli frontmatter set path=… key=status value=implemented` -- Audit / web → `defuddle parse --markdown` puis `notesmd-cli create` +- Audit / web → `curl.md ` puis `notesmd-cli create` (fallback : `defuddle parse --markdown`) - Conversion .docx/.pdf → `pandoc -f -t markdown` ## 5. Orchestration — Agathe (60) chef d'orchestre diff --git a/framework/agents/_shared/obsidian-doc-protocol.md b/framework/agents/_shared/obsidian-doc-protocol.md index 26221e2..47ac4ee 100644 --- a/framework/agents/_shared/obsidian-doc-protocol.md +++ b/framework/agents/_shared/obsidian-doc-protocol.md @@ -71,26 +71,47 @@ sinon : Elle reste disponible à titre informatif, mais ulk privilégie NotesMD CLI pour son indépendance vis-à-vis de l'app desktop. -## CLI Defuddle — **obligatoire** (web → Markdown) +## CLI curl.md — **obligatoire** (URL → Markdown, premier réflexe) -`defuddle` (https://github.com/kepano/defuddle, MIT) est en priorité `required` -dans le registre ulk depuis 2026-04-29. À privilégier systématiquement sur -`WebFetch` quand le résultat doit être réutilisé (note, spec, mémoire, citation). +`curl.md` (https://github.com/wevm/curl.md, MIT) est en priorité `required` +dans le registre ulk depuis **2026-05-07**. **Premier réflexe** dès qu'un agent +consulte, cite, extrait ou indexe le contenu textuel d'une URL. -- **Install** : `npm install -g defuddle` · vérifier `defuddle --version` -- **Note** : le package historique `defuddle-cli` est fusionné dans `defuddle`. +**Remplace** : `WebFetch` et `defuddle parse ` (qui devient fallback HTML local). + +- **Install** : `curl -fsSL https://curl.md/install.sh | bash` (ou `npm install -g curl.md` · `bun add -g curl.md`) +- **Vérifier** : `curl.md --version` +- **Sans install (1-shot)** : `curl https://curl.md/` — pratique en CI / hooks ```bash -defuddle parse https://example.com/article --markdown # → stdout Markdown propre -defuddle parse page.html --json # → JSON avec metadata -defuddle parse https://example.com --property title --property byline +curl.md https://example.com/article # → stdout Markdown +curl.md https://example.com/article > /tmp/article.md # → fichier +curl.md https://example.com/article \ + | notesmd-cli create name="docs/research/source" content=- ``` -Workflow type (chaîné avec NotesMD CLI) : +**Service public gratuit**, pas d'API key obligatoire. Connexion offerte pour +quotas plus élevés. Voir `_shared/curl-md-protocol.md` pour le détail +(coexistence avec shot-scraper / obscura, fallback, sécurité, plugin Claude). + +## CLI Defuddle — **fallback** (HTML local, curl.md down) + +`defuddle` (https://github.com/kepano/defuddle, MIT) est passé du rôle +"obligatoire URL→MD" (2026-04-29) au rôle de **fallback** (2026-05-07) — voir +section précédente. Reste `recommended` dans le registre. + +À utiliser dans **deux** cas seulement : + +1. **Fichier HTML local** : `defuddle parse page.html --markdown` +2. **curl.md indisponible** (réseau coupé, host down, URL privée non réseau-réachable) → fallback explicite avec warning + +- **Install** : `npm install -g defuddle` · vérifier `defuddle --version` +- **Note** : le package historique `defuddle-cli` est fusionné dans `defuddle`. ```bash -md=$(defuddle parse https://example.com/article --markdown) -notesmd-cli create name="docs/research/source-X" content="$md" +defuddle parse page.html --markdown # fichier local +defuddle parse https://example.com --markdown # fallback si curl.md HS +defuddle parse page.html --json # JSON + metadata ``` ### Exemples canoniques (NotesMD CLI) @@ -143,13 +164,17 @@ pandoc -f pdf -t markdown spec-recue.pdf -o docs/spec-imported.md # pdf → md pandoc --from gfm --to commonmark docs/todo.md -o docs/todo-cm.md # normalisation Markdown ``` -### Chaînage type avec defuddle / notesmd-cli +### Chaînage type avec curl.md / notesmd-cli ```bash # Brief Word client → spec Obsidian pandoc -f docx -t markdown brief.docx \ | notesmd-cli create name="docs/spec/from-brief" content=- +# Article web → note de recherche Obsidian (curl.md = premier réflexe) +curl.md https://example.com/article \ + | notesmd-cli create name="docs/research/source" content=- + # Spec Obsidian → PDF livrable pandoc -f markdown -t pdf "$(notesmd-cli print name=docs/spec/auth)" \ -o docs/exports/spec-auth.pdf diff --git a/framework/agents/_shared/token-optimizers-protocol.md b/framework/agents/_shared/token-optimizers-protocol.md index 684bc28..1524c7e 100644 --- a/framework/agents/_shared/token-optimizers-protocol.md +++ b/framework/agents/_shared/token-optimizers-protocol.md @@ -38,7 +38,8 @@ Les **4 règles d'hygiène de contexte** (`_shared/context-hygiene-protocol.md`) | **Context Mode hook** | Output Bash/MCP > 8KB | ✅ Livré (INTG-001) | `--with-context-mode` | -$8 à -$24/mois | | **Skill `/context-mode`** | Query/list/stats/purge DB | ✅ Livré (INTG-002) | `--with-context-mode` | (UX) | | **RTK proxy** | Output verbose Bash | ✅ Base ulk (2026-04-27) | `rtk proxy ` | -60 à -90% sur la commande | -| **defuddle** | Web fetch propre | ✅ Required (2026-04-29) | `defuddle parse ` | -50 à -80% vs `WebFetch` brut | +| **curl.md** | URL → Markdown agents | ✅ Required (2026-05-07) | `curl.md ` | -50 à -90% vs `WebFetch` brut | +| **defuddle** | HTML local / fallback URL | ✅ Recommended (2026-05-07, demoted) | `defuddle parse page.html` | (fallback de curl.md) | | **CLI > MCP** | Cache write/read MCP | ✅ Continu | `gh`, `vercel`, `wrangler`, `gws`, `notion`, `linear.sh` | -10 à -20K tokens/turn par MCP retiré | | **`extends:` modulaire** | Cache write agents | ✅ Sargeras sprint | Frontmatter `extends:` | Variable (extraction god-files) | | **Apfel / Ollama local** | Délégation micro-tâches | ✅ Optionnel | godspeed (00), 2b3 (08) | $0 sur les tâches déléguées | @@ -100,10 +101,18 @@ rtk proxy gh pr list --json number,title,labels,reviewDecision --limit 50 ### Pour les agents qui fetchent le web ```bash -# Au lieu de WebFetch brut → réutilisation problématique +# Premier réflexe : curl.md (URL → Markdown optimisé pour agents) +curl.md "https://example.com/article" > /tmp/article.md + +# Sans CLI installée (CI / hooks) : +curl -fsSL "https://curl.md/https://example.com/article" > /tmp/article.md + +# Fallback (curl.md down ou fichier HTML local) : defuddle parse "https://example.com/article" --markdown > /tmp/article.md ``` +Voir `_shared/curl-md-protocol.md` pour la chaîne complète (sécurité, fallback, plugin Claude). + ### Pour les agents qui touchent docs/spec*/todo Voir `_shared/obsidian-doc-protocol.md` (CLI `notesmd-cli` prioritaire, économie I/O sur les frontmatter). diff --git a/framework/cli/cmd/install.go b/framework/cli/cmd/install.go index 8645861..18afec8 100644 --- a/framework/cli/cmd/install.go +++ b/framework/cli/cmd/install.go @@ -54,6 +54,7 @@ type installFlags struct { withDesignCLIs bool withDevOpsCLIs bool withMobileCLIs bool + withCurlMD bool // behaviour dryRun bool noTUI bool @@ -111,6 +112,7 @@ func init() { f.Bool("with-design-clis", false, "Install design CLIs (imagemagick, ffmpeg, svgo…)") f.Bool("with-devops-clis", false, "Install DevOps CLIs (terraform, ansible, pulumi, act…)") f.Bool("with-mobile-clis", false, "Install mobile CLIs (fastlane, expo, eas-cli…)") + f.Bool("with-curl-md", false, "Install curl.md CLI (URL → Markdown for agents — enabled by default)") f.Bool("dry-run", false, "Simulate without writing anything") f.Bool("no-tui", false, "Non-interactive mode (CI/CD friendly)") f.Bool("fast", false, "Quick reinstall — skips wizard, plain output") @@ -321,6 +323,7 @@ func parseInstallFlags(cmd *cobra.Command) (installFlags, error) { boolFlag("with-design-clis", &flags.withDesignCLIs) boolFlag("with-devops-clis", &flags.withDevOpsCLIs) boolFlag("with-mobile-clis", &flags.withMobileCLIs) + boolFlag("with-curl-md", &flags.withCurlMD) boolFlag("dry-run", &flags.dryRun) boolFlag("no-tui", &flags.noTUI) boolFlag("fast", &flags.fast) @@ -377,6 +380,7 @@ func applyFlags(flags installFlags, state *installer.State) { set("design-clis", flags.withDesignCLIs) set("devops-clis", flags.withDevOpsCLIs) set("mobile-clis", flags.withMobileCLIs) + set("curl-md", flags.withCurlMD) } // applyProfile adjusts module defaults based on --profile. diff --git a/framework/cli/internal/installer/catalog.go b/framework/cli/internal/installer/catalog.go index 394a36a..f8edda7 100644 --- a/framework/cli/internal/installer/catalog.go +++ b/framework/cli/internal/installer/catalog.go @@ -153,6 +153,12 @@ var All = []Installable{ }, // --- External tools --- + &ExternalModule{ + base: base{key: "curl-md", flag: "--with-curl-md", label: "curl.md", description: "URL → Markdown pour agents (wevm, MIT) — premier réflexe consultation/extraction web, remplace WebFetch + defuddle (required)", enabledByDefault: true, category: "tools"}, + dep: "curl", + runCmd: []string{"sh", "-c", "if command -v curl.md >/dev/null 2>&1; then echo \"curl.md déjà présent : $(curl.md --version 2>/dev/null || echo installed)\"; exit 0; fi; curl -fsSL https://curl.md/install.sh | bash"}, + message: "curl requis (préinstallé sur macOS/Linux). Alternatives : npm install -g curl.md · bun add -g curl.md. Service gratuit sans API key — voir _shared/curl-md-protocol.md.", + }, &ExternalModule{ base: base{key: "shot-scraper", flag: "--with-shot-scraper", label: "shot-scraper", description: "captures web headless (screenshots, JS, accessibilité) — remplace mcp__chrome-devtools__* (required)", category: "tools"}, dep: "pip3", diff --git a/framework/cli/internal/installer/modules_test.go b/framework/cli/internal/installer/modules_test.go index 62a829c..6c0ab3e 100644 --- a/framework/cli/internal/installer/modules_test.go +++ b/framework/cli/internal/installer/modules_test.go @@ -48,7 +48,7 @@ func TestDefaultModules(t *testing.T) { t.Errorf("DefaultModules len: got %d, want %d", len(defaults), len(All)) } // modules enabled by default - for _, key := range []string{"figma-skills", "swift-skills", "flutter-skills", "context-audit", "obsidian-skills", "symbols", "architecture-diagram", "rtk-hook"} { + for _, key := range []string{"figma-skills", "swift-skills", "flutter-skills", "context-audit", "obsidian-skills", "symbols", "architecture-diagram", "rtk-hook", "curl-md"} { if !defaults[key] { t.Errorf("%s should be enabled by default", key) } diff --git a/framework/tools/cli-registry.json b/framework/tools/cli-registry.json index ca44044..aa6a631 100644 --- a/framework/tools/cli-registry.json +++ b/framework/tools/cli-registry.json @@ -446,6 +446,32 @@ "vhs record --output demo.gif" ] }, + { + "id": "curl-md", + "name": "curl.md (wevm)", + "command": "curl.md", + "check": "curl.md --version", + "install": { + "macos": "curl -fsSL https://curl.md/install.sh | bash", + "linux": "curl -fsSL https://curl.md/install.sh | bash", + "windows": "curl -fsSL https://curl.md/install.sh | bash", + "npm": "npm install -g curl.md", + "bun": "bun add -g curl.md", + "note": "URL → Markdown optimisé pour agents (token-savings massif vs HTML brut). Source : https://github.com/wevm/curl.md (MIT, wevm). Service public gratuit (rate limit généreux, pas d'auth obligatoire) — connexion offerte pour quotas plus élevés. Adopté en base ulk depuis 2026-05-07 (priority `required`). Remplace `WebFetch` et `defuddle` comme premier réflexe pour toute consultation/extraction d'une page web. Usage 1-shot sans install : `curl https://curl.md/`." + }, + "replaces_mcp": null, + "required_by": [ + "all agents (consultation / extraction web → Markdown)" + ], + "priority": "required", + "category": "doc", + "examples": [ + "curl https://curl.md/https://example.com/article", + "curl.md https://example.com/article", + "curl.md https://example.com/article > /tmp/article.md", + "curl.md https://example.com | notesmd-cli create name=\"docs/research/source\" content=-" + ] + }, { "id": "defuddle", "name": "Defuddle (kepano)", @@ -456,18 +482,18 @@ "linux": "npm install -g defuddle", "windows": "npm install -g defuddle", "npx": "npx defuddle …", - "note": "Extrait du Markdown propre depuis du HTML / une URL — gain tokens majeur sur les fetch web. Source : https://github.com/kepano/defuddle (MIT, Steph Ango). Le package `defuddle-cli` historique est fusionné dans `defuddle`. Adopté en base ulk depuis 2026-04-29 (priority `required`)." + "note": "Extracteur HTML local → Markdown. Rôle révisé (2026-05-07) : **fallback** quand `curl.md` est indisponible (réseau coupé, host curl.md down) ou pour les fichiers HTML locaux (`page.html`). Source : https://github.com/kepano/defuddle (MIT, Steph Ango). Le package `defuddle-cli` historique est fusionné dans `defuddle`." }, "replaces_mcp": null, "required_by": [ - "all agents (mode CLI : extraction web → Markdown)" + "fallback URL→Markdown (curl.md down) · fichiers HTML locaux" ], - "priority": "required", + "priority": "recommended", "category": "doc", "examples": [ - "defuddle parse https://example.com/article --markdown", + "defuddle parse page.html --markdown", "defuddle parse page.html --json", - "defuddle parse https://example.com --property title --property byline", + "defuddle parse https://example.com --property title --property byline # fallback si curl.md HS", "curl -s https://example.com | defuddle parse - --markdown" ] },