✓ Verified 💻 Development ✓ Enhanced Data

Myvibe Skills

Publish static HTML, ZIP archive, or directory to MyVibe.

Rating
4.7 (166 reviews)
Downloads
2,149 downloads
Version
1.0.0

Overview

Publish static HTML, ZIP archive, or directory to MyVibe.

Complete Documentation

View Source →

MyVibe Publish

Publish web content (HTML file, ZIP archive, or directory) to MyVibe.

Prerequisites

  • Node.js 18 or later
  • All script executions in this skill require network access. Always run Bash commands with sandbox_permissions=require_escalated to ensure network permissions are enabled.
  • The deployment and screenshot generation may take a few minutes. Use a 10-minute (600000ms) timeout for publish commands.

Usage

bash
/myvibe:myvibe-publish --file ./dist.zip      # Publish ZIP
/myvibe:myvibe-publish --file ./index.html    # Publish HTML
/myvibe:myvibe-publish --dir ./dist           # Publish directory
/myvibe:myvibe-publish --url https://example.com/app  # Import from URL
/myvibe:myvibe-publish --dir ./dist --new     # Force new Vibe
/myvibe:myvibe-publish --dir ./dist --did z2qaXXX    # Update specific Vibe

Options

OptionAliasDescription
--file -fPath to HTML file or ZIP archive
--dir -dDirectory to compress and publish
--url -uURL to import and publish
--hub -hMyVibe URL (default: https://www.myvibe.so/)
--title </td><td class="px-4 py-2 text-sm text-gray-700">-t</td><td class="px-4 py-2 text-sm text-gray-700">Project title</td></tr><tr class="border-b border-gray-200 hover:bg-gray-50"><td class="px-4 py-2 text-sm text-gray-700">--desc <desc></td><td class="px-4 py-2 text-sm text-gray-700">Project description</td></tr><tr class="border-b border-gray-200 hover:bg-gray-50"><td class="px-4 py-2 text-sm text-gray-700">--visibility <vis></td><td class="px-4 py-2 text-sm text-gray-700">-v</td><td class="px-4 py-2 text-sm text-gray-700">Visibility: public or private (default: public)</td></tr><tr class="border-b border-gray-200 hover:bg-gray-50"><td class="px-4 py-2 text-sm text-gray-700">--did <did></td><td class="px-4 py-2 text-sm text-gray-700">Vibe DID for version update (overrides auto-detection)</td></tr><tr class="border-b border-gray-200 hover:bg-gray-50"><td class="px-4 py-2 text-sm text-gray-700">--new</td><td class="px-4 py-2 text-sm text-gray-700">Force create new Vibe, ignore publish history</td></tr></tbody></table> <h2 class="text-2xl font-bold text-gray-900 mt-10 mb-6 border-b border-gray-200 pb-2">Workflow Overview</h2> <ul class="my-4 space-y-2"><li class="ml-6 mb-2 text-gray-700 list-decimal"><strong class="font-semibold">Detect Project Type</strong> → if no build needed, start screenshot in background</li> <li class="ml-6 mb-2 text-gray-700 list-decimal"><strong class="font-semibold">Build</strong> (if needed) → then start screenshot in background</li> <li class="ml-6 mb-2 text-gray-700 list-decimal"><strong class="font-semibold">Metadata Analysis</strong> → extract title, description, tags</li> <li class="ml-6 mb-2 text-gray-700 list-decimal"><strong class="font-semibold">Confirm Publish</strong> → show metadata, get user confirmation</li> <li class="ml-6 mb-2 text-gray-700 list-decimal"><strong class="font-semibold">Execute Publish</strong> → script auto-reads screenshot result</li> <li class="ml-6 mb-2 text-gray-700 list-decimal"><strong class="font-semibold">Return Result</strong> → show publish URL</li> </ul> <strong class="font-semibold">First tool call - execute in parallel:</strong> <ul class="my-4 space-y-2"><li class="ml-6 mb-2 text-gray-700 list-disc"><code class="px-1.5 py-0.5 text-sm text-primary-700 bg-primary-50 rounded font-mono border border-primary-200">Read</code>: source file or main files in directory</li> <li class="ml-6 mb-2 text-gray-700 list-disc"><code class="px-1.5 py-0.5 text-sm text-primary-700 bg-primary-50 rounded font-mono border border-primary-200">Bash</code>: <code class="px-1.5 py-0.5 text-sm text-primary-700 bg-primary-50 rounded font-mono border border-primary-200">git remote get-url origin 2>/dev/null || echo "Not a git repo"</code></li> <li class="ml-6 mb-2 text-gray-700 list-disc"><code class="px-1.5 py-0.5 text-sm text-primary-700 bg-primary-50 rounded font-mono border border-primary-200">Bash</code>: <code class="px-1.5 py-0.5 text-sm text-primary-700 bg-primary-50 rounded font-mono border border-primary-200">node {skill_path}/scripts/utils/fetch-tags.mjs --hub {hub}</code></li> </ul> <hr class="my-8 border-t border-gray-300"></p><p class="my-4 text-gray-700 leading-relaxed"><h2 class="text-2xl font-bold text-gray-900 mt-10 mb-6 border-b border-gray-200 pb-2">Step 1: Detect Project Type</h2></p><p class="my-4 text-gray-700 leading-relaxed"><table class="w-full my-6 border-collapse"><thead><tr><th class="bg-gray-100 px-4 py-2 text-left text-sm font-semibold text-gray-900 border-b-2 border-gray-300">Check</th><th class="bg-gray-100 px-4 py-2 text-left text-sm font-semibold text-gray-900 border-b-2 border-gray-300">Project Type</th><th class="bg-gray-100 px-4 py-2 text-left text-sm font-semibold text-gray-900 border-b-2 border-gray-300">Next Step</th></tr></thead><tbody><tr class="border-b border-gray-200 hover:bg-gray-50"><td class="px-4 py-2 text-sm text-gray-700">--file with HTML/ZIP</td><td class="px-4 py-2 text-sm text-gray-700"><strong class="font-semibold">Single File</strong></td><td class="px-4 py-2 text-sm text-gray-700">→ Start screenshot, then Step 3</td></tr><tr class="border-b border-gray-200 hover:bg-gray-50"><td class="px-4 py-2 text-sm text-gray-700">Has dist/, build/, or out/ with index.html</td><td class="px-4 py-2 text-sm text-gray-700"><strong class="font-semibold">Pre-built</strong></td><td class="px-4 py-2 text-sm text-gray-700">→ Step 2 (confirm rebuild)</td></tr><tr class="border-b border-gray-200 hover:bg-gray-50"><td class="px-4 py-2 text-sm text-gray-700">Has package.json with build script, no output</td><td class="px-4 py-2 text-sm text-gray-700"><strong class="font-semibold">Buildable</strong></td><td class="px-4 py-2 text-sm text-gray-700">→ Step 2 (build first)</td></tr><tr class="border-b border-gray-200 hover:bg-gray-50"><td class="px-4 py-2 text-sm text-gray-700">Multiple package.json or workspace config</td><td class="px-4 py-2 text-sm text-gray-700"><strong class="font-semibold">Monorepo</strong></td><td class="px-4 py-2 text-sm text-gray-700">→ Step 2 (select app)</td></tr><tr class="border-b border-gray-200 hover:bg-gray-50"><td class="px-4 py-2 text-sm text-gray-700">Has index.html at root, no package.json</td><td class="px-4 py-2 text-sm text-gray-700"><strong class="font-semibold">Static</strong></td><td class="px-4 py-2 text-sm text-gray-700">→ Start screenshot, then Step 3</td></tr></tbody></table> <strong class="font-semibold">Start screenshot for non-build projects</strong> (run_in_background: true):</p><p class="my-4 text-gray-700 leading-relaxed">For directory source (<code class="px-1.5 py-0.5 text-sm text-primary-700 bg-primary-50 rounded font-mono border border-primary-200">--dir</code>): <div class="relative group my-6"> <div class="absolute top-2 right-2 px-2 py-1 text-xs font-medium text-gray-400 bg-gray-800 rounded">bash</div> <pre class="bg-gray-900 text-gray-100 p-4 rounded-lg overflow-x-auto text-sm leading-relaxed"><code class="language-bash">node {skill_path}/scripts/utils/generate-screenshot.mjs --dir {publish_target} --hub {hub}</code></pre> </div></p><p class="my-4 text-gray-700 leading-relaxed">For single file source (<code class="px-1.5 py-0.5 text-sm text-primary-700 bg-primary-50 rounded font-mono border border-primary-200">--file</code>): <div class="relative group my-6"> <div class="absolute top-2 right-2 px-2 py-1 text-xs font-medium text-gray-400 bg-gray-800 rounded">bash</div> <pre class="bg-gray-900 text-gray-100 p-4 rounded-lg overflow-x-auto text-sm leading-relaxed"><code class="language-bash">node {skill_path}/scripts/utils/generate-screenshot.mjs --file {publish_target} --hub {hub}</code></pre> </div></p><p class="my-4 text-gray-700 leading-relaxed">IMPORTANT: Use <code class="px-1.5 py-0.5 text-sm text-primary-700 bg-primary-50 rounded font-mono border border-primary-200">--file</code> when the source is a single HTML file, and <code class="px-1.5 py-0.5 text-sm text-primary-700 bg-primary-50 rounded font-mono border border-primary-200">--dir</code> when it is a directory. The flag must match the <code class="px-1.5 py-0.5 text-sm text-primary-700 bg-primary-50 rounded font-mono border border-primary-200">source.type</code> in the publish config so that both scripts calculate the same hash for the screenshot result file.</p><p class="my-4 text-gray-700 leading-relaxed"><strong class="font-semibold">After starting the screenshot background task</strong>, use <code class="px-1.5 py-0.5 text-sm text-primary-700 bg-primary-50 rounded font-mono border border-primary-200">TaskOutput</code> (with <code class="px-1.5 py-0.5 text-sm text-primary-700 bg-primary-50 rounded font-mono border border-primary-200">block: false</code>) to check the task output before proceeding. If the output contains "agent-browser is not installed" or "Chromium is not installed": <ul class="my-4 space-y-2"><li class="ml-6 mb-2 text-gray-700 list-decimal">Install agent-browser: <code class="px-1.5 py-0.5 text-sm text-primary-700 bg-primary-50 rounded font-mono border border-primary-200">npm install -g agent-browser && agent-browser install</code></li> <li class="ml-6 mb-2 text-gray-700 list-decimal">Re-run the screenshot command (same command as above, run_in_background: true)</li> <li class="ml-6 mb-2 text-gray-700 list-decimal">Check again with <code class="px-1.5 py-0.5 text-sm text-primary-700 bg-primary-50 rounded font-mono border border-primary-200">TaskOutput</code> (block: false) to confirm it's running</li> </ul> This ensures the screenshot can complete successfully in the background while you continue with metadata analysis.</p><p class="my-4 text-gray-700 leading-relaxed"><hr class="my-8 border-t border-gray-300"></p><p class="my-4 text-gray-700 leading-relaxed"><h2 class="text-2xl font-bold text-gray-900 mt-10 mb-6 border-b border-gray-200 pb-2">Step 2: Build (if needed)</h2></p><p class="my-4 text-gray-700 leading-relaxed">Detect package manager from lock files, build command from package.json scripts.</p><p class="my-4 text-gray-700 leading-relaxed">Use <code class="px-1.5 py-0.5 text-sm text-primary-700 bg-primary-50 rounded font-mono border border-primary-200">AskUserQuestion</code> to confirm: <ul class="my-4 space-y-2"><li class="ml-6 mb-2 text-gray-700 list-disc"><strong class="font-semibold">Pre-built</strong>: "Rebuild or use existing output?"</li> <li class="ml-6 mb-2 text-gray-700 list-disc"><strong class="font-semibold">Buildable</strong>: "Build before publishing?"</li> <li class="ml-6 mb-2 text-gray-700 list-disc"><strong class="font-semibold">Monorepo</strong>: "Which app to publish?"</li> </ul> After build completes, start screenshot in background (same check as Step 1: use <code class="px-1.5 py-0.5 text-sm text-primary-700 bg-primary-50 rounded font-mono border border-primary-200">TaskOutput</code> block: false to verify agent-browser is available, install if needed, then retry), then proceed to Step 3.</p><p class="my-4 text-gray-700 leading-relaxed"><hr class="my-8 border-t border-gray-300"></p><p class="my-4 text-gray-700 leading-relaxed"><h2 class="text-2xl font-bold text-gray-900 mt-10 mb-6 border-b border-gray-200 pb-2">Step 3: Metadata Analysis</h2></p><p class="my-4 text-gray-700 leading-relaxed"><h3 class="text-xl font-semibold text-gray-900 mt-8 mb-4">Extract title</h3> Priority: <code class="px-1.5 py-0.5 text-sm text-primary-700 bg-primary-50 rounded font-mono border border-primary-200"><title></code> → <code class="px-1.5 py-0.5 text-sm text-primary-700 bg-primary-50 rounded font-mono border border-primary-200">og:title</code> → package.json name → first <code class="px-1.5 py-0.5 text-sm text-primary-700 bg-primary-50 rounded font-mono border border-primary-200"><h1></code></p><p class="my-4 text-gray-700 leading-relaxed"><h3 class="text-xl font-semibold text-gray-900 mt-8 mb-4">Generate description (50-150 words, story-style)</h3></p><p class="my-4 text-gray-700 leading-relaxed">Cover: <strong class="font-semibold">Why</strong> (motivation) → <strong class="font-semibold">What</strong> (functionality) → <strong class="font-semibold">Journey</strong> (optional)</p><p class="my-4 text-gray-700 leading-relaxed">Sources: conversation history, README.md, source code, package.json, git log</p><p class="my-4 text-gray-700 leading-relaxed">Guidelines: <ul class="my-4 space-y-2"><li class="ml-6 mb-2 text-gray-700 list-disc">Natural, conversational tone</li> <li class="ml-6 mb-2 text-gray-700 list-disc">Focus on value and story, not technical specs</li> <li class="ml-6 mb-2 text-gray-700 list-disc">Avoid generic "A web app built with React"</li> </ul> <h3 class="text-xl font-semibold text-gray-900 mt-8 mb-4">Extract githubRepo</h3> From git remote or package.json repository field. Convert SSH to HTTPS format.</p><p class="my-4 text-gray-700 leading-relaxed"><h3 class="text-xl font-semibold text-gray-900 mt-8 mb-4">Match tags</h3></p><p class="my-4 text-gray-700 leading-relaxed">Fetch tags: <code class="px-1.5 py-0.5 text-sm text-primary-700 bg-primary-50 rounded font-mono border border-primary-200">node {skill_path}/scripts/utils/fetch-tags.mjs --hub {hub}</code></p><p class="my-4 text-gray-700 leading-relaxed"><table class="w-full my-6 border-collapse"><thead><tr><th class="bg-gray-100 px-4 py-2 text-left text-sm font-semibold text-gray-900 border-b-2 border-gray-300">Tag Type</th><th class="bg-gray-100 px-4 py-2 text-left text-sm font-semibold text-gray-900 border-b-2 border-gray-300">Match Method</th></tr></thead><tbody><tr class="border-b border-gray-200 hover:bg-gray-50"><td class="px-4 py-2 text-sm text-gray-700"><strong class="font-semibold">techStackTags</strong></td><td class="px-4 py-2 text-sm text-gray-700">Match package.json dependencies against tag slug</td></tr><tr class="border-b border-gray-200 hover:bg-gray-50"><td class="px-4 py-2 text-sm text-gray-700"><strong class="font-semibold">platformTags</strong></td><td class="px-4 py-2 text-sm text-gray-700">From conversation context (Claude Code, Cursor, etc.)</td></tr><tr class="border-b border-gray-200 hover:bg-gray-50"><td class="px-4 py-2 text-sm text-gray-700"><strong class="font-semibold">modelTags</strong></td><td class="px-4 py-2 text-sm text-gray-700">From conversation context (Claude 3.5 Sonnet, GPT-4, etc.)</td></tr><tr class="border-b border-gray-200 hover:bg-gray-50"><td class="px-4 py-2 text-sm text-gray-700"><strong class="font-semibold">categoryTags</strong></td><td class="px-4 py-2 text-sm text-gray-700">Infer from project (game libs → game, charts → viz)</td></tr></tbody></table> <hr class="my-8 border-t border-gray-300"></p><p class="my-4 text-gray-700 leading-relaxed"><h2 class="text-2xl font-bold text-gray-900 mt-10 mb-6 border-b border-gray-200 pb-2">Step 4: Confirm Publish</h2></p><p class="my-4 text-gray-700 leading-relaxed">Display metadata and use <code class="px-1.5 py-0.5 text-sm text-primary-700 bg-primary-50 rounded font-mono border border-primary-200">AskUserQuestion</code>:</p><p class="my-4 text-gray-700 leading-relaxed"><div class="relative group my-6"> <div class="absolute top-2 right-2 px-2 py-1 text-xs font-medium text-gray-400 bg-gray-800 rounded">text</div> <pre class="bg-gray-900 text-gray-100 p-4 rounded-lg overflow-x-auto text-sm leading-relaxed"><code class="language-text">Publishing to MyVibe: ────────────────────── Title: [value] Description: [50-150 word story] GitHub: [URL or "Not detected"] Cover Image: [Will be included if ready] Tags: Tech Stack: [...] | Platform: [...] | Category: [...] | Model: [...]</code></pre> </div></p><p class="my-4 text-gray-700 leading-relaxed">Options: "Publish" / "Edit details"</p><p class="my-4 text-gray-700 leading-relaxed"><hr class="my-8 border-t border-gray-300"></p><p class="my-4 text-gray-700 leading-relaxed"><h2 class="text-2xl font-bold text-gray-900 mt-10 mb-6 border-b border-gray-200 pb-2">Step 5: Execute Publish</h2></p><p class="my-4 text-gray-700 leading-relaxed"><strong class="font-semibold">Check dependencies</strong>: If <code class="px-1.5 py-0.5 text-sm text-primary-700 bg-primary-50 rounded font-mono border border-primary-200">scripts/node_modules</code> missing, run <code class="px-1.5 py-0.5 text-sm text-primary-700 bg-primary-50 rounded font-mono border border-primary-200">npm install</code> first. The publish script automatically reads the screenshot result file. Execute publish directly:</p><p class="my-4 text-gray-700 leading-relaxed">Pass config via stdin:</p><p class="my-4 text-gray-700 leading-relaxed"><div class="relative group my-6"> <div class="absolute top-2 right-2 px-2 py-1 text-xs font-medium text-gray-400 bg-gray-800 rounded">bash</div> <pre class="bg-gray-900 text-gray-100 p-4 rounded-lg overflow-x-auto text-sm leading-relaxed"><code class="language-bash">node {skill_path}/scripts/publish.mjs --config-stdin <<'EOF' { "source": { "type": "dir", "path": "./dist", "did": "z2qaXXXX" }, "hub": "https://www.myvibe.so", "metadata": { "title": "My App", "description": "Story description here", "visibility": "public", "githubRepo": "https://github.com/user/repo", "platformTags": [1, 2], "techStackTags": [3, 4], "categoryTags": [5], "modelTags": [6] } } EOF</code></pre> </div> <ul class="my-4 space-y-2"><li class="ml-6 mb-2 text-gray-700 list-disc"><code class="px-1.5 py-0.5 text-sm text-primary-700 bg-primary-50 rounded font-mono border border-primary-200">did</code> optional - for explicit version updates</li> <li class="ml-6 mb-2 text-gray-700 list-disc"><code class="px-1.5 py-0.5 text-sm text-primary-700 bg-primary-50 rounded font-mono border border-primary-200">coverImage</code> auto-read from <code class="px-1.5 py-0.5 text-sm text-primary-700 bg-primary-50 rounded font-mono border border-primary-200">/tmp/myvibe-screenshot-{hash}.json</code></li> <li class="ml-6 mb-2 text-gray-700 list-disc">Screenshot result file cleaned up after publish</li> </ul> <hr class="my-8 border-t border-gray-300"></p><p class="my-4 text-gray-700 leading-relaxed"><h2 class="text-2xl font-bold text-gray-900 mt-10 mb-6 border-b border-gray-200 pb-2">Step 6: Return Result</h2></p><p class="my-4 text-gray-700 leading-relaxed">After publish script completes, <strong class="font-semibold">check the script output</strong> for these messages:</p><p class="my-4 text-gray-700 leading-relaxed"><h3 class="text-xl font-semibold text-gray-900 mt-8 mb-4">Success Message</h3> Always include the Vibe URL in your response: <div class="relative group my-6"> <div class="absolute top-2 right-2 px-2 py-1 text-xs font-medium text-gray-400 bg-gray-800 rounded">text</div> <pre class="bg-gray-900 text-gray-100 p-4 rounded-lg overflow-x-auto text-sm leading-relaxed"><code class="language-text">Published successfully! 🔗 [URL]</code></pre> </div></p><p class="my-4 text-gray-700 leading-relaxed"><h3 class="text-xl font-semibold text-gray-900 mt-8 mb-4">Upgrade Prompt (Important)</h3> The script prints an upgrade prompt when updating an existing Vibe without version history enabled: <div class="relative group my-6"> <div class="absolute top-2 right-2 px-2 py-1 text-xs font-medium text-gray-400 bg-gray-800 rounded">text</div> <pre class="bg-gray-900 text-gray-100 p-4 rounded-lg overflow-x-auto text-sm leading-relaxed"><code class="language-text">📦 Previous version overwritten. Want to keep version history? Upgrade to Creator → {hub}/pricing</code></pre> </div></p><p class="my-4 text-gray-700 leading-relaxed"><strong class="font-semibold">You MUST include this upgrade information in your response to the user if the script output contains it.</strong> This helps free-tier users discover the version history feature.</p><p class="my-4 text-gray-700 leading-relaxed"><hr class="my-8 border-t border-gray-300"></p><p class="my-4 text-gray-700 leading-relaxed"><h2 class="text-2xl font-bold text-gray-900 mt-10 mb-6 border-b border-gray-200 pb-2">Error Handling</h2></p><p class="my-4 text-gray-700 leading-relaxed"><table class="w-full my-6 border-collapse"><thead><tr><th class="bg-gray-100 px-4 py-2 text-left text-sm font-semibold text-gray-900 border-b-2 border-gray-300">Error</th><th class="bg-gray-100 px-4 py-2 text-left text-sm font-semibold text-gray-900 border-b-2 border-gray-300">Action</th></tr></thead><tbody><tr class="border-b border-gray-200 hover:bg-gray-50"><td class="px-4 py-2 text-sm text-gray-700">Dependencies missing</td><td class="px-4 py-2 text-sm text-gray-700">Run npm install in scripts directory</td></tr><tr class="border-b border-gray-200 hover:bg-gray-50"><td class="px-4 py-2 text-sm text-gray-700">401/403 Auth error</td><td class="px-4 py-2 text-sm text-gray-700">Token auto-cleared, re-run to authorize</td></tr><tr class="border-b border-gray-200 hover:bg-gray-50"><td class="px-4 py-2 text-sm text-gray-700">Build failed</td><td class="px-4 py-2 text-sm text-gray-700">Analyze error, offer fix, or publish source as-is</td></tr><tr class="border-b border-gray-200 hover:bg-gray-50"><td class="px-4 py-2 text-sm text-gray-700">Screenshot failed</td><td class="px-4 py-2 text-sm text-gray-700">Skip coverImage, proceed without it</td></tr><tr class="border-b border-gray-200 hover:bg-gray-50"><td class="px-4 py-2 text-sm text-gray-700">agent-browser missing</td><td class="px-4 py-2 text-sm text-gray-700">Run npm install -g agent-browser && agent-browser install</td></tr><tr class="border-b border-gray-200 hover:bg-gray-50"><td class="px-4 py-2 text-sm text-gray-700">Script execution failed (network/sandbox)</td><td class="px-4 py-2 text-sm text-gray-700">Check if network permissions are enabled. Add sandbox_permissions=require_escalated and retry</td></tr><tr class="border-b border-gray-200 hover:bg-gray-50"><td class="px-4 py-2 text-sm text-gray-700">Private mode is only available for Creator and Studio users</td><td class="px-4 py-2 text-sm text-gray-700">See "Private Mode Error Handling" below</td></tr></tbody></table> <h3 class="text-xl font-semibold text-gray-900 mt-8 mb-4">Private Mode Error Handling</h3></p><p class="my-4 text-gray-700 leading-relaxed">When publishing with <code class="px-1.5 py-0.5 text-sm text-primary-700 bg-primary-50 rounded font-mono border border-primary-200">visibility: private</code> fails with "Private mode is only available for Creator and Studio users", use <code class="px-1.5 py-0.5 text-sm text-primary-700 bg-primary-50 rounded font-mono border border-primary-200">AskUserQuestion</code> to let the user choose:</p><p class="my-4 text-gray-700 leading-relaxed"><strong class="font-semibold">Question:</strong> "Private publishing requires a Creator or Studio subscription. How would you like to proceed?"</p><p class="my-4 text-gray-700 leading-relaxed"><table class="w-full my-6 border-collapse"><thead><tr><th class="bg-gray-100 px-4 py-2 text-left text-sm font-semibold text-gray-900 border-b-2 border-gray-300">Option</th><th class="bg-gray-100 px-4 py-2 text-left text-sm font-semibold text-gray-900 border-b-2 border-gray-300">Label</th><th class="bg-gray-100 px-4 py-2 text-left text-sm font-semibold text-gray-900 border-b-2 border-gray-300">Description</th></tr></thead><tbody><tr class="border-b border-gray-200 hover:bg-gray-50"><td class="px-4 py-2 text-sm text-gray-700">1</td><td class="px-4 py-2 text-sm text-gray-700">Publish as Public</td><td class="px-4 py-2 text-sm text-gray-700">Your Vibe will be visible to everyone. You can change this later after upgrading.</td></tr><tr class="border-b border-gray-200 hover:bg-gray-50"><td class="px-4 py-2 text-sm text-gray-700">2</td><td class="px-4 py-2 text-sm text-gray-700">View Upgrade Options</td><td class="px-4 py-2 text-sm text-gray-700">Open the pricing page to explore subscription plans with private publishing.</td></tr></tbody></table> <strong class="font-semibold">Actions based on selection:</strong> <ul class="my-4 space-y-2"><li class="ml-6 mb-2 text-gray-700 list-disc"><strong class="font-semibold">Option 1</strong>: Re-run publish with <code class="px-1.5 py-0.5 text-sm text-primary-700 bg-primary-50 rounded font-mono border border-primary-200">visibility: "public"</code>, inform user the Vibe is now public</li> <li class="ml-6 mb-2 text-gray-700 list-disc"><strong class="font-semibold">Option 2</strong>: Display the pricing URL <code class="px-1.5 py-0.5 text-sm text-primary-700 bg-primary-50 rounded font-mono border border-primary-200">{hub}/pricing</code> and stop the publish flow</li> </ul> <h2 class="text-2xl font-bold text-gray-900 mt-10 mb-6 border-b border-gray-200 pb-2">Notes</h2> <ul class="my-4 space-y-2"><li class="ml-6 mb-2 text-gray-700 list-disc">Always analyze content for meaningful title/description - never use directory names</li> <li class="ml-6 mb-2 text-gray-700 list-disc">Confirm with user before publishing</li> <li class="ml-6 mb-2 text-gray-700 list-disc">Default hub: https://www.myvibe.so/</li> <li class="ml-6 mb-2 text-gray-700 list-disc">Tags fetched fresh from API on each publish</li> <li class="ml-6 mb-2 text-gray-700 list-disc">Publish history in <code class="px-1.5 py-0.5 text-sm text-primary-700 bg-primary-50 rounded font-mono border border-primary-200">~/.myvibe/published.yaml</code> for auto version updates</li> <li class="ml-6 mb-2 text-gray-700 list-disc">Use <code class="px-1.5 py-0.5 text-sm text-primary-700 bg-primary-50 rounded font-mono border border-primary-200">--new</code> to force new Vibe instead of updating</li> </ul></p></div> </div> </div> <!-- Installation --> <section class="card" aria-labelledby="installation-heading" data-astro-cid-jrlgpo3w> <h2 id="installation-heading" class="text-2xl font-bold text-gray-900 mb-4" data-astro-cid-jrlgpo3w>Installation</h2> <div class="code-block-container relative group " data-astro-cid-i4kugh4e> <div class="flex items-center justify-between px-4 py-2 bg-gray-800 border-b border-gray-700 rounded-t-lg" data-astro-cid-i4kugh4e> <span class="text-sm text-gray-300 font-mono" data-astro-cid-i4kugh4e>Terminal</span> <span class="text-xs text-gray-500 uppercase" data-astro-cid-i4kugh4e>bash</span> </div> <div class="relative" data-astro-cid-i4kugh4e> <pre class="!mt-0 !rounded-t-none" data-astro-cid-i4kugh4e><code id="code-13wslyhcd" class="language-bash" data-astro-cid-i4kugh4e> openclaw install myvibe-skills </code></pre> <!-- Copy Button --> <button class="copy-button absolute top-2 right-2 p-2 bg-gray-700 hover:bg-gray-600 text-gray-300 rounded-lg transition-all duration-200 opacity-0 group-hover:opacity-100 focus:opacity-100" data-code-id="code-13wslyhcd" aria-label="Copy code to clipboard" data-astro-cid-i4kugh4e> <svg class="w-4 h-4" fill="none" stroke="currentColor" viewBox="0 0 24 24" data-astro-cid-i4kugh4e> <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M8 16H6a2 2 0 01-2-2V6a2 2 0 012-2h8a2 2 0 012 2v2m-6 12h8a2 2 0 002-2v-8a2 2 0 00-2-2h-8a2 2 0 00-2 2v8a2 2 0 002 2z" data-astro-cid-i4kugh4e></path> </svg> <span class="copy-text sr-only" data-astro-cid-i4kugh4e>Copy</span> </button> <!-- Copied Indicator --> <div class="copied-indicator absolute top-2 right-14 px-3 py-1.5 bg-green-600 text-white text-sm rounded-lg opacity-0 transition-opacity duration-200 pointer-events-none" data-astro-cid-i4kugh4e> Copied! </div> </div> </div> <script>(function(){const codeId = "code-13wslyhcd"; const copyButton = document.querySelector(`[data-code-id="${codeId}"]`); const copiedIndicator = document.querySelector('.copied-indicator'); if (copyButton) { copyButton.addEventListener('click', async () => { const codeElement = document.getElementById(codeId); const code = codeElement?.textContent || ''; try { await navigator.clipboard.writeText(code); // Show copied state copyButton.classList.add('copied'); copiedIndicator?.classList.remove('opacity-0'); // Reset after 2 seconds setTimeout(() => { copyButton.classList.remove('copied'); copiedIndicator?.classList.add('opacity-0'); }, 2000); } catch (err) { console.error('Failed to copy code:', err); } }); } })();</script> </section> <!-- Verification Command (if available from enhanced data) --> <!-- Code Examples (if available) --> <div class="card" data-astro-cid-cpq6uwpo><h2 class="text-2xl font-bold text-gray-900 mb-6 flex items-center" data-astro-cid-cpq6uwpo><span class="text-2xl mr-2" data-astro-cid-cpq6uwpo>💻</span>Code Examples</h2><div class="space-y-6" data-astro-cid-cpq6uwpo><div class="code-example" data-astro-cid-cpq6uwpo><h3 class="text-lg font-semibold text-gray-900 mb-2" data-astro-cid-cpq6uwpo>/myvibe:myvibe-publish --dir ./dist --did z2qaXXX # Update specific Vibe</h3><div class="relative" data-astro-cid-cpq6uwpo><div class="flex items-center justify-between bg-gray-800 text-gray-300 px-4 py-2 rounded-t-lg text-sm" data-astro-cid-cpq6uwpo><span class="font-mono" data-astro-cid-cpq6uwpo>myvibemyvibe-publish---dir-dist---did-z2qaxxx--update-specific-vibe.txt</span><button class="copy-btn px-3 py-1 bg-primary-600 hover:bg-primary-700 text-white rounded text-xs font-medium transition-colors" data-astro-cid-cpq6uwpo> Copy Code </button></div><pre class="bg-gray-900 text-gray-100 p-4 rounded-b-lg overflow-x-auto text-sm leading-relaxed" data-astro-cid-cpq6uwpo><code class="language-text" data-astro-cid-cpq6uwpo>## Options | Option | Alias | Description | |--------|-------|-------------| | `--file <path>` | `-f` | Path to HTML file or ZIP archive | | `--dir <path>` | `-d` | Directory to compress and publish | | `--url <url>` | `-u` | URL to import and publish | | `--hub <url>` | `-h` | MyVibe URL (default: https://www.myvibe.so/) | | `--title <title>` | `-t` | Project title | | `--desc <desc>` | | Project description | | `--visibility <vis>` | `-v` | Visibility: public or private (default: public) | | `--did <did>` | | Vibe DID for version update (overrides auto-detection) | | `--new` | | Force create new Vibe, ignore publish history | ## Workflow Overview 1. **Detect Project Type** → if no build needed, start screenshot in background 2. **Build** (if needed) → then start screenshot in background 3. **Metadata Analysis** → extract title, description, tags 4. **Confirm Publish** → show metadata, get user confirmation 5. **Execute Publish** → script auto-reads screenshot result 6. **Return Result** → show publish URL **First tool call - execute in parallel:** - `Read`: source file or main files in directory - `Bash`: `git remote get-url origin 2>/dev/null || echo "Not a git repo"` - `Bash`: `node {skill_path}/scripts/utils/fetch-tags.mjs --hub {hub}` --- ## Step 1: Detect Project Type | Check | Project Type | Next Step | |-------|-------------|-----------| | `--file` with HTML/ZIP | **Single File** | → Start screenshot, then Step 3 | | Has `dist/`, `build/`, or `out/` with index.html | **Pre-built** | → Step 2 (confirm rebuild) | | Has `package.json` with build script, no output | **Buildable** | → Step 2 (build first) | | Multiple `package.json` or workspace config | **Monorepo** | → Step 2 (select app) | | Has `index.html` at root, no `package.json` | **Static** | → Start screenshot, then Step 3 | **Start screenshot for non-build projects** (run_in_background: true): For directory source (`--dir`):</code></pre></div></div><div class="code-example" data-astro-cid-cpq6uwpo><h3 class="text-lg font-semibold text-gray-900 mb-2" data-astro-cid-cpq6uwpo>node {skill_path}/scripts/utils/generate-screenshot.mjs --file {publish_target} --hub {hub}</h3><div class="relative" data-astro-cid-cpq6uwpo><div class="flex items-center justify-between bg-gray-800 text-gray-300 px-4 py-2 rounded-t-lg text-sm" data-astro-cid-cpq6uwpo><span class="font-mono" data-astro-cid-cpq6uwpo>node-skillpathscriptsutilsgenerate-screenshotmjs---file-publishtarget---hub-hub.txt</span><button class="copy-btn px-3 py-1 bg-primary-600 hover:bg-primary-700 text-white rounded text-xs font-medium transition-colors" data-astro-cid-cpq6uwpo> Copy Code </button></div><pre class="bg-gray-900 text-gray-100 p-4 rounded-b-lg overflow-x-auto text-sm leading-relaxed" data-astro-cid-cpq6uwpo><code class="language-text" data-astro-cid-cpq6uwpo>IMPORTANT: Use `--file` when the source is a single HTML file, and `--dir` when it is a directory. The flag must match the `source.type` in the publish config so that both scripts calculate the same hash for the screenshot result file. **After starting the screenshot background task**, use `TaskOutput` (with `block: false`) to check the task output before proceeding. If the output contains "agent-browser is not installed" or "Chromium is not installed": 1. Install agent-browser: `npm install -g agent-browser && agent-browser install` 2. Re-run the screenshot command (same command as above, run_in_background: true) 3. Check again with `TaskOutput` (block: false) to confirm it's running This ensures the screenshot can complete successfully in the background while you continue with metadata analysis. --- ## Step 2: Build (if needed) Detect package manager from lock files, build command from package.json scripts. Use `AskUserQuestion` to confirm: - **Pre-built**: "Rebuild or use existing output?" - **Buildable**: "Build before publishing?" - **Monorepo**: "Which app to publish?" After build completes, start screenshot in background (same check as Step 1: use `TaskOutput` block: false to verify agent-browser is available, install if needed, then retry), then proceed to Step 3. --- ## Step 3: Metadata Analysis ### Extract title Priority: `<title>` → `og:title` → package.json name → first `<h1>` ### Generate description (50-150 words, story-style) Cover: **Why** (motivation) → **What** (functionality) → **Journey** (optional) Sources: conversation history, README.md, source code, package.json, git log Guidelines: - Natural, conversational tone - Focus on value and story, not technical specs - Avoid generic "A web app built with React" ### Extract githubRepo From git remote or package.json repository field. Convert SSH to HTTPS format. ### Match tags Fetch tags: `node {skill_path}/scripts/utils/fetch-tags.mjs --hub {hub}` | Tag Type | Match Method | |----------|--------------| | **techStackTags** | Match package.json dependencies against tag slug | | **platformTags** | From conversation context (Claude Code, Cursor, etc.) | | **modelTags** | From conversation context (Claude 3.5 Sonnet, GPT-4, etc.) | | **categoryTags** | Infer from project (game libs → game, charts → viz) | --- ## Step 4: Confirm Publish Display metadata and use `AskUserQuestion`:</code></pre></div></div><div class="code-example" data-astro-cid-cpq6uwpo><h3 class="text-lg font-semibold text-gray-900 mb-2" data-astro-cid-cpq6uwpo>Tags: Tech Stack: [...] | Platform: [...] | Category: [...] | Model: [...]</h3><div class="relative" data-astro-cid-cpq6uwpo><div class="flex items-center justify-between bg-gray-800 text-gray-300 px-4 py-2 rounded-t-lg text-sm" data-astro-cid-cpq6uwpo><span class="font-mono" data-astro-cid-cpq6uwpo>tags-tech-stack---platform---category---model-.txt</span><button class="copy-btn px-3 py-1 bg-primary-600 hover:bg-primary-700 text-white rounded text-xs font-medium transition-colors" data-astro-cid-cpq6uwpo> Copy Code </button></div><pre class="bg-gray-900 text-gray-100 p-4 rounded-b-lg overflow-x-auto text-sm leading-relaxed" data-astro-cid-cpq6uwpo><code class="language-text" data-astro-cid-cpq6uwpo>Options: "Publish" / "Edit details" --- ## Step 5: Execute Publish **Check dependencies**: If `scripts/node_modules` missing, run `npm install` first. The publish script automatically reads the screenshot result file. Execute publish directly: Pass config via stdin:</code></pre></div></div><div class="code-example" data-astro-cid-cpq6uwpo><h3 class="text-lg font-semibold text-gray-900 mb-2" data-astro-cid-cpq6uwpo>EOF</h3><div class="relative" data-astro-cid-cpq6uwpo><div class="flex items-center justify-between bg-gray-800 text-gray-300 px-4 py-2 rounded-t-lg text-sm" data-astro-cid-cpq6uwpo><span class="font-mono" data-astro-cid-cpq6uwpo>eof.txt</span><button class="copy-btn px-3 py-1 bg-primary-600 hover:bg-primary-700 text-white rounded text-xs font-medium transition-colors" data-astro-cid-cpq6uwpo> Copy Code </button></div><pre class="bg-gray-900 text-gray-100 p-4 rounded-b-lg overflow-x-auto text-sm leading-relaxed" data-astro-cid-cpq6uwpo><code class="language-text" data-astro-cid-cpq6uwpo>- `did` optional - for explicit version updates - `coverImage` auto-read from `/tmp/myvibe-screenshot-{hash}.json` - Screenshot result file cleaned up after publish --- ## Step 6: Return Result After publish script completes, **check the script output** for these messages: ### Success Message Always include the Vibe URL in your response:</code></pre></div></div><div class="code-example" data-astro-cid-cpq6uwpo><h3 class="text-lg font-semibold text-gray-900 mb-2" data-astro-cid-cpq6uwpo>🔗 [URL]</h3><div class="relative" data-astro-cid-cpq6uwpo><div class="flex items-center justify-between bg-gray-800 text-gray-300 px-4 py-2 rounded-t-lg text-sm" data-astro-cid-cpq6uwpo><span class="font-mono" data-astro-cid-cpq6uwpo>-url.txt</span><button class="copy-btn px-3 py-1 bg-primary-600 hover:bg-primary-700 text-white rounded text-xs font-medium transition-colors" data-astro-cid-cpq6uwpo> Copy Code </button></div><pre class="bg-gray-900 text-gray-100 p-4 rounded-b-lg overflow-x-auto text-sm leading-relaxed" data-astro-cid-cpq6uwpo><code class="language-text" data-astro-cid-cpq6uwpo>### Upgrade Prompt (Important) The script prints an upgrade prompt when updating an existing Vibe without version history enabled:</code></pre></div></div><div class="code-example" data-astro-cid-cpq6uwpo><div class="relative" data-astro-cid-cpq6uwpo><div class="flex items-center justify-between bg-gray-800 text-gray-300 px-4 py-2 rounded-t-lg text-sm" data-astro-cid-cpq6uwpo><span class="font-mono" data-astro-cid-cpq6uwpo>example.sh</span><button class="copy-btn px-3 py-1 bg-primary-600 hover:bg-primary-700 text-white rounded text-xs font-medium transition-colors" data-astro-cid-cpq6uwpo> Copy Code </button></div><pre class="bg-gray-900 text-gray-100 p-4 rounded-b-lg overflow-x-auto text-sm leading-relaxed" data-astro-cid-cpq6uwpo><code class="language-bash" data-astro-cid-cpq6uwpo>/myvibe:myvibe-publish --file ./dist.zip # Publish ZIP /myvibe:myvibe-publish --file ./index.html # Publish HTML /myvibe:myvibe-publish --dir ./dist # Publish directory /myvibe:myvibe-publish --url https://example.com/app # Import from URL /myvibe:myvibe-publish --dir ./dist --new # Force new Vibe /myvibe:myvibe-publish --dir ./dist --did z2qaXXX # Update specific Vibe</code></pre></div></div><div class="code-example" data-astro-cid-cpq6uwpo><div class="relative" data-astro-cid-cpq6uwpo><div class="flex items-center justify-between bg-gray-800 text-gray-300 px-4 py-2 rounded-t-lg text-sm" data-astro-cid-cpq6uwpo><span class="font-mono" data-astro-cid-cpq6uwpo>example.txt</span><button class="copy-btn px-3 py-1 bg-primary-600 hover:bg-primary-700 text-white rounded text-xs font-medium transition-colors" data-astro-cid-cpq6uwpo> Copy Code </button></div><pre class="bg-gray-900 text-gray-100 p-4 rounded-b-lg overflow-x-auto text-sm leading-relaxed" data-astro-cid-cpq6uwpo><code class="language-text" data-astro-cid-cpq6uwpo>Publishing to MyVibe: ────────────────────── Title: [value] Description: [50-150 word story] GitHub: [URL or "Not detected"] Cover Image: [Will be included if ready] Tags: Tech Stack: [...] | Platform: [...] | Category: [...] | Model: [...]</code></pre></div></div><div class="code-example" data-astro-cid-cpq6uwpo><div class="relative" data-astro-cid-cpq6uwpo><div class="flex items-center justify-between bg-gray-800 text-gray-300 px-4 py-2 rounded-t-lg text-sm" data-astro-cid-cpq6uwpo><span class="font-mono" data-astro-cid-cpq6uwpo>example.sh</span><button class="copy-btn px-3 py-1 bg-primary-600 hover:bg-primary-700 text-white rounded text-xs font-medium transition-colors" data-astro-cid-cpq6uwpo> Copy Code </button></div><pre class="bg-gray-900 text-gray-100 p-4 rounded-b-lg overflow-x-auto text-sm leading-relaxed" data-astro-cid-cpq6uwpo><code class="language-bash" data-astro-cid-cpq6uwpo>node {skill_path}/scripts/publish.mjs --config-stdin <<'EOF' { "source": { "type": "dir", "path": "./dist", "did": "z2qaXXXX" }, "hub": "https://www.myvibe.so", "metadata": { "title": "My App", "description": "Story description here", "visibility": "public", "githubRepo": "https://github.com/user/repo", "platformTags": [1, 2], "techStackTags": [3, 4], "categoryTags": [5], "modelTags": [6] } } EOF</code></pre></div></div></div></div> <!-- Configuration Table (if available) --> <!-- Requirements --> <!-- Code Example --> <!-- Testing Notes --> <!-- Tags --> <div class="card" data-astro-cid-jrlgpo3w> <h2 class="text-2xl font-bold text-gray-900 mb-4" data-astro-cid-jrlgpo3w>Tags</h2> <div class="flex flex-wrap gap-2" data-astro-cid-jrlgpo3w> <span class="px-3 py-1.5 text-sm text-gray-600 bg-gray-50 rounded-lg border border-gray-200" data-astro-cid-jrlgpo3w> #web_and-frontend-development </span> </div> </div> </div> <!-- Sidebar --> <div class="space-y-6" data-astro-cid-jrlgpo3w> <!-- Quick Info --> <div class="card" data-astro-cid-jrlgpo3w> <h3 class="font-semibold text-gray-900 mb-4" data-astro-cid-jrlgpo3w>Quick Info</h3> <div class="space-y-3 text-sm" data-astro-cid-jrlgpo3w> <div class="flex justify-between" data-astro-cid-jrlgpo3w> <span class="text-gray-600" data-astro-cid-jrlgpo3w>Category</span> <span class="font-medium text-gray-900" data-astro-cid-jrlgpo3w>Development</span> </div> <div class="flex justify-between" data-astro-cid-jrlgpo3w> <span class="text-gray-600" data-astro-cid-jrlgpo3w>Model</span> <span class="font-medium text-gray-900" data-astro-cid-jrlgpo3w>Claude 3.5</span> </div> <div class="flex justify-between" data-astro-cid-jrlgpo3w> <span class="text-gray-600" data-astro-cid-jrlgpo3w>Complexity</span> <span class="font-medium text-gray-900" data-astro-cid-jrlgpo3w>One-Click</span> </div> <div class="flex justify-between" data-astro-cid-jrlgpo3w> <span class="text-gray-600" data-astro-cid-jrlgpo3w>Author</span> <span class="font-medium text-gray-900" data-astro-cid-jrlgpo3w>zhuzhuyule</span> </div> <div class="flex justify-between" data-astro-cid-jrlgpo3w> <span class="text-gray-600" data-astro-cid-jrlgpo3w>Last Updated</span> <span class="font-medium text-gray-900" data-astro-cid-jrlgpo3w>3/10/2026</span> </div> </div> </div> <!-- Model Badge --> <div class="card bg-gradient-to-br from-blue-50 to-indigo-50 border-blue-100" data-astro-cid-jrlgpo3w> <div class="flex items-center justify-between" data-astro-cid-jrlgpo3w> <div class="flex items-center space-x-3" data-astro-cid-jrlgpo3w> <div class="text-3xl" data-astro-cid-jrlgpo3w>🚀</div> <div data-astro-cid-jrlgpo3w> <div class="text-sm text-gray-600" data-astro-cid-jrlgpo3w>Optimized for</div> <div class="font-semibold text-gray-900" data-astro-cid-jrlgpo3w>Claude 3.5</div> </div> </div> <span class="inline-flex items-center gap-1.5 px-2.5 py-1 text-xs font-medium rounded-lg bg-purple-50 text-purple-700 border border-purple-200 hover:bg-purple-100 transition-colors" title="Optimized for Claude 3.5 Sonnet" data-astro-cid-3xlfahoe> <span data-astro-cid-3xlfahoe>🧠</span> </span> </div> </div> <!-- Install CTA --> <div class="card bg-gradient-to-br from-primary-500 to-primary-600 text-white border-0" data-astro-cid-jrlgpo3w> <h3 class="font-semibold text-lg mb-2" data-astro-cid-jrlgpo3w>Ready to Install?</h3> <p class="text-primary-100 text-sm mb-4" data-astro-cid-jrlgpo3w> Get started with this skill in seconds </p> <div class="bg-white/20 backdrop-blur-sm rounded-lg p-3 font-mono text-sm" data-astro-cid-jrlgpo3w> openclaw install myvibe-skills </div> </div> <!-- External Links (if available) --> <div class="card" data-astro-cid-jrlgpo3w> <h3 class="font-semibold text-gray-900 mb-4" data-astro-cid-jrlgpo3w>Resources</h3> <div class="space-y-3" data-astro-cid-jrlgpo3w> <a href="https://github.com/openclaw/skills/tree/main/skills/zhuzhuyule/myvibe-skills/SKILL.md" target="_blank" rel="noopener noreferrer" class="flex items-center justify-between p-3 rounded-lg border border-gray-200 hover:border-primary-300 hover:bg-primary-50 transition-colors" data-astro-cid-jrlgpo3w> <div class="flex items-center space-x-3" data-astro-cid-jrlgpo3w> <div class="text-2xl" data-astro-cid-jrlgpo3w>📂</div> <div data-astro-cid-jrlgpo3w> <div class="font-medium text-gray-900" data-astro-cid-jrlgpo3w>OpenClaw Skills</div> <div class="text-xs text-gray-500" data-astro-cid-jrlgpo3w>View on OpenClaw GitHub</div> </div> </div> <span class="text-primary-600" data-astro-cid-jrlgpo3w>→</span> </a> </div> </div> </div> </div> </div> </section> <section class="section bg-gray-50" data-astro-cid-jrlgpo3w> <div class="container" data-astro-cid-jrlgpo3w> <h2 class="text-2xl font-bold text-gray-900 mb-6" data-astro-cid-jrlgpo3w>Related Skills</h2> <div class="grid md:grid-cols-2 lg:grid-cols-3 gap-6" data-astro-cid-jrlgpo3w> <a href="/skills/4claw/" class="skill-card group block" data-astro-cid-rwasicqo> <!-- Header --> <div class="flex items-start justify-between mb-4" data-astro-cid-rwasicqo> <div class="flex-1" data-astro-cid-rwasicqo> <div class="flex items-center space-x-2 mb-2" data-astro-cid-rwasicqo> <span class="inline-flex items-center px-2 py-0.5 text-xs font-semibold text-green-700 bg-green-50 rounded-full border border-green-200" data-astro-cid-rwasicqo> ✓ Verified </span> <span class="inline-flex items-center px-2 py-0.5 text-xs font-medium text-gray-600 bg-gray-100 rounded-full" data-astro-cid-rwasicqo> 💻 Development </span> </div> <h3 class="text-lg font-semibold text-gray-900 group-hover:text-primary-600 transition-colors" data-astro-cid-rwasicqo> 4claw </h3> </div> </div> <!-- Description --> <p class="text-sm text-gray-600 mb-4 line-clamp-2" data-astro-cid-rwasicqo> 4claw — a moderated imageboard for AI agents. </p> <!-- Badges --> <div class="flex flex-wrap gap-2 mb-4" data-astro-cid-rwasicqo> <span class="inline-flex items-center gap-1.5 px-2.5 py-1 text-xs font-medium rounded-lg bg-purple-50 text-purple-700 border border-purple-200 hover:bg-purple-100 transition-colors" title="Optimized for Claude 3.5 Sonnet" data-astro-cid-3xlfahoe> <span data-astro-cid-3xlfahoe>🧠</span> <span data-astro-cid-3xlfahoe>Claude-Ready</span> </span> <span class="inline-flex items-center px-2.5 py-1 text-xs font-medium rounded-lg class={complexityInfo.level === 1 ? 'text-green-700 bg-green-50' : complexityInfo.level === 2 ? 'text-blue-700 bg-blue-50' : 'text-purple-700 bg-purple-50'}> {complexityInfo.level === 1 ? '⚡' : complexityInfo.level === 2 ? '🔗' : '🧠'} {complexityInfo.name} </span> </div> <!-- Tags --> {skill.tags.length > 0 && ( <div class=" flex flex-wrap gap-1.5 mb-4" data-astro-cid-rwasicqo> <span class="inline-block px-2 py-1 text-xs text-gray-500 bg-gray-50 rounded border border-gray-100" data-astro-cid-rwasicqo> #ai_and-llms </span> </span></div> )} <!-- Footer Stats --> <div class="flex items-center justify-between pt-4 border-t border-gray-100" data-astro-cid-rwasicqo> <div class="flex items-center space-x-4 text-sm text-gray-500" data-astro-cid-rwasicqo> <div class="flex items-center space-x-1" data-astro-cid-rwasicqo> <span class="text-yellow-500" data-astro-cid-rwasicqo>★</span> <span class="font-medium" data-astro-cid-rwasicqo>4.4</span> <span class="text-xs" data-astro-cid-rwasicqo>(118)</span> </div> <div class="flex items-center space-x-1" data-astro-cid-rwasicqo> <span data-astro-cid-rwasicqo>↓</span> <span class="font-medium" data-astro-cid-rwasicqo>4,990</span> </div> </div> <div class="text-xs text-gray-400" data-astro-cid-rwasicqo> v1.0.0 </div> </div> </a> <a href="/skills/aap-passport/" class="skill-card group block" data-astro-cid-rwasicqo> <!-- Header --> <div class="flex items-start justify-between mb-4" data-astro-cid-rwasicqo> <div class="flex-1" data-astro-cid-rwasicqo> <div class="flex items-center space-x-2 mb-2" data-astro-cid-rwasicqo> <span class="inline-flex items-center px-2 py-0.5 text-xs font-semibold text-green-700 bg-green-50 rounded-full border border-green-200" data-astro-cid-rwasicqo> ✓ Verified </span> <span class="inline-flex items-center px-2 py-0.5 text-xs font-medium text-gray-600 bg-gray-100 rounded-full" data-astro-cid-rwasicqo> 💻 Development </span> </div> <h3 class="text-lg font-semibold text-gray-900 group-hover:text-primary-600 transition-colors" data-astro-cid-rwasicqo> Aap Passport </h3> </div> </div> <!-- Description --> <p class="text-sm text-gray-600 mb-4 line-clamp-2" data-astro-cid-rwasicqo> Agent Attestation Protocol - The Reverse Turing Test. </p> <!-- Badges --> <div class="flex flex-wrap gap-2 mb-4" data-astro-cid-rwasicqo> <span class="inline-flex items-center gap-1.5 px-2.5 py-1 text-xs font-medium rounded-lg bg-purple-50 text-purple-700 border border-purple-200 hover:bg-purple-100 transition-colors" title="Optimized for Claude 3.5 Sonnet" data-astro-cid-3xlfahoe> <span data-astro-cid-3xlfahoe>🧠</span> <span data-astro-cid-3xlfahoe>Claude-Ready</span> </span> <span class="inline-flex items-center px-2.5 py-1 text-xs font-medium rounded-lg class={complexityInfo.level === 1 ? 'text-green-700 bg-green-50' : complexityInfo.level === 2 ? 'text-blue-700 bg-blue-50' : 'text-purple-700 bg-purple-50'}> {complexityInfo.level === 1 ? '⚡' : complexityInfo.level === 2 ? '🔗' : '🧠'} {complexityInfo.name} </span> </div> <!-- Tags --> {skill.tags.length > 0 && ( <div class=" flex flex-wrap gap-1.5 mb-4" data-astro-cid-rwasicqo> <span class="inline-block px-2 py-1 text-xs text-gray-500 bg-gray-50 rounded border border-gray-100" data-astro-cid-rwasicqo> #ai_and-llms </span> </span></div> )} <!-- Footer Stats --> <div class="flex items-center justify-between pt-4 border-t border-gray-100" data-astro-cid-rwasicqo> <div class="flex items-center space-x-4 text-sm text-gray-500" data-astro-cid-rwasicqo> <div class="flex items-center space-x-1" data-astro-cid-rwasicqo> <span class="text-yellow-500" data-astro-cid-rwasicqo>★</span> <span class="font-medium" data-astro-cid-rwasicqo>4.3</span> <span class="text-xs" data-astro-cid-rwasicqo>(89)</span> </div> <div class="flex items-center space-x-1" data-astro-cid-rwasicqo> <span data-astro-cid-rwasicqo>↓</span> <span class="font-medium" data-astro-cid-rwasicqo>4,621</span> </div> </div> <div class="text-xs text-gray-400" data-astro-cid-rwasicqo> v1.0.0 </div> </div> </a> <a href="/skills/acestep-lyrics-transcription/" class="skill-card group block" data-astro-cid-rwasicqo> <!-- Header --> <div class="flex items-start justify-between mb-4" data-astro-cid-rwasicqo> <div class="flex-1" data-astro-cid-rwasicqo> <div class="flex items-center space-x-2 mb-2" data-astro-cid-rwasicqo> <span class="inline-flex items-center px-2 py-0.5 text-xs font-semibold text-green-700 bg-green-50 rounded-full border border-green-200" data-astro-cid-rwasicqo> ✓ Verified </span> <span class="inline-flex items-center px-2 py-0.5 text-xs font-medium text-gray-600 bg-gray-100 rounded-full" data-astro-cid-rwasicqo> 💻 Development </span> </div> <h3 class="text-lg font-semibold text-gray-900 group-hover:text-primary-600 transition-colors" data-astro-cid-rwasicqo> Acestep Lyrics Transcription </h3> </div> </div> <!-- Description --> <p class="text-sm text-gray-600 mb-4 line-clamp-2" data-astro-cid-rwasicqo> Transcribe audio to timestamped lyrics using OpenAI Whisper or ElevenLabs Scribe API. </p> <!-- Badges --> <div class="flex flex-wrap gap-2 mb-4" data-astro-cid-rwasicqo> <span class="inline-flex items-center gap-1.5 px-2.5 py-1 text-xs font-medium rounded-lg bg-green-50 text-emerald-700 border border-emerald-200 hover:bg-green-100 transition-colors" title="Works best with GPT-4 and GPT-4 Turbo" data-astro-cid-3xlfahoe> <span data-astro-cid-3xlfahoe>⚡</span> <span data-astro-cid-3xlfahoe>GPT-Optimized</span> </span> <span class="inline-flex items-center px-2.5 py-1 text-xs font-medium rounded-lg class={complexityInfo.level === 1 ? 'text-green-700 bg-green-50' : complexityInfo.level === 2 ? 'text-blue-700 bg-blue-50' : 'text-purple-700 bg-purple-50'}> {complexityInfo.level === 1 ? '⚡' : complexityInfo.level === 2 ? '🔗' : '🧠'} {complexityInfo.name} </span> </div> <!-- Tags --> {skill.tags.length > 0 && ( <div class=" flex flex-wrap gap-1.5 mb-4" data-astro-cid-rwasicqo> <span class="inline-block px-2 py-1 text-xs text-gray-500 bg-gray-50 rounded border border-gray-100" data-astro-cid-rwasicqo> #ai_and-llms </span><span class="inline-block px-2 py-1 text-xs text-gray-500 bg-gray-50 rounded border border-gray-100" data-astro-cid-rwasicqo> #api </span><span class="inline-block px-2 py-1 text-xs text-gray-500 bg-gray-50 rounded border border-gray-100" data-astro-cid-rwasicqo> #script </span> </span></div> )} <!-- Footer Stats --> <div class="flex items-center justify-between pt-4 border-t border-gray-100" data-astro-cid-rwasicqo> <div class="flex items-center space-x-4 text-sm text-gray-500" data-astro-cid-rwasicqo> <div class="flex items-center space-x-1" data-astro-cid-rwasicqo> <span class="text-yellow-500" data-astro-cid-rwasicqo>★</span> <span class="font-medium" data-astro-cid-rwasicqo>3.8</span> <span class="text-xs" data-astro-cid-rwasicqo>(274)</span> </div> <div class="flex items-center space-x-1" data-astro-cid-rwasicqo> <span data-astro-cid-rwasicqo>↓</span> <span class="font-medium" data-astro-cid-rwasicqo>17,648</span> </div> </div> <div class="text-xs text-gray-400" data-astro-cid-rwasicqo> v1.0.0 </div> </div> </a> <a href="/skills/adaptive-suite/" class="skill-card group block" data-astro-cid-rwasicqo> <!-- Header --> <div class="flex items-start justify-between mb-4" data-astro-cid-rwasicqo> <div class="flex-1" data-astro-cid-rwasicqo> <div class="flex items-center space-x-2 mb-2" data-astro-cid-rwasicqo> <span class="inline-flex items-center px-2 py-0.5 text-xs font-semibold text-green-700 bg-green-50 rounded-full border border-green-200" data-astro-cid-rwasicqo> ✓ Verified </span> <span class="inline-flex items-center px-2 py-0.5 text-xs font-medium text-gray-600 bg-gray-100 rounded-full" data-astro-cid-rwasicqo> 💻 Development </span> </div> <h3 class="text-lg font-semibold text-gray-900 group-hover:text-primary-600 transition-colors" data-astro-cid-rwasicqo> Adaptive Suite </h3> </div> </div> <!-- Description --> <p class="text-sm text-gray-600 mb-4 line-clamp-2" data-astro-cid-rwasicqo> A continuously adaptive skill suite that empowers Clawdbot. </p> <!-- Badges --> <div class="flex flex-wrap gap-2 mb-4" data-astro-cid-rwasicqo> <span class="inline-flex items-center gap-1.5 px-2.5 py-1 text-xs font-medium rounded-lg bg-purple-50 text-purple-700 border border-purple-200 hover:bg-purple-100 transition-colors" title="Optimized for Claude 3.5 Sonnet" data-astro-cid-3xlfahoe> <span data-astro-cid-3xlfahoe>🧠</span> <span data-astro-cid-3xlfahoe>Claude-Ready</span> </span> <span class="inline-flex items-center px-2.5 py-1 text-xs font-medium rounded-lg class={complexityInfo.level === 1 ? 'text-green-700 bg-green-50' : complexityInfo.level === 2 ? 'text-blue-700 bg-blue-50' : 'text-purple-700 bg-purple-50'}> {complexityInfo.level === 1 ? '⚡' : complexityInfo.level === 2 ? '🔗' : '🧠'} {complexityInfo.name} </span> </div> <!-- Tags --> {skill.tags.length > 0 && ( <div class=" flex flex-wrap gap-1.5 mb-4" data-astro-cid-rwasicqo> <span class="inline-block px-2 py-1 text-xs text-gray-500 bg-gray-50 rounded border border-gray-100" data-astro-cid-rwasicqo> #ai_and-llms </span><span class="inline-block px-2 py-1 text-xs text-gray-500 bg-gray-50 rounded border border-gray-100" data-astro-cid-rwasicqo> #bot </span> </span></div> )} <!-- Footer Stats --> <div class="flex items-center justify-between pt-4 border-t border-gray-100" data-astro-cid-rwasicqo> <div class="flex items-center space-x-4 text-sm text-gray-500" data-astro-cid-rwasicqo> <div class="flex items-center space-x-1" data-astro-cid-rwasicqo> <span class="text-yellow-500" data-astro-cid-rwasicqo>★</span> <span class="font-medium" data-astro-cid-rwasicqo>4.7</span> <span class="text-xs" data-astro-cid-rwasicqo>(88)</span> </div> <div class="flex items-center space-x-1" data-astro-cid-rwasicqo> <span data-astro-cid-rwasicqo>↓</span> <span class="font-medium" data-astro-cid-rwasicqo>1,625</span> </div> </div> <div class="text-xs text-gray-400" data-astro-cid-rwasicqo> v1.0.0 </div> </div> </a> </div> </div> </section> </main> <footer class="bg-gray-900 text-gray-300"> <div class="container py-16"> <div class="grid grid-cols-2 md:grid-cols-6 gap-8 mb-12"> <!-- Brand Column --> <div class="col-span-2"> <a href="/" class="flex items-center mb-4"> <!-- SVG Logo --> <img src="/logo.svg" alt="AICLawSkills Logo" class="h-10 w-auto rounded-lg"> </a> <p class="text-sm text-gray-400 mb-6 max-w-sm"> The comprehensive skill library for OpenClaw AI automation platform. Explore verified skills and boost your productivity. </p> <!-- Social Proof Stats --> <div class="mb-6 grid grid-cols-3 gap-4"> <div class="text-center"> <div class="text-2xl font-bold text-white">100%</div> <div class="text-xs text-gray-400">Verified Skills</div> </div> <div class="text-center"> <div class="text-2xl font-bold text-white">Free</div> <div class="text-xs text-gray-400">Open Source</div> </div> <div class="text-center"> <div class="text-2xl font-bold text-white">4.8★</div> <div class="text-xs text-gray-400">User Rating</div> </div> </div> <!-- Trust Badges --> <div class="flex flex-wrap gap-3 mb-6"> <div class="flex items-center gap-2 text-xs text-gray-400 bg-gray-800 px-3 py-1 rounded-full"> <span class="text-green-400">✓</span> 100% Verified </div> <div class="flex items-center gap-2 text-xs text-gray-400 bg-gray-800 px-3 py-1 rounded-full"> <span class="text-blue-400">🛡️</span> Security Audited </div> <div class="flex items-center gap-2 text-xs text-gray-400 bg-gray-800 px-3 py-1 rounded-full"> <span class="text-purple-400">⚡</span> Updated Weekly </div> </div> <div class="flex space-x-4"> <a href="https://github.com" class="text-gray-400 hover:text-white transition-colors" aria-label="GitHub"> <svg class="h-5 w-5" fill="currentColor" viewBox="0 0 24 24"> <path fill-rule="evenodd" d="M12 2C6.477 2 2 6.484 2 12.017c0 4.425 2.865 8.18 6.839 9.504.5.092.682-.217.682-.483 0-.237-.008-.868-.013-1.703-2.782.605-3.369-1.343-3.369-1.343-.454-1.158-1.11-1.466-1.11-1.466-.908-.62.069-.608.069-.608 1.003.07 1.531 1.032 1.531 1.032.892 1.53 2.341 1.088 2.91.832.092-.647.35-1.088.636-1.338-2.22-.253-4.555-1.113-4.555-4.951 0-1.093.39-1.988 1.029-2.688-.103-.253-.446-1.272.098-2.65 0 0 .84-.27 2.75 1.026A9.564 9.564 0 0112 6.844c.85.004 1.705.115 2.504.337 1.909-1.296 2.747-1.027 2.747-1.027.546 1.379.202 2.398.1 2.651.64.7 1.028 1.595 1.028 2.688 0 3.848-2.339 4.695-4.566 4.943.359.309.678.92.678 1.855 0 1.338-.012 2.419-.012 2.747 0 .268.18.58.688.482A10.019 10.019 0 0022 12.017C22 6.484 17.522 2 12 2z" clip-rule="evenodd"></path> </svg> </a> <a href="https://twitter.com" class="text-gray-400 hover:text-white transition-colors" aria-label="Twitter"> <svg class="h-5 w-5" fill="currentColor" viewBox="0 0 24 24"> <path d="M8.29 20.251c7.547 0 11.675-6.253 11.675-11.675 0-.178 0-.355-.012-.53A8.348 8.348 0 0022 5.92a8.19 8.19 0 01-2.357.646 4.118 4.118 0 001.804-2.27 8.224 8.224 0 01-2.605.996 4.107 4.107 0 00-6.993 3.743 11.65 11.65 0 01-8.457-4.287 4.106 4.106 0 001.27 5.477A4.072 4.072 0 012.8 9.713v.052a4.105 4.105 0 003.292 4.022 4.095 4.095 0 01-1.853.07 4.108 4.108 0 003.834 2.85A8.233 8.233 0 012 18.407a11.616 11.616 0 006.29 1.84"></path> </svg> </a> </div> </div> <!-- Product Links --> <div> <h3 class="text-sm font-semibold text-white uppercase tracking-wider mb-4">Product</h3> <ul class="space-y-3"> <li> <a href="/skills/" class="text-sm text-gray-400 hover:text-primary-400 transition-colors"> All Skills </a> </li><li> <a href="/skills/#categories" class="text-sm text-gray-400 hover:text-primary-400 transition-colors"> Browse by Category </a> </li><li> <a href="/skill-bundles/" class="text-sm text-gray-400 hover:text-primary-400 transition-colors"> Skill Bundles </a> </li><li> <a href="/skills/category/web-scrapers" class="text-sm text-gray-400 hover:text-primary-400 transition-colors"> Web Scrapers </a> </li><li> <a href="/skills/category/ecommerce" class="text-sm text-gray-400 hover:text-primary-400 transition-colors"> E-commerce </a> </li><li> <a href="/skills/category/social-media" class="text-sm text-gray-400 hover:text-primary-400 transition-colors"> Social Media </a> </li><li> <a href="/skills/category/development" class="text-sm text-gray-400 hover:text-primary-400 transition-colors"> Development </a> </li> </ul> </div> <!-- Resources Links --> <div> <h3 class="text-sm font-semibold text-white uppercase tracking-wider mb-4">Resources</h3> <ul class="space-y-3"> <li> <a href="/get-started/" class="text-sm text-gray-400 hover:text-primary-400 transition-colors"> Documentation </a> </li><li> <a href="/get-started/installation" class="text-sm text-gray-400 hover:text-primary-400 transition-colors"> Installation </a> </li><li> <a href="/get-started/configuration" class="text-sm text-gray-400 hover:text-primary-400 transition-colors"> Configuration </a> </li><li> <a href="/get-started/troubleshooting" class="text-sm text-gray-400 hover:text-primary-400 transition-colors"> Troubleshooting </a> </li> </ul> </div> <!-- Security Links --> <div> <h3 class="text-sm font-semibold text-white uppercase tracking-wider mb-4">🔒 Security</h3> <ul class="space-y-3"> <li> <a href="/security/" class="text-sm text-gray-400 hover:text-primary-400 transition-colors"> Security Overview </a> </li><li> <a href="/security/5-step-hardening-guide" class="text-sm text-gray-400 hover:text-primary-400 transition-colors"> 5-Step Hardening Guide </a> </li><li> <a href="/security/auth-none-dangers" class="text-sm text-gray-400 hover:text-primary-400 transition-colors"> Why auth:none is Dangerous </a> </li><li> <a href="/security/tailscale-guide" class="text-sm text-gray-400 hover:text-primary-400 transition-colors"> Tailscale Setup Guide </a> </li> </ul> </div> <!-- Use Cases --> <div> <h3 class="text-sm font-semibold text-white uppercase tracking-wider mb-4">Use Cases</h3> <ul class="space-y-3"> <li> <a href="/use-cases/ecommerce" class="text-sm text-gray-400 hover:text-primary-400 transition-colors flex items-center"> <span class="mr-2">🛒</span> E-commerce </a> </li><li> <a href="/use-cases/development" class="text-sm text-gray-400 hover:text-primary-400 transition-colors flex items-center"> <span class="mr-2">💻</span> Development </a> </li><li> <a href="/use-cases/content-creation" class="text-sm text-gray-400 hover:text-primary-400 transition-colors flex items-center"> <span class="mr-2">📝</span> Content Creation </a> </li> </ul> </div> </div> <!-- Comparisons Section --> <div class="border-t border-gray-800 pt-8 mb-8"> <h3 class="text-sm font-semibold text-white uppercase tracking-wider mb-4">Comparisons</h3> <div class="flex flex-wrap gap-6"> <a href="/comparisons/" class="text-sm text-gray-400 hover:text-primary-400 transition-colors"> Comparisons </a><a href="/comparisons/skill-comparison/" class="text-sm text-gray-400 hover:text-primary-400 transition-colors"> Skill Comparison </a><a href="/comparisons/cost-comparison/" class="text-sm text-gray-400 hover:text-primary-400 transition-colors"> Cost Analysis </a><a href="/comparisons/architecture-comparison/" class="text-sm text-gray-400 hover:text-primary-400 transition-colors"> Architecture </a><a href="/tools/benchmarks/" class="text-sm text-gray-400 hover:text-primary-400 transition-colors"> Benchmarks </a><a href="/tools/hardware/" class="text-sm text-gray-400 hover:text-primary-400 transition-colors"> Hardware </a> </div> </div> <!-- Bottom Bar --> <div class="border-t border-gray-800 pt-8 flex flex-col md:flex-row justify-between items-center space-y-4 md:space-y-0"> <p class="text-sm text-gray-400"> © 2026 AICLawSkills. All rights reserved. </p> <div class="flex space-x-6"> <a href="/legal/about" class="text-sm text-gray-400 hover:text-white transition-colors"> About </a><a href="/legal/privacy" class="text-sm text-gray-400 hover:text-white transition-colors"> Privacy Policy </a><a href="/legal/terms" class="text-sm text-gray-400 hover:text-white transition-colors"> Terms of Service </a><a href="/legal/contact" class="text-sm text-gray-400 hover:text-white transition-colors"> Contact </a> </div> </div> </div> </footer> <div id="search-backdrop" class="search-backdrop hidden fixed inset-0 bg-black/50 z-50 transition-opacity" data-astro-cid-2eu6zh2g></div> <div id="search-modal" class="search-modal hidden fixed inset-0 z-50 flex items-start justify-center pt-[15vh] px-4" data-astro-cid-2eu6zh2g> <div class="relative w-full max-w-2xl bg-white rounded-xl shadow-2xl border border-gray-200 overflow-hidden" data-astro-cid-2eu6zh2g> <!-- Search Input --> <div class="flex items-center px-4 py-3 border-b border-gray-200" data-astro-cid-2eu6zh2g> <svg class="w-5 h-5 text-gray-400 mr-3" fill="none" stroke="currentColor" viewBox="0 0 24 24" data-astro-cid-2eu6zh2g> <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M21 21l-6-6m2-5a7 7 0 11-14 0 7 7 0 0114 0z" data-astro-cid-2eu6zh2g></path> </svg> <input id="search-input" type="text" placeholder="Search skills... (e.g., 'shopify', 'email', 'automation')" class="flex-1 outline-none text-gray-900 placeholder-gray-400" data-astro-cid-2eu6zh2g> <div class="flex items-center gap-2 ml-2" data-astro-cid-2eu6zh2g> <kbd class="hidden sm:inline-block px-2 py-1 text-xs font-semibold text-gray-400 bg-gray-100 border border-gray-200 rounded" data-astro-cid-2eu6zh2g>ESC</kbd> </div> </div> <!-- Search Results --> <div id="search-results" class="max-h-[50vh] overflow-y-auto" data-astro-cid-2eu6zh2g> <!-- Empty State --> <div id="search-empty" class="px-4 py-8 text-center text-gray-500" data-astro-cid-2eu6zh2g> <svg class="w-12 h-12 mx-auto mb-3 text-gray-300" fill="none" stroke="currentColor" viewBox="0 0 24 24" data-astro-cid-2eu6zh2g> <path stroke-linecap="round" stroke-linejoin="round" stroke-width="1.5" d="M21 21l-6-6m2-5a7 7 0 11-14 0 7 7 0 0114 0z" data-astro-cid-2eu6zh2g></path> </svg> <p class="text-sm font-medium" data-astro-cid-2eu6zh2g>Start typing to search skills</p> <p class="text-xs mt-1 text-gray-400" data-astro-cid-2eu6zh2g>Search by name, category, or tags</p> </div> <!-- Results will be injected here --> <div id="search-results-list" class="py-2 hidden" data-astro-cid-2eu6zh2g></div> </div> <!-- Footer --> <div class="px-4 py-2 border-t border-gray-200 bg-gray-50 flex items-center justify-between text-xs text-gray-500" data-astro-cid-2eu6zh2g> <div class="flex items-center gap-3" data-astro-cid-2eu6zh2g> <span class="flex items-center gap-1" data-astro-cid-2eu6zh2g> <kbd data-astro-cid-2eu6zh2g>↑</kbd><kbd data-astro-cid-2eu6zh2g>↓</kbd> to navigate </span> <span class="flex items-center gap-1" data-astro-cid-2eu6zh2g> <kbd data-astro-cid-2eu6zh2g>↵</kbd> to select </span> </div> <span id="search-count" data-astro-cid-2eu6zh2g>0 results</span> </div> </div> </div> <script> // Skills data will be injected server-side window.SKILLS_DATA = []; </script> </body></html>