diff --git a/agent/prompt_builder.py b/agent/prompt_builder.py index 09b583898..bf5d61528 100644 --- a/agent/prompt_builder.py +++ b/agent/prompt_builder.py @@ -22,6 +22,7 @@ from agent.skill_utils import ( get_disabled_skill_names, iter_skill_index_files, parse_frontmatter, + skill_matches_environment, skill_matches_platform, ) from utils import atomic_json_write @@ -1005,6 +1006,13 @@ def _parse_skill_file(skill_file: Path) -> tuple[bool, dict, str]: if not skill_matches_platform(frontmatter): return False, frontmatter, "" + # Environment relevance gate (offer-time only): hide skills tagged for + # a runtime environment that isn't active (e.g. kanban-only skills for + # non-kanban users, s6-only skills outside the container). Explicit + # loads (skill_view / --skills) bypass this — see skill_matches_environment. + if not skill_matches_environment(frontmatter): + return False, frontmatter, "" + return True, frontmatter, extract_skill_description(frontmatter) except Exception as e: logger.warning("Failed to parse skill file %s: %s", skill_file, e) diff --git a/agent/skill_commands.py b/agent/skill_commands.py index 018d84865..269c2fdd2 100644 --- a/agent/skill_commands.py +++ b/agent/skill_commands.py @@ -270,7 +270,7 @@ def scan_skill_commands() -> Dict[str, Dict[str, Any]]: _skill_commands_platform = _resolve_skill_commands_platform() _skill_commands = {} try: - from tools.skills_tool import SKILLS_DIR, _parse_frontmatter, skill_matches_platform, _get_disabled_skill_names + from tools.skills_tool import SKILLS_DIR, _parse_frontmatter, skill_matches_platform, skill_matches_environment, _get_disabled_skill_names from agent.skill_utils import get_external_skills_dirs, iter_skill_index_files disabled = _get_disabled_skill_names() seen_names: set = set() @@ -291,6 +291,10 @@ def scan_skill_commands() -> Dict[str, Dict[str, Any]]: # Skip skills incompatible with the current OS platform if not skill_matches_platform(frontmatter): continue + # Skip skills not relevant to the current runtime env + # (kanban/docker/s6). Offer-time only; explicit load bypasses. + if not skill_matches_environment(frontmatter): + continue name = frontmatter.get('name', skill_md.parent.name) if name in seen_names: continue diff --git a/agent/skill_utils.py b/agent/skill_utils.py index 5b8e4c22a..62bcc5a2b 100644 --- a/agent/skill_utils.py +++ b/agent/skill_utils.py @@ -169,6 +169,106 @@ def skill_matches_platform(frontmatter: Dict[str, Any]) -> bool: return False +# ── Environment matching ────────────────────────────────────────────────── + +# Recognized environment tags and how each is detected. An environment tag is +# a *relevance* gate, not a hard-compatibility gate (that is what ``platforms:`` +# is for). A skill tagged for an environment it isn't relevant to is hidden from +# the skills index / offer surfaces so it does not add noise for users who will +# never need it — but it can ALWAYS still be loaded explicitly (``skill_view``, +# ``--skills``), because an explicit request is explicit consent. +# +# Detection is cached for the process lifetime via ``_ENV_DETECT_CACHE``. +_KNOWN_ENVIRONMENTS = frozenset({"kanban", "docker", "s6"}) + +_ENV_DETECT_CACHE: Dict[str, bool] = {} + + +def _detect_environment(env: str) -> bool: + """Return True when the named runtime environment is currently active. + + Cached per process. Unknown env names return True (fail-open: never hide a + skill because of a tag we don't understand). + """ + if env in _ENV_DETECT_CACHE: + return _ENV_DETECT_CACHE[env] + + result = True + if env == "kanban": + # Kanban is "active" either as a dispatcher-spawned worker (the + # dispatcher sets ``HERMES_KANBAN_TASK`` / ``HERMES_KANBAN_BOARD`` in the + # worker env) or as an orchestrator profile that has opted into the + # kanban toolset. Mirror the same signals the kanban tools themselves + # gate on (``tools/kanban_tools.py``) so the offer filter agrees with + # tool availability. + if os.getenv("HERMES_KANBAN_TASK") or os.getenv("HERMES_KANBAN_BOARD"): + result = True + else: + try: + from tools.kanban_tools import _profile_has_kanban_toolset + + result = bool(_profile_has_kanban_toolset()) + except Exception: + result = False + elif env == "docker": + try: + from hermes_constants import is_container + + result = is_container() + except Exception: + result = False + elif env == "s6": + # The Hermes Docker image runs s6-overlay as PID 1 (/init). s6 plants + # its runtime scaffolding under /run/s6 and ships its admin tree under + # /package/admin/s6-overlay. Either marker means we're inside an + # s6-supervised container. + result = os.path.isdir("/run/s6") or os.path.isdir( + "/package/admin/s6-overlay" + ) + + _ENV_DETECT_CACHE[env] = result + return result + + +def skill_matches_environment(frontmatter: Dict[str, Any]) -> bool: + """Return True when the skill is relevant to the current runtime environment. + + Skills may declare an ``environments`` list in their YAML frontmatter:: + + environments: [kanban] # only relevant when kanban is active + environments: [s6] # only relevant inside the s6 Docker image + environments: [docker] # only relevant inside any container + + If the field is absent or empty the skill is relevant in **all** + environments (backward-compatible default). + + This is an OFFER-time filter: it controls whether a skill shows up in the + skills index / autocomplete / slash-command list. It is intentionally NOT + enforced by ``skill_view`` or ``--skills`` preloading — an explicit load is + explicit consent, and load-bearing force-loads (e.g. the kanban dispatcher + injecting ``--skills kanban-worker``) must always succeed regardless of how + the offer surfaces filter the skill. + + A skill matches when ANY of its declared environments is currently active + (OR semantics, mirroring ``platforms``). Unknown env tags fail open. + """ + environments = frontmatter.get("environments") + if not environments: + return True + if not isinstance(environments, list): + environments = [environments] + for env in environments: + normalized = str(env).lower().strip() + if not normalized: + continue + if normalized not in _KNOWN_ENVIRONMENTS: + # Tag we don't understand — don't hide the skill over it. + return True + if _detect_environment(normalized): + return True + return False + + # ── Disabled skills ─────────────────────────────────────────────────────── diff --git a/skills/creative/baoyu-article-illustrator/PORT_NOTES.md b/optional-skills/creative/baoyu-article-illustrator/PORT_NOTES.md similarity index 100% rename from skills/creative/baoyu-article-illustrator/PORT_NOTES.md rename to optional-skills/creative/baoyu-article-illustrator/PORT_NOTES.md diff --git a/skills/creative/baoyu-article-illustrator/SKILL.md b/optional-skills/creative/baoyu-article-illustrator/SKILL.md similarity index 100% rename from skills/creative/baoyu-article-illustrator/SKILL.md rename to optional-skills/creative/baoyu-article-illustrator/SKILL.md diff --git a/skills/creative/baoyu-article-illustrator/prompts/system.md b/optional-skills/creative/baoyu-article-illustrator/prompts/system.md similarity index 100% rename from skills/creative/baoyu-article-illustrator/prompts/system.md rename to optional-skills/creative/baoyu-article-illustrator/prompts/system.md diff --git a/skills/creative/baoyu-article-illustrator/references/palettes/macaron.md b/optional-skills/creative/baoyu-article-illustrator/references/palettes/macaron.md similarity index 100% rename from skills/creative/baoyu-article-illustrator/references/palettes/macaron.md rename to optional-skills/creative/baoyu-article-illustrator/references/palettes/macaron.md diff --git a/skills/creative/baoyu-article-illustrator/references/palettes/mono-ink.md b/optional-skills/creative/baoyu-article-illustrator/references/palettes/mono-ink.md similarity index 100% rename from skills/creative/baoyu-article-illustrator/references/palettes/mono-ink.md rename to optional-skills/creative/baoyu-article-illustrator/references/palettes/mono-ink.md diff --git a/skills/creative/baoyu-article-illustrator/references/palettes/neon.md b/optional-skills/creative/baoyu-article-illustrator/references/palettes/neon.md similarity index 100% rename from skills/creative/baoyu-article-illustrator/references/palettes/neon.md rename to optional-skills/creative/baoyu-article-illustrator/references/palettes/neon.md diff --git a/skills/creative/baoyu-article-illustrator/references/palettes/warm.md b/optional-skills/creative/baoyu-article-illustrator/references/palettes/warm.md similarity index 100% rename from skills/creative/baoyu-article-illustrator/references/palettes/warm.md rename to optional-skills/creative/baoyu-article-illustrator/references/palettes/warm.md diff --git a/skills/creative/baoyu-article-illustrator/references/prompt-construction.md b/optional-skills/creative/baoyu-article-illustrator/references/prompt-construction.md similarity index 100% rename from skills/creative/baoyu-article-illustrator/references/prompt-construction.md rename to optional-skills/creative/baoyu-article-illustrator/references/prompt-construction.md diff --git a/skills/creative/baoyu-article-illustrator/references/style-presets.md b/optional-skills/creative/baoyu-article-illustrator/references/style-presets.md similarity index 100% rename from skills/creative/baoyu-article-illustrator/references/style-presets.md rename to optional-skills/creative/baoyu-article-illustrator/references/style-presets.md diff --git a/skills/creative/baoyu-article-illustrator/references/styles.md b/optional-skills/creative/baoyu-article-illustrator/references/styles.md similarity index 100% rename from skills/creative/baoyu-article-illustrator/references/styles.md rename to optional-skills/creative/baoyu-article-illustrator/references/styles.md diff --git a/skills/creative/baoyu-article-illustrator/references/styles/blueprint.md b/optional-skills/creative/baoyu-article-illustrator/references/styles/blueprint.md similarity index 100% rename from skills/creative/baoyu-article-illustrator/references/styles/blueprint.md rename to optional-skills/creative/baoyu-article-illustrator/references/styles/blueprint.md diff --git a/skills/creative/baoyu-article-illustrator/references/styles/chalkboard.md b/optional-skills/creative/baoyu-article-illustrator/references/styles/chalkboard.md similarity index 100% rename from skills/creative/baoyu-article-illustrator/references/styles/chalkboard.md rename to optional-skills/creative/baoyu-article-illustrator/references/styles/chalkboard.md diff --git a/skills/creative/baoyu-article-illustrator/references/styles/editorial.md b/optional-skills/creative/baoyu-article-illustrator/references/styles/editorial.md similarity index 100% rename from skills/creative/baoyu-article-illustrator/references/styles/editorial.md rename to optional-skills/creative/baoyu-article-illustrator/references/styles/editorial.md diff --git a/skills/creative/baoyu-article-illustrator/references/styles/elegant.md b/optional-skills/creative/baoyu-article-illustrator/references/styles/elegant.md similarity index 100% rename from skills/creative/baoyu-article-illustrator/references/styles/elegant.md rename to optional-skills/creative/baoyu-article-illustrator/references/styles/elegant.md diff --git a/skills/creative/baoyu-article-illustrator/references/styles/fantasy-animation.md b/optional-skills/creative/baoyu-article-illustrator/references/styles/fantasy-animation.md similarity index 100% rename from skills/creative/baoyu-article-illustrator/references/styles/fantasy-animation.md rename to optional-skills/creative/baoyu-article-illustrator/references/styles/fantasy-animation.md diff --git a/skills/creative/baoyu-article-illustrator/references/styles/flat-doodle.md b/optional-skills/creative/baoyu-article-illustrator/references/styles/flat-doodle.md similarity index 100% rename from skills/creative/baoyu-article-illustrator/references/styles/flat-doodle.md rename to optional-skills/creative/baoyu-article-illustrator/references/styles/flat-doodle.md diff --git a/skills/creative/baoyu-article-illustrator/references/styles/flat.md b/optional-skills/creative/baoyu-article-illustrator/references/styles/flat.md similarity index 100% rename from skills/creative/baoyu-article-illustrator/references/styles/flat.md rename to optional-skills/creative/baoyu-article-illustrator/references/styles/flat.md diff --git a/skills/creative/baoyu-article-illustrator/references/styles/ink-notes.md b/optional-skills/creative/baoyu-article-illustrator/references/styles/ink-notes.md similarity index 100% rename from skills/creative/baoyu-article-illustrator/references/styles/ink-notes.md rename to optional-skills/creative/baoyu-article-illustrator/references/styles/ink-notes.md diff --git a/skills/creative/baoyu-article-illustrator/references/styles/intuition-machine.md b/optional-skills/creative/baoyu-article-illustrator/references/styles/intuition-machine.md similarity index 100% rename from skills/creative/baoyu-article-illustrator/references/styles/intuition-machine.md rename to optional-skills/creative/baoyu-article-illustrator/references/styles/intuition-machine.md diff --git a/skills/creative/baoyu-article-illustrator/references/styles/minimal.md b/optional-skills/creative/baoyu-article-illustrator/references/styles/minimal.md similarity index 100% rename from skills/creative/baoyu-article-illustrator/references/styles/minimal.md rename to optional-skills/creative/baoyu-article-illustrator/references/styles/minimal.md diff --git a/skills/creative/baoyu-article-illustrator/references/styles/nature.md b/optional-skills/creative/baoyu-article-illustrator/references/styles/nature.md similarity index 100% rename from skills/creative/baoyu-article-illustrator/references/styles/nature.md rename to optional-skills/creative/baoyu-article-illustrator/references/styles/nature.md diff --git a/skills/creative/baoyu-article-illustrator/references/styles/notion.md b/optional-skills/creative/baoyu-article-illustrator/references/styles/notion.md similarity index 100% rename from skills/creative/baoyu-article-illustrator/references/styles/notion.md rename to optional-skills/creative/baoyu-article-illustrator/references/styles/notion.md diff --git a/skills/creative/baoyu-article-illustrator/references/styles/pixel-art.md b/optional-skills/creative/baoyu-article-illustrator/references/styles/pixel-art.md similarity index 100% rename from skills/creative/baoyu-article-illustrator/references/styles/pixel-art.md rename to optional-skills/creative/baoyu-article-illustrator/references/styles/pixel-art.md diff --git a/skills/creative/baoyu-article-illustrator/references/styles/playful.md b/optional-skills/creative/baoyu-article-illustrator/references/styles/playful.md similarity index 100% rename from skills/creative/baoyu-article-illustrator/references/styles/playful.md rename to optional-skills/creative/baoyu-article-illustrator/references/styles/playful.md diff --git a/skills/creative/baoyu-article-illustrator/references/styles/retro.md b/optional-skills/creative/baoyu-article-illustrator/references/styles/retro.md similarity index 100% rename from skills/creative/baoyu-article-illustrator/references/styles/retro.md rename to optional-skills/creative/baoyu-article-illustrator/references/styles/retro.md diff --git a/skills/creative/baoyu-article-illustrator/references/styles/scientific.md b/optional-skills/creative/baoyu-article-illustrator/references/styles/scientific.md similarity index 100% rename from skills/creative/baoyu-article-illustrator/references/styles/scientific.md rename to optional-skills/creative/baoyu-article-illustrator/references/styles/scientific.md diff --git a/skills/creative/baoyu-article-illustrator/references/styles/screen-print.md b/optional-skills/creative/baoyu-article-illustrator/references/styles/screen-print.md similarity index 100% rename from skills/creative/baoyu-article-illustrator/references/styles/screen-print.md rename to optional-skills/creative/baoyu-article-illustrator/references/styles/screen-print.md diff --git a/skills/creative/baoyu-article-illustrator/references/styles/sketch-notes.md b/optional-skills/creative/baoyu-article-illustrator/references/styles/sketch-notes.md similarity index 100% rename from skills/creative/baoyu-article-illustrator/references/styles/sketch-notes.md rename to optional-skills/creative/baoyu-article-illustrator/references/styles/sketch-notes.md diff --git a/skills/creative/baoyu-article-illustrator/references/styles/sketch.md b/optional-skills/creative/baoyu-article-illustrator/references/styles/sketch.md similarity index 100% rename from skills/creative/baoyu-article-illustrator/references/styles/sketch.md rename to optional-skills/creative/baoyu-article-illustrator/references/styles/sketch.md diff --git a/skills/creative/baoyu-article-illustrator/references/styles/vector-illustration.md b/optional-skills/creative/baoyu-article-illustrator/references/styles/vector-illustration.md similarity index 100% rename from skills/creative/baoyu-article-illustrator/references/styles/vector-illustration.md rename to optional-skills/creative/baoyu-article-illustrator/references/styles/vector-illustration.md diff --git a/skills/creative/baoyu-article-illustrator/references/styles/vintage.md b/optional-skills/creative/baoyu-article-illustrator/references/styles/vintage.md similarity index 100% rename from skills/creative/baoyu-article-illustrator/references/styles/vintage.md rename to optional-skills/creative/baoyu-article-illustrator/references/styles/vintage.md diff --git a/skills/creative/baoyu-article-illustrator/references/styles/warm.md b/optional-skills/creative/baoyu-article-illustrator/references/styles/warm.md similarity index 100% rename from skills/creative/baoyu-article-illustrator/references/styles/warm.md rename to optional-skills/creative/baoyu-article-illustrator/references/styles/warm.md diff --git a/skills/creative/baoyu-article-illustrator/references/styles/watercolor.md b/optional-skills/creative/baoyu-article-illustrator/references/styles/watercolor.md similarity index 100% rename from skills/creative/baoyu-article-illustrator/references/styles/watercolor.md rename to optional-skills/creative/baoyu-article-illustrator/references/styles/watercolor.md diff --git a/skills/creative/baoyu-article-illustrator/references/usage.md b/optional-skills/creative/baoyu-article-illustrator/references/usage.md similarity index 100% rename from skills/creative/baoyu-article-illustrator/references/usage.md rename to optional-skills/creative/baoyu-article-illustrator/references/usage.md diff --git a/skills/creative/baoyu-article-illustrator/references/workflow.md b/optional-skills/creative/baoyu-article-illustrator/references/workflow.md similarity index 100% rename from skills/creative/baoyu-article-illustrator/references/workflow.md rename to optional-skills/creative/baoyu-article-illustrator/references/workflow.md diff --git a/skills/creative/baoyu-comic/PORT_NOTES.md b/optional-skills/creative/baoyu-comic/PORT_NOTES.md similarity index 100% rename from skills/creative/baoyu-comic/PORT_NOTES.md rename to optional-skills/creative/baoyu-comic/PORT_NOTES.md diff --git a/skills/creative/baoyu-comic/SKILL.md b/optional-skills/creative/baoyu-comic/SKILL.md similarity index 100% rename from skills/creative/baoyu-comic/SKILL.md rename to optional-skills/creative/baoyu-comic/SKILL.md diff --git a/skills/creative/baoyu-comic/references/analysis-framework.md b/optional-skills/creative/baoyu-comic/references/analysis-framework.md similarity index 100% rename from skills/creative/baoyu-comic/references/analysis-framework.md rename to optional-skills/creative/baoyu-comic/references/analysis-framework.md diff --git a/skills/creative/baoyu-comic/references/art-styles/chalk.md b/optional-skills/creative/baoyu-comic/references/art-styles/chalk.md similarity index 100% rename from skills/creative/baoyu-comic/references/art-styles/chalk.md rename to optional-skills/creative/baoyu-comic/references/art-styles/chalk.md diff --git a/skills/creative/baoyu-comic/references/art-styles/ink-brush.md b/optional-skills/creative/baoyu-comic/references/art-styles/ink-brush.md similarity index 100% rename from skills/creative/baoyu-comic/references/art-styles/ink-brush.md rename to optional-skills/creative/baoyu-comic/references/art-styles/ink-brush.md diff --git a/skills/creative/baoyu-comic/references/art-styles/ligne-claire.md b/optional-skills/creative/baoyu-comic/references/art-styles/ligne-claire.md similarity index 100% rename from skills/creative/baoyu-comic/references/art-styles/ligne-claire.md rename to optional-skills/creative/baoyu-comic/references/art-styles/ligne-claire.md diff --git a/skills/creative/baoyu-comic/references/art-styles/manga.md b/optional-skills/creative/baoyu-comic/references/art-styles/manga.md similarity index 100% rename from skills/creative/baoyu-comic/references/art-styles/manga.md rename to optional-skills/creative/baoyu-comic/references/art-styles/manga.md diff --git a/skills/creative/baoyu-comic/references/art-styles/minimalist.md b/optional-skills/creative/baoyu-comic/references/art-styles/minimalist.md similarity index 100% rename from skills/creative/baoyu-comic/references/art-styles/minimalist.md rename to optional-skills/creative/baoyu-comic/references/art-styles/minimalist.md diff --git a/skills/creative/baoyu-comic/references/art-styles/realistic.md b/optional-skills/creative/baoyu-comic/references/art-styles/realistic.md similarity index 100% rename from skills/creative/baoyu-comic/references/art-styles/realistic.md rename to optional-skills/creative/baoyu-comic/references/art-styles/realistic.md diff --git a/skills/creative/baoyu-comic/references/auto-selection.md b/optional-skills/creative/baoyu-comic/references/auto-selection.md similarity index 100% rename from skills/creative/baoyu-comic/references/auto-selection.md rename to optional-skills/creative/baoyu-comic/references/auto-selection.md diff --git a/skills/creative/baoyu-comic/references/base-prompt.md b/optional-skills/creative/baoyu-comic/references/base-prompt.md similarity index 100% rename from skills/creative/baoyu-comic/references/base-prompt.md rename to optional-skills/creative/baoyu-comic/references/base-prompt.md diff --git a/skills/creative/baoyu-comic/references/character-template.md b/optional-skills/creative/baoyu-comic/references/character-template.md similarity index 100% rename from skills/creative/baoyu-comic/references/character-template.md rename to optional-skills/creative/baoyu-comic/references/character-template.md diff --git a/skills/creative/baoyu-comic/references/layouts/cinematic.md b/optional-skills/creative/baoyu-comic/references/layouts/cinematic.md similarity index 100% rename from skills/creative/baoyu-comic/references/layouts/cinematic.md rename to optional-skills/creative/baoyu-comic/references/layouts/cinematic.md diff --git a/skills/creative/baoyu-comic/references/layouts/dense.md b/optional-skills/creative/baoyu-comic/references/layouts/dense.md similarity index 100% rename from skills/creative/baoyu-comic/references/layouts/dense.md rename to optional-skills/creative/baoyu-comic/references/layouts/dense.md diff --git a/skills/creative/baoyu-comic/references/layouts/four-panel.md b/optional-skills/creative/baoyu-comic/references/layouts/four-panel.md similarity index 100% rename from skills/creative/baoyu-comic/references/layouts/four-panel.md rename to optional-skills/creative/baoyu-comic/references/layouts/four-panel.md diff --git a/skills/creative/baoyu-comic/references/layouts/mixed.md b/optional-skills/creative/baoyu-comic/references/layouts/mixed.md similarity index 100% rename from skills/creative/baoyu-comic/references/layouts/mixed.md rename to optional-skills/creative/baoyu-comic/references/layouts/mixed.md diff --git a/skills/creative/baoyu-comic/references/layouts/splash.md b/optional-skills/creative/baoyu-comic/references/layouts/splash.md similarity index 100% rename from skills/creative/baoyu-comic/references/layouts/splash.md rename to optional-skills/creative/baoyu-comic/references/layouts/splash.md diff --git a/skills/creative/baoyu-comic/references/layouts/standard.md b/optional-skills/creative/baoyu-comic/references/layouts/standard.md similarity index 100% rename from skills/creative/baoyu-comic/references/layouts/standard.md rename to optional-skills/creative/baoyu-comic/references/layouts/standard.md diff --git a/skills/creative/baoyu-comic/references/layouts/webtoon.md b/optional-skills/creative/baoyu-comic/references/layouts/webtoon.md similarity index 100% rename from skills/creative/baoyu-comic/references/layouts/webtoon.md rename to optional-skills/creative/baoyu-comic/references/layouts/webtoon.md diff --git a/skills/creative/baoyu-comic/references/ohmsha-guide.md b/optional-skills/creative/baoyu-comic/references/ohmsha-guide.md similarity index 100% rename from skills/creative/baoyu-comic/references/ohmsha-guide.md rename to optional-skills/creative/baoyu-comic/references/ohmsha-guide.md diff --git a/skills/creative/baoyu-comic/references/partial-workflows.md b/optional-skills/creative/baoyu-comic/references/partial-workflows.md similarity index 100% rename from skills/creative/baoyu-comic/references/partial-workflows.md rename to optional-skills/creative/baoyu-comic/references/partial-workflows.md diff --git a/skills/creative/baoyu-comic/references/presets/concept-story.md b/optional-skills/creative/baoyu-comic/references/presets/concept-story.md similarity index 100% rename from skills/creative/baoyu-comic/references/presets/concept-story.md rename to optional-skills/creative/baoyu-comic/references/presets/concept-story.md diff --git a/skills/creative/baoyu-comic/references/presets/four-panel.md b/optional-skills/creative/baoyu-comic/references/presets/four-panel.md similarity index 100% rename from skills/creative/baoyu-comic/references/presets/four-panel.md rename to optional-skills/creative/baoyu-comic/references/presets/four-panel.md diff --git a/skills/creative/baoyu-comic/references/presets/ohmsha.md b/optional-skills/creative/baoyu-comic/references/presets/ohmsha.md similarity index 100% rename from skills/creative/baoyu-comic/references/presets/ohmsha.md rename to optional-skills/creative/baoyu-comic/references/presets/ohmsha.md diff --git a/skills/creative/baoyu-comic/references/presets/shoujo.md b/optional-skills/creative/baoyu-comic/references/presets/shoujo.md similarity index 100% rename from skills/creative/baoyu-comic/references/presets/shoujo.md rename to optional-skills/creative/baoyu-comic/references/presets/shoujo.md diff --git a/skills/creative/baoyu-comic/references/presets/wuxia.md b/optional-skills/creative/baoyu-comic/references/presets/wuxia.md similarity index 100% rename from skills/creative/baoyu-comic/references/presets/wuxia.md rename to optional-skills/creative/baoyu-comic/references/presets/wuxia.md diff --git a/skills/creative/baoyu-comic/references/storyboard-template.md b/optional-skills/creative/baoyu-comic/references/storyboard-template.md similarity index 100% rename from skills/creative/baoyu-comic/references/storyboard-template.md rename to optional-skills/creative/baoyu-comic/references/storyboard-template.md diff --git a/skills/creative/baoyu-comic/references/tones/action.md b/optional-skills/creative/baoyu-comic/references/tones/action.md similarity index 100% rename from skills/creative/baoyu-comic/references/tones/action.md rename to optional-skills/creative/baoyu-comic/references/tones/action.md diff --git a/skills/creative/baoyu-comic/references/tones/dramatic.md b/optional-skills/creative/baoyu-comic/references/tones/dramatic.md similarity index 100% rename from skills/creative/baoyu-comic/references/tones/dramatic.md rename to optional-skills/creative/baoyu-comic/references/tones/dramatic.md diff --git a/skills/creative/baoyu-comic/references/tones/energetic.md b/optional-skills/creative/baoyu-comic/references/tones/energetic.md similarity index 100% rename from skills/creative/baoyu-comic/references/tones/energetic.md rename to optional-skills/creative/baoyu-comic/references/tones/energetic.md diff --git a/skills/creative/baoyu-comic/references/tones/neutral.md b/optional-skills/creative/baoyu-comic/references/tones/neutral.md similarity index 100% rename from skills/creative/baoyu-comic/references/tones/neutral.md rename to optional-skills/creative/baoyu-comic/references/tones/neutral.md diff --git a/skills/creative/baoyu-comic/references/tones/romantic.md b/optional-skills/creative/baoyu-comic/references/tones/romantic.md similarity index 100% rename from skills/creative/baoyu-comic/references/tones/romantic.md rename to optional-skills/creative/baoyu-comic/references/tones/romantic.md diff --git a/skills/creative/baoyu-comic/references/tones/vintage.md b/optional-skills/creative/baoyu-comic/references/tones/vintage.md similarity index 100% rename from skills/creative/baoyu-comic/references/tones/vintage.md rename to optional-skills/creative/baoyu-comic/references/tones/vintage.md diff --git a/skills/creative/baoyu-comic/references/tones/warm.md b/optional-skills/creative/baoyu-comic/references/tones/warm.md similarity index 100% rename from skills/creative/baoyu-comic/references/tones/warm.md rename to optional-skills/creative/baoyu-comic/references/tones/warm.md diff --git a/skills/creative/baoyu-comic/references/workflow.md b/optional-skills/creative/baoyu-comic/references/workflow.md similarity index 100% rename from skills/creative/baoyu-comic/references/workflow.md rename to optional-skills/creative/baoyu-comic/references/workflow.md diff --git a/skills/creative/creative-ideation/SKILL.md b/optional-skills/creative/creative-ideation/SKILL.md similarity index 100% rename from skills/creative/creative-ideation/SKILL.md rename to optional-skills/creative/creative-ideation/SKILL.md diff --git a/skills/creative/creative-ideation/references/full-prompt-library.md b/optional-skills/creative/creative-ideation/references/full-prompt-library.md similarity index 100% rename from skills/creative/creative-ideation/references/full-prompt-library.md rename to optional-skills/creative/creative-ideation/references/full-prompt-library.md diff --git a/skills/creative/pixel-art/ATTRIBUTION.md b/optional-skills/creative/pixel-art/ATTRIBUTION.md similarity index 100% rename from skills/creative/pixel-art/ATTRIBUTION.md rename to optional-skills/creative/pixel-art/ATTRIBUTION.md diff --git a/skills/creative/pixel-art/SKILL.md b/optional-skills/creative/pixel-art/SKILL.md similarity index 100% rename from skills/creative/pixel-art/SKILL.md rename to optional-skills/creative/pixel-art/SKILL.md diff --git a/skills/creative/pixel-art/references/palettes.md b/optional-skills/creative/pixel-art/references/palettes.md similarity index 100% rename from skills/creative/pixel-art/references/palettes.md rename to optional-skills/creative/pixel-art/references/palettes.md diff --git a/skills/creative/pixel-art/scripts/__init__.py b/optional-skills/creative/pixel-art/scripts/__init__.py similarity index 100% rename from skills/creative/pixel-art/scripts/__init__.py rename to optional-skills/creative/pixel-art/scripts/__init__.py diff --git a/skills/creative/pixel-art/scripts/palettes.py b/optional-skills/creative/pixel-art/scripts/palettes.py similarity index 100% rename from skills/creative/pixel-art/scripts/palettes.py rename to optional-skills/creative/pixel-art/scripts/palettes.py diff --git a/skills/creative/pixel-art/scripts/pixel_art.py b/optional-skills/creative/pixel-art/scripts/pixel_art.py similarity index 100% rename from skills/creative/pixel-art/scripts/pixel_art.py rename to optional-skills/creative/pixel-art/scripts/pixel_art.py diff --git a/skills/creative/pixel-art/scripts/pixel_art_video.py b/optional-skills/creative/pixel-art/scripts/pixel_art_video.py similarity index 100% rename from skills/creative/pixel-art/scripts/pixel_art_video.py rename to optional-skills/creative/pixel-art/scripts/pixel_art_video.py diff --git a/skills/software-development/hermes-s6-container-supervision/SKILL.md b/optional-skills/devops/hermes-s6-container-supervision/SKILL.md similarity index 99% rename from skills/software-development/hermes-s6-container-supervision/SKILL.md rename to optional-skills/devops/hermes-s6-container-supervision/SKILL.md index 934b26bc1..16e8a7b29 100644 --- a/skills/software-development/hermes-s6-container-supervision/SKILL.md +++ b/optional-skills/devops/hermes-s6-container-supervision/SKILL.md @@ -4,6 +4,8 @@ description: Modify, debug, or extend the s6-overlay supervision tree inside the version: 1.0.0 author: Hermes Agent license: MIT +platforms: [linux] +environments: [s6] metadata: hermes: tags: [docker, s6, supervision, gateway, profiles] diff --git a/skills/gaming/DESCRIPTION.md b/optional-skills/gaming/DESCRIPTION.md similarity index 100% rename from skills/gaming/DESCRIPTION.md rename to optional-skills/gaming/DESCRIPTION.md diff --git a/skills/gaming/minecraft-modpack-server/SKILL.md b/optional-skills/gaming/minecraft-modpack-server/SKILL.md similarity index 100% rename from skills/gaming/minecraft-modpack-server/SKILL.md rename to optional-skills/gaming/minecraft-modpack-server/SKILL.md diff --git a/skills/gaming/pokemon-player/SKILL.md b/optional-skills/gaming/pokemon-player/SKILL.md similarity index 100% rename from skills/gaming/pokemon-player/SKILL.md rename to optional-skills/gaming/pokemon-player/SKILL.md diff --git a/skills/mlops/research/DESCRIPTION.md b/optional-skills/mlops/research/DESCRIPTION.md similarity index 100% rename from skills/mlops/research/DESCRIPTION.md rename to optional-skills/mlops/research/DESCRIPTION.md diff --git a/skills/mlops/research/dspy/SKILL.md b/optional-skills/mlops/research/dspy/SKILL.md similarity index 100% rename from skills/mlops/research/dspy/SKILL.md rename to optional-skills/mlops/research/dspy/SKILL.md diff --git a/skills/mlops/research/dspy/references/examples.md b/optional-skills/mlops/research/dspy/references/examples.md similarity index 100% rename from skills/mlops/research/dspy/references/examples.md rename to optional-skills/mlops/research/dspy/references/examples.md diff --git a/skills/mlops/research/dspy/references/modules.md b/optional-skills/mlops/research/dspy/references/modules.md similarity index 100% rename from skills/mlops/research/dspy/references/modules.md rename to optional-skills/mlops/research/dspy/references/modules.md diff --git a/skills/mlops/research/dspy/references/optimizers.md b/optional-skills/mlops/research/dspy/references/optimizers.md similarity index 100% rename from skills/mlops/research/dspy/references/optimizers.md rename to optional-skills/mlops/research/dspy/references/optimizers.md diff --git a/skills/software-development/subagent-driven-development/SKILL.md b/optional-skills/software-development/subagent-driven-development/SKILL.md similarity index 97% rename from skills/software-development/subagent-driven-development/SKILL.md rename to optional-skills/software-development/subagent-driven-development/SKILL.md index d2cff3d80..3a1469f36 100644 --- a/skills/software-development/subagent-driven-development/SKILL.md +++ b/optional-skills/software-development/subagent-driven-development/SKILL.md @@ -8,7 +8,7 @@ platforms: [linux, macos, windows] metadata: hermes: tags: [delegation, subagent, implementation, workflow, parallel] - related_skills: [writing-plans, requesting-code-review, test-driven-development] + related_skills: [plan, requesting-code-review, test-driven-development] --- # Subagent-Driven Development @@ -22,7 +22,7 @@ Execute implementation plans by dispatching fresh subagents per task with system ## When to Use Use this skill when: -- You have an implementation plan (from writing-plans skill or user requirements) +- You have an implementation plan (from the `plan` skill or user requirements) - Tasks are mostly independent - Quality and spec compliance are important - You want automated review between tasks @@ -254,10 +254,10 @@ git add -A && git commit -m "feat: complete [feature name] implementation" ## Integration with Other Skills -### With writing-plans +### With plan -This skill EXECUTES plans created by the writing-plans skill: -1. User requirements → writing-plans → implementation plan +This skill EXECUTES plans created by the `plan` skill: +1. User requirements → plan → implementation plan 2. Implementation plan → subagent-driven-development → working code ### With test-driven-development diff --git a/skills/software-development/subagent-driven-development/references/context-budget-discipline.md b/optional-skills/software-development/subagent-driven-development/references/context-budget-discipline.md similarity index 100% rename from skills/software-development/subagent-driven-development/references/context-budget-discipline.md rename to optional-skills/software-development/subagent-driven-development/references/context-budget-discipline.md diff --git a/skills/software-development/subagent-driven-development/references/gates-taxonomy.md b/optional-skills/software-development/subagent-driven-development/references/gates-taxonomy.md similarity index 100% rename from skills/software-development/subagent-driven-development/references/gates-taxonomy.md rename to optional-skills/software-development/subagent-driven-development/references/gates-taxonomy.md diff --git a/skills/autonomous-ai-agents/hermes-agent/SKILL.md b/skills/autonomous-ai-agents/hermes-agent/SKILL.md index 2d3d49577..d6188ec49 100644 --- a/skills/autonomous-ai-agents/hermes-agent/SKILL.md +++ b/skills/autonomous-ai-agents/hermes-agent/SKILL.md @@ -140,6 +140,10 @@ hermes mcp test NAME Test connection hermes mcp configure NAME Toggle tool selection ``` +How the built-in MCP client connects servers (stdio/HTTP), auto-discovers +their tools, and exposes them as first-class tools, plus catalog install +(`hermes mcp install `): `skill_view(name="hermes-agent", file_path="references/native-mcp.md")`. + ### Gateway (Messaging Platforms) ``` @@ -188,6 +192,9 @@ hermes webhook remove NAME Remove a subscription hermes webhook test NAME Send a test POST ``` +Full setup, route config, payload templating, and event-driven agent-run +patterns: `skill_view(name="hermes-agent", file_path="references/webhooks.md")`. + ### Profiles ``` diff --git a/skills/mcp/native-mcp/SKILL.md b/skills/autonomous-ai-agents/hermes-agent/references/native-mcp.md similarity index 97% rename from skills/mcp/native-mcp/SKILL.md rename to skills/autonomous-ai-agents/hermes-agent/references/native-mcp.md index ca3896745..2d9133d8b 100644 --- a/skills/mcp/native-mcp/SKILL.md +++ b/skills/autonomous-ai-agents/hermes-agent/references/native-mcp.md @@ -1,16 +1,3 @@ ---- -name: native-mcp -description: "MCP client: connect servers, register tools (stdio/HTTP)." -version: 1.0.0 -author: Hermes Agent -license: MIT -platforms: [linux, macos, windows] -metadata: - hermes: - tags: [MCP, Tools, Integrations] - related_skills: [mcporter] ---- - # Native MCP Client Hermes Agent has a built-in MCP client that connects to MCP servers at startup, discovers their tools, and makes them available as first-class tools the agent can call directly. No bridge CLI needed -- tools from MCP servers appear alongside built-in tools like `terminal`, `read_file`, etc. diff --git a/skills/devops/webhook-subscriptions/SKILL.md b/skills/autonomous-ai-agents/hermes-agent/references/webhooks.md similarity index 96% rename from skills/devops/webhook-subscriptions/SKILL.md rename to skills/autonomous-ai-agents/hermes-agent/references/webhooks.md index 1f359b1a5..a1758d64f 100644 --- a/skills/devops/webhook-subscriptions/SKILL.md +++ b/skills/autonomous-ai-agents/hermes-agent/references/webhooks.md @@ -1,13 +1,3 @@ ---- -name: webhook-subscriptions -description: "Webhook subscriptions: event-driven agent runs." -version: 1.1.0 -platforms: [linux, macos, windows] -metadata: - hermes: - tags: [webhook, events, automation, integrations, notifications, push] ---- - # Webhook Subscriptions Create 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. diff --git a/skills/autonomous-ai-agents/kanban-codex-lane/SKILL.md b/skills/autonomous-ai-agents/kanban-codex-lane/SKILL.md deleted file mode 100644 index bffd20330..000000000 --- a/skills/autonomous-ai-agents/kanban-codex-lane/SKILL.md +++ /dev/null @@ -1,277 +0,0 @@ ---- -name: kanban-codex-lane -description: Use when a Hermes Kanban worker wants to run Codex CLI as an isolated implementation lane while Hermes keeps ownership of task lifecycle, reconciliation, testing, and handoff. -version: 1.0.0 -author: Hermes Agent -license: MIT -metadata: - hermes: - tags: [kanban, codex, worktrees, autonomous-agents, prediction-market-bot] - related_skills: [kanban-worker, codex, hermes-agent] ---- - -# Kanban Codex Lane - -## Overview - -This skill defines the lightweight Hermes+Codex dual-lane convention for Kanban workers. Hermes is always the task owner: it calls `kanban_show`, decides whether Codex is appropriate, creates or selects an isolated workspace, starts and monitors Codex, reconciles any diff, runs verification, and writes the final `kanban_complete` or `kanban_block` handoff. Codex is an input lane only. Codex output is not a task completion signal, not a trusted reviewer, and not allowed to write durable Kanban state directly. - -The convention exists so a Hermes worker can use Codex for bounded implementation help without changing the dispatcher. The dispatcher must still spawn Hermes workers. A worker may optionally spawn Codex inside its own run, then accept, partially accept, or reject the lane after independent review and tests. - -## When to Use - -Use the Codex lane when all of these are true: - -- The Kanban task is a coding, refactor, documentation, test, or mechanical migration task with clear acceptance criteria. -- A bounded diff can be evaluated by Hermes in one run. -- The repo can be copied or checked out in an isolated git worktree/branch. -- Hermes can run the relevant tests itself after Codex exits. -- The prompt can state all safety constraints and files that must not change. - -Do not use the Codex lane when any of these are true: - -- The task requires human judgment that is not already captured in the Kanban body. -- The worker lacks repo access, Codex auth, or time to reconcile the result. -- The change touches secrets, credential stores, private user data, or production order-entry systems. -- A small direct edit is faster and safer than spawning another agent. -- The task is research-only and should produce a written handoff rather than a diff. -- The worker would be tempted to mark Done based only on Codex self-report. - -## Ownership Rules - -1. Hermes owns the Kanban lifecycle. Codex must never call `kanban_complete`, `kanban_block`, `kanban_create`, gateway messaging, or any Hermes board CLI as a substitute for the worker. -2. Hermes owns final acceptance. Treat Codex commits/diffs as untrusted patches until reviewed and verified. -3. Hermes owns test execution. Codex may run tests, but those runs are advisory; repeat required verification from Hermes with the repo's canonical wrapper. -4. Hermes owns safety. If Codex changes safety boundaries, risk gates, live trading behavior, or secrets handling, reject the lane even if tests pass. -5. Hermes owns cleanup. Kill stuck Codex processes and remove temporary worktrees when they are no longer needed. - -## Required Worktree and Branch Pattern - -Never run Codex directly in a shared dirty checkout. Use a branch/worktree name that ties the lane to the Kanban task and keeps untrusted edits isolated. - -Recommended variables: - -```bash -TASK_ID="${HERMES_KANBAN_TASK:-t_manual}" -REPO="/path/to/repo" -BASE="$(git -C "$REPO" rev-parse --abbrev-ref HEAD)" -SAFE_TASK="$(printf '%s' "$TASK_ID" | tr -cd '[:alnum:]_-')" -BRANCH="codex/${SAFE_TASK}/$(date -u +%Y%m%d%H%M%S)" -WORKTREE="/tmp/${SAFE_TASK}-codex-lane" -``` - -Create the isolated lane: - -```bash -git -C "$REPO" fetch --all --prune -git -C "$REPO" worktree add -b "$BRANCH" "$WORKTREE" "$BASE" -git -C "$WORKTREE" status --short --branch -``` - -If the current Kanban workspace is already an isolated git worktree created for this task, you may create a sibling Codex branch inside it only if `git status --short` is clean except for intentional Hermes edits. Otherwise create a separate temporary worktree and cherry-pick or copy accepted commits back after reconciliation. - -Cleanup after reconciliation: - -```bash -git -C "$REPO" worktree remove "$WORKTREE" -git -C "$REPO" branch -D "$BRANCH" # only after accepted commits were copied/cherry-picked or intentionally rejected -``` - -Keep the worktree if it is needed as an artifact for review; record it in `codex_lane.artifacts` and mention it in the handoff. - -## Codex Capability Checks - -Run these before spawning Codex. Missing Codex is a normal reason to skip the lane, not a task blocker if Hermes can do the task directly. - -```bash -command -v codex -codex --version -codex features list | grep -i goals || true -``` - -If `/goal` support is required, enable or launch with the feature flag only after checking availability: - -```bash -codex features enable goals || true -codex --enable goals --version -``` - -Authentication can be via `OPENAI_API_KEY` or the Codex CLI OAuth state (often `~/.codex/auth.json`). Do not print token files. A missing `OPENAI_API_KEY` is not proof that auth is unavailable. - -## Mode Selection - -Use `codex exec` for bounded one-shot edits where Codex should exit on its own: - -```python -terminal( - command="codex exec --full-auto '$(cat /tmp/codex_prompt.md)'", - workdir=WORKTREE, - background=True, - pty=True, - notify_on_complete=True, -) -``` - -Use Codex `/goal` only for broader multi-step work that benefits from durable objective tracking. Launch interactively in a PTY/tmux session or with `codex --enable goals` if the feature is disabled by default. Keep the goal objective self-contained: repo path, task id, safety constraints, allowed scope, acceptance criteria, tests, and commit expectations. - -Example `/goal` objective text to paste into Codex: - -```text -/goal Work in this repository only: . Task: . -Hermes owns the Kanban lifecycle; do not call Hermes kanban tools or messaging. -Create small commits on branch <BRANCH>. Follow the PMB safety constraints in the prompt. -Run the requested verification commands and report exact outputs. Stop after producing a diff and summary. -``` - -Do not use `--yolo` for prediction-market-bot or safety-sensitive repos. Prefer `--full-auto` inside the isolated worktree, then rely on Hermes reconciliation. - -## Prompt Construction - -Use the linked template at `templates/pmb-codex-lane-prompt.md` for prediction-market-bot work. For other repos, keep the same structure and replace the PMB-specific safety block with repo-specific invariants. - -Every Codex prompt must include: - -- `task_id`, title, and full Kanban acceptance criteria. -- Repo path, worktree path, branch name, and allowed file scope. -- Explicit statement: Hermes owns Kanban lifecycle; Codex is an input lane only. -- Required output: concise summary, files changed, commits, tests run, and known risks. -- Prohibited actions: secrets access, external messaging, board mutation, unrelated refactors, dependency upgrades unless required. -- Verification commands Codex may run and commands Hermes will run afterward. - -For PMB, include these mandatory safety constraints verbatim: - -```text -PMB safety constraints: -- live-SIM is paper-only; do not add or enable live REST order entry. -- Never use market orders. -- Do not add execution crossing or bypass price/risk checks. -- Do not fake passive fills, fills, PnL, order states, or reconciliation evidence. -- Do not weaken risk gates, limits, kill switches, or fail-closed behavior. -- Keep research/selection outside the C++ hot path unless explicitly requested. -- Do not read, print, write, or require secrets/tokens/credentials. -``` - -## Monitoring, Timeout, and Kill Behavior - -Start long Codex lanes in the background with PTY and completion notification: - -```python -result = terminal( - command="codex exec --full-auto '$(cat /tmp/codex_prompt.md)'", - workdir=WORKTREE, - background=True, - pty=True, - notify_on_complete=True, -) -session_id = result["session_id"] -``` - -Monitor without interfering: - -```python -process(action="poll", session_id=session_id) -process(action="log", session_id=session_id, limit=200) -process(action="wait", session_id=session_id, timeout=300) -``` - -Send a Kanban heartbeat every few minutes for lanes longer than two minutes, e.g. `kanban_heartbeat(note="Codex lane running in <WORKTREE>; waiting for tests/diff")`. - -Kill conditions: - -- No useful output for the task's remaining runtime budget. -- Codex requests secrets, production credentials, or external permissions. -- Codex attempts to modify files outside the worktree. -- Codex starts unrelated rewrites or dependency churn. -- Codex is still running near the worker timeout and no safe partial artifact exists. - -Kill command: - -```python -process(action="kill", session_id=session_id) -``` - -After kill, inspect `git status --short`, preserve useful patches only if safe, and record `codex_lane.result: timed_out` or `rejected` with a concrete `rejected_reason`. - -## Reconciliation Checklist - -Hermes must perform this checklist before accepting any Codex lane result: - -- [ ] `git -C <WORKTREE> status --short --branch` shows only expected files. -- [ ] `git -C <WORKTREE> diff --stat` and `git diff` were reviewed by Hermes. -- [ ] No secrets, credentials, generated caches, unrelated data, or local artifacts are included. -- [ ] PMB safety constraints were preserved: no live REST order entry, no market orders, no execution crossing, no fake passive fills/PnL, no risk-gate weakening, no secrets. -- [ ] Codex commits are small enough to cherry-pick or squash cleanly. -- [ ] Hermes ran the canonical tests itself, using `scripts/run_tests.sh` for Hermes Agent or the repo's documented wrapper for other repos. -- [ ] Any Codex-run tests are listed separately from Hermes-run tests. -- [ ] Accepted commits/diffs were applied to the Hermes-owned workspace/branch. -- [ ] Rejected or partial work has a concrete reason and artifact path if useful. - -Acceptance outcomes: - -- `accepted`: Codex diff/commits were reviewed, applied, and verified. -- `partial`: Some Codex work was accepted after edits or cherry-picks; rejected parts are documented. -- `rejected`: No Codex changes were accepted; reason is documented. -- `timed_out`: Codex exceeded the lane budget; useful artifacts may or may not exist. - -## kanban_complete Metadata Schema - -Include this object under `metadata.codex_lane` for every task where the lane was considered. If Codex was not used, set `used: false` and explain why in `rejected_reason` or a sibling `notes` field. - -```json -{ - "codex_lane": { - "used": true, - "mode": "exec | goal | skipped", - "worktree": "/absolute/path/to/codex/worktree", - "branch": "codex/t_caa69668/20260508100000", - "command": "codex exec --full-auto ...", - "result": "accepted | rejected | partial | timed_out", - "accepted_commits": ["<sha1>", "<sha2>"], - "rejected_reason": "empty when fully accepted; otherwise concrete reason", - "tests_run": [ - {"command": "scripts/run_tests.sh tests/tools/test_x.py", "exit_code": 0, "owner": "hermes"}, - {"command": "codex-reported: npm test", "exit_code": 0, "owner": "codex"} - ], - "artifacts": ["/absolute/path/to/log-or-patch"] - } -} -``` - -For tasks that intentionally skip Codex: - -```json -{ - "codex_lane": { - "used": false, - "mode": "skipped", - "worktree": null, - "branch": null, - "command": null, - "result": "rejected", - "accepted_commits": [], - "rejected_reason": "Direct Hermes edit was smaller and safer than spawning Codex.", - "tests_run": [], - "artifacts": [] - } -} -``` - -## Common Pitfalls - -1. Treating Codex self-report as verification. Always inspect the diff and rerun tests from Hermes. -2. Running Codex in the user's dirty main checkout. Always isolate in a worktree/branch. -3. Letting Codex own Kanban. Codex may summarize progress, but Hermes writes board state. -4. Forgetting PMB safety invariants in the prompt. Missing safety text is a lane setup failure. -5. Using `/goal` for quick edits. Prefer `codex exec` unless durable multi-step continuation is needed. -6. Killing a stuck lane without recording why. `rejected_reason` must explain the decision. -7. Accepting broad unrelated cleanup because tests pass. Reject or cherry-pick only the scoped changes. - -## Verification Checklist - -- [ ] Codex was skipped or started only after `command -v codex`, `codex --version`, and optional goals feature checks. -- [ ] Codex ran only in an isolated worktree/branch. -- [ ] Prompt included task scope, ownership rules, PMB safety constraints when applicable, and verification commands. -- [ ] Hermes reviewed `git diff` and safety-sensitive files. -- [ ] Hermes ran canonical tests independently. -- [ ] `kanban_complete.metadata.codex_lane` follows the schema above. -- [ ] Temporary processes and unnecessary worktrees were cleaned up. diff --git a/skills/autonomous-ai-agents/kanban-codex-lane/templates/pmb-codex-lane-prompt.md b/skills/autonomous-ai-agents/kanban-codex-lane/templates/pmb-codex-lane-prompt.md deleted file mode 100644 index 73962f768..000000000 --- a/skills/autonomous-ai-agents/kanban-codex-lane/templates/pmb-codex-lane-prompt.md +++ /dev/null @@ -1,57 +0,0 @@ -# PMB Codex Lane Prompt Template - -Use this template when a Hermes Kanban worker chooses to run Codex as an implementation lane for prediction-market-bot. Fill every bracketed field before launching Codex. Do not include secrets. - -```text -You are Codex CLI running as an input lane for a Hermes Kanban worker. - -Ownership: -- Hermes owns the Kanban task lifecycle, final review, test verification, and handoff. -- You are an implementation lane only. Do not call Hermes kanban tools, Hermes CLI board commands, messaging gateways, or external notification tools. -- Produce a scoped diff/commits and a concise report; do not mark any task complete. - -Task: -- task_id: [KANBAN_TASK_ID] -- title: [KANBAN_TITLE] -- acceptance criteria: - [PASTE_ACCEPTANCE_CRITERIA] - -Repository and isolation: -- repo: [REPO_PATH] -- worktree: [CODEX_WORKTREE_PATH] -- branch: [CODEX_BRANCH] -- allowed files/scope: [ALLOWED_FILES_OR_DIRECTORIES] -- forbidden files/scope: [FORBIDDEN_FILES_OR_DIRECTORIES] - -PMB safety constraints: -- live-SIM is paper-only; do not add or enable live REST order entry. -- Never use market orders. -- Do not add execution crossing or bypass price/risk checks. -- Do not fake passive fills, fills, PnL, order states, or reconciliation evidence. -- Do not weaken risk gates, limits, kill switches, or fail-closed behavior. -- Keep research/selection outside the C++ hot path unless explicitly requested. -- Do not read, print, write, or require secrets/tokens/credentials. - -Implementation constraints: -- Follow existing project conventions and style. -- Keep diffs small and reviewable. -- Do not perform unrelated refactors, dependency upgrades, formatting sweeps, or generated-file churn. -- If a requirement is unsafe or ambiguous, stop and report the blocker instead of guessing. -- Commit only if asked by the Hermes worker; if committing, use small commits with clear subjects. - -Verification you may run: -- [COMMAND_1] -- [COMMAND_2] - -Verification Hermes will rerun independently: -- [HERMES_COMMAND_1] -- [HERMES_COMMAND_2] - -Required final report: -- Summary of changes. -- Files changed. -- Commit SHAs, if any. -- Tests/commands run with exit codes. -- Safety constraints checked. -- Known risks or incomplete items. -``` diff --git a/skills/devops/kanban-orchestrator/SKILL.md b/skills/devops/kanban-orchestrator/SKILL.md index 760f83071..fb5aa58a8 100644 --- a/skills/devops/kanban-orchestrator/SKILL.md +++ b/skills/devops/kanban-orchestrator/SKILL.md @@ -3,6 +3,7 @@ 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. version: 3.0.0 platforms: [linux, macos, windows] +environments: [kanban] metadata: hermes: tags: [kanban, multi-agent, orchestration, routing] diff --git a/skills/devops/kanban-worker/SKILL.md b/skills/devops/kanban-worker/SKILL.md index ef9022d9a..7dd64ad55 100644 --- a/skills/devops/kanban-worker/SKILL.md +++ b/skills/devops/kanban-worker/SKILL.md @@ -3,6 +3,7 @@ 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. version: 2.0.0 platforms: [linux, macos, windows] +environments: [kanban] metadata: hermes: tags: [kanban, multi-agent, collaboration, workflow, pitfalls] diff --git a/skills/diagramming/DESCRIPTION.md b/skills/diagramming/DESCRIPTION.md deleted file mode 100644 index 2d7c738ab..000000000 --- a/skills/diagramming/DESCRIPTION.md +++ /dev/null @@ -1,3 +0,0 @@ ---- -description: Diagram creation skills for generating visual diagrams, flowcharts, architecture diagrams, and illustrations using tools like Excalidraw. ---- diff --git a/skills/domain/DESCRIPTION.md b/skills/domain/DESCRIPTION.md deleted file mode 100644 index ae139e683..000000000 --- a/skills/domain/DESCRIPTION.md +++ /dev/null @@ -1,24 +0,0 @@ ---- -name: domain-intel -description: Passive domain reconnaissance using Python stdlib. Use this skill for subdomain discovery, SSL certificate inspection, WHOIS lookups, DNS records, domain availability checks, and bulk multi-domain analysis. No API keys required. Triggers on requests like "find subdomains", "check ssl cert", "whois lookup", "is this domain available", "bulk check these domains". -license: MIT ---- - -Passive domain intelligence using only Python stdlib and public data sources. -Zero dependencies. Zero API keys. Works out of the box. - -## Capabilities - -- Subdomain discovery via crt.sh certificate transparency logs -- Live SSL/TLS certificate inspection (expiry, cipher, SANs, TLS version) -- WHOIS lookup — supports 100+ TLDs via direct TCP queries -- DNS records: A, AAAA, MX, NS, TXT, CNAME -- Domain availability check (DNS + WHOIS + SSL signals) -- Bulk multi-domain analysis in parallel (up to 20 domains) - -## Data Sources - -- crt.sh — Certificate Transparency logs -- WHOIS servers — Direct TCP to 100+ authoritative TLD servers -- Google DNS-over-HTTPS — MX/NS/TXT/CNAME resolution -- System DNS — A/AAAA records diff --git a/skills/gifs/DESCRIPTION.md b/skills/gifs/DESCRIPTION.md deleted file mode 100644 index c3490dff3..000000000 --- a/skills/gifs/DESCRIPTION.md +++ /dev/null @@ -1,3 +0,0 @@ ---- -description: Skills for searching, downloading, and working with GIFs and short-form animated media. ---- diff --git a/skills/inference-sh/DESCRIPTION.md b/skills/inference-sh/DESCRIPTION.md deleted file mode 100644 index 011ede4c1..000000000 --- a/skills/inference-sh/DESCRIPTION.md +++ /dev/null @@ -1,19 +0,0 @@ -# inference.sh - -Run 150+ AI applications in the cloud via the [inference.sh](https://inference.sh) platform. - -**One API key for everything** — access image generation, video creation, LLMs, search, 3D, and more through a single account. No need to manage separate API keys for each provider. - -## Available Skills - -- **cli**: Use the inference.sh CLI (`infsh`) via the terminal tool - -## What's Included - -- **Image Generation**: FLUX, Reve, Seedream, Grok Imagine, Gemini -- **Video Generation**: Veo, Wan, Seedance, OmniHuman, HunyuanVideo -- **LLMs**: Claude, Gemini, Kimi, GLM-4 (via OpenRouter) -- **Search**: Tavily, Exa -- **3D**: Rodin -- **Social**: Twitter/X automation -- **Audio**: TTS, voice cloning diff --git a/skills/mcp/DESCRIPTION.md b/skills/mcp/DESCRIPTION.md deleted file mode 100644 index 30a066033..000000000 --- a/skills/mcp/DESCRIPTION.md +++ /dev/null @@ -1,3 +0,0 @@ ---- -description: 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. ---- diff --git a/skills/media/spotify/SKILL.md b/skills/media/spotify/SKILL.md deleted file mode 100644 index 47fe0e24b..000000000 --- a/skills/media/spotify/SKILL.md +++ /dev/null @@ -1,135 +0,0 @@ ---- -name: spotify -description: "Spotify: play, search, queue, manage playlists and devices." -version: 1.0.0 -author: Hermes Agent -license: MIT -platforms: [linux, macos, windows] -prerequisites: - tools: [spotify_playback, spotify_devices, spotify_queue, spotify_search, spotify_playlists, spotify_albums, spotify_library] -metadata: - hermes: - tags: [spotify, music, playback, playlists, media] - related_skills: [gif-search] ---- - -# Spotify - -Control the user's Spotify account via the Hermes Spotify toolset (7 tools). Setup guide: https://hermes-agent.nousresearch.com/docs/user-guide/features/spotify - -## When to use this skill - -The user says something like "play X", "pause", "skip", "queue up X", "what's playing", "search for X", "add to my X playlist", "make a playlist", "save this to my library", etc. - -## The 7 tools - -- `spotify_playback` — play, pause, next, previous, seek, set_repeat, set_shuffle, set_volume, get_state, get_currently_playing, recently_played -- `spotify_devices` — list, transfer -- `spotify_queue` — get, add -- `spotify_search` — search the catalog -- `spotify_playlists` — list, get, create, add_items, remove_items, update_details -- `spotify_albums` — get, tracks -- `spotify_library` — list/save/remove with `kind: "tracks"|"albums"` - -Playback-mutating actions require Spotify Premium; search/library/playlist ops work on Free. - -## Canonical patterns (minimize tool calls) - -### "Play <artist/track/album>" -One search, then play by URI. Do NOT loop through search results describing them unless the user asked for options. - -``` -spotify_search({"query": "miles davis kind of blue", "types": ["album"], "limit": 1}) -→ got album URI spotify:album:1weenld61qoidwYuZ1GESA -spotify_playback({"action": "play", "context_uri": "spotify:album:1weenld61qoidwYuZ1GESA"}) -``` - -For "play some <artist>" (no specific song), prefer `types: ["artist"]` and play the artist context URI — Spotify handles smart shuffle. If the user says "the song" or "that track", search `types: ["track"]` and pass `uris: [track_uri]` to play. - -### "What's playing?" / "What am I listening to?" -Single call — don't chain get_state after get_currently_playing. - -``` -spotify_playback({"action": "get_currently_playing"}) -``` - -If it returns 204/empty (`is_playing: false`), tell the user nothing is playing. Don't retry. - -### "Pause" / "Skip" / "Volume 50" -Direct action, no preflight inspection needed. - -``` -spotify_playback({"action": "pause"}) -spotify_playback({"action": "next"}) -spotify_playback({"action": "set_volume", "volume_percent": 50}) -``` - -### "Add to my <playlist name> playlist" -1. `spotify_playlists list` to find the playlist ID by name -2. Get the track URI (from currently playing, or search) -3. `spotify_playlists add_items` with the playlist_id and URIs - -``` -spotify_playlists({"action": "list"}) -→ found "Late Night Jazz" = 37i9dQZF1DX4wta20PHgwo -spotify_playback({"action": "get_currently_playing"}) -→ current track uri = spotify:track:0DiWol3AO6WpXZgp0goxAV -spotify_playlists({"action": "add_items", - "playlist_id": "37i9dQZF1DX4wta20PHgwo", - "uris": ["spotify:track:0DiWol3AO6WpXZgp0goxAV"]}) -``` - -### "Create a playlist called X and add the last 3 songs I played" -``` -spotify_playback({"action": "recently_played", "limit": 3}) -spotify_playlists({"action": "create", "name": "Focus 2026"}) -→ got playlist_id back in response -spotify_playlists({"action": "add_items", "playlist_id": <id>, "uris": [<3 uris>]}) -``` - -### "Save / unsave / is this saved?" -Use `spotify_library` with the right `kind`. - -``` -spotify_library({"kind": "tracks", "action": "save", "uris": ["spotify:track:..."]}) -spotify_library({"kind": "albums", "action": "list", "limit": 50}) -``` - -### "Transfer playback to my <device>" -``` -spotify_devices({"action": "list"}) -→ pick the device_id by matching name/type -spotify_devices({"action": "transfer", "device_id": "<id>", "play": true}) -``` - -## Critical failure modes - -**`403 Forbidden — No active device found`** on any playback action means Spotify isn't running anywhere. Tell the user: "Open Spotify on your phone/desktop/web player first, start any track for a second, then retry." Don't retry the tool call blindly — it will fail the same way. You can call `spotify_devices list` to confirm; an empty list means no active device. - -**`403 Forbidden — Premium required`** means the user is on Free and tried to mutate playback. Don't retry; tell them this action needs Premium. Reads still work (search, playlists, library, get_state). - -**`204 No Content` on `get_currently_playing`** is NOT an error — it means nothing is playing. The tool returns `is_playing: false`. Just report that to the user. - -**`429 Too Many Requests`** = rate limit. Wait and retry once. If it keeps happening, you're looping — stop. - -**`401 Unauthorized` after a retry** — refresh token revoked. Tell the user to run `hermes auth spotify` again. - -## URI and ID formats - -Spotify uses three interchangeable ID formats. The tools accept all three and normalize: - -- URI: `spotify:track:0DiWol3AO6WpXZgp0goxAV` (preferred) -- URL: `https://open.spotify.com/track/0DiWol3AO6WpXZgp0goxAV` -- Bare ID: `0DiWol3AO6WpXZgp0goxAV` - -When in doubt, use full URIs. Search results return URIs in the `uri` field — pass those directly. - -Entity types: `track`, `album`, `artist`, `playlist`, `show`, `episode`. Use the right type for the action — `spotify_playback.play` with a `context_uri` expects album/playlist/artist; `uris` expects an array of track URIs. - -## What NOT to do - -- **Don't call `get_state` before every action.** Spotify accepts play/pause/skip without preflight. Only inspect state when the user asked "what's playing" or you need to reason about device/track. -- **Don't describe search results unless asked.** If the user said "play X", search, grab the top URI, play it. They'll hear it's wrong if it's wrong. -- **Don't retry on `403 Premium required` or `403 No active device`.** Those are permanent until user action. -- **Don't use `spotify_search` to find a playlist by name** — that searches the public Spotify catalog. User playlists come from `spotify_playlists list`. -- **Don't mix `kind: "tracks"` with album URIs** in `spotify_library` (or vice versa). The tool normalizes IDs but the API endpoint differs. diff --git a/skills/mlops/training/DESCRIPTION.md b/skills/mlops/training/DESCRIPTION.md deleted file mode 100644 index fddb5248d..000000000 --- a/skills/mlops/training/DESCRIPTION.md +++ /dev/null @@ -1,3 +0,0 @@ ---- -description: Fine-tuning, RLHF/DPO/GRPO training, distributed training frameworks, and optimization tools for training LLMs and other models. ---- diff --git a/skills/mlops/vector-databases/DESCRIPTION.md b/skills/mlops/vector-databases/DESCRIPTION.md deleted file mode 100644 index 99a4ae094..000000000 --- a/skills/mlops/vector-databases/DESCRIPTION.md +++ /dev/null @@ -1,3 +0,0 @@ ---- -description: Vector similarity search and embedding databases for RAG, semantic search, and AI application backends. ---- diff --git a/skills/productivity/linear/SKILL.md b/skills/productivity/linear/SKILL.md deleted file mode 100644 index a08a03e43..000000000 --- a/skills/productivity/linear/SKILL.md +++ /dev/null @@ -1,380 +0,0 @@ ---- -name: linear -description: "Linear: manage issues, projects, teams via GraphQL + curl." -version: 1.0.0 -author: Hermes Agent -license: MIT -platforms: [linux, macos, windows] -prerequisites: - env_vars: [LINEAR_API_KEY] - commands: [curl] -metadata: - hermes: - tags: [Linear, Project Management, Issues, GraphQL, API, Productivity] ---- - -# Linear — Issue & Project Management - -Manage Linear issues, projects, and teams directly via the GraphQL API using `curl`. No MCP server, no OAuth flow, no extra dependencies. - -## Setup - -1. Get a personal API key from **Linear Settings > Account > Security & access > Personal API keys** (URL: https://linear.app/settings/account/security). Note: the org-level *Settings > API* page only shows OAuth apps and workspace-member keys, not personal keys. -2. Set `LINEAR_API_KEY` in your environment (via `hermes setup` or your env config) - -## API Basics - -- **Endpoint:** `https://api.linear.app/graphql` (POST) -- **Auth header:** `Authorization: $LINEAR_API_KEY` (no "Bearer" prefix for API keys) -- **All requests are POST** with `Content-Type: application/json` -- **Both UUIDs and short identifiers** (e.g., `ENG-123`) work for `issue(id:)` - -Base curl pattern: -```bash -curl -s -X POST https://api.linear.app/graphql \ - -H "Authorization: $LINEAR_API_KEY" \ - -H "Content-Type: application/json" \ - -d '{"query": "{ viewer { id name } }"}' | python3 -m json.tool -``` - -## Python helper script (ergonomic alternative) - -For faster one-liners that don't need hand-written GraphQL, this skill ships a stdlib Python CLI at `scripts/linear_api.py`. Zero dependencies. Same auth (reads `LINEAR_API_KEY`). - -```bash -SCRIPT=$(dirname "$(find ~/.hermes -path '*skills/productivity/linear/scripts/linear_api.py' 2>/dev/null | head -1)")/linear_api.py - -python3 "$SCRIPT" whoami -python3 "$SCRIPT" list-teams -python3 "$SCRIPT" get-issue ENG-42 -python3 "$SCRIPT" get-document 38359beef67c # fetch a doc by slugId from the URL -python3 "$SCRIPT" raw 'query { viewer { name } }' -``` - -All subcommands: `whoami`, `list-teams`, `list-projects`, `list-states`, `list-issues`, `get-issue`, `search-issues`, `create-issue`, `update-issue`, `update-status`, `add-comment`, `list-documents`, `get-document`, `search-documents`, `raw`. Run with `--help` for flags. - -Use the script when: you want a quick answer without crafting GraphQL. Use curl when: you need a query the script doesn't wrap, or you want to compose filters inline. - -## Workflow States - -Linear uses `WorkflowState` objects with a `type` field. **6 state types:** - -| Type | Description | -|------|-------------| -| `triage` | Incoming issues needing review | -| `backlog` | Acknowledged but not yet planned | -| `unstarted` | Planned/ready but not started | -| `started` | Actively being worked on | -| `completed` | Done | -| `canceled` | Won't do | - -Each team has its own named states (e.g., "In Progress" is type `started`). To change an issue's status, you need the `stateId` (UUID) of the target state — query workflow states first. - -**Priority values:** 0 = None, 1 = Urgent, 2 = High, 3 = Medium, 4 = Low - -## Common Queries - -### Get current user -```bash -curl -s -X POST https://api.linear.app/graphql \ - -H "Authorization: $LINEAR_API_KEY" \ - -H "Content-Type: application/json" \ - -d '{"query": "{ viewer { id name email } }"}' | python3 -m json.tool -``` - -### List teams -```bash -curl -s -X POST https://api.linear.app/graphql \ - -H "Authorization: $LINEAR_API_KEY" \ - -H "Content-Type: application/json" \ - -d '{"query": "{ teams { nodes { id name key } } }"}' | python3 -m json.tool -``` - -### List workflow states for a team -```bash -curl -s -X POST https://api.linear.app/graphql \ - -H "Authorization: $LINEAR_API_KEY" \ - -H "Content-Type: application/json" \ - -d '{"query": "{ workflowStates(filter: { team: { key: { eq: \"ENG\" } } }) { nodes { id name type } } }"}' | python3 -m json.tool -``` - -### List issues (first 20) -```bash -curl -s -X POST https://api.linear.app/graphql \ - -H "Authorization: $LINEAR_API_KEY" \ - -H "Content-Type: application/json" \ - -d '{"query": "{ issues(first: 20) { nodes { identifier title priority state { name type } assignee { name } team { key } url } pageInfo { hasNextPage endCursor } } }"}' | python3 -m json.tool -``` - -### List my assigned issues -```bash -curl -s -X POST https://api.linear.app/graphql \ - -H "Authorization: $LINEAR_API_KEY" \ - -H "Content-Type: application/json" \ - -d '{"query": "{ viewer { assignedIssues(first: 25) { nodes { identifier title state { name type } priority url } } } }"}' | python3 -m json.tool -``` - -### Get a single issue (by identifier like ENG-123) -```bash -curl -s -X POST https://api.linear.app/graphql \ - -H "Authorization: $LINEAR_API_KEY" \ - -H "Content-Type: application/json" \ - -d '{"query": "{ issue(id: \"ENG-123\") { id identifier title description priority state { id name type } assignee { id name } team { key } project { name } labels { nodes { name } } comments { nodes { body user { name } createdAt } } url } }"}' | python3 -m json.tool -``` - -### Search issues by text -```bash -curl -s -X POST https://api.linear.app/graphql \ - -H "Authorization: $LINEAR_API_KEY" \ - -H "Content-Type: application/json" \ - -d '{"query": "{ issueSearch(query: \"bug login\", first: 10) { nodes { identifier title state { name } assignee { name } url } } }"}' | python3 -m json.tool -``` - -### Filter issues by state type -```bash -curl -s -X POST https://api.linear.app/graphql \ - -H "Authorization: $LINEAR_API_KEY" \ - -H "Content-Type: application/json" \ - -d '{"query": "{ issues(filter: { state: { type: { in: [\"started\"] } } }, first: 20) { nodes { identifier title state { name } assignee { name } } } }"}' | python3 -m json.tool -``` - -### Filter by team and assignee -```bash -curl -s -X POST https://api.linear.app/graphql \ - -H "Authorization: $LINEAR_API_KEY" \ - -H "Content-Type: application/json" \ - -d '{"query": "{ issues(filter: { team: { key: { eq: \"ENG\" } }, assignee: { email: { eq: \"user@example.com\" } } }, first: 20) { nodes { identifier title state { name } priority } } }"}' | python3 -m json.tool -``` - -### List projects -```bash -curl -s -X POST https://api.linear.app/graphql \ - -H "Authorization: $LINEAR_API_KEY" \ - -H "Content-Type: application/json" \ - -d '{"query": "{ projects(first: 20) { nodes { id name description progress lead { name } teams { nodes { key } } url } } }"}' | python3 -m json.tool -``` - -### List team members -```bash -curl -s -X POST https://api.linear.app/graphql \ - -H "Authorization: $LINEAR_API_KEY" \ - -H "Content-Type: application/json" \ - -d '{"query": "{ users { nodes { id name email active } } }"}' | python3 -m json.tool -``` - -### List labels -```bash -curl -s -X POST https://api.linear.app/graphql \ - -H "Authorization: $LINEAR_API_KEY" \ - -H "Content-Type: application/json" \ - -d '{"query": "{ issueLabels { nodes { id name color } } }"}' | python3 -m json.tool -``` - -## Common Mutations - -### Create an issue -```bash -curl -s -X POST https://api.linear.app/graphql \ - -H "Authorization: $LINEAR_API_KEY" \ - -H "Content-Type: application/json" \ - -d '{ - "query": "mutation($input: IssueCreateInput!) { issueCreate(input: $input) { success issue { id identifier title url } } }", - "variables": { - "input": { - "teamId": "TEAM_UUID", - "title": "Fix login bug", - "description": "Users cannot login with SSO", - "priority": 2 - } - } - }' | python3 -m json.tool -``` - -### Update issue status -First get the target state UUID from the workflow states query above, then: -```bash -curl -s -X POST https://api.linear.app/graphql \ - -H "Authorization: $LINEAR_API_KEY" \ - -H "Content-Type: application/json" \ - -d '{"query": "mutation { issueUpdate(id: \"ENG-123\", input: { stateId: \"STATE_UUID\" }) { success issue { identifier state { name type } } } }"}' | python3 -m json.tool -``` - -### Assign an issue -```bash -curl -s -X POST https://api.linear.app/graphql \ - -H "Authorization: $LINEAR_API_KEY" \ - -H "Content-Type: application/json" \ - -d '{"query": "mutation { issueUpdate(id: \"ENG-123\", input: { assigneeId: \"USER_UUID\" }) { success issue { identifier assignee { name } } } }"}' | python3 -m json.tool -``` - -### Set priority -```bash -curl -s -X POST https://api.linear.app/graphql \ - -H "Authorization: $LINEAR_API_KEY" \ - -H "Content-Type: application/json" \ - -d '{"query": "mutation { issueUpdate(id: \"ENG-123\", input: { priority: 1 }) { success issue { identifier priority } } }"}' | python3 -m json.tool -``` - -### Add a comment -```bash -curl -s -X POST https://api.linear.app/graphql \ - -H "Authorization: $LINEAR_API_KEY" \ - -H "Content-Type: application/json" \ - -d '{"query": "mutation { commentCreate(input: { issueId: \"ISSUE_UUID\", body: \"Investigated. Root cause is X.\" }) { success comment { id body } } }"}' | python3 -m json.tool -``` - -### Set due date -```bash -curl -s -X POST https://api.linear.app/graphql \ - -H "Authorization: $LINEAR_API_KEY" \ - -H "Content-Type: application/json" \ - -d '{"query": "mutation { issueUpdate(id: \"ENG-123\", input: { dueDate: \"2026-04-01\" }) { success issue { identifier dueDate } } }"}' | python3 -m json.tool -``` - -### Add labels to an issue -```bash -curl -s -X POST https://api.linear.app/graphql \ - -H "Authorization: $LINEAR_API_KEY" \ - -H "Content-Type: application/json" \ - -d '{"query": "mutation { issueUpdate(id: \"ENG-123\", input: { labelIds: [\"LABEL_UUID_1\", \"LABEL_UUID_2\"] }) { success issue { identifier labels { nodes { name } } } } }"}' | python3 -m json.tool -``` - -### Add issue to a project -```bash -curl -s -X POST https://api.linear.app/graphql \ - -H "Authorization: $LINEAR_API_KEY" \ - -H "Content-Type: application/json" \ - -d '{"query": "mutation { issueUpdate(id: \"ENG-123\", input: { projectId: \"PROJECT_UUID\" }) { success issue { identifier project { name } } } }"}' | python3 -m json.tool -``` - -### Create a project -```bash -curl -s -X POST https://api.linear.app/graphql \ - -H "Authorization: $LINEAR_API_KEY" \ - -H "Content-Type: application/json" \ - -d '{ - "query": "mutation($input: ProjectCreateInput!) { projectCreate(input: $input) { success project { id name url } } }", - "variables": { - "input": { - "name": "Q2 Auth Overhaul", - "description": "Replace legacy auth with OAuth2 and PKCE", - "teamIds": ["TEAM_UUID"] - } - } - }' | python3 -m json.tool -``` - -## Documents - -Linear **Documents** are prose docs (RFCs, specs, notes) stored alongside issues. They have their own `documents` root query and `document(id:)` single-fetch. - -### Document URLs and `slugId` - -Document URLs look like: -``` -https://linear.app/<workspace>/document/<slug>-<hexSlugId> -``` - -The trailing hex segment is the `slugId`. Example: `https://linear.app/nousresearch/document/rfc-hermes-permission-gateway-discord-38359beef67c` → `slugId` is `38359beef67c`. - -**Important schema detail:** the Markdown body is in the `content` field. The ProseMirror JSON is in `contentState` (not `contentData` — that field does not exist and the API returns 400). - -### Fetch a document by slugId - -`document(id:)` only accepts UUIDs. To fetch by the URL's hex slug, filter the collection: - -```bash -curl -s -X POST https://api.linear.app/graphql \ - -H "Authorization: $LINEAR_API_KEY" \ - -H "Content-Type: application/json" \ - -d '{"query": "query($s: String!) { documents(filter: { slugId: { eq: $s } }, first: 1) { nodes { id title content contentState slugId url creator { name } project { name } updatedAt } } }", "variables": {"s": "38359beef67c"}}' \ - | python3 -m json.tool -``` - -Or via the Python helper: -```bash -python3 scripts/linear_api.py get-document 38359beef67c -``` - -### Fetch a document by UUID - -```bash -curl -s -X POST https://api.linear.app/graphql \ - -H "Authorization: $LINEAR_API_KEY" \ - -H "Content-Type: application/json" \ - -d '{"query": "{ document(id: \"11700cff-b514-4db3-afcc-3ed1afacba1c\") { title content url } }"}' \ - | python3 -m json.tool -``` - -### List recent documents - -```bash -curl -s -X POST https://api.linear.app/graphql \ - -H "Authorization: $LINEAR_API_KEY" \ - -H "Content-Type: application/json" \ - -d '{"query": "{ documents(first: 25, orderBy: updatedAt) { nodes { id title slugId url updatedAt project { name } } } }"}' \ - | python3 -m json.tool -``` - -### Search documents by title - -Linear's schema has no `searchDocuments` root. Use a title-substring filter instead: - -```bash -curl -s -X POST https://api.linear.app/graphql \ - -H "Authorization: $LINEAR_API_KEY" \ - -H "Content-Type: application/json" \ - -d '{"query": "{ documents(filter: { title: { containsIgnoreCase: \"RFC\" } }, first: 25) { nodes { title slugId url } } }"}' \ - | python3 -m json.tool -``` - -## Pagination - -Linear uses Relay-style cursor pagination: - -```bash -# First page -curl -s -X POST https://api.linear.app/graphql \ - -H "Authorization: $LINEAR_API_KEY" \ - -H "Content-Type: application/json" \ - -d '{"query": "{ issues(first: 20) { nodes { identifier title } pageInfo { hasNextPage endCursor } } }"}' | python3 -m json.tool - -# Next page — use endCursor from previous response -curl -s -X POST https://api.linear.app/graphql \ - -H "Authorization: $LINEAR_API_KEY" \ - -H "Content-Type: application/json" \ - -d '{"query": "{ issues(first: 20, after: \"CURSOR_FROM_PREVIOUS\") { nodes { identifier title } pageInfo { hasNextPage endCursor } } }"}' | python3 -m json.tool -``` - -Default page size: 50. Max: 250. Always use `first: N` to limit results. - -## Filtering Reference - -Comparators: `eq`, `neq`, `in`, `nin`, `lt`, `lte`, `gt`, `gte`, `contains`, `startsWith`, `containsIgnoreCase` - -Combine filters with `or: [...]` for OR logic (default is AND within a filter object). - -## Typical Workflow - -1. **Query teams** to get team IDs and keys -2. **Query workflow states** for target team to get state UUIDs -3. **List or search issues** to find what needs work -4. **Create issues** with team ID, title, description, priority -5. **Update status** by setting `stateId` to the target workflow state -6. **Add comments** to track progress -7. **Mark complete** by setting `stateId` to the team's "completed" type state - -## Rate Limits - -- 5,000 requests/hour per API key -- 3,000,000 complexity points/hour -- Use `first: N` to limit results and reduce complexity cost -- Monitor `X-RateLimit-Requests-Remaining` response header - -## Important Notes - -- Always use `terminal` tool with `curl` for API calls — do NOT use `web_extract` or `browser` -- Always check the `errors` array in GraphQL responses — HTTP 200 can still contain errors -- If `stateId` is omitted when creating issues, Linear defaults to the first backlog state -- The `description` field supports Markdown -- Use `python3 -m json.tool` or `jq` to format JSON responses for readability diff --git a/skills/productivity/linear/scripts/linear_api.py b/skills/productivity/linear/scripts/linear_api.py deleted file mode 100644 index cb8c5d846..000000000 --- a/skills/productivity/linear/scripts/linear_api.py +++ /dev/null @@ -1,445 +0,0 @@ -#!/usr/bin/env python3 -"""Linear GraphQL API CLI — zero dependencies, stdlib only. - -Usage: - linear_api.py <command> [args...] - -Commands: - whoami Show authenticated user - list-teams List all teams - list-projects [--team KEY] List projects (optionally filter by team) - list-states [--team KEY] List workflow states - list-issues [filters] List issues - --team KEY Filter by team key (e.g. ENG) - --status NAME Filter by workflow state name - --assignee NAME Filter by assignee name (exact) - --label NAME Filter by label name - --limit N Max results (default: 25) - get-issue <IDENTIFIER> Full issue details (e.g. ENG-42) - search-issues <query> Full-text search across issues - create-issue [options] Create a new issue - --title TITLE Required - --team KEY Required - --description DESC - --priority 0-4 0=none, 1=urgent, 4=low - --label NAME - --assignee NAME - --parent IDENTIFIER Parent issue ID for sub-issues - update-issue <IDENTIFIER> [options] Update existing issue (same options as create) - update-status <IDENTIFIER> <STATE> Move issue to workflow state (by state name) - add-comment <IDENTIFIER> <body> Add comment to issue - - list-documents [--limit N] List documents (docs, not issues) - get-document <SLUG_OR_ID> Fetch a document by slugId (from URL) or UUID - search-documents <query> Search documents by title - - raw <graphql_query> [variables_json] Run an arbitrary GraphQL query - Use --vars '{"key":"value"}' for variables - -Auth: - Set LINEAR_API_KEY environment variable (from Linear Settings -> API). - Uses the personal API key header format: `Authorization: <KEY>` (no Bearer prefix). - -Output: - JSON to stdout. Errors to stderr with non-zero exit code. -""" -from __future__ import annotations - -import argparse -import json -import os -import sys -import urllib.error -import urllib.request -from typing import Any - -API_URL = "https://api.linear.app/graphql" - - -def _get_key() -> str: - key = os.environ.get("LINEAR_API_KEY", "").strip() - if not key: - sys.stderr.write( - "ERROR: LINEAR_API_KEY not set.\n" - "Create one at https://linear.app/settings/api and export it,\n" - "or add `LINEAR_API_KEY=lin_api_...` to ~/.hermes/.env\n" - ) - sys.exit(2) - return key - - -def gql(query: str, variables: dict[str, Any] | None = None) -> dict[str, Any]: - """Execute a GraphQL query against Linear. Raises on HTTP error or GraphQL errors.""" - key = _get_key() - payload = {"query": query} - if variables: - payload["variables"] = variables - data = json.dumps(payload).encode("utf-8") - req = urllib.request.Request( - API_URL, - data=data, - headers={ - "Content-Type": "application/json", - "Authorization": key, # Personal API key — NO `Bearer` prefix - "User-Agent": "hermes-agent-linear-skill/1.0", - }, - method="POST", - ) - try: - with urllib.request.urlopen(req, timeout=30) as resp: - body = resp.read().decode("utf-8") - except urllib.error.HTTPError as e: - sys.stderr.write(f"HTTP {e.code}: {e.read().decode('utf-8', 'replace')}\n") - sys.exit(1) - except urllib.error.URLError as e: - sys.stderr.write(f"Network error: {e}\n") - sys.exit(1) - - result = json.loads(body) - if "errors" in result and result["errors"]: - sys.stderr.write(f"GraphQL errors: {json.dumps(result['errors'], indent=2)}\n") - # Still return data if partial success; let caller decide - if not result.get("data"): - sys.exit(1) - return result.get("data", {}) or {} - - -def emit(obj: Any) -> None: - print(json.dumps(obj, indent=2, default=str)) - - -# ---------- Commands ---------- - -def cmd_whoami(_args: argparse.Namespace) -> None: - q = "query { viewer { id name email displayName } }" - emit(gql(q).get("viewer")) - - -def cmd_list_teams(_args: argparse.Namespace) -> None: - q = "query { teams(first: 100) { nodes { id key name description } } }" - emit(gql(q).get("teams", {}).get("nodes", [])) - - -def _resolve_team_id(key_or_name: str) -> str | None: - """Map a team key (ENG) or name to UUID.""" - q = "query { teams(first: 100) { nodes { id key name } } }" - teams = gql(q).get("teams", {}).get("nodes", []) - kl = key_or_name.lower() - for t in teams: - if t["key"].lower() == kl or t["name"].lower() == kl: - return t["id"] - return None - - -def cmd_list_projects(args: argparse.Namespace) -> None: - if args.team: - tid = _resolve_team_id(args.team) - if not tid: - sys.stderr.write(f"Team not found: {args.team}\n") - sys.exit(1) - q = """query($id: String!) { - team(id: $id) { projects(first: 100) { nodes { id name description state } } } - }""" - data = gql(q, {"id": tid}) - emit(data.get("team", {}).get("projects", {}).get("nodes", [])) - else: - q = "query { projects(first: 100) { nodes { id name description state } } }" - emit(gql(q).get("projects", {}).get("nodes", [])) - - -def cmd_list_states(args: argparse.Namespace) -> None: - if args.team: - tid = _resolve_team_id(args.team) - if not tid: - sys.stderr.write(f"Team not found: {args.team}\n") - sys.exit(1) - q = """query($id: String!) { - team(id: $id) { states(first: 100) { nodes { id name type color } } } - }""" - emit(gql(q, {"id": tid}).get("team", {}).get("states", {}).get("nodes", [])) - else: - q = "query { workflowStates(first: 200) { nodes { id name type team { key } } } }" - emit(gql(q).get("workflowStates", {}).get("nodes", [])) - - -def cmd_list_issues(args: argparse.Namespace) -> None: - filt: dict[str, Any] = {} - if args.team: - filt["team"] = {"key": {"eq": args.team}} - if args.status: - filt["state"] = {"name": {"eq": args.status}} - if args.assignee: - filt["assignee"] = {"name": {"eq": args.assignee}} - if args.label: - filt["labels"] = {"name": {"eq": args.label}} - - q = """query($filter: IssueFilter, $first: Int!) { - issues(filter: $filter, first: $first, orderBy: updatedAt) { - nodes { - id identifier title - state { name } priority - assignee { name } - team { key } - updatedAt url - } - } - }""" - data = gql(q, {"filter": filt or None, "first": args.limit}) - emit(data.get("issues", {}).get("nodes", [])) - - -def cmd_get_issue(args: argparse.Namespace) -> None: - q = """query($id: String!) { - issue(id: $id) { - id identifier title description - state { name type } - priority priorityLabel - assignee { name email } - creator { name } - team { key name } - project { name } - labels { nodes { name } } - parent { identifier title } - children { nodes { identifier title state { name } } } - comments { nodes { user { name } body createdAt } } - createdAt updatedAt url - } - }""" - emit(gql(q, {"id": args.identifier}).get("issue")) - - -def cmd_search_issues(args: argparse.Namespace) -> None: - q = """query($term: String!, $first: Int!) { - searchIssues(term: $term, first: $first) { - nodes { id identifier title state { name } url } - } - }""" - emit(gql(q, {"term": args.query, "first": args.limit}).get("searchIssues", {}).get("nodes", [])) - - -def cmd_create_issue(args: argparse.Namespace) -> None: - tid = _resolve_team_id(args.team) - if not tid: - sys.stderr.write(f"Team not found: {args.team}\n") - sys.exit(1) - inp: dict[str, Any] = {"title": args.title, "teamId": tid} - if args.description: - inp["description"] = args.description - if args.priority is not None: - inp["priority"] = args.priority - if args.parent: - inp["parentId"] = args.parent - # TODO: label + assignee name->id lookup (omitted for v1 brevity) - - q = """mutation($input: IssueCreateInput!) { - issueCreate(input: $input) { - success issue { id identifier title url } - } - }""" - emit(gql(q, {"input": inp}).get("issueCreate")) - - -def cmd_update_issue(args: argparse.Namespace) -> None: - inp: dict[str, Any] = {} - if args.title: - inp["title"] = args.title - if args.description: - inp["description"] = args.description - if args.priority is not None: - inp["priority"] = args.priority - if not inp: - sys.stderr.write("No update fields provided.\n") - sys.exit(1) - q = """mutation($id: String!, $input: IssueUpdateInput!) { - issueUpdate(id: $id, input: $input) { - success issue { identifier title url } - } - }""" - emit(gql(q, {"id": args.identifier, "input": inp}).get("issueUpdate")) - - -def cmd_update_status(args: argparse.Namespace) -> None: - # Resolve state name -> id within the issue's team - get_q = """query($id: String!) { - issue(id: $id) { team { id states(first: 100) { nodes { id name } } } } - }""" - issue = gql(get_q, {"id": args.identifier}).get("issue") - if not issue: - sys.stderr.write(f"Issue not found: {args.identifier}\n") - sys.exit(1) - sl = args.state.lower() - match = next((s for s in issue["team"]["states"]["nodes"] if s["name"].lower() == sl), None) - if not match: - sys.stderr.write( - f"State '{args.state}' not found. Available: " - f"{[s['name'] for s in issue['team']['states']['nodes']]}\n" - ) - sys.exit(1) - - q = """mutation($id: String!, $stateId: String!) { - issueUpdate(id: $id, input: { stateId: $stateId }) { - success issue { identifier state { name } url } - } - }""" - emit(gql(q, {"id": args.identifier, "stateId": match["id"]}).get("issueUpdate")) - - -def cmd_add_comment(args: argparse.Namespace) -> None: - q = """mutation($input: CommentCreateInput!) { - commentCreate(input: $input) { - success comment { id body createdAt } - } - }""" - emit(gql(q, {"input": {"issueId": args.identifier, "body": args.body}}).get("commentCreate")) - - -# ---- Documents ---- - -def cmd_list_documents(args: argparse.Namespace) -> None: - q = """query($first: Int!) { - documents(first: $first, orderBy: updatedAt) { - nodes { id title slugId updatedAt url project { name } creator { name } } - } - }""" - emit(gql(q, {"first": args.limit}).get("documents", {}).get("nodes", [])) - - -def cmd_get_document(args: argparse.Namespace) -> None: - """Fetch a document by slugId (from URL) OR full UUID. - - Linear document URLs look like: - https://linear.app/<workspace>/document/<slug>-<shortid> - The part we want is the final hex segment (the slugId). - """ - ref = args.ref - # If it looks like a UUID, query by id. Otherwise, assume slugId. - is_uuid = len(ref) == 36 and ref.count("-") == 4 - if is_uuid: - q = """query($id: String!) { - document(id: $id) { - id title content contentState slugId - createdAt updatedAt url - creator { name } project { name } - } - }""" - emit(gql(q, {"id": ref}).get("document")) - else: - # Query the collection and filter by slugId — the doc() query only accepts UUIDs. - q = """query($slug: String!) { - documents(filter: { slugId: { eq: $slug } }, first: 1) { - nodes { - id title content contentState slugId - createdAt updatedAt url - creator { name } project { name } - } - } - }""" - nodes = gql(q, {"slug": ref}).get("documents", {}).get("nodes", []) - emit(nodes[0] if nodes else None) - - -def cmd_search_documents(args: argparse.Namespace) -> None: - # Linear doesn't have a first-class searchDocuments — use title filter as a fallback. - q = """query($term: String!, $first: Int!) { - documents(filter: { title: { containsIgnoreCase: $term } }, first: $first) { - nodes { id title slugId url updatedAt } - } - }""" - emit(gql(q, {"term": args.query, "first": args.limit}).get("documents", {}).get("nodes", [])) - - -def cmd_raw(args: argparse.Namespace) -> None: - variables = json.loads(args.vars) if args.vars else None - emit(gql(args.query, variables)) - - -# ---------- Arg parsing ---------- - -def build_parser() -> argparse.ArgumentParser: - p = argparse.ArgumentParser(prog="linear_api.py", description="Linear GraphQL CLI") - sub = p.add_subparsers(dest="cmd", required=True) - - sub.add_parser("whoami").set_defaults(func=cmd_whoami) - sub.add_parser("list-teams").set_defaults(func=cmd_list_teams) - - lp = sub.add_parser("list-projects") - lp.add_argument("--team") - lp.set_defaults(func=cmd_list_projects) - - ls = sub.add_parser("list-states") - ls.add_argument("--team") - ls.set_defaults(func=cmd_list_states) - - li = sub.add_parser("list-issues") - li.add_argument("--team") - li.add_argument("--status") - li.add_argument("--assignee") - li.add_argument("--label") - li.add_argument("--limit", type=int, default=25) - li.set_defaults(func=cmd_list_issues) - - gi = sub.add_parser("get-issue") - gi.add_argument("identifier") - gi.set_defaults(func=cmd_get_issue) - - si = sub.add_parser("search-issues") - si.add_argument("query") - si.add_argument("--limit", type=int, default=25) - si.set_defaults(func=cmd_search_issues) - - ci = sub.add_parser("create-issue") - ci.add_argument("--title", required=True) - ci.add_argument("--team", required=True) - ci.add_argument("--description") - ci.add_argument("--priority", type=int, choices=[0, 1, 2, 3, 4]) - ci.add_argument("--label") - ci.add_argument("--assignee") - ci.add_argument("--parent") - ci.set_defaults(func=cmd_create_issue) - - ui = sub.add_parser("update-issue") - ui.add_argument("identifier") - ui.add_argument("--title") - ui.add_argument("--description") - ui.add_argument("--priority", type=int, choices=[0, 1, 2, 3, 4]) - ui.set_defaults(func=cmd_update_issue) - - us = sub.add_parser("update-status") - us.add_argument("identifier") - us.add_argument("state") - us.set_defaults(func=cmd_update_status) - - ac = sub.add_parser("add-comment") - ac.add_argument("identifier") - ac.add_argument("body") - ac.set_defaults(func=cmd_add_comment) - - ld = sub.add_parser("list-documents") - ld.add_argument("--limit", type=int, default=50) - ld.set_defaults(func=cmd_list_documents) - - gd = sub.add_parser("get-document") - gd.add_argument("ref", help="slugId (hex suffix from URL) or full UUID") - gd.set_defaults(func=cmd_get_document) - - sd = sub.add_parser("search-documents") - sd.add_argument("query") - sd.add_argument("--limit", type=int, default=25) - sd.set_defaults(func=cmd_search_documents) - - r = sub.add_parser("raw") - r.add_argument("query") - r.add_argument("--vars", help="JSON string of variables") - r.set_defaults(func=cmd_raw) - - return p - - -def main(argv: list[str] | None = None) -> None: - parser = build_parser() - args = parser.parse_args(argv) - args.func(args) - - -if __name__ == "__main__": - main() diff --git a/skills/software-development/debugging-hermes-tui-commands/SKILL.md b/skills/software-development/debugging-hermes-tui-commands/SKILL.md deleted file mode 100644 index 6accc1e2d..000000000 --- a/skills/software-development/debugging-hermes-tui-commands/SKILL.md +++ /dev/null @@ -1,152 +0,0 @@ ---- -name: debugging-hermes-tui-commands -description: "Debug Hermes TUI slash commands: Python, gateway, Ink UI." -version: 1.0.0 -author: Hermes Agent -license: MIT -platforms: [linux, macos, windows] -metadata: - hermes: - tags: [debugging, hermes-agent, tui, slash-commands, typescript, python] - related_skills: [python-debugpy, node-inspect-debugger, systematic-debugging] ---- - -# Debugging Hermes TUI Slash Commands - -## Overview - -Hermes slash commands span three layers — Python command registry, tui_gateway JSON-RPC bridge, and the Ink/TypeScript frontend. When a command misbehaves (missing from autocomplete, works in CLI but not TUI, config persists but UI doesn't update), the bug is almost always one layer being out of sync with another. - -Use this skill when you encounter issues with slash commands in the Hermes TUI, particularly when commands aren't showing in autocomplete, aren't working properly in the TUI, or need to be added/updated. - -## When to Use - -- A slash command exists in one part of the codebase but doesn't work fully -- A command needs to be added to both backend and frontend -- Command autocomplete isn't working for specific commands -- Command behavior is inconsistent between CLI and TUI -- A command persists config but doesn't apply live in the TUI - -## Architecture Overview - -``` -Python backend (hermes_cli/commands.py) <- canonical COMMAND_REGISTRY - │ - ▼ -TUI gateway (tui_gateway/server.py) <- slash.exec / command.dispatch - │ - ▼ -TUI frontend (ui-tui/src/app/slash/) <- local handlers + fallthrough -``` - -Command definitions must be registered consistently across Python and TypeScript to work properly. The Python `COMMAND_REGISTRY` is the source of truth for: CLI dispatch, gateway help, Telegram BotCommand menu, Slack subcommand map, and autocomplete data shipped to Ink. - -## Investigation Steps - -1. **Check if the command exists in the TUI frontend:** - ```bash - search_files --pattern "/commandname" --file_glob "*.ts" --path ui-tui/ - search_files --pattern "/commandname" --file_glob "*.tsx" --path ui-tui/ - ``` - -2. **Examine the TUI command definition:** - ```bash - read_file ui-tui/src/app/slash/commands/core.ts - # If not there: - search_files --pattern "commandname" --path ui-tui/src/app/slash/commands --target files - ``` - -3. **Check if the command exists in the Python backend:** - ```bash - search_files --pattern "CommandDef" --file_glob "*.py" --path hermes_cli/ - search_files --pattern "commandname" --path hermes_cli/commands.py --context 3 - ``` - -4. **Examine the gateway implementation:** - ```bash - search_files --pattern "complete.slash|slash.exec" --path tui_gateway/ - ``` - -## Fix: Missing Command Autocomplete - -If a command exists in the TUI but doesn't show in autocomplete: - -1. Add a `CommandDef` entry to `COMMAND_REGISTRY` in `hermes_cli/commands.py`: - ```python - CommandDef("commandname", "Description of the command", "Session", - cli_only=True, aliases=("alias",), - args_hint="[arg1|arg2|arg3]", - subcommands=("arg1", "arg2", "arg3")), - ``` - -2. Pick `cli_only` vs gateway availability carefully: - - `cli_only=True` — only in the interactive CLI/TUI - - `gateway_only=True` — only in messaging platforms - - neither — available everywhere - - `gateway_config_gate="display.foo"` — config-gated availability in the gateway - -3. Ensure `subcommands` matches the expected tab-completion options shown by the TUI. - -4. If the command runs server-side, add a handler in `HermesCLI.process_command()` in `cli.py`: - ```python - elif canonical == "commandname": - self._handle_commandname(cmd_original) - ``` - -5. For gateway-available commands, add a handler in `gateway/run.py`: - ```python - if canonical == "commandname": - return await self._handle_commandname(event) - ``` - -## Common Issues - -1. **Command shows in TUI but not in autocomplete.** The command is defined in the TUI codebase but missing from `COMMAND_REGISTRY` in `hermes_cli/commands.py`. Autocomplete data ships from Python. - -2. **Command shows in autocomplete but doesn't work.** Check the command handler in `tui_gateway/server.py` and the frontend handler in `ui-tui/src/app/createSlashHandler.ts`. If the command is local-only in Ink, it must be handled in `app.tsx` built-in branch; otherwise it falls through to `slash.exec` and must have a Python handler. - -3. **Command behavior differs between CLI and TUI.** The command might have different implementations. Check both `cli.py::process_command` and the TUI's local handler. Local TUI handlers take precedence over gateway dispatch. - -4. **Command persists config but doesn't apply live.** For TUI-local commands, updating `config.set` is not enough. Also patch the relevant nanostore state immediately (usually `patchUiState(...)`) and pass any new state through rendering components. Example: `/details collapsed` must update live detail visibility, not just save `details_mode`; in-session global `/details <mode>` may need a separate command-override flag so live commands can override built-in section defaults while startup/config sync preserves default-expanded thinking/tools behavior. - -5. **Gateway dispatch silently ignores the command.** The gateway only dispatches commands it knows about. Check `GATEWAY_KNOWN_COMMANDS` (derived from `COMMAND_REGISTRY` automatically) includes the canonical name. If the command is `cli_only` with a `gateway_config_gate`, verify the gated config value is truthy. - -## Debugging Tactics - -When surface-level inspection doesn't reveal the bug: - -- **Python side hangs or misbehaves:** use the `python-debugpy` skill to break inside `_SlashWorker.exec` or the command handler. `remote-pdb` set at the handler entry is the fastest path. -- **Ink side not reacting:** use the `node-inspect-debugger` skill to break in `app.tsx`'s slash dispatch or the local command branch. `sb('dist/app.js', <line>)` after `npm run build`. -- **Registry mismatch / unclear which side is wrong:** compare the canonical `COMMAND_REGISTRY` entry against the TUI's local command list side-by-side. - -## Pitfalls - -- Don't forget to set the appropriate category for the command in `CommandDef` (e.g., "Session", "Configuration", "Tools & Skills", "Info", "Exit") -- Make sure any aliases are properly registered in the `aliases` tuple — no other file changes are needed, everything downstream (Telegram menu, Slack mapping, autocomplete, help) derives from it -- For commands with subcommands, ensure the `subcommands` tuple in `CommandDef` matches what's in the TUI code -- `cli_only=True` commands won't work in gateway/messaging platforms — unless you add a `gateway_config_gate` and the gate is truthy -- After adding live UI state, search every consumer of the old prop/helper and thread the new state through all render paths, not just the active streaming path. TUI detail rendering has at least two important paths: live `StreamingAssistant`/`ToolTrail` and transcript/pending `MessageLine` rows. A `/clean` pass should explicitly check both. -- Rebuild the TUI (`npm --prefix ui-tui run build`) before testing — tsx watch mode may lag on first launch - -## Verification - -After fixing: - -1. Rebuild the TUI: - ```bash - cd /home/bb/hermes-agent && npm --prefix ui-tui run build - ``` - -2. Run the TUI and test the command: - ```bash - hermes --tui - ``` - -3. Type `/` and verify the command appears in autocomplete suggestions with the expected description and args hint. - -4. Execute the command and confirm: - - Expected behavior fires - - Any persisted config updates correctly (`read_file ~/.hermes/config.yaml`) - - Live UI state reflects the change immediately (not just after restart) - -5. If the command is also gateway-available, test it from at least one messaging platform (or run the gateway tests: `scripts/run_tests.sh tests/gateway/`). diff --git a/skills/software-development/hermes-agent-skill-authoring/SKILL.md b/skills/software-development/hermes-agent-skill-authoring/SKILL.md index 3ab3644dc..2c345355f 100644 --- a/skills/software-development/hermes-agent-skill-authoring/SKILL.md +++ b/skills/software-development/hermes-agent-skill-authoring/SKILL.md @@ -8,7 +8,7 @@ platforms: [linux, macos, windows] metadata: hermes: tags: [skills, authoring, hermes-agent, conventions, skill-md] - related_skills: [writing-plans, requesting-code-review] + related_skills: [plan, requesting-code-review] --- # Authoring Hermes-Agent Skills (in-repo) diff --git a/skills/software-development/plan/SKILL.md b/skills/software-development/plan/SKILL.md index dcfba8e22..10a5ae420 100644 --- a/skills/software-development/plan/SKILL.md +++ b/skills/software-development/plan/SKILL.md @@ -1,14 +1,14 @@ --- name: plan -description: "Plan mode: write markdown plan to .hermes/plans/, no exec." -version: 1.0.0 -author: Hermes Agent +description: "Plan mode: write an actionable markdown plan to .hermes/plans/, no execution. Bite-sized tasks, exact paths, complete code." +version: 2.0.0 +author: Hermes Agent (writing-craft adapted from obra/superpowers) license: MIT platforms: [linux, macos, windows] metadata: hermes: - tags: [planning, plan-mode, implementation, workflow] - related_skills: [writing-plans, subagent-driven-development] + tags: [planning, plan-mode, implementation, workflow, design, documentation] + related_skills: [subagent-driven-development, test-driven-development, requesting-code-review] --- # Plan Mode @@ -56,3 +56,283 @@ If not, create a sensible timestamped filename yourself under `.hermes/plans/`. - If no explicit instruction accompanies `/plan`, infer the task from the current conversation context. - If it is genuinely underspecified, ask a brief clarifying question instead of guessing. - After saving the plan, reply briefly with what you planned and the saved path. + +--- + +# Writing the Plan Well + +The rest of this skill is the craft of authoring a *good* implementation plan — the content that goes inside the markdown file above. + +## Overview + +Write comprehensive implementation plans assuming the implementer has zero context for the codebase and questionable taste. Document everything they need: which files to touch, complete code, testing commands, docs to check, how to verify. Give them bite-sized tasks. DRY. YAGNI. TDD. Frequent commits. + +Assume the implementer is a skilled developer but knows almost nothing about the toolset or problem domain. Assume they don't know good test design very well. + +**Core principle:** A good plan makes implementation obvious. If someone has to guess, the plan is incomplete. + +## When a Full Implementation Plan Helps + +**Always use before:** +- Implementing multi-step features +- Breaking down complex requirements +- Delegating to subagents via subagent-driven-development + +**Don't skip when:** +- Feature seems simple (assumptions cause bugs) +- You plan to implement it yourself (future you needs guidance) +- Working alone (documentation matters) + +## Bite-Sized Task Granularity + +**Each task = 2-5 minutes of focused work.** + +Every step is one action: +- "Write the failing test" — step +- "Run it to make sure it fails" — step +- "Implement the minimal code to make the test pass" — step +- "Run the tests and make sure they pass" — step +- "Commit" — step + +**Too big:** +```markdown +### Task 1: Build authentication system +[50 lines of code across 5 files] +``` + +**Right size:** +```markdown +### Task 1: Create User model with email field +[10 lines, 1 file] + +### Task 2: Add password hash field to User +[8 lines, 1 file] + +### Task 3: Create password hashing utility +[15 lines, 1 file] +``` + +## Plan Document Structure + +### Header (Required) + +Every plan MUST start with: + +```markdown +# [Feature Name] Implementation Plan + +> **For Hermes:** Use subagent-driven-development skill to implement this plan task-by-task. + +**Goal:** [One sentence describing what this builds] + +**Architecture:** [2-3 sentences about approach] + +**Tech Stack:** [Key technologies/libraries] + +--- +``` + +### Task Structure + +Each task follows this format: + +````markdown +### Task N: [Descriptive Name] + +**Objective:** What this task accomplishes (one sentence) + +**Files:** +- Create: `exact/path/to/new_file.py` +- Modify: `exact/path/to/existing.py:45-67` (line numbers if known) +- Test: `tests/path/to/test_file.py` + +**Step 1: Write failing test** + +```python +def test_specific_behavior(): + result = function(input) + assert result == expected +``` + +**Step 2: Run test to verify failure** + +Run: `pytest tests/path/test.py::test_specific_behavior -v` +Expected: FAIL — "function not defined" + +**Step 3: Write minimal implementation** + +```python +def function(input): + return expected +``` + +**Step 4: Run test to verify pass** + +Run: `pytest tests/path/test.py::test_specific_behavior -v` +Expected: PASS + +**Step 5: Commit** + +```bash +git add tests/path/test.py src/path/file.py +git commit -m "feat: add specific feature" +``` +```` + +## Writing Process + +### Step 1: Understand Requirements + +Read and understand: +- Feature requirements +- Design documents or user description +- Acceptance criteria +- Constraints + +### Step 2: Explore the Codebase + +Use Hermes tools to understand the project: + +```python +# Understand project structure +search_files("*.py", target="files", path="src/") + +# Look at similar features +search_files("similar_pattern", path="src/", file_glob="*.py") + +# Check existing tests +search_files("*.py", target="files", path="tests/") + +# Read key files +read_file("src/app.py") +``` + +### Step 3: Design Approach + +Decide: +- Architecture pattern +- File organization +- Dependencies needed +- Testing strategy + +### Step 4: Write Tasks + +Create tasks in order: +1. Setup/infrastructure +2. Core functionality (TDD for each) +3. Edge cases +4. Integration +5. Cleanup/documentation + +### Step 5: Add Complete Details + +For each task, include: +- **Exact file paths** (not "the config file" but `src/config/settings.py`) +- **Complete code examples** (not "add validation" but the actual code) +- **Exact commands** with expected output +- **Verification steps** that prove the task works + +### Step 6: Review the Plan + +Check: +- [ ] Tasks are sequential and logical +- [ ] Each task is bite-sized (2-5 min) +- [ ] File paths are exact +- [ ] Code examples are complete (copy-pasteable) +- [ ] Commands are exact with expected output +- [ ] No missing context +- [ ] DRY, YAGNI, TDD principles applied + +## Principles + +### DRY (Don't Repeat Yourself) + +**Bad:** Copy-paste validation in 3 places +**Good:** Extract validation function, use everywhere + +### YAGNI (You Aren't Gonna Need It) + +**Bad:** Add "flexibility" for future requirements +**Good:** Implement only what's needed now + +```python +# Bad — YAGNI violation +class User: + def __init__(self, name, email): + self.name = name + self.email = email + self.preferences = {} # Not needed yet! + self.metadata = {} # Not needed yet! + +# Good — YAGNI +class User: + def __init__(self, name, email): + self.name = name + self.email = email +``` + +### TDD (Test-Driven Development) + +Every task that produces code should include the full TDD cycle: +1. Write failing test +2. Run to verify failure +3. Write minimal code +4. Run to verify pass + +See `test-driven-development` skill for details. + +### Frequent Commits + +Commit after every task: +```bash +git add [files] +git commit -m "type: description" +``` + +## Common Mistakes + +### Vague Tasks + +**Bad:** "Add authentication" +**Good:** "Create User model with email and password_hash fields" + +### Incomplete Code + +**Bad:** "Step 1: Add validation function" +**Good:** "Step 1: Add validation function" followed by the complete function code + +### Missing Verification + +**Bad:** "Step 3: Test it works" +**Good:** "Step 3: Run `pytest tests/test_auth.py -v`, expected: 3 passed" + +### Missing File Paths + +**Bad:** "Create the model file" +**Good:** "Create: `src/models/user.py`" + +## Execution Handoff + +After saving the plan, offer the execution approach: + +**"Plan complete and saved. Ready to execute using subagent-driven-development — I'll dispatch a fresh subagent per task with two-stage review (spec compliance then code quality). Shall I proceed?"** + +When executing, use the `subagent-driven-development` skill: +- Fresh `delegate_task` per task with full context +- Spec compliance review after each task +- Code quality review after spec passes +- Proceed only when both reviews approve + +## Remember + +``` +Bite-sized tasks (2-5 min each) +Exact file paths +Complete code (copy-pasteable) +Exact commands with expected output +Verification steps +DRY, YAGNI, TDD +Frequent commits +``` + +**A good plan makes implementation obvious.** diff --git a/skills/software-development/requesting-code-review/SKILL.md b/skills/software-development/requesting-code-review/SKILL.md index 4a2ba70bf..ad861e9ff 100644 --- a/skills/software-development/requesting-code-review/SKILL.md +++ b/skills/software-development/requesting-code-review/SKILL.md @@ -8,7 +8,7 @@ platforms: [linux, macos, windows] metadata: hermes: tags: [code-review, security, verification, quality, pre-commit, auto-fix] - related_skills: [subagent-driven-development, writing-plans, test-driven-development, github-code-review] + related_skills: [subagent-driven-development, plan, test-driven-development, github-code-review] --- # Pre-Commit Code Verification @@ -266,7 +266,7 @@ The two-stage review (spec compliance + code quality) uses this pipeline. **test-driven-development:** This pipeline verifies TDD discipline was followed — tests exist, tests pass, no regressions. -**writing-plans:** Validates implementation matches the plan requirements. +**plan:** Validates implementation matches the plan requirements. ## Pitfalls diff --git a/skills/software-development/spike/SKILL.md b/skills/software-development/spike/SKILL.md index 93eb15d8e..2a980f0ad 100644 --- a/skills/software-development/spike/SKILL.md +++ b/skills/software-development/spike/SKILL.md @@ -8,7 +8,7 @@ platforms: [linux, macos, windows] metadata: hermes: tags: [spike, prototype, experiment, feasibility, throwaway, exploration, research, planning, mvp, proof-of-concept] - related_skills: [sketch, writing-plans, subagent-driven-development, plan] + related_skills: [sketch, subagent-driven-development, plan] --- # Spike @@ -20,7 +20,7 @@ Load this when the user says things like "let me try this", "I want to see if X ## When NOT to use this - The answer is knowable from docs or reading code — just do research, don't build -- The work is production path — use `writing-plans` / `plan` instead +- The work is production path — use the `plan` skill instead - The idea is already validated — jump straight to implementation ## If the user has the full GSD system installed diff --git a/skills/software-development/systematic-debugging/SKILL.md b/skills/software-development/systematic-debugging/SKILL.md index 635fde794..7ecad2232 100644 --- a/skills/software-development/systematic-debugging/SKILL.md +++ b/skills/software-development/systematic-debugging/SKILL.md @@ -8,7 +8,7 @@ platforms: [linux, macos, windows] metadata: hermes: tags: [debugging, troubleshooting, problem-solving, root-cause, investigation] - related_skills: [test-driven-development, writing-plans, subagent-driven-development] + related_skills: [test-driven-development, plan, subagent-driven-development] --- # Systematic Debugging diff --git a/skills/software-development/test-driven-development/SKILL.md b/skills/software-development/test-driven-development/SKILL.md index 1ae1195e9..8484c69bc 100644 --- a/skills/software-development/test-driven-development/SKILL.md +++ b/skills/software-development/test-driven-development/SKILL.md @@ -8,7 +8,7 @@ platforms: [linux, macos, windows] metadata: hermes: tags: [testing, tdd, development, quality, red-green-refactor] - related_skills: [systematic-debugging, writing-plans, subagent-driven-development] + related_skills: [systematic-debugging, plan, subagent-driven-development] --- # Test-Driven Development (TDD) diff --git a/skills/software-development/writing-plans/SKILL.md b/skills/software-development/writing-plans/SKILL.md deleted file mode 100644 index abb321dd8..000000000 --- a/skills/software-development/writing-plans/SKILL.md +++ /dev/null @@ -1,297 +0,0 @@ ---- -name: writing-plans -description: "Write implementation plans: bite-sized tasks, paths, code." -version: 1.1.0 -author: Hermes Agent (adapted from obra/superpowers) -license: MIT -platforms: [linux, macos, windows] -metadata: - hermes: - tags: [planning, design, implementation, workflow, documentation] - related_skills: [subagent-driven-development, test-driven-development, requesting-code-review] ---- - -# Writing Implementation Plans - -## Overview - -Write comprehensive implementation plans assuming the implementer has zero context for the codebase and questionable taste. Document everything they need: which files to touch, complete code, testing commands, docs to check, how to verify. Give them bite-sized tasks. DRY. YAGNI. TDD. Frequent commits. - -Assume the implementer is a skilled developer but knows almost nothing about the toolset or problem domain. Assume they don't know good test design very well. - -**Core principle:** A good plan makes implementation obvious. If someone has to guess, the plan is incomplete. - -## When to Use - -**Always use before:** -- Implementing multi-step features -- Breaking down complex requirements -- Delegating to subagents via subagent-driven-development - -**Don't skip when:** -- Feature seems simple (assumptions cause bugs) -- You plan to implement it yourself (future you needs guidance) -- Working alone (documentation matters) - -## Bite-Sized Task Granularity - -**Each task = 2-5 minutes of focused work.** - -Every step is one action: -- "Write the failing test" — step -- "Run it to make sure it fails" — step -- "Implement the minimal code to make the test pass" — step -- "Run the tests and make sure they pass" — step -- "Commit" — step - -**Too big:** -```markdown -### Task 1: Build authentication system -[50 lines of code across 5 files] -``` - -**Right size:** -```markdown -### Task 1: Create User model with email field -[10 lines, 1 file] - -### Task 2: Add password hash field to User -[8 lines, 1 file] - -### Task 3: Create password hashing utility -[15 lines, 1 file] -``` - -## Plan Document Structure - -### Header (Required) - -Every plan MUST start with: - -```markdown -# [Feature Name] Implementation Plan - -> **For Hermes:** Use subagent-driven-development skill to implement this plan task-by-task. - -**Goal:** [One sentence describing what this builds] - -**Architecture:** [2-3 sentences about approach] - -**Tech Stack:** [Key technologies/libraries] - ---- -``` - -### Task Structure - -Each task follows this format: - -````markdown -### Task N: [Descriptive Name] - -**Objective:** What this task accomplishes (one sentence) - -**Files:** -- Create: `exact/path/to/new_file.py` -- Modify: `exact/path/to/existing.py:45-67` (line numbers if known) -- Test: `tests/path/to/test_file.py` - -**Step 1: Write failing test** - -```python -def test_specific_behavior(): - result = function(input) - assert result == expected -``` - -**Step 2: Run test to verify failure** - -Run: `pytest tests/path/test.py::test_specific_behavior -v` -Expected: FAIL — "function not defined" - -**Step 3: Write minimal implementation** - -```python -def function(input): - return expected -``` - -**Step 4: Run test to verify pass** - -Run: `pytest tests/path/test.py::test_specific_behavior -v` -Expected: PASS - -**Step 5: Commit** - -```bash -git add tests/path/test.py src/path/file.py -git commit -m "feat: add specific feature" -``` -```` - -## Writing Process - -### Step 1: Understand Requirements - -Read and understand: -- Feature requirements -- Design documents or user description -- Acceptance criteria -- Constraints - -### Step 2: Explore the Codebase - -Use Hermes tools to understand the project: - -```python -# Understand project structure -search_files("*.py", target="files", path="src/") - -# Look at similar features -search_files("similar_pattern", path="src/", file_glob="*.py") - -# Check existing tests -search_files("*.py", target="files", path="tests/") - -# Read key files -read_file("src/app.py") -``` - -### Step 3: Design Approach - -Decide: -- Architecture pattern -- File organization -- Dependencies needed -- Testing strategy - -### Step 4: Write Tasks - -Create tasks in order: -1. Setup/infrastructure -2. Core functionality (TDD for each) -3. Edge cases -4. Integration -5. Cleanup/documentation - -### Step 5: Add Complete Details - -For each task, include: -- **Exact file paths** (not "the config file" but `src/config/settings.py`) -- **Complete code examples** (not "add validation" but the actual code) -- **Exact commands** with expected output -- **Verification steps** that prove the task works - -### Step 6: Review the Plan - -Check: -- [ ] Tasks are sequential and logical -- [ ] Each task is bite-sized (2-5 min) -- [ ] File paths are exact -- [ ] Code examples are complete (copy-pasteable) -- [ ] Commands are exact with expected output -- [ ] No missing context -- [ ] DRY, YAGNI, TDD principles applied - -### Step 7: Save the Plan - -```bash -mkdir -p docs/plans -# Save plan to docs/plans/YYYY-MM-DD-feature-name.md -git add docs/plans/ -git commit -m "docs: add implementation plan for [feature]" -``` - -## Principles - -### DRY (Don't Repeat Yourself) - -**Bad:** Copy-paste validation in 3 places -**Good:** Extract validation function, use everywhere - -### YAGNI (You Aren't Gonna Need It) - -**Bad:** Add "flexibility" for future requirements -**Good:** Implement only what's needed now - -```python -# Bad — YAGNI violation -class User: - def __init__(self, name, email): - self.name = name - self.email = email - self.preferences = {} # Not needed yet! - self.metadata = {} # Not needed yet! - -# Good — YAGNI -class User: - def __init__(self, name, email): - self.name = name - self.email = email -``` - -### TDD (Test-Driven Development) - -Every task that produces code should include the full TDD cycle: -1. Write failing test -2. Run to verify failure -3. Write minimal code -4. Run to verify pass - -See `test-driven-development` skill for details. - -### Frequent Commits - -Commit after every task: -```bash -git add [files] -git commit -m "type: description" -``` - -## Common Mistakes - -### Vague Tasks - -**Bad:** "Add authentication" -**Good:** "Create User model with email and password_hash fields" - -### Incomplete Code - -**Bad:** "Step 1: Add validation function" -**Good:** "Step 1: Add validation function" followed by the complete function code - -### Missing Verification - -**Bad:** "Step 3: Test it works" -**Good:** "Step 3: Run `pytest tests/test_auth.py -v`, expected: 3 passed" - -### Missing File Paths - -**Bad:** "Create the model file" -**Good:** "Create: `src/models/user.py`" - -## Execution Handoff - -After saving the plan, offer the execution approach: - -**"Plan complete and saved. Ready to execute using subagent-driven-development — I'll dispatch a fresh subagent per task with two-stage review (spec compliance then code quality). Shall I proceed?"** - -When executing, use the `subagent-driven-development` skill: -- Fresh `delegate_task` per task with full context -- Spec compliance review after each task -- Code quality review after spec passes -- Proceed only when both reviews approve - -## Remember - -``` -Bite-sized tasks (2-5 min each) -Exact file paths -Complete code (copy-pasteable) -Exact commands with expected output -Verification steps -DRY, YAGNI, TDD -Frequent commits -``` - -**A good plan makes implementation obvious.** diff --git a/tests/tools/test_kanban_codex_lane_skill.py b/tests/tools/test_kanban_codex_lane_skill.py deleted file mode 100644 index 8aada2582..000000000 --- a/tests/tools/test_kanban_codex_lane_skill.py +++ /dev/null @@ -1,98 +0,0 @@ -"""Regression coverage for the bundled Kanban Codex lane skill.""" - -import json -from pathlib import Path - -from tools import skills_tool -from tools.skill_manager_tool import _validate_frontmatter - - -REPO_ROOT = Path(__file__).resolve().parents[2] -SKILL_DIR = REPO_ROOT / "skills" / "autonomous-ai-agents" / "kanban-codex-lane" -SKILL_MD = SKILL_DIR / "SKILL.md" -TEMPLATE = SKILL_DIR / "templates" / "pmb-codex-lane-prompt.md" - - -def _skill_text() -> str: - return SKILL_MD.read_text(encoding="utf-8") - - -def test_kanban_codex_lane_skill_frontmatter_is_valid(): - content = _skill_text() - - assert _validate_frontmatter(content) is None - assert "name: kanban-codex-lane" in content - assert "description: Use when" in content - - -def test_kanban_codex_lane_skill_is_discoverable_with_template(monkeypatch, tmp_path): - local_skills = tmp_path / "skills" - local_skills.mkdir() - bundled_skills = REPO_ROOT / "skills" - - monkeypatch.setattr(skills_tool, "SKILLS_DIR", local_skills) - monkeypatch.setattr( - "agent.skill_utils.get_external_skills_dirs", - lambda: [bundled_skills], - ) - - listed = json.loads(skills_tool.skills_list("autonomous-ai-agents")) - assert listed["success"] is True - assert any(skill["name"] == "kanban-codex-lane" for skill in listed["skills"]) - - viewed = json.loads(skills_tool.skill_view("kanban-codex-lane")) - assert viewed["success"] is True - assert viewed["path"].endswith("kanban-codex-lane/SKILL.md") - assert viewed["linked_files"]["templates"] == ["templates/pmb-codex-lane-prompt.md"] - - template = json.loads( - skills_tool.skill_view( - "kanban-codex-lane", - file_path="templates/pmb-codex-lane-prompt.md", - ) - ) - assert template["success"] is True - assert "PMB safety constraints" in template["content"] - - -def test_kanban_codex_lane_documents_required_contracts(): - content = _skill_text() - template = TEMPLATE.read_text(encoding="utf-8") - - required_skill_phrases = [ - "Hermes is always the task owner", - "Codex is an input lane only", - "git -C \"$REPO\" worktree add -b \"$BRANCH\" \"$WORKTREE\" \"$BASE\"", - "codex --version", - "codex features list | grep -i goals || true", - "codex exec --full-auto", - "/goal Work in this repository only", - "process(action=\"kill\", session_id=session_id)", - "scripts/run_tests.sh", - '"codex_lane"', - '"used"', - '"mode"', - '"worktree"', - '"branch"', - '"command"', - '"result"', - '"accepted_commits"', - '"rejected_reason"', - '"tests_run"', - '"artifacts"', - "accepted | rejected | partial | timed_out", - ] - for phrase in required_skill_phrases: - assert phrase in content - - required_safety_phrases = [ - "live-SIM is paper-only; do not add or enable live REST order entry", - "Never use market orders", - "Do not add execution crossing", - "Do not fake passive fills", - "Do not weaken risk gates", - "Do not read, print, write, or require secrets/tokens/credentials", - ] - for phrase in required_safety_phrases: - assert phrase in content - assert phrase in template diff --git a/tools/skills_tool.py b/tools/skills_tool.py index d771226f9..04bf35abe 100644 --- a/tools/skills_tool.py +++ b/tools/skills_tool.py @@ -159,6 +159,18 @@ def skill_matches_platform(frontmatter: Dict[str, Any]) -> bool: return _impl(frontmatter) +def skill_matches_environment(frontmatter: Dict[str, Any]) -> bool: + """Check if a skill is relevant to the current runtime environment. + + Delegates to ``agent.skill_utils.skill_matches_environment`` — kept here + as a public re-export so existing callers don't need updating. This is an + offer-time relevance gate (kanban/docker/s6), NOT a hard-compatibility gate; + explicit skill loads bypass it. + """ + from agent.skill_utils import skill_matches_environment as _impl + return _impl(frontmatter) + + def _normalize_prerequisite_values(value: Any) -> List[str]: if not value: return [] @@ -592,6 +604,9 @@ def _find_all_skills(*, skip_disabled: bool = False) -> List[Dict[str, Any]]: if not skill_matches_platform(frontmatter): continue + if not skill_matches_environment(frontmatter): + continue + name = frontmatter.get("name", skill_dir.name)[:MAX_NAME_LENGTH] if name in seen_names: continue diff --git a/website/docs/reference/optional-skills-catalog.md b/website/docs/reference/optional-skills-catalog.md index 6d5b7c8e6..fa012f7f0 100644 --- a/website/docs/reference/optional-skills-catalog.md +++ b/website/docs/reference/optional-skills-catalog.md @@ -55,11 +55,15 @@ hermes skills uninstall <skill-name> | Skill | Description | |-------|-------------| +| [**baoyu-article-illustrator**](/docs/user-guide/skills/optional/creative/creative-baoyu-article-illustrator) | Article illustrations: type × style × palette consistency. | +| [**baoyu-comic**](/docs/user-guide/skills/optional/creative/creative-baoyu-comic) | Knowledge comics (知识漫画): educational, biography, tutorial. | | [**blender-mcp**](/docs/user-guide/skills/optional/creative/creative-blender-mcp) | Control Blender directly from Hermes via socket connection to the blender-mcp addon. Create 3D objects, materials, animations, and run arbitrary Blender Python (bpy) code. Use when user wants to create or modify anything in Blender. | | [**concept-diagrams**](/docs/user-guide/skills/optional/creative/creative-concept-diagrams) | Generate flat, minimal light/dark-aware SVG diagrams as standalone HTML files, using a unified educational visual language with 9 semantic color ramps, sentence-case typography, and automatic dark mode. Best suited for educational and no... | +| [**ideation**](/docs/user-guide/skills/optional/creative/creative-creative-ideation) | Generate project ideas via creative constraints. | | [**hyperframes**](/docs/user-guide/skills/optional/creative/creative-hyperframes) | Create HTML-based video compositions, animated title cards, social overlays, captioned talking-head videos, audio-reactive visuals, and shader transitions using HyperFrames. HTML is the source of truth for video. Use when the user wants... | | [**kanban-video-orchestrator**](/docs/user-guide/skills/optional/creative/creative-kanban-video-orchestrator) | Plan, set up, and monitor a multi-agent video production pipeline backed by Hermes Kanban. Use when the user wants to make ANY video — narrative film, product/marketing, music video, explainer, ASCII/terminal art, abstract/generative loo... | | [**meme-generation**](/docs/user-guide/skills/optional/creative/creative-meme-generation) | Generate real meme images by picking a template and overlaying text with Pillow. Produces actual .png meme files. | +| [**pixel-art**](/docs/user-guide/skills/optional/creative/creative-pixel-art) | Pixel art w/ era palettes (NES, Game Boy, PICO-8). | ## devops @@ -67,6 +71,7 @@ hermes skills uninstall <skill-name> |-------|-------------| | [**inference-sh-cli**](/docs/user-guide/skills/optional/devops/devops-cli) | Run 150+ AI apps via inference.sh CLI (infsh) — image generation, video creation, LLMs, search, 3D, social automation. Uses the terminal tool. Triggers: inference.sh, infsh, ai apps, flux, veo, image generation, video generation, seedrea... | | [**docker-management**](/docs/user-guide/skills/optional/devops/devops-docker-management) | Manage Docker containers, images, volumes, networks, and Compose stacks — lifecycle ops, debugging, cleanup, and Dockerfile optimization. | +| [**hermes-s6-container-supervision**](/docs/user-guide/skills/optional/devops/devops-hermes-s6-container-supervision) | Modify, debug, or extend the s6-overlay supervision tree inside the Hermes Agent Docker image — adding new services, debugging profile gateways, understanding the Architecture B main-program pattern. | | [**pinggy-tunnel**](/docs/user-guide/skills/optional/devops/devops-pinggy-tunnel) | Zero-install localhost tunnels over SSH via Pinggy. | | [**watchers**](/docs/user-guide/skills/optional/devops/devops-watchers) | Poll RSS, JSON APIs, and GitHub with watermark dedup. | @@ -95,6 +100,13 @@ hermes skills uninstall <skill-name> | [**pptx-author**](/docs/user-guide/skills/optional/finance/finance-pptx-author) | Build PowerPoint decks headless with python-pptx. Pairs with excel-author for model-backed decks where every number traces to a workbook cell. Use for pitch decks, IC memos, earnings notes. | | [**stocks**](/docs/user-guide/skills/optional/finance/finance-stocks) | Stock quotes, history, search, compare, crypto via Yahoo. | +## gaming + +| Skill | Description | +|-------|-------------| +| [**minecraft-modpack-server**](/docs/user-guide/skills/optional/gaming/gaming-minecraft-modpack-server) | Host modded Minecraft servers (CurseForge, Modrinth). | +| [**pokemon-player**](/docs/user-guide/skills/optional/gaming/gaming-pokemon-player) | Play Pokemon via headless emulator + RAM reads. | + ## health | Skill | Description | @@ -123,6 +135,7 @@ hermes skills uninstall <skill-name> | [**axolotl**](/docs/user-guide/skills/optional/mlops/mlops-training-axolotl) | Axolotl: YAML LLM fine-tuning (LoRA, DPO, GRPO). | | [**chroma**](/docs/user-guide/skills/optional/mlops/mlops-chroma) | Open-source embedding database for AI applications. Store embeddings and metadata, perform vector and full-text search, filter by metadata. Simple 4-function API. Scales from notebooks to production clusters. Use for semantic search, RAG... | | [**clip**](/docs/user-guide/skills/optional/mlops/mlops-clip) | OpenAI's model connecting vision and language. Enables zero-shot image classification, image-text matching, and cross-modal retrieval. Trained on 400M image-text pairs. Use for image search, content moderation, or vision-language tasks w... | +| [**dspy**](/docs/user-guide/skills/optional/mlops/mlops-research-dspy) | DSPy: declarative LM programs, auto-optimize prompts, RAG. | | [**faiss**](/docs/user-guide/skills/optional/mlops/mlops-faiss) | Facebook's library for efficient similarity search and clustering of dense vectors. Supports billions of vectors, GPU acceleration, and various index types (Flat, IVF, HNSW). Use for fast k-NN search, large-scale vector retrieval, or whe... | | [**optimizing-attention-flash**](/docs/user-guide/skills/optional/mlops/mlops-flash-attention) | Optimizes transformer attention with Flash Attention for 2-4x speedup and 10-20x memory reduction. Use when training/running transformers with long sequences (>512 tokens), encountering GPU memory issues with attention, or need faster in... | | [**guidance**](/docs/user-guide/skills/optional/mlops/mlops-guidance) | Control LLM output with regex and grammars, guarantee valid JSON/XML/code generation, enforce structured formats, and build multi-step workflows with Guidance - Microsoft Research's constrained generation framework | @@ -191,6 +204,7 @@ hermes skills uninstall <skill-name> |-------|-------------| | [**code-wiki**](/docs/user-guide/skills/optional/software-development/software-development-code-wiki) | Generate wiki docs + Mermaid diagrams for any codebase. | | [**rest-graphql-debug**](/docs/user-guide/skills/optional/software-development/software-development-rest-graphql-debug) | Debug REST/GraphQL APIs: status codes, auth, schemas, repro. | +| [**subagent-driven-development**](/docs/user-guide/skills/optional/software-development/software-development-subagent-driven-development) | Execute plans via delegate_task subagents (2-stage review). | ## web-development diff --git a/website/docs/reference/skills-catalog.md b/website/docs/reference/skills-catalog.md index 5382a4b35..0ecf856cf 100644 --- a/website/docs/reference/skills-catalog.md +++ b/website/docs/reference/skills-catalog.md @@ -29,7 +29,6 @@ If a skill is missing from this list but present in the repo, the catalog is reg | [`claude-code`](/docs/user-guide/skills/bundled/autonomous-ai-agents/autonomous-ai-agents-claude-code) | Delegate coding to Claude Code CLI (features, PRs). | `autonomous-ai-agents/claude-code` | | [`codex`](/docs/user-guide/skills/bundled/autonomous-ai-agents/autonomous-ai-agents-codex) | Delegate coding to OpenAI Codex CLI (features, PRs). | `autonomous-ai-agents/codex` | | [`hermes-agent`](/docs/user-guide/skills/bundled/autonomous-ai-agents/autonomous-ai-agents-hermes-agent) | Configure, extend, or contribute to Hermes Agent. | `autonomous-ai-agents/hermes-agent` | -| [`kanban-codex-lane`](/docs/user-guide/skills/bundled/autonomous-ai-agents/autonomous-ai-agents-kanban-codex-lane) | Use when a Hermes Kanban worker wants to run Codex CLI as an isolated implementation lane while Hermes keeps ownership of task lifecycle, reconciliation, testing, and handoff. | `autonomous-ai-agents/kanban-codex-lane` | | [`opencode`](/docs/user-guide/skills/bundled/autonomous-ai-agents/autonomous-ai-agents-opencode) | Delegate coding to OpenCode CLI (features, PR review). | `autonomous-ai-agents/opencode` | ## creative @@ -39,18 +38,14 @@ If a skill is missing from this list but present in the repo, the catalog is reg | [`architecture-diagram`](/docs/user-guide/skills/bundled/creative/creative-architecture-diagram) | Dark-themed SVG architecture/cloud/infra diagrams as HTML. | `creative/architecture-diagram` | | [`ascii-art`](/docs/user-guide/skills/bundled/creative/creative-ascii-art) | ASCII art: pyfiglet, cowsay, boxes, image-to-ascii. | `creative/ascii-art` | | [`ascii-video`](/docs/user-guide/skills/bundled/creative/creative-ascii-video) | ASCII video: convert video/audio to colored ASCII MP4/GIF. | `creative/ascii-video` | -| [`baoyu-article-illustrator`](/docs/user-guide/skills/bundled/creative/creative-baoyu-article-illustrator) | Article illustrations: type × style × palette consistency. | `creative/baoyu-article-illustrator` | -| [`baoyu-comic`](/docs/user-guide/skills/bundled/creative/creative-baoyu-comic) | Knowledge comics (知识漫画): educational, biography, tutorial. | `creative/baoyu-comic` | | [`baoyu-infographic`](/docs/user-guide/skills/bundled/creative/creative-baoyu-infographic) | Infographics: 21 layouts x 21 styles (信息图, 可视化). | `creative/baoyu-infographic` | | [`claude-design`](/docs/user-guide/skills/bundled/creative/creative-claude-design) | Design one-off HTML artifacts (landing, deck, prototype). | `creative/claude-design` | | [`comfyui`](/docs/user-guide/skills/bundled/creative/creative-comfyui) | 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. | `creative/comfyui` | -| [`ideation`](/docs/user-guide/skills/bundled/creative/creative-creative-ideation) | Generate project ideas via creative constraints. | `creative/creative-ideation` | | [`design-md`](/docs/user-guide/skills/bundled/creative/creative-design-md) | Author/validate/export Google's DESIGN.md token spec files. | `creative/design-md` | | [`excalidraw`](/docs/user-guide/skills/bundled/creative/creative-excalidraw) | Hand-drawn Excalidraw JSON diagrams (arch, flow, seq). | `creative/excalidraw` | | [`humanizer`](/docs/user-guide/skills/bundled/creative/creative-humanizer) | Humanize text: strip AI-isms and add real voice. | `creative/humanizer` | | [`manim-video`](/docs/user-guide/skills/bundled/creative/creative-manim-video) | Manim CE animations: 3Blue1Brown math/algo videos. | `creative/manim-video` | | [`p5js`](/docs/user-guide/skills/bundled/creative/creative-p5js) | p5.js sketches: gen art, shaders, interactive, 3D. | `creative/p5js` | -| [`pixel-art`](/docs/user-guide/skills/bundled/creative/creative-pixel-art) | Pixel art w/ era palettes (NES, Game Boy, PICO-8). | `creative/pixel-art` | | [`popular-web-designs`](/docs/user-guide/skills/bundled/creative/creative-popular-web-designs) | 54 real design systems (Stripe, Linear, Vercel) as HTML/CSS. | `creative/popular-web-designs` | | [`pretext`](/docs/user-guide/skills/bundled/creative/creative-pretext) | 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 HT... | `creative/pretext` | | [`sketch`](/docs/user-guide/skills/bundled/creative/creative-sketch) | Throwaway HTML mockups: 2-3 design variants to compare. | `creative/sketch` | @@ -69,7 +64,6 @@ If a skill is missing from this list but present in the repo, the catalog is reg |-------|-------------|------| | [`kanban-orchestrator`](/docs/user-guide/skills/bundled/devops/devops-kanban-orchestrator) | 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... | `devops/kanban-orchestrator` | | [`kanban-worker`](/docs/user-guide/skills/bundled/devops/devops-kanban-worker) | 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 det... | `devops/kanban-worker` | -| [`webhook-subscriptions`](/docs/user-guide/skills/bundled/devops/devops-webhook-subscriptions) | Webhook subscriptions: event-driven agent runs. | `devops/webhook-subscriptions` | ## dogfood @@ -83,13 +77,6 @@ If a skill is missing from this list but present in the repo, the catalog is reg |-------|-------------|------| | [`himalaya`](/docs/user-guide/skills/bundled/email/email-himalaya) | Himalaya CLI: IMAP/SMTP email from terminal. | `email/himalaya` | -## gaming - -| Skill | Description | Path | -|-------|-------------|------| -| [`minecraft-modpack-server`](/docs/user-guide/skills/bundled/gaming/gaming-minecraft-modpack-server) | Host modded Minecraft servers (CurseForge, Modrinth). | `gaming/minecraft-modpack-server` | -| [`pokemon-player`](/docs/user-guide/skills/bundled/gaming/gaming-pokemon-player) | Play Pokemon via headless emulator + RAM reads. | `gaming/pokemon-player` | - ## github | Skill | Description | Path | @@ -101,12 +88,6 @@ If a skill is missing from this list but present in the repo, the catalog is reg | [`github-pr-workflow`](/docs/user-guide/skills/bundled/github/github-github-pr-workflow) | GitHub PR lifecycle: branch, commit, open, CI, merge. | `github/github-pr-workflow` | | [`github-repo-management`](/docs/user-guide/skills/bundled/github/github-github-repo-management) | Clone/create/fork repos; manage remotes, releases. | `github/github-repo-management` | -## mcp - -| Skill | Description | Path | -|-------|-------------|------| -| [`native-mcp`](/docs/user-guide/skills/bundled/mcp/mcp-native-mcp) | MCP client: connect servers, register tools (stdio/HTTP). | `mcp/native-mcp` | - ## media | Skill | Description | Path | @@ -114,7 +95,6 @@ If a skill is missing from this list but present in the repo, the catalog is reg | [`gif-search`](/docs/user-guide/skills/bundled/media/media-gif-search) | Search/download GIFs from Tenor via curl + jq. | `media/gif-search` | | [`heartmula`](/docs/user-guide/skills/bundled/media/media-heartmula) | HeartMuLa: Suno-like song generation from lyrics + tags. | `media/heartmula` | | [`songsee`](/docs/user-guide/skills/bundled/media/media-songsee) | Audio spectrograms/features (mel, chroma, MFCC) via CLI. | `media/songsee` | -| [`spotify`](/docs/user-guide/skills/bundled/media/media-spotify) | Spotify: play, search, queue, manage playlists and devices. | `media/spotify` | | [`youtube-content`](/docs/user-guide/skills/bundled/media/media-youtube-content) | YouTube transcripts to summaries, threads, blogs. | `media/youtube-content` | ## mlops @@ -122,7 +102,6 @@ If a skill is missing from this list but present in the repo, the catalog is reg | Skill | Description | Path | |-------|-------------|------| | [`audiocraft-audio-generation`](/docs/user-guide/skills/bundled/mlops/mlops-models-audiocraft) | AudioCraft: MusicGen text-to-music, AudioGen text-to-sound. | `mlops/models/audiocraft` | -| [`dspy`](/docs/user-guide/skills/bundled/mlops/mlops-research-dspy) | DSPy: declarative LM programs, auto-optimize prompts, RAG. | `mlops/research/dspy` | | [`huggingface-hub`](/docs/user-guide/skills/bundled/mlops/mlops-huggingface-hub) | HuggingFace hf CLI: search/download/upload models, datasets. | `mlops/huggingface-hub` | | [`llama-cpp`](/docs/user-guide/skills/bundled/mlops/mlops-inference-llama-cpp) | llama.cpp local GGUF inference + HF Hub model discovery. | `mlops/inference/llama-cpp` | | [`evaluating-llms-harness`](/docs/user-guide/skills/bundled/mlops/mlops-evaluation-lm-evaluation-harness) | lm-eval-harness: benchmark LLMs (MMLU, GSM8K, etc.). | `mlops/evaluation/lm-evaluation-harness` | @@ -143,7 +122,6 @@ If a skill is missing from this list but present in the repo, the catalog is reg |-------|-------------|------| | [`airtable`](/docs/user-guide/skills/bundled/productivity/productivity-airtable) | Airtable REST API via curl. Records CRUD, filters, upserts. | `productivity/airtable` | | [`google-workspace`](/docs/user-guide/skills/bundled/productivity/productivity-google-workspace) | Gmail, Calendar, Drive, Docs, Sheets via gws CLI or Python. | `productivity/google-workspace` | -| [`linear`](/docs/user-guide/skills/bundled/productivity/productivity-linear) | Linear: manage issues, projects, teams via GraphQL + curl. | `productivity/linear` | | [`maps`](/docs/user-guide/skills/bundled/productivity/productivity-maps) | Geocode, POIs, routes, timezones via OpenStreetMap/OSRM. | `productivity/maps` | | [`nano-pdf`](/docs/user-guide/skills/bundled/productivity/productivity-nano-pdf) | Edit PDF text/typos/titles via nano-pdf CLI (NL prompts). | `productivity/nano-pdf` | | [`notion`](/docs/user-guide/skills/bundled/productivity/productivity-notion) | Notion API + ntn CLI: pages, databases, markdown, Workers. | `productivity/notion` | @@ -183,18 +161,14 @@ If a skill is missing from this list but present in the repo, the catalog is reg | Skill | Description | Path | |-------|-------------|------| -| [`debugging-hermes-tui-commands`](/docs/user-guide/skills/bundled/software-development/software-development-debugging-hermes-tui-commands) | Debug Hermes TUI slash commands: Python, gateway, Ink UI. | `software-development/debugging-hermes-tui-commands` | | [`hermes-agent-skill-authoring`](/docs/user-guide/skills/bundled/software-development/software-development-hermes-agent-skill-authoring) | Author in-repo SKILL.md: frontmatter, validator, structure. | `software-development/hermes-agent-skill-authoring` | -| [`hermes-s6-container-supervision`](/docs/user-guide/skills/bundled/software-development/software-development-hermes-s6-container-supervision) | Modify, debug, or extend the s6-overlay supervision tree inside the Hermes Agent Docker image — adding new services, debugging profile gateways, understanding the Architecture B main-program pattern. | `software-development/hermes-s6-container-supervision` | | [`node-inspect-debugger`](/docs/user-guide/skills/bundled/software-development/software-development-node-inspect-debugger) | Debug Node.js via --inspect + Chrome DevTools Protocol CLI. | `software-development/node-inspect-debugger` | -| [`plan`](/docs/user-guide/skills/bundled/software-development/software-development-plan) | Plan mode: write markdown plan to .hermes/plans/, no exec. | `software-development/plan` | +| [`plan`](/docs/user-guide/skills/bundled/software-development/software-development-plan) | Plan mode: write an actionable markdown plan to .hermes/plans/, no execution. Bite-sized tasks, exact paths, complete code. | `software-development/plan` | | [`python-debugpy`](/docs/user-guide/skills/bundled/software-development/software-development-python-debugpy) | Debug Python: pdb REPL + debugpy remote (DAP). | `software-development/python-debugpy` | | [`requesting-code-review`](/docs/user-guide/skills/bundled/software-development/software-development-requesting-code-review) | Pre-commit review: security scan, quality gates, auto-fix. | `software-development/requesting-code-review` | | [`spike`](/docs/user-guide/skills/bundled/software-development/software-development-spike) | Throwaway experiments to validate an idea before build. | `software-development/spike` | -| [`subagent-driven-development`](/docs/user-guide/skills/bundled/software-development/software-development-subagent-driven-development) | Execute plans via delegate_task subagents (2-stage review). | `software-development/subagent-driven-development` | | [`systematic-debugging`](/docs/user-guide/skills/bundled/software-development/software-development-systematic-debugging) | 4-phase root cause debugging: understand bugs before fixing. | `software-development/systematic-debugging` | | [`test-driven-development`](/docs/user-guide/skills/bundled/software-development/software-development-test-driven-development) | TDD: enforce RED-GREEN-REFACTOR, tests before code. | `software-development/test-driven-development` | -| [`writing-plans`](/docs/user-guide/skills/bundled/software-development/software-development-writing-plans) | Write implementation plans: bite-sized tasks, paths, code. | `software-development/writing-plans` | ## yuanbao diff --git a/website/docs/user-guide/skills/bundled/autonomous-ai-agents/autonomous-ai-agents-hermes-agent.md b/website/docs/user-guide/skills/bundled/autonomous-ai-agents/autonomous-ai-agents-hermes-agent.md index 57579e0f1..dc43372f1 100644 --- a/website/docs/user-guide/skills/bundled/autonomous-ai-agents/autonomous-ai-agents-hermes-agent.md +++ b/website/docs/user-guide/skills/bundled/autonomous-ai-agents/autonomous-ai-agents-hermes-agent.md @@ -157,6 +157,10 @@ hermes mcp test NAME Test connection hermes mcp configure NAME Toggle tool selection ``` +How the built-in MCP client connects servers (stdio/HTTP), auto-discovers +their tools, and exposes them as first-class tools, plus catalog install +(`hermes mcp install <name>`): `skill_view(name="hermes-agent", file_path="references/native-mcp.md")`. + ### Gateway (Messaging Platforms) ``` @@ -205,6 +209,9 @@ hermes webhook remove NAME Remove a subscription hermes webhook test NAME Send a test POST ``` +Full setup, route config, payload templating, and event-driven agent-run +patterns: `skill_view(name="hermes-agent", file_path="references/webhooks.md")`. + ### Profiles ``` diff --git a/website/docs/user-guide/skills/bundled/devops/devops-kanban-orchestrator.md b/website/docs/user-guide/skills/bundled/devops/devops-kanban-orchestrator.md index be60ff797..7e5c46c88 100644 --- a/website/docs/user-guide/skills/bundled/devops/devops-kanban-orchestrator.md +++ b/website/docs/user-guide/skills/bundled/devops/devops-kanban-orchestrator.md @@ -196,6 +196,30 @@ Tell them what you created in plain prose, naming the actual profiles you used: **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. +## Goal-mode cards (persistent workers) + +By default a dispatched worker gets **one shot** at its card: it does its work, calls `kanban_complete`/`kanban_block`, and exits. For open-ended cards where one turn rarely finishes the job, pass `goal_mode=True` to wrap that worker in a Ralph-style goal loop — the same engine behind the `/goal` slash command: + +```python +kanban_create( + title="Translate the full docs site to French", + body="Acceptance: every page translated, no English left, links intact.", + assignee="<translator-profile>", + goal_mode=True, # judge re-checks the card after each turn + goal_max_turns=15, # optional budget (default 20) +)["task_id"] +``` + +How it behaves: +- After each worker turn, an auxiliary judge evaluates the worker's response against the card's **title + body** (treated as the acceptance criteria). +- Not done + budget remains → the worker keeps going **in the same session** (full context retained — not a fresh respawn). +- Worker calls `kanban_complete`/`kanban_block` itself → loop stops, normal lifecycle. +- Budget exhausted without completion → the card is **blocked** for human review (sticky), never a silent exit. + +When to use it: long, multi-step, or "keep going until X is true" cards. When NOT to: cheap one-shot cards (translation of a single string, a quick lookup) — the judge overhead isn't worth it, and the dispatcher's existing retry/circuit-breaker already handles transient worker failures. + +Write the body as **explicit acceptance criteria** — the judge is only as good as the goal text. "Translate the README" is weaker than "Translate every section of the README to French; no English sentences remain." + ## Recovering stuck workers When 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: diff --git a/website/docs/user-guide/skills/bundled/devops/devops-kanban-worker.md b/website/docs/user-guide/skills/bundled/devops/devops-kanban-worker.md index 6312dafbb..e5cdc3277 100644 --- a/website/docs/user-guide/skills/bundled/devops/devops-kanban-worker.md +++ b/website/docs/user-guide/skills/bundled/devops/devops-kanban-worker.md @@ -185,6 +185,7 @@ You can configure the gateway to receive cross-profile Kanban task notifications ## Do NOT - 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. +- Call `clarify` to ask the human a question. You are running headless — there is no live user to answer. The call will time out (default ~120s) and the task will sit silently in `running` with no signal that it needs input. Use `kanban_comment` (context) + `kanban_block(reason=...)` (decision needed) instead — the task surfaces on the board as blocked, the operator sees it, unblocks with their answer in a comment, and you respawn with the thread. - Modify files outside `$HERMES_KANBAN_WORKSPACE` unless the task body says to. - Create follow-up tasks assigned to yourself — assign to the right specialist. - Complete a task you didn't actually finish. Block it instead. diff --git a/website/docs/user-guide/skills/bundled/devops/devops-webhook-subscriptions.md b/website/docs/user-guide/skills/bundled/devops/devops-webhook-subscriptions.md deleted file mode 100644 index 4dfd6eab8..000000000 --- a/website/docs/user-guide/skills/bundled/devops/devops-webhook-subscriptions.md +++ /dev/null @@ -1,222 +0,0 @@ ---- -title: "Webhook Subscriptions — Webhook subscriptions: event-driven agent runs" -sidebar_label: "Webhook Subscriptions" -description: "Webhook subscriptions: event-driven agent runs" ---- - -{/* This page is auto-generated from the skill's SKILL.md by website/scripts/generate-skill-docs.py. Edit the source SKILL.md, not this page. */} - -# Webhook Subscriptions - -Webhook subscriptions: event-driven agent runs. - -## Skill metadata - -| | | -|---|---| -| Source | Bundled (installed by default) | -| Path | `skills/devops/webhook-subscriptions` | -| Version | `1.1.0` | -| Platforms | linux, macos, windows | -| Tags | `webhook`, `events`, `automation`, `integrations`, `notifications`, `push` | - -## Reference: full SKILL.md - -:::info -The following is the complete skill definition that Hermes loads when this skill is triggered. This is what the agent sees as instructions when the skill is active. -::: - -# Webhook Subscriptions - -Create 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. - -## Setup (Required First) - -The webhook platform must be enabled before subscriptions can be created. Check with: -```bash -hermes webhook list -``` - -If it says "Webhook platform is not enabled", set it up: - -### Option 1: Setup wizard -```bash -hermes gateway setup -``` -Follow the prompts to enable webhooks, set the port, and set a global HMAC secret. - -### Option 2: Manual config -Add to `~/.hermes/config.yaml`: -```yaml -platforms: - webhook: - enabled: true - extra: - host: "0.0.0.0" - port: 8644 - secret: "generate-a-strong-secret-here" -``` - -### Option 3: Environment variables -Add to `~/.hermes/.env`: -```bash -WEBHOOK_ENABLED=true -WEBHOOK_PORT=8644 -WEBHOOK_SECRET=generate-a-strong-secret-here -``` - -After configuration, start (or restart) the gateway: -```bash -hermes gateway run -# Or if using systemd: -systemctl --user restart hermes-gateway -``` - -Verify it's running: -```bash -curl http://localhost:8644/health -``` - -## Commands - -All management is via the `hermes webhook` CLI command: - -### Create a subscription -```bash -hermes webhook subscribe <name> \ - --prompt "Prompt template with {payload.fields}" \ - --events "event1,event2" \ - --description "What this does" \ - --skills "skill1,skill2" \ - --deliver telegram \ - --deliver-chat-id "12345" \ - --secret "optional-custom-secret" -``` - -Returns the webhook URL and HMAC secret. The user configures their service to POST to that URL. - -### List subscriptions -```bash -hermes webhook list -``` - -### Remove a subscription -```bash -hermes webhook remove <name> -``` - -### Test a subscription -```bash -hermes webhook test <name> -hermes webhook test <name> --payload '{"key": "value"}' -``` - -## Prompt Templates - -Prompts support `{dot.notation}` for accessing nested payload fields: - -- `{issue.title}` — GitHub issue title -- `{pull_request.user.login}` — PR author -- `{data.object.amount}` — Stripe payment amount -- `{sensor.temperature}` — IoT sensor reading - -If no prompt is specified, the full JSON payload is dumped into the agent prompt. - -## Common Patterns - -### GitHub: new issues -```bash -hermes webhook subscribe github-issues \ - --events "issues" \ - --prompt "New GitHub issue #{issue.number}: {issue.title}\n\nAction: {action}\nAuthor: {issue.user.login}\nBody:\n{issue.body}\n\nPlease triage this issue." \ - --deliver telegram \ - --deliver-chat-id "-100123456789" -``` - -Then in GitHub repo Settings → Webhooks → Add webhook: -- Payload URL: the returned webhook_url -- Content type: application/json -- Secret: the returned secret -- Events: "Issues" - -### GitHub: PR reviews -```bash -hermes webhook subscribe github-prs \ - --events "pull_request" \ - --prompt "PR #{pull_request.number} {action}: {pull_request.title}\nBy: {pull_request.user.login}\nBranch: {pull_request.head.ref}\n\n{pull_request.body}" \ - --skills "github-code-review" \ - --deliver github_comment -``` - -### Stripe: payment events -```bash -hermes webhook subscribe stripe-payments \ - --events "payment_intent.succeeded,payment_intent.payment_failed" \ - --prompt "Payment {data.object.status}: {data.object.amount} cents from {data.object.receipt_email}" \ - --deliver telegram \ - --deliver-chat-id "-100123456789" -``` - -### CI/CD: build notifications -```bash -hermes webhook subscribe ci-builds \ - --events "pipeline" \ - --prompt "Build {object_attributes.status} on {project.name} branch {object_attributes.ref}\nCommit: {commit.message}" \ - --deliver discord \ - --deliver-chat-id "1234567890" -``` - -### Generic monitoring alert -```bash -hermes webhook subscribe alerts \ - --prompt "Alert: {alert.name}\nSeverity: {alert.severity}\nMessage: {alert.message}\n\nPlease investigate and suggest remediation." \ - --deliver origin -``` - -### Direct delivery (no agent, zero LLM cost) - -For 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. - -Use this for: -- External service push notifications (Supabase/Firebase webhooks → Telegram) -- Monitoring alerts that should forward verbatim -- Inter-agent pings where one agent is telling another agent's user something -- Any webhook where an LLM round trip would be wasted effort - -```bash -hermes webhook subscribe antenna-matches \ - --deliver telegram \ - --deliver-chat-id "123456789" \ - --deliver-only \ - --prompt "🎉 New match: {match.user_name} matched with you!" \ - --description "Antenna match notifications" -``` - -The 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. - -Requires `--deliver` to be a real target (telegram, discord, slack, github_comment, etc.) — `--deliver log` is rejected because log-only direct delivery is pointless. - -## Security - -- Each subscription gets an auto-generated HMAC-SHA256 secret (or provide your own with `--secret`) -- The webhook adapter validates signatures on every incoming POST -- Static routes from config.yaml cannot be overwritten by dynamic subscriptions -- Subscriptions persist to `~/.hermes/webhook_subscriptions.json` - -## How It Works - -1. `hermes webhook subscribe` writes to `~/.hermes/webhook_subscriptions.json` -2. The webhook adapter hot-reloads this file on each incoming request (mtime-gated, negligible overhead) -3. When a POST arrives matching a route, the adapter formats the prompt and triggers an agent run -4. The agent's response is delivered to the configured target (Telegram, Discord, GitHub comment, etc.) - -## Troubleshooting - -If webhooks aren't working: - -1. **Is the gateway running?** Check with `systemctl --user status hermes-gateway` or `ps aux | grep gateway` -2. **Is the webhook server listening?** `curl http://localhost:8644/health` should return `{"status": "ok"}` -3. **Check gateway logs:** `grep webhook ~/.hermes/logs/gateway.log | tail -20` -4. **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`. -5. **Firewall/NAT?** The webhook URL must be reachable from the service. For local development, use a tunnel (ngrok, cloudflared). -6. **Wrong event type?** Check `--events` filter matches what the service sends. Use `hermes webhook test <name>` to verify the route works. diff --git a/website/docs/user-guide/skills/bundled/mcp/mcp-native-mcp.md b/website/docs/user-guide/skills/bundled/mcp/mcp-native-mcp.md deleted file mode 100644 index eeeb44d6a..000000000 --- a/website/docs/user-guide/skills/bundled/mcp/mcp-native-mcp.md +++ /dev/null @@ -1,375 +0,0 @@ ---- -title: "Native Mcp — MCP client: connect servers, register tools (stdio/HTTP)" -sidebar_label: "Native Mcp" -description: "MCP client: connect servers, register tools (stdio/HTTP)" ---- - -{/* This page is auto-generated from the skill's SKILL.md by website/scripts/generate-skill-docs.py. Edit the source SKILL.md, not this page. */} - -# Native Mcp - -MCP client: connect servers, register tools (stdio/HTTP). - -## Skill metadata - -| | | -|---|---| -| Source | Bundled (installed by default) | -| Path | `skills/mcp/native-mcp` | -| Version | `1.0.0` | -| Author | Hermes Agent | -| License | MIT | -| Platforms | linux, macos, windows | -| Tags | `MCP`, `Tools`, `Integrations` | -| Related skills | [`mcporter`](/docs/user-guide/skills/optional/mcp/mcp-mcporter) | - -## Reference: full SKILL.md - -:::info -The following is the complete skill definition that Hermes loads when this skill is triggered. This is what the agent sees as instructions when the skill is active. -::: - -# Native MCP Client - -Hermes Agent has a built-in MCP client that connects to MCP servers at startup, discovers their tools, and makes them available as first-class tools the agent can call directly. No bridge CLI needed -- tools from MCP servers appear alongside built-in tools like `terminal`, `read_file`, etc. - -## When to Use - -Use this whenever you want to: -- Connect to MCP servers and use their tools from within Hermes Agent -- Add external capabilities (filesystem access, GitHub, databases, APIs) via MCP -- Run local stdio-based MCP servers (npx, uvx, or any command) -- Connect to remote HTTP/StreamableHTTP MCP servers -- Have MCP tools auto-discovered and available in every conversation - -For ad-hoc, one-off MCP tool calls from the terminal without configuring anything, see the `mcporter` skill instead. - -## Prerequisites - -- **mcp Python package** -- optional dependency; install with `pip install mcp`. If not installed, MCP support is silently disabled. -- **Node.js** -- required for `npx`-based MCP servers (most community servers) -- **uv** -- required for `uvx`-based MCP servers (Python-based servers) - -Install the MCP SDK: - -```bash -pip install mcp -# or, if using uv: -uv pip install mcp -``` - -## Quick Start - -Add MCP servers to `~/.hermes/config.yaml` under the `mcp_servers` key: - -```yaml -mcp_servers: - time: - command: "uvx" - args: ["mcp-server-time"] -``` - -Restart Hermes Agent. On startup it will: -1. Connect to the server -2. Discover available tools -3. Register them with the prefix `mcp_time_*` -4. Inject them into all platform toolsets - -You can then use the tools naturally -- just ask the agent to get the current time. - -## Configuration Reference - -Each entry under `mcp_servers` is a server name mapped to its config. There are two transport types: **stdio** (command-based) and **HTTP** (url-based). - -### Stdio Transport (command + args) - -```yaml -mcp_servers: - server_name: - command: "npx" # (required) executable to run - args: ["-y", "pkg-name"] # (optional) command arguments, default: [] - env: # (optional) environment variables for the subprocess - SOME_API_KEY: "value" - timeout: 120 # (optional) per-tool-call timeout in seconds, default: 120 - connect_timeout: 60 # (optional) initial connection timeout in seconds, default: 60 -``` - -### HTTP Transport (url) - -```yaml -mcp_servers: - server_name: - url: "https://my-server.example.com/mcp" # (required) server URL - headers: # (optional) HTTP headers - Authorization: "Bearer sk-..." - timeout: 180 # (optional) per-tool-call timeout in seconds, default: 120 - connect_timeout: 60 # (optional) initial connection timeout in seconds, default: 60 -``` - -### All Config Options - -| Option | Type | Default | Description | -|-------------------|--------|---------|---------------------------------------------------| -| `command` | string | -- | Executable to run (stdio transport, required) | -| `args` | list | `[]` | Arguments passed to the command | -| `env` | dict | `{}` | Extra environment variables for the subprocess | -| `url` | string | -- | Server URL (HTTP transport, required) | -| `headers` | dict | `{}` | HTTP headers sent with every request | -| `timeout` | int | `120` | Per-tool-call timeout in seconds | -| `connect_timeout` | int | `60` | Timeout for initial connection and discovery | - -Note: A server config must have either `command` (stdio) or `url` (HTTP), not both. - -## How It Works - -### Startup Discovery - -When Hermes Agent starts, `discover_mcp_tools()` is called during tool initialization: - -1. Reads `mcp_servers` from `~/.hermes/config.yaml` -2. For each server, spawns a connection in a dedicated background event loop -3. Initializes the MCP session and calls `list_tools()` to discover available tools -4. Registers each tool in the Hermes tool registry - -### Tool Naming Convention - -MCP tools are registered with the naming pattern: - -``` -mcp_{server_name}_{tool_name} -``` - -Hyphens and dots in names are replaced with underscores for LLM API compatibility. - -Examples: -- Server `filesystem`, tool `read_file` → `mcp_filesystem_read_file` -- Server `github`, tool `list-issues` → `mcp_github_list_issues` -- Server `my-api`, tool `fetch.data` → `mcp_my_api_fetch_data` - -### Auto-Injection - -After discovery, MCP tools are automatically injected into all `hermes-*` platform toolsets (CLI, Discord, Telegram, etc.). This means MCP tools are available in every conversation without any additional configuration. - -### Connection Lifecycle - -- Each server runs as a long-lived asyncio Task in a background daemon thread -- Connections persist for the lifetime of the agent process -- If a connection drops, automatic reconnection with exponential backoff kicks in (up to 5 retries, max 60s backoff) -- On agent shutdown, all connections are gracefully closed - -### Idempotency - -`discover_mcp_tools()` is idempotent -- calling it multiple times only connects to servers that aren't already connected. Failed servers are retried on subsequent calls. - -## Transport Types - -### Stdio Transport - -The most common transport. Hermes launches the MCP server as a subprocess and communicates over stdin/stdout. - -```yaml -mcp_servers: - filesystem: - command: "npx" - args: ["-y", "@modelcontextprotocol/server-filesystem", "/home/user/projects"] -``` - -The subprocess inherits a **filtered** environment (see Security section below) plus any variables you specify in `env`. - -### HTTP / StreamableHTTP Transport - -For remote or shared MCP servers. Requires the `mcp` package to include HTTP client support (`mcp.client.streamable_http`). - -```yaml -mcp_servers: - remote_api: - url: "https://mcp.example.com/mcp" - headers: - Authorization: "Bearer sk-..." -``` - -If HTTP support is not available in your installed `mcp` version, the server will fail with an ImportError and other servers will continue normally. - -## Security - -### Environment Variable Filtering - -For stdio servers, Hermes does NOT pass your full shell environment to MCP subprocesses. Only safe baseline variables are inherited: - -- `PATH`, `HOME`, `USER`, `LANG`, `LC_ALL`, `TERM`, `SHELL`, `TMPDIR` -- Any `XDG_*` variables - -All other environment variables (API keys, tokens, secrets) are excluded unless you explicitly add them via the `env` config key. This prevents accidental credential leakage to untrusted MCP servers. - -```yaml -mcp_servers: - github: - command: "npx" - args: ["-y", "@modelcontextprotocol/server-github"] - env: - # Only this token is passed to the subprocess - GITHUB_PERSONAL_ACCESS_TOKEN: "ghp_..." -``` - -### Credential Stripping in Error Messages - -If an MCP tool call fails, any credential-like patterns in the error message are automatically redacted before being shown to the LLM. This covers: - -- GitHub PATs (`ghp_...`) -- OpenAI-style keys (`sk-...`) -- Bearer tokens -- Generic `token=`, `key=`, `API_KEY=`, `password=`, `secret=` patterns - -## Troubleshooting - -### "MCP SDK not available -- skipping MCP tool discovery" - -The `mcp` Python package is not installed. Install it: - -```bash -pip install mcp -``` - -### "No MCP servers configured" - -No `mcp_servers` key in `~/.hermes/config.yaml`, or it's empty. Add at least one server. - -### "Failed to connect to MCP server 'X'" - -Common causes: -- **Command not found**: The `command` binary isn't on PATH. Ensure `npx`, `uvx`, or the relevant command is installed. -- **Package not found**: For npx servers, the npm package may not exist or may need `-y` in args to auto-install. -- **Timeout**: The server took too long to start. Increase `connect_timeout`. -- **Port conflict**: For HTTP servers, the URL may be unreachable. - -### "MCP server 'X' requires HTTP transport but mcp.client.streamable_http is not available" - -Your `mcp` package version doesn't include HTTP client support. Upgrade: - -```bash -pip install --upgrade mcp -``` - -### Tools not appearing - -- Check that the server is listed under `mcp_servers` (not `mcp` or `servers`) -- Ensure the YAML indentation is correct -- Look at Hermes Agent startup logs for connection messages -- Tool names are prefixed with `mcp_{server}_{tool}` -- look for that pattern - -### Connection keeps dropping - -The client retries up to 5 times with exponential backoff (1s, 2s, 4s, 8s, 16s, capped at 60s). If the server is fundamentally unreachable, it gives up after 5 attempts. Check the server process and network connectivity. - -## Examples - -### Time Server (uvx) - -```yaml -mcp_servers: - time: - command: "uvx" - args: ["mcp-server-time"] -``` - -Registers tools like `mcp_time_get_current_time`. - -### Filesystem Server (npx) - -```yaml -mcp_servers: - filesystem: - command: "npx" - args: ["-y", "@modelcontextprotocol/server-filesystem", "/home/user/documents"] - timeout: 30 -``` - -Registers tools like `mcp_filesystem_read_file`, `mcp_filesystem_write_file`, `mcp_filesystem_list_directory`. - -### GitHub Server with Authentication - -```yaml -mcp_servers: - github: - command: "npx" - args: ["-y", "@modelcontextprotocol/server-github"] - env: - GITHUB_PERSONAL_ACCESS_TOKEN: "ghp_xxxxxxxxxxxxxxxxxxxx" - timeout: 60 -``` - -Registers tools like `mcp_github_list_issues`, `mcp_github_create_pull_request`, etc. - -### Remote HTTP Server - -```yaml -mcp_servers: - company_api: - url: "https://mcp.mycompany.com/v1/mcp" - headers: - Authorization: "Bearer sk-xxxxxxxxxxxxxxxxxxxx" - X-Team-Id: "engineering" - timeout: 180 - connect_timeout: 30 -``` - -### Multiple Servers - -```yaml -mcp_servers: - time: - command: "uvx" - args: ["mcp-server-time"] - - filesystem: - command: "npx" - args: ["-y", "@modelcontextprotocol/server-filesystem", "/tmp"] - - github: - command: "npx" - args: ["-y", "@modelcontextprotocol/server-github"] - env: - GITHUB_PERSONAL_ACCESS_TOKEN: "ghp_xxxxxxxxxxxxxxxxxxxx" - - company_api: - url: "https://mcp.internal.company.com/mcp" - headers: - Authorization: "Bearer sk-xxxxxxxxxxxxxxxxxxxx" - timeout: 300 -``` - -All tools from all servers are registered and available simultaneously. Each server's tools are prefixed with its name to avoid collisions. - -## Sampling (Server-Initiated LLM Requests) - -Hermes supports MCP's `sampling/createMessage` capability — MCP servers can request LLM completions through the agent during tool execution. This enables agent-in-the-loop workflows (data analysis, content generation, decision-making). - -Sampling is **enabled by default**. Configure per server: - -```yaml -mcp_servers: - my_server: - command: "npx" - args: ["-y", "my-mcp-server"] - sampling: - enabled: true # default: true - model: "gemini-3-flash" # model override (optional) - max_tokens_cap: 4096 # max tokens per request - timeout: 30 # LLM call timeout (seconds) - max_rpm: 10 # max requests per minute - allowed_models: [] # model whitelist (empty = all) - max_tool_rounds: 5 # tool loop limit (0 = disable) - log_level: "info" # audit verbosity -``` - -Servers can also include `tools` in sampling requests for multi-turn tool-augmented workflows. The `max_tool_rounds` config prevents infinite tool loops. Per-server audit metrics (requests, errors, tokens, tool use count) are tracked via `get_mcp_status()`. - -Disable sampling for untrusted servers with `sampling: { enabled: false }`. - -## Notes - -- MCP tools are called synchronously from the agent's perspective but run asynchronously on a dedicated background event loop -- Tool results are returned as JSON with either `{"result": "..."}` or `{"error": "..."}` -- The native MCP client is independent of `mcporter` -- you can use both simultaneously -- Server connections are persistent and shared across all conversations in the same agent process -- Adding or removing servers requires restarting the agent (no hot-reload currently) diff --git a/website/docs/user-guide/skills/bundled/media/media-spotify.md b/website/docs/user-guide/skills/bundled/media/media-spotify.md deleted file mode 100644 index 7df9764f0..000000000 --- a/website/docs/user-guide/skills/bundled/media/media-spotify.md +++ /dev/null @@ -1,151 +0,0 @@ ---- -title: "Spotify — Spotify: play, search, queue, manage playlists and devices" -sidebar_label: "Spotify" -description: "Spotify: play, search, queue, manage playlists and devices" ---- - -{/* This page is auto-generated from the skill's SKILL.md by website/scripts/generate-skill-docs.py. Edit the source SKILL.md, not this page. */} - -# Spotify - -Spotify: play, search, queue, manage playlists and devices. - -## Skill metadata - -| | | -|---|---| -| Source | Bundled (installed by default) | -| Path | `skills/media/spotify` | -| Version | `1.0.0` | -| Author | Hermes Agent | -| License | MIT | -| Platforms | linux, macos, windows | -| Tags | `spotify`, `music`, `playback`, `playlists`, `media` | -| Related skills | [`gif-search`](/docs/user-guide/skills/bundled/media/media-gif-search) | - -## Reference: full SKILL.md - -:::info -The following is the complete skill definition that Hermes loads when this skill is triggered. This is what the agent sees as instructions when the skill is active. -::: - -# Spotify - -Control the user's Spotify account via the Hermes Spotify toolset (7 tools). Setup guide: https://hermes-agent.nousresearch.com/docs/user-guide/features/spotify - -## When to use this skill - -The user says something like "play X", "pause", "skip", "queue up X", "what's playing", "search for X", "add to my X playlist", "make a playlist", "save this to my library", etc. - -## The 7 tools - -- `spotify_playback` — play, pause, next, previous, seek, set_repeat, set_shuffle, set_volume, get_state, get_currently_playing, recently_played -- `spotify_devices` — list, transfer -- `spotify_queue` — get, add -- `spotify_search` — search the catalog -- `spotify_playlists` — list, get, create, add_items, remove_items, update_details -- `spotify_albums` — get, tracks -- `spotify_library` — list/save/remove with `kind: "tracks"|"albums"` - -Playback-mutating actions require Spotify Premium; search/library/playlist ops work on Free. - -## Canonical patterns (minimize tool calls) - -### "Play <artist/track/album>" -One search, then play by URI. Do NOT loop through search results describing them unless the user asked for options. - -``` -spotify_search({"query": "miles davis kind of blue", "types": ["album"], "limit": 1}) -→ got album URI spotify:album:1weenld61qoidwYuZ1GESA -spotify_playback({"action": "play", "context_uri": "spotify:album:1weenld61qoidwYuZ1GESA"}) -``` - -For "play some <artist>" (no specific song), prefer `types: ["artist"]` and play the artist context URI — Spotify handles smart shuffle. If the user says "the song" or "that track", search `types: ["track"]` and pass `uris: [track_uri]` to play. - -### "What's playing?" / "What am I listening to?" -Single call — don't chain get_state after get_currently_playing. - -``` -spotify_playback({"action": "get_currently_playing"}) -``` - -If it returns 204/empty (`is_playing: false`), tell the user nothing is playing. Don't retry. - -### "Pause" / "Skip" / "Volume 50" -Direct action, no preflight inspection needed. - -``` -spotify_playback({"action": "pause"}) -spotify_playback({"action": "next"}) -spotify_playback({"action": "set_volume", "volume_percent": 50}) -``` - -### "Add to my <playlist name> playlist" -1. `spotify_playlists list` to find the playlist ID by name -2. Get the track URI (from currently playing, or search) -3. `spotify_playlists add_items` with the playlist_id and URIs - -``` -spotify_playlists({"action": "list"}) -→ found "Late Night Jazz" = 37i9dQZF1DX4wta20PHgwo -spotify_playback({"action": "get_currently_playing"}) -→ current track uri = spotify:track:0DiWol3AO6WpXZgp0goxAV -spotify_playlists({"action": "add_items", - "playlist_id": "37i9dQZF1DX4wta20PHgwo", - "uris": ["spotify:track:0DiWol3AO6WpXZgp0goxAV"]}) -``` - -### "Create a playlist called X and add the last 3 songs I played" -``` -spotify_playback({"action": "recently_played", "limit": 3}) -spotify_playlists({"action": "create", "name": "Focus 2026"}) -→ got playlist_id back in response -spotify_playlists({"action": "add_items", "playlist_id": <id>, "uris": [<3 uris>]}) -``` - -### "Save / unsave / is this saved?" -Use `spotify_library` with the right `kind`. - -``` -spotify_library({"kind": "tracks", "action": "save", "uris": ["spotify:track:..."]}) -spotify_library({"kind": "albums", "action": "list", "limit": 50}) -``` - -### "Transfer playback to my <device>" -``` -spotify_devices({"action": "list"}) -→ pick the device_id by matching name/type -spotify_devices({"action": "transfer", "device_id": "<id>", "play": true}) -``` - -## Critical failure modes - -**`403 Forbidden — No active device found`** on any playback action means Spotify isn't running anywhere. Tell the user: "Open Spotify on your phone/desktop/web player first, start any track for a second, then retry." Don't retry the tool call blindly — it will fail the same way. You can call `spotify_devices list` to confirm; an empty list means no active device. - -**`403 Forbidden — Premium required`** means the user is on Free and tried to mutate playback. Don't retry; tell them this action needs Premium. Reads still work (search, playlists, library, get_state). - -**`204 No Content` on `get_currently_playing`** is NOT an error — it means nothing is playing. The tool returns `is_playing: false`. Just report that to the user. - -**`429 Too Many Requests`** = rate limit. Wait and retry once. If it keeps happening, you're looping — stop. - -**`401 Unauthorized` after a retry** — refresh token revoked. Tell the user to run `hermes auth spotify` again. - -## URI and ID formats - -Spotify uses three interchangeable ID formats. The tools accept all three and normalize: - -- URI: `spotify:track:0DiWol3AO6WpXZgp0goxAV` (preferred) -- URL: `https://open.spotify.com/track/0DiWol3AO6WpXZgp0goxAV` -- Bare ID: `0DiWol3AO6WpXZgp0goxAV` - -When in doubt, use full URIs. Search results return URIs in the `uri` field — pass those directly. - -Entity types: `track`, `album`, `artist`, `playlist`, `show`, `episode`. Use the right type for the action — `spotify_playback.play` with a `context_uri` expects album/playlist/artist; `uris` expects an array of track URIs. - -## What NOT to do - -- **Don't call `get_state` before every action.** Spotify accepts play/pause/skip without preflight. Only inspect state when the user asked "what's playing" or you need to reason about device/track. -- **Don't describe search results unless asked.** If the user said "play X", search, grab the top URI, play it. They'll hear it's wrong if it's wrong. -- **Don't retry on `403 Premium required` or `403 No active device`.** Those are permanent until user action. -- **Don't use `spotify_search` to find a playlist by name** — that searches the public Spotify catalog. User playlists come from `spotify_playlists list`. -- **Don't mix `kind: "tracks"` with album URIs** in `spotify_library` (or vice versa). The tool normalizes IDs but the API endpoint differs. diff --git a/website/docs/user-guide/skills/bundled/productivity/productivity-linear.md b/website/docs/user-guide/skills/bundled/productivity/productivity-linear.md deleted file mode 100644 index 750a21ba7..000000000 --- a/website/docs/user-guide/skills/bundled/productivity/productivity-linear.md +++ /dev/null @@ -1,395 +0,0 @@ ---- -title: "Linear — Linear: manage issues, projects, teams via GraphQL + curl" -sidebar_label: "Linear" -description: "Linear: manage issues, projects, teams via GraphQL + curl" ---- - -{/* This page is auto-generated from the skill's SKILL.md by website/scripts/generate-skill-docs.py. Edit the source SKILL.md, not this page. */} - -# Linear - -Linear: manage issues, projects, teams via GraphQL + curl. - -## Skill metadata - -| | | -|---|---| -| Source | Bundled (installed by default) | -| Path | `skills/productivity/linear` | -| Version | `1.0.0` | -| Author | Hermes Agent | -| License | MIT | -| Platforms | linux, macos, windows | -| Tags | `Linear`, `Project Management`, `Issues`, `GraphQL`, `API`, `Productivity` | - -## Reference: full SKILL.md - -:::info -The following is the complete skill definition that Hermes loads when this skill is triggered. This is what the agent sees as instructions when the skill is active. -::: - -# Linear — Issue & Project Management - -Manage Linear issues, projects, and teams directly via the GraphQL API using `curl`. No MCP server, no OAuth flow, no extra dependencies. - -## Setup - -1. Get a personal API key from **Linear Settings > Account > Security & access > Personal API keys** (URL: https://linear.app/settings/account/security). Note: the org-level *Settings > API* page only shows OAuth apps and workspace-member keys, not personal keys. -2. Set `LINEAR_API_KEY` in your environment (via `hermes setup` or your env config) - -## API Basics - -- **Endpoint:** `https://api.linear.app/graphql` (POST) -- **Auth header:** `Authorization: $LINEAR_API_KEY` (no "Bearer" prefix for API keys) -- **All requests are POST** with `Content-Type: application/json` -- **Both UUIDs and short identifiers** (e.g., `ENG-123`) work for `issue(id:)` - -Base curl pattern: -```bash -curl -s -X POST https://api.linear.app/graphql \ - -H "Authorization: $LINEAR_API_KEY" \ - -H "Content-Type: application/json" \ - -d '{"query": "{ viewer { id name } }"}' | python3 -m json.tool -``` - -## Python helper script (ergonomic alternative) - -For faster one-liners that don't need hand-written GraphQL, this skill ships a stdlib Python CLI at `scripts/linear_api.py`. Zero dependencies. Same auth (reads `LINEAR_API_KEY`). - -```bash -SCRIPT=$(dirname "$(find ~/.hermes -path '*skills/productivity/linear/scripts/linear_api.py' 2>/dev/null | head -1)")/linear_api.py - -python3 "$SCRIPT" whoami -python3 "$SCRIPT" list-teams -python3 "$SCRIPT" get-issue ENG-42 -python3 "$SCRIPT" get-document 38359beef67c # fetch a doc by slugId from the URL -python3 "$SCRIPT" raw 'query { viewer { name } }' -``` - -All subcommands: `whoami`, `list-teams`, `list-projects`, `list-states`, `list-issues`, `get-issue`, `search-issues`, `create-issue`, `update-issue`, `update-status`, `add-comment`, `list-documents`, `get-document`, `search-documents`, `raw`. Run with `--help` for flags. - -Use the script when: you want a quick answer without crafting GraphQL. Use curl when: you need a query the script doesn't wrap, or you want to compose filters inline. - -## Workflow States - -Linear uses `WorkflowState` objects with a `type` field. **6 state types:** - -| Type | Description | -|------|-------------| -| `triage` | Incoming issues needing review | -| `backlog` | Acknowledged but not yet planned | -| `unstarted` | Planned/ready but not started | -| `started` | Actively being worked on | -| `completed` | Done | -| `canceled` | Won't do | - -Each team has its own named states (e.g., "In Progress" is type `started`). To change an issue's status, you need the `stateId` (UUID) of the target state — query workflow states first. - -**Priority values:** 0 = None, 1 = Urgent, 2 = High, 3 = Medium, 4 = Low - -## Common Queries - -### Get current user -```bash -curl -s -X POST https://api.linear.app/graphql \ - -H "Authorization: $LINEAR_API_KEY" \ - -H "Content-Type: application/json" \ - -d '{"query": "{ viewer { id name email } }"}' | python3 -m json.tool -``` - -### List teams -```bash -curl -s -X POST https://api.linear.app/graphql \ - -H "Authorization: $LINEAR_API_KEY" \ - -H "Content-Type: application/json" \ - -d '{"query": "{ teams { nodes { id name key } } }"}' | python3 -m json.tool -``` - -### List workflow states for a team -```bash -curl -s -X POST https://api.linear.app/graphql \ - -H "Authorization: $LINEAR_API_KEY" \ - -H "Content-Type: application/json" \ - -d '{"query": "{ workflowStates(filter: { team: { key: { eq: \"ENG\" } } }) { nodes { id name type } } }"}' | python3 -m json.tool -``` - -### List issues (first 20) -```bash -curl -s -X POST https://api.linear.app/graphql \ - -H "Authorization: $LINEAR_API_KEY" \ - -H "Content-Type: application/json" \ - -d '{"query": "{ issues(first: 20) { nodes { identifier title priority state { name type } assignee { name } team { key } url } pageInfo { hasNextPage endCursor } } }"}' | python3 -m json.tool -``` - -### List my assigned issues -```bash -curl -s -X POST https://api.linear.app/graphql \ - -H "Authorization: $LINEAR_API_KEY" \ - -H "Content-Type: application/json" \ - -d '{"query": "{ viewer { assignedIssues(first: 25) { nodes { identifier title state { name type } priority url } } } }"}' | python3 -m json.tool -``` - -### Get a single issue (by identifier like ENG-123) -```bash -curl -s -X POST https://api.linear.app/graphql \ - -H "Authorization: $LINEAR_API_KEY" \ - -H "Content-Type: application/json" \ - -d '{"query": "{ issue(id: \"ENG-123\") { id identifier title description priority state { id name type } assignee { id name } team { key } project { name } labels { nodes { name } } comments { nodes { body user { name } createdAt } } url } }"}' | python3 -m json.tool -``` - -### Search issues by text -```bash -curl -s -X POST https://api.linear.app/graphql \ - -H "Authorization: $LINEAR_API_KEY" \ - -H "Content-Type: application/json" \ - -d '{"query": "{ issueSearch(query: \"bug login\", first: 10) { nodes { identifier title state { name } assignee { name } url } } }"}' | python3 -m json.tool -``` - -### Filter issues by state type -```bash -curl -s -X POST https://api.linear.app/graphql \ - -H "Authorization: $LINEAR_API_KEY" \ - -H "Content-Type: application/json" \ - -d '{"query": "{ issues(filter: { state: { type: { in: [\"started\"] } } }, first: 20) { nodes { identifier title state { name } assignee { name } } } }"}' | python3 -m json.tool -``` - -### Filter by team and assignee -```bash -curl -s -X POST https://api.linear.app/graphql \ - -H "Authorization: $LINEAR_API_KEY" \ - -H "Content-Type: application/json" \ - -d '{"query": "{ issues(filter: { team: { key: { eq: \"ENG\" } }, assignee: { email: { eq: \"user@example.com\" } } }, first: 20) { nodes { identifier title state { name } priority } } }"}' | python3 -m json.tool -``` - -### List projects -```bash -curl -s -X POST https://api.linear.app/graphql \ - -H "Authorization: $LINEAR_API_KEY" \ - -H "Content-Type: application/json" \ - -d '{"query": "{ projects(first: 20) { nodes { id name description progress lead { name } teams { nodes { key } } url } } }"}' | python3 -m json.tool -``` - -### List team members -```bash -curl -s -X POST https://api.linear.app/graphql \ - -H "Authorization: $LINEAR_API_KEY" \ - -H "Content-Type: application/json" \ - -d '{"query": "{ users { nodes { id name email active } } }"}' | python3 -m json.tool -``` - -### List labels -```bash -curl -s -X POST https://api.linear.app/graphql \ - -H "Authorization: $LINEAR_API_KEY" \ - -H "Content-Type: application/json" \ - -d '{"query": "{ issueLabels { nodes { id name color } } }"}' | python3 -m json.tool -``` - -## Common Mutations - -### Create an issue -```bash -curl -s -X POST https://api.linear.app/graphql \ - -H "Authorization: $LINEAR_API_KEY" \ - -H "Content-Type: application/json" \ - -d '{ - "query": "mutation($input: IssueCreateInput!) { issueCreate(input: $input) { success issue { id identifier title url } } }", - "variables": { - "input": { - "teamId": "TEAM_UUID", - "title": "Fix login bug", - "description": "Users cannot login with SSO", - "priority": 2 - } - } - }' | python3 -m json.tool -``` - -### Update issue status -First get the target state UUID from the workflow states query above, then: -```bash -curl -s -X POST https://api.linear.app/graphql \ - -H "Authorization: $LINEAR_API_KEY" \ - -H "Content-Type: application/json" \ - -d '{"query": "mutation { issueUpdate(id: \"ENG-123\", input: { stateId: \"STATE_UUID\" }) { success issue { identifier state { name type } } } }"}' | python3 -m json.tool -``` - -### Assign an issue -```bash -curl -s -X POST https://api.linear.app/graphql \ - -H "Authorization: $LINEAR_API_KEY" \ - -H "Content-Type: application/json" \ - -d '{"query": "mutation { issueUpdate(id: \"ENG-123\", input: { assigneeId: \"USER_UUID\" }) { success issue { identifier assignee { name } } } }"}' | python3 -m json.tool -``` - -### Set priority -```bash -curl -s -X POST https://api.linear.app/graphql \ - -H "Authorization: $LINEAR_API_KEY" \ - -H "Content-Type: application/json" \ - -d '{"query": "mutation { issueUpdate(id: \"ENG-123\", input: { priority: 1 }) { success issue { identifier priority } } }"}' | python3 -m json.tool -``` - -### Add a comment -```bash -curl -s -X POST https://api.linear.app/graphql \ - -H "Authorization: $LINEAR_API_KEY" \ - -H "Content-Type: application/json" \ - -d '{"query": "mutation { commentCreate(input: { issueId: \"ISSUE_UUID\", body: \"Investigated. Root cause is X.\" }) { success comment { id body } } }"}' | python3 -m json.tool -``` - -### Set due date -```bash -curl -s -X POST https://api.linear.app/graphql \ - -H "Authorization: $LINEAR_API_KEY" \ - -H "Content-Type: application/json" \ - -d '{"query": "mutation { issueUpdate(id: \"ENG-123\", input: { dueDate: \"2026-04-01\" }) { success issue { identifier dueDate } } }"}' | python3 -m json.tool -``` - -### Add labels to an issue -```bash -curl -s -X POST https://api.linear.app/graphql \ - -H "Authorization: $LINEAR_API_KEY" \ - -H "Content-Type: application/json" \ - -d '{"query": "mutation { issueUpdate(id: \"ENG-123\", input: { labelIds: [\"LABEL_UUID_1\", \"LABEL_UUID_2\"] }) { success issue { identifier labels { nodes { name } } } } }"}' | python3 -m json.tool -``` - -### Add issue to a project -```bash -curl -s -X POST https://api.linear.app/graphql \ - -H "Authorization: $LINEAR_API_KEY" \ - -H "Content-Type: application/json" \ - -d '{"query": "mutation { issueUpdate(id: \"ENG-123\", input: { projectId: \"PROJECT_UUID\" }) { success issue { identifier project { name } } } }"}' | python3 -m json.tool -``` - -### Create a project -```bash -curl -s -X POST https://api.linear.app/graphql \ - -H "Authorization: $LINEAR_API_KEY" \ - -H "Content-Type: application/json" \ - -d '{ - "query": "mutation($input: ProjectCreateInput!) { projectCreate(input: $input) { success project { id name url } } }", - "variables": { - "input": { - "name": "Q2 Auth Overhaul", - "description": "Replace legacy auth with OAuth2 and PKCE", - "teamIds": ["TEAM_UUID"] - } - } - }' | python3 -m json.tool -``` - -## Documents - -Linear **Documents** are prose docs (RFCs, specs, notes) stored alongside issues. They have their own `documents` root query and `document(id:)` single-fetch. - -### Document URLs and `slugId` - -Document URLs look like: -``` -https://linear.app/<workspace>/document/<slug>-<hexSlugId> -``` - -The trailing hex segment is the `slugId`. Example: `https://linear.app/nousresearch/document/rfc-hermes-permission-gateway-discord-38359beef67c` → `slugId` is `38359beef67c`. - -**Important schema detail:** the Markdown body is in the `content` field. The ProseMirror JSON is in `contentState` (not `contentData` — that field does not exist and the API returns 400). - -### Fetch a document by slugId - -`document(id:)` only accepts UUIDs. To fetch by the URL's hex slug, filter the collection: - -```bash -curl -s -X POST https://api.linear.app/graphql \ - -H "Authorization: $LINEAR_API_KEY" \ - -H "Content-Type: application/json" \ - -d '{"query": "query($s: String!) { documents(filter: { slugId: { eq: $s } }, first: 1) { nodes { id title content contentState slugId url creator { name } project { name } updatedAt } } }", "variables": {"s": "38359beef67c"}}' \ - | python3 -m json.tool -``` - -Or via the Python helper: -```bash -python3 scripts/linear_api.py get-document 38359beef67c -``` - -### Fetch a document by UUID - -```bash -curl -s -X POST https://api.linear.app/graphql \ - -H "Authorization: $LINEAR_API_KEY" \ - -H "Content-Type: application/json" \ - -d '{"query": "{ document(id: \"11700cff-b514-4db3-afcc-3ed1afacba1c\") { title content url } }"}' \ - | python3 -m json.tool -``` - -### List recent documents - -```bash -curl -s -X POST https://api.linear.app/graphql \ - -H "Authorization: $LINEAR_API_KEY" \ - -H "Content-Type: application/json" \ - -d '{"query": "{ documents(first: 25, orderBy: updatedAt) { nodes { id title slugId url updatedAt project { name } } } }"}' \ - | python3 -m json.tool -``` - -### Search documents by title - -Linear's schema has no `searchDocuments` root. Use a title-substring filter instead: - -```bash -curl -s -X POST https://api.linear.app/graphql \ - -H "Authorization: $LINEAR_API_KEY" \ - -H "Content-Type: application/json" \ - -d '{"query": "{ documents(filter: { title: { containsIgnoreCase: \"RFC\" } }, first: 25) { nodes { title slugId url } } }"}' \ - | python3 -m json.tool -``` - -## Pagination - -Linear uses Relay-style cursor pagination: - -```bash -# First page -curl -s -X POST https://api.linear.app/graphql \ - -H "Authorization: $LINEAR_API_KEY" \ - -H "Content-Type: application/json" \ - -d '{"query": "{ issues(first: 20) { nodes { identifier title } pageInfo { hasNextPage endCursor } } }"}' | python3 -m json.tool - -# Next page — use endCursor from previous response -curl -s -X POST https://api.linear.app/graphql \ - -H "Authorization: $LINEAR_API_KEY" \ - -H "Content-Type: application/json" \ - -d '{"query": "{ issues(first: 20, after: \"CURSOR_FROM_PREVIOUS\") { nodes { identifier title } pageInfo { hasNextPage endCursor } } }"}' | python3 -m json.tool -``` - -Default page size: 50. Max: 250. Always use `first: N` to limit results. - -## Filtering Reference - -Comparators: `eq`, `neq`, `in`, `nin`, `lt`, `lte`, `gt`, `gte`, `contains`, `startsWith`, `containsIgnoreCase` - -Combine filters with `or: [...]` for OR logic (default is AND within a filter object). - -## Typical Workflow - -1. **Query teams** to get team IDs and keys -2. **Query workflow states** for target team to get state UUIDs -3. **List or search issues** to find what needs work -4. **Create issues** with team ID, title, description, priority -5. **Update status** by setting `stateId` to the target workflow state -6. **Add comments** to track progress -7. **Mark complete** by setting `stateId` to the team's "completed" type state - -## Rate Limits - -- 5,000 requests/hour per API key -- 3,000,000 complexity points/hour -- Use `first: N` to limit results and reduce complexity cost -- Monitor `X-RateLimit-Requests-Remaining` response header - -## Important Notes - -- Always use `terminal` tool with `curl` for API calls — do NOT use `web_extract` or `browser` -- Always check the `errors` array in GraphQL responses — HTTP 200 can still contain errors -- If `stateId` is omitted when creating issues, Linear defaults to the first backlog state -- The `description` field supports Markdown -- Use `python3 -m json.tool` or `jq` to format JSON responses for readability diff --git a/website/docs/user-guide/skills/bundled/software-development/software-development-debugging-hermes-tui-commands.md b/website/docs/user-guide/skills/bundled/software-development/software-development-debugging-hermes-tui-commands.md deleted file mode 100644 index 00c3388e3..000000000 --- a/website/docs/user-guide/skills/bundled/software-development/software-development-debugging-hermes-tui-commands.md +++ /dev/null @@ -1,172 +0,0 @@ ---- -title: "Debugging Hermes Tui Commands — Debug Hermes TUI slash commands: Python, gateway, Ink UI" -sidebar_label: "Debugging Hermes Tui Commands" -description: "Debug Hermes TUI slash commands: Python, gateway, Ink UI" ---- - -{/* This page is auto-generated from the skill's SKILL.md by website/scripts/generate-skill-docs.py. Edit the source SKILL.md, not this page. */} - -# Debugging Hermes Tui Commands - -Debug Hermes TUI slash commands: Python, gateway, Ink UI. - -## Skill metadata - -| | | -|---|---| -| Source | Bundled (installed by default) | -| Path | `skills/software-development/debugging-hermes-tui-commands` | -| Version | `1.0.0` | -| Author | Hermes Agent | -| License | MIT | -| Platforms | linux, macos, windows | -| Tags | `debugging`, `hermes-agent`, `tui`, `slash-commands`, `typescript`, `python` | -| Related skills | [`python-debugpy`](/docs/user-guide/skills/bundled/software-development/software-development-python-debugpy), [`node-inspect-debugger`](/docs/user-guide/skills/bundled/software-development/software-development-node-inspect-debugger), [`systematic-debugging`](/docs/user-guide/skills/bundled/software-development/software-development-systematic-debugging) | - -## Reference: full SKILL.md - -:::info -The following is the complete skill definition that Hermes loads when this skill is triggered. This is what the agent sees as instructions when the skill is active. -::: - -# Debugging Hermes TUI Slash Commands - -## Overview - -Hermes slash commands span three layers — Python command registry, tui_gateway JSON-RPC bridge, and the Ink/TypeScript frontend. When a command misbehaves (missing from autocomplete, works in CLI but not TUI, config persists but UI doesn't update), the bug is almost always one layer being out of sync with another. - -Use this skill when you encounter issues with slash commands in the Hermes TUI, particularly when commands aren't showing in autocomplete, aren't working properly in the TUI, or need to be added/updated. - -## When to Use - -- A slash command exists in one part of the codebase but doesn't work fully -- A command needs to be added to both backend and frontend -- Command autocomplete isn't working for specific commands -- Command behavior is inconsistent between CLI and TUI -- A command persists config but doesn't apply live in the TUI - -## Architecture Overview - -<!-- ascii-guard-ignore --> -``` -Python backend (hermes_cli/commands.py) <- canonical COMMAND_REGISTRY - │ - ▼ -TUI gateway (tui_gateway/server.py) <- slash.exec / command.dispatch - │ - ▼ -TUI frontend (ui-tui/src/app/slash/) <- local handlers + fallthrough -``` -<!-- ascii-guard-ignore-end --> - -Command definitions must be registered consistently across Python and TypeScript to work properly. The Python `COMMAND_REGISTRY` is the source of truth for: CLI dispatch, gateway help, Telegram BotCommand menu, Slack subcommand map, and autocomplete data shipped to Ink. - -## Investigation Steps - -1. **Check if the command exists in the TUI frontend:** - ```bash - search_files --pattern "/commandname" --file_glob "*.ts" --path ui-tui/ - search_files --pattern "/commandname" --file_glob "*.tsx" --path ui-tui/ - ``` - -2. **Examine the TUI command definition:** - ```bash - read_file ui-tui/src/app/slash/commands/core.ts - # If not there: - search_files --pattern "commandname" --path ui-tui/src/app/slash/commands --target files - ``` - -3. **Check if the command exists in the Python backend:** - ```bash - search_files --pattern "CommandDef" --file_glob "*.py" --path hermes_cli/ - search_files --pattern "commandname" --path hermes_cli/commands.py --context 3 - ``` - -4. **Examine the gateway implementation:** - ```bash - search_files --pattern "complete.slash|slash.exec" --path tui_gateway/ - ``` - -## Fix: Missing Command Autocomplete - -If a command exists in the TUI but doesn't show in autocomplete: - -1. Add a `CommandDef` entry to `COMMAND_REGISTRY` in `hermes_cli/commands.py`: - ```python - CommandDef("commandname", "Description of the command", "Session", - cli_only=True, aliases=("alias",), - args_hint="[arg1|arg2|arg3]", - subcommands=("arg1", "arg2", "arg3")), - ``` - -2. Pick `cli_only` vs gateway availability carefully: - - `cli_only=True` — only in the interactive CLI/TUI - - `gateway_only=True` — only in messaging platforms - - neither — available everywhere - - `gateway_config_gate="display.foo"` — config-gated availability in the gateway - -3. Ensure `subcommands` matches the expected tab-completion options shown by the TUI. - -4. If the command runs server-side, add a handler in `HermesCLI.process_command()` in `cli.py`: - ```python - elif canonical == "commandname": - self._handle_commandname(cmd_original) - ``` - -5. For gateway-available commands, add a handler in `gateway/run.py`: - ```python - if canonical == "commandname": - return await self._handle_commandname(event) - ``` - -## Common Issues - -1. **Command shows in TUI but not in autocomplete.** The command is defined in the TUI codebase but missing from `COMMAND_REGISTRY` in `hermes_cli/commands.py`. Autocomplete data ships from Python. - -2. **Command shows in autocomplete but doesn't work.** Check the command handler in `tui_gateway/server.py` and the frontend handler in `ui-tui/src/app/createSlashHandler.ts`. If the command is local-only in Ink, it must be handled in `app.tsx` built-in branch; otherwise it falls through to `slash.exec` and must have a Python handler. - -3. **Command behavior differs between CLI and TUI.** The command might have different implementations. Check both `cli.py::process_command` and the TUI's local handler. Local TUI handlers take precedence over gateway dispatch. - -4. **Command persists config but doesn't apply live.** For TUI-local commands, updating `config.set` is not enough. Also patch the relevant nanostore state immediately (usually `patchUiState(...)`) and pass any new state through rendering components. Example: `/details collapsed` must update live detail visibility, not just save `details_mode`; in-session global `/details <mode>` may need a separate command-override flag so live commands can override built-in section defaults while startup/config sync preserves default-expanded thinking/tools behavior. - -5. **Gateway dispatch silently ignores the command.** The gateway only dispatches commands it knows about. Check `GATEWAY_KNOWN_COMMANDS` (derived from `COMMAND_REGISTRY` automatically) includes the canonical name. If the command is `cli_only` with a `gateway_config_gate`, verify the gated config value is truthy. - -## Debugging Tactics - -When surface-level inspection doesn't reveal the bug: - -- **Python side hangs or misbehaves:** use the `python-debugpy` skill to break inside `_SlashWorker.exec` or the command handler. `remote-pdb` set at the handler entry is the fastest path. -- **Ink side not reacting:** use the `node-inspect-debugger` skill to break in `app.tsx`'s slash dispatch or the local command branch. `sb('dist/app.js', <line>)` after `npm run build`. -- **Registry mismatch / unclear which side is wrong:** compare the canonical `COMMAND_REGISTRY` entry against the TUI's local command list side-by-side. - -## Pitfalls - -- Don't forget to set the appropriate category for the command in `CommandDef` (e.g., "Session", "Configuration", "Tools & Skills", "Info", "Exit") -- Make sure any aliases are properly registered in the `aliases` tuple — no other file changes are needed, everything downstream (Telegram menu, Slack mapping, autocomplete, help) derives from it -- For commands with subcommands, ensure the `subcommands` tuple in `CommandDef` matches what's in the TUI code -- `cli_only=True` commands won't work in gateway/messaging platforms — unless you add a `gateway_config_gate` and the gate is truthy -- After adding live UI state, search every consumer of the old prop/helper and thread the new state through all render paths, not just the active streaming path. TUI detail rendering has at least two important paths: live `StreamingAssistant`/`ToolTrail` and transcript/pending `MessageLine` rows. A `/clean` pass should explicitly check both. -- Rebuild the TUI (`npm --prefix ui-tui run build`) before testing — tsx watch mode may lag on first launch - -## Verification - -After fixing: - -1. Rebuild the TUI: - ```bash - cd /home/bb/hermes-agent && npm --prefix ui-tui run build - ``` - -2. Run the TUI and test the command: - ```bash - hermes --tui - ``` - -3. Type `/` and verify the command appears in autocomplete suggestions with the expected description and args hint. - -4. Execute the command and confirm: - - Expected behavior fires - - Any persisted config updates correctly (`read_file ~/.hermes/config.yaml`) - - Live UI state reflects the change immediately (not just after restart) - -5. If the command is also gateway-available, test it from at least one messaging platform (or run the gateway tests: `scripts/run_tests.sh tests/gateway/`). diff --git a/website/docs/user-guide/skills/bundled/software-development/software-development-hermes-agent-skill-authoring.md b/website/docs/user-guide/skills/bundled/software-development/software-development-hermes-agent-skill-authoring.md index dcca5752b..10183a9a2 100644 --- a/website/docs/user-guide/skills/bundled/software-development/software-development-hermes-agent-skill-authoring.md +++ b/website/docs/user-guide/skills/bundled/software-development/software-development-hermes-agent-skill-authoring.md @@ -21,7 +21,7 @@ Author in-repo SKILL.md: frontmatter, validator, structure. | License | MIT | | Platforms | linux, macos, windows | | Tags | `skills`, `authoring`, `hermes-agent`, `conventions`, `skill-md` | -| Related skills | [`writing-plans`](/docs/user-guide/skills/bundled/software-development/software-development-writing-plans), [`requesting-code-review`](/docs/user-guide/skills/bundled/software-development/software-development-requesting-code-review) | +| Related skills | [`plan`](/docs/user-guide/skills/bundled/software-development/software-development-plan), [`requesting-code-review`](/docs/user-guide/skills/bundled/software-development/software-development-requesting-code-review) | ## Reference: full SKILL.md diff --git a/website/docs/user-guide/skills/bundled/software-development/software-development-plan.md b/website/docs/user-guide/skills/bundled/software-development/software-development-plan.md index 254f7bc4f..36d390bd2 100644 --- a/website/docs/user-guide/skills/bundled/software-development/software-development-plan.md +++ b/website/docs/user-guide/skills/bundled/software-development/software-development-plan.md @@ -1,14 +1,14 @@ --- -title: "Plan — Plan mode: write markdown plan to" +title: "Plan — Plan mode: write an actionable markdown plan to" sidebar_label: "Plan" -description: "Plan mode: write markdown plan to" +description: "Plan mode: write an actionable markdown plan to" --- {/* This page is auto-generated from the skill's SKILL.md by website/scripts/generate-skill-docs.py. Edit the source SKILL.md, not this page. */} # Plan -Plan mode: write markdown plan to .hermes/plans/, no exec. +Plan mode: write an actionable markdown plan to .hermes/plans/, no execution. Bite-sized tasks, exact paths, complete code. ## Skill metadata @@ -16,12 +16,12 @@ Plan mode: write markdown plan to .hermes/plans/, no exec. |---|---| | Source | Bundled (installed by default) | | Path | `skills/software-development/plan` | -| Version | `1.0.0` | -| Author | Hermes Agent | +| Version | `2.0.0` | +| Author | Hermes Agent (writing-craft adapted from obra/superpowers) | | License | MIT | | Platforms | linux, macos, windows | -| Tags | `planning`, `plan-mode`, `implementation`, `workflow` | -| Related skills | [`writing-plans`](/docs/user-guide/skills/bundled/software-development/software-development-writing-plans), [`subagent-driven-development`](/docs/user-guide/skills/bundled/software-development/software-development-subagent-driven-development) | +| Tags | `planning`, `plan-mode`, `implementation`, `workflow`, `design`, `documentation` | +| Related skills | [`subagent-driven-development`](/docs/user-guide/skills/optional/software-development/software-development-subagent-driven-development), [`test-driven-development`](/docs/user-guide/skills/bundled/software-development/software-development-test-driven-development), [`requesting-code-review`](/docs/user-guide/skills/bundled/software-development/software-development-requesting-code-review) | ## Reference: full SKILL.md @@ -74,3 +74,283 @@ If not, create a sensible timestamped filename yourself under `.hermes/plans/`. - If no explicit instruction accompanies `/plan`, infer the task from the current conversation context. - If it is genuinely underspecified, ask a brief clarifying question instead of guessing. - After saving the plan, reply briefly with what you planned and the saved path. + +--- + +# Writing the Plan Well + +The rest of this skill is the craft of authoring a *good* implementation plan — the content that goes inside the markdown file above. + +## Overview + +Write comprehensive implementation plans assuming the implementer has zero context for the codebase and questionable taste. Document everything they need: which files to touch, complete code, testing commands, docs to check, how to verify. Give them bite-sized tasks. DRY. YAGNI. TDD. Frequent commits. + +Assume the implementer is a skilled developer but knows almost nothing about the toolset or problem domain. Assume they don't know good test design very well. + +**Core principle:** A good plan makes implementation obvious. If someone has to guess, the plan is incomplete. + +## When a Full Implementation Plan Helps + +**Always use before:** +- Implementing multi-step features +- Breaking down complex requirements +- Delegating to subagents via subagent-driven-development + +**Don't skip when:** +- Feature seems simple (assumptions cause bugs) +- You plan to implement it yourself (future you needs guidance) +- Working alone (documentation matters) + +## Bite-Sized Task Granularity + +**Each task = 2-5 minutes of focused work.** + +Every step is one action: +- "Write the failing test" — step +- "Run it to make sure it fails" — step +- "Implement the minimal code to make the test pass" — step +- "Run the tests and make sure they pass" — step +- "Commit" — step + +**Too big:** +```markdown +### Task 1: Build authentication system +[50 lines of code across 5 files] +``` + +**Right size:** +```markdown +### Task 1: Create User model with email field +[10 lines, 1 file] + +### Task 2: Add password hash field to User +[8 lines, 1 file] + +### Task 3: Create password hashing utility +[15 lines, 1 file] +``` + +## Plan Document Structure + +### Header (Required) + +Every plan MUST start with: + +```markdown +# [Feature Name] Implementation Plan + +> **For Hermes:** Use subagent-driven-development skill to implement this plan task-by-task. + +**Goal:** [One sentence describing what this builds] + +**Architecture:** [2-3 sentences about approach] + +**Tech Stack:** [Key technologies/libraries] + +--- +``` + +### Task Structure + +Each task follows this format: + +````markdown +### Task N: [Descriptive Name] + +**Objective:** What this task accomplishes (one sentence) + +**Files:** +- Create: `exact/path/to/new_file.py` +- Modify: `exact/path/to/existing.py:45-67` (line numbers if known) +- Test: `tests/path/to/test_file.py` + +**Step 1: Write failing test** + +```python +def test_specific_behavior(): + result = function(input) + assert result == expected +``` + +**Step 2: Run test to verify failure** + +Run: `pytest tests/path/test.py::test_specific_behavior -v` +Expected: FAIL — "function not defined" + +**Step 3: Write minimal implementation** + +```python +def function(input): + return expected +``` + +**Step 4: Run test to verify pass** + +Run: `pytest tests/path/test.py::test_specific_behavior -v` +Expected: PASS + +**Step 5: Commit** + +```bash +git add tests/path/test.py src/path/file.py +git commit -m "feat: add specific feature" +``` +```` + +## Writing Process + +### Step 1: Understand Requirements + +Read and understand: +- Feature requirements +- Design documents or user description +- Acceptance criteria +- Constraints + +### Step 2: Explore the Codebase + +Use Hermes tools to understand the project: + +```python +# Understand project structure +search_files("*.py", target="files", path="src/") + +# Look at similar features +search_files("similar_pattern", path="src/", file_glob="*.py") + +# Check existing tests +search_files("*.py", target="files", path="tests/") + +# Read key files +read_file("src/app.py") +``` + +### Step 3: Design Approach + +Decide: +- Architecture pattern +- File organization +- Dependencies needed +- Testing strategy + +### Step 4: Write Tasks + +Create tasks in order: +1. Setup/infrastructure +2. Core functionality (TDD for each) +3. Edge cases +4. Integration +5. Cleanup/documentation + +### Step 5: Add Complete Details + +For each task, include: +- **Exact file paths** (not "the config file" but `src/config/settings.py`) +- **Complete code examples** (not "add validation" but the actual code) +- **Exact commands** with expected output +- **Verification steps** that prove the task works + +### Step 6: Review the Plan + +Check: +- [ ] Tasks are sequential and logical +- [ ] Each task is bite-sized (2-5 min) +- [ ] File paths are exact +- [ ] Code examples are complete (copy-pasteable) +- [ ] Commands are exact with expected output +- [ ] No missing context +- [ ] DRY, YAGNI, TDD principles applied + +## Principles + +### DRY (Don't Repeat Yourself) + +**Bad:** Copy-paste validation in 3 places +**Good:** Extract validation function, use everywhere + +### YAGNI (You Aren't Gonna Need It) + +**Bad:** Add "flexibility" for future requirements +**Good:** Implement only what's needed now + +```python +# Bad — YAGNI violation +class User: + def __init__(self, name, email): + self.name = name + self.email = email + self.preferences = {} # Not needed yet! + self.metadata = {} # Not needed yet! + +# Good — YAGNI +class User: + def __init__(self, name, email): + self.name = name + self.email = email +``` + +### TDD (Test-Driven Development) + +Every task that produces code should include the full TDD cycle: +1. Write failing test +2. Run to verify failure +3. Write minimal code +4. Run to verify pass + +See `test-driven-development` skill for details. + +### Frequent Commits + +Commit after every task: +```bash +git add [files] +git commit -m "type: description" +``` + +## Common Mistakes + +### Vague Tasks + +**Bad:** "Add authentication" +**Good:** "Create User model with email and password_hash fields" + +### Incomplete Code + +**Bad:** "Step 1: Add validation function" +**Good:** "Step 1: Add validation function" followed by the complete function code + +### Missing Verification + +**Bad:** "Step 3: Test it works" +**Good:** "Step 3: Run `pytest tests/test_auth.py -v`, expected: 3 passed" + +### Missing File Paths + +**Bad:** "Create the model file" +**Good:** "Create: `src/models/user.py`" + +## Execution Handoff + +After saving the plan, offer the execution approach: + +**"Plan complete and saved. Ready to execute using subagent-driven-development — I'll dispatch a fresh subagent per task with two-stage review (spec compliance then code quality). Shall I proceed?"** + +When executing, use the `subagent-driven-development` skill: +- Fresh `delegate_task` per task with full context +- Spec compliance review after each task +- Code quality review after spec passes +- Proceed only when both reviews approve + +## Remember + +``` +Bite-sized tasks (2-5 min each) +Exact file paths +Complete code (copy-pasteable) +Exact commands with expected output +Verification steps +DRY, YAGNI, TDD +Frequent commits +``` + +**A good plan makes implementation obvious.** diff --git a/website/docs/user-guide/skills/bundled/software-development/software-development-requesting-code-review.md b/website/docs/user-guide/skills/bundled/software-development/software-development-requesting-code-review.md index 30a0be661..66100e83f 100644 --- a/website/docs/user-guide/skills/bundled/software-development/software-development-requesting-code-review.md +++ b/website/docs/user-guide/skills/bundled/software-development/software-development-requesting-code-review.md @@ -21,7 +21,7 @@ Pre-commit review: security scan, quality gates, auto-fix. | License | MIT | | Platforms | linux, macos, windows | | Tags | `code-review`, `security`, `verification`, `quality`, `pre-commit`, `auto-fix` | -| Related skills | [`subagent-driven-development`](/docs/user-guide/skills/bundled/software-development/software-development-subagent-driven-development), [`writing-plans`](/docs/user-guide/skills/bundled/software-development/software-development-writing-plans), [`test-driven-development`](/docs/user-guide/skills/bundled/software-development/software-development-test-driven-development), [`github-code-review`](/docs/user-guide/skills/bundled/github/github-github-code-review) | +| Related skills | [`subagent-driven-development`](/docs/user-guide/skills/optional/software-development/software-development-subagent-driven-development), [`plan`](/docs/user-guide/skills/bundled/software-development/software-development-plan), [`test-driven-development`](/docs/user-guide/skills/bundled/software-development/software-development-test-driven-development), [`github-code-review`](/docs/user-guide/skills/bundled/github/github-github-code-review) | ## Reference: full SKILL.md @@ -284,7 +284,7 @@ The two-stage review (spec compliance + code quality) uses this pipeline. **test-driven-development:** This pipeline verifies TDD discipline was followed — tests exist, tests pass, no regressions. -**writing-plans:** Validates implementation matches the plan requirements. +**plan:** Validates implementation matches the plan requirements. ## Pitfalls diff --git a/website/docs/user-guide/skills/bundled/software-development/software-development-spike.md b/website/docs/user-guide/skills/bundled/software-development/software-development-spike.md index 695a6cbde..56c0954b6 100644 --- a/website/docs/user-guide/skills/bundled/software-development/software-development-spike.md +++ b/website/docs/user-guide/skills/bundled/software-development/software-development-spike.md @@ -21,7 +21,7 @@ Throwaway experiments to validate an idea before build. | License | MIT | | Platforms | linux, macos, windows | | Tags | `spike`, `prototype`, `experiment`, `feasibility`, `throwaway`, `exploration`, `research`, `planning`, `mvp`, `proof-of-concept` | -| Related skills | [`sketch`](/docs/user-guide/skills/bundled/creative/creative-sketch), [`writing-plans`](/docs/user-guide/skills/bundled/software-development/software-development-writing-plans), [`subagent-driven-development`](/docs/user-guide/skills/bundled/software-development/software-development-subagent-driven-development), [`plan`](/docs/user-guide/skills/bundled/software-development/software-development-plan) | +| Related skills | [`sketch`](/docs/user-guide/skills/bundled/creative/creative-sketch), [`subagent-driven-development`](/docs/user-guide/skills/optional/software-development/software-development-subagent-driven-development), [`plan`](/docs/user-guide/skills/bundled/software-development/software-development-plan) | ## Reference: full SKILL.md @@ -38,7 +38,7 @@ Load this when the user says things like "let me try this", "I want to see if X ## When NOT to use this - The answer is knowable from docs or reading code — just do research, don't build -- The work is production path — use `writing-plans` / `plan` instead +- The work is production path — use the `plan` skill instead - The idea is already validated — jump straight to implementation ## If the user has the full GSD system installed diff --git a/website/docs/user-guide/skills/bundled/software-development/software-development-systematic-debugging.md b/website/docs/user-guide/skills/bundled/software-development/software-development-systematic-debugging.md index e86f46c9a..19c5272d7 100644 --- a/website/docs/user-guide/skills/bundled/software-development/software-development-systematic-debugging.md +++ b/website/docs/user-guide/skills/bundled/software-development/software-development-systematic-debugging.md @@ -21,7 +21,7 @@ description: "4-phase root cause debugging: understand bugs before fixing" | License | MIT | | Platforms | linux, macos, windows | | Tags | `debugging`, `troubleshooting`, `problem-solving`, `root-cause`, `investigation` | -| Related skills | [`test-driven-development`](/docs/user-guide/skills/bundled/software-development/software-development-test-driven-development), [`writing-plans`](/docs/user-guide/skills/bundled/software-development/software-development-writing-plans), [`subagent-driven-development`](/docs/user-guide/skills/bundled/software-development/software-development-subagent-driven-development) | +| Related skills | [`test-driven-development`](/docs/user-guide/skills/bundled/software-development/software-development-test-driven-development), [`plan`](/docs/user-guide/skills/bundled/software-development/software-development-plan), [`subagent-driven-development`](/docs/user-guide/skills/optional/software-development/software-development-subagent-driven-development) | ## Reference: full SKILL.md diff --git a/website/docs/user-guide/skills/bundled/software-development/software-development-test-driven-development.md b/website/docs/user-guide/skills/bundled/software-development/software-development-test-driven-development.md index 5b424f3ad..db79e71f6 100644 --- a/website/docs/user-guide/skills/bundled/software-development/software-development-test-driven-development.md +++ b/website/docs/user-guide/skills/bundled/software-development/software-development-test-driven-development.md @@ -21,7 +21,7 @@ TDD: enforce RED-GREEN-REFACTOR, tests before code. | License | MIT | | Platforms | linux, macos, windows | | Tags | `testing`, `tdd`, `development`, `quality`, `red-green-refactor` | -| Related skills | [`systematic-debugging`](/docs/user-guide/skills/bundled/software-development/software-development-systematic-debugging), [`writing-plans`](/docs/user-guide/skills/bundled/software-development/software-development-writing-plans), [`subagent-driven-development`](/docs/user-guide/skills/bundled/software-development/software-development-subagent-driven-development) | +| Related skills | [`systematic-debugging`](/docs/user-guide/skills/bundled/software-development/software-development-systematic-debugging), [`plan`](/docs/user-guide/skills/bundled/software-development/software-development-plan), [`subagent-driven-development`](/docs/user-guide/skills/optional/software-development/software-development-subagent-driven-development) | ## Reference: full SKILL.md diff --git a/website/docs/user-guide/skills/bundled/software-development/software-development-writing-plans.md b/website/docs/user-guide/skills/bundled/software-development/software-development-writing-plans.md deleted file mode 100644 index 6dc0a5298..000000000 --- a/website/docs/user-guide/skills/bundled/software-development/software-development-writing-plans.md +++ /dev/null @@ -1,315 +0,0 @@ ---- -title: "Writing Plans — Write implementation plans: bite-sized tasks, paths, code" -sidebar_label: "Writing Plans" -description: "Write implementation plans: bite-sized tasks, paths, code" ---- - -{/* This page is auto-generated from the skill's SKILL.md by website/scripts/generate-skill-docs.py. Edit the source SKILL.md, not this page. */} - -# Writing Plans - -Write implementation plans: bite-sized tasks, paths, code. - -## Skill metadata - -| | | -|---|---| -| Source | Bundled (installed by default) | -| Path | `skills/software-development/writing-plans` | -| Version | `1.1.0` | -| Author | Hermes Agent (adapted from obra/superpowers) | -| License | MIT | -| Platforms | linux, macos, windows | -| Tags | `planning`, `design`, `implementation`, `workflow`, `documentation` | -| Related skills | [`subagent-driven-development`](/docs/user-guide/skills/bundled/software-development/software-development-subagent-driven-development), [`test-driven-development`](/docs/user-guide/skills/bundled/software-development/software-development-test-driven-development), [`requesting-code-review`](/docs/user-guide/skills/bundled/software-development/software-development-requesting-code-review) | - -## Reference: full SKILL.md - -:::info -The following is the complete skill definition that Hermes loads when this skill is triggered. This is what the agent sees as instructions when the skill is active. -::: - -# Writing Implementation Plans - -## Overview - -Write comprehensive implementation plans assuming the implementer has zero context for the codebase and questionable taste. Document everything they need: which files to touch, complete code, testing commands, docs to check, how to verify. Give them bite-sized tasks. DRY. YAGNI. TDD. Frequent commits. - -Assume the implementer is a skilled developer but knows almost nothing about the toolset or problem domain. Assume they don't know good test design very well. - -**Core principle:** A good plan makes implementation obvious. If someone has to guess, the plan is incomplete. - -## When to Use - -**Always use before:** -- Implementing multi-step features -- Breaking down complex requirements -- Delegating to subagents via subagent-driven-development - -**Don't skip when:** -- Feature seems simple (assumptions cause bugs) -- You plan to implement it yourself (future you needs guidance) -- Working alone (documentation matters) - -## Bite-Sized Task Granularity - -**Each task = 2-5 minutes of focused work.** - -Every step is one action: -- "Write the failing test" — step -- "Run it to make sure it fails" — step -- "Implement the minimal code to make the test pass" — step -- "Run the tests and make sure they pass" — step -- "Commit" — step - -**Too big:** -```markdown -### Task 1: Build authentication system -[50 lines of code across 5 files] -``` - -**Right size:** -```markdown -### Task 1: Create User model with email field -[10 lines, 1 file] - -### Task 2: Add password hash field to User -[8 lines, 1 file] - -### Task 3: Create password hashing utility -[15 lines, 1 file] -``` - -## Plan Document Structure - -### Header (Required) - -Every plan MUST start with: - -```markdown -# [Feature Name] Implementation Plan - -> **For Hermes:** Use subagent-driven-development skill to implement this plan task-by-task. - -**Goal:** [One sentence describing what this builds] - -**Architecture:** [2-3 sentences about approach] - -**Tech Stack:** [Key technologies/libraries] - ---- -``` - -### Task Structure - -Each task follows this format: - -````markdown -### Task N: [Descriptive Name] - -**Objective:** What this task accomplishes (one sentence) - -**Files:** -- Create: `exact/path/to/new_file.py` -- Modify: `exact/path/to/existing.py:45-67` (line numbers if known) -- Test: `tests/path/to/test_file.py` - -**Step 1: Write failing test** - -```python -def test_specific_behavior(): - result = function(input) - assert result == expected -``` - -**Step 2: Run test to verify failure** - -Run: `pytest tests/path/test.py::test_specific_behavior -v` -Expected: FAIL — "function not defined" - -**Step 3: Write minimal implementation** - -```python -def function(input): - return expected -``` - -**Step 4: Run test to verify pass** - -Run: `pytest tests/path/test.py::test_specific_behavior -v` -Expected: PASS - -**Step 5: Commit** - -```bash -git add tests/path/test.py src/path/file.py -git commit -m "feat: add specific feature" -``` -```` - -## Writing Process - -### Step 1: Understand Requirements - -Read and understand: -- Feature requirements -- Design documents or user description -- Acceptance criteria -- Constraints - -### Step 2: Explore the Codebase - -Use Hermes tools to understand the project: - -```python -# Understand project structure -search_files("*.py", target="files", path="src/") - -# Look at similar features -search_files("similar_pattern", path="src/", file_glob="*.py") - -# Check existing tests -search_files("*.py", target="files", path="tests/") - -# Read key files -read_file("src/app.py") -``` - -### Step 3: Design Approach - -Decide: -- Architecture pattern -- File organization -- Dependencies needed -- Testing strategy - -### Step 4: Write Tasks - -Create tasks in order: -1. Setup/infrastructure -2. Core functionality (TDD for each) -3. Edge cases -4. Integration -5. Cleanup/documentation - -### Step 5: Add Complete Details - -For each task, include: -- **Exact file paths** (not "the config file" but `src/config/settings.py`) -- **Complete code examples** (not "add validation" but the actual code) -- **Exact commands** with expected output -- **Verification steps** that prove the task works - -### Step 6: Review the Plan - -Check: -- [ ] Tasks are sequential and logical -- [ ] Each task is bite-sized (2-5 min) -- [ ] File paths are exact -- [ ] Code examples are complete (copy-pasteable) -- [ ] Commands are exact with expected output -- [ ] No missing context -- [ ] DRY, YAGNI, TDD principles applied - -### Step 7: Save the Plan - -```bash -mkdir -p docs/plans -# Save plan to docs/plans/YYYY-MM-DD-feature-name.md -git add docs/plans/ -git commit -m "docs: add implementation plan for [feature]" -``` - -## Principles - -### DRY (Don't Repeat Yourself) - -**Bad:** Copy-paste validation in 3 places -**Good:** Extract validation function, use everywhere - -### YAGNI (You Aren't Gonna Need It) - -**Bad:** Add "flexibility" for future requirements -**Good:** Implement only what's needed now - -```python -# Bad — YAGNI violation -class User: - def __init__(self, name, email): - self.name = name - self.email = email - self.preferences = {} # Not needed yet! - self.metadata = {} # Not needed yet! - -# Good — YAGNI -class User: - def __init__(self, name, email): - self.name = name - self.email = email -``` - -### TDD (Test-Driven Development) - -Every task that produces code should include the full TDD cycle: -1. Write failing test -2. Run to verify failure -3. Write minimal code -4. Run to verify pass - -See `test-driven-development` skill for details. - -### Frequent Commits - -Commit after every task: -```bash -git add [files] -git commit -m "type: description" -``` - -## Common Mistakes - -### Vague Tasks - -**Bad:** "Add authentication" -**Good:** "Create User model with email and password_hash fields" - -### Incomplete Code - -**Bad:** "Step 1: Add validation function" -**Good:** "Step 1: Add validation function" followed by the complete function code - -### Missing Verification - -**Bad:** "Step 3: Test it works" -**Good:** "Step 3: Run `pytest tests/test_auth.py -v`, expected: 3 passed" - -### Missing File Paths - -**Bad:** "Create the model file" -**Good:** "Create: `src/models/user.py`" - -## Execution Handoff - -After saving the plan, offer the execution approach: - -**"Plan complete and saved. Ready to execute using subagent-driven-development — I'll dispatch a fresh subagent per task with two-stage review (spec compliance then code quality). Shall I proceed?"** - -When executing, use the `subagent-driven-development` skill: -- Fresh `delegate_task` per task with full context -- Spec compliance review after each task -- Code quality review after spec passes -- Proceed only when both reviews approve - -## Remember - -``` -Bite-sized tasks (2-5 min each) -Exact file paths -Complete code (copy-pasteable) -Exact commands with expected output -Verification steps -DRY, YAGNI, TDD -Frequent commits -``` - -**A good plan makes implementation obvious.** diff --git a/website/docs/user-guide/skills/bundled/creative/creative-baoyu-article-illustrator.md b/website/docs/user-guide/skills/optional/creative/creative-baoyu-article-illustrator.md similarity index 84% rename from website/docs/user-guide/skills/bundled/creative/creative-baoyu-article-illustrator.md rename to website/docs/user-guide/skills/optional/creative/creative-baoyu-article-illustrator.md index 7c179f6bd..2fbe498b7 100644 --- a/website/docs/user-guide/skills/bundled/creative/creative-baoyu-article-illustrator.md +++ b/website/docs/user-guide/skills/optional/creative/creative-baoyu-article-illustrator.md @@ -14,8 +14,8 @@ Article illustrations: type × style × palette consistency. | | | |---|---| -| Source | Bundled (installed by default) | -| Path | `skills/creative/baoyu-article-illustrator` | +| Source | Optional — install with `hermes skills install official/creative/baoyu-article-illustrator` | +| Path | `optional-skills/creative/baoyu-article-illustrator` | | Version | `1.57.0` | | Author | 宝玉 (JimLiu) | | License | MIT | @@ -48,7 +48,7 @@ Trigger this skill when the user asks to illustrate an article, add images to an Combine freely: `type=infographic, style=vector-illustration, palette=macaron`. -Or use presets: `edu-visual` → type + style + palette in one shot. See [style-presets.md](https://github.com/NousResearch/hermes-agent/blob/main/skills/creative/baoyu-article-illustrator/references/style-presets.md). +Or use presets: `edu-visual` → type + style + palette in one shot. See [style-presets.md](https://github.com/NousResearch/hermes-agent/blob/main/optional-skills/creative/baoyu-article-illustrator/references/style-presets.md). ## Types @@ -63,7 +63,7 @@ Or use presets: `edu-visual` → type + style + palette in one shot. See [style- ## Styles -See [references/styles.md](https://github.com/NousResearch/hermes-agent/blob/main/skills/creative/baoyu-article-illustrator/references/styles.md) for Core Styles, the full gallery, and Type × Style compatibility. +See [references/styles.md](https://github.com/NousResearch/hermes-agent/blob/main/optional-skills/creative/baoyu-article-illustrator/references/styles.md) for Core Styles, the full gallery, and Type × Style compatibility. ## Output Structure @@ -116,7 +116,7 @@ If the user supplies reference images (paths pasted inline, attachments, or a UR 2. **Do not** try to copy the binary via `write_file` / `read_file` — those are text-only. If you want a local copy for the record, use `terminal` (`cp "$src" "{output-dir}/references/NN-ref-{slug}.{ext}"`). The skill itself never needs to read the binary; it works off the vision description. 3. Since `image_generate` doesn't take image inputs, the vision description is what gets embedded in prompts during Step 5. -Full procedures: [references/workflow.md](https://github.com/NousResearch/hermes-agent/blob/main/skills/creative/baoyu-article-illustrator/references/workflow.md#step-1-detect-reference-images). +Full procedures: [references/workflow.md](https://github.com/NousResearch/hermes-agent/blob/main/optional-skills/creative/baoyu-article-illustrator/references/workflow.md#step-1-detect-reference-images). ### Step 2: Analyze @@ -129,7 +129,7 @@ Full procedures: [references/workflow.md](https://github.com/NousResearch/hermes Read source (file path → `read_file`, or pasted text) and write the analysis to `{output-dir}/analysis.md` using `write_file`. -Full procedures: [references/workflow.md](https://github.com/NousResearch/hermes-agent/blob/main/skills/creative/baoyu-article-illustrator/references/workflow.md#step-2-analyze). +Full procedures: [references/workflow.md](https://github.com/NousResearch/hermes-agent/blob/main/optional-skills/creative/baoyu-article-illustrator/references/workflow.md#step-2-analyze). ### Step 3: Confirm Settings @@ -145,7 +145,7 @@ Use the `clarify` tool. Since `clarify` handles one question at a time, ask the Don't ask more than 2-3 `clarify` questions in a row. If the user already specified these in their request, skip entirely. -Full procedures: [references/workflow.md](https://github.com/NousResearch/hermes-agent/blob/main/skills/creative/baoyu-article-illustrator/references/workflow.md#step-3-confirm-settings). +Full procedures: [references/workflow.md](https://github.com/NousResearch/hermes-agent/blob/main/optional-skills/creative/baoyu-article-illustrator/references/workflow.md#step-3-confirm-settings). ### Step 4: Generate Outline → `outline.md` @@ -159,7 +159,7 @@ Save `{output-dir}/outline.md` using `write_file` with frontmatter (type, densit **Filename**: 01-infographic-concept-name.png ``` -Full template: [references/workflow.md](https://github.com/NousResearch/hermes-agent/blob/main/skills/creative/baoyu-article-illustrator/references/workflow.md#step-4-generate-outline). +Full template: [references/workflow.md](https://github.com/NousResearch/hermes-agent/blob/main/optional-skills/creative/baoyu-article-illustrator/references/workflow.md#step-4-generate-outline). ### Step 5: Generate Prompts @@ -167,7 +167,7 @@ Full template: [references/workflow.md](https://github.com/NousResearch/hermes-a For each illustration: -1. Create a prompt file per [references/prompt-construction.md](https://github.com/NousResearch/hermes-agent/blob/main/skills/creative/baoyu-article-illustrator/references/prompt-construction.md). +1. Create a prompt file per [references/prompt-construction.md](https://github.com/NousResearch/hermes-agent/blob/main/optional-skills/creative/baoyu-article-illustrator/references/prompt-construction.md). 2. Save to `{output-dir}/prompts/NN-{type}-{slug}.md` using `write_file` with YAML frontmatter. 3. Prompts MUST use type-specific templates with structured sections (ZONES / LABELS / COLORS / STYLE / ASPECT). 4. LABELS MUST include article-specific data: actual numbers, terms, metrics, quotes. @@ -186,7 +186,7 @@ Note: the underlying image-generation backend is user-configured (default: FAL F ### Step 7: Finalize -Insert `![description](https://github.com/NousResearch/hermes-agent/blob/main/skills/creative/baoyu-article-illustrator/{relative-path}/NN-{type}-{slug}.png)` after the corresponding paragraph. Alt text: concise description in the article's language. +Insert `![description](https://github.com/NousResearch/hermes-agent/blob/main/optional-skills/creative/baoyu-article-illustrator/{relative-path}/NN-{type}-{slug}.png)` after the corresponding paragraph. Alt text: concise description in the article's language. Report: @@ -208,11 +208,11 @@ Images: X/N generated | File | Content | |------|---------| -| [references/workflow.md](https://github.com/NousResearch/hermes-agent/blob/main/skills/creative/baoyu-article-illustrator/references/workflow.md) | Detailed procedures | -| [references/usage.md](https://github.com/NousResearch/hermes-agent/blob/main/skills/creative/baoyu-article-illustrator/references/usage.md) | Invocation examples | -| [references/styles.md](https://github.com/NousResearch/hermes-agent/blob/main/skills/creative/baoyu-article-illustrator/references/styles.md) | Style gallery + Palette gallery | -| [references/style-presets.md](https://github.com/NousResearch/hermes-agent/blob/main/skills/creative/baoyu-article-illustrator/references/style-presets.md) | Preset shortcuts (type + style + palette) | -| [references/prompt-construction.md](https://github.com/NousResearch/hermes-agent/blob/main/skills/creative/baoyu-article-illustrator/references/prompt-construction.md) | Prompt templates | +| [references/workflow.md](https://github.com/NousResearch/hermes-agent/blob/main/optional-skills/creative/baoyu-article-illustrator/references/workflow.md) | Detailed procedures | +| [references/usage.md](https://github.com/NousResearch/hermes-agent/blob/main/optional-skills/creative/baoyu-article-illustrator/references/usage.md) | Invocation examples | +| [references/styles.md](https://github.com/NousResearch/hermes-agent/blob/main/optional-skills/creative/baoyu-article-illustrator/references/styles.md) | Style gallery + Palette gallery | +| [references/style-presets.md](https://github.com/NousResearch/hermes-agent/blob/main/optional-skills/creative/baoyu-article-illustrator/references/style-presets.md) | Preset shortcuts (type + style + palette) | +| [references/prompt-construction.md](https://github.com/NousResearch/hermes-agent/blob/main/optional-skills/creative/baoyu-article-illustrator/references/prompt-construction.md) | Prompt templates | ## Pitfalls diff --git a/website/docs/user-guide/skills/bundled/creative/creative-baoyu-comic.md b/website/docs/user-guide/skills/optional/creative/creative-baoyu-comic.md similarity index 91% rename from website/docs/user-guide/skills/bundled/creative/creative-baoyu-comic.md rename to website/docs/user-guide/skills/optional/creative/creative-baoyu-comic.md index 28e2acbdd..88fdc93af 100644 --- a/website/docs/user-guide/skills/bundled/creative/creative-baoyu-comic.md +++ b/website/docs/user-guide/skills/optional/creative/creative-baoyu-comic.md @@ -14,8 +14,8 @@ Knowledge comics (知识漫画): educational, biography, tutorial. | | | |---|---| -| Source | Bundled (installed by default) | -| Path | `skills/creative/baoyu-comic` | +| Source | Optional — install with `hermes skills install official/creative/baoyu-comic` | +| Path | `optional-skills/creative/baoyu-comic` | | Version | `1.56.1` | | Author | 宝玉 (JimLiu) | | License | MIT | @@ -89,7 +89,7 @@ Character consistency is driven by **text descriptions** in `characters/characte | Images only | Generate images from existing prompts directory | | Regenerate N | Regenerate specific page(s) only (e.g., `3` or `2,5,8`) | -Details: [references/partial-workflows.md](https://github.com/NousResearch/hermes-agent/blob/main/skills/creative/baoyu-comic/references/partial-workflows.md) +Details: [references/partial-workflows.md](https://github.com/NousResearch/hermes-agent/blob/main/optional-skills/creative/baoyu-comic/references/partial-workflows.md) ### Art, Tone & Preset Catalogue @@ -107,7 +107,7 @@ Details: [references/partial-workflows.md](https://github.com/NousResearch/herme Full rules at `references/presets/<preset>.md` — load the file when a preset is picked. -- **Compatibility matrix** and **content-signal → preset** table live in [references/auto-selection.md](https://github.com/NousResearch/hermes-agent/blob/main/skills/creative/baoyu-comic/references/auto-selection.md). Read it before recommending combinations in Step 2. +- **Compatibility matrix** and **content-signal → preset** table live in [references/auto-selection.md](https://github.com/NousResearch/hermes-agent/blob/main/optional-skills/creative/baoyu-comic/references/auto-selection.md). Read it before recommending combinations in Step 2. ## File Structure @@ -185,7 +185,7 @@ Input → Analyze → [Check Existing?] → [Confirm: Style + Reviews] → Story ### User Questions -Use 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](https://github.com/NousResearch/hermes-agent/blob/main/skills/creative/baoyu-comic/references/workflow.md) for the full Step 2 question set. +Use 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](https://github.com/NousResearch/hermes-agent/blob/main/optional-skills/creative/baoyu-comic/references/workflow.md) for the full Step 2 question set. **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. @@ -221,15 +221,15 @@ Use Hermes' built-in `image_generate` tool for all image rendering. Its schema a **Backup rule**: existing `prompts/…md` and `…png` files → rename with `-backup-YYYYMMDD-HHMMSS` suffix before regenerating. -Full step-by-step workflow (analysis, storyboard, review gates, regeneration variants): [references/workflow.md](https://github.com/NousResearch/hermes-agent/blob/main/skills/creative/baoyu-comic/references/workflow.md). +Full step-by-step workflow (analysis, storyboard, review gates, regeneration variants): [references/workflow.md](https://github.com/NousResearch/hermes-agent/blob/main/optional-skills/creative/baoyu-comic/references/workflow.md). ## References **Core Templates**: -- [analysis-framework.md](https://github.com/NousResearch/hermes-agent/blob/main/skills/creative/baoyu-comic/references/analysis-framework.md) - Deep content analysis -- [character-template.md](https://github.com/NousResearch/hermes-agent/blob/main/skills/creative/baoyu-comic/references/character-template.md) - Character definition format -- [storyboard-template.md](https://github.com/NousResearch/hermes-agent/blob/main/skills/creative/baoyu-comic/references/storyboard-template.md) - Storyboard structure -- [ohmsha-guide.md](https://github.com/NousResearch/hermes-agent/blob/main/skills/creative/baoyu-comic/references/ohmsha-guide.md) - Ohmsha manga specifics +- [analysis-framework.md](https://github.com/NousResearch/hermes-agent/blob/main/optional-skills/creative/baoyu-comic/references/analysis-framework.md) - Deep content analysis +- [character-template.md](https://github.com/NousResearch/hermes-agent/blob/main/optional-skills/creative/baoyu-comic/references/character-template.md) - Character definition format +- [storyboard-template.md](https://github.com/NousResearch/hermes-agent/blob/main/optional-skills/creative/baoyu-comic/references/storyboard-template.md) - Storyboard structure +- [ohmsha-guide.md](https://github.com/NousResearch/hermes-agent/blob/main/optional-skills/creative/baoyu-comic/references/ohmsha-guide.md) - Ohmsha manga specifics **Style Definitions**: - `references/art-styles/` - Art styles (ligne-claire, manga, realistic, ink-brush, chalk, minimalist) @@ -238,9 +238,9 @@ Full step-by-step workflow (analysis, storyboard, review gates, regeneration var - `references/layouts/` - Layouts (standard, cinematic, dense, splash, mixed, webtoon, four-panel) **Workflow**: -- [workflow.md](https://github.com/NousResearch/hermes-agent/blob/main/skills/creative/baoyu-comic/references/workflow.md) - Full workflow details -- [auto-selection.md](https://github.com/NousResearch/hermes-agent/blob/main/skills/creative/baoyu-comic/references/auto-selection.md) - Content signal analysis -- [partial-workflows.md](https://github.com/NousResearch/hermes-agent/blob/main/skills/creative/baoyu-comic/references/partial-workflows.md) - Partial workflow options +- [workflow.md](https://github.com/NousResearch/hermes-agent/blob/main/optional-skills/creative/baoyu-comic/references/workflow.md) - Full workflow details +- [auto-selection.md](https://github.com/NousResearch/hermes-agent/blob/main/optional-skills/creative/baoyu-comic/references/auto-selection.md) - Content signal analysis +- [partial-workflows.md](https://github.com/NousResearch/hermes-agent/blob/main/optional-skills/creative/baoyu-comic/references/partial-workflows.md) - Partial workflow options ## Page Modification diff --git a/website/docs/user-guide/skills/bundled/creative/creative-creative-ideation.md b/website/docs/user-guide/skills/optional/creative/creative-creative-ideation.md similarity index 97% rename from website/docs/user-guide/skills/bundled/creative/creative-creative-ideation.md rename to website/docs/user-guide/skills/optional/creative/creative-creative-ideation.md index 43fe20b1b..0640fb8b4 100644 --- a/website/docs/user-guide/skills/bundled/creative/creative-creative-ideation.md +++ b/website/docs/user-guide/skills/optional/creative/creative-creative-ideation.md @@ -14,8 +14,8 @@ Generate project ideas via creative constraints. | | | |---|---| -| Source | Bundled (installed by default) | -| Path | `skills/creative/creative-ideation` | +| Source | Optional — install with `hermes skills install official/creative/creative-ideation` | +| Path | `optional-skills/creative/creative-ideation` | | Version | `1.0.0` | | Author | SHL0MS | | License | MIT | diff --git a/website/docs/user-guide/skills/bundled/creative/creative-pixel-art.md b/website/docs/user-guide/skills/optional/creative/creative-pixel-art.md similarity index 98% rename from website/docs/user-guide/skills/bundled/creative/creative-pixel-art.md rename to website/docs/user-guide/skills/optional/creative/creative-pixel-art.md index ede496d1b..c2f3d20b2 100644 --- a/website/docs/user-guide/skills/bundled/creative/creative-pixel-art.md +++ b/website/docs/user-guide/skills/optional/creative/creative-pixel-art.md @@ -14,8 +14,8 @@ Pixel art w/ era palettes (NES, Game Boy, PICO-8). | | | |---|---| -| Source | Bundled (installed by default) | -| Path | `skills/creative/pixel-art` | +| Source | Optional — install with `hermes skills install official/creative/pixel-art` | +| Path | `optional-skills/creative/pixel-art` | | Version | `2.0.0` | | Author | dodo-reach | | License | MIT | diff --git a/website/docs/user-guide/skills/bundled/software-development/software-development-hermes-s6-container-supervision.md b/website/docs/user-guide/skills/optional/devops/devops-hermes-s6-container-supervision.md similarity index 98% rename from website/docs/user-guide/skills/bundled/software-development/software-development-hermes-s6-container-supervision.md rename to website/docs/user-guide/skills/optional/devops/devops-hermes-s6-container-supervision.md index 4f35a9a38..08bb06751 100644 --- a/website/docs/user-guide/skills/bundled/software-development/software-development-hermes-s6-container-supervision.md +++ b/website/docs/user-guide/skills/optional/devops/devops-hermes-s6-container-supervision.md @@ -14,11 +14,12 @@ Modify, debug, or extend the s6-overlay supervision tree inside the Hermes Agent | | | |---|---| -| Source | Bundled (installed by default) | -| Path | `skills/software-development/hermes-s6-container-supervision` | +| Source | Optional — install with `hermes skills install official/devops/hermes-s6-container-supervision` | +| Path | `optional-skills/devops/hermes-s6-container-supervision` | | Version | `1.0.0` | | Author | Hermes Agent | | License | MIT | +| Platforms | linux | | Tags | `docker`, `s6`, `supervision`, `gateway`, `profiles` | | Related skills | [`hermes-agent`](/docs/user-guide/skills/bundled/autonomous-ai-agents/autonomous-ai-agents-hermes-agent), `hermes-agent-dev` | diff --git a/website/docs/user-guide/skills/bundled/gaming/gaming-minecraft-modpack-server.md b/website/docs/user-guide/skills/optional/gaming/gaming-minecraft-modpack-server.md similarity index 97% rename from website/docs/user-guide/skills/bundled/gaming/gaming-minecraft-modpack-server.md rename to website/docs/user-guide/skills/optional/gaming/gaming-minecraft-modpack-server.md index f5c042ce0..a4d588f21 100644 --- a/website/docs/user-guide/skills/bundled/gaming/gaming-minecraft-modpack-server.md +++ b/website/docs/user-guide/skills/optional/gaming/gaming-minecraft-modpack-server.md @@ -14,8 +14,8 @@ Host modded Minecraft servers (CurseForge, Modrinth). | | | |---|---| -| Source | Bundled (installed by default) | -| Path | `skills/gaming/minecraft-modpack-server` | +| Source | Optional — install with `hermes skills install official/gaming/minecraft-modpack-server` | +| Path | `optional-skills/gaming/minecraft-modpack-server` | | Platforms | linux, macos | ## Reference: full SKILL.md diff --git a/website/docs/user-guide/skills/bundled/gaming/gaming-pokemon-player.md b/website/docs/user-guide/skills/optional/gaming/gaming-pokemon-player.md similarity index 98% rename from website/docs/user-guide/skills/bundled/gaming/gaming-pokemon-player.md rename to website/docs/user-guide/skills/optional/gaming/gaming-pokemon-player.md index 04cd513d4..fe523b645 100644 --- a/website/docs/user-guide/skills/bundled/gaming/gaming-pokemon-player.md +++ b/website/docs/user-guide/skills/optional/gaming/gaming-pokemon-player.md @@ -14,8 +14,8 @@ Play Pokemon via headless emulator + RAM reads. | | | |---|---| -| Source | Bundled (installed by default) | -| Path | `skills/gaming/pokemon-player` | +| Source | Optional — install with `hermes skills install official/gaming/pokemon-player` | +| Path | `optional-skills/gaming/pokemon-player` | | Platforms | linux, macos, windows | ## Reference: full SKILL.md diff --git a/website/docs/user-guide/skills/bundled/mlops/mlops-research-dspy.md b/website/docs/user-guide/skills/optional/mlops/mlops-research-dspy.md similarity index 99% rename from website/docs/user-guide/skills/bundled/mlops/mlops-research-dspy.md rename to website/docs/user-guide/skills/optional/mlops/mlops-research-dspy.md index 9140bfac6..a7f4ca9d8 100644 --- a/website/docs/user-guide/skills/bundled/mlops/mlops-research-dspy.md +++ b/website/docs/user-guide/skills/optional/mlops/mlops-research-dspy.md @@ -14,8 +14,8 @@ DSPy: declarative LM programs, auto-optimize prompts, RAG. | | | |---|---| -| Source | Bundled (installed by default) | -| Path | `skills/mlops/research/dspy` | +| Source | Optional — install with `hermes skills install official/mlops/dspy` | +| Path | `optional-skills/mlops/research/dspy` | | Version | `1.0.0` | | Author | Orchestra Research | | License | MIT | diff --git a/website/docs/user-guide/skills/bundled/software-development/software-development-subagent-driven-development.md b/website/docs/user-guide/skills/optional/software-development/software-development-subagent-driven-development.md similarity index 93% rename from website/docs/user-guide/skills/bundled/software-development/software-development-subagent-driven-development.md rename to website/docs/user-guide/skills/optional/software-development/software-development-subagent-driven-development.md index 1ad785991..e773edd76 100644 --- a/website/docs/user-guide/skills/bundled/software-development/software-development-subagent-driven-development.md +++ b/website/docs/user-guide/skills/optional/software-development/software-development-subagent-driven-development.md @@ -14,14 +14,14 @@ Execute plans via delegate_task subagents (2-stage review). | | | |---|---| -| Source | Bundled (installed by default) | -| Path | `skills/software-development/subagent-driven-development` | +| Source | Optional — install with `hermes skills install official/software-development/subagent-driven-development` | +| Path | `optional-skills/software-development/subagent-driven-development` | | Version | `1.1.0` | | Author | Hermes Agent (adapted from obra/superpowers) | | License | MIT | | Platforms | linux, macos, windows | | Tags | `delegation`, `subagent`, `implementation`, `workflow`, `parallel` | -| Related skills | [`writing-plans`](/docs/user-guide/skills/bundled/software-development/software-development-writing-plans), [`requesting-code-review`](/docs/user-guide/skills/bundled/software-development/software-development-requesting-code-review), [`test-driven-development`](/docs/user-guide/skills/bundled/software-development/software-development-test-driven-development) | +| Related skills | [`plan`](/docs/user-guide/skills/bundled/software-development/software-development-plan), [`requesting-code-review`](/docs/user-guide/skills/bundled/software-development/software-development-requesting-code-review), [`test-driven-development`](/docs/user-guide/skills/bundled/software-development/software-development-test-driven-development) | ## Reference: full SKILL.md @@ -40,7 +40,7 @@ Execute implementation plans by dispatching fresh subagents per task with system ## When to Use Use this skill when: -- You have an implementation plan (from writing-plans skill or user requirements) +- You have an implementation plan (from the `plan` skill or user requirements) - Tasks are mostly independent - Quality and spec compliance are important - You want automated review between tasks @@ -272,10 +272,10 @@ git add -A && git commit -m "feat: complete [feature name] implementation" ## Integration with Other Skills -### With writing-plans +### With plan -This skill EXECUTES plans created by the writing-plans skill: -1. User requirements → writing-plans → implementation plan +This skill EXECUTES plans created by the `plan` skill: +1. User requirements → plan → implementation plan 2. Implementation plan → subagent-driven-development → working code ### With test-driven-development diff --git a/website/i18n/zh-Hans/docusaurus-plugin-content-docs/current/reference/skills-catalog.md b/website/i18n/zh-Hans/docusaurus-plugin-content-docs/current/reference/skills-catalog.md index 039b5b7e0..a92ae82d3 100644 --- a/website/i18n/zh-Hans/docusaurus-plugin-content-docs/current/reference/skills-catalog.md +++ b/website/i18n/zh-Hans/docusaurus-plugin-content-docs/current/reference/skills-catalog.md @@ -38,18 +38,14 @@ Hermes 在执行 `hermes update` 时也会同步内置技能,但同步清单 | [`architecture-diagram`](/user-guide/skills/bundled/creative/creative-architecture-diagram) | 以 HTML 形式生成深色主题的 SVG 架构/云/基础设施图。 | `creative/architecture-diagram` | | [`ascii-art`](/user-guide/skills/bundled/creative/creative-ascii-art) | ASCII 艺术:pyfiglet、cowsay、boxes、图像转 ASCII。 | `creative/ascii-art` | | [`ascii-video`](/user-guide/skills/bundled/creative/creative-ascii-video) | ASCII 视频:将视频/音频转换为彩色 ASCII MP4/GIF。 | `creative/ascii-video` | -| [`baoyu-article-illustrator`](/user-guide/skills/bundled/creative/creative-baoyu-article-illustrator) | 文章插图:类型 × 风格 × 调色板一致性。 | `creative/baoyu-article-illustrator` | -| [`baoyu-comic`](/user-guide/skills/bundled/creative/creative-baoyu-comic) | 知识漫画:教育、传记、教程。 | `creative/baoyu-comic` | | [`baoyu-infographic`](/user-guide/skills/bundled/creative/creative-baoyu-infographic) | 信息图(可视化):21 种布局 × 21 种风格。 | `creative/baoyu-infographic` | | [`claude-design`](/user-guide/skills/bundled/creative/creative-claude-design) | 设计一次性 HTML 制品(落地页、幻灯片、原型)。 | `creative/claude-design` | | [`comfyui`](/user-guide/skills/bundled/creative/creative-comfyui) | 使用 ComfyUI 生成图像、视频和音频——安装、启动、管理节点/模型、运行带参数注入的工作流。使用官方 comfy-cli 管理生命周期,通过 REST/WebSocket API 直接执行。 | `creative/comfyui` | -| [`ideation`](/user-guide/skills/bundled/creative/creative-creative-ideation) | 通过创意约束生成项目创意。 | `creative/creative-ideation` | | [`design-md`](/user-guide/skills/bundled/creative/creative-design-md) | 编写/验证/导出 Google 的 DESIGN.md token 规范文件。 | `creative/design-md` | | [`excalidraw`](/user-guide/skills/bundled/creative/creative-excalidraw) | 手绘风格的 Excalidraw JSON 图表(架构、流程、时序)。 | `creative/excalidraw` | | [`humanizer`](/user-guide/skills/bundled/creative/creative-humanizer) | 人性化文本:去除 AI 腔,加入真实语气。 | `creative/humanizer` | | [`manim-video`](/user-guide/skills/bundled/creative/creative-manim-video) | Manim CE 动画:3Blue1Brown 风格数学/算法视频。 | `creative/manim-video` | | [`p5js`](/user-guide/skills/bundled/creative/creative-p5js) | p5.js 草图:生成艺术、着色器、交互、3D。 | `creative/p5js` | -| [`pixel-art`](/user-guide/skills/bundled/creative/creative-pixel-art) | 像素艺术,支持复古调色板(NES、Game Boy、PICO-8)。 | `creative/pixel-art` | | [`popular-web-designs`](/user-guide/skills/bundled/creative/creative-popular-web-designs) | 54 种真实设计系统(Stripe、Linear、Vercel)的 HTML/CSS 实现。 | `creative/popular-web-designs` | | [`pretext`](/user-guide/skills/bundled/creative/creative-pretext) | 使用 @chenglou/pretext 构建创意浏览器 demo——无 DOM 的文本布局,支持 ASCII 艺术、绕障碍物的排版流、文字即几何游戏、动态排版和文字驱动的生成艺术。生成单文件 HTML。 | `creative/pretext` | | [`sketch`](/user-guide/skills/bundled/creative/creative-sketch) | 一次性 HTML 原型:生成 2-3 个设计变体供对比。 | `creative/sketch` | @@ -68,7 +64,6 @@ Hermes 在执行 `hermes update` 时也会同步内置技能,但同步清单 |-------|-------------|------| | [`kanban-orchestrator`](/user-guide/skills/bundled/devops/devops-kanban-orchestrator) | 面向编排器(orchestrator)配置文件的分解策略与反诱惑规则,用于通过 Kanban 路由工作。"不要自己做工作"规则和基本生命周期会自动注入每个 Kanban worker 的系统 prompt;如需更深入的细节,请加载此技能。 | `devops/kanban-orchestrator` | | [`kanban-worker`](/user-guide/skills/bundled/devops/devops-kanban-worker) | Hermes Kanban worker 的陷阱、示例和边界情况。生命周期本身会作为 `KANBAN_GUIDANCE` 自动注入每个 worker 的系统 prompt(来自 `agent/prompt_builder.py`);当需要更深入细节时加载此技能。 | `devops/kanban-worker` | -| [`webhook-subscriptions`](/user-guide/skills/bundled/devops/devops-webhook-subscriptions) | Webhook 订阅:事件驱动的 agent 运行。 | `devops/webhook-subscriptions` | ## dogfood @@ -86,8 +81,6 @@ Hermes 在执行 `hermes update` 时也会同步内置技能,但同步清单 | 技能 | 描述 | 路径 | |-------|-------------|------| -| [`minecraft-modpack-server`](/user-guide/skills/bundled/gaming/gaming-minecraft-modpack-server) | 托管模组版 Minecraft 服务器(CurseForge、Modrinth)。 | `gaming/minecraft-modpack-server` | -| [`pokemon-player`](/user-guide/skills/bundled/gaming/gaming-pokemon-player) | 通过无头模拟器 + RAM 读取来游玩 Pokemon。 | `gaming/pokemon-player` | ## github @@ -104,7 +97,6 @@ Hermes 在执行 `hermes update` 时也会同步内置技能,但同步清单 | 技能 | 描述 | 路径 | |-------|-------------|------| -| [`native-mcp`](/user-guide/skills/bundled/mcp/mcp-native-mcp) | MCP 客户端:连接服务器、注册工具(stdio/HTTP)。 | `mcp/native-mcp` | ## media @@ -113,7 +105,6 @@ Hermes 在执行 `hermes update` 时也会同步内置技能,但同步清单 | [`gif-search`](/user-guide/skills/bundled/media/media-gif-search) | 通过 curl + jq 从 Tenor 搜索/下载 GIF。 | `media/gif-search` | | [`heartmula`](/user-guide/skills/bundled/media/media-heartmula) | HeartMuLa:根据歌词 + 标签生成类 Suno 风格的歌曲。 | `media/heartmula` | | [`songsee`](/user-guide/skills/bundled/media/media-songsee) | 通过 CLI 生成音频频谱图/特征(mel、chroma、MFCC)。 | `media/songsee` | -| [`spotify`](/user-guide/skills/bundled/media/media-spotify) | Spotify:播放、搜索、排队、管理播放列表和设备。 | `media/spotify` | | [`youtube-content`](/user-guide/skills/bundled/media/media-youtube-content) | 将 YouTube 字幕转换为摘要、推文串、博客文章。 | `media/youtube-content` | ## mlops @@ -121,7 +112,6 @@ Hermes 在执行 `hermes update` 时也会同步内置技能,但同步清单 | 技能 | 描述 | 路径 | |-------|-------------|------| | [`audiocraft-audio-generation`](/user-guide/skills/bundled/mlops/mlops-models-audiocraft) | AudioCraft:MusicGen 文本转音乐、AudioGen 文本转音效。 | `mlops/models/audiocraft` | -| [`dspy`](/user-guide/skills/bundled/mlops/mlops-research-dspy) | DSPy:声明式 LM 程序,自动优化 prompt,支持 RAG。 | `mlops/research/dspy` | | [`huggingface-hub`](/user-guide/skills/bundled/mlops/mlops-huggingface-hub) | HuggingFace hf CLI:搜索/下载/上传模型、数据集。 | `mlops/huggingface-hub` | | [`llama-cpp`](/user-guide/skills/bundled/mlops/mlops-inference-llama-cpp) | llama.cpp 本地 GGUF 推理 + HF Hub 模型发现。 | `mlops/inference/llama-cpp` | | [`evaluating-llms-harness`](/user-guide/skills/bundled/mlops/mlops-evaluation-lm-evaluation-harness) | lm-eval-harness:对 LLM 进行基准测试(MMLU、GSM8K 等)。 | `mlops/evaluation/lm-evaluation-harness` | @@ -142,7 +132,6 @@ Hermes 在执行 `hermes update` 时也会同步内置技能,但同步清单 |-------|-------------|------| | [`airtable`](/user-guide/skills/bundled/productivity/productivity-airtable) | 通过 curl 调用 Airtable REST API:记录增删改查、过滤、upsert。 | `productivity/airtable` | | [`google-workspace`](/user-guide/skills/bundled/productivity/productivity-google-workspace) | 通过 gws CLI 或 Python 操作 Gmail、Calendar、Drive、Docs、Sheets。 | `productivity/google-workspace` | -| [`linear`](/user-guide/skills/bundled/productivity/productivity-linear) | Linear:通过 GraphQL + curl 管理 issue、项目、团队。 | `productivity/linear` | | [`maps`](/user-guide/skills/bundled/productivity/productivity-maps) | 通过 OpenStreetMap/OSRM 进行地理编码、POI 查询、路线规划、时区查询。 | `productivity/maps` | | [`nano-pdf`](/user-guide/skills/bundled/productivity/productivity-nano-pdf) | 通过 nano-pdf CLI 编辑 PDF 文本/错别字/标题(自然语言 prompt)。 | `productivity/nano-pdf` | | [`notion`](/user-guide/skills/bundled/productivity/productivity-notion) | Notion API + ntn CLI:页面、数据库、Markdown、Workers。 | `productivity/notion` | @@ -182,17 +171,14 @@ Hermes 在执行 `hermes update` 时也会同步内置技能,但同步清单 | 技能 | 描述 | 路径 | |-------|-------------|------| -| [`debugging-hermes-tui-commands`](/user-guide/skills/bundled/software-development/software-development-debugging-hermes-tui-commands) | 调试 Hermes TUI 斜杠命令:Python、gateway、Ink UI。 | `software-development/debugging-hermes-tui-commands` | | [`hermes-agent-skill-authoring`](/user-guide/skills/bundled/software-development/software-development-hermes-agent-skill-authoring) | 编写仓库内 SKILL.md:frontmatter、验证器、结构规范。 | `software-development/hermes-agent-skill-authoring` | | [`node-inspect-debugger`](/user-guide/skills/bundled/software-development/software-development-node-inspect-debugger) | 通过 --inspect + Chrome DevTools Protocol CLI 调试 Node.js。 | `software-development/node-inspect-debugger` | | [`plan`](/user-guide/skills/bundled/software-development/software-development-plan) | 计划模式:将 Markdown 计划写入 `.hermes/plans/`,不执行。 | `software-development/plan` | | [`python-debugpy`](/user-guide/skills/bundled/software-development/software-development-python-debugpy) | 调试 Python:pdb REPL + debugpy 远程调试(DAP)。 | `software-development/python-debugpy` | | [`requesting-code-review`](/user-guide/skills/bundled/software-development/software-development-requesting-code-review) | 提交前审查:安全扫描、质量门控、自动修复。 | `software-development/requesting-code-review` | | [`spike`](/user-guide/skills/bundled/software-development/software-development-spike) | 一次性实验,在正式构建前验证想法。 | `software-development/spike` | -| [`subagent-driven-development`](/user-guide/skills/bundled/software-development/software-development-subagent-driven-development) | 通过 `delegate_task` 子 agent 执行计划(两阶段审查)。 | `software-development/subagent-driven-development` | | [`systematic-debugging`](/user-guide/skills/bundled/software-development/software-development-systematic-debugging) | 四阶段根因调试:先理解 bug,再修复。 | `software-development/systematic-debugging` | | [`test-driven-development`](/user-guide/skills/bundled/software-development/software-development-test-driven-development) | TDD:强制执行红-绿-重构流程,先写测试再写代码。 | `software-development/test-driven-development` | -| [`writing-plans`](/user-guide/skills/bundled/software-development/software-development-writing-plans) | 编写实现计划:细粒度任务、路径、代码。 | `software-development/writing-plans` | ## yuanbao diff --git a/website/i18n/zh-Hans/docusaurus-plugin-content-docs/current/user-guide/skills/bundled/creative/creative-baoyu-article-illustrator.md b/website/i18n/zh-Hans/docusaurus-plugin-content-docs/current/user-guide/skills/bundled/creative/creative-baoyu-article-illustrator.md deleted file mode 100644 index 0ba0549a6..000000000 --- a/website/i18n/zh-Hans/docusaurus-plugin-content-docs/current/user-guide/skills/bundled/creative/creative-baoyu-article-illustrator.md +++ /dev/null @@ -1,225 +0,0 @@ ---- -title: "宝玉文章配图助手 — 文章插图:类型 × 风格 × 调色板一致性" -sidebar_label: "宝玉文章配图助手" -description: "文章插图:类型 × 风格 × 调色板一致性" ---- - -{/* This page is auto-generated from the skill's SKILL.md by website/scripts/generate-skill-docs.py. Edit the source SKILL.md, not this page. */} - -# 宝玉文章配图助手 - -文章插图:类型 × 风格 × 调色板一致性。 - -## Skill 元数据 - -| | | -|---|---| -| 来源 | 内置(默认安装) | -| 路径 | `skills/creative/baoyu-article-illustrator` | -| 版本 | `1.57.0` | -| 作者 | 宝玉 (JimLiu) | -| 许可证 | MIT | -| 平台 | linux, macos, windows | -| 标签 | `article-illustration`, `creative`, `image-generation` | - -## 参考:完整 SKILL.md - -:::info -以下是 Hermes 在触发此 skill 时加载的完整 skill 定义。这是 agent 在 skill 激活时所看到的指令内容。 -::: - -# 文章配图助手 - -改编自 [baoyu-article-illustrator](https://github.com/JimLiu/baoyu-skills),适配 Hermes Agent 的工具生态系统。 - -分析文章,识别插图位置,以 **类型 × 风格 × 调色板** 一致性生成图像。 - -## 使用时机 - -当用户要求为文章配图、添加图片、生成插图,或使用"为文章配图"、"illustrate article"、"add images"等短语时,触发此 skill。用户提供文章(文件路径或粘贴内容),并可选择指定类型、风格、调色板或密度。 - -## 三个维度 - -| 维度 | 控制内容 | 示例 | -|-----------|----------|----------| -| **类型(Type)** | 信息结构 | infographic、scene、flowchart、comparison、framework、timeline | -| **风格(Style)** | 渲染方式 | notion、warm、minimal、blueprint、watercolor、elegant | -| **调色板(Palette)** | 配色方案(可选) | macaron、warm、neon — 覆盖风格的默认颜色 | - -可自由组合:`type=infographic, style=vector-illustration, palette=macaron`。 - -或使用预设:`edu-visual` → 一次性指定 type + style + palette。参见 [style-presets.md](https://github.com/NousResearch/hermes-agent/blob/main/skills/creative/baoyu-article-illustrator/references/style-presets.md)。 - -## 类型 - -| 类型 | 最适合 | -|------|----------| -| `infographic` | 数据、指标、技术内容 | -| `scene` | 叙事、情感表达 | -| `flowchart` | 流程、工作流 | -| `comparison` | 并排对比、选项比较 | -| `framework` | 模型、架构 | -| `timeline` | 历史、演进 | - -## 风格 - -参见 [references/styles.md](https://github.com/NousResearch/hermes-agent/blob/main/skills/creative/baoyu-article-illustrator/references/styles.md),包含核心风格、完整图库及类型 × 风格兼容性说明。 - -## 输出结构 - -<!-- ascii-guard-ignore --> -``` -{output-dir}/ -├── source-{slug}.{ext} # 仅用于粘贴内容 -├── outline.md -├── prompts/ -│ └── NN-{type}-{slug}.md -└── NN-{type}-{slug}.png -``` -<!-- ascii-guard-ignore-end --> - -**默认输出目录**: - -| 输入 | 输出目录 | Markdown 插入路径 | -|-------|------------------|----------------------| -| 文章文件路径 | `{article-dir}/imgs/` | `imgs/NN-{type}-{slug}.png` | -| 粘贴内容 | `illustrations/{topic-slug}/`(当前工作目录) | `illustrations/{topic-slug}/NN-{type}-{slug}.png` | - -如果用户要求不同的布局(例如图片与文章并排,或使用 `illustrations/` 子目录),请遵从用户要求。 - -**Slug**:2-4 个单词,kebab-case 格式。**冲突时**:追加 `-YYYYMMDD-HHMMSS`。 - -## 核心原则 - -- **可视化概念,而非隐喻** — 若文章使用了隐喻(如"电锯切西瓜"),应插图展示其底层概念,而非字面图像。 -- **标签使用文章数据** — 使用文章中的实际数字、术语和引用,而非通用占位符。 -- **Prompt 文件是可复现性记录** — 每张插图在生成图像前必须在 `prompts/` 下保存对应的 prompt 文件。 -- **清除敏感信息** — 在将任何内容写入磁盘前,扫描源内容中的 API 密钥、token 或凭据。 - -## 工作流程 - -``` -- [ ] 步骤 1:检测参考图像(如有提供) -- [ ] 步骤 2:分析内容 -- [ ] 步骤 3:确认设置(使用 clarify 工具,每次一个问题) -- [ ] 步骤 4:生成大纲 -- [ ] 步骤 5:生成 prompt -- [ ] 步骤 6:生成图像(image_generate) -- [ ] 步骤 7:收尾 -``` - -### 步骤 1:检测参考图像 - -如果用户提供了参考图像(内联粘贴的路径、附件或 URL): - -1. 对每个参考图像,使用路径/URL 调用 `vision_analyze`,询问风格、调色板、构图和主题。将返回的描述通过 `write_file` 记录到 `{output-dir}/references/NN-ref-{slug}.md`。 -2. **不要**尝试通过 `write_file` / `read_file` 复制二进制文件 — 这些工具仅支持文本。如需本地副本留存记录,使用 `terminal`(`cp "$src" "{output-dir}/references/NN-ref-{slug}.{ext}"`)。skill 本身无需读取二进制文件;它基于 vision 描述工作。 -3. 由于 `image_generate` 不接受图像输入,vision 描述将在步骤 5 中嵌入到 prompt 中。 - -完整流程:[references/workflow.md](https://github.com/NousResearch/hermes-agent/blob/main/skills/creative/baoyu-article-illustrator/references/workflow.md#step-1-detect-reference-images)。 - -### 步骤 2:分析 - -| 分析项 | 输出 | -|----------|--------| -| 内容类型 | 技术型 / 教程型 / 方法论型 / 叙事型 | -| 目的 | 信息传递 / 可视化 / 想象力激发 | -| 核心论点 | 2-5 个主要观点 | -| 插图位置 | 插图能增加价值的位置 | - -读取源文件(文件路径 → `read_file`,或粘贴文本),并使用 `write_file` 将分析结果写入 `{output-dir}/analysis.md`。 - -完整流程:[references/workflow.md](https://github.com/NousResearch/hermes-agent/blob/main/skills/creative/baoyu-article-illustrator/references/workflow.md#step-2-analyze)。 - -### 步骤 3:确认设置 - -使用 `clarify` 工具。由于 `clarify` 每次只处理一个问题,请先问最重要的问题。若用户请求中已包含答案,则跳过对应问题。 - -| 顺序 | 问题 | 选项 | -|-------|----------|---------| -| Q1 | **预设或类型** | [推荐预设]、[备选预设],或手动选择:infographic、scene、flowchart、comparison、framework、timeline、mixed | -| Q2 | **密度** | minimal(1-2 张)、balanced(3-5 张)、per-section(推荐)、rich(6+ 张) | -| Q3 | **风格** *(若 Q1 已选预设则跳过)* | [推荐]、minimal-flat、sci-fi、hand-drawn、editorial、scene、poster | -| Q4 | **调色板** *(可选)* | 默认(风格颜色)、macaron、warm、neon | -| Q5 | **语言** *(仅当文章语言不明确时)* | 文章语言 / 用户语言 | - -连续 `clarify` 问题不超过 2-3 个。若用户在请求中已指定这些内容,则完全跳过。 - -完整流程:[references/workflow.md](https://github.com/NousResearch/hermes-agent/blob/main/skills/creative/baoyu-article-illustrator/references/workflow.md#step-3-confirm-settings)。 - -### 步骤 4:生成大纲 → `outline.md` - -使用 `write_file` 将 `{output-dir}/outline.md` 保存,包含 frontmatter(type、density、style、palette、image_count)及每张插图的条目: - -```yaml -## Illustration 1 -**Position**: [section/paragraph] -**Purpose**: [why] -**Visual Content**: [what to show] -**Filename**: 01-infographic-concept-name.png -``` - -完整模板:[references/workflow.md](https://github.com/NousResearch/hermes-agent/blob/main/skills/creative/baoyu-article-illustrator/references/workflow.md#step-4-generate-outline)。 - -### 步骤 5:生成 Prompt - -**阻塞条件**:每张插图必须在生成图像前保存 prompt 文件 — prompt 文件是可复现性记录。 - -对每张插图: - -1. 按照 [references/prompt-construction.md](https://github.com/NousResearch/hermes-agent/blob/main/skills/creative/baoyu-article-illustrator/references/prompt-construction.md) 创建 prompt 文件。 -2. 使用 `write_file` 将文件保存到 `{output-dir}/prompts/NN-{type}-{slug}.md`,包含 YAML frontmatter。 -3. Prompt 必须使用特定类型的模板,包含结构化章节(ZONES / LABELS / COLORS / STYLE / ASPECT)。 -4. LABELS 必须包含文章特定数据:实际数字、术语、指标、引用。 -5. 按 prompt frontmatter 处理参考图像(`direct`/`style`/`palette`)— 对于 `direct` 用法,在 prompt 中嵌入参考图像的文字描述(因为 `image_generate` 不接受参考图像输入)。 - -### 步骤 6:生成图像 - -对每个 prompt 文件: - -1. 调用 `image_generate(prompt=..., aspect_ratio=...)`。`image_generate` 返回包含图像 URL 的 JSON 结果;它不会写入磁盘,也不接受输出路径参数。 -2. 将 prompt 的 `ASPECT` 映射到 `image_generate` 的枚举值:`16:9` → `landscape`,`9:16` → `portrait`,`1:1` → `square`。自定义比例 → 映射到最近的命名比例。 -3. 通过 `terminal` 将返回的 URL 下载到 `{output-dir}/NN-{type}-{slug}.png`(例如 `curl -sSL -o "{output-dir}/NN-{type}-{slug}.png" "{url}"`)。 -4. 生成失败时,自动重试一次。 - -注意:底层图像生成后端由用户配置(默认:FAL FLUX 2 Klein 9B),agent 无法通过 `image_generate` 选择后端。不要在 prompt 中写入模型名称并期望其路由生效。 - -### 步骤 7:收尾 - -在对应段落后插入 `![描述](https://github.com/NousResearch/hermes-agent/blob/main/skills/creative/baoyu-article-illustrator/{relative-path}/NN-{type}-{slug}.png)`。Alt 文本:用文章语言简洁描述。 - -报告: - -``` -Article Illustration Complete! -Article: [path] | Type: [type] | Density: [level] | Style: [style] | Palette: [palette or default] -Images: X/N generated -``` - -## 修改操作 - -| 操作 | 步骤 | -|--------|-------| -| 编辑 | 更新 prompt → 重新生成 → 更新引用 | -| 添加 | 确定位置 → 编写 prompt → 生成 → 更新大纲 → 插入 | -| 删除 | 删除文件 → 移除引用 → 更新大纲 | - -## 参考文档 - -| 文件 | 内容 | -|------|---------| -| [references/workflow.md](https://github.com/NousResearch/hermes-agent/blob/main/skills/creative/baoyu-article-illustrator/references/workflow.md) | 详细流程 | -| [references/usage.md](https://github.com/NousResearch/hermes-agent/blob/main/skills/creative/baoyu-article-illustrator/references/usage.md) | 调用示例 | -| [references/styles.md](https://github.com/NousResearch/hermes-agent/blob/main/skills/creative/baoyu-article-illustrator/references/styles.md) | 风格图库 + 调色板图库 | -| [references/style-presets.md](https://github.com/NousResearch/hermes-agent/blob/main/skills/creative/baoyu-article-illustrator/references/style-presets.md) | 预设快捷方式(type + style + palette) | -| [references/prompt-construction.md](https://github.com/NousResearch/hermes-agent/blob/main/skills/creative/baoyu-article-illustrator/references/prompt-construction.md) | Prompt 模板 | - -## 常见陷阱 - -1. **数据完整性至关重要** — 绝不摘要、改写或篡改源统计数据。"73% increase"保持原样。 -2. **清除敏感信息** — 在将任何内容写入输出文件前,扫描源内容中的 API 密钥、token 或凭据。 -3. **不要字面插图隐喻** — 可视化底层概念,而非字面图像。 -4. **Prompt 文件是强制要求** — 没有保存 prompt 文件就不能生成图像。该文件是后续重新生成或切换后端的依据。 -5. **`image_generate` 的宽高比** — 该工具支持 `landscape`、`portrait` 和 `square`。自定义比例映射到最近的选项。 -6. **`image_generate` 返回 URL,而非本地文件** — 在将本地图像路径插入文章前,始终通过 `terminal`(`curl`)下载。 -7. **agent 无法选择后端** — `image_generate` 使用用户配置的模型(默认:FAL FLUX 2 Klein 9B)。不要在 prompt 中写入 `"use <model> to generate this"` 并期望其路由生效。 \ No newline at end of file diff --git a/website/i18n/zh-Hans/docusaurus-plugin-content-docs/current/user-guide/skills/bundled/creative/creative-baoyu-comic.md b/website/i18n/zh-Hans/docusaurus-plugin-content-docs/current/user-guide/skills/bundled/creative/creative-baoyu-comic.md deleted file mode 100644 index b004c7689..000000000 --- a/website/i18n/zh-Hans/docusaurus-plugin-content-docs/current/user-guide/skills/bundled/creative/creative-baoyu-comic.md +++ /dev/null @@ -1,264 +0,0 @@ ---- -title: "Baoyu Comic — 知识漫画:教育、传记、教程" -sidebar_label: "Baoyu Comic" -description: "知识漫画:教育、传记、教程" ---- - -{/* This page is auto-generated from the skill's SKILL.md by website/scripts/generate-skill-docs.py. Edit the source SKILL.md, not this page. */} - -# Baoyu Comic - -知识漫画(Knowledge comics):教育、传记、教程。 - -## Skill 元数据 - -| | | -|---|---| -| 来源 | 内置(默认安装) | -| 路径 | `skills/creative/baoyu-comic` | -| 版本 | `1.56.1` | -| 作者 | 宝玉 (JimLiu) | -| 许可证 | MIT | -| 平台 | linux, macos, windows | -| 标签 | `comic`, `knowledge-comic`, `creative`, `image-generation` | - -## 参考:完整 SKILL.md - -:::info -以下是 Hermes 在触发此 skill 时加载的完整 skill 定义。这是 agent 在 skill 激活时所看到的指令内容。 -::: - -# 知识漫画创作器 - -改编自 [baoyu-comic](https://github.com/JimLiu/baoyu-skills),适配 Hermes Agent 的工具生态系统。 - -创作具有灵活艺术风格 × 基调组合的原创知识漫画。 - -## 使用时机 - -当用户要求创作知识/教育漫画、传记漫画、教程漫画,或使用"知识漫画"、"教育漫画"、"Logicomix 风格"等词语时,触发此 skill。用户提供内容(文本、文件路径、URL 或主题),并可选择指定艺术风格、基调、版式、宽高比或语言。 - -## 参考图片 - -Hermes 的 `image_generate` 工具**仅接受 prompt(提示词)**——它接受文本 prompt 和宽高比,并返回图片 URL。它**不**接受参考图片。当用户提供参考图片时,将其用于**以文字提取特征**,并嵌入每页 prompt 中: - -**接收方式**:当用户提供文件路径时接受(或在对话中粘贴图片)。 -- 文件路径 → 复制到漫画输出目录下的 `refs/NN-ref-{slug}.{ext}`,用于溯源 -- 粘贴图片但无路径 → 通过 `clarify` 向用户询问路径,或以文字形式提取风格特征作为备选 -- 无参考图片 → 跳过此部分 - -**使用模式**(每张参考图片): - -| 用途 | 效果 | -|-------|--------| -| `style` | 提取风格特征(线条处理、纹理、氛围),追加到每页 prompt 正文 | -| `palette` | 提取十六进制颜色,追加到每页 prompt 正文 | -| `scene` | 提取场景构图或主体说明,追加到相关页面 | - -**存在参考图片时,在每页 prompt 的 frontmatter 中记录**: - -```yaml -references: - - ref_id: 01 - filename: 01-ref-scene.png - usage: style - traits: "muted earth tones, soft-edged ink wash, low-contrast backgrounds" -``` - -角色一致性通过 `characters/characters.md` 中的**文字描述**来驱动(在步骤 3 中编写),并内联嵌入每页 prompt(步骤 5)。步骤 7.1 中可选生成的 PNG 角色表是面向用户的审阅产物,而非 `image_generate` 的输入。 - -## 选项 - -### 视觉维度 - -| 选项 | 可选值 | 说明 | -|--------|--------|-------------| -| 艺术风格 | ligne-claire(默认)、manga、realistic、ink-brush、chalk、minimalist | 艺术风格 / 渲染技术 | -| 基调 | neutral(默认)、warm、dramatic、romantic、energetic、vintage、action | 情绪 / 氛围 | -| 版式 | standard(默认)、cinematic、dense、splash、mixed、webtoon、four-panel | 分格排列方式 | -| 宽高比 | 3:4(默认,竖版)、4:3(横版)、16:9(宽屏) | 页面宽高比 | -| 语言 | auto(默认)、zh、en、ja 等 | 输出语言 | -| 参考图片 | 文件路径 | 用于风格 / 调色板特征提取的参考图片(不传入图像模型)。见上方[参考图片](#reference-images)。 | - -### 部分工作流选项 - -| 选项 | 说明 | -|--------|-------------| -| 仅分镜 | 仅生成分镜,跳过 prompt 和图片 | -| 仅 prompt | 生成分镜 + prompt,跳过图片 | -| 仅图片 | 从现有 prompts 目录生成图片 | -| 重新生成第 N 页 | 仅重新生成指定页面(如 `3` 或 `2,5,8`) | - -详情:[references/partial-workflows.md](https://github.com/NousResearch/hermes-agent/blob/main/skills/creative/baoyu-comic/references/partial-workflows.md) - -### 艺术风格、基调与预设目录 - -- **艺术风格**(6 种):`ligne-claire`、`manga`、`realistic`、`ink-brush`、`chalk`、`minimalist`。完整定义见 `references/art-styles/<style>.md`。 -- **基调**(7 种):`neutral`、`warm`、`dramatic`、`romantic`、`energetic`、`vintage`、`action`。完整定义见 `references/tones/<tone>.md`。 -- **预设**(5 种),具有超出普通艺术风格+基调的特殊规则: - - | 预设 | 等效组合 | Hook | - |--------|-----------|------| - | `ohmsha` | manga + neutral | 视觉隐喻、无纯对话页、道具揭示 | - | `wuxia` | ink-brush + action | 气效、战斗视觉、氛围感 | - | `shoujo` | manga + romantic | 装饰元素、眼部细节、浪漫节拍 | - | `concept-story` | manga + warm | 视觉符号体系、成长弧线、对话与动作平衡 | - | `four-panel` | minimalist + neutral + four-panel 版式 | 起承转合结构、黑白+点缀色、火柴人角色 | - - 完整规则见 `references/presets/<preset>.md`——选择预设时加载对应文件。 - -- **兼容性矩阵**和**内容信号 → 预设**对照表见 [references/auto-selection.md](https://github.com/NousResearch/hermes-agent/blob/main/skills/creative/baoyu-comic/references/auto-selection.md)。在步骤 2 推荐组合前请先阅读。 - -## 文件结构 - -输出目录:`comic/{topic-slug}/` -- Slug:从主题中取 2-4 个词,使用 kebab-case(如 `alan-turing-bio`) -- 冲突时:追加时间戳(如 `turing-story-20260118-143052`) - -**内容**: -| 文件 | 说明 | -|------|-------------| -| `source-{slug}.md` | 保存的源内容(kebab-case slug 与输出目录一致) | -| `analysis.md` | 内容分析 | -| `storyboard.md` | 含分格说明的分镜脚本 | -| `characters/characters.md` | 角色定义 | -| `characters/characters.png` | 角色参考表(从 `image_generate` 下载) | -| `prompts/NN-{cover\|page}-[slug].md` | 生成 prompt | -| `NN-{cover\|page}-[slug].png` | 生成的图片(从 `image_generate` 下载) | -| `refs/NN-ref-{slug}.{ext}` | 用户提供的参考图片(可选,用于溯源) | - -## 语言处理 - -**检测优先级**: -1. 用户指定语言(显式选项) -2. 用户对话语言 -3. 源内容语言 - -**规则**:对所有交互使用用户的输入语言: -- 分镜大纲和场景描述 -- 图片生成 prompt -- 用户选择选项和确认信息 -- 进度更新、问题、错误、摘要 - -技术术语保持英文。 - -## 工作流 - -### 进度清单 - -``` -Comic Progress: -- [ ] Step 1: Setup & Analyze - - [ ] 1.1 Analyze content - - [ ] 1.2 Check existing directory -- [ ] Step 2: Confirmation - Style & options ⚠️ REQUIRED -- [ ] Step 3: Generate storyboard + characters -- [ ] Step 4: Review outline (conditional) -- [ ] Step 5: Generate prompts -- [ ] Step 6: Review prompts (conditional) -- [ ] Step 7: Generate images - - [ ] 7.1 Generate character sheet (if needed) → characters/characters.png - - [ ] 7.2 Generate pages (with character descriptions embedded in prompt) -- [ ] Step 8: Completion report -``` - -### 流程 - -``` -Input → Analyze → [Check Existing?] → [Confirm: Style + Reviews] → Storyboard → [Review?] → Prompts → [Review?] → Images → Complete -``` - -### 步骤摘要 - -| 步骤 | 操作 | 关键输出 | -|------|--------|------------| -| 1.1 | 分析内容 | `analysis.md`、`source-{slug}.md` | -| 1.2 | 检查现有目录 | 处理冲突 | -| 2 | 确认风格、重点、受众、审阅方式 | 用户偏好 | -| 3 | 生成分镜 + 角色 | `storyboard.md`、`characters/` | -| 4 | 审阅大纲(如已请求) | 用户确认 | -| 5 | 生成 prompt | `prompts/*.md` | -| 6 | 审阅 prompt(如已请求) | 用户确认 | -| 7.1 | 生成角色表(如需要) | `characters/characters.png` | -| 7.2 | 生成页面 | `*.png` 文件 | -| 8 | 完成报告 | 摘要 | - -### 用户问题 - -使用 `clarify` 工具确认选项。由于 `clarify` 每次只处理一个问题,请先提出最重要的问题,然后依次进行。完整的步骤 2 问题集见 [references/workflow.md](https://github.com/NousResearch/hermes-agent/blob/main/skills/creative/baoyu-comic/references/workflow.md)。 - -**超时处理(关键)**:`clarify` 可能返回 `"The user did not provide a response within the time limit. Use your best judgement to make the choice and proceed."` ——这**不是**用户对所有选项使用默认值的同意。 - -- 仅将其视为**该单个问题**的默认值。继续依次提出步骤 2 的其余问题;每个问题都是独立的确认节点。 -- **在下一条消息中向用户明确展示该默认值**,以便其有机会纠正:例如 `"Style: defaulted to ohmsha preset (clarify timed out). Say the word to switch."` ——未报告的默认值与从未询问过无异。 -- 在一次超时后,**不要**将步骤 2 折叠为"全部使用默认值"的单次处理。如果用户确实不在,他们对所有五个问题同样不在——但他们可以在回来后纠正可见的默认值,而无法纠正不可见的默认值。 - -### 步骤 7:图片生成 - -所有图片渲染均使用 Hermes 内置的 `image_generate` 工具。其 schema 仅接受 `prompt` 和 `aspect_ratio`(`landscape` | `portrait` | `square`);它**返回 URL**,而非本地文件。因此,每张生成的页面或角色表都必须下载到输出目录。 - -**Prompt 文件要求(硬性规定)**:在调用 `image_generate` 之前,必须将每张图片的完整最终 prompt 写入 `prompts/` 下的独立文件(命名规则:`NN-{type}-[slug].md`)。Prompt 文件是可复现性记录。 - -**宽高比映射** ——分镜的 `aspect_ratio` 字段映射到 `image_generate` 的格式如下: - -| 分镜比例 | `image_generate` 格式 | -|------------------|-------------------------| -| `3:4`、`9:16`、`2:3` | `portrait` | -| `4:3`、`16:9`、`3:2` | `landscape` | -| `1:1` | `square` | - -**下载步骤** ——每次调用 `image_generate` 后: -1. 从工具结果中读取 URL -2. 使用**绝对**输出路径获取图片字节,例如: - `curl -fsSL "<url>" -o /abs/path/to/comic/<slug>/NN-page-<slug>.png` -3. 在继续下一页之前,验证该文件存在于该确切路径且非空 - -**永远不要依赖 shell CWD 持久性来指定 `-o` 路径。** 终端工具的持久 shell CWD 可能在批次之间发生变化(会话过期、`TERMINAL_LIFETIME_SECONDS`、失败的 `cd` 导致停留在错误目录)。`curl -o relative/path.png` 是一个隐蔽的陷阱:如果 CWD 已偏移,文件会落在其他地方且不报错。**始终向 `-o` 传递完全限定的绝对路径**,或向终端工具传递 `workdir=<abs path>`。2026 年 4 月事故:一个 10 页漫画的第 06-09 页落在了仓库根目录,而非 `comic/<slug>/`,原因是第 3 批次继承了第 2 批次的过期 CWD,`curl -o 06-page-skills.png` 写入了错误目录。随后 agent 花了数轮声称文件存在于它们实际不在的位置。 - -**7.1 角色表** ——当漫画为多页且有反复出现的角色时,生成角色表(保存至 `characters/characters.png`,宽高比 `landscape`)。对于简单预设(如 four-panel minimalist)或单页漫画可跳过。在调用 `image_generate` 之前,`characters/characters.md` 中的 prompt 文件必须已存在。渲染出的 PNG 是**面向用户的审阅产物**(供用户直观验证角色设计),也是后续重新生成或手动编辑 prompt 的参考——它**不**驱动步骤 7.2。页面 prompt 已在步骤 5 中根据 `characters/characters.md` 中的**文字描述**编写;`image_generate` 无法接受图片作为视觉输入。 - -**7.2 页面** ——在调用 `image_generate` 之前,每页的 prompt 必须已存在于 `prompts/NN-{cover|page}-[slug].md`。由于 `image_generate` 仅接受 prompt,角色一致性通过在步骤 5 中**将角色描述(来源于 `characters/characters.md`)内联嵌入每页 prompt** 来保证。无论步骤 7.1 是否生成 PNG 表,嵌入方式均相同;PNG 仅作为审阅/重新生成的辅助工具。 - -**备份规则**:现有的 `prompts/…md` 和 `…png` 文件 → 在重新生成前,以 `-backup-YYYYMMDD-HHMMSS` 后缀重命名。 - -完整的逐步工作流(分析、分镜、审阅节点、重新生成变体):[references/workflow.md](https://github.com/NousResearch/hermes-agent/blob/main/skills/creative/baoyu-comic/references/workflow.md)。 - -## 参考资料 - -**核心模板**: -- [analysis-framework.md](https://github.com/NousResearch/hermes-agent/blob/main/skills/creative/baoyu-comic/references/analysis-framework.md) - 深度内容分析 -- [character-template.md](https://github.com/NousResearch/hermes-agent/blob/main/skills/creative/baoyu-comic/references/character-template.md) - 角色定义格式 -- [storyboard-template.md](https://github.com/NousResearch/hermes-agent/blob/main/skills/creative/baoyu-comic/references/storyboard-template.md) - 分镜结构 -- [ohmsha-guide.md](https://github.com/NousResearch/hermes-agent/blob/main/skills/creative/baoyu-comic/references/ohmsha-guide.md) - Ohmsha manga 细节 - -**风格定义**: -- `references/art-styles/` - 艺术风格(ligne-claire、manga、realistic、ink-brush、chalk、minimalist) -- `references/tones/` - 基调(neutral、warm、dramatic、romantic、energetic、vintage、action) -- `references/presets/` - 含特殊规则的预设(ohmsha、wuxia、shoujo、concept-story、four-panel) -- `references/layouts/` - 版式(standard、cinematic、dense、splash、mixed、webtoon、four-panel) - -**工作流**: -- [workflow.md](https://github.com/NousResearch/hermes-agent/blob/main/skills/creative/baoyu-comic/references/workflow.md) - 完整工作流详情 -- [auto-selection.md](https://github.com/NousResearch/hermes-agent/blob/main/skills/creative/baoyu-comic/references/auto-selection.md) - 内容信号分析 -- [partial-workflows.md](https://github.com/NousResearch/hermes-agent/blob/main/skills/creative/baoyu-comic/references/partial-workflows.md) - 部分工作流选项 - -## 页面修改 - -| 操作 | 步骤 | -|--------|-------| -| **编辑** | **先更新 prompt 文件** → 重新生成图片 → 下载新 PNG | -| **添加** | 在指定位置创建 prompt → 嵌入角色描述后生成 → 重新编号后续页面 → 更新分镜 | -| **删除** | 删除文件 → 重新编号后续页面 → 更新分镜 | - -**重要**:更新页面时,务必**先**更新 prompt 文件(`prompts/NN-{cover|page}-[slug].md`),再重新生成。这确保变更有据可查且可复现。 - -## 注意事项 - -- 图片生成:每页 10-30 秒;失败时自动重试一次 -- **始终下载** `image_generate` 返回的 URL 到本地 PNG——下游工具(以及用户审阅)期望文件在输出目录中,而非临时 URL -- **`curl -o` 使用绝对路径** ——永远不要依赖持久 shell 的 CWD 跨批次持久性。隐蔽陷阱:文件落在错误目录,随后对预期路径执行 `ls` 显示为空。见步骤 7"下载步骤"。 -- 对敏感公众人物使用风格化替代形象 -- **步骤 2 确认为必须** ——不可跳过 -- **步骤 4/6 为条件性** ——仅在用户于步骤 2 中请求时执行 -- **步骤 7.1 角色表** ——推荐用于多页漫画,简单预设可选。PNG 是审阅/重新生成辅助工具;页面 prompt(在步骤 5 中编写)使用 `characters/characters.md` 中的文字描述,而非 PNG。`image_generate` 不接受图片作为视觉输入 -- **清除敏感信息** ——在写入任何输出文件之前,扫描源内容中的 API 密钥、token 或凭据 \ No newline at end of file diff --git a/website/i18n/zh-Hans/docusaurus-plugin-content-docs/current/user-guide/skills/bundled/creative/creative-creative-ideation.md b/website/i18n/zh-Hans/docusaurus-plugin-content-docs/current/user-guide/skills/bundled/creative/creative-creative-ideation.md deleted file mode 100644 index 5f5a85996..000000000 --- a/website/i18n/zh-Hans/docusaurus-plugin-content-docs/current/user-guide/skills/bundled/creative/creative-creative-ideation.md +++ /dev/null @@ -1,167 +0,0 @@ ---- -title: "创意构思 — 通过创意约束生成项目想法" -sidebar_label: "创意构思" -description: "通过创意约束生成项目想法" ---- - -{/* This page is auto-generated from the skill's SKILL.md by website/scripts/generate-skill-docs.py. Edit the source SKILL.md, not this page. */} - -# 创意构思 - -通过创意约束生成项目想法。 - -## Skill 元数据 - -| | | -|---|---| -| 来源 | 内置(默认安装) | -| 路径 | `skills/creative/creative-ideation` | -| 版本 | `1.0.0` | -| 作者 | SHL0MS | -| 许可证 | MIT | -| 平台 | linux, macos, windows | -| 标签 | `Creative`, `Ideation`, `Projects`, `Brainstorming`, `Inspiration` | - -## 参考:完整 SKILL.md - -:::info -以下是 Hermes 在触发此 skill 时加载的完整 skill 定义。这是 agent 在 skill 激活时所看到的指令内容。 -::: - -# 创意构思 - -## 使用时机 - -当用户说"我想做点什么"、"给我一个项目想法"、"我很无聊"、"我该做什么"、"给我一些灵感",或任何类似"我有工具但没有方向"的表达时使用。适用于代码、艺术、硬件、写作、工具,以及任何可以被创造出来的事物。 - -通过创意约束(constraint)生成项目想法。约束 + 方向 = 创造力。 - -## 工作原理 - -1. **从下方约束库中选取一个约束** — 随机选取,或根据用户的领域/心情匹配 -2. **广义解读** — 一个编程 prompt 可以变成硬件项目,一个艺术 prompt 可以变成 CLI 工具 -3. **生成 3 个满足约束的具体项目想法** -4. **如果用户选定了一个,就开始构建** — 创建项目、编写代码、发布上线 - -## 规则 - -每个 prompt 都尽可能广义地解读。"这包括 X 吗?"→ 是的。prompt 提供方向和适度约束。没有这两者,就没有创造力。 - -## 约束库 - -### 面向开发者 - -**解决自己的痛点:** -构建你这周希望存在的工具。50 行以内。今天就发布。 - -**自动化那件烦人的事:** -你工作流中最繁琐的部分是什么?用脚本解决它。花两小时修复一个每天让你浪费五分钟的问题。 - -**那个本该存在的 CLI 工具:** -想想你希望能输入的命令。`git undo-that-thing-i-just-did`。`docker why-is-this-broken`。`npm explain-yourself`。现在把它做出来。 - -**除了胶水什么都不新:** -完全用现有的 API、库和数据集做点东西。唯一的原创贡献是你连接它们的方式。 - -**弗兰肯斯坦周:** -拿一个做 X 的东西,让它做 Y。一个能播放音乐的 git 仓库。一个能生成诗歌的 Dockerfile。一个发送赞美的 cron job。 - -**做减法:** -在代码库崩溃之前你能删掉多少?把一个工具精简到最小可用功能。一直删,直到只剩本质。 - -**高概念,低投入:** -一个深刻的想法,随意地实现。概念应该很精彩。实现应该只需要一个下午。如果花的时间更长,说明你想太多了。 - -### 面向创客与艺术家 - -**厚颜无耻地抄:** -选一个你欣赏的东西 — 一个工具、一件艺术品、一个界面。从头重新创作它。学习就在你的版本与原版之间的差距里。 - -**一百万个某物:** -一百万既多又不多。一百万像素是一张 1MB 的照片。一百万次 API 调用是某个普通的周二。任何东西达到一百万的规模都会变得有趣。 - -**做一个会死的东西:** -一个每天失去一个功能的网站。一个会遗忘的聊天机器人。一个倒计时到虚无的东西。关于腐烂、终结或放手的练习。 - -**做大量数学:** -生成式几何、shader golf、数学艺术、计算折纸。是时候重新学一下 arcsin 是什么了。 - -### 面向所有人 - -**文本是通用界面:** -构建一个文本是唯一界面的东西。没有按钮,没有图形,只有文字进文字出。文本几乎可以进出任何东西。 - -**从结语开始:** -想一个会成为有趣句子的东西。倒推着把它变成现实。"我教会了我的恒温器来煤气灯效应我" → 现在把它做出来。 - -**恶意 UI:** -做一个故意让人痛苦的东西。一个需要满足 47 个条件的密码框。一个每个标签都在撒谎的表单。一个评判你命令的 CLI。 - -**再来一次:** -回想一个旧项目。从头再做一遍。不要看原版。看看你的思维方式发生了什么变化。 - -更多约束请参见 `references/full-prompt-library.md`,涵盖沟通、规模、哲学、转化等 30+ 个约束。 - -## 将约束与用户匹配 - -| 用户说 | 从以下选取 | -|-----------|-----------| -| "我想做点什么"(没有方向) | 随机 — 任意约束 | -| "我在学 [语言]" | 厚颜无耻地抄、自动化那件烦人的事 | -| "我想要奇怪的东西" | 恶意 UI、弗兰肯斯坦周、从结语开始 | -| "我想要有用的东西" | 解决自己的痛点、那个本该存在的 CLI、自动化那件烦人的事 | -| "我想要美的东西" | 做大量数学、一百万个某物 | -| "我精疲力竭了" | 高概念低投入、做一个会死的东西 | -| "周末项目" | 除了胶水什么都不新、从结语开始 | -| "我想要挑战" | 一百万个某物、做减法、再来一次 | - -## 输出格式 - -``` -## 约束:[名称] -> [约束,一句话] - -### 想法 - -1. **[一句话概括]** - [2-3 句话:你要构建什么以及为什么有趣] - ⏱ [周末 / 一周 / 一个月] • 🔧 [技术栈] - -2. **[一句话概括]** - [2-3 句话] - ⏱ ... • 🔧 ... - -3. **[一句话概括]** - [2-3 句话] - ⏱ ... • 🔧 ... -``` - -## 示例 - -``` -## Constraint: The CLI tool that should exist -> Think of a command you've wished you could type. Now build it. - -### Ideas - -1. **`git whatsup` — show what happened while you were away** - Compares your last active commit to HEAD and summarizes what changed, - who committed, and what PRs merged. Like a morning standup from your repo. - ⏱ weekend • 🔧 Python, GitPython, click - -2. **`explain 503` — HTTP status codes for humans** - Pipe any status code or error message and get a plain-English explanation - with common causes and fixes. Pulls from a curated database, not an LLM. - ⏱ weekend • 🔧 Rust or Go, static dataset - -3. **`deps why <package>` — why is this in my dependency tree** - Traces a transitive dependency back to the direct dependency that pulled - it in. Answers "why do I have 47 copies of lodash" in one command. - ⏱ weekend • 🔧 Node.js, npm/yarn lockfile parsing -``` - -用户选定一个后,开始构建 — 创建项目、编写代码、持续迭代。 - -## 致谢 - -约束方法灵感来源于 [wttdotm.com/prompts.html](https://wttdotm.com/prompts.html)。已针对软件开发和通用创意构思进行改编和扩展。 \ No newline at end of file diff --git a/website/i18n/zh-Hans/docusaurus-plugin-content-docs/current/user-guide/skills/bundled/creative/creative-pixel-art.md b/website/i18n/zh-Hans/docusaurus-plugin-content-docs/current/user-guide/skills/bundled/creative/creative-pixel-art.md deleted file mode 100644 index f8f9862e6..000000000 --- a/website/i18n/zh-Hans/docusaurus-plugin-content-docs/current/user-guide/skills/bundled/creative/creative-pixel-art.md +++ /dev/null @@ -1,214 +0,0 @@ ---- -title: "Pixel Art — 像素艺术(NES、Game Boy、PICO-8 时代调色板)" -sidebar_label: "Pixel Art" -description: "像素艺术(NES、Game Boy、PICO-8 时代调色板)" ---- - -{/* This page is auto-generated from the skill's SKILL.md by website/scripts/generate-skill-docs.py. Edit the source SKILL.md, not this page. */} - -# Pixel Art - -像素艺术(NES、Game Boy、PICO-8 时代调色板)。 - -## Skill 元数据 - -| | | -|---|---| -| 来源 | 内置(默认安装) | -| 路径 | `skills/creative/pixel-art` | -| 版本 | `2.0.0` | -| 作者 | dodo-reach | -| 许可证 | MIT | -| 平台 | linux, macos, windows | -| 标签 | `creative`, `pixel-art`, `arcade`, `snes`, `nes`, `gameboy`, `retro`, `image`, `video` | - -## 参考:完整 SKILL.md - -:::info -以下是 Hermes 在触发此 skill 时加载的完整 skill 定义。这是 skill 激活时 agent 所看到的指令内容。 -::: - -# Pixel Art - -将任意图像转换为复古像素艺术,并可选地将其制作成带有时代感特效(雨、萤火虫、雪、余烬)的短 MP4 或 GIF 动画。 - -此 skill 附带两个脚本: - -- `scripts/pixel_art.py` — 照片 → 像素艺术 PNG(Floyd-Steinberg 抖动算法) -- `scripts/pixel_art_video.py` — 像素艺术 PNG → 动画 MP4(+ 可选 GIF) - -每个脚本均可作为模块导入或直接运行。预设可对齐硬件调色板以获得时代准确的色彩(NES、Game Boy、PICO-8 等),或使用自适应 N 色量化实现街机/SNES 风格。 - -## 使用场景 - -- 用户希望从源图像生成复古像素艺术 -- 用户要求 NES / Game Boy / PICO-8 / C64 / 街机 / SNES 风格 -- 用户需要短循环动画(雨景、夜空、雪景等) -- 海报、专辑封面、社交帖子、精灵图、角色、头像 - -## 工作流程 - -生成前,先与用户确认风格。不同预设产生的效果差异很大,重新生成代价较高。 - -### 第一步 — 提供风格选项 - -使用 `clarify` 提供 4 个代表性预设。根据用户的需求选择组合——不要一次性列出全部 14 个。 - -当用户意图不明确时的默认菜单: - -```python -clarify( - question="Which pixel-art style do you want?", - choices=[ - "arcade — bold, chunky 80s cabinet feel (16 colors, 8px)", - "nes — Nintendo 8-bit hardware palette (54 colors, 8px)", - "gameboy — 4-shade green Game Boy DMG", - "snes — cleaner 16-bit look (32 colors, 4px)", - ], -) -``` - -当用户已指定时代(如"80 年代街机"、"Gameboy")时,跳过 `clarify`,直接使用对应预设。 - -### 第二步 — 提供动画选项(可选) - -如果用户要求视频/GIF,或输出内容适合加入动效,询问选择哪个场景: - -```python -clarify( - question="Want to animate it? Pick a scene or skip.", - choices=[ - "night — stars + fireflies + leaves", - "urban — rain + neon pulse", - "snow — falling snowflakes", - "skip — just the image", - ], -) -``` - -每轮最多调用 `clarify` 两次:一次选风格,一次选场景(如涉及动画)。若用户在消息中已明确指定风格和场景,则完全跳过 `clarify`。 - -### 第三步 — 生成 - -先运行 `pixel_art()`;若用户要求动画,则将结果传入 `pixel_art_video()`。 - -## 预设目录 - -| 预设 | 时代 | 调色板 | 像素块 | 适用场景 | -|--------|-----|---------|-------|----------| -| `arcade` | 80 年代街机 | 自适应 16 色 | 8px | 粗犷海报、主角艺术 | -| `snes` | 16 位 | 自适应 32 色 | 4px | 角色、细节场景 | -| `nes` | 8 位 | NES(54 色) | 8px | 真实 NES 风格 | -| `gameboy` | DMG 掌机 | 4 阶绿色 | 8px | 单色 Game Boy | -| `gameboy_pocket` | Pocket 掌机 | 4 阶灰色 | 8px | 单色 GB Pocket | -| `pico8` | PICO-8 | 16 固定色 | 6px | 幻想主机风格 | -| `c64` | Commodore 64 | 16 固定色 | 8px | 8 位家用电脑 | -| `apple2` | Apple II 高分辨率 | 6 固定色 | 10px | 极致复古,6 色 | -| `teletext` | BBC Teletext | 8 纯色 | 10px | 粗犷原色块 | -| `mspaint` | Windows MS Paint | 24 固定色 | 8px | 怀旧桌面风格 | -| `mono_green` | CRT 荧光绿 | 2 绿色 | 6px | 终端/CRT 美学 | -| `mono_amber` | CRT 琥珀色 | 2 琥珀色 | 6px | 琥珀显示器风格 | -| `neon` | 赛博朋克 | 10 霓虹色 | 6px | 蒸汽波/赛博风 | -| `pastel` | 柔和粉彩 | 10 粉彩色 | 6px | 可爱风 / 温柔风 | - -命名调色板位于 `scripts/palettes.py`(完整列表见 `references/palettes.md`,共 28 个命名调色板)。任何预设均可覆盖: - -```python -pixel_art("in.png", "out.png", preset="snes", palette="PICO_8", block=6) -``` - -## 场景目录(用于视频) - -| 场景 | 特效 | -|-------|---------| -| `night` | 闪烁星星 + 萤火虫 + 飘落树叶 | -| `dusk` | 萤火虫 + 闪光 | -| `tavern` | 尘埃粒子 + 暖色闪光 | -| `indoor` | 尘埃粒子 | -| `urban` | 雨 + 霓虹脉冲 | -| `nature` | 树叶 + 萤火虫 | -| `magic` | 闪光 + 萤火虫 | -| `storm` | 雨 + 闪电 | -| `underwater` | 气泡 + 光斑 | -| `fire` | 余烬 + 闪光 | -| `snow` | 雪花 + 闪光 | -| `desert` | 热浪扭曲 + 尘埃 | - -## 调用方式 - -### Python(导入) - -```python -import sys -sys.path.insert(0, "/home/teknium/.hermes/skills/creative/pixel-art/scripts") -from pixel_art import pixel_art -from pixel_art_video import pixel_art_video - -# 1. 转换为像素艺术 -pixel_art("/path/to/photo.jpg", "/tmp/pixel.png", preset="nes") - -# 2. 制作动画(可选) -pixel_art_video( - "/tmp/pixel.png", - "/tmp/pixel.mp4", - scene="night", - duration=6, - fps=15, - seed=42, - export_gif=True, -) -``` - -### CLI - -```bash -cd /home/teknium/.hermes/skills/creative/pixel-art/scripts - -python pixel_art.py in.jpg out.png --preset gameboy -python pixel_art.py in.jpg out.png --preset snes --palette PICO_8 --block 6 - -python pixel_art_video.py out.png out.mp4 --scene night --duration 6 --gif -``` - -## 流水线原理 - -**像素转换:** -1. 增强对比度/色彩/锐度(调色板越小,增强越强) -2. 色调分离,在量化前简化色调区域 -3. 以 `block` 为步长使用 `Image.NEAREST` 缩小(硬像素,无插值) -4. 使用 Floyd-Steinberg 抖动进行量化——针对自适应 N 色调色板或命名硬件调色板 -5. 使用 `Image.NEAREST` 放大还原 - -在缩小后再量化,可使抖动与最终像素网格对齐。若先量化再缩小,会将误差扩散浪费在最终消失的细节上。 - -**视频叠加:** -- 每帧复制基础帧(静态背景) -- 叠加无状态的逐帧粒子绘制(每种特效一个函数) -- 通过 ffmpeg `libx264 -pix_fmt yuv420p -crf 18` 编码 -- 可选 GIF,通过 `palettegen` + `paletteuse` 生成 - -## 依赖项 - -- Python 3.9+ -- Pillow(`pip install Pillow`) -- PATH 中的 ffmpeg(仅视频需要——Hermes 会安装此包) - -## 注意事项 - -- 调色板键名区分大小写(`"NES"`、`"PICO_8"`、`"GAMEBOY_ORIGINAL"`)。 -- 非常小的源图像(宽度 <100px)在 8-10px 像素块下会崩溃。若源图太小,请先放大。 -- `block` 或 `palette` 为小数时会破坏量化——保持为正整数。 -- 动画粒子数量针对约 640x480 画布调优。对于非常大的图像,可能需要用不同 seed 进行第二次处理以调整密度。 -- `mono_green` / `mono_amber` 强制 `color=0.0`(去饱和)。若覆盖并保留色度,2 色调色板在平滑区域可能产生条纹。 -- `clarify` 循环:每轮最多调用两次(风格,然后是场景)。不要反复向用户询问选项。 - -## 验证 - -- PNG 已在输出路径创建 -- 在预设像素块大小下可见清晰的方形像素块 -- 色彩数量与预设匹配(目视检查图像或运行 `Image.open(p).getcolors()`) -- 视频为有效 MP4(`ffprobe` 可打开)且大小非零 - -## 致谢 - -命名硬件调色板及 `pixel_art_video.py` 中的程序化动画循环移植自 [pixel-art-studio](https://github.com/Synero/pixel-art-studio)(MIT 许可证)。详见此 skill 目录中的 `ATTRIBUTION.md`。 \ No newline at end of file diff --git a/website/i18n/zh-Hans/docusaurus-plugin-content-docs/current/user-guide/skills/bundled/devops/devops-webhook-subscriptions.md b/website/i18n/zh-Hans/docusaurus-plugin-content-docs/current/user-guide/skills/bundled/devops/devops-webhook-subscriptions.md deleted file mode 100644 index aee2ab77c..000000000 --- a/website/i18n/zh-Hans/docusaurus-plugin-content-docs/current/user-guide/skills/bundled/devops/devops-webhook-subscriptions.md +++ /dev/null @@ -1,222 +0,0 @@ ---- -title: "Webhook Subscriptions — Webhook subscriptions: event-driven agent runs" -sidebar_label: "Webhook Subscriptions" -description: "Webhook subscriptions:事件驱动的 agent 运行" ---- - -{/* This page is auto-generated from the skill's SKILL.md by website/scripts/generate-skill-docs.py. Edit the source SKILL.md, not this page. */} - -# Webhook Subscriptions - -Webhook subscriptions:事件驱动的 agent 运行。 - -## Skill 元数据 - -| | | -|---|---| -| 来源 | 内置(默认安装) | -| 路径 | `skills/devops/webhook-subscriptions` | -| 版本 | `1.1.0` | -| 平台 | linux, macos, windows | -| 标签 | `webhook`, `events`, `automation`, `integrations`, `notifications`, `push` | - -## 参考:完整 SKILL.md - -:::info -以下是 Hermes 在触发此 skill 时加载的完整 skill 定义。这是 agent 在 skill 激活时所看到的指令内容。 -::: - -# Webhook Subscriptions - -创建动态 webhook 订阅,使外部服务(GitHub、GitLab、Stripe、CI/CD、IoT 传感器、监控工具)能够通过向 URL 发送 POST 请求来触发 Hermes agent 运行。 - -## 设置(必须先完成) - -在创建订阅之前,必须先启用 webhook 平台。检查方式: -```bash -hermes webhook list -``` - -如果提示"Webhook platform is not enabled",请进行设置: - -### 选项 1:设置向导 -```bash -hermes gateway setup -``` -按照提示启用 webhook、设置端口并配置全局 HMAC 密钥。 - -### 选项 2:手动配置 -在 `~/.hermes/config.yaml` 中添加: -```yaml -platforms: - webhook: - enabled: true - extra: - host: "0.0.0.0" - port: 8644 - secret: "generate-a-strong-secret-here" -``` - -### 选项 3:环境变量 -在 `~/.hermes/.env` 中添加: -```bash -WEBHOOK_ENABLED=true -WEBHOOK_PORT=8644 -WEBHOOK_SECRET=generate-a-strong-secret-here -``` - -配置完成后,启动(或重启)gateway: -```bash -hermes gateway run -# 如果使用 systemd: -systemctl --user restart hermes-gateway -``` - -验证是否正在运行: -```bash -curl http://localhost:8644/health -``` - -## 命令 - -所有管理操作均通过 `hermes webhook` CLI 命令完成: - -### 创建订阅 -```bash -hermes webhook subscribe <name> \ - --prompt "Prompt template with {payload.fields}" \ - --events "event1,event2" \ - --description "What this does" \ - --skills "skill1,skill2" \ - --deliver telegram \ - --deliver-chat-id "12345" \ - --secret "optional-custom-secret" -``` - -返回 webhook URL 和 HMAC 密钥。用户将其服务配置为向该 URL 发送 POST 请求。 - -### 列出订阅 -```bash -hermes webhook list -``` - -### 删除订阅 -```bash -hermes webhook remove <name> -``` - -### 测试订阅 -```bash -hermes webhook test <name> -hermes webhook test <name> --payload '{"key": "value"}' -``` - -## Prompt 模板 - -Prompt(提示词)支持使用 `{dot.notation}` 访问嵌套的 payload 字段: - -- `{issue.title}` — GitHub issue 标题 -- `{pull_request.user.login}` — PR 作者 -- `{data.object.amount}` — Stripe 支付金额 -- `{sensor.temperature}` — IoT 传感器读数 - -如果未指定 prompt,完整的 JSON payload 将直接传入 agent prompt。 - -## 常见模式 - -### GitHub:新 issue -```bash -hermes webhook subscribe github-issues \ - --events "issues" \ - --prompt "New GitHub issue #{issue.number}: {issue.title}\n\nAction: {action}\nAuthor: {issue.user.login}\nBody:\n{issue.body}\n\nPlease triage this issue." \ - --deliver telegram \ - --deliver-chat-id "-100123456789" -``` - -然后在 GitHub 仓库的 Settings → Webhooks → Add webhook 中: -- Payload URL:返回的 webhook_url -- Content type:application/json -- Secret:返回的 secret -- Events:"Issues" - -### GitHub:PR 审查 -```bash -hermes webhook subscribe github-prs \ - --events "pull_request" \ - --prompt "PR #{pull_request.number} {action}: {pull_request.title}\nBy: {pull_request.user.login}\nBranch: {pull_request.head.ref}\n\n{pull_request.body}" \ - --skills "github-code-review" \ - --deliver github_comment -``` - -### Stripe:支付事件 -```bash -hermes webhook subscribe stripe-payments \ - --events "payment_intent.succeeded,payment_intent.payment_failed" \ - --prompt "Payment {data.object.status}: {data.object.amount} cents from {data.object.receipt_email}" \ - --deliver telegram \ - --deliver-chat-id "-100123456789" -``` - -### CI/CD:构建通知 -```bash -hermes webhook subscribe ci-builds \ - --events "pipeline" \ - --prompt "Build {object_attributes.status} on {project.name} branch {object_attributes.ref}\nCommit: {commit.message}" \ - --deliver discord \ - --deliver-chat-id "1234567890" -``` - -### 通用监控告警 -```bash -hermes webhook subscribe alerts \ - --prompt "Alert: {alert.name}\nSeverity: {alert.severity}\nMessage: {alert.message}\n\nPlease investigate and suggest remediation." \ - --deliver origin -``` - -### 直接投递(无 agent,零 LLM 成本) - -适用于只需将通知推送给用户聊天的场景——无需推理,无需 agent 循环——添加 `--deliver-only`。渲染后的 `--prompt` 模板将作为字面消息体直接分发到目标适配器。 - -适用场景: -- 外部服务推送通知(Supabase/Firebase webhooks → Telegram) -- 应原样转发的监控告警 -- 一个 agent 向另一个 agent 的用户发送消息的 agent 间通信 -- 任何 LLM 往返调用属于浪费的 webhook 场景 - -```bash -hermes webhook subscribe antenna-matches \ - --deliver telegram \ - --deliver-chat-id "123456789" \ - --deliver-only \ - --prompt "🎉 New match: {match.user_name} matched with you!" \ - --description "Antenna match notifications" -``` - -投递成功时 POST 返回 `200 OK`,目标失败时返回 `502`——以便上游服务能够智能重试。HMAC 认证、速率限制和幂等性仍然适用。 - -要求 `--deliver` 为真实目标(telegram、discord、slack、github_comment 等)——`--deliver log` 会被拒绝,因为仅记录日志的直接投递毫无意义。 - -## 安全性 - -- 每个订阅自动生成 HMAC-SHA256 密钥(也可通过 `--secret` 自行提供) -- webhook 适配器对每个传入的 POST 请求验证签名 -- `config.yaml` 中的静态路由不会被动态订阅覆盖 -- 订阅持久化保存至 `~/.hermes/webhook_subscriptions.json` - -## 工作原理 - -1. `hermes webhook subscribe` 写入 `~/.hermes/webhook_subscriptions.json` -2. webhook 适配器在每次收到请求时热重载该文件(基于 mtime 检测,开销可忽略不计) -3. 当匹配路由的 POST 请求到达时,适配器格式化 prompt 并触发 agent 运行 -4. agent 的响应被投递到已配置的目标(Telegram、Discord、GitHub comment 等) - -## 故障排查 - -如果 webhook 无法正常工作: - -1. **gateway 是否在运行?** 通过 `systemctl --user status hermes-gateway` 或 `ps aux | grep gateway` 检查 -2. **webhook 服务器是否在监听?** `curl http://localhost:8644/health` 应返回 `{"status": "ok"}` -3. **查看 gateway 日志:** `grep webhook ~/.hermes/logs/gateway.log | tail -20` -4. **签名不匹配?** 验证服务中的 secret 与 `hermes webhook list` 返回的一致。GitHub 发送 `X-Hub-Signature-256`,GitLab 发送 `X-Gitlab-Token`。 -5. **防火墙/NAT?** webhook URL 必须能从该服务访问到。本地开发时,请使用隧道工具(ngrok、cloudflared)。 -6. **事件类型错误?** 检查 `--events` 过滤器是否与服务发送的事件匹配。使用 `hermes webhook test <name>` 验证路由是否正常工作。 \ No newline at end of file diff --git a/website/i18n/zh-Hans/docusaurus-plugin-content-docs/current/user-guide/skills/bundled/gaming/gaming-minecraft-modpack-server.md b/website/i18n/zh-Hans/docusaurus-plugin-content-docs/current/user-guide/skills/bundled/gaming/gaming-minecraft-modpack-server.md deleted file mode 100644 index 2e47a94c6..000000000 --- a/website/i18n/zh-Hans/docusaurus-plugin-content-docs/current/user-guide/skills/bundled/gaming/gaming-minecraft-modpack-server.md +++ /dev/null @@ -1,206 +0,0 @@ ---- -title: "Minecraft模组包服务器 — 托管模组 Minecraft 服务器(CurseForge、Modrinth)" -sidebar_label: "Minecraft 模组包服务器" -description: "托管模组 Minecraft 服务器(CurseForge、Modrinth)" ---- - -{/* This page is auto-generated from the skill's SKILL.md by website/scripts/generate-skill-docs.py. Edit the source SKILL.md, not this page. */} - -# Minecraft 模组包服务器 - -托管模组 Minecraft 服务器(CurseForge、Modrinth)。 - -## 技能元数据 - -| | | -|---|---| -| 来源 | 内置(默认安装) | -| 路径 | `skills/gaming/minecraft-modpack-server` | -| 平台 | linux, macos | - -## 参考:完整 SKILL.md - -:::info -以下是 Hermes 在触发该技能时加载的完整技能定义。这是技能激活时 Agent 所看到的指令内容。 -::: - -# Minecraft 模组包服务器配置 - -## 适用场景 -- 用户希望从服务器包 zip 文件搭建模组 Minecraft 服务器 -- 用户需要 NeoForge/Forge 服务器配置方面的帮助 -- 用户询问 Minecraft 服务器性能调优或备份相关问题 - -## 首先收集用户偏好 -开始配置前,向用户询问以下内容: -- **服务器名称 / MOTD** — 服务器列表中显示什么? -- **种子(Seed)** — 指定种子还是随机? -- **难度** — 和平 / 简单 / 普通 / 困难? -- **游戏模式** — 生存 / 创造 / 冒险? -- **在线模式** — true(Mojang 验证,正版账号)还是 false(局域网/离线友好)? -- **玩家数量** — 预计多少玩家同时在线?(影响内存与视距调优) -- **内存分配** — 由用户指定,还是由 Agent 根据模组数量和可用内存决定? -- **视距 / 模拟距离** — 由用户指定,还是由 Agent 根据玩家数量和硬件决定? -- **PvP** — 开启还是关闭? -- **白名单** — 开放服务器还是仅白名单? -- **备份** — 是否需要自动备份?多久一次? - -若用户不在意,使用合理默认值,但务必在生成配置前先行询问。 - -## 步骤 - -### 1. 下载并检查模组包 -```bash -mkdir -p ~/minecraft-server -cd ~/minecraft-server -wget -O serverpack.zip "<URL>" -unzip -o serverpack.zip -d server -ls server/ -``` -查找:`startserver.sh`、安装器 jar(neoforge/forge)、`user_jvm_args.txt`、`mods/` 文件夹。 -检查脚本以确定:模组加载器类型、版本及所需 Java 版本。 - -### 2. 安装 Java -- Minecraft 1.21+ → Java 21:`sudo apt install openjdk-21-jre-headless` -- Minecraft 1.18-1.20 → Java 17:`sudo apt install openjdk-17-jre-headless` -- Minecraft 1.16 及以下 → Java 8:`sudo apt install openjdk-8-jre-headless` -- 验证:`java -version` - -### 3. 安装模组加载器 -大多数服务器包包含安装脚本。使用 `INSTALL_ONLY` 环境变量可仅安装而不启动: -```bash -cd ~/minecraft-server/server -ATM10_INSTALL_ONLY=true bash startserver.sh -# 或对于通用 Forge 包: -# java -jar forge-*-installer.jar --installServer -``` -此步骤会下载库文件、修补服务器 jar 等。 - -### 4. 接受 EULA -```bash -echo "eula=true" > ~/minecraft-server/server/eula.txt -``` - -### 5. 配置 server.properties -模组/局域网的关键设置: -```properties -motd=\u00a7b\u00a7lServer Name \u00a7r\u00a78| \u00a7aModpack Name -server-port=25565 -online-mode=true # false 表示无 Mojang 验证的局域网 -enforce-secure-profile=true # 与 online-mode 保持一致 -difficulty=hard # 大多数模组包以困难难度为平衡基准 -allow-flight=true # 模组服务器必须开启(飞行坐骑/物品) -spawn-protection=0 # 允许所有人在出生点建造 -max-tick-time=180000 # 模组服务器需要更长的 tick 超时时间 -enable-command-block=true -``` - -性能设置(根据硬件调整): -```properties -# 2 名玩家,高性能机器: -view-distance=16 -simulation-distance=10 - -# 4-6 名玩家,中等配置机器: -view-distance=10 -simulation-distance=6 - -# 8+ 名玩家或较弱硬件: -view-distance=8 -simulation-distance=4 -``` - -### 6. 调整 JVM 参数(user_jvm_args.txt) -根据玩家数量和模组数量调整内存。模组服务器的经验法则: -- 100-200 个模组:6-12GB -- 200-350+ 个模组:12-24GB -- 为操作系统/其他任务至少保留 8GB 空闲内存 - -``` --Xms12G --Xmx24G --XX:+UseG1GC --XX:+ParallelRefProcEnabled --XX:MaxGCPauseMillis=200 --XX:+UnlockExperimentalVMOptions --XX:+DisableExplicitGC --XX:+AlwaysPreTouch --XX:G1NewSizePercent=30 --XX:G1MaxNewSizePercent=40 --XX:G1HeapRegionSize=8M --XX:G1ReservePercent=20 --XX:G1HeapWastePercent=5 --XX:G1MixedGCCountTarget=4 --XX:InitiatingHeapOccupancyPercent=15 --XX:G1MixedGCLiveThresholdPercent=90 --XX:G1RSetUpdatingPauseTimePercent=5 --XX:SurvivorRatio=32 --XX:+PerfDisableSharedMem --XX:MaxTenuringThreshold=1 -``` - -### 7. 开放防火墙 -```bash -sudo ufw allow 25565/tcp comment "Minecraft Server" -``` -检查:`sudo ufw status | grep 25565` - -### 8. 创建启动脚本 -```bash -cat > ~/start-minecraft.sh << 'EOF' -#!/bin/bash -cd ~/minecraft-server/server -java @user_jvm_args.txt @libraries/net/neoforged/neoforge/<VERSION>/unix_args.txt nogui -EOF -chmod +x ~/start-minecraft.sh -``` -注意:对于 Forge(非 NeoForge),参数文件路径不同。请查看 `startserver.sh` 获取确切路径。 - -### 9. 配置自动备份 -创建备份脚本: -```bash -cat > ~/minecraft-server/backup.sh << 'SCRIPT' -#!/bin/bash -SERVER_DIR="$HOME/minecraft-server/server" -BACKUP_DIR="$HOME/minecraft-server/backups" -WORLD_DIR="$SERVER_DIR/world" -MAX_BACKUPS=24 -mkdir -p "$BACKUP_DIR" -[ ! -d "$WORLD_DIR" ] && echo "[BACKUP] No world folder" && exit 0 -TIMESTAMP=$(date +%Y-%m-%d_%H-%M-%S) -BACKUP_FILE="$BACKUP_DIR/world_${TIMESTAMP}.tar.gz" -echo "[BACKUP] Starting at $(date)" -tar -czf "$BACKUP_FILE" -C "$SERVER_DIR" world -SIZE=$(du -h "$BACKUP_FILE" | cut -f1) -echo "[BACKUP] Saved: $BACKUP_FILE ($SIZE)" -BACKUP_COUNT=$(ls -1t "$BACKUP_DIR"/world_*.tar.gz 2>/dev/null | wc -l) -if [ "$BACKUP_COUNT" -gt "$MAX_BACKUPS" ]; then - REMOVE=$((BACKUP_COUNT - MAX_BACKUPS)) - ls -1t "$BACKUP_DIR"/world_*.tar.gz | tail -n "$REMOVE" | xargs rm -f - echo "[BACKUP] Pruned $REMOVE old backup(s)" -fi -echo "[BACKUP] Done at $(date)" -SCRIPT -chmod +x ~/minecraft-server/backup.sh -``` - -添加每小时 cron 任务: -```bash -(crontab -l 2>/dev/null | grep -v "minecraft/backup.sh"; echo "0 * * * * $HOME/minecraft-server/backup.sh >> $HOME/minecraft-server/backups/backup.log 2>&1") | crontab - -``` - -## 常见问题 -- 模组服务器**务必**设置 `allow-flight=true` — 带喷气背包/飞行功能的模组否则会踢出玩家 -- `max-tick-time=180000` 或更高 — 模组服务器在世界生成期间经常出现长 tick -- 首次启动**很慢**(大型模组包需要数分钟)— 不必惊慌 -- 首次启动时出现"Can't keep up!"警告属正常现象,初始区块生成完成后会恢复 -- 若 `online-mode=false`,同时设置 `enforce-secure-profile=false`,否则客户端会被拒绝连接 -- 模组包的 `startserver.sh` 通常包含自动重启循环 — 请另行创建不含该循环的干净启动脚本 -- 删除 `world/` 文件夹可使用新种子重新生成世界 -- 部分模组包使用环境变量控制行为(例如 ATM10 使用 `ATM10_JAVA`、`ATM10_RESTART`、`ATM10_INSTALL_ONLY`) - -## 验证 -- `pgrep -fa neoforge` 或 `pgrep -fa minecraft` 检查是否正在运行 -- 查看日志:`tail -f ~/minecraft-server/server/logs/latest.log` -- 日志中出现"Done (Xs)!"表示服务器已就绪 -- 测试连接:玩家在多人游戏中添加服务器 IP \ No newline at end of file diff --git a/website/i18n/zh-Hans/docusaurus-plugin-content-docs/current/user-guide/skills/bundled/gaming/gaming-pokemon-player.md b/website/i18n/zh-Hans/docusaurus-plugin-content-docs/current/user-guide/skills/bundled/gaming/gaming-pokemon-player.md deleted file mode 100644 index 970635d65..000000000 --- a/website/i18n/zh-Hans/docusaurus-plugin-content-docs/current/user-guide/skills/bundled/gaming/gaming-pokemon-player.md +++ /dev/null @@ -1,232 +0,0 @@ ---- -title: "Pokemon Player — 通过无头模拟器 + RAM 读取来玩宝可梦" -sidebar_label: "Pokemon Player" -description: "通过无头模拟器 + RAM 读取来玩宝可梦" ---- - -{/* This page is auto-generated from the skill's SKILL.md by website/scripts/generate-skill-docs.py. Edit the source SKILL.md, not this page. */} - -# Pokemon Player - -通过无头模拟器 + RAM 读取来玩宝可梦。 - -## Skill 元数据 - -| | | -|---|---| -| 来源 | 内置(默认安装) | -| 路径 | `skills/gaming/pokemon-player` | -| 平台 | linux, macos, windows | - -## 参考:完整 SKILL.md - -:::info -以下是 Hermes 在触发此 skill 时加载的完整 skill 定义。这是 agent 在 skill 激活时看到的指令内容。 -::: - -# Pokemon Player - -通过使用 `pokemon-agent` 包进行无头模拟来玩宝可梦游戏。 - -## 使用时机 -- 用户说"play pokemon"、"start pokemon"、"pokemon game" -- 用户询问 Pokemon Red、Blue、Yellow、FireRed 等 -- 用户想观看 AI 玩宝可梦 -- 用户提到 ROM 文件(.gb、.gbc、.gba) - -## 启动流程 - -### 1. 首次设置(克隆、venv、安装) -仓库为 GitHub 上的 NousResearch/pokemon-agent。克隆后, -设置 Python 3.10+ 虚拟环境。使用 uv(速度更快,优先推荐) -创建 venv 并以可编辑模式安装带有 pyboy extra 的包。 -若 uv 不可用,则回退到 python3 -m venv + pip。 - -本机已在 /home/teknium/pokemon-agent 完成设置, -venv 已就绪 —— 只需 cd 进入该目录并执行 source .venv/bin/activate。 - -还需要一个 ROM 文件。请向用户索取。本机在该目录的 -roms/pokemon_red.gb 处已有一个。 -**绝不**下载或提供 ROM 文件 —— 始终向用户索取。 - -### 2. 启动游戏服务器 -在已激活 venv 的 pokemon-agent 目录内,运行 -pokemon-agent serve,通过 --rom 指定 ROM 路径,--port 9876。 -使用 & 在后台运行。 -如需从存档恢复,添加 --load-state 并指定存档名称。 -等待 4 秒启动完成,然后通过 GET /health 验证。 - -### 3. 为用户设置实时看板(dashboard) -通过 localhost.run 使用 SSH 反向隧道,让用户可在浏览器中查看 -看板。使用 ssh 连接,将本地端口 9876 转发到 nokey@localhost.run -的远程端口 80。将输出重定向到日志文件,等待 10 秒, -然后在日志中 grep .lhr.life URL。将附加了 /dashboard/ 的 URL 提供给用户。 -隧道 URL 每次都会变化 —— 重启后请给用户新的 URL。 - -## 存档与读档 - -### 何时存档 -- 每 15-20 回合游戏操作后 -- 在道馆战、对手遭遇或高风险战斗**前**务必存档 -- 进入新城镇或地下城前 -- 在任何不确定的操作前 - -### 如何存档 -使用描述性名称 POST /save。示例: -before_brock、route1_start、mt_moon_entrance、got_cut - -### 如何读档 -使用存档名称 POST /load。 - -### 列出可用存档 -GET /saves 返回所有已保存状态。 - -### 服务器启动时读档 -启动服务器时使用 --load-state 标志可自动加载存档。 -这比启动后通过 API 加载更快。 - -## 游戏循环 - -### 第 1 步:观察(OBSERVE)—— 检查状态并截图 -GET /state 获取位置、HP、战斗、对话信息。 -GET /screenshot 并保存到 /tmp/pokemon.png,然后使用 vision_analyze。 -两者都要做 —— RAM 状态提供数值,视觉提供空间感知。 - -### 第 2 步:判断(ORIENT) -- 屏幕上有对话/文字 → 推进对话 -- 在战斗中 → 战斗或逃跑 -- 队伍受伤 → 前往宝可梦中心 -- 接近目标 → 谨慎导航 - -### 第 3 步:决策(DECIDE) -优先级:对话 > 战斗 > 治疗 > 剧情目标 > 练级 > 探索 - -### 第 4 步:行动(ACT)—— 最多移动 2-4 步,然后重新检查 -POST /action,使用**简短**的动作列表(2-4 个动作,而非 10-15 个)。 - -### 第 5 步:验证(VERIFY)—— 每次移动序列后截图 -截图并使用 vision_analyze 确认移动到了预期位置。 -这是**最重要**的步骤。没有视觉你**一定会**迷路。 - -### 第 6 步:用 PKM: 前缀将进度记录到记忆中 - -### 第 7 步:定期存档 - -## 动作参考 -- press_a —— 确认、对话、选择 -- press_b —— 取消、关闭菜单 -- press_start —— 打开游戏菜单 -- walk_up/down/left/right —— 移动一格 -- hold_b_N —— 按住 B 键 N 帧(用于加速文字显示) -- wait_60 —— 等待约 1 秒(60 帧) -- a_until_dialog_end —— 反复按 A 直到对话结束 - -## 经验总结的关键提示 - -### 持续使用视觉 -- 每移动 2-4 步截一次图 -- RAM 状态告诉你位置和 HP,但**不告诉你周围有什么** -- 悬崖、栅栏、标牌、建筑门口、NPC —— 只能通过截图看到 -- 向视觉模型提出具体问题:"我北边一格是什么?" -- 卡住时,在尝试随机方向前务必先截图 - -### 传送过渡需要额外等待时间 -走过门或楼梯时,地图切换期间屏幕会淡入黑色。 -**必须**等待切换完成。在任何门/楼梯传送后添加 2-3 个 wait_60 动作。 -不等待的话,位置读取会是旧数据,你会以为自己还在旧地图。 - -### 建筑出口陷阱 -离开建筑时,你会出现在门**正前方**。 -如果向北走,你会直接回到建筑内。**务必**先向左或向右侧移 2 格, -再朝目标方向前进。 - -### 对话处理 -第一代文字逐字母缓慢滚动。要加速对话, -按住 B 键 120 帧,然后按 A。根据需要重复。按住 B 使文字以最快速度显示。 -然后按 A 推进到下一行。 -a_until_dialog_end 动作会检查 RAM 对话标志,但该标志 -**不能捕获所有文字状态**。如果对话似乎卡住, -改用手动 hold_b + press_a 模式,并通过截图验证。 - -### 悬崖是单向的 -悬崖(小型断崖边缘)只能向下跳(向南),不能向上攀爬(向北)。 -如果向北被悬崖阻挡,必须向左或向右找到绕行缺口。 -使用视觉识别缺口在哪个方向。明确询问视觉模型。 - -### 导航策略 -- 每次移动 2-4 步,然后截图检查位置 -- 进入新区域时,立即截图定向 -- 询问视觉模型"去[目的地]往哪个方向?" -- 若尝试 3 次以上仍卡住,截图并完全重新评估 -- 不要连发 10-15 个移动动作 —— 你会走过头或卡住 - -### 从野生战斗逃跑 -在战斗菜单中,RUN 在右下角。从默认光标位置(FIGHT,左上角)到达 RUN: -按下再按右将光标移到 RUN,然后按 A。用 hold_b 加速文字/动画。 - -### 战斗(FIGHT) -战斗菜单中 FIGHT 在左上角(默认光标位置)。 -按 A 进入招式选择,再按 A 使用第一个招式。 -然后按住 B 加速攻击动画和文字。 - -## 战斗策略 - -### 决策树 -1. 想要捕捉?→ 削弱后投掷精灵球 -2. 不需要的野生宝可梦?→ 逃跑 -3. 有属性克制?→ 使用效果拔群的招式 -4. 无克制优势?→ 使用最强的本系招式 -5. HP 低?→ 换人或使用药水 - -### 第一代属性克制表(关键对应) -- 水克火、地面、岩石 -- 火克草、虫、冰 -- 草克水、地面、岩石 -- 电克水、飞行 -- 地面克火、电、岩石、毒 -- 超能力克格斗、毒(第一代中极为强势!) - -### 第一代特性 -- 特殊能力 = 特殊招式的攻击**和**防御 -- 超能力属性过于强大(幽灵系招式存在 bug) -- 要害一击基于速度能力值 -- 缠绕/束缚使对手无法行动 -- 专注能量 bug:**降低**要害率而非提升 - -## 记忆约定 -| 前缀 | 用途 | 示例 | -|--------|---------|---------| -| PKM:OBJECTIVE | 当前目标 | 从青莲市商店取包裹 | -| PKM:MAP | 导航知识 | 青莲:商店在东北方 | -| PKM:STRATEGY | 战斗/队伍计划 | 对战小霞前需要草系 | -| PKM:PROGRESS | 里程碑追踪 | 击败对手,前往青莲市 | -| PKM:STUCK | 卡住情况 | y=28 处悬崖向右绕行 | -| PKM:TEAM | 队伍备注 | 杰尼龟 Lv6,撞击 + 尾巴摇摆 | - -## 进度里程碑 -- 选择初始宝可梦 -- 从青莲市商店取回包裹,获得图鉴 -- 岩石徽章 —— 小刚(岩石)→ 使用水/草 -- 瀑布徽章 —— 小霞(水)→ 使用草/电 -- 雷电徽章 —— 马修(电)→ 使用地面 -- 彩虹徽章 —— 莉卡(草)→ 使用火/冰/飞行 -- 灵魂徽章 —— 阿桂(毒)→ 使用地面/超能力 -- 沼泽徽章 —— 娜姿(超能力)→ 最难道馆 -- 火山徽章 —— 夏伯(火)→ 使用水/地面 -- 大地徽章 —— 坂木(地面)→ 使用水/草/冰 -- 四天王 → 冠军! - -## 停止游戏 -1. 通过 POST /save 以描述性名称存档 -2. 用 PKM:PROGRESS 更新记忆 -3. 告知用户:"游戏已存为 [名称]!说 'play pokemon' 可继续。" -4. 终止服务器和隧道后台进程 - -## 注意事项 -- **绝不**下载或提供 ROM 文件 -- 不要在未检查视觉的情况下发送超过 4-5 个动作 -- 离开建筑后向北走前务必先侧移 -- 门/楼梯传送后务必添加 wait_60 x2-3 -- 通过 RAM 检测对话不可靠 —— 用截图验证 -- 在高风险遭遇**前**存档 -- 每次重启隧道 URL 都会变化 \ No newline at end of file diff --git a/website/i18n/zh-Hans/docusaurus-plugin-content-docs/current/user-guide/skills/bundled/mcp/mcp-native-mcp.md b/website/i18n/zh-Hans/docusaurus-plugin-content-docs/current/user-guide/skills/bundled/mcp/mcp-native-mcp.md deleted file mode 100644 index f03388f7c..000000000 --- a/website/i18n/zh-Hans/docusaurus-plugin-content-docs/current/user-guide/skills/bundled/mcp/mcp-native-mcp.md +++ /dev/null @@ -1,375 +0,0 @@ ---- -title: "Native Mcp — MCP 客户端:连接服务器、注册工具(stdio/HTTP)" -sidebar_label: "Native Mcp" -description: "MCP 客户端:连接服务器、注册工具(stdio/HTTP)" ---- - -{/* This page is auto-generated from the skill's SKILL.md by website/scripts/generate-skill-docs.py. Edit the source SKILL.md, not this page. */} - -# Native Mcp - -MCP 客户端:连接服务器、注册工具(stdio/HTTP)。 - -## Skill 元数据 - -| | | -|---|---| -| 来源 | 内置(默认安装) | -| 路径 | `skills/mcp/native-mcp` | -| 版本 | `1.0.0` | -| 作者 | Hermes Agent | -| 许可证 | MIT | -| 平台 | linux, macos, windows | -| 标签 | `MCP`, `Tools`, `Integrations` | -| 相关 skill | [`mcporter`](/user-guide/skills/optional/mcp/mcp-mcporter) | - -## 参考:完整 SKILL.md - -:::info -以下是 Hermes 在触发此 skill 时加载的完整 skill 定义。这是 agent 在 skill 激活时所看到的指令内容。 -::: - -# Native MCP 客户端 - -Hermes Agent 内置了一个 MCP 客户端,它在启动时连接到 MCP 服务器,发现其工具,并将其作为一等工具直接提供给 agent 调用。无需桥接 CLI——来自 MCP 服务器的工具与 `terminal`、`read_file` 等内置工具并列显示。 - -## 使用场景 - -在以下情况下使用此 skill: -- 连接到 MCP 服务器并在 Hermes Agent 中使用其工具 -- 通过 MCP 添加外部能力(文件系统访问、GitHub、数据库、API) -- 运行基于 stdio 的本地 MCP 服务器(npx、uvx 或任意命令) -- 连接到远程 HTTP/StreamableHTTP MCP 服务器 -- 让 MCP 工具自动发现并在每次对话中可用 - -如需从终端进行临时、一次性的 MCP 工具调用而无需任何配置,请改用 `mcporter` skill。 - -## 前置条件 - -- **mcp Python 包** — 可选依赖;通过 `pip install mcp` 安装。若未安装,MCP 支持将静默禁用。 -- **Node.js** — 基于 `npx` 的 MCP 服务器(大多数社区服务器)所需 -- **uv** — 基于 `uvx` 的 MCP 服务器(Python 服务器)所需 - -安装 MCP SDK: - -```bash -pip install mcp -# 或者,如果使用 uv: -uv pip install mcp -``` - -## 快速开始 - -在 `~/.hermes/config.yaml` 的 `mcp_servers` 键下添加 MCP 服务器: - -```yaml -mcp_servers: - time: - command: "uvx" - args: ["mcp-server-time"] -``` - -重启 Hermes Agent。启动时它将: -1. 连接到服务器 -2. 发现可用工具 -3. 以 `mcp_time_*` 前缀注册它们 -4. 将其注入所有平台工具集 - -之后即可自然地使用这些工具——只需让 agent 获取当前时间即可。 - -## 配置参考 - -`mcp_servers` 下的每个条目是一个服务器名称到其配置的映射。有两种传输类型:**stdio**(基于命令)和 **HTTP**(基于 url)。 - -### Stdio 传输(command + args) - -```yaml -mcp_servers: - server_name: - command: "npx" # (必填)要运行的可执行文件 - args: ["-y", "pkg-name"] # (可选)命令参数,默认:[] - env: # (可选)子进程的环境变量 - SOME_API_KEY: "value" - timeout: 120 # (可选)每次工具调用超时(秒),默认:120 - connect_timeout: 60 # (可选)初始连接超时(秒),默认:60 -``` - -### HTTP 传输(url) - -```yaml -mcp_servers: - server_name: - url: "https://my-server.example.com/mcp" # (必填)服务器 URL - headers: # (可选)HTTP 请求头 - Authorization: "Bearer sk-..." - timeout: 180 # (可选)每次工具调用超时(秒),默认:120 - connect_timeout: 60 # (可选)初始连接超时(秒),默认:60 -``` - -### 所有配置选项 - -| 选项 | 类型 | 默认值 | 描述 | -|-------------------|--------|---------|---------------------------------------------------| -| `command` | string | -- | 要运行的可执行文件(stdio 传输,必填) | -| `args` | list | `[]` | 传递给命令的参数 | -| `env` | dict | `{}` | 子进程的额外环境变量 | -| `url` | string | -- | 服务器 URL(HTTP 传输,必填) | -| `headers` | dict | `{}` | 每次请求发送的 HTTP 请求头 | -| `timeout` | int | `120` | 每次工具调用超时(秒) | -| `connect_timeout` | int | `60` | 初始连接和发现的超时时间 | - -注意:服务器配置必须有 `command`(stdio)或 `url`(HTTP)之一,不能同时存在。 - -## 工作原理 - -### 启动发现 - -Hermes Agent 启动时,`discover_mcp_tools()` 在工具初始化期间被调用: - -1. 从 `~/.hermes/config.yaml` 读取 `mcp_servers` -2. 对每个服务器,在专用后台事件循环中生成连接 -3. 初始化 MCP 会话并调用 `list_tools()` 发现可用工具 -4. 在 Hermes 工具注册表中注册每个工具 - -### 工具命名规范 - -MCP 工具按以下命名模式注册: - -``` -mcp_{server_name}_{tool_name} -``` - -名称中的连字符和点号会替换为下划线,以兼容 LLM API。 - -示例: -- 服务器 `filesystem`,工具 `read_file` → `mcp_filesystem_read_file` -- 服务器 `github`,工具 `list-issues` → `mcp_github_list_issues` -- 服务器 `my-api`,工具 `fetch.data` → `mcp_my_api_fetch_data` - -### 自动注入 - -发现完成后,MCP 工具会自动注入所有 `hermes-*` 平台工具集(CLI、Discord、Telegram 等)。这意味着 MCP 工具无需任何额外配置即可在每次对话中使用。 - -### 连接生命周期 - -- 每个服务器作为长期存活的 asyncio Task 运行在后台守护线程中 -- 连接在 agent 进程的整个生命周期内持续存在 -- 若连接断开,将自动以指数退避方式重连(最多重试 5 次,最大退避 60 秒) -- agent 关闭时,所有连接将优雅关闭 - -### 幂等性 - -`discover_mcp_tools()` 是幂等的——多次调用只会连接尚未连接的服务器。失败的服务器将在后续调用时重试。 - -## 传输类型 - -### Stdio 传输 - -最常见的传输方式。Hermes 将 MCP 服务器作为子进程启动,并通过 stdin/stdout 通信。 - -```yaml -mcp_servers: - filesystem: - command: "npx" - args: ["-y", "@modelcontextprotocol/server-filesystem", "/home/user/projects"] -``` - -子进程继承**经过过滤的**环境(见下方安全章节)以及你在 `env` 中指定的任何变量。 - -### HTTP / StreamableHTTP 传输 - -用于远程或共享 MCP 服务器。要求 `mcp` 包包含 HTTP 客户端支持(`mcp.client.streamable_http`)。 - -```yaml -mcp_servers: - remote_api: - url: "https://mcp.example.com/mcp" - headers: - Authorization: "Bearer sk-..." -``` - -如果你安装的 `mcp` 版本不支持 HTTP 客户端,该服务器将以 ImportError 失败,其他服务器将正常继续运行。 - -## 安全 - -### 环境变量过滤 - -对于 stdio 服务器,Hermes **不会**将你的完整 shell 环境传递给 MCP 子进程。只有以下安全基线变量会被继承: - -- `PATH`、`HOME`、`USER`、`LANG`、`LC_ALL`、`TERM`、`SHELL`、`TMPDIR` -- 所有 `XDG_*` 变量 - -所有其他环境变量(API 密钥、token、密钥等)均被排除,除非你通过 `env` 配置键显式添加。这可防止凭据意外泄露给不受信任的 MCP 服务器。 - -```yaml -mcp_servers: - github: - command: "npx" - args: ["-y", "@modelcontextprotocol/server-github"] - env: - # 只有此 token 会传递给子进程 - GITHUB_PERSONAL_ACCESS_TOKEN: "ghp_..." -``` - -### 错误消息中的凭据脱敏 - -若 MCP 工具调用失败,错误消息中任何类似凭据的模式都会在展示给 LLM 之前自动脱敏。涵盖: - -- GitHub PAT(`ghp_...`) -- OpenAI 风格密钥(`sk-...`) -- Bearer token -- 通用的 `token=`、`key=`、`API_KEY=`、`password=`、`secret=` 模式 - -## 故障排查 - -### "MCP SDK not available -- skipping MCP tool discovery" - -`mcp` Python 包未安装。请安装: - -```bash -pip install mcp -``` - -### "No MCP servers configured" - -`~/.hermes/config.yaml` 中没有 `mcp_servers` 键,或该键为空。请至少添加一个服务器。 - -### "Failed to connect to MCP server 'X'" - -常见原因: -- **命令未找到**:`command` 指定的二进制文件不在 PATH 中。请确保 `npx`、`uvx` 或相关命令已安装。 -- **包未找到**:对于 npx 服务器,npm 包可能不存在,或需要在 args 中加入 `-y` 以自动安装。 -- **超时**:服务器启动耗时过长。请增大 `connect_timeout`。 -- **端口冲突**:对于 HTTP 服务器,URL 可能无法访问。 - -### "MCP server 'X' requires HTTP transport but mcp.client.streamable_http is not available" - -你安装的 `mcp` 包版本不包含 HTTP 客户端支持。请升级: - -```bash -pip install --upgrade mcp -``` - -### 工具未出现 - -- 检查服务器是否列在 `mcp_servers` 下(而非 `mcp` 或 `servers`) -- 确保 YAML 缩进正确 -- 查看 Hermes Agent 启动日志中的连接信息 -- 工具名称以 `mcp_{server}_{tool}` 为前缀——请查找该模式 - -### 连接持续断开 - -客户端以指数退避方式最多重试 5 次(1s、2s、4s、8s、16s,上限 60s)。若服务器根本无法访问,5 次尝试后将放弃。请检查服务器进程和网络连通性。 - -## 示例 - -### 时间服务器(uvx) - -```yaml -mcp_servers: - time: - command: "uvx" - args: ["mcp-server-time"] -``` - -注册如 `mcp_time_get_current_time` 等工具。 - -### 文件系统服务器(npx) - -```yaml -mcp_servers: - filesystem: - command: "npx" - args: ["-y", "@modelcontextprotocol/server-filesystem", "/home/user/documents"] - timeout: 30 -``` - -注册如 `mcp_filesystem_read_file`、`mcp_filesystem_write_file`、`mcp_filesystem_list_directory` 等工具。 - -### 带认证的 GitHub 服务器 - -```yaml -mcp_servers: - github: - command: "npx" - args: ["-y", "@modelcontextprotocol/server-github"] - env: - GITHUB_PERSONAL_ACCESS_TOKEN: "ghp_xxxxxxxxxxxxxxxxxxxx" - timeout: 60 -``` - -注册如 `mcp_github_list_issues`、`mcp_github_create_pull_request` 等工具。 - -### 远程 HTTP 服务器 - -```yaml -mcp_servers: - company_api: - url: "https://mcp.mycompany.com/v1/mcp" - headers: - Authorization: "Bearer sk-xxxxxxxxxxxxxxxxxxxx" - X-Team-Id: "engineering" - timeout: 180 - connect_timeout: 30 -``` - -### 多服务器 - -```yaml -mcp_servers: - time: - command: "uvx" - args: ["mcp-server-time"] - - filesystem: - command: "npx" - args: ["-y", "@modelcontextprotocol/server-filesystem", "/tmp"] - - github: - command: "npx" - args: ["-y", "@modelcontextprotocol/server-github"] - env: - GITHUB_PERSONAL_ACCESS_TOKEN: "ghp_xxxxxxxxxxxxxxxxxxxx" - - company_api: - url: "https://mcp.internal.company.com/mcp" - headers: - Authorization: "Bearer sk-xxxxxxxxxxxxxxxxxxxx" - timeout: 300 -``` - -所有服务器的所有工具同时注册并可用。每个服务器的工具以其名称为前缀,避免冲突。 - -## Sampling(服务器发起的 LLM 请求) - -Hermes 支持 MCP 的 `sampling/createMessage` 能力——MCP 服务器可在工具执行期间通过 agent 请求 LLM 补全。这支持 agent-in-the-loop 工作流(数据分析、内容生成、决策制定)。 - -Sampling **默认启用**。可按服务器配置: - -```yaml -mcp_servers: - my_server: - command: "npx" - args: ["-y", "my-mcp-server"] - sampling: - enabled: true # 默认:true - model: "gemini-3-flash" # 模型覆盖(可选) - max_tokens_cap: 4096 # 每次请求最大 token 数 - timeout: 30 # LLM 调用超时(秒) - max_rpm: 10 # 每分钟最大请求数 - allowed_models: [] # 模型白名单(空 = 全部允许) - max_tool_rounds: 5 # 工具循环上限(0 = 禁用) - log_level: "info" # 审计日志详细程度 -``` - -服务器还可以在 sampling 请求中包含 `tools`,用于多轮工具增强工作流。`max_tool_rounds` 配置可防止无限工具循环。每个服务器的审计指标(请求数、错误数、token 数、工具使用次数)通过 `get_mcp_status()` 追踪。 - -对不受信任的服务器,可通过 `sampling: { enabled: false }` 禁用 sampling。 - -## 注意事项 - -- MCP 工具从 agent 角度同步调用,但在专用后台事件循环上异步运行 -- 工具结果以 JSON 形式返回,格式为 `{"result": "..."}` 或 `{"error": "..."}` -- native MCP 客户端与 `mcporter` 相互独立——可同时使用两者 -- 服务器连接在同一 agent 进程的所有对话中持久共享 -- 添加或移除服务器需要重启 agent(当前不支持热重载) \ No newline at end of file diff --git a/website/i18n/zh-Hans/docusaurus-plugin-content-docs/current/user-guide/skills/bundled/media/media-spotify.md b/website/i18n/zh-Hans/docusaurus-plugin-content-docs/current/user-guide/skills/bundled/media/media-spotify.md deleted file mode 100644 index 66a5414ee..000000000 --- a/website/i18n/zh-Hans/docusaurus-plugin-content-docs/current/user-guide/skills/bundled/media/media-spotify.md +++ /dev/null @@ -1,151 +0,0 @@ ---- -title: "Spotify — Spotify:播放、搜索、队列、管理播放列表和设备" -sidebar_label: "Spotify" -description: "Spotify:播放、搜索、队列、管理播放列表和设备" ---- - -{/* This page is auto-generated from the skill's SKILL.md by website/scripts/generate-skill-docs.py. Edit the source SKILL.md, not this page. */} - -# Spotify - -Spotify:播放、搜索、队列、管理播放列表和设备。 - -## Skill 元数据 - -| | | -|---|---| -| 来源 | 内置(默认安装) | -| 路径 | `skills/media/spotify` | -| 版本 | `1.0.0` | -| 作者 | Hermes Agent | -| 许可证 | MIT | -| 平台 | linux, macos, windows | -| 标签 | `spotify`, `music`, `playback`, `playlists`, `media` | -| 相关 skill | [`gif-search`](/user-guide/skills/bundled/media/media-gif-search) | - -## 参考:完整 SKILL.md - -:::info -以下是 Hermes 在触发此 skill 时加载的完整 skill 定义。这是 agent 在 skill 激活时所看到的指令内容。 -::: - -# Spotify - -通过 Hermes Spotify 工具集(7 个工具)控制用户的 Spotify 账户。设置指南:https://hermes-agent.nousresearch.com/docs/user-guide/features/spotify - -## 何时使用此 skill - -用户说出类似以下内容时:"play X"、"pause"、"skip"、"queue up X"、"what's playing"、"search for X"、"add to my X playlist"、"make a playlist"、"save this to my library" 等。 - -## 7 个工具 - -- `spotify_playback` — play、pause、next、previous、seek、set_repeat、set_shuffle、set_volume、get_state、get_currently_playing、recently_played -- `spotify_devices` — list、transfer -- `spotify_queue` — get、add -- `spotify_search` — 搜索曲库 -- `spotify_playlists` — list、get、create、add_items、remove_items、update_details -- `spotify_albums` — get、tracks -- `spotify_library` — 使用 `kind: "tracks"|"albums"` 进行 list/save/remove - -修改播放状态的操作需要 Spotify Premium;搜索/曲库/播放列表操作在免费版上也可使用。 - -## 规范模式(最小化工具调用次数) - -### "Play <artist/track/album>" -一次搜索,然后通过 URI 播放。除非用户要求选项,否则**不要**循环遍历搜索结果并逐一描述。 - -``` -spotify_search({"query": "miles davis kind of blue", "types": ["album"], "limit": 1}) -→ got album URI spotify:album:1weenld61qoidwYuZ1GESA -spotify_playback({"action": "play", "context_uri": "spotify:album:1weenld61qoidwYuZ1GESA"}) -``` - -对于"play some <artist>"(无特定歌曲),优先使用 `types: ["artist"]` 并播放艺术家的 context URI — Spotify 会自动处理智能随机播放。如果用户说"the song"或"that track",则搜索 `types: ["track"]` 并将 `uris: [track_uri]` 传给 play。 - -### "What's playing?" / "What am I listening to?" -单次调用——不要在 get_currently_playing 之后再链式调用 get_state。 - -``` -spotify_playback({"action": "get_currently_playing"}) -``` - -如果返回 204/空(`is_playing: false`),告知用户当前没有播放内容。不要重试。 - -### "Pause" / "Skip" / "Volume 50" -直接执行操作,无需预先检查状态。 - -``` -spotify_playback({"action": "pause"}) -spotify_playback({"action": "next"}) -spotify_playback({"action": "set_volume", "volume_percent": 50}) -``` - -### "Add to my <playlist name> playlist" -1. 用 `spotify_playlists list` 按名称查找播放列表 ID -2. 获取曲目 URI(来自当前播放,或通过搜索) -3. 用 playlist_id 和 URI 调用 `spotify_playlists add_items` - -``` -spotify_playlists({"action": "list"}) -→ found "Late Night Jazz" = 37i9dQZF1DX4wta20PHgwo -spotify_playback({"action": "get_currently_playing"}) -→ current track uri = spotify:track:0DiWol3AO6WpXZgp0goxAV -spotify_playlists({"action": "add_items", - "playlist_id": "37i9dQZF1DX4wta20PHgwo", - "uris": ["spotify:track:0DiWol3AO6WpXZgp0goxAV"]}) -``` - -### "Create a playlist called X and add the last 3 songs I played" -``` -spotify_playback({"action": "recently_played", "limit": 3}) -spotify_playlists({"action": "create", "name": "Focus 2026"}) -→ got playlist_id back in response -spotify_playlists({"action": "add_items", "playlist_id": <id>, "uris": [<3 uris>]}) -``` - -### "Save / unsave / is this saved?" -使用 `spotify_library` 并指定正确的 `kind`。 - -``` -spotify_library({"kind": "tracks", "action": "save", "uris": ["spotify:track:..."]}) -spotify_library({"kind": "albums", "action": "list", "limit": 50}) -``` - -### "Transfer playback to my <device>" -``` -spotify_devices({"action": "list"}) -→ pick the device_id by matching name/type -spotify_devices({"action": "transfer", "device_id": "<id>", "play": true}) -``` - -## 关键失败模式 - -**`403 Forbidden — No active device found`** 出现在任何播放操作上,意味着 Spotify 在任何地方都未运行。告知用户:"请先在手机/桌面/网页播放器上打开 Spotify,随便播放一首曲目几秒钟,然后重试。"不要盲目重试工具调用——结果会完全相同。可以调用 `spotify_devices list` 确认;空列表意味着没有活跃设备。 - -**`403 Forbidden — Premium required`** 意味着用户使用的是免费版,并尝试修改播放状态。不要重试;告知用户此操作需要 Premium。读取操作仍然有效(搜索、播放列表、曲库、get_state)。 - -**`get_currently_playing` 返回 `204 No Content`** 不是错误——它表示当前没有播放内容。工具返回 `is_playing: false`。直接将此情况告知用户即可。 - -**`429 Too Many Requests`** = 速率限制。等待后重试一次。如果持续发生,说明你在循环——停止。 - -**`401 Unauthorized` 重试后仍出现** — 刷新令牌已被撤销。告知用户重新运行 `hermes auth spotify`。 - -## URI 和 ID 格式 - -Spotify 使用三种可互换的 ID 格式。工具接受所有三种并会自动规范化: - -- URI:`spotify:track:0DiWol3AO6WpXZgp0goxAV`(推荐) -- URL:`https://open.spotify.com/track/0DiWol3AO6WpXZgp0goxAV` -- 裸 ID:`0DiWol3AO6WpXZgp0goxAV` - -如有疑问,使用完整 URI。搜索结果在 `uri` 字段中返回 URI——直接传入即可。 - -实体类型:`track`、`album`、`artist`、`playlist`、`show`、`episode`。请为操作使用正确的类型——`spotify_playback.play` 的 `context_uri` 期望 album/playlist/artist;`uris` 期望曲目 URI 数组。 - -## 禁止事项 - -- **不要在每次操作前调用 `get_state`。** Spotify 接受 play/pause/skip 而无需预检。仅在用户询问"what's playing"或需要推断设备/曲目时才检查状态。 -- **除非被要求,否则不要描述搜索结果。** 如果用户说"play X",搜索、获取排名第一的 URI、播放。如果播放错了,他们自己会听出来。 -- **不要在 `403 Premium required` 或 `403 No active device` 时重试。** 在用户采取行动之前,这些错误是永久性的。 -- **不要用 `spotify_search` 按名称查找播放列表** — 那会搜索 Spotify 公开曲库。用户播放列表来自 `spotify_playlists list`。 -- **不要在 `spotify_library` 中将 `kind: "tracks"` 与专辑 URI 混用**(反之亦然)。工具会规范化 ID,但 API 端点不同。 \ No newline at end of file diff --git a/website/i18n/zh-Hans/docusaurus-plugin-content-docs/current/user-guide/skills/bundled/mlops/mlops-research-dspy.md b/website/i18n/zh-Hans/docusaurus-plugin-content-docs/current/user-guide/skills/bundled/mlops/mlops-research-dspy.md deleted file mode 100644 index e33864c1a..000000000 --- a/website/i18n/zh-Hans/docusaurus-plugin-content-docs/current/user-guide/skills/bundled/mlops/mlops-research-dspy.md +++ /dev/null @@ -1,609 +0,0 @@ ---- -title: "Dspy — DSPy:声明式语言模型程序、自动优化 prompt、RAG" -sidebar_label: "Dspy" -description: "DSPy:声明式语言模型程序、自动优化 prompt、RAG" ---- - -{/* This page is auto-generated from the skill's SKILL.md by website/scripts/generate-skill-docs.py. Edit the source SKILL.md, not this page. */} - -# Dspy - -DSPy:声明式语言模型程序、自动优化 prompt(提示词)、RAG(检索增强生成)。 - -## Skill 元数据 - -| | | -|---|---| -| 来源 | 内置(默认安装) | -| 路径 | `skills/mlops/research/dspy` | -| 版本 | `1.0.0` | -| 作者 | Orchestra Research | -| 许可证 | MIT | -| 依赖 | `dspy`, `openai`, `anthropic` | -| 平台 | linux, macos, windows | -| 标签 | `Prompt Engineering`, `DSPy`, `Declarative Programming`, `RAG`, `Agents`, `Prompt Optimization`, `LM Programming`, `Stanford NLP`, `Automatic Optimization`, `Modular AI` | - -## 参考:完整 SKILL.md - -:::info -以下是 Hermes 在触发此 skill 时加载的完整 skill 定义。这是 skill 激活时 agent 所看到的指令内容。 -::: - -# DSPy:声明式语言模型编程 - -## 何时使用此 Skill - -在以下场景中使用 DSPy: -- **构建复杂 AI 系统**,包含多个组件和工作流 -- **以声明式方式编程语言模型**,而非手动进行 prompt 工程 -- **使用数据驱动方法自动优化 prompt** -- **创建可维护、可移植的模块化 AI 流水线** -- **通过优化器系统性地改善模型输出** -- **构建可靠性更高的 RAG 系统、agent 或分类器** - -**GitHub Stars**:22,000+ | **创建者**:Stanford NLP - -## 安装 - -```bash -# 稳定版本 -pip install dspy - -# 最新开发版本 -pip install git+https://github.com/stanfordnlp/dspy.git - -# 指定语言模型提供商 -pip install dspy[openai] # OpenAI -pip install dspy[anthropic] # Anthropic Claude -pip install dspy[all] # 所有提供商 -``` - -## 快速开始 - -### 基础示例:问答 - -```python -import dspy - -# 配置语言模型 -lm = dspy.Claude(model="claude-sonnet-4-5-20250929") -dspy.settings.configure(lm=lm) - -# 定义 signature(输入 → 输出) -class QA(dspy.Signature): - """Answer questions with short factual answers.""" - question = dspy.InputField() - answer = dspy.OutputField(desc="often between 1 and 5 words") - -# 创建模块 -qa = dspy.Predict(QA) - -# 使用 -response = qa(question="What is the capital of France?") -print(response.answer) # "Paris" -``` - -### 思维链推理 - -```python -import dspy - -lm = dspy.Claude(model="claude-sonnet-4-5-20250929") -dspy.settings.configure(lm=lm) - -# 使用 ChainOfThought 获得更好的推理效果 -class MathProblem(dspy.Signature): - """Solve math word problems.""" - problem = dspy.InputField() - answer = dspy.OutputField(desc="numerical answer") - -# ChainOfThought 自动生成推理步骤 -cot = dspy.ChainOfThought(MathProblem) - -response = cot(problem="If John has 5 apples and gives 2 to Mary, how many does he have?") -print(response.rationale) # 显示推理步骤 -print(response.answer) # "3" -``` - -## 核心概念 - -### 1. Signature - -Signature 定义 AI 任务的结构(输入 → 输出): - -```python -# 内联 signature(简单形式) -qa = dspy.Predict("question -> answer") - -# 类 signature(详细形式) -class Summarize(dspy.Signature): - """Summarize text into key points.""" - text = dspy.InputField() - summary = dspy.OutputField(desc="bullet points, 3-5 items") - -summarizer = dspy.ChainOfThought(Summarize) -``` - -**各形式适用场景:** -- **内联**:快速原型开发、简单任务 -- **类**:复杂任务、类型提示、更好的文档说明 - -### 2. 模块 - -模块是将输入转换为输出的可复用组件: - -#### dspy.Predict -基础预测模块: - -```python -predictor = dspy.Predict("context, question -> answer") -result = predictor(context="Paris is the capital of France", - question="What is the capital?") -``` - -#### dspy.ChainOfThought -在回答前生成推理步骤: - -```python -cot = dspy.ChainOfThought("question -> answer") -result = cot(question="Why is the sky blue?") -print(result.rationale) # 推理步骤 -print(result.answer) # 最终答案 -``` - -#### dspy.ReAct -带工具的类 agent 推理: - -```python -from dspy.predict import ReAct - -class SearchQA(dspy.Signature): - """Answer questions using search.""" - question = dspy.InputField() - answer = dspy.OutputField() - -def search_tool(query: str) -> str: - """Search Wikipedia.""" - # 你的搜索实现 - return results - -react = ReAct(SearchQA, tools=[search_tool]) -result = react(question="When was Python created?") -``` - -#### dspy.ProgramOfThought -生成并执行代码进行推理: - -```python -pot = dspy.ProgramOfThought("question -> answer") -result = pot(question="What is 15% of 240?") -# 生成:answer = 240 * 0.15 -``` - -### 3. 优化器 - -优化器使用训练数据自动改善你的模块: - -#### BootstrapFewShot -从示例中学习: - -```python -from dspy.teleprompt import BootstrapFewShot - -# 训练数据 -trainset = [ - dspy.Example(question="What is 2+2?", answer="4").with_inputs("question"), - dspy.Example(question="What is 3+5?", answer="8").with_inputs("question"), -] - -# 定义指标 -def validate_answer(example, pred, trace=None): - return example.answer == pred.answer - -# 优化 -optimizer = BootstrapFewShot(metric=validate_answer, max_bootstrapped_demos=3) -optimized_qa = optimizer.compile(qa, trainset=trainset) - -# 现在 optimized_qa 性能更好! -``` - -#### MIPRO(最重要的 Prompt 优化) -迭代式改善 prompt: - -```python -from dspy.teleprompt import MIPRO - -optimizer = MIPRO( - metric=validate_answer, - num_candidates=10, - init_temperature=1.0 -) - -optimized_cot = optimizer.compile( - cot, - trainset=trainset, - num_trials=100 -) -``` - -#### BootstrapFinetune -为模型微调创建数据集: - -```python -from dspy.teleprompt import BootstrapFinetune - -optimizer = BootstrapFinetune(metric=validate_answer) -optimized_module = optimizer.compile(qa, trainset=trainset) - -# 导出用于微调的训练数据 -``` - -### 4. 构建复杂系统 - -#### 多阶段流水线 - -```python -import dspy - -class MultiHopQA(dspy.Module): - def __init__(self): - super().__init__() - self.retrieve = dspy.Retrieve(k=3) - self.generate_query = dspy.ChainOfThought("question -> search_query") - self.generate_answer = dspy.ChainOfThought("context, question -> answer") - - def forward(self, question): - # 阶段 1:生成搜索查询 - search_query = self.generate_query(question=question).search_query - - # 阶段 2:检索上下文 - passages = self.retrieve(search_query).passages - context = "\n".join(passages) - - # 阶段 3:生成答案 - answer = self.generate_answer(context=context, question=question).answer - return dspy.Prediction(answer=answer, context=context) - -# 使用流水线 -qa_system = MultiHopQA() -result = qa_system(question="Who wrote the book that inspired the movie Blade Runner?") -``` - -#### 带优化的 RAG 系统 - -```python -import dspy -from dspy.retrieve.chromadb_rm import ChromadbRM - -# 配置检索器 -retriever = ChromadbRM( - collection_name="documents", - persist_directory="./chroma_db" -) - -class RAG(dspy.Module): - def __init__(self, num_passages=3): - super().__init__() - self.retrieve = dspy.Retrieve(k=num_passages) - self.generate = dspy.ChainOfThought("context, question -> answer") - - def forward(self, question): - context = self.retrieve(question).passages - return self.generate(context=context, question=question) - -# 创建并优化 -rag = RAG() - -# 使用训练数据优化 -from dspy.teleprompt import BootstrapFewShot - -optimizer = BootstrapFewShot(metric=validate_answer) -optimized_rag = optimizer.compile(rag, trainset=trainset) -``` - -## 语言模型提供商配置 - -### Anthropic Claude - -```python -import dspy - -lm = dspy.Claude( - model="claude-sonnet-4-5-20250929", - api_key="your-api-key", # 或设置 ANTHROPIC_API_KEY 环境变量 - max_tokens=1000, - temperature=0.7 -) -dspy.settings.configure(lm=lm) -``` - -### OpenAI - -```python -lm = dspy.OpenAI( - model="gpt-4", - api_key="your-api-key", - max_tokens=1000 -) -dspy.settings.configure(lm=lm) -``` - -### 本地模型(Ollama) - -```python -lm = dspy.OllamaLocal( - model="llama3.1", - base_url="http://localhost:11434" -) -dspy.settings.configure(lm=lm) -``` - -### 多模型 - -```python -# 不同任务使用不同模型 -cheap_lm = dspy.OpenAI(model="gpt-3.5-turbo") -strong_lm = dspy.Claude(model="claude-sonnet-4-5-20250929") - -# 检索使用廉价模型,推理使用强力模型 -with dspy.settings.context(lm=cheap_lm): - context = retriever(question) - -with dspy.settings.context(lm=strong_lm): - answer = generator(context=context, question=question) -``` - -## 常见模式 - -### 模式 1:结构化输出 - -```python -from pydantic import BaseModel, Field - -class PersonInfo(BaseModel): - name: str = Field(description="Full name") - age: int = Field(description="Age in years") - occupation: str = Field(description="Current job") - -class ExtractPerson(dspy.Signature): - """Extract person information from text.""" - text = dspy.InputField() - person: PersonInfo = dspy.OutputField() - -extractor = dspy.TypedPredictor(ExtractPerson) -result = extractor(text="John Doe is a 35-year-old software engineer.") -print(result.person.name) # "John Doe" -print(result.person.age) # 35 -``` - -### 模式 2:断言驱动优化 - -```python -import dspy -from dspy.primitives.assertions import assert_transform_module, backtrack_handler - -class MathQA(dspy.Module): - def __init__(self): - super().__init__() - self.solve = dspy.ChainOfThought("problem -> solution: float") - - def forward(self, problem): - solution = self.solve(problem=problem).solution - - # 断言解答为数值 - dspy.Assert( - isinstance(float(solution), float), - "Solution must be a number", - backtrack=backtrack_handler - ) - - return dspy.Prediction(solution=solution) -``` - -### 模式 3:自洽性 - -```python -import dspy -from collections import Counter - -class ConsistentQA(dspy.Module): - def __init__(self, num_samples=5): - super().__init__() - self.qa = dspy.ChainOfThought("question -> answer") - self.num_samples = num_samples - - def forward(self, question): - # 生成多个答案 - answers = [] - for _ in range(self.num_samples): - result = self.qa(question=question) - answers.append(result.answer) - - # 返回最常见的答案 - most_common = Counter(answers).most_common(1)[0][0] - return dspy.Prediction(answer=most_common) -``` - -### 模式 4:带重排序的检索 - -```python -class RerankedRAG(dspy.Module): - def __init__(self): - super().__init__() - self.retrieve = dspy.Retrieve(k=10) - self.rerank = dspy.Predict("question, passage -> relevance_score: float") - self.answer = dspy.ChainOfThought("context, question -> answer") - - def forward(self, question): - # 检索候选段落 - passages = self.retrieve(question).passages - - # 对段落重排序 - scored = [] - for passage in passages: - score = float(self.rerank(question=question, passage=passage).relevance_score) - scored.append((score, passage)) - - # 取前 3 名 - top_passages = [p for _, p in sorted(scored, reverse=True)[:3]] - context = "\n\n".join(top_passages) - - # 生成答案 - return self.answer(context=context, question=question) -``` - -## 评估与指标 - -### 自定义指标 - -```python -def exact_match(example, pred, trace=None): - """精确匹配指标。""" - return example.answer.lower() == pred.answer.lower() - -def f1_score(example, pred, trace=None): - """文本重叠的 F1 分数。""" - pred_tokens = set(pred.answer.lower().split()) - gold_tokens = set(example.answer.lower().split()) - - if not pred_tokens: - return 0.0 - - precision = len(pred_tokens & gold_tokens) / len(pred_tokens) - recall = len(pred_tokens & gold_tokens) / len(gold_tokens) - - if precision + recall == 0: - return 0.0 - - return 2 * (precision * recall) / (precision + recall) -``` - -### 评估 - -```python -from dspy.evaluate import Evaluate - -# 创建评估器 -evaluator = Evaluate( - devset=testset, - metric=exact_match, - num_threads=4, - display_progress=True -) - -# 评估模型 -score = evaluator(qa_system) -print(f"Accuracy: {score}") - -# 比较优化前后 -score_before = evaluator(qa) -score_after = evaluator(optimized_qa) -print(f"Improvement: {score_after - score_before:.2%}") -``` - -## 最佳实践 - -### 1. 从简单开始,逐步迭代 - -```python -# 从 Predict 开始 -qa = dspy.Predict("question -> answer") - -# 如有需要,添加推理 -qa = dspy.ChainOfThought("question -> answer") - -# 有数据后进行优化 -optimized_qa = optimizer.compile(qa, trainset=data) -``` - -### 2. 使用描述性 Signature - -```python -# ❌ 差:模糊 -class Task(dspy.Signature): - input = dspy.InputField() - output = dspy.OutputField() - -# ✅ 好:描述性强 -class SummarizeArticle(dspy.Signature): - """Summarize news articles into 3-5 key points.""" - article = dspy.InputField(desc="full article text") - summary = dspy.OutputField(desc="bullet points, 3-5 items") -``` - -### 3. 使用有代表性的数据进行优化 - -```python -# 创建多样化的训练示例 -trainset = [ - dspy.Example(question="factual", answer="...).with_inputs("question"), - dspy.Example(question="reasoning", answer="...").with_inputs("question"), - dspy.Example(question="calculation", answer="...").with_inputs("question"), -] - -# 使用验证集计算指标 -def metric(example, pred, trace=None): - return example.answer in pred.answer -``` - -### 4. 保存和加载优化后的模型 - -```python -# 保存 -optimized_qa.save("models/qa_v1.json") - -# 加载 -loaded_qa = dspy.ChainOfThought("question -> answer") -loaded_qa.load("models/qa_v1.json") -``` - -### 5. 监控与调试 - -```python -# 启用追踪 -dspy.settings.configure(lm=lm, trace=[]) - -# 运行预测 -result = qa(question="...") - -# 检查追踪记录 -for call in dspy.settings.trace: - print(f"Prompt: {call['prompt']}") - print(f"Response: {call['response']}") -``` - -## 与其他方案的对比 - -| 特性 | 手动 Prompt | LangChain | DSPy | -|---------|-----------------|-----------|------| -| Prompt 工程 | 手动 | 手动 | 自动 | -| 优化方式 | 试错 | 无 | 数据驱动 | -| 模块化程度 | 低 | 中 | 高 | -| 类型安全 | 否 | 有限 | 是(Signature) | -| 可移植性 | 低 | 中 | 高 | -| 学习曲线 | 低 | 中 | 中高 | - -**选择 DSPy 的场景:** -- 你有训练数据或可以生成训练数据 -- 你需要系统性地改善 prompt -- 你在构建复杂的多阶段系统 -- 你希望跨不同语言模型进行优化 - -**选择其他方案的场景:** -- 快速原型开发(手动 prompt) -- 使用现有工具的简单链式调用(LangChain) -- 需要自定义优化逻辑 - -## 资源 - -- **文档**:https://dspy.ai -- **GitHub**:https://github.com/stanfordnlp/dspy(22k+ stars) -- **Discord**:https://discord.gg/XCGy2WDCQB -- **Twitter**:@DSPyOSS -- **论文**:"DSPy: Compiling Declarative Language Model Calls into Self-Improving Pipelines" - -## 另请参阅 - -- `references/modules.md` — 详细模块指南(Predict、ChainOfThought、ReAct、ProgramOfThought) -- `references/optimizers.md` — 优化算法(BootstrapFewShot、MIPRO、BootstrapFinetune) -- `references/examples.md` — 真实世界示例(RAG、agent、分类器) \ No newline at end of file diff --git a/website/i18n/zh-Hans/docusaurus-plugin-content-docs/current/user-guide/skills/bundled/productivity/productivity-linear.md b/website/i18n/zh-Hans/docusaurus-plugin-content-docs/current/user-guide/skills/bundled/productivity/productivity-linear.md deleted file mode 100644 index 714013a9c..000000000 --- a/website/i18n/zh-Hans/docusaurus-plugin-content-docs/current/user-guide/skills/bundled/productivity/productivity-linear.md +++ /dev/null @@ -1,395 +0,0 @@ ---- -title: "Linear — Linear: manage issues, projects, teams via GraphQL + curl" -sidebar_label: "Linear" -description: "Linear:通过 GraphQL + curl 管理 issues、项目和团队" ---- - -{/* This page is auto-generated from the skill's SKILL.md by website/scripts/generate-skill-docs.py. Edit the source SKILL.md, not this page. */} - -# Linear - -Linear:通过 GraphQL + curl 管理 issues、项目和团队。 - -## Skill 元数据 - -| | | -|---|---| -| 来源 | 内置(默认安装) | -| 路径 | `skills/productivity/linear` | -| 版本 | `1.0.0` | -| 作者 | Hermes Agent | -| 许可证 | MIT | -| 平台 | linux, macos, windows | -| 标签 | `Linear`, `Project Management`, `Issues`, `GraphQL`, `API`, `Productivity` | - -## 参考:完整 SKILL.md - -:::info -以下是 Hermes 在触发此 skill 时加载的完整 skill 定义。这是 agent 在 skill 激活时所看到的指令内容。 -::: - -# Linear — Issue 与项目管理 - -直接通过 GraphQL API 使用 `curl` 管理 Linear 的 issues、项目和团队。无需 MCP server,无需 OAuth 流程,无需额外依赖。 - -## 配置 - -1. 从 **Linear 设置 > Account > Security & access > Personal API keys** 获取个人 API key(URL:https://linear.app/settings/account/security)。注意:组织级别的 *Settings > API* 页面仅显示 OAuth 应用和工作区成员 key,不显示个人 key。 -2. 在环境中设置 `LINEAR_API_KEY`(通过 `hermes setup` 或你的环境配置) - -## API 基础 - -- **端点:** `https://api.linear.app/graphql`(POST) -- **认证头:** `Authorization: $LINEAR_API_KEY`(API key 无需 "Bearer" 前缀) -- **所有请求均为 POST**,使用 `Content-Type: application/json` -- **UUID 和短标识符**(如 `ENG-123`)均可用于 `issue(id:)` - -基础 curl 模式: -```bash -curl -s -X POST https://api.linear.app/graphql \ - -H "Authorization: $LINEAR_API_KEY" \ - -H "Content-Type: application/json" \ - -d '{"query": "{ viewer { id name } }"}' | python3 -m json.tool -``` - -## Python 辅助脚本(更便捷的替代方案) - -如需无需手写 GraphQL 的快速单行命令,此 skill 提供了一个基于标准库的 Python CLI,路径为 `scripts/linear_api.py`。零依赖,使用相同的认证方式(读取 `LINEAR_API_KEY`)。 - -```bash -SCRIPT=$(dirname "$(find ~/.hermes -path '*skills/productivity/linear/scripts/linear_api.py' 2>/dev/null | head -1)")/linear_api.py - -python3 "$SCRIPT" whoami -python3 "$SCRIPT" list-teams -python3 "$SCRIPT" get-issue ENG-42 -python3 "$SCRIPT" get-document 38359beef67c # fetch a doc by slugId from the URL -python3 "$SCRIPT" raw 'query { viewer { name } }' -``` - -所有子命令:`whoami`、`list-teams`、`list-projects`、`list-states`、`list-issues`、`get-issue`、`search-issues`、`create-issue`、`update-issue`、`update-status`、`add-comment`、`list-documents`、`get-document`、`search-documents`、`raw`。运行时加 `--help` 查看参数说明。 - -适合使用脚本的场景:需要快速获取结果而不想编写 GraphQL。适合使用 curl 的场景:需要脚本未封装的查询,或需要内联组合过滤条件。 - -## 工作流状态 - -Linear 使用带有 `type` 字段的 `WorkflowState` 对象。**共 6 种状态类型:** - -| 类型 | 描述 | -|------|-------------| -| `triage` | 待审核的新 issue | -| `backlog` | 已确认但尚未规划 | -| `unstarted` | 已规划/就绪但未开始 | -| `started` | 正在积极处理中 | -| `completed` | 已完成 | -| `canceled` | 不予处理 | - -每个团队有其自己命名的状态(例如,"In Progress" 对应类型 `started`)。要更改 issue 的状态,需要目标状态的 `stateId`(UUID)——请先查询工作流状态。 - -**优先级值:** 0 = 无,1 = 紧急,2 = 高,3 = 中,4 = 低 - -## 常用查询 - -### 获取当前用户 -```bash -curl -s -X POST https://api.linear.app/graphql \ - -H "Authorization: $LINEAR_API_KEY" \ - -H "Content-Type: application/json" \ - -d '{"query": "{ viewer { id name email } }"}' | python3 -m json.tool -``` - -### 列出团队 -```bash -curl -s -X POST https://api.linear.app/graphql \ - -H "Authorization: $LINEAR_API_KEY" \ - -H "Content-Type: application/json" \ - -d '{"query": "{ teams { nodes { id name key } } }"}' | python3 -m json.tool -``` - -### 列出某团队的工作流状态 -```bash -curl -s -X POST https://api.linear.app/graphql \ - -H "Authorization: $LINEAR_API_KEY" \ - -H "Content-Type: application/json" \ - -d '{"query": "{ workflowStates(filter: { team: { key: { eq: \"ENG\" } } }) { nodes { id name type } } }"}' | python3 -m json.tool -``` - -### 列出 issues(前 20 条) -```bash -curl -s -X POST https://api.linear.app/graphql \ - -H "Authorization: $LINEAR_API_KEY" \ - -H "Content-Type: application/json" \ - -d '{"query": "{ issues(first: 20) { nodes { identifier title priority state { name type } assignee { name } team { key } url } pageInfo { hasNextPage endCursor } } }"}' | python3 -m json.tool -``` - -### 列出分配给我的 issues -```bash -curl -s -X POST https://api.linear.app/graphql \ - -H "Authorization: $LINEAR_API_KEY" \ - -H "Content-Type: application/json" \ - -d '{"query": "{ viewer { assignedIssues(first: 25) { nodes { identifier title state { name type } priority url } } } }"}' | python3 -m json.tool -``` - -### 获取单个 issue(通过标识符如 ENG-123) -```bash -curl -s -X POST https://api.linear.app/graphql \ - -H "Authorization: $LINEAR_API_KEY" \ - -H "Content-Type: application/json" \ - -d '{"query": "{ issue(id: \"ENG-123\") { id identifier title description priority state { id name type } assignee { id name } team { key } project { name } labels { nodes { name } } comments { nodes { body user { name } createdAt } } url } }"}' | python3 -m json.tool -``` - -### 按文本搜索 issues -```bash -curl -s -X POST https://api.linear.app/graphql \ - -H "Authorization: $LINEAR_API_KEY" \ - -H "Content-Type: application/json" \ - -d '{"query": "{ issueSearch(query: \"bug login\", first: 10) { nodes { identifier title state { name } assignee { name } url } } }"}' | python3 -m json.tool -``` - -### 按状态类型过滤 issues -```bash -curl -s -X POST https://api.linear.app/graphql \ - -H "Authorization: $LINEAR_API_KEY" \ - -H "Content-Type: application/json" \ - -d '{"query": "{ issues(filter: { state: { type: { in: [\"started\"] } } }, first: 20) { nodes { identifier title state { name } assignee { name } } } }"}' | python3 -m json.tool -``` - -### 按团队和负责人过滤 -```bash -curl -s -X POST https://api.linear.app/graphql \ - -H "Authorization: $LINEAR_API_KEY" \ - -H "Content-Type: application/json" \ - -d '{"query": "{ issues(filter: { team: { key: { eq: \"ENG\" } }, assignee: { email: { eq: \"user@example.com\" } } }, first: 20) { nodes { identifier title state { name } priority } } }"}' | python3 -m json.tool -``` - -### 列出项目 -```bash -curl -s -X POST https://api.linear.app/graphql \ - -H "Authorization: $LINEAR_API_KEY" \ - -H "Content-Type: application/json" \ - -d '{"query": "{ projects(first: 20) { nodes { id name description progress lead { name } teams { nodes { key } } url } } }"}' | python3 -m json.tool -``` - -### 列出团队成员 -```bash -curl -s -X POST https://api.linear.app/graphql \ - -H "Authorization: $LINEAR_API_KEY" \ - -H "Content-Type: application/json" \ - -d '{"query": "{ users { nodes { id name email active } } }"}' | python3 -m json.tool -``` - -### 列出标签 -```bash -curl -s -X POST https://api.linear.app/graphql \ - -H "Authorization: $LINEAR_API_KEY" \ - -H "Content-Type: application/json" \ - -d '{"query": "{ issueLabels { nodes { id name color } } }"}' | python3 -m json.tool -``` - -## 常用变更操作 - -### 创建 issue -```bash -curl -s -X POST https://api.linear.app/graphql \ - -H "Authorization: $LINEAR_API_KEY" \ - -H "Content-Type: application/json" \ - -d '{ - "query": "mutation($input: IssueCreateInput!) { issueCreate(input: $input) { success issue { id identifier title url } } }", - "variables": { - "input": { - "teamId": "TEAM_UUID", - "title": "Fix login bug", - "description": "Users cannot login with SSO", - "priority": 2 - } - } - }' | python3 -m json.tool -``` - -### 更新 issue 状态 -首先从上方的工作流状态查询中获取目标状态 UUID,然后: -```bash -curl -s -X POST https://api.linear.app/graphql \ - -H "Authorization: $LINEAR_API_KEY" \ - -H "Content-Type: application/json" \ - -d '{"query": "mutation { issueUpdate(id: \"ENG-123\", input: { stateId: \"STATE_UUID\" }) { success issue { identifier state { name type } } } }"}' | python3 -m json.tool -``` - -### 分配 issue -```bash -curl -s -X POST https://api.linear.app/graphql \ - -H "Authorization: $LINEAR_API_KEY" \ - -H "Content-Type: application/json" \ - -d '{"query": "mutation { issueUpdate(id: \"ENG-123\", input: { assigneeId: \"USER_UUID\" }) { success issue { identifier assignee { name } } } }"}' | python3 -m json.tool -``` - -### 设置优先级 -```bash -curl -s -X POST https://api.linear.app/graphql \ - -H "Authorization: $LINEAR_API_KEY" \ - -H "Content-Type: application/json" \ - -d '{"query": "mutation { issueUpdate(id: \"ENG-123\", input: { priority: 1 }) { success issue { identifier priority } } }"}' | python3 -m json.tool -``` - -### 添加评论 -```bash -curl -s -X POST https://api.linear.app/graphql \ - -H "Authorization: $LINEAR_API_KEY" \ - -H "Content-Type: application/json" \ - -d '{"query": "mutation { commentCreate(input: { issueId: \"ISSUE_UUID\", body: \"Investigated. Root cause is X.\" }) { success comment { id body } } }"}' | python3 -m json.tool -``` - -### 设置截止日期 -```bash -curl -s -X POST https://api.linear.app/graphql \ - -H "Authorization: $LINEAR_API_KEY" \ - -H "Content-Type: application/json" \ - -d '{"query": "mutation { issueUpdate(id: \"ENG-123\", input: { dueDate: \"2026-04-01\" }) { success issue { identifier dueDate } } }"}' | python3 -m json.tool -``` - -### 为 issue 添加标签 -```bash -curl -s -X POST https://api.linear.app/graphql \ - -H "Authorization: $LINEAR_API_KEY" \ - -H "Content-Type: application/json" \ - -d '{"query": "mutation { issueUpdate(id: \"ENG-123\", input: { labelIds: [\"LABEL_UUID_1\", \"LABEL_UUID_2\"] }) { success issue { identifier labels { nodes { name } } } } }"}' | python3 -m json.tool -``` - -### 将 issue 添加到项目 -```bash -curl -s -X POST https://api.linear.app/graphql \ - -H "Authorization: $LINEAR_API_KEY" \ - -H "Content-Type: application/json" \ - -d '{"query": "mutation { issueUpdate(id: \"ENG-123\", input: { projectId: \"PROJECT_UUID\" }) { success issue { identifier project { name } } } }"}' | python3 -m json.tool -``` - -### 创建项目 -```bash -curl -s -X POST https://api.linear.app/graphql \ - -H "Authorization: $LINEAR_API_KEY" \ - -H "Content-Type: application/json" \ - -d '{ - "query": "mutation($input: ProjectCreateInput!) { projectCreate(input: $input) { success project { id name url } } }", - "variables": { - "input": { - "name": "Q2 Auth Overhaul", - "description": "Replace legacy auth with OAuth2 and PKCE", - "teamIds": ["TEAM_UUID"] - } - } - }' | python3 -m json.tool -``` - -## 文档 - -Linear **Documents** 是与 issues 并列存储的文档(RFC、规范、笔记等)。它们有独立的 `documents` 根查询和 `document(id:)` 单条获取接口。 - -### 文档 URL 与 `slugId` - -文档 URL 格式如下: -``` -https://linear.app/<workspace>/document/<slug>-<hexSlugId> -``` - -末尾的十六进制段即为 `slugId`。示例:`https://linear.app/nousresearch/document/rfc-hermes-permission-gateway-discord-38359beef67c` → `slugId` 为 `38359beef67c`。 - -**重要 schema 细节:** Markdown 正文在 `content` 字段中。ProseMirror JSON 在 `contentState` 中(不是 `contentData`——该字段不存在,API 会返回 400)。 - -### 通过 slugId 获取文档 - -`document(id:)` 仅接受 UUID。若要通过 URL 中的十六进制 slug 获取,需过滤集合: - -```bash -curl -s -X POST https://api.linear.app/graphql \ - -H "Authorization: $LINEAR_API_KEY" \ - -H "Content-Type: application/json" \ - -d '{"query": "query($s: String!) { documents(filter: { slugId: { eq: $s } }, first: 1) { nodes { id title content contentState slugId url creator { name } project { name } updatedAt } } }", "variables": {"s": "38359beef67c"}}' \ - | python3 -m json.tool -``` - -或通过 Python 辅助脚本: -```bash -python3 scripts/linear_api.py get-document 38359beef67c -``` - -### 通过 UUID 获取文档 - -```bash -curl -s -X POST https://api.linear.app/graphql \ - -H "Authorization: $LINEAR_API_KEY" \ - -H "Content-Type: application/json" \ - -d '{"query": "{ document(id: \"11700cff-b514-4db3-afcc-3ed1afacba1c\") { title content url } }"}' \ - | python3 -m json.tool -``` - -### 列出最近文档 - -```bash -curl -s -X POST https://api.linear.app/graphql \ - -H "Authorization: $LINEAR_API_KEY" \ - -H "Content-Type: application/json" \ - -d '{"query": "{ documents(first: 25, orderBy: updatedAt) { nodes { id title slugId url updatedAt project { name } } } }"}' \ - | python3 -m json.tool -``` - -### 按标题搜索文档 - -Linear 的 schema 没有 `searchDocuments` 根查询。请改用标题子字符串过滤: - -```bash -curl -s -X POST https://api.linear.app/graphql \ - -H "Authorization: $LINEAR_API_KEY" \ - -H "Content-Type: application/json" \ - -d '{"query": "{ documents(filter: { title: { containsIgnoreCase: \"RFC\" } }, first: 25) { nodes { title slugId url } } }"}' \ - | python3 -m json.tool -``` - -## 分页 - -Linear 使用 Relay 风格的游标分页: - -```bash -# 第一页 -curl -s -X POST https://api.linear.app/graphql \ - -H "Authorization: $LINEAR_API_KEY" \ - -H "Content-Type: application/json" \ - -d '{"query": "{ issues(first: 20) { nodes { identifier title } pageInfo { hasNextPage endCursor } } }"}' | python3 -m json.tool - -# 下一页——使用上一响应中的 endCursor -curl -s -X POST https://api.linear.app/graphql \ - -H "Authorization: $LINEAR_API_KEY" \ - -H "Content-Type: application/json" \ - -d '{"query": "{ issues(first: 20, after: \"CURSOR_FROM_PREVIOUS\") { nodes { identifier title } pageInfo { hasNextPage endCursor } } }"}' | python3 -m json.tool -``` - -默认页大小:50。最大:250。始终使用 `first: N` 限制结果数量。 - -## 过滤参考 - -比较运算符:`eq`、`neq`、`in`、`nin`、`lt`、`lte`、`gt`、`gte`、`contains`、`startsWith`、`containsIgnoreCase` - -使用 `or: [...]` 实现 OR 逻辑(filter 对象内默认为 AND)。 - -## 典型工作流 - -1. **查询团队**,获取团队 ID 和 key -2. **查询目标团队的工作流状态**,获取状态 UUID -3. **列出或搜索 issues**,找到需要处理的内容 -4. **创建 issues**,提供团队 ID、标题、描述、优先级 -5. **更新状态**,将 `stateId` 设置为目标工作流状态 -6. **添加评论**,跟踪进度 -7. **标记完成**,将 `stateId` 设置为团队的 "completed" 类型状态 - -## 速率限制 - -- 每个 API key 每小时 5,000 次请求 -- 每小时 3,000,000 复杂度点 -- 使用 `first: N` 限制结果数量以降低复杂度消耗 -- 监控响应头 `X-RateLimit-Requests-Remaining` - -## 重要说明 - -- 始终使用 `terminal` 工具配合 `curl` 进行 API 调用——不要使用 `web_extract` 或 `browser` -- 始终检查 GraphQL 响应中的 `errors` 数组——HTTP 200 仍可能包含错误 -- 创建 issues 时若省略 `stateId`,Linear 默认使用第一个 backlog 状态 -- `description` 字段支持 Markdown -- 使用 `python3 -m json.tool` 或 `jq` 格式化 JSON 响应以提高可读性 \ No newline at end of file diff --git a/website/i18n/zh-Hans/docusaurus-plugin-content-docs/current/user-guide/skills/bundled/software-development/software-development-debugging-hermes-tui-commands.md b/website/i18n/zh-Hans/docusaurus-plugin-content-docs/current/user-guide/skills/bundled/software-development/software-development-debugging-hermes-tui-commands.md deleted file mode 100644 index f2aed6c8e..000000000 --- a/website/i18n/zh-Hans/docusaurus-plugin-content-docs/current/user-guide/skills/bundled/software-development/software-development-debugging-hermes-tui-commands.md +++ /dev/null @@ -1,172 +0,0 @@ ---- -title: "Debugging Hermes Tui Commands — Debug Hermes TUI slash commands: Python, gateway, Ink UI" -sidebar_label: "Debugging Hermes Tui Commands" -description: "调试 Hermes TUI slash 命令:Python、gateway、Ink UI" ---- - -{/* This page is auto-generated from the skill's SKILL.md by website/scripts/generate-skill-docs.py. Edit the source SKILL.md, not this page. */} - -# 调试 Hermes TUI 命令 - -调试 Hermes TUI slash(斜杠)命令:Python、gateway、Ink UI。 - -## Skill 元数据 - -| | | -|---|---| -| 来源 | 内置(默认安装) | -| 路径 | `skills/software-development/debugging-hermes-tui-commands` | -| 版本 | `1.0.0` | -| 作者 | Hermes Agent | -| 许可证 | MIT | -| 平台 | linux, macos, windows | -| 标签 | `debugging`, `hermes-agent`, `tui`, `slash-commands`, `typescript`, `python` | -| 相关 skill | [`python-debugpy`](/user-guide/skills/bundled/software-development/software-development-python-debugpy)、[`node-inspect-debugger`](/user-guide/skills/bundled/software-development/software-development-node-inspect-debugger)、[`systematic-debugging`](/user-guide/skills/bundled/software-development/software-development-systematic-debugging) | - -## 参考:完整 SKILL.md - -:::info -以下是 Hermes 在触发该 skill 时加载的完整 skill 定义。这是 agent 在 skill 激活时所看到的指令内容。 -::: - -# 调试 Hermes TUI Slash 命令 - -## 概述 - -Hermes slash 命令跨越三个层次——Python 命令注册表、tui_gateway JSON-RPC 桥接层,以及 Ink/TypeScript 前端。当某个命令出现异常(不在自动补全中显示、在 CLI 中正常但在 TUI 中不工作、配置已持久化但 UI 未更新),问题几乎总是某一层与另一层不同步所致。 - -当你在 Hermes TUI 中遇到 slash 命令问题时使用本 skill,尤其是命令未出现在自动补全中、在 TUI 中无法正常工作,或需要添加/更新命令时。 - -## 适用场景 - -- slash 命令存在于代码库的某一部分,但未完全生效 -- 需要同时在后端和前端添加某个命令 -- 特定命令的自动补全不工作 -- 命令在 CLI 和 TUI 之间行为不一致 -- 命令已持久化配置,但未在 TUI 中实时生效 - -## 架构概览 - -<!-- ascii-guard-ignore --> -``` -Python backend (hermes_cli/commands.py) <- 规范的 COMMAND_REGISTRY - │ - ▼ -TUI gateway (tui_gateway/server.py) <- slash.exec / command.dispatch - │ - ▼ -TUI frontend (ui-tui/src/app/slash/) <- 本地处理器 + fallthrough -``` -<!-- ascii-guard-ignore-end --> - -命令定义必须在 Python 和 TypeScript 中保持一致注册才能正常工作。Python 的 `COMMAND_REGISTRY` 是以下内容的唯一真实来源:CLI 分发、gateway 帮助、Telegram BotCommand 菜单、Slack 子命令映射,以及发送给 Ink 的自动补全数据。 - -## 排查步骤 - -1. **检查命令是否存在于 TUI 前端:** - ```bash - search_files --pattern "/commandname" --file_glob "*.ts" --path ui-tui/ - search_files --pattern "/commandname" --file_glob "*.tsx" --path ui-tui/ - ``` - -2. **查看 TUI 命令定义:** - ```bash - read_file ui-tui/src/app/slash/commands/core.ts - # 如果不在那里: - search_files --pattern "commandname" --path ui-tui/src/app/slash/commands --target files - ``` - -3. **检查命令是否存在于 Python 后端:** - ```bash - search_files --pattern "CommandDef" --file_glob "*.py" --path hermes_cli/ - search_files --pattern "commandname" --path hermes_cli/commands.py --context 3 - ``` - -4. **查看 gateway 实现:** - ```bash - search_files --pattern "complete.slash|slash.exec" --path tui_gateway/ - ``` - -## 修复:命令自动补全缺失 - -如果命令存在于 TUI 但未出现在自动补全中: - -1. 在 `hermes_cli/commands.py` 的 `COMMAND_REGISTRY` 中添加 `CommandDef` 条目: - ```python - CommandDef("commandname", "Description of the command", "Session", - cli_only=True, aliases=("alias",), - args_hint="[arg1|arg2|arg3]", - subcommands=("arg1", "arg2", "arg3")), - ``` - -2. 谨慎选择 `cli_only` 与 gateway 可用性: - - `cli_only=True` — 仅在交互式 CLI/TUI 中可用 - - `gateway_only=True` — 仅在消息平台中可用 - - 两者均不设置 — 所有地方均可用 - - `gateway_config_gate="display.foo"` — 在 gateway 中受配置项控制的可用性 - -3. 确保 `subcommands` 与 TUI 显示的预期 tab 补全选项一致。 - -4. 如果命令在服务端运行,在 `cli.py` 的 `HermesCLI.process_command()` 中添加处理器: - ```python - elif canonical == "commandname": - self._handle_commandname(cmd_original) - ``` - -5. 对于 gateway 可用的命令,在 `gateway/run.py` 中添加处理器: - ```python - if canonical == "commandname": - return await self._handle_commandname(event) - ``` - -## 常见问题 - -1. **命令在 TUI 中显示但不在自动补全中。** 命令已在 TUI 代码库中定义,但 `hermes_cli/commands.py` 的 `COMMAND_REGISTRY` 中缺失。自动补全数据由 Python 端提供。 - -2. **命令在自动补全中显示但不工作。** 检查 `tui_gateway/server.py` 中的命令处理器,以及 `ui-tui/src/app/createSlashHandler.ts` 中的前端处理器。如果命令在 Ink 中是纯本地命令,必须在 `app.tsx` 的内置分支中处理;否则会 fallthrough 到 `slash.exec`,必须有对应的 Python 处理器。 - -3. **命令在 CLI 和 TUI 之间行为不同。** 该命令可能有不同的实现。同时检查 `cli.py::process_command` 和 TUI 的本地处理器。TUI 本地处理器优先于 gateway 分发。 - -4. **命令已持久化配置但未实时生效。** 对于 TUI 本地命令,仅更新 `config.set` 是不够的。还需立即修改相关的 nanostore 状态(通常是 `patchUiState(...)`),并将新状态传递给所有渲染组件。示例:`/details collapsed` 必须实时更新详情可见性,而不仅仅是保存 `details_mode`;会话内全局 `/details <mode>` 可能需要单独的命令覆盖标志,以便实时命令能覆盖内置分区默认值,同时启动/配置同步保留默认展开的 thinking/tools 行为。 - -5. **Gateway 分发静默忽略命令。** Gateway 只分发它已知的命令。检查 `GATEWAY_KNOWN_COMMANDS`(自动从 `COMMAND_REGISTRY` 派生)是否包含规范名称。如果命令是带有 `gateway_config_gate` 的 `cli_only`,验证被门控的配置值是否为真值。 - -## 调试策略 - -当表层排查无法定位问题时: - -- **Python 端挂起或行为异常:** 使用 `python-debugpy` skill 在 `_SlashWorker.exec` 或命令处理器内设置断点。在处理器入口处设置 `remote-pdb` 是最快的方式。 -- **Ink 端无响应:** 使用 `node-inspect-debugger` skill 在 `app.tsx` 的 slash 分发或本地命令分支处设置断点。`npm run build` 后执行 `sb('dist/app.js', <line>)`。 -- **注册表不匹配/不清楚哪一侧有问题:** 将规范的 `COMMAND_REGISTRY` 条目与 TUI 的本地命令列表并排比较。 - -## 注意事项 - -- 不要忘记在 `CommandDef` 中为命令设置适当的分类(例如 "Session"、"Configuration"、"Tools & Skills"、"Info"、"Exit") -- 确保所有别名都正确注册在 `aliases` 元组中——无需修改其他文件,下游所有内容(Telegram 菜单、Slack 映射、自动补全、帮助)均从此派生 -- 对于带子命令的命令,确保 `CommandDef` 中的 `subcommands` 元组与 TUI 代码中的内容一致 -- `cli_only=True` 的命令在 gateway/消息平台中不可用——除非添加 `gateway_config_gate` 且该门控值为真 -- 添加实时 UI 状态后,搜索旧 prop/helper 的所有消费者,并将新状态贯穿所有渲染路径,而不仅仅是活跃的流式路径。TUI 详情渲染至少有两条重要路径:实时的 `StreamingAssistant`/`ToolTrail` 和转录/待处理的 `MessageLine` 行。`/clean` 操作应明确检查两者。 -- 测试前重新构建 TUI(`npm --prefix ui-tui run build`)——tsx watch 模式在首次启动时可能有延迟 - -## 验证 - -修复后: - -1. 重新构建 TUI: - ```bash - cd /home/bb/hermes-agent && npm --prefix ui-tui run build - ``` - -2. 运行 TUI 并测试命令: - ```bash - hermes --tui - ``` - -3. 输入 `/` 并验证命令出现在自动补全建议中,且显示预期的描述和参数提示。 - -4. 执行命令并确认: - - 预期行为已触发 - - 所有持久化配置正确更新(`read_file ~/.hermes/config.yaml`) - - 实时 UI 状态立即反映变更(而非重启后才生效) - -5. 如果命令也支持 gateway,至少在一个消息平台上测试(或运行 gateway 测试:`scripts/run_tests.sh tests/gateway/`)。 \ No newline at end of file diff --git a/website/i18n/zh-Hans/docusaurus-plugin-content-docs/current/user-guide/skills/bundled/software-development/software-development-subagent-driven-development.md b/website/i18n/zh-Hans/docusaurus-plugin-content-docs/current/user-guide/skills/bundled/software-development/software-development-subagent-driven-development.md deleted file mode 100644 index dd8d57735..000000000 --- a/website/i18n/zh-Hans/docusaurus-plugin-content-docs/current/user-guide/skills/bundled/software-development/software-development-subagent-driven-development.md +++ /dev/null @@ -1,370 +0,0 @@ ---- -title: "子智能体驱动开发 — 通过 delegate_task 子智能体执行计划(两阶段审查)" -sidebar_label: "子智能体驱动开发" -description: "通过 delegate_task 子智能体执行计划(两阶段审查)" ---- - -{/* This page is auto-generated from the skill's SKILL.md by website/scripts/generate-skill-docs.py. Edit the source SKILL.md, not this page. */} - -# 子智能体驱动开发 - -通过 delegate_task 子智能体执行计划(两阶段审查)。 - -## Skill 元数据 - -| | | -|---|---| -| 来源 | 内置(默认安装) | -| 路径 | `skills/software-development/subagent-driven-development` | -| 版本 | `1.1.0` | -| 作者 | Hermes Agent(改编自 obra/superpowers) | -| 许可证 | MIT | -| 平台 | linux, macos, windows | -| 标签 | `delegation`, `subagent`, `implementation`, `workflow`, `parallel` | -| 相关 skill | [`writing-plans`](/user-guide/skills/bundled/software-development/software-development-writing-plans)、[`requesting-code-review`](/user-guide/skills/bundled/software-development/software-development-requesting-code-review)、[`test-driven-development`](/user-guide/skills/bundled/software-development/software-development-test-driven-development) | - -## 参考:完整 SKILL.md - -:::info -以下是 Hermes 在触发此 skill 时加载的完整 skill 定义。这是智能体在 skill 激活时所看到的指令内容。 -::: - -# 子智能体驱动开发 - -## 概述 - -通过为每个任务派发全新子智能体并进行系统性两阶段审查来执行实现计划。 - -**核心原则:** 每个任务使用全新子智能体 + 两阶段审查(规格合规性审查,然后是质量审查)= 高质量、快速迭代。 - -## 使用时机 - -在以下情况下使用此 skill: -- 你有一个实现计划(来自 writing-plans skill 或用户需求) -- 任务大体上相互独立 -- 质量和规格合规性很重要 -- 你希望在任务之间进行自动化审查 - -**与手动执行相比:** -- 每个任务拥有全新上下文(不会因累积状态而产生混乱) -- 自动化审查流程能尽早发现问题 -- 对所有任务进行一致的质量检查 -- 子智能体可以在开始工作前提问 - -## 流程 - -### 1. 读取并解析计划 - -读取计划文件。预先提取所有任务的完整文本和上下文。创建待办列表: - -```python -# Read the plan -read_file("docs/plans/feature-plan.md") - -# Create todo list with all tasks -todo([ - {"id": "task-1", "content": "Create User model with email field", "status": "pending"}, - {"id": "task-2", "content": "Add password hashing utility", "status": "pending"}, - {"id": "task-3", "content": "Create login endpoint", "status": "pending"}, -]) -``` - -**关键:** 只读取计划一次。提取所有内容。不要让子智能体读取计划文件——直接在上下文中提供完整的任务文本。 - -### 2. 每个任务的工作流 - -对计划中的**每个**任务执行以下步骤: - -#### 步骤 1:派发实现者子智能体 - -使用 `delegate_task` 并提供完整上下文: - -```python -delegate_task( - goal="Implement Task 1: Create User model with email and password_hash fields", - context=""" - TASK FROM PLAN: - - Create: src/models/user.py - - Add User class with email (str) and password_hash (str) fields - - Use bcrypt for password hashing - - Include __repr__ for debugging - - FOLLOW TDD: - 1. Write failing test in tests/models/test_user.py - 2. Run: pytest tests/models/test_user.py -v (verify FAIL) - 3. Write minimal implementation - 4. Run: pytest tests/models/test_user.py -v (verify PASS) - 5. Run: pytest tests/ -q (verify no regressions) - 6. Commit: git add -A && git commit -m "feat: add User model with password hashing" - - PROJECT CONTEXT: - - Python 3.11, Flask app in src/app.py - - Existing models in src/models/ - - Tests use pytest, run from project root - - bcrypt already in requirements.txt - """, - toolsets=['terminal', 'file'] -) -``` - -#### 步骤 2:派发规格合规性审查者 - -实现者完成后,对照原始规格进行验证: - -```python -delegate_task( - goal="Review if implementation matches the spec from the plan", - context=""" - ORIGINAL TASK SPEC: - - Create src/models/user.py with User class - - Fields: email (str), password_hash (str) - - Use bcrypt for password hashing - - Include __repr__ - - CHECK: - - [ ] All requirements from spec implemented? - - [ ] File paths match spec? - - [ ] Function signatures match spec? - - [ ] Behavior matches expected? - - [ ] Nothing extra added (no scope creep)? - - OUTPUT: PASS or list of specific spec gaps to fix. - """, - toolsets=['file'] -) -``` - -**如果发现规格问题:** 修复差距,然后重新运行规格审查。仅在规格合规后继续。 - -#### 步骤 3:派发代码质量审查者 - -规格合规性通过后: - -```python -delegate_task( - goal="Review code quality for Task 1 implementation", - context=""" - FILES TO REVIEW: - - src/models/user.py - - tests/models/test_user.py - - CHECK: - - [ ] Follows project conventions and style? - - [ ] Proper error handling? - - [ ] Clear variable/function names? - - [ ] Adequate test coverage? - - [ ] No obvious bugs or missed edge cases? - - [ ] No security issues? - - OUTPUT FORMAT: - - Critical Issues: [must fix before proceeding] - - Important Issues: [should fix] - - Minor Issues: [optional] - - Verdict: APPROVED or REQUEST_CHANGES - """, - toolsets=['file'] -) -``` - -**如果发现质量问题:** 修复问题,重新审查。仅在获得批准后继续。 - -#### 步骤 4:标记为完成 - -```python -todo([{"id": "task-1", "content": "Create User model with email field", "status": "completed"}], merge=True) -``` - -### 3. 最终审查 - -所有任务完成后,派发最终集成审查者: - -```python -delegate_task( - goal="Review the entire implementation for consistency and integration issues", - context=""" - All tasks from the plan are complete. Review the full implementation: - - Do all components work together? - - Any inconsistencies between tasks? - - All tests passing? - - Ready for merge? - """, - toolsets=['terminal', 'file'] -) -``` - -### 4. 验证并提交 - -```bash -# Run full test suite -pytest tests/ -q - -# Review all changes -git diff --stat - -# Final commit if needed -git add -A && git commit -m "feat: complete [feature name] implementation" -``` - -## 任务粒度 - -**每个任务 = 2-5 分钟的专注工作。** - -**粒度过大:** -- "实现用户认证系统" - -**合适的粒度:** -- "创建包含 email 和 password 字段的 User 模型" -- "添加密码哈希函数" -- "创建登录端点" -- "添加 JWT token 生成" -- "创建注册端点" - -## 红线——绝对不要做这些 - -- 没有计划就开始实现 -- 跳过审查(规格合规性审查或代码质量审查) -- 在未修复关键/重要问题的情况下继续推进 -- 为涉及相同文件的任务派发多个实现子智能体 -- 让子智能体读取计划文件(应在上下文中直接提供完整文本) -- 跳过场景设定上下文(子智能体需要了解任务所处的位置) -- 忽略子智能体的提问(在让其继续之前先回答) -- 在规格合规性上接受"差不多就行" -- 跳过审查循环(审查者发现问题 → 实现者修复 → 再次审查) -- 让实现者自我审查替代实际审查(两者都需要) -- **在规格合规性通过之前开始代码质量审查**(顺序错误) -- 在任一审查存在未解决问题时进入下一个任务 - -## 处理问题 - -### 如果子智能体提问 - -- 清晰、完整地回答 -- 如有需要,提供额外上下文 -- 不要催促其进入实现阶段 - -### 如果审查者发现问题 - -- 实现者子智能体(或新的子智能体)修复问题 -- 审查者再次审查 -- 重复直到获得批准 -- 不要跳过重新审查 - -### 如果子智能体任务失败 - -- 派发新的修复子智能体,并提供关于出错原因的具体说明 -- 不要在控制器会话中手动修复(会污染上下文) - -## 效率说明 - -**为什么每个任务使用全新子智能体:** -- 防止累积状态导致的上下文污染 -- 每个子智能体获得干净、专注的上下文 -- 不会因先前任务的代码或推理而产生混乱 - -**为什么进行两阶段审查:** -- 规格审查能尽早发现构建不足或过度构建的问题 -- 质量审查确保实现构建良好 -- 在问题跨任务叠加之前将其捕获 - -**成本权衡:** -- 更多子智能体调用(每个任务:实现者 + 2 个审查者) -- 但能尽早发现问题(比后期调试叠加问题更经济) - -## 与其他 Skill 的集成 - -### 与 writing-plans - -此 skill 执行由 writing-plans skill 创建的计划: -1. 用户需求 → writing-plans → 实现计划 -2. 实现计划 → subagent-driven-development → 可运行代码 - -### 与 test-driven-development - -实现者子智能体应遵循 TDD: -1. 先编写失败的测试 -2. 实现最小化代码 -3. 验证测试通过 -4. 提交 - -在每个实现者上下文中都包含 TDD 指令。 - -### 与 requesting-code-review - -两阶段审查流程即是代码审查。对于最终集成审查,使用 requesting-code-review skill 的审查维度。 - -### 与 systematic-debugging - -如果子智能体在实现过程中遇到 bug: -1. 遵循 systematic-debugging 流程 -2. 在修复之前找到根本原因 -3. 编写回归测试 -4. 恢复实现 - -## 示例工作流 - -``` -[Read plan: docs/plans/auth-feature.md] -[Create todo list with 5 tasks] - ---- Task 1: Create User model --- -[Dispatch implementer subagent] - Implementer: "Should email be unique?" - You: "Yes, email must be unique" - Implementer: Implemented, 3/3 tests passing, committed. - -[Dispatch spec reviewer] - Spec reviewer: ✅ PASS — all requirements met - -[Dispatch quality reviewer] - Quality reviewer: ✅ APPROVED — clean code, good tests - -[Mark Task 1 complete] - ---- Task 2: Password hashing --- -[Dispatch implementer subagent] - Implementer: No questions, implemented, 5/5 tests passing. - -[Dispatch spec reviewer] - Spec reviewer: ❌ Missing: password strength validation (spec says "min 8 chars") - -[Implementer fixes] - Implementer: Added validation, 7/7 tests passing. - -[Dispatch spec reviewer again] - Spec reviewer: ✅ PASS - -[Dispatch quality reviewer] - Quality reviewer: Important: Magic number 8, extract to constant - Implementer: Extracted MIN_PASSWORD_LENGTH constant - Quality reviewer: ✅ APPROVED - -[Mark Task 2 complete] - -... (continue for all tasks) - -[After all tasks: dispatch final integration reviewer] -[Run full test suite: all passing] -[Done!] -``` - -## 记住 - -``` -Fresh subagent per task -Two-stage review every time -Spec compliance FIRST -Code quality SECOND -Never skip reviews -Catch issues early -``` - -**质量不是偶然的,它是系统化流程的结果。** - -## 延伸阅读(按需加载) - -当编排涉及大量上下文使用、较长的审查循环或复杂的验证检查点时,加载以下特定领域的参考资料: - -- **`references/context-budget-discipline.md`** — 四级上下文退化模型(PEAK / GOOD / DEGRADING / POOR)、随上下文窗口大小调整的读取深度规则,以及静默退化的早期预警信号。当一次运行明显会消耗大量上下文时加载(多阶段计划、大量子智能体、大型产物)。 -- **`references/gates-taxonomy.md`** — 四种规范化 gate(关卡)类型(Pre-flight、Revision、Escalation、Abort)及其行为、恢复方式和示例。在设计或审查任何包含验证检查点的工作流时加载——明确使用该词汇表,使每个 gate 都具有明确的入口、失败行为和恢复规则。 - -两份参考资料均改编自 gsd-build/get-shit-done(MIT © 2025 Lex Christopherson)。 \ No newline at end of file diff --git a/website/i18n/zh-Hans/docusaurus-plugin-content-docs/current/user-guide/skills/bundled/software-development/software-development-writing-plans.md b/website/i18n/zh-Hans/docusaurus-plugin-content-docs/current/user-guide/skills/bundled/software-development/software-development-writing-plans.md deleted file mode 100644 index 618e4d04b..000000000 --- a/website/i18n/zh-Hans/docusaurus-plugin-content-docs/current/user-guide/skills/bundled/software-development/software-development-writing-plans.md +++ /dev/null @@ -1,315 +0,0 @@ ---- -title: "编写计划 — 编写实施计划:细粒度任务、路径、代码" -sidebar_label: "编写计划" -description: "编写实施计划:细粒度任务、路径、代码" ---- - -{/* This page is auto-generated from the skill's SKILL.md by website/scripts/generate-skill-docs.py. Edit the source SKILL.md, not this page. */} - -# 编写计划 - -编写实施计划:细粒度任务、路径、代码。 - -## Skill 元数据 - -| | | -|---|---| -| 来源 | 内置(默认安装) | -| 路径 | `skills/software-development/writing-plans` | -| 版本 | `1.1.0` | -| 作者 | Hermes Agent(改编自 obra/superpowers) | -| 许可证 | MIT | -| 平台 | linux, macos, windows | -| 标签 | `planning`, `design`, `implementation`, `workflow`, `documentation` | -| 相关 skill | [`subagent-driven-development`](/user-guide/skills/bundled/software-development/software-development-subagent-driven-development)、[`test-driven-development`](/user-guide/skills/bundled/software-development/software-development-test-driven-development)、[`requesting-code-review`](/user-guide/skills/bundled/software-development/software-development-requesting-code-review) | - -## 参考:完整 SKILL.md - -:::info -以下是 Hermes 在触发该 skill 时加载的完整 skill 定义。这是 agent 在 skill 激活时所看到的指令内容。 -::: - -# 编写实施计划 - -## 概述 - -编写全面的实施计划,假设实施者对代码库零上下文、品味存疑。记录他们所需的一切:需要修改哪些文件、完整代码、测试命令、需查阅的文档、如何验证。给出细粒度任务。DRY。YAGNI。TDD。频繁提交。 - -假设实施者是一名熟练的开发者,但对工具集或问题域几乎一无所知。假设他们对良好的测试设计了解不多。 - -**核心原则:** 好的计划让实施变得显而易见。如果有人需要猜测,说明计划不完整。 - -## 使用时机 - -**始终在以下情况前使用:** -- 实施多步骤功能 -- 拆解复杂需求 -- 通过 subagent-driven-development 委派给子 agent - -**不要跳过的情况:** -- 功能看似简单(假设会导致 bug) -- 你打算自己实施(未来的你需要指引) -- 独自工作(文档很重要) - -## 细粒度任务粒度 - -**每个任务 = 2-5 分钟的专注工作。** - -每一步都是单一动作: -- "编写失败的测试" — 一步 -- "运行以确认它失败" — 一步 -- "编写使测试通过的最小代码" — 一步 -- "运行测试并确认通过" — 一步 -- "提交" — 一步 - -**太大:** -```markdown -### Task 1: Build authentication system -[50 lines of code across 5 files] -``` - -**合适大小:** -```markdown -### Task 1: Create User model with email field -[10 lines, 1 file] - -### Task 2: Add password hash field to User -[8 lines, 1 file] - -### Task 3: Create password hashing utility -[15 lines, 1 file] -``` - -## 计划文档结构 - -### 头部(必填) - -每个计划必须以以下内容开头: - -```markdown -# [Feature Name] Implementation Plan - -> **For Hermes:** Use subagent-driven-development skill to implement this plan task-by-task. - -**Goal:** [One sentence describing what this builds] - -**Architecture:** [2-3 sentences about approach] - -**Tech Stack:** [Key technologies/libraries] - ---- -``` - -### 任务结构 - -每个任务遵循以下格式: - -````markdown -### Task N: [Descriptive Name] - -**Objective:** What this task accomplishes (one sentence) - -**Files:** -- Create: `exact/path/to/new_file.py` -- Modify: `exact/path/to/existing.py:45-67` (line numbers if known) -- Test: `tests/path/to/test_file.py` - -**Step 1: Write failing test** - -```python -def test_specific_behavior(): - result = function(input) - assert result == expected -``` - -**Step 2: Run test to verify failure** - -Run: `pytest tests/path/test.py::test_specific_behavior -v` -Expected: FAIL — "function not defined" - -**Step 3: Write minimal implementation** - -```python -def function(input): - return expected -``` - -**Step 4: Run test to verify pass** - -Run: `pytest tests/path/test.py::test_specific_behavior -v` -Expected: PASS - -**Step 5: Commit** - -```bash -git add tests/path/test.py src/path/file.py -git commit -m "feat: add specific feature" -``` -```` - -## 编写流程 - -### 第一步:理解需求 - -阅读并理解: -- 功能需求 -- 设计文档或用户描述 -- 验收标准 -- 约束条件 - -### 第二步:探索代码库 - -使用 Hermes 工具了解项目: - -```python -# Understand project structure -search_files("*.py", target="files", path="src/") - -# Look at similar features -search_files("similar_pattern", path="src/", file_glob="*.py") - -# Check existing tests -search_files("*.py", target="files", path="tests/") - -# Read key files -read_file("src/app.py") -``` - -### 第三步:设计方案 - -决定: -- 架构模式 -- 文件组织 -- 所需依赖 -- 测试策略 - -### 第四步:编写任务 - -按顺序创建任务: -1. 搭建/基础设施 -2. 核心功能(每项均采用 TDD) -3. 边界情况 -4. 集成 -5. 清理/文档 - -### 第五步:补充完整细节 - -每个任务包含: -- **精确的文件路径**(不是"配置文件",而是 `src/config/settings.py`) -- **完整的代码示例**(不是"添加验证",而是实际代码) -- **精确的命令**及预期输出 -- **验证步骤**,证明任务有效 - -### 第六步:审查计划 - -检查: -- [ ] 任务顺序合理、逻辑清晰 -- [ ] 每个任务粒度合适(2-5 分钟) -- [ ] 文件路径精确 -- [ ] 代码示例完整(可直接复制粘贴) -- [ ] 命令精确并附有预期输出 -- [ ] 无缺失上下文 -- [ ] 遵循 DRY、YAGNI、TDD 原则 - -### 第七步:保存计划 - -```bash -mkdir -p docs/plans -# Save plan to docs/plans/YYYY-MM-DD-feature-name.md -git add docs/plans/ -git commit -m "docs: add implementation plan for [feature]" -``` - -## 原则 - -### DRY(不要重复自己) - -**差:** 在 3 处复制粘贴验证逻辑 -**好:** 提取验证函数,统一使用 - -### YAGNI(你不会需要它) - -**差:** 为未来需求添加"灵活性" -**好:** 只实现当前所需 - -```python -# Bad — YAGNI violation -class User: - def __init__(self, name, email): - self.name = name - self.email = email - self.preferences = {} # Not needed yet! - self.metadata = {} # Not needed yet! - -# Good — YAGNI -class User: - def __init__(self, name, email): - self.name = name - self.email = email -``` - -### TDD(测试驱动开发) - -每个产出代码的任务都应包含完整的 TDD 循环: -1. 编写失败的测试 -2. 运行以确认失败 -3. 编写最小代码 -4. 运行以确认通过 - -详见 `test-driven-development` skill。 - -### 频繁提交 - -每个任务完成后提交: -```bash -git add [files] -git commit -m "type: description" -``` - -## 常见错误 - -### 任务描述模糊 - -**差:** "添加认证" -**好:** "创建包含 email 和 password_hash 字段的 User 模型" - -### 代码不完整 - -**差:** "第一步:添加验证函数" -**好:** "第一步:添加验证函数",后跟完整的函数代码 - -### 缺少验证步骤 - -**差:** "第三步:测试是否有效" -**好:** "第三步:运行 `pytest tests/test_auth.py -v`,预期:3 passed" - -### 缺少文件路径 - -**差:** "创建模型文件" -**好:** "创建:`src/models/user.py`" - -## 执行交接 - -保存计划后,提供执行方案: - -**"计划已完成并保存。准备使用 subagent-driven-development 执行——我将为每个任务派发一个全新的子 agent,进行两阶段审查(规格合规性检查,然后代码质量检查)。是否继续?"** - -执行时,使用 `subagent-driven-development` skill: -- 每个任务使用携带完整上下文的独立 `delegate_task` -- 每个任务完成后进行规格合规性审查 -- 规格通过后进行代码质量审查 -- 两项审查均通过后方可继续 - -## 记住 - -``` -细粒度任务(每个 2-5 分钟) -精确的文件路径 -完整代码(可直接复制粘贴) -精确命令及预期输出 -验证步骤 -DRY、YAGNI、TDD -频繁提交 -``` - -**好的计划让实施变得显而易见。** \ No newline at end of file diff --git a/website/sidebars.ts b/website/sidebars.ts index b408af2ba..0454b8d53 100644 --- a/website/sidebars.ts +++ b/website/sidebars.ts @@ -149,7 +149,6 @@ const sidebars: SidebarsConfig = { 'user-guide/skills/bundled/autonomous-ai-agents/autonomous-ai-agents-claude-code', 'user-guide/skills/bundled/autonomous-ai-agents/autonomous-ai-agents-codex', 'user-guide/skills/bundled/autonomous-ai-agents/autonomous-ai-agents-hermes-agent', - 'user-guide/skills/bundled/autonomous-ai-agents/autonomous-ai-agents-kanban-codex-lane', 'user-guide/skills/bundled/autonomous-ai-agents/autonomous-ai-agents-opencode', ], }, @@ -162,18 +161,14 @@ const sidebars: SidebarsConfig = { 'user-guide/skills/bundled/creative/creative-architecture-diagram', 'user-guide/skills/bundled/creative/creative-ascii-art', 'user-guide/skills/bundled/creative/creative-ascii-video', - 'user-guide/skills/bundled/creative/creative-baoyu-article-illustrator', - 'user-guide/skills/bundled/creative/creative-baoyu-comic', 'user-guide/skills/bundled/creative/creative-baoyu-infographic', 'user-guide/skills/bundled/creative/creative-claude-design', 'user-guide/skills/bundled/creative/creative-comfyui', - 'user-guide/skills/bundled/creative/creative-creative-ideation', 'user-guide/skills/bundled/creative/creative-design-md', 'user-guide/skills/bundled/creative/creative-excalidraw', 'user-guide/skills/bundled/creative/creative-humanizer', 'user-guide/skills/bundled/creative/creative-manim-video', 'user-guide/skills/bundled/creative/creative-p5js', - 'user-guide/skills/bundled/creative/creative-pixel-art', 'user-guide/skills/bundled/creative/creative-popular-web-designs', 'user-guide/skills/bundled/creative/creative-pretext', 'user-guide/skills/bundled/creative/creative-sketch', @@ -198,7 +193,6 @@ const sidebars: SidebarsConfig = { items: [ 'user-guide/skills/bundled/devops/devops-kanban-orchestrator', 'user-guide/skills/bundled/devops/devops-kanban-worker', - 'user-guide/skills/bundled/devops/devops-webhook-subscriptions', ], }, { @@ -219,16 +213,6 @@ const sidebars: SidebarsConfig = { 'user-guide/skills/bundled/email/email-himalaya', ], }, - { - type: 'category', - label: 'gaming', - key: 'skills-bundled-gaming', - collapsed: true, - items: [ - 'user-guide/skills/bundled/gaming/gaming-minecraft-modpack-server', - 'user-guide/skills/bundled/gaming/gaming-pokemon-player', - ], - }, { type: 'category', label: 'github', @@ -243,15 +227,6 @@ const sidebars: SidebarsConfig = { 'user-guide/skills/bundled/github/github-github-repo-management', ], }, - { - type: 'category', - label: 'mcp', - key: 'skills-bundled-mcp', - collapsed: true, - items: [ - 'user-guide/skills/bundled/mcp/mcp-native-mcp', - ], - }, { type: 'category', label: 'media', @@ -261,7 +236,6 @@ const sidebars: SidebarsConfig = { 'user-guide/skills/bundled/media/media-gif-search', 'user-guide/skills/bundled/media/media-heartmula', 'user-guide/skills/bundled/media/media-songsee', - 'user-guide/skills/bundled/media/media-spotify', 'user-guide/skills/bundled/media/media-youtube-content', ], }, @@ -272,7 +246,6 @@ const sidebars: SidebarsConfig = { collapsed: true, items: [ 'user-guide/skills/bundled/mlops/mlops-models-audiocraft', - 'user-guide/skills/bundled/mlops/mlops-research-dspy', 'user-guide/skills/bundled/mlops/mlops-huggingface-hub', 'user-guide/skills/bundled/mlops/mlops-inference-llama-cpp', 'user-guide/skills/bundled/mlops/mlops-evaluation-lm-evaluation-harness', @@ -299,7 +272,6 @@ const sidebars: SidebarsConfig = { items: [ 'user-guide/skills/bundled/productivity/productivity-airtable', 'user-guide/skills/bundled/productivity/productivity-google-workspace', - 'user-guide/skills/bundled/productivity/productivity-linear', 'user-guide/skills/bundled/productivity/productivity-maps', 'user-guide/skills/bundled/productivity/productivity-nano-pdf', 'user-guide/skills/bundled/productivity/productivity-notion', @@ -354,18 +326,14 @@ const sidebars: SidebarsConfig = { key: 'skills-bundled-software-development', collapsed: true, items: [ - 'user-guide/skills/bundled/software-development/software-development-debugging-hermes-tui-commands', 'user-guide/skills/bundled/software-development/software-development-hermes-agent-skill-authoring', - 'user-guide/skills/bundled/software-development/software-development-hermes-s6-container-supervision', 'user-guide/skills/bundled/software-development/software-development-node-inspect-debugger', 'user-guide/skills/bundled/software-development/software-development-plan', 'user-guide/skills/bundled/software-development/software-development-python-debugpy', 'user-guide/skills/bundled/software-development/software-development-requesting-code-review', 'user-guide/skills/bundled/software-development/software-development-spike', - 'user-guide/skills/bundled/software-development/software-development-subagent-driven-development', 'user-guide/skills/bundled/software-development/software-development-systematic-debugging', 'user-guide/skills/bundled/software-development/software-development-test-driven-development', - 'user-guide/skills/bundled/software-development/software-development-writing-plans', ], }, { @@ -423,11 +391,15 @@ const sidebars: SidebarsConfig = { key: 'skills-optional-creative', collapsed: true, items: [ + 'user-guide/skills/optional/creative/creative-baoyu-article-illustrator', + 'user-guide/skills/optional/creative/creative-baoyu-comic', 'user-guide/skills/optional/creative/creative-blender-mcp', 'user-guide/skills/optional/creative/creative-concept-diagrams', + 'user-guide/skills/optional/creative/creative-creative-ideation', 'user-guide/skills/optional/creative/creative-hyperframes', 'user-guide/skills/optional/creative/creative-kanban-video-orchestrator', 'user-guide/skills/optional/creative/creative-meme-generation', + 'user-guide/skills/optional/creative/creative-pixel-art', ], }, { @@ -438,6 +410,7 @@ const sidebars: SidebarsConfig = { items: [ 'user-guide/skills/optional/devops/devops-cli', 'user-guide/skills/optional/devops/devops-docker-management', + 'user-guide/skills/optional/devops/devops-hermes-s6-container-supervision', 'user-guide/skills/optional/devops/devops-pinggy-tunnel', 'user-guide/skills/optional/devops/devops-watchers', ], @@ -476,6 +449,16 @@ const sidebars: SidebarsConfig = { 'user-guide/skills/optional/finance/finance-stocks', ], }, + { + type: 'category', + label: 'gaming', + key: 'skills-optional-gaming', + collapsed: true, + items: [ + 'user-guide/skills/optional/gaming/gaming-minecraft-modpack-server', + 'user-guide/skills/optional/gaming/gaming-pokemon-player', + ], + }, { type: 'category', label: 'health', @@ -515,6 +498,7 @@ const sidebars: SidebarsConfig = { 'user-guide/skills/optional/mlops/mlops-training-axolotl', 'user-guide/skills/optional/mlops/mlops-chroma', 'user-guide/skills/optional/mlops/mlops-clip', + 'user-guide/skills/optional/mlops/mlops-research-dspy', 'user-guide/skills/optional/mlops/mlops-faiss', 'user-guide/skills/optional/mlops/mlops-flash-attention', 'user-guide/skills/optional/mlops/mlops-guidance', @@ -595,6 +579,7 @@ const sidebars: SidebarsConfig = { items: [ 'user-guide/skills/optional/software-development/software-development-code-wiki', 'user-guide/skills/optional/software-development/software-development-rest-graphql-debug', + 'user-guide/skills/optional/software-development/software-development-subagent-driven-development', ], }, {