refactor(skill): SKILL.md-relative path resolver, drop Codex native plugin
STEP 0 (CANONICAL PATH SELF-CHECK) used to force any SKILL.md load that wasn't
under $HOME/.claude/plugins/cache/last30days-skill/last30days/{version}/ to
re-Read from there. That guard is Claude-Code-specific (defends against the
marketplaces/ stale-clone bug) and broke under non-Claude installers like
`npx skills add`, ~/.codex/skills/, and ~/.agents/skills/.
The new STEP 0 narrows the check to its actual target: fire only when the
loaded SKILL.md path contains /.claude/plugins/marketplaces/. Every other
install path is trusted. The 2026-04-22 incident workaround is preserved
without breaking other harnesses.
Step 1 SKILL_ROOT resolver collapses the Codex-first / Claude-fallback /
CWD-fallback chain into a single precedence walk: Claude plugin cache
(versioned) first, then ~/.codex/skills, ~/.agents/skills, repo checkout,
./.skills/last30days (npx skills install dir), CWD, and GEMINI_EXTENSION_DIR.
Also drops Codex native plugin support: .codex-plugin/plugin.json is deleted,
the badge VERSION jq fallback in line 108 stops looking at it, and render.py's
_skill_version no longer scans for it. Codex users install via `npx skills add`
or the per-harness skill dir going forward.
render.py::_skill_version gains a SKILL.md frontmatter fallback so the badge
no longer emits `v?` on install dirs that sync.sh populates (which don't
include .claude-plugin/plugin.json).
This commit is contained in:
@@ -12,21 +12,30 @@ from . import dates, schema
|
||||
|
||||
|
||||
def _skill_version() -> str:
|
||||
"""Read plugin version from a plugin manifest if available.
|
||||
"""Read plugin version from .claude-plugin/plugin.json, falling back to SKILL.md frontmatter.
|
||||
|
||||
Tries nearest plugin.json by walking up from render.py's own location.
|
||||
Falls back to "?" if not found. This keeps the badge emission from
|
||||
crashing on non-plugin-cache installs (repo checkout, Gemini, Codex).
|
||||
sync.sh does not copy .claude-plugin/ to non-cache install dirs (~/.codex/skills,
|
||||
~/.agents/skills, Hermes), so SKILL.md frontmatter is the fallback that keeps the
|
||||
badge from emitting v? on those installs. Returns "?" only if both sources are missing.
|
||||
"""
|
||||
import re
|
||||
|
||||
here = pathlib.Path(__file__).resolve()
|
||||
for parent in [here.parent, *here.parents]:
|
||||
for manifest_dir in (".codex-plugin", ".claude-plugin"):
|
||||
candidate = parent / manifest_dir / "plugin.json"
|
||||
if candidate.is_file():
|
||||
try:
|
||||
return json.loads(candidate.read_text()).get("version", "?")
|
||||
except (json.JSONDecodeError, OSError):
|
||||
return "?"
|
||||
for parent in here.parents:
|
||||
manifest = parent / ".claude-plugin" / "plugin.json"
|
||||
if manifest.is_file():
|
||||
try:
|
||||
return json.loads(manifest.read_text()).get("version", "?")
|
||||
except (json.JSONDecodeError, OSError):
|
||||
break
|
||||
|
||||
for parent in here.parents:
|
||||
skill_md = parent / "SKILL.md"
|
||||
if skill_md.is_file():
|
||||
match = re.search(r'^version:\s*"([^"]+)"\s*$', skill_md.read_text(), re.MULTILINE)
|
||||
if match:
|
||||
return match.group(1)
|
||||
break
|
||||
return "?"
|
||||
|
||||
|
||||
|
||||
Reference in New Issue
Block a user