Skip to content

DOC

2026 04 09 site refonte

Site Refonte — Swiss + Use Cases Implementation Plan

For agentic workers: REQUIRED SUB-SKILL: Use superpowers:subagent-driven-development (recommended) or superpowers:executing-plans to implement this plan task-by-task. Steps use checkbox (- [ ]) syntax for tracking.

Goal: Réécrire site/index.html avec un design Swiss International Style (navy #02065D + orange #FF9A04), layout split asymétrique, 10 use cases expandables, grille agents filtrables, animations géométriques — stack HTML + Tailwind CDN + Alpine.js.

Architecture: Single HTML file self-contained. Alpine.js pour l’interactivité (expand use cases, filtres agents, copy, modal). site/data/commands.json existant réutilisé pour la grille agents. Modal fetch GitHub raw inchangé.

Tech Stack: HTML5, Tailwind CSS CDN v3, Alpine.js CDN, IBM Plex Mono (Google Fonts), Iconify CDN


Files

FichierAction
site/index.htmlRéécriture complète
site/data/commands.jsonInchangé

Task 1 : Foundation — head, palette, CSS custom, squelette

Files:

  • Modify: site/index.html (réécriture complète)

  • Step 1 : Vérifier le fichier actuel

wc -l /Users/izo/Dev/Docs/Ulk/site/index.html

Expected : ~1636 lignes.

  • Step 2 : Écrire le nouveau fichier avec foundation complète

Écrire exactement ce contenu à /Users/izo/Dev/Docs/Ulk/site/index.html :

<!DOCTYPE html>
<html lang="fr">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>ulk — AI Development Toolkit for Claude Code</title>
  <meta name="description" content="71 agents IA spécialisés pour Claude Code. Zéro config, mémoire inter-sessions, CLI-first.">
  <link rel="icon" href="https://raw.githubusercontent.com/izo/Ulk/main/ulk.png" type="image/png">

  <!-- Fonts -->
  <link rel="preconnect" href="https://fonts.googleapis.com">
  <link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
  <link href="https://fonts.googleapis.com/css2?family=IBM+Plex+Mono:wght@400;500;700;900&family=IBM+Plex+Sans:wght@400;500;700&display=swap" rel="stylesheet">

  <!-- Tailwind -->
  <script src="https://cdn.tailwindcss.com"></script>
  <script>
    tailwind.config = {
      theme: {
        extend: {
          colors: {
            navy: '#02065D',
            'navy-dark': '#01043d',
            'navy-deeper': '#010230',
            swiss: '#FF9A04',
            'swiss-muted': 'rgba(255,154,4,0.15)',
          },
          fontFamily: {
            mono: ['IBM Plex Mono', 'monospace'],
            sans: ['IBM Plex Sans', 'system-ui', 'sans-serif'],
          },
          animation: {
            'pulse-slow': 'pulse-slow 4s cubic-bezier(0.4,0,0.6,1) infinite',
            'spin-slow': 'spin 12s linear infinite',
            'type-1': 'typing 0.5s steps(12,end) 0.3s both',
            'type-2': 'typing 0.5s steps(15,end) 1.4s both',
            'type-3': 'typing 0.5s steps(10,end) 2.5s both',
          },
          keyframes: {
            'pulse-slow': {
              '0%,100%': { transform: 'scale(1)', opacity: '0.85' },
              '50%': { transform: 'scale(1.06)', opacity: '1' },
            },
            'typing': {
              from: { width: '0', opacity: '0' },
              to: { width: '100%', opacity: '1' },
            },
          },
        }
      }
    }
  </script>

  <!-- Alpine.js -->
  <script defer src="https://unpkg.com/alpinejs@3.x.x/dist/cdn.min.js"></script>

  <!-- Iconify -->
  <script src="https://code.iconify.design/3/3.1.1/iconify.min.js"></script>

  <style>
    /* Base */
    *, *::before, *::after { box-sizing: border-box; }
    body { background: #02065D; color: #fff; font-family: 'IBM Plex Mono', monospace; }

    /* Swiss geometric circle */
    .swiss-circle {
      border-radius: 50%;
      background: #FF9A04;
      animation: pulse-slow 4s cubic-bezier(0.4,0,0.6,1) infinite;
    }
    .swiss-circle-ring {
      border-radius: 50%;
      border: 3px solid #FF9A04;
      animation: pulse-slow 4s cubic-bezier(0.4,0,0.6,1) infinite 0.5s;
    }

    /* Split layout */
    .split-left {
      position: sticky;
      top: 0;
      height: 100vh;
      background: #02065D;
      border-right: 3px solid #FF9A04;
      display: flex;
      flex-direction: column;
      justify-content: space-between;
      padding: 2rem;
    }

    /* Use case row */
    .use-case-row {
      border-bottom: 1px solid rgba(255,255,255,0.06);
      transition: all 0.2s ease;
    }
    .use-case-row:hover { background: rgba(255,154,4,0.04); }
    .use-case-row.open { border-left: 3px solid #FF9A04; background: rgba(255,154,4,0.06); }

    /* Agent card */
    .agent-card {
      background: rgba(255,255,255,0.03);
      border: 1px solid rgba(255,255,255,0.08);
      border-radius: 8px;
      transition: all 0.2s ease;
      cursor: pointer;
    }
    .agent-card:hover {
      background: rgba(255,154,4,0.06);
      border-color: rgba(255,154,4,0.3);
    }

    /* Filter pill */
    .filter-pill {
      border: 1px solid rgba(255,255,255,0.15);
      border-radius: 99px;
      padding: 4px 14px;
      font-size: 11px;
      cursor: pointer;
      transition: all 0.15s;
      white-space: nowrap;
    }
    .filter-pill:hover, .filter-pill.active {
      background: #FF9A04;
      border-color: #FF9A04;
      color: #000;
      font-weight: 700;
    }

    /* Code block */
    .code-block {
      background: #010230;
      border: 1px solid rgba(255,154,4,0.2);
      border-radius: 8px;
      font-family: 'IBM Plex Mono', monospace;
      font-size: 13px;
    }

    /* Modal */
    .modal-backdrop {
      position: fixed; inset: 0;
      background: rgba(1,2,45,0.85);
      backdrop-filter: blur(4px);
      z-index: 50;
      display: flex; align-items: center; justify-content: center;
    }
    .modal-panel {
      background: #01043d;
      border: 1px solid rgba(255,154,4,0.2);
      border-radius: 12px;
      width: min(720px, 95vw);
      max-height: 80vh;
      overflow-y: auto;
    }

    /* Terminal typing lines */
    .terminal-line {
      overflow: hidden;
      white-space: nowrap;
      display: block;
    }
    .terminal-line-1 { animation: typing 0.4s steps(18,end) 0.4s both; }
    .terminal-line-2 { animation: typing 0.4s steps(14,end) 1.2s both; }
    .terminal-line-3 { animation: typing 0.4s steps(12,end) 2.0s both; }

    /* Swiss section header */
    .section-header {
      display: flex;
      align-items: center;
      gap: 1rem;
      padding: 2rem 0 1.5rem;
      border-bottom: 2px solid #FF9A04;
      margin-bottom: 2rem;
    }
    .section-header-label {
      font-size: 11px;
      letter-spacing: 0.15em;
      text-transform: uppercase;
      color: #FF9A04;
      font-weight: 700;
    }
    .section-header-num {
      font-size: 11px;
      color: rgba(255,255,255,0.3);
      margin-left: auto;
    }

    /* Scrollbar */
    ::-webkit-scrollbar { width: 4px; }
    ::-webkit-scrollbar-track { background: #01043d; }
    ::-webkit-scrollbar-thumb { background: rgba(255,154,4,0.3); border-radius: 2px; }

    /* Mobile */
    @media (max-width: 768px) {
      .split-left { position: relative; height: auto; }
      .desktop-only { display: none; }
    }
  </style>
</head>
<body x-data="ulkApp()" x-init="init()">

  <!-- NAV -->
  <nav id="nav" style="background:#01043d; border-bottom:1px solid rgba(255,154,4,0.2);"
       class="sticky top-0 z-50 flex items-center justify-between px-6 py-3">
    <div class="flex items-center gap-3">
      <span class="font-mono font-black text-white text-lg tracking-tight">ulk</span>
      <span class="text-xs font-mono px-2 py-0.5 rounded"
            style="background:rgba(255,154,4,0.12); color:#FF9A04; border:1px solid rgba(255,154,4,0.2);">
        v3.5.0
      </span>
    </div>
    <div class="flex items-center gap-6">
      <a href="#use-cases" class="text-xs font-mono text-white/50 hover:text-swiss transition-colors hidden md:block">Use Cases</a>
      <a href="#agents" class="text-xs font-mono text-white/50 hover:text-swiss transition-colors hidden md:block">Agents</a>
      <a href="#install" class="text-xs font-mono text-white/50 hover:text-swiss transition-colors hidden md:block">Install</a>
      <a href="https://github.com/izo/ulk" target="_blank"
         class="text-xs font-mono px-3 py-1.5 rounded transition-all"
         style="background:#FF9A04; color:#000; font-weight:700;">
        GitHub →
      </a>
    </div>
  </nav>

  <!-- HERO -->
  <section class="min-h-screen md:grid" style="grid-template-columns: 38% 62%;">

    <!-- Left col — Swiss identity -->
    <div class="split-left">
      <div class="text-xs font-mono tracking-widest uppercase" style="color:rgba(255,255,255,0.3);">
        AI Development Toolkit
      </div>

      <div>
        <div class="font-mono font-black leading-none mb-6" style="font-size:clamp(3rem,8vw,5.5rem);">
          <div class="text-white">AI</div>
          <div class="text-white">Dev</div>
          <div style="color:#FF9A04;">ulk.</div>
        </div>
        <div class="flex gap-3">
          <div class="swiss-circle" style="width:48px;height:48px;"></div>
          <div class="swiss-circle-ring" style="width:48px;height:48px;"></div>
          <div style="width:48px;height:48px;border-radius:50%;background:rgba(255,154,4,0.2);"></div>
        </div>
      </div>

      <div>
        <div class="text-xs font-mono mb-1" style="color:rgba(255,255,255,0.3);">
          71 agents · zero config
        </div>
        <div class="text-xs font-mono" style="color:rgba(255,255,255,0.3);">
          ships today
        </div>
      </div>
    </div>

    <!-- Right col — Tagline + Install -->
    <div class="flex flex-col justify-center px-8 md:px-16 py-16" style="background:#01043d;">
      <div class="text-xs font-mono tracking-widest uppercase mb-6" style="color:#FF9A04;">
        for Claude Code
      </div>

      <h1 class="font-sans font-black mb-4 text-white leading-tight"
          style="font-size:clamp(2rem,5vw,3.5rem);">
        Ship faster.<br>
        <span style="color:rgba(255,255,255,0.4);">Think less.</span>
      </h1>

      <p class="font-sans text-base mb-10" style="color:rgba(255,255,255,0.55); max-width:480px;">
        71 agents IA spécialisés qui détectent votre stack, orchestrent le travail, et committent proprement.
        Bruce s'en charge. Vous tapez une commande.
      </p>

      <!-- Terminal animation -->
      <div class="code-block p-4 mb-8" style="max-width:480px;">
        <div class="text-xs font-mono mb-3" style="color:rgba(255,255,255,0.2);">$ claude</div>
        <div class="font-mono text-sm space-y-1">
          <span class="terminal-line terminal-line-1" style="color:#FF9A04;">/ulk:bruce go</span>
          <span class="terminal-line terminal-line-2" style="color:rgba(255,255,255,0.5);">scanning project...</span>
          <span class="terminal-line terminal-line-3" style="color:#4ade80;">✓ ready — Next.js 14 detected</span>
        </div>
      </div>

      <!-- CTA -->
      <div class="flex flex-col sm:flex-row gap-3" style="max-width:480px;">
        <div class="code-block flex items-center justify-between px-4 py-3 flex-1">
          <code class="text-sm" style="color:#FF9A04;">
            curl -fsSL …/install-remote.sh | bash
          </code>
          <button @click="copyInstall()"
                  class="ml-3 text-xs font-mono px-2 py-1 rounded transition-all flex-shrink-0"
                  style="background:rgba(255,154,4,0.15); color:#FF9A04; border:1px solid rgba(255,154,4,0.2);"
                  x-text="copied ? '✓ copied' : 'copy'">
          </button>
        </div>
        <a href="https://github.com/izo/ulk" target="_blank"
           class="text-sm font-mono px-4 py-3 rounded border transition-all text-center"
           style="border-color:rgba(255,255,255,0.15); color:rgba(255,255,255,0.6);">
          View source →
        </a>
      </div>
    </div>
  </section>

  <!-- USE CASES -->
  <section id="use-cases" style="background:#010230; padding:5rem 0;">
    <div style="max-width:1100px; margin:0 auto; padding:0 2rem;">

      <div class="section-header">
        <span class="section-header-label">Use Cases</span>
        <span style="font-size:11px; color:rgba(255,255,255,0.2); font-family:monospace;">10 workflows</span>
        <span class="section-header-num">02 / 06</span>
      </div>

      <div class="space-y-0">
        <template x-for="(uc, i) in useCases" :key="i">
          <div class="use-case-row px-0 py-0" :class="{ 'open': uc.open }">
            <!-- Row header -->
            <button class="w-full text-left px-4 py-5 md:px-6 flex items-center gap-4 md:gap-8"
                    @click="uc.open = !uc.open">
              <span class="font-mono font-black text-2xl md:text-4xl flex-shrink-0"
                    style="color:#FF9A04; width:3rem;" x-text="String(i+1).padStart(2,'0')"></span>
              <span class="font-mono font-bold text-white text-sm md:text-base flex-1" x-text="uc.title"></span>
              <span class="hidden md:flex items-center gap-2 text-xs font-mono flex-shrink-0"
                    style="color:rgba(255,255,255,0.35);">
                <template x-for="(step, si) in uc.flow" :key="si">
                  <span class="flex items-center gap-1">
                    <span x-text="step"></span>
                    <span x-show="si < uc.flow.length - 1" style="color:rgba(255,154,4,0.4);">→</span>
                  </span>
                </template>
              </span>
              <span class="font-mono text-xs px-2 py-1 rounded flex-shrink-0"
                    style="background:rgba(255,154,4,0.12); color:#FF9A04; border:1px solid rgba(255,154,4,0.2);"
                    x-text="uc.agent"></span>
              <span class="font-mono text-xs ml-2 flex-shrink-0" style="color:rgba(255,154,4,0.5);"
                    x-text="uc.open ? '↑' : '↓'"></span>
            </button>
            <!-- Expanded content -->
            <div x-show="uc.open" x-transition:enter="transition ease-out duration-200"
                 x-transition:enter-start="opacity-0 -translate-y-2"
                 x-transition:enter-end="opacity-100 translate-y-0"
                 class="px-4 md:px-6 pb-6 pt-0">
              <div class="grid md:grid-cols-2 gap-6" style="border-top:1px solid rgba(255,154,4,0.1); padding-top:1.5rem;">
                <div>
                  <div class="text-xs font-mono uppercase tracking-wider mb-3" style="color:#FF9A04;">Description</div>
                  <p class="text-sm font-sans" style="color:rgba(255,255,255,0.6); line-height:1.6;" x-text="uc.desc"></p>
                </div>
                <div>
                  <div class="text-xs font-mono uppercase tracking-wider mb-3" style="color:#FF9A04;">Commandes</div>
                  <div class="space-y-2">
                    <template x-for="cmd in uc.commands" :key="cmd">
                      <div class="code-block px-3 py-2 text-xs font-mono" style="color:#FF9A04;" x-text="cmd"></div>
                    </template>
                  </div>
                </div>
              </div>
            </div>
          </div>
        </template>
      </div>
    </div>
  </section>

  <!-- AGENTS GRID -->
  <section id="agents" style="background:#02065D; padding:5rem 0;">
    <div style="max-width:1100px; margin:0 auto; padding:0 2rem;">

      <div class="section-header">
        <span class="section-header-label">Agents</span>
        <span style="font-size:11px; color:rgba(255,255,255,0.2); font-family:monospace;"
              x-text="filteredAgents.length + ' agents'"></span>
        <span class="section-header-num">03 / 06</span>
      </div>

      <!-- Filters -->
      <div class="flex flex-wrap gap-2 mb-8">
        <template x-for="cat in categories" :key="cat.id">
          <button class="filter-pill font-mono"
                  :class="{ 'active': activeCategory === cat.id }"
                  @click="activeCategory = cat.id"
                  x-text="cat.name"></button>
        </template>
      </div>

      <!-- Grid -->
      <div class="grid grid-cols-1 sm:grid-cols-2 lg:grid-cols-3 gap-3">
        <template x-for="agent in filteredAgents" :key="agent.name">
          <div class="agent-card p-4" @click="openModal(agent)">
            <div class="flex items-start gap-3">
              <div class="flex-shrink-0 w-8 h-8 rounded flex items-center justify-center"
                   style="background:rgba(255,154,4,0.1);">
                <span class="iconify text-swiss" :data-icon="'mdi:' + (agent.icon || 'robot')"
                      style="width:16px;height:16px;"></span>
              </div>
              <div class="flex-1 min-w-0">
                <div class="flex items-center gap-2 mb-1">
                  <span class="font-mono font-bold text-sm text-white" x-text="agent.name"></span>
                  <span class="text-xs font-mono px-1.5 py-0.5 rounded" x-show="agent.model === 'opus'"
                        style="background:rgba(255,154,4,0.12);color:#FF9A04;font-size:10px;">opus</span>
                </div>
                <p class="text-xs font-sans line-clamp-2" style="color:rgba(255,255,255,0.45);"
                   x-text="agent.description"></p>
              </div>
            </div>
            <div class="mt-3 text-xs font-mono" style="color:rgba(255,154,4,0.5);">
              <span x-text="'/ulk:' + agent.name"></span>
            </div>
          </div>
        </template>
      </div>
    </div>
  </section>

  <!-- FEATURES -->
  <section id="features" style="background:#010230; padding:5rem 0;">
    <div style="max-width:1100px; margin:0 auto; padding:0 2rem;">

      <div class="section-header">
        <span class="section-header-label">Pourquoi ulk</span>
        <span class="section-header-num">04 / 06</span>
      </div>

      <div class="grid md:grid-cols-3 gap-8">
        <!-- Feature 1 -->
        <div class="space-y-4">
          <div class="flex gap-3 items-start">
            <div class="swiss-circle flex-shrink-0" style="width:40px;height:40px;margin-top:4px;"></div>
            <div>
              <h3 class="font-mono font-black text-white text-lg mb-2">Zéro config</h3>
              <p class="font-sans text-sm" style="color:rgba(255,255,255,0.5); line-height:1.6;">
                Détection automatique de stack. Next.js, Nuxt, Astro, SPIP, Swift, Go, Python — aucun fichier à créer. Bruce détecte et orchestre.
              </p>
            </div>
          </div>
        </div>
        <!-- Feature 2 -->
        <div class="space-y-4">
          <div class="flex gap-3 items-start">
            <div style="width:40px;height:40px;background:#FF9A04;border-radius:4px;flex-shrink:0;margin-top:4px;
                        animation:pulse-slow 4s cubic-bezier(0.4,0,0.6,1) infinite 1s;"></div>
            <div>
              <h3 class="font-mono font-black text-white text-lg mb-2">Mémoire inter-sessions</h3>
              <p class="font-sans text-sm" style="color:rgba(255,255,255,0.5); line-height:1.6;">
                8 agents persistent leur état. Bruce se souvient du projet, de la stack, des préférences. Task Runner ajuste ses estimations.
              </p>
            </div>
          </div>
        </div>
        <!-- Feature 3 -->
        <div class="space-y-4">
          <div class="flex gap-3 items-start">
            <div style="width:40px;height:40px;flex-shrink:0;margin-top:4px;
                        border:3px solid #FF9A04;transform:rotate(45deg);
                        animation:spin 12s linear infinite;"></div>
            <div>
              <h3 class="font-mono font-black text-white text-lg mb-2">CLI &gt; MCP</h3>
              <p class="font-sans text-sm" style="color:rgba(255,255,255,0.5); line-height:1.6;">
                Les outils CLI consomment 0 token. ulk utilise <code class="text-swiss">gh</code>, <code class="text-swiss">vercel</code>, <code class="text-swiss">neonctl</code> en priorité. MCP réservé à Figma, Notion, Linear.
              </p>
            </div>
          </div>
        </div>
      </div>
    </div>
  </section>

  <!-- INSTALL -->
  <section id="install" style="background:#000010; padding:5rem 0 6rem;">
    <div style="max-width:700px; margin:0 auto; padding:0 2rem; text-align:center;">

      <div class="font-mono font-black mb-2" style="font-size:clamp(2.5rem,8vw,5rem); color:#FF9A04; line-height:1;">
        SHIP
      </div>
      <div class="font-mono font-black mb-10" style="font-size:clamp(2.5rem,8vw,5rem); color:rgba(255,255,255,0.15); line-height:1;">
        TODAY.
      </div>

      <div class="code-block p-4 mb-4 text-left">
        <div class="text-xs font-mono mb-2" style="color:rgba(255,255,255,0.2);">Installation</div>
        <div class="flex items-center justify-between">
          <code class="text-sm font-mono" style="color:#FF9A04;">
            curl -fsSL https://raw.githubusercontent.com/izo/ulk/main/install-remote.sh | bash
          </code>
          <button @click="copyInstall()" class="ml-4 flex-shrink-0 text-xs font-mono px-3 py-1.5 rounded transition-all"
                  style="background:rgba(255,154,4,0.15); color:#FF9A04; border:1px solid rgba(255,154,4,0.2);"
                  x-text="copied ? '✓' : 'copy'"></button>
        </div>
      </div>

      <div class="code-block p-4 mb-10 text-left text-xs font-mono space-y-1"
           style="color:rgba(255,255,255,0.4);">
        <div><span style="color:#FF9A04;">./install.sh</span>                    # base</div>
        <div><span style="color:#FF9A04;">./install.sh</span> --with-vps          # + 16 agents VPS</div>
        <div><span style="color:#FF9A04;">./install.sh</span> --with-addy-skills  # + checklists</div>
        <div><span style="color:rgba(255,255,255,0.2);">./uninstall.sh</span>               # désinstaller</div>
      </div>

      <div class="text-xs font-mono" style="color:rgba(255,255,255,0.2);">
        MIT · <a href="https://github.com/izo/ulk" class="hover:text-swiss transition-colors">github.com/izo/ulk</a> · made with ulk
      </div>
    </div>
  </section>

  <!-- MODAL -->
  <div class="modal-backdrop" x-show="modal.open" x-transition @click.self="modal.open = false"
       style="display:none;">
    <div class="modal-panel p-6">
      <div class="flex items-center justify-between mb-4">
        <span class="font-mono font-bold text-white text-lg" x-text="modal.agent?.name"></span>
        <button @click="modal.open = false"
                class="text-xs font-mono px-3 py-1 rounded"
                style="background:rgba(255,255,255,0.05); color:rgba(255,255,255,0.5);">esc</button>
      </div>
      <div x-show="modal.loading" class="text-xs font-mono text-center py-8" style="color:#FF9A04;">
        loading...
      </div>
      <div x-show="!modal.loading" class="font-sans text-sm" style="color:rgba(255,255,255,0.7); line-height:1.7;"
           x-html="modal.content"></div>
    </div>
  </div>

  <script>
    function ulkApp() {
      return {
        copied: false,
        activeCategory: 'all',
        categories: [],
        allAgents: [],
        modal: { open: false, agent: null, content: '', loading: false },

        useCases: [
          {
            open: false,
            title: 'Nouveau projet',
            flow: ['brief', 'spec', 'todo', 'ship'],
            agent: 'bruce',
            desc: 'Partez de zéro. Bruce interroge votre idée, Shuri génère la spec et le backlog Kanban, Task Runner exécute les premières tâches.',
            commands: ['/ulk:bruce go', '/ulk:shuri mode=spec', '/ulk:task-runner']
          },
          {
            open: false,
            title: 'Session de développement',
            flow: ['scan', 'tâche', 'commit', 'clear'],
            agent: 'task-runner + 2b3',
            desc: 'Godspeed scanne le projet en 30s, Task Runner prend la prochaine tâche, 2b3 checkpoint en fin de session.',
            commands: ['/ulk:godspeed', '/ulk:bruce next', '/ulk:2b3']
          },
          {
            open: false,
            title: 'Audit pré-release',
            flow: ['10 axes', 'score', 'GO/NO-GO'],
            agent: 'sargeras',
            desc: 'Audit omniscient sur 10 axes avec métriques quantitatives. Verdict production-ready avec liste des top 20 actions.',
            commands: ['/ulk:sargeras', '/ulk:blackemperor', '# mode: audit-complet']
          },
          {
            open: false,
            title: 'Fixer des erreurs',
            flow: ['erreur', 'diagnostic', 'patch'],
            agent: 'robocop',
            desc: 'Robocop détecte et corrige toutes les erreurs : runtime, compilation, tests, linting. Supporte tous les stacks.',
            commands: ['/ulk:robocop', '/ulk:bruce fix', '# ou passer l\'issue GitHub']
          },
          {
            open: false,
            title: 'Documenter du code existant',
            flow: ['code', 'spec', 'todo', 'sync'],
            agent: 'strange',
            desc: 'Strange reconstitue 6 documents depuis le code source (cahier des charges, doc technique, user stories, glossaire, architecture).',
            commands: ['/ulk:strange', '/ulk:shuri mode=sync', '/ulk:friday mode=context']
          },
          {
            open: false,
            title: 'App mobile',
            flow: ['web', 'API', 'iOS + Android'],
            agent: 'happy → steve + fluke',
            desc: 'Happy audite le projet web et génère l\'API complète (OpenAPI 3.1). Steve produit le starter SwiftUI, Fluke le starter Kotlin/Flutter.',
            commands: ['/ulk:happy', '/ulk:steve', '/ulk:fluke']
          },
          {
            open: false,
            title: 'Migration de stack',
            flow: ['source', 'plan', 'exécution'],
            agent: 'ranma',
            desc: 'Ranma planifie les migrations entre stacks : WordPress → SPIP, Next.js → Nuxt, PHP → Node, etc. Plan détaillé + exécution.',
            commands: ['/ulk:ranma', '# ex: WordPress → Next.js']
          },
          {
            open: false,
            title: 'Déploiement',
            flow: ['build', 'deploy', 'verify'],
            agent: 'deploy:vercel',
            desc: '5 agents de déploiement : Vercel, Netlify, Cloudflare, Docker, AWS. Détection automatique du framework, preview + production.',
            commands: ['/ulk:deploy:vercel', '/ulk:deploy:docker', '/ulk:deploy:aws']
          },
          {
            open: false,
            title: 'Optimisation performance',
            flow: ['CWV', 'bundle', 'DB', 'fix'],
            agent: 'perf-auditor + vision',
            desc: 'Perf Auditor mesure Core Web Vitals, bundle size et requêtes DB. Vision simplifie le code. Rapport avec priorités et fixes.',
            commands: ['/ulk:perf-auditor', '/ulk:vision mode=simplify', '/ulk:blackemperor']
          },
          {
            open: false,
            title: 'Reverse design system',
            flow: ['Figma', 'tokens', 'composants'],
            agent: 'agamotto',
            desc: 'Agamotto reconstitue le design system depuis Figma (MCP), Pencil ou Penpot : tokens, composants, patterns, guidelines → docs/design-system/.',
            commands: ['/ulk:agamotto', '# nécessite Figma MCP ou fichier .pen']
          },
        ],

        get filteredAgents() {
          if (this.activeCategory === 'all') return this.allAgents;
          return this.allAgents.filter(a => a.category === this.activeCategory);
        },

        async init() {
          try {
            const res = await fetch('/data/commands.json');
            const data = await res.json();
            this.categories = [{ id: 'all', name: 'Tous' }, ...data.categories.map(c => ({ id: c.id, name: c.name }))];
            this.allAgents = data.categories.flatMap(c =>
              c.commands.map(cmd => ({ ...cmd, category: c.id, prefix: c.prefix }))
            );
          } catch(e) { console.warn('commands.json not loaded', e); }
        },

        copyInstall() {
          navigator.clipboard.writeText('curl -fsSL https://raw.githubusercontent.com/izo/ulk/main/install-remote.sh | bash');
          this.copied = true;
          setTimeout(() => this.copied = false, 2000);
        },

        async openModal(agent) {
          this.modal = { open: true, agent, content: '', loading: true };
          try {
            const agentFileMap = {
              bruce: 'agents/orchestrators/25-bruce.md',
              godspeed: 'agents/00-godspeed.md',
              shuri: 'agents/docs/01-shuri.md',
              'task-runner': 'agents/session/04-task-runner.md',
              vision: 'agents/audit/05-vision.md',
              '2b3': 'agents/session/08-2b3.md',
              robocop: 'agents/session/11-robocop.md',
              sargeras: 'agents/audit/45-sargeras.md',
              gandalf: 'agents/session/34-gandalf.md',
            };
            const file = agentFileMap[agent.name] || `agents/${agent.name}.md`;
            const url = `https://raw.githubusercontent.com/izo/ulk/main/${file}`;
            const resp = await fetch(url);
            if (resp.ok) {
              const text = await resp.text();
              this.modal.content = this.renderMarkdown(text.replace(/^---[\s\S]*?---\n/, '').slice(0, 3000));
            } else {
              this.modal.content = `<p style="color:#FF9A04">${agent.description}</p>`;
            }
          } catch(e) {
            this.modal.content = `<p style="color:rgba(255,255,255,0.5)">${agent.description}</p>`;
          }
          this.modal.loading = false;
        },

        renderMarkdown(md) {
          return md
            .replace(/^#{1,3} (.+)$/gm, '<h3 style="color:#FF9A04;font-weight:700;margin:1em 0 0.5em;font-family:monospace;">$1</h3>')
            .replace(/`([^`]+)`/g, '<code style="background:rgba(255,154,4,0.1);color:#FF9A04;padding:1px 4px;border-radius:3px;">$1</code>')
            .replace(/\*\*([^*]+)\*\*/g, '<strong style="color:#fff;">$1</strong>')
            .replace(/\n\n/g, '<br><br>')
            .replace(/^- (.+)$/gm, '<li style="color:rgba(255,255,255,0.6);margin:4px 0;">$1</li>');
        },
      }
    }
  </script>
</body>
</html>
  • Step 3 : Vérifier le fichier
wc -l /Users/izo/Dev/Docs/Ulk/site/index.html

Expected : environ 350-450 lignes.

  • Step 4 : Ouvrir dans le navigateur
open /Users/izo/Dev/Docs/Ulk/site/index.html

Vérifier visuellement :

  • Fond navy #02065D

  • Nav sticky orange

  • Hero split : titre massif gauche + install droite

  • 10 use cases listés (cliquables)

  • Grille agents (peut ne pas charger sans serveur)

  • Section features + install

  • Step 5 : Commit

cd /Users/izo/Dev/Docs/Ulk
git add site/index.html
git commit -m "feat(site): refonte Swiss Navy+Orange — hero split, 10 use cases, agents grid, Alpine.js"

Task 2 : Ajuster les chemins agents dans agentFileMap

Files:

  • Modify: site/index.html — section agentFileMap dans le script

La réorganisation des agents a changé les chemins. Mettre à jour le map avec les bons chemins post-réorganisation.

  • Step 1 : Vérifier les chemins actuels des agents clés
ls /Users/izo/Dev/Docs/Ulk/agents/orchestrators/ | head -5
ls /Users/izo/Dev/Docs/Ulk/agents/session/ | head -10
ls /Users/izo/Dev/Docs/Ulk/agents/audit/ | head -10
ls /Users/izo/Dev/Docs/Ulk/agents/docs/ | head -5
  • Step 2 : Mettre à jour agentFileMap dans site/index.html

Remplacer le bloc agentFileMap par un map complet avec les vrais chemins :

const agentFileMap = {
  // Orchestrators
  bruce: 'agents/orchestrators/25-bruce.md',
  blackemperor: 'agents/orchestrators/18-blackemperor.md',
  lovecraft: 'agents/orchestrators/47-obsidian-doc.md',
  // Session
  godspeed: 'agents/session/00-godspeed.md',
  'task-runner': 'agents/session/04-task-runner.md',
  '2b3': 'agents/session/08-2b3.md',
  robocop: 'agents/session/11-robocop.md',
  gandalf: 'agents/session/34-gandalf.md',
  // Docs
  shuri: 'agents/docs/01-shuri.md',
  friday: 'agents/docs/09-friday.md',
  strange: 'agents/docs/16-strange.md',
  'obsidian-vault': 'agents/docs/39-obsidian-vault.md',
  // Audit
  vision: 'agents/audit/05-vision.md',
  'a11y-auditor': 'agents/audit/06-a11y-auditor.md',
  'perf-auditor': 'agents/audit/07-perf-auditor.md',
  sargeras: 'agents/audit/45-sargeras.md',
  'seo-auditor': 'agents/audit/32-seo-auditor.md',
  amiral: 'agents/audit/41-amiral.md',
  'claude-md-optimizer': 'agents/audit/42-claude-md-optimizer.md',
  'tools-checker': 'agents/audit/43-tools-checker.md',
  // Mobile
  happy: 'agents/mobile/49-happy.md',
  steve: 'agents/mobile/27-steve.md',
  fluke: 'agents/mobile/48-fluke.md',
  // Sync
  bifrost: 'agents/sync/21-bifrost.md',
  brigitte: 'agents/sync/24-brigitte.md',
  // Specials
  tony: 'agents/specials/50-tony.md',
  rodin: 'agents/specials/46-rodin.md',
  ranma: 'agents/specials/31-ranma.md',
  picsou: 'agents/specials/26-picsou.md',
  agamotto: 'agents/specials/17-agamotto.md',
  sensei: 'agents/specials/38-sensei.md',
  astride: 'agents/specials/40-astride.md',
};

NOTE : vérifier d’abord les vrais chemins avec ls agents/*/ avant d’appliquer. Corriger les chemins qui ne correspondent pas.

  • Step 3 : Vérifier quelques chemins
ls /Users/izo/Dev/Docs/Ulk/agents/mobile/ 2>/dev/null || echo "mobile/ not found"
ls /Users/izo/Dev/Docs/Ulk/agents/specials/ 2>/dev/null || echo "specials/ not found"
ls /Users/izo/Dev/Docs/Ulk/agents/sync/ 2>/dev/null || echo "sync/ not found"

Adapter les chemins selon les dossiers réels qui existent.

  • Step 4 : Commit
cd /Users/izo/Dev/Docs/Ulk
git add site/index.html
git commit -m "fix(site): mettre à jour agentFileMap avec chemins post-réorganisation"

Task 3 : Tester localement avec serveur HTTP

Files:

  • Read: site/index.html (test uniquement)

Le fichier doit tourner sur un serveur local (pas file://) pour que fetch('/data/commands.json') fonctionne.

  • Step 1 : Lancer un serveur local
cd /Users/izo/Dev/Docs/Ulk/site
python3 -m http.server 8080
  • Step 2 : Ouvrir dans le navigateur

Naviguer vers http://localhost:8080

Vérifier :

  • Nav sticky navy/orange visible

  • Hero : fond navy, titre “AI Dev ulk.”, cercles orange animés, terminal animation

  • Section Use Cases : 10 lignes numérotées, clic sur “01 Nouveau projet” expand/collapse

  • Section Agents : grille de cartes, filtres par catégorie fonctionnels (click “Agents”, “Deploy”, etc.)

  • Modal : clic sur une carte agent → modal s’ouvre, contenu markdown chargé

  • Section Features : 3 colonnes avec formes géométriques animées

  • Section Install : “SHIP TODAY.” + code block + copy button

  • Copy button : clic → texte change en ”✓”

  • Mobile : réduire fenêtre < 768px → layout stack vertical

  • Step 3 : Fixer les problèmes visuels

Si Alpine.js ne charge pas les agents (erreur CORS sur fetch local) : normal en file://, OK sur serveur.

Si les icônes Iconify ne s’affichent pas : vérifier la connexion internet (chargement CDN).

Si animations ne jouent pas : vérifier que le CSS animation est bien dans <style>.

  • Step 4 : Commit final de polish
cd /Users/izo/Dev/Docs/Ulk
git add site/index.html
git commit -m "fix(site): polish post-test — ajustements visuels mineurs"

Task 4 : Vérification finale + .gitignore

  • Step 1 : Ajouter .superpowers/ au .gitignore
echo ".superpowers/" >> /Users/izo/Dev/Docs/Ulk/.gitignore
  • Step 2 : Vérifier le git status
cd /Users/izo/Dev/Docs/Ulk
git status
git log --oneline -5
  • Step 3 : Vérifier que le déploiement GitHub Pages fonctionnera
# Vérifier que .nojekyll existe
ls /Users/izo/Dev/Docs/Ulk/site/.nojekyll
# Vérifier que data/commands.json est présent
ls /Users/izo/Dev/Docs/Ulk/site/data/commands.json
  • Step 4 : Commit final
cd /Users/izo/Dev/Docs/Ulk
git add .gitignore
git commit -m "chore: add .superpowers/ to .gitignore"