From 1b3a5070a3317dcdf379f0dd49b4e24d5d5d62c9 Mon Sep 17 00:00:00 2001 From: YoungjaeDev Date: Mon, 27 Jul 2026 09:56:39 +0900 Subject: [PATCH 01/12] chore: retire Hermes adapter generator and guards Delete scripts/sync-hermes-manifests.mjs, scripts/mock-load-hermes.py, and the 7 generated plugin.yaml + __init__.py adapter pairs. Hermes consumes plugins//skills/ through npx skills (scripts/install-skills.mjs), which covers 23 plugins / 52 skills against the adapter allowlist's 7 / 20, needs no per-plugin allowlist, and lands in ~/.hermes/skills/ where skills are auto-indexed into skills_list() instead of requiring an explicit skill_view() load. Codex manifests stay: npx skills carries skills only, and core-config (4 hooks, 0 skills), llm-wiki (6 hooks) and paper-search-tools (1 MCP server) ship non-skill payloads that only the Codex manifest delivers. Drop HERMES_ELIGIBLE from manifest-eligibility.mjs, its two count checks from check-doc-consistency.mjs, and the hermes --check + mock-load steps from .githooks/pre-commit and .github/workflows/validate-codex.yml. Refs #166 --- .githooks/pre-commit | 15 +- .github/workflows/validate-codex.yml | 12 +- plugins/anti-slop-design/__init__.py | 54 ------- plugins/anti-slop-design/plugin.yaml | 5 - plugins/brightdata-guide/__init__.py | 54 ------- plugins/brightdata-guide/plugin.yaml | 5 - plugins/github-dev/__init__.py | 54 ------- plugins/github-dev/plugin.yaml | 5 - plugins/interview/__init__.py | 54 ------- plugins/interview/plugin.yaml | 5 - plugins/ml-toolkit/__init__.py | 54 ------- plugins/ml-toolkit/plugin.yaml | 5 - plugins/ppt-yeong-style/__init__.py | 54 ------- plugins/ppt-yeong-style/plugin.yaml | 5 - plugins/tcrei-prompt/__init__.py | 54 ------- plugins/tcrei-prompt/plugin.yaml | 5 - scripts/check-doc-consistency.mjs | 11 +- scripts/manifest-eligibility.mjs | 24 ++-- scripts/mock-load-hermes.py | 77 ---------- scripts/sync-hermes-manifests.mjs | 203 --------------------------- 20 files changed, 20 insertions(+), 735 deletions(-) delete mode 100644 plugins/anti-slop-design/__init__.py delete mode 100644 plugins/anti-slop-design/plugin.yaml delete mode 100644 plugins/brightdata-guide/__init__.py delete mode 100644 plugins/brightdata-guide/plugin.yaml delete mode 100644 plugins/github-dev/__init__.py delete mode 100644 plugins/github-dev/plugin.yaml delete mode 100644 plugins/interview/__init__.py delete mode 100644 plugins/interview/plugin.yaml delete mode 100644 plugins/ml-toolkit/__init__.py delete mode 100644 plugins/ml-toolkit/plugin.yaml delete mode 100644 plugins/ppt-yeong-style/__init__.py delete mode 100644 plugins/ppt-yeong-style/plugin.yaml delete mode 100644 plugins/tcrei-prompt/__init__.py delete mode 100644 plugins/tcrei-prompt/plugin.yaml delete mode 100644 scripts/mock-load-hermes.py delete mode 100644 scripts/sync-hermes-manifests.mjs diff --git a/.githooks/pre-commit b/.githooks/pre-commit index c06d6493..6b5c036c 100755 --- a/.githooks/pre-commit +++ b/.githooks/pre-commit @@ -2,6 +2,8 @@ # Shared, version-controlled pre-commit hook (lives in the repo, not .git/hooks/). # Enforce the Codex manifest-drift guard AND the skill-description length guard # (both run inside sync-codex-manifests.mjs --check) before every commit. +# Hermes needs no guard here: it consumes plugins//skills/ via `npx skills` +# (scripts/install-skills.mjs), so there is no generated adapter that can drift (#166). # # Activate once per clone: git config core.hooksPath .githooks set -euo pipefail @@ -13,24 +15,13 @@ repo_root="$(git rev-parse --show-toplevel)" # can still commit; CI installs node and enforces all of these on the PR. if command -v node >/dev/null 2>&1; then node "$repo_root/scripts/sync-codex-manifests.mjs" --check - node "$repo_root/scripts/sync-hermes-manifests.mjs" --check node "$repo_root/scripts/check-doc-consistency.mjs" node "$repo_root/scripts/check-skill-tool-portability.mjs" --check # Skill-prose progressive-disclosure smell detector — INFORMATIONAL ONLY. It exits 0 # regardless, but the `|| true` keeps it non-blocking even if node itself errors. node "$repo_root/scripts/check-skill-prose.mjs" || true else - echo "pre-commit: node not found — skipping Codex/Hermes/doc guards (CI still enforces them)" >&2 -fi -# Hermes adapter mock-load — same guard CI runs, so import/registration regressions -# in generated __init__.py fail at commit time, not only in CI. The adapters -# `import yaml`, so the guard checks both python3 AND PyYAML; skip (not fail) when -# either is absent locally so a bare interpreter can still commit. CI installs both -# and enforces it on the PR. -if command -v python3 >/dev/null 2>&1 && python3 -c 'import yaml' >/dev/null 2>&1; then - python3 "$repo_root/scripts/mock-load-hermes.py" -else - echo "pre-commit: python3+PyYAML not both present — skipping Hermes mock-load (CI still enforces it)" >&2 + echo "pre-commit: node not found — skipping Codex/doc guards (CI still enforces them)" >&2 fi # cr-fix's CLI-fallback and CR-state paths only execute after the primary path diff --git a/.github/workflows/validate-codex.yml b/.github/workflows/validate-codex.yml index 717228bc..1a1c1b34 100644 --- a/.github/workflows/validate-codex.yml +++ b/.github/workflows/validate-codex.yml @@ -1,8 +1,9 @@ name: validate-codex -# Catch Codex + Hermes manifest drift, skill-description length violations, -# README/AGENTS doc-consistency drift, and Hermes adapter load breakage at PR -# time, even if a contributor skipped the local .githooks pre-commit hook. +# Catch Codex manifest drift, skill-description length violations, and +# README/AGENTS doc-consistency drift at PR time, even if a contributor skipped +# the local .githooks pre-commit hook. Hermes has no generated artifact to guard — +# it consumes plugins//skills/ via `npx skills` (see scripts/install-skills.mjs). on: push: pull_request: @@ -21,7 +22,6 @@ jobs: with: node-version: '20' - run: node scripts/sync-codex-manifests.mjs --check - - run: node scripts/sync-hermes-manifests.mjs --check # README.md / AGENTS.md plugin name-set + count strings must match the # marketplace registry — drift the version files and manifest --checks miss. - run: node scripts/check-doc-consistency.mjs @@ -32,10 +32,6 @@ jobs: # Progressive-disclosure smell detector (skill docs > ~500 lines, deep bundled # references). INFORMATIONAL ONLY — always exits 0, never blocks the run. - run: node scripts/check-skill-prose.mjs || true - # Import each generated Hermes adapter with a stub ctx and assert register_skill - # fires — catches a generated-but-never-executed adapter regression (PyYAML is - # preinstalled on ubuntu-latest). See scripts/mock-load-hermes.py. - - run: python3 scripts/mock-load-hermes.py # cr-fix's CLI-fallback / CR-state / rate-limit paths only run after the # primary path fails, so nothing exercised them until they broke in # production (issues #105, #110). Fixture-driven, no network, sub-second. diff --git a/plugins/anti-slop-design/__init__.py b/plugins/anti-slop-design/__init__.py deleted file mode 100644 index cdbadbd8..00000000 --- a/plugins/anti-slop-design/__init__.py +++ /dev/null @@ -1,54 +0,0 @@ -"""Hermes Agent adapter for the anti-slop-design plugin. - -The upstream plugin already ships skills for Claude Code and Codex. Hermes loads -plugin-provided skills through a small Python entrypoint, so this module simply -registers the existing SKILL.md files under the ``anti-slop-design:`` namespace. -""" - -from __future__ import annotations - -from pathlib import Path -from typing import Any - -import yaml - - -def _frontmatter_from_skill(skill_md: Path) -> dict[str, Any]: - """Decode the YAML frontmatter from a SKILL.md file.""" - text = skill_md.read_text(encoding="utf-8", errors="replace") - if not text.startswith("---"): - return {} - try: - _, frontmatter, _ = text.split("---", 2) - except ValueError: - return {} - try: - data = yaml.safe_load(frontmatter) or {} - except yaml.YAMLError: - return {} - return data if isinstance(data, dict) else {} - - -def _description_from_skill(skill_md: Path) -> str: - """Extract the decoded frontmatter description from a SKILL.md file.""" - description = _frontmatter_from_skill(skill_md).get("description", "") - if description is None: - return "" - if isinstance(description, str): - return description.strip() - return str(description).strip() - - -def register(ctx) -> None: - """Register anti-slop-design skills with Hermes. - - Hermes automatically qualifies these as ``anti-slop-design:`` based on the - plugin manifest name, matching the existing Claude/Codex command namespace. - """ - skills_root = Path(__file__).resolve().parent / "skills" - for skill_md in sorted(skills_root.glob("*/SKILL.md")): - ctx.register_skill( - skill_md.parent.name, - skill_md, - _description_from_skill(skill_md), - ) diff --git a/plugins/anti-slop-design/plugin.yaml b/plugins/anti-slop-design/plugin.yaml deleted file mode 100644 index 32fa21c0..00000000 --- a/plugins/anti-slop-design/plugin.yaml +++ /dev/null @@ -1,5 +0,0 @@ -name: anti-slop-design -version: "0.3.3" -description: "Anti-AI-slop design guard for web/SaaS landing, decks (PPT), dashboards, and copy. Runs a clarify->context->plan->run->audit->revise flow with a two-phase audit gate (pre-emit self-critique + binary slop checklist) and hands Korean copy rewriting to humanize-korean. Source-grounded in 6 OSS anti-slop repos." -author: "YoungjaeDev" -kind: standalone diff --git a/plugins/brightdata-guide/__init__.py b/plugins/brightdata-guide/__init__.py deleted file mode 100644 index 97d80f55..00000000 --- a/plugins/brightdata-guide/__init__.py +++ /dev/null @@ -1,54 +0,0 @@ -"""Hermes Agent adapter for the brightdata-guide plugin. - -The upstream plugin already ships skills for Claude Code and Codex. Hermes loads -plugin-provided skills through a small Python entrypoint, so this module simply -registers the existing SKILL.md files under the ``brightdata-guide:`` namespace. -""" - -from __future__ import annotations - -from pathlib import Path -from typing import Any - -import yaml - - -def _frontmatter_from_skill(skill_md: Path) -> dict[str, Any]: - """Decode the YAML frontmatter from a SKILL.md file.""" - text = skill_md.read_text(encoding="utf-8", errors="replace") - if not text.startswith("---"): - return {} - try: - _, frontmatter, _ = text.split("---", 2) - except ValueError: - return {} - try: - data = yaml.safe_load(frontmatter) or {} - except yaml.YAMLError: - return {} - return data if isinstance(data, dict) else {} - - -def _description_from_skill(skill_md: Path) -> str: - """Extract the decoded frontmatter description from a SKILL.md file.""" - description = _frontmatter_from_skill(skill_md).get("description", "") - if description is None: - return "" - if isinstance(description, str): - return description.strip() - return str(description).strip() - - -def register(ctx) -> None: - """Register brightdata-guide skills with Hermes. - - Hermes automatically qualifies these as ``brightdata-guide:`` based on the - plugin manifest name, matching the existing Claude/Codex command namespace. - """ - skills_root = Path(__file__).resolve().parent / "skills" - for skill_md in sorted(skills_root.glob("*/SKILL.md")): - ctx.register_skill( - skill_md.parent.name, - skill_md, - _description_from_skill(skill_md), - ) diff --git a/plugins/brightdata-guide/plugin.yaml b/plugins/brightdata-guide/plugin.yaml deleted file mode 100644 index 79a8c231..00000000 --- a/plugins/brightdata-guide/plugin.yaml +++ /dev/null @@ -1,5 +0,0 @@ -name: brightdata-guide -version: "1.1.0" -description: "Bright Data web data access via MCP tools + CLI — scraping (Web Unlocker), SERP, 40+ structured web_data_* extractors, browser automation. Guide skill; operator sets BRIGHTDATA_API_KEY, delegate subagents fall back to the bdata CLI." -author: "YoungjaeDev" -kind: standalone diff --git a/plugins/github-dev/__init__.py b/plugins/github-dev/__init__.py deleted file mode 100644 index bb92e87b..00000000 --- a/plugins/github-dev/__init__.py +++ /dev/null @@ -1,54 +0,0 @@ -"""Hermes Agent adapter for the github-dev plugin. - -The upstream plugin already ships skills for Claude Code and Codex. Hermes loads -plugin-provided skills through a small Python entrypoint, so this module simply -registers the existing SKILL.md files under the ``github-dev:`` namespace. -""" - -from __future__ import annotations - -from pathlib import Path -from typing import Any - -import yaml - - -def _frontmatter_from_skill(skill_md: Path) -> dict[str, Any]: - """Decode the YAML frontmatter from a SKILL.md file.""" - text = skill_md.read_text(encoding="utf-8", errors="replace") - if not text.startswith("---"): - return {} - try: - _, frontmatter, _ = text.split("---", 2) - except ValueError: - return {} - try: - data = yaml.safe_load(frontmatter) or {} - except yaml.YAMLError: - return {} - return data if isinstance(data, dict) else {} - - -def _description_from_skill(skill_md: Path) -> str: - """Extract the decoded frontmatter description from a SKILL.md file.""" - description = _frontmatter_from_skill(skill_md).get("description", "") - if description is None: - return "" - if isinstance(description, str): - return description.strip() - return str(description).strip() - - -def register(ctx) -> None: - """Register github-dev skills with Hermes. - - Hermes automatically qualifies these as ``github-dev:`` based on the - plugin manifest name, matching the existing Claude/Codex command namespace. - """ - skills_root = Path(__file__).resolve().parent / "skills" - for skill_md in sorted(skills_root.glob("*/SKILL.md")): - ctx.register_skill( - skill_md.parent.name, - skill_md, - _description_from_skill(skill_md), - ) diff --git a/plugins/github-dev/plugin.yaml b/plugins/github-dev/plugin.yaml deleted file mode 100644 index e94495b9..00000000 --- a/plugins/github-dev/plugin.yaml +++ /dev/null @@ -1,5 +0,0 @@ -name: github-dev -version: "2.11.0" -description: "GitHub workflow: commit, PR, issue, worktree, unified CodeRabbit + ChatGPT-Codex cr-fix pipeline v2 (Step 5 pre-flight review detection across CR commit-status + comments + Codex reviews + Codex emoji 3-channel; autonomous Step 9 judgment replaces per-finding AskUserQuestion — LLM judges real/spurious + severity + fix-size and applies/defers/skips with logged reasoning; rate-limit sniffer now covers commit-status description + in-place comment edits; polling interval 60s → 8s; --auto-merge + --skip-minor + --cr-source retained), project tracking, release. All workflows are now skills (commit-and-push, create-issue-label, decompose-issue, update-progress, resolve-issue, release, cr-fix, post-merge) — no commands surface, so they run under Codex too. post-merge runs a mandatory built-in wiki-lore ingest step (absorbed llm-wiki:post-merge-wiki) plus an optional Step 4.5 ephemeral-artifact pruning gate (heuristic candidates → AskUserQuestion → git rm). 2.8.0 correctness repairs: CR-state fetch failures map to a real error channel (no longer masked as a clean 'none'), a null-repository GraphQL response fails loudly instead of a silent false-clean convergence, and an active `@coderabbitai rate limit` query resolves ambiguous passive rate-limit sniffs." -author: "YoungjaeDev" -kind: standalone diff --git a/plugins/interview/__init__.py b/plugins/interview/__init__.py deleted file mode 100644 index 7a41d9bb..00000000 --- a/plugins/interview/__init__.py +++ /dev/null @@ -1,54 +0,0 @@ -"""Hermes Agent adapter for the interview plugin. - -The upstream plugin already ships skills for Claude Code and Codex. Hermes loads -plugin-provided skills through a small Python entrypoint, so this module simply -registers the existing SKILL.md files under the ``interview:`` namespace. -""" - -from __future__ import annotations - -from pathlib import Path -from typing import Any - -import yaml - - -def _frontmatter_from_skill(skill_md: Path) -> dict[str, Any]: - """Decode the YAML frontmatter from a SKILL.md file.""" - text = skill_md.read_text(encoding="utf-8", errors="replace") - if not text.startswith("---"): - return {} - try: - _, frontmatter, _ = text.split("---", 2) - except ValueError: - return {} - try: - data = yaml.safe_load(frontmatter) or {} - except yaml.YAMLError: - return {} - return data if isinstance(data, dict) else {} - - -def _description_from_skill(skill_md: Path) -> str: - """Extract the decoded frontmatter description from a SKILL.md file.""" - description = _frontmatter_from_skill(skill_md).get("description", "") - if description is None: - return "" - if isinstance(description, str): - return description.strip() - return str(description).strip() - - -def register(ctx) -> None: - """Register interview skills with Hermes. - - Hermes automatically qualifies these as ``interview:`` based on the - plugin manifest name, matching the existing Claude/Codex command namespace. - """ - skills_root = Path(__file__).resolve().parent / "skills" - for skill_md in sorted(skills_root.glob("*/SKILL.md")): - ctx.register_skill( - skill_md.parent.name, - skill_md, - _description_from_skill(skill_md), - ) diff --git a/plugins/interview/plugin.yaml b/plugins/interview/plugin.yaml deleted file mode 100644 index 065f2415..00000000 --- a/plugins/interview/plugin.yaml +++ /dev/null @@ -1,5 +0,0 @@ -name: interview -version: "1.3.0" -description: "Structured requirements gathering" -author: "YoungjaeDev" -kind: standalone diff --git a/plugins/ml-toolkit/__init__.py b/plugins/ml-toolkit/__init__.py deleted file mode 100644 index 48c21e63..00000000 --- a/plugins/ml-toolkit/__init__.py +++ /dev/null @@ -1,54 +0,0 @@ -"""Hermes Agent adapter for the ml-toolkit plugin. - -The upstream plugin already ships skills for Claude Code and Codex. Hermes loads -plugin-provided skills through a small Python entrypoint, so this module simply -registers the existing SKILL.md files under the ``ml-toolkit:`` namespace. -""" - -from __future__ import annotations - -from pathlib import Path -from typing import Any - -import yaml - - -def _frontmatter_from_skill(skill_md: Path) -> dict[str, Any]: - """Decode the YAML frontmatter from a SKILL.md file.""" - text = skill_md.read_text(encoding="utf-8", errors="replace") - if not text.startswith("---"): - return {} - try: - _, frontmatter, _ = text.split("---", 2) - except ValueError: - return {} - try: - data = yaml.safe_load(frontmatter) or {} - except yaml.YAMLError: - return {} - return data if isinstance(data, dict) else {} - - -def _description_from_skill(skill_md: Path) -> str: - """Extract the decoded frontmatter description from a SKILL.md file.""" - description = _frontmatter_from_skill(skill_md).get("description", "") - if description is None: - return "" - if isinstance(description, str): - return description.strip() - return str(description).strip() - - -def register(ctx) -> None: - """Register ml-toolkit skills with Hermes. - - Hermes automatically qualifies these as ``ml-toolkit:`` based on the - plugin manifest name, matching the existing Claude/Codex command namespace. - """ - skills_root = Path(__file__).resolve().parent / "skills" - for skill_md in sorted(skills_root.glob("*/SKILL.md")): - ctx.register_skill( - skill_md.parent.name, - skill_md, - _description_from_skill(skill_md), - ) diff --git a/plugins/ml-toolkit/plugin.yaml b/plugins/ml-toolkit/plugin.yaml deleted file mode 100644 index 4ed8859a..00000000 --- a/plugins/ml-toolkit/plugin.yaml +++ /dev/null @@ -1,5 +0,0 @@ -name: ml-toolkit -version: "1.4.3" -description: "ML/multimodal development principles, GPU parallel processing, Gradio CV apps, CV notebook generation, interactive CV data exploration" -author: "YoungjaeDev" -kind: standalone diff --git a/plugins/ppt-yeong-style/__init__.py b/plugins/ppt-yeong-style/__init__.py deleted file mode 100644 index c6d6ca12..00000000 --- a/plugins/ppt-yeong-style/__init__.py +++ /dev/null @@ -1,54 +0,0 @@ -"""Hermes Agent adapter for the ppt-yeong-style plugin. - -The upstream plugin already ships skills for Claude Code and Codex. Hermes loads -plugin-provided skills through a small Python entrypoint, so this module simply -registers the existing SKILL.md files under the ``ppt-yeong-style:`` namespace. -""" - -from __future__ import annotations - -from pathlib import Path -from typing import Any - -import yaml - - -def _frontmatter_from_skill(skill_md: Path) -> dict[str, Any]: - """Decode the YAML frontmatter from a SKILL.md file.""" - text = skill_md.read_text(encoding="utf-8", errors="replace") - if not text.startswith("---"): - return {} - try: - _, frontmatter, _ = text.split("---", 2) - except ValueError: - return {} - try: - data = yaml.safe_load(frontmatter) or {} - except yaml.YAMLError: - return {} - return data if isinstance(data, dict) else {} - - -def _description_from_skill(skill_md: Path) -> str: - """Extract the decoded frontmatter description from a SKILL.md file.""" - description = _frontmatter_from_skill(skill_md).get("description", "") - if description is None: - return "" - if isinstance(description, str): - return description.strip() - return str(description).strip() - - -def register(ctx) -> None: - """Register ppt-yeong-style skills with Hermes. - - Hermes automatically qualifies these as ``ppt-yeong-style:`` based on the - plugin manifest name, matching the existing Claude/Codex command namespace. - """ - skills_root = Path(__file__).resolve().parent / "skills" - for skill_md in sorted(skills_root.glob("*/SKILL.md")): - ctx.register_skill( - skill_md.parent.name, - skill_md, - _description_from_skill(skill_md), - ) diff --git a/plugins/ppt-yeong-style/plugin.yaml b/plugins/ppt-yeong-style/plugin.yaml deleted file mode 100644 index 859945c9..00000000 --- a/plugins/ppt-yeong-style/plugin.yaml +++ /dev/null @@ -1,5 +0,0 @@ -name: ppt-yeong-style -version: "0.9.3" -description: "yeong 스타일 강의·제안 덱 작성 규약 — ppt-master 빌드 엔진 위에 얹는 작성 레이어(엔진 자체가 아님). 스킬 3종: 메인 ppt-yeong-style(미감 시그니처 §0 'Editorial restraint, one committed accent'·md 소스 규약·작성 원칙 16종·밀도 리듬·역할 기반 색·codex-image vs SVG 경계·앱 UI 실물 강제·레버 조합 차별화·윤문·렌더 QA + references/ 6종 + 주입 페이로드) + lecture-deck(강의 덱 운영 — 실습 handouts 생성 규약·프롬프트 카드·placeholder→실캡처 스크린샷 슬롯·리넘버링 4중 동기화·전사 회고 루프·강사 노트 태그 + cc-common 47장 레퍼런스) + deck-review(관점별 리뷰 서브에이전트 4종 audience-fit·story-flow·fact-check·design-qa 병렬 오케스트레이션 + codex:rescue 교차 리뷰, 페르소나는 파라미터). 의존 스킬은 있으면 사용, 없으면 생략 + 설치 제안 문구(ppt-master만 prerequisite-stop). ppt-master로 그냥 'PPT 만들기'와 달리 yeong 규약이 필요할 때." -author: "YoungjaeDev" -kind: standalone diff --git a/plugins/tcrei-prompt/__init__.py b/plugins/tcrei-prompt/__init__.py deleted file mode 100644 index c599f2e6..00000000 --- a/plugins/tcrei-prompt/__init__.py +++ /dev/null @@ -1,54 +0,0 @@ -"""Hermes Agent adapter for the tcrei-prompt plugin. - -The upstream plugin already ships skills for Claude Code and Codex. Hermes loads -plugin-provided skills through a small Python entrypoint, so this module simply -registers the existing SKILL.md files under the ``tcrei-prompt:`` namespace. -""" - -from __future__ import annotations - -from pathlib import Path -from typing import Any - -import yaml - - -def _frontmatter_from_skill(skill_md: Path) -> dict[str, Any]: - """Decode the YAML frontmatter from a SKILL.md file.""" - text = skill_md.read_text(encoding="utf-8", errors="replace") - if not text.startswith("---"): - return {} - try: - _, frontmatter, _ = text.split("---", 2) - except ValueError: - return {} - try: - data = yaml.safe_load(frontmatter) or {} - except yaml.YAMLError: - return {} - return data if isinstance(data, dict) else {} - - -def _description_from_skill(skill_md: Path) -> str: - """Extract the decoded frontmatter description from a SKILL.md file.""" - description = _frontmatter_from_skill(skill_md).get("description", "") - if description is None: - return "" - if isinstance(description, str): - return description.strip() - return str(description).strip() - - -def register(ctx) -> None: - """Register tcrei-prompt skills with Hermes. - - Hermes automatically qualifies these as ``tcrei-prompt:`` based on the - plugin manifest name, matching the existing Claude/Codex command namespace. - """ - skills_root = Path(__file__).resolve().parent / "skills" - for skill_md in sorted(skills_root.glob("*/SKILL.md")): - ctx.register_skill( - skill_md.parent.name, - skill_md, - _description_from_skill(skill_md), - ) diff --git a/plugins/tcrei-prompt/plugin.yaml b/plugins/tcrei-prompt/plugin.yaml deleted file mode 100644 index 36fcd7a0..00000000 --- a/plugins/tcrei-prompt/plugin.yaml +++ /dev/null @@ -1,5 +0,0 @@ -name: tcrei-prompt -version: "1.1.2" -description: "Rewrite prompts using Google's TCREI structure for next-session reuse" -author: "YoungjaeDev" -kind: standalone diff --git a/scripts/check-doc-consistency.mjs b/scripts/check-doc-consistency.mjs index 0509d6a2..e0111277 100644 --- a/scripts/check-doc-consistency.mjs +++ b/scripts/check-doc-consistency.mjs @@ -12,7 +12,7 @@ import { readFileSync } from 'node:fs'; import { dirname, join, resolve } from 'node:path'; import { fileURLToPath } from 'node:url'; -import { CODEX_EXCLUDED, HERMES_ELIGIBLE } from './manifest-eligibility.mjs'; +import { CODEX_EXCLUDED } from './manifest-eligibility.mjs'; const ROOT = resolve(dirname(fileURLToPath(import.meta.url)), '..'); const marketplace = JSON.parse(readFileSync(join(ROOT, '.claude-plugin', 'marketplace.json'), 'utf8')); @@ -21,10 +21,9 @@ const canonical = marketplace.plugins.map((p) => p.name); const canonicalSet = new Set(canonical); const TOTAL = canonical.length; -// Eligibility comes from the shared SoT the generators also import, so this guard's -// counts cannot drift from sync-{codex,hermes}-manifests.mjs. +// Eligibility comes from the shared SoT the generator also imports, so this guard's +// counts cannot drift from sync-codex-manifests.mjs. const CODEX_ELIGIBLE = canonical.filter((n) => !CODEX_EXCLUDED.has(n)).length; -const HERMES_ELIGIBLE_COUNT = HERMES_ELIGIBLE.size; const errors = []; @@ -94,8 +93,6 @@ checkCount('README.md Codex share', readme, /(\d+) \/ (\d+) 플러그인/g, [COD checkCount('AGENTS.md ## Plugins (N)', agents, /## Plugins \((\d+)\)/g, [TOTAL]); checkCount('AGENTS.md eligible N개', agents, /eligible (\d+)개/g, [CODEX_ELIGIBLE]); checkCount('AGENTS.md # N entries', agents, /# (\d+) entries/g, [CODEX_ELIGIBLE]); -checkCount('AGENTS.md 현재 N개', agents, /현재 (\d+)개/g, [HERMES_ELIGIBLE_COUNT]); -checkCount('README.md Hermes 이번 라운드', readme, /이번 라운드 (\d+)개/g, [HERMES_ELIGIBLE_COUNT]); if (errors.length) { console.error('doc-consistency drift detected:'); @@ -103,4 +100,4 @@ if (errors.length) { console.error('\nfix README.md / AGENTS.md to match .claude-plugin/marketplace.json.'); process.exit(1); } -console.log(`doc-consistency OK — ${TOTAL} plugins, Codex-eligible ${CODEX_ELIGIBLE}, Hermes ${HERMES_ELIGIBLE_COUNT}; trees + table + counts consistent.`); +console.log(`doc-consistency OK — ${TOTAL} plugins, Codex-eligible ${CODEX_ELIGIBLE}; trees + table + counts consistent.`); diff --git a/scripts/manifest-eligibility.mjs b/scripts/manifest-eligibility.mjs index ef1a8d6c..0b4348fd 100644 --- a/scripts/manifest-eligibility.mjs +++ b/scripts/manifest-eligibility.mjs @@ -1,22 +1,16 @@ // Single source of truth for which plugins each downstream runtime covers. -// Imported by sync-codex-manifests.mjs (Codex EXCLUDED), sync-hermes-manifests.mjs -// (Hermes allowlist), and check-doc-consistency.mjs (doc count checks) so the three -// cannot drift. Update the eligibility HERE, never in a copy — the doc-consistency -// guard reads these same sets, so a stale copy would silently pass stale counts. +// Imported by sync-codex-manifests.mjs (Codex EXCLUDED) and check-doc-consistency.mjs +// (doc count checks) so the two cannot drift. Update the eligibility HERE, never in a +// copy — the doc-consistency guard reads this same set, so a stale copy would silently +// pass stale counts. +// +// Hermes has no eligibility set: it consumes `plugins//skills/` through +// `npx skills` (scripts/install-skills.mjs), which covers every skill-bearing plugin +// with no per-plugin allowlist to keep in sync. The old HERMES_ELIGIBLE allowlist and +// its generated plugin.yaml / __init__.py adapters were retired in #166. // Plugins intentionally not bridged to Codex. // codex-image — the Claude->Codex bridge itself (syncing it to Codex is circular) // core-config was here but is now Codex-eligible: Codex plugins support bundled hooks // (hooks/codex-hooks.json), so its prompt_inject UserPromptSubmit hook ships natively. export const CODEX_EXCLUDED = new Set(['codex-image']); - -// Plugins that get generated Hermes adapters (plugin.yaml + __init__.py). -export const HERMES_ELIGIBLE = new Set([ - 'github-dev', - 'interview', - 'anti-slop-design', - 'tcrei-prompt', - 'ppt-yeong-style', - 'ml-toolkit', - 'brightdata-guide', -]); diff --git a/scripts/mock-load-hermes.py b/scripts/mock-load-hermes.py deleted file mode 100644 index 3a1d8871..00000000 --- a/scripts/mock-load-hermes.py +++ /dev/null @@ -1,77 +0,0 @@ -#!/usr/bin/env python3 -"""Mock-load every generated Hermes adapter and assert its register_skill calls fire. - -The byte-drift guard (sync-hermes-manifests.mjs --check) only checks that the -generated plugins//__init__.py matches the generator output — it never -executes it. A generator regression that emits a syntactically broken or -non-registering adapter passes --check but fails at Hermes load time. This smoke -test imports each adapter with a stub ctx and asserts register() registers one -skill per SKILL.md, catching that "generated but never executed" gap. - -Requires PyYAML (the adapters do `import yaml`); it is preinstalled on the CI -runner. Run: python3 scripts/mock-load-hermes.py -""" - -import importlib.util -import sys -from pathlib import Path - -ROOT = Path(__file__).resolve().parent.parent -PLUGINS = ROOT / "plugins" - - -class StubCtx: - """Records register_skill calls the way the real Hermes context would receive them.""" - - def __init__(self): - self.calls = [] - - def register_skill(self, name, path, description): - assert isinstance(name, str) and name, f"empty skill name from {path!r}" - self.calls.append((name, str(path), description)) - - -def load_adapter(init_py): - spec = importlib.util.spec_from_file_location( - f"hermes_adapter_{init_py.parent.name}", init_py - ) - module = importlib.util.module_from_spec(spec) - spec.loader.exec_module(module) - return module - - -def main(): - adapters = sorted(PLUGINS.glob("*/__init__.py")) - if not adapters: - sys.exit( - "no Hermes adapters found — expected generated plugins//__init__.py" - ) - - failures = [] - for init_py in adapters: - plugin = init_py.parent.name - expected = len(sorted((init_py.parent / "skills").glob("*/SKILL.md"))) - try: - module = load_adapter(init_py) - ctx = StubCtx() - module.register(ctx) - except Exception as exc: # noqa: BLE001 - report any adapter breakage - failures.append(f"{plugin}: {type(exc).__name__}: {exc}") - continue - if len(ctx.calls) != expected: - failures.append( - f"{plugin}: register_skill fired {len(ctx.calls)}x, expected {expected}" - ) - - if failures: - print("Hermes adapter mock-load FAILED:") - for line in failures: - print(f" {line}") - sys.exit(1) - print( - f"Hermes adapter mock-load OK — {len(adapters)} adapters, register_skill exercised." - ) - - -if __name__ == "__main__": - main() diff --git a/scripts/sync-hermes-manifests.mjs b/scripts/sync-hermes-manifests.mjs deleted file mode 100644 index 56208655..00000000 --- a/scripts/sync-hermes-manifests.mjs +++ /dev/null @@ -1,203 +0,0 @@ -#!/usr/bin/env node -// Generate Hermes Agent adapters from the Claude marketplace source-of-truth. -// One source tree, three runtimes — Claude (native), Codex (.codex-plugin via -// sync-codex-manifests.mjs), Hermes (plugin.yaml + __init__.py, this file). -// -// Each eligible plugin gets two derived files in its root: -// plugin.yaml — Hermes manifest; name/version/description from marketplace.json -// __init__.py — generic Python entrypoint that registers every SKILL.md as a -// `:` Hermes skill. No per-plugin logic. -// -// Modes: -// (default) write/overwrite adapters on disk -// --check diff against on-disk; exit 1 with diff on drift (CI guard) -// --dry-run print what would be written, exit 0 - -import { readFileSync, writeFileSync, existsSync, statSync, readdirSync, rmSync } from 'node:fs'; -import { dirname, join, resolve } from 'node:path'; -import { fileURLToPath } from 'node:url'; - -const ROOT = resolve(dirname(fileURLToPath(import.meta.url)), '..'); -const SOURCE = join(ROOT, '.claude-plugin', 'marketplace.json'); -const PLUGINS_DIR = join(ROOT, 'plugins'); - -// Plugins that ship a Hermes adapter. Allowlist (mirror of the Codex generator's -// EXCLUDED denylist) — add a name here to extend Hermes coverage in a later round. -// Intentionally absent: core-config (no skills to register), codex-image (codex -// CLI dependency + redundant with Hermes native image generation). -import { HERMES_ELIGIBLE } from './manifest-eligibility.mjs'; - -const AUTHOR = 'YoungjaeDev'; - -const args = new Set(process.argv.slice(2)); -const MODE = args.has('--check') ? 'check' : args.has('--dry-run') ? 'dry' : 'write'; - -function readJSON(path) { - return JSON.parse(readFileSync(path, 'utf8')); -} - -function isFile(path) { - try { return statSync(path).isFile(); } catch { return false; } -} - -function isDir(path) { - try { return statSync(path).isDirectory(); } catch { return false; } -} - -// Minimal YAML double-quote scalar — escape backslash + double-quote only; the -// marketplace descriptions contain no control chars, so this is sufficient. -function yamlQuote(value) { - return '"' + String(value).replace(/\\/g, '\\\\').replace(/"/g, '\\"') + '"'; -} - -function buildPluginYaml(entry) { - return [ - `name: ${entry.name}`, - `version: ${yamlQuote(entry.version)}`, - `description: ${yamlQuote(entry.description)}`, - `author: ${yamlQuote(AUTHOR)}`, - `kind: standalone`, - ].join('\n') + '\n'; -} - -// Generic Hermes entrypoint. Identical structure for every plugin (only the -// plugin name is templated into the docstrings) — matches the pilot github-dev -// adapter byte-for-byte so absorbing it into this generator is a no-op. -function buildInitPy(name) { - const lines = [ - `"""Hermes Agent adapter for the ${name} plugin.`, - ``, - `The upstream plugin already ships skills for Claude Code and Codex. Hermes loads`, - `plugin-provided skills through a small Python entrypoint, so this module simply`, - 'registers the existing SKILL.md files under the ``' + name + ':`` namespace.', - `"""`, - ``, - `from __future__ import annotations`, - ``, - `from pathlib import Path`, - `from typing import Any`, - ``, - `import yaml`, - ``, - ``, - `def _frontmatter_from_skill(skill_md: Path) -> dict[str, Any]:`, - ` """Decode the YAML frontmatter from a SKILL.md file."""`, - ` text = skill_md.read_text(encoding="utf-8", errors="replace")`, - ` if not text.startswith("---"):`, - ` return {}`, - ` try:`, - ` _, frontmatter, _ = text.split("---", 2)`, - ` except ValueError:`, - ` return {}`, - ` try:`, - ` data = yaml.safe_load(frontmatter) or {}`, - ` except yaml.YAMLError:`, - ` return {}`, - ` return data if isinstance(data, dict) else {}`, - ``, - ``, - `def _description_from_skill(skill_md: Path) -> str:`, - ` """Extract the decoded frontmatter description from a SKILL.md file."""`, - ` description = _frontmatter_from_skill(skill_md).get("description", "")`, - ` if description is None:`, - ` return ""`, - ` if isinstance(description, str):`, - ` return description.strip()`, - ` return str(description).strip()`, - ``, - ``, - `def register(ctx) -> None:`, - ' """Register ' + name + ' skills with Hermes.', - ``, - ' Hermes automatically qualifies these as ``' + name + ':`` based on the', - ` plugin manifest name, matching the existing Claude/Codex command namespace.`, - ` """`, - ` skills_root = Path(__file__).resolve().parent / "skills"`, - ` for skill_md in sorted(skills_root.glob("*/SKILL.md")):`, - ` ctx.register_skill(`, - ` skill_md.parent.name,`, - ` skill_md,`, - ` _description_from_skill(skill_md),`, - ` )`, - ]; - return lines.join('\n') + '\n'; -} - -function compare(path, next) { - if (!existsSync(path)) return { drift: true, reason: 'missing' }; - return readFileSync(path, 'utf8') === next ? { drift: false } : { drift: true, reason: 'changed' }; -} - -// An adapter file (plugin.yaml or __init__.py) under a plugin dir that is NOT in -// HERMES_ELIGIBLE is an orphan — left behind when a plugin leaves the allowlist -// or is removed from the marketplace. Flagged in --check, removed in write mode. -function findOrphanAdapters(expectedPaths) { - if (!isDir(PLUGINS_DIR)) return []; - const expected = new Set(expectedPaths); - const orphans = []; - for (const name of readdirSync(PLUGINS_DIR)) { - for (const file of ['plugin.yaml', '__init__.py']) { - const path = join(PLUGINS_DIR, name, file); - if (isFile(path) && !expected.has(path)) orphans.push(path); - } - } - return orphans; -} - -function main() { - const source = readJSON(SOURCE); - const eligible = source.plugins.filter((p) => HERMES_ELIGIBLE.has(p.name)); - - const outputs = []; - for (const entry of eligible) { - const pluginDir = join(PLUGINS_DIR, entry.name); - outputs.push({ path: join(pluginDir, 'plugin.yaml'), content: buildPluginYaml(entry) }); - outputs.push({ path: join(pluginDir, '__init__.py'), content: buildInitPy(entry.name) }); - } - - const orphans = findOrphanAdapters(outputs.map((o) => o.path)); - - if (MODE === 'check') { - const drifted = []; - for (const { path, content } of outputs) { - const cmp = compare(path, content); - if (cmp.drift) drifted.push({ path, reason: cmp.reason }); - } - for (const path of orphans) drifted.push({ path, reason: 'orphan' }); - if (drifted.length === 0) { - console.log(`up to date (${outputs.length} adapter files, ${eligible.length} plugins)`); - return; - } - console.error(`drift detected in ${drifted.length} file(s):`); - for (const d of drifted) console.error(` ${d.reason}: ${d.path}`); - console.error('\nrun without --check to regenerate (orphans will be removed).'); - process.exit(1); - } - - if (MODE === 'dry') { - for (const { path, content } of outputs) { - const cmp = compare(path, content); - const tag = cmp.drift ? (cmp.reason === 'missing' ? 'CREATE' : 'UPDATE') : 'OK '; - console.log(`${tag} ${path} (${content.length} bytes)`); - } - for (const path of orphans) console.log(`REMOVE ${path} (orphan)`); - console.log(`\n${outputs.length} adapter files, ${orphans.length} orphans (dry-run, no writes).`); - return; - } - - let created = 0, updated = 0, unchanged = 0; - for (const { path, content } of outputs) { - const cmp = compare(path, content); - if (!cmp.drift) { unchanged++; continue; } - writeFileSync(path, content); - if (cmp.reason === 'missing') created++; else updated++; - } - let removed = 0; - for (const path of orphans) { - rmSync(path, { force: true }); - removed++; - } - console.log(`wrote ${outputs.length} adapter files: ${created} created, ${updated} updated, ${unchanged} unchanged, ${removed} orphans removed.`); -} - -main(); From edacdbd5536b65b189dfdb1b28c4b4e284a75c2c Mon Sep 17 00:00:00 2001 From: YoungjaeDev Date: Mon, 27 Jul 2026 09:58:12 +0900 Subject: [PATCH 02/12] fix(code-scout,e2e-harness): correct Hermes load claims MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Six spots stated that these plugins do not load on Hermes because they are absent from HERMES_ELIGIBLE. With the adapter allowlist gone, npx skills installs every skill-bearing plugin, so both now load on Hermes — and, like Codex, Hermes registers no named agents, so it takes the same Path B generic dispatch with Task mapped to delegate_task. Left as-is these sentences would also cite scripts/sync-hermes-manifests.mjs, which no longer exists. code-scout 2.3.0 -> 2.3.1, e2e-harness 0.2.1 -> 0.2.2, marketplace 2.7.0 -> 2.8.0 (MINOR, matching the #164 precedent for a removal). Codex manifests regenerated. Refs #166 --- .claude-plugin/marketplace.json | 6 +++--- plugins/code-scout/.claude-plugin/plugin.json | 2 +- plugins/code-scout/.codex-plugin/plugin.json | 2 +- plugins/code-scout/CLAUDE.md | 2 +- plugins/code-scout/skills/research-orchestrator/SKILL.md | 2 +- plugins/e2e-harness/.claude-plugin/plugin.json | 2 +- plugins/e2e-harness/.codex-plugin/plugin.json | 2 +- plugins/e2e-harness/references/role-contracts.md | 2 +- plugins/e2e-harness/skills/e2e-author/SKILL.md | 2 +- plugins/e2e-harness/skills/e2e-debug/SKILL.md | 2 +- plugins/e2e-harness/skills/e2e-setup/SKILL.md | 2 +- 11 files changed, 13 insertions(+), 13 deletions(-) diff --git a/.claude-plugin/marketplace.json b/.claude-plugin/marketplace.json index 4be5f2d8..1488fe6e 100644 --- a/.claude-plugin/marketplace.json +++ b/.claude-plugin/marketplace.json @@ -5,7 +5,7 @@ }, "metadata": { "description": "Personal Claude Code plugin collection with 24 specialized plugins. Codex 0.135 + Hermes Agent native — generated `.agents/plugins/marketplace.json` + per-plugin `.codex-plugin/plugin.json` (`scripts/sync-codex-manifests.mjs`) and Hermes `plugin.yaml` + `__init__.py` adapters (`scripts/sync-hermes-manifests.mjs`).", - "version": "2.7.0" + "version": "2.8.0" }, "plugins": [ { @@ -26,14 +26,14 @@ "name": "e2e-harness", "source": "./plugins/e2e-harness", "description": "Playwright E2E test-harness engineering — wraps Playwright's official AI test agents (npx playwright init-agents --loop=claude generates planner/generator/healer). Three skills close the planner -> generator -> healer self-improving loop: e2e-setup onboards the full harness (agents, auth separation via storageState + setup-project dependency, page.route mocking with Next.js BFF/SSR guidance, E2E operating SSOT doc, GitHub Actions CI with trace/report artifact upload + PR-failure comment + path/label gating); e2e-author selects critical user flows and runs planner -> review-gate -> generator with semantic getByRole locators and a --repeat-each burn-in flake gate; e2e-debug downloads the CI trace, inspects it headlessly, and runs the healer with bounded retries (skip-after-3 + reason comment). Never overwrites an existing playwright.config (merge + backup); degrades gracefully when Playwright is not installed.", - "version": "0.2.1", + "version": "0.2.2", "category": "testing" }, { "name": "code-scout", "source": "./plugins/code-scout", "description": "Multi-axis code & ML research harness. 5-axis scout team (github/hf/web/docs/paper) + synthesis-scout + research-orchestrator skill + exa-web-search skill. exa MCP first, WebSearch fallback, brightdata tier-3, insane-search tier-4 (WAF/blocked URLs). paper-scout wraps paper-search-tools 8-source family. /deep-research is the sibling for non-code/ML topics (code-scout does not delegate).", - "version": "2.3.0", + "version": "2.3.1", "category": "research" }, { diff --git a/plugins/code-scout/.claude-plugin/plugin.json b/plugins/code-scout/.claude-plugin/plugin.json index 7976afea..614da9aa 100644 --- a/plugins/code-scout/.claude-plugin/plugin.json +++ b/plugins/code-scout/.claude-plugin/plugin.json @@ -1,6 +1,6 @@ { "name": "code-scout", - "version": "2.3.0", + "version": "2.3.1", "description": "Multi-axis code & ML research harness. 5-axis scout team (github/hf/web/docs/paper) + synthesis-scout + research-orchestrator skill + exa-web-search skill. exa MCP first, WebSearch fallback, brightdata tier-3, insane-search tier-4 (WAF/blocked URLs). paper-scout wraps paper-search-tools 8-source family. /deep-research is the sibling for non-code/ML topics (code-scout does not delegate).", "skills": [ "./skills/research-orchestrator", diff --git a/plugins/code-scout/.codex-plugin/plugin.json b/plugins/code-scout/.codex-plugin/plugin.json index 140cfd79..02d322a4 100644 --- a/plugins/code-scout/.codex-plugin/plugin.json +++ b/plugins/code-scout/.codex-plugin/plugin.json @@ -1,6 +1,6 @@ { "name": "code-scout", - "version": "2.3.0", + "version": "2.3.1", "description": "Multi-axis code & ML research harness. 5-axis scout team (github/hf/web/docs/paper) + synthesis-scout + research-orchestrator skill + exa-web-search skill. exa MCP first, WebSearch fallback, brightdata tier-3, insane-search tier-4 (WAF/blocked URLs). paper-scout wraps paper-search-tools 8-source family. /deep-research is the sibling for non-code/ML topics (code-scout does not delegate).", "author": { "name": "YoungjaeDev" diff --git a/plugins/code-scout/CLAUDE.md b/plugins/code-scout/CLAUDE.md index 8fa8241a..ee077886 100644 --- a/plugins/code-scout/CLAUDE.md +++ b/plugins/code-scout/CLAUDE.md @@ -15,7 +15,7 @@ Multi-axis code & ML research harness. v2.1 grows the v2.0 4-axis team to a 5-ax | Already have artifacts, just need merge | `Agent(subagent_type="code-scout:synthesis-scout")` | | General non-code/ML topic (politics / market / history / biographies) | `/deep-research` directly — code-scout doesn't delegate, boundary is intentional | -**Runtime note:** the single-axis `Agent(subagent_type="code-scout:*-scout")` rows above are **Claude-only** — Codex 0.135 exposes the skills but cannot register the `agents/*.md` definitions. Under Codex, enter through `Skill("code-scout:research-orchestrator")`; it detects that the named agents are unregisterable and runs the same axes via generic parallel subagents (or sequential in-agent when delegation is unavailable), synthesizing in-skill. (Hermes is forward-compat: `code-scout` is not yet in `HERMES_ELIGIBLE`, so the skill does not load on Hermes today; the same generic-delegation path is ready via `delegate_task` once it is added.) See `skills/research-orchestrator/references/axis-contracts.md` for the shared contract all three execution paths consume. +**Runtime note:** the single-axis `Agent(subagent_type="code-scout:*-scout")` rows above are **Claude-only** — Codex 0.135 exposes the skills but cannot register the `agents/*.md` definitions. Under Codex, enter through `Skill("code-scout:research-orchestrator")`; it detects that the named agents are unregisterable and runs the same axes via generic parallel subagents (or sequential in-agent when delegation is unavailable), synthesizing in-skill. (Hermes loads this skill too — `npx skills` installs every skill-bearing plugin — and lands on the same generic-delegation path, mapping `Task` to `delegate_task`.) See `skills/research-orchestrator/references/axis-contracts.md` for the shared contract all three execution paths consume. For the full routing matrix (should / should-NOT, near-miss disambiguation vs `paper-search-tools`, `deepwiki:ask`, `github-dev:*`, `/deep-research`), see `skills/research-orchestrator/references/agent-routing.md`. diff --git a/plugins/code-scout/skills/research-orchestrator/SKILL.md b/plugins/code-scout/skills/research-orchestrator/SKILL.md index 9363bad7..a1d2341f 100644 --- a/plugins/code-scout/skills/research-orchestrator/SKILL.md +++ b/plugins/code-scout/skills/research-orchestrator/SKILL.md @@ -107,7 +107,7 @@ Before dispatch, pick the execution path **once**. This decides *how* the chosen | **B — generic parallel subagents** | Named `code-scout:*-scout` are NOT registerable, but a generic subagent-delegation tool is available (Codex `Task`, Hermes `delegate_task`). | Phase 4B — one generic subagent per axis, each carrying its `axis-contracts.md` contract inline. | | **C — sequential in-agent** | Neither named agents nor generic delegation is available (delegation unsupported / disabled, or concurrency exhausted / repeated dispatch failure). | Phase 4C — run the axes one at a time in the current agent, following each `axis-contracts.md` contract. | -Detection is a runtime fact: Claude Code registers `agents/*.md` as plugin subagents (Path A); Codex 0.135 exposes this skill but cannot register those agent files, so it lands on Path B (generic `Task` delegation), degrading to Path C only when delegation is unavailable. Hermes support is **forward-compatible, not active** — `code-scout` is not in the Hermes adapter allowlist (`HERMES_ELIGIBLE` in `scripts/sync-hermes-manifests.mjs`), so it does not load on Hermes today; the Path B `delegate_task` mapping is ready for when it is added. **Never silently drop an axis because its named agent is missing — switch paths instead.** Tell the user which path you took in one sentence. +Detection is a runtime fact: Claude Code registers `agents/*.md` as plugin subagents (Path A); Codex 0.135 exposes this skill but cannot register those agent files, so it lands on Path B (generic `Task` delegation), degrading to Path C only when delegation is unavailable. Hermes behaves the same way: it loads this skill (installed via `npx skills`) but registers no named agents either, so it also lands on Path B, mapping `Task` to `delegate_task`. **Never silently drop an axis because its named agent is missing — switch paths instead.** Tell the user which path you took in one sentence. ### 4. Fan-out dispatch diff --git a/plugins/e2e-harness/.claude-plugin/plugin.json b/plugins/e2e-harness/.claude-plugin/plugin.json index 2bcd73c8..193dfc0b 100644 --- a/plugins/e2e-harness/.claude-plugin/plugin.json +++ b/plugins/e2e-harness/.claude-plugin/plugin.json @@ -1,6 +1,6 @@ { "name": "e2e-harness", - "version": "0.2.1", + "version": "0.2.2", "description": "Playwright E2E test-harness engineering — wraps Playwright's official AI test agents (npx playwright init-agents --loop=claude generates planner/generator/healer). Three skills close the planner -> generator -> healer self-improving loop: e2e-setup onboards the full harness (agents, auth separation via storageState + setup-project dependency, page.route mocking with Next.js BFF/SSR guidance, E2E operating SSOT doc, GitHub Actions CI with trace/report artifact upload + PR-failure comment + path/label gating); e2e-author selects critical user flows and runs planner -> review-gate -> generator with semantic getByRole locators and a --repeat-each burn-in flake gate; e2e-debug downloads the CI trace, inspects it headlessly, and runs the healer with bounded retries (skip-after-3 + reason comment). Never overwrites an existing playwright.config (merge + backup); degrades gracefully when Playwright is not installed.", "skills": [ "./skills/e2e-setup", diff --git a/plugins/e2e-harness/.codex-plugin/plugin.json b/plugins/e2e-harness/.codex-plugin/plugin.json index 0d90449f..a18b8a35 100644 --- a/plugins/e2e-harness/.codex-plugin/plugin.json +++ b/plugins/e2e-harness/.codex-plugin/plugin.json @@ -1,6 +1,6 @@ { "name": "e2e-harness", - "version": "0.2.1", + "version": "0.2.2", "description": "Playwright E2E test-harness engineering — wraps Playwright's official AI test agents (npx playwright init-agents --loop=claude generates planner/generator/healer). Three skills close the planner -> generator -> healer self-improving loop: e2e-setup onboards the full harness (agents, auth separation via storageState + setup-project dependency, page.route mocking with Next.js BFF/SSR guidance, E2E operating SSOT doc, GitHub Actions CI with trace/report artifact upload + PR-failure comment + path/label gating); e2e-author selects critical user flows and runs planner -> review-gate -> generator with semantic getByRole locators and a --repeat-each burn-in flake gate; e2e-debug downloads the CI trace, inspects it headlessly, and runs the healer with bounded retries (skip-after-3 + reason comment). Never overwrites an existing playwright.config (merge + backup); degrades gracefully when Playwright is not installed.", "author": { "name": "YoungjaeDev" diff --git a/plugins/e2e-harness/references/role-contracts.md b/plugins/e2e-harness/references/role-contracts.md index 745974d0..786f2c61 100644 --- a/plugins/e2e-harness/references/role-contracts.md +++ b/plugins/e2e-harness/references/role-contracts.md @@ -6,7 +6,7 @@ Shared planner / generator / healer role contracts consumed by **all three execu - **Path B — generic subagents (Codex 0.135).** Codex exposes these skills but cannot register `.claude/agents/*.md` as named subagents, so it dispatches one **generic** subagent per role, carrying that role's contract from this file inline (`Task(prompt=...)`). This file is the portable condensation of the generated agents' behavior. - **Path C — sequential in-agent.** When no delegation channel is available, the skill executes each role itself, one at a time, following the contract below. -> Hermes is **forward-compatible, not active**: `e2e-harness` is not in `HERMES_ELIGIBLE` (`scripts/sync-hermes-manifests.mjs`), so this plugin does not load on Hermes today. The Path B dispatch maps to Hermes `delegate_task` (see the tool-name table at the end) for when/if `e2e-harness` is added to the allowlist; on the live non-Claude runtime (Codex) the tool is `Task`. +> **Hermes takes Path B as well.** Its skills are installed with `npx skills` (`scripts/install-skills.mjs`), and like Codex it registers no `.claude/agents/*.md`, so the same generic dispatch applies — the tool is `delegate_task` under Hermes and `Task` under Codex (see the tool-name table at the end). Keep these contracts in sync with the behavior of the init-agents-generated agents (verified on Playwright 1.61 — see `.llmwiki/wiki/e2e-harness-ops/playwright-ai-harness.md`) when either changes. diff --git a/plugins/e2e-harness/skills/e2e-author/SKILL.md b/plugins/e2e-harness/skills/e2e-author/SKILL.md index fe23a808..f142bf50 100644 --- a/plugins/e2e-harness/skills/e2e-author/SKILL.md +++ b/plugins/e2e-harness/skills/e2e-author/SKILL.md @@ -8,7 +8,7 @@ allowed-tools: Read Write Edit Bash Glob Grep Task AskUserQuestion Turn a critical user flow into a reliable Playwright spec by driving the planner and generator **roles**. This skill orchestrates; the roles do the exploration and code generation. A spec read is a behavior contract; a spec run is a sensor. -Two runtime families, three execution paths, same gates: on **Claude Code** the roles are the named agents `e2e-setup` generated via `init-agents --loop=claude` (**Path A**); on **Codex 0.135** those agent files are not registerable as named subagents, so each role runs as a **generic subagent** carrying the bundled contract from `references/role-contracts.md` (**Path B**), or in-agent sequentially when no delegation is available (**Path C**). Hermes is forward-compatible only — `e2e-harness` is not yet in `HERMES_ELIGIBLE`, so it does not load on Hermes today; the generic dispatch maps to Hermes `delegate_task` for when it is added. +Two runtime families, three execution paths, same gates: on **Claude Code** the roles are the named agents `e2e-setup` generated via `init-agents --loop=claude` (**Path A**); on **Codex 0.135** those agent files are not registerable as named subagents, so each role runs as a **generic subagent** carrying the bundled contract from `references/role-contracts.md` (**Path B**), or in-agent sequentially when no delegation is available (**Path C**). Hermes loads these skills too (installed via `npx skills`) and registers no named agents either, so it takes the same generic dispatch, mapping `Task` to `delegate_task`. ## Precondition check diff --git a/plugins/e2e-harness/skills/e2e-debug/SKILL.md b/plugins/e2e-harness/skills/e2e-debug/SKILL.md index dfb045cc..e3ea645e 100644 --- a/plugins/e2e-harness/skills/e2e-debug/SKILL.md +++ b/plugins/e2e-harness/skills/e2e-debug/SKILL.md @@ -8,7 +8,7 @@ allowed-tools: Read Write Edit Bash Glob Grep Task AskUserQuestion The third leg of the harness. A CI failure is a sensor reading; this skill turns it back into a green test (or an honest quarantine), closing the planner -> generator -> **healer** self-improving loop. -Two runtime families, three execution paths, same bounded loop: on **Claude Code** the healer is the named agent `e2e-setup` generated (**Path A**); on **Codex 0.135** that agent file is not registerable, so the healer runs as a **generic subagent** carrying the bundled contract from `references/role-contracts.md` (**Path B**), or in-agent sequentially when no delegation is available (**Path C**). Hermes is forward-compatible only — `e2e-harness` is not yet in `HERMES_ELIGIBLE`, so it does not load on Hermes today; the generic dispatch maps to Hermes `delegate_task` for when it is added. +Two runtime families, three execution paths, same bounded loop: on **Claude Code** the healer is the named agent `e2e-setup` generated (**Path A**); on **Codex 0.135** that agent file is not registerable, so the healer runs as a **generic subagent** carrying the bundled contract from `references/role-contracts.md` (**Path B**), or in-agent sequentially when no delegation is available (**Path C**). Hermes loads these skills too (installed via `npx skills`) and registers no named agents either, so it takes the same generic dispatch, mapping `Task` to `delegate_task`. > **Verified against Playwright 1.61.0.** The headless `npx playwright trace` CLI was introduced in 1.59; the subcommand set below is confirmed on 1.61. The GUI viewer `npx playwright show-trace ` is also available if a human wants to look. diff --git a/plugins/e2e-harness/skills/e2e-setup/SKILL.md b/plugins/e2e-harness/skills/e2e-setup/SKILL.md index 67541763..11a85d4f 100644 --- a/plugins/e2e-harness/skills/e2e-setup/SKILL.md +++ b/plugins/e2e-harness/skills/e2e-setup/SKILL.md @@ -8,7 +8,7 @@ allowed-tools: Read Write Edit Bash Glob Grep AskUserQuestion Stand up Playwright's official AI test harness (planner -> generator -> healer) plus the surrounding engineering (auth separation, deterministic mocking, an E2E SSOT doc, gated CI). The harness is the point: a test run is a sensor, a test file is a spec, and the three roles form a self-improving loop. This skill only does **setup + orchestration + CI + integration** — it does not re-implement the roles. -> **Two runtime paths (Step 2).** Under **Claude Code**, `init-agents --loop=claude` generates the planner/generator/healer as registerable `.claude/agents/*.md`, and `e2e-author` / `e2e-debug` dispatch them by name (**Path A**). Under **Codex 0.135**, those generated agent files are not registerable as named subagents, so setup skips them, ensures the `.mcp.json` `playwright-test` entry, and the author/debug skills run the same roles as **generic subagents** carrying the bundled `references/role-contracts.md` (**Path B**), or sequentially when no delegation is available (**Path C**). The engineering below (Steps 3-7) and every gate are identical on both paths. (Hermes is forward-compatible only — `e2e-harness` is not yet in `HERMES_ELIGIBLE`, so it does not load on Hermes today; the generic path maps to Hermes `delegate_task` for when it is added.) +> **Two runtime paths (Step 2).** Under **Claude Code**, `init-agents --loop=claude` generates the planner/generator/healer as registerable `.claude/agents/*.md`, and `e2e-author` / `e2e-debug` dispatch them by name (**Path A**). Under **Codex 0.135**, those generated agent files are not registerable as named subagents, so setup skips them, ensures the `.mcp.json` `playwright-test` entry, and the author/debug skills run the same roles as **generic subagents** carrying the bundled `references/role-contracts.md` (**Path B**), or sequentially when no delegation is available (**Path C**). The engineering below (Steps 3-7) and every gate are identical on both paths. (Hermes loads these skills too — installed via `npx skills` — and registers no named agents either, so it takes the same generic path, mapping `Task` to `delegate_task`.) > **Why this skill exists (the harness-engineering point).** Installing the official agents is NOT enough — out of the box they skip auth setup, can't resolve project-known API errors, and don't know test-account usage, because they lack codebase context. Steps 3-7 below *onboard them like a new hire*: the config, auth scaffold, route-mock guidance, and especially the E2E SSOT doc are the context an agent needs to work autonomously. Skipping them is the usual reason "the official agents didn't just work." From 6f7c932fa2dbb304c85a20dc1b8acfdd831756f4 Mon Sep 17 00:00:00 2001 From: YoungjaeDev Date: Mon, 27 Jul 2026 10:03:14 +0900 Subject: [PATCH 03/12] docs: make npx skills the Hermes delivery path MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Rewrite the Hermes sections of AGENTS.md and README.md around scripts/install-skills.mjs, drop the adapter regeneration rules from .claude/rules/dual-integration.md and code_review.md, and correct two claims the retirement invalidates: - the guard list is 4, not 5 (sync-hermes --check is gone) - Hermes indexes ~/.hermes/skills/ passively — installed skills appear in skills_list() and become slash commands, so a description surfaces a skill the same way it does under Claude Code and Codex. The old "explicit skill_view() load only" rule described the adapter path, not this one. Also document the flat-namespace tradeoff (cr-fix, not github-dev:cr-fix) and fix install-skills.mjs's global lockfile path, which read ~/.agents/skills-lock.json but is ~/.agents/.skill-lock.json. Refs #166 --- .claude/rules/dual-integration.md | 12 ++--- AGENTS.md | 32 ++++++------- README.md | 76 +++++++++++++------------------ code_review.md | 2 +- scripts/install-skills.mjs | 9 +++- 5 files changed, 62 insertions(+), 69 deletions(-) diff --git a/.claude/rules/dual-integration.md b/.claude/rules/dual-integration.md index afb8e22f..40605a28 100644 --- a/.claude/rules/dual-integration.md +++ b/.claude/rules/dual-integration.md @@ -2,7 +2,7 @@ This marketplace is driven by **Claude Code, Codex CLI, and Hermes Agent**. Instructions, hooks, and lore that live on only one surface are invisible to part of the toolchain. When you edit anything that shapes agent behavior, check the paired surfaces on the other runtimes in the same change. -Since 1.40.0 the runtimes share one source tree: Codex 0.135 reads `plugins//` in place via generated `.codex-plugin/plugin.json` manifests, and Hermes Agent reads it via generated `plugin.yaml` + `__init__.py` adapters (the old `codex-bridge` body-transform mirror was retired). So "keeping the surfaces in sync" is mostly about guidance, hooks, and manifest/adapter regeneration — not copying files. +Since 1.40.0 the runtimes share one source tree: Codex 0.135 reads `plugins//` in place via generated `.codex-plugin/plugin.json` manifests, and Hermes Agent gets its skills from the same tree through `npx skills` (`scripts/install-skills.mjs`) with no generated artifact at all — the old `codex-bridge` body-transform mirror and the Hermes `plugin.yaml` + `__init__.py` adapters were both retired. So "keeping the surfaces in sync" is mostly about guidance, hooks, and Codex manifest regeneration — not copying files. ## Role @@ -16,7 +16,7 @@ Top-level guidance no longer needs mirroring at all: root `CLAUDE.md` is a one-l |---|---|---|---| | Top-level guidance | `CLAUDE.md` → one-line `@AGENTS.md` import; `.claude/rules/*.md` (auto-loaded) | `AGENTS.md` (read verbatim — no `@import` mechanism) | `AGENTS.md` (read verbatim) | | Prompt-submit injection | plugin `UserPromptSubmit` hook (`plugin.json` → `hooks/*.sh`) | bundled `hooks/codex-hooks.json` → generated manifest `hooks` (`codex` format arg, `/hooks` trust); legacy manual `~/.codex/hooks.json` still works | (separate hook surface — currently unused) | -| Skill delivery | `plugins/*/skills` (native) | same tree in place + generated `.codex-plugin/plugin.json` (`scripts/sync-codex-manifests.mjs`) | same tree in place + generated `plugin.yaml` + `__init__.py` (`scripts/sync-hermes-manifests.mjs`) | +| Skill delivery | `plugins/*/skills` (native) | same tree in place + generated `.codex-plugin/plugin.json` (`scripts/sync-codex-manifests.mjs`) | same tree installed into `~/.hermes/skills/` by `npx skills` (`scripts/install-skills.mjs`) — no generated artifact | | Command / subagent | `plugins/*/{commands,agents}` (native) | not supported by Codex 0.135 — Claude-only | not supported by Hermes — skills only | | Skill-body tool names | Claude tool names (`Bash`, `Read`, …) | identical to Claude (body read verbatim) | mapped to Hermes tools via in-body compat table (`Bash`→`terminal`, `AskUserQuestion`→`clarify`, …) | | Shared neutral lore | `.llmwiki/` (read by Claude) | `.llmwiki/` (read by Codex — same root, never forked) | `.llmwiki/` (read by Hermes — same root) | @@ -27,7 +27,7 @@ Top-level guidance no longer needs mirroring at all: root `CLAUDE.md` is a one-l - **Mirror cross-cutting `.claude/rules/` rules into `AGENTS.md`.** Codex has no `@import` mechanism at all — it reads `AGENTS.md` byte-for-byte and expands nothing — so a rule that both agents must honor needs a concise mirror block in `AGENTS.md` plus a one-line pointer in the `## Modular Rules` section of `AGENTS.md` (which Claude reaches through the `CLAUDE.md` → `@AGENTS.md` import). `@import` is a Claude-only feature and only works from `CLAUDE.md`; Codex and Hermes read `AGENTS.md` verbatim. - **Pair every hook change.** A new or changed Claude `UserPromptSubmit` / `SessionStart` hook in a `plugin.json` should be mirrored to Codex. The primary path is a bundled `hooks/codex-hooks.json` descriptor that `node scripts/sync-codex-manifests.mjs` wires into the generated manifest's top-level `hooks` (the legacy manual `~/.codex/hooks.json` copy still works). Prefer one shared script with a format arg (plain stdout for Claude, JSON `additionalContext` for Codex) over two divergent copies. Either path needs a `/hooks` trust approval in Codex. - **Regenerate Codex manifests after a plugin's skills / `version` / `description` / `category` change.** Run `node scripts/sync-codex-manifests.mjs` (the `--check` drift guard otherwise fails). Codex reads skill bodies in place — no transform — so valid frontmatter still matters; `commands/` and `agents/` are Claude-only and are not emitted. A source-controlled `hooks/codex-hooks.json` is wired into the manifest's top-level `hooks`; `--check` validates the descriptor shape + referenced scripts and rejects orphans. Only codex-image is excluded (see `manifest-eligibility.mjs` `CODEX_EXCLUDED`) — core-config is now Codex-eligible as a hooks-only manifest. -- **Regenerate Hermes adapters after a HERMES_ELIGIBLE plugin's `version` / `description` change.** Run `node scripts/sync-hermes-manifests.mjs` (the `--check` drift + orphan guard otherwise fails). `plugin.yaml` / `__init__.py` are generated from `marketplace.json` — never hand-edit them. Coverage is the generator's `HERMES_ELIGIBLE` allowlist (the symmetric counterpart of Codex's `EXCLUDED` denylist); add a name to extend it. +- **Nothing to regenerate for Hermes.** `npx skills` parses `.claude-plugin/marketplace.json` at install time and pulls `plugins//skills/*/SKILL.md` straight from the tree, so there is no derived Hermes artifact to keep in sync and no eligibility allowlist to extend — coverage is every skill-bearing plugin. Adding a plugin needs no Hermes-side action. - **Keep shared skill bodies runtime-portable.** Claude and Codex share tool names, so a body that also runs under Hermes carries a compatibility table mapping Claude/Codex tool terms (`Bash`, `Read`, `Edit`, `AskUserQuestion`, `Task`, `Skill`, `NotebookEdit`, image generation) to Hermes tools (`terminal`, `read_file`, `patch`, `clarify`, `delegate_task`, `skill_view`, Jupyter Live Kernel / `write_file`·`patch`, `image_generate`). Add or refresh the table when a body's tool usage changes. A body that invokes bundled `scripts/` must not reference `${CLAUDE_PLUGIN_ROOT}` bare — Codex 0.135 does not export it, so the call fails at step one; carry the cross-runtime `PLUGIN_ROOT` resolver block instead (`CLAUDE_PLUGIN_ROOT` → source-tree `plugins/` → Codex cache lookup; reference implementations: project-init, mem0-ops). - **Keep subagent delegation Claude-only acceleration.** A Claude-side subagent dispatch may only wrap a skill phase whose inline cross-runtime path stays primary and complete — never move skill logic into an agent definition (Codex 0.135 and Hermes have no agents surface, so relocated logic silently vanishes for them). - **Keep skill `description` frontmatter under 1024 chars.** Codex 0.135 silently skips any skill whose `description` exceeds 1024 characters; Claude Code has no such limit, so the violation is invisible on the Claude side. `--check` validates description length (not just drift), and the shared `.githooks/pre-commit` runs it on every commit — activate once per clone with `git config core.hooksPath .githooks`. Put the full trigger list / per-tool rationale in the skill body, not the description. @@ -35,14 +35,14 @@ Top-level guidance no longer needs mirroring at all: root `CLAUDE.md` is a one-l - **Write instruction and skill documentation prose in English.** Skill bodies, bundled reference docs, and plugin `CLAUDE.md` prose are English so all three runtimes — and the Codex GitHub cloud reviewer — read one language. Domain content is exempt and stays in its source language: marketing/UI copy, form presets, humanize samples, illustrative Korean example outputs, and the i18n / trigger phrases inside a skill `description:` frontmatter field (translating those breaks skill matching). A skill whose output is functional content in the user's language (a seeded stub, a runtime message shown to the user) keeps that content as-is — translating it changes what the plugin emits, not just its documentation. - **Keep shared lore in the neutral root.** Cross-agent insight and wiki content live under `.llmwiki/` (never `.claude/`-only), so both runtimes read one copy. - **State when a change is intentionally single-surface.** If guidance applies to only one agent (e.g. a Claude-only Plan Mode rule), say so in the change so the asymmetry reads as deliberate, not forgotten. -- **Hermes plugin skills load explicitly, never by passive index.** Under Hermes a plugin skill is reached only through an explicit `skill_view(":")` load (or asking Hermes to load that qualified skill) after the plugin is enabled — it is never auto-surfaced by its `description` the way Claude Code and Codex 0.135 index skills. The trigger phrasing still belongs in the `description`, but the load itself is a deliberate call, so a body that assumes it was auto-selected from its description is wrong for Hermes. This is why every shared body carries the Hermes compatibility note at its top; treat that note as the load contract, not decoration. +- **Hermes indexes `~/.hermes/skills/` passively, like the other two runtimes.** That directory is Hermes' skill source of truth: anything installed there is listed by `skills_list()` and also becomes a slash command, so a `description` surfaces a skill the same way it does under Claude Code and Codex 0.135. (This replaces the old plugin-adapter contract, where a skill was reachable only through an explicit `skill_view(":")` call after enabling the plugin.) Names install flat — `cr-fix`, not `github-dev:cr-fix` — so keep skill names distinctive enough not to collide with skills from other sources. - **Centralize a skill's tool-name mapping gradually, in `references/-tools.md`.** The inline Claude/Codex→Hermes compatibility table at the top of each shared body is the current mechanism, but for a *new or newly-edited* skill prefer offloading the mapping to a bundled `references/-tools.md` and pointing the body at it — one authored table per harness instead of the same table re-typed into every body. This is a deliberate gradual migration: do not rewrite existing bodies just to relocate the table (surgical-diff), only adopt the reference-file form when you are already editing that body's tool usage. ## Don'ts - **Never add behavioral guidance to `CLAUDE.md` alone when it should bind both agents.** A Claude-only edit silently exempts every Codex session. - **Never wire a Claude hook without considering the Codex counterpart.** The bundled `hooks/codex-hooks.json` descriptor rides the generated Codex manifest, but Codex still requires a `/hooks` trust approval before a plugin's hooks run (the legacy `~/.codex/hooks.json` path needs the same trust). Neither is silently auto-enabled. -- **Never hand-edit generated manifests/adapters.** `.codex-plugin/plugin.json` + `.agents/plugins/marketplace.json` (Codex) and `plugin.yaml` + `__init__.py` (Hermes) are generator output; edit the marketplace source + regenerate, or the `--check` guards flag drift. +- **Never hand-edit generated manifests.** `.codex-plugin/plugin.json` + `.agents/plugins/marketplace.json` are generator output; edit the marketplace source + regenerate, or the `--check` guard flags drift. Hermes has no generated counterpart to protect. - **Never promote wiki lore to `.claude/rules/`.** Neither Codex nor Hermes reads `.claude/rules/`. Cross-agent insight graduates to `.llmwiki/insight/` and is surfaced via the shared prompt-injection hook (see `llm-wiki` ingest rules). `.claude/rules/` is reserved for mechanical tool-operation rules (versioning, this file), not lore. - **Never fork `.llmwiki/` into per-agent copies.** One neutral root is the point; a `.codex/wiki/` fork defeats it. - **Never reduce `AGENTS.md` to a pointer at `CLAUDE.md`.** An `@CLAUDE.md` line is dead text under Codex and Hermes (neither expands `@`), and a prose "read CLAUDE.md first" redirect cannot reach the Codex GitHub cloud reviewer, which loads the `## Review guidelines` section straight into its system prompt rather than following an arbitrary prose redirect to other files (a specifically-referenced `code_review.md` is the one documented exception the reviewer *can* follow — a soft guarantee per the Codex best-practices doc, distinct from a vague "go read X" pointer). The failure is silent — Codex reports no error, it just runs with no guidance. This repo took the inverse, which is the safe direction: `AGENTS.md` is the SSOT and `CLAUDE.md` is a one-line `@AGENTS.md` import — the form the official Claude docs recommend, and portable to Windows checkouts. (A symlink achieves the same and is marginally stronger — one file cannot drift from itself — but checks out broken on Windows without `core.symlinks` (git writes `CLAUDE.md` as a text file containing the literal target string), so the import is preferred here.) @@ -50,4 +50,4 @@ Top-level guidance no longer needs mirroring at all: root `CLAUDE.md` is a one-l ## Source of Truth - This file is the Claude-side SSOT; the `AGENTS.md` "멀티런타임 통합" block is its Codex/Hermes mirror — keep them consistent. -- Related: `plugin-versioning.md` (version bump + manifest/adapter regen), the `AGENTS.md` "Codex 통합 (shared-source)" and "Hermes 통합 (shared-source)" sections, `.llmwiki/wiki/plugin-ops/shared-source-codex-manifests.md` (Codex shared-source rationale), and `.llmwiki/wiki/plugin-ops/hermes-plugin-adapter.md` (Hermes adapter rationale). +- Related: `plugin-versioning.md` (version bump + Codex manifest regen), the `AGENTS.md` "Codex 통합 (shared-source)" and "Hermes 통합 (shared-source)" sections, `.llmwiki/wiki/plugin-ops/shared-source-codex-manifests.md` (Codex shared-source rationale), and `.llmwiki/wiki/plugin-ops/skills-install-wrapper.md` (why Hermes goes through `npx skills` instead of a generated adapter; the retired adapter's rationale is kept at `hermes-plugin-adapter.md`). diff --git a/AGENTS.md b/AGENTS.md index 417505c1..88f352e1 100644 --- a/AGENTS.md +++ b/AGENTS.md @@ -13,7 +13,7 @@ - 플러그인 개발 중 라이브러리·런타임·플랫폼 사실을 확인할 때는 `docs/llm-doc-sources.md` 에 정리된 LLM 문서 소스(mcpdocs 등록 + deepwiki 타깃)를 먼저 사용하세요. - 문서와 매니페스트가 함께 움직이는 저장소이므로 코드 변경뿐 아니라 `README.md`, 이 문서, marketplace manifest의 동기화 필요성을 항상 확인하세요. -플러그인 트리 하나를 Claude Code, Codex 0.135(`scripts/sync-codex-manifests.mjs`), Hermes Agent(`scripts/sync-hermes-manifests.mjs`)가 함께 읽습니다 — one source, three runtimes. +플러그인 트리 하나를 Claude Code, Codex 0.135(`scripts/sync-codex-manifests.mjs`), Hermes Agent(`scripts/install-skills.mjs` → `npx skills`)가 함께 읽습니다 — one source, three runtimes. ## Plugins (24) @@ -108,10 +108,9 @@ - `plugins//`: 각 플러그인의 원본 디렉터리. - `plugins//.claude-plugin/plugin.json`: 플러그인별 매니페스트와 버전. - `plugins//.codex-plugin/plugin.json`: Codex 0.135 용 매니페스트 (generated, do not edit by hand). -- `plugins//plugin.yaml` + `plugins//__init__.py`: Hermes Agent 어댑터 (HERMES_ELIGIBLE 플러그인만, generated, do not edit by hand). - `.agents/plugins/marketplace.json`: Codex marketplace 카탈로그 (generated). - `scripts/sync-codex-manifests.mjs`: Codex 매니페스트 생성기. `--check` 로 drift 가드, `--dry-run` 으로 출력 미리보기. -- `scripts/sync-hermes-manifests.mjs`: Hermes 어댑터 생성기. `--check` drift + orphan 가드, `--dry-run` 미리보기. +- `scripts/install-skills.mjs`: 스킬 설치 진입점. `npx skills` 를 감싸 Codex·Hermes 에 스킬을 설치한다. Hermes 는 생성 산출물이 없다 (이 스크립트가 유일한 경로). ## 멀티런타임 통합 (Claude Code ↔ Codex ↔ Hermes Agent) @@ -121,14 +120,14 @@ |---|---|---|---| | 최상위 지침 | `CLAUDE.md` (`@AGENTS.md` import), `.claude/rules/*.md` (auto-load) | `AGENTS.md` (verbatim 로드 — `@import` 메커니즘 자체가 없음) | `AGENTS.md` (verbatim) | | 프롬프트 주입 hook | 플러그인 `UserPromptSubmit` (`plugin.json` → `hooks/*.sh`) | 번들 `hooks/codex-hooks.json` → 매니페스트 `hooks` 배선 (`codex` 포맷 인자, `/hooks` trust). 레거시 수동 `~/.codex/hooks.json` 도 여전히 동작 | (별도 hook surface — 현재 미사용) | -| skill | `plugins/*/skills` (native) | 같은 트리 in-place + generated `.codex-plugin/plugin.json` (아래 "Codex 통합") | 같은 트리 in-place + generated `plugin.yaml` + `__init__.py` (아래 "Hermes 통합") | +| skill | `plugins/*/skills` (native) | 같은 트리 in-place + generated `.codex-plugin/plugin.json` (아래 "Codex 통합") | 같은 트리에서 `npx skills` 로 `~/.hermes/skills/` 에 설치 — 생성 산출물 없음 (아래 "Hermes 통합") | | command / subagent | `plugins/*/{commands,agents}` (native) | Codex 0.135 미지원 (Claude-only) | Hermes 미지원 (skill 만) | | skill 본문 도구명 | Claude 도구명 (`Bash`, `Read`, ...) | Claude 와 동일 (본문 그대로 읽음) | 본문의 호환 표로 Hermes 도구명 매핑 (`Bash`→`terminal`, `AskUserQuestion`→`clarify`, ...) | | 공유 중립 lore | `.llmwiki/` (세 에이전트 동일 루트, fork 금지) | `.llmwiki/` | `.llmwiki/` | - 최상위 지침은 이 파일 한 곳에만 쓴다. `CLAUDE.md` 는 `@AGENTS.md` 한 줄 import 라 편집할 내용이 없다. - Claude hook 을 추가/변경하면 Codex 대응을 점검한다: 플러그인이 번들 `hooks/codex-hooks.json` 디스크립터를 실으면 `node scripts/sync-codex-manifests.mjs` 가 이를 매니페스트 top-level `hooks` 로 배선한다 (레거시 수동 `~/.codex/hooks.json` 경로는 여전히 유효). 어느 쪽이든 Codex hook 은 별도 `/hooks` trust 승인이 필요하다 (자동 등록 안 됨). -- skill / 버전 / description 을 바꾸면 Codex 매니페스트 재생성(`node scripts/sync-codex-manifests.mjs`) + (Hermes-eligible 이면) Hermes 어댑터 재생성(`node scripts/sync-hermes-manifests.mjs`)이 필요한지 점검한다 ("Codex 통합" / "Hermes 통합" 섹션 + `plugin-versioning.md`). +- skill / 버전 / description 을 바꾸면 Codex 매니페스트 재생성(`node scripts/sync-codex-manifests.mjs`)이 필요한지 점검한다 ("Codex 통합" 섹션 + `plugin-versioning.md`). Hermes 쪽에는 재생성할 산출물이 없다 — 설치본은 `npx skills` 가 소스 트리에서 직접 가져간다. - skill 본문을 추가/변경할 때 Hermes 호환 표(Claude/Codex 도구 용어 → Hermes 도구)를 점검한다 — 3런타임 포터블. - subagent 위임은 Claude 전용 가속일 뿐이다 — skill 단계의 인라인 크로스런타임 경로가 primary 로 남아야 하고, skill 로직을 agent 정의로 옮기지 않는다 (Codex 0.135 / Hermes 는 agents surface 가 없어 옮긴 로직이 조용히 사라진다). - wiki lore 는 `.claude/rules/` 로 승격하지 않는다 — Codex/Hermes 가 못 읽는다. cross-agent insight 는 `.llmwiki/insight/` 로 graduate 후 공유 주입 hook 으로 노출한다. @@ -153,9 +152,9 @@ - 플러그인 버전을 올릴 때는 `plugins//.claude-plugin/plugin.json`과 `.claude-plugin/marketplace.json`의 해당 항목을 같은 변경에 포함하세요. - `plugins//` 아래 **어떤 파일이든** 바뀌면 버전 범프 대상입니다 — 코드/스킬뿐 아니라 번들 `references/`·`docs`·asset 편집도 포함. 캐시로 게이트된 사용자는 버전 범프가 있어야 새 내용을 받으므로, 문서만 고쳐도 해당 플러그인 PATCH + `metadata.version`을 올립니다 (Codex-eligible 이면 매니페스트 재생성). 반면 루트 문서(`AGENTS.md`, `README.md`, `code_review.md`, `.claude/rules/*`)는 플러그인 콘텐츠가 아니라 어떤 플러그인도 범프하지 않습니다. -- Hermes-eligible 플러그인: `plugins//plugin.yaml`(Hermes 어댑터)의 `version`은 `sync-hermes-manifests.mjs` 가 marketplace 에서 파생해 생성하므로, 버전 범프 후 `node scripts/sync-hermes-manifests.mjs` 재실행으로 갱신하세요. `sync-hermes-manifests.mjs --check` 가 drift 를 가드하므로 수동 동기화는 불필요합니다 (단 Codex `--check` 는 Codex 매니페스트만 봅니다). +- Hermes 쪽에는 버전을 담은 생성 산출물이 없습니다 — 설치본은 `npx skills` 가 소스 트리에서 직접 가져가므로 별도 재생성이나 drift 가드가 필요 없습니다. - 어떤 플러그인 버전이든 변경하면 `.claude-plugin/marketplace.json`의 `metadata.version`도 marketplace release 버전으로 올리세요. -- 플러그인을 추가하거나 제거하면 이 문서의 `## Plugins (N)` 수와 목록, `README.md`의 플러그인 수와 목록도 갱신하세요. 이 문서의 미러 카운트(Hermes allowlist `현재 N개`, Codex 검증 주석 `# N entries`)도 같은 변경에서 함께 갱신하세요 — `--check` 가 못 잡습니다. +- 플러그인을 추가하거나 제거하면 이 문서의 `## Plugins (N)` 수와 목록, `README.md`의 플러그인 수와 목록도 갱신하세요. 이 문서의 미러 카운트(Codex 검증 주석 `# N entries`)도 같은 변경에서 함께 갱신하세요 — `--check` 가 못 잡습니다. - 버전은 semver를 따릅니다. 버그 수정은 PATCH, 하위 호환 기능은 MINOR, 깨지는 변경은 MAJOR입니다. - Claude Code 플러그인 캐시 이슈 때문에 사용자 문서나 릴리스 안내에는 필요 시 `rm -rf ~/.claude/plugins/cache/my-claude-plugins/` 후 marketplace update 및 Claude Code 재시작 절차를 유지하세요. @@ -235,26 +234,25 @@ node scripts/sync-codex-manifests.mjs --check # CI drift guard ## Hermes 통합 (shared-source) ```bash -node scripts/sync-hermes-manifests.mjs # write adapters -node scripts/sync-hermes-manifests.mjs --check # CI drift guard (validate-codex.yml + .githooks/pre-commit) +node scripts/install-skills.mjs # 대화형 설치 (스킬 선택 → 타겟 → scope) +node scripts/install-skills.mjs --selftest # 검색 로직 self-check (TTY·네트워크 불필요) ``` -- Hermes Agent 도 **동일한** `plugins//` 트리를 직접 읽습니다. 어댑터(`plugin.yaml` + `__init__.py`)는 `scripts/sync-hermes-manifests.mjs` 가 `.claude-plugin/marketplace.json` 으로부터 생성합니다 — `plugins//plugin.yaml` / `__init__.py` 를 손으로 편집하지 마세요. -- 대상은 생성기의 `HERMES_ELIGIBLE` allowlist (Codex `EXCLUDED` denylist 의 대칭). 현재 7개: `github-dev`, `interview`, `anti-slop-design`, `tcrei-prompt`, `ppt-yeong-style`, `ml-toolkit`, `brightdata-guide`. 커버리지 확장은 allowlist 에 이름 추가. -- Hermes-eligible 플러그인의 `version` / `description` 을 바꾸면 `node scripts/sync-hermes-manifests.mjs` 를 실행해 어댑터를 재생성하세요. `plugin.yaml` 의 `version` 은 marketplace 파생이므로 `--check` 가 drift + orphan 어댑터를 잡습니다 (수동 동기화 불필요 — 생성으로 해소). -- `__init__.py` 는 `skills/*/SKILL.md` 를 `:` 으로 등록하는 제네릭 엔트리포인트입니다 (플러그인별 로직 없음, `import yaml`=PyYAML 가정). +- Hermes Agent 도 **동일한** `plugins//` 트리를 직접 읽습니다. 다만 **생성 산출물이 없습니다** — `npx skills`(vercel-labs/skills)가 `.claude-plugin/marketplace.json` 을 직접 파싱해 `plugins//skills/*/SKILL.md` 를 찾아 `~/.hermes/skills/` 로 설치합니다. `scripts/install-skills.mjs` 는 그 위에 플러그인 그룹 선택기와 `HERMES_HOME` 프로필 타겟팅만 얹은 zero-dep 래퍼입니다. +- 커버리지는 allowlist 가 아니라 "스킬을 가진 플러그인 전부"입니다 (현재 23 플러그인 / 52 스킬). 유지할 명단이 없으므로 플러그인을 추가해도 Hermes 쪽에 할 일이 없습니다. +- `~/.hermes/skills/` 는 Hermes 의 skill SoT 이고, 여기 설치된 스킬은 `skills_list()` 에 자동 노출되며 슬래시 커맨드가 됩니다 (공식 docs). 즉 `description` 기반 표면화가 Claude Code·Codex 와 동일하게 동작합니다. +- 설치는 심볼릭 링크가 기본이라 `~/.agents/skills/` 하나를 정본으로 두고 각 에이전트 디렉터리가 그걸 가리킵니다. 이름은 평평합니다 — `github-dev:cr-fix` 가 아니라 `cr-fix` 이므로 외부 스킬과 이름이 겹치지 않게 유지하세요. +- 이전의 네이티브 어댑터(`plugin.yaml` + `__init__.py`)와 `scripts/sync-hermes-manifests.mjs` 생성기는 #166 에서 제거했습니다. 어댑터는 7 플러그인 / 20 스킬만 덮으면서 버전 범프마다 재생성과 `--check` 를 요구했고, 로드에 `skill_view(":")` 명시 호출이 필요했습니다. - 공유 skill 본문은 3런타임 포터블이어야 합니다. Claude/Codex 는 도구명이 동일하므로, 본문에 Claude/Codex 도구 용어를 Hermes 도구로 매핑하는 호환 표(`Bash`→`terminal`, `Read`→`read_file`, `Edit`→`patch`, `AskUserQuestion`→`clarify`, `Task`→`delegate_task`, `Skill`→`skill_view`, 이미지 생성→`image_generate`, `NotebookEdit`→Hermes Jupyter Live Kernel / `write_file`·`patch` 등)를 둡니다. 새 skill 추가/도구 사용 변경 시 이 표를 점검하세요. 신규·편집 skill 은 이 표를 본문마다 다시 타이핑하는 대신 번들 `references/-tools.md` 로 중앙화하고 본문이 그것을 가리키는 형태를 우선합니다 — 점진 이관이므로 이미 그 본문의 도구 사용을 편집 중일 때만 채택하고, 표를 옮기려고 기존 본문을 새로 쓰지는 않습니다 (surgical-diff). - 번들 `scripts/` 를 호출하는 skill 본문은 `${CLAUDE_PLUGIN_ROOT}` 를 그대로 쓰지 마세요 — Codex 0.135 는 이 변수를 export 하지 않아 첫 단계에서 실패합니다. 크로스 런타임 `PLUGIN_ROOT` resolver 블록(`CLAUDE_PLUGIN_ROOT` → 소스트리 `plugins/` → Codex 캐시 탐색)을 본문에 포함하세요 (레퍼런스 구현: project-init, mem0-ops). -- Hermes plugin 스킬은 **명시 로드**입니다 (passive index 아님) — Claude Code/Codex 0.135 가 `description` 으로 skill 을 자동 표면화하는 것과 달리, Hermes 는 `--enable` 후 새 세션에서 `skill_view(":")` 로 명시 호출해야만 로드됩니다. trigger 문구는 여전히 `description` 에 두되 로드 자체는 의도된 호출이므로, "description 으로 자동 선택됐다" 고 가정하는 본문은 Hermes 에서 틀립니다 (본문 상단 Hermes 호환 노트를 로드 계약으로 취급). 어댑터와 무관한 스킬 단위 설치는 `node scripts/install-skills.mjs` (`npx skills`) 로 가능합니다. -- 생성기는 Node 18+ built-in 만 사용합니다. 런타임 의존성을 추가하지 마세요. +- `install-skills.mjs` 는 Node 18+ built-in 만 사용합니다. 런타임 의존성을 추가하지 마세요. ## 검증 -- Codex / Hermes 매니페스트 drift 가드 (모든 PR 에서 실행): +- Codex 매니페스트 drift 가드 (모든 PR 에서 실행): ```bash node scripts/sync-codex-manifests.mjs --check -node scripts/sync-hermes-manifests.mjs --check ``` - 로컬 Codex CLI 에서 marketplace 등록 확인: diff --git a/README.md b/README.md index 96e95cd7..e3ab668d 100644 --- a/README.md +++ b/README.md @@ -43,21 +43,20 @@ Claude Code에 빠져 있는 것들을 채웁니다: 설치 후 `/github-dev:resolve-issue 123` 같은 명령어로 바로 사용 가능합니다. -### Hermes Agent에서 github-dev만 설치 +### Hermes Agent / Codex에 스킬 설치 -Hermes Agent는 모노레포의 `plugins/github-dev` 서브디렉터리만 설치할 수 있습니다: +Claude Code 밖에서는 플러그인이 아니라 **스킬 단위**로 설치합니다. 대화형 설치기가 `npx skills` 를 감싸고 있습니다: ```bash -hermes plugins install YoungjaeDev/my-claude-plugins/plugins/github-dev --enable -hermes gateway restart # Slack/Telegram 등 gateway 사용 시 +node scripts/install-skills.mjs ``` -설치 후 새 Hermes 세션에서 plugin skill을 명시적으로 로드합니다 (`github-dev:`은 system prompt/skills_list에 자동 노출되지 않는 opt-in 대상입니다): +플러그인 그룹에서 원하는 스킬을 고른 뒤 타겟(`hermes-agent` / `codex`)과 scope(global `~/` / project `./`)를 선택하면 끝입니다. Hermes 는 `~/.hermes/skills/`, Codex 는 `~/.codex/skills/` 에 설치되고, 두 런타임 모두 거기 있는 스킬을 자동으로 인덱싱합니다 (Hermes 에서는 슬래시 커맨드로도 잡힙니다). -```text -skill_view("github-dev:resolve-issue") # 이후 이슈 번호와 함께 실행 요청 -skill_view("github-dev:cr-fix") # 이후 --cr-source auto 등 인자와 함께 실행 요청 -skill_view("github-dev:commit-and-push") +특정 스킬만 바로 넣으려면 `npx skills` 를 직접 써도 됩니다: + +```bash +npx skills add YoungjaeDev/my-claude-plugins -a hermes-agent -s cr-fix -s post-merge -g ``` ## 플러그인 업데이트 @@ -186,7 +185,7 @@ Playwright 공식 AI 테스트 에이전트(planner/generator/healer)를 래핑 | `/e2e-harness:e2e-author` | CUF(critical user flow) 선정 → planner 계획서 → **사용자 검토 게이트** → generator 스펙 생성(semantic `getByRole` 강제) → `--repeat-each` 번인으로 플래키 차단 | | `/e2e-harness:e2e-debug` | 실패한 CI run/PR 입력 → 트레이스 아티팩트 다운로드 → 헤드리스 trace 분석 → healer 원인 분석·수리(최대 3회 후 skip + 사유 코멘트) → 재실행 검증 | -**Cross-runtime (Claude / Codex):** 세 스킬은 런타임에 따라 두 런타임 계열·세 실행 경로(Path A/B/C)로 갈립니다. **Claude Code** 는 `init-agents --loop=claude` 가 생성한 named agent(planner/generator/healer)를 이름으로 디스패치합니다(**Path A**). **Codex 0.135** 는 그 agent 파일을 named subagent 로 등록하지 못하므로, 번들된 `references/role-contracts.md` 의 역할 계약을 인라인으로 실은 **generic subagent** 로 같은 역할을 실행하거나(**Path B**), 위임이 불가능하면 순차 실행합니다(**Path C**). CUF 선정·계획 검토 게이트·semantic locator·`--repeat-each` 번인·trace-first 진단·healer 3회 상한 등 모든 게이트는 두 경로에서 동일합니다. `--loop=codex` 는 버전 추정이 아니라 feature-detect 로만 사용하고, `.mcp.json` 의 `playwright-test` 항목은 기존 서버를 덮어쓰지 않고 머지합니다. (Hermes 는 forward-compatible — `e2e-harness` 는 아직 `HERMES_ELIGIBLE` 이 아니라 현재 Hermes 에는 로드되지 않으며, generic 경로가 향후 편입 시 `delegate_task` 로 매핑됩니다.) +**Cross-runtime (Claude / Codex):** 세 스킬은 런타임에 따라 두 런타임 계열·세 실행 경로(Path A/B/C)로 갈립니다. **Claude Code** 는 `init-agents --loop=claude` 가 생성한 named agent(planner/generator/healer)를 이름으로 디스패치합니다(**Path A**). **Codex 0.135** 는 그 agent 파일을 named subagent 로 등록하지 못하므로, 번들된 `references/role-contracts.md` 의 역할 계약을 인라인으로 실은 **generic subagent** 로 같은 역할을 실행하거나(**Path B**), 위임이 불가능하면 순차 실행합니다(**Path C**). CUF 선정·계획 검토 게이트·semantic locator·`--repeat-each` 번인·trace-first 진단·healer 3회 상한 등 모든 게이트는 두 경로에서 동일합니다. `--loop=codex` 는 버전 추정이 아니라 feature-detect 로만 사용하고, `.mcp.json` 의 `playwright-test` 항목은 기존 서버를 덮어쓰지 않고 머지합니다. (Hermes 도 이 스킬들을 로드하며 named agent 를 등록하지 못하는 것은 Codex 와 같아, 같은 generic 경로를 `delegate_task` 로 매핑해 실행합니다.) **Requirements:** Node.js + Playwright (`npm init playwright@latest`), `gh` CLI (e2e-debug 의 CI 트레이스 fetch) @@ -216,7 +215,7 @@ Playwright 공식 AI 테스트 에이전트(planner/generator/healer)를 래핑 | `paper-scout` | paper-search-tools 8-source 래핑 (arXiv/Semantic Scholar/Crossref/PubMed/bioRxiv/medRxiv/IACR/Google Scholar). 도메인별 2-3 source 선택, 학술 신호 감지 시 deep mode 5-axis 에 자동 인입 | | `synthesis-scout` | dedup (DOI 포함) / trust ranking (peer-reviewed > arxiv high-cite > arxiv recent) / conflict resolution / 최종 보고서 | -**런타임 이식성 (v2.2.0)**: 이 6개 agent 는 **Claude Code 전용** — Codex 0.135 는 skill 은 노출하지만 `agents/*.md` 를 등록하지 못한다 (Hermes 도 `delegate_task` fallback 대상이지만 `code-scout` 는 아직 Hermes-eligible 이 아니라 로드되지 않는다 — forward-compat). 그 런타임에서는 `research-orchestrator` skill 이 named agent 미등록을 감지해 동일 축을 generic 병렬 subagent (Codex `Task` / Hermes `delegate_task`) 로, 위임 불가 시 현재 에이전트 내 순차 실행으로 돌리고 synthesis 를 in-skill 로 수행한다. 세 경로가 공유하는 계약은 `skills/research-orchestrator/references/axis-contracts.md`. Claude named-agent quick / deep 경로 동작은 무변경. +**런타임 이식성 (v2.2.0)**: 이 6개 agent 는 **Claude Code 전용** — Codex 0.135 는 skill 은 노출하지만 `agents/*.md` 를 등록하지 못한다 (Hermes 도 이 skill 을 로드하되 마찬가지로 named agent 는 등록하지 못해 `delegate_task` fallback 을 탄다). 그 런타임에서는 `research-orchestrator` skill 이 named agent 미등록을 감지해 동일 축을 generic 병렬 subagent (Codex `Task` / Hermes `delegate_task`) 로, 위임 불가 시 현재 에이전트 내 순차 실행으로 돌리고 synthesis 를 in-skill 로 수행한다. 세 경로가 공유하는 계약은 `skills/research-orchestrator/references/axis-contracts.md`. Claude named-agent quick / deep 경로 동작은 무변경. **경계 — `/deep-research` 와 분리**: code-scout 는 code / ML / docs / papers 도메인 전용. 정책 / 시장 / 역사 / 인물 등 일반 토픽은 sibling `/deep-research` 직접 호출 (7-phase + adversarial verify + state machine). orchestrator 가 위임하지 않음 — 의도된 boundary. @@ -234,7 +233,7 @@ Agent(subagent_type="code-scout:paper-scout", prompt="query=sparse autoencoder interpretability\nworkspace_dir=$WORKSPACE\nartifact_id=05_paper") ``` -> 위 `Agent(subagent_type="code-scout:*-scout")` 직접 호출은 **Claude Code 전용**이다. Codex 에서는 이 named agent 들이 등록되지 않으므로 `Skill("code-scout:research-orchestrator")` 로 진입하면 orchestrator 가 generic subagent / 순차 fallback 으로 같은 축을 실행한다 (Hermes 는 `code-scout` 가 아직 Hermes-eligible 이 아니라 미로드 — 위 "런타임 이식성" 참조). +> 위 `Agent(subagent_type="code-scout:*-scout")` 직접 호출은 **Claude Code 전용**이다. Codex 에서는 이 named agent 들이 등록되지 않으므로 `Skill("code-scout:research-orchestrator")` 로 진입하면 orchestrator 가 generic subagent / 순차 fallback 으로 같은 축을 실행한다 (Hermes 도 같은 경로를 타되 도구명이 `delegate_task` 다 — 위 "런타임 이식성" 참조). **Workspace 준비 (위 직접 호출 전에 실제 셸에서):** ```bash @@ -689,47 +688,36 @@ git config core.hooksPath .githooks 활성화하면 매 커밋 전에 `node scripts/sync-codex-manifests.mjs --check` 가 돌아 drift / 길이 위반을 차단합니다. 훅을 건너뛴 기여자도 PR 시 `.github/workflows/validate-codex.yml` 이 동일 명령으로 잡습니다. -### Hermes Agent (shared source) +### 스킬 설치 (Hermes Agent / Codex) -Hermes Agent 도 동일한 `plugins//` 트리를 네이티브로 읽습니다. 어댑터(`plugin.yaml` + `__init__.py`)는 `scripts/sync-hermes-manifests.mjs` 가 `.claude-plugin/marketplace.json` 으로부터 생성: +Hermes Agent 도 동일한 `plugins//` 트리를 읽습니다. 다만 **생성 산출물이 없습니다** — `npx skills`([vercel-labs/skills](https://github.com/vercel-labs/skills))가 `.claude-plugin/marketplace.json` 을 직접 파싱해 `plugins//skills/*/SKILL.md` 를 찾아 설치합니다. `scripts/install-skills.mjs` 는 그 위에 플러그인 그룹 선택기와 Hermes 프로필 타겟팅만 얹은 zero-dep 래퍼입니다: ```bash -# 어댑터 생성 / 재생성 (eligible 플러그인의 version·description 변경 시) -node scripts/sync-hermes-manifests.mjs +# 대화형 — 스킬 선택 → 타겟(hermes-agent / codex) → scope(global / project) → Hermes 프로필 +node scripts/install-skills.mjs -# PR drift 가드 — CI(validate-codex.yml) + .githooks/pre-commit 에서 실행 -node scripts/sync-hermes-manifests.mjs --check +# 검색 로직 self-check (TTY·네트워크 불필요) +node scripts/install-skills.mjs --selftest -# Hermes 에 플러그인 단위 설치 (plugin.yaml 어댑터 필요) -hermes plugins install YoungjaeDev/my-claude-plugins/plugins/github-dev --enable -hermes gateway restart # 메시징 게이트웨이 사용 시 +# npx skills 직접 사용 +npx skills add YoungjaeDev/my-claude-plugins -a hermes-agent -s cr-fix -g +npx skills add . -l # 이 저장소가 노출하는 스킬 목록 ``` -어댑터 필드는 marketplace 엔트리에서 파생되고(`plugin.yaml` name/version/description, `__init__.py` 는 SKILL.md 를 `:` 로 등록하는 제네릭 엔트리포인트 — 플러그인별 로직 없음), 대상은 `HERMES_ELIGIBLE` allowlist (이번 라운드 7개: `github-dev`, `interview`, `anti-slop-design`, `tcrei-prompt`, `ppt-yeong-style`, `ml-toolkit`, `brightdata-guide`) 입니다. allowlist 에 이름을 추가하면 커버리지가 확장됩니다. `--check` 가 어댑터 drift + orphan 어댑터를 잡습니다. 공유 skill 본문은 Claude/Codex 도구 용어를 Hermes 도구로 매핑하는 호환 표를 포함합니다. - -플러그인 스킬은 opt-in 이라 enable 후 `skill_view(":")` 로 명시 로드합니다 (`--enable` 후 새 Hermes 세션 시작). +커버리지는 allowlist 가 아니라 "스킬을 가진 플러그인 전부" 입니다 (현재 23 플러그인 / 52 스킬). 설치 경로는 Hermes `~/.hermes/skills/`, Codex `~/.codex/skills/` 이고, 두 런타임 모두 그 디렉터리를 자동 인덱싱합니다 — Hermes 에서는 `skills_list()` 에 노출되며 슬래시 커맨드로도 잡힙니다. 설치 메커니즘(symlink/copy)·충돌·lockfile 은 `npx skills` 에 위임하고, Hermes 프로필은 `HERMES_HOME` env 로 타겟팅합니다. -**설치 두 경로:** -- **플러그인 단위** (`hermes plugins install .../plugins/` — 위 `plugin.yaml` 어댑터 필요, 이번 PR 이 5개 추가). 플러그인 전체를 Hermes 에 등록. -- **스킬 단위** (`node scripts/install-skills.mjs` → `npx skills` — 어댑터와 무관, 어댑터 없는 플러그인도 가능). 개별 skill 만 설치. +스킬 이름은 평평하게 설치됩니다 (`github-dev:cr-fix` 가 아니라 `cr-fix`). 이 저장소의 52개는 서로 유니크하며 `--selftest` 가 이를 강제하지만, 다른 출처의 스킬과 이름이 겹치지 않는지는 확인이 필요합니다. -### 스킬을 Hermes / Codex 에 설치 (스킬 단위) - -이 마켓플레이스의 skill 을 **스킬 단위**로 Hermes Agent 와 Codex 에 설치하는 대화형 도구 (위 `plugin.yaml` 어댑터와 무관 — 어댑터 없는 플러그인도 설치 가능). `npx skills`(vercel-labs/skills) 를 래핑하며 Node builtin 만 사용(zero-dep): - -```bash -node scripts/install-skills.mjs -``` +> 이전에는 Hermes 용 네이티브 어댑터(`plugin.yaml` + `__init__.py`)를 `scripts/sync-hermes-manifests.mjs` 로 생성했습니다. 7 플러그인 / 20 스킬만 덮으면서 버전 범프마다 재생성과 drift 가드를 요구했고 로드에 `skill_view()` 명시 호출이 필요해, #166 에서 제거하고 `npx skills` 경로로 일원화했습니다. -플러그인 그룹 단위로 skill 을 고른 뒤 타겟(`hermes-agent` / `codex`)·scope(global `~/` / project `./`)·Hermes profile 을 선택하면 `npx skills add` 로 설치합니다. 설치 메커니즘(symlink/copy)·충돌·lockfile 은 `npx skills` 에 위임하고, Hermes profile 은 `HERMES_HOME` env 로 타겟팅합니다. +공유 skill 본문은 Claude/Codex 도구 용어를 Hermes 도구로 매핑하는 호환 표를 포함합니다. ### CI 가드가 지키는 것 (curation / security) -shared-source 배선은 5개 가드가 매 PR 과 매 커밋(`.githooks/pre-commit`)에서 함께 검증합니다 — 한 런타임에만 보이는 변경이 다른 도구체인에 조용히 깨진 채로 나가는 것을 막는 것이 목적입니다: +shared-source 배선은 4개 가드가 매 PR 과 매 커밋(`.githooks/pre-commit`)에서 함께 검증합니다 — 한 런타임에만 보이는 변경이 다른 도구체인에 조용히 깨진 채로 나가는 것을 막는 것이 목적입니다: - `sync-codex-manifests.mjs --check` — Codex 매니페스트 drift + skill `description` 1024자 초과(Codex silent skip) + 번들 hook 디스크립터 shape·참조 스크립트 존재·orphan. -- `sync-hermes-manifests.mjs --check` — Hermes 어댑터 drift + orphan. -- `check-doc-consistency.mjs` — 플러그인 트리·표·카운트(총 24 / Codex-eligible 23 / Hermes 7)가 `manifest-eligibility.mjs` SoT 와 일치. +- `check-doc-consistency.mjs` — 플러그인 트리·표·카운트(총 24 / Codex-eligible 23)가 `manifest-eligibility.mjs` SoT 와 일치. - `check-skill-tool-portability.mjs --check` — 공유 스킬 본문의 `AskUserQuestion` 사용이 파일럿 표준 매핑 또는 baseline 에 등록됐는지(미등록 크로스런타임 상호작용 경로 차단). - `check-skill-prose.mjs` — 500줄 초과·깊은 참조 경로에 대한 정보성 경고(비차단, 항상 exit 0). @@ -737,7 +725,7 @@ drift·길이·shape 위반은 **차단**(exit 1)이고, prose 경고는 측정 ### 머신 로컬 운영 갱신 (PR 밖 오퍼레이터 체크리스트) -Codex 의 UserPromptSubmit 훅과 Hermes 스킬은 이제 **번들 디스크립터/어댑터**로 배포되므로 marketplace 업데이트가 정본입니다. 다만 예전에 손으로 설치한 복사본(수동 `~/.codex/hooks/prompt_inject.sh`, 스킬 단위로 깐 `~/.agents/skills/<...>`)을 쓰던 머신은 그 복사본이 stale 해질 수 있습니다. 아래는 리포지토리 상태를 바꾸지 않는 **머신 로컬 작업**이라 PR 에 포함되지 않으며, marketplace 업데이트 후 한 번 실행합니다: +Codex 의 UserPromptSubmit 훅은 이제 **번들 디스크립터**로 배포되므로 marketplace 업데이트가 정본입니다. 다만 예전에 손으로 설치한 복사본(수동 `~/.codex/hooks/prompt_inject.sh`)이나 `npx skills` 로 깐 스킬 사본(`~/.agents/skills/<...>`)을 쓰던 머신은 그 복사본이 stale 해질 수 있습니다. 아래는 리포지토리 상태를 바꾸지 않는 **머신 로컬 작업**이라 PR 에 포함되지 않으며, marketplace 업데이트 후 한 번 실행합니다: ```bash # 1) marketplace 캐시 갱신 (위 "플러그인 업데이트" 절차) @@ -747,11 +735,11 @@ rm -rf ~/.claude/plugins/cache/my-claude-plugins/ codex plugin marketplace add ~/.claude/plugins/marketplaces/my-claude-plugins codex plugin add core-config@my-claude-plugins # 이후 /hooks 로 trust 재승인 -# 3) Hermes: 스킬 단위 설치본 갱신 -node scripts/install-skills.mjs # 또는 hermes plugins install ... --enable +# 3) Hermes / Codex: 스킬 설치본 갱신 +npx skills update -g # 또는 node scripts/install-skills.mjs 로 재설치 ``` -번들 디스크립터/어댑터를 쓰는 신규 설치는 marketplace 업데이트만으로 최신이 됩니다 — 이 체크리스트는 레거시 수동 복사본을 쓰는 머신에만 필요합니다. +번들 디스크립터를 쓰는 신규 설치는 marketplace 업데이트만으로 최신이 됩니다 — 이 체크리스트는 레거시 수동 복사본이나 별도 스킬 설치본을 쓰는 머신에만 필요합니다. ## 요구사항 @@ -761,9 +749,9 @@ node scripts/install-skills.mjs # 또는 hermes plugins install | `gh` | GitHub 플러그인 | github-dev | | `uv` | Python MCP 서버 | core-config | | `ruff` | Python 포매팅 | core-config | -| Node 18+ | Codex/Hermes 매니페스트 생성기 런타임 | `scripts/sync-{codex,hermes}-manifests.mjs` | +| Node 18+ | Codex 매니페스트 생성기 + 스킬 설치기 런타임 | `scripts/sync-codex-manifests.mjs`, `scripts/install-skills.mjs` | | Codex CLI 0.135+ | shared-source 네이티브 로드 (`.codex-plugin/plugin.json`) | Codex 사용자 | -| Hermes Agent | shared-source 네이티브 로드 (`plugin.yaml` + `__init__.py`) | Hermes 사용자 | +| Hermes Agent | `npx skills` 로 `~/.hermes/skills/` 에 스킬 설치 | Hermes 사용자 | ## 프로젝트 구조 diff --git a/code_review.md b/code_review.md index 1390fc24..bf4dfc85 100644 --- a/code_review.md +++ b/code_review.md @@ -33,7 +33,7 @@ - 새 dependency, GitHub Actions, CI/CD 권한 변경 — 최소 권한, lockfile, supply-chain. ## Domain-specific (Claude Code plugin marketplace) -- 새 플러그인 추가 / 제거 PR 은 `AGENTS.md`의 플러그인 수, `README.md` badge + 표 + detail + 트리, `AGENTS.md` / `README.md` 의 Codex-eligible count (total − 2 excluded: core-config·codex-image), `marketplace.json` entry + `metadata.version`, `.claude/settings.json` 의 `plugins.local` entry, 그리고 `node scripts/sync-codex-manifests.mjs` + (Hermes-eligible 이면) `node scripts/sync-hermes-manifests.mjs` 재실행 — 동시 업데이트 필수. Codex-eligible count 는 version 파일도 `--check` 도 못 잡으니 수동 확인. +- 새 플러그인 추가 / 제거 PR 은 `AGENTS.md`의 플러그인 수, `README.md` badge + 표 + detail + 트리, `AGENTS.md` / `README.md` 의 Codex-eligible count (total − 2 excluded: core-config·codex-image), `marketplace.json` entry + `metadata.version`, `.claude/settings.json` 의 `plugins.local` entry, 그리고 `node scripts/sync-codex-manifests.mjs` 재실행 — 동시 업데이트 필수 (Hermes 는 생성 산출물이 없어 재실행 대상이 아니다). Codex-eligible count 는 version 파일도 `--check` 도 못 잡으니 수동 확인. - 기존 플러그인에 **skill 추가** PR 은 plugin 수를 바꾸지 않지만 문서 동기화가 필요하다 — 해당 플러그인의 `plugins//CLAUDE.md` skill 목록, 그리고 version bump 이 `description` 도 바꿨다면 `AGENTS.md` / `README.md` 의 한 줄 설명. 매니페스트 재생성 + `metadata.version` bump 은 그대로 적용. - **플러그인 제거 PR 추가 주의** — (a) `git grep -niE ''` 로 레포 전체(다른 플러그인 skill 본문·`docs/` 포함, 과거 `.claude/spec/*` 제외)에서 live 참조를 훑어 제거. count 파일만으론 부족하다 (예: `code-scout` 의 `agent-routing.md` 라우팅). 살아남은 참조는 존재하지 않는 플러그인으로 사용자를 안내한다. (b) 삭제된 플러그인이 생성하던 tracked 산출물(예: `workflow-viz` → `docs/architecture/*`)은 orphaned 이니 같은 변경에서 제거. (c) 플러그인 제거는 `metadata.version` **MINOR** bump (MAJOR 아님 — metadata.version 은 per-release counter, semver-breaking 규칙은 per-plugin 스코프; `midjourney` 삭제 선례가 MINOR). 리뷰어의 "breaking→MAJOR" 지적보다 이 컨벤션 우선. - Codex 매니페스트 (`plugins/*/.codex-plugin/plugin.json`, `.agents/plugins/marketplace.json`) 가 `--check` 통과해야 함. 수동 편집 흔적 검토. diff --git a/scripts/install-skills.mjs b/scripts/install-skills.mjs index 5d7f3a88..1a80bb17 100644 --- a/scripts/install-skills.mjs +++ b/scripts/install-skills.mjs @@ -2,6 +2,13 @@ // Skills installer TUI — pick this marketplace's skills and install them to // Hermes Agent / Codex by wrapping `npx skills` (vercel-labs/skills). // +// This is the ONLY delivery path for Hermes: since #166 there is no generated +// Hermes adapter, so `npx skills` reading .claude-plugin/marketplace.json in place +// is what puts skills in ~/.hermes/skills/ (where Hermes indexes them into +// skills_list() and exposes them as slash commands). Codex additionally has the +// generated .codex-plugin manifests, which carry hooks and MCP servers that skills +// alone cannot. +// // Zero-dep: Node builtins only. Run directly: // node scripts/install-skills.mjs interactive install // node scripts/install-skills.mjs --selftest pure-logic self-check (no TTY/network) @@ -250,7 +257,7 @@ async function interactive() { out('\n=== summary ===\n'); for (const r of results) out(` ${r.ok ? 'OK ' : 'FAIL'} ${r.agent}${r.ok ? '' : ` (exit ${r.code})`}\n`); out(` ${skills.length} skill(s): ${skills.join(', ')}\n`); - out(` lockfile: global → ~/.agents/skills-lock.json · project → ./skills-lock.json (managed by npx skills)\n`); + out(` lockfile: global → ~/.agents/.skill-lock.json · project → ./skills-lock.json (managed by npx skills)\n`); if (results.some((r) => !r.ok)) process.exitCode = 1; } From e4296aa66c3d1618e584cf424100a76f808baab8 Mon Sep 17 00:00:00 2001 From: YoungjaeDev Date: Mon, 27 Jul 2026 10:04:36 +0900 Subject: [PATCH 04/12] docs: correct install-mechanism claim for hermes-agent An end-to-end install run (npx skills v1.5.20, 2026-07-27) put a real copied directory at ~/.hermes/skills/cr-fix, not a symlink into ~/.agents/skills/ the way the claude-code target does. The section claimed symlinking outright, so note that -a hermes-agent copies and that source-tree edits therefore need a reinstall or npx skills update to reach the Hermes copy. Refs #166 --- AGENTS.md | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/AGENTS.md b/AGENTS.md index 88f352e1..294570e7 100644 --- a/AGENTS.md +++ b/AGENTS.md @@ -241,7 +241,8 @@ node scripts/install-skills.mjs --selftest # 검색 로직 self-check (TTY· - Hermes Agent 도 **동일한** `plugins//` 트리를 직접 읽습니다. 다만 **생성 산출물이 없습니다** — `npx skills`(vercel-labs/skills)가 `.claude-plugin/marketplace.json` 을 직접 파싱해 `plugins//skills/*/SKILL.md` 를 찾아 `~/.hermes/skills/` 로 설치합니다. `scripts/install-skills.mjs` 는 그 위에 플러그인 그룹 선택기와 `HERMES_HOME` 프로필 타겟팅만 얹은 zero-dep 래퍼입니다. - 커버리지는 allowlist 가 아니라 "스킬을 가진 플러그인 전부"입니다 (현재 23 플러그인 / 52 스킬). 유지할 명단이 없으므로 플러그인을 추가해도 Hermes 쪽에 할 일이 없습니다. - `~/.hermes/skills/` 는 Hermes 의 skill SoT 이고, 여기 설치된 스킬은 `skills_list()` 에 자동 노출되며 슬래시 커맨드가 됩니다 (공식 docs). 즉 `description` 기반 표면화가 Claude Code·Codex 와 동일하게 동작합니다. -- 설치는 심볼릭 링크가 기본이라 `~/.agents/skills/` 하나를 정본으로 두고 각 에이전트 디렉터리가 그걸 가리킵니다. 이름은 평평합니다 — `github-dev:cr-fix` 가 아니라 `cr-fix` 이므로 외부 스킬과 이름이 겹치지 않게 유지하세요. +- 설치 방식은 `npx skills` 가 정합니다 — 문서상 기본은 심볼릭 링크(`~/.agents/skills/` 를 정본으로 두고 각 에이전트 디렉터리가 가리킴)이고 `--copy` 또는 링크 불가 시 복사입니다. 다만 `-a hermes-agent` 는 실측(2026-07-27, skills v1.5.20)에서 링크가 아니라 **복사**로 설치됐으므로, 소스 트리를 고쳐도 Hermes 설치본에 자동 반영되지 않습니다 — 재설치하거나 `npx skills update` 를 도세요. +- 이름은 평평하게 설치됩니다 — `github-dev:cr-fix` 가 아니라 `cr-fix` 이므로 외부 스킬과 이름이 겹치지 않게 유지하세요. - 이전의 네이티브 어댑터(`plugin.yaml` + `__init__.py`)와 `scripts/sync-hermes-manifests.mjs` 생성기는 #166 에서 제거했습니다. 어댑터는 7 플러그인 / 20 스킬만 덮으면서 버전 범프마다 재생성과 `--check` 를 요구했고, 로드에 `skill_view(":")` 명시 호출이 필요했습니다. - 공유 skill 본문은 3런타임 포터블이어야 합니다. Claude/Codex 는 도구명이 동일하므로, 본문에 Claude/Codex 도구 용어를 Hermes 도구로 매핑하는 호환 표(`Bash`→`terminal`, `Read`→`read_file`, `Edit`→`patch`, `AskUserQuestion`→`clarify`, `Task`→`delegate_task`, `Skill`→`skill_view`, 이미지 생성→`image_generate`, `NotebookEdit`→Hermes Jupyter Live Kernel / `write_file`·`patch` 등)를 둡니다. 새 skill 추가/도구 사용 변경 시 이 표를 점검하세요. 신규·편집 skill 은 이 표를 본문마다 다시 타이핑하는 대신 번들 `references/-tools.md` 로 중앙화하고 본문이 그것을 가리키는 형태를 우선합니다 — 점진 이관이므로 이미 그 본문의 도구 사용을 편집 중일 때만 채택하고, 표를 옮기려고 기존 본문을 새로 쓰지는 않습니다 (surgical-diff). - 번들 `scripts/` 를 호출하는 skill 본문은 `${CLAUDE_PLUGIN_ROOT}` 를 그대로 쓰지 마세요 — Codex 0.135 는 이 변수를 export 하지 않아 첫 단계에서 실패합니다. 크로스 런타임 `PLUGIN_ROOT` resolver 블록(`CLAUDE_PLUGIN_ROOT` → 소스트리 `plugins/` → Codex 캐시 탐색)을 본문에 포함하세요 (레퍼런스 구현: project-init, mem0-ops). From 7866b2e0f3c42178664e64c5c271cdaff9fa3859 Mon Sep 17 00:00:00 2001 From: YoungjaeDev Date: Mon, 27 Jul 2026 10:08:01 +0900 Subject: [PATCH 05/12] docs(wiki): supersede hermes-plugin-adapter with skills-install-wrapper MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Diff-logged first (log.md), then applied. hermes-plugin-adapter goes status: stale with a Superseded-by back-pointer rather than being deleted — its measured findings outlive the mechanism: the register_skill signature settled against upstream source, the git-pull-only update model, and the generated-but-never-executed blind spot where CI tested only byte-drift, so a behavioral break would have passed every guard. That last one is the structural case for the retirement. skills-install-wrapper takes over as the Hermes hub: sole delivery path, 47->52 skills, the flat-namespace hazard against third-party skills, the resolved layout divergence, and two newly measured facts — Hermes indexes ~/.hermes/skills/ passively (skills_list + slash commands, per upstream docs), retiring the skill_view() opt-in contract, and -a hermes-agent copies rather than symlinks. Also retargets two See-also pointers off the now-stale page and corrects a pre-existing sources off-by-one on it (5 declared, 6 present). Refs #166 --- .llmwiki/wiki/index.md | 4 +- .llmwiki/wiki/log.md | 12 +++++ .../agents-md-verbatim-no-import.md | 2 +- .../wiki/plugin-ops/hermes-plugin-adapter.md | 48 +++++++++++------- .../shared-source-codex-manifests.md | 2 +- .../wiki/plugin-ops/skills-install-wrapper.md | 50 +++++++++++++++---- 6 files changed, 88 insertions(+), 30 deletions(-) diff --git a/.llmwiki/wiki/index.md b/.llmwiki/wiki/index.md index 17bc4dec..21ac55ff 100644 --- a/.llmwiki/wiki/index.md +++ b/.llmwiki/wiki/index.md @@ -81,8 +81,8 @@ Operational lore for the plugin system itself — cache, loading, version resolu - [prompt-inject Korean-persistence](plugin-ops/prompt-inject-korean-persistence.md) — the per-prompt block must explicitly name internal workflow / subagent / English-skill paths (ultracode, deep-research) as NOT a "별도 지시"; otherwise a downstream English skill body reads as the override the bare Korean-default line defers to, and the final user answer regresses to English. - [Skill authoring: source-ground then coverage-audit](plugin-ops/skill-authoring-source-grounded-then-audit.md) — build a reference/guidance skill from source-grounded OSS investigation (read repos, not summaries — counts drift), then audit the distillation on the documented-vs-enforced axis (a pattern in the reference taxonomy is not the same as one in the binary ship-gate); or harvest from your own dogfooded build and interview-gate generic vs project-specific before merging into the shared plugin; or, when *adopting* from an external skill library, triage gap-fill / reflect / skip and diff the posture and defaults, not just the rule list (a famous skill can overlap ~90% of your rules yet win on the opposite default posture) — with a fourth lane, diverge-fork, for wanting the capability in a direction upstream would never take, which zeroes update latency rather than speeding it, so attempt upstream first. - [Skill-on-skill engine layering](plugin-ops/skill-engine-layering.md) — a thin writing/convention layer on another skill's engine references it by bare name (no vendor) + graceful-degrades optional deps, but a HARD engine in a separate marketplace is NOT a degrade target: a fresh install of the layer alone has no engine and blocks the build, so stop-before-build + guide install (prerequisite-stop). Invisible in the author's env where the engine is already installed. "Copy" also covers reproducing the engine's internal API in prose (script names, ports, step ordinals, enum values) — reference lever *concepts* + stable contract keys, engine SKILL.md is SOT. Re-audit periodically, not just at authoring time — the engine evolves independently, so a full re-read of its actual current file tree can surface missing lever coverage or an inaccurate mechanism claim that a re-read of the layer's own prose would miss. Declared mirrors (references detail file / injection payload / README section) fan out in the same edit — a review cycle can be 4/4 mirror-sync gaps, and drift runs in reverse too (mirror-only rules). -- [Skills install wrapper (npx skills)](plugin-ops/skills-install-wrapper.md) — `scripts/install-skills.mjs` installs marketplace skills into Hermes/Codex by wrapping `npx skills`: source arg `.` (reads marketplace.json, groups by plugin), selection via *repeated* `-s ` (comma fails), codex global lands in `~/.agents/skills/`, Hermes profile targeted by injecting `HERMES_HOME` (one spawn per agent/profile). EXCLUDED is manifest-eligibility-scoped, not install-scoped — the installer filters by skill count, so codex-image stays installable to Codex. -- [Hermes native plugin adapter](plugin-ops/hermes-plugin-adapter.md) — a third runtime (Hermes Agent) reads the same `plugins//` tree via `plugin.yaml` + `__init__.py` adapters **generated by `scripts/sync-hermes-manifests.mjs`** from marketplace.json (PR #84; github-dev pilot PR #83 absorbed into the generator, coverage now 7 HERMES_ELIGIBLE plugins — the generator allowlist is SoT), installed with `hermes plugins install //plugins/ --enable` (bare install warns without the adapter). `plugin.yaml` keeps all 5 marketplace-derived fields (name/version/description/author/kind:standalone) — CodeRabbit's minimal-manifest push was declined (drift moot post-generator, kind load-bearing). Hermes plugin skills are opt-in — load via `skill_view("plugin:skill")`, never bare invocation; restart after `--enable`. Bodies carry a Claude/Codex→Hermes tool-name map (Bash→terminal, Read/Write→read_file/write_file, Edit→patch, Glob/Grep→search_files, AskUserQuestion→clarify, Task→delegate_task, Monitor→process, Skill→skill_view, image gen→image_generate, WebFetch/WebSearch→web_extract/browser_*, NotebookEdit→Jupyter Live Kernel) + a 3-branch `SKILL_DIR` (source → `$HERMES_HOME` → `~/.hermes`; the `${HERMES_SKILL_DIR}` var was tried in PR #84 and reverted — undocumented/unset on install). `--check` guards adapter drift + orphans in CI + pre-commit. Update model: `hermes plugins update` is a plain `git pull` (errors on non-git installs; `plugin.yaml version` unread by Hermes) and the adapters are generated-but-never-executed — only byte-drift is tested. Distinct from skills-install-wrapper (npx skill-level install) and shared-source (Codex manifest gen). Version sync → `.claude/rules/plugin-versioning.md`. +- [Skills install wrapper (npx skills)](plugin-ops/skills-install-wrapper.md) — hub for Hermes delivery: since #166 `npx skills` (wrapped by `scripts/install-skills.mjs`) is the **only** Hermes path, covering all 23 skill-bearing plugins / 52 skills with no generated artifact and no allowlist. Source arg `.` reads marketplace.json and groups by plugin; selection is *repeated* `-s ` (comma fails); names install **flat** (`cr-fix`, not `github-dev:cr-fix`) so collisions with third-party skills are the caller's problem. `~/.hermes/skills/` is Hermes' skill SoT and is indexed passively — `skills_list()` + slash commands — which retires the adapter era's explicit `skill_view()` load contract. `-a hermes-agent` COPIES rather than symlinks (measured), so source edits need a reinstall. Codex keeps its manifest generator alongside, because skills-only installs drop hooks (core-config 4, llm-wiki 6) and MCP servers (paper-search-tools). EXCLUDED is manifest-eligibility-scoped, not install-scoped. Supersedes hermes-plugin-adapter. +- [Hermes native plugin adapter (RETIRED)](plugin-ops/hermes-plugin-adapter.md) — `status: stale`, superseded by skills-install-wrapper. Records the mechanism removed in #166: `plugin.yaml` + `__init__.py` adapters generated by `scripts/sync-hermes-manifests.mjs` for a 7-plugin `HERMES_ELIGIBLE` allowlist, installed via `hermes plugins install .../plugins/ --enable`, skills reachable only through `skill_view("plugin:skill")`. Kept for the findings that outlive it: `register_skill(self, name, path, description="")` settled by upstream source read (docs lagged), `hermes plugins update` is a plain `git pull` with no version compare, and the adapters were **generated but never executed** — CI tested byte-drift only, so any behavioral break would have passed every guard. That last one is the structural argument for the retirement, not a footnote to it. - [codex-image delegated-CLI bridge design](plugin-ops/codex-image-bridge-design.md) — a Claude skill that shells out to `codex exec` for image gen: inherit the sub-CLI's default model (omit `-m`, auto-tracks latest, no pin maintenance; `--model` opt-in only); least-privilege `-s workspace-write` default over the `--dangerously-bypass-approvals-and-sandbox` bypass (codex 0.142 has no `--yolo` for `codex exec`); validate passthrough at the shell trust boundary (`--model` vs `^[A-Za-z0-9._:-]+$`, enum `--reasoning`/`--sandbox`) — trailing `-` in a char class is literal (a Codex P2 misread, refuted). `disable-model-invocation` retired in 1.2.0: hiding the skill hid the recipe without preventing autonomous cost (140k-token `codex exec` re-derivation dogfood) — the cost gate moved in-body (explicit grounding + ask-when-ambiguous). `-i, --image` is a generic attach flag with no edit-vs-reference semantics of its own (1.3.0 `--ref` addition relies on unverified prompt-text framing); the real injection defense is quoting/array-exec, not a character denylist — a denylist including `\`/`:` broke Windows paths entirely (cr-fix PR #92 dogfood, 5 findings incl. one P0). A second injection surface — the prompt-body heredoc — needs a per-invocation random LITERAL delimiter (a `<<"$DELIM"` variable form is NOT parameter-expanded, so it gives zero randomization; live canary repro, #130). - [mem0 v2 list API contract quirks](plugin-ops/mem0-rest-list-contract.md) — 라이브 검증된 계약 quirk 3종: entity 와일드카드는 non-null만 매칭(전체 앱 = bare app_id 필터), list는 만료 메모리 기본 은닉(`show_expired: true` 필수), `HTTPResponse.length`는 chunked에서 None(본문 직접 읽기). 삭제·백업 SSOT가 이걸 놓치면 "정리 완료"가 거짓 보고가 된다. - [mem0 hook latency budget](plugin-ops/mem0-hook-latency-budget.md) — mem0 플러그인 UserPromptSubmit 훅의 8s 예산은 worst-case(resume 2연속 검색 ~10s + rerank 기본 on)를 못 버틴다; 레버는 캐시 파일이 아니라 사용자 소유 settings.json env(`MEM0_RERANK=off`)에 둔다. 플러그인의 rerank-on 기본값은 mem0 공식 Best Practice와 반대. 단 env-lever는 플래그별로 다름 — `auto_save`는 `_identity.sh`가 `~/.mem0/settings.json` 값으로 env를 매 훅 덮어써서 그 파일이 SOT. diff --git a/.llmwiki/wiki/log.md b/.llmwiki/wiki/log.md index efd164b0..ca2022ed 100644 --- a/.llmwiki/wiki/log.md +++ b/.llmwiki/wiki/log.md @@ -6,6 +6,18 @@ Every `/ingest-finding` run and every `/github-dev:post-merge` run that executes --- +## 2026-07-27 — #166: Hermes plugin adapter retired, npx skills is the sole Hermes path (ingest-finding) + +Diff log written before applying the page edits (git-revertible). PR #166 deletes `scripts/sync-hermes-manifests.mjs`, `scripts/mock-load-hermes.py`, and the 7 generated `plugin.yaml` + `__init__.py` adapter pairs, plus the `HERMES_ELIGIBLE` allowlist and both Hermes CI/pre-commit guards. Hermes now gets skills only through `npx skills` (`scripts/install-skills.mjs`). Supersede, not overwrite — the adapter page keeps real historical value (the `register_skill` signature settlement, the git-pull-only update model, the generated-but-never-executed blind spot). + +- plugin-ops/hermes-plugin-adapter.md: status active→stale, add `> Superseded-by: [[skills-install-wrapper]]` + a retirement note at the top; body kept intact as the record of a retired mechanism. last_verified 2026-07-27, sources 5→7 (adds the #166 entry and corrects a pre-existing off-by-one — the page already carried 6 `## Sources` bullets under `sources: 5`). +- plugin-ops/skills-install-wrapper.md: add `> Supersedes: [[hermes-plugin-adapter]]`; record that this is now the only Hermes delivery path, that `~/.hermes/skills/` is Hermes' skill SoT with passive `skills_list()` + slash-command exposure (retiring the `skill_view()` opt-in load contract), that `-a hermes-agent` installs by COPY not symlink (measured), and that the layout-divergence caveat resolves to the single flat layout. Skill count 47→52. last_verified 2026-07-27, sources 2→4. +- plugin-ops/shared-source-codex-manifests.md: See-also target retargeted to [[skills-install-wrapper]] (the live Hermes page) — the stale adapter page is no longer the right entry point. +- plugin-ops/agents-md-verbatim-no-import.md: same See-also retarget. +- index.md: rewrote both plugin-ops hooks (skills-install-wrapper now carries the Hermes contract; hermes-plugin-adapter marked retired). + +No insight graduation: the finding is one PR old, so it fails the "recurs across 2+ independent sessions" bar. + ## 2026-07-24 — post-merge #164: brightdata CLI preflight quirks + rg hidden-path parity blindspot (post-merge) Diff log written before applying the page edits (git-revertible). Merge SHA `b5d288f` — search-stack migration (firecrawl→brightdata + slidev plugin removal). Config integration (Step 6): none new — plugin counts / version bumps / the code-scout brightdata tier landed in the merge itself, and the plugin-removal-is-MINOR rule already lives in `.claude/rules/plugin-versioning.md`; the durable lore is provider-quirk + a verification debugging-story, routed here. diff --git a/.llmwiki/wiki/plugin-ops/agents-md-verbatim-no-import.md b/.llmwiki/wiki/plugin-ops/agents-md-verbatim-no-import.md index 6ef2b1f9..b780aff1 100644 --- a/.llmwiki/wiki/plugin-ops/agents-md-verbatim-no-import.md +++ b/.llmwiki/wiki/plugin-ops/agents-md-verbatim-no-import.md @@ -56,7 +56,7 @@ The rule used to read "Codex cannot `@import` `.claude/rules/`", which implies a > Refines: [[shared-source-codex-manifests]] > See-also: [[insight-layer-via-hook]] -> See-also: [[hermes-plugin-adapter]] +> See-also: [[skills-install-wrapper]] > Promoted-to: [[agents-md-no-import]] > Evidence: .claude/rules/dual-integration.md > Evidence: plugins/project-init/references/codex-review-discovery.md diff --git a/.llmwiki/wiki/plugin-ops/hermes-plugin-adapter.md b/.llmwiki/wiki/plugin-ops/hermes-plugin-adapter.md index 021494c6..3cbc2d0a 100644 --- a/.llmwiki/wiki/plugin-ops/hermes-plugin-adapter.md +++ b/.llmwiki/wiki/plugin-ops/hermes-plugin-adapter.md @@ -1,28 +1,41 @@ --- id: hermes-plugin-adapter aliases: [hermes-adapter, plugin-yaml, hermes-native-plugin, skill-view-optin, hermes-third-runtime, hermes-plugins-update] -last_verified: 2026-07-12 -status: active +last_verified: 2026-07-27 +status: stale volatility: stable -sources: 5 +sources: 7 --- -# Hermes native plugin adapter (third runtime) +# Hermes native plugin adapter (third runtime, RETIRED) + +> **Retired in PR #166 (2026-07-27).** This mechanism no longer exists. Hermes now +> receives skills only through `npx skills` — see the Superseded-by link below. The +> page is kept because its measured findings outlive the mechanism: the +> `register_skill` signature settlement, the git-pull-only update model, and the +> generated-but-never-executed blind spot that let a behavioral break pass every +> guard. Read it as a record, not as instructions. +> +> **Why it went**: the adapter covered 7 plugins / 20 skills while `npx skills` +> covers 23 / 52, it demanded regeneration plus a `--check` drift guard on every +> version bump, and it required an explicit `skill_view()` load where +> `~/.hermes/skills/` is passively indexed. The generated-but-never-executed +> problem below was structural, not incidental — a delivery path whose only test is +> byte-drift cannot detect that it stopped working. + +> Superseded-by: [[skills-install-wrapper]] +> See-also: [[shared-source-codex-manifests]] -The shared-source `plugins//` tree is read by a **third** runtime, Hermes +The shared-source `plugins//` tree was read by a **third** runtime, Hermes Agent — alongside Claude Code (native) and Codex 0.135 (generated -`.codex-plugin/plugin.json`). Hermes consumes the same tree in place via native -adapters (`plugin.yaml` + `__init__.py`) that, since PR #84, are **generated by -`scripts/sync-hermes-manifests.mjs`** from `marketplace.json` — the mirror of the -Codex manifest generator, not the `npx skills` install path. `github-dev` was the -hand-written pilot (PR #83); PR #84 absorbed it into the generator and extended -coverage via a `HERMES_ELIGIBLE` allowlist — currently 7 plugins (`github-dev`, -`interview`, `anti-slop-design`, `tcrei-prompt`, `ppt-yeong-style`, `ml-toolkit`, -`brightdata-guide`). The allowlist is the SoT; this page's count goes stale on -every extension, so verify against `scripts/sync-hermes-manifests.mjs`. - -> See-also: [[shared-source-codex-manifests]] -> See-also: [[skills-install-wrapper]] +`.codex-plugin/plugin.json`). Hermes consumed the same tree in place via native +adapters (`plugin.yaml` + `__init__.py`) that, from PR #84 until #166, were +**generated by `scripts/sync-hermes-manifests.mjs`** from `marketplace.json` — the +mirror of the Codex manifest generator, not the `npx skills` install path. +`github-dev` was the hand-written pilot (PR #83); PR #84 absorbed it into the +generator and extended coverage via a `HERMES_ELIGIBLE` allowlist that ended at 7 +plugins (`github-dev`, `interview`, `anti-slop-design`, `tcrei-prompt`, +`ppt-yeong-style`, `ml-toolkit`, `brightdata-guide`). ## The adapter = two files in the plugin root @@ -138,3 +151,4 @@ fallback. Do not reintroduce `HERMES_SKILL_DIR`.) - DeepWiki (NousResearch/hermes-agent) — `register(ctx)` + `ctx.register_skill(name, path, description)` contract; plugin skills opt-in via `skill_view("plugin:skill")`. - Session 88102e17 (2026-07-10) — real-machine `hermes plugins update` output (git-pull-only update model); upstream docs re-check (subpath install undocumented, `author:` undocumented, `kind` enum); HERMES_ELIGIBLE count 6 → 7 correction. - Fleet-recon research read of upstream source (2026-07-12) — `hermes_cli/plugins.py` L1196 `register_skill(self, name, path, description="")`: settles the signature, retires the 2026-07-10 "2-arg documented" caveat (docs lag source). +- PR #166 (2026-07-27) — retires the whole adapter layer: generator, mock-load smoke test, 7 adapter pairs, `HERMES_ELIGIBLE`, and both CI/pre-commit guards deleted in favor of `npx skills`. diff --git a/.llmwiki/wiki/plugin-ops/shared-source-codex-manifests.md b/.llmwiki/wiki/plugin-ops/shared-source-codex-manifests.md index 8c32804c..bdd20e48 100644 --- a/.llmwiki/wiki/plugin-ops/shared-source-codex-manifests.md +++ b/.llmwiki/wiki/plugin-ops/shared-source-codex-manifests.md @@ -15,7 +15,7 @@ generator (`scripts/sync-codex-manifests.mjs`, ~140 LOC, zero runtime dependencies) emits Codex's required catalog files from `.claude-plugin/ marketplace.json`; both runtimes then read the same skill bodies in place. -> See-also: [[hermes-plugin-adapter]] +> See-also: [[skills-install-wrapper]] A third runtime, Hermes Agent, now consumes the same tree via a native `plugin.yaml` + `__init__.py` adapter (github-dev pilot) — "Claude + Codex" is diff --git a/.llmwiki/wiki/plugin-ops/skills-install-wrapper.md b/.llmwiki/wiki/plugin-ops/skills-install-wrapper.md index 4c1127b7..1c6c74f6 100644 --- a/.llmwiki/wiki/plugin-ops/skills-install-wrapper.md +++ b/.llmwiki/wiki/plugin-ops/skills-install-wrapper.md @@ -1,10 +1,10 @@ --- id: skills-install-wrapper aliases: [install-skills, npx-skills, skills-installer-tui, hermes-install, agents-skills-dir] -last_verified: 2026-06-24 +last_verified: 2026-07-27 status: active volatility: stable -sources: 2 +sources: 4 --- # Installing marketplace skills to Hermes / Codex (npx skills wrapper) @@ -15,6 +15,14 @@ no custom exporter. It is a dev script (outside `plugins/`, so it does not affec `sync-codex-manifests --check`) and adds only two things over the raw CLI: a plugin-grouped selector and Hermes profile targeting. +Since PR #166 this is the **only** Hermes delivery path — the generated +`plugin.yaml` + `__init__.py` adapters were retired (see the Supersedes link below). +Codex keeps its manifest generator alongside this route, because `npx skills` +carries skills *only*: core-config (4 hooks, 0 skills), llm-wiki (6 hooks) and +paper-search-tools (1 MCP server) ship payloads that no skill installer delivers. + +> Supersedes: [[hermes-plugin-adapter]] + ## The `npx skills add` contract (measured) - **Source arg = repo root `.`** — `npx skills add .` validates the local path, @@ -23,8 +31,11 @@ plugin-grouped selector and Hermes profile targeting. can install a cross-plugin selection. - **Skill selection = *repeated* `-s ` flags.** Comma is NOT a separator: `-s a,b` → `No matching skills found` (exit 1). The flag matches the skill's - frontmatter `name`, which is globally unique across this repo's 47 skills, so - `-s ` against source `.` is unambiguous. + frontmatter `name`, which is globally unique across this repo's 52 skills (23 + skill-bearing plugins, re-measured 2026-07-27), so `-s ` against source `.` + is unambiguous. Names install **flat** — `cr-fix`, not `github-dev:cr-fix` — so + uniqueness must hold against *other people's* skills too, not just this repo's; + `install-skills.mjs --selftest` only guards the intra-repo half. - **Agents** — `-a hermes-agent` / `-a codex`. Run inside an agent, `npx skills` auto-detects it and goes **non-interactive (no picker)** — so a wrapper MUST pass `-a` explicitly or it silently targets the detected agent; with `-y` + @@ -34,11 +45,30 @@ plugin-grouped selector and Hermes profile targeting. dir the retired `codex-bridge` wrote to — NOT `~/.codex/skills` (which holds only `.system`). Symlink/copy, conflicts, remove, update, and the lockfile are all owned by `npx skills`, not reimplemented. -- **Layout divergence vs the plugin-adapter route**: this route installs flat - per-skill dirs under `$HERMES_HOME/skills//`, while - `hermes plugins install` implies `$HERMES_HOME/plugins//skills/`. Skill - bodies whose `SKILL_DIR` fallback only covers one route miss the other — see - the layout-divergence caveat in [[hermes-plugin-adapter]]. +- **Layout divergence resolved (#166)**: this route installs flat per-skill dirs + under `$HERMES_HOME/skills//`, while the retired `hermes plugins install` + route implied `$HERMES_HOME/plugins//skills/`. With the adapter gone there + is one layout, so a `SKILL_DIR` fallback chain only has to cover the flat one — + which is also the only layout ever *measured* here. +- **`-a hermes-agent` COPIES, it does not symlink** (measured 2026-07-27, skills + v1.5.20): `~/.hermes/skills/cr-fix/` came out a real directory while + `~/.claude/skills/*` entries are symlinks into `~/.agents/skills/`. Upstream + documents symlink-with-copy-fallback, so do not assume the link; a source-tree + edit does **not** reach an existing Hermes install until a reinstall or + `npx skills update`. + +## Hermes indexes `~/.hermes/skills/` passively + +Upstream docs call `~/.hermes/skills/` "the primary directory and source of truth" +and state that "every installed skill is automatically available as a slash +command", surfacing at `skills_list()` (Level 0 progressive disclosure). So under +this route a skill's `description` surfaces it the same way it does under Claude +Code and Codex 0.135. + +This **retires the opt-in load contract** the adapter route carried, where a skill +was reachable only via an explicit `skill_view(":")` call after +`--enable`. A skill body that says "you were explicitly loaded, not auto-selected" +is describing the retired route and is now wrong for Hermes. ## Hermes profile = HERMES_HOME bridge @@ -69,3 +99,5 @@ refinement, not a v1 bug. - `scripts/install-skills.mjs` (P0 install wrapper) + `.claude/spec/2026-06-24-skills-installer-tui.md` — the wrapper, the selector, and the HERMES_HOME / skill-count design decisions. - vercel-labs/skills `npx skills add` CLI — `-s` (repeated, comma-rejecting) / `-a` / `-g` semantics, agent auto-detect non-interactive mode, `~/.agents/skills` codex target, `$HERMES_HOME/skills` hermes target; measured 2026-06-24. +- PR #166 (2026-07-27) — retires the Hermes adapter layer, making this the sole Hermes path; re-measured `npx skills add . -l` → 52 skills, and an end-to-end `-a hermes-agent -s cr-fix -g` install that landed a copied (not symlinked) `~/.hermes/skills/cr-fix/`. +- Hermes Agent docs, Skills System page (`hermes-agent.nousresearch.com/docs/user-guide/features/skills`, read 2026-07-27) — `~/.hermes/skills/` is "the primary directory and source of truth"; "every installed skill is automatically available as a slash command"; `skills_list()` is Level 0 of progressive disclosure. From 581c4f52fe7f5c6769336cb0d37dfdf2e89b9a85 Mon Sep 17 00:00:00 2001 From: YoungjaeDev Date: Mon, 27 Jul 2026 10:37:53 +0900 Subject: [PATCH 06/12] fix: clear adapter references rg missed under dot-dirs CodeRabbit iteration 1. Five findings; four applied, one deferred. Applied: - .claude-plugin/marketplace.json metadata still advertised the generated plugin.yaml/__init__.py adapters as the Hermes path (CR Minor) - code_review.md said Codex-eligible is total-2; core-config became eligible as a hooks-only manifest, so it is total-1 (CR Major) - three e2e-harness runtime tables still read "forward-compat only - not loaded today" for Hermes, contradicting the Path B text this PR added (CR Major) - README claimed npx skills installs to ~/.codex/skills/ for the codex target. Measured: -a codex -g lands in ~/.agents/skills/, and ~/.codex/skills/ holds only .system. The wiki already recorded this; the README contradicted it (CR Major) Deferred: pinning npx skills to a version (CR Major, supply-chain). Real, but it trades drift risk for a pin nobody is assigned to bump - a policy call. Also fixes two live files CodeRabbit did not flag and my own verification grep missed: .coderabbit.yaml (its review instructions still told reviewers to expect regenerated Hermes adapters) and .claude/rules/plugin-versioning.md (paths: frontmatter globbed plugins/*/plugin.yaml, plus three regeneration rules). Both were invisible because recursive rg skips dot-directories unless --hidden is passed - the exact Mode 6 trap already recorded in .llmwiki/wiki/plugin-ops/detector-cannot-look-vs-nothing-wrong.md from PR #164. e2e-harness 0.2.2 -> 0.2.3, marketplace 2.8.0 -> 2.8.1. Refs #166 --- .claude-plugin/marketplace.json | 6 ++--- .claude/rules/plugin-versioning.md | 10 +++---- .coderabbit.yaml | 27 +++++++++---------- README.md | 4 +-- code_review.md | 2 +- .../e2e-harness/.claude-plugin/plugin.json | 2 +- plugins/e2e-harness/.codex-plugin/plugin.json | 2 +- .../e2e-harness/references/role-contracts.md | 2 +- .../e2e-harness/skills/e2e-author/SKILL.md | 2 +- plugins/e2e-harness/skills/e2e-debug/SKILL.md | 2 +- 10 files changed, 29 insertions(+), 30 deletions(-) diff --git a/.claude-plugin/marketplace.json b/.claude-plugin/marketplace.json index 1488fe6e..80e40455 100644 --- a/.claude-plugin/marketplace.json +++ b/.claude-plugin/marketplace.json @@ -4,8 +4,8 @@ "name": "YoungjaeDev" }, "metadata": { - "description": "Personal Claude Code plugin collection with 24 specialized plugins. Codex 0.135 + Hermes Agent native — generated `.agents/plugins/marketplace.json` + per-plugin `.codex-plugin/plugin.json` (`scripts/sync-codex-manifests.mjs`) and Hermes `plugin.yaml` + `__init__.py` adapters (`scripts/sync-hermes-manifests.mjs`).", - "version": "2.8.0" + "description": "Personal Claude Code plugin collection with 24 specialized plugins. Codex 0.135 native — generated `.agents/plugins/marketplace.json` + per-plugin `.codex-plugin/plugin.json` (`scripts/sync-codex-manifests.mjs`). Hermes Agent installs skills from the same tree via `npx skills` (`scripts/install-skills.mjs`), with no generated adapter.", + "version": "2.8.1" }, "plugins": [ { @@ -26,7 +26,7 @@ "name": "e2e-harness", "source": "./plugins/e2e-harness", "description": "Playwright E2E test-harness engineering — wraps Playwright's official AI test agents (npx playwright init-agents --loop=claude generates planner/generator/healer). Three skills close the planner -> generator -> healer self-improving loop: e2e-setup onboards the full harness (agents, auth separation via storageState + setup-project dependency, page.route mocking with Next.js BFF/SSR guidance, E2E operating SSOT doc, GitHub Actions CI with trace/report artifact upload + PR-failure comment + path/label gating); e2e-author selects critical user flows and runs planner -> review-gate -> generator with semantic getByRole locators and a --repeat-each burn-in flake gate; e2e-debug downloads the CI trace, inspects it headlessly, and runs the healer with bounded retries (skip-after-3 + reason comment). Never overwrites an existing playwright.config (merge + backup); degrades gracefully when Playwright is not installed.", - "version": "0.2.2", + "version": "0.2.3", "category": "testing" }, { diff --git a/.claude/rules/plugin-versioning.md b/.claude/rules/plugin-versioning.md index be0839bb..37833617 100644 --- a/.claude/rules/plugin-versioning.md +++ b/.claude/rules/plugin-versioning.md @@ -1,5 +1,5 @@ --- -paths: .claude-plugin/marketplace.json, plugins/*/.claude-plugin/plugin.json, plugins/*/CLAUDE.md, plugins/*/plugin.yaml +paths: .claude-plugin/marketplace.json, plugins/*/.claude-plugin/plugin.json, plugins/*/CLAUDE.md --- # Plugin Versioning Rules @@ -14,7 +14,7 @@ Keep plugin versions synchronized across the two source-of-truth files and docum - `plugins//.claude-plugin/plugin.json` — per-plugin manifest. Bumping `version` triggers Claude Code's plugin cache refresh. - `.claude-plugin/marketplace.json` — marketplace registry. Contains per-plugin `version` (must match `plugin.json`) and top-level `metadata.version` (bumped once per marketplace release). -- `plugins//plugin.yaml` + `plugins//__init__.py` — Hermes adapters for HERMES_ELIGIBLE plugins, **generated** by `scripts/sync-hermes-manifests.mjs` from `marketplace.json` (`plugin.yaml` `version` / `description` are marketplace-derived; `__init__.py` is a generic skill-registration entrypoint). Do not hand-edit — bump the marketplace entry and re-run the generator. `sync-hermes-manifests.mjs --check` guards adapter drift + orphans, so this is no longer a manual three-way sync. (`sync-codex-manifests.mjs --check` validates Codex manifests only.) +- Hermes has **no versioned artifact** — `npx skills` (`scripts/install-skills.mjs`) reads the source tree at install time, so a version bump needs no Hermes-side regeneration and no drift guard. The generated `plugin.yaml` + `__init__.py` adapters were retired in #166. - `AGENTS.md` (root) — plugin count summary (keep in sync when adding/removing plugins). Root `CLAUDE.md` is a one-line `@AGENTS.md` import; edit `AGENTS.md`. - `README.md` — user-facing plugin count + badge. - `.claude/settings.json` — tracked local-load list (`plugins.local`). A plugin absent here is registered in the marketplace but does NOT auto-load in local dev. @@ -27,8 +27,8 @@ Keep plugin versions synchronized across the two source-of-truth files and docum - **Update plugin count** in root `AGENTS.md` (`## Plugins (N)` + structure tree) AND `README.md` (description sentence + badge + detail section) when adding or removing a plugin. - **Adding a skill to an existing plugin syncs docs too** (distinct from the plugin-count update above — a skill add does NOT change the plugin count): update that plugin's `plugins//CLAUDE.md` skill listing, and — when the version bump also changed the plugin `description` — the matching one-line description in root `AGENTS.md` and `README.md`. Manifest regen + `metadata.version` bump still apply. - **Update the Codex-eligible count too** — distinct from the total and easy to miss. Adding/removing a plugin changes the Codex-eligible number (total − 1 EXCLUDED: `codex-image`; `core-config` is now Codex-eligible as a hooks-only manifest). Fix it in `AGENTS.md`'s Codex-integration section (`eligible 23개`) and `README.md`'s Codex section (`N / M plugins`). Neither the version files nor `sync-codex-manifests.mjs --check` catches a stale eligible count. -- **Sync the `AGENTS.md` count-homes too** — beyond `## Plugins (N)`, `AGENTS.md` carries two counts that no `--check` guards: the Hermes-allowlist count (`현재 N개: …`) and the Codex verification comment (`# N entries`). A Hermes-eligible plugin add left both stale until a reviewer caught it. Update them in the same change as the plugin-count and Codex-eligible bumps. -- **Re-run both generators after any version / description change** — `node scripts/sync-codex-manifests.mjs` (regenerates `.codex-plugin/` + catalog) and `node scripts/sync-hermes-manifests.mjs` (regenerates `plugin.yaml` + `__init__.py` for HERMES_ELIGIBLE plugins). Both `--check` guards run in `.githooks/pre-commit` + `.github/workflows/validate-codex.yml`, so unregenerated output fails CI. +- **Sync the `AGENTS.md` count-homes too** — beyond `## Plugins (N)`, `AGENTS.md` carries the Codex verification comment (`# N entries`), which no `--check` guards. Update it in the same change as the plugin-count and Codex-eligible bumps. +- **Re-run the Codex generator after any version / description change** — `node scripts/sync-codex-manifests.mjs` (regenerates `.codex-plugin/` + catalog). Its `--check` guard runs in `.githooks/pre-commit` + `.github/workflows/validate-codex.yml`, so unregenerated output fails CI. - **Register new plugins in `.claude/settings.json`** (`plugins.local` array, `./plugins/`) when adding a plugin — this tracked file is what auto-loads plugins locally; marketplace registration alone does not. Neither the version files nor `sync-codex-manifests.mjs --check` catch this omission. - **Adhere to semver** at the plugin level: `MAJOR.MINOR.PATCH`. PATCH for fixes, MINOR for backward-compatible features, MAJOR for breaking changes. - **Document cache workaround** in release notes and user docs — the manual `rm -rf` is the only reliable refresh path until the Claude Code plugin cache bugs are fixed upstream. @@ -53,7 +53,7 @@ Keep plugin versions synchronized across the two source-of-truth files and docum 2. Update the matching `version` in `.claude-plugin/marketplace.json`. 3. Bump `metadata.version` in `.claude-plugin/marketplace.json`. 4. (If adding/removing a plugin) update plugin counts in `AGENTS.md` and `README.md`, and add/remove its `./plugins/` entry in `.claude/settings.json` (`plugins.local`). -5. Re-run `node scripts/sync-codex-manifests.mjs` and `node scripts/sync-hermes-manifests.mjs` to regenerate derived manifests/adapters. +5. Re-run `node scripts/sync-codex-manifests.mjs` to regenerate the derived Codex manifests. 6. Commit all changes together. ## User Update Workflow diff --git a/.coderabbit.yaml b/.coderabbit.yaml index a42e2777..9536395f 100644 --- a/.coderabbit.yaml +++ b/.coderabbit.yaml @@ -38,11 +38,10 @@ reviews: (Codex 0.135 silently skips longer ones) and must be quoted if it contains a colon-space (": "), or YAML parses it as a nested mapping and the skill fails to load. Do NOT flag generated manifests as manually edited: - `plugins/*/.codex-plugin/plugin.json`, `plugins/*/plugin.yaml`, and - `plugins/*/__init__.py` are generator output from - `scripts/sync-codex-manifests.mjs` / `scripts/sync-hermes-manifests.mjs`; a - diff to them is expected after a version or description change, and the - generators' `--check` (run in CI) is the arbiter of correctness. A version + `plugins/*/.codex-plugin/plugin.json` is generator output from + `scripts/sync-codex-manifests.mjs`; a + diff to it is expected after a version or description change, and the + generator's `--check` (run in CI) is the arbiter of correctness. A version bump must update `plugins//.claude-plugin/plugin.json` and the matching `.claude-plugin/marketplace.json` entry together. - path: ".llmwiki/**" @@ -57,12 +56,12 @@ reviews: Markdown notes into code or config. - path: "scripts/*.mjs" instructions: >- - These are the Codex/Hermes manifest generators (`sync-codex-manifests.mjs`, - `sync-hermes-manifests.mjs`). They must use Node 18+ built-ins only -- flag any - added runtime dependency (an `import`/`require` of a non-builtin package). Their - output lives under `plugins/*/.codex-plugin/`, `plugins/*/plugin.yaml`, - `plugins/*/__init__.py`, and `.agents/`; that output is generated, never - hand-edited. + These are the Codex manifest generator (`sync-codex-manifests.mjs`) and the + skills installer (`install-skills.mjs`). They must use Node 18+ built-ins only -- + flag any added runtime dependency (an `import`/`require` of a non-builtin package). + The generator's output lives under `plugins/*/.codex-plugin/` and `.agents/`; + that output is generated, never hand-edited. Hermes has no generated artifact -- + `install-skills.mjs` wraps `npx skills`, which reads the source tree directly. pre_merge_checks: custom_checks: - name: "Plugin version triple-sync" @@ -82,9 +81,9 @@ reviews: Advisory only. PASS if no plugin `version`/`description`/skill changed, OR if the corresponding generated manifests were regenerated in the same PR: `plugins//.codex-plugin/plugin.json` plus `.agents/plugins/marketplace.json` - for any eligible plugin, and `plugins//plugin.yaml` plus `__init__.py` - for HERMES_ELIGIBLE plugins. FAIL if a version or description change lacks the - matching regenerated manifest diff. CI (`sync-*-manifests.mjs --check`) is + for any Codex-eligible plugin. Hermes has no generated artifact, so nothing is + expected on that side. FAIL if a version or description change lacks the + matching regenerated manifest diff. CI (`sync-codex-manifests.mjs --check`) is authoritative. - name: "Skill description under 1024 chars" mode: warning diff --git a/README.md b/README.md index e3ab668d..b1c68556 100644 --- a/README.md +++ b/README.md @@ -51,7 +51,7 @@ Claude Code 밖에서는 플러그인이 아니라 **스킬 단위**로 설치 node scripts/install-skills.mjs ``` -플러그인 그룹에서 원하는 스킬을 고른 뒤 타겟(`hermes-agent` / `codex`)과 scope(global `~/` / project `./`)를 선택하면 끝입니다. Hermes 는 `~/.hermes/skills/`, Codex 는 `~/.codex/skills/` 에 설치되고, 두 런타임 모두 거기 있는 스킬을 자동으로 인덱싱합니다 (Hermes 에서는 슬래시 커맨드로도 잡힙니다). +플러그인 그룹에서 원하는 스킬을 고른 뒤 타겟(`hermes-agent` / `codex`)과 scope(global `~/` / project `./`)를 선택하면 끝입니다. global 설치 경로는 Hermes 가 `~/.hermes/skills/`, Codex 가 `~/.agents/skills/` 입니다 (실측 2026-07-27 — `~/.codex/skills/` 에는 `.system` 만 들어있습니다). 두 런타임 모두 자기 경로의 스킬을 자동으로 인덱싱합니다 (Hermes 에서는 슬래시 커맨드로도 잡힙니다). 특정 스킬만 바로 넣으려면 `npx skills` 를 직접 써도 됩니다: @@ -704,7 +704,7 @@ npx skills add YoungjaeDev/my-claude-plugins -a hermes-agent -s cr-fix -g npx skills add . -l # 이 저장소가 노출하는 스킬 목록 ``` -커버리지는 allowlist 가 아니라 "스킬을 가진 플러그인 전부" 입니다 (현재 23 플러그인 / 52 스킬). 설치 경로는 Hermes `~/.hermes/skills/`, Codex `~/.codex/skills/` 이고, 두 런타임 모두 그 디렉터리를 자동 인덱싱합니다 — Hermes 에서는 `skills_list()` 에 노출되며 슬래시 커맨드로도 잡힙니다. 설치 메커니즘(symlink/copy)·충돌·lockfile 은 `npx skills` 에 위임하고, Hermes 프로필은 `HERMES_HOME` env 로 타겟팅합니다. +커버리지는 allowlist 가 아니라 "스킬을 가진 플러그인 전부" 입니다 (현재 23 플러그인 / 52 스킬). global 설치 경로는 Hermes `~/.hermes/skills/`, Codex `~/.agents/skills/` 이고(실측 2026-07-27 — `~/.codex/skills/` 는 `.system` 전용), 두 런타임 모두 그 디렉터리를 자동 인덱싱합니다 — Hermes 에서는 `skills_list()` 에 노출되며 슬래시 커맨드로도 잡힙니다. 설치 메커니즘(symlink/copy)·충돌·lockfile 은 `npx skills` 에 위임하고, Hermes 프로필은 `HERMES_HOME` env 로 타겟팅합니다. 스킬 이름은 평평하게 설치됩니다 (`github-dev:cr-fix` 가 아니라 `cr-fix`). 이 저장소의 52개는 서로 유니크하며 `--selftest` 가 이를 강제하지만, 다른 출처의 스킬과 이름이 겹치지 않는지는 확인이 필요합니다. diff --git a/code_review.md b/code_review.md index bf4dfc85..374ca499 100644 --- a/code_review.md +++ b/code_review.md @@ -33,7 +33,7 @@ - 새 dependency, GitHub Actions, CI/CD 권한 변경 — 최소 권한, lockfile, supply-chain. ## Domain-specific (Claude Code plugin marketplace) -- 새 플러그인 추가 / 제거 PR 은 `AGENTS.md`의 플러그인 수, `README.md` badge + 표 + detail + 트리, `AGENTS.md` / `README.md` 의 Codex-eligible count (total − 2 excluded: core-config·codex-image), `marketplace.json` entry + `metadata.version`, `.claude/settings.json` 의 `plugins.local` entry, 그리고 `node scripts/sync-codex-manifests.mjs` 재실행 — 동시 업데이트 필수 (Hermes 는 생성 산출물이 없어 재실행 대상이 아니다). Codex-eligible count 는 version 파일도 `--check` 도 못 잡으니 수동 확인. +- 새 플러그인 추가 / 제거 PR 은 `AGENTS.md`의 플러그인 수, `README.md` badge + 표 + detail + 트리, `AGENTS.md` / `README.md` 의 Codex-eligible count (total − 1 excluded: `codex-image` 하나뿐 — `core-config` 는 hooks-only 매니페스트로 eligible), `marketplace.json` entry + `metadata.version`, `.claude/settings.json` 의 `plugins.local` entry, 그리고 `node scripts/sync-codex-manifests.mjs` 재실행 — 동시 업데이트 필수 (Hermes 는 생성 산출물이 없어 재실행 대상이 아니다). Codex-eligible count 는 version 파일도 `--check` 도 못 잡으니 수동 확인. - 기존 플러그인에 **skill 추가** PR 은 plugin 수를 바꾸지 않지만 문서 동기화가 필요하다 — 해당 플러그인의 `plugins//CLAUDE.md` skill 목록, 그리고 version bump 이 `description` 도 바꿨다면 `AGENTS.md` / `README.md` 의 한 줄 설명. 매니페스트 재생성 + `metadata.version` bump 은 그대로 적용. - **플러그인 제거 PR 추가 주의** — (a) `git grep -niE ''` 로 레포 전체(다른 플러그인 skill 본문·`docs/` 포함, 과거 `.claude/spec/*` 제외)에서 live 참조를 훑어 제거. count 파일만으론 부족하다 (예: `code-scout` 의 `agent-routing.md` 라우팅). 살아남은 참조는 존재하지 않는 플러그인으로 사용자를 안내한다. (b) 삭제된 플러그인이 생성하던 tracked 산출물(예: `workflow-viz` → `docs/architecture/*`)은 orphaned 이니 같은 변경에서 제거. (c) 플러그인 제거는 `metadata.version` **MINOR** bump (MAJOR 아님 — metadata.version 은 per-release counter, semver-breaking 규칙은 per-plugin 스코프; `midjourney` 삭제 선례가 MINOR). 리뷰어의 "breaking→MAJOR" 지적보다 이 컨벤션 우선. - Codex 매니페스트 (`plugins/*/.codex-plugin/plugin.json`, `.agents/plugins/marketplace.json`) 가 `--check` 통과해야 함. 수동 편집 흔적 검토. diff --git a/plugins/e2e-harness/.claude-plugin/plugin.json b/plugins/e2e-harness/.claude-plugin/plugin.json index 193dfc0b..7f31d634 100644 --- a/plugins/e2e-harness/.claude-plugin/plugin.json +++ b/plugins/e2e-harness/.claude-plugin/plugin.json @@ -1,6 +1,6 @@ { "name": "e2e-harness", - "version": "0.2.2", + "version": "0.2.3", "description": "Playwright E2E test-harness engineering — wraps Playwright's official AI test agents (npx playwright init-agents --loop=claude generates planner/generator/healer). Three skills close the planner -> generator -> healer self-improving loop: e2e-setup onboards the full harness (agents, auth separation via storageState + setup-project dependency, page.route mocking with Next.js BFF/SSR guidance, E2E operating SSOT doc, GitHub Actions CI with trace/report artifact upload + PR-failure comment + path/label gating); e2e-author selects critical user flows and runs planner -> review-gate -> generator with semantic getByRole locators and a --repeat-each burn-in flake gate; e2e-debug downloads the CI trace, inspects it headlessly, and runs the healer with bounded retries (skip-after-3 + reason comment). Never overwrites an existing playwright.config (merge + backup); degrades gracefully when Playwright is not installed.", "skills": [ "./skills/e2e-setup", diff --git a/plugins/e2e-harness/.codex-plugin/plugin.json b/plugins/e2e-harness/.codex-plugin/plugin.json index a18b8a35..c4e882fd 100644 --- a/plugins/e2e-harness/.codex-plugin/plugin.json +++ b/plugins/e2e-harness/.codex-plugin/plugin.json @@ -1,6 +1,6 @@ { "name": "e2e-harness", - "version": "0.2.2", + "version": "0.2.3", "description": "Playwright E2E test-harness engineering — wraps Playwright's official AI test agents (npx playwright init-agents --loop=claude generates planner/generator/healer). Three skills close the planner -> generator -> healer self-improving loop: e2e-setup onboards the full harness (agents, auth separation via storageState + setup-project dependency, page.route mocking with Next.js BFF/SSR guidance, E2E operating SSOT doc, GitHub Actions CI with trace/report artifact upload + PR-failure comment + path/label gating); e2e-author selects critical user flows and runs planner -> review-gate -> generator with semantic getByRole locators and a --repeat-each burn-in flake gate; e2e-debug downloads the CI trace, inspects it headlessly, and runs the healer with bounded retries (skip-after-3 + reason comment). Never overwrites an existing playwright.config (merge + backup); degrades gracefully when Playwright is not installed.", "author": { "name": "YoungjaeDev" diff --git a/plugins/e2e-harness/references/role-contracts.md b/plugins/e2e-harness/references/role-contracts.md index 786f2c61..acf8def9 100644 --- a/plugins/e2e-harness/references/role-contracts.md +++ b/plugins/e2e-harness/references/role-contracts.md @@ -87,7 +87,7 @@ Each role drives the app through the approved `playwright-test` MCP server. A ge ## Runtime tool names -These skills dispatch and read through whatever tools the host runtime exposes. Claude and Codex share tool names; Hermes (forward-compat only — not loaded today) maps as: +These skills dispatch and read through whatever tools the host runtime exposes. Claude and Codex share tool names; Hermes maps as: | Claude / Codex | Hermes | Used here for | |---|---|---| diff --git a/plugins/e2e-harness/skills/e2e-author/SKILL.md b/plugins/e2e-harness/skills/e2e-author/SKILL.md index f142bf50..ab47715c 100644 --- a/plugins/e2e-harness/skills/e2e-author/SKILL.md +++ b/plugins/e2e-harness/skills/e2e-author/SKILL.md @@ -80,4 +80,4 @@ Two runtime families, three execution paths, same gates: on **Claude Code** the ## Runtime tool names -Dispatch and file tools differ by runtime. Claude and Codex share names; Hermes (forward-compat only — not loaded today) maps as: `Task` → `delegate_task` (planner/generator dispatch), `Bash` → `terminal` (`npx playwright`, resolver), `Read` → `read_file` (the role contract, specs), `Write`/`Edit` → `write_file`/`patch`, `AskUserQuestion` → `clarify` (CUF selection + review gate). Full contract + table: `${PLUGIN_ROOT}/references/role-contracts.md`. +Dispatch and file tools differ by runtime. Claude and Codex share names; Hermes maps as: `Task` → `delegate_task` (planner/generator dispatch), `Bash` → `terminal` (`npx playwright`, resolver), `Read` → `read_file` (the role contract, specs), `Write`/`Edit` → `write_file`/`patch`, `AskUserQuestion` → `clarify` (CUF selection + review gate). Full contract + table: `${PLUGIN_ROOT}/references/role-contracts.md`. diff --git a/plugins/e2e-harness/skills/e2e-debug/SKILL.md b/plugins/e2e-harness/skills/e2e-debug/SKILL.md index e3ea645e..9a36c299 100644 --- a/plugins/e2e-harness/skills/e2e-debug/SKILL.md +++ b/plugins/e2e-harness/skills/e2e-debug/SKILL.md @@ -93,4 +93,4 @@ Two runtime families, three execution paths, same bounded loop: on **Claude Code ## Runtime tool names -Dispatch and file tools differ by runtime. Claude and Codex share names; Hermes (forward-compat only — not loaded today) maps as: `Task` → `delegate_task` (healer dispatch), `Bash` → `terminal` (`npx playwright trace`, `gh run download`, resolver), `Read` → `read_file` (the role contract), `Write`/`Edit` → `write_file`/`patch` (patch the spec), `AskUserQuestion` → `clarify`. Full contract + table: `${PLUGIN_ROOT}/references/role-contracts.md`. +Dispatch and file tools differ by runtime. Claude and Codex share names; Hermes maps as: `Task` → `delegate_task` (healer dispatch), `Bash` → `terminal` (`npx playwright trace`, `gh run download`, resolver), `Read` → `read_file` (the role contract), `Write`/`Edit` → `write_file`/`patch` (patch the spec), `AskUserQuestion` → `clarify`. Full contract + table: `${PLUGIN_ROOT}/references/role-contracts.md`. From e4504716483144d6e5b46f87d9871f490bdf15bd Mon Sep 17 00:00:00 2001 From: YoungjaeDev Date: Mon, 27 Jul 2026 10:57:59 +0900 Subject: [PATCH 07/12] docs(install-skills): record why npx skills stays unpinned MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit CodeRabbit (#168) flagged the floating `npx skills` as a supply-chain risk. Fair in general, but this installer is run interactively by a human, never from CI, so the exposure is one attended invocation rather than an automated pipeline. Pinning trades that for a bump owner nobody is assigned, and an unbumped pin rots silently while the upstream CLI is still moving fast. Records the deferral and the condition for revisiting — switch to skills@ and name a bump cadence in the same change. Refs #166 --- scripts/install-skills.mjs | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/scripts/install-skills.mjs b/scripts/install-skills.mjs index 1a80bb17..325b2a54 100644 --- a/scripts/install-skills.mjs +++ b/scripts/install-skills.mjs @@ -192,6 +192,16 @@ const hermesInstalled = () => isDir(HERMES_BASE); // One `npx skills add` spawn per (agent, profile). Selection passed as repeated // `-s ` flags (comma is NOT a valid separator for this CLI). +// +// `skills` is deliberately UNPINNED. A CodeRabbit review (#168) flagged the +// floating `npx skills` as a supply-chain risk, which is fair in general — but +// this is an interactive installer a human runs by hand, never a CI step, so the +// exposure is one attended invocation rather than an automated pipeline. Pinning +// buys that back at the cost of an owner: someone has to bump `skills@` +// here and in the README, and an unbumped pin rots silently while the upstream +// CLI is still moving fast. Revisit as a pair — switch to `skills@` and +// name a bump cadence (or wire renovate/dependabot) in the same change; a pin +// with no bump owner is worse than the float. function installFor(agent, skills, globalScope, profile) { const args = ['--yes', 'skills', 'add', ROOT, '-a', agent]; for (const s of skills) args.push('-s', s); From 7a3872096d5ac3656f0163daa14b798140c8614b Mon Sep 17 00:00:00 2001 From: YoungjaeDev Date: Mon, 27 Jul 2026 11:05:43 +0900 Subject: [PATCH 08/12] fix(plugins): repoint Hermes install docs at npx skills MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Codex review (P2) caught six plugin CLAUDE.md files still instructing users to run `hermes plugins install .../plugins/ --enable`, which needs the plugin.yaml this PR deletes. Following those docs fails outright. The same review exposed a second class the first sweep missed: 18 SKILL.md Hermes-compat notes still describe the adapter-era load contract — skills reachable only via an explicit `skill_view(":")` call. Under npx skills they land flat in ~/.hermes/skills// and are indexed passively, so both the qualified name and the explicit-load instruction are wrong. Both classes were invisible to the earlier verification because it grepped for the deleted artifact names (sync-hermes, HERMES_ELIGIBLE, plugin.yaml) and never for the user-facing commands that depend on them (hermes plugins install, skill_view). A removal sweep has to cover both the artifact and its callers. 24 files across 7 plugins. Version bumps: anti-slop-design 0.3.4, github-dev 2.11.1, interview 1.3.1, ml-toolkit 1.4.4, paper-search-tools 1.1.1, ppt-yeong-style 0.9.4, tcrei-prompt 1.1.3, marketplace 2.9.0. Refs #166 --- .claude-plugin/marketplace.json | 16 ++++++++-------- .../.claude-plugin/plugin.json | 6 ++++-- .../anti-slop-design/.codex-plugin/plugin.json | 2 +- plugins/anti-slop-design/CLAUDE.md | 14 +++++--------- .../skills/anti-slop-design/SKILL.md | 2 +- plugins/github-dev/.claude-plugin/plugin.json | 2 +- plugins/github-dev/.codex-plugin/plugin.json | 2 +- plugins/github-dev/CLAUDE.md | 18 ++++++++++-------- .../github-dev/skills/commit-and-push/SKILL.md | 2 +- plugins/github-dev/skills/cr-fix/SKILL.md | 2 +- .../skills/create-issue-label/SKILL.md | 2 +- .../github-dev/skills/decompose-issue/SKILL.md | 2 +- plugins/github-dev/skills/post-merge/SKILL.md | 2 +- plugins/github-dev/skills/release/SKILL.md | 2 +- .../github-dev/skills/resolve-issue/SKILL.md | 2 +- .../github-dev/skills/update-progress/SKILL.md | 2 +- plugins/interview/.claude-plugin/plugin.json | 2 +- plugins/interview/.codex-plugin/plugin.json | 2 +- plugins/interview/CLAUDE.md | 12 ++++-------- .../skills/interview-methodology/SKILL.md | 2 +- plugins/ml-toolkit/.claude-plugin/plugin.json | 2 +- plugins/ml-toolkit/.codex-plugin/plugin.json | 2 +- plugins/ml-toolkit/CLAUDE.md | 18 ++++++------------ plugins/ml-toolkit/skills/cv-explorer/SKILL.md | 2 +- plugins/ml-toolkit/skills/cv-notebook/SKILL.md | 2 +- .../skills/gpu-parallel-pipeline/SKILL.md | 2 +- .../ml-toolkit/skills/gradio-cv-app/SKILL.md | 2 +- .../skills/ml-dev-principles/SKILL.md | 2 +- .../.claude-plugin/plugin.json | 2 +- .../.codex-plugin/plugin.json | 2 +- .../paper-search-tools/skills/setup/SKILL.md | 7 +++++-- .../ppt-yeong-style/.claude-plugin/plugin.json | 2 +- .../ppt-yeong-style/.codex-plugin/plugin.json | 2 +- plugins/ppt-yeong-style/CLAUDE.md | 12 ++++-------- .../skills/ppt-yeong-style/SKILL.md | 4 ++-- .../tcrei-prompt/.claude-plugin/plugin.json | 2 +- plugins/tcrei-prompt/.codex-plugin/plugin.json | 2 +- plugins/tcrei-prompt/CLAUDE.md | 12 ++++-------- .../tcrei-prompt/skills/tcrei-prompt/SKILL.md | 2 +- 39 files changed, 81 insertions(+), 96 deletions(-) diff --git a/.claude-plugin/marketplace.json b/.claude-plugin/marketplace.json index 80e40455..350fe079 100644 --- a/.claude-plugin/marketplace.json +++ b/.claude-plugin/marketplace.json @@ -5,7 +5,7 @@ }, "metadata": { "description": "Personal Claude Code plugin collection with 24 specialized plugins. Codex 0.135 native — generated `.agents/plugins/marketplace.json` + per-plugin `.codex-plugin/plugin.json` (`scripts/sync-codex-manifests.mjs`). Hermes Agent installs skills from the same tree via `npx skills` (`scripts/install-skills.mjs`), with no generated adapter.", - "version": "2.8.1" + "version": "2.9.0" }, "plugins": [ { @@ -19,7 +19,7 @@ "name": "github-dev", "source": "./plugins/github-dev", "description": "GitHub workflow: commit, PR, issue, worktree, unified CodeRabbit + ChatGPT-Codex cr-fix pipeline v2 (Step 5 pre-flight review detection across CR commit-status + comments + Codex reviews + Codex emoji 3-channel; autonomous Step 9 judgment replaces per-finding AskUserQuestion — LLM judges real/spurious + severity + fix-size and applies/defers/skips with logged reasoning; rate-limit sniffer now covers commit-status description + in-place comment edits; polling interval 60s → 8s; --auto-merge + --skip-minor + --cr-source retained), project tracking, release. All workflows are now skills (commit-and-push, create-issue-label, decompose-issue, update-progress, resolve-issue, release, cr-fix, post-merge) — no commands surface, so they run under Codex too. post-merge runs a mandatory built-in wiki-lore ingest step (absorbed llm-wiki:post-merge-wiki) plus an optional Step 4.5 ephemeral-artifact pruning gate (heuristic candidates → AskUserQuestion → git rm). 2.8.0 correctness repairs: CR-state fetch failures map to a real error channel (no longer masked as a clean 'none'), a null-repository GraphQL response fails loudly instead of a silent false-clean convergence, and an active `@coderabbitai rate limit` query resolves ambiguous passive rate-limit sniffs.", - "version": "2.11.0", + "version": "2.11.1", "category": "github" }, { @@ -61,7 +61,7 @@ "name": "ml-toolkit", "source": "./plugins/ml-toolkit", "description": "ML/multimodal development principles, GPU parallel processing, Gradio CV apps, CV notebook generation, interactive CV data exploration", - "version": "1.4.3", + "version": "1.4.4", "category": "development" }, { @@ -75,14 +75,14 @@ "name": "interview", "source": "./plugins/interview", "description": "Structured requirements gathering", - "version": "1.3.0", + "version": "1.3.1", "category": "planning" }, { "name": "paper-search-tools", "source": "./plugins/paper-search-tools", "description": "Academic paper search (arXiv, PubMed, Semantic Scholar, etc.)", - "version": "1.1.0", + "version": "1.1.1", "category": "research" }, { @@ -103,7 +103,7 @@ "name": "tcrei-prompt", "source": "./plugins/tcrei-prompt", "description": "Rewrite prompts using Google's TCREI structure for next-session reuse", - "version": "1.1.2", + "version": "1.1.3", "category": "content" }, { @@ -138,7 +138,7 @@ "name": "anti-slop-design", "source": "./plugins/anti-slop-design", "description": "Anti-AI-slop design guard for web/SaaS landing, decks (PPT), dashboards, and copy. Runs a clarify->context->plan->run->audit->revise flow with a two-phase audit gate (pre-emit self-critique + binary slop checklist) and hands Korean copy rewriting to humanize-korean. Source-grounded in 6 OSS anti-slop repos.", - "version": "0.3.3", + "version": "0.3.4", "category": "design" }, { @@ -152,7 +152,7 @@ "name": "ppt-yeong-style", "source": "./plugins/ppt-yeong-style", "description": "yeong 스타일 강의·제안 덱 작성 규약 — ppt-master 빌드 엔진 위에 얹는 작성 레이어(엔진 자체가 아님). 스킬 3종: 메인 ppt-yeong-style(미감 시그니처 §0 'Editorial restraint, one committed accent'·md 소스 규약·작성 원칙 16종·밀도 리듬·역할 기반 색·codex-image vs SVG 경계·앱 UI 실물 강제·레버 조합 차별화·윤문·렌더 QA + references/ 6종 + 주입 페이로드) + lecture-deck(강의 덱 운영 — 실습 handouts 생성 규약·프롬프트 카드·placeholder→실캡처 스크린샷 슬롯·리넘버링 4중 동기화·전사 회고 루프·강사 노트 태그 + cc-common 47장 레퍼런스) + deck-review(관점별 리뷰 서브에이전트 4종 audience-fit·story-flow·fact-check·design-qa 병렬 오케스트레이션 + codex:rescue 교차 리뷰, 페르소나는 파라미터). 의존 스킬은 있으면 사용, 없으면 생략 + 설치 제안 문구(ppt-master만 prerequisite-stop). ppt-master로 그냥 'PPT 만들기'와 달리 yeong 규약이 필요할 때.", - "version": "0.9.3", + "version": "0.9.4", "category": "design" }, { diff --git a/plugins/anti-slop-design/.claude-plugin/plugin.json b/plugins/anti-slop-design/.claude-plugin/plugin.json index 5c8a5671..6a62a00f 100644 --- a/plugins/anti-slop-design/.claude-plugin/plugin.json +++ b/plugins/anti-slop-design/.claude-plugin/plugin.json @@ -1,6 +1,8 @@ { "name": "anti-slop-design", - "version": "0.3.3", + "version": "0.3.4", "description": "Anti-AI-slop design guard for web/SaaS landing, decks (PPT), dashboards, and copy. Runs a clarify->context->plan->run->audit->revise flow with a two-phase audit gate (pre-emit self-critique + binary slop checklist) and hands Korean copy rewriting to humanize-korean. Source-grounded in 6 OSS anti-slop repos.", - "skills": ["./skills/anti-slop-design"] + "skills": [ + "./skills/anti-slop-design" + ] } diff --git a/plugins/anti-slop-design/.codex-plugin/plugin.json b/plugins/anti-slop-design/.codex-plugin/plugin.json index 0d677d22..969ab2ce 100644 --- a/plugins/anti-slop-design/.codex-plugin/plugin.json +++ b/plugins/anti-slop-design/.codex-plugin/plugin.json @@ -1,6 +1,6 @@ { "name": "anti-slop-design", - "version": "0.3.3", + "version": "0.3.4", "description": "Anti-AI-slop design guard for web/SaaS landing, decks (PPT), dashboards, and copy. Runs a clarify->context->plan->run->audit->revise flow with a two-phase audit gate (pre-emit self-critique + binary slop checklist) and hands Korean copy rewriting to humanize-korean. Source-grounded in 6 OSS anti-slop repos.", "author": { "name": "YoungjaeDev" diff --git a/plugins/anti-slop-design/CLAUDE.md b/plugins/anti-slop-design/CLAUDE.md index e4768b7d..739bf78c 100644 --- a/plugins/anti-slop-design/CLAUDE.md +++ b/plugins/anti-slop-design/CLAUDE.md @@ -10,17 +10,13 @@ Anti-AI-slop design guard for web/SaaS landing, decks (PPT), dashboards, and cop ## Hermes Agent -Install this plugin from the monorepo subdirectory: +Install the skill (`npx skills`, wrapped by the repo's installer): ```bash -hermes plugins install YoungjaeDev/my-claude-plugins/plugins/anti-slop-design --enable -hermes gateway restart # if using Hermes through a messaging gateway +node scripts/install-skills.mjs # interactive picker +npx skills add YoungjaeDev/my-claude-plugins -a hermes-agent -s anti-slop-design -g ``` -Load the skill explicitly (Hermes plugin skills are opt-in; start a fresh Hermes session after `--enable`): +It lands in `~/.hermes/skills/anti-slop-design/`, which Hermes indexes automatically — it shows up in `skills_list()` and as a slash command under its **flat** name `anti-slop-design`, not `anti-slop-design:anti-slop-design`. -```text -skill_view("anti-slop-design:anti-slop-design") -``` - -The skill body carries a Hermes compatibility table mapping Claude/Codex tool terms (`AskUserQuestion`, `Read`, `Skill`) to Hermes tools (`clarify`, `read_file`, `skill_view`). The Korean-copy handoff to `humanize-korean` runs via `skill_view("humanize-korean:humanize-korean")` under Hermes. +The skill body carries a Hermes compatibility table mapping Claude/Codex tool terms (`AskUserQuestion`, `Read`, `Skill`) to Hermes tools (`clarify`, `read_file`, `skill_view`). The Korean-copy handoff runs against the separately-installed `humanize-korean` skill. diff --git a/plugins/anti-slop-design/skills/anti-slop-design/SKILL.md b/plugins/anti-slop-design/skills/anti-slop-design/SKILL.md index 87f54d0b..3ef0e52d 100644 --- a/plugins/anti-slop-design/skills/anti-slop-design/SKILL.md +++ b/plugins/anti-slop-design/skills/anti-slop-design/SKILL.md @@ -15,7 +15,7 @@ When this skill is loaded through Hermes as `anti-slop-design:anti-slop-design`, | AskUserQuestion | clarify | | Skill | skill_view (list available via skills_list) | -Treat `$ARGUMENTS` as the natural-language arguments supplied when the user asks Hermes to load the skill. Plugin-provided skills are explicit opt-in loads in Hermes; use `skill_view("anti-slop-design:anti-slop-design")` (or ask Hermes to load that qualified skill) rather than relying on bare text. +Treat `$ARGUMENTS` as the natural-language arguments supplied when the user asks Hermes to load the skill. Installed into `~/.hermes/skills/` by `npx skills`, this skill is indexed automatically — it appears in `skills_list()` and as a slash command under its **flat** name `anti-slop-design`. An enterprise anti-slop guard for building, auditing, or improving web/SaaS landings, presentation decks (PPT), dashboards/admin UI, and marketing/UI copy — it **blocks the AI-generated look (slop) before generation** and **audits it after**. diff --git a/plugins/github-dev/.claude-plugin/plugin.json b/plugins/github-dev/.claude-plugin/plugin.json index 3ddef7a1..3c8acc96 100644 --- a/plugins/github-dev/.claude-plugin/plugin.json +++ b/plugins/github-dev/.claude-plugin/plugin.json @@ -1,6 +1,6 @@ { "name": "github-dev", - "version": "2.11.0", + "version": "2.11.1", "description": "GitHub workflow: commit, PR, issue, worktree, unified CodeRabbit + ChatGPT-Codex cr-fix pipeline v2 (Step 5 pre-flight review detection across CR commit-status + comments + Codex reviews + Codex emoji 3-channel; autonomous Step 9 judgment replaces per-finding AskUserQuestion — LLM judges real/spurious + severity + fix-size and applies/defers/skips with logged reasoning; rate-limit sniffer now covers commit-status description + in-place comment edits; polling interval 60s → 8s; --auto-merge + --skip-minor + --cr-source retained), project tracking, release. All workflows are now skills (commit-and-push, create-issue-label, decompose-issue, update-progress, resolve-issue, release, cr-fix, post-merge) — no commands surface, so they run under Codex too. post-merge runs a mandatory built-in wiki-lore ingest step (absorbed llm-wiki:post-merge-wiki) plus an optional Step 4.5 ephemeral-artifact pruning gate (heuristic candidates → AskUserQuestion → git rm). 2.8.0 correctness repairs: CR-state fetch failures map to a real error channel (no longer masked as a clean 'none'), a null-repository GraphQL response fails loudly instead of a silent false-clean convergence, and an active `@coderabbitai rate limit` query resolves ambiguous passive rate-limit sniffs.", "skills": [ "./skills/cr-fix", diff --git a/plugins/github-dev/.codex-plugin/plugin.json b/plugins/github-dev/.codex-plugin/plugin.json index a481a988..ef460784 100644 --- a/plugins/github-dev/.codex-plugin/plugin.json +++ b/plugins/github-dev/.codex-plugin/plugin.json @@ -1,6 +1,6 @@ { "name": "github-dev", - "version": "2.11.0", + "version": "2.11.1", "description": "GitHub workflow: commit, PR, issue, worktree, unified CodeRabbit + ChatGPT-Codex cr-fix pipeline v2 (Step 5 pre-flight review detection across CR commit-status + comments + Codex reviews + Codex emoji 3-channel; autonomous Step 9 judgment replaces per-finding AskUserQuestion — LLM judges real/spurious + severity + fix-size and applies/defers/skips with logged reasoning; rate-limit sniffer now covers commit-status description + in-place comment edits; polling interval 60s → 8s; --auto-merge + --skip-minor + --cr-source retained), project tracking, release. All workflows are now skills (commit-and-push, create-issue-label, decompose-issue, update-progress, resolve-issue, release, cr-fix, post-merge) — no commands surface, so they run under Codex too. post-merge runs a mandatory built-in wiki-lore ingest step (absorbed llm-wiki:post-merge-wiki) plus an optional Step 4.5 ephemeral-artifact pruning gate (heuristic candidates → AskUserQuestion → git rm). 2.8.0 correctness repairs: CR-state fetch failures map to a real error channel (no longer masked as a clean 'none'), a null-repository GraphQL response fails loudly instead of a silent false-clean convergence, and an active `@coderabbitai rate limit` query resolves ambiguous passive rate-limit sniffs.", "author": { "name": "YoungjaeDev" diff --git a/plugins/github-dev/CLAUDE.md b/plugins/github-dev/CLAUDE.md index fecb5c7c..27c23290 100644 --- a/plugins/github-dev/CLAUDE.md +++ b/plugins/github-dev/CLAUDE.md @@ -33,23 +33,25 @@ GitHub workflow automation skills for Claude Code. All workflows are skills (no ## Hermes Agent -Hermes can install only this plugin from the monorepo subdirectory: +Install the workflows you want as skills (`npx skills`, wrapped by the repo's installer): ```bash -hermes plugins install YoungjaeDev/my-claude-plugins/plugins/github-dev --enable -hermes gateway restart # if using Hermes through a messaging gateway +node scripts/install-skills.mjs # interactive picker +npx skills add YoungjaeDev/my-claude-plugins -a hermes-agent \ + -s cr-fix -s resolve-issue -s commit-and-push -g # or name them directly ``` -Hermes exposes the existing workflows as namespaced plugin skills. Load them explicitly with `skill_view` or ask Hermes to load the qualified skill: +They land in `~/.hermes/skills//`, which Hermes indexes automatically — each one shows up in `skills_list()` and as a slash command. Ask for them by their **flat** name: ```text -skill_view("github-dev:commit-and-push") -skill_view("github-dev:resolve-issue") # then provide the issue number in the same request -skill_view("github-dev:cr-fix") # then provide flags such as --cr-source auto +cr-fix # then provide flags such as --cr-source auto +resolve-issue # then provide the issue number in the same request +commit-and-push ``` Notes: -- Hermes uses `github-dev:` qualified skill names rather than Claude slash commands, and plugin-provided skills are explicit opt-in loads. +- Names are flat, not `github-dev:` — the qualified form belonged to the plugin-adapter route retired in #166. +- `-a hermes-agent` copies rather than symlinks, so re-run the installer (or `npx skills update`) after changing a skill body. - Start a fresh Hermes session after enabling the plugin so the plugin skill registry is rebuilt. - The skill bodies include a Hermes compatibility table mapping Claude/Codex tool terms (`Bash`, `Read`, `Edit`, `AskUserQuestion`, `Task`, `Monitor`) to Hermes tools (`terminal`, `read_file`, `patch`, `clarify`, `delegate_task`, `process`). diff --git a/plugins/github-dev/skills/commit-and-push/SKILL.md b/plugins/github-dev/skills/commit-and-push/SKILL.md index 7252259d..ba0e1c4b 100644 --- a/plugins/github-dev/skills/commit-and-push/SKILL.md +++ b/plugins/github-dev/skills/commit-and-push/SKILL.md @@ -21,7 +21,7 @@ When this skill is loaded through Hermes as `github-dev:`, map Claude/Cod | Task | delegate_task | | Monitor | process | -Treat `$ARGUMENTS` as the natural-language arguments supplied when the user asks Hermes to load the skill. Plugin-provided skills are explicit opt-in loads in Hermes; use `skill_view("github-dev:")` (or ask Hermes to load that qualified skill) rather than relying on bare text like `github-dev: ...`. +Treat `$ARGUMENTS` as the natural-language arguments supplied when the user asks Hermes to run the skill. Installed into `~/.hermes/skills/` by `npx skills`, this skill is indexed automatically — it appears in `skills_list()` and as a slash command under its **flat** name (``, not `github-dev:`). Analyze only the files provided as arguments, create an appropriate commit message, commit, and push. diff --git a/plugins/github-dev/skills/cr-fix/SKILL.md b/plugins/github-dev/skills/cr-fix/SKILL.md index d3e450aa..6a9fc482 100644 --- a/plugins/github-dev/skills/cr-fix/SKILL.md +++ b/plugins/github-dev/skills/cr-fix/SKILL.md @@ -21,7 +21,7 @@ When this skill is loaded through Hermes as `github-dev:`, map Claude/Cod | Task | delegate_task | | Monitor | process | -Treat `$ARGUMENTS` as the natural-language arguments supplied when the user asks Hermes to load the skill. Plugin-provided skills are explicit opt-in loads in Hermes; use `skill_view("github-dev:")` (or ask Hermes to load that qualified skill) rather than relying on bare text like `github-dev: ...`. +Treat `$ARGUMENTS` as the natural-language arguments supplied when the user asks Hermes to run the skill. Installed into `~/.hermes/skills/` by `npx skills`, this skill is indexed automatically — it appears in `skills_list()` and as a slash command under its **flat** name (``, not `github-dev:`). Self-contained skill that owns the full review-resolution loop. One Claude turn drives the entire pipeline; wait phases use `Bash(run_in_background=true)` + `Monitor` so token cost is ~0 during reviews. diff --git a/plugins/github-dev/skills/create-issue-label/SKILL.md b/plugins/github-dev/skills/create-issue-label/SKILL.md index 91d7b9f3..e3983846 100644 --- a/plugins/github-dev/skills/create-issue-label/SKILL.md +++ b/plugins/github-dev/skills/create-issue-label/SKILL.md @@ -21,7 +21,7 @@ When this skill is loaded through Hermes as `github-dev:`, map Claude/Cod | Task | delegate_task | | Monitor | process | -Treat `$ARGUMENTS` as the natural-language arguments supplied when the user asks Hermes to load the skill. Plugin-provided skills are explicit opt-in loads in Hermes; use `skill_view("github-dev:")` (or ask Hermes to load that qualified skill) rather than relying on bare text like `github-dev: ...`. +Treat `$ARGUMENTS` as the natural-language arguments supplied when the user asks Hermes to run the skill. Installed into `~/.hermes/skills/` by `npx skills`, this skill is indexed automatically — it appears in `skills_list()` and as a slash command under its **flat** name (``, not `github-dev:`). Analyze project structure and create appropriate GitHub issue labels. Follow project guidelines in `@CLAUDE.md`. diff --git a/plugins/github-dev/skills/decompose-issue/SKILL.md b/plugins/github-dev/skills/decompose-issue/SKILL.md index b7ad8d5a..1f6c6ed2 100644 --- a/plugins/github-dev/skills/decompose-issue/SKILL.md +++ b/plugins/github-dev/skills/decompose-issue/SKILL.md @@ -21,7 +21,7 @@ When this skill is loaded through Hermes as `github-dev:`, map Claude/Cod | Task | delegate_task | | Monitor | process | -Treat `$ARGUMENTS` as the natural-language arguments supplied when the user asks Hermes to load the skill. Plugin-provided skills are explicit opt-in loads in Hermes; use `skill_view("github-dev:")` (or ask Hermes to load that qualified skill) rather than relying on bare text like `github-dev: ...`. +Treat `$ARGUMENTS` as the natural-language arguments supplied when the user asks Hermes to run the skill. Installed into `~/.hermes/skills/` by `npx skills`, this skill is indexed automatically — it appears in `skills_list()` and as a slash command under its **flat** name (``, not `github-dev:`). ## Cross-runtime interactive input diff --git a/plugins/github-dev/skills/post-merge/SKILL.md b/plugins/github-dev/skills/post-merge/SKILL.md index 19a9517a..21aba7f6 100644 --- a/plugins/github-dev/skills/post-merge/SKILL.md +++ b/plugins/github-dev/skills/post-merge/SKILL.md @@ -21,7 +21,7 @@ When this skill is loaded through Hermes as `github-dev:`, map Claude/Cod | Task | delegate_task | | Monitor | process | -Treat `$ARGUMENTS` as the natural-language arguments supplied when the user asks Hermes to load the skill. Plugin-provided skills are explicit opt-in loads in Hermes; use `skill_view("github-dev:")` (or ask Hermes to load that qualified skill) rather than relying on bare text like `github-dev: ...`. +Treat `$ARGUMENTS` as the natural-language arguments supplied when the user asks Hermes to run the skill. Installed into `~/.hermes/skills/` by `npx skills`, this skill is indexed automatically — it appears in `skills_list()` and as a slash command under its **flat** name (``, not `github-dev:`). Local cleanup + knowledge integration after a PR is merged. One run takes a merged PR from branch cleanup → tracking sync → config/memory integration → **mandatory** wiki-lore ingest → README → commit. Follow project guidelines in `@CLAUDE.md` and `@AGENTS.md` throughout. diff --git a/plugins/github-dev/skills/release/SKILL.md b/plugins/github-dev/skills/release/SKILL.md index 88e869d6..f6468d3e 100644 --- a/plugins/github-dev/skills/release/SKILL.md +++ b/plugins/github-dev/skills/release/SKILL.md @@ -21,7 +21,7 @@ When this skill is loaded through Hermes as `github-dev:`, map Claude/Cod | Task | delegate_task | | Monitor | process | -Treat `$ARGUMENTS` as the natural-language arguments supplied when the user asks Hermes to load the skill. Plugin-provided skills are explicit opt-in loads in Hermes; use `skill_view("github-dev:")` (or ask Hermes to load that qualified skill) rather than relying on bare text like `github-dev: ...`. +Treat `$ARGUMENTS` as the natural-language arguments supplied when the user asks Hermes to run the skill. Installed into `~/.hermes/skills/` by `npx skills`, this skill is indexed automatically — it appears in `skills_list()` and as a slash command under its **flat** name (``, not `github-dev:`). Create a versioned GitHub release with automatic version detection, version file updates, tagging, and changelog generation via `gh release create --generate-notes`. diff --git a/plugins/github-dev/skills/resolve-issue/SKILL.md b/plugins/github-dev/skills/resolve-issue/SKILL.md index 42f89ce9..269585bd 100644 --- a/plugins/github-dev/skills/resolve-issue/SKILL.md +++ b/plugins/github-dev/skills/resolve-issue/SKILL.md @@ -21,7 +21,7 @@ When this skill is loaded through Hermes as `github-dev:`, map Claude/Cod | Task | delegate_task | | Monitor | process | -Treat `$ARGUMENTS` as the natural-language arguments supplied when the user asks Hermes to load the skill. Plugin-provided skills are explicit opt-in loads in Hermes; use `skill_view("github-dev:")` (or ask Hermes to load that qualified skill) rather than relying on bare text like `github-dev: ...`. +Treat `$ARGUMENTS` as the natural-language arguments supplied when the user asks Hermes to run the skill. Installed into `~/.hermes/skills/` by `npx skills`, this skill is indexed automatically — it appears in `skills_list()` and as a slash command under its **flat** name (``, not `github-dev:`). Act as an expert developer who systematically analyzes and resolves GitHub issues. Receive a GitHub issue number as argument and resolve the issue. Follow project guidelines in `@CLAUDE.md`. diff --git a/plugins/github-dev/skills/update-progress/SKILL.md b/plugins/github-dev/skills/update-progress/SKILL.md index d6df17e6..1b6f14b3 100644 --- a/plugins/github-dev/skills/update-progress/SKILL.md +++ b/plugins/github-dev/skills/update-progress/SKILL.md @@ -21,7 +21,7 @@ When this skill is loaded through Hermes as `github-dev:`, map Claude/Cod | Task | delegate_task | | Monitor | process | -Treat `$ARGUMENTS` as the natural-language arguments supplied when the user asks Hermes to load the skill. Plugin-provided skills are explicit opt-in loads in Hermes; use `skill_view("github-dev:")` (or ask Hermes to load that qualified skill) rather than relying on bare text like `github-dev: ...`. +Treat `$ARGUMENTS` as the natural-language arguments supplied when the user asks Hermes to run the skill. Installed into `~/.hermes/skills/` by `npx skills`, this skill is indexed automatically — it appears in `skills_list()` and as a slash command under its **flat** name (``, not `github-dev:`). Manually sync project progress to GitHub milestones and issues. Regenerates architecture diagrams and updates tracking sections. Follow project guidelines in `@CLAUDE.md`. diff --git a/plugins/interview/.claude-plugin/plugin.json b/plugins/interview/.claude-plugin/plugin.json index 517ecf29..aef096e9 100644 --- a/plugins/interview/.claude-plugin/plugin.json +++ b/plugins/interview/.claude-plugin/plugin.json @@ -1,5 +1,5 @@ { "name": "interview", - "version": "1.3.0", + "version": "1.3.1", "description": "Structured requirements gathering" } diff --git a/plugins/interview/.codex-plugin/plugin.json b/plugins/interview/.codex-plugin/plugin.json index be0a4e07..94b291c3 100644 --- a/plugins/interview/.codex-plugin/plugin.json +++ b/plugins/interview/.codex-plugin/plugin.json @@ -1,6 +1,6 @@ { "name": "interview", - "version": "1.3.0", + "version": "1.3.1", "description": "Structured requirements gathering", "author": { "name": "YoungjaeDev" diff --git a/plugins/interview/CLAUDE.md b/plugins/interview/CLAUDE.md index 94274816..23db068c 100644 --- a/plugins/interview/CLAUDE.md +++ b/plugins/interview/CLAUDE.md @@ -61,17 +61,13 @@ Full spec at `.claude/spec/{YYYY-MM-DD}-{feature-name}.md`: ## Hermes Agent -Install this plugin from the monorepo subdirectory: +Install the skill (`npx skills`, wrapped by the repo's installer): ```bash -hermes plugins install YoungjaeDev/my-claude-plugins/plugins/interview --enable -hermes gateway restart # if using Hermes through a messaging gateway +node scripts/install-skills.mjs # interactive picker +npx skills add YoungjaeDev/my-claude-plugins -a hermes-agent -s interview-methodology -g ``` -Load the skill explicitly (Hermes plugin skills are opt-in; start a fresh Hermes session after `--enable`): - -```text -skill_view("interview:interview-methodology") -``` +It lands in `~/.hermes/skills/interview-methodology/`, which Hermes indexes automatically — it shows up in `skills_list()` and as a slash command under its **flat** name `interview-methodology`, not `interview:interview-methodology`. The skill body carries a Hermes compatibility table mapping Claude/Codex tool terms (e.g. `AskUserQuestion`, `Read`, `Write`) to Hermes tools (`clarify`, `read_file`, `write_file`). diff --git a/plugins/interview/skills/interview-methodology/SKILL.md b/plugins/interview/skills/interview-methodology/SKILL.md index 8c75dc1f..7bdae4c2 100644 --- a/plugins/interview/skills/interview-methodology/SKILL.md +++ b/plugins/interview/skills/interview-methodology/SKILL.md @@ -21,7 +21,7 @@ When this skill is loaded through Hermes as `interview:interview-methodology`, m The last three cover the relentless mode's read-only fact-dispatch (dispatch a sub-agent, run a lookup, search) so a Hermes `grill me` session can follow rule 4 instead of stalling. -Treat `$ARGUMENTS` as the natural-language arguments supplied when the user asks Hermes to load the skill. Plugin-provided skills are explicit opt-in loads in Hermes; use `skill_view("interview:interview-methodology")` (or ask Hermes to load that qualified skill) rather than relying on bare text. +Treat `$ARGUMENTS` as the natural-language arguments supplied when the user asks Hermes to load the skill. Installed into `~/.hermes/skills/` by `npx skills`, this skill is indexed automatically — it appears in `skills_list()` and as a slash command under its **flat** name `interview-methodology`, not `interview:interview-methodology`. ## Cross-runtime interactive input diff --git a/plugins/ml-toolkit/.claude-plugin/plugin.json b/plugins/ml-toolkit/.claude-plugin/plugin.json index d6b838cf..f68c5783 100644 --- a/plugins/ml-toolkit/.claude-plugin/plugin.json +++ b/plugins/ml-toolkit/.claude-plugin/plugin.json @@ -1,5 +1,5 @@ { "name": "ml-toolkit", - "version": "1.4.3", + "version": "1.4.4", "description": "ML/multimodal development principles, GPU parallel processing, Gradio CV apps, CV notebook generation, interactive CV data exploration" } diff --git a/plugins/ml-toolkit/.codex-plugin/plugin.json b/plugins/ml-toolkit/.codex-plugin/plugin.json index d6a28d1f..f840ca3d 100644 --- a/plugins/ml-toolkit/.codex-plugin/plugin.json +++ b/plugins/ml-toolkit/.codex-plugin/plugin.json @@ -1,6 +1,6 @@ { "name": "ml-toolkit", - "version": "1.4.3", + "version": "1.4.4", "description": "ML/multimodal development principles, GPU parallel processing, Gradio CV apps, CV notebook generation, interactive CV data exploration", "author": { "name": "YoungjaeDev" diff --git a/plugins/ml-toolkit/CLAUDE.md b/plugins/ml-toolkit/CLAUDE.md index 9a227548..095f5b8c 100644 --- a/plugins/ml-toolkit/CLAUDE.md +++ b/plugins/ml-toolkit/CLAUDE.md @@ -97,22 +97,16 @@ See `core-config/guidelines/ml-guidelines.md` for common ML pitfalls (BGR/RGB, b ## Hermes Agent -Install this plugin from the monorepo subdirectory: +Install the skills you want (`npx skills`, wrapped by the repo's installer): ```bash -hermes plugins install YoungjaeDev/my-claude-plugins/plugins/ml-toolkit --enable -hermes gateway restart # if using Hermes through a messaging gateway +node scripts/install-skills.mjs # interactive picker +npx skills add YoungjaeDev/my-claude-plugins -a hermes-agent \ + -s ml-dev-principles -s gpu-parallel-pipeline -s cv-explorer \ + -s cv-notebook -s gradio-cv-app -g # or name them directly ``` -Load a skill explicitly (Hermes plugin skills are opt-in; start a fresh Hermes session after `--enable`): - -```text -skill_view("ml-toolkit:ml-dev-principles") -skill_view("ml-toolkit:gpu-parallel-pipeline") -skill_view("ml-toolkit:cv-explorer") -skill_view("ml-toolkit:cv-notebook") -skill_view("ml-toolkit:gradio-cv-app") -``` +They land in `~/.hermes/skills//`, which Hermes indexes automatically — each shows up in `skills_list()` and as a slash command under its **flat** name (`ml-dev-principles`, `gpu-parallel-pipeline`, `cv-explorer`, `cv-notebook`, `gradio-cv-app`), not `ml-toolkit:`. Notes: - Skill bodies carry a Hermes compatibility table mapping Claude/Codex tool terms (`Bash`, `Write`, `NotebookEdit`, ...) to Hermes tools (`terminal`, `write_file`, ...). diff --git a/plugins/ml-toolkit/skills/cv-explorer/SKILL.md b/plugins/ml-toolkit/skills/cv-explorer/SKILL.md index 0b34e93b..5a4efe9f 100644 --- a/plugins/ml-toolkit/skills/cv-explorer/SKILL.md +++ b/plugins/ml-toolkit/skills/cv-explorer/SKILL.md @@ -16,7 +16,7 @@ When this skill is loaded through Hermes as `ml-toolkit:cv-explorer`, map Claude | Edit | patch | | NotebookEdit | Hermes "Jupyter Live Kernel" skill, or write_file / patch on the .ipynb JSON | -Treat `$ARGUMENTS` as the natural-language arguments supplied when the user asks Hermes to load the skill. Plugin-provided skills are explicit opt-in loads in Hermes; use `skill_view("ml-toolkit:cv-explorer")` (or ask Hermes to load that qualified skill) rather than relying on bare text. +Treat `$ARGUMENTS` as the natural-language arguments supplied when the user asks Hermes to load the skill. Installed into `~/.hermes/skills/` by `npx skills`, this skill is indexed automatically — it appears in `skills_list()` and as a slash command under its **flat** name `cv-explorer`, not `ml-toolkit:cv-explorer`. > **NotebookEdit across runtimes**: Claude and Codex use the `NotebookEdit` tool to author `.ipynb` cells (the global rule forbids hand-editing notebook JSON under Claude). Under Hermes there is no `NotebookEdit` tool — use the Hermes "Jupyter Live Kernel" skill, or write/patch the `.ipynb` JSON directly with `write_file` / `patch` (Hermes' Claude/GPT brain can emit valid notebook JSON). diff --git a/plugins/ml-toolkit/skills/cv-notebook/SKILL.md b/plugins/ml-toolkit/skills/cv-notebook/SKILL.md index ff4892f1..ea34baee 100644 --- a/plugins/ml-toolkit/skills/cv-notebook/SKILL.md +++ b/plugins/ml-toolkit/skills/cv-notebook/SKILL.md @@ -16,7 +16,7 @@ When this skill is loaded through Hermes as `ml-toolkit:cv-notebook`, map Claude | Edit | patch | | NotebookEdit | Hermes "Jupyter Live Kernel" skill, or write_file / patch on the .ipynb JSON | -Treat `$ARGUMENTS` as the natural-language arguments supplied when the user asks Hermes to load the skill. Plugin-provided skills are explicit opt-in loads in Hermes; use `skill_view("ml-toolkit:cv-notebook")` (or ask Hermes to load that qualified skill) rather than relying on bare text. +Treat `$ARGUMENTS` as the natural-language arguments supplied when the user asks Hermes to load the skill. Installed into `~/.hermes/skills/` by `npx skills`, this skill is indexed automatically — it appears in `skills_list()` and as a slash command under its **flat** name `cv-notebook`, not `ml-toolkit:cv-notebook`. > **NotebookEdit across runtimes**: Claude and Codex use the `NotebookEdit` tool to author `.ipynb` cells (the global rule forbids hand-editing notebook JSON under Claude). Under Hermes there is no `NotebookEdit` tool — use the Hermes "Jupyter Live Kernel" skill, or write/patch the `.ipynb` JSON directly with `write_file` / `patch` (Hermes' Claude/GPT brain can emit valid notebook JSON). diff --git a/plugins/ml-toolkit/skills/gpu-parallel-pipeline/SKILL.md b/plugins/ml-toolkit/skills/gpu-parallel-pipeline/SKILL.md index f90103f7..df5ea700 100644 --- a/plugins/ml-toolkit/skills/gpu-parallel-pipeline/SKILL.md +++ b/plugins/ml-toolkit/skills/gpu-parallel-pipeline/SKILL.md @@ -16,7 +16,7 @@ When this skill is loaded through Hermes as `ml-toolkit:gpu-parallel-pipeline`, | Write | write_file | | Edit | patch | -Treat `$ARGUMENTS` as the natural-language arguments supplied when the user asks Hermes to load the skill. Plugin-provided skills are explicit opt-in loads in Hermes; use `skill_view("ml-toolkit:gpu-parallel-pipeline")` (or ask Hermes to load that qualified skill) rather than relying on bare text. +Treat `$ARGUMENTS` as the natural-language arguments supplied when the user asks Hermes to load the skill. Installed into `~/.hermes/skills/` by `npx skills`, this skill is indexed automatically — it appears in `skills_list()` and as a slash command under its **flat** name `gpu-parallel-pipeline`, not `ml-toolkit:gpu-parallel-pipeline`. ## Overview diff --git a/plugins/ml-toolkit/skills/gradio-cv-app/SKILL.md b/plugins/ml-toolkit/skills/gradio-cv-app/SKILL.md index 02d500a3..994ba5a8 100644 --- a/plugins/ml-toolkit/skills/gradio-cv-app/SKILL.md +++ b/plugins/ml-toolkit/skills/gradio-cv-app/SKILL.md @@ -15,7 +15,7 @@ When this skill is loaded through Hermes as `ml-toolkit:gradio-cv-app`, map Clau | Write | write_file | | Edit | patch | -Treat `$ARGUMENTS` as the natural-language arguments supplied when the user asks Hermes to load the skill. Plugin-provided skills are explicit opt-in loads in Hermes; use `skill_view("ml-toolkit:gradio-cv-app")` (or ask Hermes to load that qualified skill) rather than relying on bare text. +Treat `$ARGUMENTS` as the natural-language arguments supplied when the user asks Hermes to load the skill. Installed into `~/.hermes/skills/` by `npx skills`, this skill is indexed automatically — it appears in `skills_list()` and as a slash command under its **flat** name `gradio-cv-app`, not `ml-toolkit:gradio-cv-app`. A skill for creating professional Gradio computer vision apps. Combines PRITHIVSAKTHIUR's functional patterns with Editorial design principles. diff --git a/plugins/ml-toolkit/skills/ml-dev-principles/SKILL.md b/plugins/ml-toolkit/skills/ml-dev-principles/SKILL.md index 171395b9..ce283b15 100644 --- a/plugins/ml-toolkit/skills/ml-dev-principles/SKILL.md +++ b/plugins/ml-toolkit/skills/ml-dev-principles/SKILL.md @@ -15,7 +15,7 @@ When this skill is loaded through Hermes as `ml-toolkit:ml-dev-principles`, map | Read | read_file | | Write | write_file | -Treat `$ARGUMENTS` as the natural-language arguments supplied when the user asks Hermes to load the skill. Plugin-provided skills are explicit opt-in loads in Hermes; use `skill_view("ml-toolkit:ml-dev-principles")` (or ask Hermes to load that qualified skill) rather than relying on bare text. +Treat `$ARGUMENTS` as the natural-language arguments supplied when the user asks Hermes to load the skill. Installed into `~/.hermes/skills/` by `npx skills`, this skill is indexed automatically — it appears in `skills_list()` and as a slash command under its **flat** name `ml-dev-principles`, not `ml-toolkit:ml-dev-principles`. ML·멀티모달·CV 작업을 *어떻게* 진행할지에 대한 범용 규율(어떤 라이브러리를 쓰느냐가 아니라). 작업 시작 시 한 번 훑고 적용한다. 한 문장 요약: **집계/규칙 텍스트만 보지 말고 실제(이미지·원문·util)를 직접 봐라.** diff --git a/plugins/paper-search-tools/.claude-plugin/plugin.json b/plugins/paper-search-tools/.claude-plugin/plugin.json index 10c80d65..43ec84f2 100644 --- a/plugins/paper-search-tools/.claude-plugin/plugin.json +++ b/plugins/paper-search-tools/.claude-plugin/plugin.json @@ -1,6 +1,6 @@ { "name": "paper-search-tools", - "version": "1.1.0", + "version": "1.1.1", "description": "Academic paper search (arXiv, PubMed, Semantic Scholar, etc.)", "license": "Apache-2.0" } diff --git a/plugins/paper-search-tools/.codex-plugin/plugin.json b/plugins/paper-search-tools/.codex-plugin/plugin.json index b13187b2..d2f4f650 100644 --- a/plugins/paper-search-tools/.codex-plugin/plugin.json +++ b/plugins/paper-search-tools/.codex-plugin/plugin.json @@ -1,6 +1,6 @@ { "name": "paper-search-tools", - "version": "1.1.0", + "version": "1.1.1", "description": "Academic paper search (arXiv, PubMed, Semantic Scholar, etc.)", "author": { "name": "YoungjaeDev" diff --git a/plugins/paper-search-tools/skills/setup/SKILL.md b/plugins/paper-search-tools/skills/setup/SKILL.md index 071ab642..71c29f88 100644 --- a/plugins/paper-search-tools/skills/setup/SKILL.md +++ b/plugins/paper-search-tools/skills/setup/SKILL.md @@ -137,8 +137,11 @@ registration and the connect/disable surface differ per runtime: already points `mcpServers` at the same `.mcp.json`, so the server is registered automatically — do **not** add a second manual entry. Just run the step 5 handshake to verify. Only a standalone (non-plugin) Codex needs a manual MCP entry with the step-4 `docker run` args. -- **Hermes** — load the skill explicitly (`skill_view("paper-search-tools:setup")`), register the - server per Hermes' MCP configuration with the step-4 `docker run` args, and verify with step 5. +- **Hermes** — install this skill with `npx skills` (it lands in `~/.hermes/skills/setup/` and is + indexed automatically, under the flat name `setup`), register the server per Hermes' MCP + configuration with the step-4 `docker run` args, and verify with step 5. Note that `npx skills` + carries skills only — the bundled `.mcp.json` does not travel with it, which is why the MCP entry + is registered by hand here. ### Hermes tool-name compatibility diff --git a/plugins/ppt-yeong-style/.claude-plugin/plugin.json b/plugins/ppt-yeong-style/.claude-plugin/plugin.json index e9c85feb..3d1ec1cb 100644 --- a/plugins/ppt-yeong-style/.claude-plugin/plugin.json +++ b/plugins/ppt-yeong-style/.claude-plugin/plugin.json @@ -1,6 +1,6 @@ { "name": "ppt-yeong-style", - "version": "0.9.3", + "version": "0.9.4", "description": "yeong 스타일 강의·제안 덱 작성 규약 — ppt-master 빌드 엔진 위에 얹는 작성 레이어(엔진 자체가 아님). 스킬 3종: 메인 ppt-yeong-style(미감 시그니처 §0 'Editorial restraint, one committed accent'·md 소스 규약·작성 원칙 16종·밀도 리듬·역할 기반 색·codex-image vs SVG 경계·앱 UI 실물 강제·레버 조합 차별화·윤문·렌더 QA + references/ 6종 + 주입 페이로드) + lecture-deck(강의 덱 운영 — 실습 handouts 생성 규약·프롬프트 카드·placeholder→실캡처 스크린샷 슬롯·리넘버링 4중 동기화·전사 회고 루프·강사 노트 태그 + cc-common 47장 레퍼런스) + deck-review(관점별 리뷰 서브에이전트 4종 audience-fit·story-flow·fact-check·design-qa 병렬 오케스트레이션 + codex:rescue 교차 리뷰, 페르소나는 파라미터). 의존 스킬은 있으면 사용, 없으면 생략 + 설치 제안 문구(ppt-master만 prerequisite-stop). ppt-master로 그냥 'PPT 만들기'와 달리 yeong 규약이 필요할 때.", "skills": [ "./skills/ppt-yeong-style", diff --git a/plugins/ppt-yeong-style/.codex-plugin/plugin.json b/plugins/ppt-yeong-style/.codex-plugin/plugin.json index 21bc3013..7a12b7c3 100644 --- a/plugins/ppt-yeong-style/.codex-plugin/plugin.json +++ b/plugins/ppt-yeong-style/.codex-plugin/plugin.json @@ -1,6 +1,6 @@ { "name": "ppt-yeong-style", - "version": "0.9.3", + "version": "0.9.4", "description": "yeong 스타일 강의·제안 덱 작성 규약 — ppt-master 빌드 엔진 위에 얹는 작성 레이어(엔진 자체가 아님). 스킬 3종: 메인 ppt-yeong-style(미감 시그니처 §0 'Editorial restraint, one committed accent'·md 소스 규약·작성 원칙 16종·밀도 리듬·역할 기반 색·codex-image vs SVG 경계·앱 UI 실물 강제·레버 조합 차별화·윤문·렌더 QA + references/ 6종 + 주입 페이로드) + lecture-deck(강의 덱 운영 — 실습 handouts 생성 규약·프롬프트 카드·placeholder→실캡처 스크린샷 슬롯·리넘버링 4중 동기화·전사 회고 루프·강사 노트 태그 + cc-common 47장 레퍼런스) + deck-review(관점별 리뷰 서브에이전트 4종 audience-fit·story-flow·fact-check·design-qa 병렬 오케스트레이션 + codex:rescue 교차 리뷰, 페르소나는 파라미터). 의존 스킬은 있으면 사용, 없으면 생략 + 설치 제안 문구(ppt-master만 prerequisite-stop). ppt-master로 그냥 'PPT 만들기'와 달리 yeong 규약이 필요할 때.", "author": { "name": "YoungjaeDev" diff --git a/plugins/ppt-yeong-style/CLAUDE.md b/plugins/ppt-yeong-style/CLAUDE.md index 232c2c4b..c00234e2 100644 --- a/plugins/ppt-yeong-style/CLAUDE.md +++ b/plugins/ppt-yeong-style/CLAUDE.md @@ -50,18 +50,14 @@ ppt-yeong-style/ ## Hermes Agent -monorepo 서브디렉토리에서 플러그인을 설치: +스킬을 설치 (`npx skills`, 저장소 설치기가 래핑): ```bash -hermes plugins install YoungjaeDev/my-claude-plugins/plugins/ppt-yeong-style --enable -hermes gateway restart # 메시징 게이트웨이로 Hermes를 쓰는 경우 +node scripts/install-skills.mjs # 대화형 선택 +npx skills add YoungjaeDev/my-claude-plugins -a hermes-agent -s ppt-yeong-style -g ``` -스킬을 명시적으로 로드 (Hermes plugin skill은 opt-in, `--enable` 후 새 Hermes 세션 시작): - -```text -skill_view("ppt-yeong-style:ppt-yeong-style") -``` +`~/.hermes/skills/ppt-yeong-style/` 에 설치되고 Hermes가 자동으로 인덱싱한다 — `skills_list()` 에 노출되고 슬래시 커맨드로도 잡힌다. 이름은 **평평**해서 `ppt-yeong-style:ppt-yeong-style` 이 아니라 `ppt-yeong-style` 이다. - 스킬 본문은 Claude/Codex 도구 용어(`Bash`, `Read`, `AskUserQuestion`, 이미지 생성, `Skill`)를 Hermes 도구(`terminal`, `read_file`, `clarify`, `image_generate`, `skill_view`)로 매핑하는 호환 표를 포함한다. - 전제: 빌드 엔진인 외부 `ppt-master` 플러그인 enable + `uv` 설치가 필요하다. 미설치 시 빌드 진입 전 중단. diff --git a/plugins/ppt-yeong-style/skills/ppt-yeong-style/SKILL.md b/plugins/ppt-yeong-style/skills/ppt-yeong-style/SKILL.md index 3ea17b71..f3e1be1c 100644 --- a/plugins/ppt-yeong-style/skills/ppt-yeong-style/SKILL.md +++ b/plugins/ppt-yeong-style/skills/ppt-yeong-style/SKILL.md @@ -17,9 +17,9 @@ When this skill is loaded through Hermes as `ppt-yeong-style:ppt-yeong-style`, m | Skill | skill_view (list available via skills_list) | | (image generation) | image_generate | -Treat `$ARGUMENTS` as the natural-language arguments supplied when the user asks Hermes to load the skill. Plugin-provided skills are explicit opt-in loads in Hermes; use `skill_view("ppt-yeong-style:ppt-yeong-style")` (or ask Hermes to load that qualified skill) rather than relying on bare text. +Treat `$ARGUMENTS` as the natural-language arguments supplied when the user asks Hermes to load the skill. Installed into `~/.hermes/skills/` by `npx skills`, this skill is indexed automatically — it appears in `skills_list()` and as a slash command under its **flat** name `ppt-yeong-style`. -**Hermes 전제**: 이 스킬은 외부 `ppt-master` 플러그인의 빌드 엔진(`uv run` 스크립트)에 의존한다. Hermes 세션에서는 (1) `ppt-master` 플러그인이 enable 되어 있고 (2) `uv`가 설치되어 있어야 한다. 둘 중 하나라도 없으면 빌드 단계 진입 전에 중단하고 사용자에게 설치를 요청한다 (`skill_view("ppt-master:ppt-master")`로 엔진 스킬 로드 가능). +**Hermes 전제**: 이 스킬은 외부 `ppt-master` 플러그인의 빌드 엔진(`uv run` 스크립트)에 의존한다. Hermes 세션에서는 (1) `ppt-master` 플러그인이 enable 되어 있고 (2) `uv`가 설치되어 있어야 한다. 둘 중 하나라도 없으면 빌드 단계 진입 전에 중단하고 사용자에게 설치를 요청한다. ## 목차 diff --git a/plugins/tcrei-prompt/.claude-plugin/plugin.json b/plugins/tcrei-prompt/.claude-plugin/plugin.json index 1b2fbe99..2fe8f32f 100644 --- a/plugins/tcrei-prompt/.claude-plugin/plugin.json +++ b/plugins/tcrei-prompt/.claude-plugin/plugin.json @@ -1,5 +1,5 @@ { "name": "tcrei-prompt", - "version": "1.1.2", + "version": "1.1.3", "description": "Rewrite prompts using Google's TCREI structure for next-session reuse" } diff --git a/plugins/tcrei-prompt/.codex-plugin/plugin.json b/plugins/tcrei-prompt/.codex-plugin/plugin.json index a8dade0e..afaa592e 100644 --- a/plugins/tcrei-prompt/.codex-plugin/plugin.json +++ b/plugins/tcrei-prompt/.codex-plugin/plugin.json @@ -1,6 +1,6 @@ { "name": "tcrei-prompt", - "version": "1.1.2", + "version": "1.1.3", "description": "Rewrite prompts using Google's TCREI structure for next-session reuse", "author": { "name": "YoungjaeDev" diff --git a/plugins/tcrei-prompt/CLAUDE.md b/plugins/tcrei-prompt/CLAUDE.md index ebdfd7dd..fa161720 100644 --- a/plugins/tcrei-prompt/CLAUDE.md +++ b/plugins/tcrei-prompt/CLAUDE.md @@ -37,17 +37,13 @@ Google's Prompting Essentials (Coursera) 5-step structure: ## Hermes Agent -Install this plugin from the monorepo subdirectory: +Install the skill (`npx skills`, wrapped by the repo's installer): ```bash -hermes plugins install YoungjaeDev/my-claude-plugins/plugins/tcrei-prompt --enable -hermes gateway restart # if using Hermes through a messaging gateway +node scripts/install-skills.mjs # interactive picker +npx skills add YoungjaeDev/my-claude-plugins -a hermes-agent -s tcrei-prompt -g ``` -Load the skill explicitly (Hermes plugin skills are opt-in; start a fresh Hermes session after `--enable`): - -```text -skill_view("tcrei-prompt:tcrei-prompt") -``` +It lands in `~/.hermes/skills/tcrei-prompt/`, which Hermes indexes automatically — it shows up in `skills_list()` and as a slash command under its **flat** name `tcrei-prompt`, not `tcrei-prompt:tcrei-prompt`. The skill body carries a Hermes compatibility table mapping Claude/Codex tool terms (`Write`, `AskUserQuestion`, `Read`) to Hermes tools (`write_file`, `clarify`, `read_file`). Phase 3 self-verification runs inline (no `Task`/subagent) so it is portable across all three runtimes. diff --git a/plugins/tcrei-prompt/skills/tcrei-prompt/SKILL.md b/plugins/tcrei-prompt/skills/tcrei-prompt/SKILL.md index 3871b2c5..b082de42 100644 --- a/plugins/tcrei-prompt/skills/tcrei-prompt/SKILL.md +++ b/plugins/tcrei-prompt/skills/tcrei-prompt/SKILL.md @@ -26,7 +26,7 @@ When this skill is loaded through Hermes as `tcrei-prompt:tcrei-prompt`, map Cla | Write | write_file | | AskUserQuestion | clarify | -Treat `$ARGUMENTS` as the natural-language arguments supplied when the user asks Hermes to load the skill. Plugin-provided skills are explicit opt-in loads in Hermes; use `skill_view("tcrei-prompt:tcrei-prompt")` (or ask Hermes to load that qualified skill) rather than relying on bare text. +Treat `$ARGUMENTS` as the natural-language arguments supplied when the user asks Hermes to load the skill. Installed into `~/.hermes/skills/` by `npx skills`, this skill is indexed automatically — it appears in `skills_list()` and as a slash command under its **flat** name `tcrei-prompt`. Rewrites rough prompts into Google's TCREI 5-step structure and outputs copy-paste-ready prompts for the next session. Based on Google's Prompting From 425f88eab3eed043dbc0c8a4a6835ba2f4faf433 Mon Sep 17 00:00:00 2001 From: YoungjaeDev Date: Mon, 27 Jul 2026 11:06:51 +0900 Subject: [PATCH 09/12] =?UTF-8?q?docs(wiki):=20add=20Mode=207=20=E2=80=94?= =?UTF-8?q?=20removal=20sweeps=20must=20grep=20the=20callers?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Diff-logged first, then applied. PR #168's removal sweep grepped the deleted artifact names (sync-hermes, HERMES_ELIGIBLE, plugin.yaml) and reported clean, while 24 files across 7 plugins still carried the commands that consume those artifacts — `hermes plugins install` and `skill_view(":")`. Neither string contains any searched token, so the sweep could not see them. Codex review caught it. Mode 6 is the right query at too narrow a scope; Mode 7 is full scope with the wrong noun. The same PR also repeated Mode 6 verbatim (no --hidden, missed .coderabbit.yaml and .claude/rules/plugin-versioning.md) despite this page already documenting it — recorded in the sources entry, since a lesson that did not transfer is itself evidence about the page. sources 5 -> 6, last_verified 2026-07-27. MOC hook extended. Refs #166 --- .llmwiki/wiki/index.md | 2 +- .llmwiki/wiki/log.md | 8 ++++++++ .../detector-cannot-look-vs-nothing-wrong.md | 11 +++++++++-- 3 files changed, 18 insertions(+), 3 deletions(-) diff --git a/.llmwiki/wiki/index.md b/.llmwiki/wiki/index.md index 21ac55ff..8a8de028 100644 --- a/.llmwiki/wiki/index.md +++ b/.llmwiki/wiki/index.md @@ -88,7 +88,7 @@ Operational lore for the plugin system itself — cache, loading, version resolu - [mem0 hook latency budget](plugin-ops/mem0-hook-latency-budget.md) — mem0 플러그인 UserPromptSubmit 훅의 8s 예산은 worst-case(resume 2연속 검색 ~10s + rerank 기본 on)를 못 버틴다; 레버는 캐시 파일이 아니라 사용자 소유 settings.json env(`MEM0_RERANK=off`)에 둔다. 플러그인의 rerank-on 기본값은 mem0 공식 Best Practice와 반대. 단 env-lever는 플래그별로 다름 — `auto_save`는 `_identity.sh`가 `~/.mem0/settings.json` 값으로 env를 매 훅 덮어써서 그 파일이 SOT. - [Worktree lifecycle gotchas around squash-merge](plugin-ops/worktree-squash-merge-gotchas.md) — `EnterWorktree`'s default `baseRef: fresh` branches from `origin/`, not local HEAD, so local-only unpushed commits are invisible until rebased in; `gh pr merge --delete-branch` run inside a worktree can switch that worktree's checkout to the base branch and fail a local fast-forward, triggering an `ExitWorktree` ancestry false-positive resolved via bidirectional content-diff + `git reset --hard origin/main`; and squash-merging a base PR with `--delete-branch` auto-CLOSES stacked child PRs instead of retargeting them. - [AGENTS.md is loaded verbatim](plugin-ops/agents-md-verbatim-no-import.md) — Codex has no `@import` mechanism at all (`agents_md.rs` byte-reads and concatenates), Hermes shows no evidence of one, and Claude never reads `AGENTS.md`; so an `@CLAUDE.md` pointer silently strips all guidance from both, and a prose redirect still misses the Codex cloud reviewer (it loads `## Review guidelines` into its system prompt, it doesn't walk files). The only loader-valid direction is `CLAUDE.md` importing `@AGENTS.md`. -- [A detector must never say "nothing wrong" when it means "could not look"](plugin-ops/detector-cannot-look-vs-nothing-wrong.md) — `set -euo pipefail` turns `find`'s exit-1-on-no-match and `jq`'s exit-on-corrupt-input into a whole-script abort that prints zero bytes; patching it with `|| true` then converts the failure into a confident "no duplicates". Guard on the question you are asking ("can I enumerate `mcpServers` as an object?", not "is this valid JSON?"), contain each failure in its axis, and report `unreadable` as its own state. Same family: a valid TOML `65_536 # bytes` is not valid JSON for `--argjson`, and `${f#$HOME/}` is a pattern expansion. Mode 4 extends it to remote fetchers — a degraded API answer that still parses (GraphQL null envelope, missing pageInfo, probe rc 0) must not read as "clean". Mode 5: the check's own tool is non-portable (`realpath -m` aborts on BSD), so its gate skips every item and the loop converges auto-merge-eligible `clean` — verify tool portability under stock userland. +- [A detector must never say "nothing wrong" when it means "could not look"](plugin-ops/detector-cannot-look-vs-nothing-wrong.md) — `set -euo pipefail` turns `find`'s exit-1-on-no-match and `jq`'s exit-on-corrupt-input into a whole-script abort that prints zero bytes; patching it with `|| true` then converts the failure into a confident "no duplicates". Guard on the question you are asking ("can I enumerate `mcpServers` as an object?", not "is this valid JSON?"), contain each failure in its axis, and report `unreadable` as its own state. Same family: a valid TOML `65_536 # bytes` is not valid JSON for `--argjson`, and `${f#$HOME/}` is a pattern expansion. Mode 4 extends it to remote fetchers — a degraded API answer that still parses (GraphQL null envelope, missing pageInfo, probe rc 0) must not read as "clean". Mode 5: the check's own tool is non-portable (`realpath -m` aborts on BSD), so its gate skips every item and the loop converges auto-merge-eligible `clean` — verify tool portability under stock userland. Modes 6-7 move the trap into ad-hoc verification commands: recursive `rg` skips dot-dirs unless `--hidden` (so a removal gate never looks at the generated manifests), and a removal sweep that greps only the deleted artifact's *name* misses every surviving *caller* of it (`hermes plugins install`, a `paths:` glob) — run two queries, the identifiers and the call sites. - [Verify shell portability under stock userland](plugin-ops/stock-userland-verification.md) — an interactive shell can shadow `grep` with a `ugrep` function that accepts `-P`, so a `grep -oP` line dead on BSD userland looks healthy when tested by hand; hooks run as child processes that do not inherit the function, and Codex/Hermes have no shim. A portability claim verified in the interactive shell is unsound — re-verify under `env -i PATH=/usr/bin:/bin`, the environment hooks and other runtimes actually get. - [jq `capture()` on a non-match yields nothing](plugin-ops/jq-capture-yields-empty.md) — it neither throws nor returns null, so `try … catch null` never fires; and an `empty` inside an object constructor deletes the whole object, silently dropping the element from `[ .[] | {…} ]`. Wrap every `capture()` in `first_or_null(f): ([f?] | .[0])`. The long-standing "capture() THROWS" comment in `sniff-cr-rate-limit.sh` explained a correct line with the wrong mechanism. Third member: without `-r`, an empty string result prints as the two-char literal `""` and passes `[ -n ]` — jq output feeding a shell truthiness test must use `-r`. - [SubagentStop hook payload contract](plugin-ops/subagentstop-hook-payload.md) — docs are silent on the two facts that matter: `SubagentStop`'s `transcript_path`/`session_id` are the PARENT's, and the subagent's own transcript is under `agent_transcript_path` (`.../subagents/agent-.jsonl`, present at fire time). A capture hook must prefer `agent_transcript_path` + key by `agent_id` (session_id collides with the parent). Verified empirically. diff --git a/.llmwiki/wiki/log.md b/.llmwiki/wiki/log.md index ca2022ed..39e619db 100644 --- a/.llmwiki/wiki/log.md +++ b/.llmwiki/wiki/log.md @@ -6,6 +6,14 @@ Every `/ingest-finding` run and every `/github-dev:post-merge` run that executes --- +## 2026-07-27 — #166 review: removal sweeps must grep the callers, not just the artifact (ingest-finding) + +Diff log written before applying the page edit (git-revertible). Second ingest of the day, from PR #168's review round rather than its authoring. A removal sweep that grepped only the deleted artifact names (`sync-hermes`, `HERMES_ELIGIBLE`, `plugin.yaml`) reported clean while 24 files across 7 plugins still instructed users to run `hermes plugins install` and `skill_view(":")` — the *callers* of the deleted artifact. Codex review caught it. Same page as the existing default-scope trap because both are the same question: "did the detector look where the breakage actually is?" + +- plugin-ops/detector-cannot-look-vs-nothing-wrong.md: add Mode 7 (removal sweep greps the artifact's name but not the user-facing commands that depend on it) + a `## Sources` entry for PR #168; sources 5→6, last_verified 2026-07-24 → 2026-07-27. + +No insight graduation: Mode 6 (the sibling trap) has not graduated either, and the page is already the consolidated home for this failure family. + ## 2026-07-27 — #166: Hermes plugin adapter retired, npx skills is the sole Hermes path (ingest-finding) Diff log written before applying the page edits (git-revertible). PR #166 deletes `scripts/sync-hermes-manifests.mjs`, `scripts/mock-load-hermes.py`, and the 7 generated `plugin.yaml` + `__init__.py` adapter pairs, plus the `HERMES_ELIGIBLE` allowlist and both Hermes CI/pre-commit guards. Hermes now gets skills only through `npx skills` (`scripts/install-skills.mjs`). Supersede, not overwrite — the adapter page keeps real historical value (the `register_skill` signature settlement, the git-pull-only update model, the generated-but-never-executed blind spot). diff --git a/.llmwiki/wiki/plugin-ops/detector-cannot-look-vs-nothing-wrong.md b/.llmwiki/wiki/plugin-ops/detector-cannot-look-vs-nothing-wrong.md index e852476b..482a0367 100644 --- a/.llmwiki/wiki/plugin-ops/detector-cannot-look-vs-nothing-wrong.md +++ b/.llmwiki/wiki/plugin-ops/detector-cannot-look-vs-nothing-wrong.md @@ -1,10 +1,10 @@ --- id: detector-cannot-look-vs-nothing-wrong aliases: [pipefail-kills-detector, jq-failure-in-command-substitution, argjson-strict-json, read-only-detector-silent-failure, fetcher-false-clean] -last_verified: 2026-07-24 +last_verified: 2026-07-27 status: active volatility: stable -sources: 5 +sources: 6 --- # A detector must never report "nothing wrong" when it means "could not look" @@ -73,6 +73,12 @@ The meta-lesson beyond containment: **a detector written and tested on one platf Modes 1-5 are committed detector *scripts*; Mode 6 is the same trap in an ad-hoc verification *command*. A removal/parity gate over this repo — "prove the retired vendor token is gone" — was run as `rg -i firecrawl --glob '!docs/**' …`, which returned 0 hits and read as "fully removed." But **recursive ripgrep skips dot-directories by default**, so the grep never looked in `.claude-plugin/marketplace.json`, `.agents/`, or `.claude/settings.json` — exactly where the generated manifests and the tracked load-list live. A stale `firecrawl tier-3` string survived in the code-scout manifest description and passed the parity gate; it was caught only by re-running with `rg --hidden`. A true parity/removal gate over this repo must pass `--hidden` (the generated Codex/Hermes manifests + settings live under dot-dirs). Sibling trap in the same PR: a plugin CHANGELOG that names the retired vendor token *in prose* re-breaks a repo-wide token-parity check — describe a removed dependency by its slot ("the tier-3 fetch tool"), not its vendor name. Distinct from the `rg`-is-a-shell-function shadowing in [[stock-userland-verification]]: here the tool runs fine, its **default coverage** is the blind spot. +## Mode 7: the sweep greps the artifact's name but not its callers — "0 hits" because it searched the wrong noun + +Mode 6 is the right query with too narrow a *scope*; Mode 7 is full scope with the wrong *query*. Retiring a mechanism (PR #166, the Hermes plugin adapter) was verified by grepping the deleted artifact names — `sync-hermes`, `HERMES_ELIGIBLE`, `plugin.yaml`, `__init__.py` — which came back clean. But 24 files across 7 plugins still carried the *user-facing commands that depend on those artifacts*: `hermes plugins install .../plugins/ --enable` (needs the deleted `plugin.yaml`) and `skill_view(":")` (a qualified name that no longer exists once skills install flat). None of those lines contains any of the searched tokens, so the sweep could not see them. A user following the surviving docs fails immediately. + +The rule: **a removal sweep needs two queries — the artifact's identifiers, and the call sites that consume it.** Write the second query by asking "what would a user or a script have typed to *use* this thing?", not "what is this thing called". Instruction repos make this sharper than code repos, where a compiler or import error would have surfaced the dangling caller; prose has no such backstop, so the grep is the only gate. Related failure of the same shape: a `> See-also:` or `paths:` glob pointing at a deleted file, which likewise carries none of the artifact's own tokens. + ## Why this recurs Each instance arrives disguised as an edge case ("who has a corrupt config?", "who greps a dot-dir?"), and each one is discovered only by running the check against the input it silently skips rather than reading it. The invariant is cheap to state and hard to remember: **a diagnostic that cannot evaluate an axis — whether because it aborted, degraded, could not run, or never looked there — says so, keeps going, and never converts ignorance into an all-clear.** @@ -92,3 +98,4 @@ Each instance arrives disguised as an edge case ("who has a corrupt config?", "w 3. **PR #122** (`fix(github-dev): cr-fix correctness repair set`) — the remote-fetcher instances (Mode 4): `fetch-cr-threads.sh` null-envelope false-clean + pagination coherence (fixtures `gql-null-repository` / `gql-null-pullrequest` / `gql-missing-pageinfo` / `gql-cursorless-next`), `auto-merge-gate.sh` probe rc 0 (`probe failure -> protection_http 0`), `cr-commit-state.sh` `state:"error"` channel + `ERROR_STREAK_MAX` terminal poller test. 4. **PR #153** (`fix(github-dev): cr-fix path-trust works on BSD/macOS userland`) — the non-portable-tool instance (Mode 5): `path-trust.sh` `realpath -m` aborted under `set -e` on BSD/macOS for every path, so the Step 9c gate skipped every finding and Step 13 converged `final_state=clean` (auto-merge eligible). Fixed with a POSIX `cd`+`pwd -P`+`readlink` resolver that also follows a final-component symlink chain (a Critical the fix's own review surfaced), plus the first test coverage for the gate (12 cases, RED-verified against both prior revisions). Surfaced by a macOS-26 compatibility audit of all 24 plugins. 5. **PR #164** (`feat(search-stack): replace firecrawl with brightdata, remove slidev plugin`) — the default-scope instance (Mode 6): a `rg -i firecrawl` removal/parity gate returned 0 hits while a stale `firecrawl tier-3` string survived in `.claude-plugin/`/`.agents/` (recursive ripgrep skips dot-dirs by default); caught only by `rg --hidden`. See [[brightdata-cli-preflight-quirks]] for the migration's other lore. +6. **PR #168** (`chore: retire Hermes plugin adapters in favor of npx skills`) — the wrong-noun instance (Mode 7), plus a same-PR recurrence of Mode 6. The removal sweep grepped `sync-hermes|HERMES_ELIGIBLE|mock-load-hermes` and reported clean twice: once missing `.coderabbit.yaml` / `.claude/rules/plugin-versioning.md` / `.claude-plugin/marketplace.json` because `--hidden` was absent (Mode 6, repeated even though this page already documented it), and once missing 24 files whose surviving text was `hermes plugins install` / `skill_view(...)` rather than any searched token (Mode 7). CodeRabbit caught the first class, Codex the second. Same PR also produced [[skills-install-wrapper]]'s measured install facts. From 79ee0be5e867dfba2a04fd0d444a35622b392ebc Mon Sep 17 00:00:00 2001 From: YoungjaeDev Date: Mon, 27 Jul 2026 11:29:13 +0900 Subject: [PATCH 10/12] fix: drop qualified Hermes names from compat headers, add migration path MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Two review rounds, two findings. CodeRabbit (Major + Minor): the previous commit fixed the load-contract sentence but left the compatibility header ten lines above it reading "When this skill is loaded through Hermes as `:`". 17 SKILL.md files still named the retired qualified form as the live contract. Now they read "When this skill runs under Hermes". The one remaining mention of the qualified name is a deliberate contrast in the install prose ("flat name X, not plugin:X"), which orients someone migrating rather than instructing them. Codex (P1): existing `hermes plugins install` users lose everything on update. `hermes plugins update` is a plain git pull with no version compare (recorded in .llmwiki/wiki/plugin-ops/hermes-plugin-adapter.md), so pulling this release deletes plugin.yaml/__init__.py — the registration entrypoints — while nothing populates ~/.hermes/skills/ in their place. The 20 skills silently vanish. README now carries an ordered migration: install the skills FIRST, verify ~/.hermes/skills/, then disable the legacy plugin. Recovery is documented too (reinstall the skills; nothing is lost but registration state). A one-release compatibility adapter was considered and rejected — it would reinstate the machinery this PR removes to protect a route with no measured user (~/.hermes/plugins/ holds one unrelated plugin). anti-slop-design 0.3.5, github-dev 2.11.2, interview 1.3.2, ml-toolkit 1.4.5, ppt-yeong-style 0.9.5, tcrei-prompt 1.1.4, marketplace 2.9.1. Refs #166 --- .claude-plugin/marketplace.json | 14 +++++++------- README.md | 17 +++++++++++++++++ .../anti-slop-design/.claude-plugin/plugin.json | 2 +- .../anti-slop-design/.codex-plugin/plugin.json | 2 +- .../skills/anti-slop-design/SKILL.md | 2 +- plugins/github-dev/.claude-plugin/plugin.json | 2 +- plugins/github-dev/.codex-plugin/plugin.json | 2 +- .../github-dev/skills/commit-and-push/SKILL.md | 2 +- plugins/github-dev/skills/cr-fix/SKILL.md | 2 +- .../skills/create-issue-label/SKILL.md | 2 +- .../github-dev/skills/decompose-issue/SKILL.md | 2 +- plugins/github-dev/skills/post-merge/SKILL.md | 2 +- plugins/github-dev/skills/release/SKILL.md | 2 +- .../github-dev/skills/resolve-issue/SKILL.md | 2 +- .../github-dev/skills/update-progress/SKILL.md | 2 +- plugins/interview/.claude-plugin/plugin.json | 2 +- plugins/interview/.codex-plugin/plugin.json | 2 +- .../skills/interview-methodology/SKILL.md | 2 +- plugins/ml-toolkit/.claude-plugin/plugin.json | 2 +- plugins/ml-toolkit/.codex-plugin/plugin.json | 2 +- plugins/ml-toolkit/skills/cv-explorer/SKILL.md | 2 +- plugins/ml-toolkit/skills/cv-notebook/SKILL.md | 2 +- .../skills/gpu-parallel-pipeline/SKILL.md | 2 +- .../ml-toolkit/skills/gradio-cv-app/SKILL.md | 2 +- .../skills/ml-dev-principles/SKILL.md | 2 +- .../ppt-yeong-style/.claude-plugin/plugin.json | 2 +- .../ppt-yeong-style/.codex-plugin/plugin.json | 2 +- .../skills/ppt-yeong-style/SKILL.md | 2 +- plugins/tcrei-prompt/.claude-plugin/plugin.json | 2 +- plugins/tcrei-prompt/.codex-plugin/plugin.json | 2 +- .../tcrei-prompt/skills/tcrei-prompt/SKILL.md | 2 +- 31 files changed, 53 insertions(+), 36 deletions(-) diff --git a/.claude-plugin/marketplace.json b/.claude-plugin/marketplace.json index 350fe079..a0574157 100644 --- a/.claude-plugin/marketplace.json +++ b/.claude-plugin/marketplace.json @@ -5,7 +5,7 @@ }, "metadata": { "description": "Personal Claude Code plugin collection with 24 specialized plugins. Codex 0.135 native — generated `.agents/plugins/marketplace.json` + per-plugin `.codex-plugin/plugin.json` (`scripts/sync-codex-manifests.mjs`). Hermes Agent installs skills from the same tree via `npx skills` (`scripts/install-skills.mjs`), with no generated adapter.", - "version": "2.9.0" + "version": "2.9.1" }, "plugins": [ { @@ -19,7 +19,7 @@ "name": "github-dev", "source": "./plugins/github-dev", "description": "GitHub workflow: commit, PR, issue, worktree, unified CodeRabbit + ChatGPT-Codex cr-fix pipeline v2 (Step 5 pre-flight review detection across CR commit-status + comments + Codex reviews + Codex emoji 3-channel; autonomous Step 9 judgment replaces per-finding AskUserQuestion — LLM judges real/spurious + severity + fix-size and applies/defers/skips with logged reasoning; rate-limit sniffer now covers commit-status description + in-place comment edits; polling interval 60s → 8s; --auto-merge + --skip-minor + --cr-source retained), project tracking, release. All workflows are now skills (commit-and-push, create-issue-label, decompose-issue, update-progress, resolve-issue, release, cr-fix, post-merge) — no commands surface, so they run under Codex too. post-merge runs a mandatory built-in wiki-lore ingest step (absorbed llm-wiki:post-merge-wiki) plus an optional Step 4.5 ephemeral-artifact pruning gate (heuristic candidates → AskUserQuestion → git rm). 2.8.0 correctness repairs: CR-state fetch failures map to a real error channel (no longer masked as a clean 'none'), a null-repository GraphQL response fails loudly instead of a silent false-clean convergence, and an active `@coderabbitai rate limit` query resolves ambiguous passive rate-limit sniffs.", - "version": "2.11.1", + "version": "2.11.2", "category": "github" }, { @@ -61,7 +61,7 @@ "name": "ml-toolkit", "source": "./plugins/ml-toolkit", "description": "ML/multimodal development principles, GPU parallel processing, Gradio CV apps, CV notebook generation, interactive CV data exploration", - "version": "1.4.4", + "version": "1.4.5", "category": "development" }, { @@ -75,7 +75,7 @@ "name": "interview", "source": "./plugins/interview", "description": "Structured requirements gathering", - "version": "1.3.1", + "version": "1.3.2", "category": "planning" }, { @@ -103,7 +103,7 @@ "name": "tcrei-prompt", "source": "./plugins/tcrei-prompt", "description": "Rewrite prompts using Google's TCREI structure for next-session reuse", - "version": "1.1.3", + "version": "1.1.4", "category": "content" }, { @@ -138,7 +138,7 @@ "name": "anti-slop-design", "source": "./plugins/anti-slop-design", "description": "Anti-AI-slop design guard for web/SaaS landing, decks (PPT), dashboards, and copy. Runs a clarify->context->plan->run->audit->revise flow with a two-phase audit gate (pre-emit self-critique + binary slop checklist) and hands Korean copy rewriting to humanize-korean. Source-grounded in 6 OSS anti-slop repos.", - "version": "0.3.4", + "version": "0.3.5", "category": "design" }, { @@ -152,7 +152,7 @@ "name": "ppt-yeong-style", "source": "./plugins/ppt-yeong-style", "description": "yeong 스타일 강의·제안 덱 작성 규약 — ppt-master 빌드 엔진 위에 얹는 작성 레이어(엔진 자체가 아님). 스킬 3종: 메인 ppt-yeong-style(미감 시그니처 §0 'Editorial restraint, one committed accent'·md 소스 규약·작성 원칙 16종·밀도 리듬·역할 기반 색·codex-image vs SVG 경계·앱 UI 실물 강제·레버 조합 차별화·윤문·렌더 QA + references/ 6종 + 주입 페이로드) + lecture-deck(강의 덱 운영 — 실습 handouts 생성 규약·프롬프트 카드·placeholder→실캡처 스크린샷 슬롯·리넘버링 4중 동기화·전사 회고 루프·강사 노트 태그 + cc-common 47장 레퍼런스) + deck-review(관점별 리뷰 서브에이전트 4종 audience-fit·story-flow·fact-check·design-qa 병렬 오케스트레이션 + codex:rescue 교차 리뷰, 페르소나는 파라미터). 의존 스킬은 있으면 사용, 없으면 생략 + 설치 제안 문구(ppt-master만 prerequisite-stop). ppt-master로 그냥 'PPT 만들기'와 달리 yeong 규약이 필요할 때.", - "version": "0.9.4", + "version": "0.9.5", "category": "design" }, { diff --git a/README.md b/README.md index b1c68556..d8286011 100644 --- a/README.md +++ b/README.md @@ -710,6 +710,23 @@ npx skills add . -l # 이 저장소가 노출하는 스킬 목록 > 이전에는 Hermes 용 네이티브 어댑터(`plugin.yaml` + `__init__.py`)를 `scripts/sync-hermes-manifests.mjs` 로 생성했습니다. 7 플러그인 / 20 스킬만 덮으면서 버전 범프마다 재생성과 drift 가드를 요구했고 로드에 `skill_view()` 명시 호출이 필요해, #166 에서 제거하고 `npx skills` 경로로 일원화했습니다. +#### 기존 `hermes plugins install` 사용자 마이그레이션 (필수, 순서 주의) + +이전 안내대로 `hermes plugins install .../plugins/ --enable` 로 설치했다면 **업데이트하기 전에 먼저 스킬을 설치하세요.** `hermes plugins update` 는 버전 비교 없는 순수 `git pull` 이라, 이 릴리스를 그대로 당기면 등록 엔트리포인트인 `plugin.yaml` / `__init__.py` 가 사라지면서 **해당 플러그인의 스킬이 전부 사라집니다** — 그 자리를 채워줄 것이 자동으로 설치되지는 않습니다. + +```bash +# 1) 먼저 스킬을 설치한다 (아직 레거시 플러그인이 살아있는 상태에서) +node scripts/install-skills.mjs # 또는 npx skills add ... -a hermes-agent -g + +# 2) ~/.hermes/skills/ 에 실제로 들어왔는지 확인한다 +ls ~/.hermes/skills/ + +# 3) 확인된 뒤에 레거시 플러그인을 비활성화 / 제거한다 +hermes plugins disable +``` + +이미 `hermes plugins update` 를 먼저 돌려버렸다면 스킬만 다시 설치하면 복구됩니다 (1단계). 데이터 손실은 없고, 사라지는 것은 등록 상태뿐입니다. + 공유 skill 본문은 Claude/Codex 도구 용어를 Hermes 도구로 매핑하는 호환 표를 포함합니다. ### CI 가드가 지키는 것 (curation / security) diff --git a/plugins/anti-slop-design/.claude-plugin/plugin.json b/plugins/anti-slop-design/.claude-plugin/plugin.json index 6a62a00f..524c05d3 100644 --- a/plugins/anti-slop-design/.claude-plugin/plugin.json +++ b/plugins/anti-slop-design/.claude-plugin/plugin.json @@ -1,6 +1,6 @@ { "name": "anti-slop-design", - "version": "0.3.4", + "version": "0.3.5", "description": "Anti-AI-slop design guard for web/SaaS landing, decks (PPT), dashboards, and copy. Runs a clarify->context->plan->run->audit->revise flow with a two-phase audit gate (pre-emit self-critique + binary slop checklist) and hands Korean copy rewriting to humanize-korean. Source-grounded in 6 OSS anti-slop repos.", "skills": [ "./skills/anti-slop-design" diff --git a/plugins/anti-slop-design/.codex-plugin/plugin.json b/plugins/anti-slop-design/.codex-plugin/plugin.json index 969ab2ce..6c6a0322 100644 --- a/plugins/anti-slop-design/.codex-plugin/plugin.json +++ b/plugins/anti-slop-design/.codex-plugin/plugin.json @@ -1,6 +1,6 @@ { "name": "anti-slop-design", - "version": "0.3.4", + "version": "0.3.5", "description": "Anti-AI-slop design guard for web/SaaS landing, decks (PPT), dashboards, and copy. Runs a clarify->context->plan->run->audit->revise flow with a two-phase audit gate (pre-emit self-critique + binary slop checklist) and hands Korean copy rewriting to humanize-korean. Source-grounded in 6 OSS anti-slop repos.", "author": { "name": "YoungjaeDev" diff --git a/plugins/anti-slop-design/skills/anti-slop-design/SKILL.md b/plugins/anti-slop-design/skills/anti-slop-design/SKILL.md index 3ef0e52d..1de50486 100644 --- a/plugins/anti-slop-design/skills/anti-slop-design/SKILL.md +++ b/plugins/anti-slop-design/skills/anti-slop-design/SKILL.md @@ -7,7 +7,7 @@ description: "Anti-AI-slop design guard for websites/SaaS landing, presentation ## Hermes Agent Compatibility -When this skill is loaded through Hermes as `anti-slop-design:anti-slop-design`, map Claude/Codex tool names to Hermes tools: +When this skill runs under Hermes, map Claude/Codex tool names to Hermes tools: | Claude/Codex term | Hermes tool | |---|---| diff --git a/plugins/github-dev/.claude-plugin/plugin.json b/plugins/github-dev/.claude-plugin/plugin.json index 3c8acc96..23f273c0 100644 --- a/plugins/github-dev/.claude-plugin/plugin.json +++ b/plugins/github-dev/.claude-plugin/plugin.json @@ -1,6 +1,6 @@ { "name": "github-dev", - "version": "2.11.1", + "version": "2.11.2", "description": "GitHub workflow: commit, PR, issue, worktree, unified CodeRabbit + ChatGPT-Codex cr-fix pipeline v2 (Step 5 pre-flight review detection across CR commit-status + comments + Codex reviews + Codex emoji 3-channel; autonomous Step 9 judgment replaces per-finding AskUserQuestion — LLM judges real/spurious + severity + fix-size and applies/defers/skips with logged reasoning; rate-limit sniffer now covers commit-status description + in-place comment edits; polling interval 60s → 8s; --auto-merge + --skip-minor + --cr-source retained), project tracking, release. All workflows are now skills (commit-and-push, create-issue-label, decompose-issue, update-progress, resolve-issue, release, cr-fix, post-merge) — no commands surface, so they run under Codex too. post-merge runs a mandatory built-in wiki-lore ingest step (absorbed llm-wiki:post-merge-wiki) plus an optional Step 4.5 ephemeral-artifact pruning gate (heuristic candidates → AskUserQuestion → git rm). 2.8.0 correctness repairs: CR-state fetch failures map to a real error channel (no longer masked as a clean 'none'), a null-repository GraphQL response fails loudly instead of a silent false-clean convergence, and an active `@coderabbitai rate limit` query resolves ambiguous passive rate-limit sniffs.", "skills": [ "./skills/cr-fix", diff --git a/plugins/github-dev/.codex-plugin/plugin.json b/plugins/github-dev/.codex-plugin/plugin.json index ef460784..204262f9 100644 --- a/plugins/github-dev/.codex-plugin/plugin.json +++ b/plugins/github-dev/.codex-plugin/plugin.json @@ -1,6 +1,6 @@ { "name": "github-dev", - "version": "2.11.1", + "version": "2.11.2", "description": "GitHub workflow: commit, PR, issue, worktree, unified CodeRabbit + ChatGPT-Codex cr-fix pipeline v2 (Step 5 pre-flight review detection across CR commit-status + comments + Codex reviews + Codex emoji 3-channel; autonomous Step 9 judgment replaces per-finding AskUserQuestion — LLM judges real/spurious + severity + fix-size and applies/defers/skips with logged reasoning; rate-limit sniffer now covers commit-status description + in-place comment edits; polling interval 60s → 8s; --auto-merge + --skip-minor + --cr-source retained), project tracking, release. All workflows are now skills (commit-and-push, create-issue-label, decompose-issue, update-progress, resolve-issue, release, cr-fix, post-merge) — no commands surface, so they run under Codex too. post-merge runs a mandatory built-in wiki-lore ingest step (absorbed llm-wiki:post-merge-wiki) plus an optional Step 4.5 ephemeral-artifact pruning gate (heuristic candidates → AskUserQuestion → git rm). 2.8.0 correctness repairs: CR-state fetch failures map to a real error channel (no longer masked as a clean 'none'), a null-repository GraphQL response fails loudly instead of a silent false-clean convergence, and an active `@coderabbitai rate limit` query resolves ambiguous passive rate-limit sniffs.", "author": { "name": "YoungjaeDev" diff --git a/plugins/github-dev/skills/commit-and-push/SKILL.md b/plugins/github-dev/skills/commit-and-push/SKILL.md index ba0e1c4b..5201cbdc 100644 --- a/plugins/github-dev/skills/commit-and-push/SKILL.md +++ b/plugins/github-dev/skills/commit-and-push/SKILL.md @@ -8,7 +8,7 @@ allowed-tools: Read Bash Task ## Hermes Agent Compatibility -When this skill is loaded through Hermes as `github-dev:`, map Claude/Codex tool names to Hermes tools: +When this skill runs under Hermes, map Claude/Codex tool names to Hermes tools: | Claude/Codex term | Hermes tool | |---|---| diff --git a/plugins/github-dev/skills/cr-fix/SKILL.md b/plugins/github-dev/skills/cr-fix/SKILL.md index 6a9fc482..be4bd4ed 100644 --- a/plugins/github-dev/skills/cr-fix/SKILL.md +++ b/plugins/github-dev/skills/cr-fix/SKILL.md @@ -8,7 +8,7 @@ allowed-tools: Read Write Edit Bash Glob Grep AskUserQuestion ## Hermes Agent Compatibility -When this skill is loaded through Hermes as `github-dev:`, map Claude/Codex tool names to Hermes tools: +When this skill runs under Hermes, map Claude/Codex tool names to Hermes tools: | Claude/Codex term | Hermes tool | |---|---| diff --git a/plugins/github-dev/skills/create-issue-label/SKILL.md b/plugins/github-dev/skills/create-issue-label/SKILL.md index e3983846..679a14c1 100644 --- a/plugins/github-dev/skills/create-issue-label/SKILL.md +++ b/plugins/github-dev/skills/create-issue-label/SKILL.md @@ -8,7 +8,7 @@ allowed-tools: Read Bash Glob Grep ## Hermes Agent Compatibility -When this skill is loaded through Hermes as `github-dev:`, map Claude/Codex tool names to Hermes tools: +When this skill runs under Hermes, map Claude/Codex tool names to Hermes tools: | Claude/Codex term | Hermes tool | |---|---| diff --git a/plugins/github-dev/skills/decompose-issue/SKILL.md b/plugins/github-dev/skills/decompose-issue/SKILL.md index 1f6c6ed2..90e80ca1 100644 --- a/plugins/github-dev/skills/decompose-issue/SKILL.md +++ b/plugins/github-dev/skills/decompose-issue/SKILL.md @@ -8,7 +8,7 @@ allowed-tools: Read Write Edit Bash Glob Grep AskUserQuestion ## Hermes Agent Compatibility -When this skill is loaded through Hermes as `github-dev:`, map Claude/Codex tool names to Hermes tools: +When this skill runs under Hermes, map Claude/Codex tool names to Hermes tools: | Claude/Codex term | Hermes tool | |---|---| diff --git a/plugins/github-dev/skills/post-merge/SKILL.md b/plugins/github-dev/skills/post-merge/SKILL.md index 21aba7f6..cc5cde35 100644 --- a/plugins/github-dev/skills/post-merge/SKILL.md +++ b/plugins/github-dev/skills/post-merge/SKILL.md @@ -8,7 +8,7 @@ allowed-tools: Read Write Edit Bash Glob Grep AskUserQuestion ## Hermes Agent Compatibility -When this skill is loaded through Hermes as `github-dev:`, map Claude/Codex tool names to Hermes tools: +When this skill runs under Hermes, map Claude/Codex tool names to Hermes tools: | Claude/Codex term | Hermes tool | |---|---| diff --git a/plugins/github-dev/skills/release/SKILL.md b/plugins/github-dev/skills/release/SKILL.md index f6468d3e..a79e7c35 100644 --- a/plugins/github-dev/skills/release/SKILL.md +++ b/plugins/github-dev/skills/release/SKILL.md @@ -8,7 +8,7 @@ allowed-tools: Read Edit Bash AskUserQuestion ## Hermes Agent Compatibility -When this skill is loaded through Hermes as `github-dev:`, map Claude/Codex tool names to Hermes tools: +When this skill runs under Hermes, map Claude/Codex tool names to Hermes tools: | Claude/Codex term | Hermes tool | |---|---| diff --git a/plugins/github-dev/skills/resolve-issue/SKILL.md b/plugins/github-dev/skills/resolve-issue/SKILL.md index 269585bd..a1d8a82a 100644 --- a/plugins/github-dev/skills/resolve-issue/SKILL.md +++ b/plugins/github-dev/skills/resolve-issue/SKILL.md @@ -8,7 +8,7 @@ allowed-tools: Read Write Edit Bash Glob Grep AskUserQuestion Task ## Hermes Agent Compatibility -When this skill is loaded through Hermes as `github-dev:`, map Claude/Codex tool names to Hermes tools: +When this skill runs under Hermes, map Claude/Codex tool names to Hermes tools: | Claude/Codex term | Hermes tool | |---|---| diff --git a/plugins/github-dev/skills/update-progress/SKILL.md b/plugins/github-dev/skills/update-progress/SKILL.md index 1b6f14b3..098e67fb 100644 --- a/plugins/github-dev/skills/update-progress/SKILL.md +++ b/plugins/github-dev/skills/update-progress/SKILL.md @@ -8,7 +8,7 @@ allowed-tools: Read Edit Bash Glob Grep AskUserQuestion ## Hermes Agent Compatibility -When this skill is loaded through Hermes as `github-dev:`, map Claude/Codex tool names to Hermes tools: +When this skill runs under Hermes, map Claude/Codex tool names to Hermes tools: | Claude/Codex term | Hermes tool | |---|---| diff --git a/plugins/interview/.claude-plugin/plugin.json b/plugins/interview/.claude-plugin/plugin.json index aef096e9..4dba5665 100644 --- a/plugins/interview/.claude-plugin/plugin.json +++ b/plugins/interview/.claude-plugin/plugin.json @@ -1,5 +1,5 @@ { "name": "interview", - "version": "1.3.1", + "version": "1.3.2", "description": "Structured requirements gathering" } diff --git a/plugins/interview/.codex-plugin/plugin.json b/plugins/interview/.codex-plugin/plugin.json index 94b291c3..4a208500 100644 --- a/plugins/interview/.codex-plugin/plugin.json +++ b/plugins/interview/.codex-plugin/plugin.json @@ -1,6 +1,6 @@ { "name": "interview", - "version": "1.3.1", + "version": "1.3.2", "description": "Structured requirements gathering", "author": { "name": "YoungjaeDev" diff --git a/plugins/interview/skills/interview-methodology/SKILL.md b/plugins/interview/skills/interview-methodology/SKILL.md index 7bdae4c2..1a5f44e6 100644 --- a/plugins/interview/skills/interview-methodology/SKILL.md +++ b/plugins/interview/skills/interview-methodology/SKILL.md @@ -8,7 +8,7 @@ version: 0.4.0 ## Hermes Agent Compatibility -When this skill is loaded through Hermes as `interview:interview-methodology`, map Claude/Codex tool names to Hermes tools: +When this skill runs under Hermes, map Claude/Codex tool names to Hermes tools: | Claude/Codex term | Hermes tool | |---|---| diff --git a/plugins/ml-toolkit/.claude-plugin/plugin.json b/plugins/ml-toolkit/.claude-plugin/plugin.json index f68c5783..0f31a661 100644 --- a/plugins/ml-toolkit/.claude-plugin/plugin.json +++ b/plugins/ml-toolkit/.claude-plugin/plugin.json @@ -1,5 +1,5 @@ { "name": "ml-toolkit", - "version": "1.4.4", + "version": "1.4.5", "description": "ML/multimodal development principles, GPU parallel processing, Gradio CV apps, CV notebook generation, interactive CV data exploration" } diff --git a/plugins/ml-toolkit/.codex-plugin/plugin.json b/plugins/ml-toolkit/.codex-plugin/plugin.json index f840ca3d..9bb68298 100644 --- a/plugins/ml-toolkit/.codex-plugin/plugin.json +++ b/plugins/ml-toolkit/.codex-plugin/plugin.json @@ -1,6 +1,6 @@ { "name": "ml-toolkit", - "version": "1.4.4", + "version": "1.4.5", "description": "ML/multimodal development principles, GPU parallel processing, Gradio CV apps, CV notebook generation, interactive CV data exploration", "author": { "name": "YoungjaeDev" diff --git a/plugins/ml-toolkit/skills/cv-explorer/SKILL.md b/plugins/ml-toolkit/skills/cv-explorer/SKILL.md index 5a4efe9f..44738ff5 100644 --- a/plugins/ml-toolkit/skills/cv-explorer/SKILL.md +++ b/plugins/ml-toolkit/skills/cv-explorer/SKILL.md @@ -7,7 +7,7 @@ description: Generate interactive CV data exploration notebooks with ipywidgets ## Hermes Agent Compatibility -When this skill is loaded through Hermes as `ml-toolkit:cv-explorer`, map Claude/Codex tool names to Hermes tools: +When this skill runs under Hermes, map Claude/Codex tool names to Hermes tools: | Claude/Codex term | Hermes tool | |---|---| diff --git a/plugins/ml-toolkit/skills/cv-notebook/SKILL.md b/plugins/ml-toolkit/skills/cv-notebook/SKILL.md index ea34baee..3dc9c378 100644 --- a/plugins/ml-toolkit/skills/cv-notebook/SKILL.md +++ b/plugins/ml-toolkit/skills/cv-notebook/SKILL.md @@ -7,7 +7,7 @@ description: Generate production-quality Computer Vision Jupyter notebooks. Supp ## Hermes Agent Compatibility -When this skill is loaded through Hermes as `ml-toolkit:cv-notebook`, map Claude/Codex tool names to Hermes tools: +When this skill runs under Hermes, map Claude/Codex tool names to Hermes tools: | Claude/Codex term | Hermes tool | |---|---| diff --git a/plugins/ml-toolkit/skills/gpu-parallel-pipeline/SKILL.md b/plugins/ml-toolkit/skills/gpu-parallel-pipeline/SKILL.md index df5ea700..096a0a63 100644 --- a/plugins/ml-toolkit/skills/gpu-parallel-pipeline/SKILL.md +++ b/plugins/ml-toolkit/skills/gpu-parallel-pipeline/SKILL.md @@ -7,7 +7,7 @@ description: Design and implement PyTorch GPU parallel processing pipelines for ## Hermes Agent Compatibility -When this skill is loaded through Hermes as `ml-toolkit:gpu-parallel-pipeline`, map Claude/Codex tool names to Hermes tools: +When this skill runs under Hermes, map Claude/Codex tool names to Hermes tools: | Claude/Codex term | Hermes tool | |---|---| diff --git a/plugins/ml-toolkit/skills/gradio-cv-app/SKILL.md b/plugins/ml-toolkit/skills/gradio-cv-app/SKILL.md index 994ba5a8..fd0ba1ca 100644 --- a/plugins/ml-toolkit/skills/gradio-cv-app/SKILL.md +++ b/plugins/ml-toolkit/skills/gradio-cv-app/SKILL.md @@ -7,7 +7,7 @@ description: Creates professional Gradio computer vision apps. Applies a refined ## Hermes Agent Compatibility -When this skill is loaded through Hermes as `ml-toolkit:gradio-cv-app`, map Claude/Codex tool names to Hermes tools: +When this skill runs under Hermes, map Claude/Codex tool names to Hermes tools: | Claude/Codex term | Hermes tool | |---|---| diff --git a/plugins/ml-toolkit/skills/ml-dev-principles/SKILL.md b/plugins/ml-toolkit/skills/ml-dev-principles/SKILL.md index ce283b15..956b6d2d 100644 --- a/plugins/ml-toolkit/skills/ml-dev-principles/SKILL.md +++ b/plugins/ml-toolkit/skills/ml-dev-principles/SKILL.md @@ -7,7 +7,7 @@ description: General working discipline for ML / multimodal / CV development (ho ## Hermes Agent Compatibility -When this skill is loaded through Hermes as `ml-toolkit:ml-dev-principles`, map Claude/Codex tool names to Hermes tools: +When this skill runs under Hermes, map Claude/Codex tool names to Hermes tools: | Claude/Codex term | Hermes tool | |---|---| diff --git a/plugins/ppt-yeong-style/.claude-plugin/plugin.json b/plugins/ppt-yeong-style/.claude-plugin/plugin.json index 3d1ec1cb..de2a2d6d 100644 --- a/plugins/ppt-yeong-style/.claude-plugin/plugin.json +++ b/plugins/ppt-yeong-style/.claude-plugin/plugin.json @@ -1,6 +1,6 @@ { "name": "ppt-yeong-style", - "version": "0.9.4", + "version": "0.9.5", "description": "yeong 스타일 강의·제안 덱 작성 규약 — ppt-master 빌드 엔진 위에 얹는 작성 레이어(엔진 자체가 아님). 스킬 3종: 메인 ppt-yeong-style(미감 시그니처 §0 'Editorial restraint, one committed accent'·md 소스 규약·작성 원칙 16종·밀도 리듬·역할 기반 색·codex-image vs SVG 경계·앱 UI 실물 강제·레버 조합 차별화·윤문·렌더 QA + references/ 6종 + 주입 페이로드) + lecture-deck(강의 덱 운영 — 실습 handouts 생성 규약·프롬프트 카드·placeholder→실캡처 스크린샷 슬롯·리넘버링 4중 동기화·전사 회고 루프·강사 노트 태그 + cc-common 47장 레퍼런스) + deck-review(관점별 리뷰 서브에이전트 4종 audience-fit·story-flow·fact-check·design-qa 병렬 오케스트레이션 + codex:rescue 교차 리뷰, 페르소나는 파라미터). 의존 스킬은 있으면 사용, 없으면 생략 + 설치 제안 문구(ppt-master만 prerequisite-stop). ppt-master로 그냥 'PPT 만들기'와 달리 yeong 규약이 필요할 때.", "skills": [ "./skills/ppt-yeong-style", diff --git a/plugins/ppt-yeong-style/.codex-plugin/plugin.json b/plugins/ppt-yeong-style/.codex-plugin/plugin.json index 7a12b7c3..39088835 100644 --- a/plugins/ppt-yeong-style/.codex-plugin/plugin.json +++ b/plugins/ppt-yeong-style/.codex-plugin/plugin.json @@ -1,6 +1,6 @@ { "name": "ppt-yeong-style", - "version": "0.9.4", + "version": "0.9.5", "description": "yeong 스타일 강의·제안 덱 작성 규약 — ppt-master 빌드 엔진 위에 얹는 작성 레이어(엔진 자체가 아님). 스킬 3종: 메인 ppt-yeong-style(미감 시그니처 §0 'Editorial restraint, one committed accent'·md 소스 규약·작성 원칙 16종·밀도 리듬·역할 기반 색·codex-image vs SVG 경계·앱 UI 실물 강제·레버 조합 차별화·윤문·렌더 QA + references/ 6종 + 주입 페이로드) + lecture-deck(강의 덱 운영 — 실습 handouts 생성 규약·프롬프트 카드·placeholder→실캡처 스크린샷 슬롯·리넘버링 4중 동기화·전사 회고 루프·강사 노트 태그 + cc-common 47장 레퍼런스) + deck-review(관점별 리뷰 서브에이전트 4종 audience-fit·story-flow·fact-check·design-qa 병렬 오케스트레이션 + codex:rescue 교차 리뷰, 페르소나는 파라미터). 의존 스킬은 있으면 사용, 없으면 생략 + 설치 제안 문구(ppt-master만 prerequisite-stop). ppt-master로 그냥 'PPT 만들기'와 달리 yeong 규약이 필요할 때.", "author": { "name": "YoungjaeDev" diff --git a/plugins/ppt-yeong-style/skills/ppt-yeong-style/SKILL.md b/plugins/ppt-yeong-style/skills/ppt-yeong-style/SKILL.md index f3e1be1c..f37e20c8 100644 --- a/plugins/ppt-yeong-style/skills/ppt-yeong-style/SKILL.md +++ b/plugins/ppt-yeong-style/skills/ppt-yeong-style/SKILL.md @@ -7,7 +7,7 @@ description: "yeong 스타일 강의·제안 덱 작성 규약 — ppt-master ## Hermes Agent Compatibility -When this skill is loaded through Hermes as `ppt-yeong-style:ppt-yeong-style`, map Claude/Codex tool names to Hermes tools: +When this skill runs under Hermes, map Claude/Codex tool names to Hermes tools: | Claude/Codex term | Hermes tool | |---|---| diff --git a/plugins/tcrei-prompt/.claude-plugin/plugin.json b/plugins/tcrei-prompt/.claude-plugin/plugin.json index 2fe8f32f..5db077db 100644 --- a/plugins/tcrei-prompt/.claude-plugin/plugin.json +++ b/plugins/tcrei-prompt/.claude-plugin/plugin.json @@ -1,5 +1,5 @@ { "name": "tcrei-prompt", - "version": "1.1.3", + "version": "1.1.4", "description": "Rewrite prompts using Google's TCREI structure for next-session reuse" } diff --git a/plugins/tcrei-prompt/.codex-plugin/plugin.json b/plugins/tcrei-prompt/.codex-plugin/plugin.json index afaa592e..fc1636bb 100644 --- a/plugins/tcrei-prompt/.codex-plugin/plugin.json +++ b/plugins/tcrei-prompt/.codex-plugin/plugin.json @@ -1,6 +1,6 @@ { "name": "tcrei-prompt", - "version": "1.1.3", + "version": "1.1.4", "description": "Rewrite prompts using Google's TCREI structure for next-session reuse", "author": { "name": "YoungjaeDev" diff --git a/plugins/tcrei-prompt/skills/tcrei-prompt/SKILL.md b/plugins/tcrei-prompt/skills/tcrei-prompt/SKILL.md index b082de42..4614fed6 100644 --- a/plugins/tcrei-prompt/skills/tcrei-prompt/SKILL.md +++ b/plugins/tcrei-prompt/skills/tcrei-prompt/SKILL.md @@ -18,7 +18,7 @@ allowed-tools: ## Hermes Agent Compatibility -When this skill is loaded through Hermes as `tcrei-prompt:tcrei-prompt`, map Claude/Codex tool names to Hermes tools: +When this skill runs under Hermes, map Claude/Codex tool names to Hermes tools: | Claude/Codex term | Hermes tool | |---|---| From c6c3ce52664efbd5b3528746f322b67226e4d93e Mon Sep 17 00:00:00 2001 From: YoungjaeDev Date: Mon, 27 Jul 2026 11:40:54 +0900 Subject: [PATCH 11/12] fix(cr-fix,gpu-parallel-pipeline): flat Hermes dir as default fallback MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Codex P1, and the only functional bug this PR produced rather than a doc drift. Both SKILL_DIR resolvers ended with $HOME/.hermes/plugins//skills/ — the plugin-adapter layout this PR deletes. Every branch above it that could have reached the flat layout is guarded by [ -n "$HERMES_HOME" ], and the default profile leaves that variable unset, so a normal Hermes install fell through to a directory that does not exist. cr-fix would have failed at Step 1 before parsing a single argument. Reordered so the flat layout npx skills actually writes comes first among the Hermes branches, kept the legacy adapter paths as explicit fallbacks for a profile installed before #166, and made the terminal default flat. Two resolver test cases added, RED-verified against the previous resolver: the old code returned .hermes/plugins/... where .hermes/skills/... was expected. Suite 87 -> 89. Codex also caught brightdata-guide sitting at 1.1.0 while the other six adapter-deleted plugins were bumped — the inconsistency read as an oversight rather than the "generated artifacts need no bump" call it was, so it is bumped too and the rule now applies uniformly. brightdata-guide 1.1.1, github-dev 2.11.3, ml-toolkit 1.4.6, marketplace 2.9.2. Refs #166 --- .claude-plugin/marketplace.json | 8 ++++---- .../.claude-plugin/plugin.json | 2 +- .../brightdata-guide/.codex-plugin/plugin.json | 2 +- plugins/github-dev/.claude-plugin/plugin.json | 2 +- plugins/github-dev/.codex-plugin/plugin.json | 2 +- plugins/github-dev/skills/cr-fix/SKILL.md | 15 +++++++++------ .../skills/cr-fix/tests/run-tests.sh | 18 ++++++++++++++++-- plugins/ml-toolkit/.claude-plugin/plugin.json | 2 +- plugins/ml-toolkit/.codex-plugin/plugin.json | 2 +- .../skills/gpu-parallel-pipeline/SKILL.md | 10 ++++++---- 10 files changed, 41 insertions(+), 22 deletions(-) diff --git a/.claude-plugin/marketplace.json b/.claude-plugin/marketplace.json index a0574157..482d1c71 100644 --- a/.claude-plugin/marketplace.json +++ b/.claude-plugin/marketplace.json @@ -5,7 +5,7 @@ }, "metadata": { "description": "Personal Claude Code plugin collection with 24 specialized plugins. Codex 0.135 native — generated `.agents/plugins/marketplace.json` + per-plugin `.codex-plugin/plugin.json` (`scripts/sync-codex-manifests.mjs`). Hermes Agent installs skills from the same tree via `npx skills` (`scripts/install-skills.mjs`), with no generated adapter.", - "version": "2.9.1" + "version": "2.9.2" }, "plugins": [ { @@ -19,7 +19,7 @@ "name": "github-dev", "source": "./plugins/github-dev", "description": "GitHub workflow: commit, PR, issue, worktree, unified CodeRabbit + ChatGPT-Codex cr-fix pipeline v2 (Step 5 pre-flight review detection across CR commit-status + comments + Codex reviews + Codex emoji 3-channel; autonomous Step 9 judgment replaces per-finding AskUserQuestion — LLM judges real/spurious + severity + fix-size and applies/defers/skips with logged reasoning; rate-limit sniffer now covers commit-status description + in-place comment edits; polling interval 60s → 8s; --auto-merge + --skip-minor + --cr-source retained), project tracking, release. All workflows are now skills (commit-and-push, create-issue-label, decompose-issue, update-progress, resolve-issue, release, cr-fix, post-merge) — no commands surface, so they run under Codex too. post-merge runs a mandatory built-in wiki-lore ingest step (absorbed llm-wiki:post-merge-wiki) plus an optional Step 4.5 ephemeral-artifact pruning gate (heuristic candidates → AskUserQuestion → git rm). 2.8.0 correctness repairs: CR-state fetch failures map to a real error channel (no longer masked as a clean 'none'), a null-repository GraphQL response fails loudly instead of a silent false-clean convergence, and an active `@coderabbitai rate limit` query resolves ambiguous passive rate-limit sniffs.", - "version": "2.11.2", + "version": "2.11.3", "category": "github" }, { @@ -40,7 +40,7 @@ "name": "brightdata-guide", "source": "./plugins/brightdata-guide", "description": "Bright Data web data access via MCP tools + CLI — scraping (Web Unlocker), SERP, 40+ structured web_data_* extractors, browser automation. Guide skill; operator sets BRIGHTDATA_API_KEY, delegate subagents fall back to the bdata CLI.", - "version": "1.1.0", + "version": "1.1.1", "category": "research" }, { @@ -61,7 +61,7 @@ "name": "ml-toolkit", "source": "./plugins/ml-toolkit", "description": "ML/multimodal development principles, GPU parallel processing, Gradio CV apps, CV notebook generation, interactive CV data exploration", - "version": "1.4.5", + "version": "1.4.6", "category": "development" }, { diff --git a/plugins/brightdata-guide/.claude-plugin/plugin.json b/plugins/brightdata-guide/.claude-plugin/plugin.json index 3029f90a..a90545e2 100644 --- a/plugins/brightdata-guide/.claude-plugin/plugin.json +++ b/plugins/brightdata-guide/.claude-plugin/plugin.json @@ -1,6 +1,6 @@ { "name": "brightdata-guide", - "version": "1.1.0", + "version": "1.1.1", "description": "Bright Data web data access via MCP tools + CLI — scraping (Web Unlocker), SERP, 40+ structured web_data_* extractors, browser automation. Guide skill; operator sets BRIGHTDATA_API_KEY, delegate subagents fall back to the bdata CLI.", "license": "MIT" } diff --git a/plugins/brightdata-guide/.codex-plugin/plugin.json b/plugins/brightdata-guide/.codex-plugin/plugin.json index a4e36905..aa0a9042 100644 --- a/plugins/brightdata-guide/.codex-plugin/plugin.json +++ b/plugins/brightdata-guide/.codex-plugin/plugin.json @@ -1,6 +1,6 @@ { "name": "brightdata-guide", - "version": "1.1.0", + "version": "1.1.1", "description": "Bright Data web data access via MCP tools + CLI — scraping (Web Unlocker), SERP, 40+ structured web_data_* extractors, browser automation. Guide skill; operator sets BRIGHTDATA_API_KEY, delegate subagents fall back to the bdata CLI.", "author": { "name": "YoungjaeDev" diff --git a/plugins/github-dev/.claude-plugin/plugin.json b/plugins/github-dev/.claude-plugin/plugin.json index 23f273c0..cdda68a9 100644 --- a/plugins/github-dev/.claude-plugin/plugin.json +++ b/plugins/github-dev/.claude-plugin/plugin.json @@ -1,6 +1,6 @@ { "name": "github-dev", - "version": "2.11.2", + "version": "2.11.3", "description": "GitHub workflow: commit, PR, issue, worktree, unified CodeRabbit + ChatGPT-Codex cr-fix pipeline v2 (Step 5 pre-flight review detection across CR commit-status + comments + Codex reviews + Codex emoji 3-channel; autonomous Step 9 judgment replaces per-finding AskUserQuestion — LLM judges real/spurious + severity + fix-size and applies/defers/skips with logged reasoning; rate-limit sniffer now covers commit-status description + in-place comment edits; polling interval 60s → 8s; --auto-merge + --skip-minor + --cr-source retained), project tracking, release. All workflows are now skills (commit-and-push, create-issue-label, decompose-issue, update-progress, resolve-issue, release, cr-fix, post-merge) — no commands surface, so they run under Codex too. post-merge runs a mandatory built-in wiki-lore ingest step (absorbed llm-wiki:post-merge-wiki) plus an optional Step 4.5 ephemeral-artifact pruning gate (heuristic candidates → AskUserQuestion → git rm). 2.8.0 correctness repairs: CR-state fetch failures map to a real error channel (no longer masked as a clean 'none'), a null-repository GraphQL response fails loudly instead of a silent false-clean convergence, and an active `@coderabbitai rate limit` query resolves ambiguous passive rate-limit sniffs.", "skills": [ "./skills/cr-fix", diff --git a/plugins/github-dev/.codex-plugin/plugin.json b/plugins/github-dev/.codex-plugin/plugin.json index 204262f9..f6741b4d 100644 --- a/plugins/github-dev/.codex-plugin/plugin.json +++ b/plugins/github-dev/.codex-plugin/plugin.json @@ -1,6 +1,6 @@ { "name": "github-dev", - "version": "2.11.2", + "version": "2.11.3", "description": "GitHub workflow: commit, PR, issue, worktree, unified CodeRabbit + ChatGPT-Codex cr-fix pipeline v2 (Step 5 pre-flight review detection across CR commit-status + comments + Codex reviews + Codex emoji 3-channel; autonomous Step 9 judgment replaces per-finding AskUserQuestion — LLM judges real/spurious + severity + fix-size and applies/defers/skips with logged reasoning; rate-limit sniffer now covers commit-status description + in-place comment edits; polling interval 60s → 8s; --auto-merge + --skip-minor + --cr-source retained), project tracking, release. All workflows are now skills (commit-and-push, create-issue-label, decompose-issue, update-progress, resolve-issue, release, cr-fix, post-merge) — no commands surface, so they run under Codex too. post-merge runs a mandatory built-in wiki-lore ingest step (absorbed llm-wiki:post-merge-wiki) plus an optional Step 4.5 ephemeral-artifact pruning gate (heuristic candidates → AskUserQuestion → git rm). 2.8.0 correctness repairs: CR-state fetch failures map to a real error channel (no longer masked as a clean 'none'), a null-repository GraphQL response fails loudly instead of a silent false-clean convergence, and an active `@coderabbitai rate limit` query resolves ambiguous passive rate-limit sniffs.", "author": { "name": "YoungjaeDev" diff --git a/plugins/github-dev/skills/cr-fix/SKILL.md b/plugins/github-dev/skills/cr-fix/SKILL.md index be4bd4ed..8256d43d 100644 --- a/plugins/github-dev/skills/cr-fix/SKILL.md +++ b/plugins/github-dev/skills/cr-fix/SKILL.md @@ -77,14 +77,17 @@ elif [ -d "plugins/github-dev/skills/cr-fix" ]; then SKILL_DIR="plugins/github-dev/skills/cr-fix" elif [ -n "$CODEX_CAND" ] && [ -d "$CODEX_CAND/skills/cr-fix" ]; then SKILL_DIR="$CODEX_CAND/skills/cr-fix" -elif [ -n "${HERMES_HOME:-}" ] && [ -d "$HERMES_HOME/plugins/github-dev/skills/cr-fix" ]; then - SKILL_DIR="$HERMES_HOME/plugins/github-dev/skills/cr-fix" elif [ -n "${HERMES_HOME:-}" ] && [ -d "$HERMES_HOME/skills/cr-fix" ]; then - # unverified flat Hermes layout (no live-Hermes confirmation yet) — additive - # branch guarded by -d, never rewrites the plugin-layout branch above + # Flat layout — what `npx skills` produces, and the only Hermes layout since #166. SKILL_DIR="$HERMES_HOME/skills/cr-fix" -else +elif [ -n "${HERMES_HOME:-}" ] && [ -d "$HERMES_HOME/plugins/github-dev/skills/cr-fix" ]; then + # Legacy plugin-adapter layout, kept for a profile installed before #166. + SKILL_DIR="$HERMES_HOME/plugins/github-dev/skills/cr-fix" +elif [ -d "$HOME/.hermes/plugins/github-dev/skills/cr-fix" ]; then SKILL_DIR="$HOME/.hermes/plugins/github-dev/skills/cr-fix" +else + # Default profile (HERMES_HOME unset) — npx skills installs flat here. + SKILL_DIR="$HOME/.hermes/skills/cr-fix" fi eval "$(bash "$SKILL_DIR/scripts/parse-args.sh" $ARGUMENTS)" @@ -92,7 +95,7 @@ eval "$(bash "$SKILL_DIR/scripts/parse-args.sh" $ARGUMENTS)" Sets: `SKILL_DIR, MAX_ITER, TIMEOUT, INTERVAL, AUTO_MERGE, PASTE, NO_BUILD, CODEX_GRACE, NO_CODEX, SKIP_MINOR, MINOR_STOP, GENERALIZE, CR_SOURCE, SMALL_DIFF_LOC, SMALL_DIFF_FILES`. -`SKILL_DIR` resolves in order: Claude Code's `${CLAUDE_PLUGIN_ROOT}`, the source-tree plugin path, the Codex 0.135 cache (`~/.codex/plugins/cache//github-dev//`, newest by `sort -V`), the active Hermes profile install (`$HERMES_HOME/plugins/github-dev/...` then the flat `$HERMES_HOME/skills/cr-fix` layout), then the default `~/.hermes/plugins/github-dev/...` install. Without the `${CLAUDE_PLUGIN_ROOT}` and Codex-cache branches, an invocation outside the source tree resolved to a non-existent Hermes path and `parse-args.sh` was unreachable. All `scripts/` and `references/` paths below resolve relative to this. +`SKILL_DIR` resolves in order: Claude Code's `${CLAUDE_PLUGIN_ROOT}`, the source-tree plugin path, the Codex 0.135 cache (`~/.codex/plugins/cache//github-dev//`, newest by `sort -V`), the active Hermes profile (flat `$HERMES_HOME/skills/cr-fix` first, then the legacy `$HERMES_HOME/plugins/github-dev/...` adapter layout), the legacy default `~/.hermes/plugins/github-dev/...`, and finally the flat default `~/.hermes/skills/cr-fix`. Without the `${CLAUDE_PLUGIN_ROOT}` and Codex-cache branches, an invocation outside the source tree resolved to a non-existent Hermes path and `parse-args.sh` was unreachable. The **last** branch is the one that matters for a normal Hermes install: `npx skills` writes the flat layout, and with `HERMES_HOME` unset (the default profile) every `$HERMES_HOME`-guarded branch is skipped, so a final fallback pointing at the retired plugin layout would strand the skill before it parses a single argument. All `scripts/` and `references/` paths below resolve relative to this. ## Step 2: Resolve repo / PR / START_SHA + pre-flight setup diff --git a/plugins/github-dev/skills/cr-fix/tests/run-tests.sh b/plugins/github-dev/skills/cr-fix/tests/run-tests.sh index ef5c4efe..216766dd 100755 --- a/plugins/github-dev/skills/cr-fix/tests/run-tests.sh +++ b/plugins/github-dev/skills/cr-fix/tests/run-tests.sh @@ -522,9 +522,10 @@ fi if [ -n "${CLAUDE_PLUGIN_ROOT:-}" ] && [ -d "$CLAUDE_PLUGIN_ROOT/skills/cr-fix" ]; then SKILL_DIR="$CLAUDE_PLUGIN_ROOT/skills/cr-fix" elif [ -d "plugins/github-dev/skills/cr-fix" ]; then SKILL_DIR="plugins/github-dev/skills/cr-fix" elif [ -n "$CODEX_CAND" ] && [ -d "$CODEX_CAND/skills/cr-fix" ]; then SKILL_DIR="$CODEX_CAND/skills/cr-fix" -elif [ -n "${HERMES_HOME:-}" ] && [ -d "$HERMES_HOME/plugins/github-dev/skills/cr-fix" ]; then SKILL_DIR="$HERMES_HOME/plugins/github-dev/skills/cr-fix" elif [ -n "${HERMES_HOME:-}" ] && [ -d "$HERMES_HOME/skills/cr-fix" ]; then SKILL_DIR="$HERMES_HOME/skills/cr-fix" -else SKILL_DIR="$HOME/.hermes/plugins/github-dev/skills/cr-fix"; fi +elif [ -n "${HERMES_HOME:-}" ] && [ -d "$HERMES_HOME/plugins/github-dev/skills/cr-fix" ]; then SKILL_DIR="$HERMES_HOME/plugins/github-dev/skills/cr-fix" +elif [ -d "$HOME/.hermes/plugins/github-dev/skills/cr-fix" ]; then SKILL_DIR="$HOME/.hermes/plugins/github-dev/skills/cr-fix" +else SKILL_DIR="$HOME/.hermes/skills/cr-fix"; fi printf '%s' "$SKILL_DIR" SH # From a non-source-tree cwd so the source-tree branch cannot win. @@ -541,6 +542,19 @@ mkdir -p "$RS/cache2/zeta/github-dev/2.10.0/skills/cr-fix" \ got=$(cd "$RS" && CLAUDE_PLUGIN_ROOT="" CODEX_PLUGIN_CACHE="$RS/cache2" HERMES_HOME="" bash resolver.sh) is "resolver: version outranks marketplace name" "$got" "$RS/cache2/alpha/github-dev/3.0.0/skills/cr-fix" +# Default Hermes profile (HERMES_HOME unset) must land on the FLAT layout that +# `npx skills` actually writes. Every $HERMES_HOME-guarded branch is skipped when +# the var is unset, so before #166's fix the final fallback returned the retired +# plugin-adapter path and parse-args.sh was unreachable. (Codex P1) +HH=$(mktemp -d) +got=$(cd "$RS" && CLAUDE_PLUGIN_ROOT="" CODEX_PLUGIN_CACHE="$RS/empty-cache" HOME="$HH" bash -c 'unset HERMES_HOME; . ./resolver.sh') +is "resolver: unset HERMES_HOME -> flat default" "$got" "$HH/.hermes/skills/cr-fix" +# A profile that still carries the legacy adapter layout keeps resolving to it. +mkdir -p "$HH/.hermes/plugins/github-dev/skills/cr-fix" +got=$(cd "$RS" && CLAUDE_PLUGIN_ROOT="" CODEX_PLUGIN_CACHE="$RS/empty-cache" HOME="$HH" bash -c 'unset HERMES_HOME; . ./resolver.sh') +is "resolver: legacy plugin layout still wins when present" "$got" "$HH/.hermes/plugins/github-dev/skills/cr-fix" +rm -rf "$HH" + # Fresh env (no cache at all) must not kill an errexit caller — the unguarded # CODEX_CAND ls substitution died rc=2 under set -euo pipefail. (counsel P1) rrc=0; (cd "$RS" && CLAUDE_PLUGIN_ROOT="" CODEX_PLUGIN_CACHE="$RS/no-such-cache" HERMES_HOME="" \ diff --git a/plugins/ml-toolkit/.claude-plugin/plugin.json b/plugins/ml-toolkit/.claude-plugin/plugin.json index 0f31a661..0ee96a4d 100644 --- a/plugins/ml-toolkit/.claude-plugin/plugin.json +++ b/plugins/ml-toolkit/.claude-plugin/plugin.json @@ -1,5 +1,5 @@ { "name": "ml-toolkit", - "version": "1.4.5", + "version": "1.4.6", "description": "ML/multimodal development principles, GPU parallel processing, Gradio CV apps, CV notebook generation, interactive CV data exploration" } diff --git a/plugins/ml-toolkit/.codex-plugin/plugin.json b/plugins/ml-toolkit/.codex-plugin/plugin.json index 9bb68298..830c18a5 100644 --- a/plugins/ml-toolkit/.codex-plugin/plugin.json +++ b/plugins/ml-toolkit/.codex-plugin/plugin.json @@ -1,6 +1,6 @@ { "name": "ml-toolkit", - "version": "1.4.5", + "version": "1.4.6", "description": "ML/multimodal development principles, GPU parallel processing, Gradio CV apps, CV notebook generation, interactive CV data exploration", "author": { "name": "YoungjaeDev" diff --git a/plugins/ml-toolkit/skills/gpu-parallel-pipeline/SKILL.md b/plugins/ml-toolkit/skills/gpu-parallel-pipeline/SKILL.md index 096a0a63..771e67c0 100644 --- a/plugins/ml-toolkit/skills/gpu-parallel-pipeline/SKILL.md +++ b/plugins/ml-toolkit/skills/gpu-parallel-pipeline/SKILL.md @@ -119,12 +119,14 @@ elif SKILL_DIR=$( done < <(ls -1d "${CODEX_PLUGIN_CACHE:-$HOME/.codex/plugins/cache}"/*/ml-toolkit/*/ 2>/dev/null \ | awk -F/ '{print $(NF-1)"\t"$0}' | sort -t. -k1,1rn -k2,2rn -k3,3rn | cut -f2- | sed 's#/$##') ); [ -n "$SKILL_DIR" ]; then : # Codex 0.135 plugin cache (highest COMPLETE version) -elif [ -n "${HERMES_HOME:-}" ] && [ -d "$HERMES_HOME/plugins/ml-toolkit/skills/gpu-parallel-pipeline" ]; then - SKILL_DIR="$HERMES_HOME/plugins/ml-toolkit/skills/gpu-parallel-pipeline" # Hermes profile install elif [ -n "${HERMES_HOME:-}" ] && [ -d "$HERMES_HOME/skills/gpu-parallel-pipeline" ]; then - SKILL_DIR="$HERMES_HOME/skills/gpu-parallel-pipeline" # Hermes skill-level install (unverified) + SKILL_DIR="$HERMES_HOME/skills/gpu-parallel-pipeline" # Hermes profile, flat (npx skills) +elif [ -n "${HERMES_HOME:-}" ] && [ -d "$HERMES_HOME/plugins/ml-toolkit/skills/gpu-parallel-pipeline" ]; then + SKILL_DIR="$HERMES_HOME/plugins/ml-toolkit/skills/gpu-parallel-pipeline" # legacy plugin-adapter layout +elif [ -d "$HOME/.hermes/plugins/ml-toolkit/skills/gpu-parallel-pipeline" ]; then + SKILL_DIR="$HOME/.hermes/plugins/ml-toolkit/skills/gpu-parallel-pipeline" # legacy default install else - SKILL_DIR="$HOME/.hermes/plugins/ml-toolkit/skills/gpu-parallel-pipeline" # Hermes default install + SKILL_DIR="$HOME/.hermes/skills/gpu-parallel-pipeline" # default profile, flat (npx skills) fi [ -d "$SKILL_DIR" ] || { echo "gpu-parallel-pipeline: skill dir not resolved" >&2; exit 1; } python "$SKILL_DIR/scripts/check_gpu_memory.py" From ddc4c2fea506975cbca0a253cb87328bbd411c87 Mon Sep 17 00:00:00 2001 From: YoungjaeDev Date: Mon, 27 Jul 2026 11:51:21 +0900 Subject: [PATCH 12/12] fix: flat-before-legacy resolver order, scope back the Hermes claim MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit CodeRabbit (Major): both resolvers probed the legacy $HOME/.hermes/plugins/... path before the flat one, so a half-migrated machine carrying both directories would run the stale adapter copy. Flat is probed first now. The terminal else stays flat — my first pass at this reordering moved it to the legacy path and the new default-profile test caught it (89 pass, 1 fail) before it shipped. Third resolver case added: flat beats legacy when both exist. Suite 89 -> 90. Codex (P1 x2): the docs claimed all 52 skills work under Hermes. Measured, they do not. npx skills carries the skills// directory and nothing above it — -s cr-fix arrives whole (23 scripts included), -s e2e-author arrives as a lone SKILL.md because its role-contracts.md lives at plugin level. So two classes install but cannot run: skills depending on plugin-level files (e2e-harness, deepwiki, docs-forge, llm-wiki) and skills mandating a tool Hermes lacks (notebook:edit-notebook is NotebookEdit-only and forbids Edit/Write). The first class never worked on Hermes — none of those plugins were in the old HERMES_ELIGIBLE allowlist — so this is an overclaim in my own documentation, not a regression. README and AGENTS.md now state the boundary, with the measurement behind it, plus the authoring rule it implies: bundle a skill's files inside skills//, not at plugin level. The installer deliberately does not filter these out — a filter is the allowlist this PR just removed, wearing a different name. Per-skill portability audit is follow-up work. github-dev 2.11.4, ml-toolkit 1.4.7, marketplace 2.9.3. Refs #166 --- .claude-plugin/marketplace.json | 6 +++--- AGENTS.md | 3 ++- README.md | 9 ++++++++- plugins/github-dev/.claude-plugin/plugin.json | 2 +- plugins/github-dev/.codex-plugin/plugin.json | 2 +- plugins/github-dev/skills/cr-fix/SKILL.md | 8 ++++++-- plugins/github-dev/skills/cr-fix/tests/run-tests.sh | 10 ++++++++-- plugins/ml-toolkit/.claude-plugin/plugin.json | 2 +- plugins/ml-toolkit/.codex-plugin/plugin.json | 2 +- .../ml-toolkit/skills/gpu-parallel-pipeline/SKILL.md | 4 +++- 10 files changed, 34 insertions(+), 14 deletions(-) diff --git a/.claude-plugin/marketplace.json b/.claude-plugin/marketplace.json index 482d1c71..b036f54c 100644 --- a/.claude-plugin/marketplace.json +++ b/.claude-plugin/marketplace.json @@ -5,7 +5,7 @@ }, "metadata": { "description": "Personal Claude Code plugin collection with 24 specialized plugins. Codex 0.135 native — generated `.agents/plugins/marketplace.json` + per-plugin `.codex-plugin/plugin.json` (`scripts/sync-codex-manifests.mjs`). Hermes Agent installs skills from the same tree via `npx skills` (`scripts/install-skills.mjs`), with no generated adapter.", - "version": "2.9.2" + "version": "2.9.3" }, "plugins": [ { @@ -19,7 +19,7 @@ "name": "github-dev", "source": "./plugins/github-dev", "description": "GitHub workflow: commit, PR, issue, worktree, unified CodeRabbit + ChatGPT-Codex cr-fix pipeline v2 (Step 5 pre-flight review detection across CR commit-status + comments + Codex reviews + Codex emoji 3-channel; autonomous Step 9 judgment replaces per-finding AskUserQuestion — LLM judges real/spurious + severity + fix-size and applies/defers/skips with logged reasoning; rate-limit sniffer now covers commit-status description + in-place comment edits; polling interval 60s → 8s; --auto-merge + --skip-minor + --cr-source retained), project tracking, release. All workflows are now skills (commit-and-push, create-issue-label, decompose-issue, update-progress, resolve-issue, release, cr-fix, post-merge) — no commands surface, so they run under Codex too. post-merge runs a mandatory built-in wiki-lore ingest step (absorbed llm-wiki:post-merge-wiki) plus an optional Step 4.5 ephemeral-artifact pruning gate (heuristic candidates → AskUserQuestion → git rm). 2.8.0 correctness repairs: CR-state fetch failures map to a real error channel (no longer masked as a clean 'none'), a null-repository GraphQL response fails loudly instead of a silent false-clean convergence, and an active `@coderabbitai rate limit` query resolves ambiguous passive rate-limit sniffs.", - "version": "2.11.3", + "version": "2.11.4", "category": "github" }, { @@ -61,7 +61,7 @@ "name": "ml-toolkit", "source": "./plugins/ml-toolkit", "description": "ML/multimodal development principles, GPU parallel processing, Gradio CV apps, CV notebook generation, interactive CV data exploration", - "version": "1.4.6", + "version": "1.4.7", "category": "development" }, { diff --git a/AGENTS.md b/AGENTS.md index 294570e7..36f7e845 100644 --- a/AGENTS.md +++ b/AGENTS.md @@ -239,7 +239,8 @@ node scripts/install-skills.mjs --selftest # 검색 로직 self-check (TTY· ``` - Hermes Agent 도 **동일한** `plugins//` 트리를 직접 읽습니다. 다만 **생성 산출물이 없습니다** — `npx skills`(vercel-labs/skills)가 `.claude-plugin/marketplace.json` 을 직접 파싱해 `plugins//skills/*/SKILL.md` 를 찾아 `~/.hermes/skills/` 로 설치합니다. `scripts/install-skills.mjs` 는 그 위에 플러그인 그룹 선택기와 `HERMES_HOME` 프로필 타겟팅만 얹은 zero-dep 래퍼입니다. -- 커버리지는 allowlist 가 아니라 "스킬을 가진 플러그인 전부"입니다 (현재 23 플러그인 / 52 스킬). 유지할 명단이 없으므로 플러그인을 추가해도 Hermes 쪽에 할 일이 없습니다. +- **설치** 커버리지는 allowlist 가 아니라 "스킬을 가진 플러그인 전부"입니다 (현재 23 플러그인 / 52 스킬). 유지할 명단이 없으므로 플러그인을 추가해도 Hermes 쪽에 할 일이 없습니다. +- **설치 가능 ≠ 실행 가능.** `npx skills` 는 `skills//` 디렉터리 안만 나릅니다 — 그 하위 `scripts/`·`references/`·`assets/` 는 따라오지만 **plugin-level 파일은 오지 않습니다** (실측 2026-07-27: `-s cr-fix` 는 scripts 23개 포함 온전, `-s e2e-author` 는 `SKILL.md` 하나만). 따라서 (a) plugin-level 파일에 의존하는 스킬(`e2e-harness`·`deepwiki`·`docs-forge`·`llm-wiki`)과 (b) Hermes 에 없는 도구를 강제하는 스킬(`notebook:edit-notebook` 의 `NotebookEdit` 전용 규칙)은 설치돼도 실행되지 않습니다. (a) 부류는 이전 어댑터 allowlist 에도 없어 Hermes 에서 동작한 적이 없습니다. 설치기는 이를 필터링하지 않습니다 — 필터는 방금 없앤 allowlist 의 재도입이기 때문입니다. **새 skill 이 번들 파일을 쓸 때는 plugin-level 이 아니라 `skills//` 안에 두세요.** - `~/.hermes/skills/` 는 Hermes 의 skill SoT 이고, 여기 설치된 스킬은 `skills_list()` 에 자동 노출되며 슬래시 커맨드가 됩니다 (공식 docs). 즉 `description` 기반 표면화가 Claude Code·Codex 와 동일하게 동작합니다. - 설치 방식은 `npx skills` 가 정합니다 — 문서상 기본은 심볼릭 링크(`~/.agents/skills/` 를 정본으로 두고 각 에이전트 디렉터리가 가리킴)이고 `--copy` 또는 링크 불가 시 복사입니다. 다만 `-a hermes-agent` 는 실측(2026-07-27, skills v1.5.20)에서 링크가 아니라 **복사**로 설치됐으므로, 소스 트리를 고쳐도 Hermes 설치본에 자동 반영되지 않습니다 — 재설치하거나 `npx skills update` 를 도세요. - 이름은 평평하게 설치됩니다 — `github-dev:cr-fix` 가 아니라 `cr-fix` 이므로 외부 스킬과 이름이 겹치지 않게 유지하세요. diff --git a/README.md b/README.md index d8286011..a6e8915e 100644 --- a/README.md +++ b/README.md @@ -704,7 +704,14 @@ npx skills add YoungjaeDev/my-claude-plugins -a hermes-agent -s cr-fix -g npx skills add . -l # 이 저장소가 노출하는 스킬 목록 ``` -커버리지는 allowlist 가 아니라 "스킬을 가진 플러그인 전부" 입니다 (현재 23 플러그인 / 52 스킬). global 설치 경로는 Hermes `~/.hermes/skills/`, Codex `~/.agents/skills/` 이고(실측 2026-07-27 — `~/.codex/skills/` 는 `.system` 전용), 두 런타임 모두 그 디렉터리를 자동 인덱싱합니다 — Hermes 에서는 `skills_list()` 에 노출되며 슬래시 커맨드로도 잡힙니다. 설치 메커니즘(symlink/copy)·충돌·lockfile 은 `npx skills` 에 위임하고, Hermes 프로필은 `HERMES_HOME` env 로 타겟팅합니다. +**설치** 커버리지는 allowlist 가 아니라 "스킬을 가진 플러그인 전부" 입니다 (현재 23 플러그인 / 52 스킬). global 설치 경로는 Hermes `~/.hermes/skills/`, Codex `~/.agents/skills/` 이고(실측 2026-07-27 — `~/.codex/skills/` 는 `.system` 전용), 두 런타임 모두 그 디렉터리를 자동 인덱싱합니다 — Hermes 에서는 `skills_list()` 에 노출되며 슬래시 커맨드로도 잡힙니다. + +> **설치된다고 전부 동작하는 것은 아닙니다.** `npx skills` 는 스킬 디렉터리 **안**만 나릅니다 — `skills//` 하위의 `scripts/`·`references/`·`assets/` 는 따라오지만 그 **위**의 plugin-level 파일은 오지 않습니다 (실측 2026-07-27: `-s cr-fix` 는 scripts 23개까지 온전히, `-s e2e-author` 는 `SKILL.md` 하나만). 그래서 두 부류는 Hermes 에서 설치는 되지만 실행되지 않습니다: +> +> - **plugin-level 파일에 의존하는 스킬** — `e2e-harness`(`references/role-contracts.md` 없으면 abort), `deepwiki`, `docs-forge`, `llm-wiki`. 이들은 이전 어댑터 allowlist 에도 없었으므로 Hermes 에서 동작한 적이 없습니다 (이번 변경이 만든 회귀가 아님). +> - **Hermes 에 없는 도구를 강제하는 스킬** — 예: `notebook:edit-notebook` 은 `NotebookEdit` 전용이고 `Edit`/`Write` 대체를 금지합니다. +> +> 스킬별 Hermes 이식성 감사는 별도 작업입니다. 설치기는 이를 필터링하지 않습니다 — 필터를 두면 방금 없앤 allowlist 가 이름만 바꿔 돌아오기 때문입니다. 설치 메커니즘(symlink/copy)·충돌·lockfile 은 `npx skills` 에 위임하고, Hermes 프로필은 `HERMES_HOME` env 로 타겟팅합니다. 스킬 이름은 평평하게 설치됩니다 (`github-dev:cr-fix` 가 아니라 `cr-fix`). 이 저장소의 52개는 서로 유니크하며 `--selftest` 가 이를 강제하지만, 다른 출처의 스킬과 이름이 겹치지 않는지는 확인이 필요합니다. diff --git a/plugins/github-dev/.claude-plugin/plugin.json b/plugins/github-dev/.claude-plugin/plugin.json index cdda68a9..6b5f1c82 100644 --- a/plugins/github-dev/.claude-plugin/plugin.json +++ b/plugins/github-dev/.claude-plugin/plugin.json @@ -1,6 +1,6 @@ { "name": "github-dev", - "version": "2.11.3", + "version": "2.11.4", "description": "GitHub workflow: commit, PR, issue, worktree, unified CodeRabbit + ChatGPT-Codex cr-fix pipeline v2 (Step 5 pre-flight review detection across CR commit-status + comments + Codex reviews + Codex emoji 3-channel; autonomous Step 9 judgment replaces per-finding AskUserQuestion — LLM judges real/spurious + severity + fix-size and applies/defers/skips with logged reasoning; rate-limit sniffer now covers commit-status description + in-place comment edits; polling interval 60s → 8s; --auto-merge + --skip-minor + --cr-source retained), project tracking, release. All workflows are now skills (commit-and-push, create-issue-label, decompose-issue, update-progress, resolve-issue, release, cr-fix, post-merge) — no commands surface, so they run under Codex too. post-merge runs a mandatory built-in wiki-lore ingest step (absorbed llm-wiki:post-merge-wiki) plus an optional Step 4.5 ephemeral-artifact pruning gate (heuristic candidates → AskUserQuestion → git rm). 2.8.0 correctness repairs: CR-state fetch failures map to a real error channel (no longer masked as a clean 'none'), a null-repository GraphQL response fails loudly instead of a silent false-clean convergence, and an active `@coderabbitai rate limit` query resolves ambiguous passive rate-limit sniffs.", "skills": [ "./skills/cr-fix", diff --git a/plugins/github-dev/.codex-plugin/plugin.json b/plugins/github-dev/.codex-plugin/plugin.json index f6741b4d..e370ed92 100644 --- a/plugins/github-dev/.codex-plugin/plugin.json +++ b/plugins/github-dev/.codex-plugin/plugin.json @@ -1,6 +1,6 @@ { "name": "github-dev", - "version": "2.11.3", + "version": "2.11.4", "description": "GitHub workflow: commit, PR, issue, worktree, unified CodeRabbit + ChatGPT-Codex cr-fix pipeline v2 (Step 5 pre-flight review detection across CR commit-status + comments + Codex reviews + Codex emoji 3-channel; autonomous Step 9 judgment replaces per-finding AskUserQuestion — LLM judges real/spurious + severity + fix-size and applies/defers/skips with logged reasoning; rate-limit sniffer now covers commit-status description + in-place comment edits; polling interval 60s → 8s; --auto-merge + --skip-minor + --cr-source retained), project tracking, release. All workflows are now skills (commit-and-push, create-issue-label, decompose-issue, update-progress, resolve-issue, release, cr-fix, post-merge) — no commands surface, so they run under Codex too. post-merge runs a mandatory built-in wiki-lore ingest step (absorbed llm-wiki:post-merge-wiki) plus an optional Step 4.5 ephemeral-artifact pruning gate (heuristic candidates → AskUserQuestion → git rm). 2.8.0 correctness repairs: CR-state fetch failures map to a real error channel (no longer masked as a clean 'none'), a null-repository GraphQL response fails loudly instead of a silent false-clean convergence, and an active `@coderabbitai rate limit` query resolves ambiguous passive rate-limit sniffs.", "author": { "name": "YoungjaeDev" diff --git a/plugins/github-dev/skills/cr-fix/SKILL.md b/plugins/github-dev/skills/cr-fix/SKILL.md index 8256d43d..fd03dd7e 100644 --- a/plugins/github-dev/skills/cr-fix/SKILL.md +++ b/plugins/github-dev/skills/cr-fix/SKILL.md @@ -83,10 +83,14 @@ elif [ -n "${HERMES_HOME:-}" ] && [ -d "$HERMES_HOME/skills/cr-fix" ]; then elif [ -n "${HERMES_HOME:-}" ] && [ -d "$HERMES_HOME/plugins/github-dev/skills/cr-fix" ]; then # Legacy plugin-adapter layout, kept for a profile installed before #166. SKILL_DIR="$HERMES_HOME/plugins/github-dev/skills/cr-fix" +elif [ -d "$HOME/.hermes/skills/cr-fix" ]; then + # Default profile, flat — where npx skills installs. Probed BEFORE the legacy + # path so a half-migrated machine carrying both dirs runs the current copy. + SKILL_DIR="$HOME/.hermes/skills/cr-fix" elif [ -d "$HOME/.hermes/plugins/github-dev/skills/cr-fix" ]; then - SKILL_DIR="$HOME/.hermes/plugins/github-dev/skills/cr-fix" + SKILL_DIR="$HOME/.hermes/plugins/github-dev/skills/cr-fix" # legacy default install else - # Default profile (HERMES_HOME unset) — npx skills installs flat here. + # Nothing on disk — name the path a fresh install would use, not the retired one. SKILL_DIR="$HOME/.hermes/skills/cr-fix" fi diff --git a/plugins/github-dev/skills/cr-fix/tests/run-tests.sh b/plugins/github-dev/skills/cr-fix/tests/run-tests.sh index 216766dd..e0e6fe77 100755 --- a/plugins/github-dev/skills/cr-fix/tests/run-tests.sh +++ b/plugins/github-dev/skills/cr-fix/tests/run-tests.sh @@ -524,6 +524,7 @@ elif [ -d "plugins/github-dev/skills/cr-fix" ]; then SKILL_DIR="plugins/github-d elif [ -n "$CODEX_CAND" ] && [ -d "$CODEX_CAND/skills/cr-fix" ]; then SKILL_DIR="$CODEX_CAND/skills/cr-fix" elif [ -n "${HERMES_HOME:-}" ] && [ -d "$HERMES_HOME/skills/cr-fix" ]; then SKILL_DIR="$HERMES_HOME/skills/cr-fix" elif [ -n "${HERMES_HOME:-}" ] && [ -d "$HERMES_HOME/plugins/github-dev/skills/cr-fix" ]; then SKILL_DIR="$HERMES_HOME/plugins/github-dev/skills/cr-fix" +elif [ -d "$HOME/.hermes/skills/cr-fix" ]; then SKILL_DIR="$HOME/.hermes/skills/cr-fix" elif [ -d "$HOME/.hermes/plugins/github-dev/skills/cr-fix" ]; then SKILL_DIR="$HOME/.hermes/plugins/github-dev/skills/cr-fix" else SKILL_DIR="$HOME/.hermes/skills/cr-fix"; fi printf '%s' "$SKILL_DIR" @@ -549,10 +550,15 @@ is "resolver: version outranks marketplace name" "$got" "$RS/cache2/alpha/github HH=$(mktemp -d) got=$(cd "$RS" && CLAUDE_PLUGIN_ROOT="" CODEX_PLUGIN_CACHE="$RS/empty-cache" HOME="$HH" bash -c 'unset HERMES_HOME; . ./resolver.sh') is "resolver: unset HERMES_HOME -> flat default" "$got" "$HH/.hermes/skills/cr-fix" -# A profile that still carries the legacy adapter layout keeps resolving to it. +# Legacy-only machine (never re-installed via npx skills) still resolves. mkdir -p "$HH/.hermes/plugins/github-dev/skills/cr-fix" got=$(cd "$RS" && CLAUDE_PLUGIN_ROOT="" CODEX_PLUGIN_CACHE="$RS/empty-cache" HOME="$HH" bash -c 'unset HERMES_HOME; . ./resolver.sh') -is "resolver: legacy plugin layout still wins when present" "$got" "$HH/.hermes/plugins/github-dev/skills/cr-fix" +is "resolver: legacy-only machine still resolves" "$got" "$HH/.hermes/plugins/github-dev/skills/cr-fix" +# Half-migrated machine (both dirs present) must run the CURRENT copy, not the +# stale adapter one left behind by the old install. (CR Major) +mkdir -p "$HH/.hermes/skills/cr-fix" +got=$(cd "$RS" && CLAUDE_PLUGIN_ROOT="" CODEX_PLUGIN_CACHE="$RS/empty-cache" HOME="$HH" bash -c 'unset HERMES_HOME; . ./resolver.sh') +is "resolver: flat beats legacy when both exist" "$got" "$HH/.hermes/skills/cr-fix" rm -rf "$HH" # Fresh env (no cache at all) must not kill an errexit caller — the unguarded diff --git a/plugins/ml-toolkit/.claude-plugin/plugin.json b/plugins/ml-toolkit/.claude-plugin/plugin.json index 0ee96a4d..c450d7d3 100644 --- a/plugins/ml-toolkit/.claude-plugin/plugin.json +++ b/plugins/ml-toolkit/.claude-plugin/plugin.json @@ -1,5 +1,5 @@ { "name": "ml-toolkit", - "version": "1.4.6", + "version": "1.4.7", "description": "ML/multimodal development principles, GPU parallel processing, Gradio CV apps, CV notebook generation, interactive CV data exploration" } diff --git a/plugins/ml-toolkit/.codex-plugin/plugin.json b/plugins/ml-toolkit/.codex-plugin/plugin.json index 830c18a5..46363200 100644 --- a/plugins/ml-toolkit/.codex-plugin/plugin.json +++ b/plugins/ml-toolkit/.codex-plugin/plugin.json @@ -1,6 +1,6 @@ { "name": "ml-toolkit", - "version": "1.4.6", + "version": "1.4.7", "description": "ML/multimodal development principles, GPU parallel processing, Gradio CV apps, CV notebook generation, interactive CV data exploration", "author": { "name": "YoungjaeDev" diff --git a/plugins/ml-toolkit/skills/gpu-parallel-pipeline/SKILL.md b/plugins/ml-toolkit/skills/gpu-parallel-pipeline/SKILL.md index 771e67c0..3594e74e 100644 --- a/plugins/ml-toolkit/skills/gpu-parallel-pipeline/SKILL.md +++ b/plugins/ml-toolkit/skills/gpu-parallel-pipeline/SKILL.md @@ -123,10 +123,12 @@ elif [ -n "${HERMES_HOME:-}" ] && [ -d "$HERMES_HOME/skills/gpu-parallel-pipelin SKILL_DIR="$HERMES_HOME/skills/gpu-parallel-pipeline" # Hermes profile, flat (npx skills) elif [ -n "${HERMES_HOME:-}" ] && [ -d "$HERMES_HOME/plugins/ml-toolkit/skills/gpu-parallel-pipeline" ]; then SKILL_DIR="$HERMES_HOME/plugins/ml-toolkit/skills/gpu-parallel-pipeline" # legacy plugin-adapter layout +elif [ -d "$HOME/.hermes/skills/gpu-parallel-pipeline" ]; then + SKILL_DIR="$HOME/.hermes/skills/gpu-parallel-pipeline" # default profile, flat (npx skills) elif [ -d "$HOME/.hermes/plugins/ml-toolkit/skills/gpu-parallel-pipeline" ]; then SKILL_DIR="$HOME/.hermes/plugins/ml-toolkit/skills/gpu-parallel-pipeline" # legacy default install else - SKILL_DIR="$HOME/.hermes/skills/gpu-parallel-pipeline" # default profile, flat (npx skills) + SKILL_DIR="$HOME/.hermes/skills/gpu-parallel-pipeline" # nothing on disk — name the fresh-install path fi [ -d "$SKILL_DIR" ] || { echo "gpu-parallel-pipeline: skill dir not resolved" >&2; exit 1; } python "$SKILL_DIR/scripts/check_gpu_memory.py"