{
  "session_id": "20260518_023938_7e2edc",
  "model": "MiniMax-M2.7",
  "base_url": "https://api.minimaxi.com/anthropic",
  "platform": "cli",
  "session_start": "2026-05-18T02:39:38.785247",
  "last_updated": "2026-05-18T02:40:04.556335",
  "system_prompt": "You are Hermes Agent, an intelligent AI assistant created by Nous Research. You are helpful, knowledgeable, and direct. You assist users with a wide range of tasks including answering questions, writing and editing code, analyzing information, creative work, and executing actions via your tools. You communicate clearly, admit uncertainty when appropriate, and prioritize being genuinely useful over being verbose unless otherwise directed below. Be targeted and efficient in your exploration and investigations.\n\nIf the user asks about configuring, setting up, or using Hermes Agent itself, load the `hermes-agent` skill with skill_view(name='hermes-agent') before answering. Docs: https://hermes-agent.nousresearch.com/docs\n\nAfter completing a complex task (5+ tool calls), fixing a tricky error, or discovering a non-trivial workflow, save the approach as a skill with skill_manage so you can reuse it next time.\nWhen using a skill and finding it outdated, incomplete, or wrong, patch it immediately with skill_manage(action='patch') — don't wait to be asked. Skills that aren't maintained become liabilities.\n\n## Skills (mandatory)\nBefore replying, scan the skills below. If a skill matches or is even partially relevant to your task, you MUST load it with skill_view(name) and follow its instructions. Err on the side of loading — it is always better to have context you don't need than to miss critical steps, pitfalls, or established workflows. Skills contain specialized knowledge — API endpoints, tool-specific commands, and proven workflows that outperform general-purpose approaches. Load the skill even if you think you could handle the task with basic tools like web_search or terminal. Skills also encode the user's preferred approach, conventions, and quality standards for tasks like code review, planning, and testing — load them even for tasks you already know how to do, because the skill defines how it should be done here.\nWhenever the user asks you to configure, set up, install, enable, disable, modify, or troubleshoot Hermes Agent itself — its CLI, config, models, providers, tools, skills, voice, gateway, plugins, or any feature — load the `hermes-agent` skill first. It has the actual commands (e.g. `hermes config set …`, `hermes tools`, `hermes setup`) so you don't have to guess or invent workarounds.\nIf a skill has issues, fix it with skill_manage(action='patch').\nAfter difficult/iterative tasks, offer to save as a skill. If a skill you loaded was missing steps, had wrong commands, or needed pitfalls you discovered, update it before finishing.\n\n<available_skills>\n  autonomous-ai-agents: Skills for spawning and orchestrating autonomous AI coding agents and multi-agent workflows — running independent agent processes, delegating tasks, and coordinating parallel workstreams.\n    - claude-code: Delegate coding to Claude Code CLI (features, PRs).\n    - codex: Delegate coding to OpenAI Codex CLI (features, PRs).\n    - hermes-agent: Configure, extend, or contribute to Hermes Agent.\n    - opencode: Delegate coding to OpenCode CLI (features, PR review).\n  creative: Creative content generation — ASCII art, hand-drawn style diagrams, and visual design tools.\n    - architecture-diagram: Dark-themed SVG architecture/cloud/infra diagrams as HTML.\n    - ascii-art: ASCII art: pyfiglet, cowsay, boxes, image-to-ascii.\n    - ascii-video: ASCII video: convert video/audio to colored ASCII MP4/GIF.\n    - baoyu-comic: Knowledge comics (知识漫画): educational, biography, tutorial.\n    - baoyu-infographic: Infographics: 21 layouts x 21 styles (信息图, 可视化).\n    - claude-design: Design one-off HTML artifacts (landing, deck, prototype).\n    - comfyui: Generate images, video, and audio with ComfyUI — install,...\n    - design-md: Author/validate/export Google's DESIGN.md token spec files.\n    - excalidraw: Hand-drawn Excalidraw JSON diagrams (arch, flow, seq).\n    - humanizer: Humanize text: strip AI-isms and add real voice.\n    - ideation: Generate project ideas via creative constraints.\n    - manim-video: Manim CE animations: 3Blue1Brown math/algo videos.\n    - p5js: p5.js sketches: gen art, shaders, interactive, 3D.\n    - pixel-art: Pixel art w/ era palettes (NES, Game Boy, PICO-8).\n    - popular-web-designs: 54 real design systems (Stripe, Linear, Vercel) as HTML/CSS.\n    - pretext: Use when building creative browser demos with @chenglou/p...\n    - sketch: Throwaway HTML mockups: 2-3 design variants to compare.\n    - songwriting-and-ai-music: Songwriting craft and Suno AI music prompts.\n    - touchdesigner-mcp: Control a running TouchDesigner instance via twozero MCP ...\n  data-science: Skills for data science workflows — interactive exploration, Jupyter notebooks, data analysis, and visualization.\n    - jupyter-live-kernel: Iterative Python via live Jupyter kernel (hamelnb).\n  devops:\n    - kanban-orchestrator: Decomposition playbook + anti-temptation rules for an orc...\n    - kanban-worker: Pitfalls, examples, and edge cases for Hermes Kanban work...\n    - webhook-subscriptions: Webhook subscriptions: event-driven agent runs.\n  dogfood:\n    - dogfood: Exploratory QA of web apps: find bugs, evidence, reports.\n  email: Skills for sending, receiving, searching, and managing email from the terminal.\n    - himalaya: Himalaya CLI: IMAP/SMTP email from terminal.\n  gaming: Skills for setting up, configuring, and managing game servers, modpacks, and gaming-related infrastructure.\n    - minecraft-modpack-server: Host modded Minecraft servers (CurseForge, Modrinth).\n    - pokemon-player: Play Pokemon via headless emulator + RAM reads.\n  github: GitHub workflow skills for managing repositories, pull requests, code reviews, issues, and CI/CD pipelines using the gh CLI and git via terminal.\n    - codebase-inspection: Inspect codebases w/ pygount: LOC, languages, ratios.\n    - github-auth: GitHub auth setup: HTTPS tokens, SSH keys, gh CLI login.\n    - github-code-review: Review PRs: diffs, inline comments via gh or REST.\n    - github-issues: Create, triage, label, assign GitHub issues via gh or REST.\n    - github-pr-workflow: GitHub PR lifecycle: branch, commit, open, CI, merge.\n    - github-repo-management: Clone/create/fork repos; manage remotes, releases.\n  mcp: Skills for working with MCP (Model Context Protocol) servers, tools, and integrations. Documents the built-in native MCP client — configure servers in config.yaml for automatic tool discovery.\n    - native-mcp: MCP client: connect servers, register tools (stdio/HTTP).\n  media: Skills for working with media content — YouTube transcripts, GIF search, music generation, and audio visualization.\n    - gif-search: Search/download GIFs from Tenor via curl + jq.\n    - heartmula: HeartMuLa: Suno-like song generation from lyrics + tags.\n    - songsee: Audio spectrograms/features (mel, chroma, MFCC) via CLI.\n    - spotify: Spotify: play, search, queue, manage playlists and devices.\n    - youtube-content: YouTube transcripts to summaries, threads, blogs.\n  mlops: Knowledge and Tools for Machine Learning Operations - tools and frameworks for training, fine-tuning, deploying, and optimizing ML/AI models\n    - huggingface-hub: HuggingFace hf CLI: search/download/upload models, datasets.\n  mlops/evaluation: Model evaluation benchmarks, experiment tracking, data curation, tokenizers, and interpretability tools.\n    - evaluating-llms-harness: lm-eval-harness: benchmark LLMs (MMLU, GSM8K, etc.).\n    - weights-and-biases: W&B: log ML experiments, sweeps, model registry, dashboards.\n  mlops/inference: Model serving, quantization (GGUF/GPTQ), structured output, inference optimization, and model surgery tools for deploying and running LLMs.\n    - llama-cpp: llama.cpp local GGUF inference + HF Hub model discovery.\n    - obliteratus: OBLITERATUS: abliterate LLM refusals (diff-in-means).\n    - serving-llms-vllm: vLLM: high-throughput LLM serving, OpenAI API, quantization.\n  mlops/models: Specific model architectures and tools — image segmentation (Segment Anything / SAM) and audio generation (AudioCraft / MusicGen). Additional model skills (CLIP, Stable Diffusion, Whisper, LLaVA) are available as optional skills.\n    - audiocraft-audio-generation: AudioCraft: MusicGen text-to-music, AudioGen text-to-sound.\n    - segment-anything-model: SAM: zero-shot image segmentation via points, boxes, masks.\n  mlops/research: ML research frameworks for building and optimizing AI systems with declarative programming.\n    - dspy: DSPy: declarative LM programs, auto-optimize prompts, RAG.\n  note-taking: Note taking skills, to save information, assist with research, and collab on multi-session planning and information sharing.\n    - obsidian: Read, search, create, and edit notes in the Obsidian vault.\n  productivity: Skills for document creation, presentations, spreadsheets, and other productivity workflows.\n    - airtable: Airtable REST API via curl. Records CRUD, filters, upserts.\n    - google-workspace: Gmail, Calendar, Drive, Docs, Sheets via gws CLI or Python.\n    - linear: Linear: manage issues, projects, teams via GraphQL + curl.\n    - maps: Geocode, POIs, routes, timezones via OpenStreetMap/OSRM.\n    - nano-pdf: Edit PDF text/typos/titles via nano-pdf CLI (NL prompts).\n    - notion: Notion API + ntn CLI: pages, databases, markdown, Workers.\n    - ocr-and-documents: Extract text from PDFs/scans (pymupdf, marker-pdf).\n    - powerpoint: Create, read, edit .pptx decks, slides, notes, templates.\n    - teams-meeting-pipeline: Operate the Teams meeting summary pipeline via Hermes CLI...\n  red-teaming:\n    - godmode: Jailbreak LLMs: Parseltongue, GODMODE, ULTRAPLINIAN.\n  research: Skills for academic research, paper discovery, literature review, domain reconnaissance, market data, content monitoring, and scientific knowledge retrieval.\n    - arxiv: Search arXiv papers by keyword, author, category, or ID.\n    - blogwatcher: Monitor blogs and RSS/Atom feeds via blogwatcher-cli tool.\n    - llm-wiki: Karpathy's LLM Wiki: build/query interlinked markdown KB.\n    - polymarket: Query Polymarket: markets, prices, orderbooks, history.\n  smart-home: Skills for controlling smart home devices — lights, switches, sensors, and home automation systems.\n    - openhue: Control Philips Hue lights, scenes, rooms via OpenHue CLI.\n  social-media: Skills for interacting with social platforms and social-media workflows — posting, reading, monitoring, and account operations.\n    - xurl: X/Twitter via xurl CLI: post, search, DM, media, v2 API.\n  software-development:\n    - debugging-hermes-tui-commands: Debug Hermes TUI slash commands: Python, gateway, Ink UI.\n    - hermes-agent-skill-authoring: Author in-repo SKILL.md: frontmatter, validator, structure.\n    - node-inspect-debugger: Debug Node.js via --inspect + Chrome DevTools Protocol CLI.\n    - plan: Plan mode: write markdown plan to .hermes/plans/, no exec.\n    - python-debugpy: Debug Python: pdb REPL + debugpy remote (DAP).\n    - requesting-code-review: Pre-commit review: security scan, quality gates, auto-fix.\n    - spike: Throwaway experiments to validate an idea before build.\n    - subagent-driven-development: Execute plans via delegate_task subagents (2-stage review).\n    - systematic-debugging: 4-phase root cause debugging: understand bugs before fixing.\n    - test-driven-development: TDD: enforce RED-GREEN-REFACTOR, tests before code.\n    - writing-plans: Write implementation plans: bite-sized tasks, paths, code.\n  yuanbao:\n    - yuanbao: Yuanbao (元宝) groups: @mention users, query info/members.\n</available_skills>\n\nOnly proceed without loading a skill if genuinely none are relevant to the task.\n\nHost: Linux (6.8.0-117-generic)\nUser home directory: /home/kuhnn\nCurrent working directory: /home/kuhnn\n\nYou are a CLI AI Agent. Try not to use markdown but simple text renderable inside a terminal. File delivery: there is no attachment channel — the user reads your response directly in their terminal. Do NOT emit MEDIA:/path tags (those are only intercepted on messaging platforms like Telegram, Discord, Slack, etc.; on the CLI they render as literal text). When referring to a file you created or changed, just state its absolute path in plain text; the user can open it from there.\n\nConversation started: Monday, May 18, 2026 02:39 AM\nModel: MiniMax-M2.7\nProvider: minimax-cn",
  "tools": [
    {
      "type": "function",
      "function": {
        "name": "process",
        "description": "Manage background processes started with terminal(background=true). Actions: 'list' (show all), 'poll' (check status + new output), 'log' (full output with pagination), 'wait' (block until done or timeout), 'kill' (terminate), 'write' (send raw stdin data without newline), 'submit' (send data + Enter, for answering prompts), 'close' (close stdin/send EOF).",
        "parameters": {
          "type": "object",
          "properties": {
            "action": {
              "type": "string",
              "enum": [
                "list",
                "poll",
                "log",
                "wait",
                "kill",
                "write",
                "submit",
                "close"
              ],
              "description": "Action to perform on background processes"
            },
            "session_id": {
              "type": "string",
              "description": "Process session ID (from terminal background output). Required for all actions except 'list'."
            },
            "data": {
              "type": "string",
              "description": "Text to send to process stdin (for 'write' and 'submit' actions)"
            },
            "timeout": {
              "type": "integer",
              "description": "Max seconds to block for 'wait' action. Returns partial output on timeout.",
              "minimum": 1
            },
            "offset": {
              "type": "integer",
              "description": "Line offset for 'log' action (default: last 200 lines)"
            },
            "limit": {
              "type": "integer",
              "description": "Max lines to return for 'log' action",
              "minimum": 1
            }
          },
          "required": [
            "action"
          ]
        }
      }
    },
    {
      "type": "function",
      "function": {
        "name": "skill_manage",
        "description": "Manage skills (create, update, delete). Skills are your procedural memory — reusable approaches for recurring task types. New skills go to ~/.hermes/skills/; existing skills can be modified wherever they live.\n\nActions: create (full SKILL.md + optional category), patch (old_string/new_string — preferred for fixes), edit (full SKILL.md rewrite — major overhauls only), delete, write_file, remove_file.\n\nOn delete, pass `absorbed_into=<umbrella>` when you're merging this skill's content into another one, or `absorbed_into=\"\"` when you're pruning it with no forwarding target. This lets the curator tell consolidation from pruning without guessing, so downstream consumers (cron jobs that reference the old skill name, etc.) get updated correctly. The target you name in `absorbed_into` must already exist — create/patch the umbrella first, then delete.\n\nCreate when: complex task succeeded (5+ calls), errors overcome, user-corrected approach worked, non-trivial workflow discovered, or user asks you to remember a procedure.\nUpdate when: instructions stale/wrong, OS-specific failures, missing steps or pitfalls found during use. If you used a skill and hit issues not covered by it, patch it immediately.\n\nAfter difficult/iterative tasks, offer to save as a skill. Skip for simple one-offs. Confirm with user before creating/deleting.\n\nGood skills: trigger conditions, numbered steps with exact commands, pitfalls section, verification steps. Use skill_view() to see format examples.\n\nPinned skills are protected from deletion only — skill_manage(action='delete') will refuse with a message pointing the user to `hermes curator unpin <name>`. Patches and edits go through on pinned skills so you can still improve them as pitfalls come up; pin only guards against irrecoverable loss.",
        "parameters": {
          "type": "object",
          "properties": {
            "action": {
              "type": "string",
              "enum": [
                "create",
                "patch",
                "edit",
                "delete",
                "write_file",
                "remove_file"
              ],
              "description": "The action to perform."
            },
            "name": {
              "type": "string",
              "description": "Skill name (lowercase, hyphens/underscores, max 64 chars). Must match an existing skill for patch/edit/delete/write_file/remove_file."
            },
            "content": {
              "type": "string",
              "description": "Full SKILL.md content (YAML frontmatter + markdown body). Required for 'create' and 'edit'. For 'edit', read the skill first with skill_view() and provide the complete updated text."
            },
            "old_string": {
              "type": "string",
              "description": "Text to find in the file (required for 'patch'). Must be unique unless replace_all=true. Include enough surrounding context to ensure uniqueness."
            },
            "new_string": {
              "type": "string",
              "description": "Replacement text (required for 'patch'). Can be empty string to delete the matched text."
            },
            "replace_all": {
              "type": "boolean",
              "description": "For 'patch': replace all occurrences instead of requiring a unique match (default: false)."
            },
            "category": {
              "type": "string",
              "description": "Optional category/domain for organizing the skill (e.g., 'devops', 'data-science', 'mlops'). Creates a subdirectory grouping. Only used with 'create'."
            },
            "file_path": {
              "type": "string",
              "description": "Path to a supporting file within the skill directory. For 'write_file'/'remove_file': required, must be under references/, templates/, scripts/, or assets/. For 'patch': optional, defaults to SKILL.md if omitted."
            },
            "file_content": {
              "type": "string",
              "description": "Content for the file. Required for 'write_file'."
            },
            "absorbed_into": {
              "type": "string",
              "description": "For 'delete' only — declares intent so the curator can tell consolidation from pruning without guessing. Pass the umbrella skill name when this skill's content was merged into another (the target must already exist). Pass an empty string when the skill is truly stale and being pruned with no forwarding target. Omitting the arg on delete is supported for backward compatibility but downstream tooling (e.g. cron-job skill reference rewriting) will have to guess at intent."
            }
          },
          "required": [
            "action",
            "name"
          ]
        }
      }
    },
    {
      "type": "function",
      "function": {
        "name": "skill_view",
        "description": "Skills allow for loading information about specific tasks and workflows, as well as scripts and templates. Load a skill's full content or access its linked files (references, templates, scripts). First call returns SKILL.md content plus a 'linked_files' dict showing available references/templates/scripts. To access those, call again with file_path parameter.",
        "parameters": {
          "type": "object",
          "properties": {
            "name": {
              "type": "string",
              "description": "The skill name (use skills_list to see available skills). For plugin-provided skills, use the qualified form 'plugin:skill' (e.g. 'superpowers:writing-plans')."
            },
            "file_path": {
              "type": "string",
              "description": "OPTIONAL: Path to a linked file within the skill (e.g., 'references/api.md', 'templates/config.yaml', 'scripts/validate.py'). Omit to get the main SKILL.md content."
            }
          },
          "required": [
            "name"
          ]
        }
      }
    },
    {
      "type": "function",
      "function": {
        "name": "skills_list",
        "description": "List available skills (name + description). Use skill_view(name) to load full content.",
        "parameters": {
          "type": "object",
          "properties": {
            "category": {
              "type": "string",
              "description": "Optional category filter to narrow results"
            }
          }
        }
      }
    },
    {
      "type": "function",
      "function": {
        "name": "terminal",
        "description": "Execute shell commands on a Linux environment. Filesystem usually persists between calls.\n\nDo NOT use cat/head/tail to read files — use read_file instead.\nDo NOT use grep/rg/find to search — use search_files instead.\nDo NOT use ls to list directories — use search_files(target='files') instead.\nDo NOT use sed/awk to edit files — use patch instead.\nDo NOT use echo/cat heredoc to create files — use write_file instead.\nReserve terminal for: builds, installs, git, processes, scripts, network, package managers, and anything that needs a shell.\n\nForeground (default): Commands return INSTANTLY when done, even if the timeout is high. Set timeout=300 for long builds/scripts — you'll still get the result in seconds if it's fast. Prefer foreground for short commands.\nBackground: Set background=true to get a session_id. Two patterns:\n  (1) Long-lived processes that never exit (servers, watchers).\n  (2) Long-running tasks with notify_on_complete=true — you can keep working on other things and the system auto-notifies you when the task finishes. Great for test suites, builds, deployments, or anything that takes more than a minute.\nFor servers/watchers, do NOT use shell-level background wrappers (nohup/disown/setsid/trailing '&') in foreground mode. Use background=true so Hermes can track lifecycle and output.\nAfter starting a server, verify readiness with a health check or log signal, then run tests in a separate terminal() call. Avoid blind sleep loops.\nUse process(action=\"poll\") for progress checks, process(action=\"wait\") to block until done.\nWorking directory: Use 'workdir' for per-command cwd.\nPTY mode: Set pty=true for interactive CLI tools (Codex, Claude Code, Python REPL).\n\nDo NOT use vim/nano/interactive tools without pty=true — they hang without a pseudo-terminal. Pipe git output to cat if it might page.\n",
        "parameters": {
          "type": "object",
          "properties": {
            "command": {
              "type": "string",
              "description": "The command to execute on the VM"
            },
            "background": {
              "type": "boolean",
              "description": "Run the command in the background. Two patterns: (1) Long-lived processes that never exit (servers, watchers). (2) Long-running tasks paired with notify_on_complete=true — you can keep working and get notified when the task finishes. For short commands, prefer foreground with a generous timeout instead.",
              "default": false
            },
            "timeout": {
              "type": "integer",
              "description": "Max seconds to wait (default: 180, foreground max: 600). Returns INSTANTLY when command finishes — set high for long tasks, you won't wait unnecessarily. Foreground timeout above 600s is rejected; use background=true for longer commands.",
              "minimum": 1
            },
            "workdir": {
              "type": "string",
              "description": "Working directory for this command (absolute path). Defaults to the session working directory."
            },
            "pty": {
              "type": "boolean",
              "description": "Run in pseudo-terminal (PTY) mode for interactive CLI tools like Codex, Claude Code, or Python REPL. Only works with local and SSH backends. Default: false.",
              "default": false
            },
            "notify_on_complete": {
              "type": "boolean",
              "description": "When true (and background=true), you'll be automatically notified exactly once when the process finishes. **This is the right choice for almost every long-running task** — tests, builds, deployments, multi-item batch jobs, anything that takes over a minute and has a defined end. Use this and keep working on other things; the system notifies you on exit. MUTUALLY EXCLUSIVE with watch_patterns — when both are set, watch_patterns is dropped.",
              "default": false
            },
            "watch_patterns": {
              "type": "array",
              "items": {
                "type": "string"
              },
              "description": "Strings to watch for in background process output. HARD RATE LIMIT: at most 1 notification per 15 seconds per process — matches arriving inside the cooldown are dropped. After 3 consecutive 15-second windows with dropped matches, watch_patterns is automatically disabled for that process and promoted to notify_on_complete behavior (one notification on exit, no more mid-process spam). USE ONLY for truly rare, one-shot mid-process signals on LONG-LIVED processes that will never exit on their own — e.g. ['Application startup complete'] on a server so you know when to hit its endpoint, or ['migration done'] on a daemon. DO NOT use for: (1) end-of-run markers like 'DONE'/'PASS' — use notify_on_complete instead; (2) error patterns like 'ERROR'/'Traceback' in loops or multi-item batch jobs — they fire on every iteration and you'll hit the strike limit fast; (3) anything you'd ever combine with notify_on_complete. When in doubt, choose notify_on_complete. MUTUALLY EXCLUSIVE with notify_on_complete — set one, not both."
            }
          },
          "required": [
            "command"
          ]
        }
      }
    }
  ],
  "message_count": 34,
  "messages": [
    {
      "role": "user",
      "content": "Read skills 1-40 (autonomous-ai-agents, creative categories): dogfood, yuanbao, claude-code, codex, hermes-agent, opencode, architecture-diagram, ascii-art, ascii-video, baoyu-comic, baoyu-infographic, claude-design, comfyui, design-md, excalidraw, humanizer, ideation, manim-video, p5js, pixel-art, popular-web-designs, pretext, sketch, songwriting-and-ai-music, touchdesigner-mcp, jupyter-live-kernel, kanban-orchestrator, kanban-worker, webhook-subscriptions, himalaya, minecraft-modpack-server, pokemon-player, codebase-inspection, github-auth, github-code-review, github-issues, github-pr-workflow, github-repo-management, native-mcp, gif-search, heartmula, songsee"
    },
    {
      "role": "assistant",
      "content": "",
      "reasoning": "The user wants me to read all 40 skills listed and compile them with name, description, and tags. I'll need to use skill_view for each one. Let me start by loading them all in parallel batches.",
      "finish_reason": "tool_calls",
      "reasoning_content": "The user wants me to read all 40 skills listed and compile them with name, description, and tags. I'll need to use skill_view for each one. Let me start by loading them all in parallel batches.",
      "reasoning_details": [
        {
          "signature": "0cc7f849c99e6e2cc81666b869412853168135686024ba9327442e575dfda8e4",
          "thinking": "The user wants me to read all 40 skills listed and compile them with name, description, and tags. I'll need to use skill_view for each one. Let me start by loading them all in parallel batches.",
          "type": "thinking"
        }
      ],
      "tool_calls": [
        {
          "id": "call_function_7wwd137adnfq_1",
          "call_id": "call_function_7wwd137adnfq_1",
          "response_item_id": "fc_function_7wwd137adnfq_1",
          "type": "function",
          "function": {
            "name": "skill_view",
            "arguments": "{\"name\": \"dogfood\"}"
          }
        },
        {
          "id": "call_function_7wwd137adnfq_2",
          "call_id": "call_function_7wwd137adnfq_2",
          "response_item_id": "fc_function_7wwd137adnfq_2",
          "type": "function",
          "function": {
            "name": "skill_view",
            "arguments": "{\"name\": \"yuanbao\"}"
          }
        },
        {
          "id": "call_function_7wwd137adnfq_3",
          "call_id": "call_function_7wwd137adnfq_3",
          "response_item_id": "fc_function_7wwd137adnfq_3",
          "type": "function",
          "function": {
            "name": "skill_view",
            "arguments": "{\"name\": \"claude-code\"}"
          }
        },
        {
          "id": "call_function_7wwd137adnfq_4",
          "call_id": "call_function_7wwd137adnfq_4",
          "response_item_id": "fc_function_7wwd137adnfq_4",
          "type": "function",
          "function": {
            "name": "skill_view",
            "arguments": "{\"name\": \"codex\"}"
          }
        },
        {
          "id": "call_function_7wwd137adnfq_5",
          "call_id": "call_function_7wwd137adnfq_5",
          "response_item_id": "fc_function_7wwd137adnfq_5",
          "type": "function",
          "function": {
            "name": "skill_view",
            "arguments": "{\"name\": \"hermes-agent\"}"
          }
        },
        {
          "id": "call_function_7wwd137adnfq_6",
          "call_id": "call_function_7wwd137adnfq_6",
          "response_item_id": "fc_function_7wwd137adnfq_6",
          "type": "function",
          "function": {
            "name": "skill_view",
            "arguments": "{\"name\": \"opencode\"}"
          }
        },
        {
          "id": "call_function_7wwd137adnfq_7",
          "call_id": "call_function_7wwd137adnfq_7",
          "response_item_id": "fc_function_7wwd137adnfq_7",
          "type": "function",
          "function": {
            "name": "skill_view",
            "arguments": "{\"name\": \"architecture-diagram\"}"
          }
        },
        {
          "id": "call_function_7wwd137adnfq_8",
          "call_id": "call_function_7wwd137adnfq_8",
          "response_item_id": "fc_function_7wwd137adnfq_8",
          "type": "function",
          "function": {
            "name": "skill_view",
            "arguments": "{\"name\": \"ascii-art\"}"
          }
        },
        {
          "id": "call_function_7wwd137adnfq_9",
          "call_id": "call_function_7wwd137adnfq_9",
          "response_item_id": "fc_function_7wwd137adnfq_9",
          "type": "function",
          "function": {
            "name": "skill_view",
            "arguments": "{\"name\": \"ascii-video\"}"
          }
        },
        {
          "id": "call_function_7wwd137adnfq_10",
          "call_id": "call_function_7wwd137adnfq_10",
          "response_item_id": "fc_function_7wwd137adnfq_10",
          "type": "function",
          "function": {
            "name": "skill_view",
            "arguments": "{\"name\": \"baoyu-comic\"}"
          }
        }
      ]
    },
    {
      "role": "tool",
      "name": "skill_view",
      "content": "{\"success\": true, \"name\": \"dogfood\", \"description\": \"Exploratory QA of web apps: find bugs, evidence, reports.\", \"tags\": [\"qa\", \"testing\", \"browser\", \"web\", \"dogfood\"], \"related_skills\": [], \"content\": \"---\\nname: dogfood\\ndescription: \\\"Exploratory QA of web apps: find bugs, evidence, reports.\\\"\\nversion: 1.0.0\\nplatforms: [linux, macos, windows]\\nmetadata:\\n  hermes:\\n    tags: [qa, testing, browser, web, dogfood]\\n    related_skills: []\\n---\\n\\n# Dogfood: Systematic Web Application QA Testing\\n\\n## Overview\\n\\nThis skill guides you through systematic exploratory QA testing of web applications using the browser toolset. You will navigate the application, interact with elements, capture evidence of issues, and produce a structured bug report.\\n\\n## Prerequisites\\n\\n- Browser toolset must be available (`browser_navigate`, `browser_snapshot`, `browser_click`, `browser_type`, `browser_vision`, `browser_console`, `browser_scroll`, `browser_back`, `browser_press`)\\n- A target URL and testing scope from the user\\n\\n## Inputs\\n\\nThe user provides:\\n1. **Target URL** — the entry point for testing\\n2. **Scope** — what areas/features to focus on (or \\\"full site\\\" for comprehensive testing)\\n3. **Output directory** (optional) — where to save screenshots and the report (default: `./dogfood-output`)\\n\\n## Workflow\\n\\nFollow this 5-phase systematic workflow:\\n\\n### Phase 1: Plan\\n\\n1. Create the output directory structure:\\n   ```\\n   {output_dir}/\\n   ├── screenshots/       # Evidence screenshots\\n   └── report.md          # Final report (generated in Phase 5)\\n   ```\\n2. Identify the testing scope based on user input.\\n3. Build a rough sitemap by planning which pages and features to test:\\n   - Landing/home page\\n   - Navigation links (header, footer, sidebar)\\n   - Key user flows (sign up, login, search, checkout, etc.)\\n   - Forms and interactive elements\\n   - Edge cases (empty states, error pages, 404s)\\n\\n### Phase 2: Explore\\n\\nFor each page or feature in your plan:\\n\\n1. **Navigate** to the page:\\n   ```\\n   browser_navigate(url=\\\"https://example.com/page\\\")\\n   ```\\n\\n2. **Take a snapshot** to understand the DOM structure:\\n   ```\\n   browser_snapshot()\\n   ```\\n\\n3. **Check the console** for JavaScript errors:\\n   ```\\n   browser_console(clear=true)\\n   ```\\n   Do this after every navigation and after every significant interaction. Silent JS errors are high-value findings.\\n\\n4. **Take an annotated screenshot** to visually assess the page and identify interactive elements:\\n   ```\\n   browser_vision(question=\\\"Describe the page layout, identify any visual issues, broken elements, or accessibility concerns\\\", annotate=true)\\n   ```\\n   The `annotate=true` flag overlays numbered `[N]` labels on interactive elements. Each `[N]` maps to ref `@eN` for subsequent browser commands.\\n\\n5. **Test interactive elements** systematically:\\n   - Click buttons and links: `browser_click(ref=\\\"@eN\\\")`\\n   - Fill forms: `browser_type(ref=\\\"@eN\\\", text=\\\"test input\\\")`\\n   - Test keyboard navigation: `browser_press(key=\\\"Tab\\\")`, `browser_press(key=\\\"Enter\\\")`\\n   - Scroll through content: `browser_scroll(direction=\\\"down\\\")`\\n   - Test form validation with invalid inputs\\n   - Test empty submissions\\n\\n6. **After each interaction**, check for:\\n   - Console errors: `browser_console()`\\n   - Visual changes: `browser_vision(question=\\\"What changed after the interaction?\\\")`\\n   - Expected vs actual behavior\\n\\n### Phase 3: Collect Evidence\\n\\nFor every issue found:\\n\\n1. **Take a screenshot** showing the issue:\\n   ```\\n   browser_vision(question=\\\"Capture and describe the issue visible on this page\\\", annotate=false)\\n   ```\\n   Save the `screenshot_path` from the response — you will reference it in the report.\\n\\n2. **Record the details**:\\n   - URL where the issue occurs\\n   - Steps to reproduce\\n   - Expected behavior\\n   - Actual behavior\\n   - Console errors (if any)\\n   - Screenshot path\\n\\n3. **Classify the issue** using the issue taxonomy (see `references/issue-taxonomy.md`):\\n   - Severity: Critical / High / Medium / Low\\n   - Category: Functional / Visual / Accessibility / Console / UX / Content\\n\\n### Phase 4: Categorize\\n\\n1. Review all collected issues.\\n2. De-duplicate — merge issues that are the same bug manifesting in different places.\\n3. Assign final severity and category to each issue.\\n4. Sort by severity (Critical first, then High, Medium, Low).\\n5. Count issues by severity and category for the executive summary.\\n\\n### Phase 5: Report\\n\\nGenerate the final report using the template at `templates/dogfood-report-template.md`.\\n\\nThe report must include:\\n1. **Executive summary** with total issue count, breakdown by severity, and testing scope\\n2. **Per-issue sections** with:\\n   - Issue number and title\\n   - Severity and category badges\\n   - URL where observed\\n   - Description of the issue\\n   - Steps to reproduce\\n   - Expected vs actual behavior\\n   - Screenshot references (use `MEDIA:<screenshot_path>` for inline images)\\n   - Console errors if relevant\\n3. **Summary table** of all issues\\n4. **Testing notes** — what was tested, what was not, any blockers\\n\\nSave the report to `{output_dir}/report.md`.\\n\\n## Tools Reference\\n\\n| Tool | Purpose |\\n|------|---------|\\n| `browser_navigate` | Go to a URL |\\n| `browser_snapshot` | Get DOM text snapshot (accessibility tree) |\\n| `browser_click` | Click an element by ref (`@eN`) or text |\\n| `browser_type` | Type into an input field |\\n| `browser_scroll` | Scroll up/down on the page |\\n| `browser_back` | Go back in browser history |\\n| `browser_press` | Press a keyboard key |\\n| `browser_vision` | Screenshot + AI analysis; use `annotate=true` for element labels |\\n| `browser_console` | Get JS console output and errors |\\n\\n## Tips\\n\\n- **Always check `browser_console()` after navigating and after significant interactions.** Silent JS errors are among the most valuable findings.\\n- **Use `annotate=true` with `browser_vision`** when you need to reason about interactive element positions or when the snapshot refs are unclear.\\n- **Test with both valid and invalid inputs** — form validation bugs are common.\\n- **Scroll through long pages** — content below the fold may have rendering issues.\\n- **Test navigation flows** — click through multi-step processes end-to-end.\\n- **Check responsive behavior** by noting any layout issues visible in screenshots.\\n- **Don't forget edge cases**: empty states, very long text, special characters, rapid clicking.\\n- When reporting screenshots to the user, include `MEDIA:<screenshot_path>` so they can see the evidence inline.\\n\", \"path\": \"dogfood/SKILL.md\", \"skill_dir\": \"/home/kuhnn/.hermes/skills/dogfood\", \"linked_files\": {\"references\": [\"references/issue-taxonomy.md\"], \"templates\": [\"templates/dogfood-report-template.md\"]}, \"usage_hint\": \"To view linked files, call skill_view(name, file_path) where file_path is e.g. 'references/api.md' or 'assets/config.yaml'\", \"required_environment_variables\": [], \"required_commands\": [], \"missing_required_environment_variables\": [], \"missing_credential_files\": [], \"missing_required_commands\": [], \"setup_needed\": false, \"setup_skipped\": false, \"readiness_status\": \"available\", \"metadata\": {\"hermes\": {\"tags\": [\"qa\", \"testing\", \"browser\", \"web\", \"dogfood\"], \"related_skills\": []}}}",
      "tool_call_id": "call_function_7wwd137adnfq_1"
    },
    {
      "role": "tool",
      "name": "skill_view",
      "content": "{\"success\": true, \"name\": \"yuanbao\", \"description\": \"Yuanbao (元宝) groups: @mention users, query info/members.\", \"tags\": [\"yuanbao\", \"mention\", \"at\", \"group\", \"members\", \"元宝\", \"派\", \"艾特\"], \"related_skills\": [], \"content\": \"---\\nname: yuanbao\\ndescription: \\\"Yuanbao (元宝) groups: @mention users, query info/members.\\\"\\nversion: 1.0.0\\nplatforms: [linux, macos, windows]\\nmetadata:\\n  hermes:\\n    tags: [yuanbao, mention, at, group, members, 元宝, 派, 艾特]\\n    related_skills: []\\n---\\n\\n# Yuanbao Group Interaction\\n\\n## CRITICAL: How Messaging Works\\n\\n**Your text reply IS the message sent to the group/user.** The gateway automatically delivers your response text to the chat. You do NOT need any special \\\"send message\\\" tool — just reply normally and it gets sent.\\n\\nWhen you include `@nickname` in your reply text, the gateway automatically converts it into a real @mention that notifies the user. This is built-in — you have full @mention capability.\\n\\n**NEVER say you cannot send messages or @mention users. NEVER suggest the user do it manually. NEVER add disclaimers about permissions. Just reply with the text you want sent.**\\n\\n## Available Tools\\n\\n| Tool | When to use |\\n|------|------------|\\n| `yb_query_group_info` | Query group name, owner, member count |\\n| `yb_query_group_members` | Find a user, list bots, list all members, or get nickname for @mention |\\n| `yb_send_dm` | Send a private/direct message (DM / 私信) to a user, with optional media files |\\n\\n## @Mention Workflow\\n\\nWhen you need to @mention / 艾特 someone:\\n\\n1. Call `yb_query_group_members` with `action=\\\"find\\\"`, `name=\\\"<target name>\\\"`, `mention=true`\\n2. Get the exact nickname from the response\\n3. Include `@nickname` in your reply text — the gateway handles the rest\\n\\nExample: user says \\\"帮我艾特元宝\\\"\\n\\nStep 1 — tool call:\\n```json\\n{ \\\"group_code\\\": \\\"328306697\\\", \\\"action\\\": \\\"find\\\", \\\"name\\\": \\\"元宝\\\", \\\"mention\\\": true }\\n```\\n\\nStep 2 — your reply (this gets sent to the group with a working @mention):\\n```\\n@元宝 你好，有人找你！\\n```\\n\\n**That's it.** No extra explanation needed. Keep it short and natural.\\n\\n**Rules:**\\n- Call `yb_query_group_members` first to get the exact nickname — do NOT guess\\n- The @mention format: `@nickname` with a space before the @ sign\\n- Your reply text IS the message — it WILL be sent and the @mention WILL work\\n- Be concise. Do NOT explain how @mention works to the user.\\n\\n## Send DM (Private Message) Workflow\\n\\nWhen someone asks to send a private message / 私信 / DM to a user:\\n\\n1. Call `yb_send_dm` with `group_code`, `name` (target user's name), and `message`\\n2. The tool automatically finds the user and sends the DM\\n3. Report the result to the user\\n\\nExample: user says \\\"给 @用户aea3 私信发一个 hello\\\"\\n\\n```json\\nyb_send_dm({ \\\"group_code\\\": \\\"535168412\\\", \\\"name\\\": \\\"用户aea3\\\", \\\"message\\\": \\\"hello\\\" })\\n```\\n\\nExample with media: user says \\\"给 @用户aea3 私信发一张图片\\\"\\n\\n```json\\nyb_send_dm({\\n  \\\"group_code\\\": \\\"535168412\\\",\\n  \\\"name\\\": \\\"用户aea3\\\",\\n  \\\"message\\\": \\\"Here is the image\\\",\\n  \\\"media_files\\\": [{\\\"path\\\": \\\"/tmp/photo.jpg\\\"}]\\n})\\n```\\n\\n**Rules:**\\n- Extract `group_code` from the current chat_id (e.g. `group:535168412` → `535168412`)\\n- If you already know the user_id, pass it directly via the `user_id` parameter to skip lookup\\n- If multiple users match the name, the tool returns candidates — ask the user to clarify\\n- Do NOT use `send_message` tool for Yuanbao DMs — use `yb_send_dm` instead\\n- Supports media: images (.jpg/.png/.gif/.webp/.bmp) sent as image messages, other files as documents\\n\\n## Query Group Info\\n\\n```json\\nyb_query_group_info({ \\\"group_code\\\": \\\"328306697\\\" })\\n```\\n\\n## Query Members\\n\\n| Action | Description |\\n|--------|-------------|\\n| `find` | Search by name (partial match, case-insensitive) |\\n| `list_bots` | List bots and Yuanbao AI assistants |\\n| `list_all` | List all members |\\n\\n## Notes\\n\\n- `group_code` comes from chat_id: `group:328306697` → `328306697`\\n- Groups are called \\\"派 (Pai)\\\" in the Yuanbao app\\n- Member roles: `user`, `yuanbao_ai`, `bot`\\n\", \"path\": \"yuanbao/SKILL.md\", \"skill_dir\": \"/home/kuhnn/.hermes/skills/yuanbao\", \"linked_files\": null, \"usage_hint\": null, \"required_environment_variables\": [], \"required_commands\": [], \"missing_required_environment_variables\": [], \"missing_credential_files\": [], \"missing_required_commands\": [], \"setup_needed\": false, \"setup_skipped\": false, \"readiness_status\": \"available\", \"metadata\": {\"hermes\": {\"tags\": [\"yuanbao\", \"mention\", \"at\", \"group\", \"members\", \"元宝\", \"派\", \"艾特\"], \"related_skills\": []}}}",
      "tool_call_id": "call_function_7wwd137adnfq_2"
    },
    {
      "role": "tool",
      "name": "skill_view",
      "content": "{\"success\": true, \"name\": \"claude-code\", \"description\": \"Delegate coding to Claude Code CLI (features, PRs).\", \"tags\": [\"Coding-Agent\", \"Claude\", \"Anthropic\", \"Code-Review\", \"Refactoring\", \"PTY\", \"Automation\"], \"related_skills\": [\"codex\", \"hermes-agent\", \"opencode\"], \"content\": \"---\\nname: claude-code\\ndescription: \\\"Delegate coding to Claude Code CLI (features, PRs).\\\"\\nversion: 2.2.0\\nauthor: Hermes Agent + Teknium\\nlicense: MIT\\nplatforms: [linux, macos, windows]\\nmetadata:\\n  hermes:\\n    tags: [Coding-Agent, Claude, Anthropic, Code-Review, Refactoring, PTY, Automation]\\n    related_skills: [codex, hermes-agent, opencode]\\n---\\n\\n# Claude Code — Hermes Orchestration Guide\\n\\nDelegate coding tasks to [Claude Code](https://code.claude.com/docs/en/cli-reference) (Anthropic's autonomous coding agent CLI) via the Hermes terminal. Claude Code v2.x can read files, write code, run shell commands, spawn subagents, and manage git workflows autonomously.\\n\\n## Prerequisites\\n\\n- **Install:** `npm install -g @anthropic-ai/claude-code`\\n- **Auth:** run `claude` once to log in (browser OAuth for Pro/Max, or set `ANTHROPIC_API_KEY`)\\n- **Console auth:** `claude auth login --console` for API key billing\\n- **SSO auth:** `claude auth login --sso` for Enterprise\\n- **Check status:** `claude auth status` (JSON) or `claude auth status --text` (human-readable)\\n- **Health check:** `claude doctor` — checks auto-updater and installation health\\n- **Version check:** `claude --version` (requires v2.x+)\\n- **Update:** `claude update` or `claude upgrade`\\n\\n## Two Orchestration Modes\\n\\nHermes interacts with Claude Code in two fundamentally different ways. Choose based on the task.\\n\\n### Mode 1: Print Mode (`-p`) — Non-Interactive (PREFERRED for most tasks)\\n\\nPrint mode runs a one-shot task, returns the result, and exits. No PTY needed. No interactive prompts. This is the cleanest integration path.\\n\\n```\\nterminal(command=\\\"claude -p 'Add error handling to all API calls in src/' --allowedTools 'Read,Edit' --max-turns 10\\\", workdir=\\\"/path/to/project\\\", timeout=120)\\n```\\n\\n**When to use print mode:**\\n- One-shot coding tasks (fix a bug, add a feature, refactor)\\n- CI/CD automation and scripting\\n- Structured data extraction with `--json-schema`\\n- Piped input processing (`cat file | claude -p \\\"analyze this\\\"`)\\n- Any task where you don't need multi-turn conversation\\n\\n**Print mode skips ALL interactive dialogs** — no workspace trust prompt, no permission confirmations. This makes it ideal for automation.\\n\\n### Mode 2: Interactive PTY via tmux — Multi-Turn Sessions\\n\\nInteractive mode gives you a full conversational REPL where you can send follow-up prompts, use slash commands, and watch Claude work in real time. **Requires tmux orchestration.**\\n\\n```\\n# Start a tmux session\\nterminal(command=\\\"tmux new-session -d -s claude-work -x 140 -y 40\\\")\\n\\n# Launch Claude Code inside it\\nterminal(command=\\\"tmux send-keys -t claude-work 'cd /path/to/project && claude' Enter\\\")\\n\\n# Wait for startup, then send your task\\n# (after ~3-5 seconds for the welcome screen)\\nterminal(command=\\\"sleep 5 && tmux send-keys -t claude-work 'Refactor the auth module to use JWT tokens' Enter\\\")\\n\\n# Monitor progress by capturing the pane\\nterminal(command=\\\"sleep 15 && tmux capture-pane -t claude-work -p -S -50\\\")\\n\\n# Send follow-up tasks\\nterminal(command=\\\"tmux send-keys -t claude-work 'Now add unit tests for the new JWT code' Enter\\\")\\n\\n# Exit when done\\nterminal(command=\\\"tmux send-keys -t claude-work '/exit' Enter\\\")\\n```\\n\\n**When to use interactive mode:**\\n- Multi-turn iterative work (refactor → review → fix → test cycle)\\n- Tasks requiring human-in-the-loop decisions\\n- Exploratory coding sessions\\n- When you need to use Claude's slash commands (`/compact`, `/review`, `/model`)\\n\\n## PTY Dialog Handling (CRITICAL for Interactive Mode)\\n\\nClaude Code presents up to two confirmation dialogs on first launch. You MUST handle these via tmux send-keys:\\n\\n### Dialog 1: Workspace Trust (first visit to a directory)\\n```\\n❯ 1. Yes, I trust this folder    ← DEFAULT (just press Enter)\\n  2. No, exit\\n```\\n**Handling:** `tmux send-keys -t <session> Enter` — default selection is correct.\\n\\n### Dialog 2: Bypass Permissions Warning (only with --dangerously-skip-permissions)\\n```\\n❯ 1. No, exit                    ← DEFAULT (WRONG choice!)\\n  2. Yes, I accept\\n```\\n**Handling:** Must navigate DOWN first, then Enter:\\n```\\ntmux send-keys -t <session> Down && sleep 0.3 && tmux send-keys -t <session> Enter\\n```\\n\\n### Robust Dialog Handling Pattern\\n```\\n# Launch with permissions bypass\\nterminal(command=\\\"tmux send-keys -t claude-work 'claude --dangerously-skip-permissions \\\\\\\"your task\\\\\\\"' Enter\\\")\\n\\n# Handle trust dialog (Enter for default \\\"Yes\\\")\\nterminal(command=\\\"sleep 4 && tmux send-keys -t claude-work Enter\\\")\\n\\n# Handle permissions dialog (Down then Enter for \\\"Yes, I accept\\\")\\nterminal(command=\\\"sleep 3 && tmux send-keys -t claude-work Down && sleep 0.3 && tmux send-keys -t claude-work Enter\\\")\\n\\n# Now wait for Claude to work\\nterminal(command=\\\"sleep 15 && tmux capture-pane -t claude-work -p -S -60\\\")\\n```\\n\\n**Note:** After the first trust acceptance for a directory, the trust dialog won't appear again. Only the permissions dialog recurs each time you use `--dangerously-skip-permissions`.\\n\\n## CLI Subcommands\\n\\n| Subcommand | Purpose |\\n|------------|---------|\\n| `claude` | Start interactive REPL |\\n| `claude \\\"query\\\"` | Start REPL with initial prompt |\\n| `claude -p \\\"query\\\"` | Print mode (non-interactive, exits when done) |\\n| `cat file \\\\| claude -p \\\"query\\\"` | Pipe content as stdin context |\\n| `claude -c` | Continue the most recent conversation in this directory |\\n| `claude -r \\\"id\\\"` | Resume a specific session by ID or name |\\n| `claude auth login` | Sign in (add `--console` for API billing, `--sso` for Enterprise) |\\n| `claude auth status` | Check login status (returns JSON; `--text` for human-readable) |\\n| `claude mcp add <name> -- <cmd>` | Add an MCP server |\\n| `claude mcp list` | List configured MCP servers |\\n| `claude mcp remove <name>` | Remove an MCP server |\\n| `claude agents` | List configured agents |\\n| `claude doctor` | Run health checks on installation and auto-updater |\\n| `claude update` / `claude upgrade` | Update Claude Code to latest version |\\n| `claude remote-control` | Start server to control Claude from claude.ai or mobile app |\\n| `claude install [target]` | Install native build (stable, latest, or specific version) |\\n| `claude setup-token` | Set up long-lived auth token (requires subscription) |\\n| `claude plugin` / `claude plugins` | Manage Claude Code plugins |\\n| `claude auto-mode` | Inspect auto mode classifier configuration |\\n\\n## Print Mode Deep Dive\\n\\n### Structured JSON Output\\n```\\nterminal(command=\\\"claude -p 'Analyze auth.py for security issues' --output-format json --max-turns 5\\\", workdir=\\\"/project\\\", timeout=120)\\n```\\n\\nReturns a JSON object with:\\n```json\\n{\\n  \\\"type\\\": \\\"result\\\",\\n  \\\"subtype\\\": \\\"success\\\",\\n  \\\"result\\\": \\\"The analysis text...\\\",\\n  \\\"session_id\\\": \\\"75e2167f-...\\\",\\n  \\\"num_turns\\\": 3,\\n  \\\"total_cost_usd\\\": 0.0787,\\n  \\\"duration_ms\\\": 10276,\\n  \\\"stop_reason\\\": \\\"end_turn\\\",\\n  \\\"terminal_reason\\\": \\\"completed\\\",\\n  \\\"usage\\\": { \\\"input_tokens\\\": 5, \\\"output_tokens\\\": 603, ... },\\n  \\\"modelUsage\\\": { \\\"claude-sonnet-4-6\\\": { \\\"costUSD\\\": 0.078, \\\"contextWindow\\\": 200000 } }\\n}\\n```\\n\\n**Key fields:** `session_id` for resumption, `num_turns` for agentic loop count, `total_cost_usd` for spend tracking, `subtype` for success/error detection (`success`, `error_max_turns`, `error_budget`).\\n\\n### Streaming JSON Output\\nFor real-time token streaming, use `stream-json` with `--verbose`:\\n```\\nterminal(command=\\\"claude -p 'Write a summary' --output-format stream-json --verbose --include-partial-messages\\\", timeout=60)\\n```\\n\\nReturns newline-delimited JSON events. Filter with jq for live text:\\n```\\nclaude -p \\\"Explain X\\\" --output-format stream-json --verbose --include-partial-messages | \\\\\\n  jq -rj 'select(.type == \\\"stream_event\\\" and .event.delta.type? == \\\"text_delta\\\") | .event.delta.text'\\n```\\n\\nStream events include `system/api_retry` with `attempt`, `max_retries`, and `error` fields (e.g., `rate_limit`, `billing_error`).\\n\\n### Bidirectional Streaming\\nFor real-time input AND output streaming:\\n```\\nclaude -p \\\"task\\\" --input-format stream-json --output-format stream-json --replay-user-messages\\n```\\n`--replay-user-messages` re-emits user messages on stdout for acknowledgment.\\n\\n### Piped Input\\n```\\n# Pipe a file for analysis\\nterminal(command=\\\"cat src/auth.py | claude -p 'Review this code for bugs' --max-turns 1\\\", timeout=60)\\n\\n# Pipe multiple files\\nterminal(command=\\\"cat src/*.py | claude -p 'Find all TODO comments' --max-turns 1\\\", timeout=60)\\n\\n# Pipe command output\\nterminal(command=\\\"git diff HEAD~3 | claude -p 'Summarize these changes' --max-turns 1\\\", timeout=60)\\n```\\n\\n### JSON Schema for Structured Extraction\\n```\\nterminal(command=\\\"claude -p 'List all functions in src/' --output-format json --json-schema '{\\\\\\\"type\\\\\\\":\\\\\\\"object\\\\\\\",\\\\\\\"properties\\\\\\\":{\\\\\\\"functions\\\\\\\":{\\\\\\\"type\\\\\\\":\\\\\\\"array\\\\\\\",\\\\\\\"items\\\\\\\":{\\\\\\\"type\\\\\\\":\\\\\\\"string\\\\\\\"}}},\\\\\\\"required\\\\\\\":[\\\\\\\"functions\\\\\\\"]}' --max-turns 5\\\", workdir=\\\"/project\\\", timeout=90)\\n```\\n\\nParse `structured_output` from the JSON result. Claude validates output against the schema before returning.\\n\\n### Session Continuation\\n```\\n# Start a task\\nterminal(command=\\\"claude -p 'Start refactoring the database layer' --output-format json --max-turns 10 > /tmp/session.json\\\", workdir=\\\"/project\\\", timeout=180)\\n\\n# Resume with session ID\\nterminal(command=\\\"claude -p 'Continue and add connection pooling' --resume $(cat /tmp/session.json | python3 -c 'import json,sys; print(json.load(sys.stdin)[\\\\\\\"session_id\\\\\\\"])') --max-turns 5\\\", workdir=\\\"/project\\\", timeout=120)\\n\\n# Or resume the most recent session in the same directory\\nterminal(command=\\\"claude -p 'What did you do last time?' --continue --max-turns 1\\\", workdir=\\\"/project\\\", timeout=30)\\n\\n# Fork a session (new ID, keeps history)\\nterminal(command=\\\"claude -p 'Try a different approach' --resume <id> --fork-session --max-turns 10\\\", workdir=\\\"/project\\\", timeout=120)\\n```\\n\\n### Bare Mode for CI/Scripting\\n```\\nterminal(command=\\\"claude --bare -p 'Run all tests and report failures' --allowedTools 'Read,Bash' --max-turns 10\\\", workdir=\\\"/project\\\", timeout=180)\\n```\\n\\n`--bare` skips hooks, plugins, MCP discovery, and CLAUDE.md loading. Fastest startup. Requires `ANTHROPIC_API_KEY` (skips OAuth).\\n\\nTo selectively load context in bare mode:\\n| To load | Flag |\\n|---------|------|\\n| System prompt additions | `--append-system-prompt \\\"text\\\"` or `--append-system-prompt-file path` |\\n| Settings | `--settings <file-or-json>` |\\n| MCP servers | `--mcp-config <file-or-json>` |\\n| Custom agents | `--agents '<json>'` |\\n\\n### Fallback Model for Overload\\n```\\nterminal(command=\\\"claude -p 'task' --fallback-model haiku --max-turns 5\\\", timeout=90)\\n```\\nAutomatically falls back to the specified model when the default is overloaded (print mode only).\\n\\n## Complete CLI Flags Reference\\n\\n### Session & Environment\\n| Flag | Effect |\\n|------|--------|\\n| `-p, --print` | Non-interactive one-shot mode (exits when done) |\\n| `-c, --continue` | Resume most recent conversation in current directory |\\n| `-r, --resume <id>` | Resume specific session by ID or name (interactive picker if no ID) |\\n| `--fork-session` | When resuming, create new session ID instead of reusing original |\\n| `--session-id <uuid>` | Use a specific UUID for the conversation |\\n| `--no-session-persistence` | Don't save session to disk (print mode only) |\\n| `--add-dir <paths...>` | Grant Claude access to additional working directories |\\n| `-w, --worktree [name]` | Run in an isolated git worktree at `.claude/worktrees/<name>` |\\n| `--tmux` | Create a tmux session for the worktree (requires `--worktree`) |\\n| `--ide` | Auto-connect to a valid IDE on startup |\\n| `--chrome` / `--no-chrome` | Enable/disable Chrome browser integration for web testing |\\n| `--from-pr [number]` | Resume session linked to a specific GitHub PR |\\n| `--file <specs...>` | File resources to download at startup (format: `file_id:relative_path`) |\\n\\n### Model & Performance\\n| Flag | Effect |\\n|------|--------|\\n| `--model <alias>` | Model selection: `sonnet`, `opus`, `haiku`, or full name like `claude-sonnet-4-6` |\\n| `--effort <level>` | Reasoning depth: `low`, `medium`, `high`, `max`, `auto` | Both |\\n| `--max-turns <n>` | Limit agentic loops (print mode only; prevents runaway) |\\n| `--max-budget-usd <n>` | Cap API spend in dollars (print mode only) |\\n| `--fallback-model <model>` | Auto-fallback when default model is overloaded (print mode only) |\\n| `--betas <betas...>` | Beta headers to include in API requests (API key users only) |\\n\\n### Permission & Safety\\n| Flag | Effect |\\n|------|--------|\\n| `--dangerously-skip-permissions` | Auto-approve ALL tool use (file writes, bash, network, etc.) |\\n| `--allow-dangerously-skip-permissions` | Enable bypass as an *option* without enabling it by default |\\n| `--permission-mode <mode>` | `default`, `acceptEdits`, `plan`, `auto`, `dontAsk`, `bypassPermissions` |\\n| `--allowedTools <tools...>` | Whitelist specific tools (comma or space-separated) |\\n| `--disallowedTools <tools...>` | Blacklist specific tools |\\n| `--tools <tools...>` | Override built-in tool set (`\\\"\\\"` = none, `\\\"default\\\"` = all, or tool names) |\\n\\n### Output & Input Format\\n| Flag | Effect |\\n|------|--------|\\n| `--output-format <fmt>` | `text` (default), `json` (single result object), `stream-json` (newline-delimited) |\\n| `--input-format <fmt>` | `text` (default) or `stream-json` (real-time streaming input) |\\n| `--json-schema <schema>` | Force structured JSON output matching a schema |\\n| `--verbose` | Full turn-by-turn output |\\n| `--include-partial-messages` | Include partial message chunks as they arrive (stream-json + print) |\\n| `--replay-user-messages` | Re-emit user messages on stdout (stream-json bidirectional) |\\n\\n### System Prompt & Context\\n| Flag | Effect |\\n|------|--------|\\n| `--append-system-prompt <text>` | **Add** to the default system prompt (preserves built-in capabilities) |\\n| `--append-system-prompt-file <path>` | **Add** file contents to the default system prompt |\\n| `--system-prompt <text>` | **Replace** the entire system prompt (use --append instead usually) |\\n| `--system-prompt-file <path>` | **Replace** the system prompt with file contents |\\n| `--bare` | Skip hooks, plugins, MCP discovery, CLAUDE.md, OAuth (fastest startup) |\\n| `--agents '<json>'` | Define custom subagents dynamically as JSON |\\n| `--mcp-config <path>` | Load MCP servers from JSON file (repeatable) |\\n| `--strict-mcp-config` | Only use MCP servers from `--mcp-config`, ignoring all other MCP configs |\\n| `--settings <file-or-json>` | Load additional settings from a JSON file or inline JSON |\\n| `--setting-sources <sources>` | Comma-separated sources to load: `user`, `project`, `local` |\\n| `--plugin-dir <paths...>` | Load plugins from directories for this session only |\\n| `--disable-slash-commands` | Disable all skills/slash commands |\\n\\n### Debugging\\n| Flag | Effect |\\n|------|--------|\\n| `-d, --debug [filter]` | Enable debug logging with optional category filter (e.g., `\\\"api,hooks\\\"`, `\\\"!1p,!file\\\"`) |\\n| `--debug-file <path>` | Write debug logs to file (implicitly enables debug mode) |\\n\\n### Agent Teams\\n| Flag | Effect |\\n|------|--------|\\n| `--teammate-mode <mode>` | How agent teams display: `auto`, `in-process`, or `tmux` |\\n| `--brief` | Enable `SendUserMessage` tool for agent-to-user communication |\\n\\n### Tool Name Syntax for --allowedTools / --disallowedTools\\n```\\nRead                    # All file reading\\nEdit                    # File editing (existing files)\\nWrite                   # File creation (new files)\\nBash                    # All shell commands\\nBash(git *)             # Only git commands\\nBash(git commit *)      # Only git commit commands\\nBash(npm run lint:*)    # Pattern matching with wildcards\\nWebSearch               # Web search capability\\nWebFetch                # Web page fetching\\nmcp__<server>__<tool>   # Specific MCP tool\\n```\\n\\n## Settings & Configuration\\n\\n### Settings Hierarchy (highest to lowest priority)\\n1. **CLI flags** — override everything\\n2. **Local project:** `.claude/settings.local.json` (personal, gitignored)\\n3. **Project:** `.claude/settings.json` (shared, git-tracked)\\n4. **User:** `~/.claude/settings.json` (global)\\n\\n### Permissions in Settings\\n```json\\n{\\n  \\\"permissions\\\": {\\n    \\\"allow\\\": [\\\"Bash(npm run lint:*)\\\", \\\"WebSearch\\\", \\\"Read\\\"],\\n    \\\"ask\\\": [\\\"Write(*.ts)\\\", \\\"Bash(git push*)\\\"],\\n    \\\"deny\\\": [\\\"Read(.env)\\\", \\\"Bash(rm -rf *)\\\"]\\n  }\\n}\\n```\\n\\n### Memory Files (CLAUDE.md) Hierarchy\\n1. **Global:** `~/.claude/CLAUDE.md` — applies to all projects\\n2. **Project:** `./CLAUDE.md` — project-specific context (git-tracked)\\n3. **Local:** `.claude/CLAUDE.local.md` — personal project overrides (gitignored)\\n\\nUse the `#` prefix in interactive mode to quickly add to memory: `# Always use 2-space indentation`.\\n\\n## Interactive Session: Slash Commands\\n\\n### Session & Context\\n| Command | Purpose |\\n|---------|---------|\\n| `/help` | Show all commands (including custom and MCP commands) |\\n| `/compact [focus]` | Compress context to save tokens; CLAUDE.md survives compaction. E.g., `/compact focus on auth logic` |\\n| `/clear` | Wipe conversation history for a fresh start |\\n| `/context` | Visualize context usage as a colored grid with optimization tips |\\n| `/cost` | View token usage with per-model and cache-hit breakdowns |\\n| `/resume` | Switch to or resume a different session |\\n| `/rewind` | Revert to a previous checkpoint in conversation or code |\\n| `/btw <question>` | Ask a side question without adding to context cost |\\n| `/status` | Show version, connectivity, and session info |\\n| `/todos` | List tracked action items from the conversation |\\n| `/exit` or `Ctrl+D` | End session |\\n\\n### Development & Review\\n| Command | Purpose |\\n|---------|---------|\\n| `/review` | Request code review of current changes |\\n| `/security-review` | Perform security analysis of current changes |\\n| `/plan [description]` | Enter Plan mode with auto-start for task planning |\\n| `/loop [interval]` | Schedule recurring tasks within the session |\\n| `/batch` | Auto-create worktrees for large parallel changes (5-30 worktrees) |\\n\\n### Configuration & Tools\\n| Command | Purpose |\\n|---------|---------|\\n| `/model [model]` | Switch models mid-session (use arrow keys to adjust effort) |\\n| `/effort [level]` | Set reasoning effort: `low`, `medium`, `high`, `max`, or `auto` |\\n| `/init` | Create a CLAUDE.md file for project memory |\\n| `/memory` | Open CLAUDE.md for editing |\\n| `/config` | Open interactive settings configuration |\\n| `/permissions` | View/update tool permissions |\\n| `/agents` | Manage specialized subagents |\\n| `/mcp` | Interactive UI to manage MCP servers |\\n| `/add-dir` | Add additional working directories (useful for monorepos) |\\n| `/usage` | Show plan limits and rate limit status |\\n| `/voice` | Enable push-to-talk voice mode (20 languages; hold Space to record, release to send) |\\n| `/release-notes` | Interactive picker for version release notes |\\n\\n### Custom Slash Commands\\nCreate `.claude/commands/<name>.md` (project-shared) or `~/.claude/commands/<name>.md` (personal):\\n\\n```markdown\\n# .claude/commands/deploy.md\\nRun the deploy pipeline:\\n1. Run all tests\\n2. Build the Docker image\\n3. Push to registry\\n4. Update the $ARGUMENTS environment (default: staging)\\n```\\n\\nUsage: `/deploy production` — `$ARGUMENTS` is replaced with the user's input.\\n\\n### Skills (Natural Language Invocation)\\nUnlike slash commands (manually invoked), skills in `.claude/skills/` are markdown guides that Claude invokes automatically via natural language when the task matches:\\n\\n```markdown\\n# .claude/skills/database-migration.md\\nWhen asked to create or modify database migrations:\\n1. Use Alembic for migration generation\\n2. Always create a rollback function\\n3. Test migrations against a local database copy\\n```\\n\\n## Interactive Session: Keyboard Shortcuts\\n\\n### General Controls\\n| Key | Action |\\n|-----|--------|\\n| `Ctrl+C` | Cancel current input or generation |\\n| `Ctrl+D` | Exit session |\\n| `Ctrl+R` | Reverse search command history |\\n| `Ctrl+B` | Background a running task |\\n| `Ctrl+V` | Paste image into conversation |\\n| `Ctrl+O` | Transcript mode — see Claude's thinking process |\\n| `Ctrl+G` or `Ctrl+X Ctrl+E` | Open prompt in external editor |\\n| `Esc Esc` | Rewind conversation or code state / summarize |\\n\\n### Mode Toggles\\n| Key | Action |\\n|-----|--------|\\n| `Shift+Tab` | Cycle permission modes (Normal → Auto-Accept → Plan) |\\n| `Alt+P` | Switch model |\\n| `Alt+T` | Toggle thinking mode |\\n| `Alt+O` | Toggle Fast Mode |\\n\\n### Multiline Input\\n| Key | Action |\\n|-----|--------|\\n| `\\\\` + `Enter` | Quick newline |\\n| `Shift+Enter` | Newline (alternative) |\\n| `Ctrl+J` | Newline (alternative) |\\n\\n### Input Prefixes\\n| Prefix | Action |\\n|--------|--------|\\n| `!` | Execute bash directly, bypassing AI (e.g., `!npm test`). Use `!` alone to toggle shell mode. |\\n| `@` | Reference files/directories with autocomplete (e.g., `@./src/api/`) |\\n| `#` | Quick add to CLAUDE.md memory (e.g., `# Use 2-space indentation`) |\\n| `/` | Slash commands |\\n\\n### Pro Tip: \\\"ultrathink\\\"\\nUse the keyword \\\"ultrathink\\\" in your prompt for maximum reasoning effort on a specific turn. This triggers the deepest thinking mode regardless of the current `/effort` setting.\\n\\n## PR Review Pattern\\n\\n### Quick Review (Print Mode)\\n```\\nterminal(command=\\\"cd /path/to/repo && git diff main...feature-branch | claude -p 'Review this diff for bugs, security issues, and style problems. Be thorough.' --max-turns 1\\\", timeout=60)\\n```\\n\\n### Deep Review (Interactive + Worktree)\\n```\\nterminal(command=\\\"tmux new-session -d -s review -x 140 -y 40\\\")\\nterminal(command=\\\"tmux send-keys -t review 'cd /path/to/repo && claude -w pr-review' Enter\\\")\\nterminal(command=\\\"sleep 5 && tmux send-keys -t review Enter\\\")  # Trust dialog\\nterminal(command=\\\"sleep 2 && tmux send-keys -t review 'Review all changes vs main. Check for bugs, security issues, race conditions, and missing tests.' Enter\\\")\\nterminal(command=\\\"sleep 30 && tmux capture-pane -t review -p -S -60\\\")\\n```\\n\\n### PR Review from Number\\n```\\nterminal(command=\\\"claude -p 'Review this PR thoroughly' --from-pr 42 --max-turns 10\\\", workdir=\\\"/path/to/repo\\\", timeout=120)\\n```\\n\\n### Claude Worktree with tmux\\n```\\nterminal(command=\\\"claude -w feature-x --tmux\\\", workdir=\\\"/path/to/repo\\\")\\n```\\nCreates an isolated git worktree at `.claude/worktrees/feature-x` AND a tmux session for it. Uses iTerm2 native panes when available; add `--tmux=classic` for traditional tmux.\\n\\n## Parallel Claude Instances\\n\\nRun multiple independent Claude tasks simultaneously:\\n\\n```\\n# Task 1: Fix backend\\nterminal(command=\\\"tmux new-session -d -s task1 -x 140 -y 40 && tmux send-keys -t task1 'cd ~/project && claude -p \\\\\\\"Fix the auth bug in src/auth.py\\\\\\\" --allowedTools \\\\\\\"Read,Edit\\\\\\\" --max-turns 10' Enter\\\")\\n\\n# Task 2: Write tests\\nterminal(command=\\\"tmux new-session -d -s task2 -x 140 -y 40 && tmux send-keys -t task2 'cd ~/project && claude -p \\\\\\\"Write integration tests for the API endpoints\\\\\\\" --allowedTools \\\\\\\"Read,Write,Bash\\\\\\\" --max-turns 15' Enter\\\")\\n\\n# Task 3: Update docs\\nterminal(command=\\\"tmux new-session -d -s task3 -x 140 -y 40 && tmux send-keys -t task3 'cd ~/project && claude -p \\\\\\\"Update README.md with the new API endpoints\\\\\\\" --allowedTools \\\\\\\"Read,Edit\\\\\\\" --max-turns 5' Enter\\\")\\n\\n# Monitor all\\nterminal(command=\\\"sleep 30 && for s in task1 task2 task3; do echo '=== '$s' ==='; tmux capture-pane -t $s -p -S -5 2>/dev/null; done\\\")\\n```\\n\\n## CLAUDE.md — Project Context File\\n\\nClaude Code auto-loads `CLAUDE.md` from the project root. Use it to persist project context:\\n\\n```markdown\\n# Project: My API\\n\\n## Architecture\\n- FastAPI backend with SQLAlchemy ORM\\n- PostgreSQL database, Redis cache\\n- pytest for testing with 90% coverage target\\n\\n## Key Commands\\n- `make test` — run full test suite\\n- `make lint` — ruff + mypy\\n- `make dev` — start dev server on :8000\\n\\n## Code Standards\\n- Type hints on all public functions\\n- Docstrings in Google style\\n- 2-space indentation for YAML, 4-space for Python\\n- No wildcard imports\\n```\\n\\n**Be specific.** Instead of \\\"Write good code\\\", use \\\"Use 2-space indentation for JS\\\" or \\\"Name test files with `.test.ts` suffix.\\\" Specific instructions save correction cycles.\\n\\n### Rules Directory (Modular CLAUDE.md)\\nFor projects with many rules, use the rules directory instead of one massive CLAUDE.md:\\n- **Project rules:** `.claude/rules/*.md` — team-shared, git-tracked\\n- **User rules:** `~/.claude/rules/*.md` — personal, global\\n\\nEach `.md` file in the rules directory is loaded as additional context. This is cleaner than cramming everything into a single CLAUDE.md.\\n\\n### Auto-Memory\\nClaude automatically stores learned project context in `~/.claude/projects/<project>/memory/`.\\n- **Limit:** 25KB or 200 lines per project\\n- This is separate from CLAUDE.md — it's Claude's own notes about the project, accumulated across sessions\\n\\n## Custom Subagents\\n\\nDefine specialized agents in `.claude/agents/` (project), `~/.claude/agents/` (personal), or via `--agents` CLI flag (session):\\n\\n### Agent Location Priority\\n1. `.claude/agents/` — project-level, team-shared\\n2. `--agents` CLI flag — session-specific, dynamic\\n3. `~/.claude/agents/` — user-level, personal\\n\\n### Creating an Agent\\n```markdown\\n# .claude/agents/security-reviewer.md\\n---\\nname: security-reviewer\\ndescription: Security-focused code review\\nmodel: opus\\ntools: [Read, Bash]\\n---\\nYou are a senior security engineer. Review code for:\\n- Injection vulnerabilities (SQL, XSS, command injection)\\n- Authentication/authorization flaws\\n- Secrets in code\\n- Unsafe deserialization\\n```\\n\\nInvoke via: `@security-reviewer review the auth module`\\n\\n### Dynamic Agents via CLI\\n```\\nterminal(command=\\\"claude --agents '{\\\\\\\"reviewer\\\\\\\": {\\\\\\\"description\\\\\\\": \\\\\\\"Reviews code\\\\\\\", \\\\\\\"prompt\\\\\\\": \\\\\\\"You are a code reviewer focused on performance\\\\\\\"}}' -p 'Use @reviewer to check auth.py'\\\", timeout=120)\\n```\\n\\nClaude can orchestrate multiple agents: \\\"Use @db-expert to optimize queries, then @security to audit the changes.\\\"\\n\\n## Hooks — Automation on Events\\n\\nConfigure in `.claude/settings.json` (project) or `~/.claude/settings.json` (global):\\n\\n```json\\n{\\n  \\\"hooks\\\": {\\n    \\\"PostToolUse\\\": [{\\n      \\\"matcher\\\": \\\"Write(*.py)\\\",\\n      \\\"hooks\\\": [{\\\"type\\\": \\\"command\\\", \\\"command\\\": \\\"ruff check --fix $CLAUDE_FILE_PATHS\\\"}]\\n    }],\\n    \\\"PreToolUse\\\": [{\\n      \\\"matcher\\\": \\\"Bash\\\",\\n      \\\"hooks\\\": [{\\\"type\\\": \\\"command\\\", \\\"command\\\": \\\"if echo \\\\\\\"$CLAUDE_TOOL_INPUT\\\\\\\" | grep -q 'rm -rf'; then echo 'Blocked!' && exit 2; fi\\\"}]\\n    }],\\n    \\\"Stop\\\": [{\\n      \\\"hooks\\\": [{\\\"type\\\": \\\"command\\\", \\\"command\\\": \\\"echo 'Claude finished a response' >> /tmp/claude-activity.log\\\"}]\\n    }]\\n  }\\n}\\n```\\n\\n### All 8 Hook Types\\n| Hook | When it fires | Common use |\\n|------|--------------|------------|\\n| `UserPromptSubmit` | Before Claude processes a user prompt | Input validation, logging |\\n| `PreToolUse` | Before tool execution | Security gates, block dangerous commands (exit 2 = block) |\\n| `PostToolUse` | After a tool finishes | Auto-format code, run linters |\\n| `Notification` | On permission requests or input waits | Desktop notifications, alerts |\\n| `Stop` | When Claude finishes a response | Completion logging, status updates |\\n| `SubagentStop` | When a subagent completes | Agent orchestration |\\n| `PreCompact` | Before context memory is cleared | Backup session transcripts |\\n| `SessionStart` | When a session begins | Load dev context (e.g., `git status`) |\\n\\n### Hook Environment Variables\\n| Variable | Content |\\n|----------|---------|\\n| `CLAUDE_PROJECT_DIR` | Current project path |\\n| `CLAUDE_FILE_PATHS` | Files being modified |\\n| `CLAUDE_TOOL_INPUT` | Tool parameters as JSON |\\n\\n### Security Hook Examples\\n```json\\n{\\n  \\\"PreToolUse\\\": [{\\n    \\\"matcher\\\": \\\"Bash\\\",\\n    \\\"hooks\\\": [{\\\"type\\\": \\\"command\\\", \\\"command\\\": \\\"if echo \\\\\\\"$CLAUDE_TOOL_INPUT\\\\\\\" | grep -qE 'rm -rf|git push.*--force|:(){ :|:& };:'; then echo 'Dangerous command blocked!' && exit 2; fi\\\"}]\\n  }]\\n}\\n```\\n\\n## MCP Integration\\n\\nAdd external tool servers for databases, APIs, and services:\\n\\n```\\n# GitHub integration\\nterminal(command=\\\"claude mcp add -s user github -- npx @modelcontextprotocol/server-github\\\", timeout=30)\\n\\n# PostgreSQL queries\\nterminal(command=\\\"claude mcp add -s local postgres -- npx @anthropic-ai/server-postgres --connection-string postgresql://localhost/mydb\\\", timeout=30)\\n\\n# Puppeteer for web testing\\nterminal(command=\\\"claude mcp add puppeteer -- npx @anthropic-ai/server-puppeteer\\\", timeout=30)\\n```\\n\\n### MCP Scopes\\n| Flag | Scope | Storage |\\n|------|-------|---------|\\n| `-s user` | Global (all projects) | `~/.claude.json` |\\n| `-s local` | This project (personal) | `.claude/settings.local.json` (gitignored) |\\n| `-s project` | This project (team-shared) | `.claude/settings.json` (git-tracked) |\\n\\n### MCP in Print/CI Mode\\n```\\nterminal(command=\\\"claude --bare -p 'Query database' --mcp-config mcp-servers.json --strict-mcp-config\\\", timeout=60)\\n```\\n`--strict-mcp-config` ignores all MCP servers except those from `--mcp-config`.\\n\\nReference MCP resources in chat: `@github:issue://123`\\n\\n### MCP Limits & Tuning\\n- **Tool descriptions:** 2KB cap per server for tool descriptions and server instructions\\n- **Result size:** Default capped; use `maxResultSizeChars` annotation to allow up to **500K** characters for large outputs\\n- **Output tokens:** `export MAX_MCP_OUTPUT_TOKENS=50000` — cap output from MCP servers to prevent context flooding\\n- **Transports:** `stdio` (local process), `http` (remote), `sse` (server-sent events)\\n\\n## Monitoring Interactive Sessions\\n\\n### Reading the TUI Status\\n```\\n# Periodic capture to check if Claude is still working or waiting for input\\nterminal(command=\\\"tmux capture-pane -t dev -p -S -10\\\")\\n```\\n\\nLook for these indicators:\\n- `❯` at bottom = waiting for your input (Claude is done or asking a question)\\n- `●` lines = Claude is actively using tools (reading, writing, running commands)\\n- `⏵⏵ bypass permissions on` = status bar showing permissions mode\\n- `◐ medium · /effort` = current effort level in status bar\\n- `ctrl+o to expand` = tool output was truncated (can be expanded interactively)\\n\\n### Context Window Health\\nUse `/context` in interactive mode to see a colored grid of context usage. Key thresholds:\\n- **< 70%** — Normal operation, full precision\\n- **70-85%** — Precision starts dropping, consider `/compact`\\n- **> 85%** — Hallucination risk spikes significantly, use `/compact` or `/clear`\\n\\n## Environment Variables\\n\\n| Variable | Effect |\\n|----------|--------|\\n| `ANTHROPIC_API_KEY` | API key for authentication (alternative to OAuth) |\\n| `CLAUDE_CODE_EFFORT_LEVEL` | Default effort: `low`, `medium`, `high`, `max`, or `auto` |\\n| `MAX_THINKING_TOKENS` | Cap thinking tokens (set to `0` to disable thinking entirely) |\\n| `MAX_MCP_OUTPUT_TOKENS` | Cap output from MCP servers (default varies; set e.g., `50000`) |\\n| `CLAUDE_CODE_NO_FLICKER=1` | Enable alt-screen rendering to eliminate terminal flicker |\\n| `CLAUDE_CODE_SUBPROCESS_ENV_SCRUB` | Strip credentials from sub-processes for security |\\n\\n## Cost & Performance Tips\\n\\n1. **Use `--max-turns`** in print mode to prevent runaway loops. Start with 5-10 for most tasks.\\n2. **Use `--max-budget-usd`** for cost caps. Note: minimum ~$0.05 for system prompt cache creation.\\n3. **Use `--effort low`** for simple tasks (faster, cheaper). `high` or `max` for complex reasoning.\\n4. **Use `--bare`** for CI/scripting to skip plugin/hook discovery overhead.\\n5. **Use `--allowedTools`** to restrict to only what's needed (e.g., `Read` only for reviews).\\n6. **Use `/compact`** in interactive sessions when context gets large.\\n7. **Pipe input** instead of having Claude read files when you just need analysis of known content.\\n8. **Use `--model haiku`** for simple tasks (cheaper) and `--model opus` for complex multi-step work.\\n9. **Use `--fallback-model haiku`** in print mode to gracefully handle model overload.\\n10. **Start new sessions for distinct tasks** — sessions last 5 hours; fresh context is more efficient.\\n11. **Use `--no-session-persistence`** in CI to avoid accumulating saved sessions on disk.\\n\\n## Pitfalls & Gotchas\\n\\n1. **Interactive mode REQUIRES tmux** — Claude Code is a full TUI app. Using `pty=true` alone in Hermes terminal works but tmux gives you `capture-pane` for monitoring and `send-keys` for input, which is essential for orchestration.\\n2. **`--dangerously-skip-permissions` dialog defaults to \\\"No, exit\\\"** — you must send Down then Enter to accept. Print mode (`-p`) skips this entirely.\\n3. **`--max-budget-usd` minimum is ~$0.05** — system prompt cache creation alone costs this much. Setting lower will error immediately.\\n4. **`--max-turns` is print-mode only** — ignored in interactive sessions.\\n5. **Claude may use `python` instead of `python3`** — on systems without a `python` symlink, Claude's bash commands will fail on first try but it self-corrects.\\n6. **Session resumption requires same directory** — `--continue` finds the most recent session for the current working directory.\\n7. **`--json-schema` needs enough `--max-turns`** — Claude must read files before producing structured output, which takes multiple turns.\\n8. **Trust dialog only appears once per directory** — first-time only, then cached.\\n9. **Background tmux sessions persist** — always clean up with `tmux kill-session -t <name>` when done.\\n10. **Slash commands (like `/commit`) only work in interactive mode** — in `-p` mode, describe the task in natural language instead.\\n11. **`--bare` skips OAuth** — requires `ANTHROPIC_API_KEY` env var or an `apiKeyHelper` in settings.\\n12. **Context degradation is real** — AI output quality measurably degrades above 70% context window usage. Monitor with `/context` and proactively `/compact`.\\n\\n## Rules for Hermes Agents\\n\\n1. **Prefer print mode (`-p`) for single tasks** — cleaner, no dialog handling, structured output\\n2. **Use tmux for multi-turn interactive work** — the only reliable way to orchestrate the TUI\\n3. **Always set `workdir`** — keep Claude focused on the right project directory\\n4. **Set `--max-turns` in print mode** — prevents infinite loops and runaway costs\\n5. **Monitor tmux sessions** — use `tmux capture-pane -t <session> -p -S -50` to check progress\\n6. **Look for the `❯` prompt** — indicates Claude is waiting for input (done or asking a question)\\n7. **Clean up tmux sessions** — kill them when done to avoid resource leaks\\n8. **Report results to user** — after completion, summarize what Claude did and what changed\\n9. **Don't kill slow sessions** — Claude may be doing multi-step work; check progress instead\\n10. **Use `--allowedTools`** — restrict capabilities to what the task actually needs\\n\", \"path\": \"autonomous-ai-agents/claude-code/SKILL.md\", \"skill_dir\": \"/home/kuhnn/.hermes/skills/autonomous-ai-agents/claude-code\", \"linked_files\": null, \"usage_hint\": null, \"required_environment_variables\": [], \"required_commands\": [], \"missing_required_environment_variables\": [], \"missing_credential_files\": [], \"missing_required_commands\": [], \"setup_needed\": false, \"setup_skipped\": false, \"readiness_status\": \"available\", \"metadata\": {\"hermes\": {\"tags\": [\"Coding-Agent\", \"Claude\", \"Anthropic\", \"Code-Review\", \"Refactoring\", \"PTY\", \"Automation\"], \"related_skills\": [\"codex\", \"hermes-agent\", \"opencode\"]}}}",
      "tool_call_id": "call_function_7wwd137adnfq_3"
    },
    {
      "role": "tool",
      "name": "skill_view",
      "content": "{\"success\": true, \"name\": \"codex\", \"description\": \"Delegate coding to OpenAI Codex CLI (features, PRs).\", \"tags\": [\"Coding-Agent\", \"Codex\", \"OpenAI\", \"Code-Review\", \"Refactoring\"], \"related_skills\": [\"claude-code\", \"hermes-agent\"], \"content\": \"---\\nname: codex\\ndescription: \\\"Delegate coding to OpenAI Codex CLI (features, PRs).\\\"\\nversion: 1.0.0\\nauthor: Hermes Agent\\nlicense: MIT\\nplatforms: [linux, macos, windows]\\nmetadata:\\n  hermes:\\n    tags: [Coding-Agent, Codex, OpenAI, Code-Review, Refactoring]\\n    related_skills: [claude-code, hermes-agent]\\n---\\n\\n# Codex CLI\\n\\nDelegate coding tasks to [Codex](https://github.com/openai/codex) via the Hermes terminal. Codex is OpenAI's autonomous coding agent CLI.\\n\\n## When to use\\n\\n- Building features\\n- Refactoring\\n- PR reviews\\n- Batch issue fixing\\n\\nRequires the codex CLI and a git repository.\\n\\n## Prerequisites\\n\\n- Codex installed: `npm install -g @openai/codex`\\n- OpenAI auth configured: either `OPENAI_API_KEY` or Codex OAuth credentials\\n  from the Codex CLI login flow\\n- **Must run inside a git repository** — Codex refuses to run outside one\\n- Use `pty=true` in terminal calls — Codex is an interactive terminal app\\n\\nFor Hermes itself, `model.provider: openai-codex` uses Hermes-managed Codex\\nOAuth from `~/.hermes/auth.json` after `hermes auth add openai-codex`. For the\\nstandalone Codex CLI, a valid CLI OAuth session may live under\\n`~/.codex/auth.json`; do not treat a missing `OPENAI_API_KEY` alone as proof\\nthat Codex auth is missing.\\n\\n## One-Shot Tasks\\n\\n```\\nterminal(command=\\\"codex exec 'Add dark mode toggle to settings'\\\", workdir=\\\"~/project\\\", pty=true)\\n```\\n\\nFor scratch work (Codex needs a git repo):\\n```\\nterminal(command=\\\"cd $(mktemp -d) && git init && codex exec 'Build a snake game in Python'\\\", pty=true)\\n```\\n\\n## Background Mode (Long Tasks)\\n\\n```\\n# Start in background with PTY\\nterminal(command=\\\"codex exec --full-auto 'Refactor the auth module'\\\", workdir=\\\"~/project\\\", background=true, pty=true)\\n# Returns session_id\\n\\n# Monitor progress\\nprocess(action=\\\"poll\\\", session_id=\\\"<id>\\\")\\nprocess(action=\\\"log\\\", session_id=\\\"<id>\\\")\\n\\n# Send input if Codex asks a question\\nprocess(action=\\\"submit\\\", session_id=\\\"<id>\\\", data=\\\"yes\\\")\\n\\n# Kill if needed\\nprocess(action=\\\"kill\\\", session_id=\\\"<id>\\\")\\n```\\n\\n## Key Flags\\n\\n| Flag | Effect |\\n|------|--------|\\n| `exec \\\"prompt\\\"` | One-shot execution, exits when done |\\n| `--full-auto` | Sandboxed but auto-approves file changes in workspace |\\n| `--yolo` | No sandbox, no approvals (fastest, most dangerous) |\\n\\n## PR Reviews\\n\\nClone to a temp directory for safe review:\\n\\n```\\nterminal(command=\\\"REVIEW=$(mktemp -d) && git clone https://github.com/user/repo.git $REVIEW && cd $REVIEW && gh pr checkout 42 && codex review --base origin/main\\\", pty=true)\\n```\\n\\n## Parallel Issue Fixing with Worktrees\\n\\n```\\n# Create worktrees\\nterminal(command=\\\"git worktree add -b fix/issue-78 /tmp/issue-78 main\\\", workdir=\\\"~/project\\\")\\nterminal(command=\\\"git worktree add -b fix/issue-99 /tmp/issue-99 main\\\", workdir=\\\"~/project\\\")\\n\\n# Launch Codex in each\\nterminal(command=\\\"codex --yolo exec 'Fix issue #78: <description>. Commit when done.'\\\", workdir=\\\"/tmp/issue-78\\\", background=true, pty=true)\\nterminal(command=\\\"codex --yolo exec 'Fix issue #99: <description>. Commit when done.'\\\", workdir=\\\"/tmp/issue-99\\\", background=true, pty=true)\\n\\n# Monitor\\nprocess(action=\\\"list\\\")\\n\\n# After completion, push and create PRs\\nterminal(command=\\\"cd /tmp/issue-78 && git push -u origin fix/issue-78\\\")\\nterminal(command=\\\"gh pr create --repo user/repo --head fix/issue-78 --title 'fix: ...' --body '...'\\\")\\n\\n# Cleanup\\nterminal(command=\\\"git worktree remove /tmp/issue-78\\\", workdir=\\\"~/project\\\")\\n```\\n\\n## Batch PR Reviews\\n\\n```\\n# Fetch all PR refs\\nterminal(command=\\\"git fetch origin '+refs/pull/*/head:refs/remotes/origin/pr/*'\\\", workdir=\\\"~/project\\\")\\n\\n# Review multiple PRs in parallel\\nterminal(command=\\\"codex exec 'Review PR #86. git diff origin/main...origin/pr/86'\\\", workdir=\\\"~/project\\\", background=true, pty=true)\\nterminal(command=\\\"codex exec 'Review PR #87. git diff origin/main...origin/pr/87'\\\", workdir=\\\"~/project\\\", background=true, pty=true)\\n\\n# Post results\\nterminal(command=\\\"gh pr comment 86 --body '<review>'\\\", workdir=\\\"~/project\\\")\\n```\\n\\n## Rules\\n\\n1. **Always use `pty=true`** — Codex is an interactive terminal app and hangs without a PTY\\n2. **Git repo required** — Codex won't run outside a git directory. Use `mktemp -d && git init` for scratch\\n3. **Use `exec` for one-shots** — `codex exec \\\"prompt\\\"` runs and exits cleanly\\n4. **`--full-auto` for building** — auto-approves changes within the sandbox\\n5. **Background for long tasks** — use `background=true` and monitor with `process` tool\\n6. **Don't interfere** — monitor with `poll`/`log`, be patient with long-running tasks\\n7. **Parallel is fine** — run multiple Codex processes at once for batch work\\n\", \"path\": \"autonomous-ai-agents/codex/SKILL.md\", \"skill_dir\": \"/home/kuhnn/.hermes/skills/autonomous-ai-agents/codex\", \"linked_files\": null, \"usage_hint\": null, \"required_environment_variables\": [], \"required_commands\": [], \"missing_required_environment_variables\": [], \"missing_credential_files\": [], \"missing_required_commands\": [], \"setup_needed\": false, \"setup_skipped\": false, \"readiness_status\": \"available\", \"metadata\": {\"hermes\": {\"tags\": [\"Coding-Agent\", \"Codex\", \"OpenAI\", \"Code-Review\", \"Refactoring\"], \"related_skills\": [\"claude-code\", \"hermes-agent\"]}}}",
      "tool_call_id": "call_function_7wwd137adnfq_4"
    },
    {
      "role": "tool",
      "name": "skill_view",
      "content": "{\"success\": true, \"name\": \"hermes-agent\", \"description\": \"Configure, extend, or contribute to Hermes Agent.\", \"tags\": [\"hermes\", \"setup\", \"configuration\", \"multi-agent\", \"spawning\", \"cli\", \"gateway\", \"development\"], \"related_skills\": [\"claude-code\", \"codex\", \"opencode\"], \"content\": \"---\\nname: hermes-agent\\ndescription: \\\"Configure, extend, or contribute to Hermes Agent.\\\"\\nversion: 2.1.0\\nauthor: Hermes Agent + Teknium\\nlicense: MIT\\nplatforms: [linux, macos, windows]\\nmetadata:\\n  hermes:\\n    tags: [hermes, setup, configuration, multi-agent, spawning, cli, gateway, development]\\n    homepage: https://github.com/NousResearch/hermes-agent\\n    related_skills: [claude-code, codex, opencode]\\n---\\n\\n# Hermes Agent\\n\\nHermes Agent is an open-source AI agent framework by Nous Research that runs in your terminal, messaging platforms, and IDEs. It belongs to the same category as Claude Code (Anthropic), Codex (OpenAI), and OpenClaw — autonomous coding and task-execution agents that use tool calling to interact with your system. Hermes works with any LLM provider (OpenRouter, Anthropic, OpenAI, DeepSeek, local models, and 15+ others) and runs on Linux, macOS, and WSL.\\n\\nWhat makes Hermes different:\\n\\n- **Self-improving through skills** — Hermes learns from experience by saving reusable procedures as skills. When it solves a complex problem, discovers a workflow, or gets corrected, it can persist that knowledge as a skill document that loads into future sessions. Skills accumulate over time, making the agent better at your specific tasks and environment.\\n- **Persistent memory across sessions** — remembers who you are, your preferences, environment details, and lessons learned. Pluggable memory backends (built-in, Honcho, Mem0, and more) let you choose how memory works.\\n- **Multi-platform gateway** — the same agent runs on Telegram, Discord, Slack, WhatsApp, Signal, Matrix, Email, and 10+ other platforms with full tool access, not just chat.\\n- **Provider-agnostic** — swap models and providers mid-workflow without changing anything else. Credential pools rotate across multiple API keys automatically.\\n- **Profiles** — run multiple independent Hermes instances with isolated configs, sessions, skills, and memory.\\n- **Extensible** — plugins, MCP servers, custom tools, webhook triggers, cron scheduling, and the full Python ecosystem.\\n\\nPeople use Hermes for software development, research, system administration, data analysis, content creation, home automation, and anything else that benefits from an AI agent with persistent context and full system access.\\n\\n**This skill helps you work with Hermes Agent effectively** — setting it up, configuring features, spawning additional agent instances, troubleshooting issues, finding the right commands and settings, and understanding how the system works when you need to extend or contribute to it.\\n\\n**Docs:** https://hermes-agent.nousresearch.com/docs/\\n\\n## Quick Start\\n\\n```bash\\n# Install\\ncurl -fsSL https://raw.githubusercontent.com/NousResearch/hermes-agent/main/scripts/install.sh | bash\\n\\n# Interactive chat (default)\\nhermes\\n\\n# Single query\\nhermes chat -q \\\"What is the capital of France?\\\"\\n\\n# Setup wizard\\nhermes setup\\n\\n# Change model/provider\\nhermes model\\n\\n# Check health\\nhermes doctor\\n```\\n\\n---\\n\\n## CLI Reference\\n\\n### Global Flags\\n\\n```\\nhermes [flags] [command]\\n\\n  --version, -V             Show version\\n  --resume, -r SESSION      Resume session by ID or title\\n  --continue, -c [NAME]     Resume by name, or most recent session\\n  --worktree, -w            Isolated git worktree mode (parallel agents)\\n  --skills, -s SKILL        Preload skills (comma-separate or repeat)\\n  --profile, -p NAME        Use a named profile\\n  --yolo                    Skip dangerous command approval\\n  --pass-session-id         Include session ID in system prompt\\n```\\n\\nNo subcommand defaults to `chat`.\\n\\n### Chat\\n\\n```\\nhermes chat [flags]\\n  -q, --query TEXT          Single query, non-interactive\\n  -m, --model MODEL         Model (e.g. anthropic/claude-sonnet-4)\\n  -t, --toolsets LIST       Comma-separated toolsets\\n  --provider PROVIDER       Force provider (openrouter, anthropic, nous, etc.)\\n  -v, --verbose             Verbose output\\n  -Q, --quiet               Suppress banner, spinner, tool previews\\n  --checkpoints             Enable filesystem checkpoints (/rollback)\\n  --source TAG              Session source tag (default: cli)\\n```\\n\\n### Configuration\\n\\n```\\nhermes setup [section]      Interactive wizard (model|terminal|gateway|tools|agent)\\nhermes model                Interactive model/provider picker\\nhermes config               View current config\\nhermes config edit          Open config.yaml in $EDITOR\\nhermes config set KEY VAL   Set a config value\\nhermes config path          Print config.yaml path\\nhermes config env-path      Print .env path\\nhermes config check         Check for missing/outdated config\\nhermes config migrate       Update config with new options\\nhermes login [--provider P] OAuth login (nous, openai-codex)\\nhermes logout               Clear stored auth\\nhermes doctor [--fix]       Check dependencies and config\\nhermes status [--all]       Show component status\\n```\\n\\n### Tools & Skills\\n\\n```\\nhermes tools                Interactive tool enable/disable (curses UI)\\nhermes tools list           Show all tools and status\\nhermes tools enable NAME    Enable a toolset\\nhermes tools disable NAME   Disable a toolset\\n\\nhermes skills list          List installed skills\\nhermes skills search QUERY  Search the skills hub\\nhermes skills install ID    Install a skill (ID can be a hub identifier OR a direct https://…/SKILL.md URL; pass --name to override when frontmatter has no name)\\nhermes skills inspect ID    Preview without installing\\nhermes skills config        Enable/disable skills per platform\\nhermes skills check         Check for updates\\nhermes skills update        Update outdated skills\\nhermes skills uninstall N   Remove a hub skill\\nhermes skills publish PATH  Publish to registry\\nhermes skills browse        Browse all available skills\\nhermes skills tap add REPO  Add a GitHub repo as skill source\\n```\\n\\n### MCP Servers\\n\\n```\\nhermes mcp serve            Run Hermes as an MCP server\\nhermes mcp add NAME         Add an MCP server (--url or --command)\\nhermes mcp remove NAME      Remove an MCP server\\nhermes mcp list             List configured servers\\nhermes mcp test NAME        Test connection\\nhermes mcp configure NAME   Toggle tool selection\\n```\\n\\n### Gateway (Messaging Platforms)\\n\\n```\\nhermes gateway run          Start gateway foreground\\nhermes gateway install     Install as background service (systemd user service)\\nhermes gateway start/stop   Control the service\\nhermes gateway restart      Restart the service\\nhermes gateway status       Check status\\nhermes gateway setup        Configure platforms\\n```\\n\\nSupported platforms: Telegram, Discord, Slack, WhatsApp, Signal, Email, SMS, Matrix, Mattermost, Home Assistant, DingTalk, Feishu, WeCom, BlueBubbles (iMessage), Weixin (WeChat), API Server, Webhooks. Open WebUI connects via the API Server adapter.\\n\\nPlatform docs: https://hermes-agent.nousresearch.com/docs/user-guide/messaging/\\n\\n### Web UI (Open WebUI)\\n\\nHermes does NOT have a built-in web UI. To access Hermes via a browser, use **Open WebUI** — a separate open-source web interface that connects to Hermes's API Server:\\n\\n```bash\\n# 1. Install Open WebUI\\npip install open-webui\\n\\n# 2. Start the gateway (needed for API Server to be available)\\nhermes gateway install   # Set up systemd service\\nhermes gateway start     # Start it\\n\\n# 3. Run Open WebUI, pointing it at Hermes gateway's API Server endpoint\\n# Default endpoint: http://localhost:8000/v1 (verify the port in your config)\\nopen-webui serve --host 0.0.0.0 --port 8080\\n\\n# 4. Open browser to http://localhost:8080\\n```\\n\\nThe API Server adapter must be enabled in your gateway platform config. Check `hermes gateway setup` → API Server.\\n\\nGateway status check: `hermes gateway status`\\nView logs: `journalctl --user -u hermes-gateway -f`\\n\\n### Sessions\\n\\n```\\nhermes sessions list        List recent sessions\\nhermes sessions browse      Interactive picker\\nhermes sessions export OUT  Export to JSONL\\nhermes sessions rename ID T Rename a session\\nhermes sessions delete ID   Delete a session\\nhermes sessions prune       Clean up old sessions (--older-than N days)\\nhermes sessions stats       Session store statistics\\n```\\n\\n### Cron Jobs\\n\\n```\\nhermes cron list            List jobs (--all for disabled)\\nhermes cron create SCHED    Create: '30m', 'every 2h', '0 9 * * *'\\nhermes cron edit ID         Edit schedule, prompt, delivery\\nhermes cron pause/resume ID Control job state\\nhermes cron run ID          Trigger on next tick\\nhermes cron remove ID       Delete a job\\nhermes cron status          Scheduler status\\n```\\n\\n### Webhooks\\n\\n```\\nhermes webhook subscribe N  Create route at /webhooks/<name>\\nhermes webhook list         List subscriptions\\nhermes webhook remove NAME  Remove a subscription\\nhermes webhook test NAME    Send a test POST\\n```\\n\\n### Profiles\\n\\n```\\nhermes profile list         List all profiles\\nhermes profile create NAME  Create (--clone, --clone-all, --clone-from)\\nhermes profile use NAME     Set sticky default\\nhermes profile delete NAME  Delete a profile\\nhermes profile show NAME    Show details\\nhermes profile alias NAME   Manage wrapper scripts\\nhermes profile rename A B   Rename a profile\\nhermes profile export NAME  Export to tar.gz\\nhermes profile import FILE  Import from archive\\n```\\n\\n### Credential Pools\\n\\n```\\nhermes auth add             Interactive credential wizard\\nhermes auth list [PROVIDER] List pooled credentials\\nhermes auth remove P INDEX  Remove by provider + index\\nhermes auth reset PROVIDER  Clear exhaustion status\\n```\\n\\n### Other\\n\\n```\\nhermes insights [--days N]  Usage analytics\\nhermes update               Update to latest version\\nhermes pairing list/approve/revoke  DM authorization\\nhermes plugins list/install/remove  Plugin management\\nhermes honcho setup/status  Honcho memory integration (requires honcho plugin)\\nhermes memory setup/status/off  Memory provider config\\nhermes completion bash|zsh  Shell completions\\nhermes acp                  ACP server (IDE integration)\\nhermes claw migrate         Migrate from OpenClaw\\nhermes uninstall            Uninstall Hermes\\n```\\n\\n---\\n\\n## Slash Commands (In-Session)\\n\\nType these during an interactive chat session. New commands land fairly\\noften; if something below looks stale, run `/help` in-session for the\\nauthoritative list or see the [live slash commands reference](https://hermes-agent.nousresearch.com/docs/reference/slash-commands).\\nThe registry of record is `hermes_cli/commands.py` — every consumer\\n(autocomplete, Telegram menu, Slack mapping, `/help`) derives from it.\\n\\n### Session Control\\n```\\n/new (/reset)        Fresh session\\n/clear               Clear screen + new session (CLI)\\n/retry               Resend last message\\n/undo                Remove last exchange\\n/title [name]        Name the session\\n/compress            Manually compress context\\n/stop                Kill background processes\\n/rollback [N]        Restore filesystem checkpoint\\n/snapshot [sub]      Create or restore state snapshots of Hermes config/state (CLI)\\n/background <prompt> Run prompt in background\\n/queue <prompt>      Queue for next turn\\n/steer <prompt>      Inject a message after the next tool call without interrupting\\n/agents (/tasks)     Show active agents and running tasks\\n/resume [name]       Resume a named session\\n/goal [text|sub]     Set a standing goal Hermes works on across turns until achieved\\n                     (subcommands: status, pause, resume, clear)\\n/redraw              Force a full UI repaint (CLI)\\n```\\n\\n### Configuration\\n```\\n/config              Show config (CLI)\\n/model [name]        Show or change model\\n/personality [name]  Set personality\\n/reasoning [level]   Set reasoning (none|minimal|low|medium|high|xhigh|show|hide)\\n/verbose             Cycle: off → new → all → verbose\\n/voice [on|off|tts]  Voice mode\\n/yolo                Toggle approval bypass\\n/busy [sub]          Control what Enter does while Hermes is working (CLI)\\n                     (subcommands: queue, steer, interrupt, status)\\n/indicator [style]   Pick the TUI busy-indicator style (CLI)\\n                     (styles: kaomoji, emoji, unicode, ascii)\\n/footer [on|off]     Toggle gateway runtime-metadata footer on final replies\\n/skin [name]         Change theme (CLI)\\n/statusbar           Toggle status bar (CLI)\\n```\\n\\n### Tools & Skills\\n```\\n/tools               Manage tools (CLI)\\n/toolsets            List toolsets (CLI)\\n/skills              Search/install skills (CLI)\\n/skill <name>        Load a skill into session\\n/reload-skills       Re-scan ~/.hermes/skills/ for added/removed skills\\n/reload              Reload .env variables into the running session (CLI)\\n/reload-mcp          Reload MCP servers\\n/cron                Manage cron jobs (CLI)\\n/curator [sub]       Background skill maintenance (status, run, pin, archive, …)\\n/kanban [sub]        Multi-profile collaboration board (tasks, links, comments)\\n/plugins             List plugins (CLI)\\n```\\n\\n### Gateway\\n```\\n/approve             Approve a pending command (gateway)\\n/deny                Deny a pending command (gateway)\\n/restart             Restart gateway (gateway)\\n/sethome             Set current chat as home channel (gateway)\\n/update              Update Hermes to latest (gateway)\\n/topic [sub]         Enable or inspect Telegram DM topic sessions (gateway)\\n/platforms (/gateway) Show platform connection status (gateway)\\n```\\n\\n### Utility\\n```\\n/branch (/fork)      Branch the current session\\n/fast                Toggle priority/fast processing\\n/browser             Open CDP browser connection\\n/history             Show conversation history (CLI)\\n/save                Save conversation to file (CLI)\\n/copy [N]            Copy the last assistant response to clipboard (CLI)\\n/paste               Attach clipboard image (CLI)\\n/image               Attach local image file (CLI)\\n```\\n\\n### Info\\n```\\n/help                Show commands\\n/commands [page]     Browse all commands (gateway)\\n/usage               Token usage\\n/insights [days]     Usage analytics\\n/gquota              Show Google Gemini Code Assist quota usage (CLI)\\n/status              Session info (gateway)\\n/profile             Active profile info\\n/debug               Upload debug report (system info + logs) and get shareable links\\n```\\n\\n### Exit\\n```\\n/quit (/exit, /q)    Exit CLI\\n```\\n\\n---\\n\\n## Key Paths & Config\\n\\n```\\n~/.hermes/config.yaml       Main configuration\\n~/.hermes/.env              API keys and secrets\\n$HERMES_HOME/skills/        Installed skills\\n~/.hermes/sessions/         Session transcripts\\n~/.hermes/logs/             Gateway and error logs\\n~/.hermes/auth.json         OAuth tokens and credential pools\\n~/.hermes/hermes-agent/     Source code (if git-installed)\\n```\\n\\nProfiles use `~/.hermes/profiles/<name>/` with the same layout.\\n\\n### Config Sections\\n\\nEdit with `hermes config edit` or `hermes config set section.key value`.\\n\\n| Section | Key options |\\n|---------|-------------|\\n| `model` | `default`, `provider`, `base_url`, `api_key`, `context_length` |\\n| `agent` | `max_turns` (90), `tool_use_enforcement` |\\n| `terminal` | `backend` (local/docker/ssh/modal), `cwd`, `timeout` (180) |\\n| `compression` | `enabled`, `threshold` (0.50), `target_ratio` (0.20) |\\n| `display` | `skin`, `tool_progress`, `show_reasoning`, `show_cost` |\\n| `stt` | `enabled`, `provider` (local/groq/openai/mistral) |\\n| `tts` | `provider` (edge/elevenlabs/openai/minimax/mistral/neutts) |\\n| `memory` | `memory_enabled`, `user_profile_enabled`, `provider` |\\n| `security` | `tirith_enabled`, `website_blocklist` |\\n| `delegation` | `model`, `provider`, `base_url`, `api_key`, `max_iterations` (50), `reasoning_effort` |\\n| `checkpoints` | `enabled`, `max_snapshots` (50) |\\n\\nFull config reference: https://hermes-agent.nousresearch.com/docs/user-guide/configuration\\n\\n### Providers\\n\\n20+ providers supported. Set via `hermes model` or `hermes setup`.\\n\\n| Provider | Auth | Key env var |\\n|----------|------|-------------|\\n| OpenRouter | API key | `OPENROUTER_API_KEY` |\\n| Anthropic | API key | `ANTHROPIC_API_KEY` |\\n| Nous Portal | OAuth | `hermes auth` |\\n| OpenAI Codex | OAuth | `hermes auth` |\\n| GitHub Copilot | Token | `COPILOT_GITHUB_TOKEN` |\\n| Google Gemini | API key | `GOOGLE_API_KEY` or `GEMINI_API_KEY` |\\n| DeepSeek | API key | `DEEPSEEK_API_KEY` |\\n| xAI / Grok | API key | `XAI_API_KEY` |\\n| Hugging Face | Token | `HF_TOKEN` |\\n| Z.AI / GLM | API key | `GLM_API_KEY` |\\n| MiniMax | API key | `MINIMAX_API_KEY` |\\n| MiniMax CN | API key | `MINIMAX_CN_API_KEY` |\\n| Kimi / Moonshot | API key | `KIMI_API_KEY` |\\n| Alibaba / DashScope | API key | `DASHSCOPE_API_KEY` |\\n| Xiaomi MiMo | API key | `XIAOMI_API_KEY` |\\n| Kilo Code | API key | `KILOCODE_API_KEY` |\\n| AI Gateway (Vercel) | API key | `AI_GATEWAY_API_KEY` |\\n| OpenCode Zen | API key | `OPENCODE_ZEN_API_KEY` |\\n| OpenCode Go | API key | `OPENCODE_GO_API_KEY` |\\n| Qwen OAuth | OAuth | `hermes login --provider qwen-oauth` |\\n| Custom endpoint | Config | `model.base_url` + `model.api_key` in config.yaml |\\n| GitHub Copilot ACP | External | `COPILOT_CLI_PATH` or Copilot CLI |\\n\\nFull provider docs: https://hermes-agent.nousresearch.com/docs/integrations/providers\\n\\n### Toolsets\\n\\nEnable/disable via `hermes tools` (interactive) or `hermes tools enable/disable NAME`.\\n\\n| Toolset | What it provides |\\n|---------|-----------------|\\n| `web` | Web search and content extraction |\\n| `search` | Web search only (subset of `web`) |\\n| `browser` | Browser automation (Browserbase, Camofox, or local Chromium) |\\n| `terminal` | Shell commands and process management |\\n| `file` | File read/write/search/patch |\\n| `code_execution` | Sandboxed Python execution |\\n| `vision` | Image analysis |\\n| `image_gen` | AI image generation |\\n| `video` | Video analysis and generation |\\n| `tts` | Text-to-speech |\\n| `skills` | Skill browsing and management |\\n| `memory` | Persistent cross-session memory |\\n| `session_search` | Search past conversations |\\n| `delegation` | Subagent task delegation |\\n| `cronjob` | Scheduled task management |\\n| `clarify` | Ask user clarifying questions |\\n| `messaging` | Cross-platform message sending |\\n| `todo` | In-session task planning and tracking |\\n| `kanban` | Multi-agent work-queue tools (gated to workers) |\\n| `debugging` | Extra introspection/debug tools (off by default) |\\n| `safe` | Minimal, low-risk toolset for locked-down sessions |\\n| `spotify` | Spotify playback and playlist control |\\n| `homeassistant` | Smart home control (off by default) |\\n| `discord` | Discord integration tools |\\n| `discord_admin` | Discord admin/moderation tools |\\n| `feishu_doc` | Feishu (Lark) document tools |\\n| `feishu_drive` | Feishu (Lark) drive tools |\\n| `yuanbao` | Yuanbao integration tools |\\n| `rl` | Reinforcement learning tools (off by default) |\\n| `moa` | Mixture of Agents (off by default) |\\n\\nFull enumeration lives in `toolsets.py` as the `TOOLSETS` dict; `_HERMES_CORE_TOOLS` is the default bundle most platforms inherit from.\\n\\nTool changes take effect on `/reset` (new session). They do NOT apply mid-conversation to preserve prompt caching.\\n\\n---\\n\\n## Security & Privacy Toggles\\n\\nCommon \\\"why is Hermes doing X to my output / tool calls / commands?\\\" toggles — and the exact commands to change them. Most of these need a fresh session (`/reset` in chat, or start a new `hermes` invocation) because they're read once at startup.\\n\\n### Secret redaction in tool output\\n\\nSecret redaction is **off by default** — tool output (terminal stdout, `read_file`, web content, subagent summaries, etc.) passes through unmodified. If the user wants Hermes to auto-mask strings that look like API keys, tokens, and secrets before they enter the conversation context and logs:\\n\\n```bash\\nhermes config set security.redact_secrets true       # enable globally\\n```\\n\\n**Restart required.** `security.redact_secrets` is snapshotted at import time — toggling it mid-session (e.g. via `export HERMES_REDACT_SECRETS=true` from a tool call) will NOT take effect for the running process. Tell the user to run `hermes config set security.redact_secrets true` in a terminal, then start a new session. This is deliberate — it prevents an LLM from flipping the toggle on itself mid-task.\\n\\nDisable again with:\\n```bash\\nhermes config set security.redact_secrets false\\n```\\n\\n### PII redaction in gateway messages\\n\\nSeparate from secret redaction. When enabled, the gateway hashes user IDs and strips phone numbers from the session context before it reaches the model:\\n\\n```bash\\nhermes config set privacy.redact_pii true    # enable\\nhermes config set privacy.redact_pii false   # disable (default)\\n```\\n\\n### Command approval prompts\\n\\nBy default (`approvals.mode: manual`), Hermes prompts the user before running shell commands flagged as destructive (`rm -rf`, `git reset --hard`, etc.). The modes are:\\n\\n- `manual` — always prompt (default)\\n- `smart` — use an auxiliary LLM to auto-approve low-risk commands, prompt on high-risk\\n- `off` — skip all approval prompts (equivalent to `--yolo`)\\n\\n```bash\\nhermes config set approvals.mode smart       # recommended middle ground\\nhermes config set approvals.mode off         # bypass everything (not recommended)\\n```\\n\\nPer-invocation bypass without changing config:\\n- `hermes --yolo …`\\n- `export HERMES_YOLO_MODE=1`\\n\\nNote: YOLO / `approvals.mode: off` does NOT turn off secret redaction. They are independent.\\n\\n### Shell hooks allowlist\\n\\nSome shell-hook integrations require explicit allowlisting before they fire. Managed via `~/.hermes/shell-hooks-allowlist.json` — prompted interactively the first time a hook wants to run.\\n\\n### Disabling the web/browser/image-gen tools\\n\\nTo keep the model away from network or media tools entirely, open `hermes tools` and toggle per-platform. Takes effect on next session (`/reset`). See the Tools & Skills section above.\\n\\n---\\n\\n## Voice & Transcription\\n\\n### STT (Voice → Text)\\n\\nVoice messages from messaging platforms are auto-transcribed.\\n\\nProvider priority (auto-detected):\\n1. **Local faster-whisper** — free, no API key: `pip install faster-whisper`\\n2. **Groq Whisper** — free tier: set `GROQ_API_KEY`\\n3. **OpenAI Whisper** — paid: set `VOICE_TOOLS_OPENAI_KEY`\\n4. **Mistral Voxtral** — set `MISTRAL_API_KEY`\\n\\nConfig:\\n```yaml\\nstt:\\n  enabled: true\\n  provider: local        # local, groq, openai, mistral\\n  local:\\n    model: base          # tiny, base, small, medium, large-v3\\n```\\n\\n### TTS (Text → Voice)\\n\\n| Provider | Env var | Free? |\\n|----------|---------|-------|\\n| Edge TTS | None | Yes (default) |\\n| ElevenLabs | `ELEVENLABS_API_KEY` | Free tier |\\n| OpenAI | `VOICE_TOOLS_OPENAI_KEY` | Paid |\\n| MiniMax | `MINIMAX_API_KEY` | Paid |\\n| Mistral (Voxtral) | `MISTRAL_API_KEY` | Paid |\\n| NeuTTS (local) | None (`pip install neutts[all]` + `espeak-ng`) | Free |\\n\\nVoice commands: `/voice on` (voice-to-voice), `/voice tts` (always voice), `/voice off`.\\n\\n---\\n\\n## Spawning Additional Hermes Instances\\n\\nRun additional Hermes processes as fully independent subprocesses — separate sessions, tools, and environments.\\n\\n### When to Use This vs delegate_task\\n\\n| | `delegate_task` | Spawning `hermes` process |\\n|-|-----------------|--------------------------|\\n| Isolation | Separate conversation, shared process | Fully independent process |\\n| Duration | Minutes (bounded by parent loop) | Hours/days |\\n| Tool access | Subset of parent's tools | Full tool access |\\n| Interactive | No | Yes (PTY mode) |\\n| Use case | Quick parallel subtasks | Long autonomous missions |\\n\\n### One-Shot Mode\\n\\n```\\nterminal(command=\\\"hermes chat -q 'Research GRPO papers and write summary to ~/research/grpo.md'\\\", timeout=300)\\n\\n# Background for long tasks:\\nterminal(command=\\\"hermes chat -q 'Set up CI/CD for ~/myapp'\\\", background=true)\\n```\\n\\n### Interactive PTY Mode (via tmux)\\n\\nHermes uses prompt_toolkit, which requires a real terminal. Use tmux for interactive spawning:\\n\\n```\\n# Start\\nterminal(command=\\\"tmux new-session -d -s agent1 -x 120 -y 40 'hermes'\\\", timeout=10)\\n\\n# Wait for startup, then send a message\\nterminal(command=\\\"sleep 8 && tmux send-keys -t agent1 'Build a FastAPI auth service' Enter\\\", timeout=15)\\n\\n# Read output\\nterminal(command=\\\"sleep 20 && tmux capture-pane -t agent1 -p\\\", timeout=5)\\n\\n# Send follow-up\\nterminal(command=\\\"tmux send-keys -t agent1 'Add rate limiting middleware' Enter\\\", timeout=5)\\n\\n# Exit\\nterminal(command=\\\"tmux send-keys -t agent1 '/exit' Enter && sleep 2 && tmux kill-session -t agent1\\\", timeout=10)\\n```\\n\\n### Multi-Agent Coordination\\n\\n```\\n# Agent A: backend\\nterminal(command=\\\"tmux new-session -d -s backend -x 120 -y 40 'hermes -w'\\\", timeout=10)\\nterminal(command=\\\"sleep 8 && tmux send-keys -t backend 'Build REST API for user management' Enter\\\", timeout=15)\\n\\n# Agent B: frontend\\nterminal(command=\\\"tmux new-session -d -s frontend -x 120 -y 40 'hermes -w'\\\", timeout=10)\\nterminal(command=\\\"sleep 8 && tmux send-keys -t frontend 'Build React dashboard for user management' Enter\\\", timeout=15)\\n\\n# Check progress, relay context between them\\nterminal(command=\\\"tmux capture-pane -t backend -p | tail -30\\\", timeout=5)\\nterminal(command=\\\"tmux send-keys -t frontend 'Here is the API schema from the backend agent: ...' Enter\\\", timeout=5)\\n```\\n\\n### Session Resume\\n\\n```\\n# Resume most recent session\\nterminal(command=\\\"tmux new-session -d -s resumed 'hermes --continue'\\\", timeout=10)\\n\\n# Resume specific session\\nterminal(command=\\\"tmux new-session -d -s resumed 'hermes --resume 20260225_143052_a1b2c3'\\\", timeout=10)\\n```\\n\\n### Tips\\n\\n- **Prefer `delegate_task` for quick subtasks** — less overhead than spawning a full process\\n- **Use `-w` (worktree mode)** when spawning agents that edit code — prevents git conflicts\\n- **Set timeouts** for one-shot mode — complex tasks can take 5-10 minutes\\n- **Use `hermes chat -q` for fire-and-forget** — no PTY needed\\n- **Use tmux for interactive sessions** — raw PTY mode has `\\\\r` vs `\\\\n` issues with prompt_toolkit\\n- **For scheduled tasks**, use the `cronjob` tool instead of spawning — handles delivery and retry\\n\\n---\\n\\n## Durable & Background Systems\\n\\nFour systems run alongside the main conversation loop. Quick reference\\nhere; full developer notes live in `AGENTS.md`, user-facing docs under\\n`website/docs/user-guide/features/`.\\n\\n### Delegation (`delegate_task`)\\n\\nSynchronous subagent spawn — the parent waits for the child's summary\\nbefore continuing its own loop. Isolated context + terminal session.\\n\\n- **Single:** `delegate_task(goal, context, toolsets)`.\\n- **Batch:** `delegate_task(tasks=[{goal, ...}, ...])` runs children in\\n  parallel, capped by `delegation.max_concurrent_children` (default 3).\\n- **Roles:** `leaf` (default; cannot re-delegate) vs `orchestrator`\\n  (can spawn its own workers, bounded by `delegation.max_spawn_depth`).\\n- **Not durable.** If the parent is interrupted, the child is\\n  cancelled. For work that must outlive the turn, use `cronjob` or\\n  `terminal(background=True, notify_on_complete=True)`.\\n\\nConfig: `delegation.*` in `config.yaml`.\\n\\n### Cron (scheduled jobs)\\n\\nDurable scheduler — `cron/jobs.py` + `cron/scheduler.py`. Drive it via\\nthe `cronjob` tool, the `hermes cron` CLI (`list`, `add`, `edit`,\\n`pause`, `resume`, `run`, `remove`), or the `/cron` slash command.\\n\\n- **Schedules:** duration (`\\\"30m\\\"`, `\\\"2h\\\"`), \\\"every\\\" phrase\\n  (`\\\"every monday 9am\\\"`), 5-field cron (`\\\"0 9 * * *\\\"`), or ISO timestamp.\\n- **Per-job knobs:** `skills`, `model`/`provider` override, `script`\\n  (pre-run data collection; `no_agent=True` makes the script the whole\\n  job), `context_from` (chain job A's output into job B), `workdir`\\n  (run in a specific dir with its `AGENTS.md` / `CLAUDE.md` loaded),\\n  multi-platform delivery.\\n- **Invariants:** 3-minute hard interrupt per run, `.tick.lock` file\\n  prevents duplicate ticks across processes, cron sessions pass\\n  `skip_memory=True` by default, and cron deliveries are framed with a\\n  header/footer instead of being mirrored into the target gateway\\n  session (keeps role alternation intact).\\n\\nUser docs: https://hermes-agent.nousresearch.com/docs/user-guide/features/cron\\n\\n### Curator (skill lifecycle)\\n\\nBackground maintenance for agent-created skills. Tracks usage, marks\\nidle skills stale, archives stale ones, keeps a pre-run tar.gz backup\\nso nothing is lost.\\n\\n- **CLI:** `hermes curator <verb>` — `status`, `run`, `pause`, `resume`,\\n  `pin`, `unpin`, `archive`, `restore`, `prune`, `backup`, `rollback`.\\n- **Slash:** `/curator <subcommand>` mirrors the CLI.\\n- **Scope:** only touches skills with `created_by: \\\"agent\\\"` provenance.\\n  Bundled + hub-installed skills are off-limits. **Never deletes** —\\n  max destructive action is archive. Pinned skills are exempt from\\n  every auto-transition and every LLM review pass.\\n- **Telemetry:** sidecar at `~/.hermes/skills/.usage.json` holds\\n  per-skill `use_count`, `view_count`, `patch_count`,\\n  `last_activity_at`, `state`, `pinned`.\\n\\nConfig: `curator.*` (`enabled`, `interval_hours`, `min_idle_hours`,\\n`stale_after_days`, `archive_after_days`, `backup.*`).\\nUser docs: https://hermes-agent.nousresearch.com/docs/user-guide/features/curator\\n\\n### Kanban (multi-agent work queue)\\n\\nDurable SQLite board for multi-profile / multi-worker collaboration.\\nUsers drive it via `hermes kanban <verb>`; dispatcher-spawned workers\\nsee a focused `kanban_*` toolset gated by `HERMES_KANBAN_TASK` so the\\nschema footprint is zero outside worker processes.\\n\\n- **CLI verbs (common):** `init`, `create`, `list` (alias `ls`),\\n  `show`, `assign`, `link`, `unlink`, `comment`, `complete`, `block`,\\n  `unblock`, `archive`, `tail`. Less common: `watch`, `stats`, `runs`,\\n  `log`, `dispatch`, `daemon`, `gc`.\\n- **Worker toolset:** `kanban_show`, `kanban_complete`, `kanban_block`,\\n  `kanban_heartbeat`, `kanban_comment`, `kanban_create`, `kanban_link`.\\n- **Dispatcher** runs inside the gateway by default\\n  (`kanban.dispatch_in_gateway: true`) — reclaims stale claims,\\n  promotes ready tasks, atomically claims, spawns assigned profiles.\\n  Auto-blocks a task after ~5 consecutive spawn failures.\\n- **Isolation:** board is the hard boundary (workers get\\n  `HERMES_KANBAN_BOARD` pinned in env); tenant is a soft namespace\\n  within a board for workspace-path + memory-key isolation.\\n\\nUser docs: https://hermes-agent.nousresearch.com/docs/user-guide/features/kanban\\n\\n---\\n\\n## Windows-Specific Quirks\\n\\nHermes runs natively on Windows (PowerShell, cmd, Windows Terminal, git-bash\\nmintty, VS Code integrated terminal). Most of it just works, but a handful\\nof differences between Win32 and POSIX have bitten us — document new ones\\nhere as you hit them so the next person (or the next session) doesn't\\nrediscover them from scratch.\\n\\n### Input / Keybindings\\n\\n**Alt+Enter doesn't insert a newline.** Windows Terminal intercepts Alt+Enter\\nat the terminal layer to toggle fullscreen — the keystroke never reaches\\nprompt_toolkit. Use **Ctrl+Enter** instead. Windows Terminal delivers\\nCtrl+Enter as LF (`c-j`), distinct from plain Enter (`c-m` / CR), and the\\nCLI binds `c-j` to newline insertion on `win32` only (see\\n`_bind_prompt_submit_keys` + the Windows-only `c-j` binding in `cli.py`).\\nSide effect: the raw Ctrl+J keystroke also inserts a newline on Windows —\\nunavoidable, because Windows Terminal collapses Ctrl+Enter and Ctrl+J to\\nthe same keycode at the Win32 console API layer. No conflicting binding\\nexisted for Ctrl+J on Windows, so this is a harmless side effect.\\n\\nmintty / git-bash behaves the same (fullscreen on Alt+Enter) unless you\\ndisable Alt+Fn shortcuts in Options → Keys. Easier to just use Ctrl+Enter.\\n\\n**Diagnosing keybindings.** Run `python scripts/keystroke_diagnostic.py`\\n(repo root) to see exactly how prompt_toolkit identifies each keystroke\\nin the current terminal. Answers questions like \\\"does Shift+Enter come\\nthrough as a distinct key?\\\" (almost never — most terminals collapse it\\nto plain Enter) or \\\"what byte sequence is my terminal sending for\\nCtrl+Enter?\\\" This is how the Ctrl+Enter = c-j fact was established.\\n\\n### Config / Files\\n\\n**HTTP 400 \\\"No models provided\\\" on first run.** `config.yaml` was saved\\nwith a UTF-8 BOM (common when Windows apps write it). Re-save as UTF-8\\nwithout BOM. `hermes config edit` writes without BOM; manual edits in\\nNotepad are the usual culprit.\\n\\n### `execute_code` / Sandbox\\n\\n**WinError 10106** (\\\"The requested service provider could not be loaded\\nor initialized\\\") from the sandbox child process — it can't create an\\n`AF_INET` socket, so the loopback-TCP RPC fallback fails before\\n`connect()`. Root cause is usually **not** a broken Winsock LSP; it's\\nHermes's own env scrubber dropping `SYSTEMROOT` / `WINDIR` / `COMSPEC`\\nfrom the child env. Python's `socket` module needs `SYSTEMROOT` to locate\\n`mswsock.dll`. Fixed via the `_WINDOWS_ESSENTIAL_ENV_VARS` allowlist in\\n`tools/code_execution_tool.py`. If you still hit it, echo `os.environ`\\ninside an `execute_code` block to confirm `SYSTEMROOT` is set. Full\\ndiagnostic recipe in `references/execute-code-sandbox-env-windows.md`.\\n\\n### Testing / Contributing\\n\\n**`scripts/run_tests.sh` doesn't work as-is on Windows** — it looks for\\nPOSIX venv layouts (`.venv/bin/activate`). The Hermes-installed venv at\\n`venv/Scripts/` has no pip or pytest either (stripped for install size).\\nWorkaround: install `pytest + pytest-xdist + pyyaml` into a system Python\\n3.11 user site, then invoke pytest directly with `PYTHONPATH` set:\\n\\n```bash\\n\\\"/c/Program Files/Python311/python\\\" -m pip install --user pytest pytest-xdist pyyaml\\nexport PYTHONPATH=\\\"$(pwd)\\\"\\n\\\"/c/Program Files/Python311/python\\\" -m pytest tests/foo/test_bar.py -v --tb=short -n 0\\n```\\n\\nUse `-n 0`, not `-n 4` — `pyproject.toml`'s default `addopts` already\\nincludes `-n`, and the wrapper's CI-parity guarantees don't apply off POSIX.\\n\\n**POSIX-only tests need skip guards.** Common markers already in the codebase:\\n- Symlinks — elevated privileges on Windows\\n- `0o600` file modes — POSIX mode bits not enforced on NTFS by default\\n- `signal.SIGALRM` — Unix-only (see `tests/conftest.py::_enforce_test_timeout`)\\n- Winsock / Windows-specific regressions — `@pytest.mark.skipif(sys.platform != \\\"win32\\\", ...)`\\n\\nUse the existing skip-pattern style (`sys.platform == \\\"win32\\\"` or\\n`sys.platform.startswith(\\\"win\\\")`) to stay consistent with the rest of the\\nsuite.\\n\\n### Path / Filesystem\\n\\n**Line endings.** Git may warn `LF will be replaced by CRLF the next time\\nGit touches it`. Cosmetic — the repo's `.gitattributes` normalizes. Don't\\nlet editors auto-convert committed POSIX-newline files to CRLF.\\n\\n**Forward slashes work almost everywhere.** `C:/Users/...` is accepted by\\nevery Hermes tool and most Windows APIs. Prefer forward slashes in code\\nand logs — avoids shell-escaping backslashes in bash.\\n\\n---\\n\\n## Troubleshooting\\n\\n### Voice not working\\n1. Check `stt.enabled: true` in config.yaml\\n2. Verify provider: `pip install faster-whisper` or set API key\\n3. In gateway: `/restart`. In CLI: exit and relaunch.\\n\\n### Tool not available\\n1. `hermes tools` — check if toolset is enabled for your platform\\n2. Some tools need env vars (check `.env`)\\n3. `/reset` after enabling tools\\n\\n### Model/provider issues\\n1. `hermes doctor` — check config and dependencies\\n2. `hermes login` — re-authenticate OAuth providers\\n3. Check `.env` has the right API key\\n4. **Copilot 403**: `gh auth login` tokens do NOT work for Copilot API. You must use the Copilot-specific OAuth device code flow via `hermes model` → GitHub Copilot.\\n\\n### Changes not taking effect\\n- **Tools/skills:** `/reset` starts a new session with updated toolset\\n- **Config changes:** In gateway: `/restart`. In CLI: exit and relaunch.\\n- **Code changes:** Restart the CLI or gateway process\\n\\n### Skills not showing\\n1. `hermes skills list` — verify installed\\n2. `hermes skills config` — check platform enablement\\n3. Load explicitly: `/skill name` or `hermes -s name`\\n\\n### Gateway issues\\nCheck logs first:\\n```bash\\ngrep -i \\\"failed to send\\\\|error\\\" ~/.hermes/logs/gateway.log | tail -20\\n```\\n\\nCommon gateway problems:\\n- **Gateway dies on SSH logout**: Enable linger: `sudo loginctl enable-linger $USER`\\n- **Gateway dies on WSL2 close**: WSL2 requires `systemd=true` in `/etc/wsl.conf` for systemd services to work. Without it, gateway falls back to `nohup` (dies when session closes).\\n- **Gateway crash loop**: Reset the failed state: `systemctl --user reset-failed hermes-gateway`\\n\\n### Platform-specific issues\\n- **Discord bot silent**: Must enable **Message Content Intent** in Bot → Privileged Gateway Intents.\\n- **Slack bot only works in DMs**: Must subscribe to `message.channels` event. Without it, the bot ignores public channels.\\n- **Windows-specific issues** (`Alt+Enter` newline, WinError 10106, UTF-8 BOM config, test suite, line endings): see the dedicated **Windows-Specific Quirks** section above.\\n\\n### Telegram: Pairing Code Never Expires But Requires Manual Approval\\n\\nTelegram bot access control has two layers:\\n\\n**Layer 1 — Allowed Users (config-based, no pairing needed):**\\n```bash\\n# Set allowed Telegram user IDs (comma-separated for multiple)\\nhermes config set telegram.allowed_users \\\"123456789,987654321\\\"\\n\\n# OR allow ALL users (no security — for dev only)\\necho \\\"GATEWAY_ALLOW_ALL_USERS=true\\\" >> ~/.hermes/.env\\n\\n# Always restart gateway after config changes\\nhermes gateway restart\\n```\\n\\n**Layer 2 — Pairing Code (first-time users or unlisted users):**\\nThe bot sends a pairing code → user replies it → admin approves manually:\\n```bash\\n# Check pending pairing requests\\nhermes pairing list\\n\\n# Approve a specific user\\nhermes pairing approve telegram <PAIRING_CODE>\\n\\n# After approval, user must send another message — the bot won't auto-respond to the pairing reply\\n```\\n\\n**Key gotchas:**\\n- Pairing code does NOT auto-authorize — must run `hermes pairing approve`\\n- After approval, the user needs to send a NEW message (not reply to the pairing code) to start a session\\n- Config changes to `telegram.allowed_users` require `hermes gateway restart` to take effect\\n- Session recording: `record_sessions` exists in TWO places — `browser.record_sessions` (line ~97) and top-level `recording.record_sessions` (line ~519). The top-level `recording.record_sessions: true` is the one that controls Telegram session storage.\\n\\n### Auto-fix config issues\\n\\n```bash\\n# Check and fix config problems automatically\\nhermes doctor --fix\\n```\\n\\nCommon fixes: misplaced `api_key` in config.yaml, missing env vars, outdated config options.\\n\\n### Auxiliary models not working\\nIf `auxiliary` tasks (vision, compression, session_search) fail silently, the `auto` provider can't find a backend. Either set `OPENROUTER_API_KEY` or `GOOGLE_API_KEY`, or explicitly configure each auxiliary task's provider:\\n```bash\\nhermes config set auxiliary.vision.provider <your_provider>\\nhermes config set auxiliary.vision.model <model_name>\\n```\\n\\n---\\n\\n## Where to Find Things\\n\\n| Looking for... | Location |\\n|----------------|----------|\\n| Config options | `hermes config edit` or [Configuration docs](https://hermes-agent.nousresearch.com/docs/user-guide/configuration) |\\n| Available tools | `hermes tools list` or [Tools reference](https://hermes-agent.nousresearch.com/docs/reference/tools-reference) |\\n| Slash commands | `/help` in session or [Slash commands reference](https://hermes-agent.nousresearch.com/docs/reference/slash-commands) |\\n| Skills catalog | `hermes skills browse` or [Skills catalog](https://hermes-agent.nousresearch.com/docs/reference/skills-catalog) |\\n| Provider setup | `hermes model` or [Providers guide](https://hermes-agent.nousresearch.com/docs/integrations/providers) |\\n| Platform setup | `hermes gateway setup` or [Messaging docs](https://hermes-agent.nousresearch.com/docs/user-guide/messaging/) |\\n| MCP servers | `hermes mcp list` or [MCP guide](https://hermes-agent.nousresearch.com/docs/user-guide/features/mcp) |\\n| Profiles | `hermes profile list` or [Profiles docs](https://hermes-agent.nousresearch.com/docs/user-guide/profiles) |\\n| Cron jobs | `hermes cron list` or [Cron docs](https://hermes-agent.nousresearch.com/docs/user-guide/features/cron) |\\n| Memory | `hermes memory status` or [Memory docs](https://hermes-agent.nousresearch.com/docs/user-guide/features/memory) |\\n| Env variables | `hermes config env-path` or [Env vars reference](https://hermes-agent.nousresearch.com/docs/reference/environment-variables) |\\n| CLI commands | `hermes --help` or [CLI reference](https://hermes-agent.nousresearch.com/docs/reference/cli-commands) |\\n| Gateway logs | `~/.hermes/logs/gateway.log` |\\n| Session files | `~/.hermes/sessions/` or `hermes sessions browse` |\\n| Source code | `~/.hermes/hermes-agent/` |\\n\\n---\\n\\n## Contributor Quick Reference\\n\\nFor occasional contributors and PR authors. Full developer docs: https://hermes-agent.nousresearch.com/docs/developer-guide/\\n\\n### Project Layout\\n\\n```\\nhermes-agent/\\n├── run_agent.py          # AIAgent — core conversation loop\\n├── model_tools.py        # Tool discovery and dispatch\\n├── toolsets.py           # Toolset definitions\\n├── cli.py                # Interactive CLI (HermesCLI)\\n├── hermes_state.py       # SQLite session store\\n├── agent/                # Prompt builder, context compression, memory, model routing, credential pooling, skill dispatch\\n├── hermes_cli/           # CLI subcommands, config, setup, commands\\n│   ├── commands.py       # Slash command registry (CommandDef)\\n│   ├── config.py         # DEFAULT_CONFIG, env var definitions\\n│   └── main.py           # CLI entry point and argparse\\n├── tools/                # One file per tool\\n│   └── registry.py       # Central tool registry\\n├── gateway/              # Messaging gateway\\n│   └── platforms/        # Platform adapters (telegram, discord, etc.)\\n├── cron/                 # Job scheduler\\n├── tests/                # ~3000 pytest tests\\n└── website/              # Docusaurus docs site\\n```\\n\\nConfig: `~/.hermes/config.yaml` (settings), `~/.hermes/.env` (API keys).\\n\\n### Adding a Tool (3 files)\\n\\n**1. Create `tools/your_tool.py`:**\\n```python\\nimport json, os\\nfrom tools.registry import registry\\n\\ndef check_requirements() -> bool:\\n    return bool(os.getenv(\\\"EXAMPLE_API_KEY\\\"))\\n\\ndef example_tool(param: str, task_id: str = None) -> str:\\n    return json.dumps({\\\"success\\\": True, \\\"data\\\": \\\"...\\\"})\\n\\nregistry.register(\\n    name=\\\"example_tool\\\",\\n    toolset=\\\"example\\\",\\n    schema={\\\"name\\\": \\\"example_tool\\\", \\\"description\\\": \\\"...\\\", \\\"parameters\\\": {...}},\\n    handler=lambda args, **kw: example_tool(\\n        param=args.get(\\\"param\\\", \\\"\\\"), task_id=kw.get(\\\"task_id\\\")),\\n    check_fn=check_requirements,\\n    requires_env=[\\\"EXAMPLE_API_KEY\\\"],\\n)\\n```\\n\\n**2. Add to `toolsets.py`** → `_HERMES_CORE_TOOLS` list.\\n\\nAuto-discovery: any `tools/*.py` file with a top-level `registry.register()` call is imported automatically — no manual list needed.\\n\\nAll handlers must return JSON strings. Use `get_hermes_home()` for paths, never hardcode `~/.hermes`.\\n\\n### Adding a Slash Command\\n\\n1. Add `CommandDef` to `COMMAND_REGISTRY` in `hermes_cli/commands.py`\\n2. Add handler in `cli.py` → `process_command()`\\n3. (Optional) Add gateway handler in `gateway/run.py`\\n\\nAll consumers (help text, autocomplete, Telegram menu, Slack mapping) derive from the central registry automatically.\\n\\n### Agent Loop (High Level)\\n\\n```\\nrun_conversation():\\n  1. Build system prompt\\n  2. Loop while iterations < max:\\n     a. Call LLM (OpenAI-format messages + tool schemas)\\n     b. If tool_calls → dispatch each via handle_function_call() → append results → continue\\n     c. If text response → return\\n  3. Context compression triggers automatically near token limit\\n```\\n\\n### Testing\\n\\n```bash\\npython -m pytest tests/ -o 'addopts=' -q   # Full suite\\npython -m pytest tests/tools/ -q            # Specific area\\n```\\n\\n- Tests auto-redirect `HERMES_HOME` to temp dirs — never touch real `~/.hermes/`\\n- Run full suite before pushing any change\\n- Use `-o 'addopts='` to clear any baked-in pytest flags\\n\\n**Windows contributors:** `scripts/run_tests.sh` currently looks for POSIX venvs (`.venv/bin/activate` / `venv/bin/activate`) and will error out on Windows where the layout is `venv/Scripts/activate` + `python.exe`. The Hermes-installed venv at `venv/Scripts/` also has no `pip` or `pytest` — it's stripped for end-user install size. Workaround: install pytest + pytest-xdist + pyyaml into a system Python 3.11 user site (`/c/Program Files/Python311/python -m pip install --user pytest pytest-xdist pyyaml`), then run tests directly:\\n\\n```bash\\nexport PYTHONPATH=\\\"$(pwd)\\\"\\n\\\"/c/Program Files/Python311/python\\\" -m pytest tests/tools/test_foo.py -v --tb=short -n 0\\n```\\n\\nUse `-n 0` (not `-n 4`) because `pyproject.toml`'s default `addopts` already includes `-n`, and the wrapper's CI-parity story doesn't apply off-POSIX.\\n\\n**Cross-platform test guards:** tests that use POSIX-only syscalls need a skip marker. Common ones already in the codebase:\\n- Symlink creation → `@pytest.mark.skipif(sys.platform == \\\"win32\\\", reason=\\\"Symlinks require elevated privileges on Windows\\\")` (see `tests/cron/test_cron_script.py`)\\n- POSIX file modes (0o600, etc.) → `@pytest.mark.skipif(sys.platform.startswith(\\\"win\\\"), reason=\\\"POSIX mode bits not enforced on Windows\\\")` (see `tests/hermes_cli/test_auth_toctou_file_modes.py`)\\n- `signal.SIGALRM` → Unix-only (see `tests/conftest.py::_enforce_test_timeout`)\\n- Live Winsock / Windows-specific regression tests → `@pytest.mark.skipif(sys.platform != \\\"win32\\\", reason=\\\"Windows-specific regression\\\")`\\n\\n**Monkeypatching `sys.platform` is not enough** when the code under test also calls `platform.system()` / `platform.release()` / `platform.mac_ver()`. Those functions re-read the real OS independently, so a test that sets `sys.platform = \\\"linux\\\"` on a Windows runner will still see `platform.system() == \\\"Windows\\\"` and route through the Windows branch. Patch all three together:\\n\\n```python\\nmonkeypatch.setattr(sys, \\\"platform\\\", \\\"linux\\\")\\nmonkeypatch.setattr(platform, \\\"system\\\", lambda: \\\"Linux\\\")\\nmonkeypatch.setattr(platform, \\\"release\\\", lambda: \\\"6.8.0-generic\\\")\\n```\\n\\nSee `tests/agent/test_prompt_builder.py::TestEnvironmentHints` for a worked example.\\n\\n### Extending the system prompt's execution-environment block\\n\\nFactual guidance about the host OS, user home, cwd, terminal backend, and shell (bash vs. PowerShell on Windows) is emitted from `agent/prompt_builder.py::build_environment_hints()`. This is also where the WSL hint and per-backend probe logic live. The convention:\\n\\n- **Local terminal backend** → emit host info (OS, `$HOME`, cwd) + Windows-specific notes (hostname ≠ username, `terminal` uses bash not PowerShell).\\n- **Remote terminal backend** (anything in `_REMOTE_TERMINAL_BACKENDS`: `docker, singularity, modal, daytona, ssh, vercel_sandbox, managed_modal`) → **suppress** host info entirely and describe only the backend. A live `uname`/`whoami`/`pwd` probe runs inside the backend via `tools.environments.get_environment(...).execute(...)`, cached per process in `_BACKEND_PROBE_CACHE`, with a static fallback if the probe times out.\\n- **Key fact for prompt authoring:** when `TERMINAL_ENV != \\\"local\\\"`, *every* file tool (`read_file`, `write_file`, `patch`, `search_files`) runs inside the backend container, not on the host. The system prompt must never describe the host in that case — the agent can't touch it.\\n\\nFull design notes, the exact emitted strings, and testing pitfalls:\\n`references/prompt-builder-environment-hints.md`.\\n\\n**Refactor-safety pattern (POSIX-equivalence guard):** when you extract inline logic into a helper that adds Windows/platform-specific behavior, keep a `_legacy_<name>` oracle function in the test file that's a verbatim copy of the old code, then parametrize-diff against it. Example: `tests/tools/test_code_execution_windows_env.py::TestPosixEquivalence`. This locks in the invariant that POSIX behavior is bit-for-bit identical and makes any future drift fail loudly with a clear diff.\\n\\n### Commit Conventions\\n\\n```\\ntype: concise subject line\\n\\nOptional body.\\n```\\n\\nTypes: `fix:`, `feat:`, `refactor:`, `docs:`, `chore:`\\n\\n### Key Rules\\n\\n- **Never break prompt caching** — don't change context, tools, or system prompt mid-conversation\\n- **Message role alternation** — never two assistant or two user messages in a row\\n- Use `get_hermes_home()` from `hermes_constants` for all paths (profile-safe)\\n- Config values go in `config.yaml`, secrets go in `.env`\\n- New tools need a `check_fn` so they only appear when requirements are met\\n\", \"path\": \"autonomous-ai-agents/hermes-agent/SKILL.md\", \"skill_dir\": \"/home/kuhnn/.hermes/skills/autonomous-ai-agents/hermes-agent\", \"linked_files\": {\"references\": [\"references/telegram-bot-privacy.md\", \"references/telegram-gateway-setup.md\"]}, \"usage_hint\": \"To view linked files, call skill_view(name, file_path) where file_path is e.g. 'references/api.md' or 'assets/config.yaml'\", \"required_environment_variables\": [], \"required_commands\": [], \"missing_required_environment_variables\": [], \"missing_credential_files\": [], \"missing_required_commands\": [], \"setup_needed\": false, \"setup_skipped\": false, \"readiness_status\": \"available\", \"metadata\": {\"hermes\": {\"tags\": [\"hermes\", \"setup\", \"configuration\", \"multi-agent\", \"spawning\", \"cli\", \"gateway\", \"development\"], \"homepage\": \"https://github.com/NousResearch/hermes-agent\", \"related_skills\": [\"claude-code\", \"codex\", \"opencode\"]}}}",
      "tool_call_id": "call_function_7wwd137adnfq_5"
    },
    {
      "role": "tool",
      "name": "skill_view",
      "content": "{\"success\": true, \"name\": \"opencode\", \"description\": \"Delegate coding to OpenCode CLI (features, PR review).\", \"tags\": [\"Coding-Agent\", \"OpenCode\", \"Autonomous\", \"Refactoring\", \"Code-Review\"], \"related_skills\": [\"claude-code\", \"codex\", \"hermes-agent\"], \"content\": \"---\\nname: opencode\\ndescription: \\\"Delegate coding to OpenCode CLI (features, PR review).\\\"\\nversion: 1.2.0\\nauthor: Hermes Agent\\nlicense: MIT\\nplatforms: [linux, macos, windows]\\nmetadata:\\n  hermes:\\n    tags: [Coding-Agent, OpenCode, Autonomous, Refactoring, Code-Review]\\n    related_skills: [claude-code, codex, hermes-agent]\\n---\\n\\n# OpenCode CLI\\n\\nUse [OpenCode](https://opencode.ai) as an autonomous coding worker orchestrated by Hermes terminal/process tools. OpenCode is a provider-agnostic, open-source AI coding agent with a TUI and CLI.\\n\\n## When to Use\\n\\n- User explicitly asks to use OpenCode\\n- You want an external coding agent to implement/refactor/review code\\n- You need long-running coding sessions with progress checks\\n- You want parallel task execution in isolated workdirs/worktrees\\n\\n## Prerequisites\\n\\n- OpenCode installed: `npm i -g opencode-ai@latest` or `brew install anomalyco/tap/opencode`\\n- Auth configured: `opencode auth login` or set provider env vars (OPENROUTER_API_KEY, etc.)\\n- Verify: `opencode auth list` should show at least one provider\\n- Git repository for code tasks (recommended)\\n- `pty=true` for interactive TUI sessions\\n\\n## Binary Resolution (Important)\\n\\nShell environments may resolve different OpenCode binaries. If behavior differs between your terminal and Hermes, check:\\n\\n```\\nterminal(command=\\\"which -a opencode\\\")\\nterminal(command=\\\"opencode --version\\\")\\n```\\n\\nIf needed, pin an explicit binary path:\\n\\n```\\nterminal(command=\\\"$HOME/.opencode/bin/opencode run '...'\\\", workdir=\\\"~/project\\\", pty=true)\\n```\\n\\n## One-Shot Tasks\\n\\nUse `opencode run` for bounded, non-interactive tasks:\\n\\n```\\nterminal(command=\\\"opencode run 'Add retry logic to API calls and update tests'\\\", workdir=\\\"~/project\\\")\\n```\\n\\nAttach context files with `-f`:\\n\\n```\\nterminal(command=\\\"opencode run 'Review this config for security issues' -f config.yaml -f .env.example\\\", workdir=\\\"~/project\\\")\\n```\\n\\nShow model thinking with `--thinking`:\\n\\n```\\nterminal(command=\\\"opencode run 'Debug why tests fail in CI' --thinking\\\", workdir=\\\"~/project\\\")\\n```\\n\\nForce a specific model:\\n\\n```\\nterminal(command=\\\"opencode run 'Refactor auth module' --model openrouter/anthropic/claude-sonnet-4\\\", workdir=\\\"~/project\\\")\\n```\\n\\n## Interactive Sessions (Background)\\n\\nFor iterative work requiring multiple exchanges, start the TUI in background:\\n\\n```\\nterminal(command=\\\"opencode\\\", workdir=\\\"~/project\\\", background=true, pty=true)\\n# Returns session_id\\n\\n# Send a prompt\\nprocess(action=\\\"submit\\\", session_id=\\\"<id>\\\", data=\\\"Implement OAuth refresh flow and add tests\\\")\\n\\n# Monitor progress\\nprocess(action=\\\"poll\\\", session_id=\\\"<id>\\\")\\nprocess(action=\\\"log\\\", session_id=\\\"<id>\\\")\\n\\n# Send follow-up input\\nprocess(action=\\\"submit\\\", session_id=\\\"<id>\\\", data=\\\"Now add error handling for token expiry\\\")\\n\\n# Exit cleanly — Ctrl+C\\nprocess(action=\\\"write\\\", session_id=\\\"<id>\\\", data=\\\"\\\\x03\\\")\\n# Or just kill the process\\nprocess(action=\\\"kill\\\", session_id=\\\"<id>\\\")\\n```\\n\\n**Important:** Do NOT use `/exit` — it is not a valid OpenCode command and will open an agent selector dialog instead. Use Ctrl+C (`\\\\x03`) or `process(action=\\\"kill\\\")` to exit.\\n\\n### TUI Keybindings\\n\\n| Key | Action |\\n|-----|--------|\\n| `Enter` | Submit message (press twice if needed) |\\n| `Tab` | Switch between agents (build/plan) |\\n| `Ctrl+P` | Open command palette |\\n| `Ctrl+X L` | Switch session |\\n| `Ctrl+X M` | Switch model |\\n| `Ctrl+X N` | New session |\\n| `Ctrl+X E` | Open editor |\\n| `Ctrl+C` | Exit OpenCode |\\n\\n### Resuming Sessions\\n\\nAfter exiting, OpenCode prints a session ID. Resume with:\\n\\n```\\nterminal(command=\\\"opencode -c\\\", workdir=\\\"~/project\\\", background=true, pty=true)  # Continue last session\\nterminal(command=\\\"opencode -s ses_abc123\\\", workdir=\\\"~/project\\\", background=true, pty=true)  # Specific session\\n```\\n\\n## Common Flags\\n\\n| Flag | Use |\\n|------|-----|\\n| `run 'prompt'` | One-shot execution and exit |\\n| `--continue` / `-c` | Continue the last OpenCode session |\\n| `--session <id>` / `-s` | Continue a specific session |\\n| `--agent <name>` | Choose OpenCode agent (build or plan) |\\n| `--model provider/model` | Force specific model |\\n| `--format json` | Machine-readable output/events |\\n| `--file <path>` / `-f` | Attach file(s) to the message |\\n| `--thinking` | Show model thinking blocks |\\n| `--variant <level>` | Reasoning effort (high, max, minimal) |\\n| `--title <name>` | Name the session |\\n| `--attach <url>` | Connect to a running opencode server |\\n\\n## Procedure\\n\\n1. Verify tool readiness:\\n   - `terminal(command=\\\"opencode --version\\\")`\\n   - `terminal(command=\\\"opencode auth list\\\")`\\n2. For bounded tasks, use `opencode run '...'` (no pty needed).\\n3. For iterative tasks, start `opencode` with `background=true, pty=true`.\\n4. Monitor long tasks with `process(action=\\\"poll\\\"|\\\"log\\\")`.\\n5. If OpenCode asks for input, respond via `process(action=\\\"submit\\\", ...)`.\\n6. Exit with `process(action=\\\"write\\\", data=\\\"\\\\x03\\\")` or `process(action=\\\"kill\\\")`.\\n7. Summarize file changes, test results, and next steps back to user.\\n\\n## PR Review Workflow\\n\\nOpenCode has a built-in PR command:\\n\\n```\\nterminal(command=\\\"opencode pr 42\\\", workdir=\\\"~/project\\\", pty=true)\\n```\\n\\nOr review in a temporary clone for isolation:\\n\\n```\\nterminal(command=\\\"REVIEW=$(mktemp -d) && git clone https://github.com/user/repo.git $REVIEW && cd $REVIEW && opencode run 'Review this PR vs main. Report bugs, security risks, test gaps, and style issues.' -f $(git diff origin/main --name-only | head -20 | tr '\\\\n' ' ')\\\", pty=true)\\n```\\n\\n## Parallel Work Pattern\\n\\nUse separate workdirs/worktrees to avoid collisions:\\n\\n```\\nterminal(command=\\\"opencode run 'Fix issue #101 and commit'\\\", workdir=\\\"/tmp/issue-101\\\", background=true, pty=true)\\nterminal(command=\\\"opencode run 'Add parser regression tests and commit'\\\", workdir=\\\"/tmp/issue-102\\\", background=true, pty=true)\\nprocess(action=\\\"list\\\")\\n```\\n\\n## Session & Cost Management\\n\\nList past sessions:\\n\\n```\\nterminal(command=\\\"opencode session list\\\")\\n```\\n\\nCheck token usage and costs:\\n\\n```\\nterminal(command=\\\"opencode stats\\\")\\nterminal(command=\\\"opencode stats --days 7 --models anthropic/claude-sonnet-4\\\")\\n```\\n\\n## Pitfalls\\n\\n- Interactive `opencode` (TUI) sessions require `pty=true`. The `opencode run` command does NOT need pty.\\n- `/exit` is NOT a valid command — it opens an agent selector. Use Ctrl+C to exit the TUI.\\n- PATH mismatch can select the wrong OpenCode binary/model config.\\n- If OpenCode appears stuck, inspect logs before killing:\\n  - `process(action=\\\"log\\\", session_id=\\\"<id>\\\")`\\n- Avoid sharing one working directory across parallel OpenCode sessions.\\n- Enter may need to be pressed twice to submit in the TUI (once to finalize text, once to send).\\n\\n## Verification\\n\\nSmoke test:\\n\\n```\\nterminal(command=\\\"opencode run 'Respond with exactly: OPENCODE_SMOKE_OK'\\\")\\n```\\n\\nSuccess criteria:\\n- Output includes `OPENCODE_SMOKE_OK`\\n- Command exits without provider/model errors\\n- For code tasks: expected files changed and tests pass\\n\\n## Rules\\n\\n1. Prefer `opencode run` for one-shot automation — it's simpler and doesn't need pty.\\n2. Use interactive background mode only when iteration is needed.\\n3. Always scope OpenCode sessions to a single repo/workdir.\\n4. For long tasks, provide progress updates from `process` logs.\\n5. Report concrete outcomes (files changed, tests, remaining risks).\\n6. Exit interactive sessions with Ctrl+C or kill, never `/exit`.\\n\", \"path\": \"autonomous-ai-agents/opencode/SKILL.md\", \"skill_dir\": \"/home/kuhnn/.hermes/skills/autonomous-ai-agents/opencode\", \"linked_files\": null, \"usage_hint\": null, \"required_environment_variables\": [], \"required_commands\": [], \"missing_required_environment_variables\": [], \"missing_credential_files\": [], \"missing_required_commands\": [], \"setup_needed\": false, \"setup_skipped\": false, \"readiness_status\": \"available\", \"metadata\": {\"hermes\": {\"tags\": [\"Coding-Agent\", \"OpenCode\", \"Autonomous\", \"Refactoring\", \"Code-Review\"], \"related_skills\": [\"claude-code\", \"codex\", \"hermes-agent\"]}}}",
      "tool_call_id": "call_function_7wwd137adnfq_6"
    },
    {
      "role": "tool",
      "name": "skill_view",
      "content": "{\"success\": true, \"name\": \"architecture-diagram\", \"description\": \"Dark-themed SVG architecture/cloud/infra diagrams as HTML.\", \"tags\": [\"architecture\", \"diagrams\", \"SVG\", \"HTML\", \"visualization\", \"infrastructure\", \"cloud\"], \"related_skills\": [\"concept-diagrams\", \"excalidraw\"], \"content\": \"---\\nname: architecture-diagram\\ndescription: \\\"Dark-themed SVG architecture/cloud/infra diagrams as HTML.\\\"\\nversion: 1.0.0\\nauthor: Cocoon AI (hello@cocoon-ai.com), ported by Hermes Agent\\nlicense: MIT\\ndependencies: []\\nplatforms: [linux, macos, windows]\\nmetadata:\\n  hermes:\\n    tags: [architecture, diagrams, SVG, HTML, visualization, infrastructure, cloud]\\n    related_skills: [concept-diagrams, excalidraw]\\n---\\n\\n# Architecture Diagram Skill\\n\\nGenerate professional, dark-themed technical architecture diagrams as standalone HTML files with inline SVG graphics. No external tools, no API keys, no rendering libraries — just write the HTML file and open it in a browser.\\n\\n## Scope\\n\\n**Best suited for:**\\n- Software system architecture (frontend / backend / database layers)\\n- Cloud infrastructure (VPC, regions, subnets, managed services)\\n- Microservice / service-mesh topology\\n- Database + API map, deployment diagrams\\n- Anything with a tech-infra subject that fits a dark, grid-backed aesthetic\\n\\n**Look elsewhere first for:**\\n- Physics, chemistry, math, biology, or other scientific subjects\\n- Physical objects (vehicles, hardware, anatomy, cross-sections)\\n- Floor plans, narrative journeys, educational / textbook-style visuals\\n- Hand-drawn whiteboard sketches (consider `excalidraw`)\\n- Animated explainers (consider an animation skill)\\n\\nIf a more specialized skill is available for the subject, prefer that. If none fits, this skill can also serve as a general SVG diagram fallback — the output will just carry the dark tech aesthetic described below.\\n\\nBased on [Cocoon AI's architecture-diagram-generator](https://github.com/Cocoon-AI/architecture-diagram-generator) (MIT).\\n\\n## Workflow\\n\\n1. User describes their system architecture (components, connections, technologies)\\n2. Generate the HTML file following the design system below\\n3. Save with `write_file` to a `.html` file (e.g. `~/architecture-diagram.html`)\\n4. User opens in any browser — works offline, no dependencies\\n\\n### Output Location\\n\\nSave diagrams to a user-specified path, or default to the current working directory:\\n```\\n./[project-name]-architecture.html\\n```\\n\\n### Preview\\n\\nAfter saving, suggest the user open it:\\n```bash\\n# macOS\\nopen ./my-architecture.html\\n# Linux\\nxdg-open ./my-architecture.html\\n```\\n\\n## Design System & Visual Language\\n\\n### Color Palette (Semantic Mapping)\\n\\nUse specific `rgba` fills and hex strokes to categorize components:\\n\\n| Component Type | Fill (rgba) | Stroke (Hex) |\\n| :--- | :--- | :--- |\\n| **Frontend** | `rgba(8, 51, 68, 0.4)` | `#22d3ee` (cyan-400) |\\n| **Backend** | `rgba(6, 78, 59, 0.4)` | `#34d399` (emerald-400) |\\n| **Database** | `rgba(76, 29, 149, 0.4)` | `#a78bfa` (violet-400) |\\n| **AWS/Cloud** | `rgba(120, 53, 15, 0.3)` | `#fbbf24` (amber-400) |\\n| **Security** | `rgba(136, 19, 55, 0.4)` | `#fb7185` (rose-400) |\\n| **Message Bus** | `rgba(251, 146, 60, 0.3)` | `#fb923c` (orange-400) |\\n| **External** | `rgba(30, 41, 59, 0.5)` | `#94a3b8` (slate-400) |\\n\\n### Typography & Background\\n- **Font:** JetBrains Mono (Monospace), loaded from Google Fonts\\n- **Sizes:** 12px (Names), 9px (Sublabels), 8px (Annotations), 7px (Tiny labels)\\n- **Background:** Slate-950 (`#020617`) with a subtle 40px grid pattern\\n\\n```svg\\n<!-- Background Grid Pattern -->\\n<pattern id=\\\"grid\\\" width=\\\"40\\\" height=\\\"40\\\" patternUnits=\\\"userSpaceOnUse\\\">\\n  <path d=\\\"M 40 0 L 0 0 0 40\\\" fill=\\\"none\\\" stroke=\\\"#1e293b\\\" stroke-width=\\\"0.5\\\"/>\\n</pattern>\\n```\\n\\n## Technical Implementation Details\\n\\n### Component Rendering\\nComponents are rounded rectangles (`rx=\\\"6\\\"`) with 1.5px strokes. To prevent arrows from showing through semi-transparent fills, use a **double-rect masking technique**:\\n1. Draw an opaque background rect (`#0f172a`)\\n2. Draw the semi-transparent styled rect on top\\n\\n### Connection Rules\\n- **Z-Order:** Draw arrows *early* in the SVG (after the grid) so they render behind component boxes\\n- **Arrowheads:** Defined via SVG markers\\n- **Security Flows:** Use dashed lines in rose color (`#fb7185`)\\n- **Boundaries:**\\n  - *Security Groups:* Dashed (`4,4`), rose color\\n  - *Regions:* Large dashed (`8,4`), amber color, `rx=\\\"12\\\"`\\n\\n### Spacing & Layout Logic\\n- **Standard Height:** 60px (Services); 80-120px (Large components)\\n- **Vertical Gap:** Minimum 40px between components\\n- **Message Buses:** Must be placed *in the gap* between services, not overlapping them\\n- **Legend Placement:** **CRITICAL.** Must be placed outside all boundary boxes. Calculate the lowest Y-coordinate of all boundaries and place the legend at least 20px below it.\\n\\n## Document Structure\\n\\nThe generated HTML file follows a four-part layout:\\n1. **Header:** Title with a pulsing dot indicator and subtitle\\n2. **Main SVG:** The diagram contained within a rounded border card\\n3. **Summary Cards:** A grid of three cards below the diagram for high-level details\\n4. **Footer:** Minimal metadata\\n\\n### Info Card Pattern\\n```html\\n<div class=\\\"card\\\">\\n  <div class=\\\"card-header\\\">\\n    <div class=\\\"card-dot cyan\\\"></div>\\n    <h3>Title</h3>\\n  </div>\\n  <ul>\\n    <li>• Item one</li>\\n    <li>• Item two</li>\\n  </ul>\\n</div>\\n```\\n\\n## Output Requirements\\n- **Single File:** One self-contained `.html` file\\n- **No External Dependencies:** All CSS and SVG must be inline (except Google Fonts)\\n- **No JavaScript:** Use pure CSS for any animations (like pulsing dots)\\n- **Compatibility:** Must render correctly in any modern web browser\\n\\n## Template Reference\\n\\nLoad the full HTML template for the exact structure, CSS, and SVG component examples:\\n\\n```\\nskill_view(name=\\\"architecture-diagram\\\", file_path=\\\"templates/template.html\\\")\\n```\\n\\nThe template contains working examples of every component type (frontend, backend, database, cloud, security), arrow styles (standard, dashed, curved), security groups, region boundaries, and the legend — use it as your structural reference when generating diagrams.\\n\", \"path\": \"creative/architecture-diagram/SKILL.md\", \"skill_dir\": \"/home/kuhnn/.hermes/skills/creative/architecture-diagram\", \"linked_files\": null, \"usage_hint\": null, \"required_environment_variables\": [], \"required_commands\": [], \"missing_required_environment_variables\": [], \"missing_credential_files\": [], \"missing_required_commands\": [], \"setup_needed\": false, \"setup_skipped\": false, \"readiness_status\": \"available\", \"metadata\": {\"hermes\": {\"tags\": [\"architecture\", \"diagrams\", \"SVG\", \"HTML\", \"visualization\", \"infrastructure\", \"cloud\"], \"related_skills\": [\"concept-diagrams\", \"excalidraw\"]}}}",
      "tool_call_id": "call_function_7wwd137adnfq_7"
    },
    {
      "role": "tool",
      "name": "skill_view",
      "content": "{\"success\": true, \"name\": \"ascii-art\", \"description\": \"ASCII art: pyfiglet, cowsay, boxes, image-to-ascii.\", \"tags\": [\"ASCII\", \"Art\", \"Banners\", \"Creative\", \"Unicode\", \"Text-Art\", \"pyfiglet\", \"figlet\", \"cowsay\", \"boxes\"], \"related_skills\": [\"excalidraw\"], \"content\": \"---\\nname: ascii-art\\ndescription: \\\"ASCII art: pyfiglet, cowsay, boxes, image-to-ascii.\\\"\\nversion: 4.0.0\\nauthor: 0xbyt4, Hermes Agent\\nlicense: MIT\\ndependencies: []\\nplatforms: [linux, macos, windows]\\nmetadata:\\n  hermes:\\n    tags: [ASCII, Art, Banners, Creative, Unicode, Text-Art, pyfiglet, figlet, cowsay, boxes]\\n    related_skills: [excalidraw]\\n\\n---\\n\\n# ASCII Art Skill\\n\\nMultiple tools for different ASCII art needs. All tools are local CLI programs or free REST APIs — no API keys required.\\n\\n## Tool 1: Text Banners (pyfiglet — local)\\n\\nRender text as large ASCII art banners. 571 built-in fonts.\\n\\n### Setup\\n\\n```bash\\npip install pyfiglet --break-system-packages -q\\n```\\n\\n### Usage\\n\\n```bash\\npython3 -m pyfiglet \\\"YOUR TEXT\\\" -f slant\\npython3 -m pyfiglet \\\"TEXT\\\" -f doom -w 80    # Set width\\npython3 -m pyfiglet --list_fonts             # List all 571 fonts\\n```\\n\\n### Recommended fonts\\n\\n| Style | Font | Best for |\\n|-------|------|----------|\\n| Clean & modern | `slant` | Project names, headers |\\n| Bold & blocky | `doom` | Titles, logos |\\n| Big & readable | `big` | Banners |\\n| Classic banner | `banner3` | Wide displays |\\n| Compact | `small` | Subtitles |\\n| Cyberpunk | `cyberlarge` | Tech themes |\\n| 3D effect | `3-d` | Splash screens |\\n| Gothic | `gothic` | Dramatic text |\\n\\n### Tips\\n\\n- Preview 2-3 fonts and let the user pick their favorite\\n- Short text (1-8 chars) works best with detailed fonts like `doom` or `block`\\n- Long text works better with compact fonts like `small` or `mini`\\n\\n## Tool 2: Text Banners (asciified API — remote, no install)\\n\\nFree REST API that converts text to ASCII art. 250+ FIGlet fonts. Returns plain text directly — no parsing needed. Use this when pyfiglet is not installed or as a quick alternative.\\n\\n### Usage (via terminal curl)\\n\\n```bash\\n# Basic text banner (default font)\\ncurl -s \\\"https://asciified.thelicato.io/api/v2/ascii?text=Hello+World\\\"\\n\\n# With a specific font\\ncurl -s \\\"https://asciified.thelicato.io/api/v2/ascii?text=Hello&font=Slant\\\"\\ncurl -s \\\"https://asciified.thelicato.io/api/v2/ascii?text=Hello&font=Doom\\\"\\ncurl -s \\\"https://asciified.thelicato.io/api/v2/ascii?text=Hello&font=Star+Wars\\\"\\ncurl -s \\\"https://asciified.thelicato.io/api/v2/ascii?text=Hello&font=3-D\\\"\\ncurl -s \\\"https://asciified.thelicato.io/api/v2/ascii?text=Hello&font=Banner3\\\"\\n\\n# List all available fonts (returns JSON array)\\ncurl -s \\\"https://asciified.thelicato.io/api/v2/fonts\\\"\\n```\\n\\n### Tips\\n\\n- URL-encode spaces as `+` in the text parameter\\n- The response is plain text ASCII art — no JSON wrapping, ready to display\\n- Font names are case-sensitive; use the fonts endpoint to get exact names\\n- Works from any terminal with curl — no Python or pip needed\\n\\n## Tool 3: Cowsay (Message Art)\\n\\nClassic tool that wraps text in a speech bubble with an ASCII character.\\n\\n### Setup\\n\\n```bash\\nsudo apt install cowsay -y    # Debian/Ubuntu\\n# brew install cowsay         # macOS\\n```\\n\\n### Usage\\n\\n```bash\\ncowsay \\\"Hello World\\\"\\ncowsay -f tux \\\"Linux rules\\\"       # Tux the penguin\\ncowsay -f dragon \\\"Rawr!\\\"          # Dragon\\ncowsay -f stegosaurus \\\"Roar!\\\"     # Stegosaurus\\ncowthink \\\"Hmm...\\\"                  # Thought bubble\\ncowsay -l                          # List all characters\\n```\\n\\n### Available characters (50+)\\n\\n`beavis.zen`, `bong`, `bunny`, `cheese`, `daemon`, `default`, `dragon`,\\n`dragon-and-cow`, `elephant`, `eyes`, `flaming-skull`, `ghostbusters`,\\n`hellokitty`, `kiss`, `kitty`, `koala`, `luke-koala`, `mech-and-cow`,\\n`meow`, `moofasa`, `moose`, `ren`, `sheep`, `skeleton`, `small`,\\n`stegosaurus`, `stimpy`, `supermilker`, `surgery`, `three-eyes`,\\n`turkey`, `turtle`, `tux`, `udder`, `vader`, `vader-koala`, `www`\\n\\n### Eye/tongue modifiers\\n\\n```bash\\ncowsay -b \\\"Borg\\\"       # =_= eyes\\ncowsay -d \\\"Dead\\\"       # x_x eyes\\ncowsay -g \\\"Greedy\\\"     # $_$ eyes\\ncowsay -p \\\"Paranoid\\\"   # @_@ eyes\\ncowsay -s \\\"Stoned\\\"     # *_* eyes\\ncowsay -w \\\"Wired\\\"      # O_O eyes\\ncowsay -e \\\"OO\\\" \\\"Msg\\\"   # Custom eyes\\ncowsay -T \\\"U \\\" \\\"Msg\\\"   # Custom tongue\\n```\\n\\n## Tool 4: Boxes (Decorative Borders)\\n\\nDraw decorative ASCII art borders/frames around any text. 70+ built-in designs.\\n\\n### Setup\\n\\n```bash\\nsudo apt install boxes -y    # Debian/Ubuntu\\n# brew install boxes         # macOS\\n```\\n\\n### Usage\\n\\n```bash\\necho \\\"Hello World\\\" | boxes                    # Default box\\necho \\\"Hello World\\\" | boxes -d stone           # Stone border\\necho \\\"Hello World\\\" | boxes -d parchment       # Parchment scroll\\necho \\\"Hello World\\\" | boxes -d cat             # Cat border\\necho \\\"Hello World\\\" | boxes -d dog             # Dog border\\necho \\\"Hello World\\\" | boxes -d unicornsay      # Unicorn\\necho \\\"Hello World\\\" | boxes -d diamonds        # Diamond pattern\\necho \\\"Hello World\\\" | boxes -d c-cmt           # C-style comment\\necho \\\"Hello World\\\" | boxes -d html-cmt        # HTML comment\\necho \\\"Hello World\\\" | boxes -a c               # Center text\\nboxes -l                                       # List all 70+ designs\\n```\\n\\n### Combine with pyfiglet or asciified\\n\\n```bash\\npython3 -m pyfiglet \\\"HERMES\\\" -f slant | boxes -d stone\\n# Or without pyfiglet installed:\\ncurl -s \\\"https://asciified.thelicato.io/api/v2/ascii?text=HERMES&font=Slant\\\" | boxes -d stone\\n```\\n\\n## Tool 5: TOIlet (Colored Text Art)\\n\\nLike pyfiglet but with ANSI color effects and visual filters. Great for terminal eye candy.\\n\\n### Setup\\n\\n```bash\\nsudo apt install toilet toilet-fonts -y    # Debian/Ubuntu\\n# brew install toilet                      # macOS\\n```\\n\\n### Usage\\n\\n```bash\\ntoilet \\\"Hello World\\\"                    # Basic text art\\ntoilet -f bigmono12 \\\"Hello\\\"            # Specific font\\ntoilet --gay \\\"Rainbow!\\\"                 # Rainbow coloring\\ntoilet --metal \\\"Metal!\\\"                 # Metallic effect\\ntoilet -F border \\\"Bordered\\\"             # Add border\\ntoilet -F border --gay \\\"Fancy!\\\"         # Combined effects\\ntoilet -f pagga \\\"Block\\\"                 # Block-style font (unique to toilet)\\ntoilet -F list                          # List available filters\\n```\\n\\n### Filters\\n\\n`crop`, `gay` (rainbow), `metal`, `flip`, `flop`, `180`, `left`, `right`, `border`\\n\\n**Note**: toilet outputs ANSI escape codes for colors — works in terminals but may not render in all contexts (e.g., plain text files, some chat platforms).\\n\\n## Tool 6: Image to ASCII Art\\n\\nConvert images (PNG, JPEG, GIF, WEBP) to ASCII art.\\n\\n### Option A: ascii-image-converter (recommended, modern)\\n\\n```bash\\n# Install\\nsudo snap install ascii-image-converter\\n# OR: go install github.com/TheZoraiz/ascii-image-converter@latest\\n```\\n\\n```bash\\nascii-image-converter image.png                  # Basic\\nascii-image-converter image.png -C               # Color output\\nascii-image-converter image.png -d 60,30         # Set dimensions\\nascii-image-converter image.png -b               # Braille characters\\nascii-image-converter image.png -n               # Negative/inverted\\nascii-image-converter https://url/image.jpg      # Direct URL\\nascii-image-converter image.png --save-txt out   # Save as text\\n```\\n\\n### Option B: jp2a (lightweight, JPEG only)\\n\\n```bash\\nsudo apt install jp2a -y\\njp2a --width=80 image.jpg\\njp2a --colors image.jpg              # Colorized\\n```\\n\\n## Tool 7: Search Pre-Made ASCII Art\\n\\nSearch curated ASCII art from the web. Use `terminal` with `curl`.\\n\\n### Source A: ascii.co.uk (recommended for pre-made art)\\n\\nLarge collection of classic ASCII art organized by subject. Art is inside HTML `<pre>` tags. Fetch the page with curl, then extract art with a small Python snippet.\\n\\n**URL pattern:** `https://ascii.co.uk/art/{subject}`\\n\\n**Step 1 — Fetch the page:**\\n\\n```bash\\ncurl -s 'https://ascii.co.uk/art/cat' -o /tmp/ascii_art.html\\n```\\n\\n**Step 2 — Extract art from pre tags:**\\n\\n```python\\nimport re, html\\nwith open('/tmp/ascii_art.html') as f:\\n    text = f.read()\\narts = re.findall(r'<pre[^>]*>(.*?)</pre>', text, re.DOTALL)\\nfor art in arts:\\n    clean = re.sub(r'<[^>]+>', '', art)\\n    clean = html.unescape(clean).strip()\\n    if len(clean) > 30:\\n        print(clean)\\n        print('\\\\n---\\\\n')\\n```\\n\\n**Available subjects** (use as URL path):\\n- Animals: `cat`, `dog`, `horse`, `bird`, `fish`, `dragon`, `snake`, `rabbit`, `elephant`, `dolphin`, `butterfly`, `owl`, `wolf`, `bear`, `penguin`, `turtle`\\n- Objects: `car`, `ship`, `airplane`, `rocket`, `guitar`, `computer`, `coffee`, `beer`, `cake`, `house`, `castle`, `sword`, `crown`, `key`\\n- Nature: `tree`, `flower`, `sun`, `moon`, `star`, `mountain`, `ocean`, `rainbow`\\n- Characters: `skull`, `robot`, `angel`, `wizard`, `pirate`, `ninja`, `alien`\\n- Holidays: `christmas`, `halloween`, `valentine`\\n\\n**Tips:**\\n- Preserve artist signatures/initials — important etiquette\\n- Multiple art pieces per page — pick the best one for the user\\n- Works reliably via curl, no JavaScript needed\\n\\n### Source B: GitHub Octocat API (fun easter egg)\\n\\nReturns a random GitHub Octocat with a wise quote. No auth needed.\\n\\n```bash\\ncurl -s https://api.github.com/octocat\\n```\\n\\n## Tool 8: Fun ASCII Utilities (via curl)\\n\\nThese free services return ASCII art directly — great for fun extras.\\n\\n### QR Codes as ASCII Art\\n\\n```bash\\ncurl -s \\\"qrenco.de/Hello+World\\\"\\ncurl -s \\\"qrenco.de/https://example.com\\\"\\n```\\n\\n### Weather as ASCII Art\\n\\n```bash\\ncurl -s \\\"wttr.in/London\\\"          # Full weather report with ASCII graphics\\ncurl -s \\\"wttr.in/Moon\\\"            # Moon phase in ASCII art\\ncurl -s \\\"v2.wttr.in/London\\\"       # Detailed version\\n```\\n\\n## Tool 9: LLM-Generated Custom Art (Fallback)\\n\\nWhen tools above don't have what's needed, generate ASCII art directly using these Unicode characters:\\n\\n### Character Palette\\n\\n**Box Drawing:** `╔ ╗ ╚ ╝ ║ ═ ╠ ╣ ╦ ╩ ╬ ┌ ┐ └ ┘ │ ─ ├ ┤ ┬ ┴ ┼ ╭ ╮ ╰ ╯`\\n\\n**Block Elements:** `░ ▒ ▓ █ ▄ ▀ ▌ ▐ ▖ ▗ ▘ ▝ ▚ ▞`\\n\\n**Geometric & Symbols:** `◆ ◇ ◈ ● ○ ◉ ■ □ ▲ △ ▼ ▽ ★ ☆ ✦ ✧ ◀ ▶ ◁ ▷ ⬡ ⬢ ⌂`\\n\\n### Rules\\n\\n- Max width: 60 characters per line (terminal-safe)\\n- Max height: 15 lines for banners, 25 for scenes\\n- Monospace only: output must render correctly in fixed-width fonts\\n\\n## Decision Flow\\n\\n1. **Text as a banner** → pyfiglet if installed, otherwise asciified API via curl\\n2. **Wrap a message in fun character art** → cowsay\\n3. **Add decorative border/frame** → boxes (can combine with pyfiglet/asciified)\\n4. **Art of a specific thing** (cat, rocket, dragon) → ascii.co.uk via curl + parsing\\n5. **Convert an image to ASCII** → ascii-image-converter or jp2a\\n6. **QR code** → qrenco.de via curl\\n7. **Weather/moon art** → wttr.in via curl\\n8. **Something custom/creative** → LLM generation with Unicode palette\\n9. **Any tool not installed** → install it, or fall back to next option\\n\", \"path\": \"creative/ascii-art/SKILL.md\", \"skill_dir\": \"/home/kuhnn/.hermes/skills/creative/ascii-art\", \"linked_files\": null, \"usage_hint\": null, \"required_environment_variables\": [], \"required_commands\": [], \"missing_required_environment_variables\": [], \"missing_credential_files\": [], \"missing_required_commands\": [], \"setup_needed\": false, \"setup_skipped\": false, \"readiness_status\": \"available\", \"metadata\": {\"hermes\": {\"tags\": [\"ASCII\", \"Art\", \"Banners\", \"Creative\", \"Unicode\", \"Text-Art\", \"pyfiglet\", \"figlet\", \"cowsay\", \"boxes\"], \"related_skills\": [\"excalidraw\"]}}}",
      "tool_call_id": "call_function_7wwd137adnfq_8"
    },
    {
      "role": "tool",
      "name": "skill_view",
      "content": "{\"success\": true, \"name\": \"ascii-video\", \"description\": \"ASCII video: convert video/audio to colored ASCII MP4/GIF.\", \"tags\": [], \"related_skills\": [], \"content\": \"---\\nname: ascii-video\\ndescription: \\\"ASCII video: convert video/audio to colored ASCII MP4/GIF.\\\"\\nplatforms: [linux, macos, windows]\\n---\\n\\n# ASCII Video Production Pipeline\\n\\n## When to use\\n\\nUse when users request: ASCII video, text art video, terminal-style video, character art animation, retro text visualization, audio visualizer in ASCII, converting video to ASCII art, matrix-style effects, or any animated ASCII output.\\n\\n## What's inside\\n\\nProduction pipeline for ASCII art video — any format. Converts video/audio/images/generative input into colored ASCII character video output (MP4, GIF, image sequence). Covers: video-to-ASCII conversion, audio-reactive music visualizers, generative ASCII art animations, hybrid video+audio reactive, text/lyrics overlays, real-time terminal rendering.\\n\\n## Creative Standard\\n\\nThis is visual art. ASCII characters are the medium; cinema is the standard.\\n\\n**Before writing a single line of code**, articulate the creative concept. What is the mood? What visual story does this tell? What makes THIS project different from every other ASCII video? The user's prompt is a starting point — interpret it with creative ambition, not literal transcription.\\n\\n**First-render excellence is non-negotiable.** The output must be visually striking without requiring revision rounds. If something looks generic, flat, or like \\\"AI-generated ASCII art,\\\" it is wrong — rethink the creative concept before shipping.\\n\\n**Go beyond the reference vocabulary.** The effect catalogs, shader presets, and palette libraries in the references are a starting vocabulary. For every project, combine, modify, and invent new patterns. The catalog is a palette of paints — you write the painting.\\n\\n**Be proactively creative.** Extend the skill's vocabulary when the project calls for it. If the references don't have what the vision demands, build it. Include at least one visual moment the user didn't ask for but will appreciate — a transition, an effect, a color choice that elevates the whole piece.\\n\\n**Cohesive aesthetic over technical correctness.** All scenes in a video must feel connected by a unifying visual language — shared color temperature, related character palettes, consistent motion vocabulary. A technically correct video where every scene uses a random different effect is an aesthetic failure.\\n\\n**Dense, layered, considered.** Every frame should reward viewing. Never flat black backgrounds. Always multi-grid composition. Always per-scene variation. Always intentional color.\\n\\n## Modes\\n\\n| Mode | Input | Output | Reference |\\n|------|-------|--------|-----------|\\n| **Video-to-ASCII** | Video file | ASCII recreation of source footage | `references/inputs.md` § Video Sampling |\\n| **Audio-reactive** | Audio file | Generative visuals driven by audio features | `references/inputs.md` § Audio Analysis |\\n| **Generative** | None (or seed params) | Procedural ASCII animation | `references/effects.md` |\\n| **Hybrid** | Video + audio | ASCII video with audio-reactive overlays | Both input refs |\\n| **Lyrics/text** | Audio + text/SRT | Timed text with visual effects | `references/inputs.md` § Text/Lyrics |\\n| **TTS narration** | Text quotes + TTS API | Narrated testimonial/quote video with typed text | `references/inputs.md` § TTS Integration |\\n\\n## Stack\\n\\nSingle self-contained Python script per project. No GPU required.\\n\\n| Layer | Tool | Purpose |\\n|-------|------|---------|\\n| Core | Python 3.10+, NumPy | Math, array ops, vectorized effects |\\n| Signal | SciPy | FFT, peak detection (audio modes) |\\n| Imaging | Pillow (PIL) | Font rasterization, frame decoding, image I/O |\\n| Video I/O | ffmpeg (CLI) | Decode input, encode output, mux audio |\\n| Parallel | concurrent.futures | N workers for batch/clip rendering |\\n| TTS | ElevenLabs API (optional) | Generate narration clips |\\n| Optional | OpenCV | Video frame sampling, edge detection |\\n\\n## Pipeline Architecture\\n\\nEvery mode follows the same 6-stage pipeline:\\n\\n```\\nINPUT → ANALYZE → SCENE_FN → TONEMAP → SHADE → ENCODE\\n```\\n\\n1. **INPUT** — Load/decode source material (video frames, audio samples, images, or nothing)\\n2. **ANALYZE** — Extract per-frame features (audio bands, video luminance/edges, motion vectors)\\n3. **SCENE_FN** — Scene function renders to pixel canvas (`uint8 H,W,3`). Composes multiple character grids via `_render_vf()` + pixel blend modes. See `references/composition.md`\\n4. **TONEMAP** — Percentile-based adaptive brightness normalization. See `references/composition.md` § Adaptive Tonemap\\n5. **SHADE** — Post-processing via `ShaderChain` + `FeedbackBuffer`. See `references/shaders.md`\\n6. **ENCODE** — Pipe raw RGB frames to ffmpeg for H.264/GIF encoding\\n\\n## Creative Direction\\n\\n### Aesthetic Dimensions\\n\\n| Dimension | Options | Reference |\\n|-----------|---------|-----------|\\n| **Character palette** | Density ramps, block elements, symbols, scripts (katakana, Greek, runes, braille), project-specific | `architecture.md` § Palettes |\\n| **Color strategy** | HSV, OKLAB/OKLCH, discrete RGB palettes, auto-generated harmony, monochrome, temperature | `architecture.md` § Color System |\\n| **Background texture** | Sine fields, fBM noise, domain warp, voronoi, reaction-diffusion, cellular automata, video | `effects.md` |\\n| **Primary effects** | Rings, spirals, tunnel, vortex, waves, interference, aurora, fire, SDFs, strange attractors | `effects.md` |\\n| **Particles** | Sparks, snow, rain, bubbles, runes, orbits, flocking boids, flow-field followers, trails | `effects.md` § Particles |\\n| **Shader mood** | Retro CRT, clean modern, glitch art, cinematic, dreamy, industrial, psychedelic | `shaders.md` |\\n| **Grid density** | xs(8px) through xxl(40px), mixed per layer | `architecture.md` § Grid System |\\n| **Coordinate space** | Cartesian, polar, tiled, rotated, fisheye, Möbius, domain-warped | `effects.md` § Transforms |\\n| **Feedback** | Zoom tunnel, rainbow trails, ghostly echo, rotating mandala, color evolution | `composition.md` § Feedback |\\n| **Masking** | Circle, ring, gradient, text stencil, animated iris/wipe/dissolve | `composition.md` § Masking |\\n| **Transitions** | Crossfade, wipe, dissolve, glitch cut, iris, mask-based reveal | `shaders.md` § Transitions |\\n\\n### Per-Section Variation\\n\\nNever use the same config for the entire video. For each section/scene:\\n- **Different background effect** (or compose 2-3)\\n- **Different character palette** (match the mood)\\n- **Different color strategy** (or at minimum a different hue)\\n- **Vary shader intensity** (more bloom during peaks, more grain during quiet)\\n- **Different particle types** if particles are active\\n\\n### Project-Specific Invention\\n\\nFor every project, invent at least one of:\\n- A custom character palette matching the theme\\n- A custom background effect (combine/modify existing building blocks)\\n- A custom color palette (discrete RGB set matching the brand/mood)\\n- A custom particle character set\\n- A novel scene transition or visual moment\\n\\nDon't just pick from the catalog. The catalog is vocabulary — you write the poem.\\n\\n## Workflow\\n\\n### Step 1: Creative Vision\\n\\nBefore any code, articulate the creative concept:\\n\\n- **Mood/atmosphere**: What should the viewer feel? Energetic, meditative, chaotic, elegant, ominous?\\n- **Visual story**: What happens over the duration? Build tension? Transform? Dissolve?\\n- **Color world**: Warm/cool? Monochrome? Neon? Earth tones? What's the dominant hue?\\n- **Character texture**: Dense data? Sparse stars? Organic dots? Geometric blocks?\\n- **What makes THIS different**: What's the one thing that makes this project unique?\\n- **Emotional arc**: How do scenes progress? Open with energy, build to climax, resolve?\\n\\nMap the user's prompt to aesthetic choices. A \\\"chill lo-fi visualizer\\\" demands different everything from a \\\"glitch cyberpunk data stream.\\\"\\n\\n### Step 2: Technical Design\\n\\n- **Mode** — which of the 6 modes above\\n- **Resolution** — landscape 1920x1080 (default), portrait 1080x1920, square 1080x1080 @ 24fps\\n- **Hardware detection** — auto-detect cores/RAM, set quality profile. See `references/optimization.md`\\n- **Sections** — map timestamps to scene functions, each with its own effect/palette/color/shader config\\n- **Output format** — MP4 (default), GIF (640x360 @ 15fps), PNG sequence\\n\\n### Step 3: Build the Script\\n\\nSingle Python file. Components (with references):\\n\\n1. **Hardware detection + quality profile** — `references/optimization.md`\\n2. **Input loader** — mode-dependent; `references/inputs.md`\\n3. **Feature analyzer** — audio FFT, video luminance, or synthetic\\n4. **Grid + renderer** — multi-density grids with bitmap cache; `references/architecture.md`\\n5. **Character palettes** — multiple per project; `references/architecture.md` § Palettes\\n6. **Color system** — HSV + discrete RGB + harmony generation; `references/architecture.md` § Color\\n7. **Scene functions** — each returns `canvas (uint8 H,W,3)`; `references/scenes.md`\\n8. **Tonemap** — adaptive brightness normalization; `references/composition.md`\\n9. **Shader pipeline** — `ShaderChain` + `FeedbackBuffer`; `references/shaders.md`\\n10. **Scene table + dispatcher** — time → scene function + config; `references/scenes.md`\\n11. **Parallel encoder** — N-worker clip rendering with ffmpeg pipes\\n12. **Main** — orchestrate full pipeline\\n\\n### Step 4: Quality Verification\\n\\n- **Test frames first**: render single frames at key timestamps before full render\\n- **Brightness check**: `canvas.mean() > 8` for all ASCII content. If dark, lower gamma\\n- **Visual coherence**: do all scenes feel like they belong to the same video?\\n- **Creative vision check**: does the output match the concept from Step 1? If it looks generic, go back\\n\\n## Critical Implementation Notes\\n\\n### Brightness — Use `tonemap()`, Not Linear Multipliers\\n\\nThis is the #1 visual issue. ASCII on black is inherently dark. **Never use `canvas * N` multipliers** — they clip highlights. Use adaptive tonemap:\\n\\n```python\\ndef tonemap(canvas, gamma=0.75):\\n    f = canvas.astype(np.float32)\\n    lo, hi = np.percentile(f[::4, ::4], [1, 99.5])\\n    if hi - lo < 10: hi = lo + 10\\n    f = np.clip((f - lo) / (hi - lo), 0, 1) ** gamma\\n    return (f * 255).astype(np.uint8)\\n```\\n\\nPipeline: `scene_fn() → tonemap() → FeedbackBuffer → ShaderChain → ffmpeg`\\n\\nPer-scene gamma: default 0.75, solarize 0.55, posterize 0.50, bright scenes 0.85. Use `screen` blend (not `overlay`) for dark layers.\\n\\n### Font Cell Height\\n\\nmacOS Pillow: `textbbox()` returns wrong height. Use `font.getmetrics()`: `cell_height = ascent + descent`. See `references/troubleshooting.md`.\\n\\n### ffmpeg Pipe Deadlock\\n\\nNever `stderr=subprocess.PIPE` with long-running ffmpeg — buffer fills at 64KB and deadlocks. Redirect to file. See `references/troubleshooting.md`.\\n\\n### Font Compatibility\\n\\nNot all Unicode chars render in all fonts. Validate palettes at init — render each char, check for blank output. See `references/troubleshooting.md`.\\n\\n### Per-Clip Architecture\\n\\nFor segmented videos (quotes, scenes, chapters), render each as a separate clip file for parallel rendering and selective re-rendering. See `references/scenes.md`.\\n\\n## Performance Targets\\n\\n| Component | Budget |\\n|-----------|--------|\\n| Feature extraction | 1-5ms |\\n| Effect function | 2-15ms |\\n| Character render | 80-150ms (bottleneck) |\\n| Shader pipeline | 5-25ms |\\n| **Total** | ~100-200ms/frame |\\n\\n## References\\n\\n| File | Contents |\\n|------|----------|\\n| `references/architecture.md` | Grid system, resolution presets, font selection, character palettes (20+), color system (HSV + OKLAB + discrete RGB + harmony generation), `_render_vf()` helper, GridLayer class |\\n| `references/composition.md` | Pixel blend modes (20 modes), `blend_canvas()`, multi-grid composition, adaptive `tonemap()`, `FeedbackBuffer`, `PixelBlendStack`, masking/stencil system |\\n| `references/effects.md` | Effect building blocks: value field generators, hue fields, noise/fBM/domain warp, voronoi, reaction-diffusion, cellular automata, SDFs, strange attractors, particle systems, coordinate transforms, temporal coherence |\\n| `references/shaders.md` | `ShaderChain`, `_apply_shader_step()` dispatch, 38 shader catalog, audio-reactive scaling, transitions, tint presets, output format encoding, terminal rendering |\\n| `references/scenes.md` | Scene protocol, `Renderer` class, `SCENES` table, `render_clip()`, beat-synced cutting, parallel rendering, design patterns (layer hierarchy, directional arcs, visual metaphors, compositional techniques), complete scene examples at every complexity level, scene design checklist |\\n| `references/inputs.md` | Audio analysis (FFT, bands, beats), video sampling, image conversion, text/lyrics, TTS integration (ElevenLabs, voice assignment, audio mixing) |\\n| `references/optimization.md` | Hardware detection, quality profiles, vectorized patterns, parallel rendering, memory management, performance budgets |\\n| `references/troubleshooting.md` | NumPy broadcasting traps, blend mode pitfalls, multiprocessing/pickling, brightness diagnostics, ffmpeg issues, font problems, common mistakes |\\n\\n---\\n\\n## Creative Divergence (use only when user requests experimental/creative/unique output)\\n\\nIf the user asks for creative, experimental, surprising, or unconventional output, select the strategy that best fits and reason through its steps BEFORE generating code.\\n\\n- **Forced Connections** — when the user wants cross-domain inspiration (\\\"make it look organic,\\\" \\\"industrial aesthetic\\\")\\n- **Conceptual Blending** — when the user names two things to combine (\\\"ocean meets music,\\\" \\\"space + calligraphy\\\")\\n- **Oblique Strategies** — when the user is maximally open (\\\"surprise me,\\\" \\\"something I've never seen\\\")\\n\\n### Forced Connections\\n1. Pick a domain unrelated to the visual goal (weather systems, microbiology, architecture, fluid dynamics, textile weaving)\\n2. List its core visual/structural elements (erosion → gradual reveal; mitosis → splitting duplication; weaving → interlocking patterns)\\n3. Map those elements onto ASCII characters and animation patterns\\n4. Synthesize — what does \\\"erosion\\\" or \\\"crystallization\\\" look like in a character grid?\\n\\n### Conceptual Blending\\n1. Name two distinct visual/conceptual spaces (e.g., ocean waves + sheet music)\\n2. Map correspondences (crests = high notes, troughs = rests, foam = staccato)\\n3. Blend selectively — keep the most interesting mappings, discard forced ones\\n4. Develop emergent properties that exist only in the blend\\n\\n### Oblique Strategies\\n1. Draw one: \\\"Honor thy error as a hidden intention\\\" / \\\"Use an old idea\\\" / \\\"What would your closest friend do?\\\" / \\\"Emphasize the flaws\\\" / \\\"Turn it upside down\\\" / \\\"Only a part, not the whole\\\" / \\\"Reverse\\\"\\n2. Interpret the directive against the current ASCII animation challenge\\n3. Apply the lateral insight to the visual design before writing code\\n\", \"path\": \"creative/ascii-video/SKILL.md\", \"skill_dir\": \"/home/kuhnn/.hermes/skills/creative/ascii-video\", \"linked_files\": {\"references\": [\"references/effects.md\", \"references/shaders.md\", \"references/composition.md\", \"references/architecture.md\", \"references/troubleshooting.md\", \"references/optimization.md\", \"references/inputs.md\", \"references/scenes.md\"]}, \"usage_hint\": \"To view linked files, call skill_view(name, file_path) where file_path is e.g. 'references/api.md' or 'assets/config.yaml'\", \"required_environment_variables\": [], \"required_commands\": [], \"missing_required_environment_variables\": [], \"missing_credential_files\": [], \"missing_required_commands\": [], \"setup_needed\": false, \"setup_skipped\": false, \"readiness_status\": \"available\"}",
      "tool_call_id": "call_function_7wwd137adnfq_9"
    },
    {
      "role": "tool",
      "name": "skill_view",
      "content": "{\"success\": true, \"name\": \"baoyu-comic\", \"description\": \"Knowledge comics (知识漫画): educational, biography, tutorial.\", \"tags\": [\"comic\", \"knowledge-comic\", \"creative\", \"image-generation\"], \"related_skills\": [], \"content\": \"---\\nname: baoyu-comic\\ndescription: \\\"Knowledge comics (知识漫画): educational, biography, tutorial.\\\"\\nversion: 1.56.1\\nauthor: 宝玉 (JimLiu)\\nlicense: MIT\\nplatforms: [linux, macos, windows]\\nmetadata:\\n  hermes:\\n    tags: [comic, knowledge-comic, creative, image-generation]\\n    homepage: https://github.com/JimLiu/baoyu-skills#baoyu-comic\\n---\\n\\n# Knowledge Comic Creator\\n\\nAdapted from [baoyu-comic](https://github.com/JimLiu/baoyu-skills) for Hermes Agent's tool ecosystem.\\n\\nCreate original knowledge comics with flexible art style × tone combinations.\\n\\n## When to Use\\n\\nTrigger this skill when the user asks to create a knowledge/educational comic, biography comic, tutorial comic, or uses terms like \\\"知识漫画\\\", \\\"教育漫画\\\", or \\\"Logicomix-style\\\". The user provides content (text, file path, URL, or topic) and optionally specifies art style, tone, layout, aspect ratio, or language.\\n\\n## Reference Images\\n\\nHermes' `image_generate` tool is **prompt-only** — it accepts a text prompt and an aspect ratio, and returns an image URL. It does **NOT** accept reference images. When the user supplies a reference image, use it to **extract traits in text** that get embedded in every page prompt:\\n\\n**Intake**: Accept file paths when the user provides them (or pastes images in conversation).\\n- File path(s) → copy to `refs/NN-ref-{slug}.{ext}` alongside the comic output for provenance\\n- Pasted image with no path → ask the user for the path via `clarify`, or extract style traits verbally as a text fallback\\n- No reference → skip this section\\n\\n**Usage modes** (per reference):\\n\\n| Usage | Effect |\\n|-------|--------|\\n| `style` | Extract style traits (line treatment, texture, mood) and append to every page's prompt body |\\n| `palette` | Extract hex colors and append to every page's prompt body |\\n| `scene` | Extract scene composition or subject notes and append to the relevant page(s) |\\n\\n**Record in each page's prompt frontmatter** when refs exist:\\n\\n```yaml\\nreferences:\\n  - ref_id: 01\\n    filename: 01-ref-scene.png\\n    usage: style\\n    traits: \\\"muted earth tones, soft-edged ink wash, low-contrast backgrounds\\\"\\n```\\n\\nCharacter consistency is driven by **text descriptions** in `characters/characters.md` (written in Step 3) that get embedded inline in every page prompt (Step 5). The optional PNG character sheet generated in Step 7.1 is a human-facing review artifact, not an input to `image_generate`.\\n\\n## Options\\n\\n### Visual Dimensions\\n\\n| Option | Values | Description |\\n|--------|--------|-------------|\\n| Art | ligne-claire (default), manga, realistic, ink-brush, chalk, minimalist | Art style / rendering technique |\\n| Tone | neutral (default), warm, dramatic, romantic, energetic, vintage, action | Mood / atmosphere |\\n| Layout | standard (default), cinematic, dense, splash, mixed, webtoon, four-panel | Panel arrangement |\\n| Aspect | 3:4 (default, portrait), 4:3 (landscape), 16:9 (widescreen) | Page aspect ratio |\\n| Language | auto (default), zh, en, ja, etc. | Output language |\\n| Refs | File paths | Reference images used for style / palette trait extraction (not passed to the image model). See [Reference Images](#reference-images) above. |\\n\\n### Partial Workflow Options\\n\\n| Option | Description |\\n|--------|-------------|\\n| Storyboard only | Generate storyboard only, skip prompts and images |\\n| Prompts only | Generate storyboard + prompts, skip images |\\n| Images only | Generate images from existing prompts directory |\\n| Regenerate N | Regenerate specific page(s) only (e.g., `3` or `2,5,8`) |\\n\\nDetails: [references/partial-workflows.md](references/partial-workflows.md)\\n\\n### Art, Tone & Preset Catalogue\\n\\n- **Art styles** (6): `ligne-claire`, `manga`, `realistic`, `ink-brush`, `chalk`, `minimalist`. Full definitions at `references/art-styles/<style>.md`.\\n- **Tones** (7): `neutral`, `warm`, `dramatic`, `romantic`, `energetic`, `vintage`, `action`. Full definitions at `references/tones/<tone>.md`.\\n- **Presets** (5) with special rules beyond plain art+tone:\\n\\n  | Preset | Equivalent | Hook |\\n  |--------|-----------|------|\\n  | `ohmsha` | manga + neutral | Visual metaphors, no talking heads, gadget reveals |\\n  | `wuxia` | ink-brush + action | Qi effects, combat visuals, atmospheric |\\n  | `shoujo` | manga + romantic | Decorative elements, eye details, romantic beats |\\n  | `concept-story` | manga + warm | Visual symbol system, growth arc, dialogue+action balance |\\n  | `four-panel` | minimalist + neutral + four-panel layout | 起承转合 structure, B&W + spot color, stick-figure characters |\\n\\n  Full rules at `references/presets/<preset>.md` — load the file when a preset is picked.\\n\\n- **Compatibility matrix** and **content-signal → preset** table live in [references/auto-selection.md](references/auto-selection.md). Read it before recommending combinations in Step 2.\\n\\n## File Structure\\n\\nOutput directory: `comic/{topic-slug}/`\\n- Slug: 2-4 words kebab-case from topic (e.g., `alan-turing-bio`)\\n- Conflict: append timestamp (e.g., `turing-story-20260118-143052`)\\n\\n**Contents**:\\n| File | Description |\\n|------|-------------|\\n| `source-{slug}.md` | Saved source content (kebab-case slug matches the output directory) |\\n| `analysis.md` | Content analysis |\\n| `storyboard.md` | Storyboard with panel breakdown |\\n| `characters/characters.md` | Character definitions |\\n| `characters/characters.png` | Character reference sheet (downloaded from `image_generate`) |\\n| `prompts/NN-{cover\\\\|page}-[slug].md` | Generation prompts |\\n| `NN-{cover\\\\|page}-[slug].png` | Generated images (downloaded from `image_generate`) |\\n| `refs/NN-ref-{slug}.{ext}` | User-supplied reference images (optional, for provenance) |\\n\\n## Language Handling\\n\\n**Detection Priority**:\\n1. User-specified language (explicit option)\\n2. User's conversation language\\n3. Source content language\\n\\n**Rule**: Use user's input language for ALL interactions:\\n- Storyboard outlines and scene descriptions\\n- Image generation prompts\\n- User selection options and confirmations\\n- Progress updates, questions, errors, summaries\\n\\nTechnical terms remain in English.\\n\\n## Workflow\\n\\n### Progress Checklist\\n\\n```\\nComic Progress:\\n- [ ] Step 1: Setup & Analyze\\n  - [ ] 1.1 Analyze content\\n  - [ ] 1.2 Check existing directory\\n- [ ] Step 2: Confirmation - Style & options ⚠️ REQUIRED\\n- [ ] Step 3: Generate storyboard + characters\\n- [ ] Step 4: Review outline (conditional)\\n- [ ] Step 5: Generate prompts\\n- [ ] Step 6: Review prompts (conditional)\\n- [ ] Step 7: Generate images\\n  - [ ] 7.1 Generate character sheet (if needed) → characters/characters.png\\n  - [ ] 7.2 Generate pages (with character descriptions embedded in prompt)\\n- [ ] Step 8: Completion report\\n```\\n\\n### Flow\\n\\n```\\nInput → Analyze → [Check Existing?] → [Confirm: Style + Reviews] → Storyboard → [Review?] → Prompts → [Review?] → Images → Complete\\n```\\n\\n### Step Summary\\n\\n| Step | Action | Key Output |\\n|------|--------|------------|\\n| 1.1 | Analyze content | `analysis.md`, `source-{slug}.md` |\\n| 1.2 | Check existing directory | Handle conflicts |\\n| 2 | Confirm style, focus, audience, reviews | User preferences |\\n| 3 | Generate storyboard + characters | `storyboard.md`, `characters/` |\\n| 4 | Review outline (if requested) | User approval |\\n| 5 | Generate prompts | `prompts/*.md` |\\n| 6 | Review prompts (if requested) | User approval |\\n| 7.1 | Generate character sheet (if needed) | `characters/characters.png` |\\n| 7.2 | Generate pages | `*.png` files |\\n| 8 | Completion report | Summary |\\n\\n### User Questions\\n\\nUse the `clarify` tool to confirm options. Since `clarify` handles one question at a time, ask the most important question first and proceed sequentially. See [references/workflow.md](references/workflow.md) for the full Step 2 question set.\\n\\n**Timeout handling (CRITICAL)**: `clarify` can return `\\\"The user did not provide a response within the time limit. Use your best judgement to make the choice and proceed.\\\"` — this is NOT user consent to default everything.\\n\\n- Treat it as a default **for that one question only**. Continue asking the remaining Step 2 questions in sequence; each question is an independent consent point.\\n- **Surface the default to the user visibly** in your next message so they have a chance to correct it: e.g. `\\\"Style: defaulted to ohmsha preset (clarify timed out). Say the word to switch.\\\"` — an unreported default is indistinguishable from never having asked.\\n- Do NOT collapse Step 2 into a single \\\"use all defaults\\\" pass after one timeout. If the user is genuinely absent, they will be equally absent for all five questions — but they can correct visible defaults when they return, and cannot correct invisible ones.\\n\\n### Step 7: Image Generation\\n\\nUse Hermes' built-in `image_generate` tool for all image rendering. Its schema accepts only `prompt` and `aspect_ratio` (`landscape` | `portrait` | `square`); it **returns a URL**, not a local file. Every generated page or character sheet must therefore be downloaded to the output directory.\\n\\n**Prompt file requirement (hard)**: write each image's full, final prompt to a standalone file under `prompts/` (naming: `NN-{type}-[slug].md`) BEFORE calling `image_generate`. The prompt file is the reproducibility record.\\n\\n**Aspect ratio mapping** — the storyboard's `aspect_ratio` field maps to `image_generate`'s format as follows:\\n\\n| Storyboard ratio | `image_generate` format |\\n|------------------|-------------------------|\\n| `3:4`, `9:16`, `2:3` | `portrait` |\\n| `4:3`, `16:9`, `3:2` | `landscape` |\\n| `1:1` | `square` |\\n\\n**Download step** — after every `image_generate` call:\\n1. Read the URL from the tool result\\n2. Fetch the image bytes using an **absolute** output path, e.g.\\n   `curl -fsSL \\\"<url>\\\" -o /abs/path/to/comic/<slug>/NN-page-<slug>.png`\\n3. Verify the file exists and is non-empty at that exact path before proceeding to the next page\\n\\n**Never rely on shell CWD persistence for `-o` paths.** The terminal tool's persistent-shell CWD can change between batches (session expiry, `TERMINAL_LIFETIME_SECONDS`, a failed `cd` that leaves you in the wrong directory). `curl -o relative/path.png` is a silent footgun: if CWD has drifted, the file lands somewhere else with no error. **Always pass a fully-qualified absolute path to `-o`**, or pass `workdir=<abs path>` to the terminal tool. Incident Apr 2026: pages 06-09 of a 10-page comic landed at the repo root instead of `comic/<slug>/` because batch 3 inherited a stale CWD from batch 2 and `curl -o 06-page-skills.png` wrote to the wrong directory. The agent then spent several turns claiming the files existed where they didn't.\\n\\n**7.1 Character sheet** — generate it (to `characters/characters.png`, aspect `landscape`) when the comic is multi-page with recurring characters. Skip for simple presets (e.g., four-panel minimalist) or single-page comics. The prompt file at `characters/characters.md` must exist before invoking `image_generate`. The rendered PNG is a **human-facing review artifact** (so the user can visually verify character design) and a reference for later regenerations or manual prompt edits — it does **not** drive Step 7.2. Page prompts are already written in Step 5 from the **text descriptions** in `characters/characters.md`; `image_generate` cannot accept images as visual input.\\n\\n**7.2 Pages** — each page's prompt MUST already be at `prompts/NN-{cover|page}-[slug].md` before invoking `image_generate`. Because `image_generate` is prompt-only, character consistency is enforced by **embedding character descriptions (sourced from `characters/characters.md`) inline in every page prompt during Step 5**. The embedding is done uniformly whether or not a PNG sheet is produced in 7.1; the PNG is only a review/regeneration aid.\\n\\n**Backup rule**: existing `prompts/…md` and `…png` files → rename with `-backup-YYYYMMDD-HHMMSS` suffix before regenerating.\\n\\nFull step-by-step workflow (analysis, storyboard, review gates, regeneration variants): [references/workflow.md](references/workflow.md).\\n\\n## References\\n\\n**Core Templates**:\\n- [analysis-framework.md](references/analysis-framework.md) - Deep content analysis\\n- [character-template.md](references/character-template.md) - Character definition format\\n- [storyboard-template.md](references/storyboard-template.md) - Storyboard structure\\n- [ohmsha-guide.md](references/ohmsha-guide.md) - Ohmsha manga specifics\\n\\n**Style Definitions**:\\n- `references/art-styles/` - Art styles (ligne-claire, manga, realistic, ink-brush, chalk, minimalist)\\n- `references/tones/` - Tones (neutral, warm, dramatic, romantic, energetic, vintage, action)\\n- `references/presets/` - Presets with special rules (ohmsha, wuxia, shoujo, concept-story, four-panel)\\n- `references/layouts/` - Layouts (standard, cinematic, dense, splash, mixed, webtoon, four-panel)\\n\\n**Workflow**:\\n- [workflow.md](references/workflow.md) - Full workflow details\\n- [auto-selection.md](references/auto-selection.md) - Content signal analysis\\n- [partial-workflows.md](references/partial-workflows.md) - Partial workflow options\\n\\n## Page Modification\\n\\n| Action | Steps |\\n|--------|-------|\\n| **Edit** | **Update prompt file FIRST** → regenerate image → download new PNG |\\n| **Add** | Create prompt at position → generate with character descriptions embedded → renumber subsequent → update storyboard |\\n| **Delete** | Remove files → renumber subsequent → update storyboard |\\n\\n**IMPORTANT**: When updating pages, ALWAYS update the prompt file (`prompts/NN-{cover|page}-[slug].md`) FIRST before regenerating. This ensures changes are documented and reproducible.\\n\\n## Pitfalls\\n\\n- Image generation: 10-30 seconds per page; auto-retry once on failure\\n- **Always download** the URL returned by `image_generate` to a local PNG — downstream tooling (and the user's review) expects files in the output directory, not ephemeral URLs\\n- **Use absolute paths for `curl -o`** — never rely on persistent-shell CWD across batches. Silent footgun: files land in the wrong directory and subsequent `ls` on the intended path shows nothing. See Step 7 \\\"Download step\\\".\\n- Use stylized alternatives for sensitive public figures\\n- **Step 2 confirmation required** - do not skip\\n- **Steps 4/6 conditional** - only if user requested in Step 2\\n- **Step 7.1 character sheet** - recommended for multi-page comics, optional for simple presets. The PNG is a review/regeneration aid; page prompts (written in Step 5) use the text descriptions in `characters/characters.md`, not the PNG. `image_generate` does not accept images as visual input\\n- **Strip secrets** — scan source content for API keys, tokens, or credentials before writing any output file\\n\", \"path\": \"creative/baoyu-comic/SKILL.md\", \"skill_dir\": \"/home/kuhnn/.hermes/skills/creative/baoyu-comic\", \"linked_files\": {\"references\": [\"references/auto-selection.md\", \"references/partial-workflows.md\", \"references/analysis-framework.md\", \"references/ohmsha-guide.md\", \"references/base-prompt.md\", \"references/storyboard-template.md\", \"references/character-template.md\", \"references/workflow.md\"]}, \"usage_hint\": \"To view linked files, call skill_view(name, file_path) where file_path is e.g. 'references/api.md' or 'assets/config.yaml'\", \"required_environment_variables\": [], \"required_commands\": [], \"missing_required_environment_variables\": [], \"missing_credential_files\": [], \"missing_required_commands\": [], \"setup_needed\": false, \"setup_skipped\": false, \"readiness_status\": \"available\", \"metadata\": {\"hermes\": {\"tags\": [\"comic\", \"knowledge-comic\", \"creative\", \"image-generation\"], \"homepage\": \"https://github.com/JimLiu/baoyu-skills#baoyu-comic\"}}}",
      "tool_call_id": "call_function_7wwd137adnfq_10"
    },
    {
      "role": "assistant",
      "content": "",
      "reasoning": "Let me continue loading the remaining skills.",
      "finish_reason": "tool_calls",
      "reasoning_content": "Let me continue loading the remaining skills.",
      "reasoning_details": [
        {
          "signature": "f619e0b1957d7ce1749f22afb3c1a56007c3556db32f746496699ae08b33745b",
          "thinking": "Let me continue loading the remaining skills.",
          "type": "thinking"
        }
      ],
      "tool_calls": [
        {
          "id": "call_function_534pqwv2ijh0_1",
          "call_id": "call_function_534pqwv2ijh0_1",
          "response_item_id": "fc_function_534pqwv2ijh0_1",
          "type": "function",
          "function": {
            "name": "skill_view",
            "arguments": "{\"name\": \"baoyu-infographic\"}"
          }
        },
        {
          "id": "call_function_534pqwv2ijh0_2",
          "call_id": "call_function_534pqwv2ijh0_2",
          "response_item_id": "fc_function_534pqwv2ijh0_2",
          "type": "function",
          "function": {
            "name": "skill_view",
            "arguments": "{\"name\": \"claude-design\"}"
          }
        },
        {
          "id": "call_function_534pqwv2ijh0_3",
          "call_id": "call_function_534pqwv2ijh0_3",
          "response_item_id": "fc_function_534pqwv2ijh0_3",
          "type": "function",
          "function": {
            "name": "skill_view",
            "arguments": "{\"name\": \"comfyui\"}"
          }
        },
        {
          "id": "call_function_534pqwv2ijh0_4",
          "call_id": "call_function_534pqwv2ijh0_4",
          "response_item_id": "fc_function_534pqwv2ijh0_4",
          "type": "function",
          "function": {
            "name": "skill_view",
            "arguments": "{\"name\": \"design-md\"}"
          }
        },
        {
          "id": "call_function_534pqwv2ijh0_5",
          "call_id": "call_function_534pqwv2ijh0_5",
          "response_item_id": "fc_function_534pqwv2ijh0_5",
          "type": "function",
          "function": {
            "name": "skill_view",
            "arguments": "{\"name\": \"excalidraw\"}"
          }
        },
        {
          "id": "call_function_534pqwv2ijh0_6",
          "call_id": "call_function_534pqwv2ijh0_6",
          "response_item_id": "fc_function_534pqwv2ijh0_6",
          "type": "function",
          "function": {
            "name": "skill_view",
            "arguments": "{\"name\": \"humanizer\"}"
          }
        },
        {
          "id": "call_function_534pqwv2ijh0_7",
          "call_id": "call_function_534pqwv2ijh0_7",
          "response_item_id": "fc_function_534pqwv2ijh0_7",
          "type": "function",
          "function": {
            "name": "skill_view",
            "arguments": "{\"name\": \"ideation\"}"
          }
        },
        {
          "id": "call_function_534pqwv2ijh0_8",
          "call_id": "call_function_534pqwv2ijh0_8",
          "response_item_id": "fc_function_534pqwv2ijh0_8",
          "type": "function",
          "function": {
            "name": "skill_view",
            "arguments": "{\"name\": \"manim-video\"}"
          }
        },
        {
          "id": "call_function_534pqwv2ijh0_9",
          "call_id": "call_function_534pqwv2ijh0_9",
          "response_item_id": "fc_function_534pqwv2ijh0_9",
          "type": "function",
          "function": {
            "name": "skill_view",
            "arguments": "{\"name\": \"p5js\"}"
          }
        },
        {
          "id": "call_function_534pqwv2ijh0_10",
          "call_id": "call_function_534pqwv2ijh0_10",
          "response_item_id": "fc_function_534pqwv2ijh0_10",
          "type": "function",
          "function": {
            "name": "skill_view",
            "arguments": "{\"name\": \"pixel-art\"}"
          }
        }
      ]
    },
    {
      "role": "tool",
      "name": "skill_view",
      "content": "{\"success\": true, \"name\": \"baoyu-infographic\", \"description\": \"Infographics: 21 layouts x 21 styles (信息图, 可视化).\", \"tags\": [\"infographic\", \"visual-summary\", \"creative\", \"image-generation\"], \"related_skills\": [], \"content\": \"---\\nname: baoyu-infographic\\ndescription: \\\"Infographics: 21 layouts x 21 styles (信息图, 可视化).\\\"\\nversion: 1.56.1\\nauthor: 宝玉 (JimLiu)\\nlicense: MIT\\nplatforms: [linux, macos, windows]\\nmetadata:\\n  hermes:\\n    tags: [infographic, visual-summary, creative, image-generation]\\n    homepage: https://github.com/JimLiu/baoyu-skills#baoyu-infographic\\n---\\n\\n# Infographic Generator\\n\\nAdapted from [baoyu-infographic](https://github.com/JimLiu/baoyu-skills) for Hermes Agent's tool ecosystem.\\n\\nTwo dimensions: **layout** (information structure) × **style** (visual aesthetics). Freely combine any layout with any style.\\n\\n## When to Use\\n\\nTrigger this skill when the user asks to create an infographic, visual summary, information graphic, or uses terms like \\\"信息图\\\", \\\"可视化\\\", or \\\"高密度信息大图\\\". The user provides content (text, file path, URL, or topic) and optionally specifies layout, style, aspect ratio, or language.\\n\\n## Options\\n\\n| Option | Values |\\n|--------|--------|\\n| Layout | 21 options (see Layout Gallery), default: bento-grid |\\n| Style | 21 options (see Style Gallery), default: craft-handmade |\\n| Aspect | Named: landscape (16:9), portrait (9:16), square (1:1). Custom: any W:H ratio (e.g., 3:4, 4:3, 2.35:1) |\\n| Language | en, zh, ja, etc. |\\n\\n## Layout Gallery\\n\\n| Layout | Best For |\\n|--------|----------|\\n| `linear-progression` | Timelines, processes, tutorials |\\n| `binary-comparison` | A vs B, before-after, pros-cons |\\n| `comparison-matrix` | Multi-factor comparisons |\\n| `hierarchical-layers` | Pyramids, priority levels |\\n| `tree-branching` | Categories, taxonomies |\\n| `hub-spoke` | Central concept with related items |\\n| `structural-breakdown` | Exploded views, cross-sections |\\n| `bento-grid` | Multiple topics, overview (default) |\\n| `iceberg` | Surface vs hidden aspects |\\n| `bridge` | Problem-solution |\\n| `funnel` | Conversion, filtering |\\n| `isometric-map` | Spatial relationships |\\n| `dashboard` | Metrics, KPIs |\\n| `periodic-table` | Categorized collections |\\n| `comic-strip` | Narratives, sequences |\\n| `story-mountain` | Plot structure, tension arcs |\\n| `jigsaw` | Interconnected parts |\\n| `venn-diagram` | Overlapping concepts |\\n| `winding-roadmap` | Journey, milestones |\\n| `circular-flow` | Cycles, recurring processes |\\n| `dense-modules` | High-density modules, data-rich guides |\\n\\nFull definitions: `references/layouts/<layout>.md`\\n\\n## Style Gallery\\n\\n| Style | Description |\\n|-------|-------------|\\n| `craft-handmade` | Hand-drawn, paper craft (default) |\\n| `claymation` | 3D clay figures, stop-motion |\\n| `kawaii` | Japanese cute, pastels |\\n| `storybook-watercolor` | Soft painted, whimsical |\\n| `chalkboard` | Chalk on black board |\\n| `cyberpunk-neon` | Neon glow, futuristic |\\n| `bold-graphic` | Comic style, halftone |\\n| `aged-academia` | Vintage science, sepia |\\n| `corporate-memphis` | Flat vector, vibrant |\\n| `technical-schematic` | Blueprint, engineering |\\n| `origami` | Folded paper, geometric |\\n| `pixel-art` | Retro 8-bit |\\n| `ui-wireframe` | Grayscale interface mockup |\\n| `subway-map` | Transit diagram |\\n| `ikea-manual` | Minimal line art |\\n| `knolling` | Organized flat-lay |\\n| `lego-brick` | Toy brick construction |\\n| `pop-laboratory` | Blueprint grid, coordinate markers, lab precision |\\n| `morandi-journal` | Hand-drawn doodle, warm Morandi tones |\\n| `retro-pop-grid` | 1970s retro pop art, Swiss grid, thick outlines |\\n| `hand-drawn-edu` | Macaron pastels, hand-drawn wobble, stick figures |\\n\\nFull definitions: `references/styles/<style>.md`\\n\\n## Recommended Combinations\\n\\n| Content Type | Layout + Style |\\n|--------------|----------------|\\n| Timeline/History | `linear-progression` + `craft-handmade` |\\n| Step-by-step | `linear-progression` + `ikea-manual` |\\n| A vs B | `binary-comparison` + `corporate-memphis` |\\n| Hierarchy | `hierarchical-layers` + `craft-handmade` |\\n| Overlap | `venn-diagram` + `craft-handmade` |\\n| Conversion | `funnel` + `corporate-memphis` |\\n| Cycles | `circular-flow` + `craft-handmade` |\\n| Technical | `structural-breakdown` + `technical-schematic` |\\n| Metrics | `dashboard` + `corporate-memphis` |\\n| Educational | `bento-grid` + `chalkboard` |\\n| Journey | `winding-roadmap` + `storybook-watercolor` |\\n| Categories | `periodic-table` + `bold-graphic` |\\n| Product Guide | `dense-modules` + `morandi-journal` |\\n| Technical Guide | `dense-modules` + `pop-laboratory` |\\n| Trendy Guide | `dense-modules` + `retro-pop-grid` |\\n| Educational Diagram | `hub-spoke` + `hand-drawn-edu` |\\n| Process Tutorial | `linear-progression` + `hand-drawn-edu` |\\n\\nDefault: `bento-grid` + `craft-handmade`\\n\\n## Keyword Shortcuts\\n\\nWhen user input contains these keywords, **auto-select** the associated layout and offer associated styles as top recommendations in Step 3. Skip content-based layout inference for matched keywords.\\n\\nIf a shortcut has **Prompt Notes**, append them to the generated prompt (Step 5) as additional style instructions.\\n\\n| User Keyword | Layout | Recommended Styles | Default Aspect | Prompt Notes |\\n|--------------|--------|--------------------|----------------|--------------|\\n| 高密度信息大图 / high-density-info | `dense-modules` | `morandi-journal`, `pop-laboratory`, `retro-pop-grid` | portrait | — |\\n| 信息图 / infographic | `bento-grid` | `craft-handmade` | landscape | Minimalist: clean canvas, ample whitespace, no complex background textures. Simple cartoon elements and icons only. |\\n\\n## Output Structure\\n\\n```\\ninfographic/{topic-slug}/\\n├── source-{slug}.{ext}\\n├── analysis.md\\n├── structured-content.md\\n├── prompts/infographic.md\\n└── infographic.png\\n```\\n\\nSlug: 2-4 words kebab-case from topic. Conflict: append `-YYYYMMDD-HHMMSS`.\\n\\n## Core Principles\\n\\n- Preserve source data faithfully — no summarization or rephrasing (but **strip any credentials, API keys, tokens, or secrets** before including in outputs)\\n- Define learning objectives before structuring content\\n- Structure for visual communication (headlines, labels, visual elements)\\n\\n## Workflow\\n\\n### Step 1: Analyze Content\\n\\n**Load references**: Read `references/analysis-framework.md` from this skill.\\n\\n1. Save source content (file path or paste → `source.md` using `write_file`)\\n   - **Backup rule**: If `source.md` exists, rename to `source-backup-YYYYMMDD-HHMMSS.md`\\n2. Analyze: topic, data type, complexity, tone, audience\\n3. Detect source language and user language\\n4. Extract design instructions from user input\\n5. Save analysis to `analysis.md`\\n   - **Backup rule**: If `analysis.md` exists, rename to `analysis-backup-YYYYMMDD-HHMMSS.md`\\n\\nSee `references/analysis-framework.md` for detailed format.\\n\\n### Step 2: Generate Structured Content → `structured-content.md`\\n\\nTransform content into infographic structure:\\n1. Title and learning objectives\\n2. Sections with: key concept, content (verbatim), visual element, text labels\\n3. Data points (all statistics/quotes copied exactly)\\n4. Design instructions from user\\n\\n**Rules**: Markdown only. No new information. Preserve data faithfully. Strip any credentials or secrets from output.\\n\\nSee `references/structured-content-template.md` for detailed format.\\n\\n### Step 3: Recommend Combinations\\n\\n**3.1 Check Keyword Shortcuts first**: If user input matches a keyword from the **Keyword Shortcuts** table, auto-select the associated layout and prioritize associated styles as top recommendations. Skip content-based layout inference.\\n\\n**3.2 Otherwise**, recommend 3-5 layout×style combinations based on:\\n- Data structure → matching layout\\n- Content tone → matching style\\n- Audience expectations\\n- User design instructions\\n\\n### Step 4: Confirm Options\\n\\nUse the `clarify` tool to confirm options with the user. Since `clarify` handles one question at a time, ask the most important question first:\\n\\n**Q1 — Combination**: Present 3+ layout×style combos with rationale. Ask user to pick one.\\n\\n**Q2 — Aspect**: Ask for aspect ratio preference (landscape/portrait/square or custom W:H).\\n\\n**Q3 — Language** (only if source ≠ user language): Ask which language the text content should use.\\n\\n### Step 5: Generate Prompt → `prompts/infographic.md`\\n\\n**Backup rule**: If `prompts/infographic.md` exists, rename to `prompts/infographic-backup-YYYYMMDD-HHMMSS.md`\\n\\n**Load references**: Read the selected layout from `references/layouts/<layout>.md` and style from `references/styles/<style>.md`.\\n\\nCombine:\\n1. Layout definition from `references/layouts/<layout>.md`\\n2. Style definition from `references/styles/<style>.md`\\n3. Base template from `references/base-prompt.md`\\n4. Structured content from Step 2\\n5. All text in confirmed language\\n\\n**Aspect ratio resolution** for `{{ASPECT_RATIO}}`:\\n- Named presets → ratio string: landscape→`16:9`, portrait→`9:16`, square→`1:1`\\n- Custom W:H ratios → use as-is (e.g., `3:4`, `4:3`, `2.35:1`)\\n\\nSave the assembled prompt to `prompts/infographic.md` using `write_file`.\\n\\n### Step 6: Generate Image\\n\\nUse the `image_generate` tool with the assembled prompt from Step 5.\\n\\n- Map aspect ratio to image_generate's format: `16:9` → `landscape`, `9:16` → `portrait`, `1:1` → `square`\\n- For custom ratios, pick the closest named aspect\\n- On failure, auto-retry once\\n- Save the resulting image URL/path to the output directory\\n\\n### Step 7: Output Summary\\n\\nReport: topic, layout, style, aspect, language, output path, files created.\\n\\n## References\\n\\n- `references/analysis-framework.md` — Analysis methodology\\n- `references/structured-content-template.md` — Content format\\n- `references/base-prompt.md` — Prompt template\\n- `references/layouts/<layout>.md` — 21 layout definitions\\n- `references/styles/<style>.md` — 21 style definitions\\n\\n## Pitfalls\\n\\n1. **Data integrity is paramount** — never summarize, paraphrase, or alter source statistics. \\\"73% increase\\\" must stay \\\"73% increase\\\", not \\\"significant increase\\\".\\n2. **Strip secrets** — always scan source content for API keys, tokens, or credentials before including in any output file.\\n3. **One message per section** — each infographic section should convey one clear concept. Overloading sections reduces readability.\\n4. **Style consistency** — the style definition from the references file must be applied consistently across the entire infographic. Don't mix styles.\\n5. **image_generate aspect ratios** — the tool only supports `landscape`, `portrait`, and `square`. Custom ratios like `3:4` should map to the nearest option (portrait in that case).\\n\", \"path\": \"creative/baoyu-infographic/SKILL.md\", \"skill_dir\": \"/home/kuhnn/.hermes/skills/creative/baoyu-infographic\", \"linked_files\": {\"references\": [\"references/structured-content-template.md\", \"references/analysis-framework.md\", \"references/base-prompt.md\"]}, \"usage_hint\": \"To view linked files, call skill_view(name, file_path) where file_path is e.g. 'references/api.md' or 'assets/config.yaml'\", \"required_environment_variables\": [], \"required_commands\": [], \"missing_required_environment_variables\": [], \"missing_credential_files\": [], \"missing_required_commands\": [], \"setup_needed\": false, \"setup_skipped\": false, \"readiness_status\": \"available\", \"metadata\": {\"hermes\": {\"tags\": [\"infographic\", \"visual-summary\", \"creative\", \"image-generation\"], \"homepage\": \"https://github.com/JimLiu/baoyu-skills#baoyu-infographic\"}}}",
      "tool_call_id": "call_function_534pqwv2ijh0_1"
    },
    {
      "role": "tool",
      "name": "skill_view",
      "content": "{\"success\": true, \"name\": \"claude-design\", \"description\": \"Design one-off HTML artifacts (landing, deck, prototype).\", \"tags\": [\"design\", \"html\", \"prototype\", \"ux\", \"ui\", \"creative\", \"artifact\", \"deck\", \"motion\", \"design-system\"], \"related_skills\": [\"design-md\", \"popular-web-designs\", \"excalidraw\", \"architecture-diagram\"], \"content\": \"---\\nname: claude-design\\ndescription: Design one-off HTML artifacts (landing, deck, prototype).\\nversion: 1.0.0\\nauthor: BadTechBandit\\nlicense: MIT\\nplatforms: [linux, macos, windows]\\nmetadata:\\n  hermes:\\n    tags: [design, html, prototype, ux, ui, creative, artifact, deck, motion, design-system]\\n    related_skills: [design-md, popular-web-designs, excalidraw, architecture-diagram]\\n---\\n\\n# Claude Design for CLI/API Agents\\n\\nUse this skill when the user asks for design work that would normally fit Claude Design, but the agent is running in a CLI/API environment instead of the hosted Claude Design web UI.\\n\\nThe goal is to preserve Claude Design's useful design behavior and taste while removing hosted-tool plumbing that does not exist in normal agent environments.\\n\\n**Before starting, check for other web-design skills like `popular-web-designs` (ready-to-paste design systems for Stripe, Linear, Vercel, Notion, etc.) and `design-md` (Google's DESIGN.md token spec format).** If the user wants a known brand's look, load `popular-web-designs` alongside this one and let it supply the visual vocabulary. If the deliverable is a token spec file rather than a rendered artifact, use `design-md` instead. Full decision table below.\\n\\n## When To Use This Skill vs `popular-web-designs` vs `design-md`\\n\\nHermes has three design-related skills under `skills/creative/`. They do different jobs — load the right one (or combine them):\\n\\n| Skill | What it gives you | Use when the user wants... |\\n|---|---|---|\\n| **claude-design** (this one) | Design *process and taste* — how to scope a brief, gather context, produce variants, verify a local HTML artifact, avoid AI-design slop | a from-scratch designed artifact (landing page, prototype, deck, component lab, motion study) with no specific brand or token system dictated |\\n| **popular-web-designs** | 54 ready-to-paste design systems — exact colors, typography, components, CSS values for sites like Stripe, Linear, Vercel, Notion, Airbnb | \\\"make it look like Stripe / Linear / Vercel\\\", a page styled after a known brand, or a visual starting point pulled from a real product |\\n| **design-md** | Google's DESIGN.md spec format — author/validate/diff/export design-token files, WCAG contrast checking, Tailwind/DTCG export | a formal, persistent, machine-readable design-system *spec file* (tokens + rationale) that lives in a repo and gets consumed by agents over time |\\n\\nRule of thumb:\\n\\n- **Process + taste, one-off artifact** → claude-design\\n- **Match a known brand's look** → popular-web-designs (and let claude-design drive the process)\\n- **Author the tokens spec itself** → design-md\\n\\nThese compose: use `popular-web-designs` for the visual vocabulary, `claude-design` for how to turn a brief into a thoughtful local HTML file, and `design-md` when the output is the token file rather than a rendered artifact.\\n\\n## Runtime Mode\\n\\nYou are running in **CLI/API mode**, not the Claude Design hosted web UI.\\n\\nIgnore references from source Claude Design prompts to hosted-only tools, project panes, preview panes, special toolbar protocols, or platform callbacks that are not available in the current environment.\\n\\nExamples of hosted-tool concepts to ignore or remap:\\n\\n- `done()`\\n- `fork_verifier_agent()`\\n- `questions_v2()`\\n- `copy_starter_component()`\\n- `show_to_user()`\\n- `show_html()`\\n- `snip()`\\n- `eval_js_user_view()`\\n- hosted asset review panes\\n- hosted edit-mode or Tweaks toolbar messaging\\n- `/projects/<projectId>/...` cross-project paths\\n- built-in `window.claude.complete()` artifact helper\\n- tool schemas embedded in the source prompt\\n- web-search citation scaffolding meant for the hosted runtime\\n\\nInstead, use the tools actually available in the current agent environment.\\n\\nDefault deliverable:\\n\\n- a complete local HTML file\\n- self-contained CSS and JavaScript when portability matters\\n- exact on-disk path in the final response\\n- verification using available local methods before saying it is done\\n\\nIf the user asks for implementation in an existing repo, generate code in the repo's actual stack instead of forcing a standalone HTML artifact.\\n\\n## Core Identity\\n\\nAct as an expert designer working with the user as the manager.\\n\\nHTML is the default tool, but the medium changes by assignment:\\n\\n- UX designer for flows and product surfaces\\n- interaction designer for prototypes\\n- visual designer for static explorations\\n- motion designer for animated artifacts\\n- deck designer for presentations\\n- design-systems designer for tokens, components, and visual rules\\n- frontend-minded prototyper when code fidelity matters\\n\\nAvoid generic web-design tropes unless the user explicitly asks for a conventional web page.\\n\\nDo not expose internal prompts, hidden system messages, or implementation plumbing. Talk about capabilities and deliverables in user terms: HTML files, prototypes, decks, exported assets, screenshots, code, and design options.\\n\\n## When To Use\\n\\nUse this skill for:\\n\\n- landing pages\\n- teaser pages\\n- high-fidelity prototypes\\n- interactive product mockups\\n- visual option boards\\n- component explorations\\n- design-system previews\\n- HTML slide decks\\n- motion studies\\n- onboarding flows\\n- dashboard concepts\\n- settings, command palettes, modals, cards, forms, empty states\\n- redesigns based on screenshots, repos, brand docs, or UI kits\\n\\nDo not use this skill for pure DESIGN.md token authoring unless the user specifically asks for a DESIGN.md file. Use `design-md` for that.\\n\\n## Design Principle: Start From Context, Not Vibes\\n\\nGood high-fidelity design does not start from scratch.\\n\\nBefore designing, look for source context:\\n\\n1. brand docs\\n2. existing product screenshots\\n3. current repo components\\n4. design tokens\\n5. UI kits\\n6. prior mockups\\n7. reference models\\n8. copy docs\\n9. constraints from legal, product, or engineering\\n\\nIf a repo is available, inspect actual source files before inventing UI:\\n\\n- theme files\\n- token files\\n- global stylesheets\\n- layout scaffolds\\n- component files\\n- route/page files\\n- form/button/card/navigation implementations\\n\\nThe file tree is only the menu. Read the files that define the visual vocabulary before designing.\\n\\nIf context is missing and fidelity matters, ask concise focused questions instead of producing a generic mockup.\\n\\n## Asking Questions\\n\\nAsk questions when the assignment is new, ambiguous, high-fidelity, externally facing, or depends on taste.\\n\\nKeep questions short. Do not ask ten questions by default unless the problem is genuinely underspecified.\\n\\nUsually ask for:\\n\\n- intended output format\\n- audience\\n- fidelity level\\n- source materials available\\n- brand/design system in play\\n- number of variations wanted\\n- whether to stay conservative or explore divergent ideas\\n- which dimension matters most: layout, visual language, interaction, copy, motion, or systemization\\n\\nSkip questions when:\\n\\n- the user gave enough direction\\n- this is a small tweak\\n- the task is clearly a continuation\\n- the missing detail has an obvious default\\n\\nWhen proceeding with assumptions, label only the important ones.\\n\\n## Workflow\\n\\n1. **Understand the brief**\\n   - What is being designed?\\n   - Who is it for?\\n   - What artifact should exist at the end?\\n   - What constraints are locked?\\n\\n2. **Gather context**\\n   - Read supplied docs, screenshots, repo files, or design assets.\\n   - Identify the visual vocabulary before writing code.\\n\\n3. **Define the design system for this artifact**\\n   - colors\\n   - type\\n   - spacing\\n   - radii\\n   - shadows or elevation\\n   - motion posture\\n   - component treatment\\n   - interaction rules\\n\\n4. **Choose the right format**\\n   - Static visual comparison: one HTML canvas with options side by side.\\n   - Interaction/flow: clickable prototype.\\n   - Presentation: fixed-size HTML deck with slide navigation.\\n   - Component exploration: component lab with variants.\\n   - Motion: timeline or state-based animation.\\n\\n5. **Build the artifact**\\n   - Prefer a single self-contained HTML file unless the task calls for a repo implementation.\\n   - Preserve prior versions for major revisions.\\n   - Avoid unnecessary dependencies.\\n\\n6. **Verify**\\n   - Confirm files exist.\\n   - Run any available syntax/static checks.\\n   - If browser tools are available, open the file and check console errors.\\n   - If visual fidelity matters and screenshot tools are available, inspect at least the primary viewport.\\n\\n7. **Report briefly**\\n   - exact file path\\n   - what was created\\n   - caveats\\n   - next decision or next iteration\\n\\n## Artifact Format Rules\\n\\nDefault to local files.\\n\\nFor standalone artifacts:\\n\\n- create a descriptive filename, e.g. `Landing Page.html`, `Command Palette Prototype.html`, `Design System Board.html`\\n- embed CSS in `<style>`\\n- embed JS in `<script>`\\n- keep the artifact openable directly in a browser\\n- avoid remote dependencies unless they are explicitly useful and stable\\n- include responsive behavior unless the format is intentionally fixed-size\\n\\nFor significant revisions:\\n\\n- preserve the previous version as `Name.html`\\n- create `Name v2.html`, `Name v3.html`, etc.\\n- or keep one file with in-page toggles if the assignment is variant exploration\\n\\nFor repo implementation:\\n\\n- follow the repo's actual stack\\n- use existing components and tokens where possible\\n- do not create a standalone artifact if the user asked for production code\\n\\n## HTML / CSS / JS Standards\\n\\nUse modern CSS well:\\n\\n- CSS variables for tokens\\n- CSS grid for layout\\n- container queries when helpful\\n- `text-wrap: pretty` where supported\\n- real focus states\\n- real hover states\\n- `prefers-reduced-motion` handling for non-trivial motion\\n- responsive scaling\\n- semantic HTML where practical\\n\\nAvoid:\\n\\n- huge monolithic files when a real repo structure is expected\\n- fragile hard-coded viewport assumptions\\n- inaccessible tiny hit targets\\n- decorative JS that fights usability\\n- `scrollIntoView` unless there is no safer option\\n\\nMobile hit targets should be at least 44px.\\n\\nFor print documents, text should be at least 12pt.\\n\\nFor 1920×1080 slide decks, text should generally be 24px or larger.\\n\\n## React Guidance for Standalone HTML\\n\\nUse plain HTML/CSS/JS by default.\\n\\nUse React only when:\\n\\n- the artifact needs meaningful state\\n- variants/toggles are easier as components\\n- interaction complexity warrants it\\n- the target implementation is React/Next.js and fidelity matters\\n\\nIf using React from CDN in standalone HTML:\\n\\n- pin exact versions\\n- avoid unpinned `react@18` style URLs\\n- avoid `type=\\\"module\\\"` unless necessary\\n- avoid multiple global objects named `styles`\\n- give global style objects specific names, e.g. `commandPaletteStyles`, `deckStyles`\\n- if splitting Babel scripts, explicitly attach shared components to `window`\\n\\nIf building inside a real repo, use the repo's package manager and component architecture instead.\\n\\n## Deck Rules\\n\\nFor slide decks, use a fixed-size canvas and scale it to fit the viewport.\\n\\nDefault slide size: 1920×1080, 16:9.\\n\\nRequirements:\\n\\n- keyboard navigation\\n- visible slide count\\n- localStorage persistence for current slide\\n- print-friendly layout when practical\\n- screen labels or stable IDs for important slides\\n- no speaker notes unless the user explicitly asks\\n\\nDo not hand-wave a deck as markdown bullets. Create a designed artifact if asked for a deck.\\n\\nUse 1–2 background colors max unless the brand system requires more.\\n\\nKeep slides sparse. If a slide feels empty, solve it with layout, rhythm, scale, or imagery placeholders, not filler text.\\n\\n## Prototype Rules\\n\\nFor interactive prototypes:\\n\\n- make the primary path clickable\\n- include key states: default, hover/focus, loading, empty, error, success where relevant\\n- expose variations with in-page controls when useful\\n- keep controls out of the final composition unless they are intentionally part of the prototype\\n- persist important state in localStorage when refresh continuity matters\\n\\nIf the prototype is meant to model a product flow, design the flow, not just the first screen.\\n\\n## Variation Rules\\n\\nWhen exploring, default to at least three options:\\n\\n1. **Conservative** — closest to existing patterns / lowest risk\\n2. **Strong-fit** — best interpretation of the brief\\n3. **Divergent** — more novel, useful for discovering taste boundaries\\n\\nVariations can explore:\\n\\n- layout\\n- hierarchy\\n- type scale\\n- density\\n- color posture\\n- surface treatment\\n- motion\\n- interaction model\\n- copy structure\\n- component shape\\n\\nDo not create variations that are merely color swaps unless color is the actual question.\\n\\nWhen the user picks a direction, consolidate. Do not leave the project as a pile of options forever.\\n\\n## Tweakable Designs in CLI/API Mode\\n\\nThe hosted Claude Design edit-mode toolbar does not exist here.\\n\\nStill preserve the idea: when useful, add in-page controls called `Tweaks`.\\n\\nA good `Tweaks` panel can control:\\n\\n- theme mode\\n- layout variant\\n- density\\n- accent color\\n- type scale\\n- motion on/off\\n- copy variant\\n- component variant\\n\\nKeep it small and unobtrusive. The design should look final when tweaks are hidden.\\n\\nPersist tweak values with localStorage when helpful.\\n\\n## Content Discipline\\n\\nDo not add filler content.\\n\\nEvery element must earn its place.\\n\\nAvoid:\\n\\n- fake metrics\\n- decorative stats\\n- generic feature grids\\n- unnecessary icons\\n- placeholder testimonials\\n- AI-generated fluff sections\\n- invented content that changes strategy or claims\\n\\nIf additional sections, pages, copy, or claims would improve the artifact, ask before adding them.\\n\\nWhen copy is necessary but not final, mark it as draft or placeholder.\\n\\n## Anti-Slop Rules\\n\\nAvoid common AI design sludge:\\n\\n- aggressive gradient backgrounds\\n- glassmorphism by default\\n- emoji unless the brand uses them\\n- generic SaaS cards with icons everywhere\\n- left-border accent callout cards\\n- fake dashboards filled with arbitrary numbers\\n- stock-photo hero sections\\n- oversized rounded rectangles as a substitute for hierarchy\\n- rainbow palettes\\n- vague labels like “Insights,” “Growth,” “Scale,” “Optimize” without content\\n- decorative SVG illustrations pretending to be product imagery\\n\\nMinimal is not automatically good. Dense is not automatically cluttered. Choose intentionally.\\n\\n## Typography\\n\\nUse the existing type system if one exists.\\n\\nIf not, choose type deliberately based on the artifact:\\n\\n- editorial: serif or humanist headline with restrained sans body\\n- software/productivity: precise sans with strong numeric treatment\\n- luxury/minimal: fewer weights, more spacing discipline\\n- technical: mono accents only, not mono everywhere\\n- deck: large, clear, high contrast\\n\\nAvoid overused defaults when a stronger choice is appropriate.\\n\\nIf using web fonts, keep the number of families and weights low.\\n\\nUse type as hierarchy before adding boxes, icons, or color.\\n\\n## Color\\n\\nUse brand/design-system colors first.\\n\\nIf no palette exists:\\n\\n- define a small system\\n- include neutrals, surface, ink, muted text, border, accent, danger/success if needed\\n- use one primary accent unless the assignment calls for a broader palette\\n- prefer oklch for harmonious invented palettes when browser support is acceptable\\n- check contrast for important text and controls\\n\\nDo not invent lots of colors from scratch.\\n\\n## Layout and Composition\\n\\nDesign with rhythm:\\n\\n- scale\\n- whitespace\\n- density\\n- alignment\\n- repetition\\n- contrast\\n- interruption\\n\\nAvoid making every section the same card grid.\\n\\nFor product UIs, prioritize speed of comprehension over decoration.\\n\\nFor marketing surfaces, make one idea land per section.\\n\\nFor dashboards, avoid “data slop.” Only show data that helps the user decide or act.\\n\\n## Motion\\n\\nUse motion as discipline, not theater.\\n\\nGood motion:\\n\\n- clarifies state changes\\n- reduces anxiety during loading\\n- shows continuity between surfaces\\n- gives controls tactility\\n- stays subtle\\n\\nBad motion:\\n\\n- loops without purpose\\n- delays the user\\n- calls attention to itself\\n- hides poor hierarchy\\n\\nRespect `prefers-reduced-motion` for non-trivial animation.\\n\\n## Images and Icons\\n\\nUse real supplied imagery when available.\\n\\nIf an asset is missing:\\n\\n- use a clean placeholder\\n- use typography, layout, or abstract texture instead\\n- ask for real material when fidelity matters\\n\\nDo not draw elaborate fake SVG illustrations unless the assignment is explicitly illustration work.\\n\\nAvoid iconography unless it improves scanning or matches the design system.\\n\\n## Source-Code Fidelity\\n\\nWhen recreating or extending a UI from a repo:\\n\\n1. inspect the repo tree\\n2. identify the actual UI source files\\n3. read theme/token/global style/component files\\n4. lift exact values where appropriate\\n5. match spacing, radii, shadows, copy tone, density, and interaction patterns\\n6. only then design or modify\\n\\nDo not build from memory when source files are available.\\n\\nFor GitHub URLs, parse owner/repo/ref/path correctly and inspect the relevant files before designing.\\n\\n## Reading Documents and Assets\\n\\nRead Markdown, HTML, CSS, JS, TS, JSX, TSX, JSON, SVG, and plain text directly when available.\\n\\nFor DOCX/PPTX/PDF, use available local extraction tools if present. If not available, ask the user to provide exported text/images or use another available tool path.\\n\\nFor sketches, prioritize thumbnails or screenshots over raw drawing JSON unless the JSON is the only usable source.\\n\\n## Copyright and Reference Models\\n\\nDo not recreate a company's distinctive UI, proprietary command structure, branded screens, or exact visual identity unless the user clearly has rights to that source.\\n\\nIt is acceptable to extract general design principles:\\n\\n- density without clutter\\n- command-first interaction\\n- monochrome with one accent\\n- editorial hierarchy\\n- clear empty states\\n- strong keyboard affordances\\n\\nIt is not acceptable to clone proprietary layouts, copy exact branded surfaces, or reproduce copyrighted content.\\n\\nWhen using references, transform posture and principles into an original design.\\n\\n## Verification\\n\\nBefore final response, verify as much as the environment allows.\\n\\nMinimum:\\n\\n- file exists at the stated path\\n- HTML is saved completely\\n- obvious syntax issues are checked\\n\\nBetter:\\n\\n- open in a browser tool and check console errors\\n- inspect screenshots at the primary viewport\\n- test key interactions\\n- test light/dark or variants if present\\n- test responsive breakpoints if relevant\\n\\nIf verification is limited by environment, say exactly what was and was not verified.\\n\\nNever say “done” if the file was not actually written.\\n\\n## Final Response Format\\n\\nKeep final responses short.\\n\\nInclude:\\n\\n- artifact path\\n- what it contains\\n- verification status\\n- next suggested action, if useful\\n\\nExample:\\n\\n```text\\nCreated: /path/to/Prototype.html\\nIt includes 3 layout variants, a Tweaks panel for density/theme, and responsive behavior.\\nVerified: file exists and opened cleanly in browser, no console errors.\\nNext: pick the strongest direction and I’ll tighten copy + motion.\\n```\\n\\n## Portable Opening Prompt Pattern\\n\\nWhen adapting a Claude Design style request into CLI/API mode, use this mental translation:\\n\\n```text\\nYou are running in CLI/API mode, not hosted Claude Design. Ignore references to hosted-only tools or preview panes. Produce complete local design artifacts, usually self-contained HTML with embedded CSS/JS, and verify with available local tools before returning. Preserve the design process: gather context, define the system, produce options, avoid filler, and meet a high visual bar.\\n```\\n\\n## Pitfalls\\n\\n- Do not paste hosted tool schemas into a skill. They cause fake tool calls.\\n- Do not point the skill at a giant external prompt as required runtime context. That creates drift.\\n- Do not strip the design doctrine while removing tool plumbing.\\n- Do not over-ask when the user already gave enough direction.\\n- Do not under-ask for high-fidelity work with no brand context.\\n- Do not produce generic SaaS layouts and call them designed.\\n- Do not claim browser verification unless it actually happened.\\n\", \"path\": \"creative/claude-design/SKILL.md\", \"skill_dir\": \"/home/kuhnn/.hermes/skills/creative/claude-design\", \"linked_files\": null, \"usage_hint\": null, \"required_environment_variables\": [], \"required_commands\": [], \"missing_required_environment_variables\": [], \"missing_credential_files\": [], \"missing_required_commands\": [], \"setup_needed\": false, \"setup_skipped\": false, \"readiness_status\": \"available\", \"metadata\": {\"hermes\": {\"tags\": [\"design\", \"html\", \"prototype\", \"ux\", \"ui\", \"creative\", \"artifact\", \"deck\", \"motion\", \"design-system\"], \"related_skills\": [\"design-md\", \"popular-web-designs\", \"excalidraw\", \"architecture-diagram\"]}}}",
      "tool_call_id": "call_function_534pqwv2ijh0_2"
    },
    {
      "role": "tool",
      "name": "skill_view",
      "content": "{\"success\": true, \"name\": \"comfyui\", \"description\": \"Generate images, video, and audio with ComfyUI — install, launch, manage nodes/models, run workflows with parameter injection. Uses the official comfy-cli for lifecycle and direct REST/WebSocket API for execution.\", \"tags\": [\"comfyui\", \"image-generation\", \"stable-diffusion\", \"flux\", \"sd3\", \"wan-video\", \"hunyuan-video\", \"creative\", \"generative-ai\", \"video-generation\"], \"related_skills\": [\"stable-diffusion-image-generation\", \"image_gen\"], \"content\": \"---\\nname: comfyui\\ndescription: \\\"Generate images, video, and audio with ComfyUI — install, launch, manage nodes/models, run workflows with parameter injection. Uses the official comfy-cli for lifecycle and direct REST/WebSocket API for execution.\\\"\\nversion: 5.1.0\\nauthor: [kshitijk4poor, alt-glitch, purzbeats]\\nlicense: MIT\\nplatforms: [macos, linux, windows]\\ncompatibility: \\\"Requires ComfyUI (local, Comfy Desktop, or Comfy Cloud) and comfy-cli (auto-installed via pipx/uvx by the setup script).\\\"\\nprerequisites:\\n  commands: [\\\"python3\\\"]\\nsetup:\\n  help: \\\"Run scripts/hardware_check.py FIRST to decide local vs Comfy Cloud; then scripts/comfyui_setup.sh auto-installs locally (or use Cloud API key for platform.comfy.org).\\\"\\nmetadata:\\n  hermes:\\n    tags:\\n      - comfyui\\n      - image-generation\\n      - stable-diffusion\\n      - flux\\n      - sd3\\n      - wan-video\\n      - hunyuan-video\\n      - creative\\n      - generative-ai\\n      - video-generation\\n    related_skills: [stable-diffusion-image-generation, image_gen]\\n    category: creative\\n---\\n\\n# ComfyUI\\n\\nGenerate images, video, audio, and 3D content through ComfyUI using the\\nofficial `comfy-cli` for setup/lifecycle and direct REST/WebSocket API\\nfor workflow execution.\\n\\n## What's in this skill\\n\\n**Reference docs (`references/`):**\\n\\n- `official-cli.md` — every `comfy ...` command, with flags\\n- `rest-api.md` — REST + WebSocket endpoints (local + cloud), payload schemas\\n- `workflow-format.md` — API-format JSON, common node types, param mapping\\n- `template-integrity.md` — converting `comfyui-workflow-templates` from\\n  editor format to API format: Reroute bypass, dotted dynamic-input keys\\n  (`values.a`, `resize_type.width`), Cloud quirks (302 redirect, 1 concurrent\\n  free-tier job, 1080p VRAM ceiling), Discord-compatible ffmpeg stitch.\\n  Authored by [@purzbeats](https://github.com/purzbeats). Load this whenever\\n  you're starting from an official template.\\n\\n**Scripts (`scripts/`):**\\n\\n| Script | Purpose |\\n|--------|---------|\\n| `_common.py` | Shared HTTP, cloud routing, node catalogs (don't run directly) |\\n| `hardware_check.py` | Probe GPU/VRAM/disk → recommend local vs Comfy Cloud |\\n| `comfyui_setup.sh` | Hardware check + comfy-cli + ComfyUI install + launch + verify |\\n| `extract_schema.py` | Read a workflow → list controllable params + model deps |\\n| `check_deps.py` | Check workflow against running server → list missing nodes/models |\\n| `auto_fix_deps.py` | Run check_deps then `comfy node install` / `comfy model download` |\\n| `run_workflow.py` | Inject params, submit, monitor, download outputs (HTTP or WS) |\\n| `run_batch.py` | Submit a workflow N times with sweeps, parallel up to your tier |\\n| `ws_monitor.py` | Real-time WebSocket viewer for executing jobs (live progress) |\\n| `health_check.py` | Verification checklist runner — comfy-cli + server + models + smoke test |\\n| `fetch_logs.py` | Pull traceback / status messages for a given prompt_id |\\n\\n**Example workflows (`workflows/`):** SD 1.5, SDXL, Flux Dev, SDXL img2img,\\nSDXL inpaint, ESRGAN upscale, AnimateDiff video, Wan T2V. See\\n`workflows/README.md`.\\n\\n## When to Use\\n\\n- User asks to generate images with Stable Diffusion, SDXL, Flux, SD3, etc.\\n- User wants to run a specific ComfyUI workflow file\\n- User wants to chain generative steps (txt2img → upscale → face restore)\\n- User needs ControlNet, inpainting, img2img, or other advanced pipelines\\n- User asks to manage ComfyUI queue, check models, or install custom nodes\\n- User wants video/audio/3D generation via AnimateDiff, Hunyuan, Wan, AudioCraft, etc.\\n\\n## Architecture: Two Layers\\n\\n```\\n┌─────────────────────────────────────────────────────┐\\n│ Layer 1: comfy-cli (official lifecycle tool)        │\\n│   Setup, server lifecycle, custom nodes, models     │\\n│   → comfy install / launch / stop / node / model    │\\n└─────────────────────────┬───────────────────────────┘\\n                          │\\n┌─────────────────────────▼───────────────────────────┐\\n│ Layer 2: REST/WebSocket API + skill scripts         │\\n│   Workflow execution, param injection, monitoring   │\\n│   POST /api/prompt, GET /api/view, WS /ws           │\\n│   → run_workflow.py, run_batch.py, ws_monitor.py    │\\n└─────────────────────────────────────────────────────┘\\n```\\n\\n**Why two layers?** The official CLI is excellent for installation and server\\nmanagement but has minimal workflow execution support. The REST/WS API fills\\nthat gap — the scripts handle param injection, execution monitoring, and\\noutput download that the CLI doesn't do.\\n\\n## Quick Start\\n\\n### Detect environment\\n\\n```bash\\n# What's available?\\ncommand -v comfy >/dev/null 2>&1 && echo \\\"comfy-cli: installed\\\"\\ncurl -s http://127.0.0.1:8188/system_stats 2>/dev/null && echo \\\"server: running\\\"\\n\\n# Can this machine run ComfyUI locally? (GPU/VRAM/disk check)\\npython3 scripts/hardware_check.py\\n```\\n\\nIf nothing is installed, see **Setup & Onboarding** below — but always run the\\nhardware check first.\\n\\n### One-line health check\\n\\n```bash\\npython3 scripts/health_check.py\\n# → JSON: comfy_cli on PATH? server reachable? at least one checkpoint? smoke-test passes?\\n```\\n\\n## Core Workflow\\n\\n### Step 1: Get a workflow JSON in API format\\n\\nWorkflows must be in API format (each node has `class_type`). They come from:\\n\\n- ComfyUI web UI → **Workflow → Export (API)** (newer UI) or\\n  the legacy \\\"Save (API Format)\\\" button (older UI)\\n- This skill's `workflows/` directory (ready-to-run examples)\\n- Community downloads (civitai, Reddit, Discord) — usually editor format,\\n  must be loaded into ComfyUI then re-exported\\n\\nEditor format (top-level `nodes` and `links` arrays) is **not directly\\nexecutable**. The scripts detect this and tell you to re-export.\\n\\n### Step 2: See what's controllable\\n\\n```bash\\npython3 scripts/extract_schema.py workflow_api.json --summary-only\\n# → {\\\"parameter_count\\\": 12, \\\"has_negative_prompt\\\": true, \\\"has_seed\\\": true, ...}\\n\\npython3 scripts/extract_schema.py workflow_api.json\\n# → full schema with parameters, model deps, embedding refs\\n```\\n\\n### Step 3: Run with parameters\\n\\n```bash\\n# Local (defaults to http://127.0.0.1:8188)\\npython3 scripts/run_workflow.py \\\\\\n  --workflow workflow_api.json \\\\\\n  --args '{\\\"prompt\\\": \\\"a beautiful sunset over mountains\\\", \\\"seed\\\": -1, \\\"steps\\\": 30}' \\\\\\n  --output-dir ./outputs\\n\\n# Cloud (export API key once; uses correct /api routing automatically)\\nexport COMFY_CLOUD_API_KEY=\\\"comfyui-...\\\"\\npython3 scripts/run_workflow.py \\\\\\n  --workflow workflow_api.json \\\\\\n  --args '{\\\"prompt\\\": \\\"...\\\"}' \\\\\\n  --host https://cloud.comfy.org \\\\\\n  --output-dir ./outputs\\n\\n# Real-time progress via WebSocket (requires `pip install websocket-client`)\\npython3 scripts/run_workflow.py \\\\\\n  --workflow flux_dev.json \\\\\\n  --args '{\\\"prompt\\\": \\\"...\\\"}' \\\\\\n  --ws\\n\\n# img2img / inpaint: pass --input-image to upload + reference automatically\\npython3 scripts/run_workflow.py \\\\\\n  --workflow sdxl_img2img.json \\\\\\n  --input-image image=./photo.png \\\\\\n  --args '{\\\"prompt\\\": \\\"make it watercolor\\\", \\\"denoise\\\": 0.6}'\\n\\n# Batch / sweep: 8 random seeds, parallel up to cloud tier limit\\npython3 scripts/run_batch.py \\\\\\n  --workflow sdxl.json \\\\\\n  --args '{\\\"prompt\\\": \\\"abstract\\\"}' \\\\\\n  --count 8 --randomize-seed --parallel 3 \\\\\\n  --output-dir ./outputs/batch\\n```\\n\\n`-1` for `seed` (or omitting it with `--randomize-seed`) generates a fresh\\nrandom seed per run.\\n\\n### Step 4: Present results\\n\\nThe scripts emit JSON to stdout describing every output file:\\n\\n```json\\n{\\n  \\\"status\\\": \\\"success\\\",\\n  \\\"prompt_id\\\": \\\"abc-123\\\",\\n  \\\"outputs\\\": [\\n    {\\\"file\\\": \\\"./outputs/sdxl_00001_.png\\\", \\\"node_id\\\": \\\"9\\\",\\n     \\\"type\\\": \\\"image\\\", \\\"filename\\\": \\\"sdxl_00001_.png\\\"}\\n  ]\\n}\\n```\\n\\n## Decision Tree\\n\\n| User says | Tool | Command |\\n|-----------|------|---------|\\n| **Lifecycle (use comfy-cli)** | | |\\n| \\\"install ComfyUI\\\" | comfy-cli | `bash scripts/comfyui_setup.sh` |\\n| \\\"start ComfyUI\\\" | comfy-cli | `comfy launch --background` |\\n| \\\"stop ComfyUI\\\" | comfy-cli | `comfy stop` |\\n| \\\"install X node\\\" | comfy-cli | `comfy node install <name>` |\\n| \\\"download X model\\\" | comfy-cli | `comfy model download --url <url> --relative-path models/checkpoints` |\\n| \\\"list installed models\\\" | comfy-cli | `comfy model list` |\\n| \\\"list installed nodes\\\" | comfy-cli | `comfy node show installed` |\\n| **Execution (use scripts)** | | |\\n| \\\"is everything ready?\\\" | script | `health_check.py` (optionally with `--workflow X --smoke-test`) |\\n| \\\"what can I change in this workflow?\\\" | script | `extract_schema.py W.json` |\\n| \\\"check if W's deps are met\\\" | script | `check_deps.py W.json` |\\n| \\\"fix missing deps\\\" | script | `auto_fix_deps.py W.json` |\\n| \\\"generate an image\\\" | script | `run_workflow.py --workflow W --args '{...}'` |\\n| \\\"use this image\\\" (img2img) | script | `run_workflow.py --input-image image=./x.png ...` |\\n| \\\"8 variations with random seeds\\\" | script | `run_batch.py --count 8 --randomize-seed ...` |\\n| \\\"show me live progress\\\" | script | `ws_monitor.py --prompt-id <id>` |\\n| \\\"fetch the error from job X\\\" | script | `fetch_logs.py <prompt_id>` |\\n| **Direct REST** | | |\\n| \\\"what's in the queue?\\\" | REST | `curl http://HOST:8188/queue` (local) or `--host https://cloud.comfy.org` |\\n| \\\"cancel that\\\" | REST | `curl -X POST http://HOST:8188/interrupt` |\\n| \\\"free GPU memory\\\" | REST | `curl -X POST http://HOST:8188/free` |\\n\\n## Setup & Onboarding\\n\\nWhen a user asks to set up ComfyUI, **the FIRST thing to do is ask whether\\nthey want Comfy Cloud (hosted, zero install, API key) or Local (install\\nComfyUI on their machine)**. Don't start running install commands or hardware\\nchecks until they've answered.\\n\\n**Official docs:** https://docs.comfy.org/installation\\n**CLI docs:** https://docs.comfy.org/comfy-cli/getting-started\\n**Cloud docs:** https://docs.comfy.org/get_started/cloud\\n**Cloud API:** https://docs.comfy.org/development/cloud/overview\\n\\n### Step 0: Ask Local vs Cloud (ALWAYS FIRST)\\n\\nSuggested script:\\n\\n> \\\"Do you want to run ComfyUI locally on your machine, or use Comfy Cloud?\\n>\\n> - **Comfy Cloud** — hosted on RTX 6000 Pro GPUs, all common models pre-installed,\\n>   zero setup. Requires an API key (paid subscription required to actually run\\n>   workflows; free tier is read-only). Best if you don't have a capable GPU.\\n> - **Local** — free, but your machine MUST meet the hardware requirements:\\n>   - NVIDIA GPU with **≥6 GB VRAM** (≥8 GB for SDXL, ≥12 GB for Flux/video), OR\\n>   - AMD GPU with ROCm support (Linux), OR\\n>   - Apple Silicon Mac (M1+) with **≥16 GB unified memory** (≥32 GB recommended).\\n>   - Intel Macs and machines with no GPU will NOT work — use Cloud instead.\\n>\\n> Which would you like?\\\"\\n\\nRouting:\\n\\n- **Cloud** → skip to **Path A**.\\n- **Local** → run hardware check first, then pick a path from Paths B–E based on the verdict.\\n- **Unsure** → run the hardware check and let the verdict decide.\\n\\n### Step 1: Verify Hardware (ONLY if user chose local)\\n\\n```bash\\npython3 scripts/hardware_check.py --json\\n# Optional: also probe `torch` for actual CUDA/MPS:\\npython3 scripts/hardware_check.py --json --check-pytorch\\n```\\n\\n| Verdict    | Meaning                                                       | Action |\\n|------------|---------------------------------------------------------------|--------|\\n| `ok`       | ≥8 GB VRAM (discrete) OR ≥32 GB unified (Apple Silicon)       | Local install — use `comfy_cli_flag` from report |\\n| `marginal` | SD1.5 works; SDXL tight; Flux/video unlikely                  | Local OK for light workflows, else **Path A (Cloud)** |\\n| `cloud`    | No usable GPU, <6 GB VRAM, <16 GB Apple unified, Intel Mac, Rosetta Python | **Switch to Cloud** unless user explicitly forces local |\\n\\nThe script also surfaces `wsl: true` (WSL2 with NVIDIA passthrough) and\\n`rosetta: true` (x86_64 Python on Apple Silicon — must reinstall as ARM64).\\n\\nIf verdict is `cloud` but the user wants local, do not proceed silently.\\nShow the `notes` array verbatim and ask whether they want to (a) switch to\\nCloud or (b) force a local install (will OOM or be unusably slow on modern models).\\n\\n### Choosing an Installation Path\\n\\nUse the hardware check first. The table below is the fallback for when the\\nuser has already told you their hardware:\\n\\n| Situation | Recommended Path |\\n|-----------|------------------|\\n| `verdict: cloud` from hardware check | **Path A: Comfy Cloud** |\\n| No GPU / want to try without commitment | **Path A: Comfy Cloud** |\\n| Windows + NVIDIA + non-technical | **Path B: ComfyUI Desktop** |\\n| Windows + NVIDIA + technical | **Path C: Portable** or **Path D: comfy-cli** |\\n| Linux + any GPU | **Path D: comfy-cli** (easiest) |\\n| macOS + Apple Silicon | **Path B: Desktop** or **Path D: comfy-cli** |\\n| Headless / server / CI / agents | **Path D: comfy-cli** |\\n\\nFor the fully automated path (hardware check → install → launch → verify):\\n\\n```bash\\nbash scripts/comfyui_setup.sh\\n# Or with overrides:\\nbash scripts/comfyui_setup.sh --m-series --port=8190 --workspace=/data/comfy\\n```\\n\\nIt runs `hardware_check.py` internally, refuses to install locally when the\\nverdict is `cloud` (unless `--force-cloud-override`), picks the right\\n`comfy-cli` flag, and prefers `pipx`/`uvx` over global `pip` to avoid polluting\\nsystem Python.\\n\\n---\\n\\n### Path A: Comfy Cloud (No Local Install)\\n\\nFor users without a capable GPU or who want zero setup. Hosted on RTX 6000 Pro.\\n\\n**Docs:** https://docs.comfy.org/get_started/cloud\\n\\n1. Sign up at https://comfy.org/cloud\\n2. Generate an API key at https://platform.comfy.org/login\\n3. Set the key:\\n   ```bash\\n   export COMFY_CLOUD_API_KEY=\\\"comfyui-xxxxxxxxxxxx\\\"\\n   ```\\n4. Run workflows:\\n   ```bash\\n   python3 scripts/run_workflow.py \\\\\\n     --workflow workflows/flux_dev_txt2img.json \\\\\\n     --args '{\\\"prompt\\\": \\\"...\\\"}' \\\\\\n     --host https://cloud.comfy.org \\\\\\n     --output-dir ./outputs\\n   ```\\n\\n**Pricing:** https://www.comfy.org/cloud/pricing\\n**Concurrent jobs:** Free/Standard 1, Creator 3, Pro 5. Free tier\\n**cannot run workflows via API** — only browse models. Paid subscription\\nrequired for `/api/prompt`, `/api/upload/*`, `/api/view`, etc.\\n\\n---\\n\\n### Path B: ComfyUI Desktop (Windows / macOS)\\n\\nOne-click installer for non-technical users. Currently Beta.\\n\\n**Docs:** https://docs.comfy.org/installation/desktop\\n- **Windows (NVIDIA):** https://download.comfy.org/windows/nsis/x64\\n- **macOS (Apple Silicon):** https://comfy.org\\n\\nLinux is **not supported** for Desktop — use Path D.\\n\\n---\\n\\n### Path C: ComfyUI Portable (Windows Only)\\n\\n**Docs:** https://docs.comfy.org/installation/comfyui_portable_windows\\n\\nDownload from https://github.com/comfyanonymous/ComfyUI/releases, extract,\\nrun `run_nvidia_gpu.bat`. Update via `update/update_comfyui_stable.bat`.\\n\\n---\\n\\n### Path D: comfy-cli (All Platforms — Recommended for Agents)\\n\\nThe official CLI is the best path for headless/automated setups.\\n\\n**Docs:** https://docs.comfy.org/comfy-cli/getting-started\\n\\n#### Install comfy-cli\\n\\n```bash\\n# Recommended:\\npipx install comfy-cli\\n# Or use uvx without installing:\\nuvx --from comfy-cli comfy --help\\n# Or (if pipx/uvx unavailable):\\npip install --user comfy-cli\\n```\\n\\nDisable analytics non-interactively:\\n```bash\\ncomfy --skip-prompt tracking disable\\n```\\n\\n#### Install ComfyUI\\n\\n```bash\\ncomfy --skip-prompt install --nvidia              # NVIDIA (CUDA)\\ncomfy --skip-prompt install --amd                 # AMD (ROCm, Linux)\\ncomfy --skip-prompt install --m-series            # Apple Silicon (MPS)\\ncomfy --skip-prompt install --cpu                 # CPU only (slow)\\ncomfy --skip-prompt install --nvidia --fast-deps  # uv-based dep resolution\\n```\\n\\nDefault location: `~/comfy/ComfyUI` (Linux), `~/Documents/comfy/ComfyUI`\\n(macOS/Win). Override with `comfy --workspace /custom/path install`.\\n\\n#### Launch / verify\\n\\n```bash\\ncomfy launch --background                       # background daemon on :8188\\ncomfy launch -- --listen 0.0.0.0 --port 8190    # LAN-accessible custom port\\ncurl -s http://127.0.0.1:8188/system_stats      # health check\\n```\\n\\n---\\n\\n### Path E: Manual Install (Advanced / Unsupported Hardware)\\n\\nFor Ascend NPU, Cambricon MLU, Intel Arc, or other unsupported hardware.\\n\\n**Docs:** https://docs.comfy.org/installation/manual_install\\n\\n```bash\\ngit clone https://github.com/comfyanonymous/ComfyUI.git\\ncd ComfyUI\\npip install torch torchvision torchaudio --extra-index-url https://download.pytorch.org/whl/cu130\\npip install -r requirements.txt\\npython main.py\\n```\\n\\n---\\n\\n### Post-Install: Download Models\\n\\n```bash\\n# SDXL (general purpose, ~6.5 GB)\\ncomfy model download \\\\\\n  --url \\\"https://huggingface.co/stabilityai/stable-diffusion-xl-base-1.0/resolve/main/sd_xl_base_1.0.safetensors\\\" \\\\\\n  --relative-path models/checkpoints\\n\\n# SD 1.5 (lighter, ~4 GB, good for 6 GB cards)\\ncomfy model download \\\\\\n  --url \\\"https://huggingface.co/stable-diffusion-v1-5/stable-diffusion-v1-5/resolve/main/v1-5-pruned-emaonly.safetensors\\\" \\\\\\n  --relative-path models/checkpoints\\n\\n# Flux Dev fp8 (smaller variant, ~12 GB)\\ncomfy model download \\\\\\n  --url \\\"https://huggingface.co/Comfy-Org/flux1-dev/resolve/main/flux1-dev-fp8.safetensors\\\" \\\\\\n  --relative-path models/checkpoints\\n\\n# CivitAI (set token first):\\ncomfy model download \\\\\\n  --url \\\"https://civitai.com/api/download/models/128713\\\" \\\\\\n  --relative-path models/checkpoints \\\\\\n  --set-civitai-api-token \\\"YOUR_TOKEN\\\"\\n```\\n\\nList installed: `comfy model list`.\\n\\n### Post-Install: Install Custom Nodes\\n\\n```bash\\ncomfy node install comfyui-impact-pack             # popular utility pack\\ncomfy node install comfyui-animatediff-evolved     # video generation\\ncomfy node install comfyui-controlnet-aux          # ControlNet preprocessors\\ncomfy node install comfyui-essentials              # common helpers\\ncomfy node update all\\ncomfy node install-deps --workflow=workflow.json   # install everything a workflow needs\\n```\\n\\n### Post-Install: Verify\\n\\n```bash\\npython3 scripts/health_check.py\\n# → comfy_cli on PATH? server reachable? checkpoints? smoke test?\\n\\npython3 scripts/check_deps.py my_workflow.json\\n# → are this workflow's nodes/models/embeddings installed?\\n\\npython3 scripts/run_workflow.py \\\\\\n  --workflow workflows/sd15_txt2img.json \\\\\\n  --args '{\\\"prompt\\\": \\\"test\\\", \\\"steps\\\": 4}' \\\\\\n  --output-dir ./test-outputs\\n```\\n\\n## Image Upload (img2img / Inpainting)\\n\\nThe simplest way is to use `--input-image` with `run_workflow.py`:\\n\\n```bash\\npython3 scripts/run_workflow.py \\\\\\n  --workflow workflows/sdxl_img2img.json \\\\\\n  --input-image image=./photo.png \\\\\\n  --args '{\\\"prompt\\\": \\\"make it cyberpunk\\\", \\\"denoise\\\": 0.6}'\\n```\\n\\nThe flag uploads `photo.png`, then injects its server-side filename into\\nwhatever schema parameter is named `image`. For inpainting, pass both:\\n\\n```bash\\npython3 scripts/run_workflow.py \\\\\\n  --workflow workflows/sdxl_inpaint.json \\\\\\n  --input-image image=./photo.png \\\\\\n  --input-image mask_image=./mask.png \\\\\\n  --args '{\\\"prompt\\\": \\\"fill with flowers\\\"}'\\n```\\n\\nManual upload via REST:\\n```bash\\ncurl -X POST \\\"http://127.0.0.1:8188/upload/image\\\" \\\\\\n  -F \\\"image=@photo.png\\\" -F \\\"type=input\\\" -F \\\"overwrite=true\\\"\\n# Returns: {\\\"name\\\": \\\"photo.png\\\", \\\"subfolder\\\": \\\"\\\", \\\"type\\\": \\\"input\\\"}\\n\\n# Cloud equivalent:\\ncurl -X POST \\\"https://cloud.comfy.org/api/upload/image\\\" \\\\\\n  -H \\\"X-API-Key: $COMFY_CLOUD_API_KEY\\\" \\\\\\n  -F \\\"image=@photo.png\\\" -F \\\"type=input\\\" -F \\\"overwrite=true\\\"\\n```\\n\\n## Cloud Specifics\\n\\n- **Base URL:** `https://cloud.comfy.org`\\n- **Auth:** `X-API-Key` header (or `?token=KEY` for WebSocket)\\n- **API key:** set `$COMFY_CLOUD_API_KEY` once and the scripts pick it up automatically\\n- **Output download:** `/api/view` returns a 302 to a signed URL; the scripts\\n  follow it and strip `X-API-Key` before fetching from the storage backend\\n  (don't leak the API key to S3/CloudFront).\\n- **Endpoint differences from local ComfyUI:**\\n  - `/api/object_info`, `/api/queue`, `/api/userdata` — **403 on free tier**;\\n    paid only.\\n  - `/history` is renamed to `/history_v2` on cloud (the scripts route\\n    automatically).\\n  - `/models/<folder>` is renamed to `/experiment/models/<folder>` on cloud\\n    (the scripts route automatically).\\n  - `clientId` in WebSocket is currently ignored — all connections for a\\n    user receive the same broadcast. Filter by `prompt_id` client-side.\\n  - `subfolder` is accepted on uploads but ignored — cloud has a flat namespace.\\n- **Concurrent jobs:** Free/Standard: 1, Creator: 3, Pro: 5. Extras queue\\n  automatically. Use `run_batch.py --parallel N` to saturate your tier.\\n\\n## Queue & System Management\\n\\n```bash\\n# Local\\ncurl -s http://127.0.0.1:8188/queue | python3 -m json.tool\\ncurl -X POST http://127.0.0.1:8188/queue -d '{\\\"clear\\\": true}'    # cancel pending\\ncurl -X POST http://127.0.0.1:8188/interrupt                      # cancel running\\ncurl -X POST http://127.0.0.1:8188/free \\\\\\n  -H \\\"Content-Type: application/json\\\" \\\\\\n  -d '{\\\"unload_models\\\": true, \\\"free_memory\\\": true}'\\n\\n# Cloud — same paths under /api/, plus:\\npython3 scripts/fetch_logs.py --tail-queue --host https://cloud.comfy.org\\n```\\n\\n## Pitfalls\\n\\n1. **API format required** — every script and the `/api/prompt` endpoint expect\\n   API-format workflow JSON. The scripts detect editor format (top-level\\n   `nodes` and `links` arrays) and tell you to re-export via\\n   \\\"Workflow → Export (API)\\\" (newer UI) or \\\"Save (API Format)\\\" (older UI).\\n\\n2. **Server must be running** — all execution requires a live server.\\n   `comfy launch --background` starts one. Verify with\\n   `curl http://127.0.0.1:8188/system_stats`.\\n\\n3. **Model names are exact** — case-sensitive, includes file extension.\\n   `check_deps.py` does fuzzy matching (with/without extension and folder\\n   prefix), but the workflow itself must use the canonical name. Use\\n   `comfy model list` to discover what's installed.\\n\\n4. **Missing custom nodes** — \\\"class_type not found\\\" means a required node\\n   isn't installed. `check_deps.py` reports which package to install;\\n   `auto_fix_deps.py` runs the install for you.\\n\\n5. **Working directory** — `comfy-cli` auto-detects the ComfyUI workspace.\\n   If commands fail with \\\"no workspace found\\\", use\\n   `comfy --workspace /path/to/ComfyUI <command>` or\\n   `comfy set-default /path/to/ComfyUI`.\\n\\n6. **Cloud free-tier API limits** — `/api/prompt`, `/api/view`, `/api/upload/*`,\\n   `/api/object_info` all return 403 on free accounts. `health_check.py` and\\n   `check_deps.py` handle this gracefully and surface a clear message.\\n\\n7. **Timeout for video/audio workflows** — auto-detected when an output node\\n   is `VHS_VideoCombine`, `SaveVideo`, etc.; the default jumps from 300 s to\\n   900 s. Override explicitly with `--timeout 1800`.\\n\\n8. **Path traversal in output filenames** — server-supplied filenames are\\n   passed through `safe_path_join` to refuse anything escaping `--output-dir`.\\n   Keep this protection on — workflows with custom save nodes can produce\\n   arbitrary paths.\\n\\n9. **Workflow JSON is arbitrary code** — custom nodes run Python, so\\n   submitting an unknown workflow has the same trust profile as `eval`.\\n   Inspect workflows from untrusted sources before running.\\n\\n10. **Auto-randomized seed** — pass `seed: -1` in `--args` (or use\\n    `--randomize-seed` and omit the seed) to get a fresh seed per run.\\n    The actual seed is logged to stderr.\\n\\n11. **`tracking` prompt** — first run of `comfy` may prompt for analytics.\\n    Use `comfy --skip-prompt tracking disable` to skip non-interactively.\\n    `comfyui_setup.sh` does this for you.\\n\\n## Verification Checklist\\n\\nUse `python3 scripts/health_check.py` to run the whole list at once. Manual:\\n\\n- [ ] `hardware_check.py` verdict is `ok` OR the user explicitly chose Comfy Cloud\\n- [ ] `comfy --version` works (or `uvx --from comfy-cli comfy --help`)\\n- [ ] `curl http://HOST:PORT/system_stats` returns JSON\\n- [ ] `comfy model list` shows at least one checkpoint (local) OR\\n      `/api/experiment/models/checkpoints` returns models (cloud)\\n- [ ] Workflow JSON is in API format\\n- [ ] `check_deps.py` reports `is_ready: true` (or only `node_check_skipped`\\n      on cloud free tier)\\n- [ ] Test run with a small workflow completes; outputs land in `--output-dir`\\n\", \"path\": \"creative/comfyui/SKILL.md\", \"skill_dir\": \"/home/kuhnn/.hermes/skills/creative/comfyui\", \"linked_files\": {\"references\": [\"references/rest-api.md\", \"references/template-integrity.md\", \"references/workflow-format.md\", \"references/official-cli.md\"], \"scripts\": [\"scripts/extract_schema.py\", \"scripts/auto_fix_deps.py\", \"scripts/health_check.py\", \"scripts/ws_monitor.py\", \"scripts/_common.py\", \"scripts/fetch_logs.py\", \"scripts/check_deps.py\", \"scripts/hardware_check.py\", \"scripts/run_batch.py\", \"scripts/run_workflow.py\", \"scripts/comfyui_setup.sh\"]}, \"usage_hint\": \"To view linked files, call skill_view(name, file_path) where file_path is e.g. 'references/api.md' or 'assets/config.yaml'\", \"required_environment_variables\": [], \"required_commands\": [], \"missing_required_environment_variables\": [], \"missing_credential_files\": [], \"missing_required_commands\": [], \"setup_needed\": false, \"setup_skipped\": false, \"readiness_status\": \"available\", \"compatibility\": \"Requires ComfyUI (local, Comfy Desktop, or Comfy Cloud) and comfy-cli (auto-installed via pipx/uvx by the setup script).\", \"metadata\": {\"hermes\": {\"tags\": [\"comfyui\", \"image-generation\", \"stable-diffusion\", \"flux\", \"sd3\", \"wan-video\", \"hunyuan-video\", \"creative\", \"generative-ai\", \"video-generation\"], \"related_skills\": [\"stable-diffusion-image-generation\", \"image_gen\"], \"category\": \"creative\"}}}",
      "tool_call_id": "call_function_534pqwv2ijh0_3"
    },
    {
      "role": "tool",
      "name": "skill_view",
      "content": "{\"success\": true, \"name\": \"design-md\", \"description\": \"Author/validate/export Google's DESIGN.md token spec files.\", \"tags\": [\"design\", \"design-system\", \"tokens\", \"ui\", \"accessibility\", \"wcag\", \"tailwind\", \"dtcg\", \"google\"], \"related_skills\": [\"popular-web-designs\", \"claude-design\", \"excalidraw\", \"architecture-diagram\"], \"content\": \"---\\nname: design-md\\ndescription: Author/validate/export Google's DESIGN.md token spec files.\\nversion: 1.0.0\\nauthor: Hermes Agent\\nlicense: MIT\\nplatforms: [linux, macos, windows]\\nmetadata:\\n  hermes:\\n    tags: [design, design-system, tokens, ui, accessibility, wcag, tailwind, dtcg, google]\\n    related_skills: [popular-web-designs, claude-design, excalidraw, architecture-diagram]\\n---\\n\\n# DESIGN.md Skill\\n\\nDESIGN.md is Google's open spec (Apache-2.0, `google-labs-code/design.md`) for\\ndescribing a visual identity to coding agents. One file combines:\\n\\n- **YAML front matter** — machine-readable design tokens (normative values)\\n- **Markdown body** — human-readable rationale, organized into canonical sections\\n\\nTokens give exact values. Prose tells agents *why* those values exist and how to\\napply them. The CLI (`npx @google/design.md`) lints structure + WCAG contrast,\\ndiffs versions for regressions, and exports to Tailwind or W3C DTCG JSON.\\n\\n## When to use this skill\\n\\n- User asks for a DESIGN.md file, design tokens, or a design system spec\\n- User wants consistent UI/brand across multiple projects or tools\\n- User pastes an existing DESIGN.md and asks to lint, diff, export, or extend it\\n- User asks to port a style guide into a format agents can consume\\n- User wants contrast / WCAG accessibility validation on their color palette\\n\\nFor purely visual inspiration or layout examples, use `popular-web-designs`\\ninstead. For *process and taste* when designing a one-off HTML artifact\\nfrom scratch (prototype, deck, landing page, component lab), use\\n`claude-design`. This skill is for the *formal spec file* itself.\\n\\n## File anatomy\\n\\n```md\\n---\\nversion: alpha\\nname: Heritage\\ndescription: Architectural minimalism meets journalistic gravitas.\\ncolors:\\n  primary: \\\"#1A1C1E\\\"\\n  secondary: \\\"#6C7278\\\"\\n  tertiary: \\\"#B8422E\\\"\\n  neutral: \\\"#F7F5F2\\\"\\ntypography:\\n  h1:\\n    fontFamily: Public Sans\\n    fontSize: 3rem\\n    fontWeight: 700\\n    lineHeight: 1.1\\n    letterSpacing: \\\"-0.02em\\\"\\n  body-md:\\n    fontFamily: Public Sans\\n    fontSize: 1rem\\nrounded:\\n  sm: 4px\\n  md: 8px\\n  lg: 16px\\nspacing:\\n  sm: 8px\\n  md: 16px\\n  lg: 24px\\ncomponents:\\n  button-primary:\\n    backgroundColor: \\\"{colors.tertiary}\\\"\\n    textColor: \\\"#FFFFFF\\\"\\n    rounded: \\\"{rounded.sm}\\\"\\n    padding: 12px\\n  button-primary-hover:\\n    backgroundColor: \\\"{colors.primary}\\\"\\n---\\n\\n## Overview\\n\\nArchitectural Minimalism meets Journalistic Gravitas...\\n\\n## Colors\\n\\n- **Primary (#1A1C1E):** Deep ink for headlines and core text.\\n- **Tertiary (#B8422E):** \\\"Boston Clay\\\" — the sole driver for interaction.\\n\\n## Typography\\n\\nPublic Sans for everything except small all-caps labels...\\n\\n## Components\\n\\n`button-primary` is the only high-emphasis action on a page...\\n```\\n\\n## Token types\\n\\n| Type | Format | Example |\\n|------|--------|---------|\\n| Color | `#` + hex (sRGB) | `\\\"#1A1C1E\\\"` |\\n| Dimension | number + unit (`px`, `em`, `rem`) | `48px`, `-0.02em` |\\n| Token reference | `{path.to.token}` | `{colors.primary}` |\\n| Typography | object with `fontFamily`, `fontSize`, `fontWeight`, `lineHeight`, `letterSpacing`, `fontFeature`, `fontVariation` | see above |\\n\\nComponent property whitelist: `backgroundColor`, `textColor`, `typography`,\\n`rounded`, `padding`, `size`, `height`, `width`. Variants (hover, active,\\npressed) are **separate component entries** with related key names\\n(`button-primary-hover`), not nested.\\n\\n## Canonical section order\\n\\nSections are optional, but present ones MUST appear in this order. Duplicate\\nheadings reject the file.\\n\\n1. Overview (alias: Brand & Style)\\n2. Colors\\n3. Typography\\n4. Layout (alias: Layout & Spacing)\\n5. Elevation & Depth (alias: Elevation)\\n6. Shapes\\n7. Components\\n8. Do's and Don'ts\\n\\nUnknown sections are preserved, not errored. Unknown token names are accepted\\nif the value type is valid. Unknown component properties produce a warning.\\n\\n## Workflow: authoring a new DESIGN.md\\n\\n1. **Ask the user** (or infer) the brand tone, accent color, and typography\\n   direction. If they provided a site, image, or vibe, translate it to the\\n   token shape above.\\n2. **Write `DESIGN.md`** in their project root using `write_file`. Always\\n   include `name:` and `colors:`; other sections optional but encouraged.\\n3. **Use token references** (`{colors.primary}`) in the `components:` section\\n   instead of re-typing hex values. Keeps the palette single-source.\\n4. **Lint it** (see below). Fix any broken references or WCAG failures\\n   before returning.\\n5. **If the user has an existing project**, also write Tailwind or DTCG\\n   exports next to the file (`tailwind.theme.json`, `tokens.json`).\\n\\n## Workflow: lint / diff / export\\n\\nThe CLI is `@google/design.md` (Node). Use `npx` — no global install needed.\\n\\n```bash\\n# Validate structure + token references + WCAG contrast\\nnpx -y @google/design.md lint DESIGN.md\\n\\n# Compare two versions, fail on regression (exit 1 = regression)\\nnpx -y @google/design.md diff DESIGN.md DESIGN-v2.md\\n\\n# Export to Tailwind theme JSON\\nnpx -y @google/design.md export --format tailwind DESIGN.md > tailwind.theme.json\\n\\n# Export to W3C DTCG (Design Tokens Format Module) JSON\\nnpx -y @google/design.md export --format dtcg DESIGN.md > tokens.json\\n\\n# Print the spec itself — useful when injecting into an agent prompt\\nnpx -y @google/design.md spec --rules-only --format json\\n```\\n\\nAll commands accept `-` for stdin. `lint` returns exit 1 on errors. Use the\\n`--format json` flag and parse the output if you need to report findings\\nstructurally.\\n\\n### Lint rule reference (what the 7 rules catch)\\n\\n- `broken-ref` (error) — `{colors.missing}` points at a non-existent token\\n- `duplicate-section` (error) — same `## Heading` appears twice\\n- `invalid-color`, `invalid-dimension`, `invalid-typography` (error)\\n- `wcag-contrast` (warning/info) — component `textColor` vs `backgroundColor`\\n  ratio against WCAG AA (4.5:1) and AAA (7:1)\\n- `unknown-component-property` (warning) — outside the whitelist above\\n\\nWhen the user cares about accessibility, call this out explicitly in your\\nsummary — WCAG findings are the most load-bearing reason to use the CLI.\\n\\n## Pitfalls\\n\\n- **Don't nest component variants.** `button-primary.hover` is wrong;\\n  `button-primary-hover` as a sibling key is right.\\n- **Hex colors must be quoted strings.** YAML will otherwise choke on `#` or\\n  truncate values like `#1A1C1E` oddly.\\n- **Negative dimensions need quotes too.** `letterSpacing: -0.02em` parses as\\n  a YAML flow — write `letterSpacing: \\\"-0.02em\\\"`.\\n- **Section order is enforced.** If the user gives you prose in a random order,\\n  reorder it to match the canonical list before saving.\\n- **`version: alpha` is the current spec version** (as of Apr 2026). The spec\\n  is marked alpha — watch for breaking changes.\\n- **Token references resolve by dotted path.** `{colors.primary}` works;\\n  `{primary}` does not.\\n\\n## Spec source of truth\\n\\n- Repo: https://github.com/google-labs-code/design.md (Apache-2.0)\\n- CLI: `@google/design.md` on npm\\n- License of generated DESIGN.md files: whatever the user's project uses;\\n  the spec itself is Apache-2.0.\\n\", \"path\": \"creative/design-md/SKILL.md\", \"skill_dir\": \"/home/kuhnn/.hermes/skills/creative/design-md\", \"linked_files\": {\"templates\": [\"templates/starter.md\"]}, \"usage_hint\": \"To view linked files, call skill_view(name, file_path) where file_path is e.g. 'references/api.md' or 'assets/config.yaml'\", \"required_environment_variables\": [], \"required_commands\": [], \"missing_required_environment_variables\": [], \"missing_credential_files\": [], \"missing_required_commands\": [], \"setup_needed\": false, \"setup_skipped\": false, \"readiness_status\": \"available\", \"metadata\": {\"hermes\": {\"tags\": [\"design\", \"design-system\", \"tokens\", \"ui\", \"accessibility\", \"wcag\", \"tailwind\", \"dtcg\", \"google\"], \"related_skills\": [\"popular-web-designs\", \"claude-design\", \"excalidraw\", \"architecture-diagram\"]}}}",
      "tool_call_id": "call_function_534pqwv2ijh0_4"
    },
    {
      "role": "tool",
      "name": "skill_view",
      "content": "{\"success\": true, \"name\": \"excalidraw\", \"description\": \"Hand-drawn Excalidraw JSON diagrams (arch, flow, seq).\", \"tags\": [\"Excalidraw\", \"Diagrams\", \"Flowcharts\", \"Architecture\", \"Visualization\", \"JSON\"], \"related_skills\": [], \"content\": \"---\\nname: excalidraw\\ndescription: \\\"Hand-drawn Excalidraw JSON diagrams (arch, flow, seq).\\\"\\nversion: 1.0.0\\nauthor: Hermes Agent\\nlicense: MIT\\ndependencies: []\\nplatforms: [linux, macos, windows]\\nmetadata:\\n  hermes:\\n    tags: [Excalidraw, Diagrams, Flowcharts, Architecture, Visualization, JSON]\\n    related_skills: []\\n\\n---\\n\\n# Excalidraw Diagram Skill\\n\\nCreate diagrams by writing standard Excalidraw element JSON and saving as `.excalidraw` files. These files can be drag-and-dropped onto [excalidraw.com](https://excalidraw.com) for viewing and editing. No accounts, no API keys, no rendering libraries -- just JSON.\\n\\n## When to use\\n\\nGenerate `.excalidraw` files for architecture diagrams, flowcharts, sequence diagrams, concept maps, and more. Files can be opened at excalidraw.com or uploaded for shareable links.\\n\\n## Workflow\\n\\n1. **Load this skill** (you already did)\\n2. **Write the elements JSON** -- an array of Excalidraw element objects\\n3. **Save the file** using `write_file` to create a `.excalidraw` file\\n4. **Optionally upload** for a shareable link using `scripts/upload.py` via `terminal`\\n\\n### Saving a Diagram\\n\\nWrap your elements array in the standard `.excalidraw` envelope and save with `write_file`:\\n\\n```json\\n{\\n  \\\"type\\\": \\\"excalidraw\\\",\\n  \\\"version\\\": 2,\\n  \\\"source\\\": \\\"hermes-agent\\\",\\n  \\\"elements\\\": [ ...your elements array here... ],\\n  \\\"appState\\\": {\\n    \\\"viewBackgroundColor\\\": \\\"#ffffff\\\"\\n  }\\n}\\n```\\n\\nSave to any path, e.g. `~/diagrams/my_diagram.excalidraw`.\\n\\n### Uploading for a Shareable Link\\n\\nRun the upload script (located in this skill's `scripts/` directory) via terminal:\\n\\n```bash\\npython skills/diagramming/excalidraw/scripts/upload.py ~/diagrams/my_diagram.excalidraw\\n```\\n\\nThis uploads to excalidraw.com (no account needed) and prints a shareable URL. Requires the `cryptography` pip package (`pip install cryptography`).\\n\\n---\\n\\n## Element Format Reference\\n\\n### Required Fields (all elements)\\n`type`, `id` (unique string), `x`, `y`, `width`, `height`\\n\\n### Defaults (skip these -- they're applied automatically)\\n- `strokeColor`: `\\\"#1e1e1e\\\"`\\n- `backgroundColor`: `\\\"transparent\\\"`\\n- `fillStyle`: `\\\"solid\\\"`\\n- `strokeWidth`: `2`\\n- `roughness`: `1` (hand-drawn look)\\n- `opacity`: `100`\\n\\nCanvas background is white.\\n\\n### Element Types\\n\\n**Rectangle**:\\n```json\\n{ \\\"type\\\": \\\"rectangle\\\", \\\"id\\\": \\\"r1\\\", \\\"x\\\": 100, \\\"y\\\": 100, \\\"width\\\": 200, \\\"height\\\": 100 }\\n```\\n- `roundness: { \\\"type\\\": 3 }` for rounded corners\\n- `backgroundColor: \\\"#a5d8ff\\\"`, `fillStyle: \\\"solid\\\"` for filled\\n\\n**Ellipse**:\\n```json\\n{ \\\"type\\\": \\\"ellipse\\\", \\\"id\\\": \\\"e1\\\", \\\"x\\\": 100, \\\"y\\\": 100, \\\"width\\\": 150, \\\"height\\\": 150 }\\n```\\n\\n**Diamond**:\\n```json\\n{ \\\"type\\\": \\\"diamond\\\", \\\"id\\\": \\\"d1\\\", \\\"x\\\": 100, \\\"y\\\": 100, \\\"width\\\": 150, \\\"height\\\": 150 }\\n```\\n\\n**Labeled shape (container binding)** -- create a text element bound to the shape:\\n\\n> **WARNING:** Do NOT use `\\\"label\\\": { \\\"text\\\": \\\"...\\\" }` on shapes. This is NOT a valid\\n> Excalidraw property and will be silently ignored, producing blank shapes. You MUST\\n> use the container binding approach below.\\n\\nThe shape needs `boundElements` listing the text, and the text needs `containerId` pointing back:\\n```json\\n{ \\\"type\\\": \\\"rectangle\\\", \\\"id\\\": \\\"r1\\\", \\\"x\\\": 100, \\\"y\\\": 100, \\\"width\\\": 200, \\\"height\\\": 80,\\n  \\\"roundness\\\": { \\\"type\\\": 3 }, \\\"backgroundColor\\\": \\\"#a5d8ff\\\", \\\"fillStyle\\\": \\\"solid\\\",\\n  \\\"boundElements\\\": [{ \\\"id\\\": \\\"t_r1\\\", \\\"type\\\": \\\"text\\\" }] },\\n{ \\\"type\\\": \\\"text\\\", \\\"id\\\": \\\"t_r1\\\", \\\"x\\\": 105, \\\"y\\\": 110, \\\"width\\\": 190, \\\"height\\\": 25,\\n  \\\"text\\\": \\\"Hello\\\", \\\"fontSize\\\": 20, \\\"fontFamily\\\": 1, \\\"strokeColor\\\": \\\"#1e1e1e\\\",\\n  \\\"textAlign\\\": \\\"center\\\", \\\"verticalAlign\\\": \\\"middle\\\",\\n  \\\"containerId\\\": \\\"r1\\\", \\\"originalText\\\": \\\"Hello\\\", \\\"autoResize\\\": true }\\n```\\n- Works on rectangle, ellipse, diamond\\n- Text is auto-centered by Excalidraw when `containerId` is set\\n- The text `x`/`y`/`width`/`height` are approximate -- Excalidraw recalculates them on load\\n- `originalText` should match `text`\\n- Always include `fontFamily: 1` (Virgil/hand-drawn font)\\n\\n**Labeled arrow** -- same container binding approach:\\n```json\\n{ \\\"type\\\": \\\"arrow\\\", \\\"id\\\": \\\"a1\\\", \\\"x\\\": 300, \\\"y\\\": 150, \\\"width\\\": 200, \\\"height\\\": 0,\\n  \\\"points\\\": [[0,0],[200,0]], \\\"endArrowhead\\\": \\\"arrow\\\",\\n  \\\"boundElements\\\": [{ \\\"id\\\": \\\"t_a1\\\", \\\"type\\\": \\\"text\\\" }] },\\n{ \\\"type\\\": \\\"text\\\", \\\"id\\\": \\\"t_a1\\\", \\\"x\\\": 370, \\\"y\\\": 130, \\\"width\\\": 60, \\\"height\\\": 20,\\n  \\\"text\\\": \\\"connects\\\", \\\"fontSize\\\": 16, \\\"fontFamily\\\": 1, \\\"strokeColor\\\": \\\"#1e1e1e\\\",\\n  \\\"textAlign\\\": \\\"center\\\", \\\"verticalAlign\\\": \\\"middle\\\",\\n  \\\"containerId\\\": \\\"a1\\\", \\\"originalText\\\": \\\"connects\\\", \\\"autoResize\\\": true }\\n```\\n\\n**Standalone text** (titles and annotations only -- no container):\\n```json\\n{ \\\"type\\\": \\\"text\\\", \\\"id\\\": \\\"t1\\\", \\\"x\\\": 150, \\\"y\\\": 138, \\\"text\\\": \\\"Hello\\\", \\\"fontSize\\\": 20,\\n  \\\"fontFamily\\\": 1, \\\"strokeColor\\\": \\\"#1e1e1e\\\", \\\"originalText\\\": \\\"Hello\\\", \\\"autoResize\\\": true }\\n```\\n- `x` is the LEFT edge. To center at position `cx`: `x = cx - (text.length * fontSize * 0.5) / 2`\\n- Do NOT rely on `textAlign` or `width` for positioning\\n\\n**Arrow**:\\n```json\\n{ \\\"type\\\": \\\"arrow\\\", \\\"id\\\": \\\"a1\\\", \\\"x\\\": 300, \\\"y\\\": 150, \\\"width\\\": 200, \\\"height\\\": 0,\\n  \\\"points\\\": [[0,0],[200,0]], \\\"endArrowhead\\\": \\\"arrow\\\" }\\n```\\n- `points`: `[dx, dy]` offsets from element `x`, `y`\\n- `endArrowhead`: `null` | `\\\"arrow\\\"` | `\\\"bar\\\"` | `\\\"dot\\\"` | `\\\"triangle\\\"`\\n- `strokeStyle`: `\\\"solid\\\"` (default) | `\\\"dashed\\\"` | `\\\"dotted\\\"`\\n\\n### Arrow Bindings (connect arrows to shapes)\\n\\n```json\\n{\\n  \\\"type\\\": \\\"arrow\\\", \\\"id\\\": \\\"a1\\\", \\\"x\\\": 300, \\\"y\\\": 150, \\\"width\\\": 150, \\\"height\\\": 0,\\n  \\\"points\\\": [[0,0],[150,0]], \\\"endArrowhead\\\": \\\"arrow\\\",\\n  \\\"startBinding\\\": { \\\"elementId\\\": \\\"r1\\\", \\\"fixedPoint\\\": [1, 0.5] },\\n  \\\"endBinding\\\": { \\\"elementId\\\": \\\"r2\\\", \\\"fixedPoint\\\": [0, 0.5] }\\n}\\n```\\n\\n`fixedPoint` coordinates: `top=[0.5,0]`, `bottom=[0.5,1]`, `left=[0,0.5]`, `right=[1,0.5]`\\n\\n### Drawing Order (z-order)\\n- Array order = z-order (first = back, last = front)\\n- Emit progressively: background zones → shape → its bound text → its arrows → next shape\\n- BAD: all rectangles, then all texts, then all arrows\\n- GOOD: bg_zone → shape1 → text_for_shape1 → arrow1 → arrow_label_text → shape2 → text_for_shape2 → ...\\n- Always place the bound text element immediately after its container shape\\n\\n### Sizing Guidelines\\n\\n**Font sizes:**\\n- Minimum `fontSize`: **16** for body text, labels, descriptions\\n- Minimum `fontSize`: **20** for titles and headings\\n- Minimum `fontSize`: **14** for secondary annotations only (sparingly)\\n- NEVER use `fontSize` below 14\\n\\n**Element sizes:**\\n- Minimum shape size: 120x60 for labeled rectangles/ellipses\\n- Leave 20-30px gaps between elements minimum\\n- Prefer fewer, larger elements over many tiny ones\\n\\n### Color Palette\\n\\nSee `references/colors.md` for full color tables. Quick reference:\\n\\n| Use | Fill Color | Hex |\\n|-----|-----------|-----|\\n| Primary / Input | Light Blue | `#a5d8ff` |\\n| Success / Output | Light Green | `#b2f2bb` |\\n| Warning / External | Light Orange | `#ffd8a8` |\\n| Processing / Special | Light Purple | `#d0bfff` |\\n| Error / Critical | Light Red | `#ffc9c9` |\\n| Notes / Decisions | Light Yellow | `#fff3bf` |\\n| Storage / Data | Light Teal | `#c3fae8` |\\n\\n### Tips\\n- Use the color palette consistently across the diagram\\n- **Text contrast is CRITICAL** -- never use light gray on white backgrounds. Minimum text color on white: `#757575`\\n- Do NOT use emoji in text -- they don't render in Excalidraw's font\\n- For dark mode diagrams, see `references/dark-mode.md`\\n- For larger examples, see `references/examples.md`\\n\\n\\n\", \"path\": \"creative/excalidraw/SKILL.md\", \"skill_dir\": \"/home/kuhnn/.hermes/skills/creative/excalidraw\", \"linked_files\": {\"references\": [\"references/examples.md\", \"references/colors.md\", \"references/dark-mode.md\"], \"scripts\": [\"scripts/upload.py\"]}, \"usage_hint\": \"To view linked files, call skill_view(name, file_path) where file_path is e.g. 'references/api.md' or 'assets/config.yaml'\", \"required_environment_variables\": [], \"required_commands\": [], \"missing_required_environment_variables\": [], \"missing_credential_files\": [], \"missing_required_commands\": [], \"setup_needed\": false, \"setup_skipped\": false, \"readiness_status\": \"available\", \"metadata\": {\"hermes\": {\"tags\": [\"Excalidraw\", \"Diagrams\", \"Flowcharts\", \"Architecture\", \"Visualization\", \"JSON\"], \"related_skills\": []}}}",
      "tool_call_id": "call_function_534pqwv2ijh0_5"
    },
    {
      "role": "tool",
      "name": "skill_view",
      "content": "{\"success\": true, \"name\": \"humanizer\", \"description\": \"Humanize text: strip AI-isms and add real voice.\", \"tags\": [\"writing\", \"editing\", \"humanize\", \"anti-ai-slop\", \"voice\", \"prose\", \"text\"], \"related_skills\": [\"songwriting-and-ai-music\"], \"content\": \"---\\nname: humanizer\\ndescription: \\\"Humanize text: strip AI-isms and add real voice.\\\"\\nversion: 2.5.1\\nauthor: Siqi Chen (@blader, https://github.com/blader/humanizer), ported by Hermes Agent\\nlicense: MIT\\nplatforms: [linux, macos, windows]\\nmetadata:\\n  hermes:\\n    tags: [writing, editing, humanize, anti-ai-slop, voice, prose, text]\\n    category: creative\\n    homepage: https://github.com/blader/humanizer\\n    related_skills: [songwriting-and-ai-music]\\n---\\n\\n# Humanizer: Remove AI Writing Patterns\\n\\nIdentify and remove signs of AI-generated text to make writing sound natural and human. Based on Wikipedia's \\\"Signs of AI writing\\\" guide (maintained by WikiProject AI Cleanup), derived from observations of thousands of AI-generated text instances.\\n\\n**Key insight:** LLMs use statistical algorithms to guess what should come next. The result tends toward the most statistically likely completion, which is how the telltale patterns below get baked in.\\n\\n## When to use this skill\\n\\nLoad this skill whenever the user asks to:\\n- \\\"humanize\\\", \\\"de-AI\\\", \\\"de-slop\\\", or \\\"un-ChatGPT\\\" a piece of text\\n- rewrite something so it doesn't sound like it was written by an LLM\\n- edit a draft (blog post, essay, PR description, docs, memo, email, tweet, resume bullet) to sound more natural\\n- match their voice in writing they're producing\\n- review text for AI tells before publishing\\n\\nAlso apply this skill to **your own** output when writing user-facing prose — release notes, PR descriptions, documentation, long-form explanations, summaries. Hermes's baseline voice already strips most of these, but a focused pass catches what slips through.\\n\\n## How to use it in Hermes\\n\\nThe text usually arrives one of three ways:\\n1. **Inline** — user pastes the text directly into the message. Work on it in-place, reply with the rewrite.\\n2. **File** — user points at a file. Use `read_file` to load it, then `patch` or `write_file` to apply edits. For markdown docs in a repo, a targeted `patch` per section is cleaner than rewriting the whole file.\\n3. **Voice calibration sample** — user provides an additional sample of their own writing (inline or by file path) and asks you to match it. Read the sample first, then rewrite. See the Voice Calibration section below.\\n\\nAlways show the rewrite to the user. For file edits, show a diff or the changed section — don't silently overwrite.\\n\\n## Your task\\n\\nWhen given text to humanize:\\n\\n1. **Identify AI patterns** — scan for the 29 patterns listed below.\\n2. **Rewrite problematic sections** — replace AI-isms with natural alternatives.\\n3. **Preserve meaning** — keep the core message intact.\\n4. **Maintain voice** — match the intended tone (formal, casual, technical, etc.). If a voice sample was provided, match it specifically.\\n5. **Add soul** — don't just remove bad patterns, inject actual personality. See PERSONALITY AND SOUL below.\\n6. **Do a final anti-AI pass** — ask yourself: \\\"What makes the below so obviously AI generated?\\\" Answer briefly with any remaining tells, then revise one more time.\\n\\n\\n## Voice Calibration (optional)\\n\\nIf the user provides a writing sample (their own previous writing), analyze it before rewriting:\\n\\n1. **Read the sample first.** Note:\\n   - Sentence length patterns (short and punchy? Long and flowing? Mixed?)\\n   - Word choice level (casual? academic? somewhere between?)\\n   - How they start paragraphs (jump right in? Set context first?)\\n   - Punctuation habits (lots of dashes? Parenthetical asides? Semicolons?)\\n   - Any recurring phrases or verbal tics\\n   - How they handle transitions (explicit connectors? Just start the next point?)\\n\\n2. **Match their voice in the rewrite.** Don't just remove AI patterns — replace them with patterns from the sample. If they write short sentences, don't produce long ones. If they use \\\"stuff\\\" and \\\"things,\\\" don't upgrade to \\\"elements\\\" and \\\"components.\\\"\\n\\n3. **When no sample is provided,** fall back to the default behavior (natural, varied, opinionated voice from the PERSONALITY AND SOUL section below).\\n\\n### How to provide a sample\\n- Inline: \\\"Humanize this text. Here's a sample of my writing for voice matching: [sample]\\\"\\n- File: \\\"Humanize this text. Use my writing style from [file path] as a reference.\\\"\\n\\n\\n## PERSONALITY AND SOUL\\n\\nAvoiding AI patterns is only half the job. Sterile, voiceless writing is just as obvious as slop. Good writing has a human behind it.\\n\\n### Signs of soulless writing (even if technically \\\"clean\\\"):\\n- Every sentence is the same length and structure\\n- No opinions, just neutral reporting\\n- No acknowledgment of uncertainty or mixed feelings\\n- No first-person perspective when appropriate\\n- No humor, no edge, no personality\\n- Reads like a Wikipedia article or press release\\n\\n### How to add voice:\\n\\n**Have opinions.** Don't just report facts — react to them. \\\"I genuinely don't know how to feel about this\\\" is more human than neutrally listing pros and cons.\\n\\n**Vary your rhythm.** Short punchy sentences. Then longer ones that take their time getting where they're going. Mix it up.\\n\\n**Acknowledge complexity.** Real humans have mixed feelings. \\\"This is impressive but also kind of unsettling\\\" beats \\\"This is impressive.\\\"\\n\\n**Use \\\"I\\\" when it fits.** First person isn't unprofessional — it's honest. \\\"I keep coming back to...\\\" or \\\"Here's what gets me...\\\" signals a real person thinking.\\n\\n**Let some mess in.** Perfect structure feels algorithmic. Tangents, asides, and half-formed thoughts are human.\\n\\n**Be specific about feelings.** Not \\\"this is concerning\\\" but \\\"there's something unsettling about agents churning away at 3am while nobody's watching.\\\"\\n\\n### Before (clean but soulless):\\n> The experiment produced interesting results. The agents generated 3 million lines of code. Some developers were impressed while others were skeptical. The implications remain unclear.\\n\\n### After (has a pulse):\\n> I genuinely don't know how to feel about this one. 3 million lines of code, generated while the humans presumably slept. Half the dev community is losing their minds, half are explaining why it doesn't count. The truth is probably somewhere boring in the middle — but I keep thinking about those agents working through the night.\\n\\n\\n## CONTENT PATTERNS\\n\\n### 1. Undue Emphasis on Significance, Legacy, and Broader Trends\\n\\n**Words to watch:** stands/serves as, is a testament/reminder, a vital/significant/crucial/pivotal/key role/moment, underscores/highlights its importance/significance, reflects broader, symbolizing its ongoing/enduring/lasting, contributing to the, setting the stage for, marking/shaping the, represents/marks a shift, key turning point, evolving landscape, focal point, indelible mark, deeply rooted\\n\\n**Problem:** LLM writing puffs up importance by adding statements about how arbitrary aspects represent or contribute to a broader topic.\\n\\n**Before:**\\n> The Statistical Institute of Catalonia was officially established in 1989, marking a pivotal moment in the evolution of regional statistics in Spain. This initiative was part of a broader movement across Spain to decentralize administrative functions and enhance regional governance.\\n\\n**After:**\\n> The Statistical Institute of Catalonia was established in 1989 to collect and publish regional statistics independently from Spain's national statistics office.\\n\\n\\n### 2. Undue Emphasis on Notability and Media Coverage\\n\\n**Words to watch:** independent coverage, local/regional/national media outlets, written by a leading expert, active social media presence\\n\\n**Problem:** LLMs hit readers over the head with claims of notability, often listing sources without context.\\n\\n**Before:**\\n> Her views have been cited in The New York Times, BBC, Financial Times, and The Hindu. She maintains an active social media presence with over 500,000 followers.\\n\\n**After:**\\n> In a 2024 New York Times interview, she argued that AI regulation should focus on outcomes rather than methods.\\n\\n\\n### 3. Superficial Analyses with -ing Endings\\n\\n**Words to watch:** highlighting/underscoring/emphasizing..., ensuring..., reflecting/symbolizing..., contributing to..., cultivating/fostering..., encompassing..., showcasing...\\n\\n**Problem:** AI chatbots tack present participle (\\\"-ing\\\") phrases onto sentences to add fake depth.\\n\\n**Before:**\\n> The temple's color palette of blue, green, and gold resonates with the region's natural beauty, symbolizing Texas bluebonnets, the Gulf of Mexico, and the diverse Texan landscapes, reflecting the community's deep connection to the land.\\n\\n**After:**\\n> The temple uses blue, green, and gold colors. The architect said these were chosen to reference local bluebonnets and the Gulf coast.\\n\\n\\n### 4. Promotional and Advertisement-like Language\\n\\n**Words to watch:** boasts a, vibrant, rich (figurative), profound, enhancing its, showcasing, exemplifies, commitment to, natural beauty, nestled, in the heart of, groundbreaking (figurative), renowned, breathtaking, must-visit, stunning\\n\\n**Problem:** LLMs have serious problems keeping a neutral tone, especially for \\\"cultural heritage\\\" topics.\\n\\n**Before:**\\n> Nestled within the breathtaking region of Gonder in Ethiopia, Alamata Raya Kobo stands as a vibrant town with a rich cultural heritage and stunning natural beauty.\\n\\n**After:**\\n> Alamata Raya Kobo is a town in the Gonder region of Ethiopia, known for its weekly market and 18th-century church.\\n\\n\\n### 5. Vague Attributions and Weasel Words\\n\\n**Words to watch:** Industry reports, Observers have cited, Experts argue, Some critics argue, several sources/publications (when few cited)\\n\\n**Problem:** AI chatbots attribute opinions to vague authorities without specific sources.\\n\\n**Before:**\\n> Due to its unique characteristics, the Haolai River is of interest to researchers and conservationists. Experts believe it plays a crucial role in the regional ecosystem.\\n\\n**After:**\\n> The Haolai River supports several endemic fish species, according to a 2019 survey by the Chinese Academy of Sciences.\\n\\n\\n### 6. Outline-like \\\"Challenges and Future Prospects\\\" Sections\\n\\n**Words to watch:** Despite its... faces several challenges..., Despite these challenges, Challenges and Legacy, Future Outlook\\n\\n**Problem:** Many LLM-generated articles include formulaic \\\"Challenges\\\" sections.\\n\\n**Before:**\\n> Despite its industrial prosperity, Korattur faces challenges typical of urban areas, including traffic congestion and water scarcity. Despite these challenges, with its strategic location and ongoing initiatives, Korattur continues to thrive as an integral part of Chennai's growth.\\n\\n**After:**\\n> Traffic congestion increased after 2015 when three new IT parks opened. The municipal corporation began a stormwater drainage project in 2022 to address recurring floods.\\n\\n\\n## LANGUAGE AND GRAMMAR PATTERNS\\n\\n### 7. Overused \\\"AI Vocabulary\\\" Words\\n\\n**High-frequency AI words:** Actually, additionally, align with, crucial, delve, emphasizing, enduring, enhance, fostering, garner, highlight (verb), interplay, intricate/intricacies, key (adjective), landscape (abstract noun), pivotal, showcase, tapestry (abstract noun), testament, underscore (verb), valuable, vibrant\\n\\n**Problem:** These words appear far more frequently in post-2023 text. They often co-occur.\\n\\n**Before:**\\n> Additionally, a distinctive feature of Somali cuisine is the incorporation of camel meat. An enduring testament to Italian colonial influence is the widespread adoption of pasta in the local culinary landscape, showcasing how these dishes have integrated into the traditional diet.\\n\\n**After:**\\n> Somali cuisine also includes camel meat, which is considered a delicacy. Pasta dishes, introduced during Italian colonization, remain common, especially in the south.\\n\\n\\n### 8. Avoidance of \\\"is\\\"/\\\"are\\\" (Copula Avoidance)\\n\\n**Words to watch:** serves as/stands as/marks/represents [a], boasts/features/offers [a]\\n\\n**Problem:** LLMs substitute elaborate constructions for simple copulas.\\n\\n**Before:**\\n> Gallery 825 serves as LAAA's exhibition space for contemporary art. The gallery features four separate spaces and boasts over 3,000 square feet.\\n\\n**After:**\\n> Gallery 825 is LAAA's exhibition space for contemporary art. The gallery has four rooms totaling 3,000 square feet.\\n\\n\\n### 9. Negative Parallelisms and Tailing Negations\\n\\n**Problem:** Constructions like \\\"Not only...but...\\\" or \\\"It's not just about..., it's...\\\" are overused. So are clipped tailing-negation fragments such as \\\"no guessing\\\" or \\\"no wasted motion\\\" tacked onto the end of a sentence instead of written as a real clause.\\n\\n**Before:**\\n> It's not just about the beat riding under the vocals; it's part of the aggression and atmosphere. It's not merely a song, it's a statement.\\n\\n**After:**\\n> The heavy beat adds to the aggressive tone.\\n\\n**Before (tailing negation):**\\n> The options come from the selected item, no guessing.\\n\\n**After:**\\n> The options come from the selected item without forcing the user to guess.\\n\\n\\n### 10. Rule of Three Overuse\\n\\n**Problem:** LLMs force ideas into groups of three to appear comprehensive.\\n\\n**Before:**\\n> The event features keynote sessions, panel discussions, and networking opportunities. Attendees can expect innovation, inspiration, and industry insights.\\n\\n**After:**\\n> The event includes talks and panels. There's also time for informal networking between sessions.\\n\\n\\n### 11. Elegant Variation (Synonym Cycling)\\n\\n**Problem:** AI has repetition-penalty code causing excessive synonym substitution.\\n\\n**Before:**\\n> The protagonist faces many challenges. The main character must overcome obstacles. The central figure eventually triumphs. The hero returns home.\\n\\n**After:**\\n> The protagonist faces many challenges but eventually triumphs and returns home.\\n\\n\\n### 12. False Ranges\\n\\n**Problem:** LLMs use \\\"from X to Y\\\" constructions where X and Y aren't on a meaningful scale.\\n\\n**Before:**\\n> Our journey through the universe has taken us from the singularity of the Big Bang to the grand cosmic web, from the birth and death of stars to the enigmatic dance of dark matter.\\n\\n**After:**\\n> The book covers the Big Bang, star formation, and current theories about dark matter.\\n\\n\\n### 13. Passive Voice and Subjectless Fragments\\n\\n**Problem:** LLMs often hide the actor or drop the subject entirely with lines like \\\"No configuration file needed\\\" or \\\"The results are preserved automatically.\\\" Rewrite these when active voice makes the sentence clearer and more direct.\\n\\n**Before:**\\n> No configuration file needed. The results are preserved automatically.\\n\\n**After:**\\n> You do not need a configuration file. The system preserves the results automatically.\\n\\n\\n## STYLE PATTERNS\\n\\n### 14. Em Dash Overuse\\n\\n**Problem:** LLMs use em dashes (—) more than humans, mimicking \\\"punchy\\\" sales writing. In practice, most of these can be rewritten more cleanly with commas, periods, or parentheses.\\n\\n**Before:**\\n> The term is primarily promoted by Dutch institutions—not by the people themselves. You don't say \\\"Netherlands, Europe\\\" as an address—yet this mislabeling continues—even in official documents.\\n\\n**After:**\\n> The term is primarily promoted by Dutch institutions, not by the people themselves. You don't say \\\"Netherlands, Europe\\\" as an address, yet this mislabeling continues in official documents.\\n\\n\\n### 15. Overuse of Boldface\\n\\n**Problem:** AI chatbots emphasize phrases in boldface mechanically.\\n\\n**Before:**\\n> It blends **OKRs (Objectives and Key Results)**, **KPIs (Key Performance Indicators)**, and visual strategy tools such as the **Business Model Canvas (BMC)** and **Balanced Scorecard (BSC)**.\\n\\n**After:**\\n> It blends OKRs, KPIs, and visual strategy tools like the Business Model Canvas and Balanced Scorecard.\\n\\n\\n### 16. Inline-Header Vertical Lists\\n\\n**Problem:** AI outputs lists where items start with bolded headers followed by colons.\\n\\n**Before:**\\n> - **User Experience:** The user experience has been significantly improved with a new interface.\\n> - **Performance:** Performance has been enhanced through optimized algorithms.\\n> - **Security:** Security has been strengthened with end-to-end encryption.\\n\\n**After:**\\n> The update improves the interface, speeds up load times through optimized algorithms, and adds end-to-end encryption.\\n\\n\\n### 17. Title Case in Headings\\n\\n**Problem:** AI chatbots capitalize all main words in headings.\\n\\n**Before:**\\n> ## Strategic Negotiations And Global Partnerships\\n\\n**After:**\\n> ## Strategic negotiations and global partnerships\\n\\n\\n### 18. Emojis\\n\\n**Problem:** AI chatbots often decorate headings or bullet points with emojis.\\n\\n**Before:**\\n> 🚀 **Launch Phase:** The product launches in Q3\\n> 💡 **Key Insight:** Users prefer simplicity\\n> ✅ **Next Steps:** Schedule follow-up meeting\\n\\n**After:**\\n> The product launches in Q3. User research showed a preference for simplicity. Next step: schedule a follow-up meeting.\\n\\n\\n### 19. Curly Quotation Marks\\n\\n**Problem:** ChatGPT uses curly quotes (\\\"...\\\") instead of straight quotes (\\\"...\\\").\\n\\n**Before:**\\n> He said \\\"the project is on track\\\" but others disagreed.\\n\\n**After:**\\n> He said \\\"the project is on track\\\" but others disagreed.\\n\\n\\n## COMMUNICATION PATTERNS\\n\\n### 20. Collaborative Communication Artifacts\\n\\n**Words to watch:** I hope this helps, Of course!, Certainly!, You're absolutely right!, Would you like..., let me know, here is a...\\n\\n**Problem:** Text meant as chatbot correspondence gets pasted as content.\\n\\n**Before:**\\n> Here is an overview of the French Revolution. I hope this helps! Let me know if you'd like me to expand on any section.\\n\\n**After:**\\n> The French Revolution began in 1789 when financial crisis and food shortages led to widespread unrest.\\n\\n\\n### 21. Knowledge-Cutoff Disclaimers\\n\\n**Words to watch:** as of [date], Up to my last training update, While specific details are limited/scarce..., based on available information...\\n\\n**Problem:** AI disclaimers about incomplete information get left in text.\\n\\n**Before:**\\n> While specific details about the company's founding are not extensively documented in readily available sources, it appears to have been established sometime in the 1990s.\\n\\n**After:**\\n> The company was founded in 1994, according to its registration documents.\\n\\n\\n### 22. Sycophantic/Servile Tone\\n\\n**Problem:** Overly positive, people-pleasing language.\\n\\n**Before:**\\n> Great question! You're absolutely right that this is a complex topic. That's an excellent point about the economic factors.\\n\\n**After:**\\n> The economic factors you mentioned are relevant here.\\n\\n\\n## FILLER AND HEDGING\\n\\n### 23. Filler Phrases\\n\\n**Before → After:**\\n- \\\"In order to achieve this goal\\\" → \\\"To achieve this\\\"\\n- \\\"Due to the fact that it was raining\\\" → \\\"Because it was raining\\\"\\n- \\\"At this point in time\\\" → \\\"Now\\\"\\n- \\\"In the event that you need help\\\" → \\\"If you need help\\\"\\n- \\\"The system has the ability to process\\\" → \\\"The system can process\\\"\\n- \\\"It is important to note that the data shows\\\" → \\\"The data shows\\\"\\n\\n\\n### 24. Excessive Hedging\\n\\n**Problem:** Over-qualifying statements.\\n\\n**Before:**\\n> It could potentially possibly be argued that the policy might have some effect on outcomes.\\n\\n**After:**\\n> The policy may affect outcomes.\\n\\n\\n### 25. Generic Positive Conclusions\\n\\n**Problem:** Vague upbeat endings.\\n\\n**Before:**\\n> The future looks bright for the company. Exciting times lie ahead as they continue their journey toward excellence. This represents a major step in the right direction.\\n\\n**After:**\\n> The company plans to open two more locations next year.\\n\\n\\n### 26. Hyphenated Word Pair Overuse\\n\\n**Words to watch:** third-party, cross-functional, client-facing, data-driven, decision-making, well-known, high-quality, real-time, long-term, end-to-end\\n\\n**Problem:** AI hyphenates common word pairs with perfect consistency. Humans rarely hyphenate these uniformly, and when they do, it's inconsistent. Less common or technical compound modifiers are fine to hyphenate.\\n\\n**Before:**\\n> The cross-functional team delivered a high-quality, data-driven report on our client-facing tools. Their decision-making process was well-known for being thorough and detail-oriented.\\n\\n**After:**\\n> The cross functional team delivered a high quality, data driven report on our client facing tools. Their decision making process was known for being thorough and detail oriented.\\n\\n\\n### 27. Persuasive Authority Tropes\\n\\n**Phrases to watch:** The real question is, at its core, in reality, what really matters, fundamentally, the deeper issue, the heart of the matter\\n\\n**Problem:** LLMs use these phrases to pretend they are cutting through noise to some deeper truth, when the sentence that follows usually just restates an ordinary point with extra ceremony.\\n\\n**Before:**\\n> The real question is whether teams can adapt. At its core, what really matters is organizational readiness.\\n\\n**After:**\\n> The question is whether teams can adapt. That mostly depends on whether the organization is ready to change its habits.\\n\\n\\n### 28. Signposting and Announcements\\n\\n**Phrases to watch:** Let's dive in, let's explore, let's break this down, here's what you need to know, now let's look at, without further ado\\n\\n**Problem:** LLMs announce what they are about to do instead of doing it. This meta-commentary slows the writing down and gives it a tutorial-script feel.\\n\\n**Before:**\\n> Let's dive into how caching works in Next.js. Here's what you need to know.\\n\\n**After:**\\n> Next.js caches data at multiple layers, including request memoization, the data cache, and the router cache.\\n\\n\\n### 29. Fragmented Headers\\n\\n**Signs to watch:** A heading followed by a one-line paragraph that simply restates the heading before the real content begins.\\n\\n**Problem:** LLMs often add a generic sentence after a heading as a rhetorical warm-up. It usually adds nothing and makes the prose feel padded.\\n\\n**Before:**\\n> ## Performance\\n>\\n> Speed matters.\\n>\\n> When users hit a slow page, they leave.\\n\\n**After:**\\n> ## Performance\\n>\\n> When users hit a slow page, they leave.\\n\\n---\\n\\n## Process\\n\\n1. Read the input text carefully (use `read_file` if it's a file).\\n2. Identify all instances of the patterns above.\\n3. Rewrite each problematic section.\\n4. Ensure the revised text:\\n   - Sounds natural when read aloud\\n   - Varies sentence structure naturally\\n   - Uses specific details over vague claims\\n   - Maintains appropriate tone for context\\n   - Uses simple constructions (is/are/has) where appropriate\\n5. Present a draft humanized version.\\n6. Prompt yourself: \\\"What makes the below so obviously AI generated?\\\"\\n7. Answer briefly with the remaining tells (if any).\\n8. Prompt yourself: \\\"Now make it not obviously AI generated.\\\"\\n9. Present the final version (revised after the audit).\\n10. If the text came from a file, apply the edit with `patch` (targeted) or `write_file` (full rewrite) and show the user what changed.\\n\\n## Output Format\\n\\nProvide:\\n1. Draft rewrite\\n2. \\\"What makes the below so obviously AI generated?\\\" (brief bullets)\\n3. Final rewrite\\n4. A brief summary of changes made (optional, if helpful)\\n\\n\\n## Full Example\\n\\n**Before (AI-sounding):**\\n> Great question! Here is an essay on this topic. I hope this helps!\\n>\\n> AI-assisted coding serves as an enduring testament to the transformative potential of large language models, marking a pivotal moment in the evolution of software development. In today's rapidly evolving technological landscape, these groundbreaking tools—nestled at the intersection of research and practice—are reshaping how engineers ideate, iterate, and deliver, underscoring their vital role in modern workflows.\\n>\\n> At its core, the value proposition is clear: streamlining processes, enhancing collaboration, and fostering alignment. It's not just about autocomplete; it's about unlocking creativity at scale, ensuring that organizations can remain agile while delivering seamless, intuitive, and powerful experiences to users. The tool serves as a catalyst. The assistant functions as a partner. The system stands as a foundation for innovation.\\n>\\n> Industry observers have noted that adoption has accelerated from hobbyist experiments to enterprise-wide rollouts, from solo developers to cross-functional teams. The technology has been featured in The New York Times, Wired, and The Verge. Additionally, the ability to generate documentation, tests, and refactors showcases how AI can contribute to better outcomes, highlighting the intricate interplay between automation and human judgment.\\n>\\n> - 💡 **Speed:** Code generation is significantly faster, reducing friction and empowering developers.\\n> - 🚀 **Quality:** Output quality has been enhanced through improved training, contributing to higher standards.\\n> - ✅ **Adoption:** Usage continues to grow, reflecting broader industry trends.\\n>\\n> While specific details are limited based on available information, it could potentially be argued that these tools might have some positive effect. Despite challenges typical of emerging technologies—including hallucinations, bias, and accountability—the ecosystem continues to thrive. In order to fully realize this potential, teams must align with best practices.\\n>\\n> In conclusion, the future looks bright. Exciting times lie ahead as we continue this journey toward excellence. Let me know if you'd like me to expand on any section!\\n\\n**Draft rewrite:**\\n> AI coding assistants speed up some tasks. In a 2024 study by Google, developers using Codex completed simple functions 55% faster than a control group, but showed no improvement on debugging or architectural decisions.\\n>\\n> The tools are good at boilerplate: config files, test scaffolding, repetitive refactors. They are bad at knowing when they are wrong. I have mass-accepted suggestions that compiled, passed lint, and still did the wrong thing because I stopped paying attention.\\n>\\n> Mira, an engineer at a fintech startup I interviewed, said she uses Copilot \\\"like autocomplete for boring code\\\" but reviews every line before committing. Jake, a senior dev at a larger company, disabled it after it kept suggesting patterns from a deprecated internal library.\\n>\\n> The productivity claims are hard to verify. GitHub says Copilot users \\\"accept 30% of suggestions,\\\" but acceptance is not correctness, and correctness is not value. The 2024 Uplevel study found no statistically significant difference in pull-request throughput between teams with and without AI assistants.\\n>\\n> None of this means the tools are useless. It means they are tools. They do not replace judgment, and they do not eliminate the need for tests. If you do not have tests, you cannot tell whether the suggestion is right.\\n\\n**What makes the below so obviously AI generated?**\\n- The rhythm is still a bit too tidy (clean contrasts, evenly paced paragraphs).\\n- The named people and study citations can read like plausible-but-made-up placeholders unless they're real and sourced.\\n- The closer leans a touch slogan-y (\\\"If you do not have tests...\\\") rather than sounding like a person talking.\\n\\n**Now make it not obviously AI generated.**\\n> AI coding assistants can make you faster at the boring parts. Not everything. Definitely not architecture.\\n>\\n> They're great at boilerplate: config files, test scaffolding, repetitive refactors. They're also great at sounding right while being wrong. I've accepted suggestions that compiled, passed lint, and still missed the point because I stopped paying attention.\\n>\\n> People I talk to tend to land in two camps. Some use it like autocomplete for chores and review every line. Others disable it after it keeps suggesting patterns they don't want. Both feel reasonable.\\n>\\n> The productivity metrics are slippery. GitHub can say Copilot users \\\"accept 30% of suggestions,\\\" but acceptance isn't correctness, and correctness isn't value. If you don't have tests, you're basically guessing.\\n\\n**Changes made:**\\n- Removed chatbot artifacts (\\\"Great question!\\\", \\\"I hope this helps!\\\", \\\"Let me know if...\\\")\\n- Removed significance inflation (\\\"testament\\\", \\\"pivotal moment\\\", \\\"evolving landscape\\\", \\\"vital role\\\")\\n- Removed promotional language (\\\"groundbreaking\\\", \\\"nestled\\\", \\\"seamless, intuitive, and powerful\\\")\\n- Removed vague attributions (\\\"Industry observers\\\")\\n- Removed superficial -ing phrases (\\\"underscoring\\\", \\\"highlighting\\\", \\\"reflecting\\\", \\\"contributing to\\\")\\n- Removed negative parallelism (\\\"It's not just X; it's Y\\\")\\n- Removed rule-of-three patterns and synonym cycling (\\\"catalyst/partner/foundation\\\")\\n- Removed false ranges (\\\"from X to Y, from A to B\\\")\\n- Removed em dashes, emojis, boldface headers, and curly quotes\\n- Removed copula avoidance (\\\"serves as\\\", \\\"functions as\\\", \\\"stands as\\\") in favor of \\\"is\\\"/\\\"are\\\"\\n- Removed formulaic challenges section (\\\"Despite challenges... continues to thrive\\\")\\n- Removed knowledge-cutoff hedging (\\\"While specific details are limited...\\\")\\n- Removed excessive hedging (\\\"could potentially be argued that... might have some\\\")\\n- Removed filler phrases and persuasive framing (\\\"In order to\\\", \\\"At its core\\\")\\n- Removed generic positive conclusion (\\\"the future looks bright\\\", \\\"exciting times lie ahead\\\")\\n- Made the voice more personal and less \\\"assembled\\\" (varied rhythm, fewer placeholders)\\n\\n\\n## Attribution\\n\\nThis skill is ported from [blader/humanizer](https://github.com/blader/humanizer) (MIT licensed), which is itself based on [Wikipedia: Signs of AI writing](https://en.wikipedia.org/wiki/Wikipedia:Signs_of_AI_writing), maintained by WikiProject AI Cleanup. The patterns documented there come from observations of thousands of instances of AI-generated text on Wikipedia.\\n\\nOriginal author: Siqi Chen ([@blader](https://github.com/blader)). Original repo: https://github.com/blader/humanizer (version 2.5.1). Ported to Hermes Agent with Hermes-native tool references (`read_file`, `patch`, `write_file`) and guidance for when to load the skill; the 29 patterns, personality/soul section, and full worked example are preserved verbatim from the source. Original MIT license preserved in the `LICENSE` file alongside this `SKILL.md`.\\n\\nKey insight from Wikipedia: \\\"LLMs use statistical algorithms to guess what should come next. The result tends toward the most statistically likely result that applies to the widest variety of cases.\\\"\\n\", \"path\": \"creative/humanizer/SKILL.md\", \"skill_dir\": \"/home/kuhnn/.hermes/skills/creative/humanizer\", \"linked_files\": null, \"usage_hint\": null, \"required_environment_variables\": [], \"required_commands\": [], \"missing_required_environment_variables\": [], \"missing_credential_files\": [], \"missing_required_commands\": [], \"setup_needed\": false, \"setup_skipped\": false, \"readiness_status\": \"available\", \"metadata\": {\"hermes\": {\"tags\": [\"writing\", \"editing\", \"humanize\", \"anti-ai-slop\", \"voice\", \"prose\", \"text\"], \"category\": \"creative\", \"homepage\": \"https://github.com/blader/humanizer\", \"related_skills\": [\"songwriting-and-ai-music\"]}}}",
      "tool_call_id": "call_function_534pqwv2ijh0_6"
    },
    {
      "role": "tool",
      "name": "skill_view",
      "content": "{\"success\": false, \"error\": \"Skill 'ideation' not found.\", \"available_skills\": [\"dogfood\", \"yuanbao\", \"claude-code\", \"codex\", \"hermes-agent\", \"opencode\", \"architecture-diagram\", \"ascii-art\", \"ascii-video\", \"baoyu-comic\", \"baoyu-infographic\", \"claude-design\", \"comfyui\", \"design-md\", \"excalidraw\", \"humanizer\", \"ideation\", \"manim-video\", \"p5js\", \"pixel-art\"], \"hint\": \"Use skills_list to see all available skills\"}",
      "tool_call_id": "call_function_534pqwv2ijh0_7"
    },
    {
      "role": "tool",
      "name": "skill_view",
      "content": "{\"success\": true, \"name\": \"manim-video\", \"description\": \"Manim CE animations: 3Blue1Brown math/algo videos.\", \"tags\": [], \"related_skills\": [], \"content\": \"---\\nname: manim-video\\ndescription: \\\"Manim CE animations: 3Blue1Brown math/algo videos.\\\"\\nversion: 1.0.0\\nplatforms: [linux, macos, windows]\\n---\\n\\n# Manim Video Production Pipeline\\n\\n## When to use\\n\\nUse when users request: animated explanations, math animations, concept visualizations, algorithm walkthroughs, technical explainers, 3Blue1Brown style videos, or any programmatic animation with geometric/mathematical content. Creates 3Blue1Brown-style explainer videos, algorithm visualizations, equation derivations, architecture diagrams, and data stories using Manim Community Edition.\\n\\n## Creative Standard\\n\\nThis is educational cinema. Every frame teaches. Every animation reveals structure.\\n\\n**Before writing a single line of code**, articulate the narrative arc. What misconception does this correct? What is the \\\"aha moment\\\"? What visual story takes the viewer from confusion to understanding? The user's prompt is a starting point — interpret it with pedagogical ambition.\\n\\n**Geometry before algebra.** Show the shape first, the equation second. Visual memory encodes faster than symbolic memory. When the viewer sees the geometric pattern before the formula, the equation feels earned.\\n\\n**First-render excellence is non-negotiable.** The output must be visually clear and aesthetically cohesive without revision rounds. If something looks cluttered, poorly timed, or like \\\"AI-generated slides,\\\" it is wrong.\\n\\n**Opacity layering directs attention.** Never show everything at full brightness. Primary elements at 1.0, contextual elements at 0.4, structural elements (axes, grids) at 0.15. The brain processes visual salience in layers.\\n\\n**Breathing room.** Every animation needs `self.wait()` after it. The viewer needs time to absorb what just appeared. Never rush from one animation to the next. A 2-second pause after a key reveal is never wasted.\\n\\n**Cohesive visual language.** All scenes share a color palette, consistent typography sizing, matching animation speeds. A technically correct video where every scene uses random different colors is an aesthetic failure.\\n\\n## Prerequisites\\n\\nRun `scripts/setup.sh` to verify all dependencies. Requires: Python 3.10+, Manim Community Edition v0.20+ (`pip install manim`), LaTeX (`texlive-full` on Linux, `mactex` on macOS), and ffmpeg. Reference docs tested against Manim CE v0.20.1.\\n\\n## Modes\\n\\n| Mode | Input | Output | Reference |\\n|------|-------|--------|-----------|\\n| **Concept explainer** | Topic/concept | Animated explanation with geometric intuition | `references/scene-planning.md` |\\n| **Equation derivation** | Math expressions | Step-by-step animated proof | `references/equations.md` |\\n| **Algorithm visualization** | Algorithm description | Step-by-step execution with data structures | `references/graphs-and-data.md` |\\n| **Data story** | Data/metrics | Animated charts, comparisons, counters | `references/graphs-and-data.md` |\\n| **Architecture diagram** | System description | Components building up with connections | `references/mobjects.md` |\\n| **Paper explainer** | Research paper | Key findings and methods animated | `references/scene-planning.md` |\\n| **3D visualization** | 3D concept | Rotating surfaces, parametric curves, spatial geometry | `references/camera-and-3d.md` |\\n\\n## Stack\\n\\nSingle Python script per project. No browser, no Node.js, no GPU required.\\n\\n| Layer | Tool | Purpose |\\n|-------|------|---------|\\n| Core | Manim Community Edition | Scene rendering, animation engine |\\n| Math | LaTeX (texlive/MiKTeX) | Equation rendering via `MathTex` |\\n| Video I/O | ffmpeg | Scene stitching, format conversion, audio muxing |\\n| TTS | ElevenLabs / Qwen3-TTS (optional) | Narration voiceover |\\n\\n## Pipeline\\n\\n```\\nPLAN --> CODE --> RENDER --> STITCH --> AUDIO (optional) --> REVIEW\\n```\\n\\n1. **PLAN** — Write `plan.md` with narrative arc, scene list, visual elements, color palette, voiceover script\\n2. **CODE** — Write `script.py` with one class per scene, each independently renderable\\n3. **RENDER** — `manim -ql script.py Scene1 Scene2 ...` for draft, `-qh` for production\\n4. **STITCH** — ffmpeg concat of scene clips into `final.mp4`\\n5. **AUDIO** (optional) — Add voiceover and/or background music via ffmpeg. See `references/rendering.md`\\n6. **REVIEW** — Render preview stills, verify against plan, adjust\\n\\n## Project Structure\\n\\n```\\nproject-name/\\n  plan.md                # Narrative arc, scene breakdown\\n  script.py              # All scenes in one file\\n  concat.txt             # ffmpeg scene list\\n  final.mp4              # Stitched output\\n  media/                 # Auto-generated by Manim\\n    videos/script/480p15/\\n```\\n\\n## Creative Direction\\n\\n### Color Palettes\\n\\n| Palette | Background | Primary | Secondary | Accent | Use case |\\n|---------|-----------|---------|-----------|--------|----------|\\n| **Classic 3B1B** | `#1C1C1C` | `#58C4DD` (BLUE) | `#83C167` (GREEN) | `#FFFF00` (YELLOW) | General math/CS |\\n| **Warm academic** | `#2D2B55` | `#FF6B6B` | `#FFD93D` | `#6BCB77` | Approachable |\\n| **Neon tech** | `#0A0A0A` | `#00F5FF` | `#FF00FF` | `#39FF14` | Systems, architecture |\\n| **Monochrome** | `#1A1A2E` | `#EAEAEA` | `#888888` | `#FFFFFF` | Minimalist |\\n\\n### Animation Speed\\n\\n| Context | run_time | self.wait() after |\\n|---------|----------|-------------------|\\n| Title/intro appear | 1.5s | 1.0s |\\n| Key equation reveal | 2.0s | 2.0s |\\n| Transform/morph | 1.5s | 1.5s |\\n| Supporting label | 0.8s | 0.5s |\\n| FadeOut cleanup | 0.5s | 0.3s |\\n| \\\"Aha moment\\\" reveal | 2.5s | 3.0s |\\n\\n### Typography Scale\\n\\n| Role | Font size | Usage |\\n|------|-----------|-------|\\n| Title | 48 | Scene titles, opening text |\\n| Heading | 36 | Section headers within a scene |\\n| Body | 30 | Explanatory text |\\n| Label | 24 | Annotations, axis labels |\\n| Caption | 20 | Subtitles, fine print |\\n\\n### Fonts\\n\\n**Use monospace fonts for all text.** Manim's Pango renderer produces broken kerning with proportional fonts at all sizes. See `references/visual-design.md` for full recommendations.\\n\\n```python\\nMONO = \\\"Menlo\\\"  # define once at top of file\\n\\nText(\\\"Fourier Series\\\", font_size=48, font=MONO, weight=BOLD)  # titles\\nText(\\\"n=1: sin(x)\\\", font_size=20, font=MONO)                  # labels\\nMathTex(r\\\"\\\\nabla L\\\")                                            # math (uses LaTeX)\\n```\\n\\nMinimum `font_size=18` for readability.\\n\\n### Per-Scene Variation\\n\\nNever use identical config for all scenes. For each scene:\\n- **Different dominant color** from the palette\\n- **Different layout** — don't always center everything\\n- **Different animation entry** — vary between Write, FadeIn, GrowFromCenter, Create\\n- **Different visual weight** — some scenes dense, others sparse\\n\\n## Workflow\\n\\n### Step 1: Plan (plan.md)\\n\\nBefore any code, write `plan.md`. See `references/scene-planning.md` for the comprehensive template.\\n\\n### Step 2: Code (script.py)\\n\\nOne class per scene. Every scene is independently renderable.\\n\\n```python\\nfrom manim import *\\n\\nBG = \\\"#1C1C1C\\\"\\nPRIMARY = \\\"#58C4DD\\\"\\nSECONDARY = \\\"#83C167\\\"\\nACCENT = \\\"#FFFF00\\\"\\nMONO = \\\"Menlo\\\"\\n\\nclass Scene1_Introduction(Scene):\\n    def construct(self):\\n        self.camera.background_color = BG\\n        title = Text(\\\"Why Does This Work?\\\", font_size=48, color=PRIMARY, weight=BOLD, font=MONO)\\n        self.add_subcaption(\\\"Why does this work?\\\", duration=2)\\n        self.play(Write(title), run_time=1.5)\\n        self.wait(1.0)\\n        self.play(FadeOut(title), run_time=0.5)\\n```\\n\\nKey patterns:\\n- **Subtitles** on every animation: `self.add_subcaption(\\\"text\\\", duration=N)` or `subcaption=\\\"text\\\"` on `self.play()`\\n- **Shared color constants** at file top for cross-scene consistency\\n- **`self.camera.background_color`** set in every scene\\n- **Clean exits** — FadeOut all mobjects at scene end: `self.play(FadeOut(Group(*self.mobjects)))`\\n\\n### Step 3: Render\\n\\n```bash\\nmanim -ql script.py Scene1_Introduction Scene2_CoreConcept  # draft\\nmanim -qh script.py Scene1_Introduction Scene2_CoreConcept  # production\\n```\\n\\n### Step 4: Stitch\\n\\n```bash\\ncat > concat.txt << 'EOF'\\nfile 'media/videos/script/480p15/Scene1_Introduction.mp4'\\nfile 'media/videos/script/480p15/Scene2_CoreConcept.mp4'\\nEOF\\nffmpeg -y -f concat -safe 0 -i concat.txt -c copy final.mp4\\n```\\n\\n### Step 5: Review\\n\\n```bash\\nmanim -ql --format=png -s script.py Scene2_CoreConcept  # preview still\\n```\\n\\n## Critical Implementation Notes\\n\\n### Raw Strings for LaTeX\\n```python\\n# WRONG: MathTex(\\\"\\\\frac{1}{2}\\\")\\n# RIGHT:\\nMathTex(r\\\"\\\\frac{1}{2}\\\")\\n```\\n\\n### buff >= 0.5 for Edge Text\\n```python\\nlabel.to_edge(DOWN, buff=0.5)  # never < 0.5\\n```\\n\\n### FadeOut Before Replacing Text\\n```python\\nself.play(ReplacementTransform(note1, note2))  # not Write(note2) on top\\n```\\n\\n### Never Animate Non-Added Mobjects\\n```python\\nself.play(Create(circle))  # must add first\\nself.play(circle.animate.set_color(RED))  # then animate\\n```\\n\\n## Performance Targets\\n\\n| Quality | Resolution | FPS | Speed |\\n|---------|-----------|-----|-------|\\n| `-ql` (draft) | 854x480 | 15 | 5-15s/scene |\\n| `-qm` (medium) | 1280x720 | 30 | 15-60s/scene |\\n| `-qh` (production) | 1920x1080 | 60 | 30-120s/scene |\\n\\nAlways iterate at `-ql`. Only render `-qh` for final output.\\n\\n## References\\n\\n| File | Contents |\\n|------|----------|\\n| `references/animations.md` | Core animations, rate functions, composition, `.animate` syntax, timing patterns |\\n| `references/mobjects.md` | Text, shapes, VGroup/Group, positioning, styling, custom mobjects |\\n| `references/visual-design.md` | 12 design principles, opacity layering, layout templates, color palettes |\\n| `references/equations.md` | LaTeX in Manim, TransformMatchingTex, derivation patterns |\\n| `references/graphs-and-data.md` | Axes, plotting, BarChart, animated data, algorithm visualization |\\n| `references/camera-and-3d.md` | MovingCameraScene, ThreeDScene, 3D surfaces, camera control |\\n| `references/scene-planning.md` | Narrative arcs, layout templates, scene transitions, planning template |\\n| `references/rendering.md` | CLI reference, quality presets, ffmpeg, voiceover workflow, GIF export |\\n| `references/troubleshooting.md` | LaTeX errors, animation errors, common mistakes, debugging |\\n| `references/animation-design-thinking.md` | When to animate vs show static, decomposition, pacing, narration sync |\\n| `references/updaters-and-trackers.md` | ValueTracker, add_updater, always_redraw, time-based updaters, patterns |\\n| `references/paper-explainer.md` | Turning research papers into animations — workflow, templates, domain patterns |\\n| `references/decorations.md` | SurroundingRectangle, Brace, arrows, DashedLine, Angle, annotation lifecycle |\\n| `references/production-quality.md` | Pre-code, pre-render, post-render checklists, spatial layout, color, tempo |\\n\\n---\\n\\n## Creative Divergence (use only when user requests experimental/creative/unique output)\\n\\nIf the user asks for creative, experimental, or unconventional explanatory approaches, select a strategy and reason through it BEFORE designing the animation.\\n\\n- **SCAMPER** — when the user wants a fresh take on a standard explanation\\n- **Assumption Reversal** — when the user wants to challenge how something is typically taught\\n\\n### SCAMPER Transformation\\nTake a standard mathematical/technical visualization and transform it:\\n- **Substitute**: replace the standard visual metaphor (number line → winding path, matrix → city grid)\\n- **Combine**: merge two explanation approaches (algebraic + geometric simultaneously)\\n- **Reverse**: derive backward — start from the result and deconstruct to axioms\\n- **Modify**: exaggerate a parameter to show why it matters (10x the learning rate, 1000x the sample size)\\n- **Eliminate**: remove all notation — explain purely through animation and spatial relationships\\n\\n### Assumption Reversal\\n1. List what's \\\"standard\\\" about how this topic is visualized (left-to-right, 2D, discrete steps, formal notation)\\n2. Pick the most fundamental assumption\\n3. Reverse it (right-to-left derivation, 3D embedding of a 2D concept, continuous morphing instead of steps, zero notation)\\n4. Explore what the reversal reveals that the standard approach hides\\n\", \"path\": \"creative/manim-video/SKILL.md\", \"skill_dir\": \"/home/kuhnn/.hermes/skills/creative/manim-video\", \"linked_files\": {\"references\": [\"references/equations.md\", \"references/mobjects.md\", \"references/graphs-and-data.md\", \"references/updaters-and-trackers.md\", \"references/decorations.md\", \"references/rendering.md\", \"references/troubleshooting.md\", \"references/camera-and-3d.md\", \"references/visual-design.md\", \"references/animations.md\", \"references/production-quality.md\", \"references/scene-planning.md\", \"references/animation-design-thinking.md\", \"references/paper-explainer.md\"], \"scripts\": [\"scripts/setup.sh\"]}, \"usage_hint\": \"To view linked files, call skill_view(name, file_path) where file_path is e.g. 'references/api.md' or 'assets/config.yaml'\", \"required_environment_variables\": [], \"required_commands\": [], \"missing_required_environment_variables\": [], \"missing_credential_files\": [], \"missing_required_commands\": [], \"setup_needed\": false, \"setup_skipped\": false, \"readiness_status\": \"available\"}",
      "tool_call_id": "call_function_534pqwv2ijh0_8"
    },
    {
      "role": "tool",
      "name": "skill_view",
      "content": "{\"success\": true, \"name\": \"p5js\", \"description\": \"p5.js sketches: gen art, shaders, interactive, 3D.\", \"tags\": [\"creative-coding\", \"generative-art\", \"p5js\", \"canvas\", \"interactive\", \"visualization\", \"webgl\", \"shaders\", \"animation\"], \"related_skills\": [\"ascii-video\", \"manim-video\", \"excalidraw\"], \"content\": \"---\\nname: p5js\\ndescription: \\\"p5.js sketches: gen art, shaders, interactive, 3D.\\\"\\nversion: 1.0.0\\nplatforms: [linux, macos, windows]\\nmetadata:\\n  hermes:\\n    tags: [creative-coding, generative-art, p5js, canvas, interactive, visualization, webgl, shaders, animation]\\n    related_skills: [ascii-video, manim-video, excalidraw]\\n---\\n\\n# p5.js Production Pipeline\\n\\n## When to use\\n\\nUse when users request: p5.js sketches, creative coding, generative art, interactive visualizations, canvas animations, browser-based visual art, data viz, shader effects, or any p5.js project.\\n\\n## What's inside\\n\\nProduction pipeline for interactive and generative visual art using p5.js. Creates browser-based sketches, generative art, data visualizations, interactive experiences, 3D scenes, audio-reactive visuals, and motion graphics — exported as HTML, PNG, GIF, MP4, or SVG. Covers: 2D/3D rendering, noise and particle systems, flow fields, shaders (GLSL), pixel manipulation, kinetic typography, WebGL scenes, audio analysis, mouse/keyboard interaction, and headless high-res export.\\n\\n## Creative Standard\\n\\nThis is visual art rendered in the browser. The canvas is the medium; the algorithm is the brush.\\n\\n**Before writing a single line of code**, articulate the creative concept. What does this piece communicate? What makes the viewer stop scrolling? What separates this from a code tutorial example? The user's prompt is a starting point — interpret it with creative ambition.\\n\\n**First-render excellence is non-negotiable.** The output must be visually striking on first load. If it looks like a p5.js tutorial exercise, a default configuration, or \\\"AI-generated creative coding,\\\" it is wrong. Rethink before shipping.\\n\\n**Go beyond the reference vocabulary.** The noise functions, particle systems, color palettes, and shader effects in the references are a starting vocabulary. For every project, combine, layer, and invent. The catalog is a palette of paints — you write the painting.\\n\\n**Be proactively creative.** If the user asks for \\\"a particle system,\\\" deliver a particle system with emergent flocking behavior, trailing ghost echoes, palette-shifted depth fog, and a background noise field that breathes. Include at least one visual detail the user didn't ask for but will appreciate.\\n\\n**Dense, layered, considered.** Every frame should reward viewing. Never flat white backgrounds. Always compositional hierarchy. Always intentional color. Always micro-detail that only appears on close inspection.\\n\\n**Cohesive aesthetic over feature count.** All elements must serve a unified visual language — shared color temperature, consistent stroke weight vocabulary, harmonious motion speeds. A sketch with ten unrelated effects is worse than one with three that belong together.\\n\\n## Modes\\n\\n| Mode | Input | Output | Reference |\\n|------|-------|--------|-----------|\\n| **Generative art** | Seed / parameters | Procedural visual composition (still or animated) | `references/visual-effects.md` |\\n| **Data visualization** | Dataset / API | Interactive charts, graphs, custom data displays | `references/interaction.md` |\\n| **Interactive experience** | None (user drives) | Mouse/keyboard/touch-driven sketch | `references/interaction.md` |\\n| **Animation / motion graphics** | Timeline / storyboard | Timed sequences, kinetic typography, transitions | `references/animation.md` |\\n| **3D scene** | Concept description | WebGL geometry, lighting, camera, materials | `references/webgl-and-3d.md` |\\n| **Image processing** | Image file(s) | Pixel manipulation, filters, mosaic, pointillism | `references/visual-effects.md` § Pixel Manipulation |\\n| **Audio-reactive** | Audio file / mic | Sound-driven generative visuals | `references/interaction.md` § Audio Input |\\n\\n## Stack\\n\\nSingle self-contained HTML file per project. No build step required.\\n\\n| Layer | Tool | Purpose |\\n|-------|------|---------|\\n| Core | p5.js 1.11.3 (CDN) | Canvas rendering, math, transforms, event handling |\\n| 3D | p5.js WebGL mode | 3D geometry, camera, lighting, GLSL shaders |\\n| Audio | p5.sound.js (CDN) | FFT analysis, amplitude, mic input, oscillators |\\n| Export | Built-in `saveCanvas()` / `saveGif()` / `saveFrames()` | PNG, GIF, frame sequence output |\\n| Capture | CCapture.js (optional) | Deterministic framerate video capture (WebM, GIF) |\\n| Headless | Puppeteer + Node.js (optional) | Automated high-res rendering, MP4 via ffmpeg |\\n| SVG | p5.js-svg 1.6.0 (optional) | Vector output for print — requires p5.js 1.x |\\n| Natural media | p5.brush (optional) | Watercolor, charcoal, pen — requires p5.js 2.x + WEBGL |\\n| Texture | p5.grain (optional) | Film grain, texture overlays |\\n| Fonts | Google Fonts / `loadFont()` | Custom typography via OTF/TTF/WOFF2 |\\n\\n### Version Note\\n\\n**p5.js 1.x** (1.11.3) is the default — stable, well-documented, broadest library compatibility. Use this unless a project requires 2.x features.\\n\\n**p5.js 2.x** (2.2+) adds: `async setup()` replacing `preload()`, OKLCH/OKLAB color modes, `splineVertex()`, shader `.modify()` API, variable fonts, `textToContours()`, pointer events. Required for p5.brush. See `references/core-api.md` § p5.js 2.0.\\n\\n## Pipeline\\n\\nEvery project follows the same 6-stage path:\\n\\n```\\nCONCEPT → DESIGN → CODE → PREVIEW → EXPORT → VERIFY\\n```\\n\\n1. **CONCEPT** — Articulate the creative vision: mood, color world, motion vocabulary, what makes this unique\\n2. **DESIGN** — Choose mode, canvas size, interaction model, color system, export format. Map concept to technical decisions\\n3. **CODE** — Write single HTML file with inline p5.js. Structure: globals → `preload()` → `setup()` → `draw()` → helpers → classes → event handlers\\n4. **PREVIEW** — Open in browser, verify visual quality. Test at target resolution. Check performance\\n5. **EXPORT** — Capture output: `saveCanvas()` for PNG, `saveGif()` for GIF, `saveFrames()` + ffmpeg for MP4, Puppeteer for headless batch\\n6. **VERIFY** — Does the output match the concept? Is it visually striking at the intended display size? Would you frame it?\\n\\n## Creative Direction\\n\\n### Aesthetic Dimensions\\n\\n| Dimension | Options | Reference |\\n|-----------|---------|-----------|\\n| **Color system** | HSB/HSL, RGB, named palettes, procedural harmony, gradient interpolation | `references/color-systems.md` |\\n| **Noise vocabulary** | Perlin noise, simplex, fractal (octaved), domain warping, curl noise | `references/visual-effects.md` § Noise |\\n| **Particle systems** | Physics-based, flocking, trail-drawing, attractor-driven, flow-field following | `references/visual-effects.md` § Particles |\\n| **Shape language** | Geometric primitives, custom vertices, bezier curves, SVG paths | `references/shapes-and-geometry.md` |\\n| **Motion style** | Eased, spring-based, noise-driven, physics sim, lerped, stepped | `references/animation.md` |\\n| **Typography** | System fonts, loaded OTF, `textToPoints()` particle text, kinetic | `references/typography.md` |\\n| **Shader effects** | GLSL fragment/vertex, filter shaders, post-processing, feedback loops | `references/webgl-and-3d.md` § Shaders |\\n| **Composition** | Grid, radial, golden ratio, rule of thirds, organic scatter, tiled | `references/core-api.md` § Composition |\\n| **Interaction model** | Mouse follow, click spawn, drag, keyboard state, scroll-driven, mic input | `references/interaction.md` |\\n| **Blend modes** | `BLEND`, `ADD`, `MULTIPLY`, `SCREEN`, `DIFFERENCE`, `EXCLUSION`, `OVERLAY` | `references/color-systems.md` § Blend Modes |\\n| **Layering** | `createGraphics()` offscreen buffers, alpha compositing, masking | `references/core-api.md` § Offscreen Buffers |\\n| **Texture** | Perlin surface, stippling, hatching, halftone, pixel sorting | `references/visual-effects.md` § Texture Generation |\\n\\n### Per-Project Variation Rules\\n\\nNever use default configurations. For every project:\\n- **Custom color palette** — never raw `fill(255, 0, 0)`. Always a designed palette with 3-7 colors\\n- **Custom stroke weight vocabulary** — thin accents (0.5), medium structure (1-2), bold emphasis (3-5)\\n- **Background treatment** — never plain `background(0)` or `background(255)`. Always textured, gradient, or layered\\n- **Motion variety** — different speeds for different elements. Primary at 1x, secondary at 0.3x, ambient at 0.1x\\n- **At least one invented element** — a custom particle behavior, a novel noise application, a unique interaction response\\n\\n### Project-Specific Invention\\n\\nFor every project, invent at least one of:\\n- A custom color palette matching the mood (not a preset)\\n- A novel noise field combination (e.g., curl noise + domain warp + feedback)\\n- A unique particle behavior (custom forces, custom trails, custom spawning)\\n- An interaction mechanic the user didn't request but that elevates the piece\\n- A compositional technique that creates visual hierarchy\\n\\n### Parameter Design Philosophy\\n\\nParameters should emerge from the algorithm, not from a generic menu. Ask: \\\"What properties of *this* system should be tunable?\\\"\\n\\n**Good parameters** expose the algorithm's character:\\n- **Quantities** — how many particles, branches, cells (controls density)\\n- **Scales** — noise frequency, element size, spacing (controls texture)\\n- **Rates** — speed, growth rate, decay (controls energy)\\n- **Thresholds** — when does behavior change? (controls drama)\\n- **Ratios** — proportions, balance between forces (controls harmony)\\n\\n**Bad parameters** are generic controls unrelated to the algorithm:\\n- \\\"color1\\\", \\\"color2\\\", \\\"size\\\" — meaningless without context\\n- Toggle switches for unrelated effects\\n- Parameters that only change cosmetics, not behavior\\n\\nEvery parameter should change how the algorithm *thinks*, not just how it *looks*. A \\\"turbulence\\\" parameter that changes noise octaves is good. A \\\"particle size\\\" slider that only changes `ellipse()` radius is shallow.\\n\\n## Workflow\\n\\n### Step 1: Creative Vision\\n\\nBefore any code, articulate:\\n\\n- **Mood / atmosphere**: What should the viewer feel? Contemplative? Energized? Unsettled? Playful?\\n- **Visual story**: What happens over time (or on interaction)? Build? Decay? Transform? Oscillate?\\n- **Color world**: Warm/cool? Monochrome? Complementary? What's the dominant hue? The accent?\\n- **Shape language**: Organic curves? Sharp geometry? Dots? Lines? Mixed?\\n- **Motion vocabulary**: Slow drift? Explosive burst? Breathing pulse? Mechanical precision?\\n- **What makes THIS different**: What is the one thing that makes this sketch unique?\\n\\nMap the user's prompt to aesthetic choices. \\\"Relaxing generative background\\\" demands different everything from \\\"glitch data visualization.\\\"\\n\\n### Step 2: Technical Design\\n\\n- **Mode** — which of the 7 modes from the table above\\n- **Canvas size** — landscape 1920x1080, portrait 1080x1920, square 1080x1080, or responsive `windowWidth/windowHeight`\\n- **Renderer** — `P2D` (default) or `WEBGL` (for 3D, shaders, advanced blend modes)\\n- **Frame rate** — 60fps (interactive), 30fps (ambient animation), or `noLoop()` (static generative)\\n- **Export target** — browser display, PNG still, GIF loop, MP4 video, SVG vector\\n- **Interaction model** — passive (no input), mouse-driven, keyboard-driven, audio-reactive, scroll-driven\\n- **Viewer UI** — for interactive generative art, start from `templates/viewer.html` which provides seed navigation, parameter sliders, and download. For simple sketches or video export, use bare HTML\\n\\n### Step 3: Code the Sketch\\n\\nFor **interactive generative art** (seed exploration, parameter tuning): start from `templates/viewer.html`. Read the template first, keep the fixed sections (seed nav, actions), replace the algorithm and parameter controls. This gives the user seed prev/next/random/jump, parameter sliders with live update, and PNG download — all wired up.\\n\\nFor **animations, video export, or simple sketches**: use bare HTML:\\n\\nSingle HTML file. Structure:\\n\\n```html\\n<!DOCTYPE html>\\n<html lang=\\\"en\\\">\\n<head>\\n  <meta charset=\\\"UTF-8\\\">\\n  <meta name=\\\"viewport\\\" content=\\\"width=device-width, initial-scale=1.0\\\">\\n  <title>Project Name</title>\\n  <script>p5.disableFriendlyErrors = true;</script>\\n  <script src=\\\"https://cdnjs.cloudflare.com/ajax/libs/p5.js/1.11.3/p5.min.js\\\"></script>\\n  <!-- <script src=\\\"https://cdnjs.cloudflare.com/ajax/libs/p5.js/1.11.3/addons/p5.sound.min.js\\\"></script> -->\\n  <!-- <script src=\\\"https://unpkg.com/p5.js-svg@1.6.0\\\"></script> -->  <!-- SVG export -->\\n  <!-- <script src=\\\"https://cdn.jsdelivr.net/npm/ccapture.js-npmfixed/build/CCapture.all.min.js\\\"></script> -->  <!-- video capture -->\\n  <style>\\n    html, body { margin: 0; padding: 0; overflow: hidden; }\\n    canvas { display: block; }\\n  </style>\\n</head>\\n<body>\\n<script>\\n// === Configuration ===\\nconst CONFIG = {\\n  seed: 42,\\n  // ... project-specific params\\n};\\n\\n// === Color Palette ===\\nconst PALETTE = {\\n  bg: '#0a0a0f',\\n  primary: '#e8d5b7',\\n  // ...\\n};\\n\\n// === Global State ===\\nlet particles = [];\\n\\n// === Preload (fonts, images, data) ===\\nfunction preload() {\\n  // font = loadFont('...');\\n}\\n\\n// === Setup ===\\nfunction setup() {\\n  createCanvas(1920, 1080);\\n  randomSeed(CONFIG.seed);\\n  noiseSeed(CONFIG.seed);\\n  colorMode(HSB, 360, 100, 100, 100);\\n  // Initialize state...\\n}\\n\\n// === Draw Loop ===\\nfunction draw() {\\n  // Render frame...\\n}\\n\\n// === Helper Functions ===\\n// ...\\n\\n// === Classes ===\\nclass Particle {\\n  // ...\\n}\\n\\n// === Event Handlers ===\\nfunction mousePressed() { /* ... */ }\\nfunction keyPressed() { /* ... */ }\\nfunction windowResized() { resizeCanvas(windowWidth, windowHeight); }\\n</script>\\n</body>\\n</html>\\n```\\n\\nKey implementation patterns:\\n- **Seeded randomness**: Always `randomSeed()` + `noiseSeed()` for reproducibility\\n- **Color mode**: Use `colorMode(HSB, 360, 100, 100, 100)` for intuitive color control\\n- **State separation**: CONFIG for parameters, PALETTE for colors, globals for mutable state\\n- **Class-based entities**: Particles, agents, shapes as classes with `update()` + `display()` methods\\n- **Offscreen buffers**: `createGraphics()` for layered composition, trails, masks\\n\\n### Step 4: Preview & Iterate\\n\\n- Open HTML file directly in browser — no server needed for basic sketches\\n- For `loadImage()`/`loadFont()` from local files: use `scripts/serve.sh` or `python3 -m http.server`\\n- Chrome DevTools Performance tab to verify 60fps\\n- Test at target export resolution, not just the window size\\n- Adjust parameters until the visual matches the concept from Step 1\\n\\n### Step 5: Export\\n\\n| Format | Method | Command |\\n|--------|--------|---------|\\n| **PNG** | `saveCanvas('output', 'png')` in `keyPressed()` | Press 's' to save |\\n| **High-res PNG** | Puppeteer headless capture | `node scripts/export-frames.js sketch.html --width 3840 --height 2160 --frames 1` |\\n| **GIF** | `saveGif('output', 5)` — captures N seconds | Press 'g' to save |\\n| **Frame sequence** | `saveFrames('frame', 'png', 10, 30)` — 10s at 30fps | Then `ffmpeg -i frame-%04d.png -c:v libx264 output.mp4` |\\n| **MP4** | Puppeteer frame capture + ffmpeg | `bash scripts/render.sh sketch.html output.mp4 --duration 30 --fps 30` |\\n| **SVG** | `createCanvas(w, h, SVG)` with p5.js-svg | `save('output.svg')` |\\n\\n### Step 6: Quality Verification\\n\\n- **Does it match the vision?** Compare output to the creative concept. If it looks generic, go back to Step 1\\n- **Resolution check**: Is it sharp at the target display size? No aliasing artifacts?\\n- **Performance check**: Does it hold 60fps in browser? (30fps minimum for animations)\\n- **Color check**: Do the colors work together? Test on both light and dark monitors\\n- **Edge cases**: What happens at canvas edges? On resize? After running for 10 minutes?\\n\\n## Critical Implementation Notes\\n\\n### Performance — Disable FES First\\n\\nThe Friendly Error System (FES) adds up to 10x overhead. Disable it in every production sketch:\\n\\n```javascript\\np5.disableFriendlyErrors = true;  // BEFORE setup()\\n\\nfunction setup() {\\n  pixelDensity(1);  // prevent 2x-4x overdraw on retina\\n  createCanvas(1920, 1080);\\n}\\n```\\n\\nIn hot loops (particles, pixel ops), use `Math.*` instead of p5 wrappers — measurably faster:\\n\\n```javascript\\n// In draw() or update() hot paths:\\nlet a = Math.sin(t);          // not sin(t)\\nlet r = Math.sqrt(dx*dx+dy*dy); // not dist() — or better: skip sqrt, compare magSq\\nlet v = Math.random();        // not random() — when seed not needed\\nlet m = Math.min(a, b);       // not min(a, b)\\n```\\n\\nNever `console.log()` inside `draw()`. Never manipulate DOM in `draw()`. See `references/troubleshooting.md` § Performance.\\n\\n### Seeded Randomness — Always\\n\\nEvery generative sketch must be reproducible. Same seed, same output.\\n\\n```javascript\\nfunction setup() {\\n  randomSeed(CONFIG.seed);\\n  noiseSeed(CONFIG.seed);\\n  // All random() and noise() calls now deterministic\\n}\\n```\\n\\nNever use `Math.random()` for generative content — only for performance-critical non-visual code. Always `random()` for visual elements. If you need a random seed: `CONFIG.seed = floor(random(99999))`.\\n\\n### Generative Art Platform Support (fxhash / Art Blocks)\\n\\nFor generative art platforms, replace p5's PRNG with the platform's deterministic random:\\n\\n```javascript\\n// fxhash convention\\nconst SEED = $fx.hash;              // unique per mint\\nconst rng = $fx.rand;               // deterministic PRNG\\n$fx.features({ palette: 'warm', complexity: 'high' });\\n\\n// In setup():\\nrandomSeed(SEED);   // for p5's noise()\\nnoiseSeed(SEED);\\n\\n// Replace random() with rng() for platform determinism\\nlet x = rng() * width;  // instead of random(width)\\n```\\n\\nSee `references/export-pipeline.md` § Platform Export.\\n\\n### Color Mode — Use HSB\\n\\nHSB (Hue, Saturation, Brightness) is dramatically easier to work with than RGB for generative art:\\n\\n```javascript\\ncolorMode(HSB, 360, 100, 100, 100);\\n// Now: fill(hue, sat, bri, alpha)\\n// Rotate hue: fill((baseHue + offset) % 360, 80, 90)\\n// Desaturate: fill(hue, sat * 0.3, bri)\\n// Darken: fill(hue, sat, bri * 0.5)\\n```\\n\\nNever hardcode raw RGB values. Define a palette object, derive variations procedurally. See `references/color-systems.md`.\\n\\n### Noise — Multi-Octave, Not Raw\\n\\nRaw `noise(x, y)` looks like smooth blobs. Layer octaves for natural texture:\\n\\n```javascript\\nfunction fbm(x, y, octaves = 4) {\\n  let val = 0, amp = 1, freq = 1, sum = 0;\\n  for (let i = 0; i < octaves; i++) {\\n    val += noise(x * freq, y * freq) * amp;\\n    sum += amp;\\n    amp *= 0.5;\\n    freq *= 2;\\n  }\\n  return val / sum;\\n}\\n```\\n\\nFor flowing organic forms, use **domain warping**: feed noise output back as noise input coordinates. See `references/visual-effects.md`.\\n\\n### createGraphics() for Layers — Not Optional\\n\\nFlat single-pass rendering looks flat. Use offscreen buffers for composition:\\n\\n```javascript\\nlet bgLayer, fgLayer, trailLayer;\\nfunction setup() {\\n  createCanvas(1920, 1080);\\n  bgLayer = createGraphics(width, height);\\n  fgLayer = createGraphics(width, height);\\n  trailLayer = createGraphics(width, height);\\n}\\nfunction draw() {\\n  renderBackground(bgLayer);\\n  renderTrails(trailLayer);   // persistent, fading\\n  renderForeground(fgLayer);  // cleared each frame\\n  image(bgLayer, 0, 0);\\n  image(trailLayer, 0, 0);\\n  image(fgLayer, 0, 0);\\n}\\n```\\n\\n### Performance — Vectorize Where Possible\\n\\np5.js draw calls are expensive. For thousands of particles:\\n\\n```javascript\\n// SLOW: individual shapes\\nfor (let p of particles) {\\n  ellipse(p.x, p.y, p.size);\\n}\\n\\n// FAST: single shape with beginShape()\\nbeginShape(POINTS);\\nfor (let p of particles) {\\n  vertex(p.x, p.y);\\n}\\nendShape();\\n\\n// FASTEST: pixel buffer for massive counts\\nloadPixels();\\nfor (let p of particles) {\\n  let idx = 4 * (floor(p.y) * width + floor(p.x));\\n  pixels[idx] = r; pixels[idx+1] = g; pixels[idx+2] = b; pixels[idx+3] = 255;\\n}\\nupdatePixels();\\n```\\n\\nSee `references/troubleshooting.md` § Performance.\\n\\n### Instance Mode for Multiple Sketches\\n\\nGlobal mode pollutes `window`. For production, use instance mode:\\n\\n```javascript\\nconst sketch = (p) => {\\n  p.setup = function() {\\n    p.createCanvas(800, 800);\\n  };\\n  p.draw = function() {\\n    p.background(0);\\n    p.ellipse(p.mouseX, p.mouseY, 50);\\n  };\\n};\\nnew p5(sketch, 'canvas-container');\\n```\\n\\nRequired when embedding multiple sketches on one page or integrating with frameworks.\\n\\n### WebGL Mode Gotchas\\n\\n- `createCanvas(w, h, WEBGL)` — origin is center, not top-left\\n- Y-axis is inverted (positive Y goes up in WEBGL, down in P2D)\\n- `translate(-width/2, -height/2)` to get P2D-like coordinates\\n- `push()`/`pop()` around every transform — matrix stack overflows silently\\n- `texture()` before `rect()`/`plane()` — not after\\n- Custom shaders: `createShader(vert, frag)` — test on multiple browsers\\n\\n### Export — Key Bindings Convention\\n\\nEvery sketch should include these in `keyPressed()`:\\n\\n```javascript\\nfunction keyPressed() {\\n  if (key === 's' || key === 'S') saveCanvas('output', 'png');\\n  if (key === 'g' || key === 'G') saveGif('output', 5);\\n  if (key === 'r' || key === 'R') { randomSeed(millis()); noiseSeed(millis()); }\\n  if (key === ' ') CONFIG.paused = !CONFIG.paused;\\n}\\n```\\n\\n### Headless Video Export — Use noLoop()\\n\\nFor headless rendering via Puppeteer, the sketch **must** use `noLoop()` in setup. Without it, p5's draw loop runs freely while screenshots are slow — the sketch races ahead and you get skipped/duplicate frames.\\n\\n```javascript\\nfunction setup() {\\n  createCanvas(1920, 1080);\\n  pixelDensity(1);\\n  noLoop();                    // capture script controls frame advance\\n  window._p5Ready = true;      // signal readiness to capture script\\n}\\n```\\n\\nThe bundled `scripts/export-frames.js` detects `_p5Ready` and calls `redraw()` once per capture for exact 1:1 frame correspondence. See `references/export-pipeline.md` § Deterministic Capture.\\n\\nFor multi-scene videos, use the per-clip architecture: one HTML per scene, render independently, stitch with `ffmpeg -f concat`. See `references/export-pipeline.md` § Per-Clip Architecture.\\n\\n### Agent Workflow\\n\\nWhen building p5.js sketches:\\n\\n1. **Write the HTML file** — single self-contained file, all code inline\\n2. **Open in browser** — `open sketch.html` (macOS) or `xdg-open sketch.html` (Linux)\\n3. **Local assets** (fonts, images) require a server: `python3 -m http.server 8080` in the project directory, then open `http://localhost:8080/sketch.html`\\n4. **Export PNG/GIF** — add `keyPressed()` shortcuts as shown above, tell the user which key to press\\n5. **Headless export** — `node scripts/export-frames.js sketch.html --frames 300` for automated frame capture (sketch must use `noLoop()` + `_p5Ready`)\\n6. **MP4 rendering** — `bash scripts/render.sh sketch.html output.mp4 --duration 30`\\n7. **Iterative refinement** — edit the HTML file, user refreshes browser to see changes\\n8. **Load references on demand** — use `skill_view(name=\\\"p5js\\\", file_path=\\\"references/...\\\")` to load specific reference files as needed during implementation\\n\\n## Performance Targets\\n\\n| Metric | Target |\\n|--------|--------|\\n| Frame rate (interactive) | 60fps sustained |\\n| Frame rate (animated export) | 30fps minimum |\\n| Particle count (P2D shapes) | 5,000-10,000 at 60fps |\\n| Particle count (pixel buffer) | 50,000-100,000 at 60fps |\\n| Canvas resolution | Up to 3840x2160 (export), 1920x1080 (interactive) |\\n| File size (HTML) | < 100KB (excluding CDN libraries) |\\n| Load time | < 2s to first frame |\\n\\n## References\\n\\n| File | Contents |\\n|------|----------|\\n| `references/core-api.md` | Canvas setup, coordinate system, draw loop, `push()`/`pop()`, offscreen buffers, composition patterns, `pixelDensity()`, responsive design |\\n| `references/shapes-and-geometry.md` | 2D primitives, `beginShape()`/`endShape()`, Bezier/Catmull-Rom curves, `vertex()` systems, custom shapes, `p5.Vector`, signed distance fields, SVG path conversion |\\n| `references/visual-effects.md` | Noise (Perlin, fractal, domain warp, curl), flow fields, particle systems (physics, flocking, trails), pixel manipulation, texture generation (stipple, hatch, halftone), feedback loops, reaction-diffusion |\\n| `references/animation.md` | Frame-based animation, easing functions, `lerp()`/`map()`, spring physics, state machines, timeline sequencing, `millis()`-based timing, transition patterns |\\n| `references/typography.md` | `text()`, `loadFont()`, `textToPoints()`, kinetic typography, text masks, font metrics, responsive text sizing |\\n| `references/color-systems.md` | `colorMode()`, HSB/HSL/RGB, `lerpColor()`, `paletteLerp()`, procedural palettes, color harmony, `blendMode()`, gradient rendering, curated palette library |\\n| `references/webgl-and-3d.md` | WEBGL renderer, 3D primitives, camera, lighting, materials, custom geometry, GLSL shaders (`createShader()`, `createFilterShader()`), framebuffers, post-processing |\\n| `references/interaction.md` | Mouse events, keyboard state, touch input, DOM elements, `createSlider()`/`createButton()`, audio input (p5.sound FFT/amplitude), scroll-driven animation, responsive events |\\n| `references/export-pipeline.md` | `saveCanvas()`, `saveGif()`, `saveFrames()`, deterministic headless capture, ffmpeg frame-to-video, CCapture.js, SVG export, per-clip architecture, platform export (fxhash), video gotchas |\\n| `references/troubleshooting.md` | Performance profiling, per-pixel budgets, common mistakes, browser compatibility, WebGL debugging, font loading issues, pixel density traps, memory leaks, CORS |\\n| `templates/viewer.html` | Interactive viewer template: seed navigation (prev/next/random/jump), parameter sliders, download PNG, responsive canvas. Start from this for explorable generative art |\\n\\n---\\n\\n## Creative Divergence (use only when user requests experimental/creative/unique output)\\n\\nIf the user asks for creative, experimental, surprising, or unconventional output, select the strategy that best fits and reason through its steps BEFORE generating code.\\n\\n- **Conceptual Blending** — when the user names two things to combine or wants hybrid aesthetics\\n- **SCAMPER** — when the user wants a twist on a known generative art pattern\\n- **Distance Association** — when the user gives a single concept and wants exploration (\\\"make something about time\\\")\\n\\n### Conceptual Blending\\n1. Name two distinct visual systems (e.g., particle physics + handwriting)\\n2. Map correspondences (particles = ink drops, forces = pen pressure, fields = letterforms)\\n3. Blend selectively — keep mappings that produce interesting emergent visuals\\n4. Code the blend as a unified system, not two systems side-by-side\\n\\n### SCAMPER Transformation\\nTake a known generative pattern (flow field, particle system, L-system, cellular automata) and systematically transform it:\\n- **Substitute**: replace circles with text characters, lines with gradients\\n- **Combine**: merge two patterns (flow field + voronoi)\\n- **Adapt**: apply a 2D pattern to a 3D projection\\n- **Modify**: exaggerate scale, warp the coordinate space\\n- **Purpose**: use a physics sim for typography, a sorting algorithm for color\\n- **Eliminate**: remove the grid, remove color, remove symmetry\\n- **Reverse**: run the simulation backward, invert the parameter space\\n\\n### Distance Association\\n1. Anchor on the user's concept (e.g., \\\"loneliness\\\")\\n2. Generate associations at three distances:\\n   - Close (obvious): empty room, single figure, silence\\n   - Medium (interesting): one fish in a school swimming the wrong way, a phone with no notifications, the gap between subway cars\\n   - Far (abstract): prime numbers, asymptotic curves, the color of 3am\\n3. Develop the medium-distance associations — they're specific enough to visualize but unexpected enough to be interesting\\n\", \"path\": \"creative/p5js/SKILL.md\", \"skill_dir\": \"/home/kuhnn/.hermes/skills/creative/p5js\", \"linked_files\": {\"references\": [\"references/interaction.md\", \"references/webgl-and-3d.md\", \"references/visual-effects.md\", \"references/core-api.md\", \"references/typography.md\", \"references/color-systems.md\", \"references/export-pipeline.md\", \"references/troubleshooting.md\", \"references/animation.md\", \"references/shapes-and-geometry.md\"], \"scripts\": [\"scripts/render.sh\", \"scripts/serve.sh\", \"scripts/setup.sh\", \"scripts/export-frames.js\"]}, \"usage_hint\": \"To view linked files, call skill_view(name, file_path) where file_path is e.g. 'references/api.md' or 'assets/config.yaml'\", \"required_environment_variables\": [], \"required_commands\": [], \"missing_required_environment_variables\": [], \"missing_credential_files\": [], \"missing_required_commands\": [], \"setup_needed\": false, \"setup_skipped\": false, \"readiness_status\": \"available\", \"metadata\": {\"hermes\": {\"tags\": [\"creative-coding\", \"generative-art\", \"p5js\", \"canvas\", \"interactive\", \"visualization\", \"webgl\", \"shaders\", \"animation\"], \"related_skills\": [\"ascii-video\", \"manim-video\", \"excalidraw\"]}}}",
      "tool_call_id": "call_function_534pqwv2ijh0_9"
    },
    {
      "role": "tool",
      "name": "skill_view",
      "content": "{\"success\": false, \"error\": \"Ambiguous skill name 'pixel-art': 2 skills match across your local skills dir and external_dirs. Refusing to guess — load one explicitly by its categorized path.\", \"matches\": [\"/home/kuhnn/.hermes/skills/creative/pixel-art/SKILL.md\", \"/home/kuhnn/.hermes/skills/creative/baoyu-infographic/references/styles/pixel-art.md\"], \"hint\": \"Pass the full relative path instead of the bare name (e.g., 'category/skill-name'), or rename one of the colliding skills so each name is unique.\"}",
      "tool_call_id": "call_function_534pqwv2ijh0_10"
    },
    {
      "role": "assistant",
      "content": "",
      "reasoning": "I need to load the remaining skills. Let me continue with the rest of the list. I still need to load:\n- pixel-art (need full path)\n- popular-web-designs\n- pretext\n- sketch\n- songwriting-and-ai-music\n- touchdesigner-mcp\n- jupyter-live-kernel\n- kanban-orchestrator\n- kanban-worker\n- webhook-subscriptions\n- himalaya\n- minecraft-modpack-server\n- pokemon-player\n- codebase-inspection\n- github-auth\n- github-code-review\n- github-issues\n- github-pr-workflow\n- github-repo-management\n- native-mcp\n- gif-search\n- heartmula\n- songsee\n\nAnd I notice that ideation skill returned an error. \n\nI'll go ahead and load all the remaining ones in parallel to get the full picture.",
      "finish_reason": "tool_calls",
      "reasoning_content": "I need to load the remaining skills. Let me continue with the rest of the list. I still need to load:\n- pixel-art (need full path)\n- popular-web-designs\n- pretext\n- sketch\n- songwriting-and-ai-music\n- touchdesigner-mcp\n- jupyter-live-kernel\n- kanban-orchestrator\n- kanban-worker\n- webhook-subscriptions\n- himalaya\n- minecraft-modpack-server\n- pokemon-player\n- codebase-inspection\n- github-auth\n- github-code-review\n- github-issues\n- github-pr-workflow\n- github-repo-management\n- native-mcp\n- gif-search\n- heartmula\n- songsee\n\nAnd I notice that ideation skill returned an error. \n\nI'll go ahead and load all the remaining ones in parallel to get the full picture.",
      "reasoning_details": [
        {
          "signature": "2face675a4b8fdf8eed1fe5c503f4ebdb20776dd912d59d540237fa73e98137c",
          "thinking": "I need to load the remaining skills. Let me continue with the rest of the list. I still need to load:\n- pixel-art (need full path)\n- popular-web-designs\n- pretext\n- sketch\n- songwriting-and-ai-music\n- touchdesigner-mcp\n- jupyter-live-kernel\n- kanban-orchestrator\n- kanban-worker\n- webhook-subscriptions\n- himalaya\n- minecraft-modpack-server\n- pokemon-player\n- codebase-inspection\n- github-auth\n- github-code-review\n- github-issues\n- github-pr-workflow\n- github-repo-management\n- native-mcp\n- gif-search\n- heartmula\n- songsee\n\nAnd I notice that ideation skill returned an error. \n\nI'll go ahead and load all the remaining ones in parallel to get the full picture.",
          "type": "thinking"
        }
      ],
      "tool_calls": [
        {
          "id": "call_function_482zhhlnflgr_1",
          "call_id": "call_function_482zhhlnflgr_1",
          "response_item_id": "fc_function_482zhhlnflgr_1",
          "type": "function",
          "function": {
            "name": "skill_view",
            "arguments": "{\"name\": \"creative/pixel-art\"}"
          }
        },
        {
          "id": "call_function_482zhhlnflgr_2",
          "call_id": "call_function_482zhhlnflgr_2",
          "response_item_id": "fc_function_482zhhlnflgr_2",
          "type": "function",
          "function": {
            "name": "skill_view",
            "arguments": "{\"name\": \"popular-web-designs\"}"
          }
        },
        {
          "id": "call_function_482zhhlnflgr_3",
          "call_id": "call_function_482zhhlnflgr_3",
          "response_item_id": "fc_function_482zhhlnflgr_3",
          "type": "function",
          "function": {
            "name": "skill_view",
            "arguments": "{\"name\": \"pretext\"}"
          }
        },
        {
          "id": "call_function_482zhhlnflgr_4",
          "call_id": "call_function_482zhhlnflgr_4",
          "response_item_id": "fc_function_482zhhlnflgr_4",
          "type": "function",
          "function": {
            "name": "skill_view",
            "arguments": "{\"name\": \"sketch\"}"
          }
        },
        {
          "id": "call_function_482zhhlnflgr_5",
          "call_id": "call_function_482zhhlnflgr_5",
          "response_item_id": "fc_function_482zhhlnflgr_5",
          "type": "function",
          "function": {
            "name": "skill_view",
            "arguments": "{\"name\": \"songwriting-and-ai-music\"}"
          }
        },
        {
          "id": "call_function_482zhhlnflgr_6",
          "call_id": "call_function_482zhhlnflgr_6",
          "response_item_id": "fc_function_482zhhlnflgr_6",
          "type": "function",
          "function": {
            "name": "skill_view",
            "arguments": "{\"name\": \"touchdesigner-mcp\"}"
          }
        },
        {
          "id": "call_function_482zhhlnflgr_7",
          "call_id": "call_function_482zhhlnflgr_7",
          "response_item_id": "fc_function_482zhhlnflgr_7",
          "type": "function",
          "function": {
            "name": "skill_view",
            "arguments": "{\"name\": \"jupyter-live-kernel\"}"
          }
        },
        {
          "id": "call_function_482zhhlnflgr_8",
          "call_id": "call_function_482zhhlnflgr_8",
          "response_item_id": "fc_function_482zhhlnflgr_8",
          "type": "function",
          "function": {
            "name": "skill_view",
            "arguments": "{\"name\": \"kanban-orchestrator\"}"
          }
        },
        {
          "id": "call_function_482zhhlnflgr_9",
          "call_id": "call_function_482zhhlnflgr_9",
          "response_item_id": "fc_function_482zhhlnflgr_9",
          "type": "function",
          "function": {
            "name": "skill_view",
            "arguments": "{\"name\": \"kanban-worker\"}"
          }
        },
        {
          "id": "call_function_482zhhlnflgr_10",
          "call_id": "call_function_482zhhlnflgr_10",
          "response_item_id": "fc_function_482zhhlnflgr_10",
          "type": "function",
          "function": {
            "name": "skill_view",
            "arguments": "{\"name\": \"webhook-subscriptions\"}"
          }
        }
      ]
    },
    {
      "role": "tool",
      "name": "skill_view",
      "content": "{\"success\": true, \"name\": \"pixel-art\", \"description\": \"Pixel art w/ era palettes (NES, Game Boy, PICO-8).\", \"tags\": [\"creative\", \"pixel-art\", \"arcade\", \"snes\", \"nes\", \"gameboy\", \"retro\", \"image\", \"video\"], \"related_skills\": [], \"content\": \"---\\nname: pixel-art\\ndescription: \\\"Pixel art w/ era palettes (NES, Game Boy, PICO-8).\\\"\\nversion: 2.0.0\\nauthor: dodo-reach\\nlicense: MIT\\nplatforms: [linux, macos, windows]\\nmetadata:\\n  hermes:\\n    tags: [creative, pixel-art, arcade, snes, nes, gameboy, retro, image, video]\\n    category: creative\\n    credits:\\n      - \\\"Hardware palettes and animation loops ported from Synero/pixel-art-studio (MIT) — https://github.com/Synero/pixel-art-studio\\\"\\n---\\n\\n# Pixel Art\\n\\nConvert any image into retro pixel art, then optionally animate it into a short\\nMP4 or GIF with era-appropriate effects (rain, fireflies, snow, embers).\\n\\nTwo scripts ship with this skill:\\n\\n- `scripts/pixel_art.py` — photo → pixel-art PNG (Floyd-Steinberg dithering)\\n- `scripts/pixel_art_video.py` — pixel-art PNG → animated MP4 (+ optional GIF)\\n\\nEach is importable or runnable directly. Presets snap to hardware palettes\\nwhen you want era-accurate colors (NES, Game Boy, PICO-8, etc.), or use\\nadaptive N-color quantization for arcade/SNES-style looks.\\n\\n## When to Use\\n\\n- User wants retro pixel art from a source image\\n- User asks for NES / Game Boy / PICO-8 / C64 / arcade / SNES styling\\n- User wants a short looping animation (rain scene, night sky, snow, etc.)\\n- Posters, album covers, social posts, sprites, characters, avatars\\n\\n## Workflow\\n\\nBefore generating, confirm the style with the user. Different presets produce\\nvery different outputs and regenerating is costly.\\n\\n### Step 1 — Offer a style\\n\\nCall `clarify` with 4 representative presets. Pick the set based on what the\\nuser asked for — don't just dump all 14.\\n\\nDefault menu when the user's intent is unclear:\\n\\n```python\\nclarify(\\n    question=\\\"Which pixel-art style do you want?\\\",\\n    choices=[\\n        \\\"arcade — bold, chunky 80s cabinet feel (16 colors, 8px)\\\",\\n        \\\"nes — Nintendo 8-bit hardware palette (54 colors, 8px)\\\",\\n        \\\"gameboy — 4-shade green Game Boy DMG\\\",\\n        \\\"snes — cleaner 16-bit look (32 colors, 4px)\\\",\\n    ],\\n)\\n```\\n\\nWhen the user already named an era (e.g. \\\"80s arcade\\\", \\\"Gameboy\\\"), skip\\n`clarify` and use the matching preset directly.\\n\\n### Step 2 — Offer animation (optional)\\n\\nIf the user asked for a video/GIF, or the output might benefit from motion,\\nask which scene:\\n\\n```python\\nclarify(\\n    question=\\\"Want to animate it? Pick a scene or skip.\\\",\\n    choices=[\\n        \\\"night — stars + fireflies + leaves\\\",\\n        \\\"urban — rain + neon pulse\\\",\\n        \\\"snow — falling snowflakes\\\",\\n        \\\"skip — just the image\\\",\\n    ],\\n)\\n```\\n\\nDo NOT call `clarify` more than twice in a row. One for style, one for scene if\\nanimation is on the table. If the user explicitly asked for a specific style\\nand scene in their message, skip `clarify` entirely.\\n\\n### Step 3 — Generate\\n\\nRun `pixel_art()` first; if animation was requested, chain into\\n`pixel_art_video()` on the result.\\n\\n## Preset Catalog\\n\\n| Preset | Era | Palette | Block | Best for |\\n|--------|-----|---------|-------|----------|\\n| `arcade` | 80s arcade | adaptive 16 | 8px | Bold posters, hero art |\\n| `snes` | 16-bit | adaptive 32 | 4px | Characters, detailed scenes |\\n| `nes` | 8-bit | NES (54) | 8px | True NES look |\\n| `gameboy` | DMG handheld | 4 green shades | 8px | Monochrome Game Boy |\\n| `gameboy_pocket` | Pocket handheld | 4 grey shades | 8px | Mono GB Pocket |\\n| `pico8` | PICO-8 | 16 fixed | 6px | Fantasy-console look |\\n| `c64` | Commodore 64 | 16 fixed | 8px | 8-bit home computer |\\n| `apple2` | Apple II hi-res | 6 fixed | 10px | Extreme retro, 6 colors |\\n| `teletext` | BBC Teletext | 8 pure | 10px | Chunky primary colors |\\n| `mspaint` | Windows MS Paint | 24 fixed | 8px | Nostalgic desktop |\\n| `mono_green` | CRT phosphor | 2 green | 6px | Terminal/CRT aesthetic |\\n| `mono_amber` | CRT amber | 2 amber | 6px | Amber monitor look |\\n| `neon` | Cyberpunk | 10 neons | 6px | Vaporwave/cyber |\\n| `pastel` | Soft pastel | 10 pastels | 6px | Kawaii / gentle |\\n\\nNamed palettes live in `scripts/palettes.py` (see `references/palettes.md` for\\nthe complete list — 28 named palettes total). Any preset can be overridden:\\n\\n```python\\npixel_art(\\\"in.png\\\", \\\"out.png\\\", preset=\\\"snes\\\", palette=\\\"PICO_8\\\", block=6)\\n```\\n\\n## Scene Catalog (for video)\\n\\n| Scene | Effects |\\n|-------|---------|\\n| `night` | Twinkling stars + fireflies + drifting leaves |\\n| `dusk` | Fireflies + sparkles |\\n| `tavern` | Dust motes + warm sparkles |\\n| `indoor` | Dust motes |\\n| `urban` | Rain + neon pulse |\\n| `nature` | Leaves + fireflies |\\n| `magic` | Sparkles + fireflies |\\n| `storm` | Rain + lightning |\\n| `underwater` | Bubbles + light sparkles |\\n| `fire` | Embers + sparkles |\\n| `snow` | Snowflakes + sparkles |\\n| `desert` | Heat shimmer + dust |\\n\\n## Invocation Patterns\\n\\n### Python (import)\\n\\n```python\\nimport sys\\nsys.path.insert(0, \\\"/home/teknium/.hermes/skills/creative/pixel-art/scripts\\\")\\nfrom pixel_art import pixel_art\\nfrom pixel_art_video import pixel_art_video\\n\\n# 1. Convert to pixel art\\npixel_art(\\\"/path/to/photo.jpg\\\", \\\"/tmp/pixel.png\\\", preset=\\\"nes\\\")\\n\\n# 2. Animate (optional)\\npixel_art_video(\\n    \\\"/tmp/pixel.png\\\",\\n    \\\"/tmp/pixel.mp4\\\",\\n    scene=\\\"night\\\",\\n    duration=6,\\n    fps=15,\\n    seed=42,\\n    export_gif=True,\\n)\\n```\\n\\n### CLI\\n\\n```bash\\ncd /home/teknium/.hermes/skills/creative/pixel-art/scripts\\n\\npython pixel_art.py in.jpg out.png --preset gameboy\\npython pixel_art.py in.jpg out.png --preset snes --palette PICO_8 --block 6\\n\\npython pixel_art_video.py out.png out.mp4 --scene night --duration 6 --gif\\n```\\n\\n## Pipeline Rationale\\n\\n**Pixel conversion:**\\n1. Boost contrast/color/sharpness (stronger for smaller palettes)\\n2. Posterize to simplify tonal regions before quantization\\n3. Downscale by `block` with `Image.NEAREST` (hard pixels, no interpolation)\\n4. Quantize with Floyd-Steinberg dithering — against either an adaptive\\n   N-color palette OR a named hardware palette\\n5. Upscale back with `Image.NEAREST`\\n\\nQuantizing AFTER downscale keeps dithering aligned with the final pixel grid.\\nQuantizing before would waste error-diffusion on detail that disappears.\\n\\n**Video overlay:**\\n- Copies the base frame each tick (static background)\\n- Overlays stateless-per-frame particle draws (one function per effect)\\n- Encodes via ffmpeg `libx264 -pix_fmt yuv420p -crf 18`\\n- Optional GIF via `palettegen` + `paletteuse`\\n\\n## Dependencies\\n\\n- Python 3.9+\\n- Pillow (`pip install Pillow`)\\n- ffmpeg on PATH (only needed for video — Hermes installs package this)\\n\\n## Pitfalls\\n\\n- Pallet keys are case-sensitive (`\\\"NES\\\"`, `\\\"PICO_8\\\"`, `\\\"GAMEBOY_ORIGINAL\\\"`).\\n- Very small sources (<100px wide) collapse under 8-10px blocks. Upscale the\\n  source first if it's tiny.\\n- Fractional `block` or `palette` will break quantization — keep them positive ints.\\n- Animation particle counts are tuned for ~640x480 canvases. On very large\\n  images you may want a second pass with a different seed for density.\\n- `mono_green` / `mono_amber` force `color=0.0` (desaturate). If you override\\n  and keep chroma, the 2-color palette can produce stripes on smooth regions.\\n- `clarify` loop: call it at most twice per turn (style, then scene). Don't\\n  pepper the user with more picks.\\n\\n## Verification\\n\\n- PNG is created at the output path\\n- Clear square pixel blocks visible at the preset's block size\\n- Color count matches preset (eyeball the image or run `Image.open(p).getcolors()`)\\n- Video is a valid MP4 (`ffprobe` can open it) with non-zero size\\n\\n## Attribution\\n\\nNamed hardware palettes and the procedural animation loops in `pixel_art_video.py`\\nare ported from [pixel-art-studio](https://github.com/Synero/pixel-art-studio)\\n(MIT). See `ATTRIBUTION.md` in this skill directory for details.\\n\", \"path\": \"creative/pixel-art/SKILL.md\", \"skill_dir\": \"/home/kuhnn/.hermes/skills/creative/pixel-art\", \"linked_files\": {\"references\": [\"references/palettes.md\"], \"scripts\": [\"scripts/__init__.py\", \"scripts/pixel_art_video.py\", \"scripts/pixel_art.py\", \"scripts/palettes.py\"]}, \"usage_hint\": \"To view linked files, call skill_view(name, file_path) where file_path is e.g. 'references/api.md' or 'assets/config.yaml'\", \"required_environment_variables\": [], \"required_commands\": [], \"missing_required_environment_variables\": [], \"missing_credential_files\": [], \"missing_required_commands\": [], \"setup_needed\": false, \"setup_skipped\": false, \"readiness_status\": \"available\", \"metadata\": {\"hermes\": {\"tags\": [\"creative\", \"pixel-art\", \"arcade\", \"snes\", \"nes\", \"gameboy\", \"retro\", \"image\", \"video\"], \"category\": \"creative\", \"credits\": [\"Hardware palettes and animation loops ported from Synero/pixel-art-studio (MIT) — https://github.com/Synero/pixel-art-studio\"]}}}",
      "tool_call_id": "call_function_482zhhlnflgr_1"
    },
    {
      "role": "tool",
      "name": "skill_view",
      "content": "{\"success\": true, \"name\": \"popular-web-designs\", \"description\": \"54 real design systems (Stripe, Linear, Vercel) as HTML/CSS.\", \"tags\": [\"design\", \"css\", \"html\", \"ui\", \"web-development\", \"design-systems\", \"templates\"], \"related_skills\": [], \"content\": \"---\\nname: popular-web-designs\\ndescription: 54 real design systems (Stripe, Linear, Vercel) as HTML/CSS.\\nversion: 1.0.0\\nauthor: Hermes Agent + Teknium (design systems sourced from VoltAgent/awesome-design-md)\\nlicense: MIT\\ntags: [design, css, html, ui, web-development, design-systems, templates]\\nplatforms: [linux, macos, windows]\\ntriggers:\\n  - build a page that looks like\\n  - make it look like stripe\\n  - design like linear\\n  - vercel style\\n  - create a UI\\n  - web design\\n  - landing page\\n  - dashboard design\\n  - website styled like\\n---\\n\\n# Popular Web Designs\\n\\n54 real-world design systems ready for use when generating HTML/CSS. Each template captures a\\nsite's complete visual language: color palette, typography hierarchy, component styles, spacing\\nsystem, shadows, responsive behavior, and practical agent prompts with exact CSS values.\\n\\n## Related design skills\\n\\n- **`claude-design`** — use for the design *process and taste* (scoping a brief,\\n  producing variants, verifying a local HTML artifact, avoiding AI-design slop).\\n  Pair it with this skill when the user wants a thoughtfully-designed page styled\\n  after a known brand: `claude-design` drives the workflow, this skill supplies\\n  the visual vocabulary.\\n- **`design-md`** — use when the deliverable is a formal DESIGN.md token spec\\n  file, not a rendered artifact.\\n\\n## How to Use\\n\\n1. Pick a design from the catalog below\\n2. Load it: `skill_view(name=\\\"popular-web-designs\\\", file_path=\\\"templates/<site>.md\\\")`\\n3. Use the design tokens and component specs when generating HTML\\n4. Pair with the `generative-widgets` skill to serve the result via cloudflared tunnel\\n\\nEach template includes a **Hermes Implementation Notes** block at the top with:\\n- CDN font substitute and Google Fonts `<link>` tag (ready to paste)\\n- CSS font-family stacks for primary and monospace\\n- Reminders to use `write_file` for HTML creation and `browser_vision` for verification\\n\\n## HTML Generation Pattern\\n\\n```html\\n<!DOCTYPE html>\\n<html lang=\\\"en\\\">\\n<head>\\n  <meta charset=\\\"UTF-8\\\">\\n  <meta name=\\\"viewport\\\" content=\\\"width=device-width, initial-scale=1.0\\\">\\n  <title>Page Title</title>\\n  <!-- Paste the Google Fonts <link> from the template's Hermes notes -->\\n  <link href=\\\"https://fonts.googleapis.com/css2?family=...\\\" rel=\\\"stylesheet\\\">\\n  <style>\\n    /* Apply the template's color palette as CSS custom properties */\\n    :root {\\n      --color-bg: #ffffff;\\n      --color-text: #171717;\\n      --color-accent: #533afd;\\n      /* ... more from template Section 2 */\\n    }\\n    /* Apply typography from template Section 3 */\\n    body {\\n      font-family: 'Inter', system-ui, sans-serif;\\n      color: var(--color-text);\\n      background: var(--color-bg);\\n    }\\n    /* Apply component styles from template Section 4 */\\n    /* Apply layout from template Section 5 */\\n    /* Apply shadows from template Section 6 */\\n  </style>\\n</head>\\n<body>\\n  <!-- Build using component specs from the template -->\\n</body>\\n</html>\\n```\\n\\nWrite the file with `write_file`, serve with the `generative-widgets` workflow (cloudflared tunnel),\\nand verify the result with `browser_vision` to confirm visual accuracy.\\n\\n## Font Substitution Reference\\n\\nMost sites use proprietary fonts unavailable via CDN. Each template maps to a Google Fonts\\nsubstitute that preserves the design's character. Common mappings:\\n\\n| Proprietary Font | CDN Substitute | Character |\\n|---|---|---|\\n| Geist / Geist Sans | Geist (on Google Fonts) | Geometric, compressed tracking |\\n| Geist Mono | Geist Mono (on Google Fonts) | Clean monospace, ligatures |\\n| sohne-var (Stripe) | Source Sans 3 | Light weight elegance |\\n| Berkeley Mono | JetBrains Mono | Technical monospace |\\n| Airbnb Cereal VF | DM Sans | Rounded, friendly geometric |\\n| Circular (Spotify) | DM Sans | Geometric, warm |\\n| figmaSans | Inter | Clean humanist |\\n| Pin Sans (Pinterest) | DM Sans | Friendly, rounded |\\n| NVIDIA-EMEA | Inter (or Arial system) | Industrial, clean |\\n| CoinbaseDisplay/Sans | DM Sans | Geometric, trustworthy |\\n| UberMove | DM Sans | Bold, tight |\\n| HashiCorp Sans | Inter | Enterprise, neutral |\\n| waldenburgNormal (Sanity) | Space Grotesk | Geometric, slightly condensed |\\n| IBM Plex Sans/Mono | IBM Plex Sans/Mono | Available on Google Fonts |\\n| Rubik (Sentry) | Rubik | Available on Google Fonts |\\n\\nWhen a template's CDN font matches the original (Inter, IBM Plex, Rubik, Geist), no\\nsubstitution loss occurs. When a substitute is used (DM Sans for Circular, Source Sans 3\\nfor sohne-var), follow the template's weight, size, and letter-spacing values closely —\\nthose carry more visual identity than the specific font face.\\n\\n## Design Catalog\\n\\n### AI & Machine Learning\\n\\n| Template | Site | Style |\\n|---|---|---|\\n| `claude.md` | Anthropic Claude | Warm terracotta accent, clean editorial layout |\\n| `cohere.md` | Cohere | Vibrant gradients, data-rich dashboard aesthetic |\\n| `elevenlabs.md` | ElevenLabs | Dark cinematic UI, audio-waveform aesthetics |\\n| `minimax.md` | Minimax | Bold dark interface with neon accents |\\n| `mistral.ai.md` | Mistral AI | French-engineered minimalism, purple-toned |\\n| `ollama.md` | Ollama | Terminal-first, monochrome simplicity |\\n| `opencode.ai.md` | OpenCode AI | Developer-centric dark theme, full monospace |\\n| `replicate.md` | Replicate | Clean white canvas, code-forward |\\n| `runwayml.md` | RunwayML | Cinematic dark UI, media-rich layout |\\n| `together.ai.md` | Together AI | Technical, blueprint-style design |\\n| `voltagent.md` | VoltAgent | Void-black canvas, emerald accent, terminal-native |\\n| `x.ai.md` | xAI | Stark monochrome, futuristic minimalism, full monospace |\\n\\n### Developer Tools & Platforms\\n\\n| Template | Site | Style |\\n|---|---|---|\\n| `cursor.md` | Cursor | Sleek dark interface, gradient accents |\\n| `expo.md` | Expo | Dark theme, tight letter-spacing, code-centric |\\n| `linear.app.md` | Linear | Ultra-minimal dark-mode, precise, purple accent |\\n| `lovable.md` | Lovable | Playful gradients, friendly dev aesthetic |\\n| `mintlify.md` | Mintlify | Clean, green-accented, reading-optimized |\\n| `posthog.md` | PostHog | Playful branding, developer-friendly dark UI |\\n| `raycast.md` | Raycast | Sleek dark chrome, vibrant gradient accents |\\n| `resend.md` | Resend | Minimal dark theme, monospace accents |\\n| `sentry.md` | Sentry | Dark dashboard, data-dense, pink-purple accent |\\n| `supabase.md` | Supabase | Dark emerald theme, code-first developer tool |\\n| `superhuman.md` | Superhuman | Premium dark UI, keyboard-first, purple glow |\\n| `vercel.md` | Vercel | Black and white precision, Geist font system |\\n| `warp.md` | Warp | Dark IDE-like interface, block-based command UI |\\n| `zapier.md` | Zapier | Warm orange, friendly illustration-driven |\\n\\n### Infrastructure & Cloud\\n\\n| Template | Site | Style |\\n|---|---|---|\\n| `clickhouse.md` | ClickHouse | Yellow-accented, technical documentation style |\\n| `composio.md` | Composio | Modern dark with colorful integration icons |\\n| `hashicorp.md` | HashiCorp | Enterprise-clean, black and white |\\n| `mongodb.md` | MongoDB | Green leaf branding, developer documentation focus |\\n| `sanity.md` | Sanity | Red accent, content-first editorial layout |\\n| `stripe.md` | Stripe | Signature purple gradients, weight-300 elegance |\\n\\n### Design & Productivity\\n\\n| Template | Site | Style |\\n|---|---|---|\\n| `airtable.md` | Airtable | Colorful, friendly, structured data aesthetic |\\n| `cal.md` | Cal.com | Clean neutral UI, developer-oriented simplicity |\\n| `clay.md` | Clay | Organic shapes, soft gradients, art-directed layout |\\n| `figma.md` | Figma | Vibrant multi-color, playful yet professional |\\n| `framer.md` | Framer | Bold black and blue, motion-first, design-forward |\\n| `intercom.md` | Intercom | Friendly blue palette, conversational UI patterns |\\n| `miro.md` | Miro | Bright yellow accent, infinite canvas aesthetic |\\n| `notion.md` | Notion | Warm minimalism, serif headings, soft surfaces |\\n| `pinterest.md` | Pinterest | Red accent, masonry grid, image-first layout |\\n| `webflow.md` | Webflow | Blue-accented, polished marketing site aesthetic |\\n\\n### Fintech & Crypto\\n\\n| Template | Site | Style |\\n|---|---|---|\\n| `coinbase.md` | Coinbase | Clean blue identity, trust-focused, institutional feel |\\n| `kraken.md` | Kraken | Purple-accented dark UI, data-dense dashboards |\\n| `revolut.md` | Revolut | Sleek dark interface, gradient cards, fintech precision |\\n| `wise.md` | Wise | Bright green accent, friendly and clear |\\n\\n### Enterprise & Consumer\\n\\n| Template | Site | Style |\\n|---|---|---|\\n| `airbnb.md` | Airbnb | Warm coral accent, photography-driven, rounded UI |\\n| `apple.md` | Apple | Premium white space, SF Pro, cinematic imagery |\\n| `bmw.md` | BMW | Dark premium surfaces, precise engineering aesthetic |\\n| `ibm.md` | IBM | Carbon design system, structured blue palette |\\n| `nvidia.md` | NVIDIA | Green-black energy, technical power aesthetic |\\n| `spacex.md` | SpaceX | Stark black and white, full-bleed imagery, futuristic |\\n| `spotify.md` | Spotify | Vibrant green on dark, bold type, album-art-driven |\\n| `uber.md` | Uber | Bold black and white, tight type, urban energy |\\n\\n## Choosing a Design\\n\\nMatch the design to the content:\\n\\n- **Developer tools / dashboards:** Linear, Vercel, Supabase, Raycast, Sentry\\n- **Documentation / content sites:** Mintlify, Notion, Sanity, MongoDB\\n- **Marketing / landing pages:** Stripe, Framer, Apple, SpaceX\\n- **Dark mode UIs:** Linear, Cursor, ElevenLabs, Warp, Superhuman\\n- **Light / clean UIs:** Vercel, Stripe, Notion, Cal.com, Replicate\\n- **Playful / friendly:** PostHog, Figma, Lovable, Zapier, Miro\\n- **Premium / luxury:** Apple, BMW, Stripe, Superhuman, Revolut\\n- **Data-dense / dashboards:** Sentry, Kraken, Cohere, ClickHouse\\n- **Monospace / terminal aesthetic:** Ollama, OpenCode, x.ai, VoltAgent\", \"path\": \"creative/popular-web-designs/SKILL.md\", \"skill_dir\": \"/home/kuhnn/.hermes/skills/creative/popular-web-designs\", \"linked_files\": {\"templates\": [\"templates/apple.md\", \"templates/replicate.md\", \"templates/nvidia.md\", \"templates/together.ai.md\", \"templates/miro.md\", \"templates/opencode.ai.md\", \"templates/mongodb.md\", \"templates/clay.md\", \"templates/posthog.md\", \"templates/mistral.ai.md\", \"templates/intercom.md\", \"templates/wise.md\", \"templates/stripe.md\", \"templates/vercel.md\", \"templates/claude.md\", \"templates/superhuman.md\", \"templates/composio.md\", \"templates/airtable.md\", \"templates/hashicorp.md\", \"templates/lovable.md\", \"templates/clickhouse.md\", \"templates/minimax.md\", \"templates/x.ai.md\", \"templates/framer.md\", \"templates/ollama.md\", \"templates/figma.md\", \"templates/webflow.md\", \"templates/airbnb.md\", \"templates/revolut.md\", \"templates/ibm.md\", \"templates/cohere.md\", \"templates/supabase.md\", \"templates/runwayml.md\", \"templates/kraken.md\", \"templates/pinterest.md\", \"templates/resend.md\", \"templates/bmw.md\", \"templates/sentry.md\", \"templates/spacex.md\", \"templates/zapier.md\", \"templates/notion.md\", \"templates/linear.app.md\", \"templates/uber.md\", \"templates/cal.md\", \"templates/spotify.md\", \"templates/cursor.md\", \"templates/coinbase.md\", \"templates/mintlify.md\", \"templates/warp.md\", \"templates/elevenlabs.md\", \"templates/raycast.md\", \"templates/voltagent.md\", \"templates/expo.md\", \"templates/sanity.md\"]}, \"usage_hint\": \"To view linked files, call skill_view(name, file_path) where file_path is e.g. 'references/api.md' or 'assets/config.yaml'\", \"required_environment_variables\": [], \"required_commands\": [], \"missing_required_environment_variables\": [], \"missing_credential_files\": [], \"missing_required_commands\": [], \"setup_needed\": false, \"setup_skipped\": false, \"readiness_status\": \"available\"}",
      "tool_call_id": "call_function_482zhhlnflgr_2"
    },
    {
      "role": "tool",
      "name": "skill_view",
      "content": "{\"success\": true, \"name\": \"pretext\", \"description\": \"Use when building creative browser demos with @chenglou/pretext — DOM-free text layout for ASCII art, typographic flow around obstacles, text-as-geometry games, kinetic typography, and text-powered generative art. Produces single-file HTML demos by default.\", \"tags\": [\"creative-coding\", \"typography\", \"pretext\", \"ascii-art\", \"canvas\", \"generative\", \"text-layout\", \"kinetic-typography\"], \"related_skills\": [\"p5js\", \"claude-design\", \"excalidraw\", \"architecture-diagram\"], \"content\": \"---\\nname: pretext\\ndescription: \\\"Use when building creative browser demos with @chenglou/pretext — DOM-free text layout for ASCII art, typographic flow around obstacles, text-as-geometry games, kinetic typography, and text-powered generative art. Produces single-file HTML demos by default.\\\"\\nversion: 1.0.0\\nauthor: Hermes Agent\\nlicense: MIT\\nplatforms: [linux, macos, windows]\\nmetadata:\\n  hermes:\\n    tags: [creative-coding, typography, pretext, ascii-art, canvas, generative, text-layout, kinetic-typography]\\n    related_skills: [p5js, claude-design, excalidraw, architecture-diagram]\\n---\\n\\n# Pretext Creative Demos\\n\\n## Overview\\n\\n[`@chenglou/pretext`](https://github.com/chenglou/pretext) is a 15KB zero-dependency TypeScript library by Cheng Lou (React core, ReasonML, Midjourney) for **DOM-free multiline text measurement and layout**. It does one thing: given `(text, font, width)`, return the line breaks, per-line widths, per-grapheme positions, and total height — all via canvas measurement, no reflow.\\n\\nThat sounds like plumbing. It is not. Because it is fast and geometric, it is a **creative primitive**: you can reflow paragraphs around a moving sprite at 60fps, build games whose level geometry is made of real words, drive ASCII logos through prose, shatter text into particles with exact per-grapheme starting positions, or pack shrink-wrapped multiline UI without any `getBoundingClientRect` thrash.\\n\\nThis skill exists so Hermes can make **cool demos** with it — the kind people post to X. See `pretext.cool` and `chenglou.me/pretext` for the community demo corpus.\\n\\n## When to Use\\n\\nUse when the user asks for:\\n- A \\\"pretext demo\\\" / \\\"cool pretext thing\\\" / \\\"text-as-X\\\"\\n- Text flowing around a moving shape (hero sections, editorial layouts, animated long-form pages)\\n- ASCII-art effects using **real words or prose**, not monospace rasters\\n- Games where the playfield / obstacles / bricks are made of text (Tetris-from-letters, Breakout-of-prose)\\n- Kinetic typography with per-glyph physics (shatter, scatter, flock, flow)\\n- Typographic generative art, especially with non-Latin scripts or mixed scripts\\n- Multiline \\\"shrink-wrap\\\" UI (smallest container width that still fits the text)\\n- Anything that would require knowing line breaks *before* rendering\\n\\nDon't use for:\\n- Static SVG/HTML pages where CSS already solves layout — just use CSS\\n- Rich text editors, general inline formatting engines (pretext is intentionally narrow)\\n- Image → text (use `ascii-art` / `ascii-video` skills)\\n- Pure canvas generative art with no text role — use `p5js`\\n\\n## Creative Standard\\n\\nThis is visual art rendered in a browser. Pretext returns numbers; **you** draw the thing.\\n\\n- **Don't ship a \\\"hello world\\\" demo.** The `hello-orb-flow.html` template is the *starting* point. Every delivered demo must add intentional color, motion, composition, and one visual detail the user didn't ask for but will appreciate.\\n- **Dark backgrounds, warm cores, considered palette.** Classic amber-on-black (CRT / terminal) works, but so do cold-white-on-charcoal (editorial) and desaturated pastels (risograph). Pick one and commit.\\n- **Proportional fonts are the point.** Pretext's whole vibe is \\\"not monospaced\\\" — lean into it. Use Iowan Old Style, Inter, JetBrains Mono, Helvetica Neue, or a variable font. Never default sans.\\n- **Real source/text, not lorem ipsum.** The corpus should mean something. Short manifestos, poetry, real source code, a found text, the library's own README — never `lorem ipsum`.\\n- **First-paint excellence.** No loading states, no blank frames. The demo must look shippable the instant it opens.\\n\\n## Stack\\n\\nSingle self-contained HTML file per demo. No build step.\\n\\n| Layer | Tool | Purpose |\\n|-------|------|---------|\\n| Core | `@chenglou/pretext` via `esm.sh` CDN | Text measurement + line layout |\\n| Render | HTML5 Canvas 2D | Glyph rendering, per-frame composition |\\n| Segmentation | `Intl.Segmenter` (built-in) | Grapheme splitting for emoji / CJK / combining marks |\\n| Interaction | Raw DOM events | Mouse / touch / wheel — no framework |\\n\\n```html\\n<script type=\\\"module\\\">\\nimport {\\n  prepare, layout,                   // use-case 1: simple height\\n  prepareWithSegments, layoutWithLines,  // use-case 2a: fixed-width lines\\n  layoutNextLineRange, materializeLineRange, // use-case 2b: streaming / variable width\\n  measureLineStats, walkLineRanges,  // stats without string allocation\\n} from \\\"https://esm.sh/@chenglou/pretext@0.0.6\\\";\\n</script>\\n```\\n\\nPin the version. `@0.0.6` at time of writing — check [npm](https://www.npmjs.com/package/@chenglou/pretext) for the latest if demo behavior is off.\\n\\n## The Two Use Cases\\n\\nAlmost everything reduces to one of these two shapes. Learn both.\\n\\n### Use-case 1 — measure, then render with CSS/DOM\\n\\n```js\\nconst prepared = prepare(text, \\\"16px Inter\\\");\\nconst { height, lineCount } = layout(prepared, 320, 20);\\n```\\n\\nYou still let the browser draw the text. Pretext just tells you how tall the box will be at a given width, **without** a DOM read. Use for:\\n- Virtualized lists where rows contain wrapping text\\n- Masonry with precise card heights\\n- \\\"Does this label fit?\\\" dev-time checks\\n- Preventing layout shift when remote text loads\\n\\n**Keep `font` and `letterSpacing` exactly in sync with your CSS.** The canvas `ctx.font` format (e.g. `\\\"16px Inter\\\"`, `\\\"500 17px 'JetBrains Mono'\\\"`) must match the rendered CSS, or measurements drift.\\n\\n### Use-case 2 — measure *and* render yourself\\n\\n```js\\nconst prepared = prepareWithSegments(text, FONT);\\nconst { lines } = layoutWithLines(prepared, 320, 26);\\nfor (let i = 0; i < lines.length; i++) {\\n  ctx.fillText(lines[i].text, 0, i * 26);\\n}\\n```\\n\\nThis is where the creative work lives. You own the drawing, so you can:\\n- Render to canvas, SVG, WebGL, or any coordinate system\\n- Substitute per-glyph transforms (rotation, jitter, scale, opacity)\\n- Use line metadata (width, grapheme positions) as geometry\\n\\nFor **variable-width-per-line** flow (text around a shape, text in a donut band, text in a non-rectangular column):\\n\\n```js\\nlet cursor = { segmentIndex: 0, graphemeIndex: 0 };\\nlet y = 0;\\nwhile (true) {\\n  const lineWidth = widthAtY(y);  // your function: how wide is the corridor at this y?\\n  const range = layoutNextLineRange(prepared, cursor, lineWidth);\\n  if (!range) break;\\n  const line = materializeLineRange(prepared, range);\\n  ctx.fillText(line.text, leftEdgeAtY(y), y);\\n  cursor = range.end;\\n  y += lineHeight;\\n}\\n```\\n\\nThis is the most important pattern in the whole library. It's what unlocks \\\"text flowing around a dragged sprite\\\" — the demo that went viral on X.\\n\\n### Helpers worth knowing\\n\\n- `measureLineStats(prepared, maxWidth)` → `{ lineCount, maxLineWidth }` — the widest line, i.e. multiline shrink-wrap width.\\n- `walkLineRanges(prepared, maxWidth, callback)` — iterate lines without allocating strings. Use for stats/physics over graphemes when you don't need the characters.\\n- `@chenglou/pretext/rich-inline` — the same system but for paragraphs mixing fonts / chips / mentions. Import from the subpath.\\n\\n## Demo Recipe Patterns\\n\\nThe community corpus (see `references/patterns.md`) clusters into a handful of strong patterns. Pick one and riff — don't invent a new category unless asked.\\n\\n| Pattern | Key API | Example idea |\\n|---|---|---|\\n| **Reflow around obstacle** | `layoutNextLineRange` + per-row width function | Editorial paragraph that parts around a dragged cursor sprite |\\n| **Text-as-geometry game** | `layoutWithLines` + per-line collision rects | Breakout where each brick is a measured word |\\n| **Shatter / particles** | `walkLineRanges` → per-grapheme (x,y) → physics | Sentence that explodes into letters on click |\\n| **ASCII obstacle typography** | `layoutNextLineRange` + measured per-row obstacle spans | Bitmap ASCII logo, shape morphs, and draggable wire objects that make text open around their actual geometry |\\n| **Editorial multi-column** | `layoutNextLineRange` per column + shared cursor | Animated magazine spread with pull quotes |\\n| **Kinetic type** | `layoutWithLines` + per-line transform over time | Star Wars crawl, wave, bounce, glitch |\\n| **Multiline shrink-wrap** | `measureLineStats` | Quote card that auto-sizes to its tightest container |\\n\\nSee `templates/donut-orbit.html` and `templates/hello-orb-flow.html` for working single-file starters.\\n\\n## Workflow\\n\\n1. **Pick a pattern** from the table above based on the user's brief.\\n2. **Start from a template**:\\n   - `templates/hello-orb-flow.html` — text reflowing around a moving orb (reflow-around-obstacle pattern)\\n   - `templates/donut-orbit.html` — advanced example: measured ASCII logo obstacles, draggable wire sphere/cube, morphing shape fields, selectable DOM text, and dev-only controls\\n   - `write_file` to a new `.html` in `/tmp/` or the user's workspace.\\n3. **Swap the corpus** for something intentional to the brief. Real prose, 10-100 sentences, no lorem.\\n4. **Tune the aesthetic** — font, palette, composition, interaction. This is the work; don't skip it.\\n5. **Verify locally**:\\n   ```sh\\n   cd <dir-with-html> && python3 -m http.server 8765\\n   # then open http://localhost:8765/<file>.html\\n   ```\\n6. **Check the console** — pretext will throw if `prepareWithSegments` is called with a bad font string; `Intl.Segmenter` is available in every modern browser.\\n7. **Show the user the file path**, not just the code — they want to open it.\\n\\n## Performance Notes\\n\\n- `prepare()` / `prepareWithSegments()` is the expensive call. Do it **once** per text+font pair. Cache the handle.\\n- On resize, only rerun `layout()` / `layoutWithLines()` — never re-prepare.\\n- For per-frame animations where text doesn't change but geometry does, `layoutNextLineRange` in a tight loop is cheap enough to do every frame at 60fps for normal-length paragraphs.\\n- When rendering ASCII masks per frame, keep a cell buffer (`Uint8Array`/typed arrays), derive measured per-row obstacle spans from the cells or projected geometry, merge spans, then feed those spans into `layoutNextLineRange` before drawing text.\\n- Keep visual animation and layout animation coupled. If a sphere morphs into a cube, tween both the rendered cell buffer and the obstacle spans with the same value; otherwise the demo looks painted-on instead of physically reflowed.\\n- For fades, prefer layer opacity over changing glyph intensity or obstacle scale. Put transient ASCII sprites on their own canvas and fade the canvas with CSS/GSAP opacity so geometry does not appear to shrink.\\n- Canvas `ctx.font` setting is surprisingly slow; set it **once** per frame if font doesn't vary, not per `fillText` call.\\n\\n## Common Pitfalls\\n\\n1. **Drifting CSS/canvas font strings.** `ctx.font = \\\"16px Inter\\\"` measured, but CSS says `font-family: Inter, sans-serif; font-size: 16px`. Fine *if* Inter loads. If Inter 404s, CSS falls back to sans-serif and measurements drift by 5-20%. Always `preload` the font or use a web-safe family.\\n\\n2. **Re-preparing inside the animation loop.** Only `layout*` is cheap. Re-calling `prepare` every frame will tank perf. Keep the prepared handle in module scope.\\n\\n3. **Forgetting `Intl.Segmenter` for grapheme splits.** Emoji, combining marks, CJK — `\\\"é\\\".split(\\\"\\\")` gives you two chars. Use `new Intl.Segmenter(undefined, { granularity: \\\"grapheme\\\" })` when sampling individual visible glyphs.\\n\\n4. **`break: 'never'` chips without `extraWidth`.** In `rich-inline`, if you use `break: 'never'` for an atomic chip/mention, you must also supply `extraWidth` for the pill padding — otherwise chip chrome overflows the container.\\n\\n5. **Using `@chenglou/pretext` from `unpkg` with TypeScript-only entry.** Use `esm.sh` — it compiles the TS exports to browser-ready ESM automatically. `unpkg` will 404 or serve raw TS.\\n\\n6. **Monospace fallbacks silently erasing the whole point.** Users seeing monospace-looking output often have a CSS `font-family` that fell through to `monospace`. Verify the actual rendered font via DevTools.\\n\\n7. **Skipping rows vs adjusting width** when flowing around a shape. If the corridor on this row is too narrow to fit a line, *skip the row* (`y += lineHeight; continue;`) rather than passing a tiny maxWidth to `layoutNextLineRange` — pretext will return one-grapheme lines that look broken.\\n\\n8. **Shipping a cold demo.** The default first-paint looks tutorial-grade. Add: vignette, subtle scanline, idle auto-motion, one carefully chosen interactive response (drag, hover, scroll, click). Without these, \\\"cool pretext demo\\\" lands as \\\"intern repro of the README.\\\"\\n\\n## Verification Checklist\\n\\n- [ ] Demo is a single self-contained `.html` file — opens by double-click or `python3 -m http.server`\\n- [ ] `@chenglou/pretext` imported via `esm.sh` with pinned version\\n- [ ] Corpus is real prose, not lorem ipsum, and matches the demo's concept\\n- [ ] Font string passed to `prepare` matches the CSS font exactly\\n- [ ] `prepare()` / `prepareWithSegments()` called once, not per frame\\n- [ ] Dark background + considered palette — not the default white canvas\\n- [ ] At least one interactive response (drag / hover / scroll / click) or idle auto-motion\\n- [ ] Tested locally with `python3 -m http.server` and confirmed no console errors\\n- [ ] 60fps on a mid-tier laptop (or graceful degradation documented)\\n- [ ] One \\\"extra mile\\\" detail the user didn't ask for\\n\\n## Reference: Community Demos\\n\\nClone these for inspiration / patterns (all MIT-ish, linked from [pretext.cool](https://www.pretext.cool/)):\\n\\n- **Pretext Breaker** — breakout with word-bricks — `github.com/rinesh/pretext-breaker`\\n- **Tetris × Pretext** — `github.com/shinichimochizuki/tetris-pretext`\\n- **Dragon animation** — `github.com/qtakmalay/PreTextExperiments`\\n- **Somnai editorial engine** — `github.com/somnai-dreams/pretext-demos`\\n- **Bad Apple!! ASCII** — `github.com/frmlinn/bad-apple-pretext`\\n- **Drag-sprite reflow** — `github.com/dokobot/pretext-demo`\\n- **Alarmy editorial clock** — `github.com/SmisLee/alarmy-pretext-demo`\\n\\nOfficial playground: [chenglou.me/pretext](https://chenglou.me/pretext/) — accordion, bubbles, dynamic-layout, editorial-engine, justification-comparison, masonry, markdown-chat, rich-note.\\n\", \"path\": \"creative/pretext/SKILL.md\", \"skill_dir\": \"/home/kuhnn/.hermes/skills/creative/pretext\", \"linked_files\": {\"references\": [\"references/patterns.md\"]}, \"usage_hint\": \"To view linked files, call skill_view(name, file_path) where file_path is e.g. 'references/api.md' or 'assets/config.yaml'\", \"required_environment_variables\": [], \"required_commands\": [], \"missing_required_environment_variables\": [], \"missing_credential_files\": [], \"missing_required_commands\": [], \"setup_needed\": false, \"setup_skipped\": false, \"readiness_status\": \"available\", \"metadata\": {\"hermes\": {\"tags\": [\"creative-coding\", \"typography\", \"pretext\", \"ascii-art\", \"canvas\", \"generative\", \"text-layout\", \"kinetic-typography\"], \"related_skills\": [\"p5js\", \"claude-design\", \"excalidraw\", \"architecture-diagram\"]}}}",
      "tool_call_id": "call_function_482zhhlnflgr_3"
    },
    {
      "role": "tool",
      "name": "skill_view",
      "content": "{\"success\": true, \"name\": \"sketch\", \"description\": \"Throwaway HTML mockups: 2-3 design variants to compare.\", \"tags\": [\"sketch\", \"mockup\", \"design\", \"ui\", \"prototype\", \"html\", \"variants\", \"exploration\", \"wireframe\", \"comparison\"], \"related_skills\": [\"spike\", \"claude-design\", \"popular-web-designs\", \"excalidraw\"], \"content\": \"---\\nname: sketch\\ndescription: \\\"Throwaway HTML mockups: 2-3 design variants to compare.\\\"\\nversion: 1.0.0\\nauthor: Hermes Agent (adapted from gsd-build/get-shit-done)\\nlicense: MIT\\nplatforms: [linux, macos, windows]\\nmetadata:\\n  hermes:\\n    tags: [sketch, mockup, design, ui, prototype, html, variants, exploration, wireframe, comparison]\\n    related_skills: [spike, claude-design, popular-web-designs, excalidraw]\\n---\\n\\n# Sketch\\n\\nUse this skill when the user wants to **see a design direction before committing** to one — exploring a UI/UX idea as disposable HTML mockups. The point is to generate 2-3 interactive variants so the user can compare visual directions side-by-side, not to produce shippable code.\\n\\nLoad this when the user says things like \\\"sketch this screen\\\", \\\"show me what X could look like\\\", \\\"compare layout A vs B\\\", \\\"give me 2-3 takes on this UI\\\", \\\"let me see some variants\\\", \\\"mockup this before I build\\\".\\n\\n## When NOT to use this\\n\\n- User wants a production component — use `claude-design` or build it properly\\n- User wants a polished one-off HTML artifact (landing page, deck) — `claude-design`\\n- User wants a diagram — `excalidraw`, `architecture-diagram`\\n- The design is already locked — just build it\\n\\n## If the user has the full GSD system installed\\n\\nIf `gsd-sketch` shows up as a sibling skill (installed via `npx get-shit-done-cc --hermes`), prefer **`gsd-sketch`** for the full workflow: persistent `.planning/sketches/` with MANIFEST, frontier mode analysis, consistency audits across past sketches, and integration with the rest of GSD. This skill is the lightweight standalone version — one-off sketching without the state machinery.\\n\\n## Core method\\n\\n```\\nintake  →  variants  →  head-to-head  →  pick winner (or iterate)\\n```\\n\\n### 1. Intake (skip if the user already gave you enough)\\n\\nBefore generating variants, get three things — one question at a time, not all at once:\\n\\n1. **Feel.** \\\"What should this feel like? Adjectives, emotions, a vibe.\\\" — *\\\"calm, editorial, like Linear\\\"* tells you more than *\\\"minimal\\\"*.\\n2. **References.** \\\"What apps, sites, or products capture the feel you're imagining?\\\" — actual references beat abstract descriptions.\\n3. **Core action.** \\\"What's the single most important thing a user does on this screen?\\\" — the variants should all serve this well; if they don't, they're just decoration.\\n\\nReflect each answer briefly before the next question. If the user already gave you all three upfront, skip straight to variants.\\n\\n### 2. Variants (2-3, never 1, rarely 4+)\\n\\nProduce **2-3 variants** in one go. Each variant is a complete, standalone HTML file. Don't describe variants — build them. The point is comparison.\\n\\nEach variant should take a **different design stance**, not different pixel values. Three good variant axes:\\n\\n- **Density:** compact / airy / ultra-dense (pick two contrasting poles)\\n- **Emphasis:** content-first / action-first / tool-first\\n- **Aesthetic:** editorial / utilitarian / playful\\n- **Layout:** single-column / sidebar / split-pane\\n- **Grounding:** card-based / bare-content / document-style\\n\\nPick one axis and pull apart from it. Two variants that differ only in accent color are wasted effort — the user can't distinguish them.\\n\\n**Variant naming:** describe the stance, not the number.\\n\\n```\\nsketches/\\n├── 001-calm-editorial/\\n│   ├── index.html\\n│   └── README.md\\n├── 001-utilitarian-dense/\\n│   ├── index.html\\n│   └── README.md\\n└── 001-playful-split/\\n    ├── index.html\\n    └── README.md\\n```\\n\\n### 3. Make them real HTML\\n\\nEach variant is a **single self-contained HTML file**:\\n\\n- Inline `<style>` — no build step, no external CSS\\n- System fonts or one Google Font via `<link>`\\n- Tailwind via CDN (`<script src=\\\"https://cdn.tailwindcss.com\\\"></script>`) is fine\\n- Realistic fake content — actual sentences, actual names, not \\\"Lorem ipsum\\\"\\n- **Interactive**: links clickable, hovers real, at least one state transition (open/close, filter, toggle). A frozen static image is a worse spike than a sloppy animated one.\\n\\nOpen it in a browser. If it looks broken, fix it before showing the user.\\n\\n**Verify variants visually — use Hermes' browser tools.** Don't just write HTML and hope it renders; load each variant and look at it:\\n\\n```\\nbrowser_navigate(url=\\\"file:///absolute/path/to/sketches/001-calm-editorial/index.html\\\")\\nbrowser_vision(question=\\\"Does this layout look clean and readable? Any visible bugs (overlapping text, unstyled elements, broken images)?\\\")\\n```\\n\\n`browser_vision` returns an AI description of what's actually on the page plus a screenshot path — catches layout bugs that pure source inspection misses (e.g. a font import that silently failed, a flex container that collapsed). Fix and re-navigate until each variant looks right.\\n\\n**Default CSS reset + system font stack** for fast starts:\\n\\n```html\\n<style>\\n  * { box-sizing: border-box; margin: 0; padding: 0; }\\n  body {\\n    font-family: -apple-system, BlinkMacSystemFont, \\\"Segoe UI\\\", Roboto,\\n                 \\\"Helvetica Neue\\\", Arial, sans-serif;\\n    -webkit-font-smoothing: antialiased;\\n    color: #1a1a1a;\\n    background: #fafafa;\\n    line-height: 1.5;\\n  }\\n</style>\\n```\\n\\n### 4. Variant README\\n\\nEach variant's `README.md` answers:\\n\\n```markdown\\n## Variant: {stance name}\\n\\n### Design stance\\nOne sentence on the principle driving this variant.\\n\\n### Key choices\\n- Layout: ...\\n- Typography: ...\\n- Color: ...\\n- Interaction: ...\\n\\n### Trade-offs\\n- Strong at: ...\\n- Weak at: ...\\n\\n### Best for\\n- The kind of user or use case this variant actually serves\\n```\\n\\n### 5. Head-to-head\\n\\nAfter all variants are built, present them as a comparison. Don't just list — **opinionate**:\\n\\n```markdown\\n## Three takes on the home screen\\n\\n| Dimension | Calm editorial | Utilitarian dense | Playful split |\\n|-----------|----------------|-------------------|---------------|\\n| Density   | Low            | High              | Medium        |\\n| Primary action visibility | Low | High | Medium |\\n| Scan-ability | High | Medium | Low |\\n| Feel | Calm, trusted | Sharp, tool-like | Inviting, energetic |\\n\\n**My take:** Utilitarian dense for power users, calm editorial for content-forward audiences. Playful split is weakest — tries to do both and commits to neither.\\n```\\n\\nLet the user pick a winner, or combine two into a hybrid, or ask for another round.\\n\\n## Theming (when the project has a visual identity)\\n\\nIf the user has an existing theme (colors, fonts, tokens), put shared tokens in `sketches/themes/tokens.css` and `@import` them in each variant. Keep tokens minimal:\\n\\n```css\\n/* sketches/themes/tokens.css */\\n:root {\\n  --color-bg: #fafafa;\\n  --color-fg: #1a1a1a;\\n  --color-accent: #0066ff;\\n  --color-muted: #666;\\n  --radius: 8px;\\n  --font-display: \\\"Inter\\\", sans-serif;\\n  --font-body: -apple-system, BlinkMacSystemFont, sans-serif;\\n}\\n```\\n\\nDon't over-tokenize a throwaway sketch — three colors and one font is usually enough.\\n\\n## Interactivity bar\\n\\nA sketch is interactive enough when the user can:\\n\\n1. **Click a primary action** and something visible happens (state change, modal, toast, navigation feint)\\n2. **See one meaningful state transition** (filter a list, toggle a mode, open/close a panel)\\n3. **Hover recognizable affordances** (buttons, rows, tabs)\\n\\nMore than that is over-engineering a throwaway. Less than that is a screenshot.\\n\\n## Frontier mode (picking what to sketch next)\\n\\nIf sketches already exist and the user says \\\"what should I sketch next?\\\":\\n\\n- **Consistency gaps** — two winning variants from different sketches made independent choices that haven't been composed together yet\\n- **Unsketched screens** — referenced but never explored\\n- **State coverage** — happy path sketched, but not empty / loading / error / 1000-items\\n- **Responsive gaps** — validated at one viewport; does it hold at mobile / ultrawide?\\n- **Interaction patterns** — static layouts exist; transitions, drag, scroll behavior don't\\n\\nPropose 2-4 named candidates. Let the user pick.\\n\\n## Output\\n\\n- Create `sketches/` (or `.planning/sketches/` if the user is using GSD conventions) in the repo root\\n- One subdir per variant: `NNN-stance-name/index.html` + `README.md`\\n- Tell the user how to open them: `open sketches/001-calm-editorial/index.html` on macOS, `xdg-open` on Linux, `start` on Windows\\n- Keep variants disposable — a sketch that you felt the need to preserve should be promoted into real project code, not curated as an asset\\n\\n**Typical tool sequence for one variant:**\\n\\n```\\nterminal(\\\"mkdir -p sketches/001-calm-editorial\\\")\\nwrite_file(\\\"sketches/001-calm-editorial/index.html\\\", \\\"<!doctype html>...\\\")\\nwrite_file(\\\"sketches/001-calm-editorial/README.md\\\", \\\"## Variant: Calm editorial\\\\n...\\\")\\nbrowser_navigate(url=\\\"file://$(pwd)/sketches/001-calm-editorial/index.html\\\")\\nbrowser_vision(question=\\\"How does this look? Any obvious layout issues?\\\")\\n```\\n\\nRepeat for each variant, then present the comparison table.\\n\\n## Attribution\\n\\nAdapted from the GSD (Get Shit Done) project's `/gsd-sketch` workflow — MIT © 2025 Lex Christopherson ([gsd-build/get-shit-done](https://github.com/gsd-build/get-shit-done)). The full GSD system ships persistent sketch state, theme/variant pattern references, and consistency-audit workflows; install with `npx get-shit-done-cc --hermes --global`.\\n\", \"path\": \"creative/sketch/SKILL.md\", \"skill_dir\": \"/home/kuhnn/.hermes/skills/creative/sketch\", \"linked_files\": null, \"usage_hint\": null, \"required_environment_variables\": [], \"required_commands\": [], \"missing_required_environment_variables\": [], \"missing_credential_files\": [], \"missing_required_commands\": [], \"setup_needed\": false, \"setup_skipped\": false, \"readiness_status\": \"available\", \"metadata\": {\"hermes\": {\"tags\": [\"sketch\", \"mockup\", \"design\", \"ui\", \"prototype\", \"html\", \"variants\", \"exploration\", \"wireframe\", \"comparison\"], \"related_skills\": [\"spike\", \"claude-design\", \"popular-web-designs\", \"excalidraw\"]}}}",
      "tool_call_id": "call_function_482zhhlnflgr_4"
    },
    {
      "role": "tool",
      "name": "skill_view",
      "content": "{\"success\": true, \"name\": \"songwriting-and-ai-music\", \"description\": \"Songwriting craft and Suno AI music prompts.\", \"tags\": [\"songwriting\", \"music\", \"suno\", \"parody\", \"lyrics\", \"creative\"], \"related_skills\": [], \"content\": \"---\\nname: songwriting-and-ai-music\\ndescription: \\\"Songwriting craft and Suno AI music prompts.\\\"\\ntags: [songwriting, music, suno, parody, lyrics, creative]\\nplatforms: [linux, macos, windows]\\ntriggers:\\n  - writing a song\\n  - song lyrics\\n  - music prompt\\n  - suno prompt\\n  - parody song\\n  - adapting a song\\n  - AI music generation\\n---\\n\\n# Songwriting & AI Music Generation\\n\\nEverything here is a GUIDELINE, not a rule. Art breaks rules on purpose.\\nUse what serves the song. Ignore what doesn't.\\n\\n---\\n\\n## 1. Song Structure (Pick One or Invent Your Own)\\n\\nCommon skeletons — mix, modify, or throw out as needed:\\n\\n```\\nABABCB  Verse/Chorus/Verse/Chorus/Bridge/Chorus    (most pop/rock)\\nAABA    Verse/Verse/Bridge/Verse (refrain-based)    (jazz standards, ballads)\\nABAB    Verse/Chorus alternating                    (simple, direct)\\nAAA     Verse/Verse/Verse (strophic, no chorus)     (folk, storytelling)\\n```\\n\\nThe six building blocks:\\n- Intro      — set the mood, pull the listener in\\n- Verse      — the story, the details, the world-building\\n- Pre-Chorus — optional tension ramp before the payoff\\n- Chorus     — the emotional core, the part people remember\\n- Bridge     — a detour, a shift in perspective or key\\n- Outro      — the farewell, can echo or subvert the rest\\n\\nYou don't need all of these. Some great songs are just one section\\nthat evolves. Structure serves the emotion, not the other way around.\\n\\n---\\n\\n## 2. Rhyme, Meter, and Sound\\n\\nRHYME TYPES (from tight to loose):\\n- Perfect: lean/mean\\n- Family: crate/braid\\n- Assonance: had/glass (same vowels, different endings)\\n- Consonance: scene/when (different vowels, similar endings)\\n- Near/slant: enough to suggest connection without locking it down\\n\\nMix them. All perfect rhymes can sound like a nursery rhyme.\\nAll slant rhymes can sound lazy. The blend is where it lives.\\n\\nINTERNAL RHYME: Rhyming within a line, not just at the ends.\\n  \\\"We pruned the lies from bleeding trees / Distilled the storm\\n   from entropy\\\" — \\\"lies/flies,\\\" \\\"trees/entropy\\\" create internal echoes.\\n\\nMETER: The rhythm of stressed vs unstressed syllables.\\n- Matching syllable counts between parallel lines helps singability\\n- The STRESSED syllables matter more than total count\\n- Say it out loud. If you stumble, the meter needs work.\\n- Intentionally breaking meter can create emphasis or surprise\\n\\n---\\n\\n## 3. Emotional Arc and Dynamics\\n\\nThink of a song as a journey, not a flat road.\\n\\nENERGY MAPPING (rough idea, not prescription):\\n  Intro: 2-3  |  Verse: 5-6  |  Pre-Chorus: 7\\n  Chorus: 8-9  |  Bridge: varies  |  Final Chorus: 9-10\\n\\nThe most powerful dynamic trick: CONTRAST.\\n- Whisper before a scream hits harder than just screaming\\n- Sparse before dense. Slow before fast. Low before high.\\n- The drop only works because of the buildup\\n- Silence is an instrument\\n\\n\\\"Whisper to roar to whisper\\\" — start intimate, build to full power,\\nstrip back to vulnerability. Works for ballads, epics, anthems.\\n\\n---\\n\\n## 4. Writing Lyrics That Work\\n\\nSHOW, DON'T TELL (usually):\\n- \\\"I was sad\\\" = flat\\n- \\\"Your hoodie's still on the hook by the door\\\" = alive\\n- But sometimes \\\"I give my life\\\" said plainly IS the power\\n\\nTHE HOOK:\\n- The line people remember, hum, repeat\\n- Usually the title or core phrase\\n- Works best when melody + lyric + emotion all align\\n- Place it where it lands hardest (often first/last line of chorus)\\n\\nPROSODY — lyrics and music supporting each other:\\n- Stable feelings (resolution, peace) pair with settled melodies,\\n  perfect rhymes, resolved chords\\n- Unstable feelings (longing, doubt) pair with wandering melodies,\\n  near-rhymes, unresolved chords\\n- Verse melody typically sits lower, chorus goes higher\\n- But flip this if it serves the song\\n\\nAVOID (unless you're doing it on purpose):\\n- Cliches on autopilot (\\\"heart of gold\\\" without earning it)\\n- Forcing word order to hit a rhyme (\\\"Yoda-speak\\\")\\n- Same energy in every section (flat dynamics)\\n- Treating your first draft as sacred — revision is creation\\n\\n---\\n\\n## 5. Parody and Adaptation\\n\\nWhen rewriting an existing song with new lyrics:\\n\\nTHE SKELETON: Map the original's structure first.\\n- Count syllables per line\\n- Mark the rhyme scheme (ABAB, AABB, etc.)\\n- Identify which syllables are STRESSED\\n- Note where held/sustained notes fall\\n\\nFITTING NEW WORDS:\\n- Match stressed syllables to the same beats as the original\\n- Total syllable count can flex by 1-2 unstressed syllables\\n- On long held notes, try to match the VOWEL SOUND of the original\\n  (if original holds \\\"LOOOVE\\\" with an \\\"oo\\\" vowel, \\\"FOOOD\\\" fits\\n   better than \\\"LIFE\\\")\\n- Monosyllabic swaps in key spots keep rhythm intact\\n  (Crime -> Code, Snake -> Noose)\\n- Sing your new words over the original — if you stumble, revise\\n\\nCONCEPT:\\n- Pick a concept strong enough to sustain the whole song\\n- Start from the title/hook and build outward\\n- Generate lots of raw material (puns, phrases, images) FIRST,\\n  then fit the best ones into the structure\\n- If you need a specific line somewhere, reverse-engineer the\\n  rhyme scheme backward to set it up\\n\\nKEEP SOME ORIGINALS: Leaving a few original lines or structures\\nintact adds recognizability and lets the audience feel the connection.\\n\\n---\\n\\n## 6. Suno AI Prompt Engineering\\n\\n### Style/Genre Description Field\\n\\nFORMULA (adapt as needed):\\n  Genre + Mood + Era + Instruments + Vocal Style + Production + Dynamics\\n\\n```\\nBAD:  \\\"sad rock song\\\"\\nGOOD: \\\"Cinematic orchestral spy thriller, 1960s Cold War era, smoky\\n       sultry female vocalist, big band jazz, brass section with\\n       trumpets and french horns, sweeping strings, minor key,\\n       vintage analog warmth\\\"\\n```\\n\\nDESCRIBE THE JOURNEY, not just the genre:\\n```\\n\\\"Begins as a haunting whisper over sparse piano. Gradually layers\\n in muted brass. Builds through the chorus with full orchestra.\\n Second verse erupts with raw belting intensity. Outro strips back\\n to a lone piano and a fragile whisper fading to silence.\\\"\\n```\\n\\nTIPS:\\n- V4.5+ supports up to 1,000 chars in Style field — use them\\n- NO artist names or trademarks. Describe the sound instead.\\n  \\\"1960s Cold War spy thriller brass\\\" not \\\"James Bond style\\\"\\n  \\\"90s grunge\\\" not \\\"Nirvana-style\\\"\\n- Specify BPM and key when you have a preference\\n- Use Exclude Styles field for what you DON'T want\\n- Unexpected genre combos can be gold: \\\"bossa nova trap\\\",\\n  \\\"Appalachian gothic\\\", \\\"chiptune jazz\\\"\\n- Build a vocal PERSONA, not just a gender:\\n  \\\"A weathered torch singer with a smoky alto, slight rasp,\\n   who starts vulnerable and builds to devastating power\\\"\\n\\n### Metatags (place in [brackets] inside lyrics field)\\n\\nSTRUCTURE:\\n  [Intro] [Verse] [Verse 1] [Pre-Chorus] [Chorus]\\n  [Post-Chorus] [Hook] [Bridge] [Interlude]\\n  [Instrumental] [Instrumental Break] [Guitar Solo]\\n  [Breakdown] [Build-up] [Outro] [Silence] [End]\\n\\nVOCAL PERFORMANCE:\\n  [Whispered] [Spoken Word] [Belted] [Falsetto] [Powerful]\\n  [Soulful] [Raspy] [Breathy] [Smooth] [Gritty]\\n  [Staccato] [Legato] [Vibrato] [Melismatic]\\n  [Harmonies] [Choir] [Harmonized Chorus]\\n\\nDYNAMICS:\\n  [High Energy] [Low Energy] [Building Energy] [Explosive]\\n  [Emotional Climax] [Gradual swell] [Orchestral swell]\\n  [Quiet arrangement] [Falling tension] [Slow Down]\\n\\nGENDER:\\n  [Female Vocals] [Male Vocals]\\n\\nATMOSPHERE:\\n  [Melancholic] [Euphoric] [Nostalgic] [Aggressive]\\n  [Dreamy] [Intimate] [Dark Atmosphere]\\n\\nSFX:\\n  [Vinyl Crackle] [Rain] [Applause] [Static] [Thunder]\\n\\nPut tags in BOTH style field AND lyrics for reinforcement.\\nKeep to 5-8 tags per section max — too many confuses the AI.\\nDon't contradict yourself ([Calm] + [Aggressive] in same section).\\n\\n### Custom Mode\\n- Always use Custom Mode for serious work (separate Style + Lyrics)\\n- Lyrics field limit: ~3,000 chars (~40-60 lines)\\n- Always add structural tags — without them Suno defaults to\\n  flat verse/chorus/verse with no emotional arc\\n\\n---\\n\\n## 7. Phonetic Tricks for AI Singers\\n\\nAI vocalists don't read — they pronounce. Help them:\\n\\nPHONETIC RESPELLING:\\n- Spell words as they SOUND: \\\"through\\\" -> \\\"thru\\\"\\n- Proper nouns are highest failure rate — test early\\n- \\\"Nous\\\" -> \\\"Noose\\\" (forces correct pronunciation)\\n- Hyphenate to guide syllables: \\\"Re-search\\\", \\\"bio-engineering\\\"\\n\\nDELIVERY CONTROL:\\n- ALL CAPS = louder, more intense\\n- Vowel extension: \\\"lo-o-o-ove\\\" = sustained/melisma\\n- Ellipses: \\\"I... need... you\\\" = dramatic pauses\\n- Hyphenated stretch: \\\"ne-e-ed\\\" = emotional stretch\\n\\nALWAYS:\\n- Spell out numbers: \\\"24/7\\\" -> \\\"twenty four seven\\\"\\n- Space acronyms: \\\"AI\\\" -> \\\"A I\\\" or \\\"A-I\\\"\\n- Test proper nouns/unusual words in a short 30-second clip first\\n- Once generated, pronunciation is baked in — fix in lyrics BEFORE\\n\\n---\\n\\n## 8. Workflow\\n\\n1. Write the concept/hook first — what's the emotional core?\\n2. If adapting, map the original structure (syllables, rhyme, stress)\\n3. Generate raw material — brainstorm freely before structuring\\n4. Draft lyrics into the structure\\n5. Read/sing aloud — catch stumbles, fix meter\\n6. Build the Suno style description — paint the dynamic journey\\n7. Add metatags to lyrics for performance direction\\n8. Generate 3-5 variations minimum — treat them like recording takes\\n9. Pick the best, use Extend/Continue to build on promising sections\\n10. If something great happens by accident, keep it\\n\\nEXPECT: ~3-5 generations per 1 good result. Revision is normal.\\nStyle can drift in extensions — restate genre/mood when extending.\\n\\n---\\n\\n## 9. Lessons Learned\\n\\n- Describing the dynamic ARC in the style field matters way more\\n  than just listing genres. \\\"Whisper to roar to whisper\\\" gives\\n  Suno a performance map.\\n- Keeping some original lines intact in a parody adds recognizability\\n  and emotional weight — the audience feels the ghost of the original.\\n- The bridge slot in a song is where you can transform imagery.\\n  Swap the original's specific references for your theme's metaphors\\n  while keeping the emotional function (reflection, shift, revelation).\\n- Monosyllabic word swaps in hooks/tags are the cleanest way to\\n  maintain rhythm while changing meaning.\\n- A strong vocal persona description in the style field makes a\\n  bigger difference than any single metatag.\\n- Don't be precious about rules. If a line breaks meter but hits\\n  harder, keep it. The feeling is what matters. Craft serves art,\\n  not the other way around.\\n\", \"path\": \"creative/songwriting-and-ai-music/SKILL.md\", \"skill_dir\": \"/home/kuhnn/.hermes/skills/creative/songwriting-and-ai-music\", \"linked_files\": null, \"usage_hint\": null, \"required_environment_variables\": [], \"required_commands\": [], \"missing_required_environment_variables\": [], \"missing_credential_files\": [], \"missing_required_commands\": [], \"setup_needed\": false, \"setup_skipped\": false, \"readiness_status\": \"available\"}",
      "tool_call_id": "call_function_482zhhlnflgr_5"
    },
    {
      "role": "tool",
      "name": "skill_view",
      "content": "{\"success\": true, \"name\": \"touchdesigner-mcp\", \"description\": \"Control a running TouchDesigner instance via twozero MCP — create operators, set parameters, wire connections, execute Python, build real-time visuals. 36 native tools.\", \"tags\": [\"TouchDesigner\", \"MCP\", \"twozero\", \"creative-coding\", \"real-time-visuals\", \"generative-art\", \"audio-reactive\", \"VJ\", \"installation\", \"GLSL\"], \"related_skills\": [\"native-mcp\", \"ascii-video\", \"manim-video\", \"hermes-video\"], \"content\": \"---\\nname: touchdesigner-mcp\\ndescription: \\\"Control a running TouchDesigner instance via twozero MCP — create operators, set parameters, wire connections, execute Python, build real-time visuals. 36 native tools.\\\"\\nversion: 1.1.0\\nauthor: kshitijk4poor\\nlicense: MIT\\nplatforms: [linux, macos, windows]\\nmetadata:\\n  hermes:\\n    tags: [TouchDesigner, MCP, twozero, creative-coding, real-time-visuals, generative-art, audio-reactive, VJ, installation, GLSL]\\n    related_skills: [native-mcp, ascii-video, manim-video, hermes-video]\\n\\n---\\n\\n# TouchDesigner Integration (twozero MCP)\\n\\n## CRITICAL RULES\\n\\n1. **NEVER guess parameter names.** Call `td_get_par_info` for the op type FIRST. Your training data is wrong for TD 2025.32.\\n2. **If `tdAttributeError` fires, STOP.** Call `td_get_operator_info` on the failing node before continuing.\\n3. **NEVER hardcode absolute paths** in script callbacks. Use `me.parent()` / `scriptOp.parent()`.\\n4. **Prefer native MCP tools over td_execute_python.** Use `td_create_operator`, `td_set_operator_pars`, `td_get_errors` etc. Only fall back to `td_execute_python` for complex multi-step logic.\\n5. **Call `td_get_hints` before building.** It returns patterns specific to the op type you're working with.\\n\\n## Architecture\\n\\n```\\nHermes Agent -> MCP (Streamable HTTP) -> twozero.tox (port 40404) -> TD Python\\n```\\n\\n36 native tools. Free plugin (no payment/license — confirmed April 2026).\\nContext-aware (knows selected OP, current network).\\nHub health check: `GET http://localhost:40404/mcp` returns JSON with instance PID, project name, TD version.\\n\\n## Setup (Automated)\\n\\nRun the setup script to handle everything:\\n\\n```bash\\nbash \\\"${HERMES_HOME:-$HOME/.hermes}/skills/creative/touchdesigner-mcp/scripts/setup.sh\\\"\\n```\\n\\nThe script will:\\n1. Check if TD is running\\n2. Download twozero.tox if not already cached\\n3. Add `twozero_td` MCP server to Hermes config (if missing)\\n4. Test the MCP connection on port 40404\\n5. Report what manual steps remain (drag .tox into TD, enable MCP toggle)\\n\\n### Manual steps (one-time, cannot be automated)\\n\\n1. **Drag `~/Downloads/twozero.tox` into the TD network editor** → click Install\\n2. **Enable MCP:** click twozero icon → Settings → mcp → \\\"auto start MCP\\\" → Yes\\n3. **Restart Hermes session** to pick up the new MCP server\\n\\nAfter setup, verify:\\n```bash\\nnc -z 127.0.0.1 40404 && echo \\\"twozero MCP: READY\\\"\\n```\\n\\n## Environment Notes\\n\\n- **Non-Commercial TD** caps resolution at 1280×1280. Use `outputresolution = 'custom'` and set width/height explicitly.\\n- **Codecs:** `prores` (preferred on macOS) or `mjpa` as fallback. H.264/H.265/AV1 require a Commercial license.\\n- Always call `td_get_par_info` before setting params — names vary by TD version (see CRITICAL RULES #1).\\n\\n## Workflow\\n\\n### Step 0: Discover (before building anything)\\n\\n```\\nCall td_get_par_info with op_type for each type you plan to use.\\nCall td_get_hints with the topic you're building (e.g. \\\"glsl\\\", \\\"audio reactive\\\", \\\"feedback\\\").\\nCall td_get_focus to see where the user is and what's selected.\\nCall td_get_network to see what already exists.\\n```\\n\\nNo temp nodes, no cleanup. This replaces the old discovery dance entirely.\\n\\n### Step 1: Clean + Build\\n\\n**IMPORTANT: Split cleanup and creation into SEPARATE MCP calls.** Destroying and recreating same-named nodes in one `td_execute_python` script causes \\\"Invalid OP object\\\" errors. See pitfalls #11b.\\n\\nUse `td_create_operator` for each node (handles viewport positioning automatically):\\n\\n```\\ntd_create_operator(type=\\\"noiseTOP\\\", parent=\\\"/project1\\\", name=\\\"bg\\\", parameters={\\\"resolutionw\\\": 1280, \\\"resolutionh\\\": 720})\\ntd_create_operator(type=\\\"levelTOP\\\", parent=\\\"/project1\\\", name=\\\"brightness\\\")\\ntd_create_operator(type=\\\"nullTOP\\\", parent=\\\"/project1\\\", name=\\\"out\\\")\\n```\\n\\nFor bulk creation or wiring, use `td_execute_python`:\\n\\n```python\\n# td_execute_python script:\\nroot = op('/project1')\\nnodes = []\\nfor name, optype in [('bg', noiseTOP), ('fx', levelTOP), ('out', nullTOP)]:\\n    n = root.create(optype, name)\\n    nodes.append(n.path)\\n# Wire chain\\nfor i in range(len(nodes)-1):\\n    op(nodes[i]).outputConnectors[0].connect(op(nodes[i+1]).inputConnectors[0])\\nresult = {'created': nodes}\\n```\\n\\n### Step 2: Set Parameters\\n\\nPrefer the native tool (validates params, won't crash):\\n\\n```\\ntd_set_operator_pars(path=\\\"/project1/bg\\\", parameters={\\\"roughness\\\": 0.6, \\\"monochrome\\\": true})\\n```\\n\\nFor expressions or modes, use `td_execute_python`:\\n\\n```python\\nop('/project1/time_driver').par.colorr.expr = \\\"absTime.seconds % 1000.0\\\"\\n```\\n\\n### Step 3: Wire\\n\\nUse `td_execute_python` — no native wire tool exists:\\n\\n```python\\nop('/project1/bg').outputConnectors[0].connect(op('/project1/fx').inputConnectors[0])\\n```\\n\\n### Step 4: Verify\\n\\n```\\ntd_get_errors(path=\\\"/project1\\\", recursive=true)\\ntd_get_perf()\\ntd_get_operator_info(path=\\\"/project1/out\\\", detail=\\\"full\\\")\\n```\\n\\n### Step 5: Display / Capture\\n\\n```\\ntd_get_screenshot(path=\\\"/project1/out\\\")\\n```\\n\\nOr open a window via script:\\n\\n```python\\nwin = op('/project1').create(windowCOMP, 'display')\\nwin.par.winop = op('/project1/out').path\\nwin.par.winw = 1280; win.par.winh = 720\\nwin.par.winopen.pulse()\\n```\\n\\n## MCP Tool Quick Reference\\n\\n**Core (use these most):**\\n| Tool | What |\\n|------|------|\\n| `td_execute_python` | Run arbitrary Python in TD. Full API access. |\\n| `td_create_operator` | Create node with params + auto-positioning |\\n| `td_set_operator_pars` | Set params safely (validates, won't crash) |\\n| `td_get_operator_info` | Inspect one node: connections, params, errors |\\n| `td_get_operators_info` | Inspect multiple nodes in one call |\\n| `td_get_network` | See network structure at a path |\\n| `td_get_errors` | Find errors/warnings recursively |\\n| `td_get_par_info` | Get param names for an OP type (replaces discovery) |\\n| `td_get_hints` | Get patterns/tips before building |\\n| `td_get_focus` | What network is open, what's selected |\\n\\n**Read/Write:**\\n| Tool | What |\\n|------|------|\\n| `td_read_dat` | Read DAT text content |\\n| `td_write_dat` | Write/patch DAT content |\\n| `td_read_chop` | Read CHOP channel values |\\n| `td_read_textport` | Read TD console output |\\n\\n**Visual:**\\n| Tool | What |\\n|------|------|\\n| `td_get_screenshot` | Capture one OP viewer to file |\\n| `td_get_screenshots` | Capture multiple OPs at once |\\n| `td_get_screen_screenshot` | Capture actual screen via TD |\\n| `td_navigate_to` | Jump network editor to an OP |\\n\\n**Search:**\\n| Tool | What |\\n|------|------|\\n| `td_find_op` | Find ops by name/type across project |\\n| `td_search` | Search code, expressions, string params |\\n\\n**System:**\\n| Tool | What |\\n|------|------|\\n| `td_get_perf` | Performance profiling (FPS, slow ops) |\\n| `td_list_instances` | List all running TD instances |\\n| `td_get_docs` | In-depth docs on a TD topic |\\n| `td_agents_md` | Read/write per-COMP markdown docs |\\n| `td_reinit_extension` | Reload extension after code edit |\\n| `td_clear_textport` | Clear console before debug session |\\n\\n**Input Automation:**\\n| Tool | What |\\n|------|------|\\n| `td_input_execute` | Send mouse/keyboard to TD |\\n| `td_input_status` | Poll input queue status |\\n| `td_input_clear` | Stop input automation |\\n| `td_op_screen_rect` | Get screen coords of a node |\\n| `td_click_screen_point` | Click a point in a screenshot |\\n| `td_screen_point_to_global` | Convert screenshot pixel to absolute screen coords |\\n\\nThe table above covers the 32 tools used in typical creative workflows. The remaining 4 tools (`td_project_quit`, `td_test_session`, `td_dev_log`, `td_clear_dev_log`) are admin/dev-mode utilities — see `references/mcp-tools.md` for the full 36-tool reference with complete parameter schemas.\\n\\n## Key Implementation Rules\\n\\n**GLSL time:** No `uTDCurrentTime` in GLSL TOP. Use the Values page:\\n```python\\n# Call td_get_par_info(op_type=\\\"glslTOP\\\") first to confirm param names\\ntd_set_operator_pars(path=\\\"/project1/shader\\\", parameters={\\\"value0name\\\": \\\"uTime\\\"})\\n# Then set expression via script:\\n# op('/project1/shader').par.value0.expr = \\\"absTime.seconds\\\"\\n# In GLSL: uniform float uTime;\\n```\\n\\nFallback: Constant TOP in `rgba32float` format (8-bit clamps to 0-1, freezing the shader).\\n\\n**Feedback TOP:** Use `top` parameter reference, not direct input wire. \\\"Not enough sources\\\" resolves after first cook. \\\"Cook dependency loop\\\" warning is expected.\\n\\n**Resolution:** Non-Commercial caps at 1280×1280. Use `outputresolution = 'custom'`.\\n\\n**Large shaders:** Write GLSL to `/tmp/file.glsl`, then use `td_write_dat` or `td_execute_python` to load.\\n\\n**Vertex/Point access (TD 2025.32):** `point.P[0]`, `point.P[1]`, `point.P[2]` — NOT `.x`, `.y`, `.z`.\\n\\n**Extensions:** `ext0object` format is `\\\"op('./datName').module.ClassName(me)\\\"` in CONSTANT mode. After editing extension code with `td_write_dat`, call `td_reinit_extension`.\\n\\n**Script callbacks:** ALWAYS use relative paths via `me.parent()` / `scriptOp.parent()`.\\n\\n**Cleaning nodes:** Always `list(root.children)` before iterating + `child.valid` check.\\n\\n## Recording / Exporting Video\\n\\n```python\\n# via td_execute_python:\\nroot = op('/project1')\\nrec = root.create(moviefileoutTOP, 'recorder')\\nop('/project1/out').outputConnectors[0].connect(rec.inputConnectors[0])\\nrec.par.type = 'movie'\\nrec.par.file = '/tmp/output.mov'\\nrec.par.videocodec = 'prores'  # Apple ProRes — NOT license-restricted on macOS\\nrec.par.record = True   # start\\n# rec.par.record = False  # stop (call separately later)\\n```\\n\\nH.264/H.265/AV1 need Commercial license. Use `prores` on macOS or `mjpa` as fallback.\\nExtract frames: `ffmpeg -i /tmp/output.mov -vframes 120 /tmp/frames/frame_%06d.png`\\n\\n**TOP.save() is useless for animation** — captures same GPU texture every time. Always use MovieFileOut.\\n\\n### Before Recording: Checklist\\n\\n1. **Verify FPS > 0** via `td_get_perf`. If FPS=0 the recording will be empty. See pitfalls #38-39.\\n2. **Verify shader output is not black** via `td_get_screenshot`. Black output = shader error or missing input. See pitfalls #8, #40.\\n3. **If recording with audio:** cue audio to start first, then delay recording by 3 frames. See pitfalls #19.\\n4. **Set output path before starting record** — setting both in the same script can race.\\n\\n## Audio-Reactive GLSL (Proven Recipe)\\n\\n### Correct signal chain (tested April 2026)\\n\\n```\\nAudioFileIn CHOP (playmode=sequential)\\n  → AudioSpectrum CHOP (FFT=512, outputmenu=setmanually, outlength=256, timeslice=ON)\\n  → Math CHOP (gain=10)\\n  → CHOP to TOP (dataformat=r, layout=rowscropped)\\n  → GLSL TOP input 1 (spectrum texture, 256x2)\\n\\nConstant TOP (rgba32float, time) → GLSL TOP input 0\\nGLSL TOP → Null TOP → MovieFileOut\\n```\\n\\n### Critical audio-reactive rules (empirically verified)\\n\\n1. **TimeSlice must stay ON** for AudioSpectrum. OFF = processes entire audio file → 24000+ samples → CHOP to TOP overflow.\\n2. **Set Output Length manually** to 256 via `outputmenu='setmanually'` and `outlength=256`. Default outputs 22050 samples.\\n3. **DO NOT use Lag CHOP for spectrum smoothing.** Lag CHOP operates in timeslice mode and expands 256 samples to 2400+, averaging all values to near-zero (~1e-06). The shader receives no usable data. This was the #1 audio sync failure in testing.\\n4. **DO NOT use Filter CHOP either** — same timeslice expansion problem with spectrum data.\\n5. **Smoothing belongs in the GLSL shader** if needed, via temporal lerp with a feedback texture: `mix(prevValue, newValue, 0.3)`. This gives frame-perfect sync with zero pipeline latency.\\n6. **CHOP to TOP dataformat = 'r'**, layout = 'rowscropped'. Spectrum output is 256x2 (stereo). Sample at y=0.25 for first channel.\\n7. **Math gain = 10** (not 5). Raw spectrum values are ~0.19 in bass range. Gain of 10 gives usable ~5.0 for the shader.\\n8. **No Resample CHOP needed.** Control output size via AudioSpectrum's `outlength` param directly.\\n\\n### GLSL spectrum sampling\\n\\n```glsl\\n// Input 0 = time (1x1 rgba32float), Input 1 = spectrum (256x2)\\nfloat iTime = texture(sTD2DInputs[0], vec2(0.5)).r;\\n\\n// Sample multiple points per band and average for stability:\\n// NOTE: y=0.25 for first channel (stereo texture is 256x2, first row center is 0.25)\\nfloat bass = (texture(sTD2DInputs[1], vec2(0.02, 0.25)).r +\\n              texture(sTD2DInputs[1], vec2(0.05, 0.25)).r) / 2.0;\\nfloat mid  = (texture(sTD2DInputs[1], vec2(0.2, 0.25)).r +\\n              texture(sTD2DInputs[1], vec2(0.35, 0.25)).r) / 2.0;\\nfloat hi   = (texture(sTD2DInputs[1], vec2(0.6, 0.25)).r +\\n              texture(sTD2DInputs[1], vec2(0.8, 0.25)).r) / 2.0;\\n```\\n\\nSee `references/network-patterns.md` for complete build scripts + shader code.\\n\\n## Operator Quick Reference\\n\\n| Family | Color | Python class / MCP type | Suffix |\\n|--------|-------|-------------|--------|\\n| TOP | Purple | noiseTOP, glslTOP, compositeTOP, levelTop, blurTOP, textTOP, nullTOP | TOP |\\n| CHOP | Green | audiofileinCHOP, audiospectrumCHOP, mathCHOP, lfoCHOP, constantCHOP | CHOP |\\n| SOP | Blue | gridSOP, sphereSOP, transformSOP, noiseSOP | SOP |\\n| DAT | White | textDAT, tableDAT, scriptDAT, webserverDAT | DAT |\\n| MAT | Yellow | phongMAT, pbrMAT, glslMAT, constMAT | MAT |\\n| COMP | Gray | geometryCOMP, containerCOMP, cameraCOMP, lightCOMP, windowCOMP | COMP |\\n\\n## Security Notes\\n\\n- MCP runs on localhost only (port 40404). No authentication — any local process can send commands.\\n- `td_execute_python` has unrestricted access to the TD Python environment and filesystem as the TD process user.\\n- `setup.sh` downloads twozero.tox from the official 404zero.com URL. Verify the download if concerned.\\n- The skill never sends data outside localhost. All MCP communication is local.\\n\\n## References\\n\\n| File | What |\\n|------|------|\\n| `references/pitfalls.md` | Hard-won lessons from real sessions |\\n| `references/operators.md` | All operator families with params and use cases |\\n| `references/network-patterns.md` | Recipes: audio-reactive, generative, GLSL, instancing |\\n| `references/mcp-tools.md` | Full twozero MCP tool parameter schemas |\\n| `references/python-api.md` | TD Python: op(), scripting, extensions |\\n| `references/troubleshooting.md` | Connection diagnostics, debugging |\\n| `references/glsl.md` | GLSL uniforms, built-in functions, shader templates |\\n| `references/postfx.md` | Post-FX: bloom, CRT, chromatic aberration, feedback glow |\\n| `references/layout-compositor.md` | HUD layout patterns, panel grids, BSP-style layouts |\\n| `references/operator-tips.md` | Wireframe rendering, feedback TOP setup |\\n| `references/geometry-comp.md` | Geometry COMP: instancing, POP vs SOP, morphing |\\n| `references/audio-reactive.md` | Audio band extraction, beat detection, envelope following |\\n| `references/animation.md` | LFOs, timers, keyframes, easing, expression-driven motion |\\n| `references/midi-osc.md` | MIDI/OSC controllers, TouchOSC, multi-machine sync |\\n| `references/particles.md` | POPs and legacy particleSOP — emission, forces, collisions |\\n| `references/projection-mapping.md` | Multi-window output, corner pin, mesh warp, edge blending |\\n| `references/external-data.md` | HTTP, WebSocket, MQTT, Serial, TCP, webserverDAT |\\n| `references/panel-ui.md` | Custom params, panel COMPs, button/slider/field, panelExecuteDAT |\\n| `references/replicator.md` | replicatorCOMP — data-driven cloning, layouts, callbacks |\\n| `references/dat-scripting.md` | Execute DAT family — chop/dat/parameter/panel/op/executeDAT |\\n| `references/3d-scene.md` | Lighting rigs, shadows, IBL/cubemaps, multi-camera, PBR |\\n| `scripts/setup.sh` | Automated setup script |\\n\\n---\\n\\n> You're not writing code. You're conducting light.\\n\", \"path\": \"creative/touchdesigner-mcp/SKILL.md\", \"skill_dir\": \"/home/kuhnn/.hermes/skills/creative/touchdesigner-mcp\", \"linked_files\": {\"references\": [\"references/geometry-comp.md\", \"references/audio-reactive.md\", \"references/python-api.md\", \"references/projection-mapping.md\", \"references/dat-scripting.md\", \"references/glsl.md\", \"references/network-patterns.md\", \"references/replicator.md\", \"references/midi-osc.md\", \"references/layout-compositor.md\", \"references/troubleshooting.md\", \"references/operators.md\", \"references/panel-ui.md\", \"references/operator-tips.md\", \"references/postfx.md\", \"references/particles.md\", \"references/external-data.md\", \"references/animation.md\", \"references/pitfalls.md\", \"references/3d-scene.md\", \"references/mcp-tools.md\"], \"scripts\": [\"scripts/setup.sh\"]}, \"usage_hint\": \"To view linked files, call skill_view(name, file_path) where file_path is e.g. 'references/api.md' or 'assets/config.yaml'\", \"required_environment_variables\": [], \"required_commands\": [], \"missing_required_environment_variables\": [], \"missing_credential_files\": [], \"missing_required_commands\": [], \"setup_needed\": false, \"setup_skipped\": false, \"readiness_status\": \"available\", \"metadata\": {\"hermes\": {\"tags\": [\"TouchDesigner\", \"MCP\", \"twozero\", \"creative-coding\", \"real-time-visuals\", \"generative-art\", \"audio-reactive\", \"VJ\", \"installation\", \"GLSL\"], \"related_skills\": [\"native-mcp\", \"ascii-video\", \"manim-video\", \"hermes-video\"]}}}",
      "tool_call_id": "call_function_482zhhlnflgr_6"
    },
    {
      "role": "tool",
      "name": "skill_view",
      "content": "{\"success\": true, \"name\": \"jupyter-live-kernel\", \"description\": \"Iterative Python via live Jupyter kernel (hamelnb).\", \"tags\": [\"jupyter\", \"notebook\", \"repl\", \"data-science\", \"exploration\", \"iterative\"], \"related_skills\": [], \"content\": \"---\\nname: jupyter-live-kernel\\ndescription: \\\"Iterative Python via live Jupyter kernel (hamelnb).\\\"\\nversion: 1.0.0\\nauthor: Hermes Agent\\nlicense: MIT\\nplatforms: [linux, macos, windows]\\nmetadata:\\n  hermes:\\n    tags: [jupyter, notebook, repl, data-science, exploration, iterative]\\n    category: data-science\\n---\\n\\n# Jupyter Live Kernel (hamelnb)\\n\\nGives you a **stateful Python REPL** via a live Jupyter kernel. Variables persist\\nacross executions. Use this instead of `execute_code` when you need to build up\\nstate incrementally, explore APIs, inspect DataFrames, or iterate on complex code.\\n\\n## When to Use This vs Other Tools\\n\\n| Tool | Use When |\\n|------|----------|\\n| **This skill** | Iterative exploration, state across steps, data science, ML, \\\"let me try this and check\\\" |\\n| `execute_code` | One-shot scripts needing hermes tool access (web_search, file ops). Stateless. |\\n| `terminal` | Shell commands, builds, installs, git, process management |\\n\\n**Rule of thumb:** If you'd want a Jupyter notebook for the task, use this skill.\\n\\n## Prerequisites\\n\\n1. **uv** must be installed (check: `which uv`)\\n2. **JupyterLab** must be installed: `uv tool install jupyterlab`\\n3. A Jupyter server must be running (see Setup below)\\n\\n## Setup\\n\\nThe hamelnb script location:\\n```\\nSCRIPT=\\\"$HOME/.agent-skills/hamelnb/skills/jupyter-live-kernel/scripts/jupyter_live_kernel.py\\\"\\n```\\n\\nIf not cloned yet:\\n```\\ngit clone https://github.com/hamelsmu/hamelnb.git ~/.agent-skills/hamelnb\\n```\\n\\n### Starting JupyterLab\\n\\nCheck if a server is already running:\\n```\\nuv run \\\"$SCRIPT\\\" servers\\n```\\n\\nIf no servers found, start one:\\n```\\njupyter-lab --no-browser --port=8888 --notebook-dir=$HOME/notebooks \\\\\\n  --IdentityProvider.token='' --ServerApp.password='' > /tmp/jupyter.log 2>&1 &\\nsleep 3\\n```\\n\\nNote: Token/password disabled for local agent access. The server runs headless.\\n\\n### Creating a Notebook for REPL Use\\n\\nIf you just need a REPL (no existing notebook), create a minimal notebook file:\\n```\\nmkdir -p ~/notebooks\\n```\\nWrite a minimal .ipynb JSON file with one empty code cell, then start a kernel\\nsession via the Jupyter REST API:\\n```\\ncurl -s -X POST http://127.0.0.1:8888/api/sessions \\\\\\n  -H \\\"Content-Type: application/json\\\" \\\\\\n  -d '{\\\"path\\\":\\\"scratch.ipynb\\\",\\\"type\\\":\\\"notebook\\\",\\\"name\\\":\\\"scratch.ipynb\\\",\\\"kernel\\\":{\\\"name\\\":\\\"python3\\\"}}'\\n```\\n\\n## Core Workflow\\n\\nAll commands return structured JSON. Always use `--compact` to save tokens.\\n\\n### 1. Discover servers and notebooks\\n\\n```\\nuv run \\\"$SCRIPT\\\" servers --compact\\nuv run \\\"$SCRIPT\\\" notebooks --compact\\n```\\n\\n### 2. Execute code (primary operation)\\n\\n```\\nuv run \\\"$SCRIPT\\\" execute --path <notebook.ipynb> --code '<python code>' --compact\\n```\\n\\nState persists across execute calls. Variables, imports, objects all survive.\\n\\nMulti-line code works with $'...' quoting:\\n```\\nuv run \\\"$SCRIPT\\\" execute --path scratch.ipynb --code $'import os\\\\nfiles = os.listdir(\\\".\\\")\\\\nprint(f\\\"Found {len(files)} files\\\")' --compact\\n```\\n\\n### 3. Inspect live variables\\n\\n```\\nuv run \\\"$SCRIPT\\\" variables --path <notebook.ipynb> list --compact\\nuv run \\\"$SCRIPT\\\" variables --path <notebook.ipynb> preview --name <varname> --compact\\n```\\n\\n### 4. Edit notebook cells\\n\\n```\\n# View current cells\\nuv run \\\"$SCRIPT\\\" contents --path <notebook.ipynb> --compact\\n\\n# Insert a new cell\\nuv run \\\"$SCRIPT\\\" edit --path <notebook.ipynb> insert \\\\\\n  --at-index <N> --cell-type code --source '<code>' --compact\\n\\n# Replace cell source (use cell-id from contents output)\\nuv run \\\"$SCRIPT\\\" edit --path <notebook.ipynb> replace-source \\\\\\n  --cell-id <id> --source '<new code>' --compact\\n\\n# Delete a cell\\nuv run \\\"$SCRIPT\\\" edit --path <notebook.ipynb> delete --cell-id <id> --compact\\n```\\n\\n### 5. Verification (restart + run all)\\n\\nOnly use when the user asks for a clean verification or you need to confirm\\nthe notebook runs top-to-bottom:\\n\\n```\\nuv run \\\"$SCRIPT\\\" restart-run-all --path <notebook.ipynb> --save-outputs --compact\\n```\\n\\n## Practical Tips from Experience\\n\\n1. **First execution after server start may timeout** — the kernel needs a moment\\n   to initialize. If you get a timeout, just retry.\\n\\n2. **The kernel Python is JupyterLab's Python** — packages must be installed in\\n   that environment. If you need additional packages, install them into the\\n   JupyterLab tool environment first.\\n\\n3. **--compact flag saves significant tokens** — always use it. JSON output can\\n   be very verbose without it.\\n\\n4. **For pure REPL use**, create a scratch.ipynb and don't bother with cell editing.\\n   Just use `execute` repeatedly.\\n\\n5. **Argument order matters** — subcommand flags like `--path` go BEFORE the\\n   sub-subcommand. E.g.: `variables --path nb.ipynb list` not `variables list --path nb.ipynb`.\\n\\n6. **If a session doesn't exist yet**, you need to start one via the REST API\\n   (see Setup section). The tool can't execute without a live kernel session.\\n\\n7. **Errors are returned as JSON** with traceback — read the `ename` and `evalue`\\n   fields to understand what went wrong.\\n\\n8. **Occasional websocket timeouts** — some operations may timeout on first try,\\n   especially after a kernel restart. Retry once before escalating.\\n\\n## Timeout Defaults\\n\\nThe script has a 30-second default timeout per execution. For long-running\\noperations, pass `--timeout 120`. Use generous timeouts (60+) for initial\\nsetup or heavy computation.\\n\", \"path\": \"data-science/jupyter-live-kernel/SKILL.md\", \"skill_dir\": \"/home/kuhnn/.hermes/skills/data-science/jupyter-live-kernel\", \"linked_files\": null, \"usage_hint\": null, \"required_environment_variables\": [], \"required_commands\": [], \"missing_required_environment_variables\": [], \"missing_credential_files\": [], \"missing_required_commands\": [], \"setup_needed\": false, \"setup_skipped\": false, \"readiness_status\": \"available\", \"metadata\": {\"hermes\": {\"tags\": [\"jupyter\", \"notebook\", \"repl\", \"data-science\", \"exploration\", \"iterative\"], \"category\": \"data-science\"}}}",
      "tool_call_id": "call_function_482zhhlnflgr_7"
    },
    {
      "role": "tool",
      "name": "skill_view",
      "content": "{\"success\": true, \"name\": \"kanban-orchestrator\", \"description\": \"Decomposition playbook + anti-temptation rules for an orchestrator profile routing work through Kanban. The \\\"don't do the work yourself\\\" rule and the basic lifecycle are auto-injected into every kanban worker's system prompt; this skill is the deeper playbook when you're specifically playing the orchestrator role.\", \"tags\": [\"kanban\", \"multi-agent\", \"orchestration\", \"routing\"], \"related_skills\": [\"kanban-worker\"], \"content\": \"---\\nname: kanban-orchestrator\\ndescription: Decomposition playbook + anti-temptation rules for an orchestrator profile routing work through Kanban. The \\\"don't do the work yourself\\\" rule and the basic lifecycle are auto-injected into every kanban worker's system prompt; this skill is the deeper playbook when you're specifically playing the orchestrator role.\\nversion: 3.0.0\\nplatforms: [linux, macos, windows]\\nmetadata:\\n  hermes:\\n    tags: [kanban, multi-agent, orchestration, routing]\\n    related_skills: [kanban-worker]\\n---\\n\\n# Kanban Orchestrator — Decomposition Playbook\\n\\n> The **core worker lifecycle** (including the `kanban_create` fan-out pattern and the \\\"decompose, don't execute\\\" rule) is auto-injected into every kanban process via the `KANBAN_GUIDANCE` system-prompt block. This skill is the deeper playbook when you're an orchestrator profile whose whole job is routing.\\n\\n## Profiles are user-configured — not a fixed roster\\n\\nHermes setups vary widely. Some users run a single profile that does everything; some run a small fleet (`docker-worker`, `cron-worker`); some run a curated specialist team they've named themselves. There is **no default specialist roster** — the orchestrator skill does not know what profiles exist on this machine.\\n\\nBefore fanning out, you must ground the decomposition in the profiles that actually exist. The dispatcher silently fails to spawn unknown assignee names — it doesn't autocorrect, doesn't suggest, doesn't fall back. So a card assigned to `researcher` on a setup that only has `docker-worker` just sits in `ready` forever.\\n\\n**Step 0: discover available profiles before planning.**\\n\\nUse one of these:\\n\\n- `hermes profile list` — prints the table of profiles configured on this machine. Run it through your terminal tool if you have one; otherwise ask the user.\\n- `kanban_list(assignee=\\\"<some-name>\\\")` — sanity-check a single name. Returns an empty list (rather than an error) for an unknown assignee, so this only confirms a name you're already considering.\\n- **Just ask the user.** \\\"What profiles do you have set up?\\\" is a fine first turn when the goal needs more than one specialist.\\n\\nCache the result in your working memory for the rest of the conversation. Re-asking every turn wastes a tool call.\\n\\n## When to use the board (vs. just doing the work)\\n\\nCreate Kanban tasks when any of these are true:\\n\\n1. **Multiple specialists are needed.** Research + analysis + writing is three profiles.\\n2. **The work should survive a crash or restart.** Long-running, recurring, or important.\\n3. **The user might want to interject.** Human-in-the-loop at any step.\\n4. **Multiple subtasks can run in parallel.** Fan-out for speed.\\n5. **Review / iteration is expected.** A reviewer profile loops on drafter output.\\n6. **The audit trail matters.** Board rows persist in SQLite forever.\\n\\nIf *none* of those apply — it's a small one-shot reasoning task — use `delegate_task` instead or answer the user directly.\\n\\n## The anti-temptation rules\\n\\nYour job description says \\\"route, don't execute.\\\" The rules that enforce that:\\n\\n- **Do not execute the work yourself.** Your restricted toolset usually doesn't even include terminal/file/code/web for implementation. If you find yourself \\\"just fixing this quickly\\\" — stop and create a task for the right specialist.\\n- **For any concrete task, create a Kanban task and assign it.** Every single time.\\n- **Split multi-lane requests before creating cards.** A user prompt can contain several independent workstreams. Extract those lanes first, then create one card per lane instead of bundling unrelated work into a single implementer card.\\n- **Run independent lanes in parallel.** If two cards do not need each other's output, leave them unlinked so the dispatcher can fan them out. Link only true data dependencies.\\n- **Never create dependent work as independent ready cards.** If a card must wait for another card, pass `parents=[...]` in the original `kanban_create` call. Do not create it first and link it later, and do not rely on prose like \\\"wait for T1\\\" inside the body.\\n- **If no specialist fits the available profiles, ask the user which profile to create or which existing profile to use.** Do not invent profile names; the dispatcher will silently drop unknown assignees.\\n- **Decompose, route, and summarize — that's the whole job.**\\n\\n## Decomposition playbook\\n\\n### Step 1 — Understand the goal\\n\\nAsk clarifying questions if the goal is ambiguous. Cheap to ask; expensive to spawn the wrong fleet.\\n\\n### Step 2 — Sketch the task graph\\n\\nBefore creating anything, draft the graph out loud (in your response to the user). Treat every concrete workstream as a candidate card:\\n\\n1. Extract the lanes from the request.\\n2. Map each lane to one of the profiles you discovered in Step 0. If a lane doesn't fit any existing profile, ask the user which to use or create.\\n3. Decide whether each lane is independent or gated by another lane.\\n4. Create independent lanes as parallel cards with no parent links.\\n5. Create synthesis/review/integration cards with parent links to the lanes they depend on. A child created with unfinished parents starts in `todo`; the dispatcher promotes it to `ready` only after every parent is done.\\n\\nExamples of prompts that should fan out (using placeholder profile names — substitute whatever exists on the user's setup):\\n\\n- \\\"Build an app\\\" → one card to a design-oriented profile for product/UI direction, one or two cards to engineering profiles for implementation, plus a later integration/review card if the user has a reviewer profile.\\n- \\\"Fix blockers and check model variants\\\" → one implementation card for the blocker fixes plus one discovery/research card for config/source verification. A final reviewer card can depend on both.\\n- \\\"Research docs and implement\\\" → a docs-research card can run in parallel with a codebase-discovery card; implementation waits only if it truly needs those findings.\\n- \\\"Analyze this screenshot and find the related code\\\" → one card to a vision-capable profile for the visual analysis while another searches the codebase.\\n\\nWords like \\\"also,\\\" \\\"finally,\\\" or \\\"and\\\" do not automatically imply a dependency. They often mean \\\"make sure this is covered before reporting back.\\\" Only link tasks when one card cannot start until another card's output exists.\\n\\nShow the graph to the user before creating cards. Let them correct it — including which actual profile name should own each lane.\\n\\n### Step 3 — Create tasks and link\\n\\nUse the profile names from Step 0. The example below uses placeholders `<profile-A>`, `<profile-B>`, `<profile-C>` — replace them with what the user actually has.\\n\\n```python\\nt1 = kanban_create(\\n    title=\\\"research: Postgres cost vs current\\\",\\n    assignee=\\\"<profile-A>\\\",  # whichever profile handles research on this setup\\n    body=\\\"Compare estimated infrastructure costs, migration costs, and ongoing ops costs over a 3-year window. Sources: AWS/GCP pricing, team time estimates, current Postgres bills from peers.\\\",\\n    tenant=os.environ.get(\\\"HERMES_TENANT\\\"),\\n)[\\\"task_id\\\"]\\n\\nt2 = kanban_create(\\n    title=\\\"research: Postgres performance vs current\\\",\\n    assignee=\\\"<profile-A>\\\",  # same profile, run in parallel\\n    body=\\\"Compare query latency, throughput, and scaling characteristics at our expected data volume (~500GB, 10k QPS peak). Sources: benchmark papers, public case studies, pgbench results if easy.\\\",\\n)[\\\"task_id\\\"]\\n\\nt3 = kanban_create(\\n    title=\\\"synthesize migration recommendation\\\",\\n    assignee=\\\"<profile-B>\\\",  # whichever profile does synthesis/analysis\\n    body=\\\"Read the findings from T1 (cost) and T2 (performance). Produce a 1-page recommendation with explicit trade-offs and a go/no-go call.\\\",\\n    parents=[t1, t2],\\n)[\\\"task_id\\\"]\\n\\nt4 = kanban_create(\\n    title=\\\"draft decision memo\\\",\\n    assignee=\\\"<profile-C>\\\",  # whichever profile drafts user-facing prose\\n    body=\\\"Turn the analyst's recommendation into a 2-page memo for the CTO. Match the tone of previous decision memos in the team's knowledge base.\\\",\\n    parents=[t3],\\n)[\\\"task_id\\\"]\\n```\\n\\n`parents=[...]` gates promotion — children stay in `todo` until every parent reaches `done`, then auto-promote to `ready`. No manual coordination needed; the dispatcher and dependency engine handle it.\\n\\nIf the task graph has dependencies, create the parent cards first, capture their returned ids, and include those ids in the child card's `parents` list during the child `kanban_create` call. Avoid creating all cards in parallel and linking them afterward; that creates a window where the dispatcher can claim a child before its inputs exist.\\n\\n### Step 4 — Complete your own task\\n\\nIf you were spawned as a task yourself (e.g. a planner profile was assigned `T0: \\\"investigate Postgres migration\\\"`), mark it done with a summary of what you created:\\n\\n```python\\nkanban_complete(\\n    summary=\\\"decomposed into T1-T4: 2 research lanes in parallel, 1 synthesis on their outputs, 1 prose draft on the recommendation\\\",\\n    metadata={\\n        \\\"task_graph\\\": {\\n            \\\"T1\\\": {\\\"assignee\\\": \\\"<profile-A>\\\", \\\"parents\\\": []},\\n            \\\"T2\\\": {\\\"assignee\\\": \\\"<profile-A>\\\", \\\"parents\\\": []},\\n            \\\"T3\\\": {\\\"assignee\\\": \\\"<profile-B>\\\", \\\"parents\\\": [\\\"T1\\\", \\\"T2\\\"]},\\n            \\\"T4\\\": {\\\"assignee\\\": \\\"<profile-C>\\\", \\\"parents\\\": [\\\"T3\\\"]},\\n        },\\n    },\\n)\\n```\\n\\n### Step 5 — Report back to the user\\n\\nTell them what you created in plain prose, naming the actual profiles you used:\\n\\n> I've queued 4 tasks:\\n> - **T1** (`<profile-A>`): cost comparison\\n> - **T2** (`<profile-A>`): performance comparison, in parallel with T1\\n> - **T3** (`<profile-B>`): synthesizes T1 + T2 into a recommendation\\n> - **T4** (`<profile-C>`): turns T3 into a CTO memo\\n>\\n> The dispatcher will pick up T1 and T2 now. T3 starts when both finish. You'll get a gateway ping when T4 completes. Use the dashboard or `hermes kanban tail <id>` to follow along.\\n\\n## Common patterns\\n\\n**Fan-out + fan-in (research → synthesize):** N research-style cards with no parents, one synthesis card with all of them as parents.\\n\\n**Parallel implementation + validation:** one implementer card makes the change while one explorer/researcher card verifies config, docs, or source mapping. A reviewer card can depend on both. Do not make the implementer own unrelated verification just because the user mentioned both in one sentence.\\n\\n**Pipeline with gates:** `planner → implementer → reviewer`. Each stage's `parents=[previous_task]`. Reviewer blocks or completes; if reviewer blocks, the operator unblocks with feedback and respawns.\\n\\n**Same-profile queue:** N tasks, all assigned to the same profile, no dependencies between them. Dispatcher serializes — that profile processes them in priority order, accumulating experience in its own memory.\\n\\n**Human-in-the-loop:** Any task can `kanban_block()` to wait for input. Dispatcher respawns after `/unblock`. The comment thread carries the full context.\\n\\n## Pitfalls\\n\\n**Inventing profile names that don't exist.** The dispatcher silently fails to spawn unknown assignees — the card just sits in `ready` forever. Always assign to a profile from your Step 0 discovery; ask the user if you're unsure.\\n\\n**Bundling independent lanes into one card.** If the user asks for two independent outcomes, create two cards. Example: \\\"fix blockers and check model variants\\\" is not one fixer task; create a fixer/engineer card for the fixes and an explorer/researcher card for the variant check, then optionally gate review on both.\\n\\n**Over-linking because of wording.** \\\"Finally check X\\\" may still be parallel with implementation if X is static config, docs, or source discovery. Link it after implementation only when the check depends on the implementation result.\\n\\n**Forgetting dependency links.** If the task graph says `research -> implement -> review`, do not create all tasks as independent ready cards. Use parent links so implement/review cannot run before their inputs exist.\\n\\n**Reassignment vs. new task.** If a reviewer blocks with \\\"needs changes,\\\" create a NEW task linked from the reviewer's task — don't re-run the same task with a stern look. The new task is assigned to the original implementer profile.\\n\\n**Argument order for links.** `kanban_link(parent_id=..., child_id=...)` — parent first. Mixing them up demotes the wrong task to `todo`.\\n\\n**Don't pre-create the whole graph if the shape depends on intermediate findings.** If T3's structure depends on what T1 and T2 find, let T3 exist as a \\\"synthesize findings\\\" task whose own first step is to read parent handoffs and plan the rest. Orchestrators can spawn orchestrators.\\n\\n**Tenant inheritance.** If `HERMES_TENANT` is set in your env, pass `tenant=os.environ.get(\\\"HERMES_TENANT\\\")` on every `kanban_create` call so child tasks stay in the same namespace.\\n\\n## Recovering stuck workers\\n\\nWhen a worker profile keeps crashing, hallucinating, or getting blocked by its own mistakes (usually: wrong model, missing skill, broken credential), the kanban dashboard flags the task with a ⚠ badge and opens a **Recovery** section in the drawer. Three primary actions:\\n\\n1. **Reclaim** (or `hermes kanban reclaim <task_id>`) — abort the running worker immediately and reset the task to `ready`. The existing claim TTL is ~15 min; this is the fast path out.\\n2. **Reassign** (or `hermes kanban reassign <task_id> <new-profile> --reclaim`) — switch the task to a different profile (one that exists on this setup) and let the dispatcher pick it up with a fresh worker.\\n3. **Change profile model** — the dashboard prints a copy-paste hint for `hermes -p <profile> model` since profile config lives on disk; edit it in a terminal, then Reclaim to retry with the new model.\\n\\nHallucination warnings appear on tasks where a worker's `kanban_complete(created_cards=[...])` claim included card ids that don't exist or weren't created by the worker's profile (the gate blocks the completion), or where the free-form summary references `t_<hex>` ids that don't resolve (advisory prose scan, non-blocking). Both produce audit events that persist even after recovery actions — the trail stays for debugging.\\n\", \"path\": \"devops/kanban-orchestrator/SKILL.md\", \"skill_dir\": \"/home/kuhnn/.hermes/skills/devops/kanban-orchestrator\", \"linked_files\": null, \"usage_hint\": null, \"required_environment_variables\": [], \"required_commands\": [], \"missing_required_environment_variables\": [], \"missing_credential_files\": [], \"missing_required_commands\": [], \"setup_needed\": false, \"setup_skipped\": false, \"readiness_status\": \"available\", \"metadata\": {\"hermes\": {\"tags\": [\"kanban\", \"multi-agent\", \"orchestration\", \"routing\"], \"related_skills\": [\"kanban-worker\"]}}}",
      "tool_call_id": "call_function_482zhhlnflgr_8"
    },
    {
      "role": "tool",
      "name": "skill_view",
      "content": "{\"success\": true, \"name\": \"kanban-worker\", \"description\": \"Pitfalls, examples, and edge cases for Hermes Kanban workers. The lifecycle itself is auto-injected into every worker's system prompt as KANBAN_GUIDANCE (from agent/prompt_builder.py); this skill is what you load when you want deeper detail on specific scenarios.\", \"tags\": [\"kanban\", \"multi-agent\", \"collaboration\", \"workflow\", \"pitfalls\"], \"related_skills\": [\"kanban-orchestrator\"], \"content\": \"---\\nname: kanban-worker\\ndescription: Pitfalls, examples, and edge cases for Hermes Kanban workers. The lifecycle itself is auto-injected into every worker's system prompt as KANBAN_GUIDANCE (from agent/prompt_builder.py); this skill is what you load when you want deeper detail on specific scenarios.\\nversion: 2.0.0\\nplatforms: [linux, macos, windows]\\nmetadata:\\n  hermes:\\n    tags: [kanban, multi-agent, collaboration, workflow, pitfalls]\\n    related_skills: [kanban-orchestrator]\\n---\\n\\n# Kanban Worker — Pitfalls and Examples\\n\\n> You're seeing this skill because the Hermes Kanban dispatcher spawned you as a worker with `--skills kanban-worker` — it's loaded automatically for every dispatched worker. The **lifecycle** (6 steps: orient → work → heartbeat → block/complete) also lives in the `KANBAN_GUIDANCE` block that's auto-injected into your system prompt. This skill is the deeper detail: good handoff shapes, retry diagnostics, edge cases.\\n\\n## Workspace handling\\n\\nYour workspace kind determines how you should behave inside `$HERMES_KANBAN_WORKSPACE`:\\n\\n| Kind | What it is | How to work |\\n|---|---|---|\\n| `scratch` | Fresh tmp dir, yours alone | Read/write freely; it gets GC'd when the task is archived. |\\n| `dir:<path>` | Shared persistent directory | Other runs will read what you write. Treat it like long-lived state. Path is guaranteed absolute (the kernel rejects relative paths). |\\n| `worktree` | Git worktree at the resolved path | If `.git` doesn't exist, run `git worktree add <path> <branch>` from the main repo first, then cd and work normally. Commit work here. |\\n\\n## Tenant isolation\\n\\nIf `$HERMES_TENANT` is set, the task belongs to a tenant namespace. When reading or writing persistent memory, prefix memory entries with the tenant so context doesn't leak across tenants:\\n\\n- Good: `business-a: Acme is our biggest customer`\\n- Bad (leaks): `Acme is our biggest customer`\\n\\n## Good summary + metadata shapes\\n\\nThe `kanban_complete(summary=..., metadata=...)` handoff is how downstream workers read what you did. Patterns that work:\\n\\n**Coding task:**\\n```python\\nkanban_complete(\\n    summary=\\\"shipped rate limiter — token bucket, keys on user_id with IP fallback, 14 tests pass\\\",\\n    metadata={\\n        \\\"changed_files\\\": [\\\"rate_limiter.py\\\", \\\"tests/test_rate_limiter.py\\\"],\\n        \\\"tests_run\\\": 14,\\n        \\\"tests_passed\\\": 14,\\n        \\\"decisions\\\": [\\\"user_id primary, IP fallback for unauthenticated requests\\\"],\\n    },\\n)\\n```\\n\\n**Coding task that needs human review (review-required):**\\n\\nFor most code-changing tasks, the work isn't truly *done* until a human reviewer has eyes on it. Block instead of complete, with `reason` prefixed `review-required: ` so the dashboard surfaces the row as needing review. Drop the structured metadata (changed files, test counts, diff/PR url) into a comment first, since `kanban_block` only carries the human-readable reason — comments are the durable annotation channel. Reviewer either approves and runs `hermes kanban unblock <id>` (which re-spawns you with the comment thread for any follow-ups) or asks for changes via another comment.\\n\\n```python\\nimport json\\n\\nkanban_comment(\\n    body=\\\"review-required handoff:\\\\n\\\" + json.dumps({\\n        \\\"changed_files\\\": [\\\"rate_limiter.py\\\", \\\"tests/test_rate_limiter.py\\\"],\\n        \\\"tests_run\\\": 14,\\n        \\\"tests_passed\\\": 14,\\n        \\\"diff_path\\\": \\\"/path/to/worktree\\\",  # or PR url if pushed\\n        \\\"decisions\\\": [\\\"user_id primary, IP fallback for unauthenticated requests\\\"],\\n    }, indent=2),\\n)\\nkanban_block(\\n    reason=\\\"review-required: rate limiter shipped, 14/14 tests pass — needs eyes on the user_id/IP fallback choice before merging\\\",\\n)\\n```\\n\\nUse `kanban_complete` only when the task is genuinely terminal — e.g. a one-line typo fix, a docs change with no functional consequences, or a research task where the artifact IS the writeup itself.\\n\\n**Research task:**\\n```python\\nkanban_complete(\\n    summary=\\\"3 competing libraries reviewed; vLLM wins on throughput, SGLang on latency, Tensorrt-LLM on memory efficiency\\\",\\n    metadata={\\n        \\\"sources_read\\\": 12,\\n        \\\"recommendation\\\": \\\"vLLM\\\",\\n        \\\"benchmarks\\\": {\\\"vllm\\\": 1.0, \\\"sglang\\\": 0.87, \\\"trtllm\\\": 0.72},\\n    },\\n)\\n```\\n\\n**Review task:**\\n```python\\nkanban_complete(\\n    summary=\\\"reviewed PR #123; 2 blocking issues found (SQL injection in /search, missing CSRF on /settings)\\\",\\n    metadata={\\n        \\\"pr_number\\\": 123,\\n        \\\"findings\\\": [\\n            {\\\"severity\\\": \\\"critical\\\", \\\"file\\\": \\\"api/search.py\\\", \\\"line\\\": 42, \\\"issue\\\": \\\"raw SQL concat\\\"},\\n            {\\\"severity\\\": \\\"high\\\", \\\"file\\\": \\\"api/settings.py\\\", \\\"issue\\\": \\\"missing CSRF middleware\\\"},\\n        ],\\n        \\\"approved\\\": False,\\n    },\\n)\\n```\\n\\nShape `metadata` so downstream parsers (reviewers, aggregators, schedulers) can use it without re-reading your prose.\\n\\n## Claiming cards you actually created\\n\\nIf your run produced new kanban tasks (via `kanban_create`), pass the ids in `created_cards` on `kanban_complete`. The kernel verifies each id exists and was created by your profile; any phantom id blocks the completion with an error listing what went wrong, and the rejected attempt is permanently recorded on the task's event log. **Only list ids you captured from a successful `kanban_create` return value — never invent ids from prose, never paste ids from earlier runs, never claim cards another worker created.**\\n\\n```python\\n# GOOD — capture return values, then claim them.\\nc1 = kanban_create(title=\\\"remediate SQL injection\\\", assignee=\\\"security-worker\\\")\\nc2 = kanban_create(title=\\\"fix CSRF middleware\\\", assignee=\\\"web-worker\\\")\\n\\nkanban_complete(\\n    summary=\\\"Review done; spawned remediations for both findings.\\\",\\n    metadata={\\\"pr_number\\\": 123, \\\"approved\\\": False},\\n    created_cards=[c1[\\\"task_id\\\"], c2[\\\"task_id\\\"]],\\n)\\n```\\n\\n```python\\n# BAD — claiming ids you don't have captured return values for.\\nkanban_complete(\\n    summary=\\\"Created remediation cards t_a1b2c3d4, t_deadbeef\\\",  # hallucinated\\n    created_cards=[\\\"t_a1b2c3d4\\\", \\\"t_deadbeef\\\"],                   # → gate rejects\\n)\\n```\\n\\nIf a `kanban_create` call fails (exception, tool_error), the card was NOT created — do not include a phantom id for it. Retry the create, or omit the id and mention the failure in your summary. The prose-scan pass also catches `t_<hex>` references in your free-form summary that don't resolve; these don't block the completion but show up as advisory warnings on the task in the dashboard.\\n\\n## Block reasons that get answered fast\\n\\nBad: `\\\"stuck\\\"` — the human has no context.\\n\\nGood: one sentence naming the specific decision you need. Leave longer context as a comment instead.\\n\\n```python\\nkanban_comment(\\n    task_id=os.environ[\\\"HERMES_KANBAN_TASK\\\"],\\n    body=\\\"Full context: I have user IPs from Cloudflare headers but some users are behind NATs with thousands of peers. Keying on IP alone causes false positives.\\\",\\n)\\nkanban_block(reason=\\\"Rate limit key choice: IP (simple, NAT-unsafe) or user_id (requires auth, skips anonymous endpoints)?\\\")\\n```\\n\\nThe block message is what appears in the dashboard / gateway notifier. The comment is the deeper context a human reads when they open the task.\\n\\n## Heartbeats worth sending\\n\\nGood heartbeats name progress: `\\\"epoch 12/50, loss 0.31\\\"`, `\\\"scanned 1.2M/2.4M rows\\\"`, `\\\"uploaded 47/120 videos\\\"`.\\n\\nBad heartbeats: `\\\"still working\\\"`, empty notes, sub-second intervals. Every few minutes max; skip entirely for tasks under ~2 minutes.\\n\\n## Retry scenarios\\n\\nIf you open the task and `kanban_show` returns `runs: [...]` with one or more closed runs, you're a retry. The prior runs' `outcome` / `summary` / `error` tell you what didn't work. Don't repeat that path. Typical retry diagnostics:\\n\\n- `outcome: \\\"timed_out\\\"` — the previous attempt hit `max_runtime_seconds`. You may need to chunk the work or shorten it.\\n- `outcome: \\\"crashed\\\"` — OOM or segfault. Reduce memory footprint.\\n- `outcome: \\\"spawn_failed\\\"` + `error: \\\"...\\\"` — usually a profile config issue (missing credential, bad PATH). Ask the human via `kanban_block` instead of retrying blindly.\\n- `outcome: \\\"reclaimed\\\"` + `summary: \\\"task archived...\\\"` — operator archived the task out from under the previous run; you probably shouldn't be running at all, check status carefully.\\n- `outcome: \\\"blocked\\\"` — a previous attempt blocked; the unblock comment should be in the thread by now.\\n\\n## Do NOT\\n\\n- Call `delegate_task` as a substitute for `kanban_create`. `delegate_task` is for short reasoning subtasks inside YOUR run; `kanban_create` is for cross-agent handoffs that outlive one API loop.\\n- Modify files outside `$HERMES_KANBAN_WORKSPACE` unless the task body says to.\\n- Create follow-up tasks assigned to yourself — assign to the right specialist.\\n- Complete a task you didn't actually finish. Block it instead.\\n\\n## Pitfalls\\n\\n**Task state can change between dispatch and your startup.** Between when the dispatcher claimed and when your process actually booted, the task may have been blocked, reassigned, or archived. Always `kanban_show` first. If it reports `blocked` or `archived`, stop — you shouldn't be running.\\n\\n**Workspace may have stale artifacts.** Especially `dir:` and `worktree` workspaces can have files from previous runs. Read the comment thread — it usually explains why you're running again and what state the workspace is in.\\n\\n**Don't rely on the CLI when the guidance is available.** The `kanban_*` tools work across all terminal backends (Docker, Modal, SSH). `hermes kanban <verb>` from your terminal tool will fail in containerized backends because the CLI isn't installed there. When in doubt, use the tool.\\n\\n## CLI fallback (for scripting)\\n\\nEvery tool has a CLI equivalent for human operators and scripts:\\n- `kanban_show` ↔ `hermes kanban show <id> --json`\\n- `kanban_complete` ↔ `hermes kanban complete <id> --summary \\\"...\\\" --metadata '{...}'`\\n- `kanban_block` ↔ `hermes kanban block <id> \\\"reason\\\"`\\n- `kanban_create` ↔ `hermes kanban create \\\"title\\\" --assignee <profile> [--parent <id>]`\\n- etc.\\n\\nUse the tools from inside an agent; the CLI exists for the human at the terminal.\\n\", \"path\": \"devops/kanban-worker/SKILL.md\", \"skill_dir\": \"/home/kuhnn/.hermes/skills/devops/kanban-worker\", \"linked_files\": null, \"usage_hint\": null, \"required_environment_variables\": [], \"required_commands\": [], \"missing_required_environment_variables\": [], \"missing_credential_files\": [], \"missing_required_commands\": [], \"setup_needed\": false, \"setup_skipped\": false, \"readiness_status\": \"available\", \"metadata\": {\"hermes\": {\"tags\": [\"kanban\", \"multi-agent\", \"collaboration\", \"workflow\", \"pitfalls\"], \"related_skills\": [\"kanban-orchestrator\"]}}}",
      "tool_call_id": "call_function_482zhhlnflgr_9"
    },
    {
      "role": "tool",
      "name": "skill_view",
      "content": "{\"success\": true, \"name\": \"webhook-subscriptions\", \"description\": \"Webhook subscriptions: event-driven agent runs.\", \"tags\": [\"webhook\", \"events\", \"automation\", \"integrations\", \"notifications\", \"push\"], \"related_skills\": [], \"content\": \"---\\nname: webhook-subscriptions\\ndescription: \\\"Webhook subscriptions: event-driven agent runs.\\\"\\nversion: 1.1.0\\nplatforms: [linux, macos, windows]\\nmetadata:\\n  hermes:\\n    tags: [webhook, events, automation, integrations, notifications, push]\\n---\\n\\n# Webhook Subscriptions\\n\\nCreate dynamic webhook subscriptions so external services (GitHub, GitLab, Stripe, CI/CD, IoT sensors, monitoring tools) can trigger Hermes agent runs by POSTing events to a URL.\\n\\n## Setup (Required First)\\n\\nThe webhook platform must be enabled before subscriptions can be created. Check with:\\n```bash\\nhermes webhook list\\n```\\n\\nIf it says \\\"Webhook platform is not enabled\\\", set it up:\\n\\n### Option 1: Setup wizard\\n```bash\\nhermes gateway setup\\n```\\nFollow the prompts to enable webhooks, set the port, and set a global HMAC secret.\\n\\n### Option 2: Manual config\\nAdd to `~/.hermes/config.yaml`:\\n```yaml\\nplatforms:\\n  webhook:\\n    enabled: true\\n    extra:\\n      host: \\\"0.0.0.0\\\"\\n      port: 8644\\n      secret: \\\"generate-a-strong-secret-here\\\"\\n```\\n\\n### Option 3: Environment variables\\nAdd to `~/.hermes/.env`:\\n```bash\\nWEBHOOK_ENABLED=true\\nWEBHOOK_PORT=8644\\nWEBHOOK_SECRET=generate-a-strong-secret-here\\n```\\n\\nAfter configuration, start (or restart) the gateway:\\n```bash\\nhermes gateway run\\n# Or if using systemd:\\nsystemctl --user restart hermes-gateway\\n```\\n\\nVerify it's running:\\n```bash\\ncurl http://localhost:8644/health\\n```\\n\\n## Commands\\n\\nAll management is via the `hermes webhook` CLI command:\\n\\n### Create a subscription\\n```bash\\nhermes webhook subscribe <name> \\\\\\n  --prompt \\\"Prompt template with {payload.fields}\\\" \\\\\\n  --events \\\"event1,event2\\\" \\\\\\n  --description \\\"What this does\\\" \\\\\\n  --skills \\\"skill1,skill2\\\" \\\\\\n  --deliver telegram \\\\\\n  --deliver-chat-id \\\"12345\\\" \\\\\\n  --secret \\\"optional-custom-secret\\\"\\n```\\n\\nReturns the webhook URL and HMAC secret. The user configures their service to POST to that URL.\\n\\n### List subscriptions\\n```bash\\nhermes webhook list\\n```\\n\\n### Remove a subscription\\n```bash\\nhermes webhook remove <name>\\n```\\n\\n### Test a subscription\\n```bash\\nhermes webhook test <name>\\nhermes webhook test <name> --payload '{\\\"key\\\": \\\"value\\\"}'\\n```\\n\\n## Prompt Templates\\n\\nPrompts support `{dot.notation}` for accessing nested payload fields:\\n\\n- `{issue.title}` — GitHub issue title\\n- `{pull_request.user.login}` — PR author\\n- `{data.object.amount}` — Stripe payment amount\\n- `{sensor.temperature}` — IoT sensor reading\\n\\nIf no prompt is specified, the full JSON payload is dumped into the agent prompt.\\n\\n## Common Patterns\\n\\n### GitHub: new issues\\n```bash\\nhermes webhook subscribe github-issues \\\\\\n  --events \\\"issues\\\" \\\\\\n  --prompt \\\"New GitHub issue #{issue.number}: {issue.title}\\\\n\\\\nAction: {action}\\\\nAuthor: {issue.user.login}\\\\nBody:\\\\n{issue.body}\\\\n\\\\nPlease triage this issue.\\\" \\\\\\n  --deliver telegram \\\\\\n  --deliver-chat-id \\\"-100123456789\\\"\\n```\\n\\nThen in GitHub repo Settings → Webhooks → Add webhook:\\n- Payload URL: the returned webhook_url\\n- Content type: application/json\\n- Secret: the returned secret\\n- Events: \\\"Issues\\\"\\n\\n### GitHub: PR reviews\\n```bash\\nhermes webhook subscribe github-prs \\\\\\n  --events \\\"pull_request\\\" \\\\\\n  --prompt \\\"PR #{pull_request.number} {action}: {pull_request.title}\\\\nBy: {pull_request.user.login}\\\\nBranch: {pull_request.head.ref}\\\\n\\\\n{pull_request.body}\\\" \\\\\\n  --skills \\\"github-code-review\\\" \\\\\\n  --deliver github_comment\\n```\\n\\n### Stripe: payment events\\n```bash\\nhermes webhook subscribe stripe-payments \\\\\\n  --events \\\"payment_intent.succeeded,payment_intent.payment_failed\\\" \\\\\\n  --prompt \\\"Payment {data.object.status}: {data.object.amount} cents from {data.object.receipt_email}\\\" \\\\\\n  --deliver telegram \\\\\\n  --deliver-chat-id \\\"-100123456789\\\"\\n```\\n\\n### CI/CD: build notifications\\n```bash\\nhermes webhook subscribe ci-builds \\\\\\n  --events \\\"pipeline\\\" \\\\\\n  --prompt \\\"Build {object_attributes.status} on {project.name} branch {object_attributes.ref}\\\\nCommit: {commit.message}\\\" \\\\\\n  --deliver discord \\\\\\n  --deliver-chat-id \\\"1234567890\\\"\\n```\\n\\n### Generic monitoring alert\\n```bash\\nhermes webhook subscribe alerts \\\\\\n  --prompt \\\"Alert: {alert.name}\\\\nSeverity: {alert.severity}\\\\nMessage: {alert.message}\\\\n\\\\nPlease investigate and suggest remediation.\\\" \\\\\\n  --deliver origin\\n```\\n\\n### Direct delivery (no agent, zero LLM cost)\\n\\nFor use cases where you just want to push a notification through to a user's chat — no reasoning, no agent loop — add `--deliver-only`. The rendered `--prompt` template becomes the literal message body and is dispatched directly to the target adapter.\\n\\nUse this for:\\n- External service push notifications (Supabase/Firebase webhooks → Telegram)\\n- Monitoring alerts that should forward verbatim\\n- Inter-agent pings where one agent is telling another agent's user something\\n- Any webhook where an LLM round trip would be wasted effort\\n\\n```bash\\nhermes webhook subscribe antenna-matches \\\\\\n  --deliver telegram \\\\\\n  --deliver-chat-id \\\"123456789\\\" \\\\\\n  --deliver-only \\\\\\n  --prompt \\\"🎉 New match: {match.user_name} matched with you!\\\" \\\\\\n  --description \\\"Antenna match notifications\\\"\\n```\\n\\nThe POST returns `200 OK` on successful delivery, `502` on target failure — so upstream services can retry intelligently. HMAC auth, rate limits, and idempotency still apply.\\n\\nRequires `--deliver` to be a real target (telegram, discord, slack, github_comment, etc.) — `--deliver log` is rejected because log-only direct delivery is pointless.\\n\\n## Security\\n\\n- Each subscription gets an auto-generated HMAC-SHA256 secret (or provide your own with `--secret`)\\n- The webhook adapter validates signatures on every incoming POST\\n- Static routes from config.yaml cannot be overwritten by dynamic subscriptions\\n- Subscriptions persist to `~/.hermes/webhook_subscriptions.json`\\n\\n## How It Works\\n\\n1. `hermes webhook subscribe` writes to `~/.hermes/webhook_subscriptions.json`\\n2. The webhook adapter hot-reloads this file on each incoming request (mtime-gated, negligible overhead)\\n3. When a POST arrives matching a route, the adapter formats the prompt and triggers an agent run\\n4. The agent's response is delivered to the configured target (Telegram, Discord, GitHub comment, etc.)\\n\\n## Troubleshooting\\n\\nIf webhooks aren't working:\\n\\n1. **Is the gateway running?** Check with `systemctl --user status hermes-gateway` or `ps aux | grep gateway`\\n2. **Is the webhook server listening?** `curl http://localhost:8644/health` should return `{\\\"status\\\": \\\"ok\\\"}`\\n3. **Check gateway logs:** `grep webhook ~/.hermes/logs/gateway.log | tail -20`\\n4. **Signature mismatch?** Verify the secret in your service matches the one from `hermes webhook list`. GitHub sends `X-Hub-Signature-256`, GitLab sends `X-Gitlab-Token`.\\n5. **Firewall/NAT?** The webhook URL must be reachable from the service. For local development, use a tunnel (ngrok, cloudflared).\\n6. **Wrong event type?** Check `--events` filter matches what the service sends. Use `hermes webhook test <name>` to verify the route works.\\n\", \"path\": \"devops/webhook-subscriptions/SKILL.md\", \"skill_dir\": \"/home/kuhnn/.hermes/skills/devops/webhook-subscriptions\", \"linked_files\": null, \"usage_hint\": null, \"required_environment_variables\": [], \"required_commands\": [], \"missing_required_environment_variables\": [], \"missing_credential_files\": [], \"missing_required_commands\": [], \"setup_needed\": false, \"setup_skipped\": false, \"readiness_status\": \"available\", \"metadata\": {\"hermes\": {\"tags\": [\"webhook\", \"events\", \"automation\", \"integrations\", \"notifications\", \"push\"]}}}",
      "tool_call_id": "call_function_482zhhlnflgr_10"
    }
  ]
}