Parse an entire plugin directory.
(plugin_dir: Path)
| 151 | |
| 152 | |
| 153 | def parse_plugin(plugin_dir: Path) -> ParsedPlugin: |
| 154 | """Parse an entire plugin directory.""" |
| 155 | plugin_json_path = plugin_dir / ".claude-plugin" / "plugin.json" |
| 156 | plugin_json = {} |
| 157 | if plugin_json_path.exists(): |
| 158 | plugin_json = json.loads(plugin_json_path.read_text(encoding="utf-8")) |
| 159 | |
| 160 | name = plugin_json.get("name", plugin_dir.name) |
| 161 | |
| 162 | skills = [] |
| 163 | skills_dir = plugin_dir / "skills" |
| 164 | if skills_dir.exists(): |
| 165 | for skill_dir in sorted(skills_dir.iterdir()): |
| 166 | if skill_dir.is_dir() and (skill_dir / "SKILL.md").exists(): |
| 167 | skills.append(parse_skill(skill_dir)) |
| 168 | |
| 169 | agents = [] |
| 170 | agents_dir = plugin_dir / "agents" |
| 171 | if agents_dir.exists(): |
| 172 | for agent_file in sorted(agents_dir.glob("*.md")): |
| 173 | agents.append(parse_agent(agent_file)) |
| 174 | |
| 175 | return ParsedPlugin( |
| 176 | path=plugin_dir, |
| 177 | name=name, |
| 178 | skills=skills, |
| 179 | agents=agents, |
| 180 | plugin_json=plugin_json, |
| 181 | ) |
| 182 | |
| 183 | |
| 184 | def _split_frontmatter(content: str) -> tuple[dict, str]: |